From owner-svn-src-stable-8@FreeBSD.ORG Fri Nov 16 03:02:08 2012 Return-Path: Delivered-To: svn-src-stable-8@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 13116D1C; Fri, 16 Nov 2012 03:02:08 +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 E237F8FC12; Fri, 16 Nov 2012 03:02:07 +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 qAG32723004974; Fri, 16 Nov 2012 03:02:07 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qAG327mK004970; Fri, 16 Nov 2012 03:02:07 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201211160302.qAG327mK004970@svn.freebsd.org> From: Alexander Motin Date: Fri, 16 Nov 2012 03:02:07 +0000 (UTC) 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 X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-8@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for only the 8-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Nov 2012 03:02:08 -0000 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);