mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] s390 (5/10): dasd driver fixes.
@ 2004-03-16 13:50 Martin Schwidefsky
  0 siblings, 0 replies; 2+ messages in thread
From: Martin Schwidefsky @ 2004-03-16 13:50 UTC (permalink / raw)
  To: akpm, linux-kernel

dasd driver fixes:
 - Remove additional dasd attributes for a ccw-device if the discipline
   (=driver) gets unloaded.
 - Fix race of dasd_generic_offline against dasd_open.
 - Remove irq_exit calls from diag interrupt handler. The irq_enter/
   irq_exit is done in the external interrupt handler.

diffstat:
 drivers/s390/block/Kconfig       |    8 +++---
 drivers/s390/block/dasd.c        |   49 +++++++++++++++++++++++++++++++--------
 drivers/s390/block/dasd_devmap.c |    9 ++++++-
 drivers/s390/block/dasd_diag.c   |    4 ---
 drivers/s390/block/dasd_int.h    |    4 ++-
 5 files changed, 55 insertions(+), 19 deletions(-)

diff -urN linux-2.6/drivers/s390/block/Kconfig linux-2.6-s390/drivers/s390/block/Kconfig
--- linux-2.6/drivers/s390/block/Kconfig	Thu Mar 11 03:55:21 2004
+++ linux-2.6-s390/drivers/s390/block/Kconfig	Tue Mar 16 14:03:09 2004
@@ -48,12 +48,12 @@
 	  say "Y".
 
 config DASD_DIAG
-	tristate "Support for DIAG access to CMS reserved Disks"
+	tristate "Support for DIAG access to Disks"
 	depends on DASD && ARCH_S390X = 'n'
 	help
-	  Select this option if you want to use CMS reserved Disks under VM
-	  with the Diagnose250 command.  If you are not running under VM or
-	  unsure what it is, say "N".
+	  Select this option if you want to use Diagnose250 command to access
+	  Disks under VM.  If you are not running under VM or unsure what it is, 
+	  say "N".
 
 config DASD_CMB
 	tristate "Compatibility interface for DASD channel measurement blocks"
diff -urN linux-2.6/drivers/s390/block/dasd.c linux-2.6-s390/drivers/s390/block/dasd.c
--- linux-2.6/drivers/s390/block/dasd.c	Thu Mar 11 03:55:26 2004
+++ linux-2.6-s390/drivers/s390/block/dasd.c	Tue Mar 16 14:03:09 2004
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.129 $
+ * $Revision: 1.133 $
  */
 
 #include <linux/config.h>
