diff options
author | gibbs <gibbs@FreeBSD.org> | 2000-07-25 20:40:34 +0000 |
---|---|---|
committer | gibbs <gibbs@FreeBSD.org> | 2000-07-25 20:40:34 +0000 |
commit | 218edb7befe15334d4053ab8e1621558da5eccb0 (patch) | |
tree | bcc29f0a93e1db35d0a5893f10624126184372b6 /sys/dev | |
parent | 054be419e85a7a245c93d61488067c0cc308fa50 (diff) | |
download | FreeBSD-src-218edb7befe15334d4053ab8e1621558da5eccb0.zip FreeBSD-src-218edb7befe15334d4053ab8e1621558da5eccb0.tar.gz |
Properly handle the case where the residual is 0, but, as the target
didn't bother to send a saved data pointers after the last transfer,
is not recorded in sgptr. This was only a problem if the target
reported non-zero status as we always check the residual in that case.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/sys/dev/aic7xxx/aic7xxx.c b/sys/dev/aic7xxx/aic7xxx.c index 8ac28db..3b9aabf 100644 --- a/sys/dev/aic7xxx/aic7xxx.c +++ b/sys/dev/aic7xxx/aic7xxx.c @@ -7091,31 +7091,38 @@ ahc_calc_residual(struct scb *scb) uint32_t resid; /* - * 4 cases. + * 5 cases. * 1) No residual. * SG_RESID_VALID clear in sgptr. * 2) Transferless command * 3) Never performed any transfers. * sgptr has SG_FULL_RESID set. - * 4) We have a partial residual. + * 4) No residual but target did not + * save data pointers after the + * last transfer, so sgptr was + * never updated. + * 5) We have a partial residual. * Use residual_sgptr to determine * where we are. */ - /* Cases 1, 2 & 3 are easy. Check them first. */ hscb = scb->hscb; if ((hscb->sgptr & SG_RESID_VALID) == 0) + /* Case 1 */ return; hscb->sgptr &= ~SG_RESID_VALID; if ((hscb->sgptr & SG_LIST_NULL) != 0) + /* Case 2 */ return; spkt = &hscb->shared_data.status; if ((hscb->sgptr & SG_FULL_RESID) != 0) + /* Case 3 */ resid = scb->ccb->csio.dxfer_len; - else if ((hscb->sgptr & ~SG_PTR_MASK) != 0) - panic("Bogus sgptr value 0x%x\n", hscb->sgptr); + else if ((spkt->residual_sg_ptr & SG_LIST_NULL) != 0) + /* Case 4 */ + return; else if ((spkt->residual_sg_ptr & ~SG_PTR_MASK) != 0) panic("Bogus resid sgptr value 0x%x\n", spkt->residual_sg_ptr); else { |