Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix locking for ac97.
  • Loading branch information
ad committed Dec 13, 2008
1 parent d320404 commit ee43ef0
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 19 deletions.
6 changes: 4 additions & 2 deletions sys/dev/pci/auacer.c
@@ -1,4 +1,4 @@
/* $NetBSD: auacer.c,v 1.21.12.2 2008/12/12 23:06:57 ad Exp $ */
/* $NetBSD: auacer.c,v 1.21.12.3 2008/12/13 13:38:00 ad Exp $ */

/*-
* Copyright (c) 2004, 2008 The NetBSD Foundation, Inc.
Expand Down Expand Up @@ -44,7 +44,7 @@


#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: auacer.c,v 1.21.12.2 2008/12/12 23:06:57 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: auacer.c,v 1.21.12.3 2008/12/13 13:38:00 ad Exp $");

#include <sys/param.h>
#include <sys/systm.h>
Expand Down Expand Up @@ -336,6 +336,7 @@ auacer_attach(struct device *parent, struct device *self, void *aux)

/* setup audio_format */
memcpy(sc->sc_formats, auacer_formats, sizeof(auacer_formats));
mutex_enter(&sc->sc_lock);
if (!AC97_IS_4CH(sc->codec_if))
AUFMT_INVALIDATE(&sc->sc_formats[AUACER_FORMATS_4CH]);
if (!AC97_IS_6CH(sc->codec_if))
Expand All @@ -346,6 +347,7 @@ auacer_attach(struct device *parent, struct device *self, void *aux)
sc->sc_formats[i].frequency[0] = 48000;
}
}
mutex_exit(&sc->sc_lock);

