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