From owner-svn-src-stable@FreeBSD.ORG Mon Jul 8 17:20:05 2013 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 8FDD5BE2; Mon, 8 Jul 2013 17:20:05 +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 808411DB1; Mon, 8 Jul 2013 17:20:05 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r68HK5kR048859; Mon, 8 Jul 2013 17:20:05 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r68HK5Sk048858; Mon, 8 Jul 2013 17:20:05 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201307081720.r68HK5Sk048858@svn.freebsd.org> From: Alexander Motin Date: Mon, 8 Jul 2013 17:20:05 +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: r253041 - stable/9/sys/dev/ata/chipsets X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 08 Jul 2013 17:20:05 -0000 Author: mav Date: Mon Jul 8 17:20:05 2013 New Revision: 253041 URL: http://svnweb.freebsd.org/changeset/base/253041 Log: MFC r252203: Add test for SATA registers writability and skip using them if it failed. There are some systems reported, where PCI BAR(5), used for SATA registers access, is present, but not functional. Attempt to use it brakes devices detection logic. Try to detect those cases on attach by setting and testing some bits in SControl register. If bits are unsettable, fallback to legacy ATA without hot-plug detection, speed control/reporting, etc. Modified: stable/9/sys/dev/ata/chipsets/ata-intel.c Directory Properties: stable/9/sys/ (props changed) stable/9/sys/dev/ (props changed) Modified: stable/9/sys/dev/ata/chipsets/ata-intel.c ============================================================================== --- stable/9/sys/dev/ata/chipsets/ata-intel.c Mon Jul 8 16:03:18 2013 (r253040) +++ stable/9/sys/dev/ata/chipsets/ata-intel.c Mon Jul 8 17:20:05 2013 (r253041) @@ -73,6 +73,7 @@ static int ata_intel_sata_cscr_write(dev int reg, u_int32_t result); static int ata_intel_sata_sidpr_write(device_t dev, int port, int reg, u_int32_t result); +static int ata_intel_sata_sidpr_test(device_t dev); static int ata_intel_31244_ch_attach(device_t dev); static int ata_intel_31244_ch_detach(device_t dev); static int ata_intel_31244_status(device_t dev); @@ -417,22 +418,20 @@ ata_intel_ch_attach(device_t dev) } if (ch->flags & ATA_SATA) { if ((ctlr->chip->cfg1 & INTEL_ICH5)) { - ch->flags |= ATA_PERIODIC_POLL; - ch->hw.status = ata_intel_sata_status; ch->hw.pm_read = ata_intel_sata_cscr_read; ch->hw.pm_write = ata_intel_sata_cscr_write; } else if (ctlr->r_res2) { - ch->flags |= ATA_PERIODIC_POLL; - ch->hw.status = ata_intel_sata_status; if ((ctlr->chip->cfg1 & INTEL_ICH7)) { ch->hw.pm_read = ata_intel_sata_ahci_read; ch->hw.pm_write = ata_intel_sata_ahci_write; - } else { + } else if (ata_intel_sata_sidpr_test(dev)) { ch->hw.pm_read = ata_intel_sata_sidpr_read; ch->hw.pm_write = ata_intel_sata_sidpr_write; }; } if (ch->hw.pm_write != NULL) { + ch->flags |= ATA_PERIODIC_POLL; + ch->hw.status = ata_intel_sata_status; ata_sata_scr_write(ch, 0, ATA_SERROR, 0xffffffff); if ((ch->flags & ATA_NO_SLAVE) == 0) { @@ -836,6 +835,32 @@ ata_intel_sata_sidpr_write(device_t dev, } static int +ata_intel_sata_sidpr_test(device_t dev) +{ + struct ata_channel *ch = device_get_softc(dev); + int port; + uint32_t val; + + port = (ch->flags & ATA_NO_SLAVE) ? 0 : 1; + for (; port >= 0; port--) { + ata_intel_sata_sidpr_read(dev, port, ATA_SCONTROL, &val); + if ((val & ATA_SC_IPM_MASK) == + (ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER)) + return (1); + val |= ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER; + ata_intel_sata_sidpr_write(dev, port, ATA_SCONTROL, val); + ata_intel_sata_sidpr_read(dev, port, ATA_SCONTROL, &val); + if ((val & ATA_SC_IPM_MASK) == + (ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER)) + return (1); + } + if (bootverbose) + device_printf(dev, + "SControl registers are not functional: %08x\n", val); + return (0); +} + +static int ata_intel_31244_ch_attach(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));