diff options
author | mjacob <mjacob@FreeBSD.org> | 1999-01-10 02:55:10 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 1999-01-10 02:55:10 +0000 |
commit | ff7067b486fe9c2e7a3f425bb8f6fa90ae36230e (patch) | |
tree | 6760200a6a3718898453189c32c742191d1d57ef /sys/dev/isp | |
parent | 418e56ef2d4feebc43484df992f4a335fd725208 (diff) | |
download | FreeBSD-src-ff7067b486fe9c2e7a3f425bb8f6fa90ae36230e.zip FreeBSD-src-ff7067b486fe9c2e7a3f425bb8f6fa90ae36230e.tar.gz |
Add some prototype deadchip detection. Set FIFO bursting (1XX0 only-
it's already on for the 2XX0) and detect the broken 1040A FIFO. Change
bzero to MEMZERO (portability with **nux). Use memcpy for same reason.
Finally detect QUEUE FULL conditions and return this as an error that
will get cam_periph_error to do it's 'tagged openings now XXX' dance.
Diffstat (limited to 'sys/dev/isp')
-rw-r--r-- | sys/dev/isp/isp.c | 136 |
1 files changed, 88 insertions, 48 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index 2e10c87..83df478 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -1,5 +1,5 @@ -/* $Id: $ */ -/* release_12_28_98_A */ +/* $Id: isp.c,v 1.9 1998/12/28 19:22:25 mjacob Exp $ */ +/* release_12_28_98_A+ */ /* * Machine and OS Independent (well, as best as possible) * code for the Qlogic ISP SCSI adapters. @@ -128,7 +128,7 @@ isp_reset(isp) { static char once = 1; mbreg_t mbs; - int loops, i, dodnld = 1; + int loops, i, dodnld = 1, deadchip; char *revname; isp->isp_state = ISP_NILSTATE; @@ -139,16 +139,26 @@ isp_reset(isp) * here. */ isp->isp_dblev = DFLT_DBLEVEL; + deadchip = ISP_READ(isp, HCCR) & HCCR_RESET; + if (deadchip) { + ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); + if (ISP_READ(isp, HCCR) & HCCR_RESET) { + isp_dumpregs(isp, "still reset after release"); + SYS_DELAY(1000); + } else { + deadchip = 1; + } + } + if (isp->isp_type & ISP_HA_FC) { revname = "2100"; } else { sdparam *sdp = isp->isp_param; - - int rev = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK; - switch (rev) { + i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK; + switch (i) { default: PRINTF("%s: unknown chip rev. 0x%x- assuming a 1020\n", - isp->isp_name, rev); + isp->isp_name, i); /* FALLTHROUGH */ case 1: revname = "1020"; @@ -185,16 +195,20 @@ isp_reset(isp) * Try and figure out if we're connected to a differential bus. * You have to pause the RISC processor to read SXP registers. */ - ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE); - i = 100; - while ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) { - SYS_DELAY(20); - if (--i == 0) { - PRINTF("%s: unable to pause RISC processor\n", - isp->isp_name); - i = -1; - break; + if (deadchip == 0) { + ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE); + i = 100; + while ((ISP_READ(isp, HCCR) & HCCR_PAUSE) == 0) { + SYS_DELAY(20); + if (--i == 0) { + isp_dumpregs(isp, + "cannot stop RISC processor"); + i = -1; + break; + } } + } else { + i = 0; } if (i > 0) { if (isp->isp_bustype != ISP_BT_SBUS) { @@ -229,9 +243,10 @@ isp_reset(isp) sdp->isp_clock = 40; } /* - * Restart processor + * Restart processor, if necessary. */ - ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); + if (deadchip == 0) + ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); } /* * Machine dependent clock (if set) overrides @@ -249,7 +264,7 @@ isp_reset(isp) */ ISP_RESET0(isp); - if (once == 1) { + if (once == 1 && deadchip == 0) { once = 0; /* * Get the current running firmware revision out of the @@ -270,6 +285,7 @@ isp_reset(isp) } } + /* * Hit the chip over the head with hammer, * and give the ISP a chance to recover. @@ -337,9 +353,21 @@ isp_reset(isp) ISP_WRITE(isp, HCCR, HCCR_CMD_RESET); SYS_DELAY(100); + /* + * Establish some initial burst rate thingies + * (only for the 1XX0 boards). This really should + * be done later after fetching from NVRAM. + */ if (isp->isp_type & ISP_HA_SCSI) { - ISP_SETBITS(isp, BIU_CONF1, isp->isp_mdvec->dv_conf1); - if (isp->isp_mdvec->dv_conf1 & BIU_BURST_ENABLE) { + u_int16_t conf1 = isp->isp_mdvec->dv_conf1; + /* + * Busted FIFO. Turn off all but burst enables. + */ + if (isp->isp_type == ISP_HA_SCSI_1040A) { + conf1 &= BIU_BURST_ENABLE; + } + ISP_SETBITS(isp, BIU_CONF1, conf1); + if (conf1 & BIU_BURST_ENABLE) { ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST); ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST); } @@ -737,7 +765,7 @@ isp_fibre_init(isp) icbp = (isp_icb_t *) fcp->isp_scratch; - bzero(icbp, sizeof (*icbp)); + MEMZERO(icbp, sizeof (*icbp)); icbp->icb_version = ICB_VERSION1; #ifdef ISP_TARGET_MODE @@ -936,7 +964,7 @@ ispscsicmd(xs) u_int8_t niptr; ispmarkreq_t *marker = (ispmarkreq_t *) reqp; - bzero((void *) marker, sizeof (*marker)); + MEMZERO((void *) marker, sizeof (*marker)); marker->req_header.rqs_entry_count = 1; marker->req_header.rqs_entry_type = RQSTYPE_MARKER; marker->req_modifier = SYNC_ALL; @@ -963,7 +991,7 @@ ispscsicmd(xs) iptr = niptr; } - bzero((void *) reqp, UZSIZE); + MEMZERO((void *) reqp, UZSIZE); reqp->req_header.rqs_entry_count = 1; if (isp->isp_type & ISP_HA_FC) { reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS; @@ -1030,7 +1058,7 @@ ispscsicmd(xs) #endif } - bcopy((void *)XS_CDBP(xs), reqp->req_cdb, XS_CDBLEN(xs)); + memcpy(reqp->req_cdb, XS_CDBP(xs), XS_CDBLEN(xs)); IDPRINTF(5, ("%s(%d.%d): START%d cmd 0x%x datalen %d\n", isp->isp_name, XS_TGT(xs), XS_LUN(xs), reqp->req_header.rqs_seqno, @@ -1291,14 +1319,14 @@ isp_intr(arg) XS_STS(xs) = sp->req_scsi_status & 0xff; if (isp->isp_type & ISP_HA_SCSI) { if (sp->req_state_flags & RQSF_GOT_SENSE) { - bcopy(sp->req_sense_data, XS_SNSP(xs), + memcpy(XS_SNSP(xs), sp->req_sense_data, XS_SNSLEN(xs)); XS_SNS_IS_VALID(xs); } } else { if (XS_STS(xs) == SCSI_CHECK) { XS_SNS_IS_VALID(xs); - bcopy(sp->req_sense_data, XS_SNSP(xs), + memcpy(XS_SNSP(xs), sp->req_sense_data, XS_SNSLEN(xs)); sp->req_state_flags |= RQSF_GOT_SENSE; } @@ -1318,8 +1346,9 @@ isp_intr(arg) } else { PRINTF("%s: unknown return %x\n", isp->isp_name, sp->req_header.rqs_entry_type); - if (XS_NOERR(xs)) + if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_BOTCH); + } } if (isp->isp_type & ISP_HA_SCSI) { XS_RESID(xs) = sp->req_resid; @@ -1663,7 +1692,7 @@ isp_handle_other_response(isp, sp, optrp) } PRINTF("%s: datalen %d cdb0=0x%x\n", isp->isp_name, at2->req_datalen, at2->req_cdb[0]); - bzero ((void *) ct2, sizeof (*ct2)); + MEMZERO((void *) ct2, sizeof (*ct2)); ct2->req_header.rqs_entry_type = RQSTYPE_CTIO2; ct2->req_header.rqs_entry_count = 1; ct2->req_header.rqs_flags = 0; @@ -1689,10 +1718,10 @@ isp_handle_other_response(isp, sp, optrp) ct2->req_seg_count = 1; if (at2->req_cdb[0] == 0x12) { s = sizeof(tgtiqd); - bcopy((void *)tgtiqd, fcp->isp_scratch, s); + memcpy(fcp->isp_scratch, tgtiqd, s); } else { s = at2->req_datalen; - bzero(fcp->isp_scratch, s); + MEMZERO(fcp->isp_scratch, s); } ct2->req_m.mode0.req_dataseg[0].ds_base = fcp->isp_scdma; @@ -1744,9 +1773,8 @@ isp_handle_other_response(isp, sp, optrp) ct2->req_m.mode1.req_sense_len = 18; ct2->req_m.mode1.req_scsi_status |= at2->req_scsi_status; - bcopy((void *)at2->req_sense, - (void *)ct2->req_m.mode1.req_response, - sizeof (at2->req_sense)); + memcpy(ct2->req_m.mode1.req_response, + at2->req_sense, sizeof (at2->req_sense)); } break; } @@ -1798,7 +1826,7 @@ isp_handle_other_response(isp, sp, optrp) PRINTF("%s: Request Queue Overflow other response\n", isp->isp_name); } else { - bcopy(ireqp, reqp, reqsize); + memcpy(reqp, ireqp, reqsize); ISP_WRITE(isp, INMAILBOX4, iptr); isp->isp_reqidx = iptr; } @@ -1862,7 +1890,7 @@ isp_modify_lun(isp, lun, icnt, ccnt) return (-1); } - bzero((void *) ip, sizeof (*ip)); + MEMZERO((void *) ip, sizeof (*ip)); ip->req_header.rqs_entry_type = RQSTYPE_ENABLE_LUN; ip->req_header.rqs_entry_count = 1; ip->req_header.rqs_seqno = isp->isp_seqno++; @@ -1890,7 +1918,7 @@ isp_notify_ack(isp, ptrp) na_entry_t _nas; } un; - bzero((caddr_t)&un, sizeof (un)); + MEMZERO((caddr_t)&un, sizeof (un)); un._nas.na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK; un._nas.na_header.rqs_entry_count = 1; @@ -1926,7 +1954,7 @@ isp_notify_ack(isp, ptrp) PRINTF("%s: Request Queue Overflow For isp_notify_ack\n", isp->isp_name); } else { - bcopy(ireqp, reqp, sizeof (un)); + memcpy(reqp, ireqp, sizeof (un)); ISP_WRITE(isp, INMAILBOX4, iptr); isp->isp_reqidx = iptr; } @@ -1981,8 +2009,7 @@ isp_handle_atio (isp, aep) if (status & TGTSVALID) { - bcopy((caddr_t) aep->at_sense, - (caddr_t) &cdp->cd_sensedata, + memcpy(&cdp->cd_sensedata, aep->at_sense, sizeof (cdp->cd_sensedata)); PRINTF("%s: Bus Phase Sequence error key 0x%x\n", isp->isp_name, cdp->cd_sensedata[2] & 0xf); @@ -2023,7 +2050,7 @@ isp_handle_atio (isp, aep) cdp->cd_lun = aep->at_lun; cdp->cd_tagtype = aep->at_tag_type; cdp->cd_tagval = aep->at_tag_val; - bcopy(aep->at_cdb, cdp->cd_cdb, 16); + memcpy(cdp->cd_cdb, aep->at_cdb, 16); PRINTF("%s: CDB 0x%x itl %d/%d/%d\n", isp->isp_name, cdp->cd_cdb[0], cdp->cd_iid, cdp->cd_tgt, cdp->cd_lun); (*isp->isp_tmd_newcmd)(isp, cdp); @@ -2099,7 +2126,7 @@ isp_handle_atio2(isp, aep) cdp->cd_iid = aep->at_iid; cdp->cd_tgt = 0; cdp->cd_lun = aep->at_lun; - bcopy(aep->at_cdb, cdp->cd_cdb, 16); + memcpy(cdp->cd_cdb, aep->at_cdb, 16); cdp->cd_rxid = aep->at_rxid; cdp->cp_origdlen = aep->at_datalen; cdp->cp_totbytes = 0; @@ -2296,8 +2323,17 @@ isp_parse_status(isp, sp, xs) break; case RQCS_QUEUE_FULL: - PRINTF("%s: internal queues full for target %d lun %d\n", - isp->isp_name, XS_TGT(xs), XS_LUN(xs)); + PRINTF("%s: internal queues full for target %d lun %d " + "status 0x%x\n", isp->isp_name, XS_TGT(xs), XS_LUN(xs), + XS_STS(xs)); + /* + * If QFULL or some other status byte is set, then this + * isn't an error, per se. + */ + if (XS_STS(xs) != 0) { + XS_SETERR(xs, HBA_NOERROR); + return; + } break; case RQCS_PHASE_SKIPPED: @@ -3196,9 +3232,9 @@ isp_read_nvram(isp) if (isp->isp_type & ISP_HA_SCSI) { sdparam *sdp = (sdparam *) isp->isp_param; - /* XXX CHECK THIS FOR SANITY XXX */ sdp->isp_fifo_threshold = - ISP_NVRAM_FIFO_THRESHOLD(nvram_data); + ISP_NVRAM_FIFO_THRESHOLD(nvram_data) | + (ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2); sdp->isp_initiator_id = ISP_NVRAM_INITIATOR_ID(nvram_data); @@ -3240,8 +3276,6 @@ isp_read_nvram(isp) sdp->isp_tag_aging = ISP_NVRAM_TAG_AGE_LIMIT(nvram_data); - /* XXX ISP_NVRAM_FIFO_THRESHOLD_128 XXX */ - sdp->isp_selection_timeout = ISP_NVRAM_SELECTION_TIMEOUT(nvram_data); @@ -3250,6 +3284,12 @@ isp_read_nvram(isp) sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data); +#if 0 + PRINTF("%s: fifo_threshold = 0x%x cbena%d dbena%d\n", + isp->isp_name, sdp->isp_fifo_threshold, + sdp->isp_cmd_dma_burst_enable, + sdp->isp_data_dma_burst_enabl); +#endif for (i = 0; i < 16; i++) { sdp->isp_devparam[i].dev_enable = ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i); |