~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to drivers/s390/block/dasd_devmap.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
#include <linux/ctype.h>
19
19
#include <linux/init.h>
20
20
#include <linux/module.h>
 
21
#include <linux/slab.h>
21
22
 
22
23
#include <asm/debug.h>
23
24
#include <asm/uaccess.h>
48
49
        unsigned int devindex;
49
50
        unsigned short features;
50
51
        struct dasd_device *device;
51
 
        struct dasd_uid uid;
52
52
};
53
53
 
54
54
/*
208
208
                        features |= DASD_FEATURE_READONLY;
209
209
                else if (len == 4 && !strncmp(str, "diag", 4))
210
210
                        features |= DASD_FEATURE_USEDIAG;
 
211
                else if (len == 3 && !strncmp(str, "raw", 3))
 
212
                        features |= DASD_FEATURE_USERAW;
211
213
                else if (len == 6 && !strncmp(str, "erplog", 6))
212
214
                        features |= DASD_FEATURE_ERPLOG;
213
215
                else if (len == 8 && !strncmp(str, "failfast", 8))
639
641
{
640
642
        wake_up(&dasd_delete_wq);
641
643
}
 
644
EXPORT_SYMBOL_GPL(dasd_put_device_wake);
642
645
 
643
646
/*
644
647
 * Return dasd_device structure associated with cdev.
742
745
              const char *buf, size_t count)
743
746
{
744
747
        struct dasd_devmap *devmap;
 
748
        struct dasd_device *device;
745
749
        int val;
746
750
        char *endp;
747
751
 
758
762
                devmap->features |= DASD_FEATURE_READONLY;
759
763
        else
760
764
                devmap->features &= ~DASD_FEATURE_READONLY;
761
 
        if (devmap->device)
762
 
                devmap->device->features = devmap->features;
763
 
        if (devmap->device && devmap->device->block
764
 
            && devmap->device->block->gdp)
765
 
                set_disk_ro(devmap->device->block->gdp, val);
 
765
        device = devmap->device;
 
766
        if (device) {
 
767
                device->features = devmap->features;
 
768
                val = val || test_bit(DASD_FLAG_DEVICE_RO, &device->flags);
 
769
        }
766
770
        spin_unlock(&dasd_devmap_lock);
 
771
        if (device && device->block && device->block->gdp)
 
772
                set_disk_ro(device->block->gdp, val);
767
773
        return count;
768
774
}
769
775
 
853
859
        spin_lock(&dasd_devmap_lock);
854
860
        /* Changing diag discipline flag is only allowed in offline state. */
855
861
        rc = count;
