| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Siemens Gigaset 307x driver | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 3 |  * Common header file for all connection variants | 
 | 4 |  * | 
| Tilman Schmidt | 70440cf | 2006-04-10 22:55:14 -0700 | [diff] [blame] | 5 |  * Written by Stefan Eilers | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 6 |  *        and Hansjoerg Lipp <hjlipp@web.de> | 
 | 7 |  * | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 8 |  * ===================================================================== | 
 | 9 |  *	This program is free software; you can redistribute it and/or | 
 | 10 |  *	modify it under the terms of the GNU General Public License as | 
 | 11 |  *	published by the Free Software Foundation; either version 2 of | 
 | 12 |  *	the License, or (at your option) any later version. | 
 | 13 |  * ===================================================================== | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 14 |  */ | 
 | 15 |  | 
 | 16 | #ifndef GIGASET_H | 
 | 17 | #define GIGASET_H | 
 | 18 |  | 
| Tilman Schmidt | c8770dc | 2008-12-26 01:21:29 -0800 | [diff] [blame] | 19 | /* define global prefix for pr_ macros in linux/kernel.h */ | 
 | 20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 
 | 21 |  | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 22 | #include <linux/kernel.h> | 
 | 23 | #include <linux/compiler.h> | 
 | 24 | #include <linux/types.h> | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 25 | #include <linux/spinlock.h> | 
 | 26 | #include <linux/isdnif.h> | 
 | 27 | #include <linux/usb.h> | 
 | 28 | #include <linux/skbuff.h> | 
 | 29 | #include <linux/netdevice.h> | 
 | 30 | #include <linux/ppp_defs.h> | 
 | 31 | #include <linux/timer.h> | 
 | 32 | #include <linux/interrupt.h> | 
 | 33 | #include <linux/tty.h> | 
 | 34 | #include <linux/tty_driver.h> | 
 | 35 | #include <linux/list.h> | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 36 | #include <asm/atomic.h> | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 37 |  | 
 | 38 | #define GIG_VERSION {0,5,0,0} | 
 | 39 | #define GIG_COMPAT  {0,4,0,0} | 
 | 40 |  | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 41 | #define MAX_REC_PARAMS 10	/* Max. number of params in response string */ | 
 | 42 | #define MAX_RESP_SIZE 512	/* Max. size of a response string */ | 
 | 43 | #define HW_HDR_LEN 2		/* Header size used to store ack info */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 44 |  | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 45 | #define MAX_EVENTS 64		/* size of event queue */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 46 |  | 
 | 47 | #define RBUFSIZE 8192 | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 48 | #define SBUFSIZE 4096		/* sk_buff payload size */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 49 |  | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 50 | #define TRANSBUFSIZE 768	/* bytes per skb for transparent receive */ | 
 | 51 | #define MAX_BUF_SIZE (SBUFSIZE - 2)	/* Max. size of a data packet from LL */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 52 |  | 
 | 53 | /* compile time options */ | 
 | 54 | #define GIG_MAJOR 0 | 
 | 55 |  | 
 | 56 | #define GIG_MAYINITONDIAL | 
 | 57 | #define GIG_RETRYCID | 
 | 58 | #define GIG_X75 | 
 | 59 |  | 
| Tilman Schmidt | ec81b5e | 2006-04-10 22:55:03 -0700 | [diff] [blame] | 60 | #define GIG_TICK 100		/* in milliseconds */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 61 |  | 
 | 62 | /* timeout values (unit: 1 sec) */ | 
 | 63 | #define INIT_TIMEOUT 1 | 
 | 64 |  | 
 | 65 | /* timeout values (unit: 0.1 sec) */ | 
 | 66 | #define RING_TIMEOUT 3		/* for additional parameters to RING */ | 
 | 67 | #define BAS_TIMEOUT 20		/* for response to Base USB ops */ | 
 | 68 | #define ATRDY_TIMEOUT 3		/* for HD_READY_SEND_ATDATA */ | 
 | 69 |  | 
 | 70 | #define BAS_RETRY 3		/* max. retries for base USB ops */ | 
 | 71 |  | 
 | 72 | #define MAXACT 3 | 
 | 73 |  | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 74 | extern int gigaset_debuglevel;	/* "needs" cast to (enum debuglevel) */ | 
 | 75 |  | 
