Disable ppb(4)'s interrupt for a while. It causes hangup on some environment.

Define PPB_USEINTR if you'd like to use interrupt.
This commit is contained in:
msaitoh 2017-04-26 08:00:03 +00:00
parent f029f15347
commit b4bafc1cd0
1 changed files with 26 additions and 2 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ppb.c,v 1.59 2017/04/26 03:54:37 msaitoh Exp $ */ /* $NetBSD: ppb.c,v 1.60 2017/04/26 08:00:03 msaitoh Exp $ */
/* /*
* Copyright (c) 1996, 1998 Christopher G. Demetriou. All rights reserved. * Copyright (c) 1996, 1998 Christopher G. Demetriou. All rights reserved.
@ -31,7 +31,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ppb.c,v 1.59 2017/04/26 03:54:37 msaitoh Exp $"); __KERNEL_RCSID(0, "$NetBSD: ppb.c,v 1.60 2017/04/26 08:00:03 msaitoh Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -60,7 +60,9 @@ static int ppbmatch(device_t, cfdata_t, void *);
static void ppbattach(device_t, device_t, void *); static void ppbattach(device_t, device_t, void *);
static int ppbdetach(device_t, int); static int ppbdetach(device_t, int);
static void ppbchilddet(device_t, device_t); static void ppbchilddet(device_t, device_t);
#ifdef PPB_USEINTR
static int ppb_intr(void *); static int ppb_intr(void *);
#endif
static bool ppb_resume(device_t, const pmf_qual_t *); static bool ppb_resume(device_t, const pmf_qual_t *);
static bool ppb_suspend(device_t, const pmf_qual_t *); static bool ppb_suspend(device_t, const pmf_qual_t *);
@ -203,8 +205,10 @@ ppbattach(device_t parent, device_t self, void *aux)
struct pci_attach_args *pa = aux; struct pci_attach_args *pa = aux;
pci_chipset_tag_t pc = pa->pa_pc; pci_chipset_tag_t pc = pa->pa_pc;
struct pcibus_attach_args pba; struct pcibus_attach_args pba;
#ifdef PPB_USEINTR
char const *intrstr; char const *intrstr;
char intrbuf[PCI_INTRSTR_LEN]; char intrbuf[PCI_INTRSTR_LEN];
#endif
pcireg_t busdata, reg; pcireg_t busdata, reg;
pci_aprint_devinfo(pa, NULL); pci_aprint_devinfo(pa, NULL);
@ -237,6 +241,7 @@ ppbattach(device_t parent, device_t self, void *aux)
/* Check for PCI Express capabilities and setup hotplug support. */ /* Check for PCI Express capabilities and setup hotplug support. */
if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PCIEXPRESS, if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PCIEXPRESS,
&sc->sc_pciecapoff, &reg) && (reg & PCIE_XCAP_SI)) { &sc->sc_pciecapoff, &reg) && (reg & PCIE_XCAP_SI)) {
#ifdef PPB_USEINTR
#if 0 #if 0
/* /*
* XXX Initialize workqueue or something else for * XXX Initialize workqueue or something else for
@ -304,6 +309,17 @@ ppbattach(device_t parent, device_t self, void *aux)
pci_conf_write(pc, pa->pa_tag, pci_conf_write(pc, pa->pa_tag,
sc->sc_pciecapoff + PCIE_SLCSR, slcsr); sc->sc_pciecapoff + PCIE_SLCSR, slcsr);
} }
#else
reg = pci_conf_read(sc->sc_pc, sc->sc_tag,
sc->sc_pciecapoff + PCIE_SLCSR);
if (reg & PCIE_SLCSR_NOTIFY_MASK) {
aprint_debug_dev(self,
"disabling notification events\n");
reg &= ~PCIE_SLCSR_NOTIFY_MASK;
pci_conf_write(sc->sc_pc, sc->sc_tag,
sc->sc_pciecapoff + PCIE_SLCSR, reg);
}
#endif /* PPB_USEINTR */
} }
if (!pmf_device_register(self, ppb_suspend, ppb_resume)) if (!pmf_device_register(self, ppb_suspend, ppb_resume))
@ -327,6 +343,7 @@ ppbattach(device_t parent, device_t self, void *aux)
pba.pba_intrswiz = pa->pa_intrswiz; pba.pba_intrswiz = pa->pa_intrswiz;
pba.pba_intrtag = pa->pa_intrtag; pba.pba_intrtag = pa->pa_intrtag;
#ifdef PPB_USEINTR
/* Attach event counters */ /* Attach event counters */
evcnt_attach_dynamic(&sc->sc_ev_intr, EVCNT_TYPE_INTR, NULL, evcnt_attach_dynamic(&sc->sc_ev_intr, EVCNT_TYPE_INTR, NULL,
device_xname(sc->sc_dev), "Interrupt"); device_xname(sc->sc_dev), "Interrupt");
@ -342,6 +359,7 @@ ppbattach(device_t parent, device_t self, void *aux)
device_xname(sc->sc_dev), "Command Completed"); device_xname(sc->sc_dev), "Command Completed");
evcnt_attach_dynamic(&sc->sc_ev_lacs, EVCNT_TYPE_MISC, NULL, evcnt_attach_dynamic(&sc->sc_ev_lacs, EVCNT_TYPE_MISC, NULL,
device_xname(sc->sc_dev), "Data Link Layer State Changed"); device_xname(sc->sc_dev), "Data Link Layer State Changed");
#endif
config_found_ia(self, "pcibus", &pba, pcibusprint); config_found_ia(self, "pcibus", &pba, pcibusprint);
} }
@ -349,13 +367,16 @@ ppbattach(device_t parent, device_t self, void *aux)
static int static int
ppbdetach(device_t self, int flags) ppbdetach(device_t self, int flags)
{ {
#ifdef PPB_USEINTR
struct ppb_softc *sc = device_private(self); struct ppb_softc *sc = device_private(self);
pcireg_t slcsr; pcireg_t slcsr;
#endif
int rc; int rc;
if ((rc = config_detach_children(self, flags)) != 0) if ((rc = config_detach_children(self, flags)) != 0)
return rc; return rc;
#ifdef PPB_USEINTR
/* Detach event counters */ /* Detach event counters */
evcnt_detach(&sc->sc_ev_intr); evcnt_detach(&sc->sc_ev_intr);
evcnt_detach(&sc->sc_ev_abp); evcnt_detach(&sc->sc_ev_abp);
@ -377,6 +398,7 @@ ppbdetach(device_t self, int flags)
pci_intr_disestablish(sc->sc_pc, sc->sc_intrhand); pci_intr_disestablish(sc->sc_pc, sc->sc_intrhand);
pci_intr_release(sc->sc_pc, sc->sc_pihp, 1); pci_intr_release(sc->sc_pc, sc->sc_pihp, 1);
} }
#endif
pmf_device_deregister(self); pmf_device_deregister(self);
return 0; return 0;
@ -418,6 +440,7 @@ ppbchilddet(device_t self, device_t child)
/* we keep no references to child devices, so do nothing */ /* we keep no references to child devices, so do nothing */
} }
#ifdef PPB_USEINTR
static int static int
ppb_intr(void *arg) ppb_intr(void *arg)
{ {
@ -482,3 +505,4 @@ ppb_intr(void *arg)
return 0; return 0;
} }
#endif /* PPB_USEINTR */