Fix locking against myself problem:
hdaudio_intr() -> mutex_enter(&sc->sc_corb_mtx); hdaudio_rirb_dequeue() -> hdaudio_rirb_unsol() -> hdafg_unsol() -> hdafg_assoc_dump_dd() -> hdaudio_command() -> mutex_enter(&sc->sc_corb_mtx); Should that be done differently?
This commit is contained in:
parent
e117ce5a17
commit
64741f5e61
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: hdafg.c,v 1.25 2014/09/23 13:29:30 nat Exp $ */
|
||||
/* $NetBSD: hdafg.c,v 1.26 2015/02/11 00:37:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk>
|
||||
|
@ -60,7 +60,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: hdafg.c,v 1.25 2014/09/23 13:29:30 nat Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: hdafg.c,v 1.26 2015/02/11 00:37:25 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -836,21 +836,24 @@ hdafg_assoc_type_string(struct hdaudio_assoc *as)
|
|||
}
|
||||
|
||||
static void
|
||||
hdafg_assoc_dump_dd(struct hdafg_softc *sc, struct hdaudio_assoc *as, int pin)
|
||||
hdafg_assoc_dump_dd(struct hdafg_softc *sc, struct hdaudio_assoc *as, int pin,
|
||||
int lock)
|
||||
{
|
||||
struct hdafg_dd_info hdi;
|
||||
struct hdaudio_widget *w;
|
||||
uint8_t elddata[256];
|
||||
unsigned int elddatalen = 0, i;
|
||||
uint32_t res;
|
||||
uint32_t (*cmd)(struct hdaudio_codec *, int, uint32_t, uint32_t) =
|
||||
lock ? hdaudio_command : hdaudio_command_unlocked;
|
||||
|
||||
w = hdafg_widget_lookup(sc, as->as_pins[pin]);
|
||||
|
||||
if (w->w_pin.cap & COP_PINCAP_TRIGGER_REQD) {
|
||||
hdaudio_command(sc->sc_codec, as->as_pins[pin],
|
||||
(*cmd)(sc->sc_codec, as->as_pins[pin],
|
||||
CORB_SET_PIN_SENSE, 0);
|
||||
}
|
||||
res = hdaudio_command(sc->sc_codec, as->as_pins[pin],
|
||||
res = (*cmd)(sc->sc_codec, as->as_pins[pin],
|
||||
CORB_GET_PIN_SENSE, 0);
|
||||
|
||||
#ifdef HDAFG_HDMI_DEBUG
|
||||
|
@ -864,13 +867,13 @@ hdafg_assoc_dump_dd(struct hdafg_softc *sc, struct hdaudio_assoc *as, int pin)
|
|||
if ((res &
|
||||
(COP_GET_PIN_SENSE_PRESENSE_DETECT|COP_GET_PIN_SENSE_ELD_VALID)) ==
|
||||
(COP_GET_PIN_SENSE_PRESENSE_DETECT|COP_GET_PIN_SENSE_ELD_VALID)) {
|
||||
res = hdaudio_command(sc->sc_codec, as->as_pins[pin],
|
||||
res = (*cmd)(sc->sc_codec, as->as_pins[pin],
|
||||
CORB_GET_HDMI_DIP_SIZE, COP_DIP_ELD_SIZE);
|
||||
elddatalen = COP_DIP_BUFFER_SIZE(res);
|
||||
if (elddatalen == 0)
|
||||
elddatalen = sizeof(elddata); /* paranoid */
|
||||
for (i = 0; i < elddatalen; i++) {
|
||||
res = hdaudio_command(sc->sc_codec, as->as_pins[pin],
|
||||
res = (*cmd)(sc->sc_codec, as->as_pins[pin],
|
||||
CORB_GET_HDMI_ELD_DATA, i);
|
||||
if (!(res & COP_ELD_VALID)) {
|
||||
hda_error(sc, "bad ELD size (%u/%u)\n",
|
||||
|
@ -1089,7 +1092,7 @@ hdafg_assoc_dump(struct hdafg_softc *sc)
|
|||
for (j = 0; j < HDAUDIO_MAXPINS; j++) {
|
||||
if (as[i].as_pins[j] == 0)
|
||||
continue;
|
||||
hdafg_assoc_dump_dd(sc, &as[i], j);
|
||||
hdafg_assoc_dump_dd(sc, &as[i], j, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4268,7 +4271,7 @@ hdafg_unsol(device_t self, uint8_t tag)
|
|||
for (j = 0; j < HDAUDIO_MAXPINS; j++) {
|
||||
if (as[i].as_pins[j] == 0)
|
||||
continue;
|
||||
hdafg_assoc_dump_dd(sc, &as[i], j);
|
||||
hdafg_assoc_dump_dd(sc, &as[i], j, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: hdaudio.c,v 1.24 2014/09/21 14:30:22 christos Exp $ */
|
||||
/* $NetBSD: hdaudio.c,v 1.25 2015/02/11 00:37:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk>
|
||||
|
@ -30,7 +30,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: hdaudio.c,v 1.24 2014/09/21 14:30:22 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: hdaudio.c,v 1.25 2015/02/11 00:37:25 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -326,16 +326,26 @@ hdaudio_rirb_dequeue(struct hdaudio_softc *sc, bool unsol)
|
|||
uint32_t
|
||||
hdaudio_command(struct hdaudio_codec *co, int nid, uint32_t control,
|
||||
uint32_t param)
|
||||
{
|
||||
uint32_t result;
|
||||
struct hdaudio_softc *sc = co->co_host;
|
||||
mutex_enter(&sc->sc_corb_mtx);
|
||||
result = hdaudio_command_unlocked(co, nid, control, param);
|
||||
mutex_exit(&sc->sc_corb_mtx);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
hdaudio_command_unlocked(struct hdaudio_codec *co, int nid, uint32_t control,
|
||||
uint32_t param)
|
||||
{
|
||||
struct hdaudio_softc *sc = co->co_host;
|
||||
uint32_t result;
|
||||
|
||||
mutex_enter(&sc->sc_corb_mtx);
|
||||
hda_trace(sc, "cmd : request %08X %08X (%02X)\n",
|
||||
control, param, nid);
|
||||
hdaudio_corb_enqueue(sc, co->co_addr, nid, control, param);
|
||||
result = hdaudio_rirb_dequeue(sc, false);
|
||||
mutex_exit(&sc->sc_corb_mtx);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: hdaudiovar.h,v 1.9 2011/02/13 17:49:12 jmcneill Exp $ */
|
||||
/* $NetBSD: hdaudiovar.h,v 1.10 2015/02/11 00:37:25 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Precedence Technologies Ltd <support@precedence.co.uk>
|
||||
|
@ -176,6 +176,8 @@ int hdaudio_rescan(struct hdaudio_softc *, const char *, const int *);
|
|||
void hdaudio_childdet(struct hdaudio_softc *, device_t);
|
||||
|
||||
uint32_t hdaudio_command(struct hdaudio_codec *, int, uint32_t, uint32_t);
|
||||
uint32_t hdaudio_command_unlocked(struct hdaudio_codec *, int, uint32_t,
|
||||
uint32_t);
|
||||
int hdaudio_intr(struct hdaudio_softc *);
|
||||
|
||||
int hdaudio_dma_alloc(struct hdaudio_softc *, struct hdaudio_dma *, int);
|
||||
|
|
Loading…
Reference in New Issue