This patch requires "libsas: Add a sysfs knob to enable/disable a phy" to be applied. It hooks the SControl write function to provide basic SATA phy control for phy enable/disable and speed limits. Power management is still broken, though it is unclear that libata actually uses those SControl bits anyway. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- drivers/scsi/libsas/sas_ata.c | 42 ++++++++++++++++++++++++++++++++++- drivers/scsi/libsas/sas_scsi_host.c | 1 + 2 files changed, 42 insertions(+), 1 deletions(-) diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 16c3e5a..2bb619e 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -270,6 +270,46 @@ static void sas_ata_tf_read(struct ata_p memcpy(tf, &dev->sata_dev.tf, sizeof (*tf)); } +static void sas_ata_scontrol_write(struct domain_device *dev, u32 val) +{ + u32 tmp = dev->sata_dev.scontrol; + struct sas_phy *phy = dev->port->phy; + + val &= 0x0FF; /* only set max spd and dev ctrl */ + val |= 0x300; /* disallow host pm */ + val |= tmp & 0xFFFFF000; /* preserve upper bits */ + + /* disable phy */ + if ((val & 0x4) && !(tmp & 0x4)) + sas_phy_enable(phy, 0); + + /* enable phy */ + if (!(val & 0x4) && (tmp & 0x4)) + sas_phy_enable(phy, 1); + + /* reset phy */ + if ((val & 0x1) && !(tmp & 0x1)) + sas_phy_reset(phy, 0); + + /* speed limit */ + if ((val & 0xF0) != (tmp & 0xF0)) { + struct sas_phy_linkrates rates = {0}; + + switch ((val & 0xF0) >> 4) { + case 0: + case 2: + rates.maximum_linkrate = SAS_LINK_RATE_3_0_GBPS; + break; + case 1: + rates.maximum_linkrate = SAS_LINK_RATE_1_5_GBPS; + break; + } + sas_set_phy_speed(phy, &rates); + } + + dev->sata_dev.scontrol = val; +} + static void sas_ata_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) { @@ -281,7 +321,7 @@ static void sas_ata_scr_write(struct ata dev->sata_dev.sstatus = val; break; case SCR_CONTROL: - dev->sata_dev.scontrol = val; + sas_ata_scontrol_write(dev, val); break; case SCR_ERROR: dev->sata_dev.serror = val; diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index fee9c10..5b0c471 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -1040,3 +1040,4 @@ EXPORT_SYMBOL_GPL(sas_eh_device_reset_ha EXPORT_SYMBOL_GPL(sas_slave_alloc); EXPORT_SYMBOL_GPL(sas_target_destroy); EXPORT_SYMBOL_GPL(sas_ioctl); +EXPORT_SYMBOL_GPL(sas_set_phy_speed); - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html