Changeset b4b534ac in mainline for uspace/lib/usbdev/src


Ignore:
Timestamp:
2016-07-22T08:24:47Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f76d2c2
Parents:
5b18137 (diff), 8351f9a4 (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 from lp:~jan.vesely/helenos/usb

Location:
uspace/lib/usbdev/src
Files:
1 added
1 deleted
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbdev/src/altiface.c

    r5b18137 rb4b534ac  
    3434 */
    3535
    36 #include <usb/dev/driver.h>
    37 #include <usb/dev/request.h>
    38 #include <usb/debug.h>
     36#include <usb/dev/alternate_ifaces.h>
    3937#include <usb/dev/dp.h>
     38#include <assert.h>
    4039#include <errno.h>
    41 #include <str_error.h>
    42 #include <assert.h>
     40#include <stdlib.h>
    4341
    4442/** Count number of alternate settings of a interface.
     
    105103        }
    106104
    107         alternates->alternative_count
    108             = usb_interface_count_alternates(config_descr, config_descr_size,
    109                 interface_number);
     105        const size_t alt_count = usb_interface_count_alternates(config_descr,
     106            config_descr_size, interface_number);
    110107
    111         if (alternates->alternative_count == 0) {
     108        if (alt_count == 0) {
    112109                return ENOENT;
    113110        }
    114111
    115         alternates->alternatives = calloc(alternates->alternative_count,
     112        usb_alternate_interface_descriptors_t *alts = calloc(alt_count,
    116113            sizeof(usb_alternate_interface_descriptors_t));
    117         if (alternates->alternatives == NULL) {
     114        if (alts == NULL) {
    118115                return ENOMEM;
    119116        }
     
    128125        };
    129126
    130         usb_alternate_interface_descriptors_t *iterator
    131             = &alternates->alternatives[0];
    132 
    133         const usb_alternate_interface_descriptors_t *end
    134             = &alternates->alternatives[alternates->alternative_count];
    135127
    136128        const void *iface_ptr =
    137129            usb_dp_get_nested_descriptor(&dp_parser, &dp_data, dp_data.data);
    138130
    139         while (iface_ptr != NULL && iterator < end) {
     131        usb_alternate_interface_descriptors_t *iterator = alts;
     132        for (; iface_ptr != NULL && iterator < &alts[alt_count]; ++iterator) {
    140133                const usb_standard_interface_descriptor_t *iface = iface_ptr;
    141134
     
    159152                    dp_data.data + dp_data.size : iface_ptr;
    160153
    161                 iterator->nested_descriptors_size
    162                     = next - iterator->nested_descriptors;
     154                iterator->nested_descriptors_size =
     155                    next - iterator->nested_descriptors;
     156        }
    163157
    164                 ++iterator;
    165         }
     158        alternates->alternatives = alts;
     159        alternates->alternative_count = alt_count;
    166160
    167161        return EOK;
  • uspace/lib/usbdev/src/devdrv.c

    r5b18137 rb4b534ac  
    3333 * USB device driver framework.
    3434 */
    35 #include <usb/dev/driver.h>
     35
     36#include <usb_iface.h>
     37#include <usb/dev/alternate_ifaces.h>
     38#include <usb/dev/device.h>
     39#include <usb/dev/pipes.h>
    3640#include <usb/dev/request.h>
    3741#include <usb/debug.h>
    38 #include <usb/dev.h>
     42#include <usb/descriptor.h>
     43#include <usb/usb.h>
     44
     45#include <assert.h>
     46#include <async.h>
     47#include <devman.h>
    3948#include <errno.h>
    40 #include <str_error.h>
    41 #include <assert.h>
    42 
    43 static int generic_device_add(ddf_dev_t *);
    44 static int generic_device_remove(ddf_dev_t *);
    45 static int generic_device_gone(ddf_dev_t *);
    46 
    47 static driver_ops_t generic_driver_ops = {
    48         .dev_add = generic_device_add,
    49         .dev_remove = generic_device_remove,
    50         .dev_gone = generic_device_gone,
    51 };
    52 static driver_t generic_driver = {
    53         .driver_ops = &generic_driver_ops
    54 };
    55 
    56 static const usb_driver_t *driver = NULL;
    57 
    58 /** Main routine of USB device driver.
    59  *
    60  * Under normal conditions, this function never returns.
    61  *
    62  * @param drv USB device driver structure.
    63  * @return Task exit status.
    64  */
    65 int usb_driver_main(const usb_driver_t *drv)
    66 {
    67         assert(drv != NULL);
    68 
    69         /* Prepare the generic driver. */
    70         generic_driver.name = drv->name;
    71 
    72         driver = drv;
    73 
    74         return ddf_driver_main(&generic_driver);
    75 }
     49#include <stdlib.h>
     50
     51#include <ddf/driver.h>
     52
     53/** USB device structure. */
     54typedef struct usb_device {
     55        /** Connection to device on USB bus */
     56        usb_dev_session_t *bus_session;
     57        /** devman handle */
     58        devman_handle_t handle;
     59        /** The default control pipe. */
     60        usb_pipe_t ctrl_pipe;
     61
     62        /** Other endpoint pipes.
     63         * This is an array of other endpoint pipes in the same order as
     64         * in usb_driver_t.
     65         */
     66        usb_endpoint_mapping_t *pipes;
     67        /** Number of other endpoint pipes. */
     68        size_t pipes_count;
     69        /** Current interface.
     70         * Usually, drivers operate on single interface only.
     71         * This item contains the value of the interface or -1 for any.
     72         */
     73        int interface_no;
     74        /** Alternative interfaces. */
     75        usb_alternate_interfaces_t alternate_interfaces;
     76        /** Some useful descriptors for USB device. */
     77        usb_device_descriptors_t descriptors;
     78        /** Generic DDF device backing this one. DO NOT TOUCH! */
     79        ddf_dev_t *ddf_dev;
     80        /** Custom driver data.
     81         * Do not use the entry in generic device, that is already used
     82         * by the framework.
     83         */
     84        void *driver_data;
     85
     86} usb_device_t;
    7687
    7788/** Count number of pipes the driver expects.
     
    8091 * @return Number of pipes (excluding default control pipe).
    8192 */
    82 static inline size_t count_other_pipes(
    83     const usb_endpoint_description_t **endpoints)
     93static inline size_t count_pipes(const usb_endpoint_description_t **endpoints)
    8494{
    8595        size_t count;
    8696        for (count = 0; endpoints != NULL && endpoints[count] != NULL; ++count);
    8797        return count;
    88 }
    89 
    90 /** Callback when a new device is supposed to be controlled by this driver.
    91  *
    92  * This callback is a wrapper for USB specific version of @c device_add.
    93  *
    94  * @param gen_dev Device structure as prepared by DDF.
    95  * @return Error code.
    96  */
    97 int generic_device_add(ddf_dev_t *gen_dev)
    98 {
    99         assert(driver);
    100         assert(driver->ops);
    101         assert(driver->ops->device_add);
    102 
    103         /* Get place for driver data. */
    104         usb_device_t *dev = ddf_dev_data_alloc(gen_dev, sizeof(usb_device_t));
    105         if (dev == NULL) {
    106                 usb_log_error("USB device `%s' structure allocation failed.\n",
    107                     ddf_dev_get_name(gen_dev));
    108                 return ENOMEM;
    109         }
    110 
    111         /* Initialize generic USB driver data. */
    112         const char *err_msg = NULL;
    113         int rc = usb_device_init(dev, gen_dev, driver->endpoints, &err_msg);
    114         if (rc != EOK) {
    115                 usb_log_error("USB device `%s' init failed (%s): %s.\n",
    116                     ddf_dev_get_name(gen_dev), err_msg, str_error(rc));
    117                 return rc;
    118         }
    119 
    120         /* Start USB driver specific initialization. */
    121         rc = driver->ops->device_add(dev);
    122         if (rc != EOK)
    123                 usb_device_deinit(dev);
    124         return rc;
    125 }
    126 
    127 /** Callback when a device is supposed to be removed from the system.
    128  *
    129  * This callback is a wrapper for USB specific version of @c device_remove.
    130  *
    131  * @param gen_dev Device structure as prepared by DDF.
    132  * @return Error code.
    133  */
    134 int generic_device_remove(ddf_dev_t *gen_dev)
    135 {
    136         assert(driver);
    137         assert(driver->ops);
    138         if (driver->ops->device_rem == NULL)
    139                 return ENOTSUP;
    140         /* Just tell the driver to stop whatever it is doing */
    141         usb_device_t *usb_dev = ddf_dev_data_get(gen_dev);
    142         const int ret = driver->ops->device_rem(usb_dev);
    143         if (ret != EOK)
    144                 return ret;
    145         usb_device_deinit(usb_dev);
    146         return EOK;
    147 }
    148 
    149 /** Callback when a device was removed from the system.
    150  *
    151  * This callback is a wrapper for USB specific version of @c device_gone.
    152  *
    153  * @param gen_dev Device structure as prepared by DDF.
    154  * @return Error code.
    155  */
    156 int generic_device_gone(ddf_dev_t *gen_dev)
    157 {
    158         assert(driver);
    159         assert(driver->ops);
    160         if (driver->ops->device_gone == NULL)
    161                 return ENOTSUP;
    162         usb_device_t *usb_dev = ddf_dev_data_get(gen_dev);
    163         const int ret = driver->ops->device_gone(usb_dev);
    164         if (ret == EOK)
    165                 usb_device_deinit(usb_dev);
    166 
    167         return ret;
    168 }
    169 
    170 /** Destroy existing pipes of a USB device.
    171  *
    172  * @param dev Device where to destroy the pipes.
    173  */
    174 static void destroy_current_pipes(usb_device_t *dev)
    175 {
    176         usb_device_destroy_pipes(dev->pipes, dev->pipes_count);
    177         dev->pipes = NULL;
    178         dev->pipes_count = 0;
    17998}
    18099
     
    201120 * @return Error code.
    202121 */
    203 int usb_device_select_interface(usb_device_t *dev, uint8_t alternate_setting,
    204     const usb_endpoint_description_t **endpoints)
    205 {
    206         if (dev->interface_no < 0) {
     122int usb_device_select_interface(usb_device_t *usb_dev,
     123    uint8_t alternate_setting, const usb_endpoint_description_t **endpoints)
     124{
     125        assert(usb_dev);
     126
     127        if (usb_dev->interface_no < 0) {
    207128                return EINVAL;
    208129        }
    209130
    210         /* Destroy existing pipes. */
    211         destroy_current_pipes(dev);
    212 
    213131        /* Change the interface itself. */
    214         int rc = usb_request_set_interface(&dev->ctrl_pipe, dev->interface_no,
    215             alternate_setting);
     132        int rc = usb_request_set_interface(&usb_dev->ctrl_pipe,
     133            usb_dev->interface_no, alternate_setting);
    216134        if (rc != EOK) {
    217135                return rc;
    218136        }
    219137
     138        /* Change current alternative */
     139        usb_dev->alternate_interfaces.current = alternate_setting;
     140
     141        /* Destroy existing pipes. */
     142        usb_device_destroy_pipes(usb_dev);
     143
    220144        /* Create new pipes. */
    221         rc = usb_device_create_pipes(&dev->wire, endpoints,
    222             dev->descriptors.configuration, dev->descriptors.configuration_size,
    223             dev->interface_no, (int)alternate_setting,
    224             &dev->pipes, &dev->pipes_count);
     145        rc = usb_device_create_pipes(usb_dev, endpoints);
    225146
    226147        return rc;
     
    233154 * @return Error code.
    234155 */
    235 int usb_device_retrieve_descriptors(usb_pipe_t *ctrl_pipe,
    236     usb_device_descriptors_t *descriptors)
    237 {
    238         assert(descriptors != NULL);
    239 
    240         descriptors->configuration = NULL;
    241 
    242         int rc;
    243 
    244         /* It is worth to start a long transfer. */
    245         usb_pipe_start_long_transfer(ctrl_pipe);
     156static int usb_device_retrieve_descriptors(usb_device_t *usb_dev)
     157{
     158        assert(usb_dev);
     159        assert(usb_dev->descriptors.full_config == NULL);
    246160
    247161        /* Get the device descriptor. */
    248         rc = usb_request_get_device_descriptor(ctrl_pipe, &descriptors->device);
     162        int rc = usb_request_get_device_descriptor(&usb_dev->ctrl_pipe,
     163            &usb_dev->descriptors.device);
    249164        if (rc != EOK) {
    250                 goto leave;
     165                return rc;
    251166        }
    252167
    253168        /* Get the full configuration descriptor. */
    254169        rc = usb_request_get_full_configuration_descriptor_alloc(
    255             ctrl_pipe, 0, (void **) &descriptors->configuration,
    256             &descriptors->configuration_size);
    257 
    258 leave:
    259         usb_pipe_end_long_transfer(ctrl_pipe);
     170            &usb_dev->ctrl_pipe, 0,
     171            &usb_dev->descriptors.full_config,
     172            &usb_dev->descriptors.full_config_size);
     173
    260174
    261175        return rc;
     
    266180 * @param[in] descriptors Where to store the descriptors.
    267181 */
    268 void usb_device_release_descriptors(usb_device_descriptors_t *descriptors)
    269 {
    270         assert(descriptors);
    271         free(descriptors->configuration);
    272         descriptors->configuration = NULL;
     182static void usb_device_release_descriptors(usb_device_t *usb_dev)
     183{
     184        assert(usb_dev);
     185        free(usb_dev->descriptors.full_config);
     186        usb_dev->descriptors.full_config = NULL;
     187        usb_dev->descriptors.full_config_size = 0;
    273188}
    274189
     
    280195 * - registers endpoints with the host controller
    281196 *
    282  * @param[in] wire Initialized backing connection to the host controller.
    283197 * @param[in] endpoints Endpoints description, NULL terminated.
    284198 * @param[in] config_descr Configuration descriptor of active configuration.
     
    292206 * @return Error code.
    293207 */
    294 int usb_device_create_pipes(usb_device_connection_t *wire,
    295     const usb_endpoint_description_t **endpoints,
    296     const uint8_t *config_descr, size_t config_descr_size,
    297     int interface_no, int interface_setting,
    298     usb_endpoint_mapping_t **pipes_ptr, size_t *pipes_count_ptr)
    299 {
    300         assert(wire != NULL);
    301         assert(config_descr != NULL);
    302         assert(config_descr_size > 0);
    303         assert(pipes_ptr != NULL);
    304 
    305         size_t i;
    306         int rc;
    307 
    308         const size_t pipe_count = count_other_pipes(endpoints);
     208int usb_device_create_pipes(usb_device_t *usb_dev,
     209    const usb_endpoint_description_t **endpoints)
     210{
     211        assert(usb_dev);
     212        assert(usb_dev->descriptors.full_config);
     213        assert(usb_dev->pipes == NULL);
     214        assert(usb_dev->pipes_count == 0);
     215
     216        size_t pipe_count = count_pipes(endpoints);
    309217        if (pipe_count == 0) {
    310                 if (pipes_count_ptr)
    311                         *pipes_count_ptr = pipe_count;
    312                 *pipes_ptr = NULL;
    313218                return EOK;
    314219        }
    315220
    316         usb_endpoint_mapping_t *pipes
    317             = calloc(pipe_count, sizeof(usb_endpoint_mapping_t));
     221        usb_endpoint_mapping_t *pipes =
     222            calloc(pipe_count, sizeof(usb_endpoint_mapping_t));
    318223        if (pipes == NULL) {
    319224                return ENOMEM;
     
    321226
    322227        /* Now initialize. */
    323         for (i = 0; i < pipe_count; i++) {
     228        for (size_t i = 0; i < pipe_count; i++) {
    324229                pipes[i].description = endpoints[i];
    325                 pipes[i].interface_no = interface_no;
    326                 pipes[i].interface_setting = interface_setting;
     230                pipes[i].interface_no = usb_dev->interface_no;
     231                pipes[i].interface_setting =
     232                    usb_dev->alternate_interfaces.current;
    327233        }
    328234
    329235        /* Find the mapping from configuration descriptor. */
    330         rc = usb_pipe_initialize_from_configuration(pipes, pipe_count,
    331             config_descr, config_descr_size, wire);
     236        int rc = usb_pipe_initialize_from_configuration(pipes, pipe_count,
     237            usb_dev->descriptors.full_config,
     238            usb_dev->descriptors.full_config_size,
     239            usb_dev->bus_session);
    332240        if (rc != EOK) {
    333241                free(pipes);
     
    336244
    337245        /* Register created pipes. */
    338         for (i = 0; i < pipe_count; i++) {
     246        for (size_t i = 0; i < pipe_count; i++) {
    339247                if (pipes[i].present) {
    340248                        rc = usb_pipe_register(&pipes[i].pipe,
     
    346254        }
    347255
    348         *pipes_ptr = pipes;
    349         if (pipes_count_ptr != NULL) {
    350                 *pipes_count_ptr = pipe_count;
    351         }
     256        usb_dev->pipes = pipes;
     257        usb_dev->pipes_count = pipe_count;
    352258
    353259        return EOK;
     
    360266         */
    361267rollback_unregister_endpoints:
    362         for (i = 0; i < pipe_count; i++) {
     268        for (size_t i = 0; i < pipe_count; i++) {
    363269                if (pipes[i].present) {
    364270                        usb_pipe_unregister(&pipes[i].pipe);
     
    372278/** Destroy pipes previously created by usb_device_create_pipes.
    373279 *
    374  * @param[in] pipes Endpoint mapping to be destroyed.
    375  * @param[in] pipes_count Number of endpoints.
    376  */
    377 void usb_device_destroy_pipes(usb_endpoint_mapping_t *pipes, size_t pipes_count)
    378 {
     280 * @param[in] usb_dev USB device.
     281 */
     282void usb_device_destroy_pipes(usb_device_t *usb_dev)
     283{
     284        assert(usb_dev);
     285        assert(usb_dev->pipes || usb_dev->pipes_count == 0);
    379286        /* Destroy the pipes. */
    380         for (size_t i = 0; i < pipes_count; ++i) {
    381                 assert(pipes);
     287        for (size_t i = 0; i < usb_dev->pipes_count; ++i) {
    382288                usb_log_debug2("Unregistering pipe %zu: %spresent.\n",
    383                     i, pipes[i].present ? "" : "not ");
    384                 if (pipes[i].present)
    385                         usb_pipe_unregister(&pipes[i].pipe);
    386         }
    387         free(pipes);
     289                    i, usb_dev->pipes[i].present ? "" : "not ");
     290                if (usb_dev->pipes[i].present)
     291                        usb_pipe_unregister(&usb_dev->pipes[i].pipe);
     292        }
     293        free(usb_dev->pipes);
     294        usb_dev->pipes = NULL;
     295        usb_dev->pipes_count = 0;
     296}
     297
     298usb_pipe_t *usb_device_get_default_pipe(usb_device_t *usb_dev)
     299{
     300        assert(usb_dev);
     301        return &usb_dev->ctrl_pipe;
     302}
     303
     304usb_endpoint_mapping_t *usb_device_get_mapped_ep_desc(usb_device_t *usb_dev,
     305    const usb_endpoint_description_t *desc)
     306{
     307        assert(usb_dev);
     308        for (unsigned i = 0; i < usb_dev->pipes_count; ++i) {
     309                if (usb_dev->pipes[i].description == desc)
     310                        return &usb_dev->pipes[i];
     311        }
     312        return NULL;
     313}
     314
     315usb_endpoint_mapping_t * usb_device_get_mapped_ep(
     316    usb_device_t *usb_dev, usb_endpoint_t ep)
     317{
     318        assert(usb_dev);
     319        for (unsigned i = 0; i < usb_dev->pipes_count; ++i) {
     320                if (usb_dev->pipes[i].pipe.endpoint_no == ep)
     321                        return &usb_dev->pipes[i];
     322        }
     323        return NULL;
     324}
     325
     326int usb_device_get_iface_number(usb_device_t *usb_dev)
     327{
     328        assert(usb_dev);
     329        return usb_dev->interface_no;
     330}
     331
     332devman_handle_t usb_device_get_devman_handle(usb_device_t *usb_dev)
     333{
     334        assert(usb_dev);
     335        return usb_dev->handle;
     336}
     337
     338const usb_device_descriptors_t *usb_device_descriptors(usb_device_t *usb_dev)
     339{
     340        assert(usb_dev);
     341        return &usb_dev->descriptors;
     342}
     343
     344const usb_alternate_interfaces_t * usb_device_get_alternative_ifaces(
     345    usb_device_t *usb_dev)
     346{
     347        assert(usb_dev);
     348        return &usb_dev->alternate_interfaces;
     349}
     350
     351/** Clean instance of a USB device.
     352 *
     353 * @param dev Device to be de-initialized.
     354 *
     355 * Does not free/destroy supplied pointer.
     356 */
     357static void usb_device_fini(usb_device_t *usb_dev)
     358{
     359        if (usb_dev) {
     360                /* Destroy existing pipes. */
     361                usb_device_destroy_pipes(usb_dev);
     362                /* Ignore errors and hope for the best. */
     363                usb_alternate_interfaces_deinit(&usb_dev->alternate_interfaces);
     364                usb_device_release_descriptors(usb_dev);
     365                free(usb_dev->driver_data);
     366                usb_dev->driver_data = NULL;
     367                usb_dev_disconnect(usb_dev->bus_session);
     368                usb_dev->bus_session = NULL;
     369        }
    388370}
    389371
     
    397379 * @return Error code.
    398380 */
    399 int usb_device_init(usb_device_t *usb_dev, ddf_dev_t *ddf_dev,
    400     const usb_endpoint_description_t **endpoints, const char **errstr_ptr)
     381static int usb_device_init(usb_device_t *usb_dev, ddf_dev_t *ddf_dev,
     382    const usb_endpoint_description_t **endpoints, const char **errstr_ptr,
     383    devman_handle_t handle, int interface_no)
    401384{
    402385        assert(usb_dev != NULL);
    403         assert(ddf_dev != NULL);
     386        assert(errstr_ptr);
    404387
    405388        *errstr_ptr = NULL;
    406389
    407390        usb_dev->ddf_dev = ddf_dev;
     391        usb_dev->handle = handle;
     392        usb_dev->interface_no = interface_no;
    408393        usb_dev->driver_data = NULL;
    409         usb_dev->descriptors.configuration = NULL;
     394        usb_dev->descriptors.full_config = NULL;
     395        usb_dev->descriptors.full_config_size = 0;
    410396        usb_dev->pipes_count = 0;
    411397        usb_dev->pipes = NULL;
    412398
    413         /* Get assigned params */
    414         devman_handle_t hc_handle;
    415         usb_address_t address;
    416 
    417         int rc = usb_get_info_by_handle(ddf_dev_get_handle(ddf_dev),
    418             &hc_handle, &address, &usb_dev->interface_no);
    419         if (rc != EOK) {
    420                 *errstr_ptr = "device parameters retrieval";
    421                 return rc;
    422         }
    423 
    424         /* Initialize hc connection. */
    425         usb_hc_connection_initialize(&usb_dev->hc_conn, hc_handle);
    426 
    427         /* Initialize backing wire and control pipe. */
    428         rc = usb_device_connection_initialize(
    429             &usb_dev->wire, &usb_dev->hc_conn, address);
    430         if (rc != EOK) {
    431                 *errstr_ptr = "device connection initialization";
    432                 return rc;
     399        usb_dev->bus_session = usb_dev_connect(handle);
     400
     401        if (!usb_dev->bus_session) {
     402                *errstr_ptr = "device bus session create";
     403                return ENOMEM;
    433404        }
    434405
    435406        /* This pipe was registered by the hub driver,
    436407         * during device initialization. */
    437         rc = usb_pipe_initialize_default_control(
    438             &usb_dev->ctrl_pipe, &usb_dev->wire);
     408        int rc = usb_pipe_initialize_default_control(
     409            &usb_dev->ctrl_pipe, usb_dev->bus_session);
    439410        if (rc != EOK) {
     411                usb_dev_disconnect(usb_dev->bus_session);
    440412                *errstr_ptr = "default control pipe initialization";
    441413                return rc;
    442414        }
    443415
    444         /* Open hc connection for pipe registration. */
    445         rc = usb_hc_connection_open(&usb_dev->hc_conn);
    446         if (rc != EOK) {
    447                 *errstr_ptr = "hc connection open";
    448                 return rc;
    449         }
    450 
    451416        /* Retrieve standard descriptors. */
    452         rc = usb_device_retrieve_descriptors(
    453             &usb_dev->ctrl_pipe, &usb_dev->descriptors);
     417        rc = usb_device_retrieve_descriptors(usb_dev);
    454418        if (rc != EOK) {
    455419                *errstr_ptr = "descriptor retrieval";
    456                 usb_hc_connection_close(&usb_dev->hc_conn);
     420                usb_dev_disconnect(usb_dev->bus_session);
    457421                return rc;
    458422        }
     
    463427         * controlling a device. */
    464428        rc = usb_alternate_interfaces_init(&usb_dev->alternate_interfaces,
    465             usb_dev->descriptors.configuration,
    466             usb_dev->descriptors.configuration_size, usb_dev->interface_no);
    467         const int alternate_iface =
    468             (rc == EOK) ? usb_dev->alternate_interfaces.current : 0;
    469 
    470         /* Create and register other pipes than default control (EP 0) */
    471         rc = usb_device_create_pipes(&usb_dev->wire, endpoints,
    472             usb_dev->descriptors.configuration,
    473             usb_dev->descriptors.configuration_size,
    474             usb_dev->interface_no, (int)alternate_iface,
    475             &usb_dev->pipes, &usb_dev->pipes_count);
    476         if (rc != EOK) {
    477                 usb_hc_connection_close(&usb_dev->hc_conn);
    478                 /* Full configuration descriptor is allocated. */
    479                 usb_device_release_descriptors(&usb_dev->descriptors);
    480                 /* Alternate interfaces may be allocated */
    481                 usb_alternate_interfaces_deinit(&usb_dev->alternate_interfaces);
    482                 *errstr_ptr = "pipes initialization";
    483                 return rc;
    484         }
    485 
    486         usb_hc_connection_close(&usb_dev->hc_conn);
     429            usb_dev->descriptors.full_config,
     430            usb_dev->descriptors.full_config_size, usb_dev->interface_no);
     431
     432        if (endpoints) {
     433                /* Create and register other pipes than default control (EP 0)*/
     434                rc = usb_device_create_pipes(usb_dev, endpoints);
     435                if (rc != EOK) {
     436                        usb_device_fini(usb_dev);
     437                        *errstr_ptr = "pipes initialization";
     438                        return rc;
     439                }
     440        }
     441
    487442        return EOK;
    488443}
    489444
    490 /** Clean instance of a USB device.
    491  *
    492  * @param dev Device to be de-initialized.
    493  *
    494  * Does not free/destroy supplied pointer.
    495  */
    496 void usb_device_deinit(usb_device_t *dev)
    497 {
    498         if (dev) {
    499                 /* Destroy existing pipes. */
    500                 destroy_current_pipes(dev);
    501                 /* Ignore errors and hope for the best. */
    502                 usb_hc_connection_deinitialize(&dev->hc_conn);
    503                 usb_alternate_interfaces_deinit(&dev->alternate_interfaces);
    504                 usb_device_release_descriptors(&dev->descriptors);
    505                 free(dev->driver_data);
    506                 dev->driver_data = NULL;
    507         }
     445static int usb_device_get_info(async_sess_t *sess, devman_handle_t *handle,
     446        int *iface_no)
     447{
     448        assert(handle);
     449        assert(iface_no);
     450        async_exch_t *exch = async_exchange_begin(sess);
     451        if (!exch)
     452                return EPARTY;
     453        int ret = usb_get_my_device_handle(exch, handle);
     454        if (ret == EOK) {
     455                ret = usb_get_my_interface(exch, iface_no);
     456                if (ret == ENOTSUP) {
     457                        *iface_no = -1;
     458                        ret = EOK;
     459                }
     460        }
     461        async_exchange_end(exch);
     462        return ret;
     463}
     464
     465int usb_device_create_ddf(ddf_dev_t *ddf_dev,
     466    const usb_endpoint_description_t **desc, const char **err)
     467{
     468        assert(ddf_dev);
     469        assert(err);
     470
     471        devman_handle_t h = 0;
     472        int iface_no = -1;
     473
     474        async_sess_t *sess = devman_parent_device_connect(
     475            ddf_dev_get_handle(ddf_dev), IPC_FLAG_BLOCKING);
     476        const int ret = usb_device_get_info(sess, &h, &iface_no);
     477        async_hangup(sess);
     478        if (ret != EOK)
     479                return ret;
     480
     481        usb_device_t *usb_dev =
     482            ddf_dev_data_alloc(ddf_dev, sizeof(usb_device_t));
     483        if (usb_dev == NULL) {
     484                *err = "DDF data alloc";
     485                return ENOMEM;
     486        }
     487       
     488        return usb_device_init(usb_dev, ddf_dev, desc, err, h, iface_no);
     489}
     490
     491void usb_device_destroy_ddf(ddf_dev_t *ddf_dev)
     492{
     493        assert(ddf_dev);
     494        usb_device_t *usb_dev = ddf_dev_data_get(ddf_dev);
     495        assert(usb_dev);
     496        usb_device_fini(usb_dev);
     497        return;
     498}
     499
     500usb_device_t * usb_device_create(devman_handle_t handle)
     501{
     502        devman_handle_t h = 0;
     503        int iface_no = -1;
     504
     505        async_sess_t *sess = devman_device_connect(handle, IPC_FLAG_BLOCKING);
     506        int ret = usb_device_get_info(sess, &h, &iface_no);
     507        if (sess)
     508                async_hangup(sess);
     509        if (ret != EOK)
     510                return NULL;
     511
     512        usb_device_t *usb_dev = malloc(sizeof(usb_device_t));
     513        if (!usb_dev)
     514                return NULL;
     515
     516        const char* dummy = NULL;
     517        ret = usb_device_init(usb_dev, NULL, NULL, &dummy, handle, iface_no);
     518        if (ret != EOK) {
     519                free(usb_dev);
     520                usb_dev = NULL;
     521        }
     522        return usb_dev;
     523}
     524
     525void usb_device_destroy(usb_device_t *usb_dev)
     526{
     527        if (usb_dev) {
     528                usb_device_fini(usb_dev);
     529                free(usb_dev);
     530        }
     531}
     532
     533const char *usb_device_get_name(usb_device_t *usb_dev)
     534{
     535        assert(usb_dev);
     536        if (usb_dev->ddf_dev)
     537                return ddf_dev_get_name(usb_dev->ddf_dev);
     538        return NULL;
     539}
     540
     541ddf_fun_t *usb_device_ddf_fun_create(usb_device_t *usb_dev, fun_type_t ftype,
     542    const char* name)
     543{
     544        assert(usb_dev);
     545        if (usb_dev->ddf_dev)
     546                return ddf_fun_create(usb_dev->ddf_dev, ftype, name);
     547        return NULL;
     548}
     549
     550async_exch_t * usb_device_bus_exchange_begin(usb_device_t *usb_dev)
     551{
     552        assert(usb_dev);
     553        return async_exchange_begin(usb_dev->bus_session);
     554}
     555
     556void usb_device_bus_exchange_end(async_exch_t *exch)
     557{
     558        async_exchange_end(exch);
    508559}
    509560
     
    521572}
    522573
     574void * usb_device_data_get(usb_device_t *usb_dev)
     575{
     576        assert(usb_dev);
     577        return usb_dev->driver_data;
     578}
     579
    523580/**
    524581 * @}
  • uspace/lib/usbdev/src/devpoll.c

    r5b18137 rb4b534ac  
    3333 * USB device driver framework - automatic interrupt polling.
    3434 */
     35#include <usb/dev/device.h>
     36#include <usb/dev/pipes.h>
    3537#include <usb/dev/poll.h>
    3638#include <usb/dev/request.h>
     39#include <usb/classes/classes.h>
    3740#include <usb/debug.h>
    38 #include <usb/classes/classes.h>
     41#include <usb/descriptor.h>
     42#include <usb/usb.h>
     43
     44#include <assert.h>
     45#include <async.h>
    3946#include <errno.h>
     47#include <fibril.h>
     48#include <stdbool.h>
     49#include <stdlib.h>
    4050#include <str_error.h>
    41 #include <assert.h>
     51#include <sys/types.h>
    4252
    4353/** Maximum number of failed consecutive requests before announcing failure. */
     
    5161        /** USB device to poll. */
    5262        usb_device_t *dev;
    53         /** Device pipe to use for polling. */
    54         size_t pipe_index;
     63        /** Device enpoint mapping to use for polling. */
     64        usb_endpoint_mapping_t *polling_mapping;
    5565        /** Size of the recieved data. */
    5666        size_t request_size;
     
    7282        const usb_device_auto_polling_t *params = &data->auto_polling;
    7383
    74         usb_pipe_t *pipe
    75             = &data->dev->pipes[data->pipe_index].pipe;
     84        usb_pipe_t *pipe = &data->polling_mapping->pipe;
    7685
    7786        if (params->debug > 0) {
    7887                const usb_endpoint_mapping_t *mapping
    79                     = &data->dev->pipes[data->pipe_index];
    80                 usb_log_debug("Poll%p: started polling of `%s' - " \
     88                    = data->polling_mapping;
     89                usb_log_debug("Poll (%p): started polling of `%s' - " \
    8190                    "interface %d (%s,%d,%d), %zuB/%zu.\n",
    82                     data, ddf_dev_get_name(data->dev->ddf_dev),
     91                    data, usb_device_get_name(data->dev),
    8392                    (int) mapping->interface->interface_number,
    8493                    usb_str_class(mapping->interface->interface_class),
     
    8897        }
    8998
    90         usb_pipe_start_long_transfer(pipe);
    9199        size_t failed_attempts = 0;
    92100        while (failed_attempts <= params->max_failures) {
     
    95103                    data->request_size, &actual_size);
    96104
    97                 if (params->debug > 1) {
    98                         if (rc == EOK) {
     105                if (rc == EOK) {
     106                        if (params->debug > 1) {
    99107                                usb_log_debug(
    100108                                    "Poll%p: received: '%s' (%zuB).\n",
     
    103111                                        actual_size, 16),
    104112                                    actual_size);
    105                         } else {
     113                        }
     114                } else {
    106115                                usb_log_debug(
    107116                                    "Poll%p: polling failed: %s.\n",
    108117                                    data, str_error(rc));
    109                         }
    110118                }
    111119
     
    117125                         */
    118126                        usb_request_clear_endpoint_halt(
    119                             &data->dev->ctrl_pipe, pipe->endpoint_no);
     127                            usb_device_get_default_pipe(data->dev),
     128                            pipe->endpoint_no);
    120129                }
    121130
     
    145154
    146155                /* Take a rest before next request. */
     156                //TODO: This is broken, the time is in ms not us.
     157                // but first we need to fix drivers to actually stop using this,
     158                // since polling dealy should be implemented in HC schedule
    147159                async_usleep(params->delay);
    148160        }
    149 
    150         usb_pipe_end_long_transfer(pipe);
    151161
    152162        const bool failed = failed_attempts > 0;
     
    159169                if (failed) {
    160170                        usb_log_error("Polling of device `%s' terminated: "
    161                             "recurring failures.\n", ddf_dev_get_name(
    162                             data->dev->ddf_dev));
     171                            "recurring failures.\n",
     172                            usb_device_get_name(data->dev));
    163173                } else {
    164174                        usb_log_debug("Polling of device `%s' terminated: "
    165                             "driver request.\n", ddf_dev_get_name(
    166                             data->dev->ddf_dev));
     175                            "driver request.\n",
     176                            usb_device_get_name(data->dev));
    167177                }
    168178        }
     
    175185}
    176186
     187
    177188/** Start automatic device polling over interrupt in pipe.
    178189 *
    179  * @warning It is up to the callback to produce delays between individual
    180  * requests.
     190 * The polling settings is copied thus it is okay to destroy the structure
     191 * after this function returns.
    181192 *
    182193 * @warning There is no guarantee when the request to the device
     
    185196 *
    186197 * @param dev Device to be periodically polled.
     198 * @param epm Endpoint mapping to use.
     199 * @param polling Polling settings.
     200 * @param request_size How many bytes to ask for in each request.
     201 * @param arg Custom argument (passed as is to the callbacks).
     202 * @return Error code.
     203 * @retval EOK New fibril polling the device was already started.
     204 */
     205static int usb_device_auto_polling_internal(usb_device_t *dev,
     206    usb_endpoint_mapping_t *epm, const usb_device_auto_polling_t *polling,
     207    size_t request_size)
     208{
     209        if ((dev == NULL) || (polling == NULL) || (polling->on_data == NULL)) {
     210                return EBADMEM;
     211        }
     212
     213        if (request_size == 0)
     214                return EINVAL;
     215
     216        if (!epm || (epm->pipe.transfer_type != USB_TRANSFER_INTERRUPT) ||
     217            (epm->pipe.direction != USB_DIRECTION_IN))
     218                return EINVAL;
     219
     220
     221        polling_data_t *polling_data = malloc(sizeof(polling_data_t));
     222        if (polling_data == NULL) {
     223                return ENOMEM;
     224        }
     225
     226        /* Fill-in the data. */
     227        polling_data->buffer = malloc(sizeof(request_size));
     228        if (polling_data->buffer == NULL) {
     229                free(polling_data);
     230                return ENOMEM;
     231        }
     232        polling_data->request_size = request_size;
     233        polling_data->dev = dev;
     234        polling_data->polling_mapping = epm;
     235
     236        /* Copy provided settings. */
     237        polling_data->auto_polling = *polling;
     238
     239        /* Negative value means use descriptor provided value. */
     240        if (polling->delay < 0) {
     241                polling_data->auto_polling.delay =
     242                    epm->descriptor->poll_interval;
     243        }
     244
     245        fid_t fibril = fibril_create(polling_fibril, polling_data);
     246        if (fibril == 0) {
     247                free(polling_data->buffer);
     248                free(polling_data);
     249                return ENOMEM;
     250        }
     251        fibril_add_ready(fibril);
     252
     253        /* Fibril launched. That fibril will free the allocated data. */
     254
     255        return EOK;
     256}
     257/** Start automatic device polling over interrupt in pipe.
     258 *
     259 * The polling settings is copied thus it is okay to destroy the structure
     260 * after this function returns.
     261 *
     262 * @warning There is no guarantee when the request to the device
     263 * will be sent for the first time (it is possible that this
     264 * first request would be executed prior to return from this function).
     265 *
     266 * @param dev Device to be periodically polled.
    187267 * @param pipe_index Index of the endpoint pipe used for polling.
     268 * @param polling Polling settings.
     269 * @param req_size How many bytes to ask for in each request.
     270 * @param arg Custom argument (passed as is to the callbacks).
     271 * @return Error code.
     272 * @retval EOK New fibril polling the device was already started.
     273 */
     274int usb_device_auto_polling(usb_device_t *usb_dev, usb_endpoint_t ep,
     275    const usb_device_auto_polling_t *polling, size_t req_size)
     276{
     277        usb_endpoint_mapping_t *epm = usb_device_get_mapped_ep(usb_dev, ep);
     278        return usb_device_auto_polling_internal(usb_dev, epm, polling, req_size);
     279}
     280
     281/** Start automatic device polling over interrupt in pipe.
     282 *
     283 * @warning It is up to the callback to produce delays between individual
     284 * requests.
     285 *
     286 * @warning There is no guarantee when the request to the device
     287 * will be sent for the first time (it is possible that this
     288 * first request would be executed prior to return from this function).
     289 *
     290 * @param dev Device to be periodically polled.
     291 * @param ep Endpoint  used for polling.
    188292 * @param callback Callback when data are available.
    189293 * @param request_size How many bytes to ask for in each request.
     294 * @param delay NUmber of ms to wait between queries, -1 to use descriptor val.
    190295 * @param terminated_callback Callback when polling is terminated.
    191296 * @param arg Custom argument (passed as is to the callbacks).
     
    193298 * @retval EOK New fibril polling the device was already started.
    194299 */
    195 int usb_device_auto_poll(usb_device_t *dev, size_t pipe_index,
    196     usb_polling_callback_t callback, size_t request_size,
     300int usb_device_auto_poll(usb_device_t *dev, usb_endpoint_t ep,
     301    usb_polling_callback_t callback, size_t request_size, int delay,
    197302    usb_polling_terminted_callback_t terminated_callback, void *arg)
    198303{
     
    200305                .debug = 1,
    201306                .auto_clear_halt = true,
    202                 .delay = 0,
     307                .delay = delay,
    203308                .max_failures = MAX_FAILED_ATTEMPTS,
    204309                .on_data = callback,
     
    208313        };
    209314
    210         return usb_device_auto_polling(dev, pipe_index, &auto_polling,
    211            request_size);
    212 }
    213 
    214 /** Start automatic device polling over interrupt in pipe.
    215  *
    216  * The polling settings is copied thus it is okay to destroy the structure
    217  * after this function returns.
    218  *
    219  * @warning There is no guarantee when the request to the device
    220  * will be sent for the first time (it is possible that this
    221  * first request would be executed prior to return from this function).
    222  *
    223  * @param dev Device to be periodically polled.
    224  * @param pipe_index Index of the endpoint pipe used for polling.
    225  * @param polling Polling settings.
    226  * @param request_size How many bytes to ask for in each request.
    227  * @param arg Custom argument (passed as is to the callbacks).
    228  * @return Error code.
    229  * @retval EOK New fibril polling the device was already started.
    230  */
    231 int usb_device_auto_polling(usb_device_t *dev, size_t pipe_index,
    232     const usb_device_auto_polling_t *polling,
    233     size_t request_size)
    234 {
    235         if ((dev == NULL) || (polling == NULL) || (polling->on_data == NULL)) {
    236                 return EBADMEM;
    237         }
    238 
    239         if (pipe_index >= dev->pipes_count || request_size == 0) {
    240                 return EINVAL;
    241         }
    242         if ((dev->pipes[pipe_index].pipe.transfer_type != USB_TRANSFER_INTERRUPT)
    243             || (dev->pipes[pipe_index].pipe.direction != USB_DIRECTION_IN)) {
    244                 return EINVAL;
    245         }
    246 
    247         polling_data_t *polling_data = malloc(sizeof(polling_data_t));
    248         if (polling_data == NULL) {
    249                 return ENOMEM;
    250         }
    251 
    252         /* Fill-in the data. */
    253         polling_data->buffer = malloc(sizeof(request_size));
    254         if (polling_data->buffer == NULL) {
    255                 free(polling_data);
    256                 return ENOMEM;
    257         }
    258         polling_data->request_size = request_size;
    259         polling_data->dev = dev;
    260         polling_data->pipe_index = pipe_index;
    261 
    262         /* Copy provided settings. */
    263         polling_data->auto_polling = *polling;
    264 
    265         /* Negative value means use descriptor provided value. */
    266         if (polling->delay < 0) {
    267                 polling_data->auto_polling.delay =
    268                     (int) dev->pipes[pipe_index].descriptor->poll_interval;
    269         }
    270 
    271         fid_t fibril = fibril_create(polling_fibril, polling_data);
    272         if (fibril == 0) {
    273                 free(polling_data->buffer);
    274                 free(polling_data);
    275                 return ENOMEM;
    276         }
    277         fibril_add_ready(fibril);
    278 
    279         /* Fibril launched. That fibril will free the allocated data. */
    280 
    281         return EOK;
     315        usb_endpoint_mapping_t *epm = usb_device_get_mapped_ep(dev, ep);
     316        return usb_device_auto_polling_internal(
     317            dev, epm, &auto_polling, request_size);
     318}
     319
     320int usb_device_auto_polling_desc(usb_device_t *usb_dev,
     321    const usb_endpoint_description_t *desc,
     322    const usb_device_auto_polling_t *polling, size_t req_size)
     323{
     324        usb_endpoint_mapping_t *epm =
     325            usb_device_get_mapped_ep_desc(usb_dev, desc);
     326        return usb_device_auto_polling_internal(usb_dev, epm, polling, req_size);
     327}
     328
     329int usb_device_auto_poll_desc(usb_device_t * usb_dev,
     330    const usb_endpoint_description_t *desc, usb_polling_callback_t callback,
     331    size_t req_size, int delay,
     332    usb_polling_terminted_callback_t terminated_callback, void *arg)
     333{
     334        const usb_device_auto_polling_t auto_polling = {
     335                .debug = 1,
     336                .auto_clear_halt = true,
     337                .delay = delay,
     338                .max_failures = MAX_FAILED_ATTEMPTS,
     339                .on_data = callback,
     340                .on_polling_end = terminated_callback,
     341                .on_error = NULL,
     342                .arg = arg,
     343        };
     344
     345        usb_endpoint_mapping_t *epm =
     346            usb_device_get_mapped_ep_desc(usb_dev, desc);
     347        return usb_device_auto_polling_internal(
     348            usb_dev, epm, &auto_polling, req_size);
    282349}
    283350
  • uspace/lib/usbdev/src/dp.c

    r5b18137 rb4b534ac  
    4141 * sibling.
    4242 */
    43 #include <stdio.h>
    44 #include <str_error.h>
    45 #include <errno.h>
    46 #include <assert.h>
    47 #include <stdbool.h>
    4843#include <usb/dev/dp.h>
    4944#include <usb/descriptor.h>
     45
     46#include <assert.h>
     47#include <errno.h>
     48#include <stdlib.h>
     49#include <stdbool.h>
     50#include <sys/types.h>
    5051
    5152#define NESTING(parentname, childname) \
     
    304305 * @param arg Custom (user) argument.
    305306 */
    306 void usb_dp_walk_simple(uint8_t *descriptors, size_t descriptors_size,
     307void usb_dp_walk_simple(const uint8_t *descriptors, size_t descriptors_size,
    307308    const usb_dp_descriptor_nesting_t *descriptor_nesting,
    308309    walk_callback_t callback, void *arg)
  • uspace/lib/usbdev/src/pipes.c

    r5b18137 rb4b534ac  
    3535#include <usb/dev/pipes.h>
    3636#include <usb/dev/request.h>
     37#include <usb/usb.h>
     38#include <usb_iface.h>
     39
     40#include <assert.h>
     41#include <async.h>
    3742#include <errno.h>
    38 #include <assert.h>
    39 
    40 /** Prepare pipe for a long transfer.
    41  *
    42  * Long transfer is transfer consisting of several requests to the HC.
    43  * Calling this function is optional and it has positive effect of
    44  * improved performance because IPC session is initiated only once.
    45  *
    46  * @param pipe Pipe over which the transfer will happen.
    47  * @return Error code.
    48  */
    49 int usb_pipe_start_long_transfer(usb_pipe_t *pipe)
    50 {
    51         assert(pipe);
    52         assert(pipe->wire);
    53         assert(pipe->wire->hc_connection);
    54         return usb_hc_connection_open(pipe->wire->hc_connection);
    55 }
    56 
    57 /** Terminate a long transfer on a pipe.
    58  * @param pipe Pipe where to end the long transfer.
    59  * @return Error code.
    60  * @see usb_pipe_start_long_transfer
    61  */
    62 int usb_pipe_end_long_transfer(usb_pipe_t *pipe)
    63 {
    64         assert(pipe);
    65         assert(pipe->wire);
    66         assert(pipe->wire->hc_connection);
    67         return usb_hc_connection_close(pipe->wire->hc_connection);
    68 }
     43#include <mem.h>
    6944
    7045/** Try to clear endpoint halt of default control pipe.
     
    12196        memcpy(&setup_packet, setup_buffer, 8);
    12297
     98        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
    12399        size_t act_size = 0;
    124         const int rc = usb_device_control_read(pipe->wire,
     100        const int rc = usb_read(exch,
    125101            pipe->endpoint_no, setup_packet, buffer, buffer_size, &act_size);
     102        async_exchange_end(exch);
    126103
    127104        if (rc == ESTALL) {
     
    173150        memcpy(&setup_packet, setup_buffer, 8);
    174151
    175         const int rc = usb_device_control_write(pipe->wire,
     152        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
     153        const int rc = usb_write(exch,
    176154            pipe->endpoint_no, setup_packet, buffer, buffer_size);
     155        async_exchange_end(exch);
    177156
    178157        if (rc == ESTALL) {
     
    217196            return ENOTSUP;
    218197
     198        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
    219199        size_t act_size = 0;
    220         const int rc = usb_device_read(pipe->wire,
    221             pipe->endpoint_no, buffer, size, &act_size);
     200        const int rc =
     201            usb_read(exch, pipe->endpoint_no, 0, buffer, size, &act_size);
     202        async_exchange_end(exch);
    222203
    223204        if (rc == EOK && size_transfered != NULL) {
     
    256237            return ENOTSUP;
    257238
    258         return usb_device_write(pipe->wire,
    259             pipe->endpoint_no, buffer, size);
     239        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
     240        const int rc = usb_write(exch, pipe->endpoint_no, 0, buffer, size);
     241        async_exchange_end(exch);
     242        return rc;
    260243}
    261244
     
    263246 *
    264247 * @param pipe Endpoint pipe to be initialized.
    265  * @param connection Connection to the USB device backing this pipe (the wire).
    266248 * @param endpoint_no Endpoint number (in USB 1.1 in range 0 to 15).
    267249 * @param transfer_type Transfer type (e.g. interrupt or bulk).
     
    270252 * @return Error code.
    271253 */
    272 int usb_pipe_initialize(usb_pipe_t *pipe,
    273     usb_device_connection_t *connection, usb_endpoint_t endpoint_no,
     254int usb_pipe_initialize(usb_pipe_t *pipe, usb_endpoint_t endpoint_no,
    274255    usb_transfer_type_t transfer_type, size_t max_packet_size,
    275     usb_direction_t direction)
    276 {
    277         assert(pipe);
    278         assert(connection);
    279 
    280         pipe->wire = connection;
     256    usb_direction_t direction, unsigned packets, usb_dev_session_t *bus_session)
     257{
     258        assert(pipe);
     259
    281260        pipe->endpoint_no = endpoint_no;
    282261        pipe->transfer_type = transfer_type;
     262        pipe->packets = packets;
    283263        pipe->max_packet_size = max_packet_size;
    284264        pipe->direction = direction;
    285265        pipe->auto_reset_halt = false;
     266        pipe->bus_session = bus_session;
    286267
    287268        return EOK;
     
    291272 *
    292273 * @param pipe Endpoint pipe to be initialized.
    293  * @param connection Connection to the USB device backing this pipe (the wire).
    294274 * @return Error code.
    295275 */
    296276int usb_pipe_initialize_default_control(usb_pipe_t *pipe,
    297     usb_device_connection_t *connection)
    298 {
    299         assert(pipe);
    300         assert(connection);
    301 
    302         int rc = usb_pipe_initialize(pipe, connection, 0, USB_TRANSFER_CONTROL,
    303             CTRL_PIPE_MIN_PACKET_SIZE, USB_DIRECTION_BOTH);
     277    usb_dev_session_t *bus_session)
     278{
     279        assert(pipe);
     280
     281        const int rc = usb_pipe_initialize(pipe, 0, USB_TRANSFER_CONTROL,
     282            CTRL_PIPE_MIN_PACKET_SIZE, USB_DIRECTION_BOTH, 1, bus_session);
    304283
    305284        pipe->auto_reset_halt = true;
     
    317296{
    318297        assert(pipe);
    319         assert(pipe->wire);
    320 
    321         return usb_device_register_endpoint(pipe->wire,
    322            pipe->endpoint_no, pipe->transfer_type,
    323            pipe->direction, pipe->max_packet_size, interval);
     298        assert(pipe->bus_session);
     299        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
     300        if (!exch)
     301                return ENOMEM;
     302        const int ret = usb_register_endpoint(exch, pipe->endpoint_no,
     303            pipe->transfer_type, pipe->direction, pipe->max_packet_size,
     304            pipe->packets, interval);
     305        async_exchange_end(exch);
     306        return ret;
    324307}
    325308
     
    332315{
    333316        assert(pipe);
    334         assert(pipe->wire);
    335 
    336         return usb_device_unregister_endpoint(pipe->wire,
    337             pipe->endpoint_no, pipe->direction);
     317        assert(pipe->bus_session);
     318        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
     319        if (!exch)
     320                return ENOMEM;
     321        const int ret = usb_unregister_endpoint(exch, pipe->endpoint_no,
     322            pipe->direction);
     323        async_exchange_end(exch);
     324        return ret;
    338325}
    339326
  • uspace/lib/usbdev/src/pipesinit.c

    r5b18137 rb4b534ac  
    3434 *
    3535 */
    36 #include <usb/usb.h>
    3736#include <usb/dev/pipes.h>
    3837#include <usb/dev/dp.h>
    3938#include <usb/dev/request.h>
     39#include <usb/usb.h>
     40#include <usb/descriptor.h>
     41
     42#include <assert.h>
    4043#include <errno.h>
    41 #include <assert.h>
    4244
    4345#define DEV_DESCR_MAX_PACKET_SIZE_OFFSET 7
     
    148150 * @param interface Interface descriptor under which belongs the @p endpoint.
    149151 * @param endpoint Endpoint descriptor.
    150  * @param wire Connection backing the endpoint pipes.
    151152 * @return Error code.
    152153 */
     
    155156    usb_standard_interface_descriptor_t *interface,
    156157    usb_standard_endpoint_descriptor_t *endpoint_desc,
    157     usb_device_connection_t *wire)
     158    usb_dev_session_t *bus_session)
    158159{
    159160
     
    193194        }
    194195
    195         int rc = usb_pipe_initialize(&ep_mapping->pipe, wire,
     196        int rc = usb_pipe_initialize(&ep_mapping->pipe,
    196197            ep_no, description.transfer_type,
    197             uint16_usb2host(endpoint_desc->max_packet_size),
    198             description.direction);
     198            ED_MPS_PACKET_SIZE_GET(
     199                uint16_usb2host(endpoint_desc->max_packet_size)),
     200            description.direction,
     201            ED_MPS_TRANS_OPPORTUNITIES_GET(
     202                uint16_usb2host(endpoint_desc->max_packet_size)), bus_session);
    199203        if (rc != EOK) {
    200204                return rc;
     
    220224    usb_endpoint_mapping_t *mapping, size_t mapping_count,
    221225    const usb_dp_parser_t *parser, const usb_dp_parser_data_t *parser_data,
    222     const uint8_t *interface_descriptor)
     226    const uint8_t *interface_descriptor, usb_dev_session_t *bus_session)
    223227{
    224228        const uint8_t *descriptor = usb_dp_get_nested_descriptor(parser,
     
    236240                            (usb_standard_endpoint_descriptor_t *)
    237241                                descriptor,
    238                             (usb_device_connection_t *) parser_data->arg);
     242                            bus_session);
    239243                }
    240244
     
    280284    usb_endpoint_mapping_t *mapping, size_t mapping_count,
    281285    const uint8_t *config_descriptor, size_t config_descriptor_size,
    282     usb_device_connection_t *connection)
    283 {
    284         assert(connection);
     286    usb_dev_session_t *bus_session)
     287{
    285288
    286289        if (config_descriptor == NULL) {
     
    306309                .data = config_descriptor,
    307310                .size = config_descriptor_size,
    308                 .arg = connection
    309311        };
    310312
     
    319321        do {
    320322                (void) process_interface(mapping, mapping_count,
    321                     &dp_parser, &dp_data, interface);
     323                    &dp_parser, &dp_data, interface, bus_session);
    322324                interface = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data,
    323325                    config_descriptor, interface);
     
    347349                return EINVAL;
    348350        }
    349 
    350 
    351         usb_pipe_start_long_transfer(pipe);
    352351
    353352        uint8_t dev_descr_start[CTRL_PIPE_MIN_PACKET_SIZE];
     
    367366                }
    368367        }
    369         usb_pipe_end_long_transfer(pipe);
    370368        if (rc != EOK) {
    371369                return rc;
  • uspace/lib/usbdev/src/recognise.c

    r5b18137 rb4b534ac  
    3434 */
    3535
    36 #include <sys/types.h>
    37 #include <fibril_synch.h>
    38 #include <usb/debug.h>
    39 #include <usb/dev/hub.h>
    4036#include <usb/dev/pipes.h>
    4137#include <usb/dev/recognise.h>
    42 #include <usb/ddfiface.h>
    4338#include <usb/dev/request.h>
    4439#include <usb/classes/classes.h>
     40
     41#include <assert.h>
     42#include <errno.h>
    4543#include <stdio.h>
    46 #include <errno.h>
    47 #include <assert.h>
    48 
    49 /** DDF operations of child devices. */
    50 static ddf_dev_ops_t child_ops = {
    51         .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl
    52 };
     44#include <sys/types.h>
    5345
    5446/** Get integer part from BCD coded number. */
     
    242234                    (int) device_descriptor->product_id,
    243235                    BCD_ARGS(device_descriptor->device_version));
    244                
     236
    245237                /* Next, without release number. */
    246238                ADD_MATCHID_OR_RETURN(matches, 90,
     
    248240                    (int) device_descriptor->vendor_id,
    249241                    (int) device_descriptor->product_id);
    250         }       
    251 
    252         /*
    253          * If the device class points to interface we skip adding
    254          * class directly but we add a multi interface device.
    255          */
    256         if (device_descriptor->device_class != USB_CLASS_USE_INTERFACE) {
    257                 ADD_MATCHID_OR_RETURN(matches, 50, "usb&class=%s",
    258                     usb_str_class(device_descriptor->device_class));
    259         } else {
    260                 ADD_MATCHID_OR_RETURN(matches, 50, "usb&mid");
    261         }
    262        
     242        }
     243
     244        /* Class match id */
     245        ADD_MATCHID_OR_RETURN(matches, 50, "usb&class=%s",
     246            usb_str_class(device_descriptor->device_class));
     247
    263248        /* As a last resort, try fallback driver. */
    264249        ADD_MATCHID_OR_RETURN(matches, 10, "usb&fallback");
     
    302287}
    303288
    304 /** Probe for device kind and register it in devman.
    305  *
    306  * @param[in] ctrl_pipe Control pipe to the device.
    307  * @param[in] parent Parent device.
    308  * @param[in] dev_ops Child device ops. Default child_ops will be used if NULL.
    309  * @param[in] dev_data Arbitrary pointer to be stored in the child
    310  *      as @c driver_data.
    311  * @param[out] child_fun Storage where pointer to allocated child function
    312  *      will be written.
    313  * @return Error code.
    314  *
    315  */
    316 int usb_device_register_child_in_devman(usb_pipe_t *ctrl_pipe,
    317     ddf_dev_t *parent, ddf_fun_t *fun, ddf_dev_ops_t *dev_ops)
    318 {
    319         if (ctrl_pipe == NULL)
    320                 return EINVAL;
    321        
    322         if (!dev_ops && ddf_fun_data_get(fun) != NULL) {
    323                 usb_log_warning("Using standard fun ops with arbitrary "
    324                     "driver data. This does not have to work.\n");
    325         }
    326        
    327         /** Index to append after device name for uniqueness. */
    328         static atomic_t device_name_index = {0};
    329         const size_t this_device_name_index =
    330             (size_t) atomic_preinc(&device_name_index);
    331        
    332         int rc;
    333        
    334         /*
    335          * TODO: Once the device driver framework support persistent
    336          * naming etc., something more descriptive could be created.
    337          */
    338         char child_name[12];  /* The format is: "usbAB_aXYZ", length 11 */
    339         rc = snprintf(child_name, sizeof(child_name),
    340             "usb%02zu_a%d", this_device_name_index, ctrl_pipe->wire->address);
    341         if (rc < 0) {
    342                 goto failure;
    343         }
    344        
    345         rc = ddf_fun_set_name(fun, child_name);
    346         if (rc != EOK)
    347                 goto failure;
    348        
    349         if (dev_ops != NULL)
    350                 ddf_fun_set_ops(fun, dev_ops);
    351         else
    352                 ddf_fun_set_ops(fun, &child_ops);
    353        
    354         /*
    355          * Store the attached device in fun
    356          * driver data if there is no other data
    357          */
    358         if (ddf_fun_data_get(fun) == NULL) {
    359                 usb_hub_attached_device_t *new_device = ddf_fun_data_alloc(
    360                     fun, sizeof(usb_hub_attached_device_t));
    361                 if (!new_device) {
    362                         rc = ENOMEM;
    363                         goto failure;
    364                 }
    365                
    366                 new_device->address = ctrl_pipe->wire->address;
    367                 new_device->fun = fun;
    368         }
    369        
    370         match_id_list_t match_ids;
    371         init_match_ids(&match_ids);
    372         rc = usb_device_create_match_ids(ctrl_pipe, &match_ids);
    373         if (rc != EOK)
    374                 goto failure;
    375        
    376         list_foreach(match_ids.ids, link, match_id_t, match_id) {
    377                 rc = ddf_fun_add_match_id(fun, match_id->id, match_id->score);
    378                 if (rc != EOK) {
    379                         clean_match_ids(&match_ids);
    380                         goto failure;
    381                 }
    382         }
    383        
    384         clean_match_ids(&match_ids);
    385        
    386         rc = ddf_fun_bind(fun);
    387         if (rc != EOK)
    388                 goto failure;
    389        
    390         return EOK;
    391        
    392 failure:
    393         return rc;
    394 }
    395 
    396289/**
    397290 * @}
  • uspace/lib/usbdev/src/request.c

    r5b18137 rb4b534ac  
    3434 */
    3535#include <usb/dev/request.h>
     36#include <usb/request.h>
     37#include <usb/usb.h>
     38
    3639#include <errno.h>
    37 #include <assert.h>
    38 #include <usb/debug.h>
     40#include <mem.h>
     41#include <stdlib.h>
     42#include <str.h>
    3943
    4044#define MAX_DATA_LENGTH ((size_t)(0xFFFF))
     
    5155 * @param request Actual request (e.g. GET_DESCRIPTOR).
    5256 * @param value Value of @c wValue field of setup packet
    53  *      (must be in USB endianness).
     57 *      (must be in USB endianness).
    5458 * @param index Value of @c wIndex field of setup packet
    55  *      (must be in USB endianness).
     59 *      (must be in USB endianness).
    5660 * @param data Data to be sent during DATA stage
    57  *      (expected to be in USB endianness).
     61 *      (expected to be in USB endianness).
    5862 * @param data_size Size of the @p data buffer (in native endianness).
    5963 * @return Error code.
     
    6468int usb_control_request_set(usb_pipe_t *pipe,
    6569    usb_request_type_t request_type, usb_request_recipient_t recipient,
    66     uint8_t request,
    67     uint16_t value, uint16_t index,
    68     void *data, size_t data_size)
     70    uint8_t request, uint16_t value, uint16_t index,
     71    const void *data, size_t data_size)
    6972{
    7073        if (pipe == NULL) {
     
    8588         */
    8689
    87         usb_device_request_setup_packet_t setup_packet;
    88         setup_packet.request_type = (request_type << 5) | recipient;
    89         setup_packet.request = request;
    90         setup_packet.value = value;
    91         setup_packet.index = index;
    92         setup_packet.length = (uint16_t) data_size;
    93 
    94         int rc = usb_pipe_control_write(pipe,
    95             &setup_packet, sizeof(setup_packet),
    96             data, data_size);
    97 
    98         return rc;
     90        const usb_device_request_setup_packet_t setup_packet = {
     91                .request_type = (request_type << 5) | recipient,
     92                .request = request,
     93                .value = value,
     94                .index = index,
     95                .length = (uint16_t) data_size,
     96        };
     97
     98        return usb_pipe_control_write(pipe,
     99            &setup_packet, sizeof(setup_packet), data, data_size);
    99100}
    100101
     
    108109  * @param request Actual request (e.g. GET_DESCRIPTOR).
    109110  * @param value Value of @c wValue field of setup packet
    110   *     (must be in USB endianness).
     111  *     (must be in USB endianness).
    111112  * @param index Value of @c wIndex field of setup packet
    112113  *     (must be in USB endianness).
     
    114115  *     (they will come in USB endianness).
    115116  * @param data_size Size of the @p data buffer
    116   *     (in native endianness).
     117  *     (in native endianness).
    117118  * @param actual_data_size Actual size of transfered data
    118   *        (in native endianness).
     119  *     (in native endianness).
    119120  * @return Error code.
    120121  * @retval EBADMEM @p pipe is NULL.
     
    124125int usb_control_request_get(usb_pipe_t *pipe,
    125126    usb_request_type_t request_type, usb_request_recipient_t recipient,
    126     uint8_t request,
    127     uint16_t value, uint16_t index,
     127    uint8_t request, uint16_t value, uint16_t index,
    128128    void *data, size_t data_size, size_t *actual_data_size)
    129129{
     
    209209{
    210210        if (request_type == USB_REQUEST_TYPE_STANDARD) {
    211                 if ((recipient == USB_REQUEST_RECIPIENT_DEVICE)
    212                     && (index != 0)) {
     211                if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) && (index != 0))
     212                {
    213213                        return EINVAL;
    214214                }
    215215        }
    216216
    217         int rc = usb_control_request_set(pipe, request_type, recipient,
    218             USB_DEVREQ_CLEAR_FEATURE,
    219             uint16_host2usb(feature_selector), uint16_host2usb(index),
    220             NULL, 0);
    221 
    222         return rc;
     217        return usb_control_request_set(pipe,
     218            request_type, recipient, USB_DEVREQ_CLEAR_FEATURE,
     219            uint16_host2usb(feature_selector), uint16_host2usb(index), NULL, 0);
    223220}
    224221
     
    237234{
    238235        if (request_type == USB_REQUEST_TYPE_STANDARD) {
    239                 if ((recipient == USB_REQUEST_RECIPIENT_DEVICE)
    240                     && (index != 0)) {
     236                if ((recipient == USB_REQUEST_RECIPIENT_DEVICE) && (index != 0))
     237                {
    241238                        return EINVAL;
    242239                }
    243240        }
    244241
    245         int rc = usb_control_request_set(pipe, request_type, recipient,
    246             USB_DEVREQ_SET_FEATURE,
    247             uint16_host2usb(feature_selector), uint16_host2usb(index),
    248             NULL, 0);
    249 
    250         return rc;
     242        return usb_control_request_set(pipe,
     243            request_type, recipient, USB_DEVREQ_SET_FEATURE,
     244            uint16_host2usb(feature_selector), uint16_host2usb(index), NULL, 0);
    251245}
    252246
     
    277271        }
    278272
     273        /* The wValue field specifies the descriptor type in the high byte
     274         * and the descriptor index in the low byte. USB 1.1 spec p. 189
     275         */
    279276        const uint16_t wValue = descriptor_index | (descriptor_type << 8);
    280277
     
    313310         * Get only first byte to retrieve descriptor length.
    314311         */
    315         uint8_t tmp_buffer[1];
     312        uint8_t tmp_buffer;
    316313        size_t bytes_transfered;
    317314        rc = usb_request_get_descriptor(pipe, request_type, recipient,
    318315            descriptor_type, descriptor_index, language,
    319             &tmp_buffer, 1, &bytes_transfered);
     316            &tmp_buffer, sizeof(tmp_buffer), &bytes_transfered);
    320317        if (rc != EOK) {
    321318                return rc;
    322319        }
    323320        if (bytes_transfered != 1) {
    324                 /* FIXME: some better error code? */
    325                 return ESTALL;
    326         }
    327 
    328         size_t size = tmp_buffer[0];
     321                return ELIMIT;
     322        }
     323
     324        const size_t size = tmp_buffer;
    329325        if (size == 0) {
    330                 /* FIXME: some better error code? */
    331                 return ESTALL;
     326                return ELIMIT;
    332327        }
    333328
     
    349344        if (bytes_transfered != size) {
    350345                free(buffer);
    351                 /* FIXME: some better error code? */
    352                 return ESTALL;
     346                return ELIMIT;
    353347        }
    354348
     
    378372        int rc = usb_request_get_descriptor(pipe,
    379373            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    380             USB_DESCTYPE_DEVICE, 0, 0,
    381             &descriptor_tmp, sizeof(descriptor_tmp),
     374            USB_DESCTYPE_DEVICE, 0, 0, &descriptor_tmp, sizeof(descriptor_tmp),
    382375            &actually_transferred);
    383376
     
    421414        size_t actually_transferred = 0;
    422415        usb_standard_configuration_descriptor_t descriptor_tmp;
    423         int rc = usb_request_get_descriptor(pipe,
     416        const int rc = usb_request_get_descriptor(pipe,
    424417            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    425418            USB_DESCTYPE_CONFIGURATION, index, 0,
     
    479472int usb_request_get_full_configuration_descriptor_alloc(
    480473    usb_pipe_t *pipe, int index,
    481     void **descriptor_ptr, size_t *descriptor_size)
     474    const void **descriptor_ptr, size_t *descriptor_size)
    482475{
    483476        int rc;
     
    546539    usb_request_type_t request_type, usb_request_recipient_t recipient,
    547540    uint8_t descriptor_type, uint8_t descriptor_index,
    548     uint16_t language,
    549     void *buffer, size_t size)
     541    uint16_t language, const void *buffer, size_t size)
    550542{
    551543        if (buffer == NULL) {
     
    560552
    561553        return usb_control_request_set(pipe,
    562             request_type, recipient,
    563             USB_DEVREQ_SET_DESCRIPTOR,
    564             wValue, language,
    565             buffer, size);
     554            request_type, recipient, USB_DEVREQ_SET_DESCRIPTOR,
     555            wValue, language, buffer, size);
    566556}
    567557
     
    578568        size_t actual_size;
    579569
    580         int rc = usb_control_request_get(pipe,
     570        const int rc = usb_control_request_get(pipe,
    581571            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    582             USB_DEVREQ_GET_CONFIGURATION,
    583             0, 0,
    584             &value, 1, &actual_size);
     572            USB_DEVREQ_GET_CONFIGURATION, 0, 0, &value, 1, &actual_size);
    585573
    586574        if (rc != EOK) {
     
    607595    uint8_t configuration_value)
    608596{
    609         uint16_t config_value
     597        const uint16_t config_value
    610598            = uint16_host2usb((uint16_t) configuration_value);
    611599
     
    629617        size_t actual_size;
    630618
    631         int rc = usb_control_request_get(pipe,
     619        const int rc = usb_control_request_get(pipe,
    632620            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE,
    633621            USB_DEVREQ_GET_INTERFACE,
    634622            0, uint16_host2usb((uint16_t) interface_index),
    635             &value, 1, &actual_size);
     623            &value, sizeof(value), &actual_size);
    636624
    637625        if (rc != EOK) {
     
    678666    l18_win_locales_t **languages_ptr, size_t *languages_count)
    679667{
    680         int rc;
    681 
    682         if (languages_ptr == NULL) {
    683                 return EBADMEM;
    684         }
    685         if (languages_count == NULL) {
     668        if (languages_ptr == NULL || languages_count == NULL) {
    686669                return EBADMEM;
    687670        }
     
    689672        uint8_t *string_descriptor = NULL;
    690673        size_t string_descriptor_size = 0;
    691         rc = usb_request_get_descriptor_alloc(pipe,
     674        const int rc = usb_request_get_descriptor_alloc(pipe,
    692675            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    693676            USB_DESCTYPE_STRING, 0, 0,
     
    710693        }
    711694
    712         size_t langs_count = string_descriptor_size / 2;
    713         l18_win_locales_t *langs
    714             = malloc(sizeof(l18_win_locales_t) * langs_count);
     695        const size_t langs_count = string_descriptor_size / 2;
     696        l18_win_locales_t *langs =
     697            calloc(langs_count, sizeof(l18_win_locales_t));
    715698        if (langs == NULL) {
    716699                free(string_descriptor);
     
    718701        }
    719702
    720         size_t i;
    721         for (i = 0; i < langs_count; i++) {
     703        for (size_t i = 0; i < langs_count; i++) {
    722704                /* Language code from the descriptor is in USB endianness. */
    723705                /* FIXME: is this really correct? */
    724                 uint16_t lang_code = (string_descriptor[2 + 2 * i + 1] << 8)
     706                const uint16_t lang_code =
     707                    (string_descriptor[2 + 2 * i + 1] << 8)
    725708                    + string_descriptor[2 + 2 * i];
    726709                langs[i] = uint16_usb2host(lang_code);
     
    761744        }
    762745        /* Language is actually two byte value. */
    763         if (lang > 0xFFFF) {
     746        if (lang > L18N_WIN_LOCALE_MAX) {
    764747                return ERANGE;
    765748        }
     
    795778        }
    796779
    797         size_t string_char_count = string_size / 2;
     780        const size_t string_char_count = string_size / 2;
    798781        string_chars = malloc(sizeof(wchar_t) * (string_char_count + 1));
    799782        if (string_chars == NULL) {
     
    807790         * do not have them).
    808791         */
    809         size_t i;
    810         for (i = 0; i < string_char_count; i++) {
    811                 uint16_t uni_char = (string[2 + 2 * i + 1] << 8)
     792        for (size_t i = 0; i < string_char_count; i++) {
     793                const uint16_t uni_char = (string[2 + 2 * i + 1] << 8)
    812794                    + string[2 + 2 * i];
    813795                string_chars[i] = uni_char;
     
    827809
    828810leave:
    829         if (string != NULL) {
    830                 free(string);
    831         }
    832         if (string_chars != NULL) {
    833                 free(string_chars);
    834         }
     811        free(string);
     812        free(string_chars);
    835813
    836814        return rc;
     
    847825        return usb_request_clear_feature(pipe,
    848826            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_ENDPOINT,
    849             uint16_host2usb(USB_FEATURE_SELECTOR_ENDPOINT_HALT),
     827            uint16_host2usb(USB_FEATURE_ENDPOINT_HALT),
    850828            uint16_host2usb(ep_index));
    851829}
Note: See TracChangeset for help on using the changeset viewer.