xref: /openbmc/u-boot/test/dm/usb.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2e00cb223SSimon Glass /*
3e00cb223SSimon Glass  * Copyright (C) 2015 Google, Inc
4e00cb223SSimon Glass  */
5e00cb223SSimon Glass 
6e00cb223SSimon Glass #include <common.h>
724b852a7SSimon Glass #include <console.h>
8e00cb223SSimon Glass #include <dm.h>
9e00cb223SSimon Glass #include <usb.h>
10e00cb223SSimon Glass #include <asm/io.h>
113884c98cSSimon Glass #include <asm/state.h>
12bff1a71eSSimon Glass #include <asm/test.h>
133884c98cSSimon Glass #include <dm/device-internal.h>
14e00cb223SSimon Glass #include <dm/test.h>
15431cbd6dSSimon Glass #include <dm/uclass-internal.h>
16e721b882SJoe Hershberger #include <test/ut.h>
17e00cb223SSimon Glass 
18e00cb223SSimon Glass /* Test that sandbox USB works correctly */
dm_test_usb_base(struct unit_test_state * uts)19e721b882SJoe Hershberger static int dm_test_usb_base(struct unit_test_state *uts)
20e00cb223SSimon Glass {
21e00cb223SSimon Glass 	struct udevice *bus;
22e00cb223SSimon Glass 
23e00cb223SSimon Glass 	ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 0, &bus));
24e00cb223SSimon Glass 	ut_assertok(uclass_get_device(UCLASS_USB, 0, &bus));
25e00cb223SSimon Glass 	ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 2, &bus));
26e00cb223SSimon Glass 
27e00cb223SSimon Glass 	return 0;
28e00cb223SSimon Glass }
29e00cb223SSimon Glass DM_TEST(dm_test_usb_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
30e00cb223SSimon Glass 
31e00cb223SSimon Glass /*
32e00cb223SSimon Glass  * Test that we can use the flash stick. This is more of a functional test. It
33e00cb223SSimon Glass  * covers scanning the bug, setting up a hub and a flash stick and reading
34e00cb223SSimon Glass  * data from the flash stick.
35e00cb223SSimon Glass  */
dm_test_usb_flash(struct unit_test_state * uts)36e721b882SJoe Hershberger static int dm_test_usb_flash(struct unit_test_state *uts)
37e00cb223SSimon Glass {
38e00cb223SSimon Glass 	struct udevice *dev;
394101f687SSimon Glass 	struct blk_desc *dev_desc;
40e00cb223SSimon Glass 	char cmp[1024];
41e00cb223SSimon Glass 
423884c98cSSimon Glass 	state_set_skip_delays(true);
43e00cb223SSimon Glass 	ut_assertok(usb_init());
44e00cb223SSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
45ebac37cfSSimon Glass 	ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc));
46e00cb223SSimon Glass 
47e00cb223SSimon Glass 	/* Read a few blocks and look for the string we expect */
48e00cb223SSimon Glass 	ut_asserteq(512, dev_desc->blksz);
49e00cb223SSimon Glass 	memset(cmp, '\0', sizeof(cmp));
502a981dc2SSimon Glass 	ut_asserteq(2, blk_dread(dev_desc, 0, 2, cmp));
51e00cb223SSimon Glass 	ut_assertok(strcmp(cmp, "this is a test"));
5261ccd886SSimon Glass 	ut_assertok(usb_stop());
53e00cb223SSimon Glass 
54e00cb223SSimon Glass 	return 0;
55e00cb223SSimon Glass }
56e00cb223SSimon Glass DM_TEST(dm_test_usb_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
57431cbd6dSSimon Glass 
58431cbd6dSSimon Glass /* test that we can handle multiple storage devices */
dm_test_usb_multi(struct unit_test_state * uts)59431cbd6dSSimon Glass static int dm_test_usb_multi(struct unit_test_state *uts)
60431cbd6dSSimon Glass {
61431cbd6dSSimon Glass 	struct udevice *dev;
62431cbd6dSSimon Glass 
63431cbd6dSSimon Glass 	state_set_skip_delays(true);
64431cbd6dSSimon Glass 	ut_assertok(usb_init());
65431cbd6dSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
66431cbd6dSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
67431cbd6dSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
6861ccd886SSimon Glass 	ut_assertok(usb_stop());
69431cbd6dSSimon Glass 
70431cbd6dSSimon Glass 	return 0;
71431cbd6dSSimon Glass }
72431cbd6dSSimon Glass DM_TEST(dm_test_usb_multi, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
73431cbd6dSSimon Glass 
count_usb_devices(void)74431cbd6dSSimon Glass static int count_usb_devices(void)
75431cbd6dSSimon Glass {
76431cbd6dSSimon Glass 	struct udevice *hub;
77431cbd6dSSimon Glass 	struct uclass *uc;
78431cbd6dSSimon Glass 	int count = 0;
79431cbd6dSSimon Glass 	int ret;
80431cbd6dSSimon Glass 
81431cbd6dSSimon Glass 	ret = uclass_get(UCLASS_USB_HUB, &uc);
82431cbd6dSSimon Glass 	if (ret)
83431cbd6dSSimon Glass 		return ret;
84431cbd6dSSimon Glass 
85431cbd6dSSimon Glass 	uclass_foreach_dev(hub, uc) {
86431cbd6dSSimon Glass 		struct udevice *dev;
87431cbd6dSSimon Glass 
88431cbd6dSSimon Glass 		count++;
89431cbd6dSSimon Glass 		for (device_find_first_child(hub, &dev);
90431cbd6dSSimon Glass 		     dev;
91431cbd6dSSimon Glass 		     device_find_next_child(&dev)) {
92431cbd6dSSimon Glass 			count++;
93431cbd6dSSimon Glass 		}
94431cbd6dSSimon Glass 	}
95431cbd6dSSimon Glass 
96431cbd6dSSimon Glass 	return count;
97431cbd6dSSimon Glass }
98431cbd6dSSimon Glass 
99f4d4f7d4SBin Meng /* test that no USB devices are found after we stop the stack */
dm_test_usb_stop(struct unit_test_state * uts)100f4d4f7d4SBin Meng static int dm_test_usb_stop(struct unit_test_state *uts)
101431cbd6dSSimon Glass {
102f4d4f7d4SBin Meng 	struct udevice *dev;
103431cbd6dSSimon Glass 
104431cbd6dSSimon Glass 	/* Scan and check that all devices are present */
105431cbd6dSSimon Glass 	state_set_skip_delays(true);
106431cbd6dSSimon Glass 	ut_assertok(usb_init());
107431cbd6dSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
108431cbd6dSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
109431cbd6dSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
110a57a8174SSimon Glass 	ut_asserteq(6, count_usb_devices());
111431cbd6dSSimon Glass 	ut_assertok(usb_stop());
112f4d4f7d4SBin Meng 	ut_asserteq(0, count_usb_devices());
113431cbd6dSSimon Glass 
114431cbd6dSSimon Glass 	return 0;
115431cbd6dSSimon Glass }
116f4d4f7d4SBin Meng DM_TEST(dm_test_usb_stop, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
117bff1a71eSSimon Glass 
dm_test_usb_keyb(struct unit_test_state * uts)118bff1a71eSSimon Glass static int dm_test_usb_keyb(struct unit_test_state *uts)
119bff1a71eSSimon Glass {
120bff1a71eSSimon Glass 	struct udevice *dev;
121bff1a71eSSimon Glass 
122bff1a71eSSimon Glass 	state_set_skip_delays(true);
123bff1a71eSSimon Glass 	ut_assertok(usb_init());
124bff1a71eSSimon Glass 
125bff1a71eSSimon Glass 	/* Initially there should be no characters */
126bff1a71eSSimon Glass 	ut_asserteq(0, tstc());
127bff1a71eSSimon Glass 
128bff1a71eSSimon Glass 	ut_assertok(uclass_get_device_by_name(UCLASS_USB_EMUL, "keyb",
129bff1a71eSSimon Glass 					      &dev));
130bff1a71eSSimon Glass 
131bff1a71eSSimon Glass 	/*
132bff1a71eSSimon Glass 	 * Add a string to the USB keyboard buffer - it should appear in
133bff1a71eSSimon Glass 	 * stdin
134bff1a71eSSimon Glass 	 */
135bff1a71eSSimon Glass 	ut_assertok(sandbox_usb_keyb_add_string(dev, "ab"));
136bff1a71eSSimon Glass 	ut_asserteq(1, tstc());
137bff1a71eSSimon Glass 	ut_asserteq('a', getc());
138bff1a71eSSimon Glass 	ut_asserteq(1, tstc());
139bff1a71eSSimon Glass 	ut_asserteq('b', getc());
140bff1a71eSSimon Glass 	ut_asserteq(0, tstc());
141bff1a71eSSimon Glass 
142bff1a71eSSimon Glass 	ut_assertok(usb_stop());
143bff1a71eSSimon Glass 
144bff1a71eSSimon Glass 	return 0;
145bff1a71eSSimon Glass }
146bff1a71eSSimon Glass DM_TEST(dm_test_usb_keyb, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
147