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>
16 #include <test/test.h>
19 struct keyboard_test_data {
25 /* Test that sandbox USB works correctly */
26 static int dm_test_usb_base(struct unit_test_state *uts)
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));
36 DM_TEST(dm_test_usb_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
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.
43 static int dm_test_usb_flash(struct unit_test_state *uts)
45 struct blk_desc *dev_desc, *chk;
46 struct udevice *dev, *blk;
49 state_set_skip_delays(true);
50 ut_assertok(usb_init());
51 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
52 ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc));
53 chk = blk_get_by_device(dev);
54 ut_asserteq_ptr(chk, dev_desc);
56 ut_assertok(device_find_first_child_by_uclass(dev, UCLASS_BLK, &blk));
57 ut_asserteq_ptr(chk, blk_get_by_device(dev));
59 /* Read a few blocks and look for the string we expect */
60 ut_asserteq(512, dev_desc->blksz);
61 memset(cmp, '\0', sizeof(cmp));
62 ut_asserteq(2, blk_read(blk, 0, 2, cmp));
63 ut_asserteq_str("this is a test", cmp);
65 strcpy(cmp, "another test");
66 ut_asserteq(1, blk_write(blk, 1, 1, cmp));
68 memset(cmp, '\0', sizeof(cmp));
69 ut_asserteq(2, blk_read(blk, 0, 2, cmp));
70 ut_asserteq_str("this is a test", cmp);
71 ut_asserteq_str("another test", cmp + 512);
73 memset(cmp, '\0', sizeof(cmp));
74 ut_asserteq(1, blk_write(blk, 1, 1, cmp));
76 memset(cmp, '\0', sizeof(cmp));
77 ut_asserteq(2, blk_read(blk, 0, 2, cmp));
78 ut_asserteq_str("this is a test", cmp);
79 ut_asserteq_str("", cmp + 512);
81 ut_assertok(usb_stop());
85 DM_TEST(dm_test_usb_flash, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
87 /* test that we can handle multiple storage devices */
88 static int dm_test_usb_multi(struct unit_test_state *uts)
92 state_set_skip_delays(true);
93 ut_assertok(usb_init());
94 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
95 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
96 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
97 ut_assertok(usb_stop());
101 DM_TEST(dm_test_usb_multi, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
103 /* test that we have an associated ofnode with the usb device */
104 static int dm_test_usb_fdt_node(struct unit_test_state *uts)
109 state_set_skip_delays(true);
110 ut_assertok(usb_init());
111 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
112 node = ofnode_path("/usb@1/hub/usbstor@1");
113 ut_asserteq(1, ofnode_equal(node, dev_ofnode(dev)));
114 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
115 ut_asserteq(1, ofnode_equal(ofnode_null(), dev_ofnode(dev)));
116 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
117 node = ofnode_path("/usb@1/hub/usbstor@3");
118 ut_asserteq(1, ofnode_equal(node, dev_ofnode(dev)));
119 ut_assertok(usb_stop());
123 DM_TEST(dm_test_usb_fdt_node, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
125 static int count_usb_devices(void)
132 ret = uclass_get(UCLASS_USB_HUB, &uc);
136 uclass_foreach_dev(hub, uc) {
140 for (device_find_first_child(hub, &dev);
142 device_find_next_child(&dev)) {
150 /* test that no USB devices are found after we stop the stack */
151 static int dm_test_usb_stop(struct unit_test_state *uts)
155 /* Scan and check that all devices are present */
156 state_set_skip_delays(true);
157 ut_assertok(usb_init());
158 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
159 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
160 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
161 ut_asserteq(6, count_usb_devices());
162 ut_assertok(usb_stop());
163 ut_asserteq(0, count_usb_devices());
167 DM_TEST(dm_test_usb_stop, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
170 * dm_test_usb_keyb() - test USB keyboard driver
172 * This test copies USB keyboard scan codes into the key buffer of the USB
173 * keyboard emulation driver. These are picked up during emulated interrupts
174 * by the USB keyboard driver and converted to characters and escape sequences.
175 * The test then reads and verifies these characters and escape sequences from
176 * the standard input.
178 * TODO: The following features are not yet tested:
183 * * numerical pad keys
185 * TODO: The following features are not yet implemented by the USB keyboard
186 * driver and therefore not tested:
188 * * modifiers for non-alpha-numeric keys, e.g. <SHIFT><TAB> and <ALT><F4>
189 * * some special keys, e.g. <PRINT>
190 * * some modifiers, e.g. <ALT> and <META>
191 * * alternative keyboard layouts
193 * @uts: unit test state
194 * Return: 0 on success
196 static int dm_test_usb_keyb(struct unit_test_state *uts)
199 const struct keyboard_test_data *pos;
200 const struct keyboard_test_data kbd_test_data[] = {
254 /* <LEFT-SHIFT><A> */
256 /* <RIGHT-SHIFT><Z> */
259 /* <LEFT-CONTROL><A> */
260 {0x01, 0x04, "\x01"},
261 /* <RIGHT-CONTROL><Z> */
262 {0x10, 0x1d, "\x1a"},
285 /* <LEFT-SHIFT><1> */
287 /* <RIGHT-SHIFT><2> */
289 /* <LEFT-SHIFT><3> */
291 /* <RIGHT-SHIFT><4> */
293 /* <LEFT-SHIFT><5> */
295 /* <RIGHT-SHIFT><6> */
297 /* <LEFT-SHIFT><7> */
299 /* <RIGHT-SHIFT><8> */
301 /* <LEFT-SHIFT><9> */
303 /* <RIGHT-SHIFT><0> */
309 {0x00, 0x29, "\x1b"},
311 {0x00, 0x2a, "\x08"},
313 {0x00, 0x2b, "\x09"},
341 /* <LEFT-SHIFT><ENTER> */
343 /* <RIGHT-SHIFT><ESCAPE> */
344 {0x20, 0x29, "\x1b"},
345 /* <LEFT-SHIFT><BACKSPACE> */
346 {0x02, 0x2a, "\x08"},
347 /* <RIGHT-SHIFT><TAB> */
348 {0x20, 0x2b, "\x09"},
349 /* <LEFT-SHIFT><SPACE> */
353 /* <LEFT-SHIFT><EQUAL> */
355 /* <RIGHT-SHIFT><LEFT BRACE> */
357 /* <LEFT-SHIFT><RIGHT BRACE> */
359 /* <RIGHT-SHIFT><BACKSLASH> */
361 /* <LEFT-SHIFT><HASH-TILDE> */
363 /* <RIGHT-SHIFT><SEMICOLON> */
365 /* <LEFT-SHIFT><APOSTROPHE> */
367 /* <RIGHT-SHIFT><GRAVE> */
369 /* <LEFT-SHIFT><COMMA> */
371 /* <RIGHT-SHIFT><DOT> */
373 /* <LEFT-SHIFT><SLASH> */
375 #ifdef CONFIG_USB_KEYBOARD_FN_KEYS
377 {0x00, 0x3a, "\x1bOP"},
379 {0x00, 0x3b, "\x1bOQ"},
381 {0x00, 0x3c, "\x1bOR"},
383 {0x00, 0x3d, "\x1bOS"},
385 {0x00, 0x3e, "\x1b[15~"},
387 {0x00, 0x3f, "\x1b[17~"},
389 {0x00, 0x40, "\x1b[18~"},
391 {0x00, 0x41, "\x1b[19~"},
393 {0x00, 0x42, "\x1b[20~"},
395 {0x00, 0x43, "\x1b[21~"},
397 {0x00, 0x44, "\x1b[23~"},
399 {0x00, 0x45, "\x1b[24~"},
401 {0x00, 0x49, "\x1b[2~"},
403 {0x00, 0x4a, "\x1b[H"},
405 {0x00, 0x4b, "\x1b[5~"},
407 {0x00, 0x4c, "\x1b[3~"},
409 {0x00, 0x4d, "\x1b[F"},
411 {0x00, 0x4e, "\x1b[6~"},
413 {0x00, 0x4f, "\x1b[C"},
415 {0x00, 0x50, "\x1b[D"},
417 {0x00, 0x51, "\x1b[B"},
419 {0x00, 0x52, "\x1b[A"},
420 #endif /* CONFIG_USB_KEYBOARD_FN_KEYS */
427 state_set_skip_delays(true);
428 ut_assertok(usb_init());
430 /* Initially there should be no characters */
431 ut_asserteq(0, tstc());
433 ut_assertok(uclass_get_device_by_name(UCLASS_USB_EMUL, "keyb@3",
437 * Add scan codes to the USB keyboard buffer. They should appear as
438 * corresponding characters and escape sequences in stdin.
440 for (pos = kbd_test_data; pos->scancode; ++pos) {
442 char scancodes[USB_KBD_BOOT_REPORT_SIZE] = {0};
444 scancodes[0] = pos->modifiers;
445 scancodes[2] = pos->scancode;
447 ut_assertok(sandbox_usb_keyb_add_string(dev, scancodes));
449 for (c = pos->result; *c; ++c) {
450 ut_asserteq(1, tstc());
451 ut_asserteq(*c, getchar());
453 ut_asserteq(0, tstc());
455 ut_assertok(usb_stop());
459 DM_TEST(dm_test_usb_keyb, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);