]> git.neil.brown.name Git - history.git/commitdiff
ISDN/HiSax: Simplified request_region() etc.
authorKai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
Sun, 12 Jan 2003 11:53:28 +0000 (05:53 -0600)
committerKai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
Sun, 12 Jan 2003 11:53:28 +0000 (05:53 -0600)
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.

28 files changed:
drivers/isdn/hisax/asuscom.c
drivers/isdn/hisax/avm_a1.c
drivers/isdn/hisax/avm_pci.c
drivers/isdn/hisax/bkm_a8.c
drivers/isdn/hisax/config.c
drivers/isdn/hisax/diva.c
drivers/isdn/hisax/elsa.c
drivers/isdn/hisax/enternow_pci.c
drivers/isdn/hisax/gazel.c
drivers/isdn/hisax/hfc_sx.c
drivers/isdn/hisax/hfcscard.c
drivers/isdn/hisax/hisax.h
drivers/isdn/hisax/isurf.c
drivers/isdn/hisax/ix1_micro.c
drivers/isdn/hisax/mic.c
drivers/isdn/hisax/netjet.c
drivers/isdn/hisax/niccy.c
drivers/isdn/hisax/nj_s.c
drivers/isdn/hisax/nj_u.c
drivers/isdn/hisax/s0box.c
drivers/isdn/hisax/saphir.c
drivers/isdn/hisax/sedlbauer.c
drivers/isdn/hisax/sportster.c
drivers/isdn/hisax/teleint.c
drivers/isdn/hisax/teles0.c
drivers/isdn/hisax/teles3.c
drivers/isdn/hisax/telespci.c
drivers/isdn/hisax/w6692.c

index 84c146ba72b45609bc52f0b386d45dfcf5cfea45..8dc380e98dfa60754f0c95de653870c2d4df6d96 100644 (file)
@@ -188,13 +188,6 @@ ipac_writefifo(struct IsdnCardState *cs, u8 off, u8 * data, int size)
 
 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
 asuscom_reset(struct IsdnCardState *cs)
 {
@@ -233,14 +226,14 @@ Asus_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 static struct card_ops asuscom_ops = {
        .init     = inithscxisac,
        .reset    = asuscom_reset,
-       .release  = asuscom_release,
+       .release  = hisax_release_resources,
        .irq_func = hscxisac_irq,
 };
 
 static struct card_ops asuscom_ipac_ops = {
        .init     = ipac_init,
        .reset    = asuscom_ipac_reset,
-       .release  = asuscom_release,
+       .release  = hisax_release_resources,
        .irq_func = ipac_irq,
 };
 
@@ -319,15 +312,8 @@ setup_asuscom(struct IsdnCard *card)
        bytecnt = 8;
        cs->hw.asus.cfg_reg = card->para[1];
        cs->irq = card->para[0];
-       if (!request_region((cs->hw.asus.cfg_reg), bytecnt,
-                           "asuscom isdn")) {
-               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);
-       }
+       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->cardmsg = &Asus_card_msg;
@@ -355,11 +341,13 @@ setup_asuscom(struct IsdnCard *card)
                if (HscxVersion(cs, "ISDNLink:")) {
                        printk(KERN_WARNING
                        "ISDNLink: wrong HSCX versions check IO address\n");
-                       asuscom_release(cs);
-                       return (0);
+                       goto err;
                }
        }
        printk(KERN_INFO "ISDNLink: resetting card\n");
        cs->card_ops->reset(cs);
-       return (1);
+       return 1;
+ err:
+       hisax_release_resources(cs);
+       return 0;
 }
index 06b3c6c90e952a92cb225b3f3800c646f3bc7f3e..5e352d5edc1c7554720a36f597550d64f95bfb7b 100644 (file)
@@ -146,24 +146,6 @@ avm_a1_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        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
 AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 {
@@ -178,15 +160,9 @@ avm_a1_init(struct IsdnCardState *cs)
        inithscxisac(cs);
 }
 
-static void
-avm_a1_release(struct IsdnCardState *cs)
-{
-       release_ioregs(cs, 0x3f);
-}
-
 static struct card_ops avm_a1_ops = {
        .init     = avm_a1_init,
-       .release  = avm_a1_release,
+       .release  = hisax_release_resources,
        .irq_func = avm_a1_interrupt,
 };
 
@@ -202,73 +178,25 @@ setup_avm_a1(struct IsdnCard *card)
        if (cs->typ != ISDN_CTYPE_A1)
                return (0);
 
-       cs->hw.avm.cfg_reg = card->para[1] + 0x1800;
-       cs->hw.avm.isac = card->para[1] + 0x1400 - 0x20;
-       cs->hw.avm.hscx[0] = card->para[1] + 0x400 - 0x20;
-       cs->hw.avm.hscx[1] = card->para[1] + 0xc00 - 0x20;
-       cs->hw.avm.isacfifo = card->para[1] + 0x1000;
-       cs->hw.avm.hscxfifo[0] = card->para[1];
-       cs->hw.avm.hscxfifo[1] = card->para[1] + 0x800;
+       cs->hw.avm.cfg_reg     = request_io(&cs->rs, card->para[1] + 0x1800,  8, "avm cfg");
+       if (!cs->hw.avm.cfg_reg) goto err;
+       cs->hw.avm.isac        = request_io(&cs->rs, card->para[1] + 0x1400, 32, "HiSax isac");
+       if (!cs->hw.avm.isac) goto err;
+       cs->hw.avm.isacfifo    = request_io(&cs->rs, card->para[1] + 0x1000,  1, "HiSax isac fifo");
+       if (!cs->hw.avm.isacfifo) goto err;
+       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];
-       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);
        HZDELAY(HZ / 5 + 1);
        byteout(cs->hw.avm.cfg_reg, 0x1);
@@ -316,8 +244,10 @@ setup_avm_a1(struct IsdnCard *card)
        if (HscxVersion(cs, "AVM A1:")) {
                printk(KERN_WARNING
                       "AVM A1: wrong HSCX versions check IO address\n");
-               release_ioregs(cs, 0x3f);
-               return (0);
+               goto err;
        }
-       return (1);
+       return 1;
+ err:
+       hisax_release_resources(cs);
+       return 0;
 }
index 42b9d2fe45c8ff3d3a9adf8aba06964332d42390..3dd6c8b148d639591cd28efba2501e52d249b78a 100644 (file)
@@ -592,7 +592,7 @@ static void
 avm_pcipnp_release(struct IsdnCardState *cs)
 {
        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 = {
@@ -693,15 +693,10 @@ setup_avm_pcipnp(struct IsdnCard *card)
        }
 ready:
        cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10;
-       if (!request_region((cs->hw.avm.cfg_reg), 32, (cs->subtyp == AVM_FRITZ_PCI)
-                        ? "avm PCI" : "avm PnP")) {
-               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 + 31);
-               return (0);
-       }
+       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);
@@ -726,5 +721,8 @@ ready:
        cs->cardmsg = &AVM_card_msg;
        cs->card_ops = &avm_pci_ops;
        ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:");
-       return (1);
+       return 1;
+ err:
+       hisax_release_resources(cs);
+       return 0;
 }