| Tilman Schmidt | c652cbd | 2008-02-06 01:38:24 -0800 | [diff] [blame] | 76 | /* debug flags, combine by adding/bitwise OR */ | 
| Tilman Schmidt | 73a8881 | 2006-04-22 02:35:30 -0700 | [diff] [blame] | 77 | enum debuglevel { | 
| Tilman Schmidt | c652cbd | 2008-02-06 01:38:24 -0800 | [diff] [blame] | 78 | 	DEBUG_INTR	  = 0x00008, /* interrupt processing */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 79 | 	DEBUG_CMD	  = 0x00020, /* sent/received LL commands */ | 
 | 80 | 	DEBUG_STREAM	  = 0x00040, /* application data stream I/O events */ | 
 | 81 | 	DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */ | 
 | 82 | 	DEBUG_LLDATA	  = 0x00100, /* sent/received LL data */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 83 | 	DEBUG_DRIVER	  = 0x00400, /* driver structure */ | 
 | 84 | 	DEBUG_HDLC	  = 0x00800, /* M10x HDLC processing */ | 
 | 85 | 	DEBUG_WRITE	  = 0x01000, /* M105 data write */ | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 86 | 	DEBUG_TRANSCMD	  = 0x02000, /* AT-COMMANDS+RESPONSES */ | 
 | 87 | 	DEBUG_MCMD	  = 0x04000, /* COMMANDS THAT ARE SENT VERY OFTEN */ | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 88 | 	DEBUG_INIT	  = 0x08000, /* (de)allocation+initialization of data | 
 | 89 | 					structures */ | 
| Tilman Schmidt | c652cbd | 2008-02-06 01:38:24 -0800 | [diff] [blame] | 90 | 	DEBUG_SUSPEND	  = 0x10000, /* suspend/resume processing */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 91 | 	DEBUG_OUTPUT	  = 0x20000, /* output to device */ | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 92 | 	DEBUG_ISO	  = 0x40000, /* isochronous transfers */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 93 | 	DEBUG_IF	  = 0x80000, /* character device operations */ | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 94 | 	DEBUG_USBREQ	  = 0x100000, /* USB communication (except payload | 
 | 95 | 					 data) */ | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 96 | 	DEBUG_LOCKCMD	  = 0x200000, /* AT commands and responses when | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 97 | 					 MS_LOCKED */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 98 |  | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 99 | 	DEBUG_ANY	  = 0x3fffff, /* print message if any of the others is | 
 | 100 | 					 activated */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 101 | }; | 
 | 102 |  | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 103 | #ifdef CONFIG_GIGASET_DEBUG | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 104 |  | 
 | 105 | #define gig_dbg(level, format, arg...) \ | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 106 | 	do { \ | 
 | 107 | 		if (unlikely(((enum debuglevel)gigaset_debuglevel) & (level))) \ | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 108 | 			printk(KERN_DEBUG KBUILD_MODNAME ": " format "\n", \ | 
 | 109 | 			       ## arg); \ | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 110 | 	} while (0) | 
| Tilman Schmidt | 73a8881 | 2006-04-22 02:35:30 -0700 | [diff] [blame] | 111 | #define DEBUG_DEFAULT (DEBUG_TRANSCMD | DEBUG_CMD | DEBUG_USBREQ) | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 112 |  | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 113 | #else | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 114 |  | 
 | 115 | #define gig_dbg(level, format, arg...) do {} while (0) | 
 | 116 | #define DEBUG_DEFAULT 0 | 
 | 117 |  | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 118 | #endif | 
 | 119 |  | 
 | 120 | void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | 
| Tilman Schmidt | 0137150 | 2006-04-10 22:55:11 -0700 | [diff] [blame] | 121 | 			size_t len, const unsigned char *buf); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 122 |  | 
 | 123 | /* connection state */ | 
 | 124 | #define ZSAU_NONE			0 | 
 | 125 | #define ZSAU_DISCONNECT_IND		4 | 
 | 126 | #define ZSAU_OUTGOING_CALL_PROCEEDING	1 | 
 | 127 | #define ZSAU_PROCEEDING			1 | 
 | 128 | #define ZSAU_CALL_DELIVERED		2 | 
 | 129 | #define ZSAU_ACTIVE			3 | 
 | 130 | #define ZSAU_NULL			5 | 
 | 131 | #define ZSAU_DISCONNECT_REQ		6 | 
 | 132 | #define ZSAU_UNKNOWN			-1 | 
 | 133 |  | 
 | 134 | /* USB control transfer requests */ | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 135 | #define OUT_VENDOR_REQ	(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT) | 
 | 136 | #define IN_VENDOR_REQ	(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT) | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 137 |  | 
 | 138 | /* int-in-events 3070 */ | 
 | 139 | #define HD_B1_FLOW_CONTROL		0x80 | 
 | 140 | #define HD_B2_FLOW_CONTROL		0x81 | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 141 | #define HD_RECEIVEATDATA_ACK		(0x35)		// 3070 | 
 | 142 | 						// att: HD_RECEIVE>>AT<<DATA_ACK | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 143 | #define HD_READY_SEND_ATDATA		(0x36)		// 3070 | 
 | 144 | #define HD_OPEN_ATCHANNEL_ACK		(0x37)		// 3070 | 
 | 145 | #define HD_CLOSE_ATCHANNEL_ACK		(0x38)		// 3070 | 
 | 146 | #define HD_DEVICE_INIT_OK		(0x11)		// ISurf USB + 3070 | 
 | 147 | #define HD_OPEN_B1CHANNEL_ACK		(0x51)		// ISurf USB + 3070 | 
 | 148 | #define HD_OPEN_B2CHANNEL_ACK		(0x52)		// ISurf USB + 3070 | 
 | 149 | #define HD_CLOSE_B1CHANNEL_ACK		(0x53)		// ISurf USB + 3070 | 
 | 150 | #define HD_CLOSE_B2CHANNEL_ACK		(0x54)		// ISurf USB + 3070 | 
 | 151 | // 	 Powermangment | 
 | 152 | #define HD_SUSPEND_END			(0x61)		// ISurf USB | 
 | 153 | //   Configuration | 
 | 154 | #define HD_RESET_INTERRUPT_PIPE_ACK	(0xFF)		// ISurf USB + 3070 | 
 | 155 |  | 
 | 156 | /* control requests 3070 */ | 
 | 157 | #define	HD_OPEN_B1CHANNEL		(0x23)		// ISurf USB + 3070 | 
 | 158 | #define	HD_CLOSE_B1CHANNEL		(0x24)		// ISurf USB + 3070 | 
 | 159 | #define	HD_OPEN_B2CHANNEL		(0x25)		// ISurf USB + 3070 | 
 | 160 | #define	HD_CLOSE_B2CHANNEL		(0x26)		// ISurf USB + 3070 | 
 | 161 | #define HD_RESET_INTERRUPT_PIPE		(0x27)		// ISurf USB + 3070 | 
 | 162 | #define	HD_DEVICE_INIT_ACK		(0x34)		// ISurf USB + 3070 | 
 | 163 | #define	HD_WRITE_ATMESSAGE		(0x12)		// 3070 | 
 | 164 | #define	HD_READ_ATMESSAGE		(0x13)		// 3070 | 
 | 165 | #define	HD_OPEN_ATCHANNEL		(0x28)		// 3070 | 
 | 166 | #define	HD_CLOSE_ATCHANNEL		(0x29)		// 3070 | 
 | 167 |  | 