@@ -1655,11 +1655,24 @@
 {
 	struct gendisk *disk = inp->i_bdev->bd_disk;
 	struct dasd_device *device = disk->private_data;
-	int rc;
+	int old_count, rc;
+
+	/*
+	 * We use a negative value in open_count to indicate that  
+	 * the device must not be used. 
+	 */
+	do {
+		old_count = atomic_read(&device->open_count);
+		if (old_count < 0)  
+			return -ENODEV;
+	} while (atomic_compare_and_swap(old_count, old_count + 1,
+					 &device->open_count));
+
+	if (!try_module_get(device->discipline->owner)) {
+		rc = -EINVAL;
+		goto unlock;
+	}
 
-	if (!try_module_get(device->discipline->owner))
-		return -EINVAL;
-	
 	if (dasd_probeonly) {
 		MESSAGE(KERN_INFO,
 			"No access to device %s due to probeonly mode",
@@ -1676,11 +1689,12 @@
 		goto out;
 	}
 
-	atomic_inc(&device->open_count);
 	return 0;
 
 out:
 	module_put(device->discipline->owner);
+unlock:
+	atomic_dec(&device->open_count);
 	return rc;
 }
 
@@ -1741,7 +1755,7 @@
 	ret = dasd_add_sysfs_files(cdev);
 	if (ret) {
 		printk(KERN_WARNING
-		       "dasd_generic_probe: could not add driverfs entries"
+		       "dasd_generic_probe: could not add sysfs entries "
 		       "for %s\n", cdev->dev.bus_id);
 	}
 
@@ -1757,8 +1771,15 @@
 {
 	struct dasd_device *device;
 
+	dasd_remove_sysfs_files(cdev);
 	device = dasd_device_from_cdev(cdev);
 	if (!IS_ERR(device)) {
+		/*
+		 * This device is removed unconditionally. Set open_count
+		 * to -1 to prevent dasd_open from opening it while it is
+		 * no quite down yet.
+		 */
+		atomic_set(&device->open_count,-1);
 		dasd_set_target_state(device, DASD_STATE_NEW);
 		/* dasd_delete_device destroys the device reference. */
 		dasd_delete_device(device);
@@ -1830,15 +1851,23 @@
 	struct dasd_device *device;
 
 	device = dasd_device_from_cdev(cdev);
-	if (atomic_read(&device->open_count) > 0) {
+	/*
+	 * We must make sure that this device is currently not in use 
+	 * (current open_count == 0 ). We set open_count to -1 to indicate 
+	 * that from now on set_offline is in progress and the device must
+	 * not be used otherwise. 
+	 */
+	if (atomic_compare_and_swap(0, -1, &device->open_count)) {
 		printk (KERN_WARNING "Can't offline dasd device with open"
 			" count = %i.\n",
 			atomic_read(&device->open_count));
 		dasd_put_device(device);
 		return -EBUSY;
 	}
-	dasd_put_device(device);
-	dasd_generic_remove (cdev);
+	dasd_set_target_state(device, DASD_STATE_NEW);
+	/* dasd_delete_device destroys the device reference. */
+	dasd_delete_device(device);
+
 	return 0;
 }
 
diff -urN linux-2.6/drivers/s390/block/dasd_devmap.c linux-2.6-s390/drivers/s390/block/dasd_devmap.c
--- linux-2.6/drivers/s390/block/dasd_devmap.c	Thu Mar 11 03:55:27 2004
+++ linux-2.6-s390/drivers/s390/block/dasd_devmap.c	Tue Mar 16 14:03:09 2004
@@ -11,7 +11,7 @@
  * functions may not be called from interrupt context. In particular
  * dasd_get_device is a no-no from interrupt context.
  *
- * $Revision: 1.25 $
+ * $Revision: 1.26 $
  */
 
 #include <linux/config.h>
@@ -681,6 +681,13 @@
 	return sysfs_create_group(&cdev->dev.kobj, &dasd_attr_group);
 }
 
+void
+dasd_remove_sysfs_files(struct ccw_device *cdev)
+{
+	sysfs_remove_group(&cdev->dev.kobj, &dasd_attr_group);
+}
+
+
 int
 dasd_devmap_init(void)
 {
diff -urN linux-2.6/drivers/s390/block/dasd_diag.c linux-2.6-s390/drivers/s390/block/dasd_diag.c
--- linux-2.6/drivers/s390/block/dasd_diag.c	Thu Mar 11 03:55:21 2004
+++ linux-2.6-s390/drivers/s390/block/dasd_diag.c	Tue Mar 16 14:03:09 2004
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.33 $
+ * $Revision: 1.34 $
  */
 
 #include <linux/config.h>
@@ -173,7 +173,6 @@
 
 	if (!ip) {		/* no intparm: unsolicited interrupt */
 		MESSAGE(KERN_DEBUG, "%s", "caught unsolicited interrupt");
-		irq_exit();
 		return;
 	}
 	cqr = (struct dasd_ccw_req *)(addr_t) ip;
@@ -183,7 +182,6 @@
 			    " magic number of dasd_ccw_req 0x%08X doesn't"
 			    " match discipline 0x%08X",
 			    cqr->magic, *(int *) (&device->discipline->name));
-		irq_exit();
 		return;
 	}
 
diff -urN linux-2.6/drivers/s390/block/dasd_int.h linux-2.6-s390/drivers/s390/block/dasd_int.h
--- linux-2.6/drivers/s390/block/dasd_int.h	Thu Mar 11 03:55:36 2004
+++ linux-2.6-s390/drivers/s390/block/dasd_int.h	Tue Mar 16 14:03:09 2004
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.54 $
+ * $Revision: 1.55 $
  */
 
 #ifndef DASD_INT_H
@@ -485,6 +485,8 @@
 void dasd_delete_device(struct dasd_device *);
 
 int dasd_add_sysfs_files(struct ccw_device *);
+void dasd_remove_sysfs_files(struct ccw_device *);
+
 struct dasd_device *dasd_device_from_cdev(struct ccw_device *);
 struct dasd_device *dasd_device_from_devindex(int);
 

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH] s390 (5/10): dasd driver fixes.
@ 2004-03-12 19:37 Martin Schwidefsky
  0 siblings, 0 replies; 2+ messages in thread