index 64233fcba1eee8022fafe2edcf5a5b14cc6739d3..fa564a74a3c56d3d44826241d1f09c0a997b816a 100644 (file)
@@ -98,14 +98,6 @@ set_ipac_active(struct IsdnCardState *cs, u_int active)
        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
 enable_bkm_int(struct IsdnCardState *cs, unsigned bEnable)
 {
@@ -162,7 +154,7 @@ bkm_a8_release(struct IsdnCardState *cs)
 {
        set_ipac_active(cs, 0);
        enable_bkm_int(cs, 0);
-       release_io_sct_quadro(cs);
+       hisax_release_resources(cs);
 }
 
 static struct card_ops bkm_a8_ops = {
@@ -172,18 +164,6 @@ static struct card_ops bkm_a8_ops = {
        .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 u16  sub_vendor_id __initdata = 0;
 static u16  sub_sys_id __initdata = 0;
@@ -295,28 +275,28 @@ setup_sct_quadro(struct IsdnCard *card)
        cs->hw.ax.plx_adr = pci_ioaddr1;
        /* Enter all ipac_base addresses */
        switch(cs->subtyp) {
-               case 1:
-                       cs->hw.ax.base = pci_ioaddr5 + 0x00;
-                       if (sct_alloc_io(pci_ioaddr1, 128))
-                               return(0);
-                       if (sct_alloc_io(pci_ioaddr5, 64))
-                               return(0);
-                       break;
-               case 2:
-                       cs->hw.ax.base = pci_ioaddr4 + 0x08;
-                       if (sct_alloc_io(pci_ioaddr4, 64))
-                               return(0);
-                       break;
-               case 3:
-                       cs->hw.ax.base = pci_ioaddr3 + 0x10;
-                       if (sct_alloc_io(pci_ioaddr3, 64))
-                               return(0);
-                       break;
-               case 4:
-                       cs->hw.ax.base = pci_ioaddr2 + 0x20;
-                       if (sct_alloc_io(pci_ioaddr2, 64))
-                               return(0);
-                       break;
+       case 1:
+               cs->hw.ax.base = pci_ioaddr5 + 0x00;
+               if (!request_io(&cs->rs, pci_ioaddr1, 128, "scitel"))
+                       goto err;
+               if (!request_io(&cs->rs, pci_ioaddr5, 64, "scitel"))
+                       goto err;
+               break;
+       case 2:
+               cs->hw.ax.base = pci_ioaddr4 + 0x08;
+               if (!request_io(&cs->rs, pci_ioaddr4, 64, "scitel"))
+                       goto err;
+               break;
+       case 3:
+               cs->hw.ax.base = pci_ioaddr3 + 0x10;
+               if (!request_io(&cs->rs, pci_ioaddr3, 64, "scitel"))
+                       goto err;
+               break;
+       case 4:
+               cs->hw.ax.base = pci_ioaddr2 + 0x20;
+               if (!request_io(&cs->rs, pci_ioaddr2, 64, "scitel"))
+                       goto err;
+               break;
        }       
        cs->hw.ax.data_adr = cs->hw.ax.base + 4;
        ipac_write(cs, IPAC_MASK, 0xFF);
@@ -338,8 +318,11 @@ setup_sct_quadro(struct IsdnCard *card)
                CardType[card->typ],
                sct_quadro_subtypes[cs->subtyp],
                ipac_read(cs, IPAC_ID));
-       return (1);
+       return 1;
 #else
        printk(KERN_ERR "HiSax: bkm_a8 only supported on PCI Systems\n");
 #endif /* CONFIG_PCI */
+ err:
+       hisax_release_resources(cs);
+       return 0;
 }
index 6d853cb44780a0b058e42e4ec56459dd1a9f9c6b..19e345bf420c6378c14984f3069df7636ad3c8fb 100644 (file)
@@ -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->typ = card->typ;
        spin_lock_init(&cs->lock);
+       resources_init(&cs->rs);
        SET_MODULE_OWNER(&cs->iif);
        strcpy(cs->iif.id, id);
        cs->iif.channels = 2;
@@ -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>
 
 static struct pci_device_id hisax_pci_tbl[] __initdata = {
index 766537762bab5927a10ae79ad84c72232c09f7e1..65577e445cd0513a4654163b23f6b073cbf0f740 100644 (file)
@@ -362,25 +362,11 @@ diva_ipacx_pci_irq(int intno, void *dev_id, struct pt_regs *regs)
 static void
 diva_release(struct IsdnCardState *cs)
 {
-       int bytecnt;
-
        del_timer(&cs->hw.diva.tl);
        if (cs->hw.diva.cfg_reg)
                byteout(cs->hw.diva.ctrl, 0); /* LED off, Reset */
 
-       if (cs->subtyp == DIVA_ISA)
-               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);
+       hisax_release_resources(cs);
 }
 
 static void
@@ -561,7 +547,7 @@ static struct card_ops diva_ops = {
 static struct card_ops diva_ipac_isa_ops = {
        .init     = ipac_init,
        .reset    = diva_ipac_isa_reset,
-       .release  = diva_ipac_isa_release,
+       .release  = hisax_release_resources,
        .irq_func = ipac_irq,
 };
 
@@ -798,16 +784,8 @@ ready:
                        cs->hw.diva.pci_cfg);
        if ((cs->subtyp != DIVA_IPAC_PCI) &&
            (cs->subtyp != DIVA_IPACX_PCI)   ) {
-               if (check_region(cs->hw.diva.cfg_reg, bytecnt)) {
-                       printk(KERN_WARNING
-                              "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");
-               }
+               if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, bytecnt, "diva isdn"))
+                       return 0;
        }
        cs->cardmsg = &Diva_card_msg;
        if (cs->subtyp == DIVA_IPAC_ISA) {
index 8c4c70ec9ab03aa88676411486879eab3e6b51bd..bf9753003382caf0e148feb934e88de05ceeac86 100644 (file)
@@ -387,8 +387,6 @@ elsa_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
 static void
 elsa_release(struct IsdnCardState *cs)
 {
-       int bytecnt = 8;
-
        del_timer(&cs->hw.elsa.tl);
 #if ARCOFI_USE
        clear_arcofi(cs);
@@ -398,28 +396,23 @@ elsa_release(struct IsdnCardState *cs)
        if (cs->subtyp == ELSA_QS1000PCI) {
                byteout(cs->hw.elsa.cfg + 0x4c, 0x01);  /* disable IRQ */
                writereg(cs, cs->hw.elsa.isac, IPAC_ATX, 0xff);
-               bytecnt = 2;
-               release_region(cs->hw.elsa.cfg, 0x80);
        }
        if (cs->subtyp == ELSA_QS3000PCI) {
                byteout(cs->hw.elsa.cfg + 0x4c, 0x03); /* disable ELSA PCI IRQ */
                writereg(cs, cs->hw.elsa.isac, IPAC_ATX, 0xff);
-               release_region(cs->hw.elsa.cfg, 0x80);
        }
        if (cs->subtyp == ELSA_PCMCIA_IPAC) {
                writereg(cs, cs->hw.elsa.isac, IPAC_ATX, 0xff);
        }
+#if ARCOFI_USE
        if ((cs->subtyp == ELSA_PCFPRO) ||
                (cs->subtyp == ELSA_QS3000) ||
                (cs->subtyp == ELSA_PCF) ||
                (cs->subtyp == ELSA_QS3000PCI)) {
-               bytecnt = 16;
-#if ARCOFI_USE
                release_modem(cs);
-#endif
        }
-       if (cs->hw.elsa.base)
-               release_region(cs->hw.elsa.base, bytecnt);
+#endif
+       hisax_release_resources(cs);
 }
 
 static int
@@ -532,28 +525,14 @@ check_arcofi(struct IsdnCardState *cs)
                                "Elsa: %s detected modem at 0x%lx\n",
                                Elsa_Types[cs->subtyp],
                                cs->hw.elsa.base+8);