if (0 != auconv_create_encodings(sc->sc_formats, AUACER_NFORMATS,
&sc->sc_encodings)) {
Expand Down
28 changes: 20 additions & 8 deletions sys/dev/pci/auich.c
@@ -1,4 +1,4 @@
/* $NetBSD: auich.c,v 1.128.2.2 2008/12/12 23:06:57 ad Exp $ */
/* $NetBSD: auich.c,v 1.128.2.3 2008/12/13 13:38:00 ad Exp $ */

/*-
* Copyright (c) 2000, 2004, 2005, 2008 The NetBSD Foundation, Inc.
Expand Down Expand Up @@ -111,7 +111,7 @@
*/

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: auich.c,v 1.128.2.2 2008/12/12 23:06:57 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: auich.c,v 1.128.2.3 2008/12/13 13:38:00 ad Exp $");

#include <sys/param.h>
#include <sys/systm.h>
Expand Down Expand Up @@ -183,6 +183,7 @@ struct auich_softc {
struct ac97_host_if host_if;
int sc_codecnum;
int sc_codectype;
int sc_fixedrate;
enum ac97_host_flags sc_codecflags;
bool sc_spdif;

Expand Down Expand Up @@ -608,7 +609,10 @@ auich_attach(device_t parent, device_t self, void *aux)
if (ac97_attach_type(&sc->host_if, self, sc->sc_codectype,
&sc->sc_lock) != 0)
return;

mutex_enter(&sc->sc_lock);
sc->codec_if->vtbl->unlock(sc->codec_if);
sc->sc_fixedrate = AC97_IS_FIXED_RATE(sc->codec_if);

/* setup audio_format */
if (sc->sc_codectype == AC97_CODEC_TYPE_AUDIO) {
Expand All @@ -623,13 +627,15 @@ auich_attach(device_t parent, device_t self, void *aux)
sc->sc_audio_formats[i].frequency[0] = 48000;
}
}
mutex_exit(&sc->sc_lock);
if (0 != auconv_create_encodings(sc->sc_audio_formats, AUICH_AUDIO_NFORMATS,
&sc->sc_encodings))
return;
if (0 != auconv_create_encodings(auich_spdif_formats, AUICH_SPDIF_NFORMATS,
&sc->sc_spdif_encodings))
return;
} else {
mutex_exit(&sc->sc_lock);
memcpy(sc->sc_modem_formats, auich_modem_formats, sizeof(auich_modem_formats));
if (0 != auconv_create_encodings(sc->sc_modem_formats, AUICH_MODEM_NFORMATS,
&sc->sc_encodings))
Expand All @@ -643,8 +649,7 @@ auich_attach(device_t parent, device_t self, void *aux)
config_interrupts(self, auich_finish_attach);

/* sysctl setup */
if (AC97_IS_FIXED_RATE(sc->codec_if) &&
sc->sc_codectype == AC97_CODEC_TYPE_AUDIO)
if (sc->sc_fixedrate && sc->sc_codectype == AC97_CODEC_TYPE_AUDIO)
return;

err = sysctl_createv(&sc->sc_log, 0, NULL, NULL, 0,
Expand All @@ -659,7 +664,7 @@ auich_attach(device_t parent, device_t self, void *aux)
goto sysctl_err;
node_mib = node->sysctl_num;

if (!AC97_IS_FIXED_RATE(sc->codec_if)) {
if (!sc->sc_fixedrate) {
/* passing the sc address instead of &sc->sc_ac97_clock */
err = sysctl_createv(&sc->sc_log, 0, NULL, &node_ac97clock,
CTLFLAG_READWRITE,
Expand Down Expand Up @@ -765,8 +770,10 @@ auich_finish_attach(device_t self)
{
struct auich_softc *sc = device_private(self);

mutex_enter(&sc->sc_lock);
if (!AC97_IS_FIXED_RATE(sc->codec_if))
auich_calibrate(sc);
mutex_exit(&sc->sc_lock);

sc->sc_audiodev = audio_attach_mi(&auich_hw_if, sc, sc->sc_dev);

Expand Down Expand Up @@ -916,7 +923,9 @@ auich_open(void *addr, int flags)
struct auich_softc *sc;

sc = (struct auich_softc *)addr;
mutex_spin_exit(&sc->sc_intr_lock);
sc->codec_if->vtbl->lock(sc->codec_if);
mutex_spin_enter(&sc->sc_intr_lock);
return 0;
}

Expand All @@ -926,7 +935,9 @@ auich_close(void *addr)
struct auich_softc *sc;

sc = (struct auich_softc *)addr;
mutex_spin_exit(&sc->sc_intr_lock);
sc->codec_if->vtbl->unlock(sc->codec_if);
mutex_spin_enter(&sc->sc_intr_lock);
}

static int
Expand Down Expand Up @@ -1669,6 +1680,7 @@ auich_calibrate(struct auich_softc *sc)
(0 - 1) & ICH_LVI_MASK);

/* start */
kpreempt_disable();
microtime(&t1);
bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, ICH_RPBM);

Expand All @@ -1685,6 +1697,7 @@ auich_calibrate(struct auich_softc *sc)

/* stop */
bus_space_write_1(sc->iot, sc->aud_ioh, ICH_PCMI + ICH_CTRL, 0);
kpreempt_enable();

/* reset */
DELAY(100);
Expand Down Expand Up @@ -1727,13 +1740,12 @@ auich_clear_cas(struct auich_softc *sc)
return;
}


static void
auich_get_locks(void *addr, kmutex_t **intr, kmutex_t **proc)
auich_get_locks(void *addr, kmutex_t **intr, kmutex_t **thread)
{
struct auich_softc *sc;

sc = addr;
*intr = &sc->sc_intr_lock;
*proc = &sc->sc_lock;
*thread = &sc->sc_lock;
}
8 changes: 6 additions & 2 deletions sys/dev/pci/auixp.c
@@ -1,4 +1,4 @@
/* $NetBSD: auixp.c,v 1.28.16.2 2008/12/12 23:06:57 ad Exp $ */
/* $NetBSD: auixp.c,v 1.28.16.3 2008/12/13 13:38:00 ad Exp $ */

/*
* Copyright (c) 2004, 2005 Reinoud Zandijk <reinoud@netbsd.org>
Expand Down Expand Up @@ -50,7 +50,7 @@
*/

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: auixp.c,v 1.28.16.2 2008/12/12 23:06:57 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: auixp.c,v 1.28.16.3 2008/12/13 13:38:00 ad Exp $");

#include <sys/types.h>
#include <sys/errno.h>
Expand Down Expand Up @@ -1233,10 +1233,12 @@ auixp_post_config(device_t self)

/* copy formats and invalidate entries not suitable for codec0 */
memcpy(sc->sc_formats, auixp_formats, sizeof(auixp_formats));
mutex_enter(&sc->sc_lock);
sc->has_4ch = AC97_IS_4CH(codec->codec_if);
sc->has_6ch = AC97_IS_6CH(codec->codec_if);
sc->is_fixed = AC97_IS_FIXED_RATE(codec->codec_if);
sc->has_spdif = AC97_HAS_SPDIF(codec->codec_if);
mutex_exit(&sc->sc_lock);

for (i = 0; i < AUIXP_NFORMATS; i++) {
if (sc->is_fixed) {
Expand Down Expand Up @@ -1779,9 +1781,11 @@ auixp_resume(device_t dv PMF_FN_ARGS)
{
struct auixp_softc *sc = device_private(dv);

mutex_enter(&sc->sc_lock);
auixp_reset_codec(sc);
delay(1000);
(sc->sc_codec[0].codec_if->vtbl->restore_ports)(sc->sc_codec[0].codec_if);
mutex_exit(&sc->sc_lock);

return true;
}
Expand Down
16 changes: 14 additions & 2 deletions sys/dev/pci/auvia.c
@@ -1,4 +1,4 @@
/* $NetBSD: auvia.c,v 1.67.6.2 2008/12/11 19:49:30 ad Exp $ */
/* $NetBSD: auvia.c,v 1.67.6.3 2008/12/13 13:38:00 ad Exp $ */

/*-
* Copyright (c) 2000, 2008 The NetBSD Foundation, Inc.
Expand Down Expand Up @@ -40,7 +40,7 @@
*/

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: auvia.c,v 1.67.6.2 2008/12/11 19:49:30 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: auvia.c,v 1.67.6.3 2008/12/13 13:38:00 ad Exp $");

#include <sys/param.h>
#include <sys/systm.h>
Expand Down Expand Up @@ -476,6 +476,7 @@ auvia_attach(device_t parent, device_t self, void *aux)

/* setup audio_format */
memcpy(sc->sc_formats, auvia_formats, sizeof(auvia_formats));
mutex_enter(&sc->sc_lock);
if (sc->sc_play.sc_base != VIA8233_MP_BASE || !AC97_IS_4CH(sc->codec_if)) {
AUFMT_INVALIDATE(&sc->sc_formats[AUVIA_FORMATS_4CH_8]);
AUFMT_INVALIDATE(&sc->sc_formats[AUVIA_FORMATS_4CH_16]);
Expand All @@ -490,10 +491,13 @@ auvia_attach(device_t parent, device_t self, void *aux)
sc->sc_formats[r].frequency[0] = 48000;
}
}
mutex_exit(&sc->sc_lock);

if (0 != auconv_create_encodings(sc->sc_formats, AUVIA_NFORMATS,
&sc->sc_encodings)) {
mutex_enter(&sc->sc_lock);
sc->codec_if->vtbl->detach(sc->codec_if);
mutex_exit(&sc->sc_lock);
pci_intr_disestablish(pc, sc->sc_ih);
bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_iosize);
mutex_destroy(&sc->sc_lock);
Expand All @@ -503,7 +507,9 @@ auvia_attach(device_t parent, device_t self, void *aux)
}
if (0 != auconv_create_encodings(auvia_spdif_formats,
AUVIA_SPDIF_NFORMATS, &sc->sc_spdif_encodings)) {
mutex_enter(&sc->sc_lock);
sc->codec_if->vtbl->detach(sc->codec_if);
mutex_exit(&sc->sc_lock);
pci_intr_disestablish(pc, sc->sc_ih);
bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_iosize);
mutex_destroy(&sc->sc_lock);
Expand All @@ -516,7 +522,9 @@ auvia_attach(device_t parent, device_t self, void *aux)
aprint_error_dev(self, "couldn't establish power handler\n");

audio_attach_mi(&auvia_hw_if, sc, &sc->sc_dev);
mutex_enter(&sc->sc_lock);
sc->codec_if->vtbl->unlock(sc->codec_if);
mutex_exit(&sc->sc_lock);
return;
}