| Tilman Schmidt | c652cbd | 2008-02-06 01:38:24 -0800 | [diff] [blame] | 168 | /* number of B channels supported by base driver */ | 
 | 169 | #define BAS_CHANNELS	2 | 
 | 170 |  | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 171 | /* USB frames for isochronous transfer */ | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 172 | #define BAS_FRAMETIME	1	/* number of milliseconds between frames */ | 
 | 173 | #define BAS_NUMFRAMES	8	/* number of frames per URB */ | 
 | 174 | #define BAS_MAXFRAME	16	/* allocated bytes per frame */ | 
 | 175 | #define BAS_NORMFRAME	8	/* send size without flow control */ | 
 | 176 | #define BAS_HIGHFRAME	10	/* "    "    with positive flow control */ | 
 | 177 | #define BAS_LOWFRAME	5	/* "    "    with negative flow control */ | 
 | 178 | #define BAS_CORRFRAMES	4	/* flow control multiplicator */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 179 |  | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 180 | #define BAS_INBUFSIZE	(BAS_MAXFRAME * BAS_NUMFRAMES) | 
 | 181 | 					/* size of isoc in buf per URB */ | 
 | 182 | #define BAS_OUTBUFSIZE	4096		/* size of common isoc out buffer */ | 
 | 183 | #define BAS_OUTBUFPAD	BAS_MAXFRAME	/* size of pad area for isoc out buf */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 184 |  | 
 | 185 | #define BAS_INURBS	3 | 
 | 186 | #define BAS_OUTURBS	3 | 
 | 187 |  | 
 | 188 | /* variable commands in struct bc_state */ | 
 | 189 | #define AT_ISO		0 | 
 | 190 | #define AT_DIAL		1 | 
 | 191 | #define AT_MSN		2 | 
 | 192 | #define AT_BC		3 | 
 | 193 | #define AT_PROTO	4 | 
 | 194 | #define AT_TYPE		5 | 
 | 195 | #define AT_HLC		6 | 
 | 196 | #define AT_NUM		7 | 
 | 197 |  | 
 | 198 | /* variables in struct at_state_t */ | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 199 | #define VAR_ZSAU	0 | 
 | 200 | #define VAR_ZDLE	1 | 
 | 201 | #define VAR_ZVLS	2 | 
 | 202 | #define VAR_ZCTP	3 | 
 | 203 | #define VAR_NUM		4 | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 204 |  | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 205 | #define STR_NMBR	0 | 
 | 206 | #define STR_ZCPN	1 | 
 | 207 | #define STR_ZCON	2 | 
 | 208 | #define STR_ZBC		3 | 
 | 209 | #define STR_ZHLC	4 | 
 | 210 | #define STR_NUM		5 | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 211 |  | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 212 | #define EV_TIMEOUT	-105 | 
 | 213 | #define EV_IF_VER	-106 | 
 | 214 | #define EV_PROC_CIDMODE	-107 | 
 | 215 | #define EV_SHUTDOWN	-108 | 
 | 216 | #define EV_START	-110 | 
 | 217 | #define EV_STOP		-111 | 
 | 218 | #define EV_IF_LOCK	-112 | 
 | 219 | #define EV_PROTO_L2	-113 | 
 | 220 | #define EV_ACCEPT	-114 | 
 | 221 | #define EV_DIAL		-115 | 
 | 222 | #define EV_HUP		-116 | 
 | 223 | #define EV_BC_OPEN	-117 | 
 | 224 | #define EV_BC_CLOSED	-118 | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 225 |  | 
 | 226 | /* input state */ | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 227 | #define INS_command	0x0001 | 
 | 228 | #define INS_DLE_char	0x0002 | 
 | 229 | #define INS_byte_stuff	0x0004 | 
 | 230 | #define INS_have_data	0x0008 | 
 | 231 | #define INS_skip_frame	0x0010 | 
 | 232 | #define INS_DLE_command	0x0020 | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 233 | #define INS_flag_hunt	0x0040 | 
 | 234 |  | 
 | 235 | /* channel state */ | 
 | 236 | #define CHS_D_UP	0x01 | 
 | 237 | #define CHS_B_UP	0x02 | 
 | 238 | #define CHS_NOTIFY_LL	0x04 | 
 | 239 |  | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 240 | #define ICALL_REJECT	0 | 
 | 241 | #define ICALL_ACCEPT	1 | 
 | 242 | #define ICALL_IGNORE	2 | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 243 |  | 
 | 244 | /* device state */ | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 245 | #define MS_UNINITIALIZED	0 | 
 | 246 | #define MS_INIT			1 | 
 | 247 | #define MS_LOCKED		2 | 
 | 248 | #define MS_SHUTDOWN		3 | 
 | 249 | #define MS_RECOVER		4 | 
 | 250 | #define MS_READY		5 | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 251 |  | 
 | 252 | /* mode */ | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 253 | #define M_UNKNOWN	0 | 
 | 254 | #define M_CONFIG	1 | 
 | 255 | #define M_UNIMODEM	2 | 
 | 256 | #define M_CID		3 | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 257 |  | 
 | 258 | /* start mode */ | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 259 | #define SM_LOCKED	0 | 
 | 260 | #define SM_ISDN		1 /* default */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 261 |  | 
 | 262 | struct gigaset_ops; | 
 | 263 | struct gigaset_driver; | 
 | 264 |  | 
 | 265 | struct usb_cardstate; | 
 | 266 | struct ser_cardstate; | 
 | 267 | struct bas_cardstate; | 
 | 268 |  | 
 | 269 | struct bc_state; | 
 | 270 | struct usb_bc_state; | 
 | 271 | struct ser_bc_state; | 
 | 272 | struct bas_bc_state; | 
 | 273 |  | 
 | 274 | struct reply_t { | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 275 | 	int	resp_code;	/* RSP_XXXX */ | 
 | 276 | 	int	min_ConState;	/* <0 => ignore */ | 
 | 277 | 	int	max_ConState;	/* <0 => ignore */ | 
 | 278 | 	int	parameter;	/* e.g. ZSAU_XXXX <0: ignore*/ | 
 | 279 | 	int	new_ConState;	/* <0 => ignore */ | 
 | 280 | 	int	timeout;	/* >0 => *HZ; <=0 => TOUT_XXXX*/ | 
 | 281 | 	int	action[MAXACT];	/* ACT_XXXX */ | 
 | 282 | 	char	*command;	/* NULL==none */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 283 | }; | 
 | 284 |  | 
 | 285 | extern struct reply_t gigaset_tab_cid_m10x[]; | 
 | 286 | extern struct reply_t gigaset_tab_nocid_m10x[]; | 
 | 287 |  | 
 | 288 | struct inbuf_t { | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 289 | 	unsigned char		*rcvbuf;	/* usb-gigaset receive buffer */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 290 | 	struct bc_state		*bcs; | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 291 | 	struct cardstate	*cs; | 
 | 292 | 	int			inputstate; | 
| Tilman Schmidt | 9d4bee2 | 2008-02-06 01:38:28 -0800 | [diff] [blame] | 293 | 	int			head, tail; | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 294 | 	unsigned char		data[RBUFSIZE]; | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 295 | }; | 
 | 296 |  | 
 | 297 | /* isochronous write buffer structure | 
 | 298 |  * circular buffer with pad area for extraction of complete USB frames | 
 | 299 |  * - data[read..nextread-1] is valid data already submitted to the USB subsystem | 
 | 300 |  * - data[nextread..write-1] is valid data yet to be sent | 
 | 301 |  * - data[write] is the next byte to write to | 
 | 302 |  *   - in byte-oriented L2 procotols, it is completely free | 
 | 303 |  *   - in bit-oriented L2 procotols, it may contain a partial byte of valid data | 
 | 304 |  * - data[write+1..read-1] is free | 
 | 305 |  * - wbits is the number of valid data bits in data[write], starting at the LSB | 
 | 306 |  * - writesem is the semaphore for writing to the buffer: | 
 | 307 |  *   if writesem <= 0, data[write..read-1] is currently being written to | 
 | 308 |  * - idle contains the byte value to repeat when the end of valid data is | 
 | 309 |  *   reached; if nextread==write (buffer contains no data to send), either the | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 310 |  *   BAS_OUTBUFPAD bytes immediately before data[write] (if | 
 | 311 |  *   write>=BAS_OUTBUFPAD) or those of the pad area (if write<BAS_OUTBUFPAD) | 
 | 312 |  *   are also filled with that value | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 313 |  */ | 
 | 314 | struct isowbuf_t { | 
| Tilman Schmidt | 9d4bee2 | 2008-02-06 01:38:28 -0800 | [diff] [blame] | 315 | 	int		read; | 
 | 316 | 	int		nextread; | 
 | 317 | 	int		write; | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 318 | 	atomic_t	writesem; | 
 | 319 | 	int		wbits; | 
 | 320 | 	unsigned char	data[BAS_OUTBUFSIZE + BAS_OUTBUFPAD]; | 
 | 321 | 	unsigned char	idle; | 
 | 322 | }; | 
 | 323 |  | 
 | 324 | /* isochronous write URB context structure | 
 | 325 |  * data to be stored along with the URB and retrieved when it is returned | 
 | 326 |  * as completed by the USB subsystem | 
 | 327 |  * - urb: pointer to the URB itself | 
 | 328 |  * - bcs: pointer to the B Channel control structure | 
 | 329 |  * - limit: end of write buffer area covered by this URB | 
| Tilman Schmidt | dbd9823 | 2008-02-06 01:38:23 -0800 | [diff] [blame] | 330 |  * - status: URB completion status | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 331 |  */ | 
 | 332 | struct isow_urbctx_t { | 
 | 333 | 	struct urb *urb; | 
 | 334 | 	struct bc_state *bcs; | 
 | 335 | 	int limit; | 
| Tilman Schmidt | dbd9823 | 2008-02-06 01:38:23 -0800 | [diff] [blame] | 336 | 	int status; | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 337 | }; | 
 | 338 |  | 
 | 339 | /* AT state structure | 
 | 340 |  * data associated with the state of an ISDN connection, whether or not | 
 | 341 |  * it is currently assigned a B channel | 
 | 342 |  */ | 
 | 343 | struct at_state_t { | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 344 | 	struct list_head	list; | 
 | 345 | 	int			waiting; | 
 | 346 | 	int			getstring; | 
| Tilman Schmidt | 69049cc | 2006-04-10 22:55:16 -0700 | [diff] [blame] | 347 | 	unsigned		timer_index; | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 348 | 	unsigned long		timer_expires; | 
 | 349 | 	int			timer_active; | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 350 | 	unsigned int		ConState;	/* State of connection */ | 
 | 351 | 	struct reply_t		*replystruct; | 
 | 352 | 	int			cid; | 
 | 353 | 	int			int_var[VAR_NUM];	/* see VAR_XXXX */ | 
 | 354 | 	char			*str_var[STR_NUM];	/* see STR_XXXX */ | 
 | 355 | 	unsigned		pending_commands;	/* see PC_XXXX */ | 
| Tilman Schmidt | 69049cc | 2006-04-10 22:55:16 -0700 | [diff] [blame] | 356 | 	unsigned		seq_index; | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 357 |  | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 358 | 	struct cardstate	*cs; | 
 | 359 | 	struct bc_state		*bcs; | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 360 | }; | 
 | 361 |  | 
 | 362 | struct resp_type_t { | 
 | 363 | 	unsigned char	*response; | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 364 | 	int		resp_code;	/* RSP_XXXX */ | 
 | 365 | 	int		type;		/* RT_XXXX */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 366 | }; | 
 | 367 |  | 
 | 368 | struct event_t { | 
 | 369 | 	int type; | 
 | 370 | 	void *ptr, *arg; | 
 | 371 | 	int parameter; | 
 | 372 | 	int cid; | 
 | 373 | 	struct at_state_t *at_state; | 
 | 374 | }; | 
 | 375 |  | 
 | 376 | /* This buffer holds all information about the used B-Channel */ | 
 | 377 | struct bc_state { | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 378 | 	struct sk_buff *tx_skb;		/* Current transfer buffer to modem */ | 
 | 379 | 	struct sk_buff_head squeue;	/* B-Channel send Queue */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 380 |  | 
 | 381 | 	/* Variables for debugging .. */ | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 382 | 	int corrupted;			/* Counter for corrupted packages */ | 
 | 383 | 	int trans_down;			/* Counter of packages (downstream) */ | 
 | 384 | 	int trans_up;			/* Counter of packages (upstream) */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 385 |  | 
 | 386 | 	struct at_state_t at_state; | 
 | 387 | 	unsigned long rcvbytes; | 
 | 388 |  | 
 | 389 | 	__u16 fcs; | 
 | 390 | 	struct sk_buff *skb; | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 391 | 	int inputstate;			/* see INS_XXXX */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 392 |  | 
 | 393 | 	int channel; | 
 | 394 |  | 
 | 395 | 	struct cardstate *cs; | 
 | 396 |  | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 397 | 	unsigned chstate;		/* bitmap (CHS_*) */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 398 | 	int ignore; | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 399 | 	unsigned proto2;		/* Layer 2 protocol (ISDN_PROTO_L2_*) */ | 
 | 400 | 	char *commands[AT_NUM];		/* see AT_XXXX */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 401 |  | 
 | 402 | #ifdef CONFIG_GIGASET_DEBUG | 
 | 403 | 	int emptycount; | 
 | 404 | #endif | 
 | 405 | 	int busy; | 
 | 406 | 	int use_count; | 
 | 407 |  | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 408 | 	/* private data of hardware drivers */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 409 | 	union { | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 410 | 		struct ser_bc_state *ser;	/* serial hardware driver */ | 
 | 411 | 		struct usb_bc_state *usb;	/* usb hardware driver (m105) */ | 
 | 412 | 		struct bas_bc_state *bas;	/* usb hardware driver (base) */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 413 | 	} hw; | 
 | 414 | }; | 
 | 415 |  | 
 | 416 | struct cardstate { | 
 | 417 | 	struct gigaset_driver *driver; | 
 | 418 | 	unsigned minor_index; | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 419 | 	struct device *dev; | 
| Greg Kroah-Hartman | 01107d3 | 2006-08-07 22:19:37 -0700 | [diff] [blame] | 420 | 	struct device *tty_dev; | 
| Tilman Schmidt | e468c04 | 2008-02-06 01:38:29 -0800 | [diff] [blame] | 421 | 	unsigned flags; | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 422 |  | 
 | 423 | 	const struct gigaset_ops *ops; | 
 | 424 |  | 
 | 425 | 	/* Stuff to handle communication */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 426 | 	wait_queue_head_t waitqueue; | 
 | 427 | 	int waiting; | 
| Tilman Schmidt | 9d4bee2 | 2008-02-06 01:38:28 -0800 | [diff] [blame] | 428 | 	int mode;			/* see M_XXXX */ | 
 | 429 | 	int mstate;			/* Modem state: see MS_XXXX */ | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 430 | 					/* only changed by the event layer */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 431 | 	int cmd_result; | 
 | 432 |  | 
 | 433 | 	int channels; | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 434 | 	struct bc_state *bcs;		/* Array of struct bc_state */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 435 |  | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 436 | 	int onechannel;			/* data and commands transmitted in one | 
 | 437 | 					   stream (M10x) */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 438 |  | 
 | 439 | 	spinlock_t lock; | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 440 | 	struct at_state_t at_state;	/* at_state_t for cid == 0 */ | 
 | 441 | 	struct list_head temp_at_states;/* list of temporary "struct | 
 | 442 | 					   at_state_t"s without B channel */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 443 |  | 
 | 444 | 	struct inbuf_t *inbuf; | 
 | 445 |  | 
 | 446 | 	struct cmdbuf_t *cmdbuf, *lastcmdbuf; | 
 | 447 | 	spinlock_t cmdlock; | 
 | 448 | 	unsigned curlen, cmdbytes; | 
 | 449 |  | 
 | 450 | 	unsigned open_count; | 
 | 451 | 	struct tty_struct *tty; | 
 | 452 | 	struct tasklet_struct if_wake_tasklet; | 
 | 453 | 	unsigned control_state; | 
 | 454 |  | 
 | 455 | 	unsigned fwver[4]; | 
 | 456 | 	int gotfwver; | 
 | 457 |  | 
| Tilman Schmidt | 69049cc | 2006-04-10 22:55:16 -0700 | [diff] [blame] | 458 | 	unsigned running;		/* !=0 if events are handled */ | 
 | 459 | 	unsigned connected;		/* !=0 if hardware is connected */ | 
 | 460 | 	unsigned isdn_up;		/* !=0 after ISDN_STAT_RUN */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 461 |  | 
| Tilman Schmidt | 69049cc | 2006-04-10 22:55:16 -0700 | [diff] [blame] | 462 | 	unsigned cidmode; | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 463 |  | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 464 | 	int myid;			/* id for communication with LL */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 465 | 	isdn_if iif; | 
 | 466 |  | 
 | 467 | 	struct reply_t *tabnocid; | 
 | 468 | 	struct reply_t *tabcid; | 
 | 469 | 	int cs_init; | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 470 | 	int ignoreframes;		/* frames to ignore after setting up the | 
 | 471 | 					   B channel */ | 
| Tilman Schmidt | abfd1dc | 2006-04-10 22:55:12 -0700 | [diff] [blame] | 472 | 	struct mutex mutex;		/* locks this structure: | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 473 | 					 *   connected is not changed, | 
 | 474 | 					 *   hardware_up is not changed, | 
 | 475 | 					 *   MState is not changed to or from | 
 | 476 | 					 *   MS_LOCKED */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 477 |  | 
 | 478 | 	struct timer_list timer; | 
 | 479 | 	int retry_count; | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 480 | 	int dle;			/* !=0 if modem commands/responses are | 
 | 481 | 					   dle encoded */ | 
 | 482 | 	int cur_at_seq;			/* sequence of AT commands being | 
 | 483 | 					   processed */ | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 484 | 	int curchannel;			/* channel those commands are meant | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 485 | 					   for */ | 
| Tilman Schmidt | 9d4bee2 | 2008-02-06 01:38:28 -0800 | [diff] [blame] | 486 | 	int commands_pending;		/* flag(s) in xxx.commands_pending have | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 487 | 					   been set */ | 
 | 488 | 	struct tasklet_struct event_tasklet; | 
 | 489 | 					/* tasklet for serializing AT commands. | 
 | 490 | 					 * Scheduled | 
 | 491 | 					 *   -> for modem reponses (and | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 492 | 					 *      incoming data for M10x) | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 493 | 					 *   -> on timeout | 
 | 494 | 					 *   -> after setting bits in | 
 | 495 | 					 *      xxx.at_state.pending_command | 
 | 496 | 					 *      (e.g. command from LL) */ | 
 | 497 | 	struct tasklet_struct write_tasklet; | 
 | 498 | 					/* tasklet for serial output | 
 | 499 | 					 * (not used in base driver) */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 500 |  | 
 | 501 | 	/* event queue */ | 
 | 502 | 	struct event_t events[MAX_EVENTS]; | 
| Tilman Schmidt | 69049cc | 2006-04-10 22:55:16 -0700 | [diff] [blame] | 503 | 	unsigned ev_tail, ev_head; | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 504 | 	spinlock_t ev_lock; | 
 | 505 |  | 
 | 506 | 	/* current modem response */ | 
 | 507 | 	unsigned char respdata[MAX_RESP_SIZE]; | 
 | 508 | 	unsigned cbytes; | 
 | 509 |  | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 510 | 	/* private data of hardware drivers */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 511 | 	union { | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 512 | 		struct usb_cardstate *usb; /* USB hardware driver (m105) */ | 
 | 513 | 		struct ser_cardstate *ser; /* serial hardware driver */ | 
 | 514 | 		struct bas_cardstate *bas; /* USB hardware driver (base) */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 515 | 	} hw; | 
 | 516 | }; | 
 | 517 |  | 
 | 518 | struct gigaset_driver { | 
 | 519 | 	struct list_head list; | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 520 | 	spinlock_t lock;		/* locks minor tables and blocked */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 521 | 	struct tty_driver *tty; | 
 | 522 | 	unsigned have_tty; | 
 | 523 | 	unsigned minor; | 
 | 524 | 	unsigned minors; | 
 | 525 | 	struct cardstate *cs; | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 526 | 	int blocked; | 
 | 527 |  | 
 | 528 | 	const struct gigaset_ops *ops; | 
 | 529 | 	struct module *owner; | 
 | 530 | }; | 
 | 531 |  | 
 | 532 | struct cmdbuf_t { | 
 | 533 | 	struct cmdbuf_t *next, *prev; | 
 | 534 | 	int len, offset; | 
 | 535 | 	struct tasklet_struct *wake_tasklet; | 
 | 536 | 	unsigned char buf[0]; | 
 | 537 | }; | 
 | 538 |  | 
 | 539 | struct bas_bc_state { | 
 | 540 | 	/* isochronous output state */ | 
| Tilman Schmidt | 9d4bee2 | 2008-02-06 01:38:28 -0800 | [diff] [blame] | 541 | 	int		running; | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 542 | 	atomic_t	corrbytes; | 
 | 543 | 	spinlock_t	isooutlock; | 
 | 544 | 	struct isow_urbctx_t	isoouturbs[BAS_OUTURBS]; | 
 | 545 | 	struct isow_urbctx_t	*isooutdone, *isooutfree, *isooutovfl; | 
 | 546 | 	struct isowbuf_t	*isooutbuf; | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 547 | 	unsigned numsub;		/* submitted URB counter | 
 | 548 | 					   (for diagnostic messages only) */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 549 | 	struct tasklet_struct	sent_tasklet; | 
 | 550 |  | 
 | 551 | 	/* isochronous input state */ | 
 | 552 | 	spinlock_t isoinlock; | 
 | 553 | 	struct urb *isoinurbs[BAS_INURBS]; | 
 | 554 | 	unsigned char isoinbuf[BAS_INBUFSIZE * BAS_INURBS]; | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 555 | 	struct urb *isoindone;		/* completed isoc read URB */ | 
| Tilman Schmidt | dbd9823 | 2008-02-06 01:38:23 -0800 | [diff] [blame] | 556 | 	int isoinstatus;		/* status of completed URB */ | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 557 | 	int loststatus;			/* status of dropped URB */ | 
 | 558 | 	unsigned isoinlost;		/* number of bytes lost */ | 
 | 559 | 	/* state of bit unstuffing algorithm | 
 | 560 | 	   (in addition to BC_state.inputstate) */ | 
 | 561 | 	unsigned seqlen;		/* number of '1' bits not yet | 
 | 562 | 					   unstuffed */ | 
 | 563 | 	unsigned inbyte, inbits;	/* collected bits for next byte */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 564 | 	/* statistics */ | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 565 | 	unsigned goodbytes;		/* bytes correctly received */ | 
 | 566 | 	unsigned alignerrs;		/* frames with incomplete byte at end */ | 
 | 567 | 	unsigned fcserrs;		/* FCS errors */ | 
 | 568 | 	unsigned frameerrs;		/* framing errors */ | 
 | 569 | 	unsigned giants;		/* long frames */ | 
 | 570 | 	unsigned runts;			/* short frames */ | 
 | 571 | 	unsigned aborts;		/* HDLC aborts */ | 
 | 572 | 	unsigned shared0s;		/* '0' bits shared between flags */ | 
 | 573 | 	unsigned stolen0s;		/* '0' stuff bits also serving as | 
 | 574 | 					   leading flag bits */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 575 | 	struct tasklet_struct rcvd_tasklet; | 
 | 576 | }; | 
 | 577 |  | 
 | 578 | struct gigaset_ops { | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 579 | 	/* Called from ev-layer.c/interface.c for sending AT commands to the | 
 | 580 | 	   device */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 581 | 	int (*write_cmd)(struct cardstate *cs, | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 582 | 			 const unsigned char *buf, int len, | 
 | 583 | 			 struct tasklet_struct *wake_tasklet); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 584 |  | 
 | 585 | 	/* Called from interface.c for additional device control */ | 
 | 586 | 	int (*write_room)(struct cardstate *cs); | 
 | 587 | 	int (*chars_in_buffer)(struct cardstate *cs); | 
 | 588 | 	int (*brkchars)(struct cardstate *cs, const unsigned char buf[6]); | 
 | 589 |  | 
 | 590 | 	/* Called from ev-layer.c after setting up connection | 
 | 591 | 	 * Should call gigaset_bchannel_up(), when finished. */ | 
 | 592 | 	int (*init_bchannel)(struct bc_state *bcs); | 
 | 593 |  | 
 | 594 | 	/* Called from ev-layer.c after hanging up | 
 | 595 | 	 * Should call gigaset_bchannel_down(), when finished. */ | 
 | 596 | 	int (*close_bchannel)(struct bc_state *bcs); | 
 | 597 |  | 
 | 598 | 	/* Called by gigaset_initcs() for setting up bcs->hw.xxx */ | 
 | 599 | 	int (*initbcshw)(struct bc_state *bcs); | 
 | 600 |  | 
 | 601 | 	/* Called by gigaset_freecs() for freeing bcs->hw.xxx */ | 
 | 602 | 	int (*freebcshw)(struct bc_state *bcs); | 
 | 603 |  | 
| Tilman Schmidt | 73a8881 | 2006-04-22 02:35:30 -0700 | [diff] [blame] | 604 | 	/* Called by gigaset_bchannel_down() for resetting bcs->hw.xxx */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 605 | 	void (*reinitbcshw)(struct bc_state *bcs); | 
 | 606 |  | 
 | 607 | 	/* Called by gigaset_initcs() for setting up cs->hw.xxx */ | 
 | 608 | 	int (*initcshw)(struct cardstate *cs); | 
 | 609 |  | 
 | 610 | 	/* Called by gigaset_freecs() for freeing cs->hw.xxx */ | 
 | 611 | 	void (*freecshw)(struct cardstate *cs); | 
 | 612 |  | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 613 | 	/* Called from common.c/interface.c for additional serial port | 
 | 614 | 	   control */ | 
 | 615 | 	int (*set_modem_ctrl)(struct cardstate *cs, unsigned old_state, | 
 | 616 | 			      unsigned new_state); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 617 | 	int (*baud_rate)(struct cardstate *cs, unsigned cflag); | 
 | 618 | 	int (*set_line_ctrl)(struct cardstate *cs, unsigned cflag); | 
 | 619 |  | 
 | 620 | 	/* Called from i4l.c to put an skb into the send-queue. */ | 
 | 621 | 	int (*send_skb)(struct bc_state *bcs, struct sk_buff *skb); | 
 | 622 |  | 
 | 623 | 	/* Called from ev-layer.c to process a block of data | 
 | 624 | 	 * received through the common/control channel. */ | 
 | 625 | 	void (*handle_input)(struct inbuf_t *inbuf); | 
 | 626 |  | 
 | 627 | }; | 
 | 628 |  | 
 | 629 | /* = Common structures and definitions ======================================= */ | 
 | 630 |  | 
 | 631 | /* Parser states for DLE-Event: | 
 | 632 |  * <DLE-EVENT>: <DLE_FLAG> "X" <EVENT> <DLE_FLAG> "." | 
 | 633 |  * <DLE_FLAG>:  0x10 | 
 | 634 |  * <EVENT>:     ((a-z)* | (A-Z)* | (0-10)*)+ | 
 | 635 |  */ | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 636 | #define DLE_FLAG	0x10 | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 637 |  | 
 | 638 | /* =========================================================================== | 
 | 639 |  *  Functions implemented in asyncdata.c | 
 | 640 |  */ | 
 | 641 |  | 
 | 642 | /* Called from i4l.c to put an skb into the send-queue. | 
 | 643 |  * After sending gigaset_skb_sent() should be called. */ | 
 | 644 | int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb); | 
 | 645 |  | 
 | 646 | /* Called from ev-layer.c to process a block of data | 
 | 647 |  * received through the common/control channel. */ | 
 | 648 | void gigaset_m10x_input(struct inbuf_t *inbuf); | 
 | 649 |  | 
 | 650 | /* =========================================================================== | 
 | 651 |  *  Functions implemented in isocdata.c | 
 | 652 |  */ | 
 | 653 |  | 
 | 654 | /* Called from i4l.c to put an skb into the send-queue. | 
 | 655 |  * After sending gigaset_skb_sent() should be called. */ | 
 | 656 | int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb); | 
 | 657 |  | 
 | 658 | /* Called from ev-layer.c to process a block of data | 
 | 659 |  * received through the common/control channel. */ | 
 | 660 | void gigaset_isoc_input(struct inbuf_t *inbuf); | 
 | 661 |  | 
 | 662 | /* Called from bas-gigaset.c to process a block of data | 
 | 663 |  * received through the isochronous channel */ | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 664 | void gigaset_isoc_receive(unsigned char *src, unsigned count, | 
 | 665 | 			  struct bc_state *bcs); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 666 |  | 
 | 667 | /* Called from bas-gigaset.c to put a block of data | 
 | 668 |  * into the isochronous output buffer */ | 
 | 669 | int gigaset_isoc_buildframe(struct bc_state *bcs, unsigned char *in, int len); | 
 | 670 |  | 
 | 671 | /* Called from bas-gigaset.c to initialize the isochronous output buffer */ | 
 | 672 | void gigaset_isowbuf_init(struct isowbuf_t *iwb, unsigned char idle); | 
 | 673 |  | 
 | 674 | /* Called from bas-gigaset.c to retrieve a block of bytes for sending */ | 
 | 675 | int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size); | 
 | 676 |  | 
 | 677 | /* =========================================================================== | 
 | 678 |  *  Functions implemented in i4l.c/gigaset.h | 
 | 679 |  */ | 
 | 680 |  | 
 | 681 | /* Called by gigaset_initcs() for setting up with the isdn4linux subsystem */ | 
 | 682 | int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid); | 
 | 683 |  | 
 | 684 | /* Called from xxx-gigaset.c to indicate completion of sending an skb */ | 
 | 685 | void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb); | 
 | 686 |  | 
 | 687 | /* Called from common.c/ev-layer.c to indicate events relevant to the LL */ | 
 | 688 | int gigaset_isdn_icall(struct at_state_t *at_state); | 
 | 689 | int gigaset_isdn_setup_accept(struct at_state_t *at_state); | 
 | 690 | int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data); | 
 | 691 |  | 
 | 692 | void gigaset_i4l_cmd(struct cardstate *cs, int cmd); | 
 | 693 | void gigaset_i4l_channel_cmd(struct bc_state *bcs, int cmd); | 
 | 694 |  | 
 | 695 |  | 
 | 696 | static inline void gigaset_isdn_rcv_err(struct bc_state *bcs) | 
 | 697 | { | 
 | 698 | 	isdn_ctrl response; | 
 | 699 |  | 
 | 700 | 	/* error -> LL */ | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 701 | 	gig_dbg(DEBUG_CMD, "sending L1ERR"); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 702 | 	response.driver = bcs->cs->myid; | 
 | 703 | 	response.command = ISDN_STAT_L1ERR; | 
 | 704 | 	response.arg = bcs->channel; | 
 | 705 | 	response.parm.errcode = ISDN_STAT_L1ERR_RECV; | 
 | 706 | 	bcs->cs->iif.statcallb(&response); | 
 | 707 | } | 
 | 708 |  | 
 | 709 | /* =========================================================================== | 
 | 710 |  *  Functions implemented in ev-layer.c | 
 | 711 |  */ | 
 | 712 |  | 
 | 713 | /* tasklet called from common.c to process queued events */ | 
 | 714 | void gigaset_handle_event(unsigned long data); | 
 | 715 |  | 
 | 716 | /* called from isocdata.c / asyncdata.c | 
 | 717 |  * when a complete modem response line has been received */ | 
 | 718 | void gigaset_handle_modem_response(struct cardstate *cs); | 
 | 719 |  | 
 | 720 | /* =========================================================================== | 
 | 721 |  *  Functions implemented in proc.c | 
 | 722 |  */ | 
 | 723 |  | 
 | 724 | /* initialize sysfs for device */ | 
