various fixes

This commit is contained in:
Matt Jacob 2000-08-27 23:38:44 +00:00
parent 3aa9aaf931
commit b6b6ad2f23
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=65140
7 changed files with 481 additions and 313 deletions

View file

@ -595,7 +595,9 @@ isp_reset(isp)
isp_prt(isp, ISP_LOGERR, "Ram Checksum Failure");
return;
}
isp->isp_loaded_fw = 1;
} else {
isp->isp_loaded_fw = 0;
isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
}
@ -750,7 +752,7 @@ isp_scsi_init(isp)
/*
* If we have fast memory timing enabled, turn it on.
*/
if (isp->isp_fast_mttr) {
if (sdp_chan0->isp_fast_mttr) {
ISP_WRITE(isp, RISC_MTR, 0x1313);
}
@ -923,87 +925,51 @@ isp_scsi_channel_init(isp, channel)
if (sdp->isp_devparam[tgt].dev_enable == 0) {
continue;
}
sdf = DPARM_SAFE_DFLT;
/*
* If we're in LVD mode, then we pretty much should
* only disable tagged queuing.
* It is not quite clear when this changed over so that
* we could force narrow and async for 1000/1020 cards,
* but assume that this is only the case for loaded
* firmware.
*/
if (IS_ULTRA2(isp) && sdp->isp_lvdmode) {
sdf = DPARM_DEFAULT & ~DPARM_TQING;
} else {
int rvf = ISP_FW_REVX(isp->isp_fwrev);
sdf = DPARM_SAFE_DFLT;
/*
* It is not quite clear when this changed over so that
* we could force narrow and async, so assume >= 7.55
* for i/t F/W and = 4.55 for initiator f/w.
*/
if ((ISP_FW_REV(4, 55, 0) <= rvf &&
(ISP_FW_REV(5, 0, 0) > rvf)) ||
(ISP_FW_REV(7, 55, 0) <= rvf)) {
sdf |= DPARM_NARROW | DPARM_ASYNC;
}
if (isp->isp_loaded_fw) {
sdf |= DPARM_NARROW | DPARM_ASYNC;
}
mbs.param[0] = MBOX_SET_TARGET_PARAMS;
mbs.param[1] = (tgt << 8) | (channel << 15);
mbs.param[2] = sdf;
mbs.param[3] =
(sdp->isp_devparam[tgt].sync_offset << 8) |
(sdp->isp_devparam[tgt].sync_period);
if ((sdf & DPARM_SYNC) == 0) {
mbs.param[3] = 0;
} else {
mbs.param[3] =
(sdp->isp_devparam[tgt].sync_offset << 8) |
(sdp->isp_devparam[tgt].sync_period);
}
isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
sdf = DPARM_SAFE_DFLT;
mbs.param[0] = MBOX_SET_TARGET_PARAMS;
mbs.param[1] = (tgt << 8) | (channel << 15);
mbs.param[2] = sdf;
mbs.param[3] =
(sdp->isp_devparam[tgt].sync_offset << 8) |
(sdp->isp_devparam[tgt].sync_period);
mbs.param[3] = 0;
isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
continue;
}
}
#if 0
/*
* We don't update dev_flags with what we've set
* because that's not the ultimate goal setting.
* If we succeed with the command, we *do* update
* cur_dflags by getting target parameters.
*/
mbs.param[0] = MBOX_GET_TARGET_PARAMS;
mbs.param[1] = (tgt << 8) | (channel << 15);
isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
/*
* Urrr.... We'll set cur_dflags to DPARM_SAFE_DFLT so
* we don't try and do tags if tags aren't enabled.
*/
sdp->isp_devparam[tgt].cur_dflags = DPARM_SAFE_DFLT;
} else {
sdp->isp_devparam[tgt].cur_dflags = mbs.param[2];
sdp->isp_devparam[tgt].cur_offset = mbs.param[3] >> 8;
sdp->isp_devparam[tgt].cur_period = mbs.param[3] & 0xff;
}
isp_prt(isp, ISP_LOGTDEBUG0,
"set flags 0x%x got 0x%x back for target %d",
sdf, mbs.param[2], tgt);
#else
/*
* We don't update any information because we need to run
* at least one command per target to cause a new state
* to be latched.
*/
#endif
/*
* We don't update any information directly from the f/w
* because we need to run at least one command to cause a
* new state to be latched up. So, we just assume that we
* converge to the values we just had set.
*
* Ensure that we don't believe tagged queuing is enabled yet.
* It turns out that sometimes the ISP just ignores our
* attempts to set parameters for devices that it hasn't
* seen yet.
*/
sdp->isp_devparam[tgt].cur_dflags &= ~DPARM_TQING;
sdp->isp_devparam[tgt].cur_dflags = sdf & ~DPARM_TQING;
for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
mbs.param[1] = (channel << 15) | (tgt << 8) | lun;
@ -1015,6 +981,13 @@ isp_scsi_channel_init(isp, channel)
}
}
}
for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
if (sdp->isp_devparam[tgt].dev_refresh) {
isp->isp_sendmarker |= (1 << channel);
isp->isp_update |= (1 << channel);
break;
}
}
}
/*
@ -1038,20 +1011,21 @@ isp_fibre_init(isp)
MEMZERO(icbp, sizeof (*icbp));
icbp->icb_version = ICB_VERSION1;
#ifdef ISP_TARGET_MODE
fcp->isp_fwoptions = ICBOPT_TGT_ENABLE;
#else
fcp->isp_fwoptions = 0;
#endif
fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
/*
* Firmware Options are either retrieved from NVRAM or
* are patched elsewhere. We check them for sanity here
* and make changes based on board revision, but otherwise
* let others decide policy.
*/
/*
* If this is a 2100 < revision 5, we have to turn off FAIRNESS.
*/
if ((isp->isp_type == ISP_HA_FC_2100) && isp->isp_revision < 5) {
fcp->isp_fwoptions &= ~ICBOPT_FAIRNESS;
}
fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
/*
* We have to use FULL LOGIN even though it resets the loop too much
* because otherwise port database entries don't get updated after
@ -1060,11 +1034,11 @@ isp_fibre_init(isp)
if (ISP_FW_REVX(isp->isp_fwrev) < ISP_FW_REV(1, 17, 0)) {
fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
}
#ifndef ISP_NO_FASTPOST_FC
fcp->isp_fwoptions |= ICBOPT_FAST_POST;
#endif
if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
/*
* Insist on Port Database Update Async notifications
*/
fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
/*
* We don't set ICBOPT_PORTNAME because we want our
@ -1096,7 +1070,10 @@ isp_fibre_init(isp)
icbp->icb_retry_delay = fcp->isp_retry_delay;
icbp->icb_retry_count = fcp->isp_retry_count;
icbp->icb_hardaddr = loopid;
#ifdef PRET_A_PORTE
/*
* Right now we just set extended options to prefer point-to-point
* over loop based upon some soft config options.
*/
if (IS_2200(isp)) {
icbp->icb_fwoptions |= ICBOPT_EXTENDED;
/*
@ -1107,7 +1084,6 @@ isp_fibre_init(isp)
else
icbp->icb_xfwoptions = ICBXOPT_LOOP_2_PTP;
}
#endif
icbp->icb_logintime = 60; /* 60 second login timeout */
if (fcp->isp_nodewwn) {
@ -1122,6 +1098,8 @@ isp_fibre_init(isp)
icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_MSW(isp->isp_rquest_dma);
icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_LSW(isp->isp_result_dma);
icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_MSW(isp->isp_result_dma);
isp_prt(isp, ISP_LOGDEBUG1,
"isp_fibre_init: fwoptions 0x%x", fcp->isp_fwoptions);
ISP_SWIZZLE_ICB(isp, icbp);
/*
@ -1293,7 +1271,8 @@ isp_fclink_test(isp, usdelay)
* waiting.
*/
isp_prt(isp, ISP_LOGDEBUG3, "usec%d: 0x%lx->0x%lx enano %u",
count, GET_NANOSEC(&hra), GET_NANOSEC(&hrb), enano);
count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb),
enano);
/*
* This peculiar code is an attempt to try and avoid
@ -2222,6 +2201,10 @@ isp_start(xs)
if (XS_TAG_P(xs)) {
t2reqp->req_flags = XS_TAG_TYPE(xs);
} else {
/*
* If we don't know what tag to use, use HEAD OF QUEUE
* for Request Sense or Ordered (for safety's sake).
*/
if (XS_CDBP(xs)[0] == 0x3) /* REQUEST SENSE */
t2reqp->req_flags = REQFLAG_HTAG;
else
@ -2381,6 +2364,10 @@ isp_control(isp, ctl, arg)
if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
return (0);
}
/*
* XXX: Look for command in the REQUEST QUEUE. That is,
* XXX: It hasen't been picked up by firmware yet.
*/
break;
case ISPCTL_UPDATE_PARAMS:
@ -2399,19 +2386,46 @@ isp_control(isp, ctl, arg)
return (isp_pdb_sync(isp, -1));
}
break;
#ifdef ISP_TARGET_MODE
case ISPCTL_TOGGLE_TMODE:
{
int ena = *(int *)arg;
if (IS_SCSI(isp)) {
int ena = *(int *)arg;
mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
mbs.param[1] = (ena)? ENABLE_TARGET_FLAG : 0;
isp_mboxcmd(isp, &mbs, MBLOGALL);
if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
break;
}
} else {
fcparam *fcp = isp->isp_param;
/*
* We assume somebody has quiesced this bus.
*/
if (ena) {
if (fcp->isp_fwoptions & ICBOPT_TGT_ENABLE) {
return (0);
}
fcp->isp_fwoptions |= ICBOPT_TGT_ENABLE;
} else {
if (!(fcp->isp_fwoptions & ICBOPT_TGT_ENABLE)) {
return (0);
}
fcp->isp_fwoptions &= ~ICBOPT_TGT_ENABLE;
}
isp->isp_state = ISP_NILSTATE;
isp_reset(isp);
if (isp->isp_state != ISP_RESETSTATE) {
break;
}
isp_init(isp);
if (isp->isp_state != ISP_INITSTATE) {
break;
}
isp->isp_state = ISP_RUNSTATE;
}
return (0);
}
#endif
}
return (-1);
@ -2590,6 +2604,7 @@ isp_intr(arg)
ISP_UNSWIZZLE_RESPONSE(isp, sp, oop);
if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) {
if (isp_handle_other_response(isp, sp, &optr) == 0) {
MEMZERO(sp, sizeof (isphdr_t));
continue;
}
/*
@ -2600,6 +2615,7 @@ isp_intr(arg)
if (sp->req_header.rqs_entry_type != RQSTYPE_REQUEST) {
isp_prt(isp, ISP_LOGERR, notresp,
sp->req_header.rqs_entry_type, oop, optr);
MEMZERO(sp, sizeof (isphdr_t));
continue;
}
buddaboom = 1;
@ -2638,6 +2654,7 @@ isp_intr(arg)
#undef _RQS_OFLAGS
}
if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) {
MEMZERO(sp, sizeof (isphdr_t));
isp_prt(isp, ISP_LOGERR,
"bad request handle %d", sp->req_handle);
ISP_WRITE(isp, INMAILBOX5, optr);
@ -2645,6 +2662,7 @@ isp_intr(arg)
}
xs = isp_find_xs(isp, sp->req_handle);
if (xs == NULL) {
MEMZERO(sp, sizeof (isphdr_t));
isp_prt(isp, ISP_LOGERR,
"cannot find handle 0x%x in xflist",
sp->req_handle);
@ -2658,38 +2676,65 @@ isp_intr(arg)
if (buddaboom) {
XS_SETERR(xs, HBA_BOTCH);
}
*XS_STSP(xs) = sp->req_scsi_status & 0xff;
if (IS_SCSI(isp)) {
if (sp->req_state_flags & RQSF_GOT_SENSE) {
XS_SAVE_SENSE(xs, sp);
}
if (IS_FC(isp) && (sp->req_scsi_status & RQCS_SV)) {
/*
* A new synchronous rate was negotiated for this
* target. Mark state such that we'll go look up
* that which has changed later.
* Fibre Channel F/W doesn't say we got status
* if there's Sense Data instead. I guess they
* think it goes w/o saying.
*/
if (sp->req_status_flags & RQSTF_NEGOTIATION) {
sdparam *sdp = isp->isp_param;
sdp += XS_CHANNEL(xs);
sdp->isp_devparam[XS_TGT(xs)].dev_refresh = 1;
isp->isp_update |= (1 << XS_CHANNEL(xs));
}
} else {
if (sp->req_scsi_status & RQCS_SV) {
XS_SAVE_SENSE(xs, sp);
/* force that we 'got' sense */
sp->req_state_flags |= RQSF_GOT_SENSE;
}
sp->req_state_flags |= RQSF_GOT_STATUS;
}
if (sp->req_state_flags & RQSF_GOT_STATUS) {
*XS_STSP(xs) = sp->req_scsi_status & 0xff;
}
if (sp->req_header.rqs_entry_type == RQSTYPE_RESPONSE) {
switch (sp->req_header.rqs_entry_type) {
case RQSTYPE_RESPONSE:
XS_SET_STATE_STAT(isp, xs, sp);
isp_parse_status(isp, sp, xs);
if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) &&
(*XS_STSP(xs) == SCSI_BUSY)) {
XS_SETERR(xs, HBA_TGTBSY);
}
} else if (sp->req_header.rqs_entry_type == RQSTYPE_REQUEST) {
if (IS_SCSI(isp)) {
XS_RESID(xs) = sp->req_resid;
if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
(*XS_STSP(xs) == SCSI_CHECK) &&
(sp->req_state_flags & RQSF_GOT_SENSE)) {
XS_SAVE_SENSE(xs, sp);
}
/*
* A new synchronous rate was negotiated for
* this target. Mark state such that we'll go
* look up that which has changed later.
*/
if (sp->req_status_flags & RQSTF_NEGOTIATION) {
int t = XS_TGT(xs);
sdparam *sdp = isp->isp_param;
sdp += XS_CHANNEL(xs);
sdp->isp_devparam[t].dev_refresh = 1;
isp->isp_update |=
(1 << XS_CHANNEL(xs));
}
} else {
if (sp->req_status_flags & RQSF_XFER_COMPLETE) {
XS_RESID(xs) = 0;
} else if (sp->req_scsi_status & RQCS_RESID) {
XS_RESID(xs) = sp->req_resid;
} else {
XS_RESID(xs) = 0;
}
if ((sp->req_state_flags & RQSF_GOT_STATUS) &&
(*XS_STSP(xs) == SCSI_CHECK) &&
(sp->req_scsi_status & RQCS_SV)) {
XS_SAVE_SENSE(xs, sp);
}
}
isp_prt(isp, ISP_LOGDEBUG2, "asked for %d got resid %d",
XS_XFRLEN(xs), sp->req_resid);
break;
case RQSTYPE_REQUEST:
if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
/*
* Force Queue Full status.
@ -2699,24 +2744,25 @@ isp_intr(arg)
} else if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_BOTCH);
}
} else {
XS_RESID(xs) = XS_XFRLEN(xs);
break;
default:
isp_prt(isp, ISP_LOGWARN,
"unhandled respose queue type 0x%x",
sp->req_header.rqs_entry_type);
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_BOTCH);
}
break;
}
if (IS_SCSI(isp)) {
XS_RESID(xs) = sp->req_resid;
} else if (sp->req_scsi_status & RQCS_RV) {
XS_RESID(xs) = sp->req_resid;
isp_prt(isp, ISP_LOGDEBUG2, "cnt %d rsd %d",
XS_XFRLEN(xs), sp->req_resid);
}
/*
* Free any dma resources. As a side effect, this may
* also do any cache flushing necessary for data coherence. */
if (XS_XFRLEN(xs)) {
ISP_DMAFREE(isp, xs, sp->req_handle);
}
if (((isp->isp_dblev & (ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
((isp->isp_dblev & ISP_LOGDEBUG1) && !XS_NOERR(xs))) {
char skey;
@ -2739,6 +2785,7 @@ isp_intr(arg)
if (isp->isp_nactive > 0)
isp->isp_nactive--;
complist[ndone++] = xs; /* defer completion call until later */
MEMZERO(sp, sizeof (isphdr_t));
if (ndone == MAX_REQUESTQ_COMPLETIONS) {
break;
}
@ -2783,8 +2830,6 @@ isp_parse_async(isp, mbox)
}
switch (mbox) {
case MBOX_COMMAND_COMPLETE: /* sometimes these show up */
break;
case ASYNC_BUS_RESET:
isp->isp_sendmarker |= (1 << bus);
#ifdef ISP_TARGET_MODE
@ -2857,23 +2902,23 @@ isp_parse_async(isp, mbox)
switch (mbox & 0x1c00) {
case SXP_PINS_LVD_MODE:
isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
((sdparam *)isp->isp_param)->isp_diffmode = 0;
((sdparam *)isp->isp_param)->isp_ultramode = 0;
((sdparam *)isp->isp_param)->isp_lvdmode = 1;
SDPARAM(isp)->isp_diffmode = 0;
SDPARAM(isp)->isp_ultramode = 0;
SDPARAM(isp)->isp_lvdmode = 1;
break;
case SXP_PINS_HVD_MODE:
isp_prt(isp, ISP_LOGINFO,
"Transition to Differential mode");
((sdparam *)isp->isp_param)->isp_diffmode = 1;
((sdparam *)isp->isp_param)->isp_ultramode = 0;
((sdparam *)isp->isp_param)->isp_lvdmode = 0;
SDPARAM(isp)->isp_diffmode = 1;
SDPARAM(isp)->isp_ultramode = 0;
SDPARAM(isp)->isp_lvdmode = 0;
break;
case SXP_PINS_SE_MODE:
isp_prt(isp, ISP_LOGINFO,
"Transition to Single Ended mode");
((sdparam *)isp->isp_param)->isp_diffmode = 0;
((sdparam *)isp->isp_param)->isp_ultramode = 1;
((sdparam *)isp->isp_param)->isp_lvdmode = 0;
SDPARAM(isp)->isp_diffmode = 0;
SDPARAM(isp)->isp_ultramode = 1;
SDPARAM(isp)->isp_lvdmode = 0;
break;
default:
isp_prt(isp, ISP_LOGWARN,
@ -2895,15 +2940,24 @@ isp_parse_async(isp, mbox)
break;
case ASYNC_CTIO_DONE:
/* Should only occur when Fast Posting Set for 2100s */
isp_prt(isp, ISP_LOGDEBUG3, "Fast Posting CTIO done");
#ifdef ISP_TARGET_MODE
/*
* Bus gets overloaded with the handle. Dual bus
* cards don't put bus# into the handle.
*/
bus = (ISP_READ(isp, OUTMAILBOX2) << 16) |
ISP_READ(isp, OUTMAILBOX1);
isp_target_async(isp, bus, mbox);
#else
isp_prt(isp, ISP_LOGINFO, "Fast Posting CTIO done");
#endif
break;
case ASYNC_LIP_OCCURRED:
((fcparam *) isp->isp_param)->isp_lipseq =
FCPARAM(isp)->isp_lipseq =
ISP_READ(isp, OUTMAILBOX1);
((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
((fcparam *) isp->isp_param)->isp_loopstate = LOOP_LIP_RCVD;
FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
isp->isp_sendmarker = 1;
isp_mark_getpdb_all(isp);
isp_prt(isp, ISP_LOGINFO, "LIP occurred");
@ -2914,8 +2968,8 @@ isp_parse_async(isp, mbox)
case ASYNC_LOOP_UP:
isp->isp_sendmarker = 1;
((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
((fcparam *) isp->isp_param)->isp_loopstate = LOOP_LIP_RCVD;
FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
isp_mark_getpdb_all(isp);
isp_async(isp, ISPASYNC_LOOP_UP, NULL);
#ifdef ISP_TARGET_MODE
@ -2925,8 +2979,8 @@ isp_parse_async(isp, mbox)
case ASYNC_LOOP_DOWN:
isp->isp_sendmarker = 1;
((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
((fcparam *) isp->isp_param)->isp_loopstate = LOOP_NIL;
FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
FCPARAM(isp)->isp_loopstate = LOOP_NIL;
isp_mark_getpdb_all(isp);
isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);
#ifdef ISP_TARGET_MODE
@ -2936,8 +2990,8 @@ isp_parse_async(isp, mbox)
case ASYNC_LOOP_RESET:
isp->isp_sendmarker = 1;
((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
((fcparam *) isp->isp_param)->isp_loopstate = LOOP_NIL;
FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
FCPARAM(isp)->isp_loopstate = LOOP_NIL;
isp_mark_getpdb_all(isp);
isp_prt(isp, ISP_LOGINFO, "Loop RESET");
#ifdef ISP_TARGET_MODE
@ -2947,7 +3001,7 @@ isp_parse_async(isp, mbox)
case ASYNC_PDB_CHANGED:
isp->isp_sendmarker = 1;
((fcparam *) isp->isp_param)->isp_loopstate = LOOP_PDB_RCVD;
FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
isp_mark_getpdb_all(isp);
isp_prt(isp, ISP_LOGINFO, "Port Database Changed");
break;
@ -2957,19 +3011,19 @@ isp_parse_async(isp, mbox)
/*
* Not correct, but it will force us to rescan the loop.
*/
((fcparam *) isp->isp_param)->isp_loopstate = LOOP_PDB_RCVD;
FCPARAM(isp)->isp_loopstate = LOOP_PDB_RCVD;
isp_async(isp, ISPASYNC_CHANGE_NOTIFY, NULL);
break;
case ASYNC_PTPMODE:
if (((fcparam *) isp->isp_param)->isp_onfabric)
((fcparam *) isp->isp_param)->isp_topo = TOPO_N_PORT;
if (FCPARAM(isp)->isp_onfabric)
FCPARAM(isp)->isp_topo = TOPO_N_PORT;
else
((fcparam *) isp->isp_param)->isp_topo = TOPO_F_PORT;
FCPARAM(isp)->isp_topo = TOPO_F_PORT;
isp_mark_getpdb_all(isp);
isp->isp_sendmarker = 1;
((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
((fcparam *) isp->isp_param)->isp_loopstate = LOOP_LIP_RCVD;
FCPARAM(isp)->isp_fwstate = FW_CONFIG_WAIT;
FCPARAM(isp)->isp_loopstate = LOOP_LIP_RCVD;
#ifdef ISP_TARGET_MODE
isp_target_async(isp, bus, mbox);
#endif
@ -3021,6 +3075,9 @@ isp_handle_other_response(isp, sp, optrp)
u_int16_t *optrp;
{
switch (sp->req_header.rqs_entry_type) {
case RQSTYPE_STATUS_CONT:
isp_prt(isp, ISP_LOGINFO, "Ignored Continuation Response");
return (0);
case RQSTYPE_ATIO:
case RQSTYPE_CTIO:
case RQSTYPE_ENABLE_LUN:
@ -3060,7 +3117,7 @@ isp_parse_status(isp, sp, xs)
case RQCS_INCOMPLETE:
if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
isp_prt(isp, ISP_LOGDEBUG0,
isp_prt(isp, ISP_LOGDEBUG1,
"Selection Timeout for %d.%d.%d",
XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
if (XS_NOERR(xs)) {
@ -3163,10 +3220,7 @@ isp_parse_status(isp, sp, xs)
return;
case RQCS_DATA_OVERRUN:
if (IS_FC(isp)) {
XS_RESID(xs) = sp->req_resid;
break;
}
XS_RESID(xs) = sp->req_resid;
isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d",
XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
if (XS_NOERR(xs)) {
@ -3247,9 +3301,7 @@ isp_parse_status(isp, sp, xs)
break;
case RQCS_DATA_UNDERRUN:
if (IS_FC(isp)) {
XS_RESID(xs) = sp->req_resid;
}
XS_RESID(xs) = sp->req_resid;
if (XS_NOERR(xs)) {
XS_SETERR(xs, HBA_NOERROR);
}
@ -3414,9 +3466,9 @@ isp_fastpost_complete(isp, fph)
if (XS_XFRLEN(xs)) {
ISP_DMAFREE(isp, xs, fph);
}
isp_done(xs);
if (isp->isp_nactive)
isp->isp_nactive--;
isp_done(xs);
}
#define HIBYT(x) ((x) >> 0x8)
@ -4040,13 +4092,13 @@ static void
isp_update(isp)
struct ispsoftc *isp;
{
int bus;
int bus, upmask;
for (bus = 0; isp->isp_update != 0; bus++) {
if (isp->isp_update & (1 << bus)) {
for (bus = 0, upmask = isp->isp_update; upmask != 0; bus++) {
if (upmask & (1 << bus)) {
isp_update_bus(isp, bus);
isp->isp_update ^= (1 << bus);
}
upmask &= ~(1 << bus);
}
}
@ -4059,10 +4111,13 @@ isp_update_bus(isp, bus)
mbreg_t mbs;
sdparam *sdp;
isp->isp_update &= ~(1 << bus);
if (IS_FC(isp)) {
/*
* There are no 'per-bus' settings for Fibre Channel.
*/
return;
}
sdp = isp->isp_param;
sdp += bus;
@ -4071,35 +4126,57 @@ isp_update_bus(isp, bus)
int get;
if (sdp->isp_devparam[tgt].dev_enable == 0) {
sdp->isp_devparam[tgt].dev_update = 0;
sdp->isp_devparam[tgt].dev_refresh = 0;
isp_prt(isp, ISP_LOGDEBUG1,
"skipping target %d bus %d update", tgt, bus);
continue;
}
/*
* If the goal is to update the status of the device,
* take what's in dev_flags and try and set the device
* toward that. Otherwise, if we're just refreshing the
* current device state, get the current parameters.
*/
if (sdp->isp_devparam[tgt].dev_update) {
/*
* Refresh overrides set
*/
if (sdp->isp_devparam[tgt].dev_refresh) {
mbs.param[0] = MBOX_GET_TARGET_PARAMS;
sdp->isp_devparam[tgt].dev_refresh = 0;
get = 1;
} else if (sdp->isp_devparam[tgt].dev_update) {
mbs.param[0] = MBOX_SET_TARGET_PARAMS;
mbs.param[2] = sdp->isp_devparam[tgt].dev_flags;
/*
* Insist that PARITY must be enabled if SYNC
* is enabled.
* Make sure dev_flags has "Renegotiate on Error"
* on and "Freeze Queue on Error" off.
*/
if (mbs.param[2] & DPARM_SYNC) {
sdp->isp_devparam[tgt].dev_flags |= DPARM_RENEG;
sdp->isp_devparam[tgt].dev_flags &= ~DPARM_QFRZ;
mbs.param[2] = sdp->isp_devparam[tgt].dev_flags;
/*
* Insist that PARITY must be enabled
* if SYNC or WIDE is enabled.
*/
if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
mbs.param[2] |= DPARM_PARITY;
}
mbs.param[3] =
(sdp->isp_devparam[tgt].sync_offset << 8) |
(sdp->isp_devparam[tgt].sync_period);
sdp->isp_devparam[tgt].dev_update = 0;
if ((mbs.param[2] & DPARM_SYNC) == 0) {
mbs.param[3] = 0;
} else {
mbs.param[3] =
(sdp->isp_devparam[tgt].sync_offset << 8) |
(sdp->isp_devparam[tgt].sync_period);
}
/*
* A command completion later that has
* RQSTF_NEGOTIATION set will cause
* the dev_refresh/announce cycle.
* RQSTF_NEGOTIATION set canl cause
* the dev_refresh/announce cycle also.
&
*
* Note: It is really important to update our current
* flags with at least the state of TAG capabilities-
@ -4110,16 +4187,13 @@ isp_update_bus(isp, bus)
sdp->isp_devparam[tgt].cur_dflags &= ~DPARM_TQING;
sdp->isp_devparam[tgt].cur_dflags |=
(sdp->isp_devparam[tgt].dev_flags & DPARM_TQING);
sdp->isp_devparam[tgt].dev_refresh = 1;
isp_prt(isp, ISP_LOGDEBUG2,
"bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
bus, tgt, mbs.param[2], mbs.param[3] >> 8,
mbs.param[3] & 0xff);
sdp->isp_devparam[tgt].dev_update = 0;
sdp->isp_devparam[tgt].dev_refresh = 1;
get = 0;
} else if (sdp->isp_devparam[tgt].dev_refresh) {
mbs.param[0] = MBOX_GET_TARGET_PARAMS;
sdp->isp_devparam[tgt].dev_refresh = 0;
get = 1;
} else {
continue;
}
@ -4138,6 +4212,14 @@ isp_update_bus(isp, bus)
get = (bus << 16) | tgt;
(void) isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &get);
}
for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
if (sdp->isp_devparam[tgt].dev_update ||
sdp->isp_devparam[tgt].dev_refresh) {
isp->isp_update |= (1 << bus);
break;
}
}
}
static void
@ -4158,13 +4240,28 @@ isp_setdfltparm(isp, channel)
fcp->isp_gotdparms = 1;
fcp->isp_maxfrmlen = ICB_DFLT_FRMLEN;
fcp->isp_maxalloc = ICB_DFLT_ALLOC;
fcp->isp_execthrottle = ICB_DFLT_THROTTLE;
fcp->isp_execthrottle = ISP_EXEC_THROTTLE;
fcp->isp_retry_delay = ICB_DFLT_RDELAY;
fcp->isp_retry_count = ICB_DFLT_RCOUNT;
/* Platform specific.... */
fcp->isp_loopid = DEFAULT_LOOPID(isp);
fcp->isp_nodewwn = DEFAULT_NODEWWN(isp);
fcp->isp_portwwn = DEFAULT_PORTWWN(isp);
fcp->isp_fwoptions = 0;
fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
#ifndef ISP_NO_FASTPOST_FC
fcp->isp_fwoptions |= ICBOPT_FAST_POST;
#endif
if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
/*
* Make sure this is turned off now until we get
* extended options from NVRAM
*/
fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
/*
* Now try and read NVRAM
@ -4256,16 +4353,26 @@ isp_setdfltparm(isp, channel)
ISP_10M_SYNCPARMS >> 8;
sdp->isp_devparam[tgt].sync_period =
ISP_10M_SYNCPARMS & 0xff;
} else if (IS_ULTRA3(isp)) {
sdp->isp_devparam[tgt].sync_offset =
ISP_80M_SYNCPARMS >> 8;
sdp->isp_devparam[tgt].sync_period =
ISP_80M_SYNCPARMS & 0xff;
} else if (IS_ULTRA2(isp)) {
sdp->isp_devparam[tgt].sync_offset =
ISP_40M_SYNCPARMS >> 8;
sdp->isp_devparam[tgt].sync_period =
ISP_40M_SYNCPARMS & 0xff;
} else {
} else if (IS_1240(isp)) {
sdp->isp_devparam[tgt].sync_offset =
ISP_20M_SYNCPARMS >> 8;
sdp->isp_devparam[tgt].sync_period =
ISP_20M_SYNCPARMS & 0xff;
} else {
sdp->isp_devparam[tgt].sync_offset =
ISP_20M_SYNCPARMS_1040 >> 8;
sdp->isp_devparam[tgt].sync_period =
ISP_20M_SYNCPARMS_1040 & 0xff;
}
/*
@ -4313,7 +4420,7 @@ isp_setdfltparm(isp, channel)
}
}
isp_prt(isp, ISP_LOGDEBUG1,
"bus %d tgt %d flags %x offset %x period %x",
"Initial bus %d tgt %d flags %x offset %x period %x",
channel, tgt, sdp->isp_devparam[tgt].dev_flags,
sdp->isp_devparam[tgt].sync_offset,
sdp->isp_devparam[tgt].sync_period);
@ -4339,7 +4446,7 @@ isp_setdfltparm(isp, channel)
sdp->isp_retry_delay = 2;
for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
sdp->isp_devparam[tgt].exc_throttle = 16;
sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
sdp->isp_devparam[tgt].dev_enable = 1;
}
}
@ -4589,7 +4696,7 @@ isp_parse_nvram_1020(isp, nvram_data)
sdp->isp_max_queue_depth =
ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
isp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
for (i = 0; i < MAX_TARGETS; i++) {
sdp->isp_devparam[i].dev_enable =
ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i);

View file

@ -2,11 +2,7 @@
/*
* Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
*
*---------------------------------------
* Copyright (c) 1997, 1998, 1999 by Matthew Jacob
* NASA/Ames Research Center
* All rights reserved.
*---------------------------------------
* Copyright (c) 1997, 1998, 1999, 2000 by Matthew Jacob
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -17,8 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@ -164,7 +158,9 @@ isp_intr_enable(void *arg)
{
struct ispsoftc *isp = arg;
ENABLE_INTS(isp);
#ifdef SERVICING_INTERRUPT
isp->isp_osinfo.intsok = 1;
#endif
/* Release our hook so that the boot can continue. */
config_intrhook_disestablish(&isp->isp_osinfo.ehook);
}
@ -399,7 +395,7 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
struct ccb_en_lun *cel = &ccb->cel;
tstate_t *tptr;
u_int16_t rstat;
int bus;
int bus, frozen = 0;
lun_id_t lun;
target_id_t tgt;
@ -408,97 +404,6 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
tgt = ccb->ccb_h.target_id;
lun = ccb->ccb_h.target_lun;
/*
* First, check to see if we're enabling on fibre channel
* and don't yet have a notion of who the heck we are (no
* loop yet).
*/
if (IS_FC(isp) && cel->enable &&
(isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) {
int rv= 2 * 1000000;
fcparam *fcp = isp->isp_param;
ISP_LOCK(isp);
rv = isp_control(isp, ISPCTL_FCLINK_TEST, &rv);
ISP_UNLOCK(isp);
if (rv || fcp->isp_fwstate != FW_READY) {
xpt_print_path(ccb->ccb_h.path);
printf("link status not good yet\n");
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
return;
}
ISP_LOCK(isp);
rv = isp_control(isp, ISPCTL_PDB_SYNC, NULL);
ISP_UNLOCK(isp);
if (rv || fcp->isp_fwstate != FW_READY) {
xpt_print_path(ccb->ccb_h.path);
printf("could not get a good port database read\n");
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
return;
}
}
/*
* Next check to see whether this is a target/lun wildcard action.
*
* If so, we enable/disable target mode but don't do any lun enabling.
*/
if (lun == CAM_LUN_WILDCARD && tgt == CAM_TARGET_WILDCARD) {
int av;
tptr = &isp->isp_osinfo.tsdflt;
if (cel->enable) {
if (isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) {
ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
return;
}
ccb->ccb_h.status =
xpt_create_path(&tptr->owner, NULL,
xpt_path_path_id(ccb->ccb_h.path),
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;
}
SLIST_INIT(&tptr->atios);
SLIST_INIT(&tptr->inots);
av = 1;
ISP_LOCK(isp);
av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
if (av) {
ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
xpt_free_path(tptr->owner);
ISP_UNLOCK(isp);
return;
}
isp->isp_osinfo.tmflags |= TM_TMODE_ENABLED;
ISP_UNLOCK(isp);
} else {
if ((isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) {
ccb->ccb_h.status = CAM_LUN_INVALID;
return;
}
if (are_any_luns_enabled(isp)) {
ccb->ccb_h.status = CAM_SCSI_BUSY;
return;
}
av = 0;
ISP_LOCK(isp);
av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
if (av) {
ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
ISP_UNLOCK(isp);
return;
}
isp->isp_osinfo.tmflags &= ~TM_TMODE_ENABLED;
ISP_UNLOCK(isp);
ccb->ccb_h.status = CAM_REQ_CMP;
}
xpt_print_path(ccb->ccb_h.path);
printf(lfmt, (cel->enable) ? "en" : "dis");
return;
}
/*
* Do some sanity checking first.
*/
@ -521,6 +426,137 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb)
}
}
/*
* If Fibre Channel, stop and drain all activity to this bus.
*/
if (IS_FC(isp)) {
ISP_LOCK(isp);
frozen = 1;
xpt_freeze_simq(isp->isp_sim, 1);
isp->isp_osinfo.drain = 1;
/* ISP_UNLOCK(isp); XXX NEED CV_WAIT HERE XXX */
while (isp->isp_osinfo.drain) {
tsleep(&isp->isp_osinfo.drain, PRIBIO, "ispdrain", 0);
}
ISP_UNLOCK(isp);
}
/*
* Check to see if we're enabling on fibre channel and
* don't yet have a notion of who the heck we are (no
* loop yet).
*/
if (IS_FC(isp) && cel->enable &&
(isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) {
int rv= 2 * 1000000;
fcparam *fcp = isp->isp_param;
ISP_LOCK(isp);
rv = isp_control(isp, ISPCTL_FCLINK_TEST, &rv);
ISP_UNLOCK(isp);
if (rv || fcp->isp_fwstate != FW_READY) {
xpt_print_path(ccb->ccb_h.path);
printf("link status not good yet\n");
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
if (frozen)
xpt_release_simq(isp->isp_sim, 1);
return;
}
ISP_LOCK(isp);
rv = isp_control(isp, ISPCTL_PDB_SYNC, NULL);
ISP_UNLOCK(isp);
if (rv || fcp->isp_fwstate != FW_READY) {
xpt_print_path(ccb->ccb_h.path);
printf("could not get a good port database read\n");
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
if (frozen)
xpt_release_simq(isp->isp_sim, 1);
return;
}
}
/*
* Next check to see whether this is a target/lun wildcard action.
*
* If so, we enable/disable target mode but don't do any lun enabling.
*/
if (lun == CAM_LUN_WILDCARD && tgt == CAM_TARGET_WILDCARD) {
int av;
tptr = &isp->isp_osinfo.tsdflt;
if (cel->enable) {
if (isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) {
ccb->ccb_h.status = CAM_LUN_ALRDY_ENA;
if (frozen)
xpt_release_simq(isp->isp_sim, 1);
return;
}
ccb->ccb_h.status =
xpt_create_path(&tptr->owner, NULL,
xpt_path_path_id(ccb->ccb_h.path),
xpt_path_target_id(ccb->ccb_h.path),
xpt_path_lun_id(ccb->ccb_h.path));
if (ccb->ccb_h.status != CAM_REQ_CMP) {
if (frozen)
xpt_release_simq(isp->isp_sim, 1);
return;
}
SLIST_INIT(&tptr->atios);
SLIST_INIT(&tptr->inots);
av = 1;
ISP_LOCK(isp);
av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
if (av) {
ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
xpt_free_path(tptr->owner);
ISP_UNLOCK(isp);
if (frozen)
xpt_release_simq(isp->isp_sim, 1);
return;
}
isp->isp_osinfo.tmflags |= TM_TMODE_ENABLED;
ISP_UNLOCK(isp);
} else {
if ((isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) {
ccb->ccb_h.status = CAM_LUN_INVALID;
if (frozen)
xpt_release_simq(isp->isp_sim, 1);
return;
}
if (are_any_luns_enabled(isp)) {
ccb->ccb_h.status = CAM_SCSI_BUSY;
if (frozen)
xpt_release_simq(isp->isp_sim, 1);
return;
}
av = 0;
ISP_LOCK(isp);
av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av);
if (av) {
ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
ISP_UNLOCK(isp);
if (frozen)
xpt_release_simq(isp->isp_sim, 1);
return;
}
isp->isp_osinfo.tmflags &= ~TM_TMODE_ENABLED;
ISP_UNLOCK(isp);
ccb->ccb_h.status = CAM_REQ_CMP;
}
xpt_print_path(ccb->ccb_h.path);
printf(lfmt, (cel->enable) ? "en" : "dis");
if (frozen)
xpt_release_simq(isp->isp_sim, 1);
return;
}
/*
* We can move along now...
*/
if (frozen)
xpt_release_simq(isp->isp_sim, 1);
if (cel->enable) {
ccb->ccb_h.status =
@ -1417,7 +1453,6 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
if (isp->isp_state != ISP_RUNSTATE &&
ccb->ccb_h.func_code == XPT_SCSI_IO) {
ISP_LOCK(isp);
DISABLE_INTS(isp);
isp_init(isp);
if (isp->isp_state != ISP_INITSTATE) {
ISP_UNLOCK(isp);
@ -1430,7 +1465,6 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
return;
}
isp->isp_state = ISP_RUNSTATE;
ENABLE_INTS(isp);
ISP_UNLOCK(isp);
}
isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code);

View file

@ -1,11 +1,7 @@
/* $FreeBSD$ */
/*
* Qlogic ISP SCSI Host Adapter FreeBSD Wrapper Definitions (CAM version)
*---------------------------------------
* Copyright (c) 1997, 1998, 1999 by Matthew Jacob
* NASA/Ames Research Center
* All rights reserved.
*---------------------------------------
* Copyright (c) 1997, 1998, 1999, 2000 by Matthew Jacob
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -16,8 +12,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@ -99,11 +93,15 @@ struct isposinfo {
struct cam_sim *sim2;
struct cam_path *path2;
struct intr_config_hook ehook;
volatile u_int16_t : 14,
islocked : 1,
intsok : 1;
u_int8_t mboxwaiting;
u_int8_t simqfrozen;
u_int8_t drain;
#ifdef SERVICING_INTERRUPT
u_int8_t intsok;
#else
u_int8_t padding;
#endif
volatile u_int32_t islocked;
int splsaved;
#ifdef ISP_TARGET_MODE
#define TM_WANTED 0x01
@ -314,8 +312,7 @@ static INLINE void
isp_lock(struct ispsoftc *isp)
{
int s = splcam();
if (isp->isp_osinfo.islocked == 0) {
isp->isp_osinfo.islocked = 1;
if (isp->isp_osinfo.islocked++ == 0) {
isp->isp_osinfo.splsaved = s;
} else {
splx(s);
@ -326,8 +323,7 @@ static INLINE void isp_unlock(struct ispsoftc *);
static INLINE void
isp_unlock(struct ispsoftc *isp)
{
if (isp->isp_osinfo.islocked) {
isp->isp_osinfo.islocked = 0;
if (--isp->isp_osinfo.islocked == 0) {
splx(isp->isp_osinfo.splsaved);
}
}

View file

@ -83,7 +83,7 @@ isp_save_xs(isp, xs, handlep)
*handlep = j+1;
if (++j == isp->isp_maxcmds)
j = 0;
isp->isp_lasthdls = j;
isp->isp_lasthdls = (u_int16_t)j;
return (0);
}
@ -206,18 +206,20 @@ isp_print_bytes(isp, msg, amt, arg)
u_int8_t *ptr = arg;
int off;
if (msg)
isp_prt(isp, ISP_LOGALL, "%s:", msg);
off = 0;
buf[0] = 0;
while (off < amt) {
int j, to;
to = off;
SNPRINTF(buf, 128, "<");
for (j = 0; j < 16; j++) {
SNPRINTF(buf, 128, "%s %02x", buf, ptr[off++] & 0xff);
if (off == amt)
break;
}
isp_prt(isp, ISP_LOGALL,
"<%s>offset=0x%x:\n%s>", msg, to, buf);
isp_prt(isp, ISP_LOGALL, "0x%08x:%s", to, buf);
buf[0] = 0;
}
}
#endif /* _ISP_INLINE_H */

View file

@ -525,11 +525,9 @@ isp_target_async(isp, bus, event)
*/
MEMZERO(&msg, sizeof msg);
if (IS_FC(isp)) {
msg.nt_iid =
((fcparam *)isp->isp_param)->isp_loopid;
msg.nt_iid = FCPARAM(isp)->isp_loopid;
} else {
msg.nt_iid =
((sdparam *)isp->isp_param)->isp_initiator_id;
msg.nt_iid = SDPARAM(isp)->isp_initiator_id;
}
msg.nt_bus = bus;
msg.nt_msg[0] = MSG_BUS_DEV_RESET;

View file

@ -374,7 +374,7 @@ typedef struct {
#define req_response_len req_time /* FC only */
u_int16_t req_sense_len;
u_int32_t req_resid;
u_int8_t _res1[8];
u_int8_t req_response[8]; /* FC only */
u_int8_t req_sense_data[32];
} ispstatusreq_t;
@ -384,20 +384,25 @@ typedef struct {
*/
#define RQCS_RU 0x800 /* Residual Under */
#define RQCS_RO 0x400 /* Residual Over */
#define RQCS_RESID (RQCS_RU|RQCS_RO)
#define RQCS_SV 0x200 /* Sense Length Valid */
#define RQCS_RV 0x100 /* Residual Valid */
#define RQCS_RV 0x100 /* FCP Response Length Valid */
/*
* Completion Status Codes.
*/
#define RQCS_COMPLETE 0x0000
#define RQCS_INCOMPLETE 0x0001
#define RQCS_DMA_ERROR 0x0002
#define RQCS_TRANSPORT_ERROR 0x0003
#define RQCS_RESET_OCCURRED 0x0004
#define RQCS_ABORTED 0x0005
#define RQCS_TIMEOUT 0x0006
#define RQCS_DATA_OVERRUN 0x0007
#define RQCS_DATA_UNDERRUN 0x0015
#define RQCS_QUEUE_FULL 0x001C
/* 1X00 Only Completion Codes */
#define RQCS_INCOMPLETE 0x0001
#define RQCS_TRANSPORT_ERROR 0x0003
#define RQCS_COMMAND_OVERRUN 0x0008
#define RQCS_STATUS_OVERRUN 0x0009
#define RQCS_BAD_MESSAGE 0x000a
@ -411,26 +416,24 @@ typedef struct {
#define RQCS_DEVICE_RESET_MSG_FAILED 0x0012
#define RQCS_ID_MSG_FAILED 0x0013
#define RQCS_UNEXP_BUS_FREE 0x0014
#define RQCS_DATA_UNDERRUN 0x0015
#define RQCS_XACT_ERR1 0x0018
#define RQCS_XACT_ERR2 0x0019
#define RQCS_XACT_ERR3 0x001A
#define RQCS_BAD_ENTRY 0x001B
#define RQCS_QUEUE_FULL 0x001C
#define RQCS_PHASE_SKIPPED 0x001D
#define RQCS_ARQS_FAILED 0x001E
#define RQCS_WIDE_FAILED 0x001F
#define RQCS_SYNCXFER_FAILED 0x0020
#define RQCS_LVD_BUSERR 0x0021
/* 2100 Only Completion Codes */
/* 2X00 Only Completion Codes */
#define RQCS_PORT_UNAVAILABLE 0x0028
#define RQCS_PORT_LOGGED_OUT 0x0029
#define RQCS_PORT_CHANGED 0x002A
#define RQCS_PORT_BUSY 0x002B
/*
* State Flags (not applicable to 2100)
* 1X00 specific State Flags
*/
#define RQSF_GOT_BUS 0x0100
#define RQSF_GOT_TARGET 0x0200
@ -441,7 +444,7 @@ typedef struct {
#define RQSF_XFER_COMPLETE 0x4000
/*
* Status Flags (not applicable to 2100)
* 1X00 Status Flags
*/
#define RQSTF_DISCONNECT 0x0001
#define RQSTF_SYNCHRONOUS 0x0002
@ -452,6 +455,29 @@ typedef struct {
#define RQSTF_TIMEOUT 0x0040
#define RQSTF_NEGOTIATION 0x0080
/*
* 2X00 specific state flags
*/
/* RQSF_SENT_CDB */
/* RQSF_XFRD_DATA */
/* RQSF_GOT_STATUS */
/* RQSF_XFER_COMPLETE */
/*
* 2X00 specific status flags
*/
/* RQSTF_ABORTED */
/* RQSTF_TIMEOUT */
#define RQSTF_DMA_ERROR 0x0080
#define RQSTF_LOGOUT 0x2000
/*
* Miscellaneous
*/
#ifndef ISP_EXEC_THROTTLE
#define ISP_EXEC_THROTTLE 16
#endif
/*
* FC (ISP2100) specific data structures
*/

View file

@ -153,9 +153,11 @@ struct ispmdvec {
#define ISP_QUEUE_ENTRY(q, idx) ((q) + ((idx) * QENTRY_LEN))
#define ISP_QUEUE_SIZE(n) ((n) * QENTRY_LEN)
#define ISP_NXT_QENTRY(idx, qlen) (((idx) + 1) & ((qlen)-1))
#define ISP_QAVAIL(in, out, qlen) \
#define ISP_QFREE(in, out, qlen) \
((in == out)? (qlen - 1) : ((in > out)? \
((qlen - 1) - (in - out)) : (out - in - 1)))
#define ISP_QAVAIL(isp) \
ISP_QFREE(isp->isp_reqidx, isp->isp_reqodx, RQUEST_QUEUE_LEN(isp))
#define ISP_ADD_REQUEST(isp, iptr) \
MEMORYBARRIER(isp, SYNC_REQUEST, iptr, QENTRY_LEN); \
@ -176,7 +178,7 @@ typedef struct {
isp_ultramode : 1,
isp_diffmode : 1,
isp_lvdmode : 1,
: 1,
isp_fast_mttr : 1, /* fast sram */
isp_initiator_id : 4,
isp_async_data_setup : 4;
u_int16_t isp_selection_timeout;
@ -211,15 +213,18 @@ typedef struct {
#define DPARM_ARQ 0x0400
#define DPARM_QFRZ 0x0200
#define DPARM_RENEG 0x0100
#define DPARM_NARROW 0x0080 /* Possibly only available with >= 7.55 fw */
#define DPARM_ASYNC 0x0040 /* Possibly only available with >= 7.55 fw */
#define DPARM_NARROW 0x0080
#define DPARM_ASYNC 0x0040
#define DPARM_PPR 0x0020
#define DPARM_DEFAULT (0xFF00 & ~DPARM_QFRZ)
#define DPARM_SAFE_DFLT (DPARM_DEFAULT & ~(DPARM_WIDE|DPARM_SYNC|DPARM_TQING))
/* technically, not really correct, as they need to be rated based upon clock */
#define ISP_40M_SYNCPARMS 0x080a
#define ISP_20M_SYNCPARMS 0x080c
#define ISP_80M_SYNCPARMS 0x0c09
#define ISP_40M_SYNCPARMS 0x0c0a
#define ISP_20M_SYNCPARMS 0x0c0c
#define ISP_20M_SYNCPARMS_1040 0x080c
#define ISP_10M_SYNCPARMS 0x0c19
#define ISP_08M_SYNCPARMS 0x0c25
#define ISP_05M_SYNCPARMS 0x0c32
@ -304,7 +309,7 @@ typedef struct {
/*
* Soft Structure per host adapter
*/
struct ispsoftc {
typedef struct ispsoftc {
/*
* Platform (OS) specific data
*/
@ -330,9 +335,9 @@ struct ispsoftc {
u_int32_t
isp_touched : 1, /* board ever seen? */
isp_fast_mttr : 1, /* fast sram */
isp_bustype : 1, /* SBus or PCI */
: 1,
isp_bustype : 1, /* SBus or PCI */
isp_loaded_fw : 1, /* loaded firmware */
isp_dblev : 12, /* debug log mask */
isp_clock : 8, /* input clock */
isp_confopts : 8; /* config options */
@ -366,7 +371,7 @@ struct ispsoftc {
caddr_t isp_result;
u_int32_t isp_rquest_dma;
u_int32_t isp_result_dma;
};
} ispsoftc_t;
#define SDPARAM(isp) ((sdparam *) (isp)->isp_param)
#define FCPARAM(isp) ((fcparam *) (isp)->isp_param)