Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 10 Jan 2009 18:19:22 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r187030 - in head/sys: dev/sound/pcm sys
Message-ID:  <200901101819.n0AIJMsP005436@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Sat Jan 10 18:19:22 2009
New Revision: 187030
URL: http://svn.freebsd.org/changeset/base/187030

Log:
  Import some new constants and structures fields from OSSv4.
  Implement some OSSv4 ioctls to make ossinfo tool work and print
  something reasonable.

Modified:
  head/sys/dev/sound/pcm/dsp.c
  head/sys/dev/sound/pcm/mixer.c
  head/sys/dev/sound/pcm/sound.c
  head/sys/dev/sound/pcm/sound.h
  head/sys/sys/soundcard.h

Modified: head/sys/dev/sound/pcm/dsp.c
==============================================================================
--- head/sys/dev/sound/pcm/dsp.c	Sat Jan 10 17:56:50 2009	(r187029)
+++ head/sys/dev/sound/pcm/dsp.c	Sat Jan 10 18:19:22 2009	(r187030)
@@ -814,7 +814,12 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd
 		case SNDCTL_SYSINFO:
 			sound_oss_sysinfo((oss_sysinfo *)arg);
 			break;
+		case SNDCTL_CARDINFO:
+			ret = sound_oss_card_info((oss_card_info *)arg);
+			break;
 		case SNDCTL_AUDIOINFO:
+		case SNDCTL_AUDIOINFO_EX:
+		case SNDCTL_ENGINEINFO:
 			ret = dsp_oss_audioinfo(i_dev, (oss_audioinfo *)arg);
 			break;
 		case SNDCTL_MIXERINFO:
@@ -1370,9 +1375,9 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd
 
     	case SNDCTL_DSP_GETCAPS:
 		pcm_lock(d);
-		*arg_i = DSP_CAP_REALTIME | DSP_CAP_MMAP | DSP_CAP_TRIGGER;
+		*arg_i = PCM_CAP_REALTIME | PCM_CAP_MMAP | PCM_CAP_TRIGGER;
 		if (rdch && wrch && !(dsp_get_flags(i_dev) & SD_F_SIMPLEX))
-			*arg_i |= DSP_CAP_DUPLEX;
+			*arg_i |= PCM_CAP_DUPLEX;
 		pcm_unlock(d);
 		break;
 
@@ -1770,18 +1775,6 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd
 		break;
 #if 0
 	/**
-	 * @note The SNDCTL_CARDINFO ioctl was omitted per 4Front developer
-	 * documentation.  "The usability of this call is very limited. It's
-	 * provided only for completeness of the API. OSS API doesn't have
-	 * any concept of card. Any information returned by this ioctl calld
-	 * is reserved exclusively for the utility programs included in the
-	 * OSS package. Applications should not try to use for this
-	 * information in any ways."
-	 */
-	case SNDCTL_CARDINFO:
-		ret = EINVAL;
-		break;
-	/**
 	 * @note The S/PDIF interface ioctls, @c SNDCTL_DSP_READCTL and
 	 * @c SNDCTL_DSP_WRITECTL have been omitted at the suggestion of
 	 * 4Front Technologies.
@@ -2282,13 +2275,14 @@ dsp_oss_audioinfo(struct cdev *i_dev, os
 			/*
 			 * These flags stolen from SNDCTL_DSP_GETCAPS handler.
 			 * Note, however, that a single channel operates in
-			 * only one direction, so DSP_CAP_DUPLEX is out.
+			 * only one direction, so PCM_CAP_DUPLEX is out.
 			 */
 			/**
 			 * @todo @c SNDCTL_AUDIOINFO::caps - Make drivers keep
 			 *       these in pcmchan::caps?
 			 */
