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
This commit is contained in:
parent
b3c69eef25
commit
54f90e7783
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=244052
@ -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_online(void *arg)
|
||||
{
|
||||
cfcs_onoffline(arg, /*online*/ 1);
|
||||
}
|
||||
|
||||
static void
|
||||
cfcs_offline(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;
|
||||
}
|
||||
|
||||
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);
|
||||
cfcs_onoffline(arg, /*online*/ 0);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -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;
|
||||
|
||||
status = xpt_create_path_unlocked(&path, /*periph*/ NULL,
|
||||
bus_softc->path_id,
|
||||
targ_id.id,
|
||||
lun_id);
|
||||
CAM_SIM_LOCK(sim);
|
||||
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user