aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd_devmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/block/dasd_devmap.c')
-rw-r--r--drivers/s390/block/dasd_devmap.c155
1 files changed, 154 insertions, 1 deletions
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 8d41f3ed38d7..cb6a67bc89ff 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -208,6 +208,8 @@ dasd_feature_list(char *str, char **endp)
208 features |= DASD_FEATURE_READONLY; 208 features |= DASD_FEATURE_READONLY;
209 else if (len == 4 && !strncmp(str, "diag", 4)) 209 else if (len == 4 && !strncmp(str, "diag", 4))
210 features |= DASD_FEATURE_USEDIAG; 210 features |= DASD_FEATURE_USEDIAG;
211 else if (len == 3 && !strncmp(str, "raw", 3))
212 features |= DASD_FEATURE_USERAW;
211 else if (len == 6 && !strncmp(str, "erplog", 6)) 213 else if (len == 6 && !strncmp(str, "erplog", 6))
212 features |= DASD_FEATURE_ERPLOG; 214 features |= DASD_FEATURE_ERPLOG;
213 else if (len == 8 && !strncmp(str, "failfast", 8)) 215 else if (len == 8 && !strncmp(str, "failfast", 8))
@@ -639,6 +641,7 @@ dasd_put_device_wake(struct dasd_device *device)
639{ 641{
640 wake_up(&dasd_delete_wq); 642 wake_up(&dasd_delete_wq);
641} 643}
644EXPORT_SYMBOL_GPL(dasd_put_device_wake);
642 645
643/* 646/*
644 * Return dasd_device structure associated with cdev. 647 * Return dasd_device structure associated with cdev.
@@ -856,7 +859,7 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
856 spin_lock(&dasd_devmap_lock); 859 spin_lock(&dasd_devmap_lock);
857 /* Changing diag discipline flag is only allowed in offline state. */ 860 /* Changing diag discipline flag is only allowed in offline state. */
858 rc = count; 861 rc = count;
859 if (!devmap->device) { 862 if (!devmap->device && !(devmap->features & DASD_FEATURE_USERAW)) {
860 if (val) 863 if (val)
861 devmap->features |= DASD_FEATURE_USEDIAG; 864 devmap->features |= DASD_FEATURE_USEDIAG;
862 else 865 else
@@ -869,6 +872,56 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
869 872
870static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store); 873static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
871 874
875/*
876 * use_raw controls whether the driver should give access to raw eckd data or
877 * operate in standard mode
878 */
879static ssize_t
880dasd_use_raw_show(struct device *dev, struct device_attribute *attr, char *buf)
881{
882 struct dasd_devmap *devmap;
883 int use_raw;
884
885 devmap = dasd_find_busid(dev_name(dev));
886 if (!IS_ERR(devmap))
887 use_raw = (devmap->features & DASD_FEATURE_USERAW) != 0;
888 else
889 use_raw = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USERAW) != 0;
890 return sprintf(buf, use_raw ? "1\n" : "0\n");
891}
892
893static ssize_t
894dasd_use_raw_store(struct device *dev, struct device_attribute *attr,
895 const char *buf, size_t count)
896{
897 struct dasd_devmap *devmap;
898 ssize_t rc;
899 unsigned long val;
900
901 devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
902 if (IS_ERR(devmap))
903 return PTR_ERR(devmap);
904
905 if ((strict_strtoul(buf, 10, &val) != 0) || val > 1)
906 return -EINVAL;
907
908 spin_lock(&dasd_devmap_lock);
909 /* Changing diag discipline flag is only allowed in offline state. */
910 rc = count;
911 if (!devmap->device && !(devmap->features & DASD_FEATURE_USEDIAG)) {
912 if (val)
913 devmap->features |= DASD_FEATURE_USERAW;
914 else
915 devmap->features &= ~DASD_FEATURE_USERAW;
916 } else
917 rc = -EPERM;
918 spin_unlock(&dasd_devmap_lock);
919 return rc;
920}
921
922static DEVICE_ATTR(raw_track_access, 0644, dasd_use_raw_show,
923 dasd_use_raw_store);
924
872static ssize_t 925static ssize_t
873dasd_discipline_show(struct device *dev, struct device_attribute *attr, 926dasd_discipline_show(struct device *dev, struct device_attribute *attr,
874 char *buf) 927 char *buf)
@@ -1126,6 +1179,103 @@ dasd_expires_store(struct device *dev, struct device_attribute *attr,
1126 1179
1127static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store); 1180static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store);
1128 1181
1182static ssize_t dasd_reservation_policy_show(struct device *dev,
1183 struct device_attribute *attr,
1184 char *buf)
1185{
1186 struct dasd_devmap *devmap;
1187 int rc = 0;
1188
1189 devmap = dasd_find_busid(dev_name(dev));
1190 if (IS_ERR(devmap)) {
1191 rc = snprintf(buf, PAGE_SIZE, "ignore\n");
1192 } else {
1193 spin_lock(&dasd_devmap_lock);
1194 if (devmap->features & DASD_FEATURE_FAILONSLCK)
1195 rc = snprintf(buf, PAGE_SIZE, "fail\n");
1196 else
1197 rc = snprintf(buf, PAGE_SIZE, "ignore\n");
1198 spin_unlock(&dasd_devmap_lock);
1199 }
1200 return rc;
1201}
1202
1203static ssize_t dasd_reservation_policy_store(struct device *dev,
1204 struct device_attribute *attr,
1205 const char *buf, size_t count)
1206{
1207 struct dasd_devmap *devmap;
1208 int rc;
1209
1210 devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
1211 if (IS_ERR(devmap))
1212 return PTR_ERR(devmap);
1213 rc = 0;
1214 spin_lock(&dasd_devmap_lock);
1215 if (sysfs_streq("ignore", buf))
1216 devmap->features &= ~DASD_FEATURE_FAILONSLCK;
1217 else if (sysfs_streq("fail", buf))
1218 devmap->features |= DASD_FEATURE_FAILONSLCK;
1219 else
1220 rc = -EINVAL;
1221 if (devmap->device)
1222 devmap->device->features = devmap->features;
1223 spin_unlock(&dasd_devmap_lock);
1224 if (rc)
1225 return rc;
1226 else
1227 return count;
1228}
1229
1230static DEVICE_ATTR(reservation_policy, 0644,
1231 dasd_reservation_policy_show, dasd_reservation_policy_store);
1232
1233static ssize_t dasd_reservation_state_show(struct device *dev,
1234 struct device_attribute *attr,
1235 char *buf)
1236{
1237 struct dasd_device *device;
1238 int rc = 0;
1239
1240 device = dasd_device_from_cdev(to_ccwdev(dev));
1241 if (IS_ERR(device))
1242 return snprintf(buf, PAGE_SIZE, "none\n");
1243
1244 if (test_bit(DASD_FLAG_IS_RESERVED, &device->flags))
1245 rc = snprintf(buf, PAGE_SIZE, "reserved\n");
1246 else if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags))
1247 rc = snprintf(buf, PAGE_SIZE, "lost\n");
1248 else
1249 rc = snprintf(buf, PAGE_SIZE, "none\n");
1250 dasd_put_device(device);
1251 return rc;
1252}
1253
1254static ssize_t dasd_reservation_state_store(struct device *dev,
1255 struct device_attribute *attr,
1256 const char *buf, size_t count)
1257{
1258 struct dasd_device *device;
1259 int rc = 0;
1260
1261 device = dasd_device_from_cdev(to_ccwdev(dev));
1262 if (IS_ERR(device))
1263 return -ENODEV;
1264 if (sysfs_streq("reset", buf))
1265 clear_bit(DASD_FLAG_LOCK_STOLEN, &device->flags);
1266 else
1267 rc = -EINVAL;
1268 dasd_put_device(device);
1269
1270 if (rc)
1271 return rc;
1272 else
1273 return count;
1274}
1275
1276static DEVICE_ATTR(last_known_reservation_state, 0644,
1277 dasd_reservation_state_show, dasd_reservation_state_store);
1278
1129static struct attribute * dasd_attrs[] = { 1279static struct attribute * dasd_attrs[] = {
1130 &dev_attr_readonly.attr, 1280 &dev_attr_readonly.attr,
1131 &dev_attr_discipline.attr, 1281 &dev_attr_discipline.attr,
@@ -1134,10 +1284,13 @@ static struct attribute * dasd_attrs[] = {
1134 &dev_attr_vendor.attr, 1284 &dev_attr_vendor.attr,
1135 &dev_attr_uid.attr, 1285 &dev_attr_uid.attr,
1136 &dev_attr_use_diag.attr, 1286 &dev_attr_use_diag.attr,
1287 &dev_attr_raw_track_access.attr,
1137 &dev_attr_eer_enabled.attr, 1288 &dev_attr_eer_enabled.attr,
1138 &dev_attr_erplog.attr, 1289 &dev_attr_erplog.attr,
1139 &dev_attr_failfast.attr, 1290 &dev_attr_failfast.attr,
1140 &dev_attr_expires.attr, 1291 &dev_attr_expires.attr,
1292 &dev_attr_reservation_policy.attr,
1293 &dev_attr_last_known_reservation_state.attr,
1141 NULL, 1294 NULL,
1142}; 1295};
1143 1296