xref: /rk3399_rockchip-uboot/test/dm/usb.c (revision ebac37cfbfb32ea44704fe032fadd5cf334824b7)
1e00cb223SSimon Glass /*
2e00cb223SSimon Glass  * Copyright (C) 2015 Google, Inc
3e00cb223SSimon Glass  *
4e00cb223SSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
5e00cb223SSimon Glass  */
6e00cb223SSimon Glass 
7e00cb223SSimon Glass #include <common.h>
824b852a7SSimon Glass #include <console.h>
9e00cb223SSimon Glass #include <dm.h>
10e00cb223SSimon Glass #include <usb.h>
11e00cb223SSimon Glass #include <asm/io.h>
123884c98cSSimon Glass #include <asm/state.h>
13bff1a71eSSimon Glass #include <asm/test.h>
143884c98cSSimon Glass #include <dm/device-internal.h>
15e00cb223SSimon Glass #include <dm/test.h>
16431cbd6dSSimon Glass #include <dm/uclass-internal.h>
17e721b882SJoe Hershberger #include <test/ut.h>
18e00cb223SSimon Glass 
19431cbd6dSSimon Glass DECLARE_GLOBAL_DATA_PTR;
20431cbd6dSSimon Glass 
21e00cb223SSimon Glass /* Test that sandbox USB works correctly */
22e721b882SJoe Hershberger static int dm_test_usb_base(struct unit_test_state *uts)
23e00cb223SSimon Glass {
24e00cb223SSimon Glass 	struct udevice *bus;
25e00cb223SSimon Glass 
26e00cb223SSimon Glass 	ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 0, &bus));
27e00cb223SSimon Glass 	ut_assertok(uclass_get_device(UCLASS_USB, 0, &bus));
28e00cb223SSimon Glass 	ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 2, &bus));
29e00cb223SSimon Glass 
30e00cb223SSimon Glass 	return 0;
31e00cb223SSimon Glass }
32e00cb223SSimon Glass DM_TEST(dm_test_usb_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
33e00cb223SSimon Glass 
34e00cb223SSimon Glass /*
35e00cb223SSimon Glass  * Test that we can use the flash stick. This is more of a functional test. It
36e00cb223SSimon Glass  * covers scanning the bug, setting up a hub and a flash stick and reading
37e00cb223SSimon Glass  * data from the flash stick.
38e00cb223SSimon Glass  */
39e721b882SJoe Hershberger static int dm_test_usb_flash(struct unit_test_state *uts)
40e00cb223SSimon Glass {
41e00cb223SSimon Glass 	struct udevice *dev;
424101f687SSimon Glass 	struct blk_desc *dev_desc;
43e00cb223SSimon Glass 	char cmp[1024];
44e00cb223SSimon Glass 
453884c98cSSimon Glass 	state_set_skip_delays(true);
46e00cb223SSimon Glass 	ut_assertok(usb_init());
47e00cb223SSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
48*ebac37cfSSimon Glass 	ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc));
49e00cb223SSimon Glass 
50e00cb223SSimon Glass 	/* Read a few blocks and look for the string we expect */
51e00cb223SSimon Glass 	ut_asserteq(512, dev_desc->blksz);
52e00cb223SSimon Glass 	memset(cmp, '\0', sizeof(cmp));
537c4213f6SStephen Warren 	ut_asserteq(2, dev_desc->block_read(dev_desc, 0, 2, cmp));
54e00cb223SSimon Glass 	ut_assertok(strcmp(cmp, "this is a test"));
55e00cb223SSimon Glass 
56e00cb223SSimon Glass 	return 0;
57e00cb223SSimon Glass }
58e00cb223SSimon Glass DM_TEST(dm_test_usb_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
59431cbd6dSSimon Glass 
60431cbd6dSSimon Glass /* test that we can handle multiple storage devices */
61431cbd6dSSimon Glass static int dm_test_usb_multi(struct unit_test_state *uts)
62431cbd6dSSimon Glass {
63431cbd6dSSimon Glass 	struct udevice *dev;
64431cbd6dSSimon Glass 
65431cbd6dSSimon Glass 	state_set_skip_delays(true);
66431cbd6dSSimon Glass 	ut_assertok(usb_init());
67431cbd6dSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
68431cbd6dSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
69431cbd6dSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
70431cbd6dSSimon Glass 
71431cbd6dSSimon Glass 	return 0;
72431cbd6dSSimon Glass }
73431cbd6dSSimon Glass DM_TEST(dm_test_usb_multi, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
74431cbd6dSSimon Glass 
75431cbd6dSSimon Glass static int count_usb_devices(void)
76431cbd6dSSimon Glass {
77431cbd6dSSimon Glass 	struct udevice *hub;
78431cbd6dSSimon Glass 	struct uclass *uc;
79431cbd6dSSimon Glass 	int count = 0;
80431cbd6dSSimon Glass 	int ret;
81431cbd6dSSimon Glass 
82431cbd6dSSimon Glass 	ret = uclass_get(UCLASS_USB_HUB, &uc);
83431cbd6dSSimon Glass 	if (ret)
84431cbd6dSSimon Glass 		return ret;
85431cbd6dSSimon Glass 
86431cbd6dSSimon Glass 	uclass_foreach_dev(hub, uc) {
87431cbd6dSSimon Glass 		struct udevice *dev;
88431cbd6dSSimon Glass 
89431cbd6dSSimon Glass 		count++;
90431cbd6dSSimon Glass 		for (device_find_first_child(hub, &dev);
91431cbd6dSSimon Glass 		     dev;
92431cbd6dSSimon Glass 		     device_find_next_child(&dev)) {
93431cbd6dSSimon Glass 			count++;
94431cbd6dSSimon Glass 		}
95431cbd6dSSimon Glass 	}
96431cbd6dSSimon Glass 
97431cbd6dSSimon Glass 	return count;
98431cbd6dSSimon Glass }
99431cbd6dSSimon Glass 
100431cbd6dSSimon Glass /* test that we can remove an emulated device and it is then not found */
101431cbd6dSSimon Glass static int dm_test_usb_remove(struct unit_test_state *uts)
102431cbd6dSSimon Glass {
103431cbd6dSSimon Glass 	struct udevice *dev, *emul;
104431cbd6dSSimon Glass 
105431cbd6dSSimon Glass 	/* Scan and check that all devices are present */
106431cbd6dSSimon Glass 	state_set_skip_delays(true);
107431cbd6dSSimon Glass 	ut_assertok(usb_init());
108431cbd6dSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
109431cbd6dSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
110431cbd6dSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
111a57a8174SSimon Glass 	ut_asserteq(6, count_usb_devices());
112431cbd6dSSimon Glass 	ut_assertok(usb_stop());
113a57a8174SSimon Glass 	ut_asserteq(6, count_usb_devices());
114431cbd6dSSimon Glass 
115431cbd6dSSimon Glass 	/* Remove the second emulation device */
116431cbd6dSSimon Glass 	ut_assertok(uclass_find_device_by_name(UCLASS_USB_EMUL, "flash-stick@1",
117431cbd6dSSimon Glass 					       &dev));
118431cbd6dSSimon Glass 	ut_assertok(device_unbind(dev));
119431cbd6dSSimon Glass 
120431cbd6dSSimon Glass 	/* Rescan - only the first and third should be present */
121431cbd6dSSimon Glass 	ut_assertok(usb_init());
122431cbd6dSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
123431cbd6dSSimon Glass 	ut_assertok(usb_emul_find_for_dev(dev, &emul));
124431cbd6dSSimon Glass 	ut_asserteq_str("flash-stick@0", emul->name);
125431cbd6dSSimon Glass 	ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
126431cbd6dSSimon Glass 	ut_assertok(usb_emul_find_for_dev(dev, &emul));
127431cbd6dSSimon Glass 	ut_asserteq_str("flash-stick@2", emul->name);
128431cbd6dSSimon Glass 
129431cbd6dSSimon Glass 	ut_asserteq(-ENODEV, uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
130431cbd6dSSimon Glass 
131a57a8174SSimon Glass 	ut_asserteq(5, count_usb_devices());
132431cbd6dSSimon Glass 	ut_assertok(usb_stop());
133a57a8174SSimon Glass 	ut_asserteq(5, count_usb_devices());
134431cbd6dSSimon Glass 
135431cbd6dSSimon Glass 	return 0;
136431cbd6dSSimon Glass }
137431cbd6dSSimon Glass DM_TEST(dm_test_usb_remove, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
138431cbd6dSSimon Glass 
139431cbd6dSSimon Glass const char usb_tree_base[] =
140431cbd6dSSimon Glass "  1  Hub (12 Mb/s, 100mA)\n"
141431cbd6dSSimon Glass "  |  sandbox hub 2345\n"
142431cbd6dSSimon Glass "  |\n"
143431cbd6dSSimon Glass "  |\b+-2  Mass Storage (12 Mb/s, 100mA)\n"
144431cbd6dSSimon Glass "  |    sandbox flash flash-stick@0\n"
145431cbd6dSSimon Glass "  |  \n"
146431cbd6dSSimon Glass "  |\b+-3  Mass Storage (12 Mb/s, 100mA)\n"
147431cbd6dSSimon Glass "  |    sandbox flash flash-stick@1\n"
148431cbd6dSSimon Glass "  |  \n"
149431cbd6dSSimon Glass "  |\b+-4  Mass Storage (12 Mb/s, 100mA)\n"
150a57a8174SSimon Glass "  |    sandbox flash flash-stick@2\n"
151a57a8174SSimon Glass "  |  \n"
152a57a8174SSimon Glass "  |\b+-5  Human Interface (12 Mb/s, 100mA)\n"
153a57a8174SSimon Glass "       sandbox keyboard keyb@3\n"
154431cbd6dSSimon Glass "     \n";
155431cbd6dSSimon Glass 
156431cbd6dSSimon Glass /* test that the 'usb tree' command output looks correct */
157431cbd6dSSimon Glass static int dm_test_usb_tree(struct unit_test_state *uts)
158431cbd6dSSimon Glass {
159431cbd6dSSimon Glass 	char *data;
160431cbd6dSSimon Glass 	int len;
161431cbd6dSSimon Glass 
162431cbd6dSSimon Glass 	state_set_skip_delays(true);
163431cbd6dSSimon Glass 	ut_assertok(usb_init());
164431cbd6dSSimon Glass 	console_record_reset_enable();
165431cbd6dSSimon Glass 	usb_show_tree();
166431cbd6dSSimon Glass 	len = membuff_getraw(&gd->console_out, -1, true, &data);
167431cbd6dSSimon Glass 	if (len)
168431cbd6dSSimon Glass 		data[len] = '\0';
169431cbd6dSSimon Glass 	ut_asserteq_str(usb_tree_base, data);
170431cbd6dSSimon Glass 	ut_assertok(usb_stop());
171431cbd6dSSimon Glass 
172431cbd6dSSimon Glass 	return 0;
173431cbd6dSSimon Glass }
174431cbd6dSSimon Glass DM_TEST(dm_test_usb_tree, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
175431cbd6dSSimon Glass 
176431cbd6dSSimon Glass const char usb_tree_remove[] =
177431cbd6dSSimon Glass "  1  Hub (12 Mb/s, 100mA)\n"
178431cbd6dSSimon Glass "  |  sandbox hub 2345\n"
179431cbd6dSSimon Glass "  |\n"
180431cbd6dSSimon Glass "  |\b+-2  Mass Storage (12 Mb/s, 100mA)\n"
181431cbd6dSSimon Glass "  |    sandbox flash flash-stick@0\n"
182431cbd6dSSimon Glass "  |  \n"
183431cbd6dSSimon Glass "  |\b+-3  Mass Storage (12 Mb/s, 100mA)\n"
184a57a8174SSimon Glass "  |    sandbox flash flash-stick@2\n"
185a57a8174SSimon Glass "  |  \n"
186a57a8174SSimon Glass "  |\b+-4  Human Interface (12 Mb/s, 100mA)\n"
187a57a8174SSimon Glass "       sandbox keyboard keyb@3\n"
188431cbd6dSSimon Glass "     \n";
189431cbd6dSSimon Glass 
190431cbd6dSSimon Glass /*
191431cbd6dSSimon Glass  * test that the 'usb tree' command output looks correct when we remove a
192431cbd6dSSimon Glass  * device
193431cbd6dSSimon Glass  */
194431cbd6dSSimon Glass static int dm_test_usb_tree_remove(struct unit_test_state *uts)
195431cbd6dSSimon Glass {
196431cbd6dSSimon Glass 	struct udevice *dev;
197431cbd6dSSimon Glass 	char *data;
198431cbd6dSSimon Glass 	int len;
199431cbd6dSSimon Glass 
200431cbd6dSSimon Glass 	/* Remove the second emulation device */
201431cbd6dSSimon Glass 	ut_assertok(uclass_find_device_by_name(UCLASS_USB_EMUL, "flash-stick@1",
202431cbd6dSSimon Glass 					       &dev));
203431cbd6dSSimon Glass 	ut_assertok(device_unbind(dev));
204431cbd6dSSimon Glass 
205431cbd6dSSimon Glass 	state_set_skip_delays(true);
206431cbd6dSSimon Glass 	ut_assertok(usb_init());
207431cbd6dSSimon Glass 	console_record_reset_enable();
208431cbd6dSSimon Glass 	usb_show_tree();
209431cbd6dSSimon Glass 	len = membuff_getraw(&gd->console_out, -1, true, &data);
210431cbd6dSSimon Glass 	if (len)
211431cbd6dSSimon Glass 		data[len] = '\0';
212431cbd6dSSimon Glass 	ut_asserteq_str(usb_tree_remove, data);
213431cbd6dSSimon Glass 	ut_assertok(usb_stop());
214431cbd6dSSimon Glass 
215431cbd6dSSimon Glass 	return 0;
216431cbd6dSSimon Glass }
217431cbd6dSSimon Glass DM_TEST(dm_test_usb_tree_remove, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
218cd716372SSimon Glass 
219cd716372SSimon Glass const char usb_tree_reorder[] =
220cd716372SSimon Glass "  1  Hub (12 Mb/s, 100mA)\n"
221cd716372SSimon Glass "  |  sandbox hub 2345\n"
222cd716372SSimon Glass "  |\n"
223cd716372SSimon Glass "  |\b+-2  Mass Storage (12 Mb/s, 100mA)\n"
224cd716372SSimon Glass "  |    sandbox flash flash-stick@0\n"
225cd716372SSimon Glass "  |  \n"
226cd716372SSimon Glass "  |\b+-3  Mass Storage (12 Mb/s, 100mA)\n"
227cd716372SSimon Glass "  |    sandbox flash flash-stick@2\n"
228cd716372SSimon Glass "  |  \n"
229a57a8174SSimon Glass "  |\b+-4  Human Interface (12 Mb/s, 100mA)\n"
230a57a8174SSimon Glass "  |    sandbox keyboard keyb@3\n"
231a57a8174SSimon Glass "  |  \n"
232a57a8174SSimon Glass "  |\b+-5  Mass Storage (12 Mb/s, 100mA)\n"
233cd716372SSimon Glass "       sandbox flash flash-stick@1\n"
234cd716372SSimon Glass "     \n";
235cd716372SSimon Glass 
236cd716372SSimon Glass /*
237cd716372SSimon Glass  * test that the 'usb tree' command output looks correct when we reorder two
238cd716372SSimon Glass  * devices.
239cd716372SSimon Glass  */
240cd716372SSimon Glass static int dm_test_usb_tree_reorder(struct unit_test_state *uts)
241cd716372SSimon Glass {
242cd716372SSimon Glass 	struct udevice *dev, *parent;
243cd716372SSimon Glass 	char *data;
244cd716372SSimon Glass 	int len;
245cd716372SSimon Glass 
246cd716372SSimon Glass 	/* Remove the second emulation device */
247cd716372SSimon Glass 	ut_assertok(uclass_find_device_by_name(UCLASS_USB_EMUL, "flash-stick@1",
248cd716372SSimon Glass 					       &dev));
249cd716372SSimon Glass 	parent = dev->parent;
250cd716372SSimon Glass 
251cd716372SSimon Glass 	/* Reorder the devices in the parent list and uclass list */
252cd716372SSimon Glass 	list_del(&dev->sibling_node);
253cd716372SSimon Glass 	list_add_tail(&dev->sibling_node, &parent->child_head);
254cd716372SSimon Glass 
255cd716372SSimon Glass 	list_del(&dev->uclass_node);
256cd716372SSimon Glass 	list_add_tail(&dev->uclass_node, &dev->uclass->dev_head);
257cd716372SSimon Glass 
258cd716372SSimon Glass 	state_set_skip_delays(true);
259cd716372SSimon Glass 	ut_assertok(usb_init());
260cd716372SSimon Glass 	console_record_reset_enable();
261cd716372SSimon Glass 	usb_show_tree();
262cd716372SSimon Glass 	len = membuff_getraw(&gd->console_out, -1, true, &data);
263cd716372SSimon Glass 	if (len)
264cd716372SSimon Glass 		data[len] = '\0';
265cd716372SSimon Glass 	ut_asserteq_str(usb_tree_reorder, data);
266cd716372SSimon Glass 	ut_assertok(usb_stop());
267cd716372SSimon Glass 
268cd716372SSimon Glass 	return 0;
269cd716372SSimon Glass }
270cd716372SSimon Glass DM_TEST(dm_test_usb_tree_reorder, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
271bff1a71eSSimon Glass 
272bff1a71eSSimon Glass static int dm_test_usb_keyb(struct unit_test_state *uts)
273bff1a71eSSimon Glass {
274bff1a71eSSimon Glass 	struct udevice *dev;
275bff1a71eSSimon Glass 
276bff1a71eSSimon Glass 	state_set_skip_delays(true);
277bff1a71eSSimon Glass 	ut_assertok(usb_init());
278bff1a71eSSimon Glass 
279bff1a71eSSimon Glass 	/* Initially there should be no characters */
280bff1a71eSSimon Glass 	ut_asserteq(0, tstc());
281bff1a71eSSimon Glass 
282bff1a71eSSimon Glass 	ut_assertok(uclass_get_device_by_name(UCLASS_USB_EMUL, "keyb",
283bff1a71eSSimon Glass 					      &dev));
284bff1a71eSSimon Glass 
285bff1a71eSSimon Glass 	/*
286bff1a71eSSimon Glass 	 * Add a string to the USB keyboard buffer - it should appear in
287bff1a71eSSimon Glass 	 * stdin
288bff1a71eSSimon Glass 	 */
289bff1a71eSSimon Glass 	ut_assertok(sandbox_usb_keyb_add_string(dev, "ab"));
290bff1a71eSSimon Glass 	ut_asserteq(1, tstc());
291bff1a71eSSimon Glass 	ut_asserteq('a', getc());
292bff1a71eSSimon Glass 	ut_asserteq(1, tstc());
293bff1a71eSSimon Glass 	ut_asserteq('b', getc());
294bff1a71eSSimon Glass 	ut_asserteq(0, tstc());
295bff1a71eSSimon Glass 
296bff1a71eSSimon Glass 	ut_assertok(usb_stop());
297bff1a71eSSimon Glass 
298bff1a71eSSimon Glass 	return 0;
299bff1a71eSSimon Glass }
300bff1a71eSSimon Glass DM_TEST(dm_test_usb_keyb, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
301