-			ai->caps = DSP_CAP_REALTIME | DSP_CAP_MMAP | DSP_CAP_TRIGGER;
+			ai->caps = PCM_CAP_REALTIME | PCM_CAP_MMAP | PCM_CAP_TRIGGER |
+			    ((ch->direction == PCMDIR_PLAY) ? PCM_CAP_OUTPUT : PCM_CAP_INPUT);
 
 			/*
 			 * Collect formats supported @b natively by the
@@ -2369,7 +2363,11 @@ dsp_oss_audioinfo(struct cdev *i_dev, os
 
 			for (i = 0; i < ai->nrates; i++)
 				ai->rates[i] = rates[i];
+			
+			ai->next_play_engine = 0;
+			ai->next_rec_engine = 0;
 
+printf("flags: %08x %d\n", ch->flags, ai->busy);
 			CHN_UNLOCK(ch);
 		}
 

Modified: head/sys/dev/sound/pcm/mixer.c
==============================================================================
--- head/sys/dev/sound/pcm/mixer.c	Sat Jan 10 17:56:50 2009	(r187029)
+++ head/sys/dev/sound/pcm/mixer.c	Sat Jan 10 18:19:22 2009	(r187030)
@@ -1022,6 +1022,27 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_lo
 	int ret, *arg_i = (int *)arg;
 	int v = -1, j = cmd & 0xff;
 
+	/*
+	 * Certain ioctls may be made on any type of device (audio, mixer,
+	 * and MIDI).  Handle those special cases here.
+	 */
+	if (IOCGROUP(cmd) == 'X') {
+		switch (cmd) {
+		case SNDCTL_SYSINFO:
+			sound_oss_sysinfo((oss_sysinfo *)arg);
+			return (0);
+		case SNDCTL_CARDINFO:
+			return (sound_oss_card_info((oss_card_info *)arg));
+	    	case SNDCTL_AUDIOINFO:
+	    	case SNDCTL_AUDIOINFO_EX:
+	    	case SNDCTL_ENGINEINFO:
+			return (dsp_oss_audioinfo(i_dev, (oss_audioinfo *)arg));
+		case SNDCTL_MIXERINFO:
+			return (mixer_oss_mixerinfo(i_dev, (oss_mixerinfo *)arg));
+		}
+		return (ENXIO);
+	}
+
 	m = i_dev->si_drv1;
 
 	if (m == NULL)
@@ -1033,11 +1054,6 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_lo
 		return (EBADF);
 	}
 
