1
2
3
4
5
6
7
8
9
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
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
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
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
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
354 urb->dev = adapter->usb_dev;
355
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
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;
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
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
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
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
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
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
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
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
638 adapter->leds |= GREEN_LED;
639 st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL);
640}
641
642
643
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
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
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
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
776void st5481_d_exit(void)
777{
778 FsmFree(&l1fsm);
779 FsmFree(&dout_fsm);
780}
781