Commit 122649d2 authored by Kai Germaschewski's avatar Kai Germaschewski

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.
parent dafcf82f
...@@ -231,6 +231,51 @@ static struct card_ops asuscom_ipac_ops = { ...@@ -231,6 +231,51 @@ static struct card_ops asuscom_ipac_ops = {
.irq_func = ipac_irq, .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__ #ifdef __ISAPNP__
static struct isapnp_device_id asus_ids[] __initdata = { static struct isapnp_device_id asus_ids[] __initdata = {
{ ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688), { ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688),
...@@ -255,9 +300,6 @@ static struct pnp_card *pnp_c __devinitdata = NULL; ...@@ -255,9 +300,6 @@ static struct pnp_card *pnp_c __devinitdata = NULL;
int __init int __init
setup_asuscom(struct IsdnCard *card) setup_asuscom(struct IsdnCard *card)
{ {
int bytecnt;
struct IsdnCardState *cs = card->cs;
u8 val;
char tmp[64]; char tmp[64];
strcpy(tmp, Asuscom_revision); strcpy(tmp, Asuscom_revision);
...@@ -310,36 +352,7 @@ setup_asuscom(struct IsdnCard *card) ...@@ -310,36 +352,7 @@ setup_asuscom(struct IsdnCard *card)
} }
} }
#endif #endif
bytecnt = 8; if (asuscom_probe(card->cs, card) < 0)
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);
return 1;
err:
hisax_release_resources(cs);
return 0; return 0;
return 1;
} }
...@@ -160,16 +160,16 @@ static struct card_ops avm_a1_ops = { ...@@ -160,16 +160,16 @@ static struct card_ops avm_a1_ops = {
.irq_func = avm_a1_interrupt, .irq_func = avm_a1_interrupt,
}; };
int __init static int __init
setup_avm_a1(struct IsdnCard *card) avm_a1_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{ {
int rc;
u8 val; u8 val;
struct IsdnCardState *cs = card->cs;
char tmp[64];
strcpy(tmp, avm_revision); printk(KERN_INFO "AVM A1: defined at %#lx IRQ %lu\n",
printk(KERN_INFO "HiSax: AVM driver Rev. %s\n", HiSax_getrev(tmp)); card->para[1], card->para[0]);
rc = -EBUSY;
cs->hw.avm.cfg_reg = request_io(&cs->rs, card->para[1] + 0x1800, 8, "avm cfg"); cs->hw.avm.cfg_reg = request_io(&cs->rs, card->para[1] + 0x1800, 8, "avm cfg");
if (!cs->hw.avm.cfg_reg) goto err; if (!cs->hw.avm.cfg_reg) goto err;
cs->hw.avm.isac = request_io(&cs->rs, card->para[1] + 0x1400, 32, "HiSax isac"); 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) ...@@ -216,23 +216,24 @@ setup_avm_a1(struct IsdnCard *card)
printk(KERN_INFO "AVM A1: Byte at %x is %x\n", printk(KERN_INFO "AVM A1: Byte at %x is %x\n",
cs->hw.avm.cfg_reg, val); 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; cs->card_ops = &avm_a1_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err; goto err;
return 1; return 0;
err: err:
hisax_release_resources(cs); hisax_release_resources(cs);
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 0;
return 1;
} }
...@@ -215,20 +215,13 @@ static struct card_ops avm_a1p_ops = { ...@@ -215,20 +215,13 @@ static struct card_ops avm_a1p_ops = {
.irq_func = avm_a1p_interrupt, .irq_func = avm_a1p_interrupt,
}; };
int __devinit static int __init
setup_avm_a1_pcmcia(struct IsdnCard *card) avm_a1p_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{ {
u8 model, vers; 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->irq = card->para[0];
cs->hw.avm.cfg_reg = card->para[1];
outb(cs->hw.avm.cfg_reg+ASL1_OFFSET, ASL1_W_ENABLE_S0); outb(cs->hw.avm.cfg_reg+ASL1_OFFSET, ASL1_W_ENABLE_S0);
...@@ -248,7 +241,22 @@ setup_avm_a1_pcmcia(struct IsdnCard *card) ...@@ -248,7 +241,22 @@ setup_avm_a1_pcmcia(struct IsdnCard *card)
cs->card_ops = &avm_a1p_ops; cs->card_ops = &avm_a1p_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
return 0; 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; return 1;
} }
...@@ -497,7 +497,7 @@ static struct bc_l1_ops hdlc_l1_ops = { ...@@ -497,7 +497,7 @@ static struct bc_l1_ops hdlc_l1_ops = {
.close = close_hdlcstate, .close = close_hdlcstate,
}; };
void __init static void __init
inithdlc(struct IsdnCardState *cs) inithdlc(struct IsdnCardState *cs)
{ {
u_int val; u_int val;
...@@ -596,6 +596,82 @@ static struct card_ops avm_pci_ops = { ...@@ -596,6 +596,82 @@ static struct card_ops avm_pci_ops = {
.irq_func = avm_pcipnp_interrupt, .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; static struct pci_dev *dev_avm __initdata = NULL;
#ifdef __ISAPNP__ #ifdef __ISAPNP__
static struct pnp_card *card_avm __initdata = NULL; static struct pnp_card *card_avm __initdata = NULL;
...@@ -605,17 +681,15 @@ static struct pnp_dev *pnp_avm __initdata = NULL; ...@@ -605,17 +681,15 @@ static struct pnp_dev *pnp_avm __initdata = NULL;
int __init int __init
setup_avm_pcipnp(struct IsdnCard *card) setup_avm_pcipnp(struct IsdnCard *card)
{ {
u_int val, ver;
struct IsdnCardState *cs = card->cs;
char tmp[64]; char tmp[64];
strcpy(tmp, avm_pci_rev); strcpy(tmp, avm_pci_rev);
printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp)); printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp));
if (card->para[1]) { if (card->para[1]) {
/* old manual method */ /* old manual method */
cs->hw.avm.cfg_reg = card->para[1]; if (avm_pnp_probe(card->cs, card))
cs->irq = card->para[0]; return 0;
cs->subtyp = AVM_FRITZ_PNP; return 1;
} else { } else {
#ifdef __ISAPNP__ #ifdef __ISAPNP__
if (isapnp_present()) { if (isapnp_present()) {
...@@ -647,69 +721,24 @@ setup_avm_pcipnp(struct IsdnCard *card) ...@@ -647,69 +721,24 @@ setup_avm_pcipnp(struct IsdnCard *card)
pnp_device_detach(pnp_avm); pnp_device_detach(pnp_avm);
return(0); return(0);
} }
cs->hw.avm.cfg_reg = pnp_port_start(pnp_avm, 0); card->para[1] = pnp_port_start(pnp_avm, 0);
cs->irq = pnp_irq(pnp_avm, 0); card->para[0] = pnp_irq(pnp_avm, 0);
cs->subtyp = AVM_FRITZ_PNP; if (avm_pnp_probe(card->cs, card))
goto ready; return 0;
return 1;
} }
} }
} else {
printk(KERN_INFO "FritzPnP: no ISA PnP present\n");
} }
#endif #endif
#if CONFIG_PCI #if CONFIG_PCI
if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM, if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM,
PCI_DEVICE_ID_AVM_A1, dev_avm))) { PCI_DEVICE_ID_AVM_A1, dev_avm))) {
cs->irq = dev_avm->irq; if (avm_pci_probe(card->cs, dev_avm))
if (!cs->irq) { return 0;
printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n"); return 1;
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);
} }
cs->irq_flags |= SA_SHIRQ;
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
} }
ready: printk(KERN_WARNING "FritzPCI: No card found\n");
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);
return 0; return 0;
} }
...@@ -21,11 +21,11 @@ ...@@ -21,11 +21,11 @@
#include "bkm_ax.h" #include "bkm_ax.h"
extern const char *CardType[]; extern const char *CardType[];
// FIXME needs per card lock
static spinlock_t bkm_a4t_lock = SPIN_LOCK_UNLOCKED; static spinlock_t bkm_a4t_lock = SPIN_LOCK_UNLOCKED;
const char *bkm_a4t_revision = "$Revision: 1.13.6.6 $"; const char *bkm_a4t_revision = "$Revision: 1.13.6.6 $";
static inline u8 static inline u8
readreg(unsigned int ale, unsigned long adr, u8 off) readreg(unsigned int ale, unsigned long adr, u8 off)
{ {
...@@ -249,15 +249,57 @@ static struct card_ops bkm_a4t_ops = { ...@@ -249,15 +249,57 @@ static struct card_ops bkm_a4t_ops = {
.irq_func = bkm_interrupt, .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; static struct pci_dev *dev_a4t __initdata = NULL;
int __init int __init
setup_bkm_a4t(struct IsdnCard *card) setup_bkm_a4t(struct IsdnCard *card)
{ {
struct IsdnCardState *cs = card->cs;
char tmp[64]; char tmp[64];
u_int pci_memaddr = 0, found = 0;
I20_REGISTER_FILE *pI20_Regs;
strcpy(tmp, bkm_a4t_revision); strcpy(tmp, bkm_a4t_revision);
printk(KERN_INFO "HiSax: T-Berkom driver Rev. %s\n", HiSax_getrev(tmp)); printk(KERN_INFO "HiSax: T-Berkom driver Rev. %s\n", HiSax_getrev(tmp));
...@@ -268,49 +310,13 @@ setup_bkm_a4t(struct IsdnCard *card) ...@@ -268,49 +310,13 @@ setup_bkm_a4t(struct IsdnCard *card)
sub_vendor = dev_a4t->subsystem_vendor; sub_vendor = dev_a4t->subsystem_vendor;
sub_sys = dev_a4t->subsystem_device; sub_sys = dev_a4t->subsystem_device;
if ((sub_sys == PCI_DEVICE_ID_BERKOM_A4T) && (sub_vendor == PCI_VENDOR_ID_BERKOM)) { if (sub_sys == PCI_DEVICE_ID_BERKOM_A4T &&
if (pci_enable_device(dev_a4t)) sub_vendor == PCI_VENDOR_ID_BERKOM) {
return(0); if (bkm_a4t_probe(card->cs, dev_a4t))
found = 1; return 0;
pci_memaddr = pci_resource_start(dev_a4t, 0); return 1;
cs->irq = dev_a4t->irq;
break;
} }
} }
if (!found) {
printk(KERN_WARNING "HiSax: %s: Card not found\n", CardType[card->typ]); printk(KERN_WARNING "HiSax: %s: Card not found\n", CardType[card->typ]);
return (0); 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;
} }
...@@ -362,7 +362,7 @@ diva_ipacx_pci_irq(int intno, void *dev_id, struct pt_regs *regs) ...@@ -362,7 +362,7 @@ diva_ipacx_pci_irq(int intno, void *dev_id, struct pt_regs *regs)
static void static void
diva_release(struct IsdnCardState *cs) diva_release(struct IsdnCardState *cs)
{ {
del_timer(&cs->hw.diva.tl); del_timer_sync(&cs->hw.diva.tl);
if (cs->hw.diva.cfg_reg) if (cs->hw.diva.cfg_reg)
byteout(cs->hw.diva.ctrl, 0); /* LED off, Reset */ byteout(cs->hw.diva.ctrl, 0); /* LED off, Reset */
...@@ -515,6 +515,162 @@ static struct card_ops diva_ipacx_pci_ops = { ...@@ -515,6 +515,162 @@ static struct card_ops diva_ipacx_pci_ops = {
.irq_func = diva_ipacx_pci_irq, .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 __initdata = NULL;
static struct pci_dev *dev_diva_u __initdata = NULL; static struct pci_dev *dev_diva_u __initdata = NULL;
static struct pci_dev *dev_diva201 __initdata = NULL; static struct pci_dev *dev_diva201 __initdata = NULL;
...@@ -545,40 +701,19 @@ static struct isapnp_device_id *pdev = &diva_ids[0]; ...@@ -545,40 +701,19 @@ static struct isapnp_device_id *pdev = &diva_ids[0];
static struct pnp_card *pnp_c __devinitdata = NULL; static struct pnp_card *pnp_c __devinitdata = NULL;
#endif #endif
int __init int __init
setup_diva(struct IsdnCard *card) setup_diva(struct IsdnCard *card)
{ {
int bytecnt = 8;
u8 val;
struct IsdnCardState *cs = card->cs;
char tmp[64]; char tmp[64];
strcpy(tmp, Diva_revision); strcpy(tmp, Diva_revision);
printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp)); printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp));
if (card->para[1]) { if (card->para[1]) {
cs->hw.diva.ctrl_reg = 0; if (diva_isa_probe(card->cs, card) < 0)
cs->hw.diva.cfg_reg = card->para[1]; return 0;
val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR, return 1;
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 {
#ifdef __ISAPNP__ #ifdef __ISAPNP__
if (isapnp_present()) { if (isapnp_present()) {
struct pnp_card *pb; struct pnp_card *pb;
...@@ -586,8 +721,7 @@ setup_diva(struct IsdnCard *card) ...@@ -586,8 +721,7 @@ setup_diva(struct IsdnCard *card)
while(pdev->card_vendor) { while(pdev->card_vendor) {
if ((pb = pnp_find_card(pdev->card_vendor, if ((pb = pnp_find_card(pdev->card_vendor,
pdev->card_device, pdev->card_device, pnp_c))) {
pnp_c))) {
pnp_c = pb; pnp_c = pb;
pd = NULL; pd = NULL;
if ((pd = pnp_find_dev(pnp_c, if ((pd = pnp_find_dev(pnp_c,
...@@ -613,33 +747,14 @@ setup_diva(struct IsdnCard *card) ...@@ -613,33 +747,14 @@ setup_diva(struct IsdnCard *card)
} }
card->para[1] = pnp_port_start(pd, 0); card->para[1] = pnp_port_start(pd, 0);
card->para[0] = pnp_irq(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)) { if (pdev->function == ISAPNP_FUNCTION(0xA1)) {
cs->subtyp = DIVA_IPAC_ISA; if (diva_ipac_isa_probe(cs->card, cs))
cs->hw.diva.ctrl = 0; return 0;
cs->hw.diva.isac = return 1;
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 { } else {
cs->subtyp = DIVA_ISA; if (diva_isac_isa_probe(cs->card, cs))
cs->hw.diva.ctrl = return 0;
card->para[1] + DIVA_ISA_CTRL; return 1;
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;
} else { } else {
printk(KERN_ERR "Diva PnP: PnP error card found, no device\n"); printk(KERN_ERR "Diva PnP: PnP error card found, no device\n");
return(0); return(0);
...@@ -652,111 +767,29 @@ setup_diva(struct IsdnCard *card) ...@@ -652,111 +767,29 @@ setup_diva(struct IsdnCard *card)
printk(KERN_INFO "Diva PnP: no ISAPnP card found\n"); printk(KERN_INFO "Diva PnP: no ISAPnP card found\n");
} }
} }
}
#endif #endif
#if CONFIG_PCI #if CONFIG_PCI
cs->subtyp = 0;
if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON, if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON,
PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) { PCI_DEVICE_ID_EICON_DIVA20,
if (pci_enable_device(dev_diva)) dev_diva))) {
return(0); if (diva_pci_probe(card->cs, dev_diva))
cs->subtyp = DIVA_PCI; return 0;
cs->irq = dev_diva->irq; return 1;
cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2);
} else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON, } else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON,
PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) { PCI_DEVICE_ID_EICON_DIVA20_U,
if (pci_enable_device(dev_diva_u)) dev_diva_u))) {
return(0); if (diva_pci_probe(card->cs, dev_diva_u))
cs->subtyp = DIVA_PCI; return 0;
cs->irq = dev_diva_u->irq; return 1;
cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2);
} else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON, } else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON,
PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) { PCI_DEVICE_ID_EICON_DIVA201,
if (pci_enable_device(dev_diva201)) dev_diva201))) {
return(0); if (diva_ipac_pci_probe(card->cs, dev_diva201))
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"))
return 0; return 0;
}
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; return 1;
err: }
diva_release(cs); printk(KERN_WARNING "Diva: No PCI card found\n");
#endif /* CONFIG_PCI */
return 0; return 0;
} }
...@@ -690,7 +690,47 @@ static struct card_ops elsa_ipac_ops = { ...@@ -690,7 +690,47 @@ static struct card_ops elsa_ipac_ops = {
.irq_func = elsa_interrupt_ipac, .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) 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, 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) ...@@ -699,15 +739,13 @@ probe_elsa_adr(unsigned int adr, int typ)
/* In case of the elsa pcmcia card, this region is in use, /* 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 reserved for us by the card manager. So we do not check it
here, it would fail. */ here, it would fail. */
if (typ != ISDN_CTYPE_ELSA_PCMCIA && check_region(adr, 8)) { if (typ != ISDN_CTYPE_ELSA_PCMCIA && !request_region(adr, 8, "elsa")) {
printk(KERN_WARNING printk(KERN_WARNING "Elsa: probing port 0x%x: in use\n", adr);
"Elsa: Probing Port 0x%x: already in use\n", return 0;
adr);
return (0);
} }
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
in1 = inb(adr + ELSA_CONFIG); /* 'toggelt' bei */ in1 = inb(adr + ELSA_CONFIG); /* 'toggels' at */
in2 = inb(adr + ELSA_CONFIG); /* jedem Zugriff */ in2 = inb(adr + ELSA_CONFIG); /* each access */
p16_1 += 0x04 & in1; p16_1 += 0x04 & in1;
p16_2 += 0x04 & in2; p16_2 += 0x04 & in2;
p8_1 += 0x02 & in1; p8_1 += 0x02 & in1;
...@@ -717,6 +755,7 @@ probe_elsa_adr(unsigned int adr, int typ) ...@@ -717,6 +755,7 @@ probe_elsa_adr(unsigned int adr, int typ)
pfp_1 += 0x40 & in1; pfp_1 += 0x40 & in1;
pfp_2 += 0x40 & in2; pfp_2 += 0x40 & in2;
} }
release_region(adr, 8);
printk(KERN_INFO "Elsa: Probing IO 0x%x", adr); printk(KERN_INFO "Elsa: Probing IO 0x%x", adr);
if (65 == ++p16_1 * ++p16_2) { if (65 == ++p16_1 * ++p16_2) {
printk(" PCC-16/PCF found\n"); printk(" PCC-16/PCF found\n");
...@@ -736,66 +775,33 @@ probe_elsa_adr(unsigned int adr, int typ) ...@@ -736,66 +775,33 @@ probe_elsa_adr(unsigned int adr, int typ)
} }
} }
static unsigned int static int __init
probe_elsa(struct IsdnCardState *cs) 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)))
break;
}
return (CARD_portlist[i]);
}
static struct pci_dev *dev_qs1000 __devinitdata = NULL;
static struct pci_dev *dev_qs3000 __devinitdata = NULL;
#ifdef __ISAPNP__
static struct isapnp_device_id elsa_ids[] __initdata = {
{ ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0133),
ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0133),
(unsigned long) "Elsa QS1000" },
{ ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0134),
ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0134),
(unsigned long) "Elsa QS3000" },
{ 0, }
};
static struct isapnp_device_id *pdev = &elsa_ids[0];
static struct pnp_card *pnp_c __devinitdata = NULL;
#endif
int __devinit
setup_elsa(struct IsdnCard *card)
{ {
int bytecnt; u8 val;
u8 val, pci_rev; int i, bytecnt = 8;
struct IsdnCardState *cs = card->cs; unsigned int CARD_portlist[] = {0x160, 0x170, 0x260, 0x360, 0};
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]; cs->hw.elsa.base = card->para[0];
printk(KERN_INFO "Elsa: Microlink IO probing\n"); printk(KERN_INFO "Elsa: Microlink IO probing\n");
if (cs->hw.elsa.base) { if (cs->hw.elsa.base) {
if (!(cs->subtyp = probe_elsa_adr(cs->hw.elsa.base, cs->subtyp = probe_elsa_adr(cs->hw.elsa.base, cs->typ);
cs->typ))) { if (!cs->subtyp) {
printk(KERN_WARNING printk(KERN_WARNING "Elsa: no Microlink at %#lx\n",
"Elsa: no Elsa Microlink at %#lx\n",
cs->hw.elsa.base); cs->hw.elsa.base);
return (0); goto err;
} }
} else } else {
cs->hw.elsa.base = probe_elsa(cs); for (i = 0; CARD_portlist[i]; i++) {
if (cs->hw.elsa.base) { 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.cfg = cs->hw.elsa.base + ELSA_CONFIG;
cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL; cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL;
cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE; cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE;
...@@ -806,16 +812,13 @@ setup_elsa(struct IsdnCard *card) ...@@ -806,16 +812,13 @@ setup_elsa(struct IsdnCard *card)
cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER; cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER;
val = bytein(cs->hw.elsa.cfg); val = bytein(cs->hw.elsa.cfg);
if (cs->subtyp == ELSA_PC) { if (cs->subtyp == ELSA_PC) {
const u8 CARD_IrqTab[8] = const u8 CARD_IrqTab[8] = {7, 3, 5, 9, 0, 0, 0, 0};
{7, 3, 5, 9, 0, 0, 0, 0};
cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PC) >> 2]; cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PC) >> 2];
} else if (cs->subtyp == ELSA_PCC8) { } else if (cs->subtyp == ELSA_PCC8) {
const u8 CARD_IrqTab[8] = const u8 CARD_IrqTab[8] = {7, 3, 5, 9, 0, 0, 0, 0};
{7, 3, 5, 9, 0, 0, 0, 0};
cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PCC8) >> 4]; cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PCC8) >> 4];
} else { } else {
const u8 CARD_IrqTab[8] = const u8 CARD_IrqTab[8] = {15, 10, 15, 3, 11, 5, 11, 9};
{15, 10, 15, 3, 11, 5, 11, 9};
cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX) >> 3]; cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX) >> 3];
} }
val = bytein(cs->hw.elsa.ale) & ELSA_HW_RELEASE; val = bytein(cs->hw.elsa.ale) & ELSA_HW_RELEASE;
...@@ -826,23 +829,206 @@ setup_elsa(struct IsdnCard *card) ...@@ -826,23 +829,206 @@ setup_elsa(struct IsdnCard *card)
val ^= 1; val ^= 1;
if ((cs->subtyp == ELSA_PCFPRO) && (val = 'G')) if ((cs->subtyp == ELSA_PCFPRO) && (val = 'G'))
val = 'C'; val = 'C';
printk(KERN_INFO printk(KERN_INFO "Elsa: %s found at %#lx Rev.:%c IRQ %d\n",
"Elsa: %s found at %#lx Rev.:%c IRQ %d\n", Elsa_Types[cs->subtyp], cs->hw.elsa.base, val, cs->irq);
Elsa_Types[cs->subtyp],
cs->hw.elsa.base,
val, cs->irq);
val = bytein(cs->hw.elsa.ale) & ELSA_S0_POWER_BAD; val = bytein(cs->hw.elsa.ale) & ELSA_S0_POWER_BAD;
if (val) { if (val) {
printk(KERN_WARNING printk(KERN_WARNING "Elsa: Microlink S0 bus power bad\n");
"Elsa: Microlink S0 bus power bad\n");
cs->hw.elsa.status |= ELSA_BAD_PWR; cs->hw.elsa.status |= ELSA_BAD_PWR;
} }
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 { } else {
printk(KERN_WARNING cs->subtyp = ELSA_PCMCIA;
"No Elsa Microlink found\n"); cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE_PCM;
return (0); 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;
} }
} else if (cs->typ == ISDN_CTYPE_ELSA_PNP) { 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;
static struct pci_dev *dev_qs3000 __devinitdata = NULL;
#ifdef __ISAPNP__
static struct isapnp_device_id elsa_ids[] __initdata = {
{ ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0133),
ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0133),
(unsigned long) "Elsa QS1000" },
{ ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0134),
ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0134),
(unsigned long) "Elsa QS3000" },
{ 0, }
};
static struct isapnp_device_id *pdev = &elsa_ids[0];
static struct pnp_card *pnp_c __devinitdata = NULL;
#endif
int __devinit
setup_elsa(struct IsdnCard *card)
{
char tmp[64];
strcpy(tmp, Elsa_revision);
printk(KERN_INFO "HiSax: Elsa driver Rev. %s\n", HiSax_getrev(tmp));
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__ #ifdef __ISAPNP__
if (!card->para[1] && isapnp_present()) { if (!card->para[1] && isapnp_present()) {
struct pnp_card *pb; struct pnp_card *pb;
...@@ -878,10 +1064,15 @@ setup_elsa(struct IsdnCard *card) ...@@ -878,10 +1064,15 @@ setup_elsa(struct IsdnCard *card)
} }
card->para[1] = pnp_port_start(pd, 0); card->para[1] = pnp_port_start(pd, 0);
card->para[0] = pnp_irq(pd, 0); card->para[0] = pnp_irq(pd, 0);
if (pdev->function == ISAPNP_FUNCTION(0x133)) if (pdev->function == ISAPNP_FUNCTION(0x133)) {
cs->subtyp = ELSA_QS1000; if (elsa_qs1000_probe(card->cs, card))
else return 0;
cs->subtyp = ELSA_QS3000; return 1;
} else {
if (elsa_qs3000_probe(card->cs, card))
return 0;
return 1;
}
break; break;
} else { } else {
printk(KERN_ERR "Elsa PnP: PnP error card found, no device\n"); printk(KERN_ERR "Elsa PnP: PnP error card found, no device\n");
...@@ -897,184 +1088,33 @@ setup_elsa(struct IsdnCard *card) ...@@ -897,184 +1088,33 @@ setup_elsa(struct IsdnCard *card)
} }
} }
#endif #endif
if (card->para[1] && card->para[0]) { if (elsa_qs1000_probe(card->cs, card))
cs->hw.elsa.base = card->para[1]; return 0;
cs->irq = card->para[0]; return 1;
if (!cs->subtyp)
cs->subtyp = ELSA_QS1000; } else if (card->typ == ISDN_CTYPE_ELSA_PCMCIA) {
} else { if (elsa_pcmcia_probe(card->cs, card))
printk(KERN_ERR "Elsa PnP: no parameter\n"); return 0;
} return 1;
cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG; } else if (card->typ == ISDN_CTYPE_ELSA_PCI) {
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 CONFIG_PCI #if CONFIG_PCI
cs->subtyp = 0;
if ((dev_qs1000 = pci_find_device(PCI_VENDOR_ID_ELSA, if ((dev_qs1000 = pci_find_device(PCI_VENDOR_ID_ELSA,
PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) { PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) {
if (pci_enable_device(dev_qs1000)) if (elsa_qs_pci_probe(card->cs, dev_qs1000,
return(0); ELSA_QS1000PCI))
cs->subtyp = ELSA_QS1000PCI; return 0;
cs->irq = dev_qs1000->irq; return 1;
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);
} else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ID_ELSA, } else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ID_ELSA,
PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) { PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) {
if (pci_enable_device(dev_qs3000)) if (elsa_qs_pci_probe(card->cs, dev_qs3000,
return(0); ELSA_QS3000PCI))
cs->subtyp = ELSA_QS3000PCI; return 0;
cs->irq = dev_qs3000->irq; return 1;
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);
} else { } else {
printk(KERN_WARNING "Elsa: No PCI card found\n"); printk(KERN_WARNING "Elsa: No PCI card found\n");
return(0); return 0;
}
if (!cs->irq) {
printk(KERN_WARNING "Elsa: No IRQ for PCI card found\n");
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 */ #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; return 0;
} }
...@@ -263,47 +263,17 @@ static struct card_ops enpci_ops = { ...@@ -263,47 +263,17 @@ static struct card_ops enpci_ops = {
.irq_func = enpci_interrupt, .irq_func = enpci_interrupt,
}; };
static struct pci_dev *dev_netjet __initdata = NULL; static int __init
enpci_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
/* called by config.c */
int __init
setup_enternow_pci(struct IsdnCard *card)
{ {
struct IsdnCardState *cs = card->cs; if (pci_enable_device(pdev))
char tmp[64]; goto err;
#ifdef __BIG_ENDIAN
#error "not running on big endian machines now"
#endif
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 ( ;; ) { cs->irq = pdev->irq;
if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, cs->irq_flags |= SA_SHIRQ;
PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { cs->hw.njet.base = pci_resource_start(pdev, 0);
if (pci_enable_device(dev_netjet)) if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "Fn_ISDN"))
return(0); goto err;
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);
}
cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA; cs->hw.njet.auxa = cs->hw.njet.base + NETJET_AUXDATA;
cs->hw.njet.isac = cs->hw.njet.base + 0xC0; // Fenster zum AMD cs->hw.njet.isac = cs->hw.njet.base + 0xC0; // Fenster zum AMD
...@@ -329,21 +299,53 @@ setup_enternow_pci(struct IsdnCard *card) ...@@ -329,21 +299,53 @@ setup_enternow_pci(struct IsdnCard *card)
OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ); OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ);
OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd); OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd);
break;
}
printk(KERN_INFO printk(KERN_INFO
"enter:now PCI: PCI card configured at 0x%lx IRQ %d\n", "enter:now PCI: PCI card configured at 0x%lx IRQ %d\n",
cs->hw.njet.base, cs->irq); cs->hw.njet.base, cs->irq);
if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "Fn_ISDN"))
return 0;
reset_enpci(cs); reset_enpci(cs);
cs->hw.njet.last_is0 = 0; cs->hw.njet.last_is0 = 0;
cs->hw.njet.bc_activate = enpci_bc_activate; cs->hw.njet.bc_activate = enpci_bc_activate;
cs->hw.njet.bc_deactivate = enpci_bc_deactivate; cs->hw.njet.bc_deactivate = enpci_bc_deactivate;
amd7930_setup(cs, &amd7930_ops, &enpci_setIrqMask); amd7930_setup(cs, &amd7930_ops, &enpci_setIrqMask);
cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &enpci_ops; 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)
{
char tmp[64];
#ifdef __BIG_ENDIAN
#error "not running on big endian machines now"
#endif
strcpy(tmp, enternow_pci_rev);
printk(KERN_INFO "HiSax: Formula-n Europe AG enter:now ISDN PCI 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) {
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;
}
if (enpci_probe(card->cs, dev_netjet))
return 1; return 1;
return 0;
}
printk(KERN_WARNING "enter:now PCI: No PCI card found\n");
return 0;
} }
...@@ -294,60 +294,6 @@ gazel_init(struct IsdnCardState *cs) ...@@ -294,60 +294,6 @@ gazel_init(struct IsdnCardState *cs)
inithscxisac(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 = { static struct card_ops r647_ops = {
.init = gazel_init, .init = gazel_init,
.reset = r647_reset, .reset = r647_reset,
...@@ -377,131 +323,134 @@ static struct card_ops r753_ops = { ...@@ -377,131 +323,134 @@ static struct card_ops r753_ops = {
}; };
static int __init 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"); int i, base;
// 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;
cs->hw.gazel.cfg_reg = card->para[1] + 0xC000; cs->subtyp = R647;
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->irq = card->para[0];
cs->hw.gazel.isacfifo = cs->hw.gazel.isac; cs->hw.gazel.cfg_reg = card->para[1] + 0xC000;
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"); printk(KERN_INFO "Gazel: Card ISA R647/R648 found\n");
cs->dc.isac.adf2 = 0x87; cs->dc.isac.adf2 = 0x87;
printk(KERN_INFO printk(KERN_INFO "Gazel: config irq:%d isac:0x%X cfg:0x%X\n",
"Gazel: config irq:%d isac:0x%X cfg:0x%X\n",
cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg); cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg);
printk(KERN_INFO printk(KERN_INFO
"Gazel: hscx A:0x%X hscx B:0x%X\n", "Gazel: hscx A:0x%X hscx B:0x%X\n",
cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]); cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]);
return r647_reserve_regions(cs); cs->hw.gazel.isac = card->para[1] + 0x8000;
case R742: cs->hw.gazel.hscx[0] = card->para[1];
printk(KERN_INFO "Gazel: Card ISA R742 found\n"); cs->hw.gazel.hscx[1] = card->para[1] + 0x4000;
printk(KERN_INFO cs->hw.gazel.isacfifo = cs->hw.gazel.isac;
"Gazel: config irq:%d ipac:0x%X\n", cs->hw.gazel.hscxfifo[0] = cs->hw.gazel.hscx[0];
cs->irq, cs->hw.gazel.ipac); cs->hw.gazel.hscxfifo[1] = cs->hw.gazel.hscx[1];
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; return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
} }
static struct pci_dev *dev_tel __initdata = NULL;
static int __init static int __init
setup_gazelpci(struct IsdnCardState *cs) gazel742_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{ {
u_int pci_ioaddr0 = 0, pci_ioaddr1 = 0; cs->subtyp = R742;
u8 pci_irq = 0, found; cs->irq = card->para[0];
u_int nbseek, seekcard; cs->hw.gazel.cfg_reg = card->para[1] + 0xC000;
u8 pci_rev;
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 (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel"))
if (!pci_present()) { goto err;
printk(KERN_WARNING "Gazel: No PCI bus present\n");
return 1; cs->card_ops = &r742_ops;
} if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops))
seekcard = PCI_DEVICE_ID_PLX_R685; goto err;
for (nbseek = 0; nbseek < 3; nbseek++) {
if ((dev_tel = pci_find_device(PCI_VENDOR_ID_PLX, seekcard, dev_tel))) { cs->card_ops->reset(cs);
if (pci_enable_device(dev_tel)) return 0;
return 1; err:
pci_irq = dev_tel->irq; hisax_release_resources(cs);
pci_ioaddr0 = pci_resource_start(dev_tel, 1); return -EBUSY;
pci_ioaddr1 = pci_resource_start(dev_tel, 2); }
found = 1;
} static int __init
if (found) gazel685_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
break; {
else { if (pci_enable_device(pdev))
switch (seekcard) { goto err;
case PCI_DEVICE_ID_PLX_R685:
seekcard = PCI_DEVICE_ID_PLX_R753; cs->subtyp = R685;
break; cs->irq = pdev->irq;
case PCI_DEVICE_ID_PLX_R753: cs->irq_flags |= SA_SHIRQ;
seekcard = PCI_DEVICE_ID_PLX_DJINN_ITOO; cs->hw.gazel.cfg_reg = pci_resource_start(pdev, 1);
break; 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;
}
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; cs->hw.gazel.isacfifo = cs->hw.gazel.isac;
cs->hw.gazel.hscxfifo[0] = cs->hw.gazel.hscx[0]; cs->hw.gazel.hscxfifo[0] = cs->hw.gazel.hscx[0];
cs->hw.gazel.hscxfifo[1] = cs->hw.gazel.hscx[1]; cs->hw.gazel.hscxfifo[1] = cs->hw.gazel.hscx[1];
cs->irq = pci_irq; cs->dc.isac.adf2 = 0x87;
cs->irq_flags |= SA_SHIRQ;
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;
switch (seekcard) {
case PCI_DEVICE_ID_PLX_R685:
printk(KERN_INFO "Gazel: Card PCI R685 found\n"); printk(KERN_INFO "Gazel: Card PCI R685 found\n");
cs->subtyp = R685; printk(KERN_INFO "Gazel: config irq:%d isac:0x%X cfg:0x%X\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); cs->irq, cs->hw.gazel.isac, cs->hw.gazel.cfg_reg);
printk(KERN_INFO printk(KERN_INFO "Gazel: hscx A:0x%X hscx B:0x%X\n",
"Gazel: hscx A:0x%X hscx B:0x%X\n",
cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]); cs->hw.gazel.hscx[0], cs->hw.gazel.hscx[1]);
return r685_reserve_regions(cs);
case PCI_DEVICE_ID_PLX_R753: cs->card_ops = &r685_ops;
case PCI_DEVICE_ID_PLX_DJINN_ITOO: if (hscxisac_setup(cs, &r685_isac_ops, &r685_hscx_ops))
printk(KERN_INFO "Gazel: Card PCI R753 found\n"); 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->subtyp = R753;
printk(KERN_INFO cs->irq = pdev->irq;
"Gazel: config irq:%d ipac:0x%X cfg:0x%X\n", 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); cs->irq, cs->hw.gazel.ipac, cs->hw.gazel.cfg_reg);
/* /*
* Erratum for PLX9050, revision 1: * Erratum for PLX9050, revision 1:
...@@ -509,62 +458,78 @@ setup_gazelpci(struct IsdnCardState *cs) ...@@ -509,62 +458,78 @@ setup_gazelpci(struct IsdnCardState *cs)
* can not be read (write is okay) * can not be read (write is okay)
*/ */
if (cs->hw.gazel.cfg_reg & 0x80) { if (cs->hw.gazel.cfg_reg & 0x80) {
pci_read_config_byte(dev_tel, PCI_REVISION_ID, &pci_rev); pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev);
if (pci_rev == 1) { if (pci_rev == 1) {
printk(KERN_INFO "Gazel: PLX9050 rev1 workaround activated\n"); printk(KERN_INFO "Gazel: PLX9050 rev1 workaround "
set_bit(FLG_BUGGY_PLX9050, &cs->HW_Flags); "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; 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 int __init
setup_gazel(struct IsdnCard *card) setup_gazel(struct IsdnCard *card)
{ {
struct IsdnCardState *cs = card->cs;
char tmp[64]; char tmp[64];
strcpy(tmp, gazel_revision); strcpy(tmp, gazel_revision);
printk(KERN_INFO "Gazel: Driver Revision %s\n", HiSax_getrev(tmp)); printk(KERN_INFO "Gazel: Driver Revision %s\n", HiSax_getrev(tmp));
if (card->para[0]) { if (card->para[0]) {
if (setup_gazelisa(card, cs)) printk(KERN_INFO "Gazel: ISA card automatic recognition\n");
return (0); // 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 { } else {
if (setup_gazelpci(cs)) if (gazel647_probe(card->cs, card))
return (0); return 0;
}
return 1;
} }
switch (cs->subtyp) { for (;;) {
case R647: dev_tel = pci_find_device(PCI_VENDOR_ID_PLX, dev_id, dev_tel);
case R685: if (dev_tel) {
if (cs->subtyp == R647) { switch (dev_id) {
cs->card_ops = &r647_ops; case PCI_DEVICE_ID_PLX_R685:
if (hscxisac_setup(cs, &r647_isac_ops, &r647_hscx_ops)) if (gazel685_probe(card->cs, dev_tel))
goto err; return 0;
} else { return 1;
cs->card_ops = &r685_ops; case PCI_DEVICE_ID_PLX_R753:
if (hscxisac_setup(cs, &r685_isac_ops, &r685_hscx_ops)) case PCI_DEVICE_ID_PLX_DJINN_ITOO:
goto err; 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;
} }
if (ipac_setup(cs, &ipac_dc_ops, &ipac_bc_ops)) switch (dev_id) {
goto err; case PCI_DEVICE_ID_PLX_R685:
cs->card_ops->reset(cs); dev_id = PCI_DEVICE_ID_PLX_R753;
case PCI_DEVICE_ID_PLX_R753:
dev_id = PCI_DEVICE_ID_PLX_DJINN_ITOO;
default:
break; break;
} }
return 1; }
err: printk(KERN_WARNING "Gazel: No PCI card found\n");
hisax_release_resources(cs);
return 0; return 0;
} }
...@@ -1382,6 +1382,62 @@ static struct card_ops hfcpci_ops = { ...@@ -1382,6 +1382,62 @@ static struct card_ops hfcpci_ops = {
}; };
static int __init
niccy_pci_probe(struct IsdnCardState *cs, struct pci_dev *pdev, int i)
{
int rc;
rc = -EBUSY;
if (pci_enable_device(pdev))
goto err;
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;
/* Allocate memory for FIFOS */
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);
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;
Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);
Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2);
/* At this point the needed PCI config is done */
/* fifos are still not enabled */
init_timer(&cs->hw.hfcpci.timer);
cs->hw.hfcpci.timer.function = (void *) hfcpci_Timer;
cs->hw.hfcpci.timer.data = (long) cs;
hfcpci_reset(cs);
cs->auxcmd = &hfcpci_auxcmd;
cs->card_ops = &hfcpci_ops;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
/* this variable is used as card index when more than one cards are present */ /* this variable is used as card index when more than one cards are present */
static struct pci_dev *dev_hfcpci __initdata = NULL; static struct pci_dev *dev_hfcpci __initdata = NULL;
...@@ -1399,74 +1455,16 @@ setup_hfcpci(struct IsdnCard *card) ...@@ -1399,74 +1455,16 @@ setup_hfcpci(struct IsdnCard *card)
cs->dc.hfcpci.ph_state = 0; cs->dc.hfcpci.ph_state = 0;
cs->hw.hfcpci.fifo = 255; cs->hw.hfcpci.fifo = 255;
i = 0; for (i = 0; id_list[i].vendor_id; i++) {
while (id_list[i].vendor_id) {
tmp_hfcpci = pci_find_device(id_list[i].vendor_id, tmp_hfcpci = pci_find_device(id_list[i].vendor_id,
id_list[i].device_id, id_list[i].device_id,
dev_hfcpci); dev_hfcpci);
i++; if (!tmp_hfcpci)
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; continue;
else
break;
}
}
if (tmp_hfcpci) { if (niccy_pci_probe(card->cs, tmp_hfcpci, i) < 0)
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; return 0;
}
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("ChipID: %x\n", Read_hfc(cs, HFCPCI_CHIP_ID));
cs->hw.hfcpci.int_m2 = 0; /* disable alle interrupts */
cs->hw.hfcpci.int_m1 = 0;
Write_hfc(cs, HFCPCI_INT_M1, cs->hw.hfcpci.int_m1);
Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2);
/* At this point the needed PCI config is done */
/* fifos are still not enabled */
cs->irq_flags |= SA_SHIRQ;
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 1;
err: }
hisax_release_resources(cs);
return 0; return 0;
} }
...@@ -1159,6 +1159,74 @@ static struct card_ops hfcsx_ops = { ...@@ -1159,6 +1159,74 @@ static struct card_ops hfcsx_ops = {
.irq_func = hfcsx_interrupt, .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__ #ifdef __ISAPNP__
static struct isapnp_device_id hfc_ids[] __initdata = { static struct isapnp_device_id hfc_ids[] __initdata = {
{ ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620), { ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620),
...@@ -1174,7 +1242,6 @@ static struct pnp_card *pnp_c __devinitdata = NULL; ...@@ -1174,7 +1242,6 @@ static struct pnp_card *pnp_c __devinitdata = NULL;
int __devinit int __devinit
setup_hfcsx(struct IsdnCard *card) setup_hfcsx(struct IsdnCard *card)
{ {
struct IsdnCardState *cs = card->cs;
char tmp[64]; char tmp[64];
strcpy(tmp, hfcsx_revision); strcpy(tmp, hfcsx_revision);
...@@ -1227,62 +1294,7 @@ setup_hfcsx(struct IsdnCard *card) ...@@ -1227,62 +1294,7 @@ setup_hfcsx(struct IsdnCard *card)
} }
} }
#endif #endif
cs->hw.hfcsx.base = card->para[1] & 0xfffe; if (hfcsx_probe(card->cs, card) < 0)
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"))
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; 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; return 1;
} }
...@@ -133,6 +133,50 @@ static struct card_ops hfcs_ops = { ...@@ -133,6 +133,50 @@ static struct card_ops hfcs_ops = {
.irq_func = hfcs_interrupt, .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__ #ifdef __ISAPNP__
static struct isapnp_device_id hfc_ids[] __initdata = { static struct isapnp_device_id hfc_ids[] __initdata = {
{ ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114), { ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114),
...@@ -166,7 +210,6 @@ static struct pnp_card *pnp_c __devinitdata = NULL; ...@@ -166,7 +210,6 @@ static struct pnp_card *pnp_c __devinitdata = NULL;
int __init int __init
setup_hfcs(struct IsdnCard *card) setup_hfcs(struct IsdnCard *card)
{ {
struct IsdnCardState *cs = card->cs;
char tmp[64]; char tmp[64];
strcpy(tmp, hfcs_revision); strcpy(tmp, hfcs_revision);
...@@ -220,42 +263,8 @@ setup_hfcs(struct IsdnCard *card) ...@@ -220,42 +263,8 @@ setup_hfcs(struct IsdnCard *card)
} }
} }
#endif #endif
cs->hw.hfcD.addr = card->para[1] & 0xfffe; if (hfcs_probe(card->cs, card) < 0)
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"))
return 0; return 0;
printk(KERN_INFO return 1;
"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);
} }
...@@ -187,26 +187,55 @@ static struct card_ops isurf_ops = { ...@@ -187,26 +187,55 @@ static struct card_ops isurf_ops = {
static struct pnp_card *pnp_surf __devinitdata = NULL; static struct pnp_card *pnp_surf __devinitdata = NULL;
#endif #endif
static int __init
isurf_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
unsigned long phymem;
phymem = card->para[2];
cs->hw.isurf.reset = card->para[1];
cs->irq = card->para[0];
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");
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, 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);
__set_bit(HW_ISAR, &cs->HW_Flags);
isac_setup(cs, &isac_ops);
if (isar_setup(cs, &isar_ops))
goto err;
return 0;
err:
hisax_release_resources(cs);
return -EBUSY;
}
int __init int __init
setup_isurf(struct IsdnCard *card) setup_isurf(struct IsdnCard *card)
{ {
struct IsdnCardState *cs = card->cs;
unsigned long phymem;
char tmp[64]; char tmp[64];
strcpy(tmp, ISurf_revision); strcpy(tmp, ISurf_revision);
printk(KERN_INFO "HiSax: ISurf driver Rev. %s\n", HiSax_getrev(tmp)); 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__ #ifdef __ISAPNP__
if (!card->para[1] || !card->para[2]) {
struct pnp_card *pb; struct pnp_card *pb;
struct pnp_dev *pd; struct pnp_dev *pd;
if (isapnp_present()) {
cs->subtyp = 0; cs->subtyp = 0;
if ((pb = pnp_find_card( if ((pb = pnp_find_card(
ISAPNP_VENDOR('S', 'I', 'E'), ISAPNP_VENDOR('S', 'I', 'E'),
...@@ -234,48 +263,16 @@ setup_isurf(struct IsdnCard *card) ...@@ -234,48 +263,16 @@ setup_isurf(struct IsdnCard *card)
pnp_device_detach(pd); pnp_device_detach(pd);
return(0); return(0);
} }
cs->hw.isurf.reset = pnp_port_start(pd, 0); card->para[1] = pnp_port_start(pd, 0);
phymem = pnp_port_start(pd, 1); card->para[2] = pnp_port_start(pd, 1);
cs->irq = pnp_irq(pd, 0); card->para[0] = pnp_irq(pd, 0);
} else { } else {
printk(KERN_INFO "ISurfPnP: no ISAPnP card found\n"); printk(KERN_INFO "ISurfPnP: no ISAPnP card found\n");
return(0); 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 #endif
} if (isurf_probe(card->cs, card) < 0)
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");
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);
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);
isac_setup(cs, &isac_ops);
if (isar_setup(cs, &isar_ops))
goto err;
return 1;
err:
hisax_release_resources(cs);
return 0; return 0;
return 1;
} }
...@@ -162,6 +162,29 @@ static struct card_ops ix1_ops = { ...@@ -162,6 +162,29 @@ static struct card_ops ix1_ops = {
.irq_func = hscxisac_irq, .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__ #ifdef __ISAPNP__
static struct isapnp_device_id itk_ids[] __initdata = { static struct isapnp_device_id itk_ids[] __initdata = {
{ ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25), { ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25),
...@@ -181,14 +204,18 @@ static struct pnp_card *pnp_c __devinitdata = NULL; ...@@ -181,14 +204,18 @@ static struct pnp_card *pnp_c __devinitdata = NULL;
int __init int __init
setup_ix1micro(struct IsdnCard *card) setup_ix1micro(struct IsdnCard *card)
{ {
struct IsdnCardState *cs = card->cs;
char tmp[64]; char tmp[64];
strcpy(tmp, ix1_revision); strcpy(tmp, ix1_revision);
printk(KERN_INFO "HiSax: ITK IX1 driver Rev. %s\n", HiSax_getrev(tmp)); 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__ #ifdef __ISAPNP__
if (!card->para[1] && isapnp_present()) { if (isapnp_present()) {
struct pnp_card *pb; struct pnp_card *pb;
struct pnp_dev *pd; struct pnp_dev *pd;
...@@ -221,7 +248,9 @@ setup_ix1micro(struct IsdnCard *card) ...@@ -221,7 +248,9 @@ setup_ix1micro(struct IsdnCard *card)
} }
card->para[1] = pnp_port_start(pd, 0); card->para[1] = pnp_port_start(pd, 0);
card->para[0] = pnp_irq(pd, 0); card->para[0] = pnp_irq(pd, 0);
break; if (ix1_probe(card->cs, card))
return 0;
return 1;
} else { } else {
printk(KERN_ERR "ITK PnP: PnP error card found, no device\n"); printk(KERN_ERR "ITK PnP: PnP error card found, no device\n");
} }
...@@ -231,27 +260,8 @@ setup_ix1micro(struct IsdnCard *card) ...@@ -231,27 +260,8 @@ setup_ix1micro(struct IsdnCard *card)
} }
if (!idev->card_vendor) { if (!idev->card_vendor) {
printk(KERN_INFO "ITK PnP: no ISAPnP card found\n"); printk(KERN_INFO "ITK PnP: no ISAPnP card found\n");
return(0);
} }
} }
#endif #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; return 0;
} }
...@@ -138,17 +138,11 @@ static struct card_ops mic_ops = { ...@@ -138,17 +138,11 @@ static struct card_ops mic_ops = {
.irq_func = hscxisac_irq, .irq_func = hscxisac_irq,
}; };
int __init static int __init
setup_mic(struct IsdnCard *card) 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->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.adr = cs->hw.mic.cfg_reg + MIC_ADR;
cs->hw.mic.isac = cs->hw.mic.cfg_reg + MIC_ISAC; cs->hw.mic.isac = cs->hw.mic.cfg_reg + MIC_ISAC;
cs->hw.mic.hscx = cs->hw.mic.cfg_reg + MIC_HSCX; cs->hw.mic.hscx = cs->hw.mic.cfg_reg + MIC_HSCX;
...@@ -158,11 +152,25 @@ setup_mic(struct IsdnCard *card) ...@@ -158,11 +152,25 @@ setup_mic(struct IsdnCard *card)
printk(KERN_INFO "mic: defined at 0x%x IRQ %d\n", printk(KERN_INFO "mic: defined at 0x%x IRQ %d\n",
cs->hw.mic.cfg_reg, cs->irq); cs->hw.mic.cfg_reg, cs->irq);
cs->card_ops = &mic_ops; cs->card_ops = &mic_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err; goto err;
return 1; return 0;
err: err:
hisax_release_resources(cs); hisax_release_resources(cs);
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 0;
return 1;
} }
...@@ -199,6 +199,70 @@ static struct card_ops niccy_ops = { ...@@ -199,6 +199,70 @@ static struct card_ops niccy_ops = {
.irq_func = niccy_interrupt, .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; static struct pci_dev *niccy_dev __initdata = NULL;
#ifdef __ISAPNP__ #ifdef __ISAPNP__
static struct pnp_card *pnp_c __devinitdata = NULL; static struct pnp_card *pnp_c __devinitdata = NULL;
...@@ -207,7 +271,6 @@ static struct pnp_card *pnp_c __devinitdata = NULL; ...@@ -207,7 +271,6 @@ static struct pnp_card *pnp_c __devinitdata = NULL;
int __init int __init
setup_niccy(struct IsdnCard *card) setup_niccy(struct IsdnCard *card)
{ {
struct IsdnCardState *cs = card->cs;
char tmp[64]; char tmp[64];
strcpy(tmp, niccy_revision); strcpy(tmp, niccy_revision);
...@@ -252,66 +315,18 @@ setup_niccy(struct IsdnCard *card) ...@@ -252,66 +315,18 @@ setup_niccy(struct IsdnCard *card)
} }
#endif #endif
if (card->para[1]) { if (card->para[1]) {
cs->hw.niccy.isac = card->para[1] + ISAC_PNP; if (niccy_pnp_probe(card->cs, card) < 0)
cs->hw.niccy.hscx = card->para[1] + HSCX_PNP; return 0;
cs->hw.niccy.isac_ale = card->para[2] + ISAC_PNP; return 1;
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;
} else { } else {
#if CONFIG_PCI #if CONFIG_PCI
u_int pci_ioaddr;
cs->subtyp = 0;
if ((niccy_dev = pci_find_device(PCI_VENDOR_ID_SATSAGEM, if ((niccy_dev = pci_find_device(PCI_VENDOR_ID_SATSAGEM,
PCI_DEVICE_ID_SATSAGEM_NICCY, niccy_dev))) { PCI_DEVICE_ID_SATSAGEM_NICCY, niccy_dev))) {
if (pci_enable_device(niccy_dev)) if (niccy_pci_probe(card->cs, niccy_dev) < 0)
return(0); return 0;
/* get IRQ */ return 1;
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);
} }
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 */ #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; return 0;
} }
...@@ -106,49 +106,20 @@ static struct card_ops nj_s_ops = { ...@@ -106,49 +106,20 @@ static struct card_ops nj_s_ops = {
.irq_func = nj_s_interrupt, .irq_func = nj_s_interrupt,
}; };
static struct pci_dev *dev_netjet __initdata = NULL; static int __init
nj_s_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
int __init
setup_netjet_s(struct IsdnCard *card)
{ {
struct IsdnCardState *cs = card->cs; if (pci_enable_device(pdev))
char tmp[64]; goto err;
#ifdef __BIG_ENDIAN pci_set_master(pdev);
#error "not running on big endian machines now"
#endif cs->irq = pdev->irq;
strcpy(tmp, NETjet_S_revision); cs->irq_flags |= SA_SHIRQ;
printk(KERN_INFO "HiSax: Traverse Tech. NETjet-S driver Rev. %s\n", HiSax_getrev(tmp)); cs->hw.njet.pdev = pdev;
cs->hw.njet.base = pci_resource_start(pdev, 0);
for ( ;; ) { if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn"))
if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, return 0;
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.auxa = cs->hw.njet.base + NETJET_AUXDATA;
cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF; cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF;
...@@ -168,34 +139,66 @@ setup_netjet_s(struct IsdnCard *card) ...@@ -168,34 +139,66 @@ setup_netjet_s(struct IsdnCard *card)
cs->hw.njet.auxd = 0xC0; cs->hw.njet.auxd = 0xC0;
cs->hw.njet.dmactrl = 0; 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_AUXCTRL, ~NETJET_ISACIRQ);
byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ); byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ);
byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
switch ( ( ( NETjet_ReadIC( cs, ISAC_RBCH ) >> 5 ) & 3 ) ) switch ((NETjet_ReadIC(cs, ISAC_RBCH) >> 5) & 3) {
{
case 0 : case 0 :
break; break;
case 3 : case 3 :
printk( KERN_WARNING "NETjet-S: NETspider-U PCI card found\n" ); printk(KERN_WARNING "NETjet-S: NETspider-U PCI card found\n" );
continue; goto err;
default : default :
printk( KERN_WARNING "NETjet-S: No PCI card found\n" ); printk(KERN_WARNING "NETjet-S: No PCI card found\n" );
return 0; goto err;
}
break;
} }
printk(KERN_INFO printk(KERN_INFO
"NETjet-S: PCI card configured at %#lx IRQ %d\n", "NETjet-S: PCI card configured at %#lx IRQ %d\n",
cs->hw.njet.base, cs->irq); 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); nj_s_reset(cs);
cs->irq_flags |= SA_SHIRQ; cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &nj_s_ops; cs->card_ops = &nj_s_ops;
isac_setup(cs, &netjet_dc_ops); isac_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_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 1;
return 0;
}
printk(KERN_WARNING "NETjet-S: No PCI card found\n");
return 0;
} }
...@@ -110,40 +110,20 @@ static struct card_ops nj_u_ops = { ...@@ -110,40 +110,20 @@ static struct card_ops nj_u_ops = {
.irq_func = nj_u_interrupt, .irq_func = nj_u_interrupt,
}; };
static struct pci_dev *dev_netjet __initdata = NULL; static int __init
nj_u_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
int __init
setup_netjet_u(struct IsdnCard *card)
{ {
struct IsdnCardState *cs = card->cs; if (pci_enable_device(pdev))
char tmp[64]; goto err;
#ifdef __BIG_ENDIAN
#error "not running on big endian machines now" pci_set_master(pdev);
#endif
strcpy(tmp, NETjet_U_revision); cs->irq = pdev->irq;
printk(KERN_INFO "HiSax: Traverse Tech. NETspider-U driver Rev. %s\n", HiSax_getrev(tmp)); cs->irq_flags |= SA_SHIRQ;
cs->hw.njet.pdev = pdev;
for ( ;; ) { cs->hw.njet.base = pci_resource_start(pdev, 0);
if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netspider-u isdn"))
PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { goto err;
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.auxa = cs->hw.njet.base + NETJET_AUXDATA;
cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF; cs->hw.njet.isac = cs->hw.njet.base | NETJET_ISAC_OFF;
...@@ -163,35 +143,52 @@ setup_netjet_u(struct IsdnCard *card) ...@@ -163,35 +143,52 @@ setup_netjet_u(struct IsdnCard *card)
cs->hw.njet.auxd = 0xC0; cs->hw.njet.auxd = 0xC0;
cs->hw.njet.dmactrl = 0; 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_AUXCTRL, ~NETJET_ISACIRQ);
byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ); byteout(cs->hw.njet.base + NETJET_IRQMASK1, NETJET_ISACIRQ);
byteout(cs->hw.njet.auxa, cs->hw.njet.auxd); byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
switch ( ( ( NETjet_ReadIC( cs, ICC_RBCH ) >> 5 ) & 3 ) ) switch ((NETjet_ReadIC(cs, ICC_RBCH) >> 5) & 3) {
{ case 3:
case 3 :
break; break;
case 0:
case 0 : printk(KERN_WARNING "NETspider-U: NETjet-S PCI card found\n" );
printk( KERN_WARNING "NETspider-U: NETjet-S PCI card found\n" ); goto err;
continue; default:
printk(KERN_WARNING "NETspider-U: No PCI card found\n" );
default : goto err;
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",
}
printk(KERN_INFO
"NETspider-U: PCI card configured at %#lx IRQ %d\n",
cs->hw.njet.base, cs->irq); cs->hw.njet.base, cs->irq);
if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn"))
return 0;
nj_u_reset(cs); nj_u_reset(cs);
cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &nj_u_ops; cs->card_ops = &nj_u_ops;
icc_setup(cs, &netjet_dc_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)
{
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));
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 1;
return 0;
}
printk(KERN_WARNING "NETspider-U: No PCI card found\n");
return 0;
} }
...@@ -172,14 +172,9 @@ static struct card_ops s0box_ops = { ...@@ -172,14 +172,9 @@ static struct card_ops s0box_ops = {
.irq_func = hscxisac_irq, .irq_func = hscxisac_irq,
}; };
int __init static int __init
setup_s0box(struct IsdnCard *card) 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.cfg_reg = card->para[1];
cs->hw.teles3.hscx[0] = -0x20; cs->hw.teles3.hscx[0] = -0x20;
cs->hw.teles3.hscx[1] = 0x0; cs->hw.teles3.hscx[1] = 0x0;
...@@ -200,8 +195,20 @@ setup_s0box(struct IsdnCard *card) ...@@ -200,8 +195,20 @@ setup_s0box(struct IsdnCard *card)
cs->card_ops = &s0box_ops; cs->card_ops = &s0box_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err; goto err;
return 1; return 0;
err: err:
hisax_release_resources(cs); hisax_release_resources(cs);
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 0;
return 1;
} }
...@@ -201,36 +201,21 @@ static struct card_ops saphir_ops = { ...@@ -201,36 +201,21 @@ static struct card_ops saphir_ops = {
.irq_func = saphir_interrupt, .irq_func = saphir_interrupt,
}; };
int __init static int __init
setup_saphir(struct IsdnCard *card) 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.cfg_reg = card->para[1];
cs->hw.saphir.isac = card->para[1] + ISAC_DATA; cs->hw.saphir.isac = card->para[1] + ISAC_DATA;
cs->hw.saphir.hscx = card->para[1] + HSCX_DATA; cs->hw.saphir.hscx = card->para[1] + HSCX_DATA;
cs->hw.saphir.ale = card->para[1] + ADDRESS_REG; cs->hw.saphir.ale = card->para[1] + ADDRESS_REG;
cs->irq = card->para[0]; cs->irq = card->para[0];
if (!request_io(&cs->rs, cs->hw.saphir.cfg_reg, 6, "saphir")) if (!request_io(&cs->rs, cs->hw.saphir.cfg_reg, 6, "saphir"))
goto err; goto err;
printk(KERN_INFO printk(KERN_INFO "HiSax: %s config irq:%d io:0x%X\n",
"HiSax: %s config irq:%d io:0x%X\n", CardType[cs->typ], cs->irq, cs->hw.saphir.cfg_reg);
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)) if (saphir_reset(cs))
goto err; goto err;
...@@ -238,8 +223,27 @@ setup_saphir(struct IsdnCard *card) ...@@ -238,8 +223,27 @@ setup_saphir(struct IsdnCard *card)
if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err; goto err;
return 1; 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: err:
saphir_release(cs); 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 0;
return 1;
} }
...@@ -73,7 +73,6 @@ const char *Sedlbauer_Types[] = ...@@ -73,7 +73,6 @@ const char *Sedlbauer_Types[] =
#define SEDL_SPEEDFAX_PYRAMID 7 #define SEDL_SPEEDFAX_PYRAMID 7
#define SEDL_SPEEDFAX_PCI 8 #define SEDL_SPEEDFAX_PCI 8
#define SEDL_CHIP_TEST 0
#define SEDL_CHIP_ISAC_HSCX 1 #define SEDL_CHIP_ISAC_HSCX 1
#define SEDL_CHIP_ISAC_ISAR 2 #define SEDL_CHIP_ISAC_ISAR 2
#define SEDL_CHIP_IPAC 3 #define SEDL_CHIP_IPAC 3
...@@ -452,6 +451,241 @@ static struct card_ops sedlbauer_isar_ops = { ...@@ -452,6 +451,241 @@ static struct card_ops sedlbauer_isar_ops = {
.irq_func = sedlbauer_isar_interrupt, .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; static struct pci_dev *dev_sedl __devinitdata = NULL;
#ifdef __ISAPNP__ #ifdef __ISAPNP__
...@@ -472,37 +706,29 @@ static struct pnp_card *pnp_c __devinitdata = NULL; ...@@ -472,37 +706,29 @@ static struct pnp_card *pnp_c __devinitdata = NULL;
int __devinit int __devinit
setup_sedlbauer(struct IsdnCard *card) setup_sedlbauer(struct IsdnCard *card)
{ {
int bytecnt, val;
struct IsdnCardState *cs = card->cs; struct IsdnCardState *cs = card->cs;
char tmp[64]; char tmp[64];
u16 sub_vendor_id, sub_id; u16 sub_vendor_id, sub_id;
strcpy(tmp, Sedlbauer_revision); 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 (card->para[1]) {
if (cs->typ == ISDN_CTYPE_SEDLBAUER) { if (cs->typ == ISDN_CTYPE_SEDLBAUER) {
cs->subtyp = SEDL_SPEED_CARD_WIN; if (sedl_card_win_probe(card->cs, card) < 0)
cs->hw.sedl.bus = SEDL_BUS_ISA; return 0;
cs->hw.sedl.chip = SEDL_CHIP_TEST; return 1;
} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) { } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_PCMCIA) {
cs->subtyp = SEDL_SPEED_STAR; if (sedl_star_probe(card->cs, card) < 0)
cs->hw.sedl.bus = SEDL_BUS_PCMCIA; return 0;
cs->hw.sedl.chip = SEDL_CHIP_TEST; return 1;
} else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) { } else if (cs->typ == ISDN_CTYPE_SEDLBAUER_FAX) {
cs->subtyp = SEDL_SPEED_FAX; if (sedl_fax_probe(card->cs, card) < 0)
cs->hw.sedl.bus = SEDL_BUS_ISA; return 0;
cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; return 1;
} 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;
} }
} else {
#ifdef __ISAPNP__ #ifdef __ISAPNP__
if (isapnp_present()) { if (isapnp_present()) {
struct pnp_card *pb; struct pnp_card *pb;
...@@ -540,14 +766,14 @@ setup_sedlbauer(struct IsdnCard *card) ...@@ -540,14 +766,14 @@ setup_sedlbauer(struct IsdnCard *card)
cs->hw.sedl.cfg_reg = card->para[1]; cs->hw.sedl.cfg_reg = card->para[1];
cs->irq = card->para[0]; cs->irq = card->para[0];
if (pdev->function == ISAPNP_FUNCTION(0x2)) { if (pdev->function == ISAPNP_FUNCTION(0x2)) {
cs->subtyp = SEDL_SPEED_FAX; if (sedl_fax_probe(card->cs, card))
cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; return 0;
bytecnt = 16; return 1;
} else { } else {
cs->subtyp = SEDL_SPEED_CARD_WIN; if (sedl_card_win_probe(card->cs, card))
cs->hw.sedl.chip = SEDL_CHIP_TEST; return 0;
return 1;
} }
goto ready;
} else { } else {
printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n"); printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n");
goto err; goto err;
...@@ -563,174 +789,34 @@ setup_sedlbauer(struct IsdnCard *card) ...@@ -563,174 +789,34 @@ setup_sedlbauer(struct IsdnCard *card)
#endif #endif
/* Probe for Sedlbauer speed pci */ /* Probe for Sedlbauer speed pci */
#if CONFIG_PCI #if CONFIG_PCI
if ((dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET, dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET,
PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) { PCI_DEVICE_ID_TIGERJET_100, dev_sedl);
if (pci_enable_device(dev_sedl)) if (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;
sub_vendor_id = dev_sedl->subsystem_vendor; sub_vendor_id = dev_sedl->subsystem_vendor;
sub_id = dev_sedl->subsystem_device; sub_id = dev_sedl->subsystem_device;
printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %x\n", printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %x\n",
sub_vendor_id, sub_id); sub_vendor_id, sub_id);
printk(KERN_INFO "Sedlbauer: PCI base adr %#x\n",
cs->hw.sedl.cfg_reg);
if (sub_id != PCI_SUB_ID_SEDLBAUER) { if (sub_id != PCI_SUB_ID_SEDLBAUER) {
printk(KERN_ERR "Sedlbauer: unknown sub id %#x\n", sub_id); printk(KERN_ERR "Sedlbauer: unknown sub id %#x\n", sub_id);
goto err; return 0;
} }
if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) { if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) {
cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; if (sedl_fax_pyramid_probe(cs, dev_sedl))
cs->subtyp = SEDL_SPEEDFAX_PYRAMID; return 0;
return 1;
} else if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PCI) { } else if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PCI) {
cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; if (sedl_fax_pci_probe(cs, dev_sedl))
cs->subtyp = SEDL_SPEEDFAX_PCI; return 0;
return 1;
} else if (sub_vendor_id == PCI_SUBVENDOR_SEDLBAUER_PCI) { } else if (sub_vendor_id == PCI_SUBVENDOR_SEDLBAUER_PCI) {
cs->hw.sedl.chip = SEDL_CHIP_IPAC; if (sedl_pci_probe(cs, dev_sedl))
cs->subtyp = SEDL_SPEED_PCI; return 0;
} else { return 1;
}
printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n", printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n",
sub_vendor_id); sub_vendor_id);
goto err; return 0;
} }
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 */ #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);
}
}
return 1;
err:
hisax_release_resources(cs);
return 0; return 0;
} }
...@@ -190,41 +190,28 @@ get_io_range(struct IsdnCardState *cs) ...@@ -190,41 +190,28 @@ get_io_range(struct IsdnCardState *cs)
return 0; return 0;
} }
int __init static int __init
setup_sportster(struct IsdnCard *card) sportster_probe(struct IsdnCardState *cs, 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];
cs->irq = card->para[0]; cs->irq = card->para[0];
cs->hw.spt.cfg_reg = card->para[1];
if (!get_io_range(cs)) if (!get_io_range(cs))
return (0); return -EBUSY;
cs->hw.spt.isac = cs->hw.spt.cfg_reg + SPORTSTER_ISAC; 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[0] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXA;
cs->hw.spt.hscx[1] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXB; cs->hw.spt.hscx[1] = cs->hw.spt.cfg_reg + SPORTSTER_HSCXB;
switch(cs->irq) { switch(cs->irq) {
case 5: cs->hw.spt.res_irq = 1; case 5: cs->hw.spt.res_irq = 1; break;
break; case 7: cs->hw.spt.res_irq = 2; break;
case 7: cs->hw.spt.res_irq = 2; case 10:cs->hw.spt.res_irq = 3; break;
break; case 11:cs->hw.spt.res_irq = 4; break;
case 10:cs->hw.spt.res_irq = 3; case 12:cs->hw.spt.res_irq = 5; break;
break; case 14:cs->hw.spt.res_irq = 6; break;
case 11:cs->hw.spt.res_irq = 4; case 15:cs->hw.spt.res_irq = 7; break;
break; default:
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"); printk(KERN_WARNING "Sportster: wrong IRQ\n");
return(0); goto err;
} }
sportster_reset(cs); sportster_reset(cs);
printk(KERN_INFO "HiSax: %s config irq:%d cfg:0x%X\n", printk(KERN_INFO "HiSax: %s config irq:%d cfg:0x%X\n",
...@@ -234,8 +221,22 @@ setup_sportster(struct IsdnCard *card) ...@@ -234,8 +221,22 @@ setup_sportster(struct IsdnCard *card)
cs->card_ops = &sportster_ops; cs->card_ops = &sportster_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err; goto err;
return 1; return 0;
err: err:
hisax_release_resources(cs); 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 0;
return 1;
} }
...@@ -256,15 +256,9 @@ static struct card_ops teleint_ops = { ...@@ -256,15 +256,9 @@ static struct card_ops teleint_ops = {
.irq_func = teleint_interrupt, .irq_func = teleint_interrupt,
}; };
int __init static int __init
setup_TeleInt(struct IsdnCard *card) 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->hw.hfc.addr = card->para[1] & 0x3fe;
cs->irq = card->para[0]; cs->irq = card->para[0];
cs->hw.hfc.cirm = HFC_CIRM; cs->hw.hfc.cirm = HFC_CIRM;
...@@ -309,17 +303,29 @@ setup_TeleInt(struct IsdnCard *card) ...@@ -309,17 +303,29 @@ setup_TeleInt(struct IsdnCard *card)
byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm); byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm);
byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.ctmt); byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.ctmt);
printk(KERN_INFO printk(KERN_INFO "TeleInt: defined at 0x%x IRQ %d\n",
"TeleInt: defined at 0x%x IRQ %d\n", cs->hw.hfc.addr, cs->irq);
cs->hw.hfc.addr,
cs->irq);
cs->card_ops = &teleint_ops; cs->card_ops = &teleint_ops;
teleint_reset(cs); teleint_reset(cs);
isac_setup(cs, &isac_ops); isac_setup(cs, &isac_ops);
hfc_setup(cs, &hfc_ops); hfc_setup(cs, &hfc_ops);
return 1; return 0;
err: err:
teleint_release(cs); 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 0;
return 1;
} }
...@@ -165,28 +165,35 @@ static struct card_ops teles0_ops = { ...@@ -165,28 +165,35 @@ static struct card_ops teles0_ops = {
.irq_func = hscxisac_irq, .irq_func = hscxisac_irq,
}; };
int __init static int __init
setup_teles0(struct IsdnCard *card) teles0_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{
cs->irq = card->para[0];
/* 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");
if (!cs->hw.teles0.membase)
return -EBUSY;
if (teles0_reset(cs)) {
printk(KERN_WARNING "Teles0: wrong IRQ\n");
return -EBUSY;
}
cs->card_ops = &teles0_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
return -EBUSY;
return 0;
}
static int __init
teles16_0_probe(struct IsdnCardState *cs, struct IsdnCard *card)
{ {
u8 val; 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]; 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")) if (!request_io(&cs->rs, cs->hw.teles0.cfg_reg, 8, "teles cfg"))
goto err; goto err;
...@@ -209,28 +216,44 @@ setup_teles0(struct IsdnCard *card) ...@@ -209,28 +216,44 @@ setup_teles0(struct IsdnCard *card)
cs->hw.teles0.cfg_reg + 2, val); cs->hw.teles0.cfg_reg + 2, val);
goto err; goto err;
} }
} if (teles0_probe(cs, card) < 0)
/* 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");
if (!cs->hw.teles0.membase)
goto err; goto err;
printk(KERN_INFO return 0;
"HiSax: %s config irq:%d mem:0x%p cfg:0x%X\n", err:
CardType[cs->typ], cs->irq, hisax_release_resources(cs);
cs->hw.teles0.membase, cs->hw.teles0.cfg_reg); return -EBUSY;
if (teles0_reset(cs)) { }
printk(KERN_WARNING "Teles0: wrong IRQ\n");
goto err; static int __init
} teles8_0_probe(struct IsdnCardState *cs, struct IsdnCard *card)
cs->card_ops = &teles0_ops; {
if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) cs->hw.teles0.cfg_reg = 0;
if (teles0_probe(cs, card) < 0)
goto err; goto err;
return 1;
return 0;
err: err:
hisax_release_resources(cs); 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; return 0;
} else {
if (teles8_0_probe(card->cs, card) < 0)
return 0;
}
return 1;
} }
...@@ -176,6 +176,152 @@ static struct card_ops teles3_ops = { ...@@ -176,6 +176,152 @@ static struct card_ops teles3_ops = {
.irq_func = hscxisac_irq, .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__ #ifdef __ISAPNP__
static struct isapnp_device_id teles_ids[] __initdata = { static struct isapnp_device_id teles_ids[] __initdata = {
{ ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2110), { ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2110),
...@@ -197,16 +343,10 @@ static struct pnp_card *pnp_c __devinitdata = NULL; ...@@ -197,16 +343,10 @@ static struct pnp_card *pnp_c __devinitdata = NULL;
int __devinit int __devinit
setup_teles3(struct IsdnCard *card) setup_teles3(struct IsdnCard *card)
{ {
u8 val;
struct IsdnCardState *cs = card->cs;
char tmp[64]; char tmp[64];
strcpy(tmp, teles3_revision); strcpy(tmp, teles3_revision);
printk(KERN_INFO "HiSax: Teles IO driver Rev. %s\n", HiSax_getrev(tmp)); 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__ #ifdef __ISAPNP__
if (!card->para[1] && isapnp_present()) { if (!card->para[1] && isapnp_present()) {
struct pnp_card *pnp_card; struct pnp_card *pnp_card;
...@@ -258,100 +398,18 @@ setup_teles3(struct IsdnCard *card) ...@@ -258,100 +398,18 @@ setup_teles3(struct IsdnCard *card)
} }
} }
#endif #endif
if (cs->typ == ISDN_CTYPE_16_3) { if (card->cs->typ == ISDN_CTYPE_16_3) {
cs->hw.teles3.cfg_reg = card->para[1]; if (teles16_3_probe(card->cs, card) < 0)
switch (cs->hw.teles3.cfg_reg) { return 0;
case 0x180: } else if (card->cs->typ == ISDN_CTYPE_TELESPCMCIA) {
case 0x280: if (telespcmcia_probe(card->cs, card) < 0)
case 0x380: return 0;
cs->hw.teles3.cfg_reg |= 0xc00; } else if (card->cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
break; if (compaq_probe(card->cs, card) < 0)
} return 0;
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];
} else { /* PNP */ } else { /* PNP */
cs->hw.teles3.cfg_reg = 0; if (telespnp_probe(card->cs, card) < 0)
cs->hw.teles3.isac = card->para[1] - 32; return 0;
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;
} }
cs->card_ops = &teles3_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err;
return 1; return 1;
err:
hisax_release_resources(cs);
return 0;
} }
...@@ -231,36 +231,23 @@ static struct card_ops telespci_ops = { ...@@ -231,36 +231,23 @@ static struct card_ops telespci_ops = {
.irq_func = telespci_interrupt, .irq_func = telespci_interrupt,
}; };
static struct pci_dev *dev_tel __initdata = NULL; static int __init
telespci_probe(struct IsdnCardState *cs, struct pci_dev *pdev)
int __init
setup_telespci(struct IsdnCard *card)
{ {
struct IsdnCardState *cs = card->cs; int rc;
char tmp[64];
#ifdef __BIG_ENDIAN printk(KERN_INFO "TelesPCI: defined at %#lx IRQ %d\n",
#error "not running on big endian machines now" pci_resource_start(pdev, 0), pdev->irq);
#endif
strcpy(tmp, telespci_revision); rc = -EBUSY;
printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp)); if (pci_enable_device(pdev))
if ((dev_tel = pci_find_device (PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_tel))) { goto err;
if (pci_enable_device(dev_tel))
return(0); cs->irq = pdev->irq;
cs->irq = dev_tel->irq; cs->irq_flags |= SA_SHIRQ;
if (!cs->irq) { cs->hw.teles0.membase = request_mmio(&cs->rs, pci_resource_start(pdev, 0), 4096, "telespci");
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) if (!cs->hw.teles0.membase)
goto err; 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);
}
/* Initialize Zoran PCI controller */ /* Initialize Zoran PCI controller */
writel(0x00000000, cs->hw.teles0.membase + 0x28); writel(0x00000000, cs->hw.teles0.membase + 0x28);
...@@ -270,17 +257,36 @@ setup_telespci(struct IsdnCard *card) ...@@ -270,17 +257,36 @@ setup_telespci(struct IsdnCard *card)
writel(0x70000000, cs->hw.teles0.membase + 0x3C); writel(0x70000000, cs->hw.teles0.membase + 0x3C);
writel(0x61000000, cs->hw.teles0.membase + 0x40); writel(0x61000000, cs->hw.teles0.membase + 0x40);
/* writel(0x00800000, cs->hw.teles0.membase + 0x200); */ /* 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; cs->card_ops = &telespci_ops;
if (hscxisac_setup(cs, &isac_ops, &hscx_ops)) if (hscxisac_setup(cs, &isac_ops, &hscx_ops))
goto err; goto err;
return 1; return 0;
err: err:
hisax_release_resources(cs); 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; return 0;
} }
...@@ -669,11 +669,11 @@ static int id_idx ; ...@@ -669,11 +669,11 @@ static int id_idx ;
static struct pci_dev *dev_w6692 __initdata = NULL; static struct pci_dev *dev_w6692 __initdata = NULL;
static int static int
w6692_setup(struct IsdnCardState *cs, struct dc_hw_ops *dc_ops, w6692_hw_init(struct IsdnCardState *cs)
struct bc_hw_ops *bc_ops)
{ {
cs->dc_hw_ops = dc_ops; cs->card_ops = &w6692_ops;
cs->bc_hw_ops = bc_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); dc_l1_init(cs, &w6692_dc_l1_ops);
cs->bc_l1_ops = &w6692_bc_l1_ops; cs->bc_l1_ops = &w6692_bc_l1_ops;
W6692Version(cs, "W6692:"); W6692Version(cs, "W6692:");
...@@ -685,14 +685,45 @@ w6692_setup(struct IsdnCardState *cs, struct dc_hw_ops *dc_ops, ...@@ -685,14 +685,45 @@ w6692_setup(struct IsdnCardState *cs, struct dc_hw_ops *dc_ops,
return 0; 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 int __init
setup_w6692(struct IsdnCard *card) setup_w6692(struct IsdnCard *card)
{ {
struct IsdnCardState *cs = card->cs;
char tmp[64]; char tmp[64];
u8 found = 0;
u8 pci_irq = 0;
u_int pci_ioaddr = 0;
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
#error "not running on big endian machines now" #error "not running on big endian machines now"
...@@ -704,54 +735,13 @@ setup_w6692(struct IsdnCard *card) ...@@ -704,54 +735,13 @@ setup_w6692(struct IsdnCard *card)
id_list[id_idx].device_id, id_list[id_idx].device_id,
dev_w6692); dev_w6692);
if (dev_w6692) { if (dev_w6692) {
if (pci_enable_device(dev_w6692)) card->cs->subtyp = id_idx;
continue; if (w6692_probe(card->cs, dev_w6692) < 0)
cs->subtyp = id_idx; return 0;
break; return 1;
} }
id_idx++; 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"); 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; 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);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment