Prepare v2023.10
[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_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
82         ut_assertok(usb_stop());
83
84         return 0;
85 }
86 DM_TEST(dm_test_usb_flash, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
87
88 /* test that we can handle multiple storage devices */
89 static 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));
98         ut_assertok(usb_stop());
99
100         return 0;
101 }
102 DM_TEST(dm_test_usb_multi, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
103
104 /* test that we have an associated ofnode with the usb device */
105 static 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 }
124 DM_TEST(dm_test_usb_fdt_node, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
125
126 static 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
151 /* test that no USB devices are found after we stop the stack */
152 static int dm_test_usb_stop(struct unit_test_state *uts)
153 {
154         struct udevice *dev;
155
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));
162         ut_asserteq(6, count_usb_devices());
163         ut_assertok(usb_stop());
164         ut_asserteq(0, count_usb_devices());
165
166         return 0;
167 }
168 DM_TEST(dm_test_usb_stop, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
169
170 /**
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  */
197 static int dm_test_usb_keyb(struct unit_test_state *uts)
198 {
199         struct udevice *dev;
200         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
427
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
434         ut_assertok(uclass_get_device_by_name(UCLASS_USB_EMUL, "keyb@3",
435                                               &dev));
436
437         /*
438          * Add scan codes to the USB keyboard buffer. They should appear as
439          * corresponding characters and escape sequences in stdin.
440          */
441         for (pos = kbd_test_data; pos->scancode; ++pos) {
442                 const char *c;
443                 char scancodes[USB_KBD_BOOT_REPORT_SIZE] = {0};
444
445                 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());
452                         ut_asserteq(*c, getchar());
453                 }
454                 ut_asserteq(0, tstc());
455         }
456         ut_assertok(usb_stop());
457
458         return 0;
459 }
460 DM_TEST(dm_test_usb_keyb, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);