From owner-svn-src-all@FreeBSD.ORG Thu Jun 9 16:30:14 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 38B061065670; Thu, 9 Jun 2011 16:30:14 +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 0F6C08FC13; Thu, 9 Jun 2011 16:30:14 +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 p59GUDKb086253; Thu, 9 Jun 2011 16:30:13 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p59GUDGP086251; Thu, 9 Jun 2011 16:30:13 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201106091630.p59GUDGP086251@svn.freebsd.org> From: Alexander Motin Date: Thu, 9 Jun 2011 16:30:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r222897 - head/sys/dev/ata X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 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: Thu, 09 Jun 2011 16:30:14 -0000 Author: mav Date: Thu Jun 9 16:30:13 2011 New Revision: 222897 URL: http://svn.freebsd.org/changeset/base/222897 Log: 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: head/sys/dev/ata/ata-sata.c Modified: head/sys/dev/ata/ata-sata.c ============================================================================== --- head/sys/dev/ata/ata-sata.c Thu Jun 9 11:54:11 2011 (r222896) +++ head/sys/dev/ata/ata-sata.c Thu Jun 9 16:30:13 2011 (r222897) @@ -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