From owner-svn-src-head@FreeBSD.ORG Sat Feb 7 01:15:14 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1A3491065670; Sat, 7 Feb 2009 01:15:14 +0000 (UTC) (envelope-from nwhitehorn@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 06A9B8FC1D; Sat, 7 Feb 2009 01:15:14 +0000 (UTC) (envelope-from nwhitehorn@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n171FDVi076559; Sat, 7 Feb 2009 01:15:13 GMT (envelope-from nwhitehorn@svn.freebsd.org) Received: (from nwhitehorn@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n171FD48076553; Sat, 7 Feb 2009 01:15:13 GMT (envelope-from nwhitehorn@svn.freebsd.org) Message-Id: <200902070115.n171FD48076553@svn.freebsd.org> From: Nathan Whitehorn Date: Sat, 7 Feb 2009 01:15:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r188259 - head/sys/dev/sound/macio X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 07 Feb 2009 01:15:14 -0000 Author: nwhitehorn Date: Sat Feb 7 01:15:13 2009 New Revision: 188259 URL: http://svn.freebsd.org/changeset/base/188259 Log: Rearrange this code slightly to pass softcs around instead of device_t, solving a possible panic when snd_ai2s is loaded at boot time. Also change the device setup to indicate to the pcm layer that the device is MPSAFE. Submitted by: Marco Trillo Suggestions by: Ariff Abdullah Modified: head/sys/dev/sound/macio/aoa.c head/sys/dev/sound/macio/aoa.h head/sys/dev/sound/macio/davbus.c head/sys/dev/sound/macio/i2s.c head/sys/dev/sound/macio/snapper.c head/sys/dev/sound/macio/tumbler.c Modified: head/sys/dev/sound/macio/aoa.c ============================================================================== --- head/sys/dev/sound/macio/aoa.c Sat Feb 7 01:12:51 2009 (r188258) +++ head/sys/dev/sound/macio/aoa.c Sat Feb 7 01:15:13 2009 (r188259) @@ -104,13 +104,14 @@ aoa_dma_set_program(struct aoa_dma *dma) #define AOA_BUFFER_SIZE 65536 static struct aoa_dma * -aoa_dma_create(device_t self) +aoa_dma_create(struct aoa_softc *sc) { - struct aoa_softc *sc = pcm_getdevinfo(self); struct aoa_dma *dma; bus_dma_tag_t tag; int err; + device_t self; + self = sc->sc_dev; err = bus_dma_tag_create(bus_get_dma_tag(self), 4, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, AOA_BUFFER_SIZE, 1, AOA_BUFFER_SIZE, 0, NULL, NULL, &tag); @@ -214,14 +215,13 @@ static void * aoa_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { - device_t self = devinfo; - struct aoa_softc *sc = pcm_getdevinfo(self); + struct aoa_softc *sc = devinfo; struct aoa_dma *dma; int max_slots, err; KASSERT(dir == PCMDIR_PLAY, ("bad dir")); - dma = aoa_dma_create(self); + dma = aoa_dma_create(sc); if (!dma) return (NULL); dma->pcm = c; @@ -230,7 +230,7 @@ aoa_chan_init(kobj_t obj, void *devinfo, /* One slot per block, plus branch to 0 plus STOP. */ max_slots = 2 + dma->bufsz / dma->blksz; - err = dbdma_allocate_channel(dma->reg, 0, bus_get_dma_tag(self), + err = dbdma_allocate_channel(dma->reg, 0, bus_get_dma_tag(sc->sc_dev), max_slots, &dma->channel ); if (err != 0) { aoa_dma_delete(dma); @@ -308,9 +308,9 @@ aoa_chan_free(kobj_t obj, void *data) } void -aoa_interrupt(void *arg) +aoa_interrupt(void *xsc) { - struct aoa_softc *sc = arg; + struct aoa_softc *sc = xsc; struct aoa_dma *dma; if (!(dma = sc->sc_intrp) || !dma->running) @@ -357,11 +357,16 @@ static kobj_method_t aoa_chan_methods[] CHANNEL_DECLARE(aoa_chan); int -aoa_attach(device_t self, void *sc) +aoa_attach(void *xsc) { char status[SND_STATUSLEN]; + struct aoa_softc *sc; + device_t self; int err; + sc = xsc; + self = sc->sc_dev; + if (pcm_register(self, sc, 1, 0)) return (ENXIO); @@ -369,7 +374,7 @@ aoa_attach(device_t self, void *sc) AOA_BUFFER_SIZE); DPRINTF(("pcm_getbuffersize returned %d\n", err)); - pcm_addchan(self, PCMDIR_PLAY, &aoa_chan_class, self); + pcm_addchan(self, PCMDIR_PLAY, &aoa_chan_class, sc); snprintf(status, sizeof(status), "at %s", ofw_bus_get_name(self)); pcm_setstatus(self, status); Modified: head/sys/dev/sound/macio/aoa.h ============================================================================== --- head/sys/dev/sound/macio/aoa.h Sat Feb 7 01:12:51 2009 (r188258) +++ head/sys/dev/sound/macio/aoa.h Sat Feb 7 01:15:13 2009 (r188259) @@ -35,12 +35,13 @@ #endif struct aoa_softc { - void *sc_intrp; - struct resource *sc_odma; + device_t sc_dev; + void *sc_intrp; + struct resource *sc_odma; }; void aoa_interrupt(void *); -int aoa_attach(device_t, void *sc); +int aoa_attach(void *xsc); #endif /* SOUND_AOA_H */ Modified: head/sys/dev/sound/macio/davbus.c ============================================================================== --- head/sys/dev/sound/macio/davbus.c Sat Feb 7 01:12:51 2009 (r188258) +++ head/sys/dev/sound/macio/davbus.c Sat Feb 7 01:15:13 2009 (r188259) @@ -52,7 +52,6 @@ struct davbus_softc { struct aoa_softc aoa; - device_t dev; phandle_t node; phandle_t soundnode; struct resource *reg; @@ -497,7 +496,7 @@ davbus_attach(device_t self) sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); - sc->dev = self; + sc->aoa.sc_dev = self; sc->node = ofw_bus_get_node(self); sc->soundnode = OF_child(sc->node); @@ -529,8 +528,8 @@ davbus_attach(device_t self) if (err != 0) return (err); - bus_setup_intr(self, dbdma_irq, INTR_TYPE_AV | INTR_MPSAFE, - NULL, aoa_interrupt, sc, &cookie); + snd_setup_intr(self, dbdma_irq, INTR_MPSAFE, aoa_interrupt, + sc, &cookie); /* Now initialize the controller. */ @@ -555,7 +554,7 @@ davbus_attach(device_t self) DAVBUS_OUTPUT_SUBFRAME0 | DAVBUS_RATE_44100 | DAVBUS_INTR_PORTCHG); /* Attach DBDMA engine and PCM layer */ - err = aoa_attach(self,sc); + err = aoa_attach(sc); if (err) return (err); Modified: head/sys/dev/sound/macio/i2s.c ============================================================================== --- head/sys/dev/sound/macio/i2s.c Sat Feb 7 01:12:51 2009 (r188258) +++ head/sys/dev/sound/macio/i2s.c Sat Feb 7 01:15:13 2009 (r188259) @@ -78,7 +78,6 @@ struct i2s_softc { struct aoa_softc aoa; - device_t dev; phandle_t node; phandle_t soundnode; struct resource *reg; @@ -179,7 +178,7 @@ i2s_attach(device_t self) sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); - sc->dev = self; + sc->aoa.sc_dev = self; sc->node = ofw_bus_get_node(self); port = of_find_firstchild_byname(sc->node, "i2s-a"); @@ -216,8 +215,8 @@ i2s_attach(device_t self) if (err != 0) return (err); - bus_setup_intr(self, dbdma_irq, INTR_TYPE_AV | INTR_MPSAFE, NULL, - aoa_interrupt, sc, &dbdma_ih); + snd_setup_intr(self, dbdma_irq, INTR_MPSAFE, aoa_interrupt, + sc, &dbdma_ih); oirq = rman_get_start(dbdma_irq); err = powerpc_config_intr(oirq, INTR_TRIGGER_EDGE, INTR_POLARITY_LOW); @@ -233,12 +232,12 @@ i2s_attach(device_t self) return (ENOMEM); i2s_delayed_attach->ich_func = i2s_postattach; - i2s_delayed_attach->ich_arg = self; + i2s_delayed_attach->ich_arg = sc; if (config_intrhook_establish(i2s_delayed_attach) != 0) return (ENOMEM); - return (aoa_attach(self,sc)); + return (aoa_attach(sc)); } /***************************************************************************** @@ -717,16 +716,13 @@ i2s_set_outputs(void *ptr, u_int mask) } static void -i2s_postattach(void *arg) +i2s_postattach(void *xsc) { - device_t self = arg; - struct i2s_softc *sc; + struct i2s_softc *sc = xsc; + device_t self; int i; - KASSERT(self != NULL, ("bad arg")); - KASSERT(i2s_delayed_attach != NULL, ("bogus call")); - - sc = pcm_getdevinfo(self); + self = sc->aoa.sc_dev; /* Reset the codec. */ i2s_audio_hw_reset(sc); Modified: head/sys/dev/sound/macio/snapper.c ============================================================================== --- head/sys/dev/sound/macio/snapper.c Sat Feb 7 01:12:51 2009 (r188258) +++ head/sys/dev/sound/macio/snapper.c Sat Feb 7 01:15:13 2009 (r188259) @@ -433,10 +433,14 @@ static int snapper_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right) { struct snapper_softc *sc; + struct mtx *mixer_lock; + int locked; u_int l, r; u_char reg[6]; sc = device_get_softc(mix_getdevinfo(m)); + mixer_lock = mixer_get_lock(m); + locked = mtx_owned(mixer_lock); if (left > 100 || right > 100) return (0); @@ -452,8 +456,22 @@ snapper_set(struct snd_mixer *m, unsigne reg[3] = (r & 0xff0000) >> 16; reg[4] = (r & 0x00ff00) >> 8; reg[5] = r & 0x0000ff; + + /* + * We need to unlock the mixer lock because iicbus_transfer() + * may sleep. The mixer lock itself is unnecessary here + * because it is meant to serialize hardware access, which + * is taken care of by the I2C layer, so this is safe. + */ + + if (locked) + mtx_unlock(mixer_lock); + snapper_write(sc, SNAPPER_VOLUME, reg); + if (locked) + mtx_lock(mixer_lock); + return (left | (right << 8)); } Modified: head/sys/dev/sound/macio/tumbler.c ============================================================================== --- head/sys/dev/sound/macio/tumbler.c Sat Feb 7 01:12:51 2009 (r188258) +++ head/sys/dev/sound/macio/tumbler.c Sat Feb 7 01:15:13 2009 (r188259) @@ -95,8 +95,6 @@ static int tumbler_reinit(struct snd_mix static int tumbler_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right); static int tumbler_setrecsrc(struct snd_mixer *m, u_int32_t src); -static int tumbler_set_volume(struct tumbler_softc *sc, int left, - int right); static device_method_t tumbler_methods[] = { /* Device interface. */ @@ -381,12 +379,46 @@ static int tumbler_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right) { struct tumbler_softc *sc; + struct mtx *mixer_lock; + int locked; + u_int l, r; + u_char reg[6]; sc = device_get_softc(mix_getdevinfo(m)); + mixer_lock = mixer_get_lock(m); + locked = mtx_owned(mixer_lock); switch (dev) { case SOUND_MIXER_VOLUME: - return (tumbler_set_volume(sc, left, right)); + if (left > 100 || right > 100) + return (0); + + l = (left == 0 ? 0 : tumbler_volume_table[left - 1]); + r = (right == 0 ? 0 : tumbler_volume_table[right - 1]); + + reg[0] = (l & 0xff0000) >> 16; + reg[1] = (l & 0x00ff00) >> 8; + reg[2] = l & 0x0000ff; + reg[3] = (r & 0xff0000) >> 16; + reg[4] = (r & 0x00ff00) >> 8; + reg[5] = r & 0x0000ff; + + /* + * We need to unlock the mixer lock because iicbus_transfer() + * may sleep. The mixer lock itself is unnecessary here + * because it is meant to serialize hardware access, which + * is taken care of by the I2C layer, so this is safe. + */ + + if (locked) + mtx_unlock(mixer_lock); + + tumbler_write(sc, TUMBLER_VOLUME, reg); + + if (locked) + mtx_lock(mixer_lock); + + return (left | (right << 8)); } return (0); @@ -398,26 +430,3 @@ tumbler_setrecsrc(struct snd_mixer *m, u return (0); } -static int -tumbler_set_volume(struct tumbler_softc *sc, int left, int right) -{ - u_int l, r; - u_char reg[6]; - - if (left > 100 || right > 100) - return (0); - - l = (left == 0 ? 0 : tumbler_volume_table[left - 1]); - r = (right == 0 ? 0 : tumbler_volume_table[right - 1]); - - reg[0] = (l & 0xff0000) >> 16; - reg[1] = (l & 0x00ff00) >> 8; - reg[2] = l & 0x0000ff; - reg[3] = (r & 0xff0000) >> 16; - reg[4] = (r & 0x00ff00) >> 8; - reg[5] = r & 0x0000ff; - tumbler_write(sc, TUMBLER_VOLUME, reg); - - return (left | (right << 8)); -} -