aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas/sas_expander.c
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@steeleye.com>2006-09-06 20:28:07 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-09-07 16:20:23 -0400
commita01e70e570a72b8a8c9a58062e4f5bdcd3986222 (patch)
treed2b8b5e0e69d14805ac98033561597de6e24d5c6 /drivers/scsi/libsas/sas_expander.c
parentd24e1eeb3a16e4944288c2f3bf082e1513f4b425 (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.c20
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
406int sas_smp_phy_control(struct domain_device *dev, int phy_id, 406int 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);
1711out: 1717out: