Commit 91cc110f authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN/HiSax: Simplified request_region() etc.

This patch introduces, private to the HiSax driver, new helper functions
request_io/mmio(), which correspond to request_region()/
request_mem_region() but also are verbose about failures and keep track
of the allocated regions, so unwinding in case of errors is automatic.
  
Additionally, request_mmio() will also ioremap() the region.
parent 811b6a3b
...@@ -188,13 +188,6 @@ ipac_writefifo(struct IsdnCardState *cs, u8 off, u8 * data, int size) ...@@ -188,13 +188,6 @@ ipac_writefifo(struct IsdnCardState *cs, u8 off, u8 * data, int size)
BUILD_IPAC_OPS(ipac); BUILD_IPAC_OPS(ipac);
static void
asuscom_release(struct IsdnCardState *cs)
{
if (cs->hw.asus.cfg_reg)
release_region(cs->hw.asus.cfg_reg, 8);
}
static int static int
asuscom_reset(struct IsdnCardState *cs) asuscom_reset(struct IsdnCardState *cs)
{ {
...@@ -233,14 +226,14 @@ Asus_card_msg(struct IsdnCardState *cs, int mt, void *arg) ...@@ -233,14 +226,14 @@ Asus_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static struct card_ops asuscom_ops = { static struct card_ops asuscom_ops = {
.init = inithscxisac, .init = inithscxisac,
.reset = asuscom_reset, .reset = asuscom_reset,
.release = asuscom_release, .release = hisax_release_resources,
.irq_func = hscxisac_irq, .irq_func = hscxisac_irq,
}; };
static struct card_ops asuscom_ipac_ops = { static struct card_ops asuscom_ipac_ops = {
.init = ipac_init, .init = ipac_init,
.reset = asuscom_ipac_reset, .reset = asuscom_ipac_reset,
.release = asuscom_release, .release = hisax_release_resources,
.irq_func = ipac_irq, .irq_func = ipac_irq,
}; };
...@@ -319,15 +312,8 @@ setup_asuscom(struct IsdnCard *card) ...@@ -319,15 +312,8 @@ setup_asuscom(struct IsdnCard *card)
bytecnt = 8; bytecnt = 8;
cs->hw.asus.cfg_reg = card->para[1]; cs->hw.asus.cfg_reg = card->para[1];
cs->irq = card->para[0]; cs->irq = card->para[0];
if (!request_region((cs->hw.asus.cfg_reg), bytecnt, if (!request_io(&cs->rs, cs->hw.asus.cfg_reg, bytecnt, "asuscom isdn"))
"asuscom isdn")) { goto err;
printk(KERN_WARNING
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.asus.cfg_reg,
cs->hw.asus.cfg_reg + bytecnt);
return (0);
}
printk(KERN_INFO "ISDNLink: defined at 0x%x IRQ %d\n", printk(KERN_INFO "ISDNLink: defined at 0x%x IRQ %d\n",
cs->hw.asus.cfg_reg, cs->irq); cs->hw.asus.cfg_reg, cs->irq);
cs->cardmsg = &Asus_card_msg; cs->cardmsg = &Asus_card_msg;
...@@ -355,11 +341,13 @@ setup_asuscom(struct IsdnCard *card) ...@@ -355,11 +341,13 @@ setup_asuscom(struct IsdnCard *card)
if (HscxVersion(cs, "ISDNLink:")) { if (HscxVersion(cs, "ISDNLink:")) {
printk(KERN_WARNING printk(KERN_WARNING
"ISDNLink: wrong HSCX versions check IO address\n"); "ISDNLink: wrong HSCX versions check IO address\n");
asuscom_release(cs); goto err;
return (0);
} }
} }
printk(KERN_INFO "ISDNLink: resetting card\n"); printk(KERN_INFO "ISDNLink: resetting card\n");
cs->card_ops->reset(cs); cs->card_ops->reset(cs);
return (1); return 1;
err:
hisax_release_resources(cs);
return 0;
} }
...@@ -146,24 +146,6 @@ avm_a1_interrupt(int intno, void *dev_id, struct pt_regs *regs) ...@@ -146,24 +146,6 @@ avm_a1_interrupt(int intno, void *dev_id, struct pt_regs *regs)
spin_unlock(&cs->lock); spin_unlock(&cs->lock);
} }
inline static void
release_ioregs(struct IsdnCardState *cs, int mask)
{
release_region(cs->hw.avm.cfg_reg, 8);
if (mask & 1)
release_region(cs->hw.avm.isac + 32, 32);
if (mask & 2)
release_region(cs->hw.avm.isacfifo, 1);
if (mask & 4)
release_region(cs->hw.avm.hscx[0] + 32, 32);
if (mask & 8)
release_region(cs->hw.avm.hscxfifo[0], 1);
if (mask & 0x10)
release_region(cs->hw.avm.hscx[1] + 32, 32);
if (mask & 0x20)
release_region(cs->hw.avm.hscxfifo[1], 1);
}
static int static int
AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg) AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{ {
...@@ -178,15 +160,9 @@ avm_a1_init(struct IsdnCardState *cs) ...@@ -178,15 +160,9 @@ avm_a1_init(struct IsdnCardState *cs)
inithscxisac(cs); inithscxisac(cs);
} }
static void
avm_a1_release(struct IsdnCardState *cs)
{
release_ioregs(cs, 0x3f);
}
static struct card_ops avm_a1_ops = { static struct card_ops avm_a1_ops = {
.init = avm_a1_init, .init = avm_a1_init,
.release = avm_a1_release, .release = hisax_release_resources,
.irq_func = avm_a1_interrupt, .irq_func = avm_a1_interrupt,
}; };
...@@ -202,73 +178,25 @@ setup_avm_a1(struct IsdnCard *card) ...@@ -202,73 +178,25 @@ setup_avm_a1(struct IsdnCard *card)
if (cs->typ != ISDN_CTYPE_A1) if (cs->typ != ISDN_CTYPE_A1)
return (0); return (0);
cs->hw.avm.cfg_reg = card->para[1] + 0x1800; cs->hw.avm.cfg_reg = request_io(&cs->rs, card->para[1] + 0x1800, 8, "avm cfg");
cs->hw.avm.isac = card->para[1] + 0x1400 - 0x20; if (!cs->hw.avm.cfg_reg) goto err;
cs->hw.avm.hscx[0] = card->para[1] + 0x400 - 0x20; cs->hw.avm.isac = request_io(&cs->rs, card->para[1] + 0x1400, 32, "HiSax isac");
cs->hw.avm.hscx[1] = card->para[1] + 0xc00 - 0x20; if (!cs->hw.avm.isac) goto err;
cs->hw.avm.isacfifo = card->para[1] + 0x1000; cs->hw.avm.isacfifo = request_io(&cs->rs, card->para[1] + 0x1000, 1, "HiSax isac fifo");
cs->hw.avm.hscxfifo[0] = card->para[1]; if (!cs->hw.avm.isacfifo) goto err;
cs->hw.avm.hscxfifo[1] = card->para[1] + 0x800; cs->hw.avm.hscx[0] = request_io(&cs->rs, card->para[1] + 0x400, 32, "HiSax hscx A");
if (!cs->hw.avm.hscx[0]) goto err;
cs->hw.avm.hscxfifo[0] = request_io(&cs->rs, card->para[1], 1, "HiSax hscx A fifo");
if (!cs->hw.avm.hscxfifo[0]) goto err;
cs->hw.avm.hscx[1] = request_io(&cs->rs, card->para[1] + 0xc00, 32, "HiSax hscx B");
if (!cs->hw.avm.hscx[1]) goto err;
cs->hw.avm.hscxfifo[1] = request_io(&cs->rs, card->para[1] + 0x800, 1, "HiSax hscx B fifo");
if (!cs->hw.avm.hscxfifo[1]) goto err;
cs->hw.avm.isac -= 0x20;
cs->hw.avm.hscx[0] -= 0x20;
cs->hw.avm.hscx[1] -= 0x20;
cs->irq = card->para[0]; cs->irq = card->para[0];
if (!request_region(cs->hw.avm.cfg_reg, 8, "avm cfg")) {
printk(KERN_WARNING
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.avm.cfg_reg,
cs->hw.avm.cfg_reg + 8);
return (0);
}
if (!request_region(cs->hw.avm.isac + 32, 32, "HiSax isac")) {
printk(KERN_WARNING
"HiSax: %s isac ports %x-%x already in use\n",
CardType[cs->typ],
cs->hw.avm.isac + 32,
cs->hw.avm.isac + 64);
release_ioregs(cs, 0);
return (0);
}
if (!request_region(cs->hw.avm.isacfifo, 1, "HiSax isac fifo")) {
printk(KERN_WARNING
"HiSax: %s isac fifo port %x already in use\n",
CardType[cs->typ],
cs->hw.avm.isacfifo);
release_ioregs(cs, 1);
return (0);
}
if (!request_region(cs->hw.avm.hscx[0] + 32, 32, "HiSax hscx A")) {
printk(KERN_WARNING
"HiSax: %s hscx A ports %x-%x already in use\n",
CardType[cs->typ],
cs->hw.avm.hscx[0] + 32,
cs->hw.avm.hscx[0] + 64);
release_ioregs(cs, 3);
return (0);
}
if (!request_region(cs->hw.avm.hscxfifo[0], 1, "HiSax hscx A fifo")) {
printk(KERN_WARNING
"HiSax: %s hscx A fifo port %x already in use\n",
CardType[cs->typ],
cs->hw.avm.hscxfifo[0]);
release_ioregs(cs, 7);
return (0);
}
if (!request_region(cs->hw.avm.hscx[1] + 32, 32, "HiSax hscx B")) {
printk(KERN_WARNING
"HiSax: %s hscx B ports %x-%x already in use\n",
CardType[cs->typ],
cs->hw.avm.hscx[1] + 32,
cs->hw.avm.hscx[1] + 64);
release_ioregs(cs, 0xf);
return (0);
}
if (!request_region(cs->hw.avm.hscxfifo[1], 1, "HiSax hscx B fifo")) {
printk(KERN_WARNING
"HiSax: %s hscx B fifo port %x already in use\n",
CardType[cs->typ],
cs->hw.avm.hscxfifo[1]);
release_ioregs(cs, 0x1f);
return (0);
}
byteout(cs->hw.avm.cfg_reg, 0x0); byteout(cs->hw.avm.cfg_reg, 0x0);
HZDELAY(HZ / 5 + 1); HZDELAY(HZ / 5 + 1);
byteout(cs->hw.avm.cfg_reg, 0x1); byteout(cs->hw.avm.cfg_reg, 0x1);
...@@ -316,8 +244,10 @@ setup_avm_a1(struct IsdnCard *card) ...@@ -316,8 +244,10 @@ setup_avm_a1(struct IsdnCard *card)
if (HscxVersion(cs, "AVM A1:")) { if (HscxVersion(cs, "AVM A1:")) {
printk(KERN_WARNING printk(KERN_WARNING
"AVM A1: wrong HSCX versions check IO address\n"); "AVM A1: wrong HSCX versions check IO address\n");
release_ioregs(cs, 0x3f); goto err;
return (0);
} }
return (1); return 1;
err:
hisax_release_resources(cs);
return 0;
} }
...@@ -592,7 +592,7 @@ static void ...@@ -592,7 +592,7 @@ static void
avm_pcipnp_release(struct IsdnCardState *cs) avm_pcipnp_release(struct IsdnCardState *cs)
{ {
outb(0, cs->hw.avm.cfg_reg + 2); outb(0, cs->hw.avm.cfg_reg + 2);
release_region(cs->hw.avm.cfg_reg, 32); hisax_release_resources(cs);
} }
static struct card_ops avm_pci_ops = { static struct card_ops avm_pci_ops = {
...@@ -693,15 +693,10 @@ setup_avm_pcipnp(struct IsdnCard *card) ...@@ -693,15 +693,10 @@ setup_avm_pcipnp(struct IsdnCard *card)
} }
ready: ready:
cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10; cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10;
if (!request_region((cs->hw.avm.cfg_reg), 32, (cs->subtyp == AVM_FRITZ_PCI) if (!request_io(&cs->rs, cs->hw.avm.cfg_reg, 32,
? "avm PCI" : "avm PnP")) { cs->subtyp == AVM_FRITZ_PCI ? "avm PCI" : "avm PnP"))
printk(KERN_WARNING goto err;
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.avm.cfg_reg,
cs->hw.avm.cfg_reg + 31);
return (0);
}
switch (cs->subtyp) { switch (cs->subtyp) {
case AVM_FRITZ_PCI: case AVM_FRITZ_PCI:
val = inl(cs->hw.avm.cfg_reg); val = inl(cs->hw.avm.cfg_reg);
...@@ -726,5 +721,8 @@ setup_avm_pcipnp(struct IsdnCard *card) ...@@ -726,5 +721,8 @@ setup_avm_pcipnp(struct IsdnCard *card)
cs->cardmsg = &AVM_card_msg; cs->cardmsg = &AVM_card_msg;
cs->card_ops = &avm_pci_ops; cs->card_ops = &avm_pci_ops;
ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:"); ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:");
return (1); return 1;
err:
hisax_release_resources(cs);
return 0;
} }
...@@ -98,14 +98,6 @@ set_ipac_active(struct IsdnCardState *cs, u_int active) ...@@ -98,14 +98,6 @@ set_ipac_active(struct IsdnCardState *cs, u_int active)
ipac_write(cs, IPAC_MASK, active ? 0xc0 : 0xff); ipac_write(cs, IPAC_MASK, active ? 0xc0 : 0xff);
} }
void
release_io_sct_quadro(struct IsdnCardState *cs)
{
release_region(cs->hw.ax.base & 0xffffffc0, 128);
if (cs->subtyp == SCT_1)
release_region(cs->hw.ax.plx_adr, 64);
}
static void static void
enable_bkm_int(struct IsdnCardState *cs, unsigned bEnable) enable_bkm_int(struct IsdnCardState *cs, unsigned bEnable)
{ {
...@@ -162,7 +154,7 @@ bkm_a8_release(struct IsdnCardState *cs) ...@@ -162,7 +154,7 @@ bkm_a8_release(struct IsdnCardState *cs)
{ {
set_ipac_active(cs, 0); set_ipac_active(cs, 0);
enable_bkm_int(cs, 0); enable_bkm_int(cs, 0);
release_io_sct_quadro(cs); hisax_release_resources(cs);
} }
static struct card_ops bkm_a8_ops = { static struct card_ops bkm_a8_ops = {
...@@ -172,18 +164,6 @@ static struct card_ops bkm_a8_ops = { ...@@ -172,18 +164,6 @@ static struct card_ops bkm_a8_ops = {
.irq_func = ipac_irq, .irq_func = ipac_irq,
}; };
int __init
sct_alloc_io(u_int adr, u_int len)
{
if (!request_region(adr, len, "scitel")) {
printk(KERN_WARNING
"HiSax: Scitel port %#x-%#x already in use\n",
adr, adr + len);
return (1);
}
return(0);
}
static struct pci_dev *dev_a8 __initdata = NULL; static struct pci_dev *dev_a8 __initdata = NULL;
static u16 sub_vendor_id __initdata = 0; static u16 sub_vendor_id __initdata = 0;
static u16 sub_sys_id __initdata = 0; static u16 sub_sys_id __initdata = 0;
...@@ -297,25 +277,25 @@ setup_sct_quadro(struct IsdnCard *card) ...@@ -297,25 +277,25 @@ setup_sct_quadro(struct IsdnCard *card)
switch(cs->subtyp) { switch(cs->subtyp) {
case 1: case 1:
cs->hw.ax.base = pci_ioaddr5 + 0x00; cs->hw.ax.base = pci_ioaddr5 + 0x00;
if (sct_alloc_io(pci_ioaddr1, 128)) if (!request_io(&cs->rs, pci_ioaddr1, 128, "scitel"))
return(0); goto err;
if (sct_alloc_io(pci_ioaddr5, 64)) if (!request_io(&cs->rs, pci_ioaddr5, 64, "scitel"))
return(0); goto err;
break; break;
case 2: case 2:
cs->hw.ax.base = pci_ioaddr4 + 0x08; cs->hw.ax.base = pci_ioaddr4 + 0x08;
if (sct_alloc_io(pci_ioaddr4, 64)) if (!request_io(&cs->rs, pci_ioaddr4, 64, "scitel"))
return(0); goto err;
break; break;
case 3: case 3:
cs->hw.ax.base = pci_ioaddr3 + 0x10; cs->hw.ax.base = pci_ioaddr3 + 0x10;
if (sct_alloc_io(pci_ioaddr3, 64)) if (!request_io(&cs->rs, pci_ioaddr3, 64, "scitel"))
return(0); goto err;
break; break;
case 4: case 4:
cs->hw.ax.base = pci_ioaddr2 + 0x20; cs->hw.ax.base = pci_ioaddr2 + 0x20;
if (sct_alloc_io(pci_ioaddr2, 64)) if (!request_io(&cs->rs, pci_ioaddr2, 64, "scitel"))
return(0); goto err;
break; break;
} }
cs->hw.ax.data_adr = cs->hw.ax.base + 4; cs->hw.ax.data_adr = cs->hw.ax.base + 4;
...@@ -338,8 +318,11 @@ setup_sct_quadro(struct IsdnCard *card) ...@@ -338,8 +318,11 @@ setup_sct_quadro(struct IsdnCard *card)
CardType[card->typ], CardType[card->typ],
sct_quadro_subtypes[cs->subtyp], sct_quadro_subtypes[cs->subtyp],
ipac_read(cs, IPAC_ID)); ipac_read(cs, IPAC_ID));
return (1); return 1;
#else #else
printk(KERN_ERR "HiSax: bkm_a8 only supported on PCI Systems\n"); printk(KERN_ERR "HiSax: bkm_a8 only supported on PCI Systems\n");
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
err:
hisax_release_resources(cs);
return 0;
} }
...@@ -945,6 +945,7 @@ static int __devinit checkcard(int cardnr, char *id, int *busy_flag) ...@@ -945,6 +945,7 @@ static int __devinit checkcard(int cardnr, char *id, int *busy_flag)
cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1; cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1;
cs->typ = card->typ; cs->typ = card->typ;
spin_lock_init(&cs->lock); spin_lock_init(&cs->lock);
resources_init(&cs->rs);
SET_MODULE_OWNER(&cs->iif); SET_MODULE_OWNER(&cs->iif);
strcpy(cs->iif.id, id); strcpy(cs->iif.id, id);
cs->iif.channels = 2; cs->iif.channels = 2;
...@@ -2055,6 +2056,100 @@ static void EChannel_proc_rcv(struct hisax_d_if *d_if) ...@@ -2055,6 +2056,100 @@ static void EChannel_proc_rcv(struct hisax_d_if *d_if)
} }
} }
void
resources_init(struct resources *rs)
{
INIT_LIST_HEAD(&rs->res_head);
}
void
resources_release(struct resources *rs)
{
struct res *r;
list_for_each_entry(r, &rs->res_head, node) {
if (r->flags & IORESOURCE_IO) {
release_region(r->start, r->end - r->start + 1);
}
if (r->flags & IORESOURCE_MEM) {
iounmap(r->r_u.ioremap_addr);
release_mem_region(r->start, r->end - r->start + 1);
}
}
}
unsigned long
request_io(struct resources *rs, unsigned long start, int len,
const char *name)
{
struct res *r;
r = kmalloc(sizeof(*r), GFP_KERNEL);
if (!r) {
printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__);
goto err;
}
if (!request_region(start, len, name)) {
printk(KERN_WARNING "%s: IO %#lx-%#lx already in use\n",
__FUNCTION__, start, start + len - 1);
goto err_free;
}
r->flags = IORESOURCE_IO;
r->start = start;
r->end = start + len - 1;
r->name = name;
list_add_tail(&r->node, &rs->res_head);
return r->start;
err_free:
kfree(r);
err:
return 0;
}
void *
request_mmio(struct resources *rs, unsigned long start, int len,
const char *name)
{
struct res *r;
r = kmalloc(sizeof(*r), GFP_KERNEL);
if (!r) {
printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__);
goto err;
}
if (!request_mem_region(start, len, name)) {
printk(KERN_WARNING "%s: MMIO %#lx-%#lx already in use\n",
__FUNCTION__, start, start + len - 1);
goto err_free;
}
r->flags = IORESOURCE_MEM;
r->start = start;
r->end = start + len - 1;
r->name = name;
r->r_u.ioremap_addr = ioremap(start, len);
if (!r->r_u.ioremap_addr)
goto err_release;
list_add_tail(&r->node, &rs->res_head);
return r->r_u.ioremap_addr;
err_release:
release_mem_region(r->start, r->end - r->start + 1);
err_free:
kfree(r);
err:
return 0;
}
void
hisax_resources_release(struct IsdnCardState *cs)
{
resources_release(&cs->rs);
}
#include <linux/pci.h> #include <linux/pci.h>
static struct pci_device_id hisax_pci_tbl[] __initdata = { static struct pci_device_id hisax_pci_tbl[] __initdata = {
......
...@@ -362,25 +362,11 @@ diva_ipacx_pci_irq(int intno, void *dev_id, struct pt_regs *regs) ...@@ -362,25 +362,11 @@ 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)
{ {
int bytecnt;
del_timer(&cs->hw.diva.tl); del_timer(&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 */
if (cs->subtyp == DIVA_ISA) hisax_release_resources(cs);
bytecnt = 8;
else
bytecnt = 32;
if (cs->hw.diva.cfg_reg)
release_region(cs->hw.diva.cfg_reg, bytecnt);
}
static void
diva_ipac_isa_release(struct IsdnCardState *cs)
{
if (cs->hw.diva.cfg_reg)
release_region(cs->hw.diva.cfg_reg, 8);
} }
static void static void
...@@ -561,7 +547,7 @@ static struct card_ops diva_ops = { ...@@ -561,7 +547,7 @@ static struct card_ops diva_ops = {
static struct card_ops diva_ipac_isa_ops = { static struct card_ops diva_ipac_isa_ops = {
.init = ipac_init, .init = ipac_init,
.reset = diva_ipac_isa_reset, .reset = diva_ipac_isa_reset,
.release = diva_ipac_isa_release, .release = hisax_release_resources,
.irq_func = ipac_irq, .irq_func = ipac_irq,
}; };
...@@ -798,16 +784,8 @@ setup_diva(struct IsdnCard *card) ...@@ -798,16 +784,8 @@ setup_diva(struct IsdnCard *card)
cs->hw.diva.pci_cfg); cs->hw.diva.pci_cfg);
if ((cs->subtyp != DIVA_IPAC_PCI) && if ((cs->subtyp != DIVA_IPAC_PCI) &&
(cs->subtyp != DIVA_IPACX_PCI) ) { (cs->subtyp != DIVA_IPACX_PCI) ) {
if (check_region(cs->hw.diva.cfg_reg, bytecnt)) { if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, bytecnt, "diva isdn"))
printk(KERN_WARNING return 0;
"HiSax: %s config port %lx-%lx already in use\n",
CardType[card->typ],
cs->hw.diva.cfg_reg,
cs->hw.diva.cfg_reg + bytecnt);
return (0);
} else {
request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn");
}
} }
cs->cardmsg = &Diva_card_msg; cs->cardmsg = &Diva_card_msg;
if (cs->subtyp == DIVA_IPAC_ISA) { if (cs->subtyp == DIVA_IPAC_ISA) {
......
...@@ -387,8 +387,6 @@ elsa_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs) ...@@ -387,8 +387,6 @@ elsa_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
static void static void
elsa_release(struct IsdnCardState *cs) elsa_release(struct IsdnCardState *cs)
{ {
int bytecnt = 8;
del_timer(&cs->hw.elsa.tl); del_timer(&cs->hw.elsa.tl);
#if ARCOFI_USE #if ARCOFI_USE
clear_arcofi(cs); clear_arcofi(cs);
...@@ -398,28 +396,23 @@ elsa_release(struct IsdnCardState *cs) ...@@ -398,28 +396,23 @@ elsa_release(struct IsdnCardState *cs)
if (cs->subtyp == ELSA_QS1000PCI) { if (cs->subtyp == ELSA_QS1000PCI) {
byteout(cs->hw.elsa.cfg + 0x4c, 0x01); /* disable IRQ */ byteout(cs->hw.elsa.cfg + 0x4c, 0x01); /* disable IRQ */
writereg(cs, cs->hw.elsa.isac, IPAC_ATX, 0xff); writereg(cs, cs->hw.elsa.isac, IPAC_ATX, 0xff);
bytecnt = 2;
release_region(cs->hw.elsa.cfg, 0x80);
} }
if (cs->subtyp == ELSA_QS3000PCI) { if (cs->subtyp == ELSA_QS3000PCI) {
byteout(cs->hw.elsa.cfg + 0x4c, 0x03); /* disable ELSA PCI IRQ */ byteout(cs->hw.elsa.cfg + 0x4c, 0x03); /* disable ELSA PCI IRQ */
writereg(cs, cs->hw.elsa.isac, IPAC_ATX, 0xff); writereg(cs, cs->hw.elsa.isac, IPAC_ATX, 0xff);
release_region(cs->hw.elsa.cfg, 0x80);
} }
if (cs->subtyp == ELSA_PCMCIA_IPAC) { if (cs->subtyp == ELSA_PCMCIA_IPAC) {
writereg(cs, cs->hw.elsa.isac, IPAC_ATX, 0xff); writereg(cs, cs->hw.elsa.isac, IPAC_ATX, 0xff);
} }
#if ARCOFI_USE
if ((cs->subtyp == ELSA_PCFPRO) || if ((cs->subtyp == ELSA_PCFPRO) ||
(cs->subtyp == ELSA_QS3000) || (cs->subtyp == ELSA_QS3000) ||
(cs->subtyp == ELSA_PCF) || (cs->subtyp == ELSA_PCF) ||
(cs->subtyp == ELSA_QS3000PCI)) { (cs->subtyp == ELSA_QS3000PCI)) {
bytecnt = 16;
#if ARCOFI_USE
release_modem(cs); release_modem(cs);
#endif
} }
if (cs->hw.elsa.base) #endif
release_region(cs->hw.elsa.base, bytecnt); hisax_release_resources(cs);
} }
static int static int
...@@ -532,28 +525,14 @@ check_arcofi(struct IsdnCardState *cs) ...@@ -532,28 +525,14 @@ check_arcofi(struct IsdnCardState *cs)
"Elsa: %s detected modem at 0x%lx\n", "Elsa: %s detected modem at 0x%lx\n",
Elsa_Types[cs->subtyp], Elsa_Types[cs->subtyp],
cs->hw.elsa.base+8); cs->hw.elsa.base+8);
release_region(cs->hw.elsa.base, 8); request_io(&cs->rs, cs->hw.elsa.base+8, 8, "elsa isdn modem");
if (!request_region(cs->hw.elsa.base, 16,"elsa isdn modem")) {
printk(KERN_WARNING
"HiSax: %s config port %lx-%lx already in use\n",
Elsa_Types[cs->subtyp],
cs->hw.elsa.base + 8,
cs->hw.elsa.base + 16);
}
} else if (cs->subtyp==ELSA_PCC16) { } else if (cs->subtyp==ELSA_PCC16) {
cs->subtyp = ELSA_PCF; cs->subtyp = ELSA_PCF;
printk(KERN_INFO printk(KERN_INFO
"Elsa: %s detected modem at 0x%lx\n", "Elsa: %s detected modem at 0x%lx\n",
Elsa_Types[cs->subtyp], Elsa_Types[cs->subtyp],
cs->hw.elsa.base+8); cs->hw.elsa.base+8);
release_region(cs->hw.elsa.base, 8); request_io(&cs->rs, cs->hw.elsa.base+8, 8, "elsa isdn modem");
if (!request_region(cs->hw.elsa.base, 16,"elsa isdn modem")) {
printk(KERN_WARNING
"HiSax: %s config port %lx-%lx already in use\n",
Elsa_Types[cs->subtyp],
cs->hw.elsa.base + 8,
cs->hw.elsa.base + 16);
}
} else } else
printk(KERN_INFO printk(KERN_INFO
"Elsa: %s detected modem at 0x%lx\n", "Elsa: %s detected modem at 0x%lx\n",
...@@ -1081,29 +1060,17 @@ setup_elsa(struct IsdnCard *card) ...@@ -1081,29 +1060,17 @@ setup_elsa(struct IsdnCard *card)
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 (cs->typ != ISDN_CTYPE_ELSA_PCMCIA) if (cs->typ != ISDN_CTYPE_ELSA_PCMCIA)
if (!request_region(cs->hw.elsa.base, bytecnt, "elsa isdn")) { if (!request_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn"))
printk(KERN_WARNING goto err;
"HiSax: %s config port %#lx-%#lx already in use\n",
CardType[card->typ], if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI))
cs->hw.elsa.base, if (!request_io(&cs->rs, cs->hw.elsa.cfg, 0x80, "elsa isdn pci"))
cs->hw.elsa.base + bytecnt); goto err;
return (0);
}
if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI)) {
if (!request_region(cs->hw.elsa.cfg, 0x80, "elsa isdn pci")) {
printk(KERN_WARNING
"HiSax: %s pci port %x-%x already in use\n",
CardType[card->typ],
cs->hw.elsa.cfg,
cs->hw.elsa.cfg + 0x80);
release_region(cs->hw.elsa.base, bytecnt);
return (0);
}
}
#if ARCOFI_USE #if ARCOFI_USE
init_arcofi(cs); init_arcofi(cs);
#endif #endif
cs->hw.elsa.tl.function = (void *) elsa_led_handler; cs->hw.elsa.tl.function = (void *) elsa_led_handler;
cs->hw.elsa.tl.data = (long) cs; cs->hw.elsa.tl.data = (long) cs;
init_timer(&cs->hw.elsa.tl); init_timer(&cs->hw.elsa.tl);
...@@ -1116,15 +1083,13 @@ setup_elsa(struct IsdnCard *card) ...@@ -1116,15 +1083,13 @@ setup_elsa(struct IsdnCard *card)
if (!TimerRun(cs)) { if (!TimerRun(cs)) {
printk(KERN_WARNING printk(KERN_WARNING
"Elsa: timer do not start\n"); "Elsa: timer do not start\n");
elsa_release(cs); goto err;
return (0);
} }
} }
HZDELAY(1); /* wait >=10 ms */ HZDELAY(1); /* wait >=10 ms */
if (TimerRun(cs)) { if (TimerRun(cs)) {
printk(KERN_WARNING "Elsa: timer do not run down\n"); printk(KERN_WARNING "Elsa: timer do not run down\n");
elsa_release(cs); goto err;
return (0);
} }
printk(KERN_INFO "Elsa: timer OK; resetting card\n"); printk(KERN_INFO "Elsa: timer OK; resetting card\n");
} }
...@@ -1144,8 +1109,7 @@ setup_elsa(struct IsdnCard *card) ...@@ -1144,8 +1109,7 @@ setup_elsa(struct IsdnCard *card)
if (HscxVersion(cs, "Elsa:")) { if (HscxVersion(cs, "Elsa:")) {
printk(KERN_WARNING printk(KERN_WARNING
"Elsa: wrong HSCX versions check IO address\n"); "Elsa: wrong HSCX versions check IO address\n");
elsa_release(cs); goto err;
return (0);
} }
} }
if (cs->subtyp == ELSA_PC) { if (cs->subtyp == ELSA_PC) {
...@@ -1157,5 +1121,8 @@ setup_elsa(struct IsdnCard *card) ...@@ -1157,5 +1121,8 @@ setup_elsa(struct IsdnCard *card)
writeitac(cs, ITAC_SCIE, 0); writeitac(cs, ITAC_SCIE, 0);
writeitac(cs, ITAC_STIE, 0); writeitac(cs, ITAC_STIE, 0);
} }
return (1); return 1;
err:
elsa_release(cs);
return 0;
} }
...@@ -280,7 +280,6 @@ static struct pci_dev *dev_netjet __initdata = NULL; ...@@ -280,7 +280,6 @@ static struct pci_dev *dev_netjet __initdata = NULL;
int __init int __init
setup_enternow_pci(struct IsdnCard *card) setup_enternow_pci(struct IsdnCard *card)
{ {
int bytecnt;
struct IsdnCardState *cs = card->cs; struct IsdnCardState *cs = card->cs;
char tmp[64]; char tmp[64];
...@@ -359,19 +358,11 @@ setup_enternow_pci(struct IsdnCard *card) ...@@ -359,19 +358,11 @@ setup_enternow_pci(struct IsdnCard *card)
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
bytecnt = 256;
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_region(cs->hw.njet.base, bytecnt, "Fn_ISDN")) { if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "Fn_ISDN"))
printk(KERN_WARNING return 0;
"HiSax: %s config port %lx-%lx already in use\n",
CardType[card->typ],
cs->hw.njet.base,
cs->hw.njet.base + bytecnt);
return (0);
}
reset_enpci(cs); reset_enpci(cs);
cs->hw.njet.last_is0 = 0; cs->hw.njet.last_is0 = 0;
cs->dc_hw_ops = &enternow_ops; cs->dc_hw_ops = &enternow_ops;
...@@ -381,31 +372,5 @@ setup_enternow_pci(struct IsdnCard *card) ...@@ -381,31 +372,5 @@ setup_enternow_pci(struct IsdnCard *card)
cs->irq_flags |= SA_SHIRQ; cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &enpci_ops; cs->card_ops = &enpci_ops;
return (1); return 1;
} }
...@@ -300,127 +300,85 @@ gazel_init(struct IsdnCardState *cs) ...@@ -300,127 +300,85 @@ gazel_init(struct IsdnCardState *cs)
inithscxisac(cs); inithscxisac(cs);
} }
static struct resource *
gazel_request_region(unsigned long start, unsigned long n, const char *name)
{
struct resource *rc = request_region(start, n, name);
if (!rc)
printk(KERN_WARNING "Gazel: io %#lx-%#lx already in use\n",
start, start + n);
return rc;
}
static int static int
r647_reserve_regions(struct IsdnCardState *cs) r647_reserve_regions(struct IsdnCardState *cs)
{ {
int i, base; int i, base = cs->hw.gazel.hscx[0];
base = cs->hw.gazel.hscx[0]; for (i = 0; i < 0xc000; i += 0x1000) {
for (i = 0x0000; i < 0xC000; i += 0x1000) { if (!request_io(&cs->rs, i + base, 16, "gazel"))
if (!gazel_request_region(i + base, 16, "gazel")) { goto err;
for (i -= 0x1000; i >= 0; i -= 0x1000)
release_region (i + base, 16);
return -EBUSY;
}
}
if (!gazel_request_region(0xC000 + base, 1, "gazel")) {
for (i = 0x0000; i < 0xC000; i += 0x1000)
release_region (i + base, 16);
return -EBUSY;
} }
if (!request_io(&cs->rs, 0xc000 + base, 1, "gazel"))
goto err;
return 0; return 0;
} err:
hisax_release_resources(cs);
static void return -EBUSY;
r647_release(struct IsdnCardState *cs)
{
int i;
for (i = 0x0000; i < 0xC000; i += 0x1000)
release_region(i + cs->hw.gazel.hscx[0], 16);
release_region(0xC000 + cs->hw.gazel.hscx[0], 1);
} }
static int static int
r685_reserve_regions(struct IsdnCardState *cs) r685_reserve_regions(struct IsdnCardState *cs)
{ {
if (!gazel_request_region(cs->hw.gazel.hscx[0], 0x100, "gazel")) { if (!request_io(&cs->rs, cs->hw.gazel.hscx[0], 0x100, "gazel"))
return -EBUSY; goto err;
} if (!request_io(&cs->rs, cs->hw.gazel.cfg_reg, 0x80, "gazel"))
if (!gazel_request_region(cs->hw.gazel.cfg_reg, 0x80, "gazel")) { goto err;
release_region (cs->hw.gazel.hscx[0], 0x100);
return -EBUSY;
}
return 0; return 0;
} err:
hisax_release_resources(cs);
static void return -EBUSY;
r685_release(struct IsdnCardState *cs)
{
release_region(cs->hw.gazel.hscx[0], 0x100);
release_region(cs->hw.gazel.cfg_reg, 0x80);
} }
static int static int
r742_reserve_regions(struct IsdnCardState *cs) r742_reserve_regions(struct IsdnCardState *cs)
{ {
if (!gazel_request_region(cs->hw.gazel.ipac, 0x8, "gazel")) if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel"))
return -EBUSY; goto err;
return 0; return 0;
} err:
hisax_release_resources(cs);
static void return -EBUSY;
r742_release(struct IsdnCardState *cs)
{
release_region(cs->hw.gazel.ipac, 8);
} }
static int static int
r753_reserve_regions(struct IsdnCardState *cs) r753_reserve_regions(struct IsdnCardState *cs)
{ {
if (!gazel_request_region(cs->hw.gazel.ipac, 0x8, "gazel")) { if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel"))
return -EBUSY; goto err;
} if (!request_io(&cs->rs, cs->hw.gazel.cfg_reg, 0x80, "gazel"))
if (!gazel_request_region(cs->hw.gazel.cfg_reg, 0x80, "gazel")) { goto err;
release_region (cs->hw.gazel.ipac, 0x8);
return -EBUSY;
}
return 0; return 0;
} err:
hisax_release_resources(cs);
static void return -EBUSY;
r753_release(struct IsdnCardState *cs)
{
release_region(cs->hw.gazel.ipac, 0x8);
release_region(cs->hw.gazel.cfg_reg, 0x80);
} }
static struct card_ops r647_ops = { static struct card_ops r647_ops = {
.init = gazel_init, .init = gazel_init,
.reset = r647_reset, .reset = r647_reset,
.release = r647_release, .release = hisax_release_resources,
.irq_func = hscxisac_irq, .irq_func = hscxisac_irq,
}; };
static struct card_ops r685_ops = { static struct card_ops r685_ops = {
.init = gazel_init, .init = gazel_init,
.reset = r685_reset, .reset = r685_reset,
.release = r685_release, .release = hisax_release_resources,
.irq_func = hscxisac_irq, .irq_func = hscxisac_irq,
}; };
static struct card_ops r742_ops = { static struct card_ops r742_ops = {
.init = ipac_init, .init = ipac_init,
.reset = r742_reset, .reset = r742_reset,
.release = r742_release, .release = hisax_release_resources,
.irq_func = ipac_irq, .irq_func = ipac_irq,
}; };
static struct card_ops r753_ops = { static struct card_ops r753_ops = {
.init = ipac_init, .init = ipac_init,
.reset = r753_reset, .reset = r753_reset,
.release = r753_release, .release = hisax_release_resources,
.irq_func = ipac_irq, .irq_func = ipac_irq,
}; };
......
...@@ -318,7 +318,7 @@ hfcsx_release(struct IsdnCardState *cs) ...@@ -318,7 +318,7 @@ hfcsx_release(struct IsdnCardState *cs)
schedule_timeout((30 * HZ) / 1000); /* Timeout 30ms */ schedule_timeout((30 * HZ) / 1000); /* Timeout 30ms */
Write_hfc(cs, HFCSX_CIRM, 0); /* Reset Off */ Write_hfc(cs, HFCSX_CIRM, 0); /* Reset Off */
del_timer(&cs->hw.hfcsx.timer); del_timer(&cs->hw.hfcsx.timer);
release_region(cs->hw.hfcsx.base, 2); /* release IO-Block */ hisax_release_resources(cs);
kfree(cs->hw.hfcsx.extra); kfree(cs->hw.hfcsx.extra);
cs->hw.hfcsx.extra = NULL; cs->hw.hfcsx.extra = NULL;
} }
...@@ -1236,15 +1236,8 @@ setup_hfcsx(struct IsdnCard *card) ...@@ -1236,15 +1236,8 @@ setup_hfcsx(struct IsdnCard *card)
cs->hw.hfcsx.fifo = 255; cs->hw.hfcsx.fifo = 255;
if ((cs->typ == ISDN_CTYPE_HFC_SX) || if ((cs->typ == ISDN_CTYPE_HFC_SX) ||
(cs->typ == ISDN_CTYPE_HFC_SP_PCMCIA)) { (cs->typ == ISDN_CTYPE_HFC_SP_PCMCIA)) {
if ((!cs->hw.hfcsx.base) || if (!request_io(&cs->rs, cs->hw.hfcsx.base, 2, "HFCSX isdn"))
check_region((cs->hw.hfcsx.base), 2)) { return 0;
printk(KERN_WARNING
"HiSax: HFC-SX io-base %#lx already in use\n",
cs->hw.hfcsx.base);
return(0);
} else {
request_region(cs->hw.hfcsx.base, 2, "HFCSX isdn");
}
byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.base & 0xFF); byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.base & 0xFF);
byteout(cs->hw.hfcsx.base + 1, byteout(cs->hw.hfcsx.base + 1,
((cs->hw.hfcsx.base >> 8) & 3) | 0x54); ((cs->hw.hfcsx.base >> 8) & 3) | 0x54);
...@@ -1258,23 +1251,25 @@ setup_hfcsx(struct IsdnCard *card) ...@@ -1258,23 +1251,25 @@ setup_hfcsx(struct IsdnCard *card)
tmp[0] ='P'; tmp[0] ='P';
break; break;
default: default:
printk(KERN_WARNING printk(KERN_WARNING "HFC-SX: invalid chip id 0x%x\n",
"HFC-SX: invalid chip id 0x%x\n",
cs->hw.hfcsx.chip >> 4); cs->hw.hfcsx.chip >> 4);
release_region(cs->hw.hfcsx.base, 2); hisax_release_resources(cs);
return(0); return 0;
} }
if (!ccd_sp_irqtab[cs->irq & 0xF]) { if (!ccd_sp_irqtab[cs->irq & 0xF]) {
printk(KERN_WARNING printk(KERN_WARNING
"HFC_SX: invalid irq %d specified\n",cs->irq & 0xF); "HFC_SX: invalid irq %d specified\n",
release_region(cs->hw.hfcsx.base, 2); cs->irq & 0xF);
return(0); hisax_release_resources(cs);
return 0;
} }
if (!(cs->hw.hfcsx.extra = (void *) cs->hw.hfcsx.extra = kmalloc(sizeof(struct hfcsx_extra),
kmalloc(sizeof(struct hfcsx_extra), GFP_ATOMIC))) { GFP_ATOMIC);
release_region(cs->hw.hfcsx.base, 2); if (!cs->hw.hfcsx.extra) {
printk(KERN_WARNING "HFC-SX: unable to allocate memory\n"); hisax_release_resources(cs);
return(0); printk(KERN_WARNING
"HFC-SX: unable to allocate memory\n");
return 0;
} }
printk(KERN_INFO printk(KERN_INFO
......
...@@ -69,8 +69,7 @@ hfcs_release(struct IsdnCardState *cs) ...@@ -69,8 +69,7 @@ hfcs_release(struct IsdnCardState *cs)
{ {
release2bds0(cs); release2bds0(cs);
del_timer(&cs->hw.hfcD.timer); del_timer(&cs->hw.hfcD.timer);
if (cs->hw.hfcD.addr) hisax_release_resources(cs);
release_region(cs->hw.hfcD.addr, 2);
} }
static int static int
...@@ -234,16 +233,8 @@ setup_hfcs(struct IsdnCard *card) ...@@ -234,16 +233,8 @@ setup_hfcs(struct IsdnCard *card)
cs->hw.hfcD.bfifosize = 7*1024 + 512; cs->hw.hfcD.bfifosize = 7*1024 + 512;
} else } else
return (0); return (0);
if (check_region((cs->hw.hfcD.addr), 2)) { if (!request_io(&cs->rs, cs->hw.hfcD.addr, 2, "HFCS isdn"))
printk(KERN_WARNING return 0;
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.hfcD.addr,
cs->hw.hfcD.addr + 2);
return (0);
} else {
request_region(cs->hw.hfcD.addr, 2, "HFCS isdn");
}
printk(KERN_INFO printk(KERN_INFO
"HFCS: defined at 0x%x IRQ %d HZ %d\n", "HFCS: defined at 0x%x IRQ %d HZ %d\n",
cs->hw.hfcD.addr, cs->hw.hfcD.addr,
......
...@@ -149,6 +149,35 @@ ...@@ -149,6 +149,35 @@
/* #define I4L_IRQ_FLAG SA_INTERRUPT */ /* #define I4L_IRQ_FLAG SA_INTERRUPT */
#define I4L_IRQ_FLAG 0 #define I4L_IRQ_FLAG 0
struct res {
struct list_head node;
const char *name;
unsigned long start, end;
unsigned long flags;
union {
void *ioremap_addr;
} r_u;
};
struct resources {
struct list_head res_head;
};
void
resources_init(struct resources *rs);
void
resources_release(struct resources *rs);
unsigned long
request_io(struct resources *rs, unsigned long start, int len,
const char *name);
void *
request_mmio(struct resources *rs, unsigned long start, int len,
const char *name);
/* /*
* Statemachine * Statemachine
*/ */
...@@ -563,8 +592,8 @@ struct teles3_hw { ...@@ -563,8 +592,8 @@ struct teles3_hw {
struct teles0_hw { struct teles0_hw {
unsigned int cfg_reg; unsigned int cfg_reg;
unsigned long membase;
unsigned long phymem; unsigned long phymem;
void *membase;
}; };
struct avm_hw { struct avm_hw {
...@@ -730,9 +759,8 @@ struct hfcD_hw { ...@@ -730,9 +759,8 @@ struct hfcD_hw {
struct isurf_hw { struct isurf_hw {
unsigned int reset; unsigned int reset;
unsigned long phymem; void *isac;
unsigned long isac; void *isar;
unsigned long isar;
struct isar_reg isar_r; struct isar_reg isar_r;
}; };
...@@ -919,6 +947,7 @@ struct IsdnCardState { ...@@ -919,6 +947,7 @@ struct IsdnCardState {
spinlock_t lock; spinlock_t lock;
struct card_ops *card_ops; struct card_ops *card_ops;
int protocol; int protocol;
struct resources rs;
unsigned int irq; unsigned int irq;
unsigned long irq_flags; unsigned long irq_flags;
long HW_Flags; long HW_Flags;
...@@ -994,6 +1023,9 @@ struct IsdnCardState { ...@@ -994,6 +1023,9 @@ struct IsdnCardState {
#endif #endif
}; };
void
hisax_release_resources(struct IsdnCardState *cs);
#define MON0_RX 1 #define MON0_RX 1
#define MON1_RX 2 #define MON1_RX 2
#define MON0_TX 4 #define MON0_TX 4
...@@ -1437,4 +1469,5 @@ L4L3(struct PStack *st, int pr, void *arg) ...@@ -1437,4 +1469,5 @@ L4L3(struct PStack *st, int pr, void *arg)
st->l3.l4l3(st, pr, arg); st->l3.l4l3(st, pr, arg);
} }
#endif #endif
...@@ -132,14 +132,6 @@ isurf_interrupt(int intno, void *dev_id, struct pt_regs *regs) ...@@ -132,14 +132,6 @@ isurf_interrupt(int intno, void *dev_id, struct pt_regs *regs)
spin_unlock(&cs->lock); spin_unlock(&cs->lock);
} }
static void
isurf_release(struct IsdnCardState *cs)
{
release_region(cs->hw.isurf.reset, 1);
iounmap((unsigned char *)cs->hw.isurf.isar);
release_mem_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE);
}
static void static void
reset_isurf(struct IsdnCardState *cs, u8 chips) reset_isurf(struct IsdnCardState *cs, u8 chips)
{ {
...@@ -193,7 +185,7 @@ isurf_reset(struct IsdnCardState *cs) ...@@ -193,7 +185,7 @@ isurf_reset(struct IsdnCardState *cs)
static struct card_ops isurf_ops = { static struct card_ops isurf_ops = {
.init = isurf_init, .init = isurf_init,
.reset = isurf_reset, .reset = isurf_reset,
.release = isurf_release, .release = hisax_release_resources,
.irq_func = isurf_interrupt, .irq_func = isurf_interrupt,
}; };
...@@ -215,7 +207,6 @@ setup_isurf(struct IsdnCard *card) ...@@ -215,7 +207,6 @@ setup_isurf(struct IsdnCard *card)
return(0); return(0);
if (card->para[1] && card->para[2]) { if (card->para[1] && card->para[2]) {
cs->hw.isurf.reset = card->para[1]; cs->hw.isurf.reset = card->para[1];
cs->hw.isurf.phymem = card->para[2];
cs->irq = card->para[0]; cs->irq = card->para[0];
} else { } else {
#ifdef __ISAPNP__ #ifdef __ISAPNP__
...@@ -261,32 +252,17 @@ setup_isurf(struct IsdnCard *card) ...@@ -261,32 +252,17 @@ setup_isurf(struct IsdnCard *card)
return (0); return (0);
#endif #endif
} }
if (!request_region(cs->hw.isurf.reset, 1, "isurf isdn")) { if (!request_io(&cs->rs, cs->hw.isurf.reset, 1, "isurf isdn"))
printk(KERN_WARNING goto err;
"HiSax: %s config port %x already in use\n", cs->hw.isurf.isar = request_mmio(&cs->rs, card->para[2], ISURF_IOMEM_SIZE, "isurf iomem");
CardType[card->typ], if (!cs->hw.isurf.isar)
cs->hw.isurf.reset); goto err;
return (0);
}
if (check_mem_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE)) {
printk(KERN_WARNING
"HiSax: %s memory region %lx-%lx already in use\n",
CardType[card->typ],
cs->hw.isurf.phymem,
cs->hw.isurf.phymem + ISURF_IOMEM_SIZE);
release_region(cs->hw.isurf.reset, 1);
return (0);
} else {
request_mem_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE,
"isurf iomem");
}
cs->hw.isurf.isar =
(unsigned long) ioremap(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE);
cs->hw.isurf.isac = cs->hw.isurf.isar + ISURF_ISAC_OFFSET; cs->hw.isurf.isac = cs->hw.isurf.isar + ISURF_ISAC_OFFSET;
printk(KERN_INFO printk(KERN_INFO
"ISurf: defined at 0x%x 0x%lx IRQ %d\n", "ISurf: defined at 0x%x 0x%lx IRQ %d\n",
cs->hw.isurf.reset, cs->hw.isurf.reset,
cs->hw.isurf.phymem, card->para[2],
cs->irq); cs->irq);
cs->cardmsg = &ISurf_card_msg; cs->cardmsg = &ISurf_card_msg;
...@@ -303,8 +279,11 @@ setup_isurf(struct IsdnCard *card) ...@@ -303,8 +279,11 @@ setup_isurf(struct IsdnCard *card)
if (ver < 0) { if (ver < 0) {
printk(KERN_WARNING printk(KERN_WARNING
"ISurf: wrong ISAR version (ret = %d)\n", ver); "ISurf: wrong ISAR version (ret = %d)\n", ver);
isurf_release(cs); goto err;
return (0);
} }
return (1); return 1;
err:
hisax_release_resources(cs);
return 0;
} }
...@@ -140,13 +140,6 @@ static struct bc_hw_ops hscx_ops = { ...@@ -140,13 +140,6 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo, .write_fifo = hscx_write_fifo,
}; };
static void
ix1_release(struct IsdnCardState *cs)
{
if (cs->hw.ix1.cfg_reg)
release_region(cs->hw.ix1.cfg_reg, 4);
}
static int static int
ix1_reset(struct IsdnCardState *cs) ix1_reset(struct IsdnCardState *cs)
{ {
...@@ -171,7 +164,7 @@ ix1_card_msg(struct IsdnCardState *cs, int mt, void *arg) ...@@ -171,7 +164,7 @@ ix1_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static struct card_ops ix1_ops = { static struct card_ops ix1_ops = {
.init = inithscxisac, .init = inithscxisac,
.reset = ix1_reset, .reset = ix1_reset,
.release = ix1_release, .release = hisax_release_resources,
.irq_func = hscxisac_irq, .irq_func = hscxisac_irq,
}; };
...@@ -247,17 +240,9 @@ setup_ix1micro(struct IsdnCard *card) ...@@ -247,17 +240,9 @@ setup_ix1micro(struct IsdnCard *card)
cs->hw.ix1.hscx = card->para[1] + HSCX_DATA_OFFSET; cs->hw.ix1.hscx = card->para[1] + HSCX_DATA_OFFSET;
cs->hw.ix1.cfg_reg = card->para[1]; cs->hw.ix1.cfg_reg = card->para[1];
cs->irq = card->para[0]; cs->irq = card->para[0];
if (cs->hw.ix1.cfg_reg) { if (!request_io(&cs->rs, cs->hw.ix1.cfg_reg, 4, "ix1micro cfg"))
if (check_region((cs->hw.ix1.cfg_reg), 4)) { goto err;
printk(KERN_WARNING
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.ix1.cfg_reg,
cs->hw.ix1.cfg_reg + 4);
return (0);
} else
request_region(cs->hw.ix1.cfg_reg, 4, "ix1micro cfg");
}
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, CardType[cs->typ], cs->irq,
...@@ -271,8 +256,10 @@ setup_ix1micro(struct IsdnCard *card) ...@@ -271,8 +256,10 @@ setup_ix1micro(struct IsdnCard *card)
if (HscxVersion(cs, "ix1-Micro:")) { if (HscxVersion(cs, "ix1-Micro:")) {
printk(KERN_WARNING printk(KERN_WARNING
"ix1-Micro: wrong HSCX versions check IO address\n"); "ix1-Micro: wrong HSCX versions check IO address\n");
ix1_release(cs); goto err;
return (0);
} }
return (1); return 1;
err:
hisax_release_resources(cs);
return 0;
} }
...@@ -132,13 +132,6 @@ static struct bc_hw_ops hscx_ops = { ...@@ -132,13 +132,6 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo, .write_fifo = hscx_write_fifo,
}; };
static void
mic_release(struct IsdnCardState *cs)
{
if (cs->hw.mic.cfg_reg)
release_region(cs->hw.mic.cfg_reg, 8);
}
static int static int
mic_card_msg(struct IsdnCardState *cs, int mt, void *arg) mic_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{ {
...@@ -147,14 +140,13 @@ mic_card_msg(struct IsdnCardState *cs, int mt, void *arg) ...@@ -147,14 +140,13 @@ mic_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static struct card_ops mic_ops = { static struct card_ops mic_ops = {
.init = inithscxisac, .init = inithscxisac,
.release = mic_release, .release = hisax_release_resources,
.irq_func = hscxisac_irq, .irq_func = hscxisac_irq,
}; };
int __init int __init
setup_mic(struct IsdnCard *card) setup_mic(struct IsdnCard *card)
{ {
int bytecnt;
struct IsdnCardState *cs = card->cs; struct IsdnCardState *cs = card->cs;
char tmp[64]; char tmp[64];
...@@ -163,21 +155,14 @@ setup_mic(struct IsdnCard *card) ...@@ -163,21 +155,14 @@ setup_mic(struct IsdnCard *card)
if (cs->typ != ISDN_CTYPE_MIC) if (cs->typ != ISDN_CTYPE_MIC)
return (0); return (0);
bytecnt = 8;
cs->hw.mic.cfg_reg = card->para[1]; cs->hw.mic.cfg_reg = card->para[1];
cs->irq = card->para[0]; cs->irq = card->para[0];
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;
if (!request_region((cs->hw.mic.cfg_reg), bytecnt, "mic isdn")) { if (!request_io(&cs->rs, cs->hw.mic.cfg_reg, 8, "mic isdn"))
printk(KERN_WARNING goto err;
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.mic.cfg_reg,
cs->hw.mic.cfg_reg + bytecnt);
return (0);
}
printk(KERN_INFO printk(KERN_INFO
"mic: defined at 0x%x IRQ %d\n", "mic: defined at 0x%x IRQ %d\n",
...@@ -191,8 +176,10 @@ setup_mic(struct IsdnCard *card) ...@@ -191,8 +176,10 @@ setup_mic(struct IsdnCard *card)
if (HscxVersion(cs, "mic:")) { if (HscxVersion(cs, "mic:")) {
printk(KERN_WARNING printk(KERN_WARNING
"mic: wrong HSCX versions check IO address\n"); "mic: wrong HSCX versions check IO address\n");
mic_release(cs); goto err;
return (0);
} }
return (1); return 1;
err:
hisax_release_resources(cs);
return 0;
} }
...@@ -1029,6 +1029,6 @@ netjet_release(struct IsdnCardState *cs) ...@@ -1029,6 +1029,6 @@ netjet_release(struct IsdnCardState *cs)
byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0); byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0); byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0);
releasetiger(cs); releasetiger(cs);
release_region(cs->hw.njet.base, 256); hisax_release_resources(cs);
} }
...@@ -175,12 +175,8 @@ niccy_release(struct IsdnCardState *cs) ...@@ -175,12 +175,8 @@ niccy_release(struct IsdnCardState *cs)
val = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); val = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
val &= PCI_IRQ_DISABLE; val &= PCI_IRQ_DISABLE;
outl(val, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG); outl(val, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
release_region(cs->hw.niccy.cfg_reg, 0x40);
release_region(cs->hw.niccy.isac, 4);
} else {
release_region(cs->hw.niccy.isac, 2);
release_region(cs->hw.niccy.isac_ale, 2);
} }
hisax_release_resources(cs);
} }
static int static int
...@@ -265,23 +261,10 @@ setup_niccy(struct IsdnCard *card) ...@@ -265,23 +261,10 @@ setup_niccy(struct IsdnCard *card)
cs->hw.niccy.cfg_reg = 0; cs->hw.niccy.cfg_reg = 0;
cs->subtyp = NICCY_PNP; cs->subtyp = NICCY_PNP;
cs->irq = card->para[0]; cs->irq = card->para[0];
if (!request_region(cs->hw.niccy.isac, 2, "niccy data")) { if (!request_io(&cs->rs, cs->hw.niccy.isac, 2, "niccy data"))
printk(KERN_WARNING goto err;
"HiSax: %s data port %x-%x already in use\n", if (!request_io(&cs->rs, cs->hw.niccy.isac_ale, 2, "niccy addr"))
CardType[card->typ], goto err;
cs->hw.niccy.isac,
cs->hw.niccy.isac + 1);
return (0);
}
if (!request_region(cs->hw.niccy.isac_ale, 2, "niccy addr")) {
printk(KERN_WARNING
"HiSax: %s address port %x-%x already in use\n",
CardType[card->typ],
cs->hw.niccy.isac_ale,
cs->hw.niccy.isac_ale + 1);
release_region(cs->hw.niccy.isac, 2);
return (0);
}
} else { } else {
#if CONFIG_PCI #if CONFIG_PCI
u_int pci_ioaddr; u_int pci_ioaddr;
...@@ -320,23 +303,11 @@ setup_niccy(struct IsdnCard *card) ...@@ -320,23 +303,11 @@ setup_niccy(struct IsdnCard *card)
cs->hw.niccy.isac_ale = pci_ioaddr + ISAC_PCI_ADDR; cs->hw.niccy.isac_ale = pci_ioaddr + ISAC_PCI_ADDR;
cs->hw.niccy.hscx = pci_ioaddr + HSCX_PCI_DATA; cs->hw.niccy.hscx = pci_ioaddr + HSCX_PCI_DATA;
cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR; cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR;
if (!request_region(cs->hw.niccy.isac, 4, "niccy")) {
printk(KERN_WARNING if (!request_io(&cs->rs, cs->hw.niccy.isac, 4, "niccy"))
"HiSax: %s data port %x-%x already in use\n", goto err;
CardType[card->typ], if (!request_io(&cs->rs, cs->hw.niccy.cfg_reg, 0x40, "niccy pci"))
cs->hw.niccy.isac, goto err;
cs->hw.niccy.isac + 4);
return (0);
}
if (!request_region(cs->hw.niccy.cfg_reg, 0x40, "niccy pci")) {
printk(KERN_WARNING
"HiSax: %s pci port %x-%x already in use\n",
CardType[card->typ],
cs->hw.niccy.cfg_reg,
cs->hw.niccy.cfg_reg + 0x40);
release_region(cs->hw.niccy.isac, 4);
return (0);
}
#else #else
printk(KERN_WARNING "Niccy: io0 0 and NO_PCI_BIOS\n"); printk(KERN_WARNING "Niccy: io0 0 and NO_PCI_BIOS\n");
printk(KERN_WARNING "Niccy: unable to config NICCY PCI\n"); printk(KERN_WARNING "Niccy: unable to config NICCY PCI\n");
...@@ -355,8 +326,9 @@ setup_niccy(struct IsdnCard *card) ...@@ -355,8 +326,9 @@ setup_niccy(struct IsdnCard *card)
if (HscxVersion(cs, "Niccy:")) { if (HscxVersion(cs, "Niccy:")) {
printk(KERN_WARNING printk(KERN_WARNING
"Niccy: wrong HSCX versions check IO address\n"); "Niccy: wrong HSCX versions check IO address\n");
niccy_release(cs);
return (0);
} }
return (1); return 1;
err:
niccy_release(cs);
return 0;
} }
...@@ -117,7 +117,6 @@ static struct pci_dev *dev_netjet __initdata = NULL; ...@@ -117,7 +117,6 @@ static struct pci_dev *dev_netjet __initdata = NULL;
int __init int __init
setup_netjet_s(struct IsdnCard *card) setup_netjet_s(struct IsdnCard *card)
{ {
int bytecnt;
struct IsdnCardState *cs = card->cs; struct IsdnCardState *cs = card->cs;
char tmp[64]; char tmp[64];
...@@ -211,26 +210,17 @@ setup_netjet_s(struct IsdnCard *card) ...@@ -211,26 +210,17 @@ setup_netjet_s(struct IsdnCard *card)
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
bytecnt = 256;
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 (check_region(cs->hw.njet.base, bytecnt)) { if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn"))
printk(KERN_WARNING return 0;
"HiSax: %s config port %#lx-%#lx already in use\n",
CardType[card->typ],
cs->hw.njet.base,
cs->hw.njet.base + bytecnt);
return (0);
} else {
request_region(cs->hw.njet.base, bytecnt, "netjet-s isdn");
}
nj_s_reset(cs); nj_s_reset(cs);
cs->dc_hw_ops = &netjet_dc_ops; cs->dc_hw_ops = &netjet_dc_ops;
cs->cardmsg = &NETjet_S_card_msg; cs->cardmsg = &NETjet_S_card_msg;
cs->irq_flags |= SA_SHIRQ; cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &nj_s_ops; cs->card_ops = &nj_s_ops;
ISACVersion(cs, "NETjet-S:"); ISACVersion(cs, "NETjet-S:");
return (1); return 1;
} }
...@@ -121,7 +121,6 @@ static struct pci_dev *dev_netjet __initdata = NULL; ...@@ -121,7 +121,6 @@ static struct pci_dev *dev_netjet __initdata = NULL;
int __init int __init
setup_netjet_u(struct IsdnCard *card) setup_netjet_u(struct IsdnCard *card)
{ {
int bytecnt;
struct IsdnCardState *cs = card->cs; struct IsdnCardState *cs = card->cs;
char tmp[64]; char tmp[64];
#if CONFIG_PCI #if CONFIG_PCI
...@@ -209,24 +208,17 @@ setup_netjet_u(struct IsdnCard *card) ...@@ -209,24 +208,17 @@ setup_netjet_u(struct IsdnCard *card)
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
bytecnt = 256;
printk(KERN_INFO printk(KERN_INFO
"NETspider-U: PCI card configured at %#lx IRQ %d\n", "NETspider-U: PCI card configured at %#lx IRQ %d\n",
cs->hw.njet.base, cs->irq); cs->hw.njet.base, cs->irq);
if (!request_region(cs->hw.njet.base, bytecnt, "netspider-u isdn")) { if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn"))
printk(KERN_WARNING return 0;
"HiSax: %s config port %#lx-%#lx already in use\n",
CardType[card->typ],
cs->hw.njet.base,
cs->hw.njet.base + bytecnt);
return (0);
}
nj_u_reset(cs); nj_u_reset(cs);
cs->dc_hw_ops = &netjet_dc_ops; cs->dc_hw_ops = &netjet_dc_ops;
cs->cardmsg = &NETjet_U_card_msg; cs->cardmsg = &NETjet_U_card_msg;
cs->irq_flags |= SA_SHIRQ; cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &nj_u_ops; cs->card_ops = &nj_u_ops;
ICCVersion(cs, "NETspider-U:"); ICCVersion(cs, "NETspider-U:");
return (1); return 1;
} }
...@@ -166,12 +166,6 @@ static struct bc_hw_ops hscx_ops = { ...@@ -166,12 +166,6 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo, .write_fifo = hscx_write_fifo,
}; };
void
s0box_release(struct IsdnCardState *cs)
{
release_region(cs->hw.teles3.cfg_reg, 8);
}
static int static int
S0Box_card_msg(struct IsdnCardState *cs, int mt, void *arg) S0Box_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{ {
...@@ -180,7 +174,7 @@ S0Box_card_msg(struct IsdnCardState *cs, int mt, void *arg) ...@@ -180,7 +174,7 @@ S0Box_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static struct card_ops s0box_ops = { static struct card_ops s0box_ops = {
.init = inithscxisac, .init = inithscxisac,
.release = s0box_release, .release = hisax_release_resources,
.irq_func = hscxisac_irq, .irq_func = hscxisac_irq,
}; };
...@@ -203,14 +197,8 @@ setup_s0box(struct IsdnCard *card) ...@@ -203,14 +197,8 @@ setup_s0box(struct IsdnCard *card)
cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e; cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e;
cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e; cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e;
cs->irq = card->para[0]; cs->irq = card->para[0];
if (!request_region(cs->hw.teles3.cfg_reg,8, "S0Box parallel I/O")) { if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 8, "S0Box parallel I/O"))
printk(KERN_WARNING goto err;
"HiSax: %s ports %x-%x already in use\n",
CardType[cs->typ],
cs->hw.teles3.cfg_reg,
cs->hw.teles3.cfg_reg + 7);
return 0;
}
printk(KERN_INFO printk(KERN_INFO
"HiSax: %s config irq:%d isac:0x%x cfg:0x%x\n", "HiSax: %s config irq:%d isac:0x%x cfg:0x%x\n",
CardType[cs->typ], cs->irq, CardType[cs->typ], cs->irq,
...@@ -226,8 +214,10 @@ setup_s0box(struct IsdnCard *card) ...@@ -226,8 +214,10 @@ setup_s0box(struct IsdnCard *card)
if (HscxVersion(cs, "S0Box:")) { if (HscxVersion(cs, "S0Box:")) {
printk(KERN_WARNING printk(KERN_WARNING
"S0Box: wrong HSCX versions check IO address\n"); "S0Box: wrong HSCX versions check IO address\n");
s0box_release(cs); goto err;
return (0);
} }
return (1); return 1;
err:
hisax_release_resources(cs);
return 0;
} }
...@@ -155,8 +155,7 @@ saphir_release(struct IsdnCardState *cs) ...@@ -155,8 +155,7 @@ saphir_release(struct IsdnCardState *cs)
byteout(cs->hw.saphir.cfg_reg + IRQ_REG, 0xff); byteout(cs->hw.saphir.cfg_reg + IRQ_REG, 0xff);
del_timer_sync(&cs->hw.saphir.timer); del_timer_sync(&cs->hw.saphir.timer);
cs->hw.saphir.timer.function = NULL; cs->hw.saphir.timer.function = NULL;
if (cs->hw.saphir.cfg_reg) hisax_release_resources(cs);
release_region(cs->hw.saphir.cfg_reg, 6);
} }
static int static int
...@@ -219,20 +218,15 @@ setup_saphir(struct IsdnCard *card) ...@@ -219,20 +218,15 @@ setup_saphir(struct IsdnCard *card)
if (cs->typ != ISDN_CTYPE_HSTSAPHIR) if (cs->typ != ISDN_CTYPE_HSTSAPHIR)
return (0); return (0);
init_timer(&cs->hw.saphir.timer);
/* IO-Ports */ /* 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_region((cs->hw.saphir.cfg_reg), 6, "saphir")) { if (!request_io(&cs->rs, cs->hw.saphir.cfg_reg, 6, "saphir"))
printk(KERN_WARNING goto err;
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.saphir.cfg_reg,
cs->hw.saphir.cfg_reg + 5);
return (0);
}
printk(KERN_INFO printk(KERN_INFO
"HiSax: %s config irq:%d io:0x%X\n", "HiSax: %s config irq:%d io:0x%X\n",
...@@ -241,12 +235,10 @@ setup_saphir(struct IsdnCard *card) ...@@ -241,12 +235,10 @@ setup_saphir(struct IsdnCard *card)
cs->hw.saphir.timer.function = (void *) SaphirWatchDog; cs->hw.saphir.timer.function = (void *) SaphirWatchDog;
cs->hw.saphir.timer.data = (long) cs; cs->hw.saphir.timer.data = (long) cs;
init_timer(&cs->hw.saphir.timer);
cs->hw.saphir.timer.expires = jiffies + 4*HZ; cs->hw.saphir.timer.expires = jiffies + 4*HZ;
add_timer(&cs->hw.saphir.timer); add_timer(&cs->hw.saphir.timer);
if (saphir_reset(cs)) { if (saphir_reset(cs)) {
saphir_release(cs); goto err;
return (0);
} }
cs->dc_hw_ops = &isac_ops; cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops; cs->bc_hw_ops = &hscx_ops;
...@@ -256,8 +248,10 @@ setup_saphir(struct IsdnCard *card) ...@@ -256,8 +248,10 @@ setup_saphir(struct IsdnCard *card)
if (HscxVersion(cs, "saphir:")) { if (HscxVersion(cs, "saphir:")) {
printk(KERN_WARNING printk(KERN_WARNING
"saphir: wrong HSCX versions check IO address\n"); "saphir: wrong HSCX versions check IO address\n");
saphir_release(cs); goto err;
return (0);
} }
return (1); return 1;
err:
saphir_release(cs);
return 0;
} }
...@@ -390,20 +390,6 @@ sedlbauer_reset(struct IsdnCardState *cs) ...@@ -390,20 +390,6 @@ sedlbauer_reset(struct IsdnCardState *cs)
return 0; return 0;
} }
static void
sedlbauer_release(struct IsdnCardState *cs)
{
int bytecnt = 8;
if (cs->subtyp == SEDL_SPEED_FAX) {
bytecnt = 16;
} else if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
bytecnt = 256;
}
if (cs->hw.sedl.cfg_reg)
release_region(cs->hw.sedl.cfg_reg, bytecnt);
}
static void static void
sedlbauer_isar_release(struct IsdnCardState *cs) sedlbauer_isar_release(struct IsdnCardState *cs)
{ {
...@@ -412,7 +398,7 @@ sedlbauer_isar_release(struct IsdnCardState *cs) ...@@ -412,7 +398,7 @@ sedlbauer_isar_release(struct IsdnCardState *cs)
sedlbauer_reset(cs); sedlbauer_reset(cs);
isar_write(cs, 0, ISAR_IRQBIT, 0); isar_write(cs, 0, ISAR_IRQBIT, 0);
isac_write(cs, ISAC_MASK, 0xFF); isac_write(cs, ISAC_MASK, 0xFF);
sedlbauer_release(cs); hisax_release_resources(cs);
} }
static int static int
...@@ -452,14 +438,14 @@ sedlbauer_isar_init(struct IsdnCardState *cs) ...@@ -452,14 +438,14 @@ sedlbauer_isar_init(struct IsdnCardState *cs)
static struct card_ops sedlbauer_ops = { static struct card_ops sedlbauer_ops = {
.init = inithscxisac, .init = inithscxisac,
.reset = sedlbauer_reset, .reset = sedlbauer_reset,
.release = sedlbauer_release, .release = hisax_release_resources,
.irq_func = sedlbauer_interrupt, .irq_func = sedlbauer_interrupt,
}; };
static struct card_ops sedlbauer_ipac_ops = { static struct card_ops sedlbauer_ipac_ops = {
.init = ipac_init, .init = ipac_init,
.reset = sedlbauer_reset, .reset = sedlbauer_reset,
.release = sedlbauer_release, .release = hisax_release_resources,
.irq_func = ipac_irq, .irq_func = ipac_irq,
}; };
...@@ -546,7 +532,7 @@ setup_sedlbauer(struct IsdnCard *card) ...@@ -546,7 +532,7 @@ setup_sedlbauer(struct IsdnCard *card)
printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n", printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n",
card->para[0], card->para[1]); card->para[0], card->para[1]);
pd->deactivate(pd); pd->deactivate(pd);
return(0); goto err;
} }
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];
...@@ -561,7 +547,7 @@ setup_sedlbauer(struct IsdnCard *card) ...@@ -561,7 +547,7 @@ setup_sedlbauer(struct IsdnCard *card)
goto ready; 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");
return(0); goto err;
} }
} }
pdev++; pdev++;
...@@ -576,21 +562,21 @@ setup_sedlbauer(struct IsdnCard *card) ...@@ -576,21 +562,21 @@ setup_sedlbauer(struct IsdnCard *card)
#if CONFIG_PCI #if CONFIG_PCI
if (!pci_present()) { if (!pci_present()) {
printk(KERN_ERR "Sedlbauer: no PCI bus present\n"); printk(KERN_ERR "Sedlbauer: no PCI bus present\n");
return(0); goto err;
} }
if ((dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET, if ((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 (pci_enable_device(dev_sedl))
return(0); goto err;
cs->irq = dev_sedl->irq; cs->irq = dev_sedl->irq;
if (!cs->irq) { if (!cs->irq) {
printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n"); printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n");
return(0); goto err;
} }
cs->hw.sedl.cfg_reg = pci_resource_start(dev_sedl, 0); cs->hw.sedl.cfg_reg = pci_resource_start(dev_sedl, 0);
} else { } else {
printk(KERN_WARNING "Sedlbauer: No PCI card found\n"); printk(KERN_WARNING "Sedlbauer: No PCI card found\n");
return(0); goto err;
} }
cs->irq_flags |= SA_SHIRQ; cs->irq_flags |= SA_SHIRQ;
cs->hw.sedl.bus = SEDL_BUS_PCI; cs->hw.sedl.bus = SEDL_BUS_PCI;
...@@ -602,7 +588,7 @@ setup_sedlbauer(struct IsdnCard *card) ...@@ -602,7 +588,7 @@ setup_sedlbauer(struct IsdnCard *card)
cs->hw.sedl.cfg_reg); 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);
return(0); goto err;
} }
if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) { if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) {
cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR; cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
...@@ -616,7 +602,7 @@ setup_sedlbauer(struct IsdnCard *card) ...@@ -616,7 +602,7 @@ setup_sedlbauer(struct IsdnCard *card)
} else { } else {
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);
return(0); goto err;
} }
bytecnt = 256; bytecnt = 256;
cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON; cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON;
...@@ -631,7 +617,7 @@ setup_sedlbauer(struct IsdnCard *card) ...@@ -631,7 +617,7 @@ setup_sedlbauer(struct IsdnCard *card)
byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off); byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
#else #else
printk(KERN_WARNING "Sedlbauer: NO_PCI_BIOS\n"); printk(KERN_WARNING "Sedlbauer: NO_PCI_BIOS\n");
return (0); goto err;
#endif /* CONFIG_PCI */ #endif /* CONFIG_PCI */
} }
ready: ready:
...@@ -639,14 +625,9 @@ setup_sedlbauer(struct IsdnCard *card) ...@@ -639,14 +625,9 @@ setup_sedlbauer(struct IsdnCard *card)
* 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 (cs->hw.sedl.bus != SEDL_BUS_PCMCIA && if (cs->hw.sedl.bus != SEDL_BUS_PCMCIA) {
(!request_region((cs->hw.sedl.cfg_reg), bytecnt, "sedlbauer isdn"))) { if (!request_io(&cs->rs, cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn"))
printk(KERN_WARNING goto err;
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.sedl.cfg_reg,
cs->hw.sedl.cfg_reg + bytecnt);
return (0);
} }
printk(KERN_INFO printk(KERN_INFO
...@@ -740,8 +721,7 @@ setup_sedlbauer(struct IsdnCard *card) ...@@ -740,8 +721,7 @@ setup_sedlbauer(struct IsdnCard *card)
if (ver < 0) { if (ver < 0) {
printk(KERN_WARNING printk(KERN_WARNING
"Sedlbauer: wrong ISAR version (ret = %d)\n", ver); "Sedlbauer: wrong ISAR version (ret = %d)\n", ver);
sedlbauer_release(cs); goto err;
return (0);
} }
} else { } else {
if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) { if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
...@@ -764,11 +744,13 @@ setup_sedlbauer(struct IsdnCard *card) ...@@ -764,11 +744,13 @@ setup_sedlbauer(struct IsdnCard *card)
if (HscxVersion(cs, "Sedlbauer:")) { if (HscxVersion(cs, "Sedlbauer:")) {
printk(KERN_WARNING printk(KERN_WARNING
"Sedlbauer: wrong HSCX versions check IO address\n"); "Sedlbauer: wrong HSCX versions check IO address\n");
sedlbauer_release(cs); goto err;
return (0);
} }
sedlbauer_reset(cs); sedlbauer_reset(cs);
} }
} }
return (1); return 1;
err:
hisax_release_resources(cs);
return 0;
} }
...@@ -170,7 +170,7 @@ static struct card_ops sportster_ops = { ...@@ -170,7 +170,7 @@ static struct card_ops sportster_ops = {
static int __init static int __init
get_io_range(struct IsdnCardState *cs) get_io_range(struct IsdnCardState *cs)
{ {
int i, j, adr; int i, adr;
for (i=0;i<64;i++) { for (i=0;i<64;i++) {
adr = cs->hw.spt.cfg_reg + i *1024; adr = cs->hw.spt.cfg_reg + i *1024;
...@@ -178,18 +178,16 @@ get_io_range(struct IsdnCardState *cs) ...@@ -178,18 +178,16 @@ get_io_range(struct IsdnCardState *cs)
printk(KERN_WARNING printk(KERN_WARNING
"HiSax: %s config port %x-%x already in use\n", "HiSax: %s config port %x-%x already in use\n",
CardType[cs->typ], adr, adr + 8); CardType[cs->typ], adr, adr + 8);
break; goto err;
} }
} }
if (i==64) return 1;
return(1); err:
else { for (i=i-1; i >= 0; i--) {
for (j=0; j<i; j++) { adr = cs->hw.spt.cfg_reg + i *1024;
adr = cs->hw.spt.cfg_reg + j *1024;
release_region(adr, 8); release_region(adr, 8);
} }
return(0); return 0;
}
} }
int __init int __init
......
...@@ -222,8 +222,7 @@ teleint_release(struct IsdnCardState *cs) ...@@ -222,8 +222,7 @@ teleint_release(struct IsdnCardState *cs)
{ {
del_timer(&cs->hw.hfc.timer); del_timer(&cs->hw.hfc.timer);
releasehfc(cs); releasehfc(cs);
if (cs->hw.hfc.addr) hisax_release_resources(cs);
release_region(cs->hw.hfc.addr, 2);
} }
static int static int
...@@ -286,16 +285,9 @@ setup_TeleInt(struct IsdnCard *card) ...@@ -286,16 +285,9 @@ setup_TeleInt(struct IsdnCard *card)
cs->hw.hfc.timer.function = (void *) TeleInt_Timer; cs->hw.hfc.timer.function = (void *) TeleInt_Timer;
cs->hw.hfc.timer.data = (long) cs; cs->hw.hfc.timer.data = (long) cs;
init_timer(&cs->hw.hfc.timer); init_timer(&cs->hw.hfc.timer);
if (check_region((cs->hw.hfc.addr), 2)) { if (!request_io(&cs->rs, cs->hw.hfc.addr, 2, "TeleInt isdn"))
printk(KERN_WARNING goto err;
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.hfc.addr,
cs->hw.hfc.addr + 2);
return (0);
} else {
request_region(cs->hw.hfc.addr, 2, "TeleInt isdn");
}
/* HW IO = IO */ /* HW IO = IO */
byteout(cs->hw.hfc.addr, cs->hw.hfc.addr & 0xff); byteout(cs->hw.hfc.addr, cs->hw.hfc.addr & 0xff);
byteout(cs->hw.hfc.addr | 1, ((cs->hw.hfc.addr & 0x300) >> 8) | 0x54); byteout(cs->hw.hfc.addr | 1, ((cs->hw.hfc.addr & 0x300) >> 8) | 0x54);
...@@ -320,8 +312,7 @@ setup_TeleInt(struct IsdnCard *card) ...@@ -320,8 +312,7 @@ setup_TeleInt(struct IsdnCard *card)
break; break;
default: default:
printk(KERN_WARNING "TeleInt: wrong IRQ\n"); printk(KERN_WARNING "TeleInt: wrong IRQ\n");
teleint_release(cs); goto err;
return (0);
} }
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);
...@@ -337,5 +328,8 @@ setup_TeleInt(struct IsdnCard *card) ...@@ -337,5 +328,8 @@ setup_TeleInt(struct IsdnCard *card)
cs->cardmsg = &TeleInt_card_msg; cs->cardmsg = &TeleInt_card_msg;
cs->card_ops = &teleint_ops; cs->card_ops = &teleint_ops;
ISACVersion(cs, "TeleInt:"); ISACVersion(cs, "TeleInt:");
return (1); return 1;
err:
teleint_release(cs);
return 0;
} }
...@@ -48,7 +48,7 @@ static void ...@@ -48,7 +48,7 @@ static void
isac_read_fifo(struct IsdnCardState *cs, u8 * data, int size) isac_read_fifo(struct IsdnCardState *cs, u8 * data, int size)
{ {
int i; int i;
unsigned long ad = cs->hw.teles0.membase + 0x100; void *ad = cs->hw.teles0.membase + 0x100;
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
data[i] = readb(ad); data[i] = readb(ad);
} }
...@@ -57,7 +57,7 @@ static void ...@@ -57,7 +57,7 @@ static void
isac_write_fifo(struct IsdnCardState *cs, u8 * data, int size) isac_write_fifo(struct IsdnCardState *cs, u8 * data, int size)
{ {
int i; int i;
unsigned long ad = cs->hw.teles0.membase + 0x100; void *ad = cs->hw.teles0.membase + 0x100;
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
writeb(data[i], ad); mb(); writeb(data[i], ad); mb();
} }
...@@ -88,7 +88,7 @@ static void ...@@ -88,7 +88,7 @@ static void
hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size) hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size)
{ {
int i; int i;
unsigned long ad = cs->hw.teles0.membase + (hscx ? 0x1c0 : 0x180); void *ad = cs->hw.teles0.membase + (hscx ? 0x1c0 : 0x180);
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
data[i] = readb(ad); data[i] = readb(ad);
} }
...@@ -97,7 +97,7 @@ static void ...@@ -97,7 +97,7 @@ static void
hscx_write_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size) hscx_write_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size)
{ {
int i; int i;
unsigned long ad = cs->hw.teles0.membase + (hscx ? 0x1c0 : 0x180); void *ad = cs->hw.teles0.membase + (hscx ? 0x1c0 : 0x180);
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
writeb(data[i], ad); writeb(data[i], ad);
} }
...@@ -110,15 +110,6 @@ static struct bc_hw_ops hscx_ops = { ...@@ -110,15 +110,6 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo, .write_fifo = hscx_write_fifo,
}; };
static void
teles0_release(struct IsdnCardState *cs)
{
if (cs->hw.teles0.cfg_reg)
release_region(cs->hw.teles0.cfg_reg, 8);
iounmap((unsigned char *)cs->hw.teles0.membase);
release_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE);
}
static int static int
teles0_reset(struct IsdnCardState *cs) teles0_reset(struct IsdnCardState *cs)
{ {
...@@ -176,7 +167,7 @@ Teles_card_msg(struct IsdnCardState *cs, int mt, void *arg) ...@@ -176,7 +167,7 @@ Teles_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static struct card_ops teles0_ops = { static struct card_ops teles0_ops = {
.init = inithscxisac, .init = inithscxisac,
.reset = teles0_reset, .reset = teles0_reset,
.release = teles0_release, .release = hisax_release_resources,
.irq_func = hscxisac_irq, .irq_func = hscxisac_irq,
}; };
...@@ -205,65 +196,43 @@ setup_teles0(struct IsdnCard *card) ...@@ -205,65 +196,43 @@ setup_teles0(struct IsdnCard *card)
} }
cs->irq = card->para[0]; cs->irq = card->para[0];
if (cs->hw.teles0.cfg_reg) { if (cs->hw.teles0.cfg_reg) {
if (!request_region(cs->hw.teles0.cfg_reg, 8, "teles cfg")) { if (!request_io(&cs->rs, cs->hw.teles0.cfg_reg, 8, "teles cfg"))
printk(KERN_WARNING goto err;
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.teles0.cfg_reg,
cs->hw.teles0.cfg_reg + 8);
return (0);
}
}
if (cs->hw.teles0.cfg_reg) {
if ((val = bytein(cs->hw.teles0.cfg_reg + 0)) != 0x51) { if ((val = bytein(cs->hw.teles0.cfg_reg + 0)) != 0x51) {
printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n", printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
cs->hw.teles0.cfg_reg + 0, val); cs->hw.teles0.cfg_reg + 0, val);
release_region(cs->hw.teles0.cfg_reg, 8); goto err;
return (0);
} }
if ((val = bytein(cs->hw.teles0.cfg_reg + 1)) != 0x93) { if ((val = bytein(cs->hw.teles0.cfg_reg + 1)) != 0x93) {
printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n", printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
cs->hw.teles0.cfg_reg + 1, val); cs->hw.teles0.cfg_reg + 1, val);
release_region(cs->hw.teles0.cfg_reg, 8); goto err;
return (0);
} }
val = bytein(cs->hw.teles0.cfg_reg + 2); /* 0x1e=without AB val = bytein(cs->hw.teles0.cfg_reg + 2);/* 0x1e=without AB
* 0x1f=with AB * 0x1f=with AB
* 0x1c 16.3 ??? * 0x1c 16.3 ???
*/ */
if (val != 0x1e && val != 0x1f) { if (val != 0x1e && val != 0x1f) {
printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n", printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
cs->hw.teles0.cfg_reg + 2, val); cs->hw.teles0.cfg_reg + 2, val);
release_region(cs->hw.teles0.cfg_reg, 8); goto err;
return (0);
} }
} }
/* 16.0 and 8.0 designed for IOM1 */ /* 16.0 and 8.0 designed for IOM1 */
test_and_set_bit(HW_IOM1, &cs->HW_Flags); test_and_set_bit(HW_IOM1, &cs->HW_Flags);
cs->hw.teles0.phymem = card->para[1]; cs->hw.teles0.phymem = card->para[1];
if (check_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE)) { cs->hw.teles0.membase = request_mmio(&cs->rs, cs->hw.teles0.phymem, TELES_IOMEM_SIZE, "teles iomem");
printk(KERN_WARNING if (!cs->hw.teles0.membase)
"HiSax: %s memory region %lx-%lx already in use\n", goto err;
CardType[card->typ],
cs->hw.teles0.phymem,
cs->hw.teles0.phymem + TELES_IOMEM_SIZE);
if (cs->hw.teles0.cfg_reg)
release_region(cs->hw.teles0.cfg_reg, 8);
return (0);
} else {
request_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE,
"teles iomem");
}
cs->hw.teles0.membase =
(unsigned long) ioremap(cs->hw.teles0.phymem, TELES_IOMEM_SIZE);
printk(KERN_INFO printk(KERN_INFO
"HiSax: %s config irq:%d mem:0x%lX cfg:0x%X\n", "HiSax: %s config irq:%d mem:0x%p cfg:0x%X\n",
CardType[cs->typ], cs->irq, CardType[cs->typ], cs->irq,
cs->hw.teles0.membase, cs->hw.teles0.cfg_reg); cs->hw.teles0.membase, cs->hw.teles0.cfg_reg);
if (teles0_reset(cs)) { if (teles0_reset(cs)) {
printk(KERN_WARNING "Teles0: wrong IRQ\n"); printk(KERN_WARNING "Teles0: wrong IRQ\n");
teles0_release(cs); goto err;
return (0);
} }
cs->dc_hw_ops = &isac_ops; cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops; cs->bc_hw_ops = &hscx_ops;
...@@ -273,8 +242,11 @@ setup_teles0(struct IsdnCard *card) ...@@ -273,8 +242,11 @@ setup_teles0(struct IsdnCard *card)
if (HscxVersion(cs, "Teles0:")) { if (HscxVersion(cs, "Teles0:")) {
printk(KERN_WARNING printk(KERN_WARNING
"Teles0: wrong HSCX versions check IO/MEM addresses\n"); "Teles0: wrong HSCX versions check IO/MEM addresses\n");
teles0_release(cs); goto err;
return (0);
} }
return (1); return (1);
err:
hisax_release_resources(cs);
return 0;
} }
...@@ -113,34 +113,6 @@ static struct bc_hw_ops hscx_ops = { ...@@ -113,34 +113,6 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo, .write_fifo = hscx_write_fifo,
}; };
inline static void
release_ioregs(struct IsdnCardState *cs, int mask)
{
if (mask & 1)
release_region(cs->hw.teles3.isac + 32, 32);
if (mask & 2)
release_region(cs->hw.teles3.hscx[0] + 32, 32);
if (mask & 4)
release_region(cs->hw.teles3.hscx[1] + 32, 32);
}
static void
teles3_release(struct IsdnCardState *cs)
{
if (cs->typ == ISDN_CTYPE_TELESPCMCIA) {
release_region(cs->hw.teles3.hscx[1], 96);
} else {
if (cs->hw.teles3.cfg_reg) {
if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
release_region(cs->hw.teles3.cfg_reg, 1);
} else {
release_region(cs->hw.teles3.cfg_reg, 8);
}
}
release_ioregs(cs, 0x7);
}
}
static int static int
teles3_reset(struct IsdnCardState *cs) teles3_reset(struct IsdnCardState *cs)
{ {
...@@ -206,7 +178,7 @@ Teles_card_msg(struct IsdnCardState *cs, int mt, void *arg) ...@@ -206,7 +178,7 @@ Teles_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static struct card_ops teles3_ops = { static struct card_ops teles3_ops = {
.init = inithscxisac, .init = inithscxisac,
.reset = teles3_reset, .reset = teles3_reset,
.release = teles3_release, .release = hisax_release_resources,
.irq_func = hscxisac_irq, .irq_func = hscxisac_irq,
}; };
...@@ -315,95 +287,35 @@ setup_teles3(struct IsdnCard *card) ...@@ -315,95 +287,35 @@ setup_teles3(struct IsdnCard *card)
cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e; cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e;
cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e; cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e;
if (cs->typ == ISDN_CTYPE_TELESPCMCIA) { if (cs->typ == ISDN_CTYPE_TELESPCMCIA) {
if (!request_region(cs->hw.teles3.hscx[1], 96, "HiSax Teles PCMCIA")) { if (!request_io(&cs->rs, cs->hw.teles3.hscx[1], 96, "HiSax Teles PCMCIA"))
printk(KERN_WARNING goto err;
"HiSax: %s ports %x-%x already in use\n",
CardType[cs->typ],
cs->hw.teles3.hscx[1],
cs->hw.teles3.hscx[1] + 96);
return (0);
}
} else { } else {
if (cs->hw.teles3.cfg_reg) { if (cs->hw.teles3.cfg_reg) {
if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
if (!request_region(cs->hw.teles3.cfg_reg, 1, "teles3 cfg")) { if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 1, "teles3 cfg"))
printk(KERN_WARNING goto err;
"HiSax: %s config port %x already in use\n",
CardType[card->typ],
cs->hw.teles3.cfg_reg);
return (0);
}
} else { } else {
if (!request_region(cs->hw.teles3.cfg_reg, 8, "teles3 cfg")) { if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 8, "teles3 cfg"))
printk(KERN_WARNING goto err;
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.teles3.cfg_reg,
cs->hw.teles3.cfg_reg + 8);
return (0);
} }
} }
} if (!request_io(&cs->rs, cs->hw.teles3.isac + 32, 32, "HiSax isac"))
if (!request_region(cs->hw.teles3.isac + 32, 32, "HiSax isac")) { goto err;
printk(KERN_WARNING if (!request_io(&cs->rs, cs->hw.teles3.hscx[0] + 32, 32, "HiSax hscx A"))
"HiSax: %s isac ports %x-%x already in use\n", goto err;
CardType[cs->typ], if (!request_io(&cs->rs, cs->hw.teles3.hscx[1] + 32, 32, "HiSax hscx B"))
cs->hw.teles3.isac + 32, goto err;
cs->hw.teles3.isac + 64);
if (cs->hw.teles3.cfg_reg) {
if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
release_region(cs->hw.teles3.cfg_reg, 1);
} else {
release_region(cs->hw.teles3.cfg_reg, 8);
}
}
return (0);
}
if (!request_region(cs->hw.teles3.hscx[0] + 32, 32, "HiSax hscx A")) {
printk(KERN_WARNING
"HiSax: %s hscx A ports %x-%x already in use\n",
CardType[cs->typ],
cs->hw.teles3.hscx[0] + 32,
cs->hw.teles3.hscx[0] + 64);
if (cs->hw.teles3.cfg_reg) {
if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
release_region(cs->hw.teles3.cfg_reg, 1);
} else {
release_region(cs->hw.teles3.cfg_reg, 8);
}
}
release_ioregs(cs, 1);
return (0);
}
if (!request_region(cs->hw.teles3.hscx[1] + 32, 32, "HiSax hscx B")) {
printk(KERN_WARNING
"HiSax: %s hscx B ports %x-%x already in use\n",
CardType[cs->typ],
cs->hw.teles3.hscx[1] + 32,
cs->hw.teles3.hscx[1] + 64);
if (cs->hw.teles3.cfg_reg) {
if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
release_region(cs->hw.teles3.cfg_reg, 1);
} else {
release_region(cs->hw.teles3.cfg_reg, 8);
}
}
release_ioregs(cs, 3);
return (0);
}
} }
if ((cs->hw.teles3.cfg_reg) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA)) { if ((cs->hw.teles3.cfg_reg) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA)) {
if ((val = bytein(cs->hw.teles3.cfg_reg + 0)) != 0x51) { if ((val = bytein(cs->hw.teles3.cfg_reg + 0)) != 0x51) {
printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n", printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n",
cs->hw.teles3.cfg_reg + 0, val); cs->hw.teles3.cfg_reg + 0, val);
teles3_release(cs); goto err;
return (0);
} }
if ((val = bytein(cs->hw.teles3.cfg_reg + 1)) != 0x93) { if ((val = bytein(cs->hw.teles3.cfg_reg + 1)) != 0x93) {
printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n", printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n",
cs->hw.teles3.cfg_reg + 1, val); cs->hw.teles3.cfg_reg + 1, val);
teles3_release(cs); goto err;
return (0);
} }
val = bytein(cs->hw.teles3.cfg_reg + 2);/* 0x1e=without AB val = bytein(cs->hw.teles3.cfg_reg + 2);/* 0x1e=without AB
* 0x1f=with AB * 0x1f=with AB
...@@ -415,8 +327,7 @@ setup_teles3(struct IsdnCard *card) ...@@ -415,8 +327,7 @@ setup_teles3(struct IsdnCard *card)
if (val != 0x46 && val != 0x39 && val != 0x38 && val != 0x1c && val != 0x1e && val != 0x1f) { 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", printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n",
cs->hw.teles3.cfg_reg + 2, val); cs->hw.teles3.cfg_reg + 2, val);
teles3_release(cs); goto err;
return (0);
} }
} }
printk(KERN_INFO printk(KERN_INFO
...@@ -429,8 +340,7 @@ setup_teles3(struct IsdnCard *card) ...@@ -429,8 +340,7 @@ setup_teles3(struct IsdnCard *card)
if (teles3_reset(cs)) { if (teles3_reset(cs)) {
printk(KERN_WARNING "Teles3: wrong IRQ\n"); printk(KERN_WARNING "Teles3: wrong IRQ\n");
teles3_release(cs); goto err;
return (0);
} }
cs->dc_hw_ops = &isac_ops; cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops; cs->bc_hw_ops = &hscx_ops;
...@@ -440,8 +350,11 @@ setup_teles3(struct IsdnCard *card) ...@@ -440,8 +350,11 @@ setup_teles3(struct IsdnCard *card)
if (HscxVersion(cs, "Teles3:")) { if (HscxVersion(cs, "Teles3:")) {
printk(KERN_WARNING printk(KERN_WARNING
"Teles3: wrong HSCX versions check IO address\n"); "Teles3: wrong HSCX versions check IO address\n");
teles3_release(cs); goto err;
return (0);
} }
return (1); return (1);
err:
hisax_release_resources(cs);
return (0);
} }
...@@ -45,7 +45,7 @@ const char *telespci_revision = "$Revision: 2.16.6.5 $"; ...@@ -45,7 +45,7 @@ const char *telespci_revision = "$Revision: 2.16.6.5 $";
static u8 static u8
isac_read(struct IsdnCardState *cs, u8 off) isac_read(struct IsdnCardState *cs, u8 off)
{ {
unsigned long adr = cs->hw.teles0.membase + 0x200; void *adr = cs->hw.teles0.membase + 0x200;
unsigned int portdata; unsigned int portdata;
ZORAN_WAIT_NOBUSY; ZORAN_WAIT_NOBUSY;
...@@ -63,7 +63,7 @@ isac_read(struct IsdnCardState *cs, u8 off) ...@@ -63,7 +63,7 @@ isac_read(struct IsdnCardState *cs, u8 off)
static void static void
isac_write(struct IsdnCardState *cs, u8 off, u8 data) isac_write(struct IsdnCardState *cs, u8 off, u8 data)
{ {
unsigned long adr = cs->hw.teles0.membase + 0x200; void *adr = cs->hw.teles0.membase + 0x200;
unsigned int portdata; unsigned int portdata;
ZORAN_WAIT_NOBUSY; ZORAN_WAIT_NOBUSY;
...@@ -80,7 +80,7 @@ isac_write(struct IsdnCardState *cs, u8 off, u8 data) ...@@ -80,7 +80,7 @@ isac_write(struct IsdnCardState *cs, u8 off, u8 data)
static void static void
isac_read_fifo(struct IsdnCardState *cs, u8 *data, int size) isac_read_fifo(struct IsdnCardState *cs, u8 *data, int size)
{ {
unsigned long adr = cs->hw.teles0.membase + 0x200; void *adr = cs->hw.teles0.membase + 0x200;
unsigned int portdata; unsigned int portdata;
int i; int i;
...@@ -99,7 +99,7 @@ isac_read_fifo(struct IsdnCardState *cs, u8 *data, int size) ...@@ -99,7 +99,7 @@ isac_read_fifo(struct IsdnCardState *cs, u8 *data, int size)
static void static void
isac_write_fifo(struct IsdnCardState *cs, u8 *data, int size) isac_write_fifo(struct IsdnCardState *cs, u8 *data, int size)
{ {
unsigned long adr = cs->hw.teles0.membase + 0x200; void *adr = cs->hw.teles0.membase + 0x200;
unsigned int portdata; unsigned int portdata;
int i; int i;
...@@ -124,7 +124,7 @@ static struct dc_hw_ops isac_ops = { ...@@ -124,7 +124,7 @@ static struct dc_hw_ops isac_ops = {
static u8 static u8
hscx_read(struct IsdnCardState *cs, int hscx, u8 off) hscx_read(struct IsdnCardState *cs, int hscx, u8 off)
{ {
unsigned long adr = cs->hw.teles0.membase + 0x200; void *adr = cs->hw.teles0.membase + 0x200;
unsigned int portdata; unsigned int portdata;
ZORAN_WAIT_NOBUSY; ZORAN_WAIT_NOBUSY;
...@@ -141,7 +141,7 @@ hscx_read(struct IsdnCardState *cs, int hscx, u8 off) ...@@ -141,7 +141,7 @@ hscx_read(struct IsdnCardState *cs, int hscx, u8 off)
static void static void
hscx_write(struct IsdnCardState *cs, int hscx, u8 off, u8 data) hscx_write(struct IsdnCardState *cs, int hscx, u8 off, u8 data)
{ {
unsigned long adr = cs->hw.teles0.membase + 0x200; void *adr = cs->hw.teles0.membase + 0x200;
unsigned int portdata; unsigned int portdata;
ZORAN_WAIT_NOBUSY; ZORAN_WAIT_NOBUSY;
...@@ -157,7 +157,7 @@ hscx_write(struct IsdnCardState *cs, int hscx, u8 off, u8 data) ...@@ -157,7 +157,7 @@ hscx_write(struct IsdnCardState *cs, int hscx, u8 off, u8 data)
static void static void
hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 * data, int size) hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 * data, int size)
{ {
unsigned long adr = cs->hw.teles0.membase + 0x200; void *adr = cs->hw.teles0.membase + 0x200;
unsigned int portdata; unsigned int portdata;
int i; int i;
...@@ -176,7 +176,7 @@ hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 * data, int size) ...@@ -176,7 +176,7 @@ hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 * data, int size)
static void static void
hscx_write_fifo(struct IsdnCardState *cs, int hscx, u8 * data, int size) hscx_write_fifo(struct IsdnCardState *cs, int hscx, u8 * data, int size)
{ {
unsigned long adr = cs->hw.teles0.membase + 0x200; void *adr = cs->hw.teles0.membase + 0x200;
unsigned int portdata; unsigned int portdata;
int i; int i;
...@@ -271,7 +271,7 @@ setup_telespci(struct IsdnCard *card) ...@@ -271,7 +271,7 @@ setup_telespci(struct IsdnCard *card)
printk(KERN_WARNING "Teles: No IRQ for PCI card found\n"); printk(KERN_WARNING "Teles: No IRQ for PCI card found\n");
return(0); return(0);
} }
cs->hw.teles0.membase = (u_long) ioremap(pci_resource_start(dev_tel, 0), cs->hw.teles0.membase = ioremap(pci_resource_start(dev_tel, 0),
PAGE_SIZE); PAGE_SIZE);
printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n", printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n",
pci_resource_start(dev_tel, 0), dev_tel->irq); pci_resource_start(dev_tel, 0), dev_tel->irq);
...@@ -295,7 +295,7 @@ setup_telespci(struct IsdnCard *card) ...@@ -295,7 +295,7 @@ setup_telespci(struct IsdnCard *card)
/* writel(0x00800000, cs->hw.teles0.membase + 0x200); */ /* writel(0x00800000, cs->hw.teles0.membase + 0x200); */
printk(KERN_INFO printk(KERN_INFO
"HiSax: %s config irq:%d mem:%lx\n", "HiSax: %s config irq:%d mem:%p\n",
CardType[cs->typ], cs->irq, CardType[cs->typ], cs->irq,
cs->hw.teles0.membase); cs->hw.teles0.membase);
......
...@@ -639,9 +639,9 @@ static void ...@@ -639,9 +639,9 @@ static void
w6692_release(struct IsdnCardState *cs) w6692_release(struct IsdnCardState *cs)
{ {
w6692_write_reg(cs, W_IMASK, 0xff); w6692_write_reg(cs, W_IMASK, 0xff);
release_region(cs->hw.w6692.iobase, 256);
if (cs->subtyp == W6692_USR) if (cs->subtyp == W6692_USR)
w6692_write_reg(cs, W_XDATA, 0x04); w6692_write_reg(cs, W_XDATA, 0x04);
hisax_release_resources(cs);
} }
static int static int
...@@ -738,15 +738,9 @@ setup_w6692(struct IsdnCard *card) ...@@ -738,15 +738,9 @@ setup_w6692(struct IsdnCard *card)
printk(KERN_INFO "Found: %s %s, I/O base: 0x%x, irq: %d\n", 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, id_list[cs->subtyp].vendor_name, id_list[cs->subtyp].card_name,
pci_ioaddr, pci_irq); pci_ioaddr, pci_irq);
if (!request_region((cs->hw.w6692.iobase), 256, if (!request_io(&cs->rs, cs->hw.w6692.iobase, 0x100, id_list[cs->subtyp].card_name))
id_list[cs->subtyp].card_name)) { return 0;
printk(KERN_WARNING
"HiSax: %s I/O ports %x-%x already in use\n",
id_list[cs->subtyp].card_name,
cs->hw.w6692.iobase,
cs->hw.w6692.iobase + 255);
return (0);
}
#else #else
printk(KERN_WARNING "HiSax: W6692 and NO_PCI_BIOS\n"); printk(KERN_WARNING "HiSax: W6692 and NO_PCI_BIOS\n");
printk(KERN_WARNING "HiSax: W6692 unable to config\n"); printk(KERN_WARNING "HiSax: W6692 unable to config\n");
......
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