Changeset 72af8da in mainline for uspace/drv/usbhid/kbddev.c


Ignore:
Timestamp:
2011-03-16T18:50:17Z (14 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
42a3a57
Parents:
3e7b7cd (diff), fcf07e6 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge from usb/development

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhid/kbddev.c

    r3e7b7cd r72af8da  
    3737#include <errno.h>
    3838#include <str_error.h>
    39 #include <fibril.h>
     39#include <stdio.h>
    4040
    4141#include <io/keycode.h>
    4242#include <ipc/kbd.h>
    4343#include <async.h>
     44#include <fibril.h>
     45#include <fibril_synch.h>
    4446
    4547#include <usb/usb.h>
     
    5557#include "layout.h"
    5658#include "conv.h"
    57 
    58 /*----------------------------------------------------------------------------*/
    59 
     59#include "kbdrepeat.h"
     60
     61/*----------------------------------------------------------------------------*/
     62/** Default modifiers when the keyboard is initialized. */
    6063static const unsigned DEFAULT_ACTIVE_MODS = KM_NUM_LOCK;
     64
     65/** Boot protocol report size (key part). */
    6166static const size_t BOOTP_REPORT_SIZE = 6;
     67
     68/** Boot protocol total report size. */
    6269static const size_t BOOTP_BUFFER_SIZE = 8;
     70
     71/** Boot protocol output report size. */
    6372static const size_t BOOTP_BUFFER_OUT_SIZE = 1;
     73
     74/** Boot protocol error key code. */
     75static const uint8_t BOOTP_ERROR_ROLLOVER = 1;
     76
     77/** Default idle rate for keyboards. */
     78static const uint8_t IDLE_RATE = 0;
     79
     80/** Delay before a pressed key starts auto-repeating. */
     81static const unsigned int DEFAULT_DELAY_BEFORE_FIRST_REPEAT = 500 * 1000;
     82
     83/** Delay between two repeats of a pressed key when auto-repeating. */
     84static const unsigned int DEFAULT_REPEAT_DELAY = 50 * 1000;
    6485
    6586/** Keyboard polling endpoint description for boot protocol class. */
     
    79100#define NUM_LAYOUTS 3
    80101
     102/** Keyboard layout map. */
    81103static layout_op_t *layout[NUM_LAYOUTS] = {
    82104        &us_qwerty_op,
     
    90112/* Modifier constants                                                         */
    91113/*----------------------------------------------------------------------------*/
    92 
     114/** Mapping of USB modifier key codes to generic modifier key codes. */
    93115static const keycode_t usbhid_modifiers_keycodes[USB_HID_MOD_COUNT] = {
    94116        KC_LCTRL,         /* USB_HID_MOD_LCTRL */
     
    111133};
    112134
    113 /** Default handler for IPC methods not handled by DDF.
    114  *
    115  * @param dev Device handling the call.
     135/**
     136 * Default handler for IPC methods not handled by DDF.
     137 *
     138 * Currently recognizes only one method (IPC_M_CONNECT_TO_ME), in which case it
     139 * assumes the caller is the console and thus it stores IPC phone to it for
     140 * later use by the driver to notify about key events.
     141 *
     142 * @param fun Device function handling the call.
    116143 * @param icallid Call id.
    117144 * @param icall Call data.
     
    144171/* Key processing functions                                                   */
    145172/*----------------------------------------------------------------------------*/
    146 
     173/**
     174 * Handles turning of LED lights on and off.
     175 *
     176 * In case of USB keyboards, the LEDs are handled in the driver, not in the
     177 * device. When there should be a change (lock key was pressed), the driver
     178 * uses a Set_Report request sent to the device to set the state of the LEDs.
     179 *
     180 * This functions sets the LED lights according to current settings of modifiers
     181 * kept in the keyboard device structure.
     182 *
     183 * @param kbd_dev Keyboard device structure.
     184 */
    147185static void usbhid_kbd_set_led(usbhid_kbd_t *kbd_dev)
    148186{
    149187        uint8_t buffer[BOOTP_BUFFER_OUT_SIZE];
    150188        int rc= 0;
    151         unsigned i;
    152189       
    153190        memset(buffer, 0, BOOTP_BUFFER_OUT_SIZE);
     
    177214        }
    178215       
    179         // TODO: REFACTOR!!!
    180        
    181         usb_log_debug("Output report buffer: ");
    182         for (i = 0; i < BOOTP_BUFFER_OUT_SIZE; ++i) {
    183                 usb_log_debug("0x%x ", buffer[i]);
    184         }
    185         usb_log_debug("\n");
    186        
    187         uint16_t value = 0;
    188         value |= (USB_HID_REPORT_TYPE_OUTPUT << 8);
    189 
     216        usb_log_debug("Output report buffer: %s\n",
     217            usb_debug_str_buffer(buffer, BOOTP_BUFFER_OUT_SIZE, 0));
     218       
    190219        assert(kbd_dev->hid_dev != NULL);
    191220        assert(kbd_dev->hid_dev->initialized);
    192         usbhid_req_set_report(kbd_dev->hid_dev, value, buffer,
    193             BOOTP_BUFFER_OUT_SIZE);
    194 }
    195 
    196 /*----------------------------------------------------------------------------*/
    197 
    198 static void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type,
    199     unsigned int key)
     221        usbhid_req_set_report(kbd_dev->hid_dev, USB_HID_REPORT_TYPE_OUTPUT,
     222            buffer, BOOTP_BUFFER_OUT_SIZE);
     223}
     224
     225/*----------------------------------------------------------------------------*/
     226/**
     227 * Processes key events.
     228 *
     229 * @note This function was copied from AT keyboard driver and modified to suit
     230 *       USB keyboard.
     231 *
     232 * @note Lock keys are not sent to the console, as they are completely handled
     233 *       in the driver. It may, however, be required later that the driver
     234 *       sends also these keys to application (otherwise it cannot use those
     235 *       keys at all).
     236 *
     237 * @param kbd_dev Keyboard device structure.
     238 * @param type Type of the event (press / release). Recognized values:
     239 *             KEY_PRESS, KEY_RELEASE
     240 * @param key Key code of the key according to HID Usage Tables.
     241 */
     242void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key)
    200243{
    201244        console_event_t ev;
    202245        unsigned mod_mask;
    203246
    204         // TODO: replace by our own parsing?? or are the key codes identical??
     247        /*
     248         * These parts are copy-pasted from the AT keyboard driver.
     249         *
     250         * They definitely require some refactoring, but will keep it for later
     251         * when the console and keyboard system is changed in HelenOS.
     252         */
    205253        switch (key) {
    206254        case KC_LCTRL: mod_mask = KM_LCTRL; break;
     
    228276
    229277        if (mod_mask != 0) {
    230                 usb_log_debug2("\n\nChanging mods and lock keys\n");
    231                 usb_log_debug2("\nmods before: 0x%x\n", kbd_dev->mods);
    232                 usb_log_debug2("\nLock keys before:0x%x\n\n",
    233                     kbd_dev->lock_keys);
    234                
    235278                if (type == KEY_PRESS) {
    236                         usb_log_debug2("\nKey pressed.\n");
    237279                        /*
    238280                         * Only change lock state on transition from released
     
    240282                         * up the lock state.
    241283                         */
     284                        unsigned int locks_old = kbd_dev->lock_keys;
     285                       
    242286                        kbd_dev->mods =
    243287                            kbd_dev->mods ^ (mod_mask & ~kbd_dev->lock_keys);
     
    245289
    246290                        /* Update keyboard lock indicator lights. */
    247                         usbhid_kbd_set_led(kbd_dev);
     291                        if (kbd_dev->lock_keys != locks_old) {
     292                                usbhid_kbd_set_led(kbd_dev);
     293                        }
    248294                } else {
    249                         usb_log_debug2("\nKey released.\n");
    250295                        kbd_dev->lock_keys = kbd_dev->lock_keys & ~mod_mask;
    251296                }
    252297        }
    253298
    254         usb_log_debug2("\n\nmods after: 0x%x\n", kbd_dev->mods);
    255         usb_log_debug2("\nLock keys after: 0x%x\n\n", kbd_dev->lock_keys);
    256        
    257299        if (key == KC_CAPS_LOCK || key == KC_NUM_LOCK || key == KC_SCROLL_LOCK) {
    258300                // do not send anything to the console, this is our business
     
    281323        ev.key = key;
    282324        ev.mods = kbd_dev->mods;
    283        
    284         if (ev.mods & KM_NUM_LOCK) {
    285                 usb_log_debug("\n\nNum Lock turned on.\n\n");
    286         }
    287325
    288326        ev.c = layout[active_layout]->parse_ev(&ev);
     
    300338
    301339/*----------------------------------------------------------------------------*/
    302 
     340/**
     341 * Checks if modifiers were pressed or released and generates key events.
     342 *
     343 * @param kbd_dev Keyboard device structure.
     344 * @param modifiers Bitmap of modifiers.
     345 *
     346 * @sa usbhid_kbd_push_ev()
     347 */
    303348static void usbhid_kbd_check_modifier_changes(usbhid_kbd_t *kbd_dev,
    304349    uint8_t modifiers)
     
    336381
    337382/*----------------------------------------------------------------------------*/
    338 
     383/**
     384 * Checks if some keys were pressed or released and generates key events.
     385 *
     386 * An event is created only when key is pressed or released. Besides handling
     387 * the events (usbhid_kbd_push_ev()), the auto-repeat fibril is notified about
     388 * key presses and releases (see usbhid_kbd_repeat_start() and
     389 * usbhid_kbd_repeat_stop()).
     390 *
     391 * @param kbd_dev Keyboard device structure.
     392 * @param key_codes Parsed keyboard report - codes of currently pressed keys
     393 *                  according to HID Usage Tables.
     394 * @param count Number of key codes in report (size of the report).
     395 *
     396 * @sa usbhid_kbd_push_ev(), usbhid_kbd_repeat_start(), usbhid_kbd_repeat_stop()
     397 */
    339398static void usbhid_kbd_check_key_changes(usbhid_kbd_t *kbd_dev,
    340     const uint8_t *key_codes)
    341 {
    342         // TODO: phantom state!!
    343        
     399    const uint8_t *key_codes, size_t count)
     400{
    344401        unsigned int key;
    345402        unsigned int i, j;
    346403       
    347         // TODO: quite dummy right now, think of better implementation
     404        /*
     405         * First of all, check if the kbd have reported phantom state.
     406         */
     407        i = 0;
     408        // all fields should report Error Rollover
     409        while (i < count &&
     410            key_codes[i] == BOOTP_ERROR_ROLLOVER) {
     411                ++i;
     412        }
     413        if (i == count) {
     414                usb_log_debug("Phantom state occured.\n");
     415                // phantom state, do nothing
     416                return;
     417        }
     418       
     419        /* TODO: quite dummy right now, think of better implementation */
     420        assert(count == kbd_dev->key_count);
    348421       
    349422        /*
    350423         * 1) Key releases
    351424         */
    352         for (j = 0; j < kbd_dev->keycode_count; ++j) {
     425        for (j = 0; j < count; ++j) {
    353426                // try to find the old key in the new key list
    354427                i = 0;
    355                 while (i < kbd_dev->keycode_count
    356                     && key_codes[i] != kbd_dev->keycodes[j]) {
     428                while (i < kbd_dev->key_count
     429                    && key_codes[i] != kbd_dev->keys[j]) {
    357430                        ++i;
    358431                }
    359432               
    360                 if (i == kbd_dev->keycode_count) {
     433                if (i == count) {
    361434                        // not found, i.e. the key was released
    362                         key = usbhid_parse_scancode(kbd_dev->keycodes[j]);
     435                        key = usbhid_parse_scancode(kbd_dev->keys[j]);
     436                        usbhid_kbd_repeat_stop(kbd_dev, key);
    363437                        usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, key);
    364                         usb_log_debug2("\nKey released: %d\n", key);
     438                        usb_log_debug2("Key released: %d\n", key);
    365439                } else {
    366440                        // found, nothing happens
     
    371445         * 1) Key presses
    372446         */
    373         for (i = 0; i < kbd_dev->keycode_count; ++i) {
     447        for (i = 0; i < kbd_dev->key_count; ++i) {
    374448                // try to find the new key in the old key list
    375449                j = 0;
    376                 while (j < kbd_dev->keycode_count
    377                     && kbd_dev->keycodes[j] != key_codes[i]) {
     450                while (j < count && kbd_dev->keys[j] != key_codes[i]) {
    378451                        ++j;
    379452                }
    380453               
    381                 if (j == kbd_dev->keycode_count) {
     454                if (j == count) {
    382455                        // not found, i.e. new key pressed
    383456                        key = usbhid_parse_scancode(key_codes[i]);
    384                         usb_log_debug2("\nKey pressed: %d (keycode: %d)\n", key,
     457                        usb_log_debug2("Key pressed: %d (keycode: %d)\n", key,
    385458                            key_codes[i]);
    386459                        usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key);
     460                        usbhid_kbd_repeat_start(kbd_dev, key);
    387461                } else {
    388462                        // found, nothing happens
     
    390464        }
    391465       
    392         memcpy(kbd_dev->keycodes, key_codes, kbd_dev->keycode_count);
    393        
    394         usb_log_debug2("\nNew stored keycodes: ");
    395         for (i = 0; i < kbd_dev->keycode_count; ++i) {
    396                 usb_log_debug2("%d ", kbd_dev->keycodes[i]);
    397         }
     466        memcpy(kbd_dev->keys, key_codes, count);
     467
     468        usb_log_debug("New stored keycodes: %s\n",
     469            usb_debug_str_buffer(kbd_dev->keys, kbd_dev->key_count, 0));
    398470}
    399471
     
    401473/* Callbacks for parser                                                       */
    402474/*----------------------------------------------------------------------------*/
    403 
     475/**
     476 * Callback function for the HID report parser.
     477 *
     478 * This function is called by the HID report parser with the parsed report.
     479 * The parsed report is used to check if any events occured (key was pressed or
     480 * released, modifier was pressed or released).
     481 *
     482 * @param key_codes Parsed keyboard report - codes of currently pressed keys
     483 *                  according to HID Usage Tables.
     484 * @param count Number of key codes in report (size of the report).
     485 * @param modifiers Bitmap of modifiers (Ctrl, Alt, Shift, GUI).
     486 * @param arg User-specified argument. Expects pointer to the keyboard device
     487 *            structure representing the keyboard.
     488 *
     489 * @sa usbhid_kbd_check_key_changes(), usbhid_kbd_check_modifier_changes()
     490 */
    404491static void usbhid_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
    405492    uint8_t modifiers, void *arg)
     
    410497                return;
    411498        }
    412 
    413         usb_log_debug2("Got keys from parser: ");
    414         unsigned i;
    415         for (i = 0; i < count; ++i) {
    416                 usb_log_debug2("%d ", key_codes[i]);
    417         }
    418         usb_log_debug2("\n");
    419499       
    420500        usbhid_kbd_t *kbd_dev = (usbhid_kbd_t *)arg;
    421501        assert(kbd_dev != NULL);
    422        
    423         if (count != kbd_dev->keycode_count) {
     502
     503        usb_log_debug("Got keys from parser: %s\n",
     504            usb_debug_str_buffer(key_codes, kbd_dev->key_count, 0));
     505       
     506        if (count != kbd_dev->key_count) {
    424507                usb_log_warning("Number of received keycodes (%d) differs from"
    425                     " expected number (%d).\n", count, kbd_dev->keycode_count);
     508                    " expected number (%d).\n", count, kbd_dev->key_count);
    426509                return;
    427510        }
    428511       
    429512        usbhid_kbd_check_modifier_changes(kbd_dev, modifiers);
    430         usbhid_kbd_check_key_changes(kbd_dev, key_codes);
     513        usbhid_kbd_check_key_changes(kbd_dev, key_codes, count);
    431514}
    432515
     
    434517/* General kbd functions                                                      */
    435518/*----------------------------------------------------------------------------*/
    436 
     519/**
     520 * Processes data received from the device in form of report.
     521 *
     522 * This function uses the HID report parser to translate the data received from
     523 * the device into generic USB HID key codes and into generic modifiers bitmap.
     524 * The parser then calls the given callback (usbhid_kbd_process_keycodes()).
     525 *
     526 * @note Currently, only the boot protocol is supported.
     527 *
     528 * @param kbd_dev Keyboard device structure (must be initialized).
     529 * @param buffer Data from the keyboard (i.e. the report).
     530 * @param actual_size Size of the data from keyboard (report size) in bytes.
     531 *
     532 * @sa usbhid_kbd_process_keycodes(), usb_hid_boot_keyboard_input_report().
     533 */
    437534static void usbhid_kbd_process_data(usbhid_kbd_t *kbd_dev,
    438535                                    uint8_t *buffer, size_t actual_size)
     
    444541        callbacks->keyboard = usbhid_kbd_process_keycodes;
    445542
    446         //usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks,
    447         //    NULL);
    448         /*usb_log_debug2("Calling usb_hid_boot_keyboard_input_report() with size"
    449             " %zu\n", actual_size);*/
    450         //dump_buffer("bufffer: ", buffer, actual_size);
     543        usb_log_debug("Calling usb_hid_boot_keyboard_input_report() with "
     544            "buffer %s\n", usb_debug_str_buffer(buffer, actual_size, 0));
    451545       
    452546        int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
     
    462556/* HID/KBD structure manipulation                                             */
    463557/*----------------------------------------------------------------------------*/
    464 
     558/**
     559 * Creates a new USB/HID keyboard structure.
     560 *
     561 * The structure returned by this function is not initialized. Use
     562 * usbhid_kbd_init() to initialize it prior to polling.
     563 *
     564 * @return New uninitialized structure for representing a USB/HID keyboard or
     565 *         NULL if not successful (memory error).
     566 */
    465567static usbhid_kbd_t *usbhid_kbd_new(void)
    466568{
     
    488590
    489591/*----------------------------------------------------------------------------*/
    490 
     592/**
     593 * Properly destroys the USB/HID keyboard structure.
     594 *
     595 * @param kbd_dev Pointer to the structure to be destroyed.
     596 */
    491597static void usbhid_kbd_free(usbhid_kbd_t **kbd_dev)
    492598{
     
    503609        }
    504610       
     611        if ((*kbd_dev)->repeat_mtx != NULL) {
     612                /* TODO: replace by some check and wait */
     613                assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx));
     614                free((*kbd_dev)->repeat_mtx);
     615        }
     616       
    505617        free(*kbd_dev);
    506618        *kbd_dev = NULL;
     
    508620
    509621/*----------------------------------------------------------------------------*/
    510 
     622/**
     623 * Initialization of the USB/HID keyboard structure.
     624 *
     625 * This functions initializes required structures from the device's descriptors.
     626 *
     627 * During initialization, the keyboard is switched into boot protocol, the idle
     628 * rate is set to 0 (infinity), resulting in the keyboard only reporting event
     629 * when a key is pressed or released. Finally, the LED lights are turned on
     630 * according to the default setup of lock keys.
     631 *
     632 * @note By default, the keyboards is initialized with Num Lock turned on and
     633 *       other locks turned off.
     634 *
     635 * @param kbd_dev Keyboard device structure to be initialized.
     636 * @param dev DDF device structure of the keyboard.
     637 *
     638 * @retval EOK if successful.
     639 * @retval EINVAL if some parameter is not given.
     640 * @return Other value inherited from function usbhid_dev_init().
     641 */
    511642static int usbhid_kbd_init(usbhid_kbd_t *kbd_dev, ddf_dev_t *dev)
    512643{
     
    543674       
    544675        // save the size of the report (boot protocol report by default)
    545         kbd_dev->keycode_count = BOOTP_REPORT_SIZE;
    546         kbd_dev->keycodes = (uint8_t *)calloc(
    547             kbd_dev->keycode_count, sizeof(uint8_t));
    548        
    549         if (kbd_dev->keycodes == NULL) {
     676        kbd_dev->key_count = BOOTP_REPORT_SIZE;
     677        kbd_dev->keys = (uint8_t *)calloc(
     678            kbd_dev->key_count, sizeof(uint8_t));
     679       
     680        if (kbd_dev->keys == NULL) {
    550681                usb_log_fatal("No memory!\n");
    551                 return rc;
     682                return ENOMEM;
    552683        }
    553684       
     
    556687        kbd_dev->lock_keys = 0;
    557688       
     689        kbd_dev->repeat.key_new = 0;
     690        kbd_dev->repeat.key_repeated = 0;
     691        kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT;
     692        kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY;
     693       
     694        kbd_dev->repeat_mtx = (fibril_mutex_t *)(
     695            malloc(sizeof(fibril_mutex_t)));
     696        if (kbd_dev->repeat_mtx == NULL) {
     697                usb_log_fatal("No memory!\n");
     698                free(kbd_dev->keys);
     699                return ENOMEM;
     700        }
     701       
     702        fibril_mutex_initialize(kbd_dev->repeat_mtx);
     703       
    558704        /*
    559705         * Set boot protocol.
    560706         * Set LEDs according to initial setup.
     707         * Set Idle rate
    561708         */
    562709        assert(kbd_dev->hid_dev != NULL);
     
    566713        usbhid_kbd_set_led(kbd_dev);
    567714       
     715        usbhid_req_set_idle(kbd_dev->hid_dev, IDLE_RATE);
     716       
    568717        kbd_dev->initialized = 1;
    569718        usb_log_info("HID/KBD device structure initialized.\n");
     
    575724/* HID/KBD polling                                                            */
    576725/*----------------------------------------------------------------------------*/
    577 
     726/**
     727 * Main keyboard polling function.
     728 *
     729 * This function uses the Interrupt In pipe of the keyboard to poll for events.
     730 * The keyboard is initialized in a way that it reports only when a key is
     731 * pressed or released, so there is no actual need for any sleeping between
     732 * polls (see usbhid_kbd_try_add_device() or usbhid_kbd_init()).
     733 *
     734 * @param kbd_dev Initialized keyboard structure representing the device to
     735 *                poll.
     736 *
     737 * @sa usbhid_kbd_process_data()
     738 */
    578739static void usbhid_kbd_poll(usbhid_kbd_t *kbd_dev)
    579740{
     
    598759                        usb_log_warning("Failed to start a session: %s.\n",
    599760                            str_error(sess_rc));
    600                         continue;
     761                        break;
    601762                }
    602763
     
    610771                        usb_log_warning("Error polling the keyboard: %s.\n",
    611772                            str_error(rc));
    612                         continue;
     773                        break;
    613774                }
    614775
     
    616777                        usb_log_warning("Error closing session: %s.\n",
    617778                            str_error(sess_rc));
    618                         continue;
     779                        break;
    619780                }
    620781
     
    634795                usbhid_kbd_process_data(kbd_dev, buffer, actual_size);
    635796               
    636                 async_usleep(kbd_dev->hid_dev->poll_interval);
    637         }
    638 
    639         // not reached
    640         assert(0);
    641 }
    642 
    643 /*----------------------------------------------------------------------------*/
    644 
     797                // disabled for now, no reason to sleep
     798                //async_usleep(kbd_dev->hid_dev->poll_interval);
     799        }
     800}
     801
     802/*----------------------------------------------------------------------------*/
     803/**
     804 * Function executed by the main driver fibril.
     805 *
     806 * Just starts polling the keyboard for events.
     807 *
     808 * @param arg Initialized keyboard device structure (of type usbhid_kbd_t)
     809 *            representing the device.
     810 *
     811 * @retval EOK if the fibril finished polling the device.
     812 * @retval EINVAL if no device was given in the argument.
     813 *
     814 * @sa usbhid_kbd_poll()
     815 *
     816 * @todo Change return value - only case when the fibril finishes is in case
     817 *       of some error, so the error should probably be propagated from function
     818 *       usbhid_kbd_poll() to here and up.
     819 */
    645820static int usbhid_kbd_fibril(void *arg)
    646821{
     
    664839/* API functions                                                              */
    665840/*----------------------------------------------------------------------------*/
    666 
     841/**
     842 * Function for adding a new device of type USB/HID/keyboard.
     843 *
     844 * This functions initializes required structures from the device's descriptors
     845 * and starts new fibril for polling the keyboard for events and another one for
     846 * handling auto-repeat of keys.
     847 *
     848 * During initialization, the keyboard is switched into boot protocol, the idle
     849 * rate is set to 0 (infinity), resulting in the keyboard only reporting event
     850 * when a key is pressed or released. Finally, the LED lights are turned on
     851 * according to the default setup of lock keys.
     852 *
     853 * @note By default, the keyboards is initialized with Num Lock turned on and
     854 *       other locks turned off.
     855 * @note Currently supports only boot-protocol keyboards.
     856 *
     857 * @param dev Device to add.
     858 *
     859 * @retval EOK if successful.
     860 * @retval ENOMEM if there
     861 * @return Other error code inherited from one of functions usbhid_kbd_init(),
     862 *         ddf_fun_bind() and ddf_fun_add_to_class().
     863 *
     864 * @sa usbhid_kbd_fibril(), usbhid_kbd_repeat_fibril()
     865 */
    667866int usbhid_kbd_try_add_device(ddf_dev_t *dev)
    668867{
     
    686885                    "structure.\n");
    687886                ddf_fun_destroy(kbd_fun);
    688                 return EINVAL;  // TODO: some other code??
     887                return ENOMEM;  // TODO: some other code??
    689888        }
    690889       
     
    735934        }
    736935        fibril_add_ready(fid);
     936       
     937        /*
     938         * Create new fibril for auto-repeat
     939         */
     940        fid = fibril_create(usbhid_kbd_repeat_fibril, kbd_dev);
     941        if (fid == 0) {
     942                usb_log_error("Failed to start fibril for KBD auto-repeat");
     943                return ENOMEM;
     944        }
     945        fibril_add_ready(fid);
    737946
    738947        (void)keyboard_ops;
Note: See TracChangeset for help on using the changeset viewer.