Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Nov 2012 03:02:07 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r243124 - in stable/8: share/man/man4 sys/dev/ata
Message-ID:  <201211160302.qAG327mK004970@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Fri Nov 16 03:02:07 2012
New Revision: 243124
URL: http://svnweb.freebsd.org/changeset/base/243124

Log:
  MFC r241144, r241160:
  Implement SATA revision (speed) control for legacy SATA controller for
  both boot (via loader tunables) and run-time (via `camcontrol negotiate`).
  Tested to work at least on NVIDIA MCP55 chipset.

Modified:
  stable/8/share/man/man4/ata.4
  stable/8/sys/dev/ata/ata-all.c
  stable/8/sys/dev/ata/ata-all.h
  stable/8/sys/dev/ata/ata-sata.c
Directory Properties:
  stable/8/share/man/man4/   (props changed)
  stable/8/sys/   (props changed)
  stable/8/sys/dev/   (props changed)
  stable/8/sys/dev/ata/   (props changed)

Modified: stable/8/share/man/man4/ata.4
==============================================================================
--- stable/8/share/man/man4/ata.4	Fri Nov 16 03:00:25 2012	(r243123)
+++ stable/8/share/man/man4/ata.4	Fri Nov 16 03:02:07 2012	(r243124)
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 18, 2012
+.Dd October 3, 2012
 .Dt ATA 4
 .Os
 .Sh NAME
@@ -108,7 +108,7 @@ can cause data loss on power failures an
 set to 1 to allow Message Signalled Interrupts (MSI) to be used by
 specified PCI ATA controller, if supported.
 .It Va hint.ata.X.devX.mode
-limits initial ATA mode for specified device on specified channel.
+limits the initial ATA mode for the specified device on the specified channel.
 .It Va hint.ata.X.mode
 limits initial ATA mode for every device on specified channel.
 .It Va hint.ata.X.pm_level
@@ -126,6 +126,12 @@ host initiates PARTIAL PM state transiti
 host initiates SLUMBER PM state transition every time port becomes idle.
 .El
 Modes 2 and 3 are implemented only for AHCI driver now.
+.It Va hint.ata. Ns Ar X Ns Va .dev Ns Ar X Ns Va .sata_rev
+limits the initial SATA revision (speed) for the specified device
+on the specified channel.
+Values 1, 2 and 3 are respectively 1.5, 3 and 6Gbps.
+.It Va hint.ata. Ns Ar X Ns Va .sata_rev
+Same, but for every device on the specified channel.
 .El
 .Sh DESCRIPTION
 The

Modified: stable/8/sys/dev/ata/ata-all.c
==============================================================================
--- stable/8/sys/dev/ata/ata-all.c	Fri Nov 16 03:00:25 2012	(r243123)
+++ stable/8/sys/dev/ata/ata-all.c	Fri Nov 16 03:02:07 2012	(r243124)
@@ -171,6 +171,15 @@ ata_attach(device_t dev)
     TASK_INIT(&ch->conntask, 0, ata_conn_event, dev);
 #ifdef ATA_CAM
 	for (i = 0; i < 16; i++) {
+		ch->user[i].revision = 0;
+		snprintf(buf, sizeof(buf), "dev%d.sata_rev", i);
+		if (resource_int_value(device_get_name(dev),
+		    device_get_unit(dev), buf, &mode) != 0 &&
+		    resource_int_value(device_get_name(dev),
+		    device_get_unit(dev), "sata_rev", &mode) != 0)
+			mode = -1;
+		if (mode >= 0)
+			ch->user[i].revision = mode;
 		ch->user[i].mode = 0;
 		snprintf(buf, sizeof(buf), "dev%d.mode", i);
 		if (resource_string_value(device_get_name(dev),

Modified: stable/8/sys/dev/ata/ata-all.h
==============================================================================
--- stable/8/sys/dev/ata/ata-all.h	Fri Nov 16 03:00:25 2012	(r243123)
+++ stable/8/sys/dev/ata/ata-all.h	Fri Nov 16 03:02:07 2012	(r243124)
@@ -142,6 +142,7 @@
 #define         ATA_SC_SPD_NO_SPEED     0x00000000
 #define         ATA_SC_SPD_SPEED_GEN1   0x00000010
 #define         ATA_SC_SPD_SPEED_GEN2   0x00000020
+#define         ATA_SC_SPD_SPEED_GEN3   0x00000040
 
 #define         ATA_SC_IPM_MASK         0x00000f00
 #define         ATA_SC_IPM_NONE         0x00000000

Modified: stable/8/sys/dev/ata/ata-sata.c
==============================================================================
--- stable/8/sys/dev/ata/ata-sata.c	Fri Nov 16 03:00:25 2012	(r243123)
+++ stable/8/sys/dev/ata/ata-sata.c	Fri Nov 16 03:02:07 2012	(r243124)
@@ -152,8 +152,16 @@ int
 ata_sata_phy_reset(device_t dev, int port, int quick)
 {
     struct ata_channel *ch = device_get_softc(dev);
-    int loop, retry;
-    uint32_t val;
+    int loop, retry, sata_rev;
+    uint32_t val, val1;
+
+#ifdef ATA_CAM
+    sata_rev = ch->user[port < 0 ? 0 : port].revision;
+    if (sata_rev > 0)
+	quick = 0;
+#else
+    sata_rev = 0;
+#endif
 
     if (quick) {
 	if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val))
@@ -173,9 +181,18 @@ ata_sata_phy_reset(device_t dev, int por
 	    device_printf(dev, "p%d: hard reset ...\n", port);
 	}
     }
+    if (sata_rev == 1)
+	val1 = ATA_SC_SPD_SPEED_GEN1;
+    else if (sata_rev == 2)
+	val1 = ATA_SC_SPD_SPEED_GEN2;
+    else if (sata_rev == 3)
+	val1 = ATA_SC_SPD_SPEED_GEN3;
+    else
+	val1 = 0;
     for (retry = 0; retry < 10; retry++) {
 	for (loop = 0; loop < 10; loop++) {
-	    if (ata_sata_scr_write(ch, port, ATA_SCONTROL, ATA_SC_DET_RESET))
+	    if (ata_sata_scr_write(ch, port, ATA_SCONTROL, ATA_SC_DET_RESET |
+		    val1 | ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER))
 		goto fail;
 	    ata_udelay(100);
 	    if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val))
@@ -186,7 +203,7 @@ ata_sata_phy_reset(device_t dev, int por
 	ata_udelay(5000);
 	for (loop = 0; loop < 10; loop++) {
 	    if (ata_sata_scr_write(ch, port, ATA_SCONTROL,
-		    ATA_SC_DET_IDLE | ((ch->pm_level > 0) ? 0 :
+		    ATA_SC_DET_IDLE | val1 | ((ch->pm_level > 0) ? 0 :
 		    ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER)))
 		goto fail;
 	    ata_udelay(100);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201211160302.qAG327mK004970>