[PATCH] move cleanup call to ->detach to generic code, kill use_count

Dominik Brodowski linux at brodo.de
Tue Sep 30 11:18:43 BST 2003


[depends on the three patches sent earlier today]

By moving the call to pcmcia_driver->detach to a device_model->remove call,
it is assured that it is called whenever
	a) the device is unregistered.
	b) the driver registered with this device is removed

Because of b), most of the dev_list walking in the module_exit() code 
of the PCMCIA drivers can be removed. Only if drivers fail to properly
clean up on calls to ->detach(), the walking has to be continued. A
warning is printed out for these drivers.


Additionally, the internal driver use_count is removed in ds.c, as the 
reference counting is done in the module core anyways, and that reference
core is available for cardmgr's usage by a call to module_refcount.


 drivers/bluetooth/bluecard_cs.c    |    4 ---
 drivers/bluetooth/btuart_cs.c      |    4 ---
 drivers/bluetooth/dtl1_cs.c        |    4 ---
 drivers/char/pcmcia/synclink_cs.c  |    7 ++++-
 drivers/ide/legacy/ide-cs.c        |    2 -
 drivers/isdn/hardware/avm/avm_cs.c |    7 -----
 drivers/isdn/hisax/avma1_cs.c      |    7 ++++-
 drivers/isdn/hisax/elsa_cs.c       |    4 ---
 drivers/isdn/hisax/sedlbauer_cs.c  |    1 
 drivers/mtd/maps/pcmciamtd.c       |    2 -
 drivers/net/pcmcia/3c574_cs.c      |    2 -
 drivers/net/pcmcia/3c589_cs.c      |    2 -
 drivers/net/pcmcia/axnet_cs.c      |    2 -
 drivers/net/pcmcia/com20020_cs.c   |    2 -
 drivers/net/pcmcia/fmvj18x_cs.c    |    2 -
 drivers/net/pcmcia/ibmtr_cs.c      |    2 -
 drivers/net/pcmcia/nmclan_cs.c     |    2 -
 drivers/net/pcmcia/pcnet_cs.c      |    3 --
 drivers/net/pcmcia/smc91c92_cs.c   |    2 -
 drivers/net/pcmcia/xirc2ps_cs.c    |    3 --
 drivers/net/wireless/airo_cs.c     |    7 -----
 drivers/net/wireless/atmel_cs.c    |    7 -----
 drivers/net/wireless/netwave_cs.c  |    3 --
 drivers/net/wireless/orinoco_cs.c  |    8 ------
 drivers/net/wireless/ray_cs.c      |    2 -
 drivers/net/wireless/wl3501_cs.c   |    1 
 drivers/parport/parport_cs.c       |    4 ---
 drivers/pcmcia/ds.c                |   45 ++++++++++++++++++++++++-------------
 drivers/scsi/pcmcia/aha152x_stub.c |    4 ---
 drivers/scsi/pcmcia/fdomain_stub.c |    4 ---
 drivers/scsi/pcmcia/nsp_cs.c       |    8 ++++--
 drivers/scsi/pcmcia/qlogic_stub.c  |    4 ---
 drivers/serial/serial_cs.c         |    4 ---
 drivers/telephony/ixj_pcmcia.c     |    4 ---
 include/pcmcia/ds.h                |    1 
 sound/pcmcia/vx/vx_entry.c         |   10 --------
 sound/pcmcia/vx/vxpocket.c         |    1 
 37 files changed, 51 insertions(+), 130 deletions(-)


