Changeset 1c6f4ff in mainline


Ignore:
Timestamp:
2011-04-08T07:58:15Z (13 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8b74997f
Parents:
a8a7063 (diff), fec47d4 (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:

General HID driver for handling all HID devices.

Now handles only keyboard. For generic HID device and mouse there are some
dummy functions.

Files:
17 added
9 edited

Legend:

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

    ra8a7063 r1c6f4ff  
    5050        usbhub \
    5151        usbkbd \
     52        usbhid \
    5253        usbmid \
    5354        usbmouse \
  • uspace/Makefile

    ra8a7063 r1c6f4ff  
    123123                drv/usbflbk \
    124124                drv/usbkbd \
     125                drv/usbhid \
    125126                drv/usbhub \
    126127                drv/usbmid \
     
    143144                drv/usbflbk \
    144145                drv/usbkbd \
     146                drv/usbhid \
    145147                drv/usbhub \
    146148                drv/usbmid \
  • uspace/drv/usbkbd/kbddev.c

    ra8a7063 r1c6f4ff  
    265265static void usb_kbd_set_led(usb_kbd_t *kbd_dev)
    266266{
     267        if (kbd_dev->output_size == 0) {
     268                return;
     269        }
     270       
    267271        unsigned i = 0;
    268272       
     
    288292       
    289293        int rc = usb_hid_report_output_translate(kbd_dev->parser,
    290             kbd_dev->led_path, USB_HID_PATH_COMPARE_END, kbd_dev->output_buffer,
     294            kbd_dev->led_path,
     295            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     296            kbd_dev->output_buffer,
    291297            kbd_dev->output_size, kbd_dev->led_data, kbd_dev->led_output_size);
    292298       
     
    539545 *                  according to HID Usage Tables.
    540546 * @param count Number of key codes in report (size of the report).
    541  * @param modifiers Bitmap of modifiers (Ctrl, Alt, Shift, GUI).
     547 * @param report_id
    542548 * @param arg User-specified argument. Expects pointer to the keyboard device
    543549 *            structure representing the keyboard.
     
    546552 */
    547553static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count,
    548     uint8_t modifiers, void *arg)
     554    uint8_t report_id, void *arg)
    549555{
    550556        if (arg == NULL) {
     
    557563        assert(kbd_dev != NULL);
    558564
    559         usb_log_debug("Got keys from parser: %s\n",
    560             usb_debug_str_buffer(key_codes, count, 0));
     565        usb_log_debug("Got keys from parser (report id: %u): %s\n",
     566            report_id, usb_debug_str_buffer(key_codes, count, 0));
    561567       
    562568        if (count != kbd_dev->key_count) {
     
    608614        usb_hid_report_path_t *path = usb_hid_report_path();
    609615        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
     616        usb_hid_report_path_set_report_id(path, 0);
    610617       
    611618        int rc = usb_hid_parse_report(kbd_dev->parser, buffer,
    612             actual_size, path, USB_HID_PATH_COMPARE_STRICT, callbacks, kbd_dev);
     619            actual_size, path,
     620            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     621            callbacks, kbd_dev);
    613622
    614623        usb_hid_report_path_free (path);
     
    758767        usb_hid_report_path_t *path = usb_hid_report_path();
    759768        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
     769       
     770        usb_hid_report_path_set_report_id(path, 0);
     771       
    760772        kbd_dev->key_count = usb_hid_report_input_length(
    761             kbd_dev->parser, path, USB_HID_PATH_COMPARE_STRICT);
     773            kbd_dev->parser, path,
     774            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
    762775        usb_hid_report_path_free (path);
    763776       
     
    777790        kbd_dev->output_buffer = usb_hid_report_output(kbd_dev->parser,
    778791            &kbd_dev->output_size);
    779         if (kbd_dev->output_buffer == NULL) {
     792        if (kbd_dev->output_buffer == NULL && kbd_dev->output_size != 0) {
    780793                usb_log_warning("Error creating output report buffer.\n");
    781794                free(kbd_dev->keys);
     
    790803       
    791804        kbd_dev->led_output_size = usb_hid_report_output_size(kbd_dev->parser,
    792             kbd_dev->led_path, USB_HID_PATH_COMPARE_END);
     805            kbd_dev->led_path,
     806            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY);
    793807       
    794808        usb_log_debug("Output report size (in items): %zu\n",
  • uspace/drv/usbkbd/main.c

    ra8a7063 r1c6f4ff  
    3333/**
    3434 * @file
    35  * Main routines of USB HID driver.
     35 * Main routines of USB KBD driver.
    3636 */
    3737
     
    7575 * @sa usb_kbd_fibril(), usb_kbd_repeat_fibril()
    7676 */
    77 static int usbhid_try_add_device(usb_device_t *dev)
     77static int usb_kbd_try_add_device(usb_device_t *dev)
    7878{
    7979        /* Create the function exposed under /dev/devices. */
     
    105105                usb_kbd_free(&kbd_dev);
    106106                return rc;
    107         }       
     107        }
    108108       
    109109        usb_log_debug("USB/HID KBD device structure initialized.\n");
     
    195195 * @retval EREFUSED if the device is not supported.
    196196 */
    197 static int usbhid_add_device(usb_device_t *dev)
     197static int usb_kbd_add_device(usb_device_t *dev)
    198198{
    199         usb_log_debug("usbhid_add_device()\n");
     199        usb_log_debug("usb_kbd_add_device()\n");
    200200       
    201201        if (dev->interface_no < 0) {
    202202                usb_log_warning("Device is not a supported keyboard.\n");
    203                 usb_log_error("Failed to add HID device: endpoint not found."
    204                     "\n");
     203                usb_log_error("Failed to add USB KBD device: endpoint not "
     204                    "found.\n");
    205205                return ENOTSUP;
    206206        }
    207207       
    208         int rc = usbhid_try_add_device(dev);
     208        int rc = usb_kbd_try_add_device(dev);
    209209       
    210210        if (rc != EOK) {
    211211                usb_log_warning("Device is not a supported keyboard.\n");
    212                 usb_log_error("Failed to add HID device: %s.\n",
     212                usb_log_error("Failed to add KBD device: %s.\n",
    213213                    str_error(rc));
    214214                return rc;
     
    224224/* Currently, the framework supports only device adding. Once the framework
    225225 * supports unplug, more callbacks will be added. */
    226 static usb_driver_ops_t usbhid_driver_ops = {
    227         .add_device = usbhid_add_device,
     226static usb_driver_ops_t usb_kbd_driver_ops = {
     227        .add_device = usb_kbd_add_device,
    228228};
    229229
    230230
    231231/* The driver itself. */
    232 static usb_driver_t usbhid_driver = {
     232static usb_driver_t usb_kbd_driver = {
    233233        .name = NAME,
    234         .ops = &usbhid_driver_ops,
     234        .ops = &usb_kbd_driver_ops,
    235235        .endpoints = usb_kbd_endpoints
    236236};
     
    238238/*----------------------------------------------------------------------------*/
    239239
    240 //static driver_ops_t kbd_driver_ops = {
    241 //      .add_device = usbhid_add_device,
    242 //};
    243 
    244 ///*----------------------------------------------------------------------------*/
    245 
    246 //static driver_t kbd_driver = {
    247 //      .name = NAME,
    248 //      .driver_ops = &kbd_driver_ops
    249 //};
    250 
    251 /*----------------------------------------------------------------------------*/
    252 
    253240int main(int argc, char *argv[])
    254241{
    255         printf(NAME ": HelenOS USB HID driver.\n");
     242        printf(NAME ": HelenOS USB KBD driver.\n");
    256243
    257244        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    258245
    259         return usb_driver_main(&usbhid_driver);
     246        return usb_driver_main(&usb_kbd_driver);
    260247}
    261248
  • uspace/drv/usbkbd/usbkbd.ma

    ra8a7063 r1c6f4ff  
    1 100 usb&interface&class=HID&subclass=0x01&protocol=0x01
    2 10 usb&interface&class=HID
     110 usb&interface&class=HID&subclass=0x01&protocol=0x01
  • uspace/lib/usb/include/usb/classes/hidparser.h

    ra8a7063 r1c6f4ff  
    8888        /** */ 
    8989        int depth;     
     90        uint8_t report_id;
    9091       
    9192        /** */ 
    9293        link_t link;
     94
    9395} usb_hid_report_path_t;
    9496
     
    155157        /** */ 
    156158        link_t feature;
     159       
     160        int use_report_id;
     161
     162        /** */
     163        link_t stack;
    157164} usb_hid_report_parser_t;     
    158165
     
    166173         * @param arg Custom argument.
    167174         */
    168         void (*keyboard)(const uint8_t *key_codes, size_t count, const uint8_t modifiers, void *arg);
     175        void (*keyboard)(const uint8_t *key_codes, size_t count, const uint8_t report_id, void *arg);
    169176} usb_hid_report_in_callbacks_t;
    170177
     
    269276
    270277/** */
     278int usb_hid_report_path_set_report_id(usb_hid_report_path_t *usage_path, uint8_t report_id);
     279
     280/** */
    271281int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, int32_t usage_page, int32_t usage);
    272282
  • uspace/lib/usb/src/devpoll.c

    ra8a7063 r1c6f4ff  
    6666        usb_pipe_t *pipe
    6767            = polling_data->dev->pipes[polling_data->pipe_index].pipe;
     68       
     69        usb_log_debug("Pipe interface number: %d, protocol: %d, subclass: %d, max packet size: %d\n",
     70            polling_data->dev->pipes[polling_data->pipe_index].interface_no,
     71            polling_data->dev->pipes[polling_data->pipe_index].description->interface_protocol,
     72            polling_data->dev->pipes[polling_data->pipe_index].description->interface_subclass,
     73            pipe->max_packet_size);
    6874
    6975        size_t failed_attempts = 0;
     
    8389                /* Quit the session regardless of errors. */
    8490                usb_pipe_end_session(pipe);
     91               
     92//              if (rc == ESTALL) {
     93//                      usb_log_debug("Seding clear feature...\n");
     94//                      usb_request_clear_feature(pipe, USB_REQUEST_TYPE_STANDARD,
     95//                        USB_REQUEST_RECIPIENT_ENDPOINT, 0, pipe->endpoint_no);
     96//                      continue;
     97//              }
    8598
    8699                if (rc != EOK) {
  • uspace/lib/usb/src/hidparser.c

    ra8a7063 r1c6f4ff  
    6464int usb_hid_report_reset_local_items();
    6565void usb_hid_free_report_list(link_t *head);
    66 
     66usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item);
    6767/*
    6868 * Data translation private functions
     
    106106    list_initialize(&(parser->feature));
    107107
     108        list_initialize(&(parser->stack));
     109
     110        parser->use_report_id = 0;
    108111    return EOK;   
    109112}
     
    186189                                        tmp_usage_path = NULL;
    187190
     191                                        usb_hid_report_path_set_report_id(report_item->usage_path, report_item->id);   
     192                                        if(report_item->id != 0){
     193                                                parser->use_report_id = 1;
     194                                        }
    188195                                       
    189196                                        switch(tag) {
     
    215222                                        if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) {
    216223                                                return ENOMEM;
    217                                         }
     224                                        }                                       
    218225                                        memcpy(new_report_item,report_item, sizeof(usb_hid_report_item_t));
     226                                        link_initialize(&(new_report_item->link));
     227                                       
    219228                                        /* reset local items */
    220229                                        new_report_item->usage_minimum = 0;
    221230                                        new_report_item->usage_maximum = 0;
     231                                        new_report_item->designator_index = 0;
     232                                        new_report_item->designator_minimum = 0;
     233                                        new_report_item->designator_maximum = 0;
     234                                        new_report_item->string_index = 0;
     235                                        new_report_item->string_minimum = 0;
     236                                        new_report_item->string_maximum = 0;
     237
     238                                        /* reset usage from current usage path */
     239                                        usb_hid_report_usage_path_t *path = list_get_instance(&usage_path->link, usb_hid_report_usage_path_t, link);
     240                                        path->usage = 0;
    222241                                       
    223                                         link_initialize(&(new_report_item->link));
    224242                                        report_item = new_report_item;
    225243                                                                               
     
    227245                                case USB_HID_REPORT_TAG_PUSH:
    228246                                        // push current state to stack
    229                                         // not yet implemented
     247                                        new_report_item = usb_hid_report_item_clone(report_item);
     248                                        list_prepend (&parser->stack, &new_report_item->link);
     249                                       
    230250                                        break;
    231251                                case USB_HID_REPORT_TAG_POP:
    232252                                        // restore current state from stack
    233                                         // not yet implemented                                             
     253                                        if(list_empty (&parser->stack)) {
     254                                                return EINVAL;
     255                                        }
     256                                       
     257                                        report_item = list_get_instance(&parser->stack, usb_hid_report_item_t, link);
     258                                        list_remove (parser->stack.next);
     259                                       
    234260                                        break;
    235261                                       
     
    647673        }
    648674
     675        parser->use_report_id = 0;
     676
    649677        usb_hid_free_report_list(&parser->input);
    650678        usb_hid_free_report_list(&parser->output);
     
    676704        size_t i=0;
    677705        size_t j=0;
     706        uint8_t report_id = 0;
    678707
    679708        if(parser == NULL) {
     
    686715        if(!(keys = malloc(sizeof(uint8_t) * key_count))){
    687716                return ENOMEM;
     717        }
     718
     719        if(parser->use_report_id != 0) {
     720                report_id = data[0];
     721                usb_hid_report_path_set_report_id(path, report_id);
    688722        }
    689723
     
    693727
    694728                item = list_get_instance(list_item, usb_hid_report_item_t, link);
     729
    695730                if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) &&
    696731                   (usb_hid_report_compare_usage_path(item->usage_path, path, flags) == EOK)) {
     
    715750        }
    716751
    717         callbacks->keyboard(keys, key_count, 0, arg);
     752        callbacks->keyboard(keys, key_count, report_id, arg);
    718753           
    719754        free(keys);     
     
    739774        int32_t mask;
    740775        const uint8_t *foo;
    741        
     776
    742777        // now only common numbers llowed
    743778        if(item->size > 32) {
     
    758793                (usb_pow(10,(item->unit_exponent))));
    759794        }
     795
    760796        offset = item->offset + (j * item->size);
     797        if(item->id != 0) {
     798                offset += 8;
     799                usb_log_debug("MOVED OFFSET BY 1Byte, REPORT_ID(%d)\n", item->id);
     800        }
    761801       
    762802        // FIXME
     
    942982
    943983        int only_page;
     984
     985        if(report_path->report_id != path->report_id) {
     986                return 1;
     987        }
    944988
    945989        if(path->depth == 0){
     
    10381082        else {
    10391083                path->depth = 0;
     1084                path->report_id = 0;
    10401085                list_initialize(&path->link);
    10411086                return path;
     
    11551200                return 0;
    11561201        }
    1157        
     1202
    11581203        item = parser->output.next;
    11591204        while(&parser->output != item) {
     
    11951240        int length;
    11961241        int32_t tmp_value;
     1242        size_t offset_prefix = 0;
    11971243       
    11981244        if(parser == NULL) {
    11991245                return EINVAL;
     1246        }
     1247
     1248        if(parser->use_report_id != 0) {
     1249                buffer[0] = path->report_id;
     1250                offset_prefix = 8;
    12001251        }
    12011252
     
    12181269//                              // variable item
    12191270                                value = usb_hid_translate_data_reverse(report_item, data[idx++]);
    1220                                 offset = report_item->offset + (i * report_item->size);
     1271                                offset = report_item->offset + (i * report_item->size) + offset_prefix;
    12211272                                length = report_item->size;
    12221273                        }
     
    12241275                                //bitmap
    12251276                                value += usb_hid_translate_data_reverse(report_item, data[idx++]);
    1226                                 offset = report_item->offset;
     1277                                offset = report_item->offset + offset_prefix;
    12271278                                length = report_item->size * report_item->count;
    12281279                        }
     
    13231374
    13241375
     1376int usb_hid_report_path_set_report_id(usb_hid_report_path_t *path, uint8_t report_id)
     1377{
     1378        if(path == NULL){
     1379                return EINVAL;
     1380        }
     1381
     1382        path->report_id = report_id;
     1383        return EOK;
     1384}
     1385
     1386
     1387usb_hid_report_item_t *usb_hid_report_item_clone(const usb_hid_report_item_t *item)
     1388{
     1389        usb_hid_report_item_t *new_report_item;
     1390       
     1391        if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) {
     1392                return NULL;
     1393        }                                       
     1394        memcpy(new_report_item,item, sizeof(usb_hid_report_item_t));
     1395        link_initialize(&(new_report_item->link));
     1396
     1397        return new_report_item;
     1398}
     1399
    13251400/**
    13261401 * @}
  • uspace/lib/usb/src/hidreport.c

    ra8a7063 r1c6f4ff  
    8080                d = usb_dp_get_sibling_descriptor(&parser, &parser_data,
    8181                    dev->descriptors.configuration, d);
     82                ++i;
    8283        }
    8384       
Note: See TracChangeset for help on using the changeset viewer.