From owner-svn-src-all@FreeBSD.ORG Sun Nov 2 17:23:45 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 907F9DEC; Sun, 2 Nov 2014 17:23:45 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7100EC79; Sun, 2 Nov 2014 17:23:45 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id sA2HNj5g027547; Sun, 2 Nov 2014 17:23:45 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id sA2HNjJB027546; Sun, 2 Nov 2014 17:23:45 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201411021723.sA2HNjJB027546@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Sun, 2 Nov 2014 17:23:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r273974 - stable/10/sys/cam/scsi X-SVN-Group: stable-10 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.18-1 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: Sun, 02 Nov 2014 17:23:45 -0000 Author: mav Date: Sun Nov 2 17:23:44 2014 New Revision: 273974 URL: https://svnweb.freebsd.org/changeset/base/273974 Log: MFC r272401, r272402: Rework the logic of sequential SCSI LUN scanner. Previous logic was not differentiating disconnected LUNs and absent targets. That made it to stop scan if LUN 0 was not found for any reason. That made problematic, for example, using iSCSI targets declaring SPC-2 compliance and having no LUN 0 configured. The new logic continues sequential LUN scan if: -- we have more configured LUNs that need recheck; -- this LUN is connected and its SCSI version allows more LUNs; -- this LUN is disconnected, its SCSI version allows more LUNs and we guess they may be connected (we haven't scanned first 8 LUNs yet or kern.cam.cam_srch_hi sysctl is set to scan more). Modified: stable/10/sys/cam/scsi/scsi_xpt.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cam/scsi/scsi_xpt.c ============================================================================== --- stable/10/sys/cam/scsi/scsi_xpt.c Sun Nov 2 16:04:48 2014 (r273973) +++ stable/10/sys/cam/scsi/scsi_xpt.c Sun Nov 2 17:23:44 2014 (r273974) @@ -1138,6 +1138,7 @@ out: u_int8_t periph_qual; path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID; + scsi_find_quirk(path->device); inq_buf = &path->device->inq_data; periph_qual = SID_QUAL(inq_buf); @@ -1166,8 +1167,6 @@ out: goto out; } - scsi_find_quirk(path->device); - scsi_devise_transport(path); if (path->device->lun_id == 0 && @@ -1216,10 +1215,13 @@ out: : SF_RETRY_UA, &softc->saved_ccb) == ERESTART) { goto outr; - } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { - /* Don't wedge the queue */ - xpt_release_devq(done_ccb->ccb_h.path, /*count*/1, - /*run_queue*/TRUE); + } else { + if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { + /* Don't wedge the queue */ + xpt_release_devq(done_ccb->ccb_h.path, + /*count*/1, /*run_queue*/TRUE); + } + path->device->flags &= ~CAM_DEV_INQUIRY_DATA_VALID; } /* * If we get to this point, we got an error status back @@ -1980,7 +1982,7 @@ scsi_scan_bus(struct cam_periph *periph, struct cam_path *path, *oldpath; scsi_scan_bus_info *scan_info; struct cam_et *target; - struct cam_ed *device; + struct cam_ed *device, *nextdev; int next_target; path_id_t path_id; target_id_t target_id; @@ -1989,18 +1991,10 @@ scsi_scan_bus(struct cam_periph *periph, oldpath = request_ccb->ccb_h.path; status = cam_ccb_status(request_ccb); - /* Reuse the same CCB to query if a device was really found */ scan_info = (scsi_scan_bus_info *)request_ccb->ccb_h.ppriv_ptr0; - xpt_setup_ccb(&request_ccb->ccb_h, request_ccb->ccb_h.path, - request_ccb->ccb_h.pinfo.priority); - request_ccb->ccb_h.func_code = XPT_GDEV_TYPE; - - path_id = request_ccb->ccb_h.path_id; target_id = request_ccb->ccb_h.target_id; lun_id = request_ccb->ccb_h.target_lun; - xpt_action(request_ccb); - target = request_ccb->ccb_h.path->target; next_target = 1; @@ -2077,56 +2071,39 @@ scsi_scan_bus(struct cam_periph *periph, } } } else { - mtx_unlock(&target->luns_mtx); - if (request_ccb->ccb_h.status != CAM_REQ_CMP) { - int phl; - - /* - * If we already probed lun 0 successfully, or - * we have additional configured luns on this - * target that might have "gone away", go onto - * the next lun. - */ - /* - * We may touch devices that we don't - * hold references too, so ensure they - * don't disappear out from under us. - * The target above is referenced by the - * path in the request ccb. - */ - phl = 0; - device = TAILQ_FIRST(&target->ed_entries); - if (device != NULL) { - phl = CAN_SRCH_HI_SPARSE(device); - if (device->lun_id == 0) - device = TAILQ_NEXT(device, links); - } - if ((lun_id != 0) || (device != NULL)) { - if (lun_id < (CAM_SCSI2_MAXLUN-1) || phl) { - lun_id++; - next_target = 0; - } - } - if (lun_id == request_ccb->ccb_h.target_lun - || lun_id > scan_info->cpi->max_lun) - next_target = 1; - } else { - + mtx_unlock(&target->luns_mtx); device = request_ccb->ccb_h.path->device; - - if ((SCSI_QUIRK(device)->quirks & - CAM_QUIRK_NOLUNS) == 0) { - /* Try the next lun */ - if (lun_id < (CAM_SCSI2_MAXLUN-1) - || CAN_SRCH_HI_DENSE(device)) { - lun_id++; + /* Continue sequential LUN scan if: */ + /* -- we have more LUNs that need recheck */ + mtx_lock(&target->bus->eb_mtx); + nextdev = device; + while ((nextdev = TAILQ_NEXT(nextdev, links)) != NULL) + if ((nextdev->flags & CAM_DEV_UNCONFIGURED) == 0) + break; + mtx_unlock(&target->bus->eb_mtx); + if (nextdev != NULL) { + next_target = 0; + /* -- stop if CAM_QUIRK_NOLUNS is set. */ + } else if (SCSI_QUIRK(device)->quirks & CAM_QUIRK_NOLUNS) { + next_target = 1; + /* -- this LUN is connected and its SCSI version + * allows more LUNs. */ + } else if ((device->flags & CAM_DEV_UNCONFIGURED) == 0) { + if (lun_id < (CAM_SCSI2_MAXLUN-1) || + CAN_SRCH_HI_DENSE(device)) + next_target = 0; + /* -- this LUN is disconnected, its SCSI version + * allows more LUNs and we guess they may be. */ + } else if ((device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0) { + if (lun_id < (CAM_SCSI2_MAXLUN-1) || + CAN_SRCH_HI_SPARSE(device)) next_target = 0; - } } - if (lun_id == request_ccb->ccb_h.target_lun - || lun_id > scan_info->cpi->max_lun) - next_target = 1; - } + if (next_target == 0) { + lun_id++; + if (lun_id > scan_info->cpi->max_lun) + next_target = 1; + } } /*