diff options
author | Stefan Haberland <stefan.haberland@de.ibm.com> | 2011-01-05 06:48:06 -0500 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2011-01-05 06:47:30 -0500 |
commit | e4dbb0f2b5dd6a836d0e5c60aa5f573e0bbcf76a (patch) | |
tree | cb18d0b08f2ccc8d6a078456b77f111805777db8 /drivers/s390/block/dasd_devmap.c | |
parent | 6f272b9cec285a9610a2acf101f694bc58bed37e (diff) |
[S390] dasd: Add support for raw ECKD access.
Normal I/O operations through the DASD device driver give only access
to the data fields of an ECKD device even for track based I/O.
This patch extends the DASD device driver to give access to whole
ECKD tracks including count, key and data fields.
Signed-off-by: Stefan Haberland <stefan.haberland@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block/dasd_devmap.c')
-rw-r--r-- | drivers/s390/block/dasd_devmap.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 47fc88692494..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)) |
@@ -857,7 +859,7 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr, | |||
857 | spin_lock(&dasd_devmap_lock); | 859 | spin_lock(&dasd_devmap_lock); |
858 | /* Changing diag discipline flag is only allowed in offline state. */ | 860 | /* Changing diag discipline flag is only allowed in offline state. */ |
859 | rc = count; | 861 | rc = count; |
860 | if (!devmap->device) { | 862 | if (!devmap->device && !(devmap->features & DASD_FEATURE_USERAW)) { |
861 | if (val) | 863 | if (val) |
862 | devmap->features |= DASD_FEATURE_USEDIAG; | 864 | devmap->features |= DASD_FEATURE_USEDIAG; |
863 | else | 865 | else |
@@ -870,6 +872,56 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr, | |||
870 | 872 | ||
871 | 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); |
872 | 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 | |||
873 | static ssize_t | 925 | static ssize_t |
874 | dasd_discipline_show(struct device *dev, struct device_attribute *attr, | 926 | dasd_discipline_show(struct device *dev, struct device_attribute *attr, |
875 | char *buf) | 927 | char *buf) |
@@ -1232,6 +1284,7 @@ static struct attribute * dasd_attrs[] = { | |||
1232 | &dev_attr_vendor.attr, | 1284 | &dev_attr_vendor.attr, |
1233 | &dev_attr_uid.attr, | 1285 | &dev_attr_uid.attr, |
1234 | &dev_attr_use_diag.attr, | 1286 | &dev_attr_use_diag.attr, |
1287 | &dev_attr_raw_track_access.attr, | ||
1235 | &dev_attr_eer_enabled.attr, | 1288 | &dev_attr_eer_enabled.attr, |
1236 | &dev_attr_erplog.attr, | 1289 | &dev_attr_erplog.attr, |
1237 | &dev_attr_failfast.attr, | 1290 | &dev_attr_failfast.attr, |