6954550 audiohd driver should pass warlock check onnv_141
authorZhao Edgar Liu - Sun Microsystems <Edgar.Liu@Sun.COM>
Tue, 25 May 2010 10:18:53 +0800
changeset 12488 810a15c88f06
parent 12487 963598bbd9d4
child 12489 5e419573aa3f
6954550 audiohd driver should pass warlock check
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
--- 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