From owner-p4-projects@FreeBSD.ORG Tue Apr 24 04:36:15 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6E34D16A407; Tue, 24 Apr 2007 04:36:15 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 4546F16A403 for ; Tue, 24 Apr 2007 04:36:15 +0000 (UTC) (envelope-from scottl@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 3369113C457 for ; Tue, 24 Apr 2007 04:36:15 +0000 (UTC) (envelope-from scottl@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l3O4aFm3046619 for ; Tue, 24 Apr 2007 04:36:15 GMT (envelope-from scottl@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l3O4aFii046616 for perforce@freebsd.org; Tue, 24 Apr 2007 04:36:15 GMT (envelope-from scottl@freebsd.org) Date: Tue, 24 Apr 2007 04:36:15 GMT Message-Id: <200704240436.l3O4aFii046616@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to scottl@freebsd.org using -f From: Scott Long To: Perforce Change Reviews Cc: Subject: PERFORCE change 118702 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Apr 2007 04:36:15 -0000 http://perforce.freebsd.org/chv.cgi?CH=118702 Change 118702 by scottl@scottl-x64 on 2007/04/24 04:36:12 Move the bus and LUN scan code to scsi_xpt.c Affected files ... .. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#63 edit .. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.h#10 edit .. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_xpt.c#2 edit .. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_xpt.h#2 edit Differences ... ==== //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#63 (text+ko) ==== @@ -100,31 +100,6 @@ #define CAM_MAX_HIGHPOWER 4 #endif -static int cam_srch_hi = 0; -TUNABLE_INT("kern.cam.cam_srch_hi", &cam_srch_hi); -static int sysctl_cam_search_luns(SYSCTL_HANDLER_ARGS); -SYSCTL_PROC(_kern_cam, OID_AUTO, cam_srch_hi, CTLTYPE_INT|CTLFLAG_RW, 0, 0, - sysctl_cam_search_luns, "I", - "allow search above LUN 7 for SCSI3 and greater devices"); - -#define CAM_SCSI2_MAXLUN 8 -/* - * If we're not quirked to search <= the first 8 luns - * and we are either quirked to search above lun 8, - * or we're > SCSI-2 and we've enabled hilun searching, - * or we're > SCSI-2 and the last lun was a success, - * we can look for luns above lun 8. - */ -#define CAN_SRCH_HI_SPARSE(dv) \ - (((dv->quirk->quirks & CAM_QUIRK_NOHILUNS) == 0) \ - && ((dv->quirk->quirks & CAM_QUIRK_HILUNS) \ - || (SID_ANSI_REV(&dv->inq_data) > SCSI_REV_2 && cam_srch_hi))) - -#define CAN_SRCH_HI_DENSE(dv) \ - (((dv->quirk->quirks & CAM_QUIRK_NOHILUNS) == 0) \ - && ((dv->quirk->quirks & CAM_QUIRK_HILUNS) \ - || (SID_ANSI_REV(&dv->inq_data) > SCSI_REV_2))) - typedef enum { XPT_FLAG_OPEN = 0x01 } xpt_flags; @@ -275,14 +250,6 @@ MODULE_VERSION(cam, 1); -static cam_status xpt_compile_path(struct cam_path *new_path, - struct cam_periph *perph, - path_id_t path_id, - target_id_t target_id, - lun_id_t lun_id); - -static void xpt_release_path(struct cam_path *path); - static void xpt_async_bcast(struct async_list *async_head, u_int32_t async_code, struct cam_path *path, @@ -319,11 +286,6 @@ xpt_find_target(struct cam_eb *bus, target_id_t target_id); static struct cam_ed* xpt_find_device(struct cam_et *target, lun_id_t lun_id); -static void xpt_scan_bus(struct cam_periph *periph, union ccb *ccb); -static void xpt_scan_lun(struct cam_periph *periph, - struct cam_path *path, cam_flags flags, - union ccb *ccb); -static void xptscandone(struct cam_periph *periph, union ccb *done_ccb); static xpt_busfunc_t xptconfigbuscountfunc; static xpt_busfunc_t xptconfigfunc; static void xpt_config(void *arg); @@ -3492,7 +3454,7 @@ return (status); } -static cam_status +cam_status xpt_compile_path(struct cam_path *new_path, struct cam_periph *perph, path_id_t path_id, target_id_t target_id, lun_id_t lun_id) { @@ -3563,7 +3525,7 @@ return (status); } -static void +void xpt_release_path(struct cam_path *path) { CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_release_path\n")); @@ -4677,386 +4639,6 @@ return (device); } -typedef struct { - union ccb *request_ccb; - struct ccb_pathinq *cpi; - int counter; -} xpt_scan_bus_info; - -/* - * To start a scan, request_ccb is an XPT_SCAN_BUS ccb. - * As the scan progresses, xpt_scan_bus is used as the - * callback on completion function. - */ -static void -xpt_scan_bus(struct cam_periph *periph, union ccb *request_ccb) -{ - CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE, - ("xpt_scan_bus\n")); - switch (request_ccb->ccb_h.func_code) { - case XPT_SCAN_BUS: - { - xpt_scan_bus_info *scan_info; - union ccb *work_ccb; - struct cam_path *path; - u_int i; - u_int max_target; - u_int initiator_id; - - /* Find out the characteristics of the bus */ - work_ccb = xpt_alloc_ccb_nowait(); - if (work_ccb == NULL) { - request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; - xpt_done(request_ccb); - return; - } - xpt_setup_ccb(&work_ccb->ccb_h, request_ccb->ccb_h.path, - request_ccb->ccb_h.pinfo.priority); - work_ccb->ccb_h.func_code = XPT_PATH_INQ; - xpt_action(work_ccb); - if (work_ccb->ccb_h.status != CAM_REQ_CMP) { - request_ccb->ccb_h.status = work_ccb->ccb_h.status; - xpt_free_ccb(work_ccb); - xpt_done(request_ccb); - return; - } - - if ((work_ccb->cpi.hba_misc & PIM_NOINITIATOR) != 0) { - /* - * Can't scan the bus on an adapter that - * cannot perform the initiator role. - */ - request_ccb->ccb_h.status = CAM_REQ_CMP; - xpt_free_ccb(work_ccb); - xpt_done(request_ccb); - return; - } - - /* Save some state for use while we probe for devices */ - scan_info = (xpt_scan_bus_info *) - malloc(sizeof(xpt_scan_bus_info), M_TEMP, M_NOWAIT); - scan_info->request_ccb = request_ccb; - scan_info->cpi = &work_ccb->cpi; - - /* Cache on our stack so we can work asynchronously */ - max_target = scan_info->cpi->max_target; - initiator_id = scan_info->cpi->initiator_id; - - - /* - * We can scan all targets in parallel, or do it sequentially. - */ - if (scan_info->cpi->hba_misc & PIM_SEQSCAN) { - max_target = 0; - scan_info->counter = 0; - } else { - scan_info->counter = scan_info->cpi->max_target + 1; - if (scan_info->cpi->initiator_id < scan_info->counter) { - scan_info->counter--; - } - } - - for (i = 0; i <= max_target; i++) { - cam_status status; - if (i == initiator_id) - continue; - - status = xpt_create_path(&path, xpt_periph, - request_ccb->ccb_h.path_id, - i, 0); - if (status != CAM_REQ_CMP) { - printf("xpt_scan_bus: xpt_create_path failed" - " with status %#x, bus scan halted\n", - status); - free(scan_info, M_TEMP); - request_ccb->ccb_h.status = status; - xpt_free_ccb(work_ccb); - xpt_done(request_ccb); - break; - } - work_ccb = xpt_alloc_ccb_nowait(); - if (work_ccb == NULL) { - free(scan_info, M_TEMP); - xpt_free_path(path); - request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; - xpt_done(request_ccb); - break; - } - xpt_setup_ccb(&work_ccb->ccb_h, path, - request_ccb->ccb_h.pinfo.priority); - work_ccb->ccb_h.func_code = XPT_SCAN_LUN; - work_ccb->ccb_h.cbfcnp = xpt_scan_bus; - work_ccb->ccb_h.ppriv_ptr0 = scan_info; - work_ccb->crcn.flags = request_ccb->crcn.flags; - xpt_action(work_ccb); - } - break; - } - case XPT_SCAN_LUN: - { - cam_status status; - struct cam_path *path; - xpt_scan_bus_info *scan_info; - path_id_t path_id; - target_id_t target_id; - lun_id_t lun_id; - - /* Reuse the same CCB to query if a device was really found */ - scan_info = (xpt_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); - - if (request_ccb->ccb_h.status != CAM_REQ_CMP) { - struct cam_ed *device; - struct cam_et *target; - 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. - */ - target = request_ccb->ccb_h.path->target; - /* - * 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++; - } - } else { - struct cam_ed *device; - - device = request_ccb->ccb_h.path->device; - - if ((device->quirk->quirks & CAM_QUIRK_NOLUNS) == 0) { - /* Try the next lun */ - if (lun_id < (CAM_SCSI2_MAXLUN-1) - || CAN_SRCH_HI_DENSE(device)) - lun_id++; - } - } - - /* - * Free the current request path- we're done with it. - */ - xpt_free_path(request_ccb->ccb_h.path); - - /* - * Check to see if we scan any further luns. - */ - if (lun_id == request_ccb->ccb_h.target_lun - || lun_id > scan_info->cpi->max_lun) { - int done; - - hop_again: - done = 0; - if (scan_info->cpi->hba_misc & PIM_SEQSCAN) { - scan_info->counter++; - if (scan_info->counter == - scan_info->cpi->initiator_id) { - scan_info->counter++; - } - if (scan_info->counter >= - scan_info->cpi->max_target+1) { - done = 1; - } - } else { - scan_info->counter--; - if (scan_info->counter == 0) { - done = 1; - } - } - if (done) { - xpt_free_ccb(request_ccb); - xpt_free_ccb((union ccb *)scan_info->cpi); - request_ccb = scan_info->request_ccb; - free(scan_info, M_TEMP); - request_ccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(request_ccb); - break; - } - - if ((scan_info->cpi->hba_misc & PIM_SEQSCAN) == 0) { - break; - } - status = xpt_create_path(&path, xpt_periph, - scan_info->request_ccb->ccb_h.path_id, - scan_info->counter, 0); - if (status != CAM_REQ_CMP) { - printf("xpt_scan_bus: xpt_create_path failed" - " with status %#x, bus scan halted\n", - status); - xpt_free_ccb(request_ccb); - xpt_free_ccb((union ccb *)scan_info->cpi); - request_ccb = scan_info->request_ccb; - free(scan_info, M_TEMP); - request_ccb->ccb_h.status = status; - xpt_done(request_ccb); - break; - } - xpt_setup_ccb(&request_ccb->ccb_h, path, - request_ccb->ccb_h.pinfo.priority); - request_ccb->ccb_h.func_code = XPT_SCAN_LUN; - request_ccb->ccb_h.cbfcnp = xpt_scan_bus; - request_ccb->ccb_h.ppriv_ptr0 = scan_info; - request_ccb->crcn.flags = - scan_info->request_ccb->crcn.flags; - } else { - status = xpt_create_path(&path, xpt_periph, - path_id, target_id, lun_id); - if (status != CAM_REQ_CMP) { - printf("xpt_scan_bus: xpt_create_path failed " - "with status %#x, halting LUN scan\n", - status); - goto hop_again; - } - xpt_setup_ccb(&request_ccb->ccb_h, path, - request_ccb->ccb_h.pinfo.priority); - request_ccb->ccb_h.func_code = XPT_SCAN_LUN; - request_ccb->ccb_h.cbfcnp = xpt_scan_bus; - request_ccb->ccb_h.ppriv_ptr0 = scan_info; - request_ccb->crcn.flags = - scan_info->request_ccb->crcn.flags; - } - xpt_action(request_ccb); - break; - } - default: - break; - } -} - -static void -xpt_scan_lun(struct cam_periph *periph, struct cam_path *path, - cam_flags flags, union ccb *request_ccb) -{ - struct ccb_pathinq cpi; - cam_status status; - struct cam_path *new_path; - struct cam_periph *old_periph; - - CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE, - ("xpt_scan_lun\n")); - - xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1); - cpi.ccb_h.func_code = XPT_PATH_INQ; - xpt_action((union ccb *)&cpi); - - if (cpi.ccb_h.status != CAM_REQ_CMP) { - if (request_ccb != NULL) { - request_ccb->ccb_h.status = cpi.ccb_h.status; - xpt_done(request_ccb); - } - return; - } - - if ((cpi.hba_misc & PIM_NOINITIATOR) != 0) { - /* - * Can't scan the bus on an adapter that - * cannot perform the initiator role. - */ - if (request_ccb != NULL) { - request_ccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(request_ccb); - } - return; - } - - if (request_ccb == NULL) { - request_ccb = malloc(sizeof(union ccb), M_TEMP, M_NOWAIT); - if (request_ccb == NULL) { - xpt_print(path, "xpt_scan_lun: can't allocate CCB, " - "can't continue\n"); - return; - } - new_path = malloc(sizeof(*new_path), M_TEMP, M_NOWAIT); - if (new_path == NULL) { - xpt_print(path, "xpt_scan_lun: can't allocate path, " - "can't continue\n"); - free(request_ccb, M_TEMP); - return; - } - status = xpt_compile_path(new_path, xpt_periph, - path->bus->path_id, - path->target->target_id, - path->device->lun_id); - - if (status != CAM_REQ_CMP) { - xpt_print(path, "xpt_scan_lun: can't compile path, " - "can't continue\n"); - free(request_ccb, M_TEMP); - free(new_path, M_TEMP); - return; - } - xpt_setup_ccb(&request_ccb->ccb_h, new_path, /*priority*/ 1); - request_ccb->ccb_h.cbfcnp = xptscandone; - request_ccb->ccb_h.func_code = XPT_SCAN_LUN; - request_ccb->crcn.flags = flags; - } - - if ((old_periph = cam_periph_find(path, "probe")) != NULL) { - probe_insert_ccbq(old_periph, &request_ccb->ccb_h); - } else { - status = cam_periph_alloc(proberegister, NULL, probecleanup, - probestart, "probe", - CAM_PERIPH_BIO, - request_ccb->ccb_h.path, NULL, 0, - request_ccb); - - if (status != CAM_REQ_CMP) { - xpt_print(path, "xpt_scan_lun: cam_alloc_periph " - "returned an error, can't continue probe\n"); - request_ccb->ccb_h.status = status; - xpt_done(request_ccb); - } - } -} - -static void -xptscandone(struct cam_periph *periph, union ccb *done_ccb) -{ - xpt_release_path(done_ccb->ccb_h.path); - free(done_ccb->ccb_h.path, M_TEMP); - free(done_ccb, M_TEMP); -} - -static int -sysctl_cam_search_luns(SYSCTL_HANDLER_ARGS) -{ - int error, bool; - - bool = cam_srch_hi; - error = sysctl_handle_int(oidp, &bool, sizeof(bool), req); - if (error != 0 || req->newptr == NULL) - return (error); - if (bool == 0 || bool == 1) { - cam_srch_hi = bool; - return (0); - } else { - return (EINVAL); - } -} - - void xpt_devise_transport(struct cam_path *path) { ==== //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.h#10 (text+ko) ==== @@ -80,6 +80,14 @@ void xpt_rescan(union ccb *ccb); void xpt_lock_buses(void); void xpt_unlock_buses(void); +cam_status xpt_compile_path(struct cam_path *new_path, + struct cam_periph *perph, + path_id_t path_id, + target_id_t target_id, + lun_id_t lun_id); + +void xpt_release_path(struct cam_path *path); + #endif /* _KERNEL */ #endif /* _CAM_CAM_XPT_H */ ==== //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_xpt.c#2 (text+ko) ==== @@ -64,6 +64,7 @@ #include #include #include +#include #include /* for xpt_print below */ #include "opt_cam.h" @@ -431,6 +432,31 @@ struct xpt_quirk_entry *xpt_default_quirk = &xpt_quirk_table[(sizeof(xpt_quirk_table) / sizeof(*xpt_quirk_table)) - 1]; +#define CAM_SCSI2_MAXLUN 8 +/* + * If we're not quirked to search <= the first 8 luns + * and we are either quirked to search above lun 8, + * or we're > SCSI-2 and we've enabled hilun searching, + * or we're > SCSI-2 and the last lun was a success, + * we can look for luns above lun 8. + */ +#define CAN_SRCH_HI_SPARSE(dv) \ + (((dv->quirk->quirks & CAM_QUIRK_NOHILUNS) == 0) \ + && ((dv->quirk->quirks & CAM_QUIRK_HILUNS) \ + || (SID_ANSI_REV(&dv->inq_data) > SCSI_REV_2 && cam_srch_hi))) + +#define CAN_SRCH_HI_DENSE(dv) \ + (((dv->quirk->quirks & CAM_QUIRK_NOHILUNS) == 0) \ + && ((dv->quirk->quirks & CAM_QUIRK_HILUNS) \ + || (SID_ANSI_REV(&dv->inq_data) > SCSI_REV_2))) + +static int cam_srch_hi = 0; +TUNABLE_INT("kern.cam.cam_srch_hi", &cam_srch_hi); +static int sysctl_cam_search_luns(SYSCTL_HANDLER_ARGS); +SYSCTL_PROC(_kern_cam, OID_AUTO, cam_srch_hi, CTLTYPE_INT|CTLFLAG_RW, 0, 0, + sysctl_cam_search_luns, "I", + "allow search above LUN 7 for SCSI3 and greater devices"); + void xpt_find_quirk(struct cam_ed *device) @@ -448,3 +474,381 @@ device->quirk = (struct xpt_quirk_entry *)match; } +typedef struct { + union ccb *request_ccb; + struct ccb_pathinq *cpi; + int counter; +} xpt_scan_bus_info; + +/* + * To start a scan, request_ccb is an XPT_SCAN_BUS ccb. + * As the scan progresses, xpt_scan_bus is used as the + * callback on completion function. + */ +void +xpt_scan_bus(struct cam_periph *periph, union ccb *request_ccb) +{ + CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE, + ("xpt_scan_bus\n")); + switch (request_ccb->ccb_h.func_code) { + case XPT_SCAN_BUS: + { + xpt_scan_bus_info *scan_info; + union ccb *work_ccb; + struct cam_path *path; + u_int i; + u_int max_target; + u_int initiator_id; + + /* Find out the characteristics of the bus */ + work_ccb = xpt_alloc_ccb_nowait(); + if (work_ccb == NULL) { + request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; + xpt_done(request_ccb); + return; + } + xpt_setup_ccb(&work_ccb->ccb_h, request_ccb->ccb_h.path, + request_ccb->ccb_h.pinfo.priority); + work_ccb->ccb_h.func_code = XPT_PATH_INQ; + xpt_action(work_ccb); + if (work_ccb->ccb_h.status != CAM_REQ_CMP) { + request_ccb->ccb_h.status = work_ccb->ccb_h.status; + xpt_free_ccb(work_ccb); + xpt_done(request_ccb); + return; + } + + if ((work_ccb->cpi.hba_misc & PIM_NOINITIATOR) != 0) { + /* + * Can't scan the bus on an adapter that + * cannot perform the initiator role. + */ + request_ccb->ccb_h.status = CAM_REQ_CMP; + xpt_free_ccb(work_ccb); + xpt_done(request_ccb); + return; + } + + /* Save some state for use while we probe for devices */ + scan_info = (xpt_scan_bus_info *) + malloc(sizeof(xpt_scan_bus_info), M_TEMP, M_NOWAIT); + scan_info->request_ccb = request_ccb; + scan_info->cpi = &work_ccb->cpi; + + /* Cache on our stack so we can work asynchronously */ + max_target = scan_info->cpi->max_target; + initiator_id = scan_info->cpi->initiator_id; + + + /* + * We can scan all targets in parallel, or do it sequentially. + */ + if (scan_info->cpi->hba_misc & PIM_SEQSCAN) { + max_target = 0; + scan_info->counter = 0; + } else { + scan_info->counter = scan_info->cpi->max_target + 1; + if (scan_info->cpi->initiator_id < scan_info->counter) { + scan_info->counter--; + } + } + + for (i = 0; i <= max_target; i++) { + cam_status status; + if (i == initiator_id) + continue; + + status = xpt_create_path(&path, xpt_periph, + request_ccb->ccb_h.path_id, + i, 0); + if (status != CAM_REQ_CMP) { + printf("xpt_scan_bus: xpt_create_path failed" + " with status %#x, bus scan halted\n", + status); + free(scan_info, M_TEMP); + request_ccb->ccb_h.status = status; + xpt_free_ccb(work_ccb); + xpt_done(request_ccb); + break; + } + work_ccb = xpt_alloc_ccb_nowait(); + if (work_ccb == NULL) { + free(scan_info, M_TEMP); + xpt_free_path(path); + request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; + xpt_done(request_ccb); + break; + } + xpt_setup_ccb(&work_ccb->ccb_h, path, + request_ccb->ccb_h.pinfo.priority); + work_ccb->ccb_h.func_code = XPT_SCAN_LUN; + work_ccb->ccb_h.cbfcnp = xpt_scan_bus; + work_ccb->ccb_h.ppriv_ptr0 = scan_info; + work_ccb->crcn.flags = request_ccb->crcn.flags; + xpt_action(work_ccb); + } + break; + } + case XPT_SCAN_LUN: + { + cam_status status; + struct cam_path *path; + xpt_scan_bus_info *scan_info; + path_id_t path_id; + target_id_t target_id; + lun_id_t lun_id; + + /* Reuse the same CCB to query if a device was really found */ + scan_info = (xpt_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); + + if (request_ccb->ccb_h.status != CAM_REQ_CMP) { + struct cam_ed *device; + struct cam_et *target; + 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. + */ + target = request_ccb->ccb_h.path->target; + /* + * 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++; + } + } else { + struct cam_ed *device; + + device = request_ccb->ccb_h.path->device; + + if ((device->quirk->quirks & CAM_QUIRK_NOLUNS) == 0) { + /* Try the next lun */ + if (lun_id < (CAM_SCSI2_MAXLUN-1) + || CAN_SRCH_HI_DENSE(device)) + lun_id++; + } + } + + /* + * Free the current request path- we're done with it. + */ + xpt_free_path(request_ccb->ccb_h.path); + + /* + * Check to see if we scan any further luns. + */ + if (lun_id == request_ccb->ccb_h.target_lun + || lun_id > scan_info->cpi->max_lun) { + int done; + + hop_again: + done = 0; + if (scan_info->cpi->hba_misc & PIM_SEQSCAN) { + scan_info->counter++; + if (scan_info->counter == + scan_info->cpi->initiator_id) { + scan_info->counter++; + } + if (scan_info->counter >= + scan_info->cpi->max_target+1) { + done = 1; + } + } else { + scan_info->counter--; + if (scan_info->counter == 0) { + done = 1; + } + } + if (done) { + xpt_free_ccb(request_ccb); + xpt_free_ccb((union ccb *)scan_info->cpi); + request_ccb = scan_info->request_ccb; + free(scan_info, M_TEMP); + request_ccb->ccb_h.status = CAM_REQ_CMP; + xpt_done(request_ccb); + break; + } + + if ((scan_info->cpi->hba_misc & PIM_SEQSCAN) == 0) { + break; + } + status = xpt_create_path(&path, xpt_periph, + scan_info->request_ccb->ccb_h.path_id, + scan_info->counter, 0); + if (status != CAM_REQ_CMP) { + printf("xpt_scan_bus: xpt_create_path failed" + " with status %#x, bus scan halted\n", + status); + xpt_free_ccb(request_ccb); + xpt_free_ccb((union ccb *)scan_info->cpi); + request_ccb = scan_info->request_ccb; + free(scan_info, M_TEMP); + request_ccb->ccb_h.status = status; + xpt_done(request_ccb); + break; + } + xpt_setup_ccb(&request_ccb->ccb_h, path, + request_ccb->ccb_h.pinfo.priority); + request_ccb->ccb_h.func_code = XPT_SCAN_LUN; + request_ccb->ccb_h.cbfcnp = xpt_scan_bus; + request_ccb->ccb_h.ppriv_ptr0 = scan_info; + request_ccb->crcn.flags = + scan_info->request_ccb->crcn.flags; + } else { + status = xpt_create_path(&path, xpt_periph, + path_id, target_id, lun_id); + if (status != CAM_REQ_CMP) { + printf("xpt_scan_bus: xpt_create_path failed " + "with status %#x, halting LUN scan\n", + status); + goto hop_again; + } + xpt_setup_ccb(&request_ccb->ccb_h, path, + request_ccb->ccb_h.pinfo.priority); + request_ccb->ccb_h.func_code = XPT_SCAN_LUN; + request_ccb->ccb_h.cbfcnp = xpt_scan_bus; + request_ccb->ccb_h.ppriv_ptr0 = scan_info; + request_ccb->crcn.flags = + scan_info->request_ccb->crcn.flags; + } + xpt_action(request_ccb); + break; + } + default: + break; + } +} + +void +xpt_scan_lun(struct cam_periph *periph, struct cam_path *path, + cam_flags flags, union ccb *request_ccb) +{ + struct ccb_pathinq cpi; + cam_status status; + struct cam_path *new_path; + struct cam_periph *old_periph; + + CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE, + ("xpt_scan_lun\n")); + + xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1); + cpi.ccb_h.func_code = XPT_PATH_INQ; + xpt_action((union ccb *)&cpi); + + if (cpi.ccb_h.status != CAM_REQ_CMP) { + if (request_ccb != NULL) { + request_ccb->ccb_h.status = cpi.ccb_h.status; + xpt_done(request_ccb); + } + return; + } + + if ((cpi.hba_misc & PIM_NOINITIATOR) != 0) { + /* + * Can't scan the bus on an adapter that + * cannot perform the initiator role. + */ + if (request_ccb != NULL) { + request_ccb->ccb_h.status = CAM_REQ_CMP; + xpt_done(request_ccb); + } + return; + } + + if (request_ccb == NULL) { + request_ccb = malloc(sizeof(union ccb), M_TEMP, M_NOWAIT); + if (request_ccb == NULL) { + xpt_print(path, "xpt_scan_lun: can't allocate CCB, " + "can't continue\n"); + return; + } + new_path = malloc(sizeof(*new_path), M_TEMP, M_NOWAIT); + if (new_path == NULL) { + xpt_print(path, "xpt_scan_lun: can't allocate path, " + "can't continue\n"); + free(request_ccb, M_TEMP); + return; + } + status = xpt_compile_path(new_path, xpt_periph, + path->bus->path_id, + path->target->target_id, + path->device->lun_id); + + if (status != CAM_REQ_CMP) { + xpt_print(path, "xpt_scan_lun: can't compile path, " + "can't continue\n"); + free(request_ccb, M_TEMP); + free(new_path, M_TEMP); + return; + } + xpt_setup_ccb(&request_ccb->ccb_h, new_path, /*priority*/ 1); + request_ccb->ccb_h.cbfcnp = xptscandone; + request_ccb->ccb_h.func_code = XPT_SCAN_LUN; + request_ccb->crcn.flags = flags; + } + + if ((old_periph = cam_periph_find(path, "probe")) != NULL) { + probe_insert_ccbq(old_periph, &request_ccb->ccb_h); + } else { + status = cam_periph_alloc(proberegister, NULL, probecleanup, + probestart, "probe", + CAM_PERIPH_BIO, + request_ccb->ccb_h.path, NULL, 0, + request_ccb); + + if (status != CAM_REQ_CMP) { + xpt_print(path, "xpt_scan_lun: cam_alloc_periph " + "returned an error, can't continue probe\n"); + request_ccb->ccb_h.status = status; + xpt_done(request_ccb); + } + } +} + +void +xptscandone(struct cam_periph *periph, union ccb *done_ccb) +{ + xpt_release_path(done_ccb->ccb_h.path); + free(done_ccb->ccb_h.path, M_TEMP); + free(done_ccb, M_TEMP); +} + +static int +sysctl_cam_search_luns(SYSCTL_HANDLER_ARGS) +{ + int error, bool; + + bool = cam_srch_hi; + error = sysctl_handle_int(oidp, &bool, sizeof(bool), req); + if (error != 0 || req->newptr == NULL) + return (error); + if (bool == 0 || bool == 1) { + cam_srch_hi = bool; + return (0); + } else { + return (EINVAL); + } +} ==== //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_xpt.h#2 (text+ko) ==== @@ -115,5 +115,9 @@ }; void xpt_find_quirk(struct cam_ed *device); +void xpt_scan_bus(struct cam_periph *periph, union ccb *ccb); +void xpt_scan_lun(struct cam_periph *periph, struct cam_path *path, + cam_flags flags, union ccb *ccb); +void xptscandone(struct cam_periph *periph, union ccb *done_ccb); extern struct xpt_quirk_entry *xpt_default_quirk;