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 __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 __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