You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

usbkbd.c 15KB

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