From 1543e317f1da31b75942316931e8f491a8920811 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 04 Jan 2024 10:08:02 +0000
Subject: [PATCH] disable FB
---
kernel/sound/usb/stream.c | 92 ++++++++++++++++++++++++++++-----------------
1 files changed, 57 insertions(+), 35 deletions(-)
diff --git a/kernel/sound/usb/stream.c b/kernel/sound/usb/stream.c
index 3c55274..d1a8dd5 100644
--- a/kernel/sound/usb/stream.c
+++ b/kernel/sound/usb/stream.c
@@ -1,17 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@@ -38,6 +26,15 @@
#include "clock.h"
#include "stream.h"
#include "power.h"
+#include "media.h"
+
+static void audioformat_free(struct audioformat *fp)
+{
+ list_del(&fp->list); /* unlink for avoiding double-free */
+ kfree(fp->rate_table);
+ kfree(fp->chmap);
+ kfree(fp);
+}
/*
* free a substream
@@ -48,13 +45,11 @@
if (!subs->num_formats)
return; /* not initialized */
- list_for_each_entry_safe(fp, n, &subs->fmt_list, list) {
- kfree(fp->rate_table);
- kfree(fp->chmap);
- kfree(fp);
- }
+ list_for_each_entry_safe(fp, n, &subs->fmt_list, list)
+ audioformat_free(fp);
kfree(subs->rate_list.list);
kfree(subs->str_pd);
+ snd_media_stream_delete(subs);
}
@@ -73,7 +68,6 @@
{
struct snd_usb_stream *stream = pcm->private_data;
struct snd_usb_audio *chip;
-
if (stream) {
mutex_lock(&stream->chip->dev_lock);
chip = stream->chip;
@@ -104,6 +98,7 @@
subs->tx_length_quirk = as->chip->tx_length_quirk;
subs->speed = snd_usb_get_speed(subs->dev);
subs->pkt_offset_adj = 0;
+ subs->stream_offset_adj = 0;
snd_usb_set_pcm_ops(as->pcm, stream);
@@ -505,6 +500,10 @@
return 0;
}
}
+
+ if (chip->card->registered)
+ chip->need_delayed_register = true;
+
/* look for an empty stream */
list_for_each_entry(as, &chip->pcm_list, list) {
if (as->fmt_type != fp->fmt_type)
@@ -847,8 +846,7 @@
/* ok, let's parse further... */
if (snd_usb_parse_audio_format(chip, fp, format,
fmt, stream) < 0) {
- kfree(fp->rate_table);
- kfree(fp);
+ audioformat_free(fp);
return NULL;
}
@@ -1059,9 +1057,7 @@
pd = kzalloc(sizeof(*pd), GFP_KERNEL);
if (!pd) {
- kfree(fp->chmap);
- kfree(fp->rate_table);
- kfree(fp);
+ audioformat_free(fp);
return NULL;
}
pd->pd_id = (stream == SNDRV_PCM_STREAM_PLAYBACK) ?
@@ -1080,9 +1076,7 @@
/* ok, let's parse further... */
if (snd_usb_parse_audio_format_v3(chip, fp, as, stream) < 0) {
kfree(pd);
- kfree(fp->chmap);
- kfree(fp->rate_table);
- kfree(fp);
+ audioformat_free(fp);
return NULL;
}
}
@@ -1093,7 +1087,9 @@
return fp;
}
-int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
+static int __snd_usb_parse_audio_interface(struct snd_usb_audio *chip,
+ int iface_no,
+ bool *has_non_pcm, bool non_pcm)
{
struct usb_device *dev;
struct usb_interface *iface;
@@ -1115,7 +1111,7 @@
* Dallas DS4201 workaround: It presents 5 altsettings, but the last
* one misses syncpipe, and does not produce any sound.
*/
- if (chip->usb_id == USB_ID(0x04fa, 0x4201))
+ if (chip->usb_id == USB_ID(0x04fa, 0x4201) && num >= 4)
num = 4;
for (i = 0; i < num; i++) {
@@ -1156,9 +1152,8 @@
dev_dbg(&dev->dev, "%u:%d: unknown interface protocol %#02x, assuming v1\n",
iface_no, altno, protocol);
protocol = UAC_VERSION_1;
- /* fall through */
+ fallthrough;
case UAC_VERSION_1:
- /* fall through */
case UAC_VERSION_2: {
int bm_quirk = 0;
@@ -1194,6 +1189,16 @@
else if (IS_ERR(fp))
return PTR_ERR(fp);
+ if (fp->fmt_type != UAC_FORMAT_TYPE_I)
+ *has_non_pcm = true;
+ if ((fp->fmt_type == UAC_FORMAT_TYPE_I) == non_pcm) {
+ audioformat_free(fp);
+ kfree(pd);
+ fp = NULL;
+ pd = NULL;
+ continue;
+ }
+
dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint);
if (protocol == UAC_VERSION_3)
err = snd_usb_add_audio_stream_v3(chip, stream, fp, pd);
@@ -1201,11 +1206,8 @@
err = snd_usb_add_audio_stream(chip, stream, fp);
if (err < 0) {
- list_del(&fp->list); /* unlink for avoiding double-free */
+ audioformat_free(fp);
kfree(pd);
- kfree(fp->rate_table);
- kfree(fp->chmap);
- kfree(fp);
return err;
}
/* try to set the interface... */
@@ -1216,3 +1218,23 @@
return 0;
}
+int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
+{
+ int err;
+ bool has_non_pcm = false;
+
+ /* parse PCM formats */
+ err = __snd_usb_parse_audio_interface(chip, iface_no, &has_non_pcm, false);
+ if (err < 0)
+ return err;
+
+ if (has_non_pcm) {
+ /* parse non-PCM formats */
+ err = __snd_usb_parse_audio_interface(chip, iface_no, &has_non_pcm, true);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
--
Gitblit v1.6.2