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#include <linux/init.h> 14#include <linux/gfp.h> 15#include <linux/usb.h> 16#include <linux/netdevice.h> 17#include "st5481.h" 18 19static void ph_connect(struct st5481_adapter *adapter); 20static void ph_disconnect(struct st5481_adapter *adapter); 21 22static struct Fsm l1fsm; 23 24static char *strL1State[] = 25{ 26 "ST_L1_F3", 27 "ST_L1_F4", 28 "ST_L1_F6", 29 "ST_L1_F7", 30 "ST_L1_F8", 31}; 32 33static char *strL1Event[] = 34{ 35 "EV_IND_DP", 36 "EV_IND_1", 37 "EV_IND_2", 38 "EV_IND_3", 39 "EV_IND_RSY", 40 "EV_IND_5", 41 "EV_IND_6", 42 "EV_IND_7", 43 "EV_IND_AP", 44 "EV_IND_9", 45 "EV_IND_10", 46 "EV_IND_11", 47 "EV_IND_AI8", 48 "EV_IND_AI10", 49 "EV_IND_AIL", 50 "EV_IND_DI", 51 "EV_PH_ACTIVATE_REQ", 52 "EV_PH_DEACTIVATE_REQ", 53 "EV_TIMER3", 54}; 55 56static inline void D_L1L2(struct st5481_adapter *adapter, int pr, void *arg) 57{ 58 struct hisax_if *ifc = (struct hisax_if *) &adapter->hisax_d_if; 59 60 ifc->l1l2(ifc, pr, arg); 61} 62 63static void 64l1_go_f3(struct FsmInst *fi, int event, void *arg) 65{ 66 struct st5481_adapter *adapter = fi->userdata; 67 68 if (fi->state == ST_L1_F7) 69 ph_disconnect(adapter); 70 71 FsmChangeState(fi, ST_L1_F3); 72 D_L1L2(adapter, PH_DEACTIVATE | INDICATION, NULL); 73} 74 75static void 76l1_go_f6(struct FsmInst *fi, int event, void *arg) 77{ 78 struct st5481_adapter *adapter = fi->userdata; 79 80 if (fi->state == ST_L1_F7) 81 ph_disconnect(adapter); 82 83 FsmChangeState(fi, ST_L1_F6); 84} 85 86static void 87l1_go_f7(struct FsmInst *fi, int event, void *arg) 88{ 89 struct st5481_adapter *adapter = fi->userdata; 90 91 FsmDelTimer(&adapter->timer, 0); 92 ph_connect(adapter); 93 FsmChangeState(fi, ST_L1_F7); 94 D_L1L2(adapter, PH_ACTIVATE | INDICATION, NULL); 95} 96 97static void 98l1_go_f8(struct FsmInst *fi, int event, void *arg) 99{ 100 struct st5481_adapter *adapter = fi->userdata; 101 102 if (fi->state == ST_L1_F7) 103 ph_disconnect(adapter); 104 105 FsmChangeState(fi, ST_L1_F8); 106} 107 108static void 109l1_timer3(struct FsmInst *fi, int event, void *arg) 110{ 111 struct st5481_adapter *adapter = fi->userdata; 112 113 st5481_ph_command(adapter, ST5481_CMD_DR); 114 FsmChangeState(fi, ST_L1_F3); 115 D_L1L2(adapter, PH_DEACTIVATE | INDICATION, NULL); 116} 117 118static void 119l1_ignore(struct FsmInst *fi, int event, void *arg) 120{ 121} 122 123static void 124l1_activate(struct FsmInst *fi, int event, void *arg) 125{ 126 struct st5481_adapter *adapter = fi->userdata; 127 128 st5481_ph_command(adapter, ST5481_CMD_DR); 129 st5481_ph_command(adapter, ST5481_CMD_PUP); 130 FsmRestartTimer(&adapter->timer, TIMER3_VALUE, EV_TIMER3, NULL, 2); 131 st5481_ph_command(adapter, ST5481_CMD_AR8); 132 FsmChangeState(fi, ST_L1_F4); 133} 134 135static struct FsmNode L1FnList[] __initdata = 136{ 137 {ST_L1_F3, EV_IND_DP, l1_ignore}, 138 {ST_L1_F3, EV_IND_AP, l1_go_f6}, 139 {ST_L1_F3, EV_IND_AI8, l1_go_f7}, 140 {ST_L1_F3, EV_IND_AI10, l1_go_f7}, 141 {ST_L1_F3, EV_PH_ACTIVATE_REQ, l1_activate}, 142 143 {ST_L1_F4, EV_TIMER3, l1_timer3}, 144 {ST_L1_F4, EV_IND_DP, l1_go_f3}, 145 {ST_L1_F4, EV_IND_AP, l1_go_f6}, 146 {ST_L1_F4, EV_IND_AI8, l1_go_f7}, 147 {ST_L1_F4, EV_IND_AI10, l1_go_f7}, 148 149 {ST_L1_F6, EV_TIMER3, l1_timer3}, 150 {ST_L1_F6, EV_IND_DP, l1_go_f3}, 151 {ST_L1_F6, EV_IND_AP, l1_ignore}, 152 {ST_L1_F6, EV_IND_AI8, l1_go_f7}, 153 {ST_L1_F6, EV_IND_AI10, l1_go_f7}, 154 {ST_L1_F7, EV_IND_RSY, l1_go_f8}, 155 156 {ST_L1_F7, EV_IND_DP, l1_go_f3}, 157 {ST_L1_F7, EV_IND_AP, l1_go_f6}, 158 {ST_L1_F7, EV_IND_AI8, l1_ignore}, 159 {ST_L1_F7, EV_IND_AI10, l1_ignore}, 160 {ST_L1_F7, EV_IND_RSY, l1_go_f8}, 161 162 {ST_L1_F8, EV_TIMER3, l1_timer3}, 163 {ST_L1_F8, EV_IND_DP, l1_go_f3}, 164 {ST_L1_F8, EV_IND_AP, l1_go_f6}, 165 {ST_L1_F8, EV_IND_AI8, l1_go_f8}, 166 {ST_L1_F8, EV_IND_AI10, l1_go_f8}, 167 {ST_L1_F8, EV_IND_RSY, l1_ignore}, 168}; 169 170static __printf(2, 3) 171 void l1m_debug(struct FsmInst *fi, char *fmt, ...) 172{ 173 va_list args; 174 char buf[256]; 175 176 va_start(args, fmt); 177 vsnprintf(buf, sizeof(buf), fmt, args); 178 DBG(8, "%s", buf); 179 va_end(args); 180} 181 182/* ====================================================================== 183 * D-Channel out 184 */ 185 186/* 187 D OUT state machine: 188 ==================== 189 190 Transmit short frame (< 16 bytes of encoded data): 191 192 L1 FRAME D_OUT_STATE USB D CHANNEL 193 -------- ----------- --- --------- 194 195 FIXME 196 197 -> [xx..xx] SHORT_INIT -> [7Exx..xxC1C27EFF] 198 SHORT_WAIT_DEN <> OUT_D_COUNTER=16 199 200 END_OF_SHORT <- DEN_EVENT -> 7Exx 201 xxxx 202 xxxx 203 xxxx 204 xxxx 205 xxxx 206 C1C1 207 7EFF 208 WAIT_FOR_RESET_IDLE <- D_UNDERRUN <- (8ms) 209 IDLE <> Reset pipe 210 211 212 213 Transmit long frame (>= 16 bytes of encoded data): 214 215 L1 FRAME D_OUT_STATE USB D CHANNEL 216 -------- ----------- --- --------- 217 218 -> [xx...xx] IDLE 219 WAIT_FOR_STOP <> OUT_D_COUNTER=0 220 WAIT_FOR_RESET <> Reset pipe 221 STOP 222 INIT_LONG_FRAME -> [7Exx..xx] 223 WAIT_DEN <> OUT_D_COUNTER=16 224 OUT_NORMAL <- DEN_EVENT -> 7Exx 225 END_OF_FRAME_BUSY -> [xxxx] xxxx 226 END_OF_FRAME_NOT_BUSY -> [xxxx] xxxx 227 -> [xxxx] xxxx 228 -> [C1C2] xxxx 229 -> [7EFF] xxxx 230 xxxx 231 xxxx 232 .... 233 xxxx 234 C1C2 235 7EFF 236 <- D_UNDERRUN <- (> 8ms) 237 WAIT_FOR_STOP <> OUT_D_COUNTER=0 238 WAIT_FOR_RESET <> Reset pipe 239 STOP 240 241*/ 242 243static struct Fsm dout_fsm; 244 245static char *strDoutState[] = 246{ 247 "ST_DOUT_NONE", 248 249 "ST_DOUT_SHORT_INIT", 250 "ST_DOUT_SHORT_WAIT_DEN", 251 252 "ST_DOUT_LONG_INIT", 253 "ST_DOUT_LONG_WAIT_DEN", 254 "ST_DOUT_NORMAL", 255 256 "ST_DOUT_WAIT_FOR_UNDERRUN", 257 "ST_DOUT_WAIT_FOR_NOT_BUSY", 258 "ST_DOUT_WAIT_FOR_STOP", 259 "ST_DOUT_WAIT_FOR_RESET", 260}; 261 262static char *strDoutEvent[] = 263{ 264 "EV_DOUT_START_XMIT", 265 "EV_DOUT_COMPLETE", 266 "EV_DOUT_DEN", 267 "EV_DOUT_RESETED", 268 "EV_DOUT_STOPPED", 269 "EV_DOUT_COLL", 270 "EV_DOUT_UNDERRUN", 271}; 272 273static __printf(2, 3) 274 void dout_debug(struct FsmInst *fi, char *fmt, ...) 275{ 276 va_list args; 277 char buf[256]; 278 279 va_start(args, fmt); 280 vsnprintf(buf, sizeof(buf), fmt, args); 281 DBG(0x2, "%s", buf); 282 va_end(args); 283} 284 285static void dout_stop_event(void *context) 286{ 287 struct st5481_adapter *adapter = context; 288 289 FsmEvent(&adapter->d_out.fsm, EV_DOUT_STOPPED, NULL); 290} 291 292/* 293 * Start the transfer of a D channel frame. 294 */ 295static void usb_d_out(struct st5481_adapter *adapter, int buf_nr) 296{ 297 struct st5481_d_out *d_out = &adapter->d_out; 298 struct urb *urb; 299 unsigned int num_packets, packet_offset; 300 int len, buf_size, bytes_sent; 301 struct sk_buff *skb; 302 struct usb_iso_packet_descriptor *desc; 303 304 if (d_out->fsm.state != ST_DOUT_NORMAL) 305 return; 306 307 if (test_and_set_bit(buf_nr, &d_out->busy)) { 308 DBG(2, "ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy); 309 return; 310 } 311 urb = d_out->urb[buf_nr]; 312 313 skb = d_out->tx_skb; 314 315 buf_size = NUM_ISO_PACKETS_D * SIZE_ISO_PACKETS_D_OUT; 316 317 if (skb) { 318 len = isdnhdlc_encode(&d_out->hdlc_state, 319 skb->data, skb->len, &bytes_sent, 320 urb->transfer_buffer, buf_size); 321 skb_pull(skb, bytes_sent); 322 } else { 323 // Send flags or idle 324 len = isdnhdlc_encode(&d_out->hdlc_state, 325 NULL, 0, &bytes_sent, 326 urb->transfer_buffer, buf_size); 327 } 328 329 if (len < buf_size) { 330 FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_UNDERRUN); 331 } 332 if (skb && !skb->len) { 333 d_out->tx_skb = NULL; 334 D_L1L2(adapter, PH_DATA | CONFIRM, NULL); 335 dev_kfree_skb_any(skb); 336 } 337 338 // Prepare the URB 339 urb->transfer_buffer_length = len; 340 num_packets = 0; 341 packet_offset = 0; 342 while (packet_offset < len) { 343 desc = &urb->iso_frame_desc[num_packets]; 344 desc->offset = packet_offset; 345 desc->length = SIZE_ISO_PACKETS_D_OUT; 346 if (len - packet_offset < desc->length) 347 desc->length = len - packet_offset; 348 num_packets++; 349 packet_offset += desc->length; 350 } 351 urb->number_of_packets = num_packets; 352 353 // Prepare the URB 354 urb->dev = adapter->usb_dev; 355 // Need to transmit the next buffer 2ms after the DEN_EVENT 356 urb->transfer_flags = 0; 357 urb->start_frame = usb_get_current_frame_number(adapter->usb_dev) + 2; 358 359 DBG_ISO_PACKET(0x20, urb); 360 361 if (usb_submit_urb(urb, GFP_KERNEL) < 0) { 362 // There is another URB queued up 363 urb->transfer_flags = URB_ISO_ASAP; 364 SUBMIT_URB(urb, GFP_KERNEL); 365 } 366} 367 368static void fifo_reseted(void *context) 369{ 370 struct st5481_adapter *adapter = context; 371 372 FsmEvent(&adapter->d_out.fsm, EV_DOUT_RESETED, NULL); 373} 374 375static void usb_d_out_complete(struct urb *urb) 376{ 377 struct st5481_adapter *adapter = urb->context; 378 struct st5481_d_out *d_out = &adapter->d_out; 379 long buf_nr; 380 381 DBG(2, ""); 382 383 buf_nr = get_buf_nr(d_out->urb, urb); 384 test_and_clear_bit(buf_nr, &d_out->busy); 385 386 if (unlikely(urb->status < 0)) { 387 switch (urb->status) { 388 case -ENOENT: 389 case -ESHUTDOWN: 390 case -ECONNRESET: 391 DBG(1, "urb killed status %d", urb->status); 392 break; 393 default: 394 WARNING("urb status %d", urb->status); 395 if (d_out->busy == 0) { 396 st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter); 397 } 398 break; 399 } 400 return; // Give up 401 } 402 403 FsmEvent(&adapter->d_out.fsm, EV_DOUT_COMPLETE, (void *) buf_nr); 404} 405 406/* ====================================================================== */ 407 408static void dout_start_xmit(struct FsmInst *fsm, int event, void *arg) 409{ 410 // FIXME unify? 411 struct st5481_adapter *adapter = fsm->userdata; 412 struct st5481_d_out *d_out = &adapter->d_out; 413 struct urb *urb; 414 int len, bytes_sent; 415 struct sk_buff *skb; 416 int buf_nr = 0; 417 418 skb = d_out->tx_skb; 419 420 DBG(2, "len=%d", skb->len); 421 422 isdnhdlc_out_init(&d_out->hdlc_state, HDLC_DCHANNEL | HDLC_BITREVERSE); 423 424 if (test_and_set_bit(buf_nr, &d_out->busy)) { 425 WARNING("ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy); 426 return; 427 } 428 urb = d_out->urb[buf_nr]; 429 430 DBG_SKB(0x10, skb); 431 len = isdnhdlc_encode(&d_out->hdlc_state, 432 skb->data, skb->len, &bytes_sent, 433 urb->transfer_buffer, 16); 434 skb_pull(skb, bytes_sent); 435 436 if (len < 16) 437 FsmChangeState(&d_out->fsm, ST_DOUT_SHORT_INIT); 438 else 439 FsmChangeState(&d_out->fsm, ST_DOUT_LONG_INIT); 440 441 if (skb->len == 0) { 442 d_out->tx_skb = NULL; 443 D_L1L2(adapter, PH_DATA | CONFIRM, NULL); 444 dev_kfree_skb_any(skb); 445 } 446 447// Prepare the URB 448 urb->transfer_buffer_length = len; 449 450 urb->iso_frame_desc[0].offset = 0; 451 urb->iso_frame_desc[0].length = len; 452 urb->number_of_packets = 1; 453 454 // Prepare the URB 455 urb->dev = adapter->usb_dev; 456 urb->transfer_flags = URB_ISO_ASAP; 457 458 DBG_ISO_PACKET(0x20, urb); 459 SUBMIT_URB(urb, GFP_KERNEL); 460} 461 462static void dout_short_fifo(struct FsmInst *fsm, int event, void *arg) 463{ 464 struct st5481_adapter *adapter = fsm->userdata; 465 struct st5481_d_out *d_out = &adapter->d_out; 466 467 FsmChangeState(&d_out->fsm, ST_DOUT_SHORT_WAIT_DEN); 468 st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 16, NULL, NULL); 469} 470 471static void dout_end_short_frame(struct FsmInst *fsm, int event, void *arg) 472{ 473 struct st5481_adapter *adapter = fsm->userdata; 474 struct st5481_d_out *d_out = &adapter->d_out; 475 476 FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_UNDERRUN); 477} 478 479static void dout_long_enable_fifo(struct FsmInst *fsm, int event, void *arg) 480{ 481 struct st5481_adapter *adapter = fsm->userdata; 482 struct st5481_d_out *d_out = &adapter->d_out; 483 484 st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 16, NULL, NULL); 485 FsmChangeState(&d_out->fsm, ST_DOUT_LONG_WAIT_DEN); 486} 487 488static void dout_long_den(struct FsmInst *fsm, int event, void *arg) 489{ 490 struct st5481_adapter *adapter = fsm->userdata; 491 struct st5481_d_out *d_out = &adapter->d_out; 492 493 FsmChangeState(&d_out->fsm, ST_DOUT_NORMAL); 494 usb_d_out(adapter, 0); 495 usb_d_out(adapter, 1); 496} 497 498static void dout_reset(struct FsmInst *fsm, int event, void *arg) 499{ 500 struct st5481_adapter *adapter = fsm->userdata; 501 struct st5481_d_out *d_out = &adapter->d_out; 502 503 FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_RESET); 504 st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter); 505} 506 507static void dout_stop(struct FsmInst *fsm, int event, void *arg) 508{ 509 struct st5481_adapter *adapter = fsm->userdata; 510 struct st5481_d_out *d_out = &adapter->d_out; 511 512 FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_STOP); 513 st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 0, dout_stop_event, adapter); 514} 515 516static void dout_underrun(struct FsmInst *fsm, int event, void *arg) 517{ 518 struct st5481_adapter *adapter = fsm->userdata; 519 struct st5481_d_out *d_out = &adapter->d_out; 520 521 if (test_bit(0, &d_out->busy) || test_bit(1, &d_out->busy)) { 522 FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_NOT_BUSY); 523 } else { 524 dout_stop(fsm, event, arg); 525 } 526} 527 528static void dout_check_busy(struct FsmInst *fsm, int event, void *arg) 529{ 530 struct st5481_adapter *adapter = fsm->userdata; 531 struct st5481_d_out *d_out = &adapter->d_out; 532 533 if (!test_bit(0, &d_out->busy) && !test_bit(1, &d_out->busy)) 534 dout_stop(fsm, event, arg); 535} 536 537static void dout_reseted(struct FsmInst *fsm, int event, void *arg) 538{ 539 struct st5481_adapter *adapter = fsm->userdata; 540 struct st5481_d_out *d_out = &adapter->d_out; 541 542 FsmChangeState(&d_out->fsm, ST_DOUT_NONE); 543 // FIXME locking 544 if (d_out->tx_skb) 545 FsmEvent(&d_out->fsm, EV_DOUT_START_XMIT, NULL); 546} 547 548static void dout_complete(struct FsmInst *fsm, int event, void *arg) 549{ 550 struct st5481_adapter *adapter = fsm->userdata; 551 long buf_nr = (long) arg; 552 553 usb_d_out(adapter, buf_nr); 554} 555 556static void dout_ignore(struct FsmInst *fsm, int event, void *arg) 557{ 558} 559 560static struct FsmNode DoutFnList[] __initdata = 561{ 562 {ST_DOUT_NONE, EV_DOUT_START_XMIT, dout_start_xmit}, 563 564 {ST_DOUT_SHORT_INIT, EV_DOUT_COMPLETE, dout_short_fifo}, 565 566 {ST_DOUT_SHORT_WAIT_DEN, EV_DOUT_DEN, dout_end_short_frame}, 567 {ST_DOUT_SHORT_WAIT_DEN, EV_DOUT_UNDERRUN, dout_underrun}, 568 569 {ST_DOUT_LONG_INIT, EV_DOUT_COMPLETE, dout_long_enable_fifo}, 570 571 {ST_DOUT_LONG_WAIT_DEN, EV_DOUT_DEN, dout_long_den}, 572 {ST_DOUT_LONG_WAIT_DEN, EV_DOUT_UNDERRUN, dout_underrun}, 573 574 {ST_DOUT_NORMAL, EV_DOUT_UNDERRUN, dout_underrun}, 575 {ST_DOUT_NORMAL, EV_DOUT_COMPLETE, dout_complete}, 576 577 {ST_DOUT_WAIT_FOR_UNDERRUN, EV_DOUT_UNDERRUN, dout_underrun}, 578 {ST_DOUT_WAIT_FOR_UNDERRUN, EV_DOUT_COMPLETE, dout_ignore}, 579 580 {ST_DOUT_WAIT_FOR_NOT_BUSY, EV_DOUT_COMPLETE, dout_check_busy}, 581 582 {ST_DOUT_WAIT_FOR_STOP, EV_DOUT_STOPPED, dout_reset}, 583 584 {ST_DOUT_WAIT_FOR_RESET, EV_DOUT_RESETED, dout_reseted}, 585}; 586 587void st5481_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg) 588{ 589 struct st5481_adapter *adapter = hisax_d_if->priv; 590 struct sk_buff *skb = arg; 591 592 switch (pr) { 593 case PH_ACTIVATE | REQUEST: 594 FsmEvent(&adapter->l1m, EV_PH_ACTIVATE_REQ, NULL); 595 break; 596 case PH_DEACTIVATE | REQUEST: 597 FsmEvent(&adapter->l1m, EV_PH_DEACTIVATE_REQ, NULL); 598 break; 599 case PH_DATA | REQUEST: 600 DBG(2, "PH_DATA REQUEST len %d", skb->len); 601 BUG_ON(adapter->d_out.tx_skb); 602 adapter->d_out.tx_skb = skb; 603 FsmEvent(&adapter->d_out.fsm, EV_DOUT_START_XMIT, NULL); 604 break; 605 default: 606 WARNING("pr %#x\n", pr); 607 break; 608 } 609} 610 611/* ====================================================================== 612 */ 613 614/* 615 * Start receiving on the D channel since entered state F7. 616 */ 617static void ph_connect(struct st5481_adapter *adapter) 618{ 619 struct st5481_d_out *d_out = &adapter->d_out; 620 struct st5481_in *d_in = &adapter->d_in; 621 622 DBG(8, ""); 623 624 FsmChangeState(&d_out->fsm, ST_DOUT_NONE); 625 626 // st5481_usb_device_ctrl_msg(adapter, FFMSK_D, OUT_UNDERRUN, NULL, NULL); 627 st5481_usb_device_ctrl_msg(adapter, FFMSK_D, 0xfc, NULL, NULL); 628 st5481_in_mode(d_in, L1_MODE_HDLC); 629 630#ifdef LOOPBACK 631 // Turn loopback on (data sent on B and D looped back) 632 st5481_usb_device_ctrl_msg(cs, LBB, 0x04, NULL, NULL); 633#endif 634 635 st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, NULL, NULL); 636 637 // Turn on the green LED to tell that we are in state F7 638 adapter->leds |= GREEN_LED; 639 st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL); 640} 641 642/* 643 * Stop receiving on the D channel since not in state F7. 644 */ 645static void ph_disconnect(struct st5481_adapter *adapter) 646{ 647 DBG(8, ""); 648 649 st5481_in_mode(&adapter->d_in, L1_MODE_NULL); 650 651 // Turn off the green LED to tell that we left state F7 652 adapter->leds &= ~GREEN_LED; 653 st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL); 654} 655 656static int st5481_setup_d_out(struct st5481_adapter *adapter) 657{ 658 struct usb_device *dev = adapter->usb_dev; 659 struct usb_interface *intf; 660 struct usb_host_interface *altsetting = NULL; 661 struct usb_host_endpoint *endpoint; 662 struct st5481_d_out *d_out = &adapter->d_out; 663 664 DBG(2, ""); 665 666 intf = usb_ifnum_to_if(dev, 0); 667 if (intf) 668 altsetting = usb_altnum_to_altsetting(intf, 3); 669 if (!altsetting) 670 return -ENXIO; 671 672 // Allocate URBs and buffers for the D channel out 673 endpoint = &altsetting->endpoint[EP_D_OUT-1]; 674 675 DBG(2, "endpoint address=%02x,packet size=%d", 676 endpoint->desc.bEndpointAddress, le16_to_cpu(endpoint->desc.wMaxPacketSize)); 677 678 return st5481_setup_isocpipes(d_out->urb, dev, 679 usb_sndisocpipe(dev, endpoint->desc.bEndpointAddress), 680 NUM_ISO_PACKETS_D, SIZE_ISO_PACKETS_D_OUT, 681 NUM_ISO_PACKETS_D * SIZE_ISO_PACKETS_D_OUT, 682 usb_d_out_complete, adapter); 683} 684 685static void st5481_release_d_out(struct st5481_adapter *adapter) 686{ 687 struct st5481_d_out *d_out = &adapter->d_out; 688 689 DBG(2, ""); 690 691 st5481_release_isocpipes(d_out->urb); 692} 693 694int st5481_setup_d(struct st5481_adapter *adapter) 695{ 696 int retval; 697 698 DBG(2, ""); 699 700 retval = st5481_setup_d_out(adapter); 701 if (retval) 702 goto err; 703 adapter->d_in.bufsize = MAX_DFRAME_LEN_L1; 704 adapter->d_in.num_packets = NUM_ISO_PACKETS_D; 705 adapter->d_in.packet_size = SIZE_ISO_PACKETS_D_IN; 706 adapter->d_in.ep = EP_D_IN | USB_DIR_IN; 707 adapter->d_in.counter = IN_D_COUNTER; 708 adapter->d_in.adapter = adapter; 709 adapter->d_in.hisax_if = &adapter->hisax_d_if.ifc; 710 retval = st5481_setup_in(&adapter->d_in); 711 if (retval) 712 goto err_d_out; 713 714 adapter->l1m.fsm = &l1fsm; 715 adapter->l1m.state = ST_L1_F3; 716 adapter->l1m.debug = st5481_debug & 0x100; 717 adapter->l1m.userdata = adapter; 718 adapter->l1m.printdebug = l1m_debug; 719 FsmInitTimer(&adapter->l1m, &adapter->timer); 720 721 adapter->d_out.fsm.fsm = &dout_fsm; 722 adapter->d_out.fsm.state = ST_DOUT_NONE; 723 adapter->d_out.fsm.debug = st5481_debug & 0x100; 724 adapter->d_out.fsm.userdata = adapter; 725 adapter->d_out.fsm.printdebug = dout_debug; 726 727 return 0; 728 729err_d_out: 730 st5481_release_d_out(adapter); 731err: 732 return retval; 733} 734 735void st5481_release_d(struct st5481_adapter *adapter) 736{ 737 DBG(2, ""); 738 739 st5481_release_in(&adapter->d_in); 740 st5481_release_d_out(adapter); 741} 742 743/* ====================================================================== 744 * init / exit 745 */ 746 747int __init st5481_d_init(void) 748{ 749 int retval; 750 751 l1fsm.state_count = L1_STATE_COUNT; 752 l1fsm.event_count = L1_EVENT_COUNT; 753 l1fsm.strEvent = strL1Event; 754 l1fsm.strState = strL1State; 755 retval = FsmNew(&l1fsm, L1FnList, ARRAY_SIZE(L1FnList)); 756 if (retval) 757 goto err; 758 759 dout_fsm.state_count = DOUT_STATE_COUNT; 760 dout_fsm.event_count = DOUT_EVENT_COUNT; 761 dout_fsm.strEvent = strDoutEvent; 762 dout_fsm.strState = strDoutState; 763 retval = FsmNew(&dout_fsm, DoutFnList, ARRAY_SIZE(DoutFnList)); 764 if (retval) 765 goto err_l1; 766 767 return 0; 768 769err_l1: 770 FsmFree(&l1fsm); 771err: 772 return retval; 773} 774 775// can't be __exit 776void st5481_d_exit(void) 777{ 778 FsmFree(&l1fsm); 779 FsmFree(&dout_fsm); 780} 781