diff options
author | brking@us.ibm.com <brking@us.ibm.com> | 2005-11-01 18:01:47 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-11-06 14:05:27 -0500 |
commit | b0df54bb4c9df6c1b1633a9f990b718059cda394 (patch) | |
tree | 9aea5bce33708f67428bccb84df41db6cd517d2d /drivers/scsi/ipr.c | |
parent | f37eb54b48159f7384ad0e7e70e0f67d1317aac7 (diff) |
[SCSI] ipr: handle new adapter errors
Add support for handling some new errors that may be returned
by ipr adapters.
Signed-off-by: Brian King <brking@us.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/ipr.c')
-rw-r--r-- | drivers/scsi/ipr.c | 83 |
1 files changed, 71 insertions, 12 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index eae61d994b90..b773852b4ea8 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -291,12 +291,18 @@ struct ipr_error_table_t ipr_error_table[] = { | |||
291 | "3110: Device bus error, message or command phase"}, | 291 | "3110: Device bus error, message or command phase"}, |
292 | {0x04670400, 0, 1, | 292 | {0x04670400, 0, 1, |
293 | "9091: Incorrect hardware configuration change has been detected"}, | 293 | "9091: Incorrect hardware configuration change has been detected"}, |
294 | {0x04678000, 0, 1, | ||
295 | "9073: Invalid multi-adapter configuration"}, | ||
294 | {0x046E0000, 0, 1, | 296 | {0x046E0000, 0, 1, |
295 | "FFF4: Command to logical unit failed"}, | 297 | "FFF4: Command to logical unit failed"}, |
296 | {0x05240000, 1, 0, | 298 | {0x05240000, 1, 0, |
297 | "Illegal request, invalid request type or request packet"}, | 299 | "Illegal request, invalid request type or request packet"}, |
298 | {0x05250000, 0, 0, | 300 | {0x05250000, 0, 0, |
299 | "Illegal request, invalid resource handle"}, | 301 | "Illegal request, invalid resource handle"}, |
302 | {0x05258000, 0, 0, | ||
303 | "Illegal request, commands not allowed to this device"}, | ||
304 | {0x05258100, 0, 0, | ||
305 | "Illegal request, command not allowed to a secondary adapter"}, | ||
300 | {0x05260000, 0, 0, | 306 | {0x05260000, 0, 0, |
301 | "Illegal request, invalid field in parameter list"}, | 307 | "Illegal request, invalid field in parameter list"}, |
302 | {0x05260100, 0, 0, | 308 | {0x05260100, 0, 0, |
@@ -305,6 +311,8 @@ struct ipr_error_table_t ipr_error_table[] = { | |||
305 | "Illegal request, parameter value invalid"}, | 311 | "Illegal request, parameter value invalid"}, |
306 | {0x052C0000, 0, 0, | 312 | {0x052C0000, 0, 0, |
307 | "Illegal request, command sequence error"}, | 313 | "Illegal request, command sequence error"}, |
314 | {0x052C8000, 1, 0, | ||
315 | "Illegal request, dual adapter support not enabled"}, | ||
308 | {0x06040500, 0, 1, | 316 | {0x06040500, 0, 1, |
309 | "9031: Array protection temporarily suspended, protection resuming"}, | 317 | "9031: Array protection temporarily suspended, protection resuming"}, |
310 | {0x06040600, 0, 1, | 318 | {0x06040600, 0, 1, |
@@ -321,18 +329,26 @@ struct ipr_error_table_t ipr_error_table[] = { | |||
321 | "3029: A device replacement has occurred"}, | 329 | "3029: A device replacement has occurred"}, |
322 | {0x064C8000, 0, 1, | 330 | {0x064C8000, 0, 1, |
323 | "9051: IOA cache data exists for a missing or failed device"}, | 331 | "9051: IOA cache data exists for a missing or failed device"}, |
332 | {0x064C8100, 0, 1, | ||
333 | "9055: Auxiliary cache IOA contains cache data needed by the primary IOA"}, | ||
324 | {0x06670100, 0, 1, | 334 | {0x06670100, 0, 1, |
325 | "9025: Disk unit is not supported at its physical location"}, | 335 | "9025: Disk unit is not supported at its physical location"}, |
326 | {0x06670600, 0, 1, | 336 | {0x06670600, 0, 1, |
327 | "3020: IOA detected a SCSI bus configuration error"}, | 337 | "3020: IOA detected a SCSI bus configuration error"}, |
328 | {0x06678000, 0, 1, | 338 | {0x06678000, 0, 1, |
329 | "3150: SCSI bus configuration error"}, | 339 | "3150: SCSI bus configuration error"}, |
340 | {0x06678100, 0, 1, | ||
341 | "9074: Asymmetric advanced function disk configuration"}, | ||
330 | {0x06690200, 0, 1, | 342 | {0x06690200, 0, 1, |
331 | "9041: Array protection temporarily suspended"}, | 343 | "9041: Array protection temporarily suspended"}, |
332 | {0x06698200, 0, 1, | 344 | {0x06698200, 0, 1, |
333 | "9042: Corrupt array parity detected on specified device"}, | 345 | "9042: Corrupt array parity detected on specified device"}, |
334 | {0x066B0200, 0, 1, | 346 | {0x066B0200, 0, 1, |
335 | "9030: Array no longer protected due to missing or failed disk unit"}, | 347 | "9030: Array no longer protected due to missing or failed disk unit"}, |
348 | {0x066B8000, 0, 1, | ||
349 | "9071: Link operational transition"}, | ||
350 | {0x066B8100, 0, 1, | ||
351 | "9072: Link not operational transition"}, | ||
336 | {0x066B8200, 0, 1, | 352 | {0x066B8200, 0, 1, |
337 | "9032: Array exposed but still protected"}, | 353 | "9032: Array exposed but still protected"}, |
338 | {0x07270000, 0, 0, | 354 | {0x07270000, 0, 0, |
@@ -1051,32 +1067,70 @@ static void ipr_log_array_error(struct ipr_ioa_cfg *ioa_cfg, | |||
1051 | } | 1067 | } |
1052 | 1068 | ||
1053 | /** | 1069 | /** |
1054 | * ipr_log_generic_error - Log an adapter error. | 1070 | * ipr_log_hex_data - Log additional hex IOA error data. |
1055 | * @ioa_cfg: ioa config struct | 1071 | * @data: IOA error data |
1056 | * @hostrcb: hostrcb struct | 1072 | * @len: data length |
1057 | * | 1073 | * |
1058 | * Return value: | 1074 | * Return value: |
1059 | * none | 1075 | * none |
1060 | **/ | 1076 | **/ |
1061 | static void ipr_log_generic_error(struct ipr_ioa_cfg *ioa_cfg, | 1077 | static void ipr_log_hex_data(u32 *data, int len) |
1062 | struct ipr_hostrcb *hostrcb) | ||
1063 | { | 1078 | { |
1064 | int i; | 1079 | int i; |
1065 | int ioa_data_len = be32_to_cpu(hostrcb->hcam.length); | ||
1066 | 1080 | ||
1067 | if (ioa_data_len == 0) | 1081 | if (len == 0) |
1068 | return; | 1082 | return; |
1069 | 1083 | ||
1070 | for (i = 0; i < ioa_data_len / 4; i += 4) { | 1084 | for (i = 0; i < len / 4; i += 4) { |
1071 | ipr_err("%08X: %08X %08X %08X %08X\n", i*4, | 1085 | ipr_err("%08X: %08X %08X %08X %08X\n", i*4, |
1072 | be32_to_cpu(hostrcb->hcam.u.raw.data[i]), | 1086 | be32_to_cpu(data[i]), |
1073 | be32_to_cpu(hostrcb->hcam.u.raw.data[i+1]), | 1087 | be32_to_cpu(data[i+1]), |
1074 | be32_to_cpu(hostrcb->hcam.u.raw.data[i+2]), | 1088 | be32_to_cpu(data[i+2]), |
1075 | be32_to_cpu(hostrcb->hcam.u.raw.data[i+3])); | 1089 | be32_to_cpu(data[i+3])); |
1076 | } | 1090 | } |
1077 | } | 1091 | } |
1078 | 1092 | ||
1079 | /** | 1093 | /** |
1094 | * ipr_log_dual_ioa_error - Log a dual adapter error. | ||
1095 | * @ioa_cfg: ioa config struct | ||
1096 | * @hostrcb: hostrcb struct | ||
1097 | * | ||
1098 | * Return value: | ||
1099 | * none | ||
1100 | **/ | ||
1101 | static void ipr_log_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, | ||
1102 | struct ipr_hostrcb *hostrcb) | ||
1103 | { | ||
1104 | struct ipr_hostrcb_type_07_error *error; | ||
1105 | |||
1106 | error = &hostrcb->hcam.u.error.u.type_07_error; | ||
1107 | error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; | ||
1108 | |||
1109 | ipr_err("%s\n", error->failure_reason); | ||
1110 | ipr_err("Remote Adapter VPD:\n"); | ||
1111 | ipr_log_vpd(&error->vpd); | ||
1112 | ipr_log_hex_data(error->data, | ||
1113 | be32_to_cpu(hostrcb->hcam.length) - | ||
1114 | (offsetof(struct ipr_hostrcb_error, u) + | ||
1115 | offsetof(struct ipr_hostrcb_type_07_error, data))); | ||
1116 | } | ||
1117 | |||
1118 | /** | ||
1119 | * ipr_log_generic_error - Log an adapter error. | ||
1120 | * @ioa_cfg: ioa config struct | ||
1121 | * @hostrcb: hostrcb struct | ||
1122 | * | ||
1123 | * Return value: | ||
1124 | * none | ||
1125 | **/ | ||
1126 | static void ipr_log_generic_error(struct ipr_ioa_cfg *ioa_cfg, | ||
1127 | struct ipr_hostrcb *hostrcb) | ||
1128 | { | ||
1129 | ipr_log_hex_data(hostrcb->hcam.u.raw.data, | ||
1130 | be32_to_cpu(hostrcb->hcam.length)); | ||
1131 | } | ||
1132 | |||
1133 | /** | ||
1080 | * ipr_get_error - Find the specfied IOASC in the ipr_error_table. | 1134 | * ipr_get_error - Find the specfied IOASC in the ipr_error_table. |
1081 | * @ioasc: IOASC | 1135 | * @ioasc: IOASC |
1082 | * | 1136 | * |
@@ -1161,6 +1215,9 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, | |||
1161 | case IPR_HOST_RCB_OVERLAY_ID_6: | 1215 | case IPR_HOST_RCB_OVERLAY_ID_6: |
1162 | ipr_log_array_error(ioa_cfg, hostrcb); | 1216 | ipr_log_array_error(ioa_cfg, hostrcb); |
1163 | break; | 1217 | break; |
1218 | case IPR_HOST_RCB_OVERLAY_ID_7: | ||
1219 | ipr_log_dual_ioa_error(ioa_cfg, hostrcb); | ||
1220 | break; | ||
1164 | case IPR_HOST_RCB_OVERLAY_ID_1: | 1221 | case IPR_HOST_RCB_OVERLAY_ID_1: |
1165 | case IPR_HOST_RCB_OVERLAY_ID_DEFAULT: | 1222 | case IPR_HOST_RCB_OVERLAY_ID_DEFAULT: |
1166 | default: | 1223 | default: |
@@ -3886,6 +3943,7 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg, | |||
3886 | scsi_cmd->result |= (DID_IMM_RETRY << 16); | 3943 | scsi_cmd->result |= (DID_IMM_RETRY << 16); |
3887 | break; | 3944 | break; |
3888 | case IPR_IOASC_IR_RESOURCE_HANDLE: | 3945 | case IPR_IOASC_IR_RESOURCE_HANDLE: |
3946 | case IPR_IOASC_IR_NO_CMDS_TO_2ND_IOA: | ||
3889 | scsi_cmd->result |= (DID_NO_CONNECT << 16); | 3947 | scsi_cmd->result |= (DID_NO_CONNECT << 16); |
3890 | break; | 3948 | break; |
3891 | case IPR_IOASC_HW_SEL_TIMEOUT: | 3949 | case IPR_IOASC_HW_SEL_TIMEOUT: |
@@ -3898,6 +3956,7 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg, | |||
3898 | scsi_cmd->result |= (DID_IMM_RETRY << 16); | 3956 | scsi_cmd->result |= (DID_IMM_RETRY << 16); |
3899 | break; | 3957 | break; |
3900 | case IPR_IOASC_MED_DO_NOT_REALLOC: /* prevent retries */ | 3958 | case IPR_IOASC_MED_DO_NOT_REALLOC: /* prevent retries */ |
3959 | case IPR_IOASA_IR_DUAL_IOA_DISABLED: | ||
3901 | scsi_cmd->result |= (DID_PASSTHROUGH << 16); | 3960 | scsi_cmd->result |= (DID_PASSTHROUGH << 16); |
3902 | break; | 3961 | break; |
3903 | case IPR_IOASC_BUS_WAS_RESET: | 3962 | case IPR_IOASC_BUS_WAS_RESET: |