From owner-svn-src-head@FreeBSD.ORG Fri Jan 11 16:10:12 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 40EA7EB4; Fri, 11 Jan 2013 16:10:12 +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 32FD2314; Fri, 11 Jan 2013 16:10:12 +0000 (UTC) Received: from svn.freebsd.org (svn.FreeBSD.org [8.8.178.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r0BGACJw055310; Fri, 11 Jan 2013 16:10:12 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r0BGAClQ055309; Fri, 11 Jan 2013 16:10:12 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201301111610.r0BGAClQ055309@svn.freebsd.org> From: Alexander Motin Date: Fri, 11 Jan 2013 16:10:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r245306 - head/sys/cam/scsi X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 11 Jan 2013 16:10:12 -0000 Author: mav Date: Fri Jan 11 16:10:11 2013 New Revision: 245306 URL: http://svnweb.freebsd.org/changeset/base/245306 Log: Do not schedule periph for payload/TUR requests if reprobe is in progress to avoid sending extra READ CAPACITY requests by dastart(). Schedule periph again on reprobe completion, or otherwise it may stuck indefinitely long. This should fix USB explore thread hanging on device unplug, waiting for periph destruction. Reported by: hselasky Modified: head/sys/cam/scsi/scsi_da.c Modified: head/sys/cam/scsi/scsi_da.c ============================================================================== --- head/sys/cam/scsi/scsi_da.c Fri Jan 11 15:50:01 2013 (r245305) +++ head/sys/cam/scsi/scsi_da.c Fri Jan 11 16:10:11 2013 (r245306) @@ -1081,6 +1081,9 @@ daschedule(struct cam_periph *periph) struct da_softc *softc = (struct da_softc *)periph->softc; uint32_t prio; + if (softc->state != DA_STATE_NORMAL) + return; + /* Check if cam_periph_getccb() was called. */ prio = periph->immediate_priority; @@ -1425,10 +1428,10 @@ daasync(void *callback_arg, u_int32_t co } case AC_SCSI_AEN: softc = (struct da_softc *)periph->softc; - if (softc->state == DA_STATE_NORMAL && !softc->tur) { + if (!softc->tur) { if (cam_periph_acquire(periph) == CAM_REQ_CMP) { softc->tur = 1; - xpt_schedule(periph, CAM_PRIORITY_DEV); + daschedule(periph); } } /* FALLTHROUGH */ @@ -2168,6 +2171,7 @@ dadone(struct cam_periph *periph, union struct da_softc *softc; struct ccb_scsiio *csio; u_int32_t priority; + da_ccb_state state; softc = (struct da_softc *)periph->softc; priority = done_ccb->ccb_h.pinfo.priority; @@ -2175,7 +2179,8 @@ dadone(struct cam_periph *periph, union CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone\n")); csio = &done_ccb->csio; - switch (csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK) { + state = csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK; + switch (state) { case DA_CCB_BUFFER_IO: case DA_CCB_DELETE: { @@ -2273,8 +2278,7 @@ dadone(struct cam_periph *periph, union softc->outstanding_cmds); } - if ((csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK) == - DA_CCB_DELETE) { + if (state == DA_CCB_DELETE) { while ((bp1 = bioq_takefirst(&softc->delete_run_queue)) != NULL) { bp1->bio_resid = bp->bio_resid; @@ -2300,7 +2304,7 @@ dadone(struct cam_periph *periph, union rdcap = NULL; rcaplong = NULL; - if (softc->state == DA_STATE_PROBE) + if (state == DA_CCB_PROBE) rdcap =(struct scsi_read_capacity_data *)csio->data_ptr; else rcaplong = (struct scsi_read_capacity_data_long *) @@ -2313,7 +2317,7 @@ dadone(struct cam_periph *periph, union u_int lbppbe; /* LB per physical block exponent. */ u_int lalba; /* Lowest aligned LBA. */ - if (softc->state == DA_STATE_PROBE) { + if (state == DA_CCB_PROBE) { block_size = scsi_4btoul(rdcap->length); maxsector = scsi_4btoul(rdcap->addr); lbppbe = 0; @@ -2426,7 +2430,7 @@ dadone(struct cam_periph *periph, union * If we tried READ CAPACITY(16) and failed, * fallback to READ CAPACITY(10). */ - if ((softc->state == DA_STATE_PROBE2) && + if ((state == DA_CCB_PROBE2) && (softc->flags & DA_FLAG_CAN_RC16) && (((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) || @@ -2506,7 +2510,8 @@ dadone(struct cam_periph *periph, union * operation. */ xpt_release_ccb(done_ccb); - softc->state = DA_STATE_NORMAL; + softc->state = DA_STATE_NORMAL; + daschedule(periph); wakeup(&softc->disk->d_mediasize); if ((softc->flags & DA_FLAG_PROBED) == 0) { softc->flags |= DA_FLAG_PROBED; @@ -2631,7 +2636,7 @@ damediapoll(void *arg) struct cam_periph *periph = arg; struct da_softc *softc = periph->softc; - if (softc->state == DA_STATE_NORMAL && !softc->tur) { + if (!softc->tur && softc->outstanding_cmds == 0) { if (cam_periph_acquire(periph) == CAM_REQ_CMP) { softc->tur = 1; daschedule(periph);