Commit 347f3f54 authored by Neal Liu's avatar Neal Liu Committed by Greg Kroah-Hartman
Browse files

usb: aspeed-vhub: add qualifier descriptor



USB3 Command Verifier (USB3CV) is the official tool for
USB3 Hub and Device Framework testing.

A high-speed capable device that has different device information
for full-speed and high-speed must have a Device Qualifier Descriptor.

This patch is to support device qualifier to pass
USB3CV - Chapter 9 Test [USB 2 devices] - Device Qualifier Tests.

Signed-off-by: default avatarNeal Liu <neal_liu@aspeedtech.com>
Link: https://lore.kernel.org/r/20211208100545.1441397-2-neal_liu@aspeedtech.com


Acked-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a92548f9
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -68,6 +68,18 @@ static const struct usb_device_descriptor ast_vhub_dev_desc = {
	.bNumConfigurations	= 1,
};

static const struct usb_qualifier_descriptor ast_vhub_qual_desc = {
	.bLength = 0xA,
	.bDescriptorType = USB_DT_DEVICE_QUALIFIER,
	.bcdUSB = cpu_to_le16(0x0200),
	.bDeviceClass = USB_CLASS_HUB,
	.bDeviceSubClass = 0,
	.bDeviceProtocol = 0,
	.bMaxPacketSize0 = 64,
	.bNumConfigurations = 1,
	.bRESERVED = 0,
};

/*
 * Configuration descriptor: same comments as above
 * regarding handling USB1 mode.
@@ -271,9 +283,11 @@ static int ast_vhub_rep_desc(struct ast_vhub_ep *ep,
		BUILD_BUG_ON(dsize > sizeof(vhub->vhub_dev_desc));
		BUILD_BUG_ON(USB_DT_DEVICE_SIZE >= AST_VHUB_EP0_MAX_PACKET);
		break;
	case USB_DT_OTHER_SPEED_CONFIG:
	case USB_DT_CONFIG:
		dsize = AST_VHUB_CONF_DESC_SIZE;
		memcpy(ep->buf, &vhub->vhub_conf_desc, dsize);
		((u8 *)ep->buf)[1] = desc_type;
		BUILD_BUG_ON(dsize > sizeof(vhub->vhub_conf_desc));
		BUILD_BUG_ON(AST_VHUB_CONF_DESC_SIZE >= AST_VHUB_EP0_MAX_PACKET);
		break;
@@ -283,6 +297,10 @@ static int ast_vhub_rep_desc(struct ast_vhub_ep *ep,
		BUILD_BUG_ON(dsize > sizeof(vhub->vhub_hub_desc));
		BUILD_BUG_ON(AST_VHUB_HUB_DESC_SIZE >= AST_VHUB_EP0_MAX_PACKET);
		break;
	case USB_DT_DEVICE_QUALIFIER:
		dsize = sizeof(vhub->vhub_qual_desc);
		memcpy(ep->buf, &vhub->vhub_qual_desc, dsize);
		break;
	default:
		return std_req_stall;
	}
@@ -428,6 +446,8 @@ enum std_req_rc ast_vhub_std_hub_request(struct ast_vhub_ep *ep,
		switch (wValue >> 8) {
		case USB_DT_DEVICE:
		case USB_DT_CONFIG:
		case USB_DT_DEVICE_QUALIFIER:
		case USB_DT_OTHER_SPEED_CONFIG:
			return ast_vhub_rep_desc(ep, wValue >> 8,
						 wLength);
		case USB_DT_STRING:
@@ -1033,6 +1053,10 @@ static int ast_vhub_init_desc(struct ast_vhub *vhub)
	else
		ret = ast_vhub_str_alloc_add(vhub, &ast_vhub_strings);

	/* Initialize vhub Qualifier Descriptor. */
	memcpy(&vhub->vhub_qual_desc, &ast_vhub_qual_desc,
		sizeof(vhub->vhub_qual_desc));

	return ret;
}

+1 −0
Original line number Diff line number Diff line
@@ -425,6 +425,7 @@ struct ast_vhub {
	struct ast_vhub_full_cdesc	vhub_conf_desc;
	struct usb_hub_descriptor	vhub_hub_desc;
	struct list_head		vhub_str_desc;
	struct usb_qualifier_descriptor	vhub_qual_desc;
};

/* Standard request handlers result codes */