Merge branch 'for-2.6.19' of git://brick.kernel.dk/data/git/linux-2.6-block
[powerpc.git] / drivers / scsi / aic94xx / aic94xx_scb.c
index fc1b743..7ee49b5 100644 (file)
 
 static inline void get_lrate_mode(struct asd_phy *phy, u8 oob_mode)
 {
+       struct sas_phy *sas_phy = phy->sas_phy.phy;
+
        switch (oob_mode & 7) {
        case PHY_SPEED_60:
                /* FIXME: sas transport class doesn't have this */
-               phy->sas_phy.linkrate = PHY_LINKRATE_6;
+               phy->sas_phy.linkrate = SAS_LINK_RATE_6_0_GBPS;
                phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_6_0_GBPS;
                break;
        case PHY_SPEED_30:
-               phy->sas_phy.linkrate = PHY_LINKRATE_3;
+               phy->sas_phy.linkrate = SAS_LINK_RATE_3_0_GBPS;
                phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
                break;
        case PHY_SPEED_15:
-               phy->sas_phy.linkrate = PHY_LINKRATE_1_5;
+               phy->sas_phy.linkrate = SAS_LINK_RATE_1_5_GBPS;
                phy->sas_phy.phy->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
                break;
        }
+       sas_phy->negotiated_linkrate = phy->sas_phy.linkrate;
+       sas_phy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
+       sas_phy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
+       sas_phy->maximum_linkrate = phy->phy_desc->max_sas_lrate;
+       sas_phy->minimum_linkrate = phy->phy_desc->min_sas_lrate;
+
        if (oob_mode & SAS_MODE)
                phy->sas_phy.oob_mode = SAS_OOB_MODE;
        else if (oob_mode & SATA_MODE)
@@ -540,39 +548,39 @@ static inline void set_speed_mask(u8 *speed_mask, struct asd_phy_desc *pd)
                | SATA_SPEED_30_DIS | SATA_SPEED_15_DIS;
 
        switch (pd->max_sas_lrate) {
-       case PHY_LINKRATE_6:
+       case SAS_LINK_RATE_6_0_GBPS:
                *speed_mask &= ~SAS_SPEED_60_DIS;
        default:
-       case PHY_LINKRATE_3:
+       case SAS_LINK_RATE_3_0_GBPS:
                *speed_mask &= ~SAS_SPEED_30_DIS;
-       case PHY_LINKRATE_1_5:
+       case SAS_LINK_RATE_1_5_GBPS:
                *speed_mask &= ~SAS_SPEED_15_DIS;
        }
 
        switch (pd->min_sas_lrate) {
-       case PHY_LINKRATE_6:
+       case SAS_LINK_RATE_6_0_GBPS:
                *speed_mask |= SAS_SPEED_30_DIS;
-       case PHY_LINKRATE_3:
+       case SAS_LINK_RATE_3_0_GBPS:
                *speed_mask |= SAS_SPEED_15_DIS;
        default:
-       case PHY_LINKRATE_1_5:
+       case SAS_LINK_RATE_1_5_GBPS:
                /* nothing to do */
                ;
        }
 
        switch (pd->max_sata_lrate) {
-       case PHY_LINKRATE_3:
+       case SAS_LINK_RATE_3_0_GBPS:
                *speed_mask &= ~SATA_SPEED_30_DIS;
        default:
-       case PHY_LINKRATE_1_5:
+       case SAS_LINK_RATE_1_5_GBPS:
                *speed_mask &= ~SATA_SPEED_15_DIS;
        }
 
        switch (pd->min_sata_lrate) {
-       case PHY_LINKRATE_3:
+       case SAS_LINK_RATE_3_0_GBPS:
                *speed_mask |= SATA_SPEED_15_DIS;
        default:
-       case PHY_LINKRATE_1_5:
+       case SAS_LINK_RATE_1_5_GBPS:
                /* nothing to do */
                ;
        }
@@ -710,14 +718,32 @@ static const int phy_func_table[] = {
        [PHY_FUNC_RELEASE_SPINUP_HOLD] = RELEASE_SPINUP_HOLD,
 };
 
-int asd_control_phy(struct asd_sas_phy *phy, enum phy_func func)
+int asd_control_phy(struct asd_sas_phy *phy, enum phy_func func, void *arg)
 {
        struct asd_ha_struct *asd_ha = phy->ha->lldd_ha;
+       struct asd_phy_desc *pd = asd_ha->phys[phy->id].phy_desc;
        struct asd_ascb *ascb;
+       struct sas_phy_linkrates *rates;
        int res = 1;
 
-       if (func == PHY_FUNC_CLEAR_ERROR_LOG)
+       switch (func) {
+       case PHY_FUNC_CLEAR_ERROR_LOG:
                return -ENOSYS;
+       case PHY_FUNC_SET_LINK_RATE:
+               rates = arg;
+               if (rates->minimum_linkrate) {
+                       pd->min_sas_lrate = rates->minimum_linkrate;
+                       pd->min_sata_lrate = rates->minimum_linkrate;
+               }
+               if (rates->maximum_linkrate) {
+                       pd->max_sas_lrate = rates->maximum_linkrate;
+                       pd->max_sata_lrate = rates->maximum_linkrate;
+               }
+               func = PHY_FUNC_LINK_RESET;
+               break;
+       default:
+               break;
+       }
 
        ascb = asd_ascb_alloc_list(asd_ha, &res, GFP_KERNEL);
        if (!ascb)