Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/dasd: summarize dasd configuration data in a separate structure

Summarize the dasd configuration data in a separate structure so that
functions that need temporary config data do not need to allocate the
whole eckd_private structure.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Link: https://lore.kernel.org/r/20211020115124.1735254-6-sth@linux.ibm.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Stefan Haberland and committed by
Jens Axboe
542e30ce 74e2f211

+98 -97
+90 -92
drivers/s390/block/dasd_eckd.c
··· 560 560 return -EINVAL; 561 561 } 562 562 pfxdata->format = format; 563 - pfxdata->base_address = basepriv->ned->unit_addr; 564 - pfxdata->base_lss = basepriv->ned->ID; 563 + pfxdata->base_address = basepriv->conf.ned->unit_addr; 564 + pfxdata->base_lss = basepriv->conf.ned->ID; 565 565 pfxdata->validity.define_extent = 1; 566 566 567 567 /* private uid is kept up to date, conf_data may be outdated */ ··· 736 736 return LABEL_SIZE; 737 737 } 738 738 /* create unique id from private structure. */ 739 - static void create_uid(struct dasd_eckd_private *private) 739 + static void create_uid(struct dasd_conf *conf, struct dasd_uid *uid) 740 740 { 741 741 int count; 742 - struct dasd_uid *uid; 743 742 744 - uid = &private->uid; 745 743 memset(uid, 0, sizeof(struct dasd_uid)); 746 - memcpy(uid->vendor, private->ned->HDA_manufacturer, 744 + memcpy(uid->vendor, conf->ned->HDA_manufacturer, 747 745 sizeof(uid->vendor) - 1); 748 746 EBCASC(uid->vendor, sizeof(uid->vendor) - 1); 749 - memcpy(uid->serial, &private->ned->serial, 747 + memcpy(uid->serial, &conf->ned->serial, 750 748 sizeof(uid->serial) - 1); 751 749 EBCASC(uid->serial, sizeof(uid->serial) - 1); 752 - uid->ssid = private->gneq->subsystemID; 753 - uid->real_unit_addr = private->ned->unit_addr; 754 - if (private->sneq) { 755 - uid->type = private->sneq->sua_flags; 750 + uid->ssid = conf->gneq->subsystemID; 751 + uid->real_unit_addr = conf->ned->unit_addr; 752 + if (conf->sneq) { 753 + uid->type = conf->sneq->sua_flags; 756 754 if (uid->type == UA_BASE_PAV_ALIAS) 757 - uid->base_unit_addr = private->sneq->base_unit_addr; 755 + uid->base_unit_addr = conf->sneq->base_unit_addr; 758 756 } else { 759 757 uid->type = UA_BASE_DEVICE; 760 758 } 761 - if (private->vdsneq) { 759 + if (conf->vdsneq) { 762 760 for (count = 0; count < 16; count++) { 763 761 sprintf(uid->vduit+2*count, "%02x", 764 - private->vdsneq->uit[count]); 762 + conf->vdsneq->uit[count]); 765 763 } 766 764 } 767 765 } ··· 774 776 775 777 if (!private) 776 778 return -ENODEV; 777 - if (!private->ned || !private->gneq) 779 + if (!private->conf.ned || !private->conf.gneq) 778 780 return -ENODEV; 779 781 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 780 - create_uid(private); 782 + create_uid(&private->conf, &private->uid); 781 783 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); 782 784 return 0; 783 785 } ··· 801 803 * return 0 for match 802 804 */ 803 805 static int dasd_eckd_compare_path_uid(struct dasd_device *device, 804 - struct dasd_eckd_private *private) 806 + struct dasd_conf *path_conf) 805 807 { 806 808 struct dasd_uid device_uid; 809 + struct dasd_uid path_uid; 807 810 808 - create_uid(private); 811 + create_uid(path_conf, &path_uid); 809 812 dasd_eckd_get_uid(device, &device_uid); 810 813 811 - return memcmp(&device_uid, &private->uid, sizeof(struct dasd_uid)); 814 + return memcmp(&device_uid, &path_uid, sizeof(struct dasd_uid)); 812 815 } 813 816 814 817 static void dasd_eckd_fill_rcd_cqr(struct dasd_device *device, ··· 945 946 return ret; 946 947 } 947 948 948 - static int dasd_eckd_identify_conf_parts(struct dasd_eckd_private *private) 949 + static int dasd_eckd_identify_conf_parts(struct dasd_conf *conf) 949 950 { 950 951 951 952 struct dasd_sneq *sneq; 952 953 int i, count; 953 954 954 - private->ned = NULL; 955 - private->sneq = NULL; 956 - private->vdsneq = NULL; 957 - private->gneq = NULL; 958 - count = private->conf_len / sizeof(struct dasd_sneq); 959 - sneq = (struct dasd_sneq *)private->conf_data; 955 + conf->ned = NULL; 956 + conf->sneq = NULL; 957 + conf->vdsneq = NULL; 958 + conf->gneq = NULL; 959 + count = conf->len / sizeof(struct dasd_sneq); 960 + sneq = (struct dasd_sneq *)conf->data; 960 961 for (i = 0; i < count; ++i) { 961 962 if (sneq->flags.identifier == 1 && sneq->format == 1) 962 - private->sneq = sneq; 963 + conf->sneq = sneq; 963 964 else if (sneq->flags.identifier == 1 && sneq->format == 4) 964 - private->vdsneq = (struct vd_sneq *)sneq; 965 + conf->vdsneq = (struct vd_sneq *)sneq; 965 966 else if (sneq->flags.identifier == 2) 966 - private->gneq = (struct dasd_gneq *)sneq; 967 + conf->gneq = (struct dasd_gneq *)sneq; 967 968 else if (sneq->flags.identifier == 3 && sneq->res1 == 1) 968 - private->ned = (struct dasd_ned *)sneq; 969 + conf->ned = (struct dasd_ned *)sneq; 969 970 sneq++; 970 971 } 971 - if (!private->ned || !private->gneq) { 972 - private->ned = NULL; 973 - private->sneq = NULL; 974 - private->vdsneq = NULL; 975 - private->gneq = NULL; 972 + if (!conf->ned || !conf->gneq) { 973 + conf->ned = NULL; 974 + conf->sneq = NULL; 975 + conf->vdsneq = NULL; 976 + conf->gneq = NULL; 976 977 return -EINVAL; 977 978 } 978 979 return 0; ··· 1015 1016 * with the new one if this points to the same data 1016 1017 */ 1017 1018 cdp = device->path[chp].conf_data; 1018 - if (private->conf_data == cdp) { 1019 - private->conf_data = (void *)conf_data; 1020 - dasd_eckd_identify_conf_parts(private); 1019 + if (private->conf.data == cdp) { 1020 + private->conf.data = (void *)conf_data; 1021 + dasd_eckd_identify_conf_parts(&private->conf); 1021 1022 } 1022 1023 ccw_device_get_schid(device->cdev, &sch_id); 1023 1024 device->path[chp].conf_data = conf_data; ··· 1035 1036 struct dasd_eckd_private *private = device->private; 1036 1037 int i; 1037 1038 1038 - private->conf_data = NULL; 1039 - private->conf_len = 0; 1039 + private->conf.data = NULL; 1040 + private->conf.len = 0; 1040 1041 for (i = 0; i < 8; i++) { 1041 1042 kfree(device->path[i].conf_data); 1042 1043 device->path[i].conf_data = NULL; ··· 1070 1071 } 1071 1072 } 1072 1073 1073 - static void dasd_eckd_get_uid_string(struct dasd_eckd_private *private, 1074 + static void dasd_eckd_get_uid_string(struct dasd_conf *conf, 1074 1075 char *print_uid) 1075 1076 { 1076 - struct dasd_uid *uid; 1077 + struct dasd_uid uid; 1077 1078 1078 - uid = &private->uid; 1079 - if (strlen(uid->vduit) > 0) 1079 + create_uid(conf, &uid); 1080 + if (strlen(uid.vduit) > 0) 1080 1081 snprintf(print_uid, sizeof(*print_uid), 1081 1082 "%s.%s.%04x.%02x.%s", 1082 - uid->vendor, uid->serial, uid->ssid, 1083 - uid->real_unit_addr, uid->vduit); 1083 + uid.vendor, uid.serial, uid.ssid, 1084 + uid.real_unit_addr, uid.vduit); 1084 1085 else 1085 1086 snprintf(print_uid, sizeof(*print_uid), 1086 1087 "%s.%s.%04x.%02x", 1087 - uid->vendor, uid->serial, uid->ssid, 1088 - uid->real_unit_addr); 1088 + uid.vendor, uid.serial, uid.ssid, 1089 + uid.real_unit_addr); 1089 1090 } 1090 1091 1091 1092 static int dasd_eckd_check_cabling(struct dasd_device *device, ··· 1093 1094 { 1094 1095 struct dasd_eckd_private *private = device->private; 1095 1096 char print_path_uid[60], print_device_uid[60]; 1096 - struct dasd_eckd_private path_private; 1097 + struct dasd_conf path_conf; 1097 1098 1098 - path_private.conf_data = conf_data; 1099 - path_private.conf_len = DASD_ECKD_RCD_DATA_SIZE; 1100 - if (dasd_eckd_identify_conf_parts(&path_private)) 1099 + path_conf.data = conf_data; 1100 + path_conf.len = DASD_ECKD_RCD_DATA_SIZE; 1101 + if (dasd_eckd_identify_conf_parts(&path_conf)) 1101 1102 return 1; 1102 1103 1103 - if (dasd_eckd_compare_path_uid(device, &path_private)) { 1104 - dasd_eckd_get_uid_string(&path_private, print_path_uid); 1105 - dasd_eckd_get_uid_string(private, print_device_uid); 1104 + if (dasd_eckd_compare_path_uid(device, &path_conf)) { 1105 + dasd_eckd_get_uid_string(&path_conf, print_path_uid); 1106 + dasd_eckd_get_uid_string(&private->conf, print_device_uid); 1106 1107 dev_err(&device->cdev->dev, 1107 1108 "Not all channel paths lead to the same device, path %02X leads to device %s instead of %s\n", 1108 1109 lpm, print_path_uid, print_device_uid); ··· 1148 1149 if (!conf_data_saved) { 1149 1150 /* initially clear previously stored conf_data */ 1150 1151 dasd_eckd_clear_conf_data(device); 1151 - private->conf_data = conf_data; 1152 - private->conf_len = conf_len; 1153 - if (dasd_eckd_identify_conf_parts(private)) { 1154 - private->conf_data = NULL; 1155 - private->conf_len = 0; 1152 + private->conf.data = conf_data; 1153 + private->conf.len = conf_len; 1154 + if (dasd_eckd_identify_conf_parts(&private->conf)) { 1155 + private->conf.data = NULL; 1156 + private->conf.len = 0; 1156 1157 kfree(conf_data); 1157 1158 continue; 1158 1159 } ··· 1202 1203 return 0; 1203 1204 /* is transport mode supported? */ 1204 1205 fcx_in_css = css_general_characteristics.fcx; 1205 - fcx_in_gneq = private->gneq->reserved2[7] & 0x04; 1206 + fcx_in_gneq = private->conf.gneq->reserved2[7] & 0x04; 1206 1207 fcx_in_features = private->features.feature[40] & 0x80; 1207 1208 tpm = fcx_in_css && fcx_in_gneq && fcx_in_features; 1208 1209 ··· 1271 1272 "returned error %d", rc); 1272 1273 break; 1273 1274 } 1274 - memcpy(private->conf_data, data->rcd_buffer, 1275 + memcpy(private->conf.data, data->rcd_buffer, 1275 1276 DASD_ECKD_RCD_DATA_SIZE); 1276 - if (dasd_eckd_identify_conf_parts(private)) { 1277 + if (dasd_eckd_identify_conf_parts(&private->conf)) { 1277 1278 rc = -ENODEV; 1278 1279 } else /* first valid path is enough */ 1279 1280 break; ··· 1288 1289 static void dasd_eckd_path_available_action(struct dasd_device *device, 1289 1290 struct pe_handler_work_data *data) 1290 1291 { 1291 - struct dasd_eckd_private path_private; 1292 1292 __u8 path_rcd_buf[DASD_ECKD_RCD_DATA_SIZE]; 1293 1293 __u8 lpm, opm, npm, ppm, epm, hpfpm, cablepm; 1294 1294 struct dasd_conf_data *conf_data; 1295 + struct dasd_conf path_conf; 1295 1296 unsigned long flags; 1296 1297 char print_uid[60]; 1297 1298 int rc, pos; ··· 1355 1356 */ 1356 1357 memcpy(&path_rcd_buf, data->rcd_buffer, 1357 1358 DASD_ECKD_RCD_DATA_SIZE); 1358 - path_private.conf_data = (void *) &path_rcd_buf; 1359 - path_private.conf_len = DASD_ECKD_RCD_DATA_SIZE; 1360 - if (dasd_eckd_identify_conf_parts(&path_private)) { 1361 - path_private.conf_data = NULL; 1362 - path_private.conf_len = 0; 1359 + path_conf.data = (void *)&path_rcd_buf; 1360 + path_conf.len = DASD_ECKD_RCD_DATA_SIZE; 1361 + if (dasd_eckd_identify_conf_parts(&path_conf)) { 1362 + path_conf.data = NULL; 1363 + path_conf.len = 0; 1363 1364 continue; 1364 1365 } 1365 1366 ··· 1370 1371 * the first working path UID will be used as device UID 1371 1372 */ 1372 1373 if (dasd_path_get_opm(device) && 1373 - dasd_eckd_compare_path_uid(device, &path_private)) { 1374 + dasd_eckd_compare_path_uid(device, &path_conf)) { 1374 1375 /* 1375 1376 * the comparison was not successful 1376 1377 * rebuild the device UID with at least one ··· 1384 1385 */ 1385 1386 if (rebuild_device_uid(device, data) || 1386 1387 dasd_eckd_compare_path_uid( 1387 - device, &path_private)) { 1388 - dasd_eckd_get_uid_string(&path_private, 1389 - print_uid); 1388 + device, &path_conf)) { 1389 + dasd_eckd_get_uid_string(&path_conf, print_uid); 1390 1390 dev_err(&device->cdev->dev, 1391 1391 "The newly added channel path %02X " 1392 1392 "will not be used because it leads " ··· 1601 1603 prssdp = cqr->data; 1602 1604 prssdp->order = PSF_ORDER_PRSSD; 1603 1605 prssdp->suborder = PSF_SUBORDER_VSQ; /* Volume Storage Query */ 1604 - prssdp->lss = private->ned->ID; 1605 - prssdp->volume = private->ned->unit_addr; 1606 + prssdp->lss = private->conf.ned->ID; 1607 + prssdp->volume = private->conf.ned->unit_addr; 1606 1608 1607 1609 ccw = cqr->cpaddr; 1608 1610 ccw->cmd_code = DASD_ECKD_CCW_PSF; ··· 2061 2063 device->path_thrhld = DASD_ECKD_PATH_THRHLD; 2062 2064 device->path_interval = DASD_ECKD_PATH_INTERVAL; 2063 2065 2064 - if (private->gneq) { 2066 + if (private->conf.gneq) { 2065 2067 value = 1; 2066 - for (i = 0; i < private->gneq->timeout.value; i++) 2068 + for (i = 0; i < private->conf.gneq->timeout.value; i++) 2067 2069 value = 10 * value; 2068 - value = value * private->gneq->timeout.number; 2070 + value = value * private->conf.gneq->timeout.number; 2069 2071 /* do not accept useless values */ 2070 2072 if (value != 0 && value <= DASD_EXPIRES_MAX) 2071 2073 device->default_expires = value; ··· 2172 2174 return; 2173 2175 2174 2176 dasd_alias_disconnect_device_from_lcu(device); 2175 - private->ned = NULL; 2176 - private->sneq = NULL; 2177 - private->vdsneq = NULL; 2178 - private->gneq = NULL; 2177 + private->conf.ned = NULL; 2178 + private->conf.sneq = NULL; 2179 + private->conf.vdsneq = NULL; 2180 + private->conf.gneq = NULL; 2179 2181 dasd_eckd_clear_conf_data(device); 2180 2182 dasd_path_remove_kobjects(device); 2181 2183 } ··· 3727 3729 * subset. 3728 3730 */ 3729 3731 ras_data->op_flags.guarantee_init = !!(features->feature[56] & 0x01); 3730 - ras_data->lss = private->ned->ID; 3731 - ras_data->dev_addr = private->ned->unit_addr; 3732 + ras_data->lss = private->conf.ned->ID; 3733 + ras_data->dev_addr = private->conf.ned->unit_addr; 3732 3734 ras_data->nr_exts = nr_exts; 3733 3735 3734 3736 if (by_extent) { ··· 4270 4272 4271 4273 memset(&pfxdata, 0, sizeof(pfxdata)); 4272 4274 pfxdata.format = 1; /* PFX with LRE */ 4273 - pfxdata.base_address = basepriv->ned->unit_addr; 4274 - pfxdata.base_lss = basepriv->ned->ID; 4275 + pfxdata.base_address = basepriv->conf.ned->unit_addr; 4276 + pfxdata.base_lss = basepriv->conf.ned->ID; 4275 4277 pfxdata.validity.define_extent = 1; 4276 4278 4277 4279 /* private uid is kept up to date, conf_data may be outdated */ ··· 4940 4942 info->characteristics_size = sizeof(private->rdc_data); 4941 4943 memcpy(info->characteristics, &private->rdc_data, 4942 4944 sizeof(private->rdc_data)); 4943 - info->confdata_size = min((unsigned long)private->conf_len, 4944 - sizeof(info->configuration_data)); 4945 - memcpy(info->configuration_data, private->conf_data, 4945 + info->confdata_size = min_t(unsigned long, private->conf.len, 4946 + sizeof(info->configuration_data)); 4947 + memcpy(info->configuration_data, private->conf.data, 4946 4948 info->confdata_size); 4947 4949 return 0; 4948 4950 } ··· 5799 5801 dasd_eckd_get_uid(device, &uid); 5800 5802 5801 5803 if (old_base != uid.base_unit_addr) { 5802 - dasd_eckd_get_uid_string(private, print_uid); 5804 + dasd_eckd_get_uid_string(&private->conf, print_uid); 5803 5805 dev_info(&device->cdev->dev, 5804 5806 "An Alias device was reassigned to a new base device " 5805 5807 "with UID: %s\n", print_uid); ··· 5937 5939 prssdp->order = PSF_ORDER_PRSSD; 5938 5940 prssdp->suborder = PSF_SUBORDER_QHA; /* query host access */ 5939 5941 /* LSS and Volume that will be queried */ 5940 - prssdp->lss = private->ned->ID; 5941 - prssdp->volume = private->ned->unit_addr; 5942 + prssdp->lss = private->conf.ned->ID; 5943 + prssdp->volume = private->conf.ned->unit_addr; 5942 5944 /* all other bytes of prssdp must be zero */ 5943 5945 5944 5946 ccw = cqr->cpaddr;
+8 -5
drivers/s390/block/dasd_eckd.h
··· 658 658 struct dasd_gneq gneq; 659 659 } __packed; 660 660 661 - struct dasd_eckd_private { 662 - struct dasd_eckd_characteristics rdc_data; 663 - u8 *conf_data; 664 - int conf_len; 665 - 661 + struct dasd_conf { 662 + u8 *data; 663 + int len; 666 664 /* pointers to specific parts in the conf_data */ 667 665 struct dasd_ned *ned; 668 666 struct dasd_sneq *sneq; 669 667 struct vd_sneq *vdsneq; 670 668 struct dasd_gneq *gneq; 669 + }; 670 + 671 + struct dasd_eckd_private { 672 + struct dasd_eckd_characteristics rdc_data; 673 + struct dasd_conf conf; 671 674 672 675 struct eckd_count count_area[5]; 673 676 int init_cqr_status;