summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/uts/common/io/audio/drv/audiohd/audiohd.c103
-rw-r--r--usr/src/uts/common/io/audio/drv/audiohd/audiohd.h18
-rw-r--r--usr/src/uts/common/io/warlock/audiohd.wlcmd68
-rw-r--r--usr/src/uts/intel/audiohd/Makefile34
-rw-r--r--usr/src/uts/intel/warlock/Makefile6
5 files changed, 187 insertions, 42 deletions
diff --git a/usr/src/uts/common/io/audio/drv/audiohd/audiohd.c b/usr/src/uts/common/io/audio/drv/audiohd/audiohd.c
index 5da0dff1f1..0917604d6d 100644
--- a/usr/src/uts/common/io/audio/drv/audiohd/audiohd.c
+++ b/usr/src/uts/common/io/audio/drv/audiohd/audiohd.c
@@ -91,6 +91,11 @@ static int audiohd_beep;
static int audiohd_beep_divider;
static int audiohd_beep_vol = 1;
+/* Warlock annotation */
+_NOTE(SCHEME_PROTECTS_DATA("unshared data", audiohd_beep))
+_NOTE(SCHEME_PROTECTS_DATA("unshared data", audiohd_beep_divider))
+_NOTE(SCHEME_PROTECTS_DATA("unshared data", audiohd_beep_vol))
+
static ddi_device_acc_attr_t hda_dev_accattr = {
DDI_DEVICE_ATTR_V0,
DDI_STRUCTURE_LE_ACC,
@@ -316,6 +321,9 @@ audiohd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
statep = kmem_zalloc(sizeof (*statep), KM_SLEEP);
ddi_set_driver_private(dip, statep);
+ mutex_init(&statep->hda_mutex, NULL, MUTEX_DRIVER, 0);
+ mutex_enter(&statep->hda_mutex);
+
/* interrupt cookie and initialize mutex */
if (audiohd_init_state(statep, dip) != DDI_SUCCESS) {
cmn_err(CE_WARN,
@@ -362,8 +370,6 @@ audiohd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
/* disable interrupts and clear interrupt status */
audiohd_disable_intr(statep);
- mutex_init(&statep->hda_mutex, NULL, MUTEX_DRIVER, 0);
-
/*
* Register audio controls.
*/
@@ -376,8 +382,10 @@ audiohd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
}
ddi_report_dev(dip);
+ mutex_exit(&statep->hda_mutex);
return (DDI_SUCCESS);
error:
+ mutex_exit(&statep->hda_mutex);
audiohd_destroy(statep);
return (DDI_FAILURE);
}
@@ -515,6 +523,7 @@ audiohd_free_path(audiohd_state_t *statep)
static void
audiohd_destroy(audiohd_state_t *statep)
{
+ mutex_enter(&statep->hda_mutex);
audiohd_stop_dma(statep);
if (statep->hda_ksp)
kstat_delete(statep->hda_ksp);
@@ -524,6 +533,7 @@ audiohd_destroy(audiohd_state_t *statep)
audiohd_del_controls(statep);
audiohd_fini_controller(statep);
audiohd_fini_pci(statep);
+ mutex_exit(&statep->hda_mutex);
mutex_destroy(&statep->hda_mutex);
if (statep->adev)
audio_dev_free(statep->adev);
@@ -832,13 +842,16 @@ static int
audiohd_engine_open(void *arg, int flag, unsigned *nframes, caddr_t *bufp)
{
audiohd_port_t *port = arg;
+ audiohd_state_t *statep = port->statep;
_NOTE(ARGUNUSED(flag));
+ mutex_enter(&statep->hda_mutex);
port->count = 0;
port->curpos = 0;
*nframes = port->nframes;
*bufp = port->samp_kaddr;
+ mutex_exit(&statep->hda_mutex);
return (0);
}
@@ -853,6 +866,7 @@ audiohd_engine_start(void *arg)
mutex_enter(&statep->hda_mutex);
if ((rv = audiohd_reset_port(port)) != 0) {
+ mutex_exit(&statep->hda_mutex);
return (rv);
}
/* Start DMA */
@@ -990,8 +1004,12 @@ static int
audiohd_get_control(void *arg, uint64_t *val)
{
audiohd_ctrl_t *ac = arg;
+ audiohd_state_t *statep = ac->statep;
+ mutex_enter(&statep->hda_mutex);
*val = ac->val;
+ mutex_exit(&statep->hda_mutex);
+
return (0);
}
@@ -1880,7 +1898,9 @@ audiohd_quiesce(dev_info_t *dip)
statep = ddi_get_driver_private(dip);
+ mutex_enter(&statep->hda_mutex);
audiohd_stop_dma(statep);
+ mutex_exit(&statep->hda_mutex);
return (DDI_SUCCESS);
}
@@ -1889,35 +1909,41 @@ static void
audiohd_beep_on(void *arg)
{
hda_codec_t *codec = ((audiohd_widget_t *)arg)->codec;
- audiohd_state_t *statep = codec->soft_statep;
+ audiohd_state_t *statep = codec->statep;
int caddr = codec->index;
wid_t wid = ((audiohd_widget_t *)arg)->wid_wid;
+ mutex_enter(&statep->hda_mutex);
(void) audioha_codec_verb_get(statep, caddr, wid,
AUDIOHDC_VERB_SET_BEEP_GEN, audiohd_beep_divider);
+ mutex_exit(&statep->hda_mutex);
}
static void
audiohd_beep_off(void *arg)
{
hda_codec_t *codec = ((audiohd_widget_t *)arg)->codec;
- audiohd_state_t *statep = codec->soft_statep;
+ audiohd_state_t *statep = codec->statep;
int caddr = codec->index;
wid_t wid = ((audiohd_widget_t *)arg)->wid_wid;
+ mutex_enter(&statep->hda_mutex);
(void) audioha_codec_verb_get(statep, caddr, wid,
AUDIOHDC_VERB_SET_BEEP_GEN, AUDIOHDC_MUTE_BEEP_GEN);
+ mutex_exit(&statep->hda_mutex);
}
static void
audiohd_beep_freq(void *arg, int freq)
{
hda_codec_t *codec = ((audiohd_widget_t *)arg)->codec;
+ audiohd_state_t *statep = codec->statep;
uint32_t vid = codec->vid >> 16;
+ int divider;
_NOTE(ARGUNUSED(arg));
if (freq == 0) {
- audiohd_beep_divider = 0;
+ divider = 0;
} else {
if (freq > AUDIOHDC_MAX_BEEP_GEN)
freq = AUDIOHDC_MAX_BEEP_GEN;
@@ -1930,17 +1956,20 @@ audiohd_beep_freq(void *arg, int freq)
* Sigmatel HD codec specification:
* frequency = 48000 * (257 - Divider) / 1024
*/
- audiohd_beep_divider = 257 - freq * 1024 /
- AUDIOHDC_SAMPR48000;
+ divider = 257 - freq * 1024 / AUDIOHDC_SAMPR48000;
break;
default:
- audiohd_beep_divider = AUDIOHDC_SAMPR48000 / freq;
+ divider = AUDIOHDC_SAMPR48000 / freq;
break;
}
}
if (audiohd_beep_vol == 0)
- audiohd_beep_divider = 0;
+ divider = 0;
+
+ mutex_enter(&statep->hda_mutex);
+ audiohd_beep_divider = divider;
+ mutex_exit(&statep->hda_mutex);
}
/*
@@ -2070,12 +2099,10 @@ audiohd_fini_pci(audiohd_state_t *statep)
{
if (statep->hda_reg_handle != NULL) {
ddi_regs_map_free(&statep->hda_reg_handle);
- statep->hda_reg_handle = NULL;
}
if (statep->hda_pci_handle != NULL) {
pci_config_teardown(&statep->hda_pci_handle);
- statep->hda_pci_handle = NULL;
}
} /* audiohd_fini_pci() */
@@ -2484,7 +2511,7 @@ audiohd_get_conns_from_entry(hda_codec_t *codec, audiohd_widget_t *widget,
static void
audiohd_get_conns(hda_codec_t *codec, wid_t wid)
{
- audiohd_state_t *statep = codec->soft_statep;
+ audiohd_state_t *statep = codec->statep;
audiohd_widget_t *widget = codec->widget[wid];
uint8_t caddr = codec->index;
uint32_t entry;
@@ -2547,7 +2574,7 @@ static void
audiohd_get_pin_config(audiohd_widget_t *widget)
{
hda_codec_t *codec = widget->codec;
- audiohd_state_t *statep = codec->soft_statep;
+ audiohd_state_t *statep = codec->statep;
audiohd_pin_t *pin, *prev, *p;
int caddr = codec->index;
@@ -2643,7 +2670,7 @@ static int
audiohd_create_widgets(hda_codec_t *codec)
{
audiohd_widget_t *widget;
- audiohd_state_t *statep = codec->soft_statep;
+ audiohd_state_t *statep = codec->statep;
wid_t wid;
uint32_t type, widcap;
int caddr = codec->index;
@@ -2956,7 +2983,7 @@ audiohd_create_codec(audiohd_state_t *statep)
* We output the codec information to syslog
*/
statep->codec[i] = codec;
- codec->soft_statep = statep;
+ codec->statep = statep;
(void) audiohd_create_widgets(codec);
}
@@ -3104,7 +3131,7 @@ audiohd_do_build_output_path(hda_codec_t *codec, int mixer, int *mnum,
audiohd_state_t *statep;
int i;
- statep = codec->soft_statep;
+ statep = codec->statep;
for (pin = codec->first_pin; pin; pin = pin->next) {
if ((pin->cap & AUDIOHD_PIN_CAP_MASK) == 0)
@@ -3218,8 +3245,8 @@ audiohd_build_output_amp(hda_codec_t *codec)
int i, j;
uint32_t gain;
- for (i = 0; i < codec->soft_statep->pathnum; i++) {
- path = codec->soft_statep->path[i];
+ for (i = 0; i < codec->statep->pathnum; i++) {
+ path = codec->statep->path[i];
if (path == NULL || path->path_type != PLAY ||
path->codec != codec)
continue;
@@ -3380,7 +3407,7 @@ audiohd_build_output_amp(hda_codec_t *codec)
static void
audiohd_finish_output_path(hda_codec_t *codec)
{
- audiohd_state_t *statep = codec->soft_statep;
+ audiohd_state_t *statep = codec->statep;
audiohd_path_t *path;
audiohd_widget_t *widget;
audiohd_pin_t *pin;
@@ -3388,8 +3415,8 @@ audiohd_finish_output_path(hda_codec_t *codec)
wid_t wid, next;
int i, j;
- for (i = 0; i < codec->soft_statep->pathnum; i++) {
- path = codec->soft_statep->path[i];
+ for (i = 0; i < codec->statep->pathnum; i++) {
+ path = codec->statep->path[i];
if (!path || path->path_type != PLAY || path->codec != codec)
continue;
for (j = 0; j < path->pin_nums; j++) {
@@ -3488,7 +3515,7 @@ audiohd_find_input_pins(hda_codec_t *codec, wid_t wid, int allowmixer,
{
audiohd_widget_t *widget = codec->widget[wid];
audiohd_pin_t *pin;
- audiohd_state_t *statep = codec->soft_statep;
+ audiohd_state_t *statep = codec->statep;
uint_t caddr = codec->index;
int retval = -1;
int num, i;
@@ -3614,7 +3641,7 @@ audiohd_build_input_path(hda_codec_t *codec)
int i;
int retval;
uint8_t rtag = 0;
- audiohd_state_t *statep = codec->soft_statep;
+ audiohd_state_t *statep = codec->statep;
for (wid = codec->first_wid; wid <= codec->last_wid; wid++) {
@@ -3680,8 +3707,8 @@ audiohd_build_input_amp(hda_codec_t *codec)
int i, j;
int weight;
- for (i = 0; i < codec->soft_statep->pathnum; i++) {
- path = codec->soft_statep->path[i];
+ for (i = 0; i < codec->statep->pathnum; i++) {
+ path = codec->statep->path[i];
if (path == NULL || path->path_type != RECORD ||
path->codec != codec)
continue;
@@ -3846,15 +3873,15 @@ audiohd_build_input_amp(hda_codec_t *codec)
static void
audiohd_finish_input_path(hda_codec_t *codec)
{
- audiohd_state_t *statep = codec->soft_statep;
+ audiohd_state_t *statep = codec->statep;
audiohd_path_t *path;
audiohd_widget_t *w, *wsum;
uint_t caddr = codec->index;
wid_t wid;
int i, j;
- for (i = 0; i < codec->soft_statep->pathnum; i++) {
- path = codec->soft_statep->path[i];
+ for (i = 0; i < codec->statep->pathnum; i++) {
+ path = codec->statep->path[i];
if (path == NULL || path->path_type != RECORD ||
path->codec != codec)
continue;
@@ -4075,7 +4102,7 @@ audiohd_build_monitor_path(hda_codec_t *codec)
{
audiohd_path_t *path;
audiohd_widget_t *widget, *w;
- audiohd_state_t *statep = codec->soft_statep;
+ audiohd_state_t *statep = codec->statep;
wid_t wid, next;
int i, j, k, l, find;
int mixernum = 0;
@@ -4186,7 +4213,7 @@ audiohd_do_finish_monitor_path(hda_codec_t *codec, audiohd_widget_t *wgt)
uint_t caddr = codec->index;
audiohd_widget_t *widget = wgt;
audiohd_widget_t *w;
- audiohd_state_t *statep = codec->soft_statep;
+ audiohd_state_t *statep = codec->statep;
wid_t wid;
int i;
int share = 0;
@@ -4236,7 +4263,7 @@ audiohd_finish_monitor_path(hda_codec_t *codec)
{
audiohd_path_t *path;
audiohd_widget_t *widget;
- audiohd_state_t *statep = codec->soft_statep;
+ audiohd_state_t *statep = codec->statep;
wid_t wid;
int i, j, k;
@@ -4317,7 +4344,7 @@ audiohd_build_monitor_amp(hda_codec_t *codec)
{
audiohd_path_t *path;
audiohd_widget_t *widget, *w;
- audiohd_state_t *statep = codec->soft_statep;
+ audiohd_state_t *statep = codec->statep;
audiohd_pin_t *pin;
wid_t wid, id;
int i, j, k;
@@ -4417,7 +4444,7 @@ audiohd_build_beep_path(hda_codec_t *codec)
int i;
boolean_t beeppath = B_FALSE;
- statep = codec->soft_statep;
+ statep = codec->statep;
for (pin = codec->first_pin; pin; pin = pin->next) {
if ((pin->cap & AUDIOHD_PIN_CAP_MASK) == 0)
@@ -4508,8 +4535,8 @@ audiohd_build_beep_amp(hda_codec_t *codec)
int i, j;
uint32_t gain;
- for (i = 0; i < codec->soft_statep->pathnum; i++) {
- path = codec->soft_statep->path[i];
+ for (i = 0; i < codec->statep->pathnum; i++) {
+ path = codec->statep->path[i];
if (path == NULL || path->path_type != BEEP ||
path->codec != codec)
continue;
@@ -4585,15 +4612,15 @@ audiohd_build_beep_amp(hda_codec_t *codec)
static void
audiohd_finish_beep_path(hda_codec_t *codec)
{
- audiohd_state_t *statep = codec->soft_statep;
+ audiohd_state_t *statep = codec->statep;
audiohd_path_t *path;
audiohd_widget_t *widget;
uint_t caddr = codec->index;
wid_t wid, next;
int i, j;
- for (i = 0; i < codec->soft_statep->pathnum; i++) {
- path = codec->soft_statep->path[i];
+ for (i = 0; i < codec->statep->pathnum; i++) {
+ path = codec->statep->path[i];
if (!path || path->path_type != BEEP || path->codec != codec)
continue;
if (path->pin_nums == 0) {
diff --git a/usr/src/uts/common/io/audio/drv/audiohd/audiohd.h b/usr/src/uts/common/io/audio/drv/audiohd/audiohd.h
index 54aea2617e..fc99656eab 100644
--- a/usr/src/uts/common/io/audio/drv/audiohd/audiohd.h
+++ b/usr/src/uts/common/io/audio/drv/audiohd/audiohd.h
@@ -780,7 +780,7 @@ struct hda_codec {
uint32_t stream_format;
uint32_t pcm_format;
- audiohd_state_t *soft_statep;
+ audiohd_state_t *statep;
audiohd_codec_info_t *codec_info;
/* use wid as index to the array of widget pointers */
@@ -972,4 +972,20 @@ struct audiohd_codec_info {
}
#endif
+/* Warlock annotation */
+_NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_ctrl::statep))
+_NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_state::inmask))
+_NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_state::adev))
+_NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_state::sample_bit_depth))
+_NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_state::sample_rate))
+_NOTE(READ_ONLY_DATA(audiohd_state::hda_reg_handle))
+_NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_widget::codec))
+_NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_widget::wid_wid))
+_NOTE(DATA_READABLE_WITHOUT_LOCK(hda_codec::index))
+_NOTE(DATA_READABLE_WITHOUT_LOCK(hda_codec::statep))
+_NOTE(DATA_READABLE_WITHOUT_LOCK(hda_codec::vid))
+_NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_port::nchan))
+_NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_port::statep))
+_NOTE(DATA_READABLE_WITHOUT_LOCK(audiohd_port::sync_dir))
+
#endif /* _SYS_AUDIOHD_IMPL_H_ */
diff --git a/usr/src/uts/common/io/warlock/audiohd.wlcmd b/usr/src/uts/common/io/warlock/audiohd.wlcmd
new file mode 100644
index 0000000000..91c5fcb16e
--- /dev/null
+++ b/usr/src/uts/common/io/warlock/audiohd.wlcmd
@@ -0,0 +1,68 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+
+### specify the root functions
+root audiohd_attach
+root audiohd_detach
+root audiohd_engine_open
+root audiohd_engine_close
+root audiohd_engine_start
+root audiohd_engine_stop
+root audiohd_engine_count
+root audiohd_engine_format
+root audiohd_engine_channels
+root audiohd_engine_rate
+root audiohd_engine_sync
+root audiohd_quiesce
+root audiohd_resume
+root audiohd_suspend
+
+root audiohd_set_beep
+root audiohd_set_cd
+root audiohd_set_center
+root audiohd_set_front
+root audiohd_set_headphone
+root audiohd_set_lfe
+root audiohd_set_linein
+root audiohd_set_mic
+root audiohd_set_rear
+root audiohd_set_recsrc
+root audiohd_set_speaker
+root audiohd_set_surround
+root audiohd_set_mongain
+root audiohd_beep_on
+root audiohd_beep_off
+root audiohd_beep_freq
+root audiohd_get_control
+
+### thread functions
+add bus_ops::bus_add_eventcall target warlock_dummy
+add bus_ops::bus_config target warlock_dummy
+add bus_ops::bus_get_eventcookie target warlock_dummy
+add bus_ops::bus_intr_ctl target warlock_dummy
+add bus_ops::bus_post_event target warlock_dummy
+add bus_ops::bus_remove_eventcall target warlock_dummy
+add bus_ops::bus_unconfig target warlock_dummy
diff --git a/usr/src/uts/intel/audiohd/Makefile b/usr/src/uts/intel/audiohd/Makefile
index a0487ca3f7..89a8444fe2 100644
--- a/usr/src/uts/intel/audiohd/Makefile
+++ b/usr/src/uts/intel/audiohd/Makefile
@@ -19,8 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
#
# uts/intel/audiohd/Makefile
#
@@ -40,6 +39,9 @@ OBJECTS = $(AUDIOHD_OBJS:%=$(OBJS_DIR)/%)
LINTS = $(AUDIOHD_OBJS:%.o=$(LINTS_DIR)/%.ln)
ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE)
CONF_SRCDIR = $(UTSBASE)/common/io/audio/drv/audiohd
+WARLOCK_OUT = $(AUDIOHD_OBJS:%.o=%.ll)
+WARLOCK_OK = $(MODULE).ok
+WLCMD_DIR = $(UTSBASE)/common/io/warlock
#
# Include common rules.
@@ -83,6 +85,7 @@ clean: $(CLEAN_DEPS)
$(RM) $(WARLOCK_OUT) $(WARLOCK_OK)
clobber: $(CLOBBER_DEPS)
+ $(RM) $(WARLOCK_OUT) $(WARLOCK_OK)
lint: $(LINT_DEPS)
@@ -96,3 +99,30 @@ install: $(INSTALL_DEPS)
# Include common targets.
#
include $(UTSBASE)/intel/Makefile.targ
+
+#
+# Defines for local commands.
+#
+WARLOCK = warlock
+WLCC = wlcc
+TOUCH = touch
+TEST = test
+
+#
+# lock_lint rules
+#
+AUDIOHD_FILES = $(AUDIOHD_OBJS:%.o=../audiohd/%.ll)
+
+warlock: $(WARLOCK_OK)
+
+$(WARLOCK_OK): $(WARLOCK_OUT) $(WLCMD_DIR)/audiohd.wlcmd warlock_ddi.files
+ $(WARLOCK) -c $(WLCMD_DIR)/audiohd.wlcmd $(WARLOCK_OUT) \
+ -l ../warlock/ddi_dki_impl.ll
+ $(TOUCH) $@
+
+%.ll: $(UTSBASE)/common/io/audio/drv/audiohd/audiohd.c \
+ $(UTSBASE)/common/io/audio/drv/audiohd/audiohd.h
+ $(WLCC) $(CPPFLAGS) -DDEBUG -o $@ $<
+
+warlock_ddi.files:
+ cd ../warlock; pwd; $(MAKE) warlock
diff --git a/usr/src/uts/intel/warlock/Makefile b/usr/src/uts/intel/warlock/Makefile
index 37310f84f7..461a60bdf3 100644
--- a/usr/src/uts/intel/warlock/Makefile
+++ b/usr/src/uts/intel/warlock/Makefile
@@ -51,7 +51,8 @@ include $(UTSBASE)/intel/Makefile.intel
# lock_lint rules
#
all: warlock warlock.1394 warlock.ecpp warlock.scsi \
- warlock.usb warlock.ib warlock.sata warlock.wc
+ warlock.usb warlock.ib warlock.sata warlock.wc \
+ warlock.audiohd
warlock: $(MODULE).ok
@@ -120,3 +121,6 @@ $(CLOSED_BUILD) @cd $(CLOSED)/uts/intel/marvell88sx; \
warlock.wc:
@cd ../wc; $(MAKE) clean; $(MAKE) warlock
+
+warlock.audiohd:
+ @cd ../audiohd; $(MAKE) clean; $(MAKE) warlock