uboot/test/dm/usb.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2015 Google, Inc
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6
   7#include <common.h>
   8#include <console.h>
   9#include <dm.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/ut.h>
  18
  19DECLARE_GLOBAL_DATA_PTR;
  20
  21/* Test that sandbox USB works correctly */
  22static int dm_test_usb_base(struct unit_test_state *uts)
  23{
  24        struct udevice *bus;
  25
  26        ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 0, &bus));
  27        ut_assertok(uclass_get_device(UCLASS_USB, 0, &bus));
  28        ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 2, &bus));
  29
  30        return 0;
  31}
  32DM_TEST(dm_test_usb_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
  33
  34/*
  35 * Test that we can use the flash stick. This is more of a functional test. It
  36 * covers scanning the bug, setting up a hub and a flash stick and reading
  37 * data from the flash stick.
  38 */
  39static int dm_test_usb_flash(struct unit_test_state *uts)
  40{
  41        struct udevice *dev;
  42        struct blk_desc *dev_desc;
  43        char cmp[1024];
  44
  45        state_set_skip_delays(true);
  46        ut_assertok(usb_init());
  47        ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
  48        ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc));
  49
  50        /* Read a few blocks and look for the string we expect */
  51        ut_asserteq(512, dev_desc->blksz);
  52        memset(cmp, '\0', sizeof(cmp));
  53        ut_asserteq(2, blk_dread(dev_desc, 0, 2, cmp));
  54        ut_assertok(strcmp(cmp, "this is a test"));
  55        ut_assertok(usb_stop());
  56
  57        return 0;
  58}
  59DM_TEST(dm_test_usb_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
  60
  61/* test that we can handle multiple storage devices */
  62static int dm_test_usb_multi(struct unit_test_state *uts)
  63{
  64        struct udevice *dev;
  65
  66        state_set_skip_delays(true);
  67        ut_assertok(usb_init());
  68        ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
  69        ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
  70        ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
  71        ut_assertok(usb_stop());
  72
  73        return 0;
  74}
  75DM_TEST(dm_test_usb_multi, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
  76
  77static int count_usb_devices(void)
  78{
  79        struct udevice *hub;
  80        struct uclass *uc;
  81        int count = 0;
  82        int ret;
  83
  84        ret = uclass_get(UCLASS_USB_HUB, &uc);
  85        if (ret)
  86                return ret;
  87
  88        uclass_foreach_dev(hub, uc) {
  89                struct udevice *dev;
  90
  91                count++;
  92                for (device_find_first_child(hub, &dev);
  93                     dev;
  94                     device_find_next_child(&dev)) {
  95                        count++;
  96                }
  97        }
  98
  99        return count;
 100}
 101
 102/* test that we can remove an emulated device and it is then not found */
 103static int dm_test_usb_remove(struct unit_test_state *uts)
 104{
 105        struct udevice *dev, *emul;
 106
 107        /* Scan and check that all devices are present */
 108        state_set_skip_delays(true);
 109        ut_assertok(usb_init());
 110        ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
 111        ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
 112        ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
 113        ut_asserteq(6, count_usb_devices());
 114        ut_assertok(usb_stop());
 115        ut_asserteq(6, count_usb_devices());
 116
 117        /* Remove the second emulation device */
 118        ut_assertok(uclass_find_device_by_name(UCLASS_USB_EMUL, "flash-stick@1",
 119                                               &dev));
 120        ut_assertok(device_unbind(dev));
 121
 122        /* Rescan - only the first and third should be present */
 123        ut_assertok(usb_init());
 124        ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
 125        ut_assertok(usb_emul_find_for_dev(dev, &emul));
 126        ut_asserteq_str("flash-stick@0", emul->name);
 127        ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
 128        ut_assertok(usb_emul_find_for_dev(dev, &emul));
 129        ut_asserteq_str("flash-stick@2", emul->name);
 130
 131        ut_asserteq(-ENODEV, uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
 132
 133        ut_asserteq(5, count_usb_devices());
 134        ut_assertok(usb_stop());
 135        ut_asserteq(5, count_usb_devices());
 136
 137        return 0;
 138}
 139DM_TEST(dm_test_usb_remove, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 140
 141const char usb_tree_base[] =
 142"  1  Hub (12 Mb/s, 100mA)\n"
 143"  |  sandbox hub 2345\n"
 144"  |\n"
 145"  |\b+-2  Mass Storage (12 Mb/s, 100mA)\n"
 146"  |    sandbox flash flash-stick@0\n"
 147"  |  \n"
 148"  |\b+-3  Mass Storage (12 Mb/s, 100mA)\n"
 149"  |    sandbox flash flash-stick@1\n"
 150"  |  \n"
 151"  |\b+-4  Mass Storage (12 Mb/s, 100mA)\n"
 152"  |    sandbox flash flash-stick@2\n"
 153"  |  \n"
 154"  |\b+-5  Human Interface (12 Mb/s, 100mA)\n"
 155"       sandbox keyboard keyb@3\n"
 156"     \n";
 157
 158/* test that the 'usb tree' command output looks correct */
 159static int dm_test_usb_tree(struct unit_test_state *uts)
 160{
 161        char *data;
 162        int len;
 163
 164        state_set_skip_delays(true);
 165        ut_assertok(usb_init());
 166        console_record_reset_enable();
 167        usb_show_tree();
 168        len = membuff_getraw(&gd->console_out, -1, true, &data);
 169        if (len)
 170                data[len] = '\0';
 171        ut_asserteq_str(usb_tree_base, data);
 172        ut_assertok(usb_stop());
 173
 174        return 0;
 175}
 176DM_TEST(dm_test_usb_tree, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 177
 178const char usb_tree_remove[] =
 179"  1  Hub (12 Mb/s, 100mA)\n"
 180"  |  sandbox hub 2345\n"
 181"  |\n"
 182"  |\b+-2  Mass Storage (12 Mb/s, 100mA)\n"
 183"  |    sandbox flash flash-stick@0\n"
 184"  |  \n"
 185"  |\b+-3  Mass Storage (12 Mb/s, 100mA)\n"
 186"  |    sandbox flash flash-stick@2\n"
 187"  |  \n"
 188"  |\b+-4  Human Interface (12 Mb/s, 100mA)\n"
 189"       sandbox keyboard keyb@3\n"
 190"     \n";
 191
 192/*
 193 * test that the 'usb tree' command output looks correct when we remove a
 194 * device
 195 */
 196static int dm_test_usb_tree_remove(struct unit_test_state *uts)
 197{
 198        struct udevice *dev;
 199        char *data;
 200        int len;
 201
 202        /* Remove the second emulation device */
 203        ut_assertok(uclass_find_device_by_name(UCLASS_USB_EMUL, "flash-stick@1",
 204                                               &dev));
 205        ut_assertok(device_unbind(dev));
 206
 207        state_set_skip_delays(true);
 208        ut_assertok(usb_init());
 209        console_record_reset_enable();
 210        usb_show_tree();
 211        len = membuff_getraw(&gd->console_out, -1, true, &data);
 212        if (len)
 213                data[len] = '\0';
 214        ut_asserteq_str(usb_tree_remove, data);
 215        ut_assertok(usb_stop());
 216
 217        return 0;
 218}
 219DM_TEST(dm_test_usb_tree_remove, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 220
 221const char usb_tree_reorder[] =
 222"  1  Hub (12 Mb/s, 100mA)\n"
 223"  |  sandbox hub 2345\n"
 224"  |\n"
 225"  |\b+-2  Mass Storage (12 Mb/s, 100mA)\n"
 226"  |    sandbox flash flash-stick@0\n"
 227"  |  \n"
 228"  |\b+-3  Mass Storage (12 Mb/s, 100mA)\n"
 229"  |    sandbox flash flash-stick@2\n"
 230"  |  \n"
 231"  |\b+-4  Human Interface (12 Mb/s, 100mA)\n"
 232"  |    sandbox keyboard keyb@3\n"
 233"  |  \n"
 234"  |\b+-5  Mass Storage (12 Mb/s, 100mA)\n"
 235"       sandbox flash flash-stick@1\n"
 236"     \n";
 237
 238/*
 239 * test that the 'usb tree' command output looks correct when we reorder two
 240 * devices.
 241 */
 242static int dm_test_usb_tree_reorder(struct unit_test_state *uts)
 243{
 244        struct udevice *dev, *parent;
 245        char *data;
 246        int len;
 247
 248        /* Remove the second emulation device */
 249        ut_assertok(uclass_find_device_by_name(UCLASS_USB_EMUL, "flash-stick@1",
 250                                               &dev));
 251        parent = dev->parent;
 252
 253        /* Reorder the devices in the parent list and uclass list */
 254        list_del(&dev->sibling_node);
 255        list_add_tail(&dev->sibling_node, &parent->child_head);
 256
 257        list_del(&dev->uclass_node);
 258        list_add_tail(&dev->uclass_node, &dev->uclass->dev_head);
 259
 260        state_set_skip_delays(true);
 261        ut_assertok(usb_init());
 262        console_record_reset_enable();
 263        usb_show_tree();
 264        len = membuff_getraw(&gd->console_out, -1, true, &data);
 265        if (len)
 266                data[len] = '\0';
 267        ut_asserteq_str(usb_tree_reorder, data);
 268        ut_assertok(usb_stop());
 269
 270        return 0;
 271}
 272DM_TEST(dm_test_usb_tree_reorder, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 273
 274static int dm_test_usb_keyb(struct unit_test_state *uts)
 275{
 276        struct udevice *dev;
 277
 278        state_set_skip_delays(true);
 279        ut_assertok(usb_init());
 280
 281        /* Initially there should be no characters */
 282        ut_asserteq(0, tstc());
 283
 284        ut_assertok(uclass_get_device_by_name(UCLASS_USB_EMUL, "keyb",
 285                                              &dev));
 286
 287        /*
 288         * Add a string to the USB keyboard buffer - it should appear in
 289         * stdin
 290         */
 291        ut_assertok(sandbox_usb_keyb_add_string(dev, "ab"));
 292        ut_asserteq(1, tstc());
 293        ut_asserteq('a', getc());
 294        ut_asserteq(1, tstc());
 295        ut_asserteq('b', getc());
 296        ut_asserteq(0, tstc());
 297
 298        ut_assertok(usb_stop());
 299
 300        return 0;
 301}
 302DM_TEST(dm_test_usb_keyb, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 303