aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/dgnc
diff options
context:
space:
mode:
authorSudip Mukherjee <sudipm.mukherjee@gmail.com>2016-02-27 17:33:35 +0530
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-03-11 22:09:09 -0800
commit18f038e6bfb715310526ac05e4f20e55683471de (patch)
tree6334d23c572551408e07740a51e61d95f13e56a8 /drivers/staging/dgnc
parentstaging: dgnc: unregister pci driver (diff)
downloadlinux-dev-18f038e6bfb715310526ac05e4f20e55683471de.tar.xz
linux-dev-18f038e6bfb715310526ac05e4f20e55683471de.zip
staging: dgnc: cleanup properly
dgnc_cleanup_module() was called when the module unloaded to do a total cleanup and it was also called if pci_register_driver() fails. But dgnc_cleanup_module() will try dgnc_remove_driver_sysfiles() but the sysfiles will be created only if pci_register_driver() succeeds. So if pci_register_driver() fails and we try dgnc_cleanup_module() then we were getting: [ 942.001479] BUG: unable to handle kernel NULL pointer dereference at 00000018 [ 942.001482] IP: [<c122c7a8>] sysfs_remove_file_ns+0x8/0x20 with part of the call trace as: [ 942.001544] Call Trace: [ 942.001555] [<c149acc6>] driver_remove_file+0x16/0x20 [ 942.001571] [<f864a708>] dgnc_remove_driver_sysfiles+0x18/0x40 [dgnc] [ 942.001575] [<f8643ac7>] dgnc_cleanup_module+0x47/0x260 [dgnc] [ 942.001577] [<f86cb000>] ? 0xf86cb000 [ 942.001580] [<f86cb1e6>] dgnc_init_module+0x1e6/0x1000 [dgnc] Lets have a separate cleanup function which will execute dgnc_remove_driver_sysfiles() depending on the argument passed to it. Reported-by: Navy Cheng <navych@126.com> Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/dgnc')
-rw-r--r--drivers/staging/dgnc/dgnc_driver.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c
index 22a92d15ee9d..4eb410e09609 100644
--- a/drivers/staging/dgnc/dgnc_driver.c
+++ b/drivers/staging/dgnc/dgnc_driver.c
@@ -125,12 +125,7 @@ static struct pci_driver dgnc_driver = {
*
************************************************************************/
-/*
- * dgnc_cleanup_module()
- *
- * Module unload. This is where it all ends.
- */
-static void dgnc_cleanup_module(void)
+static void cleanup(bool sysfiles)
{
int i;
unsigned long flags;
@@ -142,7 +137,8 @@ static void dgnc_cleanup_module(void)
/* Turn off poller right away. */
del_timer_sync(&dgnc_poll_timer);
- dgnc_remove_driver_sysfiles(&dgnc_driver);
+ if (sysfiles)
+ dgnc_remove_driver_sysfiles(&dgnc_driver);
device_destroy(dgnc_class, MKDEV(dgnc_Major, 0));
class_destroy(dgnc_class);
@@ -155,7 +151,16 @@ static void dgnc_cleanup_module(void)
}
dgnc_tty_post_uninit();
+}
+/*
+ * dgnc_cleanup_module()
+ *
+ * Module unload. This is where it all ends.
+ */
+static void dgnc_cleanup_module(void)
+{
+ cleanup(true);
pci_unregister_driver(&dgnc_driver);
}
@@ -182,7 +187,7 @@ static int __init dgnc_init_module(void)
rc = pci_register_driver(&dgnc_driver);
if (rc) {
pr_warn("WARNING: dgnc driver load failed. No Digi Neo or Classic boards found.\n");
- dgnc_cleanup_module();
+ cleanup(false);
return rc;
}
dgnc_create_driver_sysfiles(&dgnc_driver);