Module Name:    src
Committed By:   bouyer
Date:           Tue Jun 26 09:49:25 UTC 2012

Modified Files:
        src/sys/dev/ata: wd.c

Log Message:
In some case, when an error is reported by the disk, the ahci controller
still reports a number of bytes transfered equal to bcount.
This then triggers a KASSERT in physio_biodone:
        if (done == todo)
                KASSERT(bp->b_error == 0);
Detect this case in wd(4) (so that the workaround works for other controllers
too if they have the same issue, or if the issue is with the drive)
and claim we didn't read/write anything.


To generate a diff of this commit:
cvs rdiff -u -r1.392 -r1.393 src/sys/dev/ata/wd.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ata/wd.c
diff -u src/sys/dev/ata/wd.c:1.392 src/sys/dev/ata/wd.c:1.393
--- src/sys/dev/ata/wd.c:1.392	Thu Feb  2 19:43:02 2012
+++ src/sys/dev/ata/wd.c	Tue Jun 26 09:49:24 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.392 2012/02/02 19:43:02 tls Exp $ */
+/*	$NetBSD: wd.c,v 1.393 2012/06/26 09:49:24 bouyer Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.392 2012/02/02 19:43:02 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.393 2012/06/26 09:49:24 bouyer Exp $");
 
 #include "opt_ata.h"
 
@@ -819,6 +819,14 @@ noerror:	if ((wd->sc_wdc_bio.flags & ATA
 		bp->b_error = EIO;
 		break;
 	}
+	if (__predict_false(bp->b_error != 0) && bp->b_resid == 0) {
+		/*
+		 * the disk or controller sometimes report a complete
+		 * xfer, when there has been an error. This is wrong,
+		 * assume nothing got transfered in this case
+		 */
+		bp->b_resid = bp->b_bcount;
+	}
 	disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid),
 	    (bp->b_flags & B_READ));
 	rnd_add_uint32(&wd->rnd_source, bp->b_blkno);

Reply via email to