diff options
-rw-r--r-- | usr/src/uts/common/io/audio/drv/audiohd/audiohd.c | 103 | ||||
-rw-r--r-- | usr/src/uts/common/io/audio/drv/audiohd/audiohd.h | 18 | ||||
-rw-r--r-- | usr/src/uts/common/io/warlock/audiohd.wlcmd | 68 | ||||
-rw-r--r-- | usr/src/uts/intel/audiohd/Makefile | 34 | ||||
-rw-r--r-- | usr/src/uts/intel/warlock/Makefile | 6 |
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 |