-                       release_region(cs->hw.elsa.base, 8);
-                       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);
-                       }
+                       request_io(&cs->rs, cs->hw.elsa.base+8, 8, "elsa isdn modem");
                } else if (cs->subtyp==ELSA_PCC16) {
                        cs->subtyp = ELSA_PCF;
                        printk(KERN_INFO
                                "Elsa: %s detected modem at 0x%lx\n",
                                Elsa_Types[cs->subtyp],
                                cs->hw.elsa.base+8);
-                       release_region(cs->hw.elsa.base, 8);
-                       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);
-                       }
+                       request_io(&cs->rs, cs->hw.elsa.base+8, 8, "elsa isdn modem");
                } else
                        printk(KERN_INFO
                                "Elsa: %s detected modem at 0x%lx\n",
@@ -1081,29 +1060,17 @@ setup_elsa(struct IsdnCard *card)
           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_region(cs->hw.elsa.base, bytecnt, "elsa isdn")) {          
-                       printk(KERN_WARNING
-                              "HiSax: %s config port %#lx-%#lx already in use\n",
-                              CardType[card->typ],
-                              cs->hw.elsa.base,
-                              cs->hw.elsa.base + bytecnt);
-                       return (0);
-               }
+               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_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 ((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);
@@ -1116,15 +1083,13 @@ setup_elsa(struct IsdnCard *card)
                        if (!TimerRun(cs)) {
                                printk(KERN_WARNING
                                       "Elsa: timer do not start\n");
-                               elsa_release(cs);
-                               return (0);
+                               goto err;
                        }
                }
                HZDELAY(1);     /* wait >=10 ms */
                if (TimerRun(cs)) {
                        printk(KERN_WARNING "Elsa: timer do not run down\n");
-                       elsa_release(cs);
-                       return (0);
+                       goto err;
                }
                printk(KERN_INFO "Elsa: timer OK; resetting card\n");
        }
@@ -1143,9 +1108,8 @@ setup_elsa(struct IsdnCard *card)
                ISACVersion(cs, "Elsa:");
                if (HscxVersion(cs, "Elsa:")) {
                        printk(KERN_WARNING
-                               "Elsa: wrong HSCX versions check IO address\n");
-                       elsa_release(cs);
-                       return (0);
+                              "Elsa: wrong HSCX versions check IO address\n");
+                       goto err;
                }
        }
        if (cs->subtyp == ELSA_PC) {
@@ -1157,5 +1121,8 @@ setup_elsa(struct IsdnCard *card)
                writeitac(cs, ITAC_SCIE, 0);
                writeitac(cs, ITAC_STIE, 0);
        }
-       return (1);
+       return 1;
+ err:
+       elsa_release(cs);
+       return 0;
 }
index 8813c016fd1833ef7384fa9e29628c7454f2f62f..1e40b10856f1b769aabc19fbdf329ecacb7cfc77 100644 (file)
@@ -280,7 +280,6 @@ static struct pci_dev *dev_netjet __initdata = NULL;
 int __init
 setup_enternow_pci(struct IsdnCard *card)
 {
-       int bytecnt;
        struct IsdnCardState *cs = card->cs;
        char tmp[64];
 
@@ -359,19 +358,11 @@ setup_enternow_pci(struct IsdnCard *card)
 
 #endif /* CONFIG_PCI */
 
-       bytecnt = 256;
-
        printk(KERN_INFO
                "enter:now PCI: PCI card configured at 0x%lx IRQ %d\n",
                cs->hw.njet.base, cs->irq);
-       if (!request_region(cs->hw.njet.base, bytecnt, "Fn_ISDN")) {
-               printk(KERN_WARNING
-                          "HiSax: %s config port %lx-%lx already in use\n",
-                          CardType[card->typ],
-                          cs->hw.njet.base,
-                          cs->hw.njet.base + bytecnt);
-               return (0);
-       }
+       if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "Fn_ISDN"))
+               return 0;
        reset_enpci(cs);
        cs->hw.njet.last_is0 = 0;
        cs->dc_hw_ops = &enternow_ops;
@@ -381,31 +372,5 @@ setup_enternow_pci(struct IsdnCard *card)
        cs->irq_flags |= SA_SHIRQ;
        cs->card_ops = &enpci_ops;
 
-        return (1);
+        return 1;
 }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
index 543715c39f5d2ebfc1d5c212aeba33c6c233ec76..6985bcea0e213a499b7986b1177879b0a5a8d4cb 100644 (file)
@@ -300,127 +300,85 @@ gazel_init(struct IsdnCardState *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
 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 = 0x0000; i < 0xC000; i += 0x1000) {
-               if (!gazel_request_region(i + base, 16, "gazel")) {
-                       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;
+       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;
-}
-
-static void
-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);
+ err:
+       hisax_release_resources(cs);
+       return -EBUSY;
 }
 
 static int
 r685_reserve_regions(struct IsdnCardState *cs)
 {
-       if (!gazel_request_region(cs->hw.gazel.hscx[0], 0x100, "gazel")) {
-               return -EBUSY;
-       }
-       if (!gazel_request_region(cs->hw.gazel.cfg_reg, 0x80, "gazel")) {
-               release_region (cs->hw.gazel.hscx[0], 0x100);
-               return -EBUSY;
-       }
+       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;
-}
-
-static void
-r685_release(struct IsdnCardState *cs)
-{
-       release_region(cs->hw.gazel.hscx[0], 0x100);
-       release_region(cs->hw.gazel.cfg_reg, 0x80);
+ err:
+       hisax_release_resources(cs);
+       return -EBUSY;
 }
 
 static int
 r742_reserve_regions(struct IsdnCardState *cs)
 {
-       if (!gazel_request_region(cs->hw.gazel.ipac, 0x8, "gazel"))
-               return -EBUSY;
+       if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel"))
+               goto err;
        return 0;
-}
-
-static void
-r742_release(struct IsdnCardState *cs)
-{
-       release_region(cs->hw.gazel.ipac, 8);
+ err:
+       hisax_release_resources(cs);
+       return -EBUSY;
 }
 
 static int
 r753_reserve_regions(struct IsdnCardState *cs)
 {
-       if (!gazel_request_region(cs->hw.gazel.ipac, 0x8, "gazel")) {
-               return -EBUSY;
-       }
-       if (!gazel_request_region(cs->hw.gazel.cfg_reg, 0x80, "gazel")) {
-               release_region (cs->hw.gazel.ipac, 0x8);
-               return -EBUSY;
-       }
+       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;
-}
-
-static void
-r753_release(struct IsdnCardState *cs)
-{
-       release_region(cs->hw.gazel.ipac, 0x8);
-       release_region(cs->hw.gazel.cfg_reg, 0x80);
+ err:
+       hisax_release_resources(cs);
+       return -EBUSY;
 }
 
 static struct card_ops r647_ops = {
        .init     = gazel_init,
        .reset    = r647_reset,
-       .release  = r647_release,
+       .release  = hisax_release_resources,
        .irq_func = hscxisac_irq,
 };
 
 static struct card_ops r685_ops = {
        .init     = gazel_init,
        .reset    = r685_reset,
-       .release  = r685_release,
+       .release  = hisax_release_resources,
        .irq_func = hscxisac_irq,
 };
 
 static struct card_ops r742_ops = {
        .init     = ipac_init,
        .reset    = r742_reset,
-       .release  = r742_release,
+       .release  = hisax_release_resources,
        .irq_func = ipac_irq,
 };
 
 static struct card_ops r753_ops = {
        .init     = ipac_init,
        .reset    = r753_reset,
-       .release  = r753_release,
+       .release  = hisax_release_resources,
        .irq_func = ipac_irq,
 };
 
index bc0cd86bf3345b24eaf9aee4230ed0aed83e3a22..ee3cad1bec817b4a9ad78a43beb39442c7291e58 100644 (file)
@@ -318,7 +318,7 @@ hfcsx_release(struct IsdnCardState *cs)
        schedule_timeout((30 * HZ) / 1000);     /* Timeout 30ms */
        Write_hfc(cs, HFCSX_CIRM, 0);   /* Reset Off */
        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);
        cs->hw.hfcsx.extra = NULL;
 }
