blob: b273a515efd2be5025641a784c3c4c9e935e1e81 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glasse00cb222015-03-25 12:23:05 -06002/*
3 * Copyright (C) 2015 Google, Inc
Simon Glasse00cb222015-03-25 12:23:05 -06004 */
5
6#include <common.h>
Simon Glass24b852a2015-11-08 23:47:45 -07007#include <console.h>
Simon Glasse00cb222015-03-25 12:23:05 -06008#include <dm.h>
Simon Glasse6f6f9e2020-05-10 11:39:58 -06009#include <part.h>
Simon Glasse00cb222015-03-25 12:23:05 -060010#include <usb.h>
11#include <asm/io.h>
Simon Glass3884c982015-11-08 23:47:44 -070012#include <asm/state.h>
Simon Glassbff1a712015-11-08 23:48:08 -070013#include <asm/test.h>
Simon Glass3884c982015-11-08 23:47:44 -070014#include <dm/device-internal.h>
Simon Glasse00cb222015-03-25 12:23:05 -060015#include <dm/test.h>
Simon Glass431cbd62015-11-08 23:48:01 -070016#include <dm/uclass-internal.h>
Joe Hershbergere721b882015-05-20 14:27:27 -050017#include <test/ut.h>
Simon Glasse00cb222015-03-25 12:23:05 -060018
Heinrich Schuchardt12f1e792019-11-23 18:15:23 +010019struct keyboard_test_data {
20 const char modifiers;
21 const char scancode;
22 const char result[6];
23};
24
Simon Glasse00cb222015-03-25 12:23:05 -060025/* Test that sandbox USB works correctly */
Joe Hershbergere721b882015-05-20 14:27:27 -050026static int dm_test_usb_base(struct unit_test_state *uts)
Simon Glasse00cb222015-03-25 12:23:05 -060027{
28 struct udevice *bus;
29
30 ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 0, &bus));
31 ut_assertok(uclass_get_device(UCLASS_USB, 0, &bus));
32 ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 2, &bus));
33
34 return 0;
35}
36DM_TEST(dm_test_usb_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
37
38/*
39 * Test that we can use the flash stick. This is more of a functional test. It
40 * covers scanning the bug, setting up a hub and a flash stick and reading
41 * data from the flash stick.
42 */
Joe Hershbergere721b882015-05-20 14:27:27 -050043static int dm_test_usb_flash(struct unit_test_state *uts)
Simon Glasse00cb222015-03-25 12:23:05 -060044{
45 struct udevice *dev;
Simon Glass4101f682016-02-29 15:25:34 -070046 struct blk_desc *dev_desc;
Simon Glasse00cb222015-03-25 12:23:05 -060047 char cmp[1024];
48
Simon Glass3884c982015-11-08 23:47:44 -070049 state_set_skip_delays(true);
Simon Glasse00cb222015-03-25 12:23:05 -060050 ut_assertok(usb_init());
51 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
Simon Glassebac37c2016-02-29 15:25:43 -070052 ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc));
Simon Glasse00cb222015-03-25 12:23:05 -060053
54 /* Read a few blocks and look for the string we expect */
55 ut_asserteq(512, dev_desc->blksz);
56 memset(cmp, '\0', sizeof(cmp));
Simon Glass2a981dc2016-02-29 15:25:52 -070057 ut_asserteq(2, blk_dread(dev_desc, 0, 2, cmp));
Simon Glasse00cb222015-03-25 12:23:05 -060058 ut_assertok(strcmp(cmp, "this is a test"));
Simon Glass61ccd882016-02-29 15:26:02 -070059 ut_assertok(usb_stop());
Simon Glasse00cb222015-03-25 12:23:05 -060060
61 return 0;
62}
63DM_TEST(dm_test_usb_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glass431cbd62015-11-08 23:48:01 -070064
65/* test that we can handle multiple storage devices */
66static int dm_test_usb_multi(struct unit_test_state *uts)
67{
68 struct udevice *dev;
69
70 state_set_skip_delays(true);
71 ut_assertok(usb_init());
72 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
73 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
74 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
Simon Glass61ccd882016-02-29 15:26:02 -070075 ut_assertok(usb_stop());
Simon Glass431cbd62015-11-08 23:48:01 -070076
77 return 0;
78}
79DM_TEST(dm_test_usb_multi, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
80
Michael Wallec03b7612020-06-02 01:47:07 +020081/* test that we have an associated ofnode with the usb device */
82static int dm_test_usb_fdt_node(struct unit_test_state *uts)
83{
84 struct udevice *dev;
85 ofnode node;
86
87 state_set_skip_delays(true);
88 ut_assertok(usb_init());
89 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
90 node = ofnode_path("/usb@1/hub/usbstor@1");
91 ut_asserteq(1, ofnode_equal(node, dev_ofnode(dev)));
92 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
93 ut_asserteq(1, ofnode_equal(ofnode_null(), dev_ofnode(dev)));
94 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
95 node = ofnode_path("/usb@1/hub/usbstor@3");
96 ut_asserteq(1, ofnode_equal(node, dev_ofnode(dev)));
97 ut_assertok(usb_stop());
98
99 return 0;
100}
101DM_TEST(dm_test_usb_fdt_node, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
102
Simon Glass431cbd62015-11-08 23:48:01 -0700103static int count_usb_devices(void)
104{
105 struct udevice *hub;
106 struct uclass *uc;
107 int count = 0;
108 int ret;
109
110 ret = uclass_get(UCLASS_USB_HUB, &uc);
111 if (ret)
112 return ret;
113
114 uclass_foreach_dev(hub, uc) {
115 struct udevice *dev;
116
117 count++;
118 for (device_find_first_child(hub, &dev);
119 dev;
120 device_find_next_child(&dev)) {
121 count++;
122 }
123 }
124
125 return count;
126}
127
Bin Mengf4d4f7d2017-10-01 06:19:45 -0700128/* test that no USB devices are found after we stop the stack */
129static int dm_test_usb_stop(struct unit_test_state *uts)
Simon Glass431cbd62015-11-08 23:48:01 -0700130{
Bin Mengf4d4f7d2017-10-01 06:19:45 -0700131 struct udevice *dev;
Simon Glass431cbd62015-11-08 23:48:01 -0700132
133 /* Scan and check that all devices are present */
134 state_set_skip_delays(true);
135 ut_assertok(usb_init());
136 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
137 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
138 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
Simon Glassa57a8172016-01-07 10:23:42 -0700139 ut_asserteq(6, count_usb_devices());
Simon Glass431cbd62015-11-08 23:48:01 -0700140 ut_assertok(usb_stop());
Bin Mengf4d4f7d2017-10-01 06:19:45 -0700141 ut_asserteq(0, count_usb_devices());
Simon Glass431cbd62015-11-08 23:48:01 -0700142
143 return 0;
144}
Bin Mengf4d4f7d2017-10-01 06:19:45 -0700145DM_TEST(dm_test_usb_stop, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
Simon Glassbff1a712015-11-08 23:48:08 -0700146
Heinrich Schuchardt12f1e792019-11-23 18:15:23 +0100147/**
148 * dm_test_usb_keyb() - test USB keyboard driver
149 *
150 * This test copies USB keyboard scan codes into the key buffer of the USB
151 * keyboard emulation driver. These are picked up during emulated interrupts
152 * by the USB keyboard driver and converted to characters and escape sequences.
153 * The test then reads and verifies these characters and escape sequences from
154 * the standard input.
155 *
156 * TODO: The following features are not yet tested:
157 *
158 * * LED status
159 * * caps-lock
160 * * num-lock
161 * * numerical pad keys
162 *
163 * TODO: The following features are not yet implemented by the USB keyboard
164 * driver and therefore not tested:
165 *
166 * * modifiers for non-alpha-numeric keys, e.g. <SHIFT><TAB> and <ALT><F4>
167 * * some special keys, e.g. <PRINT>
168 * * some modifiers, e.g. <ALT> and <META>
169 * * alternative keyboard layouts
170 *
171 * @uts: unit test state
172 * Return: 0 on success
173 */
Simon Glassbff1a712015-11-08 23:48:08 -0700174static int dm_test_usb_keyb(struct unit_test_state *uts)
175{
176 struct udevice *dev;
Heinrich Schuchardt12f1e792019-11-23 18:15:23 +0100177 const struct keyboard_test_data *pos;
178 const struct keyboard_test_data kbd_test_data[] = {
179 /* <A> */
180 {0x00, 0x04, "a"},
181 /* <B> */
182 {0x00, 0x05, "b"},
183 /* <C> */
184 {0x00, 0x06, "c"},
185 /* <D> */
186 {0x00, 0x07, "d"},
187 /* <E> */
188 {0x00, 0x08, "e"},
189 /* <F> */
190 {0x00, 0x09, "f"},
191 /* <G> */
192 {0x00, 0x0a, "g"},
193 /* <H> */
194 {0x00, 0x0b, "h"},
195 /* <I> */
196 {0x00, 0x0c, "i"},
197 /* <J> */
198 {0x00, 0x0d, "j"},
199 /* <K> */
200 {0x00, 0x0e, "k"},
201 /* <L> */
202 {0x00, 0x0f, "l"},
203 /* <M> */
204 {0x00, 0x10, "m"},
205 /* <N> */
206 {0x00, 0x11, "n"},
207 /* <O> */
208 {0x00, 0x12, "o"},
209 /* <P> */
210 {0x00, 0x13, "p"},
211 /* <Q> */
212 {0x00, 0x14, "q"},
213 /* <R> */
214 {0x00, 0x15, "r"},
215 /* <S> */
216 {0x00, 0x16, "s"},
217 /* <T> */
218 {0x00, 0x17, "t"},
219 /* <U> */
220 {0x00, 0x18, "u"},
221 /* <V> */
222 {0x00, 0x19, "v"},
223 /* <W> */
224 {0x00, 0x1a, "w"},
225 /* <X> */
226 {0x00, 0x1b, "x"},
227 /* <Y> */
228 {0x00, 0x1c, "y"},
229 /* <Z> */
230 {0x00, 0x1d, "z"},
231
232 /* <LEFT-SHIFT><A> */
233 {0x02, 0x04, "A"},
234 /* <RIGHT-SHIFT><Z> */
235 {0x20, 0x1d, "Z"},
236
237 /* <LEFT-CONTROL><A> */
238 {0x01, 0x04, "\x01"},
239 /* <RIGHT-CONTROL><Z> */
240 {0x10, 0x1d, "\x1a"},
241
242 /* <1> */
243 {0x00, 0x1e, "1"},
244 /* <2> */
245 {0x00, 0x1f, "2"},
246 /* <3> */
247 {0x00, 0x20, "3"},
248 /* <4> */
249 {0x00, 0x21, "4"},
250 /* <5> */
251 {0x00, 0x22, "5"},
252 /* <6> */
253 {0x00, 0x23, "6"},
254 /* <7> */
255 {0x00, 0x24, "7"},
256 /* <8> */
257 {0x00, 0x25, "8"},
258 /* <9> */
259 {0x00, 0x26, "9"},
260 /* <0> */
261 {0x00, 0x27, "0"},
262
263 /* <LEFT-SHIFT><1> */
264 {0x02, 0x1e, "!"},
265 /* <RIGHT-SHIFT><2> */
266 {0x20, 0x1f, "@"},
267 /* <LEFT-SHIFT><3> */
268 {0x02, 0x20, "#"},
269 /* <RIGHT-SHIFT><4> */
270 {0x20, 0x21, "$"},
271 /* <LEFT-SHIFT><5> */
272 {0x02, 0x22, "%"},
273 /* <RIGHT-SHIFT><6> */
274 {0x20, 0x23, "^"},
275 /* <LEFT-SHIFT><7> */
276 {0x02, 0x24, "&"},
277 /* <RIGHT-SHIFT><8> */
278 {0x20, 0x25, "*"},
279 /* <LEFT-SHIFT><9> */
280 {0x02, 0x26, "("},
281 /* <RIGHT-SHIFT><0> */
282 {0x20, 0x27, ")"},
283
284 /* <ENTER> */
285 {0x00, 0x28, "\r"},
286 /* <ESCAPE> */
287 {0x00, 0x29, "\x1b"},
288 /* <BACKSPACE> */
289 {0x00, 0x2a, "\x08"},
290 /* <TAB> */
291 {0x00, 0x2b, "\x09"},
292 /* <SPACE> */
293 {0x00, 0x2c, " "},
294 /* <MINUS> */
295 {0x00, 0x2d, "-"},
296 /* <EQUAL> */
297 {0x00, 0x2e, "="},
298 /* <LEFT BRACE> */
299 {0x00, 0x2f, "["},
300 /* <RIGHT BRACE> */
301 {0x00, 0x30, "]"},
302 /* <BACKSLASH> */
303 {0x00, 0x31, "\\"},
304 /* <HASH-TILDE> */
305 {0x00, 0x32, "#"},
306 /* <SEMICOLON> */
307 {0x00, 0x33, ";"},
308 /* <APOSTROPHE> */
309 {0x00, 0x34, "'"},
310 /* <GRAVE> */
311 {0x00, 0x35, "`"},
312 /* <COMMA> */
313 {0x00, 0x36, ","},
314 /* <DOT> */
315 {0x00, 0x37, "."},
316 /* <SLASH> */
317 {0x00, 0x38, "/"},
318
319 /* <LEFT-SHIFT><ENTER> */
320 {0x02, 0x28, "\r"},
321 /* <RIGHT-SHIFT><ESCAPE> */
322 {0x20, 0x29, "\x1b"},
323 /* <LEFT-SHIFT><BACKSPACE> */
324 {0x02, 0x2a, "\x08"},
325 /* <RIGHT-SHIFT><TAB> */
326 {0x20, 0x2b, "\x09"},
327 /* <LEFT-SHIFT><SPACE> */
328 {0x02, 0x2c, " "},
329 /* <MINUS> */
330 {0x20, 0x2d, "_"},
331 /* <LEFT-SHIFT><EQUAL> */
332 {0x02, 0x2e, "+"},
333 /* <RIGHT-SHIFT><LEFT BRACE> */
334 {0x20, 0x2f, "{"},
335 /* <LEFT-SHIFT><RIGHT BRACE> */
336 {0x02, 0x30, "}"},
337 /* <RIGHT-SHIFT><BACKSLASH> */
338 {0x20, 0x31, "|"},
339 /* <LEFT-SHIFT><HASH-TILDE> */
340 {0x02, 0x32, "~"},
341 /* <RIGHT-SHIFT><SEMICOLON> */
342 {0x20, 0x33, ":"},
343 /* <LEFT-SHIFT><APOSTROPHE> */
344 {0x02, 0x34, "\""},
345 /* <RIGHT-SHIFT><GRAVE> */
346 {0x20, 0x35, "~"},
347 /* <LEFT-SHIFT><COMMA> */
348 {0x02, 0x36, "<"},
349 /* <RIGHT-SHIFT><DOT> */
350 {0x20, 0x37, ">"},
351 /* <LEFT-SHIFT><SLASH> */
352 {0x02, 0x38, "?"},
353#ifdef CONFIG_USB_KEYBOARD_FN_KEYS
354 /* <F1> */
355 {0x00, 0x3a, "\x1bOP"},
356 /* <F2> */
357 {0x00, 0x3b, "\x1bOQ"},
358 /* <F3> */
359 {0x00, 0x3c, "\x1bOR"},
360 /* <F4> */
361 {0x00, 0x3d, "\x1bOS"},
362 /* <F5> */
363 {0x00, 0x3e, "\x1b[15~"},
364 /* <F6> */
365 {0x00, 0x3f, "\x1b[17~"},
366 /* <F7> */
367 {0x00, 0x40, "\x1b[18~"},
368 /* <F8> */
369 {0x00, 0x41, "\x1b[19~"},
370 /* <F9> */
371 {0x00, 0x42, "\x1b[20~"},
372 /* <F10> */
373 {0x00, 0x43, "\x1b[21~"},
374 /* <F11> */
375 {0x00, 0x44, "\x1b[23~"},
376 /* <F12> */
377 {0x00, 0x45, "\x1b[24~"},
378 /* <INSERT> */
379 {0x00, 0x49, "\x1b[2~"},
380 /* <HOME> */
381 {0x00, 0x4a, "\x1b[H"},
382 /* <PAGE UP> */
383 {0x00, 0x4b, "\x1b[5~"},
384 /* <DELETE> */
385 {0x00, 0x4c, "\x1b[3~"},
386 /* <END> */
387 {0x00, 0x4d, "\x1b[F"},
388 /* <PAGE DOWN> */
389 {0x00, 0x4e, "\x1b[6~"},
390 /* <RIGHT> */
391 {0x00, 0x4f, "\x1b[C"},
392 /* <LEFT> */
393 {0x00, 0x50, "\x1b[D"},
394 /* <DOWN> */
395 {0x00, 0x51, "\x1b[B"},
396 /* <UP> */
397 {0x00, 0x52, "\x1b[A"},
398#endif /* CONFIG_USB_KEYBOARD_FN_KEYS */
399
400 /* End of list */
401 {0x00, 0x00, "\0"}
402 };
403
Simon Glassbff1a712015-11-08 23:48:08 -0700404
405 state_set_skip_delays(true);
406 ut_assertok(usb_init());
407
408 /* Initially there should be no characters */
409 ut_asserteq(0, tstc());
410
Peng Fan819ac502019-05-22 07:08:12 +0000411 ut_assertok(uclass_get_device_by_name(UCLASS_USB_EMUL, "keyb@3",
Simon Glassbff1a712015-11-08 23:48:08 -0700412 &dev));
413
414 /*
Heinrich Schuchardt12f1e792019-11-23 18:15:23 +0100415 * Add scan codes to the USB keyboard buffer. They should appear as
416 * corresponding characters and escape sequences in stdin.
Simon Glassbff1a712015-11-08 23:48:08 -0700417 */
Heinrich Schuchardt12f1e792019-11-23 18:15:23 +0100418 for (pos = kbd_test_data; pos->scancode; ++pos) {
419 const char *c;
420 char scancodes[USB_KBD_BOOT_REPORT_SIZE] = {0};
Simon Glassbff1a712015-11-08 23:48:08 -0700421
Heinrich Schuchardt12f1e792019-11-23 18:15:23 +0100422 scancodes[0] = pos->modifiers;
423 scancodes[2] = pos->scancode;
424
425 ut_assertok(sandbox_usb_keyb_add_string(dev, scancodes));
426
427 for (c = pos->result; *c; ++c) {
428 ut_asserteq(1, tstc());
429 ut_asserteq(*c, getc());
430 }
431 ut_asserteq(0, tstc());
432 }
Simon Glassbff1a712015-11-08 23:48:08 -0700433 ut_assertok(usb_stop());
434
435 return 0;
436}
437DM_TEST(dm_test_usb_keyb, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);