mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: Barebox List <barebox@lists.infradead.org>
Subject: [PATCH 19/24] usb: factor out a usb_setup_descriptor() function
Date: Wed, 25 Mar 2020 13:31:06 +0100	[thread overview]
Message-ID: <20200325123111.9612-20-s.hauer@pengutronix.de> (raw)
In-Reply-To: <20200325123111.9612-1-s.hauer@pengutronix.de>

This factors out a usb_setup_descriptor() function with the goal to
make the code better comparable to the corresponding U-Boot code.

This also incorporates this U-Boot commit:

| commit 2b338ef41127351089254b748de5cefd95c3e800
| Author: Hans de Goede <hdegoede@redhat.com>
| Date:   Tue May 5 23:56:04 2015 +0200
|
|     usb: Fix maxpacketsize for first descriptor read for low-speed usb devs
|
|     This fixes descriptor reading of lowspeed devices through ohci not working.
|
|     Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|     Acked-by: Marek Vasut <marex@denx.de>

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/usb/core/usb.c | 155 +++++++++++++++++++++++++++--------------
 1 file changed, 103 insertions(+), 52 deletions(-)

diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index e5c80aa1da..0ed897fa49 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -272,6 +272,108 @@ static int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int c
 	return 1;
 }
 
+static int usb_get_descriptor(struct usb_device *dev, unsigned char type,
+			unsigned char index, void *buf, int size)
+{
+	int res;
+	res = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+			USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+			(type << 8) + index, 0,
+			buf, size, USB_CNTL_TIMEOUT);
+	return res;
+}
+
+static int get_descriptor_len(struct usb_device *dev, int len, int expect_len)
+{
+	int err;
+
+	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, dev->descriptor, len);
+	if (err < expect_len) {
+		if (err < 0) {
+			dev_err(&dev->dev, "unable to get device descriptor (error=%d)\n",
+				err);
+			return err;
+		} else {
+			dev_err(&dev->dev, "USB device descriptor short read (expected %i, got %i)\n",
+				expect_len, err);
+			return -EIO;
+		}
+	}
+
+        return 0;
+}
+
+static int usb_setup_descriptor(struct usb_device *dev, bool do_read)
+{
+	/*
+	 * This is a Windows scheme of initialization sequence, with double
+	 * reset of the device (Linux uses the same sequence)
+	 * Some equipment is said to work only with such init sequence; this
+	 * patch is based on the work by Alan Stern:
+	 * http://sourceforge.net/mailarchive/forum.php?
+	 * thread_id=5729457&forum_id=5398
+	 */
+
+	/*
+	 * send 64-byte GET-DEVICE-DESCRIPTOR request.  Since the descriptor is
+	 * only 18 bytes long, this will terminate with a short packet.  But if
+	 * the maxpacket size is 8 or 16 the device may be waiting to transmit
+	 * some more, or keeps on retransmitting the 8 byte header.
+	 */
+
+	if (dev->speed == USB_SPEED_LOW) {
+		dev->descriptor->bMaxPacketSize0 = 8;
+		dev->maxpacketsize = PACKET_SIZE_8;
+	} else {
+		dev->descriptor->bMaxPacketSize0 = 64;
+		dev->maxpacketsize = PACKET_SIZE_64;
+	}
+
+	if (do_read && dev->speed == USB_SPEED_FULL) {
+		int err;
+
+		/*
+		 * Validate we've received only at least 8 bytes, not that
+		 * we've received the entire descriptor. The reasoning is:
+		 * - The code only uses fields in the first 8 bytes, so
+		 *   that's all we need to have fetched at this stage.
+		 * - The smallest maxpacket size is 8 bytes. Before we know
+		 *   the actual maxpacket the device uses, the USB controller
+		 *   may only accept a single packet. Consequently we are only
+		 *   guaranteed to receive 1 packet (at least 8 bytes) even in
+		 *   a non-error case.
+		 *
+		 * At least the DWC2 controller needs to be programmed with
+		 * the number of packets in addition to the number of bytes.
+		 * A request for 64 bytes of data with the maxpacket guessed
+		 * as 64 (above) yields a request for 1 packet.
+		 */
+		err = get_descriptor_len(dev, 64, 8);
+		if (err)
+			return err;
+	}
+
+	dev->epmaxpacketin[0] = dev->descriptor->bMaxPacketSize0;
+	dev->epmaxpacketout[0] = dev->descriptor->bMaxPacketSize0;
+
+	switch (dev->descriptor->bMaxPacketSize0) {
+	case 8:
+		dev->maxpacketsize  = PACKET_SIZE_8;
+		break;
+	case 16:
+		dev->maxpacketsize = PACKET_SIZE_16;
+		break;
+	case 32:
+		dev->maxpacketsize = PACKET_SIZE_32;
+		break;
+	case 64:
+		dev->maxpacketsize = PACKET_SIZE_64;
+		break;
+	}
+
+	return 0;
+}
+
 /**
  * set address of a device to the value in dev->devnum.
  * This can only be done by addressing the device via the default address (0)
@@ -289,17 +391,6 @@ static int usb_set_address(struct usb_device *dev)
 	return res;
 }
 
-static int usb_get_descriptor(struct usb_device *dev, unsigned char type,
-			unsigned char index, void *buf, int size)
-{
-	int res;
-	res = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-			USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
-			(type << 8) + index, 0,
-			buf, size, USB_CNTL_TIMEOUT);
-	return res;
-}
-
 /*
  * By the time we get here, the device is in the default state. We need to
  * identify the thing and get the ball rolling..
@@ -324,53 +415,13 @@ int usb_new_device(struct usb_device *dev)
 
 	buf = dma_alloc(USB_BUFSIZ);
 
-	/* This is a Windows scheme of initialization sequence, with double
-	 * reset of the device (Linux uses the same sequence)
-	 * Some equipment is said to work only with such init sequence; this
-	 * patch is based on the work by Alan Stern:
-	 * http://sourceforge.net/mailarchive/forum.php?
-	 * thread_id=5729457&forum_id=5398
-	 */
-
-	/* send 64-byte GET-DEVICE-DESCRIPTOR request.  Since the descriptor is
-	 * only 18 bytes long, this will terminate with a short packet.  But if
-	 * the maxpacket size is 8 or 16 the device may be waiting to transmit
-	 * some more, or keeps on retransmitting the 8 byte header. */
-
 	desc = buf;
