Ignore:
File:
1 edited

Legend:

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

    r4c86c7c r56fd7cf  
    3333 * USB device driver framework.
    3434 */
    35 
    36 #include <usb_iface.h>
    37 #include <usb/dev/device.h>
     35#include <usb/dev/driver.h>
    3836#include <usb/dev/request.h>
    3937#include <usb/debug.h>
     
    4341#include <assert.h>
    4442
    45 /** USB device structure. */
    46 typedef 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;
     43static int generic_device_add(ddf_dev_t *);
     44static int generic_device_remove(ddf_dev_t *);
     45static int generic_device_gone(ddf_dev_t *);
     46
     47static 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};
     52static driver_t generic_driver = {
     53        .driver_ops = &generic_driver_ops
     54};
     55
     56static 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 */
     65int 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}
    8276
    8377/** Count number of pipes the driver expects.
     
    8680 * @return Number of pipes (excluding default control pipe).
    8781 */
    88 static inline size_t count_pipes(const usb_endpoint_description_t **endpoints)
     82static inline size_t count_other_pipes(
     83    const usb_endpoint_description_t **endpoints)
    8984{
    9085        size_t count;
    9186        for (count = 0; endpoints != NULL && endpoints[count] != NULL; ++count);
    9287        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 */
     97int 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 */
     134int 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 */
     156int 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 */
     174static 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;
    93179}
    94180
     
    115201 * @return Error code.
    116202 */
    117 int 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) {
     203int 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) {
    123207                return EINVAL;
    124208        }
    125209
     210        /* Destroy existing pipes. */
     211        destroy_current_pipes(dev);
     212
    126213        /* 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 
    136         /* Destroy existing pipes. */
    137         usb_device_destroy_pipes(usb_dev);
     214        int rc = usb_request_set_interface(&dev->ctrl_pipe, dev->interface_no,
     215            alternate_setting);
     216        if (rc != EOK) {
     217                return rc;
     218        }
    138219
    139220        /* Create new pipes. */
    140         rc = usb_device_create_pipes(usb_dev, endpoints);
     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);
    141225
    142226        return rc;
     
    149233 * @return Error code.
    150234 */
    151 static int usb_device_retrieve_descriptors(usb_device_t *usb_dev)
    152 {
    153         assert(usb_dev);
    154         assert(usb_dev->descriptors.full_config == NULL);
     235int 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;
    155243
    156244        /* It is worth to start a long transfer. */
    157         usb_pipe_start_long_transfer(&usb_dev->ctrl_pipe);
     245        usb_pipe_start_long_transfer(ctrl_pipe);
    158246
    159247        /* Get the device descriptor. */
    160         int rc = usb_request_get_device_descriptor(&usb_dev->ctrl_pipe,
    161             &usb_dev->descriptors.device);
     248        rc = usb_request_get_device_descriptor(ctrl_pipe, &descriptors->device);
    162249        if (rc != EOK) {
    163250                goto leave;
     
    166253        /* Get the full configuration descriptor. */
    167254        rc = usb_request_get_full_configuration_descriptor_alloc(
    168             &usb_dev->ctrl_pipe, 0,
    169             &usb_dev->descriptors.full_config,
    170             &usb_dev->descriptors.full_config_size);
     255            ctrl_pipe, 0, (void **) &descriptors->configuration,
     256            &descriptors->configuration_size);
    171257
    172258leave:
    173         usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe);
     259        usb_pipe_end_long_transfer(ctrl_pipe);
    174260
    175261        return rc;
     
    180266 * @param[in] descriptors Where to store the descriptors.
    181267 */
    182 static 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;
     268void usb_device_release_descriptors(usb_device_descriptors_t *descriptors)
     269{
     270        assert(descriptors);
     271        free(descriptors->configuration);
     272        descriptors->configuration = NULL;
    188273}
    189274
     
    207292 * @return Error code.
    208293 */
    209 int 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);
     294int 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);
    218309        if (pipe_count == 0) {
     310                if (pipes_count_ptr)
     311                        *pipes_count_ptr = pipe_count;
     312                *pipes_ptr = NULL;
    219313                return EOK;
    220314        }
    221315
    222         usb_endpoint_mapping_t *pipes =
    223             calloc(pipe_count, sizeof(usb_endpoint_mapping_t));
     316        usb_endpoint_mapping_t *pipes
     317            = calloc(pipe_count, sizeof(usb_endpoint_mapping_t));
    224318        if (pipes == NULL) {
    225319                return ENOMEM;
     
    227321
    228322        /* Now initialize. */
    229         for (size_t i = 0; i < pipe_count; i++) {
     323        for (i = 0; i < pipe_count; i++) {
    230324                pipes[i].description = endpoints[i];
    231                 pipes[i].interface_no = usb_dev->interface_no;
    232                 pipes[i].interface_setting =
    233                     usb_dev->alternate_interfaces.current;
     325                pipes[i].interface_no = interface_no;
     326                pipes[i].interface_setting = interface_setting;
    234327        }
    235328
    236329        /* Find the mapping from configuration descriptor. */
    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);
     330        rc = usb_pipe_initialize_from_configuration(pipes, pipe_count,
     331            config_descr, config_descr_size, wire);
    241332        if (rc != EOK) {
    242333                free(pipes);
     
    245336
    246337        /* Register created pipes. */
    247         for (size_t i = 0; i < pipe_count; i++) {
     338        for (i = 0; i < pipe_count; i++) {
    248339                if (pipes[i].present) {
    249340                        rc = usb_pipe_register(&pipes[i].pipe,
     
    255346        }
    256347
    257         usb_dev->pipes = pipes;
    258         usb_dev->pipes_count = pipe_count;
     348        *pipes_ptr = pipes;
     349        if (pipes_count_ptr != NULL) {
     350                *pipes_count_ptr = pipe_count;
     351        }
    259352
    260353        return EOK;
     
    267360         */
    268361rollback_unregister_endpoints:
    269         for (size_t i = 0; i < pipe_count; i++) {
     362        for (i = 0; i < pipe_count; i++) {
    270363                if (pipes[i].present) {
    271364                        usb_pipe_unregister(&pipes[i].pipe);
     
    279372/** Destroy pipes previously created by usb_device_create_pipes.
    280373 *
    281  * @param[in] usb_dev USB device.
    282  */
    283 void usb_device_destroy_pipes(usb_device_t *usb_dev)
    284 {
    285         assert(usb_dev);
    286         assert(usb_dev->pipes || usb_dev->pipes_count == 0);
     374 * @param[in] pipes Endpoint mapping to be destroyed.
     375 * @param[in] pipes_count Number of endpoints.
     376 */
     377void usb_device_destroy_pipes(usb_endpoint_mapping_t *pipes, size_t pipes_count)
     378{
    287379        /* Destroy the pipes. */
    288         for (size_t i = 0; i < usb_dev->pipes_count; ++i) {
     380        for (size_t i = 0; i < pipes_count; ++i) {
     381                assert(pipes);
    289382                usb_log_debug2("Unregistering pipe %zu: %spresent.\n",
    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 
    299 usb_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 
    305 usb_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 
    316 usb_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 
    327 int usb_device_get_iface_number(usb_device_t *usb_dev)
    328 {
    329         assert(usb_dev);
    330         return usb_dev->interface_no;
    331 }
    332 
    333 const usb_device_descriptors_t *usb_device_descriptors(usb_device_t *usb_dev)
    334 {
    335         assert(usb_dev);
    336         return &usb_dev->descriptors;
    337 }
    338 
    339 const 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 
    346 static 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  */
    380 static 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         }
     383                    i, pipes[i].present ? "" : "not ");
     384                if (pipes[i].present)
     385                        usb_pipe_unregister(&pipes[i].pipe);
     386        }
     387        free(pipes);
    394388}
    395389
     
    403397 * @return Error code.
    404398 */
    405 static 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)
     399int usb_device_init(usb_device_t *usb_dev, ddf_dev_t *ddf_dev,
     400    const usb_endpoint_description_t **endpoints, const char **errstr_ptr)
    408401{
    409402        assert(usb_dev != NULL);
    410         assert(errstr_ptr);
     403        assert(ddf_dev != NULL);
    411404
    412405        *errstr_ptr = NULL;
     
    414407        usb_dev->ddf_dev = ddf_dev;
    415408        usb_dev->driver_data = NULL;
    416         usb_dev->descriptors.full_config = NULL;
    417         usb_dev->descriptors.full_config_size = 0;
     409        usb_dev->descriptors.configuration = NULL;
    418410        usb_dev->pipes_count = 0;
    419411        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         }
    430412
    431413        /* Get assigned params */
     
    433415        usb_address_t address;
    434416
    435         int rc = usb_dev_get_info(usb_dev,
     417        int rc = usb_get_info_by_handle(ddf_dev_get_handle(ddf_dev),
    436418            &hc_handle, &address, &usb_dev->interface_no);
    437419        if (rc != EOK) {
    438                 usb_dev_disconnect(usb_dev->bus_session);
    439420                *errstr_ptr = "device parameters retrieval";
    440421                return rc;
     
    448429            &usb_dev->wire, &usb_dev->hc_conn, address);
    449430        if (rc != EOK) {
    450                 usb_dev_disconnect(usb_dev->bus_session);
    451431                *errstr_ptr = "device connection initialization";
    452432                return rc;
     
    456436         * during device initialization. */
    457437        rc = usb_pipe_initialize_default_control(
    458             &usb_dev->ctrl_pipe, &usb_dev->wire, usb_dev->bus_session);
    459         if (rc != EOK) {
    460                 usb_dev_disconnect(usb_dev->bus_session);
     438            &usb_dev->ctrl_pipe, &usb_dev->wire);
     439        if (rc != EOK) {
    461440                *errstr_ptr = "default control pipe initialization";
    462441                return rc;
     
    466445        rc = usb_hc_connection_open(&usb_dev->hc_conn);
    467446        if (rc != EOK) {
    468                 usb_dev_disconnect(usb_dev->bus_session);
    469447                *errstr_ptr = "hc connection open";
    470448                return rc;
     
    472450
    473451        /* Retrieve standard descriptors. */
    474         rc = usb_device_retrieve_descriptors(usb_dev);
     452        rc = usb_device_retrieve_descriptors(
     453            &usb_dev->ctrl_pipe, &usb_dev->descriptors);
    475454        if (rc != EOK) {
    476455                *errstr_ptr = "descriptor retrieval";
    477456                usb_hc_connection_close(&usb_dev->hc_conn);
    478                 usb_dev_disconnect(usb_dev->bus_session);
    479457                return rc;
    480458        }
     
    485463         * controlling a device. */
    486464        rc = usb_alternate_interfaces_init(&usb_dev->alternate_interfaces,
    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                 }
     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;
    499484        }
    500485
     
    503488}
    504489
    505 int 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 
    519 void 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 
    528 usb_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 
    542 void 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 
    550 const 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 
    558 ddf_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 
    567 async_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 
    573 void usb_device_bus_exchange_end(async_exch_t *exch)
    574 {
    575         async_exchange_end(exch);
     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 */
     496void 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        }
    576508}
    577509
     
    589521}
    590522
    591 void * usb_device_data_get(usb_device_t *usb_dev)
    592 {
    593         assert(usb_dev);
    594         return usb_dev->driver_data;
    595 }
    596 
    597 usb_address_t usb_device_address(usb_device_t *usb_dev)
    598 {
    599         assert(usb_dev);
    600         return usb_dev->wire.address;
    601 }
    602 
    603 devman_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 }
    608523/**
    609524 * @}
Note: See TracChangeset for help on using the changeset viewer.