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"
* 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>
{
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",
goto out;
}
- atomic_inc(&device->open_count);
return 0;
out:
module_put(device->discipline->owner);
+unlock:
+ atomic_dec(&device->open_count);
return rc;
}
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);
}
{
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);
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;
}
* 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>
if (!ip) { /* no intparm: unsolicited interrupt */
MESSAGE(KERN_DEBUG, "%s", "caught unsolicited interrupt");
- irq_exit();
return;
}
cqr = (struct dasd_ccw_req *)(addr_t) ip;
" magic number of dasd_ccw_req 0x%08X doesn't"
" match discipline 0x%08X",
cqr->magic, *(int *) (&device->discipline->name));
- irq_exit();
return;
}