Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic remove check for idle status when disabling EDMA, ...
details: https://anonhg.NetBSD.org/src/rev/944ed3b93bc9
branches: trunk
changeset: 466460:944ed3b93bc9
user: jdolecek <jdolecek%NetBSD.org@localhost>
date: Sun Dec 22 20:54:00 2019 +0000
description:
remove check for idle status when disabling EDMA, and always toggle
the disable regardless of current state - this particularly seems
to fail during error recovery, and on my system this also fails
during regular boot
this matches both FreeBSD and Linux drivers - neither of those checks
the idle status
should help with PR kern/52419 and maybe also the lock spinout part
of PR kern/52126
diffstat:
sys/dev/ic/mvsata.c | 64 +++++++++++++++++-----------------------------------
1 files changed, 21 insertions(+), 43 deletions(-)
diffs (100 lines):
diff -r 05f515460a29 -r 944ed3b93bc9 sys/dev/ic/mvsata.c
--- a/sys/dev/ic/mvsata.c Sun Dec 22 19:47:34 2019 +0000
+++ b/sys/dev/ic/mvsata.c Sun Dec 22 20:54:00 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mvsata.c,v 1.49 2019/11/10 21:16:35 chs Exp $ */
+/* $NetBSD: mvsata.c,v 1.50 2019/12/22 20:54:00 jdolecek Exp $ */
/*
* Copyright (c) 2008 KIYOHARA Takashi
* All rights reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.49 2019/11/10 21:16:35 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.50 2019/12/22 20:54:00 jdolecek Exp $");
#include "opt_mvsata.h"
@@ -198,7 +198,7 @@
#ifndef MVSATA_WITHOUTDMA
static void mvsata_edma_reset_qptr(struct mvsata_port *);
static inline void mvsata_edma_enable(struct mvsata_port *);
-static int mvsata_edma_disable(struct mvsata_port *, int, int);
+static void mvsata_edma_disable(struct mvsata_port *, int, int);
static void mvsata_edma_config(struct mvsata_port *, enum mvsata_edmamode);
static void mvsata_edma_setup_crqb(struct mvsata_port *, int,
@@ -3425,54 +3425,32 @@
MVSATA_EDMA_WRITE_4(mvport, EDMA_CMD, EDMA_CMD_EENEDMA);
}
-static int
+static void
mvsata_edma_disable(struct mvsata_port *mvport, int timeout, int wflags)
{
struct ata_channel *chp = &mvport->port_ata_channel;
- uint32_t status, command;
- uint32_t idlestatus = EDMA_S_EDMAIDLE | EDMA_S_ECACHEEMPTY;
+ uint32_t command;
int t;
ata_channel_lock_owned(chp);
- if (MVSATA_EDMA_READ_4(mvport, EDMA_CMD) & EDMA_CMD_EENEDMA) {
-
- timeout = mstohz(timeout + hztoms(1) - 1);
-
- for (t = 0; ; ++t) {
- status = MVSATA_EDMA_READ_4(mvport, EDMA_S);
- if ((status & idlestatus) == idlestatus)
- break;
- if (t >= timeout)
- break;
- ata_delay(chp, hztoms(1), "mvsata_edma1", wflags);
- }
- if (t >= timeout) {
- aprint_error("%s:%d:%d: unable to stop EDMA\n",
- device_xname(MVSATA_DEV2(mvport)),
- mvport->port_hc->hc, mvport->port);
- return EBUSY;
- }
-
- /* The disable bit (eDsEDMA) is self negated. */
- MVSATA_EDMA_WRITE_4(mvport, EDMA_CMD, EDMA_CMD_EDSEDMA);
-
- for (t = 0; ; ++t) {
- command = MVSATA_EDMA_READ_4(mvport, EDMA_CMD);
- if (!(command & EDMA_CMD_EENEDMA))
- break;
- if (t >= timeout)
- break;
- ata_delay(chp, hztoms(1), "mvsata_edma2", wflags);
- }
- if (t >= timeout) {
- aprint_error("%s:%d:%d: unable to re-enable EDMA\n",
- device_xname(MVSATA_DEV2(mvport)),
- mvport->port_hc->hc, mvport->port);
- return EBUSY;
- }
+ /* The disable bit (eDsEDMA) is self negated. */
+ MVSATA_EDMA_WRITE_4(mvport, EDMA_CMD, EDMA_CMD_EDSEDMA);
+
+ timeout = mstohz(timeout + hztoms(1) - 1);
+
+ for (t = 0; ; ++t) {
+ command = MVSATA_EDMA_READ_4(mvport, EDMA_CMD);
+ if (!(command & EDMA_CMD_EENEDMA))
+ return;
+ if (t >= timeout)
+ break;
+ ata_delay(chp, hztoms(1), "mvsata_edma2", wflags);
}
- return 0;
+
+ aprint_error("%s:%d:%d: unable to disable EDMA\n",
+ device_xname(MVSATA_DEV2(mvport)),
+ mvport->port_hc->hc, mvport->port);
}
/*
Home |
Main Index |
Thread Index |
Old Index