summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>2000-07-25 20:40:34 +0000
committergibbs <gibbs@FreeBSD.org>2000-07-25 20:40:34 +0000
commit218edb7befe15334d4053ab8e1621558da5eccb0 (patch)
treebcc29f0a93e1db35d0a5893f10624126184372b6 /sys/dev
parent054be419e85a7a245c93d61488067c0cc308fa50 (diff)
downloadFreeBSD-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.c17
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 {
OpenPOWER on IntegriCloud