iPXE
usbkbd.c
Go to the documentation of this file.
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
24FILE_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 */
44static 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 */
64static 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 unsigned int special[] = {
99 0, 0, 0, 0, 0, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9,
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 unsigned int keypad[] = {
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 )
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 */
161static 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 ) {
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 */
208static 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 */
269static 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 */
289static 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 */
349static 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 */
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 */
400static 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 */
432static 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 ),
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 */
506static 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 */
520static struct usb_device_id usbkbd_ids[] = {
521 USB_ID ( 0xffff, 0xffff, "kbd", "USB keyboard", 0 ),
522};
523
524/** USB keyboard driver */
525struct usb_driver usbkbd_driver __usb_driver = {
526 .ids = usbkbd_ids,
527 .id_count = ( sizeof ( usbkbd_ids ) / sizeof ( usbkbd_ids[0] ) ),
530 .score = USB_SCORE_NORMAL,
531 .probe = usbkbd_probe,
532 .remove = usbkbd_remove,
533};
534
535/******************************************************************************
536 *
537 * Console interface
538 *
539 ******************************************************************************
540 */
541
542/**
543 * Read a character from the console
544 *
545 * @ret character Character read
546 */
547static int usbkbd_getchar ( void ) {
548 struct usb_keyboard *kbd;
549
550 /* Consume first available key */
551 list_for_each_entry ( kbd, &usb_keyboards, list ) {
552 if ( usbkbd_fill ( kbd ) )
553 return usbkbd_consume ( kbd );
554 }
555
556 return 0;
557}
558
559/**
560 * Check for available input
561 *
562 * @ret is_available Input is available
563 */
564static int usbkbd_iskey ( void ) {
565 struct usb_keyboard *kbd;
566 unsigned int fill;
567
568 /* Poll USB keyboards, refill endpoints, and set LEDs if applicable */
569 list_for_each_entry ( kbd, &usb_keyboards, list ) {
570
571 /* Poll keyboard */
572 usb_poll ( kbd->bus );
573
574 /* Refill endpoints */
575 usb_refill ( &kbd->hid.in );
576
577 /* Update keyboard LEDs, if applicable */
578 if ( kbd->leds_changed ) {
579 usbkbd_set_leds ( kbd );
580 kbd->leds_changed = 0;
581 }
582 }
583
584 /* Check for a non-empty keyboard buffer */
585 list_for_each_entry ( kbd, &usb_keyboards, list ) {
586 fill = usbkbd_fill ( kbd );
587 if ( fill )
588 return fill;
589 }
590
591 return 0;
592}
593
594/** USB keyboard console */
595struct console_driver usbkbd_console __console_driver = {
596 .getchar = usbkbd_getchar,
597 .iskey = usbkbd_iskey,
598};
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
#define ESC
Escape character.
Definition ansiesc.h:93
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned char uint8_t
Definition stdint.h:10
int old
Definition bitops.h:65
static int fill
Definition string.h:209
Assertions.
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
Character types.
int keypad(WINDOW *, bool)
ring len
Length.
Definition dwmac.h:226
Error codes.
#define DBGC2(...)
Definition compiler.h:522
#define DBGC(...)
Definition compiler.h:505
#define DBGC_HDA(...)
Definition compiler.h:506
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ENOMEM
Not enough space.
Definition errno.h:535
User interaction.
#define __console_driver
Mark a struct console_driver as being part of the console drivers table.
Definition console.h:134
Universal Serial Bus (USB)
static void usb_recycle(struct usb_endpoint *ep, struct io_buffer *iobuf)
Recycle I/O buffer.
Definition usb.h:633
#define __usb_driver
Declare a USB driver.
Definition usb.h:1453
static void usb_refill_init(struct usb_endpoint *ep, size_t reserve, size_t len, unsigned int max)
Initialise USB endpoint refill.
Definition usb.h:617
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
Definition usb.h:1401
static void usb_poll(struct usb_bus *bus)
Poll USB bus.
Definition usb.h:1072
#define USB_ID(_vendor, _product, _name, _description, _data)
Definition usb.h:1373
static void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
Definition usb.h:707
@ USB_SCORE_NORMAL
Normal driver.
Definition usb.h:1465
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
Definition usb.h:718
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
unsigned int key_remap(unsigned int character)
Remap a key.
Definition keymap.c:62
Keyboard mappings.
#define KEYMAP_PSEUDO
Pseudo key flag.
Definition keymap.h:53
#define KEYMAP_ALTGR
AltGr key flag.
Definition keymap.h:74
#define KEYMAP_CTRL
Ctrl key flag.
Definition keymap.h:56
#define KEYMAP_CAPSLOCK
CapsLock key flag.
Definition keymap.h:59
Key definitions.
#define KEY_RIGHT
Right arrow.
Definition keys.h:108
#define KEY_DC
Delete.
Definition keys.h:113
#define KEY_F12
F12.
Definition keys.h:123
#define KEY_DOWN
Down arrow.
Definition keys.h:107
#define KEY_ANSI_TERMINATOR(key)
Extract ANSI escape sequence terminating character.
Definition keys.h:104
#define KEY_F5
F5.
Definition keys.h:116
#define LF
Definition keys.h:48
#define KEY_PPAGE
Page up.
Definition keys.h:114
#define KEY_F9
F9.
Definition keys.h:120
#define BACKSPACE
Definition keys.h:46
#define KEY_ANSI_N(key)
Extract ANSI escape sequence numeric portion.
Definition keys.h:96
#define KEY_F8
F8 (for PXE)
Definition keys.h:119
#define KEY_F7
F7.
Definition keys.h:118
#define KEY_NPAGE
Page down.
Definition keys.h:115
#define KEY_END
End.
Definition keys.h:110
#define KEY_MIN
Minimum value for special keypresses.
Definition keys.h:70
#define KEY_F11
F11.
Definition keys.h:122
#define KEY_F6
F6.
Definition keys.h:117
#define KEY_F10
F10.
Definition keys.h:121
#define TAB
Definition keys.h:47
#define KEY_IC
Insert.
Definition keys.h:112
#define KEY_LEFT
Left arrow.
Definition keys.h:109
#define KEY_HOME
Home.
Definition keys.h:111
#define KEY_UP
Up arrow.
Definition keys.h:106
unsigned long tmp
Definition linux_pci.h:65
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define LIST_HEAD(list)
Declare a static list head.
Definition list.h:38
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
#define sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition stdio.h:37
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
A console driver.
Definition console.h:56
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
A USB configuration descriptor.
Definition usb.h:210
A USB device ID.
Definition usb.h:1361
A USB device.
Definition usb.h:723
struct usb_port * port
USB port.
Definition usb.h:727
A USB driver.
Definition usb.h:1419
USB endpoint driver operations.
Definition usb.h:489
A USB endpoint.
Definition usb.h:404
size_t mtu
Maximum transfer size.
Definition usb.h:412
int open
Endpoint is open.
Definition usb.h:419
A USB function.
Definition usb.h:674
struct usb_device * usb
USB device.
Definition usb.h:678
uint8_t interface[0]
List of interface numbers.
Definition usb.h:697
const char * name
Name.
Definition usb.h:676
struct usb_endpoint in
Interrupt IN endpoint.
Definition usbhid.h:55
struct usb_function * func
USB function.
Definition usbhid.h:53
struct usb_bus * bus
USB bus.
Definition usb.h:845
A USB keyboard report.
Definition usbkbd.h:20
uint8_t keycode[6]
Keycodes.
Definition usbkbd.h:26
A USB keyboard device.
Definition usbkbd.h:118
struct list_head list
List of all USB keyboards.
Definition usbkbd.h:122
unsigned int subcons
Keyboard buffer sub-consumer counter.
Definition usbkbd.h:155
struct usb_bus * bus
USB bus.
Definition usbkbd.h:125
unsigned int holdoff
Autorepeat hold-off time (in number of completions reported)
Definition usbkbd.h:134
unsigned int prod
Keyboard buffer producer counter.
Definition usbkbd.h:147
uint8_t leds
Keyboard LED state.
Definition usbkbd.h:137
unsigned int key[USBKBD_BUFSIZE]
Keyboard buffer.
Definition usbkbd.h:145
unsigned int cons
Keyboard buffer consumer counter.
Definition usbkbd.h:149
struct usb_hid hid
USB human interface device.
Definition usbkbd.h:127
struct usb_keyboard_report report
Most recent keyboard report.
Definition usbkbd.h:130
const char * name
Name.
Definition usbkbd.h:120
unsigned int keycode
Most recently pressed non-modifier key (if any)
Definition usbkbd.h:132
uint8_t leds_changed
Keyboard LEDs changed.
Definition usbkbd.h:139
struct usb_hub * hub
USB hub.
Definition usb.h:815
const char * usb_endpoint_name(struct usb_endpoint *ep)
Get USB endpoint name (for debugging)
Definition usb.c:221
int usb_refill(struct usb_endpoint *ep)
Refill endpoint.
Definition usb.c:711
int usbhid_describe(struct usb_hid *hid, struct usb_configuration_descriptor *config)
Describe USB human interface device.
Definition usbhid.c:120
void usbhid_close(struct usb_hid *hid)
Close USB human interface device.
Definition usbhid.c:83
int usbhid_open(struct usb_hid *hid)
Open USB human interface device.
Definition usbhid.c:43
static int usbhid_set_idle(struct usb_device *usb, unsigned int interface, unsigned int report, unsigned int duration)
Set idle time.
Definition usbhid.h:106
static int usbhid_set_protocol(struct usb_device *usb, unsigned int interface, unsigned int protocol)
Set protocol.
Definition usbhid.h:89
#define USBHID_PROTOCOL_BOOT
Boot protocol.
Definition usbhid.h:26
#define USBHID_REPORT_OUTPUT
Output report type.
Definition usbhid.h:45
static int usbhid_set_report(struct usb_device *usb, unsigned int interface, unsigned int type, unsigned int report, void *data, size_t len)
Set report.
Definition usbhid.h:126
static void usbhid_init(struct usb_hid *hid, struct usb_function *func, struct usb_endpoint_driver_operations *in, struct usb_endpoint_driver_operations *out)
Initialise USB human interface device.
Definition usbhid.h:69
#define USB_SUBCLASS_HID_BOOT
Subclass code for boot devices.
Definition usbhid.h:18
#define USB_CLASS_HID
Class code for human interface devices.
Definition usbhid.h:15
static unsigned int usbkbd_map(unsigned int keycode, unsigned int modifiers, unsigned int leds)
Map USB keycode to iPXE key.
Definition usbkbd.c:64
static void usbkbd_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete interrupt transfer.
Definition usbkbd.c:349
static struct usb_device_id usbkbd_ids[]
USB keyboard device IDs.
Definition usbkbd.c:520
static struct usb_endpoint_driver_operations usbkbd_operations
Interrupt endpoint operations.
Definition usbkbd.c:383
static int usbkbd_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition usbkbd.c:432
static int usbkbd_has_keycode(struct usb_keyboard_report *report, unsigned int keycode)
Check for presence of keycode in report.
Definition usbkbd.c:269
static int usbkbd_set_leds(struct usb_keyboard *kbd)
Set keyboard LEDs.
Definition usbkbd.c:400
static int usbkbd_iskey(void)
Check for available input.
Definition usbkbd.c:564
static void usbkbd_remove(struct usb_function *func)
Remove device.
Definition usbkbd.c:506
static void usbkbd_report(struct usb_keyboard *kbd, struct usb_keyboard_report *new)
Handle keyboard report.
Definition usbkbd.c:289
static void usbkbd_produce(struct usb_keyboard *kbd, unsigned int keycode, unsigned int modifiers)
Insert keypress into keyboard buffer.
Definition usbkbd.c:161
static unsigned int usbkbd_consume(struct usb_keyboard *kbd)
Consume character from keyboard buffer.
Definition usbkbd.c:208
static int usbkbd_getchar(void)
Read a character from the console.
Definition usbkbd.c:547
USB keyboard driver.
static unsigned int usbkbd_fill(struct usb_keyboard *kbd)
Calculate keyboard buffer fill level.
Definition usbkbd.h:165
#define USBKBD_PROTOCOL
Keyboard protocol.
Definition usbkbd.h:17
#define USBKBD_BUFSIZE
Keyboard buffer size.
Definition usbkbd.h:115
#define USBKBD_IDLE_DURATION
Keyboard idle duration (in 4ms units)
Definition usbkbd.h:93
#define USBKBD_SHIFT
Either Shift key.
Definition usbkbd.h:53
#define USBKBD_INTR_MAX_FILL
Interrupt endpoint maximum fill level.
Definition usbkbd.h:109
@ USBKBD_ALT_RIGHT
Right Alt key.
Definition usbkbd.h:44
#define USBKBD_CTRL
Either Ctrl key.
Definition usbkbd.h:50
@ USBKBD_KEY_NUM_LOCK
Definition usbkbd.h:74
@ USBKBD_KEY_MINUS
Definition usbkbd.h:69
@ USBKBD_KEY_PAD_DOT
Definition usbkbd.h:77
@ USBKBD_KEY_PAD_ENTER
Definition usbkbd.h:75
@ USBKBD_KEY_CAPS_LOCK
Definition usbkbd.h:71
@ USBKBD_KEY_UP
Definition usbkbd.h:73
@ USBKBD_KEY_A
Definition usbkbd.h:63
@ USBKBD_KEY_SPACE
Definition usbkbd.h:68
@ USBKBD_KEY_PAD_1
Definition usbkbd.h:76
@ USBKBD_KEY_NON_US
Definition usbkbd.h:78
@ USBKBD_KEY_Z
Definition usbkbd.h:64
@ USBKBD_KEY_0
Definition usbkbd.h:66
@ USBKBD_KEY_ENTER
Definition usbkbd.h:67
@ USBKBD_KEY_1
Definition usbkbd.h:65
@ USBKBD_KEY_SLASH
Definition usbkbd.h:70
#define USBKBD_HOLDOFF
Keyboard auto-repeat hold-off (in units of USBKBD_IDLE_DURATION)
Definition usbkbd.h:100
@ USBKBD_LED_CAPS_LOCK
Definition usbkbd.h:84
@ USBKBD_LED_NUM_LOCK
Definition usbkbd.h:83