| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Driver for ST5481 USB ISDN modem | 
|  | 3 | * | 
|  | 4 | * Author       Frode Isaksen | 
|  | 5 | * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com> | 
|  | 6 | *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de> | 
|  | 7 | * | 
|  | 8 | * This software may be used and distributed according to the terms | 
|  | 9 | * of the GNU General Public License, incorporated herein by reference. | 
|  | 10 | * | 
|  | 11 | */ | 
|  | 12 |  | 
|  | 13 | #ifndef _ST5481_H_ | 
|  | 14 | #define _ST5481_H_ | 
|  | 15 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 16 |  | 
|  | 17 | // USB IDs, the Product Id is in the range 0x4810-0x481F | 
|  | 18 |  | 
|  | 19 | #define ST_VENDOR_ID 0x0483 | 
|  | 20 | #define ST5481_PRODUCT_ID 0x4810 | 
|  | 21 | #define ST5481_PRODUCT_ID_MASK 0xFFF0 | 
|  | 22 |  | 
|  | 23 | // ST5481 endpoints when using alternative setting 3 (2B+D). | 
|  | 24 | // To get the endpoint address, OR with 0x80 for IN endpoints. | 
|  | 25 |  | 
|  | 26 | #define EP_CTRL   0x00U /* Control endpoint */ | 
|  | 27 | #define EP_INT    0x01U /* Interrupt endpoint */ | 
|  | 28 | #define EP_B1_OUT 0x02U /* B1 channel out */ | 
|  | 29 | #define EP_B1_IN  0x03U /* B1 channel in */ | 
|  | 30 | #define EP_B2_OUT 0x04U /* B2 channel out */ | 
|  | 31 | #define EP_B2_IN  0x05U /* B2 channel in */ | 
|  | 32 | #define EP_D_OUT  0x06U /* D channel out */ | 
|  | 33 | #define EP_D_IN   0x07U /* D channel in */ | 
|  | 34 |  | 
|  | 35 | // Number of isochronous packets. With 20 packets we get | 
|  | 36 | // 50 interrupts/sec for each endpoint. | 
|  | 37 |  | 
|  | 38 | #define NUM_ISO_PACKETS_D      20 | 
|  | 39 | #define NUM_ISO_PACKETS_B      20 | 
|  | 40 |  | 
|  | 41 | // Size of each isochronous packet. | 
|  | 42 | // In outgoing direction we need to match ISDN data rates: | 
|  | 43 | // D:  2 bytes / msec -> 16 kbit / s | 
|  | 44 | // B: 16 bytes / msec -> 64 kbit / s | 
|  | 45 | #define SIZE_ISO_PACKETS_D_IN  16 | 
|  | 46 | #define SIZE_ISO_PACKETS_D_OUT 2 | 
|  | 47 | #define SIZE_ISO_PACKETS_B_IN  32 | 
|  | 48 | #define SIZE_ISO_PACKETS_B_OUT 8 | 
|  | 49 |  | 
|  | 50 | // If we overrun/underrun, we send one packet with +/- 2 bytes | 
|  | 51 | #define B_FLOW_ADJUST 2 | 
|  | 52 |  | 
|  | 53 | // Registers that are written using vendor specific device request | 
|  | 54 | // on endpoint 0. | 
|  | 55 |  | 
|  | 56 | #define LBA			0x02 /* S loopback */ | 
|  | 57 | #define SET_DEFAULT		0x06 /* Soft reset */ | 
|  | 58 | #define LBB			0x1D /* S maintenance loopback */ | 
|  | 59 | #define STT			0x1e /* S force transmission signals */ | 
|  | 60 | #define SDA_MIN			0x20 /* SDA-sin minimal value */ | 
|  | 61 | #define SDA_MAX			0x21 /* SDA-sin maximal value */ | 
|  | 62 | #define SDELAY_VALUE		0x22 /* Delay between Tx and Rx clock */ | 
|  | 63 | #define IN_D_COUNTER		0x36 /* D receive channel fifo counter */ | 
|  | 64 | #define OUT_D_COUNTER		0x37 /* D transmit channel fifo counter */ | 
|  | 65 | #define IN_B1_COUNTER		0x38 /* B1 receive channel fifo counter */ | 
|  | 66 | #define OUT_B1_COUNTER		0x39 /* B1 transmit channel fifo counter */ | 
|  | 67 | #define IN_B2_COUNTER		0x3a /* B2 receive channel fifo counter */ | 
|  | 68 | #define OUT_B2_COUNTER		0x3b /* B2 transmit channel fifo counter */ | 
|  | 69 | #define FFCTRL_IN_D		0x3C /* D receive channel fifo threshold low */ | 
|  | 70 | #define FFCTRH_IN_D		0x3D /* D receive channel fifo threshold high */ | 
|  | 71 | #define FFCTRL_OUT_D		0x3E /* D transmit channel fifo threshold low */ | 
|  | 72 | #define FFCTRH_OUT_D		0x3F /* D transmit channel fifo threshold high */ | 
|  | 73 | #define FFCTRL_IN_B1		0x40 /* B1 receive channel fifo threshold low */ | 
|  | 74 | #define FFCTRH_IN_B1		0x41 /* B1 receive channel fifo threshold high */ | 
|  | 75 | #define FFCTRL_OUT_B1		0x42 /* B1 transmit channel fifo threshold low */ | 
|  | 76 | #define FFCTRH_OUT_B1		0x43 /* B1 transmit channel fifo threshold high */ | 
|  | 77 | #define FFCTRL_IN_B2		0x44 /* B2 receive channel fifo threshold low */ | 
|  | 78 | #define FFCTRH_IN_B2		0x45 /* B2 receive channel fifo threshold high */ | 
|  | 79 | #define FFCTRL_OUT_B2		0x46 /* B2 transmit channel fifo threshold low */ | 
|  | 80 | #define FFCTRH_OUT_B2		0x47 /* B2 transmit channel fifo threshold high */ | 
|  | 81 | #define MPMSK			0x4A /* Multi purpose interrupt MASK register */ | 
|  | 82 | #define	FFMSK_D			0x4c /* D fifo interrupt MASK register */ | 
|  | 83 | #define	FFMSK_B1		0x4e /* B1 fifo interrupt MASK register */ | 
|  | 84 | #define	FFMSK_B2		0x50 /* B2 fifo interrupt MASK register */ | 
|  | 85 | #define GPIO_DIR		0x52 /* GPIO pins direction registers */ | 
|  | 86 | #define GPIO_OUT		0x53 /* GPIO pins output register */ | 
|  | 87 | #define GPIO_IN			0x54 /* GPIO pins input register */ | 
|  | 88 | #define TXCI			0x56 /* CI command to be transmitted */ | 
|  | 89 |  | 
|  | 90 |  | 
|  | 91 | // Format of the interrupt packet received on endpoint 1: | 
|  | 92 | // | 
|  | 93 | // +--------+--------+--------+--------+--------+--------+ | 
|  | 94 | // !MPINT   !FFINT_D !FFINT_B1!FFINT_B2!CCIST   !GPIO_INT! | 
|  | 95 | // +--------+--------+--------+--------+--------+--------+ | 
|  | 96 |  | 
|  | 97 | // Offsets in the interrupt packet | 
|  | 98 |  | 
|  | 99 | #define MPINT			0 | 
|  | 100 | #define FFINT_D			1 | 
|  | 101 | #define FFINT_B1		2 | 
|  | 102 | #define FFINT_B2		3 | 
|  | 103 | #define CCIST			4 | 
|  | 104 | #define GPIO_INT		5 | 
|  | 105 | #define INT_PKT_SIZE            6 | 
|  | 106 |  | 
|  | 107 | // MPINT | 
|  | 108 | #define LSD_INT                 0x80 /* S line activity detected */ | 
|  | 109 | #define RXCI_INT		0x40 /* Indicate primitive arrived */ | 
|  | 110 | #define	DEN_INT			0x20 /* Signal enabling data out of D Tx fifo */ | 
|  | 111 | #define DCOLL_INT		0x10 /* D channel collision */ | 
|  | 112 | #define AMIVN_INT		0x04 /* AMI violation number reached 2 */ | 
|  | 113 | #define INFOI_INT		0x04 /* INFOi changed */ | 
|  | 114 | #define DRXON_INT               0x02 /* Reception channel active */ | 
|  | 115 | #define GPCHG_INT               0x01 /* GPIO pin value changed */ | 
|  | 116 |  | 
|  | 117 | // FFINT_x | 
|  | 118 | #define IN_OVERRUN		0x80 /* In fifo overrun */ | 
|  | 119 | #define OUT_UNDERRUN		0x40 /* Out fifo underrun */ | 
|  | 120 | #define IN_UP			0x20 /* In fifo thresholdh up-crossed */ | 
|  | 121 | #define IN_DOWN			0x10 /* In fifo thresholdl down-crossed */ | 
|  | 122 | #define OUT_UP			0x08 /* Out fifo thresholdh up-crossed */ | 
|  | 123 | #define OUT_DOWN		0x04 /* Out fifo thresholdl down-crossed */ | 
|  | 124 | #define IN_COUNTER_ZEROED	0x02 /* In down-counter reached 0 */ | 
|  | 125 | #define OUT_COUNTER_ZEROED	0x01 /* Out down-counter reached 0 */ | 
|  | 126 |  | 
|  | 127 | #define ANY_REC_INT	(IN_OVERRUN+IN_UP+IN_DOWN+IN_COUNTER_ZEROED) | 
|  | 128 | #define ANY_XMIT_INT	(OUT_UNDERRUN+OUT_UP+OUT_DOWN+OUT_COUNTER_ZEROED) | 
|  | 129 |  | 
|  | 130 |  | 
|  | 131 | // Level 1 commands that are sent using the TXCI device request | 
|  | 132 | #define ST5481_CMD_DR		 0x0 /* Deactivation Request */ | 
|  | 133 | #define ST5481_CMD_RES		 0x1 /* state machine RESet */ | 
|  | 134 | #define ST5481_CMD_TM1		 0x2 /* Test Mode 1 */ | 
|  | 135 | #define ST5481_CMD_TM2		 0x3 /* Test Mode 2 */ | 
|  | 136 | #define ST5481_CMD_PUP		 0x7 /* Power UP */ | 
|  | 137 | #define ST5481_CMD_AR8		 0x8 /* Activation Request class 1 */ | 
|  | 138 | #define ST5481_CMD_AR10		 0x9 /* Activation Request class 2 */ | 
|  | 139 | #define ST5481_CMD_ARL		 0xA /* Activation Request Loopback */ | 
|  | 140 | #define ST5481_CMD_PDN		 0xF /* Power DoWn */ | 
|  | 141 |  | 
|  | 142 | // Turn on/off the LEDs using the GPIO device request. | 
|  | 143 | // To use the B LEDs, number_of_leds must be set to 4 | 
|  | 144 | #define B1_LED		0x10U | 
|  | 145 | #define B2_LED		0x20U | 
|  | 146 | #define GREEN_LED	0x40U | 
|  | 147 | #define RED_LED	        0x80U | 
|  | 148 |  | 
|  | 149 | // D channel out states | 
|  | 150 | enum { | 
|  | 151 | ST_DOUT_NONE, | 
|  | 152 |  | 
|  | 153 | ST_DOUT_SHORT_INIT, | 
|  | 154 | ST_DOUT_SHORT_WAIT_DEN, | 
|  | 155 |  | 
|  | 156 | ST_DOUT_LONG_INIT, | 
|  | 157 | ST_DOUT_LONG_WAIT_DEN, | 
|  | 158 | ST_DOUT_NORMAL, | 
|  | 159 |  | 
|  | 160 | ST_DOUT_WAIT_FOR_UNDERRUN, | 
|  | 161 | ST_DOUT_WAIT_FOR_NOT_BUSY, | 
|  | 162 | ST_DOUT_WAIT_FOR_STOP, | 
|  | 163 | ST_DOUT_WAIT_FOR_RESET, | 
|  | 164 | }; | 
|  | 165 |  | 
|  | 166 | #define DOUT_STATE_COUNT (ST_DOUT_WAIT_FOR_RESET + 1) | 
|  | 167 |  | 
|  | 168 | // D channel out events | 
|  | 169 | enum { | 
|  | 170 | EV_DOUT_START_XMIT, | 
|  | 171 | EV_DOUT_COMPLETE, | 
|  | 172 | EV_DOUT_DEN, | 
|  | 173 | EV_DOUT_RESETED, | 
|  | 174 | EV_DOUT_STOPPED, | 
|  | 175 | EV_DOUT_COLL, | 
|  | 176 | EV_DOUT_UNDERRUN, | 
|  | 177 | }; | 
|  | 178 |  | 
|  | 179 | #define DOUT_EVENT_COUNT (EV_DOUT_UNDERRUN + 1) | 
|  | 180 |  | 
|  | 181 | // ---------------------------------------------------------------------- | 
|  | 182 |  | 
|  | 183 | enum { | 
|  | 184 | ST_L1_F3, | 
|  | 185 | ST_L1_F4, | 
|  | 186 | ST_L1_F6, | 
|  | 187 | ST_L1_F7, | 
|  | 188 | ST_L1_F8, | 
|  | 189 | }; | 
|  | 190 |  | 
|  | 191 | #define L1_STATE_COUNT (ST_L1_F8+1) | 
|  | 192 |  | 
|  | 193 | // The first 16 entries match the Level 1 indications that | 
|  | 194 | // are found at offset 4 (CCIST) in the interrupt packet | 
|  | 195 |  | 
|  | 196 | enum { | 
|  | 197 | EV_IND_DP,  // 0000 Deactivation Pending | 
|  | 198 | EV_IND_1,   // 0001 | 
|  | 199 | EV_IND_2,   // 0010 | 
|  | 200 | EV_IND_3,   // 0011 | 
|  | 201 | EV_IND_RSY, // 0100 ReSYnchronizing | 
|  | 202 | EV_IND_5,   // 0101 | 
|  | 203 | EV_IND_6,   // 0110 | 
|  | 204 | EV_IND_7,   // 0111 | 
|  | 205 | EV_IND_AP,  // 1000 Activation Pending | 
|  | 206 | EV_IND_9,   // 1001 | 
|  | 207 | EV_IND_10,  // 1010 | 
|  | 208 | EV_IND_11,  // 1011 | 
|  | 209 | EV_IND_AI8, // 1100 Activation Indication class 8 | 
|  | 210 | EV_IND_AI10,// 1101 Activation Indication class 10 | 
|  | 211 | EV_IND_AIL, // 1110 Activation Indication Loopback | 
|  | 212 | EV_IND_DI,  // 1111 Deactivation Indication | 
|  | 213 | EV_PH_ACTIVATE_REQ, | 
|  | 214 | EV_PH_DEACTIVATE_REQ, | 
|  | 215 | EV_TIMER3, | 
|  | 216 | }; | 
|  | 217 |  | 
|  | 218 | #define L1_EVENT_COUNT (EV_TIMER3 + 1) | 
|  | 219 |  | 
|  | 220 | #define ERR(format, arg...) \ | 
| Harvey Harrison | 156f1ed | 2008-04-28 02:14:40 -0700 | [diff] [blame] | 221 | printk(KERN_ERR "%s:%s: " format "\n" , __FILE__,  __func__ , ## arg) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 222 |  | 
| Arjan van de Ven | b6c6393 | 2008-07-25 01:45:52 -0700 | [diff] [blame] | 223 | #define WARNING(format, arg...) \ | 
| Harvey Harrison | 156f1ed | 2008-04-28 02:14:40 -0700 | [diff] [blame] | 224 | printk(KERN_WARNING "%s:%s: " format "\n" , __FILE__,  __func__ , ## arg) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 225 |  | 
|  | 226 | #define INFO(format, arg...) \ | 
| Harvey Harrison | 156f1ed | 2008-04-28 02:14:40 -0700 | [diff] [blame] | 227 | printk(KERN_INFO "%s:%s: " format "\n" , __FILE__,  __func__ , ## arg) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 228 |  | 
|  | 229 | #include "isdnhdlc.h" | 
|  | 230 | #include "fsm.h" | 
|  | 231 | #include "hisax_if.h" | 
|  | 232 | #include <linux/skbuff.h> | 
|  | 233 |  | 
|  | 234 | /* ====================================================================== | 
|  | 235 | * FIFO handling | 
|  | 236 | */ | 
|  | 237 |  | 
|  | 238 | /* Generic FIFO structure */ | 
|  | 239 | struct fifo { | 
|  | 240 | u_char r,w,count,size; | 
|  | 241 | spinlock_t lock; | 
|  | 242 | }; | 
|  | 243 |  | 
|  | 244 | /* | 
|  | 245 | * Init an FIFO | 
|  | 246 | */ | 
|  | 247 | static inline void fifo_init(struct fifo *fifo, int size) | 
|  | 248 | { | 
|  | 249 | fifo->r = fifo->w = fifo->count = 0; | 
|  | 250 | fifo->size = size; | 
|  | 251 | spin_lock_init(&fifo->lock); | 
|  | 252 | } | 
|  | 253 |  | 
|  | 254 | /* | 
|  | 255 | * Add an entry to the FIFO | 
|  | 256 | */ | 
|  | 257 | static inline int fifo_add(struct fifo *fifo) | 
|  | 258 | { | 
|  | 259 | unsigned long flags; | 
|  | 260 | int index; | 
|  | 261 |  | 
|  | 262 | if (!fifo) { | 
|  | 263 | return -1; | 
|  | 264 | } | 
|  | 265 |  | 
|  | 266 | spin_lock_irqsave(&fifo->lock, flags); | 
|  | 267 | if (fifo->count == fifo->size) { | 
|  | 268 | // FIFO full | 
|  | 269 | index = -1; | 
|  | 270 | } else { | 
|  | 271 | // Return index where to get the next data to add to the FIFO | 
|  | 272 | index = fifo->w++ & (fifo->size-1); | 
|  | 273 | fifo->count++; | 
|  | 274 | } | 
|  | 275 | spin_unlock_irqrestore(&fifo->lock, flags); | 
|  | 276 | return index; | 
|  | 277 | } | 
|  | 278 |  | 
|  | 279 | /* | 
|  | 280 | * Remove an entry from the FIFO with the index returned. | 
|  | 281 | */ | 
|  | 282 | static inline int fifo_remove(struct fifo *fifo) | 
|  | 283 | { | 
|  | 284 | unsigned long flags; | 
|  | 285 | int index; | 
|  | 286 |  | 
|  | 287 | if (!fifo) { | 
|  | 288 | return -1; | 
|  | 289 | } | 
|  | 290 |  | 
|  | 291 | spin_lock_irqsave(&fifo->lock, flags); | 
|  | 292 | if (!fifo->count) { | 
|  | 293 | // FIFO empty | 
|  | 294 | index = -1; | 
|  | 295 | } else { | 
|  | 296 | // Return index where to get the next data from the FIFO | 
|  | 297 | index = fifo->r++ & (fifo->size-1); | 
|  | 298 | fifo->count--; | 
|  | 299 | } | 
|  | 300 | spin_unlock_irqrestore(&fifo->lock, flags); | 
|  | 301 |  | 
|  | 302 | return index; | 
|  | 303 | } | 
|  | 304 |  | 
|  | 305 | /* ====================================================================== | 
|  | 306 | * control pipe | 
|  | 307 | */ | 
|  | 308 | typedef void (*ctrl_complete_t)(void *); | 
|  | 309 |  | 
|  | 310 | typedef struct ctrl_msg { | 
|  | 311 | struct usb_ctrlrequest dr; | 
|  | 312 | ctrl_complete_t complete; | 
|  | 313 | void *context; | 
|  | 314 | } ctrl_msg; | 
|  | 315 |  | 
|  | 316 | /* FIFO of ctrl messages waiting to be sent */ | 
|  | 317 | #define MAX_EP0_MSG 16 | 
|  | 318 | struct ctrl_msg_fifo { | 
|  | 319 | struct fifo f; | 
|  | 320 | struct ctrl_msg data[MAX_EP0_MSG]; | 
|  | 321 | }; | 
|  | 322 |  | 
|  | 323 | #define MAX_DFRAME_LEN_L1	300 | 
|  | 324 | #define HSCX_BUFMAX	4096 | 
|  | 325 |  | 
|  | 326 | struct st5481_ctrl { | 
|  | 327 | struct ctrl_msg_fifo msg_fifo; | 
|  | 328 | unsigned long busy; | 
|  | 329 | struct urb *urb; | 
|  | 330 | }; | 
|  | 331 |  | 
|  | 332 | struct st5481_intr { | 
|  | 333 | //	struct evt_fifo evt_fifo; | 
|  | 334 | struct urb *urb; | 
|  | 335 | }; | 
|  | 336 |  | 
|  | 337 | struct st5481_d_out { | 
|  | 338 | struct isdnhdlc_vars hdlc_state; | 
|  | 339 | struct urb *urb[2]; /* double buffering */ | 
|  | 340 | unsigned long busy; | 
|  | 341 | struct sk_buff *tx_skb; | 
|  | 342 | struct FsmInst fsm; | 
|  | 343 | }; | 
|  | 344 |  | 
|  | 345 | struct st5481_b_out { | 
|  | 346 | struct isdnhdlc_vars hdlc_state; | 
|  | 347 | struct urb *urb[2]; /* double buffering */ | 
|  | 348 | u_char flow_event; | 
|  | 349 | u_long busy; | 
|  | 350 | struct sk_buff *tx_skb; | 
|  | 351 | }; | 
|  | 352 |  | 
|  | 353 | struct st5481_in { | 
|  | 354 | struct isdnhdlc_vars hdlc_state; | 
|  | 355 | struct urb *urb[2]; /* double buffering */ | 
|  | 356 | int mode; | 
|  | 357 | int bufsize; | 
|  | 358 | unsigned int num_packets; | 
|  | 359 | unsigned int packet_size; | 
|  | 360 | unsigned char ep, counter; | 
|  | 361 | unsigned char *rcvbuf; | 
|  | 362 | struct st5481_adapter *adapter; | 
|  | 363 | struct hisax_if *hisax_if; | 
|  | 364 | }; | 
|  | 365 |  | 
|  | 366 | int st5481_setup_in(struct st5481_in *in); | 
|  | 367 | void st5481_release_in(struct st5481_in *in); | 
|  | 368 | void st5481_in_mode(struct st5481_in *in, int mode); | 
|  | 369 |  | 
|  | 370 | struct st5481_bcs { | 
|  | 371 | struct hisax_b_if b_if; | 
|  | 372 | struct st5481_adapter *adapter; | 
|  | 373 | struct st5481_in b_in; | 
|  | 374 | struct st5481_b_out b_out; | 
|  | 375 | int channel; | 
|  | 376 | int mode; | 
|  | 377 | }; | 
|  | 378 |  | 
|  | 379 | struct st5481_adapter { | 
|  | 380 | struct list_head list; | 
|  | 381 | int number_of_leds; | 
|  | 382 | struct usb_device *usb_dev; | 
|  | 383 | struct hisax_d_if hisax_d_if; | 
|  | 384 |  | 
|  | 385 | struct st5481_ctrl ctrl; | 
|  | 386 | struct st5481_intr intr; | 
|  | 387 | struct st5481_in d_in; | 
|  | 388 | struct st5481_d_out d_out; | 
|  | 389 |  | 
|  | 390 | unsigned char leds; | 
|  | 391 | unsigned int led_counter; | 
|  | 392 |  | 
|  | 393 | unsigned long event; | 
|  | 394 |  | 
|  | 395 | struct FsmInst l1m; | 
|  | 396 | struct FsmTimer timer; | 
|  | 397 |  | 
|  | 398 | struct st5481_bcs bcs[2]; | 
|  | 399 | }; | 
|  | 400 |  | 
|  | 401 | #define TIMER3_VALUE 7000 | 
|  | 402 |  | 
|  | 403 | /* ====================================================================== | 
|  | 404 | * | 
|  | 405 | */ | 
|  | 406 |  | 
|  | 407 | /* | 
|  | 408 | * Submit an URB with error reporting. This is a macro so | 
| Harvey Harrison | 156f1ed | 2008-04-28 02:14:40 -0700 | [diff] [blame] | 409 | * the __func__ returns the caller function name. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 410 | */ | 
|  | 411 | #define SUBMIT_URB(urb, mem_flags) \ | 
|  | 412 | ({ \ | 
|  | 413 | int status; \ | 
|  | 414 | if ((status = usb_submit_urb(urb, mem_flags)) < 0) { \ | 
| Arjan van de Ven | b6c6393 | 2008-07-25 01:45:52 -0700 | [diff] [blame] | 415 | WARNING("usb_submit_urb failed,status=%d", status); \ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 416 | } \ | 
|  | 417 | status; \ | 
|  | 418 | }) | 
|  | 419 |  | 
|  | 420 | /* | 
|  | 421 | * USB double buffering, return the URB index (0 or 1). | 
|  | 422 | */ | 
|  | 423 | static inline int get_buf_nr(struct urb *urbs[], struct urb *urb) | 
|  | 424 | { | 
|  | 425 | return (urbs[0]==urb ? 0 : 1); | 
|  | 426 | } | 
|  | 427 |  | 
|  | 428 | /* ---------------------------------------------------------------------- */ | 
|  | 429 |  | 
|  | 430 | /* B Channel */ | 
|  | 431 |  | 
|  | 432 | int  st5481_setup_b(struct st5481_bcs *bcs); | 
|  | 433 | void st5481_release_b(struct st5481_bcs *bcs); | 
|  | 434 | void st5481_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg); | 
|  | 435 |  | 
|  | 436 | /* D Channel */ | 
|  | 437 |  | 
|  | 438 | int  st5481_setup_d(struct st5481_adapter *adapter); | 
|  | 439 | void st5481_release_d(struct st5481_adapter *adapter); | 
|  | 440 | void st5481_b_l2l1(struct hisax_if *b_if, int pr, void *arg); | 
|  | 441 | int  st5481_d_init(void); | 
|  | 442 | void st5481_d_exit(void); | 
|  | 443 |  | 
|  | 444 | /* USB */ | 
|  | 445 | void st5481_ph_command(struct st5481_adapter *adapter, unsigned int command); | 
|  | 446 | int st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev, | 
|  | 447 | unsigned int pipe, int num_packets, | 
|  | 448 | int packet_size, int buf_size, | 
|  | 449 | usb_complete_t complete, void *context); | 
|  | 450 | void st5481_release_isocpipes(struct urb* urb[2]); | 
|  | 451 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 452 | void st5481_usb_pipe_reset(struct st5481_adapter *adapter, | 
|  | 453 | u_char pipe, ctrl_complete_t complete, void *context); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 454 | void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter, | 
|  | 455 | u8 request, u16 value, | 
|  | 456 | ctrl_complete_t complete, void *context); | 
|  | 457 | int  st5481_setup_usb(struct st5481_adapter *adapter); | 
|  | 458 | void st5481_release_usb(struct st5481_adapter *adapter); | 
|  | 459 | void st5481_start(struct st5481_adapter *adapter); | 
|  | 460 | void st5481_stop(struct st5481_adapter *adapter); | 
|  | 461 |  | 
|  | 462 | // ---------------------------------------------------------------------- | 
|  | 463 | // debugging macros | 
|  | 464 |  | 
|  | 465 | #define __debug_variable st5481_debug | 
|  | 466 | #include "hisax_debug.h" | 
|  | 467 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 468 | extern int st5481_debug; | 
|  | 469 |  | 
| Karsten Keil | 61ffcaf | 2005-09-17 23:52:42 +0200 | [diff] [blame] | 470 | #ifdef CONFIG_HISAX_DEBUG | 
|  | 471 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 472 | #define DBG_ISO_PACKET(level,urb) \ | 
| Harvey Harrison | 156f1ed | 2008-04-28 02:14:40 -0700 | [diff] [blame] | 473 | if (level & __debug_variable) dump_iso_packet(__func__,urb) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 474 |  | 
|  | 475 | static void __attribute__((unused)) | 
|  | 476 | dump_iso_packet(const char *name, struct urb *urb) | 
|  | 477 | { | 
|  | 478 | int i,j; | 
|  | 479 | int len,ofs; | 
|  | 480 | u_char *data; | 
|  | 481 |  | 
|  | 482 | printk(KERN_DEBUG "%s: packets=%d,errors=%d\n", | 
|  | 483 | name,urb->number_of_packets,urb->error_count); | 
|  | 484 | for (i = 0; i  < urb->number_of_packets; ++i) { | 
|  | 485 | if (urb->pipe & USB_DIR_IN) { | 
|  | 486 | len = urb->iso_frame_desc[i].actual_length; | 
|  | 487 | } else { | 
|  | 488 | len = urb->iso_frame_desc[i].length; | 
|  | 489 | } | 
|  | 490 | ofs = urb->iso_frame_desc[i].offset; | 
|  | 491 | printk(KERN_DEBUG "len=%.2d,ofs=%.3d ",len,ofs); | 
|  | 492 | if (len) { | 
|  | 493 | data = urb->transfer_buffer+ofs; | 
|  | 494 | for (j=0; j < len; j++) { | 
|  | 495 | printk ("%.2x", data[j]); | 
|  | 496 | } | 
|  | 497 | } | 
|  | 498 | printk("\n"); | 
|  | 499 | } | 
|  | 500 | } | 
|  | 501 |  | 
|  | 502 | static inline const char *ST5481_CMD_string(int evt) | 
|  | 503 | { | 
|  | 504 | static char s[16]; | 
|  | 505 |  | 
|  | 506 | switch (evt) { | 
|  | 507 | case ST5481_CMD_DR: return "DR"; | 
|  | 508 | case ST5481_CMD_RES: return "RES"; | 
|  | 509 | case ST5481_CMD_TM1: return "TM1"; | 
|  | 510 | case ST5481_CMD_TM2: return "TM2"; | 
|  | 511 | case ST5481_CMD_PUP: return "PUP"; | 
|  | 512 | case ST5481_CMD_AR8: return "AR8"; | 
|  | 513 | case ST5481_CMD_AR10: return "AR10"; | 
|  | 514 | case ST5481_CMD_ARL: return "ARL"; | 
|  | 515 | case ST5481_CMD_PDN: return "PDN"; | 
|  | 516 | }; | 
|  | 517 |  | 
|  | 518 | sprintf(s,"0x%x",evt); | 
|  | 519 | return s; | 
|  | 520 | } | 
|  | 521 |  | 
|  | 522 | #else | 
|  | 523 |  | 
|  | 524 | #define DBG_ISO_PACKET(level,urb) do {} while (0) | 
|  | 525 |  | 
|  | 526 | #endif | 
|  | 527 |  | 
|  | 528 |  | 
|  | 529 |  | 
|  | 530 | #endif |