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