Skip to content

Commit

Permalink
[PATCH] Char: stallion, fix fail paths
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jiri Slaby authored and Linus Torvalds committed Dec 8, 2006
1 parent 843b568 commit fc06b5c
Showing 1 changed file with 52 additions and 29 deletions.
81 changes: 52 additions & 29 deletions drivers/char/stallion.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ static struct stlbrd *stl_brds[STL_MAXBRDS];
* Not really much here!
*/
#define BRD_FOUND 0x1
#define STL_PROBED 0x2


/*
* Define the port structure istate flags. These set of flags are
Expand Down Expand Up @@ -2388,6 +2390,7 @@ static int __devinit stl_pciprobe(struct pci_dev *pdev,
goto err_fr;
}
brdp->brdtype = brdtype;
brdp->state |= STL_PROBED;

/*
* We have all resources from the board, so let's setup the actual
Expand Down Expand Up @@ -4677,14 +4680,37 @@ static void stl_sc26198otherisr(struct stlport *portp, unsigned int iack)
}
}

static void stl_free_isabrds(void)
{
struct stlbrd *brdp;
unsigned int i;

for (i = 0; i < stl_nrbrds; i++) {
if ((brdp = stl_brds[i]) == NULL || (brdp->state & STL_PROBED))
continue;

free_irq(brdp->irq, brdp);

stl_cleanup_panels(brdp);

release_region(brdp->ioaddr1, brdp->iosize1);
if (brdp->iosize2 > 0)
release_region(brdp->ioaddr2, brdp->iosize2);

kfree(brdp);
stl_brds[i] = NULL;
}
}

/*
* Loadable module initialization stuff.
*/
static int __init stallion_module_init(void)
{
struct stlbrd *brdp;
struct stlconf conf;
unsigned int i, retval;
unsigned int i;
int retval;

printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion);

Expand Down Expand Up @@ -4714,12 +4740,14 @@ static int __init stallion_module_init(void)
}

retval = pci_register_driver(&stl_pcidriver);
if (retval)
if (retval && stl_nrbrds == 0)
goto err;

stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
if (!stl_serial)
return -1;
if (!stl_serial) {
retval = -ENOMEM;
goto err_pcidr;
}

/*
* Set up a character driver for per board stuff. This is mainly used
Expand All @@ -4729,6 +4757,10 @@ static int __init stallion_module_init(void)
printk("STALLION: failed to register serial board device\n");

stallion_class = class_create(THIS_MODULE, "staliomem");
if (IS_ERR(stallion_class)) {
retval = PTR_ERR(stallion_class);
goto err_reg;
}
for (i = 0; i < 4; i++)
class_device_create(stallion_class, NULL,
MKDEV(STL_SIOMEMMAJOR, i), NULL,
Expand All @@ -4745,20 +4777,29 @@ static int __init stallion_module_init(void)
stl_serial->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(stl_serial, &stl_ops);

if (tty_register_driver(stl_serial)) {
put_tty_driver(stl_serial);
retval = tty_register_driver(stl_serial);
if (retval) {
printk("STALLION: failed to register serial driver\n");
return -1;
goto err_clsdev;
}

return 0;
err_clsdev:
for (i = 0; i < 4; i++)
class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
class_destroy(stallion_class);
err_reg:
unregister_chrdev(STL_SIOMEMMAJOR, "staliomem");
put_tty_driver(stl_serial);
err_pcidr:
pci_unregister_driver(&stl_pcidriver);
stl_free_isabrds();
err:
return retval;
}

static void __exit stallion_module_exit(void)
{
struct stlbrd *brdp;
int i;

pr_debug("cleanup_module()\n");
Expand All @@ -4772,13 +4813,9 @@ static void __exit stallion_module_exit(void)
* a hangup on every open port - to try to flush out any processes
* hanging onto ports.
*/
i = tty_unregister_driver(stl_serial);
tty_unregister_driver(stl_serial);
put_tty_driver(stl_serial);
if (i) {
printk("STALLION: failed to un-register tty driver, "
"errno=%d\n", -i);
return;
}

for (i = 0; i < 4; i++)
class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
Expand All @@ -4788,21 +4825,7 @@ static void __exit stallion_module_exit(void)

pci_unregister_driver(&stl_pcidriver);

for (i = 0; (i < stl_nrbrds); i++) {
if ((brdp = stl_brds[i]) == NULL)
continue;

free_irq(brdp->irq, brdp);

stl_cleanup_panels(brdp);

release_region(brdp->ioaddr1, brdp->iosize1);
if (brdp->iosize2 > 0)
release_region(brdp->ioaddr2, brdp->iosize2);

kfree(brdp);
stl_brds[i] = NULL;
}
stl_free_isabrds();
}

module_init(stallion_module_init);
Expand Down

0 comments on commit fc06b5c

Please sign in to comment.