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

Commit 82f92672 authored by Huang Rui's avatar Huang Rui Committed by Greg Kroah-Hartman
Browse files

usb: usbtest: support usb2 extension descriptor test



In Test 9 of usbtest module, it is used for performing chapter 9 tests N
times.

USB2.0 Extension descriptor is one of the generic device-level capbility
descriptors which added in section 9.6.2.1 of USB 3.0 spec.

This patch adds to support getting usb2.0 extension descriptor test
scenario for USB 3.0.

Signed-off-by: default avatarHuang Rui <ray.huang@amd.com>
Acked-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c2ec3a73
Loading
Loading
Loading
Loading
+77 −0
Original line number Diff line number Diff line
@@ -606,6 +606,28 @@ static int is_good_config(struct usbtest_dev *tdev, int len)
	return 0;
}

static int is_good_ext(struct usbtest_dev *tdev, u8 *buf)
{
	struct usb_ext_cap_descriptor *ext;
	u32 attr;

	ext = (struct usb_ext_cap_descriptor *) buf;

	if (ext->bLength != USB_DT_USB_EXT_CAP_SIZE) {
		ERROR(tdev, "bogus usb 2.0 extension descriptor length\n");
		return 0;
	}

	attr = le32_to_cpu(ext->bmAttributes);
	/* bits[1:4] is used and others are reserved */
	if (attr & ~0x1e) {	/* reserved == 0 */
		ERROR(tdev, "reserved bits set\n");
		return 0;
	}

	return 1;
}

/* sanity test for standard requests working with usb_control_mesg() and some
 * of the utility functions which use it.
 *
@@ -694,12 +716,67 @@ static int ch9_postconfig(struct usbtest_dev *dev)
	 * 3.0 spec
	 */
	if (le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0300) {
		struct usb_bos_descriptor *bos = NULL;
		struct usb_dev_cap_header *header = NULL;
		unsigned total, num, length;
		u8 *buf;

		retval = usb_get_descriptor(udev, USB_DT_BOS, 0, dev->buf,
				sizeof(*udev->bos->desc));
		if (retval != sizeof(*udev->bos->desc)) {
			dev_err(&iface->dev, "bos descriptor --> %d\n", retval);
			return (retval < 0) ? retval : -EDOM;
		}

		bos = (struct usb_bos_descriptor *)dev->buf;
		total = le16_to_cpu(bos->wTotalLength);
		num = bos->bNumDeviceCaps;

		if (total > TBUF_SIZE)
			total = TBUF_SIZE;

		/*
		 * get generic device-level capability descriptors [9.6.2]
		 * in USB 3.0 spec
		 */
		retval = usb_get_descriptor(udev, USB_DT_BOS, 0, dev->buf,
				total);
		if (retval != total) {
			dev_err(&iface->dev, "bos descriptor set --> %d\n",
					retval);
			return (retval < 0) ? retval : -EDOM;
		}

		length = sizeof(*udev->bos->desc);
		buf = dev->buf;
		for (i = 0; i < num; i++) {
			buf += length;
			if (buf + sizeof(struct usb_dev_cap_header) >
					dev->buf + total)
				break;

			header = (struct usb_dev_cap_header *)buf;
			length = header->bLength;

			if (header->bDescriptorType !=
					USB_DT_DEVICE_CAPABILITY) {
				dev_warn(&udev->dev, "not device capability descriptor, skip\n");
				continue;
			}

			switch (header->bDevCapabilityType) {
			case USB_CAP_TYPE_EXT:
				if (buf + USB_DT_USB_EXT_CAP_SIZE >
						dev->buf + total ||
						!is_good_ext(dev, buf)) {
					dev_err(&iface->dev, "bogus usb 2.0 extension descriptor\n");
					return -EDOM;
				}
				break;
			default:
				break;
			}
		}
	}

	/* there's always [9.4.3] at least one config descriptor [9.6.3] */