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