diff options
author | Wayne Boyer <wayneb@linux.vnet.ibm.com> | 2010-02-19 16:24:07 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-03-03 05:34:59 -0500 |
commit | 4565e3706329f65b5e64328b5369c53b6ab2715c (patch) | |
tree | 08a226d36be5ba667bbd2e0224e77021338774b9 /drivers/scsi/ipr.h | |
parent | 3e7ebdfa58ddaef361f9538219e66a7226fb1e5d (diff) |
[SCSI] ipr: add error handling updates for the next generation chip
Add support for the new log data notification and overlay IDs.
Signed-off-by: Wayne Boyer <wayneb@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/ipr.h')
-rw-r--r-- | drivers/scsi/ipr.h | 160 |
1 files changed, 141 insertions, 19 deletions
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index f10c57b3d215..e6e90179e45e 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h | |||
@@ -754,12 +754,29 @@ struct ipr_hostrcb_device_data_entry_enhanced { | |||
754 | struct ipr_ext_vpd cfc_last_with_dev_vpd; | 754 | struct ipr_ext_vpd cfc_last_with_dev_vpd; |
755 | }__attribute__((packed, aligned (4))); | 755 | }__attribute__((packed, aligned (4))); |
756 | 756 | ||
757 | struct ipr_hostrcb64_device_data_entry_enhanced { | ||
758 | struct ipr_ext_vpd vpd; | ||
759 | u8 ccin[4]; | ||
760 | u8 res_path[8]; | ||
761 | struct ipr_ext_vpd new_vpd; | ||
762 | u8 new_ccin[4]; | ||
763 | struct ipr_ext_vpd ioa_last_with_dev_vpd; | ||
764 | struct ipr_ext_vpd cfc_last_with_dev_vpd; | ||
765 | }__attribute__((packed, aligned (4))); | ||
766 | |||
757 | struct ipr_hostrcb_array_data_entry { | 767 | struct ipr_hostrcb_array_data_entry { |
758 | struct ipr_vpd vpd; | 768 | struct ipr_vpd vpd; |
759 | struct ipr_res_addr expected_dev_res_addr; | 769 | struct ipr_res_addr expected_dev_res_addr; |
760 | struct ipr_res_addr dev_res_addr; | 770 | struct ipr_res_addr dev_res_addr; |
761 | }__attribute__((packed, aligned (4))); | 771 | }__attribute__((packed, aligned (4))); |
762 | 772 | ||
773 | struct ipr_hostrcb64_array_data_entry { | ||
774 | struct ipr_ext_vpd vpd; | ||
775 | u8 ccin[4]; | ||
776 | u8 expected_res_path[8]; | ||
777 | u8 res_path[8]; | ||
778 | }__attribute__((packed, aligned (4))); | ||
779 | |||
763 | struct ipr_hostrcb_array_data_entry_enhanced { | 780 | struct ipr_hostrcb_array_data_entry_enhanced { |
764 | struct ipr_ext_vpd vpd; | 781 | struct ipr_ext_vpd vpd; |
765 | u8 ccin[4]; | 782 | u8 ccin[4]; |
@@ -811,6 +828,14 @@ struct ipr_hostrcb_type_13_error { | |||
811 | struct ipr_hostrcb_device_data_entry_enhanced dev[3]; | 828 | struct ipr_hostrcb_device_data_entry_enhanced dev[3]; |
812 | }__attribute__((packed, aligned (4))); | 829 | }__attribute__((packed, aligned (4))); |
813 | 830 | ||
831 | struct ipr_hostrcb_type_23_error { | ||
832 | struct ipr_ext_vpd ioa_vpd; | ||
833 | struct ipr_ext_vpd cfc_vpd; | ||
834 | __be32 errors_detected; | ||
835 | __be32 errors_logged; | ||
836 | struct ipr_hostrcb64_device_data_entry_enhanced dev[3]; | ||
837 | }__attribute__((packed, aligned (4))); | ||
838 | |||
814 | struct ipr_hostrcb_type_04_error { | 839 | struct ipr_hostrcb_type_04_error { |
815 | struct ipr_vpd ioa_vpd; | 840 | struct ipr_vpd ioa_vpd; |
816 | struct ipr_vpd cfc_vpd; | 841 | struct ipr_vpd cfc_vpd; |
@@ -838,6 +863,22 @@ struct ipr_hostrcb_type_14_error { | |||
838 | struct ipr_hostrcb_array_data_entry_enhanced array_member[18]; | 863 | struct ipr_hostrcb_array_data_entry_enhanced array_member[18]; |
839 | }__attribute__((packed, aligned (4))); | 864 | }__attribute__((packed, aligned (4))); |
840 | 865 | ||
866 | struct ipr_hostrcb_type_24_error { | ||
867 | struct ipr_ext_vpd ioa_vpd; | ||
868 | struct ipr_ext_vpd cfc_vpd; | ||
869 | u8 reserved[2]; | ||
870 | u8 exposed_mode_adn; | ||
871 | #define IPR_INVALID_ARRAY_DEV_NUM 0xff | ||
872 | u8 array_id; | ||
873 | u8 last_res_path[8]; | ||
874 | u8 protection_level[8]; | ||
875 | struct ipr_ext_vpd array_vpd; | ||
876 | u8 description[16]; | ||
877 | u8 reserved2[3]; | ||
878 | u8 num_entries; | ||
879 | struct ipr_hostrcb64_array_data_entry array_member[32]; | ||
880 | }__attribute__((packed, aligned (4))); | ||
881 | |||
841 | struct ipr_hostrcb_type_07_error { | 882 | struct ipr_hostrcb_type_07_error { |
842 | u8 failure_reason[64]; | 883 | u8 failure_reason[64]; |
843 | struct ipr_vpd vpd; | 884 | struct ipr_vpd vpd; |
@@ -875,6 +916,22 @@ struct ipr_hostrcb_config_element { | |||
875 | __be32 wwid[2]; | 916 | __be32 wwid[2]; |
876 | }__attribute__((packed, aligned (4))); | 917 | }__attribute__((packed, aligned (4))); |
877 | 918 | ||
919 | struct ipr_hostrcb64_config_element { | ||
920 | __be16 length; | ||
921 | u8 descriptor_id; | ||
922 | #define IPR_DESCRIPTOR_MASK 0xC0 | ||
923 | #define IPR_DESCRIPTOR_SIS64 0x00 | ||
924 | |||
925 | u8 reserved; | ||
926 | u8 type_status; | ||
927 | |||
928 | u8 reserved2[2]; | ||
929 | u8 link_rate; | ||
930 | |||
931 | u8 res_path[8]; | ||
932 | __be32 wwid[2]; | ||
933 | }__attribute__((packed, aligned (8))); | ||
934 | |||
878 | struct ipr_hostrcb_fabric_desc { | 935 | struct ipr_hostrcb_fabric_desc { |
879 | __be16 length; | 936 | __be16 length; |
880 | u8 ioa_port; | 937 | u8 ioa_port; |
@@ -896,6 +953,20 @@ struct ipr_hostrcb_fabric_desc { | |||
896 | struct ipr_hostrcb_config_element elem[1]; | 953 | struct ipr_hostrcb_config_element elem[1]; |
897 | }__attribute__((packed, aligned (4))); | 954 | }__attribute__((packed, aligned (4))); |
898 | 955 | ||
956 | struct ipr_hostrcb64_fabric_desc { | ||
957 | __be16 length; | ||
958 | u8 descriptor_id; | ||
959 | |||
960 | u8 reserved; | ||
961 | u8 path_state; | ||
962 | |||
963 | u8 reserved2[2]; | ||
964 | u8 res_path[8]; | ||
965 | u8 reserved3[6]; | ||
966 | __be16 num_entries; | ||
967 | struct ipr_hostrcb64_config_element elem[1]; | ||
968 | }__attribute__((packed, aligned (8))); | ||
969 | |||
899 | #define for_each_fabric_cfg(fabric, cfg) \ | 970 | #define for_each_fabric_cfg(fabric, cfg) \ |
900 | for (cfg = (fabric)->elem; \ | 971 | for (cfg = (fabric)->elem; \ |
901 | cfg < ((fabric)->elem + be16_to_cpu((fabric)->num_entries)); \ | 972 | cfg < ((fabric)->elem + be16_to_cpu((fabric)->num_entries)); \ |
@@ -908,10 +979,17 @@ struct ipr_hostrcb_type_20_error { | |||
908 | struct ipr_hostrcb_fabric_desc desc[1]; | 979 | struct ipr_hostrcb_fabric_desc desc[1]; |
909 | }__attribute__((packed, aligned (4))); | 980 | }__attribute__((packed, aligned (4))); |
910 | 981 | ||
982 | struct ipr_hostrcb_type_30_error { | ||
983 | u8 failure_reason[64]; | ||
984 | u8 reserved[3]; | ||
985 | u8 num_entries; | ||
986 | struct ipr_hostrcb64_fabric_desc desc[1]; | ||
987 | }__attribute__((packed, aligned (4))); | ||
988 | |||
911 | struct ipr_hostrcb_error { | 989 | struct ipr_hostrcb_error { |
912 | __be32 failing_dev_ioasc; | 990 | __be32 fd_ioasc; |
913 | struct ipr_res_addr failing_dev_res_addr; | 991 | struct ipr_res_addr fd_res_addr; |
914 | __be32 failing_dev_res_handle; | 992 | __be32 fd_res_handle; |
915 | __be32 prc; | 993 | __be32 prc; |
916 | union { | 994 | union { |
917 | struct ipr_hostrcb_type_ff_error type_ff_error; | 995 | struct ipr_hostrcb_type_ff_error type_ff_error; |
@@ -928,6 +1006,26 @@ struct ipr_hostrcb_error { | |||
928 | } u; | 1006 | } u; |
929 | }__attribute__((packed, aligned (4))); | 1007 | }__attribute__((packed, aligned (4))); |
930 | 1008 | ||
1009 | struct ipr_hostrcb64_error { | ||
1010 | __be32 fd_ioasc; | ||
1011 | __be32 ioa_fw_level; | ||
1012 | __be32 fd_res_handle; | ||
1013 | __be32 prc; | ||
1014 | __be64 fd_dev_id; | ||
1015 | __be64 fd_lun; | ||
1016 | u8 fd_res_path[8]; | ||
1017 | __be64 time_stamp; | ||
1018 | u8 reserved[2]; | ||
1019 | union { | ||
1020 | struct ipr_hostrcb_type_ff_error type_ff_error; | ||
1021 | struct ipr_hostrcb_type_12_error type_12_error; | ||
1022 | struct ipr_hostrcb_type_17_error type_17_error; | ||
1023 | struct ipr_hostrcb_type_23_error type_23_error; | ||
1024 | struct ipr_hostrcb_type_24_error type_24_error; | ||
1025 | struct ipr_hostrcb_type_30_error type_30_error; | ||
1026 | } u; | ||
1027 | }__attribute__((packed, aligned (8))); | ||
1028 | |||
931 | struct ipr_hostrcb_raw { | 1029 | struct ipr_hostrcb_raw { |
932 | __be32 data[sizeof(struct ipr_hostrcb_error)/sizeof(__be32)]; | 1030 | __be32 data[sizeof(struct ipr_hostrcb_error)/sizeof(__be32)]; |
933 | }__attribute__((packed, aligned (4))); | 1031 | }__attribute__((packed, aligned (4))); |
@@ -965,7 +1063,11 @@ struct ipr_hcam { | |||
965 | #define IPR_HOST_RCB_OVERLAY_ID_16 0x16 | 1063 | #define IPR_HOST_RCB_OVERLAY_ID_16 0x16 |
966 | #define IPR_HOST_RCB_OVERLAY_ID_17 0x17 | 1064 | #define IPR_HOST_RCB_OVERLAY_ID_17 0x17 |
967 | #define IPR_HOST_RCB_OVERLAY_ID_20 0x20 | 1065 | #define IPR_HOST_RCB_OVERLAY_ID_20 0x20 |
968 | #define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF | 1066 | #define IPR_HOST_RCB_OVERLAY_ID_23 0x23 |
1067 | #define IPR_HOST_RCB_OVERLAY_ID_24 0x24 | ||
1068 | #define IPR_HOST_RCB_OVERLAY_ID_26 0x26 | ||
1069 | #define IPR_HOST_RCB_OVERLAY_ID_30 0x30 | ||
1070 | #define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF | ||
969 | 1071 | ||
970 | u8 reserved1[3]; | 1072 | u8 reserved1[3]; |
971 | __be32 ilid; | 1073 | __be32 ilid; |
@@ -975,6 +1077,7 @@ struct ipr_hcam { | |||
975 | 1077 | ||
976 | union { | 1078 | union { |
977 | struct ipr_hostrcb_error error; | 1079 | struct ipr_hostrcb_error error; |
1080 | struct ipr_hostrcb64_error error64; | ||
978 | struct ipr_hostrcb_cfg_ch_not ccn; | 1081 | struct ipr_hostrcb_cfg_ch_not ccn; |
979 | struct ipr_hostrcb_raw raw; | 1082 | struct ipr_hostrcb_raw raw; |
980 | } u; | 1083 | } u; |
@@ -985,6 +1088,7 @@ struct ipr_hostrcb { | |||
985 | dma_addr_t hostrcb_dma; | 1088 | dma_addr_t hostrcb_dma; |
986 | struct list_head queue; | 1089 | struct list_head queue; |
987 | struct ipr_ioa_cfg *ioa_cfg; | 1090 | struct ipr_ioa_cfg *ioa_cfg; |
1091 | char rp_buffer[IPR_MAX_RES_PATH_LENGTH]; | ||
988 | }; | 1092 | }; |
989 | 1093 | ||
990 | /* IPR smart dump table structures */ | 1094 | /* IPR smart dump table structures */ |
@@ -1521,14 +1625,21 @@ struct ipr_ucode_image_header { | |||
1521 | } | 1625 | } |
1522 | 1626 | ||
1523 | #define ipr_hcam_err(hostrcb, fmt, ...) \ | 1627 | #define ipr_hcam_err(hostrcb, fmt, ...) \ |
1524 | { \ | 1628 | { \ |
1525 | if (ipr_is_device(&(hostrcb)->hcam.u.error.failing_dev_res_addr)) { \ | 1629 | if (ipr_is_device(hostrcb)) { \ |
1526 | ipr_ra_err((hostrcb)->ioa_cfg, \ | 1630 | if ((hostrcb)->ioa_cfg->sis64) { \ |
1527 | (hostrcb)->hcam.u.error.failing_dev_res_addr, \ | 1631 | printk(KERN_ERR IPR_NAME ": %s: " fmt, \ |
1528 | fmt, ##__VA_ARGS__); \ | 1632 | ipr_format_resource_path(&hostrcb->hcam.u.error64.fd_res_path[0], \ |
1529 | } else { \ | 1633 | &hostrcb->rp_buffer[0]), \ |
1530 | dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, ##__VA_ARGS__); \ | 1634 | __VA_ARGS__); \ |
1531 | } \ | 1635 | } else { \ |
1636 | ipr_ra_err((hostrcb)->ioa_cfg, \ | ||
1637 | (hostrcb)->hcam.u.error.fd_res_addr, \ | ||
1638 | fmt, __VA_ARGS__); \ | ||
1639 | } \ | ||
1640 | } else { \ | ||
1641 | dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, __VA_ARGS__); \ | ||
1642 | } \ | ||
1532 | } | 1643 | } |
1533 | 1644 | ||
1534 | #define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\ | 1645 | #define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\ |
@@ -1637,18 +1748,29 @@ static inline int ipr_is_naca_model(struct ipr_resource_entry *res) | |||
1637 | } | 1748 | } |
1638 | 1749 | ||
1639 | /** | 1750 | /** |
1640 | * ipr_is_device - Determine if resource address is that of a device | 1751 | * ipr_is_device - Determine if the hostrcb structure is related to a device |
1641 | * @res_addr: resource address struct | 1752 | * @hostrcb: host resource control blocks struct |
1642 | * | 1753 | * |
1643 | * Return value: | 1754 | * Return value: |
1644 | * 1 if AF / 0 if not AF | 1755 | * 1 if AF / 0 if not AF |
1645 | **/ | 1756 | **/ |
1646 | static inline int ipr_is_device(struct ipr_res_addr *res_addr) | 1757 | static inline int ipr_is_device(struct ipr_hostrcb *hostrcb) |
1647 | { | 1758 | { |
1648 | if ((res_addr->bus < IPR_MAX_NUM_BUSES) && | 1759 | struct ipr_res_addr *res_addr; |
1649 | (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1))) | 1760 | u8 *res_path; |
1650 | return 1; | 1761 | |
1651 | 1762 | if (hostrcb->ioa_cfg->sis64) { | |
1763 | res_path = &hostrcb->hcam.u.error64.fd_res_path[0]; | ||
1764 | if ((res_path[0] == 0x00 || res_path[0] == 0x80 || | ||
1765 | res_path[0] == 0x81) && res_path[2] != 0xFF) | ||
1766 | return 1; | ||
1767 | } else { | ||
1768 | res_addr = &hostrcb->hcam.u.error.fd_res_addr; | ||
1769 | |||
1770 | if ((res_addr->bus < IPR_MAX_NUM_BUSES) && | ||
1771 | (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1))) | ||
1772 | return 1; | ||
1773 | } | ||
1652 | return 0; | 1774 | return 0; |
1653 | } | 1775 | } |
1654 | 1776 | ||