Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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/usb.h>
 15 #include <linux/slab.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 
 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
 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
 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
 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
 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
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
119 l1_ignore(struct FsmInst *fi, int event, void *arg)
120 {
121 }
122 
123 static void
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 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 /*
186   D OUT state machine:
187   ====================
188 
189   Transmit short frame (< 16 bytes of encoded data):
190 
191   L1 FRAME    D_OUT_STATE           USB                  D CHANNEL
192   --------    -----------           ---                  ---------
193  
194               FIXME
195 
196  -> [xx..xx]  SHORT_INIT            -> [7Exx..xxC1C27EFF]
197               SHORT_WAIT_DEN        <> OUT_D_COUNTER=16 
198                                                  
199               END_OF_SHORT          <- DEN_EVENT         -> 7Exx
200                                                           xxxx 
201                                                           xxxx
202                                                           xxxx 
203                                                           xxxx
204                                                           xxxx
205                                                           C1C1 
206                                                           7EFF 
207               WAIT_FOR_RESET_IDLE   <- D_UNDERRUN        <- (8ms)                        
208               IDLE                  <> Reset pipe
209 
210               
211 
212   Transmit long frame (>= 16 bytes of encoded data):
213 
214   L1 FRAME    D_OUT_STATE           USB                  D CHANNEL
215   --------    -----------           ---                  ---------
216 
217  -> [xx...xx] IDLE
218               WAIT_FOR_STOP         <> OUT_D_COUNTER=0
219               WAIT_FOR_RESET        <> Reset pipe
220               STOP
221               INIT_LONG_FRAME       -> [7Exx..xx]
222               WAIT_DEN              <> OUT_D_COUNTER=16 
223               OUT_NORMAL            <- DEN_EVENT       -> 7Exx
224               END_OF_FRAME_BUSY     -> [xxxx]             xxxx 
225               END_OF_FRAME_NOT_BUSY -> [xxxx]             xxxx
226                                     -> [xxxx]             xxxx 
227                                     -> [C1C2]             xxxx
228                                     -> [7EFF]             xxxx
229                                                           xxxx 
230                                                           xxxx 
231                                                           ....
232                                                           xxxx
233                                                           C1C2
234                                                           7EFF
235                                     <- D_UNDERRUN      <- (> 8ms)                        
236               WAIT_FOR_STOP         <> OUT_D_COUNTER=0
237               WAIT_FOR_RESET        <> Reset pipe
238               STOP
239 
240 */          
241 
242 static struct Fsm dout_fsm;
243 
244 static 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 
261 static 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 
272 static 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 
283 static 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  * Start the transfer of a D channel frame.
292  */
293 static 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                 // Send flags or idle
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         // Prepare the URB
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         // Prepare the URB
352         urb->dev = adapter->usb_dev;
353         // Need to transmit the next buffer 2ms after the DEN_EVENT
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                 // There is another URB queued up
361                 urb->transfer_flags = URB_ISO_ASAP;
362                 SUBMIT_URB(urb, GFP_KERNEL);
363         }       
364 }
365 
366 static 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 
373 static 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                                 WARN("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; // Give up
399         }
400 
401         FsmEvent(&adapter->d_out.fsm, EV_DOUT_COMPLETE, (void *) buf_nr);
402 }
403 
404 /* ====================================================================== */
405 
406 static void dout_start_xmit(struct FsmInst *fsm, int event, void *arg)
407 {
408         // FIXME unify?
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, 1, 0);
421 
422         if (test_and_set_bit(buf_nr, &d_out->busy)) {
423                 WARN("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 // Prepare the URB
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         // Prepare the URB
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 
460 static 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 
469 static 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 
477 static 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 
486 static 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 
496 static 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 
505 static 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 
514 static 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 
526 static 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 
535 static 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         // FIXME locking
542         if (d_out->tx_skb)
543                 FsmEvent(&d_out->fsm, EV_DOUT_START_XMIT, NULL);
544 }
545 
546 static 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 
554 static void dout_ignore(struct FsmInst *fsm, int event, void *arg)
555 {
556 }
557 
558 static 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 
585 void 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                 WARN("pr %#x\n", pr);
605                 break;
606         }
607 }
608 
609 /* ======================================================================
610  */
611 
612 /*
613  * Start receiving on the D channel since entered state F7.
614  */
615 static 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         //      st5481_usb_device_ctrl_msg(adapter, FFMSK_D, OUT_UNDERRUN, NULL, NULL);
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         // Turn loopback on (data sent on B and D looped back)
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         // Turn on the green LED to tell that we are in state F7
636         adapter->leds |= GREEN_LED;
637         st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL);
638 }
639 
640 /*
641  * Stop receiving on the D channel since not in state F7.
642  */
643 static void ph_disconnect(struct st5481_adapter *adapter)
644 {
645         DBG(8,"");
646 
647         st5481_in_mode(&adapter->d_in, L1_MODE_NULL);
648 
649         // Turn off the green LED to tell that we left state F7
650         adapter->leds &= ~GREEN_LED;
651         st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL);
652 }
653 
654 static 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         // Allocate URBs and buffers for the D channel out
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 
683 static 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 
692 int 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 
733 void 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  * init / exit
743  */
744 
745 int __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 // can't be __exit
774 void st5481_d_exit(void)
775 {
776         FsmFree(&l1fsm);
777         FsmFree(&dout_fsm);
778 }
779 
  This page was automatically generated by the LXR engine.