-	if (cmd == SNDCTL_MIXERINFO) {
-		snd_mtxunlock(m->lock);
-		return (mixer_oss_mixerinfo(i_dev, (oss_mixerinfo *)arg));
-	}
-
 	if ((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0)) {
 		if (j == SOUND_MIXER_RECSRC)
 			ret = mixer_setrecsrc(m, *arg_i);
@@ -1075,15 +1091,6 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_lo
 
 	switch (cmd) {
  	/** @todo Double check return values, error codes. */
-	case SNDCTL_SYSINFO:
-		snd_mtxunlock(m->lock);
-		sound_oss_sysinfo((oss_sysinfo *)arg);
-		return (ret);
-		break;
-	case SNDCTL_AUDIOINFO:
-		snd_mtxunlock(m->lock);
-		return (dsp_oss_audioinfo(i_dev, (oss_audioinfo *)arg));
-		break;
 	case SNDCTL_DSP_GET_RECSRC_NAMES:
 		bcopy((void *)&m->enuminfo, arg, sizeof(oss_mixer_enuminfo));
 		break;

Modified: head/sys/dev/sound/pcm/sound.c
==============================================================================
--- head/sys/dev/sound/pcm/sound.c	Sat Jan 10 17:56:50 2009	(r187029)
+++ head/sys/dev/sound/pcm/sound.c	Sat Jan 10 18:19:22 2009	(r187030)
@@ -1493,6 +1493,38 @@ sound_oss_sysinfo(oss_sysinfo *si)
 		si->filler[i] = -1;
 }
 
+int
+sound_oss_card_info(oss_card_info *si)
+{
+	struct snddev_info *d;
+	int i, ncards;
+	
+	ncards = 0;
+
+	for (i = 0; pcm_devclass != NULL &&
+	    i < devclass_get_maxunit(pcm_devclass); i++) {
+		d = devclass_get_softc(pcm_devclass, i);
+		if (!PCM_REGISTERED(d))
+			continue;
+
+		if (ncards++ != si->card)
+			continue;
+
+		mtx_assert(d->lock, MA_NOTOWNED);
+		pcm_lock(d);
+		
+		strlcpy(si->shortname, device_get_nameunit(d->dev),
+		    sizeof(si->shortname));
+		strlcpy(si->longname, device_get_desc(d->dev),
+		    sizeof(si->longname));
+		strlcpy(si->hw_info, d->status, sizeof(si->hw_info));
+		si->intr_count = si->ack_count = 0;
+		pcm_unlock(d);
+		return (0);
+	}
+	return (ENXIO);
+}
+
 /************************************************************************/
 
 static int

Modified: head/sys/dev/sound/pcm/sound.h
==============================================================================
--- head/sys/dev/sound/pcm/sound.h	Sat Jan 10 17:56:50 2009	(r187029)
+++ head/sys/dev/sound/pcm/sound.h	Sat Jan 10 18:19:22 2009	(r187030)
@@ -601,6 +601,7 @@ struct snddev_info {
 };
 
 void	sound_oss_sysinfo(oss_sysinfo *);
+int	sound_oss_card_info(oss_card_info *);
 
 #ifdef	PCM_DEBUG_MTX
 #define	pcm_lock(d) mtx_lock(((struct snddev_info *)(d))->lock)

Modified: head/sys/sys/soundcard.h
==============================================================================
--- head/sys/sys/soundcard.h	Sat Jan 10 17:56:50 2009	(r187029)
+++ head/sys/sys/soundcard.h	Sat Jan 10 18:19:22 2009	(r187030)
@@ -801,18 +801,91 @@ typedef struct audio_buf_info {
 #define SNDCTL_DSP_NONBLOCK	_IO  ('P',14)
 
 #define SNDCTL_DSP_GETCAPS	_IOR ('P',15, int)
-#define DSP_CAP_REVISION	0x000000ff /* revision level (0 to 255) */
-#define DSP_CAP_DUPLEX		0x00000100 /* Full duplex record/playback */
-#define DSP_CAP_REALTIME	0x00000200 /* Real time capability */
-#define DSP_CAP_BATCH		0x00000400
-    /*
-     * Device has some kind of internal buffers which may
-     * cause some delays and decrease precision of timing
-     */
-#define DSP_CAP_COPROC		0x00000800
-    /* Has a coprocessor, sometimes it's a DSP but usually not */
-#define DSP_CAP_TRIGGER		0x00001000 /* Supports SETTRIGGER */
-#define DSP_CAP_MMAP 0x00002000 /* Supports mmap() */
+#	define PCM_CAP_REVISION		0x000000ff	/* Bits for revision level (0 to 255) */
+#	define PCM_CAP_DUPLEX		0x00000100	/* Full duplex record/playback */
+#	define PCM_CAP_REALTIME		0x00000200	/* Not in use */
+#	define PCM_CAP_BATCH		0x00000400	/* Device has some kind of */
+							/* internal buffers which may */
+							/* cause some delays and */
+							/* decrease precision of timing */
+#	define PCM_CAP_COPROC		0x00000800	/* Has a coprocessor */
+							/* Sometimes it's a DSP */
+							/* but usually not */
+#	define PCM_CAP_TRIGGER		0x00001000	/* Supports SETTRIGGER */
+#	define PCM_CAP_MMAP		0x00002000	/* Supports mmap() */
+#	define PCM_CAP_MULTI		0x00004000	/* Supports multiple open */
+#	define PCM_CAP_BIND		0x00008000	/* Supports binding to front/rear/center/lfe */
+#   	define PCM_CAP_INPUT		0x00010000	/* Supports recording */
+#   	define PCM_CAP_OUTPUT		0x00020000	/* Supports playback */
+#	define PCM_CAP_VIRTUAL		0x00040000	/* Virtual device */
+/* 0x00040000 and 0x00080000 reserved for future use */
+
+/* Analog/digital control capabilities */
+#	define PCM_CAP_ANALOGOUT	0x00100000
+#	define PCM_CAP_ANALOGIN		0x00200000
+#	define PCM_CAP_DIGITALOUT	0x00400000
+#	define PCM_CAP_DIGITALIN	0x00800000
+#	define PCM_CAP_ADMASK		0x00f00000
+/*
+ * NOTE! (capabilities & PCM_CAP_ADMASK)==0 means just that the
+ * digital/analog interface control features are not supported by the 
+ * device/driver. However the device still supports analog, digital or
+ * both inputs/outputs (depending on the device). See the OSS Programmer's
+ * Guide for full details.
+ */
+#	define PCM_CAP_SPECIAL		0x01000000	/* Not for ordinary "multimedia" use */
+#	define PCM_CAP_SHADOW		0x00000000	/* OBSOLETE */
+
+/*
+ * Preferred channel usage. These bits can be used to
+ * give recommendations to the application. Used by few drivers.
+ * For example if ((caps & DSP_CH_MASK) == DSP_CH_MONO) means that
+ * the device works best in mono mode. However it doesn't necessarily mean
+ * that the device cannot be used in stereo. These bits should only be used
+ * by special applications such as multi track hard disk recorders to find
+ * out the initial setup. However the user should be able to override this
+ * selection.
+ *
+ * To find out which modes are actually supported the application should 
+ * try to select them using SNDCTL_DSP_CHANNELS.
+ */
+#	define DSP_CH_MASK		0x06000000	/* Mask */
+#	define DSP_CH_ANY		0x00000000	/* No preferred mode */
+#	define DSP_CH_MONO		0x02000000
+#	define DSP_CH_STEREO		0x04000000
+#	define DSP_CH_MULTI		0x06000000	/* More than two channels */
+
+#	define PCM_CAP_HIDDEN		0x08000000	/* Hidden device */
+#	define PCM_CAP_FREERATE		0x10000000
+#	define PCM_CAP_MODEM		0x20000000	/* Modem device */
+#	define PCM_CAP_DEFAULT		0x40000000	/* "Default" device */
+
+/*
+ * The PCM_CAP_* capability names were known as DSP_CAP_* prior OSS 4.0
+ * so it's necessary to define the older names too.
+ */
+#define DSP_CAP_ADMASK		PCM_CAP_ADMASK
+#define DSP_CAP_ANALOGIN	PCM_CAP_ANALOGIN
+#define DSP_CAP_ANALOGOUT	PCM_CAP_ANALOGOUT
+#define DSP_CAP_BATCH		PCM_CAP_BATCH
+#define DSP_CAP_BIND		PCM_CAP_BIND
+#define DSP_CAP_COPROC		PCM_CAP_COPROC
+#define DSP_CAP_DEFAULT		PCM_CAP_DEFAULT
+#define DSP_CAP_DIGITALIN	PCM_CAP_DIGITALIN
+#define DSP_CAP_DIGITALOUT	PCM_CAP_DIGITALOUT
+#define DSP_CAP_DUPLEX		PCM_CAP_DUPLEX
+#define DSP_CAP_FREERATE	PCM_CAP_FREERATE
+#define DSP_CAP_HIDDEN		PCM_CAP_HIDDEN
+#define DSP_CAP_INPUT		PCM_CAP_INPUT
+#define DSP_CAP_MMAP		PCM_CAP_MMAP
+#define DSP_CAP_MODEM		PCM_CAP_MODEM
+#define DSP_CAP_MULTI		PCM_CAP_MULTI
+#define DSP_CAP_OUTPUT		PCM_CAP_OUTPUT
+#define DSP_CAP_REALTIME	PCM_CAP_REALTIME
+#define DSP_CAP_REVISION	PCM_CAP_REVISION
+#define DSP_CAP_SHADOW		PCM_CAP_SHADOW
+#define DSP_CAP_TRIGGER		PCM_CAP_TRIGGER
+#define DSP_CAP_VIRTUAL		PCM_CAP_VIRTUAL
 
 /*
  * What do these function do ?
@@ -1785,7 +1858,9 @@ typedef struct oss_audioinfo
 	int		latency;	/* In usecs, -1=unknown */
 	oss_devnode_t	devnode;	/* Device special file name (inside
 					   /dev) */
-	int filler[186];
+	int next_play_engine;
+	int next_rec_engine;
+	int filler[184];
 } oss_audioinfo;
 
 typedef struct oss_mixerinfo
@@ -1851,7 +1926,9 @@ typedef struct oss_card_info
   char shortname[16];
   char longname[128];
   int flags;
-  int filler[256];
+  char hw_info[400];
+  int intr_count, ack_count;
+  int filler[154];
 } oss_card_info;
 
 #define SNDCTL_SYSINFO          _IOR ('X', 1, oss_sysinfo)
@@ -1868,6 +1945,8 @@ typedef struct oss_card_info
 #define SNDCTL_MIDIINFO		_IOWR('X', 9, oss_midi_info)
 #define SNDCTL_MIXERINFO	_IOWR('X',10, oss_mixerinfo)
 #define SNDCTL_CARDINFO		_IOWR('X',11, oss_card_info)
+#define SNDCTL_ENGINEINFO	_IOWR('X',12, oss_audioinfo)
+#define SNDCTL_AUDIOINFO_EX	_IOWR('X',13, oss_audioinfo)
 
 /*
  * Few more "globally" available ioctl calls.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200901101819.n0AIJMsP005436>