Remove condition variables and status associated with target mode
enabling. Instead, go to an interrupt/polled model. Fix get_lun_statep so we don't panic if there are no wildcard luns enabled. MFC after: 6 days
This commit is contained in:
parent
c98d7aa472
commit
67ff51f150
@ -201,12 +201,6 @@ isp_attach(struct ispsoftc *isp)
|
||||
isp->isp_path2 = path;
|
||||
}
|
||||
|
||||
#ifdef ISP_TARGET_MODE
|
||||
cv_init(&isp->isp_osinfo.tgtcv0[0], "isp_tgcv0a");
|
||||
cv_init(&isp->isp_osinfo.tgtcv0[1], "isp_tgcv0b");
|
||||
cv_init(&isp->isp_osinfo.tgtcv1[0], "isp_tgcv1a");
|
||||
cv_init(&isp->isp_osinfo.tgtcv1[1], "isp_tgcv1b");
|
||||
#endif
|
||||
/*
|
||||
* Create device nodes
|
||||
*/
|
||||
@ -538,15 +532,12 @@ static INLINE int is_lun_enabled(struct ispsoftc *, int, lun_id_t);
|
||||
static INLINE int are_any_luns_enabled(struct ispsoftc *, int);
|
||||
static INLINE tstate_t *get_lun_statep(struct ispsoftc *, int, lun_id_t);
|
||||
static INLINE void rls_lun_statep(struct ispsoftc *, tstate_t *);
|
||||
static INLINE int isp_psema_sig_rqe(struct ispsoftc *, int);
|
||||
static INLINE int isp_cv_wait_timed_rqe(struct ispsoftc *, int, int);
|
||||
static INLINE void isp_cv_signal_rqe(struct ispsoftc *, int, int);
|
||||
static INLINE void isp_vsema_rqe(struct ispsoftc *, int);
|
||||
static INLINE atio_private_data_t *isp_get_atpd(struct ispsoftc *, int);
|
||||
static cam_status
|
||||
create_lun_state(struct ispsoftc *, int, struct cam_path *, tstate_t **);
|
||||
static void destroy_lun_state(struct ispsoftc *, tstate_t *);
|
||||
static void isp_en_lun(struct ispsoftc *, union ccb *);
|
||||
static int isp_en_lun(struct ispsoftc *, union ccb *);
|
||||
static void isp_ledone(struct ispsoftc *, lun_entry_t *);
|
||||
static cam_status isp_abort_tgt_ccb(struct ispsoftc *, union ccb *);
|
||||
static timeout_t isp_refire_putback_atio;
|
||||
static void isp_complete_ctio(union ccb *);
|
||||
@ -604,6 +595,7 @@ get_lun_statep(struct ispsoftc *isp, int bus, lun_id_t lun)
|
||||
tptr->hold++;
|
||||
return (tptr);
|
||||
}
|
||||
return (NULL);
|
||||
} else {
|
||||
tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(isp, bus, lun)];
|
||||
if (tptr == NULL) {
|
||||
@ -627,74 +619,6 @@ rls_lun_statep(struct ispsoftc *isp, tstate_t *tptr)
|
||||
tptr->hold--;
|
||||
}
|
||||
|
||||
static INLINE int
|
||||
isp_psema_sig_rqe(struct ispsoftc *isp, int bus)
|
||||
{
|
||||
while (isp->isp_osinfo.tmflags[bus] & TM_BUSY) {
|
||||
isp->isp_osinfo.tmflags[bus] |= TM_WANTED;
|
||||
#ifdef ISP_SMPLOCK
|
||||
if (cv_wait_sig(&isp->isp_osinfo.tgtcv0[bus], &isp->isp_lock)) {
|
||||
return (-1);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* It's not allowed for us to use tsleep any more because
|
||||
* a caller might have a non-sleepable lock held.
|
||||
*/
|
||||
#if 0
|
||||
if (tsleep(&isp->isp_osinfo.tgtcv0[bus], PZERO, "cv_isp", 0)) {
|
||||
return (-1);
|
||||
}
|
||||
#else
|
||||
return (-1);
|
||||
#endif
|
||||
#endif
|
||||
isp->isp_osinfo.tmflags[bus] |= TM_BUSY;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static INLINE int
|
||||
isp_cv_wait_timed_rqe(struct ispsoftc *isp, int bus, int timo)
|
||||
{
|
||||
#ifdef ISP_SMPLOCK
|
||||
if (cv_timedwait(&isp->isp_osinfo.tgtcv1[bus], &isp->isp_lock, timo)) {
|
||||
return (-1);
|
||||
}
|
||||
#else
|
||||
if (tsleep(&isp->isp_osinfo.tgtcv1[bus], PZERO, "cv_isp1", 0)) {
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
isp_cv_signal_rqe(struct ispsoftc *isp, int bus, int status)
|
||||
{
|
||||
isp->isp_osinfo.rstatus[bus] = status;
|
||||
#ifdef ISP_SMPLOCK
|
||||
cv_signal(&isp->isp_osinfo.tgtcv1[bus]);
|
||||
#else
|
||||
wakeup(&isp->isp_osinfo.tgtcv1[bus]);
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
isp_vsema_rqe(struct ispsoftc *isp, int bus)
|
||||
{
|
||||
if (isp->isp_osinfo.tmflags[bus] & TM_WANTED) {
|
||||
isp->isp_osinfo.tmflags[bus] &= ~TM_WANTED;
|
||||
#ifdef ISP_SMPLOCK
|
||||
cv_signal(&isp->isp_osinfo.tgtcv0[bus]);
|
||||
#else
|
||||
cv_signal(&isp->isp_osinfo.tgtcv0[bus]);
|
||||
/* wakeup(&isp->isp_osinfo.tgtcv0[bus]); */
|
||||
#endif
|
||||
}
|
||||
isp->isp_osinfo.tmflags[bus] &= ~TM_BUSY;
|
||||
}
|
||||
|
||||
static INLINE atio_private_data_t *
|
||||
isp_get_atpd(struct ispsoftc *isp, int tag)
|
||||
{
|
||||
@ -759,10 +683,10 @@ destroy_lun_state(struct ispsoftc *isp, tstate_t *tptr)
|
||||
int hfx;
|
||||
tstate_t *lw, *pw;
|
||||
|
||||
hfx = LUN_HASH_FUNC(isp, tptr->bus, tptr->lun);
|
||||
if (tptr->hold) {
|
||||
return;
|
||||
}
|
||||
hfx = LUN_HASH_FUNC(isp, tptr->bus, tptr->lun);
|
||||
pw = isp->isp_osinfo.lun_hash[hfx];
|
||||
if (pw == NULL) {
|
||||
return;
|
||||
@ -787,32 +711,37 @@ destroy_lun_state(struct ispsoftc *isp, tstate_t *tptr)
|
||||
}
|
||||
|
||||
/*
|
||||
* we enter with our locks held.
|
||||
* Enable luns.
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
|
||||
{
|
||||
const char lfmt[] = "lun %d now %sabled for target mode on channel %d";
|
||||
struct ccb_en_lun *cel = &ccb->cel;
|
||||
tstate_t *tptr;
|
||||
u_int16_t rstat;
|
||||
u_int32_t seq;
|
||||
int bus, cmd, av, wildcard, tm_on;
|
||||
lun_id_t lun;
|
||||
target_id_t tgt;
|
||||
|
||||
|
||||
bus = XS_CHANNEL(ccb) & 0x1;
|
||||
bus = XS_CHANNEL(ccb);
|
||||
if (bus > 1) {
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
printf("illegal bus %d\n", bus);
|
||||
ccb->ccb_h.status = CAM_PATH_INVALID;
|
||||
return (-1);
|
||||
}
|
||||
tgt = ccb->ccb_h.target_id;
|
||||
lun = ccb->ccb_h.target_lun;
|
||||
|
||||
/*
|
||||
* Do some sanity checking first.
|
||||
*/
|
||||
isp_prt(isp, ISP_LOGTDEBUG0,
|
||||
"isp_en_lun: %sabling lun 0x%x on channel %d",
|
||||
cel->enable? "en" : "dis", lun, bus);
|
||||
|
||||
|
||||
if ((lun != CAM_LUN_WILDCARD) &&
|
||||
(lun < 0 || lun >= (lun_id_t) isp->isp_maxluns)) {
|
||||
ccb->ccb_h.status = CAM_LUN_INVALID;
|
||||
return;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (IS_SCSI(isp)) {
|
||||
@ -821,7 +750,7 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
|
||||
if (tgt != CAM_TARGET_WILDCARD &&
|
||||
tgt != sdp->isp_initiator_id) {
|
||||
ccb->ccb_h.status = CAM_TID_INVALID;
|
||||
return;
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@ -832,7 +761,7 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
|
||||
if (tgt != CAM_TARGET_WILDCARD &&
|
||||
tgt != FCPARAM(isp)->isp_iid) {
|
||||
ccb->ccb_h.status = CAM_TID_INVALID;
|
||||
return;
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
@ -842,7 +771,7 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"firmware does not support target mode");
|
||||
ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
|
||||
return;
|
||||
return (-1);
|
||||
}
|
||||
/*
|
||||
* XXX: We *could* handle non-SCCLUN f/w, but we'd have to
|
||||
@ -852,7 +781,7 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"firmware not SCCLUN capable");
|
||||
ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
|
||||
return;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -861,7 +790,7 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
|
||||
wildcard = 1;
|
||||
} else {
|
||||
ccb->ccb_h.status = CAM_LUN_INVALID;
|
||||
return;
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
wildcard = 0;
|
||||
@ -880,10 +809,9 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
|
||||
if (wildcard) {
|
||||
tptr = &isp->isp_osinfo.tsdflt[bus];
|
||||
if (cel->enable) {
|
||||
if (isp->isp_osinfo.tmflags[bus] &
|
||||
TM_WILDCARD_ENABLED) {
|
||||
if (tm_on) {
|
||||
ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
|
||||
return;
|
||||
return (-1);
|
||||
}
|
||||
ccb->ccb_h.status =
|
||||
xpt_create_path(&tptr->owner, NULL,
|
||||
@ -891,20 +819,19 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
|
||||
xpt_path_target_id(ccb->ccb_h.path),
|
||||
xpt_path_lun_id(ccb->ccb_h.path));
|
||||
if (ccb->ccb_h.status != CAM_REQ_CMP) {
|
||||
return;
|
||||
return (-1);
|
||||
}
|
||||
SLIST_INIT(&tptr->atios);
|
||||
SLIST_INIT(&tptr->inots);
|
||||
isp->isp_osinfo.tmflags[bus] |= TM_WILDCARD_ENABLED;
|
||||
} else {
|
||||
if ((isp->isp_osinfo.tmflags[bus] &
|
||||
TM_WILDCARD_ENABLED) == 0) {
|
||||
if (tm_on == 0) {
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
return;
|
||||
return (-1);
|
||||
}
|
||||
if (tptr->hold) {
|
||||
ccb->ccb_h.status = CAM_SCSI_BUSY;
|
||||
return;
|
||||
return (-1);
|
||||
}
|
||||
xpt_free_path(tptr->owner);
|
||||
isp->isp_osinfo.tmflags[bus] &= ~TM_WILDCARD_ENABLED;
|
||||
@ -926,7 +853,7 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
|
||||
~TM_WILDCARD_ENABLED;
|
||||
xpt_free_path(tptr->owner);
|
||||
}
|
||||
return;
|
||||
return (-1);
|
||||
}
|
||||
isp->isp_osinfo.tmflags[bus] |= TM_TMODE_ENABLED;
|
||||
isp_prt(isp, ISP_LOGINFO,
|
||||
@ -934,12 +861,12 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
|
||||
} else if (cel->enable == 0 && tm_on && wildcard) {
|
||||
if (are_any_luns_enabled(isp, bus)) {
|
||||
ccb->ccb_h.status = CAM_SCSI_BUSY;
|
||||
return;
|
||||
return (-1);
|
||||
}
|
||||
av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
|
||||
if (av) {
|
||||
ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
|
||||
return;
|
||||
return (-1);
|
||||
}
|
||||
isp->isp_osinfo.tmflags[bus] &= ~TM_TMODE_ENABLED;
|
||||
isp_prt(isp, ISP_LOGINFO,
|
||||
@ -948,33 +875,40 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
|
||||
|
||||
if (wildcard) {
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
return;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an empty slot
|
||||
*/
|
||||
for (seq = 0; seq < NLEACT; seq++) {
|
||||
if (isp->isp_osinfo.leact[seq] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (seq >= NLEACT) {
|
||||
ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
|
||||
return (-1);
|
||||
|
||||
}
|
||||
isp->isp_osinfo.leact[seq] = ccb;
|
||||
|
||||
if (cel->enable) {
|
||||
ccb->ccb_h.status =
|
||||
create_lun_state(isp, bus, ccb->ccb_h.path, &tptr);
|
||||
if (ccb->ccb_h.status != CAM_REQ_CMP) {
|
||||
return;
|
||||
isp->isp_osinfo.leact[seq] = 0;
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
tptr = get_lun_statep(isp, bus, lun);
|
||||
if (tptr == NULL) {
|
||||
ccb->ccb_h.status = CAM_LUN_INVALID;
|
||||
return;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (isp_psema_sig_rqe(isp, bus)) {
|
||||
rls_lun_statep(isp, tptr);
|
||||
if (cel->enable)
|
||||
destroy_lun_state(isp, tptr);
|
||||
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cel->enable) {
|
||||
u_int32_t seq = isp->isp_osinfo.rollinfo++;
|
||||
int c, n, ulun = lun;
|
||||
|
||||
cmd = RQSTYPE_ENABLE_LUN;
|
||||
@ -989,33 +923,15 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
|
||||
*/
|
||||
ulun = 0;
|
||||
}
|
||||
rstat = LUN_ERR;
|
||||
if (isp_lun_cmd(isp, cmd, bus, tgt, ulun, c, n, seq)) {
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
isp_prt(isp, ISP_LOGWARN, "isp_lun_cmd failed");
|
||||
goto out;
|
||||
}
|
||||
if (isp_cv_wait_timed_rqe(isp, bus, 30 * hz)) {
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"wait for ENABLE/MODIFY LUN timed out");
|
||||
goto out;
|
||||
}
|
||||
rstat = isp->isp_osinfo.rstatus[bus];
|
||||
if (rstat != LUN_OK) {
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"ENABLE/MODIFY LUN returned 0x%x", rstat);
|
||||
goto out;
|
||||
if (isp_lun_cmd(isp, cmd, bus, tgt, ulun, c, n, seq+1) == 0) {
|
||||
rls_lun_statep(isp, tptr);
|
||||
ccb->ccb_h.status = CAM_REQ_INPROG;
|
||||
return (seq);
|
||||
}
|
||||
} else {
|
||||
int c, n, ulun = lun;
|
||||
u_int32_t seq;
|
||||
|
||||
rstat = LUN_ERR;
|
||||
seq = isp->isp_osinfo.rollinfo++;
|
||||
cmd = -RQSTYPE_MODIFY_LUN;
|
||||
|
||||
c = DFLT_CMND_CNT;
|
||||
n = DFLT_INOT_CNT;
|
||||
if (IS_FC(isp) && lun != 0) {
|
||||
@ -1026,86 +942,116 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
|
||||
*/
|
||||
ulun = 0;
|
||||
}
|
||||
if (isp_lun_cmd(isp, cmd, bus, tgt, ulun, c, n, seq)) {
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
isp_prt(isp, ISP_LOGERR, "isp_lun_cmd failed");
|
||||
goto out;
|
||||
}
|
||||
if (isp_cv_wait_timed_rqe(isp, bus, 30 * hz)) {
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"wait for MODIFY LUN timed out");
|
||||
goto out;
|
||||
}
|
||||
rstat = isp->isp_osinfo.rstatus[bus];
|
||||
if (rstat != LUN_OK) {
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"MODIFY LUN returned 0x%x", rstat);
|
||||
goto out;
|
||||
}
|
||||
if (IS_FC(isp) && lun) {
|
||||
goto out;
|
||||
if (isp_lun_cmd(isp, cmd, bus, tgt, ulun, c, n, seq+1) == 0) {
|
||||
rls_lun_statep(isp, tptr);
|
||||
ccb->ccb_h.status = CAM_REQ_INPROG;
|
||||
return (seq);
|
||||
}
|
||||
}
|
||||
rls_lun_statep(isp, tptr);
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
printf("isp_lun_cmd failed\n");
|
||||
isp->isp_osinfo.leact[seq] = 0;
|
||||
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
seq = isp->isp_osinfo.rollinfo++;
|
||||
static void
|
||||
isp_ledone(struct ispsoftc *isp, lun_entry_t *lep)
|
||||
{
|
||||
const char lfmt[] = "lun %d now %sabled for target mode on channel %d";
|
||||
union ccb *ccb;
|
||||
u_int32_t seq;
|
||||
tstate_t *tptr;
|
||||
int av;
|
||||
struct ccb_en_lun *cel;
|
||||
|
||||
rstat = LUN_ERR;
|
||||
cmd = -RQSTYPE_ENABLE_LUN;
|
||||
if (isp_lun_cmd(isp, cmd, bus, tgt, lun, 0, 0, seq)) {
|
||||
seq = lep->le_reserved - 1;
|
||||
if (seq >= NLEACT) {
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"seq out of range (%u) in isp_ledone", seq);
|
||||
return;
|
||||
}
|
||||
ccb = isp->isp_osinfo.leact[seq];
|
||||
if (ccb == 0) {
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"no ccb for seq %u in isp_ledone", seq);
|
||||
return;
|
||||
}
|
||||
cel = &ccb->cel;
|
||||
tptr = get_lun_statep(isp, XS_CHANNEL(ccb), XS_LUN(ccb));
|
||||
if (tptr == NULL) {
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
printf("null tptr in isp_ledone\n");
|
||||
isp->isp_osinfo.leact[seq] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (lep->le_status != LUN_OK) {
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
printf("ENABLE/MODIFY LUN returned 0x%x\n", lep->le_status);
|
||||
err:
|
||||
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
rls_lun_statep(isp, tptr);
|
||||
isp->isp_osinfo.leact[seq] = 0;
|
||||
ISPLOCK_2_CAMLOCK(isp);
|
||||
xpt_done(ccb);
|
||||
CAMLOCK_2_ISPLOCK(isp);
|
||||
return;
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGTDEBUG0,
|
||||
"isp_ledone: ENABLE/MODIFY done okay");
|
||||
}
|
||||
|
||||
|
||||
if (cel->enable) {
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
isp_prt(isp, /* ISP_LOGINFO */ ISP_LOGALL, lfmt,
|
||||
XS_LUN(ccb), "en", XS_CHANNEL(ccb));
|
||||
rls_lun_statep(isp, tptr);
|
||||
isp->isp_osinfo.leact[seq] = 0;
|
||||
ISPLOCK_2_CAMLOCK(isp);
|
||||
xpt_done(ccb);
|
||||
CAMLOCK_2_ISPLOCK(isp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lep->le_header.rqs_entry_type == RQSTYPE_MODIFY_LUN) {
|
||||
if (isp_lun_cmd(isp, -RQSTYPE_ENABLE_LUN, XS_CHANNEL(ccb),
|
||||
XS_TGT(ccb), XS_LUN(ccb), 0, 0, seq+1)) {
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
isp_prt(isp, ISP_LOGERR, "isp_lun_cmd failed");
|
||||
goto out;
|
||||
printf("isp_ledone: isp_lun_cmd failed\n");
|
||||
goto err;
|
||||
}
|
||||
if (isp_cv_wait_timed_rqe(isp, bus, 30 * hz)) {
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
isp_prt(isp, ISP_LOGERR,
|
||||
"wait for DISABLE LUN timed out");
|
||||
goto out;
|
||||
}
|
||||
rstat = isp->isp_osinfo.rstatus[bus];
|
||||
if (rstat != LUN_OK) {
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
rls_lun_statep(isp, tptr);
|
||||
return;
|
||||
}
|
||||
|
||||
isp_prt(isp, ISP_LOGINFO, lfmt, XS_LUN(ccb), "dis", XS_CHANNEL(ccb));
|
||||
rls_lun_statep(isp, tptr);
|
||||
destroy_lun_state(isp, tptr);
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
isp->isp_osinfo.leact[seq] = 0;
|
||||
ISPLOCK_2_CAMLOCK(isp);
|
||||
xpt_done(ccb);
|
||||
CAMLOCK_2_ISPLOCK(isp);
|
||||
if (are_any_luns_enabled(isp, XS_CHANNEL(ccb)) == 0) {
|
||||
int bus = XS_CHANNEL(ccb);
|
||||
av = bus << 31;
|
||||
av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
|
||||
if (av) {
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"DISABLE LUN returned 0x%x", rstat);
|
||||
goto out;
|
||||
}
|
||||
if (are_any_luns_enabled(isp, bus) == 0) {
|
||||
av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
|
||||
if (av) {
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"disable target mode on channel %d failed",
|
||||
bus);
|
||||
goto out;
|
||||
}
|
||||
isp->isp_osinfo.tmflags[bus] &= ~TM_TMODE_ENABLED;
|
||||
"disable target mode on channel %d failed", bus);
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGINFO,
|
||||
"Target Mode disabled on channel %d", bus);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
isp_vsema_rqe(isp, bus);
|
||||
|
||||
if (rstat != LUN_OK) {
|
||||
xpt_print_path(ccb->ccb_h.path);
|
||||
isp_prt(isp, ISP_LOGWARN,
|
||||
"lun %sable failed", (cel->enable) ? "en" : "dis");
|
||||
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
|
||||
rls_lun_statep(isp, tptr);
|
||||
if (cel->enable)
|
||||
destroy_lun_state(isp, tptr);
|
||||
} else {
|
||||
isp_prt(isp, ISP_LOGINFO, lfmt, lun,
|
||||
(cel->enable) ? "en" : "dis", bus);
|
||||
rls_lun_statep(isp, tptr);
|
||||
if (cel->enable == 0) {
|
||||
destroy_lun_state(isp, tptr);
|
||||
}
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
isp->isp_osinfo.tmflags[bus] &= ~TM_TMODE_ENABLED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static cam_status
|
||||
isp_abort_tgt_ccb(struct ispsoftc *isp, union ccb *ccb)
|
||||
{
|
||||
@ -1604,35 +1550,6 @@ isp_handle_platform_atio2(struct ispsoftc *isp, at2_entry_t *aep)
|
||||
}
|
||||
}
|
||||
|
||||
if (tptr == NULL) {
|
||||
/*
|
||||
* What we'd like to know is whether or not we have a listener
|
||||
* upstream that really hasn't configured yet. If we do, then
|
||||
* we can give a more sensible reply here. If not, then we can
|
||||
* reject this out of hand.
|
||||
*
|
||||
* Choices for what to send were
|
||||
*
|
||||
* Not Ready, Unit Not Self-Configured Yet
|
||||
* (0x2,0x3e,0x00)
|
||||
*
|
||||
* for the former and
|
||||
*
|
||||
* Illegal Request, Logical Unit Not Supported
|
||||
* (0x5,0x25,0x00)
|
||||
*
|
||||
* for the latter.
|
||||
*
|
||||
* We used to decide whether there was at least one listener
|
||||
* based upon whether the black hole driver was configured.
|
||||
* However, recent config(8) changes have made this hard to do
|
||||
* at this time.
|
||||
*
|
||||
*/
|
||||
isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
atp = isp_get_atpd(isp, 0);
|
||||
atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
|
||||
if (atiop == NULL || atp == NULL) {
|
||||
@ -1699,6 +1616,7 @@ isp_handle_platform_atio2(struct ispsoftc *isp, at2_entry_t *aep)
|
||||
atp->last_xframt = 0;
|
||||
atp->bytes_xfered = 0;
|
||||
atp->state = ATPD_STATE_CAM;
|
||||
ISPLOCK_2_CAMLOCK(siP);
|
||||
xpt_done((union ccb*)atiop);
|
||||
|
||||
isp_prt(isp, ISP_LOGTDEBUG0,
|
||||
@ -2216,14 +2134,26 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
|
||||
#ifdef ISP_TARGET_MODE
|
||||
case XPT_EN_LUN: /* Enable LUN as a target */
|
||||
{
|
||||
int iok;
|
||||
int seq, iok, i;
|
||||
CAMLOCK_2_ISPLOCK(isp);
|
||||
iok = isp->isp_osinfo.intsok;
|
||||
isp->isp_osinfo.intsok = 0;
|
||||
isp_en_lun(isp, ccb);
|
||||
seq = isp_en_lun(isp, ccb);
|
||||
if (seq < 0) {
|
||||
isp->isp_osinfo.intsok = iok;
|
||||
ISPLOCK_2_CAMLOCK(isp);
|
||||
xpt_done(ccb);
|
||||
break;
|
||||
}
|
||||
for (i = 0; isp->isp_osinfo.leact[seq] && i < 30 * 1000; i++) {
|
||||
u_int16_t isr, sema, mbox;
|
||||
if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
|
||||
isp_intr(isp, isr, sema, mbox);
|
||||
}
|
||||
DELAY(1000);
|
||||
}
|
||||
isp->isp_osinfo.intsok = iok;
|
||||
ISPLOCK_2_CAMLOCK(isp);
|
||||
xpt_done(ccb);
|
||||
break;
|
||||
}
|
||||
case XPT_NOTIFY_ACK: /* recycle notify ack */
|
||||
@ -3122,14 +3052,7 @@ isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg)
|
||||
break;
|
||||
case RQSTYPE_ENABLE_LUN:
|
||||
case RQSTYPE_MODIFY_LUN:
|
||||
if (IS_DUALBUS(isp)) {
|
||||
bus =
|
||||
GET_BUS_VAL(((lun_entry_t *)arg)->le_rsvd);
|
||||
} else {
|
||||
bus = 0;
|
||||
}
|
||||
isp_cv_signal_rqe(isp, bus,
|
||||
((lun_entry_t *)arg)->le_status);
|
||||
isp_ledone(isp, (lun_entry_t *) arg);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user