@@ -1236,45 +1236,40 @@ setup_hfcsx(struct IsdnCard *card)
        cs->hw.hfcsx.fifo = 255;
        if ((cs->typ == ISDN_CTYPE_HFC_SX) || 
            (cs->typ == ISDN_CTYPE_HFC_SP_PCMCIA)) {
-               if ((!cs->hw.hfcsx.base) || 
-                   check_region((cs->hw.hfcsx.base), 2)) {
-                 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");
-               }
+               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);
-                   release_region(cs->hw.hfcsx.base, 2);
-                   return(0);
+               case 1: 
+                       tmp[0] ='+';
+                       break;
+               case 9: 
+                       tmp[0] ='P';
+                       break;
+               default:
+                       printk(KERN_WARNING "HFC-SX: invalid chip id 0x%x\n",
+                              cs->hw.hfcsx.chip >> 4);
+                       hisax_release_resources(cs);
+                   return 0;
                }  
                if (!ccd_sp_irqtab[cs->irq & 0xF]) {
-                 printk(KERN_WARNING 
-                        "HFC_SX: invalid irq %d specified\n",cs->irq & 0xF);
-                 release_region(cs->hw.hfcsx.base, 2);
-                 return(0);
+                       printk(KERN_WARNING 
+                              "HFC_SX: invalid irq %d specified\n",
+                              cs->irq & 0xF);
+                       hisax_release_resources(cs);
+                       return 0;
                }  
-               if (!(cs->hw.hfcsx.extra = (void *)
-                     kmalloc(sizeof(struct hfcsx_extra), GFP_ATOMIC))) {
-                 release_region(cs->hw.hfcsx.base, 2);
-                 printk(KERN_WARNING "HFC-SX: unable to allocate memory\n");
-                 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
index d6e824ec66012510e8f1c582026abc101a9a45be..20495208f2b8ac4fe892bc5b43bc74511910a5be 100644 (file)
@@ -69,8 +69,7 @@ hfcs_release(struct IsdnCardState *cs)
 {
        release2bds0(cs);
        del_timer(&cs->hw.hfcD.timer);
-       if (cs->hw.hfcD.addr)
-               release_region(cs->hw.hfcD.addr, 2);
+       hisax_release_resources(cs);
 }
 
 static int
@@ -234,16 +233,8 @@ setup_hfcs(struct IsdnCard *card)
                cs->hw.hfcD.bfifosize = 7*1024 + 512;
        } else
                return (0);
