diff options
Diffstat (limited to 'drivers/isdn/hisax/diva.c')
-rw-r--r-- | drivers/isdn/hisax/diva.c | 1282 |
1 files changed, 0 insertions, 1282 deletions
diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c deleted file mode 100644 index d23df7a7784d..000000000000 --- a/drivers/isdn/hisax/diva.c +++ /dev/null @@ -1,1282 +0,0 @@ -/* $Id: diva.c,v 1.33.2.6 2004/02/11 13:21:33 keil Exp $ - * - * low level stuff for Eicon.Diehl Diva Family ISDN cards - * - * Author Karsten Keil - * Copyright by Karsten Keil <keil@isdn4linux.de> - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * For changes and modifications please read - * Documentation/isdn/HiSax.cert - * - * Thanks to Eicon Technology for documents and information - * - */ - -#include <linux/init.h> -#include "hisax.h" -#include "isac.h" -#include "hscx.h" -#include "ipac.h" -#include "ipacx.h" -#include "isdnl1.h" -#include <linux/pci.h> -#include <linux/isapnp.h> - -static const char *Diva_revision = "$Revision: 1.33.2.6 $"; - -#define byteout(addr, val) outb(val, addr) -#define bytein(addr) inb(addr) - -#define DIVA_HSCX_DATA 0 -#define DIVA_HSCX_ADR 4 -#define DIVA_ISA_ISAC_DATA 2 -#define DIVA_ISA_ISAC_ADR 6 -#define DIVA_ISA_CTRL 7 -#define DIVA_IPAC_ADR 0 -#define DIVA_IPAC_DATA 1 - -#define DIVA_PCI_ISAC_DATA 8 -#define DIVA_PCI_ISAC_ADR 0xc -#define DIVA_PCI_CTRL 0x10 - -/* SUB Types */ -#define DIVA_ISA 1 -#define DIVA_PCI 2 -#define DIVA_IPAC_ISA 3 -#define DIVA_IPAC_PCI 4 -#define DIVA_IPACX_PCI 5 - -/* CTRL (Read) */ -#define DIVA_IRQ_STAT 0x01 -#define DIVA_EEPROM_SDA 0x02 - -/* CTRL (Write) */ -#define DIVA_IRQ_REQ 0x01 -#define DIVA_RESET 0x08 -#define DIVA_EEPROM_CLK 0x40 -#define DIVA_PCI_LED_A 0x10 -#define DIVA_PCI_LED_B 0x20 -#define DIVA_ISA_LED_A 0x20 -#define DIVA_ISA_LED_B 0x40 -#define DIVA_IRQ_CLR 0x80 - -/* Siemens PITA */ -#define PITA_MISC_REG 0x1c -#ifdef __BIG_ENDIAN -#define PITA_PARA_SOFTRESET 0x00000001 -#define PITA_SER_SOFTRESET 0x00000002 -#define PITA_PARA_MPX_MODE 0x00000004 -#define PITA_INT0_ENABLE 0x00000200 -#else -#define PITA_PARA_SOFTRESET 0x01000000 -#define PITA_SER_SOFTRESET 0x02000000 -#define PITA_PARA_MPX_MODE 0x04000000 -#define PITA_INT0_ENABLE 0x00020000 -#endif -#define PITA_INT0_STATUS 0x02 - -static inline u_char -readreg(unsigned int ale, unsigned int adr, u_char off) -{ - register u_char ret; - - byteout(ale, off); - ret = bytein(adr); - return (ret); -} - -static inline void -readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - byteout(ale, off); - insb(adr, data, size); -} - - -static inline void -writereg(unsigned int ale, unsigned int adr, u_char off, u_char data) -{ - byteout(ale, off); - byteout(adr, data); -} - -static inline void -writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size) -{ - byteout(ale, off); - outsb(adr, data, size); -} - -static inline u_char -memreadreg(unsigned long adr, u_char off) -{ - return (*((unsigned char *) - (((unsigned int *)adr) + off))); -} - -static inline void -memwritereg(unsigned long adr, u_char off, u_char data) -{ - register u_char *p; - - p = (unsigned char *)(((unsigned int *)adr) + off); - *p = data; -} - -/* Interface functions */ - -static u_char -ReadISAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset)); -} - -static void -WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset, value); -} - -static void -ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - readfifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0, data, size); -} - -static void -WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size) -{ - writefifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0, data, size); -} - -static u_char -ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset) -{ - return (readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset + 0x80)); -} - -static void -WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, offset | 0x80, value); -} - -static void -ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) -{ - readfifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0x80, data, size); -} - -static void -WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) -{ - writefifo(cs->hw.diva.isac_adr, cs->hw.diva.isac, 0x80, data, size); -} - -static u_char -ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (readreg(cs->hw.diva.hscx_adr, - cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0))); -} - -static void -WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - writereg(cs->hw.diva.hscx_adr, - cs->hw.diva.hscx, offset + (hscx ? 0x40 : 0), value); -} - -static u_char -MemReadISAC_IPAC(struct IsdnCardState *cs, u_char offset) -{ - return (memreadreg(cs->hw.diva.cfg_reg, offset + 0x80)); -} - -static void -MemWriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value) -{ - memwritereg(cs->hw.diva.cfg_reg, offset | 0x80, value); -} - -static void -MemReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) -{ - while (size--) - *data++ = memreadreg(cs->hw.diva.cfg_reg, 0x80); -} - -static void -MemWriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size) -{ - while (size--) - memwritereg(cs->hw.diva.cfg_reg, 0x80, *data++); -} - -static u_char -MemReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (memreadreg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0))); -} - -static void -MemWriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - memwritereg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0), value); -} - -/* IO-Functions for IPACX type cards */ -static u_char -MemReadISAC_IPACX(struct IsdnCardState *cs, u_char offset) -{ - return (memreadreg(cs->hw.diva.cfg_reg, offset)); -} - -static void -MemWriteISAC_IPACX(struct IsdnCardState *cs, u_char offset, u_char value) -{ - memwritereg(cs->hw.diva.cfg_reg, offset, value); -} - -static void -MemReadISACfifo_IPACX(struct IsdnCardState *cs, u_char *data, int size) -{ - while (size--) - *data++ = memreadreg(cs->hw.diva.cfg_reg, 0); -} - -static void -MemWriteISACfifo_IPACX(struct IsdnCardState *cs, u_char *data, int size) -{ - while (size--) - memwritereg(cs->hw.diva.cfg_reg, 0, *data++); -} - -static u_char -MemReadHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset) -{ - return (memreadreg(cs->hw.diva.cfg_reg, offset + - (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1))); -} - -static void -MemWriteHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value) -{ - memwritereg(cs->hw.diva.cfg_reg, offset + - (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1), value); -} - -/* - * fast interrupt HSCX stuff goes here - */ - -#define READHSCX(cs, nr, reg) readreg(cs->hw.diva.hscx_adr, \ - cs->hw.diva.hscx, reg + (nr ? 0x40 : 0)) -#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.diva.hscx_adr, \ - cs->hw.diva.hscx, reg + (nr ? 0x40 : 0), data) - -#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.diva.hscx_adr, \ - cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.diva.hscx_adr, \ - cs->hw.diva.hscx, (nr ? 0x40 : 0), ptr, cnt) - -#include "hscx_irq.c" - -static irqreturn_t -diva_interrupt(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val, sval; - u_long flags; - int cnt = 5; - - spin_lock_irqsave(&cs->lock, flags); - while (((sval = bytein(cs->hw.diva.ctrl)) & DIVA_IRQ_REQ) && cnt) { - val = readreg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_ISTA + 0x40); - if (val) - hscx_int_main(cs, val); - val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_ISTA); - if (val) - isac_interrupt(cs, val); - cnt--; - } - if (!cnt) - printk(KERN_WARNING "Diva: IRQ LOOP\n"); - writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK, 0xFF); - writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK + 0x40, 0xFF); - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_MASK, 0xFF); - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_MASK, 0x0); - writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK, 0x0); - writereg(cs->hw.diva.hscx_adr, cs->hw.diva.hscx, HSCX_MASK + 0x40, 0x0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static irqreturn_t -diva_irq_ipac_isa(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char ista, val; - u_long flags; - int icnt = 5; - - spin_lock_irqsave(&cs->lock, flags); - ista = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ISTA); -Start_IPACISA: - if (cs->debug & L1_DEB_IPAC) - debugl1(cs, "IPAC ISTA %02X", ista); - if (ista & 0x0f) { - val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, HSCX_ISTA + 0x40); - 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 & readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, ISAC_ISTA + 0x80); - if (val) { - isac_interrupt(cs, val); - } - } - if (ista & 0x10) { - val = 0x01; - isac_interrupt(cs, val); - } - ista = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ISTA); - if ((ista & 0x3f) && icnt) { - icnt--; - goto Start_IPACISA; - } - if (!icnt) - printk(KERN_WARNING "DIVA IPAC IRQ LOOP\n"); - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xFF); - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xC0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static inline void -MemwaitforCEC(struct IsdnCardState *cs, int hscx) -{ - int to = 50; - - while ((MemReadHSCX(cs, hscx, HSCX_STAR) & 0x04) && to) { - udelay(1); - to--; - } - if (!to) - printk(KERN_WARNING "HiSax: waitforCEC timeout\n"); -} - - -static inline void -MemwaitforXFW(struct IsdnCardState *cs, int hscx) -{ - int to = 50; - - while (((MemReadHSCX(cs, hscx, HSCX_STAR) & 0x44) != 0x40) && to) { - udelay(1); - to--; - } - if (!to) - printk(KERN_WARNING "HiSax: waitforXFW timeout\n"); -} - -static inline void -MemWriteHSCXCMDR(struct IsdnCardState *cs, int hscx, u_char data) -{ - MemwaitforCEC(cs, hscx); - MemWriteHSCX(cs, hscx, HSCX_CMDR, data); -} - -static void -Memhscx_empty_fifo(struct BCState *bcs, int count) -{ - u_char *ptr; - struct IsdnCardState *cs = bcs->cs; - int cnt; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "hscx_empty_fifo"); - - if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) { - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "hscx_empty_fifo: incoming packet too large"); - MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80); - bcs->hw.hscx.rcvidx = 0; - return; - } - ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; - cnt = count; - while (cnt--) - *ptr++ = memreadreg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0); - MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80); - ptr = bcs->hw.hscx.rcvbuf + bcs->hw.hscx.rcvidx; - bcs->hw.hscx.rcvidx += count; - if (cs->debug & L1_DEB_HSCX_FIFO) { - char *t = bcs->blog; - - t += sprintf(t, "hscx_empty_fifo %c cnt %d", - bcs->hw.hscx.hscx ? 'B' : 'A', count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", bcs->blog); - } -} - -static void -Memhscx_fill_fifo(struct BCState *bcs) -{ - struct IsdnCardState *cs = bcs->cs; - int more, count, cnt; - int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags) ? 64 : 32; - u_char *ptr, *p; - - if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) - debugl1(cs, "hscx_fill_fifo"); - - if (!bcs->tx_skb) - return; - if (bcs->tx_skb->len <= 0) - return; - - more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0; - if (bcs->tx_skb->len > fifo_size) { - more = !0; - count = fifo_size; - } else - count = bcs->tx_skb->len; - cnt = count; - MemwaitforXFW(cs, bcs->hw.hscx.hscx); - p = ptr = bcs->tx_skb->data; - skb_pull(bcs->tx_skb, count); - bcs->tx_cnt -= count; - bcs->hw.hscx.count += count; - while (cnt--) - memwritereg(cs->hw.diva.cfg_reg, bcs->hw.hscx.hscx ? 0x40 : 0, - *p++); - MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, more ? 0x8 : 0xa); - if (cs->debug & L1_DEB_HSCX_FIFO) { - char *t = bcs->blog; - - t += sprintf(t, "hscx_fill_fifo %c cnt %d", - bcs->hw.hscx.hscx ? 'B' : 'A', count); - QuickHex(t, ptr, count); - debugl1(cs, "%s", bcs->blog); - } -} - -static void -Memhscx_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 = MemReadHSCX(cs, hscx, HSCX_RSTA); - if ((r & 0xf0) != 0xa0) { - if (!(r & 0x80)) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "HSCX invalid frame"); - if ((r & 0x40) && bcs->mode) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "HSCX RDO mode=%d", - bcs->mode); - if (!(r & 0x20)) - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "HSCX CRC error"); - MemWriteHSCXCMDR(cs, hscx, 0x80); - } else { - count = MemReadHSCX(cs, hscx, HSCX_RBCL) & ( - test_bit(HW_IPAC, &cs->HW_Flags) ? 0x3f : 0x1f); - if (count == 0) - count = fifo_size; - Memhscx_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 { - skb_put_data(skb, bcs->hw.hscx.rcvbuf, - count); - skb_queue_tail(&bcs->rqueue, skb); - } - } - } - bcs->hw.hscx.rcvidx = 0; - schedule_event(bcs, B_RCVBUFREADY); - } - if (val & 0x40) { /* RPF */ - Memhscx_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 { - skb_put_data(skb, bcs->hw.hscx.rcvbuf, - fifo_size); - skb_queue_tail(&bcs->rqueue, skb); - } - bcs->hw.hscx.rcvidx = 0; - schedule_event(bcs, B_RCVBUFREADY); - } - } - if (val & 0x10) { /* XPR */ - if (bcs->tx_skb) { - if (bcs->tx_skb->len) { - Memhscx_fill_fifo(bcs); - return; - } else { - if (test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) && - (PACKET_NOACK != bcs->tx_skb->pkt_type)) { - u_long flags; - spin_lock_irqsave(&bcs->aclock, flags); - bcs->ackcnt += bcs->hw.hscx.count; - spin_unlock_irqrestore(&bcs->aclock, flags); - schedule_event(bcs, B_ACKPENDING); - } - 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); - Memhscx_fill_fifo(bcs); - } else { - test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag); - schedule_event(bcs, B_XMTBUFREADY); - } - } -} - -static inline void -Memhscx_int_main(struct IsdnCardState *cs, u_char val) -{ - - u_char exval; - struct BCState *bcs; - - if (val & 0x01) { // EXB - bcs = cs->bcs + 1; - exval = MemReadHSCX(cs, 1, HSCX_EXIR); - if (exval & 0x40) { - if (bcs->mode == 1) - Memhscx_fill_fifo(bcs); - else { - /* Here we lost an TX interrupt, so - * restart transmitting the whole frame. - */ - if (bcs->tx_skb) { - skb_push(bcs->tx_skb, bcs->hw.hscx.count); - bcs->tx_cnt += bcs->hw.hscx.count; - bcs->hw.hscx.count = 0; - } - MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01); - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "HSCX B EXIR %x Lost TX", exval); - } - } else if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX B EXIR %x", exval); - } - if (val & 0xf8) { - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX B interrupt %x", val); - Memhscx_interrupt(cs, val, 1); - } - if (val & 0x02) { // EXA - bcs = cs->bcs; - exval = MemReadHSCX(cs, 0, HSCX_EXIR); - if (exval & 0x40) { - if (bcs->mode == L1_MODE_TRANS) - Memhscx_fill_fifo(bcs); - else { - /* Here we lost an TX interrupt, so - * restart transmitting the whole frame. - */ - if (bcs->tx_skb) { - skb_push(bcs->tx_skb, bcs->hw.hscx.count); - bcs->tx_cnt += bcs->hw.hscx.count; - bcs->hw.hscx.count = 0; - } - MemWriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01); - if (cs->debug & L1_DEB_WARN) - debugl1(cs, "HSCX A EXIR %x Lost TX", exval); - } - } else if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX A EXIR %x", exval); - } - if (val & 0x04) { // ICA - exval = MemReadHSCX(cs, 0, HSCX_ISTA); - if (cs->debug & L1_DEB_HSCX) - debugl1(cs, "HSCX A interrupt %x", exval); - Memhscx_interrupt(cs, exval, 0); - } -} - -static irqreturn_t -diva_irq_ipac_pci(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char ista, val; - int icnt = 5; - u_char *cfg; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - cfg = (u_char *) cs->hw.diva.pci_cfg; - val = *cfg; - if (!(val & PITA_INT0_STATUS)) { - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_NONE; /* other shared IRQ */ - } - *cfg = PITA_INT0_STATUS; /* Reset pending INT0 */ - ista = memreadreg(cs->hw.diva.cfg_reg, IPAC_ISTA); -Start_IPACPCI: - if (cs->debug & L1_DEB_IPAC) - debugl1(cs, "IPAC ISTA %02X", ista); - if (ista & 0x0f) { - val = memreadreg(cs->hw.diva.cfg_reg, HSCX_ISTA + 0x40); - if (ista & 0x01) - val |= 0x01; - if (ista & 0x04) - val |= 0x02; - if (ista & 0x08) - val |= 0x04; - if (val) - Memhscx_int_main(cs, val); - } - if (ista & 0x20) { - val = 0xfe & memreadreg(cs->hw.diva.cfg_reg, ISAC_ISTA + 0x80); - if (val) { - isac_interrupt(cs, val); - } - } - if (ista & 0x10) { - val = 0x01; - isac_interrupt(cs, val); - } - ista = memreadreg(cs->hw.diva.cfg_reg, IPAC_ISTA); - if ((ista & 0x3f) && icnt) { - icnt--; - goto Start_IPACPCI; - } - if (!icnt) - printk(KERN_WARNING "DIVA IPAC PCI IRQ LOOP\n"); - memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xFF); - memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xC0); - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static irqreturn_t -diva_irq_ipacx_pci(int intno, void *dev_id) -{ - struct IsdnCardState *cs = dev_id; - u_char val; - u_char *cfg; - u_long flags; - - spin_lock_irqsave(&cs->lock, flags); - cfg = (u_char *) cs->hw.diva.pci_cfg; - val = *cfg; - if (!(val & PITA_INT0_STATUS)) { - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_NONE; // other shared IRQ - } - interrupt_ipacx(cs); // handler for chip - *cfg = PITA_INT0_STATUS; // Reset PLX interrupt - spin_unlock_irqrestore(&cs->lock, flags); - return IRQ_HANDLED; -} - -static void -release_io_diva(struct IsdnCardState *cs) -{ - int bytecnt; - - if ((cs->subtyp == DIVA_IPAC_PCI) || - (cs->subtyp == DIVA_IPACX_PCI)) { - u_int *cfg = (unsigned int *)cs->hw.diva.pci_cfg; - - *cfg = 0; /* disable INT0/1 */ - *cfg = 2; /* reset pending INT0 */ - if (cs->hw.diva.cfg_reg) - iounmap((void *)cs->hw.diva.cfg_reg); - if (cs->hw.diva.pci_cfg) - iounmap((void *)cs->hw.diva.pci_cfg); - return; - } else if (cs->subtyp != DIVA_IPAC_ISA) { - del_timer(&cs->hw.diva.tl); - if (cs->hw.diva.cfg_reg) - byteout(cs->hw.diva.ctrl, 0); /* LED off, Reset */ - } - if ((cs->subtyp == DIVA_ISA) || (cs->subtyp == DIVA_IPAC_ISA)) - bytecnt = 8; - else - bytecnt = 32; - if (cs->hw.diva.cfg_reg) { - release_region(cs->hw.diva.cfg_reg, bytecnt); - } -} - -static void -iounmap_diva(struct IsdnCardState *cs) -{ - if ((cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_IPACX_PCI)) { - if (cs->hw.diva.cfg_reg) { - iounmap((void *)cs->hw.diva.cfg_reg); - cs->hw.diva.cfg_reg = 0; - } - if (cs->hw.diva.pci_cfg) { - iounmap((void *)cs->hw.diva.pci_cfg); - cs->hw.diva.pci_cfg = 0; - } - } - - return; -} - -static void -reset_diva(struct IsdnCardState *cs) -{ - if (cs->subtyp == DIVA_IPAC_ISA) { - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x20); - mdelay(10); - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_POTA2, 0x00); - mdelay(10); - writereg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_MASK, 0xc0); - } else if (cs->subtyp == DIVA_IPAC_PCI) { - unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg + - PITA_MISC_REG); - *ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE; - mdelay(10); - *ireg = PITA_PARA_MPX_MODE; - mdelay(10); - memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xc0); - } else if (cs->subtyp == DIVA_IPACX_PCI) { - unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg + - PITA_MISC_REG); - *ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE; - mdelay(10); - *ireg = PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET; - mdelay(10); - MemWriteISAC_IPACX(cs, IPACX_MASK, 0xff); // Interrupts off - } else { /* DIVA 2.0 */ - cs->hw.diva.ctrl_reg = 0; /* Reset On */ - byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); - mdelay(10); - cs->hw.diva.ctrl_reg |= DIVA_RESET; /* Reset Off */ - byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); - mdelay(10); - if (cs->subtyp == DIVA_ISA) - cs->hw.diva.ctrl_reg |= DIVA_ISA_LED_A; - else { - /* Workaround PCI9060 */ - byteout(cs->hw.diva.pci_cfg + 0x69, 9); - cs->hw.diva.ctrl_reg |= DIVA_PCI_LED_A; - } - byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); - } -} - -#define DIVA_ASSIGN 1 - -static void -diva_led_handler(struct timer_list *t) -{ - struct IsdnCardState *cs = from_timer(cs, t, hw.diva.tl); - int blink = 0; - - if ((cs->subtyp == DIVA_IPAC_ISA) || - (cs->subtyp == DIVA_IPAC_PCI) || - (cs->subtyp == DIVA_IPACX_PCI)) - return; - del_timer(&cs->hw.diva.tl); - if (cs->hw.diva.status & DIVA_ASSIGN) - cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ? - DIVA_ISA_LED_A : DIVA_PCI_LED_A; - else { - cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ? - DIVA_ISA_LED_A : DIVA_PCI_LED_A; - blink = 250; - } - if (cs->hw.diva.status & 0xf000) - cs->hw.diva.ctrl_reg |= (DIVA_ISA == cs->subtyp) ? - DIVA_ISA_LED_B : DIVA_PCI_LED_B; - else if (cs->hw.diva.status & 0x0f00) { - cs->hw.diva.ctrl_reg ^= (DIVA_ISA == cs->subtyp) ? - DIVA_ISA_LED_B : DIVA_PCI_LED_B; - blink = 500; - } else - cs->hw.diva.ctrl_reg &= ~((DIVA_ISA == cs->subtyp) ? - DIVA_ISA_LED_B : DIVA_PCI_LED_B); - - byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg); - if (blink) { - cs->hw.diva.tl.expires = jiffies + ((blink * HZ) / 1000); - add_timer(&cs->hw.diva.tl); - } -} - -static int -Diva_card_msg(struct IsdnCardState *cs, int mt, void *arg) -{ - u_int *ireg; - u_long flags; - - switch (mt) { - case CARD_RESET: - spin_lock_irqsave(&cs->lock, flags); - reset_diva(cs); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_RELEASE: - release_io_diva(cs); - return (0); - case CARD_INIT: - spin_lock_irqsave(&cs->lock, flags); - reset_diva(cs); - if (cs->subtyp == DIVA_IPACX_PCI) { - ireg = (unsigned int *)cs->hw.diva.pci_cfg; - *ireg = PITA_INT0_ENABLE; - init_ipacx(cs, 3); // init chip and enable interrupts - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - } - if (cs->subtyp == DIVA_IPAC_PCI) { - ireg = (unsigned int *)cs->hw.diva.pci_cfg; - *ireg = PITA_INT0_ENABLE; - } - inithscxisac(cs, 3); - spin_unlock_irqrestore(&cs->lock, flags); - return (0); - case CARD_TEST: - return (0); - case (MDL_REMOVE | REQUEST): - cs->hw.diva.status = 0; - break; - case (MDL_ASSIGN | REQUEST): - cs->hw.diva.status |= DIVA_ASSIGN; - break; - case MDL_INFO_SETUP: - if ((long)arg) - cs->hw.diva.status |= 0x0200; - else - cs->hw.diva.status |= 0x0100; - break; - case MDL_INFO_CONN: - if ((long)arg) - cs->hw.diva.status |= 0x2000; - else - cs->hw.diva.status |= 0x1000; - break; - case MDL_INFO_REL: - if ((long)arg) { - cs->hw.diva.status &= ~0x2000; - cs->hw.diva.status &= ~0x0200; - } else { - cs->hw.diva.status &= ~0x1000; - cs->hw.diva.status &= ~0x0100; - } - break; - } - if ((cs->subtyp != DIVA_IPAC_ISA) && - (cs->subtyp != DIVA_IPAC_PCI) && - (cs->subtyp != DIVA_IPACX_PCI)) { - spin_lock_irqsave(&cs->lock, flags); - diva_led_handler(&cs->hw.diva.tl); - spin_unlock_irqrestore(&cs->lock, flags); - } - return (0); -} - -static int setup_diva_common(struct IsdnCardState *cs) -{ - int bytecnt; - u_char val; - - if ((cs->subtyp == DIVA_ISA) || (cs->subtyp == DIVA_IPAC_ISA)) - bytecnt = 8; - else - bytecnt = 32; - - printk(KERN_INFO - "Diva: %s card configured at %#lx IRQ %d\n", - (cs->subtyp == DIVA_PCI) ? "PCI" : - (cs->subtyp == DIVA_ISA) ? "ISA" : - (cs->subtyp == DIVA_IPAC_ISA) ? "IPAC ISA" : - (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI", - cs->hw.diva.cfg_reg, cs->irq); - if ((cs->subtyp == DIVA_IPAC_PCI) || - (cs->subtyp == DIVA_IPACX_PCI) || - (cs->subtyp == DIVA_PCI)) - printk(KERN_INFO "Diva: %s space at %#lx\n", - (cs->subtyp == DIVA_PCI) ? "PCI" : - (cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI", - cs->hw.diva.pci_cfg); - if ((cs->subtyp != DIVA_IPAC_PCI) && - (cs->subtyp != DIVA_IPACX_PCI)) { - if (!request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn")) { - printk(KERN_WARNING - "HiSax: %s config port %lx-%lx already in use\n", - "diva", - cs->hw.diva.cfg_reg, - cs->hw.diva.cfg_reg + bytecnt); - iounmap_diva(cs); - return (0); - } - } - cs->BC_Read_Reg = &ReadHSCX; - cs->BC_Write_Reg = &WriteHSCX; - cs->BC_Send_Data = &hscx_fill_fifo; - cs->cardmsg = &Diva_card_msg; - setup_isac(cs); - if (cs->subtyp == DIVA_IPAC_ISA) { - cs->readisac = &ReadISAC_IPAC; - cs->writeisac = &WriteISAC_IPAC; - cs->readisacfifo = &ReadISACfifo_IPAC; - cs->writeisacfifo = &WriteISACfifo_IPAC; - cs->irq_func = &diva_irq_ipac_isa; - val = readreg(cs->hw.diva.isac_adr, cs->hw.diva.isac, IPAC_ID); - printk(KERN_INFO "Diva: IPAC version %x\n", val); - } else if (cs->subtyp == DIVA_IPAC_PCI) { - cs->readisac = &MemReadISAC_IPAC; - cs->writeisac = &MemWriteISAC_IPAC; - cs->readisacfifo = &MemReadISACfifo_IPAC; - cs->writeisacfifo = &MemWriteISACfifo_IPAC; - cs->BC_Read_Reg = &MemReadHSCX; - cs->BC_Write_Reg = &MemWriteHSCX; - cs->BC_Send_Data = &Memhscx_fill_fifo; - cs->irq_func = &diva_irq_ipac_pci; - val = memreadreg(cs->hw.diva.cfg_reg, IPAC_ID); - printk(KERN_INFO "Diva: IPAC version %x\n", val); - } else if (cs->subtyp == DIVA_IPACX_PCI) { - cs->readisac = &MemReadISAC_IPACX; - cs->writeisac = &MemWriteISAC_IPACX; - cs->readisacfifo = &MemReadISACfifo_IPACX; - cs->writeisacfifo = &MemWriteISACfifo_IPACX; - cs->BC_Read_Reg = &MemReadHSCX_IPACX; - cs->BC_Write_Reg = &MemWriteHSCX_IPACX; - cs->BC_Send_Data = NULL; // function located in ipacx module - cs->irq_func = &diva_irq_ipacx_pci; - printk(KERN_INFO "Diva: IPACX Design Id: %x\n", - MemReadISAC_IPACX(cs, IPACX_ID) & 0x3F); - } else { /* DIVA 2.0 */ - timer_setup(&cs->hw.diva.tl, diva_led_handler, 0); - cs->readisac = &ReadISAC; - cs->writeisac = &WriteISAC; - cs->readisacfifo = &ReadISACfifo; - cs->writeisacfifo = &WriteISACfifo; - cs->irq_func = &diva_interrupt; - ISACVersion(cs, "Diva:"); - if (HscxVersion(cs, "Diva:")) { - printk(KERN_WARNING - "Diva: wrong HSCX versions check IO address\n"); - release_io_diva(cs); - return (0); - } - } - return (1); -} - -#ifdef CONFIG_ISA - -static int setup_diva_isa(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - u_char val; - - if (!card->para[1]) - return (-1); /* card not found; continue search */ - - cs->hw.diva.ctrl_reg = 0; - cs->hw.diva.cfg_reg = card->para[1]; - val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR, - cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID); - printk(KERN_INFO "Diva: IPAC version %x\n", val); - if ((val == 1) || (val == 2)) { - cs->subtyp = DIVA_IPAC_ISA; - cs->hw.diva.ctrl = 0; - cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.hscx = card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR; - cs->hw.diva.hscx_adr = card->para[1] + DIVA_IPAC_ADR; - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - } else { - cs->subtyp = DIVA_ISA; - cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL; - cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA; - cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA; - cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR; - cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR; - } - cs->irq = card->para[0]; - - return (1); /* card found */ -} - -#else /* if !CONFIG_ISA */ - -static int setup_diva_isa(struct IsdnCard *card) -{ - return (-1); /* card not found; continue search */ -} - -#endif /* CONFIG_ISA */ - -#ifdef __ISAPNP__ -static struct isapnp_device_id diva_ids[] = { - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), - ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), - (unsigned long) "Diva picola" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), - ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51), - (unsigned long) "Diva picola" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), - ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), - (unsigned long) "Diva 2.0" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), - ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71), - (unsigned long) "Diva 2.0" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), - ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), - (unsigned long) "Diva 2.01" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), - ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1), - (unsigned long) "Diva 2.01" }, - { 0, } -}; - -static struct isapnp_device_id *ipid = &diva_ids[0]; -static struct pnp_card *pnp_c = NULL; - -static int setup_diva_isapnp(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - struct pnp_dev *pnp_d; - - if (!isapnp_present()) - return (-1); /* card not found; continue search */ - - while (ipid->card_vendor) { - if ((pnp_c = pnp_find_card(ipid->card_vendor, - ipid->card_device, pnp_c))) { - pnp_d = NULL; - if ((pnp_d = pnp_find_dev(pnp_c, - ipid->vendor, ipid->function, pnp_d))) { - int err; - - printk(KERN_INFO "HiSax: %s detected\n", - (char *)ipid->driver_data); - pnp_disable_dev(pnp_d); - err = pnp_activate_dev(pnp_d); - if (err < 0) { - printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", - __func__, err); - return (0); - } - card->para[1] = pnp_port_start(pnp_d, 0); - card->para[0] = pnp_irq(pnp_d, 0); - if (card->para[0] == -1 || !card->para[1]) { - printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n", - card->para[0], card->para[1]); - pnp_disable_dev(pnp_d); - return (0); - } - cs->hw.diva.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (ipid->function == ISAPNP_FUNCTION(0xA1)) { - cs->subtyp = DIVA_IPAC_ISA; - cs->hw.diva.ctrl = 0; - cs->hw.diva.isac = - card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.hscx = - card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.isac_adr = - card->para[1] + DIVA_IPAC_ADR; - cs->hw.diva.hscx_adr = - card->para[1] + DIVA_IPAC_ADR; - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - } else { - cs->subtyp = DIVA_ISA; - cs->hw.diva.ctrl = - card->para[1] + DIVA_ISA_CTRL; - cs->hw.diva.isac = - card->para[1] + DIVA_ISA_ISAC_DATA; - cs->hw.diva.hscx = - card->para[1] + DIVA_HSCX_DATA; - cs->hw.diva.isac_adr = - card->para[1] + DIVA_ISA_ISAC_ADR; - cs->hw.diva.hscx_adr = - card->para[1] + DIVA_HSCX_ADR; - } - return (1); /* card found */ - } else { - printk(KERN_ERR "Diva PnP: PnP error card found, no device\n"); - return (0); - } - } - ipid++; - pnp_c = NULL; - } - - return (-1); /* card not found; continue search */ -} - -#else /* if !ISAPNP */ - -static int setup_diva_isapnp(struct IsdnCard *card) -{ - return (-1); /* card not found; continue search */ -} - -#endif /* ISAPNP */ - -#ifdef CONFIG_PCI -static struct pci_dev *dev_diva = NULL; -static struct pci_dev *dev_diva_u = NULL; -static struct pci_dev *dev_diva201 = NULL; -static struct pci_dev *dev_diva202 = NULL; - -static int setup_diva_pci(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - - cs->subtyp = 0; - if ((dev_diva = hisax_find_pci_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) { - if (pci_enable_device(dev_diva)) - return (0); - cs->subtyp = DIVA_PCI; - cs->irq = dev_diva->irq; - cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2); - } else if ((dev_diva_u = hisax_find_pci_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) { - if (pci_enable_device(dev_diva_u)) - return (0); - cs->subtyp = DIVA_PCI; - cs->irq = dev_diva_u->irq; - cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2); - } else if ((dev_diva201 = hisax_find_pci_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) { - if (pci_enable_device(dev_diva201)) - return (0); - cs->subtyp = DIVA_IPAC_PCI; - cs->irq = dev_diva201->irq; - cs->hw.diva.pci_cfg = - (ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096); - cs->hw.diva.cfg_reg = - (ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096); - } else if ((dev_diva202 = hisax_find_pci_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) { - if (pci_enable_device(dev_diva202)) - return (0); - cs->subtyp = DIVA_IPACX_PCI; - cs->irq = dev_diva202->irq; - cs->hw.diva.pci_cfg = - (ulong) ioremap(pci_resource_start(dev_diva202, 0), 4096); - cs->hw.diva.cfg_reg = - (ulong) ioremap(pci_resource_start(dev_diva202, 1), 4096); - } else { - return (-1); /* card not found; continue search */ - } - - if (!cs->irq) { - printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); - iounmap_diva(cs); - return (0); - } - - if (!cs->hw.diva.cfg_reg) { - printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); - iounmap_diva(cs); - return (0); - } - cs->irq_flags |= IRQF_SHARED; - - if ((cs->subtyp == DIVA_IPAC_PCI) || - (cs->subtyp == DIVA_IPACX_PCI)) { - cs->hw.diva.ctrl = 0; - cs->hw.diva.isac = 0; - cs->hw.diva.hscx = 0; - cs->hw.diva.isac_adr = 0; - cs->hw.diva.hscx_adr = 0; - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - } else { - cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL; - cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA; - cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA; - cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR; - cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR; - } - - return (1); /* card found */ -} - -#else /* if !CONFIG_PCI */ - -static int setup_diva_pci(struct IsdnCard *card) -{ - return (-1); /* card not found; continue search */ -} - -#endif /* CONFIG_PCI */ - -int setup_diva(struct IsdnCard *card) -{ - int rc, have_card = 0; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, Diva_revision); - printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_DIEHLDIVA) - return (0); - cs->hw.diva.status = 0; - - rc = setup_diva_isa(card); - if (!rc) - return rc; - if (rc > 0) { - have_card = 1; - goto ready; - } - - rc = setup_diva_isapnp(card); - if (!rc) - return rc; - if (rc > 0) { - have_card = 1; - goto ready; - } - - rc = setup_diva_pci(card); - if (!rc) - return rc; - if (rc > 0) - have_card = 1; - -ready: - if (!have_card) { - printk(KERN_WARNING "Diva: No ISA, ISAPNP or PCI card found\n"); - return (0); - } - - return setup_diva_common(card->cs); -} |