static __u16 capi_put_message(__u16 applid, struct sk_buff *skb) { struct capi_ncci *np; __u32 contr; int showctl = 0; __u8 cmd, subcmd; if (ncards == 0) return CAPI_REGNOTINSTALLED; if (!VALID_APPLID(applid)) return CAPI_ILLAPPNR; if (skb->len < 12 || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data)) || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data))) return CAPI_ILLCMDORSUBCMDORMSGTOSMALL; contr = CAPIMSG_CONTROLLER(skb->data); if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) { contr = 1; if (CARD(contr)->cardstate != CARD_RUNNING) return CAPI_REGNOTINSTALLED; } if (CARD(contr)->blocked) return CAPI_SENDQUEUEFULL; cmd = CAPIMSG_COMMAND(skb->data); subcmd = CAPIMSG_SUBCOMMAND(skb->data); if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) { if ((np = find_ncci(APPL(applid), CAPIMSG_NCCI(skb->data))) != 0 && mq_enqueue(np, CAPIMSG_MSGID(skb->data)) == 0) return CAPI_SENDQUEUEFULL; CARD(contr)->nsentdatapkt++; APPL(applid)->nsentdatapkt++; if (CARD(contr)->traceflag > 2) showctl |= 2; } else { CARD(contr)->nsentctlpkt++; APPL(applid)->nsentctlpkt++; if (CARD(contr)->traceflag) showctl |= 2; } showctl |= (CARD(contr)->traceflag & 1); if (showctl & 2) { if (showctl & 1) { printk(KERN_DEBUG "kcapi: put [0x%lx] id#%d %s len=%u\n", (unsigned long) contr, CAPIMSG_APPID(skb->data), capi_cmd2str(cmd, subcmd), CAPIMSG_LEN(skb->data)); } else { printk(KERN_DEBUG "kcapi: put [0x%lx] %s\n", (unsigned long) contr, capi_message2str(skb->data)); } } CARD(contr)->driver->send_message(CARD(contr), skb); return CAPI_NOERROR; }
u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb) { struct capi_ctr *card; int showctl = 0; u8 cmd, subcmd; DBG("applid %#x", ap->applid); if (ncards == 0) return CAPI_REGNOTINSTALLED; if (ap->applid == 0) return CAPI_ILLAPPNR; if (skb->len < 12 || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data)) || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data))) return CAPI_ILLCMDORSUBCMDORMSGTOSMALL; card = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data)); if (!card || card->cardstate != CARD_RUNNING) { card = get_capi_ctr_by_nr(1); // XXX why? if (!card || card->cardstate != CARD_RUNNING) return CAPI_REGNOTINSTALLED; } if (card->blocked) return CAPI_SENDQUEUEFULL; cmd = CAPIMSG_COMMAND(skb->data); subcmd = CAPIMSG_SUBCOMMAND(skb->data); if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) { card->nsentdatapkt++; ap->nsentdatapkt++; if (card->traceflag > 2) showctl |= 2; } else { card->nsentctlpkt++; ap->nsentctlpkt++; if (card->traceflag) showctl |= 2; } showctl |= (card->traceflag & 1); if (showctl & 2) { if (showctl & 1) { printk(KERN_DEBUG "kcapi: put [%#x] id#%d %s len=%u\n", CAPIMSG_CONTROLLER(skb->data), CAPIMSG_APPID(skb->data), capi_cmd2str(cmd, subcmd), CAPIMSG_LEN(skb->data)); } else { printk(KERN_DEBUG "kcapi: put [%#x] %s\n", CAPIMSG_CONTROLLER(skb->data), capi_message2str(skb->data)); } } return card->send_message(card, skb); }
static void b1dma_dispatch_tx(avmcard *card) { avmcard_dmainfo *dma = card->dma; struct sk_buff *skb; u8 cmd, subcmd; u16 len; u32 txlen; void *p; skb = skb_dequeue(&dma->send_queue); len = CAPIMSG_LEN(skb->data); if (len) { cmd = CAPIMSG_COMMAND(skb->data); subcmd = CAPIMSG_SUBCOMMAND(skb->data); p = dma->sendbuf.dmabuf; if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { u16 dlen = CAPIMSG_DATALEN(skb->data); _put_byte(&p, SEND_DATA_B3_REQ); _put_slice(&p, skb->data, len); _put_slice(&p, skb->data + len, dlen); } else { _put_byte(&p, SEND_MESSAGE); _put_slice(&p, skb->data, len); } txlen = (u8 *)p - (u8 *)dma->sendbuf.dmabuf; #ifdef AVM_B1DMA_DEBUG printk(KERN_DEBUG "tx: put msg len=%d\n", txlen); #endif } else { txlen = skb->len - 2; #ifdef AVM_B1DMA_POLLDEBUG if (skb->data[2] == SEND_POLLACK) printk(KERN_INFO "%s: send ack\n", card->name); #endif #ifdef AVM_B1DMA_DEBUG printk(KERN_DEBUG "tx: put 0x%x len=%d\n", skb->data[2], txlen); #endif skb_copy_from_linear_data_offset(skb, 2, dma->sendbuf.dmabuf, skb->len - 2); } txlen = (txlen + 3) & ~3; b1dma_writel(card, dma->sendbuf.dmaaddr, AMCC_TXPTR); b1dma_writel(card, txlen, AMCC_TXLEN); card->csr |= EN_TX_TC_INT; dev_kfree_skb_any(skb); }
void hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) { __u16 appl_id; int _len, _len2; __u8 msghead[64]; appl_id = CAPIMSG_APPID(skb->data); switch(_hycapi_appCheck(appl_id, ctrl->cnr)) { case 0: /* printk(KERN_INFO "Need to register\n"); */ hycapi_register_internal(ctrl, appl_id, &(hycapi_applications[appl_id-1].rp)); break; case 1: break; default: printk(KERN_ERR "HYCAPI: Controller mixup!\n"); return; } switch(CAPIMSG_CMD(skb->data)) { case CAPI_DISCONNECT_B3_RESP: ctrl->free_ncci(ctrl, appl_id, CAPIMSG_NCCI(skb->data)); break; case CAPI_DATA_B3_REQ: _len = CAPIMSG_LEN(skb->data); if (_len > 22) { _len2 = _len - 22; memcpy(msghead, skb->data, 22); memcpy(skb->data + _len2, msghead, 22); skb_pull(skb, _len2); CAPIMSG_SETLEN(skb->data, 22); } break; case CAPI_LISTEN_REQ: if(hycapi_applications[appl_id-1].listen_req[ctrl->cnr-1]) { kfree_skb(hycapi_applications[appl_id-1].listen_req[ctrl->cnr-1]); hycapi_applications[appl_id-1].listen_req[ctrl->cnr-1] = NULL; } if (!(hycapi_applications[appl_id-1].listen_req[ctrl->cnr-1] = skb_copy(skb, GFP_ATOMIC))) { printk(KERN_ERR "HYSDN: memory squeeze in private_listen\n"); } break; default: break; } hycapi_sendmsg_internal(ctrl, skb); }
static void iavc_start_tx(iavc_softc_t *sc) { struct mbuf *m; u_int32_t txlen; /* If device has put us on hold, punt. */ if (sc->sc_blocked) { return; } /* If using DMA and transmitter busy, punt. */ if (sc->sc_dma && (sc->sc_csr & EN_TX_TC_INT)) { return; } /* Else, see if we have messages to send. */ IF_DEQUEUE(&sc->sc_txq, m); if (!m) { return; } /* Have message, will send. */ if (CAPIMSG_LEN(m->m_data)) { /* A proper CAPI message, possibly with B3 data */ txlen = iavc_tx_capimsg(sc, m); } else { /* A board control message to be sent as is */ txlen = iavc_tx_ctrlmsg(sc, m); } if (m->m_next) { i4b_Bfreembuf(m->m_next); m->m_next = NULL; } i4b_Dfreembuf(m); /* Kick DMA into motion if applicable */ if (sc->sc_dma) { txlen = (txlen + 3) & ~3; bus_dmamap_sync(sc->dmat, sc->tx_map, 0, txlen, BUS_DMASYNC_PREWRITE); AMCC_WRITE(sc, AMCC_TXPTR, sc->tx_map->dm_segs[0].ds_addr); AMCC_WRITE(sc, AMCC_TXLEN, txlen); sc->sc_csr |= EN_TX_TC_INT; if (!sc->sc_intr) AMCC_WRITE(sc, AMCC_INTCSR, sc->sc_csr); } }
void B1_send_message(unsigned short port, struct sk_buff *skb) { unsigned long flags; __u16 len = CAPIMSG_LEN(skb->data); __u8 cmd = CAPIMSG_COMMAND(skb->data); __u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data); __u32 contr = CAPIMSG_CONTROL(skb->data); if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { __u16 dlen = CAPIMSG_DATALEN(skb->data); if (showcapimsgs > 2) { if (showcapimsgs & 1) { printk(KERN_DEBUG "b1lli: Put [0x%lx] id#%d %s len=%u\n", (unsigned long) contr, CAPIMSG_APPID(skb->data), capi_cmd2str(cmd, subcmd), len); } else { printk(KERN_DEBUG "b1lli: Put [0x%lx] %s\n", (unsigned long) contr, capi_message2str(skb->data)); } } save_flags(flags); cli(); B1_put_byte(port, SEND_DATA_B3_REQ); B1_put_slice(port, skb->data, len); B1_put_slice(port, skb->data + len, dlen); restore_flags(flags); } else { if (showcapimsgs) { if (showcapimsgs & 1) { printk(KERN_DEBUG "b1lli: Put [0x%lx] id#%d %s len=%u\n", (unsigned long) contr, CAPIMSG_APPID(skb->data), capi_cmd2str(cmd, subcmd), len); } else { printk(KERN_DEBUG "b1lli: Put [0x%lx] %s\n", (unsigned long)contr, capi_message2str(skb->data)); } } save_flags(flags); cli(); B1_put_byte(port, SEND_MESSAGE); B1_put_slice(port, skb->data, len); restore_flags(flags); } dev_kfree_skb(skb, FREE_WRITE); }
static ssize_t capi_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { struct capidev *cdev = (struct capidev *)file->private_data; struct sk_buff *skb; int retval; __u16 mlen; if (ppos != &file->f_pos) return -ESPIPE; if (!cdev->applid) return -ENODEV; skb = alloc_skb(count, GFP_USER); if (!skb) return -ENOMEM; if ((retval = copy_from_user(skb_put(skb, count), buf, count))) { kfree_skb(skb); return -EFAULT; } mlen = CAPIMSG_LEN(skb->data); if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { if (mlen + CAPIMSG_DATALEN(skb->data) != count) { kfree_skb(skb); return -EINVAL; } } else { if (mlen != count) { kfree_skb(skb); return -EINVAL; } } CAPIMSG_SETAPPID(skb->data, cdev->applid); cdev->errcode = (*capifuncs->capi_put_message) (cdev->applid, skb); if (cdev->errcode) { kfree_skb(skb); return -EIO; } if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { cdev->nsentdatapkt++; } else { cdev->nsentctlpkt++; } return count; }
static long capi_read(struct inode *inode, struct file *file, char *buf, unsigned long count) #endif { unsigned int minor = MINOR(inode->i_rdev); struct capidev *cdev; struct sk_buff *skb; int retval; size_t copied; if (!minor || minor > CAPI_MAXMINOR || !capidevs[minor].is_registered) return -ENODEV; cdev = &capidevs[minor]; if ((skb = skb_dequeue(&cdev->recv_queue)) == 0) { if (file->f_flags & O_NONBLOCK) return -EAGAIN; for (;;) { interruptible_sleep_on(&cdev->recv_wait); if ((skb = skb_dequeue(&cdev->recv_queue)) != 0) break; if (current->signal & ~current->blocked) break; } if (skb == 0) return -ERESTARTNOHAND; } if (skb->len > count) { skb_queue_head(&cdev->recv_queue, skb); return -EMSGSIZE; } if (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3 && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) CAPIMSG_SETDATA(skb->data, buf + CAPIMSG_LEN(skb->data)); retval = copy_to_user(buf, skb->data, skb->len); if (retval) { skb_queue_head(&cdev->recv_queue, skb); return retval; } copied = skb->len; kfree_skb(skb, FREE_READ); return copied; }
static long capi_write(struct inode *inode, struct file *file, const char *buf, unsigned long count) #endif { unsigned int minor = MINOR(inode->i_rdev); struct capidev *cdev; struct sk_buff *skb; int retval; __u8 cmd; __u8 subcmd; __u16 mlen; if (!minor || minor > CAPI_MAXMINOR || !capidevs[minor].is_registered) return -ENODEV; cdev = &capidevs[minor]; skb = alloc_skb(count, GFP_USER); if ((retval = copy_from_user(skb_put(skb, count), buf, count))) { dev_kfree_skb(skb, FREE_WRITE); return retval; } cmd = CAPIMSG_COMMAND(skb->data); subcmd = CAPIMSG_SUBCOMMAND(skb->data); mlen = CAPIMSG_LEN(skb->data); if (cmd == CAPI_DATA_B3 && subcmd == CAPI_REQ) { __u16 dlen = CAPIMSG_DATALEN(skb->data); if (mlen + dlen != count) { dev_kfree_skb(skb, FREE_WRITE); return -EINVAL; } } else if (mlen != count) { dev_kfree_skb(skb, FREE_WRITE); return -EINVAL; } CAPIMSG_SETAPPID(skb->data, cdev->applid); cdev->errcode = (*capifuncs->capi_put_message) (cdev->applid, skb); if (cdev->errcode) { dev_kfree_skb(skb, FREE_WRITE); return -EIO; } return count; }
static void controllercb_handle_capimsg(struct capi_ctr * card, __u16 appl, struct sk_buff *skb) { int showctl = 0; __u8 cmd, subcmd; if (card->cardstate != CARD_RUNNING) { printk(KERN_INFO "kcapi: controller %d not active, got: %s", card->cnr, capi_message2str(skb->data)); goto error; } cmd = CAPIMSG_COMMAND(skb->data); subcmd = CAPIMSG_SUBCOMMAND(skb->data); if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) { card->nrecvdatapkt++; if (card->traceflag > 2) showctl |= 2; } else { card->nrecvctlpkt++; if (card->traceflag) showctl |= 2; } showctl |= (card->traceflag & 1); if (showctl & 2) { if (showctl & 1) { printk(KERN_DEBUG "kcapi: got [0x%lx] id#%d %s len=%u\n", (unsigned long) card->cnr, CAPIMSG_APPID(skb->data), capi_cmd2str(cmd, subcmd), CAPIMSG_LEN(skb->data)); } else { printk(KERN_DEBUG "kcapi: got [0x%lx] %s\n", (unsigned long) card->cnr, capi_message2str(skb->data)); } } skb_queue_tail(&recv_queue, skb); queue_task(&tq_recv_notify, &tq_immediate); mark_bh(IMMEDIATE_BH); return; error: kfree_skb(skb); }
void hycapi_rx_capipkt(hysdn_card *card, unsigned char *buf, unsigned short len) { struct sk_buff *skb; hycapictrl_info *cinfo = card->hyctrlinfo; struct capi_ctr *ctrl; __u16 ApplId; __u16 MsgLen, info; __u16 len2, CapiCmd; __u32 CP64[2] = {0, 0}; #ifdef HYCAPI_PRINTFNAMES printk(KERN_NOTICE "hycapi_rx_capipkt\n"); #endif if (!cinfo) { return; } ctrl = &cinfo->capi_ctrl; if (len < CAPI_MSG_BASELEN) { printk(KERN_ERR "HYSDN Card%d: invalid CAPI-message, length %d!\n", card->myid, len); return; } MsgLen = CAPIMSG_LEN(buf); ApplId = CAPIMSG_APPID(buf); CapiCmd = CAPIMSG_CMD(buf); if ((CapiCmd == CAPI_DATA_B3_IND) && (MsgLen < 30)) { len2 = len + (30 - MsgLen); if (!(skb = alloc_skb(len2, GFP_ATOMIC))) { printk(KERN_ERR "HYSDN Card%d: incoming packet dropped\n", card->myid); return; } memcpy(skb_put(skb, MsgLen), buf, MsgLen); memcpy(skb_put(skb, 2 * sizeof(__u32)), CP64, 2 * sizeof(__u32)); memcpy(skb_put(skb, len - MsgLen), buf + MsgLen, len - MsgLen); CAPIMSG_SETLEN(skb->data, 30); } else { if (!(skb = alloc_skb(len, GFP_ATOMIC))) { printk(KERN_ERR "HYSDN Card%d: incoming packet dropped\n", card->myid); return; } memcpy(skb_put(skb, len), buf, len); } switch (CAPIMSG_CMD(skb->data)) { case CAPI_CONNECT_B3_CONF: /* Check info-field for error-indication: */ info = CAPIMSG_U16(skb->data, 12); switch (info) { case 0: capilib_new_ncci(&cinfo->ncci_head, ApplId, CAPIMSG_NCCI(skb->data), hycapi_applications[ApplId - 1].rp.datablkcnt); break; case 0x0001: printk(KERN_ERR "HYSDN Card%d: NCPI not supported by current " "protocol. NCPI ignored.\n", card->myid); break; case 0x2001: printk(KERN_ERR "HYSDN Card%d: Message not supported in" " current state\n", card->myid); break; case 0x2002: printk(KERN_ERR "HYSDN Card%d: invalid PLCI\n", card->myid); break; case 0x2004: printk(KERN_ERR "HYSDN Card%d: out of NCCI\n", card->myid); break; case 0x3008: printk(KERN_ERR "HYSDN Card%d: NCPI not supported\n", card->myid); break; default: printk(KERN_ERR "HYSDN Card%d: Info in CONNECT_B3_CONF: %d\n", card->myid, info); break; } break; case CAPI_CONNECT_B3_IND: capilib_new_ncci(&cinfo->ncci_head, ApplId, CAPIMSG_NCCI(skb->data), hycapi_applications[ApplId - 1].rp.datablkcnt); break; case CAPI_DATA_B3_CONF: capilib_data_b3_conf(&cinfo->ncci_head, ApplId, CAPIMSG_NCCI(skb->data), CAPIMSG_MSGID(skb->data)); break; default: break; } capi_ctr_handle_message(ctrl, ApplId, skb); }
static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) { __u16 appl_id; int _len, _len2; __u8 msghead[64]; hycapictrl_info *cinfo = ctrl->driverdata; u16 retval = CAPI_NOERROR; appl_id = CAPIMSG_APPID(skb->data); switch (_hycapi_appCheck(appl_id, ctrl->cnr)) { case 0: /* printk(KERN_INFO "Need to register\n"); */ hycapi_register_internal(ctrl, appl_id, &(hycapi_applications[appl_id - 1].rp)); break; case 1: break; default: printk(KERN_ERR "HYCAPI: Controller mixup!\n"); retval = CAPI_ILLAPPNR; goto out; } switch (CAPIMSG_CMD(skb->data)) { case CAPI_DISCONNECT_B3_RESP: capilib_free_ncci(&cinfo->ncci_head, appl_id, CAPIMSG_NCCI(skb->data)); break; case CAPI_DATA_B3_REQ: _len = CAPIMSG_LEN(skb->data); if (_len > 22) { _len2 = _len - 22; skb_copy_from_linear_data(skb, msghead, 22); skb_copy_to_linear_data_offset(skb, _len2, msghead, 22); skb_pull(skb, _len2); CAPIMSG_SETLEN(skb->data, 22); retval = capilib_data_b3_req(&cinfo->ncci_head, CAPIMSG_APPID(skb->data), CAPIMSG_NCCI(skb->data), CAPIMSG_MSGID(skb->data)); } break; case CAPI_LISTEN_REQ: if (hycapi_applications[appl_id - 1].listen_req[ctrl->cnr - 1]) { kfree_skb(hycapi_applications[appl_id - 1].listen_req[ctrl->cnr - 1]); hycapi_applications[appl_id - 1].listen_req[ctrl->cnr - 1] = NULL; } if (!(hycapi_applications[appl_id -1].listen_req[ctrl->cnr - 1] = skb_copy(skb, GFP_ATOMIC))) { printk(KERN_ERR "HYSDN: memory squeeze in private_listen\n"); } break; default: break; } out: if (retval == CAPI_NOERROR) hycapi_sendmsg_internal(ctrl, skb); else dev_kfree_skb_any(skb); return retval; }
static void iavc_start_tx(iavc_softc_t *sc) { struct mbuf *m; u_int8_t *dmabuf; u_int32_t txlen = 0; /* If device has put us on hold, punt. */ if (sc->sc_blocked) { return; } /* If using DMA and transmitter busy, punt. */ if (sc->sc_dma && (sc->sc_csr & EN_TX_TC_INT)) { return; } /* Else, see if we have messages to send. */ _IF_DEQUEUE(&sc->sc_txq, m); if (!m) { return; } /* Have message, will send. */ if (CAPIMSG_LEN(m->m_data)) { /* A proper CAPI message, possibly with B3 data */ if (sc->sc_dma) { /* Copy message to DMA buffer. */ if (m->m_next) { dmabuf = amcc_put_byte(&sc->sc_sendbuf[0], SEND_DATA_B3_REQ); } else { dmabuf = amcc_put_byte(&sc->sc_sendbuf[0], SEND_MESSAGE); } dmabuf = amcc_put_word(dmabuf, m->m_len); bcopy(m->m_data, dmabuf, m->m_len); dmabuf += m->m_len; txlen = 5 + m->m_len; if (m->m_next) { dmabuf = amcc_put_word(dmabuf, m->m_next->m_len); bcopy(m->m_next->m_data, dmabuf, m->m_next->m_len); txlen += 4 + m->m_next->m_len; } } else { /* Use PIO. */ if (m->m_next) { iavc_put_byte(sc, SEND_DATA_B3_REQ); NDBGL4(L4_IAVCDBG, "iavc%d: tx SDB3R msg, len = %d", sc->sc_unit, m->m_len); } else { iavc_put_byte(sc, SEND_MESSAGE); NDBGL4(L4_IAVCDBG, "iavc%d: tx SM msg, len = %d", sc->sc_unit, m->m_len); } #if 0 { u_int8_t *p = mtod(m, u_int8_t*); int len; for (len = 0; len < m->m_len; len++) { printf(" %02x", *p++); if (len && (len % 16) == 0) printf("\n"); } if (len % 16) printf("\n"); } #endif iavc_put_slice(sc, m->m_data, m->m_len); if (m->m_next) { iavc_put_slice(sc, m->m_next->m_data, m->m_next->m_len); } } } else { /* A board control message to be sent as is */ if (sc->sc_dma) {
static void c4_dispatch_tx(avmcard *card) { avmcard_dmainfo *dma = card->dma; struct sk_buff *skb; u8 cmd, subcmd; u16 len; u32 txlen; void *p; if (card->csr & DBELL_DOWN_ARM) { /* tx busy */ return; } skb = skb_dequeue(&dma->send_queue); if (!skb) { #ifdef AVM_C4_DEBUG printk(KERN_DEBUG "%s: tx underrun\n", card->name); #endif return; } len = CAPIMSG_LEN(skb->data); if (len) { cmd = CAPIMSG_COMMAND(skb->data); subcmd = CAPIMSG_SUBCOMMAND(skb->data); p = dma->sendbuf.dmabuf; if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { u16 dlen = CAPIMSG_DATALEN(skb->data); _put_byte(&p, SEND_DATA_B3_REQ); _put_slice(&p, skb->data, len); _put_slice(&p, skb->data + len, dlen); } else { _put_byte(&p, SEND_MESSAGE); _put_slice(&p, skb->data, len); } txlen = (u8 *)p - (u8 *)dma->sendbuf.dmabuf; #ifdef AVM_C4_DEBUG printk(KERN_DEBUG "%s: tx put msg len=%d\n", card->name, txlen); #endif } else { txlen = skb->len-2; #ifdef AVM_C4_POLLDEBUG if (skb->data[2] == SEND_POLLACK) printk(KERN_INFO "%s: ack to c4\n", card->name); #endif #ifdef AVM_C4_DEBUG printk(KERN_DEBUG "%s: tx put 0x%x len=%d\n", card->name, skb->data[2], txlen); #endif skb_copy_from_linear_data_offset(skb, 2, dma->sendbuf.dmabuf, skb->len - 2); } txlen = (txlen + 3) & ~3; c4outmeml(card->mbase+MBOX_DOWN_ADDR, dma->sendbuf.dmaaddr); c4outmeml(card->mbase+MBOX_DOWN_LEN, txlen); card->csr |= DBELL_DOWN_ARM; c4outmeml(card->mbase+DOORBELL, DBELL_DOWN_ARM); dev_kfree_skb_any(skb); }
int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb) { struct sk_buff *nskb; unsigned int datalen; __u16 errcode, datahandle; datalen = skb->len - CAPIMSG_LEN(skb->data); if (mp->tty) { if (mp->tty->ldisc.receive_buf == 0) { printk(KERN_ERR "capi: ldisc has no receive_buf function\n"); return -1; } if (mp->ttyinstop) { #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) printk(KERN_DEBUG "capi: recv tty throttled\n"); #endif return -1; } if (mp->tty->ldisc.receive_room && mp->tty->ldisc.receive_room(mp->tty) < datalen) { #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) printk(KERN_DEBUG "capi: no room in tty\n"); #endif return -1; } if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) { printk(KERN_ERR "capi: gen_data_b3_resp failed\n"); return -1; } datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4); errcode = (*capifuncs->capi_put_message)(mp->applid, nskb); if (errcode != CAPI_NOERROR) { printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n", errcode); kfree_skb(nskb); return -1; } (void)skb_pull(skb, CAPIMSG_LEN(skb->data)); #ifdef _DEBUG_DATAFLOW printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n", datahandle, skb->len); #endif mp->tty->ldisc.receive_buf(mp->tty, skb->data, 0, skb->len); kfree_skb(skb); return 0; } else if (mp->file) { if (skb_queue_len(&mp->recvqueue) > CAPINC_MAX_RECVQUEUE) { #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) printk(KERN_DEBUG "capi: no room in raw queue\n"); #endif return -1; } if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) { printk(KERN_ERR "capi: gen_data_b3_resp failed\n"); return -1; } datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4); errcode = (*capifuncs->capi_put_message)(mp->applid, nskb); if (errcode != CAPI_NOERROR) { printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n", errcode); kfree_skb(nskb); return -1; } (void)skb_pull(skb, CAPIMSG_LEN(skb->data)); #ifdef _DEBUG_DATAFLOW printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => raw\n", datahandle, skb->len); #endif skb_queue_tail(&mp->recvqueue, skb); wake_up_interruptible(&mp->recvwait); return 0; } #ifdef _DEBUG_DATAFLOW printk(KERN_DEBUG "capi: currently no receiver\n"); #endif return -1; }
static void b1dma_dispatch_tx(avmcard *card) { avmcard_dmainfo *dma = card->dma; unsigned long flags; struct sk_buff *skb; __u8 cmd, subcmd; __u16 len; __u32 txlen; int inint; void *p; save_flags(flags); cli(); inint = card->interrupt; if (card->csr & EN_TX_TC_INT) { /* tx busy */ restore_flags(flags); return; } skb = skb_dequeue(&dma->send_queue); if (!skb) { #ifdef CONFIG_B1DMA_DEBUG printk(KERN_DEBUG "tx(%d): underrun\n", inint); #endif restore_flags(flags); return; } len = CAPIMSG_LEN(skb->data); if (len) { cmd = CAPIMSG_COMMAND(skb->data); subcmd = CAPIMSG_SUBCOMMAND(skb->data); p = dma->sendbuf; if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { __u16 dlen = CAPIMSG_DATALEN(skb->data); _put_byte(&p, SEND_DATA_B3_REQ); _put_slice(&p, skb->data, len); _put_slice(&p, skb->data + len, dlen); } else { _put_byte(&p, SEND_MESSAGE); _put_slice(&p, skb->data, len); } txlen = (__u8 *)p - (__u8 *)dma->sendbuf; #ifdef CONFIG_B1DMA_DEBUG printk(KERN_DEBUG "tx(%d): put msg len=%d\n", inint, txlen); #endif } else { txlen = skb->len-2; #ifdef CONFIG_B1DMA_POLLDEBUG if (skb->data[2] == SEND_POLLACK) printk(KERN_INFO "%s: send ack\n", card->name); #endif #ifdef CONFIG_B1DMA_DEBUG printk(KERN_DEBUG "tx(%d): put 0x%x len=%d\n", inint, skb->data[2], txlen); #endif memcpy(dma->sendbuf, skb->data+2, skb->len-2); } txlen = (txlen + 3) & ~3; b1dmaoutmeml(card->mbase+AMCC_TXPTR, virt_to_phys(dma->sendbuf)); b1dmaoutmeml(card->mbase+AMCC_TXLEN, txlen); card->csr |= EN_TX_TC_INT; if (!inint) b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr); restore_flags(flags); dev_kfree_skb_any(skb); }
static void capi_signal(__u16 applid, void *param) { struct capidev *cdev = (struct capidev *)param; #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE struct capiminor *mp; __u16 datahandle; #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ struct capincci *np; struct sk_buff *skb = 0; __u32 ncci; (void) (*capifuncs->capi_get_message) (applid, &skb); if (!skb) { printk(KERN_ERR "BUG: capi_signal: no skb\n"); return; } if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) { skb_queue_tail(&cdev->recvqueue, skb); wake_up_interruptible(&cdev->recvwait); return; } ncci = CAPIMSG_CONTROL(skb->data); for (np = cdev->nccis; np && np->ncci != ncci; np = np->next) ; if (!np) { printk(KERN_ERR "BUG: capi_signal: ncci not found\n"); skb_queue_tail(&cdev->recvqueue, skb); wake_up_interruptible(&cdev->recvwait); return; } #ifndef CONFIG_ISDN_CAPI_MIDDLEWARE skb_queue_tail(&cdev->recvqueue, skb); wake_up_interruptible(&cdev->recvwait); #else /* CONFIG_ISDN_CAPI_MIDDLEWARE */ mp = np->minorp; if (!mp) { skb_queue_tail(&cdev->recvqueue, skb); wake_up_interruptible(&cdev->recvwait); return; } if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) { datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2); #ifdef _DEBUG_DATAFLOW printk(KERN_DEBUG "capi_signal: DATA_B3_IND %u len=%d\n", datahandle, skb->len-CAPIMSG_LEN(skb->data)); #endif skb_queue_tail(&mp->inqueue, skb); mp->inbytes += skb->len; handle_minor_recv(mp); } else if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF) { datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4); #ifdef _DEBUG_DATAFLOW printk(KERN_DEBUG "capi_signal: DATA_B3_CONF %u 0x%x\n", datahandle, CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+2)); #endif kfree_skb(skb); (void)capiminor_del_ack(mp, datahandle); if (mp->tty) { if (mp->tty->ldisc.write_wakeup) mp->tty->ldisc.write_wakeup(mp->tty); } else { wake_up_interruptible(&mp->sendwait); } (void)handle_minor_send(mp); } else { /* ups, let capi application handle it :-) */ skb_queue_tail(&cdev->recvqueue, skb); wake_up_interruptible(&cdev->recvwait); } #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ }
static void c4_dispatch_tx(avmcard *card) { avmcard_dmainfo *dma = card->dma; unsigned long flags; struct sk_buff *skb; __u8 cmd, subcmd; __u16 len; __u32 txlen; void *p; save_flags(flags); cli(); if (card->csr & DBELL_DOWN_ARM) { /* tx busy */ restore_flags(flags); return; } skb = skb_dequeue(&dma->send_queue); if (!skb) { #ifdef CONFIG_C4_DEBUG printk(KERN_DEBUG "%s: tx underrun\n", card->name); #endif restore_flags(flags); return; } len = CAPIMSG_LEN(skb->data); if (len) { cmd = CAPIMSG_COMMAND(skb->data); subcmd = CAPIMSG_SUBCOMMAND(skb->data); p = dma->sendbuf; if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { __u16 dlen = CAPIMSG_DATALEN(skb->data); _put_byte(&p, SEND_DATA_B3_REQ); _put_slice(&p, skb->data, len); _put_slice(&p, skb->data + len, dlen); } else { _put_byte(&p, SEND_MESSAGE); _put_slice(&p, skb->data, len); } txlen = (__u8 *)p - (__u8 *)dma->sendbuf; #ifdef CONFIG_C4_DEBUG printk(KERN_DEBUG "%s: tx put msg len=%d\n", card->name, txlen); #endif } else { txlen = skb->len-2; #ifdef CONFIG_C4_POLLDEBUG if (skb->data[2] == SEND_POLLACK) printk(KERN_INFO "%s: ack to c4\n", card->name); #endif #ifdef CONFIG_C4_DEBUG printk(KERN_DEBUG "%s: tx put 0x%x len=%d\n", card->name, skb->data[2], txlen); #endif memcpy(dma->sendbuf, skb->data+2, skb->len-2); } txlen = (txlen + 3) & ~3; c4outmeml(card->mbase+MBOX_DOWN_ADDR, virt_to_phys(dma->sendbuf)); c4outmeml(card->mbase+MBOX_DOWN_LEN, txlen); card->csr |= DBELL_DOWN_ARM; c4outmeml(card->mbase+DOORBELL, DBELL_DOWN_ARM); restore_flags(flags); dev_kfree_skb_any(skb); }