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