diff options
Diffstat (limited to 'drivers')
-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]; |