Changeset d083126 in mainline for uspace/lib/usbdev


Ignore:
Timestamp:
2011-10-13T13:20:26Z (14 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3a5506a
Parents:
cff3fb6 (diff), 22a2b763 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge initial USB unplug support.

Support device_remove and device_gone in libusbdev.
usbhub and uhcirh try to unbind and destroy functions of attached devices.
add unplug support for usbhub driver (only works on empty hubs as there is no support in other drivers).

Drivers to go:

usbmid
usbflbk
usbhid
usbmast
usbmouse

Tested on:

qemu UHCI and emulated hub,
ICH8 hw and Alcor Micro Corp. USB Hub

Location:
uspace/lib/usbdev
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbdev/include/usb/dev/driver.h

    rcff3fb6 rd083126  
    9696        usb_device_descriptors_t descriptors;
    9797
    98         /** Generic DDF device backing this one. */
     98        /** Generic DDF device backing this one. RO: DO NOT TOUCH!*/
    9999        ddf_dev_t *ddf_dev;
    100100        /** Custom driver data.
     
    112112/** USB driver ops. */
    113113typedef struct {
    114         /** Callback when new device is about to be controlled by the driver. */
    115         int (*add_device)(usb_device_t *);
     114        /** Callback when a new device was added to the system. */
     115        int (*device_add)(usb_device_t *);
     116        /** Callback when a device is about to be removed from the system. */
     117        int (*device_rem)(usb_device_t *);
     118        /** Callback when a device was removed from the system. */
     119        int (*device_gone)(usb_device_t *);
    116120} usb_driver_ops_t;
    117121
     
    163167
    164168int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *);
    165 int usb_device_create_pipes(ddf_dev_t *, usb_device_connection_t *,
     169int usb_device_create_pipes(const ddf_dev_t *, usb_device_connection_t *,
    166170    usb_endpoint_description_t **, uint8_t *, size_t, int, int,
    167171    usb_endpoint_mapping_t **, size_t *);
    168 int usb_device_destroy_pipes(ddf_dev_t *, usb_endpoint_mapping_t *, size_t);
     172int usb_device_destroy_pipes(const ddf_dev_t *, usb_endpoint_mapping_t *, size_t);
    169173int usb_device_create(ddf_dev_t *, usb_endpoint_description_t **, usb_device_t **, const char **);
    170174void usb_device_destroy(usb_device_t *);
  • uspace/lib/usbdev/include/usb/dev/hub.h

    rcff3fb6 rd083126  
    3838#define LIBUSBDEV_HUB_H_
    3939
     40#include <ddf/driver.h>
    4041#include <sys/types.h>
    4142#include <usb/hc.h>
    4243
    4344int usb_hc_new_device_wrapper(ddf_dev_t *, usb_hc_connection_t *, usb_speed_t,
    44     int (*)(int, void *), int, void *,
    45     usb_address_t *, devman_handle_t *,
    46     ddf_dev_ops_t *, void *, ddf_fun_t **);
     45    int (*)(void *), void *, usb_address_t *, ddf_dev_ops_t *, void *,
     46    ddf_fun_t **);
    4747
    4848/** Info about device attached to host controller.
     
    5555        /** Device address. */
    5656        usb_address_t address;
    57         /** Devman handle of the device. */
    58         devman_handle_t handle;
    59 } usb_hc_attached_device_t;
     57        /** DDF function (external) of the device. */
     58        ddf_fun_t *fun;
     59} usb_hub_attached_device_t;
    6060
    6161usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_speed_t);
    6262int usb_hc_register_device(usb_hc_connection_t *,
    63     const usb_hc_attached_device_t *);
     63    const usb_hub_attached_device_t *);
    6464int usb_hc_unregister_device(usb_hc_connection_t *, usb_address_t);
    6565
  • uspace/lib/usbdev/include/usb/dev/pipes.h

    rcff3fb6 rd083126  
    159159    usb_device_connection_t *, usb_hc_connection_t *);
    160160int usb_device_connection_initialize_from_device(usb_device_connection_t *,
    161     ddf_dev_t *);
     161    const ddf_dev_t *);
    162162int usb_device_connection_initialize(usb_device_connection_t *,
    163163    devman_handle_t, usb_address_t);
    164164
    165 int usb_device_get_assigned_interface(ddf_dev_t *);
     165int usb_device_get_assigned_interface(const ddf_dev_t *);
    166166
    167167int usb_pipe_initialize(usb_pipe_t *, usb_device_connection_t *,
     
    185185int usb_pipe_control_read(usb_pipe_t *, const void *, size_t,
    186186    void *, size_t, size_t *);
    187 int usb_pipe_control_write(usb_pipe_t *, void *, size_t,
    188     void *, size_t);
     187int usb_pipe_control_write(usb_pipe_t *, const void *, size_t,
     188    const void *, size_t);
    189189
    190190#endif
  • uspace/lib/usbdev/include/usb/dev/recognise.h

    rcff3fb6 rd083126  
    5151
    5252int usb_device_register_child_in_devman(usb_address_t, devman_handle_t,
    53     ddf_dev_t *, devman_handle_t *, ddf_dev_ops_t *, void *, ddf_fun_t **);
     53    ddf_dev_t *, ddf_dev_ops_t *, void *, ddf_fun_t **);
    5454
    5555#endif
  • uspace/lib/usbdev/src/devdrv.c

    rcff3fb6 rd083126  
    4141#include <assert.h>
    4242
    43 static int generic_add_device(ddf_dev_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 *);
    4446
    4547static driver_ops_t generic_driver_ops = {
    46         .add_device = generic_add_device
     48        .add_device = generic_device_add,
     49        .dev_remove = generic_device_remove,
     50        .dev_gone = generic_device_gone,
    4751};
    4852static driver_t generic_driver = {
     
    123127        return EOK;
    124128}
    125 
    126 /** Callback when new device is supposed to be controlled by this driver.
    127  *
    128  * This callback is a wrapper for USB specific version of @c add_device.
     129/*----------------------------------------------------------------------------*/
     130/** Callback when a new device is supposed to be controlled by this driver.
     131 *
     132 * This callback is a wrapper for USB specific version of @c device_add.
    129133 *
    130134 * @param gen_dev Device structure as prepared by DDF.
    131135 * @return Error code.
    132136 */
    133 int generic_add_device(ddf_dev_t *gen_dev)
     137int generic_device_add(ddf_dev_t *gen_dev)
    134138{
    135139        assert(driver);
    136140        assert(driver->ops);
    137         assert(driver->ops->add_device);
     141        assert(driver->ops->device_add);
    138142
    139143        int rc;
     
    147151                return rc;
    148152        }
    149 
    150         return driver->ops->add_device(dev);
    151 }
    152 
     153        gen_dev->driver_data = dev;
     154
     155        return driver->ops->device_add(dev);
     156}
     157/*----------------------------------------------------------------------------*/
     158/** Callback when a device is supposed to be removed from the system.
     159 *
     160 * This callback is a wrapper for USB specific version of @c device_remove.
     161 *
     162 * @param gen_dev Device structure as prepared by DDF.
     163 * @return Error code.
     164 */
     165int generic_device_remove(ddf_dev_t *gen_dev)
     166{
     167        assert(driver);
     168        assert(driver->ops);
     169        if (driver->ops->device_rem == NULL)
     170                return ENOTSUP;
     171        /* Just tell the driver to stop whatever it is doing, keep structures */
     172        return driver->ops->device_rem(gen_dev->driver_data);
     173}
     174/*----------------------------------------------------------------------------*/
     175/** Callback when a device was removed from the system.
     176 *
     177 * This callback is a wrapper for USB specific version of @c device_gone.
     178 *
     179 * @param gen_dev Device structure as prepared by DDF.
     180 * @return Error code.
     181 */
     182int generic_device_gone(ddf_dev_t *gen_dev)
     183{
     184        assert(driver);
     185        assert(driver->ops);
     186        if (driver->ops->device_gone == NULL)
     187                return ENOTSUP;
     188        const int ret = driver->ops->device_gone(gen_dev->driver_data);
     189        if (ret == EOK)
     190                usb_device_destroy(gen_dev->driver_data);
     191
     192        return ret;
     193}
     194/*----------------------------------------------------------------------------*/
    153195/** Destroy existing pipes of a USB device.
    154196 *
     
    275317 * @return Error code.
    276318 */
    277 int usb_device_create_pipes(ddf_dev_t *dev, usb_device_connection_t *wire,
     319int usb_device_create_pipes(const ddf_dev_t *dev, usb_device_connection_t *wire,
    278320    usb_endpoint_description_t **endpoints,
    279321    uint8_t *config_descr, size_t config_descr_size,
     
    349391        }
    350392
    351         usb_hc_connection_close(&hc_conn);
     393        if (usb_hc_connection_close(&hc_conn) != EOK)
     394                usb_log_warning("usb_device_create_pipes(): "
     395                    "Failed to close connection.\n");
    352396
    353397        *pipes_ptr = pipes;
     
    371415        }
    372416
    373         usb_hc_connection_close(&hc_conn);
     417        if (usb_hc_connection_close(&hc_conn) != EOK)
     418                usb_log_warning("usb_device_create_pipes(): "
     419                    "Failed to close connection.\n");
    374420
    375421        /*
     
    395441 * @param[in] pipes_count Number of endpoints.
    396442 */
    397 int usb_device_destroy_pipes(ddf_dev_t *dev,
     443int usb_device_destroy_pipes(const ddf_dev_t *dev,
    398444    usb_endpoint_mapping_t *pipes, size_t pipes_count)
    399445{
     
    426472        }
    427473
    428         usb_hc_connection_close(&hc_conn);
     474        if (usb_hc_connection_close(&hc_conn) != EOK)
     475                usb_log_warning("usb_device_destroy_pipes(): "
     476                    "Failed to close connection.\n");
    429477
    430478        free(pipes);
     
    545593        /* Ignore errors and hope for the best. */
    546594        usb_device_destroy_pipes(dev->ddf_dev, dev->pipes, dev->pipes_count);
    547         if (dev->descriptors.configuration != NULL) {
    548                 free(dev->descriptors.configuration);
    549         }
     595        free(dev->descriptors.configuration);
    550596
    551597        if (dev->alternate_interfaces != NULL) {
    552                 if (dev->alternate_interfaces->alternatives != NULL) {
    553                         free(dev->alternate_interfaces->alternatives);
    554                 }
    555                 free(dev->alternate_interfaces);
    556         }
     598                free(dev->alternate_interfaces->alternatives);
     599        }
     600        free(dev->alternate_interfaces);
    557601
    558602        free(dev);
  • uspace/lib/usbdev/src/hub.c

    rcff3fb6 rd083126  
    3737#include <usb/dev/request.h>
    3838#include <usb/dev/recognise.h>
     39#include <usb/debug.h>
    3940#include <usbhc_iface.h>
    4041#include <errno.h>
     
    5758                assert((conn)); \
    5859                if (!usb_hc_connection_is_opened((conn))) { \
    59                         return ENOENT; \
     60                        usb_log_error("Connection not open.\n"); \
     61                        return ENOTCONN; \
    6062                } \
    6163        } while (false)
     
    9597 */
    9698int usb_hc_register_device(usb_hc_connection_t * connection,
    97     const usb_hc_attached_device_t *attached_device)
     99    const usb_hub_attached_device_t *attached_device)
    98100{
    99101        CHECK_CONNECTION(connection);
     
    105107        int rc = async_req_3_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
    106108            IPC_M_USBHC_BIND_ADDRESS,
    107             attached_device->address, attached_device->handle);
     109            attached_device->address, attached_device->fun->handle);
    108110        async_exchange_end(exch);
    109111       
     
    155157 * The @p enable_port function is expected to enable signaling on given
    156158 * port.
    157  * The two arguments to it can have arbitrary meaning
    158  * (the @p port_no is only a suggestion)
    159  * and are not touched at all by this function
    160  * (they are passed as is to the @p enable_port function).
     159 * The argument can have arbitrary meaning and it is not touched at all
     160 * by this function (it is passed as is to the @p enable_port function).
    161161 *
    162162 * If the @p enable_port fails (i.e. does not return EOK), the device
     
    175175 * @param[in] enable_port Function for enabling signaling through the port the
    176176 *      device is attached to.
    177  * @param[in] port_no Port number (passed through to @p enable_port).
    178177 * @param[in] arg Any data argument to @p enable_port.
    179178 * @param[out] assigned_address USB address of the device.
    180  * @param[out] assigned_handle Devman handle of the new device.
    181179 * @param[in] dev_ops Child device ops.
    182180 * @param[in] new_dev_data Arbitrary pointer to be stored in the child
     
    194192int usb_hc_new_device_wrapper(ddf_dev_t *parent, usb_hc_connection_t *connection,
    195193    usb_speed_t dev_speed,
    196     int (*enable_port)(int port_no, void *arg), int port_no, void *arg,
    197     usb_address_t *assigned_address, devman_handle_t *assigned_handle,
     194    int (*enable_port)(void *arg), void *arg, usb_address_t *assigned_address,
    198195    ddf_dev_ops_t *dev_ops, void *new_dev_data, ddf_fun_t **new_fun)
    199196{
     
    224221        usb_address_t dev_addr = usb_hc_request_address(&hc_conn, dev_speed);
    225222        if (dev_addr < 0) {
    226                 usb_hc_connection_close(&hc_conn);
    227                 return EADDRNOTAVAIL;
     223                rc = EADDRNOTAVAIL;
     224                goto close_connection;
    228225        }
    229226
     
    279276         * device address.
    280277         */
    281         rc = enable_port(port_no, arg);
     278        rc = enable_port(arg);
    282279        if (rc != EOK) {
    283280                goto leave_release_default_address;
     
    320317         */
    321318        /* FIXME: create device_register that will get opened ctrl pipe. */
    322         devman_handle_t child_handle;
     319        ddf_fun_t *child_fun;
    323320        rc = usb_device_register_child_in_devman(dev_addr, dev_conn.hc_handle,
    324             parent, &child_handle,
    325             dev_ops, new_dev_data, new_fun);
     321            parent, dev_ops, new_dev_data, &child_fun);
    326322        if (rc != EOK) {
    327323                rc = ESTALL;
     
    332328         * And now inform the host controller about the handle.
    333329         */
    334         usb_hc_attached_device_t new_device = {
     330        usb_hub_attached_device_t new_device = {
    335331                .address = dev_addr,
    336                 .handle = child_handle
     332                .fun = child_fun,
    337333        };
    338334        rc = usb_hc_register_device(&hc_conn, &new_device);
     
    341337                goto leave_release_free_address;
    342338        }
    343        
    344         usb_hc_connection_close(&hc_conn);
     339
    345340
    346341        /*
     
    350345                *assigned_address = dev_addr;
    351346        }
    352         if (assigned_handle != NULL) {
    353                 *assigned_handle = child_handle;
    354         }
    355 
    356         return EOK;
    357 
    358 
     347        if (new_fun != NULL) {
     348                *new_fun = child_fun;
     349        }
     350
     351        rc = EOK;
     352        goto close_connection;
    359353
    360354        /*
     
    368362        usb_hc_unregister_device(&hc_conn, dev_addr);
    369363
    370         usb_hc_connection_close(&hc_conn);
     364close_connection:
     365        if (usb_hc_connection_close(&hc_conn) != EOK)
     366                usb_log_warning("usb_hc_new_device_wrapper(): Failed to close "
     367                    "connection.\n");
    371368
    372369        return rc;
  • uspace/lib/usbdev/src/pipes.c

    rcff3fb6 rd083126  
    5252 * @return USB address or error code.
    5353 */
    54 static usb_address_t get_my_address(async_sess_t *sess, ddf_dev_t *dev)
     54static usb_address_t get_my_address(async_sess_t *sess, const ddf_dev_t *dev)
    5555{
    5656        async_exch_t *exch = async_exchange_begin(sess);
     
    7878 * @return Interface number (negative code means any).
    7979 */
    80 int usb_device_get_assigned_interface(ddf_dev_t *device)
     80int usb_device_get_assigned_interface(const ddf_dev_t *device)
    8181{
    8282        async_sess_t *parent_sess =
     
    108108 */
    109109int usb_device_connection_initialize_from_device(
    110     usb_device_connection_t *connection, ddf_dev_t *dev)
     110    usb_device_connection_t *connection, const ddf_dev_t *dev)
    111111{
    112112        assert(connection);
  • uspace/lib/usbdev/src/pipesio.c

    rcff3fb6 rd083126  
    469469 */
    470470static int usb_pipe_control_write_no_check(usb_pipe_t *pipe,
    471     void *setup_buffer, size_t setup_buffer_size,
    472     void *data_buffer, size_t data_buffer_size)
     471    const void *setup_buffer, size_t setup_buffer_size,
     472    const void *data_buffer, size_t data_buffer_size)
    473473{
    474474        /* Ensure serialization over the phone. */
     
    536536 */
    537537int usb_pipe_control_write(usb_pipe_t *pipe,
    538     void *setup_buffer, size_t setup_buffer_size,
    539     void *data_buffer, size_t data_buffer_size)
     538    const void *setup_buffer, size_t setup_buffer_size,
     539    const void *data_buffer, size_t data_buffer_size)
    540540{
    541541        assert(pipe);
  • uspace/lib/usbdev/src/recognise.c

    rcff3fb6 rd083126  
    339339 * @param[in] hc_handle Handle of the host controller.
    340340 * @param[in] parent Parent device.
    341  * @param[out] child_handle Handle of the child device.
    342341 * @param[in] dev_ops Child device ops.
    343342 * @param[in] dev_data Arbitrary pointer to be stored in the child
     
    348347 */
    349348int usb_device_register_child_in_devman(usb_address_t address,
    350     devman_handle_t hc_handle,
    351     ddf_dev_t *parent, devman_handle_t *child_handle,
     349    devman_handle_t hc_handle, ddf_dev_t *parent,
    352350    ddf_dev_ops_t *dev_ops, void *dev_data, ddf_fun_t **child_fun)
    353351{
     
    414412        }
    415413
    416         if (child_handle != NULL) {
    417                 *child_handle = child->handle;
    418         }
    419 
    420414        if (child_fun != NULL) {
    421415                *child_fun = child;
Note: See TracChangeset for help on using the changeset viewer.