From owner-svn-src-all@FreeBSD.ORG Wed May 29 04:17:06 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 62D4869; Wed, 29 May 2013 04:17:06 +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 43994288; Wed, 29 May 2013 04:17:06 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r4T4H6f9097073; Wed, 29 May 2013 04:17:06 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r4T4H6Lw097072; Wed, 29 May 2013 04:17:06 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201305290417.r4T4H6Lw097072@svn.freebsd.org> From: Alexander Motin Date: Wed, 29 May 2013 04:17:06 +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: r251096 - stable/9/sys/cam/ata X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 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: Wed, 29 May 2013 04:17:06 -0000 Author: mav Date: Wed May 29 04:17:05 2013 New Revision: 251096 URL: http://svnweb.freebsd.org/changeset/base/251096 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/9/sys/cam/ata/ata_pmp.c Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/cam/ata/ata_pmp.c ============================================================================== --- stable/9/sys/cam/ata/ata_pmp.c Wed May 29 04:14:41 2013 (r251095) +++ stable/9/sys/cam/ata/ata_pmp.c Wed May 29 04:17:05 2013 (r251096) @@ -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 @@ -429,7 +436,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 || @@ -459,6 +469,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)); @@ -468,6 +504,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, @@ -577,7 +615,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; } @@ -620,10 +661,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;