• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/isdn/hisax/
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