Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci another G5-specific fix - do a 32bit read of the...



details:   https://anonhg.NetBSD.org/src/rev/9277d475ae17
branches:  trunk
changeset: 362244:9277d475ae17
user:      macallan <macallan%NetBSD.org@localhost>
date:      Fri Jun 01 16:12:01 2018 +0000

description:
another G5-specific fix - do a 32bit read of the status register before
checking for channel interrupts. No more interrupt storms.
Adapted from FreeBSD

diffstat:

 sys/dev/pci/svwsata.c |  61 +++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 57 insertions(+), 4 deletions(-)

diffs (106 lines):

diff -r 1cebc00d93c7 -r 9277d475ae17 sys/dev/pci/svwsata.c
--- a/sys/dev/pci/svwsata.c     Fri Jun 01 13:42:14 2018 +0000
+++ b/sys/dev/pci/svwsata.c     Fri Jun 01 16:12:01 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: svwsata.c,v 1.20 2017/10/07 16:05:33 jdolecek Exp $    */
+/*     $NetBSD: svwsata.c,v 1.21 2018/06/01 16:12:01 macallan Exp $    */
 
 /*
  * Copyright (c) 2005 Mark Kettenis
@@ -17,7 +17,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: svwsata.c,v 1.20 2017/10/07 16:05:33 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: svwsata.c,v 1.21 2018/06/01 16:12:01 macallan Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -39,6 +39,7 @@
 static void svwsata_mapreg_dma(struct pciide_softc *,
     const struct pci_attach_args *);
 static void svwsata_mapchan(struct pciide_channel *);
+int svwsata_intr(void *);
 
 CFATTACH_DECL_NEW(svwsata, sizeof(struct pciide_softc),
     svwsata_match, svwsata_attach, pciide_detach, NULL);
@@ -161,7 +162,7 @@
        }
        intrstr = pci_intr_string(pa->pa_pc, intrhandle, intrbuf, sizeof(intrbuf));
        sc->sc_pci_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO,
-           pciide_pci_intr, sc);
+           svwsata_intr, sc);
        if (sc->sc_pci_ih != NULL) {
                aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev,
                    "using %s for native-PCI interrupt\n",
@@ -178,7 +179,6 @@
        interface = PCIIDE_INTERFACE_BUS_MASTER_DMA |
            PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
 
-
        for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels;
             channel++) {
                cp = &sc->pciide_channels[channel];
@@ -322,9 +322,62 @@
        bus_space_write_4(sc->sc_ba5_st, sc->sc_ba5_sh,
            (wdc_cp->ch_channel << 8) + SVWSATA_SIM, 0);
 
+#ifndef notyet
+       cp->ata_channel.ch_flags |= ATACH_DMA_BEFORE_CMD;
+#endif
        wdcattach(wdc_cp);
        return;
 
  bad:
        cp->ata_channel.ch_flags |= ATACH_DISABLED;
 }
+
+int
+svwsata_intr(void *arg)
+{
+       struct pciide_softc *sc = arg;
+       struct pciide_channel *cp;
+       struct ata_channel *wdc_cp;
+       struct wdc_regs *wdr;
+       int i, rv, crv;
+       uint8_t dmastat;
+
+       rv = 0;
+       for (i = 0; i < sc->sc_wdcdev.sc_atac.atac_nchannels; i++) {
+               volatile uint32_t status;
+               cp = &sc->pciide_channels[i];
+               wdc_cp = &cp->ata_channel;
+               wdr = CHAN_TO_WDC_REGS(wdc_cp);
+
+               /*
+                * from FreeBSD's ata-serverworks.c:
+                * We need to do a 4-byte read on the status reg before the
+                * values will report correctly
+                */
+               bus_space_read_4(wdr->cmd_iot,
+                   wdr->cmd_iohs[wd_status], 0);
+               __USE(status);
+
+               dmastat = bus_space_read_1(sc->sc_dma_iot,
+                  cp->dma_iohs[IDEDMA_CTL], 0);
+
+               /* If a compat channel skip. */
+               if (cp->compat)
+                       continue;
+
+               /* if this channel not waiting for intr, skip */
+               if ((wdc_cp->ch_flags & ATACH_IRQ_WAIT) == 0) {
+                       continue;
+               }
+               crv = wdcintr(wdc_cp);
+               if ((crv == 0)) {
+                       bus_space_write_1(sc->sc_dma_iot, 
+                           cp->dma_iohs[IDEDMA_CTL], 0, dmastat);
+               }
+               else if (crv == 1)
+                       rv = 1;         /* claim the intr */
+               else if (rv == 0)       /* crv should be -1 in this case */
+                       rv = crv;       /* if we've done no better, take it */
+       }
+       return (rv);
+}



Home | Main Index | Thread Index | Old Index