• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
dm_test_usb_base(struct unit_test_state * uts)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  */
dm_test_usb_flash(struct unit_test_state * uts)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 */
dm_test_usb_multi(struct unit_test_state * uts)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 
count_usb_devices(void)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 */
dm_test_usb_stop(struct unit_test_state * uts)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  */
dm_test_usb_keyb(struct unit_test_state * uts)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);
415