+++ /dev/null
-From db5fbfbb1ae1d24a8543fc2e9552d48c893432f0 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 18 Aug 2022 17:14:33 -0300
-Subject: ALSA: usb-audio: Add quirk to enable Avid Mbox 3 support
-
-From: Conner Knox <connerknoxpublic@gmail.com>
-
-[ Upstream commit b01104fc62b6194c852124f6c6df1c0a5c031fc1 ]
-
-Add support for Avid Mbox3 USB audio interface at 48kHz
-
-Signed-off-by: Conner Knox <connerknoxpublic@gmail.com>
-Link: https://lore.kernel.org/r/20220818201433.16360-1-mbarriolinares@gmail.com
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- sound/usb/quirks-table.h | 76 ++++++++++
- sound/usb/quirks.c | 302 +++++++++++++++++++++++++++++++++++++++
- 2 files changed, 378 insertions(+)
-
-diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
-index 1ac91c46da3c..a7f065567190 100644
---- a/sound/usb/quirks-table.h
-+++ b/sound/usb/quirks-table.h
-@@ -3021,6 +3021,82 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
- }
- }
- },
-+/* DIGIDESIGN MBOX 3 */
-+{
-+ USB_DEVICE(0x0dba, 0x5000),
-+ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
-+ .vendor_name = "Digidesign",
-+ .product_name = "Mbox 3",
-+ .ifnum = QUIRK_ANY_INTERFACE,
-+ .type = QUIRK_COMPOSITE,
-+ .data = (const struct snd_usb_audio_quirk[]) {
-+ {
-+ .ifnum = 0,
-+ .type = QUIRK_IGNORE_INTERFACE
-+ },
-+ {
-+ .ifnum = 1,
-+ .type = QUIRK_IGNORE_INTERFACE
-+ },
-+ {
-+ .ifnum = 2,
-+ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
-+ .data = &(const struct audioformat) {
-+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
-+ .channels = 4,
-+ .iface = 2,
-+ .altsetting = 1,
-+ .altset_idx = 1,
-+ .attributes = 0x00,
-+ .endpoint = 0x01,
-+ .ep_attr = USB_ENDPOINT_XFER_ISOC |
-+ USB_ENDPOINT_SYNC_ASYNC,
-+ .rates = SNDRV_PCM_RATE_48000,
-+ .rate_min = 48000,
-+ .rate_max = 48000,
-+ .nr_rates = 1,
-+ .rate_table = (unsigned int[]) {
-+ 48000
-+ }
-+ }
-+ },
-+ {
-+ .ifnum = 3,
-+ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
-+ .data = &(const struct audioformat) {
-+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
-+ .channels = 4,
-+ .iface = 3,
-+ .altsetting = 1,
-+ .altset_idx = 1,
-+ .endpoint = 0x81,
-+ .attributes = 0x00,
-+ .ep_attr = USB_ENDPOINT_XFER_ISOC |
-+ USB_ENDPOINT_SYNC_ASYNC,
-+ .maxpacksize = 0x009c,
-+ .rates = SNDRV_PCM_RATE_48000,
-+ .rate_min = 48000,
-+ .rate_max = 48000,
-+ .nr_rates = 1,
-+ .rate_table = (unsigned int[]) {
-+ 48000
-+ }
-+ }
-+ },
-+ {
-+ .ifnum = 4,
-+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
-+ .data = &(const struct snd_usb_midi_endpoint_info) {
-+ .out_cables = 0x0001,
-+ .in_cables = 0x0001
-+ }
-+ },
-+ {
-+ .ifnum = -1
-+ }
-+ }
-+ }
-+},
- {
- /* Tascam US122 MKII - playback-only support */
- USB_DEVICE_VENDOR_SPEC(0x0644, 0x8021),
-diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
-index 41f5d8242478..b571a9c9c319 100644
---- a/sound/usb/quirks.c
-+++ b/sound/usb/quirks.c
-@@ -1024,6 +1024,304 @@ static int snd_usb_axefx3_boot_quirk(struct usb_device *dev)
- return 0;
- }
-
-+static void mbox3_setup_48_24_magic(struct usb_device *dev)
-+{
-+ /* The Mbox 3 is "little endian" */
-+ /* max volume is: 0x0000. */
-+ /* min volume is: 0x0080 (shown in little endian form) */
-+
-+
-+ /* Load 48000Hz rate into buffer */
-+ u8 com_buff[4] = {0x80, 0xbb, 0x00, 0x00};
-+
-+ /* Set 48000Hz sample rate */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 0x01, 0x21, 0x0100, 0x0001, &com_buff, 4); //Is this really needed?
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 0x01, 0x21, 0x0100, 0x8101, &com_buff, 4);
-+
-+ /* Deactivate Tuner */
-+ /* on = 0x01*/
-+ /* off = 0x00*/
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 0x01, 0x21, 0x0003, 0x2001, &com_buff, 1);
-+
-+ /* Set clock source to Internal (as opposed to S/PDIF) */
-+ com_buff[0] = 0x01;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0100, 0x8001, &com_buff, 1);
-+
-+ /* Mute the hardware loopbacks to start the device in a known state. */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue input 1 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0110, 0x4001, &com_buff, 2);
-+ /* Analogue input 1 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0111, 0x4001, &com_buff, 2);
-+ /* Analogue input 2 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0114, 0x4001, &com_buff, 2);
-+ /* Analogue input 2 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0115, 0x4001, &com_buff, 2);
-+ /* Analogue input 3 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0118, 0x4001, &com_buff, 2);
-+ /* Analogue input 3 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0119, 0x4001, &com_buff, 2);
-+ /* Analogue input 4 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011c, 0x4001, &com_buff, 2);
-+ /* Analogue input 4 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011d, 0x4001, &com_buff, 2);
-+
-+ /* Set software sends to output */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ /* Analogue software return 1 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0100, 0x4001, &com_buff, 2);
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue software return 1 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0101, 0x4001, &com_buff, 2);
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue software return 2 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0104, 0x4001, &com_buff, 2);
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ /* Analogue software return 2 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0105, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue software return 3 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0108, 0x4001, &com_buff, 2);
-+ /* Analogue software return 3 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0109, 0x4001, &com_buff, 2);
-+ /* Analogue software return 4 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010c, 0x4001, &com_buff, 2);
-+ /* Analogue software return 4 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010d, 0x4001, &com_buff, 2);
-+
-+ /* Return to muting sends */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue fx return left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0120, 0x4001, &com_buff, 2);
-+ /* Analogue fx return right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0121, 0x4001, &com_buff, 2);
-+
-+ /* Analogue software input 1 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0100, 0x4201, &com_buff, 2);
-+ /* Analogue software input 2 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0101, 0x4201, &com_buff, 2);
-+ /* Analogue software input 3 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0102, 0x4201, &com_buff, 2);
-+ /* Analogue software input 4 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0103, 0x4201, &com_buff, 2);
-+ /* Analogue input 1 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0104, 0x4201, &com_buff, 2);
-+ /* Analogue input 2 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0105, 0x4201, &com_buff, 2);
-+ /* Analogue input 3 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0106, 0x4201, &com_buff, 2);
-+ /* Analogue input 4 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0107, 0x4201, &com_buff, 2);
-+
-+ /* Toggle allowing host control */
-+ com_buff[0] = 0x02;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0000, 0x2001, &com_buff, 1);
-+
-+ /* Do not dim fx returns */
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0002, 0x2001, &com_buff, 1);
-+
-+ /* Do not set fx returns to mono */
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0001, 0x2001, &com_buff, 1);
-+
-+ /* Mute the S/PDIF hardware loopback
-+ * same odd volume logic here as above
-+ */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* S/PDIF hardware input 1 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0112, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 1 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0113, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 2 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0116, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 2 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0117, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 3 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011a, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 3 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011b, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 4 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011e, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 4 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011f, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 1 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0102, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 1 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0103, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 2 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0106, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 2 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0107, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ /* S/PDIF software return 3 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010a, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* S/PDIF software return 3 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010b, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 4 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010e, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ /* S/PDIF software return 4 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010f, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* S/PDIF fx returns left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0122, 0x4001, &com_buff, 2);
-+ /* S/PDIF fx returns right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0123, 0x4001, &com_buff, 2);
-+
-+ /* Set the dropdown "Effect" to the first option */
-+ /* Room1 = 0x00 */
-+ /* Room2 = 0x01 */
-+ /* Room3 = 0x02 */
-+ /* Hall 1 = 0x03 */
-+ /* Hall 2 = 0x04 */
-+ /* Plate = 0x05 */
-+ /* Delay = 0x06 */
-+ /* Echo = 0x07 */
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0200, 0x4301, &com_buff, 1); /* max is 0xff */
-+ /* min is 0x00 */
-+
-+
-+ /* Set the effect duration to 0 */
-+ /* max is 0xffff */
-+ /* min is 0x0000 */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0400, 0x4301, &com_buff, 2);
-+
-+ /* Set the effect volume and feedback to 0 */
-+ /* max is 0xff */
-+ /* min is 0x00 */
-+ com_buff[0] = 0x00;
-+ /* feedback: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0500, 0x4301, &com_buff, 1);
-+ /* volume: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0300, 0x4301, &com_buff, 1);
-+
-+ /* Set soft button hold duration */
-+ /* 0x03 = 250ms */
-+ /* 0x05 = 500ms DEFAULT */
-+ /* 0x08 = 750ms */
-+ /* 0x0a = 1sec */
-+ com_buff[0] = 0x05;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0005, 0x2001, &com_buff, 1);
-+
-+ /* Use dim LEDs for button of state */
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0004, 0x2001, &com_buff, 1);
-+}
-+
-+#define MBOX3_DESCRIPTOR_SIZE 464
-+
-+static int snd_usb_mbox3_boot_quirk(struct usb_device *dev)
-+{
-+ struct usb_host_config *config = dev->actconfig;
-+ int err;
-+ int descriptor_size;
-+
-+ descriptor_size = le16_to_cpu(get_cfg_desc(config)->wTotalLength);
-+
-+ if (descriptor_size != MBOX3_DESCRIPTOR_SIZE) {
-+ dev_err(&dev->dev, "Invalid descriptor size=%d.\n", descriptor_size);
-+ return -ENODEV;
-+ }
-+
-+ dev_dbg(&dev->dev, "device initialised!\n");
-+
-+ err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
-+ &dev->descriptor, sizeof(dev->descriptor));
-+ config = dev->actconfig;
-+ if (err < 0)
-+ dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
-+
-+ err = usb_reset_configuration(dev);
-+ if (err < 0)
-+ dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err);
-+ dev_dbg(&dev->dev, "mbox3_boot: new boot length = %d\n",
-+ le16_to_cpu(get_cfg_desc(config)->wTotalLength));
-+
-+ mbox3_setup_48_24_magic(dev);
-+ dev_info(&dev->dev, "Digidesign Mbox 3: 24bit 48kHz");
-+
-+ return 0; /* Successful boot */
-+}
-
- #define MICROBOOK_BUF_SIZE 128
-
-@@ -1344,6 +1642,10 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
- case USB_ID(0x0dba, 0x3000):
- /* Digidesign Mbox 2 */
- return snd_usb_mbox2_boot_quirk(dev);
-+ case USB_ID(0x0dba, 0x5000):
-+ /* Digidesign Mbox 3 */
-+ return snd_usb_mbox3_boot_quirk(dev);
-+
-
- case USB_ID(0x1235, 0x0010): /* Focusrite Novation Saffire 6 USB */
- case USB_ID(0x1235, 0x0018): /* Focusrite Novation Twitch */
---
-2.35.1
-
drm-prevent-drm_copy_field-to-attempt-copying-a-null.patch
gpu-lontium-lt9611-fix-null-pointer-dereference-in-l.patch
drm-amd-display-fix-overflow-on-min_i64-definition.patch
-alsa-usb-audio-add-quirk-to-enable-avid-mbox-3-suppo.patch
udmabuf-set-ubuf-sg-null-if-the-creation-of-sg-table.patch
drm-bridge-dw_hdmi-only-trigger-hotplug-event-on-lin.patch
drm-vc4-vec-fix-timings-for-vec-modes.patch
+++ /dev/null
-From 2a27106905c25ad4a0f47c0bb5528c1081651acb Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 18 Aug 2022 17:14:33 -0300
-Subject: ALSA: usb-audio: Add quirk to enable Avid Mbox 3 support
-
-From: Conner Knox <connerknoxpublic@gmail.com>
-
-[ Upstream commit b01104fc62b6194c852124f6c6df1c0a5c031fc1 ]
-
-Add support for Avid Mbox3 USB audio interface at 48kHz
-
-Signed-off-by: Conner Knox <connerknoxpublic@gmail.com>
-Link: https://lore.kernel.org/r/20220818201433.16360-1-mbarriolinares@gmail.com
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- sound/usb/quirks-table.h | 76 ++++++++++
- sound/usb/quirks.c | 302 +++++++++++++++++++++++++++++++++++++++
- 2 files changed, 378 insertions(+)
-
-diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
-index f93201a830b5..06dfdd45cff8 100644
---- a/sound/usb/quirks-table.h
-+++ b/sound/usb/quirks-table.h
-@@ -2985,6 +2985,82 @@ YAMAHA_DEVICE(0x7010, "UB99"),
- }
- }
- },
-+/* DIGIDESIGN MBOX 3 */
-+{
-+ USB_DEVICE(0x0dba, 0x5000),
-+ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
-+ .vendor_name = "Digidesign",
-+ .product_name = "Mbox 3",
-+ .ifnum = QUIRK_ANY_INTERFACE,
-+ .type = QUIRK_COMPOSITE,
-+ .data = (const struct snd_usb_audio_quirk[]) {
-+ {
-+ .ifnum = 0,
-+ .type = QUIRK_IGNORE_INTERFACE
-+ },
-+ {
-+ .ifnum = 1,
-+ .type = QUIRK_IGNORE_INTERFACE
-+ },
-+ {
-+ .ifnum = 2,
-+ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
-+ .data = &(const struct audioformat) {
-+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
-+ .channels = 4,
-+ .iface = 2,
-+ .altsetting = 1,
-+ .altset_idx = 1,
-+ .attributes = 0x00,
-+ .endpoint = 0x01,
-+ .ep_attr = USB_ENDPOINT_XFER_ISOC |
-+ USB_ENDPOINT_SYNC_ASYNC,
-+ .rates = SNDRV_PCM_RATE_48000,
-+ .rate_min = 48000,
-+ .rate_max = 48000,
-+ .nr_rates = 1,
-+ .rate_table = (unsigned int[]) {
-+ 48000
-+ }
-+ }
-+ },
-+ {
-+ .ifnum = 3,
-+ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
-+ .data = &(const struct audioformat) {
-+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
-+ .channels = 4,
-+ .iface = 3,
-+ .altsetting = 1,
-+ .altset_idx = 1,
-+ .endpoint = 0x81,
-+ .attributes = 0x00,
-+ .ep_attr = USB_ENDPOINT_XFER_ISOC |
-+ USB_ENDPOINT_SYNC_ASYNC,
-+ .maxpacksize = 0x009c,
-+ .rates = SNDRV_PCM_RATE_48000,
-+ .rate_min = 48000,
-+ .rate_max = 48000,
-+ .nr_rates = 1,
-+ .rate_table = (unsigned int[]) {
-+ 48000
-+ }
-+ }
-+ },
-+ {
-+ .ifnum = 4,
-+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
-+ .data = &(const struct snd_usb_midi_endpoint_info) {
-+ .out_cables = 0x0001,
-+ .in_cables = 0x0001
-+ }
-+ },
-+ {
-+ .ifnum = -1
-+ }
-+ }
-+ }
-+},
- {
- /* Tascam US122 MKII - playback-only support */
- USB_DEVICE_VENDOR_SPEC(0x0644, 0x8021),
-diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
-index 5b4d8f5eade2..194c75c45628 100644
---- a/sound/usb/quirks.c
-+++ b/sound/usb/quirks.c
-@@ -1020,6 +1020,304 @@ static int snd_usb_axefx3_boot_quirk(struct usb_device *dev)
- return 0;
- }
-
-+static void mbox3_setup_48_24_magic(struct usb_device *dev)
-+{
-+ /* The Mbox 3 is "little endian" */
-+ /* max volume is: 0x0000. */
-+ /* min volume is: 0x0080 (shown in little endian form) */
-+
-+
-+ /* Load 48000Hz rate into buffer */
-+ u8 com_buff[4] = {0x80, 0xbb, 0x00, 0x00};
-+
-+ /* Set 48000Hz sample rate */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 0x01, 0x21, 0x0100, 0x0001, &com_buff, 4); //Is this really needed?
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 0x01, 0x21, 0x0100, 0x8101, &com_buff, 4);
-+
-+ /* Deactivate Tuner */
-+ /* on = 0x01*/
-+ /* off = 0x00*/
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 0x01, 0x21, 0x0003, 0x2001, &com_buff, 1);
-+
-+ /* Set clock source to Internal (as opposed to S/PDIF) */
-+ com_buff[0] = 0x01;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0100, 0x8001, &com_buff, 1);
-+
-+ /* Mute the hardware loopbacks to start the device in a known state. */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue input 1 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0110, 0x4001, &com_buff, 2);
-+ /* Analogue input 1 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0111, 0x4001, &com_buff, 2);
-+ /* Analogue input 2 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0114, 0x4001, &com_buff, 2);
-+ /* Analogue input 2 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0115, 0x4001, &com_buff, 2);
-+ /* Analogue input 3 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0118, 0x4001, &com_buff, 2);
-+ /* Analogue input 3 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0119, 0x4001, &com_buff, 2);
-+ /* Analogue input 4 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011c, 0x4001, &com_buff, 2);
-+ /* Analogue input 4 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011d, 0x4001, &com_buff, 2);
-+
-+ /* Set software sends to output */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ /* Analogue software return 1 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0100, 0x4001, &com_buff, 2);
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue software return 1 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0101, 0x4001, &com_buff, 2);
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue software return 2 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0104, 0x4001, &com_buff, 2);
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ /* Analogue software return 2 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0105, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue software return 3 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0108, 0x4001, &com_buff, 2);
-+ /* Analogue software return 3 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0109, 0x4001, &com_buff, 2);
-+ /* Analogue software return 4 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010c, 0x4001, &com_buff, 2);
-+ /* Analogue software return 4 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010d, 0x4001, &com_buff, 2);
-+
-+ /* Return to muting sends */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue fx return left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0120, 0x4001, &com_buff, 2);
-+ /* Analogue fx return right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0121, 0x4001, &com_buff, 2);
-+
-+ /* Analogue software input 1 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0100, 0x4201, &com_buff, 2);
-+ /* Analogue software input 2 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0101, 0x4201, &com_buff, 2);
-+ /* Analogue software input 3 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0102, 0x4201, &com_buff, 2);
-+ /* Analogue software input 4 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0103, 0x4201, &com_buff, 2);
-+ /* Analogue input 1 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0104, 0x4201, &com_buff, 2);
-+ /* Analogue input 2 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0105, 0x4201, &com_buff, 2);
-+ /* Analogue input 3 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0106, 0x4201, &com_buff, 2);
-+ /* Analogue input 4 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0107, 0x4201, &com_buff, 2);
-+
-+ /* Toggle allowing host control */
-+ com_buff[0] = 0x02;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0000, 0x2001, &com_buff, 1);
-+
-+ /* Do not dim fx returns */
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0002, 0x2001, &com_buff, 1);
-+
-+ /* Do not set fx returns to mono */
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0001, 0x2001, &com_buff, 1);
-+
-+ /* Mute the S/PDIF hardware loopback
-+ * same odd volume logic here as above
-+ */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* S/PDIF hardware input 1 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0112, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 1 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0113, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 2 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0116, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 2 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0117, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 3 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011a, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 3 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011b, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 4 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011e, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 4 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011f, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 1 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0102, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 1 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0103, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 2 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0106, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 2 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0107, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ /* S/PDIF software return 3 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010a, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* S/PDIF software return 3 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010b, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 4 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010e, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ /* S/PDIF software return 4 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010f, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* S/PDIF fx returns left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0122, 0x4001, &com_buff, 2);
-+ /* S/PDIF fx returns right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0123, 0x4001, &com_buff, 2);
-+
-+ /* Set the dropdown "Effect" to the first option */
-+ /* Room1 = 0x00 */
-+ /* Room2 = 0x01 */
-+ /* Room3 = 0x02 */
-+ /* Hall 1 = 0x03 */
-+ /* Hall 2 = 0x04 */
-+ /* Plate = 0x05 */
-+ /* Delay = 0x06 */
-+ /* Echo = 0x07 */
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0200, 0x4301, &com_buff, 1); /* max is 0xff */
-+ /* min is 0x00 */
-+
-+
-+ /* Set the effect duration to 0 */
-+ /* max is 0xffff */
-+ /* min is 0x0000 */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0400, 0x4301, &com_buff, 2);
-+
-+ /* Set the effect volume and feedback to 0 */
-+ /* max is 0xff */
-+ /* min is 0x00 */
-+ com_buff[0] = 0x00;
-+ /* feedback: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0500, 0x4301, &com_buff, 1);
-+ /* volume: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0300, 0x4301, &com_buff, 1);
-+
-+ /* Set soft button hold duration */
-+ /* 0x03 = 250ms */
-+ /* 0x05 = 500ms DEFAULT */
-+ /* 0x08 = 750ms */
-+ /* 0x0a = 1sec */
-+ com_buff[0] = 0x05;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0005, 0x2001, &com_buff, 1);
-+
-+ /* Use dim LEDs for button of state */
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0004, 0x2001, &com_buff, 1);
-+}
-+
-+#define MBOX3_DESCRIPTOR_SIZE 464
-+
-+static int snd_usb_mbox3_boot_quirk(struct usb_device *dev)
-+{
-+ struct usb_host_config *config = dev->actconfig;
-+ int err;
-+ int descriptor_size;
-+
-+ descriptor_size = le16_to_cpu(get_cfg_desc(config)->wTotalLength);
-+
-+ if (descriptor_size != MBOX3_DESCRIPTOR_SIZE) {
-+ dev_err(&dev->dev, "Invalid descriptor size=%d.\n", descriptor_size);
-+ return -ENODEV;
-+ }
-+
-+ dev_dbg(&dev->dev, "device initialised!\n");
-+
-+ err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
-+ &dev->descriptor, sizeof(dev->descriptor));
-+ config = dev->actconfig;
-+ if (err < 0)
-+ dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
-+
-+ err = usb_reset_configuration(dev);
-+ if (err < 0)
-+ dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err);
-+ dev_dbg(&dev->dev, "mbox3_boot: new boot length = %d\n",
-+ le16_to_cpu(get_cfg_desc(config)->wTotalLength));
-+
-+ mbox3_setup_48_24_magic(dev);
-+ dev_info(&dev->dev, "Digidesign Mbox 3: 24bit 48kHz");
-+
-+ return 0; /* Successful boot */
-+}
-
- #define MICROBOOK_BUF_SIZE 128
-
-@@ -1324,6 +1622,10 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
- case USB_ID(0x0dba, 0x3000):
- /* Digidesign Mbox 2 */
- return snd_usb_mbox2_boot_quirk(dev);
-+ case USB_ID(0x0dba, 0x5000):
-+ /* Digidesign Mbox 3 */
-+ return snd_usb_mbox3_boot_quirk(dev);
-+
-
- case USB_ID(0x1235, 0x0010): /* Focusrite Novation Saffire 6 USB */
- case USB_ID(0x1235, 0x0018): /* Focusrite Novation Twitch */
---
-2.35.1
-
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- sound/usb/card.c | 32 +++++++++++++++++++++++++-------
- sound/usb/quirks.c | 42 ------------------------------------------
- sound/usb/quirks.h | 2 --
- sound/usb/usbaudio.h | 1 +
+ sound/usb/card.c | 32 +++++++++++++++++++++++++-------
+ sound/usb/quirks.c | 42 ------------------------------------------
+ sound/usb/quirks.h | 2 --
+ sound/usb/usbaudio.h | 1 +
4 files changed, 26 insertions(+), 51 deletions(-)
-diff --git a/sound/usb/card.c b/sound/usb/card.c
-index 713b84d8d42f..207c212eabde 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
-@@ -689,7 +689,7 @@ static bool get_alias_id(struct usb_device *dev, unsigned int *id)
+@@ -689,7 +689,7 @@ static bool get_alias_id(struct usb_devi
return false;
}
{
int i;
unsigned int id, inum;
-@@ -698,14 +698,31 @@ static bool check_delayed_register_option(struct snd_usb_audio *chip, int iface)
+@@ -698,14 +698,31 @@ static bool check_delayed_register_optio
if (delayed_register[i] &&
sscanf(delayed_register[i], "%x:%x", &id, &inum) == 2 &&
id == chip->usb_id)
/* look for the corresponding quirk */
static const struct snd_usb_audio_quirk *
get_alias_quirk(struct usb_device *dev, unsigned int id)
-@@ -812,6 +829,7 @@ static int usb_audio_probe(struct usb_interface *intf,
+@@ -812,6 +829,7 @@ static int usb_audio_probe(struct usb_in
err = -ENODEV;
goto __error;
}
}
if (chip->num_interfaces >= MAX_CARD_INTERFACES) {
-@@ -861,11 +879,11 @@ static int usb_audio_probe(struct usb_interface *intf,
+@@ -861,11 +879,11 @@ static int usb_audio_probe(struct usb_in
chip->need_delayed_register = false; /* clear again */
}
err = snd_card_register(chip->card);
if (err < 0)
goto __error;
-diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
-index 194c75c45628..eadac586bcc8 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
-@@ -2030,48 +2030,6 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
- }
+@@ -1729,48 +1729,6 @@ void snd_usb_audioformat_attributes_quir
}
--/*
+ /*
- * registration quirk:
- * the registration is skipped if a device matches with the given ID,
- * unless the interface reaches to the defined one. This is for delaying
- return false;
-}
-
- /*
+-/*
* driver behavior quirk flags
*/
-diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h
-index 31abb7cb01a5..f9bfd5ac7bab 100644
+ struct usb_audio_quirk_flags_table {
--- a/sound/usb/quirks.h
+++ b/sound/usb/quirks.h
-@@ -48,8 +48,6 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
+@@ -48,8 +48,6 @@ void snd_usb_audioformat_attributes_quir
struct audioformat *fp,
int stream);
void snd_usb_init_quirk_flags(struct snd_usb_audio *chip);
#endif /* __USBAUDIO_QUIRKS_H */
-diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
-index 044cd7ab27cb..39c3c61a7e49 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -37,6 +37,7 @@ struct snd_usb_audio {
int num_suspended_intf;
int sample_rate_read_error;
---
-2.35.1
-
drm-komeda-fix-handling-of-atomic-commits-in-the-ato.patch
gpu-lontium-lt9611-fix-null-pointer-dereference-in-l.patch
drm-amd-display-fix-overflow-on-min_i64-definition.patch
-alsa-usb-audio-add-quirk-to-enable-avid-mbox-3-suppo.patch
udmabuf-set-ubuf-sg-null-if-the-creation-of-sg-table.patch
drm-bridge-dw_hdmi-only-trigger-hotplug-event-on-lin.patch
alsa-usb-audio-register-card-at-the-last-interface.patch
+++ /dev/null
-From 76c10432d14cb66169923c89fdfd7486f6567dd5 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 18 Aug 2022 17:14:33 -0300
-Subject: ALSA: usb-audio: Add quirk to enable Avid Mbox 3 support
-
-From: Conner Knox <connerknoxpublic@gmail.com>
-
-[ Upstream commit b01104fc62b6194c852124f6c6df1c0a5c031fc1 ]
-
-Add support for Avid Mbox3 USB audio interface at 48kHz
-
-Signed-off-by: Conner Knox <connerknoxpublic@gmail.com>
-Link: https://lore.kernel.org/r/20220818201433.16360-1-mbarriolinares@gmail.com
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- sound/usb/quirks-table.h | 76 ++++++++++
- sound/usb/quirks.c | 302 +++++++++++++++++++++++++++++++++++++++
- 2 files changed, 378 insertions(+)
-
-diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
-index f93201a830b5..06dfdd45cff8 100644
---- a/sound/usb/quirks-table.h
-+++ b/sound/usb/quirks-table.h
-@@ -2985,6 +2985,82 @@ YAMAHA_DEVICE(0x7010, "UB99"),
- }
- }
- },
-+/* DIGIDESIGN MBOX 3 */
-+{
-+ USB_DEVICE(0x0dba, 0x5000),
-+ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
-+ .vendor_name = "Digidesign",
-+ .product_name = "Mbox 3",
-+ .ifnum = QUIRK_ANY_INTERFACE,
-+ .type = QUIRK_COMPOSITE,
-+ .data = (const struct snd_usb_audio_quirk[]) {
-+ {
-+ .ifnum = 0,
-+ .type = QUIRK_IGNORE_INTERFACE
-+ },
-+ {
-+ .ifnum = 1,
-+ .type = QUIRK_IGNORE_INTERFACE
-+ },
-+ {
-+ .ifnum = 2,
-+ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
-+ .data = &(const struct audioformat) {
-+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
-+ .channels = 4,
-+ .iface = 2,
-+ .altsetting = 1,
-+ .altset_idx = 1,
-+ .attributes = 0x00,
-+ .endpoint = 0x01,
-+ .ep_attr = USB_ENDPOINT_XFER_ISOC |
-+ USB_ENDPOINT_SYNC_ASYNC,
-+ .rates = SNDRV_PCM_RATE_48000,
-+ .rate_min = 48000,
-+ .rate_max = 48000,
-+ .nr_rates = 1,
-+ .rate_table = (unsigned int[]) {
-+ 48000
-+ }
-+ }
-+ },
-+ {
-+ .ifnum = 3,
-+ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
-+ .data = &(const struct audioformat) {
-+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
-+ .channels = 4,
-+ .iface = 3,
-+ .altsetting = 1,
-+ .altset_idx = 1,
-+ .endpoint = 0x81,
-+ .attributes = 0x00,
-+ .ep_attr = USB_ENDPOINT_XFER_ISOC |
-+ USB_ENDPOINT_SYNC_ASYNC,
-+ .maxpacksize = 0x009c,
-+ .rates = SNDRV_PCM_RATE_48000,
-+ .rate_min = 48000,
-+ .rate_max = 48000,
-+ .nr_rates = 1,
-+ .rate_table = (unsigned int[]) {
-+ 48000
-+ }
-+ }
-+ },
-+ {
-+ .ifnum = 4,
-+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
-+ .data = &(const struct snd_usb_midi_endpoint_info) {
-+ .out_cables = 0x0001,
-+ .in_cables = 0x0001
-+ }
-+ },
-+ {
-+ .ifnum = -1
-+ }
-+ }
-+ }
-+},
- {
- /* Tascam US122 MKII - playback-only support */
- USB_DEVICE_VENDOR_SPEC(0x0644, 0x8021),
-diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
-index 5b4d8f5eade2..194c75c45628 100644
---- a/sound/usb/quirks.c
-+++ b/sound/usb/quirks.c
-@@ -1020,6 +1020,304 @@ static int snd_usb_axefx3_boot_quirk(struct usb_device *dev)
- return 0;
- }
-
-+static void mbox3_setup_48_24_magic(struct usb_device *dev)
-+{
-+ /* The Mbox 3 is "little endian" */
-+ /* max volume is: 0x0000. */
-+ /* min volume is: 0x0080 (shown in little endian form) */
-+
-+
-+ /* Load 48000Hz rate into buffer */
-+ u8 com_buff[4] = {0x80, 0xbb, 0x00, 0x00};
-+
-+ /* Set 48000Hz sample rate */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 0x01, 0x21, 0x0100, 0x0001, &com_buff, 4); //Is this really needed?
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 0x01, 0x21, 0x0100, 0x8101, &com_buff, 4);
-+
-+ /* Deactivate Tuner */
-+ /* on = 0x01*/
-+ /* off = 0x00*/
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 0x01, 0x21, 0x0003, 0x2001, &com_buff, 1);
-+
-+ /* Set clock source to Internal (as opposed to S/PDIF) */
-+ com_buff[0] = 0x01;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0100, 0x8001, &com_buff, 1);
-+
-+ /* Mute the hardware loopbacks to start the device in a known state. */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue input 1 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0110, 0x4001, &com_buff, 2);
-+ /* Analogue input 1 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0111, 0x4001, &com_buff, 2);
-+ /* Analogue input 2 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0114, 0x4001, &com_buff, 2);
-+ /* Analogue input 2 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0115, 0x4001, &com_buff, 2);
-+ /* Analogue input 3 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0118, 0x4001, &com_buff, 2);
-+ /* Analogue input 3 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0119, 0x4001, &com_buff, 2);
-+ /* Analogue input 4 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011c, 0x4001, &com_buff, 2);
-+ /* Analogue input 4 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011d, 0x4001, &com_buff, 2);
-+
-+ /* Set software sends to output */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ /* Analogue software return 1 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0100, 0x4001, &com_buff, 2);
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue software return 1 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0101, 0x4001, &com_buff, 2);
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue software return 2 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0104, 0x4001, &com_buff, 2);
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ /* Analogue software return 2 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0105, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue software return 3 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0108, 0x4001, &com_buff, 2);
-+ /* Analogue software return 3 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0109, 0x4001, &com_buff, 2);
-+ /* Analogue software return 4 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010c, 0x4001, &com_buff, 2);
-+ /* Analogue software return 4 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010d, 0x4001, &com_buff, 2);
-+
-+ /* Return to muting sends */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue fx return left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0120, 0x4001, &com_buff, 2);
-+ /* Analogue fx return right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0121, 0x4001, &com_buff, 2);
-+
-+ /* Analogue software input 1 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0100, 0x4201, &com_buff, 2);
-+ /* Analogue software input 2 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0101, 0x4201, &com_buff, 2);
-+ /* Analogue software input 3 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0102, 0x4201, &com_buff, 2);
-+ /* Analogue software input 4 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0103, 0x4201, &com_buff, 2);
-+ /* Analogue input 1 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0104, 0x4201, &com_buff, 2);
-+ /* Analogue input 2 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0105, 0x4201, &com_buff, 2);
-+ /* Analogue input 3 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0106, 0x4201, &com_buff, 2);
-+ /* Analogue input 4 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0107, 0x4201, &com_buff, 2);
-+
-+ /* Toggle allowing host control */
-+ com_buff[0] = 0x02;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0000, 0x2001, &com_buff, 1);
-+
-+ /* Do not dim fx returns */
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0002, 0x2001, &com_buff, 1);
-+
-+ /* Do not set fx returns to mono */
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0001, 0x2001, &com_buff, 1);
-+
-+ /* Mute the S/PDIF hardware loopback
-+ * same odd volume logic here as above
-+ */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* S/PDIF hardware input 1 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0112, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 1 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0113, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 2 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0116, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 2 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0117, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 3 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011a, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 3 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011b, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 4 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011e, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 4 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011f, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 1 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0102, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 1 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0103, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 2 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0106, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 2 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0107, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ /* S/PDIF software return 3 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010a, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* S/PDIF software return 3 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010b, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 4 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010e, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ /* S/PDIF software return 4 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010f, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* S/PDIF fx returns left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0122, 0x4001, &com_buff, 2);
-+ /* S/PDIF fx returns right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0123, 0x4001, &com_buff, 2);
-+
-+ /* Set the dropdown "Effect" to the first option */
-+ /* Room1 = 0x00 */
-+ /* Room2 = 0x01 */
-+ /* Room3 = 0x02 */
-+ /* Hall 1 = 0x03 */
-+ /* Hall 2 = 0x04 */
-+ /* Plate = 0x05 */
-+ /* Delay = 0x06 */
-+ /* Echo = 0x07 */
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0200, 0x4301, &com_buff, 1); /* max is 0xff */
-+ /* min is 0x00 */
-+
-+
-+ /* Set the effect duration to 0 */
-+ /* max is 0xffff */
-+ /* min is 0x0000 */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0400, 0x4301, &com_buff, 2);
-+
-+ /* Set the effect volume and feedback to 0 */
-+ /* max is 0xff */
-+ /* min is 0x00 */
-+ com_buff[0] = 0x00;
-+ /* feedback: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0500, 0x4301, &com_buff, 1);
-+ /* volume: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0300, 0x4301, &com_buff, 1);
-+
-+ /* Set soft button hold duration */
-+ /* 0x03 = 250ms */
-+ /* 0x05 = 500ms DEFAULT */
-+ /* 0x08 = 750ms */
-+ /* 0x0a = 1sec */
-+ com_buff[0] = 0x05;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0005, 0x2001, &com_buff, 1);
-+
-+ /* Use dim LEDs for button of state */
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0004, 0x2001, &com_buff, 1);
-+}
-+
-+#define MBOX3_DESCRIPTOR_SIZE 464
-+
-+static int snd_usb_mbox3_boot_quirk(struct usb_device *dev)
-+{
-+ struct usb_host_config *config = dev->actconfig;
-+ int err;
-+ int descriptor_size;
-+
-+ descriptor_size = le16_to_cpu(get_cfg_desc(config)->wTotalLength);
-+
-+ if (descriptor_size != MBOX3_DESCRIPTOR_SIZE) {
-+ dev_err(&dev->dev, "Invalid descriptor size=%d.\n", descriptor_size);
-+ return -ENODEV;
-+ }
-+
-+ dev_dbg(&dev->dev, "device initialised!\n");
-+
-+ err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
-+ &dev->descriptor, sizeof(dev->descriptor));
-+ config = dev->actconfig;
-+ if (err < 0)
-+ dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
-+
-+ err = usb_reset_configuration(dev);
-+ if (err < 0)
-+ dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err);
-+ dev_dbg(&dev->dev, "mbox3_boot: new boot length = %d\n",
-+ le16_to_cpu(get_cfg_desc(config)->wTotalLength));
-+
-+ mbox3_setup_48_24_magic(dev);
-+ dev_info(&dev->dev, "Digidesign Mbox 3: 24bit 48kHz");
-+
-+ return 0; /* Successful boot */
-+}
-
- #define MICROBOOK_BUF_SIZE 128
-
-@@ -1324,6 +1622,10 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
- case USB_ID(0x0dba, 0x3000):
- /* Digidesign Mbox 2 */
- return snd_usb_mbox2_boot_quirk(dev);
-+ case USB_ID(0x0dba, 0x5000):
-+ /* Digidesign Mbox 3 */
-+ return snd_usb_mbox3_boot_quirk(dev);
-+
-
- case USB_ID(0x1235, 0x0010): /* Focusrite Novation Saffire 6 USB */
- case USB_ID(0x1235, 0x0018): /* Focusrite Novation Twitch */
---
-2.35.1
-
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- sound/usb/card.c | 32 +++++++++++++++++++++++++-------
- sound/usb/quirks.c | 42 ------------------------------------------
- sound/usb/quirks.h | 2 --
- sound/usb/usbaudio.h | 1 +
+ sound/usb/card.c | 32 +++++++++++++++++++++++++-------
+ sound/usb/quirks.c | 42 ------------------------------------------
+ sound/usb/quirks.h | 2 --
+ sound/usb/usbaudio.h | 1 +
4 files changed, 26 insertions(+), 51 deletions(-)
-diff --git a/sound/usb/card.c b/sound/usb/card.c
-index 706d249a9ad6..3aea241435fb 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
-@@ -690,7 +690,7 @@ static bool get_alias_id(struct usb_device *dev, unsigned int *id)
+@@ -690,7 +690,7 @@ static bool get_alias_id(struct usb_devi
return false;
}
{
int i;
unsigned int id, inum;
-@@ -699,14 +699,31 @@ static bool check_delayed_register_option(struct snd_usb_audio *chip, int iface)
+@@ -699,14 +699,31 @@ static bool check_delayed_register_optio
if (delayed_register[i] &&
sscanf(delayed_register[i], "%x:%x", &id, &inum) == 2 &&
id == chip->usb_id)
/* look for the corresponding quirk */
static const struct snd_usb_audio_quirk *
get_alias_quirk(struct usb_device *dev, unsigned int id)
-@@ -813,6 +830,7 @@ static int usb_audio_probe(struct usb_interface *intf,
+@@ -813,6 +830,7 @@ static int usb_audio_probe(struct usb_in
err = -ENODEV;
goto __error;
}
}
if (chip->num_interfaces >= MAX_CARD_INTERFACES) {
-@@ -862,11 +880,11 @@ static int usb_audio_probe(struct usb_interface *intf,
+@@ -862,11 +880,11 @@ static int usb_audio_probe(struct usb_in
chip->need_delayed_register = false; /* clear again */
}
err = snd_card_register(chip->card);
if (err < 0)
goto __error;
-diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
-index 194c75c45628..eadac586bcc8 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
-@@ -2030,48 +2030,6 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
- }
+@@ -1729,48 +1729,6 @@ void snd_usb_audioformat_attributes_quir
}
--/*
+ /*
- * registration quirk:
- * the registration is skipped if a device matches with the given ID,
- * unless the interface reaches to the defined one. This is for delaying
- return false;
-}
-
- /*
+-/*
* driver behavior quirk flags
*/
-diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h
-index 31abb7cb01a5..f9bfd5ac7bab 100644
+ struct usb_audio_quirk_flags_table {
--- a/sound/usb/quirks.h
+++ b/sound/usb/quirks.h
-@@ -48,8 +48,6 @@ void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
+@@ -48,8 +48,6 @@ void snd_usb_audioformat_attributes_quir
struct audioformat *fp,
int stream);
void snd_usb_init_quirk_flags(struct snd_usb_audio *chip);
#endif /* __USBAUDIO_QUIRKS_H */
-diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
-index ffbb4b0d09a0..2c6575029b1c 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -37,6 +37,7 @@ struct snd_usb_audio {
int num_suspended_intf;
int sample_rate_read_error;
---
-2.35.1
-
+++ /dev/null
-From 7456d0bfc65c4b041fd112538000556b4e3ec57d Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 11 Sep 2022 15:15:04 -0700
-Subject: scsi: lpfc: Fix various issues reported by tools
-
-From: James Smart <jsmart2021@gmail.com>
-
-[ Upstream commit a4de8356b68e54149ebdbe6e748e2726152b650c ]
-
-This patch fixes below Smatch reported issues:
-
- 1. lpfc_hbadisc.c:3020 lpfc_mbx_cmpl_fcf_rr_read_fcf_rec()
- error: uninitialized symbol 'vlan_id'.
-
- 2. lpfc_hbadisc.c:3121 lpfc_mbx_cmpl_read_fcf_rec()
- error: uninitialized symbol 'vlan_id'.
-
- 3. lpfc_init.c:335 lpfc_dump_wakeup_param_cmpl()
- warn: always true condition '(prg->dist < 4) => (0-3 < 4)'
-
- 4. lpfc_init.c:2419 lpfc_parse_vpd()
- warn: inconsistent indenting.
-
- 5. lpfc_init.c:13248 lpfc_sli4_enable_msi()
- warn: 'phba->pcidev->irq' 2147483648 can't fit into 65535
- 'eqhdl->irq'
-
- 6. lpfc_debugfs.c:5300 lpfc_idiag_extacc_avail_get()
- error: uninitialized symbol 'ext_cnt'
-
- 7. lpfc_debugfs.c:5300 lpfc_idiag_extacc_avail_get()
- error: uninitialized symbol 'ext_size'
-
- 8. lpfc_vmid.c:248 lpfc_vmid_get_appid()
- warn: sleeping in atomic context.
-
- 9. lpfc_init.c:8342 lpfc_sli4_driver_resource_setup()
- warn: missing error code 'rc'.
-
-10. lpfc_init.c:13573 lpfc_sli4_hba_unset()
- warn: variable dereferenced before check 'phba->pport' (see
- line 13546)
-
-11. lpfc_auth.c:1923 lpfc_auth_handle_dhchap_reply()
- error: double free of 'hash_value'
-
-Fixes:
-
- 1. Initialize vlan_id to LPFC_FCOE_NULL_VID.
-
- 2. Initialize vlan_id to LPFC_FCOE_NULL_VID.
-
- 3. prg->dist is a 2 bit field. Its value can only be between 0-3.
- Remove redundent check 'if (prg->dist < 4)'.
-
- 4. Fix inconsistent indenting. Moved logic into helper function
- lpfc_fill_vpd().
-
- 5. Define 'eqhdl->irq' as int value as pci_irq_vector() returns int.
- Also, check for return value of pci_irq_vector() and log message in
- case of failure.
-
- 6. Initialize 'ext_cnt' to 0.
-
- 7. Initialize 'ext_size' to 0.
-
- 8. Use alloc_percpu_gfp() with GFP_ATOMIC flag.
-
- 9. 'rc' was not updated when dma_pool_create() fails. Update 'rc =
- -ENOMEM' when dma_pool_create() fails before calling goto statement.
-
-10. Add check for 'phba->pport' in lpfc_cpuhp_remove().
-
-11. Initialize 'hash_value' to NULL, same like 'aug_chal' variable.
-
-Link: https://lore.kernel.org/r/20220911221505.117655-13-jsmart2021@gmail.com
-Co-developed-by: Justin Tee <justin.tee@broadcom.com>
-Signed-off-by: Justin Tee <justin.tee@broadcom.com>
-Signed-off-by: James Smart <jsmart2021@gmail.com>
-Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/scsi/lpfc/lpfc_debugfs.c | 2 +-
- drivers/scsi/lpfc/lpfc_hbadisc.c | 4 +-
- drivers/scsi/lpfc/lpfc_init.c | 249 +++++++++++++++++--------------
- drivers/scsi/lpfc/lpfc_sli.c | 3 +
- drivers/scsi/lpfc/lpfc_sli4.h | 4 +-
- drivers/scsi/lpfc/lpfc_vmid.c | 4 +-
- 6 files changed, 148 insertions(+), 118 deletions(-)
-
-diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
-index 24fbf21ea051..32c46fc9fc97 100644
---- a/drivers/scsi/lpfc/lpfc_debugfs.c
-+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
-@@ -5156,7 +5156,7 @@ lpfc_idiag_mbxacc_write(struct file *file, const char __user *buf,
- static int
- lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len)
- {
-- uint16_t ext_cnt, ext_size;
-+ uint16_t ext_cnt = 0, ext_size = 0;
-
- len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
- "\nAvailable Extents Information:\n");
-diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
-index 5cd838eac455..cf234a80cfc2 100644
---- a/drivers/scsi/lpfc/lpfc_hbadisc.c
-+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
-@@ -2964,7 +2964,7 @@ lpfc_mbx_cmpl_fcf_rr_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
- uint32_t boot_flag, addr_mode;
- uint16_t next_fcf_index, fcf_index;
- uint16_t current_fcf_index;
-- uint16_t vlan_id;
-+ uint16_t vlan_id = LPFC_FCOE_NULL_VID;
- int rc;
-
- /* If link state is not up, stop the roundrobin failover process */
-@@ -3069,7 +3069,7 @@ lpfc_mbx_cmpl_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
- struct fcf_record *new_fcf_record;
- uint32_t boot_flag, addr_mode;
- uint16_t fcf_index, next_fcf_index;
-- uint16_t vlan_id;
-+ uint16_t vlan_id = LPFC_FCOE_NULL_VID;
- int rc;
-
- /* If link state is not up, no need to proceed */
-diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
-index df8216a07d9b..f7d23d2232b3 100644
---- a/drivers/scsi/lpfc/lpfc_init.c
-+++ b/drivers/scsi/lpfc/lpfc_init.c
-@@ -325,8 +325,7 @@ lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
- prog_id_word = pmboxq->u.mb.un.varWords[7];
-
- /* Decode the Option rom version word to a readable string */
-- if (prg->dist < 4)
-- dist = dist_char[prg->dist];
-+ dist = dist_char[prg->dist];
-
- if ((prg->dist == 3) && (prg->num == 0))
- snprintf(phba->OptionROMVersion, 32, "%d.%d%d",
-@@ -2255,6 +2254,101 @@ lpfc_handle_latt(struct lpfc_hba *phba)
- return;
- }
-
-+static void
-+lpfc_fill_vpd(struct lpfc_hba *phba, uint8_t *vpd, int length, int *pindex)
-+{
-+ int i, j;
-+
-+ while (length > 0) {
-+ /* Look for Serial Number */
-+ if ((vpd[*pindex] == 'S') && (vpd[*pindex + 1] == 'N')) {
-+ *pindex += 2;
-+ i = vpd[*pindex];
-+ *pindex += 1;
-+ j = 0;
-+ length -= (3+i);
-+ while (i--) {
-+ phba->SerialNumber[j++] = vpd[(*pindex)++];
-+ if (j == 31)
-+ break;
-+ }
-+ phba->SerialNumber[j] = 0;
-+ continue;
-+ } else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '1')) {
-+ phba->vpd_flag |= VPD_MODEL_DESC;
-+ *pindex += 2;
-+ i = vpd[*pindex];
-+ *pindex += 1;
-+ j = 0;
-+ length -= (3+i);
-+ while (i--) {
-+ phba->ModelDesc[j++] = vpd[(*pindex)++];
-+ if (j == 255)
-+ break;
-+ }
-+ phba->ModelDesc[j] = 0;
-+ continue;
-+ } else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '2')) {
-+ phba->vpd_flag |= VPD_MODEL_NAME;
-+ *pindex += 2;
-+ i = vpd[*pindex];
-+ *pindex += 1;
-+ j = 0;
-+ length -= (3+i);
-+ while (i--) {
-+ phba->ModelName[j++] = vpd[(*pindex)++];
-+ if (j == 79)
-+ break;
-+ }
-+ phba->ModelName[j] = 0;
-+ continue;
-+ } else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '3')) {
-+ phba->vpd_flag |= VPD_PROGRAM_TYPE;
-+ *pindex += 2;
-+ i = vpd[*pindex];
-+ *pindex += 1;
-+ j = 0;
-+ length -= (3+i);
-+ while (i--) {
-+ phba->ProgramType[j++] = vpd[(*pindex)++];
-+ if (j == 255)
-+ break;
-+ }
-+ phba->ProgramType[j] = 0;
-+ continue;
-+ } else if ((vpd[*pindex] == 'V') && (vpd[*pindex + 1] == '4')) {
-+ phba->vpd_flag |= VPD_PORT;
-+ *pindex += 2;
-+ i = vpd[*pindex];
-+ *pindex += 1;
-+ j = 0;
-+ length -= (3 + i);
-+ while (i--) {
-+ if ((phba->sli_rev == LPFC_SLI_REV4) &&
-+ (phba->sli4_hba.pport_name_sta ==
-+ LPFC_SLI4_PPNAME_GET)) {
-+ j++;
-+ (*pindex)++;
-+ } else
-+ phba->Port[j++] = vpd[(*pindex)++];
-+ if (j == 19)
-+ break;
-+ }
-+ if ((phba->sli_rev != LPFC_SLI_REV4) ||
-+ (phba->sli4_hba.pport_name_sta ==
-+ LPFC_SLI4_PPNAME_NON))
-+ phba->Port[j] = 0;
-+ continue;
-+ } else {
-+ *pindex += 2;
-+ i = vpd[*pindex];
-+ *pindex += 1;
-+ *pindex += i;
-+ length -= (3 + i);
-+ }
-+ }
-+}
-+
- /**
- * lpfc_parse_vpd - Parse VPD (Vital Product Data)
- * @phba: pointer to lpfc hba data structure.
-@@ -2274,7 +2368,7 @@ lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len)
- {
- uint8_t lenlo, lenhi;
- int Length;
-- int i, j;
-+ int i;
- int finished = 0;
- int index = 0;
-
-@@ -2307,101 +2401,10 @@ lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len)
- Length = ((((unsigned short)lenhi) << 8) + lenlo);
- if (Length > len - index)
- Length = len - index;
-- while (Length > 0) {
-- /* Look for Serial Number */
-- if ((vpd[index] == 'S') && (vpd[index+1] == 'N')) {
-- index += 2;
-- i = vpd[index];
-- index += 1;
-- j = 0;
-- Length -= (3+i);
-- while(i--) {
-- phba->SerialNumber[j++] = vpd[index++];
-- if (j == 31)
-- break;
-- }
-- phba->SerialNumber[j] = 0;
-- continue;
-- }
-- else if ((vpd[index] == 'V') && (vpd[index+1] == '1')) {
-- phba->vpd_flag |= VPD_MODEL_DESC;
-- index += 2;
-- i = vpd[index];
-- index += 1;
-- j = 0;
-- Length -= (3+i);
-- while(i--) {
-- phba->ModelDesc[j++] = vpd[index++];
-- if (j == 255)
-- break;
-- }
-- phba->ModelDesc[j] = 0;
-- continue;
-- }
-- else if ((vpd[index] == 'V') && (vpd[index+1] == '2')) {
-- phba->vpd_flag |= VPD_MODEL_NAME;
-- index += 2;
-- i = vpd[index];
-- index += 1;
-- j = 0;
-- Length -= (3+i);
-- while(i--) {
-- phba->ModelName[j++] = vpd[index++];
-- if (j == 79)
-- break;
-- }
-- phba->ModelName[j] = 0;
-- continue;
-- }
-- else if ((vpd[index] == 'V') && (vpd[index+1] == '3')) {
-- phba->vpd_flag |= VPD_PROGRAM_TYPE;
-- index += 2;
-- i = vpd[index];
-- index += 1;
-- j = 0;
-- Length -= (3+i);
-- while(i--) {
-- phba->ProgramType[j++] = vpd[index++];
-- if (j == 255)
-- break;
-- }
-- phba->ProgramType[j] = 0;
-- continue;
-- }
-- else if ((vpd[index] == 'V') && (vpd[index+1] == '4')) {
-- phba->vpd_flag |= VPD_PORT;
-- index += 2;
-- i = vpd[index];
-- index += 1;
-- j = 0;
-- Length -= (3+i);
-- while(i--) {
-- if ((phba->sli_rev == LPFC_SLI_REV4) &&
-- (phba->sli4_hba.pport_name_sta ==
-- LPFC_SLI4_PPNAME_GET)) {
-- j++;
-- index++;
-- } else
-- phba->Port[j++] = vpd[index++];
-- if (j == 19)
-- break;
-- }
-- if ((phba->sli_rev != LPFC_SLI_REV4) ||
-- (phba->sli4_hba.pport_name_sta ==
-- LPFC_SLI4_PPNAME_NON))
-- phba->Port[j] = 0;
-- continue;
-- }
-- else {
-- index += 2;
-- i = vpd[index];
-- index += 1;
-- index += i;
-- Length -= (3 + i);
-- }
-- }
-- finished = 0;
-- break;
-+
-+ lpfc_fill_vpd(phba, vpd, Length, &index);
-+ finished = 0;
-+ break;
- case 0x78:
- finished = 1;
- break;
-@@ -8286,8 +8289,10 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
- &phba->pcidev->dev,
- phba->cfg_sg_dma_buf_size,
- i, 0);
-- if (!phba->lpfc_sg_dma_buf_pool)
-+ if (!phba->lpfc_sg_dma_buf_pool) {
-+ rc = -ENOMEM;
- goto out_free_bsmbx;
-+ }
-
- phba->lpfc_cmd_rsp_buf_pool =
- dma_pool_create("lpfc_cmd_rsp_buf_pool",
-@@ -8295,8 +8300,10 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
- sizeof(struct fcp_cmnd) +
- sizeof(struct fcp_rsp),
- i, 0);
-- if (!phba->lpfc_cmd_rsp_buf_pool)
-+ if (!phba->lpfc_cmd_rsp_buf_pool) {
-+ rc = -ENOMEM;
- goto out_free_sg_dma_buf;
-+ }
-
- mempool_free(mboxq, phba->mbox_mem_pool);
-
-@@ -12386,7 +12393,7 @@ lpfc_hba_eq_hdl_array_init(struct lpfc_hba *phba)
-
- for (i = 0; i < phba->cfg_irq_chann; i++) {
- eqhdl = lpfc_get_eq_hdl(i);
-- eqhdl->irq = LPFC_VECTOR_MAP_EMPTY;
-+ eqhdl->irq = LPFC_IRQ_EMPTY;
- eqhdl->phba = phba;
- }
- }
-@@ -12759,7 +12766,7 @@ static void __lpfc_cpuhp_remove(struct lpfc_hba *phba)
-
- static void lpfc_cpuhp_remove(struct lpfc_hba *phba)
- {
-- if (phba->pport->fc_flag & FC_OFFLINE_MODE)
-+ if (phba->pport && (phba->pport->fc_flag & FC_OFFLINE_MODE))
- return;
-
- __lpfc_cpuhp_remove(phba);
-@@ -13023,9 +13030,17 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba)
- LPFC_DRIVER_HANDLER_NAME"%d", index);
-
- eqhdl->idx = index;
-- rc = request_irq(pci_irq_vector(phba->pcidev, index),
-- &lpfc_sli4_hba_intr_handler, 0,
-- name, eqhdl);
-+ rc = pci_irq_vector(phba->pcidev, index);
-+ if (rc < 0) {
-+ lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
-+ "0489 MSI-X fast-path (%d) "
-+ "pci_irq_vec failed (%d)\n", index, rc);
-+ goto cfg_fail_out;
-+ }
-+ eqhdl->irq = rc;
-+
-+ rc = request_irq(eqhdl->irq, &lpfc_sli4_hba_intr_handler, 0,
-+ name, eqhdl);
- if (rc) {
- lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
- "0486 MSI-X fast-path (%d) "
-@@ -13033,8 +13048,6 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba)
- goto cfg_fail_out;
- }
-
-- eqhdl->irq = pci_irq_vector(phba->pcidev, index);
--
- if (aff_mask) {
- /* If found a neighboring online cpu, set affinity */
- if (cpu_select < nr_cpu_ids)
-@@ -13151,7 +13164,14 @@ lpfc_sli4_enable_msi(struct lpfc_hba *phba)
- }
-
- eqhdl = lpfc_get_eq_hdl(0);
-- eqhdl->irq = pci_irq_vector(phba->pcidev, 0);
-+ rc = pci_irq_vector(phba->pcidev, 0);
-+ if (rc < 0) {
-+ pci_free_irq_vectors(phba->pcidev);
-+ lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
-+ "0496 MSI pci_irq_vec failed (%d)\n", rc);
-+ return rc;
-+ }
-+ eqhdl->irq = rc;
-
- cpu = cpumask_first(cpu_present_mask);
- lpfc_assign_eq_map_info(phba, 0, LPFC_CPU_FIRST_IRQ, cpu);
-@@ -13178,8 +13198,8 @@ lpfc_sli4_enable_msi(struct lpfc_hba *phba)
- * MSI-X -> MSI -> IRQ.
- *
- * Return codes
-- * 0 - successful
-- * other values - error
-+ * Interrupt mode (2, 1, 0) - successful
-+ * LPFC_INTR_ERROR - error
- **/
- static uint32_t
- lpfc_sli4_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode)
-@@ -13224,7 +13244,14 @@ lpfc_sli4_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode)
- intr_mode = 0;
-
- eqhdl = lpfc_get_eq_hdl(0);
-- eqhdl->irq = pci_irq_vector(phba->pcidev, 0);
-+ retval = pci_irq_vector(phba->pcidev, 0);
-+ if (retval < 0) {
-+ lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
-+ "0502 INTR pci_irq_vec failed (%d)\n",
-+ retval);
-+ return LPFC_INTR_ERROR;
-+ }
-+ eqhdl->irq = retval;
-
- cpu = cpumask_first(cpu_present_mask);
- lpfc_assign_eq_map_info(phba, 0, LPFC_CPU_FIRST_IRQ,
-diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
-index 2269253aeb3d..73a6d6a503a8 100644
---- a/drivers/scsi/lpfc/lpfc_sli.c
-+++ b/drivers/scsi/lpfc/lpfc_sli.c
-@@ -6197,6 +6197,9 @@ lpfc_sli4_get_avail_extnt_rsrc(struct lpfc_hba *phba, uint16_t type,
- struct lpfc_mbx_get_rsrc_extent_info *rsrc_info;
- LPFC_MBOXQ_t *mbox;
-
-+ *extnt_count = 0;
-+ *extnt_size = 0;
-+
- mbox = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
- if (!mbox)
- return -ENOMEM;
-diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
-index 1ddad5b170a6..cbb1aa1cf025 100644
---- a/drivers/scsi/lpfc/lpfc_sli4.h
-+++ b/drivers/scsi/lpfc/lpfc_sli4.h
-@@ -489,7 +489,7 @@ struct lpfc_hba;
- #define LPFC_SLI4_HANDLER_NAME_SZ 16
- struct lpfc_hba_eq_hdl {
- uint32_t idx;
-- uint16_t irq;
-+ int irq;
- char handler_name[LPFC_SLI4_HANDLER_NAME_SZ];
- struct lpfc_hba *phba;
- struct lpfc_queue *eq;
-@@ -611,6 +611,8 @@ struct lpfc_vector_map_info {
- };
- #define LPFC_VECTOR_MAP_EMPTY 0xffff
-
-+#define LPFC_IRQ_EMPTY 0xffffffff
-+
- /* Multi-XRI pool */
- #define XRI_BATCH 8
-
-diff --git a/drivers/scsi/lpfc/lpfc_vmid.c b/drivers/scsi/lpfc/lpfc_vmid.c
-index f64ced04b912..ed1d7f7b88a3 100644
---- a/drivers/scsi/lpfc/lpfc_vmid.c
-+++ b/drivers/scsi/lpfc/lpfc_vmid.c
-@@ -245,9 +245,7 @@ int lpfc_vmid_get_appid(struct lpfc_vport *vport, char *uuid,
- /* allocate the per cpu variable for holding */
- /* the last access time stamp only if VMID is enabled */
- if (!vmp->last_io_time)
-- vmp->last_io_time = __alloc_percpu(sizeof(u64),
-- __alignof__(struct
-- lpfc_vmid));
-+ vmp->last_io_time = alloc_percpu_gfp(u64, GFP_ATOMIC);
- if (!vmp->last_io_time) {
- hash_del(&vmp->hnode);
- vmp->flag = LPFC_VMID_SLOT_FREE;
---
-2.35.1
-
dyndbg-let-query-modname-override-actual-module-name.patch
dyndbg-drop-exported-dynamic_debug_exec_queries.patch
clk-qcom-sm6115-select-qcom_gdsc.patch
-scsi-lpfc-fix-various-issues-reported-by-tools.patch
mtd-devices-docg3-check-the-return-value-of-devm_ior.patch
remoteproc-harden-rproc_handle_vdev-against-integer-.patch
phy-amlogic-phy-meson-axg-mipi-pcie-analog-hold-refe.patch
drm-komeda-fix-handling-of-atomic-commits-in-the-ato.patch
gpu-lontium-lt9611-fix-null-pointer-dereference-in-l.patch
drm-amd-display-fix-overflow-on-min_i64-definition.patch
-alsa-usb-audio-add-quirk-to-enable-avid-mbox-3-suppo.patch
udmabuf-set-ubuf-sg-null-if-the-creation-of-sg-table.patch
platform-x86-pmc_atom-improve-quirk-message-to-be-le.patch
drm-bridge-dw_hdmi-only-trigger-hotplug-event-on-lin.patch
+++ /dev/null
-From a19e69f9947a2a0d5e183dca22b3c842ff6e3fa7 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 18 Aug 2022 17:14:33 -0300
-Subject: ALSA: usb-audio: Add quirk to enable Avid Mbox 3 support
-
-From: Conner Knox <connerknoxpublic@gmail.com>
-
-[ Upstream commit b01104fc62b6194c852124f6c6df1c0a5c031fc1 ]
-
-Add support for Avid Mbox3 USB audio interface at 48kHz
-
-Signed-off-by: Conner Knox <connerknoxpublic@gmail.com>
-Link: https://lore.kernel.org/r/20220818201433.16360-1-mbarriolinares@gmail.com
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- sound/usb/quirks-table.h | 76 ++++++++++
- sound/usb/quirks.c | 302 +++++++++++++++++++++++++++++++++++++++
- 2 files changed, 378 insertions(+)
-
-diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
-index c29ccdf9e8bc..79c97bde81fd 100644
---- a/sound/usb/quirks-table.h
-+++ b/sound/usb/quirks-table.h
-@@ -3175,6 +3175,82 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
- }
- }
- },
-+/* DIGIDESIGN MBOX 3 */
-+{
-+ USB_DEVICE(0x0dba, 0x5000),
-+ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
-+ .vendor_name = "Digidesign",
-+ .product_name = "Mbox 3",
-+ .ifnum = QUIRK_ANY_INTERFACE,
-+ .type = QUIRK_COMPOSITE,
-+ .data = (const struct snd_usb_audio_quirk[]) {
-+ {
-+ .ifnum = 0,
-+ .type = QUIRK_IGNORE_INTERFACE
-+ },
-+ {
-+ .ifnum = 1,
-+ .type = QUIRK_IGNORE_INTERFACE
-+ },
-+ {
-+ .ifnum = 2,
-+ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
-+ .data = &(const struct audioformat) {
-+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
-+ .channels = 4,
-+ .iface = 2,
-+ .altsetting = 1,
-+ .altset_idx = 1,
-+ .attributes = 0x00,
-+ .endpoint = 0x01,
-+ .ep_attr = USB_ENDPOINT_XFER_ISOC |
-+ USB_ENDPOINT_SYNC_ASYNC,
-+ .rates = SNDRV_PCM_RATE_48000,
-+ .rate_min = 48000,
-+ .rate_max = 48000,
-+ .nr_rates = 1,
-+ .rate_table = (unsigned int[]) {
-+ 48000
-+ }
-+ }
-+ },
-+ {
-+ .ifnum = 3,
-+ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
-+ .data = &(const struct audioformat) {
-+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
-+ .channels = 4,
-+ .iface = 3,
-+ .altsetting = 1,
-+ .altset_idx = 1,
-+ .endpoint = 0x81,
-+ .attributes = 0x00,
-+ .ep_attr = USB_ENDPOINT_XFER_ISOC |
-+ USB_ENDPOINT_SYNC_ASYNC,
-+ .maxpacksize = 0x009c,
-+ .rates = SNDRV_PCM_RATE_48000,
-+ .rate_min = 48000,
-+ .rate_max = 48000,
-+ .nr_rates = 1,
-+ .rate_table = (unsigned int[]) {
-+ 48000
-+ }
-+ }
-+ },
-+ {
-+ .ifnum = 4,
-+ .type = QUIRK_MIDI_FIXED_ENDPOINT,
-+ .data = &(const struct snd_usb_midi_endpoint_info) {
-+ .out_cables = 0x0001,
-+ .in_cables = 0x0001
-+ }
-+ },
-+ {
-+ .ifnum = -1
-+ }
-+ }
-+ }
-+},
- {
- /* Tascam US122 MKII - playback-only support */
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
-diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
-index 72223545abfd..1d317ae2929d 100644
---- a/sound/usb/quirks.c
-+++ b/sound/usb/quirks.c
-@@ -1018,6 +1018,304 @@ static int snd_usb_axefx3_boot_quirk(struct usb_device *dev)
- return 0;
- }
-
-+static void mbox3_setup_48_24_magic(struct usb_device *dev)
-+{
-+ /* The Mbox 3 is "little endian" */
-+ /* max volume is: 0x0000. */
-+ /* min volume is: 0x0080 (shown in little endian form) */
-+
-+
-+ /* Load 48000Hz rate into buffer */
-+ u8 com_buff[4] = {0x80, 0xbb, 0x00, 0x00};
-+
-+ /* Set 48000Hz sample rate */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 0x01, 0x21, 0x0100, 0x0001, &com_buff, 4); //Is this really needed?
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 0x01, 0x21, 0x0100, 0x8101, &com_buff, 4);
-+
-+ /* Deactivate Tuner */
-+ /* on = 0x01*/
-+ /* off = 0x00*/
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 0x01, 0x21, 0x0003, 0x2001, &com_buff, 1);
-+
-+ /* Set clock source to Internal (as opposed to S/PDIF) */
-+ com_buff[0] = 0x01;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0100, 0x8001, &com_buff, 1);
-+
-+ /* Mute the hardware loopbacks to start the device in a known state. */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue input 1 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0110, 0x4001, &com_buff, 2);
-+ /* Analogue input 1 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0111, 0x4001, &com_buff, 2);
-+ /* Analogue input 2 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0114, 0x4001, &com_buff, 2);
-+ /* Analogue input 2 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0115, 0x4001, &com_buff, 2);
-+ /* Analogue input 3 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0118, 0x4001, &com_buff, 2);
-+ /* Analogue input 3 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0119, 0x4001, &com_buff, 2);
-+ /* Analogue input 4 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011c, 0x4001, &com_buff, 2);
-+ /* Analogue input 4 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011d, 0x4001, &com_buff, 2);
-+
-+ /* Set software sends to output */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ /* Analogue software return 1 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0100, 0x4001, &com_buff, 2);
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue software return 1 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0101, 0x4001, &com_buff, 2);
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue software return 2 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0104, 0x4001, &com_buff, 2);
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ /* Analogue software return 2 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0105, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue software return 3 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0108, 0x4001, &com_buff, 2);
-+ /* Analogue software return 3 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0109, 0x4001, &com_buff, 2);
-+ /* Analogue software return 4 left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010c, 0x4001, &com_buff, 2);
-+ /* Analogue software return 4 right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010d, 0x4001, &com_buff, 2);
-+
-+ /* Return to muting sends */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* Analogue fx return left channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0120, 0x4001, &com_buff, 2);
-+ /* Analogue fx return right channel: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0121, 0x4001, &com_buff, 2);
-+
-+ /* Analogue software input 1 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0100, 0x4201, &com_buff, 2);
-+ /* Analogue software input 2 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0101, 0x4201, &com_buff, 2);
-+ /* Analogue software input 3 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0102, 0x4201, &com_buff, 2);
-+ /* Analogue software input 4 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0103, 0x4201, &com_buff, 2);
-+ /* Analogue input 1 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0104, 0x4201, &com_buff, 2);
-+ /* Analogue input 2 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0105, 0x4201, &com_buff, 2);
-+ /* Analogue input 3 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0106, 0x4201, &com_buff, 2);
-+ /* Analogue input 4 fx send: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0107, 0x4201, &com_buff, 2);
-+
-+ /* Toggle allowing host control */
-+ com_buff[0] = 0x02;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0000, 0x2001, &com_buff, 1);
-+
-+ /* Do not dim fx returns */
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0002, 0x2001, &com_buff, 1);
-+
-+ /* Do not set fx returns to mono */
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0001, 0x2001, &com_buff, 1);
-+
-+ /* Mute the S/PDIF hardware loopback
-+ * same odd volume logic here as above
-+ */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* S/PDIF hardware input 1 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0112, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 1 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0113, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 2 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0116, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 2 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0117, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 3 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011a, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 3 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011b, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 4 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011e, 0x4001, &com_buff, 2);
-+ /* S/PDIF hardware input 4 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x011f, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 1 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0102, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 1 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0103, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 2 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0106, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 2 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0107, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ /* S/PDIF software return 3 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010a, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* S/PDIF software return 3 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010b, 0x4001, &com_buff, 2);
-+ /* S/PDIF software return 4 left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010e, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ /* S/PDIF software return 4 right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x010f, 0x4001, &com_buff, 2);
-+
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x80;
-+ /* S/PDIF fx returns left channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0122, 0x4001, &com_buff, 2);
-+ /* S/PDIF fx returns right channel */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0123, 0x4001, &com_buff, 2);
-+
-+ /* Set the dropdown "Effect" to the first option */
-+ /* Room1 = 0x00 */
-+ /* Room2 = 0x01 */
-+ /* Room3 = 0x02 */
-+ /* Hall 1 = 0x03 */
-+ /* Hall 2 = 0x04 */
-+ /* Plate = 0x05 */
-+ /* Delay = 0x06 */
-+ /* Echo = 0x07 */
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0200, 0x4301, &com_buff, 1); /* max is 0xff */
-+ /* min is 0x00 */
-+
-+
-+ /* Set the effect duration to 0 */
-+ /* max is 0xffff */
-+ /* min is 0x0000 */
-+ com_buff[0] = 0x00;
-+ com_buff[1] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0400, 0x4301, &com_buff, 2);
-+
-+ /* Set the effect volume and feedback to 0 */
-+ /* max is 0xff */
-+ /* min is 0x00 */
-+ com_buff[0] = 0x00;
-+ /* feedback: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0500, 0x4301, &com_buff, 1);
-+ /* volume: */
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 1, 0x21, 0x0300, 0x4301, &com_buff, 1);
-+
-+ /* Set soft button hold duration */
-+ /* 0x03 = 250ms */
-+ /* 0x05 = 500ms DEFAULT */
-+ /* 0x08 = 750ms */
-+ /* 0x0a = 1sec */
-+ com_buff[0] = 0x05;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0005, 0x2001, &com_buff, 1);
-+
-+ /* Use dim LEDs for button of state */
-+ com_buff[0] = 0x00;
-+ snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
-+ 3, 0x21, 0x0004, 0x2001, &com_buff, 1);
-+}
-+
-+#define MBOX3_DESCRIPTOR_SIZE 464
-+
-+static int snd_usb_mbox3_boot_quirk(struct usb_device *dev)
-+{
-+ struct usb_host_config *config = dev->actconfig;
-+ int err;
-+ int descriptor_size;
-+
-+ descriptor_size = le16_to_cpu(get_cfg_desc(config)->wTotalLength);
-+
-+ if (descriptor_size != MBOX3_DESCRIPTOR_SIZE) {
-+ dev_err(&dev->dev, "Invalid descriptor size=%d.\n", descriptor_size);
-+ return -ENODEV;
-+ }
-+
-+ dev_dbg(&dev->dev, "device initialised!\n");
-+
-+ err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
-+ &dev->descriptor, sizeof(dev->descriptor));
-+ config = dev->actconfig;
-+ if (err < 0)
-+ dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
-+
-+ err = usb_reset_configuration(dev);
-+ if (err < 0)
-+ dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err);
-+ dev_dbg(&dev->dev, "mbox3_boot: new boot length = %d\n",
-+ le16_to_cpu(get_cfg_desc(config)->wTotalLength));
-+
-+ mbox3_setup_48_24_magic(dev);
-+ dev_info(&dev->dev, "Digidesign Mbox 3: 24bit 48kHz");
-+
-+ return 0; /* Successful boot */
-+}
-
- #define MICROBOOK_BUF_SIZE 128
-
-@@ -1304,6 +1602,10 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
- case USB_ID(0x0dba, 0x3000):
- /* Digidesign Mbox 2 */
- return snd_usb_mbox2_boot_quirk(dev);
-+ case USB_ID(0x0dba, 0x5000):
-+ /* Digidesign Mbox 3 */
-+ return snd_usb_mbox3_boot_quirk(dev);
-+
-
- case USB_ID(0x1235, 0x0010): /* Focusrite Novation Saffire 6 USB */
- case USB_ID(0x1235, 0x0018): /* Focusrite Novation Twitch */
---
-2.35.1
-
drm-use-size_t-type-for-len-variable-in-drm_copy_fie.patch
drm-prevent-drm_copy_field-to-attempt-copying-a-null.patch
drm-amd-display-fix-overflow-on-min_i64-definition.patch
-alsa-usb-audio-add-quirk-to-enable-avid-mbox-3-suppo.patch
drm-vc4-vec-fix-timings-for-vec-modes.patch
drm-panel-orientation-quirks-add-quirk-for-anbernic-.patch
platform-x86-msi-laptop-change-dmi-match-alias-strin.patch