-       if (check_region((cs->hw.hfcD.addr), 2)) {
-               printk(KERN_WARNING
-                      "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");
-       }
+       if (!request_io(&cs->rs, cs->hw.hfcD.addr, 2, "HFCS isdn"))
+               return 0;
        printk(KERN_INFO
               "HFCS: defined at 0x%x IRQ %d HZ %d\n",
               cs->hw.hfcD.addr,
index 29c838357bb299242ea7ce96456caf6325a03f1c..9506ab398d323a3b9daf093011443d7598642b99 100644 (file)
 /* #define I4L_IRQ_FLAG SA_INTERRUPT */
 #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
  */
@@ -563,8 +592,8 @@ struct teles3_hw {
 
 struct teles0_hw {
        unsigned int cfg_reg;
-       unsigned long membase;
        unsigned long phymem;
+       void *membase;
 };
 
 struct avm_hw {
@@ -730,9 +759,8 @@ struct hfcD_hw {
 
 struct isurf_hw {
        unsigned int reset;
-       unsigned long phymem;
-       unsigned long isac;
-       unsigned long isar;
+       void *isac;
+       void *isar;
        struct isar_reg isar_r;
 };
 
@@ -919,6 +947,7 @@ struct IsdnCardState {
        spinlock_t lock;
        struct card_ops *card_ops;
        int protocol;
+       struct resources rs;
        unsigned int irq;
        unsigned long irq_flags;
        long HW_Flags;
@@ -994,6 +1023,9 @@ struct IsdnCardState {
 #endif
 };
 
+void
+hisax_release_resources(struct IsdnCardState *cs);
+
 #define  MON0_RX       1
 #define  MON1_RX       2
 #define  MON0_TX       4
@@ -1437,4 +1469,5 @@ L4L3(struct PStack *st, int pr, void *arg)
        st->l3.l4l3(st, pr, arg);
 }
 
+
 #endif
index 9a14493a92d68dd49127d246ef6445b2d48e7806..4c8a0fd31505719b8e9f6a366588599ea1f0e439 100644 (file)
@@ -132,14 +132,6 @@ isurf_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        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
 reset_isurf(struct IsdnCardState *cs, u8 chips)
 {
@@ -193,7 +185,7 @@ isurf_reset(struct IsdnCardState *cs)
 static struct card_ops isurf_ops = {
        .init     = isurf_init,
        .reset    = isurf_reset,
-       .release  = isurf_release,
+       .release  = hisax_release_resources,
        .irq_func = isurf_interrupt,
 };
 
@@ -215,7 +207,6 @@ setup_isurf(struct IsdnCard *card)
                return(0);
        if (card->para[1] && card->para[2]) {
                cs->hw.isurf.reset = card->para[1];
-               cs->hw.isurf.phymem = card->para[2];
                cs->irq = card->para[0];
        } else {
 #ifdef __ISAPNP__
@@ -261,32 +252,17 @@ setup_isurf(struct IsdnCard *card)
                return (0);
 #endif
        }
-       if (!request_region(cs->hw.isurf.reset, 1, "isurf isdn")) {
-               printk(KERN_WARNING
-                       "HiSax: %s config port %x already in use\n",
-                       CardType[card->typ],
-                       cs->hw.isurf.reset);
-                       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);
+       if (!request_io(&cs->rs, cs->hw.isurf.reset, 1, "isurf isdn"))
+               goto err;
+       cs->hw.isurf.isar = request_mmio(&cs->rs, card->para[2], 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,
-              cs->hw.isurf.phymem,
+              card->para[2],
               cs->irq);
 
        cs->cardmsg = &ISurf_card_msg;
@@ -303,8 +279,11 @@ setup_isurf(struct IsdnCard *card)
        if (ver < 0) {
                printk(KERN_WARNING
                        "ISurf: wrong ISAR version (ret = %d)\n", ver);
-               isurf_release(cs);
-               return (0);
+               goto err;
        }
-       return (1);
+       return 1;
+ err:
+       hisax_release_resources(cs);
+       return 0;
+
 }
index 168b2fd1fca16a377b6f05c6e1973de6008c2136..523c1414fc1edfa5cd15306bcbc560226d5fdbc2 100644 (file)
@@ -140,13 +140,6 @@ static struct bc_hw_ops hscx_ops = {
        .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
 ix1_reset(struct IsdnCardState *cs)
 {
@@ -171,7 +164,7 @@ ix1_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 static struct card_ops ix1_ops = {
        .init     = inithscxisac,
        .reset    = ix1_reset,
-       .release  = ix1_release,
+       .release  = hisax_release_resources,
        .irq_func = hscxisac_irq,
 };
 
@@ -247,17 +240,9 @@ setup_ix1micro(struct IsdnCard *card)
        cs->hw.ix1.hscx = card->para[1] + HSCX_DATA_OFFSET;
        cs->hw.ix1.cfg_reg = card->para[1];
        cs->irq = card->para[0];
-       if (cs->hw.ix1.cfg_reg) {
-               if (check_region((cs->hw.ix1.cfg_reg), 4)) {
-                       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");
-       }
+       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,
@@ -271,8 +256,10 @@ setup_ix1micro(struct IsdnCard *card)
        if (HscxVersion(cs, "ix1-Micro:")) {
                printk(KERN_WARNING
                    "ix1-Micro: wrong HSCX versions check IO address\n");
-               ix1_release(cs);
-               return (0);
+               goto err;
        }
-       return (1);
+       return 1;
+ err:
+       hisax_release_resources(cs);
+       return 0;
 }
index 6bbc1e21e824deb33fbd3fb15a62ffa1583eb5ef..3e97930c431dccc35a2aa6de6c8b508976ed97b3 100644 (file)
@@ -132,13 +132,6 @@ static struct bc_hw_ops hscx_ops = {
        .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
 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 = {
        .init     = inithscxisac,
-       .release  = mic_release,
+       .release  = hisax_release_resources,
        .irq_func = hscxisac_irq,
 };
 
 int __init
 setup_mic(struct IsdnCard *card)
 {
-       int bytecnt;
        struct IsdnCardState *cs = card->cs;
        char tmp[64];
 
@@ -163,22 +155,15 @@ setup_mic(struct IsdnCard *card)
        if (cs->typ != ISDN_CTYPE_MIC)
                return (0);
 
-       bytecnt = 8;
        cs->hw.mic.cfg_reg = card->para[1];
        cs->irq = card->para[0];
        cs->hw.mic.adr = cs->hw.mic.cfg_reg + MIC_ADR;
        cs->hw.mic.isac = cs->hw.mic.cfg_reg + MIC_ISAC;
        cs->hw.mic.hscx = cs->hw.mic.cfg_reg + MIC_HSCX;
 
-       if (!request_region((cs->hw.mic.cfg_reg), bytecnt, "mic isdn")) {
-               printk(KERN_WARNING
-                      "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);
-       }
-
+       if (!request_io(&cs->rs, cs->hw.mic.cfg_reg, 8, "mic isdn"))
+               goto err;
+  
        printk(KERN_INFO
               "mic: defined at 0x%x IRQ %d\n",
               cs->hw.mic.cfg_reg,
@@ -191,8 +176,10 @@ setup_mic(struct IsdnCard *card)
        if (HscxVersion(cs, "mic:")) {
                printk(KERN_WARNING
                    "mic: wrong HSCX versions check IO address\n");
-               mic_release(cs);
-               return (0);
+               goto err;
        }
-       return (1);
+       return 1;
+ err:
+       hisax_release_resources(cs);
+       return 0;
 }
index fab21b6e6442ca98083925b0a5e7b611c0251d63..94d7e74df56e2533d8d785c23b93f0ee3b779a33 100644 (file)
@@ -1029,6 +1029,6 @@ netjet_release(struct IsdnCardState *cs)
        byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
        byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0);
        releasetiger(cs);
-       release_region(cs->hw.njet.base, 256);
+       hisax_release_resources(cs);
 }
 
index c2df12b7ba0cee3af74b8e3d4c37acc0442f02e4..af0239cfb0957d0e79987d0e63254947bfd032d1 100644 (file)
@@ -175,12 +175,8 @@ niccy_release(struct IsdnCardState *cs)
                val = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
                val &= PCI_IRQ_DISABLE;
                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
@@ -265,23 +261,10 @@ setup_niccy(struct IsdnCard *card)
                cs->hw.niccy.cfg_reg = 0;
                cs->subtyp = NICCY_PNP;
                cs->irq = card->para[0];
-               if (!request_region(cs->hw.niccy.isac, 2, "niccy data")) {
-                       printk(KERN_WARNING
-                               "HiSax: %s data port %x-%x already in use\n",
-                               CardType[card->typ],
-                               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);
-               }
+               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 {
 #if CONFIG_PCI
                u_int pci_ioaddr;
@@ -320,23 +303,11 @@ setup_niccy(struct IsdnCard *card)
                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_region(cs->hw.niccy.isac, 4, "niccy")) {
-                       printk(KERN_WARNING
-                               "HiSax: %s data port %x-%x already in use\n",
-                               CardType[card->typ],
-                               cs->hw.niccy.isac,
-                               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);
-               }
+
+               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;
 #else
                printk(KERN_WARNING "Niccy: io0 0 and NO_PCI_BIOS\n");
                printk(KERN_WARNING "Niccy: unable to config NICCY PCI\n");
@@ -355,8 +326,9 @@ setup_niccy(struct IsdnCard *card)
        if (HscxVersion(cs, "Niccy:")) {
                printk(KERN_WARNING
                    "Niccy: wrong HSCX versions check IO address\n");
-               niccy_release(cs);
-               return (0);
        }
-       return (1);
+       return 1;
+ err:
+       niccy_release(cs);
+       return 0;
 }
index a453bc87781014209b182367cee047d4ce52b14a..9e1e9dda1ab8d14701f365c1c1532617f6c02d7c 100644 (file)
@@ -117,7 +117,6 @@ static struct pci_dev *dev_netjet __initdata = NULL;
 int __init
 setup_netjet_s(struct IsdnCard *card)
 {
-       int bytecnt;
        struct IsdnCardState *cs = card->cs;
        char tmp[64];
 
@@ -211,26 +210,17 @@ setup_netjet_s(struct IsdnCard *card)
 
 #endif /* CONFIG_PCI */
 
-       bytecnt = 256;
-
        printk(KERN_INFO
                "NETjet-S: PCI card configured at %#lx IRQ %d\n",
                cs->hw.njet.base, cs->irq);
-       if (check_region(cs->hw.njet.base, bytecnt)) {
-               printk(KERN_WARNING
-                      "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");
-       }
+       if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn"))
+               return 0;
+       
        nj_s_reset(cs);
        cs->dc_hw_ops = &netjet_dc_ops;
        cs->cardmsg = &NETjet_S_card_msg;
        cs->irq_flags |= SA_SHIRQ;
        cs->card_ops = &nj_s_ops;
        ISACVersion(cs, "NETjet-S:");
-       return (1);
+       return 1;
 }
index 6e06670e55d237963eecd0bfa96e01a687fe465b..b3a004c22facacca0669babec6c6520360e9db14 100644 (file)
@@ -121,7 +121,6 @@ static struct pci_dev *dev_netjet __initdata = NULL;
 int __init
 setup_netjet_u(struct IsdnCard *card)
 {
-       int bytecnt;
        struct IsdnCardState *cs = card->cs;
        char tmp[64];
 #if CONFIG_PCI
@@ -209,24 +208,17 @@ setup_netjet_u(struct IsdnCard *card)
 
 #endif /* CONFIG_PCI */
 
-       bytecnt = 256;
-
        printk(KERN_INFO
                "NETspider-U: PCI card configured at %#lx IRQ %d\n",
                cs->hw.njet.base, cs->irq);
-       if (!request_region(cs->hw.njet.base, bytecnt, "netspider-u isdn")) {
-               printk(KERN_WARNING
-                      "HiSax: %s config port %#lx-%#lx already in use\n",
-                      CardType[card->typ],
-                      cs->hw.njet.base,
-                      cs->hw.njet.base + bytecnt);
-               return (0);
-       }
+       if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn"))
+               return 0;
+       
        nj_u_reset(cs);
        cs->dc_hw_ops = &netjet_dc_ops;
        cs->cardmsg = &NETjet_U_card_msg;
        cs->irq_flags |= SA_SHIRQ;
        cs->card_ops = &nj_u_ops;
        ICCVersion(cs, "NETspider-U:");
-       return (1);
+       return 1;
 }
index f41a3c7d3f7a286e8abf2386b9ad965fbe1c2fa3..39ee423f44462e3ad9dc36626303ee1dc8cfa31d 100644 (file)
@@ -166,12 +166,6 @@ static struct bc_hw_ops hscx_ops = {
        .write_fifo = hscx_write_fifo,
 };
  
-void
-s0box_release(struct IsdnCardState *cs)
-{
-       release_region(cs->hw.teles3.cfg_reg, 8);
-}
-
 static int
 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 = {
        .init     = inithscxisac,
-       .release  = s0box_release,
+       .release  = hisax_release_resources,
        .irq_func = hscxisac_irq,
 };
 
@@ -203,14 +197,8 @@ setup_s0box(struct IsdnCard *card)
        cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e;
        cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e;
        cs->irq = card->para[0];
-       if (!request_region(cs->hw.teles3.cfg_reg,8, "S0Box parallel I/O")) {
-               printk(KERN_WARNING
-                      "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;
-       } 
+       if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 8, "S0Box parallel I/O"))
+               goto err;
        printk(KERN_INFO
               "HiSax: %s config irq:%d isac:0x%x  cfg:0x%x\n",
               CardType[cs->typ], cs->irq,
@@ -226,8 +214,10 @@ setup_s0box(struct IsdnCard *card)
        if (HscxVersion(cs, "S0Box:")) {
                printk(KERN_WARNING
                       "S0Box: wrong HSCX versions check IO address\n");
-               s0box_release(cs);
-               return (0);
+               goto err;
        }
-       return (1);
+       return 1;
+ err:
+       hisax_release_resources(cs);
+       return 0;
 }
index 3bafecc83244c47595a89457428b36b2cfab0a56..51caffa4b2e94c0f0d21bb7131a8d264be5c130a 100644 (file)
@@ -155,8 +155,7 @@ saphir_release(struct IsdnCardState *cs)
        byteout(cs->hw.saphir.cfg_reg + IRQ_REG, 0xff);
        del_timer_sync(&cs->hw.saphir.timer);
        cs->hw.saphir.timer.function = NULL;
-       if (cs->hw.saphir.cfg_reg)
-               release_region(cs->hw.saphir.cfg_reg, 6);
+       hisax_release_resources(cs);
 }
 
 static int
@@ -219,20 +218,15 @@ setup_saphir(struct IsdnCard *card)
        if (cs->typ != ISDN_CTYPE_HSTSAPHIR)
                return (0);
 
+       init_timer(&cs->hw.saphir.timer);
        /* IO-Ports */
        cs->hw.saphir.cfg_reg = card->para[1];
        cs->hw.saphir.isac = card->para[1] + ISAC_DATA;
        cs->hw.saphir.hscx = card->para[1] + HSCX_DATA;
        cs->hw.saphir.ale = card->para[1] + ADDRESS_REG;
        cs->irq = card->para[0];
-       if (!request_region((cs->hw.saphir.cfg_reg), 6, "saphir")) {
-               printk(KERN_WARNING
-                       "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);
-       }
+       if (!request_io(&cs->rs, cs->hw.saphir.cfg_reg, 6, "saphir"))
+               goto err;
 
        printk(KERN_INFO
               "HiSax: %s config irq:%d io:0x%X\n",
@@ -241,12 +235,10 @@ setup_saphir(struct IsdnCard *card)
 
        cs->hw.saphir.timer.function = (void *) SaphirWatchDog;
        cs->hw.saphir.timer.data = (long) cs;
-       init_timer(&cs->hw.saphir.timer);
        cs->hw.saphir.timer.expires = jiffies + 4*HZ;
        add_timer(&cs->hw.saphir.timer);
        if (saphir_reset(cs)) {
-               saphir_release(cs);
-               return (0);
+               goto err;
        }
        cs->dc_hw_ops = &isac_ops;
        cs->bc_hw_ops = &hscx_ops;
@@ -256,8 +248,10 @@ setup_saphir(struct IsdnCard *card)
        if (HscxVersion(cs, "saphir:")) {
                printk(KERN_WARNING
                    "saphir: wrong HSCX versions check IO address\n");
-               saphir_release(cs);
-               return (0);
+               goto err;
        }
-       return (1);
+       return 1;
+ err:
+       saphir_release(cs);
+       return 0;
 }
index d85d37bee8ed5414040d52c5226bfb56ba849f56..a74967a7ad8a3074233efe1fe3ceaa26b313cf1f 100644 (file)
@@ -390,20 +390,6 @@ sedlbauer_reset(struct IsdnCardState *cs)
        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
 sedlbauer_isar_release(struct IsdnCardState *cs)
 {
@@ -412,7 +398,7 @@ sedlbauer_isar_release(struct IsdnCardState *cs)
        sedlbauer_reset(cs);
        isar_write(cs, 0, ISAR_IRQBIT, 0);
        isac_write(cs, ISAC_MASK, 0xFF);
-       sedlbauer_release(cs);
+       hisax_release_resources(cs);
 }
 
 static int
@@ -452,14 +438,14 @@ sedlbauer_isar_init(struct IsdnCardState *cs)
 static struct card_ops sedlbauer_ops = {
        .init     = inithscxisac,
        .reset    = sedlbauer_reset,
-       .release  = sedlbauer_release,
+       .release  = hisax_release_resources,
        .irq_func = sedlbauer_interrupt,
 };
 
 static struct card_ops sedlbauer_ipac_ops = {
        .init     = ipac_init,
        .reset    = sedlbauer_reset,
-       .release  = sedlbauer_release,
+       .release  = hisax_release_resources,
        .irq_func = ipac_irq,
 };
 
@@ -546,7 +532,7 @@ setup_sedlbauer(struct IsdnCard *card)
                                                        printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n",
                                                                card->para[0], card->para[1]);
                                                        pd->deactivate(pd);
-                                                       return(0);
+                                                       goto err;
                                                }
                                                cs->hw.sedl.cfg_reg = card->para[1];
                                                cs->irq = card->para[0];
@@ -561,7 +547,7 @@ setup_sedlbauer(struct IsdnCard *card)
                                                goto ready;
                                        } else {
                                                printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n");
-                                               return(0);
+                                               goto err;
                                        }
                                }
                                pdev++;
@@ -576,21 +562,21 @@ setup_sedlbauer(struct IsdnCard *card)
 #if CONFIG_PCI
                if (!pci_present()) {
                        printk(KERN_ERR "Sedlbauer: no PCI bus present\n");
-                       return(0);
+                       goto err;
                }
                if ((dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET,
                                PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) {
                        if (pci_enable_device(dev_sedl))
-                               return(0);
+                               goto err;
                        cs->irq = dev_sedl->irq;
                        if (!cs->irq) {
                                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);
                } else {
                        printk(KERN_WARNING "Sedlbauer: No PCI card found\n");
-                       return(0);
+                       goto err;
                }
                cs->irq_flags |= SA_SHIRQ;
                cs->hw.sedl.bus = SEDL_BUS_PCI;
@@ -602,7 +588,7 @@ setup_sedlbauer(struct IsdnCard *card)
                        cs->hw.sedl.cfg_reg);
                if (sub_id != PCI_SUB_ID_SEDLBAUER) {
                        printk(KERN_ERR "Sedlbauer: unknown sub id %#x\n", sub_id);
-                       return(0);
+                       goto err;
                }
                if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) {
                        cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
@@ -616,7 +602,7 @@ setup_sedlbauer(struct IsdnCard *card)
                } else {
                        printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n",
                                sub_vendor_id);
