summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp/isp_freebsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/isp/isp_freebsd.c')
-rw-r--r--sys/dev/isp/isp_freebsd.c1058
1 files changed, 194 insertions, 864 deletions
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index 6d7033a..73741eb 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -50,13 +50,13 @@ __FBSDID("$FreeBSD$");
MODULE_VERSION(isp, 1);
MODULE_DEPEND(isp, cam, 1, 1, 1);
int isp_announced = 0;
-int isp_fabric_hysteresis = 5;
int isp_loop_down_limit = 60; /* default loop down limit */
int isp_quickboot_time = 7; /* don't wait more than N secs for loop up */
int isp_gone_device_time = 30; /* grace time before reporting device lost */
static const char prom3[] = "Chan %d [%u] PortID 0x%06x Departed because of %s";
-static void isp_freeze_loopdown(ispsoftc_t *, int, char *);
+static void isp_freeze_loopdown(ispsoftc_t *, int);
+static void isp_loop_changed(ispsoftc_t *isp, int chan);
static d_ioctl_t ispioctl;
static void isp_intr_enable(void *);
static void isp_cam_async(void *, uint32_t, struct cam_path *, void *);
@@ -64,8 +64,6 @@ static void isp_poll(struct cam_sim *);
static timeout_t isp_watchdog;
static timeout_t isp_gdt;
static task_fn_t isp_gdt_task;
-static timeout_t isp_ldt;
-static task_fn_t isp_ldt_task;
static void isp_kthread(void *);
static void isp_action(struct cam_sim *, union ccb *);
static int isp_timer_count;
@@ -168,25 +166,13 @@ isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan)
fc->isp = isp;
fc->ready = 1;
- callout_init_mtx(&fc->ldt, &isp->isp_osinfo.lock, 0);
callout_init_mtx(&fc->gdt, &isp->isp_osinfo.lock, 0);
- TASK_INIT(&fc->ltask, 1, isp_ldt_task, fc);
TASK_INIT(&fc->gtask, 1, isp_gdt_task, fc);
-
- /*
- * We start by being "loop down" if we have an initiator role
- */
- if (fcp->role & ISP_ROLE_INITIATOR) {
- isp_freeze_loopdown(isp, chan, "isp_attach");
- callout_reset(&fc->ldt, isp_quickboot_time * hz, isp_ldt, fc);
- isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Starting Initial Loop Down Timer @ %lu", (unsigned long) time_uptime);
- }
+ isp_loop_changed(isp, chan);
ISP_UNLOCK(isp);
if (THREAD_CREATE(isp_kthread, fc, &fc->kproc, 0, 0, "%s: fc_thrd%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) {
xpt_free_path(fc->path);
ISP_LOCK(isp);
- if (callout_active(&fc->ldt))
- callout_stop(&fc->ldt);
xpt_bus_deregister(cam_sim_path(fc->sim));
ISP_UNLOCK(isp);
cam_sim_free(fc->sim, FALSE);
@@ -377,13 +363,13 @@ isp_detach(ispsoftc_t *isp)
}
static void
-isp_freeze_loopdown(ispsoftc_t *isp, int chan, char *msg)
+isp_freeze_loopdown(ispsoftc_t *isp, int chan)
{
if (IS_FC(isp)) {
struct isp_fc *fc = ISP_FC_PC(isp, chan);
if (fc->simqfrozen == 0) {
isp_prt(isp, ISP_LOGDEBUG0,
- "Chan %d %s -- freeze simq (loopdown)", chan, msg);
+ "Chan %d Freeze simq (loopdown)", chan);
fc->simqfrozen = SIMQFRZ_LOOPDOWN;
#if __FreeBSD_version >= 1000039
xpt_hold_boot();
@@ -391,7 +377,7 @@ isp_freeze_loopdown(ispsoftc_t *isp, int chan, char *msg)
xpt_freeze_simq(fc->sim, 1);
} else {
isp_prt(isp, ISP_LOGDEBUG0,
- "Chan %d %s -- mark frozen (loopdown)", chan, msg);
+ "Chan %d Mark simq frozen (loopdown)", chan);
fc->simqfrozen |= SIMQFRZ_LOOPDOWN;
}
}
@@ -405,7 +391,8 @@ isp_unfreeze_loopdown(ispsoftc_t *isp, int chan)
int wasfrozen = fc->simqfrozen & SIMQFRZ_LOOPDOWN;
fc->simqfrozen &= ~SIMQFRZ_LOOPDOWN;
if (wasfrozen && fc->simqfrozen == 0) {
- isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d releasing simq", __func__, chan);
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "Chan %d Release simq", chan);
xpt_release_simq(fc->sim, 1);
#if __FreeBSD_version >= 1000039
xpt_release_boot();
@@ -441,11 +428,13 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
if (IS_FC(isp)) {
*(int *)addr = FCPARAM(isp, chan)->role;
} else {
- *(int *)addr = SDPARAM(isp, chan)->role;
+ *(int *)addr = ISP_ROLE_INITIATOR;
}
retval = 0;
break;
case ISP_SETROLE:
+ if (IS_SCSI(isp))
+ break;
nr = *(int *)addr;
chan = nr >> 8;
if (chan < 0 || chan >= isp->isp_nchan) {
@@ -458,10 +447,7 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
break;
}
ISP_LOCK(isp);
- if (IS_FC(isp))
- *(int *)addr = FCPARAM(isp, chan)->role;
- else
- *(int *)addr = SDPARAM(isp, chan)->role;
+ *(int *)addr = FCPARAM(isp, chan)->role;
retval = isp_control(isp, ISPCTL_CHANGE_ROLE, chan, nr);
ISP_UNLOCK(isp);
retval = 0;
@@ -482,7 +468,7 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
break;
}
ISP_LOCK(isp);
- if (isp_fc_runstate(isp, chan, 5 * 1000000)) {
+ if (isp_fc_runstate(isp, chan, 5 * 1000000) != LOOP_READY) {
retval = EIO;
} else {
retval = 0;
@@ -604,7 +590,7 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
{
int needmarker;
struct isp_fc_tsk_mgmt *fct = (struct isp_fc_tsk_mgmt *) addr;
- uint16_t loopid;
+ uint16_t nphdl;
mbreg_t mbs;
if (IS_SCSI(isp)) {
@@ -618,7 +604,7 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
}
needmarker = retval = 0;
- loopid = fct->loopid;
+ nphdl = fct->loopid;
ISP_LOCK(isp);
if (IS_24XX(isp)) {
uint8_t local[QENTRY_LEN];
@@ -630,7 +616,7 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
for (i = 0; i < MAX_FC_TARG; i++) {
lp = &fcp->portdb[i];
- if (lp->handle == loopid) {
+ if (lp->handle == nphdl) {
break;
}
}
@@ -714,34 +700,34 @@ ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td)
} else {
MBSINIT(&mbs, 0, MBLOGALL, 0);
if (ISP_CAP_2KLOGIN(isp) == 0) {
- loopid <<= 8;
+ nphdl <<= 8;
}
switch (fct->action) {
case IPT_CLEAR_ACA:
mbs.param[0] = MBOX_CLEAR_ACA;
- mbs.param[1] = loopid;
+ mbs.param[1] = nphdl;
mbs.param[2] = fct->lun;
break;
case IPT_TARGET_RESET:
mbs.param[0] = MBOX_TARGET_RESET;
- mbs.param[1] = loopid;
+ mbs.param[1] = nphdl;
needmarker = 1;
break;
case IPT_LUN_RESET:
mbs.param[0] = MBOX_LUN_RESET;
- mbs.param[1] = loopid;
+ mbs.param[1] = nphdl;
mbs.param[2] = fct->lun;
needmarker = 1;
break;
case IPT_CLEAR_TASK_SET:
mbs.param[0] = MBOX_CLEAR_TASK_SET;
- mbs.param[1] = loopid;
+ mbs.param[1] = nphdl;
mbs.param[2] = fct->lun;
needmarker = 1;
break;
case IPT_ABORT_TASK_SET:
mbs.param[0] = MBOX_ABORT_TASK_SET;
- mbs.param[1] = loopid;
+ mbs.param[1] = nphdl;
mbs.param[2] = fct->lun;
needmarker = 1;
break;
@@ -774,18 +760,15 @@ isp_intr_enable(void *arg)
int chan;
ispsoftc_t *isp = arg;
ISP_LOCK(isp);
- for (chan = 0; chan < isp->isp_nchan; chan++) {
- if (IS_FC(isp)) {
+ if (IS_FC(isp)) {
+ for (chan = 0; chan < isp->isp_nchan; chan++) {
if (FCPARAM(isp, chan)->role != ISP_ROLE_NONE) {
ISP_ENABLE_INTS(isp);
break;
}
- } else {
- if (SDPARAM(isp, chan)->role != ISP_ROLE_NONE) {
- ISP_ENABLE_INTS(isp);
- break;
- }
}
+ } else {
+ ISP_ENABLE_INTS(isp);
}
isp->isp_osinfo.ehook_active = 0;
ISP_UNLOCK(isp);
@@ -831,9 +814,6 @@ isp_free_pcmd(ispsoftc_t *isp, union ccb *ccb)
* Put the target mode functions here, because some are inlines
*/
#ifdef ISP_TARGET_MODE
-static ISP_INLINE void isp_tmlock(ispsoftc_t *, const char *);
-static ISP_INLINE void isp_tmunlk(ispsoftc_t *);
-static ISP_INLINE int is_any_lun_enabled(ispsoftc_t *, int);
static ISP_INLINE int is_lun_enabled(ispsoftc_t *, int, lun_id_t);
static ISP_INLINE tstate_t *get_lun_statep(ispsoftc_t *, int, lun_id_t);
static ISP_INLINE tstate_t *get_lun_statep_from_tag(ispsoftc_t *, int, uint32_t);
@@ -848,23 +828,16 @@ static ISP_INLINE void isp_put_ntpd(ispsoftc_t *, tstate_t *, inot_private_data_
static cam_status create_lun_state(ispsoftc_t *, int, struct cam_path *, tstate_t **);
static void destroy_lun_state(ispsoftc_t *, tstate_t *);
static void isp_enable_lun(ispsoftc_t *, union ccb *);
-static cam_status isp_enable_deferred_luns(ispsoftc_t *, int);
-static cam_status isp_enable_deferred(ispsoftc_t *, int, lun_id_t);
static void isp_disable_lun(ispsoftc_t *, union ccb *);
-static int isp_enable_target_mode(ispsoftc_t *, int);
-static int isp_disable_target_mode(ispsoftc_t *, int);
-static void isp_ledone(ispsoftc_t *, lun_entry_t *);
static timeout_t isp_refire_putback_atio;
static timeout_t isp_refire_notify_ack;
static void isp_complete_ctio(union ccb *);
static void isp_target_putback_atio(union ccb *);
enum Start_Ctio_How { FROM_CAM, FROM_TIMER, FROM_SRR, FROM_CTIO_DONE };
static void isp_target_start_ctio(ispsoftc_t *, union ccb *, enum Start_Ctio_How);
-static void isp_handle_platform_atio(ispsoftc_t *, at_entry_t *);
static void isp_handle_platform_atio2(ispsoftc_t *, at2_entry_t *);
static void isp_handle_platform_atio7(ispsoftc_t *, at7_entry_t *);
static void isp_handle_platform_ctio(ispsoftc_t *, void *);
-static void isp_handle_platform_notify_scsi(ispsoftc_t *, in_entry_t *);
static void isp_handle_platform_notify_fc(ispsoftc_t *, in_fcentry_t *);
static void isp_handle_platform_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *);
static int isp_handle_platform_target_notify_ack(ispsoftc_t *, isp_notify_t *);
@@ -872,40 +845,6 @@ static void isp_handle_platform_target_tmf(ispsoftc_t *, isp_notify_t *);
static void isp_target_mark_aborted(ispsoftc_t *, union ccb *);
static void isp_target_mark_aborted_early(ispsoftc_t *, tstate_t *, uint32_t);
-static ISP_INLINE void
-isp_tmlock(ispsoftc_t *isp, const char *msg)
-{
- while (isp->isp_osinfo.tmbusy) {
- isp->isp_osinfo.tmwanted = 1;
- mtx_sleep(isp, &isp->isp_lock, PRIBIO, msg, 0);
- }
- isp->isp_osinfo.tmbusy = 1;
-}
-
-static ISP_INLINE void
-isp_tmunlk(ispsoftc_t *isp)
-{
- isp->isp_osinfo.tmbusy = 0;
- if (isp->isp_osinfo.tmwanted) {
- isp->isp_osinfo.tmwanted = 0;
- wakeup(isp);
- }
-}
-
-static ISP_INLINE int
-is_any_lun_enabled(ispsoftc_t *isp, int bus)
-{
- struct tslist *lhp;
- int i;
-
- for (i = 0; i < LUN_HASH_SIZE; i++) {
- ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
- if (SLIST_FIRST(lhp))
- return (1);
- }
- return (0);
-}
-
static ISP_INLINE int
is_lun_enabled(ispsoftc_t *isp, int bus, lun_id_t lun)
{
@@ -1107,7 +1046,7 @@ isp_dump_atpd(ispsoftc_t *isp, tstate_t *tptr)
const char *states[8] = { "Free", "ATIO", "CAM", "CTIO", "LAST_CTIO", "PDON", "?6", "7" };
for (atp = tptr->atpool; atp < &tptr->atpool[ATPDPSIZE]; atp++) {
- xpt_print(tptr->owner, "ATP: [0x%x] origdlen %u bytes_xfrd %u lun %u nphdl 0x%04x s_id 0x%06x d_id 0x%06x oxid 0x%04x state %s\n",
+ xpt_print(tptr->owner, "ATP: [0x%x] origdlen %u bytes_xfrd %u lun %x nphdl 0x%04x s_id 0x%06x d_id 0x%06x oxid 0x%04x state %s\n",
atp->tag, atp->orig_datalen, atp->bytes_xfered, atp->lun, atp->nphdl, atp->sid, atp->portid, atp->oxid, states[atp->state & 0x7]);
}
}
@@ -1222,232 +1161,59 @@ destroy_lun_state(ispsoftc_t *isp, tstate_t *tptr)
free(tptr, M_DEVBUF);
}
-/*
- * Enable a lun.
- */
static void
isp_enable_lun(ispsoftc_t *isp, union ccb *ccb)
{
- tstate_t *tptr = NULL;
- int bus, tm_enabled, target_role;
+ tstate_t *tptr;
+ int bus;
target_id_t target;
lun_id_t lun;
+ if (!IS_FC(isp) || !ISP_CAP_TMODE(isp) || !ISP_CAP_SCCFW(isp)) {
+ xpt_print(ccb->ccb_h.path, "Target mode is not supported\n");
+ ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
+ xpt_done(ccb);
+ return;
+ }
/*
- * We only support either a wildcard target/lun or a target ID of zero and a non-wildcard lun
+ * We only support either target and lun both wildcard
+ * or target and lun both non-wildcard.
*/
bus = XS_CHANNEL(ccb);
target = ccb->ccb_h.target_id;
lun = ccb->ccb_h.target_lun;
ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path,
"enabling lun %jx\n", (uintmax_t)lun);
- if (target == CAM_TARGET_WILDCARD && lun != CAM_LUN_WILDCARD) {
- ccb->ccb_h.status = CAM_LUN_INVALID;
- xpt_done(ccb);
- return;
- }
-
- if (target != CAM_TARGET_WILDCARD && lun == CAM_LUN_WILDCARD) {
+ if ((target == CAM_TARGET_WILDCARD) != (lun == CAM_LUN_WILDCARD)) {
ccb->ccb_h.status = CAM_LUN_INVALID;
xpt_done(ccb);
return;
}
- if (isp->isp_dblev & ISP_LOGTDEBUG0) {
- xpt_print(ccb->ccb_h.path,
- "enabling lun 0x%jx on channel %d\n", (uintmax_t)lun, bus);
- }
-
- /*
- * Wait until we're not busy with the lun enables subsystem
- */
- isp_tmlock(isp, "isp_enable_lun");
-
- /*
- * This is as a good a place as any to check f/w capabilities.
- */
-
- if (IS_FC(isp)) {
- if (ISP_CAP_TMODE(isp) == 0) {
- xpt_print(ccb->ccb_h.path, "firmware does not support target mode\n");
- ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
- goto done;
- }
- /*
- * We *could* handle non-SCCLUN f/w, but we'd have to
- * dork with our already fragile enable/disable code.
- */
- if (ISP_CAP_SCCFW(isp) == 0) {
- xpt_print(ccb->ccb_h.path, "firmware not SCCLUN capable\n");
- ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
- goto done;
- }
-
- target_role = (FCPARAM(isp, bus)->role & ISP_ROLE_TARGET) != 0;
- } else {
- target_role = (SDPARAM(isp, bus)->role & ISP_ROLE_TARGET) != 0;
- }
-
- /*
- * Create the state pointer.
- * It should not already exist.
- */
+ /* Create the state pointer. It should not already exist. */
tptr = get_lun_statep(isp, bus, lun);
if (tptr) {
ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
- goto done;
+ xpt_done(ccb);
+ return;
}
ccb->ccb_h.status = create_lun_state(isp, bus, ccb->ccb_h.path, &tptr);
if (ccb->ccb_h.status != CAM_REQ_CMP) {
- goto done;
- }
-
- /*
- * We have a tricky maneuver to perform here.
- *
- * If target mode isn't already enabled here,
- * *and* our current role includes target mode,
- * we enable target mode here.
- *
- */
- ISP_GET_PC(isp, bus, tm_enabled, tm_enabled);
- if (tm_enabled == 0 && target_role != 0) {
- if (isp_enable_target_mode(isp, bus)) {
- ccb->ccb_h.status = CAM_REQ_CMP_ERR;
- destroy_lun_state(isp, tptr);
- tptr = NULL;
- goto done;
- }
- tm_enabled = 1;
- }
-
- /*
- * Now check to see whether this bus is in target mode already.
- *
- * If not, a later role change into target mode will finish the job.
- */
- if (tm_enabled == 0) {
- ISP_SET_PC(isp, bus, tm_enable_defer, 1);
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_print(ccb->ccb_h.path, "Target Mode not enabled yet- lun enable deferred\n");
- goto done1;
- }
-
- /*
- * Enable the lun.
- */
- ccb->ccb_h.status = isp_enable_deferred(isp, bus, lun);
-
-done:
- if (ccb->ccb_h.status != CAM_REQ_CMP) {
- if (tptr) {
- destroy_lun_state(isp, tptr);
- tptr = NULL;
- }
- } else {
- tptr->enabled = 1;
- }
-done1:
- if (tptr) {
- rls_lun_statep(isp, tptr);
+ xpt_done(ccb);
+ return;
}
- /*
- * And we're outta here....
- */
- isp_tmunlk(isp);
+ rls_lun_statep(isp, tptr);
+ ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
}
-static cam_status
-isp_enable_deferred_luns(ispsoftc_t *isp, int bus)
-{
- tstate_t *tptr = NULL;
- struct tslist *lhp;
- int i, n;
-
-
- ISP_GET_PC(isp, bus, tm_enabled, i);
- if (i == 1) {
- return (CAM_REQ_CMP);
- }
- ISP_GET_PC(isp, bus, tm_enable_defer, i);
- if (i == 0) {
- return (CAM_REQ_CMP);
- }
- /*
- * If this succeeds, it will set tm_enable
- */
- if (isp_enable_target_mode(isp, bus)) {
- return (CAM_REQ_CMP_ERR);
- }
- isp_tmlock(isp, "isp_enable_deferred_luns");
- for (n = i = 0; i < LUN_HASH_SIZE; i++) {
- ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp);
- SLIST_FOREACH(tptr, lhp, next) {
- tptr->hold++;
- if (tptr->enabled == 0) {
- if (isp_enable_deferred(isp, bus, tptr->ts_lun) == CAM_REQ_CMP) {
- tptr->enabled = 1;
- n++;
- }
- } else {
- n++;
- }
- tptr->hold--;
- }
- }
- isp_tmunlk(isp);
- if (n == 0) {
- return (CAM_REQ_CMP_ERR);
- }
- ISP_SET_PC(isp, bus, tm_enable_defer, 0);
- return (CAM_REQ_CMP);
-}
-
-static cam_status
-isp_enable_deferred(ispsoftc_t *isp, int bus, lun_id_t lun)
-{
- cam_status status;
- int luns_already_enabled;
-
- ISP_GET_PC(isp, bus, tm_luns_enabled, luns_already_enabled);
- isp_prt(isp, ISP_LOGTINFO, "%s: bus %d lun %u luns_enabled %d", __func__, bus, lun, luns_already_enabled);
- if (IS_24XX(isp) || (IS_FC(isp) && luns_already_enabled)) {
- status = CAM_REQ_CMP;
- } else {
- int cmd_cnt, not_cnt;
-
- if (IS_23XX(isp)) {
- cmd_cnt = DFLT_CMND_CNT;
- not_cnt = DFLT_INOT_CNT;
- } else {
- cmd_cnt = 64;
- not_cnt = 8;
- }
- status = CAM_REQ_INPROG;
- isp->isp_osinfo.rptr = &status;
- if (isp_lun_cmd(isp, RQSTYPE_ENABLE_LUN, bus, lun == CAM_LUN_WILDCARD? 0 : lun, cmd_cnt, not_cnt)) {
- status = CAM_RESRC_UNAVAIL;
- } else {
- mtx_sleep(&status, &isp->isp_lock, PRIBIO, "isp_enable_deferred", 0);
- }
- isp->isp_osinfo.rptr = NULL;
- }
- if (status == CAM_REQ_CMP) {
- ISP_SET_PC(isp, bus, tm_luns_enabled, 1);
- isp_prt(isp, ISP_LOGCONFIG|ISP_LOGTINFO, "bus %d lun %u now enabled for target mode", bus, lun);
- }
- return (status);
-}
-
static void
isp_disable_lun(ispsoftc_t *isp, union ccb *ccb)
{
tstate_t *tptr = NULL;
int bus;
- cam_status status;
target_id_t target;
lun_id_t lun;
@@ -1456,143 +1222,24 @@ isp_disable_lun(ispsoftc_t *isp, union ccb *ccb)
lun = ccb->ccb_h.target_lun;
ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path,
"disabling lun %jx\n", (uintmax_t)lun);
- if (target == CAM_TARGET_WILDCARD && lun != CAM_LUN_WILDCARD) {
+ if ((target == CAM_TARGET_WILDCARD) != (lun == CAM_LUN_WILDCARD)) {
ccb->ccb_h.status = CAM_LUN_INVALID;
xpt_done(ccb);
return;
}
- if (target != CAM_TARGET_WILDCARD && lun == CAM_LUN_WILDCARD) {
- ccb->ccb_h.status = CAM_LUN_INVALID;
+ /* Find the state pointer. */
+ if ((tptr = get_lun_statep(isp, bus, lun)) == NULL) {
+ ccb->ccb_h.status = CAM_PATH_INVALID;
xpt_done(ccb);
return;
}
- /*
- * See if we're busy disabling a lun now.
- */
- isp_tmlock(isp, "isp_disable_lun");
- status = CAM_REQ_INPROG;
-
- /*
- * Find the state pointer.
- */
- if ((tptr = get_lun_statep(isp, bus, lun)) == NULL) {
- status = CAM_PATH_INVALID;
- goto done;
- }
-
- /*
- * If we're a 24XX card, we're done.
- */
- if (IS_24XX(isp)) {
- status = CAM_REQ_CMP;
- goto done;
- }
-
- /*
- * For SCC FW, we only deal with lun zero.
- */
- if (IS_FC(isp) && lun > 0) {
- status = CAM_REQ_CMP;
- goto done;
- }
- isp->isp_osinfo.rptr = &status;
- if (isp_lun_cmd(isp, RQSTYPE_ENABLE_LUN, bus, lun, 0, 0)) {
- status = CAM_RESRC_UNAVAIL;
- } else {
- mtx_sleep(ccb, &isp->isp_lock, PRIBIO, "isp_disable_lun", 0);
- }
- isp->isp_osinfo.rptr = NULL;
-done:
- if (status == CAM_REQ_CMP) {
- tptr->enabled = 0;
- if (is_any_lun_enabled(isp, bus) == 0) {
- if (isp_disable_target_mode(isp, bus)) {
- status = CAM_REQ_CMP_ERR;
- }
- }
- }
- ccb->ccb_h.status = status;
- if (status == CAM_REQ_CMP) {
- destroy_lun_state(isp, tptr);
- xpt_print(ccb->ccb_h.path, "lun now disabled for target mode\n");
- } else {
- if (tptr)
- rls_lun_statep(isp, tptr);
- }
- isp_tmunlk(isp);
+ destroy_lun_state(isp, tptr);
+ ccb->ccb_h.status = CAM_REQ_CMP;
xpt_done(ccb);
}
-static int
-isp_enable_target_mode(ispsoftc_t *isp, int bus)
-{
- int tm_enabled;
-
- ISP_GET_PC(isp, bus, tm_enabled, tm_enabled);
- if (tm_enabled != 0) {
- return (0);
- }
- if (IS_SCSI(isp)) {
- mbreg_t mbs;
- MBSINIT(&mbs, MBOX_ENABLE_TARGET_MODE, MBLOGALL, 0);
- mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
- mbs.param[1] = ENABLE_TARGET_FLAG|ENABLE_TQING_FLAG;
- mbs.param[2] = bus << 7;
- if (isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs) < 0 || mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- isp_prt(isp, ISP_LOGERR, "Unable to enable Target Role on Bus %d", bus);
- return (EIO);
- }
- }
- ISP_SET_PC(isp, bus, tm_enabled, 1);
- isp_prt(isp, ISP_LOGINFO, "Target Role enabled on Bus %d", bus);
- return (0);
-}
-
-static int
-isp_disable_target_mode(ispsoftc_t *isp, int bus)
-{
- int tm_enabled;
-
- ISP_GET_PC(isp, bus, tm_enabled, tm_enabled);
- if (tm_enabled == 0) {
- return (0);
- }
- if (IS_SCSI(isp)) {
- mbreg_t mbs;
- MBSINIT(&mbs, MBOX_ENABLE_TARGET_MODE, MBLOGALL, 0);
- mbs.param[2] = bus << 7;
- if (isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs) < 0 || mbs.param[0] != MBOX_COMMAND_COMPLETE) {
- isp_prt(isp, ISP_LOGERR, "Unable to disable Target Role on Bus %d", bus);
- return (EIO);
- }
- }
- ISP_SET_PC(isp, bus, tm_enabled, 0);
- isp_prt(isp, ISP_LOGINFO, "Target Role disabled on Bus %d", bus);
- return (0);
-}
-
-static void
-isp_ledone(ispsoftc_t *isp, lun_entry_t *lep)
-{
- uint32_t *rptr;
-
- rptr = isp->isp_osinfo.rptr;
- if (lep->le_status != LUN_OK) {
- isp_prt(isp, ISP_LOGERR, "ENABLE/MODIFY LUN returned 0x%x", lep->le_status);
- if (rptr) {
- *rptr = CAM_REQ_CMP_ERR;
- wakeup_one(rptr);
- }
- } else {
- if (rptr) {
- *rptr = CAM_REQ_CMP;
- wakeup_one(rptr);
- }
- }
-}
-
static void
isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
{
@@ -1890,7 +1537,7 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO7[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x xfrlen=%u off=%u", __func__,
cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cto->ct_scsi_status, cto->ct_flags, xfrlen, atp->bytes_xfered);
}
- } else if (IS_FC(isp)) {
+ } else {
ct2_entry_t *cto = (ct2_entry_t *) local;
if (isp->isp_osinfo.sixtyfourbit)
@@ -2039,41 +1686,6 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
}
isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO2[%x] seq %u nc %d CDB0=%x scsi status %x flags %x resid %d xfrlen %u offset %u", __func__, cto->ct_rxid,
ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cso->scsi_status, cto->ct_flags, cto->ct_resid, cso->dxfer_len, atp->bytes_xfered);
- } else {
- ct_entry_t *cto = (ct_entry_t *) local;
-
- cto->ct_header.rqs_entry_type = RQSTYPE_CTIO;
- cto->ct_header.rqs_entry_count = 1;
- cto->ct_header.rqs_seqno |= ATPD_SEQ_NOTIFY_CAM;
- ATPD_SET_SEQNO(cto, atp);
- cto->ct_iid = cso->init_id;
- cto->ct_iid |= XS_CHANNEL(ccb) << 7;
- cto->ct_tgt = ccb->ccb_h.target_id;
- cto->ct_lun = ccb->ccb_h.target_lun;
- cto->ct_fwhandle = cso->tag_id;
- if (atp->rxid) {
- cto->ct_tag_val = atp->rxid;
- cto->ct_flags |= CT_TQAE;
- }
- if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) {
- cto->ct_flags |= CT_NODISC;
- }
- if (cso->dxfer_len == 0) {
- cto->ct_flags |= CT_NO_DATA;
- } else if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
- cto->ct_flags |= CT_DATA_IN;
- } else {
- cto->ct_flags |= CT_DATA_OUT;
- }
- if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
- cto->ct_flags |= CT_SENDSTATUS|CT_CCINCR;
- cto->ct_scsi_status = cso->scsi_status;
- cto->ct_resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit - xfrlen;
- isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO[%x] seq %u nc %d scsi status %x resid %d tag_id %x", __func__,
- cto->ct_fwhandle, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), cso->scsi_status, cso->resid, cso->tag_id);
- }
- ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
- cto->ct_timeout = 10;
}
if (isp_get_pcmd(isp, ccb)) {
@@ -2103,11 +1715,8 @@ isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how)
if (IS_24XX(isp)) {
ct7_entry_t *cto = (ct7_entry_t *) local;
cto->ct_syshandle = handle;
- } else if (IS_FC(isp)) {
- ct2_entry_t *cto = (ct2_entry_t *) local;
- cto->ct_syshandle = handle;
} else {
- ct_entry_t *cto = (ct_entry_t *) local;
+ ct2_entry_t *cto = (ct2_entry_t *) local;
cto->ct_syshandle = handle;
}
@@ -2166,6 +1775,7 @@ isp_target_putback_atio(union ccb *ccb)
ispsoftc_t *isp;
struct ccb_scsiio *cso;
void *qe;
+ at2_entry_t local, *at = &local;
isp = XS_ISP(ccb);
@@ -2179,38 +1789,22 @@ isp_target_putback_atio(union ccb *ccb)
}
memset(qe, 0, QENTRY_LEN);
cso = &ccb->csio;
- if (IS_FC(isp)) {
- at2_entry_t local, *at = &local;
- ISP_MEMZERO(at, sizeof (at2_entry_t));
- at->at_header.rqs_entry_type = RQSTYPE_ATIO2;
- at->at_header.rqs_entry_count = 1;
- if (ISP_CAP_SCCFW(isp)) {
- at->at_scclun = (uint16_t) ccb->ccb_h.target_lun;
+ ISP_MEMZERO(at, sizeof (at2_entry_t));
+ at->at_header.rqs_entry_type = RQSTYPE_ATIO2;
+ at->at_header.rqs_entry_count = 1;
+ if (ISP_CAP_SCCFW(isp)) {
+ at->at_scclun = (uint16_t) ccb->ccb_h.target_lun;
#if __FreeBSD_version < 1000700
- if (at->at_scclun >= 256)
- at->at_scclun |= 0x4000;
+ if (at->at_scclun >= 256)
+ at->at_scclun |= 0x4000;
#endif
- } else {
- at->at_lun = (uint8_t) ccb->ccb_h.target_lun;
- }
- at->at_status = CT_OK;
- at->at_rxid = cso->tag_id;
- at->at_iid = cso->ccb_h.target_id;
- isp_put_atio2(isp, at, qe);
} else {
- at_entry_t local, *at = &local;
- ISP_MEMZERO(at, sizeof (at_entry_t));
- at->at_header.rqs_entry_type = RQSTYPE_ATIO;
- at->at_header.rqs_entry_count = 1;
- at->at_iid = cso->init_id;
- at->at_iid |= XS_CHANNEL(ccb) << 7;
- at->at_tgt = cso->ccb_h.target_id;
- at->at_lun = cso->ccb_h.target_lun;
- at->at_status = CT_OK;
- at->at_tag_val = AT_GET_TAG(cso->tag_id);
- at->at_handle = AT_GET_HANDLE(cso->tag_id);
- isp_put_atio(isp, at, qe);
+ at->at_lun = (uint8_t) ccb->ccb_h.target_lun;
}
+ at->at_status = CT_OK;
+ at->at_rxid = cso->tag_id;
+ at->at_iid = cso->ccb_h.target_id;
+ isp_put_atio2(isp, at, qe);
ISP_TDQE(isp, "isp_target_putback_atio", isp->isp_reqidx, qe);
ISP_SYNC_REQUEST(isp);
isp_complete_ctio(ccb);
@@ -2225,134 +1819,10 @@ isp_complete_ctio(union ccb *ccb)
}
}
-/*
- * Handle ATIO stuff that the generic code can't.
- * This means handling CDBs.
- */
-
-static void
-isp_handle_platform_atio(ispsoftc_t *isp, at_entry_t *aep)
-{
- tstate_t *tptr;
- int status, bus;
- struct ccb_accept_tio *atiop;
- atio_private_data_t *atp;
-
- /*
- * The firmware status (except for the QLTM_SVALID bit)
- * indicates why this ATIO was sent to us.
- *
- * If QLTM_SVALID is set, the firmware has recommended Sense Data.
- *
- * If the DISCONNECTS DISABLED bit is set in the flags field,
- * we're still connected on the SCSI bus.
- */
- status = aep->at_status;
- if ((status & ~QLTM_SVALID) == AT_PHASE_ERROR) {
- /*
- * Bus Phase Sequence error. We should have sense data
- * suggested by the f/w. I'm not sure quite yet what
- * to do about this for CAM.
- */
- isp_prt(isp, ISP_LOGWARN, "PHASE ERROR");
- isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
- return;
- }
- if ((status & ~QLTM_SVALID) != AT_CDB) {
- isp_prt(isp, ISP_LOGWARN, "bad atio (0x%x) leaked to platform", status);
- isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
- return;
- }
-
- bus = GET_BUS_VAL(aep->at_iid);
- tptr = get_lun_statep(isp, bus, aep->at_lun);
- if (tptr == NULL) {
- tptr = get_lun_statep(isp, bus, CAM_LUN_WILDCARD);
- if (tptr == NULL) {
- /*
- * Because we can't autofeed sense data back with
- * a command for parallel SCSI, we can't give back
- * a CHECK CONDITION. We'll give back a BUSY status
- * instead. This works out okay because the only
- * time we should, in fact, get this, is in the
- * case that somebody configured us without the
- * blackhole driver, so they get what they deserve.
- */
- isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
- return;
- }
- }
-
- atp = isp_get_atpd(isp, tptr, aep->at_handle);
- atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios);
- if (atiop == NULL || atp == NULL) {
- /*
- * Because we can't autofeed sense data back with
- * a command for parallel SCSI, we can't give back
- * a CHECK CONDITION. We'll give back a QUEUE FULL status
- * instead. This works out okay because the only time we
- * should, in fact, get this, is in the case that we've
- * run out of ATIOS.
- */
- xpt_print(tptr->owner, "no %s for lun %d from initiator %d\n", (atp == NULL && atiop == NULL)? "ATIOs *or* ATPS" :
- ((atp == NULL)? "ATPs" : "ATIOs"), aep->at_lun, aep->at_iid);
- isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0);
- if (atp) {
- isp_put_atpd(isp, tptr, atp);
- }
- rls_lun_statep(isp, tptr);
- return;
- }
- atp->rxid = aep->at_tag_val;
- atp->state = ATPD_STATE_ATIO;
- SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
- tptr->atio_count--;
- ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, atiop->ccb_h.path, "Take FREE ATIO count now %d\n", tptr->atio_count);
- atiop->ccb_h.target_id = aep->at_tgt;
- atiop->ccb_h.target_lun = aep->at_lun;
- if (aep->at_flags & AT_NODISC) {
- atiop->ccb_h.flags |= CAM_DIS_DISCONNECT;
- } else {
- atiop->ccb_h.flags &= ~CAM_DIS_DISCONNECT;
- }
-
- if (status & QLTM_SVALID) {
- size_t amt = ISP_MIN(QLTM_SENSELEN, sizeof (atiop->sense_data));
- atiop->sense_len = amt;
- ISP_MEMCPY(&atiop->sense_data, aep->at_sense, amt);
- } else {
- atiop->sense_len = 0;
- }
-
- atiop->init_id = GET_IID_VAL(aep->at_iid);
- atiop->cdb_len = aep->at_cdblen;
- ISP_MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, aep->at_cdblen);
- atiop->ccb_h.status = CAM_CDB_RECVD;
- /*
- * Construct a tag 'id' based upon tag value (which may be 0..255)
- * and the handle (which we have to preserve).
- */
- atiop->tag_id = atp->tag;
- if (aep->at_flags & AT_TQAE) {
- atiop->tag_action = aep->at_tag_type;
- atiop->ccb_h.status |= CAM_TAG_ACTION_VALID;
- }
- atp->orig_datalen = 0;
- atp->bytes_xfered = 0;
- atp->lun = aep->at_lun;
- atp->nphdl = aep->at_iid;
- atp->portid = PORT_NONE;
- atp->oxid = 0;
- atp->cdb0 = atiop->cdb_io.cdb_bytes[0];
- atp->tattr = aep->at_tag_type;
- atp->state = ATPD_STATE_CAM;
- isp_prt(isp, ISP_LOGTDEBUG0, "ATIO[0x%x] CDB=0x%x lun %d", aep->at_tag_val, atp->cdb0, atp->lun);
- rls_lun_statep(isp, tptr);
-}
-
static void
isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
{
+ fcparam *fcp;
lun_id_t lun;
fcportdb_t *lp;
tstate_t *tptr;
@@ -2373,6 +1843,7 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
return;
}
+ fcp = FCPARAM(isp, 0);
if (ISP_CAP_SCCFW(isp)) {
lun = aep->at_scclun;
#if __FreeBSD_version < 1000700
@@ -2443,7 +1914,7 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle);
tptr->atio_count--;
isp_prt(isp, ISP_LOGTDEBUG2, "Take FREE ATIO count now %d", tptr->atio_count);
- atiop->ccb_h.target_id = FCPARAM(isp, 0)->isp_loopid;
+ atiop->ccb_h.target_id = fcp->isp_loopid;
atiop->ccb_h.target_lun = lun;
/*
@@ -2466,6 +1937,10 @@ isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep)
(((uint64_t) aep->at_wwpn[3]) << 0);
isp_add_wwn_entry(isp, 0, wwpn, INI_NONE,
nphdl, PORT_ANY, 0);
+ if (fcp->isp_loopstate > LOOP_LTEST_DONE)
+ fcp->isp_loopstate = LOOP_LTEST_DONE;
+ isp_async(isp, ISPASYNC_CHANGE_NOTIFY, 0,
+ ISPASYNC_CHANGE_PDB, nphdl, 0x06, 0xff);
isp_find_pdb_by_handle(isp, 0, nphdl, &lp);
}
atiop->init_id = FC_PORTDB_TGT(isp, 0, lp);
@@ -2588,7 +2063,7 @@ isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep)
/*
* Find the PDB entry for this initiator
*/
- if (isp_find_pdb_by_sid(isp, chan, sid, &lp) == 0) {
+ if (isp_find_pdb_by_portid(isp, chan, sid, &lp) == 0) {
/*
* If we're not in the port database terminate the exchange.
*/
@@ -2903,16 +2378,7 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
int bus;
uint32_t handle, moved_data = 0, data_requested;
- /*
- * CTIO handles are 16 bits.
- * CTIO2 and CTIO7 are 32 bits.
- */
-
- if (IS_SCSI(isp)) {
- handle = ((ct_entry_t *)arg)->ct_syshandle;
- } else {
- handle = ((ct2_entry_t *)arg)->ct_syshandle;
- }
+ handle = ((ct2_entry_t *)arg)->ct_syshandle;
ccb = isp_find_xs_tgt(isp, handle);
if (ccb == NULL) {
isp_print_bytes(isp, "null ccb in isp_handle_platform_ctio", QENTRY_LEN, arg);
@@ -2937,10 +2403,8 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
if (IS_24XX(isp)) {
atp = isp_find_atpd(isp, tptr, ((ct7_entry_t *)arg)->ct_rxid);
- } else if (IS_FC(isp)) {
- atp = isp_find_atpd(isp, tptr, ((ct2_entry_t *)arg)->ct_rxid);
} else {
- atp = isp_find_atpd(isp, tptr, ((ct_entry_t *)arg)->ct_fwhandle);
+ atp = isp_find_atpd(isp, tptr, ((ct2_entry_t *)arg)->ct_rxid);
}
if (atp == NULL) {
/*
@@ -2983,7 +2447,7 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
}
isp_prt(isp, ok? ISP_LOGTDEBUG0 : ISP_LOGWARN, "%s: CTIO7[%x] seq %u nc %d sts 0x%x flg 0x%x sns %d resid %d %s", __func__, ct->ct_rxid, ATPD_GET_SEQNO(ct),
notify_cam, ct->ct_nphdl, ct->ct_flags, (ccb->ccb_h.status & CAM_SENT_SENSE) != 0, resid, sentstatus? "FIN" : "MID");
- } else if (IS_FC(isp)) {
+ } else {
ct2_entry_t *ct = arg;
if (ct->ct_status == CT_SRR) {
atp->srr_ccb = ccb;
@@ -3006,22 +2470,6 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
}
isp_prt(isp, ok? ISP_LOGTDEBUG0 : ISP_LOGWARN, "%s: CTIO2[%x] seq %u nc %d sts 0x%x flg 0x%x sns %d resid %d %s", __func__, ct->ct_rxid, ATPD_GET_SEQNO(ct),
notify_cam, ct->ct_status, ct->ct_flags, (ccb->ccb_h.status & CAM_SENT_SENSE) != 0, resid, sentstatus? "FIN" : "MID");
- } else {
- ct_entry_t *ct = arg;
-
- if (ct->ct_status == (CT_HBA_RESET & 0xff)) {
- failure = CAM_UNREC_HBA_ERROR;
- } else {
- sentstatus = ct->ct_flags & CT_SENDSTATUS;
- ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK;
- notify_cam = (ct->ct_header.rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0;
- }
- if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) {
- resid = ct->ct_resid;
- moved_data = data_requested - resid;
- }
- isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO[%x] seq %u nc %d tag %x S_ID 0x%x lun %x sts %x flg %x resid %d %s", __func__, ct->ct_fwhandle, ATPD_GET_SEQNO(ct),
- notify_cam, ct->ct_tag_val, ct->ct_iid, ct->ct_lun, ct->ct_status, ct->ct_flags, resid, sentstatus? "FIN" : "MID");
}
if (ok) {
if (moved_data) {
@@ -3075,12 +2523,6 @@ isp_handle_platform_ctio(ispsoftc_t *isp, void *arg)
}
static void
-isp_handle_platform_notify_scsi(ispsoftc_t *isp, in_entry_t *inot)
-{
- isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot);
-}
-
-static void
isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp)
{
int needack = 1;
@@ -3102,8 +2544,8 @@ isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp)
case IN_ABORT_TASK:
{
tstate_t *tptr;
- uint16_t lun;
- uint32_t loopid, sid;
+ uint16_t nphdl, lun;
+ uint32_t sid;
uint64_t wwn;
atio_private_data_t *atp;
fcportdb_t *lp;
@@ -3118,11 +2560,11 @@ isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp)
lun = inp->in_lun;
}
if (ISP_CAP_2KLOGIN(isp)) {
- loopid = ((in_fcentry_e_t *)inp)->in_iid;
+ nphdl = ((in_fcentry_e_t *)inp)->in_iid;
} else {
- loopid = inp->in_iid;
+ nphdl = inp->in_iid;
}
- if (isp_find_pdb_by_handle(isp, 0, loopid, &lp)) {
+ if (isp_find_pdb_by_handle(isp, 0, nphdl, &lp)) {
wwn = lp->port_wwn;
sid = lp->portid;
} else {
@@ -3133,7 +2575,7 @@ isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp)
if (tptr == NULL) {
tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD);
if (tptr == NULL) {
- isp_prt(isp, ISP_LOGWARN, "ABORT TASK for lun %u- but no tstate", lun);
+ isp_prt(isp, ISP_LOGWARN, "ABORT TASK for lun %x, but no tstate", lun);
return;
}
}
@@ -3158,7 +2600,7 @@ isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp)
nt->nt_hba = isp;
nt->nt_tgt = FCPARAM(isp, 0)->isp_wwpn;
nt->nt_wwn = wwn;
- nt->nt_nphdl = loopid;
+ nt->nt_nphdl = nphdl;
nt->nt_sid = sid;
nt->nt_did = PORT_ANY;
nt->nt_lun = lun;
@@ -3321,7 +2763,7 @@ isp_handle_platform_target_notify_ack(ispsoftc_t *isp, isp_notify_t *mp)
uint16_t nphdl;
sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2];
- if (isp_find_pdb_by_sid(isp, mp->nt_channel, sid, &lp)) {
+ if (isp_find_pdb_by_portid(isp, mp->nt_channel, sid, &lp)) {
nphdl = lp->handle;
} else {
nphdl = NIL_HANDLE;
@@ -3445,7 +2887,7 @@ isp_handle_platform_target_tmf(ispsoftc_t *isp, isp_notify_t *notify)
goto bad;
}
- if (isp_find_pdb_by_sid(isp, notify->nt_channel, notify->nt_sid, &lp) == 0 &&
+ if (isp_find_pdb_by_portid(isp, notify->nt_channel, notify->nt_sid, &lp) == 0 &&
isp_find_pdb_by_handle(isp, notify->nt_channel, notify->nt_nphdl, &lp) == 0) {
inot->initiator_id = CAM_TARGET_WILDCARD;
} else {
@@ -3611,14 +3053,10 @@ isp_cam_async(void *cbarg, uint32_t code, struct cam_path *path, void *arg)
if (tgt >= 0) {
nflags = sdp->isp_devparam[tgt].nvrm_flags;
-#ifndef ISP_TARGET_MODE
nflags &= DPARM_SAFE_DFLT;
if (isp->isp_loaded_fw) {
nflags |= DPARM_NARROW | DPARM_ASYNC;
}
-#else
- nflags = DPARM_DEFAULT;
-#endif
oflags = sdp->isp_devparam[tgt].goal_flags;
sdp->isp_devparam[tgt].goal_flags = nflags;
sdp->isp_devparam[tgt].dev_update = 1;
@@ -3819,41 +3257,59 @@ isp_gdt_task(void *arg, int pending)
}
/*
- * Loop Down Timer Function- when loop goes down, a timer is started and
- * and after it expires we come here and take all probational devices that
- * the OS knows about and the tell the OS that they've gone away.
- *
+ * When loop goes down we remember the time and freeze CAM command queue.
+ * During some time period we are trying to reprobe the loop. But if we
+ * fail, we tell the OS that devices have gone away and drop the freeze.
+ *
* We don't clear the devices out of our port database because, when loop
* come back up, we have to do some actual cleanup with the chip at that
* point (implicit PLOGO, e.g., to get the chip's port database state right).
*/
static void
-isp_ldt(void *arg)
+isp_loop_changed(ispsoftc_t *isp, int chan)
{
- struct isp_fc *fc = arg;
- taskqueue_enqueue(taskqueue_thread, &fc->ltask);
+ fcparam *fcp = FCPARAM(isp, chan);
+ struct isp_fc *fc = ISP_FC_PC(isp, chan);
+
+ if (fc->loop_down_time)
+ return;
+ isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Loop changed", chan);
+ if (fcp->role & ISP_ROLE_INITIATOR)
+ isp_freeze_loopdown(isp, chan);
+ fc->loop_dead = 0;
+ fc->loop_down_time = time_uptime;
+ wakeup(fc);
}
static void
-isp_ldt_task(void *arg, int pending)
+isp_loop_up(ispsoftc_t *isp, int chan)
{
- struct isp_fc *fc = arg;
- ispsoftc_t *isp = fc->isp;
- int chan = fc - isp->isp_osinfo.pc.fc;
+ struct isp_fc *fc = ISP_FC_PC(isp, chan);
+
+ isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Loop is up", chan);
+ fc->loop_seen_once = 1;
+ fc->loop_dead = 0;
+ fc->loop_down_time = 0;
+ isp_unfreeze_loopdown(isp, chan);
+}
+
+static void
+isp_loop_dead(ispsoftc_t *isp, int chan)
+{
+ fcparam *fcp = FCPARAM(isp, chan);
+ struct isp_fc *fc = ISP_FC_PC(isp, chan);
fcportdb_t *lp;
struct ac_contract ac;
struct ac_device_changed *adc;
int dbidx, i;
- ISP_LOCK(isp);
- isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Loop Down Timer expired @ %lu", chan, (unsigned long) time_uptime);
- callout_deactivate(&fc->ldt);
+ isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Loop is dead", chan);
/*
* Notify to the OS all targets who we now consider have departed.
*/
for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
- lp = &FCPARAM(isp, chan)->portdb[dbidx];
+ lp = &fcp->portdb[dbidx];
if (lp->state == FC_PORTDB_STATE_NIL)
continue;
@@ -3896,14 +3352,8 @@ isp_ldt_task(void *arg, int pending)
}
isp_unfreeze_loopdown(isp, chan);
- /*
- * The loop down timer has expired. Wake up the kthread
- * to notice that fact (or make it false).
- */
fc->loop_dead = 1;
- fc->loop_down_time = fc->loop_down_limit+1;
- wakeup(fc);
- ISP_UNLOCK(isp);
+ fc->loop_down_time = 0;
}
static void
@@ -3912,15 +3362,18 @@ isp_kthread(void *arg)
struct isp_fc *fc = arg;
ispsoftc_t *isp = fc->isp;
int chan = fc - isp->isp_osinfo.pc.fc;
- int slp = 0;
+ int slp = 0, d;
+ int lb, lim;
mtx_lock(&isp->isp_osinfo.lock);
while (isp->isp_osinfo.is_exiting == 0) {
- int lb, lim;
-
- isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d checking FC state", __func__, chan);
+ isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0,
+ "Chan %d Checking FC state", chan);
lb = isp_fc_runstate(isp, chan, 250000);
+ isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0,
+ "Chan %d FC got to %s state", chan,
+ isp_fc_loop_statename(lb));
/*
* Our action is different based upon whether we're supporting
@@ -3930,87 +3383,44 @@ isp_kthread(void *arg)
*
* If not, we simply just wait for loop to come up.
*/
- if (lb && (FCPARAM(isp, chan)->role & ISP_ROLE_INITIATOR)) {
- /*
- * Increment loop down time by the last sleep interval
- */
- fc->loop_down_time += slp;
-
- if (lb < 0) {
- isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC loop not up (down count %d)", __func__, chan, fc->loop_down_time);
- } else {
- isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC got to %d (down count %d)", __func__, chan, lb, fc->loop_down_time);
- }
-
+ if (lb == LOOP_READY || lb < 0) {
+ slp = 0;
+ } else {
/*
* If we've never seen loop up and we've waited longer
* than quickboot time, or we've seen loop up but we've
* waited longer than loop_down_limit, give up and go
* to sleep until loop comes up.
*/
- if (FCPARAM(isp, chan)->loop_seen_once == 0) {
+ if (fc->loop_seen_once == 0)
lim = isp_quickboot_time;
- } else {
+ else
lim = fc->loop_down_limit;
- }
- if (fc->loop_down_time >= lim) {
- isp_freeze_loopdown(isp, chan, "loop limit hit");
+ d = time_uptime - fc->loop_down_time;
+ if (d >= lim)
slp = 0;
- } else if (fc->loop_down_time < 10) {
+ else if (d < 10)
slp = 1;
- } else if (fc->loop_down_time < 30) {
+ else if (d < 30)
slp = 5;
- } else if (fc->loop_down_time < 60) {
+ else if (d < 60)
slp = 10;
- } else if (fc->loop_down_time < 120) {
+ else if (d < 120)
slp = 20;
- } else {
- slp = 30;
- }
-
- } else if (lb) {
- isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC Loop Down", __func__, chan);
- fc->loop_down_time += slp;
- if (fc->loop_down_time > 300)
- slp = 0;
else
- slp = 60;
- } else {
- isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC state OK", __func__, chan);
- fc->loop_down_time = 0;
- slp = 0;
+ slp = 30;
}
-
- /*
- * If this is past the first loop up or the loop is dead and if we'd frozen the simq, unfreeze it
- * now so that CAM can start sending us commands.
- *
- * If the FC state isn't okay yet, they'll hit that in isp_start which will freeze the queue again
- * or kill the commands, as appropriate.
- */
-
- if (FCPARAM(isp, chan)->loop_seen_once || fc->loop_dead) {
- isp_unfreeze_loopdown(isp, chan);
+ if (slp == 0) {
+ if (lb == LOOP_READY)
+ isp_loop_up(isp, chan);
+ else
+ isp_loop_dead(isp, chan);
}
- isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d sleep time %d", __func__, chan, slp);
-
+ isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0,
+ "Chan %d sleep for %d seconds", chan, slp);
msleep(fc, &isp->isp_osinfo.lock, PRIBIO, "ispf", slp * hz);
-
- /*
- * If slp is zero, we're waking up for the first time after
- * things have been okay. In this case, we set a deferral state
- * for all commands and delay hysteresis seconds before starting
- * the FC state evaluation. This gives the loop/fabric a chance
- * to settle.
- */
- if (slp == 0 && fc->hysteresis) {
- isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d sleep hysteresis ticks %d", __func__, chan, fc->hysteresis * hz);
- mtx_unlock(&isp->isp_osinfo.lock);
- pause("ispt", fc->hysteresis * hz);
- mtx_lock(&isp->isp_osinfo.lock);
- }
}
fc->num_threads -= 1;
mtx_unlock(&isp->isp_osinfo.lock);
@@ -4020,7 +3430,7 @@ isp_kthread(void *arg)
static void
isp_action(struct cam_sim *sim, union ccb *ccb)
{
- int bus, tgt, ts, error, lim;
+ int bus, tgt, ts, error;
ispsoftc_t *isp;
struct ccb_trans_settings *cts;
@@ -4084,26 +3494,13 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
break;
case CMD_RQLATER:
/*
- * We get this result for FC devices if the loop state isn't ready yet
- * or if the device in question has gone zombie on us.
- *
- * If we've never seen Loop UP at all, we requeue this request and wait
- * for the initial loop up delay to expire.
+ * We get this result if the loop isn't ready
+ * or if the device in question has gone zombie.
*/
- lim = ISP_FC_PC(isp, bus)->loop_down_limit;
- if (FCPARAM(isp, bus)->loop_seen_once == 0 || ISP_FC_PC(isp, bus)->loop_down_time >= lim) {
- if (FCPARAM(isp, bus)->loop_seen_once == 0) {
- isp_prt(isp, ISP_LOGDEBUG0,
- "%d.%jx loop not seen yet @ %lu",
- XS_TGT(ccb), (uintmax_t)XS_LUN(ccb),
- (unsigned long) time_uptime);
- } else {
- isp_prt(isp, ISP_LOGDEBUG0,
- "%d.%jx downtime (%d) > lim (%d)",
- XS_TGT(ccb), (uintmax_t)XS_LUN(ccb),
- ISP_FC_PC(isp, bus)->loop_down_time,
- lim);
- }
+ if (ISP_FC_PC(isp, bus)->loop_dead) {
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "%d.%jx loop is dead",
+ XS_TGT(ccb), (uintmax_t)XS_LUN(ccb));
ccb->ccb_h.status = CAM_SEL_TIMEOUT;
isp_done((struct ccb_scsiio *) ccb);
break;
@@ -4248,16 +3645,9 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
break;
#endif
case XPT_RESET_DEV: /* BDR the specified SCSI device */
- {
- struct isp_fc *fc;
-
bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path));
tgt = ccb->ccb_h.target_id;
tgt |= (bus << 16);
- if (IS_FC(isp))
- fc = ISP_FC_PC(isp, bus);
- else
- fc = NULL;
error = isp_control(isp, ISPCTL_RESET_DEV, bus, tgt);
if (error) {
@@ -4268,14 +3658,13 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
* Reference Number, because the target will expect
* that we re-start the CRN at 1 after a reset.
*/
- if (fc != NULL)
- isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1);
+ if (IS_FC(isp))
+ isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1);
ccb->ccb_h.status = CAM_REQ_CMP;
}
xpt_done(ccb);
break;
- }
case XPT_ABORT: /* Abort the specified CCB */
{
union ccb *accb = ccb->cab.abort_ccb;
@@ -4542,25 +3931,12 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
}
if (rchange) {
ISP_PATH_PRT(isp, ISP_LOGCONFIG, ccb->ccb_h.path, "changing role on from %d to %d\n", fcp->role, newrole);
-#ifdef ISP_TARGET_MODE
- ISP_SET_PC(isp, bus, tm_enabled, 0);
- ISP_SET_PC(isp, bus, tm_luns_enabled, 0);
-#endif
if (isp_control(isp, ISPCTL_CHANGE_ROLE,
bus, newrole) != 0) {
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
xpt_done(ccb);
break;
}
-#ifdef ISP_TARGET_MODE
- if (newrole == ISP_ROLE_TARGET || newrole == ISP_ROLE_BOTH) {
- /*
- * Give the new role a chance to complain and settle
- */
- msleep(isp, &isp->isp_lock, PRIBIO, "taking a breather", 2);
- ccb->ccb_h.status = isp_enable_deferred_luns(isp, bus);
- }
-#endif
}
}
xpt_done(ccb);
@@ -4606,10 +3982,11 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
cpi->version_num = 1;
#ifdef ISP_TARGET_MODE
- cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
-#else
- cpi->target_sprt = 0;
+ if (IS_FC(isp) && ISP_CAP_TMODE(isp) && ISP_CAP_SCCFW(isp))
+ cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
+ else
#endif
+ cpi->target_sprt = 0;
cpi->hba_eng_cnt = 0;
cpi->max_target = ISP_MAX_TARGETS(isp) - 1;
cpi->max_lun = ISP_MAX_LUNS(isp) == 0 ?
@@ -4829,49 +4206,20 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
msg = "LOOP Reset";
/* FALLTHROUGH */
case ISPASYNC_LOOP_DOWN:
- {
if (msg == NULL)
msg = "LOOP Down";
va_start(ap, cmd);
bus = va_arg(ap, int);
va_end(ap);
-
- FCPARAM(isp, bus)->isp_linkstate = 0;
-
- fc = ISP_FC_PC(isp, bus);
- if (cmd == ISPASYNC_LOOP_DOWN && fc->ready) {
- /*
- * We don't do any simq freezing if we are only in target mode
- */
- if (FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) {
- if (fc->path) {
- isp_freeze_loopdown(isp, bus, msg);
- }
- }
- if (!callout_active(&fc->ldt)) {
- callout_reset(&fc->ldt, fc->loop_down_limit * hz, isp_ldt, fc);
- isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Starting Loop Down Timer @ %lu", (unsigned long) time_uptime);
- }
- }
- isp_fcp_reset_crn(fc, /*tgt*/0, /*tgt_set*/ 0);
-
- isp_prt(isp, ISP_LOGINFO, "Chan %d: %s", bus, msg);
+ isp_fcp_reset_crn(isp, bus, /*tgt*/0, /*tgt_set*/ 0);
+ isp_loop_changed(isp, bus);
+ isp_prt(isp, ISP_LOGINFO, "Chan %d %s", bus, msg);
break;
- }
case ISPASYNC_LOOP_UP:
va_start(ap, cmd);
bus = va_arg(ap, int);
va_end(ap);
- fc = ISP_FC_PC(isp, bus);
- /*
- * Now we just note that Loop has come up. We don't
- * actually do anything because we're waiting for a
- * Change Notify before activating the FC cleanup
- * thread to look at the state of the loop again.
- */
- FCPARAM(isp, bus)->isp_linkstate = 1;
- fc->loop_dead = 0;
- fc->loop_down_time = 0;
+ isp_loop_changed(isp, bus);
isp_prt(isp, ISP_LOGINFO, "Chan %d Loop UP", bus);
break;
case ISPASYNC_DEV_ARRIVED:
@@ -4886,7 +4234,7 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...)
if ((FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) &&
(lp->prli_word3 & PRLI_WD3_TARGET_FUNCTION)) {
lp->is_target = 1;
- isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1);
+ isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1);
isp_make_here(isp, lp, bus, tgt);
}
if ((FCPARAM(isp, bus)->role & ISP_ROLE_TARGET) &&
@@ -4916,11 +4264,11 @@ changed:
(lp->new_prli_word3 & PRLI_WD3_TARGET_FUNCTION))) {
lp->is_target = !lp->is_target;
if (lp->is_target) {
- isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1);
+ isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1);
isp_make_here(isp, lp, bus, tgt);
} else {
isp_make_gone(isp, lp, bus, tgt);
- isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1);
+ isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1);
}
}
if (lp->is_initiator !=
@@ -4973,15 +4321,17 @@ changed:
case ISPASYNC_CHANGE_NOTIFY:
{
char *msg;
- int evt, nphdl, nlstate, reason;
+ int evt, nphdl, nlstate, portid, reason;
va_start(ap, cmd);
bus = va_arg(ap, int);
evt = va_arg(ap, int);
- if (IS_24XX(isp) && evt == ISPASYNC_CHANGE_PDB) {
+ if (evt == ISPASYNC_CHANGE_PDB) {
nphdl = va_arg(ap, int);
nlstate = va_arg(ap, int);
reason = va_arg(ap, int);
+ } else if (evt == ISPASYNC_CHANGE_SNS) {
+ portid = va_arg(ap, int);
} else {
nphdl = NIL_HANDLE;
nlstate = reason = 0;
@@ -4991,24 +4341,18 @@ changed:
if (evt == ISPASYNC_CHANGE_PDB) {
msg = "Port Database Changed";
+ isp_prt(isp, ISP_LOGINFO,
+ "Chan %d %s (nphdl 0x%x state 0x%x reason 0x%x)",
+ bus, msg, nphdl, nlstate, reason);
} else if (evt == ISPASYNC_CHANGE_SNS) {
msg = "Name Server Database Changed";
+ isp_prt(isp, ISP_LOGINFO, "Chan %d %s (PortID 0x%06x)",
+ bus, msg, portid);
} else {
msg = "Other Change Notify";
+ isp_prt(isp, ISP_LOGINFO, "Chan %d %s", bus, msg);
}
-
- /*
- * If the loop down timer is running, cancel it.
- */
- if (fc->ready && callout_active(&fc->ldt)) {
- isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Stopping Loop Down Timer @ %lu", (unsigned long) time_uptime);
- callout_stop(&fc->ldt);
- }
- isp_prt(isp, ISP_LOGINFO, "Chan %d %s", bus, msg);
- if (FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) {
- isp_freeze_loopdown(isp, bus, msg);
- }
- wakeup(fc);
+ isp_loop_changed(isp, bus);
break;
}
#ifdef ISP_TARGET_MODE
@@ -5092,20 +4436,14 @@ changed:
isp_prt(isp, ISP_LOGWARN, "%s: unhandled target action 0x%x", __func__, hp->rqs_entry_type);
break;
case RQSTYPE_NOTIFY:
- if (IS_SCSI(isp)) {
- isp_handle_platform_notify_scsi(isp, (in_entry_t *) hp);
- } else if (IS_24XX(isp)) {
+ if (IS_24XX(isp)) {
isp_handle_platform_notify_24xx(isp, (in_fcentry_24xx_t *) hp);
} else {
isp_handle_platform_notify_fc(isp, (in_fcentry_t *) hp);
}
break;
case RQSTYPE_ATIO:
- if (IS_24XX(isp)) {
- isp_handle_platform_atio7(isp, (at7_entry_t *) hp);
- } else {
- isp_handle_platform_atio(isp, (at_entry_t *) hp);
- }
+ isp_handle_platform_atio7(isp, (at7_entry_t *) hp);
break;
case RQSTYPE_ATIO2:
isp_handle_platform_atio2(isp, (at2_entry_t *) hp);
@@ -5170,10 +4508,6 @@ changed:
isp_handle_platform_target_tmf(isp, nt);
break;
}
- case RQSTYPE_ENABLE_LUN:
- case RQSTYPE_MODIFY_LUN:
- isp_ledone(isp, (lun_entry_t *) hp);
- break;
}
break;
}
@@ -5489,23 +4823,23 @@ isp_common_dmateardown(ispsoftc_t *isp, struct ccb_scsiio *csio, uint32_t hdl)
* (needed for events like a LIP).
*/
void
-isp_fcp_reset_crn(struct isp_fc *fc, uint32_t tgt, int tgt_set)
+isp_fcp_reset_crn(ispsoftc_t *isp, int chan, uint32_t tgt, int tgt_set)
{
- int i;
+ struct isp_fc *fc = ISP_FC_PC(isp, chan);
struct isp_nexus *nxp;
+ int i;
if (tgt_set == 0)
- isp_prt(fc->isp, ISP_LOG_SANCFG, "resetting CRN on all targets");
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "Chan %d resetting CRN on all targets", chan);
else
- isp_prt(fc->isp, ISP_LOG_SANCFG, "resetting CRN target %u", tgt);
+ isp_prt(isp, ISP_LOGDEBUG0,
+ "Chan %d resetting CRN on target %u", chan, tgt);
for (i = 0; i < NEXUS_HASH_WIDTH; i++) {
- nxp = fc->nexus_hash[i];
- while (nxp) {
- if ((tgt_set != 0) && (tgt == nxp->tgt))
+ for (nxp = fc->nexus_hash[i]; nxp != NULL; nxp = nxp->next) {
+ if (tgt_set == 0 || tgt == nxp->tgt)
nxp->crnseed = 0;
-
- nxp = nxp->next;
}
}
}
@@ -5519,7 +4853,7 @@ isp_fcp_next_crn(ispsoftc_t *isp, uint8_t *crnp, XS_T *cmd)
struct isp_nexus *nxp;
int idx;
- if (isp->isp_type < ISP_HA_FC_2300)
+ if (IS_2100(isp))
return (0);
chan = XS_CHANNEL(cmd);
@@ -5549,15 +4883,11 @@ isp_fcp_next_crn(ispsoftc_t *isp, uint8_t *crnp, XS_T *cmd)
nxp->next = fc->nexus_hash[idx];
fc->nexus_hash[idx] = nxp;
}
- if (nxp) {
- if (nxp->crnseed == 0)
- nxp->crnseed = 1;
- if (cmd)
- PISP_PCMD(cmd)->crn = nxp->crnseed;
- *crnp = nxp->crnseed++;
- return (0);
- }
- return (-1);
+ if (nxp->crnseed == 0)
+ nxp->crnseed = 1;
+ PISP_PCMD(cmd)->crn = nxp->crnseed;
+ *crnp = nxp->crnseed++;
+ return (0);
}
/*
OpenPOWER on IntegriCloud