1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2015 Google, Inc
12 #include <asm/state.h>
14 #include <dm/device-internal.h>
16 #include <dm/uclass-internal.h>
17 #include <test/test.h>
20 struct keyboard_test_data {
26 /* Test that sandbox USB works correctly */
27 static int dm_test_usb_base(struct unit_test_state *uts)
31 ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 0, &bus));
32 ut_assertok(uclass_get_device(UCLASS_USB, 0, &bus));
33 ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 2, &bus));
37 DM_TEST(dm_test_usb_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
40 * Test that we can use the flash stick. This is more of a functional test. It
41 * covers scanning the bug, setting up a hub and a flash stick and reading
42 * data from the flash stick.
44 static int dm_test_usb_flash(struct unit_test_state *uts)
47 struct blk_desc *dev_desc;
50 state_set_skip_delays(true);
51 ut_assertok(usb_init());
52 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
53 ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc));
55 /* Read a few blocks and look for the string we expect */
56 ut_asserteq(512, dev_desc->blksz);
57 memset(cmp, '\0', sizeof(cmp));
58 ut_asserteq(2, blk_dread(dev_desc, 0, 2, cmp));
59 ut_assertok(strcmp(cmp, "this is a test"));
60 ut_assertok(usb_stop());
64 DM_TEST(dm_test_usb_flash, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
66 /* test that we can handle multiple storage devices */
67 static int dm_test_usb_multi(struct unit_test_state *uts)
71 state_set_skip_delays(true);
72 ut_assertok(usb_init());
73 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
74 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
75 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
76 ut_assertok(usb_stop());
80 DM_TEST(dm_test_usb_multi, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
82 /* test that we have an associated ofnode with the usb device */
83 static int dm_test_usb_fdt_node(struct unit_test_state *uts)
88 state_set_skip_delays(true);
89 ut_assertok(usb_init());
90 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
91 node = ofnode_path("/usb@1/hub/usbstor@1");
92 ut_asserteq(1, ofnode_equal(node, dev_ofnode(dev)));
93 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
94 ut_asserteq(1, ofnode_equal(ofnode_null(), dev_ofnode(dev)));
95 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
96 node = ofnode_path("/usb@1/hub/usbstor@3");
97 ut_asserteq(1, ofnode_equal(node, dev_ofnode(dev)));
98 ut_assertok(usb_stop());
102 DM_TEST(dm_test_usb_fdt_node, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
104 static int count_usb_devices(void)
111 ret = uclass_get(UCLASS_USB_HUB, &uc);
115 uclass_foreach_dev(hub, uc) {
119 for (device_find_first_child(hub, &dev);
121 device_find_next_child(&dev)) {
129 /* test that no USB devices are found after we stop the stack */
130 static int dm_test_usb_stop(struct unit_test_state *uts)
134 /* Scan and check that all devices are present */
135 state_set_skip_delays(true);
136 ut_assertok(usb_init());
137 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
138 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
139 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
140 ut_asserteq(6, count_usb_devices());
141 ut_assertok(usb_stop());
142 ut_asserteq(0, count_usb_devices());
146 DM_TEST(dm_test_usb_stop, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
149 * dm_test_usb_keyb() - test USB keyboard driver
151 * This test copies USB keyboard scan codes into the key buffer of the USB
152 * keyboard emulation driver. These are picked up during emulated interrupts
153 * by the USB keyboard driver and converted to characters and escape sequences.
154 * The test then reads and verifies these characters and escape sequences from
155 * the standard input.
157 * TODO: The following features are not yet tested:
162 * * numerical pad keys
164 * TODO: The following features are not yet implemented by the USB keyboard
165 * driver and therefore not tested:
167 * * modifiers for non-alpha-numeric keys, e.g. <SHIFT><TAB> and <ALT><F4>
168 * * some special keys, e.g. <PRINT>
169 * * some modifiers, e.g. <ALT> and <META>
170 * * alternative keyboard layouts
172 * @uts: unit test state
173 * Return: 0 on success
175 static int dm_test_usb_keyb(struct unit_test_state *uts)
178 const struct keyboard_test_data *pos;
179 const struct keyboard_test_data kbd_test_data[] = {
233 /* <LEFT-SHIFT><A> */
235 /* <RIGHT-SHIFT><Z> */
238 /* <LEFT-CONTROL><A> */
239 {0x01, 0x04, "\x01"},
240 /* <RIGHT-CONTROL><Z> */
241 {0x10, 0x1d, "\x1a"},
264 /* <LEFT-SHIFT><1> */
266 /* <RIGHT-SHIFT><2> */
268 /* <LEFT-SHIFT><3> */
270 /* <RIGHT-SHIFT><4> */
272 /* <LEFT-SHIFT><5> */
274 /* <RIGHT-SHIFT><6> */
276 /* <LEFT-SHIFT><7> */
278 /* <RIGHT-SHIFT><8> */
280 /* <LEFT-SHIFT><9> */
282 /* <RIGHT-SHIFT><0> */
288 {0x00, 0x29, "\x1b"},
290 {0x00, 0x2a, "\x08"},
292 {0x00, 0x2b, "\x09"},
320 /* <LEFT-SHIFT><ENTER> */
322 /* <RIGHT-SHIFT><ESCAPE> */
323 {0x20, 0x29, "\x1b"},
324 /* <LEFT-SHIFT><BACKSPACE> */
325 {0x02, 0x2a, "\x08"},
326 /* <RIGHT-SHIFT><TAB> */
327 {0x20, 0x2b, "\x09"},
328 /* <LEFT-SHIFT><SPACE> */
332 /* <LEFT-SHIFT><EQUAL> */
334 /* <RIGHT-SHIFT><LEFT BRACE> */
336 /* <LEFT-SHIFT><RIGHT BRACE> */
338 /* <RIGHT-SHIFT><BACKSLASH> */
340 /* <LEFT-SHIFT><HASH-TILDE> */
342 /* <RIGHT-SHIFT><SEMICOLON> */
344 /* <LEFT-SHIFT><APOSTROPHE> */
346 /* <RIGHT-SHIFT><GRAVE> */
348 /* <LEFT-SHIFT><COMMA> */
350 /* <RIGHT-SHIFT><DOT> */
352 /* <LEFT-SHIFT><SLASH> */
354 #ifdef CONFIG_USB_KEYBOARD_FN_KEYS
356 {0x00, 0x3a, "\x1bOP"},
358 {0x00, 0x3b, "\x1bOQ"},
360 {0x00, 0x3c, "\x1bOR"},
362 {0x00, 0x3d, "\x1bOS"},
364 {0x00, 0x3e, "\x1b[15~"},
366 {0x00, 0x3f, "\x1b[17~"},
368 {0x00, 0x40, "\x1b[18~"},
370 {0x00, 0x41, "\x1b[19~"},
372 {0x00, 0x42, "\x1b[20~"},
374 {0x00, 0x43, "\x1b[21~"},
376 {0x00, 0x44, "\x1b[23~"},
378 {0x00, 0x45, "\x1b[24~"},
380 {0x00, 0x49, "\x1b[2~"},
382 {0x00, 0x4a, "\x1b[H"},
384 {0x00, 0x4b, "\x1b[5~"},
386 {0x00, 0x4c, "\x1b[3~"},
388 {0x00, 0x4d, "\x1b[F"},
390 {0x00, 0x4e, "\x1b[6~"},
392 {0x00, 0x4f, "\x1b[C"},
394 {0x00, 0x50, "\x1b[D"},
396 {0x00, 0x51, "\x1b[B"},
398 {0x00, 0x52, "\x1b[A"},
399 #endif /* CONFIG_USB_KEYBOARD_FN_KEYS */
406 state_set_skip_delays(true);
407 ut_assertok(usb_init());
409 /* Initially there should be no characters */
410 ut_asserteq(0, tstc());
412 ut_assertok(uclass_get_device_by_name(UCLASS_USB_EMUL, "keyb@3",
416 * Add scan codes to the USB keyboard buffer. They should appear as
417 * corresponding characters and escape sequences in stdin.
419 for (pos = kbd_test_data; pos->scancode; ++pos) {
421 char scancodes[USB_KBD_BOOT_REPORT_SIZE] = {0};
423 scancodes[0] = pos->modifiers;
424 scancodes[2] = pos->scancode;
426 ut_assertok(sandbox_usb_keyb_add_string(dev, scancodes));
428 for (c = pos->result; *c; ++c) {
429 ut_asserteq(1, tstc());
430 ut_asserteq(*c, getchar());
432 ut_asserteq(0, tstc());
434 ut_assertok(usb_stop());
438 DM_TEST(dm_test_usb_keyb, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);