diff -ruN linux-original/drivers/bluetooth/bluecard_cs.c linux/drivers/bluetooth/bluecard_cs.c
--- linux-original/drivers/bluetooth/bluecard_cs.c	2003-09-29 22:42:34.000000000 +0200
+++ linux/drivers/bluetooth/bluecard_cs.c	2003-09-30 09:21:20.792235272 +0200
@@ -1075,10 +1075,6 @@
 static void __exit exit_bluecard_cs(void)
 {
 	pcmcia_unregister_driver(&bluecard_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		bluecard_detach(dev_list);
 }
 
 module_init(init_bluecard_cs);
diff -ruN linux-original/drivers/bluetooth/btuart_cs.c linux/drivers/bluetooth/btuart_cs.c
--- linux-original/drivers/bluetooth/btuart_cs.c	2003-09-29 22:42:34.000000000 +0200
+++ linux/drivers/bluetooth/btuart_cs.c	2003-09-30 09:21:52.227456392 +0200
@@ -867,10 +867,6 @@
 static void __exit exit_btuart_cs(void)
 {
 	pcmcia_unregister_driver(&btuart_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		btuart_detach(dev_list);
 }
 
 module_init(init_btuart_cs);
diff -ruN linux-original/drivers/bluetooth/dtl1_cs.c linux/drivers/bluetooth/dtl1_cs.c
--- linux-original/drivers/bluetooth/dtl1_cs.c	2003-09-29 22:42:34.000000000 +0200
+++ linux/drivers/bluetooth/dtl1_cs.c	2003-09-30 09:21:46.848274152 +0200
@@ -819,10 +819,6 @@
 static void __exit exit_dtl1_cs(void)
 {
 	pcmcia_unregister_driver(&dtl1_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		dtl1_detach(dev_list);
 }
 
 module_init(init_dtl1_cs);
diff -ruN linux-original/drivers/char/pcmcia/synclink_cs.c linux/drivers/char/pcmcia/synclink_cs.c
--- linux-original/drivers/char/pcmcia/synclink_cs.c	2003-09-30 09:36:53.876384920 +0200
+++ linux/drivers/char/pcmcia/synclink_cs.c	2003-09-30 09:57:57.010359368 +0200
@@ -3195,7 +3195,12 @@
 
 	pcmcia_unregister_driver(&mgslpc_driver);
 
-	/* XXX: this really needs to move into generic code.. */
+	/* XXX: this really needs to move into generic code.. 
+	 * db: It's already there. But as this driver uses
+	 * STALE_LINK and other cruft, it can't be removed here (yet).
+	 */
+#warning BAD: This driver does not properly clean up on a call to ->detach.
+
 	while (dev_list != NULL) {
 		if (dev_list->state & DEV_CONFIG)
 			mgslpc_release((u_long)dev_list);
diff -ruN linux-original/drivers/ide/legacy/ide-cs.c linux/drivers/ide/legacy/ide-cs.c
--- linux-original/drivers/ide/legacy/ide-cs.c	2003-09-29 22:42:33.000000000 +0200
+++ linux/drivers/ide/legacy/ide-cs.c	2003-09-30 09:15:43.885452888 +0200
@@ -482,8 +482,6 @@
 static void __exit exit_ide_cs(void)
 {
 	pcmcia_unregister_driver(&ide_cs_driver);
-	while (dev_list != NULL)
-		ide_detach(dev_list);
 }
 
 module_init(init_ide_cs);
diff -ruN linux-original/drivers/isdn/hardware/avm/avm_cs.c linux/drivers/isdn/hardware/avm/avm_cs.c
--- linux-original/drivers/isdn/hardware/avm/avm_cs.c	2003-09-29 22:42:33.000000000 +0200
+++ linux/drivers/isdn/hardware/avm/avm_cs.c	2003-09-30 09:15:15.181816504 +0200
@@ -511,13 +511,6 @@
 static void __exit avmcs_exit(void)
 {
 	pcmcia_unregister_driver(&avmcs_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL) {
-		if (dev_list->state & DEV_CONFIG)
-			avmcs_release(dev_list);
-		avmcs_detach(dev_list);
-	}
 }
 
 module_init(avmcs_init);
diff -ruN linux-original/drivers/isdn/hisax/avma1_cs.c linux/drivers/isdn/hisax/avma1_cs.c
--- linux-original/drivers/isdn/hisax/avma1_cs.c	2003-09-30 09:38:03.550792800 +0200
+++ linux/drivers/isdn/hisax/avma1_cs.c	2003-09-30 09:39:25.409348408 +0200
@@ -521,7 +521,12 @@
 {
 	pcmcia_unregister_driver(&avma1cs_driver);
 
-	/* XXX: this really needs to move into generic code.. */
+#warning BAD: This driver doesn't properly clean up on a call to ->detach.
+	/* XXX: this really needs to move into generic code.. 
+	 * db: It's already there. But as this driver uses
+	 * STALE_LINK and other cruft, it can't be removed here (yet).
+	 */
+
 	while (dev_list != NULL) {
 		if (dev_list->state & DEV_CONFIG)
 			avma1cs_release(dev_list);
diff -ruN linux-original/drivers/isdn/hisax/elsa_cs.c linux/drivers/isdn/hisax/elsa_cs.c
--- linux-original/drivers/isdn/hisax/elsa_cs.c	2003-09-29 22:42:33.000000000 +0200
+++ linux/drivers/isdn/hisax/elsa_cs.c	2003-09-30 09:15:31.287368088 +0200
@@ -530,10 +530,6 @@
 static void __exit exit_elsa_cs(void)
 {
 	pcmcia_unregister_driver(&elsa_cs_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		elsa_cs_detach(dev_list);
 }
 
 module_init(init_elsa_cs);
diff -ruN linux-original/drivers/isdn/hisax/sedlbauer_cs.c linux/drivers/isdn/hisax/sedlbauer_cs.c
--- linux-original/drivers/isdn/hisax/sedlbauer_cs.c	2003-09-30 09:37:17.881735552 +0200
+++ linux/drivers/isdn/hisax/sedlbauer_cs.c	2003-09-30 09:37:13.529397208 +0200
@@ -633,6 +633,7 @@
 {
 	pcmcia_unregister_driver(&sedlbauer_driver);
 
+#warning BAD: This driver doesn't properly clean up on a call to ->detach.
 	/* XXX: this really needs to move into generic code.. */
 	while (dev_list != NULL) {
 		if (dev_list->state & DEV_CONFIG)
diff -ruN linux-original/drivers/mtd/maps/pcmciamtd.c linux/drivers/mtd/maps/pcmciamtd.c
--- linux-original/drivers/mtd/maps/pcmciamtd.c	2003-09-30 09:38:31.001619640 +0200
+++ linux/drivers/mtd/maps/pcmciamtd.c	2003-09-30 09:58:34.042729592 +0200
@@ -847,8 +847,8 @@
 
 static void __exit exit_pcmciamtd(void)
 {
-	DEBUG(1, DRIVER_DESC " unloading");
 	pcmcia_unregister_driver(&pcmciamtd_driver);
+#warning BAD: This driver does not properly clean up on a call to ->detach.
 
 	while(dev_list) {
 		dev_link_t *link = dev_list;
diff -ruN linux-original/drivers/net/pcmcia/3c574_cs.c linux/drivers/net/pcmcia/3c574_cs.c
--- linux-original/drivers/net/pcmcia/3c574_cs.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/net/pcmcia/3c574_cs.c	2003-09-30 09:09:59.003882856 +0200
@@ -1319,8 +1319,6 @@
 static void __exit exit_tc574(void)
 {
 	pcmcia_unregister_driver(&tc574_driver);
-	while (dev_list != NULL)
-		tc574_detach(dev_list);
 }
 
 module_init(init_tc574);
diff -ruN linux-original/drivers/net/pcmcia/3c589_cs.c linux/drivers/net/pcmcia/3c589_cs.c
--- linux-original/drivers/net/pcmcia/3c589_cs.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/net/pcmcia/3c589_cs.c	2003-09-30 09:09:44.846035176 +0200
@@ -1099,8 +1099,6 @@
 static void __exit exit_tc589(void)
 {
 	pcmcia_unregister_driver(&tc589_driver);
-	while (dev_list != NULL)
-		tc589_detach(dev_list);
 }
 
 module_init(init_tc589);
diff -ruN linux-original/drivers/net/pcmcia/axnet_cs.c linux/drivers/net/pcmcia/axnet_cs.c
--- linux-original/drivers/net/pcmcia/axnet_cs.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/net/pcmcia/axnet_cs.c	2003-09-30 09:11:12.666684408 +0200
@@ -905,8 +905,6 @@
 static void __exit exit_axnet_cs(void)
 {
 	pcmcia_unregister_driver(&axnet_cs_driver);
-	while (dev_list != NULL)
-		axnet_detach(dev_list);
 }
 
 module_init(init_axnet_cs);
diff -ruN linux-original/drivers/net/pcmcia/com20020_cs.c linux/drivers/net/pcmcia/com20020_cs.c
--- linux-original/drivers/net/pcmcia/com20020_cs.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/net/pcmcia/com20020_cs.c	2003-09-30 09:11:49.499085032 +0200
@@ -541,8 +541,6 @@
 static void __exit exit_com20020_cs(void)
 {
 	pcmcia_unregister_driver(&com20020_cs_driver);
-	while (dev_list != NULL)
-		com20020_detach(dev_list);
 }
 
 module_init(init_com20020_cs);
diff -ruN linux-original/drivers/net/pcmcia/fmvj18x_cs.c linux/drivers/net/pcmcia/fmvj18x_cs.c
--- linux-original/drivers/net/pcmcia/fmvj18x_cs.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/net/pcmcia/fmvj18x_cs.c	2003-09-30 09:10:18.137974032 +0200
@@ -811,8 +811,6 @@
 static void __exit exit_fmvj18x_cs(void)
 {
 	pcmcia_unregister_driver(&fmvj18x_cs_driver);
-	while (dev_list != NULL)
-		fmvj18x_detach(dev_list);
 }
 
 module_init(init_fmvj18x_cs);
diff -ruN linux-original/drivers/net/pcmcia/ibmtr_cs.c linux/drivers/net/pcmcia/ibmtr_cs.c
--- linux-original/drivers/net/pcmcia/ibmtr_cs.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/net/pcmcia/ibmtr_cs.c	2003-09-30 09:11:55.466177896 +0200
@@ -547,8 +547,6 @@
 static void __exit exit_ibmtr_cs(void)
 {
 	pcmcia_unregister_driver(&ibmtr_cs_driver);
-	while (dev_list != NULL)
-		ibmtr_detach(dev_list);
 }
 
 module_init(init_ibmtr_cs);
diff -ruN linux-original/drivers/net/pcmcia/nmclan_cs.c linux/drivers/net/pcmcia/nmclan_cs.c
--- linux-original/drivers/net/pcmcia/nmclan_cs.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/net/pcmcia/nmclan_cs.c	2003-09-30 09:11:25.562723912 +0200
@@ -1718,8 +1718,6 @@
 static void __exit exit_nmclan_cs(void)
 {
 	pcmcia_unregister_driver(&nmclan_cs_driver);
-	while (dev_list != NULL)
-		nmclan_detach(dev_list);
 }
 
 module_init(init_nmclan_cs);
diff -ruN linux-original/drivers/net/pcmcia/pcnet_cs.c linux/drivers/net/pcmcia/pcnet_cs.c
--- linux-original/drivers/net/pcmcia/pcnet_cs.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/net/pcmcia/pcnet_cs.c	2003-09-30 09:09:53.434729496 +0200
@@ -1580,10 +1580,7 @@
 
 static void __exit exit_pcnet_cs(void)
 {
-    DEBUG(0, "pcnet_cs: unloading\n");
     pcmcia_unregister_driver(&pcnet_driver);
-    while (dev_list != NULL)
-	pcnet_detach(dev_list);
 }
 
 module_init(init_pcnet_cs);
diff -ruN linux-original/drivers/net/pcmcia/smc91c92_cs.c linux/drivers/net/pcmcia/smc91c92_cs.c
--- linux-original/drivers/net/pcmcia/smc91c92_cs.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/net/pcmcia/smc91c92_cs.c	2003-09-30 09:11:35.339237656 +0200
@@ -2261,8 +2261,6 @@
 static void __exit exit_smc91c92_cs(void)
 {
 	pcmcia_unregister_driver(&smc91c92_cs_driver);
-	while (dev_list != NULL)
-		smc91c92_detach(dev_list);
 }
 
 module_init(init_smc91c92_cs);
diff -ruN linux-original/drivers/net/pcmcia/xirc2ps_cs.c linux/drivers/net/pcmcia/xirc2ps_cs.c
--- linux-original/drivers/net/pcmcia/xirc2ps_cs.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/net/pcmcia/xirc2ps_cs.c	2003-09-30 09:11:42.786105560 +0200
@@ -2022,9 +2022,6 @@
 exit_xirc2ps_cs(void)
 {
 	pcmcia_unregister_driver(&xirc2ps_cs_driver);
-
-	while (dev_list)
-		xirc2ps_detach(dev_list);
 }
 
 module_init(init_xirc2ps_cs);
diff -ruN linux-original/drivers/net/wireless/airo_cs.c linux/drivers/net/wireless/airo_cs.c
--- linux-original/drivers/net/wireless/airo_cs.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/net/wireless/airo_cs.c	2003-09-30 09:12:11.986666400 +0200
@@ -610,13 +610,6 @@
 static void airo_cs_cleanup(void)
 {
 	pcmcia_unregister_driver(&airo_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL) {
-		if (dev_list->state & DEV_CONFIG)
-			airo_release(dev_list);
-		airo_detach(dev_list);
-	}
 }
 
 /*
diff -ruN linux-original/drivers/net/wireless/atmel_cs.c linux/drivers/net/wireless/atmel_cs.c
--- linux-original/drivers/net/wireless/atmel_cs.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/net/wireless/atmel_cs.c	2003-09-30 09:12:46.281452800 +0200
@@ -680,13 +680,6 @@
 static void atmel_cs_cleanup(void)
 {
         pcmcia_unregister_driver(&atmel_driver);
-
-        /* XXX: this really needs to move into generic code.. */
-        while (dev_list != NULL) {
-                if (dev_list->state & DEV_CONFIG)
-                        atmel_release(dev_list);
-                atmel_detach(dev_list);
-        }
 }
 
 /*
diff -ruN linux-original/drivers/net/wireless/netwave_cs.c linux/drivers/net/wireless/netwave_cs.c
--- linux-original/drivers/net/wireless/netwave_cs.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/net/wireless/netwave_cs.c	2003-09-30 09:12:21.757181056 +0200
@@ -1726,9 +1726,6 @@
 static void __exit exit_netwave_cs(void)
 {
 	pcmcia_unregister_driver(&netwave_driver);
-
-	if (dev_list != NULL)	/* Critical situation */
-		printk("netwave_cs: devices remaining when removing module\n");
 }
 
 module_init(init_netwave_cs);
diff -ruN linux-original/drivers/net/wireless/orinoco_cs.c linux/drivers/net/wireless/orinoco_cs.c
--- linux-original/drivers/net/wireless/orinoco_cs.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/net/wireless/orinoco_cs.c	2003-09-30 09:24:54.495747400 +0200
@@ -660,14 +660,6 @@
 exit_orinoco_cs(void)
 {
 	pcmcia_unregister_driver(&orinoco_driver);
-
-	if (dev_list)
-		DEBUG(0, "orinoco_cs: Removing leftover devices.\n");
-	while (dev_list != NULL) {
-		if (dev_list->state & DEV_CONFIG)
-			orinoco_cs_release(dev_list);
-		orinoco_cs_detach(dev_list);
-	}
 }
 
 module_init(init_orinoco_cs);
diff -ruN linux-original/drivers/net/wireless/ray_cs.c linux/drivers/net/wireless/ray_cs.c
--- linux-original/drivers/net/wireless/ray_cs.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/net/wireless/ray_cs.c	2003-09-30 09:12:34.103304160 +0200
@@ -2964,8 +2964,6 @@
 #endif
 
     pcmcia_unregister_driver(&ray_driver);
-    while (dev_list != NULL)
-        ray_detach(dev_list);
 
 #ifdef CONFIG_PROC_FS
     remove_proc_entry("driver/ray_cs/ray_cs", NULL);
diff -ruN linux-original/drivers/net/wireless/wl3501_cs.c linux/drivers/net/wireless/wl3501_cs.c
--- linux-original/drivers/net/wireless/wl3501_cs.c	2003-09-30 09:29:06.891377432 +0200
+++ linux/drivers/net/wireless/wl3501_cs.c	2003-09-30 09:59:23.448218816 +0200
@@ -2341,6 +2341,7 @@
 	dprintk(0, ": unloading");
 	pcmcia_unregister_driver(&wl3501_driver);
 	while (wl3501_dev_list) {
+#warning BAD: This driver does not properly clean up on a call to ->detach.
 		/* Mark the device as non-existing to minimize calls to card */
 		wl3501_dev_list->state &= ~DEV_PRESENT;
 		if (wl3501_dev_list->state & DEV_CONFIG)
diff -ruN linux-original/drivers/parport/parport_cs.c linux/drivers/parport/parport_cs.c
--- linux-original/drivers/parport/parport_cs.c	2003-09-29 22:42:34.000000000 +0200
+++ linux/drivers/parport/parport_cs.c	2003-09-30 09:15:48.444759768 +0200
@@ -402,10 +402,6 @@
 static void __exit exit_parport_cs(void)
 {
 	pcmcia_unregister_driver(&parport_cs_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		parport_detach(dev_list);
 }
 
 module_init(init_parport_cs);
diff -ruN linux-original/drivers/pcmcia/ds.c linux/drivers/pcmcia/ds.c
--- linux-original/drivers/pcmcia/ds.c	2003-09-30 00:42:20.000000000 +0200
+++ linux/drivers/pcmcia/ds.c	2003-09-30 10:06:28.580588872 +0200
@@ -113,6 +113,8 @@
 static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info);
 static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr);
 
+static int pcmcia_remove_dev (struct device *dev);
+
 /**
  * pcmcia_register_driver - register a PCMCIA driver with the bus core
  *
@@ -123,8 +125,8 @@
 	if (!driver)
 		return -EINVAL;
 
- 	driver->use_count = 0;
 	driver->drv.bus = &pcmcia_bus_type;
+	driver->drv.remove = &pcmcia_remove_dev;
 
 	return driver_register(&driver->drv);
 }
@@ -145,10 +147,16 @@
 static int proc_read_drivers_callback(struct device_driver *driver, void *d)
 {
 	char **p = d;
-	struct pcmcia_driver *p_dev = container_of(driver, 
+	struct pcmcia_driver *p_drv = container_of(driver, 
 						   struct pcmcia_driver, drv);
 
-	*p += sprintf(*p, "%-24.24s 1 %d\n", driver->name, p_dev->use_count);
+	*p += sprintf(*p, "%-24.24s 1 %d\n", p_drv->drv.name, 
+#ifdef CONFIG_MODULE_UNLOAD
+		      module_refcount(p_drv->owner)
+#else
+		      1
+#endif
+		);
 	d = (void *) p;
 
 	return 0;
@@ -168,6 +176,25 @@
 
 /* pcmcia_device handling */
 
+static int pcmcia_remove_dev(struct device *dev)
+{
+	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+	struct pcmcia_driver *p_drv = to_pcmcia_drv(dev->driver);
+
+	if (!p_drv)
+		return 0;
+
+	/* detach the "instance" */
+	p_drv = to_pcmcia_drv(p_dev->dev.driver);
+	if (p_drv) {
+		if ((p_drv->detach) && (p_dev->instance))
+			p_drv->detach(p_dev->instance);
+		module_put(p_drv->owner);
+	}
+
+	return 0;
+}
+
 static void pcmcia_release_dev(struct device *dev)
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
@@ -385,9 +412,7 @@
 	list_add_tail(&p_dev->socket_device_list, &s->devices_list);
 	spin_unlock_irqrestore(pcmcia_dev_list_lock, flags);
 
-
 	/* try to create an "instance"... */
-	p_drv->use_count++;
 	if (p_drv->attach) {
 		p_dev->instance = p_drv->attach();
 		if (!p_dev->instance) {
@@ -490,7 +515,6 @@
 static int unbind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info)
 {
 	struct pcmcia_device	*p_dev;
-	struct pcmcia_driver	*p_drv;
 	unsigned long		flags;
 
 	DEBUG(2, "unbind_request(%d, '%s')\n", s->parent->sock,
@@ -508,15 +532,6 @@
 	list_del(&p_dev->socket_device_list);
 	spin_unlock_irqrestore(pcmcia_dev_list_lock, flags);
 
-	/* detach the "instance" */
-	p_drv = to_pcmcia_drv(p_dev->dev.driver);
-	if (p_drv) {
-		p_drv->use_count--;
-		if ((p_drv->detach) && (p_dev->instance))
-			p_drv->detach(p_dev->instance);
-	}
-	module_put(p_drv->owner);
-
 	device_unregister(&p_dev->dev);
 
 	return 0;
diff -ruN linux-original/drivers/scsi/pcmcia/aha152x_stub.c linux/drivers/scsi/pcmcia/aha152x_stub.c
--- linux-original/drivers/scsi/pcmcia/aha152x_stub.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/scsi/pcmcia/aha152x_stub.c	2003-09-30 09:14:31.930391720 +0200
@@ -356,10 +356,6 @@
 static void __exit exit_aha152x_cs(void)
 {
 	pcmcia_unregister_driver(&aha152x_cs_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		aha152x_detach(dev_list);
 }
 
 module_init(init_aha152x_cs);
diff -ruN linux-original/drivers/scsi/pcmcia/fdomain_stub.c linux/drivers/scsi/pcmcia/fdomain_stub.c
--- linux-original/drivers/scsi/pcmcia/fdomain_stub.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/scsi/pcmcia/fdomain_stub.c	2003-09-30 09:14:38.924328480 +0200
@@ -336,10 +336,6 @@
 static void __exit exit_fdomain_cs(void)
 {
 	pcmcia_unregister_driver(&fdomain_cs_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		fdomain_detach(dev_list);
 }
 
 module_init(init_fdomain_cs);
diff -ruN linux-original/drivers/scsi/pcmcia/nsp_cs.c linux/drivers/scsi/pcmcia/nsp_cs.c
--- linux-original/drivers/scsi/pcmcia/nsp_cs.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/scsi/pcmcia/nsp_cs.c	2003-09-30 09:39:13.162210256 +0200
@@ -2197,15 +2197,19 @@
 	pcmcia_unregister_driver(&nsp_driver);
 #else
 	unregister_pcmcia_driver(&dev_info);
-#endif
 
-	/* XXX: this really needs to move into generic code.. */
+
+	/* XXX: this really needs to move into generic code.. 
+	 * db: It's already there. But as this driver uses
+	 * STALE_LINK and other cruft, it can't be removed here (yet).
+	 */
 	while (dev_list != NULL) {
 		if (dev_list->state & DEV_CONFIG) {
 			nsp_cs_release(dev_list);
 		}
 		nsp_cs_detach(dev_list);
 	}
+#endif
 }
 
 
diff -ruN linux-original/drivers/scsi/pcmcia/qlogic_stub.c linux/drivers/scsi/pcmcia/qlogic_stub.c
--- linux-original/drivers/scsi/pcmcia/qlogic_stub.c	2003-09-29 22:42:32.000000000 +0200
+++ linux/drivers/scsi/pcmcia/qlogic_stub.c	2003-09-30 09:14:45.686300504 +0200
@@ -356,10 +356,6 @@
 static void __exit exit_qlogic_cs(void)
 {
 	pcmcia_unregister_driver(&qlogic_cs_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		qlogic_detach(dev_list);
 }
 
 module_init(init_qlogic_cs);
diff -ruN linux-original/drivers/serial/serial_cs.c linux/drivers/serial/serial_cs.c
--- linux-original/drivers/serial/serial_cs.c	2003-09-29 22:42:34.000000000 +0200
+++ linux/drivers/serial/serial_cs.c	2003-09-30 09:21:56.660782424 +0200
@@ -700,10 +700,6 @@
 static void __exit exit_serial_cs(void)
 {
 	pcmcia_unregister_driver(&serial_cs_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		serial_detach(dev_list);
 }
 
 module_init(init_serial_cs);
diff -ruN linux-original/drivers/telephony/ixj_pcmcia.c linux/drivers/telephony/ixj_pcmcia.c
--- linux-original/drivers/telephony/ixj_pcmcia.c	2003-09-29 22:42:34.000000000 +0200
+++ linux/drivers/telephony/ixj_pcmcia.c	2003-09-30 09:15:52.743106320 +0200
@@ -314,10 +314,6 @@
 static void ixj_pcmcia_exit(void)
 {
 	pcmcia_unregister_driver(&ixj_driver);
-
-	/* XXX: this really needs to move into generic code.. */
-	while (dev_list != NULL)
-		ixj_detach(dev_list);
 }
 
 module_init(ixj_pcmcia_init);
diff -ruN linux-original/include/pcmcia/ds.h linux/include/pcmcia/ds.h
--- linux-original/include/pcmcia/ds.h	2003-09-30 00:42:20.000000000 +0200
+++ linux/include/pcmcia/ds.h	2003-09-30 10:01:31.267787288 +0200
@@ -123,7 +123,6 @@
 extern struct bus_type pcmcia_bus_type;
 
 struct pcmcia_driver {
-	int			use_count;
 	dev_link_t		*(*attach)(void);
 	void			(*detach)(dev_link_t *);
 	struct module		*owner;
diff -ruN linux-original/sound/pcmcia/vx/vx_entry.c linux/sound/pcmcia/vx/vx_entry.c
--- linux-original/sound/pcmcia/vx/vx_entry.c	2003-09-29 22:42:43.000000000 +0200
+++ linux/sound/pcmcia/vx/vx_entry.c	2003-09-30 09:22:45.551349928 +0200
@@ -241,15 +241,6 @@
 }
 
 /*
- * snd_vxpocket_detach_all - detach all instances linked to the hw
- */
-void snd_vxpocket_detach_all(struct snd_vxp_entry *hw)
-{
-	while (hw->dev_list != NULL)
-		snd_vxpocket_detach(hw, hw->dev_list);
-}
-
-/*
  * configuration callback
  */
 
@@ -369,4 +360,3 @@
 EXPORT_SYMBOL(snd_vxpocket_ops);
 EXPORT_SYMBOL(snd_vxpocket_attach);
 EXPORT_SYMBOL(snd_vxpocket_detach);
-EXPORT_SYMBOL(snd_vxpocket_detach_all);
diff -ruN linux-original/sound/pcmcia/vx/vxpocket.c linux/sound/pcmcia/vx/vxpocket.c
--- linux-original/sound/pcmcia/vx/vxpocket.c	2003-09-29 22:42:43.000000000 +0200
+++ linux/sound/pcmcia/vx/vxpocket.c	2003-09-30 09:22:48.921837536 +0200
@@ -169,7 +169,6 @@
 static void __exit exit_vxpocket(void)
 {
 	pcmcia_unregister_driver(&vxp_cs_driver);
-	snd_vxpocket_detach_all(&hw_entry);
 }
 
 module_init(init_vxpocket);



More information about the linux-pcmcia mailing list