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