-                       return(0);
+                       goto err;
                }
                bytecnt = 256;
                cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON;
@@ -631,7 +617,7 @@ setup_sedlbauer(struct IsdnCard *card)
                byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
 #else
                printk(KERN_WARNING "Sedlbauer: NO_PCI_BIOS\n");
-               return (0);
+               goto err;
 #endif /* CONFIG_PCI */
        }       
 ready: 
@@ -639,14 +625,9 @@ ready:
         * 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 &&
-           (!request_region((cs->hw.sedl.cfg_reg), bytecnt, "sedlbauer isdn"))) {
-               printk(KERN_WARNING
-                       "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);
+       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
@@ -740,8 +721,7 @@ ready:
                        if (ver < 0) {
                                printk(KERN_WARNING
                                        "Sedlbauer: wrong ISAR version (ret = %d)\n", ver);
-                               sedlbauer_release(cs);
-                               return (0);
+                               goto err;
                        }
                } else {
                        if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
@@ -764,11 +744,13 @@ ready:
                        if (HscxVersion(cs, "Sedlbauer:")) {
                                printk(KERN_WARNING
                                        "Sedlbauer: wrong HSCX versions check IO address\n");
-                               sedlbauer_release(cs);
-                               return (0);
+                               goto err;
                        }
                        sedlbauer_reset(cs);
                }
        }
