aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd_devmap.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/s390/block/dasd_devmap.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (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.c187
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}
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.
@@ -671,6 +674,36 @@ dasd_device_from_cdev(struct ccw_device *cdev)
671 return device; 674 return device;
672} 675}
673 676
677void 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
689struct 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
870static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store); 903static 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 */
909static ssize_t
910dasd_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
923static ssize_t
924dasd_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
952static DEVICE_ATTR(raw_track_access, 0644, dasd_use_raw_show,
953 dasd_use_raw_store);
954
872static ssize_t 955static ssize_t
873dasd_discipline_show(struct device *dev, struct device_attribute *attr, 956dasd_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
1127static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store); 1210static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store);
1128 1211
1212static 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
1233static 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
1260static DEVICE_ATTR(reservation_policy, 0644,
1261 dasd_reservation_policy_show, dasd_reservation_policy_store);
1262
1263static 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
1284static 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
1306static DEVICE_ATTR(last_known_reservation_state, 0644,
1307 dasd_reservation_state_show, dasd_reservation_state_store);
1308
1129static struct attribute * dasd_attrs[] = { 1309static 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