| Tilman Schmidt | b1d4746 | 2006-04-10 22:55:07 -0700 | [diff] [blame] | 725 | void gigaset_init_dev_sysfs(struct cardstate *cs); | 
 | 726 | void gigaset_free_dev_sysfs(struct cardstate *cs); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 727 |  | 
 | 728 | /* =========================================================================== | 
 | 729 |  *  Functions implemented in common.c/gigaset.h | 
 | 730 |  */ | 
 | 731 |  | 
 | 732 | void gigaset_bcs_reinit(struct bc_state *bcs); | 
 | 733 | void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 734 | 		     struct cardstate *cs, int cid); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 735 | int gigaset_get_channel(struct bc_state *bcs); | 
 | 736 | void gigaset_free_channel(struct bc_state *bcs); | 
 | 737 | int gigaset_get_channels(struct cardstate *cs); | 
 | 738 | void gigaset_free_channels(struct cardstate *cs); | 
 | 739 | void gigaset_block_channels(struct cardstate *cs); | 
 | 740 |  | 
 | 741 | /* Allocate and initialize driver structure. */ | 
 | 742 | struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 743 | 					  const char *procname, | 
 | 744 | 					  const char *devname, | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 745 | 					  const struct gigaset_ops *ops, | 
 | 746 | 					  struct module *owner); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 747 |  | 
 | 748 | /* Deallocate driver structure. */ | 
 | 749 | void gigaset_freedriver(struct gigaset_driver *drv); | 
 | 750 | void gigaset_debugdrivers(void); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 751 | struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty); | 
 | 752 | struct cardstate *gigaset_get_cs_by_id(int id); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 753 | void gigaset_blockdriver(struct gigaset_driver *drv); | 
 | 754 |  | 
