Commit df6a797d authored by Paul Fulghum's avatar Paul Fulghum Committed by Linus Torvalds

[PATCH] synclink_cs.c driver init modifications

* Fix cleanup on driver init failure
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent ef00b707
/* /*
* linux/drivers/char/pcmcia/synclink_cs.c * linux/drivers/char/pcmcia/synclink_cs.c
* *
* $Id: synclink_cs.c,v 4.21 2004/03/08 15:29:23 paulkf Exp $ * $Id: synclink_cs.c,v 4.22 2004/06/01 20:27:46 paulkf Exp $
* *
* Device driver for Microgate SyncLink PC Card * Device driver for Microgate SyncLink PC Card
* multiprotocol serial adapter. * multiprotocol serial adapter.
...@@ -489,7 +489,7 @@ MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICE_COUNT) "i"); ...@@ -489,7 +489,7 @@ MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICE_COUNT) "i");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static char *driver_name = "SyncLink PC Card driver"; static char *driver_name = "SyncLink PC Card driver";
static char *driver_version = "$Revision: 4.21 $"; static char *driver_version = "$Revision: 4.22 $";
static struct tty_driver *serial_driver; static struct tty_driver *serial_driver;
...@@ -3133,9 +3133,35 @@ static struct tty_operations mgslpc_ops = { ...@@ -3133,9 +3133,35 @@ static struct tty_operations mgslpc_ops = {
.tiocmset = tiocmset, .tiocmset = tiocmset,
}; };
static void synclink_cs_cleanup(void)
{
int rc;
printk("Unloading %s: version %s\n", driver_name, driver_version);
while(mgslpc_device_list)
mgslpc_remove_device(mgslpc_device_list);
if (serial_driver) {
if ((rc = tty_unregister_driver(serial_driver)))
printk("%s(%d) failed to unregister tty driver err=%d\n",
__FILE__,__LINE__,rc);
put_tty_driver(serial_driver);
}
pcmcia_unregister_driver(&mgslpc_driver);
/* XXX: this really needs to move into generic code.. */
while (dev_list != NULL) {
if (dev_list->state & DEV_CONFIG)
mgslpc_release((u_long)dev_list);
mgslpc_detach(dev_list);
}
}
static int __init synclink_cs_init(void) static int __init synclink_cs_init(void)
{ {
int error; int rc;
if (break_on_load) { if (break_on_load) {
mgslpc_get_text_ptr(); mgslpc_get_text_ptr();
...@@ -3144,14 +3170,13 @@ static int __init synclink_cs_init(void) ...@@ -3144,14 +3170,13 @@ static int __init synclink_cs_init(void)
printk("%s %s\n", driver_name, driver_version); printk("%s %s\n", driver_name, driver_version);
serial_driver = alloc_tty_driver(MAX_DEVICE_COUNT); if ((rc = pcmcia_register_driver(&mgslpc_driver)) < 0)
if (!serial_driver) return rc;
return -ENOMEM;
error = pcmcia_register_driver(&mgslpc_driver); serial_driver = alloc_tty_driver(MAX_DEVICE_COUNT);
if (error) { if (!serial_driver) {
put_tty_driver(serial_driver); rc = -ENOMEM;
return error; goto error;
} }
/* Initialize the tty_driver structure */ /* Initialize the tty_driver structure */
...@@ -3169,39 +3194,28 @@ static int __init synclink_cs_init(void) ...@@ -3169,39 +3194,28 @@ static int __init synclink_cs_init(void)
serial_driver->flags = TTY_DRIVER_REAL_RAW; serial_driver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(serial_driver, &mgslpc_ops); tty_set_operations(serial_driver, &mgslpc_ops);
if (tty_register_driver(serial_driver) < 0) if ((rc = tty_register_driver(serial_driver)) < 0) {
printk("%s(%d):Couldn't register serial driver\n", printk("%s(%d):Couldn't register serial driver\n",
__FILE__,__LINE__); __FILE__,__LINE__);
put_tty_driver(serial_driver);
serial_driver = NULL;
goto error;
}
printk("%s %s, tty major#%d\n", printk("%s %s, tty major#%d\n",
driver_name, driver_version, driver_name, driver_version,
serial_driver->major); serial_driver->major);
return 0; return 0;
error:
synclink_cs_cleanup();
return rc;
} }
static void __exit synclink_cs_exit(void) static void __exit synclink_cs_exit(void)
{ {
int rc; synclink_cs_cleanup();
printk("Unloading %s: version %s\n", driver_name, driver_version);
while(mgslpc_device_list)
mgslpc_remove_device(mgslpc_device_list);
if ((rc = tty_unregister_driver(serial_driver)))
printk("%s(%d) failed to unregister tty driver err=%d\n",
__FILE__,__LINE__,rc);
put_tty_driver(serial_driver);
pcmcia_unregister_driver(&mgslpc_driver);
/* XXX: this really needs to move into generic code.. */
while (dev_list != NULL) {
if (dev_list->state & DEV_CONFIG)
mgslpc_release((u_long)dev_list);
mgslpc_detach(dev_list);
}
} }
module_init(synclink_cs_init); module_init(synclink_cs_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