Changeset 20a3465 in mainline for uspace/drv/bus/usb/usbhid


Ignore:
Timestamp:
2011-10-30T19:50:54Z (14 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3ce78580, 48902fa
Parents:
4c3ad56 (diff), 45bf63c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes

Location:
uspace/drv/bus/usb/usbhid
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/usbhid/generic/hiddev.c

    r4c3ad56 r20a3465  
    4848/*----------------------------------------------------------------------------*/
    4949
    50 usb_endpoint_description_t usb_hid_generic_poll_endpoint_description = {
     50const usb_endpoint_description_t usb_hid_generic_poll_endpoint_description = {
    5151        .transfer_type = USB_TRANSFER_INTERRUPT,
    5252        .direction = USB_DIRECTION_IN,
    5353        .interface_class = USB_CLASS_HID,
     54        .interface_subclass = -1,
     55        .interface_protocol = -1,
    5456        .flags = 0
    5557};
     
    9294        usb_log_debug2("Generic HID: Get event length (fun: %p, "
    9395            "fun->driver_data: %p.\n", fun, fun->driver_data);
    94        
     96
    9597        if (fun == NULL || fun->driver_data == NULL) {
    9698                return 0;
     
    98100
    99101        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
    100        
     102
    101103        usb_log_debug2("hid_dev: %p, Max input report size (%zu).\n",
    102104            hid_dev, hid_dev->max_input_report_size);
    103        
     105
    104106        return hid_dev->max_input_report_size;
    105107}
     
    111113{
    112114        usb_log_debug2("Generic HID: Get event.\n");
    113        
     115
    114116        if (fun == NULL || fun->driver_data == NULL || buffer == NULL
    115117            || act_size == NULL || event_nr == NULL) {
     
    119121
    120122        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
    121        
     123
    122124        if (hid_dev->input_report_size > size) {
    123125                usb_log_debug("input_report_size > size (%zu, %zu)\n",
     
    125127                return EINVAL;  // TODO: other error code
    126128        }
    127        
     129
    128130        /*! @todo This should probably be somehow atomic. */
    129131        memcpy(buffer, hid_dev->input_report,
     
    131133        *act_size = hid_dev->input_report_size;
    132134        *event_nr = usb_hid_report_number(hid_dev);
    133        
     135
    134136        usb_log_debug2("OK\n");
    135        
     137
    136138        return EOK;
    137139}
     
    142144{
    143145        usb_log_debug("Generic HID: Get report descriptor length.\n");
    144        
     146
    145147        if (fun == NULL || fun->driver_data == NULL) {
    146148                usb_log_debug("No function");
    147149                return EINVAL;
    148150        }
    149        
    150         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
    151        
     151
     152        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
     153
    152154        usb_log_debug2("hid_dev->report_desc_size = %zu\n",
    153155            hid_dev->report_desc_size);
    154        
     156
    155157        return hid_dev->report_desc_size;
    156158}
     
    162164{
    163165        usb_log_debug2("Generic HID: Get report descriptor.\n");
    164        
     166
    165167        if (fun == NULL || fun->driver_data == NULL) {
    166168                usb_log_debug("No function");
    167169                return EINVAL;
    168170        }
    169        
    170         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
    171        
     171
     172        usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;
     173
    172174        if (hid_dev->report_desc_size > size) {
    173175                return EINVAL;
    174176        }
    175        
     177
    176178        memcpy(desc, hid_dev->report_desc, hid_dev->report_desc_size);
    177179        *actual_size = hid_dev->report_desc_size;
    178        
     180
    179181        return EOK;
    180182}
     
    190192/*----------------------------------------------------------------------------*/
    191193
    192 static int usb_generic_hid_create_function(usb_hid_dev_t *hid_dev)
    193 {       
     194void usb_generic_hid_deinit(usb_hid_dev_t *hid_dev, void *data)
     195{
     196        ddf_fun_t *fun = data;
     197        const int ret = ddf_fun_unbind(fun);
     198        if (ret != EOK) {
     199                usb_log_error("Failed to unbind generic hid fun.\n");
     200                return;
     201        }
     202        usb_log_debug2("%s unbound.\n", fun->name);
     203        /* We did not allocate this, so leave this alone
     204         * the device would take care of it */
     205        fun->driver_data = NULL;
     206        ddf_fun_destroy(fun);
     207}
     208
     209/*----------------------------------------------------------------------------*/
     210
     211int usb_generic_hid_init(usb_hid_dev_t *hid_dev, void **data)
     212{
     213        if (hid_dev == NULL) {
     214                return EINVAL;
     215        }
     216
    194217        /* Create the exposed function. */
    195218        /** @todo Generate numbers for the devices? */
     
    201224                return ENOMEM;
    202225        }
    203        
     226
    204227        fun->ops = &usb_generic_hid_ops;
    205         fun->driver_data = hid_dev;
    206228
    207229        int rc = ddf_fun_bind(fun);
     
    212234                return rc;
    213235        }
    214        
     236        /* This is nasty both device and this function have the same
     237         * driver data, thus destruction would lead to double free */
     238        fun->driver_data = hid_dev;
     239
    215240        usb_log_debug("HID function created. Handle: %" PRIun "\n", fun->handle);
    216        
    217         return EOK;
    218 }
    219 
    220 /*----------------------------------------------------------------------------*/
    221 
    222 int usb_generic_hid_init(usb_hid_dev_t *hid_dev, void **data)
    223 {
    224         if (hid_dev == NULL) {
    225                 return EINVAL;
    226         }
    227        
    228         return usb_generic_hid_create_function(hid_dev);
     241        *data = fun;
     242
     243        return EOK;
    229244}
    230245
  • uspace/drv/bus/usb/usbhid/generic/hiddev.h

    r4c3ad56 r20a3465  
    4141struct usb_hid_dev;
    4242
    43 usb_endpoint_description_t usb_hid_generic_poll_endpoint_description;
     43extern const usb_endpoint_description_t
     44    usb_hid_generic_poll_endpoint_description;
    4445
    4546const char *HID_GENERIC_FUN_NAME;
     
    5051int usb_generic_hid_init(struct usb_hid_dev *hid_dev, void **data);
    5152
     53void usb_generic_hid_deinit(struct usb_hid_dev *hid_dev, void *data);
     54
    5255bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev, void *data);
    5356
  • uspace/drv/bus/usb/usbhid/kbd/conv.c

    r4c3ad56 r20a3465  
    8787        [0x26] = KC_9,
    8888        [0x27] = KC_0,
    89        
     89
    9090        [0x28] = KC_ENTER,
    9191        [0x29] = KC_ESCAPE,
     
    109109
    110110        [0x39] = KC_CAPS_LOCK,
    111        
     111
    112112        [0x3a] = KC_F1,
    113113        [0x3b] = KC_F2,
     
    122122        [0x44] = KC_F11,
    123123        [0x45] = KC_F12,
    124        
     124
    125125        [0x46] = KC_PRTSCR,
    126126        [0x47] = KC_SCROLL_LOCK,
     
    136136        [0x51] = KC_DOWN,
    137137        [0x52] = KC_UP,
    138        
     138
    139139        //[0x64] = // some funny key
    140        
     140
    141141        [0xe0] = KC_LCTRL,
    142142        [0xe1] = KC_LSHIFT,
     
    147147        [0xe6] = KC_RALT,
    148148        //[0xe7] = KC_R // TODO: right GUI
    149        
     149
    150150        [0x53] = KC_NUM_LOCK,
    151151        [0x54] = KC_NSLASH,
     
    165165        [0x62] = KC_N0,
    166166        [0x63] = KC_NPERIOD
    167        
     167
    168168};
    169169
     
    186186
    187187        key = map[scancode];
    188        
     188
    189189        return key;
    190190}
  • uspace/drv/bus/usb/usbhid/kbd/kbddev.c

    r4c3ad56 r20a3465  
    8888
    8989/** Keyboard polling endpoint description for boot protocol class. */
    90 usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description = {
     90const usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description = {
    9191        .transfer_type = USB_TRANSFER_INTERRUPT,
    9292        .direction = USB_DIRECTION_IN,
     
    174174{
    175175        sysarg_t method = IPC_GET_IMETHOD(*icall);
    176        
     176
    177177        usb_kbd_t *kbd_dev = (usb_kbd_t *) fun->driver_data;
    178178        if (kbd_dev == NULL) {
     
    182182                return;
    183183        }
    184        
     184
    185185        async_sess_t *sess =
    186186            async_callback_receive_start(EXCHANGE_SERIALIZE, icall);
     
    237237
    238238        usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    239             hid_dev->report, NULL, kbd_dev->led_path,
     239            &hid_dev->report, NULL, kbd_dev->led_path,
    240240            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    241241            USB_HID_REPORT_TYPE_OUTPUT);
    242        
     242
    243243        while (field != NULL) {
    244                
    245                 if ((field->usage == USB_HID_LED_NUM_LOCK) 
     244
     245                if ((field->usage == USB_HID_LED_NUM_LOCK)
    246246                    && (kbd_dev->mods & KM_NUM_LOCK)){
    247247                        field->value = 1;
    248248                }
    249249
    250                 if ((field->usage == USB_HID_LED_CAPS_LOCK) 
     250                if ((field->usage == USB_HID_LED_CAPS_LOCK)
    251251                    && (kbd_dev->mods & KM_CAPS_LOCK)){
    252252                        field->value = 1;
    253253                }
    254254
    255                 if ((field->usage == USB_HID_LED_SCROLL_LOCK) 
     255                if ((field->usage == USB_HID_LED_SCROLL_LOCK)
    256256                    && (kbd_dev->mods & KM_SCROLL_LOCK)){
    257257                        field->value = 1;
    258258                }
    259                
    260                 field = usb_hid_report_get_sibling(hid_dev->report, field,
    261                     kbd_dev->led_path, 
    262                 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    263                         USB_HID_REPORT_TYPE_OUTPUT);
    264         }
    265        
     259
     260                field = usb_hid_report_get_sibling(
     261                    &hid_dev->report, field, kbd_dev->led_path,
     262                USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     263                    USB_HID_REPORT_TYPE_OUTPUT);
     264        }
     265
    266266        // TODO: what about the Report ID?
    267         int rc = usb_hid_report_output_translate(hid_dev->report, 0,
     267        int rc = usb_hid_report_output_translate(&hid_dev->report, 0,
    268268            kbd_dev->output_buffer, kbd_dev->output_size);
    269        
     269
    270270        if (rc != EOK) {
    271271                usb_log_warning("Error translating LED output to output report"
     
    273273                return;
    274274        }
    275        
     275
    276276        usb_log_debug("Output report buffer: %s\n",
    277277            usb_debug_str_buffer(kbd_dev->output_buffer, kbd_dev->output_size,
    278278                0));
    279        
     279
    280280        usbhid_req_set_report(&hid_dev->usb_dev->ctrl_pipe,
    281281            hid_dev->usb_dev->interface_no, USB_HID_REPORT_TYPE_OUTPUT,
     
    300300                return;
    301301        }
    302        
     302
    303303        async_exch_t *exch = async_exchange_begin(kbd_dev->console_sess);
    304304        async_msg_2(exch, KBDEV_EVENT, type, key);
     
    347347        unsigned int key;
    348348        size_t i;
    349        
     349
    350350        /*
    351351         * First of all, check if the kbd have reported phantom state.
     
    362362                return;
    363363        }
    364        
     364
    365365        /*
    366366         * Key releases
     
    382382                }
    383383        }
    384        
     384
    385385        /*
    386386         * Key presses
     
    402402                }
    403403        }
    404        
     404
    405405        memcpy(kbd_dev->keys_old, kbd_dev->keys, kbd_dev->key_count * 4);
    406        
     406
    407407        char key_buffer[512];
    408408        ddf_dump_buffer(key_buffer, 512,
     
    432432static void usb_kbd_process_data(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev)
    433433{
    434         assert(hid_dev->report != NULL);
    435434        assert(hid_dev != NULL);
    436435        assert(kbd_dev != NULL);
    437        
     436
    438437        usb_hid_report_path_t *path = usb_hid_report_path();
    439438        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    440439
    441440        usb_hid_report_path_set_report_id (path, hid_dev->report_id);
    442        
     441
    443442        // fill in the currently pressed keys
    444        
     443
    445444        usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    446             hid_dev->report, NULL, path,
    447             USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
     445            &hid_dev->report, NULL, path,
     446            USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    448447            USB_HID_REPORT_TYPE_INPUT);
    449448        unsigned i = 0;
    450        
     449
    451450        while (field != NULL) {
    452451                usb_log_debug2("FIELD (%p) - VALUE(%d) USAGE(%u)\n",
     
    454453               
    455454                assert(i < kbd_dev->key_count);
    456                
     455
    457456                // save the key usage
    458457                if (field->value != 0) {
     
    463462                }
    464463                usb_log_debug2("Saved %u. key usage %d\n", i, kbd_dev->keys[i]);
    465                
     464
    466465                ++i;
    467                 field = usb_hid_report_get_sibling(hid_dev->report, field, path,
    468                     USB_HID_PATH_COMPARE_END
    469                     | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
     466                field = usb_hid_report_get_sibling(
     467                    &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
     468                        | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    470469                    USB_HID_REPORT_TYPE_INPUT);
    471470        }
    472        
     471
    473472        usb_hid_report_path_free(path);
    474        
     473
    475474        usb_kbd_check_key_changes(hid_dev, kbd_dev);
    476475}
     
    502501
    503502        if (kbd_dev == NULL) {
    504                 usb_log_fatal("No memory!\n");
     503                usb_log_error("No memory!\n");
    505504                return NULL;
    506505        }
    507        
     506
    508507        kbd_dev->console_sess = NULL;
    509508        kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED;
    510        
     509
    511510        return kbd_dev;
    512511}
     
    514513/*----------------------------------------------------------------------------*/
    515514
    516 static int usb_kbd_create_function(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev)
    517 {
    518         assert(hid_dev != NULL);
    519         assert(hid_dev->usb_dev != NULL);
     515static int usb_kbd_create_function(usb_kbd_t *kbd_dev)
     516{
    520517        assert(kbd_dev != NULL);
    521        
     518        assert(kbd_dev->hid_dev != NULL);
     519        assert(kbd_dev->hid_dev->usb_dev != NULL);
     520
    522521        /* Create the exposed function. */
    523522        usb_log_debug("Creating DDF function %s...\n", HID_KBD_FUN_NAME);
    524         ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
    525             HID_KBD_FUN_NAME);
     523        ddf_fun_t *fun = ddf_fun_create(kbd_dev->hid_dev->usb_dev->ddf_dev,
     524            fun_exposed, HID_KBD_FUN_NAME);
    526525        if (fun == NULL) {
    527526                usb_log_error("Could not create DDF function node.\n");
    528527                return ENOMEM;
    529528        }
    530        
     529
    531530        /*
    532531         * Store the initialized HID device and HID ops
     
    540539                usb_log_error("Could not bind DDF function: %s.\n",
    541540                    str_error(rc));
     541                fun->driver_data = NULL; /* We need this later */
    542542                ddf_fun_destroy(fun);
    543543                return rc;
    544544        }
    545        
     545
    546546        usb_log_debug("%s function created. Handle: %" PRIun "\n",
    547547            HID_KBD_FUN_NAME, fun->handle);
    548        
     548
    549549        usb_log_debug("Adding DDF function to category %s...\n",
    550550            HID_KBD_CLASS_NAME);
     
    554554                    "Could not add DDF function to category %s: %s.\n",
    555555                    HID_KBD_CLASS_NAME, str_error(rc));
     556                fun->driver_data = NULL; /* We need this later */
    556557                ddf_fun_destroy(fun);
    557558                return rc;
    558559        }
    559        
     560        kbd_dev->fun = fun;
     561
    560562        return EOK;
    561563}
     
    587589{
    588590        usb_log_debug("Initializing HID/KBD structure...\n");
    589        
     591
    590592        if (hid_dev == NULL) {
    591593                usb_log_error("Failed to init keyboard structure: no structure"
     
    593595                return EINVAL;
    594596        }
    595        
     597
    596598        usb_kbd_t *kbd_dev = usb_kbd_new();
    597599        if (kbd_dev == NULL) {
     
    603605        /* Store link to HID device */
    604606        kbd_dev->hid_dev = hid_dev;
    605        
     607
    606608        /*
    607609         * TODO: make more general
     
    609611        usb_hid_report_path_t *path = usb_hid_report_path();
    610612        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0);
    611        
     613
    612614        usb_hid_report_path_set_report_id(path, 0);
    613        
     615
    614616        kbd_dev->key_count = usb_hid_report_size(
    615             hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);
     617            &hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);
    616618        usb_hid_report_path_free(path);
    617        
     619
    618620        usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count);
    619        
    620         kbd_dev->keys = (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t));
    621        
     621
     622        kbd_dev->keys = calloc(kbd_dev->key_count, sizeof(int32_t));
     623
    622624        if (kbd_dev->keys == NULL) {
    623                 usb_log_fatal("No memory!\n");
     625                usb_log_error("No memory!\n");
    624626                free(kbd_dev);
    625627                return ENOMEM;
    626628        }
    627        
     629
    628630        kbd_dev->keys_old =
    629631                (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t));
    630        
     632
    631633        if (kbd_dev->keys_old == NULL) {
    632                 usb_log_fatal("No memory!\n");
     634                usb_log_error("No memory!\n");
    633635                free(kbd_dev->keys);
    634636                free(kbd_dev);
    635637                return ENOMEM;
    636638        }
    637        
     639
    638640        /*
    639641         * Output report
    640642         */
    641643        kbd_dev->output_size = 0;
    642         kbd_dev->output_buffer = usb_hid_report_output(hid_dev->report,
     644        kbd_dev->output_buffer = usb_hid_report_output(&hid_dev->report,
    643645            &kbd_dev->output_size, 0);
    644646        if (kbd_dev->output_buffer == NULL) {
     
    647649                return ENOMEM;
    648650        }
    649        
     651
    650652        usb_log_debug("Output buffer size: %zu\n", kbd_dev->output_size);
    651        
     653
    652654        kbd_dev->led_path = usb_hid_report_path();
    653655        usb_hid_report_path_append_item(
    654656            kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0);
    655        
    656         kbd_dev->led_output_size = usb_hid_report_size(hid_dev->report,
    657             0, USB_HID_REPORT_TYPE_OUTPUT);
    658        
     657
     658        kbd_dev->led_output_size = usb_hid_report_size(
     659            &hid_dev->report, 0, USB_HID_REPORT_TYPE_OUTPUT);
     660
    659661        usb_log_debug("Output report size (in items): %zu\n",
    660662            kbd_dev->led_output_size);
    661        
     663
    662664        kbd_dev->led_data = (int32_t *)calloc(
    663665            kbd_dev->led_output_size, sizeof(int32_t));
    664        
     666
    665667        if (kbd_dev->led_data == NULL) {
    666668                usb_log_warning("Error creating buffer for LED output report."
     
    671673                return ENOMEM;
    672674        }
    673        
     675
    674676        /*
    675677         * Modifiers and locks
     
    678680        kbd_dev->mods = DEFAULT_ACTIVE_MODS;
    679681        kbd_dev->lock_keys = 0;
    680        
     682
    681683        /*
    682684         * Autorepeat
     
    686688        kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT;
    687689        kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY;
    688        
    689         kbd_dev->repeat_mtx = (fibril_mutex_t *)(
    690             malloc(sizeof(fibril_mutex_t)));
    691         if (kbd_dev->repeat_mtx == NULL) {
    692                 usb_log_fatal("No memory!\n");
    693                 free(kbd_dev->keys);
    694                 usb_hid_report_output_free(kbd_dev->output_buffer);
    695                 free(kbd_dev);
    696                 return ENOMEM;
    697         }
    698        
    699         fibril_mutex_initialize(kbd_dev->repeat_mtx);
    700        
     690
     691        fibril_mutex_initialize(&kbd_dev->repeat_mtx);
     692
    701693        // save the KBD device structure into the HID device structure
    702694        *data = kbd_dev;
    703        
     695
    704696        // set handler for incoming calls
    705697        kbd_dev->ops.default_handler = default_connection_handler;
    706        
     698
    707699        /*
    708700         * Set LEDs according to initial setup.
     
    710702         */
    711703        usb_kbd_set_led(hid_dev, kbd_dev);
    712        
     704
    713705        usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
    714706            hid_dev->usb_dev->interface_no, IDLE_RATE);
    715        
     707
    716708        /*
    717709         * Create new fibril for auto-repeat
     
    723715        }
    724716        fibril_add_ready(fid);
    725        
     717
    726718        kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED;
    727719        usb_log_debug("HID/KBD device structure initialized.\n");
    728        
     720
    729721        usb_log_debug("Creating KBD function...\n");
    730         int rc = usb_kbd_create_function(hid_dev, kbd_dev);
     722        int rc = usb_kbd_create_function(kbd_dev);
    731723        if (rc != EOK) {
    732724                usb_kbd_destroy(kbd_dev);
    733725                return rc;
    734726        }
    735        
     727
    736728        return EOK;
    737729}
     
    745737                return false;
    746738        }
    747        
     739
    748740        usb_kbd_t *kbd_dev = (usb_kbd_t *)data;
    749741        assert(kbd_dev != NULL);
    750        
     742
    751743        // TODO: add return value from this function
    752744        usb_kbd_process_data(hid_dev, kbd_dev);
    753        
     745
    754746        return true;
    755747}
     
    780772                return;
    781773        }
    782        
     774
    783775        // hangup session to the console
    784776        async_hangup(kbd_dev->console_sess);
    785        
    786         if (kbd_dev->repeat_mtx != NULL) {
    787                 //assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx));
    788                 // FIXME - the fibril_mutex_is_locked may not cause
    789                 // fibril scheduling
    790                 while (fibril_mutex_is_locked(kbd_dev->repeat_mtx)) {}
    791                 free(kbd_dev->repeat_mtx);
    792         }
    793        
     777
     778        //assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx));
     779        // FIXME - the fibril_mutex_is_locked may not cause
     780        // fibril scheduling
     781        while (fibril_mutex_is_locked(&kbd_dev->repeat_mtx)) {}
     782
    794783        // free all buffers
    795         if (kbd_dev->keys != NULL) {
    796                 free(kbd_dev->keys);
    797         }
    798         if (kbd_dev->keys_old != NULL) {
    799                 free(kbd_dev->keys_old);
    800         }
    801         if (kbd_dev->led_data != NULL) {
    802                 free(kbd_dev->led_data);
    803         }
     784        free(kbd_dev->keys);
     785        free(kbd_dev->keys_old);
     786        free(kbd_dev->led_data);
     787
    804788        if (kbd_dev->led_path != NULL) {
    805789                usb_hid_report_path_free(kbd_dev->led_path);
     
    808792                usb_hid_report_output_free(kbd_dev->output_buffer);
    809793        }
     794
     795        if (ddf_fun_unbind(kbd_dev->fun) != EOK) {
     796                usb_log_warning("Failed to unbind kbd function.\n");
     797        } else {
     798                usb_log_debug2("%s unbound.\n", kbd_dev->fun->name);
     799                kbd_dev->fun->driver_data = NULL;
     800                ddf_fun_destroy(kbd_dev->fun);
     801        }
    810802}
    811803
     
    817809                return;
    818810        }
    819        
     811
    820812        if (data != NULL) {
    821                 usb_kbd_t *kbd_dev = (usb_kbd_t *)data;
     813                usb_kbd_t *kbd_dev = data;
    822814                if (usb_kbd_is_initialized(kbd_dev)) {
    823815                        usb_kbd_mark_unusable(kbd_dev);
    824                 } else {
     816                        /* wait for autorepeat */
     817                        async_usleep(CHECK_DELAY);
    825818                        usb_kbd_destroy(kbd_dev);
    826819                }
     
    832825int usb_kbd_set_boot_protocol(usb_hid_dev_t *hid_dev)
    833826{
    834         int rc = usb_hid_parse_report_descriptor(hid_dev->report,
    835             USB_KBD_BOOT_REPORT_DESCRIPTOR,
     827        int rc = usb_hid_parse_report_descriptor(
     828            &hid_dev->report, USB_KBD_BOOT_REPORT_DESCRIPTOR,
    836829            USB_KBD_BOOT_REPORT_DESCRIPTOR_SIZE);
    837        
     830
    838831        if (rc != EOK) {
    839832                usb_log_error("Failed to parse boot report descriptor: %s\n",
     
    841834                return rc;
    842835        }
    843        
    844         rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe, 
     836
     837        rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe,
    845838            hid_dev->usb_dev->interface_no, USB_HID_PROTOCOL_BOOT);
    846        
     839
    847840        if (rc != EOK) {
    848841                usb_log_warning("Failed to set boot protocol to the device: "
     
    850843                return rc;
    851844        }
    852        
     845
    853846        return EOK;
    854847}
  • uspace/drv/bus/usb/usbhid/kbd/kbddev.h

    r4c3ad56 r20a3465  
    7575        /** Currently pressed modifiers (bitmap). */
    7676        uint8_t modifiers;
    77        
     77
    7878        /** Currently active modifiers including locks. Sent to the console. */
    7979        unsigned mods;
    80        
     80
    8181        /** Currently active lock keys. */
    8282        unsigned lock_keys;
    83        
     83
    8484        /** IPC session to the console device (for sending key events). */
    8585        async_sess_t *console_sess;
    86        
     86
    8787        /** @todo What is this actually? */
    8888        ddf_dev_ops_t ops;
    89        
     89
    9090        /** Information for auto-repeat of keys. */
    9191        usb_kbd_repeat_t repeat;
    92        
     92
    9393        /** Mutex for accessing the information about auto-repeat. */
    94         fibril_mutex_t *repeat_mtx;
    95        
     94        fibril_mutex_t repeat_mtx;
     95
    9696        uint8_t *output_buffer;
    97        
     97
    9898        size_t output_size;
    99        
     99
    100100        size_t led_output_size;
    101        
     101
    102102        usb_hid_report_path_t *led_path;
    103        
     103
    104104        int32_t *led_data;
    105        
     105
    106106        /** State of the structure (for checking before use).
    107107         *
     
    111111         */
    112112        int initialized;
     113
     114        /** DDF function */
     115        ddf_fun_t *fun;
    113116} usb_kbd_t;
    114117
    115118/*----------------------------------------------------------------------------*/
    116119
    117 usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description;
     120extern const usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description;
    118121
    119122const char *HID_KBD_FUN_NAME;
  • uspace/drv/bus/usb/usbhid/kbd/kbdrepeat.c

    r4c3ad56 r20a3465  
    4646
    4747
    48 /** Delay between auto-repeat state checks when no key is being repeated. */
    49 static unsigned int CHECK_DELAY = 10000;
    5048
    5149/*----------------------------------------------------------------------------*/
     
    7371{
    7472        unsigned int delay = 0;
    75        
     73
    7674        usb_log_debug("Starting autorepeat loop.\n");
    7775
     
    7977                // check if the kbd structure is usable
    8078                if (!usb_kbd_is_initialized(kbd)) {
    81                         if (usb_kbd_is_ready_to_destroy(kbd)) {
    82                                 usb_kbd_destroy(kbd);
    83                         }
     79                        usb_log_warning("kbd not ready, exiting autorepeat.\n");
    8480                        return;
    8581                }
    8682               
    87                 fibril_mutex_lock(kbd->repeat_mtx);
     83                fibril_mutex_lock(&kbd->repeat_mtx);
    8884
    8985                if (kbd->repeat.key_new > 0) {
     
    109105                        delay = CHECK_DELAY;
    110106                }
    111                 fibril_mutex_unlock(kbd->repeat_mtx);
     107                fibril_mutex_unlock(&kbd->repeat_mtx);
    112108               
    113109                async_usleep(delay);
     
    130126{
    131127        usb_log_debug("Autorepeat fibril spawned.\n");
    132        
     128
    133129        if (arg == NULL) {
    134130                usb_log_error("No device!\n");
    135131                return EINVAL;
    136132        }
    137        
     133
    138134        usb_kbd_t *kbd = (usb_kbd_t *)arg;
    139        
     135
    140136        usb_kbd_repeat_loop(kbd);
    141        
     137
    142138        return EOK;
    143139}
     
    156152void usb_kbd_repeat_start(usb_kbd_t *kbd, unsigned int key)
    157153{
    158         fibril_mutex_lock(kbd->repeat_mtx);
     154        fibril_mutex_lock(&kbd->repeat_mtx);
    159155        kbd->repeat.key_new = key;
    160         fibril_mutex_unlock(kbd->repeat_mtx);
     156        fibril_mutex_unlock(&kbd->repeat_mtx);
    161157}
    162158
     
    174170void usb_kbd_repeat_stop(usb_kbd_t *kbd, unsigned int key)
    175171{
    176         fibril_mutex_lock(kbd->repeat_mtx);
     172        fibril_mutex_lock(&kbd->repeat_mtx);
    177173        if (key == kbd->repeat.key_new) {
    178174                kbd->repeat.key_new = 0;
    179175        }
    180         fibril_mutex_unlock(kbd->repeat_mtx);
     176        fibril_mutex_unlock(&kbd->repeat_mtx);
    181177}
    182178
  • uspace/drv/bus/usb/usbhid/kbd/kbdrepeat.h

    r4c3ad56 r20a3465  
    3737#define USB_HID_KBDREPEAT_H_
    3838
     39/** Delay between auto-repeat state checks when no key is being repeated. */
     40#define CHECK_DELAY 10000
     41
    3942struct usb_kbd_t;
    4043
  • uspace/drv/bus/usb/usbhid/main.c

    r4c3ad56 r20a3465  
    4646#include "usbhid.h"
    4747
    48 /*----------------------------------------------------------------------------*/
    49 
    5048#define NAME "usbhid"
    5149
     
    6765 *
    6866 * @param dev Device to add.
    69  *
    70  * @retval EOK if successful.
    71  * @retval ENOMEM if there
    72  * @return Other error code inherited from one of functions usb_kbd_init(),
    73  *         ddf_fun_bind() and ddf_fun_add_to_class().
     67 * @return Error code.
    7468 */
    7569static int usb_hid_try_add_device(usb_device_t *dev)
    7670{
    7771        assert(dev != NULL);
    78        
    79         /*
    80          * Initialize device (get and process descriptors, get address, etc.)
    81          */
     72
     73        /* Initialize device (get and process descriptors, get address, etc.) */
    8274        usb_log_debug("Initializing USB/HID device...\n");
    83        
    84         usb_hid_dev_t *hid_dev = usb_hid_new();
     75
     76        usb_hid_dev_t *hid_dev =
     77            usb_device_data_alloc(dev, sizeof(usb_hid_dev_t));
    8578        if (hid_dev == NULL) {
    8679                usb_log_error("Error while creating USB/HID device "
     
    8881                return ENOMEM;
    8982        }
    90        
     83
    9184        int rc = usb_hid_init(hid_dev, dev);
    92        
     85
    9386        if (rc != EOK) {
    9487                usb_log_error("Failed to initialize USB/HID device.\n");
    95                 usb_hid_destroy(hid_dev);
     88                usb_hid_deinit(hid_dev);
    9689                return rc;
    97         }       
    98        
     90        }
     91
    9992        usb_log_debug("USB/HID device structure initialized.\n");
    100        
     93
    10194        /*
    10295         * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da
     
    109102         *    pouzit usb/classes/hid/iface.h - prvy int je telefon
    110103         */
    111        
     104
    112105        /* Start automated polling function.
    113106         * This will create a separate fibril that will query the device
     
    125118           /* Custom argument. */
    126119           hid_dev);
    127        
    128        
     120
    129121        if (rc != EOK) {
    130122                usb_log_error("Failed to start polling fibril for `%s'.\n",
    131123                    dev->ddf_dev->name);
     124                usb_hid_deinit(hid_dev);
    132125                return rc;
    133126        }
     127        hid_dev->running = true;
    134128
    135129        /*
     
    138132        return EOK;
    139133}
    140 
    141134/*----------------------------------------------------------------------------*/
    142135/**
     
    146139 *
    147140 * @param dev Structure representing the new device.
    148  *
    149  * @retval EOK if successful.
    150  * @retval EREFUSED if the device is not supported.
     141 * @return Error code.
    151142 */
    152143static int usb_hid_device_add(usb_device_t *dev)
    153144{
    154145        usb_log_debug("usb_hid_device_add()\n");
    155        
     146
    156147        if (dev == NULL) {
    157148                usb_log_warning("Wrong parameter given for add_device().\n");
    158149                return EINVAL;
    159150        }
    160        
     151
    161152        if (dev->interface_no < 0) {
    162153                usb_log_warning("Device is not a supported HID device.\n");
     
    165156                return ENOTSUP;
    166157        }
    167        
     158
    168159        int rc = usb_hid_try_add_device(dev);
    169        
     160
    170161        if (rc != EOK) {
    171162                usb_log_warning("Device is not a supported HID device.\n");
     
    174165                return rc;
    175166        }
    176        
     167
    177168        usb_log_info("HID device `%s' ready to use.\n", dev->ddf_dev->name);
    178169
    179170        return EOK;
    180171}
    181 
    182 /*----------------------------------------------------------------------------*/
    183 
    184 /* Currently, the framework supports only device adding. Once the framework
    185  * supports unplug, more callbacks will be added. */
    186 static usb_driver_ops_t usb_hid_driver_ops = {
    187         .device_add = usb_hid_device_add,
     172/*----------------------------------------------------------------------------*/
     173/**
     174 * Callback for a device about to be removed from the driver.
     175 *
     176 * @param dev Structure representing the device.
     177 * @return Error code.
     178 */
     179static int usb_hid_device_rem(usb_device_t *dev)
     180{
     181        return EOK;
     182}
     183/*----------------------------------------------------------------------------*/
     184/**
     185 * Callback for removing a device from the driver.
     186 *
     187 * @param dev Structure representing the device.
     188 * @return Error code.
     189 */
     190static int usb_hid_device_gone(usb_device_t *dev)
     191{
     192        usb_hid_dev_t *hid_dev = dev->driver_data;
     193        unsigned tries = 10;
     194        while (hid_dev->running) {
     195                async_usleep(100000);
     196                if (!tries--) {
     197                        usb_log_error("Can't remove hub, still running.\n");
     198                        return EBUSY;
     199                }
     200        }
     201
     202        assert(!hid_dev->running);
     203        usb_hid_deinit(hid_dev);
     204        usb_log_debug2("%s destruction complete.\n", dev->ddf_dev->name);
     205        return EOK;
     206}
     207/*----------------------------------------------------------------------------*/
     208/** USB generic driver callbacks */
     209static const usb_driver_ops_t usb_hid_driver_ops = {
     210        .device_add = usb_hid_device_add,
     211        .device_rem = usb_hid_device_rem,
     212        .device_gone = usb_hid_device_gone,
    188213};
    189 
    190 
    191 /* The driver itself. */
    192 static usb_driver_t usb_hid_driver = {
     214/*----------------------------------------------------------------------------*/
     215/** The driver itself. */
     216static const usb_driver_t usb_hid_driver = {
    193217        .name = NAME,
    194218        .ops = &usb_hid_driver_ops,
    195219        .endpoints = usb_hid_endpoints
    196220};
    197 
    198 /*----------------------------------------------------------------------------*/
    199 
     221/*----------------------------------------------------------------------------*/
    200222int main(int argc, char *argv[])
    201223{
     
    206228        return usb_driver_main(&usb_hid_driver);
    207229}
    208 
    209230/**
    210231 * @}
  • uspace/drv/bus/usb/usbhid/mouse/mousedev.c

    r4c3ad56 r20a3465  
    5959/*----------------------------------------------------------------------------*/
    6060
    61 usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description = {
     61const usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description = {
    6262        .transfer_type = USB_TRANSFER_INTERRUPT,
    6363        .direction = USB_DIRECTION_IN,
     
    124124{
    125125        usb_mouse_t *mouse_dev = (usb_mouse_t *) fun->driver_data;
    126        
     126
    127127        if (mouse_dev == NULL) {
    128128                usb_log_debug("default_connection_handler: Missing "
     
    131131                return;
    132132        }
    133        
     133
    134134        usb_log_debug("default_connection_handler: fun->name: %s\n",
    135135                      fun->name);
    136136        usb_log_debug("default_connection_handler: mouse_sess: %p, "
    137137            "wheel_sess: %p\n", mouse_dev->mouse_sess, mouse_dev->wheel_sess);
    138        
     138
    139139        async_sess_t **sess_ptr =
    140140            (str_cmp(fun->name, HID_MOUSE_FUN_NAME) == 0) ?
    141141            &mouse_dev->mouse_sess : &mouse_dev->wheel_sess;
    142        
     142
    143143        async_sess_t *sess =
    144144            async_callback_receive_start(EXCHANGE_SERIALIZE, icall);
     
    170170        mouse->mouse_sess = NULL;
    171171        mouse->wheel_sess = NULL;
    172        
     172
    173173        return mouse;
    174174}
     
    179179{
    180180        assert(mouse_dev != NULL);
    181        
     181
    182182        // hangup session to the console
    183183        if (mouse_dev->mouse_sess != NULL)
    184184                async_hangup(mouse_dev->mouse_sess);
    185        
     185
    186186        if (mouse_dev->wheel_sess != NULL)
    187187                async_hangup(mouse_dev->wheel_sess);
     188        int ret = ddf_fun_unbind(mouse_dev->mouse_fun);
     189        if (ret != EOK) {
     190                usb_log_error("Failed to unbind mouse function.\n");
     191        } else {
     192                ddf_fun_destroy(mouse_dev->mouse_fun);
     193                /* Prevent double free */
     194                mouse_dev->wheel_fun->driver_data = NULL;
     195        }
     196
     197        ret = ddf_fun_unbind(mouse_dev->wheel_fun);
     198        if (ret != EOK) {
     199                usb_log_error("Failed to unbind wheel function.\n");
     200        } else {
     201                ddf_fun_destroy(mouse_dev->wheel_fun);
     202        }
    188203}
    189204
     
    199214                return;
    200215        }
    201        
     216
    202217        int count = ((wheel < 0) ? -wheel : wheel) * ARROWS_PER_SINGLE_WHEEL;
    203218        int i;
    204        
     219
    205220        for (i = 0; i < count; i++) {
    206221                /* Send arrow press and release. */
     
    246261{
    247262        assert(mouse_dev != NULL);
    248        
     263
    249264        if (mouse_dev->mouse_sess == NULL) {
    250265                usb_log_warning(NAME " No console session.\n");
     
    253268
    254269        int shift_x = get_mouse_axis_move_value(hid_dev->report_id,
    255             hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_X);
     270            &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_X);
    256271        int shift_y = get_mouse_axis_move_value(hid_dev->report_id,
    257             hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_Y);
     272            &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_Y);
    258273        int wheel = get_mouse_axis_move_value(hid_dev->report_id,
    259             hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL);
     274            &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL);
    260275
    261276        if ((shift_x != 0) || (shift_y != 0)) {
    262                 async_exch_t *exch = async_exchange_begin(mouse_dev->mouse_sess);
     277                async_exch_t *exch =
     278                    async_exchange_begin(mouse_dev->mouse_sess);
    263279                async_req_2_0(exch, MOUSEEV_MOVE_EVENT, shift_x, shift_y);
    264280                async_exchange_end(exch);
    265281        }
    266        
     282
    267283        if (wheel != 0)
    268284                usb_mouse_send_wheel(mouse_dev, wheel);
    269        
     285
    270286        /*
    271287         * Buttons
     
    274290        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0);
    275291        usb_hid_report_path_set_report_id(path, hid_dev->report_id);
    276        
     292
    277293        usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    278             hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END
    279             | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    280             USB_HID_REPORT_TYPE_INPUT);
     294            &hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END
     295            | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, USB_HID_REPORT_TYPE_INPUT);
    281296
    282297        while (field != NULL) {
     
    299314                        async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, field->usage, 0);
    300315                        async_exchange_end(exch);
    301                        
     316
    302317                        mouse_dev->buttons[field->usage - field->usage_minimum] =
    303318                           field->value;
    304319                }
    305                
     320
    306321                field = usb_hid_report_get_sibling(
    307                     hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
    308                     | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
     322                    &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
     323                    | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    309324                    USB_HID_REPORT_TYPE_INPUT);
    310325        }
    311        
     326
    312327        usb_hid_report_path_free(path);
    313328
     
    321336        assert(hid_dev != NULL);
    322337        assert(mouse != NULL);
    323        
     338
    324339        /* Create the exposed function. */
    325340        usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME);
     
    330345                return ENOMEM;
    331346        }
    332        
     347
    333348        fun->ops = &mouse->ops;
    334349        fun->driver_data = mouse;
     
    338353                usb_log_error("Could not bind DDF function: %s.\n",
    339354                    str_error(rc));
    340                 ddf_fun_destroy(fun);
    341                 return rc;
    342         }
    343        
     355                return rc;
     356        }
     357
    344358        usb_log_debug("Adding DDF function to category %s...\n",
    345359            HID_MOUSE_CATEGORY);
     
    349363                    "Could not add DDF function to category %s: %s.\n",
    350364                    HID_MOUSE_CATEGORY, str_error(rc));
    351                 ddf_fun_destroy(fun);
    352                 return rc;
    353         }
    354        
     365                return rc;
     366        }
     367        mouse->mouse_fun = fun;
     368
    355369        /*
    356370         * Special function for acting as keyboard (wheel)
     
    364378                return ENOMEM;
    365379        }
    366        
     380
    367381        /*
    368382         * Store the initialized HID device and HID ops
     
    376390                usb_log_error("Could not bind DDF function: %s.\n",
    377391                    str_error(rc));
    378                 ddf_fun_destroy(fun);
    379                 return rc;
    380         }
    381        
     392                return rc;
     393        }
     394
    382395        usb_log_debug("Adding DDF function to category %s...\n",
    383396            HID_MOUSE_WHEEL_CATEGORY);
     
    387400                    "Could not add DDF function to category %s: %s.\n",
    388401                    HID_MOUSE_WHEEL_CATEGORY, str_error(rc));
    389                 ddf_fun_destroy(fun);
    390                 return rc;
    391         }
    392        
     402                return rc;
     403        }
     404        mouse->wheel_fun = fun;
     405
    393406        return EOK;
    394407}
     
    441454{
    442455        usb_log_debug("Initializing HID/Mouse structure...\n");
    443        
     456
    444457        if (hid_dev == NULL) {
    445458                usb_log_error("Failed to init keyboard structure: no structure"
     
    447460                return EINVAL;
    448461        }
    449        
     462
    450463        usb_mouse_t *mouse_dev = usb_mouse_new();
    451464        if (mouse_dev == NULL) {
     
    454467                return ENOMEM;
    455468        }
    456        
     469
    457470        // FIXME: This may not be optimal since stupid hardware vendor may
    458471        // use buttons 1, 2, 3 and 6000 and we would allocate array of
     
    461474        // that the current solution is good enough.
    462475        /* Adding 1 because we will be accessing buttons[highest]. */
    463         mouse_dev->buttons_count = usb_mouse_get_highest_button(hid_dev->report,
    464             hid_dev->report_id) + 1;
     476        mouse_dev->buttons_count = 1 + usb_mouse_get_highest_button(
     477            &hid_dev->report, hid_dev->report_id);
    465478        mouse_dev->buttons = calloc(mouse_dev->buttons_count, sizeof(int32_t));
    466        
     479
    467480        if (mouse_dev->buttons == NULL) {
    468481                usb_log_error(NAME ": out of memory, giving up on device!\n");
     
    474487        // save the Mouse device structure into the HID device structure
    475488        *data = mouse_dev;
    476        
     489
    477490        // set handler for incoming calls
    478491        mouse_dev->ops.default_handler = default_connection_handler;
    479        
     492
    480493        // TODO: how to know if the device supports the request???
    481494        usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe,
    482495            hid_dev->usb_dev->interface_no, IDLE_RATE);
    483        
     496
    484497        int rc = usb_mouse_create_function(hid_dev, mouse_dev);
    485498        if (rc != EOK) {
     
    487500                return rc;
    488501        }
    489        
     502
    490503        return EOK;
    491504}
     
    500513                return false;
    501514        }
    502        
     515
    503516        usb_mouse_t *mouse_dev = (usb_mouse_t *)data;
    504517               
     
    511524{
    512525        if (data != NULL) {
    513                 usb_mouse_destroy((usb_mouse_t *)data);
     526                usb_mouse_destroy(data);
    514527        }
    515528}
     
    519532int usb_mouse_set_boot_protocol(usb_hid_dev_t *hid_dev)
    520533{
    521         int rc = usb_hid_parse_report_descriptor(hid_dev->report,
    522             USB_MOUSE_BOOT_REPORT_DESCRIPTOR,
     534        int rc = usb_hid_parse_report_descriptor(
     535            &hid_dev->report, USB_MOUSE_BOOT_REPORT_DESCRIPTOR,
    523536            USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE);
    524        
     537
    525538        if (rc != EOK) {
    526539                usb_log_error("Failed to parse boot report descriptor: %s\n",
     
    528541                return rc;
    529542        }
    530        
    531         rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe, 
     543
     544        rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe,
    532545            hid_dev->usb_dev->interface_no, USB_HID_PROTOCOL_BOOT);
    533        
     546
    534547        if (rc != EOK) {
    535548                usb_log_warning("Failed to set boot protocol to the device: "
     
    537550                return rc;
    538551        }
    539        
     552
    540553        return EOK;
    541554}
  • uspace/drv/bus/usb/usbhid/mouse/mousedev.h

    r4c3ad56 r20a3465  
    4949        async_sess_t *mouse_sess;
    5050        async_sess_t *wheel_sess;
    51        
     51
    5252        /* Mouse buttons statuses. */
    5353        int32_t *buttons;
    5454        size_t buttons_count;
    55        
     55
    5656        ddf_dev_ops_t ops;
     57        /* DDF mouse function */
     58        ddf_fun_t *mouse_fun;
     59        /* DDF mouse function */
     60        ddf_fun_t *wheel_fun;
    5761} usb_mouse_t;
    5862
    5963/*----------------------------------------------------------------------------*/
    6064
    61 usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description;
     65extern const usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description;
    6266
    6367const char *HID_MOUSE_FUN_NAME;
  • uspace/drv/bus/usb/usbhid/multimedia/multimedia.c

    r4c3ad56 r20a3465  
    6464        //int32_t *keys;
    6565        /** Count of stored keys (i.e. number of keys in the report). */
    66         //size_t key_count;     
     66        //size_t key_count;
    6767        /** IPC session to the console device (for sending key events). */
    6868        async_sess_t *console_sess;
     69        /** DDF function */
     70        ddf_fun_t *fun;
    6971} usb_multimedia_t;
    7072
     
    8688{
    8789        usb_log_debug(NAME " default_connection_handler()\n");
    88        
     90
    8991        usb_multimedia_t *multim_dev = (usb_multimedia_t *)fun->driver_data;
    90        
     92
    9193        if (multim_dev == NULL) {
    9294                async_answer_0(icallid, EINVAL);
    9395                return;
    9496        }
    95        
     97
    9698        async_sess_t *sess =
    9799            async_callback_receive_start(EXCHANGE_SERIALIZE, icall);
     
    137139        assert(hid_dev != NULL);
    138140        assert(multim_dev != NULL);
    139        
     141
    140142        kbd_event_t ev;
    141        
     143
    142144        ev.type = type;
    143145        ev.key = key;
     
    151153                return;
    152154        }
    153        
     155
    154156        async_exch_t *exch = async_exchange_begin(multim_dev->console_sess);
    155157        async_msg_4(exch, KBDEV_EVENT, ev.type, ev.key, ev.mods, ev.c);
     
    159161/*----------------------------------------------------------------------------*/
    160162
    161 static int usb_multimedia_create_function(usb_hid_dev_t *hid_dev,
    162     usb_multimedia_t *multim_dev)
    163 {
     163int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data)
     164{
     165        if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
     166                return EINVAL; /*! @todo Other return code? */
     167        }
     168
     169        usb_log_debug(NAME " Initializing HID/multimedia structure...\n");
     170
    164171        /* Create the exposed function. */
    165         ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,
    166             NAME);
     172        ddf_fun_t *fun = ddf_fun_create(
     173            hid_dev->usb_dev->ddf_dev, fun_exposed, NAME);
    167174        if (fun == NULL) {
    168175                usb_log_error("Could not create DDF function node.\n");
    169176                return ENOMEM;
    170177        }
    171        
     178
    172179        fun->ops = &multimedia_ops;
    173         fun->driver_data = multim_dev;   // TODO: maybe change to hid_dev->data
    174        
     180
     181        usb_multimedia_t *multim_dev =
     182            ddf_fun_data_alloc(fun, sizeof(usb_multimedia_t));
     183        if (multim_dev == NULL) {
     184                ddf_fun_destroy(fun);
     185                return ENOMEM;
     186        }
     187
     188        multim_dev->console_sess = NULL;
     189        multim_dev->fun = fun;
     190
     191        //todo Autorepeat?
     192
    175193        int rc = ddf_fun_bind(fun);
    176194        if (rc != EOK) {
    177195                usb_log_error("Could not bind DDF function: %s.\n",
    178196                    str_error(rc));
    179                 // TODO: Can / should I destroy the DDF function?
    180197                ddf_fun_destroy(fun);
    181198                return rc;
    182199        }
    183        
     200
    184201        usb_log_debug("%s function created (handle: %" PRIun ").\n",
    185202            NAME, fun->handle);
    186        
     203
    187204        rc = ddf_fun_add_to_category(fun, "keyboard");
    188205        if (rc != EOK) {
     
    190207                    "Could not add DDF function to category 'keyboard': %s.\n",
    191208                    str_error(rc));
    192                 // TODO: Can / should I destroy the DDF function?
    193209                ddf_fun_destroy(fun);
    194210                return rc;
    195211        }
    196        
    197         return EOK;
    198 }
    199 
    200 /*----------------------------------------------------------------------------*/
    201 
    202 int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data)
    203 {
    204         if (hid_dev == NULL || hid_dev->usb_dev == NULL) {
    205                 return EINVAL; /*! @todo Other return code? */
    206         }
    207        
    208         usb_log_debug(NAME " Initializing HID/multimedia structure...\n");
    209        
    210         usb_multimedia_t *multim_dev = (usb_multimedia_t *)malloc(
    211             sizeof(usb_multimedia_t));
    212         if (multim_dev == NULL) {
    213                 return ENOMEM;
    214         }
    215        
    216         multim_dev->console_sess = NULL;
    217        
    218         /*! @todo Autorepeat */
    219        
    220         // save the KBD device structure into the HID device structure
     212
     213        /* Save the KBD device structure into the HID device structure. */
    221214        *data = multim_dev;
    222        
    223         usb_log_debug(NAME " HID/multimedia device structure initialized.\n");
    224        
    225         int rc = usb_multimedia_create_function(hid_dev, multim_dev);
    226         if (rc != EOK)
    227                 return rc;
    228        
     215
    229216        usb_log_debug(NAME " HID/multimedia structure initialized.\n");
    230        
    231217        return EOK;
    232218}
     
    239225                return;
    240226        }
    241        
     227
    242228        if (data != NULL) {
    243229                usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;
    244230                // hangup session to the console
    245231                async_hangup(multim_dev->console_sess);
     232                const int ret = ddf_fun_unbind(multim_dev->fun);
     233                if (ret != EOK) {
     234                        usb_log_error("Failed to unbind multim function.\n");
     235                } else {
     236                        usb_log_debug2("%s unbound.\n", multim_dev->fun->name);
     237                        ddf_fun_destroy(multim_dev->fun);
     238                }
    246239        }
    247240}
     
    257250
    258251        usb_multimedia_t *multim_dev = (usb_multimedia_t *)data;
    259        
     252
    260253        usb_hid_report_path_t *path = usb_hid_report_path();
    261254        usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0);
     
    264257
    265258        usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    266             hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END
    267             | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 
     259            &hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END
     260            | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    268261            USB_HID_REPORT_TYPE_INPUT);
    269262
     
    283276                                               key);
    284277                }
    285                
     278
    286279                field = usb_hid_report_get_sibling(
    287                     hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
     280                    &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END
    288281                    | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,
    289282                    USB_HID_REPORT_TYPE_INPUT);
    290         }       
     283        }
    291284
    292285        usb_hid_report_path_free(path);
    293        
     286
    294287        return true;
    295288}
  • uspace/drv/bus/usb/usbhid/subdrivers.c

    r4c3ad56 r20a3465  
    4242#include "generic/hiddev.h"
    4343
    44 static usb_hid_subdriver_usage_t path_kbd[] = {
    45         {USB_HIDUT_PAGE_GENERIC_DESKTOP, 
    46          USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD}, 
     44static const usb_hid_subdriver_usage_t path_kbd[] = {
     45        {USB_HIDUT_PAGE_GENERIC_DESKTOP,
     46         USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD},
    4747        {0, 0}
    4848};
    4949
    50 static usb_hid_subdriver_usage_t path_mouse[] = {
     50static const usb_hid_subdriver_usage_t path_mouse[] = {
    5151        {USB_HIDUT_PAGE_GENERIC_DESKTOP, USB_HIDUT_USAGE_GENERIC_DESKTOP_MOUSE},
    5252        {0, 0}
    5353};
    5454
    55 static usb_hid_subdriver_usage_t multim_key_path[] = {
     55static const usb_hid_subdriver_usage_t multim_key_path[] = {
    5656        {USB_HIDUT_PAGE_CONSUMER, USB_HIDUT_USAGE_CONSUMER_CONSUMER_CONTROL},
    5757        {0, 0}
     
    7171                        .poll_end = NULL
    7272                },
    73                
    7473        },
    7574        {
     
    102101};
    103102
     103const int USB_HID_MAX_SUBDRIVERS =
     104    sizeof(usb_hid_subdrivers) / sizeof(usb_hid_subdrivers[0]);
     105
    104106/**
    105107 * @}
  • uspace/drv/bus/usb/usbhid/subdrivers.h

    r4c3ad56 r20a3465  
    6464         */
    6565        const usb_hid_subdriver_usage_t *usage_path;
    66        
     66
    6767        /** Report ID for which the path should apply. */
    6868        int report_id;
    69        
     69
    7070        /** Compare type for the Usage path. */
    7171        int compare;
    72        
     72
    7373        /** Vendor ID (set to -1 if not specified). */
    7474        int vendor_id;
    75        
     75
    7676        /** Product ID (set to -1 if not specified). */
    7777        int product_id;
    78        
     78
    7979        /** Subdriver for controlling this device. */
    80         usb_hid_subdriver_t subdriver;
     80        const usb_hid_subdriver_t subdriver;
    8181} usb_hid_subdriver_mapping_t;
    8282
     
    8484
    8585extern const usb_hid_subdriver_mapping_t usb_hid_subdrivers[];
     86extern const int USB_HID_MAX_SUBDRIVERS;
    8687
    8788/*----------------------------------------------------------------------------*/
  • uspace/drv/bus/usb/usbhid/usbhid.c

    r4c3ad56 r20a3465  
    5454
    5555/* Array of endpoints expected on the device, NULL terminated. */
    56 usb_endpoint_description_t *usb_hid_endpoints[USB_HID_POLL_EP_COUNT + 1] = {
     56const usb_endpoint_description_t *usb_hid_endpoints[] = {
    5757        &usb_hid_kbd_poll_endpoint_description,
    5858        &usb_hid_mouse_poll_endpoint_description,
     
    6161};
    6262
    63 static const int USB_HID_MAX_SUBDRIVERS = 10;
    64 
    6563/*----------------------------------------------------------------------------*/
    6664
    6765static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev)
    6866{
    69         assert(hid_dev != NULL && hid_dev->subdriver_count == 0);
    70        
    71         hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
    72             sizeof(usb_hid_subdriver_t));
     67        assert(hid_dev != NULL);
     68        assert(hid_dev->subdriver_count == 0);
     69
     70        hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));
    7371        if (hid_dev->subdrivers == NULL) {
    7472                return ENOMEM;
    7573        }
    76        
    77         assert(hid_dev->subdriver_count >= 0);
    78        
    79         // set the init callback
    80         hid_dev->subdrivers[hid_dev->subdriver_count].init = usb_kbd_init;
    81        
    82         // set the polling callback
    83         hid_dev->subdrivers[hid_dev->subdriver_count].poll =
    84             usb_kbd_polling_callback;
    85        
    86         // set the polling ended callback
    87         hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL;
    88        
    89         // set the deinit callback
    90         hid_dev->subdrivers[hid_dev->subdriver_count].deinit = usb_kbd_deinit;
    91        
    92         // set subdriver count
    93         ++hid_dev->subdriver_count;
    94        
     74        hid_dev->subdriver_count = 1;
     75        // TODO 0 should be keyboard, but find a better way
     76        hid_dev->subdrivers[0] = usb_hid_subdrivers[0].subdriver;
     77
    9578        return EOK;
    9679}
     
    10083static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev)
    10184{
    102         assert(hid_dev != NULL && hid_dev->subdriver_count == 0);
    103        
    104         hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
    105             sizeof(usb_hid_subdriver_t));
     85        assert(hid_dev != NULL);
     86        assert(hid_dev->subdriver_count == 0);
     87
     88        hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));
    10689        if (hid_dev->subdrivers == NULL) {
    10790                return ENOMEM;
    10891        }
    109        
    110         assert(hid_dev->subdriver_count >= 0);
    111        
    112         // set the init callback
    113         hid_dev->subdrivers[hid_dev->subdriver_count].init = usb_mouse_init;
    114        
    115         // set the polling callback
    116         hid_dev->subdrivers[hid_dev->subdriver_count].poll =
    117             usb_mouse_polling_callback;
    118        
    119         // set the polling ended callback
    120         hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL;
    121        
    122         // set the deinit callback
    123         hid_dev->subdrivers[hid_dev->subdriver_count].deinit = usb_mouse_deinit;
    124        
    125         // set subdriver count
    126         ++hid_dev->subdriver_count;
    127        
     92        hid_dev->subdriver_count = 1;
     93        // TODO 2 should be mouse, but find a better way
     94        hid_dev->subdrivers[2] = usb_hid_subdrivers[0].subdriver;
     95
    12896        return EOK;
    12997}
     
    134102{
    135103        assert(hid_dev != NULL && hid_dev->subdriver_count == 0);
    136        
    137         hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(
    138             sizeof(usb_hid_subdriver_t));
     104
     105        hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));
    139106        if (hid_dev->subdrivers == NULL) {
    140107                return ENOMEM;
    141108        }
    142        
    143         assert(hid_dev->subdriver_count >= 0);
    144        
    145         // set the init callback
    146         hid_dev->subdrivers[hid_dev->subdriver_count].init =
    147             usb_generic_hid_init;
    148        
    149         // set the polling callback
    150         hid_dev->subdrivers[hid_dev->subdriver_count].poll =
    151             usb_generic_hid_polling_callback;
    152        
    153         // set the polling ended callback
    154         hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL;
    155        
    156         // set the deinit callback
    157         hid_dev->subdrivers[hid_dev->subdriver_count].deinit = NULL;
    158        
    159         // set subdriver count
    160         ++hid_dev->subdriver_count;
    161        
     109        hid_dev->subdriver_count = 1;
     110
     111        /* Set generic hid subdriver routines */
     112        hid_dev->subdrivers[0].init = usb_generic_hid_init;
     113        hid_dev->subdrivers[0].poll = usb_generic_hid_polling_callback;
     114        hid_dev->subdrivers[0].poll_end = NULL;
     115        hid_dev->subdrivers[0].deinit = usb_generic_hid_deinit;
     116
    162117        return EOK;
    163118}
     
    165120/*----------------------------------------------------------------------------*/
    166121
    167 static bool usb_hid_ids_match(usb_hid_dev_t *hid_dev,
     122static bool usb_hid_ids_match(const usb_hid_dev_t *hid_dev,
    168123    const usb_hid_subdriver_mapping_t *mapping)
    169124{
    170125        assert(hid_dev != NULL);
    171126        assert(hid_dev->usb_dev != NULL);
    172        
    173         return (hid_dev->usb_dev->descriptors.device.vendor_id 
     127
     128        return (hid_dev->usb_dev->descriptors.device.vendor_id
    174129            == mapping->vendor_id
    175130            && hid_dev->usb_dev->descriptors.device.product_id
     
    179134/*----------------------------------------------------------------------------*/
    180135
    181 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 
     136static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev,
    182137    const usb_hid_subdriver_mapping_t *mapping)
    183138{
    184139        assert(hid_dev != NULL);
    185140        assert(mapping != NULL);
    186        
     141
    187142        usb_hid_report_path_t *usage_path = usb_hid_report_path();
    188143        if (usage_path == NULL) {
     
    191146        }
    192147        int i = 0;
    193         while (mapping->usage_path[i].usage != 0 
     148        while (mapping->usage_path[i].usage != 0
    194149            || mapping->usage_path[i].usage_page != 0) {
    195                 if (usb_hid_report_path_append_item(usage_path, 
    196                     mapping->usage_path[i].usage_page, 
     150                if (usb_hid_report_path_append_item(usage_path,
     151                    mapping->usage_path[i].usage_page,
    197152                    mapping->usage_path[i].usage) != EOK) {
    198153                        usb_log_debug("Failed to append to usage path.\n");
     
    202157                ++i;
    203158        }
    204        
    205         assert(hid_dev->report != NULL);
    206        
     159
    207160        usb_log_debug("Compare flags: %d\n", mapping->compare);
    208        
     161
    209162        bool matches = false;
    210163        uint8_t report_id = mapping->report_id;
     
    212165        do {
    213166                usb_log_debug("Trying report id %u\n", report_id);
    214                
     167
    215168                if (report_id != 0) {
    216169                        usb_hid_report_path_set_report_id(usage_path,
     
    219172
    220173                usb_hid_report_field_t *field = usb_hid_report_get_sibling(
    221                     hid_dev->report,
    222                     NULL, usage_path, mapping->compare,
     174                    &hid_dev->report, NULL, usage_path, mapping->compare,
    223175                    USB_HID_REPORT_TYPE_INPUT);
    224                
     176
    225177                usb_log_debug("Field: %p\n", field);
    226178
     
    229181                        break;
    230182                }
    231                
     183
    232184                report_id = usb_hid_get_next_report_id(
    233                     hid_dev->report, report_id,
    234                     USB_HID_REPORT_TYPE_INPUT);
     185                    &hid_dev->report, report_id, USB_HID_REPORT_TYPE_INPUT);
    235186        } while (!matches && report_id != 0);
    236        
     187
    237188        usb_hid_report_path_free(usage_path);
    238        
     189
    239190        return matches;
    240191}
     
    242193/*----------------------------------------------------------------------------*/
    243194
    244 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev, 
     195static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev,
    245196    const usb_hid_subdriver_t **subdrivers, int count)
    246197{
    247198        int i;
    248        
     199
    249200        if (count <= 0) {
    250201                hid_dev->subdriver_count = 0;
     
    252203                return EOK;
    253204        }
    254        
    255         // add one generic HID subdriver per device
    256        
    257         hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc((count + 1) *
    258             sizeof(usb_hid_subdriver_t));
     205
     206        /* +1 for generic hid subdriver */
     207        hid_dev->subdrivers = calloc((count + 1), sizeof(usb_hid_subdriver_t));
    259208        if (hid_dev->subdrivers == NULL) {
    260209                return ENOMEM;
    261210        }
    262        
     211
    263212        for (i = 0; i < count; ++i) {
    264213                hid_dev->subdrivers[i].init = subdrivers[i]->init;
     
    267216                hid_dev->subdrivers[i].poll_end = subdrivers[i]->poll_end;
    268217        }
    269        
     218
     219        /* Add one generic HID subdriver per device */
    270220        hid_dev->subdrivers[count].init = usb_generic_hid_init;
    271221        hid_dev->subdrivers[count].poll = usb_generic_hid_polling_callback;
    272         hid_dev->subdrivers[count].deinit = NULL;
     222        hid_dev->subdrivers[count].deinit = usb_generic_hid_deinit;
    273223        hid_dev->subdrivers[count].poll_end = NULL;
    274        
     224
    275225        hid_dev->subdriver_count = count + 1;
    276        
     226
    277227        return EOK;
    278228}
     
    283233{
    284234        assert(hid_dev != NULL);
    285        
     235
    286236        const usb_hid_subdriver_t *subdrivers[USB_HID_MAX_SUBDRIVERS];
    287        
     237
    288238        int i = 0, count = 0;
    289239        const usb_hid_subdriver_mapping_t *mapping = &usb_hid_subdrivers[i];
     
    291241        bool ids_matched;
    292242        bool matched;
    293        
     243
    294244        while (count < USB_HID_MAX_SUBDRIVERS &&
    295245            (mapping->usage_path != NULL
     
    306256                        return EINVAL;
    307257                }
    308                
     258
    309259                ids_matched = false;
    310260                matched = false;
    311                
     261
    312262                if (mapping->vendor_id >= 0) {
    313263                        assert(mapping->product_id >= 0);
     
    320270                        }
    321271                }
    322                
     272
    323273                if (mapping->usage_path != NULL) {
    324274                        usb_log_debug("Comparing device against usage path.\n");
     
    331281                        matched = ids_matched;
    332282                }
    333                
     283
    334284                if (matched) {
    335285                        usb_log_debug("Subdriver matched.\n");
    336286                        subdrivers[count++] = &mapping->subdriver;
    337287                }
    338                
     288
    339289                mapping = &usb_hid_subdrivers[++i];
    340290        }
    341        
    342         // we have all subdrivers determined, save them into the hid device
     291
     292        /* We have all subdrivers determined, save them into the hid device */
     293        // TODO Dowe really need this complicated stuff if there is
     294        // max_subdrivers limitation?
    343295        return usb_hid_save_subdrivers(hid_dev, subdrivers, count);
    344296}
     
    346298/*----------------------------------------------------------------------------*/
    347299
    348 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev)
    349 {
    350         assert(hid_dev != NULL && dev != NULL);
    351        
    352         int rc = EOK;
    353        
     300static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, const usb_device_t *dev)
     301{
     302        assert(hid_dev);
     303        assert(dev);
     304
    354305        if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) {
    355306                usb_log_debug("Found keyboard endpoint.\n");
     
    367318                usb_log_error("None of supported endpoints found - probably"
    368319                    " not a supported device.\n");
    369                 rc = ENOTSUP;
    370         }
    371        
    372         return rc;
     320                return ENOTSUP;
     321        }
     322
     323        return EOK;
    373324}
    374325
     
    377328static int usb_hid_init_report(usb_hid_dev_t *hid_dev)
    378329{
    379         assert(hid_dev != NULL && hid_dev->report != NULL);
    380        
     330        assert(hid_dev != NULL);
     331
    381332        uint8_t report_id = 0;
    382         size_t size;
    383        
    384333        size_t max_size = 0;
    385        
     334
    386335        do {
    387336                usb_log_debug("Getting size of the report.\n");
    388                 size = usb_hid_report_byte_size(hid_dev->report, report_id,
    389                     USB_HID_REPORT_TYPE_INPUT);
     337                const size_t size =
     338                    usb_hid_report_byte_size(&hid_dev->report, report_id,
     339                        USB_HID_REPORT_TYPE_INPUT);
    390340                usb_log_debug("Report ID: %u, size: %zu\n", report_id, size);
    391341                max_size = (size > max_size) ? size : max_size;
    392342                usb_log_debug("Getting next report ID\n");
    393                 report_id = usb_hid_get_next_report_id(hid_dev->report,
     343                report_id = usb_hid_get_next_report_id(&hid_dev->report,
    394344                    report_id, USB_HID_REPORT_TYPE_INPUT);
    395345        } while (report_id != 0);
    396        
     346
    397347        usb_log_debug("Max size of input report: %zu\n", max_size);
    398        
    399         hid_dev->max_input_report_size = max_size;
     348
    400349        assert(hid_dev->input_report == NULL);
    401        
    402         hid_dev->input_report = malloc(max_size);
     350
     351        hid_dev->input_report = calloc(1, max_size);
    403352        if (hid_dev->input_report == NULL) {
    404353                return ENOMEM;
    405354        }
    406         memset(hid_dev->input_report, 0, max_size);
    407        
     355        hid_dev->max_input_report_size = max_size;
     356
    408357        return EOK;
    409358}
     
    411360/*----------------------------------------------------------------------------*/
    412361
    413 usb_hid_dev_t *usb_hid_new(void)
    414 {
    415         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)calloc(1,
    416             sizeof(usb_hid_dev_t));
    417        
    418         if (hid_dev == NULL) {
    419                 usb_log_fatal("No memory!\n");
    420                 return NULL;
    421         }
    422        
    423         hid_dev->report = (usb_hid_report_t *)(malloc(sizeof(
    424             usb_hid_report_t)));
    425         if (hid_dev->report == NULL) {
    426                 usb_log_fatal("No memory!\n");
    427                 free(hid_dev);
    428                 return NULL;
    429         }
    430        
    431         hid_dev->poll_pipe_index = -1;
    432        
    433         return hid_dev;
    434 }
    435 
    436 /*----------------------------------------------------------------------------*/
    437 
    438362int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev)
    439363{
    440364        int rc, i;
    441        
     365
    442366        usb_log_debug("Initializing HID structure...\n");
    443        
     367
    444368        if (hid_dev == NULL) {
    445369                usb_log_error("Failed to init HID structure: no structure given"
     
    447371                return EINVAL;
    448372        }
    449        
     373
    450374        if (dev == NULL) {
    451375                usb_log_error("Failed to init HID structure: no USB device"
     
    453377                return EINVAL;
    454378        }
    455        
     379
     380        usb_hid_report_init(&hid_dev->report);
     381
    456382        /* The USB device should already be initialized, save it in structure */
    457383        hid_dev->usb_dev = dev;
    458        
     384        hid_dev->poll_pipe_index = -1;
     385
    459386        rc = usb_hid_check_pipes(hid_dev, dev);
    460387        if (rc != EOK) {
    461388                return rc;
    462389        }
    463                
     390
    464391        /* Get the report descriptor and parse it. */
    465         rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 
    466             hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size);
    467        
     392        rc = usb_hid_process_report_descriptor(hid_dev->usb_dev,
     393            &hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size);
     394
    468395        bool fallback = false;
    469        
     396
    470397        if (rc == EOK) {
    471398                // try to find subdrivers that may want to handle this device
     
    484411                fallback = true;
    485412        }
    486        
     413
    487414        if (fallback) {
    488415                // fall back to boot protocol
     
    503430                        break;
    504431                default:
    505                         assert(hid_dev->poll_pipe_index 
     432                        assert(hid_dev->poll_pipe_index
    506433                            == USB_HID_GENERIC_POLL_EP_NO);
    507                        
     434
    508435                        usb_log_info("Falling back to generic HID driver.\n");
    509436                        rc = usb_hid_set_generic_hid_subdriver(hid_dev);
    510437                }
    511438        }
    512        
     439
    513440        if (rc != EOK) {
    514441                usb_log_error("No subdriver for handling this device could be"
    515442                    " initialized: %s.\n", str_error(rc));
    516                 usb_log_debug("Subdriver count: %d\n", 
     443                usb_log_debug("Subdriver count: %d\n",
    517444                    hid_dev->subdriver_count);
    518                
    519445        } else {
    520446                bool ok = false;
    521                
    522                 usb_log_debug("Subdriver count: %d\n", 
     447
     448                usb_log_debug("Subdriver count: %d\n",
    523449                    hid_dev->subdriver_count);
    524                
     450
    525451                for (i = 0; i < hid_dev->subdriver_count; ++i) {
    526452                        if (hid_dev->subdrivers[i].init != NULL) {
     
    539465                        }
    540466                }
    541                
     467
    542468                rc = (ok) ? EOK : -1;   // what error to report
    543469        }
    544        
    545        
     470
     471
    546472        if (rc == EOK) {
    547473                // save max input report size and allocate space for the report
     
    552478                }
    553479        }
    554        
    555        
     480
    556481        return rc;
    557482}
     
    559484/*----------------------------------------------------------------------------*/
    560485
    561 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 
     486bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
    562487    size_t buffer_size, void *arg)
    563488{
    564         int i;
    565        
    566489        if (dev == NULL || arg == NULL || buffer == NULL) {
    567490                usb_log_error("Missing arguments to polling callback.\n");
    568491                return false;
    569492        }
    570        
    571         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
    572        
     493        usb_hid_dev_t *hid_dev = arg;
     494
    573495        assert(hid_dev->input_report != NULL);
     496
    574497        usb_log_debug("New data [%zu/%zu]: %s\n", buffer_size,
    575498            hid_dev->max_input_report_size,
     
    582505                usb_hid_new_report(hid_dev);
    583506        }
    584        
    585         // parse the input report
    586        
    587         int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size,
    588             &hid_dev->report_id);
    589        
     507
     508        /* Parse the input report */
     509        const int rc = usb_hid_parse_report(
     510            &hid_dev->report, buffer, buffer_size, &hid_dev->report_id);
    590511        if (rc != EOK) {
    591512                usb_log_warning("Error in usb_hid_parse_report():"
    592513                    "%s\n", str_error(rc));
    593         }       
    594        
     514        }
     515
    595516        bool cont = false;
    596        
    597         // continue if at least one of the subdrivers want to continue
    598         for (i = 0; i < hid_dev->subdriver_count; ++i) {
    599                 if (hid_dev->subdrivers[i].poll != NULL
    600                     && hid_dev->subdrivers[i].poll(hid_dev,
    601                         hid_dev->subdrivers[i].data)) {
    602                         cont = true;
    603                 }
    604         }
    605        
     517        /* Continue if at least one of the subdrivers want to continue */
     518        for (int i = 0; i < hid_dev->subdriver_count; ++i) {
     519                if (hid_dev->subdrivers[i].poll != NULL) {
     520                        cont = cont || hid_dev->subdrivers[i].poll(
     521                            hid_dev, hid_dev->subdrivers[i].data);
     522                }
     523        }
     524
    606525        return cont;
    607526}
     
    609528/*----------------------------------------------------------------------------*/
    610529
    611 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason,
    612      void *arg)
    613 {
    614         int i;
    615        
    616         if (dev == NULL || arg == NULL) {
    617                 return;
    618         }
    619        
    620         usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;
    621        
    622         for (i = 0; i < hid_dev->subdriver_count; ++i) {
     530void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, void *arg)
     531{
     532        assert(dev);
     533        assert(arg);
     534
     535        usb_hid_dev_t *hid_dev = arg;
     536
     537        for (int i = 0; i < hid_dev->subdriver_count; ++i) {
    623538                if (hid_dev->subdrivers[i].poll_end != NULL) {
    624                         hid_dev->subdrivers[i].poll_end(hid_dev,
    625                             hid_dev->subdrivers[i].data, reason);
    626                 }
    627         }
    628        
    629         usb_hid_destroy(hid_dev);
     539                        hid_dev->subdrivers[i].poll_end(
     540                            hid_dev, hid_dev->subdrivers[i].data, reason);
     541                }
     542        }
     543
     544        hid_dev->running = false;
    630545}
    631546
     
    639554/*----------------------------------------------------------------------------*/
    640555
    641 int usb_hid_report_number(usb_hid_dev_t *hid_dev)
     556int usb_hid_report_number(const usb_hid_dev_t *hid_dev)
    642557{
    643558        return hid_dev->report_nr;
     
    646561/*----------------------------------------------------------------------------*/
    647562
    648 void usb_hid_destroy(usb_hid_dev_t *hid_dev)
    649 {
    650         int i;
    651        
    652         if (hid_dev == NULL) {
    653                 return;
    654         }
    655        
     563void usb_hid_deinit(usb_hid_dev_t *hid_dev)
     564{
     565        assert(hid_dev);
     566        assert(hid_dev->subdrivers != NULL || hid_dev->subdriver_count == 0);
     567
     568
    656569        usb_log_debug("Subdrivers: %p, subdriver count: %d\n",
    657570            hid_dev->subdrivers, hid_dev->subdriver_count);
    658        
    659         assert(hid_dev->subdrivers != NULL
    660             || hid_dev->subdriver_count == 0);
    661        
    662         for (i = 0; i < hid_dev->subdriver_count; ++i) {
     571
     572        for (int i = 0; i < hid_dev->subdriver_count; ++i) {
    663573                if (hid_dev->subdrivers[i].deinit != NULL) {
    664574                        hid_dev->subdrivers[i].deinit(hid_dev,
     
    666576                }
    667577        }
    668        
    669         // free the subdrivers info
    670         if (hid_dev->subdrivers != NULL) {
    671                 free(hid_dev->subdrivers);
    672         }
    673 
    674         // destroy the parser
    675         if (hid_dev->report != NULL) {
    676                 usb_hid_free_report(hid_dev->report);
    677         }
    678 
    679         if (hid_dev->report_desc != NULL) {
    680                 free(hid_dev->report_desc);
    681         }
     578
     579        /* Free allocated structures */
     580        free(hid_dev->subdrivers);
     581        free(hid_dev->report_desc);
     582
     583        /* Destroy the parser */
     584        usb_hid_report_deinit(&hid_dev->report);
     585
    682586}
    683587
  • uspace/drv/bus/usb/usbhid/usbhid.h

    r4c3ad56 r20a3465  
    102102        /** Structure holding generic USB device information. */
    103103        usb_device_t *usb_dev;
    104        
     104
    105105        /** Index of the polling pipe in usb_hid_endpoints array. */
    106106        int poll_pipe_index;
    107        
     107
    108108        /** Subdrivers. */
    109109        usb_hid_subdriver_t *subdrivers;
    110        
     110
    111111        /** Number of subdrivers. */
    112112        int subdriver_count;
    113        
     113
    114114        /** Report descriptor. */
    115115        uint8_t *report_desc;
     
    117117        /** Report descriptor size. */
    118118        size_t report_desc_size;
    119        
     119
    120120        /** HID Report parser. */
    121         usb_hid_report_t *report;
    122        
     121        usb_hid_report_t report;
     122
    123123        uint8_t report_id;
    124        
     124
    125125        uint8_t *input_report;
    126        
     126
    127127        size_t input_report_size;
    128128        size_t max_input_report_size;
    129        
     129
    130130        int report_nr;
     131        volatile bool running;
    131132};
    132133
     
    140141};
    141142
    142 usb_endpoint_description_t *usb_hid_endpoints[USB_HID_POLL_EP_COUNT + 1];
     143extern const usb_endpoint_description_t *usb_hid_endpoints[];
    143144
    144145/*----------------------------------------------------------------------------*/
    145146
    146 usb_hid_dev_t *usb_hid_new(void);
    147 
    148147int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev);
    149148
    150 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,
    151     size_t buffer_size, void *arg);
     149void usb_hid_deinit(usb_hid_dev_t *hid_dev);
    152150
    153 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason,
    154      void *arg);
     151bool usb_hid_polling_callback(usb_device_t *dev,
     152    uint8_t *buffer, size_t buffer_size, void *arg);
     153
     154void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, void *arg);
    155155
    156156void usb_hid_new_report(usb_hid_dev_t *hid_dev);
    157157
    158 int usb_hid_report_number(usb_hid_dev_t *hid_dev);
    159 
    160 void usb_hid_destroy(usb_hid_dev_t *hid_dev);
     158int usb_hid_report_number(const usb_hid_dev_t *hid_dev);
    161159
    162160#endif /* USB_HID_USBHID_H_ */
Note: See TracChangeset for help on using the changeset viewer.