All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2 #upstream] ahci: preserve PORTS_IMPL over host resets
@ 2006-11-02  3:17 Tejun Heo
  2006-11-02  3:20 ` [PATCH 2/2 #upstream] ahci: honor PORTS_IMPL on ICH8s Tejun Heo
  2006-11-07  9:46 ` [PATCH 1/2 #upstream] ahci: preserve PORTS_IMPL over host resets Jeff Garzik
  0 siblings, 2 replies; 8+ messages in thread
From: Tejun Heo @ 2006-11-02  3:17 UTC (permalink / raw)
  To: Jeff Garzik, robbat2; +Cc: linux-ide

Instead of writing 0xf blindly, preserve the content of write-once
PORTS_IMPL register over host resets.

This patch is taken from Jeff Garzik's AHCI init update patch.

Signed-off-by: Tejun Heo <htejun@gmail.com>
---
Protection against 0 PI is added as suggested in the following
message.

    http://article.gmane.org/gmane.linux.ide/13365

 drivers/ata/ahci.c |   23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

Index: work/drivers/ata/ahci.c
===================================================================
--- work.orig/drivers/ata/ahci.c
+++ work/drivers/ata/ahci.c
@@ -389,6 +389,11 @@ static struct pci_driver ahci_pci_driver
 };
 
 
+static inline int ahci_nr_ports(u32 cap)
+{
+	return (cap & 0x1f) + 1;
+}
+
 static inline unsigned long ahci_port_base_ul (unsigned long base, unsigned int port)
 {
 	return base + 0x100 + (port * 0x80);
@@ -598,11 +603,12 @@ static int ahci_deinit_port(void __iomem
 
 static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
 {
-	u32 cap_save, tmp;
+	u32 cap_save, impl_save, tmp;
 
 	cap_save = readl(mmio + HOST_CAP);
 	cap_save &= ( (1<<28) | (1<<17) );
 	cap_save |= (1 << 27);
+	impl_save = readl(mmio + HOST_PORTS_IMPL);
 
 	/* global controller reset */
 	tmp = readl(mmio + HOST_CTL);
@@ -623,10 +629,21 @@ static int ahci_reset_controller(void __
 		return -EIO;
 	}
 
+	/* turn on AHCI mode */
 	writel(HOST_AHCI_EN, mmio + HOST_CTL);
 	(void) readl(mmio + HOST_CTL);	/* flush */
+
+	/* These write-once registers are normally cleared on reset.
+	 * Restore BIOS values... which we HOPE were present before
+	 * reset.
+	 */
+	if (!impl_save) {
+		impl_save = (1 << ahci_nr_ports(cap_save)) - 1;
+		dev_printk(KERN_WARNING, &pdev->dev,
+			   "PORTS_IMPL is zero, forcing 0x%x\n", impl_save);
+	}
 	writel(cap_save, mmio + HOST_CAP);
-	writel(0xf, mmio + HOST_PORTS_IMPL);
+	writel(impl_save, mmio + HOST_PORTS_IMPL);
 	(void) readl(mmio + HOST_PORTS_IMPL);	/* flush */
 
 	if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
@@ -1431,7 +1448,7 @@ static int ahci_host_init(struct ata_pro
 
 	hpriv->cap = readl(mmio + HOST_CAP);
 	hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
-	probe_ent->n_ports = (hpriv->cap & 0x1f) + 1;
+	probe_ent->n_ports = ahci_nr_ports(hpriv->cap);
 
 	VPRINTK("cap 0x%x  port_map 0x%x  n_ports %d\n",
 		hpriv->cap, hpriv->port_map, probe_ent->n_ports);

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2006-11-14 18:46 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-02  3:17 [PATCH 1/2 #upstream] ahci: preserve PORTS_IMPL over host resets Tejun Heo
2006-11-02  3:20 ` [PATCH 2/2 #upstream] ahci: honor PORTS_IMPL on ICH8s Tejun Heo
2006-11-06  1:05   ` Robin H. Johnson
2006-11-07  9:54     ` Tejun Heo
2006-11-09  6:08     ` Tejun Heo
2006-11-11  2:37       ` Tejun Heo
2006-11-14 18:45       ` Jeff Garzik
2006-11-07  9:46 ` [PATCH 1/2 #upstream] ahci: preserve PORTS_IMPL over host resets Jeff Garzik

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.