Changeset 81c508c in mainline


Ignore:
Timestamp:
2011-02-27T00:25:28Z (13 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
299d53e, cc44f7e
Parents:
b8622e2 (diff), c2fa801 (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:

USBHID: logging (#76), modifiers (#65), locks (#66), LEDs (#26), init (#67).

Location:
uspace
Files:
2 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhid/Makefile

    rb8622e2 r81c508c  
    3939SOURCES = \
    4040        main.c \
    41         descparser.c \
    42         descdump.c \
    4341        conv.c \
    4442        $(STOLEN_LAYOUT_SOURCES)
  • uspace/drv/usbhid/conv.c

    rb8622e2 r81c508c  
    3636#include <io/keycode.h>
    3737#include <stdint.h>
     38#include <stdio.h>
     39#include <usb/debug.h>
    3840#include "conv.h"
    3941
     
    141143        //[0xe7] = KC_R // TODO: right GUI
    142144       
     145        [0x53] = KC_NUM_LOCK,
     146        [0x54] = KC_NSLASH,
     147        [0x55] = KC_NTIMES,
     148        [0x56] = KC_NMINUS,
     149        [0x57] = KC_NPLUS,
     150        [0x58] = KC_NENTER,
     151        [0x59] = KC_N1,
     152        [0x5a] = KC_N2,
     153        [0x5b] = KC_N3,
     154        [0x5c] = KC_N4,
     155        [0x5d] = KC_N5,
     156        [0x5e] = KC_N6,
     157        [0x5f] = KC_N7,
     158        [0x60] = KC_N8,
     159        [0x61] = KC_N9,
     160        [0x62] = KC_N0,
     161        [0x63] = KC_NPERIOD
     162       
    143163};
    144164
     
    189209
    190210        key = map[scancode];
     211       
     212        if (scancode == 0x53) {
     213                usb_log_debug("\n\nWe have a NUM LOCK!, sending key %u\n\n", key);
     214        }
     215       
     216        if (scancode == 0x47) {
     217                usb_log_debug("\n\nWe have a SCROLL LOCK!, sending key %u\n\n", key);
     218        }
     219       
     220        if (scancode == 0x39) {
     221                usb_log_debug("\n\nWe have a CAPS LOCK!, sending key %u\n\n", key);
     222        }
     223       
    191224//      if (key != 0)
    192225//              kbd_push_ev(type, key);
  • uspace/drv/usbhid/hid.h

    rb8622e2 r81c508c  
    3737#define USBHID_HID_H_
    3838
     39#include <stdint.h>
     40
    3941#include <usb/classes/hid.h>
    4042#include <ddf/driver.h>
    4143#include <usb/pipes.h>
    42 
    43 /**
    44  *
    45  */
    46 typedef struct {
    47         usb_standard_interface_descriptor_t iface_desc;
    48         usb_standard_endpoint_descriptor_t *endpoints;
    49         usb_standard_hid_descriptor_t hid_desc;
    50         uint8_t *report_desc;
    51         //usb_standard_hid_class_descriptor_info_t *class_desc_info;
    52         //uint8_t **class_descs;
    53 } usb_hid_iface_t;
    54 
    55 /**
    56  *
    57  */
    58 typedef struct {
    59         usb_standard_configuration_descriptor_t config_descriptor;
    60         usb_hid_iface_t *interfaces;
    61 } usb_hid_configuration_t;
    6244
    6345/**
     
    6850typedef struct {
    6951        ddf_dev_t *device;
    70         usb_hid_configuration_t *conf;
    71         usb_hid_report_parser_t *parser;
    7252
    7353        usb_device_connection_t wire;
    7454        usb_endpoint_pipe_t ctrl_pipe;
    7555        usb_endpoint_pipe_t poll_pipe;
     56       
     57        uint16_t iface;
     58       
     59        uint8_t *report_desc;
     60        usb_hid_report_parser_t *parser;
     61       
     62        uint8_t *keycodes;
     63        size_t keycode_count;
     64        uint8_t modifiers;
     65       
     66        unsigned mods;
     67        unsigned lock_keys;
    7668} usb_hid_dev_kbd_t;
    7769
    78 // TODO: more configurations!
    79 
    8070#endif
  • uspace/drv/usbhid/main.c

    rb8622e2 r81c508c  
    5151#include <usb/descriptor.h>
    5252#include <io/console.h>
     53#include <stdint.h>
     54#include <usb/dp.h>
    5355#include "hid.h"
    54 #include "descparser.h"
    55 #include "descdump.h"
    5656#include "conv.h"
    5757#include "layout.h"
    5858
    5959#define BUFFER_SIZE 8
     60#define BUFFER_OUT_SIZE 1
    6061#define NAME "usbhid"
    6162
    62 #define GUESSED_POLL_ENDPOINT 1
     63//#define GUESSED_POLL_ENDPOINT 1
     64#define BOOTP_REPORT_SIZE 6
     65
     66static unsigned DEFAULT_ACTIVE_MODS = KM_NUM_LOCK;
    6367
    6468/** Keyboard polling endpoint description for boot protocol class. */
     
    120124
    121125static void dump_buffer(const char *msg, const uint8_t *buffer, size_t length)
    122 {
     126{uint8_t buffer[BUFFER_SIZE];
    123127        printf("%s\n", msg);
    124128       
     
    137141 */
    138142
    139 /** Currently active modifiers.
     143/** Currently active modifiers (locks is probably better word).
    140144 *
    141145 * TODO: put to device?
    142146 */
    143 static unsigned mods = KM_NUM_LOCK;
     147//static unsigned mods = KM_NUM_LOCK;
    144148
    145149/** Currently pressed lock keys. We track these to tackle autorepeat. 
     
    147151 * TODO: put to device?
    148152 */
    149 static unsigned lock_keys;
     153//static unsigned lock_keys;
    150154
    151155#define NUM_LAYOUTS 3
     
    159163static int active_layout = 0;
    160164
    161 static void kbd_push_ev(int type, unsigned int key)
     165static void usbkbd_req_set_report(usb_hid_dev_kbd_t *kbd_dev, uint16_t iface,
     166    usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size)
     167{
     168        int rc, sess_rc;
     169       
     170        sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);
     171        if (sess_rc != EOK) {
     172                usb_log_warning("Failed to start a session: %s.\n",
     173                    str_error(sess_rc));
     174                return;
     175        }
     176
     177        usb_log_debug("Sending Set_Report request to the device.\n");
     178       
     179        rc = usb_control_request_set(&kbd_dev->ctrl_pipe,
     180            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     181            USB_HIDREQ_SET_REPORT, type, iface, buffer, buf_size);
     182
     183        sess_rc = usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);
     184
     185        if (rc != EOK) {
     186                usb_log_warning("Error sending output report to the keyboard: "
     187                    "%s.\n", str_error(rc));
     188                return;
     189        }
     190
     191        if (sess_rc != EOK) {
     192                usb_log_warning("Error closing session: %s.\n",
     193                    str_error(sess_rc));
     194                return;
     195        }
     196}
     197
     198static void usbkbd_req_set_protocol(usb_hid_dev_kbd_t *kbd_dev,
     199    usb_hid_protocol_t protocol)
     200{
     201        int rc, sess_rc;
     202       
     203        sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);
     204        if (sess_rc != EOK) {
     205                usb_log_warning("Failed to start a session: %s.\n",
     206                    str_error(sess_rc));
     207                return;
     208        }
     209
     210        usb_log_debug("Sending Set_Protocol request to the device ("
     211            "protocol: %d, iface: %d).\n", protocol, kbd_dev->iface);
     212       
     213        rc = usb_control_request_set(&kbd_dev->ctrl_pipe,
     214            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
     215            USB_HIDREQ_SET_PROTOCOL, protocol, kbd_dev->iface, NULL, 0);
     216
     217        sess_rc = usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);
     218
     219        if (rc != EOK) {
     220                usb_log_warning("Error sending output report to the keyboard: "
     221                    "%s.\n", str_error(rc));
     222                return;
     223        }
     224
     225        if (sess_rc != EOK) {
     226                usb_log_warning("Error closing session: %s.\n",
     227                    str_error(sess_rc));
     228                return;
     229        }
     230}
     231
     232static void usbkbd_set_led(usb_hid_dev_kbd_t *kbd_dev)
     233{
     234        uint8_t buffer[BUFFER_OUT_SIZE];
     235        int rc= 0, i;
     236       
     237        memset(buffer, 0, BUFFER_OUT_SIZE);
     238        uint8_t leds = 0;
     239
     240        if (kbd_dev->mods & KM_NUM_LOCK) {
     241                leds |= USB_HID_LED_NUM_LOCK;
     242        }
     243       
     244        if (kbd_dev->mods & KM_CAPS_LOCK) {
     245                leds |= USB_HID_LED_CAPS_LOCK;
     246        }
     247       
     248        if (kbd_dev->mods & KM_SCROLL_LOCK) {
     249                leds |= USB_HID_LED_SCROLL_LOCK;
     250        }
     251
     252        // TODO: COMPOSE and KANA
     253       
     254        usb_log_debug("Creating output report.\n");
     255        usb_log_debug("Leds: 0x%x\n", leds);
     256        if ((rc = usb_hid_boot_keyboard_output_report(
     257            leds, buffer, BUFFER_OUT_SIZE)) != EOK) {
     258                usb_log_warning("Error composing output report to the keyboard:"
     259                    "%s.\n", str_error(rc));
     260                return;
     261        }
     262       
     263        usb_log_debug("Output report buffer: ");
     264        for (i = 0; i < BUFFER_OUT_SIZE; ++i) {
     265                usb_log_debug("0x%x ", buffer[i]);
     266        }
     267        usb_log_debug("\n");
     268       
     269        uint16_t value = 0;
     270        value |= (USB_HID_REPORT_TYPE_OUTPUT << 8);
     271
     272        usbkbd_req_set_report(kbd_dev, kbd_dev->iface, value, buffer,
     273            BUFFER_OUT_SIZE);
     274}
     275
     276static void kbd_push_ev(int type, unsigned int key, usb_hid_dev_kbd_t *kbd_dev)
    162277{
    163278        console_event_t ev;
     
    177292        if (mod_mask != 0) {
    178293                if (type == KEY_PRESS)
    179                         mods = mods | mod_mask;
     294                        kbd_dev->mods = kbd_dev->mods | mod_mask;
    180295                else
    181                         mods = mods & ~mod_mask;
     296                        kbd_dev->mods = kbd_dev->mods & ~mod_mask;
    182297        }
    183298
    184299        switch (key) {
    185         case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break;
    186         case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break;
    187         case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break;
     300        case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; usb_log_debug2("\n\nPushing CAPS LOCK! (mask: %u)\n\n", mod_mask); break;
     301        case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; usb_log_debug2("\n\nPushing NUM LOCK! (mask: %u)\n\n", mod_mask); break;
     302        case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; usb_log_debug2("\n\nPushing SCROLL LOCK! (mask: %u)\n\n", mod_mask); break;
    188303        default: mod_mask = 0; break;
    189304        }
    190305
    191306        if (mod_mask != 0) {
     307                usb_log_debug2("\n\nChanging mods and lock keys\n");
     308                usb_log_debug2("\nmods before: 0x%x\n", kbd_dev->mods);
     309                usb_log_debug2("\nLock keys before:0x%x\n\n", kbd_dev->lock_keys);
     310               
    192311                if (type == KEY_PRESS) {
     312                        usb_log_debug2("\nKey pressed.\n");
    193313                        /*
    194314                         * Only change lock state on transition from released
     
    196316                         * up the lock state.
    197317                         */
    198                         mods = mods ^ (mod_mask & ~lock_keys);
    199                         lock_keys = lock_keys | mod_mask;
     318                        kbd_dev->mods =
     319                            kbd_dev->mods ^ (mod_mask & ~kbd_dev->lock_keys);
     320                        kbd_dev->lock_keys = kbd_dev->lock_keys | mod_mask;
    200321
    201322                        /* Update keyboard lock indicator lights. */
    202                         // TODO
    203                         //kbd_ctl_set_ind(mods);
     323                        usbkbd_set_led(kbd_dev);
    204324                } else {
    205                         lock_keys = lock_keys & ~mod_mask;
    206                 }
    207         }
    208 /*
    209         printf("type: %d\n", type);
    210         printf("mods: 0x%x\n", mods);
    211         printf("keycode: %u\n", key);
    212 */
    213        
    214         if (type == KEY_PRESS && (mods & KM_LCTRL) &&
    215                 key == KC_F1) {
     325                        usb_log_debug2("\nKey released.\n");
     326                        kbd_dev->lock_keys = kbd_dev->lock_keys & ~mod_mask;
     327                }
     328        }
     329
     330        usb_log_debug2("\n\nmods after: 0x%x\n", kbd_dev->mods);
     331        usb_log_debug2("\nLock keys after: 0x%x\n\n", kbd_dev->lock_keys);
     332       
     333        if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F1) {
    216334                active_layout = 0;
    217335                layout[active_layout]->reset();
     
    219337        }
    220338
    221         if (type == KEY_PRESS && (mods & KM_LCTRL) &&
    222                 key == KC_F2) {
     339        if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F2) {
    223340                active_layout = 1;
    224341                layout[active_layout]->reset();
     
    226343        }
    227344
    228         if (type == KEY_PRESS && (mods & KM_LCTRL) &&
    229                 key == KC_F3) {
     345        if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F3) {
    230346                active_layout = 2;
    231347                layout[active_layout]->reset();
     
    235351        ev.type = type;
    236352        ev.key = key;
    237         ev.mods = mods;
     353        ev.mods = kbd_dev->mods;
     354       
     355        if (ev.mods & KM_NUM_LOCK) {
     356                usb_log_debug("\n\nNum Lock turned on.\n\n");
     357        }
    238358
    239359        ev.c = layout[active_layout]->parse_ev(&ev);
    240360
    241         printf("Sending key %d to the console\n", ev.key);
     361        usb_log_debug2("Sending key %d to the console\n", ev.key);
    242362        assert(console_callback_phone != -1);
    243         async_msg_4(console_callback_phone, KBD_EVENT, ev.type, ev.key, ev.mods, ev.c);
     363        async_msg_4(console_callback_phone, KBD_EVENT, ev.type, ev.key,
     364            ev.mods, ev.c);
    244365}
    245366/*
     
    249370        /*
    250371         * TODO:
    251          * 1) key press / key release - how does the keyboard notify about release?
     372         * 1) key press / key release - how does the keyboard notify about
     373         *    release?
    252374         * 2) layouts (use the already defined), not important now
    253375         * 3)
    254376         */
    255377
     378static const keycode_t usb_hid_modifiers_keycodes[USB_HID_MOD_COUNT] = {
     379        KC_LCTRL,         /* USB_HID_MOD_LCTRL */
     380        KC_LSHIFT,        /* USB_HID_MOD_LSHIFT */
     381        KC_LALT,          /* USB_HID_MOD_LALT */
     382        0,                /* USB_HID_MOD_LGUI */
     383        KC_RCTRL,         /* USB_HID_MOD_RCTRL */
     384        KC_RSHIFT,        /* USB_HID_MOD_RSHIFT */
     385        KC_RALT,          /* USB_HID_MOD_RALT */
     386        0,                /* USB_HID_MOD_RGUI */
     387};
     388
     389static void usbkbd_check_modifier_changes(usb_hid_dev_kbd_t *kbd_dev,
     390    uint8_t modifiers)
     391{
     392        /*
     393         * TODO: why the USB keyboard has NUM_, SCROLL_ and CAPS_LOCK
     394         *       both as modifiers and as keys with their own scancodes???
     395         *
     396         * modifiers should be sent as normal keys to usbkbd_parse_scancode()!!
     397         * so maybe it would be better if I received it from report parser in
     398         * that way
     399         */
     400       
     401        int i;
     402        for (i = 0; i < USB_HID_MOD_COUNT; ++i) {
     403                if ((modifiers & usb_hid_modifiers_consts[i]) &&
     404                    !(kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
     405                        // modifier pressed
     406                        if (usb_hid_modifiers_keycodes[i] != 0) {
     407                                kbd_push_ev(KEY_PRESS,
     408                                    usb_hid_modifiers_keycodes[i], kbd_dev);
     409                        }
     410                } else if (!(modifiers & usb_hid_modifiers_consts[i]) &&
     411                    (kbd_dev->modifiers & usb_hid_modifiers_consts[i])) {
     412                        // modifier released
     413                        if (usb_hid_modifiers_keycodes[i] != 0) {
     414                                kbd_push_ev(KEY_RELEASE,
     415                                    usb_hid_modifiers_keycodes[i], kbd_dev);
     416                        }
     417                }       // no change
     418        }
     419       
     420        kbd_dev->modifiers = modifiers;
     421}
     422
     423static void usbkbd_check_key_changes(usb_hid_dev_kbd_t *kbd_dev,
     424    const uint8_t *key_codes)
     425{
     426        // TODO: phantom state!!
     427       
     428        unsigned int key;
     429        unsigned int i, j;
     430       
     431        // TODO: quite dummy right now, think of better implementation
     432       
     433        // key releases
     434        for (j = 0; j < kbd_dev->keycode_count; ++j) {
     435                // try to find the old key in the new key list
     436                i = 0;
     437                while (i < kbd_dev->keycode_count
     438                    && key_codes[i] != kbd_dev->keycodes[j]) {
     439                        ++i;
     440                }
     441               
     442                if (i == kbd_dev->keycode_count) {
     443                        // not found, i.e. the key was released
     444                        key = usbkbd_parse_scancode(kbd_dev->keycodes[j]);
     445                        kbd_push_ev(KEY_RELEASE, key, kbd_dev);
     446                        usb_log_debug2("\nKey released: %d\n", key);
     447                } else {
     448                        // found, nothing happens
     449                }
     450        }
     451       
     452        // key presses
     453        for (i = 0; i < kbd_dev->keycode_count; ++i) {
     454                // try to find the new key in the old key list
     455                j = 0;
     456                while (j < kbd_dev->keycode_count
     457                    && kbd_dev->keycodes[j] != key_codes[i]) {
     458                        ++j;
     459                }
     460               
     461                if (j == kbd_dev->keycode_count) {
     462                        // not found, i.e. new key pressed
     463                        key = usbkbd_parse_scancode(key_codes[i]);
     464                        usb_log_debug2("\nKey pressed: %d (keycode: %d)\n", key,
     465                            key_codes[i]);
     466                        kbd_push_ev(KEY_PRESS, key, kbd_dev);
     467                } else {
     468                        // found, nothing happens
     469                }
     470        }
     471       
     472        memcpy(kbd_dev->keycodes, key_codes, kbd_dev->keycode_count);
     473       
     474        usb_log_debug2("\nNew stored keycodes: ");
     475        for (i = 0; i < kbd_dev->keycode_count; ++i) {
     476                usb_log_debug2("%d ", kbd_dev->keycodes[i]);
     477        }
     478}
     479
    256480/*
    257481 * Callbacks for parser
     
    260484    uint8_t modifiers, void *arg)
    261485{
    262         printf("Got keys: ");
     486        if (arg == NULL) {
     487                usb_log_warning("Missing argument in callback "
     488                    "usbkbd_process_keycodes().\n");
     489                return;
     490        }
     491
     492        usb_log_debug2("Got keys from parser: ");
    263493        unsigned i;
    264494        for (i = 0; i < count; ++i) {
    265                 printf("%d ", key_codes[i]);
    266         }
    267         printf("\n");
    268 
    269         for (i = 0; i < count; ++i) {
    270                 // TODO: Key press / release
    271 
    272                 // TODO: NOT WORKING
    273                 unsigned int key = usbkbd_parse_scancode(key_codes[i]);
    274 
    275                 if (key == 0) {
    276                         continue;
    277                 }
    278                 kbd_push_ev(KEY_PRESS, key);
    279         }
    280         printf("\n");
     495                usb_log_debug2("%d ", key_codes[i]);
     496        }
     497        usb_log_debug2("\n");
     498       
     499        usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)arg;
     500       
     501        if (count != kbd_dev->keycode_count) {
     502                usb_log_warning("Number of received keycodes (%d) differs from"
     503                    " expected number (%d).\n", count, kbd_dev->keycode_count);
     504                return;
     505        }
     506       
     507        usbkbd_check_modifier_changes(kbd_dev, modifiers);
     508        usbkbd_check_key_changes(kbd_dev, key_codes);
    281509}
    282510
     
    284512 * Kbd functions
    285513 */
    286 static int usbkbd_get_report_descriptor(usb_hid_dev_kbd_t *kbd_dev)
    287 {
    288         // iterate over all configurations and interfaces
    289         // TODO: more configurations!!
    290         unsigned i;
    291         for (i = 0; i < kbd_dev->conf->config_descriptor.interface_count; ++i) {
    292                 // TODO: endianness
    293                 uint16_t length =
    294                     kbd_dev->conf->interfaces[i].hid_desc.report_desc_info.length;
    295                 size_t actual_size = 0;
    296 
    297                 // allocate space for the report descriptor
    298                 kbd_dev->conf->interfaces[i].report_desc = (uint8_t *)malloc(length);
     514//static int usbkbd_get_report_descriptor(usb_hid_dev_kbd_t *kbd_dev)
     515//{
     516//      // iterate over all configurations and interfaces
     517//      // TODO: more configurations!!
     518//      unsigned i;
     519//      for (i = 0; i < kbd_dev->conf->config_descriptor.interface_count; ++i) {
     520//              // TODO: endianness
     521//              uint16_t length =  kbd_dev->conf->interfaces[i].hid_desc.
     522//                  report_desc_info.length;
     523//              size_t actual_size = 0;
     524
     525//              // allocate space for the report descriptor
     526//              kbd_dev->conf->interfaces[i].report_desc =
     527//                  (uint8_t *)malloc(length);
    299528               
    300                 // get the descriptor from the device
    301                 int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe,
    302                     USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,
    303                     i, 0,
    304                     kbd_dev->conf->interfaces[i].report_desc, length,
    305                     &actual_size);
    306 
    307                 if (rc != EOK) {
    308                         return rc;
    309                 }
    310 
    311                 assert(actual_size == length);
    312 
    313                 //dump_hid_class_descriptor(0, USB_DESCTYPE_HID_REPORT,
    314                 //    kbd_dev->conf->interfaces[i].report_desc, length);
    315         }
    316 
     529//              // get the descriptor from the device
     530//              int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe,
     531//                  USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,
     532//                  i, 0,
     533//                  kbd_dev->conf->interfaces[i].report_desc, length,
     534//                  &actual_size);
     535
     536//              if (rc != EOK) {
     537//                      return rc;
     538//              }
     539
     540//              assert(actual_size == length);
     541
     542//              //dump_hid_class_descriptor(0, USB_DESCTYPE_HID_REPORT,
     543//              //    kbd_dev->conf->interfaces[i].report_desc, length);
     544//      }
     545
     546//      return EOK;
     547//}
     548
     549static int usbkbd_get_report_descriptor(usb_hid_dev_kbd_t *kbd_dev,
     550    uint8_t *config_desc, size_t config_desc_size, uint8_t *iface_desc)
     551{
     552        assert(kbd_dev != NULL);
     553        assert(config_desc != NULL);
     554        assert(config_desc_size != 0);
     555        assert(iface_desc != NULL);
     556       
     557        usb_dp_parser_t parser =  {
     558                .nesting = usb_dp_standard_descriptor_nesting
     559        };
     560       
     561        usb_dp_parser_data_t parser_data = {
     562                .data = config_desc,
     563                .size = config_desc_size,
     564                .arg = NULL
     565        };
     566       
     567        /*
     568         * First nested descriptor of interface descriptor.
     569         */
     570        uint8_t *d =
     571            usb_dp_get_nested_descriptor(&parser, &parser_data, iface_desc);
     572       
     573        /*
     574         * Search through siblings until the HID descriptor is found.
     575         */
     576        while (d != NULL && *(d + 1) != USB_DESCTYPE_HID) {
     577                d = usb_dp_get_sibling_descriptor(&parser, &parser_data,
     578                    iface_desc, d);
     579        }
     580       
     581        if (d == NULL) {
     582                usb_log_fatal("No HID descriptor found!\n");
     583                return ENOENT;
     584        }
     585       
     586        if (*d != sizeof(usb_standard_hid_descriptor_t)) {
     587                usb_log_fatal("HID descriptor hass wrong size (%u, expected %u"
     588                    ")\n", *d, sizeof(usb_standard_hid_descriptor_t));
     589                return EINVAL;
     590        }
     591       
     592        usb_standard_hid_descriptor_t *hid_desc =
     593            (usb_standard_hid_descriptor_t *)d;
     594       
     595        uint16_t length =  hid_desc->report_desc_info.length;
     596        size_t actual_size = 0;
     597
     598        /*
     599         * Allocate space for the report descriptor.
     600         */
     601        kbd_dev->report_desc = (uint8_t *)malloc(length);
     602        if (kbd_dev->report_desc == NULL) {
     603                usb_log_fatal("Failed to allocate space for Report descriptor."
     604                    "\n");
     605                return ENOMEM;
     606        }
     607       
     608        usb_log_debug("Getting Report descriptor, expected size: %u\n", length);
     609       
     610        /*
     611         * Get the descriptor from the device.
     612         */
     613        int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe,
     614            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
     615            USB_DESCTYPE_HID_REPORT, 0,
     616            kbd_dev->iface, kbd_dev->report_desc, length, &actual_size);
     617
     618        if (rc != EOK) {
     619                return rc;
     620        }
     621
     622        if (actual_size != length) {
     623                free(kbd_dev->report_desc);
     624                kbd_dev->report_desc = NULL;
     625                usb_log_fatal("Report descriptor has wrong size (%u, expected "
     626                    "%u)\n", actual_size, length);
     627                return EINVAL;
     628        }
     629       
     630        usb_log_debug("Done.\n");
     631       
    317632        return EOK;
    318633}
     634
    319635static int usbkbd_process_descriptors(usb_hid_dev_kbd_t *kbd_dev)
    320636{
     
    364680            descriptors, config_desc.total_length,
    365681            &kbd_dev->wire);
     682       
    366683        if (rc != EOK) {
    367684                usb_log_error("Failed to initialize poll pipe: %s.\n",
    368685                    str_error(rc));
     686                free(descriptors);
    369687                return rc;
    370688        }
     689       
    371690        if (!endpoint_mapping[0].present) {
    372691                usb_log_warning("Not accepting device, " \
    373692                    "not boot-protocol keyboard.\n");
     693                free(descriptors);
    374694                return EREFUSED;
    375695        }
    376 
    377 
    378 
    379 
    380         kbd_dev->conf = (usb_hid_configuration_t *)calloc(1,
    381             sizeof(usb_hid_configuration_t));
    382         if (kbd_dev->conf == NULL) {
     696       
     697        usb_log_debug("Accepted device. Saving interface, and getting Report"
     698            " descriptor.\n");
     699       
     700        /*
     701         * Save assigned interface number.
     702         */
     703        if (endpoint_mapping[0].interface_no < 0) {
     704                usb_log_error("Bad interface number.\n");
    383705                free(descriptors);
    384                 return ENOMEM;
    385         }
    386        
    387         /*rc = usbkbd_parse_descriptors(descriptors, transferred, kbd_dev->conf);
     706                return EINVAL;
     707        }
     708       
     709        kbd_dev->iface = endpoint_mapping[0].interface_no;
     710       
     711        assert(endpoint_mapping[0].interface != NULL);
     712       
     713        rc = usbkbd_get_report_descriptor(kbd_dev, descriptors, transferred,
     714            (uint8_t *)endpoint_mapping[0].interface);
     715       
    388716        free(descriptors);
    389         if (rc != EOK) {
    390                 printf("Problem with parsing standard descriptors.\n");
     717       
     718        if (rc != EOK) {
     719                usb_log_warning("Problem with parsing REPORT descriptor.\n");
    391720                return rc;
    392721        }
    393 
    394         // get and report descriptors*/
    395         rc = usbkbd_get_report_descriptor(kbd_dev);
    396         if (rc != EOK) {
    397                 printf("Problem with parsing HID REPORT descriptor.\n");
    398                 return rc;
    399         }
    400        
    401         //usbkbd_print_config(kbd_dev->conf);
    402 
    403         /*
    404          * TODO:
    405          * 1) select one configuration (lets say the first)
    406          * 2) how many interfaces?? how to select one??
    407      *    ("The default setting for an interface is always alternate setting zero.")
    408          * 3) find endpoint which is IN and INTERRUPT (parse), save its number
    409      *    as the endpoint for polling
    410          */
    411 
     722       
     723        usb_log_debug("Done parsing descriptors.\n");
     724       
    412725        return EOK;
    413726}
     
    421734
    422735        if (kbd_dev == NULL) {
    423                 fprintf(stderr, NAME ": No memory!\n");
     736                usb_log_fatal("No memory!\n");
    424737                return NULL;
    425738        }
     
    449762
    450763        /*
    451          * will need all descriptors:
    452          * 1) choose one configuration from configuration descriptors
    453          *    (set it to the device)
    454          * 2) set endpoints from endpoint descriptors
    455          */
    456 
    457         // TODO: get descriptors, parse descriptors and save endpoints
     764         * Get descriptors, parse descriptors and save endpoints.
     765         */
    458766        usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);
    459         //usb_request_set_configuration(&kbd_dev->ctrl_pipe, 1);
     767       
    460768        rc = usbkbd_process_descriptors(kbd_dev);
     769       
    461770        usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);
    462771        if (rc != EOK) {
    463772                goto error_leave;
    464773        }
    465 
     774       
     775        // save the size of the report (boot protocol report by default)
     776        kbd_dev->keycode_count = BOOTP_REPORT_SIZE;
     777        kbd_dev->keycodes = (uint8_t *)calloc(
     778            kbd_dev->keycode_count, sizeof(uint8_t));
     779       
     780        if (kbd_dev->keycodes == NULL) {
     781                usb_log_fatal("No memory!\n");
     782                goto error_leave;
     783        }
     784       
     785        kbd_dev->modifiers = 0;
     786        kbd_dev->mods = DEFAULT_ACTIVE_MODS;
     787        kbd_dev->lock_keys = 0;
     788       
     789        // set boot protocol
     790        usbkbd_req_set_protocol(kbd_dev, USB_HID_PROTOCOL_BOOT);
     791       
     792        // set LEDs according to internal setup (NUM LOCK enabled)
     793        usbkbd_set_led(kbd_dev);
     794       
    466795        return kbd_dev;
    467796
     
    476805        usb_hid_report_in_callbacks_t *callbacks =
    477806            (usb_hid_report_in_callbacks_t *)malloc(
    478                 sizeof(usb_hid_report_in_callbacks_t));
     807                sizeof(usb_hid_report_in_callbacks_t));
    479808        callbacks->keyboard = usbkbd_process_keycodes;
    480809
    481810        //usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks,
    482811        //    NULL);
    483         printf("Calling usb_hid_boot_keyboard_input_report() with size %zu\n",
    484             actual_size);
     812        /*usb_log_debug2("Calling usb_hid_boot_keyboard_input_report() with size"
     813            " %zu\n", actual_size);*/
    485814        //dump_buffer("bufffer: ", buffer, actual_size);
    486         int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size, callbacks,
    487             NULL);
    488         if (rc != EOK) {
    489                 printf("Error in usb_hid_boot_keyboard_input_report(): %d\n", rc);
     815        int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size,
     816            callbacks, kbd_dev);
     817       
     818        if (rc != EOK) {
     819                usb_log_warning("Error in usb_hid_boot_keyboard_input_report():"
     820                    "%s\n", str_error(rc));
    490821        }
    491822}
     
    497828        size_t actual_size;
    498829
    499         printf("Polling keyboard...\n");
     830        usb_log_info("Polling keyboard...\n");
    500831
    501832        while (true) {
     
    504835                sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->poll_pipe);
    505836                if (sess_rc != EOK) {
    506                         printf("Failed to start a session: %s.\n",
     837                        usb_log_warning("Failed to start a session: %s.\n",
    507838                            str_error(sess_rc));
    508839                        continue;
     
    514845
    515846                if (rc != EOK) {
    516                         printf("Error polling the keyboard: %s.\n",
     847                        usb_log_warning("Error polling the keyboard: %s.\n",
    517848                            str_error(rc));
    518849                        continue;
     
    520851
    521852                if (sess_rc != EOK) {
    522                         printf("Error closing session: %s.\n",
     853                        usb_log_warning("Error closing session: %s.\n",
    523854                            str_error(sess_rc));
    524855                        continue;
     
    530861                 */
    531862                if (actual_size == 0) {
    532                         printf("Keyboard returned NAK\n");
     863                        usb_log_debug("Keyboard returned NAK\n");
    533864                        continue;
    534865                }
     
    537868                 * TODO: Process pressed keys.
    538869                 */
    539                 printf("Calling usbkbd_process_interrupt_in()\n");
     870                usb_log_debug("Calling usbkbd_process_interrupt_in()\n");
    540871                usbkbd_process_interrupt_in(kbd_dev, buffer, actual_size);
    541872        }
     
    547878static int usbkbd_fibril_device(void *arg)
    548879{
    549         printf("!!! USB device fibril\n");
    550 
    551880        if (arg == NULL) {
    552                 printf("No device!\n");
     881                usb_log_error("No device!\n");
    553882                return -1;
    554883        }
    555 
    556         ddf_dev_t *dev = (ddf_dev_t *)arg;
    557 
    558         // initialize device (get and process descriptors, get address, etc.)
    559         usb_hid_dev_kbd_t *kbd_dev = usbkbd_init_device(dev);
    560         if (kbd_dev == NULL) {
    561                 printf("Error while initializing device.\n");
    562                 return -1;
    563         }
     884       
     885        usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)arg;
    564886
    565887        usbkbd_poll_keyboard(kbd_dev);
     
    570892static int usbkbd_add_device(ddf_dev_t *dev)
    571893{
    572         /* For now, fail immediately. */
    573         //return ENOTSUP;
    574 
    575         /*
    576          * When everything is okay, connect to "our" HC.
    577          *
    578          * Not supported yet, skip..
    579          */
    580 //      int phone = usb_drv_hc_connect_auto(dev, 0);
    581 //      if (phone < 0) {
    582 //              /*
    583 //               * Connecting to HC failed, roll-back and announce
    584 //               * failure.
    585 //               */
    586 //              return phone;
    587 //      }
    588 
    589 //      dev->parent_phone = phone;
    590 
    591894        /*
    592895         * Create default function.
     
    601904        rc = ddf_fun_add_to_class(kbd_fun, "keyboard");
    602905        assert(rc == EOK);
    603 
     906       
     907        /*
     908         * Initialize device (get and process descriptors, get address, etc.)
     909         */
     910        usb_hid_dev_kbd_t *kbd_dev = usbkbd_init_device(dev);
     911        if (kbd_dev == NULL) {
     912                usb_log_error("Error while initializing device.\n");
     913                return -1;
     914        }
     915
     916        usb_log_info("Device initialized.\n");
     917       
    604918        /*
    605919         * Create new fibril for handling this keyboard
    606920         */
    607         fid_t fid = fibril_create(usbkbd_fibril_device, dev);
     921        fid_t fid = fibril_create(usbkbd_fibril_device, kbd_dev);
    608922        if (fid == 0) {
    609                 printf("%s: failed to start fibril for HID device\n", NAME);
     923                usb_log_error("Failed to start fibril for HID device\n");
    610924                return ENOMEM;
    611925        }
     
    634948int main(int argc, char *argv[])
    635949{
    636         usb_log_enable(USB_LOG_LEVEL_INFO, "usbhid");
     950        usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
    637951        return ddf_driver_main(&kbd_driver);
    638952}
  • uspace/drv/usbhub/usbhub.c

    rb8622e2 r81c508c  
    253253        usb_endpoint_pipe_start_session(&result->endpoints.control);
    254254        opResult = usb_request_get_descriptor(&result->endpoints.control,
    255                         USB_REQUEST_TYPE_CLASS,
    256                         USB_DESCTYPE_HUB, 0, 0, serialized_descriptor,
     255                        USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
     256                        USB_DESCTYPE_HUB,
     257                        0, 0, serialized_descriptor,
    257258                        USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
    258259        usb_endpoint_pipe_end_session(&result->endpoints.control);
  • uspace/lib/usb/include/usb/classes/hid.h

    rb8622e2 r81c508c  
    5151} usb_hid_request_t;
    5252
     53typedef enum {
     54        USB_HID_REPORT_TYPE_INPUT = 1,
     55        USB_HID_REPORT_TYPE_OUTPUT = 2,
     56        USB_HID_REPORT_TYPE_FEATURE = 3
     57} usb_hid_report_type_t;
     58
     59typedef enum {
     60        USB_HID_PROTOCOL_BOOT = 0,
     61        USB_HID_PROTOCOL_REPORT = 1
     62} usb_hid_protocol_t;
     63
    5364/** USB/HID subclass constants. */
    5465typedef enum {
     
    6273        USB_HID_PROTOCOL_KEYBOARD = 1,
    6374        USB_HID_PROTOCOL_MOUSE = 2
    64 } usb_hid_protocol_t;
     75} usb_hid_iface_protocol_t;
    6576
    6677/** Part of standard USB HID descriptor specifying one class descriptor.
  • uspace/lib/usb/include/usb/classes/hidparser.h

    rb8622e2 r81c508c  
    7070} usb_hid_report_in_callbacks_t;
    7171
    72 #define USB_HID_BOOT_KEYBOARD_NUM_LOCK          0x01
    73 #define USB_HID_BOOT_KEYBOARD_CAPS_LOCK         0x02
    74 #define USB_HID_BOOT_KEYBOARD_SCROLL_LOCK       0x04
    75 #define USB_HID_BOOT_KEYBOARD_COMPOSE           0x08
    76 #define USB_HID_BOOT_KEYBOARD_KANA                      0x10
     72
     73typedef enum {
     74        USB_HID_MOD_LCTRL = 0x01,
     75        USB_HID_MOD_LSHIFT = 0x02,
     76        USB_HID_MOD_LALT = 0x04,
     77        USB_HID_MOD_LGUI = 0x08,
     78        USB_HID_MOD_RCTRL = 0x10,
     79        USB_HID_MOD_RSHIFT = 0x20,
     80        USB_HID_MOD_RALT = 0x40,
     81        USB_HID_MOD_RGUI = 0x80,
     82        USB_HID_MOD_COUNT = 8
     83} usb_hid_modifiers_t;
     84
     85typedef enum {
     86        USB_HID_LED_NUM_LOCK = 0x1,
     87        USB_HID_LED_CAPS_LOCK = 0x2,
     88        USB_HID_LED_SCROLL_LOCK = 0x4,
     89        USB_HID_LED_COMPOSE = 0x8,
     90        USB_HID_LED_KANA = 0x10,
     91        USB_HID_LED_COUNT = 5
     92} usb_hid_led_t;
     93
     94static const usb_hid_modifiers_t
     95    usb_hid_modifiers_consts[USB_HID_MOD_COUNT] = {
     96        USB_HID_MOD_LCTRL,
     97        USB_HID_MOD_LSHIFT,
     98        USB_HID_MOD_LALT,
     99        USB_HID_MOD_LGUI,
     100        USB_HID_MOD_RCTRL,
     101        USB_HID_MOD_RSHIFT,
     102        USB_HID_MOD_RALT,
     103        USB_HID_MOD_RGUI
     104};
     105
     106//static const usb_hid_led_t usb_hid_led_consts[USB_HID_LED_COUNT] = {
     107//      USB_HID_LED_NUM_LOCK,
     108//      USB_HID_LED_CAPS_LOCK,
     109//      USB_HID_LED_SCROLL_LOCK,
     110//      USB_HID_LED_COMPOSE,
     111//      USB_HID_LED_KANA
     112//};
     113
     114//#define USB_HID_BOOT_KEYBOARD_NUM_LOCK                0x01
     115//#define USB_HID_BOOT_KEYBOARD_CAPS_LOCK               0x02
     116//#define USB_HID_BOOT_KEYBOARD_SCROLL_LOCK     0x04
     117//#define USB_HID_BOOT_KEYBOARD_COMPOSE         0x08
     118//#define USB_HID_BOOT_KEYBOARD_KANA                    0x10
    77119
    78120/*
  • uspace/lib/usb/include/usb/request.h

    rb8622e2 r81c508c  
    9696int usb_request_set_address(usb_endpoint_pipe_t *, usb_address_t);
    9797int usb_request_get_descriptor(usb_endpoint_pipe_t *, usb_request_type_t,
    98     uint8_t, uint8_t, uint16_t, void *, size_t, size_t *);
     98    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t,
     99    size_t *);
    99100int usb_request_get_descriptor_alloc(usb_endpoint_pipe_t *, usb_request_type_t,
    100     uint8_t, uint8_t, uint16_t, void **, size_t *);
     101    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void **, size_t *);
    101102int usb_request_get_device_descriptor(usb_endpoint_pipe_t *,
    102103    usb_standard_device_descriptor_t *);
  • uspace/lib/usb/src/hidparser.c

    rb8622e2 r81c508c  
    144144int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size)
    145145{
    146         if(size != 1){
     146        if (size < 1){
    147147                return -1;
    148148        }
    149149
    150         /* used only first five bits, others are only padding*/
    151         *data = leds;
     150        data[0] = leds;
    152151        return EOK;
    153152}
  • uspace/lib/usb/src/request.c

    rb8622e2 r81c508c  
    3636#include <errno.h>
    3737#include <assert.h>
     38#include <usb/debug.h>
    3839
    3940#define MAX_DATA_LENGTH ((size_t)(0xFFFF))
     
    209210 */
    210211int usb_request_get_descriptor(usb_endpoint_pipe_t *pipe,
    211     usb_request_type_t request_type,
     212    usb_request_type_t request_type, usb_request_recipient_t recipient,
    212213    uint8_t descriptor_type, uint8_t descriptor_index,
    213214    uint16_t language,
     
    224225
    225226        return usb_control_request_get(pipe,
    226             request_type, USB_REQUEST_RECIPIENT_DEVICE,
     227            request_type, recipient,
    227228            USB_DEVREQ_GET_DESCRIPTOR,
    228229            wValue, language,
     
    242243 */
    243244int usb_request_get_descriptor_alloc(usb_endpoint_pipe_t * pipe,
    244     usb_request_type_t request_type,
     245    usb_request_type_t request_type, usb_request_recipient_t recipient,
    245246    uint8_t descriptor_type, uint8_t descriptor_index,
    246247    uint16_t language,
     
    258259        uint8_t tmp_buffer[1];
    259260        size_t bytes_transfered;
    260         rc = usb_request_get_descriptor(pipe, request_type,
     261        rc = usb_request_get_descriptor(pipe, request_type, recipient,
    261262            descriptor_type, descriptor_index, language,
    262263            &tmp_buffer, 1, &bytes_transfered);
     
    283284        }
    284285
    285         rc = usb_request_get_descriptor(pipe, request_type,
     286        rc = usb_request_get_descriptor(pipe, request_type, recipient,
    286287            descriptor_type, descriptor_index, language,
    287288            buffer, size, &bytes_transfered);
     
    320321        usb_standard_device_descriptor_t descriptor_tmp;
    321322        int rc = usb_request_get_descriptor(pipe,
    322             USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_DEVICE,
    323             0, 0,
     323            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
     324            USB_DESCTYPE_DEVICE, 0, 0,
    324325            &descriptor_tmp, sizeof(descriptor_tmp),
    325326            &actually_transferred);
     
    366367        usb_standard_configuration_descriptor_t descriptor_tmp;
    367368        int rc = usb_request_get_descriptor(pipe,
    368             USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_CONFIGURATION,
    369             index, 0,
     369            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
     370            USB_DESCTYPE_CONFIGURATION, index, 0,
    370371            &descriptor_tmp, sizeof(descriptor_tmp),
    371372            &actually_transferred);
     
    406407
    407408        return usb_request_get_descriptor(pipe,
    408             USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_CONFIGURATION,
    409             index, 0,
     409            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
     410            USB_DESCTYPE_CONFIGURATION, index, 0,
    410411            descriptor, descriptor_size, actual_size);
    411412}
     
    452453        size_t string_descriptor_size = 0;
    453454        rc = usb_request_get_descriptor_alloc(pipe,
    454             USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_STRING, 0, 0,
     455            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
     456            USB_DESCTYPE_STRING, 0, 0,
    455457            (void **) &string_descriptor, &string_descriptor_size);
    456458        if (rc != EOK) {
     
    531533        size_t string_size;
    532534        rc = usb_request_get_descriptor_alloc(pipe,
    533             USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_STRING,
    534             index, uint16_host2usb(lang),
     535            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
     536            USB_DESCTYPE_STRING, index, uint16_host2usb(lang),
    535537            (void **) &string, &string_size);
    536538        if (rc != EOK) {
Note: See TracChangeset for help on using the changeset viewer.