summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp/isp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/isp/isp.c')
-rw-r--r--sys/dev/isp/isp.c51
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;
}
OpenPOWER on IntegriCloud