From owner-svn-src-stable@FreeBSD.ORG Wed May 29 04:18:03 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 1632120D; Wed, 29 May 2013 04:18:03 +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 ED647292; Wed, 29 May 2013 04:18:02 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r4T4I2p6097293; Wed, 29 May 2013 04:18:02 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r4T4I28Y097292; Wed, 29 May 2013 04:18:02 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201305290418.r4T4I28Y097292@svn.freebsd.org> From: Alexander Motin Date: Wed, 29 May 2013 04:18:02 +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: r251097 - stable/8/sys/cam/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@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: Wed, 29 May 2013 04:18:03 -0000 Author: mav Date: Wed May 29 04:18:02 2013 New Revision: 251097 URL: http://svnweb.freebsd.org/changeset/base/251097 Log: MFC r250508: Disable sending Early R_OK on SiI3726/SiI3826 port multipliers. With "cached read" HDD testing and multiple ports busy on a SATA host controller, 3726/3826 PMP will very rarely drop a deferred R_OK that was intended for the host. Symptom will be all 5 drives under test will timeout, get reset, and recover. Modified: stable/8/sys/cam/ata/ata_pmp.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/cam/ (props changed) Modified: stable/8/sys/cam/ata/ata_pmp.c ============================================================================== --- stable/8/sys/cam/ata/ata_pmp.c Wed May 29 04:17:05 2013 (r251096) +++ stable/8/sys/cam/ata/ata_pmp.c Wed May 29 04:18:02 2013 (r251097) @@ -64,6 +64,9 @@ __FBSDID("$FreeBSD$"); typedef enum { PMP_STATE_NORMAL, PMP_STATE_PORTS, + PMP_STATE_PM_QUIRKS_1, + PMP_STATE_PM_QUIRKS_2, + PMP_STATE_PM_QUIRKS_3, PMP_STATE_PRECONFIG, PMP_STATE_RESET, PMP_STATE_CONNECT, @@ -319,7 +322,11 @@ pmpasync(void *callback_arg, u_int32_t c if (code == AC_SENT_BDR || code == AC_BUS_RESET) softc->found = 0; /* We have to reset everything. */ if (softc->state == PMP_STATE_NORMAL) { - softc->state = PMP_STATE_PRECONFIG; + if (softc->pm_pid == 0x37261095 || + softc->pm_pid == 0x38261095) + softc->state = PMP_STATE_PM_QUIRKS_1; + else + softc->state = PMP_STATE_PRECONFIG; cam_periph_acquire(periph); xpt_schedule(periph, CAM_PRIORITY_DEV); } else @@ -434,7 +441,10 @@ pmpstart(struct cam_periph *periph, unio if (softc->restart) { softc->restart = 0; - softc->state = min(softc->state, PMP_STATE_PRECONFIG); + if (softc->pm_pid == 0x37261095 || softc->pm_pid == 0x38261095) + softc->state = min(softc->state, PMP_STATE_PM_QUIRKS_1); + else + softc->state = min(softc->state, PMP_STATE_PRECONFIG); } /* Fetch user wanted device speed. */ if (softc->state == PMP_STATE_RESET || @@ -464,6 +474,32 @@ pmpstart(struct cam_periph *periph, unio pmp_default_timeout * 1000); ata_pm_read_cmd(ataio, 2, 15); break; + + case PMP_STATE_PM_QUIRKS_1: + case PMP_STATE_PM_QUIRKS_3: + cam_fill_ataio(ataio, + pmp_retry_count, + pmpdone, + /*flags*/CAM_DIR_NONE, + 0, + /*data_ptr*/NULL, + /*dxfer_len*/0, + pmp_default_timeout * 1000); + ata_pm_read_cmd(ataio, 129, 15); + break; + + case PMP_STATE_PM_QUIRKS_2: + cam_fill_ataio(ataio, + pmp_retry_count, + pmpdone, + /*flags*/CAM_DIR_NONE, + 0, + /*data_ptr*/NULL, + /*dxfer_len*/0, + pmp_default_timeout * 1000); + ata_pm_write_cmd(ataio, 129, 15, softc->caps & ~0x1); + break; + case PMP_STATE_PRECONFIG: /* Get/update host SATA capabilities. */ bzero(&cts, sizeof(cts)); @@ -473,6 +509,8 @@ pmpstart(struct cam_periph *periph, unio xpt_action((union ccb *)&cts); if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS) softc->caps = cts.xport_specific.sata.caps; + else + softc->caps = 0; cam_fill_ataio(ataio, pmp_retry_count, pmpdone, @@ -582,7 +620,10 @@ pmpdone(struct cam_periph *periph, union if (softc->restart) { softc->restart = 0; xpt_release_ccb(done_ccb); - softc->state = min(softc->state, PMP_STATE_PRECONFIG); + if (softc->pm_pid == 0x37261095 || softc->pm_pid == 0x38261095) + softc->state = min(softc->state, PMP_STATE_PM_QUIRKS_1); + else + softc->state = min(softc->state, PMP_STATE_PRECONFIG); xpt_schedule(periph, priority); return; } @@ -623,10 +664,48 @@ pmpdone(struct cam_periph *periph, union printf("%s%d: %d fan-out ports\n", periph->periph_name, periph->unit_number, softc->pm_ports); + if (softc->pm_pid == 0x37261095 || softc->pm_pid == 0x38261095) + softc->state = PMP_STATE_PM_QUIRKS_1; + else + softc->state = PMP_STATE_PRECONFIG; + xpt_release_ccb(done_ccb); + xpt_schedule(periph, priority); + return; + + case PMP_STATE_PM_QUIRKS_1: + softc->caps = (ataio->res.lba_high << 24) + + (ataio->res.lba_mid << 16) + + (ataio->res.lba_low << 8) + + ataio->res.sector_count; + if (softc->caps & 0x1) + softc->state = PMP_STATE_PM_QUIRKS_2; + else + softc->state = PMP_STATE_PRECONFIG; + xpt_release_ccb(done_ccb); + xpt_schedule(periph, priority); + return; + + case PMP_STATE_PM_QUIRKS_2: + if (bootverbose) + softc->state = PMP_STATE_PM_QUIRKS_3; + else + softc->state = PMP_STATE_PRECONFIG; + xpt_release_ccb(done_ccb); + xpt_schedule(periph, priority); + return; + + case PMP_STATE_PM_QUIRKS_3: + res = (ataio->res.lba_high << 24) + + (ataio->res.lba_mid << 16) + + (ataio->res.lba_low << 8) + + ataio->res.sector_count; + printf("%s%d: Disabling SiI3x26 R_OK in GSCR_POLL: %x->%x\n", + periph->periph_name, periph->unit_number, softc->caps, res); softc->state = PMP_STATE_PRECONFIG; xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); return; + case PMP_STATE_PRECONFIG: softc->pm_step = 0; softc->state = PMP_STATE_RESET;