1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/init.h>
14#include <linux/usb.h>
15#include <linux/slab.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
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
242static struct Fsm dout_fsm;
243
244static char *strDoutState[] =
245{
246 "ST_DOUT_NONE",
247
248 "ST_DOUT_SHORT_INIT",
249 "ST_DOUT_SHORT_WAIT_DEN",
250
251 "ST_DOUT_LONG_INIT",
252 "ST_DOUT_LONG_WAIT_DEN",
253 "ST_DOUT_NORMAL",
254
255 "ST_DOUT_WAIT_FOR_UNDERRUN",
256 "ST_DOUT_WAIT_FOR_NOT_BUSY",
257 "ST_DOUT_WAIT_FOR_STOP",
258 "ST_DOUT_WAIT_FOR_RESET",
259};
260
261static char *strDoutEvent[] =
262{
263 "EV_DOUT_START_XMIT",
264 "EV_DOUT_COMPLETE",
265 "EV_DOUT_DEN",
266 "EV_DOUT_RESETED",
267 "EV_DOUT_STOPPED",
268 "EV_DOUT_COLL",
269 "EV_DOUT_UNDERRUN",
270};
271
272static void dout_debug(struct FsmInst *fi, char *fmt, ...)
273{
274 va_list args;
275 char buf[256];
276
277 va_start(args, fmt);
278 vsnprintf(buf, sizeof(buf), fmt, args);
279 DBG(0x2, "%s", buf);
280 va_end(args);
281}
282
283static void dout_stop_event(void *context)
284{
285 struct st5481_adapter *adapter = context;
286
287 FsmEvent(&adapter->d_out.fsm, EV_DOUT_STOPPED, NULL);
288}
289
290
291
292
293static void usb_d_out(struct st5481_adapter *adapter, int buf_nr)
294{
295 struct st5481_d_out *d_out = &adapter->d_out;
296 struct urb *urb;
297 unsigned int num_packets, packet_offset;
298 int len, buf_size, bytes_sent;
299 struct sk_buff *skb;
300 struct usb_iso_packet_descriptor *desc;
301
302 if (d_out->fsm.state != ST_DOUT_NORMAL)
303 return;
304
305 if (test_and_set_bit(buf_nr, &d_out->busy)) {
306 DBG(2, "ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy);
307 return;
308 }
309 urb = d_out->urb[buf_nr];
310
311 skb = d_out->tx_skb;
312
313 buf_size = NUM_ISO_PACKETS_D * SIZE_ISO_PACKETS_D_OUT;
314
315 if (skb) {
316 len = isdnhdlc_encode(&d_out->hdlc_state,
317 skb->data, skb->len, &bytes_sent,
318 urb->transfer_buffer, buf_size);
319 skb_pull(skb,bytes_sent);
320 } else {
321
322 len = isdnhdlc_encode(&d_out->hdlc_state,
323 NULL, 0, &bytes_sent,
324 urb->transfer_buffer, buf_size);
325 }
326
327 if (len < buf_size) {
328 FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_UNDERRUN);
329 }
330 if (skb && !skb->len) {
331 d_out->tx_skb = NULL;
332 D_L1L2(adapter, PH_DATA | CONFIRM, NULL);
333 dev_kfree_skb_any(skb);
334 }
335
336
337 urb->transfer_buffer_length = len;
338 num_packets = 0;
339 packet_offset = 0;
340 while (packet_offset < len) {
341 desc = &urb->iso_frame_desc[num_packets];
342 desc->offset = packet_offset;
343 desc->length = SIZE_ISO_PACKETS_D_OUT;
344 if (len - packet_offset < desc->length)
345 desc->length = len - packet_offset;
346 num_packets++;
347 packet_offset += desc->length;
348 }
349 urb->number_of_packets = num_packets;
350
351
352 urb->dev = adapter->usb_dev;
353
354 urb->transfer_flags = 0;
355 urb->start_frame = usb_get_current_frame_number(adapter->usb_dev)+2;
356
357 DBG_ISO_PACKET(0x20,urb);
358
359 if (usb_submit_urb(urb, GFP_KERNEL) < 0) {
360
361 urb->transfer_flags = URB_ISO_ASAP;
362 SUBMIT_URB(urb, GFP_KERNEL);
363 }
364}
365
366static void fifo_reseted(void *context)
367{
368 struct st5481_adapter *adapter = context;
369
370 FsmEvent(&adapter->d_out.fsm, EV_DOUT_RESETED, NULL);
371}
372
373static void usb_d_out_complete(struct urb *urb)
374{
375 struct st5481_adapter *adapter = urb->context;
376 struct st5481_d_out *d_out = &adapter->d_out;
377 long buf_nr;
378
379 DBG(2, "");
380
381 buf_nr = get_buf_nr(d_out->urb, urb);
382 test_and_clear_bit(buf_nr, &d_out->busy);
383
384 if (unlikely(urb->status < 0)) {
385 switch (urb->status) {
386 case -ENOENT:
387 case -ESHUTDOWN:
388 case -ECONNRESET:
389 DBG(1,"urb killed status %d", urb->status);
390 break;
391 default:
392 WARNING("urb status %d",urb->status);
393 if (d_out->busy == 0) {
394 st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter);
395 }
396 break;
397 }
398 return;
399 }
400
401 FsmEvent(&adapter->d_out.fsm, EV_DOUT_COMPLETE, (void *) buf_nr);
402}
403
404
405
406static void dout_start_xmit(struct FsmInst *fsm, int event, void *arg)
407{
408
409 struct st5481_adapter *adapter = fsm->userdata;
410 struct st5481_d_out *d_out = &adapter->d_out;
411 struct urb *urb;
412 int len, bytes_sent;
413 struct sk_buff *skb;
414 int buf_nr = 0;
415
416 skb = d_out->tx_skb;
417
418 DBG(2,"len=%d",skb->len);
419
420 isdnhdlc_out_init(&d_out->hdlc_state, HDLC_DCHANNEL | HDLC_BITREVERSE);
421
422 if (test_and_set_bit(buf_nr, &d_out->busy)) {
423 WARNING("ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy);
424 return;
425 }
426 urb = d_out->urb[buf_nr];
427
428 DBG_SKB(0x10, skb);
429 len = isdnhdlc_encode(&d_out->hdlc_state,
430 skb->data, skb->len, &bytes_sent,
431 urb->transfer_buffer, 16);
432 skb_pull(skb, bytes_sent);
433
434 if(len < 16)
435 FsmChangeState(&d_out->fsm, ST_DOUT_SHORT_INIT);
436 else
437 FsmChangeState(&d_out->fsm, ST_DOUT_LONG_INIT);
438
439 if (skb->len == 0) {
440 d_out->tx_skb = NULL;
441 D_L1L2(adapter, PH_DATA | CONFIRM, NULL);
442 dev_kfree_skb_any(skb);
443 }
444
445
446 urb->transfer_buffer_length = len;
447
448 urb->iso_frame_desc[0].offset = 0;
449 urb->iso_frame_desc[0].length = len;
450 urb->number_of_packets = 1;
451
452
453 urb->dev = adapter->usb_dev;
454 urb->transfer_flags = URB_ISO_ASAP;
455
456 DBG_ISO_PACKET(0x20,urb);
457 SUBMIT_URB(urb, GFP_KERNEL);
458}
459
460static void dout_short_fifo(struct FsmInst *fsm, int event, void *arg)
461{
462 struct st5481_adapter *adapter = fsm->userdata;
463 struct st5481_d_out *d_out = &adapter->d_out;
464
465 FsmChangeState(&d_out->fsm, ST_DOUT_SHORT_WAIT_DEN);
466 st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 16, NULL, NULL);
467}
468
469static void dout_end_short_frame(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 FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_UNDERRUN);
475}
476
477static void dout_long_enable_fifo(struct FsmInst *fsm, int event, void *arg)
478{
479 struct st5481_adapter *adapter = fsm->userdata;
480 struct st5481_d_out *d_out = &adapter->d_out;
481
482 st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 16, NULL, NULL);
483 FsmChangeState(&d_out->fsm, ST_DOUT_LONG_WAIT_DEN);
484}
485
486static void dout_long_den(struct FsmInst *fsm, int event, void *arg)
487{
488 struct st5481_adapter *adapter = fsm->userdata;
489 struct st5481_d_out *d_out = &adapter->d_out;
490
491 FsmChangeState(&d_out->fsm, ST_DOUT_NORMAL);
492 usb_d_out(adapter, 0);
493 usb_d_out(adapter, 1);
494}
495
496static void dout_reset(struct FsmInst *fsm, int event, void *arg)
497{
498 struct st5481_adapter *adapter = fsm->userdata;
499 struct st5481_d_out *d_out = &adapter->d_out;
500
501 FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_RESET);
502 st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter);
503}
504
505static void dout_stop(struct FsmInst *fsm, int event, void *arg)
506{
507 struct st5481_adapter *adapter = fsm->userdata;
508 struct st5481_d_out *d_out = &adapter->d_out;
509
510 FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_STOP);
511 st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 0, dout_stop_event, adapter);
512}
513
514static void dout_underrun(struct FsmInst *fsm, int event, void *arg)
515{
516 struct st5481_adapter *adapter = fsm->userdata;
517 struct st5481_d_out *d_out = &adapter->d_out;
518
519 if (test_bit(0, &d_out->busy) || test_bit(1, &d_out->busy)) {
520 FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_NOT_BUSY);
521 } else {
522 dout_stop(fsm, event, arg);
523 }
524}
525
526static void dout_check_busy(struct FsmInst *fsm, int event, void *arg)
527{
528 struct st5481_adapter *adapter = fsm->userdata;
529 struct st5481_d_out *d_out = &adapter->d_out;
530
531 if (!test_bit(0, &d_out->busy) && !test_bit(1, &d_out->busy))
532 dout_stop(fsm, event, arg);
533}
534
535static void dout_reseted(struct FsmInst *fsm, int event, void *arg)
536{
537 struct st5481_adapter *adapter = fsm->userdata;
538 struct st5481_d_out *d_out = &adapter->d_out;
539
540 FsmChangeState(&d_out->fsm, ST_DOUT_NONE);
541
542 if (d_out->tx_skb)
543 FsmEvent(&d_out->fsm, EV_DOUT_START_XMIT, NULL);
544}
545
546static void dout_complete(struct FsmInst *fsm, int event, void *arg)
547{
548 struct st5481_adapter *adapter = fsm->userdata;
549 long buf_nr = (long) arg;
550
551 usb_d_out(adapter, buf_nr);
552}
553
554static void dout_ignore(struct FsmInst *fsm, int event, void *arg)
555{
556}
557
558static struct FsmNode DoutFnList[] __initdata =
559{
560 {ST_DOUT_NONE, EV_DOUT_START_XMIT, dout_start_xmit},
561
562 {ST_DOUT_SHORT_INIT, EV_DOUT_COMPLETE, dout_short_fifo},
563
564 {ST_DOUT_SHORT_WAIT_DEN, EV_DOUT_DEN, dout_end_short_frame},
565 {ST_DOUT_SHORT_WAIT_DEN, EV_DOUT_UNDERRUN, dout_underrun},
566
567 {ST_DOUT_LONG_INIT, EV_DOUT_COMPLETE, dout_long_enable_fifo},
568
569 {ST_DOUT_LONG_WAIT_DEN, EV_DOUT_DEN, dout_long_den},
570 {ST_DOUT_LONG_WAIT_DEN, EV_DOUT_UNDERRUN, dout_underrun},
571
572 {ST_DOUT_NORMAL, EV_DOUT_UNDERRUN, dout_underrun},
573 {ST_DOUT_NORMAL, EV_DOUT_COMPLETE, dout_complete},
574
575 {ST_DOUT_WAIT_FOR_UNDERRUN, EV_DOUT_UNDERRUN, dout_underrun},
576 {ST_DOUT_WAIT_FOR_UNDERRUN, EV_DOUT_COMPLETE, dout_ignore},
577
578 {ST_DOUT_WAIT_FOR_NOT_BUSY, EV_DOUT_COMPLETE, dout_check_busy},
579
580 {ST_DOUT_WAIT_FOR_STOP, EV_DOUT_STOPPED, dout_reset},
581
582 {ST_DOUT_WAIT_FOR_RESET, EV_DOUT_RESETED, dout_reseted},
583};
584
585void st5481_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg)
586{
587 struct st5481_adapter *adapter = hisax_d_if->priv;
588 struct sk_buff *skb = arg;
589
590 switch (pr) {
591 case PH_ACTIVATE | REQUEST:
592 FsmEvent(&adapter->l1m, EV_PH_ACTIVATE_REQ, NULL);
593 break;
594 case PH_DEACTIVATE | REQUEST:
595 FsmEvent(&adapter->l1m, EV_PH_DEACTIVATE_REQ, NULL);
596 break;
597 case PH_DATA | REQUEST:
598 DBG(2, "PH_DATA REQUEST len %d", skb->len);
599 BUG_ON(adapter->d_out.tx_skb);
600 adapter->d_out.tx_skb = skb;
601 FsmEvent(&adapter->d_out.fsm, EV_DOUT_START_XMIT, NULL);
602 break;
603 default:
604 WARNING("pr %#x\n", pr);
605 break;
606 }
607}
608
609
610
611
612
613
614
615static void ph_connect(struct st5481_adapter *adapter)
616{
617 struct st5481_d_out *d_out = &adapter->d_out;
618 struct st5481_in *d_in = &adapter->d_in;
619
620 DBG(8,"");
621
622 FsmChangeState(&d_out->fsm, ST_DOUT_NONE);
623
624
625 st5481_usb_device_ctrl_msg(adapter, FFMSK_D, 0xfc, NULL, NULL);
626 st5481_in_mode(d_in, L1_MODE_HDLC);
627
628#ifdef LOOPBACK
629
630 st5481_usb_device_ctrl_msg(cs, LBB, 0x04, NULL, NULL);
631#endif
632
633 st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, NULL, NULL);
634
635
636 adapter->leds |= GREEN_LED;
637 st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL);
638}
639
640
641
642
643static void ph_disconnect(struct st5481_adapter *adapter)
644{
645 DBG(8,"");
646
647 st5481_in_mode(&adapter->d_in, L1_MODE_NULL);
648
649
650 adapter->leds &= ~GREEN_LED;
651 st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL);
652}
653
654static int st5481_setup_d_out(struct st5481_adapter *adapter)
655{
656 struct usb_device *dev = adapter->usb_dev;
657 struct usb_interface *intf;
658 struct usb_host_interface *altsetting = NULL;
659 struct usb_host_endpoint *endpoint;
660 struct st5481_d_out *d_out = &adapter->d_out;
661
662 DBG(2,"");
663
664 intf = usb_ifnum_to_if(dev, 0);
665 if (intf)
666 altsetting = usb_altnum_to_altsetting(intf, 3);
667 if (!altsetting)
668 return -ENXIO;
669
670
671 endpoint = &altsetting->endpoint[EP_D_OUT-1];
672
673 DBG(2,"endpoint address=%02x,packet size=%d",
674 endpoint->desc.bEndpointAddress, le16_to_cpu(endpoint->desc.wMaxPacketSize));
675
676 return st5481_setup_isocpipes(d_out->urb, dev,
677 usb_sndisocpipe(dev, endpoint->desc.bEndpointAddress),
678 NUM_ISO_PACKETS_D, SIZE_ISO_PACKETS_D_OUT,
679 NUM_ISO_PACKETS_D * SIZE_ISO_PACKETS_D_OUT,
680 usb_d_out_complete, adapter);
681}
682
683static void st5481_release_d_out(struct st5481_adapter *adapter)
684{
685 struct st5481_d_out *d_out = &adapter->d_out;
686
687 DBG(2,"");
688
689 st5481_release_isocpipes(d_out->urb);
690}
691
692int st5481_setup_d(struct st5481_adapter *adapter)
693{
694 int retval;
695
696 DBG(2,"");
697
698 retval = st5481_setup_d_out(adapter);
699 if (retval)
700 goto err;
701 adapter->d_in.bufsize = MAX_DFRAME_LEN_L1;
702 adapter->d_in.num_packets = NUM_ISO_PACKETS_D;
703 adapter->d_in.packet_size = SIZE_ISO_PACKETS_D_IN;
704 adapter->d_in.ep = EP_D_IN | USB_DIR_IN;
705 adapter->d_in.counter = IN_D_COUNTER;
706 adapter->d_in.adapter = adapter;
707 adapter->d_in.hisax_if = &adapter->hisax_d_if.ifc;
708 retval = st5481_setup_in(&adapter->d_in);
709 if (retval)
710 goto err_d_out;
711
712 adapter->l1m.fsm = &l1fsm;
713 adapter->l1m.state = ST_L1_F3;
714 adapter->l1m.debug = st5481_debug & 0x100;
715 adapter->l1m.userdata = adapter;
716 adapter->l1m.printdebug = l1m_debug;
717 FsmInitTimer(&adapter->l1m, &adapter->timer);
718
719 adapter->d_out.fsm.fsm = &dout_fsm;
720 adapter->d_out.fsm.state = ST_DOUT_NONE;
721 adapter->d_out.fsm.debug = st5481_debug & 0x100;
722 adapter->d_out.fsm.userdata = adapter;
723 adapter->d_out.fsm.printdebug = dout_debug;
724
725 return 0;
726
727 err_d_out:
728 st5481_release_d_out(adapter);
729 err:
730 return retval;
731}
732
733void st5481_release_d(struct st5481_adapter *adapter)
734{
735 DBG(2,"");
736
737 st5481_release_in(&adapter->d_in);
738 st5481_release_d_out(adapter);
739}
740
741
742
743
744
745int __init st5481_d_init(void)
746{
747 int retval;
748
749 l1fsm.state_count = L1_STATE_COUNT;
750 l1fsm.event_count = L1_EVENT_COUNT;
751 l1fsm.strEvent = strL1Event;
752 l1fsm.strState = strL1State;
753 retval = FsmNew(&l1fsm, L1FnList, ARRAY_SIZE(L1FnList));
754 if (retval)
755 goto err;
756
757 dout_fsm.state_count = DOUT_STATE_COUNT;
758 dout_fsm.event_count = DOUT_EVENT_COUNT;
759 dout_fsm.strEvent = strDoutEvent;
760 dout_fsm.strState = strDoutState;
761 retval = FsmNew(&dout_fsm, DoutFnList, ARRAY_SIZE(DoutFnList));
762 if (retval)
763 goto err_l1;
764
765 return 0;
766
767 err_l1:
768 FsmFree(&l1fsm);
769 err:
770 return retval;
771}
772
773
774void st5481_d_exit(void)
775{
776 FsmFree(&l1fsm);
777 FsmFree(&dout_fsm);
778}
779