-       return (1);
+       return 1;
+ err:
+       hisax_release_resources(cs);
+       return 0;
 }
index 3f12c0c88ae7517069fbed2cb519cc960263eb40..d2a7d8017b247e27937ee4fae387e62947bd75c2 100644 (file)
@@ -170,7 +170,7 @@ static struct card_ops sportster_ops = {
 static int __init
 get_io_range(struct IsdnCardState *cs)
 {
-       int i, j, adr;
+       int i, adr;
        
        for (i=0;i<64;i++) {
                adr = cs->hw.spt.cfg_reg + i *1024;
@@ -178,20 +178,18 @@ get_io_range(struct IsdnCardState *cs)
                        printk(KERN_WARNING
                                "HiSax: %s config port %x-%x already in use\n",
                                CardType[cs->typ], adr, adr + 8);
-                       break;
+                       goto err;
                }
        }
-       if (i==64)
-               return(1);
-       else {
-               for (j=0; j<i; j++) {
-                       adr = cs->hw.spt.cfg_reg + j *1024;
-                       release_region(adr, 8);
-               }
-               return(0);
+       return 1;
+ err:
+       for (i=i-1; i >= 0; i--) {
+               adr = cs->hw.spt.cfg_reg + i *1024;
+               release_region(adr, 8);
        }
+       return 0;
 }
-
+  
 int __init
 setup_sportster(struct IsdnCard *card)
 {
index c9caf4505553532f0b0505023e31b24a2937376e..799a9b534c849c90978ece86209461d9d2b4c138 100644 (file)
@@ -222,8 +222,7 @@ teleint_release(struct IsdnCardState *cs)
 {
        del_timer(&cs->hw.hfc.timer);
        releasehfc(cs);
-       if (cs->hw.hfc.addr)
-               release_region(cs->hw.hfc.addr, 2);
+       hisax_release_resources(cs);
 }
 
 static int
@@ -286,16 +285,9 @@ setup_TeleInt(struct IsdnCard *card)
        cs->hw.hfc.timer.function = (void *) TeleInt_Timer;
        cs->hw.hfc.timer.data = (long) cs;
        init_timer(&cs->hw.hfc.timer);
-       if (check_region((cs->hw.hfc.addr), 2)) {
-               printk(KERN_WARNING
-                      "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");
-       }
+       if (!request_io(&cs->rs, cs->hw.hfc.addr, 2, "TeleInt isdn"))
+               goto err;
+       
        /* HW IO = IO */
        byteout(cs->hw.hfc.addr, cs->hw.hfc.addr & 0xff);
        byteout(cs->hw.hfc.addr | 1, ((cs->hw.hfc.addr & 0x300) >> 8) | 0x54);
@@ -320,8 +312,7 @@ setup_TeleInt(struct IsdnCard *card)
                        break;
                default:
                        printk(KERN_WARNING "TeleInt: wrong IRQ\n");
-                       teleint_release(cs);
-                       return (0);
+                       goto err;
        }
        byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm);
        byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.ctmt);
@@ -337,5 +328,8 @@ setup_TeleInt(struct IsdnCard *card)
        cs->cardmsg = &TeleInt_card_msg;
        cs->card_ops = &teleint_ops;
        ISACVersion(cs, "TeleInt:");
-       return (1);
+       return 1;
+ err:
+       teleint_release(cs);
+       return 0;
 }
index 90ff17925afefe68b8c20c022acb79999ea2c25c..b7f410d1a00ebca758332bec45a4686b4bb9fafa 100644 (file)
@@ -48,7 +48,7 @@ static void
 isac_read_fifo(struct IsdnCardState *cs, u8 * data, int size)
 {
        int i;
-       unsigned long ad = cs->hw.teles0.membase + 0x100;
+       void *ad = cs->hw.teles0.membase + 0x100;
        for (i = 0; i < size; i++)
                data[i] = readb(ad);
 }
@@ -57,7 +57,7 @@ static void
 isac_write_fifo(struct IsdnCardState *cs, u8 * data, int size)
 {
        int i;
-       unsigned long ad = cs->hw.teles0.membase + 0x100;
+       void *ad = cs->hw.teles0.membase + 0x100;
        for (i = 0; i < size; i++) {
                writeb(data[i], ad); mb();
        }
@@ -88,7 +88,7 @@ static void
 hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size)
 {
        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++)
                data[i] = readb(ad);
 }
@@ -97,7 +97,7 @@ static void
 hscx_write_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size)
 {
        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++) {
                writeb(data[i], ad);
        }
@@ -110,15 +110,6 @@ static struct bc_hw_ops hscx_ops = {
        .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
 teles0_reset(struct IsdnCardState *cs)
 {
@@ -176,7 +167,7 @@ Teles_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 static struct card_ops teles0_ops = {
        .init     = inithscxisac,
        .reset    = teles0_reset,
-       .release  = teles0_release,
+       .release  = hisax_release_resources,
        .irq_func = hscxisac_irq,
 };
 
@@ -205,65 +196,43 @@ setup_teles0(struct IsdnCard *card)
        }
        cs->irq = card->para[0];
        if (cs->hw.teles0.cfg_reg) {
-               if (!request_region(cs->hw.teles0.cfg_reg, 8, "teles cfg")) {
-                       printk(KERN_WARNING
-                         "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 (!request_io(&cs->rs, cs->hw.teles0.cfg_reg, 8, "teles cfg"))
+                       goto err;
+
                if ((val = bytein(cs->hw.teles0.cfg_reg + 0)) != 0x51) {
                        printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
                               cs->hw.teles0.cfg_reg + 0, val);
-                       release_region(cs->hw.teles0.cfg_reg, 8);
-                       return (0);
+                       goto err;
                }
                if ((val = bytein(cs->hw.teles0.cfg_reg + 1)) != 0x93) {
                        printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
                               cs->hw.teles0.cfg_reg + 1, val);
-                       release_region(cs->hw.teles0.cfg_reg, 8);
-                       return (0);
+                       goto err;
                }
-               val = bytein(cs->hw.teles0.cfg_reg + 2);        /* 0x1e=without AB
-                                                                  * 0x1f=with AB
-                                                                  * 0x1c 16.3 ???
-                                                                */
+               val = bytein(cs->hw.teles0.cfg_reg + 2);/* 0x1e=without AB
+                                                        * 0x1f=with AB
+                                                        * 0x1c 16.3 ???
+                                                        */
                if (val != 0x1e && val != 0x1f) {
                        printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
                               cs->hw.teles0.cfg_reg + 2, val);
-                       release_region(cs->hw.teles0.cfg_reg, 8);
-                       return (0);
+                       goto err;
                }
        }
        /* 16.0 and 8.0 designed for IOM1 */
        test_and_set_bit(HW_IOM1, &cs->HW_Flags);
        cs->hw.teles0.phymem = card->para[1];
