From bcbec50333d0c724a16c70ce1cf20a68bee1a2c6 Mon Sep 17 00:00:00 2001 From: mjacob Date: Sun, 27 Aug 2000 23:38:44 +0000 Subject: various fixes --- sys/dev/isp/isp.c | 447 ++++++++++++++++++++++++++++------------------ sys/dev/isp/isp_freebsd.c | 94 ++++++---- sys/dev/isp/isp_freebsd.h | 24 ++- sys/dev/isp/isp_inline.h | 10 +- sys/dev/isp/isp_target.c | 6 +- sys/dev/isp/ispmbox.h | 44 ++++- sys/dev/isp/ispvar.h | 25 +-- 7 files changed, 409 insertions(+), 241 deletions(-) (limited to 'sys') diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index 891527c..e477fc8 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -595,7 +595,9 @@ again: 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; + /* + * Make sure dev_flags has "Renegotiate on Error" + * on and "Freeze Queue on Error" off. + */ + 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 - * is enabled. + * Insist that PARITY must be enabled + * if SYNC or WIDE is enabled. */ - if (mbs.param[2] & DPARM_SYNC) { + 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); diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index 05bd5eb..b38065b 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -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; @@ -409,8 +405,45 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb) 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 + * Do some sanity checking first. + */ + + if (lun < 0 || lun >= (lun_id_t) isp->isp_maxluns) { + ccb->ccb_h.status = CAM_LUN_INVALID; + return; + } + if (IS_SCSI(isp)) { + if (tgt != CAM_TARGET_WILDCARD && + tgt != ((sdparam *) isp->isp_param)->isp_initiator_id) { + ccb->ccb_h.status = CAM_TID_INVALID; + return; + } + } else { + if (tgt != CAM_TARGET_WILDCARD && + tgt != ((fcparam *) isp->isp_param)->isp_loopid) { + ccb->ccb_h.status = CAM_TID_INVALID; + return; + } + } + + /* + * 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 && @@ -425,6 +458,8 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb) 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); @@ -434,6 +469,8 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb) 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; } } @@ -450,6 +487,8 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb) 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 = @@ -458,6 +497,8 @@ 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) { + if (frozen) + xpt_release_simq(isp->isp_sim, 1); return; } SLIST_INIT(&tptr->atios); @@ -469,6 +510,8 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb) 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; @@ -476,10 +519,14 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb) } 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; @@ -488,6 +535,8 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb) 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; @@ -496,30 +545,17 @@ isp_en_lun(struct ispsoftc *isp, union ccb *ccb) } xpt_print_path(ccb->ccb_h.path); printf(lfmt, (cel->enable) ? "en" : "dis"); + if (frozen) + xpt_release_simq(isp->isp_sim, 1); return; } /* - * Do some sanity checking first. + * We can move along now... */ - if (lun < 0 || lun >= (lun_id_t) isp->isp_maxluns) { - ccb->ccb_h.status = CAM_LUN_INVALID; - return; - } - if (IS_SCSI(isp)) { - if (tgt != CAM_TARGET_WILDCARD && - tgt != ((sdparam *) isp->isp_param)->isp_initiator_id) { - ccb->ccb_h.status = CAM_TID_INVALID; - return; - } - } else { - if (tgt != CAM_TARGET_WILDCARD && - tgt != ((fcparam *) isp->isp_param)->isp_loopid) { - ccb->ccb_h.status = CAM_TID_INVALID; - return; - } - } + if (frozen) + xpt_release_simq(isp->isp_sim, 1); if (cel->enable) { @@ -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); diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h index 7a88c9f..e376c10 100644 --- a/sys/dev/isp/isp_freebsd.h +++ b/sys/dev/isp/isp_freebsd.h @@ -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); } } diff --git a/sys/dev/isp/isp_inline.h b/sys/dev/isp/isp_inline.h index 8c086b9..a32461e 100644 --- a/sys/dev/isp/isp_inline.h +++ b/sys/dev/isp/isp_inline.h @@ -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 */ diff --git a/sys/dev/isp/isp_target.c b/sys/dev/isp/isp_target.c index dced16c..b7c4632 100644 --- a/sys/dev/isp/isp_target.c +++ b/sys/dev/isp/isp_target.c @@ -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; diff --git a/sys/dev/isp/ispmbox.h b/sys/dev/isp/ispmbox.h index dc03a09..e93b947 100644 --- a/sys/dev/isp/ispmbox.h +++ b/sys/dev/isp/ispmbox.h @@ -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 @@ -453,6 +456,29 @@ typedef struct { #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 */ diff --git a/sys/dev/isp/ispvar.h b/sys/dev/isp/ispvar.h index b846070..0afbfcb 100644 --- a/sys/dev/isp/ispvar.h +++ b/sys/dev/isp/ispvar.h @@ -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) -- cgit v1.1