xref: /openbmc/u-boot/common/usb.c (revision 67cf22cbdef8c62ffa28b4caf935825fe410c68d)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2affae2bfSwdenk /*
3affae2bfSwdenk  * Most of this source has been derived from the Linux USB
4460c322fSWolfgang Denk  * project:
5460c322fSWolfgang Denk  * (C) Copyright Linus Torvalds 1999
6460c322fSWolfgang Denk  * (C) Copyright Johannes Erdfelt 1999-2001
7460c322fSWolfgang Denk  * (C) Copyright Andreas Gal 1999
8460c322fSWolfgang Denk  * (C) Copyright Gregory P. Smith 1999
9460c322fSWolfgang Denk  * (C) Copyright Deti Fliegl 1999 (new USB architecture)
10460c322fSWolfgang Denk  * (C) Copyright Randy Dunlap 2000
11460c322fSWolfgang Denk  * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id)
12460c322fSWolfgang Denk  * (C) Copyright Yggdrasil Computing, Inc. 2000
13460c322fSWolfgang Denk  *     (usb_device_id matching changes by Adam J. Richter)
14460c322fSWolfgang Denk  *
15460c322fSWolfgang Denk  * Adapted for U-Boot:
16460c322fSWolfgang Denk  * (C) Copyright 2001 Denis Peter, MPL AG Switzerland
17affae2bfSwdenk  */
18affae2bfSwdenk 
19affae2bfSwdenk /*
20affae2bfSwdenk  * How it works:
21affae2bfSwdenk  *
22affae2bfSwdenk  * Since this is a bootloader, the devices will not be automatic
23affae2bfSwdenk  * (re)configured on hotplug, but after a restart of the USB the
24affae2bfSwdenk  * device should work.
25affae2bfSwdenk  *
26affae2bfSwdenk  * For each transfer (except "Interrupt") we wait for completion.
27affae2bfSwdenk  */
28affae2bfSwdenk #include <common.h>
29affae2bfSwdenk #include <command.h>
3095fbfe42SSimon Glass #include <dm.h>
31cf92e05cSSimon Glass #include <memalign.h>
32affae2bfSwdenk #include <asm/processor.h>
3366cf6410SMike Frysinger #include <linux/compiler.h>
349c998aa8SWolfgang Denk #include <linux/ctype.h>
35c918261cSChristian Eggers #include <asm/byteorder.h>
36b2fb47f1STom Rini #include <asm/unaligned.h>
3797b9eb9eSMarek Vasut #include <errno.h>
38affae2bfSwdenk #include <usb.h>
39affae2bfSwdenk 
40cd0a9de6Swdenk #define USB_BUFSIZ	512
41cd0a9de6Swdenk 
4295fbfe42SSimon Glass static int asynch_allowed;
4395fbfe42SSimon Glass char usb_started; /* flag for the started/stopped USB status */
4495fbfe42SSimon Glass 
45*fd09c205SSven Schwermer #if !CONFIG_IS_ENABLED(DM_USB)
46affae2bfSwdenk static struct usb_device usb_dev[USB_MAX_DEVICE];
47affae2bfSwdenk static int dev_index;
48e51aae38SBartlomiej Sieka 
4993c2582fSLucas Stach #ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
5093c2582fSLucas Stach #define CONFIG_USB_MAX_CONTROLLER_COUNT 1
5193c2582fSLucas Stach #endif
52affae2bfSwdenk 
53affae2bfSwdenk /***************************************************************************
54affae2bfSwdenk  * Init USB Device
55affae2bfSwdenk  */
56affae2bfSwdenk int usb_init(void)
57affae2bfSwdenk {
5893c2582fSLucas Stach 	void *ctrl;
5993c2582fSLucas Stach 	struct usb_device *dev;
6093c2582fSLucas Stach 	int i, start_index = 0;
61d906bbc2SHans de Goede 	int controllers_initialized = 0;
6297b9eb9eSMarek Vasut 	int ret;
63affae2bfSwdenk 
64affae2bfSwdenk 	dev_index = 0;
65affae2bfSwdenk 	asynch_allowed = 1;
66affae2bfSwdenk 	usb_hub_reset();
6793c2582fSLucas Stach 
6893c2582fSLucas Stach 	/* first make all devices unknown */
6993c2582fSLucas Stach 	for (i = 0; i < USB_MAX_DEVICE; i++) {
7093c2582fSLucas Stach 		memset(&usb_dev[i], 0, sizeof(struct usb_device));
7193c2582fSLucas Stach 		usb_dev[i].devnum = -1;
7293c2582fSLucas Stach 	}
7393c2582fSLucas Stach 
74affae2bfSwdenk 	/* init low_level USB */
7593c2582fSLucas Stach 	for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) {
7693c2582fSLucas Stach 		/* init low_level USB */
7793c2582fSLucas Stach 		printf("USB%d:   ", i);
7897b9eb9eSMarek Vasut 		ret = usb_lowlevel_init(i, USB_INIT_HOST, &ctrl);
7997b9eb9eSMarek Vasut 		if (ret == -ENODEV) {	/* No such device. */
8097b9eb9eSMarek Vasut 			puts("Port not available.\n");
81d906bbc2SHans de Goede 			controllers_initialized++;
8297b9eb9eSMarek Vasut 			continue;
8397b9eb9eSMarek Vasut 		}
8497b9eb9eSMarek Vasut 
8597b9eb9eSMarek Vasut 		if (ret) {		/* Other error. */
8693c2582fSLucas Stach 			puts("lowlevel init failed\n");
8793c2582fSLucas Stach 			continue;
8893c2582fSLucas Stach 		}
8993c2582fSLucas Stach 		/*
9093c2582fSLucas Stach 		 * lowlevel init is OK, now scan the bus for devices
9193c2582fSLucas Stach 		 * i.e. search HUBs and configure them
9293c2582fSLucas Stach 		 */
93d906bbc2SHans de Goede 		controllers_initialized++;
9493c2582fSLucas Stach 		start_index = dev_index;
9593c2582fSLucas Stach 		printf("scanning bus %d for devices... ", i);
9679b58887SSimon Glass 		ret = usb_alloc_new_device(ctrl, &dev);
9779b58887SSimon Glass 		if (ret)
988879be88SPaul Kocialkowski 			break;
998879be88SPaul Kocialkowski 
10093c2582fSLucas Stach 		/*
10193c2582fSLucas Stach 		 * device 0 is always present
10293c2582fSLucas Stach 		 * (root hub, so let it analyze)
10393c2582fSLucas Stach 		 */
1048879be88SPaul Kocialkowski 		ret = usb_new_device(dev);
1058879be88SPaul Kocialkowski 		if (ret)
10679b58887SSimon Glass 			usb_free_device(dev->controller);
10793c2582fSLucas Stach 
1088879be88SPaul Kocialkowski 		if (start_index == dev_index) {
10993c2582fSLucas Stach 			puts("No USB Device found\n");
1108879be88SPaul Kocialkowski 			continue;
1118879be88SPaul Kocialkowski 		} else {
11293c2582fSLucas Stach 			printf("%d USB Device(s) found\n",
11393c2582fSLucas Stach 				dev_index - start_index);
1148879be88SPaul Kocialkowski 		}
11593c2582fSLucas Stach 
116e51aae38SBartlomiej Sieka 		usb_started = 1;
11793c2582fSLucas Stach 	}
11893c2582fSLucas Stach 
119ceb4972aSVivek Gautam 	debug("scan end\n");
12093c2582fSLucas Stach 	/* if we were not able to find at least one working bus, bail out */
121d906bbc2SHans de Goede 	if (controllers_initialized == 0)
12293c2582fSLucas Stach 		puts("USB error: all controllers failed lowlevel init\n");
12393c2582fSLucas Stach 
1245a80b344SPaul Kocialkowski 	return usb_started ? 0 : -ENODEV;
125affae2bfSwdenk }
126affae2bfSwdenk 
127affae2bfSwdenk /******************************************************************************
128affae2bfSwdenk  * Stop USB this stops the LowLevel Part and deregisters USB devices.
129affae2bfSwdenk  */
130affae2bfSwdenk int usb_stop(void)
131affae2bfSwdenk {
13293c2582fSLucas Stach 	int i;
133eba1f2fcSRemy Bohmer 
134eba1f2fcSRemy Bohmer 	if (usb_started) {
135affae2bfSwdenk 		asynch_allowed = 1;
136e51aae38SBartlomiej Sieka 		usb_started = 0;
137affae2bfSwdenk 		usb_hub_reset();
13893c2582fSLucas Stach 
13993c2582fSLucas Stach 		for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) {
14093c2582fSLucas Stach 			if (usb_lowlevel_stop(i))
14193c2582fSLucas Stach 				printf("failed to stop USB controller %d\n", i);
142eba1f2fcSRemy Bohmer 		}
14393c2582fSLucas Stach 	}
14493c2582fSLucas Stach 
14593c2582fSLucas Stach 	return 0;
146affae2bfSwdenk }
147affae2bfSwdenk 
14808f3bb0bSVincent Palatin /******************************************************************************
14908f3bb0bSVincent Palatin  * Detect if a USB device has been plugged or unplugged.
15008f3bb0bSVincent Palatin  */
15108f3bb0bSVincent Palatin int usb_detect_change(void)
15208f3bb0bSVincent Palatin {
15308f3bb0bSVincent Palatin 	int i, j;
15408f3bb0bSVincent Palatin 	int change = 0;
15508f3bb0bSVincent Palatin 
15608f3bb0bSVincent Palatin 	for (j = 0; j < USB_MAX_DEVICE; j++) {
15708f3bb0bSVincent Palatin 		for (i = 0; i < usb_dev[j].maxchild; i++) {
15808f3bb0bSVincent Palatin 			struct usb_port_status status;
15908f3bb0bSVincent Palatin 
16008f3bb0bSVincent Palatin 			if (usb_get_port_status(&usb_dev[j], i + 1,
16108f3bb0bSVincent Palatin 						&status) < 0)
16208f3bb0bSVincent Palatin 				/* USB request failed */
16308f3bb0bSVincent Palatin 				continue;
16408f3bb0bSVincent Palatin 
16508f3bb0bSVincent Palatin 			if (le16_to_cpu(status.wPortChange) &
16608f3bb0bSVincent Palatin 			    USB_PORT_STAT_C_CONNECTION)
16708f3bb0bSVincent Palatin 				change++;
16808f3bb0bSVincent Palatin 		}
16908f3bb0bSVincent Palatin 	}
17008f3bb0bSVincent Palatin 
17108f3bb0bSVincent Palatin 	return change;
17208f3bb0bSVincent Palatin }
17308f3bb0bSVincent Palatin 
174affae2bfSwdenk /*
175affae2bfSwdenk  * disables the asynch behaviour of the control message. This is used for data
176affae2bfSwdenk  * transfers that uses the exclusiv access to the control and bulk messages.
17789d48367SSimon Glass  * Returns the old value so it can be restored later.
178affae2bfSwdenk  */
17989d48367SSimon Glass int usb_disable_asynch(int disable)
180affae2bfSwdenk {
18189d48367SSimon Glass 	int old_value = asynch_allowed;
18289d48367SSimon Glass 
183affae2bfSwdenk 	asynch_allowed = !disable;
18489d48367SSimon Glass 	return old_value;
185affae2bfSwdenk }
186*fd09c205SSven Schwermer #endif /* !CONFIG_IS_ENABLED(DM_USB) */
187affae2bfSwdenk 
188affae2bfSwdenk 
189affae2bfSwdenk /*-------------------------------------------------------------------
190affae2bfSwdenk  * Message wrappers.
191affae2bfSwdenk  *
192affae2bfSwdenk  */
193affae2bfSwdenk 
194affae2bfSwdenk /*
195affae2bfSwdenk  * submits an Interrupt Message
196affae2bfSwdenk  */
197affae2bfSwdenk int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe,
198affae2bfSwdenk 			void *buffer, int transfer_len, int interval)
199affae2bfSwdenk {
200affae2bfSwdenk 	return submit_int_msg(dev, pipe, buffer, transfer_len, interval);
201affae2bfSwdenk }
202affae2bfSwdenk 
203affae2bfSwdenk /*
204affae2bfSwdenk  * submits a control message and waits for comletion (at least timeout * 1ms)
205affae2bfSwdenk  * If timeout is 0, we don't wait for completion (used as example to set and
206affae2bfSwdenk  * clear keyboards LEDs). For data transfers, (storage transfers) we don't
207affae2bfSwdenk  * allow control messages with 0 timeout, by previousely resetting the flag
208affae2bfSwdenk  * asynch_allowed (usb_disable_asynch(1)).
209a6f70a3dSVagrant Cascadian  * returns the transferred length if OK or -1 if error. The transferred length
210affae2bfSwdenk  * and the current status are stored in the dev->act_len and dev->status.
211affae2bfSwdenk  */
212affae2bfSwdenk int usb_control_msg(struct usb_device *dev, unsigned int pipe,
213affae2bfSwdenk 			unsigned char request, unsigned char requesttype,
214affae2bfSwdenk 			unsigned short value, unsigned short index,
215affae2bfSwdenk 			void *data, unsigned short size, int timeout)
216affae2bfSwdenk {
217f5766139SPuneet Saxena 	ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet, 1);
218651d95c8SHans de Goede 	int err;
219e159e486SMarek Vasut 
2206f5794a6SRemy Bohmer 	if ((timeout == 0) && (!asynch_allowed)) {
2216f5794a6SRemy Bohmer 		/* request for a asynch control pipe is not allowed */
2225a80b344SPaul Kocialkowski 		return -EINVAL;
2236f5794a6SRemy Bohmer 	}
2249c998aa8SWolfgang Denk 
225affae2bfSwdenk 	/* set setup command */
226f5766139SPuneet Saxena 	setup_packet->requesttype = requesttype;
227f5766139SPuneet Saxena 	setup_packet->request = request;
228f5766139SPuneet Saxena 	setup_packet->value = cpu_to_le16(value);
229f5766139SPuneet Saxena 	setup_packet->index = cpu_to_le16(index);
230f5766139SPuneet Saxena 	setup_packet->length = cpu_to_le16(size);
231ceb4972aSVivek Gautam 	debug("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
2326f5794a6SRemy Bohmer 	      "value 0x%X index 0x%X length 0x%X\n",
233affae2bfSwdenk 	      request, requesttype, value, index, size);
234affae2bfSwdenk 	dev->status = USB_ST_NOT_PROC; /*not yet processed */
235affae2bfSwdenk 
236651d95c8SHans de Goede 	err = submit_control_msg(dev, pipe, data, size, setup_packet);
237651d95c8SHans de Goede 	if (err < 0)
238651d95c8SHans de Goede 		return err;
2396f5794a6SRemy Bohmer 	if (timeout == 0)
240affae2bfSwdenk 		return (int)size;
2416f5794a6SRemy Bohmer 
24248867208SRemy Bohmer 	/*
24384d36b30SRemy Bohmer 	 * Wait for status to update until timeout expires, USB driver
24484d36b30SRemy Bohmer 	 * interrupt handler may set the status when the USB operation has
24584d36b30SRemy Bohmer 	 * been completed.
24648867208SRemy Bohmer 	 */
24784d36b30SRemy Bohmer 	while (timeout--) {
24884d36b30SRemy Bohmer 		if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC))
24984d36b30SRemy Bohmer 			break;
2505b84dd67SMike Frysinger 		mdelay(1);
251affae2bfSwdenk 	}
25284d36b30SRemy Bohmer 	if (dev->status)
25384d36b30SRemy Bohmer 		return -1;
254affae2bfSwdenk 
25548867208SRemy Bohmer 	return dev->act_len;
25684d36b30SRemy Bohmer 
25748867208SRemy Bohmer }
25848867208SRemy Bohmer 
259affae2bfSwdenk /*-------------------------------------------------------------------
260affae2bfSwdenk  * submits bulk message, and waits for completion. returns 0 if Ok or
2615a80b344SPaul Kocialkowski  * negative if Error.
262affae2bfSwdenk  * synchronous behavior
263affae2bfSwdenk  */
264affae2bfSwdenk int usb_bulk_msg(struct usb_device *dev, unsigned int pipe,
265affae2bfSwdenk 			void *data, int len, int *actual_length, int timeout)
266affae2bfSwdenk {
267affae2bfSwdenk 	if (len < 0)
2685a80b344SPaul Kocialkowski 		return -EINVAL;
269affae2bfSwdenk 	dev->status = USB_ST_NOT_PROC; /*not yet processed */
270fd06028dSIlya Yanok 	if (submit_bulk_msg(dev, pipe, data, len) < 0)
2715a80b344SPaul Kocialkowski 		return -EIO;
272affae2bfSwdenk 	while (timeout--) {
273affae2bfSwdenk 		if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC))
274affae2bfSwdenk 			break;
2755b84dd67SMike Frysinger 		mdelay(1);
276affae2bfSwdenk 	}
277affae2bfSwdenk 	*actual_length = dev->act_len;
278affae2bfSwdenk 	if (dev->status == 0)
279affae2bfSwdenk 		return 0;
280affae2bfSwdenk 	else
2815a80b344SPaul Kocialkowski 		return -EIO;
282affae2bfSwdenk }
283affae2bfSwdenk 
284affae2bfSwdenk 
285affae2bfSwdenk /*-------------------------------------------------------------------
286affae2bfSwdenk  * Max Packet stuff
287affae2bfSwdenk  */
288affae2bfSwdenk 
289affae2bfSwdenk /*
290affae2bfSwdenk  * returns the max packet size, depending on the pipe direction and
291affae2bfSwdenk  * the configurations values
292affae2bfSwdenk  */
293affae2bfSwdenk int usb_maxpacket(struct usb_device *dev, unsigned long pipe)
294affae2bfSwdenk {
2956f5794a6SRemy Bohmer 	/* direction is out -> use emaxpacket out */
2966f5794a6SRemy Bohmer 	if ((pipe & USB_DIR_IN) == 0)
297de39f8c1SMichael Trimarchi 		return dev->epmaxpacketout[((pipe>>15) & 0xf)];
298affae2bfSwdenk 	else
299de39f8c1SMichael Trimarchi 		return dev->epmaxpacketin[((pipe>>15) & 0xf)];
300affae2bfSwdenk }
301affae2bfSwdenk 
3025e8baf87SMarek Vasut /*
3035e8baf87SMarek Vasut  * The routine usb_set_maxpacket_ep() is extracted from the loop of routine
304be19d324SRemy Bohmer  * usb_set_maxpacket(), because the optimizer of GCC 4.x chokes on this routine
305be19d324SRemy Bohmer  * when it is inlined in 1 single routine. What happens is that the register r3
306be19d324SRemy Bohmer  * is used as loop-count 'i', but gets overwritten later on.
307be19d324SRemy Bohmer  * This is clearly a compiler bug, but it is easier to workaround it here than
308be19d324SRemy Bohmer  * to update the compiler (Occurs with at least several GCC 4.{1,2},x
309be19d324SRemy Bohmer  * CodeSourcery compilers like e.g. 2007q3, 2008q1, 2008q3 lite editions on ARM)
3105e8baf87SMarek Vasut  *
3115e8baf87SMarek Vasut  * NOTE: Similar behaviour was observed with GCC4.6 on ARMv5.
312be19d324SRemy Bohmer  */
31366cf6410SMike Frysinger static void noinline
3145e8baf87SMarek Vasut usb_set_maxpacket_ep(struct usb_device *dev, int if_idx, int ep_idx)
315be19d324SRemy Bohmer {
316be19d324SRemy Bohmer 	int b;
3175e8baf87SMarek Vasut 	struct usb_endpoint_descriptor *ep;
318b2fb47f1STom Rini 	u16 ep_wMaxPacketSize;
3195e8baf87SMarek Vasut 
3205e8baf87SMarek Vasut 	ep = &dev->config.if_desc[if_idx].ep_desc[ep_idx];
321be19d324SRemy Bohmer 
322be19d324SRemy Bohmer 	b = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
323b2fb47f1STom Rini 	ep_wMaxPacketSize = get_unaligned(&ep->wMaxPacketSize);
324be19d324SRemy Bohmer 
325be19d324SRemy Bohmer 	if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
326be19d324SRemy Bohmer 						USB_ENDPOINT_XFER_CONTROL) {
327be19d324SRemy Bohmer 		/* Control => bidirectional */
328b2fb47f1STom Rini 		dev->epmaxpacketout[b] = ep_wMaxPacketSize;
329b2fb47f1STom Rini 		dev->epmaxpacketin[b] = ep_wMaxPacketSize;
330ceb4972aSVivek Gautam 		debug("##Control EP epmaxpacketout/in[%d] = %d\n",
331be19d324SRemy Bohmer 		      b, dev->epmaxpacketin[b]);
332be19d324SRemy Bohmer 	} else {
333be19d324SRemy Bohmer 		if ((ep->bEndpointAddress & 0x80) == 0) {
334be19d324SRemy Bohmer 			/* OUT Endpoint */
335b2fb47f1STom Rini 			if (ep_wMaxPacketSize > dev->epmaxpacketout[b]) {
336b2fb47f1STom Rini 				dev->epmaxpacketout[b] = ep_wMaxPacketSize;
337ceb4972aSVivek Gautam 				debug("##EP epmaxpacketout[%d] = %d\n",
338be19d324SRemy Bohmer 				      b, dev->epmaxpacketout[b]);
339be19d324SRemy Bohmer 			}
340be19d324SRemy Bohmer 		} else {
341be19d324SRemy Bohmer 			/* IN Endpoint */
342b2fb47f1STom Rini 			if (ep_wMaxPacketSize > dev->epmaxpacketin[b]) {
343b2fb47f1STom Rini 				dev->epmaxpacketin[b] = ep_wMaxPacketSize;
344ceb4972aSVivek Gautam 				debug("##EP epmaxpacketin[%d] = %d\n",
345be19d324SRemy Bohmer 				      b, dev->epmaxpacketin[b]);
346be19d324SRemy Bohmer 			}
347be19d324SRemy Bohmer 		} /* if out */
348be19d324SRemy Bohmer 	} /* if control */
349be19d324SRemy Bohmer }
350be19d324SRemy Bohmer 
351affae2bfSwdenk /*
352affae2bfSwdenk  * set the max packed value of all endpoints in the given configuration
353affae2bfSwdenk  */
354c08b1b26SMarek Vasut static int usb_set_maxpacket(struct usb_device *dev)
355affae2bfSwdenk {
356be19d324SRemy Bohmer 	int i, ii;
357affae2bfSwdenk 
3588f8bd565STom Rix 	for (i = 0; i < dev->config.desc.bNumInterfaces; i++)
3598f8bd565STom Rix 		for (ii = 0; ii < dev->config.if_desc[i].desc.bNumEndpoints; ii++)
3605e8baf87SMarek Vasut 			usb_set_maxpacket_ep(dev, i, ii);
361affae2bfSwdenk 
362affae2bfSwdenk 	return 0;
363affae2bfSwdenk }
364affae2bfSwdenk 
365affae2bfSwdenk /*******************************************************************************
366affae2bfSwdenk  * Parse the config, located in buffer, and fills the dev->config structure.
367affae2bfSwdenk  * Note that all little/big endian swapping are done automatically.
368eaf3e613SJulius Werner  * (wTotalLength has already been swapped and sanitized when it was read.)
369affae2bfSwdenk  */
370c08b1b26SMarek Vasut static int usb_parse_config(struct usb_device *dev,
371c08b1b26SMarek Vasut 			unsigned char *buffer, int cfgno)
372affae2bfSwdenk {
373affae2bfSwdenk 	struct usb_descriptor_header *head;
3747455af41SBartlomiej Sieka 	int index, ifno, epno, curr_if_num;
375b2fb47f1STom Rini 	u16 ep_wMaxPacketSize;
376605bd75aSVivek Gautam 	struct usb_interface *if_desc = NULL;
3777455af41SBartlomiej Sieka 
378affae2bfSwdenk 	ifno = -1;
379affae2bfSwdenk 	epno = -1;
3807455af41SBartlomiej Sieka 	curr_if_num = -1;
381affae2bfSwdenk 
382affae2bfSwdenk 	dev->configno = cfgno;
383affae2bfSwdenk 	head = (struct usb_descriptor_header *) &buffer[0];
384affae2bfSwdenk 	if (head->bDescriptorType != USB_DT_CONFIG) {
3856f5794a6SRemy Bohmer 		printf(" ERROR: NOT USB_CONFIG_DESC %x\n",
3866f5794a6SRemy Bohmer 			head->bDescriptorType);
3875a80b344SPaul Kocialkowski 		return -EINVAL;
388affae2bfSwdenk 	}
389eaf3e613SJulius Werner 	if (head->bLength != USB_DT_CONFIG_SIZE) {
390eaf3e613SJulius Werner 		printf("ERROR: Invalid USB CFG length (%d)\n", head->bLength);
3915a80b344SPaul Kocialkowski 		return -EINVAL;
392eaf3e613SJulius Werner 	}
393eaf3e613SJulius Werner 	memcpy(&dev->config, head, USB_DT_CONFIG_SIZE);
394affae2bfSwdenk 	dev->config.no_of_if = 0;
395affae2bfSwdenk 
3968f8bd565STom Rix 	index = dev->config.desc.bLength;
3976f5794a6SRemy Bohmer 	/* Ok the first entry must be a configuration entry,
3986f5794a6SRemy Bohmer 	 * now process the others */
399affae2bfSwdenk 	head = (struct usb_descriptor_header *) &buffer[index];
400eaf3e613SJulius Werner 	while (index + 1 < dev->config.desc.wTotalLength && head->bLength) {
401affae2bfSwdenk 		switch (head->bDescriptorType) {
402affae2bfSwdenk 		case USB_DT_INTERFACE:
403eaf3e613SJulius Werner 			if (head->bLength != USB_DT_INTERFACE_SIZE) {
404eaf3e613SJulius Werner 				printf("ERROR: Invalid USB IF length (%d)\n",
405eaf3e613SJulius Werner 					head->bLength);
406eaf3e613SJulius Werner 				break;
407eaf3e613SJulius Werner 			}
408eaf3e613SJulius Werner 			if (index + USB_DT_INTERFACE_SIZE >
409eaf3e613SJulius Werner 			    dev->config.desc.wTotalLength) {
410eaf3e613SJulius Werner 				puts("USB IF descriptor overflowed buffer!\n");
411eaf3e613SJulius Werner 				break;
412eaf3e613SJulius Werner 			}
4136f5794a6SRemy Bohmer 			if (((struct usb_interface_descriptor *) \
414eaf3e613SJulius Werner 			     head)->bInterfaceNumber != curr_if_num) {
4157455af41SBartlomiej Sieka 				/* this is a new interface, copy new desc */
416affae2bfSwdenk 				ifno = dev->config.no_of_if;
417eaf3e613SJulius Werner 				if (ifno >= USB_MAXINTERFACES) {
418eaf3e613SJulius Werner 					puts("Too many USB interfaces!\n");
419eaf3e613SJulius Werner 					/* try to go on with what we have */
4205a80b344SPaul Kocialkowski 					return -EINVAL;
421eaf3e613SJulius Werner 				}
422605bd75aSVivek Gautam 				if_desc = &dev->config.if_desc[ifno];
4237455af41SBartlomiej Sieka 				dev->config.no_of_if++;
424eaf3e613SJulius Werner 				memcpy(if_desc, head,
425eaf3e613SJulius Werner 					USB_DT_INTERFACE_SIZE);
426605bd75aSVivek Gautam 				if_desc->no_of_ep = 0;
427605bd75aSVivek Gautam 				if_desc->num_altsetting = 1;
4286f5794a6SRemy Bohmer 				curr_if_num =
429605bd75aSVivek Gautam 				     if_desc->desc.bInterfaceNumber;
4307455af41SBartlomiej Sieka 			} else {
4317455af41SBartlomiej Sieka 				/* found alternate setting for the interface */
432605bd75aSVivek Gautam 				if (ifno >= 0) {
433605bd75aSVivek Gautam 					if_desc = &dev->config.if_desc[ifno];
434605bd75aSVivek Gautam 					if_desc->num_altsetting++;
435605bd75aSVivek Gautam 				}
4367455af41SBartlomiej Sieka 			}
437affae2bfSwdenk 			break;
438affae2bfSwdenk 		case USB_DT_ENDPOINT:
4392f0eb2acSBin Meng 			if (head->bLength != USB_DT_ENDPOINT_SIZE &&
4402f0eb2acSBin Meng 			    head->bLength != USB_DT_ENDPOINT_AUDIO_SIZE) {
441eaf3e613SJulius Werner 				printf("ERROR: Invalid USB EP length (%d)\n",
442eaf3e613SJulius Werner 					head->bLength);
443eaf3e613SJulius Werner 				break;
444eaf3e613SJulius Werner 			}
4452f0eb2acSBin Meng 			if (index + head->bLength >
446eaf3e613SJulius Werner 			    dev->config.desc.wTotalLength) {
447eaf3e613SJulius Werner 				puts("USB EP descriptor overflowed buffer!\n");
448eaf3e613SJulius Werner 				break;
449eaf3e613SJulius Werner 			}
450eaf3e613SJulius Werner 			if (ifno < 0) {
451eaf3e613SJulius Werner 				puts("Endpoint descriptor out of order!\n");
452eaf3e613SJulius Werner 				break;
453eaf3e613SJulius Werner 			}
454affae2bfSwdenk 			epno = dev->config.if_desc[ifno].no_of_ep;
455605bd75aSVivek Gautam 			if_desc = &dev->config.if_desc[ifno];
456447b9cdfSPeng Fan 			if (epno >= USB_MAXENDPOINTS) {
457eaf3e613SJulius Werner 				printf("Interface %d has too many endpoints!\n",
458eaf3e613SJulius Werner 					if_desc->desc.bInterfaceNumber);
4595a80b344SPaul Kocialkowski 				return -EINVAL;
460eaf3e613SJulius Werner 			}
4616f5794a6SRemy Bohmer 			/* found an endpoint */
462605bd75aSVivek Gautam 			if_desc->no_of_ep++;
463eaf3e613SJulius Werner 			memcpy(&if_desc->ep_desc[epno], head,
464eaf3e613SJulius Werner 				USB_DT_ENDPOINT_SIZE);
465b2fb47f1STom Rini 			ep_wMaxPacketSize = get_unaligned(&dev->config.\
466b2fb47f1STom Rini 							if_desc[ifno].\
467b2fb47f1STom Rini 							ep_desc[epno].\
468b2fb47f1STom Rini 							wMaxPacketSize);
469b2fb47f1STom Rini 			put_unaligned(le16_to_cpu(ep_wMaxPacketSize),
470b2fb47f1STom Rini 					&dev->config.\
471b2fb47f1STom Rini 					if_desc[ifno].\
472b2fb47f1STom Rini 					ep_desc[epno].\
473b2fb47f1STom Rini 					wMaxPacketSize);
474ceb4972aSVivek Gautam 			debug("if %d, ep %d\n", ifno, epno);
475affae2bfSwdenk 			break;
4766497c667SVivek Gautam 		case USB_DT_SS_ENDPOINT_COMP:
477eaf3e613SJulius Werner 			if (head->bLength != USB_DT_SS_EP_COMP_SIZE) {
478eaf3e613SJulius Werner 				printf("ERROR: Invalid USB EPC length (%d)\n",
479eaf3e613SJulius Werner 					head->bLength);
480eaf3e613SJulius Werner 				break;
481eaf3e613SJulius Werner 			}
482eaf3e613SJulius Werner 			if (index + USB_DT_SS_EP_COMP_SIZE >
483eaf3e613SJulius Werner 			    dev->config.desc.wTotalLength) {
484eaf3e613SJulius Werner 				puts("USB EPC descriptor overflowed buffer!\n");
485eaf3e613SJulius Werner 				break;
486eaf3e613SJulius Werner 			}
487eaf3e613SJulius Werner 			if (ifno < 0 || epno < 0) {
488eaf3e613SJulius Werner 				puts("EPC descriptor out of order!\n");
489eaf3e613SJulius Werner 				break;
490eaf3e613SJulius Werner 			}
4916497c667SVivek Gautam 			if_desc = &dev->config.if_desc[ifno];
492eaf3e613SJulius Werner 			memcpy(&if_desc->ss_ep_comp_desc[epno], head,
493eaf3e613SJulius Werner 				USB_DT_SS_EP_COMP_SIZE);
4946497c667SVivek Gautam 			break;
495affae2bfSwdenk 		default:
496affae2bfSwdenk 			if (head->bLength == 0)
4975a80b344SPaul Kocialkowski 				return -EINVAL;
4986f5794a6SRemy Bohmer 
499ceb4972aSVivek Gautam 			debug("unknown Description Type : %x\n",
5006f5794a6SRemy Bohmer 			      head->bDescriptorType);
5016f5794a6SRemy Bohmer 
502ceb4972aSVivek Gautam #ifdef DEBUG
503affae2bfSwdenk 			{
504fad2e1b0SWolfgang Denk 				unsigned char *ch = (unsigned char *)head;
505ceb4972aSVivek Gautam 				int i;
506ceb4972aSVivek Gautam 
507affae2bfSwdenk 				for (i = 0; i < head->bLength; i++)
508ceb4972aSVivek Gautam 					debug("%02X ", *ch++);
509ceb4972aSVivek Gautam 				debug("\n\n\n");
510affae2bfSwdenk 			}
511ceb4972aSVivek Gautam #endif
512affae2bfSwdenk 			break;
513affae2bfSwdenk 		}
514affae2bfSwdenk 		index += head->bLength;
515affae2bfSwdenk 		head = (struct usb_descriptor_header *)&buffer[index];
516affae2bfSwdenk 	}
5175a80b344SPaul Kocialkowski 	return 0;
518affae2bfSwdenk }
519affae2bfSwdenk 
520affae2bfSwdenk /***********************************************************************
521affae2bfSwdenk  * Clears an endpoint
522affae2bfSwdenk  * endp: endpoint number in bits 0-3;
523affae2bfSwdenk  * direction flag in bit 7 (1 = IN, 0 = OUT)
524affae2bfSwdenk  */
525affae2bfSwdenk int usb_clear_halt(struct usb_device *dev, int pipe)
526affae2bfSwdenk {
527affae2bfSwdenk 	int result;
528affae2bfSwdenk 	int endp = usb_pipeendpoint(pipe)|(usb_pipein(pipe)<<7);
529affae2bfSwdenk 
530affae2bfSwdenk 	result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
5316f5794a6SRemy Bohmer 				 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0,
5326f5794a6SRemy Bohmer 				 endp, NULL, 0, USB_CNTL_TIMEOUT * 3);
533affae2bfSwdenk 
534affae2bfSwdenk 	/* don't clear if failed */
535affae2bfSwdenk 	if (result < 0)
536affae2bfSwdenk 		return result;
5379c998aa8SWolfgang Denk 
5389c998aa8SWolfgang Denk 	/*
5399c998aa8SWolfgang Denk 	 * NOTE: we do not get status and verify reset was successful
5409c998aa8SWolfgang Denk 	 * as some devices are reported to lock up upon this check..
5419c998aa8SWolfgang Denk 	 */
5429c998aa8SWolfgang Denk 
543affae2bfSwdenk 	usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
5449c998aa8SWolfgang Denk 
545affae2bfSwdenk 	/* toggle is reset on clear */
546affae2bfSwdenk 	usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);
547affae2bfSwdenk 	return 0;
548affae2bfSwdenk }
549affae2bfSwdenk 
550affae2bfSwdenk 
551affae2bfSwdenk /**********************************************************************
552affae2bfSwdenk  * get_descriptor type
553affae2bfSwdenk  */
554c08b1b26SMarek Vasut static int usb_get_descriptor(struct usb_device *dev, unsigned char type,
5556f5794a6SRemy Bohmer 			unsigned char index, void *buf, int size)
556affae2bfSwdenk {
5578319aeb1SMasahiro Yamada 	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
558affae2bfSwdenk 			       USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
5598319aeb1SMasahiro Yamada 			       (type << 8) + index, 0, buf, size,
5608319aeb1SMasahiro Yamada 			       USB_CNTL_TIMEOUT);
561affae2bfSwdenk }
562affae2bfSwdenk 
563affae2bfSwdenk /**********************************************************************
564c75f57fbSStefan Brüns  * gets len of configuration cfgno
565affae2bfSwdenk  */
566c75f57fbSStefan Brüns int usb_get_configuration_len(struct usb_device *dev, int cfgno)
567affae2bfSwdenk {
568affae2bfSwdenk 	int result;
569c75f57fbSStefan Brüns 	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, 9);
570c60795f4SIlya Yanok 	struct usb_config_descriptor *config;
571affae2bfSwdenk 
572c60795f4SIlya Yanok 	config = (struct usb_config_descriptor *)&buffer[0];
57348867208SRemy Bohmer 	result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 9);
57448867208SRemy Bohmer 	if (result < 9) {
575affae2bfSwdenk 		if (result < 0)
5766f5794a6SRemy Bohmer 			printf("unable to get descriptor, error %lX\n",
5776f5794a6SRemy Bohmer 				dev->status);
578affae2bfSwdenk 		else
5796f5794a6SRemy Bohmer 			printf("config descriptor too short " \
58048867208SRemy Bohmer 				"(expected %i, got %i)\n", 9, result);
5815a80b344SPaul Kocialkowski 		return -EIO;
582affae2bfSwdenk 	}
583c75f57fbSStefan Brüns 	return le16_to_cpu(config->wTotalLength);
584cd0a9de6Swdenk }
585cd0a9de6Swdenk 
586c75f57fbSStefan Brüns /**********************************************************************
587c75f57fbSStefan Brüns  * gets configuration cfgno and store it in the buffer
588c75f57fbSStefan Brüns  */
589c75f57fbSStefan Brüns int usb_get_configuration_no(struct usb_device *dev, int cfgno,
590c75f57fbSStefan Brüns 			     unsigned char *buffer, int length)
591c75f57fbSStefan Brüns {
592c75f57fbSStefan Brüns 	int result;
593c75f57fbSStefan Brüns 	struct usb_config_descriptor *config;
594c75f57fbSStefan Brüns 
595c75f57fbSStefan Brüns 	config = (struct usb_config_descriptor *)&buffer[0];
596eaf3e613SJulius Werner 	result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, length);
597c75f57fbSStefan Brüns 	debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result,
598c75f57fbSStefan Brüns 	      le16_to_cpu(config->wTotalLength));
599c75f57fbSStefan Brüns 	config->wTotalLength = result; /* validated, with CPU byte order */
600eaf3e613SJulius Werner 
601affae2bfSwdenk 	return result;
602affae2bfSwdenk }
603affae2bfSwdenk 
604affae2bfSwdenk /********************************************************************
605affae2bfSwdenk  * set address of a device to the value in dev->devnum.
606affae2bfSwdenk  * This can only be done by addressing the device via the default address (0)
607affae2bfSwdenk  */
608c08b1b26SMarek Vasut static int usb_set_address(struct usb_device *dev)
609affae2bfSwdenk {
610ceb4972aSVivek Gautam 	debug("set address %d\n", dev->devnum);
6118319aeb1SMasahiro Yamada 
6128319aeb1SMasahiro Yamada 	return usb_control_msg(dev, usb_snddefctrl(dev), USB_REQ_SET_ADDRESS,
6138319aeb1SMasahiro Yamada 			       0, (dev->devnum), 0, NULL, 0, USB_CNTL_TIMEOUT);
614affae2bfSwdenk }
615affae2bfSwdenk 
616affae2bfSwdenk /********************************************************************
617affae2bfSwdenk  * set interface number to interface
618affae2bfSwdenk  */
619affae2bfSwdenk int usb_set_interface(struct usb_device *dev, int interface, int alternate)
620affae2bfSwdenk {
6218f8bd565STom Rix 	struct usb_interface *if_face = NULL;
622affae2bfSwdenk 	int ret, i;
623affae2bfSwdenk 
6248f8bd565STom Rix 	for (i = 0; i < dev->config.desc.bNumInterfaces; i++) {
6258f8bd565STom Rix 		if (dev->config.if_desc[i].desc.bInterfaceNumber == interface) {
626affae2bfSwdenk 			if_face = &dev->config.if_desc[i];
627affae2bfSwdenk 			break;
628affae2bfSwdenk 		}
629affae2bfSwdenk 	}
630affae2bfSwdenk 	if (!if_face) {
631affae2bfSwdenk 		printf("selecting invalid interface %d", interface);
6325a80b344SPaul Kocialkowski 		return -EINVAL;
633affae2bfSwdenk 	}
6347455af41SBartlomiej Sieka 	/*
6357455af41SBartlomiej Sieka 	 * We should return now for devices with only one alternate setting.
6366f5794a6SRemy Bohmer 	 * According to 9.4.10 of the Universal Serial Bus Specification
6376f5794a6SRemy Bohmer 	 * Revision 2.0 such devices can return with a STALL. This results in
6386f5794a6SRemy Bohmer 	 * some USB sticks timeouting during initialization and then being
6396f5794a6SRemy Bohmer 	 * unusable in U-Boot.
6407455af41SBartlomiej Sieka 	 */
6417455af41SBartlomiej Sieka 	if (if_face->num_altsetting == 1)
6427455af41SBartlomiej Sieka 		return 0;
643affae2bfSwdenk 
6446f5794a6SRemy Bohmer 	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
6456f5794a6SRemy Bohmer 				USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE,
6466f5794a6SRemy Bohmer 				alternate, interface, NULL, 0,
6476f5794a6SRemy Bohmer 				USB_CNTL_TIMEOUT * 5);
6486f5794a6SRemy Bohmer 	if (ret < 0)
649affae2bfSwdenk 		return ret;
650affae2bfSwdenk 
651affae2bfSwdenk 	return 0;
652affae2bfSwdenk }
653affae2bfSwdenk 
654affae2bfSwdenk /********************************************************************
655affae2bfSwdenk  * set configuration number to configuration
656affae2bfSwdenk  */
657c08b1b26SMarek Vasut static int usb_set_configuration(struct usb_device *dev, int configuration)
658affae2bfSwdenk {
659affae2bfSwdenk 	int res;
660ceb4972aSVivek Gautam 	debug("set configuration %d\n", configuration);
661affae2bfSwdenk 	/* set setup command */
662affae2bfSwdenk 	res = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
663affae2bfSwdenk 				USB_REQ_SET_CONFIGURATION, 0,
664affae2bfSwdenk 				configuration, 0,
665affae2bfSwdenk 				NULL, 0, USB_CNTL_TIMEOUT);
666affae2bfSwdenk 	if (res == 0) {
667affae2bfSwdenk 		dev->toggle[0] = 0;
668affae2bfSwdenk 		dev->toggle[1] = 0;
669affae2bfSwdenk 		return 0;
6706f5794a6SRemy Bohmer 	} else
6715a80b344SPaul Kocialkowski 		return -EIO;
672affae2bfSwdenk }
673affae2bfSwdenk 
674affae2bfSwdenk /********************************************************************
675affae2bfSwdenk  * set protocol to protocol
676affae2bfSwdenk  */
677affae2bfSwdenk int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol)
678affae2bfSwdenk {
679affae2bfSwdenk 	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
680affae2bfSwdenk 		USB_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
681affae2bfSwdenk 		protocol, ifnum, NULL, 0, USB_CNTL_TIMEOUT);
682affae2bfSwdenk }
683affae2bfSwdenk 
684affae2bfSwdenk /********************************************************************
685affae2bfSwdenk  * set idle
686affae2bfSwdenk  */
687affae2bfSwdenk int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id)
688affae2bfSwdenk {
689affae2bfSwdenk 	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
690affae2bfSwdenk 		USB_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
691affae2bfSwdenk 		(duration << 8) | report_id, ifnum, NULL, 0, USB_CNTL_TIMEOUT);
692affae2bfSwdenk }
693affae2bfSwdenk 
694affae2bfSwdenk /********************************************************************
695affae2bfSwdenk  * get report
696affae2bfSwdenk  */
6976f5794a6SRemy Bohmer int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type,
6986f5794a6SRemy Bohmer 		   unsigned char id, void *buf, int size)
699affae2bfSwdenk {
700affae2bfSwdenk 	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
7016f5794a6SRemy Bohmer 			USB_REQ_GET_REPORT,
7026f5794a6SRemy Bohmer 			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
703affae2bfSwdenk 			(type << 8) + id, ifnum, buf, size, USB_CNTL_TIMEOUT);
704affae2bfSwdenk }
705affae2bfSwdenk 
706affae2bfSwdenk /********************************************************************
707affae2bfSwdenk  * get class descriptor
708affae2bfSwdenk  */
709affae2bfSwdenk int usb_get_class_descriptor(struct usb_device *dev, int ifnum,
710affae2bfSwdenk 		unsigned char type, unsigned char id, void *buf, int size)
711affae2bfSwdenk {
712affae2bfSwdenk 	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
713affae2bfSwdenk 		USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,
714affae2bfSwdenk 		(type << 8) + id, ifnum, buf, size, USB_CNTL_TIMEOUT);
715affae2bfSwdenk }
716affae2bfSwdenk 
717affae2bfSwdenk /********************************************************************
718affae2bfSwdenk  * get string index in buffer
719affae2bfSwdenk  */
720c08b1b26SMarek Vasut static int usb_get_string(struct usb_device *dev, unsigned short langid,
7216f5794a6SRemy Bohmer 		   unsigned char index, void *buf, int size)
722affae2bfSwdenk {
7239c998aa8SWolfgang Denk 	int i;
7249c998aa8SWolfgang Denk 	int result;
7259c998aa8SWolfgang Denk 
7269c998aa8SWolfgang Denk 	for (i = 0; i < 3; ++i) {
7279c998aa8SWolfgang Denk 		/* some devices are flaky */
7289c998aa8SWolfgang Denk 		result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
729affae2bfSwdenk 			USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
7309c998aa8SWolfgang Denk 			(USB_DT_STRING << 8) + index, langid, buf, size,
7319c998aa8SWolfgang Denk 			USB_CNTL_TIMEOUT);
7329c998aa8SWolfgang Denk 
7339c998aa8SWolfgang Denk 		if (result > 0)
7349c998aa8SWolfgang Denk 			break;
735affae2bfSwdenk 	}
736affae2bfSwdenk 
7379c998aa8SWolfgang Denk 	return result;
7389c998aa8SWolfgang Denk }
7399c998aa8SWolfgang Denk 
7409c998aa8SWolfgang Denk 
7419c998aa8SWolfgang Denk static void usb_try_string_workarounds(unsigned char *buf, int *length)
7429c998aa8SWolfgang Denk {
7439c998aa8SWolfgang Denk 	int newlength, oldlength = *length;
7449c998aa8SWolfgang Denk 
7459c998aa8SWolfgang Denk 	for (newlength = 2; newlength + 1 < oldlength; newlength += 2)
7469c998aa8SWolfgang Denk 		if (!isprint(buf[newlength]) || buf[newlength + 1])
7479c998aa8SWolfgang Denk 			break;
7489c998aa8SWolfgang Denk 
7499c998aa8SWolfgang Denk 	if (newlength > 2) {
7509c998aa8SWolfgang Denk 		buf[0] = newlength;
7519c998aa8SWolfgang Denk 		*length = newlength;
7529c998aa8SWolfgang Denk 	}
7539c998aa8SWolfgang Denk }
7549c998aa8SWolfgang Denk 
7559c998aa8SWolfgang Denk 
7569c998aa8SWolfgang Denk static int usb_string_sub(struct usb_device *dev, unsigned int langid,
7579c998aa8SWolfgang Denk 		unsigned int index, unsigned char *buf)
7589c998aa8SWolfgang Denk {
7599c998aa8SWolfgang Denk 	int rc;
7609c998aa8SWolfgang Denk 
7619c998aa8SWolfgang Denk 	/* Try to read the string descriptor by asking for the maximum
7629c998aa8SWolfgang Denk 	 * possible number of bytes */
7639c998aa8SWolfgang Denk 	rc = usb_get_string(dev, langid, index, buf, 255);
7649c998aa8SWolfgang Denk 
7659c998aa8SWolfgang Denk 	/* If that failed try to read the descriptor length, then
7669c998aa8SWolfgang Denk 	 * ask for just that many bytes */
7679c998aa8SWolfgang Denk 	if (rc < 2) {
7689c998aa8SWolfgang Denk 		rc = usb_get_string(dev, langid, index, buf, 2);
7699c998aa8SWolfgang Denk 		if (rc == 2)
7709c998aa8SWolfgang Denk 			rc = usb_get_string(dev, langid, index, buf, buf[0]);
7719c998aa8SWolfgang Denk 	}
7729c998aa8SWolfgang Denk 
7739c998aa8SWolfgang Denk 	if (rc >= 2) {
7749c998aa8SWolfgang Denk 		if (!buf[0] && !buf[1])
7759c998aa8SWolfgang Denk 			usb_try_string_workarounds(buf, &rc);
7769c998aa8SWolfgang Denk 
7779c998aa8SWolfgang Denk 		/* There might be extra junk at the end of the descriptor */
7789c998aa8SWolfgang Denk 		if (buf[0] < rc)
7799c998aa8SWolfgang Denk 			rc = buf[0];
7809c998aa8SWolfgang Denk 
7819c998aa8SWolfgang Denk 		rc = rc - (rc & 1); /* force a multiple of two */
7829c998aa8SWolfgang Denk 	}
7839c998aa8SWolfgang Denk 
7849c998aa8SWolfgang Denk 	if (rc < 2)
7855a80b344SPaul Kocialkowski 		rc = -EINVAL;
7869c998aa8SWolfgang Denk 
7879c998aa8SWolfgang Denk 	return rc;
7889c998aa8SWolfgang Denk }
7899c998aa8SWolfgang Denk 
7909c998aa8SWolfgang Denk 
791affae2bfSwdenk /********************************************************************
792affae2bfSwdenk  * usb_string:
793affae2bfSwdenk  * Get string index and translate it to ascii.
794affae2bfSwdenk  * returns string length (> 0) or error (< 0)
795affae2bfSwdenk  */
796affae2bfSwdenk int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
797affae2bfSwdenk {
798f5766139SPuneet Saxena 	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, mybuf, USB_BUFSIZ);
799affae2bfSwdenk 	unsigned char *tbuf;
800affae2bfSwdenk 	int err;
801affae2bfSwdenk 	unsigned int u, idx;
802affae2bfSwdenk 
803affae2bfSwdenk 	if (size <= 0 || !buf || !index)
8045a80b344SPaul Kocialkowski 		return -EINVAL;
805affae2bfSwdenk 	buf[0] = 0;
806affae2bfSwdenk 	tbuf = &mybuf[0];
807affae2bfSwdenk 
808affae2bfSwdenk 	/* get langid for strings if it's not yet known */
809affae2bfSwdenk 	if (!dev->have_langid) {
8109c998aa8SWolfgang Denk 		err = usb_string_sub(dev, 0, 0, tbuf);
811affae2bfSwdenk 		if (err < 0) {
812ceb4972aSVivek Gautam 			debug("error getting string descriptor 0 " \
813f1c1f540SStefan Roese 			      "(error=%lx)\n", dev->status);
8145a80b344SPaul Kocialkowski 			return -EIO;
815affae2bfSwdenk 		} else if (tbuf[0] < 4) {
816ceb4972aSVivek Gautam 			debug("string descriptor 0 too short\n");
8175a80b344SPaul Kocialkowski 			return -EIO;
818affae2bfSwdenk 		} else {
819affae2bfSwdenk 			dev->have_langid = -1;
820affae2bfSwdenk 			dev->string_langid = tbuf[2] | (tbuf[3] << 8);
821affae2bfSwdenk 				/* always use the first langid listed */
822ceb4972aSVivek Gautam 			debug("USB device number %d default " \
8236f5794a6SRemy Bohmer 			      "language ID 0x%x\n",
824affae2bfSwdenk 			      dev->devnum, dev->string_langid);
825affae2bfSwdenk 		}
826affae2bfSwdenk 	}
8279c998aa8SWolfgang Denk 
8289c998aa8SWolfgang Denk 	err = usb_string_sub(dev, dev->string_langid, index, tbuf);
829affae2bfSwdenk 	if (err < 0)
830affae2bfSwdenk 		return err;
831cd0a9de6Swdenk 
832affae2bfSwdenk 	size--;		/* leave room for trailing NULL char in output buffer */
833affae2bfSwdenk 	for (idx = 0, u = 2; u < err; u += 2) {
834affae2bfSwdenk 		if (idx >= size)
835affae2bfSwdenk 			break;
836affae2bfSwdenk 		if (tbuf[u+1])			/* high byte */
837affae2bfSwdenk 			buf[idx++] = '?';  /* non-ASCII character */
838affae2bfSwdenk 		else
839affae2bfSwdenk 			buf[idx++] = tbuf[u];
840affae2bfSwdenk 	}
841affae2bfSwdenk 	buf[idx] = 0;
842affae2bfSwdenk 	err = idx;
843affae2bfSwdenk 	return err;
844affae2bfSwdenk }
845affae2bfSwdenk 
846affae2bfSwdenk 
847affae2bfSwdenk /********************************************************************
848affae2bfSwdenk  * USB device handling:
849affae2bfSwdenk  * the USB device are static allocated [USB_MAX_DEVICE].
850affae2bfSwdenk  */
851affae2bfSwdenk 
852*fd09c205SSven Schwermer #if !CONFIG_IS_ENABLED(DM_USB)
853affae2bfSwdenk 
854affae2bfSwdenk /* returns a pointer to the device with the index [index].
855affae2bfSwdenk  * if the device is not assigned (dev->devnum==-1) returns NULL
856affae2bfSwdenk  */
857affae2bfSwdenk struct usb_device *usb_get_dev_index(int index)
858affae2bfSwdenk {
859affae2bfSwdenk 	if (usb_dev[index].devnum == -1)
860affae2bfSwdenk 		return NULL;
861affae2bfSwdenk 	else
862affae2bfSwdenk 		return &usb_dev[index];
863affae2bfSwdenk }
864affae2bfSwdenk 
86579b58887SSimon Glass int usb_alloc_new_device(struct udevice *controller, struct usb_device **devp)
866affae2bfSwdenk {
867affae2bfSwdenk 	int i;
868ceb4972aSVivek Gautam 	debug("New Device %d\n", dev_index);
869affae2bfSwdenk 	if (dev_index == USB_MAX_DEVICE) {
8705f535fe1Swdenk 		printf("ERROR, too many USB Devices, max=%d\n", USB_MAX_DEVICE);
87179b58887SSimon Glass 		return -ENOSPC;
872affae2bfSwdenk 	}
8736f5794a6SRemy Bohmer 	/* default Address is 0, real addresses start with 1 */
8746f5794a6SRemy Bohmer 	usb_dev[dev_index].devnum = dev_index + 1;
875affae2bfSwdenk 	usb_dev[dev_index].maxchild = 0;
876affae2bfSwdenk 	for (i = 0; i < USB_MAXCHILDREN; i++)
877affae2bfSwdenk 		usb_dev[dev_index].children[i] = NULL;
878affae2bfSwdenk 	usb_dev[dev_index].parent = NULL;
879c7e3b2b5SLucas Stach 	usb_dev[dev_index].controller = controller;
880affae2bfSwdenk 	dev_index++;
88179b58887SSimon Glass 	*devp = &usb_dev[dev_index - 1];
88279b58887SSimon Glass 
88379b58887SSimon Glass 	return 0;
884affae2bfSwdenk }
885affae2bfSwdenk 
886359439d2SMilind Choudhary /*
887359439d2SMilind Choudhary  * Free the newly created device node.
888359439d2SMilind Choudhary  * Called in error cases where configuring a newly attached
889359439d2SMilind Choudhary  * device fails for some reason.
890359439d2SMilind Choudhary  */
89179b58887SSimon Glass void usb_free_device(struct udevice *controller)
892359439d2SMilind Choudhary {
893359439d2SMilind Choudhary 	dev_index--;
894ceb4972aSVivek Gautam 	debug("Freeing device node: %d\n", dev_index);
895359439d2SMilind Choudhary 	memset(&usb_dev[dev_index], 0, sizeof(struct usb_device));
896359439d2SMilind Choudhary 	usb_dev[dev_index].devnum = -1;
897359439d2SMilind Choudhary }
898affae2bfSwdenk 
899affae2bfSwdenk /*
9005853e133SVivek Gautam  * XHCI issues Enable Slot command and thereafter
9015853e133SVivek Gautam  * allocates device contexts. Provide a weak alias
9025853e133SVivek Gautam  * function for the purpose, so that XHCI overrides it
9035853e133SVivek Gautam  * and EHCI/OHCI just work out of the box.
9045853e133SVivek Gautam  */
9055853e133SVivek Gautam __weak int usb_alloc_device(struct usb_device *udev)
9065853e133SVivek Gautam {
9075853e133SVivek Gautam 	return 0;
9085853e133SVivek Gautam }
909*fd09c205SSven Schwermer #endif /* !CONFIG_IS_ENABLED(DM_USB) */
910862e75c0SSimon Glass 
911682c9f8dSHans de Goede static int usb_hub_port_reset(struct usb_device *dev, struct usb_device *hub)
912862e75c0SSimon Glass {
9133ed9eb93SStefan Roese 	if (!hub)
9148802f563SHans de Goede 		usb_reset_root_port(dev);
915862e75c0SSimon Glass 
916862e75c0SSimon Glass 	return 0;
917862e75c0SSimon Glass }
918862e75c0SSimon Glass 
9190ed27905SSimon Glass static int get_descriptor_len(struct usb_device *dev, int len, int expect_len)
920affae2bfSwdenk {
921128fcac0SSimon Glass 	__maybe_unused struct usb_device_descriptor *desc;
922f5766139SPuneet Saxena 	ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
9230ed27905SSimon Glass 	int err;
9240ed27905SSimon Glass 
9250ed27905SSimon Glass 	desc = (struct usb_device_descriptor *)tmpbuf;
9260ed27905SSimon Glass 
9270ed27905SSimon Glass 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, len);
9280ed27905SSimon Glass 	if (err < expect_len) {
9290ed27905SSimon Glass 		if (err < 0) {
9300ed27905SSimon Glass 			printf("unable to get device descriptor (error=%d)\n",
9310ed27905SSimon Glass 				err);
9320ed27905SSimon Glass 			return err;
9330ed27905SSimon Glass 		} else {
9340ed27905SSimon Glass 			printf("USB device descriptor short read (expected %i, got %i)\n",
9350ed27905SSimon Glass 				expect_len, err);
9360ed27905SSimon Glass 			return -EIO;
9370ed27905SSimon Glass 		}
9380ed27905SSimon Glass 	}
9390ed27905SSimon Glass 	memcpy(&dev->descriptor, tmpbuf, sizeof(dev->descriptor));
9400ed27905SSimon Glass 
9410ed27905SSimon Glass 	return 0;
9420ed27905SSimon Glass }
9430ed27905SSimon Glass 
9440ed27905SSimon Glass static int usb_setup_descriptor(struct usb_device *dev, bool do_read)
9450ed27905SSimon Glass {
9465853e133SVivek Gautam 	/*
94753d8aa0fSSimon Glass 	 * This is a Windows scheme of initialization sequence, with double
94848867208SRemy Bohmer 	 * reset of the device (Linux uses the same sequence)
949c9e8436bSRemy Bohmer 	 * Some equipment is said to work only with such init sequence; this
950c9e8436bSRemy Bohmer 	 * patch is based on the work by Alan Stern:
951de39f8c1SMichael Trimarchi 	 * http://sourceforge.net/mailarchive/forum.php?
952de39f8c1SMichael Trimarchi 	 * thread_id=5729457&forum_id=5398
9539c998aa8SWolfgang Denk 	 */
9549c998aa8SWolfgang Denk 
95553d8aa0fSSimon Glass 	/*
95653d8aa0fSSimon Glass 	 * send 64-byte GET-DEVICE-DESCRIPTOR request.  Since the descriptor is
9579c998aa8SWolfgang Denk 	 * only 18 bytes long, this will terminate with a short packet.  But if
9589c998aa8SWolfgang Denk 	 * the maxpacket size is 8 or 16 the device may be waiting to transmit
9592b338ef4SHans de Goede 	 * some more, or keeps on retransmitting the 8 byte header.
9602b338ef4SHans de Goede 	 */
9619c998aa8SWolfgang Denk 
9622b338ef4SHans de Goede 	if (dev->speed == USB_SPEED_LOW) {
9632b338ef4SHans de Goede 		dev->descriptor.bMaxPacketSize0 = 8;
9642b338ef4SHans de Goede 		dev->maxpacketsize = PACKET_SIZE_8;
9652b338ef4SHans de Goede 	} else {
9662b338ef4SHans de Goede 		dev->descriptor.bMaxPacketSize0 = 64;
96748867208SRemy Bohmer 		dev->maxpacketsize = PACKET_SIZE_64;
9682b338ef4SHans de Goede 	}
9692b338ef4SHans de Goede 	dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0;
9702b338ef4SHans de Goede 	dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
97148867208SRemy Bohmer 
972c008faa7SBin Meng 	if (do_read && dev->speed == USB_SPEED_FULL) {
973128fcac0SSimon Glass 		int err;
974862e75c0SSimon Glass 
97525c06736SStephen Warren 		/*
976c008faa7SBin Meng 		 * Validate we've received only at least 8 bytes, not that
977c008faa7SBin Meng 		 * we've received the entire descriptor. The reasoning is:
978c008faa7SBin Meng 		 * - The code only uses fields in the first 8 bytes, so
979c008faa7SBin Meng 		 *   that's all we need to have fetched at this stage.
980c008faa7SBin Meng 		 * - The smallest maxpacket size is 8 bytes. Before we know
981c008faa7SBin Meng 		 *   the actual maxpacket the device uses, the USB controller
982c008faa7SBin Meng 		 *   may only accept a single packet. Consequently we are only
983c008faa7SBin Meng 		 *   guaranteed to receive 1 packet (at least 8 bytes) even in
984c008faa7SBin Meng 		 *   a non-error case.
98525c06736SStephen Warren 		 *
986c008faa7SBin Meng 		 * At least the DWC2 controller needs to be programmed with
987c008faa7SBin Meng 		 * the number of packets in addition to the number of bytes.
988c008faa7SBin Meng 		 * A request for 64 bytes of data with the maxpacket guessed
989c008faa7SBin Meng 		 * as 64 (above) yields a request for 1 packet.
99025c06736SStephen Warren 		 */
9910ed27905SSimon Glass 		err = get_descriptor_len(dev, 64, 8);
9920ed27905SSimon Glass 		if (err)
993128fcac0SSimon Glass 			return err;
994128fcac0SSimon Glass 	}
9959c998aa8SWolfgang Denk 
996affae2bfSwdenk 	dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0;
997affae2bfSwdenk 	dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
998affae2bfSwdenk 	switch (dev->descriptor.bMaxPacketSize0) {
999de39f8c1SMichael Trimarchi 	case 8:
1000de39f8c1SMichael Trimarchi 		dev->maxpacketsize  = PACKET_SIZE_8;
1001de39f8c1SMichael Trimarchi 		break;
1002de39f8c1SMichael Trimarchi 	case 16:
1003de39f8c1SMichael Trimarchi 		dev->maxpacketsize = PACKET_SIZE_16;
1004de39f8c1SMichael Trimarchi 		break;
1005de39f8c1SMichael Trimarchi 	case 32:
1006de39f8c1SMichael Trimarchi 		dev->maxpacketsize = PACKET_SIZE_32;
1007de39f8c1SMichael Trimarchi 		break;
1008de39f8c1SMichael Trimarchi 	case 64:
1009de39f8c1SMichael Trimarchi 		dev->maxpacketsize = PACKET_SIZE_64;
1010de39f8c1SMichael Trimarchi 		break;
101104ee6ee2SPaul Kocialkowski 	default:
1012c008faa7SBin Meng 		printf("%s: invalid max packet size\n", __func__);
101304ee6ee2SPaul Kocialkowski 		return -EIO;
1014affae2bfSwdenk 	}
1015128fcac0SSimon Glass 
1016128fcac0SSimon Glass 	return 0;
1017128fcac0SSimon Glass }
1018128fcac0SSimon Glass 
101991398f98SSimon Glass static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read,
10209eb72dd1SHans de Goede 			      struct usb_device *parent)
102191398f98SSimon Glass {
102291398f98SSimon Glass 	int err;
102391398f98SSimon Glass 
102491398f98SSimon Glass 	/*
102591398f98SSimon Glass 	 * Allocate usb 3.0 device context.
102691398f98SSimon Glass 	 * USB 3.0 (xHCI) protocol tries to allocate device slot
102791398f98SSimon Glass 	 * and related data structures first. This call does that.
102891398f98SSimon Glass 	 * Refer to sec 4.3.2 in xHCI spec rev1.0
102991398f98SSimon Glass 	 */
103091398f98SSimon Glass 	err = usb_alloc_device(dev);
103191398f98SSimon Glass 	if (err) {
103291398f98SSimon Glass 		printf("Cannot allocate device context to get SLOT_ID\n");
103391398f98SSimon Glass 		return err;
103491398f98SSimon Glass 	}
103591398f98SSimon Glass 	err = usb_setup_descriptor(dev, do_read);
103691398f98SSimon Glass 	if (err)
103791398f98SSimon Glass 		return err;
1038682c9f8dSHans de Goede 	err = usb_hub_port_reset(dev, parent);
103991398f98SSimon Glass 	if (err)
104091398f98SSimon Glass 		return err;
104191398f98SSimon Glass 
104291398f98SSimon Glass 	dev->devnum = addr;
104391398f98SSimon Glass 
104491398f98SSimon Glass 	err = usb_set_address(dev); /* set address */
104591398f98SSimon Glass 
104691398f98SSimon Glass 	if (err < 0) {
104791398f98SSimon Glass 		printf("\n      USB device not accepting new address " \
104891398f98SSimon Glass 			"(error=%lX)\n", dev->status);
104991398f98SSimon Glass 		return err;
105091398f98SSimon Glass 	}
105191398f98SSimon Glass 
105291398f98SSimon Glass 	mdelay(10);	/* Let the SET_ADDRESS settle */
105391398f98SSimon Glass 
1054932bb668SBin Meng 	/*
1055932bb668SBin Meng 	 * If we haven't read device descriptor before, read it here
1056932bb668SBin Meng 	 * after device is assigned an address. This is only applicable
1057932bb668SBin Meng 	 * to xHCI so far.
1058932bb668SBin Meng 	 */
1059932bb668SBin Meng 	if (!do_read) {
1060932bb668SBin Meng 		err = usb_setup_descriptor(dev, true);
1061932bb668SBin Meng 		if (err)
1062932bb668SBin Meng 			return err;
1063932bb668SBin Meng 	}
1064932bb668SBin Meng 
106591398f98SSimon Glass 	return 0;
106691398f98SSimon Glass }
106791398f98SSimon Glass 
106895fbfe42SSimon Glass int usb_select_config(struct usb_device *dev)
1069128fcac0SSimon Glass {
10702f1b4302SMarek Vasut 	unsigned char *tmpbuf = NULL;
10710ed27905SSimon Glass 	int err;
1072128fcac0SSimon Glass 
10730ed27905SSimon Glass 	err = get_descriptor_len(dev, USB_DT_DEVICE_SIZE, USB_DT_DEVICE_SIZE);
10740ed27905SSimon Glass 	if (err)
10750ed27905SSimon Glass 		return err;
1076128fcac0SSimon Glass 
1077affae2bfSwdenk 	/* correct le values */
1078c918261cSChristian Eggers 	le16_to_cpus(&dev->descriptor.bcdUSB);
1079c918261cSChristian Eggers 	le16_to_cpus(&dev->descriptor.idVendor);
1080c918261cSChristian Eggers 	le16_to_cpus(&dev->descriptor.idProduct);
1081c918261cSChristian Eggers 	le16_to_cpus(&dev->descriptor.bcdDevice);
10820ed27905SSimon Glass 
1083ef71290bSMarek Vasut 	/*
1084ef71290bSMarek Vasut 	 * Kingston DT Ultimate 32GB USB 3.0 seems to be extremely sensitive
1085ef71290bSMarek Vasut 	 * about this first Get Descriptor request. If there are any other
1086ef71290bSMarek Vasut 	 * requests in the first microframe, the stick crashes. Wait about
1087ef71290bSMarek Vasut 	 * one microframe duration here (1mS for USB 1.x , 125uS for USB 2.0).
1088ef71290bSMarek Vasut 	 */
1089ef71290bSMarek Vasut 	mdelay(1);
1090ef71290bSMarek Vasut 
1091affae2bfSwdenk 	/* only support for one config for now */
1092c75f57fbSStefan Brüns 	err = usb_get_configuration_len(dev, 0);
1093c75f57fbSStefan Brüns 	if (err >= 0) {
1094c75f57fbSStefan Brüns 		tmpbuf = (unsigned char *)malloc_cache_aligned(err);
1095c75f57fbSStefan Brüns 		if (!tmpbuf)
1096c75f57fbSStefan Brüns 			err = -ENOMEM;
1097c75f57fbSStefan Brüns 		else
1098c75f57fbSStefan Brüns 			err = usb_get_configuration_no(dev, 0, tmpbuf, err);
1099c75f57fbSStefan Brüns 	}
11008b8d779dSVincent Palatin 	if (err < 0) {
11018b8d779dSVincent Palatin 		printf("usb_new_device: Cannot read configuration, " \
11028b8d779dSVincent Palatin 		       "skipping device %04x:%04x\n",
11038b8d779dSVincent Palatin 		       dev->descriptor.idVendor, dev->descriptor.idProduct);
1104c75f57fbSStefan Brüns 		free(tmpbuf);
11050ed27905SSimon Glass 		return err;
11068b8d779dSVincent Palatin 	}
1107f5766139SPuneet Saxena 	usb_parse_config(dev, tmpbuf, 0);
1108c75f57fbSStefan Brüns 	free(tmpbuf);
1109affae2bfSwdenk 	usb_set_maxpacket(dev);
11100ed27905SSimon Glass 	/*
11110ed27905SSimon Glass 	 * we set the default configuration here
11120ed27905SSimon Glass 	 * This seems premature. If the driver wants a different configuration
11130ed27905SSimon Glass 	 * it will need to select itself.
11140ed27905SSimon Glass 	 */
11150ed27905SSimon Glass 	err = usb_set_configuration(dev, dev->config.desc.bConfigurationValue);
11160ed27905SSimon Glass 	if (err < 0) {
11176f5794a6SRemy Bohmer 		printf("failed to set default configuration " \
11186f5794a6SRemy Bohmer 			"len %d, status %lX\n", dev->act_len, dev->status);
11190ed27905SSimon Glass 		return err;
1120affae2bfSwdenk 	}
1121f647bf0bSMarek Vasut 
1122f647bf0bSMarek Vasut 	/*
1123f647bf0bSMarek Vasut 	 * Wait until the Set Configuration request gets processed by the
1124f647bf0bSMarek Vasut 	 * device. This is required by at least SanDisk Cruzer Pop USB 2.0
1125f647bf0bSMarek Vasut 	 * and Kingston DT Ultimate 32GB USB 3.0 on DWC2 OTG controller.
1126f647bf0bSMarek Vasut 	 */
1127f647bf0bSMarek Vasut 	mdelay(10);
1128f647bf0bSMarek Vasut 
1129ceb4972aSVivek Gautam 	debug("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",
11306f5794a6SRemy Bohmer 	      dev->descriptor.iManufacturer, dev->descriptor.iProduct,
11316f5794a6SRemy Bohmer 	      dev->descriptor.iSerialNumber);
1132affae2bfSwdenk 	memset(dev->mf, 0, sizeof(dev->mf));
1133affae2bfSwdenk 	memset(dev->prod, 0, sizeof(dev->prod));
1134affae2bfSwdenk 	memset(dev->serial, 0, sizeof(dev->serial));
1135affae2bfSwdenk 	if (dev->descriptor.iManufacturer)
11366f5794a6SRemy Bohmer 		usb_string(dev, dev->descriptor.iManufacturer,
11376f5794a6SRemy Bohmer 			   dev->mf, sizeof(dev->mf));
1138affae2bfSwdenk 	if (dev->descriptor.iProduct)
11396f5794a6SRemy Bohmer 		usb_string(dev, dev->descriptor.iProduct,
11406f5794a6SRemy Bohmer 			   dev->prod, sizeof(dev->prod));
1141affae2bfSwdenk 	if (dev->descriptor.iSerialNumber)
11426f5794a6SRemy Bohmer 		usb_string(dev, dev->descriptor.iSerialNumber,
11436f5794a6SRemy Bohmer 			   dev->serial, sizeof(dev->serial));
1144ceb4972aSVivek Gautam 	debug("Manufacturer %s\n", dev->mf);
1145ceb4972aSVivek Gautam 	debug("Product      %s\n", dev->prod);
1146ceb4972aSVivek Gautam 	debug("SerialNumber %s\n", dev->serial);
11470ed27905SSimon Glass 
11480ed27905SSimon Glass 	return 0;
11490ed27905SSimon Glass }
11500ed27905SSimon Glass 
115195fbfe42SSimon Glass int usb_setup_device(struct usb_device *dev, bool do_read,
11529eb72dd1SHans de Goede 		     struct usb_device *parent)
11530ed27905SSimon Glass {
11540ed27905SSimon Glass 	int addr;
11550ed27905SSimon Glass 	int ret;
11560ed27905SSimon Glass 
11570ed27905SSimon Glass 	/* We still haven't set the Address yet */
11580ed27905SSimon Glass 	addr = dev->devnum;
11590ed27905SSimon Glass 	dev->devnum = 0;
11600ed27905SSimon Glass 
11619eb72dd1SHans de Goede 	ret = usb_prepare_device(dev, addr, do_read, parent);
11620ed27905SSimon Glass 	if (ret)
11630ed27905SSimon Glass 		return ret;
11640ed27905SSimon Glass 	ret = usb_select_config(dev);
11650ed27905SSimon Glass 
11660ed27905SSimon Glass 	return ret;
11670ed27905SSimon Glass }
11680ed27905SSimon Glass 
1169*fd09c205SSven Schwermer #if !CONFIG_IS_ENABLED(DM_USB)
11700ed27905SSimon Glass /*
11710ed27905SSimon Glass  * By the time we get here, the device has gotten a new device ID
11720ed27905SSimon Glass  * and is in the default state. We need to identify the thing and
11730ed27905SSimon Glass  * get the ball rolling..
11740ed27905SSimon Glass  *
11750ed27905SSimon Glass  * Returns 0 for success, != 0 for error.
11760ed27905SSimon Glass  */
11770ed27905SSimon Glass int usb_new_device(struct usb_device *dev)
11780ed27905SSimon Glass {
11790ed27905SSimon Glass 	bool do_read = true;
11800ed27905SSimon Glass 	int err;
11810ed27905SSimon Glass 
11820ed27905SSimon Glass 	/*
11830ed27905SSimon Glass 	 * XHCI needs to issue a Address device command to setup
11840ed27905SSimon Glass 	 * proper device context structures, before it can interact
11850ed27905SSimon Glass 	 * with the device. So a get_descriptor will fail before any
11860ed27905SSimon Glass 	 * of that is done for XHCI unlike EHCI.
11870ed27905SSimon Glass 	 */
11880a8cc1a3SMasahiro Yamada #ifdef CONFIG_USB_XHCI_HCD
11890ed27905SSimon Glass 	do_read = false;
11900ed27905SSimon Glass #endif
11919eb72dd1SHans de Goede 	err = usb_setup_device(dev, do_read, dev->parent);
11920ed27905SSimon Glass 	if (err)
11930ed27905SSimon Glass 		return err;
11940ed27905SSimon Glass 
11950ed27905SSimon Glass 	/* Now probe if the device is a hub */
11960ed27905SSimon Glass 	err = usb_hub_probe(dev, 0);
11970ed27905SSimon Glass 	if (err < 0)
11980ed27905SSimon Glass 		return err;
11990ed27905SSimon Glass 
1200affae2bfSwdenk 	return 0;
1201affae2bfSwdenk }
120295fbfe42SSimon Glass #endif
1203affae2bfSwdenk 
120416297cfbSMateusz Zalega __weak
1205bba67914STroy Kisky int board_usb_init(int index, enum usb_init_type init)
120616297cfbSMateusz Zalega {
120716297cfbSMateusz Zalega 	return 0;
120816297cfbSMateusz Zalega }
1209db378d78SKishon Vijay Abraham I 
1210db378d78SKishon Vijay Abraham I __weak
1211db378d78SKishon Vijay Abraham I int board_usb_cleanup(int index, enum usb_init_type init)
1212db378d78SKishon Vijay Abraham I {
1213db378d78SKishon Vijay Abraham I 	return 0;
1214db378d78SKishon Vijay Abraham I }
121595fbfe42SSimon Glass 
121695fbfe42SSimon Glass bool usb_device_has_child_on_port(struct usb_device *parent, int port)
121795fbfe42SSimon Glass {
1218*fd09c205SSven Schwermer #if CONFIG_IS_ENABLED(DM_USB)
121995fbfe42SSimon Glass 	return false;
122095fbfe42SSimon Glass #else
122195fbfe42SSimon Glass 	return parent->children[port] != NULL;
122295fbfe42SSimon Glass #endif
122395fbfe42SSimon Glass }
122495fbfe42SSimon Glass 
1225*fd09c205SSven Schwermer #if CONFIG_IS_ENABLED(DM_USB)
1226faa7db24SStefan Brüns void usb_find_usb2_hub_address_port(struct usb_device *udev,
1227faa7db24SStefan Brüns 			       uint8_t *hub_address, uint8_t *hub_port)
1228faa7db24SStefan Brüns {
1229faa7db24SStefan Brüns 	struct udevice *parent;
1230faa7db24SStefan Brüns 	struct usb_device *uparent, *ttdev;
1231faa7db24SStefan Brüns 
1232faa7db24SStefan Brüns 	/*
1233faa7db24SStefan Brüns 	 * When called from usb-uclass.c: usb_scan_device() udev->dev points
1234faa7db24SStefan Brüns 	 * to the parent udevice, not the actual udevice belonging to the
1235faa7db24SStefan Brüns 	 * udev as the device is not instantiated yet. So when searching
1236faa7db24SStefan Brüns 	 * for the first usb-2 parent start with udev->dev not
1237faa7db24SStefan Brüns 	 * udev->dev->parent .
1238faa7db24SStefan Brüns 	 */
1239faa7db24SStefan Brüns 	ttdev = udev;
1240faa7db24SStefan Brüns 	parent = udev->dev;
1241faa7db24SStefan Brüns 	uparent = dev_get_parent_priv(parent);
1242faa7db24SStefan Brüns 
1243faa7db24SStefan Brüns 	while (uparent->speed != USB_SPEED_HIGH) {
1244faa7db24SStefan Brüns 		struct udevice *dev = parent;
1245faa7db24SStefan Brüns 
1246faa7db24SStefan Brüns 		if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) {
1247faa7db24SStefan Brüns 			printf("Error: Cannot find high speed parent of usb-1 device\n");
1248faa7db24SStefan Brüns 			*hub_address = 0;
1249faa7db24SStefan Brüns 			*hub_port = 0;
1250faa7db24SStefan Brüns 			return;
1251faa7db24SStefan Brüns 		}
1252faa7db24SStefan Brüns 
1253faa7db24SStefan Brüns 		ttdev = dev_get_parent_priv(dev);
1254faa7db24SStefan Brüns 		parent = dev->parent;
1255faa7db24SStefan Brüns 		uparent = dev_get_parent_priv(parent);
1256faa7db24SStefan Brüns 	}
1257faa7db24SStefan Brüns 	*hub_address = uparent->devnum;
1258faa7db24SStefan Brüns 	*hub_port = ttdev->portnr;
1259faa7db24SStefan Brüns }
1260faa7db24SStefan Brüns #else
1261faa7db24SStefan Brüns void usb_find_usb2_hub_address_port(struct usb_device *udev,
1262faa7db24SStefan Brüns 			       uint8_t *hub_address, uint8_t *hub_port)
1263faa7db24SStefan Brüns {
1264faa7db24SStefan Brüns 	/* Find out the nearest parent which is high speed */
1265faa7db24SStefan Brüns 	while (udev->parent->parent != NULL)
1266faa7db24SStefan Brüns 		if (udev->parent->speed != USB_SPEED_HIGH) {
1267faa7db24SStefan Brüns 			udev = udev->parent;
1268faa7db24SStefan Brüns 		} else {
1269faa7db24SStefan Brüns 			*hub_address = udev->parent->devnum;
1270faa7db24SStefan Brüns 			*hub_port = udev->portnr;
1271faa7db24SStefan Brüns 			return;
1272faa7db24SStefan Brüns 		}
1273faa7db24SStefan Brüns 
1274faa7db24SStefan Brüns 	printf("Error: Cannot find high speed parent of usb-1 device\n");
1275faa7db24SStefan Brüns 	*hub_address = 0;
1276faa7db24SStefan Brüns 	*hub_port = 0;
1277faa7db24SStefan Brüns }
1278faa7db24SStefan Brüns #endif
1279faa7db24SStefan Brüns 
1280faa7db24SStefan Brüns 
1281affae2bfSwdenk /* EOF */
1282