inline void modem_fill(struct BCState *bcs) { if (bcs->tx_skb) { if (bcs->tx_skb->len) { write_modem(bcs); return; } else { if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count); dev_kfree_skb_any(bcs->tx_skb); bcs->tx_skb = NULL; } } if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { bcs->hw.hscx.count = 0; test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); write_modem(bcs); } else { test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); hscx_sched_event(bcs, B_XMTBUFREADY); } }
static inline void receive_chars(struct IsdnCardState *cs, int *status) { unsigned char ch; struct sk_buff *skb; do { ch = serial_in(cs, UART_RX); if (cs->hw.elsa.rcvcnt >= MAX_MODEM_BUF) break; cs->hw.elsa.rcvbuf[cs->hw.elsa.rcvcnt++] = ch; #ifdef SERIAL_DEBUG_INTR printk("DR%02x:%02x...", ch, *status); #endif if (*status & (UART_LSR_BI | UART_LSR_PE | UART_LSR_FE | UART_LSR_OE)) { #ifdef SERIAL_DEBUG_INTR printk("handling exept...."); #endif } *status = serial_inp(cs, UART_LSR); } while (*status & UART_LSR_DR); if (cs->hw.elsa.MFlag == 2) { if (!(skb = dev_alloc_skb(cs->hw.elsa.rcvcnt))) printk(KERN_WARNING "ElsaSER: receive out of memory\n"); else { memcpy(skb_put(skb, cs->hw.elsa.rcvcnt), cs->hw.elsa.rcvbuf, cs->hw.elsa.rcvcnt); skb_queue_tail(& cs->hw.elsa.bcs->rqueue, skb); } hscx_sched_event(cs->hw.elsa.bcs, B_RCVBUFREADY); } else { char tmp[128]; char *t = tmp; t += sprintf(t, "modem read cnt %d", cs->hw.elsa.rcvcnt); QuickHex(t, cs->hw.elsa.rcvbuf, cs->hw.elsa.rcvcnt); debugl1(cs, tmp); } cs->hw.elsa.rcvcnt = 0; }
static inline void hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx) { u_char r; struct BCState *bcs = cs->bcs + hscx; struct sk_buff *skb; int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32; int count; if (!test_bit(BC_FLG_INIT, &bcs->Flag)) return; if (val & 0x80) { /* RME */ r = READHSCX(cs, hscx, HSCX_RSTA); if ((r & 0xf0) != 0xa0) { if (!(r & 0x80)) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX invalid frame"); #ifdef ERROR_STATISTIC bcs->err_inv++; #endif } if ((r & 0x40) && bcs->mode) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX RDO mode=%d", bcs->mode); #ifdef ERROR_STATISTIC bcs->err_rdo++; #endif } if (!(r & 0x20)) { if (cs->debug & L1_DEB_WARN) debugl1(cs, "HSCX CRC error"); #ifdef ERROR_STATISTIC bcs->err_crc++; #endif } WriteHSCXCMDR(cs, hscx, 0x80); } else { count = READHSCX(cs, hscx, HSCX_RBCL) & ( test_bit(HW_IPAC, &cs->HW_Flags)? 0x3f: 0x1f); if (count == 0) count = fifo_size; hscx_empty_fifo(bcs, count); if ((count = bcs->hw.hscx.rcvidx - 1) > 0) { if (cs->debug & L1_DEB_HSCX_FIFO) debugl1(cs, "HX Frame %d", count); if (!(skb = dev_alloc_skb(count))) printk(KERN_WARNING "HSCX: receive out of memory\n"); else { memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count); skb_queue_tail(&bcs->rqueue, skb); } } } bcs->hw.hscx.rcvidx = 0; hscx_sched_event(bcs, B_RCVBUFREADY); } if (val & 0x40) { /* RPF */ hscx_empty_fifo(bcs, fifo_size); if (bcs->mode == L1_MODE_TRANS) { /* receive audio data */ if (!(skb = dev_alloc_skb(fifo_size))) printk(KERN_WARNING "HiSax: receive out of memory\n"); else { memcpy(skb_put(skb, fifo_size), bcs->hw.hscx.rcvbuf, fifo_size); skb_queue_tail(&bcs->rqueue, skb); } bcs->hw.hscx.rcvidx = 0; hscx_sched_event(bcs, B_RCVBUFREADY); } } if (val & 0x10) { /* XPR */ if (bcs->tx_skb) { if (bcs->tx_skb->len) { hscx_fill_fifo(bcs); return; } else { if (bcs->st->lli.l1writewakeup && (PACKET_NOACK != bcs->tx_skb->pkt_type)) bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count); dev_kfree_skb_irq(bcs->tx_skb); bcs->hw.hscx.count = 0; bcs->tx_skb = NULL; } } if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) { bcs->hw.hscx.count = 0; test_and_set_bit(BC_FLG_BUSY, &bcs->Flag); hscx_fill_fifo(bcs); } else { test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); hscx_sched_event(bcs, B_XMTBUFREADY); } } }
static inline void hscx_interrupt(struct IsdnCardState *sp, u_char val, u_char hscx) { u_char r; struct HscxState *hsp = sp->hs + hscx; struct sk_buff *skb; int count; char tmp[32]; if (!hsp->init) return; if (val & 0x80) { /* RME */ r = HscxReadReg(sp->hscx[hsp->hscx], hscx, HSCX_RSTA); if ((r & 0xf0) != 0xa0) { if (!(r & 0x80)) if (sp->debug & L1_DEB_WARN) debugl1(sp, "HSCX invalid frame"); if ((r & 0x40) && hsp->mode) if (sp->debug & L1_DEB_WARN) { sprintf(tmp, "HSCX RDO mode=%d", hsp->mode); debugl1(sp, tmp); } if (!(r & 0x20)) if (sp->debug & L1_DEB_WARN) debugl1(sp, "HSCX CRC error"); writehscxCMDR(sp->hscx[hsp->hscx], hsp->hscx, 0x80); } else { count = HscxReadReg(sp->hscx[hsp->hscx], hscx, HSCX_RBCL) & 0x1f; if (count == 0) count = 32; hscx_empty_fifo(hsp, count); if ((count = hsp->rcvidx - 1) > 0) { if (sp->debug & L1_DEB_HSCX_FIFO) { sprintf(tmp, "HX Frame %d", count); debugl1(sp, tmp); } if (!(skb = dev_alloc_skb(count))) printk(KERN_WARNING "IX1: receive out of memory\n"); else { memcpy(skb_put(skb, count), hsp->rcvbuf, count); skb_queue_tail(&hsp->rqueue, skb); } } } hsp->rcvidx = 0; hscx_sched_event(hsp, HSCX_RCVBUFREADY); } if (val & 0x40) { /* RPF */ hscx_empty_fifo(hsp, 32); if (hsp->mode == 1) { /* receive audio data */ if (!(skb = dev_alloc_skb(32))) printk(KERN_WARNING "IX1: receive out of memory\n"); else { memcpy(skb_put(skb, 32), hsp->rcvbuf, 32); skb_queue_tail(&hsp->rqueue, skb); } hsp->rcvidx = 0; hscx_sched_event(hsp, HSCX_RCVBUFREADY); } } if (val & 0x10) { /* XPR */ if (hsp->tx_skb) if (hsp->tx_skb->len) { hscx_fill_fifo(hsp); return; } else { dev_kfree_skb(hsp->tx_skb, FREE_WRITE); hsp->count = 0; if (hsp->st->l4.l1writewakeup) hsp->st->l4.l1writewakeup(hsp->st); hsp->tx_skb = NULL; } if ((hsp->tx_skb = skb_dequeue(&hsp->squeue))) { hsp->count = 0; hscx_fill_fifo(hsp); } else hscx_sched_event(hsp, HSCX_XMTBUFREADY); } }