patch-2.4.11-dontuse linux/drivers/usb/audio.c
Next file: linux/drivers/usb/dsbr100.c
Previous file: linux/drivers/usb/acm.c
Back to the patch index
Back to the overall index
- Lines: 337
- Date:
Fri Oct 5 12:04:50 2001
- Orig file:
v2.4.10/linux/drivers/usb/audio.c
- Orig date:
Tue Jul 3 17:08:21 2001
diff -u --recursive --new-file v2.4.10/linux/drivers/usb/audio.c linux/drivers/usb/audio.c
@@ -3,7 +3,7 @@
/*
* audio.c -- USB Audio Class driver
*
- * Copyright (C) 1999, 2000
+ * Copyright (C) 1999, 2000, 2001
* Alan Cox (alan@lxorguk.ukuu.org.uk)
* Thomas Sailer (sailer@ife.ee.ethz.ch)
*
@@ -12,6 +12,8 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
+ * Debugging:
+ * Use the 'lsusb' utility to dump the descriptors.
*
* 1999-09-07: Alan Cox
* Parsing Audio descriptor patch
@@ -92,9 +94,11 @@
* 2000-11-26: Thomas Sailer
* Workaround for Dallas DS4201. The DS4201 uses PCM8 as format tag for
* its 8 bit modes, but expects signed data (and should therefore have used PCM).
- * 2001-04-08: gb
- * Identify version on module load.
- *
+ * 2001-03-10: Thomas Sailer
+ * provide abs function, prevent picking up a bogus kernel macro
+ * for abs. Bug report by Andrew Morton <andrewm@uow.edu.au>
+ * 2001-06-16: Bryce Nesbitt <bryce@obviously.com>
+ * Fix SNDCTL_DSP_STEREO API violation
*/
/*
@@ -205,6 +209,9 @@
#define dprintk(x)
+#undef abs
+extern int abs(int __x) __attribute__ ((__const__)); /* Shut up warning */
+
/* --------------------------------------------------------------------- */
/*
@@ -390,6 +397,17 @@
/* --------------------------------------------------------------------- */
+/* prevent picking up a bogus abs macro */
+#undef abs
+extern inline int abs(int x)
+{
+ if (x < 0)
+ return -x;
+ return x;
+}
+
+/* --------------------------------------------------------------------- */
+
extern inline unsigned ld2(unsigned int x)
{
unsigned r = 0;
@@ -485,10 +503,10 @@
}
db->bufsize = nr << PAGE_SHIFT;
db->ready = 1;
- dprintk((KERN_DEBUG "dmabuf_init: bytepersec %d bufs %d ossfragshift %d ossmaxfrags %d "
- "fragshift %d fragsize %d numfrag %d dmasize %d bufsize %d fmt 0x%x\n",
+ dprintk((KERN_DEBUG "usbaudio: dmabuf_init bytepersec %d bufs %d ossfragshift %d ossmaxfrags %d "
+ "fragshift %d fragsize %d numfrag %d dmasize %d bufsize %d fmt 0x%x srate %d\n",
bytepersec, bufs, db->ossfragshift, db->ossmaxfrags, db->fragshift, db->fragsize,
- db->numfrag, db->dmasize, db->bufsize, db->format));
+ db->numfrag, db->dmasize, db->bufsize, db->format, db->srate));
return 0;
}
@@ -860,9 +878,11 @@
u->dma.count += cnt;
if (u->format == u->dma.format) {
/* we do not need format conversion */
+ dprintk((KERN_DEBUG "usbaudio: no sample format conversion\n"));
dmabuf_copyin(&u->dma, cp, cnt);
} else {
/* we need sampling format conversion */
+ dprintk((KERN_DEBUG "usbaudio: sample format conversion %x != %x\n", u->format, u->dma.format));
usbin_convert(u, cp, scnt);
}
}
@@ -1533,7 +1553,7 @@
d->srate = fmt->sratelo;
if (d->srate > fmt->sratehi)
d->srate = fmt->sratehi;
- dprintk((KERN_DEBUG "usb_audio: set_format_in: usb_set_interface %u %u\n", alts->bInterfaceNumber, fmt->altsetting));
+ dprintk((KERN_DEBUG "usbaudio: set_format_in: usb_set_interface %u %u\n", alts->bInterfaceNumber, fmt->altsetting));
if (usb_set_interface(dev, alts->bInterfaceNumber, fmt->altsetting) < 0) {
printk(KERN_WARNING "usbaudio: usb_set_interface failed, device %d interface %d altsetting %d\n",
dev->devnum, u->interface, fmt->altsetting);
@@ -1628,7 +1648,7 @@
d->srate = fmt->sratelo;
if (d->srate > fmt->sratehi)
d->srate = fmt->sratehi;
- dprintk((KERN_DEBUG "usb_audio: set_format_out: usb_set_interface %u %u\n", alts->bInterfaceNumber, fmt->altsetting));
+ dprintk((KERN_DEBUG "usbaudio: set_format_out: usb_set_interface %u %u\n", alts->bInterfaceNumber, fmt->altsetting));
if (usb_set_interface(dev, u->interface, fmt->altsetting) < 0) {
printk(KERN_WARNING "usbaudio: usb_set_interface failed, device %d interface %d altsetting %d\n",
dev->devnum, u->interface, fmt->altsetting);
@@ -1925,13 +1945,6 @@
/* --------------------------------------------------------------------- */
-static loff_t usb_audio_llseek(struct file *file, loff_t offset, int origin)
-{
- return -ESPIPE;
-}
-
-/* --------------------------------------------------------------------- */
-
static int usb_audio_open_mixdev(struct inode *inode, struct file *file)
{
int minor = MINOR(inode->i_rdev);
@@ -2071,7 +2084,7 @@
static /*const*/ struct file_operations usb_mixer_fops = {
owner: THIS_MODULE,
- llseek: usb_audio_llseek,
+ llseek: no_llseek,
ioctl: usb_audio_ioctl_mixdev,
open: usb_audio_open_mixdev,
release: usb_audio_release_mixdev,
@@ -2341,12 +2354,18 @@
unsigned long flags;
audio_buf_info abinfo;
count_info cinfo;
- int val, val2, mapped, ret;
+ int val = 0;
+ int val2, mapped, ret;
if (!s->usbdev)
return -EIO;
mapped = ((file->f_mode & FMODE_WRITE) && as->usbout.dma.mapped) ||
((file->f_mode & FMODE_READ) && as->usbin.dma.mapped);
+#if 0
+ if (arg)
+ get_user(val, (int *)arg);
+ printk(KERN_DEBUG "usbaudio: usb_audio_ioctl cmd=%x arg=%lx *arg=%d\n", cmd, arg, val)
+#endif
switch (cmd) {
case OSS_GETVERSION:
return put_user(SOUND_VERSION, (int *)arg);
@@ -2388,8 +2407,14 @@
return put_user((file->f_mode & FMODE_READ) ? as->usbin.dma.srate : as->usbout.dma.srate, (int *)arg);
case SNDCTL_DSP_STEREO:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
val2 = (file->f_mode & FMODE_READ) ? as->usbin.dma.format : as->usbout.dma.format;
- if (set_format(as, file->f_mode, val2 | AFMT_STEREO, 0))
+ if (val)
+ val2 |= AFMT_STEREO;
+ else
+ val2 &= ~AFMT_STEREO;
+ if (set_format(as, file->f_mode, val2, 0))
return -EIO;
return 0;
@@ -2590,6 +2615,7 @@
case SOUND_PCM_READ_FILTER:
return -EINVAL;
}
+ dprintk((KERN_DEBUG "usbaudio: usb_audio_ioctl - no command found\n"));
return -ENOIOCTLCMD;
}
@@ -2690,7 +2716,7 @@
static /*const*/ struct file_operations usb_audio_fops = {
owner: THIS_MODULE,
- llseek: usb_audio_llseek,
+ llseek: no_llseek,
read: usb_audio_read,
write: usb_audio_write,
poll: usb_audio_poll,
@@ -2815,8 +2841,10 @@
if (alts->bInterfaceClass != USB_CLASS_AUDIO || alts->bInterfaceSubClass != 2)
continue;
if (alts->bNumEndpoints < 1) {
- printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u does not have an endpoint\n",
- dev->devnum, asifin, i);
+ if (i != 0) { /* altsetting 0 has no endpoints (Section B.3.4.1) */
+ printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u does not have an endpoint\n",
+ dev->devnum, asifin, i);
+ }
continue;
}
if ((alts->endpoint[0].bmAttributes & 0x03) != 0x01 ||
@@ -2871,8 +2899,10 @@
fp->format = format;
fp->altsetting = i;
fp->sratelo = fp->sratehi = fmt[8] | (fmt[9] << 8) | (fmt[10] << 16);
+ printk(KERN_INFO "usbaudio: valid input sample rate %u\n", fp->sratelo);
for (j = fmt[7] ? (fmt[7]-1) : 1; j > 0; j--) {
k = fmt[8+3*j] | (fmt[9+3*j] << 8) | (fmt[10+3*j] << 16);
+ printk(KERN_INFO "usbaudio: valid input sample rate %u\n", k);
if (k > fp->sratehi)
fp->sratehi = k;
if (k < fp->sratelo)
@@ -2902,6 +2932,7 @@
dev->devnum, asifout, i);
continue;
}
+ /* See USB audio formats manual, section 2 */
fmt = find_csinterface_descriptor(buffer, buflen, NULL, AS_GENERAL, asifout, i);
if (!fmt) {
printk(KERN_ERR "usbaudio: device %u interface %u altsetting %u FORMAT_TYPE descriptor not found\n",
@@ -2951,8 +2982,10 @@
fp->format = format;
fp->altsetting = i;
fp->sratelo = fp->sratehi = fmt[8] | (fmt[9] << 8) | (fmt[10] << 16);
+ printk(KERN_INFO "usbaudio: valid output sample rate %u\n", fp->sratelo);
for (j = fmt[7] ? (fmt[7]-1) : 1; j > 0; j--) {
k = fmt[8+3*j] | (fmt[9+3*j] << 8) | (fmt[10+3*j] << 16);
+ printk(KERN_INFO "usbaudio: valid output sample rate %u\n", k);
if (k > fp->sratehi)
fp->sratehi = k;
if (k < fp->sratelo)
@@ -2972,6 +3005,7 @@
kfree(as);
return;
}
+ printk(KERN_INFO "usbaudio: registered dsp 14,%d\n", as->dev_audio);
/* everything successful */
list_add_tail(&as->list, &s->audiolist);
}
@@ -3318,6 +3352,8 @@
state->chconfig = proc[8+proc[6]] | (proc[9+proc[6]] << 8);
}
+
+/* See Audio Class Spec, section 4.3.2.5 */
static void usb_audio_featureunit(struct consmixstate *state, unsigned char *ftr)
{
struct mixerchannel *ch;
@@ -3335,7 +3371,7 @@
if (state->nrchannels > 2)
printk(KERN_WARNING "usbaudio: feature unit %u: OSS mixer interface does not support more than 2 channels\n", ftr[3]);
if (state->nrchannels == 1 && ftr[0] == 7+ftr[5]) {
- printk(KERN_WARNING "usbaudio: workaround for broken Philips Camera Microphone descriptor enabled\n");
+ printk(KERN_DEBUG "usbaudio: workaround for Philips camera microphone descriptor enabled\n");
mchftr = ftr[6];
chftr = 0;
} else {
@@ -3465,7 +3501,7 @@
usb_audio_selectorunit(state, p1);
return;
- case FEATURE_UNIT:
+ case FEATURE_UNIT: /* See USB Audio Class Spec 4.3.2.5 */
if (p1[0] < 7 || p1[0] < 7+p1[5]) {
printk(KERN_ERR "usbaudio: unit %u: invalid FEATURE_UNIT descriptor\n", unitid);
return;
@@ -3517,7 +3553,7 @@
state.buflen = buflen;
state.ctrlif = ctrlif;
set_bit(oterm[3], &state.unitbitmap); /* mark terminal ID as visited */
- printk(KERN_INFO "usbaudio: constructing mixer for Terminal %u type 0x%04x\n",
+ printk(KERN_DEBUG "usbaudio: constructing mixer for Terminal %u type 0x%04x\n",
oterm[3], oterm[4] | (oterm[5] << 8));
usb_audio_recurseunit(&state, oterm[7]);
if (!state.nrmixch) {
@@ -3536,6 +3572,7 @@
kfree(ms);
return;
}
+ printk(KERN_INFO "usbaudio: registered mixer 14,%d\n", ms->dev_mixer);
list_add_tail(&ms->list, &s->mixerlist);
}
@@ -3688,8 +3725,8 @@
return NULL;
}
ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buf, 8);
- if (ret<0) {
- printk(KERN_ERR "usbaudio: cannot get first 8 bytes of config descriptor %d of device %d\n", i, dev->devnum);
+ if (ret < 0) {
+ printk(KERN_ERR "usbaudio: cannot get first 8 bytes of config descriptor %d of device %d (error %d)\n", i, dev->devnum, ret);
return NULL;
}
if (buf[1] != USB_DT_CONFIG || buf[0] < 9) {
@@ -3702,7 +3739,7 @@
ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buffer, buflen);
if (ret < 0) {
kfree(buffer);
- printk(KERN_ERR "usbaudio: cannot get config descriptor %d of device %d\n", i, dev->devnum);
+ printk(KERN_ERR "usbaudio: cannot get config descriptor %d of device %d (error %d)\n", i, dev->devnum, ret);
return NULL;
}
return usb_audio_parsecontrol(dev, buffer, buflen, ifnum);
@@ -3720,11 +3757,11 @@
/* we get called with -1 for every audiostreaming interface registered */
if (s == (struct usb_audio_state *)-1) {
- dprintk((KERN_DEBUG "usb_audio_disconnect: called with -1\n"));
+ dprintk((KERN_DEBUG "usbaudio: note, usb_audio_disconnect called with -1\n"));
return;
}
if (!s->usbdev) {
- dprintk((KERN_DEBUG "usb_audio_disconnect: already called for %p!\n", s));
+ dprintk((KERN_DEBUG "usbaudio: error, usb_audio_disconnect already called for %p!\n", s));
return;
}
down(&open_sem);
@@ -3738,14 +3775,18 @@
usbout_disc(as);
wake_up(&as->usbin.dma.wait);
wake_up(&as->usbout.dma.wait);
- if (as->dev_audio >= 0)
+ if (as->dev_audio >= 0) {
unregister_sound_dsp(as->dev_audio);
+ printk(KERN_INFO "usbaudio: unregister dsp 14,%d\n", as->dev_audio);
+ }
as->dev_audio = -1;
}
for(list = s->mixerlist.next; list != &s->mixerlist; list = list->next) {
ms = list_entry(list, struct usb_mixerdev, list);
- if (ms->dev_mixer >= 0)
+ if (ms->dev_mixer >= 0) {
unregister_sound_mixer(ms->dev_mixer);
+ printk(KERN_INFO "usbaudio: unregister mixer 14,%d\n", ms->dev_mixer);
+ }
ms->dev_mixer = -1;
}
release(s);
@@ -3770,4 +3811,5 @@
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)