Files
u-boot/test/dm/usb.c
Tom Rini d678a59d2d Revert "Merge patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet""
When bringing in the series 'arm: dts: am62-beagleplay: Fix Beagleplay
Ethernet"' I failed to notice that b4 noticed it was based on next and
so took that as the base commit and merged that part of next to master.

This reverts commit c8ffd1356d, reversing
changes made to 2ee6f3a5f7.

Reported-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Tom Rini <trini@konsulko.com>
2024-05-19 08:16:36 -06:00

461 lines
11 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2015 Google, Inc
*/
#include <common.h>
#include <console.h>
#include <dm.h>
#include <part.h>
#include <usb.h>
#include <asm/io.h>
#include <asm/state.h>
#include <asm/test.h>
#include <dm/device-internal.h>
#include <dm/test.h>
#include <dm/uclass-internal.h>
#include <test/test.h>
#include <test/ut.h>
struct keyboard_test_data {
const char modifiers;
const char scancode;
const char result[6];
};
/* Test that sandbox USB works correctly */
static int dm_test_usb_base(struct unit_test_state *uts)
{
struct udevice *bus;
ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 0, &bus));
ut_assertok(uclass_get_device(UCLASS_USB, 0, &bus));
ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 2, &bus));
return 0;
}
DM_TEST(dm_test_usb_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
/*
* Test that we can use the flash stick. This is more of a functional test. It
* covers scanning the bug, setting up a hub and a flash stick and reading
* data from the flash stick.
*/
static int dm_test_usb_flash(struct unit_test_state *uts)
{
struct blk_desc *dev_desc, *chk;
struct udevice *dev, *blk;
char cmp[1024];
state_set_skip_delays(true);
ut_assertok(usb_init());
ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc));
chk = blk_get_by_device(dev);
ut_asserteq_ptr(chk, dev_desc);
ut_assertok(device_find_first_child_by_uclass(dev, UCLASS_BLK, &blk));
ut_asserteq_ptr(chk, blk_get_by_device(dev));
/* Read a few blocks and look for the string we expect */
ut_asserteq(512, dev_desc->blksz);
memset(cmp, '\0', sizeof(cmp));
ut_asserteq(2, blk_read(blk, 0, 2, cmp));
ut_asserteq_str("this is a test", cmp);
strcpy(cmp, "another test");
ut_asserteq(1, blk_write(blk, 1, 1, cmp));
memset(cmp, '\0', sizeof(cmp));
ut_asserteq(2, blk_read(blk, 0, 2, cmp));
ut_asserteq_str("this is a test", cmp);
ut_asserteq_str("another test", cmp + 512);
memset(cmp, '\0', sizeof(cmp));
ut_asserteq(1, blk_write(blk, 1, 1, cmp));
memset(cmp, '\0', sizeof(cmp));
ut_asserteq(2, blk_read(blk, 0, 2, cmp));
ut_asserteq_str("this is a test", cmp);
ut_asserteq_str("", cmp + 512);
ut_assertok(usb_stop());
return 0;
}
DM_TEST(dm_test_usb_flash, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
/* test that we can handle multiple storage devices */
static int dm_test_usb_multi(struct unit_test_state *uts)
{
struct udevice *dev;
state_set_skip_delays(true);
ut_assertok(usb_init());
ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
ut_assertok(usb_stop());
return 0;
}
DM_TEST(dm_test_usb_multi, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
/* test that we have an associated ofnode with the usb device */
static int dm_test_usb_fdt_node(struct unit_test_state *uts)
{
struct udevice *dev;
ofnode node;
state_set_skip_delays(true);
ut_assertok(usb_init());
ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
node = ofnode_path("/usb@1/hub/usbstor@1");
ut_asserteq(1, ofnode_equal(node, dev_ofnode(dev)));
ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
ut_asserteq(1, ofnode_equal(ofnode_null(), dev_ofnode(dev)));
ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
node = ofnode_path("/usb@1/hub/usbstor@3");
ut_asserteq(1, ofnode_equal(node, dev_ofnode(dev)));
ut_assertok(usb_stop());
return 0;
}
DM_TEST(dm_test_usb_fdt_node, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
static int count_usb_devices(void)
{
struct udevice *hub;
struct uclass *uc;
int count = 0;
int ret;
ret = uclass_get(UCLASS_USB_HUB, &uc);
if (ret)
return ret;
uclass_foreach_dev(hub, uc) {
struct udevice *dev;
count++;
for (device_find_first_child(hub, &dev);
dev;
device_find_next_child(&dev)) {
count++;
}
}
return count;
}
/* test that no USB devices are found after we stop the stack */
static int dm_test_usb_stop(struct unit_test_state *uts)
{
struct udevice *dev;
/* Scan and check that all devices are present */
state_set_skip_delays(true);
ut_assertok(usb_init());
ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
ut_asserteq(6, count_usb_devices());
ut_assertok(usb_stop());
ut_asserteq(0, count_usb_devices());
return 0;
}
DM_TEST(dm_test_usb_stop, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
/**
* dm_test_usb_keyb() - test USB keyboard driver
*
* This test copies USB keyboard scan codes into the key buffer of the USB
* keyboard emulation driver. These are picked up during emulated interrupts
* by the USB keyboard driver and converted to characters and escape sequences.
* The test then reads and verifies these characters and escape sequences from
* the standard input.
*
* TODO: The following features are not yet tested:
*
* * LED status
* * caps-lock
* * num-lock
* * numerical pad keys
*
* TODO: The following features are not yet implemented by the USB keyboard
* driver and therefore not tested:
*
* * modifiers for non-alpha-numeric keys, e.g. <SHIFT><TAB> and <ALT><F4>
* * some special keys, e.g. <PRINT>
* * some modifiers, e.g. <ALT> and <META>
* * alternative keyboard layouts
*
* @uts: unit test state
* Return: 0 on success
*/
static int dm_test_usb_keyb(struct unit_test_state *uts)
{
struct udevice *dev;
const struct keyboard_test_data *pos;
const struct keyboard_test_data kbd_test_data[] = {
/* <A> */
{0x00, 0x04, "a"},
/* <B> */
{0x00, 0x05, "b"},
/* <C> */
{0x00, 0x06, "c"},
/* <D> */
{0x00, 0x07, "d"},
/* <E> */
{0x00, 0x08, "e"},
/* <F> */
{0x00, 0x09, "f"},
/* <G> */
{0x00, 0x0a, "g"},
/* <H> */
{0x00, 0x0b, "h"},
/* <I> */
{0x00, 0x0c, "i"},
/* <J> */
{0x00, 0x0d, "j"},
/* <K> */
{0x00, 0x0e, "k"},
/* <L> */
{0x00, 0x0f, "l"},
/* <M> */
{0x00, 0x10, "m"},
/* <N> */
{0x00, 0x11, "n"},
/* <O> */
{0x00, 0x12, "o"},
/* <P> */
{0x00, 0x13, "p"},
/* <Q> */
{0x00, 0x14, "q"},
/* <R> */
{0x00, 0x15, "r"},
/* <S> */
{0x00, 0x16, "s"},
/* <T> */
{0x00, 0x17, "t"},
/* <U> */
{0x00, 0x18, "u"},
/* <V> */
{0x00, 0x19, "v"},
/* <W> */
{0x00, 0x1a, "w"},
/* <X> */
{0x00, 0x1b, "x"},
/* <Y> */
{0x00, 0x1c, "y"},
/* <Z> */
{0x00, 0x1d, "z"},
/* <LEFT-SHIFT><A> */
{0x02, 0x04, "A"},
/* <RIGHT-SHIFT><Z> */
{0x20, 0x1d, "Z"},
/* <LEFT-CONTROL><A> */
{0x01, 0x04, "\x01"},
/* <RIGHT-CONTROL><Z> */
{0x10, 0x1d, "\x1a"},
/* <1> */
{0x00, 0x1e, "1"},
/* <2> */
{0x00, 0x1f, "2"},
/* <3> */
{0x00, 0x20, "3"},
/* <4> */
{0x00, 0x21, "4"},
/* <5> */
{0x00, 0x22, "5"},
/* <6> */
{0x00, 0x23, "6"},
/* <7> */
{0x00, 0x24, "7"},
/* <8> */
{0x00, 0x25, "8"},
/* <9> */
{0x00, 0x26, "9"},
/* <0> */
{0x00, 0x27, "0"},
/* <LEFT-SHIFT><1> */
{0x02, 0x1e, "!"},
/* <RIGHT-SHIFT><2> */
{0x20, 0x1f, "@"},
/* <LEFT-SHIFT><3> */
{0x02, 0x20, "#"},
/* <RIGHT-SHIFT><4> */
{0x20, 0x21, "$"},
/* <LEFT-SHIFT><5> */
{0x02, 0x22, "%"},
/* <RIGHT-SHIFT><6> */
{0x20, 0x23, "^"},
/* <LEFT-SHIFT><7> */
{0x02, 0x24, "&"},
/* <RIGHT-SHIFT><8> */
{0x20, 0x25, "*"},
/* <LEFT-SHIFT><9> */
{0x02, 0x26, "("},
/* <RIGHT-SHIFT><0> */
{0x20, 0x27, ")"},
/* <ENTER> */
{0x00, 0x28, "\r"},
/* <ESCAPE> */
{0x00, 0x29, "\x1b"},
/* <BACKSPACE> */
{0x00, 0x2a, "\x08"},
/* <TAB> */
{0x00, 0x2b, "\x09"},
/* <SPACE> */
{0x00, 0x2c, " "},
/* <MINUS> */
{0x00, 0x2d, "-"},
/* <EQUAL> */
{0x00, 0x2e, "="},
/* <LEFT BRACE> */
{0x00, 0x2f, "["},
/* <RIGHT BRACE> */
{0x00, 0x30, "]"},
/* <BACKSLASH> */
{0x00, 0x31, "\\"},
/* <HASH-TILDE> */
{0x00, 0x32, "#"},
/* <SEMICOLON> */
{0x00, 0x33, ";"},
/* <APOSTROPHE> */
{0x00, 0x34, "'"},
/* <GRAVE> */
{0x00, 0x35, "`"},
/* <COMMA> */
{0x00, 0x36, ","},
/* <DOT> */
{0x00, 0x37, "."},
/* <SLASH> */
{0x00, 0x38, "/"},
/* <LEFT-SHIFT><ENTER> */
{0x02, 0x28, "\r"},
/* <RIGHT-SHIFT><ESCAPE> */
{0x20, 0x29, "\x1b"},
/* <LEFT-SHIFT><BACKSPACE> */
{0x02, 0x2a, "\x08"},
/* <RIGHT-SHIFT><TAB> */
{0x20, 0x2b, "\x09"},
/* <LEFT-SHIFT><SPACE> */
{0x02, 0x2c, " "},
/* <MINUS> */
{0x20, 0x2d, "_"},
/* <LEFT-SHIFT><EQUAL> */
{0x02, 0x2e, "+"},
/* <RIGHT-SHIFT><LEFT BRACE> */
{0x20, 0x2f, "{"},
/* <LEFT-SHIFT><RIGHT BRACE> */
{0x02, 0x30, "}"},
/* <RIGHT-SHIFT><BACKSLASH> */
{0x20, 0x31, "|"},
/* <LEFT-SHIFT><HASH-TILDE> */
{0x02, 0x32, "~"},
/* <RIGHT-SHIFT><SEMICOLON> */
{0x20, 0x33, ":"},
/* <LEFT-SHIFT><APOSTROPHE> */
{0x02, 0x34, "\""},
/* <RIGHT-SHIFT><GRAVE> */
{0x20, 0x35, "~"},
/* <LEFT-SHIFT><COMMA> */
{0x02, 0x36, "<"},
/* <RIGHT-SHIFT><DOT> */
{0x20, 0x37, ">"},
/* <LEFT-SHIFT><SLASH> */
{0x02, 0x38, "?"},
#ifdef CONFIG_USB_KEYBOARD_FN_KEYS
/* <F1> */
{0x00, 0x3a, "\x1bOP"},
/* <F2> */
{0x00, 0x3b, "\x1bOQ"},
/* <F3> */
{0x00, 0x3c, "\x1bOR"},
/* <F4> */
{0x00, 0x3d, "\x1bOS"},
/* <F5> */
{0x00, 0x3e, "\x1b[15~"},
/* <F6> */
{0x00, 0x3f, "\x1b[17~"},
/* <F7> */
{0x00, 0x40, "\x1b[18~"},
/* <F8> */
{0x00, 0x41, "\x1b[19~"},
/* <F9> */
{0x00, 0x42, "\x1b[20~"},
/* <F10> */
{0x00, 0x43, "\x1b[21~"},
/* <F11> */
{0x00, 0x44, "\x1b[23~"},
/* <F12> */
{0x00, 0x45, "\x1b[24~"},
/* <INSERT> */
{0x00, 0x49, "\x1b[2~"},
/* <HOME> */
{0x00, 0x4a, "\x1b[H"},
/* <PAGE UP> */
{0x00, 0x4b, "\x1b[5~"},
/* <DELETE> */
{0x00, 0x4c, "\x1b[3~"},
/* <END> */
{0x00, 0x4d, "\x1b[F"},
/* <PAGE DOWN> */
{0x00, 0x4e, "\x1b[6~"},
/* <RIGHT> */
{0x00, 0x4f, "\x1b[C"},
/* <LEFT> */
{0x00, 0x50, "\x1b[D"},
/* <DOWN> */
{0x00, 0x51, "\x1b[B"},
/* <UP> */
{0x00, 0x52, "\x1b[A"},
#endif /* CONFIG_USB_KEYBOARD_FN_KEYS */
/* End of list */
{0x00, 0x00, "\0"}
};
state_set_skip_delays(true);
ut_assertok(usb_init());
/* Initially there should be no characters */
ut_asserteq(0, tstc());
ut_assertok(uclass_get_device_by_name(UCLASS_USB_EMUL, "keyb@3",
&dev));
/*
* Add scan codes to the USB keyboard buffer. They should appear as
* corresponding characters and escape sequences in stdin.
*/
for (pos = kbd_test_data; pos->scancode; ++pos) {
const char *c;
char scancodes[USB_KBD_BOOT_REPORT_SIZE] = {0};
scancodes[0] = pos->modifiers;
scancodes[2] = pos->scancode;
ut_assertok(sandbox_usb_keyb_add_string(dev, scancodes));
for (c = pos->result; *c; ++c) {
ut_asserteq(1, tstc());
ut_asserteq(*c, getchar());
}
ut_asserteq(0, tstc());
}
ut_assertok(usb_stop());
return 0;
}
DM_TEST(dm_test_usb_keyb, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);