[PATCH 2.6.3] pcnet32.c add PCI hot remove support
From: Don Fry <hidden>
Date: 2004-02-20 22:55:32
This patch adds support for PCI hot remove. Tested on PPC64 boxes. The driver has also been checked to comply with PCMCIA/cardbus remove requirements, but as I don't have a PCMCIA card, it is untested. If a PCMCIA card is removed, reads will return FFFF. The FFFF will cause all while loops to exit.
--- linux-2.6.3/drivers/net/mii.pcnet32.c Fri Feb 20 14:32:10 2004
+++ linux-2.6.3/drivers/net/pcnet32.c Fri Feb 20 14:43:55 2004@@ -935,8 +935,13 @@ if (register_netdev(dev)) goto err_free_consistent; - lp->next = pcnet32_dev; - pcnet32_dev = dev; + if (pdev) { + pci_set_drvdata(pdev, dev); + } else { + lp->next = pcnet32_dev; + pcnet32_dev = dev; + } + printk(KERN_INFO "%s: registered as %s\n",dev->name, lp->name); cards_found++; return 0;
@@ -1330,6 +1335,9 @@ rap = lp->a.read_rap(ioaddr); while ((csr0 = lp->a.read_csr (ioaddr, 0)) & 0x8600 && --boguscnt >= 0) { + if (csr == 0xffff) { + break; /* PCMCIA remove happened */ + } /* Acknowledge all of the current interrupt sources ASAP. */ lp->a.write_csr (ioaddr, 0, csr0 & ~0x004f);
@@ -1764,9 +1772,25 @@ mod_timer (&(lp->watchdog_timer), PCNET32_WATCHDOG_TIMEOUT); } +static void __devexit pcnet32_remove_one(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + + if (dev) { + struct pcnet32_private *lp = dev->priv; + + unregister_netdev(dev); + release_region(dev->base_addr, PCNET32_TOTAL_SIZE); + pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr); + free_netdev(dev); + pci_set_drvdata(pdev, NULL); + } +} + static struct pci_driver pcnet32_driver = { .name = DRV_NAME, .probe = pcnet32_probe_pci, + .remove = __devexit_p(pcnet32_remove_one), .id_table = pcnet32_pci_tbl, };
--
Don Fry
brazilnut@us.ibm.com