aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2005-11-05 16:20:21 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-11-05 16:20:21 -0500
commit5d994b7f5d1c77acaa0b9b4c1b9f0f278605c309 (patch)
tree6c74ec305642a6e74c522c22223ff57a96793049
parent37c12e7497b6fe2b6a890814f0ff4edce696d862 (diff)
[DRIVER MODEL] Fix depca
Release code in driver modules is a potential cause of oopsen. The device may be in use by a userspace process, which will keep a reference to the device. If the module is unloaded, the module text will be freed. Subsequently, when the last reference is dropped, the release code will be called, which no longer exists. Use generic platform device allocation/release code in modules. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/net/depca.c24
1 files changed, 7 insertions, 17 deletions
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 4d26e5e7d18b..0d33a93df96b 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -1470,15 +1470,6 @@ static int __init depca_mca_probe(struct device *device)
1470** ISA bus I/O device probe 1470** ISA bus I/O device probe
1471*/ 1471*/
1472 1472
1473static void depca_platform_release (struct device *device)
1474{
1475 struct platform_device *pldev;
1476
1477 /* free device */
1478 pldev = to_platform_device (device);
1479 kfree (pldev);
1480}
1481
1482static void __init depca_platform_probe (void) 1473static void __init depca_platform_probe (void)
1483{ 1474{
1484 int i; 1475 int i;
@@ -1491,19 +1482,16 @@ static void __init depca_platform_probe (void)
1491 * line, use it (if valid) */ 1482 * line, use it (if valid) */
1492 if (io && io != depca_io_ports[i].iobase) 1483 if (io && io != depca_io_ports[i].iobase)
1493 continue; 1484 continue;
1494 1485
1495 if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) 1486 pldev = platform_device_alloc(depca_string, i);
1487 if (!pldev)
1496 continue; 1488 continue;
1497 1489
1498 memset (pldev, 0, sizeof (*pldev));
1499 pldev->name = depca_string;
1500 pldev->id = i;
1501 pldev->dev.platform_data = (void *) depca_io_ports[i].iobase; 1490 pldev->dev.platform_data = (void *) depca_io_ports[i].iobase;
1502 pldev->dev.release = depca_platform_release;
1503 depca_io_ports[i].device = pldev; 1491 depca_io_ports[i].device = pldev;
1504 1492
1505 if (platform_device_register (pldev)) { 1493 if (platform_device_add(pldev)) {
1506 kfree (pldev); 1494 platform_device_put(pldev);
1507 depca_io_ports[i].device = NULL; 1495 depca_io_ports[i].device = NULL;
1508 continue; 1496 continue;
1509 } 1497 }
@@ -1515,6 +1503,7 @@ static void __init depca_platform_probe (void)
1515 * allocated structure */ 1503 * allocated structure */
1516 1504
1517 depca_io_ports[i].device = NULL; 1505 depca_io_ports[i].device = NULL;
1506 pldev->dev.platform_data = NULL;
1518 platform_device_unregister (pldev); 1507 platform_device_unregister (pldev);
1519 } 1508 }
1520 } 1509 }
@@ -2112,6 +2101,7 @@ static void __exit depca_module_exit (void)
2112 2101
2113 for (i = 0; depca_io_ports[i].iobase; i++) { 2102 for (i = 0; depca_io_ports[i].iobase; i++) {
2114 if (depca_io_ports[i].device) { 2103 if (depca_io_ports[i].device) {
2104 depca_io_ports[i].device->dev.platform_data = NULL;
2115 platform_device_unregister (depca_io_ports[i].device); 2105 platform_device_unregister (depca_io_ports[i].device);
2116 depca_io_ports[i].device = NULL; 2106 depca_io_ports[i].device = NULL;
2117 } 2107 }