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

Commit 71a55a93 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: core: Add support to parse config summary capability descriptors"

parents 9e2c041e 1f64d4e3
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1020,6 +1020,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 function */
			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 −1
Original line number Diff line number Diff line
@@ -42,6 +42,36 @@ static int is_activesync(struct usb_interface_descriptor *desc)
		&& desc->bInterfaceProtocol == 1;
}

static int get_usb_audio_config(struct usb_host_bos *bos)
{
	unsigned int desc_cnt, num_cfg_desc, len = 0;
	unsigned char *buffer;
	struct usb_config_summary_descriptor *conf_summary;

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

	num_cfg_desc = bos->num_config_summary_desc;
	conf_summary = bos->config_summary;
	buffer = (unsigned char *)conf_summary;
	for (desc_cnt = 0; desc_cnt < num_cfg_desc; desc_cnt++) {
		conf_summary =
			(struct usb_config_summary_descriptor *)(buffer + len);

		len += conf_summary->bLength;

		if (conf_summary->bcdVersion != USB_CONFIG_SUMMARY_DESC_REV ||
				conf_summary->bClass != USB_CLASS_AUDIO)
			continue;

		/* return 1st config as per device preference */
		return conf_summary->bConfigurationIndex[0];
	}

done:
	return -EINVAL;
}

int usb_choose_configuration(struct usb_device *udev)
{
	int i;
@@ -145,6 +175,9 @@ int usb_choose_configuration(struct usb_device *udev)
			insufficient_power, plural(insufficient_power));

	if (best) {
		/* choose device preferred config */
		i = get_usb_audio_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
@@ -404,6 +404,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,
+20 −0
Original line number Diff line number Diff line
@@ -1081,6 +1081,26 @@ struct usb_ptm_cap_descriptor {
 */
#define USB_DT_USB_SSP_CAP_SIZE(ssac)	(12 + (ssac + 1) * 4)

/*
 * Configuration Summary descriptors: Defines a list of device preferred
 * configurations. 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
#define USB_CONFIG_SUMMARY_DESC_REV	0x100

struct usb_config_summary_descriptor {
	__u8 bLength;
	__u8 bDescriptorType;
	__u8 bDevCapabilityType;
	__u16 bcdVersion;
	__u8 bClass;
	__u8 bSubClass;
	__u8 bProtocol;
	__u8 bConfigurationCount;
	__u8 bConfigurationIndex[];
} __attribute__((packed));

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

/* USB_DT_WIRELESS_ENDPOINT_COMP:  companion descriptor associated with