856
 
        if (!devmap->device) {
 
862
        if (!devmap->device && !(devmap->features & DASD_FEATURE_USERAW)) {
857
863
                if (val)
858
864
                        devmap->features |= DASD_FEATURE_USEDIAG;
859
865
                else
866
872
 
867
873
static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
868
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
 
869
925
static ssize_t
870
926
dasd_discipline_show(struct device *dev, struct device_attribute *attr,
871
927
                     char *buf)
874
930
        ssize_t len;
875
931
 
876
932
        device = dasd_device_from_cdev(to_ccwdev(dev));
877
 
        if (!IS_ERR(device) && device->discipline) {
 
933
        if (IS_ERR(device))
 
934
                goto out;
 
935
        else if (!device->discipline) {
 
936
                dasd_put_device(device);
 
937
                goto out;
 
938
        } else {
878
939
                len = snprintf(buf, PAGE_SIZE, "%s\n",
879
940
                               device->discipline->name);
880
941
                dasd_put_device(device);
881
 
        } else
882
 
                len = snprintf(buf, PAGE_SIZE, "none\n");
 
942
                return len;
 
943
        }
 
944
out:
 
945
        len = snprintf(buf, PAGE_SIZE, "none\n");
883
946
        return len;
884
947
}
885
948
 
925
988
 
926
989
static DEVICE_ATTR(status, 0444, dasd_device_status_show, NULL);
927
990
 
928
 
static ssize_t
929
 
dasd_alias_show(struct device *dev, struct device_attribute *attr, char *buf)
 
991
static ssize_t dasd_alias_show(struct device *dev,
 
992
                               struct device_attribute *attr, char *buf)
930
993
{
931
 
        struct dasd_devmap *devmap;
932
 
        int alias;
 
994
        struct dasd_device *device;
 
995
        struct dasd_uid uid;
933
996
 
934
 
        devmap = dasd_find_busid(dev_name(dev));
935
 
        spin_lock(&dasd_devmap_lock);
936
 
        if (IS_ERR(devmap) || strlen(devmap->uid.vendor) == 0) {
937
 
                spin_unlock(&dasd_devmap_lock);
 
997
        device = dasd_device_from_cdev(to_ccwdev(dev));
 
998
        if (IS_ERR(device))
938
999
                return sprintf(buf, "0\n");
 
1000
 
 
1001
        if (device->discipline && device->discipline->get_uid &&
 
1002
            !device->discipline->get_uid(device, &uid)) {
 
1003
                if (uid.type == UA_BASE_PAV_ALIAS ||
 
1004
                    uid.type == UA_HYPER_PAV_ALIAS) {
 
1005
                        dasd_put_device(device);
 
1006
                        return sprintf(buf, "1\n");
 
1007
                }
939
1008
        }
940
 
        if (devmap->uid.type == UA_BASE_PAV_ALIAS ||
941
 
            devmap->uid.type == UA_HYPER_PAV_ALIAS)
942
 
                alias = 1;
943
 
        else
944
 
                alias = 0;
945
 
        spin_unlock(&dasd_devmap_lock);
946
 
        return sprintf(buf, alias ? "1\n" : "0\n");
 
1009
        dasd_put_device(device);
 
1010
 
 
1011
        return sprintf(buf, "0\n");
947
1012
}
948
1013
 
949
1014
static DEVICE_ATTR(alias, 0444, dasd_alias_show, NULL);
950
1015
 
951
 
static ssize_t
952
 
dasd_vendor_show(struct device *dev, struct device_attribute *attr, char *buf)
 
1016
static ssize_t dasd_vendor_show(struct device *dev,
 
1017
                                struct device_attribute *attr, char *buf)
953
1018
{
954
 
        struct dasd_devmap *devmap;
 
1019
        struct dasd_device *device;
 
1020
        struct dasd_uid uid;
955
1021
        char *vendor;
956
1022
 
957
 
        devmap = dasd_find_busid(dev_name(dev));
958
 
        spin_lock(&dasd_devmap_lock);
959
 
        if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0)
960
 
                vendor = devmap->uid.vendor;
961
 
        else
962
 
                vendor = "";
963
 
        spin_unlock(&dasd_devmap_lock);
 
1023
        device = dasd_device_from_cdev(to_ccwdev(dev));
 
1024
        vendor = "";
 
1025
        if (IS_ERR(device))
 
1026
                return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
 
1027
 
 
1028
        if (device->discipline && device->discipline->get_uid &&
 
1029
            !device->discipline->get_uid(device, &uid))
 
1030
                        vendor = uid.vendor;
 
1031
 
 
1032
        dasd_put_device(device);
964
1033
 
965
1034
        return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
966
1035
}
974
1043
static ssize_t
975
1044
dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf)
976
1045
{
977
 
        struct dasd_devmap *devmap;
 
1046
        struct dasd_device *device;
 
1047
        struct dasd_uid uid;
978
1048
        char uid_string[UID_STRLEN];
979
1049
        char ua_string[3];
980
 
        struct dasd_uid *uid;
981
 
 
982
 
        devmap = dasd_find_busid(dev_name(dev));
983
 
        spin_lock(&dasd_devmap_lock);
984
 
        if (IS_ERR(devmap) || strlen(devmap->uid.vendor) == 0) {
985
 
                spin_unlock(&dasd_devmap_lock);
986
 
                return sprintf(buf, "\n");
987
 
        }
988
 
        uid = &devmap->uid;
989
 
        switch (uid->type) {
990
 
        case UA_BASE_DEVICE:
991
 
                sprintf(ua_string, "%02x", uid->real_unit_addr);
992
 
                break;
993
 
        case UA_BASE_PAV_ALIAS:
994
 
                sprintf(ua_string, "%02x", uid->base_unit_addr);
995
 
                break;
996
 
        case UA_HYPER_PAV_ALIAS:
997
 
                sprintf(ua_string, "xx");
998
 
                break;
999
 
        default:
1000
 
                /* should not happen, treat like base device */
1001
 
                sprintf(ua_string, "%02x", uid->real_unit_addr);
1002
 
                break;
1003
 
        }
1004
 
        if (strlen(uid->vduit) > 0)
1005
 
                snprintf(uid_string, sizeof(uid_string),
1006
 
                         "%s.%s.%04x.%s.%s",
1007
 
                         uid->vendor, uid->serial,
1008
 
                         uid->ssid, ua_string,
1009
 
                         uid->vduit);
1010
 
        else
1011
 
                snprintf(uid_string, sizeof(uid_string),
1012
 
                         "%s.%s.%04x.%s",
1013
 
                         uid->vendor, uid->serial,
1014
 
                         uid->ssid, ua_string);
1015
 
        spin_unlock(&dasd_devmap_lock);
 
1050
 
 
1051
        device = dasd_device_from_cdev(to_ccwdev(dev));
 
1052
        uid_string[0] = 0;
 
1053
        if (IS_ERR(device))
 
1054
                return snprintf(buf, PAGE_SIZE, "%s\n", uid_string);
 
1055
 
 
1056
        if (device->discipline && device->discipline->get_uid &&
 
1057
            !device->discipline->get_uid(device, &uid)) {
 
1058
                switch (uid.type) {
 
1059
                case UA_BASE_DEVICE:
 
1060
                        snprintf(ua_string, sizeof(ua_string), "%02x",
 
1061
                                 uid.real_unit_addr);
 
1062
                        break;
 
1063
                case UA_BASE_PAV_ALIAS:
 
1064
                        snprintf(ua_string, sizeof(ua_string), "%02x",
 
1065
                                 uid.base_unit_addr);
 
1066
                        break;
 
1067
                case UA_HYPER_PAV_ALIAS:
 
1068
                        snprintf(ua_string, sizeof(ua_string), "xx");
 
1069
                        break;
 
1070
                default:
 
1071
                        /* should not happen, treat like base device */
 
1072
                        snprintf(ua_string, sizeof(ua_string), "%02x",
 
1073
                                 uid.real_unit_addr);
 
1074
                        break;
 
1075
                }
 
1076
 
 
1077
                if (strlen(uid.vduit) > 0)
 
1078
                        snprintf(uid_string, sizeof(uid_string),
 
1079
                                 "%s.%s.%04x.%s.%s",
 
1080
                                 uid.vendor, uid.serial, uid.ssid, ua_string,
 
1081
                                 uid.vduit);
 
1082
                else
 
1083
                        snprintf(uid_string, sizeof(uid_string),
 
1084
                                 "%s.%s.%04x.%s",
 
1085
                                 uid.vendor, uid.serial, uid.ssid, ua_string);
 
1086
        }
 
1087
        dasd_put_device(device);
 
1088
 
1016
1089
        return snprintf(buf, PAGE_SIZE, "%s\n", uid_string);
1017
1090
}
1018
 
 
1019
1091
static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL);
1020
1092
 
