Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[~shefty/rdma-dev.git] / drivers / s390 / block / dasd_devmap.c
index 20cfd028edcfae886f44584289295c20372aa5d6..c196827c228fb9f3ce79412e7422051f2307d14d 100644 (file)
@@ -951,6 +951,39 @@ dasd_use_raw_store(struct device *dev, struct device_attribute *attr,
 static DEVICE_ATTR(raw_track_access, 0644, dasd_use_raw_show,
                   dasd_use_raw_store);
 
+static ssize_t
+dasd_safe_offline_store(struct device *dev, struct device_attribute *attr,
+                       const char *buf, size_t count)
+{
+       struct ccw_device *cdev = to_ccwdev(dev);
+       struct dasd_device *device;
+       int rc;
+
+       device = dasd_device_from_cdev(cdev);
+       if (IS_ERR(device)) {
+               rc = PTR_ERR(device);
+               goto out;
+       }
+
+       if (test_bit(DASD_FLAG_OFFLINE, &device->flags) ||
+           test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) {
+               /* Already doing offline processing */
+               dasd_put_device(device);
+               rc = -EBUSY;
+               goto out;
+       }
+
+       set_bit(DASD_FLAG_SAFE_OFFLINE, &device->flags);
+       dasd_put_device(device);
+
+       rc = ccw_device_set_offline(cdev);
+
+out:
+       return rc ? rc : count;
+}
+
+static DEVICE_ATTR(safe_offline, 0200, NULL, dasd_safe_offline_store);
+
 static ssize_t
 dasd_discipline_show(struct device *dev, struct device_attribute *attr,
                     char *buf)
@@ -1320,6 +1353,7 @@ static struct attribute * dasd_attrs[] = {
        &dev_attr_expires.attr,
        &dev_attr_reservation_policy.attr,
        &dev_attr_last_known_reservation_state.attr,
+       &dev_attr_safe_offline.attr,
        NULL,
 };