Module Name: src Committed By: gson Date: Sun Aug 12 18:39:32 UTC 2012
Modified Files: src/sys/dev/pci: eso.c Log Message: Add missing locking calls to eso_attach() to avoid panic on boot. Partly based on a patch from mrg. Fixes PR kern/46791. To generate a diff of this commit: cvs rdiff -u -r1.60 -r1.61 src/sys/dev/pci/eso.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/eso.c diff -u src/sys/dev/pci/eso.c:1.60 src/sys/dev/pci/eso.c:1.61 --- src/sys/dev/pci/eso.c:1.60 Tue May 15 18:11:28 2012 +++ src/sys/dev/pci/eso.c Sun Aug 12 18:39:32 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: eso.c,v 1.60 2012/05/15 18:11:28 mrg Exp $ */ +/* $NetBSD: eso.c,v 1.61 2012/08/12 18:39:32 gson Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: eso.c,v 1.60 2012/05/15 18:11:28 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: eso.c,v 1.61 2012/08/12 18:39:32 gson Exp $"); #include "mpu.h" @@ -260,13 +260,16 @@ eso_attach(device_t parent, device_t sel pci_intr_handle_t ih; bus_addr_t vcbase; const char *intrstring; - int idx; + int idx, error; uint8_t a2mode, mvctl; sc = device_private(self); pa = aux; aprint_naive(": Audio controller\n"); + mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); + mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO); + sc->sc_revision = PCI_REVISION(pa->pa_class); aprint_normal(": ESS Solo-1 PCI AudioDrive "); if (sc->sc_revision < @@ -314,7 +317,10 @@ eso_attach(device_t parent, device_t sel PCI_COMMAND_MASTER_ENABLE); /* Reset the device; bail out upon failure. */ - if (eso_reset(sc) != 0) { + mutex_spin_enter(&sc->sc_intr_lock); + error = eso_reset(sc); + mutex_spin_exit(&sc->sc_intr_lock); + if (error != 0) { aprint_error_dev(&sc->sc_dev, "can't reset\n"); return; } @@ -329,6 +335,8 @@ eso_attach(device_t parent, device_t sel ESO_IO_IRQCTL_A1IRQ | ESO_IO_IRQCTL_A2IRQ | ESO_IO_IRQCTL_HVIRQ | ESO_IO_IRQCTL_MPUIRQ); + mutex_spin_enter(&sc->sc_intr_lock); + /* Set up A1's sample rate generator for new-style parameters. */ a2mode = eso_read_mixreg(sc, ESO_MIXREG_A2MODE); a2mode |= ESO_MIXREG_A2MODE_NEWA1 | ESO_MIXREG_A2MODE_ASYNC; @@ -373,17 +381,17 @@ eso_attach(device_t parent, device_t sel sc->sc_gain[idx][ESO_LEFT] = sc->sc_gain[idx][ESO_RIGHT] = v; eso_set_gain(sc, idx); } + eso_set_recsrc(sc, ESO_MIXREG_ERS_MIC); + mutex_spin_exit(&sc->sc_intr_lock); + /* Map and establish the interrupt. */ if (pci_intr_map(pa, &ih)) { aprint_error_dev(&sc->sc_dev, "couldn't map interrupt\n"); return; } - mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); - mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO); - intrstring = pci_intr_string(pa->pa_pc, ih); sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, eso_intr, sc); if (sc->sc_ih == NULL) {