Changeset 59e01689 in mainline for uspace/drv


Ignore:
Timestamp:
2011-03-19T18:30:20Z (15 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
09daa8b
Parents:
e93e319 (diff), 3746bfe (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

Location:
uspace/drv
Files:
6 edited

Legend:

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

    re93e319 r59e01689  
    158158        }
    159159       
     160        hid_dev->report_desc_size = length;
     161       
    160162        usb_log_debug("Done.\n");
    161163       
     
    262264       
    263265        if (rc != EOK) {
    264                 usb_log_warning("Problem with parsing Report descriptor: %s.\n",
    265                     str_error(rc));
    266                 return rc;
    267         }
     266                usb_log_warning("Problem with getting Report descriptor: %s.\n",
     267                    str_error(rc));
     268                return rc;
     269        }
     270       
     271        rc = usb_hid_parse_report_descriptor(hid_dev->parser,
     272            hid_dev->report_desc, hid_dev->report_desc_size);
     273        if (rc != EOK) {
     274                usb_log_warning("Problem parsing Report descriptor: %s.\n",
     275                    str_error(rc));
     276                return rc;
     277        }
     278       
     279        usb_hid_descriptor_print(hid_dev->parser);
    268280       
    269281        return EOK;
     
    289301       
    290302        memset(dev, 0, sizeof(usbhid_dev_t));
     303       
     304        dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof(
     305            usb_hid_report_parser_t)));
     306        if (dev->parser == NULL) {
     307                usb_log_fatal("No memory!\n");
     308                free(dev);
     309                return NULL;
     310        }
    291311       
    292312        dev->initialized = 0;
     
    399419
    400420        /*
     421         * Initialize the report parser.
     422         */
     423        rc = usb_hid_parser_init(hid_dev->parser);
     424        if (rc != EOK) {
     425                usb_log_error("Failed to initialize report parser.\n");
     426                return rc;
     427        }
     428
     429        /*
    401430         * Get descriptors, parse descriptors and save endpoints.
    402431         */
     
    411440        if (rc != EOK) {
    412441                /* TODO: end session?? */
     442                usb_endpoint_pipe_end_session(&hid_dev->ctrl_pipe);
    413443                usb_log_error("Failed to process descriptors: %s.\n",
    414444                    str_error(rc));
  • uspace/drv/usbhid/hiddev.h

    re93e319 r59e01689  
    3232/** @file
    3333 * Generic USB HID device structure and API.
     34 *
     35 * @todo Add function for parsing report - this is generic HID function, not
     36 *       keyboard-specific, as the report parser is also generic.
     37 * @todo Add function for polling as that is also a generic HID process.
     38 * @todo Add interrupt in pipe to the structure.
    3439 */
    3540
     
    7580        /** Report descriptor. */
    7681        uint8_t *report_desc;
     82
     83        size_t report_desc_size;
     84
    7785        /** HID Report parser. */
    7886        usb_hid_report_parser_t *parser;
  • uspace/drv/usbhid/kbddev.c

    re93e319 r59e01689  
    5151#include <usb/classes/hidparser.h>
    5252#include <usb/classes/classes.h>
     53#include <usb/classes/hidut.h>
    5354
    5455#include "kbddev.h"
     
    9394        .flags = 0
    9495};
     96
     97typedef enum usbhid_kbd_flags {
     98        USBHID_KBD_STATUS_UNINITIALIZED = 0,
     99        USBHID_KBD_STATUS_INITIALIZED = 1,
     100        USBHID_KBD_STATUS_TO_DESTROY = -1
     101} usbhid_kbd_flags;
    95102
    96103/*----------------------------------------------------------------------------*/
     
    124131};
    125132
     133typedef enum usbhid_lock_code {
     134        USBHID_LOCK_NUM = 0x53,
     135        USBHID_LOCK_CAPS = 0x39,
     136        USBHID_LOCK_SCROLL = 0x47,
     137        USBHID_LOCK_COUNT = 3
     138} usbhid_lock_code;
     139
     140static const usbhid_lock_code usbhid_lock_codes[USBHID_LOCK_COUNT] = {
     141        USBHID_LOCK_NUM,
     142        USBHID_LOCK_CAPS,
     143        USBHID_LOCK_SCROLL
     144};
     145
    126146/*----------------------------------------------------------------------------*/
    127147/* IPC method handler                                                         */
     
    218238       
    219239        assert(kbd_dev->hid_dev != NULL);
    220         assert(kbd_dev->hid_dev->initialized);
     240        assert(kbd_dev->hid_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
    221241        usbhid_req_set_report(kbd_dev->hid_dev, USB_HID_REPORT_TYPE_OUTPUT,
    222242            buffer, BOOTP_BUFFER_OUT_SIZE);
     
    346366 * @sa usbhid_kbd_push_ev()
    347367 */
    348 static void usbhid_kbd_check_modifier_changes(usbhid_kbd_t *kbd_dev,
    349     uint8_t modifiers)
    350 {
    351         /*
    352          * TODO: why the USB keyboard has NUM_, SCROLL_ and CAPS_LOCK
    353          *       both as modifiers and as keys with their own scancodes???
    354          *
    355          * modifiers should be sent as normal keys to usbhid_parse_scancode()!!
    356          * so maybe it would be better if I received it from report parser in
    357          * that way
    358          */
    359        
    360         int i;
    361         for (i = 0; i < USB_HID_MOD_COUNT; ++i) {
    362                 if ((modifiers & usb_hid_modifiers_consts[i]) &&
    363                     !(kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
    364                         // modifier pressed
    365                         if (usbhid_modifiers_keycodes[i] != 0) {
    366                                 usbhid_kbd_push_ev(kbd_dev, KEY_PRESS,
    367                                     usbhid_modifiers_keycodes[i]);
    368                         }
    369                 } else if (!(modifiers & usb_hid_modifiers_consts[i]) &&
    370                     (kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
    371                         // modifier released
    372                         if (usbhid_modifiers_keycodes[i] != 0) {
    373                                 usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE,
    374                                     usbhid_modifiers_keycodes[i]);
    375                         }
    376                 }       // no change
    377         }
    378        
    379         kbd_dev->modifiers = modifiers;
     368//static void usbhid_kbd_check_modifier_changes(usbhid_kbd_t *kbd_dev,
     369//    const uint8_t *key_codes, size_t count)
     370//{
     371//      /*
     372//       * TODO: why the USB keyboard has NUM_, SCROLL_ and CAPS_LOCK
     373//       *       both as modifiers and as keyUSB_HID_LOCK_COUNTs with their own scancodes???
     374//       *
     375//       * modifiers should be sent as normal keys to usbhid_parse_scancode()!!
     376//       * so maybe it would be better if I received it from report parser in
     377//       * that way
     378//       */
     379       
     380//      int i;
     381//      for (i = 0; i < count; ++i) {
     382//              if ((modifiers & usb_hid_modifiers_consts[i]) &&
     383//                  !(kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
     384//                      // modifier pressed
     385//                      if (usbhid_modifiers_keycodes[i] != 0) {
     386//                              usbhid_kbd_push_ev(kbd_dev, KEY_PRESS,
     387//                                  usbhid_modifiers_keycodes[i]);
     388//                      }
     389//              } else if (!(modifiers & usb_hid_modifiers_consts[i]) &&
     390//                  (kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
     391//                      // modifier released
     392//                      if (usbhid_modifiers_keycodes[i] != 0) {
     393//                              usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE,
     394//                                  usbhid_modifiers_keycodes[i]);
     395//                      }
     396//              }       // no change
     397//      }
     398       
     399//      kbd_dev->modifiers = modifiers;
     400//}
     401
     402/*----------------------------------------------------------------------------*/
     403
     404static inline int usbhid_kbd_is_lock(unsigned int key_code)
     405{
     406        return (key_code == KC_NUM_LOCK
     407            || key_code == KC_SCROLL_LOCK
     408            || key_code == KC_CAPS_LOCK);
    380409}
    381410
     
    404433        /*
    405434         * First of all, check if the kbd have reported phantom state.
     435         *
     436         * TODO: this must be changed as we don't know which keys are modifiers
     437         *       and which are regular keys.
    406438         */
    407439        i = 0;
     
    434466                        // not found, i.e. the key was released
    435467                        key = usbhid_parse_scancode(kbd_dev->keys[j]);
    436                         usbhid_kbd_repeat_stop(kbd_dev, key);
     468                        if (!usbhid_kbd_is_lock(key)) {
     469                                usbhid_kbd_repeat_stop(kbd_dev, key);
     470                        }
    437471                        usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, key);
    438472                        usb_log_debug2("Key released: %d\n", key);
     
    458492                            key_codes[i]);
    459493                        usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key);
    460                         usbhid_kbd_repeat_start(kbd_dev, key);
     494                        if (!usbhid_kbd_is_lock(key)) {
     495                                usbhid_kbd_repeat_start(kbd_dev, key);
     496                        }
    461497                } else {
    462498                        // found, nothing happens
     
    502538
    503539        usb_log_debug("Got keys from parser: %s\n",
    504             usb_debug_str_buffer(key_codes, kbd_dev->key_count, 0));
     540            usb_debug_str_buffer(key_codes, count, 0));
    505541       
    506542        if (count != kbd_dev->key_count) {
     
    510546        }
    511547       
    512         usbhid_kbd_check_modifier_changes(kbd_dev, modifiers);
     548        ///usbhid_kbd_check_modifier_changes(kbd_dev, key_codes, count);
    513549        usbhid_kbd_check_key_changes(kbd_dev, key_codes, count);
    514550}
     
    535571                                    uint8_t *buffer, size_t actual_size)
    536572{
     573        assert(kbd_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
     574        assert(kbd_dev->hid_dev->parser != NULL);
     575       
    537576        usb_hid_report_in_callbacks_t *callbacks =
    538577            (usb_hid_report_in_callbacks_t *)malloc(
     
    541580        callbacks->keyboard = usbhid_kbd_process_keycodes;
    542581
    543         usb_log_debug("Calling usb_hid_boot_keyboard_input_report() with "
     582        usb_log_debug("Calling usb_hid_parse_report() with "
    544583            "buffer %s\n", usb_debug_str_buffer(buffer, actual_size, 0));
    545584       
    546         int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
    547             callbacks, kbd_dev);
     585//      int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
     586//          callbacks, kbd_dev);
     587        int rc = usb_hid_parse_report(kbd_dev->hid_dev->parser, buffer,
     588            actual_size, callbacks, kbd_dev);
    548589       
    549590        if (rc != EOK) {
     
    584625       
    585626        kbd_dev->console_phone = -1;
    586         kbd_dev->initialized = 0;
     627        kbd_dev->initialized = USBHID_KBD_STATUS_UNINITIALIZED;
    587628       
    588629        return kbd_dev;
     
    590631
    591632/*----------------------------------------------------------------------------*/
    592 /**
    593  * Properly destroys the USB/HID keyboard structure.
    594  *
    595  * @param kbd_dev Pointer to the structure to be destroyed.
    596  */
    597 static void usbhid_kbd_free(usbhid_kbd_t **kbd_dev)
    598 {
    599         if (kbd_dev == NULL || *kbd_dev == NULL) {
    600                 return;
    601         }
    602        
    603         // hangup phone to the console
    604         async_hangup((*kbd_dev)->console_phone);
    605        
    606         if ((*kbd_dev)->hid_dev != NULL) {
    607                 usbhid_dev_free(&(*kbd_dev)->hid_dev);
    608                 assert((*kbd_dev)->hid_dev == NULL);
    609         }
    610        
    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        
    617         free(*kbd_dev);
    618         *kbd_dev = NULL;
     633
     634static void usbhid_kbd_mark_unusable(usbhid_kbd_t *kbd_dev)
     635{
     636        kbd_dev->initialized = USBHID_KBD_STATUS_TO_DESTROY;
    619637}
    620638
     
    658676        }
    659677       
    660         if (kbd_dev->initialized) {
     678        if (kbd_dev->initialized == USBHID_KBD_STATUS_INITIALIZED) {
    661679                usb_log_warning("Keyboard structure already initialized.\n");
    662680                return EINVAL;
     
    671689        }
    672690       
    673         assert(kbd_dev->hid_dev->initialized);
     691        assert(kbd_dev->hid_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
    674692       
    675693        // save the size of the report (boot protocol report by default)
    676         kbd_dev->key_count = BOOTP_REPORT_SIZE;
     694//      kbd_dev->key_count = BOOTP_REPORT_SIZE;
     695       
     696        usb_hid_report_path_t path;
     697        path.usage_page = USB_HIDUT_PAGE_KEYBOARD;
     698        kbd_dev->key_count = usb_hid_report_input_length(
     699            kbd_dev->hid_dev->parser, &path);
     700       
     701        usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
     702       
    677703        kbd_dev->keys = (uint8_t *)calloc(
    678704            kbd_dev->key_count, sizeof(uint8_t));
     
    709735        assert(kbd_dev->hid_dev != NULL);
    710736        assert(kbd_dev->hid_dev->initialized);
    711         usbhid_req_set_protocol(kbd_dev->hid_dev, USB_HID_PROTOCOL_BOOT);
     737        //usbhid_req_set_protocol(kbd_dev->hid_dev, USB_HID_PROTOCOL_BOOT);
    712738       
    713739        usbhid_kbd_set_led(kbd_dev);
     
    715741        usbhid_req_set_idle(kbd_dev->hid_dev, IDLE_RATE);
    716742       
    717         kbd_dev->initialized = 1;
     743        kbd_dev->initialized = USBHID_KBD_STATUS_INITIALIZED;
    718744        usb_log_info("HID/KBD device structure initialized.\n");
    719745       
     
    829855        usbhid_kbd_poll(kbd_dev);
    830856       
     857        // as there is another fibril using this device, so we must leave the
     858        // structure to it, but mark it for destroying.
     859        usbhid_kbd_mark_unusable(kbd_dev);
    831860        // at the end, properly destroy the KBD structure
    832         usbhid_kbd_free(&kbd_dev);
    833         assert(kbd_dev == NULL);
     861//      usbhid_kbd_free(&kbd_dev);
     862//      assert(kbd_dev == NULL);
    834863
    835864        return EOK;
     
    953982}
    954983
     984/*----------------------------------------------------------------------------*/
     985
     986int usbhid_kbd_is_usable(const usbhid_kbd_t *kbd_dev)
     987{
     988        return (kbd_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
     989}
     990
     991/*----------------------------------------------------------------------------*/
     992/**
     993 * Properly destroys the USB/HID keyboard structure.
     994 *
     995 * @param kbd_dev Pointer to the structure to be destroyed.
     996 */
     997void usbhid_kbd_free(usbhid_kbd_t **kbd_dev)
     998{
     999        if (kbd_dev == NULL || *kbd_dev == NULL) {
     1000                return;
     1001        }
     1002       
     1003        // hangup phone to the console
     1004        async_hangup((*kbd_dev)->console_phone);
     1005       
     1006        if ((*kbd_dev)->hid_dev != NULL) {
     1007                usbhid_dev_free(&(*kbd_dev)->hid_dev);
     1008                assert((*kbd_dev)->hid_dev == NULL);
     1009        }
     1010       
     1011        if ((*kbd_dev)->repeat_mtx != NULL) {
     1012                /* TODO: replace by some check and wait */
     1013                assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx));
     1014                free((*kbd_dev)->repeat_mtx);
     1015        }
     1016
     1017        free(*kbd_dev);
     1018        *kbd_dev = NULL;
     1019}
     1020
    9551021/**
    9561022 * @}
  • uspace/drv/usbhid/kbddev.h

    re93e319 r59e01689  
    4242
    4343#include <usb/classes/hid.h>
     44#include <usb/classes/hidparser.h>
    4445#include <ddf/driver.h>
    4546#include <usb/pipes.h>
     
    100101        fibril_mutex_t *repeat_mtx;
    101102       
    102         /** State of the structure (for checking before use). */
     103        /** State of the structure (for checking before use).
     104         *
     105         * 0 - not initialized
     106         * 1 - initialized
     107         * -1 - ready for destroying
     108         */
    103109        int initialized;
    104110} usbhid_kbd_t;
     
    107113
    108114int usbhid_kbd_try_add_device(ddf_dev_t *dev);
     115
     116int usbhid_kbd_is_usable(const usbhid_kbd_t *kbd_dev);
     117
     118void usbhid_kbd_free(usbhid_kbd_t **kbd_dev);
    109119
    110120void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key);
  • uspace/drv/usbhid/kbdrepeat.c

    re93e319 r59e01689  
    7777
    7878        while (true) {
     79                // check if the kbd structure is usable
     80                if (!usbhid_kbd_is_usable(kbd)) {
     81                        usbhid_kbd_free(&kbd);
     82                        assert(kbd == NULL);
     83                        return;
     84                }
     85               
    7986                fibril_mutex_lock(kbd->repeat_mtx);
    8087
  • uspace/drv/usbmouse/init.c

    re93e319 r59e01689  
    124124                goto leave;
    125125        }
     126       
     127        /* Open the control pipe. */
     128        rc = usb_endpoint_pipe_start_session(&dev->ctrl_pipe);
     129        if (rc != EOK) {
     130                goto leave;
     131        }
     132       
     133        /* Set the boot protocol. */
     134        rc = usb_control_request_set(&dev->ctrl_pipe,
     135            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     136            USB_HIDREQ_SET_PROTOCOL, USB_HID_PROTOCOL_BOOT, dev->interface_no,
     137            NULL, 0);
     138        if (rc != EOK) {
     139                goto leave;
     140        }
     141       
     142        /* Close the control pipe (ignore errors). */
     143        usb_endpoint_pipe_end_session(&dev->ctrl_pipe);
     144
    126145
    127146        /* Everything allright. */
Note: See TracChangeset for help on using the changeset viewer.