Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
st5481_d.c
Go to the documentation of this file.
1 /*
2  * Driver for ST5481 USB ISDN modem
3  *
4  * Author Frode Isaksen
5  * Copyright 2001 by Frode Isaksen <[email protected]>
6  * 2001 by Kai Germaschewski <[email protected]>
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 
19 static void ph_connect(struct st5481_adapter *adapter);
20 static void ph_disconnect(struct st5481_adapter *adapter);
21 
22 static struct Fsm l1fsm;
23 
24 static 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 
33 static 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 
56 static 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 
63 static void
64 l1_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 
72  D_L1L2(adapter, PH_DEACTIVATE | INDICATION, NULL);
73 }
74 
75 static void
76 l1_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 
84 }
85 
86 static void
87 l1_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);
94  D_L1L2(adapter, PH_ACTIVATE | INDICATION, NULL);
95 }
96 
97 static void
98 l1_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 
106 }
107 
108 static void
109 l1_timer3(struct FsmInst *fi, int event, void *arg)
110 {
111  struct st5481_adapter *adapter = fi->userdata;
112 
115  D_L1L2(adapter, PH_DEACTIVATE | INDICATION, NULL);
116 }
117 
118 static void
119 l1_ignore(struct FsmInst *fi, int event, void *arg)
120 {
121 }
122 
123 static void
124 l1_activate(struct FsmInst *fi, int event, void *arg)
125 {
126  struct st5481_adapter *adapter = fi->userdata;
127 
133 }
134 
135 static 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 
170 static __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 
243 static struct Fsm dout_fsm;
244 
245 static 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 
262 static 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 
273 static __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 
285 static 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  */
295 static 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 
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) {
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 
368 static 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 
375 static 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 
408 static 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 
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)
438  else
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 
462 static 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 
469 }
470 
471 static 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 
477 }
478 
479 static 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 
486 }
487 
488 static 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 
494  usb_d_out(adapter, 0);
495  usb_d_out(adapter, 1);
496 }
497 
498 static 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 
504  st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter);
505 }
506 
507 static 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 
513  st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 0, dout_stop_event, adapter);
514 }
515 
516 static 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)) {
523  } else {
524  dout_stop(fsm, event, arg);
525  }
526 }
527 
528 static 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 
537 static 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 
548 static 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 
556 static void dout_ignore(struct FsmInst *fsm, int event, void *arg)
557 {
558 }
559 
560 static 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 
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 
587 void 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  */
617 static 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);
629 
630 #ifdef LOOPBACK
631  // Turn loopback on (data sent on B and D looped back)
633 #endif
634 
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  */
645 static 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 
656 static 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 
685 static 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 
692 }
693 
694 int 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 
729 err_d_out:
730  st5481_release_d_out(adapter);
731 err:
732  return retval;
733 }
734 
735 void 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 
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 
769 err_l1:
770  FsmFree(&l1fsm);
771 err:
772  return retval;
773 }
774 
775 // can't be __exit
776 void st5481_d_exit(void)
777 {
778  FsmFree(&l1fsm);
779  FsmFree(&dout_fsm);
780 }