1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2015 Google, Inc
11 #include <asm/state.h>
13 #include <dm/device-internal.h>
15 #include <dm/uclass-internal.h>
18 struct keyboard_test_data {
24 /* Test that sandbox USB works correctly */
25 static int dm_test_usb_base(struct unit_test_state *uts)
29 ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 0, &bus));
30 ut_assertok(uclass_get_device(UCLASS_USB, 0, &bus));
31 ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 2, &bus));
35 DM_TEST(dm_test_usb_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
38 * Test that we can use the flash stick. This is more of a functional test. It
39 * covers scanning the bug, setting up a hub and a flash stick and reading
40 * data from the flash stick.
42 static int dm_test_usb_flash(struct unit_test_state *uts)
45 struct blk_desc *dev_desc;
48 state_set_skip_delays(true);
49 ut_assertok(usb_init());
50 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
51 ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc));
53 /* Read a few blocks and look for the string we expect */
54 ut_asserteq(512, dev_desc->blksz);
55 memset(cmp, '\0', sizeof(cmp));
56 ut_asserteq(2, blk_dread(dev_desc, 0, 2, cmp));
57 ut_assertok(strcmp(cmp, "this is a test"));
58 ut_assertok(usb_stop());
62 DM_TEST(dm_test_usb_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
64 /* test that we can handle multiple storage devices */
65 static int dm_test_usb_multi(struct unit_test_state *uts)
69 state_set_skip_delays(true);
70 ut_assertok(usb_init());
71 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
72 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
73 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
74 ut_assertok(usb_stop());
78 DM_TEST(dm_test_usb_multi, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
80 static int count_usb_devices(void)
87 ret = uclass_get(UCLASS_USB_HUB, &uc);
91 uclass_foreach_dev(hub, uc) {
95 for (device_find_first_child(hub, &dev);
97 device_find_next_child(&dev)) {
105 /* test that no USB devices are found after we stop the stack */
106 static int dm_test_usb_stop(struct unit_test_state *uts)
110 /* Scan and check that all devices are present */
111 state_set_skip_delays(true);
112 ut_assertok(usb_init());
113 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
114 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
115 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
116 ut_asserteq(6, count_usb_devices());
117 ut_assertok(usb_stop());
118 ut_asserteq(0, count_usb_devices());
122 DM_TEST(dm_test_usb_stop, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
125 * dm_test_usb_keyb() - test USB keyboard driver
127 * This test copies USB keyboard scan codes into the key buffer of the USB
128 * keyboard emulation driver. These are picked up during emulated interrupts
129 * by the USB keyboard driver and converted to characters and escape sequences.
130 * The test then reads and verifies these characters and escape sequences from
131 * the standard input.
133 * TODO: The following features are not yet tested:
138 * * numerical pad keys
140 * TODO: The following features are not yet implemented by the USB keyboard
141 * driver and therefore not tested:
143 * * modifiers for non-alpha-numeric keys, e.g. <SHIFT><TAB> and <ALT><F4>
144 * * some special keys, e.g. <PRINT>
145 * * some modifiers, e.g. <ALT> and <META>
146 * * alternative keyboard layouts
148 * @uts: unit test state
149 * Return: 0 on success
151 static int dm_test_usb_keyb(struct unit_test_state *uts)
154 const struct keyboard_test_data *pos;
155 const struct keyboard_test_data kbd_test_data[] = {
209 /* <LEFT-SHIFT><A> */
211 /* <RIGHT-SHIFT><Z> */
214 /* <LEFT-CONTROL><A> */
215 {0x01, 0x04, "\x01"},
216 /* <RIGHT-CONTROL><Z> */
217 {0x10, 0x1d, "\x1a"},
240 /* <LEFT-SHIFT><1> */
242 /* <RIGHT-SHIFT><2> */
244 /* <LEFT-SHIFT><3> */
246 /* <RIGHT-SHIFT><4> */
248 /* <LEFT-SHIFT><5> */
250 /* <RIGHT-SHIFT><6> */
252 /* <LEFT-SHIFT><7> */
254 /* <RIGHT-SHIFT><8> */
256 /* <LEFT-SHIFT><9> */
258 /* <RIGHT-SHIFT><0> */
264 {0x00, 0x29, "\x1b"},
266 {0x00, 0x2a, "\x08"},
268 {0x00, 0x2b, "\x09"},
296 /* <LEFT-SHIFT><ENTER> */
298 /* <RIGHT-SHIFT><ESCAPE> */
299 {0x20, 0x29, "\x1b"},
300 /* <LEFT-SHIFT><BACKSPACE> */
301 {0x02, 0x2a, "\x08"},
302 /* <RIGHT-SHIFT><TAB> */
303 {0x20, 0x2b, "\x09"},
304 /* <LEFT-SHIFT><SPACE> */
308 /* <LEFT-SHIFT><EQUAL> */
310 /* <RIGHT-SHIFT><LEFT BRACE> */
312 /* <LEFT-SHIFT><RIGHT BRACE> */
314 /* <RIGHT-SHIFT><BACKSLASH> */
316 /* <LEFT-SHIFT><HASH-TILDE> */
318 /* <RIGHT-SHIFT><SEMICOLON> */
320 /* <LEFT-SHIFT><APOSTROPHE> */
322 /* <RIGHT-SHIFT><GRAVE> */
324 /* <LEFT-SHIFT><COMMA> */
326 /* <RIGHT-SHIFT><DOT> */
328 /* <LEFT-SHIFT><SLASH> */
330 #ifdef CONFIG_USB_KEYBOARD_FN_KEYS
332 {0x00, 0x3a, "\x1bOP"},
334 {0x00, 0x3b, "\x1bOQ"},
336 {0x00, 0x3c, "\x1bOR"},
338 {0x00, 0x3d, "\x1bOS"},
340 {0x00, 0x3e, "\x1b[15~"},
342 {0x00, 0x3f, "\x1b[17~"},
344 {0x00, 0x40, "\x1b[18~"},
346 {0x00, 0x41, "\x1b[19~"},
348 {0x00, 0x42, "\x1b[20~"},
350 {0x00, 0x43, "\x1b[21~"},
352 {0x00, 0x44, "\x1b[23~"},
354 {0x00, 0x45, "\x1b[24~"},
356 {0x00, 0x49, "\x1b[2~"},
358 {0x00, 0x4a, "\x1b[H"},
360 {0x00, 0x4b, "\x1b[5~"},
362 {0x00, 0x4c, "\x1b[3~"},
364 {0x00, 0x4d, "\x1b[F"},
366 {0x00, 0x4e, "\x1b[6~"},
368 {0x00, 0x4f, "\x1b[C"},
370 {0x00, 0x50, "\x1b[D"},
372 {0x00, 0x51, "\x1b[B"},
374 {0x00, 0x52, "\x1b[A"},
375 #endif /* CONFIG_USB_KEYBOARD_FN_KEYS */
382 state_set_skip_delays(true);
383 ut_assertok(usb_init());
385 /* Initially there should be no characters */
386 ut_asserteq(0, tstc());
388 ut_assertok(uclass_get_device_by_name(UCLASS_USB_EMUL, "keyb@3",
392 * Add scan codes to the USB keyboard buffer. They should appear as
393 * corresponding characters and escape sequences in stdin.
395 for (pos = kbd_test_data; pos->scancode; ++pos) {
397 char scancodes[USB_KBD_BOOT_REPORT_SIZE] = {0};
399 scancodes[0] = pos->modifiers;
400 scancodes[2] = pos->scancode;
402 ut_assertok(sandbox_usb_keyb_add_string(dev, scancodes));
404 for (c = pos->result; *c; ++c) {
405 ut_asserteq(1, tstc());
406 ut_asserteq(*c, getc());
408 ut_asserteq(0, tstc());
410 ut_assertok(usb_stop());
414 DM_TEST(dm_test_usb_keyb, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);