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 void l1m_debug(struct FsmInst *fi, char *fmt, ...) 171{ 172 va_list args; 173 char buf[256]; 174 175 va_start(args, fmt); 176 vsnprintf(buf, sizeof(buf), fmt, args); 177 DBG(8, "%s", buf); 178 va_end(args); 179} 180 181/* ====================================================================== 182 * D-Channel out 183 */ 184 185 186static struct Fsm dout_fsm; 187 188static char *strDoutState[] = 189{ 190 "ST_DOUT_NONE", 191 192 "ST_DOUT_SHORT_INIT", 193 "ST_DOUT_SHORT_WAIT_DEN", 194 195 "ST_DOUT_LONG_INIT", 196 "ST_DOUT_LONG_WAIT_DEN", 197 "ST_DOUT_NORMAL", 198 199 "ST_DOUT_WAIT_FOR_UNDERRUN", 200 "ST_DOUT_WAIT_FOR_NOT_BUSY", 201 "ST_DOUT_WAIT_FOR_STOP", 202 "ST_DOUT_WAIT_FOR_RESET", 203}; 204 205static char *strDoutEvent[] = 206{ 207 "EV_DOUT_START_XMIT", 208 "EV_DOUT_COMPLETE", 209 "EV_DOUT_DEN", 210 "EV_DOUT_RESETED", 211 "EV_DOUT_STOPPED", 212 "EV_DOUT_COLL", 213 "EV_DOUT_UNDERRUN", 214}; 215 216static void dout_debug(struct FsmInst *fi, char *fmt, ...) 217{ 218 va_list args; 219 char buf[256]; 220 221 va_start(args, fmt); 222 vsnprintf(buf, sizeof(buf), fmt, args); 223 DBG(0x2, "%s", buf); 224 va_end(args); 225} 226 227static void dout_stop_event(void *context) 228{ 229 struct st5481_adapter *adapter = context; 230 231 FsmEvent(&adapter->d_out.fsm, EV_DOUT_STOPPED, NULL); 232} 233 234/* 235 * Start the transfer of a D channel frame. 236 */ 237static void usb_d_out(struct st5481_adapter *adapter, int buf_nr) 238{ 239 struct st5481_d_out *d_out = &adapter->d_out; 240 struct urb *urb; 241 unsigned int num_packets, packet_offset; 242 int len, buf_size, bytes_sent; 243 struct sk_buff *skb; 244 struct usb_iso_packet_descriptor *desc; 245 246 if (d_out->fsm.state != ST_DOUT_NORMAL) 247 return; 248 249 if (test_and_set_bit(buf_nr, &d_out->busy)) { 250 DBG(2, "ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy); 251 return; 252 } 253 urb = d_out->urb[buf_nr]; 254 255 skb = d_out->tx_skb; 256 257 buf_size = NUM_ISO_PACKETS_D * SIZE_ISO_PACKETS_D_OUT; 258 259 if (skb) { 260 len = isdnhdlc_encode(&d_out->hdlc_state, 261 skb->data, skb->len, &bytes_sent, 262 urb->transfer_buffer, buf_size); 263 skb_pull(skb,bytes_sent); 264 } else { 265 // Send flags or idle 266 len = isdnhdlc_encode(&d_out->hdlc_state, 267 NULL, 0, &bytes_sent, 268 urb->transfer_buffer, buf_size); 269 } 270 271 if (len < buf_size) { 272 FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_UNDERRUN); 273 } 274 if (skb && !skb->len) { 275 d_out->tx_skb = NULL; 276 D_L1L2(adapter, PH_DATA | CONFIRM, NULL); 277 dev_kfree_skb_any(skb); 278 } 279 280 // Prepare the URB 281 urb->transfer_buffer_length = len; 282 num_packets = 0; 283 packet_offset = 0; 284 while (packet_offset < len) { 285 desc = &urb->iso_frame_desc[num_packets]; 286 desc->offset = packet_offset; 287 desc->length = SIZE_ISO_PACKETS_D_OUT; 288 if (len - packet_offset < desc->length) 289 desc->length = len - packet_offset; 290 num_packets++; 291 packet_offset += desc->length; 292 } 293 urb->number_of_packets = num_packets; 294 295 // Prepare the URB 296 urb->dev = adapter->usb_dev; 297 // Need to transmit the next buffer 2ms after the DEN_EVENT 298 urb->transfer_flags = 0; 299 urb->start_frame = usb_get_current_frame_number(adapter->usb_dev)+2; 300 301 DBG_ISO_PACKET(0x20,urb); 302 303 if (usb_submit_urb(urb, GFP_KERNEL) < 0) { 304 // There is another URB queued up 305 urb->transfer_flags = URB_ISO_ASAP; 306 SUBMIT_URB(urb, GFP_KERNEL); 307 } 308} 309 310static void fifo_reseted(void *context) 311{ 312 struct st5481_adapter *adapter = context; 313 314 FsmEvent(&adapter->d_out.fsm, EV_DOUT_RESETED, NULL); 315} 316 317static void usb_d_out_complete(struct urb *urb) 318{ 319 struct st5481_adapter *adapter = urb->context; 320 struct st5481_d_out *d_out = &adapter->d_out; 321 long buf_nr; 322 323 DBG(2, ""); 324 325 buf_nr = get_buf_nr(d_out->urb, urb); 326 test_and_clear_bit(buf_nr, &d_out->busy); 327 328 if (unlikely(urb->status < 0)) { 329 switch (urb->status) { 330 case -ENOENT: 331 case -ESHUTDOWN: 332 case -ECONNRESET: 333 DBG(1,"urb killed status %d", urb->status); 334 break; 335 default: 336 WARNING("urb status %d",urb->status); 337 if (d_out->busy == 0) { 338 st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter); 339 } 340 break; 341 } 342 return; // Give up 343 } 344 345 FsmEvent(&adapter->d_out.fsm, EV_DOUT_COMPLETE, (void *) buf_nr); 346} 347 348/* ====================================================================== */ 349 350static void dout_start_xmit(struct FsmInst *fsm, int event, void *arg) 351{ 352 struct st5481_adapter *adapter = fsm->userdata; 353 struct st5481_d_out *d_out = &adapter->d_out; 354 struct urb *urb; 355 int len, bytes_sent; 356 struct sk_buff *skb; 357 int buf_nr = 0; 358 359 skb = d_out->tx_skb; 360 361 DBG(2,"len=%d",skb->len); 362 363 isdnhdlc_out_init(&d_out->hdlc_state, HDLC_DCHANNEL | HDLC_BITREVERSE); 364 365 if (test_and_set_bit(buf_nr, &d_out->busy)) { 366 WARNING("ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy); 367 return; 368 } 369 urb = d_out->urb[buf_nr]; 370 371 DBG_SKB(0x10, skb); 372 len = isdnhdlc_encode(&d_out->hdlc_state, 373 skb->data, skb->len, &bytes_sent, 374 urb->transfer_buffer, 16); 375 skb_pull(skb, bytes_sent); 376 377 if(len < 16) 378 FsmChangeState(&d_out->fsm, ST_DOUT_SHORT_INIT); 379 else 380 FsmChangeState(&d_out->fsm, ST_DOUT_LONG_INIT); 381 382 if (skb->len == 0) { 383 d_out->tx_skb = NULL; 384 D_L1L2(adapter, PH_DATA | CONFIRM, NULL); 385 dev_kfree_skb_any(skb); 386 } 387 388// Prepare the URB 389 urb->transfer_buffer_length = len; 390 391 urb->iso_frame_desc[0].offset = 0; 392 urb->iso_frame_desc[0].length = len; 393 urb->number_of_packets = 1; 394 395 // Prepare the URB 396 urb->dev = adapter->usb_dev; 397 urb->transfer_flags = URB_ISO_ASAP; 398 399 DBG_ISO_PACKET(0x20,urb); 400 SUBMIT_URB(urb, GFP_KERNEL); 401} 402 403static void dout_short_fifo(struct FsmInst *fsm, int event, void *arg) 404{ 405 struct st5481_adapter *adapter = fsm->userdata; 406 struct st5481_d_out *d_out = &adapter->d_out; 407 408 FsmChangeState(&d_out->fsm, ST_DOUT_SHORT_WAIT_DEN); 409 st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 16, NULL, NULL); 410} 411 412static void dout_end_short_frame(struct FsmInst *fsm, int event, void *arg) 413{ 414 struct st5481_adapter *adapter = fsm->userdata; 415 struct st5481_d_out *d_out = &adapter->d_out; 416 417 FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_UNDERRUN); 418} 419 420static void dout_long_enable_fifo(struct FsmInst *fsm, int event, void *arg) 421{ 422 struct st5481_adapter *adapter = fsm->userdata; 423 struct st5481_d_out *d_out = &adapter->d_out; 424 425 st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 16, NULL, NULL); 426 FsmChangeState(&d_out->fsm, ST_DOUT_LONG_WAIT_DEN); 427} 428 429static void dout_long_den(struct FsmInst *fsm, int event, void *arg) 430{ 431 struct st5481_adapter *adapter = fsm->userdata; 432 struct st5481_d_out *d_out = &adapter->d_out; 433 434 FsmChangeState(&d_out->fsm, ST_DOUT_NORMAL); 435 usb_d_out(adapter, 0); 436 usb_d_out(adapter, 1); 437} 438 439static void dout_reset(struct FsmInst *fsm, int event, void *arg) 440{ 441 struct st5481_adapter *adapter = fsm->userdata; 442 struct st5481_d_out *d_out = &adapter->d_out; 443 444 FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_RESET); 445 st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter); 446} 447 448static void dout_stop(struct FsmInst *fsm, int event, void *arg) 449{ 450 struct st5481_adapter *adapter = fsm->userdata; 451 struct st5481_d_out *d_out = &adapter->d_out; 452 453 FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_STOP); 454 st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 0, dout_stop_event, adapter); 455} 456 457static void dout_underrun(struct FsmInst *fsm, int event, void *arg) 458{ 459 struct st5481_adapter *adapter = fsm->userdata; 460 struct st5481_d_out *d_out = &adapter->d_out; 461 462 if (test_bit(0, &d_out->busy) || test_bit(1, &d_out->busy)) { 463 FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_NOT_BUSY); 464 } else { 465 dout_stop(fsm, event, arg); 466 } 467} 468 469static void dout_check_busy(struct FsmInst *fsm, int event, void *arg) 470{ 471 struct st5481_adapter *adapter = fsm->userdata; 472 struct st5481_d_out *d_out = &adapter->d_out; 473 474 if (!test_bit(0, &d_out->busy) && !test_bit(1, &d_out->busy)) 475 dout_stop(fsm, event, arg); 476} 477 478static void dout_reseted(struct FsmInst *fsm, int event, void *arg) 479{ 480 struct st5481_adapter *adapter = fsm->userdata; 481 struct st5481_d_out *d_out = &adapter->d_out; 482 483 FsmChangeState(&d_out->fsm, ST_DOUT_NONE); 484 if (d_out->tx_skb) 485 FsmEvent(&d_out->fsm, EV_DOUT_START_XMIT, NULL); 486} 487 488static void dout_complete(struct FsmInst *fsm, int event, void *arg) 489{ 490 struct st5481_adapter *adapter = fsm->userdata; 491 long buf_nr = (long) arg; 492 493 usb_d_out(adapter, buf_nr); 494} 495 496static void dout_ignore(struct FsmInst *fsm, int event, void *arg) 497{ 498} 499 500static struct FsmNode DoutFnList[] __initdata = 501{ 502 {ST_DOUT_NONE, EV_DOUT_START_XMIT, dout_start_xmit}, 503 504 {ST_DOUT_SHORT_INIT, EV_DOUT_COMPLETE, dout_short_fifo}, 505 506 {ST_DOUT_SHORT_WAIT_DEN, EV_DOUT_DEN, dout_end_short_frame}, 507 {ST_DOUT_SHORT_WAIT_DEN, EV_DOUT_UNDERRUN, dout_underrun}, 508 509 {ST_DOUT_LONG_INIT, EV_DOUT_COMPLETE, dout_long_enable_fifo}, 510 511 {ST_DOUT_LONG_WAIT_DEN, EV_DOUT_DEN, dout_long_den}, 512 {ST_DOUT_LONG_WAIT_DEN, EV_DOUT_UNDERRUN, dout_underrun}, 513 514 {ST_DOUT_NORMAL, EV_DOUT_UNDERRUN, dout_underrun}, 515 {ST_DOUT_NORMAL, EV_DOUT_COMPLETE, dout_complete}, 516 517 {ST_DOUT_WAIT_FOR_UNDERRUN, EV_DOUT_UNDERRUN, dout_underrun}, 518 {ST_DOUT_WAIT_FOR_UNDERRUN, EV_DOUT_COMPLETE, dout_ignore}, 519 520 {ST_DOUT_WAIT_FOR_NOT_BUSY, EV_DOUT_COMPLETE, dout_check_busy}, 521 522 {ST_DOUT_WAIT_FOR_STOP, EV_DOUT_STOPPED, dout_reset}, 523 524 {ST_DOUT_WAIT_FOR_RESET, EV_DOUT_RESETED, dout_reseted}, 525}; 526 527void st5481_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg) 528{ 529 struct st5481_adapter *adapter = hisax_d_if->priv; 530 struct sk_buff *skb = arg; 531 532 switch (pr) { 533 case PH_ACTIVATE | REQUEST: 534 FsmEvent(&adapter->l1m, EV_PH_ACTIVATE_REQ, NULL); 535 break; 536 case PH_DEACTIVATE | REQUEST: 537 FsmEvent(&adapter->l1m, EV_PH_DEACTIVATE_REQ, NULL); 538 break; 539 case PH_DATA | REQUEST: 540 DBG(2, "PH_DATA REQUEST len %d", skb->len); 541 BUG_ON(adapter->d_out.tx_skb); 542 adapter->d_out.tx_skb = skb; 543 FsmEvent(&adapter->d_out.fsm, EV_DOUT_START_XMIT, NULL); 544 break; 545 default: 546 WARNING("pr %#x\n", pr); 547 break; 548 } 549} 550 551/* ====================================================================== 552 */ 553 554/* 555 * Start receiving on the D channel since entered state F7. 556 */ 557static void ph_connect(struct st5481_adapter *adapter) 558{ 559 struct st5481_d_out *d_out = &adapter->d_out; 560 struct st5481_in *d_in = &adapter->d_in; 561 562 DBG(8,""); 563 564 FsmChangeState(&d_out->fsm, ST_DOUT_NONE); 565 566 // st5481_usb_device_ctrl_msg(adapter, FFMSK_D, OUT_UNDERRUN, NULL, NULL); 567 st5481_usb_device_ctrl_msg(adapter, FFMSK_D, 0xfc, NULL, NULL); 568 st5481_in_mode(d_in, L1_MODE_HDLC); 569 570#ifdef LOOPBACK 571 // Turn loopback on (data sent on B and D looped back) 572 st5481_usb_device_ctrl_msg(cs, LBB, 0x04, NULL, NULL); 573#endif 574 575 st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, NULL, NULL); 576 577 // Turn on the green LED to tell that we are in state F7 578 adapter->leds |= GREEN_LED; 579 st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL); 580} 581 582/* 583 * Stop receiving on the D channel since not in state F7. 584 */ 585static void ph_disconnect(struct st5481_adapter *adapter) 586{ 587 DBG(8,""); 588 589 st5481_in_mode(&adapter->d_in, L1_MODE_NULL); 590 591 // Turn off the green LED to tell that we left state F7 592 adapter->leds &= ~GREEN_LED; 593 st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL); 594} 595 596static int st5481_setup_d_out(struct st5481_adapter *adapter) 597{ 598 struct usb_device *dev = adapter->usb_dev; 599 struct usb_interface *intf; 600 struct usb_host_interface *altsetting = NULL; 601 struct usb_host_endpoint *endpoint; 602 struct st5481_d_out *d_out = &adapter->d_out; 603 604 DBG(2,""); 605 606 intf = usb_ifnum_to_if(dev, 0); 607 if (intf) 608 altsetting = usb_altnum_to_altsetting(intf, 3); 609 if (!altsetting) 610 return -ENXIO; 611 612 // Allocate URBs and buffers for the D channel out 613 endpoint = &altsetting->endpoint[EP_D_OUT-1]; 614 615 DBG(2,"endpoint address=%02x,packet size=%d", 616 endpoint->desc.bEndpointAddress, le16_to_cpu(endpoint->desc.wMaxPacketSize)); 617 618 return st5481_setup_isocpipes(d_out->urb, dev, 619 usb_sndisocpipe(dev, endpoint->desc.bEndpointAddress), 620 NUM_ISO_PACKETS_D, SIZE_ISO_PACKETS_D_OUT, 621 NUM_ISO_PACKETS_D * SIZE_ISO_PACKETS_D_OUT, 622 usb_d_out_complete, adapter); 623} 624 625static void st5481_release_d_out(struct st5481_adapter *adapter) 626{ 627 struct st5481_d_out *d_out = &adapter->d_out; 628 629 DBG(2,""); 630 631 st5481_release_isocpipes(d_out->urb); 632} 633 634int st5481_setup_d(struct st5481_adapter *adapter) 635{ 636 int retval; 637 638 DBG(2,""); 639 640 retval = st5481_setup_d_out(adapter); 641 if (retval) 642 goto err; 643 adapter->d_in.bufsize = MAX_DFRAME_LEN_L1; 644 adapter->d_in.num_packets = NUM_ISO_PACKETS_D; 645 adapter->d_in.packet_size = SIZE_ISO_PACKETS_D_IN; 646 adapter->d_in.ep = EP_D_IN | USB_DIR_IN; 647 adapter->d_in.counter = IN_D_COUNTER; 648 adapter->d_in.adapter = adapter; 649 adapter->d_in.hisax_if = &adapter->hisax_d_if.ifc; 650 retval = st5481_setup_in(&adapter->d_in); 651 if (retval) 652 goto err_d_out; 653 654 adapter->l1m.fsm = &l1fsm; 655 adapter->l1m.state = ST_L1_F3; 656 adapter->l1m.debug = st5481_debug & 0x100; 657 adapter->l1m.userdata = adapter; 658 adapter->l1m.printdebug = l1m_debug; 659 FsmInitTimer(&adapter->l1m, &adapter->timer); 660 661 adapter->d_out.fsm.fsm = &dout_fsm; 662 adapter->d_out.fsm.state = ST_DOUT_NONE; 663 adapter->d_out.fsm.debug = st5481_debug & 0x100; 664 adapter->d_out.fsm.userdata = adapter; 665 adapter->d_out.fsm.printdebug = dout_debug; 666 667 return 0; 668 669 err_d_out: 670 st5481_release_d_out(adapter); 671 err: 672 return retval; 673} 674 675void st5481_release_d(struct st5481_adapter *adapter) 676{ 677 DBG(2,""); 678 679 st5481_release_in(&adapter->d_in); 680 st5481_release_d_out(adapter); 681} 682 683/* ====================================================================== 684 * init / exit 685 */ 686 687int __init st5481_d_init(void) 688{ 689 int retval; 690 691 l1fsm.state_count = L1_STATE_COUNT; 692 l1fsm.event_count = L1_EVENT_COUNT; 693 l1fsm.strEvent = strL1Event; 694 l1fsm.strState = strL1State; 695 retval = FsmNew(&l1fsm, L1FnList, ARRAY_SIZE(L1FnList)); 696 if (retval) 697 goto err; 698 699 dout_fsm.state_count = DOUT_STATE_COUNT; 700 dout_fsm.event_count = DOUT_EVENT_COUNT; 701 dout_fsm.strEvent = strDoutEvent; 702 dout_fsm.strState = strDoutState; 703 retval = FsmNew(&dout_fsm, DoutFnList, ARRAY_SIZE(DoutFnList)); 704 if (retval) 705 goto err_l1; 706 707 return 0; 708 709 err_l1: 710 FsmFree(&l1fsm); 711 err: 712 return retval; 713} 714 715// can't be __exit 716void st5481_d_exit(void) 717{ 718 FsmFree(&l1fsm); 719 FsmFree(&dout_fsm); 720} 721