Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/ic explicitely ignore polled xfers in wdcintr(), so ...



details:   https://anonhg.NetBSD.org/src/rev/84ff538ee983
branches:  trunk
changeset: 827127:84ff538ee983
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Sun Oct 15 18:02:33 2017 +0000

description:
explicitely ignore polled xfers in wdcintr(), so it won't be processed
twice - seems setting WDSD_IBM actually has no effect at least
on some PCI-IDE, and the interrupt ends up being triggered when we release
the channel lock to call c_poll hook

fixes PR kern/52605, and should also fix the 'New panic in wdc_ata_bio_intr'
reported on current-users@

diffstat:

 sys/dev/ic/wdc.c |  16 ++++++++++++++--
 1 files changed, 14 insertions(+), 2 deletions(-)

diffs (43 lines):

diff -r 6cd23ae699b2 -r 84ff538ee983 sys/dev/ic/wdc.c
--- a/sys/dev/ic/wdc.c  Sun Oct 15 15:26:10 2017 +0000
+++ b/sys/dev/ic/wdc.c  Sun Oct 15 18:02:33 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wdc.c,v 1.284 2017/10/07 16:05:32 jdolecek Exp $ */
+/*     $NetBSD: wdc.c,v 1.285 2017/10/15 18:02:33 jdolecek Exp $ */
 
 /*
  * Copyright (c) 1998, 2001, 2003 Manuel Bouyer.  All rights reserved.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.284 2017/10/07 16:05:32 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.285 2017/10/15 18:02:33 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wdc.h"
@@ -882,12 +882,24 @@
        xfer = ata_queue_get_active_xfer(chp);
        if (xfer == NULL) {
                ATADEBUG_PRINT(("wdcintr: inactive controller\n"), DEBUG_INTR);
+ignore:
                /* try to clear the pending interrupt anyway */
                (void)bus_space_read_1(wdr->cmd_iot,
                    wdr->cmd_iohs[wd_status], 0);
                return (0);
        }
 
+       /*
+        * On some controllers (e.g. some PCI-IDE) setting the WDSD_IBM bit
+        * actually has no effect, and interrupt is triggered regardless.
+        * Ignore polled commands here, they are processed separately.
+        */
+       if (ISSET(xfer->c_flags, C_POLL)) {
+               ATADEBUG_PRINT(("%s: polled xfer ignored\n", __func__),
+                   DEBUG_INTR);
+               goto ignore;
+       }
+
        ATADEBUG_PRINT(("wdcintr\n"), DEBUG_INTR);
        KASSERT(xfer != NULL);
 



Home | Main Index | Thread Index | Old Index