Ignore:
File:
1 edited

Legend:

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

    r56fd7cf r4c86c7c  
    3333 * USB device driver framework.
    3434 */
    35 #include <usb/dev/driver.h>
     35
     36#include <usb_iface.h>
     37#include <usb/dev/device.h>
    3638#include <usb/dev/request.h>
    3739#include <usb/debug.h>
     
    4143#include <assert.h>
    4244
    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 }
     45/** USB device structure. */
     46typedef struct usb_device {
     47        /** Connection to USB hc, used by wire and arbitrary requests. */
     48        usb_hc_connection_t hc_conn;
     49        /** Connection backing the pipes.
     50         * Typically, you will not need to use this attribute at all.
     51         */
     52        usb_device_connection_t wire;
     53        /** The default control pipe. */
     54        usb_pipe_t ctrl_pipe;
     55
     56        /** Other endpoint pipes.
     57         * This is an array of other endpoint pipes in the same order as
     58         * in usb_driver_t.
     59         */
     60        usb_endpoint_mapping_t *pipes;
     61        /** Number of other endpoint pipes. */
     62        size_t pipes_count;
     63        /** Current interface.
     64         * Usually, drivers operate on single interface only.
     65         * This item contains the value of the interface or -1 for any.
     66         */
     67        int interface_no;
     68        /** Alternative interfaces. */
     69        usb_alternate_interfaces_t alternate_interfaces;
     70        /** Some useful descriptors for USB device. */
     71        usb_device_descriptors_t descriptors;
     72        /** Generic DDF device backing this one. DO NOT TOUCH! */
     73        ddf_dev_t *ddf_dev;
     74        /** Custom driver data.
     75         * Do not use the entry in generic device, that is already used
     76         * by the framework.
     77         */
     78        void *driver_data;
     79
     80        usb_dev_session_t *bus_session;
     81} usb_device_t;
    7682
    7783/** Count number of pipes the driver expects.
     
    8086 * @return Number of pipes (excluding default control pipe).
    8187 */
    82 static inline size_t count_other_pipes(
    83     const usb_endpoint_description_t **endpoints)
     88static inline size_t count_pipes(const usb_endpoint_description_t **endpoints)
    8489{
    8590        size_t count;
    8691        for (count = 0; endpoints != NULL && endpoints[count] != NULL; ++count);
    8792        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;
    17993}
    18094
     
    201115 * @return Error code.
    202116 */
    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) {
     117int usb_device_select_interface(usb_device_t *usb_dev,
     118    uint8_t alternate_setting, const usb_endpoint_description_t **endpoints)
     119{
     120        assert(usb_dev);
     121
     122        if (usb_dev->interface_no < 0) {
    207123                return EINVAL;
    208124        }
    209125
     126        /* Change the interface itself. */
     127        int rc = usb_request_set_interface(&usb_dev->ctrl_pipe,
     128            usb_dev->interface_no, alternate_setting);
     129        if (rc != EOK) {
     130                return rc;
     131        }
     132
     133        /* Change current alternative */
     134        usb_dev->alternate_interfaces.current = alternate_setting;
     135
    210136        /* Destroy existing pipes. */
    211         destroy_current_pipes(dev);
    212 
    213         /* Change the interface itself. */
    214         int rc = usb_request_set_interface(&dev->ctrl_pipe, dev->interface_no,
    215             alternate_setting);
    216         if (rc != EOK) {
    217                 return rc;
    218         }
     137        usb_device_destroy_pipes(usb_dev);
    219138
    220139        /* 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);
     140        rc = usb_device_create_pipes(usb_dev, endpoints);
    225141
    226142        return rc;
     
    233149 * @return Error code.
    234150 */
    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;
     151static int usb_device_retrieve_descriptors(usb_device_t *usb_dev)
     152{
     153        assert(usb_dev);
     154        assert(usb_dev->descriptors.full_config == NULL);
    243155
    244156        /* It is worth to start a long transfer. */
    245         usb_pipe_start_long_transfer(ctrl_pipe);
     157        usb_pipe_start_long_transfer(&usb_dev->ctrl_pipe);
    246158
    247159        /* Get the device descriptor. */
    248         rc = usb_request_get_device_descriptor(ctrl_pipe, &descriptors->device);
     160        int rc = usb_request_get_device_descriptor(&usb_dev->ctrl_pipe,
     161            &usb_dev->descriptors.device);
    249162        if (rc != EOK) {
    250163                goto leave;
     
    253166        /* Get the full configuration descriptor. */
    254167        rc = usb_request_get_full_configuration_descriptor_alloc(
    255             ctrl_pipe, 0, (void **) &descriptors->configuration,
    256             &descriptors->configuration_size);
     168            &usb_dev->ctrl_pipe, 0,
     169            &usb_dev->descriptors.full_config,
     170            &usb_dev->descriptors.full_config_size);
    257171
    258172leave:
    259         usb_pipe_end_long_transfer(ctrl_pipe);
     173        usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe);
    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
     
    292207 * @return Error code.
    293208 */
    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);
     209int usb_device_create_pipes(usb_device_t *usb_dev,
     210    const usb_endpoint_description_t **endpoints)
     211{
     212        assert(usb_dev);
     213        assert(usb_dev->descriptors.full_config);
     214        assert(usb_dev->pipes == NULL);
     215        assert(usb_dev->pipes_count == 0);
     216
     217        size_t pipe_count = count_pipes(endpoints);
    309218        if (pipe_count == 0) {
    310                 if (pipes_count_ptr)
    311                         *pipes_count_ptr = pipe_count;
    312                 *pipes_ptr = NULL;
    313219                return EOK;
    314220        }
    315221
    316         usb_endpoint_mapping_t *pipes
    317             = calloc(pipe_count, sizeof(usb_endpoint_mapping_t));
     222        usb_endpoint_mapping_t *pipes =
     223            calloc(pipe_count, sizeof(usb_endpoint_mapping_t));
    318224        if (pipes == NULL) {
    319225                return ENOMEM;
     
    321227
    322228        /* Now initialize. */
    323         for (i = 0; i < pipe_count; i++) {
     229        for (size_t i = 0; i < pipe_count; i++) {
    324230                pipes[i].description = endpoints[i];
    325                 pipes[i].interface_no = interface_no;
    326                 pipes[i].interface_setting = interface_setting;
     231                pipes[i].interface_no = usb_dev->interface_no;
     232                pipes[i].interface_setting =
     233                    usb_dev->alternate_interfaces.current;
    327234        }
    328235
    329236        /* Find the mapping from configuration descriptor. */
    330         rc = usb_pipe_initialize_from_configuration(pipes, pipe_count,
    331             config_descr, config_descr_size, wire);
     237        int rc = usb_pipe_initialize_from_configuration(pipes, pipe_count,
     238            usb_dev->descriptors.full_config,
     239            usb_dev->descriptors.full_config_size, &usb_dev->wire,
     240            usb_dev->bus_session);
    332241        if (rc != EOK) {
    333242                free(pipes);
     
    336245
    337246        /* Register created pipes. */
    338         for (i = 0; i < pipe_count; i++) {
     247        for (size_t i = 0; i < pipe_count; i++) {
    339248                if (pipes[i].present) {
    340249                        rc = usb_pipe_register(&pipes[i].pipe,
     
    346255        }
    347256
    348         *pipes_ptr = pipes;
    349         if (pipes_count_ptr != NULL) {
    350                 *pipes_count_ptr = pipe_count;
    351         }
     257        usb_dev->pipes = pipes;
     258        usb_dev->pipes_count = pipe_count;
    352259
    353260        return EOK;
     
    360267         */
    361268rollback_unregister_endpoints:
    362         for (i = 0; i < pipe_count; i++) {
     269        for (size_t i = 0; i < pipe_count; i++) {
    363270                if (pipes[i].present) {
    364271                        usb_pipe_unregister(&pipes[i].pipe);
     
    372279/** Destroy pipes previously created by usb_device_create_pipes.
    373280 *
    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 {
     281 * @param[in] usb_dev USB device.
     282 */
     283void usb_device_destroy_pipes(usb_device_t *usb_dev)
     284{
     285        assert(usb_dev);
     286        assert(usb_dev->pipes || usb_dev->pipes_count == 0);
    379287        /* Destroy the pipes. */
    380         for (size_t i = 0; i < pipes_count; ++i) {
    381                 assert(pipes);
     288        for (size_t i = 0; i < usb_dev->pipes_count; ++i) {
    382289                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);
     290                    i, usb_dev->pipes[i].present ? "" : "not ");
     291                if (usb_dev->pipes[i].present)
     292                        usb_pipe_unregister(&usb_dev->pipes[i].pipe);
     293        }
     294        free(usb_dev->pipes);
     295        usb_dev->pipes = NULL;
     296        usb_dev->pipes_count = 0;
     297}
     298
     299usb_pipe_t *usb_device_get_default_pipe(usb_device_t *usb_dev)
     300{
     301        assert(usb_dev);
     302        return &usb_dev->ctrl_pipe;
     303}
     304
     305usb_endpoint_mapping_t *usb_device_get_mapped_ep_desc(usb_device_t *usb_dev,
     306    const usb_endpoint_description_t *desc)
     307{
     308        assert(usb_dev);
     309        for (unsigned i = 0; i < usb_dev->pipes_count; ++i) {
     310                if (usb_dev->pipes[i].description == desc)
     311                        return &usb_dev->pipes[i];
     312        }
     313        return NULL;
     314}
     315
     316usb_endpoint_mapping_t * usb_device_get_mapped_ep(
     317    usb_device_t *usb_dev, usb_endpoint_t ep)
     318{
     319        assert(usb_dev);
     320        for (unsigned i = 0; i < usb_dev->pipes_count; ++i) {
     321                if (usb_dev->pipes[i].pipe.endpoint_no == ep)
     322                        return &usb_dev->pipes[i];
     323        }
     324        return NULL;
     325}
     326
     327int usb_device_get_iface_number(usb_device_t *usb_dev)
     328{
     329        assert(usb_dev);
     330        return usb_dev->interface_no;
     331}
     332
     333const usb_device_descriptors_t *usb_device_descriptors(usb_device_t *usb_dev)
     334{
     335        assert(usb_dev);
     336        return &usb_dev->descriptors;
     337}
     338
     339const usb_alternate_interfaces_t * usb_device_get_alternative_ifaces(
     340    usb_device_t *usb_dev)
     341{
     342        assert(usb_dev);
     343        return &usb_dev->alternate_interfaces;
     344}
     345
     346static int usb_dev_get_info(usb_device_t *usb_dev, devman_handle_t *handle,
     347    usb_address_t *address, int *iface_no)
     348{
     349        assert(usb_dev);
     350
     351        int ret = EOK;
     352        async_exch_t *exch = async_exchange_begin(usb_dev->bus_session);
     353        if (!exch)
     354                ret = ENOMEM;
     355
     356        if (ret == EOK && address)
     357                ret = usb_get_my_address(exch, address);
     358
     359        if (ret == EOK && handle)
     360                ret = usb_get_hc_handle(exch, handle);
     361
     362        if (ret == EOK && iface_no) {
     363                ret = usb_get_my_interface(exch, iface_no);
     364                if (ret == ENOTSUP) {
     365                        ret = EOK;
     366                        *iface_no = -1;
     367                }
     368        }
     369
     370        async_exchange_end(exch);
     371        return ret;
     372}
     373
     374/** Clean instance of a USB device.
     375 *
     376 * @param dev Device to be de-initialized.
     377 *
     378 * Does not free/destroy supplied pointer.
     379 */
     380static void usb_device_fini(usb_device_t *usb_dev)
     381{
     382        if (usb_dev) {
     383                /* Destroy existing pipes. */
     384                usb_device_destroy_pipes(usb_dev);
     385                /* Ignore errors and hope for the best. */
     386                usb_hc_connection_deinitialize(&usb_dev->hc_conn);
     387                usb_alternate_interfaces_deinit(&usb_dev->alternate_interfaces);
     388                usb_device_release_descriptors(usb_dev);
     389                free(usb_dev->driver_data);
     390                usb_dev->driver_data = NULL;
     391                usb_dev_disconnect(usb_dev->bus_session);
     392                usb_dev->bus_session = NULL;
     393        }
    388394}
    389395
     
    397403 * @return Error code.
    398404 */
    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)
     405static int usb_device_init(usb_device_t *usb_dev, ddf_dev_t *ddf_dev,
     406    const usb_endpoint_description_t **endpoints, const char **errstr_ptr,
     407    devman_handle_t handle)
    401408{
    402409        assert(usb_dev != NULL);
    403         assert(ddf_dev != NULL);
     410        assert(errstr_ptr);
    404411
    405412        *errstr_ptr = NULL;
     
    407414        usb_dev->ddf_dev = ddf_dev;
    408415        usb_dev->driver_data = NULL;
    409         usb_dev->descriptors.configuration = NULL;
     416        usb_dev->descriptors.full_config = NULL;
     417        usb_dev->descriptors.full_config_size = 0;
    410418        usb_dev->pipes_count = 0;
    411419        usb_dev->pipes = NULL;
     420
     421        if (ddf_dev)
     422                usb_dev->bus_session = usb_dev_connect_to_self(ddf_dev);
     423        else
     424                usb_dev->bus_session = usb_dev_connect(handle);
     425
     426        if (!usb_dev->bus_session) {
     427                *errstr_ptr = "device bus session create";
     428                return ENOMEM;
     429        }
    412430
    413431        /* Get assigned params */
     
    415433        usb_address_t address;
    416434
    417         int rc = usb_get_info_by_handle(ddf_dev_get_handle(ddf_dev),
     435        int rc = usb_dev_get_info(usb_dev,
    418436            &hc_handle, &address, &usb_dev->interface_no);
    419437        if (rc != EOK) {
     438                usb_dev_disconnect(usb_dev->bus_session);
    420439                *errstr_ptr = "device parameters retrieval";
    421440                return rc;
     
    429448            &usb_dev->wire, &usb_dev->hc_conn, address);
    430449        if (rc != EOK) {
     450                usb_dev_disconnect(usb_dev->bus_session);
    431451                *errstr_ptr = "device connection initialization";
    432452                return rc;
     
    436456         * during device initialization. */
    437457        rc = usb_pipe_initialize_default_control(
    438             &usb_dev->ctrl_pipe, &usb_dev->wire);
    439         if (rc != EOK) {
     458            &usb_dev->ctrl_pipe, &usb_dev->wire, usb_dev->bus_session);
     459        if (rc != EOK) {
     460                usb_dev_disconnect(usb_dev->bus_session);
    440461                *errstr_ptr = "default control pipe initialization";
    441462                return rc;
     
    445466        rc = usb_hc_connection_open(&usb_dev->hc_conn);
    446467        if (rc != EOK) {
     468                usb_dev_disconnect(usb_dev->bus_session);
    447469                *errstr_ptr = "hc connection open";
    448470                return rc;
     
    450472
    451473        /* Retrieve standard descriptors. */
    452         rc = usb_device_retrieve_descriptors(
    453             &usb_dev->ctrl_pipe, &usb_dev->descriptors);
     474        rc = usb_device_retrieve_descriptors(usb_dev);
    454475        if (rc != EOK) {
    455476                *errstr_ptr = "descriptor retrieval";
    456477                usb_hc_connection_close(&usb_dev->hc_conn);
     478                usb_dev_disconnect(usb_dev->bus_session);
    457479                return rc;
    458480        }
     
    463485         * controlling a device. */
    464486        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;
     487            usb_dev->descriptors.full_config,
     488            usb_dev->descriptors.full_config_size, usb_dev->interface_no);
     489
     490        if (endpoints) {
     491                /* Create and register other pipes than default control (EP 0)*/
     492                rc = usb_device_create_pipes(usb_dev, endpoints);
     493                if (rc != EOK) {
     494                        usb_hc_connection_close(&usb_dev->hc_conn);
     495                        usb_device_fini(usb_dev);
     496                        *errstr_ptr = "pipes initialization";
     497                        return rc;
     498                }
    484499        }
    485500
     
    488503}
    489504
    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         }
     505int usb_device_create_ddf(ddf_dev_t *ddf_dev,
     506    const usb_endpoint_description_t **desc, const char **err)
     507{
     508        assert(ddf_dev);
     509        assert(err);
     510        usb_device_t *usb_dev =
     511            ddf_dev_data_alloc(ddf_dev, sizeof(usb_device_t));
     512        if (usb_dev == NULL) {
     513                *err = "DDF data alloc";
     514                return ENOMEM;
     515        }
     516        return usb_device_init(usb_dev, ddf_dev, desc, err, 0);
     517}
     518
     519void usb_device_destroy_ddf(ddf_dev_t *ddf_dev)
     520{
     521        assert(ddf_dev);
     522        usb_device_t *usb_dev = ddf_dev_data_get(ddf_dev);
     523        assert(usb_dev);
     524        usb_device_fini(usb_dev);
     525        return;
     526}
     527
     528usb_device_t * usb_device_create(devman_handle_t handle)
     529{
     530        usb_device_t *usb_dev = malloc(sizeof(usb_device_t));
     531        if (!usb_dev)
     532                return NULL;
     533        const char* dummy = NULL;
     534        const int ret = usb_device_init(usb_dev, NULL, NULL, &dummy, handle);
     535        if (ret != EOK) {
     536                free(usb_dev);
     537                usb_dev = NULL;
     538        }
     539        return usb_dev;
     540}
     541
     542void usb_device_destroy(usb_device_t *usb_dev)
     543{
     544        if (usb_dev) {
     545                usb_device_fini(usb_dev);
     546                free(usb_dev);
     547        }
     548}
     549
     550const char *usb_device_get_name(usb_device_t *usb_dev)
     551{
     552        assert(usb_dev);
     553        if (usb_dev->ddf_dev)
     554                return ddf_dev_get_name(usb_dev->ddf_dev);
     555        return NULL;
     556}
     557
     558ddf_fun_t *usb_device_ddf_fun_create(usb_device_t *usb_dev, fun_type_t ftype,
     559    const char* name)
     560{
     561        assert(usb_dev);
     562        if (usb_dev->ddf_dev)
     563                return ddf_fun_create(usb_dev->ddf_dev, ftype, name);
     564        return NULL;
     565}
     566
     567async_exch_t * usb_device_bus_exchange_begin(usb_device_t *usb_dev)
     568{
     569        assert(usb_dev);
     570        return async_exchange_begin(usb_dev->bus_session);
     571}
     572
     573void usb_device_bus_exchange_end(async_exch_t *exch)
     574{
     575        async_exchange_end(exch);
    508576}
    509577
     
    521589}
    522590
     591void * usb_device_data_get(usb_device_t *usb_dev)
     592{
     593        assert(usb_dev);
     594        return usb_dev->driver_data;
     595}
     596
     597usb_address_t usb_device_address(usb_device_t *usb_dev)
     598{
     599        assert(usb_dev);
     600        return usb_dev->wire.address;
     601}
     602
     603devman_handle_t usb_device_hc_handle(usb_device_t *usb_dev)
     604{
     605        assert(usb_dev);
     606        return usb_dev->hc_conn.hc_handle;
     607}
    523608/**
    524609 * @}
Note: See TracChangeset for help on using the changeset viewer.