diff options
author | James Bottomley <James.Bottomley@steeleye.com> | 2006-09-06 20:28:07 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-09-07 16:20:23 -0400 |
commit | a01e70e570a72b8a8c9a58062e4f5bdcd3986222 (patch) | |
tree | d2b8b5e0e69d14805ac98033561597de6e24d5c6 /drivers/scsi/libsas/sas_expander.c | |
parent | d24e1eeb3a16e4944288c2f3bf082e1513f4b425 (diff) |
[SCSI] aci94xx: implement link rate setting
This patch implements the ability to set the minimum and maximum
linkrates for both libsas (for expanders) and aic94xx (for the host
phys). It also tidies up the setting of the hardware min and max to
make sure they're updated when the expander emits a change broadcast.
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/libsas/sas_expander.c')
-rw-r--r-- | drivers/scsi/libsas/sas_expander.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 02e796ee027e..30b8014bcc7a 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
@@ -187,10 +187,10 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, | |||
187 | phy->phy->identify.initiator_port_protocols = phy->attached_iproto; | 187 | phy->phy->identify.initiator_port_protocols = phy->attached_iproto; |
188 | phy->phy->identify.target_port_protocols = phy->attached_tproto; | 188 | phy->phy->identify.target_port_protocols = phy->attached_tproto; |
189 | phy->phy->identify.phy_identifier = phy_id; | 189 | phy->phy->identify.phy_identifier = phy_id; |
190 | phy->phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS; | 190 | phy->phy->minimum_linkrate_hw = dr->hmin_linkrate; |
191 | phy->phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS; | 191 | phy->phy->maximum_linkrate_hw = dr->hmax_linkrate; |
192 | phy->phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS; | 192 | phy->phy->minimum_linkrate = dr->pmin_linkrate; |
193 | phy->phy->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS; | 193 | phy->phy->maximum_linkrate = dr->pmax_linkrate; |
194 | phy->phy->negotiated_linkrate = phy->linkrate; | 194 | phy->phy->negotiated_linkrate = phy->linkrate; |
195 | 195 | ||
196 | if (!rediscover) | 196 | if (!rediscover) |
@@ -404,7 +404,8 @@ out: | |||
404 | #define PC_RESP_SIZE 8 | 404 | #define PC_RESP_SIZE 8 |
405 | 405 | ||
406 | int sas_smp_phy_control(struct domain_device *dev, int phy_id, | 406 | int sas_smp_phy_control(struct domain_device *dev, int phy_id, |
407 | enum phy_func phy_func) | 407 | enum phy_func phy_func, |
408 | struct sas_phy_linkrates *rates) | ||
408 | { | 409 | { |
409 | u8 *pc_req; | 410 | u8 *pc_req; |
410 | u8 *pc_resp; | 411 | u8 *pc_resp; |
@@ -423,6 +424,10 @@ int sas_smp_phy_control(struct domain_device *dev, int phy_id, | |||
423 | pc_req[1] = SMP_PHY_CONTROL; | 424 | pc_req[1] = SMP_PHY_CONTROL; |
424 | pc_req[9] = phy_id; | 425 | pc_req[9] = phy_id; |
425 | pc_req[10]= phy_func; | 426 | pc_req[10]= phy_func; |
427 | if (rates) { | ||
428 | pc_req[32] = rates->minimum_linkrate << 4; | ||
429 | pc_req[33] = rates->maximum_linkrate << 4; | ||
430 | } | ||
426 | 431 | ||
427 | res = smp_execute_task(dev, pc_req, PC_REQ_SIZE, pc_resp,PC_RESP_SIZE); | 432 | res = smp_execute_task(dev, pc_req, PC_REQ_SIZE, pc_resp,PC_RESP_SIZE); |
428 | 433 | ||
@@ -436,7 +441,7 @@ static void sas_ex_disable_phy(struct domain_device *dev, int phy_id) | |||
436 | struct expander_device *ex = &dev->ex_dev; | 441 | struct expander_device *ex = &dev->ex_dev; |
437 | struct ex_phy *phy = &ex->ex_phy[phy_id]; | 442 | struct ex_phy *phy = &ex->ex_phy[phy_id]; |
438 | 443 | ||
439 | sas_smp_phy_control(dev, phy_id, PHY_FUNC_DISABLE); | 444 | sas_smp_phy_control(dev, phy_id, PHY_FUNC_DISABLE, NULL); |
440 | phy->linkrate = SAS_PHY_DISABLED; | 445 | phy->linkrate = SAS_PHY_DISABLED; |
441 | } | 446 | } |
442 | 447 | ||
@@ -731,7 +736,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) | |||
731 | 736 | ||
732 | /* Phy state */ | 737 | /* Phy state */ |
733 | if (ex_phy->linkrate == SAS_SATA_SPINUP_HOLD) { | 738 | if (ex_phy->linkrate == SAS_SATA_SPINUP_HOLD) { |
734 | if (!sas_smp_phy_control(dev, phy_id, PHY_FUNC_LINK_RESET)) | 739 | if (!sas_smp_phy_control(dev, phy_id, PHY_FUNC_LINK_RESET, NULL)) |
735 | res = sas_ex_phy_discover(dev, phy_id); | 740 | res = sas_ex_phy_discover(dev, phy_id); |
736 | if (res) | 741 | if (res) |
737 | return res; | 742 | return res; |
@@ -1706,6 +1711,7 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id) | |||
1706 | SAS_ADDR(phy->attached_sas_addr)) { | 1711 | SAS_ADDR(phy->attached_sas_addr)) { |
1707 | SAS_DPRINTK("ex %016llx phy 0x%x broadcast flutter\n", | 1712 | SAS_DPRINTK("ex %016llx phy 0x%x broadcast flutter\n", |
1708 | SAS_ADDR(dev->sas_addr), phy_id); | 1713 | SAS_ADDR(dev->sas_addr), phy_id); |
1714 | sas_ex_phy_discover(dev, phy_id); | ||
1709 | } else | 1715 | } else |
1710 | res = sas_discover_new(dev, phy_id); | 1716 | res = sas_discover_new(dev, phy_id); |
1711 | out: | 1717 | out: |