staging: ion: add dma_map_sg/dma_umap_sg to map_dma_buf
[firefly-linux-kernel-4.4.55.git] / sound / usb / stream.c
index 8ee14f2365e749d964c369acef5ac45f95a060ca..65627639851642b9fb3e97aeb09d2410aca0332d 100644 (file)
@@ -316,7 +316,9 @@ static struct snd_pcm_chmap_elem *convert_chmap(int channels, unsigned int bits,
 /*
  * add this endpoint to the chip instance.
  * if a stream with the same endpoint already exists, append to it.
- * if not, create a new pcm stream.
+ * if not, create a new pcm stream. note, fp is added to the substream
+ * fmt_list and will be freed on the chip instance release. do not free
+ * fp or do remove it from the substream fmt_list to avoid double-free.
  */
 int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
                             int stream,
@@ -677,11 +679,15 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
                                        * (fp->maxpacksize & 0x7ff);
                fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no);
                fp->clock = clock;
+               INIT_LIST_HEAD(&fp->list);
 
                /* some quirks for attributes here */
 
                switch (chip->usb_id) {
                case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */
+#ifdef CONFIG_HID_RKVR
+               case USB_ID(0x071B, 0x3205): /* RockChip NanoC VR */
+#endif
                        /* Optoplay sets the sample rate attribute although
                         * it seems not supporting it in fact.
                         */
@@ -725,6 +731,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
                dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint);
                err = snd_usb_add_audio_stream(chip, stream, fp);
                if (err < 0) {
+                       list_del(&fp->list); /* unlink for avoiding double-free */
                        kfree(fp->rate_table);
                        kfree(fp->chmap);
                        kfree(fp);