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 }
int __init setup_gazel(struct IsdnCard *card) { struct IsdnCardState *cs = card->cs; char tmp[64]; u_char val; strcpy(tmp, gazel_revision); printk(KERN_INFO "Gazel: Driver Revision %s\n", HiSax_getrev(tmp)); if (cs->typ != ISDN_CTYPE_GAZEL) return (0); if (card->para[0]) { if (setup_gazelisa(card, cs)) return (0); } else { #if CONFIG_PCI if (setup_gazelpci(cs)) return (0); #else printk(KERN_WARNING "Gazel: Card PCI requested and NO_PCI_BIOS, unable to config\n"); return (0); #endif /* CONFIG_PCI */ } if (reserve_regions(card, cs)) { return (0); } if (reset_gazel(cs)) { printk(KERN_WARNING "Gazel: wrong IRQ\n"); release_io_gazel(cs); return (0); } cs->readisac = &ReadISAC; cs->writeisac = &WriteISAC; cs->readisacfifo = &ReadISACfifo; cs->writeisacfifo = &WriteISACfifo; cs->BC_Read_Reg = &ReadHSCX; cs->BC_Write_Reg = &WriteHSCX; cs->BC_Send_Data = &hscx_fill_fifo; cs->cardmsg = &Gazel_card_msg; switch (cs->subtyp) { case R647: case R685: cs->irq_func = &gazel_interrupt; ISACVersion(cs, "Gazel:"); if (HscxVersion(cs, "Gazel:")) { printk(KERN_WARNING "Gazel: wrong HSCX versions check IO address\n"); release_io_gazel(cs); return (0); } break; case R742: case R753: cs->irq_func = &gazel_interrupt_ipac; val = ReadISAC(cs, IPAC_ID - 0x80); printk(KERN_INFO "Gazel: IPAC version %x\n", val); break; } return (1); }