diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/s390/block/dasd_devmap.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/s390/block/dasd_devmap.c')
-rw-r--r-- | drivers/s390/block/dasd_devmap.c | 187 |
1 files changed, 185 insertions, 2 deletions
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 8d41f3ed38d7..d71511c7850a 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)) |
@@ -300,7 +302,7 @@ dasd_parse_keyword( char *parsestring ) { | |||
300 | /* | 302 | /* |
301 | * Try to interprete the first element on the comma separated parse string | 303 | * Try to interprete the first element on the comma separated parse string |
302 | * as a device number or a range of devices. If the interpretation is | 304 | * as a device number or a range of devices. If the interpretation is |
303 | * successfull, create the matching dasd_devmap entries and return a pointer | 305 | * successful, create the matching dasd_devmap entries and return a pointer |
304 | * to the residual string. | 306 | * to the residual string. |
305 | * If interpretation fails or in case of an error, return an error code. | 307 | * If interpretation fails or in case of an error, return an error code. |
306 | */ | 308 | */ |
@@ -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. |
@@ -671,6 +674,36 @@ dasd_device_from_cdev(struct ccw_device *cdev) | |||
671 | return device; | 674 | return device; |
672 | } | 675 | } |
673 | 676 | ||
677 | void dasd_add_link_to_gendisk(struct gendisk *gdp, struct dasd_device *device) | ||
678 | { | ||
679 | struct dasd_devmap *devmap; | ||
680 | |||
681 | devmap = dasd_find_busid(dev_name(&device->cdev->dev)); | ||
682 | if (IS_ERR(devmap)) | ||
683 | return; | ||
684 | spin_lock(&dasd_devmap_lock); | ||
685 | gdp->private_data = devmap; | ||
686 | spin_unlock(&dasd_devmap_lock); | ||
687 | } | ||
688 | |||
689 | struct dasd_device *dasd_device_from_gendisk(struct gendisk *gdp) | ||
690 | { | ||
691 | struct dasd_device *device; | ||
692 | struct dasd_devmap *devmap; | ||
693 | |||
694 | if (!gdp->private_data) | ||
695 | return NULL; | ||
696 | device = NULL; | ||
697 | spin_lock(&dasd_devmap_lock); | ||
698 | devmap = gdp->private_data; | ||
699 | if (devmap && devmap->device) { | ||
700 | device = devmap->device; | ||
701 | dasd_get_device(device); | ||
702 | } | ||
703 | spin_unlock(&dasd_devmap_lock); | ||
704 | return device; | ||
705 | } | ||
706 | |||
674 | /* | 707 | /* |
675 | * SECTION: files in sysfs | 708 | * SECTION: files in sysfs |
676 | */ | 709 | */ |
@@ -856,7 +889,7 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr, | |||
856 | spin_lock(&dasd_devmap_lock); | 889 | spin_lock(&dasd_devmap_lock); |
857 | /* Changing diag discipline flag is only allowed in offline state. */ | 890 | /* Changing diag discipline flag is only allowed in offline state. */ |
858 | rc = count; | 891 | rc = count; |
859 | if (!devmap->device) { | 892 | if (!devmap->device && !(devmap->features & DASD_FEATURE_USERAW)) { |
860 | if (val) | 893 | if (val) |
861 | devmap->features |= DASD_FEATURE_USEDIAG; | 894 | devmap->features |= DASD_FEATURE_USEDIAG; |
862 | else | 895 | else |
@@ -869,6 +902,56 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr, | |||
869 | 902 | ||
870 | static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store); | 903 | static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store); |
871 | 904 | ||
905 | /* | ||
906 | * use_raw controls whether the driver should give access to raw eckd data or | ||
907 | * operate in standard mode | ||
908 | */ | ||
909 | static ssize_t | ||
910 | dasd_use_raw_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
911 | { | ||
912 | struct dasd_devmap *devmap; | ||
913 | int use_raw; | ||
914 | |||
915 | devmap = dasd_find_busid(dev_name(dev)); | ||
916 | if (!IS_ERR(devmap)) | ||
917 | use_raw = (devmap->features & DASD_FEATURE_USERAW) != 0; | ||
918 | else | ||
919 | use_raw = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USERAW) != 0; | ||
920 | return sprintf(buf, use_raw ? "1\n" : "0\n"); | ||
921 | } | ||
922 | |||
923 | static ssize_t | ||
924 | dasd_use_raw_store(struct device *dev, struct device_attribute *attr, | ||
925 | const char *buf, size_t count) | ||
926 | { | ||
927 | struct dasd_devmap *devmap; | ||
928 | ssize_t rc; | ||
929 | unsigned long val; | ||
930 | |||
931 | devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); | ||
932 | if (IS_ERR(devmap)) | ||
933 | return PTR_ERR(devmap); | ||
934 | |||
935 | if ((strict_strtoul(buf, 10, &val) != 0) || val > 1) | ||
936 | return -EINVAL; | ||
937 | |||
938 | spin_lock(&dasd_devmap_lock); | ||
939 | /* Changing diag discipline flag is only allowed in offline state. */ | ||
940 | rc = count; | ||
941 | if (!devmap->device && !(devmap->features & DASD_FEATURE_USEDIAG)) { | ||
942 | if (val) | ||
943 | devmap->features |= DASD_FEATURE_USERAW; | ||
944 | else | ||
945 | devmap->features &= ~DASD_FEATURE_USERAW; | ||
946 | } else | ||
947 | rc = -EPERM; | ||
948 | spin_unlock(&dasd_devmap_lock); | ||
949 | return rc; | ||
950 | } | ||
951 | |||
952 | static DEVICE_ATTR(raw_track_access, 0644, dasd_use_raw_show, | ||
953 | dasd_use_raw_store); | ||
954 | |||
872 | static ssize_t | 955 | static ssize_t |
873 | dasd_discipline_show(struct device *dev, struct device_attribute *attr, | 956 | dasd_discipline_show(struct device *dev, struct device_attribute *attr, |
874 | char *buf) | 957 | char *buf) |
@@ -1126,6 +1209,103 @@ dasd_expires_store(struct device *dev, struct device_attribute *attr, | |||
1126 | 1209 | ||
1127 | static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store); | 1210 | static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store); |
1128 | 1211 | ||
1212 | static ssize_t dasd_reservation_policy_show(struct device *dev, | ||
1213 | struct device_attribute *attr, | ||
1214 | char *buf) | ||
1215 | { | ||
1216 | struct dasd_devmap *devmap; | ||
1217 | int rc = 0; | ||
1218 | |||
1219 | devmap = dasd_find_busid(dev_name(dev)); | ||
1220 | if (IS_ERR(devmap)) { | ||
1221 | rc = snprintf(buf, PAGE_SIZE, "ignore\n"); | ||
1222 | } else { | ||
1223 | spin_lock(&dasd_devmap_lock); | ||
1224 | if (devmap->features & DASD_FEATURE_FAILONSLCK) | ||
1225 | rc = snprintf(buf, PAGE_SIZE, "fail\n"); | ||
1226 | else | ||
1227 | rc = snprintf(buf, PAGE_SIZE, "ignore\n"); | ||
1228 | spin_unlock(&dasd_devmap_lock); | ||
1229 | } | ||
1230 | return rc; | ||
1231 | } | ||
1232 | |||
1233 | static ssize_t dasd_reservation_policy_store(struct device *dev, | ||
1234 | struct device_attribute *attr, | ||
1235 | const char *buf, size_t count) | ||
1236 | { | ||
1237 | struct dasd_devmap *devmap; | ||
1238 | int rc; | ||
1239 | |||
1240 | devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); | ||
1241 | if (IS_ERR(devmap)) | ||
1242 | return PTR_ERR(devmap); | ||
1243 | rc = 0; | ||
1244 | spin_lock(&dasd_devmap_lock); | ||
1245 | if (sysfs_streq("ignore", buf)) | ||
1246 | devmap->features &= ~DASD_FEATURE_FAILONSLCK; | ||
1247 | else if (sysfs_streq("fail", buf)) | ||
1248 | devmap->features |= DASD_FEATURE_FAILONSLCK; | ||
1249 | else | ||
1250 | rc = -EINVAL; | ||
1251 | if (devmap->device) | ||
1252 | devmap->device->features = devmap->features; | ||
1253 | spin_unlock(&dasd_devmap_lock); | ||
1254 | if (rc) | ||
1255 | return rc; | ||
1256 | else | ||
1257 | return count; | ||
1258 | } | ||
1259 | |||
1260 | static DEVICE_ATTR(reservation_policy, 0644, | ||
1261 | dasd_reservation_policy_show, dasd_reservation_policy_store); | ||
1262 | |||
1263 | static ssize_t dasd_reservation_state_show(struct device *dev, | ||
1264 | struct device_attribute *attr, | ||
1265 | char *buf) | ||
1266 | { | ||
1267 | struct dasd_device *device; | ||
1268 | int rc = 0; | ||
1269 | |||
1270 | device = dasd_device_from_cdev(to_ccwdev(dev)); | ||
1271 | if (IS_ERR(device)) | ||
1272 | return snprintf(buf, PAGE_SIZE, "none\n"); | ||
1273 | |||
1274 | if (test_bit(DASD_FLAG_IS_RESERVED, &device->flags)) | ||
1275 | rc = snprintf(buf, PAGE_SIZE, "reserved\n"); | ||
1276 | else if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags)) | ||
1277 | rc = snprintf(buf, PAGE_SIZE, "lost\n"); | ||
1278 | else | ||
1279 | rc = snprintf(buf, PAGE_SIZE, "none\n"); | ||
1280 | dasd_put_device(device); | ||
1281 | return rc; | ||
1282 | } | ||
1283 | |||
1284 | static ssize_t dasd_reservation_state_store(struct device *dev, | ||
1285 | struct device_attribute *attr, | ||
1286 | const char *buf, size_t count) | ||
1287 | { | ||
1288 | struct dasd_device *device; | ||
1289 | int rc = 0; | ||
1290 | |||
1291 | device = dasd_device_from_cdev(to_ccwdev(dev)); | ||
1292 | if (IS_ERR(device)) | ||
1293 | return -ENODEV; | ||
1294 | if (sysfs_streq("reset", buf)) | ||
1295 | clear_bit(DASD_FLAG_LOCK_STOLEN, &device->flags); | ||
1296 | else | ||
1297 | rc = -EINVAL; | ||
1298 | dasd_put_device(device); | ||
1299 | |||
1300 | if (rc) | ||
1301 | return rc; | ||
1302 | else | ||
1303 | return count; | ||
1304 | } | ||
1305 | |||
1306 | static DEVICE_ATTR(last_known_reservation_state, 0644, | ||
1307 | dasd_reservation_state_show, dasd_reservation_state_store); | ||
1308 | |||
1129 | static struct attribute * dasd_attrs[] = { | 1309 | static struct attribute * dasd_attrs[] = { |
1130 | &dev_attr_readonly.attr, | 1310 | &dev_attr_readonly.attr, |
1131 | &dev_attr_discipline.attr, | 1311 | &dev_attr_discipline.attr, |
@@ -1134,10 +1314,13 @@ static struct attribute * dasd_attrs[] = { | |||
1134 | &dev_attr_vendor.attr, | 1314 | &dev_attr_vendor.attr, |
1135 | &dev_attr_uid.attr, | 1315 | &dev_attr_uid.attr, |
1136 | &dev_attr_use_diag.attr, | 1316 | &dev_attr_use_diag.attr, |
1317 | &dev_attr_raw_track_access.attr, | ||
1137 | &dev_attr_eer_enabled.attr, | 1318 | &dev_attr_eer_enabled.attr, |
1138 | &dev_attr_erplog.attr, | 1319 | &dev_attr_erplog.attr, |
1139 | &dev_attr_failfast.attr, | 1320 | &dev_attr_failfast.attr, |
1140 | &dev_attr_expires.attr, | 1321 | &dev_attr_expires.attr, |
1322 | &dev_attr_reservation_policy.attr, | ||
1323 | &dev_attr_last_known_reservation_state.attr, | ||
1141 | NULL, | 1324 | NULL, |
1142 | }; | 1325 | }; |
1143 | 1326 | ||