From owner-svn-src-all@FreeBSD.ORG Fri Nov 16 02:26:23 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id CBA43CA5; Fri, 16 Nov 2012 02:26:23 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id AE3468FC08; Fri, 16 Nov 2012 02:26:23 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qAG2QNTo099651; Fri, 16 Nov 2012 02:26:23 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qAG2QNPC099647; Fri, 16 Nov 2012 02:26:23 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201211160226.qAG2QNPC099647@svn.freebsd.org> From: Alexander Motin Date: Fri, 16 Nov 2012 02:26:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r243118 - in stable/9: share/man/man4 sys/dev/ata X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Nov 2012 02:26:24 -0000 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);