From owner-svn-src-all@FreeBSD.ORG Sat Mar 2 00:37:32 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id BD9DE9F1; Sat, 2 Mar 2013 00:37:32 +0000 (UTC) (envelope-from marius@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id AFB331EC0; Sat, 2 Mar 2013 00:37:32 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r220bWta057331; Sat, 2 Mar 2013 00:37:32 GMT (envelope-from marius@svn.freebsd.org) Received: (from marius@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r220bWJg057328; Sat, 2 Mar 2013 00:37:32 GMT (envelope-from marius@svn.freebsd.org) Message-Id: <201303020037.r220bWJg057328@svn.freebsd.org> From: Marius Strobl Date: Sat, 2 Mar 2013 00:37:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r247600 - in head/sys: conf sparc64/pci X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 02 Mar 2013 00:37:32 -0000 Author: marius Date: Sat Mar 2 00:37:31 2013 New Revision: 247600 URL: http://svnweb.freebsd.org/changeset/base/247600 Log: - While Netra X1 generally show no ill effects when registering a power fail interrupt handler, there seems to be either a broken batch of them or a tendency to develop a defect which causes this interrupt to fire inadvertedly. Given that apart from this problem these machines work just fine, add a tunable allowing the setup of the power fail interrupt to be disabled. While at it, remove the DEBUGGER_ON_POWERFAIL compile time option and make that behavior also selectable via the newly added tunable. - Apparently, it's no longer a problem to call shutdown_nice(9) from within an interrupt filter (some other drivers in the tree do the same). So change the power fail interrupt from an handler in order to simplify the code and get rid of a !INTR_MPSAFE handler. - Use NULL instead of 0 for pointers. MFC after: 1 week Modified: head/sys/conf/options.sparc64 head/sys/sparc64/pci/psycho.c Modified: head/sys/conf/options.sparc64 ============================================================================== --- head/sys/conf/options.sparc64 Sat Mar 2 00:21:29 2013 (r247599) +++ head/sys/conf/options.sparc64 Sat Mar 2 00:37:31 2013 (r247600) @@ -23,7 +23,6 @@ PSM_DEBUG opt_psm.h PSM_HOOKRESUME opt_psm.h PSM_RESETAFTERSUSPEND opt_psm.h -DEBUGGER_ON_POWERFAIL opt_psycho.h PSYCHO_DEBUG opt_psycho.h SCHIZO_DEBUG opt_schizo.h Modified: head/sys/sparc64/pci/psycho.c ============================================================================== --- head/sys/sparc64/pci/psycho.c Sat Mar 2 00:21:29 2013 (r247599) +++ head/sys/sparc64/pci/psycho.c Sat Mar 2 00:37:31 2013 (r247600) @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -80,7 +81,7 @@ static const struct psycho_desc *psycho_ const char *); static const struct psycho_desc *psycho_get_desc(device_t); static void psycho_set_intr(struct psycho_softc *, u_int, bus_addr_t, - driver_filter_t, driver_intr_t); + driver_filter_t); static int psycho_find_intrmap(struct psycho_softc *, u_int, bus_addr_t *, bus_addr_t *, u_long *); static void sabre_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, @@ -94,8 +95,9 @@ static void psycho_intr_clear(void *); static driver_filter_t psycho_ue; static driver_filter_t psycho_ce; static driver_filter_t psycho_pci_bus; -static driver_filter_t psycho_powerfail; -static driver_intr_t psycho_overtemp; +static driver_filter_t psycho_powerdebug; +static driver_filter_t psycho_powerdown; +static driver_filter_t psycho_overtemp; #ifdef PSYCHO_MAP_WAKEUP static driver_filter_t psycho_wakeup; #endif @@ -159,9 +161,16 @@ static devclass_t psycho_devclass; DEFINE_CLASS_0(pcib, psycho_driver, psycho_methods, sizeof(struct psycho_softc)); -EARLY_DRIVER_MODULE(psycho, nexus, psycho_driver, psycho_devclass, 0, 0, +EARLY_DRIVER_MODULE(psycho, nexus, psycho_driver, psycho_devclass, NULL, NULL, BUS_PASS_BUS); +static SYSCTL_NODE(_hw, OID_AUTO, psycho, CTLFLAG_RD, 0, "psycho parameters"); + +static u_int psycho_powerfail = 1; +TUNABLE_INT("hw.psycho.powerfail", &psycho_powerfail); +SYSCTL_UINT(_hw_psycho, OID_AUTO, powerfail, CTLFLAG_RDTUN, &psycho_powerfail, + 0, "powerfail action (0: none, 1: shutdown (default), 2: debugger)"); + static SLIST_HEAD(, psycho_softc) psycho_softcs = SLIST_HEAD_INITIALIZER(psycho_softcs); @@ -610,15 +619,20 @@ psycho_attach(device_t dev) * 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_set_intr(sc, 1, PSR_UE_INT_MAP, psycho_ue); + psycho_set_intr(sc, 2, PSR_CE_INT_MAP, psycho_ce); + switch (psycho_powerfail) { + case 0: + break; + case 2: + psycho_set_intr(sc, 3, PSR_POWER_INT_MAP, + psycho_powerdebug); + break; + default: + psycho_set_intr(sc, 3, PSR_POWER_INT_MAP, + psycho_powerdown); + break; + } if (sc->sc_mode == PSYCHO_MODE_PSYCHO) { /* * Hummingbirds/Sabres do not have the following two @@ -630,14 +644,14 @@ psycho_attach(device_t dev) * over-temperature interrupt. */ psycho_set_intr(sc, 4, PSR_SPARE_INT_MAP, - NULL, psycho_overtemp); + 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); + psycho_wakeup); #endif /* PSYCHO_MAP_WAKEUP */ } } @@ -647,7 +661,7 @@ psycho_attach(device_t dev) * 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); + PSR_PCIBERR_INT_MAP, psycho_pci_bus); /* * Set the latency timer register as this isn't always done by the @@ -687,7 +701,7 @@ psycho_attach(device_t dev) static void psycho_set_intr(struct psycho_softc *sc, u_int index, bus_addr_t intrmap, - driver_filter_t filt, driver_intr_t intr) + driver_filter_t handler) { u_long vec; int rid; @@ -708,7 +722,7 @@ psycho_set_intr(struct psycho_softc *sc, INTVEC(PSYCHO_READ8(sc, intrmap)) != vec || intr_vectors[vec].iv_ic != &psycho_ic || bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index], - INTR_TYPE_MISC | INTR_BRIDGE, filt, intr, sc, + INTR_TYPE_MISC | INTR_BRIDGE, handler, NULL, sc, &sc->sc_ihand[index]) != 0) panic("%s: failed to set up interrupt %d", __func__, index); } @@ -837,13 +851,16 @@ psycho_pci_bus(void *arg) } static int -psycho_powerfail(void *arg) +psycho_powerdebug(void *arg __unused) { -#ifdef DEBUGGER_ON_POWERFAIL - struct psycho_softc *sc = arg; kdb_enter(KDB_WHY_POWERFAIL, "powerfail"); -#else + return (FILTER_HANDLED); +} + +static int +psycho_powerdown(void *arg __unused) +{ static int shutdown; /* As the interrupt is cleared we may be called multiple times. */ @@ -851,22 +868,22 @@ psycho_powerfail(void *arg) return (FILTER_HANDLED); shutdown++; printf("Power Failure Detected: Shutting down NOW.\n"); - shutdown_nice(0); -#endif + shutdown_nice(RB_POWEROFF); return (FILTER_HANDLED); } -static void -psycho_overtemp(void *arg) +static int +psycho_overtemp(void *arg __unused) { static int shutdown; /* As the interrupt is cleared we may be called multiple times. */ if (shutdown != 0) - return; + return (FILTER_HANDLED); shutdown++; printf("DANGER: OVER TEMPERATURE detected.\nShutting down NOW.\n"); shutdown_nice(RB_POWEROFF); + return (FILTER_HANDLED); } #ifdef PSYCHO_MAP_WAKEUP