Changeset 8961c22 in mainline


Ignore:
Timestamp:
2011-04-09T08:35:58Z (13 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1e1b1a9
Parents:
3e490eb (diff), 61727bf (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 with usb/development

Files:
17 added
23 edited

Legend:

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

    r3e490eb r8961c22  
    5050        usbhub \
    5151        usbkbd \
     52        usbhid \
    5253        usbmid \
    5354        usbmouse \
  • uspace/Makefile

    r3e490eb r8961c22  
    123123                drv/usbflbk \
    124124                drv/usbkbd \
     125                drv/usbhid \
    125126                drv/usbhub \
    126127                drv/usbmid \
     
    143144                drv/usbflbk \
    144145                drv/usbkbd \
     146                drv/usbhid \
    145147                drv/usbhub \
    146148                drv/usbmid \
  • uspace/drv/ohci/root_hub.c

    r3e490eb r8961c22  
    249249                opResult = EINVAL;
    250250        }
    251         usb_transfer_batch_finish(request, opResult);
     251        usb_transfer_batch_finish_error(request, opResult);
    252252        return EOK;
    253253}
     
    863863}
    864864
    865 
    866 
    867 
    868865/**
    869866 * @}
  • uspace/drv/uhci-hcd/batch.c

    r3e490eb r8961c22  
    8080 * transaction and callback.
    8181 */
    82 usb_transfer_batch_t * batch_get(ddf_fun_t *fun, usb_target_t target,
    83     usb_transfer_type_t transfer_type, size_t max_packet_size,
    84     usb_speed_t speed, char *buffer, size_t buffer_size,
    85     char* setup_buffer, size_t setup_size,
     82usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep,
     83    char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size,
    8684    usbhc_iface_transfer_in_callback_t func_in,
    87     usbhc_iface_transfer_out_callback_t func_out, void *arg, endpoint_t *ep
    88     )
    89 {
     85    usbhc_iface_transfer_out_callback_t func_out, void *arg)
     86{
     87        assert(ep);
    9088        assert(func_in == NULL || func_out == NULL);
    9189        assert(func_in != NULL || func_out != NULL);
     
    103101        CHECK_NULL_DISPOSE_RETURN(instance,
    104102            "Failed to allocate batch instance.\n");
     103        usb_target_t target =
     104            { .address = ep->address, .endpoint = ep->endpoint };
    105105        usb_transfer_batch_init(instance, target,
    106             transfer_type, speed, max_packet_size,
     106            ep->transfer_type, ep->speed, ep->max_packet_size,
    107107            buffer, NULL, buffer_size, NULL, setup_size, func_in,
    108108            func_out, arg, fun, ep, NULL);
     
    115115        instance->private_data = data;
    116116
    117         data->transfers = (buffer_size + max_packet_size - 1) / max_packet_size;
    118         if (transfer_type == USB_TRANSFER_CONTROL) {
     117        data->transfers =
     118            (buffer_size + ep->max_packet_size - 1) / ep->max_packet_size;
     119        if (ep->transfer_type == USB_TRANSFER_CONTROL) {
    119120                data->transfers += 2;
    120121        }
     
    178179                            instance, i, data->tds[i].status);
    179180                        td_print_status(&data->tds[i]);
    180                         if (instance->ep != NULL)
    181                                 endpoint_toggle_set(instance->ep,
    182                                     td_toggle(&data->tds[i]));
     181                        assert(instance->ep != NULL);
     182
     183                        endpoint_toggle_set(instance->ep,
     184                            td_toggle(&data->tds[i]));
    183185                        if (i > 0)
    184186                                goto substract_ret;
  • uspace/drv/uhci-hcd/batch.h

    r3e490eb r8961c22  
    4444
    4545usb_transfer_batch_t * batch_get(
    46     ddf_fun_t *fun,
    47                 usb_target_t target,
    48     usb_transfer_type_t transfer_type,
    49                 size_t max_packet_size,
    50     usb_speed_t speed,
    51                 char *buffer,
    52                 size_t size,
    53                 char *setup_buffer,
    54                 size_t setup_size,
     46    ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size,
     47    char *setup_buffer, size_t setup_size,
    5548    usbhc_iface_transfer_in_callback_t func_in,
    5649    usbhc_iface_transfer_out_callback_t func_out,
    57                 void *arg,
    58                 endpoint_t *ep
    59                 );
     50    void *arg);
    6051
    6152void batch_dispose(usb_transfer_batch_t *instance);
  • uspace/drv/uhci-hcd/hc.c

    r3e490eb r8961c22  
    332332            instance->transfers[batch->speed][batch->transfer_type];
    333333        assert(list);
    334         if (batch->transfer_type == USB_TRANSFER_CONTROL) {
    335                 usb_device_keeper_use_control(
    336                     &instance->manager, batch->target);
    337         }
    338334        transfer_list_add_batch(list, batch);
    339335
     
    373369                        usb_transfer_batch_t *batch =
    374370                            list_get_instance(item, usb_transfer_batch_t, link);
    375                         switch (batch->transfer_type)
    376                         {
    377                         case USB_TRANSFER_CONTROL:
    378                                 usb_device_keeper_release_control(
    379                                     &instance->manager, batch->target);
    380                                 break;
    381                         case USB_TRANSFER_INTERRUPT:
    382                         case USB_TRANSFER_ISOCHRONOUS: {
    383 /*
    384                                 int ret = bandwidth_free(&instance->bandwidth,
    385                                     batch->target.address,
    386                                     batch->target.endpoint,
    387                                     batch->direction);
    388                                 if (ret != EOK)
    389                                         usb_log_warning("Failed(%d) to free "
    390                                             "reserved bw: %s.\n", ret,
    391                                             str_error(ret));
    392 */
    393                                 }
    394                         default:
    395                                 break;
    396                         }
    397                         batch->next_step(batch);
     371                        usb_transfer_batch_finish(batch);
    398372                }
    399373        }
  • uspace/drv/uhci-hcd/iface.c

    r3e490eb r8961c22  
    4040#include "iface.h"
    4141#include "hc.h"
     42
     43static inline int setup_batch(
     44    ddf_fun_t *fun, usb_target_t target, usb_direction_t direction,
     45    void *data, size_t size, void * setup_data, size_t setup_size,
     46    usbhc_iface_transfer_in_callback_t in,
     47    usbhc_iface_transfer_out_callback_t out, void *arg, const char* name,
     48    hc_t **hc, usb_transfer_batch_t **batch)
     49{
     50        assert(hc);
     51        assert(batch);
     52        assert(fun);
     53        *hc = fun_to_hc(fun);
     54        assert(*hc);
     55
     56        size_t res_bw;
     57        endpoint_t *ep = usb_endpoint_manager_get_ep(&(*hc)->ep_manager,
     58            target.address, target.endpoint, direction, &res_bw);
     59        if (ep == NULL) {
     60                usb_log_error("Endpoint(%d:%d) not registered for %s.\n",
     61                    target.address, target.endpoint, name);
     62                return ENOENT;
     63        }
     64
     65        const size_t bw = bandwidth_count_usb11(
     66            ep->speed, ep->transfer_type, size, ep->max_packet_size);
     67        if (res_bw < bw) {
     68                usb_log_error("Endpoint(%d:%d) %s needs %zu bw "
     69                    "but only %zu is reserved.\n",
     70                    name, target.address, target.endpoint, bw, res_bw);
     71                return ENOSPC;
     72        }
     73        usb_log_debug("%s %d:%d %zu(%zu).\n",
     74            name, target.address, target.endpoint, size, ep->max_packet_size);
     75
     76        assert(ep->speed ==
     77            usb_device_keeper_get_speed(&(*hc)->manager, target.address));
     78//      assert(ep->max_packet_size == max_packet_size);
     79//      assert(ep->transfer_type == USB_TRANSFER_CONTROL);
     80
     81        *batch =
     82            batch_get(fun, ep, data, size, setup_data, setup_size,
     83                in, out, arg);
     84        if (!batch)
     85                return ENOMEM;
     86        return EOK;
     87}
     88
    4289
    4390/** Reserve default address interface function
     
    215262    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    216263{
    217         assert(fun);
    218         hc_t *hc = fun_to_hc(fun);
    219         assert(hc);
    220 
    221         usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n",
    222             target.address, target.endpoint, size, max_packet_size);
    223 
    224         size_t res_bw;
    225         endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
    226             target.address, target.endpoint, USB_DIRECTION_OUT, &res_bw);
    227         if (ep == NULL) {
    228                 usb_log_error("Endpoint(%d:%d) not registered for INT OUT.\n",
    229                         target.address, target.endpoint);
    230                 return ENOENT;
    231         }
    232         const size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type,
    233             size, ep->max_packet_size);
    234         if (res_bw < bw)
    235         {
    236                 usb_log_error("Endpoint(%d:%d) INT IN needs %zu bw "
    237                     "but only %zu is reserved.\n",
    238                     target.address, target.endpoint, bw, res_bw);
    239                 return ENOENT;
    240         }
    241         assert(ep->speed ==
    242             usb_device_keeper_get_speed(&hc->manager, target.address));
    243         assert(ep->max_packet_size == max_packet_size);
    244         assert(ep->transfer_type == USB_TRANSFER_INTERRUPT);
    245 
    246         usb_transfer_batch_t *batch =
    247             batch_get(fun, target, ep->transfer_type, ep->max_packet_size,
    248                 ep->speed, data, size, NULL, 0, NULL, callback, arg, ep);
    249         if (!batch)
    250                 return ENOMEM;
     264        usb_transfer_batch_t *batch = NULL;
     265        hc_t *hc = NULL;
     266        int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size,
     267            NULL, 0, NULL, callback, arg, "Interrupt OUT", &hc, &batch);
     268        if (ret != EOK)
     269                return ret;
    251270        batch_interrupt_out(batch);
    252         const int ret = hc_schedule(hc, batch);
     271        ret = hc_schedule(hc, batch);
    253272        if (ret != EOK) {
    254273                batch_dispose(batch);
     
    272291    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    273292{
    274         assert(fun);
    275         hc_t *hc = fun_to_hc(fun);
    276         assert(hc);
    277 
    278         usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n",
    279             target.address, target.endpoint, size, max_packet_size);
    280 
    281         size_t res_bw;
    282         endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
    283             target.address, target.endpoint, USB_DIRECTION_IN, &res_bw);
    284         if (ep == NULL) {
    285                 usb_log_error("Endpoint(%d:%d) not registered for INT IN.\n",
    286                     target.address, target.endpoint);
    287                 return ENOENT;
    288         }
    289         const size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type,
    290             size, ep->max_packet_size);
    291         if (res_bw < bw)
    292         {
    293                 usb_log_error("Endpoint(%d:%d) INT IN needs %zu bw "
    294                     "but only %zu bw is reserved.\n",
    295                     target.address, target.endpoint, bw, res_bw);
    296                 return ENOENT;
    297         }
    298 
    299         assert(ep->speed ==
    300             usb_device_keeper_get_speed(&hc->manager, target.address));
    301         assert(ep->max_packet_size == max_packet_size);
    302         assert(ep->transfer_type == USB_TRANSFER_INTERRUPT);
    303 
    304         usb_transfer_batch_t *batch =
    305             batch_get(fun, target, ep->transfer_type, ep->max_packet_size,
    306                 ep->speed, data, size, NULL, 0, callback, NULL, arg, ep);
    307         if (!batch)
    308                 return ENOMEM;
     293        usb_transfer_batch_t *batch = NULL;
     294        hc_t *hc = NULL;
     295        int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size,
     296            NULL, 0, callback, NULL, arg, "Interrupt IN", &hc, &batch);
     297        if (ret != EOK)
     298                return ret;
    309299        batch_interrupt_in(batch);
    310         const int ret = hc_schedule(hc, batch);
     300        ret = hc_schedule(hc, batch);
    311301        if (ret != EOK) {
    312302                batch_dispose(batch);
     
    330320    size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg)
    331321{
    332         assert(fun);
    333         hc_t *hc = fun_to_hc(fun);
    334         assert(hc);
    335 
    336         usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n",
    337             target.address, target.endpoint, size, max_packet_size);
    338 
    339         endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
    340             target.address, target.endpoint, USB_DIRECTION_OUT, NULL);
    341         if (ep == NULL) {
    342                 usb_log_error("Endpoint(%d:%d) not registered for BULK OUT.\n",
    343                         target.address, target.endpoint);
    344                 return ENOENT;
    345         }
    346         assert(ep->speed ==
    347             usb_device_keeper_get_speed(&hc->manager, target.address));
    348         assert(ep->max_packet_size == max_packet_size);
    349         assert(ep->transfer_type == USB_TRANSFER_BULK);
    350 
    351         usb_transfer_batch_t *batch =
    352             batch_get(fun, target, ep->transfer_type, ep->max_packet_size,
    353                 ep->speed, data, size, NULL, 0, NULL, callback, arg, ep);
    354         if (!batch)
    355                 return ENOMEM;
     322        usb_transfer_batch_t *batch = NULL;
     323        hc_t *hc = NULL;
     324        int ret = setup_batch(fun, target, USB_DIRECTION_OUT, data, size,
     325            NULL, 0, NULL, callback, arg, "Bulk OUT", &hc, &batch);
     326        if (ret != EOK)
     327                return ret;
    356328        batch_bulk_out(batch);
    357         const int ret = hc_schedule(hc, batch);
     329        ret = hc_schedule(hc, batch);
    358330        if (ret != EOK) {
    359331                batch_dispose(batch);
     
    377349    size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg)
    378350{
    379         assert(fun);
    380         hc_t *hc = fun_to_hc(fun);
    381         assert(hc);
    382         usb_log_debug("Bulk IN %d:%d %zu(%zu).\n",
    383             target.address, target.endpoint, size, max_packet_size);
    384 
    385         endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
    386             target.address, target.endpoint, USB_DIRECTION_IN, NULL);
    387         if (ep == NULL) {
    388                 usb_log_error("Endpoint(%d:%d) not registered for BULK IN.\n",
    389                         target.address, target.endpoint);
    390                 return ENOENT;
    391         }
    392         assert(ep->speed ==
    393             usb_device_keeper_get_speed(&hc->manager, target.address));
    394         assert(ep->max_packet_size == max_packet_size);
    395         assert(ep->transfer_type == USB_TRANSFER_BULK);
    396 
    397         usb_transfer_batch_t *batch =
    398             batch_get(fun, target, ep->transfer_type, ep->max_packet_size,
    399                 ep->speed, data, size, NULL, 0, callback, NULL, arg, ep);
    400         if (!batch)
    401                 return ENOMEM;
     351        usb_transfer_batch_t *batch = NULL;
     352        hc_t *hc = NULL;
     353        int ret = setup_batch(fun, target, USB_DIRECTION_IN, data, size,
     354            NULL, 0, callback, NULL, arg, "Bulk IN", &hc, &batch);
     355        if (ret != EOK)
     356                return ret;
    402357        batch_bulk_in(batch);
    403         const int ret = hc_schedule(hc, batch);
     358        ret = hc_schedule(hc, batch);
    404359        if (ret != EOK) {
    405360                batch_dispose(batch);
     
    426381    usbhc_iface_transfer_out_callback_t callback, void *arg)
    427382{
    428         assert(fun);
    429         hc_t *hc = fun_to_hc(fun);
    430         assert(hc);
    431         usb_speed_t speed =
    432             usb_device_keeper_get_speed(&hc->manager, target.address);
    433         usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n",
    434             speed, target.address, target.endpoint, size, max_packet_size);
    435         endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
    436             target.address, target.endpoint, USB_DIRECTION_BOTH, NULL);
    437         if (ep == NULL) {
    438                 usb_log_warning("Endpoint(%d:%d) not registered for CONTROL.\n",
    439                         target.address, target.endpoint);
    440         }
    441 
    442         if (setup_size != 8)
    443                 return EINVAL;
    444 
    445         usb_transfer_batch_t *batch =
    446             batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed,
    447                 data, size, setup_data, setup_size, NULL, callback, arg, ep);
    448         if (!batch)
    449                 return ENOMEM;
     383        usb_transfer_batch_t *batch = NULL;
     384        hc_t *hc = NULL;
     385        int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size,
     386            setup_data, setup_size, NULL, callback, arg, "Control WRITE",
     387            &hc, &batch);
     388        if (ret != EOK)
     389                return ret;
    450390        usb_device_keeper_reset_if_need(&hc->manager, target, setup_data);
    451391        batch_control_write(batch);
    452         const int ret = hc_schedule(hc, batch);
     392        ret = hc_schedule(hc, batch);
    453393        if (ret != EOK) {
    454394                batch_dispose(batch);
     
    475415    usbhc_iface_transfer_in_callback_t callback, void *arg)
    476416{
    477         assert(fun);
    478         hc_t *hc = fun_to_hc(fun);
    479         assert(hc);
    480         usb_speed_t speed =
    481             usb_device_keeper_get_speed(&hc->manager, target.address);
    482 
    483         usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n",
    484             speed, target.address, target.endpoint, size, max_packet_size);
    485         endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,
    486             target.address, target.endpoint, USB_DIRECTION_BOTH, NULL);
    487         if (ep == NULL) {
    488                 usb_log_warning("Endpoint(%d:%d) not registered for CONTROL.\n",
    489                         target.address, target.endpoint);
    490         }
    491         usb_transfer_batch_t *batch =
    492             batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed,
    493                 data, size, setup_data, setup_size, callback, NULL, arg, ep);
    494         if (!batch)
    495                 return ENOMEM;
     417        usb_transfer_batch_t *batch = NULL;
     418        hc_t *hc = NULL;
     419        int ret = setup_batch(fun, target, USB_DIRECTION_BOTH, data, size,
     420            setup_data, setup_size, callback, NULL, arg, "Control READ",
     421            &hc, &batch);
     422        if (ret != EOK)
     423                return ret;
    496424        batch_control_read(batch);
    497         const int ret = hc_schedule(hc, batch);
     425        ret = hc_schedule(hc, batch);
    498426        if (ret != EOK) {
    499427                batch_dispose(batch);
  • uspace/drv/uhci-hcd/transfer_list.c

    r3e490eb r8961c22  
    132132}
    133133/*----------------------------------------------------------------------------*/
    134 /** Check list for finished batches.
    135  *
    136  * @param[in] instance List to use.
    137  * @return Error code
    138  *
    139  * Creates a local list of finished batches and calls next_step on each and
    140  * every one. This is safer because next_step may theoretically access
    141  * this transfer list leading to the deadlock if its done inline.
     134/** Create list for finished batches.
     135 *
     136 * @param[in] instance List to use.
     137 * @param[in] done list to fill
    142138 */
    143139void transfer_list_remove_finished(transfer_list_t *instance, link_t *done)
     
    161157        }
    162158        fibril_mutex_unlock(&instance->guard);
    163 
    164159}
    165160/*----------------------------------------------------------------------------*/
     
    176171                    list_get_instance(current, usb_transfer_batch_t, link);
    177172                transfer_list_remove_batch(instance, batch);
    178                 usb_transfer_batch_finish(batch, EIO);
     173                usb_transfer_batch_finish_error(batch, EIO);
    179174        }
    180175        fibril_mutex_unlock(&instance->guard);
  • uspace/drv/uhci-rhd/root_hub.h

    r3e490eb r8961c22  
    4040
    4141#define UHCI_ROOT_HUB_PORT_COUNT 2
    42 #define ROOT_HUB_WAIT_USEC 5000000 /* 5 seconds */
     42#define ROOT_HUB_WAIT_USEC 250000 /* 250 miliseconds */
    4343
    4444typedef struct root_hub {
  • uspace/drv/usbkbd/kbddev.c

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

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

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

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

    r3e490eb r8961c22  
    9292void usb_transfer_batch_call_in(usb_transfer_batch_t *instance);
    9393void usb_transfer_batch_call_out(usb_transfer_batch_t *instance);
    94 void usb_transfer_batch_finish(usb_transfer_batch_t *instance, int error);
     94void usb_transfer_batch_finish(usb_transfer_batch_t *instance);
     95
     96static inline void usb_transfer_batch_finish_error(
     97    usb_transfer_batch_t *instance, int error)
     98{
     99        assert(instance);
     100        instance->error = error;
     101        usb_transfer_batch_finish(instance);
     102}
    95103
    96104#endif
  • uspace/lib/usb/include/usb/host/device_keeper.h

    r3e490eb r8961c22  
    9696usb_speed_t usb_device_keeper_get_speed(usb_device_keeper_t *instance,
    9797    usb_address_t address);
    98 
    99 void usb_device_keeper_use_control(usb_device_keeper_t *instance,
    100     usb_target_t target);
    101 
    102 void usb_device_keeper_release_control(usb_device_keeper_t *instance,
    103     usb_target_t target);
    104 
    10598#endif
    10699/**
  • uspace/lib/usb/include/usb/host/endpoint.h

    r3e490eb r8961c22  
    3939#include <bool.h>
    4040#include <adt/list.h>
     41#include <fibril_synch.h>
     42
    4143#include <usb/usb.h>
    4244
     
    4850        usb_speed_t speed;
    4951        size_t max_packet_size;
    50         bool active;
    5152        unsigned toggle:1;
     53        fibril_mutex_t guard;
     54        fibril_condvar_t avail;
     55        volatile bool active;
    5256        link_t same_device_eps;
    5357} endpoint_t;
     
    5862
    5963void endpoint_destroy(endpoint_t *instance);
     64
     65void endpoint_use(endpoint_t *instance);
     66
     67void endpoint_release(endpoint_t *instance);
    6068
    6169int endpoint_toggle_get(endpoint_t *instance);
  • uspace/lib/usb/src/devpoll.c

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

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

    r3e490eb r8961c22  
    8080                d = usb_dp_get_sibling_descriptor(&parser, &parser_data,
    8181                    dev->descriptors.configuration, d);
     82                ++i;
    8283        }
    8384       
  • uspace/lib/usb/src/host/batch.c

    r3e490eb r8961c22  
    7979        instance->error = EOK;
    8080        instance->ep = ep;
     81        endpoint_use(instance->ep);
    8182}
    8283/*----------------------------------------------------------------------------*/
     
    8687 *
    8788 */
    88 void usb_transfer_batch_finish(usb_transfer_batch_t *instance, int error)
     89void usb_transfer_batch_finish(usb_transfer_batch_t *instance)
    8990{
    9091        assert(instance);
    91         instance->error = error;
     92        assert(instance->ep);
     93        endpoint_release(instance->ep);
    9294        instance->next_step(instance);
    9395}
  • uspace/lib/usb/src/host/device_keeper.c

    r3e490eb r8961c22  
    264264        return instance->devices[address].speed;
    265265}
    266 /*----------------------------------------------------------------------------*/
    267 void usb_device_keeper_use_control(
    268     usb_device_keeper_t *instance, usb_target_t target)
    269 {
    270         assert(instance);
    271         const uint16_t ep = 1 << target.endpoint;
    272         fibril_mutex_lock(&instance->guard);
    273         while (instance->devices[target.address].control_used & ep) {
    274                 fibril_condvar_wait(&instance->change, &instance->guard);
    275         }
    276         instance->devices[target.address].control_used |= ep;
    277         fibril_mutex_unlock(&instance->guard);
    278 }
    279 /*----------------------------------------------------------------------------*/
    280 void usb_device_keeper_release_control(
    281     usb_device_keeper_t *instance, usb_target_t target)
    282 {
    283         assert(instance);
    284         const uint16_t ep = 1 << target.endpoint;
    285         fibril_mutex_lock(&instance->guard);
    286         assert((instance->devices[target.address].control_used & ep) != 0);
    287         instance->devices[target.address].control_used &= ~ep;
    288         fibril_mutex_unlock(&instance->guard);
    289         fibril_condvar_signal(&instance->change);
    290 }
    291266/**
    292267 * @}
  • uspace/lib/usb/src/host/endpoint.c

    r3e490eb r8961c22  
    3434 */
    3535
     36#include <assert.h>
    3637#include <errno.h>
    3738#include <usb/host/endpoint.h>
     
    4950        instance->max_packet_size = max_packet_size;
    5051        instance->toggle = 0;
     52        instance->active = false;
     53        fibril_mutex_initialize(&instance->guard);
     54        fibril_condvar_initialize(&instance->avail);
    5155        link_initialize(&instance->same_device_eps);
    5256        return EOK;
     
    5660{
    5761        assert(instance);
     62        assert(!instance->active);
    5863        list_remove(&instance->same_device_eps);
    5964        free(instance);
     65}
     66/*----------------------------------------------------------------------------*/
     67void endpoint_use(endpoint_t *instance)
     68{
     69        assert(instance);
     70        fibril_mutex_lock(&instance->guard);
     71        while (instance->active)
     72                fibril_condvar_wait(&instance->avail, &instance->guard);
     73        instance->active = true;
     74        fibril_mutex_unlock(&instance->guard);
     75}
     76/*----------------------------------------------------------------------------*/
     77void endpoint_release(endpoint_t *instance)
     78{
     79        assert(instance);
     80        fibril_mutex_lock(&instance->guard);
     81        instance->active = false;
     82        fibril_mutex_unlock(&instance->guard);
     83        fibril_condvar_signal(&instance->avail);
    6084}
    6185/*----------------------------------------------------------------------------*/
  • uspace/lib/usb/src/hub.c

    r3e490eb r8961c22  
    178178 * error codes than those listed as return codes by this function itself).
    179179 *
     180 * The @p connection representing connection with host controller does not
     181 * need to be started.
     182 * This function duplicates the connection to allow simultaneous calls of
     183 * this function (i.e. from different fibrils).
     184 *
    180185 * @param[in] parent Parent device (i.e. the hub device).
    181  * @param[in] connection Opened connection to host controller.
     186 * @param[in] connection Connection to host controller.
    182187 * @param[in] dev_speed New device speed.
    183188 * @param[in] enable_port Function for enabling signaling through the port the
     
    206211    ddf_dev_ops_t *dev_ops, void *new_dev_data, ddf_fun_t **new_fun)
    207212{
    208         CHECK_CONNECTION(connection);
     213        assert(connection != NULL);
     214        // FIXME: this is awful, we are accessing directly the structure.
     215        usb_hc_connection_t hc_conn = {
     216                .hc_handle = connection->hc_handle,
     217                .hc_phone = -1
     218        };
     219
     220        int rc;
     221
     222        rc = usb_hc_connection_open(&hc_conn);
     223        if (rc != EOK) {
     224                return rc;
     225        }
     226
    209227
    210228        /*
    211229         * Request new address.
    212230         */
    213         usb_address_t dev_addr = usb_hc_request_address(connection, dev_speed);
     231        usb_address_t dev_addr = usb_hc_request_address(&hc_conn, dev_speed);
    214232        if (dev_addr < 0) {
     233                usb_hc_connection_close(&hc_conn);
    215234                return EADDRNOTAVAIL;
    216235        }
    217236
    218         int rc;
    219237
    220238        /*
    221239         * Reserve the default address.
    222240         */
    223         rc = usb_hc_reserve_default_address(connection, dev_speed);
     241        rc = usb_hc_reserve_default_address(&hc_conn, dev_speed);
    224242        if (rc != EOK) {
    225243                rc = EBUSY;
     
    241259        usb_device_connection_t dev_conn;
    242260        rc = usb_device_connection_initialize_on_default_address(&dev_conn,
    243             connection);
     261            &hc_conn);
    244262        if (rc != EOK) {
    245263                rc = ENOTCONN;
     
    258276         * endpoint.
    259277         */
    260         rc = usb_pipe_register(&ctrl_pipe, 0, connection);
     278        rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
    261279        if (rc != EOK) {
    262280                rc = EREFUSED;
     
    286304         * Register the control endpoint for the new device.
    287305         */
    288         rc = usb_pipe_register(&ctrl_pipe, 0, connection);
     306        rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
    289307        if (rc != EOK) {
    290308                rc = EREFUSED;
     
    295313         * Release the original endpoint.
    296314         */
    297         unregister_control_endpoint_on_default_address(connection);
     315        unregister_control_endpoint_on_default_address(&hc_conn);
    298316
    299317        /*
    300318         * Once the address is changed, we can return the default address.
    301319         */
    302         usb_hc_release_default_address(connection);
     320        usb_hc_release_default_address(&hc_conn);
    303321
    304322
     
    325343                .handle = child_handle
    326344        };
    327         rc = usb_hc_register_device(connection, &new_device);
     345        rc = usb_hc_register_device(&hc_conn, &new_device);
    328346        if (rc != EOK) {
    329347                rc = EDESTADDRREQ;
     
    354372
    355373leave_unregister_endpoint:
    356         usb_pipe_unregister(&ctrl_pipe, connection);
     374        usb_pipe_unregister(&ctrl_pipe, &hc_conn);
    357375
    358376leave_release_default_address:
    359         usb_hc_release_default_address(connection);
     377        usb_hc_release_default_address(&hc_conn);
    360378
    361379leave_release_free_address:
    362         usb_hc_unregister_device(connection, dev_addr);
     380        usb_hc_unregister_device(&hc_conn, dev_addr);
     381
     382        usb_hc_connection_close(&hc_conn);
    363383
    364384        return rc;
Note: See TracChangeset for help on using the changeset viewer.