svn commit: r336888 - stable/9/sys/dev/usb

Hans Petter Selasky hselasky at FreeBSD.org
Mon Jul 30 09:22:22 UTC 2018


Author: hselasky
Date: Mon Jul 30 09:22:21 2018
New Revision: 336888
URL: https://svnweb.freebsd.org/changeset/base/336888

Log:
  MFC r335700:
  Improve the kernel's USB descriptor reading function.
  Some USB devices does not allow a partial descriptor readout.
  
  Found by:	bz@
  Sponsored by:	Mellanox Technologies

Modified:
  stable/9/sys/dev/usb/usb_request.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/dev/usb/usb_request.c
==============================================================================
--- stable/9/sys/dev/usb/usb_request.c	Mon Jul 30 09:21:19 2018	(r336887)
+++ stable/9/sys/dev/usb/usb_request.c	Mon Jul 30 09:22:21 2018	(r336888)
@@ -981,7 +981,7 @@ usbd_req_get_desc(struct usb_device *udev,
     uint8_t retries)
 {
 	struct usb_device_request req;
-	uint8_t *buf;
+	uint8_t *buf = desc;
 	usb_error_t err;
 
 	DPRINTFN(4, "id=%d, type=%d, index=%d, max_len=%d\n",
@@ -1003,6 +1003,32 @@ usbd_req_get_desc(struct usb_device *udev,
 		err = usbd_do_request_flags(udev, mtx, &req,
 		    desc, 0, NULL, 500 /* ms */);
 
+		if (err != 0 && err != USB_ERR_TIMEOUT &&
+		    min_len != max_len) {
+			/* clear descriptor data */
+			memset(desc, 0, max_len);
+
+			/* try to read full descriptor length */
+			USETW(req.wLength, max_len);
+
+			err = usbd_do_request_flags(udev, mtx, &req,
+			    desc, USB_SHORT_XFER_OK, NULL, 500 /* ms */);
+
+			if (err == 0) {
+				/* verify length */
+				if (buf[0] > max_len)
+					buf[0] = max_len;
+				else if (buf[0] < 2)
+					err = USB_ERR_INVAL;
+
+				min_len = buf[0];
+
+				/* enforce descriptor type */
+				buf[1] = type;
+				goto done;
+			}
+		}
+
 		if (err) {
 			if (!retries) {
 				goto done;
@@ -1013,7 +1039,6 @@ usbd_req_get_desc(struct usb_device *udev,
 
 			continue;
 		}
-		buf = desc;
 
 		if (min_len == max_len) {
 


More information about the svn-src-all mailing list