hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/sound/usb/stream.c
....@@ -1,17 +1,5 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
2
- * This program is free software; you can redistribute it and/or modify
3
- * it under the terms of the GNU General Public License as published by
4
- * the Free Software Foundation; either version 2 of the License, or
5
- * (at your option) any later version.
6
- *
7
- * This program is distributed in the hope that it will be useful,
8
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
- * GNU General Public License for more details.
11
- *
12
- * You should have received a copy of the GNU General Public License
13
- * along with this program; if not, write to the Free Software
14
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
153 */
164
175
....@@ -38,6 +26,15 @@
3826 #include "clock.h"
3927 #include "stream.h"
4028 #include "power.h"
29
+#include "media.h"
30
+
31
+static void audioformat_free(struct audioformat *fp)
32
+{
33
+ list_del(&fp->list); /* unlink for avoiding double-free */
34
+ kfree(fp->rate_table);
35
+ kfree(fp->chmap);
36
+ kfree(fp);
37
+}
4138
4239 /*
4340 * free a substream
....@@ -48,13 +45,11 @@
4845
4946 if (!subs->num_formats)
5047 return; /* not initialized */
51
- list_for_each_entry_safe(fp, n, &subs->fmt_list, list) {
52
- kfree(fp->rate_table);
53
- kfree(fp->chmap);
54
- kfree(fp);
55
- }
48
+ list_for_each_entry_safe(fp, n, &subs->fmt_list, list)
49
+ audioformat_free(fp);
5650 kfree(subs->rate_list.list);
5751 kfree(subs->str_pd);
52
+ snd_media_stream_delete(subs);
5853 }
5954
6055
....@@ -73,7 +68,6 @@
7368 {
7469 struct snd_usb_stream *stream = pcm->private_data;
7570 struct snd_usb_audio *chip;
76
-
7771 if (stream) {
7872 mutex_lock(&stream->chip->dev_lock);
7973 chip = stream->chip;
....@@ -104,6 +98,7 @@
10498 subs->tx_length_quirk = as->chip->tx_length_quirk;
10599 subs->speed = snd_usb_get_speed(subs->dev);
106100 subs->pkt_offset_adj = 0;
101
+ subs->stream_offset_adj = 0;
107102
108103 snd_usb_set_pcm_ops(as->pcm, stream);
109104
....@@ -505,6 +500,10 @@
505500 return 0;
506501 }
507502 }
503
+
504
+ if (chip->card->registered)
505
+ chip->need_delayed_register = true;
506
+
508507 /* look for an empty stream */
509508 list_for_each_entry(as, &chip->pcm_list, list) {
510509 if (as->fmt_type != fp->fmt_type)
....@@ -847,8 +846,7 @@
847846 /* ok, let's parse further... */
848847 if (snd_usb_parse_audio_format(chip, fp, format,
849848 fmt, stream) < 0) {
850
- kfree(fp->rate_table);
851
- kfree(fp);
849
+ audioformat_free(fp);
852850 return NULL;
853851 }
854852
....@@ -1059,9 +1057,7 @@
10591057
10601058 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
10611059 if (!pd) {
1062
- kfree(fp->chmap);
1063
- kfree(fp->rate_table);
1064
- kfree(fp);
1060
+ audioformat_free(fp);
10651061 return NULL;
10661062 }
10671063 pd->pd_id = (stream == SNDRV_PCM_STREAM_PLAYBACK) ?
....@@ -1080,9 +1076,7 @@
10801076 /* ok, let's parse further... */
10811077 if (snd_usb_parse_audio_format_v3(chip, fp, as, stream) < 0) {
10821078 kfree(pd);
1083
- kfree(fp->chmap);
1084
- kfree(fp->rate_table);
1085
- kfree(fp);
1079
+ audioformat_free(fp);
10861080 return NULL;
10871081 }
10881082 }
....@@ -1093,7 +1087,9 @@
10931087 return fp;
10941088 }
10951089
1096
-int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
1090
+static int __snd_usb_parse_audio_interface(struct snd_usb_audio *chip,
1091
+ int iface_no,
1092
+ bool *has_non_pcm, bool non_pcm)
10971093 {
10981094 struct usb_device *dev;
10991095 struct usb_interface *iface;
....@@ -1115,7 +1111,7 @@
11151111 * Dallas DS4201 workaround: It presents 5 altsettings, but the last
11161112 * one misses syncpipe, and does not produce any sound.
11171113 */
1118
- if (chip->usb_id == USB_ID(0x04fa, 0x4201))
1114
+ if (chip->usb_id == USB_ID(0x04fa, 0x4201) && num >= 4)
11191115 num = 4;
11201116
11211117 for (i = 0; i < num; i++) {
....@@ -1156,9 +1152,8 @@
11561152 dev_dbg(&dev->dev, "%u:%d: unknown interface protocol %#02x, assuming v1\n",
11571153 iface_no, altno, protocol);
11581154 protocol = UAC_VERSION_1;
1159
- /* fall through */
1155
+ fallthrough;
11601156 case UAC_VERSION_1:
1161
- /* fall through */
11621157 case UAC_VERSION_2: {
11631158 int bm_quirk = 0;
11641159
....@@ -1194,6 +1189,16 @@
11941189 else if (IS_ERR(fp))
11951190 return PTR_ERR(fp);
11961191
1192
+ if (fp->fmt_type != UAC_FORMAT_TYPE_I)
1193
+ *has_non_pcm = true;
1194
+ if ((fp->fmt_type == UAC_FORMAT_TYPE_I) == non_pcm) {
1195
+ audioformat_free(fp);
1196
+ kfree(pd);
1197
+ fp = NULL;
1198
+ pd = NULL;
1199
+ continue;
1200
+ }
1201
+
11971202 dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint);
11981203 if (protocol == UAC_VERSION_3)
11991204 err = snd_usb_add_audio_stream_v3(chip, stream, fp, pd);
....@@ -1201,11 +1206,8 @@
12011206 err = snd_usb_add_audio_stream(chip, stream, fp);
12021207
12031208 if (err < 0) {
1204
- list_del(&fp->list); /* unlink for avoiding double-free */
1209
+ audioformat_free(fp);
12051210 kfree(pd);
1206
- kfree(fp->rate_table);
1207
- kfree(fp->chmap);
1208
- kfree(fp);
12091211 return err;
12101212 }
12111213 /* try to set the interface... */
....@@ -1216,3 +1218,23 @@
12161218 return 0;
12171219 }
12181220
1221
+int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
1222
+{
1223
+ int err;
1224
+ bool has_non_pcm = false;
1225
+
1226
+ /* parse PCM formats */
1227
+ err = __snd_usb_parse_audio_interface(chip, iface_no, &has_non_pcm, false);
1228
+ if (err < 0)
1229
+ return err;
1230
+
1231
+ if (has_non_pcm) {
1232
+ /* parse non-PCM formats */
1233
+ err = __snd_usb_parse_audio_interface(chip, iface_no, &has_non_pcm, true);
1234
+ if (err < 0)
1235
+ return err;
1236
+ }
1237
+
1238
+ return 0;
1239
+}
1240
+