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