From owner-svn-src-stable-8@FreeBSD.ORG Tue Jun 21 08:37:56 2011 Return-Path: Delivered-To: svn-src-stable-8@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1FAB61065673; Tue, 21 Jun 2011 08:37:56 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E9C618FC14; Tue, 21 Jun 2011 08:37:55 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p5L8bti9088150; Tue, 21 Jun 2011 08:37:55 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p5L8btRY088148; Tue, 21 Jun 2011 08:37:55 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201106210837.p5L8btRY088148@svn.freebsd.org> From: Alexander Motin Date: Tue, 21 Jun 2011 08:37:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r223360 - stable/8/sys/dev/ata X-BeenThere: svn-src-stable-8@freebsd.org X-Mailman-Version: 2.1.5 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: Tue, 21 Jun 2011 08:37:56 -0000 Author: mav Date: Tue Jun 21 08:37:55 2011 New Revision: 223360 URL: http://svn.freebsd.org/changeset/base/223360 Log: MFC r222897: Intel NM10 chipset's SATA controller has same PCI ID and revision as ICH7's, but has only 2 SATA ports instead of 4. The worst part is that SStatus and SError registers for missing ports are not implemented and return wrong values (0xffffffff), that caused infinite reset loop. Just ignore that SError value while I found no better way to identify them. Modified: stable/8/sys/dev/ata/ata-sata.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/dev/ata/ata-sata.c ============================================================================== --- stable/8/sys/dev/ata/ata-sata.c Tue Jun 21 07:19:03 2011 (r223359) +++ stable/8/sys/dev/ata/ata-sata.c Tue Jun 21 08:37:55 2011 (r223360) @@ -54,6 +54,11 @@ ata_sata_phy_check_events(device_t dev, u_int32_t error, status; ata_sata_scr_read(ch, port, ATA_SERROR, &error); + + /* Check that SError value is sane. */ + if (error == 0xffffffff) + return; + /* Clear set error bits/interrupt. */ if (error) ata_sata_scr_write(ch, port, ATA_SERROR, error); @@ -163,18 +168,18 @@ ata_sata_phy_reset(device_t dev, int por if (bootverbose) { if (port < 0) { - device_printf(dev, "hardware reset ...\n"); + device_printf(dev, "hard reset ...\n"); } else { - device_printf(dev, "p%d: hardware reset ...\n", port); + device_printf(dev, "p%d: hard reset ...\n", port); } } 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)) - return (0); + goto fail; ata_udelay(100); if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val)) - return (0); + goto fail; if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_RESET) break; } @@ -183,15 +188,26 @@ ata_sata_phy_reset(device_t dev, int por if (ata_sata_scr_write(ch, port, ATA_SCONTROL, ATA_SC_DET_IDLE | ((ch->pm_level > 0) ? 0 : ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER))) - return (0); + goto fail; ata_udelay(100); if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val)) - return (0); + goto fail; if ((val & ATA_SC_DET_MASK) == 0) return ata_sata_connect(ch, port, 0); } } - return 0; +fail: + /* Clear SATA error register. */ + ata_sata_scr_write(ch, port, ATA_SERROR, 0xffffffff); + + if (bootverbose) { + if (port < 0) { + device_printf(dev, "hard reset failed\n"); + } else { + device_printf(dev, "p%d: hard reset failed\n", port); + } + } + return (0); } int