]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Fix double request_region in com20020
authorAndrew Morton <akpm@osdl.org>
Wed, 1 Oct 2003 17:57:16 +0000 (10:57 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Wed, 1 Oct 2003 17:57:16 +0000 (10:57 -0700)
From: Herbert Xu <herbert@gondor.apana.org.au>

Currently com20020 and com20020_cs both call request_region on the same
block of ports leading to a conflict.  This patch resolves this by moving
request_region out of the generic driver and into the isa/pci/cs drivers.

drivers/net/arcnet/com20020-isa.c
drivers/net/arcnet/com20020-pci.c
drivers/net/arcnet/com20020.c

index a25851f103d829fc733c7481022c531e08003ef7..1d7100987c6784a95973f36f71e1c98a7f7e658e 100644 (file)
@@ -53,6 +53,7 @@ static int __init com20020isa_probe(struct net_device *dev)
        int ioaddr;
        unsigned long airqmask;
        struct arcnet_local *lp = dev->priv;
+       int err;
 
        BUGLVL(D_NORMAL) printk(VERSION);
 
@@ -62,17 +63,20 @@ static int __init com20020isa_probe(struct net_device *dev)
                       "must specify the base address!\n");
                return -ENODEV;
        }
-       if (check_region(ioaddr, ARCNET_TOTAL_SIZE)) {
+       if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (COM20020)")) {
                BUGMSG(D_NORMAL, "IO region %xh-%xh already allocated.\n",
                       ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
                return -ENXIO;
        }
        if (ASTATUS() == 0xFF) {
                BUGMSG(D_NORMAL, "IO address %x empty\n", ioaddr);
-               return -ENODEV;
+               err = -ENODEV;
+               goto out;
+       }
+       if (com20020_check(dev)) {
+               err = -ENODEV;
+               goto out;
        }
-       if (com20020_check(dev))
-               return -ENODEV;
 
        if (!dev->irq) {
                /* if we do this, we're sure to get an IRQ since the
@@ -96,13 +100,21 @@ static int __init com20020isa_probe(struct net_device *dev)
                        dev->irq = probe_irq_off(airqmask);
                        if (dev->irq <= 0) {
                                BUGMSG(D_NORMAL, "Autoprobe IRQ failed.\n");
-                               return -ENODEV;
+                               err = -ENODEV;
+                               goto out;
                        }
                }
        }
 
        lp->card_name = "ISA COM20020";
-       return com20020_found(dev, 0);
+       if ((err = com20020_found(dev, 0)) != 0)
+               goto out;
+
+       return 0;
+
+out:
+       release_region(ioaddr, ARCNET_TOTAL_SIZE);
+       return err;
 }
 
 
@@ -170,6 +182,7 @@ int init_module(void)
 void cleanup_module(void)
 {
        com20020_remove(my_dev);
+       release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE);
 }
 
 #else
index e5fab07cb8625ba1766e3f72f554f5e0a40bd519..6ae9f59559af86e33b3eb85eb2467b63743586cd 100644 (file)
@@ -115,20 +115,20 @@ static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_de
                BUGMSG(D_NORMAL, "IO address %Xh was reported by PCI BIOS, "
                       "but seems empty!\n", ioaddr);
                err = -EIO;
-               goto out_priv;
+               goto out_port;
        }
        if (com20020_check(dev)) {
                err = -EIO;
-               goto out_priv;
+               goto out_port;
        }
 
-       release_region(ioaddr, ARCNET_TOTAL_SIZE);
-
        if ((err = com20020_found(dev, SA_SHIRQ)) != 0)
-               goto out_priv;
+               goto out_port;
 
        return 0;
 
+out_port:
+       release_region(ioaddr, ARCNET_TOTAL_SIZE);
 out_priv:
        kfree(dev->priv);
 out_dev:
@@ -138,7 +138,9 @@ out_dev:
 
 static void __devexit com20020pci_remove(struct pci_dev *pdev)
 {
-       com20020_remove(pci_get_drvdata(pdev));
+       struct net_device *dev = pci_get_drvdata(pdev);
+       com20020_remove(dev);
+       release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
 }
 
 static struct pci_device_id com20020pci_id_table[] = {
index b84a5c0669f1a4dbf82c86b4f008bbdd8c37f2f9..6b76a5f8b7abb36a5e60fef3ccf94eed182cee4f 100644 (file)
@@ -180,10 +180,6 @@ int com20020_found(struct net_device *dev, int shared)
        if (!dev->dev_addr[0])
                dev->dev_addr[0] = inb(ioaddr + 8);     /* FIXME: do this some other way! */
 
-       /* reserve the I/O region */
-       if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "arcnet (COM20020)"))
-               return -EBUSY;
-
        SET_SUBADR(SUB_SETUP1);
        outb(lp->setup, _XREG);
 
@@ -207,7 +203,6 @@ int com20020_found(struct net_device *dev, int shared)
        if (request_irq(dev->irq, &arcnet_interrupt, shared,
                        "arcnet (COM20020)", dev)) {
                BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", dev->irq);
-               release_region(ioaddr, ARCNET_TOTAL_SIZE);
                return -ENODEV;
        }
 
@@ -227,7 +222,6 @@ int com20020_found(struct net_device *dev, int shared)
               clockrates[3 - ((lp->setup2 & 0xF0) >> 4) + ((lp->setup & 0x0F) >> 1)]);
 
        if (!dev->init && register_netdev(dev)) {
-               release_region(ioaddr, ARCNET_TOTAL_SIZE);
                free_irq(dev->irq, dev);
                return -EIO;
        }
@@ -342,7 +336,6 @@ void com20020_remove(struct net_device *dev)
 {
        unregister_netdev(dev);
        free_irq(dev->irq, dev);
-       release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
        kfree(dev->priv);
        free_netdev(dev);
 }