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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to