Expand Down Expand Up @@ -646,7 +654,9 @@ auvia_open(void *addr, int flags)
struct auvia_softc *sc;

sc = (struct auvia_softc *)addr;
mutex_spin_exit(&sc->sc_intr_lock);
sc->codec_if->vtbl->lock(sc->codec_if);
mutex_spin_enter(&sc->sc_intr_lock);
return 0;
}

Expand All @@ -656,7 +666,9 @@ auvia_close(void *addr)
struct auvia_softc *sc;

sc = (struct auvia_softc *)addr;
mutex_spin_exit(&sc->sc_intr_lock);
sc->codec_if->vtbl->unlock(sc->codec_if);
mutex_spin_enter(&sc->sc_intr_lock);
}

static int
Expand Down
6 changes: 4 additions & 2 deletions sys/dev/pci/emuxki.c
@@ -1,4 +1,4 @@
/* $NetBSD: emuxki.c,v 1.54.6.2 2008/12/12 23:06:58 ad Exp $ */
/* $NetBSD: emuxki.c,v 1.54.6.3 2008/12/13 13:38:00 ad Exp $ */

/*-
* Copyright (c) 2001, 2007 The NetBSD Foundation, Inc.
Expand Down Expand Up @@ -49,7 +49,7 @@
*/

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: emuxki.c,v 1.54.6.2 2008/12/12 23:06:58 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: emuxki.c,v 1.54.6.3 2008/12/13 13:38:00 ad Exp $");

