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 __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
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 * Start the transfer of a D channel frame.
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		// 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) {
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	// 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
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; // Give up
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	// 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
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// 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
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	// FIXME locking
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 * Start receiving on the D channel since entered state F7.
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	//	st5481_usb_device_ctrl_msg(adapter, FFMSK_D, OUT_UNDERRUN, NULL, NULL);
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	// Turn loopback on (data sent on B and D looped back)
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	// 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 */
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	// 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
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	// 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
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 * init / exit
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// can't be __exit
776void st5481_d_exit(void)
777{
778	FsmFree(&l1fsm);
779	FsmFree(&dout_fsm);
780}
781