Merge tag 'rpmsg-3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/ohad/rpmsg
[cascardo/linux.git] / sound / usb / stream.c
index ad181d5..7db2f89 100644 (file)
  */
 static void free_substream(struct snd_usb_substream *subs)
 {
-       struct list_head *p, *n;
+       struct audioformat *fp, *n;
 
        if (!subs->num_formats)
                return; /* not initialized */
-       list_for_each_safe(p, n, &subs->fmt_list) {
-               struct audioformat *fp = list_entry(p, struct audioformat, list);
+       list_for_each_entry_safe(fp, n, &subs->fmt_list, list) {
                kfree(fp->rate_table);
                kfree(fp->chmap);
                kfree(fp);
@@ -94,6 +93,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
        subs->dev = as->chip->dev;
        subs->txfr_quirk = as->chip->txfr_quirk;
        subs->speed = snd_usb_get_speed(subs->dev);
+       subs->pkt_offset_adj = 0;
 
        snd_usb_set_pcm_ops(as->pcm, stream);
 
@@ -313,14 +313,12 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
                             int stream,
                             struct audioformat *fp)
 {
-       struct list_head *p;
        struct snd_usb_stream *as;
        struct snd_usb_substream *subs;
        struct snd_pcm *pcm;
        int err;
 
-       list_for_each(p, &chip->pcm_list) {
-               as = list_entry(p, struct snd_usb_stream, list);
+       list_for_each_entry(as, &chip->pcm_list, list) {
                if (as->fmt_type != fp->fmt_type)
                        continue;
                subs = &as->substream[stream];
@@ -332,8 +330,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
                }
        }
        /* look for an empty stream */
-       list_for_each(p, &chip->pcm_list) {
-               as = list_entry(p, struct snd_usb_stream, list);
+       list_for_each_entry(as, &chip->pcm_list, list) {
                if (as->fmt_type != fp->fmt_type)
                        continue;
                subs = &as->substream[stream];
@@ -396,6 +393,14 @@ static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip,
        if (!csep && altsd->bNumEndpoints >= 2)
                csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT);
 
+       /*
+        * If we can't locate the USB_DT_CS_ENDPOINT descriptor in the extra
+        * bytes after the first endpoint, go search the entire interface.
+        * Some devices have it directly *before* the standard endpoint.
+        */
+       if (!csep)
+               csep = snd_usb_find_desc(alts->extra, alts->extralen, NULL, USB_DT_CS_ENDPOINT);
+
        if (!csep || csep->bLength < 7 ||
            csep->bDescriptorSubtype != UAC_EP_GENERAL) {
                snd_printk(KERN_WARNING "%d:%u:%d : no or invalid"
@@ -463,7 +468,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
        struct usb_host_interface *alts;
        struct usb_interface_descriptor *altsd;
        int i, altno, err, stream;
-       int format = 0, num_channels = 0;
+       unsigned int format = 0, num_channels = 0;
        struct audioformat *fp = NULL;
        int num, protocol, clock = 0;
        struct uac_format_type_i_continuous_descriptor *fmt;