stream.c (daa138a58c802e7b4c2fb73f9b85bb082616ef43) stream.c (57f8770620e9b51c61089751f0b5ad3dbe376ff2)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 */
4
5
6#include <linux/init.h>
7#include <linux/slab.h>
8#include <linux/usb.h>

--- 613 unchanged lines hidden (view full) ---

622 return 0;
623}
624
625/* find an input terminal descriptor (either UAC1 or UAC2) with the given
626 * terminal id
627 */
628static void *
629snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface,
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 */
4
5
6#include <linux/init.h>
7#include <linux/slab.h>
8#include <linux/usb.h>

--- 613 unchanged lines hidden (view full) ---

622 return 0;
623}
624
625/* find an input terminal descriptor (either UAC1 or UAC2) with the given
626 * terminal id
627 */
628static void *
629snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface,
630 int terminal_id, bool uac23)
630 int terminal_id, int protocol)
631{
632 struct uac2_input_terminal_descriptor *term = NULL;
631{
632 struct uac2_input_terminal_descriptor *term = NULL;
633 size_t minlen = uac23 ? sizeof(struct uac2_input_terminal_descriptor) :
634 sizeof(struct uac_input_terminal_descriptor);
635
636 while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
637 ctrl_iface->extralen,
638 term, UAC_INPUT_TERMINAL))) {
633
634 while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
635 ctrl_iface->extralen,
636 term, UAC_INPUT_TERMINAL))) {
639 if (term->bLength < minlen)
637 if (!snd_usb_validate_audio_desc(term, protocol))
640 continue;
641 if (term->bTerminalID == terminal_id)
642 return term;
643 }
644
645 return NULL;
646}
647
648static void *
649snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface,
638 continue;
639 if (term->bTerminalID == terminal_id)
640 return term;
641 }
642
643 return NULL;
644}
645
646static void *
647snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface,
650 int terminal_id)
648 int terminal_id, int protocol)
651{
652 /* OK to use with both UAC2 and UAC3 */
653 struct uac2_output_terminal_descriptor *term = NULL;
654
655 while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
656 ctrl_iface->extralen,
657 term, UAC_OUTPUT_TERMINAL))) {
649{
650 /* OK to use with both UAC2 and UAC3 */
651 struct uac2_output_terminal_descriptor *term = NULL;
652
653 while ((term = snd_usb_find_csint_desc(ctrl_iface->extra,
654 ctrl_iface->extralen,
655 term, UAC_OUTPUT_TERMINAL))) {
658 if (term->bLength >= sizeof(*term) &&
659 term->bTerminalID == terminal_id)
656 if (!snd_usb_validate_audio_desc(term, protocol))
657 continue;
658 if (term->bTerminalID == terminal_id)
660 return term;
661 }
662
663 return NULL;
664}
665
666static struct audioformat *
667audio_format_alloc_init(struct snd_usb_audio *chip,

--- 58 unchanged lines hidden (view full) ---

726 iface_no, altno);
727 return NULL;
728 }
729
730 format = le16_to_cpu(as->wFormatTag); /* remember the format value */
731
732 iterm = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
733 as->bTerminalLink,
659 return term;
660 }
661
662 return NULL;
663}
664
665static struct audioformat *
666audio_format_alloc_init(struct snd_usb_audio *chip,

--- 58 unchanged lines hidden (view full) ---

725 iface_no, altno);
726 return NULL;
727 }
728
729 format = le16_to_cpu(as->wFormatTag); /* remember the format value */
730
731 iterm = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
732 as->bTerminalLink,
734 false);
733 protocol);
735 if (iterm) {
736 num_channels = iterm->bNrChannels;
737 chconfig = le16_to_cpu(iterm->wChannelConfig);
738 }
739 } else { /* UAC_VERSION_2 */
740 struct uac2_input_terminal_descriptor *input_term;
741 struct uac2_output_terminal_descriptor *output_term;
742 struct uac2_as_header_descriptor *as =

--- 19 unchanged lines hidden (view full) ---

762 chconfig = le32_to_cpu(as->bmChannelConfig);
763
764 /*
765 * lookup the terminal associated to this interface
766 * to extract the clock
767 */
768 input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
769 as->bTerminalLink,
734 if (iterm) {
735 num_channels = iterm->bNrChannels;
736 chconfig = le16_to_cpu(iterm->wChannelConfig);
737 }
738 } else { /* UAC_VERSION_2 */
739 struct uac2_input_terminal_descriptor *input_term;
740 struct uac2_output_terminal_descriptor *output_term;
741 struct uac2_as_header_descriptor *as =

--- 19 unchanged lines hidden (view full) ---

761 chconfig = le32_to_cpu(as->bmChannelConfig);
762
763 /*
764 * lookup the terminal associated to this interface
765 * to extract the clock
766 */
767 input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
768 as->bTerminalLink,
770 true);
769 protocol);
771 if (input_term) {
772 clock = input_term->bCSourceID;
773 if (!chconfig && (num_channels == input_term->bNrChannels))
774 chconfig = le32_to_cpu(input_term->bmChannelConfig);
775 goto found_clock;
776 }
777
778 output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf,
770 if (input_term) {
771 clock = input_term->bCSourceID;
772 if (!chconfig && (num_channels == input_term->bNrChannels))
773 chconfig = le32_to_cpu(input_term->bmChannelConfig);
774 goto found_clock;
775 }
776
777 output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf,
779 as->bTerminalLink);
778 as->bTerminalLink,
779 protocol);
780 if (output_term) {
781 clock = output_term->bCSourceID;
782 goto found_clock;
783 }
784
785 dev_err(&dev->dev,
786 "%u:%d : bogus bTerminalLink %d\n",
787 iface_no, altno, as->bTerminalLink);

--- 209 unchanged lines hidden (view full) ---

997 kfree(cluster);
998
999 /*
1000 * lookup the terminal associated to this interface
1001 * to extract the clock
1002 */
1003 input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
1004 as->bTerminalLink,
780 if (output_term) {
781 clock = output_term->bCSourceID;
782 goto found_clock;
783 }
784
785 dev_err(&dev->dev,
786 "%u:%d : bogus bTerminalLink %d\n",
787 iface_no, altno, as->bTerminalLink);

--- 209 unchanged lines hidden (view full) ---

997 kfree(cluster);
998
999 /*
1000 * lookup the terminal associated to this interface
1001 * to extract the clock
1002 */
1003 input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
1004 as->bTerminalLink,
1005 true);
1005 UAC_VERSION_3);
1006 if (input_term) {
1007 clock = input_term->bCSourceID;
1008 goto found_clock;
1009 }
1010
1011 output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf,
1006 if (input_term) {
1007 clock = input_term->bCSourceID;
1008 goto found_clock;
1009 }
1010
1011 output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf,
1012 as->bTerminalLink);
1012 as->bTerminalLink,
1013 UAC_VERSION_3);
1013 if (output_term) {
1014 clock = output_term->bCSourceID;
1015 goto found_clock;
1016 }
1017
1018 dev_err(&dev->dev, "%u:%d : bogus bTerminalLink %d\n",
1019 iface_no, altno, as->bTerminalLink);
1020 kfree(chmap);

--- 182 unchanged lines hidden ---
1014 if (output_term) {
1015 clock = output_term->bCSourceID;
1016 goto found_clock;
1017 }
1018
1019 dev_err(&dev->dev, "%u:%d : bogus bTerminalLink %d\n",
1020 iface_no, altno, as->bTerminalLink);
1021 kfree(chmap);

--- 182 unchanged lines hidden ---