diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-09 11:11:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-09 11:11:13 -0500 |
commit | 72f318897e50c29b91efd1ed24515a93c138a2ba (patch) | |
tree | 7e7ef8138d5afacd1be4655e4458dc4cee432d1e /drivers | |
parent | a0e86bd4252519321b0d102dc4ed90557aa7bee9 (diff) | |
parent | 2fa1d4fce599809e6bd7d95756709a5faef30710 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (31 commits)
[S390] disassembler: mark exception causing instructions
[S390] Enable exception traces by default
[S390] return address of compat signals
[S390] sysctl: get rid of dead declaration
[S390] dasd: fix fixpoint divide exception in define_extent
[S390] dasd: add sanity check to detect path connection error
[S390] qdio: fix kernel panic for zfcp 31-bit
[S390] Add s390x description to Documentation/kdump/kdump.txt
[S390] Add VMCOREINFO_SYMBOL(high_memory) to vmcoreinfo
[S390] dasd: fix expiration handling for recovery requests
[S390] outstanding interrupts vs. smp_send_stop
[S390] ipc: call generic sys_ipc demultiplexer
[S390] zcrypt: Fix error return codes.
[S390] zcrypt: Rework length parameter checking.
[S390] cleanup trap handling
[S390] Remove Kerntypes leftovers
[S390] topology: increase poll frequency if change is anticipated
[S390] entry[64].S improvements
[S390] make arch/s390 subdirectories depend on config option
[S390] kvm: move cmf host id constant out of lowcore
...
Fix up conflicts in arch/s390/kernel/{smp.c,topology.c} due to the
sysdev removal clashing with "topology: get rid of ifdefs" which moved
some of that code around.
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/s390/block/dasd_3990_erp.c | 4 | ||||
-rw-r--r-- | drivers/s390/block/dasd_alias.c | 10 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 411 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_setup.c | 10 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_pcixcc.c | 32 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 2 |
6 files changed, 328 insertions, 141 deletions
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index 87a0cf160fe5..0326571e7ffa 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c | |||
@@ -1718,7 +1718,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense) | |||
1718 | erp->startdev = device; | 1718 | erp->startdev = device; |
1719 | erp->memdev = device; | 1719 | erp->memdev = device; |
1720 | erp->magic = default_erp->magic; | 1720 | erp->magic = default_erp->magic; |
1721 | erp->expires = 0; | 1721 | erp->expires = default_erp->expires; |
1722 | erp->retries = 256; | 1722 | erp->retries = 256; |
1723 | erp->buildclk = get_clock(); | 1723 | erp->buildclk = get_clock(); |
1724 | erp->status = DASD_CQR_FILLED; | 1724 | erp->status = DASD_CQR_FILLED; |
@@ -2363,7 +2363,7 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr) | |||
2363 | erp->memdev = device; | 2363 | erp->memdev = device; |
2364 | erp->block = cqr->block; | 2364 | erp->block = cqr->block; |
2365 | erp->magic = cqr->magic; | 2365 | erp->magic = cqr->magic; |
2366 | erp->expires = 0; | 2366 | erp->expires = cqr->expires; |
2367 | erp->retries = 256; | 2367 | erp->retries = 256; |
2368 | erp->buildclk = get_clock(); | 2368 | erp->buildclk = get_clock(); |
2369 | erp->status = DASD_CQR_FILLED; | 2369 | erp->status = DASD_CQR_FILLED; |
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c index c388eda1e2b1..553b3c5abb0a 100644 --- a/drivers/s390/block/dasd_alias.c +++ b/drivers/s390/block/dasd_alias.c | |||
@@ -705,6 +705,16 @@ struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device) | |||
705 | if (lcu->pav == NO_PAV || | 705 | if (lcu->pav == NO_PAV || |
706 | lcu->flags & (NEED_UAC_UPDATE | UPDATE_PENDING)) | 706 | lcu->flags & (NEED_UAC_UPDATE | UPDATE_PENDING)) |
707 | return NULL; | 707 | return NULL; |
708 | if (unlikely(!(private->features.feature[8] & 0x01))) { | ||
709 | /* | ||
710 | * PAV enabled but prefix not, very unlikely | ||
711 | * seems to be a lost pathgroup | ||
712 | * use base device to do IO | ||
713 | */ | ||
714 | DBF_DEV_EVENT(DBF_ERR, base_device, "%s", | ||
715 | "Prefix not enabled with PAV enabled\n"); | ||
716 | return NULL; | ||
717 | } | ||
708 | 718 | ||
709 | spin_lock_irqsave(&lcu->lock, flags); | 719 | spin_lock_irqsave(&lcu->lock, flags); |
710 | alias_device = group->next; | 720 | alias_device = group->next; |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 6ab29680586a..bbcd5e9206ee 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -752,24 +752,13 @@ dasd_eckd_cdl_reclen(int recid) | |||
752 | return sizes_trk0[recid]; | 752 | return sizes_trk0[recid]; |
753 | return LABEL_SIZE; | 753 | return LABEL_SIZE; |
754 | } | 754 | } |
755 | 755 | /* create unique id from private structure. */ | |
756 | /* | 756 | static void create_uid(struct dasd_eckd_private *private) |
757 | * Generate device unique id that specifies the physical device. | ||
758 | */ | ||
759 | static int dasd_eckd_generate_uid(struct dasd_device *device) | ||
760 | { | 757 | { |
761 | struct dasd_eckd_private *private; | ||
762 | struct dasd_uid *uid; | ||
763 | int count; | 758 | int count; |
764 | unsigned long flags; | 759 | struct dasd_uid *uid; |
765 | 760 | ||
766 | private = (struct dasd_eckd_private *) device->private; | ||
767 | if (!private) | ||
768 | return -ENODEV; | ||
769 | if (!private->ned || !private->gneq) | ||
770 | return -ENODEV; | ||
771 | uid = &private->uid; | 761 | uid = &private->uid; |
772 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
773 | memset(uid, 0, sizeof(struct dasd_uid)); | 762 | memset(uid, 0, sizeof(struct dasd_uid)); |
774 | memcpy(uid->vendor, private->ned->HDA_manufacturer, | 763 | memcpy(uid->vendor, private->ned->HDA_manufacturer, |
775 | sizeof(uid->vendor) - 1); | 764 | sizeof(uid->vendor) - 1); |
@@ -792,6 +781,23 @@ static int dasd_eckd_generate_uid(struct dasd_device *device) | |||
792 | private->vdsneq->uit[count]); | 781 | private->vdsneq->uit[count]); |
793 | } | 782 | } |
794 | } | 783 | } |
784 | } | ||
785 | |||
786 | /* | ||
787 | * Generate device unique id that specifies the physical device. | ||
788 | */ | ||
789 | static int dasd_eckd_generate_uid(struct dasd_device *device) | ||
790 | { | ||
791 | struct dasd_eckd_private *private; | ||
792 | unsigned long flags; | ||
793 | |||
794 | private = (struct dasd_eckd_private *) device->private; | ||
795 | if (!private) | ||
796 | return -ENODEV; | ||
797 | if (!private->ned || !private->gneq) | ||
798 | return -ENODEV; | ||
799 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
800 | create_uid(private); | ||
795 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | 801 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); |
796 | return 0; | 802 | return 0; |
797 | } | 803 | } |
@@ -811,6 +817,21 @@ static int dasd_eckd_get_uid(struct dasd_device *device, struct dasd_uid *uid) | |||
811 | return -EINVAL; | 817 | return -EINVAL; |
812 | } | 818 | } |
813 | 819 | ||
820 | /* | ||
821 | * compare device UID with data of a given dasd_eckd_private structure | ||
822 | * return 0 for match | ||
823 | */ | ||
824 | static int dasd_eckd_compare_path_uid(struct dasd_device *device, | ||
825 | struct dasd_eckd_private *private) | ||
826 | { | ||
827 | struct dasd_uid device_uid; | ||
828 | |||
829 | create_uid(private); | ||
830 | dasd_eckd_get_uid(device, &device_uid); | ||
831 | |||
832 | return memcmp(&device_uid, &private->uid, sizeof(struct dasd_uid)); | ||
833 | } | ||
834 | |||
814 | static void dasd_eckd_fill_rcd_cqr(struct dasd_device *device, | 835 | static void dasd_eckd_fill_rcd_cqr(struct dasd_device *device, |
815 | struct dasd_ccw_req *cqr, | 836 | struct dasd_ccw_req *cqr, |
816 | __u8 *rcd_buffer, | 837 | __u8 *rcd_buffer, |
@@ -1005,59 +1026,120 @@ static int dasd_eckd_read_conf(struct dasd_device *device) | |||
1005 | int conf_len, conf_data_saved; | 1026 | int conf_len, conf_data_saved; |
1006 | int rc; | 1027 | int rc; |
1007 | __u8 lpm, opm; | 1028 | __u8 lpm, opm; |
1008 | struct dasd_eckd_private *private; | 1029 | struct dasd_eckd_private *private, path_private; |
1009 | struct dasd_path *path_data; | 1030 | struct dasd_path *path_data; |
1031 | struct dasd_uid *uid; | ||
1032 | char print_path_uid[60], print_device_uid[60]; | ||
1010 | 1033 | ||
1011 | private = (struct dasd_eckd_private *) device->private; | 1034 | private = (struct dasd_eckd_private *) device->private; |
1012 | path_data = &device->path_data; | 1035 | path_data = &device->path_data; |
1013 | opm = ccw_device_get_path_mask(device->cdev); | 1036 | opm = ccw_device_get_path_mask(device->cdev); |
1014 | lpm = 0x80; | ||
1015 | conf_data_saved = 0; | 1037 | conf_data_saved = 0; |
1016 | /* get configuration data per operational path */ | 1038 | /* get configuration data per operational path */ |
1017 | for (lpm = 0x80; lpm; lpm>>= 1) { | 1039 | for (lpm = 0x80; lpm; lpm>>= 1) { |
1018 | if (lpm & opm) { | 1040 | if (!(lpm & opm)) |
1019 | rc = dasd_eckd_read_conf_lpm(device, &conf_data, | 1041 | continue; |
1020 | &conf_len, lpm); | 1042 | rc = dasd_eckd_read_conf_lpm(device, &conf_data, |
1021 | if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */ | 1043 | &conf_len, lpm); |
1022 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, | 1044 | if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */ |
1023 | "Read configuration data returned " | 1045 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, |
1024 | "error %d", rc); | 1046 | "Read configuration data returned " |
1025 | return rc; | 1047 | "error %d", rc); |
1026 | } | 1048 | return rc; |
1027 | if (conf_data == NULL) { | 1049 | } |
1028 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", | 1050 | if (conf_data == NULL) { |
1029 | "No configuration data " | 1051 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", |
1030 | "retrieved"); | 1052 | "No configuration data " |
1031 | /* no further analysis possible */ | 1053 | "retrieved"); |
1032 | path_data->opm |= lpm; | 1054 | /* no further analysis possible */ |
1033 | continue; /* no error */ | 1055 | path_data->opm |= lpm; |
1056 | continue; /* no error */ | ||
1057 | } | ||
1058 | /* save first valid configuration data */ | ||
1059 | if (!conf_data_saved) { | ||
1060 | kfree(private->conf_data); | ||
1061 | private->conf_data = conf_data; | ||
1062 | private->conf_len = conf_len; | ||
1063 | if (dasd_eckd_identify_conf_parts(private)) { | ||
1064 | private->conf_data = NULL; | ||
1065 | private->conf_len = 0; | ||
1066 | kfree(conf_data); | ||
1067 | continue; | ||
1034 | } | 1068 | } |
1035 | /* save first valid configuration data */ | 1069 | /* |
1036 | if (!conf_data_saved) { | 1070 | * build device UID that other path data |
1037 | kfree(private->conf_data); | 1071 | * can be compared to it |
1038 | private->conf_data = conf_data; | 1072 | */ |
1039 | private->conf_len = conf_len; | 1073 | dasd_eckd_generate_uid(device); |
1040 | if (dasd_eckd_identify_conf_parts(private)) { | 1074 | conf_data_saved++; |
1041 | private->conf_data = NULL; | 1075 | } else { |
1042 | private->conf_len = 0; | 1076 | path_private.conf_data = conf_data; |
1043 | kfree(conf_data); | 1077 | path_private.conf_len = DASD_ECKD_RCD_DATA_SIZE; |
1044 | continue; | 1078 | if (dasd_eckd_identify_conf_parts( |
1045 | } | 1079 | &path_private)) { |
1046 | conf_data_saved++; | 1080 | path_private.conf_data = NULL; |
1081 | path_private.conf_len = 0; | ||
1082 | kfree(conf_data); | ||
1083 | continue; | ||
1047 | } | 1084 | } |
1048 | switch (dasd_eckd_path_access(conf_data, conf_len)) { | 1085 | |
1049 | case 0x02: | 1086 | if (dasd_eckd_compare_path_uid( |
1050 | path_data->npm |= lpm; | 1087 | device, &path_private)) { |
1051 | break; | 1088 | uid = &path_private.uid; |
1052 | case 0x03: | 1089 | if (strlen(uid->vduit) > 0) |
1053 | path_data->ppm |= lpm; | 1090 | snprintf(print_path_uid, |
1054 | break; | 1091 | sizeof(print_path_uid), |
1092 | "%s.%s.%04x.%02x.%s", | ||
1093 | uid->vendor, uid->serial, | ||
1094 | uid->ssid, uid->real_unit_addr, | ||
1095 | uid->vduit); | ||
1096 | else | ||
1097 | snprintf(print_path_uid, | ||
1098 | sizeof(print_path_uid), | ||
1099 | "%s.%s.%04x.%02x", | ||
1100 | uid->vendor, uid->serial, | ||
1101 | uid->ssid, | ||
1102 | uid->real_unit_addr); | ||
1103 | uid = &private->uid; | ||
1104 | if (strlen(uid->vduit) > 0) | ||
1105 | snprintf(print_device_uid, | ||
1106 | sizeof(print_device_uid), | ||
1107 | "%s.%s.%04x.%02x.%s", | ||
1108 | uid->vendor, uid->serial, | ||
1109 | uid->ssid, uid->real_unit_addr, | ||
1110 | uid->vduit); | ||
1111 | else | ||
1112 | snprintf(print_device_uid, | ||
1113 | sizeof(print_device_uid), | ||
1114 | "%s.%s.%04x.%02x", | ||
1115 | uid->vendor, uid->serial, | ||
1116 | uid->ssid, | ||
1117 | uid->real_unit_addr); | ||
1118 | dev_err(&device->cdev->dev, | ||
1119 | "Not all channel paths lead to " | ||
1120 | "the same device, path %02X leads to " | ||
1121 | "device %s instead of %s\n", lpm, | ||
1122 | print_path_uid, print_device_uid); | ||
1123 | return -EINVAL; | ||
1055 | } | 1124 | } |
1056 | path_data->opm |= lpm; | 1125 | |
1057 | if (conf_data != private->conf_data) | 1126 | path_private.conf_data = NULL; |
1058 | kfree(conf_data); | 1127 | path_private.conf_len = 0; |
1059 | } | 1128 | } |
1129 | switch (dasd_eckd_path_access(conf_data, conf_len)) { | ||
1130 | case 0x02: | ||
1131 | path_data->npm |= lpm; | ||
1132 | break; | ||
1133 | case 0x03: | ||
1134 | path_data->ppm |= lpm; | ||
1135 | break; | ||
1136 | } | ||
1137 | path_data->opm |= lpm; | ||
1138 | |||
1139 | if (conf_data != private->conf_data) | ||
1140 | kfree(conf_data); | ||
1060 | } | 1141 | } |
1142 | |||
1061 | return 0; | 1143 | return 0; |
1062 | } | 1144 | } |
1063 | 1145 | ||
@@ -1090,12 +1172,61 @@ static int verify_fcx_max_data(struct dasd_device *device, __u8 lpm) | |||
1090 | return 0; | 1172 | return 0; |
1091 | } | 1173 | } |
1092 | 1174 | ||
1175 | static int rebuild_device_uid(struct dasd_device *device, | ||
1176 | struct path_verification_work_data *data) | ||
1177 | { | ||
1178 | struct dasd_eckd_private *private; | ||
1179 | struct dasd_path *path_data; | ||
1180 | __u8 lpm, opm; | ||
1181 | int rc; | ||
1182 | |||
1183 | rc = -ENODEV; | ||
1184 | private = (struct dasd_eckd_private *) device->private; | ||
1185 | path_data = &device->path_data; | ||
1186 | opm = device->path_data.opm; | ||
1187 | |||
1188 | for (lpm = 0x80; lpm; lpm >>= 1) { | ||
1189 | if (!(lpm & opm)) | ||
1190 | continue; | ||
1191 | memset(&data->rcd_buffer, 0, sizeof(data->rcd_buffer)); | ||
1192 | memset(&data->cqr, 0, sizeof(data->cqr)); | ||
1193 | data->cqr.cpaddr = &data->ccw; | ||
1194 | rc = dasd_eckd_read_conf_immediately(device, &data->cqr, | ||
1195 | data->rcd_buffer, | ||
1196 | lpm); | ||
1197 | |||
1198 | if (rc) { | ||
1199 | if (rc == -EOPNOTSUPP) /* -EOPNOTSUPP is ok */ | ||
1200 | continue; | ||
1201 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, | ||
1202 | "Read configuration data " | ||
1203 | "returned error %d", rc); | ||
1204 | break; | ||
1205 | } | ||
1206 | memcpy(private->conf_data, data->rcd_buffer, | ||
1207 | DASD_ECKD_RCD_DATA_SIZE); | ||
1208 | if (dasd_eckd_identify_conf_parts(private)) { | ||
1209 | rc = -ENODEV; | ||
1210 | } else /* first valid path is enough */ | ||
1211 | break; | ||
1212 | } | ||
1213 | |||
1214 | if (!rc) | ||
1215 | rc = dasd_eckd_generate_uid(device); | ||
1216 | |||
1217 | return rc; | ||
1218 | } | ||
1219 | |||
1093 | static void do_path_verification_work(struct work_struct *work) | 1220 | static void do_path_verification_work(struct work_struct *work) |
1094 | { | 1221 | { |
1095 | struct path_verification_work_data *data; | 1222 | struct path_verification_work_data *data; |
1096 | struct dasd_device *device; | 1223 | struct dasd_device *device; |
1224 | struct dasd_eckd_private path_private; | ||
1225 | struct dasd_uid *uid; | ||
1226 | __u8 path_rcd_buf[DASD_ECKD_RCD_DATA_SIZE]; | ||
1097 | __u8 lpm, opm, npm, ppm, epm; | 1227 | __u8 lpm, opm, npm, ppm, epm; |
1098 | unsigned long flags; | 1228 | unsigned long flags; |
1229 | char print_uid[60]; | ||
1099 | int rc; | 1230 | int rc; |
1100 | 1231 | ||
1101 | data = container_of(work, struct path_verification_work_data, worker); | 1232 | data = container_of(work, struct path_verification_work_data, worker); |
@@ -1112,64 +1243,129 @@ static void do_path_verification_work(struct work_struct *work) | |||
1112 | ppm = 0; | 1243 | ppm = 0; |
1113 | epm = 0; | 1244 | epm = 0; |
1114 | for (lpm = 0x80; lpm; lpm >>= 1) { | 1245 | for (lpm = 0x80; lpm; lpm >>= 1) { |
1115 | if (lpm & data->tbvpm) { | 1246 | if (!(lpm & data->tbvpm)) |
1116 | memset(data->rcd_buffer, 0, sizeof(data->rcd_buffer)); | 1247 | continue; |
1117 | memset(&data->cqr, 0, sizeof(data->cqr)); | 1248 | memset(&data->rcd_buffer, 0, sizeof(data->rcd_buffer)); |
1118 | data->cqr.cpaddr = &data->ccw; | 1249 | memset(&data->cqr, 0, sizeof(data->cqr)); |
1119 | rc = dasd_eckd_read_conf_immediately(device, &data->cqr, | 1250 | data->cqr.cpaddr = &data->ccw; |
1120 | data->rcd_buffer, | 1251 | rc = dasd_eckd_read_conf_immediately(device, &data->cqr, |
1121 | lpm); | 1252 | data->rcd_buffer, |
1122 | if (!rc) { | 1253 | lpm); |
1123 | switch (dasd_eckd_path_access(data->rcd_buffer, | 1254 | if (!rc) { |
1124 | DASD_ECKD_RCD_DATA_SIZE)) { | 1255 | switch (dasd_eckd_path_access(data->rcd_buffer, |
1125 | case 0x02: | 1256 | DASD_ECKD_RCD_DATA_SIZE) |
1126 | npm |= lpm; | 1257 | ) { |
1127 | break; | 1258 | case 0x02: |
1128 | case 0x03: | 1259 | npm |= lpm; |
1129 | ppm |= lpm; | 1260 | break; |
1130 | break; | 1261 | case 0x03: |
1131 | } | 1262 | ppm |= lpm; |
1132 | opm |= lpm; | 1263 | break; |
1133 | } else if (rc == -EOPNOTSUPP) { | 1264 | } |
1134 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", | 1265 | opm |= lpm; |
1135 | "path verification: No configuration " | 1266 | } else if (rc == -EOPNOTSUPP) { |
1136 | "data retrieved"); | 1267 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", |
1137 | opm |= lpm; | 1268 | "path verification: No configuration " |
1138 | } else if (rc == -EAGAIN) { | 1269 | "data retrieved"); |
1139 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", | 1270 | opm |= lpm; |
1271 | } else if (rc == -EAGAIN) { | ||
1272 | DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", | ||
1140 | "path verification: device is stopped," | 1273 | "path verification: device is stopped," |
1141 | " try again later"); | 1274 | " try again later"); |
1142 | epm |= lpm; | 1275 | epm |= lpm; |
1143 | } else { | 1276 | } else { |
1144 | dev_warn(&device->cdev->dev, | 1277 | dev_warn(&device->cdev->dev, |
1145 | "Reading device feature codes failed " | 1278 | "Reading device feature codes failed " |
1146 | "(rc=%d) for new path %x\n", rc, lpm); | 1279 | "(rc=%d) for new path %x\n", rc, lpm); |
1147 | continue; | 1280 | continue; |
1148 | } | 1281 | } |
1149 | if (verify_fcx_max_data(device, lpm)) { | 1282 | if (verify_fcx_max_data(device, lpm)) { |
1283 | opm &= ~lpm; | ||
1284 | npm &= ~lpm; | ||
1285 | ppm &= ~lpm; | ||
1286 | continue; | ||
1287 | } | ||
1288 | |||
1289 | /* | ||
1290 | * save conf_data for comparison after | ||
1291 | * rebuild_device_uid may have changed | ||
1292 | * the original data | ||
1293 | */ | ||
1294 | memcpy(&path_rcd_buf, data->rcd_buffer, | ||
1295 | DASD_ECKD_RCD_DATA_SIZE); | ||
1296 | path_private.conf_data = (void *) &path_rcd_buf; | ||
1297 | path_private.conf_len = DASD_ECKD_RCD_DATA_SIZE; | ||
1298 | if (dasd_eckd_identify_conf_parts(&path_private)) { | ||
1299 | path_private.conf_data = NULL; | ||
1300 | path_private.conf_len = 0; | ||
1301 | continue; | ||
1302 | } | ||
1303 | |||
1304 | /* | ||
1305 | * compare path UID with device UID only if at least | ||
1306 | * one valid path is left | ||
1307 | * in other case the device UID may have changed and | ||
1308 | * the first working path UID will be used as device UID | ||
1309 | */ | ||
1310 | if (device->path_data.opm && | ||
1311 | dasd_eckd_compare_path_uid(device, &path_private)) { | ||
1312 | /* | ||
1313 | * the comparison was not successful | ||
1314 | * rebuild the device UID with at least one | ||
1315 | * known path in case a z/VM hyperswap command | ||
1316 | * has changed the device | ||
1317 | * | ||
1318 | * after this compare again | ||
1319 | * | ||
1320 | * if either the rebuild or the recompare fails | ||
1321 | * the path can not be used | ||
1322 | */ | ||
1323 | if (rebuild_device_uid(device, data) || | ||
1324 | dasd_eckd_compare_path_uid( | ||
1325 | device, &path_private)) { | ||
1326 | uid = &path_private.uid; | ||
1327 | if (strlen(uid->vduit) > 0) | ||
1328 | snprintf(print_uid, sizeof(print_uid), | ||
1329 | "%s.%s.%04x.%02x.%s", | ||
1330 | uid->vendor, uid->serial, | ||
1331 | uid->ssid, uid->real_unit_addr, | ||
1332 | uid->vduit); | ||
1333 | else | ||
1334 | snprintf(print_uid, sizeof(print_uid), | ||
1335 | "%s.%s.%04x.%02x", | ||
1336 | uid->vendor, uid->serial, | ||
1337 | uid->ssid, | ||
1338 | uid->real_unit_addr); | ||
1339 | dev_err(&device->cdev->dev, | ||
1340 | "The newly added channel path %02X " | ||
1341 | "will not be used because it leads " | ||
1342 | "to a different device %s\n", | ||
1343 | lpm, print_uid); | ||
1150 | opm &= ~lpm; | 1344 | opm &= ~lpm; |
1151 | npm &= ~lpm; | 1345 | npm &= ~lpm; |
1152 | ppm &= ~lpm; | 1346 | ppm &= ~lpm; |
1347 | continue; | ||
1153 | } | 1348 | } |
1154 | } | 1349 | } |
1350 | |||
1351 | /* | ||
1352 | * There is a small chance that a path is lost again between | ||
1353 | * above path verification and the following modification of | ||
1354 | * the device opm mask. We could avoid that race here by using | ||
1355 | * yet another path mask, but we rather deal with this unlikely | ||
1356 | * situation in dasd_start_IO. | ||
1357 | */ | ||
1358 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
1359 | if (!device->path_data.opm && opm) { | ||
1360 | device->path_data.opm = opm; | ||
1361 | dasd_generic_path_operational(device); | ||
1362 | } else | ||
1363 | device->path_data.opm |= opm; | ||
1364 | device->path_data.npm |= npm; | ||
1365 | device->path_data.ppm |= ppm; | ||
1366 | device->path_data.tbvpm |= epm; | ||
1367 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
1155 | } | 1368 | } |
1156 | /* | ||
1157 | * There is a small chance that a path is lost again between | ||
1158 | * above path verification and the following modification of | ||
1159 | * the device opm mask. We could avoid that race here by using | ||
1160 | * yet another path mask, but we rather deal with this unlikely | ||
1161 | * situation in dasd_start_IO. | ||
1162 | */ | ||
1163 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); | ||
1164 | if (!device->path_data.opm && opm) { | ||
1165 | device->path_data.opm = opm; | ||
1166 | dasd_generic_path_operational(device); | ||
1167 | } else | ||
1168 | device->path_data.opm |= opm; | ||
1169 | device->path_data.npm |= npm; | ||
1170 | device->path_data.ppm |= ppm; | ||
1171 | device->path_data.tbvpm |= epm; | ||
1172 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
1173 | 1369 | ||
1174 | dasd_put_device(device); | 1370 | dasd_put_device(device); |
1175 | if (data->isglobal) | 1371 | if (data->isglobal) |
@@ -1441,11 +1637,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
1441 | device->default_expires = value; | 1637 | device->default_expires = value; |
1442 | } | 1638 | } |
1443 | 1639 | ||
1444 | /* Generate device unique id */ | ||
1445 | rc = dasd_eckd_generate_uid(device); | ||
1446 | if (rc) | ||
1447 | goto out_err1; | ||
1448 | |||
1449 | dasd_eckd_get_uid(device, &temp_uid); | 1640 | dasd_eckd_get_uid(device, &temp_uid); |
1450 | if (temp_uid.type == UA_BASE_DEVICE) { | 1641 | if (temp_uid.type == UA_BASE_DEVICE) { |
1451 | block = dasd_alloc_block(); | 1642 | block = dasd_alloc_block(); |
@@ -2206,7 +2397,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single( | |||
2206 | sizeof(struct PFX_eckd_data)); | 2397 | sizeof(struct PFX_eckd_data)); |
2207 | } else { | 2398 | } else { |
2208 | if (define_extent(ccw++, cqr->data, first_trk, | 2399 | if (define_extent(ccw++, cqr->data, first_trk, |
2209 | last_trk, cmd, startdev) == -EAGAIN) { | 2400 | last_trk, cmd, basedev) == -EAGAIN) { |
2210 | /* Clock not in sync and XRC is enabled. | 2401 | /* Clock not in sync and XRC is enabled. |
2211 | * Try again later. | 2402 | * Try again later. |
2212 | */ | 2403 | */ |
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index 2acc01f90a6a..452989a7ec13 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c | |||
@@ -22,12 +22,9 @@ | |||
22 | static struct kmem_cache *qdio_q_cache; | 22 | static struct kmem_cache *qdio_q_cache; |
23 | static struct kmem_cache *qdio_aob_cache; | 23 | static struct kmem_cache *qdio_aob_cache; |
24 | 24 | ||
25 | struct qaob *qdio_allocate_aob() | 25 | struct qaob *qdio_allocate_aob(void) |
26 | { | 26 | { |
27 | struct qaob *aob; | 27 | return kmem_cache_zalloc(qdio_aob_cache, GFP_ATOMIC); |
28 | |||
29 | aob = kmem_cache_zalloc(qdio_aob_cache, GFP_ATOMIC); | ||
30 | return aob; | ||
31 | } | 28 | } |
32 | EXPORT_SYMBOL_GPL(qdio_allocate_aob); | 29 | EXPORT_SYMBOL_GPL(qdio_allocate_aob); |
33 | 30 | ||
@@ -180,7 +177,8 @@ static void setup_queues(struct qdio_irq *irq_ptr, | |||
180 | setup_queues_misc(q, irq_ptr, qdio_init->input_handler, i); | 177 | setup_queues_misc(q, irq_ptr, qdio_init->input_handler, i); |
181 | 178 | ||
182 | q->is_input_q = 1; | 179 | q->is_input_q = 1; |
183 | q->u.in.queue_start_poll = qdio_init->queue_start_poll[i]; | 180 | q->u.in.queue_start_poll = qdio_init->queue_start_poll_array ? |
181 | qdio_init->queue_start_poll_array[i] : NULL; | ||
184 | 182 | ||
185 | setup_storage_lists(q, irq_ptr, input_sbal_array, i); | 183 | setup_storage_lists(q, irq_ptr, input_sbal_array, i); |
186 | input_sbal_array += QDIO_MAX_BUFFERS_PER_Q; | 184 | input_sbal_array += QDIO_MAX_BUFFERS_PER_Q; |
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c index dd4737808e06..077b7d109fde 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/drivers/s390/crypto/zcrypt_pcixcc.c | |||
@@ -56,11 +56,6 @@ | |||
56 | #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */ | 56 | #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */ |
57 | 57 | ||
58 | #define PCIXCC_MAX_XCRB_MESSAGE_SIZE (12*1024) | 58 | #define PCIXCC_MAX_XCRB_MESSAGE_SIZE (12*1024) |
59 | #define PCIXCC_MAX_XCRB_RESPONSE_SIZE PCIXCC_MAX_XCRB_MESSAGE_SIZE | ||
60 | #define PCIXCC_MAX_XCRB_DATA_SIZE (11*1024) | ||
61 | #define PCIXCC_MAX_XCRB_REPLY_SIZE (5*1024) | ||
62 | |||
63 | #define PCIXCC_MAX_RESPONSE_SIZE PCIXCC_MAX_XCRB_RESPONSE_SIZE | ||
64 | 59 | ||
65 | #define PCIXCC_CLEANUP_TIME (15*HZ) | 60 | #define PCIXCC_CLEANUP_TIME (15*HZ) |
66 | 61 | ||
@@ -265,7 +260,7 @@ static int ICACRT_msg_to_type6CRT_msgX(struct zcrypt_device *zdev, | |||
265 | * @ap_msg: pointer to AP message | 260 | * @ap_msg: pointer to AP message |
266 | * @xcRB: pointer to user input data | 261 | * @xcRB: pointer to user input data |
267 | * | 262 | * |
268 | * Returns 0 on success or -EFAULT. | 263 | * Returns 0 on success or -EFAULT, -EINVAL. |
269 | */ | 264 | */ |
270 | struct type86_fmt2_msg { | 265 | struct type86_fmt2_msg { |
271 | struct type86_hdr hdr; | 266 | struct type86_hdr hdr; |
@@ -295,19 +290,12 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev, | |||
295 | CEIL4(xcRB->request_control_blk_length) + | 290 | CEIL4(xcRB->request_control_blk_length) + |
296 | xcRB->request_data_length; | 291 | xcRB->request_data_length; |
297 | if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE) | 292 | if (ap_msg->length > PCIXCC_MAX_XCRB_MESSAGE_SIZE) |
298 | return -EFAULT; | 293 | return -EINVAL; |
299 | if (CEIL4(xcRB->reply_control_blk_length) > PCIXCC_MAX_XCRB_REPLY_SIZE) | 294 | replylen = sizeof(struct type86_fmt2_msg) + |
300 | return -EFAULT; | 295 | CEIL4(xcRB->reply_control_blk_length) + |
301 | if (CEIL4(xcRB->reply_data_length) > PCIXCC_MAX_XCRB_DATA_SIZE) | 296 | xcRB->reply_data_length; |
302 | return -EFAULT; | 297 | if (replylen > PCIXCC_MAX_XCRB_MESSAGE_SIZE) |
303 | replylen = CEIL4(xcRB->reply_control_blk_length) + | 298 | return -EINVAL; |
304 | CEIL4(xcRB->reply_data_length) + | ||
305 | sizeof(struct type86_fmt2_msg); | ||
306 | if (replylen > PCIXCC_MAX_XCRB_RESPONSE_SIZE) { | ||
307 | xcRB->reply_control_blk_length = PCIXCC_MAX_XCRB_RESPONSE_SIZE - | ||
308 | (sizeof(struct type86_fmt2_msg) + | ||
309 | CEIL4(xcRB->reply_data_length)); | ||
310 | } | ||
311 | 299 | ||
312 | /* prepare type6 header */ | 300 | /* prepare type6 header */ |
313 | msg->hdr = static_type6_hdrX; | 301 | msg->hdr = static_type6_hdrX; |
@@ -326,7 +314,7 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev, | |||
326 | return -EFAULT; | 314 | return -EFAULT; |
327 | if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) > | 315 | if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) > |
328 | xcRB->request_control_blk_length) | 316 | xcRB->request_control_blk_length) |
329 | return -EFAULT; | 317 | return -EINVAL; |
330 | function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len; | 318 | function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len; |
331 | memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code)); | 319 | memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code)); |
332 | 320 | ||
@@ -678,7 +666,7 @@ static void zcrypt_pcixcc_receive(struct ap_device *ap_dev, | |||
678 | break; | 666 | break; |
679 | case PCIXCC_RESPONSE_TYPE_XCRB: | 667 | case PCIXCC_RESPONSE_TYPE_XCRB: |
680 | length = t86r->fmt2.offset2 + t86r->fmt2.count2; | 668 | length = t86r->fmt2.offset2 + t86r->fmt2.count2; |
681 | length = min(PCIXCC_MAX_XCRB_RESPONSE_SIZE, length); | 669 | length = min(PCIXCC_MAX_XCRB_MESSAGE_SIZE, length); |
682 | memcpy(msg->message, reply->message, length); | 670 | memcpy(msg->message, reply->message, length); |
683 | break; | 671 | break; |
684 | default: | 672 | default: |
@@ -1043,7 +1031,7 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev) | |||
1043 | struct zcrypt_device *zdev; | 1031 | struct zcrypt_device *zdev; |
1044 | int rc = 0; | 1032 | int rc = 0; |
1045 | 1033 | ||
1046 | zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE); | 1034 | zdev = zcrypt_device_alloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE); |
1047 | if (!zdev) | 1035 | if (!zdev) |
1048 | return -ENOMEM; | 1036 | return -ENOMEM; |
1049 | zdev->ap_dev = ap_dev; | 1037 | zdev->ap_dev = ap_dev; |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 4fae1dc19951..9c3f38da4c01 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
@@ -4552,7 +4552,7 @@ static int qeth_qdio_establish(struct qeth_card *card) | |||
4552 | init_data.no_output_qs = card->qdio.no_out_queues; | 4552 | init_data.no_output_qs = card->qdio.no_out_queues; |
4553 | init_data.input_handler = card->discipline.input_handler; | 4553 | init_data.input_handler = card->discipline.input_handler; |
4554 | init_data.output_handler = card->discipline.output_handler; | 4554 | init_data.output_handler = card->discipline.output_handler; |
4555 | init_data.queue_start_poll = queue_start_poll; | 4555 | init_data.queue_start_poll_array = queue_start_poll; |
4556 | init_data.int_parm = (unsigned long) card; | 4556 | init_data.int_parm = (unsigned long) card; |
4557 | init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; | 4557 | init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; |
4558 | init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; | 4558 | init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; |