diff options
| -rw-r--r-- | drivers/scsi/ipr.c | 175 | ||||
| -rw-r--r-- | drivers/scsi/ipr.h | 67 |
2 files changed, 241 insertions, 1 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index a5df245c8c2c..cca4972735be 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
| @@ -936,6 +936,52 @@ static void ipr_log_vpd(struct ipr_vpd *vpd) | |||
| 936 | } | 936 | } |
| 937 | 937 | ||
| 938 | /** | 938 | /** |
| 939 | * ipr_log_ext_vpd - Log the passed extended VPD to the error log. | ||
| 940 | * @vpd: vendor/product id/sn/wwn struct | ||
| 941 | * | ||
| 942 | * Return value: | ||
| 943 | * none | ||
| 944 | **/ | ||
| 945 | static void ipr_log_ext_vpd(struct ipr_ext_vpd *vpd) | ||
| 946 | { | ||
| 947 | ipr_log_vpd(&vpd->vpd); | ||
| 948 | ipr_err(" WWN: %08X%08X\n", be32_to_cpu(vpd->wwid[0]), | ||
| 949 | be32_to_cpu(vpd->wwid[1])); | ||
| 950 | } | ||
| 951 | |||
| 952 | /** | ||
| 953 | * ipr_log_enhanced_cache_error - Log a cache error. | ||
| 954 | * @ioa_cfg: ioa config struct | ||
| 955 | * @hostrcb: hostrcb struct | ||
| 956 | * | ||
| 957 | * Return value: | ||
| 958 | * none | ||
| 959 | **/ | ||
| 960 | static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg, | ||
| 961 | struct ipr_hostrcb *hostrcb) | ||
| 962 | { | ||
| 963 | struct ipr_hostrcb_type_12_error *error = | ||
| 964 | &hostrcb->hcam.u.error.u.type_12_error; | ||
| 965 | |||
| 966 | ipr_err("-----Current Configuration-----\n"); | ||
| 967 | ipr_err("Cache Directory Card Information:\n"); | ||
| 968 | ipr_log_ext_vpd(&error->ioa_vpd); | ||
| 969 | ipr_err("Adapter Card Information:\n"); | ||
| 970 | ipr_log_ext_vpd(&error->cfc_vpd); | ||
| 971 | |||
| 972 | ipr_err("-----Expected Configuration-----\n"); | ||
| 973 | ipr_err("Cache Directory Card Information:\n"); | ||
| 974 | ipr_log_ext_vpd(&error->ioa_last_attached_to_cfc_vpd); | ||
| 975 | ipr_err("Adapter Card Information:\n"); | ||
| 976 | ipr_log_ext_vpd(&error->cfc_last_attached_to_ioa_vpd); | ||
| 977 | |||
| 978 | ipr_err("Additional IOA Data: %08X %08X %08X\n", | ||
| 979 | be32_to_cpu(error->ioa_data[0]), | ||
| 980 | be32_to_cpu(error->ioa_data[1]), | ||
| 981 | be32_to_cpu(error->ioa_data[2])); | ||
| 982 | } | ||
| 983 | |||
| 984 | /** | ||
| 939 | * ipr_log_cache_error - Log a cache error. | 985 | * ipr_log_cache_error - Log a cache error. |
| 940 | * @ioa_cfg: ioa config struct | 986 | * @ioa_cfg: ioa config struct |
| 941 | * @hostrcb: hostrcb struct | 987 | * @hostrcb: hostrcb struct |
| @@ -968,6 +1014,46 @@ static void ipr_log_cache_error(struct ipr_ioa_cfg *ioa_cfg, | |||
| 968 | } | 1014 | } |
| 969 | 1015 | ||
| 970 | /** | 1016 | /** |
| 1017 | * ipr_log_enhanced_config_error - Log a configuration error. | ||
| 1018 | * @ioa_cfg: ioa config struct | ||
| 1019 | * @hostrcb: hostrcb struct | ||
| 1020 | * | ||
| 1021 | * Return value: | ||
| 1022 | * none | ||
| 1023 | **/ | ||
| 1024 | static void ipr_log_enhanced_config_error(struct ipr_ioa_cfg *ioa_cfg, | ||
| 1025 | struct ipr_hostrcb *hostrcb) | ||
| 1026 | { | ||
| 1027 | int errors_logged, i; | ||
| 1028 | struct ipr_hostrcb_device_data_entry_enhanced *dev_entry; | ||
| 1029 | struct ipr_hostrcb_type_13_error *error; | ||
| 1030 | |||
| 1031 | error = &hostrcb->hcam.u.error.u.type_13_error; | ||
| 1032 | errors_logged = be32_to_cpu(error->errors_logged); | ||
| 1033 | |||
| 1034 | ipr_err("Device Errors Detected/Logged: %d/%d\n", | ||
| 1035 | be32_to_cpu(error->errors_detected), errors_logged); | ||
| 1036 | |||
| 1037 | dev_entry = error->dev; | ||
| 1038 | |||
| 1039 | for (i = 0; i < errors_logged; i++, dev_entry++) { | ||
| 1040 | ipr_err_separator; | ||
| 1041 | |||
| 1042 | ipr_phys_res_err(ioa_cfg, dev_entry->dev_res_addr, "Device %d", i + 1); | ||
| 1043 | ipr_log_ext_vpd(&dev_entry->vpd); | ||
| 1044 | |||
| 1045 | ipr_err("-----New Device Information-----\n"); | ||
| 1046 | ipr_log_ext_vpd(&dev_entry->new_vpd); | ||
| 1047 | |||
| 1048 | ipr_err("Cache Directory Card Information:\n"); | ||
| 1049 | ipr_log_ext_vpd(&dev_entry->ioa_last_with_dev_vpd); | ||
| 1050 | |||
| 1051 | ipr_err("Adapter Card Information:\n"); | ||
| 1052 | ipr_log_ext_vpd(&dev_entry->cfc_last_with_dev_vpd); | ||
| 1053 | } | ||
| 1054 | } | ||
| 1055 | |||
| 1056 | /** | ||
| 971 | * ipr_log_config_error - Log a configuration error. | 1057 | * ipr_log_config_error - Log a configuration error. |
| 972 | * @ioa_cfg: ioa config struct | 1058 | * @ioa_cfg: ioa config struct |
| 973 | * @hostrcb: hostrcb struct | 1059 | * @hostrcb: hostrcb struct |
| @@ -1015,6 +1101,57 @@ static void ipr_log_config_error(struct ipr_ioa_cfg *ioa_cfg, | |||
| 1015 | } | 1101 | } |
| 1016 | 1102 | ||
| 1017 | /** | 1103 | /** |
| 1104 | * ipr_log_enhanced_array_error - Log an array configuration error. | ||
| 1105 | * @ioa_cfg: ioa config struct | ||
| 1106 | * @hostrcb: hostrcb struct | ||
| 1107 | * | ||
| 1108 | * Return value: | ||
| 1109 | * none | ||
| 1110 | **/ | ||
| 1111 | static void ipr_log_enhanced_array_error(struct ipr_ioa_cfg *ioa_cfg, | ||
| 1112 | struct ipr_hostrcb *hostrcb) | ||
| 1113 | { | ||
| 1114 | int i, num_entries; | ||
| 1115 | struct ipr_hostrcb_type_14_error *error; | ||
| 1116 | struct ipr_hostrcb_array_data_entry_enhanced *array_entry; | ||
| 1117 | const u8 zero_sn[IPR_SERIAL_NUM_LEN] = { [0 ... IPR_SERIAL_NUM_LEN-1] = '0' }; | ||
| 1118 | |||
| 1119 | error = &hostrcb->hcam.u.error.u.type_14_error; | ||
| 1120 | |||
| 1121 | ipr_err_separator; | ||
| 1122 | |||
| 1123 | ipr_err("RAID %s Array Configuration: %d:%d:%d:%d\n", | ||
| 1124 | error->protection_level, | ||
| 1125 | ioa_cfg->host->host_no, | ||
| 1126 | error->last_func_vset_res_addr.bus, | ||
| 1127 | error->last_func_vset_res_addr.target, | ||
| 1128 | error->last_func_vset_res_addr.lun); | ||
| 1129 | |||
| 1130 | ipr_err_separator; | ||
| 1131 | |||
| 1132 | array_entry = error->array_member; | ||
| 1133 | num_entries = min_t(u32, be32_to_cpu(error->num_entries), | ||
| 1134 | sizeof(error->array_member)); | ||
| 1135 | |||
| 1136 | for (i = 0; i < num_entries; i++, array_entry++) { | ||
| 1137 | if (!memcmp(array_entry->vpd.vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN)) | ||
| 1138 | continue; | ||
| 1139 | |||
| 1140 | if (be32_to_cpu(error->exposed_mode_adn) == i) | ||
| 1141 | ipr_err("Exposed Array Member %d:\n", i); | ||
| 1142 | else | ||
| 1143 | ipr_err("Array Member %d:\n", i); | ||
| 1144 | |||
| 1145 | ipr_log_ext_vpd(&array_entry->vpd); | ||
| 1146 | ipr_phys_res_err(ioa_cfg, array_entry->dev_res_addr, "Current Location"); | ||
| 1147 | ipr_phys_res_err(ioa_cfg, array_entry->expected_dev_res_addr, | ||
| 1148 | "Expected Location"); | ||
| 1149 | |||
| 1150 | ipr_err_separator; | ||
| 1151 | } | ||
| 1152 | } | ||
| 1153 | |||
| 1154 | /** | ||
| 1018 | * ipr_log_array_error - Log an array configuration error. | 1155 | * ipr_log_array_error - Log an array configuration error. |
| 1019 | * @ioa_cfg: ioa config struct | 1156 | * @ioa_cfg: ioa config struct |
| 1020 | * @hostrcb: hostrcb struct | 1157 | * @hostrcb: hostrcb struct |
| @@ -1094,6 +1231,31 @@ static void ipr_log_hex_data(u32 *data, int len) | |||
| 1094 | } | 1231 | } |
| 1095 | 1232 | ||
| 1096 | /** | 1233 | /** |
| 1234 | * ipr_log_enhanced_dual_ioa_error - Log an enhanced dual adapter error. | ||
| 1235 | * @ioa_cfg: ioa config struct | ||
| 1236 | * @hostrcb: hostrcb struct | ||
| 1237 | * | ||
| 1238 | * Return value: | ||
| 1239 | * none | ||
| 1240 | **/ | ||
| 1241 | static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, | ||
| 1242 | struct ipr_hostrcb *hostrcb) | ||
| 1243 | { | ||
| 1244 | struct ipr_hostrcb_type_17_error *error; | ||
| 1245 | |||
| 1246 | error = &hostrcb->hcam.u.error.u.type_17_error; | ||
| 1247 | error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; | ||
| 1248 | |||
| 1249 | ipr_err("%s\n", error->failure_reason); | ||
| 1250 | ipr_err("Remote Adapter VPD:\n"); | ||
| 1251 | ipr_log_ext_vpd(&error->vpd); | ||
| 1252 | ipr_log_hex_data(error->data, | ||
| 1253 | be32_to_cpu(hostrcb->hcam.length) - | ||
| 1254 | (offsetof(struct ipr_hostrcb_error, u) + | ||
| 1255 | offsetof(struct ipr_hostrcb_type_17_error, data))); | ||
| 1256 | } | ||
| 1257 | |||
| 1258 | /** | ||
| 1097 | * ipr_log_dual_ioa_error - Log a dual adapter error. | 1259 | * ipr_log_dual_ioa_error - Log a dual adapter error. |
| 1098 | * @ioa_cfg: ioa config struct | 1260 | * @ioa_cfg: ioa config struct |
| 1099 | * @hostrcb: hostrcb struct | 1261 | * @hostrcb: hostrcb struct |
| @@ -1221,6 +1383,19 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, | |||
| 1221 | case IPR_HOST_RCB_OVERLAY_ID_7: | 1383 | case IPR_HOST_RCB_OVERLAY_ID_7: |
| 1222 | ipr_log_dual_ioa_error(ioa_cfg, hostrcb); | 1384 | ipr_log_dual_ioa_error(ioa_cfg, hostrcb); |
| 1223 | break; | 1385 | break; |
| 1386 | case IPR_HOST_RCB_OVERLAY_ID_12: | ||
| 1387 | ipr_log_enhanced_cache_error(ioa_cfg, hostrcb); | ||
| 1388 | break; | ||
| 1389 | case IPR_HOST_RCB_OVERLAY_ID_13: | ||
| 1390 | ipr_log_enhanced_config_error(ioa_cfg, hostrcb); | ||
| 1391 | break; | ||
| 1392 | case IPR_HOST_RCB_OVERLAY_ID_14: | ||
| 1393 | case IPR_HOST_RCB_OVERLAY_ID_16: | ||
| 1394 | ipr_log_enhanced_array_error(ioa_cfg, hostrcb); | ||
| 1395 | break; | ||
| 1396 | case IPR_HOST_RCB_OVERLAY_ID_17: | ||
| 1397 | ipr_log_enhanced_dual_ioa_error(ioa_cfg, hostrcb); | ||
| 1398 | break; | ||
| 1224 | case IPR_HOST_RCB_OVERLAY_ID_1: | 1399 | case IPR_HOST_RCB_OVERLAY_ID_1: |
| 1225 | case IPR_HOST_RCB_OVERLAY_ID_DEFAULT: | 1400 | case IPR_HOST_RCB_OVERLAY_ID_DEFAULT: |
| 1226 | default: | 1401 | default: |
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index b8ae30669127..f7fa8cd2ecad 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h | |||
| @@ -254,6 +254,11 @@ struct ipr_vpd { | |||
| 254 | u8 sn[IPR_SERIAL_NUM_LEN]; | 254 | u8 sn[IPR_SERIAL_NUM_LEN]; |
| 255 | }__attribute__((packed)); | 255 | }__attribute__((packed)); |
| 256 | 256 | ||
| 257 | struct ipr_ext_vpd { | ||
| 258 | struct ipr_vpd vpd; | ||
| 259 | __be32 wwid[2]; | ||
| 260 | }__attribute__((packed)); | ||
| 261 | |||
| 257 | struct ipr_std_inq_data { | 262 | struct ipr_std_inq_data { |
| 258 | u8 peri_qual_dev_type; | 263 | u8 peri_qual_dev_type; |
| 259 | #define IPR_STD_INQ_PERI_QUAL(peri) ((peri) >> 5) | 264 | #define IPR_STD_INQ_PERI_QUAL(peri) ((peri) >> 5) |
| @@ -553,14 +558,31 @@ struct ipr_hostrcb_device_data_entry { | |||
| 553 | __be32 ioa_data[5]; | 558 | __be32 ioa_data[5]; |
| 554 | }__attribute__((packed, aligned (4))); | 559 | }__attribute__((packed, aligned (4))); |
| 555 | 560 | ||
| 561 | struct ipr_hostrcb_device_data_entry_enhanced { | ||
| 562 | struct ipr_ext_vpd vpd; | ||
| 563 | u8 ccin[4]; | ||
| 564 | struct ipr_res_addr dev_res_addr; | ||
| 565 | struct ipr_ext_vpd new_vpd; | ||
| 566 | u8 new_ccin[4]; | ||
| 567 | struct ipr_ext_vpd ioa_last_with_dev_vpd; | ||
| 568 | struct ipr_ext_vpd cfc_last_with_dev_vpd; | ||
| 569 | }__attribute__((packed, aligned (4))); | ||
| 570 | |||
| 556 | struct ipr_hostrcb_array_data_entry { | 571 | struct ipr_hostrcb_array_data_entry { |
| 557 | struct ipr_vpd vpd; | 572 | struct ipr_vpd vpd; |
| 558 | struct ipr_res_addr expected_dev_res_addr; | 573 | struct ipr_res_addr expected_dev_res_addr; |
| 559 | struct ipr_res_addr dev_res_addr; | 574 | struct ipr_res_addr dev_res_addr; |
| 560 | }__attribute__((packed, aligned (4))); | 575 | }__attribute__((packed, aligned (4))); |
| 561 | 576 | ||
| 577 | struct ipr_hostrcb_array_data_entry_enhanced { | ||
| 578 | struct ipr_ext_vpd vpd; | ||
| 579 | u8 ccin[4]; | ||
| 580 | struct ipr_res_addr expected_dev_res_addr; | ||
| 581 | struct ipr_res_addr dev_res_addr; | ||
| 582 | }__attribute__((packed, aligned (4))); | ||
| 583 | |||
| 562 | struct ipr_hostrcb_type_ff_error { | 584 | struct ipr_hostrcb_type_ff_error { |
| 563 | __be32 ioa_data[246]; | 585 | __be32 ioa_data[502]; |
| 564 | }__attribute__((packed, aligned (4))); | 586 | }__attribute__((packed, aligned (4))); |
| 565 | 587 | ||
| 566 | struct ipr_hostrcb_type_01_error { | 588 | struct ipr_hostrcb_type_01_error { |
| @@ -578,6 +600,14 @@ struct ipr_hostrcb_type_02_error { | |||
| 578 | __be32 ioa_data[3]; | 600 | __be32 ioa_data[3]; |
| 579 | }__attribute__((packed, aligned (4))); | 601 | }__attribute__((packed, aligned (4))); |
| 580 | 602 | ||
| 603 | struct ipr_hostrcb_type_12_error { | ||
| 604 | struct ipr_ext_vpd ioa_vpd; | ||
| 605 | struct ipr_ext_vpd cfc_vpd; | ||
| 606 | struct ipr_ext_vpd ioa_last_attached_to_cfc_vpd; | ||
| 607 | struct ipr_ext_vpd cfc_last_attached_to_ioa_vpd; | ||
| 608 | __be32 ioa_data[3]; | ||
| 609 | }__attribute__((packed, aligned (4))); | ||
| 610 | |||
| 581 | struct ipr_hostrcb_type_03_error { | 611 | struct ipr_hostrcb_type_03_error { |
| 582 | struct ipr_vpd ioa_vpd; | 612 | struct ipr_vpd ioa_vpd; |
| 583 | struct ipr_vpd cfc_vpd; | 613 | struct ipr_vpd cfc_vpd; |
| @@ -587,6 +617,14 @@ struct ipr_hostrcb_type_03_error { | |||
| 587 | struct ipr_hostrcb_device_data_entry dev[3]; | 617 | struct ipr_hostrcb_device_data_entry dev[3]; |
| 588 | }__attribute__((packed, aligned (4))); | 618 | }__attribute__((packed, aligned (4))); |
| 589 | 619 | ||
| 620 | struct ipr_hostrcb_type_13_error { | ||
| 621 | struct ipr_ext_vpd ioa_vpd; | ||
| 622 | struct ipr_ext_vpd cfc_vpd; | ||
| 623 | __be32 errors_detected; | ||
| 624 | __be32 errors_logged; | ||
| 625 | struct ipr_hostrcb_device_data_entry_enhanced dev[3]; | ||
| 626 | }__attribute__((packed, aligned (4))); | ||
| 627 | |||
| 590 | struct ipr_hostrcb_type_04_error { | 628 | struct ipr_hostrcb_type_04_error { |
| 591 | struct ipr_vpd ioa_vpd; | 629 | struct ipr_vpd ioa_vpd; |
| 592 | struct ipr_vpd cfc_vpd; | 630 | struct ipr_vpd cfc_vpd; |
| @@ -602,12 +640,30 @@ struct ipr_hostrcb_type_04_error { | |||
| 602 | u8 protection_level[8]; | 640 | u8 protection_level[8]; |
| 603 | }__attribute__((packed, aligned (4))); | 641 | }__attribute__((packed, aligned (4))); |
| 604 | 642 | ||
| 643 | struct ipr_hostrcb_type_14_error { | ||
| 644 | struct ipr_ext_vpd ioa_vpd; | ||
| 645 | struct ipr_ext_vpd cfc_vpd; | ||
| 646 | __be32 exposed_mode_adn; | ||
| 647 | __be32 array_id; | ||
| 648 | struct ipr_res_addr last_func_vset_res_addr; | ||
| 649 | u8 vset_serial_num[IPR_SERIAL_NUM_LEN]; | ||
| 650 | u8 protection_level[8]; | ||
| 651 | __be32 num_entries; | ||
| 652 | struct ipr_hostrcb_array_data_entry_enhanced array_member[18]; | ||
| 653 | }__attribute__((packed, aligned (4))); | ||
| 654 | |||
| 605 | struct ipr_hostrcb_type_07_error { | 655 | struct ipr_hostrcb_type_07_error { |
| 606 | u8 failure_reason[64]; | 656 | u8 failure_reason[64]; |
| 607 | struct ipr_vpd vpd; | 657 | struct ipr_vpd vpd; |
| 608 | u32 data[222]; | 658 | u32 data[222]; |
| 609 | }__attribute__((packed, aligned (4))); | 659 | }__attribute__((packed, aligned (4))); |
| 610 | 660 | ||
| 661 | struct ipr_hostrcb_type_17_error { | ||
| 662 | u8 failure_reason[64]; | ||
| 663 | struct ipr_ext_vpd vpd; | ||
| 664 | u32 data[476]; | ||
| 665 | }__attribute__((packed, aligned (4))); | ||
| 666 | |||
| 611 | struct ipr_hostrcb_error { | 667 | struct ipr_hostrcb_error { |
| 612 | __be32 failing_dev_ioasc; | 668 | __be32 failing_dev_ioasc; |
| 613 | struct ipr_res_addr failing_dev_res_addr; | 669 | struct ipr_res_addr failing_dev_res_addr; |
| @@ -620,6 +676,10 @@ struct ipr_hostrcb_error { | |||
| 620 | struct ipr_hostrcb_type_03_error type_03_error; | 676 | struct ipr_hostrcb_type_03_error type_03_error; |
| 621 | struct ipr_hostrcb_type_04_error type_04_error; | 677 | struct ipr_hostrcb_type_04_error type_04_error; |
| 622 | struct ipr_hostrcb_type_07_error type_07_error; | 678 | struct ipr_hostrcb_type_07_error type_07_error; |
| 679 | struct ipr_hostrcb_type_12_error type_12_error; | ||
| 680 | struct ipr_hostrcb_type_13_error type_13_error; | ||
| 681 | struct ipr_hostrcb_type_14_error type_14_error; | ||
| 682 | struct ipr_hostrcb_type_17_error type_17_error; | ||
| 623 | } u; | 683 | } u; |
| 624 | }__attribute__((packed, aligned (4))); | 684 | }__attribute__((packed, aligned (4))); |
| 625 | 685 | ||
| @@ -654,6 +714,11 @@ struct ipr_hcam { | |||
| 654 | #define IPR_HOST_RCB_OVERLAY_ID_4 0x04 | 714 | #define IPR_HOST_RCB_OVERLAY_ID_4 0x04 |
| 655 | #define IPR_HOST_RCB_OVERLAY_ID_6 0x06 | 715 | #define IPR_HOST_RCB_OVERLAY_ID_6 0x06 |
| 656 | #define IPR_HOST_RCB_OVERLAY_ID_7 0x07 | 716 | #define IPR_HOST_RCB_OVERLAY_ID_7 0x07 |
| 717 | #define IPR_HOST_RCB_OVERLAY_ID_12 0x12 | ||
| 718 | #define IPR_HOST_RCB_OVERLAY_ID_13 0x13 | ||
| 719 | #define IPR_HOST_RCB_OVERLAY_ID_14 0x14 | ||
| 720 | #define IPR_HOST_RCB_OVERLAY_ID_16 0x16 | ||
| 721 | #define IPR_HOST_RCB_OVERLAY_ID_17 0x17 | ||
| 657 | #define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF | 722 | #define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF |
| 658 | 723 | ||
| 659 | u8 reserved1[3]; | 724 | u8 reserved1[3]; |
