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
This commit is contained in:
parent
05aa47e6f6
commit
fd181cba14
@ -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 @@ wddone(device_t self, struct ata_xfer *xfer)
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user