dm: test: usb: Add tests for the 'usb tree' command
[oweals/u-boot.git] / test / dm / usb.c
1 /*
2  * Copyright (C) 2015 Google, Inc
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <console.h>
9 #include <dm.h>
10 #include <usb.h>
11 #include <asm/io.h>
12 #include <asm/state.h>
13 #include <dm/device-internal.h>
14 #include <dm/test.h>
15 #include <dm/uclass-internal.h>
16 #include <test/ut.h>
17
18 DECLARE_GLOBAL_DATA_PTR;
19
20 /* Test that sandbox USB works correctly */
21 static int dm_test_usb_base(struct unit_test_state *uts)
22 {
23         struct udevice *bus;
24
25         ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 0, &bus));
26         ut_assertok(uclass_get_device(UCLASS_USB, 0, &bus));
27         ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 2, &bus));
28
29         return 0;
30 }
31 DM_TEST(dm_test_usb_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
32
33 /*
34  * Test that we can use the flash stick. This is more of a functional test. It
35  * covers scanning the bug, setting up a hub and a flash stick and reading
36  * data from the flash stick.
37  */
38 static int dm_test_usb_flash(struct unit_test_state *uts)
39 {
40         struct udevice *dev;
41         block_dev_desc_t *dev_desc;
42         char cmp[1024];
43
44         state_set_skip_delays(true);
45         ut_assertok(usb_init());
46         ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
47         ut_assertok(get_device("usb", "0", &dev_desc));
48
49         /* Read a few blocks and look for the string we expect */
50         ut_asserteq(512, dev_desc->blksz);
51         memset(cmp, '\0', sizeof(cmp));
52         ut_asserteq(2, dev_desc->block_read(dev_desc->dev, 0, 2, cmp));
53         ut_assertok(strcmp(cmp, "this is a test"));
54
55         return 0;
56 }
57 DM_TEST(dm_test_usb_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
58
59 /* test that we can handle multiple storage devices */
60 static int dm_test_usb_multi(struct unit_test_state *uts)
61 {
62         struct udevice *dev;
63
64         state_set_skip_delays(true);
65         ut_assertok(usb_init());
66         ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
67         ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
68         ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
69
70         return 0;
71 }
72 DM_TEST(dm_test_usb_multi, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
73
74 static int count_usb_devices(void)
75 {
76         struct udevice *hub;
77         struct uclass *uc;
78         int count = 0;
79         int ret;
80
81         ret = uclass_get(UCLASS_USB_HUB, &uc);
82         if (ret)
83                 return ret;
84
85         uclass_foreach_dev(hub, uc) {
86                 struct udevice *dev;
87
88                 count++;
89                 for (device_find_first_child(hub, &dev);
90                      dev;
91                      device_find_next_child(&dev)) {
92                         count++;
93                 }
94         }
95
96         return count;
97 }
98
99 /* test that we can remove an emulated device and it is then not found */
100 static int dm_test_usb_remove(struct unit_test_state *uts)
101 {
102         struct udevice *dev, *emul;
103
104         /* Scan and check that all devices are present */
105         state_set_skip_delays(true);
106         ut_assertok(usb_init());
107         ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
108         ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
109         ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
110         ut_asserteq(5, count_usb_devices());
111         ut_assertok(usb_stop());
112         ut_asserteq(5, count_usb_devices());
113
114         /* Remove the second emulation device */
115         ut_assertok(uclass_find_device_by_name(UCLASS_USB_EMUL, "flash-stick@1",
116                                                &dev));
117         ut_assertok(device_unbind(dev));
118
119         /* Rescan - only the first and third should be present */
120         ut_assertok(usb_init());
121         ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
122         ut_assertok(usb_emul_find_for_dev(dev, &emul));
123         ut_asserteq_str("flash-stick@0", emul->name);
124         ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
125         ut_assertok(usb_emul_find_for_dev(dev, &emul));
126         ut_asserteq_str("flash-stick@2", emul->name);
127
128         ut_asserteq(-ENODEV, uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
129
130         ut_asserteq(4, count_usb_devices());
131         ut_assertok(usb_stop());
132         ut_asserteq(4, count_usb_devices());
133
134         return 0;
135 }
136 DM_TEST(dm_test_usb_remove, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
137
138 const char usb_tree_base[] =
139 "  1  Hub (12 Mb/s, 100mA)\n"
140 "  |  sandbox hub 2345\n"
141 "  |\n"
142 "  |\b+-2  Mass Storage (12 Mb/s, 100mA)\n"
143 "  |    sandbox flash flash-stick@0\n"
144 "  |  \n"
145 "  |\b+-3  Mass Storage (12 Mb/s, 100mA)\n"
146 "  |    sandbox flash flash-stick@1\n"
147 "  |  \n"
148 "  |\b+-4  Mass Storage (12 Mb/s, 100mA)\n"
149 "       sandbox flash flash-stick@2\n"
150 "     \n";
151
152 /* test that the 'usb tree' command output looks correct */
153 static int dm_test_usb_tree(struct unit_test_state *uts)
154 {
155         char *data;
156         int len;
157
158         state_set_skip_delays(true);
159         ut_assertok(usb_init());
160         console_record_reset_enable();
161         usb_show_tree();
162         len = membuff_getraw(&gd->console_out, -1, true, &data);
163         if (len)
164                 data[len] = '\0';
165         ut_asserteq_str(usb_tree_base, data);
166         ut_assertok(usb_stop());
167
168         return 0;
169 }
170 DM_TEST(dm_test_usb_tree, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
171
172 const char usb_tree_remove[] =
173 "  1  Hub (12 Mb/s, 100mA)\n"
174 "  |  sandbox hub 2345\n"
175 "  |\n"
176 "  |\b+-2  Mass Storage (12 Mb/s, 100mA)\n"
177 "  |    sandbox flash flash-stick@0\n"
178 "  |  \n"
179 "  |\b+-3  Mass Storage (12 Mb/s, 100mA)\n"
180 "       sandbox flash flash-stick@2\n"
181 "     \n";
182
183 /*
184  * test that the 'usb tree' command output looks correct when we remove a
185  * device
186  */
187 static int dm_test_usb_tree_remove(struct unit_test_state *uts)
188 {
189         struct udevice *dev;
190         char *data;
191         int len;
192
193         /* Remove the second emulation device */
194         ut_assertok(uclass_find_device_by_name(UCLASS_USB_EMUL, "flash-stick@1",
195                                                &dev));
196         ut_assertok(device_unbind(dev));
197
198         state_set_skip_delays(true);
199         ut_assertok(usb_init());
200         console_record_reset_enable();
201         usb_show_tree();
202         len = membuff_getraw(&gd->console_out, -1, true, &data);
203         if (len)
204                 data[len] = '\0';
205         ut_asserteq_str(usb_tree_remove, data);
206         ut_assertok(usb_stop());
207
208         return 0;
209 }
210 DM_TEST(dm_test_usb_tree_remove, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);