From: Martin Schwidefsky @ 2004-03-12 19:37 UTC (permalink / raw)
  To: akpm, linux-kernel

dasd driver fixes:
 - Remove additional dasd attributes for a ccw-device if the discipline
   (=driver) gets unloaded.
 - Fix race of dasd_generic_offline against dasd_open.
 - Remove irq_exit calls from diag interrupt handler. The irq_enter/
   irq_exit is done in the external interrupt handler.

diffstat:
 drivers/s390/block/Kconfig       |    8 +++---
 drivers/s390/block/dasd.c        |   49 +++++++++++++++++++++++++++++++--------
 drivers/s390/block/dasd_devmap.c |    9 ++++++-
 drivers/s390/block/dasd_diag.c   |    4 ---
 drivers/s390/block/dasd_int.h    |    4 ++-
 5 files changed, 55 insertions(+), 19 deletions(-)

diff -urN linux-2.6/drivers/s390/block/Kconfig linux-2.6-s390/drivers/s390/block/Kconfig
--- linux-2.6/drivers/s390/block/Kconfig	Thu Mar 11 03:55:21 2004
+++ linux-2.6-s390/drivers/s390/block/Kconfig	Fri Mar 12 20:03:33 2004
@@ -48,12 +48,12 @@
 	  say "Y".
 
 config DASD_DIAG
-	tristate "Support for DIAG access to CMS reserved Disks"
+	tristate "Support for DIAG access to Disks"
 	depends on DASD && ARCH_S390X = 'n'
 	help
-	  Select this option if you want to use CMS reserved Disks under VM
-	  with the Diagnose250 command.  If you are not running under VM or
-	  unsure what it is, say "N".
+	  Select this option if you want to use Diagnose250 command to access
+	  Disks under VM.  If you are not running under VM or unsure what it is, 
+	  say "N".
 
 config DASD_CMB
 	tristate "Compatibility interface for DASD channel measurement blocks"
diff -urN linux-2.6/drivers/s390/block/dasd.c linux-2.6-s390/drivers/s390/block/dasd.c
--- linux-2.6/drivers/s390/block/dasd.c	Thu Mar 11 03:55:26 2004
+++ linux-2.6-s390/drivers/s390/block/dasd.c	Fri Mar 12 20:03:33 2004
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.129 $
+ * $Revision: 1.133 $
  */
 
 #include <linux/config.h>
