[PATCH v3 2/4] usb: usbtest: support usb2 extension descriptor test

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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: Huang Rui <ray.huang@xxxxxxx>
---
 drivers/usb/misc/usbtest.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 77 insertions(+)

diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 38ebe1d..d9ac215 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -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, char *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;
+		char *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 = (char *)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] */
-- 
1.7.11.7


--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux