Changeset 20a3465 in mainline for uspace/lib


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/lib
Files:
24 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/str.c

    r4c3ad56 r20a3465  
    839839       
    840840        return NULL;
     841}
     842
     843/** Removes specified trailing characters from a string.
     844 *
     845 * @param str String to remove from.
     846 * @param ch  Character to remove.
     847 */
     848void str_rtrim(char *str, wchar_t ch)
     849{
     850        size_t off = 0;
     851        size_t pos = 0;
     852        wchar_t c;
     853        bool update_last_chunk = true;
     854        char *last_chunk = NULL;
     855
     856        while ((c = str_decode(str, &off, STR_NO_LIMIT))) {
     857                if (c != ch) {
     858                        update_last_chunk = true;
     859                        last_chunk = NULL;
     860                } else if (update_last_chunk) {
     861                        update_last_chunk = false;
     862                        last_chunk = (str + pos);
     863                }
     864                pos = off;
     865        }
     866
     867        if (last_chunk)
     868                *last_chunk = '\0';
     869}
     870
     871/** Removes specified leading characters from a string.
     872 *
     873 * @param str String to remove from.
     874 * @param ch  Character to remove.
     875 */
     876void str_ltrim(char *str, wchar_t ch)
     877{
     878        wchar_t acc;
     879        size_t off = 0;
     880        size_t pos = 0;
     881        size_t str_sz = str_size(str);
     882
     883        while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
     884                if (acc != ch)
     885                        break;
     886                else
     887                        pos = off;
     888        }
     889
     890        if (pos > 0) {
     891                memmove(str, &str[pos], str_sz - pos);
     892                pos = str_sz - pos;
     893                str[str_sz - pos] = '\0';
     894        }
    841895}
    842896
  • uspace/lib/c/include/str.h

    r4c3ad56 r20a3465  
    9191extern char *str_rchr(const char *str, wchar_t ch);
    9292
     93extern void str_rtrim(char *str, wchar_t ch);
     94extern void str_ltrim(char *str, wchar_t ch);
     95
    9396extern bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos);
    9497extern bool wstr_remove(wchar_t *str, size_t pos);
  • uspace/lib/usbdev/include/usb/dev/dp.h

    r4c3ad56 r20a3465  
    5959typedef struct {
    6060        /** Used descriptor nesting. */
    61         usb_dp_descriptor_nesting_t *nesting;
     61        const usb_dp_descriptor_nesting_t *nesting;
    6262} usb_dp_parser_t;
    6363
     
    6565typedef struct {
    6666        /** Data to be parsed. */
    67         uint8_t *data;
     67        const uint8_t *data;
    6868        /** Size of input data in bytes. */
    6969        size_t size;
     
    7272} usb_dp_parser_data_t;
    7373
    74 uint8_t *usb_dp_get_nested_descriptor(usb_dp_parser_t *,
    75     usb_dp_parser_data_t *, uint8_t *);
    76 uint8_t *usb_dp_get_sibling_descriptor(usb_dp_parser_t *,
    77     usb_dp_parser_data_t *, uint8_t *, uint8_t *);
     74typedef void (*walk_callback_t)(const uint8_t *, size_t, void *);
    7875
    79 void usb_dp_walk_simple(uint8_t *, size_t, usb_dp_descriptor_nesting_t *,
    80     void (*)(uint8_t *, size_t, void *), void *);
     76const uint8_t *usb_dp_get_nested_descriptor(const usb_dp_parser_t *,
     77    const usb_dp_parser_data_t *, const uint8_t *);
     78const uint8_t *usb_dp_get_sibling_descriptor(const usb_dp_parser_t *,
     79    const usb_dp_parser_data_t *, const uint8_t *, const uint8_t *);
     80
     81void usb_dp_walk_simple(uint8_t *, size_t, const usb_dp_descriptor_nesting_t *,
     82    walk_callback_t, void *);
    8183
    8284#endif
  • uspace/lib/usbdev/include/usb/dev/driver.h

    r4c3ad56 r20a3465  
    4343        usb_standard_device_descriptor_t device;
    4444        /** Full configuration descriptor of current configuration. */
    45         uint8_t *configuration;
     45        const uint8_t *configuration;
    4646        size_t configuration_size;
    4747} usb_device_descriptors_t;
     
    5353typedef struct {
    5454        /** Interface descriptor. */
    55         usb_standard_interface_descriptor_t *interface;
     55        const usb_standard_interface_descriptor_t *interface;
    5656        /** Pointer to start of descriptor tree bound with this interface. */
    57         uint8_t *nested_descriptors;
     57        const uint8_t *nested_descriptors;
    5858        /** Size of data pointed by nested_descriptors in bytes. */
    5959        size_t nested_descriptors_size;
     
    156156\endcode
    157157         */
    158         usb_endpoint_description_t **endpoints;
     158        const usb_endpoint_description_t **endpoints;
    159159        /** Driver ops. */
    160         usb_driver_ops_t *ops;
     160        const usb_driver_ops_t *ops;
    161161} usb_driver_t;
    162162
    163 int usb_driver_main(usb_driver_t *);
     163int usb_driver_main(const usb_driver_t *);
    164164
    165165int usb_device_select_interface(usb_device_t *, uint8_t,
    166     usb_endpoint_description_t **);
     166    const usb_endpoint_description_t **);
    167167
    168168int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *);
    169169int usb_device_create_pipes(const ddf_dev_t *, usb_device_connection_t *,
    170     usb_endpoint_description_t **, uint8_t *, size_t, int, int,
     170    const usb_endpoint_description_t **, const uint8_t *, size_t, int, int,
    171171    usb_endpoint_mapping_t **, size_t *);
    172172int usb_device_destroy_pipes(const ddf_dev_t *, usb_endpoint_mapping_t *, size_t);
    173 int usb_device_create(ddf_dev_t *, usb_endpoint_description_t **, usb_device_t **, const char **);
    174 void usb_device_destroy(usb_device_t *);
     173int usb_device_init(usb_device_t *, ddf_dev_t *,
     174    const usb_endpoint_description_t **, const char **);
     175void usb_device_deinit(usb_device_t *);
    175176
    176 size_t usb_interface_count_alternates(uint8_t *, size_t, uint8_t);
    177 int usb_alternate_interfaces_create(uint8_t *, size_t, int,
     177void * usb_device_data_alloc(usb_device_t *, size_t);
     178
     179size_t usb_interface_count_alternates(const uint8_t *, size_t, uint8_t);
     180int usb_alternate_interfaces_create(const uint8_t *, size_t, int,
    178181    usb_alternate_interfaces_t **);
    179 
     182void usb_alternate_interfaces_destroy(usb_alternate_interfaces_t *);
    180183#endif
    181184/**
  • uspace/lib/usbdev/include/usb/dev/pipes.h

    r4c3ad56 r20a3465  
    171171int usb_pipe_probe_default_control(usb_pipe_t *);
    172172int usb_pipe_initialize_from_configuration(usb_endpoint_mapping_t *,
    173     size_t, uint8_t *, size_t, usb_device_connection_t *);
     173    size_t, const uint8_t *, size_t, usb_device_connection_t *);
    174174int usb_pipe_register_with_speed(usb_pipe_t *, usb_speed_t,
    175175    unsigned int, usb_hc_connection_t *);
  • uspace/lib/usbdev/src/altiface.c

    r4c3ad56 r20a3465  
    4848 * @return Number of alternate interfaces for @p interface_no interface.
    4949 */
    50 size_t usb_interface_count_alternates(uint8_t *config_descr,
     50size_t usb_interface_count_alternates(const uint8_t *config_descr,
    5151    size_t config_descr_size, uint8_t interface_no)
    5252{
     
    5454        assert(config_descr_size > 0);
    5555
    56         usb_dp_parser_t dp_parser = {
     56        const usb_dp_parser_t dp_parser = {
    5757                .nesting = usb_dp_standard_descriptor_nesting
    5858        };
    59         usb_dp_parser_data_t dp_data = {
     59        const usb_dp_parser_data_t dp_data = {
    6060                .data = config_descr,
    6161                .size = config_descr_size,
     
    6565        size_t alternate_count = 0;
    6666
    67         uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser,
     67        const uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser,
    6868            &dp_data, config_descr);
    6969        while (iface_ptr != NULL) {
     
    9090 * @return Error code.
    9191 */
    92 int usb_alternate_interfaces_create(uint8_t *config_descr,
     92int usb_alternate_interfaces_create(const uint8_t *config_descr,
    9393    size_t config_descr_size, int interface_number,
    9494    usb_alternate_interfaces_t **alternates_ptr)
     
    9898        assert(config_descr_size > 0);
    9999
     100        *alternates_ptr = NULL;
    100101        if (interface_number < 0) {
    101                 alternates_ptr = NULL;
    102102                return EOK;
    103103        }
     
    105105        usb_alternate_interfaces_t *alternates
    106106            = malloc(sizeof(usb_alternate_interfaces_t));
    107 
    108107        if (alternates == NULL) {
    109108                return ENOMEM;
     
    119118        }
    120119
    121         alternates->alternatives = malloc(alternates->alternative_count
    122             * sizeof(usb_alternate_interface_descriptors_t));
     120        alternates->alternatives = calloc(alternates->alternative_count,
     121            sizeof(usb_alternate_interface_descriptors_t));
    123122        if (alternates->alternatives == NULL) {
    124123                free(alternates);
     
    140139            = &alternates->alternatives[0];
    141140
    142         uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser,
     141        const uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser,
    143142            &dp_data, dp_data.data);
    144143        while (iface_ptr != NULL) {
     
    160159                    dp_data.data, iface_ptr);
    161160                if (iface_ptr == NULL) {
    162                         uint8_t *next = dp_data.data + dp_data.size;
     161                        const uint8_t *next = dp_data.data + dp_data.size;
    163162                        cur_alt_iface->nested_descriptors_size
    164163                            = next - cur_alt_iface->nested_descriptors;
     
    176175}
    177176
    178 
     177void usb_alternate_interfaces_destroy(usb_alternate_interfaces_t *alternate)
     178{
     179        if (!alternate)
     180                return;
     181        free(alternate->alternatives);
     182        free(alternate);
     183}
    179184/**
    180185 * @}
  • uspace/lib/usbdev/src/devdrv.c

    r4c3ad56 r20a3465  
    5454};
    5555
    56 static usb_driver_t *driver = NULL;
     56static const usb_driver_t *driver = NULL;
    5757
    5858
     
    6464 * @return Task exit status.
    6565 */
    66 int usb_driver_main(usb_driver_t *drv)
     66int usb_driver_main(const usb_driver_t *drv)
    6767{
    6868        assert(drv != NULL);
     
    8181 * @return Number of pipes (excluding default control pipe).
    8282 */
    83 static size_t count_other_pipes(usb_endpoint_description_t **endpoints)
     83static size_t count_other_pipes(const usb_endpoint_description_t **endpoints)
    8484{
    8585        size_t count = 0;
     
    101101 * @return Error code.
    102102 */
    103 static int initialize_other_pipes(usb_endpoint_description_t **endpoints,
     103static int initialize_other_pipes(const usb_endpoint_description_t **endpoints,
    104104    usb_device_t *dev, int alternate_setting)
    105105{
     
    115115        int rc = usb_device_create_pipes(dev->ddf_dev, &dev->wire, endpoints,
    116116            dev->descriptors.configuration, dev->descriptors.configuration_size,
    117             dev->interface_no, alternate_setting,
    118             &pipes, &pipes_count);
     117            dev->interface_no, alternate_setting, &pipes, &pipes_count);
    119118
    120119        if (rc != EOK) {
     
    141140        assert(driver->ops->device_add);
    142141
    143         int rc;
    144 
    145         usb_device_t *dev = NULL;
     142        usb_device_t *dev = ddf_dev_data_alloc(gen_dev, sizeof(usb_device_t));
     143        if (dev == NULL) {
     144                usb_log_error("USB device `%s' structure allocation failed.\n",
     145                    gen_dev->name);
     146                return ENOMEM;
     147        }
    146148        const char *err_msg = NULL;
    147         rc = usb_device_create(gen_dev, driver->endpoints, &dev, &err_msg);
    148         if (rc != EOK) {
    149                 usb_log_error("USB device `%s' creation failed (%s): %s.\n",
     149        int rc = usb_device_init(dev, gen_dev, driver->endpoints, &err_msg);
     150        if (rc != EOK) {
     151                usb_log_error("USB device `%s' init failed (%s): %s.\n",
    150152                    gen_dev->name, err_msg, str_error(rc));
    151153                return rc;
    152154        }
    153         gen_dev->driver_data = dev;
    154 
    155         return driver->ops->device_add(dev);
     155
     156        rc = driver->ops->device_add(dev);
     157        if (rc != EOK)
     158                usb_device_deinit(dev);
     159        return rc;
    156160}
    157161/*----------------------------------------------------------------------------*/
     
    186190        if (driver->ops->device_gone == NULL)
    187191                return ENOTSUP;
    188         const int ret = driver->ops->device_gone(gen_dev->driver_data);
     192        usb_device_t *usb_dev = gen_dev->driver_data;
     193        const int ret = driver->ops->device_gone(usb_dev);
    189194        if (ret == EOK)
    190                 usb_device_destroy(gen_dev->driver_data);
     195                usb_device_deinit(usb_dev);
    191196
    192197        return ret;
     
    235240 */
    236241int usb_device_select_interface(usb_device_t *dev, uint8_t alternate_setting,
    237     usb_endpoint_description_t **endpoints)
     242    const usb_endpoint_description_t **endpoints)
    238243{
    239244        if (dev->interface_no < 0) {
     
    318323 */
    319324int usb_device_create_pipes(const ddf_dev_t *dev, usb_device_connection_t *wire,
    320     usb_endpoint_description_t **endpoints,
    321     uint8_t *config_descr, size_t config_descr_size,
     325    const usb_endpoint_description_t **endpoints,
     326    const uint8_t *config_descr, size_t config_descr_size,
    322327    int interface_no, int interface_setting,
    323328    usb_endpoint_mapping_t **pipes_ptr, size_t *pipes_count_ptr)
     
    333338        int rc;
    334339
    335         size_t pipe_count = count_other_pipes(endpoints);
     340        const size_t pipe_count = count_other_pipes(endpoints);
    336341        if (pipe_count == 0) {
     342                *pipes_count_ptr = pipe_count;
    337343                *pipes_ptr = NULL;
    338344                return EOK;
     
    445451{
    446452        assert(dev != NULL);
    447         assert(((pipes != NULL) && (pipes_count > 0))
    448             || ((pipes == NULL) && (pipes_count == 0)));
    449453
    450454        if (pipes_count == 0) {
     455                assert(pipes == NULL);
    451456                return EOK;
    452457        }
     458        assert(pipes != NULL);
    453459
    454460        int rc;
     
    468474        size_t i;
    469475        for (i = 0; i < pipes_count; i++) {
    470                 usb_pipe_unregister(pipes[i].pipe, &hc_conn);
     476                usb_log_debug2("Unregistering pipe %zu (%spresent).\n",
     477                    i, pipes[i].present ? "" : "not ");
     478                if (pipes[i].present)
     479                        usb_pipe_unregister(pipes[i].pipe, &hc_conn);
    471480                free(pipes[i].pipe);
    472481        }
     
    509518
    510519
    511 /** Create new instance of USB device.
    512  *
     520/** Initialize new instance of USB device.
     521 *
     522 * @param[in] usb_dev Pointer to the new device.
    513523 * @param[in] ddf_dev Generic DDF device backing the USB one.
    514524 * @param[in] endpoints NULL terminated array of endpoints (NULL for none).
    515  * @param[out] dev_ptr Where to store pointer to the new device.
    516525 * @param[out] errstr_ptr Where to store description of context
    517526 *      (in case error occurs).
    518527 * @return Error code.
    519528 */
    520 int usb_device_create(ddf_dev_t *ddf_dev,
    521     usb_endpoint_description_t **endpoints,
    522     usb_device_t **dev_ptr, const char **errstr_ptr)
    523 {
    524         assert(dev_ptr != NULL);
     529int usb_device_init(usb_device_t *usb_dev, ddf_dev_t *ddf_dev,
     530    const usb_endpoint_description_t **endpoints, const char **errstr_ptr)
     531{
     532        assert(usb_dev != NULL);
    525533        assert(ddf_dev != NULL);
    526534
    527         int rc;
    528 
    529         usb_device_t *dev = malloc(sizeof(usb_device_t));
    530         if (dev == NULL) {
    531                 *errstr_ptr = "structure allocation";
    532                 return ENOMEM;
    533         }
    534 
    535         // FIXME: proper deallocation in case of errors
    536 
    537         dev->ddf_dev = ddf_dev;
    538         dev->driver_data = NULL;
    539         dev->descriptors.configuration = NULL;
    540         dev->alternate_interfaces = NULL;
    541 
    542         dev->pipes_count = 0;
    543         dev->pipes = NULL;
     535        usb_dev->ddf_dev = ddf_dev;
     536        usb_dev->driver_data = NULL;
     537        usb_dev->descriptors.configuration = NULL;
     538        usb_dev->alternate_interfaces = NULL;
     539        usb_dev->pipes_count = 0;
     540        usb_dev->pipes = NULL;
    544541
    545542        /* Initialize backing wire and control pipe. */
    546         rc = init_wire_and_ctrl_pipe(dev, errstr_ptr);
     543        int rc = init_wire_and_ctrl_pipe(usb_dev, errstr_ptr);
    547544        if (rc != EOK) {
    548545                return rc;
     
    550547
    551548        /* Get our interface. */
    552         dev->interface_no = usb_device_get_assigned_interface(dev->ddf_dev);
     549        usb_dev->interface_no = usb_device_get_assigned_interface(ddf_dev);
    553550
    554551        /* Retrieve standard descriptors. */
    555         rc = usb_device_retrieve_descriptors(&dev->ctrl_pipe,
    556             &dev->descriptors);
    557         if (rc != EOK) {
     552        rc = usb_device_retrieve_descriptors(&usb_dev->ctrl_pipe,
     553            &usb_dev->descriptors);
     554        if (rc != EOK) {
     555                /* Nothing allocated, nothing to free. */
    558556                *errstr_ptr = "descriptor retrieval";
    559557                return rc;
    560558        }
    561559
    562         /* Create alternate interfaces. */
    563         rc = usb_alternate_interfaces_create(dev->descriptors.configuration,
    564             dev->descriptors.configuration_size, dev->interface_no,
    565             &dev->alternate_interfaces);
    566         if (rc != EOK) {
    567                 /* We will try to silently ignore this. */
    568                 dev->alternate_interfaces = NULL;
    569         }
    570 
    571         rc = initialize_other_pipes(endpoints, dev, 0);
    572         if (rc != EOK) {
     560        /* Create alternate interfaces. We will silently ignore failure. */
     561        //TODO Why ignore?
     562        usb_alternate_interfaces_create(usb_dev->descriptors.configuration,
     563            usb_dev->descriptors.configuration_size, usb_dev->interface_no,
     564            &usb_dev->alternate_interfaces);
     565
     566        rc = initialize_other_pipes(endpoints, usb_dev, 0);
     567        if (rc != EOK) {
     568                /* Full configuration descriptor is allocated. */
     569                free(usb_dev->descriptors.configuration);
     570                /* Alternate interfaces may be allocated */
     571                usb_alternate_interfaces_destroy(usb_dev->alternate_interfaces);
    573572                *errstr_ptr = "pipes initialization";
    574573                return rc;
     
    576575
    577576        *errstr_ptr = NULL;
    578         *dev_ptr = dev;
    579577
    580578        return EOK;
    581579}
    582580
    583 /** Destroy instance of a USB device.
    584  *
    585  * @param dev Device to be destroyed.
    586  */
    587 void usb_device_destroy(usb_device_t *dev)
    588 {
    589         if (dev == NULL) {
    590                 return;
    591         }
    592 
    593         /* Ignore errors and hope for the best. */
    594         usb_device_destroy_pipes(dev->ddf_dev, dev->pipes, dev->pipes_count);
    595         free(dev->descriptors.configuration);
    596 
    597         if (dev->alternate_interfaces != NULL) {
    598                 free(dev->alternate_interfaces->alternatives);
    599         }
    600         free(dev->alternate_interfaces);
    601 
    602         free(dev);
     581/** Clean instance of a USB device.
     582 *
     583 * @param dev Device to be de-initialized.
     584 *
     585 * Does not free/destroy supplied pointer.
     586 */
     587void usb_device_deinit(usb_device_t *dev)
     588{
     589        if (dev) {
     590                /* Ignore errors and hope for the best. */
     591                destroy_current_pipes(dev);
     592
     593                usb_alternate_interfaces_destroy(dev->alternate_interfaces);
     594                free(dev->descriptors.configuration);
     595                free(dev->driver_data);
     596        }
     597}
     598
     599void * usb_device_data_alloc(usb_device_t *usb_dev, size_t size)
     600{
     601        assert(usb_dev);
     602        assert(usb_dev->driver_data == NULL);
     603        return usb_dev->driver_data = calloc(1, size);
     604
    603605}
    604606
  • uspace/lib/usbdev/src/dp.c

    r4c3ad56 r20a3465  
    7575 * @return Whether @p ptr points inside <code>data->data</code> field.
    7676 */
    77 static bool is_valid_descriptor_pointer(usb_dp_parser_data_t *data,
    78     uint8_t *ptr)
     77static bool is_valid_descriptor_pointer(const usb_dp_parser_data_t *data,
     78    const uint8_t *ptr)
    7979{
    8080        if (ptr == NULL) {
     
    100100 * @retval NULL Invalid input or no next descriptor.
    101101 */
    102 static uint8_t *get_next_descriptor(usb_dp_parser_data_t *data,
    103     uint8_t *current)
     102static const uint8_t *get_next_descriptor(const usb_dp_parser_data_t *data,
     103    const uint8_t *current)
    104104{
    105105        assert(is_valid_descriptor_pointer(data, current));
    106106
    107         uint8_t current_length = *current;
    108         uint8_t *next = current + current_length;
     107        const uint8_t current_length = *current;
     108        const uint8_t *next = current + current_length;
    109109
    110110        if (!is_valid_descriptor_pointer(data, next)) {
     
    124124 * @retval -1 Invalid input.
    125125 */
    126 static int get_descriptor_type(usb_dp_parser_data_t *data, uint8_t *start)
     126static int get_descriptor_type(const usb_dp_parser_data_t *data, const uint8_t *start)
    127127{
    128128        if (start == NULL) {
     
    145145 * @return Whether @p child could be child of @p parent.
    146146 */
    147 static bool is_nested_descriptor_type(usb_dp_parser_t *parser,
     147static bool is_nested_descriptor_type(const usb_dp_parser_t *parser,
    148148    int child, int parent)
    149149{
    150         usb_dp_descriptor_nesting_t *nesting = parser->nesting;
     150        const usb_dp_descriptor_nesting_t *nesting = parser->nesting;
    151151        while ((nesting->child > 0) && (nesting->parent > 0)) {
    152152                if ((nesting->child == child) && (nesting->parent == parent)) {
     
    166166 * @return Whether @p child could be child of @p parent.
    167167 */
    168 static bool is_nested_descriptor(usb_dp_parser_t *parser,
    169     usb_dp_parser_data_t *data, uint8_t *child, uint8_t *parent)
     168static bool is_nested_descriptor(const usb_dp_parser_t *parser,
     169    const usb_dp_parser_data_t *data, const uint8_t *child, const uint8_t *parent)
    170170{
    171171        return is_nested_descriptor_type(parser,
     
    183183 * @retval NULL Invalid input.
    184184 */
    185 uint8_t *usb_dp_get_nested_descriptor(usb_dp_parser_t *parser,
    186     usb_dp_parser_data_t *data, uint8_t *parent)
     185const uint8_t *usb_dp_get_nested_descriptor(const usb_dp_parser_t *parser,
     186    const usb_dp_parser_data_t *data, const uint8_t *parent)
    187187{
    188188        if (!is_valid_descriptor_pointer(data, parent)) {
     
    190190        }
    191191
    192         uint8_t *next = get_next_descriptor(data, parent);
     192        const uint8_t *next = get_next_descriptor(data, parent);
    193193        if (next == NULL) {
    194194                return NULL;
     
    211211 * @retval NULL Invalid input.
    212212 */
    213 static uint8_t *skip_nested_descriptors(usb_dp_parser_t *parser,
    214     usb_dp_parser_data_t *data, uint8_t *parent)
    215 {
    216         uint8_t *child = usb_dp_get_nested_descriptor(parser, data, parent);
     213static const uint8_t *skip_nested_descriptors(const usb_dp_parser_t *parser,
     214    const usb_dp_parser_data_t *data, const uint8_t *parent)
     215{
     216        const uint8_t *child =
     217            usb_dp_get_nested_descriptor(parser, data, parent);
    217218        if (child == NULL) {
    218219                return get_next_descriptor(data, parent);
    219220        }
    220         uint8_t *next_child = skip_nested_descriptors(parser, data, child);
     221        const uint8_t *next_child =
     222            skip_nested_descriptors(parser, data, child);
    221223        while (is_nested_descriptor(parser, data, next_child, parent)) {
    222224                next_child = skip_nested_descriptors(parser, data, next_child);
     
    236238 * @retval NULL Invalid input.
    237239 */
    238 uint8_t *usb_dp_get_sibling_descriptor(usb_dp_parser_t *parser,
    239     usb_dp_parser_data_t *data, uint8_t *parent, uint8_t *sibling)
     240const uint8_t *usb_dp_get_sibling_descriptor(
     241    const usb_dp_parser_t *parser, const usb_dp_parser_data_t *data,
     242    const uint8_t *parent, const uint8_t *sibling)
    240243{
    241244        if (!is_valid_descriptor_pointer(data, parent)
     
    244247        }
    245248
    246         uint8_t *possible_sibling = skip_nested_descriptors(parser, data, sibling);
     249        const uint8_t *possible_sibling =
     250            skip_nested_descriptors(parser, data, sibling);
    247251        if (possible_sibling == NULL) {
    248252                return NULL;
     
    269273 * @param arg Custom (user) argument.
    270274 */
    271 static void usb_dp_browse_simple_internal(usb_dp_parser_t *parser,
    272     usb_dp_parser_data_t *data, uint8_t *root, size_t depth,
    273     void (*callback)(uint8_t *, size_t, void *), void *arg)
     275static void usb_dp_browse_simple_internal(const usb_dp_parser_t *parser,
     276    const usb_dp_parser_data_t *data, const uint8_t *root, size_t depth,
     277    void (*callback)(const uint8_t *, size_t, void *), void *arg)
    274278{
    275279        if (root == NULL) {
     
    277281        }
    278282        callback(root, depth, arg);
    279         uint8_t *child = usb_dp_get_nested_descriptor(parser, data, root);
     283        const uint8_t *child = usb_dp_get_nested_descriptor(parser, data, root);
    280284        do {
    281285                usb_dp_browse_simple_internal(parser, data, child, depth + 1,
     
    301305 */
    302306void usb_dp_walk_simple(uint8_t *descriptors, size_t descriptors_size,
    303     usb_dp_descriptor_nesting_t *descriptor_nesting,
    304     void (*callback)(uint8_t *, size_t, void *), void *arg)
     307    const usb_dp_descriptor_nesting_t *descriptor_nesting,
     308    walk_callback_t callback, void *arg)
    305309{
    306310        if ((descriptors == NULL) || (descriptors_size == 0)
     
    309313        }
    310314
    311         usb_dp_parser_data_t data = {
     315        const usb_dp_parser_data_t data = {
    312316                .data = descriptors,
    313317                .size = descriptors_size,
     
    315319        };
    316320
    317         usb_dp_parser_t parser = {
     321        const usb_dp_parser_t parser = {
    318322                .nesting = descriptor_nesting
    319323        };
  • uspace/lib/usbdev/src/pipesinit.c

    r4c3ad56 r20a3465  
    6868 * @return Whether the given descriptor is endpoint descriptor.
    6969 */
    70 static inline bool is_endpoint_descriptor(uint8_t *descriptor)
     70static inline bool is_endpoint_descriptor(const uint8_t *descriptor)
    7171{
    7272        return descriptor[1] == USB_DESCTYPE_ENDPOINT;
     
    8080 */
    8181static bool endpoint_fits_description(const usb_endpoint_description_t *wanted,
    82     usb_endpoint_description_t *found)
     82    const usb_endpoint_description_t *found)
    8383{
    8484#define _SAME(fieldname) ((wanted->fieldname) == (found->fieldname))
     
    120120static usb_endpoint_mapping_t *find_endpoint_mapping(
    121121    usb_endpoint_mapping_t *mapping, size_t mapping_count,
    122     usb_endpoint_description_t *found_endpoint,
     122    const usb_endpoint_description_t *found_endpoint,
    123123    int interface_number, int interface_setting)
    124124{
     
    160160    usb_device_connection_t *wire)
    161161{
    162         usb_endpoint_description_t description;
    163162
    164163        /*
     
    167166
    168167        /* Actual endpoint number is in bits 0..3 */
    169         usb_endpoint_t ep_no = endpoint->endpoint_address & 0x0F;
    170 
    171         /* Endpoint direction is set by bit 7 */
    172         description.direction = (endpoint->endpoint_address & 128)
    173             ? USB_DIRECTION_IN : USB_DIRECTION_OUT;
    174         /* Transfer type is in bits 0..2 and the enum values corresponds 1:1 */
    175         description.transfer_type = endpoint->attributes & 3;
    176 
    177         /*
    178          * Get interface characteristics.
    179          */
    180         description.interface_class = interface->interface_class;
    181         description.interface_subclass = interface->interface_subclass;
    182         description.interface_protocol = interface->interface_protocol;
     168        const usb_endpoint_t ep_no = endpoint->endpoint_address & 0x0F;
     169
     170        const usb_endpoint_description_t description = {
     171                /* Endpoint direction is set by bit 7 */
     172                .direction = (endpoint->endpoint_address & 128)
     173                    ? USB_DIRECTION_IN : USB_DIRECTION_OUT,
     174                /* Transfer type is in bits 0..2 and
     175                 * the enum values corresponds 1:1 */
     176                .transfer_type = endpoint->attributes & 3,
     177
     178                /* Get interface characteristics. */
     179                .interface_class = interface->interface_class,
     180                .interface_subclass = interface->interface_subclass,
     181                .interface_protocol = interface->interface_protocol,
     182        };
    183183
    184184        /*
     
    224224static int process_interface(
    225225    usb_endpoint_mapping_t *mapping, size_t mapping_count,
    226     usb_dp_parser_t *parser, usb_dp_parser_data_t *parser_data,
    227     uint8_t *interface_descriptor)
    228 {
    229         uint8_t *descriptor = usb_dp_get_nested_descriptor(parser,
     226    const usb_dp_parser_t *parser, const usb_dp_parser_data_t *parser_data,
     227    const uint8_t *interface_descriptor)
     228{
     229        const uint8_t *descriptor = usb_dp_get_nested_descriptor(parser,
    230230            parser_data, interface_descriptor);
    231231
     
    284284int usb_pipe_initialize_from_configuration(
    285285    usb_endpoint_mapping_t *mapping, size_t mapping_count,
    286     uint8_t *configuration_descriptor, size_t configuration_descriptor_size,
     286    const uint8_t *config_descriptor, size_t config_descriptor_size,
    287287    usb_device_connection_t *connection)
    288288{
    289289        assert(connection);
    290290
    291         if (configuration_descriptor == NULL) {
     291        if (config_descriptor == NULL) {
    292292                return EBADMEM;
    293293        }
    294         if (configuration_descriptor_size
     294        if (config_descriptor_size
    295295            < sizeof(usb_standard_configuration_descriptor_t)) {
    296296                return ERANGE;
     
    310310         * Prepare the descriptor parser.
    311311         */
    312         usb_dp_parser_t dp_parser = {
     312        const usb_dp_parser_t dp_parser = {
    313313                .nesting = descriptor_nesting
    314314        };
    315         usb_dp_parser_data_t dp_data = {
    316                 .data = configuration_descriptor,
    317                 .size = configuration_descriptor_size,
     315        const usb_dp_parser_data_t dp_data = {
     316                .data = config_descriptor,
     317                .size = config_descriptor_size,
    318318                .arg = connection
    319319        };
     
    322322         * Iterate through all interfaces.
    323323         */
    324         uint8_t *interface = usb_dp_get_nested_descriptor(&dp_parser,
    325             &dp_data, configuration_descriptor);
     324        const uint8_t *interface = usb_dp_get_nested_descriptor(&dp_parser,
     325            &dp_data, config_descriptor);
    326326        if (interface == NULL) {
    327327                return ENOENT;
     
    329329        do {
    330330                (void) process_interface(mapping, mapping_count,
    331                     &dp_parser, &dp_data,
    332                     interface);
     331                    &dp_parser, &dp_data, interface);
    333332                interface = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data,
    334                     configuration_descriptor, interface);
     333                    config_descriptor, interface);
    335334        } while (interface != NULL);
    336335
     
    514513{
    515514        assert(pipe);
     515        assert(pipe->wire);
    516516        assert(hc_connection);
    517517       
  • uspace/lib/usbdev/src/request.c

    r4c3ad56 r20a3465  
    425425
    426426        /* Everything is okay, copy the descriptor. */
    427         memcpy(descriptor, &descriptor_tmp,
    428             sizeof(descriptor_tmp));
     427        memcpy(descriptor, &descriptor_tmp, sizeof(descriptor_tmp));
    429428
    430429        return EOK;
     
    470469
    471470        /* Everything is okay, copy the descriptor. */
    472         memcpy(descriptor, &descriptor_tmp,
    473             sizeof(descriptor_tmp));
     471        memcpy(descriptor, &descriptor_tmp, sizeof(descriptor_tmp));
    474472
    475473        return EOK;
  • uspace/lib/usbhid/include/usb/hid/hiddescriptor.h

    r4c3ad56 r20a3465  
    4242#include <usb/hid/hidtypes.h>
    4343
    44 int usb_hid_parse_report_descriptor(usb_hid_report_t *report, 
     44int usb_hid_parse_report_descriptor(usb_hid_report_t *report,
    4545                const uint8_t *data, size_t size);
    46 
    47 void usb_hid_free_report(usb_hid_report_t *report);
    4846
    4947void usb_hid_descriptor_print(usb_hid_report_t *report);
    5048
    5149int usb_hid_report_init(usb_hid_report_t *report);
     50
     51void usb_hid_report_deinit(usb_hid_report_t *report);
    5252
    5353int usb_hid_report_append_fields(usb_hid_report_t *report,
     
    7878void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item);
    7979
    80 void usb_hid_free_report_list(list_t *list);
    81 
    8280usb_hid_report_item_t *usb_hid_report_item_clone(
    8381                const usb_hid_report_item_t *item);
  • uspace/lib/usbhid/src/hiddescriptor.c

    r4c3ad56 r20a3465  
    974974/*---------------------------------------------------------------------------*/
    975975
    976 /**
    977  * Releases whole linked list of report items
    978  *
    979  * @param list List of report descriptor items (usb_hid_report_item_t)
    980  * @return void
    981  */
    982 void usb_hid_free_report_list(list_t *list)
    983 {
    984         return; /* XXX What's this? */
    985        
    986 /*      usb_hid_report_item_t *report_item;
    987         link_t *next;
    988        
    989         if(list == NULL || list_empty(list)) {
    990             return;
    991         }
    992        
    993         next = list->head.next;
    994         while (next != &list->head) {
    995                 report_item = list_get_instance(next, usb_hid_report_item_t,
    996                     rpath_items_link);
    997 
    998                 while(!list_empty(&report_item->usage_path->link)) {
    999                         usb_hid_report_remove_last_item(report_item->usage_path);
    1000                 }
    1001 
    1002                
    1003             next = next->next;
    1004            
    1005             free(report_item);
    1006         }
    1007        
    1008         return;
    1009         */
    1010 }
    1011 /*---------------------------------------------------------------------------*/
    1012976
    1013977/** Frees the HID report descriptor parser structure
     
    1016980 * @return void
    1017981 */
    1018 void usb_hid_free_report(usb_hid_report_t *report)
     982void usb_hid_report_deinit(usb_hid_report_t *report)
    1019983{
    1020984        if(report == NULL){
  • uspace/lib/usbhid/src/hidparser.c

    r4c3ad56 r20a3465  
    5252        int32_t value);
    5353
    54 int usb_pow(int a, int b);
    55 
    56 /*---------------------------------------------------------------------------*/
    57 
    58 // TODO: tohle ma bejt asi jinde
    59 int usb_pow(int a, int b)
    60 {
    61         switch(b) {
     54/*---------------------------------------------------------------------------*/
     55
     56static int usb_pow(int a, int b)
     57{
     58        switch (b) {
    6259        case 0:
    6360                return 1;
     
    6764                break;
    6865        default:
    69                 return a * usb_pow(a, b-1);
     66                return a * usb_pow(a, b - 1);
    7067                break;
    7168        }
     
    8178 */
    8279size_t usb_hid_report_size(usb_hid_report_t *report, uint8_t report_id,
    83                            usb_hid_report_type_t type)
     80    usb_hid_report_type_t type)
    8481{
    8582        usb_hid_report_description_t *report_des;
    8683
    87         if(report == NULL) {
     84        if (report == NULL) {
    8885                return 0;
    8986        }
    9087
    91         report_des = usb_hid_report_find_description (report, report_id, type);
    92         if(report_des == NULL){
     88        report_des = usb_hid_report_find_description(report, report_id, type);
     89        if (report_des == NULL) {
    9390                return 0;
    94         }
    95         else {
     91        } else {
    9692                return report_des->item_length;
    9793        }
     
    106102 */
    107103size_t usb_hid_report_byte_size(usb_hid_report_t *report, uint8_t report_id,
    108                            usb_hid_report_type_t type)
     104    usb_hid_report_type_t type)
    109105{
    110106        usb_hid_report_description_t *report_des;
    111107
    112         if(report == NULL) {
     108        if (report == NULL) {
    113109                return 0;
    114110        }
    115111
    116         report_des = usb_hid_report_find_description (report, report_id, type);
    117         if(report_des == NULL){
     112        report_des = usb_hid_report_find_description(report, report_id, type);
     113        if (report_des == NULL) {
    118114                return 0;
    119         }
    120         else {
     115        } else {
    121116                return ((report_des->bit_length + 7) / 8) ;
    122117        }
     
    133128 */
    134129int usb_hid_parse_report(const usb_hid_report_t *report, const uint8_t *data,
    135         size_t size, uint8_t *report_id)
     130    size_t size, uint8_t *report_id)
    136131{
    137132        usb_hid_report_field_t *item;
     
    140135        usb_hid_report_type_t type = USB_HID_REPORT_TYPE_INPUT;
    141136       
    142         if(report == NULL) {
     137        if (report == NULL) {
    143138                return EINVAL;
    144139        }
    145140
    146         if(report->use_report_ids != 0) {
     141        if (report->use_report_ids != 0) {
    147142                *report_id = data[0];
    148         }       
    149         else {
     143        } else {
    150144                *report_id = 0;
    151145        }
    152146
    153 
    154147        report_des = usb_hid_report_find_description(report, *report_id,
    155                 type);
    156 
    157         if(report_des == NULL) {
     148            type);
     149
     150        if (report_des == NULL) {
    158151                return EINVAL;
    159152        }
     
    162155        list_foreach(report_des->report_items, list_item) {
    163156                item = list_get_instance(list_item, usb_hid_report_field_t,
    164                                 ritems_link);
    165 
    166                 if(USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) == 0) {
     157                    ritems_link);
     158
     159                if (USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) == 0) {
    167160                       
    168                         if(USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0){
    169 
    170                                 // array
     161                        if (USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) {
     162                                /* array */
    171163                                item->value =
    172164                                        usb_hid_translate_data(item, data);
    173165               
    174166                                item->usage = USB_HID_EXTENDED_USAGE(
    175                                     item->usages[
    176                                     item->value - item->physical_minimum]);
     167                                    item->usages[item->value -
     168                                    item->physical_minimum]);
    177169
    178170                                item->usage_page =
    179171                                    USB_HID_EXTENDED_USAGE_PAGE(
    180                                     item->usages[
    181                                     item->value - item->physical_minimum]);
    182 
    183                                 usb_hid_report_set_last_item (
     172                                    item->usages[item->value -
     173                                    item->physical_minimum]);
     174
     175                                usb_hid_report_set_last_item(
    184176                                    item->collection_path,
    185177                                    USB_HID_TAG_CLASS_GLOBAL,
    186178                                    item->usage_page);
    187179
    188                                 usb_hid_report_set_last_item (
     180                                usb_hid_report_set_last_item(
    189181                                    item->collection_path,
    190182                                    USB_HID_TAG_CLASS_LOCAL, item->usage);
    191                                
    192                         }
    193                         else {
    194                                 // variable item
     183                        } else {
     184                                /* variable item */
    195185                                item->value = usb_hid_translate_data(item,
    196186                                    data);                             
     
    200190       
    201191        return EOK;
    202        
    203192}
    204193
     
    217206        int part_size;
    218207       
    219         int32_t value=0;
    220         int32_t mask=0;
    221         const uint8_t *foo=0;
    222 
    223         // now only shot tags are allowed
    224         if(item->size > 32) {
     208        int32_t value = 0;
     209        int32_t mask = 0;
     210        const uint8_t *foo = 0;
     211
     212        /* now only short tags are allowed */
     213        if (item->size > 32) {
    225214                return 0;
    226215        }
    227216
    228         if((item->physical_minimum == 0) && (item->physical_maximum == 0)){
     217        if ((item->physical_minimum == 0) && (item->physical_maximum == 0)) {
    229218                item->physical_minimum = item->logical_minimum;
    230219                item->physical_maximum = item->logical_maximum;                 
     
    232221       
    233222
    234         if(item->physical_maximum == item->physical_minimum){
     223        if (item->physical_maximum == item->physical_minimum) {
    235224            resolution = 1;
    236         }
    237         else {
     225        } else {
    238226            resolution = (item->logical_maximum - item->logical_minimum) /
    239227                ((item->physical_maximum - item->physical_minimum) *
    240                 (usb_pow(10,(item->unit_exponent))));
     228                (usb_pow(10, (item->unit_exponent))));
    241229        }
    242230
    243231        offset = item->offset;
    244232        // FIXME
    245         if((size_t)(offset/8) != (size_t)((offset+item->size-1)/8)) {
     233        if ((size_t) (offset / 8) != (size_t) ((offset+item->size - 1) / 8)) {
    246234               
    247235                part_size = 0;
    248236
    249                 size_t i=0;
    250                 for(i=(size_t)(offset/8); i<=(size_t)(offset+item->size-1)/8; i++){
    251                         if(i == (size_t)(offset/8)) {
    252                                 // the higher one
     237                size_t i = 0;
     238                for (i = (size_t) (offset / 8);
     239                    i <= (size_t) (offset + item->size - 1) / 8; i++) {
     240                        if (i == (size_t) (offset / 8)) {
     241                                /* the higher one */
    253242                                part_size = 8 - (offset % 8);
    254243                                foo = data + i;
    255                                 mask =  ((1 << (item->size-part_size))-1);
     244                                mask =  ((1 << (item->size - part_size)) - 1);
    256245                                value = (*foo & mask);
    257                         }
    258                         else if(i == ((offset+item->size-1)/8)){
    259                                 // the lower one
     246                        } else if (i == ((offset + item->size - 1) / 8)) {
     247                                /* the lower one */
    260248                                foo = data + i;
    261                                 mask = ((1 << (item->size - part_size)) - 1)
    262                                         << (8 - (item->size - part_size));
     249                                mask = ((1 << (item->size - part_size)) - 1) <<
     250                                    (8 - (item->size - part_size));
    263251
    264252                                value = (((*foo & mask) >> (8 -
    265                                     (item->size - part_size))) << part_size )
    266                                     + value;
    267                         }
    268                         else {
    269                                 value = (*(data + 1) << (part_size + 8)) + value;
     253                                    (item->size - part_size))) << part_size) +
     254                                    value;
     255                        } else {
     256                                value = (*(data + 1) << (part_size + 8)) +
     257                                    value;
    270258                                part_size += 8;
    271259                        }
    272260                }
    273         }
    274         else {         
    275                 foo = data+(offset/8);
    276                 mask =  ((1 << item->size)-1) << (8-((offset%8)+item->size));
    277                 value = (*foo & mask) >> (8-((offset%8)+item->size));
    278         }
    279 
    280         if((item->logical_minimum < 0) || (item->logical_maximum < 0)){
     261        } else {               
     262                foo = data + (offset / 8);
     263                mask = ((1 << item->size) - 1) <<
     264                    (8 - ((offset % 8) + item->size));
     265                value = (*foo & mask) >> (8 - ((offset % 8) + item->size));
     266        }
     267
     268        if ((item->logical_minimum < 0) || (item->logical_maximum < 0)) {
    281269                value = USB_HID_UINT32_TO_INT32(value, item->size);
    282270        }
    283271
    284         return (int)(((value - item->logical_minimum) / resolution) +
    285                 item->physical_minimum);
    286        
     272        return (int) (((value - item->logical_minimum) / resolution) +
     273            item->physical_minimum);
    287274}
    288275
     
    299286 */
    300287uint8_t *usb_hid_report_output(usb_hid_report_t *report, size_t *size,
    301         uint8_t report_id)
    302 {
    303         if(report == NULL) {
     288    uint8_t report_id)
     289{
     290        if (report == NULL) {
    304291                *size = 0;
    305292                return NULL;
     
    310297        list_foreach(report->reports, report_it) {
    311298                report_des = list_get_instance(report_it,
    312                         usb_hid_report_description_t, reports_link);
     299                    usb_hid_report_description_t, reports_link);
    313300               
    314                 if((report_des->report_id == report_id) &&
    315                         (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)){
     301                if ((report_des->report_id == report_id) &&
     302                    (report_des->type == USB_HID_REPORT_TYPE_OUTPUT)) {
    316303                        break;
    317304                }
    318305        }
    319306
    320         if(report_des == NULL){
     307        if (report_des == NULL) {
    321308                *size = 0;
    322309                return NULL;
    323         }
    324         else {
    325                 *size = (report_des->bit_length + (8 - 1))/8;
     310        } else {
     311                *size = (report_des->bit_length + (8 - 1)) / 8;
    326312                uint8_t *ret = malloc((*size) * sizeof(uint8_t));
    327313                memset(ret, 0, (*size) * sizeof(uint8_t));
     
    337323 */
    338324void usb_hid_report_output_free(uint8_t *output)
    339 
    340 {
    341         if(output != NULL) {
    342                 free (output);
     325{
     326        if (output != NULL) {
     327                free(output);
    343328        }
    344329}
     
    354339 */
    355340int usb_hid_report_output_translate(usb_hid_report_t *report,
    356         uint8_t report_id, uint8_t *buffer, size_t size)
    357 {
    358         int32_t value=0;
     341    uint8_t report_id, uint8_t *buffer, size_t size)
     342{
     343        int32_t value = 0;
    359344        int offset;
    360345        int length;
    361346        int32_t tmp_value;
    362347       
    363         if(report == NULL) {
     348        if (report == NULL) {
    364349                return EINVAL;
    365350        }
    366351
    367         if(report->use_report_ids != 0) {
     352        if (report->use_report_ids != 0) {
    368353                buffer[0] = report_id;         
    369354        }
    370355
    371356        usb_hid_report_description_t *report_des;
    372         report_des = usb_hid_report_find_description (report, report_id,
    373                 USB_HID_REPORT_TYPE_OUTPUT);
    374        
    375         if(report_des == NULL){
     357        report_des = usb_hid_report_find_description(report, report_id,
     358            USB_HID_REPORT_TYPE_OUTPUT);
     359       
     360        if (report_des == NULL) {
    376361                return EINVAL;
    377362        }
     
    384369
    385370                value = usb_hid_translate_data_reverse(report_item,
    386                         report_item->value);
     371                    report_item->value);
    387372
    388373                offset = report_des->bit_length - report_item->offset - 1;
     
    391376                usb_log_debug("\ttranslated value: %x\n", value);
    392377
    393                 if((offset/8) == ((offset+length-1)/8)) {
    394                         // je to v jednom bytu
    395                         if(((size_t)(offset/8) >= size) ||
    396                                 ((size_t)(offset+length-1)/8) >= size) {
     378                if ((offset / 8) == ((offset + length - 1) / 8)) {
     379                        if (((size_t) (offset / 8) >= size) ||
     380                            ((size_t) (offset + length - 1) / 8) >= size) {
    397381                                break; // TODO ErrorCode
    398382                        }
    399                         size_t shift = 8 - offset%8 - length;
     383                        size_t shift = 8 - offset % 8 - length;
    400384                        value = value << shift;                                                 
    401                         value = value & (((1 << length)-1) << shift);
     385                        value = value & (((1 << length) - 1) << shift);
    402386                               
    403387                        uint8_t mask = 0;
    404388                        mask = 0xff - (((1 << length) - 1) << shift);
    405                         buffer[offset/8] = (buffer[offset/8] & mask) | value;
    406                 }
    407                 else {
     389                        buffer[offset / 8] = (buffer[offset / 8] & mask) |
     390                            value;
     391                } else {
    408392                        int i = 0;
    409393                        uint8_t mask = 0;
    410                         for(i = (offset/8); i <= ((offset+length-1)/8); i++) {
    411                                 if(i == (offset/8)) {
     394                        for (i = (offset / 8);
     395                            i <= ((offset + length - 1) / 8); i++) {
     396                                if (i == (offset / 8)) {
    412397                                        tmp_value = value;
    413398                                        tmp_value = tmp_value &
    414                                                 ((1 << (8-(offset%8)))-1);
    415 
    416                                         tmp_value = tmp_value << (offset%8);
    417        
    418                                         mask = ~(((1 << (8-(offset%8)))-1) <<
    419                                                         (offset%8));
     399                                            ((1 << (8 - (offset % 8))) - 1);
     400
     401                                        tmp_value = tmp_value << (offset % 8);
     402       
     403                                        mask = ~(((1 << (8 - (offset % 8))) - 1)
     404                                            << (offset % 8));
    420405
    421406                                        buffer[i] = (buffer[i] & mask) |
    422                                                 tmp_value;
    423                                 }
    424                                 else if (i == ((offset + length -1)/8)) {
     407                                            tmp_value;
     408                                } else if (i == ((offset + length - 1) / 8)) {
    425409                                       
    426410                                        value = value >> (length -
    427                                                 ((offset + length) % 8));
     411                                            ((offset + length) % 8));
    428412
    429413                                        value = value & ((1 << (length -
    430                                                 ((offset + length) % 8))) - 1);
     414                                            ((offset + length) % 8))) - 1);
    431415                               
    432416                                        mask = (1 << (length -
    433                                                 ((offset + length) % 8))) - 1;
     417                                            ((offset + length) % 8))) - 1;
    434418
    435419                                        buffer[i] = (buffer[i] & mask) | value;
    436                                 }
    437                                 else {
    438                                         buffer[i] = value & (0xFF << i);
     420                                } else {
     421                                        buffer[i] = value & (0xff << i);
    439422                                }
    440423                        }
    441424                }
    442425
    443                 // reset value
     426                /* reset value */
    444427                report_item->value = 0;
    445428        }
     
    456439 */
    457440uint32_t usb_hid_translate_data_reverse(usb_hid_report_field_t *item,
    458         int value)
    459 {
    460         int ret=0;
     441    int value)
     442{
     443        int ret = 0;
    461444        int resolution;
    462445
    463         if(USB_HID_ITEM_FLAG_CONSTANT(item->item_flags)) {
     446        if (USB_HID_ITEM_FLAG_CONSTANT(item->item_flags)) {
    464447                ret = item->logical_minimum;
    465448        }
    466449
    467         if((item->physical_minimum == 0) && (item->physical_maximum == 0)){
     450        if ((item->physical_minimum == 0) && (item->physical_maximum == 0)) {
    468451                item->physical_minimum = item->logical_minimum;
    469452                item->physical_maximum = item->logical_maximum;                 
    470453        }
    471454       
    472         // variable item
    473         if(item->physical_maximum == item->physical_minimum){
     455        /* variable item */
     456        if (item->physical_maximum == item->physical_minimum) {
    474457            resolution = 1;
    475         }
    476         else {
     458        } else {
    477459            resolution = (item->logical_maximum - item->logical_minimum) /
    478460                ((item->physical_maximum - item->physical_minimum) *
    479                 (usb_pow(10,(item->unit_exponent))));
     461                (usb_pow(10, (item->unit_exponent))));
    480462        }
    481463
    482464        ret = ((value - item->physical_minimum) * resolution) +
    483                 item->logical_minimum;
    484 
    485         usb_log_debug("\tvalue(%x), resolution(%x), phymin(%x) logmin(%x), \
    486                 ret(%x)\n", value, resolution, item->physical_minimum,
    487                 item->logical_minimum, ret);
    488        
    489         if((item->logical_minimum < 0) || (item->logical_maximum < 0)){
     465            item->logical_minimum;
     466
     467        usb_log_debug("\tvalue(%x), resolution(%x), phymin(%x) logmin(%x), "
     468            "ret(%x)\n", value, resolution, item->physical_minimum,
     469            item->logical_minimum, ret);
     470       
     471        if ((item->logical_minimum < 0) || (item->logical_maximum < 0)) {
    490472                return USB_HID_INT32_TO_UINT32(ret, item->size);
    491473        }
    492         return (int32_t)0 + ret;
     474
     475        return (int32_t) 0 + ret;
    493476}
    494477
     
    501484 */
    502485usb_hid_report_item_t *usb_hid_report_item_clone(
    503         const usb_hid_report_item_t *item)
     486    const usb_hid_report_item_t *item)
    504487{
    505488        usb_hid_report_item_t *new_report_item;
    506489       
    507         if(!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) {
     490        if (!(new_report_item = malloc(sizeof(usb_hid_report_item_t)))) {
    508491                return NULL;
    509492        }                                       
     
    529512 */
    530513usb_hid_report_field_t *usb_hid_report_get_sibling(usb_hid_report_t *report,
    531         usb_hid_report_field_t *field, usb_hid_report_path_t *path, int flags,
    532         usb_hid_report_type_t type)
     514    usb_hid_report_field_t *field, usb_hid_report_path_t *path, int flags,
     515    usb_hid_report_type_t type)
    533516{
    534517        usb_hid_report_description_t *report_des =
    535                 usb_hid_report_find_description(report, path->report_id, type);
     518            usb_hid_report_find_description(report, path->report_id, type);
    536519
    537520        link_t *field_it;
    538521       
    539         if(report_des == NULL){
     522        if (report_des == NULL) {
    540523                return NULL;
    541524        }
    542525
    543         if(field == NULL){
     526        if (field == NULL) {
    544527                field_it = report_des->report_items.head.next;
    545         }
    546         else {
     528        } else {
    547529                field_it = field->ritems_link.next;
    548530        }
    549531
    550         while(field_it != &report_des->report_items.head) {
     532        while (field_it != &report_des->report_items.head) {
    551533                field = list_get_instance(field_it, usb_hid_report_field_t,
    552                         ritems_link);
    553 
    554                 if(USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {
    555                         usb_hid_report_path_append_item (
    556                                 field->collection_path, field->usage_page,
    557                                 field->usage);
    558 
    559                         if(usb_hid_report_compare_usage_path(
    560                                 field->collection_path, path, flags) == EOK){
    561 
     534                    ritems_link);
     535
     536                if (USB_HID_ITEM_FLAG_CONSTANT(field->item_flags) == 0) {
     537                        usb_hid_report_path_append_item(field->collection_path,
     538                            field->usage_page, field->usage);
     539
     540                        if (usb_hid_report_compare_usage_path(
     541                            field->collection_path, path, flags) == EOK) {
    562542                                usb_hid_report_remove_last_item(
    563                                         field->collection_path);
    564 
     543                                    field->collection_path);
    565544                                return field;
    566545                        }
    567                         usb_hid_report_remove_last_item (
    568                                 field->collection_path);
     546                        usb_hid_report_remove_last_item(field->collection_path);
    569547                }
    570548                field_it = field_it->next;
     
    586564 * @retval report_id otherwise
    587565 */
    588 uint8_t usb_hid_get_next_report_id(usb_hid_report_t *report,
    589         uint8_t report_id, usb_hid_report_type_t type)
    590 {
    591         if(report == NULL){
     566uint8_t usb_hid_get_next_report_id(usb_hid_report_t *report, uint8_t report_id,
     567    usb_hid_report_type_t type)
     568{
     569        if (report == NULL) {
    592570                return 0;
    593571        }
     
    596574        link_t *report_it;
    597575       
    598         if(report_id > 0) {
     576        if (report_id > 0) {
    599577                report_des = usb_hid_report_find_description(report, report_id,
    600                         type);
    601                 if(report_des == NULL) {
     578                    type);
     579                if (report_des == NULL) {
    602580                        return 0;
    603                 }
    604                 else {
     581                } else {
    605582                        report_it = report_des->reports_link.next;
    606583                }       
    607         }
    608         else {
     584        } else {
    609585                report_it = report->reports.head.next;
    610586        }
    611587
    612         while(report_it != &report->reports.head) {
     588        while (report_it != &report->reports.head) {
    613589                report_des = list_get_instance(report_it,
    614                         usb_hid_report_description_t, reports_link);
    615 
    616                 if(report_des->type == type){
     590                    usb_hid_report_description_t, reports_link);
     591
     592                if (report_des->type == type) {
    617593                        return report_des->report_id;
    618594                }
     
    635611void usb_hid_report_reset_local_items(usb_hid_report_item_t *report_item)
    636612{
    637         if(report_item == NULL) {
     613        if (report_item == NULL) {
    638614                return;
    639615        }
     
    651627        report_item->string_minimum = 0;
    652628        report_item->string_maximum = 0;
    653 
    654         return;
    655 }
     629}
     630
    656631/**
    657632 * @}
  • uspace/lib/usbhid/src/hidreport.c

    r4c3ad56 r20a3465  
    6969         * First nested descriptor of the configuration descriptor.
    7070         */
    71         uint8_t *d =
     71        const uint8_t *d =
    7272            usb_dp_get_nested_descriptor(&parser, &parser_data,
    7373            dev->descriptors.configuration);
     
    9292         * First nested descriptor of the interface descriptor.
    9393         */
    94         uint8_t *iface_desc = d;
     94        const uint8_t *iface_desc = d;
    9595        d = usb_dp_get_nested_descriptor(&parser, &parser_data, iface_desc);
    9696       
  • uspace/lib/usbhost/include/usb/host/endpoint.h

    r4c3ad56 r20a3465  
    3636#define LIBUSBHOST_HOST_ENDPOINT_H
    3737
    38 #include <assert.h>
    3938#include <bool.h>
    4039#include <adt/list.h>
    4140#include <fibril_synch.h>
    42 
    4341#include <usb/usb.h>
    4442
     43/** Host controller side endpoint structure. */
    4544typedef struct endpoint {
     45        /** Part of linked list. */
     46        link_t link;
     47        /** USB address. */
    4648        usb_address_t address;
     49        /** USB endpoint number. */
    4750        usb_endpoint_t endpoint;
     51        /** Communication direction. */
    4852        usb_direction_t direction;
     53        /** USB transfer type. */
    4954        usb_transfer_type_t transfer_type;
     55        /** Communication speed. */
    5056        usb_speed_t speed;
     57        /** Maximum size of data packets. */
    5158        size_t max_packet_size;
     59        /** Necessary bandwidth. */
     60        size_t bandwidth;
     61        /** Value of the toggle bit. */
    5262        unsigned toggle:1;
     63        /** True if there is a batch using this scheduled for this endpoint. */
     64        volatile bool active;
     65        /** Protects resources and active status changes. */
    5366        fibril_mutex_t guard;
     67        /** Signals change of active status. */
    5468        fibril_condvar_t avail;
    55         volatile bool active;
    56         void (*destroy_hook)(struct endpoint *);
     69        /** Optional device specific data. */
    5770        struct {
     71                /** Device specific data. */
    5872                void *data;
     73                /** Callback to get the value of toggle bit. */
    5974                int (*toggle_get)(void *);
     75                /** Callback to set the value of toggle bit. */
    6076                void (*toggle_set)(void *, int);
    6177        } hc_data;
    6278} endpoint_t;
    6379
    64 endpoint_t * endpoint_get(usb_address_t address, usb_endpoint_t endpoint,
     80endpoint_t * endpoint_create(usb_address_t address, usb_endpoint_t endpoint,
    6581    usb_direction_t direction, usb_transfer_type_t type, usb_speed_t speed,
    66     size_t max_packet_size);
    67 
     82    size_t max_packet_size, size_t bw);
    6883void endpoint_destroy(endpoint_t *instance);
    6984
    7085void endpoint_set_hc_data(endpoint_t *instance,
    71     void *data, void (*destroy_hook)(endpoint_t *),
    72     int (*toggle_get)(void *), void (*toggle_set)(void *, int));
    73 
     86    void *data, int (*toggle_get)(void *), void (*toggle_set)(void *, int));
    7487void endpoint_clear_hc_data(endpoint_t *instance);
    7588
    7689void endpoint_use(endpoint_t *instance);
    77 
    7890void endpoint_release(endpoint_t *instance);
    7991
    8092int endpoint_toggle_get(endpoint_t *instance);
    81 
    8293void endpoint_toggle_set(endpoint_t *instance, int toggle);
    8394
    84 void endpoint_toggle_reset_filtered(endpoint_t *instance, usb_target_t target);
     95/** list_get_instance wrapper.
     96 * @param item Pointer to link member.
     97 * @return Pointer to enpoint_t structure.
     98 */
     99static inline endpoint_t * endpoint_get_instance(link_t *item)
     100{
     101        return list_get_instance(item, endpoint_t, link);
     102}
    85103#endif
    86104/**
  • uspace/lib/usbhost/include/usb/host/hcd.h

    r4c3ad56 r20a3465  
    3737
    3838#include <assert.h>
     39#include <usbhc_iface.h>
     40
    3941#include <usb/host/usb_device_manager.h>
    4042#include <usb/host/usb_endpoint_manager.h>
    4143#include <usb/host/usb_transfer_batch.h>
    42 #include <usbhc_iface.h>
    4344
    4445typedef struct hcd hcd_t;
    4546
     47/** Generic host controller driver structure. */
    4648struct hcd {
     49        /** Device manager storing handles and addresses. */
    4750        usb_device_manager_t dev_manager;
     51        /** Endpoint manager. */
    4852        usb_endpoint_manager_t ep_manager;
     53
     54        /** Device specific driver data. */
    4955        void *private_data;
    50 
     56        /** Transfer scheduling, implement in device driver. */
    5157        int (*schedule)(hcd_t *, usb_transfer_batch_t *);
     58        /** Hook called upon registering new endpoint. */
    5259        int (*ep_add_hook)(hcd_t *, endpoint_t *);
     60        /** Hook called upon removing of an endpoint. */
     61        void (*ep_remove_hook)(hcd_t *, endpoint_t *);
    5362};
    5463/*----------------------------------------------------------------------------*/
    55 static inline int hcd_init(hcd_t *hcd, size_t bandwidth,
     64/** Initialize hcd_t structure.
     65 * Initializes device and endpoint managers. Sets data nd hook pointer to NULL.
     66 * @param hcd hcd_t structure to initialize, non-null.
     67 * @param bandwidth Available bandwidth, passed to endpoint manager.
     68 * @param bw_count Bandwidth compute function, passed to endpoint manager.
     69 */
     70static inline void hcd_init(hcd_t *hcd, size_t bandwidth,
    5671    size_t (*bw_count)(usb_speed_t, usb_transfer_type_t, size_t, size_t))
    5772{
    5873        assert(hcd);
    5974        usb_device_manager_init(&hcd->dev_manager);
    60         return usb_endpoint_manager_init(&hcd->ep_manager, bandwidth, bw_count);
     75        usb_endpoint_manager_init(&hcd->ep_manager, bandwidth, bw_count);
     76        hcd->private_data = NULL;
     77        hcd->schedule = NULL;
     78        hcd->ep_add_hook = NULL;
     79        hcd->ep_remove_hook = NULL;
    6180}
    6281/*----------------------------------------------------------------------------*/
    63 static inline void hcd_destroy(hcd_t *hcd)
    64 {
    65         usb_endpoint_manager_destroy(&hcd->ep_manager);
    66 }
    67 /*----------------------------------------------------------------------------*/
    68 static inline void reset_ep_if_need(
    69     hcd_t *hcd, usb_target_t target, const char* setup_data)
     82/** Check registered endpoints and reset toggle bit if necessary.
     83 * @param hcd hcd_t structure, non-null.
     84 * @param target Control communication target.
     85 * @param setup_data Setup packet of the control communication.
     86 */
     87static inline void reset_ep_if_need(hcd_t *hcd, usb_target_t target,
     88    const char setup_data[8])
    7089{
    7190        assert(hcd);
    72         usb_endpoint_manager_reset_if_need(
     91        usb_endpoint_manager_reset_eps_if_need(
    7392            &hcd->ep_manager, target, (const uint8_t *)setup_data);
    7493}
    7594/*----------------------------------------------------------------------------*/
    76 static inline hcd_t * fun_to_hcd(ddf_fun_t *fun)
     95/** Data retrieve wrapper.
     96 * @param fun ddf function, non-null.
     97 * @return pointer cast to hcd_t*.
     98 */
     99static inline hcd_t * fun_to_hcd(const ddf_fun_t *fun)
    77100{
    78101        assert(fun);
  • uspace/lib/usbhost/include/usb/host/usb_device_manager.h

    r4c3ad56 r20a3465  
    4949#define USB_ADDRESS_COUNT (USB11_ADDRESS_MAX + 1)
    5050
    51 /** Information about attached USB device. */
    52 struct usb_device_info {
    53         usb_speed_t speed;
    54         bool occupied;
    55         devman_handle_t handle;
    56 };
    57 
    5851/** Host controller device manager.
    59  * You shall not access members directly but only using functions below.
     52 * You shall not access members directly.
    6053 */
    6154typedef struct {
    62         struct usb_device_info devices[USB_ADDRESS_COUNT];
     55        /** Information about attached USB devices. */
     56        struct {
     57                usb_speed_t speed;      /**< Device speed */
     58                bool occupied;          /**< The address is in use. */
     59                devman_handle_t handle; /**< Devman handle of the device. */
     60        } devices[USB_ADDRESS_COUNT];
    6361        fibril_mutex_t guard;
     62        /** The last reserved address */
    6463        usb_address_t last_address;
    6564} usb_device_manager_t;
     
    7069    usb_device_manager_t *instance, usb_speed_t speed);
    7170
    72 void usb_device_manager_bind(usb_device_manager_t *instance,
     71int usb_device_manager_bind(usb_device_manager_t *instance,
    7372    usb_address_t address, devman_handle_t handle);
    7473
    75 void usb_device_manager_release(usb_device_manager_t *instance,
     74int usb_device_manager_release(usb_device_manager_t *instance,
    7675    usb_address_t address);
    7776
    78 usb_address_t usb_device_manager_find(usb_device_manager_t *instance,
     77usb_address_t usb_device_manager_find_address(usb_device_manager_t *instance,
    7978    devman_handle_t handle);
    8079
    81 bool usb_device_manager_find_by_address(usb_device_manager_t *instance,
    82     usb_address_t address, devman_handle_t *handle);
    83 
    84 usb_speed_t usb_device_manager_get_speed(usb_device_manager_t *instance,
    85     usb_address_t address);
     80int usb_device_manager_get_info_by_address(usb_device_manager_t *instance,
     81    usb_address_t address, devman_handle_t *handle, usb_speed_t *speed);
    8682#endif
    8783/**
  • uspace/lib/usbhost/include/usb/host/usb_endpoint_manager.h

    r4c3ad56 r20a3465  
    4040#define LIBUSBHOST_HOST_USB_ENDPOINT_MANAGER_H
    4141
    42 #include <stdlib.h>
    43 #include <adt/hash_table.h>
     42#include <adt/list.h>
    4443#include <fibril_synch.h>
    4544#include <usb/usb.h>
     45
    4646#include <usb/host/endpoint.h>
    4747
    48 #define BANDWIDTH_TOTAL_USB11 12000000
     48/** Bytes per second in FULL SPEED */
     49#define BANDWIDTH_TOTAL_USB11 (12000000 / 8)
     50/** 90% of total bandwidth is available for periodic transfers */
    4951#define BANDWIDTH_AVAILABLE_USB11 ((BANDWIDTH_TOTAL_USB11 / 10) * 9)
     52/** 16 addresses per list */
     53#define ENDPOINT_LIST_COUNT 8
    5054
     55/** Endpoint management structure */
    5156typedef struct usb_endpoint_manager {
    52         hash_table_t ep_table;
     57        /** Store endpoint_t instances */
     58        list_t endpoint_lists[ENDPOINT_LIST_COUNT];
     59        /** Prevents races accessing lists */
    5360        fibril_mutex_t guard;
     61        /** Size of the bandwidth pool */
    5462        size_t free_bw;
     63        /** Use this function to count bw required by EP */
    5564        size_t (*bw_count)(usb_speed_t, usb_transfer_type_t, size_t, size_t);
    5665} usb_endpoint_manager_t;
     
    6372    size_t (*bw_count)(usb_speed_t, usb_transfer_type_t, size_t, size_t));
    6473
    65 void usb_endpoint_manager_destroy(usb_endpoint_manager_t *instance);
     74void usb_endpoint_manager_reset_eps_if_need(usb_endpoint_manager_t *instance,
     75    usb_target_t target, const uint8_t data[8]);
    6676
    67 int usb_endpoint_manager_register_ep(usb_endpoint_manager_t *instance,
    68     endpoint_t *ep, size_t data_size);
    69 
    70 int usb_endpoint_manager_unregister_ep(usb_endpoint_manager_t *instance,
     77int usb_endpoint_manager_register_ep(
     78    usb_endpoint_manager_t *instance, endpoint_t *ep, size_t data_size);
     79int usb_endpoint_manager_unregister_ep(
     80    usb_endpoint_manager_t *instance, endpoint_t *ep);
     81endpoint_t * usb_endpoint_manager_find_ep(usb_endpoint_manager_t *instance,
    7182    usb_address_t address, usb_endpoint_t ep, usb_direction_t direction);
    7283
    73 endpoint_t * usb_endpoint_manager_get_ep(usb_endpoint_manager_t *instance,
    74     usb_address_t address, usb_endpoint_t ep, usb_direction_t direction,
    75     size_t *bw);
    76 
    77 void usb_endpoint_manager_reset_if_need(
    78     usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data);
    79 
    80 /** Wrapper combining allocation and insertion */
    81 static inline int usb_endpoint_manager_add_ep(usb_endpoint_manager_t *instance,
     84int usb_endpoint_manager_add_ep(usb_endpoint_manager_t *instance,
    8285    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
    8386    usb_transfer_type_t type, usb_speed_t speed, size_t max_packet_size,
    84     size_t data_size)
    85 {
    86         endpoint_t *ep = endpoint_get(
    87             address, endpoint, direction, type, speed, max_packet_size);
    88         if (!ep)
    89                 return ENOMEM;
     87    size_t data_size, int (*callback)(endpoint_t *, void *), void *arg);
    9088
    91         const int ret =
    92             usb_endpoint_manager_register_ep(instance, ep, data_size);
    93         if (ret != EOK) {
    94                 endpoint_destroy(ep);
    95         }
    96         return ret;
    97 }
     89int usb_endpoint_manager_remove_ep(usb_endpoint_manager_t *instance,
     90    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
     91    void (*callback)(endpoint_t *, void *), void *arg);
    9892#endif
    9993/**
    10094 * @}
    10195 */
    102 
  • uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h

    r4c3ad56 r20a3465  
    4343#define USB_SETUP_PACKET_SIZE 8
    4444
    45 typedef struct usb_transfer_batch usb_transfer_batch_t;
    4645/** Structure stores additional data needed for communication with EP */
    47 struct usb_transfer_batch {
     46typedef struct usb_transfer_batch {
    4847        /** Endpoint used for communication */
    4948        endpoint_t *ep;
     
    7776        /** Callback to properly remove driver data during destruction */
    7877        void (*private_data_dtor)(void *p_data);
    79 };
     78} usb_transfer_batch_t;
    8079
    8180/** Printf formatting string for dumping usb_transfer_batch_t. */
     
    9392
    9493
    95 usb_transfer_batch_t * usb_transfer_batch_get(
     94usb_transfer_batch_t * usb_transfer_batch_create(
    9695    endpoint_t *ep,
    9796    char *buffer,
     
    105104    void (*private_data_dtor)(void *p_data)
    106105);
     106void usb_transfer_batch_destroy(const usb_transfer_batch_t *instance);
    107107
    108 void usb_transfer_batch_finish(usb_transfer_batch_t *instance,
     108void usb_transfer_batch_finish(const usb_transfer_batch_t *instance,
    109109    const void* data, size_t size);
    110 void usb_transfer_batch_call_in(usb_transfer_batch_t *instance);
    111 void usb_transfer_batch_call_out(usb_transfer_batch_t *instance);
    112 void usb_transfer_batch_dispose(usb_transfer_batch_t *instance);
    113 
    114 /** Helper function, calls callback and correctly destroys batch structure.
    115  *
    116  * @param[in] instance Batch structure to use.
    117  */
    118 static inline void usb_transfer_batch_call_in_and_dispose(
    119     usb_transfer_batch_t *instance)
    120 {
    121         assert(instance);
    122         usb_transfer_batch_call_in(instance);
    123         usb_transfer_batch_dispose(instance);
    124 }
    125110/*----------------------------------------------------------------------------*/
    126 /** Helper function calls callback and correctly destroys batch structure.
    127  *
    128  * @param[in] instance Batch structure to use.
    129  */
    130 static inline void usb_transfer_batch_call_out_and_dispose(
    131     usb_transfer_batch_t *instance)
    132 {
    133         assert(instance);
    134         usb_transfer_batch_call_out(instance);
    135         usb_transfer_batch_dispose(instance);
    136 }
    137 /*----------------------------------------------------------------------------*/
    138 /** Helper function, sets error value and finishes transfer.
     111/** Override error value and finishes transfer.
    139112 *
    140113 * @param[in] instance Batch structure to use.
     
    151124}
    152125/*----------------------------------------------------------------------------*/
    153 /** Helper function, determines batch direction absed on the present callbacks
    154  * @param[in] instance Batch structure to use.
     126/** Determine batch direction based on the callbacks present
     127 * @param[in] instance Batch structure to use, non-null.
    155128 * @return USB_DIRECTION_IN, or USB_DIRECTION_OUT.
    156129 */
  • uspace/lib/usbhost/src/endpoint.c

    r4c3ad56 r20a3465  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 
    29 /** @addtogroup drvusbuhcihc
     28/** @addtogroup libusbhost
    3029 * @{
    3130 */
     
    3938#include <usb/host/endpoint.h>
    4039
    41 endpoint_t * endpoint_get(usb_address_t address, usb_endpoint_t endpoint,
     40/** Allocate ad initialize endpoint_t structure.
     41 * @param address USB address.
     42 * @param endpoint USB endpoint number.
     43 * @param direction Communication direction.
     44 * @param type USB transfer type.
     45 * @param speed Communication speed.
     46 * @param max_packet_size Maximum size of data packets.
     47 * @param bw Required bandwidth.
     48 * @return Pointer to initialized endpoint_t structure, NULL on failure.
     49 */
     50endpoint_t * endpoint_create(usb_address_t address, usb_endpoint_t endpoint,
    4251    usb_direction_t direction, usb_transfer_type_t type, usb_speed_t speed,
    43     size_t max_packet_size)
     52    size_t max_packet_size, size_t bw)
    4453{
    4554        endpoint_t *instance = malloc(sizeof(endpoint_t));
     
    5160                instance->speed = speed;
    5261                instance->max_packet_size = max_packet_size;
     62                instance->bandwidth = bw;
    5363                instance->toggle = 0;
    5464                instance->active = false;
    55                 instance->destroy_hook = NULL;
    5665                instance->hc_data.data = NULL;
    5766                instance->hc_data.toggle_get = NULL;
    5867                instance->hc_data.toggle_set = NULL;
     68                link_initialize(&instance->link);
    5969                fibril_mutex_initialize(&instance->guard);
    6070                fibril_condvar_initialize(&instance->avail);
    61                 endpoint_clear_hc_data(instance);
    6271        }
    6372        return instance;
    6473}
    6574/*----------------------------------------------------------------------------*/
     75/** Properly dispose of endpoint_t structure.
     76 * @param instance endpoint_t structure.
     77 */
    6678void endpoint_destroy(endpoint_t *instance)
    6779{
    6880        assert(instance);
     81        //TODO: Do something about waiting fibrils.
    6982        assert(!instance->active);
    70         if (instance->hc_data.data) {
    71                 assert(instance->destroy_hook);
    72                 instance->destroy_hook(instance);
    73         }
     83        assert(instance->hc_data.data == NULL);
    7484        free(instance);
    7585}
    7686/*----------------------------------------------------------------------------*/
     87/** Set device specific data and hooks.
     88 * @param instance endpoint_t structure.
     89 * @param data device specific data.
     90 * @param toggle_get Hook to call when retrieving value of toggle bit.
     91 * @param toggle_set Hook to call when setting the value of toggle bit.
     92 */
    7793void endpoint_set_hc_data(endpoint_t *instance,
    78     void *data, void (*destroy_hook)(endpoint_t *),
    79     int (*toggle_get)(void *), void (*toggle_set)(void *, int))
     94    void *data, int (*toggle_get)(void *), void (*toggle_set)(void *, int))
    8095{
    8196        assert(instance);
    82         instance->destroy_hook = destroy_hook;
     97        fibril_mutex_lock(&instance->guard);
    8398        instance->hc_data.data = data;
    8499        instance->hc_data.toggle_get = toggle_get;
    85100        instance->hc_data.toggle_set = toggle_set;
     101        fibril_mutex_unlock(&instance->guard);
    86102}
    87103/*----------------------------------------------------------------------------*/
     104/** Clear device specific data and hooks.
     105 * @param instance endpoint_t structure.
     106 * @note This function does not free memory pointed to by data pointer.
     107 */
    88108void endpoint_clear_hc_data(endpoint_t *instance)
    89109{
    90110        assert(instance);
    91         instance->destroy_hook = NULL;
     111        fibril_mutex_lock(&instance->guard);
    92112        instance->hc_data.data = NULL;
    93113        instance->hc_data.toggle_get = NULL;
    94114        instance->hc_data.toggle_set = NULL;
     115        fibril_mutex_unlock(&instance->guard);
    95116}
    96117/*----------------------------------------------------------------------------*/
     118/** Mark the endpoint as active and block access for further fibrils.
     119 * @param instance endpoint_t structure.
     120 */
    97121void endpoint_use(endpoint_t *instance)
    98122{
     
    105129}
    106130/*----------------------------------------------------------------------------*/
     131/** Mark the endpoint as inactive and allow access for further fibrils.
     132 * @param instance endpoint_t structure.
     133 */
    107134void endpoint_release(endpoint_t *instance)
    108135{
     
    114141}
    115142/*----------------------------------------------------------------------------*/
     143/** Get the value of toggle bit.
     144 * @param instance endpoint_t structure.
     145 * @note Will use provided hook.
     146 */
    116147int endpoint_toggle_get(endpoint_t *instance)
    117148{
    118149        assert(instance);
     150        fibril_mutex_lock(&instance->guard);
    119151        if (instance->hc_data.toggle_get)
    120152                instance->toggle =
    121153                    instance->hc_data.toggle_get(instance->hc_data.data);
    122         return (int)instance->toggle;
     154        const int ret = instance->toggle;
     155        fibril_mutex_unlock(&instance->guard);
     156        return ret;
    123157}
    124158/*----------------------------------------------------------------------------*/
     159/** Set the value of toggle bit.
     160 * @param instance endpoint_t structure.
     161 * @note Will use provided hook.
     162 */
    125163void endpoint_toggle_set(endpoint_t *instance, int toggle)
    126164{
    127165        assert(instance);
    128166        assert(toggle == 0 || toggle == 1);
     167        fibril_mutex_lock(&instance->guard);
     168        instance->toggle = toggle;
    129169        if (instance->hc_data.toggle_set)
    130170                instance->hc_data.toggle_set(instance->hc_data.data, toggle);
    131         instance->toggle = toggle;
    132 }
    133 /*----------------------------------------------------------------------------*/
    134 void endpoint_toggle_reset_filtered(endpoint_t *instance, usb_target_t target)
    135 {
    136         assert(instance);
    137         if (instance->address == target.address &&
    138             (instance->endpoint == target.endpoint || target.endpoint == 0))
    139                 endpoint_toggle_set(instance, 0);
     171        fibril_mutex_unlock(&instance->guard);
    140172}
    141173/**
  • uspace/lib/usbhost/src/iface.c

    r4c3ad56 r20a3465  
    4949        assert(hcd);
    5050
    51         int ret;
    52 
    53         size_t res_bw;
    54         endpoint_t *ep = usb_endpoint_manager_get_ep(&hcd->ep_manager,
    55             target.address, target.endpoint, direction, &res_bw);
     51        endpoint_t *ep = usb_endpoint_manager_find_ep(&hcd->ep_manager,
     52            target.address, target.endpoint, direction);
    5653        if (ep == NULL) {
    5754                usb_log_error("Endpoint(%d:%d) not registered for %s.\n",
     
    6562        const size_t bw = bandwidth_count_usb11(
    6663            ep->speed, ep->transfer_type, size, ep->max_packet_size);
    67         if (res_bw < bw) {
     64        /* Check if we have enough bandwidth reserved */
     65        if (ep->bandwidth < bw) {
    6866                usb_log_error("Endpoint(%d:%d) %s needs %zu bw "
    6967                    "but only %zu is reserved.\n",
    70                     target.address, target.endpoint, name, bw, res_bw);
     68                    ep->address, ep->endpoint, name, bw, ep->bandwidth);
    7169                return ENOSPC;
    7270        }
     
    7876        /* No private data and no private data dtor */
    7977        usb_transfer_batch_t *batch =
    80             usb_transfer_batch_get(ep, data, size, setup_data,
     78            usb_transfer_batch_create(ep, data, size, setup_data,
    8179            in, out, arg, fun, NULL, NULL);
    8280        if (!batch) {
     
    8482        }
    8583
    86         ret = hcd->schedule(hcd, batch);
     84        const int ret = hcd->schedule(hcd, batch);
    8785        if (ret != EOK)
    88                 usb_transfer_batch_dispose(batch);
     86                usb_transfer_batch_destroy(batch);
    8987
    9088        return ret;
     
    130128
    131129        usb_log_debug("Address bind %d-%" PRIun ".\n", address, handle);
    132         usb_device_manager_bind(&hcd->dev_manager, address, handle);
    133         return EOK;
     130        return usb_device_manager_bind(&hcd->dev_manager, address, handle);
    134131}
    135132/*----------------------------------------------------------------------------*/
     
    147144        hcd_t *hcd = fun_to_hcd(fun);
    148145        assert(hcd);
    149         const bool found =
    150             usb_device_manager_find_by_address(&hcd->dev_manager, address, handle);
    151         return found ? EOK : ENOENT;
     146        return usb_device_manager_get_info_by_address(
     147            &hcd->dev_manager, address, handle, NULL);
    152148}
    153149/*----------------------------------------------------------------------------*/
     
    166162        usb_device_manager_release(&hcd->dev_manager, address);
    167163        return EOK;
     164}
     165/*----------------------------------------------------------------------------*/
     166static int register_helper(endpoint_t *ep, void *arg)
     167{
     168        hcd_t *hcd = arg;
     169        assert(ep);
     170        assert(hcd);
     171        if (hcd->ep_add_hook)
     172                return hcd->ep_add_hook(hcd, ep);
     173        return EOK;
     174}
     175/*----------------------------------------------------------------------------*/
     176static void unregister_helper(endpoint_t *ep, void *arg)
     177{
     178        hcd_t *hcd = arg;
     179        assert(ep);
     180        assert(hcd);
     181        if (hcd->ep_remove_hook)
     182                hcd->ep_remove_hook(hcd, ep);
    168183}
    169184/*----------------------------------------------------------------------------*/
     
    180195        /* Default address is not bound or registered,
    181196         * thus it does not provide speed info. */
    182         const usb_speed_t speed = (address == 0) ? ep_speed :
    183             usb_device_manager_get_speed(&hcd->dev_manager, address);
     197        usb_speed_t speed = ep_speed;
     198        /* NOTE The function will return EINVAL and won't
     199         * touch speed variable for default address */
     200        usb_device_manager_get_info_by_address(
     201            &hcd->dev_manager, address, NULL, &speed);
    184202
    185203        usb_log_debug("Register endpoint %d:%d %s-%s %s %zuB %ums.\n",
     
    188206            max_packet_size, interval);
    189207
    190         endpoint_t *ep = endpoint_get(
    191             address, endpoint, direction, transfer_type, speed, max_packet_size);
    192         if (!ep)
    193                 return ENOMEM;
    194         int ret = EOK;
    195 
    196         if (hcd->ep_add_hook) {
    197                 ret = hcd->ep_add_hook(hcd, ep);
    198         }
    199         if (ret != EOK) {
    200                 endpoint_destroy(ep);
    201                 return ret;
    202         }
    203 
    204         ret = usb_endpoint_manager_register_ep(&hcd->ep_manager, ep, size);
    205         if (ret != EOK) {
    206                 endpoint_destroy(ep);
    207         }
    208         return ret;
     208        return usb_endpoint_manager_add_ep(&hcd->ep_manager, address, endpoint,
     209            direction, transfer_type, speed, max_packet_size, size,
     210            register_helper, hcd);
    209211}
    210212/*----------------------------------------------------------------------------*/
     
    218220        usb_log_debug("Unregister endpoint %d:%d %s.\n",
    219221            address, endpoint, usb_str_direction(direction));
    220         return usb_endpoint_manager_unregister_ep(&hcd->ep_manager, address,
    221             endpoint, direction);
     222        return usb_endpoint_manager_remove_ep(&hcd->ep_manager, address,
     223            endpoint, direction, unregister_helper, hcd);
    222224}
    223225/*----------------------------------------------------------------------------*/
  • uspace/lib/usbhost/src/usb_device_manager.c

    r4c3ad56 r20a3465  
    3838#include <usb/host/usb_device_manager.h>
    3939
    40 /*----------------------------------------------------------------------------*/
    4140/** Initialize device manager structure.
    4241 *
     
    4847{
    4948        assert(instance);
    50         unsigned i = 0;
    51         for (; i < USB_ADDRESS_COUNT; ++i) {
     49        for (unsigned i = 0; i < USB_ADDRESS_COUNT; ++i) {
    5250                instance->devices[i].occupied = false;
    5351                instance->devices[i].handle = 0;
     
    7775                ++new_address;
    7876                if (new_address > USB11_ADDRESS_MAX)
    79                         new_address = 1;
     77                        new_address = 1; // NOTE it should be safe to put 0 here
     78                                         // TODO Use mod
    8079                if (new_address == instance->last_address) {
    8180                        fibril_mutex_unlock(&instance->guard);
     
    8685        assert(new_address != USB_ADDRESS_DEFAULT);
    8786        assert(instance->devices[new_address].occupied == false);
     87        assert(instance->devices[new_address].handle == 0);
    8888
    8989        instance->devices[new_address].occupied = true;
     
    100100 * @param[in] address Device address
    101101 * @param[in] handle Devman handle of the device.
    102  */
    103 void usb_device_manager_bind(usb_device_manager_t *instance,
     102 * @return Error code.
     103 */
     104int usb_device_manager_bind(usb_device_manager_t *instance,
    104105    usb_address_t address, devman_handle_t handle)
    105106{
    106         assert(instance);
    107         fibril_mutex_lock(&instance->guard);
    108 
    109         assert(address > 0);
    110         assert(address <= USB11_ADDRESS_MAX);
    111         assert(instance->devices[address].occupied);
    112 
     107        if ((address <= 0) || (address >= USB_ADDRESS_COUNT)) {
     108                return EINVAL;
     109        }
     110        assert(instance);
     111
     112        fibril_mutex_lock(&instance->guard);
     113        /* Not reserved */
     114        if (!instance->devices[address].occupied) {
     115                fibril_mutex_unlock(&instance->guard);
     116                return ENOENT;
     117        }
     118        /* Already bound */
     119        if (instance->devices[address].handle != 0) {
     120                fibril_mutex_unlock(&instance->guard);
     121                return EEXISTS;
     122        }
    113123        instance->devices[address].handle = handle;
    114124        fibril_mutex_unlock(&instance->guard);
     125        return EOK;
    115126}
    116127/*----------------------------------------------------------------------------*/
     
    119130 * @param[in] instance Device manager structure to use.
    120131 * @param[in] address Device address
    121  */
    122 void usb_device_manager_release(
     132 * @return Error code.
     133 */
     134int usb_device_manager_release(
    123135    usb_device_manager_t *instance, usb_address_t address)
    124136{
    125         assert(instance);
    126         assert(address > 0);
    127         assert(address <= USB11_ADDRESS_MAX);
    128 
    129         fibril_mutex_lock(&instance->guard);
    130         assert(instance->devices[address].occupied);
     137        if ((address <= 0) || (address >= USB_ADDRESS_COUNT)) {
     138                return EINVAL;
     139        }
     140        assert(instance);
     141
     142        fibril_mutex_lock(&instance->guard);
     143        if (!instance->devices[address].occupied) {
     144                fibril_mutex_unlock(&instance->guard);
     145                return ENOENT;
     146        }
    131147
    132148        instance->devices[address].occupied = false;
    133         fibril_mutex_unlock(&instance->guard);
     149        instance->devices[address].handle = 0;
     150        fibril_mutex_unlock(&instance->guard);
     151        return EOK;
    134152}
    135153/*----------------------------------------------------------------------------*/
     
    140158 * @return USB Address, or error code.
    141159 */
    142 usb_address_t usb_device_manager_find(
     160usb_address_t usb_device_manager_find_address(
    143161    usb_device_manager_t *instance, devman_handle_t handle)
    144162{
    145163        assert(instance);
    146164        fibril_mutex_lock(&instance->guard);
    147         usb_address_t address = 1;
    148         while (address <= USB11_ADDRESS_MAX) {
     165        for (usb_address_t address = 1; address <= USB11_ADDRESS_MAX; ++address)
     166        {
    149167                if (instance->devices[address].handle == handle) {
    150168                        assert(instance->devices[address].occupied);
     
    152170                        return address;
    153171                }
    154                 ++address;
    155172        }
    156173        fibril_mutex_unlock(&instance->guard);
    157174        return ENOENT;
    158175}
    159 
    160 /** Find devman handle assigned to USB address.
    161  * Intentionally refuse to find handle of default address.
     176/*----------------------------------------------------------------------------*/
     177/** Find devman handle and speed assigned to USB address.
     178 * Intentionally refuse to work on default address.
    162179 *
    163180 * @param[in] instance Device manager structure to use.
    164181 * @param[in] address Address the caller wants to find.
    165182 * @param[out] handle Where to store found handle.
    166  * @return Whether such address is currently occupied.
    167  */
    168 bool usb_device_manager_find_by_address(usb_device_manager_t *instance,
    169     usb_address_t address, devman_handle_t *handle)
    170 {
    171         assert(instance);
    172         fibril_mutex_lock(&instance->guard);
     183 * @param[out] speed Assigned speed.
     184 * @return Error code.
     185 */
     186int usb_device_manager_get_info_by_address(usb_device_manager_t *instance,
     187    usb_address_t address, devman_handle_t *handle, usb_speed_t *speed)
     188{
     189        assert(instance);
    173190        if ((address <= 0) || (address >= USB_ADDRESS_COUNT)) {
    174                 fibril_mutex_unlock(&instance->guard);
    175                 return false;
    176         }
     191                return EINVAL;
     192        }
     193
     194        fibril_mutex_lock(&instance->guard);
    177195        if (!instance->devices[address].occupied) {
    178196                fibril_mutex_unlock(&instance->guard);
    179                 return false;
     197                return ENOENT;
    180198        }
    181199
     
    183201                *handle = instance->devices[address].handle;
    184202        }
    185 
    186         fibril_mutex_unlock(&instance->guard);
    187         return true;
    188 }
    189 
    190 /*----------------------------------------------------------------------------*/
    191 /** Get speed associated with the address
    192  *
    193  * @param[in] instance Device manager structure to use.
    194  * @param[in] address Address of the device.
    195  * @return USB speed.
    196  */
    197 usb_speed_t usb_device_manager_get_speed(
    198     usb_device_manager_t *instance, usb_address_t address)
    199 {
    200         assert(instance);
    201         assert(address >= 0);
    202         assert(address <= USB11_ADDRESS_MAX);
    203 
    204         return instance->devices[address].speed;
     203        if (speed != NULL) {
     204                *speed = instance->devices[address].speed;
     205        }
     206
     207        fibril_mutex_unlock(&instance->guard);
     208        return EOK;
    205209}
    206210/**
  • uspace/lib/usbhost/src/usb_endpoint_manager.c

    r4c3ad56 r20a3465  
    3434#include <usb/host/usb_endpoint_manager.h>
    3535
    36 #define BUCKET_COUNT 7
    37 
    38 #define MAX_KEYS (3)
    39 typedef struct {
    40         link_t link;
    41         size_t bw;
    42         endpoint_t *ep;
    43 } node_t;
    44 /*----------------------------------------------------------------------------*/
    45 static hash_index_t node_hash(unsigned long key[])
    46 {
    47         /* USB endpoints use 4 bits, thus ((key[0] << 4) | key[1])
    48          * produces unique value for every address.endpoint pair */
    49         return ((key[0] << 4) | key[1]) % BUCKET_COUNT;
    50 }
    51 /*----------------------------------------------------------------------------*/
    52 static int node_compare(unsigned long key[], hash_count_t keys, link_t *item)
    53 {
    54         assert(item);
    55         node_t *node = hash_table_get_instance(item, node_t, link);
    56         assert(node);
    57         assert(node->ep);
    58         bool match = true;
    59         switch (keys) {
    60         case 3:
    61                 match = match &&
    62                     ((key[2] == node->ep->direction)
    63                     || (node->ep->direction == USB_DIRECTION_BOTH));
    64         case 2:
    65                 match = match && (key[1] == (unsigned long)node->ep->endpoint);
    66         case 1:
    67                 match = match && (key[0] == (unsigned long)node->ep->address);
    68                 break;
    69         default:
    70                 match = false;
    71         }
    72         return match;
    73 }
    74 /*----------------------------------------------------------------------------*/
    75 static void node_remove(link_t *item)
    76 {
    77         assert(item);
    78         node_t *node = hash_table_get_instance(item, node_t, link);
    79         endpoint_destroy(node->ep);
    80         free(node);
    81 }
    82 /*----------------------------------------------------------------------------*/
    83 static void node_toggle_reset_filtered(link_t *item, void *arg)
    84 {
    85         assert(item);
    86         node_t *node = hash_table_get_instance(item, node_t, link);
    87         usb_target_t *target = arg;
    88         endpoint_toggle_reset_filtered(node->ep, *target);
    89 }
    90 /*----------------------------------------------------------------------------*/
    91 static hash_table_operations_t op = {
    92         .hash = node_hash,
    93         .compare = node_compare,
    94         .remove_callback = node_remove,
    95 };
    96 /*----------------------------------------------------------------------------*/
     36/** Endpoint compare helper function.
     37 *
     38 * USB_DIRECTION_BOTH matches both IN and OUT.
     39 * @param ep Endpoint to compare, non-null.
     40 * @param address Tested address.
     41 * @param endpoint Tested endpoint number.
     42 * @param direction Tested direction.
     43 * @return True if ep can be used to communicate with given device,
     44 * false otherwise.
     45 */
     46static inline bool ep_match(const endpoint_t *ep,
     47    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction)
     48{
     49        assert(ep);
     50        return
     51            ((direction == ep->direction)
     52                || (ep->direction == USB_DIRECTION_BOTH)
     53                || (direction == USB_DIRECTION_BOTH))
     54            && (endpoint == ep->endpoint)
     55            && (address == ep->address);
     56}
     57/*----------------------------------------------------------------------------*/
     58/** Get list that holds endpints for given address.
     59 * @param instance usb_endpoint_manager structure, non-null.
     60 * @param addr USB address, must be >= 0.
     61 * @return Pointer to the appropriate list.
     62 */
     63static list_t * get_list(usb_endpoint_manager_t *instance, usb_address_t addr)
     64{
     65        assert(instance);
     66        assert(addr >= 0);
     67        return &instance->endpoint_lists[addr % ENDPOINT_LIST_COUNT];
     68}
     69/*----------------------------------------------------------------------------*/
     70/** Internal search function, works on locked structure.
     71 * @param instance usb_endpoint_manager structure, non-null.
     72 * @param address USB address, must be valid.
     73 * @param endpoint USB endpoint number.
     74 * @param direction Communication direction.
     75 * @return Pointer to endpoint_t structure representing given communication
     76 * target, NULL if there is no such endpoint registered.
     77 */
     78static endpoint_t * find_locked(usb_endpoint_manager_t *instance,
     79    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction)
     80{
     81        assert(instance);
     82        assert(fibril_mutex_is_locked(&instance->guard));
     83        if (address < 0)
     84                return NULL;
     85        list_foreach(*get_list(instance, address), iterator) {
     86                endpoint_t *ep = endpoint_get_instance(iterator);
     87                if (ep_match(ep, address, endpoint, direction))
     88                        return ep;
     89        }
     90        return NULL;
     91}
     92/*----------------------------------------------------------------------------*/
     93/** Calculate bandwidth that needs to be reserved for communication with EP.
     94 * Calculation follows USB 1.1 specification.
     95 * @param speed Device's speed.
     96 * @param type Type of the transfer.
     97 * @param size Number of byte to transfer.
     98 * @param max_packet_size Maximum bytes in one packet.
     99 */
    97100size_t bandwidth_count_usb11(usb_speed_t speed, usb_transfer_type_t type,
    98101    size_t size, size_t max_packet_size)
     
    106109        const unsigned packet_count =
    107110            (size + max_packet_size - 1) / max_packet_size;
    108         /* TODO: It may be that ISO and INT transfers use only one data packet
    109          * per transaction, but I did not find text in UB spec that confirms
    110          * this */
     111        /* TODO: It may be that ISO and INT transfers use only one packet per
     112         * transaction, but I did not find text in USB spec to confirm this */
    111113        /* NOTE: All data packets will be considered to be max_packet_size */
    112114        switch (speed)
     
    137139}
    138140/*----------------------------------------------------------------------------*/
     141/** Initialize to default state.
     142 * You need to provide valid bw_count function if you plan to use
     143 * add_endpoint/remove_endpoint pair.
     144 *
     145 * @param instance usb_endpoint_manager structure, non-null.
     146 * @param available_bandwidth Size of the bandwidth pool.
     147 * @param bw_count function to use to calculate endpoint bw requirements.
     148 * @return Error code.
     149 */
    139150int usb_endpoint_manager_init(usb_endpoint_manager_t *instance,
    140151    size_t available_bandwidth,
     
    145156        instance->free_bw = available_bandwidth;
    146157        instance->bw_count = bw_count;
    147         const bool ht =
    148             hash_table_create(&instance->ep_table, BUCKET_COUNT, MAX_KEYS, &op);
    149         return ht ? EOK : ENOMEM;
    150 }
    151 /*----------------------------------------------------------------------------*/
    152 void usb_endpoint_manager_destroy(usb_endpoint_manager_t *instance)
    153 {
    154         hash_table_destroy(&instance->ep_table);
    155 }
    156 /*----------------------------------------------------------------------------*/
    157 int usb_endpoint_manager_register_ep(usb_endpoint_manager_t *instance,
    158     endpoint_t *ep, size_t data_size)
    159 {
    160         assert(instance);
    161         assert(instance->bw_count);
    162         assert(ep);
    163         const size_t bw = instance->bw_count(ep->speed, ep->transfer_type,
    164             data_size, ep->max_packet_size);
    165 
    166         fibril_mutex_lock(&instance->guard);
    167 
    168         if (bw > instance->free_bw) {
    169                 fibril_mutex_unlock(&instance->guard);
    170                 return ENOSPC;
    171         }
    172 
    173         unsigned long key[MAX_KEYS] =
    174             {ep->address, ep->endpoint, ep->direction};
    175 
    176         const link_t *item =
    177             hash_table_find(&instance->ep_table, key);
    178         if (item != NULL) {
    179                 fibril_mutex_unlock(&instance->guard);
    180                 return EEXISTS;
    181         }
    182 
    183         node_t *node = malloc(sizeof(node_t));
    184         if (node == NULL) {
    185                 fibril_mutex_unlock(&instance->guard);
    186                 return ENOMEM;
    187         }
    188 
    189         node->bw = bw;
    190         node->ep = ep;
    191         link_initialize(&node->link);
    192 
    193         hash_table_insert(&instance->ep_table, key, &node->link);
    194         instance->free_bw -= bw;
    195         fibril_mutex_unlock(&instance->guard);
    196         return EOK;
    197 }
    198 /*----------------------------------------------------------------------------*/
    199 int usb_endpoint_manager_unregister_ep(usb_endpoint_manager_t *instance,
    200     usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction)
    201 {
    202         assert(instance);
    203         unsigned long key[MAX_KEYS] = {address, endpoint, direction};
    204 
    205         fibril_mutex_lock(&instance->guard);
    206         link_t *item = hash_table_find(&instance->ep_table, key);
    207         if (item == NULL) {
    208                 fibril_mutex_unlock(&instance->guard);
    209                 return EINVAL;
    210         }
    211 
    212         node_t *node = hash_table_get_instance(item, node_t, link);
    213         if (node->ep->active) {
    214                 fibril_mutex_unlock(&instance->guard);
    215                 return EBUSY;
    216         }
    217 
    218         instance->free_bw += node->bw;
    219         hash_table_remove(&instance->ep_table, key, MAX_KEYS);
    220 
    221         fibril_mutex_unlock(&instance->guard);
    222         return EOK;
    223 }
    224 /*----------------------------------------------------------------------------*/
    225 endpoint_t * usb_endpoint_manager_get_ep(usb_endpoint_manager_t *instance,
    226     usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
    227     size_t *bw)
    228 {
    229         assert(instance);
    230         unsigned long key[MAX_KEYS] = {address, endpoint, direction};
    231 
    232         fibril_mutex_lock(&instance->guard);
    233         const link_t *item = hash_table_find(&instance->ep_table, key);
    234         if (item == NULL) {
    235                 fibril_mutex_unlock(&instance->guard);
    236                 return NULL;
    237         }
    238         const node_t *node = hash_table_get_instance(item, node_t, link);
    239         if (bw)
    240                 *bw = node->bw;
    241 
    242         fibril_mutex_unlock(&instance->guard);
    243         return node->ep;
     158        for (unsigned i = 0; i < ENDPOINT_LIST_COUNT; ++i) {
     159                list_initialize(&instance->endpoint_lists[i]);
     160        }
     161        return EOK;
    244162}
    245163/*----------------------------------------------------------------------------*/
    246164/** Check setup packet data for signs of toggle reset.
    247165 *
    248  * @param[in] instance Device keeper structure to use.
     166 * @param[in] instance usb_endpoint_manager structure, non-null.
    249167 * @param[in] target Device to receive setup packet.
    250168 * @param[in] data Setup packet data.
    251169 *
    252  * Really ugly one.
    253  */
    254 void usb_endpoint_manager_reset_if_need(
    255     usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data)
     170 * Really ugly one. Resets toggle bit on all endpoints that need it.
     171 */
     172void usb_endpoint_manager_reset_eps_if_need(usb_endpoint_manager_t *instance,
     173    usb_target_t target, const uint8_t data[8])
    256174{
    257175        assert(instance);
     
    267185                /* Recipient is endpoint, value is zero (ENDPOINT_STALL) */
    268186                if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {
     187                        fibril_mutex_lock(&instance->guard);
    269188                        /* endpoint number is < 16, thus first byte is enough */
    270                         usb_target_t reset_target =
    271                             { .address = target.address, data[4] };
    272                         fibril_mutex_lock(&instance->guard);
    273                         hash_table_apply(&instance->ep_table,
    274                             node_toggle_reset_filtered, &reset_target);
     189                        list_foreach(*get_list(instance, target.address), it) {
     190                                endpoint_t *ep = endpoint_get_instance(it);
     191                                if ((ep->address == target.address)
     192                                    && (ep->endpoint = data[4])) {
     193                                        endpoint_toggle_set(ep,0);
     194                                }
     195                        }
    275196                        fibril_mutex_unlock(&instance->guard);
    276197                }
     
    279200        case 0x9: /* Set Configuration */
    280201        case 0x11: /* Set Interface */
    281                 /* Recipient must be device */
     202                /* Recipient must be device, this resets all endpoints,
     203                 * In fact there should be no endpoints but EP 0 registered
     204                 * as different interfaces use different endpoints. */
    282205                if ((data[0] & 0xf) == 0) {
    283                         usb_target_t reset_target =
    284                             { .address = target.address, 0 };
    285206                        fibril_mutex_lock(&instance->guard);
    286                         hash_table_apply(&instance->ep_table,
    287                             node_toggle_reset_filtered, &reset_target);
     207                        list_foreach(*get_list(instance, target.address), it) {
     208                                endpoint_t *ep = endpoint_get_instance(it);
     209                                if (ep->address == target.address) {
     210                                        endpoint_toggle_set(ep,0);
     211                                }
     212                        }
    288213                        fibril_mutex_unlock(&instance->guard);
    289214                }
     
    291216        }
    292217}
     218/*----------------------------------------------------------------------------*/
     219/** Register endpoint structure.
     220 * Checks for duplicates.
     221 * @param instance usb_endpoint_manager, non-null.
     222 * @param ep endpoint_t to register.
     223 * @param data_size Size of data to transfer.
     224 * @return Error code.
     225 */
     226int usb_endpoint_manager_register_ep(usb_endpoint_manager_t *instance,
     227    endpoint_t *ep, size_t data_size)
     228{
     229        assert(instance);
     230        if (ep == NULL || ep->address < 0)
     231                return EINVAL;
     232
     233        fibril_mutex_lock(&instance->guard);
     234        /* Check for available bandwidth */
     235        if (ep->bandwidth > instance->free_bw) {
     236                fibril_mutex_unlock(&instance->guard);
     237                return ENOSPC;
     238        }
     239
     240        /* Check for existence */
     241        const endpoint_t *endpoint =
     242            find_locked(instance, ep->address, ep->endpoint, ep->direction);
     243        if (endpoint != NULL) {
     244                fibril_mutex_unlock(&instance->guard);
     245                return EEXISTS;
     246        }
     247        list_append(&ep->link, get_list(instance, ep->address));
     248
     249        instance->free_bw -= ep->bandwidth;
     250        fibril_mutex_unlock(&instance->guard);
     251        return EOK;
     252}
     253/*----------------------------------------------------------------------------*/
     254/** Unregister endpoint structure.
     255 * Checks for duplicates.
     256 * @param instance usb_endpoint_manager, non-null.
     257 * @param ep endpoint_t to unregister.
     258 * @return Error code.
     259 */
     260int usb_endpoint_manager_unregister_ep(
     261    usb_endpoint_manager_t *instance, endpoint_t *ep)
     262{
     263        assert(instance);
     264        if (ep == NULL || ep->address < 0)
     265                return EINVAL;
     266
     267        fibril_mutex_lock(&instance->guard);
     268        if (!list_member(&ep->link, get_list(instance, ep->address))) {
     269                fibril_mutex_unlock(&instance->guard);
     270                return ENOENT;
     271        }
     272        list_remove(&ep->link);
     273        instance->free_bw += ep->bandwidth;
     274        fibril_mutex_unlock(&instance->guard);
     275        return EOK;
     276}
     277/*----------------------------------------------------------------------------*/
     278/** Find endpoint_t representing the given communication route.
     279 * @param instance usb_endpoint_manager, non-null.
     280 * @param address
     281 */
     282endpoint_t * usb_endpoint_manager_find_ep(usb_endpoint_manager_t *instance,
     283    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction)
     284{
     285        assert(instance);
     286
     287        fibril_mutex_lock(&instance->guard);
     288        endpoint_t *ep = find_locked(instance, address, endpoint, direction);
     289        fibril_mutex_unlock(&instance->guard);
     290        return ep;
     291}
     292/*----------------------------------------------------------------------------*/
     293/** Create and register new endpoint_t structure.
     294 * @param instance usb_endpoint_manager structure, non-null.
     295 * @param address USB address.
     296 * @param endpoint USB endpoint number.
     297 * @param direction Communication direction.
     298 * @param type USB transfer type.
     299 * @param speed USB Communication speed.
     300 * @param max_packet_size Maximum size of data packets.
     301 * @param data_size Expected communication size.
     302 * @param callback function to call just after registering.
     303 * @param arg Argument to pass to the callback function.
     304 * @return Error code.
     305 */
     306int usb_endpoint_manager_add_ep(usb_endpoint_manager_t *instance,
     307    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
     308    usb_transfer_type_t type, usb_speed_t speed, size_t max_packet_size,
     309    size_t data_size, int (*callback)(endpoint_t *, void *), void *arg)
     310{
     311        assert(instance);
     312        if (instance->bw_count == NULL)
     313                return ENOTSUP;
     314        if (address < 0)
     315                return EINVAL;
     316
     317        const size_t bw =
     318            instance->bw_count(speed, type, data_size, max_packet_size);
     319
     320        fibril_mutex_lock(&instance->guard);
     321        /* Check for available bandwidth */
     322        if (bw > instance->free_bw) {
     323                fibril_mutex_unlock(&instance->guard);
     324                return ENOSPC;
     325        }
     326
     327        /* Check for existence */
     328        endpoint_t *ep = find_locked(instance, address, endpoint, direction);
     329        if (ep != NULL) {
     330                fibril_mutex_unlock(&instance->guard);
     331                return EEXISTS;
     332        }
     333
     334        ep = endpoint_create(
     335            address, endpoint, direction, type, speed, max_packet_size, bw);
     336        if (!ep) {
     337                fibril_mutex_unlock(&instance->guard);
     338                return ENOMEM;
     339        }
     340
     341        if (callback) {
     342                const int ret = callback(ep, arg);
     343                if (ret != EOK) {
     344                        fibril_mutex_unlock(&instance->guard);
     345                        endpoint_destroy(ep);
     346                        return ret;
     347                }
     348        }
     349        list_append(&ep->link, get_list(instance, ep->address));
     350
     351        instance->free_bw -= ep->bandwidth;
     352        fibril_mutex_unlock(&instance->guard);
     353        return EOK;
     354}
     355/*----------------------------------------------------------------------------*/
     356/** Unregister and destroy endpoint_t structure representing given route.
     357 * @param instance usb_endpoint_manager structure, non-null.
     358 * @param address USB address.
     359 * @param endpoint USB endpoint number.
     360 * @param direction Communication direction.
     361 * @param callback Function to call after unregister, before destruction.
     362 * @arg Argument to pass to the callback function.
     363 * @return Error code.
     364 */
     365int usb_endpoint_manager_remove_ep(usb_endpoint_manager_t *instance,
     366    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
     367    void (*callback)(endpoint_t *, void *), void *arg)
     368{
     369        assert(instance);
     370        fibril_mutex_lock(&instance->guard);
     371        endpoint_t *ep = find_locked(instance, address, endpoint, direction);
     372        if (ep != NULL) {
     373                list_remove(&ep->link);
     374                instance->free_bw += ep->bandwidth;
     375        }
     376        fibril_mutex_unlock(&instance->guard);
     377        if (ep == NULL)
     378                return ENOENT;
     379
     380        if (callback) {
     381                callback(ep, arg);
     382        }
     383        endpoint_destroy(ep);
     384        return EOK;
     385}
  • uspace/lib/usbhost/src/usb_transfer_batch.c

    r4c3ad56 r20a3465  
    3737#include <usb/usb.h>
    3838#include <usb/debug.h>
     39
    3940#include <usb/host/usb_transfer_batch.h>
    4041#include <usb/host/hcd.h>
    4142
    42 usb_transfer_batch_t * usb_transfer_batch_get(
     43/** Allocate and initialize usb_transfer_batch structure.
     44 * @param ep endpoint used by the transfer batch.
     45 * @param buffer data to send/recieve.
     46 * @param buffer_size Size of data buffer.
     47 * @param setup_buffer Data to send in SETUP stage of control transfer.
     48 * @param func_in callback on IN transfer completion.
     49 * @param func_out callback on OUT transfer completion.
     50 * @param arg Argument to pass to the callback function.
     51 * @param private_data driver specific per batch data.
     52 * @param private_data_dtor Function to properly destroy private_data.
     53 * @return Pointer to valid usb_transfer_batch_t structure, NULL on failure.
     54 */
     55usb_transfer_batch_t * usb_transfer_batch_create(
    4356    endpoint_t *ep,
    4457    char *buffer,
     
    5366    )
    5467{
     68        if (func_in == NULL && func_out == NULL)
     69                return NULL;
     70        if (func_in != NULL && func_out != NULL)
     71                return NULL;
     72
    5573        usb_transfer_batch_t *instance = malloc(sizeof(usb_transfer_batch_t));
    5674        if (instance) {
     
    7896}
    7997/*----------------------------------------------------------------------------*/
    80 /** Mark batch as finished and run callback.
    81  *
    82  * @param[in] instance Batch structure to use.
    83  * @param[in] data Data to copy to the output buffer.
    84  * @param[in] size Size of @p data.
    85  */
    86 void usb_transfer_batch_finish(
    87     usb_transfer_batch_t *instance, const void *data, size_t size)
    88 {
    89         assert(instance);
    90         assert(instance->ep);
    91         /* we care about the data and there are some to copy */
    92         if (instance->ep->direction != USB_DIRECTION_OUT
    93             && data) {
    94                 const size_t min_size =
    95                     size < instance->buffer_size ? size : instance->buffer_size;
    96                 memcpy(instance->buffer, data, min_size);
    97         }
    98         if (instance->callback_out)
    99                 usb_transfer_batch_call_out(instance);
    100         if (instance->callback_in)
    101                 usb_transfer_batch_call_in(instance);
    102 
    103 }
    104 /*----------------------------------------------------------------------------*/
    105 /** Prepare data, get error status and call callback in.
    106  *
    107  * @param[in] instance Batch structure to use.
    108  * Copies data from transport buffer, and calls callback with appropriate
    109  * parameters.
    110  */
    111 void usb_transfer_batch_call_in(usb_transfer_batch_t *instance)
    112 {
    113         assert(instance);
    114         assert(instance->callback_in);
    115 
    116         usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " completed (%zuB): %s.\n",
    117             instance, USB_TRANSFER_BATCH_ARGS(*instance),
    118             instance->transfered_size, str_error(instance->error));
    119 
    120         instance->callback_in(instance->fun, instance->error,
    121             instance->transfered_size, instance->arg);
    122 }
    123 /*----------------------------------------------------------------------------*/
    124 /** Get error status and call callback out.
    125  *
    126  * @param[in] instance Batch structure to use.
    127  */
    128 void usb_transfer_batch_call_out(usb_transfer_batch_t *instance)
    129 {
    130         assert(instance);
    131         assert(instance->callback_out);
    132 
    133         usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " completed: %s.\n",
    134             instance, USB_TRANSFER_BATCH_ARGS(*instance),
    135             str_error(instance->error));
    136 
    137         if (instance->ep->transfer_type == USB_TRANSFER_CONTROL
    138             && instance->error == EOK) {
    139                 const usb_target_t target =
    140                     {{ instance->ep->address, instance->ep->endpoint }};
    141                 reset_ep_if_need(
    142                     fun_to_hcd(instance->fun), target, instance->setup_buffer);
    143         }
    144 
    145         instance->callback_out(instance->fun,
    146             instance->error, instance->arg);
    147 }
    148 /*----------------------------------------------------------------------------*/
    14998/** Correctly dispose all used data structures.
    15099 *
    151100 * @param[in] instance Batch structure to use.
    152101 */
    153 void usb_transfer_batch_dispose(usb_transfer_batch_t *instance)
     102void usb_transfer_batch_destroy(const usb_transfer_batch_t *instance)
    154103{
    155104        if (!instance)
     
    166115        free(instance);
    167116}
     117/*----------------------------------------------------------------------------*/
     118/** Prepare data and call the right callback.
     119 *
     120 * @param[in] instance Batch structure to use.
     121 * @param[in] data Data to copy to the output buffer.
     122 * @param[in] size Size of @p data.
     123 */
     124void usb_transfer_batch_finish(
     125    const usb_transfer_batch_t *instance, const void *data, size_t size)
     126{
     127        assert(instance);
     128        usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " finishing.\n",
     129            instance, USB_TRANSFER_BATCH_ARGS(*instance));
     130
     131        /* NOTE: Only one of these pointers should be set. */
     132        if (instance->callback_out) {
     133                /* Check for commands that reset toggle bit */
     134                if (instance->ep->transfer_type == USB_TRANSFER_CONTROL
     135                    && instance->error == EOK) {
     136                        const usb_target_t target =
     137                            {{ instance->ep->address, instance->ep->endpoint }};
     138                        reset_ep_if_need(fun_to_hcd(instance->fun), target,
     139                            instance->setup_buffer);
     140                }
     141                instance->callback_out(instance->fun,
     142                    instance->error, instance->arg);
     143        }
     144
     145        if (instance->callback_in) {
     146                /* We care about the data and there are some to copy */
     147                if (data) {
     148                        const size_t min_size = size < instance->buffer_size
     149                            ? size : instance->buffer_size;
     150                        memcpy(instance->buffer, data, min_size);
     151                }
     152                instance->callback_in(instance->fun, instance->error,
     153                    instance->transfered_size, instance->arg);
     154        }
     155}
    168156/**
    169157 * @}
Note: See TracChangeset for help on using the changeset viewer.