aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aic94xx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aic94xx')
-rw-r--r--drivers/scsi/aic94xx/aic94xx.h2
-rw-r--r--drivers/scsi/aic94xx/aic94xx_scb.c30
2 files changed, 29 insertions, 3 deletions
diff --git a/drivers/scsi/aic94xx/aic94xx.h b/drivers/scsi/aic94xx/aic94xx.h
index cb7caf1c9ce1..1bd5b4ecf3d5 100644
--- a/drivers/scsi/aic94xx/aic94xx.h
+++ b/drivers/scsi/aic94xx/aic94xx.h
@@ -109,6 +109,6 @@ int asd_clear_nexus_port(struct asd_sas_port *port);
109int asd_clear_nexus_ha(struct sas_ha_struct *sas_ha); 109int asd_clear_nexus_ha(struct sas_ha_struct *sas_ha);
110 110
111/* ---------- Phy Management ---------- */ 111/* ---------- Phy Management ---------- */
112int asd_control_phy(struct asd_sas_phy *phy, enum phy_func func); 112int asd_control_phy(struct asd_sas_phy *phy, enum phy_func func, void *arg);
113 113
114#endif 114#endif
diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c
index ef8ca08b545f..7ee49b51b724 100644
--- a/drivers/scsi/aic94xx/aic94xx_scb.c
+++ b/drivers/scsi/aic94xx/aic94xx_scb.c
@@ -52,6 +52,8 @@
52 52
53static inline void get_lrate_mode(struct asd_phy *phy, u8 oob_mode) 53static inline void get_lrate_mode(struct asd_phy *phy, u8 oob_mode)
54{ 54{
55 struct sas_phy *sas_phy = phy->sas_phy.phy;
56
55 switch (oob_mode & 7) { 57 switch (oob_mode & 7) {
56 case PHY_SPEED_60: 58 case PHY_SPEED_60:
57 /* FIXME: sas transport class doesn't have this */ 59 /* FIXME: sas transport class doesn't have this */
@@ -67,6 +69,12 @@ static inline void get_lrate_mode(struct asd_phy *phy, u8 oob_mode)
67 phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS; 69 phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
68 break; 70 break;
69 } 71 }
72 sas_phy->negotiated_linkrate = phy->sas_phy.linkrate;
73 sas_phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
74 sas_phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
75 sas_phy->maximum_linkrate = phy->phy_desc->max_sas_lrate;
76 sas_phy->minimum_linkrate = phy->phy_desc->min_sas_lrate;
77
70 if (oob_mode & SAS_MODE) 78 if (oob_mode & SAS_MODE)
71 phy->sas_phy.oob_mode = SAS_OOB_MODE; 79 phy->sas_phy.oob_mode = SAS_OOB_MODE;
72 else if (oob_mode & SATA_MODE) 80 else if (oob_mode & SATA_MODE)
@@ -710,14 +718,32 @@ static const int phy_func_table[] = {
710 [PHY_FUNC_RELEASE_SPINUP_HOLD] = RELEASE_SPINUP_HOLD, 718 [PHY_FUNC_RELEASE_SPINUP_HOLD] = RELEASE_SPINUP_HOLD,
711}; 719};
712 720
713int asd_control_phy(struct asd_sas_phy *phy, enum phy_func func) 721int asd_control_phy(struct asd_sas_phy *phy, enum phy_func func, void *arg)
714{ 722{
715 struct asd_ha_struct *asd_ha = phy->ha->lldd_ha; 723 struct asd_ha_struct *asd_ha = phy->ha->lldd_ha;
724 struct asd_phy_desc *pd = asd_ha->phys[phy->id].phy_desc;
716 struct asd_ascb *ascb; 725 struct asd_ascb *ascb;
726 struct sas_phy_linkrates *rates;
717 int res = 1; 727 int res = 1;
718 728
719 if (func == PHY_FUNC_CLEAR_ERROR_LOG) 729 switch (func) {
730 case PHY_FUNC_CLEAR_ERROR_LOG:
720 return -ENOSYS; 731 return -ENOSYS;
732 case PHY_FUNC_SET_LINK_RATE:
733 rates = arg;
734 if (rates->minimum_linkrate) {
735 pd->min_sas_lrate = rates->minimum_linkrate;
736 pd->min_sata_lrate = rates->minimum_linkrate;
737 }
738 if (rates->maximum_linkrate) {
739 pd->max_sas_lrate = rates->maximum_linkrate;
740 pd->max_sata_lrate = rates->maximum_linkrate;
741 }
742 func = PHY_FUNC_LINK_RESET;
743 break;
744 default:
745 break;
746 }
721 747
722 ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL); 748 ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL);
723 if (!ascb) 749 if (!ascb)