usb.c 9.2 KB

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