#include <sys/param.h>
#include <sys/device.h>
Expand Down Expand Up @@ -482,10 +482,12 @@ emuxki_attach(struct device *parent, struct device *self, void *aux)
return;
}
#if 0
mutex_enter(&sc->lock);
sc->rsourcectl.dev =
sc->codecif->vtbl->get_portnum_by_name(sc->codec_if, AudioCrecord,
AudioNsource, NULL);
sc->rsourcectl.cp = AUDIO_MIXER_ENUM;
mutex_exit(&sc->lock);
#endif
}

Expand Down
9 changes: 6 additions & 3 deletions sys/dev/pci/esm.c
@@ -1,4 +1,4 @@
/* $NetBSD: esm.c,v 1.47.16.2 2008/12/12 23:06:58 ad Exp $ */
/* $NetBSD: esm.c,v 1.47.16.3 2008/12/13 13:38:00 ad Exp $ */

/*-
* Copyright (c) 2002, 2003 Matt Fredette
Expand Down Expand Up @@ -66,7 +66,7 @@
*/

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: esm.c,v 1.47.16.2 2008/12/12 23:06:58 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: esm.c,v 1.47.16.3 2008/12/13 13:38:00 ad Exp $");

#include <sys/param.h>
#include <sys/systm.h>
Expand Down Expand Up @@ -1766,8 +1766,11 @@ esm_detach(device_t self, int flags)
/* free our DMA region */
esm_freemem(ess, &ess->sc_dma);

if (ess->codec_if != NULL)
if (ess->codec_if != NULL) {
mutex_enter(&ess->sc_lock);
ess->codec_if->vtbl->detach(ess->codec_if);
mutex_exit(&ess->sc_lock);
}

/* XXX Restore CONF_MAESTRO? */
/* XXX Restore legacy emulations? */
Expand Down

0 comments on commit ee43ef0

Please sign in to comment.