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