Subject: Re: kern/28255: pciide UDMA mode immediately downgraded to PIO on CRC error
To: None <tsutsui@ceres.dti.ne.jp>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: netbsd-bugs
Date: 12/05/2004 18:50:44
--6c2NcOVqGQ03X4Wi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Fri, Nov 12, 2004 at 03:20:01PM +0000, tsutsui@ceres.dti.ne.jp wrote:
> [...]
> >Fix:
> sys/dev/ata/ata_wdc.c:wdc_ata_bio_intr() checks ata_bio->r_error
> (which contains value of the error register), but the member is updated
> only on ata_bio->error == ERROR case and is not cleared on each
> transfer. Once a CRC error occurs and ata_bio->r_error is set,
> it still contains the error code even after the next transfers,
> so ata_dmaerr() is called repeatedly and then transfer mode
> is downgraded to PIO.
> 
> Index: ata_wdc.c
> ===================================================================
> RCS file: /cvsroot/src/sys/dev/ata/ata_wdc.c,v
> retrieving revision 1.76
> diff -u -r1.76 ata_wdc.c
> --- ata_wdc.c	28 Oct 2004 07:07:39 -0000	1.76
> +++ ata_wdc.c	12 Nov 2004 14:43:36 -0000
> @@ -612,8 +612,10 @@
>  				drv_err = WDC_ATA_ERR;
>  			}
>  		}
> -		if (ata_bio->r_error & WDCE_CRC)
> -			ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0);
> +		if (ata_bio->error == ERROR &&
> +		    (ata_bio->r_error & WDCE_CRC) != 0)
> +			ata_dmaerr(drvp,
> +			    (xfer->c_flags & C_POLL) ? AT_POLL : 0);
>  		if (drv_err != WDC_ATA_ERR)
>  			goto end;
>  	}

Hi,
the attached patch should be enouth, and avoid another if() in the critical
path. Can you test it ?

-- 
Manuel Bouyer <bouyer@antioche.eu.org>
     NetBSD: 26 ans d'experience feront toujours la difference
--

--6c2NcOVqGQ03X4Wi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff

Index: sys/dev/ata/ata_wdc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/ata_wdc.c,v
retrieving revision 1.76
diff -u -r1.76 ata_wdc.c
--- sys/dev/ata/ata_wdc.c	28 Oct 2004 07:07:39 -0000	1.76
+++ sys/dev/ata/ata_wdc.c	5 Dec 2004 17:49:00 -0000
@@ -612,10 +612,10 @@
 				drv_err = WDC_ATA_ERR;
 			}
 		}
-		if (ata_bio->r_error & WDCE_CRC)
-			ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0);
 		if (drv_err != WDC_ATA_ERR)
 			goto end;
+		if (ata_bio->r_error & WDCE_CRC)
+			ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0);
 	}
 
 	/* if we had an error, end */

--6c2NcOVqGQ03X4Wi--