linux/drivers/isdn/hisax/st5481_d.c
<<
>>
Prefs
   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