📄 st5481_d.c
字号:
WARN("urb status %d",urb->status); if (d_out->busy == 0) { st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter); } break; } return; // Give up } FsmEvent(&adapter->d_out.fsm, EV_DOUT_COMPLETE, (void *) buf_nr);}/* ====================================================================== */static void dout_start_xmit(struct FsmInst *fsm, int event, void *arg){ // FIXME unify? struct st5481_adapter *adapter = fsm->userdata; struct st5481_d_out *d_out = &adapter->d_out; struct urb *urb; int len, bytes_sent; struct sk_buff *skb; int buf_nr = 0; skb = d_out->tx_skb; DBG(2,"len=%d",skb->len); isdnhdlc_out_init(&d_out->hdlc_state, 1, 0); if (test_and_set_bit(buf_nr, &d_out->busy)) { WARN("ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy); return; } urb = d_out->urb[buf_nr]; DBG_SKB(0x10, skb); len = isdnhdlc_encode(&d_out->hdlc_state, skb->data, skb->len, &bytes_sent, urb->transfer_buffer, 16); skb_pull(skb, bytes_sent); if(len < 16) FsmChangeState(&d_out->fsm, ST_DOUT_SHORT_INIT); else FsmChangeState(&d_out->fsm, ST_DOUT_LONG_INIT); if (skb->len == 0) { d_out->tx_skb = NULL; D_L1L2(adapter, PH_DATA | CONFIRM, NULL); dev_kfree_skb_any(skb); }// Prepare the URB urb->transfer_buffer_length = len; urb->iso_frame_desc[0].offset = 0; urb->iso_frame_desc[0].length = len; urb->number_of_packets = 1; // Prepare the URB urb->dev = adapter->usb_dev; urb->transfer_flags = URB_ISO_ASAP; DBG_ISO_PACKET(0x20,urb); SUBMIT_URB(urb, GFP_KERNEL);}static void dout_short_fifo(struct FsmInst *fsm, int event, void *arg){ struct st5481_adapter *adapter = fsm->userdata; struct st5481_d_out *d_out = &adapter->d_out; FsmChangeState(&d_out->fsm, ST_DOUT_SHORT_WAIT_DEN); st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 16, NULL, NULL);}static void dout_end_short_frame(struct FsmInst *fsm, int event, void *arg){ struct st5481_adapter *adapter = fsm->userdata; struct st5481_d_out *d_out = &adapter->d_out; FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_UNDERRUN);}static void dout_long_enable_fifo(struct FsmInst *fsm, int event, void *arg){ struct st5481_adapter *adapter = fsm->userdata; struct st5481_d_out *d_out = &adapter->d_out; st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 16, NULL, NULL); FsmChangeState(&d_out->fsm, ST_DOUT_LONG_WAIT_DEN);}static void dout_long_den(struct FsmInst *fsm, int event, void *arg){ struct st5481_adapter *adapter = fsm->userdata; struct st5481_d_out *d_out = &adapter->d_out; FsmChangeState(&d_out->fsm, ST_DOUT_NORMAL); usb_d_out(adapter, 0); usb_d_out(adapter, 1);}static void dout_reset(struct FsmInst *fsm, int event, void *arg){ struct st5481_adapter *adapter = fsm->userdata; struct st5481_d_out *d_out = &adapter->d_out; FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_RESET); st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, fifo_reseted, adapter);}static void dout_stop(struct FsmInst *fsm, int event, void *arg){ struct st5481_adapter *adapter = fsm->userdata; struct st5481_d_out *d_out = &adapter->d_out; FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_STOP); st5481_usb_device_ctrl_msg(adapter, OUT_D_COUNTER, 0, dout_stop_event, adapter);}static void dout_underrun(struct FsmInst *fsm, int event, void *arg){ struct st5481_adapter *adapter = fsm->userdata; struct st5481_d_out *d_out = &adapter->d_out; if (test_bit(0, &d_out->busy) || test_bit(1, &d_out->busy)) { FsmChangeState(&d_out->fsm, ST_DOUT_WAIT_FOR_NOT_BUSY); } else { dout_stop(fsm, event, arg); }}static void dout_check_busy(struct FsmInst *fsm, int event, void *arg){ struct st5481_adapter *adapter = fsm->userdata; struct st5481_d_out *d_out = &adapter->d_out; if (!test_bit(0, &d_out->busy) && !test_bit(1, &d_out->busy)) dout_stop(fsm, event, arg);}static void dout_reseted(struct FsmInst *fsm, int event, void *arg){ struct st5481_adapter *adapter = fsm->userdata; struct st5481_d_out *d_out = &adapter->d_out; FsmChangeState(&d_out->fsm, ST_DOUT_NONE); // FIXME locking if (d_out->tx_skb) FsmEvent(&d_out->fsm, EV_DOUT_START_XMIT, NULL);}static void dout_complete(struct FsmInst *fsm, int event, void *arg){ struct st5481_adapter *adapter = fsm->userdata; int buf_nr = (int) arg; usb_d_out(adapter, buf_nr);}static void dout_ignore(struct FsmInst *fsm, int event, void *arg){}static struct FsmNode DoutFnList[] __initdata ={ {ST_DOUT_NONE, EV_DOUT_START_XMIT, dout_start_xmit}, {ST_DOUT_SHORT_INIT, EV_DOUT_COMPLETE, dout_short_fifo}, {ST_DOUT_SHORT_WAIT_DEN, EV_DOUT_DEN, dout_end_short_frame}, {ST_DOUT_SHORT_WAIT_DEN, EV_DOUT_UNDERRUN, dout_underrun}, {ST_DOUT_LONG_INIT, EV_DOUT_COMPLETE, dout_long_enable_fifo}, {ST_DOUT_LONG_WAIT_DEN, EV_DOUT_DEN, dout_long_den}, {ST_DOUT_LONG_WAIT_DEN, EV_DOUT_UNDERRUN, dout_underrun}, {ST_DOUT_NORMAL, EV_DOUT_UNDERRUN, dout_underrun}, {ST_DOUT_NORMAL, EV_DOUT_COMPLETE, dout_complete}, {ST_DOUT_WAIT_FOR_UNDERRUN, EV_DOUT_UNDERRUN, dout_underrun}, {ST_DOUT_WAIT_FOR_UNDERRUN, EV_DOUT_COMPLETE, dout_ignore}, {ST_DOUT_WAIT_FOR_NOT_BUSY, EV_DOUT_COMPLETE, dout_check_busy}, {ST_DOUT_WAIT_FOR_STOP, EV_DOUT_STOPPED, dout_reset}, {ST_DOUT_WAIT_FOR_RESET, EV_DOUT_RESETED, dout_reseted},};void st5481_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg){ struct st5481_adapter *adapter = hisax_d_if->priv; struct sk_buff *skb = arg; switch (pr) { case PH_ACTIVATE | REQUEST: FsmEvent(&adapter->l1m, EV_PH_ACTIVATE_REQ, NULL); break; case PH_DEACTIVATE | REQUEST: FsmEvent(&adapter->l1m, EV_PH_DEACTIVATE_REQ, NULL); break; case PH_DATA | REQUEST: DBG(2, "PH_DATA REQUEST len %d", skb->len); if (adapter->d_out.tx_skb) BUG(); adapter->d_out.tx_skb = skb; FsmEvent(&adapter->d_out.fsm, EV_DOUT_START_XMIT, NULL); break; default: WARN("pr %#x\n", pr); break; }}/* ====================================================================== *//* * Start receiving on the D channel since entered state F7. */static void ph_connect(struct st5481_adapter *adapter){ struct st5481_d_out *d_out = &adapter->d_out; struct st5481_in *d_in = &adapter->d_in; DBG(8,""); FsmChangeState(&d_out->fsm, ST_DOUT_NONE); // st5481_usb_device_ctrl_msg(adapter, FFMSK_D, OUT_UNDERRUN, NULL, NULL); st5481_usb_device_ctrl_msg(adapter, FFMSK_D, 0xfc, NULL, NULL); st5481_in_mode(d_in, L1_MODE_HDLC);#ifdef LOOPBACK // Turn loopback on (data sent on B and D looped back) st5481_usb_device_ctrl_msg(cs, LBB, 0x04, NULL, NULL);#endif st5481_usb_pipe_reset(adapter, EP_D_OUT | USB_DIR_OUT, NULL, NULL); // Turn on the green LED to tell that we are in state F7 adapter->leds |= GREEN_LED; st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL);}/* * Stop receiving on the D channel since not in state F7. */static void ph_disconnect(struct st5481_adapter *adapter){ DBG(8,""); st5481_in_mode(&adapter->d_in, L1_MODE_NULL); // Turn off the green LED to tell that we left state F7 adapter->leds &= ~GREEN_LED; st5481_usb_device_ctrl_msg(adapter, GPIO_OUT, adapter->leds, NULL, NULL);}static int st5481_setup_d_out(struct st5481_adapter *adapter){ struct usb_device *dev = adapter->usb_dev; struct usb_interface *intf; struct usb_host_interface *altsetting = NULL; struct usb_host_endpoint *endpoint; struct st5481_d_out *d_out = &adapter->d_out; DBG(2,""); intf = usb_ifnum_to_if(dev, 0); if (intf) altsetting = usb_altnum_to_altsetting(intf, 3); if (!altsetting) return -ENXIO; // Allocate URBs and buffers for the D channel out endpoint = &altsetting->endpoint[EP_D_OUT-1]; DBG(2,"endpoint address=%02x,packet size=%d", endpoint->desc.bEndpointAddress, le16_to_cpu(endpoint->desc.wMaxPacketSize)); return st5481_setup_isocpipes(d_out->urb, dev, usb_sndisocpipe(dev, endpoint->desc.bEndpointAddress), NUM_ISO_PACKETS_D, SIZE_ISO_PACKETS_D_OUT, NUM_ISO_PACKETS_D * SIZE_ISO_PACKETS_D_OUT, usb_d_out_complete, adapter);}static void st5481_release_d_out(struct st5481_adapter *adapter){ struct st5481_d_out *d_out = &adapter->d_out; DBG(2,""); st5481_release_isocpipes(d_out->urb);}int st5481_setup_d(struct st5481_adapter *adapter){ int retval; DBG(2,""); retval = st5481_setup_d_out(adapter); if (retval) goto err; adapter->d_in.bufsize = MAX_DFRAME_LEN_L1; adapter->d_in.num_packets = NUM_ISO_PACKETS_D; adapter->d_in.packet_size = SIZE_ISO_PACKETS_D_IN; adapter->d_in.ep = EP_D_IN | USB_DIR_IN; adapter->d_in.counter = IN_D_COUNTER; adapter->d_in.adapter = adapter; adapter->d_in.hisax_if = &adapter->hisax_d_if.ifc; retval = st5481_setup_in(&adapter->d_in); if (retval) goto err_d_out; adapter->l1m.fsm = &l1fsm; adapter->l1m.state = ST_L1_F3; adapter->l1m.debug = st5481_debug & 0x100; adapter->l1m.userdata = adapter; adapter->l1m.printdebug = l1m_debug; FsmInitTimer(&adapter->l1m, &adapter->timer); adapter->d_out.fsm.fsm = &dout_fsm; adapter->d_out.fsm.state = ST_DOUT_NONE; adapter->d_out.fsm.debug = st5481_debug & 0x100; adapter->d_out.fsm.userdata = adapter; adapter->d_out.fsm.printdebug = dout_debug; return 0; err_d_out: st5481_release_d_out(adapter); err: return retval;}void st5481_release_d(struct st5481_adapter *adapter){ DBG(2,""); st5481_release_in(&adapter->d_in); st5481_release_d_out(adapter);}/* ====================================================================== * init / exit */int __init st5481_d_init(void){ int retval; l1fsm.state_count = L1_STATE_COUNT; l1fsm.event_count = L1_EVENT_COUNT; l1fsm.strEvent = strL1Event; l1fsm.strState = strL1State; retval = FsmNew(&l1fsm, L1FnList, ARRAY_SIZE(L1FnList)); if (retval) goto err; dout_fsm.state_count = DOUT_STATE_COUNT; dout_fsm.event_count = DOUT_EVENT_COUNT; dout_fsm.strEvent = strDoutEvent; dout_fsm.strState = strDoutState; retval = FsmNew(&dout_fsm, DoutFnList, ARRAY_SIZE(DoutFnList)); if (retval) goto err_l1; return 0; err_l1: FsmFree(&l1fsm); err: return retval;}// can't be __exitvoid st5481_d_exit(void){ FsmFree(&l1fsm); FsmFree(&dout_fsm);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -