Mercurial > illumos > git > illumos-core
changeset 12488:810a15c88f06 onnv_141
6954550 audiohd driver should pass warlock check
author | Zhao Edgar Liu - Sun Microsystems <Edgar.Liu@Sun.COM> |
---|---|
date | Tue, 25 May 2010 10:18:53 +0800 |
parents | 963598bbd9d4 |
children | 5e419573aa3f |
files | usr/src/uts/common/io/audio/drv/audiohd/audiohd.c usr/src/uts/common/io/audio/drv/audiohd/audiohd.h usr/src/uts/common/io/warlock/audiohd.wlcmd usr/src/uts/intel/audiohd/Makefile usr/src/uts/intel/warlock/Makefile |
diffstat | 5 files changed, 188 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/io/audio/drv/audiohd/audiohd.c Mon May 24 18:26:21 2010 -0700 +++ b/usr/src/uts/common/io/audio/drv/audiohd/audiohd.c Tue May 25 10:18:53 2010 +0800 @@ -91,6 +91,11 @@ 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 @@ 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 @@ /* 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 @@ } 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 @@ 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_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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ * 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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ * 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_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 @@ 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 @@ 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 @@ 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_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 @@ 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 @@ 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 @@ 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_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 @@ 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_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_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 @@ 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 @@ 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 @@ 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) {
--- a/usr/src/uts/common/io/audio/drv/audiohd/audiohd.h Mon May 24 18:26:21 2010 -0700 +++ b/usr/src/uts/common/io/audio/drv/audiohd/audiohd.h Tue May 25 10:18:53 2010 +0800 @@ -780,7 +780,7 @@ 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 @@ } #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_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usr/src/uts/common/io/warlock/audiohd.wlcmd Tue May 25 10:18:53 2010 +0800 @@ -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
--- a/usr/src/uts/intel/audiohd/Makefile Mon May 24 18:26:21 2010 -0700 +++ b/usr/src/uts/intel/audiohd/Makefile Tue May 25 10:18:53 2010 +0800 @@ -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 @@ 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 @@ $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) clobber: $(CLOBBER_DEPS) + $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) lint: $(LINT_DEPS) @@ -96,3 +99,30 @@ # 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
--- a/usr/src/uts/intel/warlock/Makefile Mon May 24 18:26:21 2010 -0700 +++ b/usr/src/uts/intel/warlock/Makefile Tue May 25 10:18:53 2010 +0800 @@ -51,7 +51,8 @@ # 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 @@ warlock.wc: @cd ../wc; $(MAKE) clean; $(MAKE) warlock + +warlock.audiohd: + @cd ../audiohd; $(MAKE) clean; $(MAKE) warlock