Hi all, Here's a patch that brings the USB audio driver in 2.4.11-pre2 up to the same level as 2.4.10-ac4. Since I don't have a audio device, can someone please test this and let me know if things still work before I send it to Linus?
thanks, greg k-h diff -Naur -X dontdiff linux-2.4/drivers/usb/audio.c linux-2.4-ac/drivers/usb/audio.c --- linux-2.4/drivers/usb/audio.c Tue Sep 11 13:12:51 2001 +++ linux-2.4-ac/drivers/usb/audio.c Mon Oct 1 08:30:42 2001 @@ -3,7 +3,7 @@ /* * audio.c -- USB Audio Class driver * - * Copyright (C) 1999, 2000 + * Copyright (C) 1999, 2000, 2001 * Alan Cox ([EMAIL PROTECTED]) * Thomas Sailer ([EMAIL PROTECTED]) * @@ -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 <[EMAIL PROTECTED]> + * 2001-06-16: Bryce Nesbitt <[EMAIL PROTECTED]> + * 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"); _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel