diff options
Diffstat (limited to 'drivers/s390/block/dasd_devmap.c')
-rw-r--r-- | drivers/s390/block/dasd_devmap.c | 94 |
1 files changed, 37 insertions, 57 deletions
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 0c67258fb9ec..f4fb40257348 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c | |||
@@ -49,22 +49,6 @@ struct dasd_devmap { | |||
49 | }; | 49 | }; |
50 | 50 | ||
51 | /* | 51 | /* |
52 | * dasd_server_ssid_map contains a globally unique storage server subsystem ID. | ||
53 | * dasd_server_ssid_list contains the list of all subsystem IDs accessed by | ||
54 | * the DASD device driver. | ||
55 | */ | ||
56 | struct dasd_server_ssid_map { | ||
57 | struct list_head list; | ||
58 | struct system_id { | ||
59 | char vendor[4]; | ||
60 | char serial[15]; | ||
61 | __u16 ssid; | ||
62 | } sid; | ||
63 | }; | ||
64 | |||
65 | static struct list_head dasd_server_ssid_list; | ||
66 | |||
67 | /* | ||
68 | * Parameter parsing functions for dasd= parameter. The syntax is: | 52 | * Parameter parsing functions for dasd= parameter. The syntax is: |
69 | * <devno> : (0x)?[0-9a-fA-F]+ | 53 | * <devno> : (0x)?[0-9a-fA-F]+ |
70 | * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+ | 54 | * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+ |
@@ -721,8 +705,9 @@ dasd_ro_store(struct device *dev, struct device_attribute *attr, | |||
721 | devmap->features &= ~DASD_FEATURE_READONLY; | 705 | devmap->features &= ~DASD_FEATURE_READONLY; |
722 | if (devmap->device) | 706 | if (devmap->device) |
723 | devmap->device->features = devmap->features; | 707 | devmap->device->features = devmap->features; |
724 | if (devmap->device && devmap->device->gdp) | 708 | if (devmap->device && devmap->device->block |
725 | set_disk_ro(devmap->device->gdp, val); | 709 | && devmap->device->block->gdp) |
710 | set_disk_ro(devmap->device->block->gdp, val); | ||
726 | spin_unlock(&dasd_devmap_lock); | 711 | spin_unlock(&dasd_devmap_lock); |
727 | return count; | 712 | return count; |
728 | } | 713 | } |
@@ -893,12 +878,16 @@ dasd_alias_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
893 | 878 | ||
894 | devmap = dasd_find_busid(dev->bus_id); | 879 | devmap = dasd_find_busid(dev->bus_id); |
895 | spin_lock(&dasd_devmap_lock); | 880 | spin_lock(&dasd_devmap_lock); |
896 | if (!IS_ERR(devmap)) | 881 | if (IS_ERR(devmap) || strlen(devmap->uid.vendor) == 0) { |
897 | alias = devmap->uid.alias; | 882 | spin_unlock(&dasd_devmap_lock); |
883 | return sprintf(buf, "0\n"); | ||
884 | } | ||
885 | if (devmap->uid.type == UA_BASE_PAV_ALIAS || | ||
886 | devmap->uid.type == UA_HYPER_PAV_ALIAS) | ||
887 | alias = 1; | ||
898 | else | 888 | else |
899 | alias = 0; | 889 | alias = 0; |
900 | spin_unlock(&dasd_devmap_lock); | 890 | spin_unlock(&dasd_devmap_lock); |
901 | |||
902 | return sprintf(buf, alias ? "1\n" : "0\n"); | 891 | return sprintf(buf, alias ? "1\n" : "0\n"); |
903 | } | 892 | } |
904 | 893 | ||
@@ -930,19 +919,36 @@ static ssize_t | |||
930 | dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf) | 919 | dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf) |
931 | { | 920 | { |
932 | struct dasd_devmap *devmap; | 921 | struct dasd_devmap *devmap; |
933 | char uid[UID_STRLEN]; | 922 | char uid_string[UID_STRLEN]; |
923 | char ua_string[3]; | ||
924 | struct dasd_uid *uid; | ||
934 | 925 | ||
935 | devmap = dasd_find_busid(dev->bus_id); | 926 | devmap = dasd_find_busid(dev->bus_id); |
936 | spin_lock(&dasd_devmap_lock); | 927 | spin_lock(&dasd_devmap_lock); |
937 | if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0) | 928 | if (IS_ERR(devmap) || strlen(devmap->uid.vendor) == 0) { |
938 | snprintf(uid, sizeof(uid), "%s.%s.%04x.%02x", | 929 | spin_unlock(&dasd_devmap_lock); |
939 | devmap->uid.vendor, devmap->uid.serial, | 930 | return sprintf(buf, "\n"); |
940 | devmap->uid.ssid, devmap->uid.unit_addr); | 931 | } |
941 | else | 932 | uid = &devmap->uid; |
942 | uid[0] = 0; | 933 | switch (uid->type) { |
934 | case UA_BASE_DEVICE: | ||
935 | sprintf(ua_string, "%02x", uid->real_unit_addr); | ||
936 | break; | ||
937 | case UA_BASE_PAV_ALIAS: | ||
938 | sprintf(ua_string, "%02x", uid->base_unit_addr); | ||
939 | break; | ||
940 | case UA_HYPER_PAV_ALIAS: | ||
941 | sprintf(ua_string, "xx"); | ||
942 | break; | ||
943 | default: | ||
944 | /* should not happen, treat like base device */ | ||
945 | sprintf(ua_string, "%02x", uid->real_unit_addr); | ||
946 | break; | ||
947 | } | ||
948 | snprintf(uid_string, sizeof(uid_string), "%s.%s.%04x.%s", | ||
949 | uid->vendor, uid->serial, uid->ssid, ua_string); | ||
943 | spin_unlock(&dasd_devmap_lock); | 950 | spin_unlock(&dasd_devmap_lock); |
944 | 951 | return snprintf(buf, PAGE_SIZE, "%s\n", uid_string); | |
945 | return snprintf(buf, PAGE_SIZE, "%s\n", uid); | ||
946 | } | 952 | } |
947 | 953 | ||
948 | static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL); | 954 | static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL); |
@@ -1040,39 +1046,16 @@ int | |||
1040 | dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) | 1046 | dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) |
1041 | { | 1047 | { |
1042 | struct dasd_devmap *devmap; | 1048 | struct dasd_devmap *devmap; |
1043 | struct dasd_server_ssid_map *srv, *tmp; | ||
1044 | 1049 | ||
1045 | devmap = dasd_find_busid(cdev->dev.bus_id); | 1050 | devmap = dasd_find_busid(cdev->dev.bus_id); |
1046 | if (IS_ERR(devmap)) | 1051 | if (IS_ERR(devmap)) |
1047 | return PTR_ERR(devmap); | 1052 | return PTR_ERR(devmap); |
1048 | 1053 | ||
1049 | /* generate entry for server_ssid_map */ | ||
1050 | srv = (struct dasd_server_ssid_map *) | ||
1051 | kzalloc(sizeof(struct dasd_server_ssid_map), GFP_KERNEL); | ||
1052 | if (!srv) | ||
1053 | return -ENOMEM; | ||
1054 | strncpy(srv->sid.vendor, uid->vendor, sizeof(srv->sid.vendor) - 1); | ||
1055 | strncpy(srv->sid.serial, uid->serial, sizeof(srv->sid.serial) - 1); | ||
1056 | srv->sid.ssid = uid->ssid; | ||
1057 | |||
1058 | /* server is already contained ? */ | ||
1059 | spin_lock(&dasd_devmap_lock); | 1054 | spin_lock(&dasd_devmap_lock); |
1060 | devmap->uid = *uid; | 1055 | devmap->uid = *uid; |
1061 | list_for_each_entry(tmp, &dasd_server_ssid_list, list) { | ||
1062 | if (!memcmp(&srv->sid, &tmp->sid, | ||
1063 | sizeof(struct system_id))) { | ||
1064 | kfree(srv); | ||
1065 | srv = NULL; | ||
1066 | break; | ||
1067 | } | ||
1068 | } | ||
1069 | |||
1070 | /* add servermap to serverlist */ | ||
1071 | if (srv) | ||
1072 | list_add(&srv->list, &dasd_server_ssid_list); | ||
1073 | spin_unlock(&dasd_devmap_lock); | 1056 | spin_unlock(&dasd_devmap_lock); |
1074 | 1057 | ||
1075 | return (srv ? 1 : 0); | 1058 | return 0; |
1076 | } | 1059 | } |
1077 | EXPORT_SYMBOL_GPL(dasd_set_uid); | 1060 | EXPORT_SYMBOL_GPL(dasd_set_uid); |
1078 | 1061 | ||
@@ -1138,9 +1121,6 @@ dasd_devmap_init(void) | |||
1138 | dasd_max_devindex = 0; | 1121 | dasd_max_devindex = 0; |
1139 | for (i = 0; i < 256; i++) | 1122 | for (i = 0; i < 256; i++) |
1140 | INIT_LIST_HEAD(&dasd_hashlists[i]); | 1123 | INIT_LIST_HEAD(&dasd_hashlists[i]); |
1141 | |||
1142 | /* Initialize servermap structure. */ | ||
1143 | INIT_LIST_HEAD(&dasd_server_ssid_list); | ||
1144 | return 0; | 1124 | return 0; |
1145 | } | 1125 | } |
1146 | 1126 | ||