diff options
Diffstat (limited to 'drivers/scsi/libsas/sas_init.c')
-rw-r--r-- | drivers/scsi/libsas/sas_init.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index b961664b8106..c836a237fb79 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c | |||
@@ -159,17 +159,57 @@ static int sas_phy_reset(struct sas_phy *phy, int hard_reset) | |||
159 | struct sas_internal *i = | 159 | struct sas_internal *i = |
160 | to_sas_internal(sas_ha->core.shost->transportt); | 160 | to_sas_internal(sas_ha->core.shost->transportt); |
161 | 161 | ||
162 | ret = i->dft->lldd_control_phy(asd_phy, reset_type); | 162 | ret = i->dft->lldd_control_phy(asd_phy, reset_type, NULL); |
163 | } else { | 163 | } else { |
164 | struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent); | 164 | struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent); |
165 | struct domain_device *ddev = sas_find_dev_by_rphy(rphy); | 165 | struct domain_device *ddev = sas_find_dev_by_rphy(rphy); |
166 | ret = sas_smp_phy_control(ddev, phy->number, reset_type); | 166 | ret = sas_smp_phy_control(ddev, phy->number, reset_type, NULL); |
167 | } | 167 | } |
168 | return ret; | 168 | return ret; |
169 | } | 169 | } |
170 | 170 | ||
171 | static int sas_set_phy_speed(struct sas_phy *phy, | ||
172 | struct sas_phy_linkrates *rates) | ||
173 | { | ||
174 | int ret; | ||
175 | |||
176 | if ((rates->minimum_linkrate && | ||
177 | rates->minimum_linkrate > phy->maximum_linkrate) || | ||
178 | (rates->maximum_linkrate && | ||
179 | rates->maximum_linkrate < phy->minimum_linkrate)) | ||
180 | return -EINVAL; | ||
181 | |||
182 | if (rates->minimum_linkrate && | ||
183 | rates->minimum_linkrate < phy->minimum_linkrate_hw) | ||
184 | rates->minimum_linkrate = phy->minimum_linkrate_hw; | ||
185 | |||
186 | if (rates->maximum_linkrate && | ||
187 | rates->maximum_linkrate > phy->maximum_linkrate_hw) | ||
188 | rates->maximum_linkrate = phy->maximum_linkrate_hw; | ||
189 | |||
190 | if (scsi_is_sas_phy_local(phy)) { | ||
191 | struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); | ||
192 | struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); | ||
193 | struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number]; | ||
194 | struct sas_internal *i = | ||
195 | to_sas_internal(sas_ha->core.shost->transportt); | ||
196 | |||
197 | ret = i->dft->lldd_control_phy(asd_phy, PHY_FUNC_SET_LINK_RATE, | ||
198 | rates); | ||
199 | } else { | ||
200 | struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent); | ||
201 | struct domain_device *ddev = sas_find_dev_by_rphy(rphy); | ||
202 | ret = sas_smp_phy_control(ddev, phy->number, | ||
203 | PHY_FUNC_LINK_RESET, rates); | ||
204 | |||
205 | } | ||
206 | |||
207 | return ret; | ||
208 | } | ||
209 | |||
171 | static struct sas_function_template sft = { | 210 | static struct sas_function_template sft = { |
172 | .phy_reset = sas_phy_reset, | 211 | .phy_reset = sas_phy_reset, |
212 | .set_phy_speed = sas_set_phy_speed, | ||
173 | .get_linkerrors = sas_get_linkerrors, | 213 | .get_linkerrors = sas_get_linkerrors, |
174 | }; | 214 | }; |
175 | 215 | ||