2004-06-03 15:50:48

by Paul Fulghum

[permalink] [raw]
Subject: [PATCH] 2.6.6 synclink_cs.c driver init modifications

Changelog:

* Fix cleanup on driver init failure


--
Paul Fulghum
[email protected]


--- linux-2.6.6/drivers/char/pcmcia/synclink_cs.c 2004-06-01 15:30:02.945252239 -0500
+++ linux-2.6.6-mg1/drivers/char/pcmcia/synclink_cs.c 2004-06-01 15:28:41.033080615 -0500
@@ -1,7 +1,7 @@
/*
* 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
* multiprotocol serial adapter.
@@ -489,7 +489,7 @@
MODULE_LICENSE("GPL");

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;

@@ -3130,9 +3130,35 @@
.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)
{
- int error;
+ int rc;

if (break_on_load) {
mgslpc_get_text_ptr();
@@ -3141,14 +3167,13 @@

printk("%s %s\n", driver_name, driver_version);

- serial_driver = alloc_tty_driver(MAX_DEVICE_COUNT);
- if (!serial_driver)
- return -ENOMEM;
+ if ((rc = pcmcia_register_driver(&mgslpc_driver)) < 0)
+ return rc;

- error = pcmcia_register_driver(&mgslpc_driver);
- if (error) {
- put_tty_driver(serial_driver);
- return error;
+ serial_driver = alloc_tty_driver(MAX_DEVICE_COUNT);
+ if (!serial_driver) {
+ rc = -ENOMEM;
+ goto error;
}

/* Initialize the tty_driver structure */
@@ -3166,39 +3191,28 @@
serial_driver->flags = TTY_DRIVER_REAL_RAW;
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",
__FILE__,__LINE__);
+ put_tty_driver(serial_driver);
+ serial_driver = NULL;
+ goto error;
+ }

printk("%s %s, tty major#%d\n",
driver_name, driver_version,
serial_driver->major);

return 0;
+
+error:
+ synclink_cs_cleanup();
+ return rc;
}

static void __exit synclink_cs_exit(void)
{
- int rc;
-
- 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);
- }
+ synclink_cs_cleanup();
}

module_init(synclink_cs_init);