Ignore:
File:
1 edited

Legend:

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

    rdfe53af rd477734  
    3737#include <errno.h>
    3838#include <str_error.h>
     39#include <fibril.h>
    3940#include <stdio.h>
    4041
     
    4243#include <ipc/kbd.h>
    4344#include <async.h>
    44 #include <fibril.h>
    45 #include <fibril_synch.h>
    4645
    4746#include <usb/usb.h>
     
    5756#include "layout.h"
    5857#include "conv.h"
    59 #include "kbdrepeat.h"
    6058
    6159/*----------------------------------------------------------------------------*/
     
    6765static const uint8_t BOOTP_ERROR_ROLLOVER = 1;
    6866static const uint8_t IDLE_RATE = 0;
    69 static const unsigned int DEFAULT_DELAY_BEFORE_FIRST_REPEAT = 500 * 1000;
    70 static const unsigned int DEFAULT_REPEAT_DELAY = 50 * 1000;
    7167
    7268/** Keyboard polling endpoint description for boot protocol class. */
     
    194190/*----------------------------------------------------------------------------*/
    195191
    196 void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key)
     192static void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type,
     193    unsigned int key)
    197194{
    198195        console_event_t ev;
    199196        unsigned mod_mask;
    200197
    201         /*
    202          * These parts are copy-pasted from the AT keyboard driver.
    203          *
    204          * They definitely require some refactoring, but will keep it for later
    205          * when the console and keyboard system is changed in HelenOS.
    206          */
     198        // TODO: replace by our own parsing?? or are the key codes identical??
    207199        switch (key) {
    208200        case KC_LCTRL: mod_mask = KM_LCTRL; break;
     
    236228                         * up the lock state.
    237229                         */
    238                         unsigned int locks_old = kbd_dev->lock_keys;
    239                        
    240230                        kbd_dev->mods =
    241231                            kbd_dev->mods ^ (mod_mask & ~kbd_dev->lock_keys);
     
    243233
    244234                        /* Update keyboard lock indicator lights. */
    245                         if (kbd_dev->lock_keys != locks_old) {
    246                                 usbhid_kbd_set_led(kbd_dev);
    247                         }
     235                        usbhid_kbd_set_led(kbd_dev);
    248236                } else {
    249237                        kbd_dev->lock_keys = kbd_dev->lock_keys & ~mod_mask;
     
    340328        i = 0;
    341329        // all fields should report Error Rollover
    342         while (i < kbd_dev->key_count &&
     330        while (i < kbd_dev->keycode_count &&
    343331            key_codes[i] == BOOTP_ERROR_ROLLOVER) {
    344332                ++i;
    345333        }
    346         if (i == kbd_dev->key_count) {
     334        if (i == kbd_dev->keycode_count) {
    347335                usb_log_debug("Phantom state occured.\n");
    348336                // phantom state, do nothing
     
    355343         * 1) Key releases
    356344         */
    357         for (j = 0; j < kbd_dev->key_count; ++j) {
     345        for (j = 0; j < kbd_dev->keycode_count; ++j) {
    358346                // try to find the old key in the new key list
    359347                i = 0;
    360                 while (i < kbd_dev->key_count
    361                     && key_codes[i] != kbd_dev->keys[j]) {
     348                while (i < kbd_dev->keycode_count
     349                    && key_codes[i] != kbd_dev->keycodes[j]) {
    362350                        ++i;
    363351                }
    364352               
    365                 if (i == kbd_dev->key_count) {
     353                if (i == kbd_dev->keycode_count) {
    366354                        // not found, i.e. the key was released
    367                         key = usbhid_parse_scancode(kbd_dev->keys[j]);
    368                         usbhid_kbd_repeat_stop(kbd_dev, key);
     355                        key = usbhid_parse_scancode(kbd_dev->keycodes[j]);
    369356                        usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, key);
    370357                        usb_log_debug2("Key released: %d\n", key);
     
    377364         * 1) Key presses
    378365         */
    379         for (i = 0; i < kbd_dev->key_count; ++i) {
     366        for (i = 0; i < kbd_dev->keycode_count; ++i) {
    380367                // try to find the new key in the old key list
    381368                j = 0;
    382                 while (j < kbd_dev->key_count
    383                     && kbd_dev->keys[j] != key_codes[i]) {
     369                while (j < kbd_dev->keycode_count
     370                    && kbd_dev->keycodes[j] != key_codes[i]) {
    384371                        ++j;
    385372                }
    386373               
    387                 if (j == kbd_dev->key_count) {
     374                if (j == kbd_dev->keycode_count) {
    388375                        // not found, i.e. new key pressed
    389376                        key = usbhid_parse_scancode(key_codes[i]);
     
    391378                            key_codes[i]);
    392379                        usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key);
    393                         usbhid_kbd_repeat_start(kbd_dev, key);
    394380                } else {
    395381                        // found, nothing happens
     
    406392//      }
    407393       
    408         memcpy(kbd_dev->keys, key_codes, kbd_dev->key_count);
     394        memcpy(kbd_dev->keycodes, key_codes, kbd_dev->keycode_count);
    409395
    410396        usb_log_debug("New stored keycodes: %s\n",
    411             usb_debug_str_buffer(kbd_dev->keys, kbd_dev->key_count, 0));
     397            usb_debug_str_buffer(kbd_dev->keycodes, kbd_dev->keycode_count, 0));
    412398}
    413399
     
    429415
    430416        usb_log_debug("Got keys from parser: %s\n",
    431             usb_debug_str_buffer(key_codes, kbd_dev->key_count, 0));
    432        
    433         if (count != kbd_dev->key_count) {
     417            usb_debug_str_buffer(key_codes, kbd_dev->keycode_count, 0));
     418       
     419        if (count != kbd_dev->keycode_count) {
    434420                usb_log_warning("Number of received keycodes (%d) differs from"
    435                     " expected number (%d).\n", count, kbd_dev->key_count);
     421                    " expected number (%d).\n", count, kbd_dev->keycode_count);
    436422                return;
    437423        }
     
    444430/* General kbd functions                                                      */
    445431/*----------------------------------------------------------------------------*/
    446 /**
    447  * Processes data received from the device in form of report.
    448  *
    449  * This function uses the HID report parser to translate the data received from
    450  * the device into generic USB HID key codes and into generic modifiers bitmap.
    451  * The parser then calls the given callback (usbhid_kbd_process_keycodes()).
    452  *
    453  * @note Currently, only the boot protocol is supported.
    454  *
    455  * @param kbd_dev Keyboard device structure (must be initialized).
    456  * @param buffer Data from the keyboard (i.e. the report).
    457  * @param actual_size Size of the data from keyboard (report size) in bytes.
    458  *
    459  * @sa usbhid_kbd_process_keycodes(), usb_hid_boot_keyboard_input_report().
    460  */
     432
    461433static void usbhid_kbd_process_data(usbhid_kbd_t *kbd_dev,
    462434                                    uint8_t *buffer, size_t actual_size)
     
    483455/* HID/KBD structure manipulation                                             */
    484456/*----------------------------------------------------------------------------*/
    485 /**
    486  * Creates a new USB/HID keyboard structure.
    487  *
    488  * The structure returned by this function is not initialized. Use
    489  * usbhid_kbd_init() to initialize it prior to polling.
    490  *
    491  * @return New uninitialized structure for representing a USB/HID keyboard or
    492  *         NULL if not successful (memory error).
    493  */
     457
    494458static usbhid_kbd_t *usbhid_kbd_new(void)
    495459{
     
    517481
    518482/*----------------------------------------------------------------------------*/
    519 /**
    520  * Properly destroys the USB/HID keyboard structure.
    521  *
    522  * @param kbd_dev Pointer to the structure to be destroyed.
    523  */
     483
    524484static void usbhid_kbd_free(usbhid_kbd_t **kbd_dev)
    525485{
     
    536496        }
    537497       
    538         if ((*kbd_dev)->repeat_mtx != NULL) {
    539                 /* TODO: replace by some check and wait */
    540                 assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx));
    541                 free((*kbd_dev)->repeat_mtx);
    542         }
    543        
    544498        free(*kbd_dev);
    545499        *kbd_dev = NULL;
     
    547501
    548502/*----------------------------------------------------------------------------*/
    549 /**
    550  * Initialization of the USB/HID keyboard structure.
    551  *
    552  * This functions initializes required structures from the device's descriptors.
    553  *
    554  * During initialization, the keyboard is switched into boot protocol, the idle
    555  * rate is set to 0 (infinity), resulting in the keyboard only reporting event
    556  * when a key is pressed or released. Finally, the LED lights are turned on
    557  * according to the default setup of lock keys.
    558  *
    559  * @note By default, the keyboards is initialized with Num Lock turned on and
    560  *       other locks turned off.
    561  *
    562  * @param kbd_dev Keyboard device structure to be initialized.
    563  * @param dev DDF device structure of the keyboard.
    564  *
    565  * @retval EOK if successful.
    566  * @retval EINVAL if some parameter is not given.
    567  * @return Other value inherited from function usbhid_dev_init().
    568  */
     503
    569504static int usbhid_kbd_init(usbhid_kbd_t *kbd_dev, ddf_dev_t *dev)
    570505{
     
    601536       
    602537        // save the size of the report (boot protocol report by default)
    603         kbd_dev->key_count = BOOTP_REPORT_SIZE;
    604         kbd_dev->keys = (uint8_t *)calloc(
    605             kbd_dev->key_count, sizeof(uint8_t));
    606        
    607         if (kbd_dev->keys == NULL) {
     538        kbd_dev->keycode_count = BOOTP_REPORT_SIZE;
     539        kbd_dev->keycodes = (uint8_t *)calloc(
     540            kbd_dev->keycode_count, sizeof(uint8_t));
     541       
     542        if (kbd_dev->keycodes == NULL) {
    608543                usb_log_fatal("No memory!\n");
    609                 return ENOMEM;
     544                return rc;
    610545        }
    611546       
     
    614549        kbd_dev->lock_keys = 0;
    615550       
    616         kbd_dev->repeat.key_new = 0;
    617         kbd_dev->repeat.key_repeated = 0;
    618         kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT;
    619         kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY;
    620        
    621         kbd_dev->repeat_mtx = (fibril_mutex_t *)(
    622             malloc(sizeof(fibril_mutex_t)));
    623         if (kbd_dev->repeat_mtx == NULL) {
    624                 usb_log_fatal("No memory!\n");
    625                 free(kbd_dev->keys);
    626                 return ENOMEM;
    627         }
    628        
    629         fibril_mutex_initialize(kbd_dev->repeat_mtx);
    630        
    631551        /*
    632552         * Set boot protocol.
     
    651571/* HID/KBD polling                                                            */
    652572/*----------------------------------------------------------------------------*/
    653 /**
    654  * Main keyboard polling function.
    655  *
    656  * This function uses the Interrupt In pipe of the keyboard to poll for events.
    657  * The keyboard is initialized in a way that it reports only when a key is
    658  * pressed or released, so there is no actual need for any sleeping between
    659  * polls (see usbhid_kbd_try_add_device() or usbhid_kbd_init()).
    660  *
    661  * @param kbd_dev Initialized keyboard structure representing the device to
    662  *                poll.
    663  *
    664  * @sa usbhid_kbd_process_data()
    665  */
     573
    666574static void usbhid_kbd_poll(usbhid_kbd_t *kbd_dev)
    667575{
     
    731639
    732640/*----------------------------------------------------------------------------*/
    733 /**
    734  * Function executed by the main driver fibril.
    735  *
    736  * Just starts polling the keyboard for events.
    737  *
    738  * @param arg Initialized keyboard device structure (of type usbhid_kbd_t)
    739  *            representing the device.
    740  *
    741  * @retval EOK if the fibril finished polling the device.
    742  * @retval EINVAL if no device was given in the argument.
    743  *
    744  * @sa usbhid_kbd_poll()
    745  *
    746  * @todo Change return value - only case when the fibril finishes is in case
    747  *       of some error, so the error should probably be propagated from function
    748  *       usbhid_kbd_poll() to here and up.
    749  */
     641
    750642static int usbhid_kbd_fibril(void *arg)
    751643{
     
    769661/* API functions                                                              */
    770662/*----------------------------------------------------------------------------*/
    771 /**
    772  * Function for adding a new device of type USB/HID/keyboard.
    773  *
    774  * This functions initializes required structures from the device's descriptors
    775  * and starts a new fibril for polling the keyboard for events.
    776  *
    777  * During initialization, the keyboard is switched into boot protocol, the idle
    778  * rate is set to 0 (infinity), resulting in the keyboard only reporting event
    779  * when a key is pressed or released. Finally, the LED lights are turned on
    780  * according to the default setup of lock keys.
    781  *
    782  * @note By default, the keyboards is initialized with Num Lock turned on and
    783  *       other locks turned off.
    784  * @note Currently supports only boot-protocol keyboards.
    785  *
    786  * @param dev Device to add.
    787  *
    788  * @retval EOK if successful.
    789  * @retval ENOMEM if there
    790  * @return Other error code inherited from one of functions usbhid_kbd_init(),
    791  *         ddf_fun_bind() and ddf_fun_add_to_class().
    792  *
    793  * @sa usbhid_kbd_fibril()
    794  */
     663
    795664int usbhid_kbd_try_add_device(ddf_dev_t *dev)
    796665{
     
    814683                    "structure.\n");
    815684                ddf_fun_destroy(kbd_fun);
    816                 return ENOMEM;  // TODO: some other code??
     685                return EINVAL;  // TODO: some other code??
    817686        }
    818687       
     
    863732        }
    864733        fibril_add_ready(fid);
    865        
    866         /*
    867          * Create new fibril for auto-repeat
    868          */
    869         fid = fibril_create(usbhid_kbd_repeat_fibril, kbd_dev);
    870         if (fid == 0) {
    871                 usb_log_error("Failed to start fibril for KBD auto-repeat");
    872                 return ENOMEM;
    873         }
    874         fibril_add_ready(fid);
    875734
    876735        (void)keyboard_ops;
Note: See TracChangeset for help on using the changeset viewer.