-       if (check_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE)) {
-               printk(KERN_WARNING
-                       "HiSax: %s memory region %lx-%lx already in use\n",
-                       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);
+       cs->hw.teles0.membase = request_mmio(&cs->rs, cs->hw.teles0.phymem, TELES_IOMEM_SIZE, "teles iomem");
+       if (!cs->hw.teles0.membase)
+               goto err;
+
        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,
               cs->hw.teles0.membase, cs->hw.teles0.cfg_reg);
        if (teles0_reset(cs)) {
                printk(KERN_WARNING "Teles0: wrong IRQ\n");
-               teles0_release(cs);
-               return (0);
+               goto err;
        }
        cs->dc_hw_ops = &isac_ops;
        cs->bc_hw_ops = &hscx_ops;
@@ -273,8 +242,11 @@ setup_teles0(struct IsdnCard *card)
        if (HscxVersion(cs, "Teles0:")) {
                printk(KERN_WARNING
                 "Teles0: wrong HSCX versions check IO/MEM addresses\n");
-               teles0_release(cs);
-               return (0);
+               goto err;
        }
        return (1);
+
+ err:
+       hisax_release_resources(cs);
+       return 0;
 }
index 7821bc3a7017ac460a4a7481977150fc872f1282..51bd964d98d4a91ccec425b27d57cdf4c6597a3b 100644 (file)
@@ -113,34 +113,6 @@ static struct bc_hw_ops hscx_ops = {
        .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
 teles3_reset(struct IsdnCardState *cs)
 {
@@ -206,7 +178,7 @@ Teles_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 static struct card_ops teles3_ops = {
        .init     = inithscxisac,
        .reset    = teles3_reset,
-       .release  = teles3_release,
+       .release  = hisax_release_resources,
        .irq_func = hscxisac_irq,
 };
 
@@ -315,95 +287,35 @@ setup_teles3(struct IsdnCard *card)
        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_region(cs->hw.teles3.hscx[1], 96, "HiSax Teles PCMCIA")) {
-                       printk(KERN_WARNING
-                              "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);
-               }
+               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_region(cs->hw.teles3.cfg_reg, 1, "teles3 cfg")) {
-                                       printk(KERN_WARNING
-                                               "HiSax: %s config port %x already in use\n",
-                                               CardType[card->typ],
-                                               cs->hw.teles3.cfg_reg);
-                                       return (0);
-                               }
+                               if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 1, "teles3 cfg"))
+                                       goto err;
                        } else {
-                               if (!request_region(cs->hw.teles3.cfg_reg, 8, "teles3 cfg")) {
-                                       printk(KERN_WARNING
-                                              "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_region(cs->hw.teles3.isac + 32, 32, "HiSax isac")) {
-                       printk(KERN_WARNING
-                          "HiSax: %s isac ports %x-%x already in use\n",
-                              CardType[cs->typ],
-                              cs->hw.teles3.isac + 32,
-                              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);
-                               }
+                               if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 8, "teles3 cfg"))
+                                       goto err;
                        }
-                       release_ioregs(cs, 3);
-                       return (0);
                }
+               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);
-                       teles3_release(cs);
-                       return (0);
+                       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);
-                       teles3_release(cs);
-                       return (0);
+                       goto err;
                }
                val = bytein(cs->hw.teles3.cfg_reg + 2);/* 0x1e=without AB
                                                         * 0x1f=with AB
@@ -415,8 +327,7 @@ setup_teles3(struct IsdnCard *card)
                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);
-                       teles3_release(cs);
-                       return (0);
+                       goto err;
                }
        }
        printk(KERN_INFO
@@ -429,8 +340,7 @@ setup_teles3(struct IsdnCard *card)
 
        if (teles3_reset(cs)) {
                printk(KERN_WARNING "Teles3: wrong IRQ\n");
-               teles3_release(cs);
-               return (0);
+               goto err;
        }
        cs->dc_hw_ops = &isac_ops;
        cs->bc_hw_ops = &hscx_ops;
@@ -440,8 +350,11 @@ setup_teles3(struct IsdnCard *card)
        if (HscxVersion(cs, "Teles3:")) {
                printk(KERN_WARNING
                       "Teles3: wrong HSCX versions check IO address\n");
-               teles3_release(cs);
-               return (0);
+               goto err;
        }
        return (1);
+ err:
+       hisax_release_resources(cs);
+       return (0);
+
 }
index f19bb1d26a3f03274021c6bee8af21e6d7cf739c..31633c2a69cdb3b6eace7baf63b00ab42b6ee087 100644 (file)
@@ -45,7 +45,7 @@ const char *telespci_revision = "$Revision: 2.16.6.5 $";
 static u8
 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;
 
        ZORAN_WAIT_NOBUSY;
@@ -63,7 +63,7 @@ isac_read(struct IsdnCardState *cs, u8 off)
 static void
 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;
 
        ZORAN_WAIT_NOBUSY;
@@ -80,7 +80,7 @@ isac_write(struct IsdnCardState *cs, u8 off, u8 data)
 static void
 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;
        int i;
 
@@ -99,7 +99,7 @@ isac_read_fifo(struct IsdnCardState *cs, u8 *data, int size)
 static void
 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;
        int i;
 
@@ -124,7 +124,7 @@ static struct dc_hw_ops isac_ops = {
 static u8
 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;
 
        ZORAN_WAIT_NOBUSY;
@@ -141,7 +141,7 @@ hscx_read(struct IsdnCardState *cs, int hscx, u8 off)
 static void
 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;
 
        ZORAN_WAIT_NOBUSY;
@@ -157,7 +157,7 @@ hscx_write(struct IsdnCardState *cs, int hscx, u8 off, u8 data)
 static void
 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;
        int i;
 
@@ -176,7 +176,7 @@ hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 * data, int size)
 static void
 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;
        int i;
 
@@ -271,7 +271,7 @@ setup_telespci(struct IsdnCard *card)
                        printk(KERN_WARNING "Teles: No IRQ for PCI card found\n");
                        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);
                printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n",
                        pci_resource_start(dev_tel, 0), dev_tel->irq);
@@ -295,7 +295,7 @@ setup_telespci(struct IsdnCard *card)
        /* writel(0x00800000, cs->hw.teles0.membase + 0x200); */
 
        printk(KERN_INFO
-              "HiSax: %s config irq:%d mem:%lx\n",
+              "HiSax: %s config irq:%d mem:%p\n",
               CardType[cs->typ], cs->irq,
               cs->hw.teles0.membase);
 
index cc7f00dcb6096450106c33e95b2f34de3c01a8ae..6594cbf211dec4159cee615b96cd1f10422c8708 100644 (file)
@@ -639,9 +639,9 @@ static void
 w6692_release(struct IsdnCardState *cs)
 {
        w6692_write_reg(cs, W_IMASK, 0xff);
-       release_region(cs->hw.w6692.iobase, 256);
        if (cs->subtyp == W6692_USR)
                w6692_write_reg(cs, W_XDATA, 0x04);
+       hisax_release_resources(cs);
 }
 
 static int
@@ -738,15 +738,9 @@ setup_w6692(struct IsdnCard *card)
        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_region((cs->hw.w6692.iobase), 256,
-                           id_list[cs->subtyp].card_name)) {
-               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);
-       }
+       if (!request_io(&cs->rs, cs->hw.w6692.iobase, 0x100, id_list[cs->subtyp].card_name))
+               return 0;
+       
 #else
        printk(KERN_WARNING "HiSax: W6692 and NO_PCI_BIOS\n");
        printk(KERN_WARNING "HiSax: W6692 unable to config\n");