diff options
author | J Freyensee <james_p_freyensee@linux.intel.com> | 2010-12-09 10:37:39 +0000 |
---|---|---|
committer | Alan Cox <alan@linux.intel.com> | 2010-12-09 10:37:39 +0000 |
commit | 1fff962cb0af23f837d0b87431df72373d2ac99c (patch) | |
tree | 0f9fbd783e52afd4a5765ec7700143129ebea47a /drivers | |
parent | da2db8c87f7738ab8a789bd549cff1d504ce099f (diff) | |
download | mrst-s0i3-test-1fff962cb0af23f837d0b87431df72373d2ac99c.tar.gz mrst-s0i3-test-1fff962cb0af23f837d0b87431df72373d2ac99c.tar.xz mrst-s0i3-test-1fff962cb0af23f837d0b87431df72373d2ac99c.zip |
PTI driver cleanup path bug fix
This patch addresses some remove issues in the pti_pci_remove() and _exit()
routines in the pti driver that were uncovered in module load and unload
stress testing:
1. a double kfree() issue between the _remove() and _exit() routine
2. pci_release_region() in _remove() that was not really releasing
the region from the _probe() call, thereby causing a BUSY error
on the next load of the driver module.
3. 2. uncovered a corner-case issue in which misc_register() wasn't
called in _probe() before an error-cleanup routine was called which
was causing an issue in the _exit() routine.
4. A couple unregister_driver() calls added to exit().
Signed-off-by: J Freyensee <james_p_freyensee@linux.intel.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/misc/pti.c | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index 83dda4d64e9..f7a56be91cb 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c @@ -366,7 +366,7 @@ static void __devexit pti_pci_remove(struct pci_dev *pdev) pci_iounmap(pdev, drv_data->pti_ioaddr); pci_set_drvdata(pdev, NULL); kfree(drv_data); - pci_release_region(pdev, 0); + pci_release_region(pdev, 1); pci_disable_device(pdev); } } @@ -720,6 +720,15 @@ static int __devinit pti_pci_probe(struct pci_dev *pdev, dev_dbg(&pdev->dev, "%s %s(%d): PTI PCI ID %04x:%04x\n", __FILE__, __func__, __LINE__, pdev->vendor, pdev->device); + retval = misc_register(&pti_char_driver); + if (retval) { + pr_err("%s(%d): CHAR registration failed of pti driver\n", + __func__, __LINE__); + pr_err("%s(%d): Error value returned: %d\n", + __func__, __LINE__, retval); + return retval; + } + retval = pci_enable_device(pdev); if (retval != 0) { dev_err(&pdev->dev, @@ -769,15 +778,6 @@ static int __devinit pti_pci_probe(struct pci_dev *pdev, register_console(&pti_console); - retval = misc_register(&pti_char_driver); - if (retval) { - pr_err("%s(%d): CHAR registration failed of pti driver\n", - __func__, __LINE__); - pr_err("%s(%d): Error value returned: %d\n", - __func__, __LINE__, retval); - return retval; - } - return retval; } @@ -860,27 +860,28 @@ static void __exit pti_exit(void) { int retval; - retval = misc_deregister(&pti_char_driver); + tty_unregister_device(pti_tty_driver, 0); + tty_unregister_device(pti_tty_driver, 1); + + retval = tty_unregister_driver(pti_tty_driver); if (retval) { - pr_err("%s(%d): CHAR unregistration failed of pti driver\n", + pr_err("%s(%d): TTY unregistration failed of pti driver\n", __func__, __LINE__); pr_err("%s(%d): Error value returned: %d\n", __func__, __LINE__, retval); } - tty_unregister_device(pti_tty_driver, 0); - tty_unregister_device(pti_tty_driver, 1); + pci_unregister_driver(&pti_pci_driver); - retval = tty_unregister_driver(pti_tty_driver); + retval = misc_deregister(&pti_char_driver); if (retval) { - pr_err("%s(%d): TTY unregistration failed of pti driver\n", + pr_err("%s(%d): CHAR unregistration failed of pti driver\n", __func__, __LINE__); pr_err("%s(%d): Error value returned: %d\n", __func__, __LINE__, retval); } - kfree(drv_data); - + unregister_console(&pti_console); return; } |