Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ac5c3ee authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: core: Honor device preferred configuration"

parents b1e37ad2 38742261
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -981,6 +981,15 @@ int usb_get_bos_descriptor(struct usb_device *dev)
		case USB_PTM_CAP_TYPE:
			dev->bos->ptm_cap =
				(struct usb_ptm_cap_descriptor *)buffer;
			break;
		case USB_CAP_TYPE_CONFIG_SUMMARY:
			/* one such desc per configuration */
			if (!dev->bos->num_config_summary_desc)
				dev->bos->config_summary =
				(struct usb_config_summary_descriptor *)buffer;

			dev->bos->num_config_summary_desc++;
			break;
		default:
			break;
		}
+34 −2
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@

#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/usb/audio.h>
#include <linux/usb/audio-v3.h>
#include "usb.h"

static inline const char *plural(int n)
@@ -40,6 +42,34 @@ static int is_activesync(struct usb_interface_descriptor *desc)
		&& desc->bInterfaceProtocol == 1;
}

static int usb_audio_max_rev_config(struct usb_host_bos *bos)
{
	int desc_cnt, func_cnt, numfunc;
	int num_cfg_desc;
	struct usb_config_summary_descriptor *conf_summary;

	if (!bos || !bos->config_summary)
		goto done;

	conf_summary = bos->config_summary;
	num_cfg_desc = bos->num_config_summary_desc;

	for (desc_cnt = 0; desc_cnt < num_cfg_desc; desc_cnt++) {
		numfunc = conf_summary->bNumFunctions;
		for (func_cnt = 0; func_cnt < numfunc; func_cnt++) {
			/* honor device preferred config */
			if (conf_summary->cs_info[func_cnt].bClass ==
				USB_CLASS_AUDIO &&
				conf_summary->cs_info[func_cnt].bSubClass !=
				FULL_ADC_3_0)
				return conf_summary->bConfigurationValue;
		}
	}

done:
	return -EINVAL;
}

int usb_choose_configuration(struct usb_device *udev)
{
	int i;
@@ -130,7 +160,6 @@ int usb_choose_configuration(struct usb_device *udev)
			best = c;
			break;
		}

		/* If all the remaining configs are vendor-specific,
		 * choose the first one. */
		else if (!best)
@@ -143,6 +172,9 @@ int usb_choose_configuration(struct usb_device *udev)
			insufficient_power, plural(insufficient_power));

	if (best) {
		/* choose usb audio class preferred config if available */
		i = usb_audio_max_rev_config(udev->bos);
		if (i < 0)
			i = best->desc.bConfigurationValue;
		dev_dbg(&udev->dev,
			"configuration #%d chosen from %d choice%s\n",
+2 −0
Original line number Diff line number Diff line
@@ -333,6 +333,8 @@ struct usb_host_bos {
	struct usb_ssp_cap_descriptor	*ssp_cap;
	struct usb_ss_container_id_descriptor	*ss_id;
	struct usb_ptm_cap_descriptor	*ptm_cap;
	struct usb_config_summary_descriptor	*config_summary;
	unsigned int	num_config_summary_desc;
};

int __usb_get_extra_descriptor(char *buffer, unsigned size,
+2 −1
Original line number Diff line number Diff line
@@ -50,7 +50,8 @@
#define CLUSTER_ID_MONO		0x0001
#define CLUSTER_ID_STEREO	0x0002

#define FULL_ADC_PROFILE	0x01
/* A.2 audio function subclass codes */
#define FULL_ADC_3_0		0x01

/* BADD Profile IDs */
#define PROF_GENERIC_IO		0x20
+24 −0
Original line number Diff line number Diff line
@@ -1051,6 +1051,30 @@ struct usb_ptm_cap_descriptor {
 */
#define USB_DT_USB_SSP_CAP_SIZE(ssac)	(16 + ssac * 4)

/*
 * Configuration Summary descriptors: Defines a list of functions in the
 * configuration. This descriptor may be used by Host software to decide
 * which Configuration to use to obtain the desired functionality.
 */
#define	USB_CAP_TYPE_CONFIG_SUMMARY	0x10

struct function_class_info {
	__u8 bClass;
	__u8 bSubClass;
	__u8 bProtocol;
};

struct usb_config_summary_descriptor {
	__u8 bLength;
	__u8 bDescriptorType;
	__u8 bDevCapabilityType;
	__u16 bcdVersion;
	__u8 bConfigurationValue;
	__u8 bMaxPower;
	__u8 bNumFunctions;
	struct function_class_info cs_info[];
} __attribute__((packed));

/*-------------------------------------------------------------------------*/

/* USB_DT_WIRELESS_ENDPOINT_COMP:  companion descriptor associated with
Loading