Ignore:
File:
1 edited

Legend:

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

    r58563585 r56fd7cf  
    2727 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2828 */
    29 
    3029/** @addtogroup libusbdev
    3130 * @{
     
    3433 * USB device driver framework.
    3534 */
    36 
    37 #include <usb_iface.h>
    38 #include <usb/dev/alternate_ifaces.h>
    39 #include <usb/dev/device.h>
    40 #include <usb/dev/pipes.h>
     35#include <usb/dev/driver.h>
    4136#include <usb/dev/request.h>
    4237#include <usb/debug.h>
    43 #include <usb/descriptor.h>
    44 #include <usb/usb.h>
    45 
     38#include <usb/dev.h>
     39#include <errno.h>
     40#include <str_error.h>
    4641#include <assert.h>
    47 #include <async.h>
    48 #include <devman.h>
    49 #include <errno.h>
    50 #include <stdlib.h>
    51 
    52 #include <ddf/driver.h>
    53 
    54 /** USB device structure. */
    55 typedef struct usb_device {
    56         /** Connection to device on USB bus */
    57         usb_dev_session_t *bus_session;
    58        
    59         /** devman handle */
    60         devman_handle_t handle;
    61        
    62         /** The default control pipe. */
    63         usb_pipe_t ctrl_pipe;
    64        
    65         /** Other endpoint pipes.
    66          *
    67          * This is an array of other endpoint pipes in the same order as
    68          * in usb_driver_t.
    69          */
    70         usb_endpoint_mapping_t *pipes;
    71        
    72         /** Number of other endpoint pipes. */
    73         size_t pipes_count;
    74        
    75         /** Current interface.
    76          *
    77          * Usually, drivers operate on single interface only.
    78          * This item contains the value of the interface or -1 for any.
    79          */
    80         int interface_no;
    81        
    82         /** Alternative interfaces. */
    83         usb_alternate_interfaces_t alternate_interfaces;
    84        
    85         /** Some useful descriptors for USB device. */
    86         usb_device_descriptors_t descriptors;
    87        
    88         /** Generic DDF device backing this one. DO NOT TOUCH! */
    89         ddf_dev_t *ddf_dev;
    90        
    91         /** Custom driver data.
    92          *
    93          * Do not use the entry in generic device, that is already used
    94          * by the framework.
    95          */
    96         void *driver_data;
    97 } 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}
    9876
    9977/** Count number of pipes the driver expects.
     
    10280 * @return Number of pipes (excluding default control pipe).
    10381 */
    104 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)
    10584{
    10685        size_t count;
    10786        for (count = 0; endpoints != NULL && endpoints[count] != NULL; ++count);
    10887        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;
    109179}
    110180
     
    131201 * @return Error code.
    132202 */
    133 int usb_device_select_interface(usb_device_t *usb_dev,
    134     uint8_t alternate_setting, const usb_endpoint_description_t **endpoints)
    135 {
    136         assert(usb_dev);
    137 
    138         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) {
    139207                return EINVAL;
    140208        }
    141209
     210        /* Destroy existing pipes. */
     211        destroy_current_pipes(dev);
     212
    142213        /* Change the interface itself. */
    143         int rc = usb_request_set_interface(&usb_dev->ctrl_pipe,
    144             usb_dev->interface_no, alternate_setting);
    145         if (rc != EOK) {
    146                 return rc;
    147         }
    148        
    149         /* Change current alternative */
    150         usb_dev->alternate_interfaces.current = alternate_setting;
    151 
    152         /* Destroy existing pipes. */
    153         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        }
    154219
    155220        /* Create new pipes. */
    156         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);
    157225
    158226        return rc;
     
    165233 * @return Error code.
    166234 */
    167 static int usb_device_retrieve_descriptors(usb_device_t *usb_dev)
    168 {
    169         assert(usb_dev);
    170         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);
    171246
    172247        /* Get the device descriptor. */
    173         int rc = usb_request_get_device_descriptor(&usb_dev->ctrl_pipe,
    174             &usb_dev->descriptors.device);
    175         if (rc != EOK) {
    176                 return rc;
     248        rc = usb_request_get_device_descriptor(ctrl_pipe, &descriptors->device);
     249        if (rc != EOK) {
     250                goto leave;
    177251        }
    178252
    179253        /* Get the full configuration descriptor. */
    180254        rc = usb_request_get_full_configuration_descriptor_alloc(
    181             &usb_dev->ctrl_pipe, 0,
    182             &usb_dev->descriptors.full_config,
    183             &usb_dev->descriptors.full_config_size);
    184 
     255            ctrl_pipe, 0, (void **) &descriptors->configuration,
     256            &descriptors->configuration_size);
     257
     258leave:
     259        usb_pipe_end_long_transfer(ctrl_pipe);
    185260
    186261        return rc;
     
    191266 * @param[in] descriptors Where to store the descriptors.
    192267 */
    193 static void usb_device_release_descriptors(usb_device_t *usb_dev)
    194 {
    195         assert(usb_dev);
    196         free(usb_dev->descriptors.full_config);
    197         usb_dev->descriptors.full_config = NULL;
    198         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;
    199273}
    200274
     
    206280 * - registers endpoints with the host controller
    207281 *
     282 * @param[in] wire Initialized backing connection to the host controller.
    208283 * @param[in] endpoints Endpoints description, NULL terminated.
    209284 * @param[in] config_descr Configuration descriptor of active configuration.
     
    217292 * @return Error code.
    218293 */
    219 int usb_device_create_pipes(usb_device_t *usb_dev,
    220     const usb_endpoint_description_t **endpoints)
    221 {
    222         assert(usb_dev);
    223         assert(usb_dev->descriptors.full_config);
    224         assert(usb_dev->pipes == NULL);
    225         assert(usb_dev->pipes_count == 0);
    226 
    227         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);
    228309        if (pipe_count == 0) {
     310                if (pipes_count_ptr)
     311                        *pipes_count_ptr = pipe_count;
     312                *pipes_ptr = NULL;
    229313                return EOK;
    230314        }
    231315
    232         usb_endpoint_mapping_t *pipes =
    233             calloc(pipe_count, sizeof(usb_endpoint_mapping_t));
     316        usb_endpoint_mapping_t *pipes
     317            = calloc(pipe_count, sizeof(usb_endpoint_mapping_t));
    234318        if (pipes == NULL) {
    235319                return ENOMEM;
     
    237321
    238322        /* Now initialize. */
    239         for (size_t i = 0; i < pipe_count; i++) {
     323        for (i = 0; i < pipe_count; i++) {
    240324                pipes[i].description = endpoints[i];
    241                 pipes[i].interface_no = usb_dev->interface_no;
    242                 pipes[i].interface_setting =
    243                     usb_dev->alternate_interfaces.current;
     325                pipes[i].interface_no = interface_no;
     326                pipes[i].interface_setting = interface_setting;
    244327        }
    245328
    246329        /* Find the mapping from configuration descriptor. */
    247         int rc = usb_pipe_initialize_from_configuration(pipes, pipe_count,
    248             usb_dev->descriptors.full_config,
    249             usb_dev->descriptors.full_config_size,
    250             usb_dev->bus_session);
     330        rc = usb_pipe_initialize_from_configuration(pipes, pipe_count,
     331            config_descr, config_descr_size, wire);
    251332        if (rc != EOK) {
    252333                free(pipes);
     
    255336
    256337        /* Register created pipes. */
    257         for (size_t i = 0; i < pipe_count; i++) {
     338        for (i = 0; i < pipe_count; i++) {
    258339                if (pipes[i].present) {
    259340                        rc = usb_pipe_register(&pipes[i].pipe,
     
    265346        }
    266347
    267         usb_dev->pipes = pipes;
    268         usb_dev->pipes_count = pipe_count;
     348        *pipes_ptr = pipes;
     349        if (pipes_count_ptr != NULL) {
     350                *pipes_count_ptr = pipe_count;
     351        }
    269352
    270353        return EOK;
     
    277360         */
    278361rollback_unregister_endpoints:
    279         for (size_t i = 0; i < pipe_count; i++) {
     362        for (i = 0; i < pipe_count; i++) {
    280363                if (pipes[i].present) {
    281364                        usb_pipe_unregister(&pipes[i].pipe);
     
    289372/** Destroy pipes previously created by usb_device_create_pipes.
    290373 *
    291  * @param[in] usb_dev USB device.
    292  *
    293  */
    294 void usb_device_destroy_pipes(usb_device_t *usb_dev)
    295 {
    296         assert(usb_dev);
    297         assert(usb_dev->pipes || usb_dev->pipes_count == 0);
    298        
     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{
    299379        /* Destroy the pipes. */
    300         for (size_t i = 0; i < usb_dev->pipes_count; ++i) {
     380        for (size_t i = 0; i < pipes_count; ++i) {
     381                assert(pipes);
    301382                usb_log_debug2("Unregistering pipe %zu: %spresent.\n",
    302                     i, usb_dev->pipes[i].present ? "" : "not ");
    303                 if (usb_dev->pipes[i].present)
    304                         usb_pipe_unregister(&usb_dev->pipes[i].pipe);
    305         }
    306        
    307         free(usb_dev->pipes);
    308         usb_dev->pipes = NULL;
    309         usb_dev->pipes_count = 0;
    310 }
    311 
    312 usb_pipe_t *usb_device_get_default_pipe(usb_device_t *usb_dev)
    313 {
    314         assert(usb_dev);
    315         return &usb_dev->ctrl_pipe;
    316 }
    317 
    318 usb_endpoint_mapping_t *usb_device_get_mapped_ep_desc(usb_device_t *usb_dev,
    319     const usb_endpoint_description_t *desc)
    320 {
    321         assert(usb_dev);
    322         for (unsigned i = 0; i < usb_dev->pipes_count; ++i) {
    323                 if (usb_dev->pipes[i].description == desc)
    324                         return &usb_dev->pipes[i];
    325         }
    326         return NULL;
    327 }
    328 
    329 usb_endpoint_mapping_t * usb_device_get_mapped_ep(
    330     usb_device_t *usb_dev, usb_endpoint_t ep)
    331 {
    332         assert(usb_dev);
    333         for (unsigned i = 0; i < usb_dev->pipes_count; ++i) {
    334                 if (usb_dev->pipes[i].pipe.endpoint_no == ep)
    335                         return &usb_dev->pipes[i];
    336         }
    337         return NULL;
    338 }
    339 
    340 int usb_device_get_iface_number(usb_device_t *usb_dev)
    341 {
    342         assert(usb_dev);
    343         return usb_dev->interface_no;
    344 }
    345 
    346 devman_handle_t usb_device_get_devman_handle(usb_device_t *usb_dev)
    347 {
    348         assert(usb_dev);
    349         return usb_dev->handle;
    350 }
    351 
    352 const usb_device_descriptors_t *usb_device_descriptors(usb_device_t *usb_dev)
    353 {
    354         assert(usb_dev);
    355         return &usb_dev->descriptors;
    356 }
    357 
    358 const usb_alternate_interfaces_t * usb_device_get_alternative_ifaces(
    359     usb_device_t *usb_dev)
    360 {
    361         assert(usb_dev);
    362         return &usb_dev->alternate_interfaces;
    363 }
    364 
    365 /** Clean instance of a USB device.
    366  *
    367  * @param dev Device to be de-initialized.
    368  *
    369  * Does not free/destroy supplied pointer.
    370  */
    371 static void usb_device_fini(usb_device_t *usb_dev)
    372 {
    373         if (usb_dev) {
    374                 /* Destroy existing pipes. */
    375                 usb_device_destroy_pipes(usb_dev);
    376                 /* Ignore errors and hope for the best. */
    377                 usb_alternate_interfaces_deinit(&usb_dev->alternate_interfaces);
    378                 usb_device_release_descriptors(usb_dev);
    379                 free(usb_dev->driver_data);
    380                 usb_dev->driver_data = NULL;
    381                 usb_dev_disconnect(usb_dev->bus_session);
    382                 usb_dev->bus_session = NULL;
    383         }
     383                    i, pipes[i].present ? "" : "not ");
     384                if (pipes[i].present)
     385                        usb_pipe_unregister(&pipes[i].pipe);
     386        }
     387        free(pipes);
    384388}
    385389
     
    393397 * @return Error code.
    394398 */
    395 static int usb_device_init(usb_device_t *usb_dev, ddf_dev_t *ddf_dev,
    396     const usb_endpoint_description_t **endpoints, const char **errstr_ptr,
    397     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)
    398401{
    399402        assert(usb_dev != NULL);
    400         assert(errstr_ptr);
     403        assert(ddf_dev != NULL);
    401404
    402405        *errstr_ptr = NULL;
    403406
    404407        usb_dev->ddf_dev = ddf_dev;
    405         usb_dev->handle = handle;
    406         usb_dev->interface_no = interface_no;
    407408        usb_dev->driver_data = NULL;
    408         usb_dev->descriptors.full_config = NULL;
    409         usb_dev->descriptors.full_config_size = 0;
     409        usb_dev->descriptors.configuration = NULL;
    410410        usb_dev->pipes_count = 0;
    411411        usb_dev->pipes = NULL;
    412412
    413         usb_dev->bus_session = usb_dev_connect(handle);
    414 
    415         if (!usb_dev->bus_session) {
    416                 *errstr_ptr = "device bus session create";
    417                 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;
    418433        }
    419434
    420435        /* This pipe was registered by the hub driver,
    421436         * during device initialization. */
    422         int rc = usb_pipe_initialize_default_control(
    423             &usb_dev->ctrl_pipe, usb_dev->bus_session);
    424         if (rc != EOK) {
    425                 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) {
    426440                *errstr_ptr = "default control pipe initialization";
    427441                return rc;
    428442        }
    429443
     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
    430451        /* Retrieve standard descriptors. */
    431         rc = usb_device_retrieve_descriptors(usb_dev);
     452        rc = usb_device_retrieve_descriptors(
     453            &usb_dev->ctrl_pipe, &usb_dev->descriptors);
    432454        if (rc != EOK) {
    433455                *errstr_ptr = "descriptor retrieval";
    434                 usb_dev_disconnect(usb_dev->bus_session);
     456                usb_hc_connection_close(&usb_dev->hc_conn);
    435457                return rc;
    436458        }
     
    441463         * controlling a device. */
    442464        rc = usb_alternate_interfaces_init(&usb_dev->alternate_interfaces,
    443             usb_dev->descriptors.full_config,
    444             usb_dev->descriptors.full_config_size, usb_dev->interface_no);
    445 
    446         if (endpoints) {
    447                 /* Create and register other pipes than default control (EP 0)*/
    448                 rc = usb_device_create_pipes(usb_dev, endpoints);
    449                 if (rc != EOK) {
    450                         usb_device_fini(usb_dev);
    451                         *errstr_ptr = "pipes initialization";
    452                         return rc;
    453                 }
    454         }
    455 
     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);
    456487        return EOK;
    457488}
    458489
    459 static int usb_device_get_info(async_sess_t *sess, devman_handle_t *handle,
    460         int *iface_no)
    461 {
    462         assert(handle);
    463         assert(iface_no);
    464        
    465         async_exch_t *exch = async_exchange_begin(sess);
    466         if (!exch)
    467                 return EPARTY;
    468        
    469         int ret = usb_get_my_device_handle(exch, handle);
    470         if (ret == EOK) {
    471                 ret = usb_get_my_interface(exch, iface_no);
    472                 if (ret == ENOTSUP) {
    473                         *iface_no = -1;
    474                         ret = EOK;
    475                 }
    476         }
    477        
    478         async_exchange_end(exch);
    479         return ret;
    480 }
    481 
    482 int usb_device_create_ddf(ddf_dev_t *ddf_dev,
    483     const usb_endpoint_description_t **desc, const char **err)
    484 {
    485         assert(ddf_dev);
    486         assert(err);
    487 
    488         devman_handle_t h = 0;
    489         int iface_no = -1;
    490 
    491         async_sess_t *sess = devman_parent_device_connect(
    492             ddf_dev_get_handle(ddf_dev), IPC_FLAG_BLOCKING);
    493         if (sess == NULL)
    494                 return ENOMEM;
    495         const int ret = usb_device_get_info(sess, &h, &iface_no);
    496         async_hangup(sess);
    497         if (ret != EOK)
    498                 return ret;
    499 
    500         usb_device_t *usb_dev =
    501             ddf_dev_data_alloc(ddf_dev, sizeof(usb_device_t));
    502         if (usb_dev == NULL) {
    503                 *err = "DDF data alloc";
    504                 return ENOMEM;
    505         }
    506        
    507         return usb_device_init(usb_dev, ddf_dev, desc, err, h, iface_no);
    508 }
    509 
    510 void usb_device_destroy_ddf(ddf_dev_t *ddf_dev)
    511 {
    512         assert(ddf_dev);
    513         usb_device_t *usb_dev = ddf_dev_data_get(ddf_dev);
    514         assert(usb_dev);
    515         usb_device_fini(usb_dev);
    516         return;
    517 }
    518 
    519 usb_device_t * usb_device_create(devman_handle_t handle)
    520 {
    521         devman_handle_t h = 0;
    522         int iface_no = -1;
    523 
    524         async_sess_t *sess = devman_device_connect(handle, IPC_FLAG_BLOCKING);
    525         int ret = usb_device_get_info(sess, &h, &iface_no);
    526         if (sess)
    527                 async_hangup(sess);
    528         if (ret != EOK)
    529                 return NULL;
    530 
    531         usb_device_t *usb_dev = malloc(sizeof(usb_device_t));
    532         if (!usb_dev)
    533                 return NULL;
    534 
    535         const char* dummy = NULL;
    536         ret = usb_device_init(usb_dev, NULL, NULL, &dummy, handle, iface_no);
    537         if (ret != EOK) {
    538                 free(usb_dev);
    539                 usb_dev = NULL;
    540         }
    541         return usb_dev;
    542 }
    543 
    544 void usb_device_destroy(usb_device_t *usb_dev)
    545 {
    546         if (usb_dev) {
    547                 usb_device_fini(usb_dev);
    548                 free(usb_dev);
    549         }
    550 }
    551 
    552 const char *usb_device_get_name(usb_device_t *usb_dev)
    553 {
    554         assert(usb_dev);
    555         if (usb_dev->ddf_dev)
    556                 return ddf_dev_get_name(usb_dev->ddf_dev);
    557         return NULL;
    558 }
    559 
    560 ddf_fun_t *usb_device_ddf_fun_create(usb_device_t *usb_dev, fun_type_t ftype,
    561     const char* name)
    562 {
    563         assert(usb_dev);
    564         if (usb_dev->ddf_dev)
    565                 return ddf_fun_create(usb_dev->ddf_dev, ftype, name);
    566         return NULL;
    567 }
    568 
    569 async_exch_t * usb_device_bus_exchange_begin(usb_device_t *usb_dev)
    570 {
    571         assert(usb_dev);
    572         return async_exchange_begin(usb_dev->bus_session);
    573 }
    574 
    575 void usb_device_bus_exchange_end(async_exch_t *exch)
    576 {
    577         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        }
    578508}
    579509
     
    591521}
    592522
    593 void * usb_device_data_get(usb_device_t *usb_dev)
    594 {
    595         assert(usb_dev);
    596         return usb_dev->driver_data;
    597 }
    598 
    599523/**
    600524 * @}
Note: See TracChangeset for help on using the changeset viewer.