Changeset 9c0f158 in mainline


Ignore:
Timestamp:
2011-03-25T15:21:01Z (13 years ago)
Author:
Matej Klonfar <maklf@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
57d9c05e
Parents:
96bfe76 (diff), f08c560 (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:

development merge

Files:
2 added
4 deleted
8 edited
13 moved

Legend:

Unmodified
Added
Removed
  • boot/arch/amd64/Makefile.inc

    r96bfe76 r9c0f158  
    4949        usbflbk \
    5050        usbhub \
    51         usbhid \
     51        usbkbd \
    5252        usbmid \
    5353        usbmouse \
  • uspace/Makefile

    r96bfe76 r9c0f158  
    122122                drv/uhci-rhd \
    123123                drv/usbflbk \
    124                 drv/usbhid \
     124                drv/usbkbd \
    125125                drv/usbhub \
    126126                drv/usbmid \
     
    142142                drv/uhci-rhd \
    143143                drv/usbflbk \
    144                 drv/usbhid \
     144                drv/usbkbd \
    145145                drv/usbhub \
    146146                drv/usbmid \
  • uspace/app/usbinfo/info.c

    r96bfe76 r9c0f158  
    294294}
    295295
     296
     297void dump_status(usbinfo_device_t *dev)
     298{
     299        int rc;
     300        uint16_t device_status = 0;
     301        uint16_t ctrl_pipe_status = 0;
     302
     303        /* Device status first. */
     304        rc = usb_request_get_status(&dev->ctrl_pipe,
     305            USB_REQUEST_RECIPIENT_DEVICE, 0,
     306            &device_status);
     307        if (rc != EOK) {
     308                printf("%sFailed to get device status: %s.\n",
     309                    get_indent(0), str_error(rc));
     310                goto try_ctrl_pipe_status;
     311        }
     312
     313        printf("%sDevice status 0x%04x: power=%s, remote-wakeup=%s.\n",
     314            get_indent(0),
     315            device_status,
     316            device_status & USB_DEVICE_STATUS_SELF_POWERED ? "self" : "bus",
     317            device_status & USB_DEVICE_STATUS_REMOTE_WAKEUP ? "yes" : "no");
     318
     319        /* Interface is not interesting, skipping ;-). */
     320
     321        /* Control endpoint zero. */
     322try_ctrl_pipe_status:
     323        rc = usb_request_get_status(&dev->ctrl_pipe,
     324            USB_REQUEST_RECIPIENT_ENDPOINT, 0,
     325            &ctrl_pipe_status);
     326        if (rc != EOK) {
     327                printf("%sFailed to get control endpoint status: %s.\n",
     328                    get_indent(0), str_error(rc));
     329                goto leave;
     330        }
     331
     332        printf("%sControl endpoint zero status %04X: halted=%s.\n",
     333            get_indent(0),
     334            ctrl_pipe_status,
     335            ctrl_pipe_status & USB_ENDPOINT_STATUS_HALTED ? "yes" : "no");
     336
     337leave:
     338        return;
     339}
     340
    296341/** @}
    297342 */
  • uspace/app/usbinfo/main.c

    r96bfe76 r9c0f158  
    136136        _OPTION("-T --descriptor-tree-full", "Print detailed descriptor tree");
    137137        _OPTION("-s --strings", "Try to print all string descriptors.");
     138        _OPTION("-S --status", "Get status of the device.");
    138139
    139140        printf("\n");
     
    152153        {"descriptor-tree-full", no_argument, NULL, 'T'},
    153154        {"strings", no_argument, NULL, 's'},
     155        {"status", no_argument, NULL, 'S'},
    154156        {0, 0, NULL, 0}
    155157};
    156 static const char *short_options = "himtTs";
     158static const char *short_options = "himtTsS";
    157159
    158160static usbinfo_action_t actions[] = {
     
    180182                .opt = 's',
    181183                .action = dump_strings,
     184                .active = false
     185        },
     186        {
     187                .opt = 'S',
     188                .action = dump_status,
    182189                .active = false
    183190        },
  • uspace/app/usbinfo/usbinfo.h

    r96bfe76 r9c0f158  
    8484void dump_descriptor_tree_full(usbinfo_device_t *);
    8585void dump_strings(usbinfo_device_t *);
     86void dump_status(usbinfo_device_t *);
    8687
    8788
  • uspace/drv/ohci/batch.c

    r96bfe76 r9c0f158  
    118118        instance->next_step = batch_call_in_and_dispose;
    119119        /* TODO: implement */
    120         usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);
     120        usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);
    121121}
    122122/*----------------------------------------------------------------------------*/
  • uspace/drv/usbkbd/Makefile

    r96bfe76 r9c0f158  
    3030LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a
    3131EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I.
    32 BINARY = usbhid
     32BINARY = usbkbd
    3333
    3434STOLEN_LAYOUT_SOURCES = \
     
    4040        main.c \
    4141        conv.c \
    42         hidreq.c \
    4342        kbddev.c \
    4443        kbdrepeat.c \
    45         hiddev.c \
    4644        $(STOLEN_LAYOUT_SOURCES)
    4745
  • uspace/drv/usbkbd/conv.h

    r96bfe76 r9c0f158  
    3434 */
    3535
    36 #ifndef USBHID_CONV_H_
    37 #define USBHID_CONV_H_
     36#ifndef USB_KBD_CONV_H_
     37#define USB_KBD_CONV_H_
    3838
    3939unsigned int usbhid_parse_scancode(int scancode);
    4040
    41 #endif /* USBHID_CONV_H_ */
     41#endif /* USB_KBD_CONV_H_ */
    4242
    4343/**
  • uspace/drv/usbkbd/kbddev.c

    r96bfe76 r9c0f158  
    4646
    4747#include <usb/usb.h>
     48#include <usb/dp.h>
     49#include <usb/request.h>
    4850#include <usb/classes/hid.h>
    4951#include <usb/pipes.h>
     
    5254#include <usb/classes/classes.h>
    5355#include <usb/classes/hidut.h>
     56#include <usb/classes/hidreq.h>
     57#include <usb/classes/hidreport.h>
     58
     59#include <usb/devdrv.h>
    5460
    5561#include "kbddev.h"
    56 #include "hiddev.h"
    57 #include "hidreq.h"
     62
    5863#include "layout.h"
    5964#include "conv.h"
     
    8590static const unsigned int DEFAULT_REPEAT_DELAY = 50 * 1000;
    8691
     92/*----------------------------------------------------------------------------*/
     93
    8794/** Keyboard polling endpoint description for boot protocol class. */
    88 static usb_endpoint_description_t poll_endpoint_description = {
     95static usb_endpoint_description_t boot_poll_endpoint_description = {
    8996        .transfer_type = USB_TRANSFER_INTERRUPT,
    9097        .direction = USB_DIRECTION_IN,
     
    95102};
    96103
    97 typedef 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;
     104/* Array of endpoints expected on the device, NULL terminated. */
     105usb_endpoint_description_t
     106    *usb_kbd_endpoints[USB_KBD_POLL_EP_COUNT + 1] = {
     107        &boot_poll_endpoint_description,
     108        NULL
     109};
     110
     111/*----------------------------------------------------------------------------*/
     112
     113enum {
     114        BOOT_REPORT_DESCRIPTOR_SIZE = 63
     115};
     116
     117static const uint8_t BOOT_REPORT_DESCRIPTOR[BOOT_REPORT_DESCRIPTOR_SIZE] = {
     118        0x05, 0x01,  // Usage Page (Generic Desktop),
     119        0x09, 0x06,  // Usage (Keyboard),
     120        0xA1, 0x01,  // Collection (Application),
     121        0x75, 0x01,  //   Report Size (1),
     122        0x95, 0x08,  //   Report Count (8),       
     123        0x05, 0x07,  //   Usage Page (Key Codes);
     124        0x19, 0xE0,  //   Usage Minimum (224),
     125        0x29, 0xE7,  //   Usage Maximum (231),
     126        0x15, 0x00,  //   Logical Minimum (0),
     127        0x25, 0x01,  //   Logical Maximum (1),
     128        0x81, 0x02,  //   Input (Data, Variable, Absolute),   ; Modifier byte
     129        0x95, 0x01,  //   Report Count (1),
     130        0x75, 0x08,  //   Report Size (8),
     131        0x81, 0x01,  //   Input (Constant),                   ; Reserved byte
     132        0x95, 0x05,  //   Report Count (5),
     133        0x75, 0x01,  //   Report Size (1),
     134        0x05, 0x08,  //   Usage Page (Page# for LEDs),
     135        0x19, 0x01,  //   Usage Minimum (1),
     136        0x29, 0x05,  //   Usage Maxmimum (5),
     137        0x91, 0x02,  //   Output (Data, Variable, Absolute),  ; LED report
     138        0x95, 0x01,  //   Report Count (1),
     139        0x75, 0x03,  //   Report Size (3),
     140        0x91, 0x01,  //   Output (Constant),              ; LED report padding
     141        0x95, 0x06,  //   Report Count (6),
     142        0x75, 0x08,  //   Report Size (8),
     143        0x15, 0x00,  //   Logical Minimum (0),
     144        0x25, 0xff,  //   Logical Maximum (255),
     145        0x05, 0x07,  //   Usage Page (Key Codes),
     146        0x19, 0x00,  //   Usage Minimum (0),
     147        0x29, 0xff,  //   Usage Maximum (255),
     148        0x81, 0x00,  //   Input (Data, Array),            ; Key arrays (6 bytes)
     149        0xC0           // End Collection
     150
     151};
     152
     153/*----------------------------------------------------------------------------*/
     154
     155typedef enum usb_kbd_flags {
     156        USB_KBD_STATUS_UNINITIALIZED = 0,
     157        USB_KBD_STATUS_INITIALIZED = 1,
     158        USB_KBD_STATUS_TO_DESTROY = -1
     159} usb_kbd_flags;
    102160
    103161/*----------------------------------------------------------------------------*/
     
    132190
    133191typedef enum usbhid_lock_code {
    134         USBHID_LOCK_NUM = 0x53,
    135         USBHID_LOCK_CAPS = 0x39,
    136         USBHID_LOCK_SCROLL = 0x47,
    137         USBHID_LOCK_COUNT = 3
     192        USB_KBD_LOCK_NUM = 0x53,
     193        USB_KBD_LOCK_CAPS = 0x39,
     194        USB_KBD_LOCK_SCROLL = 0x47,
     195        USB_KBD_LOCK_COUNT = 3
    138196} usbhid_lock_code;
    139197
    140 static const usbhid_lock_code usbhid_lock_codes[USBHID_LOCK_COUNT] = {
    141         USBHID_LOCK_NUM,
    142         USBHID_LOCK_CAPS,
    143         USBHID_LOCK_SCROLL
     198static const usbhid_lock_code usbhid_lock_codes[USB_KBD_LOCK_COUNT] = {
     199        USB_KBD_LOCK_NUM,
     200        USB_KBD_LOCK_CAPS,
     201        USB_KBD_LOCK_SCROLL
    144202};
    145203
     
    149207
    150208static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
    151 static ddf_dev_ops_t keyboard_ops = {
     209ddf_dev_ops_t keyboard_ops = {
    152210        .default_handler = default_connection_handler
    153211};
     
    169227        sysarg_t method = IPC_GET_IMETHOD(*icall);
    170228       
    171         usbhid_kbd_t *kbd_dev = (usbhid_kbd_t *)fun->driver_data;
     229        usb_kbd_t *kbd_dev = (usb_kbd_t *)fun->driver_data;
    172230        assert(kbd_dev != NULL);
    173231
     
    203261 * @param kbd_dev Keyboard device structure.
    204262 */
    205 static void usbhid_kbd_set_led(usbhid_kbd_t *kbd_dev)
     263static void usb_kbd_set_led(usb_kbd_t *kbd_dev)
    206264{
    207265        uint8_t buffer[BOOTP_BUFFER_OUT_SIZE];
     
    237295            usb_debug_str_buffer(buffer, BOOTP_BUFFER_OUT_SIZE, 0));
    238296       
    239         assert(kbd_dev->hid_dev != NULL);
    240         assert(kbd_dev->hid_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
    241         usbhid_req_set_report(kbd_dev->hid_dev, USB_HID_REPORT_TYPE_OUTPUT,
     297        assert(kbd_dev->usb_dev != NULL);
     298       
     299        usbhid_req_set_report(&kbd_dev->usb_dev->ctrl_pipe,
     300            kbd_dev->usb_dev->interface_no, USB_HID_REPORT_TYPE_OUTPUT,
    242301            buffer, BOOTP_BUFFER_OUT_SIZE);
    243302}
     
    260319 * @param key Key code of the key according to HID Usage Tables.
    261320 */
    262 void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key)
     321void usb_kbd_push_ev(usb_kbd_t *kbd_dev, int type, unsigned int key)
    263322{
    264323        console_event_t ev;
     
    310369                        /* Update keyboard lock indicator lights. */
    311370                        if (kbd_dev->lock_keys != locks_old) {
    312                                 usbhid_kbd_set_led(kbd_dev);
     371                                usb_kbd_set_led(kbd_dev);
    313372                        }
    314373                } else {
     
    358417
    359418/*----------------------------------------------------------------------------*/
    360 /**
    361  * Checks if modifiers were pressed or released and generates key events.
    362  *
    363  * @param kbd_dev Keyboard device structure.
    364  * @param modifiers Bitmap of modifiers.
    365  *
    366  * @sa usbhid_kbd_push_ev()
    367  */
    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 
    404 static inline int usbhid_kbd_is_lock(unsigned int key_code)
     419
     420static inline int usb_kbd_is_lock(unsigned int key_code)
    405421{
    406422        return (key_code == KC_NUM_LOCK
     
    414430 *
    415431 * An event is created only when key is pressed or released. Besides handling
    416  * the events (usbhid_kbd_push_ev()), the auto-repeat fibril is notified about
    417  * key presses and releases (see usbhid_kbd_repeat_start() and
    418  * usbhid_kbd_repeat_stop()).
     432 * the events (usb_kbd_push_ev()), the auto-repeat fibril is notified about
     433 * key presses and releases (see usb_kbd_repeat_start() and
     434 * usb_kbd_repeat_stop()).
    419435 *
    420436 * @param kbd_dev Keyboard device structure.
     
    423439 * @param count Number of key codes in report (size of the report).
    424440 *
    425  * @sa usbhid_kbd_push_ev(), usbhid_kbd_repeat_start(), usbhid_kbd_repeat_stop()
    426  */
    427 static void usbhid_kbd_check_key_changes(usbhid_kbd_t *kbd_dev,
     441 * @sa usb_kbd_push_ev(), usb_kbd_repeat_start(), usb_kbd_repeat_stop()
     442 */
     443static void usb_kbd_check_key_changes(usb_kbd_t *kbd_dev,
    428444    const uint8_t *key_codes, size_t count)
    429445{
     
    434450         * First of all, check if the kbd have reported phantom state.
    435451         *
    436          * TODO: this must be changed as we don't know which keys are modifiers
     452         * this must be changed as we don't know which keys are modifiers
    437453         *       and which are regular keys.
    438454         */
     
    466482                        // not found, i.e. the key was released
    467483                        key = usbhid_parse_scancode(kbd_dev->keys[j]);
    468                         if (!usbhid_kbd_is_lock(key)) {
    469                                 usbhid_kbd_repeat_stop(kbd_dev, key);
     484                        if (!usb_kbd_is_lock(key)) {
     485                                usb_kbd_repeat_stop(kbd_dev, key);
    470486                        }
    471                         usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, key);
     487                        usb_kbd_push_ev(kbd_dev, KEY_RELEASE, key);
    472488                        usb_log_debug2("Key released: %d\n", key);
    473489                } else {
     
    491507                        usb_log_debug2("Key pressed: %d (keycode: %d)\n", key,
    492508                            key_codes[i]);
    493                         usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key);
    494                         if (!usbhid_kbd_is_lock(key)) {
    495                                 usbhid_kbd_repeat_start(kbd_dev, key);
     509                        usb_kbd_push_ev(kbd_dev, KEY_PRESS, key);
     510                        if (!usb_kbd_is_lock(key)) {
     511                                usb_kbd_repeat_start(kbd_dev, key);
    496512                        }
    497513                } else {
     
    523539 *            structure representing the keyboard.
    524540 *
    525  * @sa usbhid_kbd_check_key_changes(), usbhid_kbd_check_modifier_changes()
    526  */
    527 static void usbhid_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
     541 * @sa usb_kbd_check_key_changes(), usb_kbd_check_modifier_changes()
     542 */
     543static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
    528544    uint8_t modifiers, void *arg)
    529545{
     
    534550        }
    535551       
    536         usbhid_kbd_t *kbd_dev = (usbhid_kbd_t *)arg;
     552        usb_kbd_t *kbd_dev = (usb_kbd_t *)arg;
    537553        assert(kbd_dev != NULL);
    538554
     
    546562        }
    547563       
    548         ///usbhid_kbd_check_modifier_changes(kbd_dev, key_codes, count);
    549         usbhid_kbd_check_key_changes(kbd_dev, key_codes, count);
     564        ///usb_kbd_check_modifier_changes(kbd_dev, key_codes, count);
     565        usb_kbd_check_key_changes(kbd_dev, key_codes, count);
    550566}
    551567
     
    558574 * This function uses the HID report parser to translate the data received from
    559575 * the device into generic USB HID key codes and into generic modifiers bitmap.
    560  * The parser then calls the given callback (usbhid_kbd_process_keycodes()).
     576 * The parser then calls the given callback (usb_kbd_process_keycodes()).
    561577 *
    562578 * @note Currently, only the boot protocol is supported.
     
    566582 * @param actual_size Size of the data from keyboard (report size) in bytes.
    567583 *
    568  * @sa usbhid_kbd_process_keycodes(), usb_hid_boot_keyboard_input_report().
    569  */
    570 static void usbhid_kbd_process_data(usbhid_kbd_t *kbd_dev,
     584 * @sa usb_kbd_process_keycodes(), usb_hid_boot_keyboard_input_report(),
     585 *     usb_hid_parse_report().
     586 */
     587static void usb_kbd_process_data(usb_kbd_t *kbd_dev,
    571588                                    uint8_t *buffer, size_t actual_size)
    572589{
    573         assert(kbd_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
    574         assert(kbd_dev->hid_dev->parser != NULL);
     590        assert(kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED);
     591        assert(kbd_dev->parser != NULL);
    575592       
    576593        usb_hid_report_in_callbacks_t *callbacks =
     
    578595                sizeof(usb_hid_report_in_callbacks_t));
    579596       
    580         callbacks->keyboard = usbhid_kbd_process_keycodes;
     597        callbacks->keyboard = usb_kbd_process_keycodes;
    581598
    582599        usb_log_debug("Calling usb_hid_parse_report() with "
     
    588605        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    589606       
    590         int rc = usb_hid_parse_report(kbd_dev->hid_dev->parser, buffer,
     607        int rc = usb_hid_parse_report(kbd_dev->parser, buffer,
    591608            actual_size, path, USB_HID_PATH_COMPARE_STRICT, callbacks, kbd_dev);
    592609
     
    602619/* HID/KBD structure manipulation                                             */
    603620/*----------------------------------------------------------------------------*/
     621
     622static void usb_kbd_mark_unusable(usb_kbd_t *kbd_dev)
     623{
     624        kbd_dev->initialized = USB_KBD_STATUS_TO_DESTROY;
     625}
     626
     627
     628/*----------------------------------------------------------------------------*/
     629/* API functions                                                              */
     630/*----------------------------------------------------------------------------*/
    604631/**
    605632 * Creates a new USB/HID keyboard structure.
    606633 *
    607634 * The structure returned by this function is not initialized. Use
    608  * usbhid_kbd_init() to initialize it prior to polling.
     635 * usb_kbd_init() to initialize it prior to polling.
    609636 *
    610637 * @return New uninitialized structure for representing a USB/HID keyboard or
    611638 *         NULL if not successful (memory error).
    612639 */
    613 static usbhid_kbd_t *usbhid_kbd_new(void)
    614 {
    615         usbhid_kbd_t *kbd_dev =
    616             (usbhid_kbd_t *)malloc(sizeof(usbhid_kbd_t));
     640usb_kbd_t *usb_kbd_new(void)
     641{
     642        usb_kbd_t *kbd_dev =
     643            (usb_kbd_t *)malloc(sizeof(usb_kbd_t));
    617644
    618645        if (kbd_dev == NULL) {
     
    621648        }
    622649       
    623         memset(kbd_dev, 0, sizeof(usbhid_kbd_t));
    624        
    625         kbd_dev->hid_dev = usbhid_dev_new();
    626         if (kbd_dev->hid_dev == NULL) {
    627                 usb_log_fatal("Could not create HID device structure.\n");
     650        memset(kbd_dev, 0, sizeof(usb_kbd_t));
     651       
     652        kbd_dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof(
     653            usb_hid_report_parser_t)));
     654        if (kbd_dev->parser == NULL) {
     655                usb_log_fatal("No memory!\n");
     656                free(kbd_dev);
    628657                return NULL;
    629658        }
    630659       
    631660        kbd_dev->console_phone = -1;
    632         kbd_dev->initialized = USBHID_KBD_STATUS_UNINITIALIZED;
     661        kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED;
    633662       
    634663        return kbd_dev;
    635 }
    636 
    637 /*----------------------------------------------------------------------------*/
    638 
    639 static void usbhid_kbd_mark_unusable(usbhid_kbd_t *kbd_dev)
    640 {
    641         kbd_dev->initialized = USBHID_KBD_STATUS_TO_DESTROY;
    642664}
    643665
     
    663685 * @return Other value inherited from function usbhid_dev_init().
    664686 */
    665 static int usbhid_kbd_init(usbhid_kbd_t *kbd_dev, ddf_dev_t *dev)
     687int usb_kbd_init(usb_kbd_t *kbd_dev, usb_device_t *dev)
    666688{
    667689        int rc;
     
    676698       
    677699        if (dev == NULL) {
    678                 usb_log_error("Failed to init keyboard structure: no device"
     700                usb_log_error("Failed to init keyboard structure: no USB device"
    679701                    " given.\n");
    680702                return EINVAL;
    681703        }
    682704       
    683         if (kbd_dev->initialized == USBHID_KBD_STATUS_INITIALIZED) {
     705        if (kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED) {
    684706                usb_log_warning("Keyboard structure already initialized.\n");
    685707                return EINVAL;
    686708        }
    687709       
    688         rc = usbhid_dev_init(kbd_dev->hid_dev, dev, &poll_endpoint_description);
    689        
     710        /* TODO: does not work! */
     711        if (!dev->pipes[USB_KBD_POLL_EP_NO].present) {
     712                usb_log_warning("Required endpoint not found - probably not "
     713                    "a supported device.\n");
     714                return ENOTSUP;
     715        }
     716       
     717        /* The USB device should already be initialized, save it in structure */
     718        kbd_dev->usb_dev = dev;
     719       
     720        /* Initialize the report parser. */
     721        rc = usb_hid_parser_init(kbd_dev->parser);
    690722        if (rc != EOK) {
    691                 usb_log_error("Failed to initialize HID device structure: %s\n",
    692                    str_error(rc));
     723                usb_log_error("Failed to initialize report parser.\n");
    693724                return rc;
    694725        }
    695726       
    696         assert(kbd_dev->hid_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
    697        
    698         // save the size of the report (boot protocol report by default)
    699 //      kbd_dev->key_count = BOOTP_REPORT_SIZE;
    700        
    701         usb_hid_report_path_t *path;
    702         path = usb_hid_report_path();
     727        /* Get the report descriptor and parse it. */
     728        rc = usb_hid_process_report_descriptor(kbd_dev->usb_dev,
     729            kbd_dev->parser);
     730        if (rc != EOK) {
     731                usb_log_warning("Could not process report descriptor, "
     732                    "falling back to boot protocol.\n");
     733                rc = usb_hid_parse_report_descriptor(kbd_dev->parser,
     734                    BOOT_REPORT_DESCRIPTOR, BOOT_REPORT_DESCRIPTOR_SIZE);
     735                if (rc != EOK) {
     736                        usb_log_error("Failed to parse boot report descriptor:"
     737                            " %s.\n", str_error(rc));
     738                        return rc;
     739                }
     740               
     741                rc = usbhid_req_set_protocol(&kbd_dev->usb_dev->ctrl_pipe,
     742                    kbd_dev->usb_dev->interface_no, USB_HID_PROTOCOL_BOOT);
     743               
     744                if (rc != EOK) {
     745                        usb_log_warning("Failed to set boot protocol to the "
     746                            "device: %s\n", str_error(rc));
     747                        return rc;
     748                }
     749        }
     750       
     751        /*
     752         * TODO: make more general
     753         */
     754        usb_hid_report_path_t *path = usb_hid_report_path();
    703755        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    704756        kbd_dev->key_count = usb_hid_report_input_length(
    705             kbd_dev->hid_dev->parser, path, USB_HID_PATH_COMPARE_STRICT);
     757            kbd_dev->parser, path, USB_HID_PATH_COMPARE_STRICT);
    706758        usb_hid_report_path_free (path);
    707759       
     
    736788       
    737789        /*
    738          * Set boot protocol.
    739790         * Set LEDs according to initial setup.
    740791         * Set Idle rate
    741792         */
    742         assert(kbd_dev->hid_dev != NULL);
    743         assert(kbd_dev->hid_dev->initialized);
    744         //usbhid_req_set_protocol(kbd_dev->hid_dev, USB_HID_PROTOCOL_BOOT);
    745        
    746         usbhid_kbd_set_led(kbd_dev);
    747        
    748         usbhid_req_set_idle(kbd_dev->hid_dev, IDLE_RATE);
    749        
    750         kbd_dev->initialized = USBHID_KBD_STATUS_INITIALIZED;
     793        usb_kbd_set_led(kbd_dev);
     794       
     795        usbhid_req_set_idle(&kbd_dev->usb_dev->ctrl_pipe,
     796            kbd_dev->usb_dev->interface_no, IDLE_RATE);
     797       
     798        kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED;
    751799        usb_log_debug("HID/KBD device structure initialized.\n");
    752800       
     
    755803
    756804/*----------------------------------------------------------------------------*/
    757 /* HID/KBD polling                                                            */
    758 /*----------------------------------------------------------------------------*/
    759 /**
    760  * Main keyboard polling function.
    761  *
    762  * This function uses the Interrupt In pipe of the keyboard to poll for events.
    763  * The keyboard is initialized in a way that it reports only when a key is
    764  * pressed or released, so there is no actual need for any sleeping between
    765  * polls (see usbhid_kbd_try_add_device() or usbhid_kbd_init()).
    766  *
    767  * @param kbd_dev Initialized keyboard structure representing the device to
    768  *                poll.
    769  *
    770  * @sa usbhid_kbd_process_data()
    771  */
    772 static void usbhid_kbd_poll(usbhid_kbd_t *kbd_dev)
    773 {
    774         int rc, sess_rc;
    775         uint8_t buffer[BOOTP_BUFFER_SIZE];
    776         size_t actual_size;
    777        
    778         usb_log_debug("Polling keyboard...\n");
    779        
    780         if (!kbd_dev->initialized) {
    781                 usb_log_error("HID/KBD device not initialized!\n");
    782                 return;
    783         }
    784        
    785         assert(kbd_dev->hid_dev != NULL);
    786         assert(kbd_dev->hid_dev->initialized);
    787 
    788         while (true) {
    789                 sess_rc = usb_pipe_start_session(
    790                     &kbd_dev->hid_dev->poll_pipe);
    791                 if (sess_rc != EOK) {
    792                         usb_log_warning("Failed to start a session: %s.\n",
    793                             str_error(sess_rc));
    794                         break;
    795                 }
    796 
    797                 rc = usb_pipe_read(&kbd_dev->hid_dev->poll_pipe,
    798                     buffer, BOOTP_BUFFER_SIZE, &actual_size);
    799                
    800                 sess_rc = usb_pipe_end_session(
    801                     &kbd_dev->hid_dev->poll_pipe);
    802 
    803                 if (rc != EOK) {
    804                         usb_log_warning("Error polling the keyboard: %s.\n",
    805                             str_error(rc));
    806                         break;
    807                 }
    808 
    809                 if (sess_rc != EOK) {
    810                         usb_log_warning("Error closing session: %s.\n",
    811                             str_error(sess_rc));
    812                         break;
    813                 }
    814 
    815                 /*
    816                  * If the keyboard answered with NAK, it returned no data.
    817                  * This implies that no change happened since last query.
    818                  */
    819                 if (actual_size == 0) {
    820                         usb_log_debug("Keyboard returned NAK\n");
    821                         continue;
    822                 }
    823 
    824                 /*
    825                  * TODO: Process pressed keys.
    826                  */
    827                 usb_log_debug("Calling usbhid_kbd_process_data()\n");
    828                 usbhid_kbd_process_data(kbd_dev, buffer, actual_size);
    829                
    830                 // disabled for now, no reason to sleep
    831                 //async_usleep(kbd_dev->hid_dev->poll_interval);
    832         }
    833 }
    834 
    835 /*----------------------------------------------------------------------------*/
    836 /**
    837  * Function executed by the main driver fibril.
    838  *
    839  * Just starts polling the keyboard for events.
    840  *
    841  * @param arg Initialized keyboard device structure (of type usbhid_kbd_t)
    842  *            representing the device.
    843  *
    844  * @retval EOK if the fibril finished polling the device.
    845  * @retval EINVAL if no device was given in the argument.
    846  *
    847  * @sa usbhid_kbd_poll()
    848  *
    849  * @todo Change return value - only case when the fibril finishes is in case
    850  *       of some error, so the error should probably be propagated from function
    851  *       usbhid_kbd_poll() to here and up.
    852  */
    853 static int usbhid_kbd_fibril(void *arg)
    854 {
    855         if (arg == NULL) {
    856                 usb_log_error("No device!\n");
    857                 return EINVAL;
    858         }
    859        
    860         usbhid_kbd_t *kbd_dev = (usbhid_kbd_t *)arg;
    861 
    862         usbhid_kbd_poll(kbd_dev);
    863        
    864         // as there is another fibril using this device, so we must leave the
    865         // structure to it, but mark it for destroying.
    866         usbhid_kbd_mark_unusable(kbd_dev);
    867         // at the end, properly destroy the KBD structure
    868 //      usbhid_kbd_free(&kbd_dev);
    869 //      assert(kbd_dev == NULL);
    870 
    871         return EOK;
    872 }
    873 
    874 /*----------------------------------------------------------------------------*/
    875 /* API functions                                                              */
    876 /*----------------------------------------------------------------------------*/
    877 /**
    878  * Function for adding a new device of type USB/HID/keyboard.
    879  *
    880  * This functions initializes required structures from the device's descriptors
    881  * and starts new fibril for polling the keyboard for events and another one for
    882  * handling auto-repeat of keys.
    883  *
    884  * During initialization, the keyboard is switched into boot protocol, the idle
    885  * rate is set to 0 (infinity), resulting in the keyboard only reporting event
    886  * when a key is pressed or released. Finally, the LED lights are turned on
    887  * according to the default setup of lock keys.
    888  *
    889  * @note By default, the keyboards is initialized with Num Lock turned on and
    890  *       other locks turned off.
    891  * @note Currently supports only boot-protocol keyboards.
    892  *
    893  * @param dev Device to add.
    894  *
    895  * @retval EOK if successful.
    896  * @retval ENOMEM if there
    897  * @return Other error code inherited from one of functions usbhid_kbd_init(),
    898  *         ddf_fun_bind() and ddf_fun_add_to_class().
    899  *
    900  * @sa usbhid_kbd_fibril(), usbhid_kbd_repeat_fibril()
    901  */
    902 int usbhid_kbd_try_add_device(ddf_dev_t *dev)
    903 {
    904         /*
    905          * Create default function.
    906          */
    907         ddf_fun_t *kbd_fun = ddf_fun_create(dev, fun_exposed, "keyboard");
    908         if (kbd_fun == NULL) {
    909                 usb_log_error("Could not create DDF function node.\n");
    910                 return ENOMEM;
    911         }
    912        
    913         /*
    914          * Initialize device (get and process descriptors, get address, etc.)
    915          */
    916         usb_log_debug("Initializing USB/HID KBD device...\n");
    917        
    918         usbhid_kbd_t *kbd_dev = usbhid_kbd_new();
    919         if (kbd_dev == NULL) {
    920                 usb_log_error("Error while creating USB/HID KBD device "
    921                     "structure.\n");
    922                 ddf_fun_destroy(kbd_fun);
    923                 return ENOMEM;  // TODO: some other code??
    924         }
    925        
    926         int rc = usbhid_kbd_init(kbd_dev, dev);
    927        
    928         if (rc != EOK) {
    929                 usb_log_error("Failed to initialize USB/HID KBD device.\n");
    930                 ddf_fun_destroy(kbd_fun);
    931                 usbhid_kbd_free(&kbd_dev);
    932                 return rc;
    933         }       
    934        
    935         usb_log_debug("USB/HID KBD device structure initialized.\n");
    936        
    937         /*
    938          * Store the initialized keyboard device and keyboard ops
    939          * to the DDF function.
    940          */
    941         kbd_fun->driver_data = kbd_dev;
    942         kbd_fun->ops = &keyboard_ops;
    943 
    944         rc = ddf_fun_bind(kbd_fun);
    945         if (rc != EOK) {
    946                 usb_log_error("Could not bind DDF function: %s.\n",
    947                     str_error(rc));
    948                 // TODO: Can / should I destroy the DDF function?
    949                 ddf_fun_destroy(kbd_fun);
    950                 usbhid_kbd_free(&kbd_dev);
    951                 return rc;
    952         }
    953        
    954         rc = ddf_fun_add_to_class(kbd_fun, "keyboard");
    955         if (rc != EOK) {
    956                 usb_log_error(
    957                     "Could not add DDF function to class 'keyboard': %s.\n",
    958                     str_error(rc));
    959                 // TODO: Can / should I destroy the DDF function?
    960                 ddf_fun_destroy(kbd_fun);
    961                 usbhid_kbd_free(&kbd_dev);
    962                 return rc;
    963         }
    964        
    965         /*
    966          * Create new fibril for handling this keyboard
    967          */
    968         fid_t fid = fibril_create(usbhid_kbd_fibril, kbd_dev);
    969         if (fid == 0) {
    970                 usb_log_error("Failed to start fibril for `%s' device.\n",
    971                     dev->name);
    972                 return ENOMEM;
    973         }
    974         fibril_add_ready(fid);
    975        
    976         /*
    977          * Create new fibril for auto-repeat
    978          */
    979         fid = fibril_create(usbhid_kbd_repeat_fibril, kbd_dev);
    980         if (fid == 0) {
    981                 usb_log_error("Failed to start fibril for KBD auto-repeat");
    982                 return ENOMEM;
    983         }
    984         fibril_add_ready(fid);
    985 
    986         (void)keyboard_ops;
    987 
    988         /*
    989          * Hurrah, device is initialized.
    990          */
    991         return EOK;
    992 }
    993 
    994 /*----------------------------------------------------------------------------*/
    995 
    996 int usbhid_kbd_is_usable(const usbhid_kbd_t *kbd_dev)
    997 {
    998         return (kbd_dev->initialized == USBHID_KBD_STATUS_INITIALIZED);
     805
     806bool usb_kbd_polling_callback(usb_device_t *dev, uint8_t *buffer,
     807     size_t buffer_size, void *arg)
     808{
     809        if (dev == NULL || buffer == NULL || arg == NULL) {
     810                // do not continue polling (???)
     811                return false;
     812        }
     813       
     814        usb_kbd_t *kbd_dev = (usb_kbd_t *)arg;
     815       
     816        // TODO: add return value from this function
     817        usb_kbd_process_data(kbd_dev, buffer, buffer_size);
     818       
     819        return true;
     820}
     821
     822/*----------------------------------------------------------------------------*/
     823
     824void usb_kbd_polling_ended_callback(usb_device_t *dev, bool reason,
     825     void *arg)
     826{
     827        if (dev == NULL || arg == NULL) {
     828                return;
     829        }
     830       
     831        usb_kbd_t *kbd = (usb_kbd_t *)arg;
     832       
     833        usb_kbd_mark_unusable(kbd);
     834}
     835
     836/*----------------------------------------------------------------------------*/
     837
     838int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev)
     839{
     840        return (kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED);
     841}
     842
     843/*----------------------------------------------------------------------------*/
     844
     845int usb_kbd_is_ready_to_destroy(const usb_kbd_t *kbd_dev)
     846{
     847        return (kbd_dev->initialized == USB_KBD_STATUS_TO_DESTROY);
    999848}
    1000849
     
    1005854 * @param kbd_dev Pointer to the structure to be destroyed.
    1006855 */
    1007 void usbhid_kbd_free(usbhid_kbd_t **kbd_dev)
     856void usb_kbd_free(usb_kbd_t **kbd_dev)
    1008857{
    1009858        if (kbd_dev == NULL || *kbd_dev == NULL) {
     
    1014863        async_hangup((*kbd_dev)->console_phone);
    1015864       
    1016         if ((*kbd_dev)->hid_dev != NULL) {
    1017                 usbhid_dev_free(&(*kbd_dev)->hid_dev);
    1018                 assert((*kbd_dev)->hid_dev == NULL);
    1019         }
     865//      if ((*kbd_dev)->hid_dev != NULL) {
     866//              usbhid_dev_free(&(*kbd_dev)->hid_dev);
     867//              assert((*kbd_dev)->hid_dev == NULL);
     868//      }
    1020869       
    1021870        if ((*kbd_dev)->repeat_mtx != NULL) {
     
    1024873                free((*kbd_dev)->repeat_mtx);
    1025874        }
     875       
     876        // destroy the parser
     877        if ((*kbd_dev)->parser != NULL) {
     878                usb_hid_free_report_parser((*kbd_dev)->parser);
     879        }
     880       
     881        /* TODO: what about the USB device structure?? */
    1026882
    1027883        free(*kbd_dev);
  • uspace/drv/usbkbd/kbddev.h

    r96bfe76 r9c0f158  
    3434 */
    3535
    36 #ifndef USBHID_KBDDEV_H_
    37 #define USBHID_KBDDEV_H_
     36#ifndef USB_KBDDEV_H_
     37#define USB_KBDDEV_H_
    3838
    3939#include <stdint.h>
     
    4545#include <ddf/driver.h>
    4646#include <usb/pipes.h>
     47#include <usb/devdrv.h>
    4748
    48 #include "hiddev.h"
     49#include "kbdrepeat.h"
    4950
    5051/*----------------------------------------------------------------------------*/
    51 /**
    52  * Structure for keeping information needed for auto-repeat of keys.
    53  */
    54 typedef struct {
    55         /** Last pressed key. */
    56         unsigned int key_new;
    57         /** Key to be repeated. */
    58         unsigned int key_repeated;
    59         /** Delay before first repeat in microseconds. */
    60         unsigned int delay_before;
    61         /** Delay between repeats in microseconds. */
    62         unsigned int delay_between;
    63 } usbhid_kbd_repeat_t;
    64 
    6552/**
    6653 * USB/HID keyboard device type.
     
    7562 *       being device-specific.
    7663 */
    77 typedef struct {
    78         /** Structure holding generic USB/HID device information. */
    79         usbhid_dev_t *hid_dev;
     64typedef struct usb_kbd_t {
     65        /** Structure holding generic USB device information. */
     66        //usbhid_dev_t *hid_dev;
     67        usb_device_t *usb_dev;
    8068       
    8169        /** Currently pressed keys (not translated to key codes). */
     
    9684       
    9785        /** Information for auto-repeat of keys. */
    98         usbhid_kbd_repeat_t repeat;
     86        usb_kbd_repeat_t repeat;
    9987       
    10088        /** Mutex for accessing the information about auto-repeat. */
    10189        fibril_mutex_t *repeat_mtx;
     90       
     91        /** Report descriptor. */
     92        uint8_t *report_desc;
     93
     94        /** Report descriptor size. */
     95        size_t report_desc_size;
     96
     97        /** HID Report parser. */
     98        usb_hid_report_parser_t *parser;
    10299       
    103100        /** State of the structure (for checking before use).
     
    108105         */
    109106        int initialized;
    110 } usbhid_kbd_t;
     107} usb_kbd_t;
    111108
    112109/*----------------------------------------------------------------------------*/
    113110
    114 int usbhid_kbd_try_add_device(ddf_dev_t *dev);
     111enum {
     112        USB_KBD_POLL_EP_NO = 0,
     113        USB_KBD_POLL_EP_COUNT = 1
     114};
    115115
    116 int usbhid_kbd_is_usable(const usbhid_kbd_t *kbd_dev);
     116usb_endpoint_description_t *usb_kbd_endpoints[USB_KBD_POLL_EP_COUNT + 1];
    117117
    118 void usbhid_kbd_free(usbhid_kbd_t **kbd_dev);
     118ddf_dev_ops_t keyboard_ops;
    119119
    120 void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key);
     120/*----------------------------------------------------------------------------*/
    121121
    122 #endif /* USBHID_KBDDEV_H_ */
     122usb_kbd_t *usb_kbd_new(void);
     123
     124int usb_kbd_init(usb_kbd_t *kbd_dev, usb_device_t *dev);
     125
     126bool usb_kbd_polling_callback(usb_device_t *dev, uint8_t *buffer,
     127     size_t buffer_size, void *arg);
     128
     129void usb_kbd_polling_ended_callback(usb_device_t *dev, bool reason,
     130     void *arg);
     131
     132int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev);
     133
     134int usb_kbd_is_ready_to_destroy(const usb_kbd_t *kbd_dev);
     135
     136void usb_kbd_free(usb_kbd_t **kbd_dev);
     137
     138void usb_kbd_push_ev(usb_kbd_t *kbd_dev, int type, unsigned int key);
     139
     140#endif /* USB_KBDDEV_H_ */
    123141
    124142/**
  • uspace/drv/usbkbd/kbdrepeat.c

    r96bfe76 r9c0f158  
    6262 *
    6363 * If the currently repeated key is not pressed any more (
    64  * usbhid_kbd_repeat_stop() was called), it stops repeating it and starts
     64 * usb_kbd_repeat_stop() was called), it stops repeating it and starts
    6565 * checking again.
    6666 *
     
    7070 * @param kbd Keyboard device structure.
    7171 */
    72 static void usbhid_kbd_repeat_loop(usbhid_kbd_t *kbd)
     72static void usb_kbd_repeat_loop(usb_kbd_t *kbd)
    7373{
    7474        unsigned int delay = 0;
     
    7878        while (true) {
    7979                // check if the kbd structure is usable
    80                 if (!usbhid_kbd_is_usable(kbd)) {
    81                         usbhid_kbd_free(&kbd);
    82                         assert(kbd == NULL);
     80                if (!usb_kbd_is_initialized(kbd)) {
     81                        if (usb_kbd_is_ready_to_destroy(kbd)) {
     82                                usb_kbd_free(&kbd);
     83                                assert(kbd == NULL);
     84                        }
    8385                        return;
    8486                }
     
    9092                                usb_log_debug2("Repeating key: %u.\n",
    9193                                    kbd->repeat.key_repeated);
    92                                 usbhid_kbd_push_ev(kbd, KEY_PRESS,
     94                                usb_kbd_push_ev(kbd, KEY_PRESS,
    9395                                    kbd->repeat.key_repeated);
    9496                                delay = kbd->repeat.delay_between;
     
    125127 * @retval EINVAL if no argument is supplied.
    126128 */
    127 int usbhid_kbd_repeat_fibril(void *arg)
     129int usb_kbd_repeat_fibril(void *arg)
    128130{
    129131        usb_log_debug("Autorepeat fibril spawned.\n");
     
    134136        }
    135137       
    136         usbhid_kbd_t *kbd = (usbhid_kbd_t *)arg;
     138        usb_kbd_t *kbd = (usb_kbd_t *)arg;
    137139       
    138         usbhid_kbd_repeat_loop(kbd);
     140        usb_kbd_repeat_loop(kbd);
    139141       
    140142        return EOK;
     
    152154 * @param key Key to start repeating.
    153155 */
    154 void usbhid_kbd_repeat_start(usbhid_kbd_t *kbd, unsigned int key)
     156void usb_kbd_repeat_start(usb_kbd_t *kbd, unsigned int key)
    155157{
    156158        fibril_mutex_lock(kbd->repeat_mtx);
     
    170172 * @param key Key to stop repeating.
    171173 */
    172 void usbhid_kbd_repeat_stop(usbhid_kbd_t *kbd, unsigned int key)
     174void usb_kbd_repeat_stop(usb_kbd_t *kbd, unsigned int key)
    173175{
    174176        fibril_mutex_lock(kbd->repeat_mtx);
  • uspace/drv/usbkbd/kbdrepeat.h

    r96bfe76 r9c0f158  
    3434 */
    3535
    36 #ifndef USBHID_KBDREPEAT_H_
    37 #define USBHID_KBDREPEAT_H_
     36#ifndef USB_KBDREPEAT_H_
     37#define USB_KBDREPEAT_H_
    3838
    39 #include "kbddev.h"
     39struct usb_kbd_t;
     40
     41/*----------------------------------------------------------------------------*/
     42/**
     43 * Structure for keeping information needed for auto-repeat of keys.
     44 */
     45typedef struct {
     46        /** Last pressed key. */
     47        unsigned int key_new;
     48        /** Key to be repeated. */
     49        unsigned int key_repeated;
     50        /** Delay before first repeat in microseconds. */
     51        unsigned int delay_before;
     52        /** Delay between repeats in microseconds. */
     53        unsigned int delay_between;
     54} usb_kbd_repeat_t;
    4055
    4156/*----------------------------------------------------------------------------*/
    4257
    43 int usbhid_kbd_repeat_fibril(void *arg);
     58int usb_kbd_repeat_fibril(void *arg);
    4459
    45 void usbhid_kbd_repeat_start(usbhid_kbd_t *kbd, unsigned int key);
     60void usb_kbd_repeat_start(struct usb_kbd_t *kbd, unsigned int key);
    4661
    47 void usbhid_kbd_repeat_stop(usbhid_kbd_t *kbd, unsigned int key);
     62void usb_kbd_repeat_stop(struct usb_kbd_t *kbd, unsigned int key);
    4863
    49 #endif /* USBHID_KBDREPEAT_H_ */
     64#endif /* USB_KBDREPEAT_H_ */
    5065
    5166/**
  • uspace/drv/usbkbd/layout.h

    r96bfe76 r9c0f158  
    3636 */
    3737
    38 #ifndef USBHID_LAYOUT_H_
    39 #define USBHID_LAYOUT_H_
     38#ifndef USB_KBD_LAYOUT_H_
     39#define USB_KBD_LAYOUT_H_
    4040
    4141#include <sys/types.h>
  • uspace/lib/usb/Makefile

    r96bfe76 r9c0f158  
    5050        src/usb.c \
    5151        src/usbdevice.c \
     52        src/hidreq.c \
     53        src/hidreport.c \
    5254        src/host/device_keeper.c \
    5355        src/host/batch.c
  • uspace/lib/usb/include/usb/classes/hidreport.h

    r96bfe76 r9c0f158  
    11/*
    2  * Copyright (c) 2010 Lubos Slovak
     2 * Copyright (c) 2011 Lubos Slovak
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup drvusbhid
     29/** @addtogroup libusb
    3030 * @{
    3131 */
    3232/** @file
    33  * Descriptor dumping.
     33 * USB HID report parser initialization from descriptors.
    3434 */
    3535
    36 #ifndef USBHID_DESCDUMP_H_
    37 #define USBHID_DESCDUMP_H_
     36#ifndef LIBUSB_HIDREPORT_H_
     37#define LIBUSB_HIDREPORT_H_
    3838
    39 #include <usb/descriptor.h>
    40 #include <usb/classes/hid.h>
     39#include <usb/devdrv.h>
     40#include <usb/classes/hidparser.h>
    4141
    42 void dump_standard_configuration_descriptor(
    43     int index, const usb_standard_configuration_descriptor_t *d);
     42/**
     43 * Retrieves the Report descriptor from the USB device and initializes the
     44 * report parser.
     45 *
     46 * \param dev USB device representing a HID device.
     47 * \param parser HID Report parser.
     48 *
     49 * \retval EOK if successful.
     50 * \retval EINVAL if one of the parameters is not given (is NULL).
     51 * \retval ENOENT if there are some descriptors missing.
     52 * \retval ENOMEM if an error with allocation occured.
     53 * \retval EINVAL if the Report descriptor's size does not match the size
     54 *         from the interface descriptor.
     55 * \return Other value inherited from function usb_pipe_start_session(),
     56 *         usb_pipe_end_session() or usb_request_get_descriptor().
     57 */
     58int usb_hid_process_report_descriptor(usb_device_t *dev,
     59    usb_hid_report_parser_t *parser);
    4460
    45 void dump_standard_interface_descriptor(
    46     const usb_standard_interface_descriptor_t *d);
    47 
    48 void dump_standard_endpoint_descriptor(
    49     const usb_standard_endpoint_descriptor_t *d);
    50 
    51 void dump_standard_hid_descriptor_header(
    52     const usb_standard_hid_descriptor_t *d);
    53 
    54 void dump_standard_hid_class_descriptor_info(
    55     const usb_standard_hid_class_descriptor_info_t *d);
    56 
    57 void dump_hid_class_descriptor(int index, uint8_t type,
    58     const uint8_t *d, size_t size);
    59 
    60 #endif /* USBHID_DESCDUMP_H_ */
     61#endif /* LIBUSB_HIDREPORT_H_ */
    6162
    6263/**
  • uspace/lib/usb/include/usb/classes/hidreq.h

    r96bfe76 r9c0f158  
    2727 */
    2828
    29 /** @addtogroup drvusbhid
     29/** @addtogroup libusb
    3030 * @{
    3131 */
     
    3434 */
    3535
    36 #ifndef USBHID_HIDREQ_H_
    37 #define USBHID_HIDREQ_H_
     36#ifndef USB_KBD_HIDREQ_H_
     37#define USB_KBD_HIDREQ_H_
    3838
    3939#include <stdint.h>
    4040
    4141#include <usb/classes/hid.h>
    42 
    43 #include "hiddev.h"
     42#include <usb/pipes.h>
    4443
    4544/*----------------------------------------------------------------------------*/
    4645
    47 int usbhid_req_set_report(usbhid_dev_t *hid_dev,
     46int usbhid_req_set_report(usb_pipe_t *ctrl_pipe, int iface_no,
    4847    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size);
    4948
    50 int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol);
     49int usbhid_req_set_protocol(usb_pipe_t *ctrl_pipe, int iface_no,
     50    usb_hid_protocol_t protocol);
    5151
    52 int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration);
     52int usbhid_req_set_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t duration);
    5353
    54 int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type,
    55     uint8_t *buffer, size_t buf_size, size_t *actual_size);
     54int usbhid_req_get_report(usb_pipe_t *ctrl_pipe, int iface_no,
     55    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size,
     56    size_t *actual_size);
    5657
    57 int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol);
     58int usbhid_req_get_protocol(usb_pipe_t *ctrl_pipe, int iface_no,
     59    usb_hid_protocol_t *protocol);
    5860
    59 int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration);
     61int usbhid_req_get_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t *duration);
    6062
    6163/*----------------------------------------------------------------------------*/
    6264
    63 #endif /* USBHID_HIDREQ_H_ */
     65#endif /* USB_KBD_HIDREQ_H_ */
    6466
    6567/**
  • uspace/lib/usb/include/usb/request.h

    r96bfe76 r9c0f158  
    4141#include <usb/pipes.h>
    4242#include <usb/descriptor.h>
     43
     44/** USB device status - device is self powered (opposed to bus powered). */
     45#define USB_DEVICE_STATUS_SELF_POWERED ((uint16_t)(1 << 0))
     46
     47/** USB device status - remote wake-up signaling is enabled. */
     48#define USB_DEVICE_STATUS_REMOTE_WAKEUP ((uint16_t)(1 << 1))
     49
     50/** USB endpoint status - endpoint is halted (stalled). */
     51#define USB_ENDPOINT_STATUS_HALTED ((uint16_t)(1 << 0))
    4352
    4453/** Standard device request. */
  • uspace/lib/usb/src/hidreq.c

    r96bfe76 r9c0f158  
    4141#include <usb/debug.h>
    4242#include <usb/request.h>
    43 
    44 #include "hidreq.h"
    45 #include "hiddev.h"
     43#include <usb/pipes.h>
     44
     45#include <usb/classes/hidreq.h>
    4646
    4747/*----------------------------------------------------------------------------*/
     
    6060 *         usb_control_request_set().
    6161 */
    62 int usbhid_req_set_report(usbhid_dev_t *hid_dev,
     62int usbhid_req_set_report(usb_pipe_t *ctrl_pipe, int iface_no,
    6363    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size)
    6464{
    65         if (hid_dev == NULL) {
    66                 usb_log_error("usbhid_req_set_report(): no HID device structure"
    67                     " given.\n");
    68                 return EINVAL;
    69         }
    70        
    71         /*
    72          * No need for checking other parameters, as they are checked in
    73          * the called function (usb_control_request_set()).
    74          */
    75        
    76         int rc, sess_rc;
    77        
    78         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     65        if (ctrl_pipe == NULL) {
     66                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     67                return EINVAL;
     68        }
     69       
     70        if (iface_no < 0) {
     71                usb_log_warning("usbhid_req_set_report(): no interface given."
     72                    "\n");
     73                return EINVAL;
     74        }
     75       
     76        /*
     77         * No need for checking other parameters, as they are checked in
     78         * the called function (usb_control_request_set()).
     79         */
     80       
     81        int rc, sess_rc;
     82       
     83        sess_rc = usb_pipe_start_session(ctrl_pipe);
    7984        if (sess_rc != EOK) {
    8085                usb_log_warning("Failed to start a session: %s.\n",
     
    8893        usb_log_debug("Sending Set_Report request to the device.\n");
    8994       
    90         rc = usb_control_request_set(&hid_dev->ctrl_pipe,
    91             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    92             USB_HIDREQ_SET_REPORT, value, hid_dev->iface, buffer, buf_size);
    93 
    94         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     95        rc = usb_control_request_set(ctrl_pipe,
     96            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     97            USB_HIDREQ_SET_REPORT, value, iface_no, buffer, buf_size);
     98
     99        sess_rc = usb_pipe_end_session(ctrl_pipe);
    95100
    96101        if (rc != EOK) {
     
    122127 *         usb_control_request_set().
    123128 */
    124 int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol)
    125 {
    126         if (hid_dev == NULL) {
    127                 usb_log_error("usbhid_req_set_protocol(): no HID device "
    128                     "structure given.\n");
    129                 return EINVAL;
    130         }
    131        
    132         /*
    133          * No need for checking other parameters, as they are checked in
    134          * the called function (usb_control_request_set()).
    135          */
    136        
    137         int rc, sess_rc;
    138        
    139         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     129int usbhid_req_set_protocol(usb_pipe_t *ctrl_pipe, int iface_no,
     130    usb_hid_protocol_t protocol)
     131{
     132        if (ctrl_pipe == NULL) {
     133                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     134                return EINVAL;
     135        }
     136       
     137        if (iface_no < 0) {
     138                usb_log_warning("usbhid_req_set_report(): no interface given."
     139                    "\n");
     140                return EINVAL;
     141        }
     142       
     143        /*
     144         * No need for checking other parameters, as they are checked in
     145         * the called function (usb_control_request_set()).
     146         */
     147       
     148        int rc, sess_rc;
     149       
     150        sess_rc = usb_pipe_start_session(ctrl_pipe);
    140151        if (sess_rc != EOK) {
    141152                usb_log_warning("Failed to start a session: %s.\n",
     
    145156
    146157        usb_log_debug("Sending Set_Protocol request to the device ("
    147             "protocol: %d, iface: %d).\n", protocol, hid_dev->iface);
    148        
    149         rc = usb_control_request_set(&hid_dev->ctrl_pipe,
    150             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    151             USB_HIDREQ_SET_PROTOCOL, protocol, hid_dev->iface, NULL, 0);
    152 
    153         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     158            "protocol: %d, iface: %d).\n", protocol, iface_no);
     159       
     160        rc = usb_control_request_set(ctrl_pipe,
     161            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     162            USB_HIDREQ_SET_PROTOCOL, protocol, iface_no, NULL, 0);
     163
     164        sess_rc = usb_pipe_end_session(ctrl_pipe);
    154165
    155166        if (rc != EOK) {
     
    182193 *         usb_control_request_set().
    183194 */
    184 int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration)
    185 {
    186         if (hid_dev == NULL) {
    187                 usb_log_error("usbhid_req_set_idle(): no HID device "
    188                     "structure given.\n");
    189                 return EINVAL;
    190         }
    191        
    192         /*
    193          * No need for checking other parameters, as they are checked in
    194          * the called function (usb_control_request_set()).
    195          */
    196        
    197         int rc, sess_rc;
    198        
    199         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     195int usbhid_req_set_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t duration)
     196{
     197        if (ctrl_pipe == NULL) {
     198                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     199                return EINVAL;
     200        }
     201       
     202        if (iface_no < 0) {
     203                usb_log_warning("usbhid_req_set_report(): no interface given."
     204                    "\n");
     205                return EINVAL;
     206        }
     207       
     208        /*
     209         * No need for checking other parameters, as they are checked in
     210         * the called function (usb_control_request_set()).
     211         */
     212       
     213        int rc, sess_rc;
     214       
     215        sess_rc = usb_pipe_start_session(ctrl_pipe);
    200216        if (sess_rc != EOK) {
    201217                usb_log_warning("Failed to start a session: %s.\n",
     
    205221
    206222        usb_log_debug("Sending Set_Idle request to the device ("
    207             "duration: %u, iface: %d).\n", duration, hid_dev->iface);
     223            "duration: %u, iface: %d).\n", duration, iface_no);
    208224       
    209225        uint16_t value = duration << 8;
    210226       
    211         rc = usb_control_request_set(&hid_dev->ctrl_pipe,
    212             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    213             USB_HIDREQ_SET_IDLE, value, hid_dev->iface, NULL, 0);
    214 
    215         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     227        rc = usb_control_request_set(ctrl_pipe,
     228            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     229            USB_HIDREQ_SET_IDLE, value, iface_no, NULL, 0);
     230
     231        sess_rc = usb_pipe_end_session(ctrl_pipe);
    216232
    217233        if (rc != EOK) {
     
    247263 *         usb_control_request_set().
    248264 */
    249 int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type,
    250     uint8_t *buffer, size_t buf_size, size_t *actual_size)
    251 {
    252         if (hid_dev == NULL) {
    253                 usb_log_error("usbhid_req_set_report(): no HID device structure"
    254                     " given.\n");
    255                 return EINVAL;
    256         }
    257        
    258         /*
    259          * No need for checking other parameters, as they are checked in
    260          * the called function (usb_control_request_set()).
    261          */
    262        
    263         int rc, sess_rc;
    264        
    265         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     265int usbhid_req_get_report(usb_pipe_t *ctrl_pipe, int iface_no,
     266    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size,
     267    size_t *actual_size)
     268{
     269        if (ctrl_pipe == NULL) {
     270                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     271                return EINVAL;
     272        }
     273       
     274        if (iface_no < 0) {
     275                usb_log_warning("usbhid_req_set_report(): no interface given."
     276                    "\n");
     277                return EINVAL;
     278        }
     279       
     280        /*
     281         * No need for checking other parameters, as they are checked in
     282         * the called function (usb_control_request_set()).
     283         */
     284       
     285        int rc, sess_rc;
     286       
     287        sess_rc = usb_pipe_start_session(ctrl_pipe);
    266288        if (sess_rc != EOK) {
    267289                usb_log_warning("Failed to start a session: %s.\n",
     
    275297        usb_log_debug("Sending Get_Report request to the device.\n");
    276298       
    277         rc = usb_control_request_get(&hid_dev->ctrl_pipe,
    278             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    279             USB_HIDREQ_GET_REPORT, value, hid_dev->iface, buffer, buf_size,
     299        rc = usb_control_request_get(ctrl_pipe,
     300            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     301            USB_HIDREQ_GET_REPORT, value, iface_no, buffer, buf_size,
    280302            actual_size);
    281303
    282         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     304        sess_rc = usb_pipe_end_session(ctrl_pipe);
    283305
    284306        if (rc != EOK) {
     
    310332 *         usb_control_request_set().
    311333 */
    312 int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol)
    313 {
    314         if (hid_dev == NULL) {
    315                 usb_log_error("usbhid_req_set_protocol(): no HID device "
    316                     "structure given.\n");
    317                 return EINVAL;
    318         }
    319        
    320         /*
    321          * No need for checking other parameters, as they are checked in
    322          * the called function (usb_control_request_set()).
    323          */
    324        
    325         int rc, sess_rc;
    326        
    327         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     334int usbhid_req_get_protocol(usb_pipe_t *ctrl_pipe, int iface_no,
     335    usb_hid_protocol_t *protocol)
     336{
     337        if (ctrl_pipe == NULL) {
     338                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     339                return EINVAL;
     340        }
     341       
     342        if (iface_no < 0) {
     343                usb_log_warning("usbhid_req_set_report(): no interface given."
     344                    "\n");
     345                return EINVAL;
     346        }
     347       
     348        /*
     349         * No need for checking other parameters, as they are checked in
     350         * the called function (usb_control_request_set()).
     351         */
     352       
     353        int rc, sess_rc;
     354       
     355        sess_rc = usb_pipe_start_session(ctrl_pipe);
    328356        if (sess_rc != EOK) {
    329357                usb_log_warning("Failed to start a session: %s.\n",
     
    333361
    334362        usb_log_debug("Sending Get_Protocol request to the device ("
    335             "iface: %d).\n", hid_dev->iface);
     363            "iface: %d).\n", iface_no);
    336364       
    337365        uint8_t buffer[1];
    338366        size_t actual_size = 0;
    339367       
    340         rc = usb_control_request_get(&hid_dev->ctrl_pipe,
    341             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    342             USB_HIDREQ_GET_PROTOCOL, 0, hid_dev->iface, buffer, 1, &actual_size);
    343 
    344         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     368        rc = usb_control_request_get(ctrl_pipe,
     369            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     370            USB_HIDREQ_GET_PROTOCOL, 0, iface_no, buffer, 1, &actual_size);
     371
     372        sess_rc = usb_pipe_end_session(ctrl_pipe);
    345373
    346374        if (rc != EOK) {
     
    381409 *         usb_control_request_set().
    382410 */
    383 int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration)
    384 {
    385         if (hid_dev == NULL) {
    386                 usb_log_error("usbhid_req_set_idle(): no HID device "
    387                     "structure given.\n");
    388                 return EINVAL;
    389         }
    390        
    391         /*
    392          * No need for checking other parameters, as they are checked in
    393          * the called function (usb_control_request_set()).
    394          */
    395        
    396         int rc, sess_rc;
    397        
    398         sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe);
     411int usbhid_req_get_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t *duration)
     412{
     413        if (ctrl_pipe == NULL) {
     414                usb_log_warning("usbhid_req_set_report(): no pipe given.\n");
     415                return EINVAL;
     416        }
     417       
     418        if (iface_no < 0) {
     419                usb_log_warning("usbhid_req_set_report(): no interface given."
     420                    "\n");
     421                return EINVAL;
     422        }
     423       
     424        /*
     425         * No need for checking other parameters, as they are checked in
     426         * the called function (usb_control_request_set()).
     427         */
     428       
     429        int rc, sess_rc;
     430       
     431        sess_rc = usb_pipe_start_session(ctrl_pipe);
    399432        if (sess_rc != EOK) {
    400433                usb_log_warning("Failed to start a session: %s.\n",
     
    404437
    405438        usb_log_debug("Sending Get_Idle request to the device ("
    406             "iface: %d).\n", hid_dev->iface);
     439            "iface: %d).\n", iface_no);
    407440       
    408441        uint16_t value = 0;
     
    410443        size_t actual_size = 0;
    411444       
    412         rc = usb_control_request_get(&hid_dev->ctrl_pipe,
    413             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    414             USB_HIDREQ_GET_IDLE, value, hid_dev->iface, buffer, 1,
     445        rc = usb_control_request_get(ctrl_pipe,
     446            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     447            USB_HIDREQ_GET_IDLE, value, iface_no, buffer, 1,
    415448            &actual_size);
    416449
    417         sess_rc = usb_pipe_end_session(&hid_dev->ctrl_pipe);
     450        sess_rc = usb_pipe_end_session(ctrl_pipe);
    418451
    419452        if (rc != EOK) {
Note: See TracChangeset for help on using the changeset viewer.