static irqreturn_t gazel_interrupt(int intno, void *dev_id) { #define MAXCOUNT 5 struct IsdnCardState *cs = dev_id; u_char valisac, valhscx; int count = 0; u_long flags; spin_lock_irqsave(&cs->lock, flags); do { valhscx = ReadHSCX(cs, 1, HSCX_ISTA); if (valhscx) hscx_int_main(cs, valhscx); valisac = ReadISAC(cs, ISAC_ISTA); if (valisac) isac_interrupt(cs, valisac); count++; } while ((valhscx || valisac) && (count < MAXCOUNT)); WriteHSCX(cs, 0, HSCX_MASK, 0xFF); WriteHSCX(cs, 1, HSCX_MASK, 0xFF); WriteISAC(cs, ISAC_MASK, 0xFF); WriteISAC(cs, ISAC_MASK, 0x0); WriteHSCX(cs, 0, HSCX_MASK, 0x0); WriteHSCX(cs, 1, HSCX_MASK, 0x0); spin_unlock_irqrestore(&cs->lock, flags); return IRQ_HANDLED; }
static irqreturn_t avm_a1p_interrupt(int intno, void *dev_id) { struct IsdnCardState *cs = dev_id; u_char val, sval; u_long flags; spin_lock_irqsave(&cs->lock, flags); while ((sval = (~bytein(cs->hw.avm.cfg_reg+ASL0_OFFSET) & ASL0_R_IRQPENDING))) { if (cs->debug & L1_DEB_INTSTAT) debugl1(cs, "avm IntStatus %x", sval); if (sval & ASL0_R_HSCX) { val = ReadHSCX(cs, 1, HSCX_ISTA); if (val) hscx_int_main(cs, val); } if (sval & ASL0_R_ISAC) { val = ReadISAC(cs, ISAC_ISTA); if (val) isac_interrupt(cs, val); } } WriteHSCX(cs, 0, HSCX_MASK, 0xff); WriteHSCX(cs, 1, HSCX_MASK, 0xff); WriteISAC(cs, ISAC_MASK, 0xff); WriteISAC(cs, ISAC_MASK, 0x00); WriteHSCX(cs, 0, HSCX_MASK, 0x00); WriteHSCX(cs, 1, HSCX_MASK, 0x00); spin_unlock_irqrestore(&cs->lock, flags); return IRQ_HANDLED; }
void isac_empty_fifo(struct isac_hw *isac, int count) { u8 *ptr; pr_debug("%s: %s %d\n", isac->name, __func__, count); if (!isac->dch.rx_skb) { isac->dch.rx_skb = mI_alloc_skb(isac->dch.maxlen, GFP_ATOMIC); if (!isac->dch.rx_skb) { pr_info("%s: D receive out of memory\n", isac->name); WriteISAC(isac, ISAC_CMDR, 0x80); return; } } if ((isac->dch.rx_skb->len + count) >= isac->dch.maxlen) { pr_debug("%s: %s overrun %d\n", isac->name, __func__, isac->dch.rx_skb->len + count); WriteISAC(isac, ISAC_CMDR, 0x80); return; } ptr = skb_put(isac->dch.rx_skb, count); isac->read_fifo(isac->dch.hw, isac->off, ptr, count); WriteISAC(isac, ISAC_CMDR, 0x80); if (isac->dch.debug & DEBUG_HW_DFIFO) { char pfx[MISDN_MAX_IDLEN + 16]; snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-recv %s %d ", isac->name, count); print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count); } }
static void gazel_interrupt(int intno, void *dev_id, struct pt_regs *regs) { #define MAXCOUNT 5 struct IsdnCardState *cs = dev_id; u_char valisac, valhscx; int count = 0; if (!cs) { printk(KERN_WARNING "Gazel: Spurious interrupt!\n"); return; } do { valhscx = ReadHSCX(cs, 1, HSCX_ISTA); if (valhscx) hscx_int_main(cs, valhscx); valisac = ReadISAC(cs, ISAC_ISTA); if (valisac) isac_interrupt(cs, valisac); count++; } while ((valhscx || valisac) && (count < MAXCOUNT)); WriteHSCX(cs, 0, HSCX_MASK, 0xFF); WriteHSCX(cs, 1, HSCX_MASK, 0xFF); WriteISAC(cs, ISAC_MASK, 0xFF); WriteISAC(cs, ISAC_MASK, 0x0); WriteHSCX(cs, 0, HSCX_MASK, 0x0); WriteHSCX(cs, 1, HSCX_MASK, 0x0); }
static void avm_a1p_interrupt(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char val, sval; if (!cs) { printk(KERN_WARNING "AVM A1 PCMCIA: Spurious interrupt!\n"); return; } while ((sval = (~bytein(cs->hw.avm.cfg_reg+ASL0_OFFSET) & ASL0_R_IRQPENDING))) { if (cs->debug & L1_DEB_INTSTAT) debugl1(cs, "avm IntStatus %x", sval); if (sval & ASL0_R_HSCX) { val = ReadHSCX(cs, 1, HSCX_ISTA); if (val) hscx_int_main(cs, val); } if (sval & ASL0_R_ISAC) { val = ReadISAC(cs, ISAC_ISTA); if (val) isac_interrupt(cs, val); } } WriteHSCX(cs, 0, HSCX_MASK, 0xff); WriteHSCX(cs, 1, HSCX_MASK, 0xff); WriteISAC(cs, ISAC_MASK, 0xff); WriteISAC(cs, ISAC_MASK, 0x00); WriteHSCX(cs, 0, HSCX_MASK, 0x00); WriteHSCX(cs, 1, HSCX_MASK, 0x00); }
static inline void ph_command(struct isac_hw *isac, u8 command) { pr_debug("%s: ph_command %x\n", isac->name, command); if (isac->type & IPAC_TYPE_ISACX) WriteISAC(isac, ISACX_CIX0, (command << 4) | 0xE); else WriteISAC(isac, ISAC_CIX0, (command << 2) | 3); }
static void isac_rme_irq(struct isac_hw *isac) { u8 val, count; val = ReadISAC(isac, ISAC_RSTA); if ((val & 0x70) != 0x20) { if (val & 0x40) { pr_debug("%s: ISAC RDO\n", isac->name); #ifdef ERROR_STATISTIC isac->dch.err_rx++; #endif } if (!(val & 0x20)) { pr_debug("%s: ISAC CRC error\n", isac->name); #ifdef ERROR_STATISTIC isac->dch.err_crc++; #endif } WriteISAC(isac, ISAC_CMDR, 0x80); if (isac->dch.rx_skb) dev_kfree_skb(isac->dch.rx_skb); isac->dch.rx_skb = NULL; } else { count = ReadISAC(isac, ISAC_RBCL) & 0x1f; if (count == 0) count = 32; isac_empty_fifo(isac, count); recv_Dchannel(&isac->dch); } }
static irqreturn_t gazel_interrupt_ipac(int intno, void *dev_id) { struct IsdnCardState *cs = dev_id; u_char ista, val; int count = 0; u_long flags; spin_lock_irqsave(&cs->lock, flags); ista = ReadISAC(cs, IPAC_ISTA - 0x80); do { if (ista & 0x0f) { val = ReadHSCX(cs, 1, HSCX_ISTA); if (ista & 0x01) val |= 0x01; if (ista & 0x04) val |= 0x02; if (ista & 0x08) val |= 0x04; if (val) { hscx_int_main(cs, val); } } if (ista & 0x20) { val = 0xfe & ReadISAC(cs, ISAC_ISTA); if (val) { isac_interrupt(cs, val); } } if (ista & 0x10) { val = 0x01; isac_interrupt(cs, val); } ista = ReadISAC(cs, IPAC_ISTA - 0x80); count++; } while ((ista & 0x3f) && (count < MAXCOUNT)); WriteISAC(cs, IPAC_MASK - 0x80, 0xFF); WriteISAC(cs, IPAC_MASK - 0x80, 0xC0); spin_unlock_irqrestore(&cs->lock, flags); return IRQ_HANDLED; }
static void gazel_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char ista, val; int count = 0; if (!cs) { printk(KERN_WARNING "Gazel: Spurious interrupt!\n"); return; } ista = ReadISAC(cs, IPAC_ISTA - 0x80); do { if (ista & 0x0f) { val = ReadHSCX(cs, 1, HSCX_ISTA); if (ista & 0x01) val |= 0x01; if (ista & 0x04) val |= 0x02; if (ista & 0x08) val |= 0x04; if (val) { hscx_int_main(cs, val); } } if (ista & 0x20) { val = 0xfe & ReadISAC(cs, ISAC_ISTA); if (val) { isac_interrupt(cs, val); } } if (ista & 0x10) { val = 0x01; isac_interrupt(cs, val); } ista = ReadISAC(cs, IPAC_ISTA - 0x80); count++; } while ((ista & 0x3f) && (count < MAXCOUNT)); WriteISAC(cs, IPAC_MASK - 0x80, 0xFF); WriteISAC(cs, IPAC_MASK - 0x80, 0xC0); }
static void gazel_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) { struct IsdnCardState *cs = dev_id; u_char ista, val; int count = 0; if (!cs) { printk(KERN_WARNING "Gazel: Spurious interrupt!\n"); return; } do { if (ista & 0x10) { val = 0x01; isac_interrupt(cs, val); } } while ((ista & 0x3f) && (count < MAXCOUNT)); WriteISAC(cs, IPAC_MASK - 0x80, 0xFF); WriteISAC(cs, IPAC_MASK - 0x80, 0xC0); }
static void isac_fill_fifo(struct isac_hw *isac) { int count, more; u8 *ptr; if (!isac->dch.tx_skb) return; count = isac->dch.tx_skb->len - isac->dch.tx_idx; if (count <= 0) return; more = 0; if (count > 32) { more = !0; count = 32; } pr_debug("%s: %s %d\n", isac->name, __func__, count); ptr = isac->dch.tx_skb->data + isac->dch.tx_idx; isac->dch.tx_idx += count; isac->write_fifo(isac->dch.hw, isac->off, ptr, count); WriteISAC(isac, ISAC_CMDR, more ? 0x8 : 0xa); if (test_and_set_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) { pr_debug("%s: %s dbusytimer running\n", isac->name, __func__); del_timer(&isac->dch.timer); } init_timer(&isac->dch.timer); isac->dch.timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000); add_timer(&isac->dch.timer); if (isac->dch.debug & DEBUG_HW_DFIFO) { char pfx[MISDN_MAX_IDLEN + 16]; snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-send %s %d ", isac->name, count); print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count); } }
static int reset_gazel(struct IsdnCardState *cs) { unsigned long plxcntrl, addr = cs->hw.gazel.cfg_reg; switch (cs->subtyp) { case R647: writereg(addr, 0, 0); HZDELAY(10); writereg(addr, 0, 1); HZDELAY(2); break; case R685: plxcntrl = inl(addr + PLX_CNTRL); plxcntrl |= (RESET_9050 + RESET_GAZEL); outl(plxcntrl, addr + PLX_CNTRL); plxcntrl &= ~(RESET_9050 + RESET_GAZEL); HZDELAY(4); outl(plxcntrl, addr + PLX_CNTRL); HZDELAY(10); outb(INT_ISAC_EN + INT_HSCX_EN + INT_PCI_EN, addr + PLX_INCSR); break; case R753: plxcntrl = inl(addr + PLX_CNTRL); plxcntrl |= (RESET_9050 + RESET_GAZEL); outl(plxcntrl, addr + PLX_CNTRL); plxcntrl &= ~(RESET_9050 + RESET_GAZEL); WriteISAC(cs, IPAC_POTA2 - 0x80, 0x20); HZDELAY(4); outl(plxcntrl, addr + PLX_CNTRL); HZDELAY(10); WriteISAC(cs, IPAC_POTA2 - 0x80, 0x00); WriteISAC(cs, IPAC_ACFG - 0x80, 0xff); WriteISAC(cs, IPAC_AOE - 0x80, 0x0); WriteISAC(cs, IPAC_MASK - 0x80, 0xff); WriteISAC(cs, IPAC_CONF - 0x80, 0x1); outb(INT_IPAC_EN + INT_PCI_EN, addr + PLX_INCSR); WriteISAC(cs, IPAC_MASK - 0x80, 0xc0); break; case R742: WriteISAC(cs, IPAC_POTA2 - 0x80, 0x20); HZDELAY(4); WriteISAC(cs, IPAC_POTA2 - 0x80, 0x00); WriteISAC(cs, IPAC_ACFG - 0x80, 0xff); WriteISAC(cs, IPAC_AOE - 0x80, 0x0); WriteISAC(cs, IPAC_MASK - 0x80, 0xff); WriteISAC(cs, IPAC_CONF - 0x80, 0x1); WriteISAC(cs, IPAC_MASK - 0x80, 0xc0); break; } return (0); }
static void isac_mos_irq(struct isac_hw *isac) { u8 val; int ret; val = ReadISAC(isac, ISAC_MOSR); pr_debug("%s: ISAC MOSR %02x\n", isac->name, val); #if ARCOFI_USE if (val & 0x08) { if (!isac->mon_rx) { isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC); if (!isac->mon_rx) { pr_info("%s: ISAC MON RX out of memory!\n", isac->name); isac->mocr &= 0xf0; isac->mocr |= 0x0a; WriteISAC(isac, ISAC_MOCR, isac->mocr); goto afterMONR0; } else isac->mon_rxp = 0; } if (isac->mon_rxp >= MAX_MON_FRAME) { isac->mocr &= 0xf0; isac->mocr |= 0x0a; WriteISAC(isac, ISAC_MOCR, isac->mocr); isac->mon_rxp = 0; pr_debug("%s: ISAC MON RX overflow!\n", isac->name); goto afterMONR0; } isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR0); pr_debug("%s: ISAC MOR0 %02x\n", isac->name, isac->mon_rx[isac->mon_rxp - 1]); if (isac->mon_rxp == 1) { isac->mocr |= 0x04; WriteISAC(isac, ISAC_MOCR, isac->mocr); } } afterMONR0: if (val & 0x80) { if (!isac->mon_rx) { isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC); if (!isac->mon_rx) { pr_info("%s: ISAC MON RX out of memory!\n", isac->name); isac->mocr &= 0x0f; isac->mocr |= 0xa0; WriteISAC(isac, ISAC_MOCR, isac->mocr); goto afterMONR1; } else isac->mon_rxp = 0; } if (isac->mon_rxp >= MAX_MON_FRAME) { isac->mocr &= 0x0f; isac->mocr |= 0xa0; WriteISAC(isac, ISAC_MOCR, isac->mocr); isac->mon_rxp = 0; pr_debug("%s: ISAC MON RX overflow!\n", isac->name); goto afterMONR1; } isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR1); pr_debug("%s: ISAC MOR1 %02x\n", isac->name, isac->mon_rx[isac->mon_rxp - 1]); isac->mocr |= 0x40; WriteISAC(isac, ISAC_MOCR, isac->mocr); } afterMONR1: if (val & 0x04) { isac->mocr &= 0xf0; WriteISAC(isac, ISAC_MOCR, isac->mocr); isac->mocr |= 0x0a; WriteISAC(isac, ISAC_MOCR, isac->mocr); if (isac->monitor) { ret = isac->monitor(isac->dch.hw, MONITOR_RX_0, isac->mon_rx, isac->mon_rxp); if (ret) kfree(isac->mon_rx); } else { pr_info("%s: MONITOR 0 received %d but no user\n", isac->name, isac->mon_rxp); kfree(isac->mon_rx); } isac->mon_rx = NULL; isac->mon_rxp = 0; } if (val & 0x40) { isac->mocr &= 0x0f; WriteISAC(isac, ISAC_MOCR, isac->mocr); isac->mocr |= 0xa0; WriteISAC(isac, ISAC_MOCR, isac->mocr); if (isac->monitor) { ret = isac->monitor(isac->dch.hw, MONITOR_RX_1, isac->mon_rx, isac->mon_rxp); if (ret) kfree(isac->mon_rx); } else { pr_info("%s: MONITOR 1 received %d but no user\n", isac->name, isac->mon_rxp); kfree(isac->mon_rx); } isac->mon_rx = NULL; isac->mon_rxp = 0; } if (val & 0x02) { if ((!isac->mon_tx) || (isac->mon_txc && (isac->mon_txp >= isac->mon_txc) && !(val & 0x08))) { isac->mocr &= 0xf0; WriteISAC(isac, ISAC_MOCR, isac->mocr); isac->mocr |= 0x0a; WriteISAC(isac, ISAC_MOCR, isac->mocr); if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) { if (isac->monitor) ret = isac->monitor(isac->dch.hw, MONITOR_TX_0, NULL, 0); } kfree(isac->mon_tx); isac->mon_tx = NULL; isac->mon_txc = 0; isac->mon_txp = 0; goto AfterMOX0; } if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) { if (isac->monitor) ret = isac->monitor(isac->dch.hw, MONITOR_TX_0, NULL, 0); kfree(isac->mon_tx); isac->mon_tx = NULL; isac->mon_txc = 0; isac->mon_txp = 0; goto AfterMOX0; } WriteISAC(isac, ISAC_MOX0, isac->mon_tx[isac->mon_txp++]); pr_debug("%s: ISAC %02x -> MOX0\n", isac->name, isac->mon_tx[isac->mon_txp - 1]); } AfterMOX0: if (val & 0x20) { if ((!isac->mon_tx) || (isac->mon_txc && (isac->mon_txp >= isac->mon_txc) && !(val & 0x80))) { isac->mocr &= 0x0f; WriteISAC(isac, ISAC_MOCR, isac->mocr); isac->mocr |= 0xa0; WriteISAC(isac, ISAC_MOCR, isac->mocr); if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) { if (isac->monitor) ret = isac->monitor(isac->dch.hw, MONITOR_TX_1, NULL, 0); } kfree(isac->mon_tx); isac->mon_tx = NULL; isac->mon_txc = 0; isac->mon_txp = 0; goto AfterMOX1; } if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) { if (isac->monitor) ret = isac->monitor(isac->dch.hw, MONITOR_TX_1, NULL, 0); kfree(isac->mon_tx); isac->mon_tx = NULL; isac->mon_txc = 0; isac->mon_txp = 0; goto AfterMOX1; } WriteISAC(isac, ISAC_MOX1, isac->mon_tx[isac->mon_txp++]); pr_debug("%s: ISAC %02x -> MOX1\n", isac->name, isac->mon_tx[isac->mon_txp - 1]); } AfterMOX1: val = 0; /* dummy to avoid warning */ #endif }