blob: 7671ef156d8476d35b51cec387e7d6b1a9af1965 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glass31680482015-03-25 12:23:05 -06002/*
3 * Copyright (C) 2015 Google, Inc
Simon Glass31680482015-03-25 12:23:05 -06004 */
5
6#include <common.h>
Simon Glassa73bda42015-11-08 23:47:45 -07007#include <console.h>
Simon Glass31680482015-03-25 12:23:05 -06008#include <dm.h>
Simon Glass655306c2020-05-10 11:39:58 -06009#include <part.h>
Simon Glass31680482015-03-25 12:23:05 -060010#include <usb.h>
11#include <asm/io.h>
Simon Glass2d7c4992015-11-08 23:47:44 -070012#include <asm/state.h>
Simon Glassc0ccc722015-11-08 23:48:08 -070013#include <asm/test.h>
Simon Glass2d7c4992015-11-08 23:47:44 -070014#include <dm/device-internal.h>
Simon Glass31680482015-03-25 12:23:05 -060015#include <dm/test.h>
Simon Glass4700fe52015-11-08 23:48:01 -070016#include <dm/uclass-internal.h>
Simon Glass75c4d412020-07-19 10:15:37 -060017#include <test/test.h>
Joe Hershberger3a77be52015-05-20 14:27:27 -050018#include <test/ut.h>
Simon Glass31680482015-03-25 12:23:05 -060019
Heinrich Schuchardt513255b2019-11-23 18:15:23 +010020struct keyboard_test_data {
21 const char modifiers;
22 const char scancode;
23 const char result[6];
24};
25
Simon Glass31680482015-03-25 12:23:05 -060026/* Test that sandbox USB works correctly */
Joe Hershberger3a77be52015-05-20 14:27:27 -050027static int dm_test_usb_base(struct unit_test_state *uts)
Simon Glass31680482015-03-25 12:23:05 -060028{
29 struct udevice *bus;
30
31 ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 0, &bus));
32 ut_assertok(uclass_get_device(UCLASS_USB, 0, &bus));
33 ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 2, &bus));
34
35 return 0;
36}
Simon Glass974dccd2020-07-28 19:41:12 -060037DM_TEST(dm_test_usb_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass31680482015-03-25 12:23:05 -060038
39/*
40 * Test that we can use the flash stick. This is more of a functional test. It
41 * covers scanning the bug, setting up a hub and a flash stick and reading
42 * data from the flash stick.
43 */
Joe Hershberger3a77be52015-05-20 14:27:27 -050044static int dm_test_usb_flash(struct unit_test_state *uts)
Simon Glass31680482015-03-25 12:23:05 -060045{
Simon Glass18861002022-10-20 18:22:54 -060046 struct blk_desc *dev_desc, *chk;
47 struct udevice *dev, *blk;
Simon Glass31680482015-03-25 12:23:05 -060048 char cmp[1024];
49
Simon Glass2d7c4992015-11-08 23:47:44 -070050 state_set_skip_delays(true);
Simon Glass31680482015-03-25 12:23:05 -060051 ut_assertok(usb_init());
52 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
Simon Glasse6649a62016-02-29 15:25:43 -070053 ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc));
Simon Glass18861002022-10-20 18:22:54 -060054 chk = blk_get_by_device(dev);
55 ut_asserteq_ptr(chk, dev_desc);
56
57 ut_assertok(device_find_first_child_by_uclass(dev, UCLASS_BLK, &blk));
58 ut_asserteq_ptr(chk, blk_get_by_device(dev));
Simon Glass31680482015-03-25 12:23:05 -060059
60 /* Read a few blocks and look for the string we expect */
61 ut_asserteq(512, dev_desc->blksz);
62 memset(cmp, '\0', sizeof(cmp));
Simon Glass18861002022-10-20 18:22:54 -060063 ut_asserteq(2, blk_read(blk, 0, 2, cmp));
Simon Glass31b4f9e2022-10-20 18:22:55 -060064 ut_asserteq_str("this is a test", cmp);
65
66 strcpy(cmp, "another test");
67 ut_asserteq(1, blk_write(blk, 1, 1, cmp));
68
69 memset(cmp, '\0', sizeof(cmp));
70 ut_asserteq(2, blk_read(blk, 0, 2, cmp));
71 ut_asserteq_str("this is a test", cmp);
72 ut_asserteq_str("another test", cmp + 512);
73
74 memset(cmp, '\0', sizeof(cmp));
75 ut_asserteq(1, blk_write(blk, 1, 1, cmp));
76
77 memset(cmp, '\0', sizeof(cmp));
78 ut_asserteq(2, blk_read(blk, 0, 2, cmp));
79 ut_asserteq_str("this is a test", cmp);
80 ut_asserteq_str("", cmp + 512);
81
Simon Glass582b76e2016-02-29 15:26:02 -070082 ut_assertok(usb_stop());
Simon Glass31680482015-03-25 12:23:05 -060083
84 return 0;
85}
Simon Glass974dccd2020-07-28 19:41:12 -060086DM_TEST(dm_test_usb_flash, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass4700fe52015-11-08 23:48:01 -070087
88/* test that we can handle multiple storage devices */
89static int dm_test_usb_multi(struct unit_test_state *uts)
90{
91 struct udevice *dev;
92
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));
Simon Glass582b76e2016-02-29 15:26:02 -070098 ut_assertok(usb_stop());
Simon Glass4700fe52015-11-08 23:48:01 -070099
100 return 0;
101}
Simon Glass974dccd2020-07-28 19:41:12 -0600102DM_TEST(dm_test_usb_multi, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glass4700fe52015-11-08 23:48:01 -0700103
Michael Walle7c961322020-06-02 01:47:07 +0200104/* test that we have an associated ofnode with the usb device */
105static int dm_test_usb_fdt_node(struct unit_test_state *uts)
106{
107 struct udevice *dev;
108 ofnode node;
109
110 state_set_skip_delays(true);
111 ut_assertok(usb_init());
112 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
113 node = ofnode_path("/usb@1/hub/usbstor@1");
114 ut_asserteq(1, ofnode_equal(node, dev_ofnode(dev)));
115 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
116 ut_asserteq(1, ofnode_equal(ofnode_null(), dev_ofnode(dev)));
117 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
118 node = ofnode_path("/usb@1/hub/usbstor@3");
119 ut_asserteq(1, ofnode_equal(node, dev_ofnode(dev)));
120 ut_assertok(usb_stop());
121
122 return 0;
123}
Simon Glass974dccd2020-07-28 19:41:12 -0600124DM_TEST(dm_test_usb_fdt_node, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Michael Walle7c961322020-06-02 01:47:07 +0200125
Simon Glass4700fe52015-11-08 23:48:01 -0700126static int count_usb_devices(void)
127{
128 struct udevice *hub;
129 struct uclass *uc;
130 int count = 0;
131 int ret;
132
133 ret = uclass_get(UCLASS_USB_HUB, &uc);
134 if (ret)
135 return ret;
136
137 uclass_foreach_dev(hub, uc) {
138 struct udevice *dev;
139
140 count++;
141 for (device_find_first_child(hub, &dev);
142 dev;
143 device_find_next_child(&dev)) {
144 count++;
145 }
146 }
147
148 return count;
149}
150
Bin Mengb6189f22017-10-01 06:19:45 -0700151/* test that no USB devices are found after we stop the stack */
152static int dm_test_usb_stop(struct unit_test_state *uts)
Simon Glass4700fe52015-11-08 23:48:01 -0700153{
Bin Mengb6189f22017-10-01 06:19:45 -0700154 struct udevice *dev;
Simon Glass4700fe52015-11-08 23:48:01 -0700155
156 /* Scan and check that all devices are present */
157 state_set_skip_delays(true);
158 ut_assertok(usb_init());
159 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
160 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev));
161 ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev));
Simon Glassf0bfd6d2016-01-07 10:23:42 -0700162 ut_asserteq(6, count_usb_devices());
Simon Glass846bb372015-11-08 23:48:02 -0700163 ut_assertok(usb_stop());
Bin Mengb6189f22017-10-01 06:19:45 -0700164 ut_asserteq(0, count_usb_devices());
Simon Glass846bb372015-11-08 23:48:02 -0700165
166 return 0;
167}
Simon Glass974dccd2020-07-28 19:41:12 -0600168DM_TEST(dm_test_usb_stop, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
Simon Glassc0ccc722015-11-08 23:48:08 -0700169
Heinrich Schuchardt513255b2019-11-23 18:15:23 +0100170/**
171 * dm_test_usb_keyb() - test USB keyboard driver
172 *
173 * This test copies USB keyboard scan codes into the key buffer of the USB
174 * keyboard emulation driver. These are picked up during emulated interrupts
175 * by the USB keyboard driver and converted to characters and escape sequences.
176 * The test then reads and verifies these characters and escape sequences from
177 * the standard input.
178 *
179 * TODO: The following features are not yet tested:
180 *
181 * * LED status
182 * * caps-lock
183 * * num-lock
184 * * numerical pad keys
185 *
186 * TODO: The following features are not yet implemented by the USB keyboard
187 * driver and therefore not tested:
188 *
189 * * modifiers for non-alpha-numeric keys, e.g. <SHIFT><TAB> and <ALT><F4>
190 * * some special keys, e.g. <PRINT>
191 * * some modifiers, e.g. <ALT> and <META>
192 * * alternative keyboard layouts
193 *
194 * @uts: unit test state
195 * Return: 0 on success
196 */
Simon Glassc0ccc722015-11-08 23:48:08 -0700197static int dm_test_usb_keyb(struct unit_test_state *uts)
198{
199 struct udevice *dev;
Heinrich Schuchardt513255b2019-11-23 18:15:23 +0100200 const struct keyboard_test_data *pos;
201 const struct keyboard_test_data kbd_test_data[] = {
202 /* <A> */
203 {0x00, 0x04, "a"},
204 /* <B> */
205 {0x00, 0x05, "b"},
206 /* <C> */
207 {0x00, 0x06, "c"},
208 /* <D> */
209 {0x00, 0x07, "d"},
210 /* <E> */
211 {0x00, 0x08, "e"},
212 /* <F> */
213 {0x00, 0x09, "f"},
214 /* <G> */
215 {0x00, 0x0a, "g"},
216 /* <H> */
217 {0x00, 0x0b, "h"},
218 /* <I> */
219 {0x00, 0x0c, "i"},
220 /* <J> */
221 {0x00, 0x0d, "j"},
222 /* <K> */
223 {0x00, 0x0e, "k"},
224 /* <L> */
225 {0x00, 0x0f, "l"},
226 /* <M> */
227 {0x00, 0x10, "m"},
228 /* <N> */
229 {0x00, 0x11, "n"},
230 /* <O> */
231 {0x00, 0x12, "o"},
232 /* <P> */
233 {0x00, 0x13, "p"},
234 /* <Q> */
235 {0x00, 0x14, "q"},
236 /* <R> */
237 {0x00, 0x15, "r"},
238 /* <S> */
239 {0x00, 0x16, "s"},
240 /* <T> */
241 {0x00, 0x17, "t"},
242 /* <U> */
243 {0x00, 0x18, "u"},
244 /* <V> */
245 {0x00, 0x19, "v"},
246 /* <W> */
247 {0x00, 0x1a, "w"},
248 /* <X> */
249 {0x00, 0x1b, "x"},
250 /* <Y> */
251 {0x00, 0x1c, "y"},
252 /* <Z> */
253 {0x00, 0x1d, "z"},
254
255 /* <LEFT-SHIFT><A> */
256 {0x02, 0x04, "A"},
257 /* <RIGHT-SHIFT><Z> */
258 {0x20, 0x1d, "Z"},
259
260 /* <LEFT-CONTROL><A> */
261 {0x01, 0x04, "\x01"},
262 /* <RIGHT-CONTROL><Z> */
263 {0x10, 0x1d, "\x1a"},
264
265 /* <1> */
266 {0x00, 0x1e, "1"},
267 /* <2> */
268 {0x00, 0x1f, "2"},
269 /* <3> */
270 {0x00, 0x20, "3"},
271 /* <4> */
272 {0x00, 0x21, "4"},
273 /* <5> */
274 {0x00, 0x22, "5"},
275 /* <6> */
276 {0x00, 0x23, "6"},
277 /* <7> */
278 {0x00, 0x24, "7"},
279 /* <8> */
280 {0x00, 0x25, "8"},
281 /* <9> */
282 {0x00, 0x26, "9"},
283 /* <0> */
284 {0x00, 0x27, "0"},
285
286 /* <LEFT-SHIFT><1> */
287 {0x02, 0x1e, "!"},
288 /* <RIGHT-SHIFT><2> */
289 {0x20, 0x1f, "@"},
290 /* <LEFT-SHIFT><3> */
291 {0x02, 0x20, "#"},
292 /* <RIGHT-SHIFT><4> */
293 {0x20, 0x21, "$"},
294 /* <LEFT-SHIFT><5> */
295 {0x02, 0x22, "%"},
296 /* <RIGHT-SHIFT><6> */
297 {0x20, 0x23, "^"},
298 /* <LEFT-SHIFT><7> */
299 {0x02, 0x24, "&"},
300 /* <RIGHT-SHIFT><8> */
301 {0x20, 0x25, "*"},
302 /* <LEFT-SHIFT><9> */
303 {0x02, 0x26, "("},
304 /* <RIGHT-SHIFT><0> */
305 {0x20, 0x27, ")"},
306
307 /* <ENTER> */
308 {0x00, 0x28, "\r"},
309 /* <ESCAPE> */
310 {0x00, 0x29, "\x1b"},
311 /* <BACKSPACE> */
312 {0x00, 0x2a, "\x08"},
313 /* <TAB> */
314 {0x00, 0x2b, "\x09"},
315 /* <SPACE> */
316 {0x00, 0x2c, " "},
317 /* <MINUS> */
318 {0x00, 0x2d, "-"},
319 /* <EQUAL> */
320 {0x00, 0x2e, "="},
321 /* <LEFT BRACE> */
322 {0x00, 0x2f, "["},
323 /* <RIGHT BRACE> */
324 {0x00, 0x30, "]"},
325 /* <BACKSLASH> */
326 {0x00, 0x31, "\\"},
327 /* <HASH-TILDE> */
328 {0x00, 0x32, "#"},
329 /* <SEMICOLON> */
330 {0x00, 0x33, ";"},
331 /* <APOSTROPHE> */
332 {0x00, 0x34, "'"},
333 /* <GRAVE> */
334 {0x00, 0x35, "`"},
335 /* <COMMA> */
336 {0x00, 0x36, ","},
337 /* <DOT> */
338 {0x00, 0x37, "."},
339 /* <SLASH> */
340 {0x00, 0x38, "/"},
341
342 /* <LEFT-SHIFT><ENTER> */
343 {0x02, 0x28, "\r"},
344 /* <RIGHT-SHIFT><ESCAPE> */
345 {0x20, 0x29, "\x1b"},
346 /* <LEFT-SHIFT><BACKSPACE> */
347 {0x02, 0x2a, "\x08"},
348 /* <RIGHT-SHIFT><TAB> */
349 {0x20, 0x2b, "\x09"},
350 /* <LEFT-SHIFT><SPACE> */
351 {0x02, 0x2c, " "},
352 /* <MINUS> */
353 {0x20, 0x2d, "_"},
354 /* <LEFT-SHIFT><EQUAL> */
355 {0x02, 0x2e, "+"},
356 /* <RIGHT-SHIFT><LEFT BRACE> */
357 {0x20, 0x2f, "{"},
358 /* <LEFT-SHIFT><RIGHT BRACE> */
359 {0x02, 0x30, "}"},
360 /* <RIGHT-SHIFT><BACKSLASH> */
361 {0x20, 0x31, "|"},
362 /* <LEFT-SHIFT><HASH-TILDE> */
363 {0x02, 0x32, "~"},
364 /* <RIGHT-SHIFT><SEMICOLON> */
365 {0x20, 0x33, ":"},
366 /* <LEFT-SHIFT><APOSTROPHE> */
367 {0x02, 0x34, "\""},
368 /* <RIGHT-SHIFT><GRAVE> */
369 {0x20, 0x35, "~"},
370 /* <LEFT-SHIFT><COMMA> */
371 {0x02, 0x36, "<"},
372 /* <RIGHT-SHIFT><DOT> */
373 {0x20, 0x37, ">"},
374 /* <LEFT-SHIFT><SLASH> */
375 {0x02, 0x38, "?"},
376#ifdef CONFIG_USB_KEYBOARD_FN_KEYS
377 /* <F1> */
378 {0x00, 0x3a, "\x1bOP"},
379 /* <F2> */
380 {0x00, 0x3b, "\x1bOQ"},
381 /* <F3> */
382 {0x00, 0x3c, "\x1bOR"},
383 /* <F4> */
384 {0x00, 0x3d, "\x1bOS"},
385 /* <F5> */
386 {0x00, 0x3e, "\x1b[15~"},
387 /* <F6> */
388 {0x00, 0x3f, "\x1b[17~"},
389 /* <F7> */
390 {0x00, 0x40, "\x1b[18~"},
391 /* <F8> */
392 {0x00, 0x41, "\x1b[19~"},
393 /* <F9> */
394 {0x00, 0x42, "\x1b[20~"},
395 /* <F10> */
396 {0x00, 0x43, "\x1b[21~"},
397 /* <F11> */
398 {0x00, 0x44, "\x1b[23~"},
399 /* <F12> */
400 {0x00, 0x45, "\x1b[24~"},
401 /* <INSERT> */
402 {0x00, 0x49, "\x1b[2~"},
403 /* <HOME> */
404 {0x00, 0x4a, "\x1b[H"},
405 /* <PAGE UP> */
406 {0x00, 0x4b, "\x1b[5~"},
407 /* <DELETE> */
408 {0x00, 0x4c, "\x1b[3~"},
409 /* <END> */
410 {0x00, 0x4d, "\x1b[F"},
411 /* <PAGE DOWN> */
412 {0x00, 0x4e, "\x1b[6~"},
413 /* <RIGHT> */
414 {0x00, 0x4f, "\x1b[C"},
415 /* <LEFT> */
416 {0x00, 0x50, "\x1b[D"},
417 /* <DOWN> */
418 {0x00, 0x51, "\x1b[B"},
419 /* <UP> */
420 {0x00, 0x52, "\x1b[A"},
421#endif /* CONFIG_USB_KEYBOARD_FN_KEYS */
422
423 /* End of list */
424 {0x00, 0x00, "\0"}
425 };
426
Simon Glassc0ccc722015-11-08 23:48:08 -0700427
428 state_set_skip_delays(true);
429 ut_assertok(usb_init());
430
431 /* Initially there should be no characters */
432 ut_asserteq(0, tstc());
433
Peng Fane7028102019-05-22 07:08:12 +0000434 ut_assertok(uclass_get_device_by_name(UCLASS_USB_EMUL, "keyb@3",
Simon Glassc0ccc722015-11-08 23:48:08 -0700435 &dev));
436
437 /*
Heinrich Schuchardt513255b2019-11-23 18:15:23 +0100438 * Add scan codes to the USB keyboard buffer. They should appear as
439 * corresponding characters and escape sequences in stdin.
Simon Glassc0ccc722015-11-08 23:48:08 -0700440 */
Heinrich Schuchardt513255b2019-11-23 18:15:23 +0100441 for (pos = kbd_test_data; pos->scancode; ++pos) {
442 const char *c;
443 char scancodes[USB_KBD_BOOT_REPORT_SIZE] = {0};
Simon Glassc0ccc722015-11-08 23:48:08 -0700444
Heinrich Schuchardt513255b2019-11-23 18:15:23 +0100445 scancodes[0] = pos->modifiers;
446 scancodes[2] = pos->scancode;
447
448 ut_assertok(sandbox_usb_keyb_add_string(dev, scancodes));
449
450 for (c = pos->result; *c; ++c) {
451 ut_asserteq(1, tstc());
Heinrich Schuchardtc4954fb2020-10-07 18:11:48 +0200452 ut_asserteq(*c, getchar());
Heinrich Schuchardt513255b2019-11-23 18:15:23 +0100453 }
454 ut_asserteq(0, tstc());
455 }
Simon Glassc0ccc722015-11-08 23:48:08 -0700456 ut_assertok(usb_stop());
457
458 return 0;
459}
Simon Glass974dccd2020-07-28 19:41:12 -0600460DM_TEST(dm_test_usb_keyb, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);