1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2001
4 * Denis Peter, MPL AG Switzerland
5 *
6 * Adapted for U-Boot driver model
7 * (C) Copyright 2015 Google, Inc
8 *
9 * Most of this source has been derived from the Linux USB
10 * project.
11 */
12
13#include <common.h>
14#include <blk.h>
15#include <bootstage.h>
16#include <command.h>
17#include <console.h>
18#include <dm.h>
19#include <dm/uclass-internal.h>
20#include <memalign.h>
21#include <asm/byteorder.h>
22#include <asm/unaligned.h>
23#include <part.h>
24#include <usb.h>
25
26#ifdef CONFIG_USB_STORAGE
27static int usb_stor_curr_dev = -1; /* current device */
28#endif
29#if defined(CONFIG_USB_HOST_ETHER) && !defined(CONFIG_DM_ETH)
30static int __maybe_unused usb_ether_curr_dev = -1; /* current ethernet device */
31#endif
32
33/* some display routines (info command) */
34static char *usb_get_class_desc(unsigned char dclass)
35{
36	switch (dclass) {
37	case USB_CLASS_PER_INTERFACE:
38		return "See Interface";
39	case USB_CLASS_AUDIO:
40		return "Audio";
41	case USB_CLASS_COMM:
42		return "Communication";
43	case USB_CLASS_HID:
44		return "Human Interface";
45	case USB_CLASS_PRINTER:
46		return "Printer";
47	case USB_CLASS_MASS_STORAGE:
48		return "Mass Storage";
49	case USB_CLASS_HUB:
50		return "Hub";
51	case USB_CLASS_DATA:
52		return "CDC Data";
53	case USB_CLASS_VENDOR_SPEC:
54		return "Vendor specific";
55	default:
56		return "";
57	}
58}
59
60static void usb_display_class_sub(unsigned char dclass, unsigned char subclass,
61				  unsigned char proto)
62{
63	switch (dclass) {
64	case USB_CLASS_PER_INTERFACE:
65		printf("See Interface");
66		break;
67	case USB_CLASS_HID:
68		printf("Human Interface, Subclass: ");
69		switch (subclass) {
70		case USB_SUB_HID_NONE:
71			printf("None");
72			break;
73		case USB_SUB_HID_BOOT:
74			printf("Boot ");
75			switch (proto) {
76			case USB_PROT_HID_NONE:
77				printf("None");
78				break;
79			case USB_PROT_HID_KEYBOARD:
80				printf("Keyboard");
81				break;
82			case USB_PROT_HID_MOUSE:
83				printf("Mouse");
84				break;
85			default:
86				printf("reserved");
87				break;
88			}
89			break;
90		default:
91			printf("reserved");
92			break;
93		}
94		break;
95	case USB_CLASS_MASS_STORAGE:
96		printf("Mass Storage, ");
97		switch (subclass) {
98		case US_SC_RBC:
99			printf("RBC ");
100			break;
101		case US_SC_8020:
102			printf("SFF-8020i (ATAPI)");
103			break;
104		case US_SC_QIC:
105			printf("QIC-157 (Tape)");
106			break;
107		case US_SC_UFI:
108			printf("UFI");
109			break;
110		case US_SC_8070:
111			printf("SFF-8070");
112			break;
113		case US_SC_SCSI:
114			printf("Transp. SCSI");
115			break;
116		default:
117			printf("reserved");
118			break;
119		}
120		printf(", ");
121		switch (proto) {
122		case US_PR_CB:
123			printf("Command/Bulk");
124			break;
125		case US_PR_CBI:
126			printf("Command/Bulk/Int");
127			break;
128		case US_PR_BULK:
129			printf("Bulk only");
130			break;
131		default:
132			printf("reserved");
133			break;
134		}
135		break;
136	default:
137		printf("%s", usb_get_class_desc(dclass));
138		break;
139	}
140}
141
142static void usb_display_string(struct usb_device *dev, int index)
143{
144	ALLOC_CACHE_ALIGN_BUFFER(char, buffer, 256);
145
146	if (index != 0) {
147		if (usb_string(dev, index, &buffer[0], 256) > 0)
148			printf("String: \"%s\"", buffer);
149	}
150}
151
152static void usb_display_desc(struct usb_device *dev)
153{
154	uint packet_size = dev->descriptor.bMaxPacketSize0;
155
156	if (dev->descriptor.bDescriptorType == USB_DT_DEVICE) {
157		printf("%d: %s,  USB Revision %x.%x\n", dev->devnum,
158		usb_get_class_desc(dev->config.if_desc[0].desc.bInterfaceClass),
159				   (dev->descriptor.bcdUSB>>8) & 0xff,
160				   dev->descriptor.bcdUSB & 0xff);
161
162		if (strlen(dev->mf) || strlen(dev->prod) ||
163		    strlen(dev->serial))
164			printf(" - %s %s %s\n", dev->mf, dev->prod,
165				dev->serial);
166		if (dev->descriptor.bDeviceClass) {
167			printf(" - Class: ");
168			usb_display_class_sub(dev->descriptor.bDeviceClass,
169					      dev->descriptor.bDeviceSubClass,
170					      dev->descriptor.bDeviceProtocol);
171			printf("\n");
172		} else {
173			printf(" - Class: (from Interface) %s\n",
174			       usb_get_class_desc(
175				dev->config.if_desc[0].desc.bInterfaceClass));
176		}
177		if (dev->descriptor.bcdUSB >= cpu_to_le16(0x0300))
178			packet_size = 1 << packet_size;
179		printf(" - PacketSize: %d  Configurations: %d\n",
180			packet_size, dev->descriptor.bNumConfigurations);
181		printf(" - Vendor: 0x%04x  Product 0x%04x Version %d.%d\n",
182			dev->descriptor.idVendor, dev->descriptor.idProduct,
183			(dev->descriptor.bcdDevice>>8) & 0xff,
184			dev->descriptor.bcdDevice & 0xff);
185	}
186
187}
188
189static void usb_display_conf_desc(struct usb_config_descriptor *config,
190				  struct usb_device *dev)
191{
192	printf("   Configuration: %d\n", config->bConfigurationValue);
193	printf("   - Interfaces: %d %s%s%dmA\n", config->bNumInterfaces,
194	       (config->bmAttributes & 0x40) ? "Self Powered " : "Bus Powered ",
195	       (config->bmAttributes & 0x20) ? "Remote Wakeup " : "",
196		config->bMaxPower*2);
197	if (config->iConfiguration) {
198		printf("   - ");
199		usb_display_string(dev, config->iConfiguration);
200		printf("\n");
201	}
202}
203
204static void usb_display_if_desc(struct usb_interface_descriptor *ifdesc,
205				struct usb_device *dev)
206{
207	printf("     Interface: %d\n", ifdesc->bInterfaceNumber);
208	printf("     - Alternate Setting %d, Endpoints: %d\n",
209		ifdesc->bAlternateSetting, ifdesc->bNumEndpoints);
210	printf("     - Class ");
211	usb_display_class_sub(ifdesc->bInterfaceClass,
212		ifdesc->bInterfaceSubClass, ifdesc->bInterfaceProtocol);
213	printf("\n");
214	if (ifdesc->iInterface) {
215		printf("     - ");
216		usb_display_string(dev, ifdesc->iInterface);
217		printf("\n");
218	}
219}
220
221static void usb_display_ep_desc(struct usb_endpoint_descriptor *epdesc)
222{
223	printf("     - Endpoint %d %s ", epdesc->bEndpointAddress & 0xf,
224		(epdesc->bEndpointAddress & 0x80) ? "In" : "Out");
225	switch ((epdesc->bmAttributes & 0x03)) {
226	case 0:
227		printf("Control");
228		break;
229	case 1:
230		printf("Isochronous");
231		break;
232	case 2:
233		printf("Bulk");
234		break;
235	case 3:
236		printf("Interrupt");
237		break;
238	}
239	printf(" MaxPacket %d", get_unaligned(&epdesc->wMaxPacketSize));
240	if ((epdesc->bmAttributes & 0x03) == 0x3)
241		printf(" Interval %dms", epdesc->bInterval);
242	printf("\n");
243}
244
245/* main routine to diasplay the configs, interfaces and endpoints */
246static void usb_display_config(struct usb_device *dev)
247{
248	struct usb_config *config;
249	struct usb_interface *ifdesc;
250	struct usb_endpoint_descriptor *epdesc;
251	int i, ii;
252
253	config = &dev->config;
254	usb_display_conf_desc(&config->desc, dev);
255	for (i = 0; i < config->no_of_if; i++) {
256		ifdesc = &config->if_desc[i];
257		usb_display_if_desc(&ifdesc->desc, dev);
258		for (ii = 0; ii < ifdesc->no_of_ep; ii++) {
259			epdesc = &ifdesc->ep_desc[ii];
260			usb_display_ep_desc(epdesc);
261		}
262	}
263	printf("\n");
264}
265
266/*
267 * With driver model this isn't right since we can have multiple controllers
268 * and the device numbering starts at 1 on each bus.
269 * TODO(sjg@chromium.org): Add a way to specify the controller/bus.
270 */
271static struct usb_device *usb_find_device(int devnum)
272{
273#ifdef CONFIG_DM_USB
274	struct usb_device *udev;
275	struct udevice *hub;
276	struct uclass *uc;
277	int ret;
278
279	/* Device addresses start at 1 */
280	devnum++;
281	ret = uclass_get(UCLASS_USB_HUB, &uc);
282	if (ret)
283		return NULL;
284
285	uclass_foreach_dev(hub, uc) {
286		struct udevice *dev;
287
288		if (!device_active(hub))
289			continue;
290		udev = dev_get_parent_priv(hub);
291		if (udev->devnum == devnum)
292			return udev;
293
294		for (device_find_first_child(hub, &dev);
295		     dev;
296		     device_find_next_child(&dev)) {
297			if (!device_active(hub))
298				continue;
299
300			udev = dev_get_parent_priv(dev);
301			if (udev->devnum == devnum)
302				return udev;
303		}
304	}
305#else
306	struct usb_device *udev;
307	int d;
308
309	for (d = 0; d < USB_MAX_DEVICE; d++) {
310		udev = usb_get_dev_index(d);
311		if (udev == NULL)
312			return NULL;
313		if (udev->devnum == devnum)
314			return udev;
315	}
316#endif
317
318	return NULL;
319}
320
321static inline const char *portspeed(int speed)
322{
323	switch (speed) {
324	case USB_SPEED_SUPER:
325		return "5 Gb/s";
326	case USB_SPEED_HIGH:
327		return "480 Mb/s";
328	case USB_SPEED_LOW:
329		return "1.5 Mb/s";
330	default:
331		return "12 Mb/s";
332	}
333}
334
335/* shows the device tree recursively */
336static void usb_show_tree_graph(struct usb_device *dev, char *pre)
337{
338	int index;
339	int has_child, last_child;
340
341	index = strlen(pre);
342	printf(" %s", pre);
343#ifdef CONFIG_DM_USB
344	has_child = device_has_active_children(dev->dev);
345	if (device_get_uclass_id(dev->dev) == UCLASS_MASS_STORAGE) {
346		struct udevice *child;
347
348		for (device_find_first_child(dev->dev, &child);
349		     child;
350		     device_find_next_child(&child)) {
351			if (device_get_uclass_id(child) == UCLASS_BLK)
352				has_child = 0;
353		}
354	}
355#else
356	/* check if the device has connected children */
357	int i;
358
359	has_child = 0;
360	for (i = 0; i < dev->maxchild; i++) {
361		if (dev->children[i] != NULL)
362			has_child = 1;
363	}
364#endif
365	/* check if we are the last one */
366#ifdef CONFIG_DM_USB
367	/* Not the root of the usb tree? */
368	if (device_get_uclass_id(dev->dev->parent) != UCLASS_USB) {
369		last_child = device_is_last_sibling(dev->dev);
370#else
371	if (dev->parent != NULL) { /* not root? */
372		last_child = 1;
373		for (i = 0; i < dev->parent->maxchild; i++) {
374			/* search for children */
375			if (dev->parent->children[i] == dev) {
376				/* found our pointer, see if we have a
377				 * little sister
378				 */
379				while (i++ < dev->parent->maxchild) {
380					if (dev->parent->children[i] != NULL) {
381						/* found a sister */
382						last_child = 0;
383						break;
384					} /* if */
385				} /* while */
386			} /* device found */
387		} /* for all children of the parent */
388#endif
389		printf("\b+-");
390		/* correct last child */
391		if (last_child && index)
392			pre[index-1] = ' ';
393	} /* if not root hub */
394	else
395		printf(" ");
396	printf("%d ", dev->devnum);
397	pre[index++] = ' ';
398	pre[index++] = has_child ? '|' : ' ';
399	pre[index] = 0;
400	printf(" %s (%s, %dmA)\n", usb_get_class_desc(
401					dev->config.if_desc[0].desc.bInterfaceClass),
402					portspeed(dev->speed),
403					dev->config.desc.bMaxPower * 2);
404	if (strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial))
405		printf(" %s  %s %s %s\n", pre, dev->mf, dev->prod, dev->serial);
406	printf(" %s\n", pre);
407#ifdef CONFIG_DM_USB
408	struct udevice *child;
409
410	for (device_find_first_child(dev->dev, &child);
411	     child;
412	     device_find_next_child(&child)) {
413		struct usb_device *udev;
414
415		if (!device_active(child))
416			continue;
417
418		udev = dev_get_parent_priv(child);
419
420		/*
421		 * Ignore emulators and block child devices, we only want
422		 * real devices
423		 */
424		if (udev &&
425		    (device_get_uclass_id(child) != UCLASS_BOOTDEV) &&
426		    (device_get_uclass_id(child) != UCLASS_USB_EMUL) &&
427		    (device_get_uclass_id(child) != UCLASS_BLK)) {
428			usb_show_tree_graph(udev, pre);
429			pre[index] = 0;
430		}
431	}
432#else
433	if (dev->maxchild > 0) {
434		for (i = 0; i < dev->maxchild; i++) {
435			if (dev->children[i] != NULL) {
436				usb_show_tree_graph(dev->children[i], pre);
437				pre[index] = 0;
438			}
439		}
440	}
441#endif
442}
443
444/* main routine for the tree command */
445static void usb_show_subtree(struct usb_device *dev)
446{
447	char preamble[32];
448
449	memset(preamble, '\0', sizeof(preamble));
450	usb_show_tree_graph(dev, &preamble[0]);
451}
452
453#ifdef CONFIG_DM_USB
454typedef void (*usb_dev_func_t)(struct usb_device *udev);
455
456static void usb_for_each_root_dev(usb_dev_func_t func)
457{
458	struct udevice *bus;
459
460	for (uclass_find_first_device(UCLASS_USB, &bus);
461		bus;
462		uclass_find_next_device(&bus)) {
463		struct usb_device *udev;
464		struct udevice *dev;
465
466		if (!device_active(bus))
467			continue;
468
469		device_find_first_child(bus, &dev);
470		if (dev && device_active(dev)) {
471			udev = dev_get_parent_priv(dev);
472			func(udev);
473		}
474	}
475}
476#endif
477
478void usb_show_tree(void)
479{
480#ifdef CONFIG_DM_USB
481	usb_for_each_root_dev(usb_show_subtree);
482#else
483	struct usb_device *udev;
484	int i;
485
486	for (i = 0; i < USB_MAX_DEVICE; i++) {
487		udev = usb_get_dev_index(i);
488		if (udev == NULL)
489			break;
490		if (udev->parent == NULL)
491			usb_show_subtree(udev);
492	}
493#endif
494}
495
496static int usb_test(struct usb_device *dev, int port, char* arg)
497{
498	int mode;
499
500	if (port > dev->maxchild) {
501		printf("Device is no hub or does not have %d ports.\n", port);
502		return 1;
503	}
504
505	switch (arg[0]) {
506	case 'J':
507	case 'j':
508		printf("Setting Test_J mode");
509		mode = USB_TEST_MODE_J;
510		break;
511	case 'K':
512	case 'k':
513		printf("Setting Test_K mode");
514		mode = USB_TEST_MODE_K;
515		break;
516	case 'S':
517	case 's':
518		printf("Setting Test_SE0_NAK mode");
519		mode = USB_TEST_MODE_SE0_NAK;
520		break;
521	case 'P':
522	case 'p':
523		printf("Setting Test_Packet mode");
524		mode = USB_TEST_MODE_PACKET;
525		break;
526	case 'F':
527	case 'f':
528		printf("Setting Test_Force_Enable mode");
529		mode = USB_TEST_MODE_FORCE_ENABLE;
530		break;
531	default:
532		printf("Unrecognized test mode: %s\nAvailable modes: "
533		       "J, K, S[E0_NAK], P[acket], F[orce_Enable]\n", arg);
534		return 1;
535	}
536
537	if (port)
538		printf(" on downstream facing port %d...\n", port);
539	else
540		printf(" on upstream facing port...\n");
541
542	if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_FEATURE,
543			    port ? USB_RT_PORT : USB_RECIP_DEVICE,
544			    port ? USB_PORT_FEAT_TEST : USB_FEAT_TEST,
545			    (mode << 8) | port,
546			    NULL, 0, USB_CNTL_TIMEOUT) == -1) {
547		printf("Error during SET_FEATURE.\n");
548		return 1;
549	} else {
550		printf("Test mode successfully set. Use 'usb start' "
551		       "to return to normal operation.\n");
552		return 0;
553	}
554}
555
556
557/******************************************************************************
558 * usb boot command intepreter. Derived from diskboot
559 */
560#ifdef CONFIG_USB_STORAGE
561static int do_usbboot(struct cmd_tbl *cmdtp, int flag, int argc,
562		      char *const argv[])
563{
564	return common_diskboot(cmdtp, "usb", argc, argv);
565}
566#endif /* CONFIG_USB_STORAGE */
567
568static int do_usb_stop_keyboard(int force)
569{
570#if !defined CONFIG_DM_USB && defined CONFIG_USB_KEYBOARD
571	if (usb_kbd_deregister(force) != 0) {
572		printf("USB not stopped: usbkbd still using USB\n");
573		return 1;
574	}
575#endif
576	return 0;
577}
578
579static void do_usb_start(void)
580{
581	bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start");
582
583	if (usb_init() < 0)
584		return;
585
586	/* Driver model will probe the devices as they are found */
587# ifdef CONFIG_USB_STORAGE
588	/* try to recognize storage devices immediately */
589	usb_stor_curr_dev = usb_stor_scan(1);
590# endif
591#ifndef CONFIG_DM_USB
592# ifdef CONFIG_USB_KEYBOARD
593	drv_usb_kbd_init();
594# endif
595#endif /* !CONFIG_DM_USB */
596}
597
598#ifdef CONFIG_DM_USB
599static void usb_show_info(struct usb_device *udev)
600{
601	struct udevice *child;
602
603	usb_display_desc(udev);
604	usb_display_config(udev);
605	for (device_find_first_child(udev->dev, &child);
606	     child;
607	     device_find_next_child(&child)) {
608		if (device_active(child) &&
609		    (device_get_uclass_id(child) != UCLASS_BOOTDEV) &&
610		    (device_get_uclass_id(child) != UCLASS_USB_EMUL) &&
611		    (device_get_uclass_id(child) != UCLASS_BLK)) {
612			udev = dev_get_parent_priv(child);
613			if (udev)
614				usb_show_info(udev);
615		}
616	}
617}
618#endif
619
620/******************************************************************************
621 * usb command intepreter
622 */
623static int do_usb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
624{
625	struct usb_device *udev = NULL;
626	int i;
627
628	if (argc < 2)
629		return CMD_RET_USAGE;
630
631	if (strncmp(argv[1], "start", 5) == 0) {
632		if (usb_started)
633			return 0; /* Already started */
634		printf("starting USB...\n");
635		do_usb_start();
636		return 0;
637	}
638
639	if (strncmp(argv[1], "reset", 5) == 0) {
640		printf("resetting USB...\n");
641		if (do_usb_stop_keyboard(1) != 0)
642			return 1;
643		usb_stop();
644		do_usb_start();
645		return 0;
646	}
647	if (strncmp(argv[1], "stop", 4) == 0) {
648		if (argc != 2)
649			console_assign(stdin, "serial");
650		if (do_usb_stop_keyboard(0) != 0)
651			return 1;
652		printf("stopping USB..\n");
653		usb_stop();
654		return 0;
655	}
656	if (!usb_started) {
657		printf("USB is stopped. Please issue 'usb start' first.\n");
658		return 1;
659	}
660	if (strncmp(argv[1], "tree", 4) == 0) {
661		puts("USB device tree:\n");
662		usb_show_tree();
663		return 0;
664	}
665	if (strncmp(argv[1], "inf", 3) == 0) {
666		if (argc == 2) {
667#ifdef CONFIG_DM_USB
668			usb_for_each_root_dev(usb_show_info);
669#else
670			int d;
671			for (d = 0; d < USB_MAX_DEVICE; d++) {
672				udev = usb_get_dev_index(d);
673				if (udev == NULL)
674					break;
675				usb_display_desc(udev);
676				usb_display_config(udev);
677			}
678#endif
679			return 0;
680		} else {
681			/*
682			 * With driver model this isn't right since we can
683			 * have multiple controllers and the device numbering
684			 * starts at 1 on each bus.
685			 */
686			i = dectoul(argv[2], NULL);
687			printf("config for device %d\n", i);
688			udev = usb_find_device(i);
689			if (udev == NULL) {
690				printf("*** No device available ***\n");
691				return 0;
692			} else {
693				usb_display_desc(udev);
694				usb_display_config(udev);
695			}
696		}
697		return 0;
698	}
699	if (strncmp(argv[1], "test", 4) == 0) {
700		if (argc < 5)
701			return CMD_RET_USAGE;
702		i = dectoul(argv[2], NULL);
703		udev = usb_find_device(i);
704		if (udev == NULL) {
705			printf("Device %d does not exist.\n", i);
706			return 1;
707		}
708		i = dectoul(argv[3], NULL);
709		return usb_test(udev, i, argv[4]);
710	}
711#ifdef CONFIG_USB_STORAGE
712	if (strncmp(argv[1], "stor", 4) == 0)
713		return usb_stor_info();
714
715	return blk_common_cmd(argc, argv, UCLASS_USB, &usb_stor_curr_dev);
716#else
717	return CMD_RET_USAGE;
718#endif /* CONFIG_USB_STORAGE */
719}
720
721U_BOOT_CMD(
722	usb,	5,	1,	do_usb,
723	"USB sub-system",
724	"start - start (scan) USB controller\n"
725	"usb reset - reset (rescan) USB controller\n"
726	"usb stop [f] - stop USB [f]=force stop\n"
727	"usb tree - show USB device tree\n"
728	"usb info [dev] - show available USB devices\n"
729	"usb test [dev] [port] [mode] - set USB 2.0 test mode\n"
730	"    (specify port 0 to indicate the device's upstream port)\n"
731	"    Available modes: J, K, S[E0_NAK], P[acket], F[orce_Enable]\n"
732#ifdef CONFIG_USB_STORAGE
733	"usb storage - show details of USB storage devices\n"
734	"usb dev [dev] - show or set current USB storage device\n"
735	"usb part [dev] - print partition table of one or all USB storage"
736	"    devices\n"
737	"usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n"
738	"    to memory address `addr'\n"
739	"usb write addr blk# cnt - write `cnt' blocks starting at block `blk#'\n"
740	"    from memory address `addr'"
741#endif /* CONFIG_USB_STORAGE */
742);
743
744
745#ifdef CONFIG_USB_STORAGE
746U_BOOT_CMD(
747	usbboot,	3,	1,	do_usbboot,
748	"boot from USB device",
749	"loadAddr dev:part"
750);
751#endif /* CONFIG_USB_STORAGE */
752