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