1021
1093
/*
1064
1136
 
1065
1137
static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store);
1066
1138
 
 
1139
/*
 
1140
 * expiration time for default requests
 
1141
 */
 
1142
static ssize_t
 
1143
dasd_expires_show(struct device *dev, struct device_attribute *attr, char *buf)
 
1144
{
 
1145
        struct dasd_device *device;
 
1146
        int len;
 
1147
 
 
1148
        device = dasd_device_from_cdev(to_ccwdev(dev));
 
1149
        if (IS_ERR(device))
 
1150
                return -ENODEV;
 
1151
        len = snprintf(buf, PAGE_SIZE, "%lu\n", device->default_expires);
 
1152
        dasd_put_device(device);
 
1153
        return len;
 
1154
}
 
1155
 
 
1156
static ssize_t
 
1157
dasd_expires_store(struct device *dev, struct device_attribute *attr,
 
1158
               const char *buf, size_t count)
 
1159
{
 
1160
        struct dasd_device *device;
 
1161
        unsigned long val;
 
1162
 
 
1163
        device = dasd_device_from_cdev(to_ccwdev(dev));
 
1164
        if (IS_ERR(device))
 
1165
                return -ENODEV;
 
1166
 
 
1167
        if ((strict_strtoul(buf, 10, &val) != 0) ||
 
1168
            (val > DASD_EXPIRES_MAX) || val == 0) {
 
1169
                dasd_put_device(device);
 
1170
                return -EINVAL;
 
1171
        }
 
1172
 
 
1173
        if (val)
 
1174
                device->default_expires = val;
 
1175
 
 
1176
        dasd_put_device(device);
 
1177
        return count;
 
1178
}
 
