[PATCH] Handling failure of pci_register_driver().

From: Daniel Kobras (daniel.kobras@student.uni-tuebingen.de)
Date: Sun Feb 20 2000 - 12:01:19 EST


Hi!

There's an issue with the new PCI register interface: a return value of 0
from pci_register_driver() does _not_ indicate failed registration; the
supplied pci_driver struct is linked in the pci_drivers list even if no
matching PCI devices were found. This behaviour makes tons of sense when
thinking of hot pluggable devices. Unfortunately every non-cardbus driver
in 2.3.46 using pci_register_driver() gets it wrong and bails out from its
module_init() routine immediately on a zero return value, leaving a stale
entry in the pci_drivers list -> Oops... Instead, if a driver chooses to
treat a zero return value from pci_register_driver() as an error in its
init routine, it has to unregister the driver first. The patch below
should fix the affected drivers as of kernel version 2.3.46.

Regards,

Daniel.

--[snip]--

--- drivers/net/8139too.c.orig Sun Feb 20 16:22:26 2000
+++ drivers/net/8139too.c Sun Feb 20 17:24:59 2000
@@ -1865,6 +1865,8 @@
                 printk (KERN_INFO RTL8139_DRIVER_NAME
                         " loaded (%d device%s registered)\n",
                         rc, rc > 1 ? "s" : "");
+ } else {
+ pci_unregister_driver (&rtl8139_pci_driver);
         }
 
         DPRINTK ("EXIT\n");
--- drivers/net/eepro100.c.orig Sun Feb 20 17:23:48 2000
+++ drivers/net/eepro100.c Sun Feb 20 17:25:46 2000
@@ -1846,6 +1846,7 @@
         cards_found = pci_register_driver (&eepro100_driver);
         if (cards_found <= 0) {
                 printk(KERN_INFO PFX "No cards found, driver not installed.\n");
+ pci_unregister_driver (&eepro100_driver);
                 return -ENODEV;
         }
 
--- drivers/net/epic100.c.orig Sun Feb 20 17:23:59 2000
+++ drivers/net/epic100.c Sun Feb 20 17:26:04 2000
@@ -1285,6 +1285,7 @@
         if (pci_register_driver (&epic100_driver) > 0)
                 return 0;
         
+ pci_unregister_driver (&epic100_driver);
         return -ENODEV;
 }
 
--- drivers/net/tulip.c.orig Sun Feb 20 17:24:14 2000
+++ drivers/net/tulip.c Sun Feb 20 17:27:07 2000
@@ -3078,7 +3078,11 @@
 
 static int __init tulip_init (void)
 {
- return pci_register_driver (&tulip_driver) > 0 ? 0 : -ENODEV;
+ if (pci_register_driver (&tulip_driver) > 0)
+ return 0;
+
+ pci_unregister_driver (&tulip_driver);
+ return -ENODEV;
 }
 
 
--- drivers/net/yellowfin.c.orig Sun Feb 20 17:24:21 2000
+++ drivers/net/yellowfin.c Sun Feb 20 17:27:44 2000
@@ -1378,7 +1378,12 @@
 {
         if (debug) /* Emit version even if no cards detected. */
                 printk(KERN_INFO "%s", version);
- return pci_register_driver (&yellowfin_driver) > 0 ? 0 : -ENODEV;
+
+ if (pci_register_driver (&yellowfin_driver) > 0)
+ return 0;
+
+ pci_unregister_driver (&yellowfin_driver);
+ return -ENODEV;
 }
 
 
--- drivers/sound/es1370.c.orig Sun Feb 20 17:28:30 2000
+++ drivers/sound/es1370.c Sun Feb 20 17:29:14 2000
@@ -2608,8 +2608,10 @@
         if (!pci_present()) /* No PCI bus in this machine! */
                 return -ENODEV;
         printk(KERN_INFO "es1370: version v0.33 time " __TIME__ " " __DATE__ "\n");
- if (!pci_register_driver(&es1370_driver))
+ if (!pci_register_driver(&es1370_driver)) {
+ pci_unregister_driver(&es1370_driver);
                 return -ENODEV;
+ }
         return 0;
 
 }
--- drivers/sound/es1371.c.orig Sun Feb 20 17:28:34 2000
+++ drivers/sound/es1371.c Sun Feb 20 17:29:37 2000
@@ -2809,8 +2809,10 @@
         if (!pci_present()) /* No PCI bus in this machine! */
                 return -ENODEV;
         printk(KERN_INFO "es1371: version v0.25 time " __TIME__ " " __DATE__ "\n");
- if (!pci_register_driver(&es1371_driver))
+ if (!pci_register_driver(&es1371_driver)) {
+ pci_unregister_driver(&es1371_driver);
                 return -ENODEV;
+ }
         return 0;
 }
 
--- drivers/sound/esssolo1.c.orig Sun Feb 20 17:28:39 2000
+++ drivers/sound/esssolo1.c Sun Feb 20 17:30:04 2000
@@ -2338,8 +2338,10 @@
         if (!pci_present()) /* No PCI bus in this machine! */
                 return -ENODEV;
         printk(KERN_INFO "solo1: version v0.13 time " __TIME__ " " __DATE__ "\n");
- if (!pci_register_driver(&solo1_driver))
+ if (!pci_register_driver(&solo1_driver)) {
+ pci_unregister_driver(&solo1_driver);
                 return -ENODEV;
+ }
         return 0;
 }
 
--- drivers/sound/sonicvibes.c.orig Sun Feb 20 17:28:51 2000
+++ drivers/sound/sonicvibes.c Sun Feb 20 17:30:38 2000
@@ -2648,8 +2648,10 @@
         if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
                 printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
 #endif
- if (!pci_register_driver(&sv_driver))
+ if (!pci_register_driver(&sv_driver)) {
+ pci_unregister_driver(&sv_driver);
                 return -ENODEV;
+ }
         return 0;
 }
 

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Feb 23 2000 - 21:00:25 EST