Changes in / [c0964800:0c8562c] in mainline


Ignore:
Files:
2 added
11 edited

Legend:

Unmodified
Added
Removed
  • dist/Makefile

    rc0964800 r0c8562c  
    4343
    4444SUFFIX = $(suffix $(IMGFILE))
    45 DISTFILE = HelenOS-$(RELEASE)-$(PLATFORM)-$(MACHINE)-$(PROCESSOR)$(SUFFIX)
     45
     46ifdef PROFILE
     47        DISTFILE = Helenos-$(shell echo $(PROFILE) | tr '/' '-')$(SUFFIX)
     48else
     49        DISTFILE = HelenOS-$(RELEASE)-$(PLATFORM)-$(MACHINE)-$(PROCESSOR)$(SUFFIX)
     50endif
    4651
    4752.PHONY: all clean dist distfile
     
    5358        cp $< $@
    5459
     60$(IMGFILE):
     61        $(MAKE) -C ..
     62
    5563dist:
    5664        for profile in $(PROFILES); do \
  • uspace/drv/usbhid/Makefile

    rc0964800 r0c8562c  
    4242        hidreq.c \
    4343        kbddev.c \
     44        kbdrepeat.c \
    4445        hiddev.c \
    4546        $(STOLEN_LAYOUT_SOURCES)
  • uspace/drv/usbhid/conv.c

    rc0964800 r0c8562c  
    4040#include "conv.h"
    4141
     42/**
     43 * Mapping between USB HID key codes (from HID Usage Tables) and corresponding
     44 * HelenOS key codes.
     45 */
    4246static int scanmap_simple[255] = {
    4347
     
    163167};
    164168
     169/**
     170 * Translate USB HID key codes (from HID Usage Tables) to generic key codes
     171 * recognized by HelenOS.
     172 *
     173 * @param scancode USB HID key code (from HID Usage Tables).
     174 *
     175 * @retval HelenOS key code corresponding to the given USB HID key code.
     176 */
    165177unsigned int usbhid_parse_scancode(int scancode)
    166178{
  • uspace/drv/usbhid/descdump.c

    rc0964800 r0c8562c  
    4444#define BYTES_PER_LINE 12
    4545
     46/**
     47 * Dumps the given buffer in hexadecimal format to standard output.
     48 *
     49 * @param msg Message to print before the buffer.
     50 * @param buffer Buffer to print.
     51 * @param length Size of the buffer in bytes.
     52 */
    4653static void dump_buffer(const char *msg, const uint8_t *buffer, size_t length)
    4754{
     
    6269#define INDENT "  "
    6370
     71/**
     72 * Print standard configuration descriptor to standard output.
     73 *
     74 * @param index Index of the descriptor.
     75 * @param d Standard configuration descriptor to print.
     76 */
    6477void dump_standard_configuration_descriptor(
    6578    int index, const usb_standard_configuration_descriptor_t *d)
     
    8497}
    8598
     99/**
     100 * Print standard interface descriptor to standard output.
     101 *
     102 * @param d Standard interface descriptor to print.
     103 */
    86104void dump_standard_interface_descriptor(
    87105    const usb_standard_interface_descriptor_t *d)
     
    99117}
    100118
     119/**
     120 * Print standard endpoint descriptor to standard output.
     121 *
     122 * @param d Standard endpoint descriptor to print.
     123 */
    101124void dump_standard_endpoint_descriptor(
    102125    const usb_standard_endpoint_descriptor_t *d)
     
    126149}
    127150
     151/**
     152 * Print standard HID descriptor to standard output.
     153 *
     154 * @param d Standard HID descriptor to print.
     155 */
    128156void dump_standard_hid_descriptor_header(
    129157    const usb_standard_hid_descriptor_t *d)
     
    139167}
    140168
     169/**
     170 * Print HID class-specific descriptor header (type and length) to standard
     171 * output.
     172 *
     173 * @param d HID class-specific descriptor header to print.
     174 */
    141175void dump_standard_hid_class_descriptor_info(
    142176    const usb_standard_hid_class_descriptor_info_t *d)
     
    146180}
    147181
     182/**
     183 * Print HID class-specific descriptor (without the header) to standard output.
     184 *
     185 * @param index Index of the descriptor.
     186 * @param type Type of the HID class-specific descriptor (Report or Physical).
     187 * @param d HID class descriptor to print.
     188 * @param size Size of the descriptor in bytes.
     189 */
    148190void dump_hid_class_descriptor(int index, uint8_t type,
    149191    const uint8_t *d, size_t size )
  • uspace/drv/usbhid/hiddev.c

    rc0964800 r0c8562c  
    5353/* Non-API functions                                                          */
    5454/*----------------------------------------------------------------------------*/
    55 
     55/**
     56 * Retreives HID Report descriptor from the device.
     57 *
     58 * This function first parses the HID descriptor from the Interface descriptor
     59 * to get the size of the Report descriptor and then requests the Report
     60 * descriptor from the device.
     61 *
     62 * @param hid_dev HID device structure.
     63 * @param config_desc Full configuration descriptor (including all nested
     64 *                    descriptors).
     65 * @param config_desc_size Size of the full configuration descriptor (in bytes).
     66 * @param iface_desc Pointer to the interface descriptor inside the full
     67 *                   configuration descriptor (@a config_desc) for the interface
     68 *                   assigned with this device (@a hid_dev).
     69 *
     70 * @retval EOK if successful.
     71 * @retval ENOENT if no HID descriptor could be found.
     72 * @retval EINVAL if the HID descriptor  or HID report descriptor have different
     73 *                size than expected.
     74 * @retval ENOMEM if some allocation failed.
     75 * @return Other value inherited from function usb_request_get_descriptor().
     76 *
     77 * @sa usb_request_get_descriptor()
     78 */
    5679static int usbhid_dev_get_report_descriptor(usbhid_dev_t *hid_dev,
    5780    uint8_t *config_desc, size_t config_desc_size, uint8_t *iface_desc)
     
    141164
    142165/*----------------------------------------------------------------------------*/
    143 
     166/**
     167 * Retreives descriptors from the device, initializes pipes and stores
     168 * important information from descriptors.
     169 *
     170 * Initializes the polling pipe described by the given endpoint description
     171 * (@a poll_ep_desc).
     172 *
     173 * Information retreived from descriptors and stored in the HID device structure:
     174 *    - Assigned interface number (the interface controlled by this instance of
     175 *                                 the driver)
     176 *    - Polling interval (from the interface descriptor)
     177 *    - Report descriptor
     178 *
     179 * @param hid_dev HID device structure to be initialized.
     180 * @param poll_ep_desc Description of the polling (Interrupt In) endpoint
     181 *                     that has to be present in the device in order to
     182 *                     successfuly initialize the structure.
     183 *
     184 * @sa usb_endpoint_pipe_initialize_from_configuration(),
     185 *     usbhid_dev_get_report_descriptor()
     186 */
    144187static int usbhid_dev_process_descriptors(usbhid_dev_t *hid_dev,
    145188    usb_endpoint_description_t *poll_ep_desc)
     
    230273/* API functions                                                              */
    231274/*----------------------------------------------------------------------------*/
    232 
     275/**
     276 * Creates new uninitialized HID device structure.
     277 *
     278 * @return Pointer to the new HID device structure, or NULL if an error occured.
     279 */
    233280usbhid_dev_t *usbhid_dev_new(void)
    234281{
     
    249296
    250297/*----------------------------------------------------------------------------*/
    251 
     298/**
     299 * Properly destroys the HID device structure.
     300 *
     301 * @note Currently does not clean-up the used pipes, as there are no functions
     302 *       offering such functionality.
     303 *
     304 * @param hid_dev Pointer to the structure to be destroyed.
     305 */
    252306void usbhid_dev_free(usbhid_dev_t **hid_dev)
    253307{
     
    272326
    273327/*----------------------------------------------------------------------------*/
    274 
     328/**
     329 * Initializes HID device structure.
     330 *
     331 * @param hid_dev HID device structure to be initialized.
     332 * @param dev DDF device representing the HID device.
     333 * @param poll_ep_desc Description of the polling (Interrupt In) endpoint
     334 *                     that has to be present in the device in order to
     335 *                     successfuly initialize the structure.
     336 *
     337 * @retval EOK if successful.
     338 * @retval EINVAL if some argument is missing.
     339 * @return Other value inherited from one of functions
     340 *         usb_device_connection_initialize_from_device(),
     341 *         usb_endpoint_pipe_initialize_default_control(),
     342 *         usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(),
     343 *         usbhid_dev_process_descriptors().
     344 *
     345 * @sa usbhid_dev_process_descriptors()
     346 */
    275347int usbhid_dev_init(usbhid_dev_t *hid_dev, ddf_dev_t *dev,
    276348    usb_endpoint_description_t *poll_ep_desc)
     
    323395         * Get descriptors, parse descriptors and save endpoints.
    324396         */
    325         usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
     397        rc = usb_endpoint_pipe_start_session(&hid_dev->ctrl_pipe);
     398        if (rc != EOK) {
     399                usb_log_error("Failed to start session on the control pipe: %s"
     400                    ".\n", str_error(rc));
     401                return rc;
     402        }
    326403       
    327404        rc = usbhid_dev_process_descriptors(hid_dev, poll_ep_desc);
    328        
    329         usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
    330         if (rc != EOK) {
     405        if (rc != EOK) {
     406                /* TODO: end session?? */
    331407                usb_log_error("Failed to process descriptors: %s.\n",
    332408                    str_error(rc));
     
    334410        }
    335411       
     412        rc = usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
     413        if (rc != EOK) {
     414                usb_log_warning("Failed to start session on the control pipe: "
     415                    "%s.\n", str_error(rc));
     416                return rc;
     417        }
     418       
    336419        hid_dev->initialized = 1;
    337420        usb_log_info("HID device structure initialized.\n");
  • uspace/drv/usbhid/hiddev.h

    rc0964800 r0c8562c  
    4848
    4949/**
    50  * @brief USB/HID device type.
     50 * USB/HID device type.
     51 *
     52 * Holds a reference to DDF device structure, and HID-specific data, such
     53 * as information about used pipes (one Control pipe and one Interrupt In pipe),
     54 * polling interval, assigned interface number, Report descriptor and a
     55 * reference to the Report parser used to parse incoming reports and composing
     56 * outgoing reports.
    5157 */
    5258typedef struct {
     59        /** DDF device representing the controlled HID device. */
    5360        ddf_dev_t *device;
    5461
     62        /** Physical connection to the device. */
    5563        usb_device_connection_t wire;
     64        /** USB pipe corresponding to the default Control endpoint. */
    5665        usb_endpoint_pipe_t ctrl_pipe;
     66        /** USB pipe corresponding to the Interrupt In (polling) pipe. */
    5767        usb_endpoint_pipe_t poll_pipe;
    5868       
     69        /** Polling interval retreived from the Interface descriptor. */
    5970        short poll_interval;
    6071       
     72        /** Interface number assigned to this device. */
    6173        uint16_t iface;
    6274       
     75        /** Report descriptor. */
    6376        uint8_t *report_desc;
     77        /** HID Report parser. */
    6478        usb_hid_report_parser_t *parser;
    6579       
     80        /** State of the structure (for checking before use). */
    6681        int initialized;
    6782} usbhid_dev_t;
  • uspace/drv/usbhid/hidreq.c

    rc0964800 r0c8562c  
    4646
    4747/*----------------------------------------------------------------------------*/
    48 
     48/**
     49 * Send Set Report request to the HID device.
     50 *
     51 * @param hid_dev HID device to send the request to.
     52 * @param type Type of the report.
     53 * @param buffer Report data.
     54 * @param buf_size Report data size (in bytes).
     55 *
     56 * @retval EOK if successful.
     57 * @retval EINVAL if no HID device is given.
     58 * @return Other value inherited from one of functions
     59 *         usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(),
     60 *         usb_control_request_set().
     61 */
    4962int usbhid_req_set_report(usbhid_dev_t *hid_dev,
    5063    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size)
     
    97110
    98111/*----------------------------------------------------------------------------*/
    99 
     112/**
     113 * Send Set Protocol request to the HID device.
     114 *
     115 * @param hid_dev HID device to send the request to.
     116 * @param protocol Protocol to set.
     117 *
     118 * @retval EOK if successful.
     119 * @retval EINVAL if no HID device is given.
     120 * @return Other value inherited from one of functions
     121 *         usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(),
     122 *         usb_control_request_set().
     123 */
    100124int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol)
    101125{
     
    145169
    146170/*----------------------------------------------------------------------------*/
    147 
     171/**
     172 * Send Set Idle request to the HID device.
     173 *
     174 * @param hid_dev HID device to send the request to.
     175 * @param duration Duration value (is multiplicated by 4 by the device to
     176 *                 get real duration in miliseconds).
     177 *
     178 * @retval EOK if successful.
     179 * @retval EINVAL if no HID device is given.
     180 * @return Other value inherited from one of functions
     181 *         usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(),
     182 *         usb_control_request_set().
     183 */
    148184int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration)
    149185{
     
    195231
    196232/*----------------------------------------------------------------------------*/
    197 
     233/**
     234 * Send Get Report request to the HID device.
     235 *
     236 * @param[in] hid_dev HID device to send the request to.
     237 * @param[in] type Type of the report.
     238 * @param[in][out] buffer Buffer for the report data.
     239 * @param[in] buf_size Size of the buffer (in bytes).
     240 * @param[out] actual_size Actual size of report received from the device
     241 *                         (in bytes).
     242 *
     243 * @retval EOK if successful.
     244 * @retval EINVAL if no HID device is given.
     245 * @return Other value inherited from one of functions
     246 *         usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(),
     247 *         usb_control_request_set().
     248 */
    198249int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type,
    199250    uint8_t *buffer, size_t buf_size, size_t *actual_size)
     
    246297}
    247298
     299/*----------------------------------------------------------------------------*/
     300/**
     301 * Send Get Protocol request to the HID device.
     302 *
     303 * @param[in] hid_dev HID device to send the request to.
     304 * @param[out] protocol Current protocol of the device.
     305 *
     306 * @retval EOK if successful.
     307 * @retval EINVAL if no HID device is given.
     308 * @return Other value inherited from one of functions
     309 *         usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(),
     310 *         usb_control_request_set().
     311 */
    248312int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol)
    249313{
     
    303367}
    304368
     369/*----------------------------------------------------------------------------*/
     370/**
     371 * Send Get Idle request to the HID device.
     372 *
     373 * @param[in] hid_dev HID device to send the request to.
     374 * @param[out] duration Duration value (multiplicate by 4 to get real duration
     375 *                      in miliseconds).
     376 *
     377 * @retval EOK if successful.
     378 * @retval EINVAL if no HID device is given.
     379 * @return Other value inherited from one of functions
     380 *         usb_endpoint_pipe_start_session(), usb_endpoint_pipe_end_session(),
     381 *         usb_control_request_set().
     382 */
    305383int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration)
    306384{
  • uspace/drv/usbhid/kbddev.c

    rc0964800 r0c8562c  
    3737#include <errno.h>
    3838#include <str_error.h>
    39 #include <fibril.h>
    4039#include <stdio.h>
    4140
     
    4342#include <ipc/kbd.h>
    4443#include <async.h>
     44#include <fibril.h>
     45#include <fibril_synch.h>
    4546
    4647#include <usb/usb.h>
     
    5657#include "layout.h"
    5758#include "conv.h"
    58 
    59 /*----------------------------------------------------------------------------*/
    60 
     59#include "kbdrepeat.h"
     60
     61/*----------------------------------------------------------------------------*/
     62/** Default modifiers when the keyboard is initialized. */
    6163static const unsigned DEFAULT_ACTIVE_MODS = KM_NUM_LOCK;
     64
     65/** Boot protocol report size (key part). */
    6266static const size_t BOOTP_REPORT_SIZE = 6;
     67
     68/** Boot protocol total report size. */
    6369static const size_t BOOTP_BUFFER_SIZE = 8;
     70
     71/** Boot protocol output report size. */
    6472static const size_t BOOTP_BUFFER_OUT_SIZE = 1;
     73
     74/** Boot protocol error key code. */
    6575static const uint8_t BOOTP_ERROR_ROLLOVER = 1;
     76
     77/** Default idle rate for keyboards. */
    6678static 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;
    6785
    6886/** Keyboard polling endpoint description for boot protocol class. */
     
    82100#define NUM_LAYOUTS 3
    83101
     102/** Keyboard layout map. */
    84103static layout_op_t *layout[NUM_LAYOUTS] = {
    85104        &us_qwerty_op,
     
    93112/* Modifier constants                                                         */
    94113/*----------------------------------------------------------------------------*/
    95 
     114/** Mapping of USB modifier key codes to generic modifier key codes. */
    96115static const keycode_t usbhid_modifiers_keycodes[USB_HID_MOD_COUNT] = {
    97116        KC_LCTRL,         /* USB_HID_MOD_LCTRL */
     
    114133};
    115134
    116 /** Default handler for IPC methods not handled by DDF.
    117  *
    118  * @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.
    119143 * @param icallid Call id.
    120144 * @param icall Call data.
     
    147171/* Key processing functions                                                   */
    148172/*----------------------------------------------------------------------------*/
    149 
     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 */
    150185static void usbhid_kbd_set_led(usbhid_kbd_t *kbd_dev)
    151186{
     
    189224
    190225/*----------------------------------------------------------------------------*/
    191 
    192 static void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type,
    193     unsigned int key)
     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)
    194243{
    195244        console_event_t ev;
    196245        unsigned mod_mask;
    197246
    198         // 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         */
    199253        switch (key) {
    200254        case KC_LCTRL: mod_mask = KM_LCTRL; break;
     
    228282                         * up the lock state.
    229283                         */
     284                        unsigned int locks_old = kbd_dev->lock_keys;
     285                       
    230286                        kbd_dev->mods =
    231287                            kbd_dev->mods ^ (mod_mask & ~kbd_dev->lock_keys);
     
    233289
    234290                        /* Update keyboard lock indicator lights. */
    235                         usbhid_kbd_set_led(kbd_dev);
     291                        if (kbd_dev->lock_keys != locks_old) {
     292                                usbhid_kbd_set_led(kbd_dev);
     293                        }
    236294                } else {
    237295                        kbd_dev->lock_keys = kbd_dev->lock_keys & ~mod_mask;
     
    280338
    281339/*----------------------------------------------------------------------------*/
    282 
     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 */
    283348static void usbhid_kbd_check_modifier_changes(usbhid_kbd_t *kbd_dev,
    284349    uint8_t modifiers)
     
    316381
    317382/*----------------------------------------------------------------------------*/
    318 
     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 */
    319398static void usbhid_kbd_check_key_changes(usbhid_kbd_t *kbd_dev,
    320     const uint8_t *key_codes)
     399    const uint8_t *key_codes, size_t count)
    321400{
    322401        unsigned int key;
     
    328407        i = 0;
    329408        // all fields should report Error Rollover
    330         while (i < kbd_dev->keycode_count &&
     409        while (i < count &&
    331410            key_codes[i] == BOOTP_ERROR_ROLLOVER) {
    332411                ++i;
    333412        }
    334         if (i == kbd_dev->keycode_count) {
     413        if (i == count) {
    335414                usb_log_debug("Phantom state occured.\n");
    336415                // phantom state, do nothing
     
    338417        }
    339418       
    340         // TODO: quite dummy right now, think of better implementation
     419        /* TODO: quite dummy right now, think of better implementation */
     420        assert(count == kbd_dev->key_count);
    341421       
    342422        /*
    343423         * 1) Key releases
    344424         */
    345         for (j = 0; j < kbd_dev->keycode_count; ++j) {
     425        for (j = 0; j < count; ++j) {
    346426                // try to find the old key in the new key list
    347427                i = 0;
    348                 while (i < kbd_dev->keycode_count
    349                     && key_codes[i] != kbd_dev->keycodes[j]) {
     428                while (i < kbd_dev->key_count
     429                    && key_codes[i] != kbd_dev->keys[j]) {
    350430                        ++i;
    351431                }
    352432               
    353                 if (i == kbd_dev->keycode_count) {
     433                if (i == count) {
    354434                        // not found, i.e. the key was released
    355                         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);
    356437                        usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, key);
    357438                        usb_log_debug2("Key released: %d\n", key);
     
    364445         * 1) Key presses
    365446         */
    366         for (i = 0; i < kbd_dev->keycode_count; ++i) {
     447        for (i = 0; i < kbd_dev->key_count; ++i) {
    367448                // try to find the new key in the old key list
    368449                j = 0;
    369                 while (j < kbd_dev->keycode_count
    370                     && kbd_dev->keycodes[j] != key_codes[i]) {
     450                while (j < count && kbd_dev->keys[j] != key_codes[i]) {
    371451                        ++j;
    372452                }
    373453               
    374                 if (j == kbd_dev->keycode_count) {
     454                if (j == count) {
    375455                        // not found, i.e. new key pressed
    376456                        key = usbhid_parse_scancode(key_codes[i]);
     
    378458                            key_codes[i]);
    379459                        usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key);
     460                        usbhid_kbd_repeat_start(kbd_dev, key);
    380461                } else {
    381462                        // found, nothing happens
    382463                }
    383464        }
    384 //      // report all currently pressed keys
    385 //      for (i = 0; i < kbd_dev->keycode_count; ++i) {
    386 //              if (key_codes[i] != 0) {
    387 //                      key = usbhid_parse_scancode(key_codes[i]);
    388 //                      usb_log_debug2("Key pressed: %d (keycode: %d)\n", key,
    389 //                          key_codes[i]);
    390 //                      usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key);
    391 //              }
    392 //      }
    393        
    394         memcpy(kbd_dev->keycodes, key_codes, kbd_dev->keycode_count);
     465       
     466        memcpy(kbd_dev->keys, key_codes, count);
    395467
    396468        usb_log_debug("New stored keycodes: %s\n",
    397             usb_debug_str_buffer(kbd_dev->keycodes, kbd_dev->keycode_count, 0));
     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)
     
    415502
    416503        usb_log_debug("Got keys from parser: %s\n",
    417             usb_debug_str_buffer(key_codes, kbd_dev->keycode_count, 0));
    418        
    419         if (count != kbd_dev->keycode_count) {
     504            usb_debug_str_buffer(key_codes, kbd_dev->key_count, 0));
     505       
     506        if (count != kbd_dev->key_count) {
    420507                usb_log_warning("Number of received keycodes (%d) differs from"
    421                     " expected number (%d).\n", count, kbd_dev->keycode_count);
     508                    " expected number (%d).\n", count, kbd_dev->key_count);
    422509                return;
    423510        }
    424511       
    425512        usbhid_kbd_check_modifier_changes(kbd_dev, modifiers);
    426         usbhid_kbd_check_key_changes(kbd_dev, key_codes);
     513        usbhid_kbd_check_key_changes(kbd_dev, key_codes, count);
    427514}
    428515
     
    430517/* General kbd functions                                                      */
    431518/*----------------------------------------------------------------------------*/
    432 
     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 */
    433534static void usbhid_kbd_process_data(usbhid_kbd_t *kbd_dev,
    434535                                    uint8_t *buffer, size_t actual_size)
     
    455556/* HID/KBD structure manipulation                                             */
    456557/*----------------------------------------------------------------------------*/
    457 
     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 */
    458567static usbhid_kbd_t *usbhid_kbd_new(void)
    459568{
     
    481590
    482591/*----------------------------------------------------------------------------*/
    483 
     592/**
     593 * Properly destroys the USB/HID keyboard structure.
     594 *
     595 * @param kbd_dev Pointer to the structure to be destroyed.
     596 */
    484597static void usbhid_kbd_free(usbhid_kbd_t **kbd_dev)
    485598{
     
    496609        }
    497610       
     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       
    498617        free(*kbd_dev);
    499618        *kbd_dev = NULL;
     
    501620
    502621/*----------------------------------------------------------------------------*/
    503 
     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 */
    504642static int usbhid_kbd_init(usbhid_kbd_t *kbd_dev, ddf_dev_t *dev)
    505643{
     
    536674       
    537675        // save the size of the report (boot protocol report by default)
    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) {
     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) {
    543681                usb_log_fatal("No memory!\n");
    544                 return rc;
     682                return ENOMEM;
    545683        }
    546684       
     
    549687        kbd_dev->lock_keys = 0;
    550688       
     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       
    551704        /*
    552705         * Set boot protocol.
     
    571724/* HID/KBD polling                                                            */
    572725/*----------------------------------------------------------------------------*/
    573 
     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 */
    574739static void usbhid_kbd_poll(usbhid_kbd_t *kbd_dev)
    575740{
     
    594759                        usb_log_warning("Failed to start a session: %s.\n",
    595760                            str_error(sess_rc));
    596                         continue;
     761                        break;
    597762                }
    598763
     
    606771                        usb_log_warning("Error polling the keyboard: %s.\n",
    607772                            str_error(rc));
    608                         continue;
     773                        break;
    609774                }
    610775
     
    612777                        usb_log_warning("Error closing session: %s.\n",
    613778                            str_error(sess_rc));
    614                         continue;
     779                        break;
    615780                }
    616781
     
    633798                //async_usleep(kbd_dev->hid_dev->poll_interval);
    634799        }
    635 
    636         // not reached
    637         assert(0);
    638 }
    639 
    640 /*----------------------------------------------------------------------------*/
    641 
     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 */
    642820static int usbhid_kbd_fibril(void *arg)
    643821{
     
    661839/* API functions                                                              */
    662840/*----------------------------------------------------------------------------*/
    663 
     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 */
    664866int usbhid_kbd_try_add_device(ddf_dev_t *dev)
    665867{
     
    683885                    "structure.\n");
    684886                ddf_fun_destroy(kbd_fun);
    685                 return EINVAL;  // TODO: some other code??
     887                return ENOMEM;  // TODO: some other code??
    686888        }
    687889       
     
    732934        }
    733935        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);
    734946
    735947        (void)keyboard_ops;
  • uspace/drv/usbhid/kbddev.h

    rc0964800 r0c8562c  
    3939#include <stdint.h>
    4040
     41#include <fibril_synch.h>
     42
    4143#include <usb/classes/hid.h>
    4244#include <ddf/driver.h>
     
    4648
    4749/*----------------------------------------------------------------------------*/
     50/**
     51 * Structure for keeping information needed for auto-repeat of keys.
     52 */
     53typedef struct {
     54        /** Last pressed key. */
     55        unsigned int key_new;
     56        /** Key to be repeated. */
     57        unsigned int key_repeated;
     58        /** Delay before first repeat in microseconds. */
     59        unsigned int delay_before;
     60        /** Delay between repeats in microseconds. */
     61        unsigned int delay_between;
     62} usbhid_kbd_repeat_t;
    4863
    4964/**
    50  * @brief USB/HID keyboard device type.
     65 * USB/HID keyboard device type.
     66 *
     67 * Holds a reference to generic USB/HID device structure and keyboard-specific
     68 * data, such as currently pressed keys, modifiers and lock keys.
     69 *
     70 * Also holds a IPC phone to the console (since there is now no other way to
     71 * communicate with it).
     72 *
     73 * @note Storing active lock keys in this structure results in their setting
     74 *       being device-specific.
    5175 */
    5276typedef struct {
     77        /** Structure holding generic USB/HID device information. */
    5378        usbhid_dev_t *hid_dev;
    5479       
    55         uint8_t *keycodes;
    56         size_t keycode_count;
     80        /** Currently pressed keys (not translated to key codes). */
     81        uint8_t *keys;
     82        /** Count of stored keys (i.e. number of keys in the report). */
     83        size_t key_count;
     84        /** Currently pressed modifiers (bitmap). */
    5785        uint8_t modifiers;
    5886       
     87        /** Currently active modifiers including locks. Sent to the console. */
    5988        unsigned mods;
     89       
     90        /** Currently active lock keys. */
    6091        unsigned lock_keys;
    6192       
     93        /** IPC phone to the console device (for sending key events). */
    6294        int console_phone;
    6395       
     96        /** Information for auto-repeat of keys. */
     97        usbhid_kbd_repeat_t repeat;
     98       
     99        /** Mutex for accessing the information about auto-repeat. */
     100        fibril_mutex_t *repeat_mtx;
     101       
     102        /** State of the structure (for checking before use). */
    64103        int initialized;
    65104} usbhid_kbd_t;
     
    69108int usbhid_kbd_try_add_device(ddf_dev_t *dev);
    70109
     110void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key);
     111
    71112#endif /* USBHID_KBDDEV_H_ */
    72113
  • uspace/drv/usbhid/main.c

    rc0964800 r0c8562c  
    4747
    4848/*----------------------------------------------------------------------------*/
    49 
     49/**
     50 * Callback for passing a new device to the driver.
     51 *
     52 * @note Currently, only boot-protocol keyboards are supported by this driver.
     53 *
     54 * @param dev Structure representing the new device.
     55 *
     56 * @retval EOK if successful.
     57 * @retval EREFUSED if the device is not supported.
     58 */
    5059static int usbhid_add_device(ddf_dev_t *dev)
    5160{
  • uspace/lib/block/libblock.c

    rc0964800 r0c8562c  
    411411        l = hash_table_find(&cache->block_hash, &key);
    412412        if (l) {
     413found:
    413414                /*
    414415                 * We found the block in the cache.
     
    493494                                        fibril_mutex_unlock(&b->lock);
    494495                                        goto retry;
     496                                }
     497                                l = hash_table_find(&cache->block_hash, &key);
     498                                if (l) {
     499                                        /*
     500                                         * Someone else must have already
     501                                         * instantiated the block while we were
     502                                         * not holding the cache lock.
     503                                         * Leave the recycled block on the
     504                                         * freelist and continue as if we
     505                                         * found the block of interest during
     506                                         * the first try.
     507                                         */
     508                                        fibril_mutex_unlock(&b->lock);
     509                                        goto found;
    495510                                }
    496511
Note: See TracChangeset for help on using the changeset viewer.