| Tilman Schmidt | 917f508 | 2006-04-10 22:55:00 -0700 | [diff] [blame] | 755 | /* Allocate and initialize card state. Calls hardware dependent | 
 | 756 |    gigaset_init[b]cs(). */ | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 757 | struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | 
 | 758 | 				 int onechannel, int ignoreframes, | 
 | 759 | 				 int cidmode, const char *modulename); | 
 | 760 |  | 
 | 761 | /* Free card state. Calls hardware dependent gigaset_free[b]cs(). */ | 
 | 762 | void gigaset_freecs(struct cardstate *cs); | 
 | 763 |  | 
 | 764 | /* Tell common.c that hardware and driver are ready. */ | 
 | 765 | int gigaset_start(struct cardstate *cs); | 
 | 766 |  | 
 | 767 | /* Tell common.c that the device is not present any more. */ | 
 | 768 | void gigaset_stop(struct cardstate *cs); | 
 | 769 |  | 
 | 770 | /* Tell common.c that the driver is being unloaded. */ | 
| Tilman Schmidt | e468c04 | 2008-02-06 01:38:29 -0800 | [diff] [blame] | 771 | int gigaset_shutdown(struct cardstate *cs); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 772 |  | 
 | 773 | /* Tell common.c that an skb has been sent. */ | 
 | 774 | void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb); | 
 | 775 |  | 
 | 776 | /* Append event to the queue. | 
 | 777 |  * Returns NULL on failure or a pointer to the event on success. | 
 | 778 |  * ptr must be kmalloc()ed (and not be freed by the caller). | 
 | 779 |  */ | 
 | 780 | struct event_t *gigaset_add_event(struct cardstate *cs, | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 781 | 				  struct at_state_t *at_state, int type, | 
 | 782 | 				  void *ptr, int parameter, void *arg); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 783 |  | 
 | 784 | /* Called on CONFIG1 command from frontend. */ | 
 | 785 | int gigaset_enterconfigmode(struct cardstate *cs); //0: success <0: errorcode | 
 | 786 |  | 
 | 787 | /* cs->lock must not be locked */ | 
 | 788 | static inline void gigaset_schedule_event(struct cardstate *cs) | 
 | 789 | { | 
 | 790 | 	unsigned long flags; | 
 | 791 | 	spin_lock_irqsave(&cs->lock, flags); | 
| Tilman Schmidt | 69049cc | 2006-04-10 22:55:16 -0700 | [diff] [blame] | 792 | 	if (cs->running) | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 793 | 		tasklet_schedule(&cs->event_tasklet); | 
 | 794 | 	spin_unlock_irqrestore(&cs->lock, flags); | 
 | 795 | } | 
 | 796 |  | 
 | 797 | /* Tell common.c that B channel has been closed. */ | 
 | 798 | /* cs->lock must not be locked */ | 
 | 799 | static inline void gigaset_bchannel_down(struct bc_state *bcs) | 
 | 800 | { | 
 | 801 | 	gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_CLOSED, NULL, 0, NULL); | 
 | 802 |  | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 803 | 	gig_dbg(DEBUG_CMD, "scheduling BC_CLOSED"); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 804 | 	gigaset_schedule_event(bcs->cs); | 
 | 805 | } | 
 | 806 |  | 
 | 807 | /* Tell common.c that B channel has been opened. */ | 
 | 808 | /* cs->lock must not be locked */ | 
 | 809 | static inline void gigaset_bchannel_up(struct bc_state *bcs) | 
 | 810 | { | 
 | 811 | 	gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_OPEN, NULL, 0, NULL); | 
 | 812 |  | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 813 | 	gig_dbg(DEBUG_CMD, "scheduling BC_OPEN"); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 814 | 	gigaset_schedule_event(bcs->cs); | 
 | 815 | } | 
 | 816 |  | 
 | 817 | /* handling routines for sk_buff */ | 
 | 818 | /* ============================= */ | 
 | 819 |  | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 820 | /* pass received skb to LL | 
 | 821 |  * Warning: skb must not be accessed anymore! | 
 | 822 |  */ | 
 | 823 | static inline void gigaset_rcv_skb(struct sk_buff *skb, | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 824 | 				   struct cardstate *cs, | 
 | 825 | 				   struct bc_state *bcs) | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 826 | { | 
 | 827 | 	cs->iif.rcvcallb_skb(cs->myid, bcs->channel, skb); | 
 | 828 | 	bcs->trans_down++; | 
 | 829 | } | 
 | 830 |  | 
 | 831 | /* handle reception of corrupted skb | 
 | 832 |  * Warning: skb must not be accessed anymore! | 
 | 833 |  */ | 
 | 834 | static inline void gigaset_rcv_error(struct sk_buff *procskb, | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 835 | 				     struct cardstate *cs, | 
 | 836 | 				     struct bc_state *bcs) | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 837 | { | 
 | 838 | 	if (procskb) | 
 | 839 | 		dev_kfree_skb(procskb); | 
 | 840 |  | 
 | 841 | 	if (bcs->ignore) | 
 | 842 | 		--bcs->ignore; | 
 | 843 | 	else { | 
 | 844 | 		++bcs->corrupted; | 
 | 845 | 		gigaset_isdn_rcv_err(bcs); | 
 | 846 | 	} | 
 | 847 | } | 
 | 848 |  | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 849 | /* append received bytes to inbuf */ | 
