From 122649d2e005abd9d0bc98898ff0dfd54f81e789 Mon Sep 17 00:00:00 2001 From: Kai Germaschewski Date: Thu, 6 Mar 2003 12:56:03 -0600 Subject: [PATCH] ISDN/HiSax: Introduce probe() functions Just separate the setup_*() functions of hisax subdrivers into calls to *_probe() functions, a step towards using standard initialization and modularization of hisax. --- drivers/isdn/hisax/asuscom.c | 81 +++-- drivers/isdn/hisax/avm_a1.c | 41 +-- drivers/isdn/hisax/avm_a1p.c | 32 +- drivers/isdn/hisax/avm_pci.c | 149 ++++---- drivers/isdn/hisax/bkm_a4t.c | 100 +++--- drivers/isdn/hisax/diva.c | 407 ++++++++++++---------- drivers/isdn/hisax/elsa.c | 558 ++++++++++++++++-------------- drivers/isdn/hisax/enternow_pci.c | 136 ++++---- drivers/isdn/hisax/gazel.c | 373 +++++++++----------- drivers/isdn/hisax/hfc_pci.c | 124 ++++--- drivers/isdn/hisax/hfc_sx.c | 126 ++++--- drivers/isdn/hisax/hfcscard.c | 85 +++-- drivers/isdn/hisax/isurf.c | 135 ++++---- drivers/isdn/hisax/ix1_micro.c | 54 +-- drivers/isdn/hisax/mic.c | 30 +- drivers/isdn/hisax/niccy.c | 125 ++++--- drivers/isdn/hisax/nj_s.c | 161 ++++----- drivers/isdn/hisax/nj_u.c | 143 ++++---- drivers/isdn/hisax/s0box.c | 25 +- drivers/isdn/hisax/saphir.c | 50 +-- drivers/isdn/hisax/sedlbauer.c | 550 ++++++++++++++++------------- drivers/isdn/hisax/sportster.c | 63 ++-- drivers/isdn/hisax/teleint.c | 78 +++-- drivers/isdn/hisax/teles0.c | 127 ++++--- drivers/isdn/hisax/teles3.c | 256 ++++++++------ drivers/isdn/hisax/telespci.c | 74 ++-- drivers/isdn/hisax/w6692.c | 100 +++--- 27 files changed, 2255 insertions(+), 1928 deletions(-) diff --git a/drivers/isdn/hisax/asuscom.c b/drivers/isdn/hisax/asuscom.c index b86727ba1add9..7b2809b9e0b16 100644 --- a/drivers/isdn/hisax/asuscom.c +++ b/drivers/isdn/hisax/asuscom.c @@ -231,6 +231,51 @@ static struct card_ops asuscom_ipac_ops = { .irq_func = ipac_irq, }; +static int __init +asuscom_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + int rc; + u8 val; + + printk(KERN_INFO "ISDNLink: defined at %#lx IRQ %lu\n", + card->para[1], card->para[0]); + + cs->hw.asus.cfg_reg = card->para[1]; + cs->irq = card->para[0]; + + rc = -EBUSY; + if (!request_io(&cs->rs, cs->hw.asus.cfg_reg, 8, "asuscom isdn")) + goto err; + + rc = -ENODEV; + cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_IPAC_ALE; + val = readreg(cs, cs->hw.asus.cfg_reg + ASUS_IPAC_DATA, IPAC_ID); + if ((val == 1) || (val == 2)) { + cs->subtyp = ASUS_IPAC; + cs->card_ops = &asuscom_ipac_ops; + cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA; + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; + } else { + cs->subtyp = ASUS_ISACHSCX; + cs->card_ops = &asuscom_ops; + cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_ADR; + cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_ISAC; + cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_HSCX; + cs->hw.asus.u7 = cs->hw.asus.cfg_reg + ASUS_CTRL_U7; + cs->hw.asus.pots = cs->hw.asus.cfg_reg + ASUS_CTRL_POTS; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + } + printk(KERN_INFO "ISDNLink: resetting card\n"); + cs->card_ops->reset(cs); + return 0; + + err: + hisax_release_resources(cs); + return rc; +} + #ifdef __ISAPNP__ static struct isapnp_device_id asus_ids[] __initdata = { { ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688), @@ -255,9 +300,6 @@ static struct pnp_card *pnp_c __devinitdata = NULL; int __init setup_asuscom(struct IsdnCard *card) { - int bytecnt; - struct IsdnCardState *cs = card->cs; - u8 val; char tmp[64]; strcpy(tmp, Asuscom_revision); @@ -310,36 +352,7 @@ setup_asuscom(struct IsdnCard *card) } } #endif - bytecnt = 8; - cs->hw.asus.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (!request_io(&cs->rs, cs->hw.asus.cfg_reg, bytecnt, "asuscom isdn")) - goto err; - printk(KERN_INFO "ISDNLink: defined at 0x%x IRQ %d\n", - cs->hw.asus.cfg_reg, cs->irq); - cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_IPAC_ALE; - val = readreg(cs, cs->hw.asus.cfg_reg + ASUS_IPAC_DATA, IPAC_ID); - if ((val == 1) || (val == 2)) { - cs->subtyp = ASUS_IPAC; - cs->card_ops = &asuscom_ipac_ops; - cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_IPAC_DATA; - if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) - goto err; - } else { - cs->subtyp = ASUS_ISACHSCX; - cs->card_ops = &asuscom_ops; - cs->hw.asus.adr = cs->hw.asus.cfg_reg + ASUS_ADR; - cs->hw.asus.isac = cs->hw.asus.cfg_reg + ASUS_ISAC; - cs->hw.asus.hscx = cs->hw.asus.cfg_reg + ASUS_HSCX; - cs->hw.asus.u7 = cs->hw.asus.cfg_reg + ASUS_CTRL_U7; - cs->hw.asus.pots = cs->hw.asus.cfg_reg + ASUS_CTRL_POTS; - if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - goto err; - } - printk(KERN_INFO "ISDNLink: resetting card\n"); - cs->card_ops->reset(cs); + if (asuscom_probe(card->cs, card) < 0) + return 0; return 1; - err: - hisax_release_resources(cs); - return 0; } diff --git a/drivers/isdn/hisax/avm_a1.c b/drivers/isdn/hisax/avm_a1.c index adea9b9521259..675312eaddfb9 100644 --- a/drivers/isdn/hisax/avm_a1.c +++ b/drivers/isdn/hisax/avm_a1.c @@ -160,16 +160,16 @@ static struct card_ops avm_a1_ops = { .irq_func = avm_a1_interrupt, }; -int __init -setup_avm_a1(struct IsdnCard *card) +static int __init +avm_a1_probe(struct IsdnCardState *cs, struct IsdnCard *card) { + int rc; u8 val; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - strcpy(tmp, avm_revision); - printk(KERN_INFO "HiSax: AVM driver Rev. %s\n", HiSax_getrev(tmp)); + printk(KERN_INFO "AVM A1: defined at %#lx IRQ %lu\n", + card->para[1], card->para[0]); + rc = -EBUSY; cs->hw.avm.cfg_reg = request_io(&cs->rs, card->para[1] + 0x1800, 8, "avm cfg"); if (!cs->hw.avm.cfg_reg) goto err; cs->hw.avm.isac = request_io(&cs->rs, card->para[1] + 0x1400, 32, "HiSax isac"); @@ -216,23 +216,24 @@ setup_avm_a1(struct IsdnCard *card) printk(KERN_INFO "AVM A1: Byte at %x is %x\n", cs->hw.avm.cfg_reg, val); - printk(KERN_INFO - "HiSax: %s config irq:%d cfg:0x%X\n", - CardType[cs->typ], cs->irq, - cs->hw.avm.cfg_reg); - printk(KERN_INFO - "HiSax: isac:0x%X/0x%X\n", - cs->hw.avm.isac + 32, cs->hw.avm.isacfifo); - printk(KERN_INFO - "HiSax: hscx A:0x%X/0x%X hscx B:0x%X/0x%X\n", - cs->hw.avm.hscx[0] + 32, cs->hw.avm.hscxfifo[0], - cs->hw.avm.hscx[1] + 32, cs->hw.avm.hscxfifo[1]); - cs->card_ops = &avm_a1_ops; if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) goto err; - return 1; + return 0; err: hisax_release_resources(cs); - return 0; + return rc; +} + +int __init +setup_avm_a1(struct IsdnCard *card) +{ + char tmp[64]; + + strcpy(tmp, avm_revision); + printk(KERN_INFO "HiSax: AVM driver Rev. %s\n", HiSax_getrev(tmp)); + + if (avm_a1_probe(card->cs, card) < 0) + return 0; + return 1; } diff --git a/drivers/isdn/hisax/avm_a1p.c b/drivers/isdn/hisax/avm_a1p.c index 3cac20543f0a5..18469ba0110d2 100644 --- a/drivers/isdn/hisax/avm_a1p.c +++ b/drivers/isdn/hisax/avm_a1p.c @@ -215,20 +215,13 @@ static struct card_ops avm_a1p_ops = { .irq_func = avm_a1p_interrupt, }; -int __devinit -setup_avm_a1_pcmcia(struct IsdnCard *card) +static int __init +avm_a1p_probe(struct IsdnCardState *cs, struct IsdnCard *card) { u8 model, vers; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, avm_revision); - printk(KERN_INFO "HiSax: AVM A1 PCMCIA driver Rev. %s\n", - HiSax_getrev(tmp)); - cs->hw.avm.cfg_reg = card->para[1]; cs->irq = card->para[0]; - + cs->hw.avm.cfg_reg = card->para[1]; outb(cs->hw.avm.cfg_reg+ASL1_OFFSET, ASL1_W_ENABLE_S0); @@ -244,11 +237,26 @@ setup_avm_a1_pcmcia(struct IsdnCard *card) vers = bytein(cs->hw.avm.cfg_reg+VERREG_OFFSET); printk(KERN_INFO "AVM A1 PCMCIA: io 0x%x irq %d model %d version %d\n", - cs->hw.avm.cfg_reg, cs->irq, model, vers); + cs->hw.avm.cfg_reg, cs->irq, model, vers); cs->card_ops = &avm_a1p_ops; if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - return 0; + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} +int __devinit +setup_avm_a1_pcmcia(struct IsdnCard *card) +{ + char tmp[64]; + + strcpy(tmp, avm_revision); + printk(KERN_INFO "HiSax: AVM A1 PCMCIA driver Rev. %s\n", + HiSax_getrev(tmp)); + if (avm_a1p_probe(card->cs, card)) + return 0; return 1; } diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c index d938e3dcf1c9d..9a0eea542f3b4 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c @@ -497,7 +497,7 @@ static struct bc_l1_ops hdlc_l1_ops = { .close = close_hdlcstate, }; -void __init +static void __init inithdlc(struct IsdnCardState *cs) { u_int val; @@ -596,6 +596,82 @@ static struct card_ops avm_pci_ops = { .irq_func = avm_pcipnp_interrupt, }; +static int __init +avm_pcipnp_hw_init(struct IsdnCardState *cs) +{ + cs->bc_hw_ops = &hdlc_hw_ops; + cs->bc_l1_ops = &hdlc_l1_ops; + cs->card_ops = &avm_pci_ops; + avm_pcipnp_reset(cs); + return isac_setup(cs, &isac_ops); +} + +static int __init +avm_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + int rc; + u32 val; + + printk(KERN_INFO "AVM PCI: defined at %#lx IRQ %u\n", + pci_resource_start(pdev, 1), pdev->irq); + + rc = -EBUSY; + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = AVM_FRITZ_PCI; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.avm.cfg_reg = pci_resource_start(pdev, 1); + cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10; + if (!request_io(&cs->rs, cs->hw.avm.cfg_reg, 32, "avm PCI")) + goto err; + + val = inl(cs->hw.avm.cfg_reg); + printk(KERN_INFO "AVM PCI: stat %#x\n", val); + printk(KERN_INFO "AVM PCI: Class %X Rev %d\n", + val & 0xff, (val>>8) & 0xff); + + if (avm_pcipnp_hw_init(cs)) + goto err; + + return 0; + err: + hisax_release_resources(cs); + return rc; +} + +static int __init +avm_pnp_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + int rc; + u8 val, ver; + + printk(KERN_INFO "AVM PnP: defined at %#lx IRQ %lu\n", + card->para[1], card->para[0]); + + cs->subtyp = AVM_FRITZ_PNP; + cs->irq = card->para[0]; + cs->hw.avm.cfg_reg = card->para[1]; + cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10; + + rc = -EBUSY; + if (!request_io(&cs->rs, cs->hw.avm.cfg_reg, 32, "avm PnP")) + goto err; + + val = inb(cs->hw.avm.cfg_reg); + ver = inb(cs->hw.avm.cfg_reg + 1); + printk(KERN_INFO "AVM PnP: Class %X Rev %d\n", val, ver); + + if (avm_pcipnp_hw_init(cs)) + goto err; + + return 0; + err: + hisax_release_resources(cs); + return rc; +} + static struct pci_dev *dev_avm __initdata = NULL; #ifdef __ISAPNP__ static struct pnp_card *card_avm __initdata = NULL; @@ -605,17 +681,15 @@ static struct pnp_dev *pnp_avm __initdata = NULL; int __init setup_avm_pcipnp(struct IsdnCard *card) { - u_int val, ver; - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, avm_pci_rev); printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp)); if (card->para[1]) { /* old manual method */ - cs->hw.avm.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - cs->subtyp = AVM_FRITZ_PNP; + if (avm_pnp_probe(card->cs, card)) + return 0; + return 1; } else { #ifdef __ISAPNP__ if (isapnp_present()) { @@ -647,69 +721,24 @@ setup_avm_pcipnp(struct IsdnCard *card) pnp_device_detach(pnp_avm); return(0); } - cs->hw.avm.cfg_reg = pnp_port_start(pnp_avm, 0); - cs->irq = pnp_irq(pnp_avm, 0); - cs->subtyp = AVM_FRITZ_PNP; - goto ready; + card->para[1] = pnp_port_start(pnp_avm, 0); + card->para[0] = pnp_irq(pnp_avm, 0); + if (avm_pnp_probe(card->cs, card)) + return 0; + return 1; } } - } else { - printk(KERN_INFO "FritzPnP: no ISA PnP present\n"); } #endif #if CONFIG_PCI if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1, dev_avm))) { - cs->irq = dev_avm->irq; - if (!cs->irq) { - printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n"); - return(0); - } - if (pci_enable_device(dev_avm)) - return(0); - cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1); - if (!cs->hw.avm.cfg_reg) { - printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n"); - return(0); - } - cs->subtyp = AVM_FRITZ_PCI; - } else { - printk(KERN_WARNING "FritzPCI: No PCI card found\n"); - return(0); + if (avm_pci_probe(card->cs, dev_avm)) + return 0; + return 1; } - cs->irq_flags |= SA_SHIRQ; #endif /* CONFIG_PCI */ } -ready: - cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10; - if (!request_io(&cs->rs, cs->hw.avm.cfg_reg, 32, - cs->subtyp == AVM_FRITZ_PCI ? "avm PCI" : "avm PnP")) - goto err; - - switch (cs->subtyp) { - case AVM_FRITZ_PCI: - val = inl(cs->hw.avm.cfg_reg); - printk(KERN_INFO "AVM PCI: stat %#x\n", val); - printk(KERN_INFO "AVM PCI: Class %X Rev %d\n", - val & 0xff, (val>>8) & 0xff); - break; - case AVM_FRITZ_PNP: - val = inb(cs->hw.avm.cfg_reg); - ver = inb(cs->hw.avm.cfg_reg + 1); - printk(KERN_INFO "AVM PnP: Class %X Rev %d\n", val, ver); - avm_pcipnp_reset(cs); - break; - } - printk(KERN_INFO "HiSax: %s config irq:%d base:0x%X\n", - (cs->subtyp == AVM_FRITZ_PCI) ? "AVM Fritz!PCI" : "AVM Fritz!PnP", - cs->irq, cs->hw.avm.cfg_reg); - - cs->bc_hw_ops = &hdlc_hw_ops; - cs->bc_l1_ops = &hdlc_l1_ops; - cs->card_ops = &avm_pci_ops; - isac_setup(cs, &isac_ops); - return 1; - err: - hisax_release_resources(cs); + printk(KERN_WARNING "FritzPCI: No card found\n"); return 0; } diff --git a/drivers/isdn/hisax/bkm_a4t.c b/drivers/isdn/hisax/bkm_a4t.c index ce08c2b9442df..ab53ed901455e 100644 --- a/drivers/isdn/hisax/bkm_a4t.c +++ b/drivers/isdn/hisax/bkm_a4t.c @@ -21,11 +21,11 @@ #include "bkm_ax.h" extern const char *CardType[]; +// FIXME needs per card lock static spinlock_t bkm_a4t_lock = SPIN_LOCK_UNLOCKED; const char *bkm_a4t_revision = "$Revision: 1.13.6.6 $"; - static inline u8 readreg(unsigned int ale, unsigned long adr, u8 off) { @@ -249,15 +249,57 @@ static struct card_ops bkm_a4t_ops = { .irq_func = bkm_interrupt, }; +static int __init +bkm_a4t_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + I20_REGISTER_FILE *pI20_Regs; + int rc; + + printk(KERN_INFO "BKM A4T: defined at %#lx IRQ %u\n", + pci_resource_start(pdev, 0), pdev->irq); + + rc = -EBUSY; + if (pci_enable_device(pdev)) + goto err; + + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.avm.cfg_reg = pci_resource_start(pdev, 1); + + cs->hw.ax.base = (unsigned long)request_mmio(&cs->rs, pci_resource_start(pdev, 0), 4096, "Telekom A4T"); + if (!cs->hw.ax.base) + goto err; + + /* Check suspicious address */ + // FIXME needs to use read[bl] + pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); + if ((pI20_Regs->i20IntStatus & 0x8EFFFFFF) != 0) { + printk(KERN_WARNING "HiSax: address %lx suspicious\n", + cs->hw.ax.base); + goto err; + } + cs->hw.ax.isac_adr = cs->hw.ax.base + PO_OFFSET; + cs->hw.ax.jade_adr = cs->hw.ax.base + PO_OFFSET; + cs->hw.ax.isac_ale = GCS_1; + cs->hw.ax.jade_ale = GCS_3; + + reset_bkm(cs); + cs->card_ops = &bkm_a4t_ops; + isac_setup(cs, &isac_ops); + jade_setup(cs, &jade_ops); + return 0; + + err: + hisax_release_resources(cs); + return rc; +} + static struct pci_dev *dev_a4t __initdata = NULL; int __init setup_bkm_a4t(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; - u_int pci_memaddr = 0, found = 0; - I20_REGISTER_FILE *pI20_Regs; strcpy(tmp, bkm_a4t_revision); printk(KERN_INFO "HiSax: T-Berkom driver Rev. %s\n", HiSax_getrev(tmp)); @@ -268,49 +310,13 @@ setup_bkm_a4t(struct IsdnCard *card) sub_vendor = dev_a4t->subsystem_vendor; sub_sys = dev_a4t->subsystem_device; - if ((sub_sys == PCI_DEVICE_ID_BERKOM_A4T) && (sub_vendor == PCI_VENDOR_ID_BERKOM)) { - if (pci_enable_device(dev_a4t)) - return(0); - found = 1; - pci_memaddr = pci_resource_start(dev_a4t, 0); - cs->irq = dev_a4t->irq; - break; + if (sub_sys == PCI_DEVICE_ID_BERKOM_A4T && + sub_vendor == PCI_VENDOR_ID_BERKOM) { + if (bkm_a4t_probe(card->cs, dev_a4t)) + return 0; + return 1; } } - if (!found) { - printk(KERN_WARNING "HiSax: %s: Card not found\n", CardType[card->typ]); - return (0); - } - if (!cs->irq) { /* IRQ range check ?? */ - printk(KERN_WARNING "HiSax: %s: No IRQ\n", CardType[card->typ]); - return (0); - } - cs->hw.ax.base = (unsigned long)request_mmio(&cs->rs,pci_memaddr, 4096, "Telekom A4T"); - if (!cs->hw.ax.base) { - printk(KERN_WARNING "HiSax: %s: No Memory base address\n", CardType[card->typ]); - return (0); - } - - /* Check suspecious address */ - pI20_Regs = (I20_REGISTER_FILE *) (cs->hw.ax.base); - if ((pI20_Regs->i20IntStatus & 0x8EFFFFFF) != 0) { - printk(KERN_WARNING "HiSax: %s address %lx-%lx suspecious\n", - CardType[card->typ], cs->hw.ax.base, cs->hw.ax.base + 4096); - hisax_release_resources(cs); - return (0); - } - cs->hw.ax.isac_adr = cs->hw.ax.base + PO_OFFSET; - cs->hw.ax.jade_adr = cs->hw.ax.base + PO_OFFSET; - cs->hw.ax.isac_ale = GCS_1; - cs->hw.ax.jade_ale = GCS_3; - - printk(KERN_INFO "HiSax: %s: Card configured at 0x%lX IRQ %d\n", - CardType[card->typ], cs->hw.ax.base, cs->irq); - - reset_bkm(cs); - cs->irq_flags |= SA_SHIRQ; - cs->card_ops = &bkm_a4t_ops; - isac_setup(cs, &isac_ops); - jade_setup(cs, &jade_ops); - return 1; + printk(KERN_WARNING "HiSax: %s: Card not found\n", CardType[card->typ]); + return 0; } diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c index c9cf0ddd04e9f..3539afa669220 100644 --- a/drivers/isdn/hisax/diva.c +++ b/drivers/isdn/hisax/diva.c @@ -362,7 +362,7 @@ diva_ipacx_pci_irq(int intno, void *dev_id, struct pt_regs *regs) static void diva_release(struct IsdnCardState *cs) { - del_timer(&cs->hw.diva.tl); + del_timer_sync(&cs->hw.diva.tl); if (cs->hw.diva.cfg_reg) byteout(cs->hw.diva.ctrl, 0); /* LED off, Reset */ @@ -515,6 +515,162 @@ static struct card_ops diva_ipacx_pci_ops = { .irq_func = diva_ipacx_pci_irq, }; +static int __init +diva_ipac_probe(struct IsdnCardState *cs) +{ + u8 val; + + // request_io + 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); + return (val == 1 || val == 2); +} + +static int __init +diva_ipac_isa_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->subtyp = DIVA_IPAC_ISA; + cs->irq = card->para[0]; + cs->hw.diva.cfg_reg = card->para[1]; + cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA; + cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR; + printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n", + "IPAC ISA", cs->hw.diva.cfg_reg, cs->irq); + if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, 8, "diva isdn")) + goto err; + diva_ipac_isa_reset(cs); + cs->card_ops = &diva_ipac_isa_ops; + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +diva_isac_isa_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->subtyp = DIVA_ISA; + cs->irq = card->para[0]; + cs->hw.diva.cfg_reg = card->para[1]; + 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; + printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n", + "ISA", cs->hw.diva.cfg_reg, cs->irq); + if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, 8, "diva isdn")) + goto err; + diva_reset(cs); + init_timer(&cs->hw.diva.tl); + cs->hw.diva.tl.function = (void *) diva_led_handler; + cs->hw.diva.tl.data = (long) cs; + cs->card_ops = &diva_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +diva_isa_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + int is_ipac; + cs->hw.diva.cfg_reg = card->para[1]; + if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, 8, "diva isdn")) + return -EBUSY; + + is_ipac = diva_ipac_probe(cs); + hisax_release_resources(cs); + + if (is_ipac) + return diva_ipac_isa_probe(cs, card); + else + return diva_isac_isa_probe(cs, card); +} + +static int __init +diva_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = DIVA_PCI; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.diva.cfg_reg = pci_resource_start(pdev, 2); + 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; + printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n", + "PCI", cs->hw.diva.cfg_reg, cs->irq); + printk(KERN_INFO "Diva: %s space at %#lx\n", + "PCI", cs->hw.diva.pci_cfg); + if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, 32, "diva isdn")) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +diva_ipac_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = DIVA_IPAC_PCI; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.diva.pci_cfg = (unsigned long)request_mmio( + &cs->rs, pci_resource_start(pdev, 0), 4096, "diva"); + cs->hw.diva.cfg_reg = (unsigned long)request_mmio( + &cs->rs, pci_resource_start(pdev, 1), 4096, "diva"); + printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n", + "IPAC PCI", cs->hw.diva.cfg_reg, cs->irq); + printk(KERN_INFO "Diva: %s space at %#lx\n", + "IPAC PCI", cs->hw.diva.pci_cfg); + diva_ipac_pci_reset(cs); + cs->card_ops = &diva_ipac_pci_ops; + if (ipac_setup(cs, &mem_ipac_dc_ops, &mem_ipac_bc_ops)) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +diva_ipacx_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = DIVA_IPACX_PCI; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n", + "IPACX PCI", cs->hw.diva.cfg_reg, cs->irq); + printk(KERN_INFO "Diva: %s space at %#lx\n", + "IPACX PCI", cs->hw.diva.pci_cfg); + diva_ipacx_pci_reset(cs); + cs->card_ops = &diva_ipacx_pci_ops; + if (ipacx_setup(cs, &ipacx_dc_ops, &ipacx_bc_ops)) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + static struct pci_dev *dev_diva __initdata = NULL; static struct pci_dev *dev_diva_u __initdata = NULL; static struct pci_dev *dev_diva201 __initdata = NULL; @@ -545,101 +701,60 @@ static struct isapnp_device_id *pdev = &diva_ids[0]; static struct pnp_card *pnp_c __devinitdata = NULL; #endif - int __init setup_diva(struct IsdnCard *card) { - int bytecnt = 8; - u8 val; - 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 (card->para[1]) { - 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; - } 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]; - } else { + if (diva_isa_probe(card->cs, card) < 0) + return 0; + return 1; + + } #ifdef __ISAPNP__ - if (isapnp_present()) { - struct pnp_card *pb; - struct pnp_dev *pd; - - while(pdev->card_vendor) { - if ((pb = pnp_find_card(pdev->card_vendor, - pdev->card_device, - pnp_c))) { - pnp_c = pb; - pd = NULL; - if ((pd = pnp_find_dev(pnp_c, - pdev->vendor, - pdev->function, - pd))) { - printk(KERN_INFO "HiSax: %s detected\n", - (char *)pdev->driver_data); - if (pnp_device_attach(pd) < 0) { - printk(KERN_ERR "Diva PnP: attach failed\n"); + if (isapnp_present()) { + struct pnp_card *pb; + struct pnp_dev *pd; + + while(pdev->card_vendor) { + if ((pb = pnp_find_card(pdev->card_vendor, + pdev->card_device, pnp_c))) { + pnp_c = pb; + pd = NULL; + if ((pd = pnp_find_dev(pnp_c, + pdev->vendor, + pdev->function, + pd))) { + printk(KERN_INFO "HiSax: %s detected\n", + (char *)pdev->driver_data); + if (pnp_device_attach(pd) < 0) { + printk(KERN_ERR "Diva PnP: attach failed\n"); + return 0; + } + if (pnp_activate_dev(pd) < 0) { + printk(KERN_ERR "Diva PnP: activate failed\n"); + pnp_device_detach(pd); + return 0; + } + if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0)) { + printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n", + pnp_irq(pd, 0), pnp_port_start(pd, 0)); + pnp_device_detach(pd); + return(0); + } + card->para[1] = pnp_port_start(pd, 0); + card->para[0] = pnp_irq(pd, 0); + if (pdev->function == ISAPNP_FUNCTION(0xA1)) { + if (diva_ipac_isa_probe(cs->card, cs)) return 0; - } - if (pnp_activate_dev(pd) < 0) { - printk(KERN_ERR "Diva PnP: activate failed\n"); - pnp_device_detach(pd); + return 1; + } else { + if (diva_isac_isa_probe(cs->card, cs)) return 0; - } - if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0)) { - printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n", - pnp_irq(pd, 0), pnp_port_start(pd, 0)); - pnp_device_detach(pd); - return(0); - } - card->para[1] = pnp_port_start(pd, 0); - card->para[0] = pnp_irq(pd, 0); - cs->hw.diva.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (pdev->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; - } 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; - } - goto ready; + return 1; } else { printk(KERN_ERR "Diva PnP: PnP error card found, no device\n"); return(0); @@ -652,111 +767,29 @@ setup_diva(struct IsdnCard *card) printk(KERN_INFO "Diva PnP: no ISAPnP card found\n"); } } + } #endif #if CONFIG_PCI - cs->subtyp = 0; - if ((dev_diva = pci_find_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 = pci_find_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 = pci_find_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 = (unsigned long)request_mmio(&cs->rs, pci_resource_start(dev_diva201, 0), 4096, "diva"); - cs->hw.diva.cfg_reg = (unsigned long)request_mmio(&cs->rs, pci_resource_start(dev_diva201, 1), 4096, "diva"); - } else { - printk(KERN_WARNING "Diva: No PCI card found\n"); - return(0); - } - - if (!cs->irq) { - printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); - goto err; - } - - if (!cs->hw.diva.cfg_reg) { - printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); - goto err; - } - cs->irq_flags |= SA_SHIRQ; -#endif /* CONFIG_PCI */ - 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; - bytecnt = 0; - } 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; - bytecnt = 32; - } - } -ready: - 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_io(&cs->rs, cs->hw.diva.cfg_reg, bytecnt, "diva isdn")) + if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON, + PCI_DEVICE_ID_EICON_DIVA20, + dev_diva))) { + if (diva_pci_probe(card->cs, dev_diva)) return 0; + return 1; + } else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON, + PCI_DEVICE_ID_EICON_DIVA20_U, + dev_diva_u))) { + if (diva_pci_probe(card->cs, dev_diva_u)) + return 0; + return 1; + } else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON, + PCI_DEVICE_ID_EICON_DIVA201, + dev_diva201))) { + if (diva_ipac_pci_probe(card->cs, dev_diva201)) + return 0; + return 1; } - if (cs->subtyp == DIVA_IPAC_ISA) { - diva_ipac_isa_reset(cs); - cs->card_ops = &diva_ipac_isa_ops; - if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) - goto err; - } else if (cs->subtyp == DIVA_IPAC_PCI) { - diva_ipac_pci_reset(cs); - cs->card_ops = &diva_ipac_pci_ops; - if (ipac_setup(cs, &mem_ipac_dc_ops, &mem_ipac_bc_ops)) - goto err; - } else if (cs->subtyp == DIVA_IPACX_PCI) { - diva_ipacx_pci_reset(cs); - cs->card_ops = &diva_ipacx_pci_ops; - if (ipacx_setup(cs, &ipacx_dc_ops, &ipacx_bc_ops)) - goto err; - } else { /* DIVA 2.0 */ - diva_reset(cs); - cs->hw.diva.tl.function = (void *) diva_led_handler; - cs->hw.diva.tl.data = (long) cs; - init_timer(&cs->hw.diva.tl); - cs->card_ops = &diva_ops; - if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - goto err; - } - return 1; - err: - diva_release(cs); + printk(KERN_WARNING "Diva: No PCI card found\n"); +#endif /* CONFIG_PCI */ return 0; - } diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c index f9d4ed94ae313..bfc96a3e53206 100644 --- a/drivers/isdn/hisax/elsa.c +++ b/drivers/isdn/hisax/elsa.c @@ -690,7 +690,47 @@ static struct card_ops elsa_ipac_ops = { .irq_func = elsa_interrupt_ipac, }; -static unsigned char +static void __init +elsa_arcofi_init(struct IsdnCardState *cs) +{ +#if ARCOFI_USE + init_arcofi(cs); +#endif +} + +static void __init +elsa_timer_init(struct IsdnCardState *cs) +{ + cs->hw.elsa.tl.function = (void *) elsa_led_handler; + cs->hw.elsa.tl.data = (long) cs; + init_timer(&cs->hw.elsa.tl); +} + +static int __init +elsa_timer_test(struct IsdnCardState *cs) +{ + /* test timer */ + byteout(cs->hw.elsa.trig, 0xff); + byteout(cs->hw.elsa.timer, 0); + if (!TimerRun(cs)) { + byteout(cs->hw.elsa.timer, 0); /* second attempt */ + if (!TimerRun(cs)) { + printk(KERN_WARNING "Elsa: timer does not start\n"); + goto err; + } + } + HZDELAY(10 * HZ / 1000); /* wait >=10 ms */ + if (TimerRun(cs)) { + printk(KERN_WARNING "Elsa: timer does not run\n"); + goto err; + } + printk(KERN_INFO "Elsa: timer OK; resetting card\n"); + return 0; + err: + return -EBUSY; +} + +static unsigned char __init probe_elsa_adr(unsigned int adr, int typ) { int i, in1, in2, p16_1 = 0, p16_2 = 0, p8_1 = 0, p8_2 = 0, pc_1 = 0, @@ -699,15 +739,13 @@ probe_elsa_adr(unsigned int adr, int typ) /* In case of the elsa pcmcia card, this region is in use, reserved for us by the card manager. So we do not check it here, it would fail. */ - if (typ != ISDN_CTYPE_ELSA_PCMCIA && check_region(adr, 8)) { - printk(KERN_WARNING - "Elsa: Probing Port 0x%x: already in use\n", - adr); - return (0); + if (typ != ISDN_CTYPE_ELSA_PCMCIA && !request_region(adr, 8, "elsa")) { + printk(KERN_WARNING "Elsa: probing port 0x%x: in use\n", adr); + return 0; } for (i = 0; i < 16; i++) { - in1 = inb(adr + ELSA_CONFIG); /* 'toggelt' bei */ - in2 = inb(adr + ELSA_CONFIG); /* jedem Zugriff */ + in1 = inb(adr + ELSA_CONFIG); /* 'toggels' at */ + in2 = inb(adr + ELSA_CONFIG); /* each access */ p16_1 += 0x04 & in1; p16_2 += 0x04 & in2; p8_1 += 0x02 & in1; @@ -717,6 +755,7 @@ probe_elsa_adr(unsigned int adr, int typ) pfp_1 += 0x40 & in1; pfp_2 += 0x40 & in2; } + release_region(adr, 8); printk(KERN_INFO "Elsa: Probing IO 0x%x", adr); if (65 == ++p16_1 * ++p16_2) { printk(" PCC-16/PCF found\n"); @@ -736,18 +775,227 @@ probe_elsa_adr(unsigned int adr, int typ) } } -static unsigned int -probe_elsa(struct IsdnCardState *cs) +static int __init +elsa_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - int i; - unsigned int CARD_portlist[] = - {0x160, 0x170, 0x260, 0x360, 0}; - - for (i = 0; CARD_portlist[i]; i++) { - if ((cs->subtyp = probe_elsa_adr(CARD_portlist[i], cs->typ))) + u8 val; + int i, bytecnt = 8; + unsigned int CARD_portlist[] = {0x160, 0x170, 0x260, 0x360, 0}; + + cs->hw.elsa.base = card->para[0]; + printk(KERN_INFO "Elsa: Microlink IO probing\n"); + if (cs->hw.elsa.base) { + cs->subtyp = probe_elsa_adr(cs->hw.elsa.base, cs->typ); + if (!cs->subtyp) { + printk(KERN_WARNING "Elsa: no Microlink at %#lx\n", + cs->hw.elsa.base); + goto err; + } + } else { + for (i = 0; CARD_portlist[i]; i++) { + cs->subtyp = probe_elsa_adr(CARD_portlist[i], cs->typ); + if (cs->subtyp) + cs->hw.elsa.base = CARD_portlist[i]; break; + } + } + if (!cs->hw.elsa.base) + goto err; + + cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG; + cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL; + cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE; + cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC; + cs->hw.elsa.itac = cs->hw.elsa.base + ELSA_ITAC; + cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; + cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ; + cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER; + val = bytein(cs->hw.elsa.cfg); + if (cs->subtyp == ELSA_PC) { + const u8 CARD_IrqTab[8] = {7, 3, 5, 9, 0, 0, 0, 0}; + cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PC) >> 2]; + } else if (cs->subtyp == ELSA_PCC8) { + const u8 CARD_IrqTab[8] = {7, 3, 5, 9, 0, 0, 0, 0}; + cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PCC8) >> 4]; + } else { + const u8 CARD_IrqTab[8] = {15, 10, 15, 3, 11, 5, 11, 9}; + cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX) >> 3]; + } + val = bytein(cs->hw.elsa.ale) & ELSA_HW_RELEASE; + if (val < 3) + val |= 8; + val += 'A' - 3; + if (val == 'B' || val == 'C') + val ^= 1; + if ((cs->subtyp == ELSA_PCFPRO) && (val = 'G')) + val = 'C'; + printk(KERN_INFO "Elsa: %s found at %#lx Rev.:%c IRQ %d\n", + Elsa_Types[cs->subtyp], cs->hw.elsa.base, val, cs->irq); + val = bytein(cs->hw.elsa.ale) & ELSA_S0_POWER_BAD; + if (val) { + printk(KERN_WARNING "Elsa: Microlink S0 bus power bad\n"); + cs->hw.elsa.status |= ELSA_BAD_PWR; } - return (CARD_portlist[i]); + switch (cs->subtyp) { + case ELSA_PCFPRO: bytecnt = 16; break; + } + if (!request_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn")) + goto err; + elsa_arcofi_init(cs); + elsa_timer_init(cs); + if (elsa_timer_test(cs)) + goto err; + elsa_reset(cs); + cs->card_ops = &elsa_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + if (cs->subtyp == ELSA_PC) { + val = readitac(cs, ITAC_SYS); + printk(KERN_INFO "Elsa: ITAC version %s\n", ITACVer[val & 7]); + writeitac(cs, ITAC_ISEN, 0); + writeitac(cs, ITAC_RFIE, 0); + writeitac(cs, ITAC_XFIE, 0); + writeitac(cs, ITAC_SCIE, 0); + writeitac(cs, ITAC_STIE, 0); + } + return 0; + err: + elsa_release(cs); + return -EBUSY; +} + +static int __init +elsa_qs_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + int bytecnt = 8; + + cs->irq = card->para[0]; + cs->hw.elsa.base = card->para[1]; + cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG; + cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE; + cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC; + cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; + cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ; + cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER; + cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL; + printk(KERN_INFO "Elsa: %s defined at %#lx IRQ %d\n", + Elsa_Types[cs->subtyp], cs->hw.elsa.base, cs->irq); + switch (cs->subtyp) { + case ELSA_QS3000: bytecnt = 16; break; + } + if (!request_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn")) + goto err; + elsa_arcofi_init(cs); + elsa_timer_init(cs); + if (elsa_timer_test(cs)) + goto err; + elsa_reset(cs); + cs->card_ops = &elsa_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + return 0; + err: + elsa_release(cs); + return -EBUSY; +} + +static int __init +elsa_qs1000_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->subtyp = ELSA_QS1000; + return elsa_qs_probe(cs, card); +} + +static int __init +elsa_qs3000_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->subtyp = ELSA_QS3000; + return elsa_qs_probe(cs, card); +} + +static int __init +elsa_pcmcia_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + u8 val; + + cs->irq = card->para[0]; + cs->hw.elsa.base = card->para[1]; + cs->hw.elsa.ale = cs->hw.elsa.base + 0; + val = readreg(cs, cs->hw.elsa.base + 2, IPAC_ID); + if ((val == 1) || (val == 2)) { /* IPAC version 1.1/1.2 */ + cs->subtyp = ELSA_PCMCIA_IPAC; + cs->hw.elsa.isac = cs->hw.elsa.base + 2; + } else { + cs->subtyp = ELSA_PCMCIA; + cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE_PCM; + cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC_PCM; + cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; + } + cs->hw.elsa.timer = 0; + cs->hw.elsa.trig = 0; + cs->hw.elsa.ctrl = 0; + printk(KERN_INFO "Elsa: %s defined at %#lx IRQ %d\n", + Elsa_Types[cs->subtyp], cs->hw.elsa.base, cs->irq); + elsa_arcofi_init(cs); + elsa_reset(cs); + if (cs->subtyp == ELSA_PCMCIA_IPAC) { + cs->card_ops = &elsa_ipac_ops; + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; + } else { + cs->card_ops = &elsa_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + } + return 0; + err: + elsa_release(cs); + return -EBUSY; +} + +static int __init +elsa_qs_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev, + int subtyp) +{ + int bytecnt = 2; + u8 pci_rev; + + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = subtyp; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.elsa.cfg = pci_resource_start(pdev, 1); + cs->hw.elsa.base = pci_resource_start(pdev, 3); + pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev); + if (cs->hw.elsa.cfg & 0x80 && pci_rev == 1) { + printk(KERN_INFO "Elsa: PLX9050 rev1 workaround activated\n"); + __set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags); + } + cs->hw.elsa.ale = cs->hw.elsa.base; + cs->hw.elsa.isac = cs->hw.elsa.base +1; + cs->hw.elsa.hscx = cs->hw.elsa.base +1; + printk(KERN_INFO "Elsa: %s defined at %#lx/%#x IRQ %d\n", + Elsa_Types[cs->subtyp], cs->hw.elsa.base, cs->hw.elsa.cfg, + cs->irq); + switch (cs->subtyp) { + case ELSA_QS3000PCI: bytecnt = 16; break; + } + if (!request_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn")) + goto err; + if (!request_io(&cs->rs, cs->hw.elsa.cfg, 0x80, "elsa isdn pci")) + goto err; + elsa_arcofi_init(cs); + elsa_timer_init(cs); + elsa_reset(cs); + cs->card_ops = &elsa_ipac_ops; + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; + return 0; + err: + elsa_release(cs); + return -EBUSY; } static struct pci_dev *dev_qs1000 __devinitdata = NULL; @@ -771,83 +1019,21 @@ static struct pnp_card *pnp_c __devinitdata = NULL; int __devinit setup_elsa(struct IsdnCard *card) { - int bytecnt; - u8 val, pci_rev; - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, Elsa_revision); printk(KERN_INFO "HiSax: Elsa driver Rev. %s\n", HiSax_getrev(tmp)); - cs->hw.elsa.ctrl_reg = 0; - cs->hw.elsa.status = 0; - cs->hw.elsa.MFlag = 0; - cs->subtyp = 0; - if (cs->typ == ISDN_CTYPE_ELSA) { - cs->hw.elsa.base = card->para[0]; - printk(KERN_INFO "Elsa: Microlink IO probing\n"); - if (cs->hw.elsa.base) { - if (!(cs->subtyp = probe_elsa_adr(cs->hw.elsa.base, - cs->typ))) { - printk(KERN_WARNING - "Elsa: no Elsa Microlink at %#lx\n", - cs->hw.elsa.base); - return (0); - } - } else - cs->hw.elsa.base = probe_elsa(cs); - if (cs->hw.elsa.base) { - cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG; - cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL; - cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE; - cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC; - cs->hw.elsa.itac = cs->hw.elsa.base + ELSA_ITAC; - cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; - cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ; - cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER; - val = bytein(cs->hw.elsa.cfg); - if (cs->subtyp == ELSA_PC) { - const u8 CARD_IrqTab[8] = - {7, 3, 5, 9, 0, 0, 0, 0}; - cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PC) >> 2]; - } else if (cs->subtyp == ELSA_PCC8) { - const u8 CARD_IrqTab[8] = - {7, 3, 5, 9, 0, 0, 0, 0}; - cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PCC8) >> 4]; - } else { - const u8 CARD_IrqTab[8] = - {15, 10, 15, 3, 11, 5, 11, 9}; - cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX) >> 3]; - } - val = bytein(cs->hw.elsa.ale) & ELSA_HW_RELEASE; - if (val < 3) - val |= 8; - val += 'A' - 3; - if (val == 'B' || val == 'C') - val ^= 1; - if ((cs->subtyp == ELSA_PCFPRO) && (val = 'G')) - val = 'C'; - printk(KERN_INFO - "Elsa: %s found at %#lx Rev.:%c IRQ %d\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base, - val, cs->irq); - val = bytein(cs->hw.elsa.ale) & ELSA_S0_POWER_BAD; - if (val) { - printk(KERN_WARNING - "Elsa: Microlink S0 bus power bad\n"); - cs->hw.elsa.status |= ELSA_BAD_PWR; - } - } else { - printk(KERN_WARNING - "No Elsa Microlink found\n"); - return (0); - } - } else if (cs->typ == ISDN_CTYPE_ELSA_PNP) { + + if (card->typ == ISDN_CTYPE_ELSA) { + if (elsa_probe(card->cs, card)) + return 0; + return 1; + } else if (card->typ == ISDN_CTYPE_ELSA_PNP) { #ifdef __ISAPNP__ if (!card->para[1] && isapnp_present()) { struct pnp_card *pb; struct pnp_dev *pd; - + while(pdev->card_vendor) { if ((pb = pnp_find_card(pdev->card_vendor, pdev->card_device, @@ -878,10 +1064,15 @@ setup_elsa(struct IsdnCard *card) } card->para[1] = pnp_port_start(pd, 0); card->para[0] = pnp_irq(pd, 0); - if (pdev->function == ISAPNP_FUNCTION(0x133)) - cs->subtyp = ELSA_QS1000; - else - cs->subtyp = ELSA_QS3000; + if (pdev->function == ISAPNP_FUNCTION(0x133)) { + if (elsa_qs1000_probe(card->cs, card)) + return 0; + return 1; + } else { + if (elsa_qs3000_probe(card->cs, card)) + return 0; + return 1; + } break; } else { printk(KERN_ERR "Elsa PnP: PnP error card found, no device\n"); @@ -897,184 +1088,33 @@ setup_elsa(struct IsdnCard *card) } } #endif - if (card->para[1] && card->para[0]) { - cs->hw.elsa.base = card->para[1]; - cs->irq = card->para[0]; - if (!cs->subtyp) - cs->subtyp = ELSA_QS1000; - } else { - printk(KERN_ERR "Elsa PnP: no parameter\n"); - } - cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG; - cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE; - cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC; - cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; - cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ; - cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER; - cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL; - printk(KERN_INFO - "Elsa: %s defined at %#lx IRQ %d\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base, - cs->irq); - } else if (cs->typ == ISDN_CTYPE_ELSA_PCMCIA) { - cs->hw.elsa.base = card->para[1]; - cs->irq = card->para[0]; - cs->hw.elsa.ale = cs->hw.elsa.base + 0; - val = readreg(cs, cs->hw.elsa.base + 2, IPAC_ID); - if ((val == 1) || (val == 2)) { /* IPAC version 1.1/1.2 */ - cs->subtyp = ELSA_PCMCIA_IPAC; - cs->hw.elsa.isac = cs->hw.elsa.base + 2; - cs->hw.elsa.hscx = cs->hw.elsa.base + 2; - } else { - cs->subtyp = ELSA_PCMCIA; - cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE_PCM; - cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC_PCM; - cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX; - } - cs->hw.elsa.timer = 0; - cs->hw.elsa.trig = 0; - cs->hw.elsa.ctrl = 0; - printk(KERN_INFO - "Elsa: %s defined at %#lx IRQ %d\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base, - cs->irq); - } else if (cs->typ == ISDN_CTYPE_ELSA_PCI) { + if (elsa_qs1000_probe(card->cs, card)) + return 0; + return 1; + + } else if (card->typ == ISDN_CTYPE_ELSA_PCMCIA) { + if (elsa_pcmcia_probe(card->cs, card)) + return 0; + return 1; + } else if (card->typ == ISDN_CTYPE_ELSA_PCI) { #if CONFIG_PCI - cs->subtyp = 0; if ((dev_qs1000 = pci_find_device(PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) { - if (pci_enable_device(dev_qs1000)) - return(0); - cs->subtyp = ELSA_QS1000PCI; - cs->irq = dev_qs1000->irq; - cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1); - cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3); - pci_read_config_byte(dev_qs1000, PCI_REVISION_ID, &pci_rev); + if (elsa_qs_pci_probe(card->cs, dev_qs1000, + ELSA_QS1000PCI)) + return 0; + return 1; } else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) { - if (pci_enable_device(dev_qs3000)) - return(0); - cs->subtyp = ELSA_QS3000PCI; - cs->irq = dev_qs3000->irq; - cs->hw.elsa.cfg = pci_resource_start(dev_qs3000, 1); - cs->hw.elsa.base = pci_resource_start(dev_qs3000, 3); - pci_read_config_byte(dev_qs1000, PCI_REVISION_ID, &pci_rev); + if (elsa_qs_pci_probe(card->cs, dev_qs3000, + ELSA_QS3000PCI)) + return 0; + return 1; } else { printk(KERN_WARNING "Elsa: No PCI card found\n"); - return(0); - } - if (!cs->irq) { - printk(KERN_WARNING "Elsa: No IRQ for PCI card found\n"); - return(0); + return 0; } - - if (!(cs->hw.elsa.base && cs->hw.elsa.cfg)) { - printk(KERN_WARNING "Elsa: No IO-Adr for PCI card found\n"); - return(0); - } - if (cs->hw.elsa.cfg & 0x80 && pci_rev == 1) { - printk(KERN_INFO "Elsa: PLX9050 rev1 workaround activated\n"); - set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags); - } - cs->hw.elsa.ale = cs->hw.elsa.base; - cs->hw.elsa.isac = cs->hw.elsa.base +1; - cs->hw.elsa.hscx = cs->hw.elsa.base +1; - cs->hw.elsa.timer = 0; - cs->hw.elsa.trig = 0; - cs->irq_flags |= SA_SHIRQ; - printk(KERN_INFO - "Elsa: %s defined at %#lx/0x%x IRQ %d\n", - Elsa_Types[cs->subtyp], - cs->hw.elsa.base, - cs->hw.elsa.cfg, - cs->irq); #endif /* CONFIG_PCI */ - } else - return (0); - - switch (cs->subtyp) { - case ELSA_PC: - case ELSA_PCC8: - case ELSA_PCC16: - case ELSA_QS1000: - case ELSA_PCMCIA: - case ELSA_PCMCIA_IPAC: - bytecnt = 8; - break; - case ELSA_PCFPRO: - case ELSA_PCF: - case ELSA_QS3000: - case ELSA_QS3000PCI: - bytecnt = 16; - break; - case ELSA_QS1000PCI: - bytecnt = 2; - break; - default: - printk(KERN_WARNING - "Unknown ELSA subtype %d\n", cs->subtyp); - return (0); - } - /* In case of the elsa pcmcia card, this region is in use, - reserved for us by the card manager. So we do not check it - here, it would fail. */ - if (cs->typ != ISDN_CTYPE_ELSA_PCMCIA) - if (!request_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn")) - goto err; - - if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI)) - if (!request_io(&cs->rs, cs->hw.elsa.cfg, 0x80, "elsa isdn pci")) - goto err; - -#if ARCOFI_USE - init_arcofi(cs); -#endif - - cs->hw.elsa.tl.function = (void *) elsa_led_handler; - cs->hw.elsa.tl.data = (long) cs; - init_timer(&cs->hw.elsa.tl); - /* Teste Timer */ - if (cs->hw.elsa.timer) { - byteout(cs->hw.elsa.trig, 0xff); - byteout(cs->hw.elsa.timer, 0); - if (!TimerRun(cs)) { - byteout(cs->hw.elsa.timer, 0); /* 2. Versuch */ - if (!TimerRun(cs)) { - printk(KERN_WARNING - "Elsa: timer do not start\n"); - goto err; - } - } - HZDELAY(1); /* wait >=10 ms */ - if (TimerRun(cs)) { - printk(KERN_WARNING "Elsa: timer do not run down\n"); - goto err; - } - printk(KERN_INFO "Elsa: timer OK; resetting card\n"); } - elsa_reset(cs); - if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI) || (cs->subtyp == ELSA_PCMCIA_IPAC)) { - cs->card_ops = &elsa_ipac_ops; - if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) - goto err; - } else { - cs->card_ops = &elsa_ops; - if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - goto err; - } - if (cs->subtyp == ELSA_PC) { - val = readitac(cs, ITAC_SYS); - printk(KERN_INFO "Elsa: ITAC version %s\n", ITACVer[val & 7]); - writeitac(cs, ITAC_ISEN, 0); - writeitac(cs, ITAC_RFIE, 0); - writeitac(cs, ITAC_XFIE, 0); - writeitac(cs, ITAC_SCIE, 0); - writeitac(cs, ITAC_STIE, 0); - } - return 1; - err: - elsa_release(cs); return 0; } diff --git a/drivers/isdn/hisax/enternow_pci.c b/drivers/isdn/hisax/enternow_pci.c index 7585bb59f1bae..4c5b9db757b25 100644 --- a/drivers/isdn/hisax/enternow_pci.c +++ b/drivers/isdn/hisax/enternow_pci.c @@ -263,13 +263,65 @@ static struct card_ops enpci_ops = { .irq_func = enpci_interrupt, }; +static int __init +enpci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.njet.base = pci_resource_start(pdev, 0); + if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "Fn_ISDN")) + goto err; + + cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; + cs->hw.njet.isac = cs->hw.njet.base + 0xC0; // Fenster zum AMD + + /* Reset an */ + cs->hw.njet.ctrl_reg = 0x07; // geändert von 0xff + OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); + + set_current_state(TASK_UNINTERRUPTIBLE); + /* 50 ms Pause */ + schedule_timeout((50*HZ)/1000); + + cs->hw.njet.ctrl_reg = 0x30; /* Reset Off and status read clear */ + OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ + + cs->hw.njet.auxd = 0x00; // war 0xc0 + cs->hw.njet.dmactrl = 0; + + OutByte(cs->hw.njet.base + NETJET_AUXCTRL, ~TJ_AMD_IRQ); + OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ); + OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd); + + printk(KERN_INFO + "enter:now PCI: PCI card configured at 0x%lx IRQ %d\n", + cs->hw.njet.base, cs->irq); + reset_enpci(cs); + cs->hw.njet.last_is0 = 0; + cs->hw.njet.bc_activate = enpci_bc_activate; + cs->hw.njet.bc_deactivate = enpci_bc_deactivate; + amd7930_setup(cs, &amd7930_ops, &enpci_setIrqMask); + + cs->card_ops = &enpci_ops; + + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + static struct pci_dev *dev_netjet __initdata = NULL; /* called by config.c */ int __init setup_enternow_pci(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; #ifdef __BIG_ENDIAN @@ -278,72 +330,22 @@ setup_enternow_pci(struct IsdnCard *card) strcpy(tmp, enternow_pci_rev); printk(KERN_INFO "HiSax: Formula-n Europe AG enter:now ISDN PCI driver Rev. %s\n", HiSax_getrev(tmp)); - for ( ;; ) { - if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, - PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { - if (pci_enable_device(dev_netjet)) - return(0); - cs->irq = dev_netjet->irq; - if (!cs->irq) { - printk(KERN_WARNING "enter:now PCI: No IRQ for PCI card found\n"); - return(0); - } - cs->hw.njet.base = pci_resource_start(dev_netjet, 0); - if (!cs->hw.njet.base) { - printk(KERN_WARNING "enter:now PCI: No IO-Adr for PCI card found\n"); - return(0); - } - /* checks Sub-Vendor ID because system crashes with Traverse-Card */ - if ((dev_netjet->subsystem_vendor != 0x55) || - (dev_netjet->subsystem_device != 0x02)) { - printk(KERN_WARNING "enter:now: You tried to load this driver with an incompatible TigerJet-card\n"); - printk(KERN_WARNING "Use type=20 for Traverse NetJet PCI Card.\n"); - return(0); - } - } else { - printk(KERN_WARNING "enter:now PCI: No PCI card found\n"); - return(0); + dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, + PCI_DEVICE_ID_TIGERJET_300, dev_netjet); + if (dev_netjet) { + if (dev_netjet->subsystem_vendor != 0x55 || + dev_netjet->subsystem_device != 0x02) { + printk(KERN_WARNING "enter:now: You tried to load " + "this driver with an incompatible " + "TigerJet-card\n"); + printk(KERN_WARNING "Use type=20 for Traverse " + "NetJet PCI Card.\n"); + return 0; } - - cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; - cs->hw.njet.isac = cs->hw.njet.base + 0xC0; // Fenster zum AMD - - /* Reset an */ - cs->hw.njet.ctrl_reg = 0x07; // geändert von 0xff - OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - - set_current_state(TASK_UNINTERRUPTIBLE); - /* 50 ms Pause */ - schedule_timeout((50*HZ)/1000); - - cs->hw.njet.ctrl_reg = 0x30; /* Reset Off and status read clear */ - OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ - - cs->hw.njet.auxd = 0x00; // war 0xc0 - cs->hw.njet.dmactrl = 0; - - OutByte(cs->hw.njet.base + NETJET_AUXCTRL, ~TJ_AMD_IRQ); - OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ); - OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd); - - break; - } - printk(KERN_INFO - "enter:now PCI: PCI card configured at 0x%lx IRQ %d\n", - cs->hw.njet.base, cs->irq); - if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "Fn_ISDN")) + if (enpci_probe(card->cs, dev_netjet)) + return 1; return 0; - reset_enpci(cs); - cs->hw.njet.last_is0 = 0; - cs->hw.njet.bc_activate = enpci_bc_activate; - cs->hw.njet.bc_deactivate = enpci_bc_deactivate; - amd7930_setup(cs, &amd7930_ops, &enpci_setIrqMask); - - cs->irq_flags |= SA_SHIRQ; - cs->card_ops = &enpci_ops; - - return 1; + } + printk(KERN_WARNING "enter:now PCI: No PCI card found\n"); + return 0; } diff --git a/drivers/isdn/hisax/gazel.c b/drivers/isdn/hisax/gazel.c index d07e0c5fbc5bc..af60f33276378 100644 --- a/drivers/isdn/hisax/gazel.c +++ b/drivers/isdn/hisax/gazel.c @@ -294,60 +294,6 @@ gazel_init(struct IsdnCardState *cs) inithscxisac(cs); } -static int -r647_reserve_regions(struct IsdnCardState *cs) -{ - int i, base = cs->hw.gazel.hscx[0]; - - for (i = 0; i < 0xc000; i += 0x1000) { - if (!request_io(&cs->rs, i + base, 16, "gazel")) - goto err; - } - if (!request_io(&cs->rs, 0xc000 + base, 1, "gazel")) - goto err; - return 0; - err: - hisax_release_resources(cs); - return -EBUSY; -} - -static int -r685_reserve_regions(struct IsdnCardState *cs) -{ - if (!request_io(&cs->rs, cs->hw.gazel.hscx[0], 0x100, "gazel")) - goto err; - if (!request_io(&cs->rs, cs->hw.gazel.cfg_reg, 0x80, "gazel")) - goto err; - return 0; - err: - hisax_release_resources(cs); - return -EBUSY; -} - -static int -r742_reserve_regions(struct IsdnCardState *cs) -{ - if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel")) - goto err; - return 0; - err: - hisax_release_resources(cs); - return -EBUSY; -} - -static int -r753_reserve_regions(struct IsdnCardState *cs) -{ - if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel")) - goto err; - if (!request_io(&cs->rs, cs->hw.gazel.cfg_reg, 0x80, "gazel")) - goto err; - return 0; - err: - hisax_release_resources(cs); - return -EBUSY; -} - static struct card_ops r647_ops = { .init = gazel_init, .reset = r647_reset, @@ -377,194 +323,213 @@ static struct card_ops r753_ops = { }; static int __init -setup_gazelisa(struct IsdnCard *card, struct IsdnCardState *cs) +gazel647_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - printk(KERN_INFO "Gazel: ISA PnP card automatic recognition\n"); - // we got an irq parameter, assume it is an ISA card - // R742 decodes address even in not started... - // R647 returns FF if not present or not started - // eventually needs improvment - cs->hw.gazel.ipac = card->para[1]; - if (ipac_read(cs, IPAC_ID) == 1) - cs->subtyp = R742; - else - cs->subtyp = R647; + int i, base; + cs->subtyp = R647; + cs->irq = card->para[0]; cs->hw.gazel.cfg_reg = card->para[1] + 0xC000; + + printk(KERN_INFO "Gazel: Card ISA R647/R648 found\n"); + cs->dc.isac.adf2 = 0x87; + printk(KERN_INFO "Gazel: config irq:%d isac:0x%X cfg:0x%X\n", + cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg); + printk(KERN_INFO + "Gazel: hscx A:0x%X hscx B:0x%X\n", + cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]); + cs->hw.gazel.isac = card->para[1] + 0x8000; cs->hw.gazel.hscx[0] = card->para[1]; cs->hw.gazel.hscx[1] = card->para[1] + 0x4000; - cs->irq = card->para[0]; cs->hw.gazel.isacfifo = cs->hw.gazel.isac; cs->hw.gazel.hscxfifo[0] = cs->hw.gazel.hscx[0]; cs->hw.gazel.hscxfifo[1] = cs->hw.gazel.hscx[1]; - switch (cs->subtyp) { - case R647: - printk(KERN_INFO "Gazel: Card ISA R647/R648 found\n"); - cs->dc.isac.adf2 = 0x87; - printk(KERN_INFO - "Gazel: config irq:%d isac:0x%X cfg:0x%X\n", - cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg); - printk(KERN_INFO - "Gazel: hscx A:0x%X hscx B:0x%X\n", - cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]); - - return r647_reserve_regions(cs); - case R742: - printk(KERN_INFO "Gazel: Card ISA R742 found\n"); - printk(KERN_INFO - "Gazel: config irq:%d ipac:0x%X\n", - cs->irq, cs->hw.gazel.ipac); - return r742_reserve_regions(cs); + base = cs->hw.gazel.hscx[0]; + for (i = 0; i < 0xc000; i += 0x1000) { + if (!request_io(&cs->rs, base + i, 16, "gazel")) + goto err; } + if (!request_io(&cs->rs, 0xc000 + base, 1, "gazel")) + goto err; + + cs->card_ops = &r647_ops; + if (hscxisac_setup(cs, &r647_isac_ops, &r647_hscx_ops)) + goto err; + + cs->card_ops->reset(cs); return 0; + err: + hisax_release_resources(cs); + return -EBUSY; } -static struct pci_dev *dev_tel __initdata = NULL; - static int __init -setup_gazelpci(struct IsdnCardState *cs) +gazel742_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - u_int pci_ioaddr0 = 0, pci_ioaddr1 = 0; - u8 pci_irq = 0, found; - u_int nbseek, seekcard; - u8 pci_rev; + cs->subtyp = R742; + cs->irq = card->para[0]; + cs->hw.gazel.cfg_reg = card->para[1] + 0xC000; - printk(KERN_WARNING "Gazel: PCI card automatic recognition\n"); + printk(KERN_INFO "Gazel: Card ISA R742 found\n"); + printk(KERN_INFO "Gazel: config irq:%d ipac:0x%X\n", + cs->irq, cs->hw.gazel.ipac); - found = 0; - if (!pci_present()) { - printk(KERN_WARNING "Gazel: No PCI bus present\n"); - return 1; - } - seekcard = PCI_DEVICE_ID_PLX_R685; - for (nbseek = 0; nbseek < 3; nbseek++) { - if ((dev_tel = pci_find_device(PCI_VENDOR_ID_PLX, seekcard, dev_tel))) { - if (pci_enable_device(dev_tel)) - return 1; - pci_irq = dev_tel->irq; - pci_ioaddr0 = pci_resource_start(dev_tel, 1); - pci_ioaddr1 = pci_resource_start(dev_tel, 2); - found = 1; - } - if (found) - break; - else { - switch (seekcard) { - case PCI_DEVICE_ID_PLX_R685: - seekcard = PCI_DEVICE_ID_PLX_R753; - break; - case PCI_DEVICE_ID_PLX_R753: - seekcard = PCI_DEVICE_ID_PLX_DJINN_ITOO; - break; - } - } - } - if (!found) { - printk(KERN_WARNING "Gazel: No PCI card found\n"); - return -ENODEV; - } - if (!pci_irq) { - printk(KERN_WARNING "Gazel: No IRQ for PCI card found\n"); - return -ENODEV; - } - cs->hw.gazel.pciaddr[0] = pci_ioaddr0; - cs->hw.gazel.pciaddr[1] = pci_ioaddr1; - - pci_ioaddr1 &= 0xfffe; - cs->hw.gazel.cfg_reg = pci_ioaddr0 & 0xfffe; - cs->hw.gazel.ipac = pci_ioaddr1; - cs->hw.gazel.isac = pci_ioaddr1 + 0x80; - cs->hw.gazel.hscx[0] = pci_ioaddr1; - cs->hw.gazel.hscx[1] = pci_ioaddr1 + 0x40; - cs->hw.gazel.isacfifo = cs->hw.gazel.isac; + if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel")) + goto err; + + cs->card_ops = &r742_ops; + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; + + cs->card_ops->reset(cs); + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +gazel685_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = R685; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.gazel.cfg_reg = pci_resource_start(pdev, 1); + cs->hw.gazel.isac = pci_resource_start(pdev, 2) + 0x80; + cs->hw.gazel.hscx[0] = pci_resource_start(pdev, 2); + cs->hw.gazel.hscx[1] = pci_resource_start(pdev, 2) + 0x40; + cs->hw.gazel.isacfifo = cs->hw.gazel.isac; cs->hw.gazel.hscxfifo[0] = cs->hw.gazel.hscx[0]; cs->hw.gazel.hscxfifo[1] = cs->hw.gazel.hscx[1]; - cs->irq = pci_irq; - cs->irq_flags |= SA_SHIRQ; - - switch (seekcard) { - case PCI_DEVICE_ID_PLX_R685: - printk(KERN_INFO "Gazel: Card PCI R685 found\n"); - cs->subtyp = R685; - cs->dc.isac.adf2 = 0x87; - printk(KERN_INFO - "Gazel: config irq:%d isac:0x%X cfg:0x%X\n", - cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg); - printk(KERN_INFO - "Gazel: hscx A:0x%X hscx B:0x%X\n", - cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]); - return r685_reserve_regions(cs); - case PCI_DEVICE_ID_PLX_R753: - case PCI_DEVICE_ID_PLX_DJINN_ITOO: - printk(KERN_INFO "Gazel: Card PCI R753 found\n"); - cs->subtyp = R753; - printk(KERN_INFO - "Gazel: config irq:%d ipac:0x%X cfg:0x%X\n", - cs->irq, cs->hw.gazel.ipac, cs->hw.gazel.cfg_reg); - /* - * Erratum for PLX9050, revision 1: - * If bit 7 of BAR 0/1 is set, local config registers - * can not be read (write is okay) - */ - if (cs->hw.gazel.cfg_reg & 0x80) { - pci_read_config_byte(dev_tel, PCI_REVISION_ID, &pci_rev); - if (pci_rev == 1) { - printk(KERN_INFO "Gazel: PLX9050 rev1 workaround activated\n"); - set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags); - } + cs->dc.isac.adf2 = 0x87; + + if (!request_io(&cs->rs, cs->hw.gazel.hscx[0], 0x100, "gazel")) + goto err; + if (!request_io(&cs->rs, cs->hw.gazel.cfg_reg, 0x80, "gazel")) + goto err; + + printk(KERN_INFO "Gazel: Card PCI R685 found\n"); + printk(KERN_INFO "Gazel: config irq:%d isac:0x%X cfg:0x%X\n", + cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg); + printk(KERN_INFO "Gazel: hscx A:0x%X hscx B:0x%X\n", + cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]); + + cs->card_ops = &r685_ops; + if (hscxisac_setup(cs, &r685_isac_ops, &r685_hscx_ops)) + goto err; + + cs->card_ops->reset(cs); + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +gazel753_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + u8 pci_rev; + + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = R753; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.gazel.cfg_reg = pci_resource_start(pdev, 1); + cs->hw.gazel.ipac = pci_resource_start(pdev, 2); + + if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel")) + goto err; + if (!request_io(&cs->rs, cs->hw.gazel.cfg_reg, 0x80, "gazel")) + goto err; + + printk(KERN_INFO "Gazel: Card PCI R753 found\n"); + printk(KERN_INFO "Gazel: config irq:%d ipac:0x%X cfg:0x%X\n", + cs->irq, cs->hw.gazel.ipac, cs->hw.gazel.cfg_reg); + /* + * Erratum for PLX9050, revision 1: + * If bit 7 of BAR 0/1 is set, local config registers + * can not be read (write is okay) + */ + if (cs->hw.gazel.cfg_reg & 0x80) { + pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev); + if (pci_rev == 1) { + printk(KERN_INFO "Gazel: PLX9050 rev1 workaround " + "activated\n"); + __set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags); } - return r753_reserve_regions(cs); } + cs->card_ops = &r753_ops; + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + goto err; + + cs->card_ops->reset(cs); return 0; + err: + hisax_release_resources(cs); + return -EBUSY; } +static struct pci_dev *dev_tel __initdata = NULL; +static u16 __initdata dev_id = PCI_DEVICE_ID_PLX_R685; + int __init setup_gazel(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, gazel_revision); printk(KERN_INFO "Gazel: Driver Revision %s\n", HiSax_getrev(tmp)); if (card->para[0]) { - if (setup_gazelisa(card, cs)) - return (0); - } else { - if (setup_gazelpci(cs)) - return (0); + printk(KERN_INFO "Gazel: ISA card automatic recognition\n"); + // we got an irq parameter, assume it is an ISA card + // R742 decodes address even in not started... + // R647 returns FF if not present or not started + // eventually needs improvment + card->cs->hw.gazel.ipac = card->para[1]; + if (ipac_read(card->cs, IPAC_ID) == 1) { + if (gazel742_probe(card->cs, card)) + return 0; + } else { + if (gazel647_probe(card->cs, card)) + return 0; + } + return 1; } - switch (cs->subtyp) { - case R647: - case R685: - if (cs->subtyp == R647) { - cs->card_ops = &r647_ops; - if (hscxisac_setup(cs, &r647_isac_ops, &r647_hscx_ops)) - goto err; - } else { - cs->card_ops = &r685_ops; - if (hscxisac_setup(cs, &r685_isac_ops, &r685_hscx_ops)) - goto err; + for (;;) { + dev_tel = pci_find_device(PCI_VENDOR_ID_PLX, dev_id, dev_tel); + if (dev_tel) { + switch (dev_id) { + case PCI_DEVICE_ID_PLX_R685: + if (gazel685_probe(card->cs, dev_tel)) + return 0; + return 1; + case PCI_DEVICE_ID_PLX_R753: + case PCI_DEVICE_ID_PLX_DJINN_ITOO: + if (gazel753_probe(card->cs, dev_tel)) + return 0; + return 1; + } } - cs->card_ops->reset(cs); - break; - case R742: - case R753: - if (cs->subtyp == R742) { - cs->card_ops = &r742_ops; - } else { - cs->card_ops = &r753_ops; + switch (dev_id) { + case PCI_DEVICE_ID_PLX_R685: + dev_id = PCI_DEVICE_ID_PLX_R753; + case PCI_DEVICE_ID_PLX_R753: + dev_id = PCI_DEVICE_ID_PLX_DJINN_ITOO; + default: + break; } - if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) - goto err; - cs->card_ops->reset(cs); - break; } - return 1; - err: - hisax_release_resources(cs); + printk(KERN_WARNING "Gazel: No PCI card found\n"); return 0; } + + diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index e674abdbbff66..89fc57c07d4b3 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c @@ -1382,72 +1382,41 @@ static struct card_ops hfcpci_ops = { }; -/* this variable is used as card index when more than one cards are present */ -static struct pci_dev *dev_hfcpci __initdata = NULL; - -int __init -setup_hfcpci(struct IsdnCard *card) +static int __init +niccy_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev, int i) { - struct IsdnCardState *cs = card->cs; - char tmp[64]; - int i; - struct pci_dev *tmp_hfcpci = NULL; + int rc; - strcpy(tmp, hfcpci_revision); - printk(KERN_INFO "HiSax: HFC-PCI driver Rev. %s\n", HiSax_getrev(tmp)); - cs->hw.hfcpci.int_s1 = 0; - cs->dc.hfcpci.ph_state = 0; - cs->hw.hfcpci.fifo = 255; + rc = -EBUSY; + if (pci_enable_device(pdev)) + goto err; - i = 0; - while (id_list[i].vendor_id) { - tmp_hfcpci = pci_find_device(id_list[i].vendor_id, - id_list[i].device_id, - dev_hfcpci); - i++; - if (tmp_hfcpci) { - if (pci_enable_device(tmp_hfcpci)) - continue; - pci_set_master(tmp_hfcpci); - if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK))) - continue; - else - break; - } - } + pci_set_master(pdev); + + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.hfcpci.pdev = pdev; + + cs->hw.hfcpci.pci_io = request_mmio(&cs->rs, + pci_resource_start(pdev, 1), 128, + "hfc_pci"); + if (!cs->hw.hfcpci.pci_io) + goto err; - if (tmp_hfcpci) { - i--; - dev_hfcpci = tmp_hfcpci; /* old device */ - cs->irq = dev_hfcpci->irq; - cs->hw.hfcpci.pdev = tmp_hfcpci; - if (!cs->irq) { - printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); - return (0); - } - printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n", id_list[i].vendor_name, id_list[i].card_name); - } else { - printk(KERN_WARNING "HFC-PCI: No PCI card found\n"); - return (0); - } /* Allocate memory for FIFOS */ - cs->hw.hfcpci.fifos = pci_alloc_consistent(tmp_hfcpci, 32768, &cs->hw.hfcpci.fifos_dma); - if (!cs->hw.hfcpci.fifos) { - printk(KERN_WARNING "HFC-PCI: Error allocating memory for FIFO!\n"); - return 0; - } + rc = -ENOMEM; + cs->hw.hfcpci.fifos = pci_alloc_consistent(pdev, 32768, + &cs->hw.hfcpci.fifos_dma); + if (!cs->hw.hfcpci.fifos) + goto err; + pci_write_config_dword(cs->hw.hfcpci.pdev, 0x80, (u_int)cs->hw.hfcpci.fifos_dma); - cs->hw.hfcpci.pci_io = request_mmio(&cs->rs, dev_hfcpci->resource[ 1].start, 256, "hfc_pci"); - if (!cs->hw.hfcpci.pci_io) - goto err; - - printk(KERN_INFO - "HFC-PCI: defined at mem %#x fifo %#x(%#x) IRQ %d HZ %d\n", - (u_int) cs->hw.hfcpci.pci_io, - (u_int) cs->hw.hfcpci.fifos, - (u_int) cs->hw.hfcpci.fifos_dma, - cs->irq, HZ); + printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s name: %s\n", + id_list[i].vendor_name, id_list[i].card_name); + printk(KERN_INFO "HFC-PCI: defined at mem %#x fifo %#x(%#x) IRQ %d\n", + (u_int) cs->hw.hfcpci.pci_io, (u_int) cs->hw.hfcpci.fifos, + (u_int) cs->hw.hfcpci.fifos_dma, cs->irq); printk("ChipID: %x\n", Read_hfc(cs, HFCPCI_CHIP_ID)); cs->hw.hfcpci.int_m2 = 0; /* disable alle interrupts */ cs->hw.hfcpci.int_m1 = 0; @@ -1456,17 +1425,46 @@ setup_hfcpci(struct IsdnCard *card) /* At this point the needed PCI config is done */ /* fifos are still not enabled */ - cs->irq_flags |= SA_SHIRQ; - + init_timer(&cs->hw.hfcpci.timer); cs->hw.hfcpci.timer.function = (void *) hfcpci_Timer; cs->hw.hfcpci.timer.data = (long) cs; - init_timer(&cs->hw.hfcpci.timer); hfcpci_reset(cs); cs->auxcmd = &hfcpci_auxcmd; cs->card_ops = &hfcpci_ops; - return 1; + return 0; err: hisax_release_resources(cs); + return -EBUSY; +} + +/* this variable is used as card index when more than one cards are present */ +static struct pci_dev *dev_hfcpci __initdata = NULL; + +int __init +setup_hfcpci(struct IsdnCard *card) +{ + struct IsdnCardState *cs = card->cs; + char tmp[64]; + int i; + struct pci_dev *tmp_hfcpci = NULL; + + strcpy(tmp, hfcpci_revision); + printk(KERN_INFO "HiSax: HFC-PCI driver Rev. %s\n", HiSax_getrev(tmp)); + cs->hw.hfcpci.int_s1 = 0; + cs->dc.hfcpci.ph_state = 0; + cs->hw.hfcpci.fifo = 255; + + for (i = 0; id_list[i].vendor_id; i++) { + tmp_hfcpci = pci_find_device(id_list[i].vendor_id, + id_list[i].device_id, + dev_hfcpci); + if (!tmp_hfcpci) + continue; + + if (niccy_pci_probe(card->cs, tmp_hfcpci, i) < 0) + return 0; + return 1; + } return 0; } diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index 43679deac9696..d75198ad8ad61 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c @@ -1159,6 +1159,74 @@ static struct card_ops hfcsx_ops = { .irq_func = hfcsx_interrupt, }; +static int __init +hfcsx_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + int rc; + char c; + + cs->irq = card->para[0]; + cs->hw.hfcsx.base = card->para[1] & 0xfffe; + + cs->hw.hfcsx.fifo = 255; + cs->hw.hfcsx.int_s1 = 0; + cs->dc.hfcsx.ph_state = 0; + + rc = -EBUSY; + if (!request_io(&cs->rs, cs->hw.hfcsx.base, 2, "HFCSX isdn")) + goto err; + + rc = -ENODEV; + byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.base & 0xFF); + byteout(cs->hw.hfcsx.base + 1, ((cs->hw.hfcsx.base >> 8) & 3) | 0x54); + udelay(10); + cs->hw.hfcsx.chip = Read_hfc(cs,HFCSX_CHIP_ID); + switch (cs->hw.hfcsx.chip >> 4) { + case 1: + c ='+'; + break; + case 9: + c ='P'; + break; + default: + printk(KERN_WARNING "HFC-SX: invalid chip id 0x%x\n", + cs->hw.hfcsx.chip >> 4); + goto err; + } + if (!ccd_sp_irqtab[cs->irq & 0xF]) { + printk(KERN_WARNING "HFC_SX: invalid irq %d specified\n", + cs->irq & 0xF); + goto err; + } + rc = -ENOMEM; + cs->hw.hfcsx.extra = kmalloc(sizeof(struct hfcsx_extra), GFP_ATOMIC); + if (!cs->hw.hfcsx.extra) { + printk(KERN_WARNING "HFC-SX: unable to allocate memory\n"); + goto err; + } + printk(KERN_INFO "HFC-S%c chip detected at base 0x%x IRQ %d\n", + c, (u_int) cs->hw.hfcsx.base, cs->irq); + + cs->hw.hfcsx.int_m2 = 0; /* disable alle interrupts */ + cs->hw.hfcsx.int_m1 = 0; + Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1); + Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2); + + init_timer(&cs->hw.hfcsx.timer); + cs->hw.hfcsx.timer.function = (void *) hfcsx_Timer; + cs->hw.hfcsx.timer.data = (long) cs; + cs->hw.hfcsx.b_fifo_size = 0; /* fifo size still unknown */ + cs->hw.hfcsx.cirm = ccd_sp_irqtab[cs->irq & 0xF]; /* RAM not eval. */ + + hfcsx_reset(cs); + cs->auxcmd = &hfcsx_auxcmd; + cs->card_ops = &hfcsx_ops; + return 0; + err: + hisax_release_resources(cs); + return rc; +} + #ifdef __ISAPNP__ static struct isapnp_device_id hfc_ids[] __initdata = { { ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620), @@ -1174,7 +1242,6 @@ static struct pnp_card *pnp_c __devinitdata = NULL; int __devinit setup_hfcsx(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, hfcsx_revision); @@ -1227,62 +1294,7 @@ setup_hfcsx(struct IsdnCard *card) } } #endif - cs->hw.hfcsx.base = card->para[1] & 0xfffe; - cs->irq = card->para[0]; - cs->hw.hfcsx.int_s1 = 0; - cs->dc.hfcsx.ph_state = 0; - cs->hw.hfcsx.fifo = 255; - - if (!request_io(&cs->rs, cs->hw.hfcsx.base, 2, "HFCSX isdn")) + if (hfcsx_probe(card->cs, card) < 0) return 0; - byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.base & 0xFF); - byteout(cs->hw.hfcsx.base + 1, - ((cs->hw.hfcsx.base >> 8) & 3) | 0x54); - udelay(10); - cs->hw.hfcsx.chip = Read_hfc(cs,HFCSX_CHIP_ID); - switch (cs->hw.hfcsx.chip >> 4) { - case 1: - tmp[0] ='+'; - break; - case 9: - tmp[0] ='P'; - break; - default: - printk(KERN_WARNING "HFC-SX: invalid chip id 0x%x\n", - cs->hw.hfcsx.chip >> 4); - hisax_release_resources(cs); - return 0; - } - if (!ccd_sp_irqtab[cs->irq & 0xF]) { - printk(KERN_WARNING "HFC_SX: invalid irq %d specified\n", - cs->irq & 0xF); - hisax_release_resources(cs); - return 0; - } - cs->hw.hfcsx.extra = kmalloc(sizeof(struct hfcsx_extra), - GFP_ATOMIC); - if (!cs->hw.hfcsx.extra) { - hisax_release_resources(cs); - printk(KERN_WARNING "HFC-SX: unable to allocate memory\n"); - return 0; - } - - printk(KERN_INFO "HFC-S%c chip detected at base 0x%x IRQ %d HZ %d\n", - tmp[0], (u_int) cs->hw.hfcsx.base, - cs->irq, HZ); - cs->hw.hfcsx.int_m2 = 0; /* disable alle interrupts */ - cs->hw.hfcsx.int_m1 = 0; - Write_hfc(cs, HFCSX_INT_M1, cs->hw.hfcsx.int_m1); - Write_hfc(cs, HFCSX_INT_M2, cs->hw.hfcsx.int_m2); - - cs->hw.hfcsx.timer.function = (void *) hfcsx_Timer; - cs->hw.hfcsx.timer.data = (long) cs; - cs->hw.hfcsx.b_fifo_size = 0; /* fifo size still unknown */ - cs->hw.hfcsx.cirm = ccd_sp_irqtab[cs->irq & 0xF]; /* RAM not evaluated */ - init_timer(&cs->hw.hfcsx.timer); - - hfcsx_reset(cs); - cs->auxcmd = &hfcsx_auxcmd; - cs->card_ops = &hfcsx_ops; return 1; } diff --git a/drivers/isdn/hisax/hfcscard.c b/drivers/isdn/hisax/hfcscard.c index ede8af634c806..904e16a35389e 100644 --- a/drivers/isdn/hisax/hfcscard.c +++ b/drivers/isdn/hisax/hfcscard.c @@ -133,6 +133,50 @@ static struct card_ops hfcs_ops = { .irq_func = hfcs_interrupt, }; +static int __init +hfcs_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->irq = card->para[0]; + cs->hw.hfcD.addr = card->para[1]; + + if (!request_io(&cs->rs, cs->hw.hfcD.addr, 2, "HFCS isdn")) + goto err; + + printk(KERN_INFO "HFCS: defined at 0x%x IRQ %d\n", + cs->hw.hfcD.addr, cs->irq); + + cs->hw.hfcD.cip = 0; + cs->hw.hfcD.int_s1 = 0; + cs->hw.hfcD.send = NULL; + cs->bcs[0].hw.hfc.send = NULL; + cs->bcs[1].hw.hfc.send = NULL; + cs->hw.hfcD.dfifosize = 512; + cs->dc.hfcd.ph_state = 0; + cs->hw.hfcD.fifo = 255; + + if (cs->typ == ISDN_CTYPE_TELES3C) { + cs->hw.hfcD.bfifosize = 1024 + 512; + /* Teles 16.3c IO ADR is 0x200 | YY0U (YY Bit 15/14 address) */ + outb(0x00, cs->hw.hfcD.addr); + outb(0x56, cs->hw.hfcD.addr | 1); + } else if (cs->typ == ISDN_CTYPE_ACERP10) { + cs->hw.hfcD.bfifosize = 7*1024 + 512; + /* Acer P10 IO ADR is 0x300 */ + outb(0x00, cs->hw.hfcD.addr); + outb(0x57, cs->hw.hfcD.addr | 1); + } + set_cs_func(cs); + init_timer(&cs->hw.hfcD.timer); + cs->hw.hfcD.timer.function = (void *) hfcs_Timer; + cs->hw.hfcD.timer.data = (long) cs; + hfcs_reset(cs); + cs->card_ops = &hfcs_ops; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + #ifdef __ISAPNP__ static struct isapnp_device_id hfc_ids[] __initdata = { { ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114), @@ -166,7 +210,6 @@ static struct pnp_card *pnp_c __devinitdata = NULL; int __init setup_hfcs(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, hfcs_revision); @@ -220,42 +263,8 @@ setup_hfcs(struct IsdnCard *card) } } #endif - cs->hw.hfcD.addr = card->para[1] & 0xfffe; - cs->irq = card->para[0]; - cs->hw.hfcD.cip = 0; - cs->hw.hfcD.int_s1 = 0; - cs->hw.hfcD.send = NULL; - cs->bcs[0].hw.hfc.send = NULL; - cs->bcs[1].hw.hfc.send = NULL; - cs->hw.hfcD.dfifosize = 512; - cs->dc.hfcd.ph_state = 0; - cs->hw.hfcD.fifo = 255; - if (cs->typ == ISDN_CTYPE_TELES3C) { - cs->hw.hfcD.bfifosize = 1024 + 512; - } else if (cs->typ == ISDN_CTYPE_ACERP10) { - cs->hw.hfcD.bfifosize = 7*1024 + 512; - } else - return (0); - if (!request_io(&cs->rs, cs->hw.hfcD.addr, 2, "HFCS isdn")) + if (hfcs_probe(card->cs, card) < 0) return 0; - printk(KERN_INFO - "HFCS: defined at 0x%x IRQ %d HZ %d\n", - cs->hw.hfcD.addr, - cs->irq, HZ); - if (cs->typ == ISDN_CTYPE_TELES3C) { - /* Teles 16.3c IO ADR is 0x200 | YY0U (YY Bit 15/14 address) */ - outb(0x00, cs->hw.hfcD.addr); - outb(0x56, cs->hw.hfcD.addr | 1); - } else if (cs->typ == ISDN_CTYPE_ACERP10) { - /* Acer P10 IO ADR is 0x300 */ - outb(0x00, cs->hw.hfcD.addr); - outb(0x57, cs->hw.hfcD.addr | 1); - } - set_cs_func(cs); - cs->hw.hfcD.timer.function = (void *) hfcs_Timer; - cs->hw.hfcD.timer.data = (long) cs; - init_timer(&cs->hw.hfcD.timer); - hfcs_reset(cs); - cs->card_ops = &hfcs_ops; - return (1); + return 1; + } diff --git a/drivers/isdn/hisax/isurf.c b/drivers/isdn/hisax/isurf.c index 6c5dd612a824d..a9baa4443d81d 100644 --- a/drivers/isdn/hisax/isurf.c +++ b/drivers/isdn/hisax/isurf.c @@ -187,95 +187,92 @@ static struct card_ops isurf_ops = { static struct pnp_card *pnp_surf __devinitdata = NULL; #endif -int __init -setup_isurf(struct IsdnCard *card) +static int __init +isurf_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; unsigned long phymem; - char tmp[64]; - strcpy(tmp, ISurf_revision); - printk(KERN_INFO "HiSax: ISurf driver Rev. %s\n", HiSax_getrev(tmp)); - - if (card->para[1] && card->para[2]) { - cs->hw.isurf.reset = card->para[1]; - phymem = card->para[2]; - cs->irq = card->para[0]; - } else { -#ifdef __ISAPNP__ - struct pnp_card *pb; - struct pnp_dev *pd; + phymem = card->para[2]; + cs->hw.isurf.reset = card->para[1]; + cs->irq = card->para[0]; - if (isapnp_present()) { - cs->subtyp = 0; - if ((pb = pnp_find_card( - ISAPNP_VENDOR('S', 'I', 'E'), - ISAPNP_FUNCTION(0x0010), pnp_surf))) { - pnp_surf = pb; - pd = NULL; - if (!(pd = pnp_find_dev(pnp_surf, - ISAPNP_VENDOR('S', 'I', 'E'), - ISAPNP_FUNCTION(0x0010), pd))) { - printk(KERN_ERR "ISurfPnP: PnP error card found, no device\n"); - return (0); - } - if (pnp_device_attach(pd) < 0) { - printk(KERN_ERR "ISurfPnP: attach failed\n"); - return 0; - } - if (pnp_activate_dev(pd) < 0) { - printk(KERN_ERR "ISurfPnP: activate failed\n"); - pnp_device_detach(pd); - return 0; - } - if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0) || !pnp_port_valid(pd, 1)) { - printk(KERN_ERR "ISurfPnP:some resources are missing %ld/%lx/%lx\n", - pnp_irq(pd, 0), pnp_port_start(pd, 0), pnp_port_start(pd, 1)); - pnp_device_detach(pd); - return(0); - } - cs->hw.isurf.reset = pnp_port_start(pd, 0); - phymem = pnp_port_start(pd, 1); - cs->irq = pnp_irq(pd, 0); - } else { - printk(KERN_INFO "ISurfPnP: no ISAPnP card found\n"); - return(0); - } - } else { - printk(KERN_INFO "ISurfPnP: no ISAPnP bus found\n"); - return(0); - } -#else - printk(KERN_WARNING "HiSax: %s port/mem not set\n", - CardType[card->typ]); - return (0); -#endif - } if (!request_io(&cs->rs, cs->hw.isurf.reset, 1, "isurf isdn")) goto err; - cs->hw.isurf.isar = request_mmio(&cs->rs, phymem, ISURF_IOMEM_SIZE, "isurf iomem"); + + cs->hw.isurf.isar = request_mmio(&cs->rs, phymem, ISURF_IOMEM_SIZE, + "isurf iomem"); if (!cs->hw.isurf.isar) goto err; cs->hw.isurf.isac = cs->hw.isurf.isar + ISURF_ISAC_OFFSET; - printk(KERN_INFO - "ISurf: defined at 0x%x 0x%lx IRQ %d\n", - cs->hw.isurf.reset, - card->para[2], - cs->irq); + printk(KERN_INFO "ISurf: defined at 0x%x 0x%lx IRQ %d\n", + cs->hw.isurf.reset, phymem, cs->irq); cs->auxcmd = &isurf_auxcmd; cs->card_ops = &isurf_ops; cs->bcs[0].hw.isar.reg = &cs->hw.isurf.isar_r; cs->bcs[1].hw.isar.reg = &cs->hw.isurf.isar_r; reset_isurf(cs, ISURF_RESET); - test_and_set_bit(HW_ISAR, &cs->HW_Flags); + __set_bit(HW_ISAR, &cs->HW_Flags); isac_setup(cs, &isac_ops); if (isar_setup(cs, &isar_ops)) goto err; - return 1; + return 0; err: hisax_release_resources(cs); - return 0; + return -EBUSY; +} + +int __init +setup_isurf(struct IsdnCard *card) +{ + char tmp[64]; + strcpy(tmp, ISurf_revision); + printk(KERN_INFO "HiSax: ISurf driver Rev. %s\n", HiSax_getrev(tmp)); + +#ifdef __ISAPNP__ + if (!card->para[1] || !card->para[2]) { + struct pnp_card *pb; + struct pnp_dev *pd; + + cs->subtyp = 0; + if ((pb = pnp_find_card( + ISAPNP_VENDOR('S', 'I', 'E'), + ISAPNP_FUNCTION(0x0010), pnp_surf))) { + pnp_surf = pb; + pd = NULL; + if (!(pd = pnp_find_dev(pnp_surf, + ISAPNP_VENDOR('S', 'I', 'E'), + ISAPNP_FUNCTION(0x0010), pd))) { + printk(KERN_ERR "ISurfPnP: PnP error card found, no device\n"); + return (0); + } + if (pnp_device_attach(pd) < 0) { + printk(KERN_ERR "ISurfPnP: attach failed\n"); + return 0; + } + if (pnp_activate_dev(pd) < 0) { + printk(KERN_ERR "ISurfPnP: activate failed\n"); + pnp_device_detach(pd); + return 0; + } + if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0) || !pnp_port_valid(pd, 1)) { + printk(KERN_ERR "ISurfPnP:some resources are missing %ld/%lx/%lx\n", + pnp_irq(pd, 0), pnp_port_start(pd, 0), pnp_port_start(pd, 1)); + pnp_device_detach(pd); + return(0); + } + card->para[1] = pnp_port_start(pd, 0); + card->para[2] = pnp_port_start(pd, 1); + card->para[0] = pnp_irq(pd, 0); + } else { + printk(KERN_INFO "ISurfPnP: no ISAPnP card found\n"); + return 0; + } + } +#endif + if (isurf_probe(card->cs, card) < 0) + return 0; + return 1; } diff --git a/drivers/isdn/hisax/ix1_micro.c b/drivers/isdn/hisax/ix1_micro.c index 58bc3204235b0..fd770f72161e8 100644 --- a/drivers/isdn/hisax/ix1_micro.c +++ b/drivers/isdn/hisax/ix1_micro.c @@ -162,6 +162,29 @@ static struct card_ops ix1_ops = { .irq_func = hscxisac_irq, }; +static int __init +ix1_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->irq = card->para[0]; + cs->hw.ix1.isac_ale = card->para[1] + ISAC_COMMAND_OFFSET; + cs->hw.ix1.isac = card->para[1] + ISAC_DATA_OFFSET; + cs->hw.ix1.hscx = card->para[1] + HSCX_DATA_OFFSET; + cs->hw.ix1.cfg_reg = card->para[1]; + if (!request_io(&cs->rs, cs->hw.ix1.cfg_reg, 4, "ix1micro cfg")) + goto err; + + printk(KERN_INFO "HiSax: %s config irq:%d io:0x%X\n", + CardType[cs->typ], cs->irq, cs->hw.ix1.cfg_reg); + ix1_reset(cs); + cs->card_ops = &ix1_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + #ifdef __ISAPNP__ static struct isapnp_device_id itk_ids[] __initdata = { { ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25), @@ -181,14 +204,18 @@ static struct pnp_card *pnp_c __devinitdata = NULL; int __init setup_ix1micro(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, ix1_revision); printk(KERN_INFO "HiSax: ITK IX1 driver Rev. %s\n", HiSax_getrev(tmp)); + if (card->para[1]) { + if (ix1_probe(card->cs, card)) + return 0; + return 1; + } #ifdef __ISAPNP__ - if (!card->para[1] && isapnp_present()) { + if (isapnp_present()) { struct pnp_card *pb; struct pnp_dev *pd; @@ -221,7 +248,9 @@ setup_ix1micro(struct IsdnCard *card) } card->para[1] = pnp_port_start(pd, 0); card->para[0] = pnp_irq(pd, 0); - break; + if (ix1_probe(card->cs, card)) + return 0; + return 1; } else { printk(KERN_ERR "ITK PnP: PnP error card found, no device\n"); } @@ -231,27 +260,8 @@ setup_ix1micro(struct IsdnCard *card) } if (!idev->card_vendor) { printk(KERN_INFO "ITK PnP: no ISAPnP card found\n"); - return(0); } } #endif - /* IO-Ports */ - cs->hw.ix1.isac_ale = card->para[1] + ISAC_COMMAND_OFFSET; - cs->hw.ix1.isac = card->para[1] + ISAC_DATA_OFFSET; - cs->hw.ix1.hscx = card->para[1] + HSCX_DATA_OFFSET; - cs->hw.ix1.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (!request_io(&cs->rs, cs->hw.ix1.cfg_reg, 4, "ix1micro cfg")) - goto err; - - printk(KERN_INFO "HiSax: %s config irq:%d io:0x%X\n", - CardType[cs->typ], cs->irq, cs->hw.ix1.cfg_reg); - ix1_reset(cs); - cs->card_ops = &ix1_ops; - if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - goto err; - return 1; - err: - hisax_release_resources(cs); return 0; } diff --git a/drivers/isdn/hisax/mic.c b/drivers/isdn/hisax/mic.c index 7e27313798164..0143811cf6948 100644 --- a/drivers/isdn/hisax/mic.c +++ b/drivers/isdn/hisax/mic.c @@ -138,17 +138,11 @@ static struct card_ops mic_ops = { .irq_func = hscxisac_irq, }; -int __init -setup_mic(struct IsdnCard *card) +static int __init +mic_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, mic_revision); - printk(KERN_INFO "HiSax: mic driver Rev. %s\n", HiSax_getrev(tmp)); - - cs->hw.mic.cfg_reg = card->para[1]; cs->irq = card->para[0]; + cs->hw.mic.cfg_reg = card->para[1]; cs->hw.mic.adr = cs->hw.mic.cfg_reg + MIC_ADR; cs->hw.mic.isac = cs->hw.mic.cfg_reg + MIC_ISAC; cs->hw.mic.hscx = cs->hw.mic.cfg_reg + MIC_HSCX; @@ -158,11 +152,25 @@ setup_mic(struct IsdnCard *card) printk(KERN_INFO "mic: defined at 0x%x IRQ %d\n", cs->hw.mic.cfg_reg, cs->irq); + cs->card_ops = &mic_ops; if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) goto err; - return 1; + return 0; err: hisax_release_resources(cs); - return 0; + return -EBUSY; +} + +int __init +setup_mic(struct IsdnCard *card) +{ + char tmp[64]; + + strcpy(tmp, mic_revision); + printk(KERN_INFO "HiSax: mic driver Rev. %s\n", HiSax_getrev(tmp)); + + if (mic_probe(card->cs, card) < 0) + return 0; + return 1; } diff --git a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c index e34cb5b576725..a33e2b30a679a 100644 --- a/drivers/isdn/hisax/niccy.c +++ b/drivers/isdn/hisax/niccy.c @@ -199,6 +199,70 @@ static struct card_ops niccy_ops = { .irq_func = niccy_interrupt, }; +static int __init +niccy_probe(struct IsdnCardState *cs) +{ + printk(KERN_INFO "HiSax: %s %s config irq:%d data:0x%X ale:0x%X\n", + CardType[cs->typ], (cs->subtyp==1) ? "PnP":"PCI", + cs->irq, cs->hw.niccy.isac, cs->hw.niccy.isac_ale); + cs->card_ops = &niccy_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + return -EBUSY; + return 0; +} + +static int __init +niccy_pnp_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->subtyp = NICCY_PNP; + cs->irq = card->para[0]; + cs->hw.niccy.isac = card->para[1] + ISAC_PNP; + cs->hw.niccy.hscx = card->para[1] + HSCX_PNP; + cs->hw.niccy.isac_ale = card->para[2] + ISAC_PNP; + cs->hw.niccy.hscx_ale = card->para[2] + HSCX_PNP; + cs->hw.niccy.cfg_reg = 0; + + if (!request_io(&cs->rs, cs->hw.niccy.isac, 2, "niccy data")) + goto err; + if (!request_io(&cs->rs, cs->hw.niccy.isac_ale, 2, "niccy addr")) + goto err; + if (niccy_probe(cs) < 0) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +niccy_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + u32 pci_ioaddr; + + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = NICCY_PCI; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.niccy.cfg_reg = pci_resource_start(pdev, 0); + pci_ioaddr = pci_resource_start(pdev, 1); + cs->hw.niccy.isac = pci_ioaddr + ISAC_PCI_DATA; + cs->hw.niccy.isac_ale = pci_ioaddr + ISAC_PCI_ADDR; + cs->hw.niccy.hscx = pci_ioaddr + HSCX_PCI_DATA; + cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR; + if (!request_io(&cs->rs, cs->hw.niccy.isac, 4, "niccy")) + goto err; + if (!request_io(&cs->rs, cs->hw.niccy.cfg_reg, 0x40, "niccy pci")) + goto err; + if (niccy_probe(cs) < 0) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + static struct pci_dev *niccy_dev __initdata = NULL; #ifdef __ISAPNP__ static struct pnp_card *pnp_c __devinitdata = NULL; @@ -207,7 +271,6 @@ static struct pnp_card *pnp_c __devinitdata = NULL; int __init setup_niccy(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, niccy_revision); @@ -252,66 +315,18 @@ setup_niccy(struct IsdnCard *card) } #endif if (card->para[1]) { - cs->hw.niccy.isac = card->para[1] + ISAC_PNP; - cs->hw.niccy.hscx = card->para[1] + HSCX_PNP; - cs->hw.niccy.isac_ale = card->para[2] + ISAC_PNP; - cs->hw.niccy.hscx_ale = card->para[2] + HSCX_PNP; - cs->hw.niccy.cfg_reg = 0; - cs->subtyp = NICCY_PNP; - cs->irq = card->para[0]; - if (!request_io(&cs->rs, cs->hw.niccy.isac, 2, "niccy data")) - goto err; - if (!request_io(&cs->rs, cs->hw.niccy.isac_ale, 2, "niccy addr")) - goto err; + if (niccy_pnp_probe(card->cs, card) < 0) + return 0; + return 1; } else { #if CONFIG_PCI - u_int pci_ioaddr; - cs->subtyp = 0; if ((niccy_dev = pci_find_device(PCI_VENDOR_ID_SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY, niccy_dev))) { - if (pci_enable_device(niccy_dev)) - return(0); - /* get IRQ */ - if (!niccy_dev->irq) { - printk(KERN_WARNING "Niccy: No IRQ for PCI card found\n"); - return(0); - } - cs->irq = niccy_dev->irq; - cs->hw.niccy.cfg_reg = pci_resource_start(niccy_dev, 0); - if (!cs->hw.niccy.cfg_reg) { - printk(KERN_WARNING "Niccy: No IO-Adr for PCI cfg found\n"); - return(0); - } - pci_ioaddr = pci_resource_start(niccy_dev, 1); - if (!pci_ioaddr) { - printk(KERN_WARNING "Niccy: No IO-Adr for PCI card found\n"); - return(0); - } - cs->subtyp = NICCY_PCI; - } else { - printk(KERN_WARNING "Niccy: No PCI card found\n"); - return(0); + if (niccy_pci_probe(card->cs, niccy_dev) < 0) + return 0; + return 1; } - cs->irq_flags |= SA_SHIRQ; - cs->hw.niccy.isac = pci_ioaddr + ISAC_PCI_DATA; - cs->hw.niccy.isac_ale = pci_ioaddr + ISAC_PCI_ADDR; - cs->hw.niccy.hscx = pci_ioaddr + HSCX_PCI_DATA; - cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR; - - if (!request_io(&cs->rs, cs->hw.niccy.isac, 4, "niccy")) - goto err; - if (!request_io(&cs->rs, cs->hw.niccy.cfg_reg, 0x40, "niccy pci")) - goto err; #endif /* CONFIG_PCI */ } - printk(KERN_INFO "HiSax: %s %s config irq:%d data:0x%X ale:0x%X\n", - CardType[cs->typ], (cs->subtyp==1) ? "PnP":"PCI", - cs->irq, cs->hw.niccy.isac, cs->hw.niccy.isac_ale); - cs->card_ops = &niccy_ops; - if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - goto err; - return 1; - err: - niccy_release(cs); return 0; } diff --git a/drivers/isdn/hisax/nj_s.c b/drivers/isdn/hisax/nj_s.c index 047b1d7c2a6c8..b14166e0d41e6 100644 --- a/drivers/isdn/hisax/nj_s.c +++ b/drivers/isdn/hisax/nj_s.c @@ -106,96 +106,99 @@ static struct card_ops nj_s_ops = { .irq_func = nj_s_interrupt, }; -static struct pci_dev *dev_netjet __initdata = NULL; - -int __init -setup_netjet_s(struct IsdnCard *card) +static int __init +nj_s_probe(struct IsdnCardState *cs, struct pci_dev *pdev) { - struct IsdnCardState *cs = card->cs; - char tmp[64]; - -#ifdef __BIG_ENDIAN -#error "not running on big endian machines now" -#endif - strcpy(tmp, NETjet_S_revision); - printk(KERN_INFO "HiSax: Traverse Tech. NETjet-S driver Rev. %s\n", HiSax_getrev(tmp)); - - for ( ;; ) { - if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, - PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { - if (pci_enable_device(dev_netjet)) - return(0); - pci_set_master(dev_netjet); - cs->irq = dev_netjet->irq; - if (!cs->irq) { - printk(KERN_WARNING "NETjet-S: No IRQ for PCI card found\n"); - return(0); - } - cs->hw.njet.base = pci_resource_start(dev_netjet, 0); - if (!cs->hw.njet.base) { - printk(KERN_WARNING "NETjet-S: No IO-Adr for PCI card found\n"); - return(0); - } - /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG www.formula-n.com */ - if ((dev_netjet->subsystem_vendor == 0x55) && - (dev_netjet->subsystem_device == 0x02)) { - printk(KERN_WARNING "Netjet: You tried to load this driver with an incompatible TigerJet-card\n"); - printk(KERN_WARNING "Use type=41 for Formula-n enter:now ISDN PCI and compatible\n"); - return(0); - } - /* end new code */ - cs->hw.njet.pdev = dev_netjet; - } else { - printk(KERN_WARNING "NETjet-S: No PCI card found\n"); - return(0); - } - - cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; - cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF; - - cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ - byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ - - cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */ - byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); + if (pci_enable_device(pdev)) + goto err; + + pci_set_master(pdev); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ - - cs->hw.njet.auxd = 0xC0; - cs->hw.njet.dmactrl = 0; - - byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ); - byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ); - byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); - - switch ( ( ( NETjet_ReadIC( cs, ISAC_RBCH ) >> 5 ) & 3 ) ) - { - case 0 : - break; + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.njet.pdev = pdev; + cs->hw.njet.base = pci_resource_start(pdev, 0); + if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn")) + return 0; + + cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; + cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF; + + cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ + byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - case 3 : - printk( KERN_WARNING "NETjet-S: NETspider-U PCI card found\n" ); - continue; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ + + cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */ + byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ + + cs->hw.njet.auxd = 0xC0; + cs->hw.njet.dmactrl = 0; + + byteout(cs->hw.njet.auxa, 0); + byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ); + byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ); + byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); - default : - printk( KERN_WARNING "NETjet-S: No PCI card found\n" ); - return 0; - } - break; + switch ((NETjet_ReadIC(cs, ISAC_RBCH) >> 5) & 3) { + case 0 : + break; + case 3 : + printk(KERN_WARNING "NETjet-S: NETspider-U PCI card found\n" ); + goto err; + default : + printk(KERN_WARNING "NETjet-S: No PCI card found\n" ); + goto err; } printk(KERN_INFO "NETjet-S: PCI card configured at %#lx IRQ %d\n", cs->hw.njet.base, cs->irq); - if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn")) - return 0; nj_s_reset(cs); cs->irq_flags |= SA_SHIRQ; cs->card_ops = &nj_s_ops; isac_setup(cs, &netjet_dc_ops); - return 1; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static struct pci_dev *dev_netjet __initdata = NULL; + +int __init +setup_netjet_s(struct IsdnCard *card) +{ + char tmp[64]; + +#ifdef __BIG_ENDIAN +#error "not running on big endian machines now" +#endif + strcpy(tmp, NETjet_S_revision); + printk(KERN_INFO "HiSax: Traverse Tech. NETjet-S driver Rev. %s\n", + HiSax_getrev(tmp)); + + dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, + PCI_DEVICE_ID_TIGERJET_300, dev_netjet); + if (dev_netjet) { + /* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG www.formula-n.com */ + if (dev_netjet->subsystem_vendor == 0x55 && + dev_netjet->subsystem_device == 0x02) { + printk(KERN_WARNING "Netjet: You tried to load this " + "driver with an incompatible TigerJet-card\n"); + printk(KERN_WARNING "Use type=41 for Formula-n " + "enter:now ISDN PCI and compatible\n"); + return 0; + } + if (nj_s_probe(card->cs, dev_netjet)) + return 1; + return 0; + } + printk(KERN_WARNING "NETjet-S: No PCI card found\n"); + return 0; } + diff --git a/drivers/isdn/hisax/nj_u.c b/drivers/isdn/hisax/nj_u.c index 24d6489f69274..41b359c4fe6d0 100644 --- a/drivers/isdn/hisax/nj_u.c +++ b/drivers/isdn/hisax/nj_u.c @@ -110,88 +110,85 @@ static struct card_ops nj_u_ops = { .irq_func = nj_u_interrupt, }; +static int __init +nj_u_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + pci_set_master(pdev); + + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.njet.pdev = pdev; + cs->hw.njet.base = pci_resource_start(pdev, 0); + if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netspider-u isdn")) + goto err; + + cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; + cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF; + + cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ + byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ + + cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */ + byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ + + cs->hw.njet.auxd = 0xC0; + cs->hw.njet.dmactrl = 0; + + byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ); + byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ); + byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); + + switch ((NETjet_ReadIC(cs, ICC_RBCH) >> 5) & 3) { + case 3: + break; + case 0: + printk(KERN_WARNING "NETspider-U: NETjet-S PCI card found\n" ); + goto err; + default: + printk(KERN_WARNING "NETspider-U: No PCI card found\n" ); + goto err; + } + printk(KERN_INFO "NETspider-U: PCI card configured at %#lx IRQ %d\n", + cs->hw.njet.base, cs->irq); + + nj_u_reset(cs); + cs->card_ops = &nj_u_ops; + icc_setup(cs, &netjet_dc_ops); + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + static struct pci_dev *dev_netjet __initdata = NULL; int __init setup_netjet_u(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; #ifdef __BIG_ENDIAN #error "not running on big endian machines now" #endif strcpy(tmp, NETjet_U_revision); - printk(KERN_INFO "HiSax: Traverse Tech. NETspider-U driver Rev. %s\n", HiSax_getrev(tmp)); - - for ( ;; ) { - if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, - PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { - if (pci_enable_device(dev_netjet)) - return(0); - pci_set_master(dev_netjet); - cs->irq = dev_netjet->irq; - if (!cs->irq) { - printk(KERN_WARNING "NETspider-U: No IRQ for PCI card found\n"); - return(0); - } - cs->hw.njet.base = pci_resource_start(dev_netjet, 0); - if (!cs->hw.njet.base) { - printk(KERN_WARNING "NETspider-U: No IO-Adr for PCI card found\n"); - return(0); - } - cs->hw.njet.pdev = dev_netjet; - } else { - printk(KERN_WARNING "NETspider-U: No PCI card found\n"); - return(0); - } - - cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; - cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF; - - cs->hw.njet.ctrl_reg = 0xff; /* Reset On */ - byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ - - cs->hw.njet.ctrl_reg = 0x00; /* Reset Off and status read clear */ - byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg); - - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout((10*HZ)/1000); /* Timeout 10ms */ - - cs->hw.njet.auxd = 0xC0; - cs->hw.njet.dmactrl = 0; - - byteout(cs->hw.njet.auxa, 0); - byteout(cs->hw.njet.base + NETJET_AUXCTRL, ~NETJET_ISACIRQ); - byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ); - byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); - - switch ( ( ( NETjet_ReadIC( cs, ICC_RBCH ) >> 5 ) & 3 ) ) - { - case 3 : - break; - - case 0 : - printk( KERN_WARNING "NETspider-U: NETjet-S PCI card found\n" ); - continue; - - default : - printk( KERN_WARNING "NETspider-U: No PCI card found\n" ); - return 0; - } - break; - } - printk(KERN_INFO - "NETspider-U: PCI card configured at %#lx IRQ %d\n", - cs->hw.njet.base, cs->irq); - if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn")) - return 0; + printk(KERN_INFO "HiSax: Traverse Tech. NETspider-U driver Rev. %s\n", + HiSax_getrev(tmp)); - nj_u_reset(cs); - cs->irq_flags |= SA_SHIRQ; - cs->card_ops = &nj_u_ops; - icc_setup(cs, &netjet_dc_ops); - return 1; + dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, + PCI_DEVICE_ID_TIGERJET_300, dev_netjet); + if (dev_netjet) { + if (nj_u_probe(card->cs, dev_netjet)) + return 1; + return 0; + } + printk(KERN_WARNING "NETspider-U: No PCI card found\n"); + return 0; } diff --git a/drivers/isdn/hisax/s0box.c b/drivers/isdn/hisax/s0box.c index 7a676aee0b404..df6e65f4ae7b4 100644 --- a/drivers/isdn/hisax/s0box.c +++ b/drivers/isdn/hisax/s0box.c @@ -172,14 +172,9 @@ static struct card_ops s0box_ops = { .irq_func = hscxisac_irq, }; -int __init -setup_s0box(struct IsdnCard *card) +static int __init +s0box_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, s0box_revision); - printk(KERN_INFO "HiSax: S0Box IO driver Rev. %s\n", HiSax_getrev(tmp)); cs->hw.teles3.cfg_reg = card->para[1]; cs->hw.teles3.hscx[0] = -0x20; cs->hw.teles3.hscx[1] = 0x0; @@ -200,8 +195,20 @@ setup_s0box(struct IsdnCard *card) cs->card_ops = &s0box_ops; if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) goto err; - return 1; + return 0; err: hisax_release_resources(cs); - return 0; + return -EBUSY; +} + +int __init +setup_s0box(struct IsdnCard *card) +{ + char tmp[64]; + + strcpy(tmp, s0box_revision); + printk(KERN_INFO "HiSax: S0Box IO driver Rev. %s\n", HiSax_getrev(tmp)); + if (s0box_probe(card->cs, card)) + return 0; + return 1; } diff --git a/drivers/isdn/hisax/saphir.c b/drivers/isdn/hisax/saphir.c index ca2a46892e6ff..aa3f5a9eafbc3 100644 --- a/drivers/isdn/hisax/saphir.c +++ b/drivers/isdn/hisax/saphir.c @@ -201,36 +201,21 @@ static struct card_ops saphir_ops = { .irq_func = saphir_interrupt, }; -int __init -setup_saphir(struct IsdnCard *card) +static int __init +saphir_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, saphir_rev); - printk(KERN_INFO "HiSax: HST Saphir driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_HSTSAPHIR) - return (0); - - init_timer(&cs->hw.saphir.timer); - /* IO-Ports */ cs->hw.saphir.cfg_reg = card->para[1]; cs->hw.saphir.isac = card->para[1] + ISAC_DATA; cs->hw.saphir.hscx = card->para[1] + HSCX_DATA; cs->hw.saphir.ale = card->para[1] + ADDRESS_REG; cs->irq = card->para[0]; + if (!request_io(&cs->rs, cs->hw.saphir.cfg_reg, 6, "saphir")) goto err; - printk(KERN_INFO - "HiSax: %s config irq:%d io:0x%X\n", - CardType[cs->typ], cs->irq, - cs->hw.saphir.cfg_reg); + printk(KERN_INFO "HiSax: %s config irq:%d io:0x%X\n", + CardType[cs->typ], cs->irq, cs->hw.saphir.cfg_reg); - cs->hw.saphir.timer.function = (void *) SaphirWatchDog; - cs->hw.saphir.timer.data = (long) cs; - cs->hw.saphir.timer.expires = jiffies + 4*HZ; - add_timer(&cs->hw.saphir.timer); if (saphir_reset(cs)) goto err; @@ -238,8 +223,27 @@ setup_saphir(struct IsdnCard *card) if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) goto err; - return 1; - err: - saphir_release(cs); + init_timer(&cs->hw.saphir.timer); + cs->hw.saphir.timer.function = (void *) SaphirWatchDog; + cs->hw.saphir.timer.data = (long) cs; + cs->hw.saphir.timer.expires = jiffies + 4*HZ; + add_timer(&cs->hw.saphir.timer); return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +int __init +setup_saphir(struct IsdnCard *card) +{ + char tmp[64]; + + strcpy(tmp, saphir_rev); + printk(KERN_INFO "HiSax: HST Saphir driver Rev. %s\n", + HiSax_getrev(tmp)); + + if (saphir_probe(card->cs, card) < 0) + return 0; + return 1; } diff --git a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c index 54b18911b5678..a47543f2b6fe7 100644 --- a/drivers/isdn/hisax/sedlbauer.c +++ b/drivers/isdn/hisax/sedlbauer.c @@ -73,7 +73,6 @@ const char *Sedlbauer_Types[] = #define SEDL_SPEEDFAX_PYRAMID 7 #define SEDL_SPEEDFAX_PCI 8 -#define SEDL_CHIP_TEST 0 #define SEDL_CHIP_ISAC_HSCX 1 #define SEDL_CHIP_ISAC_ISAR 2 #define SEDL_CHIP_IPAC 3 @@ -452,6 +451,241 @@ static struct card_ops sedlbauer_isar_ops = { .irq_func = sedlbauer_isar_interrupt, }; +static int __init +sedl_ipac_probe(struct IsdnCardState *cs) +{ + u8 val; + + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR; + val = readreg(cs, cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC, IPAC_ID); + printk(KERN_DEBUG "Sedlbauer: testing IPAC version %x\n", val); + return (val == 1 || val == 2); +} + +static int __init +sedl_ipac_init(struct IsdnCardState *cs) +{ + cs->card_ops = &sedlbauer_ipac_ops; + if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) + return -ENODEV; + sedlbauer_reset(cs); + return 0; +} + +static int __init +sedl_isac_isar_init(struct IsdnCardState *cs) +{ + cs->bcs[0].hw.isar.reg = &cs->hw.sedl.isar; + cs->bcs[1].hw.isar.reg = &cs->hw.sedl.isar; + __set_bit(HW_ISAR, &cs->HW_Flags); + cs->card_ops = &sedlbauer_isar_ops; + cs->auxcmd = &isar_auxcmd; + isac_setup(cs, &isac_ops); + return isar_setup(cs, &isar_ops); +} + +static int __init +sedl_isac_hscx_init(struct IsdnCardState *cs) +{ + cs->card_ops = &sedlbauer_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + return -ENODEV; + sedlbauer_reset(cs); + return 0; +} + +static int __init +sedl_card_win_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->irq = card->para[0]; + cs->hw.sedl.cfg_reg = card->para[1]; + cs->hw.sedl.bus = SEDL_BUS_ISA; + if (!request_io(&cs->rs, cs->hw.sedl.cfg_reg, 8, "sedlbauer isdn")) + goto err; + + if (sedl_ipac_probe(cs)) { + cs->subtyp = SEDL_SPEED_WIN2_PC104; + cs->hw.sedl.chip = SEDL_CHIP_IPAC; + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR; + cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC; + if (sedl_ipac_init(cs)) + goto err; + } else { + cs->subtyp = SEDL_SPEED_CARD_WIN; + cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX; + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ADR; + cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ISAC; + cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_HSCX; + cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_ON; + cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF; + if (sedl_isac_hscx_init(cs)) + goto err; + } + printk(KERN_INFO "Sedlbauer %s: defined at 0x%x-0x%x IRQ %d\n", + Sedlbauer_Types[cs->subtyp], + cs->hw.sedl.cfg_reg, cs->hw.sedl.cfg_reg + 8, cs->irq); + + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +sedl_star_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->hw.sedl.bus = SEDL_BUS_PCMCIA; + if (sedl_ipac_probe(cs)) { + cs->subtyp = SEDL_SPEED_STAR2; + cs->hw.sedl.chip = SEDL_CHIP_IPAC; + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR; + cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC; + if (sedl_ipac_init(cs)) + goto err; + } else { + cs->subtyp = SEDL_SPEED_STAR; + cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX; + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ADR; + cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ISAC; + cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_HSCX; + cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET; + cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET; + if (sedl_isac_hscx_init(cs)) + goto err; + } + printk(KERN_INFO "Sedlbauer %s: defined at 0x%x-0x%x IRQ %d\n", + Sedlbauer_Types[cs->subtyp], + cs->hw.sedl.cfg_reg, cs->hw.sedl.cfg_reg + 8, cs->irq); + + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +sedl_fax_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->subtyp = SEDL_SPEED_FAX; + cs->hw.sedl.bus = SEDL_BUS_ISA; + cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; + if (!request_io(&cs->rs, cs->hw.sedl.cfg_reg, 16, "sedlbauer isdn")) + goto err; + + printk(KERN_INFO "Sedlbauer %s: defined at 0x%x-0x%x IRQ %d\n", + Sedlbauer_Types[cs->subtyp], + cs->hw.sedl.cfg_reg, cs->hw.sedl.cfg_reg + 16, cs->irq); + + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ADR; + cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ISAC; + cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ISAR; + cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ISAR_RESET_ON; + cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_ISAR_ISA_ISAR_RESET_OFF; + if (sedl_isac_isar_init(cs)) + goto err; + + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +sedl_pci_init(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.sedl.cfg_reg = pci_resource_start(pdev, 0); + cs->hw.sedl.bus = SEDL_BUS_PCI; + + if (!request_io(&cs->rs, cs->hw.sedl.cfg_reg, 256, "sedlbauer isdn")) + return -EBUSY; + + printk(KERN_INFO "Sedlbauer %s: defined at 0x%x-0x%x IRQ %d\n", + Sedlbauer_Types[cs->subtyp], + cs->hw.sedl.cfg_reg, cs->hw.sedl.cfg_reg + 256, cs->irq); + + cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON; + cs->hw.sedl.reset_off = SEDL_ISAR_PCI_ISAR_RESET_OFF; + byteout(cs->hw.sedl.cfg_reg, 0xff); + byteout(cs->hw.sedl.cfg_reg, 0x00); + byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd); + byteout(cs->hw.sedl.cfg_reg+ 5, 0x02); + byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on); + current->state = TASK_UNINTERRUPTIBLE; + schedule_timeout((10*HZ)/1000); + byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off); + return 0; +} + +static int __init +sedl_fax_pyramid_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = SEDL_SPEEDFAX_PYRAMID; + cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; + if (sedl_pci_init(cs, pdev)) + goto err; + + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ADR; + cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ISAC; + cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ISAR; + if (sedl_isac_isar_init(cs)) + goto err; + + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +sedl_fax_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = SEDL_SPEEDFAX_PCI; + cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; + + if (sedl_pci_init(cs, pdev)) + goto err; + + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ADR; + cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ISAC; + cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_ISAR_PCI_ISAR; + if (sedl_isac_isar_init(cs)) + goto err; + + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +sedl_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + if (pci_enable_device(pdev)) + goto err; + + cs->subtyp = SEDL_SPEED_PCI; + cs->hw.sedl.chip = SEDL_CHIP_IPAC; + if (sedl_pci_init(cs, pdev)) + goto err; + + cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_ADR; + cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC; + if (sedl_ipac_init(cs)) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + static struct pci_dev *dev_sedl __devinitdata = NULL; #ifdef __ISAPNP__ @@ -472,265 +706,117 @@ static struct pnp_card *pnp_c __devinitdata = NULL; int __devinit setup_sedlbauer(struct IsdnCard *card) { - int bytecnt, val; struct IsdnCardState *cs = card->cs; char tmp[64]; u16 sub_vendor_id, sub_id; strcpy(tmp, Sedlbauer_revision); - printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", HiSax_getrev(tmp)); + printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", + HiSax_getrev(tmp)); - if (cs->typ == ISDN_CTYPE_SEDLBAUER) { - cs->subtyp = SEDL_SPEED_CARD_WIN; - cs->hw.sedl.bus = SEDL_BUS_ISA; - cs->hw.sedl.chip = SEDL_CHIP_TEST; - } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) { - cs->subtyp = SEDL_SPEED_STAR; - cs->hw.sedl.bus = SEDL_BUS_PCMCIA; - cs->hw.sedl.chip = SEDL_CHIP_TEST; - } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) { - cs->subtyp = SEDL_SPEED_FAX; - cs->hw.sedl.bus = SEDL_BUS_ISA; - cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; - } else - return (0); - - bytecnt = 8; if (card->para[1]) { - cs->hw.sedl.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) { - bytecnt = 16; + if (cs->typ == ISDN_CTYPE_SEDLBAUER) { + if (sedl_card_win_probe(card->cs, card) < 0) + return 0; + return 1; + } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) { + if (sedl_star_probe(card->cs, card) < 0) + return 0; + return 1; + } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) { + if (sedl_fax_probe(card->cs, card) < 0) + return 0; + return 1; } - } else { + } #ifdef __ISAPNP__ - if (isapnp_present()) { - struct pnp_card *pb; - struct pnp_dev *pd; - - while(pdev->card_vendor) { - if ((pb = pnp_find_card(pdev->card_vendor, - pdev->card_device, - pnp_c))) { - pnp_c = pb; - pd = NULL; - if ((pd = pnp_find_dev(pnp_c, - pdev->vendor, - pdev->function, - pd))) { - printk(KERN_INFO "HiSax: %s detected\n", - (char *)pdev->driver_data); - if (pnp_device_attach(pd) < 0) { - printk(KERN_ERR "Sedlbauer PnP: attach failed\n"); - return 0; - } - if (pnp_activate_dev(pd) < 0) { - printk(KERN_ERR "Sedlbauer PnP: activate failed\n"); - pnp_device_detach(pd); + if (isapnp_present()) { + struct pnp_card *pb; + struct pnp_dev *pd; + + while(pdev->card_vendor) { + if ((pb = pnp_find_card(pdev->card_vendor, + pdev->card_device, + pnp_c))) { + pnp_c = pb; + pd = NULL; + if ((pd = pnp_find_dev(pnp_c, + pdev->vendor, + pdev->function, + pd))) { + printk(KERN_INFO "HiSax: %s detected\n", + (char *)pdev->driver_data); + if (pnp_device_attach(pd) < 0) { + printk(KERN_ERR "Sedlbauer PnP: attach failed\n"); + return 0; + } + if (pnp_activate_dev(pd) < 0) { + printk(KERN_ERR "Sedlbauer PnP: activate failed\n"); + pnp_device_detach(pd); + return 0; + } + if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0)) { + printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n", + pnp_irq(pd, 0), pnp_port_start(pd, 0)); + pnp_device_detach(pd); + goto err; + } + card->para[1] = pnp_port_start(pd, 0); + card->para[0] = pnp_irq(pd, 0); + cs->hw.sedl.cfg_reg = card->para[1]; + cs->irq = card->para[0]; + if (pdev->function == ISAPNP_FUNCTION(0x2)) { + if (sedl_fax_probe(card->cs, card)) return 0; - } - if (!pnp_irq_valid(pd, 0) || !pnp_port_valid(pd, 0)) { - printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n", - pnp_irq(pd, 0), pnp_port_start(pd, 0)); - pnp_device_detach(pd); - goto err; - } - card->para[1] = pnp_port_start(pd, 0); - card->para[0] = pnp_irq(pd, 0); - cs->hw.sedl.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (pdev->function == ISAPNP_FUNCTION(0x2)) { - cs->subtyp = SEDL_SPEED_FAX; - cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; - bytecnt = 16; - } else { - cs->subtyp = SEDL_SPEED_CARD_WIN; - cs->hw.sedl.chip = SEDL_CHIP_TEST; - } - goto ready; + return 1; } else { - printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n"); - goto err; + if (sedl_card_win_probe(card->cs, card)) + return 0; + return 1; } + } else { + printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n"); + goto err; } - pdev++; - pnp_c=NULL; - } - if (!pdev->card_vendor) { - printk(KERN_INFO "Sedlbauer PnP: no ISAPnP card found\n"); } + pdev++; + pnp_c=NULL; + } + if (!pdev->card_vendor) { + printk(KERN_INFO "Sedlbauer PnP: no ISAPnP card found\n"); } + } #endif /* Probe for Sedlbauer speed pci */ #if CONFIG_PCI - if ((dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET, - PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) { - if (pci_enable_device(dev_sedl)) - goto err; - cs->irq = dev_sedl->irq; - if (!cs->irq) { - printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n"); - goto err; - } - cs->hw.sedl.cfg_reg = pci_resource_start(dev_sedl, 0); - } else { - printk(KERN_WARNING "Sedlbauer: No PCI card found\n"); - goto err; - } - cs->irq_flags |= SA_SHIRQ; - cs->hw.sedl.bus = SEDL_BUS_PCI; + dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET, + PCI_DEVICE_ID_TIGERJET_100, dev_sedl); + if (dev_sedl) { sub_vendor_id = dev_sedl->subsystem_vendor; sub_id = dev_sedl->subsystem_device; printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %x\n", - sub_vendor_id, sub_id); - printk(KERN_INFO "Sedlbauer: PCI base adr %#x\n", - cs->hw.sedl.cfg_reg); + sub_vendor_id, sub_id); if (sub_id != PCI_SUB_ID_SEDLBAUER) { printk(KERN_ERR "Sedlbauer: unknown sub id %#x\n", sub_id); - goto err; + return 0; } if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) { - cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; - cs->subtyp = SEDL_SPEEDFAX_PYRAMID; + if (sedl_fax_pyramid_probe(cs, dev_sedl)) + return 0; + return 1; } else if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PCI) { - cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; - cs->subtyp = SEDL_SPEEDFAX_PCI; + if (sedl_fax_pci_probe(cs, dev_sedl)) + return 0; + return 1; } else if (sub_vendor_id == PCI_SUBVENDOR_SEDLBAUER_PCI) { - cs->hw.sedl.chip = SEDL_CHIP_IPAC; - cs->subtyp = SEDL_SPEED_PCI; - } else { - printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n", - sub_vendor_id); - goto err; - } - bytecnt = 256; - cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON; - cs->hw.sedl.reset_off = SEDL_ISAR_PCI_ISAR_RESET_OFF; - byteout(cs->hw.sedl.cfg_reg, 0xff); - byteout(cs->hw.sedl.cfg_reg, 0x00); - byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd); - byteout(cs->hw.sedl.cfg_reg+ 5, 0x02); - byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on); - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout((10*HZ)/1000); - byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off); -#endif /* CONFIG_PCI */ - } -ready: - /* In case of the sedlbauer pcmcia card, this region is in use, - * reserved for us by the card manager. So we do not check it - * here, it would fail. - */ - if (cs->hw.sedl.bus != SEDL_BUS_PCMCIA) { - if (!request_io(&cs->rs, cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn")) - goto err; - } - - printk(KERN_INFO - "Sedlbauer: defined at 0x%x-0x%x IRQ %d\n", - cs->hw.sedl.cfg_reg, - cs->hw.sedl.cfg_reg + bytecnt, - cs->irq); - -/* - * testing ISA and PCMCIA Cards for IPAC, default is ISAC - * do not test for PCI card, because ports are different - * and PCI card uses only IPAC (for the moment) - */ - if (cs->hw.sedl.bus != SEDL_BUS_PCI) { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR; - val = readreg(cs, cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC, - IPAC_ID); - printk(KERN_DEBUG "Sedlbauer: testing IPAC version %x\n", val); - if ((val == 1) || (val == 2)) { - /* IPAC */ - cs->subtyp = SEDL_SPEED_WIN2_PC104; - if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) { - cs->subtyp = SEDL_SPEED_STAR2; - } - cs->hw.sedl.chip = SEDL_CHIP_IPAC; - } else { - /* ISAC_HSCX oder ISAC_ISAR */ - if (cs->hw.sedl.chip == SEDL_CHIP_TEST) { - cs->hw.sedl.chip = SEDL_CHIP_ISAC_HSCX; - } - } - } - -/* - * hw.sedl.chip is now properly set - */ - printk(KERN_INFO "Sedlbauer: %s detected\n", - Sedlbauer_Types[cs->subtyp]); - - - if (cs->hw.sedl.chip == SEDL_CHIP_IPAC) { - if (cs->hw.sedl.bus == SEDL_BUS_PCI) { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_ADR; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_PCI_IPAC; - } else { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_ADR; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_IPAC_ANY_IPAC; - } - cs->card_ops = &sedlbauer_ipac_ops; - if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) - goto err; - sedlbauer_reset(cs); - } else { - /* ISAC_HSCX oder ISAC_ISAR */ - if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) { - if (cs->hw.sedl.bus == SEDL_BUS_PCI) { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + - SEDL_ISAR_PCI_ADR; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + - SEDL_ISAR_PCI_ISAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + - SEDL_ISAR_PCI_ISAR; - } else { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + - SEDL_ISAR_ISA_ADR; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + - SEDL_ISAR_ISA_ISAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + - SEDL_ISAR_ISA_ISAR; - cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + - SEDL_ISAR_ISA_ISAR_RESET_ON; - cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + - SEDL_ISAR_ISA_ISAR_RESET_OFF; - } - cs->bcs[0].hw.isar.reg = &cs->hw.sedl.isar; - cs->bcs[1].hw.isar.reg = &cs->hw.sedl.isar; - test_and_set_bit(HW_ISAR, &cs->HW_Flags); - cs->card_ops = &sedlbauer_isar_ops; - cs->auxcmd = &isar_auxcmd; - isac_setup(cs, &isac_ops); - if (isar_setup(cs, &isar_ops)) - goto err; - } else { - if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ADR; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_ISAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_HSCX; - cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET; - cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_PCMCIA_RESET; - } else { - cs->hw.sedl.adr = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ADR; - cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_ISAC; - cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_HSCX; - cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_ON; - cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg + SEDL_HSCX_ISA_RESET_OFF; - } - cs->card_ops = &sedlbauer_ops; - if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - goto err; - - sedlbauer_reset(cs); + if (sedl_pci_probe(cs, dev_sedl)) + return 0; + return 1; } + printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n", + sub_vendor_id); + return 0; } - return 1; - err: - hisax_release_resources(cs); +#endif /* CONFIG_PCI */ return 0; } diff --git a/drivers/isdn/hisax/sportster.c b/drivers/isdn/hisax/sportster.c index 5c215a9857c79..0376d745165a4 100644 --- a/drivers/isdn/hisax/sportster.c +++ b/drivers/isdn/hisax/sportster.c @@ -189,42 +189,29 @@ get_io_range(struct IsdnCardState *cs) } return 0; } - -int __init -setup_sportster(struct IsdnCard *card) -{ - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, sportster_revision); - printk(KERN_INFO "HiSax: USR Sportster driver Rev. %s\n", HiSax_getrev(tmp)); - cs->hw.spt.cfg_reg = card->para[1]; +static int __init +sportster_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ cs->irq = card->para[0]; + cs->hw.spt.cfg_reg = card->para[1]; if (!get_io_range(cs)) - return (0); + return -EBUSY; cs->hw.spt.isac = cs->hw.spt.cfg_reg + SPORTSTER_ISAC; cs->hw.spt.hscx[0] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXA; cs->hw.spt.hscx[1] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXB; switch(cs->irq) { - case 5: cs->hw.spt.res_irq = 1; - break; - case 7: cs->hw.spt.res_irq = 2; - break; - case 10:cs->hw.spt.res_irq = 3; - break; - case 11:cs->hw.spt.res_irq = 4; - break; - case 12:cs->hw.spt.res_irq = 5; - break; - case 14:cs->hw.spt.res_irq = 6; - break; - case 15:cs->hw.spt.res_irq = 7; - break; - default:sportster_release(cs); - printk(KERN_WARNING "Sportster: wrong IRQ\n"); - return(0); + case 5: cs->hw.spt.res_irq = 1; break; + case 7: cs->hw.spt.res_irq = 2; break; + case 10:cs->hw.spt.res_irq = 3; break; + case 11:cs->hw.spt.res_irq = 4; break; + case 12:cs->hw.spt.res_irq = 5; break; + case 14:cs->hw.spt.res_irq = 6; break; + case 15:cs->hw.spt.res_irq = 7; break; + default: + printk(KERN_WARNING "Sportster: wrong IRQ\n"); + goto err; } sportster_reset(cs); printk(KERN_INFO "HiSax: %s config irq:%d cfg:0x%X\n", @@ -234,8 +221,22 @@ setup_sportster(struct IsdnCard *card) cs->card_ops = &sportster_ops; if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) goto err; - return 1; - err: - hisax_release_resources(cs); return 0; + err: + sportster_release(cs); + return -EBUSY; +} + +int __init +setup_sportster(struct IsdnCard *card) +{ + char tmp[64]; + + strcpy(tmp, sportster_revision); + printk(KERN_INFO "HiSax: USR Sportster driver Rev. %s\n", + HiSax_getrev(tmp)); + + if (sportster_probe(card->cs, card) < 0) + return 0; + return 1; } diff --git a/drivers/isdn/hisax/teleint.c b/drivers/isdn/hisax/teleint.c index 88c60771dbe3b..4149475cac690 100644 --- a/drivers/isdn/hisax/teleint.c +++ b/drivers/isdn/hisax/teleint.c @@ -256,15 +256,9 @@ static struct card_ops teleint_ops = { .irq_func = teleint_interrupt, }; -int __init -setup_TeleInt(struct IsdnCard *card) +static int __init +teleint_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, TeleInt_revision); - printk(KERN_INFO "HiSax: TeleInt driver Rev. %s\n", HiSax_getrev(tmp)); - cs->hw.hfc.addr = card->para[1] & 0x3fe; cs->irq = card->para[0]; cs->hw.hfc.cirm = HFC_CIRM; @@ -284,42 +278,54 @@ setup_TeleInt(struct IsdnCard *card) byteout(cs->hw.hfc.addr, cs->hw.hfc.addr & 0xff); byteout(cs->hw.hfc.addr | 1, ((cs->hw.hfc.addr & 0x300) >> 8) | 0x54); switch (cs->irq) { - case 3: - cs->hw.hfc.cirm |= HFC_INTA; - break; - case 4: - cs->hw.hfc.cirm |= HFC_INTB; - break; - case 5: - cs->hw.hfc.cirm |= HFC_INTC; - break; - case 7: - cs->hw.hfc.cirm |= HFC_INTD; - break; - case 10: - cs->hw.hfc.cirm |= HFC_INTE; - break; - case 11: - cs->hw.hfc.cirm |= HFC_INTF; - break; - default: - printk(KERN_WARNING "TeleInt: wrong IRQ\n"); - goto err; + case 3: + cs->hw.hfc.cirm |= HFC_INTA; + break; + case 4: + cs->hw.hfc.cirm |= HFC_INTB; + break; + case 5: + cs->hw.hfc.cirm |= HFC_INTC; + break; + case 7: + cs->hw.hfc.cirm |= HFC_INTD; + break; + case 10: + cs->hw.hfc.cirm |= HFC_INTE; + break; + case 11: + cs->hw.hfc.cirm |= HFC_INTF; + break; + default: + printk(KERN_WARNING "TeleInt: wrong IRQ\n"); + goto err; } byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm); byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.ctmt); - printk(KERN_INFO - "TeleInt: defined at 0x%x IRQ %d\n", - cs->hw.hfc.addr, - cs->irq); + printk(KERN_INFO "TeleInt: defined at 0x%x IRQ %d\n", + cs->hw.hfc.addr, cs->irq); cs->card_ops = &teleint_ops; teleint_reset(cs); isac_setup(cs, &isac_ops); hfc_setup(cs, &hfc_ops); - return 1; - err: - teleint_release(cs); return 0; + + err: + hisax_release_resources(cs); + return -EBUSY; +} + +int __init +setup_TeleInt(struct IsdnCard *card) +{ + char tmp[64]; + + strcpy(tmp, TeleInt_revision); + printk(KERN_INFO "HiSax: TeleInt driver Rev. %s\n", HiSax_getrev(tmp)); + + if (teleint_probe(card->cs, card) < 0) + return 0; + return 1; } diff --git a/drivers/isdn/hisax/teles0.c b/drivers/isdn/hisax/teles0.c index b04c12bdfb339..452e56c285dfb 100644 --- a/drivers/isdn/hisax/teles0.c +++ b/drivers/isdn/hisax/teles0.c @@ -165,72 +165,95 @@ static struct card_ops teles0_ops = { .irq_func = hscxisac_irq, }; -int __init -setup_teles0(struct IsdnCard *card) +static int __init +teles0_probe(struct IsdnCardState *cs, struct IsdnCard *card) { - u8 val; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - - strcpy(tmp, teles0_revision); - printk(KERN_INFO "HiSax: Teles 8.0/16.0 driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ == ISDN_CTYPE_16_0) - cs->hw.teles0.cfg_reg = card->para[2]; - else /* 8.0 */ - cs->hw.teles0.cfg_reg = 0; - - if (card->para[1] < 0x10000) { - card->para[1] <<= 4; - printk(KERN_INFO - "Teles0: membase configured DOSish, assuming 0x%lx\n", - (unsigned long) card->para[1]); - } cs->irq = card->para[0]; - if (cs->hw.teles0.cfg_reg) { - if (!request_io(&cs->rs, cs->hw.teles0.cfg_reg, 8, "teles cfg")) - goto err; - - if ((val = bytein(cs->hw.teles0.cfg_reg + 0)) != 0x51) { - printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n", - cs->hw.teles0.cfg_reg + 0, val); - goto err; - } - if ((val = bytein(cs->hw.teles0.cfg_reg + 1)) != 0x93) { - printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n", - cs->hw.teles0.cfg_reg + 1, val); - goto err; - } - val = bytein(cs->hw.teles0.cfg_reg + 2);/* 0x1e=without AB - * 0x1f=with AB - * 0x1c 16.3 ??? - */ - if (val != 0x1e && val != 0x1f) { - printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n", - cs->hw.teles0.cfg_reg + 2, val); - goto err; - } - } /* 16.0 and 8.0 designed for IOM1 */ test_and_set_bit(HW_IOM1, &cs->HW_Flags); cs->hw.teles0.phymem = card->para[1]; - cs->hw.teles0.membase = request_mmio(&cs->rs, cs->hw.teles0.phymem, TELES_IOMEM_SIZE, "teles iomem"); + cs->hw.teles0.membase = request_mmio(&cs->rs, cs->hw.teles0.phymem, + TELES_IOMEM_SIZE, "teles iomem"); if (!cs->hw.teles0.membase) - goto err; + return -EBUSY; - printk(KERN_INFO - "HiSax: %s config irq:%d mem:0x%p cfg:0x%X\n", - CardType[cs->typ], cs->irq, - cs->hw.teles0.membase, cs->hw.teles0.cfg_reg); if (teles0_reset(cs)) { printk(KERN_WARNING "Teles0: wrong IRQ\n"); - goto err; + return -EBUSY; } cs->card_ops = &teles0_ops; if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - goto err; - return 1; + return -EBUSY; + return 0; +} + +static int __init +teles16_0_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + u8 val; + + cs->hw.teles0.cfg_reg = card->para[2]; + if (!request_io(&cs->rs, cs->hw.teles0.cfg_reg, 8, "teles cfg")) + goto err; + + if ((val = bytein(cs->hw.teles0.cfg_reg + 0)) != 0x51) { + printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n", + cs->hw.teles0.cfg_reg + 0, val); + goto err; + } + if ((val = bytein(cs->hw.teles0.cfg_reg + 1)) != 0x93) { + printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n", + cs->hw.teles0.cfg_reg + 1, val); + goto err; + } + val = bytein(cs->hw.teles0.cfg_reg + 2);/* 0x1e=without AB + * 0x1f=with AB + * 0x1c 16.3 ??? + */ + if (val != 0x1e && val != 0x1f) { + printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n", + cs->hw.teles0.cfg_reg + 2, val); + goto err; + } + if (teles0_probe(cs, card) < 0) + goto err; + + return 0; err: hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +teles8_0_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->hw.teles0.cfg_reg = 0; + + if (teles0_probe(cs, card) < 0) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +int __init +setup_teles0(struct IsdnCard *card) +{ + char tmp[64]; + + strcpy(tmp, teles0_revision); + printk(KERN_INFO "HiSax: Teles 8.0/16.0 driver Rev. %s\n", + HiSax_getrev(tmp)); + + if (card->cs->typ == ISDN_CTYPE_16_0) { + if (teles16_0_probe(card->cs, card) < 0) + return 0; + } else { + if (teles8_0_probe(card->cs, card) < 0) + return 0; + } + return 1; } diff --git a/drivers/isdn/hisax/teles3.c b/drivers/isdn/hisax/teles3.c index 08aec06d33033..ed07413798b6d 100644 --- a/drivers/isdn/hisax/teles3.c +++ b/drivers/isdn/hisax/teles3.c @@ -176,6 +176,152 @@ static struct card_ops teles3_ops = { .irq_func = hscxisac_irq, }; +static int +teles_hw_init(struct IsdnCardState *cs) +{ + + printk(KERN_INFO "HiSax: %s config irq:%d isac:0x%X cfg:0x%X\n", + CardType[cs->typ], cs->irq, + cs->hw.teles3.isac + 32, cs->hw.teles3.cfg_reg); + printk(KERN_INFO "HiSax: hscx A:0x%X hscx B:0x%X\n", + cs->hw.teles3.hscx[0] + 32, cs->hw.teles3.hscx[1] + 32); + + if (teles3_reset(cs)) { + printk(KERN_WARNING "Teles3: wrong IRQ\n"); + return -EBUSY; + } + cs->card_ops = &teles3_ops; + if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) + return -EBUSY; + return 0; +} + +static void __init +teles_setup_io(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->irq = card->para[0]; + cs->hw.teles3.isacfifo = cs->hw.teles3.isac + 0x3e; + cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e; + cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e; +} + +static int __init +telespcmcia_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->hw.teles3.cfg_reg = 0; + cs->hw.teles3.hscx[0] = card->para[1] - 0x20; + cs->hw.teles3.hscx[1] = card->para[1]; + cs->hw.teles3.isac = card->para[1] + 0x20; + teles_setup_io(cs, card); + if (!request_io(&cs->rs, cs->hw.teles3.hscx[1], 96, + "HiSax Teles PCMCIA")) + goto err; + if (teles_hw_init(cs) < 0) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +teles_request_io(struct IsdnCardState *cs) +{ + if (!request_io(&cs->rs, cs->hw.teles3.isac + 32, 32, "HiSax isac")) + return -EBUSY; + if (!request_io(&cs->rs, cs->hw.teles3.hscx[0]+32, 32, "HiSax hscx A")) + return -EBUSY; + if (!request_io(&cs->rs, cs->hw.teles3.hscx[1]+32, 32, "HiSax hscx B")) + return -EBUSY; + return 0; +} + +static int __init +teles16_3_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + u8 val; + + cs->hw.teles3.cfg_reg = card->para[1]; + switch (cs->hw.teles3.cfg_reg) { + case 0x180: + case 0x280: + case 0x380: + cs->hw.teles3.cfg_reg |= 0xc00; + break; + } + cs->hw.teles3.isac = cs->hw.teles3.cfg_reg - 0x420; + cs->hw.teles3.hscx[0] = cs->hw.teles3.cfg_reg - 0xc20; + cs->hw.teles3.hscx[1] = cs->hw.teles3.cfg_reg - 0x820; + teles_setup_io(cs, card); + if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 8, "teles3 cfg")) + goto err; + if (teles_request_io(cs) < 0) + goto err; + if ((val = bytein(cs->hw.teles3.cfg_reg + 0)) != 0x51) { + printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n", + cs->hw.teles3.cfg_reg + 0, val); + goto err; + } + if ((val = bytein(cs->hw.teles3.cfg_reg + 1)) != 0x93) { + printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n", + cs->hw.teles3.cfg_reg + 1, val); + goto err; + } + /* 0x1e without AB, 0x1f with AB, 0x1c 16.3 ???, + * 0x39 16.3 1.1, 0x38 16.3 1.3, 0x46 16.3 with AB + Video */ + val = bytein(cs->hw.teles3.cfg_reg + 2); + if (val != 0x46 && val != 0x39 && val != 0x38 && + val != 0x1c && val != 0x1e && val != 0x1f) { + printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n", + cs->hw.teles3.cfg_reg + 2, val); + goto err; + } + if (teles_hw_init(cs) < 0) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +compaq_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->hw.teles3.cfg_reg = card->para[3]; + cs->hw.teles3.isac = card->para[2] - 32; + cs->hw.teles3.hscx[0] = card->para[1] - 32; + cs->hw.teles3.hscx[1] = card->para[1]; + teles_setup_io(cs, card); + if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 1, "teles3 cfg")) + goto err; + if (teles_request_io(cs) < 0) + goto err; + if (teles_hw_init(cs) < 0) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + +static int __init +telespnp_probe(struct IsdnCardState *cs, struct IsdnCard *card) +{ + cs->hw.teles3.cfg_reg = 0; + cs->hw.teles3.isac = card->para[1] - 32; + cs->hw.teles3.hscx[0] = card->para[2] - 32; + cs->hw.teles3.hscx[1] = card->para[2]; + teles_setup_io(cs, card); + if (teles_request_io(cs) < 0) + goto err; + if (teles_hw_init(cs) < 0) + goto err; + return 0; + err: + hisax_release_resources(cs); + return -EBUSY; +} + #ifdef __ISAPNP__ static struct isapnp_device_id teles_ids[] __initdata = { { ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2110), @@ -197,16 +343,10 @@ static struct pnp_card *pnp_c __devinitdata = NULL; int __devinit setup_teles3(struct IsdnCard *card) { - u8 val; - struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, teles3_revision); printk(KERN_INFO "HiSax: Teles IO driver Rev. %s\n", HiSax_getrev(tmp)); - if ((cs->typ != ISDN_CTYPE_16_3) && (cs->typ != ISDN_CTYPE_PNP) - && (cs->typ != ISDN_CTYPE_TELESPCMCIA) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA)) - return (0); - #ifdef __ISAPNP__ if (!card->para[1] && isapnp_present()) { struct pnp_card *pnp_card; @@ -258,100 +398,18 @@ setup_teles3(struct IsdnCard *card) } } #endif - if (cs->typ == ISDN_CTYPE_16_3) { - cs->hw.teles3.cfg_reg = card->para[1]; - switch (cs->hw.teles3.cfg_reg) { - case 0x180: - case 0x280: - case 0x380: - cs->hw.teles3.cfg_reg |= 0xc00; - break; - } - cs->hw.teles3.isac = cs->hw.teles3.cfg_reg - 0x420; - cs->hw.teles3.hscx[0] = cs->hw.teles3.cfg_reg - 0xc20; - cs->hw.teles3.hscx[1] = cs->hw.teles3.cfg_reg - 0x820; - } else if (cs->typ == ISDN_CTYPE_TELESPCMCIA) { - cs->hw.teles3.cfg_reg = 0; - cs->hw.teles3.hscx[0] = card->para[1] - 0x20; - cs->hw.teles3.hscx[1] = card->para[1]; - cs->hw.teles3.isac = card->para[1] + 0x20; - } else if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { - cs->hw.teles3.cfg_reg = card->para[3]; - cs->hw.teles3.isac = card->para[2] - 32; - cs->hw.teles3.hscx[0] = card->para[1] - 32; - cs->hw.teles3.hscx[1] = card->para[1]; + if (card->cs->typ == ISDN_CTYPE_16_3) { + if (teles16_3_probe(card->cs, card) < 0) + return 0; + } else if (card->cs->typ == ISDN_CTYPE_TELESPCMCIA) { + if (telespcmcia_probe(card->cs, card) < 0) + return 0; + } else if (card->cs->typ == ISDN_CTYPE_COMPAQ_ISA) { + if (compaq_probe(card->cs, card) < 0) + return 0; } else { /* PNP */ - cs->hw.teles3.cfg_reg = 0; - cs->hw.teles3.isac = card->para[1] - 32; - cs->hw.teles3.hscx[0] = card->para[2] - 32; - cs->hw.teles3.hscx[1] = card->para[2]; - } - cs->irq = card->para[0]; - cs->hw.teles3.isacfifo = cs->hw.teles3.isac + 0x3e; - cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e; - cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e; - if (cs->typ == ISDN_CTYPE_TELESPCMCIA) { - if (!request_io(&cs->rs, cs->hw.teles3.hscx[1], 96, "HiSax Teles PCMCIA")) - goto err; - } else { - if (cs->hw.teles3.cfg_reg) { - if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { - if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 1, "teles3 cfg")) - goto err; - } else { - if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 8, "teles3 cfg")) - goto err; - } - } - if (!request_io(&cs->rs, cs->hw.teles3.isac + 32, 32, "HiSax isac")) - goto err; - if (!request_io(&cs->rs, cs->hw.teles3.hscx[0] + 32, 32, "HiSax hscx A")) - goto err; - if (!request_io(&cs->rs, cs->hw.teles3.hscx[1] + 32, 32, "HiSax hscx B")) - goto err; - } - if ((cs->hw.teles3.cfg_reg) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA)) { - if ((val = bytein(cs->hw.teles3.cfg_reg + 0)) != 0x51) { - printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n", - cs->hw.teles3.cfg_reg + 0, val); - goto err; - } - if ((val = bytein(cs->hw.teles3.cfg_reg + 1)) != 0x93) { - printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n", - cs->hw.teles3.cfg_reg + 1, val); - goto err; - } - val = bytein(cs->hw.teles3.cfg_reg + 2);/* 0x1e=without AB - * 0x1f=with AB - * 0x1c 16.3 ??? - * 0x39 16.3 1.1 - * 0x38 16.3 1.3 - * 0x46 16.3 with AB + Video (Teles-Vision) - */ - if (val != 0x46 && val != 0x39 && val != 0x38 && val != 0x1c && val != 0x1e && val != 0x1f) { - printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n", - cs->hw.teles3.cfg_reg + 2, val); - goto err; - } - } - printk(KERN_INFO - "HiSax: %s config irq:%d isac:0x%X cfg:0x%X\n", - CardType[cs->typ], cs->irq, - cs->hw.teles3.isac + 32, cs->hw.teles3.cfg_reg); - printk(KERN_INFO - "HiSax: hscx A:0x%X hscx B:0x%X\n", - cs->hw.teles3.hscx[0] + 32, cs->hw.teles3.hscx[1] + 32); - - if (teles3_reset(cs)) { - printk(KERN_WARNING "Teles3: wrong IRQ\n"); - goto err; + if (telespnp_probe(card->cs, card) < 0) + return 0; } - cs->card_ops = &teles3_ops; - if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) - goto err; return 1; - err: - hisax_release_resources(cs); - return 0; - } diff --git a/drivers/isdn/hisax/telespci.c b/drivers/isdn/hisax/telespci.c index 5e4388256cf0e..0ecd86b5ebf7c 100644 --- a/drivers/isdn/hisax/telespci.c +++ b/drivers/isdn/hisax/telespci.c @@ -231,36 +231,23 @@ static struct card_ops telespci_ops = { .irq_func = telespci_interrupt, }; -static struct pci_dev *dev_tel __initdata = NULL; - -int __init -setup_telespci(struct IsdnCard *card) +static int __init +telespci_probe(struct IsdnCardState *cs, struct pci_dev *pdev) { - struct IsdnCardState *cs = card->cs; - char tmp[64]; + int rc; -#ifdef __BIG_ENDIAN -#error "not running on big endian machines now" -#endif - strcpy(tmp, telespci_revision); - printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp)); - if ((dev_tel = pci_find_device (PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_tel))) { - if (pci_enable_device(dev_tel)) - return(0); - cs->irq = dev_tel->irq; - if (!cs->irq) { - printk(KERN_WARNING "Teles: No IRQ for PCI card found\n"); - return(0); - } - cs->hw.teles0.membase = request_mmio(&cs->rs, pci_resource_start(dev_tel, 0), 4096, "telespci"); - if (!cs->hw.teles0.membase) - goto err; - printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n", - pci_resource_start(dev_tel, 0), dev_tel->irq); - } else { - printk(KERN_WARNING "TelesPCI: No PCI card found\n"); - return(0); - } + printk(KERN_INFO "TelesPCI: defined at %#lx IRQ %d\n", + pci_resource_start(pdev, 0), pdev->irq); + + rc = -EBUSY; + if (pci_enable_device(pdev)) + goto err; + + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.teles0.membase = request_mmio(&cs->rs, pci_resource_start(pdev, 0), 4096, "telespci"); + if (!cs->hw.teles0.membase) + goto err; /* Initialize Zoran PCI controller */ writel(0x00000000, cs->hw.teles0.membase + 0x28); @@ -270,17 +257,36 @@ setup_telespci(struct IsdnCard *card) writel(0x70000000, cs->hw.teles0.membase + 0x3C); writel(0x61000000, cs->hw.teles0.membase + 0x40); /* writel(0x00800000, cs->hw.teles0.membase + 0x200); */ - printk(KERN_INFO - "HiSax: %s config irq:%d mem:%p\n", - CardType[cs->typ], cs->irq, - cs->hw.teles0.membase); - cs->irq_flags |= SA_SHIRQ; cs->card_ops = &telespci_ops; if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) goto err; - return 1; + return 0; err: hisax_release_resources(cs); + return rc; +} + +static struct pci_dev *dev_tel __initdata = NULL; + +int __init +setup_telespci(struct IsdnCard *card) +{ + char tmp[64]; + +#ifdef __BIG_ENDIAN +#error "not running on big endian machines now" +#endif + strcpy(tmp, telespci_revision); + printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", + HiSax_getrev(tmp)); + dev_tel = pci_find_device(PCI_VENDOR_ID_ZORAN, + PCI_DEVICE_ID_ZORAN_36120, dev_tel); + if (dev_tel) { + if (telespci_probe(card->cs, dev_tel) < 0) + return 0; + return 1; + } + printk(KERN_WARNING "TelesPCI: No PCI card found\n"); return 0; } diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c index 235d7e4dca6cd..cf2a4ae7cf54a 100644 --- a/drivers/isdn/hisax/w6692.c +++ b/drivers/isdn/hisax/w6692.c @@ -669,11 +669,11 @@ static int id_idx ; static struct pci_dev *dev_w6692 __initdata = NULL; static int -w6692_setup(struct IsdnCardState *cs, struct dc_hw_ops *dc_ops, - struct bc_hw_ops *bc_ops) +w6692_hw_init(struct IsdnCardState *cs) { - cs->dc_hw_ops = dc_ops; - cs->bc_hw_ops = bc_ops; + cs->card_ops = &w6692_ops; + cs->dc_hw_ops = &w6692_dc_hw_ops, + cs->bc_hw_ops = &w6692_bc_hw_ops; dc_l1_init(cs, &w6692_dc_l1_ops); cs->bc_l1_ops = &w6692_bc_l1_ops; W6692Version(cs, "W6692:"); @@ -685,14 +685,45 @@ w6692_setup(struct IsdnCardState *cs, struct dc_hw_ops *dc_ops, return 0; } +static int __init +w6692_probe(struct IsdnCardState *cs, struct pci_dev *pdev) +{ + int rc; + + printk(KERN_INFO "W6692: %s %s at %#lx IRQ %d\n", + id_list[cs->subtyp].vendor_name, id_list[cs->subtyp].card_name, + pci_resource_start(pdev, 1), pdev->irq); + + rc = -EBUSY; + if (pci_enable_device(pdev)) + goto err; + + /* USR ISDN PCI card TA need some special handling */ + if (cs->subtyp == W6692_WINBOND) { + if (pdev->subsystem_vendor == W6692_SV_USR && + pdev->subsystem_device == W6692_SD_USR) { + cs->subtyp = W6692_USR; + } + } + cs->irq = pdev->irq; + cs->irq_flags |= SA_SHIRQ; + cs->hw.w6692.iobase = pci_resource_start(pdev, 1); + + if (!request_io(&cs->rs, cs->hw.w6692.iobase, 0x100, + id_list[cs->subtyp].card_name)) + goto err; + + w6692_hw_init(cs); + return 0; + err: + hisax_release_resources(cs); + return rc; +} + int __init setup_w6692(struct IsdnCard *card) { - struct IsdnCardState *cs = card->cs; char tmp[64]; - u8 found = 0; - u8 pci_irq = 0; - u_int pci_ioaddr = 0; #ifdef __BIG_ENDIAN #error "not running on big endian machines now" @@ -704,54 +735,13 @@ setup_w6692(struct IsdnCard *card) id_list[id_idx].device_id, dev_w6692); if (dev_w6692) { - if (pci_enable_device(dev_w6692)) - continue; - cs->subtyp = id_idx; - break; + card->cs->subtyp = id_idx; + if (w6692_probe(card->cs, dev_w6692) < 0) + return 0; + return 1; } id_idx++; } - if (dev_w6692) { - found = 1; - pci_irq = dev_w6692->irq; - /* I think address 0 is allways the configuration area */ - /* and address 1 is the real IO space KKe 03.09.99 */ - pci_ioaddr = pci_resource_start(dev_w6692, 1); - /* USR ISDN PCI card TA need some special handling */ - if (cs->subtyp == W6692_WINBOND) { - if ((W6692_SV_USR == dev_w6692->subsystem_vendor) && - (W6692_SD_USR == dev_w6692->subsystem_device)) { - cs->subtyp = W6692_USR; - } - } - } - if (!found) { - printk(KERN_WARNING "W6692: No PCI card found\n"); - return (0); - } - cs->irq = pci_irq; - if (!cs->irq) { - printk(KERN_WARNING "W6692: No IRQ for PCI card found\n"); - return (0); - } - if (!pci_ioaddr) { - printk(KERN_WARNING "W6692: NO I/O Base Address found\n"); - return (0); - } - cs->hw.w6692.iobase = pci_ioaddr; - printk(KERN_INFO "Found: %s %s, I/O base: 0x%x, irq: %d\n", - id_list[cs->subtyp].vendor_name, id_list[cs->subtyp].card_name, - pci_ioaddr, pci_irq); - if (!request_io(&cs->rs, cs->hw.w6692.iobase, 0x100, id_list[cs->subtyp].card_name)) - return 0; - - printk(KERN_INFO - "HiSax: %s config irq:%d I/O:%x\n", - id_list[cs->subtyp].card_name, cs->irq, - cs->hw.w6692.iobase); - - cs->card_ops = &w6692_ops; - w6692_setup(cs, &w6692_dc_hw_ops, &w6692_bc_hw_ops); - cs->irq_flags |= SA_SHIRQ; - return (1); + printk(KERN_WARNING "W6692: No PCI card found\n"); + return 0; } -- 2.53.0