diff options
Diffstat (limited to 'drivers/s390/block/dasd_devmap.c')
-rw-r--r-- | drivers/s390/block/dasd_devmap.c | 155 |
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 | } |
644 | EXPORT_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 | ||
870 | static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store); | 873 | static 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 | */ | ||
879 | static ssize_t | ||
880 | dasd_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 | |||
893 | static ssize_t | ||
894 | dasd_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 | |||
922 | static DEVICE_ATTR(raw_track_access, 0644, dasd_use_raw_show, | ||
923 | dasd_use_raw_store); | ||
924 | |||
872 | static ssize_t | 925 | static ssize_t |
873 | dasd_discipline_show(struct device *dev, struct device_attribute *attr, | 926 | dasd_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 | ||
1127 | static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store); | 1180 | static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store); |
1128 | 1181 | ||
1182 | static 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 | |||
1203 | static 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 | |||
1230 | static DEVICE_ATTR(reservation_policy, 0644, | ||
1231 | dasd_reservation_policy_show, dasd_reservation_policy_store); | ||
1232 | |||
1233 | static 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 | |||
1254 | static 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 | |||
1276 | static DEVICE_ATTR(last_known_reservation_state, 0644, | ||
1277 | dasd_reservation_state_show, dasd_reservation_state_store); | ||
1278 | |||
1129 | static struct attribute * dasd_attrs[] = { | 1279 | static 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 | ||