Commit f2362c94 authored by Jiri Slaby's avatar Jiri Slaby Committed by Linus Torvalds

[PATCH] Char: istallion, change init sequence

Reorganizate module init and exit and implement logic, when something fails in
these functions.  The former is needed for proper handling dynamic
tty_register_device.
Signed-off-by: default avatarJiri Slaby <jirislaby@gmail.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f1cc54f8
...@@ -4545,46 +4545,49 @@ static const struct tty_operations stli_ops = { ...@@ -4545,46 +4545,49 @@ static const struct tty_operations stli_ops = {
* Loadable module initialization stuff. * Loadable module initialization stuff.
*/ */
static void istallion_cleanup_isa(void)
{
struct stlibrd *brdp;
unsigned int j;
for (j = 0; (j < stli_nrbrds); j++) {
if ((brdp = stli_brds[j]) == NULL || (brdp->state & BST_PROBED))
continue;
stli_cleanup_ports(brdp);
iounmap(brdp->membase);
if (brdp->iosize > 0)
release_region(brdp->iobase, brdp->iosize);
kfree(brdp);
stli_brds[j] = NULL;
}
}
static int __init istallion_module_init(void) static int __init istallion_module_init(void)
{ {
int i; unsigned int i;
int retval;
printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion); printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion);
spin_lock_init(&stli_lock); spin_lock_init(&stli_lock);
spin_lock_init(&brd_lock); spin_lock_init(&brd_lock);
stli_initbrds();
stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
if (!stli_serial)
return -ENOMEM;
/*
* Allocate a temporary write buffer.
*/
stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);
if (!stli_txcookbuf) if (!stli_txcookbuf) {
printk(KERN_ERR "STALLION: failed to allocate memory " printk(KERN_ERR "STALLION: failed to allocate memory "
"(size=%d)\n", STLI_TXBUFSIZE); "(size=%d)\n", STLI_TXBUFSIZE);
retval = -ENOMEM;
goto err;
}
/* stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS);
* Set up a character driver for the shared memory region. We need this if (!stli_serial) {
* to down load the slave code image. Also it is a useful debugging tool. retval = -ENOMEM;
*/ goto err_free;
if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem)) }
printk(KERN_ERR "STALLION: failed to register serial memory "
"device\n");
istallion_class = class_create(THIS_MODULE, "staliomem");
for (i = 0; i < 4; i++)
class_device_create(istallion_class, NULL,
MKDEV(STL_SIOMEMMAJOR, i),
NULL, "staliomem%d", i);
/*
* Set up the tty driver structure and register us as a driver.
*/
stli_serial->owner = THIS_MODULE; stli_serial->owner = THIS_MODULE;
stli_serial->driver_name = stli_drvname; stli_serial->driver_name = stli_drvname;
stli_serial->name = stli_serialname; stli_serial->name = stli_serialname;
...@@ -4596,58 +4599,75 @@ static int __init istallion_module_init(void) ...@@ -4596,58 +4599,75 @@ static int __init istallion_module_init(void)
stli_serial->flags = TTY_DRIVER_REAL_RAW; stli_serial->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(stli_serial, &stli_ops); tty_set_operations(stli_serial, &stli_ops);
if (tty_register_driver(stli_serial)) { retval = tty_register_driver(stli_serial);
put_tty_driver(stli_serial); if (retval) {
printk(KERN_ERR "STALLION: failed to register serial driver\n"); printk(KERN_ERR "STALLION: failed to register serial driver\n");
return -EBUSY; goto err_ttyput;
}
retval = stli_initbrds();
if (retval)
goto err_ttyunr;
/*
* Set up a character driver for the shared memory region. We need this
* to down load the slave code image. Also it is a useful debugging tool.
*/
retval = register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem);
if (retval) {
printk(KERN_ERR "STALLION: failed to register serial memory "
"device\n");
goto err_deinit;
} }
istallion_class = class_create(THIS_MODULE, "staliomem");
for (i = 0; i < 4; i++)
class_device_create(istallion_class, NULL,
MKDEV(STL_SIOMEMMAJOR, i),
NULL, "staliomem%d", i);
return 0; return 0;
err_deinit:
pci_unregister_driver(&stli_pcidriver);
istallion_cleanup_isa();
err_ttyunr:
tty_unregister_driver(stli_serial);
err_ttyput:
put_tty_driver(stli_serial);
err_free:
kfree(stli_txcookbuf);
err:
return retval;
} }
/*****************************************************************************/ /*****************************************************************************/
static void __exit istallion_module_exit(void) static void __exit istallion_module_exit(void)
{ {
struct stlibrd *brdp;
unsigned int j; unsigned int j;
int i;
printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle, printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle,
stli_drvversion); stli_drvversion);
pci_unregister_driver(&stli_pcidriver);
/*
* Free up all allocated resources used by the ports. This includes
* memory and interrupts.
*/
if (stli_timeron) { if (stli_timeron) {
stli_timeron = 0; stli_timeron = 0;
del_timer_sync(&stli_timerlist); del_timer_sync(&stli_timerlist);
} }
i = tty_unregister_driver(stli_serial); unregister_chrdev(STL_SIOMEMMAJOR, "staliomem");
put_tty_driver(stli_serial);
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, j)); class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR,
j));
class_destroy(istallion_class); class_destroy(istallion_class);
if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
printk("STALLION: failed to un-register serial memory device, "
"errno=%d\n", -i);
kfree(stli_txcookbuf);
for (j = 0; (j < stli_nrbrds); j++) { pci_unregister_driver(&stli_pcidriver);
if ((brdp = stli_brds[j]) == NULL || (brdp->state & BST_PROBED)) istallion_cleanup_isa();
continue;
stli_cleanup_ports(brdp); tty_unregister_driver(stli_serial);
put_tty_driver(stli_serial);
iounmap(brdp->membase); kfree(stli_txcookbuf);
if (brdp->iosize > 0)
release_region(brdp->iobase, brdp->iosize);
kfree(brdp);
stli_brds[j] = NULL;
}
} }
module_init(istallion_module_init); module_init(istallion_module_init);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment