Home | History | Annotate | Download | only in allocate
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28 
     29 /*
     30  * audio_clean - Clear any residual data that may be residing in the in the
     31  *	audio device driver or chip.
     32  *
     33  *	Usage: audio_clean [-Iisf] device_name
     34  *
     35  *	Note: The same operation is performed for any of the "ifs" flags.
     36  *		The "I" flag is a silent form of "i".  Support for the flags
     37  *		is provided so that the framework is place if added
     38  *		functionality is required.
     39  *
     40  *	Note: The AUDIO_SETINFO ioctl is used instead of the low level
     41  *		AUDIOSETREG command which is used to perform low level
     42  *		operations on the device.  If a process had previously used
     43  *		AUDIOSETREG to monkey with the device, then the driver would
     44  *		have reset the chip when the process performed a close,
     45  *		so this can just clear the info structure.
     46  */
     47 
     48 #include <ctype.h>
     49 #include <errno.h>
     50 #include <fcntl.h>
     51 #include <libintl.h>
     52 #include <locale.h>
     53 #include <stdio.h>
     54 #include <stdlib.h>
     55 #include <string.h>
     56 #include <strings.h>
     57 #include <stropts.h>
     58 #include <unistd.h>
     59 #include <bsm/devices.h>
     60 #include <sys/audioio.h>
     61 #include <sys/file.h>
     62 #include <sys/ioctl.h>
     63 #include <sys/param.h>
     64 #include <sys/stat.h>
     65 #include <sys/types.h>
     66 
     67 #ifndef	TEXT_DOMAIN
     68 #define	TEXT_DOMAIN	"SUNW_OST_OSCMD"
     69 #endif
     70 
     71 #ifdef	DEBUG
     72 static void print_info(audio_info_t *);
     73 static void print_prinfo(audio_prinfo_t *);
     74 #endif	/* DEBUG */
     75 
     76 static void
     77 usage(char *prog)
     78 {
     79 	(void) fprintf(stderr, "%s%s", prog,
     80 	    gettext(" : usage:[-I|-s|-f|-i] device\n"));
     81 }
     82 
     83 int
     84 main(int argc, char **argv)
     85 {
     86 	int		err = 0;
     87 	int		Audio_fd;
     88 	int		forced = 0;		/* Command line options */
     89 	int		initial = 0;
     90 	int		standard = 0;
     91 	int		verbose = 1;		/* default is to be verbose */
     92 	int		c;
     93 	char		*prog, *devname, *devpath;
     94 	devmap_t	*dm;
     95 	struct stat	st;
     96 	audio_info_t	info;
     97 
     98 	(void) setlocale(LC_ALL, "");
     99 	(void) textdomain(TEXT_DOMAIN);
    100 
    101 	prog = argv[0];		/* save program initiation name */
    102 
    103 	/*
    104 	 * Parse arguments.  Currently i, s and f all do the
    105 	 * the same thing.
    106 	 */
    107 
    108 	while ((c = getopt(argc, argv, "Iifs")) != -1) {
    109 		switch (c) {
    110 		case 'I':
    111 			verbose = 0;
    112 			initial++;
    113 			if (standard || forced)
    114 				err++;
    115 			break;
    116 		case 'i':
    117 			initial++;
    118 			if (standard || forced)
    119 				err++;
    120 			break;
    121 		case 's':
    122 			standard++;
    123 			if (initial || forced)
    124 				err++;
    125 			break;
    126 		case 'f':
    127 			forced++;
    128 			if (initial || standard)
    129 				err++;
    130 			break;
    131 		case '?':
    132 			err++;
    133 			break;
    134 		default:
    135 			err++;
    136 			break;
    137 		}
    138 		if (err) {
    139 			if (verbose)
    140 				usage(prog);
    141 			exit(1);
    142 		}
    143 	}
    144 
    145 	if ((argc - optind) != 1) {
    146 		if (verbose)
    147 			usage(prog);
    148 		exit(1);
    149 	} else {
    150 		devname = argv[optind];
    151 	}
    152 
    153 	setdmapent();
    154 	if ((dm = getdmapnam(devname)) == NULL) {
    155 		enddmapent();
    156 		if (verbose)
    157 			(void) fprintf(stderr, "%s%s",
    158 			    devname,
    159 			    gettext(" : No such allocatable device\n"));
    160 			exit(1);
    161 	}
    162 	enddmapent();
    163 	if (dm->dmap_devarray == NULL || dm->dmap_devarray[0] == NULL) {
    164 		if (verbose)
    165 			(void) fprintf(stderr, "%s%s",
    166 			    devname,
    167 			    gettext(" : No such allocatable device\n"));
    168 			exit(1);
    169 	}
    170 	devpath = strdup(dm->dmap_devarray[0]);
    171 	freedmapent(dm);
    172 
    173 	/*
    174 	 * Validate and open the audio device
    175 	 */
    176 	err = stat(devpath, &st);
    177 
    178 	if (err < 0) {
    179 		if (verbose) {
    180 			(void) fprintf(stderr, gettext("%s: cannot stat "),
    181 			    prog);
    182 			perror("audio_clean");
    183 		}
    184 		exit(1);
    185 	}
    186 	if (!S_ISCHR(st.st_mode)) {
    187 		if (verbose)
    188 			(void) fprintf(stderr,
    189 			    gettext("%s: %s is not an audio device\n"), prog,
    190 			    devpath);
    191 		exit(1);
    192 	}
    193 
    194 	/*
    195 	 * Since the device /dev/audio can suspend if someone else is
    196 	 * using it we check to see if we're going to hang before we
    197 	 * do anything.
    198 	 */
    199 	Audio_fd = open(devpath, O_WRONLY | O_NDELAY);
    200 
    201 	if ((Audio_fd < 0) && (errno == EBUSY)) {
    202 		if (verbose)
    203 			(void) fprintf(stderr, gettext("%s: waiting for %s..."),
    204 			    prog, devpath);
    205 		exit(0);
    206 	} else if (Audio_fd < 0) {
    207 		if (verbose) {
    208 			(void) fprintf(stderr, gettext("%s: error opening "),
    209 			    prog);
    210 			perror(devpath);
    211 		}
    212 		exit(1);
    213 	}
    214 
    215 #ifdef	DEBUG
    216 	/*
    217 	 * Read the audio_info structure.
    218 	 */
    219 
    220 	if (ioctl(Audio_fd, AUDIO_GETINFO, &info) != 0)  {
    221 		perror("Ioctl AUDIO_GETINFO error");
    222 		(void) close(Audio_fd);
    223 		exit(1);
    224 	}
    225 
    226 	print_info(&info);
    227 #endif	/* DEBUG */
    228 
    229 /* LINTED */
    230 	AUDIO_INITINFO(&info);	/* clear audit info structure */
    231 
    232 	if (ioctl(Audio_fd, AUDIO_SETINFO, &info) != 0) {
    233 		if (verbose)
    234 			perror(gettext("Ioctl AUDIO_SETINFO error"));
    235 		(void) close(Audio_fd);
    236 		exit(1);
    237 	}
    238 
    239 #ifdef	DEBUG
    240 	if (ioctl(Audio_fd, AUDIO_GETINFO, &info) != 0)  {
    241 		perror("Ioctl AUDIO_GETINFO-2 error");
    242 		(void) close(Audio_fd);
    243 		exit(1);
    244 	}
    245 
    246 	print_info(&info);
    247 #endif	/* DEBUG */
    248 
    249 	return (0);
    250 }
    251 
    252 
    253 #ifdef	DEBUG
    254 void
    255 print_info(audio_info_t *info)
    256 {
    257 	print_prinfo(&info->play);
    258 	print_prinfo(&info->record);
    259 	(void) printf("monitor_gain %d\n", info->monitor_gain);
    260 	(void) fflush(stdout);
    261 }
    262 
    263 
    264 void
    265 print_prinfo(audio_prinfo_t *prinfo)
    266 {
    267 	/* The following values decribe audio data encoding: */
    268 	(void) printf("sample_rate %d\n",	prinfo->sample_rate);
    269 	(void) printf("channels %d\n", 	prinfo->channels);
    270 	(void) printf("precision %d\n", 	prinfo->precision);
    271 	(void) printf("encoding %d\n", 	prinfo->encoding);
    272 
    273 	/* The following values control audio device configuration */
    274 	(void) printf("gain %d\n", 	prinfo->gain);
    275 	(void) printf("port %d\n", 	prinfo->port);
    276 	(void) printf("avail_ports %d\n", 	prinfo->avail_ports);
    277 	(void) printf("mod_ports %d\n", 	prinfo->mod_ports);
    278 
    279 	/* These are Reserved for future use, but we clear them  */
    280 	(void) printf("_xxx %d\n", 	prinfo->_xxx);
    281 
    282 	(void) printf("buffer_size %d\n", 	prinfo->buffer_size);
    283 
    284 	/* The following values describe driver state */
    285 	(void) printf("samples %d\n", 	prinfo->samples);
    286 	(void) printf("eof %d\n", 	prinfo->eof);
    287 	(void) printf("pause %d\n", 	prinfo->pause);
    288 	(void) printf("error %d\n", 	prinfo->error);
    289 	(void) printf("waiting %d\n", 	prinfo->waiting);
    290 	(void) printf("balance %d\n", 	prinfo->balance);
    291 
    292 	/* The following values are read-only state flags */
    293 	(void) printf("open %d\n", 	prinfo->open);
    294 	(void) printf("active %d\n", 	prinfo->active);
    295 }
    296 #endif	/* DEBUG */
    297