[usb] Select preferred USB device configuration based on driver score
[ipxe.git] / src / drivers / usb / usbkbd.c
1 /*
2 * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <assert.h>
30 #include <ipxe/console.h>
31 #include <ipxe/keys.h>
32 #include <ipxe/usb.h>
33 #include "usbkbd.h"
34
35 /** @file
36 *
37 * USB keyboard driver
38 *
39 */
40
41 /** List of USB keyboards */
42 static LIST_HEAD ( usb_keyboards );
43
44 /******************************************************************************
45 *
46 * Keyboard map
47 *
48 ******************************************************************************
49 */
50
51 /**
52 * Map USB keycode to iPXE key
53 *
54 * @v keycode Keycode
55 * @v modifiers Modifiers
56 * @ret key iPXE key
57 *
58 * Key codes are defined in the USB HID Usage Tables Keyboard/Keypad
59 * page.
60 */
61 static unsigned int usbkbd_map ( unsigned int keycode,
62 unsigned int modifiers ) {
63 unsigned int key;
64
65 if ( keycode < USBKBD_KEY_A ) {
66 /* Not keys */
67 key = 0;
68 } else if ( keycode <= USBKBD_KEY_Z ) {
69 /* Alphabetic keys */
70 key = ( keycode - USBKBD_KEY_A + 'a' );
71 if ( modifiers & USBKBD_CTRL ) {
72 key -= ( 'a' - CTRL_A );
73 } else if ( modifiers & USBKBD_SHIFT ) {
74 key -= ( 'a' - 'A' );
75 }
76 } else if ( keycode <= USBKBD_KEY_0 ) {
77 /* Numeric key row */
78 if ( modifiers & USBKBD_SHIFT ) {
79 key = "!@#$%^&*()" [ keycode - USBKBD_KEY_1 ];
80 } else {
81 key = ( ( ( keycode - USBKBD_KEY_1 + 1 ) % 10 ) + '0' );
82 }
83 } else if ( keycode <= USBKBD_KEY_SPACE ) {
84 /* Unmodifiable keys */
85 static const uint8_t unmodifable[] =
86 { LF, ESC, BACKSPACE, TAB, ' ' };
87 key = unmodifable[ keycode - USBKBD_KEY_ENTER ];
88 } else if ( keycode <= USBKBD_KEY_SLASH ) {
89 /* Punctuation keys */
90 if ( modifiers & USBKBD_SHIFT ) {
91 key = "_+{}|~:\"~<>?" [ keycode - USBKBD_KEY_MINUS ];
92 } else {
93 key = "-=[]\\#;'`,./" [ keycode - USBKBD_KEY_MINUS ];
94 }
95 } else if ( keycode <= USBKBD_KEY_UP ) {
96 /* Special keys */
97 static const uint16_t special[] = {
98 0, 0, 0, 0, 0, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9,
99 KEY_F10, KEY_F11, KEY_F12, 0, 0, 0, KEY_IC, KEY_HOME,
100 KEY_PPAGE, KEY_DC, KEY_END, KEY_NPAGE, KEY_RIGHT,
101 KEY_LEFT, KEY_DOWN, KEY_UP
102 };
103 key = special[ keycode - USBKBD_KEY_CAPSLOCK ];
104 } else {
105 key = 0;
106 }
107
108 return key;
109 }
110
111 /******************************************************************************
112 *
113 * Keyboard buffer
114 *
115 ******************************************************************************
116 */
117
118 /**
119 * Insert keypress into keyboard buffer
120 *
121 * @v kbd USB keyboard
122 * @v keycode Keycode
123 * @v modifiers Modifiers
124 */
125 static void usbkbd_produce ( struct usb_keyboard *kbd, unsigned int keycode,
126 unsigned int modifiers ) {
127 unsigned int key;
128
129 /* Map to iPXE key */
130 key = usbkbd_map ( keycode, modifiers );
131
132 /* Do nothing if this keycode has no corresponding iPXE key */
133 if ( ! key ) {
134 DBGC ( kbd, "KBD %s has no key for keycode %#02x:%#02x\n",
135 kbd->name, modifiers, keycode );
136 return;
137 }
138
139 /* Check for buffer overrun */
140 if ( usbkbd_fill ( kbd ) >= USBKBD_BUFSIZE ) {
141 DBGC ( kbd, "KBD %s buffer overrun (key %#02x)\n",
142 kbd->name, key );
143 return;
144 }
145
146 /* Insert into buffer */
147 kbd->key[ ( kbd->prod++ ) % USBKBD_BUFSIZE ] = key;
148 DBGC2 ( kbd, "KBD %s key %#02x produced\n", kbd->name, key );
149 }
150
151 /**
152 * Consume character from keyboard buffer
153 *
154 * @v kbd USB keyboard
155 * @ret character Character
156 */
157 static unsigned int usbkbd_consume ( struct usb_keyboard *kbd ) {
158 static char buf[] = "\x1b[xx~";
159 char *tmp = &buf[2];
160 unsigned int key;
161 unsigned int character;
162 unsigned int ansi_n;
163 unsigned int len;
164
165 /* Sanity check */
166 assert ( usbkbd_fill ( kbd ) > 0 );
167
168 /* Get current keypress */
169 key = kbd->key[ kbd->cons % USBKBD_BUFSIZE ];
170
171 /* If this is a straightforward key, just consume and return it */
172 if ( key < KEY_MIN ) {
173 kbd->cons++;
174 DBGC2 ( kbd, "KBD %s key %#02x consumed\n", kbd->name, key );
175 return key;
176 }
177
178 /* Construct ANSI sequence */
179 ansi_n = KEY_ANSI_N ( key );
180 if ( ansi_n )
181 tmp += sprintf ( tmp, "%d", ansi_n );
182 *(tmp++) = KEY_ANSI_TERMINATOR ( key );
183 *tmp = '\0';
184 len = ( tmp - buf );
185 assert ( len < sizeof ( buf ) );
186 if ( kbd->subcons == 0 ) {
187 DBGC2 ( kbd, "KBD %s key %#02x consumed as ^[%s\n",
188 kbd->name, key, &buf[1] );
189 }
190
191 /* Extract character from ANSI sequence */
192 assert ( kbd->subcons < len );
193 character = buf[ kbd->subcons++ ];
194
195 /* Consume key if applicable */
196 if ( kbd->subcons == len ) {
197 kbd->cons++;
198 kbd->subcons = 0;
199 }
200
201 return character;
202 }
203
204 /******************************************************************************
205 *
206 * Keyboard report
207 *
208 ******************************************************************************
209 */
210
211 /**
212 * Check for presence of keycode in report
213 *
214 * @v report Keyboard report
215 * @v keycode Keycode (must be non-zero)
216 * @ret has_keycode Keycode is present in report
217 */
218 static int usbkbd_has_keycode ( struct usb_keyboard_report *report,
219 unsigned int keycode ) {
220 unsigned int i;
221
222 /* Check for keycode */
223 for ( i = 0 ; i < ( sizeof ( report->keycode ) /
224 sizeof ( report->keycode[0] ) ) ; i++ ) {
225 if ( report->keycode[i] == keycode )
226 return keycode;
227 }
228
229 return 0;
230 }
231
232 /**
233 * Handle keyboard report
234 *
235 * @v kbd USB keyboard
236 * @v new New keyboard report
237 */
238 static void usbkbd_report ( struct usb_keyboard *kbd,
239 struct usb_keyboard_report *new ) {
240 struct usb_keyboard_report *old = &kbd->report;
241 unsigned int keycode;
242 unsigned int i;
243
244 /* Check if current key has been released */
245 if ( kbd->keycode && ! usbkbd_has_keycode ( new, kbd->keycode ) ) {
246 DBGC2 ( kbd, "KBD %s keycode %#02x released\n",
247 kbd->name, kbd->keycode );
248 kbd->keycode = 0;
249 }
250
251 /* Decrement auto-repeat hold-off timer, if applicable */
252 if ( kbd->holdoff )
253 kbd->holdoff--;
254
255 /* Check if a new key has been pressed */
256 for ( i = 0 ; i < ( sizeof ( new->keycode ) /
257 sizeof ( new->keycode[0] ) ) ; i++ ) {
258
259 /* Ignore keys present in the previous report */
260 keycode = new->keycode[i];
261 if ( ( keycode == 0 ) || usbkbd_has_keycode ( old, keycode ) )
262 continue;
263 DBGC2 ( kbd, "KBD %s keycode %#02x pressed\n",
264 kbd->name, keycode );
265
266 /* Insert keypress into keyboard buffer */
267 usbkbd_produce ( kbd, keycode, new->modifiers );
268
269 /* Record as most recent keycode */
270 kbd->keycode = keycode;
271
272 /* Start auto-repeat hold-off timer */
273 kbd->holdoff = USBKBD_HOLDOFF;
274 }
275
276 /* Insert auto-repeated keypress into keyboard buffer, if applicable */
277 if ( kbd->keycode && ! kbd->holdoff )
278 usbkbd_produce ( kbd, kbd->keycode, new->modifiers );
279
280 /* Record report */
281 memcpy ( old, new, sizeof ( *old ) );
282 }
283
284 /******************************************************************************
285 *
286 * Interrupt endpoint
287 *
288 ******************************************************************************
289 */
290
291 /**
292 * Complete interrupt transfer
293 *
294 * @v ep USB endpoint
295 * @v iobuf I/O buffer
296 * @v rc Completion status code
297 */
298 static void usbkbd_complete ( struct usb_endpoint *ep,
299 struct io_buffer *iobuf, int rc ) {
300 struct usb_keyboard *kbd = container_of ( ep, struct usb_keyboard,
301 hid.in );
302 struct usb_keyboard_report *report;
303
304 /* Ignore packets cancelled when the endpoint closes */
305 if ( ! ep->open )
306 goto drop;
307
308 /* Ignore packets with errors */
309 if ( rc != 0 ) {
310 DBGC ( kbd, "KBD %s interrupt IN failed: %s\n",
311 kbd->name, strerror ( rc ) );
312 goto drop;
313 }
314
315 /* Ignore underlength packets */
316 if ( iob_len ( iobuf ) < sizeof ( *report ) ) {
317 DBGC ( kbd, "KBD %s underlength report:\n", kbd->name );
318 DBGC_HDA ( kbd, 0, iobuf->data, iob_len ( iobuf ) );
319 goto drop;
320 }
321 report = iobuf->data;
322
323 /* Handle keyboard report */
324 usbkbd_report ( kbd, report );
325
326 drop:
327 /* Recycle I/O buffer */
328 usb_recycle ( &kbd->hid.in, iobuf );
329 }
330
331 /** Interrupt endpoint operations */
332 static struct usb_endpoint_driver_operations usbkbd_operations = {
333 .complete = usbkbd_complete,
334 };
335
336 /******************************************************************************
337 *
338 * USB interface
339 *
340 ******************************************************************************
341 */
342
343 /**
344 * Probe device
345 *
346 * @v func USB function
347 * @v config Configuration descriptor
348 * @ret rc Return status code
349 */
350 static int usbkbd_probe ( struct usb_function *func,
351 struct usb_configuration_descriptor *config ) {
352 struct usb_device *usb = func->usb;
353 struct usb_keyboard *kbd;
354 int rc;
355
356 /* Allocate and initialise structure */
357 kbd = zalloc ( sizeof ( *kbd ) );
358 if ( ! kbd ) {
359 rc = -ENOMEM;
360 goto err_alloc;
361 }
362 kbd->name = func->name;
363 kbd->bus = usb->port->hub->bus;
364 usbhid_init ( &kbd->hid, func, &usbkbd_operations, NULL );
365 usb_refill_init ( &kbd->hid.in, sizeof ( kbd->report ),
366 USBKBD_INTR_MAX_FILL );
367
368 /* Describe USB human interface device */
369 if ( ( rc = usbhid_describe ( &kbd->hid, config ) ) != 0 ) {
370 DBGC ( kbd, "KBD %s could not describe: %s\n",
371 kbd->name, strerror ( rc ) );
372 goto err_describe;
373 }
374 DBGC ( kbd, "KBD %s using %s (len %zd)\n",
375 kbd->name, usb_endpoint_name ( &kbd->hid.in ), kbd->hid.in.mtu );
376
377 /* Set boot protocol */
378 if ( ( rc = usbhid_set_protocol ( usb, func->interface[0],
379 USBHID_PROTOCOL_BOOT ) ) != 0 ) {
380 DBGC ( kbd, "KBD %s could not set boot protocol: %s\n",
381 kbd->name, strerror ( rc ) );
382 goto err_set_protocol;
383 }
384
385 /* Set idle time */
386 if ( ( rc = usbhid_set_idle ( usb, func->interface[0], 0,
387 USBKBD_IDLE_DURATION ) ) != 0 ) {
388 DBGC ( kbd, "KBD %s could not set idle time: %s\n",
389 kbd->name, strerror ( rc ) );
390 goto err_set_idle;
391 }
392
393 /* Open USB human interface device */
394 if ( ( rc = usbhid_open ( &kbd->hid ) ) != 0 ) {
395 DBGC ( kbd, "KBD %s could not open: %s\n",
396 kbd->name, strerror ( rc ) );
397 goto err_open;
398 }
399
400 /* Add to list of USB keyboards */
401 list_add_tail ( &kbd->list, &usb_keyboards );
402
403 usb_func_set_drvdata ( func, kbd );
404 return 0;
405
406 usbhid_close ( &kbd->hid );
407 err_open:
408 err_set_idle:
409 err_set_protocol:
410 err_describe:
411 free ( kbd );
412 err_alloc:
413 return rc;
414 }
415
416 /**
417 * Remove device
418 *
419 * @v func USB function
420 */
421 static void usbkbd_remove ( struct usb_function *func ) {
422 struct usb_keyboard *kbd = usb_func_get_drvdata ( func );
423
424 /* Remove from list of USB keyboards */
425 list_del ( &kbd->list );
426
427 /* Close USB human interface device */
428 usbhid_close ( &kbd->hid );
429
430 /* Free device */
431 free ( kbd );
432 }
433
434 /** USB keyboard device IDs */
435 static struct usb_device_id usbkbd_ids[] = {
436 {
437 .name = "kbd",
438 .vendor = USB_ANY_ID,
439 .product = USB_ANY_ID,
440 .class = {
441 .class = USB_CLASS_HID,
442 .subclass = USB_SUBCLASS_HID_BOOT,
443 .protocol = USBKBD_PROTOCOL,
444 },
445 },
446 };
447
448 /** USB keyboard driver */
449 struct usb_driver usbkbd_driver __usb_driver = {
450 .ids = usbkbd_ids,
451 .id_count = ( sizeof ( usbkbd_ids ) / sizeof ( usbkbd_ids[0] ) ),
452 .score = USB_SCORE_NORMAL,
453 .probe = usbkbd_probe,
454 .remove = usbkbd_remove,
455 };
456
457 /******************************************************************************
458 *
459 * Console interface
460 *
461 ******************************************************************************
462 */
463
464 /**
465 * Read a character from the console
466 *
467 * @ret character Character read
468 */
469 static int usbkbd_getchar ( void ) {
470 struct usb_keyboard *kbd;
471
472 /* Consume first available key */
473 list_for_each_entry ( kbd, &usb_keyboards, list ) {
474 if ( usbkbd_fill ( kbd ) )
475 return usbkbd_consume ( kbd );
476 }
477
478 return 0;
479 }
480
481 /**
482 * Check for available input
483 *
484 * @ret is_available Input is available
485 */
486 static int usbkbd_iskey ( void ) {
487 struct usb_keyboard *kbd;
488 unsigned int fill;
489
490 /* Poll all USB keyboards and refill endpoints */
491 list_for_each_entry ( kbd, &usb_keyboards, list ) {
492 usb_poll ( kbd->bus );
493 usb_refill ( &kbd->hid.in );
494 }
495
496 /* Check for a non-empty keyboard buffer */
497 list_for_each_entry ( kbd, &usb_keyboards, list ) {
498 fill = usbkbd_fill ( kbd );
499 if ( fill )
500 return fill;
501 }
502
503 return 0;
504 }
505
506 /** USB keyboard console */
507 struct console_driver usbkbd_console __console_driver = {
508 .getchar = usbkbd_getchar,
509 .iskey = usbkbd_iskey,
510 };