diff options
Diffstat (limited to 'drivers/scsi/aic94xx/aic94xx_scb.c')
-rw-r--r-- | drivers/scsi/aic94xx/aic94xx_scb.c | 30 |
1 files changed, 28 insertions, 2 deletions
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 | ||
53 | static inline void get_lrate_mode(struct asd_phy *phy, u8 oob_mode) | 53 | static 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 | ||
713 | int asd_control_phy(struct asd_sas_phy *phy, enum phy_func func) | 721 | int 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) |