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 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 */ }
void B1_handle_interrupt(avmb1_card * card) { unsigned char b1cmd; struct sk_buff *skb; unsigned ApplId; unsigned MsgLen; unsigned DataB3Len; unsigned NCCI; unsigned WindowSize; if (!B1_rx_full(card->port)) return; b1cmd = B1_get_byte(card->port); switch (b1cmd) { case RECEIVE_DATA_B3_IND: ApplId = (unsigned) B1_get_word(card->port); MsgLen = B1_get_slice(card->port, card->msgbuf); DataB3Len = B1_get_slice(card->port, card->databuf); if (showcapimsgs > 2) { __u8 cmd = CAPIMSG_COMMAND(card->msgbuf); __u8 subcmd = CAPIMSG_SUBCOMMAND(card->msgbuf); __u32 contr = CAPIMSG_CONTROL(card->msgbuf); CAPIMSG_SETDATA(card->msgbuf, card->databuf); if (showcapimsgs & 1) { printk(KERN_DEBUG "b1lli: Got [0x%lx] id#%d %s len=%u/%u\n", (unsigned long) contr, CAPIMSG_APPID(card->msgbuf), capi_cmd2str(cmd, subcmd), MsgLen, DataB3Len); } else { printk(KERN_DEBUG "b1lli: Got [0x%lx] %s\n", (unsigned long)contr, capi_message2str(card->msgbuf)); } } if (!(skb = dev_alloc_skb(DataB3Len + MsgLen))) { printk(KERN_ERR "b1lli: incoming packet dropped\n"); } else { SET_SKB_FREE(skb); memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len); CAPIMSG_SETDATA(skb->data, skb->data + MsgLen); avmb1_handle_capimsg(card, ApplId, skb); } break; case RECEIVE_MESSAGE: ApplId = (unsigned) B1_get_word(card->port); MsgLen = B1_get_slice(card->port, card->msgbuf); if (showcapimsgs) { __u8 cmd = CAPIMSG_COMMAND(card->msgbuf); __u8 subcmd = CAPIMSG_SUBCOMMAND(card->msgbuf); __u32 contr = CAPIMSG_CONTROL(card->msgbuf); if (showcapimsgs & 1) { printk(KERN_DEBUG "b1lli: Got [0x%lx] id#%d %s len=%u\n", (unsigned long) contr, CAPIMSG_APPID(card->msgbuf), capi_cmd2str(cmd, subcmd), MsgLen); } else { printk(KERN_DEBUG "b1lli: Got [0x%lx] %s\n", (unsigned long) contr, capi_message2str(card->msgbuf)); } } if (!(skb = dev_alloc_skb(MsgLen))) { printk(KERN_ERR "b1lli: incoming packet dropped\n"); } else { SET_SKB_FREE(skb); memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); avmb1_handle_capimsg(card, ApplId, skb); } break; case RECEIVE_NEW_NCCI: ApplId = B1_get_word(card->port); NCCI = B1_get_word(card->port); WindowSize = B1_get_word(card->port); if (showcapimsgs) printk(KERN_DEBUG "b1lli: NEW_NCCI app %u ncci 0x%x\n", ApplId, NCCI); avmb1_handle_new_ncci(card, ApplId, NCCI, WindowSize); break; case RECEIVE_FREE_NCCI: ApplId = B1_get_word(card->port); NCCI = B1_get_word(card->port); if (showcapimsgs) printk(KERN_DEBUG "b1lli: FREE_NCCI app %u ncci 0x%x\n", ApplId, NCCI); avmb1_handle_free_ncci(card, ApplId, NCCI); break; case RECEIVE_START: if (card->blocked) printk(KERN_DEBUG "b1lli: RESTART\n"); card->blocked = 0; break; case RECEIVE_STOP: printk(KERN_DEBUG "b1lli: STOP\n"); card->blocked = 1; break; case RECEIVE_INIT: card->versionlen = B1_get_slice(card->port, card->versionbuf); card->cardstate = CARD_ACTIVE; parse_version(card); printk(KERN_INFO "b1lli: %s-card (%s) with %s now active\n", card->version[VER_CARDTYPE], card->version[VER_DRIVER], card->version[VER_PROTO]); avmb1_card_ready(card); break; default: printk(KERN_ERR "b1lli: B1_handle_interrupt: 0x%x ???\n", b1cmd); break; } }