Merge branch 'master' of git://git.denx.de/u-boot-mips
[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 <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
18 struct keyboard_test_data {
19         const char modifiers;
20         const char scancode;
21         const char result[6];
22 };
23
24 /* Test that sandbox USB works correctly */
25 static int dm_test_usb_base(struct unit_test_state *uts)
26 {
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 }
35 DM_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  */
42 static int dm_test_usb_flash(struct unit_test_state *uts)
43 {
44         struct udevice *dev;
45         struct blk_desc *dev_desc;
46         char cmp[1024];
47
48         state_set_skip_delays(true);
49         ut_assertok(usb_init());
50         ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
51         ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc));
52
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));
56         ut_asserteq(2, blk_dread(dev_desc, 0, 2, cmp));
57         ut_assertok(strcmp(cmp, "this is a test"));
58         ut_assertok(usb_stop());
59
60         return 0;
61 }
62 DM_TEST(dm_test_usb_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
63
64 /* test that we can handle multiple storage devices */
65 static 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));
74         ut_assertok(usb_stop());
75
76         return 0;
77 }
78 DM_TEST(dm_test_usb_multi, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
79
80 static 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
105 /* test that no USB devices are found after we stop the stack */
106 static int dm_test_usb_stop(struct unit_test_state *uts)
107 {
108         struct udevice *dev;
109
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));
116         ut_asserteq(6, count_usb_devices());
117         ut_assertok(usb_stop());
118         ut_asserteq(0, count_usb_devices());
119
120         return 0;
121 }
122 DM_TEST(dm_test_usb_stop, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
123
124 /**
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  */
151 static int dm_test_usb_keyb(struct unit_test_state *uts)
152 {
153         struct udevice *dev;
154         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
381
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
388         ut_assertok(uclass_get_device_by_name(UCLASS_USB_EMUL, "keyb@3",
389                                               &dev));
390
391         /*
392          * Add scan codes to the USB keyboard buffer. They should appear as
393          * corresponding characters and escape sequences in stdin.
394          */
395         for (pos = kbd_test_data; pos->scancode; ++pos) {
396                 const char *c;
397                 char scancodes[USB_KBD_BOOT_REPORT_SIZE] = {0};
398
399                 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         }
410         ut_assertok(usb_stop());
411
412         return 0;
413 }
414 DM_TEST(dm_test_usb_keyb, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);