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