diff options
Diffstat (limited to 'sys/dev/isp/isp.c')
-rw-r--r-- | sys/dev/isp/isp.c | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/sys/dev/isp/isp.c b/sys/dev/isp/isp.c index b099a5a..03c7072 100644 --- a/sys/dev/isp/isp.c +++ b/sys/dev/isp/isp.c @@ -4262,7 +4262,7 @@ isp_start(XS_T *xs) return (i); } XS_SETERR(xs, HBA_NOERROR); - isp_prt(isp, ISP_LOGDEBUG2, + isp_prt(isp, ISP_LOGDEBUG0, "START cmd for %d.%d.%d cmd 0x%x datalen %ld", XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), XS_CDBP(xs)[0], (long) XS_XFRLEN(xs)); @@ -4739,7 +4739,7 @@ again: isp_get_hdr(isp, hp, &sp->req_header); etype = sp->req_header.rqs_entry_type; - if (IS_24XX(isp) && etype == RQSTYPE_T7RQS) { + if (IS_24XX(isp) && etype == RQSTYPE_RESPONSE) { isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe; isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp2); @@ -4889,7 +4889,7 @@ again: rlen = 0; snsp = NULL; slen = 0; - if (IS_24XX(isp) && (scsi_status & RQCS_RV) != 0) { + if (IS_24XX(isp) && (scsi_status & (RQCS_RV|RQCS_SV)) != 0) { resp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense; rlen = ((isp24xx_statusreq_t *)sp)->req_response_len; } else if (IS_FC(isp) && (scsi_status & RQCS_RV) != 0) { @@ -4927,8 +4927,8 @@ again: if (resp && rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) { isp_prt(isp, ISP_LOGWARN, - "%d.%d FCP RESPONSE: 0x%x", - XS_TGT(xs), XS_LUN(xs), + "%d.%d.%d FCP RESPONSE: 0x%x", + XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), resp[FCP_RSPNS_CODE_OFFSET]); XS_SETERR(xs, HBA_BOTCH); } @@ -5009,13 +5009,14 @@ again: /* * Free any DMA resources. As a side effect, this may - * also do any cache flushing necessary for data coherence. */ + * 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)) || + ((isp->isp_dblev & ISP_LOGDEBUG0) && ((!XS_NOERR(xs)) || (*XS_STSP(xs) != SCSI_GOOD)))) { char skey; if (req_state_flags & RQSF_GOT_SENSE) { @@ -5897,6 +5898,7 @@ static void isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs, long *rp) { + int ru_marked, sv_marked; switch (sp->req_completion_status) { case RQCS_COMPLETE: if (XS_NOERR(xs)) { @@ -5943,7 +5945,8 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, case RQCS_DATA_OVERRUN: XS_RESID(xs) = sp->req_resid; - isp_prt(isp, ISP_LOGERR, "data overrun for command on %d.%d.%d", + 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)) { XS_SETERR(xs, HBA_DATAOVR); @@ -5968,8 +5971,27 @@ isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, return; case RQCS_DATA_UNDERRUN: - + ru_marked = (sp->req_scsi_status & RQCS_RU) != 0; + /* + * We can get an underrun w/o things being marked + * if we got a non-zero status. + */ + sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0; + if ((ru_marked == 0 && sv_marked == 0) || + (sp->req_resid > XS_XFRLEN(xs))) { + isp_prt(isp, ISP_LOGWARN, bun, XS_TGT(xs), + XS_LUN(xs), XS_XFRLEN(xs), sp->req_resid, + (ru_marked)? "marked" : "not marked"); + if (XS_NOERR(xs)) { + XS_SETERR(xs, HBA_BOTCH); + } + return; + } XS_RESID(xs) = sp->req_resid; + isp_prt(isp, ISP_LOGDEBUG0, + "%d.%d.%d data underrun (%d) for command 0x%x", + XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs), + sp->req_resid, XS_CDBP(xs)[0] & 0xff); if (XS_NOERR(xs)) { XS_SETERR(xs, HBA_NOERROR); } @@ -7412,13 +7434,16 @@ isp_read_nvram_2400(ispsoftc_t *isp) } if (nvram_data[0] != 'I' || nvram_data[1] != 'S' || nvram_data[2] != 'P') { - isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header"); + isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)", + nvram_data[0], nvram_data[1], nvram_data[2]); retval = -1; goto out; } dptr = (uint32_t *) nvram_data; for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) { - csum += dptr[lwrds]; + uint32_t tmp; + ISP_IOXGET_32(isp, &dptr[lwrds], tmp); + csum += tmp; } if (csum != 0) { isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum"); @@ -7517,8 +7542,8 @@ isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp) } } if (tmp & (1U << 31)) { - tmp = ISP_READ(isp, BIU2400_FLASH_DATA); - *rp = tmp; + *rp = ISP_READ(isp, BIU2400_FLASH_DATA); + ISP_SWIZZLE_NVRAM_LONG(isp, rp); } else { *rp = 0xffffffff; } |