[acpi] Expose system MAC address via ${sysmac} setting
[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 <ctype.h>
29 #include <errno.h>
30 #include <assert.h>
31 #include <ipxe/console.h>
32 #include <ipxe/keys.h>
33 #include <ipxe/keymap.h>
34 #include <ipxe/usb.h>
35 #include "usbkbd.h"
36
37 /** @file
38 *
39 * USB keyboard driver
40 *
41 */
42
43 /** List of USB keyboards */
44 static LIST_HEAD ( usb_keyboards );
45
46 /******************************************************************************
47 *
48 * Keyboard map
49 *
50 ******************************************************************************
51 */
52
53 /**
54 * Map USB keycode to iPXE key
55 *
56 * @v keycode Keycode
57 * @v modifiers Modifiers
58 * @v leds LED state
59 * @ret key iPXE key
60 *
61 * Key codes are defined in the USB HID Usage Tables Keyboard/Keypad
62 * page.
63 */
64 static unsigned int usbkbd_map ( unsigned int keycode, unsigned int modifiers,
65 unsigned int leds ) {
66 unsigned int key;
67
68 if ( keycode < USBKBD_KEY_A ) {
69 /* Not keys */
70 key = 0;
71 } else if ( keycode <= USBKBD_KEY_Z ) {
72 /* Alphabetic keys */
73 key = ( keycode - USBKBD_KEY_A + 'a' );
74 if ( modifiers & USBKBD_SHIFT ) {
75 key -= ( 'a' - 'A' );
76 }
77 } else if ( keycode <= USBKBD_KEY_0 ) {
78 /* Numeric key row */
79 if ( modifiers & USBKBD_SHIFT ) {
80 key = "!@#$%^&*()" [ keycode - USBKBD_KEY_1 ];
81 } else {
82 key = ( ( ( keycode - USBKBD_KEY_1 + 1 ) % 10 ) + '0' );
83 }
84 } else if ( keycode <= USBKBD_KEY_SPACE ) {
85 /* Unmodifiable keys */
86 static const uint8_t unmodifable[] =
87 { LF, ESC, BACKSPACE, TAB, ' ' };
88 key = unmodifable[ keycode - USBKBD_KEY_ENTER ];
89 } else if ( keycode <= USBKBD_KEY_SLASH ) {
90 /* Punctuation keys */
91 if ( modifiers & USBKBD_SHIFT ) {
92 key = "_+{}|~:\"~<>?" [ keycode - USBKBD_KEY_MINUS ];
93 } else {
94 key = "-=[]\\#;'`,./" [ keycode - USBKBD_KEY_MINUS ];
95 }
96 } else if ( keycode <= USBKBD_KEY_UP ) {
97 /* Special keys */
98 static const uint16_t special[] = {
99 0, 0, 0, 0, 0, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9,
100 KEY_F10, KEY_F11, KEY_F12, 0, 0, 0, KEY_IC, KEY_HOME,
101 KEY_PPAGE, KEY_DC, KEY_END, KEY_NPAGE, KEY_RIGHT,
102 KEY_LEFT, KEY_DOWN, KEY_UP
103 };
104 key = special[ keycode - USBKBD_KEY_CAPS_LOCK ];
105 } else if ( keycode <= USBKBD_KEY_PAD_ENTER ) {
106 /* Keypad (unaffected by Num Lock) */
107 key = "\0/*-+\n" [ keycode - USBKBD_KEY_NUM_LOCK ];
108 } else if ( keycode <= USBKBD_KEY_PAD_DOT ) {
109 /* Keypad (affected by Num Lock) */
110 if ( leds & USBKBD_LED_NUM_LOCK ) {
111 key = "1234567890." [ keycode - USBKBD_KEY_PAD_1 ];
112 } else {
113 static const uint16_t keypad[] = {
114 KEY_END, KEY_DOWN, KEY_NPAGE, KEY_LEFT, 0,
115 KEY_RIGHT, KEY_HOME, KEY_UP, KEY_PPAGE,
116 KEY_IC, KEY_DC
117 };
118 key = keypad[ keycode - USBKBD_KEY_PAD_1 ];
119 };
120 } else if ( keycode == USBKBD_KEY_NON_US ) {
121 /* Non-US \ and | */
122 key = ( ( modifiers & USBKBD_SHIFT ) ?
123 ( KEYMAP_PSEUDO | '|' ) : ( KEYMAP_PSEUDO | '\\' ) );
124 } else {
125 key = 0;
126 }
127
128 /* Remap key if applicable */
129 if ( ( keycode < USBKBD_KEY_CAPS_LOCK ) ||
130 ( keycode == USBKBD_KEY_NON_US ) ) {
131
132 /* Apply modifiers */
133 if ( modifiers & USBKBD_CTRL )
134 key |= KEYMAP_CTRL;
135 if ( modifiers & USBKBD_ALT_RIGHT )
136 key |= KEYMAP_ALTGR;
137 if ( leds & USBKBD_LED_CAPS_LOCK )
138 key |= KEYMAP_CAPSLOCK;
139
140 /* Remap key */
141 key = key_remap ( key );
142 }
143
144 return key;
145 }
146
147 /******************************************************************************
148 *
149 * Keyboard buffer
150 *
151 ******************************************************************************
152 */
153
154 /**
155 * Insert keypress into keyboard buffer
156 *
157 * @v kbd USB keyboard
158 * @v keycode Keycode
159 * @v modifiers Modifiers
160 */
161 static void usbkbd_produce ( struct usb_keyboard *kbd, unsigned int keycode,
162 unsigned int modifiers ) {
163 unsigned int leds = 0;
164 unsigned int key;
165
166 /* Check for LED-modifying keys */
167 if ( keycode == USBKBD_KEY_CAPS_LOCK ) {
168 leds = USBKBD_LED_CAPS_LOCK;
169 } else if ( keycode == USBKBD_KEY_NUM_LOCK ) {
170 leds = USBKBD_LED_NUM_LOCK;
171 }
172
173 /* Handle LED-modifying keys */
174 if ( leds ) {
175 kbd->leds ^= leds;
176 kbd->leds_changed = 1;
177 return;
178 }
179
180 /* Map to iPXE key */
181 key = usbkbd_map ( keycode, modifiers, kbd->leds );
182
183 /* Do nothing if this keycode has no corresponding iPXE key */
184 if ( ! key ) {
185 DBGC ( kbd, "KBD %s has no key for keycode %#02x:%#02x\n",
186 kbd->name, modifiers, keycode );
187 return;
188 }
189
190 /* Check for buffer overrun */
191 if ( usbkbd_fill ( kbd ) >= USBKBD_BUFSIZE ) {
192 DBGC ( kbd, "KBD %s buffer overrun (key %#02x)\n",
193 kbd->name, key );
194 return;
195 }
196
197 /* Insert into buffer */
198 kbd->key[ ( kbd->prod++ ) % USBKBD_BUFSIZE ] = key;
199 DBGC2 ( kbd, "KBD %s key %#02x produced\n", kbd->name, key );
200 }
201
202 /**
203 * Consume character from keyboard buffer
204 *
205 * @v kbd USB keyboard
206 * @ret character Character
207 */
208 static unsigned int usbkbd_consume ( struct usb_keyboard *kbd ) {
209 static char buf[] = "\x1b[xx~";
210 char *tmp = &buf[2];
211 unsigned int key;
212 unsigned int character;
213 unsigned int ansi_n;
214 unsigned int len;
215
216 /* Sanity check */
217 assert ( usbkbd_fill ( kbd ) > 0 );
218
219 /* Get current keypress */
220 key = kbd->key[ kbd->cons % USBKBD_BUFSIZE ];
221
222 /* If this is a straightforward key, just consume and return it */
223 if ( key < KEY_MIN ) {
224 kbd->cons++;
225 DBGC2 ( kbd, "KBD %s key %#02x consumed\n", kbd->name, key );
226 return key;
227 }
228
229 /* Construct ANSI sequence */
230 ansi_n = KEY_ANSI_N ( key );
231 if ( ansi_n )
232 tmp += sprintf ( tmp, "%d", ansi_n );
233 *(tmp++) = KEY_ANSI_TERMINATOR ( key );
234 *tmp = '\0';
235 len = ( tmp - buf );
236 assert ( len < sizeof ( buf ) );
237 if ( kbd->subcons == 0 ) {
238 DBGC2 ( kbd, "KBD %s key %#02x consumed as ^[%s\n",
239 kbd->name, key, &buf[1] );
240 }
241
242 /* Extract character from ANSI sequence */
243 assert ( kbd->subcons < len );
244 character = buf[ kbd->subcons++ ];
245
246 /* Consume key if applicable */
247 if ( kbd->subcons == len ) {
248 kbd->cons++;
249 kbd->subcons = 0;
250 }
251
252 return character;
253 }
254
255 /******************************************************************************
256 *
257 * Keyboard report
258 *
259 ******************************************************************************
260 */
261
262 /**
263 * Check for presence of keycode in report
264 *
265 * @v report Keyboard report
266 * @v keycode Keycode (must be non-zero)
267 * @ret has_keycode Keycode is present in report
268 */
269 static int usbkbd_has_keycode ( struct usb_keyboard_report *report,
270 unsigned int keycode ) {
271 unsigned int i;
272
273 /* Check for keycode */
274 for ( i = 0 ; i < ( sizeof ( report->keycode ) /
275 sizeof ( report->keycode[0] ) ) ; i++ ) {
276 if ( report->keycode[i] == keycode )
277 return keycode;
278 }
279
280 return 0;
281 }
282
283 /**
284 * Handle keyboard report
285 *
286 * @v kbd USB keyboard
287 * @v new New keyboard report
288 */
289 static void usbkbd_report ( struct usb_keyboard *kbd,
290 struct usb_keyboard_report *new ) {
291 struct usb_keyboard_report *old = &kbd->report;
292 unsigned int keycode;
293 unsigned int i;
294
295 /* Check if current key has been released */
296 if ( kbd->keycode && ! usbkbd_has_keycode ( new, kbd->keycode ) ) {
297 DBGC2 ( kbd, "KBD %s keycode %#02x released\n",
298 kbd->name, kbd->keycode );
299 kbd->keycode = 0;
300 }
301
302 /* Decrement auto-repeat hold-off timer, if applicable */
303 if ( kbd->holdoff )
304 kbd->holdoff--;
305
306 /* Check if a new key has been pressed */
307 for ( i = 0 ; i < ( sizeof ( new->keycode ) /
308 sizeof ( new->keycode[0] ) ) ; i++ ) {
309
310 /* Ignore keys present in the previous report */
311 keycode = new->keycode[i];
312 if ( ( keycode == 0 ) || usbkbd_has_keycode ( old, keycode ) )
313 continue;
314 DBGC2 ( kbd, "KBD %s keycode %#02x pressed\n",
315 kbd->name, keycode );
316
317 /* Insert keypress into keyboard buffer */
318 usbkbd_produce ( kbd, keycode, new->modifiers );
319
320 /* Record as most recent keycode */
321 kbd->keycode = keycode;
322
323 /* Start auto-repeat hold-off timer */
324 kbd->holdoff = USBKBD_HOLDOFF;
325 }
326
327 /* Insert auto-repeated keypress into keyboard buffer, if applicable */
328 if ( kbd->keycode && ! kbd->holdoff )
329 usbkbd_produce ( kbd, kbd->keycode, new->modifiers );
330
331 /* Record report */
332 memcpy ( old, new, sizeof ( *old ) );
333 }
334
335 /******************************************************************************
336 *
337 * Interrupt endpoint
338 *
339 ******************************************************************************
340 */
341
342 /**
343 * Complete interrupt transfer
344 *
345 * @v ep USB endpoint
346 * @v iobuf I/O buffer
347 * @v rc Completion status code
348 */
349 static void usbkbd_complete ( struct usb_endpoint *ep,
350 struct io_buffer *iobuf, int rc ) {
351 struct usb_keyboard *kbd = container_of ( ep, struct usb_keyboard,
352 hid.in );
353 struct usb_keyboard_report *report;
354
355 /* Ignore packets cancelled when the endpoint closes */
356 if ( ! ep->open )
357 goto drop;
358
359 /* Ignore packets with errors */
360 if ( rc != 0 ) {
361 DBGC ( kbd, "KBD %s interrupt IN failed: %s\n",
362 kbd->name, strerror ( rc ) );
363 goto drop;
364 }
365
366 /* Ignore underlength packets */
367 if ( iob_len ( iobuf ) < sizeof ( *report ) ) {
368 DBGC ( kbd, "KBD %s underlength report:\n", kbd->name );
369 DBGC_HDA ( kbd, 0, iobuf->data, iob_len ( iobuf ) );
370 goto drop;
371 }
372 report = iobuf->data;
373
374 /* Handle keyboard report */
375 usbkbd_report ( kbd, report );
376
377 drop:
378 /* Recycle I/O buffer */
379 usb_recycle ( &kbd->hid.in, iobuf );
380 }
381
382 /** Interrupt endpoint operations */
383 static struct usb_endpoint_driver_operations usbkbd_operations = {
384 .complete = usbkbd_complete,
385 };
386
387 /******************************************************************************
388 *
389 * Keyboard LEDs
390 *
391 ******************************************************************************
392 */
393
394 /**
395 * Set keyboard LEDs
396 *
397 * @v kbd USB keyboard
398 * @ret rc Return status code
399 */
400 static int usbkbd_set_leds ( struct usb_keyboard *kbd ) {
401 struct usb_function *func = kbd->hid.func;
402 int rc;
403
404 DBGC2 ( kbd, "KBD %s setting LEDs to %#02x\n", kbd->name, kbd->leds );
405
406 /* Set keyboard LEDs */
407 if ( ( rc = usbhid_set_report ( func->usb, func->interface[0],
408 USBHID_REPORT_OUTPUT, 0, &kbd->leds,
409 sizeof ( kbd->leds ) ) ) != 0 ) {
410 DBGC ( kbd, "KBD %s could not set LEDs to %#02x: %s\n",
411 kbd->name, kbd->leds, strerror ( rc ) );
412 return rc;
413 }
414
415 return 0;
416 }
417
418 /******************************************************************************
419 *
420 * USB interface
421 *
422 ******************************************************************************
423 */
424
425 /**
426 * Probe device
427 *
428 * @v func USB function
429 * @v config Configuration descriptor
430 * @ret rc Return status code
431 */
432 static int usbkbd_probe ( struct usb_function *func,
433 struct usb_configuration_descriptor *config ) {
434 struct usb_device *usb = func->usb;
435 struct usb_keyboard *kbd;
436 int rc;
437
438 /* Allocate and initialise structure */
439 kbd = zalloc ( sizeof ( *kbd ) );
440 if ( ! kbd ) {
441 rc = -ENOMEM;
442 goto err_alloc;
443 }
444 kbd->name = func->name;
445 kbd->bus = usb->port->hub->bus;
446 usbhid_init ( &kbd->hid, func, &usbkbd_operations, NULL );
447 usb_refill_init ( &kbd->hid.in, 0, sizeof ( kbd->report ),
448 USBKBD_INTR_MAX_FILL );
449
450 /* Describe USB human interface device */
451 if ( ( rc = usbhid_describe ( &kbd->hid, config ) ) != 0 ) {
452 DBGC ( kbd, "KBD %s could not describe: %s\n",
453 kbd->name, strerror ( rc ) );
454 goto err_describe;
455 }
456 DBGC ( kbd, "KBD %s using %s (len %zd)\n",
457 kbd->name, usb_endpoint_name ( &kbd->hid.in ), kbd->hid.in.mtu );
458
459 /* Set boot protocol */
460 if ( ( rc = usbhid_set_protocol ( usb, func->interface[0],
461 USBHID_PROTOCOL_BOOT ) ) != 0 ) {
462 DBGC ( kbd, "KBD %s could not set boot protocol: %s\n",
463 kbd->name, strerror ( rc ) );
464 goto err_set_protocol;
465 }
466
467 /* Set idle time */
468 if ( ( rc = usbhid_set_idle ( usb, func->interface[0], 0,
469 USBKBD_IDLE_DURATION ) ) != 0 ) {
470 DBGC ( kbd, "KBD %s could not set idle time: %s\n",
471 kbd->name, strerror ( rc ) );
472 goto err_set_idle;
473 }
474
475 /* Open USB human interface device */
476 if ( ( rc = usbhid_open ( &kbd->hid ) ) != 0 ) {
477 DBGC ( kbd, "KBD %s could not open: %s\n",
478 kbd->name, strerror ( rc ) );
479 goto err_open;
480 }
481
482 /* Add to list of USB keyboards */
483 list_add_tail ( &kbd->list, &usb_keyboards );
484
485 /* Set initial LED state */
486 usbkbd_set_leds ( kbd );
487
488 usb_func_set_drvdata ( func, kbd );
489 return 0;
490
491 usbhid_close ( &kbd->hid );
492 err_open:
493 err_set_idle:
494 err_set_protocol:
495 err_describe:
496 free ( kbd );
497 err_alloc:
498 return rc;
499 }
500
501 /**
502 * Remove device
503 *
504 * @v func USB function
505 */
506 static void usbkbd_remove ( struct usb_function *func ) {
507 struct usb_keyboard *kbd = usb_func_get_drvdata ( func );
508
509 /* Remove from list of USB keyboards */
510 list_del ( &kbd->list );
511
512 /* Close USB human interface device */
513 usbhid_close ( &kbd->hid );
514
515 /* Free device */
516 free ( kbd );
517 }
518
519 /** USB keyboard device IDs */
520 static struct usb_device_id usbkbd_ids[] = {
521 {
522 .name = "kbd",
523 .vendor = USB_ANY_ID,
524 .product = USB_ANY_ID,
525 },
526 };
527
528 /** USB keyboard driver */
529 struct usb_driver usbkbd_driver __usb_driver = {
530 .ids = usbkbd_ids,
531 .id_count = ( sizeof ( usbkbd_ids ) / sizeof ( usbkbd_ids[0] ) ),
532 .class = USB_CLASS_ID ( USB_CLASS_HID, USB_SUBCLASS_HID_BOOT,
533 USBKBD_PROTOCOL ),
534 .score = USB_SCORE_NORMAL,
535 .probe = usbkbd_probe,
536 .remove = usbkbd_remove,
537 };
538
539 /******************************************************************************
540 *
541 * Console interface
542 *
543 ******************************************************************************
544 */
545
546 /**
547 * Read a character from the console
548 *
549 * @ret character Character read
550 */
551 static int usbkbd_getchar ( void ) {
552 struct usb_keyboard *kbd;
553
554 /* Consume first available key */
555 list_for_each_entry ( kbd, &usb_keyboards, list ) {
556 if ( usbkbd_fill ( kbd ) )
557 return usbkbd_consume ( kbd );
558 }
559
560 return 0;
561 }
562
563 /**
564 * Check for available input
565 *
566 * @ret is_available Input is available
567 */
568 static int usbkbd_iskey ( void ) {
569 struct usb_keyboard *kbd;
570 unsigned int fill;
571
572 /* Poll USB keyboards, refill endpoints, and set LEDs if applicable */
573 list_for_each_entry ( kbd, &usb_keyboards, list ) {
574
575 /* Poll keyboard */
576 usb_poll ( kbd->bus );
577
578 /* Refill endpoints */
579 usb_refill ( &kbd->hid.in );
580
581 /* Update keyboard LEDs, if applicable */
582 if ( kbd->leds_changed ) {
583 usbkbd_set_leds ( kbd );
584 kbd->leds_changed = 0;
585 }
586 }
587
588 /* Check for a non-empty keyboard buffer */
589 list_for_each_entry ( kbd, &usb_keyboards, list ) {
590 fill = usbkbd_fill ( kbd );
591 if ( fill )
592 return fill;
593 }
594
595 return 0;
596 }
597
598 /** USB keyboard console */
599 struct console_driver usbkbd_console __console_driver = {
600 .getchar = usbkbd_getchar,
601 .iskey = usbkbd_iskey,
602 };