diff options
author | marius <marius@FreeBSD.org> | 2008-09-18 19:45:22 +0000 |
---|---|---|
committer | marius <marius@FreeBSD.org> | 2008-09-18 19:45:22 +0000 |
commit | 39a04d946716bd76d27a6ff0327358542eec7caf (patch) | |
tree | 09bb7f66ef5d8b73472bf4fd05f7c148e974be8e /sys/sparc64/pci | |
parent | f6aef556aed56108b3f5d7d9ebd749b8c1c6c0a6 (diff) | |
download | FreeBSD-src-39a04d946716bd76d27a6ff0327358542eec7caf.zip FreeBSD-src-39a04d946716bd76d27a6ff0327358542eec7caf.tar.gz |
Clear any possibly pending PCI error bits left by the firmware. These
could trigger an error interrupt that we can't actually to do anything
against as soon as enabling the error handlers.
While at it don't bother about writing only to the write-one-to-clear
bits when clearing error bits.
Diffstat (limited to 'sys/sparc64/pci')
-rw-r--r-- | sys/sparc64/pci/psycho.c | 112 | ||||
-rw-r--r-- | sys/sparc64/pci/psychoreg.h | 8 |
2 files changed, 56 insertions, 64 deletions
diff --git a/sys/sparc64/pci/psycho.c b/sys/sparc64/pci/psycho.c index 4f027ae..d961191 100644 --- a/sys/sparc64/pci/psycho.c +++ b/sys/sparc64/pci/psycho.c @@ -369,9 +369,6 @@ psycho_attach(device_t dev) sc->sc_mtx = osc->sc_mtx; } - /* Clear PCI AFSR. */ - PCICTL_WRITE8(sc, PCR_AFS, PCIAFSR_ERRMASK); - csr = PSYCHO_READ8(sc, PSR_CS); ver = PSYCHO_GCSR_VERS(csr); sc->sc_ign = 0x1f; /* Hummingbird/Sabre IGN is always 0x1f. */ @@ -425,7 +422,7 @@ psycho_attach(device_t dev) break; } - csr |= PCICTL_SERR | PCICTL_ERRINTEN | PCICTL_ARB_4; + csr |= PCICTL_ERRINTEN | PCICTL_ARB_4; csr &= ~(PCICTL_SBHINTEN | PCICTL_WAKEUPEN); #ifdef PSYCHO_DEBUG device_printf(dev, "PCI CSR 0x%016llx -> 0x%016llx\n", @@ -533,46 +530,7 @@ psycho_attach(device_t dev) "controller for INO %d", __func__, n); } - /* - * Establish handlers for interesting interrupts... - * - * XXX We need to remember these and remove this to support - * hotplug on the UPA/FHC bus. - * - * XXX Not all controllers have these, but installing them - * is better than trying to sort through this mess. - */ - psycho_set_intr(sc, 1, PSR_UE_INT_MAP, psycho_ue, NULL); - psycho_set_intr(sc, 2, PSR_CE_INT_MAP, psycho_ce, NULL); -#ifdef DEBUGGER_ON_POWERFAIL - psycho_set_intr(sc, 3, PSR_POWER_INT_MAP, psycho_powerfail, - NULL); -#else - psycho_set_intr(sc, 3, PSR_POWER_INT_MAP, NULL, - (driver_intr_t *)psycho_powerfail); -#endif - /* Psycho-specific initialization */ if (sc->sc_mode == PSYCHO_MODE_PSYCHO) { - /* - * Hummingbirds/Sabres do not have the following two - * interrupts. - */ - - /* - * The spare hardware interrupt is used for the - * over-temperature interrupt. - */ - psycho_set_intr(sc, 4, PSR_SPARE_INT_MAP, - NULL, psycho_overtemp); -#ifdef PSYCHO_MAP_WAKEUP - /* - * psycho_wakeup() doesn't do anything useful right - * now. - */ - psycho_set_intr(sc, 5, PSR_PWRMGT_INT_MAP, - psycho_wakeup, NULL); -#endif /* PSYCHO_MAP_WAKEUP */ - /* Initialize the counter-timer. */ sparc64_counter_init(device_get_nameunit(dev), rman_get_bustag(sc->sc_mem_res), @@ -612,14 +570,6 @@ psycho_attach(device_t dev) iommu_reset(sc->sc_is); } - /* - * Register a PCI bus error interrupt handler according to which - * half this is. Hummingbird/Sabre don't have a PCI bus B error - * interrupt but they are also only used for PCI bus A. - */ - psycho_set_intr(sc, 0, sc->sc_half == 0 ? PSR_PCIAERR_INT_MAP : - PSR_PCIBERR_INT_MAP, psycho_pci_bus, NULL); - /* Allocate our tags. */ sc->sc_pci_memt = psycho_alloc_bus_tag(sc, PCI_MEMORY_BUS_SPACE); sc->sc_pci_iot = psycho_alloc_bus_tag(sc, PCI_IO_BUS_SPACE); @@ -643,11 +593,61 @@ psycho_attach(device_t dev) prop_array[0], prop_array[1], prop_array[0]); sc->sc_pci_secbus = prop_array[0]; - /* Clear PCI status error bits. */ + /* Clear any pending PCI error bits. */ PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC, - PCIR_STATUS, PCIM_STATUS_PERR | PCIM_STATUS_RMABORT | - PCIM_STATUS_RTABORT | PCIM_STATUS_STABORT | - PCIM_STATUS_PERRREPORT, 2); + PCIR_STATUS, PCIB_READ_CONFIG(dev, sc->sc_pci_secbus, + PCS_DEVICE, PCS_FUNC, PCIR_STATUS, 2), 2); + PCICTL_WRITE8(sc, PCR_CS, PCICTL_READ8(sc, PCR_CS)); + PCICTL_WRITE8(sc, PCR_AFS, PCICTL_READ8(sc, PCR_AFS)); + + if (osc == NULL) { + /* + * Establish handlers for interesting interrupts... + * + * XXX We need to remember these and remove this to support + * hotplug on the UPA/FHC bus. + * + * XXX Not all controllers have these, but installing them + * is better than trying to sort through this mess. + */ + psycho_set_intr(sc, 1, PSR_UE_INT_MAP, psycho_ue, NULL); + psycho_set_intr(sc, 2, PSR_CE_INT_MAP, psycho_ce, NULL); +#ifdef DEBUGGER_ON_POWERFAIL + psycho_set_intr(sc, 3, PSR_POWER_INT_MAP, psycho_powerfail, + NULL); +#else + psycho_set_intr(sc, 3, PSR_POWER_INT_MAP, NULL, + (driver_intr_t *)psycho_powerfail); +#endif + if (sc->sc_mode == PSYCHO_MODE_PSYCHO) { + /* + * Hummingbirds/Sabres do not have the following two + * interrupts. + */ + + /* + * The spare hardware interrupt is used for the + * over-temperature interrupt. + */ + psycho_set_intr(sc, 4, PSR_SPARE_INT_MAP, + NULL, psycho_overtemp); +#ifdef PSYCHO_MAP_WAKEUP + /* + * psycho_wakeup() doesn't do anything useful right + * now. + */ + psycho_set_intr(sc, 5, PSR_PWRMGT_INT_MAP, + psycho_wakeup, NULL); +#endif /* PSYCHO_MAP_WAKEUP */ + } + } + /* + * Register a PCI bus error interrupt handler according to which + * half this is. Hummingbird/Sabre don't have a PCI bus B error + * interrupt but they are also only used for PCI bus A. + */ + psycho_set_intr(sc, 0, sc->sc_half == 0 ? PSR_PCIAERR_INT_MAP : + PSR_PCIBERR_INT_MAP, psycho_pci_bus, NULL); /* * Set the latency timer register as this isn't always done by the @@ -808,7 +808,7 @@ psycho_ce(void *arg) device_printf(sc->sc_dev, "correctable DMA error AFAR %#lx " "AFSR %#lx\n", (u_long)afar, (u_long)afsr); /* Clear the error bits that we caught. */ - PSYCHO_WRITE8(sc, PSR_CE_AFS, afsr & CEAFSR_ERRMASK); + PSYCHO_WRITE8(sc, PSR_CE_AFS, afsr); mtx_unlock_spin(sc->sc_mtx); return (FILTER_HANDLED); } diff --git a/sys/sparc64/pci/psychoreg.h b/sys/sparc64/pci/psychoreg.h index bf7a279..ebd6f12 100644 --- a/sys/sparc64/pci/psychoreg.h +++ b/sys/sparc64/pci/psychoreg.h @@ -265,10 +265,6 @@ #define CEAFSR_P_DRD (1UL << 62) /* Pri. error caused by DVMA read */ #define CEAFSR_P_PIO (1UL << 63) /* Pri. error caused by PIO access */ -#define CEAFSR_ERRMASK \ - (CEAFSR_P_PIO | CEAFSR_P_DRD | CEAFSR_P_DWR | \ - CEAFSR_S_PIO | CEAFSR_S_DRD | CEAFSR_S_DWR) - /* PCI asynchronous fault status register */ #define PCIAFSR_P_MA (1UL << 63) /* Pri. master abort */ #define PCIAFSR_P_TA (1UL << 62) /* Pri. target abort */ @@ -282,10 +278,6 @@ #define PCIAFSR_BLK (1UL << 31) /* failed pri. transfer was block r/w */ #define PCIAFSR_MID (0x3eUL << 25) /* UPA MID causing error transaction */ -#define PCIAFSR_ERRMASK \ - (PCIAFSR_P_MA | PCIAFSR_P_TA | PCIAFSR_P_RTRY | PCIAFSR_P_RERR |\ - PCIAFSR_S_MA | PCIAFSR_S_TA | PCIAFSR_S_RTRY | PCIAFSR_S_RERR) - /* PCI diagnostic register */ #define DIAG_RTRY_DIS 0x0000000000000040 /* dis. retry limit */ #define DIAG_ISYNC_DIS 0x0000000000000020 /* dis. DMA write / int sync */ |