diff options
author | ken <ken@FreeBSD.org> | 2012-12-09 19:53:21 +0000 |
---|---|---|
committer | ken <ken@FreeBSD.org> | 2012-12-09 19:53:21 +0000 |
commit | 287e4f6a6baae6598a7ebb9580a440bbff2f9113 (patch) | |
tree | 09c72328c6e67b6e8ed0c793d8fd837be09a3719 | |
parent | d004c46035fec779a966e34d3480a59fd6ea06fd (diff) | |
download | FreeBSD-src-287e4f6a6baae6598a7ebb9580a440bbff2f9113.zip FreeBSD-src-287e4f6a6baae6598a7ebb9580a440bbff2f9113.tar.gz |
Fix a couple of CTL locking issues and clean up some duplicated code.
ctl_frontend_cam_sim.c: Coalesce cfcs_online() and cfcs_offline()
into a single function since these were
identical except for one line.
Make sure we hold the SIM lock around path
creation, and calling xpt_rescan().
scsi_ctl.c: In ctlfe_onoffline(), make sure we hold the
SIM lock around path creation and free
calls, as well as xpt_action().
In ctlfe_lun_enable(), hold the SIM lock
around path and peripheral operations that
require it.
Sponsored by: Spectra Logic Corporation
MFC after: 1 week
-rw-r--r-- | sys/cam/ctl/ctl_frontend_cam_sim.c | 42 | ||||
-rw-r--r-- | sys/cam/ctl/scsi_ctl.c | 26 |
2 files changed, 31 insertions, 37 deletions
diff --git a/sys/cam/ctl/ctl_frontend_cam_sim.c b/sys/cam/ctl/ctl_frontend_cam_sim.c index fa72059..43e4d61d 100644 --- a/sys/cam/ctl/ctl_frontend_cam_sim.c +++ b/sys/cam/ctl/ctl_frontend_cam_sim.c @@ -275,7 +275,7 @@ cfcs_shutdown(void) } static void -cfcs_online(void *arg) +cfcs_onoffline(void *arg, int online) { struct cfcs_softc *softc; union ccb *ccb; @@ -283,13 +283,12 @@ cfcs_online(void *arg) softc = (struct cfcs_softc *)arg; mtx_lock(&softc->lock); - softc->online = 1; - mtx_unlock(&softc->lock); + softc->online = online; ccb = xpt_alloc_ccb_nowait(); if (ccb == NULL) { printf("%s: unable to allocate CCB for rescan\n", __func__); - return; + goto bailout; } if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, @@ -297,37 +296,24 @@ cfcs_online(void *arg) CAM_LUN_WILDCARD) != CAM_REQ_CMP) { printf("%s: can't allocate path for rescan\n", __func__); xpt_free_ccb(ccb); - return; + goto bailout; } xpt_rescan(ccb); + +bailout: + mtx_unlock(&softc->lock); } static void -cfcs_offline(void *arg) +cfcs_online(void *arg) { - struct cfcs_softc *softc; - union ccb *ccb; - - softc = (struct cfcs_softc *)arg; - - mtx_lock(&softc->lock); - softc->online = 0; - mtx_unlock(&softc->lock); - - ccb = xpt_alloc_ccb_nowait(); - if (ccb == NULL) { - printf("%s: unable to allocate CCB for rescan\n", __func__); - return; - } + cfcs_onoffline(arg, /*online*/ 1); +} - if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, - cam_sim_path(softc->sim), CAM_TARGET_WILDCARD, - CAM_LUN_WILDCARD) != CAM_REQ_CMP) { - printf("%s: can't allocate path for rescan\n", __func__); - xpt_free_ccb(ccb); - return; - } - xpt_rescan(ccb); +static void +cfcs_offline(void *arg) +{ + cfcs_onoffline(arg, /*online*/ 0); } static int diff --git a/sys/cam/ctl/scsi_ctl.c b/sys/cam/ctl/scsi_ctl.c index 898b8f4..59357123 100644 --- a/sys/cam/ctl/scsi_ctl.c +++ b/sys/cam/ctl/scsi_ctl.c @@ -1687,16 +1687,21 @@ ctlfe_onoffline(void *arg, int online) set_wwnn = 0; + sim = bus_softc->sim; + + CAM_SIM_LOCK(sim); status = xpt_create_path(&path, /*periph*/ NULL, bus_softc->path_id, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD); if (status != CAM_REQ_CMP) { printf("%s: unable to create path!\n", __func__); + CAM_SIM_UNLOCK(sim); return; } + CAM_SIM_UNLOCK(sim); + ccb = (union ccb *)malloc(sizeof(*ccb), M_TEMP, M_WAITOK | M_ZERO); xpt_setup_ccb(&ccb->ccb_h, path, CAM_PRIORITY_NONE); - sim = xpt_path_sim(path); /* * Copan WWN format: @@ -1883,27 +1888,30 @@ ctlfe_lun_enable(void *arg, struct ctl_id targ_id, int lun_id) bus_softc = (struct ctlfe_softc *)arg; + sim = bus_softc->sim; + + CAM_SIM_LOCK(sim); - status = xpt_create_path_unlocked(&path, /*periph*/ NULL, - bus_softc->path_id, - targ_id.id, - lun_id); + status = xpt_create_path(&path, /*periph*/ NULL, bus_softc->path_id, + targ_id.id, lun_id); /* XXX KDM need some way to return status to CTL here? */ if (status != CAM_REQ_CMP) { printf("%s: could not create path, status %#x\n", __func__, status); + CAM_SIM_UNLOCK(sim); return (1); } + CAM_SIM_UNLOCK(sim); softc = malloc(sizeof(*softc), M_CTLFE, M_WAITOK | M_ZERO); - sim = xpt_path_sim(path); - mtx_lock(sim->mtx); + + CAM_SIM_LOCK(sim); periph = cam_periph_find(path, "ctl"); if (periph != NULL) { /* We've already got a periph, no need to alloc a new one. */ xpt_free_path(path); free(softc, M_CTLFE); - mtx_unlock(sim->mtx); + CAM_SIM_UNLOCK(sim); return (0); } @@ -1923,7 +1931,7 @@ ctlfe_lun_enable(void *arg, struct ctl_id targ_id, int lun_id) xpt_free_path(path); - mtx_unlock(sim->mtx); + CAM_SIM_UNLOCK(sim); return (0); } |