diff options
author | Kashyap, Desai <kashyap.desai@lsi.com> | 2009-12-16 08:25:26 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-02-08 19:19:42 -0500 |
commit | 50d5c60634673a79f8d88564e10345b50fca7378 (patch) | |
tree | 837ce67b8dad98caddfc9469acecaca124ceea1d /drivers/scsi/mpt2sas | |
parent | f7c95ef02b564d9984c0655c9659791b1dd5d7ad (diff) |
[SCSI] mpt2sas: Added phy_enable and set_phy_speed sysfs callback support.
Added new callbacks phy_enable and set_phy_speed in the
mpt2sas_transport_functions template. This will allow end user to
enable/disable phys and change links rates using the SysFS interface.
Current implementation only supports direct attached phys, but we
could in the future add support for expander based phys.
A new subroutine mpt2sas_config_set_sas_iounit_pg1 was added;
this wrapper function used to send request to controller firmware to modify
the phys and link rates. A new subroutine _transport_find_local_phy was added;
a function for easly obtaining the local phy object for direct attached.
Example to disable a phy
echo 0 > /sys/class/phy3:0/enable
Example to enable the same phy
echo 1 > /sys/class/phy3:0/enable
Example to change the link rate to 1.5
#echo "1.5 Gbit" > /sys/class/phy3:0/maximum_linkrate
#cat /sys/class/phy3:0/negotiated_linkrate
1.5 Gbit
Example to change the link rate to 3.0
#echo "3.0 Gbit" > /sys/class/phy3:0/maximum_linkrate
#cat /sys/class/phy3:0/negotiated_linkrate
3.0 Gbit
Example to change the link rate to 6.0
#echo "6.0 Gbit" > /sys/class/phy3:0/maximum_linkrate
#cat /sys/class/phy3:0/negotiated_linkrate
6.0 Gbit
Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com>
Reviewed-by: Eric Moore <eric.moore@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.h | 2 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_config.c | 51 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_transport.c | 196 |
3 files changed, 232 insertions, 17 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index 014318fa3b0e..93c067f5dbbc 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h | |||
@@ -853,6 +853,8 @@ int mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
853 | *mpi_reply, Mpi2IOUnitPage1_t *config_page); | 853 | *mpi_reply, Mpi2IOUnitPage1_t *config_page); |
854 | int mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | 854 | int mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t |
855 | *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz); | 855 | *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz); |
856 | int mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, | ||
857 | Mpi2ConfigReply_t *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz); | ||
856 | int mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | 858 | int mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t |
857 | *mpi_reply, Mpi2IOCPage8_t *config_page); | 859 | *mpi_reply, Mpi2IOCPage8_t *config_page); |
858 | int mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | 860 | int mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c index 594a389c6526..411c27d7f787 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_config.c +++ b/drivers/scsi/mpt2sas/mpt2sas_config.c | |||
@@ -324,7 +324,9 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t | |||
324 | if (r != 0) | 324 | if (r != 0) |
325 | goto out; | 325 | goto out; |
326 | if (mpi_request->Action == | 326 | if (mpi_request->Action == |
327 | MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT) { | 327 | MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT || |
328 | mpi_request->Action == | ||
329 | MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM) { | ||
328 | ioc->base_add_sg_single(&mpi_request->PageBufferSGE, | 330 | ioc->base_add_sg_single(&mpi_request->PageBufferSGE, |
329 | MPT2_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz, | 331 | MPT2_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz, |
330 | mem.page_dma); | 332 | mem.page_dma); |
@@ -882,7 +884,7 @@ mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
882 | } | 884 | } |
883 | 885 | ||
884 | /** | 886 | /** |
885 | * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 0 | 887 | * mpt2sas_config_get_sas_iounit_pg1 - obtain sas iounit page 1 |
886 | * @ioc: per adapter object | 888 | * @ioc: per adapter object |
887 | * @mpi_reply: reply mf payload returned from firmware | 889 | * @mpi_reply: reply mf payload returned from firmware |
888 | * @config_page: contents of the config page | 890 | * @config_page: contents of the config page |
@@ -907,7 +909,7 @@ mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
907 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | 909 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; |
908 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; | 910 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; |
909 | mpi_request.Header.PageNumber = 1; | 911 | mpi_request.Header.PageNumber = 1; |
910 | mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION; | 912 | mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; |
911 | mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); | 913 | mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); |
912 | r = _config_request(ioc, &mpi_request, mpi_reply, | 914 | r = _config_request(ioc, &mpi_request, mpi_reply, |
913 | MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | 915 | MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); |
@@ -922,6 +924,49 @@ mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | |||
922 | } | 924 | } |
923 | 925 | ||
924 | /** | 926 | /** |
927 | * mpt2sas_config_set_sas_iounit_pg1 - send sas iounit page 1 | ||
928 | * @ioc: per adapter object | ||
929 | * @mpi_reply: reply mf payload returned from firmware | ||
930 | * @config_page: contents of the config page | ||
931 | * @sz: size of buffer passed in config_page | ||
932 | * Context: sleep. | ||
933 | * | ||
934 | * Calling function should call config_get_number_hba_phys prior to | ||
935 | * this function, so enough memory is allocated for config_page. | ||
936 | * | ||
937 | * Returns 0 for success, non-zero for failure. | ||
938 | */ | ||
939 | int | ||
940 | mpt2sas_config_set_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t | ||
941 | *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz) | ||
942 | { | ||
943 | Mpi2ConfigRequest_t mpi_request; | ||
944 | int r; | ||
945 | |||
946 | memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t)); | ||
947 | mpi_request.Function = MPI2_FUNCTION_CONFIG; | ||
948 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER; | ||
949 | mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; | ||
950 | mpi_request.ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; | ||
951 | mpi_request.Header.PageNumber = 1; | ||
952 | mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE1_PAGEVERSION; | ||
953 | mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE); | ||
954 | r = _config_request(ioc, &mpi_request, mpi_reply, | ||
955 | MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0); | ||
956 | if (r) | ||
957 | goto out; | ||
958 | |||
959 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT; | ||
960 | _config_request(ioc, &mpi_request, mpi_reply, | ||
961 | MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); | ||
962 | mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM; | ||
963 | r = _config_request(ioc, &mpi_request, mpi_reply, | ||
964 | MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz); | ||
965 | out: | ||
966 | return r; | ||
967 | } | ||
968 | |||
969 | /** | ||
925 | * mpt2sas_config_get_expander_pg0 - obtain expander page 0 | 970 | * mpt2sas_config_get_expander_pg0 - obtain expander page 0 |
926 | * @ioc: per adapter object | 971 | * @ioc: per adapter object |
927 | * @mpi_reply: reply mf payload returned from firmware | 972 | * @mpi_reply: reply mf payload returned from firmware |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c index 3a82872bad44..789f9ee7f001 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_transport.c +++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c | |||
@@ -855,6 +855,17 @@ rphy_to_ioc(struct sas_rphy *rphy) | |||
855 | return shost_priv(shost); | 855 | return shost_priv(shost); |
856 | } | 856 | } |
857 | 857 | ||
858 | static struct _sas_phy * | ||
859 | _transport_find_local_phy(struct MPT2SAS_ADAPTER *ioc, struct sas_phy *phy) | ||
860 | { | ||
861 | int i; | ||
862 | |||
863 | for (i = 0; i < ioc->sas_hba.num_phys; i++) | ||
864 | if (ioc->sas_hba.phy[i].phy == phy) | ||
865 | return(&ioc->sas_hba.phy[i]); | ||
866 | return NULL; | ||
867 | } | ||
868 | |||
858 | /** | 869 | /** |
859 | * _transport_get_linkerrors - | 870 | * _transport_get_linkerrors - |
860 | * @phy: The sas phy object | 871 | * @phy: The sas phy object |
@@ -870,14 +881,8 @@ _transport_get_linkerrors(struct sas_phy *phy) | |||
870 | struct _sas_phy *mpt2sas_phy; | 881 | struct _sas_phy *mpt2sas_phy; |
871 | Mpi2ConfigReply_t mpi_reply; | 882 | Mpi2ConfigReply_t mpi_reply; |
872 | Mpi2SasPhyPage1_t phy_pg1; | 883 | Mpi2SasPhyPage1_t phy_pg1; |
873 | int i; | ||
874 | 884 | ||
875 | for (i = 0, mpt2sas_phy = NULL; i < ioc->sas_hba.num_phys && | 885 | mpt2sas_phy = _transport_find_local_phy(ioc, phy); |
876 | !mpt2sas_phy; i++) { | ||
877 | if (ioc->sas_hba.phy[i].phy != phy) | ||
878 | continue; | ||
879 | mpt2sas_phy = &ioc->sas_hba.phy[i]; | ||
880 | } | ||
881 | 886 | ||
882 | if (!mpt2sas_phy) /* this phy not on sas_host */ | 887 | if (!mpt2sas_phy) /* this phy not on sas_host */ |
883 | return -EINVAL; | 888 | return -EINVAL; |
@@ -971,14 +976,8 @@ _transport_phy_reset(struct sas_phy *phy, int hard_reset) | |||
971 | struct _sas_phy *mpt2sas_phy; | 976 | struct _sas_phy *mpt2sas_phy; |
972 | Mpi2SasIoUnitControlReply_t mpi_reply; | 977 | Mpi2SasIoUnitControlReply_t mpi_reply; |
973 | Mpi2SasIoUnitControlRequest_t mpi_request; | 978 | Mpi2SasIoUnitControlRequest_t mpi_request; |
974 | int i; | ||
975 | 979 | ||
976 | for (i = 0, mpt2sas_phy = NULL; i < ioc->sas_hba.num_phys && | 980 | mpt2sas_phy = _transport_find_local_phy(ioc, phy); |
977 | !mpt2sas_phy; i++) { | ||
978 | if (ioc->sas_hba.phy[i].phy != phy) | ||
979 | continue; | ||
980 | mpt2sas_phy = &ioc->sas_hba.phy[i]; | ||
981 | } | ||
982 | 981 | ||
983 | if (!mpt2sas_phy) /* this phy not on sas_host */ | 982 | if (!mpt2sas_phy) /* this phy not on sas_host */ |
984 | return -EINVAL; | 983 | return -EINVAL; |
@@ -1006,6 +1005,173 @@ _transport_phy_reset(struct sas_phy *phy, int hard_reset) | |||
1006 | } | 1005 | } |
1007 | 1006 | ||
1008 | /** | 1007 | /** |
1008 | * _transport_phy_enable - enable/disable phys | ||
1009 | * @phy: The sas phy object | ||
1010 | * @enable: enable phy when true | ||
1011 | * | ||
1012 | * Only support sas_host direct attached phys. | ||
1013 | * Returns 0 for success, non-zero for failure. | ||
1014 | */ | ||
1015 | static int | ||
1016 | _transport_phy_enable(struct sas_phy *phy, int enable) | ||
1017 | { | ||
1018 | struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy); | ||
1019 | struct _sas_phy *mpt2sas_phy; | ||
1020 | Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; | ||
1021 | Mpi2ConfigReply_t mpi_reply; | ||
1022 | u16 ioc_status; | ||
1023 | u16 sz; | ||
1024 | int rc = 0; | ||
1025 | |||
1026 | mpt2sas_phy = _transport_find_local_phy(ioc, phy); | ||
1027 | |||
1028 | if (!mpt2sas_phy) /* this phy not on sas_host */ | ||
1029 | return -EINVAL; | ||
1030 | |||
1031 | /* sas_iounit page 1 */ | ||
1032 | sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * | ||
1033 | sizeof(Mpi2SasIOUnit1PhyData_t)); | ||
1034 | sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); | ||
1035 | if (!sas_iounit_pg1) { | ||
1036 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1037 | ioc->name, __FILE__, __LINE__, __func__); | ||
1038 | rc = -ENOMEM; | ||
1039 | goto out; | ||
1040 | } | ||
1041 | if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, | ||
1042 | sas_iounit_pg1, sz))) { | ||
1043 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1044 | ioc->name, __FILE__, __LINE__, __func__); | ||
1045 | rc = -ENXIO; | ||
1046 | goto out; | ||
1047 | } | ||
1048 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
1049 | MPI2_IOCSTATUS_MASK; | ||
1050 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { | ||
1051 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1052 | ioc->name, __FILE__, __LINE__, __func__); | ||
1053 | rc = -EIO; | ||
1054 | goto out; | ||
1055 | } | ||
1056 | |||
1057 | if (enable) | ||
1058 | sas_iounit_pg1->PhyData[mpt2sas_phy->phy_id].PhyFlags | ||
1059 | &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE; | ||
1060 | else | ||
1061 | sas_iounit_pg1->PhyData[mpt2sas_phy->phy_id].PhyFlags | ||
1062 | |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE; | ||
1063 | |||
1064 | mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz); | ||
1065 | |||
1066 | out: | ||
1067 | kfree(sas_iounit_pg1); | ||
1068 | return rc; | ||
1069 | } | ||
1070 | |||
1071 | /** | ||
1072 | * _transport_phy_speed - set phy min/max link rates | ||
1073 | * @phy: The sas phy object | ||
1074 | * @rates: rates defined in sas_phy_linkrates | ||
1075 | * | ||
1076 | * Only support sas_host direct attached phys. | ||
1077 | * Returns 0 for success, non-zero for failure. | ||
1078 | */ | ||
1079 | static int | ||
1080 | _transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates) | ||
1081 | { | ||
1082 | struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy); | ||
1083 | struct _sas_phy *mpt2sas_phy; | ||
1084 | Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; | ||
1085 | Mpi2SasPhyPage0_t phy_pg0; | ||
1086 | Mpi2ConfigReply_t mpi_reply; | ||
1087 | u16 ioc_status; | ||
1088 | u16 sz; | ||
1089 | int i; | ||
1090 | int rc = 0; | ||
1091 | |||
1092 | mpt2sas_phy = _transport_find_local_phy(ioc, phy); | ||
1093 | |||
1094 | if (!mpt2sas_phy) /* this phy not on sas_host */ | ||
1095 | return -EINVAL; | ||
1096 | |||
1097 | if (!rates->minimum_linkrate) | ||
1098 | rates->minimum_linkrate = phy->minimum_linkrate; | ||
1099 | else if (rates->minimum_linkrate < phy->minimum_linkrate_hw) | ||
1100 | rates->minimum_linkrate = phy->minimum_linkrate_hw; | ||
1101 | |||
1102 | if (!rates->maximum_linkrate) | ||
1103 | rates->maximum_linkrate = phy->maximum_linkrate; | ||
1104 | else if (rates->maximum_linkrate > phy->maximum_linkrate_hw) | ||
1105 | rates->maximum_linkrate = phy->maximum_linkrate_hw; | ||
1106 | |||
1107 | /* sas_iounit page 1 */ | ||
1108 | sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * | ||
1109 | sizeof(Mpi2SasIOUnit1PhyData_t)); | ||
1110 | sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); | ||
1111 | if (!sas_iounit_pg1) { | ||
1112 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1113 | ioc->name, __FILE__, __LINE__, __func__); | ||
1114 | rc = -ENOMEM; | ||
1115 | goto out; | ||
1116 | } | ||
1117 | if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, | ||
1118 | sas_iounit_pg1, sz))) { | ||
1119 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1120 | ioc->name, __FILE__, __LINE__, __func__); | ||
1121 | rc = -ENXIO; | ||
1122 | goto out; | ||
1123 | } | ||
1124 | ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & | ||
1125 | MPI2_IOCSTATUS_MASK; | ||
1126 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { | ||
1127 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1128 | ioc->name, __FILE__, __LINE__, __func__); | ||
1129 | rc = -EIO; | ||
1130 | goto out; | ||
1131 | } | ||
1132 | |||
1133 | for (i = 0; i < ioc->sas_hba.num_phys; i++) { | ||
1134 | if (mpt2sas_phy->phy_id != i) { | ||
1135 | sas_iounit_pg1->PhyData[i].MaxMinLinkRate = | ||
1136 | (ioc->sas_hba.phy[i].phy->minimum_linkrate + | ||
1137 | (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4)); | ||
1138 | } else { | ||
1139 | sas_iounit_pg1->PhyData[i].MaxMinLinkRate = | ||
1140 | (rates->minimum_linkrate + | ||
1141 | (rates->maximum_linkrate << 4)); | ||
1142 | } | ||
1143 | } | ||
1144 | |||
1145 | if (mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, | ||
1146 | sz)) { | ||
1147 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | ||
1148 | ioc->name, __FILE__, __LINE__, __func__); | ||
1149 | rc = -ENXIO; | ||
1150 | goto out; | ||
1151 | } | ||
1152 | |||
1153 | /* link reset */ | ||
1154 | _transport_phy_reset(phy, 0); | ||
1155 | |||
1156 | /* read phy page 0, then update the rates in the sas transport phy */ | ||
1157 | if (!mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0, | ||
1158 | mpt2sas_phy->phy_id)) { | ||
1159 | phy->minimum_linkrate = _transport_convert_phy_link_rate( | ||
1160 | phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); | ||
1161 | phy->maximum_linkrate = _transport_convert_phy_link_rate( | ||
1162 | phy_pg0.ProgrammedLinkRate >> 4); | ||
1163 | phy->negotiated_linkrate = _transport_convert_phy_link_rate( | ||
1164 | phy_pg0.NegotiatedLinkRate & | ||
1165 | MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL); | ||
1166 | } | ||
1167 | |||
1168 | out: | ||
1169 | kfree(sas_iounit_pg1); | ||
1170 | return rc; | ||
1171 | } | ||
1172 | |||
1173 | |||
1174 | /** | ||
1009 | * _transport_smp_handler - transport portal for smp passthru | 1175 | * _transport_smp_handler - transport portal for smp passthru |
1010 | * @shost: shost object | 1176 | * @shost: shost object |
1011 | * @rphy: sas transport rphy object | 1177 | * @rphy: sas transport rphy object |
@@ -1207,6 +1373,8 @@ struct sas_function_template mpt2sas_transport_functions = { | |||
1207 | .get_enclosure_identifier = _transport_get_enclosure_identifier, | 1373 | .get_enclosure_identifier = _transport_get_enclosure_identifier, |
1208 | .get_bay_identifier = _transport_get_bay_identifier, | 1374 | .get_bay_identifier = _transport_get_bay_identifier, |
1209 | .phy_reset = _transport_phy_reset, | 1375 | .phy_reset = _transport_phy_reset, |
1376 | .phy_enable = _transport_phy_enable, | ||
1377 | .set_phy_speed = _transport_phy_speed, | ||
1210 | .smp_handler = _transport_smp_handler, | 1378 | .smp_handler = _transport_smp_handler, |
1211 | }; | 1379 | }; |
1212 | 1380 | ||