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

Reply via email to