aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2006-12-08 05:39:13 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-08 11:28:59 -0500
commitfc06b5cf858787934110b9398d2d5a0c0493c1dd (patch)
treeb0c7b21e911039695149eb557397e27406c101cd /drivers/char
parent843b568cf0c800b87e48fcfb171a7a83318db39c (diff)
[PATCH] Char: stallion, fix fail paths
Release everything what was allocated and check return value of isa probing. Release only ISA boards in module exit, since pci have their own pci-probing-remove. Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/stallion.c81
1 files changed, 52 insertions, 29 deletions
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 4ccf4a5834c9..7612464beeb1 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -143,6 +143,8 @@ static struct stlbrd *stl_brds[STL_MAXBRDS];
143 * Not really much here! 143 * Not really much here!
144 */ 144 */
145#define BRD_FOUND 0x1 145#define BRD_FOUND 0x1
146#define STL_PROBED 0x2
147
146 148
147/* 149/*
148 * Define the port structure istate flags. These set of flags are 150 * Define the port structure istate flags. These set of flags are
@@ -2388,6 +2390,7 @@ static int __devinit stl_pciprobe(struct pci_dev *pdev,
2388 goto err_fr; 2390 goto err_fr;
2389 } 2391 }
2390 brdp->brdtype = brdtype; 2392 brdp->brdtype = brdtype;
2393 brdp->state |= STL_PROBED;
2391 2394
2392/* 2395/*
2393 * We have all resources from the board, so let's setup the actual 2396 * We have all resources from the board, so let's setup the actual
@@ -4677,6 +4680,28 @@ static void stl_sc26198otherisr(struct stlport *portp, unsigned int iack)
4677 } 4680 }
4678} 4681}
4679 4682
4683static void stl_free_isabrds(void)
4684{
4685 struct stlbrd *brdp;
4686 unsigned int i;
4687
4688 for (i = 0; i < stl_nrbrds; i++) {
4689 if ((brdp = stl_brds[i]) == NULL || (brdp->state & STL_PROBED))
4690 continue;
4691
4692 free_irq(brdp->irq, brdp);
4693
4694 stl_cleanup_panels(brdp);
4695
4696 release_region(brdp->ioaddr1, brdp->iosize1);
4697 if (brdp->iosize2 > 0)
4698 release_region(brdp->ioaddr2, brdp->iosize2);
4699
4700 kfree(brdp);
4701 stl_brds[i] = NULL;
4702 }
4703}
4704
4680/* 4705/*
4681 * Loadable module initialization stuff. 4706 * Loadable module initialization stuff.
4682 */ 4707 */
@@ -4684,7 +4709,8 @@ static int __init stallion_module_init(void)
4684{ 4709{
4685 struct stlbrd *brdp; 4710 struct stlbrd *brdp;
4686 struct stlconf conf; 4711 struct stlconf conf;
4687 unsigned int i, retval; 4712 unsigned int i;
4713 int retval;
4688 4714
4689 printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); 4715 printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion);
4690 4716
@@ -4714,12 +4740,14 @@ static int __init stallion_module_init(void)
4714 } 4740 }
4715 4741
4716 retval = pci_register_driver(&stl_pcidriver); 4742 retval = pci_register_driver(&stl_pcidriver);
4717 if (retval) 4743 if (retval && stl_nrbrds == 0)
4718 goto err; 4744 goto err;
4719 4745
4720 stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); 4746 stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
4721 if (!stl_serial) 4747 if (!stl_serial) {
4722 return -1; 4748 retval = -ENOMEM;
4749 goto err_pcidr;
4750 }
4723 4751
4724/* 4752/*
4725 * Set up a character driver for per board stuff. This is mainly used 4753 * Set up a character driver for per board stuff. This is mainly used
@@ -4729,6 +4757,10 @@ static int __init stallion_module_init(void)
4729 printk("STALLION: failed to register serial board device\n"); 4757 printk("STALLION: failed to register serial board device\n");
4730 4758
4731 stallion_class = class_create(THIS_MODULE, "staliomem"); 4759 stallion_class = class_create(THIS_MODULE, "staliomem");
4760 if (IS_ERR(stallion_class)) {
4761 retval = PTR_ERR(stallion_class);
4762 goto err_reg;
4763 }
4732 for (i = 0; i < 4; i++) 4764 for (i = 0; i < 4; i++)
4733 class_device_create(stallion_class, NULL, 4765 class_device_create(stallion_class, NULL,
4734 MKDEV(STL_SIOMEMMAJOR, i), NULL, 4766 MKDEV(STL_SIOMEMMAJOR, i), NULL,
@@ -4745,20 +4777,29 @@ static int __init stallion_module_init(void)
4745 stl_serial->flags = TTY_DRIVER_REAL_RAW; 4777 stl_serial->flags = TTY_DRIVER_REAL_RAW;
4746 tty_set_operations(stl_serial, &stl_ops); 4778 tty_set_operations(stl_serial, &stl_ops);
4747 4779
4748 if (tty_register_driver(stl_serial)) { 4780 retval = tty_register_driver(stl_serial);
4749 put_tty_driver(stl_serial); 4781 if (retval) {
4750 printk("STALLION: failed to register serial driver\n"); 4782 printk("STALLION: failed to register serial driver\n");
4751 return -1; 4783 goto err_clsdev;
4752 } 4784 }
4753 4785
4754 return 0; 4786 return 0;
4787err_clsdev:
4788 for (i = 0; i < 4; i++)
4789 class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
4790 class_destroy(stallion_class);
4791err_reg:
4792 unregister_chrdev(STL_SIOMEMMAJOR, "staliomem");
4793 put_tty_driver(stl_serial);
4794err_pcidr:
4795 pci_unregister_driver(&stl_pcidriver);
4796 stl_free_isabrds();
4755err: 4797err:
4756 return retval; 4798 return retval;
4757} 4799}
4758 4800
4759static void __exit stallion_module_exit(void) 4801static void __exit stallion_module_exit(void)
4760{ 4802{
4761 struct stlbrd *brdp;
4762 int i; 4803 int i;
4763 4804
4764 pr_debug("cleanup_module()\n"); 4805 pr_debug("cleanup_module()\n");
@@ -4772,13 +4813,9 @@ static void __exit stallion_module_exit(void)
4772 * a hangup on every open port - to try to flush out any processes 4813 * a hangup on every open port - to try to flush out any processes
4773 * hanging onto ports. 4814 * hanging onto ports.
4774 */ 4815 */
4775 i = tty_unregister_driver(stl_serial); 4816 tty_unregister_driver(stl_serial);
4776 put_tty_driver(stl_serial); 4817 put_tty_driver(stl_serial);
4777 if (i) { 4818
4778 printk("STALLION: failed to un-register tty driver, "
4779 "errno=%d\n", -i);
4780 return;
4781 }
4782 for (i = 0; i < 4; i++) 4819 for (i = 0; i < 4; i++)
4783 class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); 4820 class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
4784 if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) 4821 if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
@@ -4788,21 +4825,7 @@ static void __exit stallion_module_exit(void)
4788 4825
4789 pci_unregister_driver(&stl_pcidriver); 4826 pci_unregister_driver(&stl_pcidriver);
4790 4827
4791 for (i = 0; (i < stl_nrbrds); i++) { 4828 stl_free_isabrds();
4792 if ((brdp = stl_brds[i]) == NULL)
4793 continue;
4794
4795 free_irq(brdp->irq, brdp);
4796
4797 stl_cleanup_panels(brdp);
4798
4799 release_region(brdp->ioaddr1, brdp->iosize1);
4800 if (brdp->iosize2 > 0)
4801 release_region(brdp->ioaddr2, brdp->iosize2);
4802
4803 kfree(brdp);
4804 stl_brds[i] = NULL;
4805 }
4806} 4829}
4807 4830
4808module_init(stallion_module_init); 4831module_init(stallion_module_init);