svn commit: r243118 - in stable/9: share/man/man4 sys/dev/ata

Alexander Motin mav at FreeBSD.org
Fri Nov 16 02:26:24 UTC 2012


Author: mav
Date: Fri Nov 16 02:26:23 2012
New Revision: 243118
URL: http://svnweb.freebsd.org/changeset/base/243118

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/9/share/man/man4/ata.4
  stable/9/sys/dev/ata/ata-all.c
  stable/9/sys/dev/ata/ata-all.h
  stable/9/sys/dev/ata/ata-sata.c
Directory Properties:
  stable/9/share/man/man4/   (props changed)
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)

Modified: stable/9/share/man/man4/ata.4
==============================================================================
--- stable/9/share/man/man4/ata.4	Fri Nov 16 01:43:23 2012	(r243117)
+++ stable/9/share/man/man4/ata.4	Fri Nov 16 02:26:23 2012	(r243118)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 18, 2012
+.Dd October 3, 2012
 .Dt ATA 4
 .Os
 .Sh NAME
@@ -99,7 +99,7 @@ set to 0 to disable the 80pin cable chec
 set to 1 to allow Message Signalled Interrupts (MSI) to be used by the
 specified PCI ATA controller, if supported.
 .It Va hint.ata.X.devX.mode
-limits the initial ATA mode for the specified device on specified the channel.
+limits the initial ATA mode for the specified device on the specified channel.
 .It Va hint.ata.X.mode
 limits the initial ATA mode for every device on the specified channel.
 .It Va hint.ata.X.pm_level
@@ -118,6 +118,12 @@ The host initiates a PARTIAL PM state tr
 host initiates SLUMBER PM state transition every time port becomes idle.
 .El
 Modes 2 and 3 are only supported for AHCI.
+.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/9/sys/dev/ata/ata-all.c
==============================================================================
--- stable/9/sys/dev/ata/ata-all.c	Fri Nov 16 01:43:23 2012	(r243117)
+++ stable/9/sys/dev/ata/ata-all.c	Fri Nov 16 02:26:23 2012	(r243118)
@@ -172,6 +172,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/9/sys/dev/ata/ata-all.h
==============================================================================
--- stable/9/sys/dev/ata/ata-all.h	Fri Nov 16 01:43:23 2012	(r243117)
+++ stable/9/sys/dev/ata/ata-all.h	Fri Nov 16 02:26:23 2012	(r243118)
@@ -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/9/sys/dev/ata/ata-sata.c
==============================================================================
--- stable/9/sys/dev/ata/ata-sata.c	Fri Nov 16 01:43:23 2012	(r243117)
+++ stable/9/sys/dev/ata/ata-sata.c	Fri Nov 16 02:26:23 2012	(r243118)
@@ -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);


More information about the svn-src-stable-9 mailing list