1179
 
 
1180
static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store);
 
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
 
1067
1279
static struct attribute * dasd_attrs[] = {
1068
1280
        &dev_attr_readonly.attr,
1069
1281
        &dev_attr_discipline.attr,
1072
1284
        &dev_attr_vendor.attr,
1073
1285
        &dev_attr_uid.attr,
1074
1286
        &dev_attr_use_diag.attr,
 
1287
        &dev_attr_raw_track_access.attr,
1075
1288
        &dev_attr_eer_enabled.attr,
1076
1289
        &dev_attr_erplog.attr,
1077
1290
        &dev_attr_failfast.attr,
 
1291
        &dev_attr_expires.attr,
 
1292
        &dev_attr_reservation_policy.attr,
 
1293
        &dev_attr_last_known_reservation_state.attr,
1078
1294
        NULL,
1079
1295
};
1080
1296
 
1083
1299
};
1084
1300
 
1085
1301
/*
1086
 
 * Return copy of the device unique identifier.
1087
 
 */
1088
 
int
1089
 
dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid)
1090
 
{
1091
 
        struct dasd_devmap *devmap;
1092
 
 
1093
 
        devmap = dasd_find_busid(dev_name(&cdev->dev));
1094
 
        if (IS_ERR(devmap))
1095
 
                return PTR_ERR(devmap);
1096
 
        spin_lock(&dasd_devmap_lock);
1097
 
        *uid = devmap->uid;
1098
 
        spin_unlock(&dasd_devmap_lock);
1099
 
        return 0;
1100
 
}
1101
 
EXPORT_SYMBOL_GPL(dasd_get_uid);
1102
 
 
1103
 
/*
1104
 
 * Register the given device unique identifier into devmap struct.
1105
 
 * In addition check if the related storage server subsystem ID is already
1106
 
 * contained in the dasd_server_ssid_list. If subsystem ID is not contained,
1107
 
 * create new entry.
1108
 
 * Return 0 if server was already in serverlist,
1109
 
 *        1 if the server was added successful
1110
 
 *       <0 in case of error.
1111
 
 */
1112
 
int
1113
 
dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid)
1114
 
{
1115
 
        struct dasd_devmap *devmap;
1116
 
 
1117
 
        devmap = dasd_find_busid(dev_name(&cdev->dev));
1118
 
        if (IS_ERR(devmap))
1119
 
                return PTR_ERR(devmap);
1120
 
 
1121
 
        spin_lock(&dasd_devmap_lock);
1122
 
        devmap->uid = *uid;
1123
 
        spin_unlock(&dasd_devmap_lock);
1124
 
 
1125
 
        return 0;
1126
 
}
1127
 
EXPORT_SYMBOL_GPL(dasd_set_uid);
1128
 
 
1129
 
/*
1130
1302
 * Return value of the specified feature.
1131
1303
 */
1132
1304
int