diff options
Diffstat (limited to 'sys/dev/isp/isp.c')
| -rw-r--r-- | sys/dev/isp/isp.c | 310 |
1 files changed, 172 insertions, 138 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index 6dd14e03a7cc..783fcea62b94 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -150,12 +150,14 @@ static void isp_parse_nvram_2100 __P((struct ispsoftc *, u_int8_t *)); * * Locking done elsewhere. */ + void isp_reset(struct ispsoftc *isp) { mbreg_t mbs; + u_int16_t code_org; int loops, i, touched, dodnld = 1; - char *revname = "????"; + char *btype = "????"; isp->isp_state = ISP_NILSTATE; @@ -163,7 +165,8 @@ isp_reset(struct ispsoftc *isp) /* * Basic types (SCSI, FibreChannel and PCI or SBus) * have been set in the MD code. We figure out more - * here. + * here. Possibly more refined types based upon PCI + * identification. Chip revision has been gathered. * * After we've fired this chip up, zero out the conf1 register * for SCSI adapters and do other settings for the 2100. @@ -205,6 +208,14 @@ isp_reset(struct ispsoftc *isp) } DISABLE_INTS(isp); + /* + * Set up default request/response queue in-pointer/out-pointer + * register indices. + */ + isp->isp_rqstinrp = INMAILBOX4; + isp->isp_rqstoutrp = OUTMAILBOX4; + isp->isp_respinrp = OUTMAILBOX5; + isp->isp_respoutrp = INMAILBOX5; /* * Put the board into PAUSE mode (so we can read the SXP registers @@ -215,13 +226,17 @@ isp_reset(struct ispsoftc *isp) if (IS_FC(isp)) { switch (isp->isp_type) { case ISP_HA_FC_2100: - revname = "2100"; + btype = "2100"; break; case ISP_HA_FC_2200: - revname = "2200"; + btype = "2200"; break; case ISP_HA_FC_2300: - revname = "2300"; + isp->isp_rqstinrp = BIU_REQINP; + isp->isp_rqstoutrp = BIU_REQOUTP; + isp->isp_respinrp = BIU_RSPINP; + isp->isp_respoutrp = BIU_RSPOUTP; + btype = "2300"; break; default: break; @@ -236,7 +251,7 @@ isp_reset(struct ispsoftc *isp) ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS); } else if (IS_1240(isp)) { sdparam *sdp = isp->isp_param; - revname = "1240"; + btype = "1240"; isp->isp_clock = 60; sdp->isp_ultramode = 1; sdp++; @@ -252,13 +267,13 @@ isp_reset(struct ispsoftc *isp) isp->isp_clock = 100; if (IS_1280(isp)) - revname = "1280"; + btype = "1280"; else if (IS_1080(isp)) - revname = "1080"; + btype = "1080"; else if (IS_12160(isp)) - revname = "12160"; + btype = "12160"; else - revname = "<UNKLVD>"; + btype = "<UNKLVD>"; l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK; switch (l) { @@ -313,7 +328,7 @@ isp_reset(struct ispsoftc *isp) isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i); /* FALLTHROUGH */ case 1: - revname = "1020"; + btype = "1020"; isp->isp_type = ISP_HA_SCSI_1020; isp->isp_clock = 40; break; @@ -323,27 +338,27 @@ isp_reset(struct ispsoftc *isp) * run the clock rate up for that unless told to * do so by the Ultra Capable bits being set. */ - revname = "1020A"; + btype = "1020A"; isp->isp_type = ISP_HA_SCSI_1020A; isp->isp_clock = 40; break; case 3: - revname = "1040"; + btype = "1040"; isp->isp_type = ISP_HA_SCSI_1040; isp->isp_clock = 60; break; case 4: - revname = "1040A"; + btype = "1040A"; isp->isp_type = ISP_HA_SCSI_1040A; isp->isp_clock = 60; break; case 5: - revname = "1040B"; + btype = "1040B"; isp->isp_type = ISP_HA_SCSI_1040B; isp->isp_clock = 60; break; case 6: - revname = "1040C"; + btype = "1040C"; isp->isp_type = ISP_HA_SCSI_1040C; isp->isp_clock = 60; break; @@ -593,11 +608,16 @@ again: dodnld = 0; } + if (IS_2300(isp)) + code_org = ISP_CODE_ORG_2300; + else + code_org = ISP_CODE_ORG; + if (dodnld) { u_int16_t fwlen = isp->isp_mdvec->dv_ispfw[3]; for (i = 0; i < fwlen; i++) { mbs.param[0] = MBOX_WRITE_RAM_WORD; - mbs.param[1] = ISP_CODE_ORG + i; + mbs.param[1] = code_org + i; mbs.param[2] = isp->isp_mdvec->dv_ispfw[i]; isp_mboxcmd(isp, &mbs, MBLOGNONE); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { @@ -612,7 +632,7 @@ again: * Verify that it downloaded correctly. */ mbs.param[0] = MBOX_VERIFY_CHECKSUM; - mbs.param[1] = ISP_CODE_ORG; + mbs.param[1] = code_org; isp_mboxcmd(isp, &mbs, MBLOGNONE); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { isp_prt(isp, ISP_LOGERR, "Ram Checksum Failure"); @@ -631,8 +651,9 @@ again: * we still need to (re)start it. */ + mbs.param[0] = MBOX_EXEC_FIRMWARE; - mbs.param[1] = ISP_CODE_ORG; + mbs.param[1] = code_org; isp_mboxcmd(isp, &mbs, MBLOGNONE); /* give it a chance to start */ USEC_SLEEP(isp, 500); @@ -655,9 +676,9 @@ again: return; } isp_prt(isp, ISP_LOGCONFIG, - "Board Revision %s, %s F/W Revision %d.%d.%d", revname, - dodnld? "loaded" : "resident", mbs.param[1], mbs.param[2], - mbs.param[3]); + "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d", + btype, isp->isp_revision, dodnld? "loaded" : "resident", + mbs.param[1], mbs.param[2], mbs.param[3]); if (IS_FC(isp)) { isp_prt(isp, ISP_LOGCONFIG, "Firmware Attributes = 0x%x", mbs.param[6]); @@ -871,8 +892,8 @@ isp_scsi_init(struct ispsoftc *isp) mbs.param[0] = MBOX_INIT_RES_QUEUE; mbs.param[1] = RESULT_QUEUE_LEN(isp); - mbs.param[2] = DMA_MSW(isp->isp_result_dma); - mbs.param[3] = DMA_LSW(isp->isp_result_dma); + mbs.param[2] = DMA_WD1(isp->isp_result_dma); + mbs.param[3] = DMA_WD0(isp->isp_result_dma); mbs.param[4] = 0; mbs.param[5] = 0; isp_mboxcmd(isp, &mbs, MBLOGALL); @@ -883,8 +904,8 @@ isp_scsi_init(struct ispsoftc *isp) mbs.param[0] = MBOX_INIT_REQ_QUEUE; mbs.param[1] = RQUEST_QUEUE_LEN(isp); - mbs.param[2] = DMA_MSW(isp->isp_rquest_dma); - mbs.param[3] = DMA_LSW(isp->isp_rquest_dma); + mbs.param[2] = DMA_WD1(isp->isp_rquest_dma); + mbs.param[3] = DMA_WD0(isp->isp_rquest_dma); mbs.param[4] = 0; isp_mboxcmd(isp, &mbs, MBLOGALL); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { @@ -1142,6 +1163,8 @@ isp_fibre_init(struct ispsoftc *isp) /* * Right now we just set extended options to prefer point-to-point * over loop based upon some soft config options. + * + * NB: for the 2300, ICBOPT_EXTENDED is required. */ if (IS_2200(isp) || IS_2300(isp)) { icbp->icb_fwoptions |= ICBOPT_EXTENDED; @@ -1162,6 +1185,15 @@ isp_fibre_init(struct ispsoftc *isp) icbp->icb_xfwoptions = ICBXOPT_LOOP_2_PTP; break; } + if (IS_2300(isp)) { + if (isp->isp_revision < 2) { + icbp->icb_fwoptions &= ~ICBOPT_FAST_POST; + } + icbp->icb_xfwoptions |= ICBXOPT_RATE_AUTO; + } + } + + if (IS_2200(isp) || IS_2300(isp)) { /* * Turn on LIP F8 async event (1) * Turn on generate AE 8013 on all LIP Resets (2) @@ -1173,7 +1205,14 @@ isp_fibre_init(struct ispsoftc *isp) mbs.param[3] = 0; isp_mboxcmd(isp, &mbs, MBLOGALL); } - icbp->icb_logintime = 60; /* 60 second login timeout */ + icbp->icb_logintime = 30; /* 30 second login timeout */ + + if (IS_2300(isp)) { + ISP_WRITE(isp, isp->isp_rqstinrp, 0); + ISP_WRITE(isp, isp->isp_rqstoutrp, 0); + ISP_WRITE(isp, isp->isp_respinrp, 0); + ISP_WRITE(isp, isp->isp_respoutrp, 0); + } nwwn = ISP_NODEWWN(isp); pwwn = ISP_PORTWWN(isp); @@ -1193,10 +1232,14 @@ isp_fibre_init(struct ispsoftc *isp) } icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp); icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp); - icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_LSW(isp->isp_rquest_dma); - 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); + icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma); + icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma); + icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma); + icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma); + icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma); + icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma); + icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma); + icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma); isp_prt(isp, ISP_LOGDEBUG1, "isp_fibre_init: fwoptions 0x%x", fcp->isp_fwoptions); ISP_SWIZZLE_ICB(isp, icbp); @@ -1207,12 +1250,12 @@ isp_fibre_init(struct ispsoftc *isp) */ mbs.param[0] = MBOX_INIT_FIRMWARE; mbs.param[1] = 0; - mbs.param[2] = DMA_MSW(fcp->isp_scdma); - mbs.param[3] = DMA_LSW(fcp->isp_scdma); + mbs.param[2] = DMA_WD1(fcp->isp_scdma); + mbs.param[3] = DMA_WD0(fcp->isp_scdma); mbs.param[4] = 0; mbs.param[5] = 0; - mbs.param[6] = 0; - mbs.param[7] = 0; + mbs.param[6] = DMA_WD3(fcp->isp_scdma); + mbs.param[7] = DMA_WD2(fcp->isp_scdma); isp_mboxcmd(isp, &mbs, MBLOGALL); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { return; @@ -1242,8 +1285,8 @@ isp_getmap(struct ispsoftc *isp, fcpos_map_t *map) mbs.param[0] = MBOX_GET_FC_AL_POSITION_MAP; mbs.param[1] = 0; - mbs.param[2] = DMA_MSW(fcp->isp_scdma); - mbs.param[3] = DMA_LSW(fcp->isp_scdma); + mbs.param[2] = DMA_WD1(fcp->isp_scdma); + mbs.param[3] = DMA_WD0(fcp->isp_scdma); /* * Unneeded. For the 2100, except for initializing f/w, registers * 4/5 have to not be written to. @@ -1280,8 +1323,8 @@ isp_getpdb(struct ispsoftc *isp, int id, isp_pdb_t *pdbp) mbs.param[0] = MBOX_GET_PORT_DB; mbs.param[1] = id << 8; - mbs.param[2] = DMA_MSW(fcp->isp_scdma); - mbs.param[3] = DMA_LSW(fcp->isp_scdma); + mbs.param[2] = DMA_WD1(fcp->isp_scdma); + mbs.param[3] = DMA_WD0(fcp->isp_scdma); /* * Unneeded. For the 2100, except for initializing f/w, registers * 4/5 have to not be written to. @@ -1289,8 +1332,8 @@ isp_getpdb(struct ispsoftc *isp, int id, isp_pdb_t *pdbp) * mbs.param[5] = 0; * */ - mbs.param[6] = 0; - mbs.param[7] = 0; + mbs.param[6] = DMA_WD3(fcp->isp_scdma); + mbs.param[7] = DMA_WD2(fcp->isp_scdma); isp_mboxcmd(isp, &mbs, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR); if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { ISP_UNSWIZZLE_AND_COPY_PDBP(isp, pdbp, fcp->isp_scratch); @@ -2183,9 +2226,13 @@ isp_scan_fabric(struct ispsoftc *isp) MEMZERO((void *) reqp, SNS_GAN_REQ_SIZE); reqp->snscb_rblen = SNS_GAN_RESP_SIZE >> 1; reqp->snscb_addr[RQRSP_ADDR0015] = - DMA_LSW(fcp->isp_scdma + 0x100); + DMA_WD0(fcp->isp_scdma + 0x100); reqp->snscb_addr[RQRSP_ADDR1631] = - DMA_MSW(fcp->isp_scdma + 0x100); + DMA_WD1(fcp->isp_scdma + 0x100); + reqp->snscb_addr[RQRSP_ADDR3247] = + DMA_WD2(fcp->isp_scdma + 0x100); + reqp->snscb_addr[RQRSP_ADDR4863] = + DMA_WD3(fcp->isp_scdma + 0x100); reqp->snscb_sblen = 6; reqp->snscb_data[0] = SNS_GAN; reqp->snscb_data[4] = portid & 0xffff; @@ -2193,10 +2240,13 @@ isp_scan_fabric(struct ispsoftc *isp) ISP_SWIZZLE_SNS_REQ(isp, reqp); mbs.param[0] = MBOX_SEND_SNS; mbs.param[1] = SNS_GAN_REQ_SIZE >> 1; - mbs.param[2] = DMA_MSW(fcp->isp_scdma); - mbs.param[3] = DMA_LSW(fcp->isp_scdma); - mbs.param[6] = 0; - mbs.param[7] = 0; + mbs.param[2] = DMA_WD1(fcp->isp_scdma); + mbs.param[3] = DMA_WD0(fcp->isp_scdma); + /* + * Leave 4 and 5 alone + */ + mbs.param[6] = DMA_WD3(fcp->isp_scdma); + mbs.param[7] = DMA_WD2(fcp->isp_scdma); isp_mboxcmd(isp, &mbs, MBLOGNONE); if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { if (fcp->isp_loopstate == LOOP_SCANNING_FABRIC) { @@ -2268,8 +2318,10 @@ isp_register_fc4_type(struct ispsoftc *isp) reqp = (sns_screq_t *) fcp->isp_scratch; MEMZERO((void *) reqp, SNS_RFT_REQ_SIZE); reqp->snscb_rblen = SNS_RFT_RESP_SIZE >> 1; - reqp->snscb_addr[RQRSP_ADDR0015] = DMA_LSW(fcp->isp_scdma + 0x100); - reqp->snscb_addr[RQRSP_ADDR1631] = DMA_MSW(fcp->isp_scdma + 0x100); + reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100); + reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100); + reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100); + reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100); reqp->snscb_sblen = 22; reqp->snscb_data[0] = SNS_RFT; reqp->snscb_data[4] = fcp->isp_portid & 0xffff; @@ -2281,10 +2333,13 @@ isp_register_fc4_type(struct ispsoftc *isp) ISP_SWIZZLE_SNS_REQ(isp, reqp); mbs.param[0] = MBOX_SEND_SNS; mbs.param[1] = SNS_RFT_REQ_SIZE >> 1; - mbs.param[2] = DMA_MSW(fcp->isp_scdma); - mbs.param[3] = DMA_LSW(fcp->isp_scdma); - mbs.param[6] = 0; - mbs.param[7] = 0; + mbs.param[2] = DMA_WD1(fcp->isp_scdma); + mbs.param[3] = DMA_WD0(fcp->isp_scdma); + /* + * Leave 4 and 5 alone + */ + mbs.param[6] = DMA_WD3(fcp->isp_scdma); + mbs.param[7] = DMA_WD2(fcp->isp_scdma); isp_mboxcmd(isp, &mbs, MBLOGALL); if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { isp_prt(isp, ISP_LOGDEBUG0, "Register FC4 types succeeded"); @@ -2603,12 +2658,12 @@ isp_start(XS_T *xs) } else { /* * If we don't know what tag to use, use HEAD OF QUEUE - * for Request Sense or Ordered (for safety's sake). + * for Request Sense or Simple. */ if (XS_CDBP(xs)[0] == 0x3) /* REQUEST SENSE */ t2reqp->req_flags = REQFLAG_HTAG; else - t2reqp->req_flags = REQFLAG_OTAG; + t2reqp->req_flags = REQFLAG_STAG; } } else { sdparam *sdp = (sdparam *)isp->isp_param; @@ -2865,65 +2920,18 @@ isp_control(struct ispsoftc *isp, ispctl_t ctl, void *arg) */ #define MAX_REQUESTQ_COMPLETIONS 32 -int -isp_intr(void *arg) +void +isp_intr(struct ispsoftc *isp, u_int16_t isr, u_int16_t sema, u_int16_t mbox) { - struct ispsoftc *isp = arg; XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs; - u_int16_t iptr, optr, isr, sema, junk; + u_int16_t iptr, optr, junk; int i, nlooked = 0, ndone = 0; - if (IS_2100(isp)) { - i = 0; - do { - isr = ISP_READ(isp, BIU_ISR); - junk = ISP_READ(isp, BIU_ISR); - } while (isr != junk && ++i < 1000); - if (isr != junk) { - isp_prt(isp, ISP_LOGWARN, - "isr unsteady (%x, %x)", isr, junk); - } - i = 0; - do { - sema = ISP_READ(isp, BIU_SEMA); - junk = ISP_READ(isp, BIU_SEMA); - } while (sema != junk && ++i < 1000); - if (sema != junk) { - isp_prt(isp, ISP_LOGWARN, - "sema unsteady (%x, %x)", sema, junk); - } - } else { - isr = ISP_READ(isp, BIU_ISR); - sema = ISP_READ(isp, BIU_SEMA); - } - isp_prt(isp, ISP_LOGDEBUG3, "isp_intr isr %x sem %x", isr, sema); - isr &= INT_PENDING_MASK(isp); - sema &= BIU_SEMA_LOCK; - isp->isp_intcnt++; - if (isr == 0 && sema == 0) { - isp->isp_intbogus++; - return (0); - } - + /* + * Is this a mailbox related interrupt? + * The mailbox semaphore will be nonzero if so. + */ if (sema) { - u_int16_t mbox; - - if (IS_2100(isp)) { - i = 0; - do { - mbox = ISP_READ(isp, OUTMAILBOX0); - junk = ISP_READ(isp, OUTMAILBOX0);; - } while (junk != mbox && ++i < 1000); - if (mbox != junk) { - isp_prt(isp, ISP_LOGWARN, - "mailbox0 unsteady (%x, %x)", mbox, junk); - ISP_WRITE(isp, BIU_SEMA, 0); - ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); - return (1); - } - } else { - mbox = ISP_READ(isp, OUTMAILBOX0); - } if (mbox & 0x4000) { int obits, i = 0; if ((obits = isp->isp_mboxbsy) != 0) { @@ -2949,9 +2957,9 @@ isp_intr(void *arg) } } if (IS_FC(isp) || isp->isp_state != ISP_RUNSTATE) { - ISP_WRITE(isp, BIU_SEMA, 0); ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); - return (1); + ISP_WRITE(isp, BIU_SEMA, 0); + return; } } @@ -2960,41 +2968,55 @@ isp_intr(void *arg) */ if (isp->isp_state != ISP_RUNSTATE) { isp_prt(isp, ISP_LOGWARN, - "interrupt (isr=%x, sema=%x) when not ready", isr, sema); - WRITE_RESPONSE_QUEUE_IN_POINTER(isp, - READ_RESPONSE_QUEUE_OUT_POINTER(isp)); + "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema); + /* + * Thank you very much! *Burrrp*! + */ + WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, + READ_RESPONSE_QUEUE_IN_POINTER(isp)); + ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); ISP_WRITE(isp, BIU_SEMA, 0); - return (1); + return; } /* - * You *must* read the Response Queue Out Pointer - * prior to clearing the RISC interrupt. + * Get the current Response Queue Out Pointer. + * + * If we're a 2300, we can ask what hardware what it thinks. */ - optr = isp->isp_residx; + if (IS_2300(isp)) { + optr = ISP_READ(isp, isp->isp_respoutrp); + if (isp->isp_residx != optr) { + isp_prt(isp, ISP_LOGWARN, "optr %x soft optr %x", + optr, isp->isp_residx); + } + } else { + optr = isp->isp_residx; + } - if (IS_2100(isp)) { + /* + * You *must* read the Response Queue In Pointer + * prior to clearing the RISC interrupt. + */ + if (IS_2100(isp) || IS_2300(isp)) { i = 0; do { - iptr = READ_RESPONSE_QUEUE_OUT_POINTER(isp); - junk = READ_RESPONSE_QUEUE_OUT_POINTER(isp); + iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp); + junk = READ_RESPONSE_QUEUE_IN_POINTER(isp); } while (junk != iptr && ++i < 1000); if (iptr != junk) { ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); isp_prt(isp, ISP_LOGWARN, - "mailbox5 unsteady (%x, %x)", iptr, junk); - return (1); + "Response Queue Out Pointer Unstable (%x, %x)", + iptr, junk); + return; } } else { - iptr = READ_RESPONSE_QUEUE_OUT_POINTER(isp); + iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp); } - if (sema) { - ISP_WRITE(isp, BIU_SEMA, 0); - } - ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); if (optr == iptr && sema == 0) { /* @@ -3005,12 +3027,22 @@ isp_intr(void *arg) * make sure the old interrupt went away (to avoid 'ringing' * effects), but that didn't stop this from occurring. */ - junk = ISP_READ(isp, BIU_ISR); - isp_prt(isp, ISP_LOGDEBUG2, - "bogus intr- isr %x (%x) iptr %x optr %x", - isr, junk, iptr, optr); - isp->isp_intbogus++; + if (IS_2300(isp)) { + USEC_DELAY(100); + iptr = READ_RESPONSE_QUEUE_IN_POINTER(isp); + junk = ISP_READ(isp, BIU_R2HSTSLO); + } else { + junk = ISP_READ(isp, BIU_ISR); + } + if (optr == iptr) { + isp_prt(isp, ISP_LOGDEBUG0, + "bogus intr- isr %x (%x) iptr %x optr %x", + isr, junk, iptr, optr); + isp->isp_intbogus++; + } } + ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT); + ISP_WRITE(isp, BIU_SEMA, 0); while (optr != iptr) { ispstatusreq_t *sp; @@ -3057,7 +3089,7 @@ isp_intr(void *arg) if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) { isp_prt(isp, ISP_LOGWARN, "continuation segment"); - WRITE_RESPONSE_QUEUE_IN_POINTER(isp, optr); + WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr); continue; } if (sp->req_header.rqs_flags & RQSFLAG_FULL) { @@ -3089,7 +3121,7 @@ isp_intr(void *arg) "bad request handle %d (type 0x%x, flags 0x%x)", sp->req_handle, sp->req_header.rqs_entry_type, sp->req_header.rqs_flags); - WRITE_RESPONSE_QUEUE_IN_POINTER(isp, optr); + WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr); continue; } xs = isp_find_xs(isp, sp->req_handle); @@ -3098,7 +3130,7 @@ isp_intr(void *arg) isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x in xflist", sp->req_handle); - WRITE_RESPONSE_QUEUE_IN_POINTER(isp, optr); + WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr); continue; } isp_destroy_handle(isp, sp->req_handle); @@ -3233,7 +3265,10 @@ isp_intr(void *arg) * ISP's notion of what we've seen so far. */ if (nlooked) { - WRITE_RESPONSE_QUEUE_IN_POINTER(isp, optr); + WRITE_RESPONSE_QUEUE_OUT_POINTER(isp, optr); + /* + * While we're at it, reqad the requst queue out pointer. + */ isp->isp_reqodx = READ_REQUEST_QUEUE_OUT_POINTER(isp); } @@ -3244,7 +3279,6 @@ isp_intr(void *arg) isp_done(xs); } } - return (1); } /* |
