Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ata only call drive reset with AT_POLL when the comm...



details:   https://anonhg.NetBSD.org/src/rev/097a58848856
branches:  trunk
changeset: 827104:097a58848856
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Sat Oct 14 13:15:14 2017 +0000

description:
only call drive reset with AT_POLL when the command itself was
polled, so that the logic for AT_POLL matches how e.g. ata_dmaerr() is
called; this was the original intent of the change in 1.428.2.25,
to make the error handling safe wrt. polled xfers

this is stopgap fix for ATA channel wedge after DMA error, as reported
by Martin Husemann in PR kern/52606, and PR kern/52605

problem happened due to ata_reset_channel() being called once in ata_dmaerr()
with flags == 0, which freezed channel and set flag to reset via thread,
then ata_reset_channel() was called via wdc_drive_reset() with AT_POLL, which
just executed the reset and cleared the flag, without clearing the extra
freeze; that logic will be refactored in separate commit

diffstat:

 sys/dev/ata/wd.c |  10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diffs (31 lines):

diff -r 4094090fd750 -r 097a58848856 sys/dev/ata/wd.c
--- a/sys/dev/ata/wd.c  Sat Oct 14 08:22:38 2017 +0000
+++ b/sys/dev/ata/wd.c  Sat Oct 14 13:15:14 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wd.c,v 1.430 2017/10/07 16:05:32 jdolecek Exp $ */
+/*     $NetBSD: wd.c,v 1.431 2017/10/14 13:15:14 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.430 2017/10/07 16:05:32 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.431 2017/10/14 13:15:14 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wd.h"
@@ -829,8 +829,10 @@
                errmsg = "error";
                do_perror = 1;
 retry:         /* Just reset and retry. Can we do more ? */
-               if ((xfer->c_flags & C_RECOVERED) == 0)
-                       (*wd->atabus->ata_reset_drive)(wd->drvp, AT_POLL, NULL);
+               if ((xfer->c_flags & C_RECOVERED) == 0) {
+                       int wflags = (xfer->c_flags & C_POLL) ? AT_POLL : 0;
+                       (*wd->atabus->ata_reset_drive)(wd->drvp, wflags, NULL);
+               }
 retry2:
                mutex_enter(&wd->sc_lock);
 



Home | Main Index | Thread Index | Old Index