From ed08d40cdec45f3f1071fa4679127d4b76dc8986 Mon Sep 17 00:00:00 2001 From: Chuansheng Liu Date: Wed, 18 Sep 2013 20:21:49 +0800 Subject: ahci: Changing two module params with static and __read_mostly Here module parameters ahci_em_messages and devslp_idle_timeout can be set as static and __read_mostly. Signed-off-by: Liu, Chuansheng Signed-off-by: Tejun Heo --- drivers/ata/libahci.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/ata/libahci.c') diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index acfd0f7..b67086f 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -189,14 +189,15 @@ struct ata_port_operations ahci_pmp_retry_srst_ops = { }; EXPORT_SYMBOL_GPL(ahci_pmp_retry_srst_ops); -int ahci_em_messages = 1; +static bool ahci_em_messages __read_mostly = true; EXPORT_SYMBOL_GPL(ahci_em_messages); -module_param(ahci_em_messages, int, 0444); +module_param(ahci_em_messages, bool, 0444); /* add other LED protocol types when they become supported */ MODULE_PARM_DESC(ahci_em_messages, "AHCI Enclosure Management Message control (0 = off, 1 = on)"); -int devslp_idle_timeout = 1000; /* device sleep idle timeout in ms */ +/* device sleep idle timeout in ms */ +static int devslp_idle_timeout __read_mostly = 1000; module_param(devslp_idle_timeout, int, 0644); MODULE_PARM_DESC(devslp_idle_timeout, "device sleep idle timeout"); -- cgit v1.1 From 8b789d89813fae01908ecc825c9dfc0ec90647ad Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Tue, 15 Oct 2013 10:44:54 +0800 Subject: ahci: imx: setup power saving methods In order to save power consumption as much as possible. * Disable sata phy internal pll reference clock when sysetem enter into suspend mode, enable it after resume. * Setup module parameter used to enable imx ahci test power down mode(PDDQ) or not, when there is no device detected on the port * minor modifications: - The format of the copyright is changed, because that the original one can't pass fsl internal patch reivew without the character '(c)'. - Exports ahci_platform_ops and ahci_error_handler(). NOTE: * The hot-plug can't be supported when PDDQ mode is ever enabled. * module parameter usage how-to: - default: enable PDDQ mode when no device detected. - add "ahci-imx.hotplug=1" into kernel command line if your don't want to enable PDDQ mode when no device detected on the port. tj: Slightly updated description and comments. Signed-off-by: Richard Zhu Signed-off-by: Tejun Heo --- drivers/ata/libahci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/ata/libahci.c') diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index b67086f..7e2a1b3 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -89,7 +89,6 @@ static int ahci_pmp_retry_softreset(struct ata_link *link, unsigned int *class, static int ahci_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline); static void ahci_postreset(struct ata_link *link, unsigned int *class); -static void ahci_error_handler(struct ata_port *ap); static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); static void ahci_dev_config(struct ata_device *dev); #ifdef CONFIG_PM @@ -1982,7 +1981,7 @@ static void ahci_thaw(struct ata_port *ap) writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); } -static void ahci_error_handler(struct ata_port *ap) +void ahci_error_handler(struct ata_port *ap) { if (!(ap->pflags & ATA_PFLAG_FROZEN)) { /* restart engine */ @@ -1995,6 +1994,7 @@ static void ahci_error_handler(struct ata_port *ap) if (!ata_dev_enabled(ap->link.device)) ahci_stop_engine(ap); } +EXPORT_SYMBOL_GPL(ahci_error_handler); static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) { -- cgit v1.1 From 89dafa20f3daab5b3e0c13d0068a28e8e64e2102 Mon Sep 17 00:00:00 2001 From: xiangliang yu Date: Sun, 27 Oct 2013 08:03:04 -0400 Subject: ahci: disabled FBS prior to issuing software reset Tested with Marvell 88se9125, attached with one port mulitplier(5 ports) and one disk, we will get following boot log messages if using current code: ata8: SATA link up 6.0 Gbps (SStatus 133 SControl 330) ata8.15: Port Multiplier 1.2, 0x1b4b:0x9715 r160, 5 ports, feat 0x1/0x1f ahci 0000:03:00.0: FBS is enabled ata8.00: hard resetting link ata8.00: SATA link down (SStatus 0 SControl 330) ata8.01: hard resetting link ata8.01: SATA link down (SStatus 0 SControl 330) ata8.02: hard resetting link ata8.02: SATA link down (SStatus 0 SControl 330) ata8.03: hard resetting link ata8.03: SATA link up 6.0 Gbps (SStatus 133 SControl 133) ata8.04: hard resetting link ata8.04: failed to resume link (SControl 133) ata8.04: failed to read SCR 0 (Emask=0x40) ata8.04: failed to read SCR 0 (Emask=0x40) ata8.04: failed to read SCR 1 (Emask=0x40) ata8.04: failed to read SCR 0 (Emask=0x40) ata8.03: native sectors (2) is smaller than sectors (976773168) ata8.03: ATA-8: ST3500413AS, JC4B, max UDMA/133 ata8.03: 976773168 sectors, multi 0: LBA48 NCQ (depth 31/32) ata8.03: configured for UDMA/133 ata8.04: failed to IDENTIFY (I/O error, err_mask=0x100) ata8.15: hard resetting link ata8.15: SATA link up 6.0 Gbps (SStatus 133 SControl 330) ata8.15: Port Multiplier vendor mismatch '0x1b4b' != '0x133' ata8.15: PMP revalidation failed (errno=-19) ata8.15: hard resetting link ata8.15: SATA link up 6.0 Gbps (SStatus 133 SControl 330) ata8.15: Port Multiplier vendor mismatch '0x1b4b' != '0x133' ata8.15: PMP revalidation failed (errno=-19) ata8.15: limiting SATA link speed to 3.0 Gbps ata8.15: hard resetting link ata8.15: SATA link up 3.0 Gbps (SStatus 123 SControl 320) ata8.15: Port Multiplier vendor mismatch '0x1b4b' != '0x133' ata8.15: PMP revalidation failed (errno=-19) ata8.15: failed to recover PMP after 5 tries, giving up ata8.15: Port Multiplier detaching ata8.03: disabled ata8.00: disabled ata8: EH complete The reason is that current detection code doesn't follow AHCI spec: First,the port multiplier detection process look like this: ahci_hardreset(link, class, deadline) if (class == ATA_DEV_PMP) { sata_pmp_attach(dev) /* will enable FBS */ sata_pmp_init_links(ap, nr_ports); ata_for_each_link(link, ap, EDGE) { sata_std_hardreset(link, class, deadline); if (link_is_online) /* do soft reset */ ahci_softreset(link, class, deadline); } } But, according to chapter 9.3.9 in AHCI spec: Prior to issuing software reset, software shall clear PxCMD.ST to '0' and then clear PxFBS.EN to '0'. The patch test ok with kernel 3.11.1. tj: Patch white space contaminated, applied manually with trivial updates. Signed-off-by: Xiangliang Yu Signed-off-by: Tejun Heo Cc: stable@vger.kernel.org --- drivers/ata/libahci.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers/ata/libahci.c') diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 7e2a1b3..6686dbe 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -1267,9 +1267,11 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class, { struct ata_port *ap = link->ap; struct ahci_host_priv *hpriv = ap->host->private_data; + struct ahci_port_priv *pp = ap->private_data; const char *reason = NULL; unsigned long now, msecs; struct ata_taskfile tf; + bool fbs_disabled = false; int rc; DPRINTK("ENTER\n"); @@ -1279,6 +1281,16 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class, if (rc && rc != -EOPNOTSUPP) ata_link_warn(link, "failed to reset engine (errno=%d)\n", rc); + /* + * According to AHCI-1.2 9.3.9: if FBS is enable, software shall + * clear PxFBS.EN to '0' prior to issuing software reset to devices + * that is attached to port multiplier. + */ + if (!ata_is_host_link(link) && pp->fbs_enabled) { + ahci_disable_fbs(ap); + fbs_disabled = true; + } + ata_tf_init(link->device, &tf); /* issue the first D2H Register FIS */ @@ -1319,6 +1331,10 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class, } else *class = ahci_dev_classify(ap); + /* re-enable FBS if disabled before */ + if (fbs_disabled) + ahci_enable_fbs(ap); + DPRINTK("EXIT, class=%u\n", *class); return 0; -- cgit v1.1