Changeset 0e2fdcf in mainline


Ignore:
Timestamp:
2011-03-01T23:02:22Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4c7c251, dc75234
Parents:
b375bb8 (diff), ac8285d (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 branch changes

Location:
uspace/drv/usbhid
Files:
5 added
5 edited
1 moved

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhid/Makefile

    rb375bb8 r0e2fdcf  
    4040        main.c \
    4141        conv.c \
     42        hidreq.c \
     43        kbddev.c \
     44        hiddev.c \
    4245        $(STOLEN_LAYOUT_SOURCES)
    4346
  • uspace/drv/usbhid/conv.c

    rb375bb8 r0e2fdcf  
    163163};
    164164
    165 unsigned int usbkbd_parse_scancode(int scancode)
     165unsigned int usbhid_parse_scancode(int scancode)
    166166{
    167 //      console_ev_type_t type;
    168167        unsigned int key;
    169168        int *map = scanmap_simple;
    170169        size_t map_length = sizeof(scanmap_simple) / sizeof(int);
    171 
    172         /*
    173          * ACK/NAK are returned as response to us sending a command.
    174          * We are not interested in them.
    175          */
    176 //      if (scancode == SC_ACK || scancode == SC_NAK)
    177 //              return;
    178 
    179 //      if (scancode == 0xe0) {
    180 //              ds = ds_e;
    181 //              return;
    182 //      }
    183 
    184 //      switch (ds) {
    185 //      case ds_s:
    186 //              map = scanmap_simple;
    187 //              map_length = sizeof(scanmap_simple) / sizeof(int);
    188 //              break;
    189 //      case ds_e:
    190 //              map = scanmap_e0;
    191 //              map_length = sizeof(scanmap_e0) / sizeof(int);
    192 //              break;
    193 //      default:
    194 //              map = NULL;
    195 //              map_length = 0;
    196 //      }
    197 
    198 //      ds = ds_s;
    199 
    200 //      if (scancode & 0x80) {
    201 //              scancode &= ~0x80;
    202 //              type = KEY_RELEASE;
    203 //      } else {
    204 //              type = KEY_PRESS;
    205 //      }
    206170
    207171        if ((scancode < 0) || ((size_t) scancode >= map_length))
     
    210174        key = map[scancode];
    211175       
    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        
    224 //      if (key != 0)
    225 //              kbd_push_ev(type, key);
    226176        return key;
    227177}
  • uspace/drv/usbhid/conv.h

    rb375bb8 r0e2fdcf  
    3737#define USBHID_CONV_H_
    3838
    39 unsigned int usbkbd_parse_scancode(int scancode);
     39unsigned int usbhid_parse_scancode(int scancode);
    4040
    41 #endif
     41#endif /* USBHID_CONV_H_ */
    4242
    4343/**
  • uspace/drv/usbhid/descdump.h

    rb375bb8 r0e2fdcf  
    3737#define USBHID_DESCDUMP_H_
    3838
    39 #include "hid.h"
     39#include <usb/descriptor.h>
     40#include <usb/classes/hid.h>
    4041
    4142void dump_standard_configuration_descriptor(
  • uspace/drv/usbhid/kbddev.h

    rb375bb8 r0e2fdcf  
    3131 */
    3232/** @file
    33  * Common definitions.
     33 * USB HID keyboard device structure and API.
    3434 */
    3535
    36 #ifndef USBHID_HID_H_
    37 #define USBHID_HID_H_
     36#ifndef USBHID_KBDDEV_H_
     37#define USBHID_KBDDEV_H_
    3838
    3939#include <stdint.h>
     
    4343#include <usb/pipes.h>
    4444
     45#include "hiddev.h"
     46
     47/*----------------------------------------------------------------------------*/
     48
    4549/**
    4650 * @brief USB/HID keyboard device type.
    47  *
    48  * Quite dummy right now.
    4951 */
    5052typedef struct {
    51         ddf_dev_t *device;
    52 
    53         usb_device_connection_t wire;
    54         usb_endpoint_pipe_t ctrl_pipe;
    55         usb_endpoint_pipe_t poll_pipe;
    56        
    57         uint16_t iface;
    58        
    59         uint8_t *report_desc;
    60         usb_hid_report_parser_t *parser;
     53        usbhid_dev_t *hid_dev;
    6154       
    6255        uint8_t *keycodes;
     
    6659        unsigned mods;
    6760        unsigned lock_keys;
    68 } usb_hid_dev_kbd_t;
     61       
     62        int console_phone;
     63       
     64        int initialized;
     65} usbhid_kbd_t;
    6966
    70 #endif
     67/*----------------------------------------------------------------------------*/
     68
     69int usbhid_kbd_try_add_device(ddf_dev_t *dev);
     70
     71#endif /* USBHID_KBDDEV_H_ */
     72
     73/**
     74 * @}
     75 */
  • uspace/drv/usbhid/main.c

    rb375bb8 r0e2fdcf  
    3737
    3838#include <ddf/driver.h>
    39 #include <ipc/driver.h>
    40 #include <ipc/kbd.h>
    41 #include <io/keycode.h>
    42 #include <io/console.h>
     39#include <usb/debug.h>
    4340#include <errno.h>
    44 #include <str_error.h>
    45 #include <fibril.h>
    46 #include <usb/debug.h>
    47 #include <usb/classes/classes.h>
    48 #include <usb/classes/hid.h>
    49 #include <usb/classes/hidparser.h>
    50 #include <usb/request.h>
    51 #include <usb/descriptor.h>
    52 #include <io/console.h>
    53 #include <stdint.h>
    54 #include <usb/dp.h>
    55 #include "hid.h"
    56 #include "conv.h"
    57 #include "layout.h"
    5841
    59 #define BUFFER_SIZE 8
    60 #define BUFFER_OUT_SIZE 1
     42#include "kbddev.h"
     43
     44/*----------------------------------------------------------------------------*/
     45
    6146#define NAME "usbhid"
    6247
    63 //#define GUESSED_POLL_ENDPOINT 1
    64 #define BOOTP_REPORT_SIZE 6
     48/*----------------------------------------------------------------------------*/
    6549
    66 static unsigned DEFAULT_ACTIVE_MODS = KM_NUM_LOCK;
    67 
    68 /** Keyboard polling endpoint description for boot protocol class. */
    69 static usb_endpoint_description_t poll_endpoint_description = {
    70         .transfer_type = USB_TRANSFER_INTERRUPT,
    71         .direction = USB_DIRECTION_IN,
    72         .interface_class = USB_CLASS_HID,
    73         .interface_subclass = USB_HID_SUBCLASS_BOOT,
    74         .interface_protocol = USB_HID_PROTOCOL_KEYBOARD,
    75         .flags = 0
    76 };
    77 
    78 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
    79 static ddf_dev_ops_t keyboard_ops = {
    80         .default_handler = default_connection_handler
    81 };
    82 
    83 static int console_callback_phone = -1;
    84 
    85 /** Default handler for IPC methods not handled by DDF.
    86  *
    87  * @param dev Device handling the call.
    88  * @param icallid Call id.
    89  * @param icall Call data.
    90  */
    91 void default_connection_handler(ddf_fun_t *fun,
    92     ipc_callid_t icallid, ipc_call_t *icall)
     50static int usbhid_add_device(ddf_dev_t *dev)
    9351{
    94         sysarg_t method = IPC_GET_IMETHOD(*icall);
    95 
    96         if (method == IPC_M_CONNECT_TO_ME) {
    97                 int callback = IPC_GET_ARG5(*icall);
    98 
    99                 if (console_callback_phone != -1) {
    100                         async_answer_0(icallid, ELIMIT);
    101                         return;
    102                 }
    103 
    104                 console_callback_phone = callback;
    105                 async_answer_0(icallid, EOK);
    106                 return;
     52        usb_log_debug("usbhid_add_device()\n");
     53       
     54        int rc = usbhid_kbd_try_add_device(dev);
     55       
     56        if (rc != EOK) {
     57                usb_log_info("Device is not a supported keyboard.\n");
     58                usb_log_error("Failed to add HID device.\n");
     59                return EREFUSED;
    10760        }
    108 
    109         async_answer_0(icallid, EINVAL);
    110 }
    111 
    112 #if 0
    113 static void send_key(int key, int type, wchar_t c) {
    114         async_msg_4(console_callback_phone, KBD_EVENT, type, key,
    115             KM_NUM_LOCK, c);
    116 }
    117 #endif
    118 
    119 /*
    120  * TODO: Move somewhere else
    121  */
    122 /*
    123 #define BYTES_PER_LINE 12
    124 
    125 static void dump_buffer(const char *msg, const uint8_t *buffer, size_t length)
    126 {uint8_t buffer[BUFFER_SIZE];
    127         printf("%s\n", msg);
    128        
    129         size_t i;
    130         for (i = 0; i < length; i++) {
    131                 printf("  0x%02X", buffer[i]);
    132                 if (((i > 0) && (((i+1) % BYTES_PER_LINE) == 0))
    133                     || (i + 1 == length)) {
    134                         printf("\n");
    135                 }
    136         }
    137 }
    138 */
    139 /*
    140  * Copy-paste from srv/hid/kbd/generic/kbd.c
    141  */
    142 
    143 /** Currently active modifiers (locks is probably better word).
    144  *
    145  * TODO: put to device?
    146  */
    147 //static unsigned mods = KM_NUM_LOCK;
    148 
    149 /** Currently pressed lock keys. We track these to tackle autorepeat. 
    150  *
    151  * TODO: put to device?
    152  */
    153 //static unsigned lock_keys;
    154 
    155 #define NUM_LAYOUTS 3
    156 
    157 static layout_op_t *layout[NUM_LAYOUTS] = {
    158         &us_qwerty_op,
    159         &us_dvorak_op,
    160         &cz_op
    161 };
    162 
    163 static int active_layout = 0;
    164 
    165 static 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 
    198 static 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 
    232 static 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 
    276 static void kbd_push_ev(int type, unsigned int key, usb_hid_dev_kbd_t *kbd_dev)
    277 {
    278         console_event_t ev;
    279         unsigned mod_mask;
    280 
    281         // TODO: replace by our own parsing?? or are the key codes identical??
    282         switch (key) {
    283         case KC_LCTRL: mod_mask = KM_LCTRL; break;
    284         case KC_RCTRL: mod_mask = KM_RCTRL; break;
    285         case KC_LSHIFT: mod_mask = KM_LSHIFT; break;
    286         case KC_RSHIFT: mod_mask = KM_RSHIFT; break;
    287         case KC_LALT: mod_mask = KM_LALT; break;
    288         case KC_RALT: mod_mask = KM_RALT; break;
    289         default: mod_mask = 0; break;
    290         }
    291 
    292         if (mod_mask != 0) {
    293                 if (type == KEY_PRESS)
    294                         kbd_dev->mods = kbd_dev->mods | mod_mask;
    295                 else
    296                         kbd_dev->mods = kbd_dev->mods & ~mod_mask;
    297         }
    298 
    299         switch (key) {
    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;
    303         default: mod_mask = 0; break;
    304         }
    305 
    306         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                
    311                 if (type == KEY_PRESS) {
    312                         usb_log_debug2("\nKey pressed.\n");
    313                         /*
    314                          * Only change lock state on transition from released
    315                          * to pressed. This prevents autorepeat from messing
    316                          * up the lock state.
    317                          */
    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;
    321 
    322                         /* Update keyboard lock indicator lights. */
    323                         usbkbd_set_led(kbd_dev);
    324                 } else {
    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) {
    334                 active_layout = 0;
    335                 layout[active_layout]->reset();
    336                 return;
    337         }
    338 
    339         if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F2) {
    340                 active_layout = 1;
    341                 layout[active_layout]->reset();
    342                 return;
    343         }
    344 
    345         if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F3) {
    346                 active_layout = 2;
    347                 layout[active_layout]->reset();
    348                 return;
    349         }
    350        
    351         ev.type = type;
    352         ev.key = key;
    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         }
    358 
    359         ev.c = layout[active_layout]->parse_ev(&ev);
    360 
    361         usb_log_debug2("Sending key %d to the console\n", ev.key);
    362         assert(console_callback_phone != -1);
    363         async_msg_4(console_callback_phone, KBD_EVENT, ev.type, ev.key,
    364             ev.mods, ev.c);
    365 }
    366 /*
    367  * End of copy-paste
    368  */
    369 
    370         /*
    371          * TODO:
    372          * 1) key press / key release - how does the keyboard notify about
    373          *    release?
    374          * 2) layouts (use the already defined), not important now
    375          * 3)
    376          */
    377 
    378 static 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 
    389 static 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 
    423 static 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 
    480 /*
    481  * Callbacks for parser
    482  */
    483 static void usbkbd_process_keycodes(const uint8_t *key_codes, size_t count,
    484     uint8_t modifiers, void *arg)
    485 {
    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: ");
    493         unsigned i;
    494         for (i = 0; i < count; ++i) {
    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);
    509 }
    510 
    511 /*
    512  * Kbd functions
    513  */
    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);
    528                
    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 
    549 static 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");
    63161       
    63262        return EOK;
    63363}
    63464
    635 static int usbkbd_process_descriptors(usb_hid_dev_kbd_t *kbd_dev)
    636 {
    637         // get the first configuration descriptor (TODO: parse also other!)
    638         usb_standard_configuration_descriptor_t config_desc;
    639        
    640         int rc;
    641         rc = usb_request_get_bare_configuration_descriptor(&kbd_dev->ctrl_pipe,
    642             0, &config_desc);
    643        
    644         if (rc != EOK) {
    645                 return rc;
    646         }
    647        
    648         // prepare space for all underlying descriptors
    649         uint8_t *descriptors = (uint8_t *)malloc(config_desc.total_length);
    650         if (descriptors == NULL) {
    651                 return ENOMEM;
    652         }
    653        
    654         size_t transferred = 0;
    655         // get full configuration descriptor
    656         rc = usb_request_get_full_configuration_descriptor(&kbd_dev->ctrl_pipe,
    657             0, descriptors,
    658             config_desc.total_length, &transferred);
    659        
    660         if (rc != EOK) {
    661                 return rc;
    662         }
    663         if (transferred != config_desc.total_length) {
    664                 return ELIMIT;
    665         }
    666        
    667         /*
    668          * Initialize the interrupt in endpoint.
    669          */
    670         usb_endpoint_mapping_t endpoint_mapping[1] = {
    671                 {
    672                         .pipe = &kbd_dev->poll_pipe,
    673                         .description = &poll_endpoint_description,
    674                         .interface_no =
    675                             usb_device_get_assigned_interface(kbd_dev->device)
    676                 }
    677         };
    678         rc = usb_endpoint_pipe_initialize_from_configuration(
    679             endpoint_mapping, 1,
    680             descriptors, config_desc.total_length,
    681             &kbd_dev->wire);
    682        
    683         if (rc != EOK) {
    684                 usb_log_error("Failed to initialize poll pipe: %s.\n",
    685                     str_error(rc));
    686                 free(descriptors);
    687                 return rc;
    688         }
    689        
    690         if (!endpoint_mapping[0].present) {
    691                 usb_log_warning("Not accepting device, " \
    692                     "not boot-protocol keyboard.\n");
    693                 free(descriptors);
    694                 return EREFUSED;
    695         }
    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");
    705                 free(descriptors);
    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        
    716         free(descriptors);
    717        
    718         if (rc != EOK) {
    719                 usb_log_warning("Problem with parsing REPORT descriptor.\n");
    720                 return rc;
    721         }
    722        
    723         usb_log_debug("Done parsing descriptors.\n");
    724        
    725         return EOK;
    726 }
    727 
    728 static usb_hid_dev_kbd_t *usbkbd_init_device(ddf_dev_t *dev)
    729 {
    730         int rc;
    731 
    732         usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)calloc(1,
    733             sizeof(usb_hid_dev_kbd_t));
    734 
    735         if (kbd_dev == NULL) {
    736                 usb_log_fatal("No memory!\n");
    737                 return NULL;
    738         }
    739 
    740         kbd_dev->device = dev;
    741 
    742         /*
    743          * Initialize the backing connection to the host controller.
    744          */
    745         rc = usb_device_connection_initialize_from_device(&kbd_dev->wire, dev);
    746         if (rc != EOK) {
    747                 printf("Problem initializing connection to device: %s.\n",
    748                     str_error(rc));
    749                 goto error_leave;
    750         }
    751 
    752         /*
    753          * Initialize device pipes.
    754          */
    755         rc = usb_endpoint_pipe_initialize_default_control(&kbd_dev->ctrl_pipe,
    756             &kbd_dev->wire);
    757         if (rc != EOK) {
    758                 printf("Failed to initialize default control pipe: %s.\n",
    759                     str_error(rc));
    760                 goto error_leave;
    761         }
    762 
    763         /*
    764          * Get descriptors, parse descriptors and save endpoints.
    765          */
    766         usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);
    767        
    768         rc = usbkbd_process_descriptors(kbd_dev);
    769        
    770         usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);
    771         if (rc != EOK) {
    772                 goto error_leave;
    773         }
    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        
    795         return kbd_dev;
    796 
    797 error_leave:
    798         free(kbd_dev);
    799         return NULL;
    800 }
    801 
    802 static void usbkbd_process_interrupt_in(usb_hid_dev_kbd_t *kbd_dev,
    803                                         uint8_t *buffer, size_t actual_size)
    804 {
    805         usb_hid_report_in_callbacks_t *callbacks =
    806             (usb_hid_report_in_callbacks_t *)malloc(
    807                 sizeof(usb_hid_report_in_callbacks_t));
    808         callbacks->keyboard = usbkbd_process_keycodes;
    809 
    810         //usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks,
    811         //    NULL);
    812         /*usb_log_debug2("Calling usb_hid_boot_keyboard_input_report() with size"
    813             " %zu\n", actual_size);*/
    814         //dump_buffer("bufffer: ", buffer, actual_size);
    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));
    821         }
    822 }
    823 
    824 static void usbkbd_poll_keyboard(usb_hid_dev_kbd_t *kbd_dev)
    825 {
    826         int rc, sess_rc;
    827         uint8_t buffer[BUFFER_SIZE];
    828         size_t actual_size;
    829 
    830         usb_log_info("Polling keyboard...\n");
    831 
    832         while (true) {
    833                 async_usleep(1000 * 10);
    834 
    835                 sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->poll_pipe);
    836                 if (sess_rc != EOK) {
    837                         usb_log_warning("Failed to start a session: %s.\n",
    838                             str_error(sess_rc));
    839                         continue;
    840                 }
    841 
    842                 rc = usb_endpoint_pipe_read(&kbd_dev->poll_pipe, buffer,
    843                     BUFFER_SIZE, &actual_size);
    844                 sess_rc = usb_endpoint_pipe_end_session(&kbd_dev->poll_pipe);
    845 
    846                 if (rc != EOK) {
    847                         usb_log_warning("Error polling the keyboard: %s.\n",
    848                             str_error(rc));
    849                         continue;
    850                 }
    851 
    852                 if (sess_rc != EOK) {
    853                         usb_log_warning("Error closing session: %s.\n",
    854                             str_error(sess_rc));
    855                         continue;
    856                 }
    857 
    858                 /*
    859                  * If the keyboard answered with NAK, it returned no data.
    860                  * This implies that no change happened since last query.
    861                  */
    862                 if (actual_size == 0) {
    863                         usb_log_debug("Keyboard returned NAK\n");
    864                         continue;
    865                 }
    866 
    867                 /*
    868                  * TODO: Process pressed keys.
    869                  */
    870                 usb_log_debug("Calling usbkbd_process_interrupt_in()\n");
    871                 usbkbd_process_interrupt_in(kbd_dev, buffer, actual_size);
    872         }
    873 
    874         // not reached
    875         assert(0);
    876 }
    877 
    878 static int usbkbd_fibril_device(void *arg)
    879 {
    880         if (arg == NULL) {
    881                 usb_log_error("No device!\n");
    882                 return -1;
    883         }
    884        
    885         usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)arg;
    886 
    887         usbkbd_poll_keyboard(kbd_dev);
    888 
    889         return EOK;
    890 }
    891 
    892 static int usbkbd_add_device(ddf_dev_t *dev)
    893 {
    894         /*
    895          * Create default function.
    896          */
    897         // FIXME - check for errors
    898         ddf_fun_t *kbd_fun = ddf_fun_create(dev, fun_exposed, "keyboard");
    899         assert(kbd_fun != NULL);
    900         kbd_fun->ops = &keyboard_ops;
    901 
    902         int rc = ddf_fun_bind(kbd_fun);
    903         assert(rc == EOK);
    904         rc = ddf_fun_add_to_class(kbd_fun, "keyboard");
    905         assert(rc == EOK);
    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        
    918         /*
    919          * Create new fibril for handling this keyboard
    920          */
    921         fid_t fid = fibril_create(usbkbd_fibril_device, kbd_dev);
    922         if (fid == 0) {
    923                 usb_log_error("Failed to start fibril for HID device\n");
    924                 return ENOMEM;
    925         }
    926         fibril_add_ready(fid);
    927 
    928         //dev->ops = &keyboard_ops;
    929         (void)keyboard_ops;
    930 
    931         //add_device_to_class(dev, "keyboard");
    932 
    933         /*
    934          * Hurrah, device is initialized.
    935          */
    936         return EOK;
    937 }
     65/*----------------------------------------------------------------------------*/
    93866
    93967static driver_ops_t kbd_driver_ops = {
    940         .add_device = usbkbd_add_device,
     68        .add_device = usbhid_add_device,
    94169};
     70
     71/*----------------------------------------------------------------------------*/
    94272
    94373static driver_t kbd_driver = {
     
    94575        .driver_ops = &kbd_driver_ops
    94676};
     77
     78/*----------------------------------------------------------------------------*/
    94779
    94880int main(int argc, char *argv[])
Note: See TracChangeset for help on using the changeset viewer.