Patch to drivers/char/pcmcia/synclink_cs.c against 2.6.6
to cleanup properly on errors during
driver initialization.
Please apply.
--
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);
On Tue, Jun 01, 2004 at 03:53:02PM -0500, Paul Fulghum wrote:
> Patch to drivers/char/pcmcia/synclink_cs.c against 2.6.6
> to cleanup properly on errors during
> driver initialization.
To put my PCMCIA hat on, are you sure you should be registering with
a subsystem which can cause you to create tty devices before you've
registered with the tty subsystem?
Eg, what could happen if you register with PCMCIA, PCMCIA hands you
a card to drive and register a tty for, and you do all of that
_before_ you've registered with the tty subsystem?
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial core
Russell King wrote:
>To put my PCMCIA hat on,
>
Is that the one with a propeller and flashing LEDs?
I'm jealous.
> are you sure you should be registering with
>a subsystem which can cause you to create tty devices before you've
>registered with the tty subsystem?
>
>Eg, what could happen if you register with PCMCIA, PCMCIA hands you
>a card to drive and register a tty for, and you do all of that
>_before_ you've registered with the tty subsystem?
>
>
Nothing.
Devices can come and go. Until the driver
registers with the tty subsystem they are not
externally accessible. The driver itself does
nothing tty related until it registers with the
tty subsystem and an external entity opens
the device as a tty device.
I believe what you describe happens with the 1st card insertion:
1. cardmgr loads the driver
2. driver registers with pcmcia
3. pcmcia creates device
4. driver registers with tty
Registering with pcmcia first makes cleanup a little easier
if it fails for some reason. This scheme has worked so far.
--
Paul Fulghum
[email protected]