static void isac_fill_fifo(struct isac *isac) { // this also works for isacsx, since // CMDR(D) register works the same int count; unsigned char cmd; u_char *ptr; BUG_ON(!isac->tx_skb); count = isac->tx_skb->len; BUG_ON(count <= 0); DBG(DBG_IRQ, "count %d", count); if (count > 0x20) { count = 0x20; cmd = ISAC_CMDR_XTF; } else { cmd = ISAC_CMDR_XTF | ISAC_CMDR_XME; } ptr = isac->tx_skb->data; skb_pull(isac->tx_skb, count); isac->tx_cnt += count; DBG_PACKET(DBG_XFIFO, ptr, count); isac->write_isac_fifo(isac, ptr, count); isac->write_isac(isac, ISAC_CMDR, cmd); }
/* * Decode frames received on the B/D channel. * Note that this function will be called continously * with 64Kbit/s / 16Kbit/s of data and hence it will be * called 50 times per second with 20 ISOC descriptors. * Called at interrupt. */ static void usb_in_complete(struct urb *urb) { struct st5481_in *in = urb->context; unsigned char *ptr; struct sk_buff *skb; int len, count, status; if (urb->status < 0) { if (urb->status != USB_ST_URB_KILLED) { WARN("urb status %d",urb->status); } else { DBG(1,"urb killed"); return; // Give up } } DBG_ISO_PACKET(0x80,urb); len = st5481_isoc_flatten(urb); ptr = urb->transfer_buffer; while (len > 0) { if (in->mode == L1_MODE_TRANS) { /* swap rx bytes to get hearable audio */ register unsigned char *dest = in->rcvbuf; status = len; for (; len; len--) *dest++ = isdnhdlc_bit_rev_tab[*ptr++]; } else { status = isdnhdlc_decode(&in->hdlc_state, ptr, len, &count, in->rcvbuf, in->bufsize); ptr += count; len -= count; } if (status > 0) { // Good frame received DBG(4,"count=%d",status); DBG_PACKET(0x400, in->rcvbuf, status); if (!(skb = dev_alloc_skb(status))) { WARN("receive out of memory\n"); break; } memcpy(skb_put(skb, status), in->rcvbuf, status); in->hisax_if->l1l2(in->hisax_if, PH_DATA | INDICATION, skb); } else if (status == -HDLC_CRC_ERROR) { INFO("CRC error"); } else if (status == -HDLC_FRAMING_ERROR) { INFO("framing error"); } else if (status == -HDLC_LENGTH_ERROR) { INFO("length error"); } } // Prepare URB for next transfer urb->dev = in->adapter->usb_dev; urb->actual_length = 0; SUBMIT_URB(urb); }
static void usb_int_complete(struct urb *urb) { u8 *data = urb->transfer_buffer; u8 irqbyte; struct st5481_adapter *adapter = urb->context; int j; int status; switch (urb->status) { case 0: break; case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: DBG(2, "urb shutting down with status: %d", urb->status); return; default: WARNING("nonzero urb status received: %d", urb->status); goto exit; } DBG_PACKET(2, data, INT_PKT_SIZE); if (urb->actual_length == 0) { goto exit; } irqbyte = data[MPINT]; if (irqbyte & DEN_INT) FsmEvent(&adapter->d_out.fsm, EV_DOUT_DEN, NULL); if (irqbyte & DCOLL_INT) FsmEvent(&adapter->d_out.fsm, EV_DOUT_COLL, NULL); irqbyte = data[FFINT_D]; if (irqbyte & OUT_UNDERRUN) FsmEvent(&adapter->d_out.fsm, EV_DOUT_UNDERRUN, NULL); if (irqbyte & OUT_DOWN) ; irqbyte = data[MPINT]; if (irqbyte & RXCI_INT) FsmEvent(&adapter->l1m, data[CCIST] & 0x0f, NULL); for (j = 0; j < 2; j++) adapter->bcs[j].b_out.flow_event |= data[FFINT_B1 + j]; urb->actual_length = 0; exit: status = usb_submit_urb(urb, GFP_ATOMIC); if (status) WARNING("usb_submit_urb failed with result %d", status); }
STATIC VOID recvproc(INT iRcvFd, INT iSndFd) { INT iRet = 0; CHAR acBuf[MAX_BUF_2048]; CHAR acBufIP[MAX_BUF_128]; INT iReplayAddrLen = 0; struct sockaddr_in stReplyAddr; struct sockaddr_in stDstAddr; STATIC ULONG g_ulSndCnt = 0; memset((CHAR*) &(stDstAddr),0, sizeof((stDstAddr))); stDstAddr.sin_family = AF_INET; stDstAddr.sin_addr.s_addr = inet_addr(g_acDestionIP); stDstAddr.sin_port = htons(g_usDestionPort); iReplayAddrLen = sizeof(stReplyAddr); memset(&stReplyAddr, 0 , sizeof(stReplyAddr)); do { iRet = recvfrom(iRcvFd, acBuf, sizeof(acBuf) - 1, 0, (struct sockaddr *)&stReplyAddr, &iReplayAddrLen); } while ((0 > iRet) && (errno == EINTR)); if (0 >= iRet) { DBG_ERROR("Receive message failed, fd %d, error:%s.\n", iRcvFd, strerror(errno)); return; } if (inet_addr(g_acLocalIP) == stReplyAddr.sin_addr.s_addr) { DBG_ERROR("Drop message received on local(%s:%hu)\n", inet_ntoa(stReplyAddr.sin_addr), ntohs(stReplyAddr.sin_port)); return; } strlcpy(acBufIP, inet_ntoa(stDstAddr.sin_addr), sizeof(acBufIP)); DBG_PACKET("%lu:Send %d length message to %s:%hu from %s:%hu\n", g_ulSndCnt++, iRet, acBufIP, ntohs(stDstAddr.sin_port), inet_ntoa(stReplyAddr.sin_addr), ntohs(stReplyAddr.sin_port)); do { iRet = sendto(iSndFd, acBuf, iRet, 0, (struct sockaddr *)&stDstAddr, sizeof(struct sockaddr_in)); } while ((0 > iRet) && (errno == EINTR)); if (0 > iRet) { DBG_ERROR("Faild to send packet to %s, error:%s\n", inet_ntoa(stDstAddr.sin_addr), strerror(errno)); return; } return; }
/* * The interrupt endpoint will be called when any * of the 6 registers changes state (depending on masks). * Decode the register values and schedule a private event. * Called at interrupt. */ static void usb_int_complete(struct urb *urb) { u_char *data = urb->transfer_buffer; u_char irqbyte; struct st5481_adapter *adapter = urb->context; int j; if (urb->status < 0) { if (urb->status != -ENOENT) { WARN("urb status %d",urb->status); urb->actual_length = 0; } else { DBG(1,"urb killed"); return; // Give up } } DBG_PACKET(1, data, INT_PKT_SIZE); if (urb->actual_length == 0) { return; } irqbyte = data[MPINT]; if (irqbyte & DEN_INT) FsmEvent(&adapter->d_out.fsm, EV_DOUT_DEN, NULL); if (irqbyte & DCOLL_INT) FsmEvent(&adapter->d_out.fsm, EV_DOUT_COLL, NULL); irqbyte = data[FFINT_D]; if (irqbyte & OUT_UNDERRUN) FsmEvent(&adapter->d_out.fsm, EV_DOUT_UNDERRUN, NULL); if (irqbyte & OUT_DOWN) ;// printk("OUT_DOWN\n"); irqbyte = data[MPINT]; if (irqbyte & RXCI_INT) FsmEvent(&adapter->l1m, data[CCIST] & 0x0f, NULL); for (j = 0; j < 2; j++) adapter->bcs[j].b_out.flow_event |= data[FFINT_B1 + j]; urb->actual_length = 0; }
static void isac_empty_fifo(struct isac *isac, int count) { // this also works for isacsx, since // CMDR(D) register works the same u_char *ptr; DBG(DBG_IRQ, "count %d", count); if ((isac->rcvidx + count) >= MAX_DFRAME_LEN_L1) { DBG(DBG_WARN, "overrun %d", isac->rcvidx + count); isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_RMC); isac->rcvidx = 0; return; } ptr = isac->rcvbuf + isac->rcvidx; isac->rcvidx += count; isac->read_isac_fifo(isac, ptr, count); isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_RMC); DBG_PACKET(DBG_RFIFO, ptr, count); }
static void rx_iso_complete(struct urb *urb) { iso_urb_struct *context_iso_urb = (iso_urb_struct *) urb->context; usb_fifo *fifo = context_iso_urb->owner_fifo; hfcusb_data *hfc = fifo->hfc; int k, len, errcode, offset, num_isoc_packets, fifon, maxlen, status; unsigned int iso_status; __u8 *buf; static __u8 eof[8]; fifon = fifo->fifonum; status = urb->status; if (urb->status == -EOVERFLOW) { DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-USB: ignoring USB DATAOVERRUN fifo(%i)", fifon); status = 0; } /* ISO transfer only partially completed, look at individual frame status for details */ if (status == -EXDEV) { DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: rx_iso_complete with -EXDEV " "urb->status %d, fifonum %d\n", status, fifon); status = 0; } if (fifo->active && !status) { num_isoc_packets = iso_packets[fifon]; maxlen = fifo->usb_packet_maxlen; for (k = 0; k < num_isoc_packets; ++k) { len = urb->iso_frame_desc[k].actual_length; offset = urb->iso_frame_desc[k].offset; buf = context_iso_urb->buffer + offset; iso_status = urb->iso_frame_desc[k].status; if (iso_status && !hfc->disc_flag) DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: rx_iso_complete " "ISO packet %i, status: %i\n", k, iso_status); if (fifon == HFCUSB_D_RX) { DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: ISO-D-RX lst_urblen:%2d " "act_urblen:%2d max-urblen:%2d EOF:0x%0x", fifo->last_urblen, len, maxlen, eof[5]); DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len); } if (fifo->last_urblen != maxlen) { /* the threshold mask is in the 2nd status byte */ hfc->threshold_mask = buf[1]; /* care for L1 state only for D-Channel to avoid overlapped iso completions */ if (fifon == HFCUSB_D_RX) { /* the S0 state is in the upper half of the 1st status byte */ s0_state_handler(hfc, buf[0] >> 4); } eof[fifon] = buf[0] & 1; if (len > 2) collect_rx_frame(fifo, buf + 2, len - 2, (len < maxlen) ? eof[fifon] : 0); } else {
static void usb_in_complete(struct urb *urb) { struct st5481_in *in = urb->context; unsigned char *ptr; struct sk_buff *skb; int len, count, status; if (unlikely(urb->status < 0)) { switch (urb->status) { case -ENOENT: case -ESHUTDOWN: case -ECONNRESET: DBG(1, "urb killed status %d", urb->status); return; default: WARNING("urb status %d", urb->status); break; } } DBG_ISO_PACKET(0x80, urb); len = st5481_isoc_flatten(urb); ptr = urb->transfer_buffer; while (len > 0) { if (in->mode == L1_MODE_TRANS) { memcpy(in->rcvbuf, ptr, len); status = len; len = 0; } else { status = isdnhdlc_decode(&in->hdlc_state, ptr, len, &count, in->rcvbuf, in->bufsize); ptr += count; len -= count; } if (status > 0) { DBG(4, "count=%d", status); DBG_PACKET(0x400, in->rcvbuf, status); if (!(skb = dev_alloc_skb(status))) { WARNING("receive out of memory\n"); break; } memcpy(skb_put(skb, status), in->rcvbuf, status); in->hisax_if->l1l2(in->hisax_if, PH_DATA | INDICATION, skb); } else if (status == -HDLC_CRC_ERROR) { INFO("CRC error"); } else if (status == -HDLC_FRAMING_ERROR) { INFO("framing error"); } else if (status == -HDLC_LENGTH_ERROR) { INFO("length error"); } } urb->dev = in->adapter->usb_dev; urb->actual_length = 0; SUBMIT_URB(urb, GFP_ATOMIC); }