Module Name: src Committed By: jdolecek Date: Sun Aug 13 11:40:25 UTC 2017
Modified Files: src/sys/dev/ata [jdolecek-ncq]: wd.c Log Message: restore the fallback to non-NCQ on retries, do this after WDIORETRIES_SINGLE retries, but only for non-FUA I/O; also only do the ATA_SINGLE fallback when non-FUA this makes sure that bio with ATA_SINGLE is not attempted as NCQ - the ATA_SINGLE I/O is usually done using PIO by drivers which actually support it, and thus are not compatible with DMA-only NCQ To generate a diff of this commit: cvs rdiff -u -r1.428.2.32 -r1.428.2.33 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.428.2.32 src/sys/dev/ata/wd.c:1.428.2.33 --- src/sys/dev/ata/wd.c:1.428.2.32 Sat Aug 12 22:12:04 2017 +++ src/sys/dev/ata/wd.c Sun Aug 13 11:40:25 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.428.2.32 2017/08/12 22:12:04 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.428.2.33 2017/08/13 11:40:25 jdolecek 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.428.2.32 2017/08/12 22:12:04 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.33 2017/08/13 11:40:25 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -720,9 +720,12 @@ wdstart1(struct wd_softc *wd, struct buf /* * If we're retrying, retry in single-sector mode. This will give us * the sector number of the problem, and will eventually allow the - * transfer to succeed. + * transfer to succeed. If FUA is requested, we can't actually + * do this, as ATA_SINGLE is usually executed as PIO transfer by drivers + * which support it, and that isn't compatible with NCQ/FUA. */ - if (xfer->c_retries >= WDIORETRIES_SINGLE) + if (xfer->c_retries >= WDIORETRIES_SINGLE && + (bp->b_flags & B_MEDIA_FUA) == 0) xfer->c_bio.flags = ATA_SINGLE; else xfer->c_bio.flags = 0; @@ -734,10 +737,17 @@ wdstart1(struct wd_softc *wd, struct buf xfer->c_bio.flags |= ATA_LBA48; /* - * If NCQ was negotiated, always use it. Some drives return random - * errors when switching between NCQ and non-NCQ I/O too often. + * If NCQ was negotiated, always use it for the first several attempts. + * Since device cancels all outstanding requests on error, downgrade + * to non-NCQ on retry, so that the retried transfer would not cause + * cascade failure for the other transfers if it fails again. + * If FUA was requested, we can't downgrade, as that would violate + * the semantics - FUA would not be honored. In that case, continue + * retrying with NCQ. */ - if (wd->drvp->drive_flags & ATA_DRIVE_NCQ) { + if (wd->drvp->drive_flags & ATA_DRIVE_NCQ && + (xfer->c_retries < WDIORETRIES_SINGLE || + (bp->b_flags & B_MEDIA_FUA) != 0)) { xfer->c_bio.flags |= ATA_LBA48; xfer->c_flags |= C_NCQ;