summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2004-02-08 19:17:56 +0000
committermjacob <mjacob@FreeBSD.org>2004-02-08 19:17:56 +0000
commit4977f49a15c933566f6912d44c2d3c9160f290a0 (patch)
tree77d3d2e5a40809fbfc72caac87cfca1b131b2162 /sys/dev
parent140b351eeb87595231bc9f949975576116992abf (diff)
downloadFreeBSD-src-4977f49a15c933566f6912d44c2d3c9160f290a0.zip
FreeBSD-src-4977f49a15c933566f6912d44c2d3c9160f290a0.tar.gz
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
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/isp/isp_freebsd.c415
1 files changed, 169 insertions, 246 deletions
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index 3ce3322..857b62d 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -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)) {
- 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 DISABLE 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_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;
- isp_prt(isp, ISP_LOGINFO,
- "Target Mode disabled on channel %d", bus);
- }
+ 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;
}
-out:
- isp_vsema_rqe(isp, bus);
-
- if (rstat != LUN_OK) {
+ if (lep->le_status != LUN_OK) {
xpt_print_path(ccb->ccb_h.path);
- isp_prt(isp, ISP_LOGWARN,
- "lun %sable failed", (cel->enable) ? "en" : "dis");
+ 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);
- if (cel->enable)
- destroy_lun_state(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_LOGINFO, lfmt, lun,
- (cel->enable) ? "en" : "dis", bus);
+ 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);
- if (cel->enable == 0) {
- destroy_lun_state(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);
+ printf("isp_ledone: isp_lun_cmd failed\n");
+ goto err;
}
- ccb->ccb_h.status = CAM_REQ_CMP;
+ 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 target mode on channel %d failed", bus);
+ } else {
+ isp_prt(isp, ISP_LOGINFO,
+ "Target Mode disabled on channel %d", bus);
+ }
+ 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;
OpenPOWER on IntegriCloud