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 | |
| 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>
| -rw-r--r-- | drivers/scsi/ipr.c | 83 | ||||
| -rw-r--r-- | drivers/scsi/ipr.h | 10 |
2 files changed, 81 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: |
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 414aa07e20f9..57d55b284caf 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h | |||
| @@ -81,6 +81,8 @@ | |||
| 81 | #define IPR_IOASC_IOASC_MASK 0xFFFFFF00 | 81 | #define IPR_IOASC_IOASC_MASK 0xFFFFFF00 |
| 82 | #define IPR_IOASC_SCSI_STATUS_MASK 0x000000FF | 82 | #define IPR_IOASC_SCSI_STATUS_MASK 0x000000FF |
| 83 | #define IPR_IOASC_IR_RESOURCE_HANDLE 0x05250000 | 83 | #define IPR_IOASC_IR_RESOURCE_HANDLE 0x05250000 |
| 84 | #define IPR_IOASC_IR_NO_CMDS_TO_2ND_IOA 0x05258100 | ||
| 85 | #define IPR_IOASA_IR_DUAL_IOA_DISABLED 0x052C8000 | ||
| 84 | #define IPR_IOASC_BUS_WAS_RESET 0x06290000 | 86 | #define IPR_IOASC_BUS_WAS_RESET 0x06290000 |
| 85 | #define IPR_IOASC_BUS_WAS_RESET_BY_OTHER 0x06298000 | 87 | #define IPR_IOASC_BUS_WAS_RESET_BY_OTHER 0x06298000 |
| 86 | #define IPR_IOASC_ABORTED_CMD_TERM_BY_HOST 0x0B5A0000 | 88 | #define IPR_IOASC_ABORTED_CMD_TERM_BY_HOST 0x0B5A0000 |
| @@ -593,6 +595,12 @@ struct ipr_hostrcb_type_04_error { | |||
| 593 | u8 protection_level[8]; | 595 | u8 protection_level[8]; |
| 594 | }__attribute__((packed, aligned (4))); | 596 | }__attribute__((packed, aligned (4))); |
| 595 | 597 | ||
| 598 | struct ipr_hostrcb_type_07_error { | ||
| 599 | u8 failure_reason[64]; | ||
| 600 | struct ipr_vpd vpd; | ||
| 601 | u32 data[222]; | ||
| 602 | }__attribute__((packed, aligned (4))); | ||
| 603 | |||
| 596 | struct ipr_hostrcb_error { | 604 | struct ipr_hostrcb_error { |
| 597 | __be32 failing_dev_ioasc; | 605 | __be32 failing_dev_ioasc; |
| 598 | struct ipr_res_addr failing_dev_res_addr; | 606 | struct ipr_res_addr failing_dev_res_addr; |
| @@ -604,6 +612,7 @@ struct ipr_hostrcb_error { | |||
| 604 | struct ipr_hostrcb_type_02_error type_02_error; | 612 | struct ipr_hostrcb_type_02_error type_02_error; |
| 605 | struct ipr_hostrcb_type_03_error type_03_error; | 613 | struct ipr_hostrcb_type_03_error type_03_error; |
| 606 | struct ipr_hostrcb_type_04_error type_04_error; | 614 | struct ipr_hostrcb_type_04_error type_04_error; |
| 615 | struct ipr_hostrcb_type_07_error type_07_error; | ||
| 607 | } u; | 616 | } u; |
| 608 | }__attribute__((packed, aligned (4))); | 617 | }__attribute__((packed, aligned (4))); |
| 609 | 618 | ||
| @@ -637,6 +646,7 @@ struct ipr_hcam { | |||
| 637 | #define IPR_HOST_RCB_OVERLAY_ID_3 0x03 | 646 | #define IPR_HOST_RCB_OVERLAY_ID_3 0x03 |
| 638 | #define IPR_HOST_RCB_OVERLAY_ID_4 0x04 | 647 | #define IPR_HOST_RCB_OVERLAY_ID_4 0x04 |
| 639 | #define IPR_HOST_RCB_OVERLAY_ID_6 0x06 | 648 | #define IPR_HOST_RCB_OVERLAY_ID_6 0x06 |
| 649 | #define IPR_HOST_RCB_OVERLAY_ID_7 0x07 | ||
| 640 | #define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF | 650 | #define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF |
| 641 | 651 | ||
| 642 | u8 reserved1[3]; | 652 | u8 reserved1[3]; |
