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 
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 
D_L1L2(struct st5481_adapter * adapter,int pr,void * arg)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
l1_go_f3(struct FsmInst * fi,int event,void * arg)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 
71 	FsmChangeState(fi, ST_L1_F3);
72 	D_L1L2(adapter, PH_DEACTIVATE | INDICATION, NULL);
73 }
74 
75 static void
l1_go_f6(struct FsmInst * fi,int event,void * arg)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 
83 	FsmChangeState(fi, ST_L1_F6);
84 }
85 
86 static void
l1_go_f7(struct FsmInst * fi,int event,void * arg)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);
93 	FsmChangeState(fi, ST_L1_F7);
94 	D_L1L2(adapter, PH_ACTIVATE | INDICATION, NULL);
95 }
96 
97 static void
l1_go_f8(struct FsmInst * fi,int event,void * arg)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 
105 	FsmChangeState(fi, ST_L1_F8);
106 }
107 
108 static void
l1_timer3(struct FsmInst * fi,int event,void * arg)109 l1_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 
118 static void
l1_ignore(struct FsmInst * fi,int event,void * arg)119 l1_ignore(struct FsmInst *fi, int event, void *arg)
120 {
121 }
122 
123 static void
l1_activate(struct FsmInst * fi,int event,void * arg)124 l1_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 
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 __attribute__((format(printf, 2, 3)))
l1m_debug(struct FsmInst * fi,char * fmt,...)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 __attribute__((format(printf, 2, 3)))
dout_debug(struct FsmInst * fi,char * fmt,...)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 
dout_stop_event(void * context)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  */
usb_d_out(struct st5481_adapter * adapter,int buf_nr)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 
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 
fifo_reseted(void * context)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 
usb_d_out_complete(struct urb * urb)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 
dout_start_xmit(struct FsmInst * fsm,int event,void * arg)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 
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 
dout_short_fifo(struct FsmInst * fsm,int event,void * arg)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 
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 
dout_end_short_frame(struct FsmInst * fsm,int event,void * arg)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 
476 	FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_UNDERRUN);
477 }
478 
dout_long_enable_fifo(struct FsmInst * fsm,int event,void * arg)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 
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 
dout_long_den(struct FsmInst * fsm,int event,void * arg)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 
493 	FsmChangeState(&d_out->fsm, ST_DOUT_NORMAL);
494 	usb_d_out(adapter, 0);
495 	usb_d_out(adapter, 1);
496 }
497 
dout_reset(struct FsmInst * fsm,int event,void * arg)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 
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 
dout_stop(struct FsmInst * fsm,int event,void * arg)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 
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 
dout_underrun(struct FsmInst * fsm,int event,void * arg)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)) {
522 		FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_NOT_BUSY);
523 	}  else {
524 		dout_stop(fsm, event, arg);
525 	}
526 }
527 
dout_check_busy(struct FsmInst * fsm,int event,void * arg)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 
dout_reseted(struct FsmInst * fsm,int event,void * arg)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 
dout_complete(struct FsmInst * fsm,int event,void * arg)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 
dout_ignore(struct FsmInst * fsm,int event,void * arg)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 
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 
st5481_d_l2l1(struct hisax_if * hisax_d_if,int pr,void * arg)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  */
ph_connect(struct st5481_adapter * adapter)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);
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  */
ph_disconnect(struct st5481_adapter * adapter)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 
st5481_setup_d_out(struct st5481_adapter * adapter)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 
st5481_release_d_out(struct st5481_adapter * adapter)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 
691 	st5481_release_isocpipes(d_out->urb);
692 }
693 
st5481_setup_d(struct st5481_adapter * adapter)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 
st5481_release_d(struct st5481_adapter * adapter)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 
st5481_d_init(void)747 int __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 
769  err_l1:
770 	FsmFree(&l1fsm);
771  err:
772 	return retval;
773 }
774 
775 // can't be __exit
st5481_d_exit(void)776 void st5481_d_exit(void)
777 {
778 	FsmFree(&l1fsm);
779 	FsmFree(&dout_fsm);
780 }
781