Ignore:
File:
1 edited

Legend:

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

    rc01987c r56fd7cf  
    3333 * USB device driver framework.
    3434 */
    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>
     35#include <usb/dev/driver.h>
    4036#include <usb/dev/request.h>
    4137#include <usb/debug.h>
    42 #include <usb/descriptor.h>
    43 #include <usb/usb.h>
    44 
     38#include <usb/dev.h>
     39#include <errno.h>
     40#include <str_error.h>
    4541#include <assert.h>
    46 #include <async.h>
    47 #include <devman.h>
    48 #include <errno.h>
    49 #include <stdlib.h>
    50 
    51 #include <ddf/driver.h>
    52 
    53 /** USB device structure. */
    54 typedef 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;
     42
     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}
    8776
    8877/** Count number of pipes the driver expects.
     
    9180 * @return Number of pipes (excluding default control pipe).
    9281 */
    93 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)
    9484{
    9585        size_t count;
    9686        for (count = 0; endpoints != NULL && endpoints[count] != NULL; ++count);
    9787        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;
    98179}
    99180
     
    120201 * @return Error code.
    121202 */
    122 int 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) {
     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) {
    128207                return EINVAL;
    129208        }
    130209
     210        /* Destroy existing pipes. */
     211        destroy_current_pipes(dev);
     212
    131213        /* Change the interface itself. */
    132         int rc = usb_request_set_interface(&usb_dev->ctrl_pipe,
    133             usb_dev->interface_no, alternate_setting);
    134         if (rc != EOK) {
    135                 return rc;
    136         }
    137 
    138         /* Change current alternative */
    139         usb_dev->alternate_interfaces.current = alternate_setting;
    140 
    141         /* Destroy existing pipes. */
    142         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        }
    143219
    144220        /* Create new pipes. */
    145         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);
    146225
    147226        return rc;
     
    154233 * @return Error code.
    155234 */
    156 static int usb_device_retrieve_descriptors(usb_device_t *usb_dev)
    157 {
    158         assert(usb_dev);
    159         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;
     243
     244        /* It is worth to start a long transfer. */
     245        usb_pipe_start_long_transfer(ctrl_pipe);
    160246
    161247        /* Get the device descriptor. */
    162         int rc = usb_request_get_device_descriptor(&usb_dev->ctrl_pipe,
    163             &usb_dev->descriptors.device);
    164         if (rc != EOK) {
    165                 return rc;
     248        rc = usb_request_get_device_descriptor(ctrl_pipe, &descriptors->device);
     249        if (rc != EOK) {
     250                goto leave;
    166251        }
    167252
    168253        /* Get the full configuration descriptor. */
    169254        rc = usb_request_get_full_configuration_descriptor_alloc(
    170             &usb_dev->ctrl_pipe, 0,
    171             &usb_dev->descriptors.full_config,
    172             &usb_dev->descriptors.full_config_size);
    173 
     255            ctrl_pipe, 0, (void **) &descriptors->configuration,
     256            &descriptors->configuration_size);
     257
     258leave:
     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
     
    195280 * - registers endpoints with the host controller
    196281 *
     282 * @param[in] wire Initialized backing connection to the host controller.
    197283 * @param[in] endpoints Endpoints description, NULL terminated.
    198284 * @param[in] config_descr Configuration descriptor of active configuration.
     
    206292 * @return Error code.
    207293 */
    208 int 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);
     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);
    217309        if (pipe_count == 0) {
     310                if (pipes_count_ptr)
     311                        *pipes_count_ptr = pipe_count;
     312                *pipes_ptr = NULL;
    218313                return EOK;
    219314        }
    220315
    221         usb_endpoint_mapping_t *pipes =
    222             calloc(pipe_count, sizeof(usb_endpoint_mapping_t));
     316        usb_endpoint_mapping_t *pipes
     317            = calloc(pipe_count, sizeof(usb_endpoint_mapping_t));
    223318        if (pipes == NULL) {
    224319                return ENOMEM;
     
    226321
    227322        /* Now initialize. */
    228         for (size_t i = 0; i < pipe_count; i++) {
     323        for (i = 0; i < pipe_count; i++) {
    229324                pipes[i].description = endpoints[i];
    230                 pipes[i].interface_no = usb_dev->interface_no;
    231                 pipes[i].interface_setting =
    232                     usb_dev->alternate_interfaces.current;
     325                pipes[i].interface_no = interface_no;
     326                pipes[i].interface_setting = interface_setting;
    233327        }
    234328
    235329        /* Find the mapping from configuration descriptor. */
    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);
     330        rc = usb_pipe_initialize_from_configuration(pipes, pipe_count,
     331            config_descr, config_descr_size, wire);
    240332        if (rc != EOK) {
    241333                free(pipes);
     
    244336
    245337        /* Register created pipes. */
    246         for (size_t i = 0; i < pipe_count; i++) {
     338        for (i = 0; i < pipe_count; i++) {
    247339                if (pipes[i].present) {
    248340                        rc = usb_pipe_register(&pipes[i].pipe,
     
    254346        }
    255347
    256         usb_dev->pipes = pipes;
    257         usb_dev->pipes_count = pipe_count;
     348        *pipes_ptr = pipes;
     349        if (pipes_count_ptr != NULL) {
     350                *pipes_count_ptr = pipe_count;
     351        }
    258352
    259353        return EOK;
     
    266360         */
    267361rollback_unregister_endpoints:
    268         for (size_t i = 0; i < pipe_count; i++) {
     362        for (i = 0; i < pipe_count; i++) {
    269363                if (pipes[i].present) {
    270364                        usb_pipe_unregister(&pipes[i].pipe);
     
    278372/** Destroy pipes previously created by usb_device_create_pipes.
    279373 *
    280  * @param[in] usb_dev USB device.
    281  */
    282 void usb_device_destroy_pipes(usb_device_t *usb_dev)
    283 {
    284         assert(usb_dev);
    285         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{
    286379        /* Destroy the pipes. */
    287         for (size_t i = 0; i < usb_dev->pipes_count; ++i) {
     380        for (size_t i = 0; i < pipes_count; ++i) {
     381                assert(pipes);
    288382                usb_log_debug2("Unregistering pipe %zu: %spresent.\n",
    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 
    298 usb_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 
    304 usb_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 
    315 usb_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 
    326 int usb_device_get_iface_number(usb_device_t *usb_dev)
    327 {
    328         assert(usb_dev);
    329         return usb_dev->interface_no;
    330 }
    331 
    332 devman_handle_t usb_device_get_devman_handle(usb_device_t *usb_dev)
    333 {
    334         assert(usb_dev);
    335         return usb_dev->handle;
    336 }
    337 
    338 const usb_device_descriptors_t *usb_device_descriptors(usb_device_t *usb_dev)
    339 {
    340         assert(usb_dev);
    341         return &usb_dev->descriptors;
    342 }
    343 
    344 const 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  */
    357 static 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         }
     383                    i, pipes[i].present ? "" : "not ");
     384                if (pipes[i].present)
     385                        usb_pipe_unregister(&pipes[i].pipe);
     386        }
     387        free(pipes);
    370388}
    371389
     
    379397 * @return Error code.
    380398 */
    381 static 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)
     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)
    384401{
    385402        assert(usb_dev != NULL);
    386         assert(errstr_ptr);
     403        assert(ddf_dev != NULL);
    387404
    388405        *errstr_ptr = NULL;
    389406
    390407        usb_dev->ddf_dev = ddf_dev;
    391         usb_dev->handle = handle;
    392         usb_dev->interface_no = interface_no;
    393408        usb_dev->driver_data = NULL;
    394         usb_dev->descriptors.full_config = NULL;
    395         usb_dev->descriptors.full_config_size = 0;
     409        usb_dev->descriptors.configuration = NULL;
    396410        usb_dev->pipes_count = 0;
    397411        usb_dev->pipes = NULL;
    398412
    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;
     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;
    404433        }
    405434
    406435        /* This pipe was registered by the hub driver,
    407436         * during device initialization. */
    408         int rc = usb_pipe_initialize_default_control(
    409             &usb_dev->ctrl_pipe, usb_dev->bus_session);
    410         if (rc != EOK) {
    411                 usb_dev_disconnect(usb_dev->bus_session);
     437        rc = usb_pipe_initialize_default_control(
     438            &usb_dev->ctrl_pipe, &usb_dev->wire);
     439        if (rc != EOK) {
    412440                *errstr_ptr = "default control pipe initialization";
    413441                return rc;
    414442        }
    415443
     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
    416451        /* Retrieve standard descriptors. */
    417         rc = usb_device_retrieve_descriptors(usb_dev);
     452        rc = usb_device_retrieve_descriptors(
     453            &usb_dev->ctrl_pipe, &usb_dev->descriptors);
    418454        if (rc != EOK) {
    419455                *errstr_ptr = "descriptor retrieval";
    420                 usb_dev_disconnect(usb_dev->bus_session);
     456                usb_hc_connection_close(&usb_dev->hc_conn);
    421457                return rc;
    422458        }
     
    427463         * controlling a device. */
    428464        rc = usb_alternate_interfaces_init(&usb_dev->alternate_interfaces,
    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 
     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);
    442487        return EOK;
    443488}
    444489
    445 static 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 
    465 int 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(EXCHANGE_ATOMIC,
    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 
    491 void 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 
    500 usb_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(
    506             EXCHANGE_ATOMIC, handle, IPC_FLAG_BLOCKING);
    507         int ret = usb_device_get_info(sess, &h, &iface_no);
    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 
    525 void 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 
    533 const 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 
    541 ddf_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 
    550 async_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 
    556 void usb_device_bus_exchange_end(async_exch_t *exch)
    557 {
    558         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        }
    559508}
    560509
     
    572521}
    573522
    574 void * usb_device_data_get(usb_device_t *usb_dev)
    575 {
    576         assert(usb_dev);
    577         return usb_dev->driver_data;
    578 }
    579 
    580523/**
    581524 * @}
Note: See TracChangeset for help on using the changeset viewer.