@@ -1655,11 +1655,24 @@
 {
 	struct gendisk *disk = inp->i_bdev->bd_disk;
 	struct dasd_device *device = disk->private_data;
-	int rc;
+	int old_count, rc;
+
+	/*
+	 * We use a negative value in open_count to indicate that  
+	 * the device must not be used. 
+	 */
+	do {
+		old_count = atomic_read(&device->open_count);
+		if (old_count < 0)  
+			return -ENODEV;
+	} while (atomic_compare_and_swap(old_count, old_count + 1,
+					 &device->open_count));
+
+	if (!try_module_get(device->discipline->owner)) {
+		rc = -EINVAL;
+		goto unlock;
+	}
 
-	if (!try_module_get(device->discipline->owner))
-		return -EINVAL;
-	
 	if (dasd_probeonly) {
 		MESSAGE(KERN_INFO,
 			"No access to device %s due to probeonly mode",
@@ -1676,11 +1689,12 @@
 		goto out;
 	}
 
-	atomic_inc(&device->open_count);
 	return 0;
 
 out:
 	module_put(device->discipline->owner);
+unlock:
+	atomic_dec(&device->open_count);
 	return rc;
 }
 
@@ -1741,7 +1755,7 @@
 	ret = dasd_add_sysfs_files(cdev);
 	if (ret) {
 		printk(KERN_WARNING
-		       "dasd_generic_probe: could not add driverfs entries"
+		       "dasd_generic_probe: could not add sysfs entries "
 		       "for %s\n", cdev->dev.bus_id);
 	}
 
@@ -1757,8 +1771,15 @@
 {
 	struct dasd_device *device;
 
+	dasd_remove_sysfs_files(cdev);
 	device = dasd_device_from_cdev(cdev);
 	if (!IS_ERR(device)) {
+		/*
+		 * This device is removed unconditionally. Set open_count
+		 * to -1 to prevent dasd_open from opening it while it is
+		 * no quite down yet.
+		 */
+		atomic_set(&device->open_count,-1);
 		dasd_set_target_state(device, DASD_STATE_NEW);
 		/* dasd_delete_device destroys the device reference. */
 		dasd_delete_device(device);
@@ -1830,15 +1851,23 @@
 	struct dasd_device *device;
 
 	device = dasd_device_from_cdev(cdev);
-	if (atomic_read(&device->open_count) > 0) {
+	/*
+	 * We must make sure that this device is currently not in use 
+	 * (current open_count == 0 ). We set open_count to -1 to indicate 
+	 * that from now on set_offline is in progress and the device must
+	 * not be used otherwise. 
+	 */
+	if (atomic_compare_and_swap(0, -1, &device->open_count)) {
 		printk (KERN_WARNING "Can't offline dasd device with open"
 			" count = %i.\n",
 			atomic_read(&device->open_count));
 		dasd_put_device(device);
 		return -EBUSY;
 	}
-	dasd_put_device(device);
-	dasd_generic_remove (cdev);
+	dasd_set_target_state(device, DASD_STATE_NEW);
+	/* dasd_delete_device destroys the device reference. */
+	dasd_delete_device(device);
+
 	return 0;
 }
 
diff -urN linux-2.6/drivers/s390/block/dasd_devmap.c linux-2.6-s390/drivers/s390/block/dasd_devmap.c
--- linux-2.6/drivers/s390/block/dasd_devmap.c	Thu Mar 11 03:55:27 2004
+++ linux-2.6-s390/drivers/s390/block/dasd_devmap.c	Fri Mar 12 20:03:33 2004
@@ -11,7 +11,7 @@
  * functions may not be called from interrupt context. In particular
  * dasd_get_device is a no-no from interrupt context.
  *
- * $Revision: 1.25 $
+ * $Revision: 1.26 $
  */
 
 #include <linux/config.h>
@@ -681,6 +681,13 @@
 	return sysfs_create_group(&cdev->dev.kobj, &dasd_attr_group);
 }
 
+void
+dasd_remove_sysfs_files(struct ccw_device *cdev)
+{
+	sysfs_remove_group(&cdev->dev.kobj, &dasd_attr_group);
+}
+
+
 int
 dasd_devmap_init(void)
 {
diff -urN linux-2.6/drivers/s390/block/dasd_diag.c linux-2.6-s390/drivers/s390/block/dasd_diag.c
--- linux-2.6/drivers/s390/block/dasd_diag.c	Thu Mar 11 03:55:21 2004
+++ linux-2.6-s390/drivers/s390/block/dasd_diag.c	Fri Mar 12 20:03:33 2004
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.33 $
+ * $Revision: 1.34 $
  */
 
 #include <linux/config.h>
@@ -173,7 +173,6 @@
 
 	if (!ip) {		/* no intparm: unsolicited interrupt */
 		MESSAGE(KERN_DEBUG, "%s", "caught unsolicited interrupt");
-		irq_exit();
 		return;
 	}
 	cqr = (struct dasd_ccw_req *)(addr_t) ip;
@@ -183,7 +182,6 @@
 			    " magic number of dasd_ccw_req 0x%08X doesn't"
 			    " match discipline 0x%08X",
 			    cqr->magic, *(int *) (&device->discipline->name));
-		irq_exit();
 		return;
 	}
 
diff -urN linux-2.6/drivers/s390/block/dasd_int.h linux-2.6-s390/drivers/s390/block/dasd_int.h
--- linux-2.6/drivers/s390/block/dasd_int.h	Thu Mar 11 03:55:36 2004
+++ linux-2.6-s390/drivers/s390/block/dasd_int.h	Fri Mar 12 20:03:33 2004
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.54 $
+ * $Revision: 1.55 $
  */
 
 #ifndef DASD_INT_H
@@ -485,6 +485,8 @@
 void dasd_delete_device(struct dasd_device *);
 
 int dasd_add_sysfs_files(struct ccw_device *);
+void dasd_remove_sysfs_files(struct ccw_device *);
+
 struct dasd_device *dasd_device_from_cdev(struct ccw_device *);
 struct dasd_device *dasd_device_from_devindex(int);
 

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-03-16 13:58 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-16 13:50 [PATCH] s390 (5/10): dasd driver fixes Martin Schwidefsky
  -- strict thread matches above, loose matches on Subject: below --
2004-03-12 19:37 Martin Schwidefsky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®