| Tilman Schmidt | 714e823 | 2006-04-10 22:55:09 -0700 | [diff] [blame] | 850 | int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, | 
 | 851 | 		       unsigned numbytes); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 852 |  | 
 | 853 | /* =========================================================================== | 
 | 854 |  *  Functions implemented in interface.c | 
 | 855 |  */ | 
 | 856 |  | 
 | 857 | /* initialize interface */ | 
 | 858 | void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname, | 
| Greg Kroah-Hartman | f4eaa37 | 2005-06-20 21:15:16 -0700 | [diff] [blame] | 859 | 			   const char *devname); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 860 | /* release interface */ | 
 | 861 | void gigaset_if_freedriver(struct gigaset_driver *drv); | 
 | 862 | /* add minor */ | 
 | 863 | void gigaset_if_init(struct cardstate *cs); | 
 | 864 | /* remove minor */ | 
 | 865 | void gigaset_if_free(struct cardstate *cs); | 
 | 866 | /* device received data */ | 
 | 867 | void gigaset_if_receive(struct cardstate *cs, | 
| Tilman Schmidt | 784d585 | 2006-04-10 22:55:04 -0700 | [diff] [blame] | 868 | 			unsigned char *buffer, size_t len); | 
| Hansjoerg Lipp | 6fd5ea6 | 2006-03-26 01:38:29 -0800 | [diff] [blame] | 869 |  | 
 | 870 | #endif |