-	dev->descriptor->bMaxPacketSize0 = 64;	    /* Start off at 64 bytes  */
-	/* Default to 64 byte max packet size */
-	dev->maxpacketsize = PACKET_SIZE_64;
-	dev->epmaxpacketin[0] = 64;
-	dev->epmaxpacketout[0] = 64;
 
 	if (parent)
 		dev->level = parent->level + 1;
 
-	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
-	if (err < 0) {
-		dev_dbg(&dev->dev, "%s: usb_get_descriptor() failed with %d\n", __func__, err);
-		goto err_out;
-	}
-
-	dev->descriptor->bMaxPacketSize0 = desc->bMaxPacketSize0;
+	usb_setup_descriptor(dev, true);
 
-	dev->epmaxpacketin[0] = dev->descriptor->bMaxPacketSize0;
-	dev->epmaxpacketout[0] = dev->descriptor->bMaxPacketSize0;
-	switch (dev->descriptor->bMaxPacketSize0) {
-	case 8:
-		dev->maxpacketsize  = PACKET_SIZE_8;
-		break;
-	case 16:
-		dev->maxpacketsize = PACKET_SIZE_16;
-		break;
-	case 32:
-		dev->maxpacketsize = PACKET_SIZE_32;
-		break;
-	case 64:
-		dev->maxpacketsize = PACKET_SIZE_64;
-		break;
-	}
 	dev->devnum = ++dev_index;
 
 	err = usb_set_address(dev); /* set address */
-- 
2.26.0.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  parent reply	other threads:[~2020-03-25 12:31 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-25 12:30 [PATCH 00/24] USB3 support Sascha Hauer
2020-03-25 12:30 ` [PATCH 01/24] usb: hub: Make debugging output more consistent Sascha Hauer
2020-03-25 12:30 ` [PATCH 02/24] usb: hub: do not reset devices twice Sascha Hauer
2020-03-25 12:30 ` [PATCH 03/24] usb: hub: let usb_scan_port() return void Sascha Hauer
2020-03-25 12:30 ` [PATCH 04/24] usb: Remove hack from the early days Sascha Hauer
2020-03-25 12:30 ` [PATCH 05/24] usb: Pass portstatus/portchange to usb_hub_port_connect_change() Sascha Hauer
2020-03-25 12:30 ` [PATCH 06/24] usb: hub: Do not power-cycle usb devices on init Sascha Hauer
2020-03-25 12:30 ` [PATCH 07/24] usb: Make driver_info const Sascha Hauer
2020-03-25 12:30 ` [PATCH 08/24] usb: Set new USB device name earlier Sascha Hauer
2020-03-25 12:30 ` [PATCH 09/24] usb: Use dev_* Sascha Hauer
2020-03-25 12:30 ` [PATCH 10/24] usb: hub: Parse and save TT details from device descriptor Sascha Hauer
2020-03-25 12:30 ` [PATCH 11/24] usb: host: make init hook optional Sascha Hauer
2020-03-25 12:30 ` [PATCH 12/24] usb: support set hub depth request for USB 3.0 hubs Sascha Hauer
2020-03-25 12:31 ` [PATCH 13/24] usb: Assign dev_index once Sascha Hauer
2020-03-25 12:31 ` [PATCH 14/24] usb: remove unnecessary variable Sascha Hauer
2020-03-25 12:31 ` [PATCH 15/24] usb: net: Allocate rx buffer dynamically Sascha Hauer
2020-03-25 14:18   ` Jules Maselbas
2020-03-26  6:22     ` Sascha Hauer
2020-03-25 12:31 ` [PATCH 16/24] usb: net: Allocate tx " Sascha Hauer
2020-03-25 12:31 ` [PATCH 17/24] net: usb: add hook for link changes Sascha Hauer
2020-03-25 12:31 ` [PATCH 18/24] usb: net: Add support for the Asix AX88179 Sascha Hauer
2020-03-25 12:31 ` Sascha Hauer [this message]
2020-03-25 12:31 ` [PATCH 20/24] usb: hub: Translate USB 3.0 hub port status into old version Sascha Hauer
2020-03-25 12:31 ` [PATCH 21/24] usb: Add super speed support Sascha Hauer
2020-03-25 12:31 ` [PATCH 22/24] usb: hub: When no connection came up remove from scanning list Sascha Hauer
2020-03-25 12:31 ` [PATCH 23/24] usb: host: remove xhci driver Sascha Hauer
2020-03-25 12:31 ` [PATCH 24/24] usb: Add U-Boot " Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200325123111.9612-20-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox