diff options
author | Justin T. Gibbs <gibbs@FreeBSD.org> | 1998-12-10 04:05:49 +0000 |
---|---|---|
committer | Justin T. Gibbs <gibbs@FreeBSD.org> | 1998-12-10 04:05:49 +0000 |
commit | 98192658200999339d26fd7f0173e62d1543adec (patch) | |
tree | 50d98f8ffcdfa68f7305e18f11e8209d652cfd8b | |
parent | bb4f7bfdbf1aff1bde778631538a7953367f7f27 (diff) | |
download | src-98192658200999339d26fd7f0173e62d1543adec.tar.gz src-98192658200999339d26fd7f0173e62d1543adec.zip |
Expand the hba_misc fied in the Path Inquiry ccb to allow a controller driver
to specify that it does not provide initiator services (PIM_NOINITIATOR)
and that the initial bus reset for device probing should be avoided
(PIM_NOBUSRESET).
Modify the XPT layer to honor these flags.
Notes
Notes:
svn path=/head/; revision=41644
-rw-r--r-- | sys/cam/cam_ccb.h | 5 | ||||
-rw-r--r-- | sys/cam/cam_xpt.c | 70 |
2 files changed, 65 insertions, 10 deletions
diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h index f2732b49a384..aaf267056b9f 100644 --- a/sys/cam/cam_ccb.h +++ b/sys/cam/cam_ccb.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cam_ccb.h,v 1.1 1998/09/15 06:33:23 gibbs Exp $ + * $Id: cam_ccb.h,v 1.2 1998/10/15 23:17:35 gibbs Exp $ */ #ifndef _CAM_CAM_CCB_H @@ -412,7 +412,8 @@ typedef enum { typedef enum { PIM_SCANHILO = 0x80, /* Bus scans from high ID to low ID */ PIM_NOREMOVE = 0x40, /* Removeable devices not included in scan */ - PIM_NOINQUIRY = 0x20, /* Inquiry data not kept by XPT */ + PIM_NOINITIATOR = 0x20, /* Initiator role not supported. */ + PIM_NOBUSRESET = 0x10, /* User has disabled initial BUS RESET */ } pi_miscflag; /* Path Inquiry CCB */ diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index 3ce285d29c70..a6d6d4bb5362 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cam_xpt.c,v 1.27 1998/11/25 13:50:10 joerg Exp $ + * $Id: cam_xpt.c,v 1.28 1998/12/06 00:06:48 mjacob Exp $ */ #include <sys/param.h> #include <sys/systm.h> @@ -4552,6 +4552,17 @@ xpt_scan_bus(struct cam_periph *periph, union ccb *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_WAITOK); @@ -4739,6 +4750,7 @@ 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; @@ -4746,6 +4758,30 @@ xpt_scan_lun(struct cam_periph *periph, struct cam_path *path, 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); @@ -5528,15 +5564,34 @@ xptconfigfunc(struct cam_eb *bus, void *arg) "status %#x for bus %d\n", status, bus->path_id); printf("xptconfigfunc: halting bus configuration\n"); xpt_free_ccb(work_ccb); + busses_to_config--; + xpt_finishconfig(xpt_periph, NULL); return(0); } xpt_setup_ccb(&work_ccb->ccb_h, path, /*priority*/1); - work_ccb->ccb_h.func_code = XPT_RESET_BUS; - work_ccb->ccb_h.cbfcnp = NULL; - CAM_DEBUG(path, CAM_DEBUG_SUBTRACE, - ("Resetting Bus\n")); + work_ccb->ccb_h.func_code = XPT_PATH_INQ; xpt_action(work_ccb); - xpt_finishconfig(xpt_periph, work_ccb); + if (work_ccb->ccb_h.status != CAM_REQ_CMP) { + printf("xptconfigfunc: CPI failed on bus %d " + "with status %d\n", bus->path_id, + work_ccb->ccb_h.status); + xpt_finishconfig(xpt_periph, work_ccb); + return(1); + } + + if ((work_ccb->cpi.hba_misc & PIM_NOBUSRESET) == 0) { + xpt_setup_ccb(&work_ccb->ccb_h, path, /*priority*/1); + work_ccb->ccb_h.func_code = XPT_RESET_BUS; + work_ccb->ccb_h.cbfcnp = NULL; + CAM_DEBUG(path, CAM_DEBUG_SUBTRACE, + ("Resetting Bus\n")); + xpt_action(work_ccb); + xpt_finishconfig(xpt_periph, work_ccb); + } else { + /* Act as though we performed a successful BUS RESET */ + work_ccb->ccb_h.func_code = XPT_RESET_BUS; + xpt_finishconfig(xpt_periph, work_ccb); + } } return(1); @@ -5654,11 +5709,10 @@ xpt_finishconfig(struct cam_periph *periph, union ccb *done_ccb) } /* FALLTHROUGH */ case XPT_SCAN_BUS: + default: xpt_free_path(done_ccb->ccb_h.path); busses_to_config--; break; - default: - break; } } |