diff options
author | Darrick J. Wong <djwong@us.ibm.com> | 2007-01-11 17:14:57 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-01-13 17:13:00 -0500 |
commit | acbf167d4ad8c27f9743a4b539d51ae9535bf21c (patch) | |
tree | e53f8330f60acaef42d74a745b3dd5131b424e49 /drivers/scsi/libsas/sas_init.c | |
parent | b218a0d8e250e0ae8fd4d4e45bd66a588b380752 (diff) |
[SCSI] libsas: Add a sysfs knob to enable/disable a phy
This patch lets a user arbitrarily enable or disable a phy via sysfs.
Potential applications include shutting down a phy to replace one
lane of wide port, and (more importantly) providing a method for the
libata SATL to control the phy.
Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/libsas/sas_init.c')
-rw-r--r-- | drivers/scsi/libsas/sas_init.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 2f0c07fc3f48..90cce34cb6f5 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c | |||
@@ -146,6 +146,36 @@ static int sas_get_linkerrors(struct sas_phy *phy) | |||
146 | return sas_smp_get_phy_events(phy); | 146 | return sas_smp_get_phy_events(phy); |
147 | } | 147 | } |
148 | 148 | ||
149 | int sas_phy_enable(struct sas_phy *phy, int enable) | ||
150 | { | ||
151 | int ret; | ||
152 | enum phy_func command; | ||
153 | |||
154 | if (enable) | ||
155 | command = PHY_FUNC_LINK_RESET; | ||
156 | else | ||
157 | command = PHY_FUNC_DISABLE; | ||
158 | |||
159 | if (scsi_is_sas_phy_local(phy)) { | ||
160 | struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); | ||
161 | struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); | ||
162 | struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number]; | ||
163 | struct sas_internal *i = | ||
164 | to_sas_internal(sas_ha->core.shost->transportt); | ||
165 | |||
166 | if (!enable) { | ||
167 | sas_phy_disconnected(asd_phy); | ||
168 | sas_ha->notify_phy_event(asd_phy, PHYE_LOSS_OF_SIGNAL); | ||
169 | } | ||
170 | ret = i->dft->lldd_control_phy(asd_phy, command, NULL); | ||
171 | } else { | ||
172 | struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent); | ||
173 | struct domain_device *ddev = sas_find_dev_by_rphy(rphy); | ||
174 | ret = sas_smp_phy_control(ddev, phy->number, command, NULL); | ||
175 | } | ||
176 | return ret; | ||
177 | } | ||
178 | |||
149 | int sas_phy_reset(struct sas_phy *phy, int hard_reset) | 179 | int sas_phy_reset(struct sas_phy *phy, int hard_reset) |
150 | { | 180 | { |
151 | int ret; | 181 | int ret; |
@@ -172,8 +202,8 @@ int sas_phy_reset(struct sas_phy *phy, int hard_reset) | |||
172 | return ret; | 202 | return ret; |
173 | } | 203 | } |
174 | 204 | ||
175 | static int sas_set_phy_speed(struct sas_phy *phy, | 205 | int sas_set_phy_speed(struct sas_phy *phy, |
176 | struct sas_phy_linkrates *rates) | 206 | struct sas_phy_linkrates *rates) |
177 | { | 207 | { |
178 | int ret; | 208 | int ret; |
179 | 209 | ||
@@ -212,6 +242,7 @@ static int sas_set_phy_speed(struct sas_phy *phy, | |||
212 | } | 242 | } |
213 | 243 | ||
214 | static struct sas_function_template sft = { | 244 | static struct sas_function_template sft = { |
245 | .phy_enable = sas_phy_enable, | ||
215 | .phy_reset = sas_phy_reset, | 246 | .phy_reset = sas_phy_reset, |
216 | .set_phy_speed = sas_set_phy_speed, | 247 | .set_phy_speed = sas_set_phy_speed, |
217 | .get_linkerrors = sas_get_linkerrors, | 248 | .get_linkerrors = sas_get_linkerrors, |