Changeset c2245a3 in mainline for uspace/lib


Ignore:
Timestamp:
2011-11-10T20:03:48Z (14 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fa76f81
Parents:
27ca3a3 (diff), 747ef72 (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 with mainline

Location:
uspace/lib
Files:
38 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/drv/generic/remote_usb.c

    r27ca3a3 rc2245a3  
    4040
    4141
    42 static void remote_usb_get_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     42static void remote_usb_get_my_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    4343static void remote_usb_get_interface(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
    4444static void remote_usb_get_hc_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
     
    4747/** Remote USB interface operations. */
    4848static remote_iface_func_ptr_t remote_usb_iface_ops [] = {
    49         remote_usb_get_address,
    50         remote_usb_get_interface,
    51         remote_usb_get_hc_handle
     49        [IPC_M_USB_GET_MY_ADDRESS] = remote_usb_get_my_address,
     50        [IPC_M_USB_GET_INTERFACE] = remote_usb_get_interface,
     51        [IPC_M_USB_GET_HOST_CONTROLLER_HANDLE] = remote_usb_get_hc_handle,
    5252};
    5353
     
    6161
    6262
    63 void remote_usb_get_address(ddf_fun_t *fun, void *iface,
     63void remote_usb_get_my_address(ddf_fun_t *fun, void *iface,
    6464    ipc_callid_t callid, ipc_call_t *call)
    6565{
    6666        usb_iface_t *usb_iface = (usb_iface_t *) iface;
    6767
    68         if (usb_iface->get_address == NULL) {
     68        if (usb_iface->get_my_address == NULL) {
    6969                async_answer_0(callid, ENOTSUP);
    7070                return;
    7171        }
    7272
    73         devman_handle_t handle = DEV_IPC_GET_ARG1(*call);
    74 
    7573        usb_address_t address;
    76         int rc = usb_iface->get_address(fun, handle, &address);
     74        int rc = usb_iface->get_my_address(fun, &address);
    7775        if (rc != EOK) {
    7876                async_answer_0(callid, rc);
  • uspace/lib/drv/generic/remote_usbhc.c

    r27ca3a3 rc2245a3  
    5555static remote_iface_func_ptr_t remote_usbhc_iface_ops[] = {
    5656        [IPC_M_USBHC_REQUEST_ADDRESS] = remote_usbhc_request_address,
     57        [IPC_M_USBHC_RELEASE_ADDRESS] = remote_usbhc_release_address,
    5758        [IPC_M_USBHC_BIND_ADDRESS] = remote_usbhc_bind_address,
    5859        [IPC_M_USBHC_GET_HANDLE_BY_ADDRESS] = remote_usbhc_find_by_address,
    59         [IPC_M_USBHC_RELEASE_ADDRESS] = remote_usbhc_release_address,
    6060
    6161        [IPC_M_USBHC_REGISTER_ENDPOINT] = remote_usbhc_register_endpoint,
     
    118118        }
    119119
    120         usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
    121 
    122         usb_address_t address;
    123         int rc = usb_iface->request_address(fun, speed, &address);
     120        usb_address_t address = DEV_IPC_GET_ARG1(*call);
     121        const bool strict = DEV_IPC_GET_ARG2(*call);
     122        const usb_speed_t speed = DEV_IPC_GET_ARG3(*call);
     123
     124        const int rc = usb_iface->request_address(fun, &address, strict, speed);
    124125        if (rc != EOK) {
    125126                async_answer_0(callid, rc);
     
    233234
    234235#define _INIT_FROM_HIGH_DATA2(type, var, arg_no) \
    235         type var = (type) DEV_IPC_GET_ARG##arg_no(*call) / (1 << 16)
     236        type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) >> 16)
    236237#define _INIT_FROM_LOW_DATA2(type, var, arg_no) \
    237         type var = (type) DEV_IPC_GET_ARG##arg_no(*call) % (1 << 16)
    238 #define _INIT_FROM_HIGH_DATA3(type, var, arg_no) \
    239         type var = (type) DEV_IPC_GET_ARG##arg_no(*call) / (1 << 16)
    240 #define _INIT_FROM_MIDDLE_DATA3(type, var, arg_no) \
    241         type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) / (1 << 8)) % (1 << 8)
    242 #define _INIT_FROM_LOW_DATA3(type, var, arg_no) \
    243         type var = (type) DEV_IPC_GET_ARG##arg_no(*call) % (1 << 8)
     238        type var = (type) (DEV_IPC_GET_ARG##arg_no(*call) & 0xffff)
    244239
    245240        const usb_target_t target = { .packed = DEV_IPC_GET_ARG1(*call) };
    246241
    247         _INIT_FROM_HIGH_DATA3(usb_speed_t, speed, 2);
    248         _INIT_FROM_MIDDLE_DATA3(usb_transfer_type_t, transfer_type, 2);
    249         _INIT_FROM_LOW_DATA3(usb_direction_t, direction, 2);
     242        _INIT_FROM_HIGH_DATA2(usb_transfer_type_t, transfer_type, 2);
     243        _INIT_FROM_LOW_DATA2(usb_direction_t, direction, 2);
    250244
    251245        _INIT_FROM_HIGH_DATA2(size_t, max_packet_size, 3);
     
    254248#undef _INIT_FROM_HIGH_DATA2
    255249#undef _INIT_FROM_LOW_DATA2
    256 #undef _INIT_FROM_HIGH_DATA3
    257 #undef _INIT_FROM_MIDDLE_DATA3
    258 #undef _INIT_FROM_LOW_DATA3
    259 
    260         int rc = usb_iface->register_endpoint(fun, target.address, speed,
     250
     251        int rc = usb_iface->register_endpoint(fun, target.address,
    261252            target.endpoint, transfer_type, direction, max_packet_size, interval);
    262253
  • uspace/lib/drv/include/usb_iface.h

    r27ca3a3 rc2245a3  
    6565         * handle must be resolved by its parent.
    6666         */
    67         IPC_M_USB_GET_ADDRESS,
     67        IPC_M_USB_GET_MY_ADDRESS,
    6868
    6969        /** Tell interface number given device can use.
     
    9090/** USB device communication interface. */
    9191typedef struct {
    92         int (*get_address)(ddf_fun_t *, devman_handle_t, usb_address_t *);
     92        int (*get_my_address)(ddf_fun_t *, usb_address_t *);
    9393        int (*get_interface)(ddf_fun_t *, devman_handle_t, int *);
    9494        int (*get_hc_handle)(ddf_fun_t *, devman_handle_t *);
  • uspace/lib/drv/include/usbhc_iface.h

    r27ca3a3 rc2245a3  
    170170/** USB host controller communication interface. */
    171171typedef struct {
    172         int (*request_address)(ddf_fun_t *, usb_speed_t, usb_address_t *);
     172        int (*request_address)(ddf_fun_t *, usb_address_t *, bool, usb_speed_t);
    173173        int (*bind_address)(ddf_fun_t *, usb_address_t, devman_handle_t);
    174174        int (*find_by_address)(ddf_fun_t *, usb_address_t, devman_handle_t *);
     
    176176
    177177        int (*register_endpoint)(ddf_fun_t *,
    178             usb_address_t, usb_speed_t, usb_endpoint_t,
     178            usb_address_t, usb_endpoint_t,
    179179            usb_transfer_type_t, usb_direction_t, size_t, unsigned int);
    180180        int (*unregister_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t,
  • uspace/lib/usb/Makefile

    r27ca3a3 rc2245a3  
    3131EXTRA_CFLAGS += \
    3232        -I$(LIBDRV_PREFIX)/include \
     33        -I$(LIBUSBDEV_PREFIX)/include \
    3334        -Iinclude
    3435
  • uspace/lib/usb/include/usb/ddfiface.h

    r27ca3a3 rc2245a3  
    3939#include <usb_iface.h>
    4040
    41 int usb_iface_get_hc_handle_hub_impl(ddf_fun_t *, devman_handle_t *);
    42 int usb_iface_get_address_hub_impl(ddf_fun_t *, devman_handle_t,
    43     usb_address_t *);
     41int usb_iface_get_hc_handle_device_impl(ddf_fun_t *, devman_handle_t *);
     42int usb_iface_get_my_address_forward_impl(ddf_fun_t *, usb_address_t *);
    4443extern usb_iface_t usb_iface_hub_impl;
    4544
    46 int usb_iface_get_hc_handle_hub_child_impl(ddf_fun_t *, devman_handle_t *);
    47 int usb_iface_get_address_hub_child_impl(ddf_fun_t *, devman_handle_t,
    48     usb_address_t *);
     45int usb_iface_get_my_address_from_device_data(ddf_fun_t *, usb_address_t *);
    4946extern usb_iface_t usb_iface_hub_child_impl;
    5047
    5148int usb_iface_get_hc_handle_hc_impl(ddf_fun_t *, devman_handle_t *);
    52 
    5349
    5450#endif
  • uspace/lib/usb/include/usb/hc.h

    r27ca3a3 rc2245a3  
    6262    devman_handle_t *);
    6363
    64 usb_address_t usb_hc_get_address_by_handle(devman_handle_t);
     64usb_address_t usb_get_address_by_handle(devman_handle_t);
    6565
    6666int usb_hc_find(devman_handle_t, devman_handle_t *);
  • uspace/lib/usb/src/class.c

    r27ca3a3 rc2245a3  
    8181                        return "application";
    8282                case USB_CLASS_VENDOR_SPECIFIC:
    83                         return "vendor";
     83                        return "vendor-specific";
    8484                default:
    8585                        return "unknown";
  • uspace/lib/usb/src/ddfiface.c

    r27ca3a3 rc2245a3  
    3939#include <usb/hc.h>
    4040#include <usb/debug.h>
     41#include <usb/dev/hub.h>
    4142#include <errno.h>
    4243#include <assert.h>
    4344
    4445/** DDF interface for USB device, implementation for typical hub. */
    45 usb_iface_t  usb_iface_hub_impl = {
    46         .get_hc_handle = usb_iface_get_hc_handle_hub_impl,
    47         .get_address = usb_iface_get_address_hub_impl
     46usb_iface_t usb_iface_hub_impl = {
     47        .get_hc_handle = usb_iface_get_hc_handle_device_impl,
     48        .get_my_address = usb_iface_get_my_address_forward_impl,
    4849};
    4950
    5051/** DDF interface for USB device, implementation for child of a typical hub. */
    51 usb_iface_t  usb_iface_hub_child_impl = {
    52         .get_hc_handle = usb_iface_get_hc_handle_hub_child_impl,
    53         .get_address = usb_iface_get_address_hub_child_impl
     52usb_iface_t usb_iface_hub_child_impl = {
     53        .get_hc_handle = usb_iface_get_hc_handle_device_impl,
     54        .get_my_address = usb_iface_get_my_address_from_device_data,
    5455};
    5556
     
    6162 * @return Error code.
    6263 */
    63 int usb_iface_get_hc_handle_hub_impl(ddf_fun_t *fun, devman_handle_t *handle)
     64int usb_iface_get_hc_handle_device_impl(ddf_fun_t *fun, devman_handle_t *handle)
    6465{
    6566        assert(fun);
    6667        return usb_hc_find(fun->handle, handle);
    67 }
    68 
    69 /** Get host controller handle, interface implementation for child of
    70  * a hub driver.
    71  *
    72  * @param[in] fun Device function the operation is running on.
    73  * @param[out] handle Storage for the host controller handle.
    74  * @return Error code.
    75  */
    76 int usb_iface_get_hc_handle_hub_child_impl(ddf_fun_t *fun,
    77     devman_handle_t *handle)
    78 {
    79         assert(fun != NULL);
    80        
    81         async_sess_t *parent_sess =
    82             devman_parent_device_connect(EXCHANGE_SERIALIZE, fun->handle,
    83             IPC_FLAG_BLOCKING);
    84         if (!parent_sess)
    85                 return ENOMEM;
    86        
    87         async_exch_t *exch = async_exchange_begin(parent_sess);
    88        
    89         sysarg_t hc_handle;
    90         int rc = async_req_1_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
    91             IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &hc_handle);
    92        
    93         async_exchange_end(exch);
    94         async_hangup(parent_sess);
    95        
    96         if (rc != EOK)
    97                 return rc;
    98        
    99         *handle = hc_handle;
    100         return EOK;
    10168}
    10269
     
    12592 * @return Error code.
    12693 */
    127 int usb_iface_get_address_hub_impl(ddf_fun_t *fun, devman_handle_t handle,
     94int usb_iface_get_my_address_forward_impl(ddf_fun_t *fun,
    12895    usb_address_t *address)
    12996{
    13097        assert(fun);
    131        
     98
    13299        async_sess_t *parent_sess =
    133100            devman_parent_device_connect(EXCHANGE_SERIALIZE, fun->handle,
     
    135102        if (!parent_sess)
    136103                return ENOMEM;
    137        
     104
    138105        async_exch_t *exch = async_exchange_begin(parent_sess);
    139        
     106
    140107        sysarg_t addr;
    141         int rc = async_req_2_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
    142             IPC_M_USB_GET_ADDRESS, handle, &addr);
    143        
     108        int rc = async_req_1_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
     109            IPC_M_USB_GET_MY_ADDRESS, &addr);
     110
    144111        async_exchange_end(exch);
    145112        async_hangup(parent_sess);
    146        
     113
    147114        if (rc != EOK)
    148115                return rc;
    149        
     116
    150117        if (address != NULL)
    151118                *address = (usb_address_t) addr;
    152        
     119
    153120        return EOK;
    154121}
     
    157124 * a hub driver.
    158125 *
     126 * This implementation eccepts 0 as valid handle and replaces it with fun's
     127 * handle.
     128 *
    159129 * @param[in] fun Device function the operation is running on.
    160130 * @param[in] handle Devman handle of USB device we want address of.
     
    162132 * @return Error code.
    163133 */
    164 int usb_iface_get_address_hub_child_impl(ddf_fun_t *fun,
    165     devman_handle_t handle, usb_address_t *address)
     134int usb_iface_get_my_address_from_device_data(ddf_fun_t *fun,
     135    usb_address_t *address)
    166136{
    167         if (handle == 0) {
    168                 handle = fun->handle;
    169         }
    170         return usb_iface_get_address_hub_impl(fun, handle, address);
     137        assert(fun);
     138        assert(fun->driver_data);
     139        usb_hub_attached_device_t *device = fun->driver_data;
     140        assert(device->fun == fun);
     141        if (address)
     142                *address = device->address;
     143        return EOK;
    171144}
    172145
  • uspace/lib/usb/src/hc.c

    r27ca3a3 rc2245a3  
    174174 * @return USB address or negative error code.
    175175 */
    176 usb_address_t usb_hc_get_address_by_handle(devman_handle_t dev_handle)
     176usb_address_t usb_get_address_by_handle(devman_handle_t dev_handle)
    177177{
    178178        async_sess_t *parent_sess =
     
    185185       
    186186        sysarg_t address;
    187         int rc = async_req_2_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
    188             IPC_M_USB_GET_ADDRESS,
    189             dev_handle, &address);
     187        int rc = async_req_1_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
     188            IPC_M_USB_GET_MY_ADDRESS, &address);
    190189       
    191190        async_exchange_end(exch);
  • uspace/lib/usb/src/resolve.c

    r27ca3a3 rc2245a3  
    200200                /* Try to get its address. */
    201201                if (!found_addr) {
    202                         dev_addr = usb_hc_get_address_by_handle(tmp_handle);
     202                        dev_addr = usb_get_address_by_handle(tmp_handle);
    203203                        if (dev_addr >= 0) {
    204204                                found_addr = true;
  • uspace/lib/usbdev/include/usb/dev/dp.h

    r27ca3a3 rc2245a3  
    5454} usb_dp_descriptor_nesting_t;
    5555
    56 extern usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[];
     56extern const usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[];
    5757
    5858/** Descriptor parser structure. */
  • uspace/lib/usbdev/include/usb/dev/driver.h

    r27ca3a3 rc2245a3  
    7272/** USB device structure. */
    7373typedef struct {
     74        /** Connection backing the pipes.
     75         * Typically, you will not need to use this attribute at all.
     76         */
     77        usb_device_connection_t wire;
    7478        /** The default control pipe. */
    7579        usb_pipe_t ctrl_pipe;
     
    8791        int interface_no;
    8892
    89         /** Alternative interfaces.
    90          * Set to NULL when the driver controls whole device
    91          * (i.e. more (or any) interfaces).
    92          */
    93         usb_alternate_interfaces_t *alternate_interfaces;
     93        /** Alternative interfaces. */
     94        usb_alternate_interfaces_t alternate_interfaces;
    9495
    9596        /** Some useful descriptors. */
    9697        usb_device_descriptors_t descriptors;
    9798
    98         /** Generic DDF device backing this one. RO: DO NOT TOUCH!*/
     99        /** Generic DDF device backing this one. DO NOT TOUCH! */
    99100        ddf_dev_t *ddf_dev;
    100101        /** Custom driver data.
     
    103104         */
    104105        void *driver_data;
    105 
    106         /** Connection backing the pipes.
    107          * Typically, you will not need to use this attribute at all.
    108          */
    109         usb_device_connection_t wire;
    110106} usb_device_t;
    111107
     
    163159int usb_driver_main(const usb_driver_t *);
    164160
     161int usb_device_init(usb_device_t *, ddf_dev_t *,
     162    const usb_endpoint_description_t **, const char **);
     163void usb_device_deinit(usb_device_t *);
     164
    165165int usb_device_select_interface(usb_device_t *, uint8_t,
    166166    const usb_endpoint_description_t **);
    167167
    168168int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *);
     169void usb_device_release_descriptors(usb_device_descriptors_t *);
     170
    169171int usb_device_create_pipes(const ddf_dev_t *, usb_device_connection_t *,
    170172    const usb_endpoint_description_t **, const uint8_t *, size_t, int, int,
    171173    usb_endpoint_mapping_t **, size_t *);
    172174int usb_device_destroy_pipes(const ddf_dev_t *, usb_endpoint_mapping_t *, size_t);
    173 int usb_device_init(usb_device_t *, ddf_dev_t *,
    174     const usb_endpoint_description_t **, const char **);
    175 void usb_device_deinit(usb_device_t *);
    176175
    177176void * usb_device_data_alloc(usb_device_t *, size_t);
    178177
    179178size_t usb_interface_count_alternates(const uint8_t *, size_t, uint8_t);
    180 int usb_alternate_interfaces_create(const uint8_t *, size_t, int,
    181     usb_alternate_interfaces_t **);
    182 void usb_alternate_interfaces_destroy(usb_alternate_interfaces_t *);
     179int usb_alternate_interfaces_init(usb_alternate_interfaces_t *,
     180    const uint8_t *, size_t, int);
     181void usb_alternate_interfaces_deinit(usb_alternate_interfaces_t *);
    183182#endif
    184183/**
  • uspace/lib/usbdev/include/usb/dev/hub.h

    r27ca3a3 rc2245a3  
    5959} usb_hub_attached_device_t;
    6060
    61 usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_speed_t);
     61usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_address_t,
     62    bool, usb_speed_t);
    6263int usb_hc_register_device(usb_hc_connection_t *,
    6364    const usb_hub_attached_device_t *);
  • uspace/lib/usbdev/include/usb/dev/pipes.h

    r27ca3a3 rc2245a3  
    141141typedef struct {
    142142        /** Endpoint pipe. */
    143         usb_pipe_t *pipe;
     143        usb_pipe_t pipe;
    144144        /** Endpoint description. */
    145145        const usb_endpoint_description_t *description;
     
    149149        int interface_setting;
    150150        /** Found descriptor fitting the description. */
    151         usb_standard_endpoint_descriptor_t *descriptor;
     151        const usb_standard_endpoint_descriptor_t *descriptor;
    152152        /** Interface descriptor the endpoint belongs to. */
    153         usb_standard_interface_descriptor_t *interface;
     153        const usb_standard_interface_descriptor_t *interface;
    154154        /** Whether the endpoint was actually found. */
    155155        bool present;
     
    172172int usb_pipe_initialize_from_configuration(usb_endpoint_mapping_t *,
    173173    size_t, const uint8_t *, size_t, usb_device_connection_t *);
    174 int usb_pipe_register_with_speed(usb_pipe_t *, usb_speed_t,
    175     unsigned int, usb_hc_connection_t *);
    176174int usb_pipe_register(usb_pipe_t *, unsigned int, usb_hc_connection_t *);
    177175int usb_pipe_unregister(usb_pipe_t *, usb_hc_connection_t *);
  • uspace/lib/usbdev/include/usb/dev/poll.h

    r27ca3a3 rc2245a3  
    8484} usb_device_auto_polling_t;
    8585
    86 int usb_device_auto_polling(usb_device_t *, size_t, usb_device_auto_polling_t *,
    87     size_t, void *);
     86int usb_device_auto_polling(usb_device_t *, size_t,
     87    const usb_device_auto_polling_t *, size_t, void *);
    8888
    8989typedef bool (*usb_polling_callback_t)(usb_device_t *,
  • uspace/lib/usbdev/include/usb/dev/recognise.h

    r27ca3a3 rc2245a3  
    5050int usb_device_create_match_ids(usb_pipe_t *, match_id_list_t *);
    5151
    52 int usb_device_register_child_in_devman(usb_address_t, devman_handle_t,
     52int usb_device_register_child_in_devman(usb_pipe_t *ctrl_pipe,
    5353    ddf_dev_t *, ddf_dev_ops_t *, void *, ddf_fun_t **);
    5454
  • uspace/lib/usbdev/include/usb/dev/request.h

    r27ca3a3 rc2245a3  
    115115int usb_request_set_feature(usb_pipe_t *, usb_request_type_t,
    116116    usb_request_recipient_t, uint16_t, uint16_t);
    117 int usb_request_set_address(usb_pipe_t *, usb_address_t);
    118117int usb_request_get_descriptor(usb_pipe_t *, usb_request_type_t,
    119     usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t, 
     118    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t,
    120119    size_t *);
    121120int usb_request_get_descriptor_alloc(usb_pipe_t *, usb_request_type_t,
     
    131130int usb_request_set_descriptor(usb_pipe_t *, usb_request_type_t,
    132131    usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t);
     132
    133133int usb_request_get_configuration(usb_pipe_t *, uint8_t *);
    134134int usb_request_set_configuration(usb_pipe_t *, uint8_t);
  • uspace/lib/usbdev/src/altiface.c

    r27ca3a3 rc2245a3  
    9090 * @return Error code.
    9191 */
    92 int usb_alternate_interfaces_create(const uint8_t *config_descr,
    93     size_t config_descr_size, int interface_number,
    94     usb_alternate_interfaces_t **alternates_ptr)
     92int usb_alternate_interfaces_init(usb_alternate_interfaces_t *alternates,
     93    const uint8_t *config_descr, size_t config_descr_size, int interface_number)
    9594{
    96         assert(alternates_ptr != NULL);
     95        assert(alternates != NULL);
    9796        assert(config_descr != NULL);
    9897        assert(config_descr_size > 0);
    9998
    100         *alternates_ptr = NULL;
     99        alternates->alternatives = NULL;
     100        alternates->alternative_count = 0;
     101        alternates->current = 0;
     102
    101103        if (interface_number < 0) {
    102104                return EOK;
    103         }
    104 
    105         usb_alternate_interfaces_t *alternates
    106             = malloc(sizeof(usb_alternate_interfaces_t));
    107         if (alternates == NULL) {
    108                 return ENOMEM;
    109105        }
    110106
     
    114110
    115111        if (alternates->alternative_count == 0) {
    116                 free(alternates);
    117112                return ENOENT;
    118113        }
     
    121116            sizeof(usb_alternate_interface_descriptors_t));
    122117        if (alternates->alternatives == NULL) {
    123                 free(alternates);
    124118                return ENOMEM;
    125119        }
    126120
    127         alternates->current = 0;
    128 
    129         usb_dp_parser_t dp_parser = {
     121        const usb_dp_parser_t dp_parser = {
    130122                .nesting = usb_dp_standard_descriptor_nesting
    131123        };
    132         usb_dp_parser_data_t dp_data = {
     124        const usb_dp_parser_data_t dp_data = {
    133125                .data = config_descr,
    134126                .size = config_descr_size,
     
    147139                    || (iface->interface_number != interface_number)) {
    148140                        iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser,
    149                             &dp_data,
    150                             dp_data.data, iface_ptr);
     141                            &dp_data, dp_data.data, iface_ptr);
    151142                        continue;
    152143                }
     
    170161        }
    171162
    172         *alternates_ptr = alternates;
    173 
    174163        return EOK;
    175164}
    176165
    177 void usb_alternate_interfaces_destroy(usb_alternate_interfaces_t *alternate)
     166void usb_alternate_interfaces_deinit(usb_alternate_interfaces_t *alternate)
    178167{
    179168        if (!alternate)
    180169                return;
    181170        free(alternate->alternatives);
    182         free(alternate);
    183171}
    184172/**
  • uspace/lib/usbdev/src/devdrv.c

    r27ca3a3 rc2245a3  
    8181 * @return Number of pipes (excluding default control pipe).
    8282 */
    83 static size_t count_other_pipes(const usb_endpoint_description_t **endpoints)
    84 {
    85         size_t count = 0;
    86         if (endpoints == NULL) {
    87                 return 0;
    88         }
    89 
    90         while (endpoints[count] != NULL) {
    91                 count++;
    92         }
    93 
     83static inline size_t count_other_pipes(
     84    const usb_endpoint_description_t **endpoints)
     85{
     86        size_t count;
     87        for (count = 0; endpoints && endpoints[count] != NULL; ++count);
    9488        return count;
    9589}
     
    10498    usb_device_t *dev, int alternate_setting)
    10599{
     100        assert(dev);
     101
    106102        if (endpoints == NULL) {
    107103                dev->pipes = NULL;
     
    300296
    301297        return rc;
     298}
     299
     300/** Cleanup structure initialized via usb_device_retrieve_descriptors.
     301 *
     302 * @param[in] descriptors Where to store the descriptors.
     303 */
     304void usb_device_release_descriptors(usb_device_descriptors_t *descriptors)
     305{
     306        assert(descriptors);
     307        free(descriptors->configuration);
     308        descriptors->configuration = NULL;
    302309}
    303310
     
    319326 *      (not NULL terminated).
    320327 * @param[out] pipes_count_ptr Where to store number of pipes
    321  *      (set to if you wish to ignore the count).
     328 *      (set to NULL if you wish to ignore the count).
    322329 * @return Error code.
    323330 */
     
    340347        const size_t pipe_count = count_other_pipes(endpoints);
    341348        if (pipe_count == 0) {
    342                 *pipes_count_ptr = pipe_count;
     349                if (pipes_count_ptr)
     350                        *pipes_count_ptr = pipe_count;
    343351                *pipes_ptr = NULL;
    344352                return EOK;
     
    346354
    347355        usb_endpoint_mapping_t *pipes
    348             = malloc(sizeof(usb_endpoint_mapping_t) * pipe_count);
     356            = calloc(pipe_count, sizeof(usb_endpoint_mapping_t));
    349357        if (pipes == NULL) {
    350358                return ENOMEM;
    351359        }
    352360
    353         /* Initialize to NULL to allow smooth rollback. */
    354         for (i = 0; i < pipe_count; i++) {
    355                 pipes[i].pipe = NULL;
    356         }
    357 
    358361        /* Now allocate and fully initialize. */
    359362        for (i = 0; i < pipe_count; i++) {
    360                 pipes[i].pipe = malloc(sizeof(usb_pipe_t));
    361                 if (pipes[i].pipe == NULL) {
    362                         rc = ENOMEM;
    363                         goto rollback_free_only;
    364                 }
    365363                pipes[i].description = endpoints[i];
    366364                pipes[i].interface_no = interface_no;
     
    389387        for (i = 0; i < pipe_count; i++) {
    390388                if (pipes[i].present) {
    391                         rc = usb_pipe_register(pipes[i].pipe,
     389                        rc = usb_pipe_register(&pipes[i].pipe,
    392390                            pipes[i].descriptor->poll_interval, &hc_conn);
    393391                        if (rc != EOK) {
     
    398396
    399397        if (usb_hc_connection_close(&hc_conn) != EOK)
    400                 usb_log_warning("usb_device_create_pipes(): "
    401                     "Failed to close connection.\n");
     398                usb_log_warning("%s: Failed to close connection.\n",
     399                    __FUNCTION__);
    402400
    403401        *pipes_ptr = pipes;
     
    417415        for (i = 0; i < pipe_count; i++) {
    418416                if (pipes[i].present) {
    419                         usb_pipe_unregister(pipes[i].pipe, &hc_conn);
     417                        usb_pipe_unregister(&pipes[i].pipe, &hc_conn);
    420418                }
    421419        }
     
    431429         */
    432430rollback_free_only:
    433         for (i = 0; i < pipe_count; i++) {
    434                 if (pipes[i].pipe != NULL) {
    435                         free(pipes[i].pipe);
    436                 }
    437         }
    438431        free(pipes);
    439432
     
    477470                    i, pipes[i].present ? "" : "not ");
    478471                if (pipes[i].present)
    479                         usb_pipe_unregister(pipes[i].pipe, &hc_conn);
    480                 free(pipes[i].pipe);
     472                        usb_pipe_unregister(&pipes[i].pipe, &hc_conn);
    481473        }
    482474
     
    489481        return EOK;
    490482}
    491 
    492 /** Initialize control pipe in a device.
    493  *
    494  * @param dev USB device in question.
    495  * @param errmsg Where to store error context.
    496  * @return
    497  */
    498 static int init_wire_and_ctrl_pipe(usb_device_t *dev, const char **errmsg)
    499 {
    500         int rc;
    501 
    502         rc = usb_device_connection_initialize_from_device(&dev->wire,
    503             dev->ddf_dev);
    504         if (rc != EOK) {
    505                 *errmsg = "device connection initialization";
    506                 return rc;
    507         }
    508 
    509         rc = usb_pipe_initialize_default_control(&dev->ctrl_pipe,
    510             &dev->wire);
    511         if (rc != EOK) {
    512                 *errmsg = "default control pipe initialization";
    513                 return rc;
    514         }
    515 
    516         return EOK;
    517 }
    518 
    519483
    520484/** Initialize new instance of USB device.
     
    533497        assert(ddf_dev != NULL);
    534498
     499        *errstr_ptr = NULL;
     500
    535501        usb_dev->ddf_dev = ddf_dev;
    536502        usb_dev->driver_data = NULL;
    537503        usb_dev->descriptors.configuration = NULL;
    538         usb_dev->alternate_interfaces = NULL;
    539504        usb_dev->pipes_count = 0;
    540505        usb_dev->pipes = NULL;
    541506
    542507        /* Initialize backing wire and control pipe. */
    543         int rc = init_wire_and_ctrl_pipe(usb_dev, errstr_ptr);
    544         if (rc != EOK) {
     508        int rc = usb_device_connection_initialize_from_device(
     509            &usb_dev->wire, ddf_dev);
     510        if (rc != EOK) {
     511                *errstr_ptr = "device connection initialization";
     512                return rc;
     513        }
     514
     515        /* This pipe was registered by the hub driver,
     516         * during device initialization. */
     517        rc = usb_pipe_initialize_default_control(&usb_dev->ctrl_pipe,
     518            &usb_dev->wire);
     519        if (rc != EOK) {
     520                *errstr_ptr = "default control pipe initialization";
    545521                return rc;
    546522        }
     
    553529            &usb_dev->descriptors);
    554530        if (rc != EOK) {
    555                 /* Nothing allocated, nothing to free. */
    556531                *errstr_ptr = "descriptor retrieval";
    557532                return rc;
    558533        }
    559534
    560         /* Create alternate interfaces. We will silently ignore failure. */
    561         //TODO Why ignore?
    562         usb_alternate_interfaces_create(usb_dev->descriptors.configuration,
    563             usb_dev->descriptors.configuration_size, usb_dev->interface_no,
    564             &usb_dev->alternate_interfaces);
    565 
    566         rc = initialize_other_pipes(endpoints, usb_dev, 0);
     535        /* Create alternate interfaces. We will silently ignore failure.
     536         * We might either control one interface or an entire device,
     537         * it makes no sense to speak about alternate interfaces when
     538         * controlling a device. */
     539        rc = usb_alternate_interfaces_init(&usb_dev->alternate_interfaces,
     540            usb_dev->descriptors.configuration,
     541            usb_dev->descriptors.configuration_size, usb_dev->interface_no);
     542        const int alternate_iface =
     543            (rc == EOK) ? usb_dev->alternate_interfaces.current : 0;
     544
     545        /* TODO Add comment here. */
     546        rc = initialize_other_pipes(endpoints, usb_dev, alternate_iface);
    567547        if (rc != EOK) {
    568548                /* Full configuration descriptor is allocated. */
    569                 free(usb_dev->descriptors.configuration);
     549                usb_device_release_descriptors(&usb_dev->descriptors);
    570550                /* Alternate interfaces may be allocated */
    571                 usb_alternate_interfaces_destroy(usb_dev->alternate_interfaces);
     551                usb_alternate_interfaces_deinit(&usb_dev->alternate_interfaces);
    572552                *errstr_ptr = "pipes initialization";
    573553                return rc;
    574554        }
    575 
    576         *errstr_ptr = NULL;
    577555
    578556        return EOK;
     
    591569                destroy_current_pipes(dev);
    592570
    593                 usb_alternate_interfaces_destroy(dev->alternate_interfaces);
    594                 free(dev->descriptors.configuration);
     571                usb_alternate_interfaces_deinit(&dev->alternate_interfaces);
     572                usb_device_release_descriptors(&dev->descriptors);
    595573                free(dev->driver_data);
    596574        }
  • uspace/lib/usbdev/src/devpoll.c

    r27ca3a3 rc2245a3  
    7373
    7474        usb_pipe_t *pipe
    75             = polling_data->dev->pipes[polling_data->pipe_index].pipe;
     75            = &polling_data->dev->pipes[polling_data->pipe_index].pipe;
    7676       
    7777        if (polling_data->debug > 0) {
     
    208208                return EINVAL;
    209209        }
    210         if ((dev->pipes[pipe_index].pipe->transfer_type != USB_TRANSFER_INTERRUPT)
    211             || (dev->pipes[pipe_index].pipe->direction != USB_DIRECTION_IN)) {
     210        if ((dev->pipes[pipe_index].pipe.transfer_type != USB_TRANSFER_INTERRUPT)
     211            || (dev->pipes[pipe_index].pipe.direction != USB_DIRECTION_IN)) {
    212212                return EINVAL;
    213213        }
    214214
    215         usb_device_auto_polling_t *auto_polling
    216             = malloc(sizeof(usb_device_auto_polling_t));
    217         if (auto_polling == NULL) {
    218                 return ENOMEM;
    219         }
    220 
    221         auto_polling->debug = 1;
    222         auto_polling->auto_clear_halt = true;
    223         auto_polling->delay = 0;
    224         auto_polling->max_failures = MAX_FAILED_ATTEMPTS;
    225         auto_polling->on_data = callback;
    226         auto_polling->on_polling_end = terminated_callback;
    227         auto_polling->on_error = NULL;
    228 
    229         int rc = usb_device_auto_polling(dev, pipe_index, auto_polling,
     215        const usb_device_auto_polling_t auto_polling = {
     216                .debug = 1,
     217                .auto_clear_halt = true,
     218                .delay = 0,
     219                .max_failures = MAX_FAILED_ATTEMPTS,
     220                .on_data = callback,
     221                .on_polling_end = terminated_callback,
     222                .on_error = NULL,
     223        };
     224
     225        return usb_device_auto_polling(dev, pipe_index, &auto_polling,
    230226           request_size, arg);
    231 
    232         free(auto_polling);
    233 
    234         return rc;
    235227}
    236228
     
    253245 */
    254246int usb_device_auto_polling(usb_device_t *dev, size_t pipe_index,
    255     usb_device_auto_polling_t *polling,
     247    const usb_device_auto_polling_t *polling,
    256248    size_t request_size, void *arg)
    257249{
     
    262254                return EINVAL;
    263255        }
    264         if ((dev->pipes[pipe_index].pipe->transfer_type != USB_TRANSFER_INTERRUPT)
    265             || (dev->pipes[pipe_index].pipe->direction != USB_DIRECTION_IN)) {
     256        if ((dev->pipes[pipe_index].pipe.transfer_type != USB_TRANSFER_INTERRUPT)
     257            || (dev->pipes[pipe_index].pipe.direction != USB_DIRECTION_IN)) {
    266258                return EINVAL;
    267259        }
  • uspace/lib/usbdev/src/dp.c

    r27ca3a3 rc2245a3  
    5757
    5858/** Nesting of standard USB descriptors. */
    59 usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[] = {
     59const usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[] = {
    6060        NESTING(CONFIGURATION, INTERFACE),
    6161        NESTING(INTERFACE, ENDPOINT),
  • uspace/lib/usbdev/src/hub.c

    r27ca3a3 rc2245a3  
    6666 *
    6767 * @param connection Opened connection to host controller.
     68 * @param preferred Preferred SUB address.
     69 * @param strict Fail if the preferred address is not avialable.
    6870 * @param speed Speed of the new device (device that will be assigned
    6971 *    the returned address).
     
    7173 */
    7274usb_address_t usb_hc_request_address(usb_hc_connection_t *connection,
    73     usb_speed_t speed)
     75    usb_address_t preferred, bool strict, usb_speed_t speed)
    7476{
    7577        CHECK_CONNECTION(connection);
     
    7880       
    7981        sysarg_t address;
    80         int rc = async_req_2_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
    81             IPC_M_USBHC_REQUEST_ADDRESS, speed,
    82             &address);
     82        int rc = async_req_4_1(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
     83            IPC_M_USBHC_REQUEST_ADDRESS, preferred, strict, speed, &address);
    8384       
    8485        async_exchange_end(exch);
     
    132133}
    133134
    134 
    135 static void unregister_control_endpoint_on_default_address(
    136     usb_hc_connection_t *connection)
     135/** Change address of connected device.
     136 * This function automatically updates the backing connection to point to
     137 * the new address. It also unregisterrs the old endpoint and registers
     138 * a new one.
     139 * This creates whole bunch of problems:
     140 *  1. All pipes using this wire are broken because they are not
     141 *     registered for new address
     142 *  2. All other pipes for this device are using wrong address,
     143 *     possibly targeting completely different device
     144 *
     145 * @param pipe Control endpoint pipe (session must be already started).
     146 * @param new_address New USB address to be set (in native endianness).
     147 * @return Error code.
     148 */
     149static int usb_request_set_address(usb_pipe_t *pipe, usb_address_t new_address,
     150    usb_hc_connection_t *hc_conn)
    137151{
    138         usb_device_connection_t dev_conn;
    139         int rc = usb_device_connection_initialize_on_default_address(&dev_conn,
    140             connection);
    141         if (rc != EOK) {
    142                 return;
    143         }
    144 
    145         usb_pipe_t ctrl_pipe;
    146         rc = usb_pipe_initialize_default_control(&ctrl_pipe, &dev_conn);
    147         if (rc != EOK) {
    148                 return;
    149         }
    150 
    151         usb_pipe_unregister(&ctrl_pipe, connection);
     152        if ((new_address < 0) || (new_address >= USB11_ADDRESS_MAX)) {
     153                return EINVAL;
     154        }
     155        assert(pipe);
     156        assert(hc_conn);
     157        assert(pipe->wire != NULL);
     158
     159        const uint16_t addr = uint16_host2usb((uint16_t)new_address);
     160
     161        int rc = usb_control_request_set(pipe,
     162            USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
     163            USB_DEVREQ_SET_ADDRESS, addr, 0, NULL, 0);
     164
     165        if (rc != EOK) {
     166                return rc;
     167        }
     168
     169        /* TODO: prevent others from accessing the wire now. */
     170        if (usb_pipe_unregister(pipe, hc_conn) != EOK) {
     171                usb_log_warning(
     172                    "Failed to unregister the old pipe on address change.\n");
     173        }
     174        /* The address is already changed so set it in the wire */
     175        pipe->wire->address = new_address;
     176        rc = usb_pipe_register(pipe, 0, hc_conn);
     177        if (rc != EOK)
     178                return EADDRNOTAVAIL;
     179
     180        return EOK;
    152181}
    153182
     
    171200 *
    172201 * @param[in] parent Parent device (i.e. the hub device).
    173  * @param[in] connection Connection to host controller.
     202 * @param[in] connection Connection to host controller. Must be non-null.
    174203 * @param[in] dev_speed New device speed.
    175204 * @param[in] enable_port Function for enabling signaling through the port the
     
    177206 * @param[in] arg Any data argument to @p enable_port.
    178207 * @param[out] assigned_address USB address of the device.
    179  * @param[in] dev_ops Child device ops.
     208 * @param[in] dev_ops Child device ops. Will use default if not provided.
    180209 * @param[in] new_dev_data Arbitrary pointer to be stored in the child
    181  *      as @c driver_data.
     210 *      as @c driver_data. Will allocate and assign usb_hub_attached_device_t
     211 *      structure if NULL.
    182212 * @param[out] new_fun Storage where pointer to allocated child function
    183  *      will be written.
     213 *      will be written. Must be non-null.
    184214 * @return Error code.
     215 * @retval EINVAL Either connection or new_fun is a NULL pointer.
    185216 * @retval ENOENT Connection to HC not opened.
    186217 * @retval EADDRNOTAVAIL Failed retrieving free address from host controller.
     
    195226    ddf_dev_ops_t *dev_ops, void *new_dev_data, ddf_fun_t **new_fun)
    196227{
    197         assert(connection != NULL);
     228        if (new_fun == NULL || connection == NULL)
     229                return EINVAL;
     230
    198231        // FIXME: this is awful, we are accessing directly the structure.
     232        // TODO: Why not use provided connection?
    199233        usb_hc_connection_t hc_conn = {
    200234                .hc_handle = connection->hc_handle,
     
    215249        }
    216250
    217 
    218251        /*
    219252         * Request new address.
    220253         */
    221         usb_address_t dev_addr = usb_hc_request_address(&hc_conn, dev_speed);
     254        usb_address_t dev_addr =
     255            usb_hc_request_address(&hc_conn, 0, false, dev_speed);
    222256        if (dev_addr < 0) {
    223257                rc = EADDRNOTAVAIL;
     
    240274
    241275        usb_pipe_t ctrl_pipe;
    242         rc = usb_pipe_initialize_default_control(&ctrl_pipe,
    243             &dev_conn);
     276        rc = usb_pipe_initialize_default_control(&ctrl_pipe, &dev_conn);
    244277        if (rc != EOK) {
    245278                rc = ENOTCONN;
     
    248281
    249282        do {
    250                 rc = usb_pipe_register_with_speed(&ctrl_pipe, dev_speed, 0,
    251                     &hc_conn);
    252                 if (rc != EOK) {
     283                rc = usb_hc_request_address(&hc_conn, USB_ADDRESS_DEFAULT,
     284                    true, dev_speed);
     285                if (rc == ENOENT) {
    253286                        /* Do not overheat the CPU ;-). */
    254287                        async_usleep(ENDPOINT_0_0_REGISTER_ATTEMPT_DELAY_USEC);
    255288                }
    256         } while (rc != EOK);
     289        } while (rc == ENOENT);
     290        if (rc < 0) {
     291                goto leave_release_free_address;
     292        }
     293
     294        /* Register control pipe on default address. */
     295        rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
     296        if (rc != EOK) {
     297                rc = ENOTCONN;
     298                goto leave_release_default_address;
     299        }
     300
    257301        struct timeval end_time;
    258302
     
    267311         * above might use much of this time so we should only wait to fill
    268312         * up the 100ms quota*/
    269         suseconds_t elapsed = tv_sub(&end_time, &start_time);
     313        const suseconds_t elapsed = tv_sub(&end_time, &start_time);
    270314        if (elapsed < 100000) {
    271315                async_usleep(100000 - elapsed);
    272316        }
    273317
    274         /*
    275          * Endpoint is registered. We can enable the port and change
    276          * device address.
    277          */
     318        /* Endpoint is registered. We can enable the port and change address. */
    278319        rc = enable_port(arg);
    279320        if (rc != EOK) {
     
    287328        async_usleep(10000);
    288329
     330        /* Get max_packet_size value. */
    289331        rc = usb_pipe_probe_default_control(&ctrl_pipe);
    290332        if (rc != EOK) {
     
    293335        }
    294336
    295         rc = usb_request_set_address(&ctrl_pipe, dev_addr);
     337        rc = usb_request_set_address(&ctrl_pipe, dev_addr, &hc_conn);
    296338        if (rc != EOK) {
    297339                rc = ESTALL;
     
    299341        }
    300342
    301         /*
    302          * Address changed. We can release the original endpoint, thus
    303          * allowing other to access the default address.
    304          */
    305         unregister_control_endpoint_on_default_address(&hc_conn);
    306 
    307         /*
    308          * Time to register the new endpoint.
    309          */
    310         rc = usb_pipe_register(&ctrl_pipe, 0, &hc_conn);
    311         if (rc != EOK) {
    312                 goto leave_release_free_address;
    313         }
    314 
    315         /*
    316          * It is time to register the device with devman.
    317          */
     343        /* Address changed. We can release the default, thus
     344         * allowing other to access the default address. */
     345        usb_hc_unregister_device(&hc_conn, USB_ADDRESS_DEFAULT);
     346
     347        /* Register the device with devman. */
    318348        /* FIXME: create device_register that will get opened ctrl pipe. */
    319349        ddf_fun_t *child_fun;
    320         rc = usb_device_register_child_in_devman(dev_addr, dev_conn.hc_handle,
     350        rc = usb_device_register_child_in_devman(&ctrl_pipe,
    321351            parent, dev_ops, new_dev_data, &child_fun);
    322352        if (rc != EOK) {
    323                 rc = ESTALL;
    324353                goto leave_release_free_address;
    325354        }
    326355
    327         /*
    328          * And now inform the host controller about the handle.
    329          */
    330         usb_hub_attached_device_t new_device = {
     356        const usb_hub_attached_device_t new_device = {
    331357                .address = dev_addr,
    332358                .fun = child_fun,
    333359        };
     360
     361
     362        /* Inform the host controller about the handle. */
    334363        rc = usb_hc_register_device(&hc_conn, &new_device);
    335364        if (rc != EOK) {
     365                /* We know nothing about that data. */
     366                if (new_dev_data)
     367                        child_fun->driver_data = NULL;
     368                /* The child function is already created. */
     369                ddf_fun_destroy(child_fun);
    336370                rc = EDESTADDRREQ;
    337371                goto leave_release_free_address;
    338372        }
    339373
    340 
    341         /*
    342          * And we are done.
    343          */
    344374        if (assigned_address != NULL) {
    345375                *assigned_address = dev_addr;
    346376        }
    347         if (new_fun != NULL) {
    348                 *new_fun = child_fun;
    349         }
     377
     378        *new_fun = child_fun;
    350379
    351380        rc = EOK;
     
    357386         */
    358387leave_release_default_address:
    359         usb_pipe_unregister(&ctrl_pipe, &hc_conn);
     388        usb_hc_unregister_device(&hc_conn, USB_ADDRESS_DEFAULT);
    360389
    361390leave_release_free_address:
    362         usb_hc_unregister_device(&hc_conn, dev_addr);
     391        /* This might be either 0:0 or dev_addr:0 */
     392        if (usb_pipe_unregister(&ctrl_pipe, &hc_conn) != EOK)
     393                usb_log_warning("%s: Failed to unregister default pipe.\n",
     394                    __FUNCTION__);
     395
     396        if (usb_hc_unregister_device(&hc_conn, dev_addr) != EOK)
     397                usb_log_warning("%s: Failed to unregister device.\n",
     398                    __FUNCTION__);
    363399
    364400close_connection:
    365401        if (usb_hc_connection_close(&hc_conn) != EOK)
    366                 usb_log_warning("usb_hc_new_device_wrapper(): Failed to close "
    367                     "connection.\n");
     402                usb_log_warning("%s: Failed to close hc connection.\n",
     403                    __FUNCTION__);
    368404
    369405        return rc;
  • uspace/lib/usbdev/src/pipes.c

    r27ca3a3 rc2245a3  
    5656        async_exch_t *exch = async_exchange_begin(sess);
    5757       
    58         /*
    59          * We are sending special value as a handle - zero - to get
    60          * handle of the parent function (that handle was used
    61          * when registering our device @p dev.
    62          */
    6358        sysarg_t address;
    64         int rc = async_req_2_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
    65             IPC_M_USB_GET_ADDRESS, 0, &address);
     59        int rc = async_req_1_1(exch, DEV_IFACE_ID(USB_DEV_IFACE),
     60            IPC_M_USB_GET_MY_ADDRESS, &address);
    6661       
    6762        async_exchange_end(exch);
     
    8075int usb_device_get_assigned_interface(const ddf_dev_t *device)
    8176{
     77        assert(device);
    8278        async_sess_t *parent_sess =
    8379            devman_parent_device_connect(EXCHANGE_ATOMIC, device->handle,
  • uspace/lib/usbdev/src/pipesinit.c

    r27ca3a3 rc2245a3  
    192192        }
    193193
    194         if (ep_mapping->pipe == NULL) {
    195                 return EBADMEM;
    196         }
    197194        if (ep_mapping->present) {
    198195                return EEXISTS;
    199196        }
    200197
    201         int rc = usb_pipe_initialize(ep_mapping->pipe, wire,
     198        int rc = usb_pipe_initialize(&ep_mapping->pipe, wire,
    202199            ep_no, description.transfer_type, endpoint->max_packet_size,
    203200            description.direction);
     
    254251 *
    255252 * The mapping array is expected to conform to following rules:
    256  * - @c pipe must point to already allocated structure with uninitialized pipe
     253 * - @c pipe must be uninitialized pipe
    257254 * - @c description must point to prepared endpoint description
    258255 * - @c descriptor does not need to be initialized (will be overwritten)
     
    297294        }
    298295
    299         /*
    300          * Go through the mapping and set all endpoints to not present.
    301          */
    302         size_t i;
    303         for (i = 0; i < mapping_count; i++) {
     296        /* Go through the mapping and set all endpoints to not present. */
     297        for (size_t i = 0; i < mapping_count; i++) {
    304298                mapping[i].present = false;
    305299                mapping[i].descriptor = NULL;
     
    307301        }
    308302
    309         /*
    310          * Prepare the descriptor parser.
    311          */
     303        /* Prepare the descriptor parser. */
    312304        const usb_dp_parser_t dp_parser = {
    313305                .nesting = descriptor_nesting
     
    454446 * @return Error code.
    455447 */
    456 int usb_pipe_register(usb_pipe_t *pipe,
    457     unsigned int interval,
    458     usb_hc_connection_t *hc_connection)
    459 {
    460         return usb_pipe_register_with_speed(pipe, USB_SPEED_MAX + 1,
    461             interval, hc_connection);
    462 }
    463 
    464 /** Register endpoint with a speed at the host controller.
    465  *
    466  * You will rarely need to use this function because it is needed only
    467  * if the registered endpoint is of address 0 and there is no other way
    468  * to tell speed of the device at address 0.
    469  *
    470  * @param pipe Pipe to be registered.
    471  * @param speed Speed of the device
    472  *      (invalid speed means use previously specified one).
    473  * @param interval Polling interval.
    474  * @param hc_connection Connection to the host controller (must be opened).
    475  * @return Error code.
    476  */
    477 int usb_pipe_register_with_speed(usb_pipe_t *pipe, usb_speed_t speed,
    478     unsigned int interval,
     448int usb_pipe_register(usb_pipe_t *pipe, unsigned interval,
    479449    usb_hc_connection_t *hc_connection)
    480450{
    481451        assert(pipe);
    482452        assert(hc_connection);
    483        
     453
    484454        if (!usb_hc_connection_is_opened(hc_connection))
    485455                return EBADF;
    486        
     456
    487457        const usb_target_t target =
    488458            {{ .address = pipe->wire->address, .endpoint = pipe->endpoint_no }};
    489 #define _PACK2(high, low) (((high) << 16) + (low))
    490 #define _PACK3(high, middle, low) (((((high) << 8) + (middle)) << 8) + (low))
    491        
     459#define _PACK2(high, low) (((high & 0xffff) << 16) | (low & 0xffff))
     460
    492461        async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess);
    493462        int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE),
    494463            IPC_M_USBHC_REGISTER_ENDPOINT, target.packed,
    495             _PACK3(speed, pipe->transfer_type, pipe->direction),
     464            _PACK2(pipe->transfer_type, pipe->direction),
    496465            _PACK2(pipe->max_packet_size, interval));
    497466        async_exchange_end(exch);
    498        
     467
    499468#undef _PACK2
    500 #undef _PACK3
    501        
    502469        return rc;
    503470}
  • uspace/lib/usbdev/src/recognise.c

    r27ca3a3 rc2245a3  
    3535#include <sys/types.h>
    3636#include <fibril_synch.h>
     37#include <usb/debug.h>
     38#include <usb/dev/hub.h>
    3739#include <usb/dev/pipes.h>
    3840#include <usb/dev/recognise.h>
     
    5052
    5153/** DDF operations of child devices. */
    52 ddf_dev_ops_t child_ops = {
     54static ddf_dev_ops_t child_ops = {
    5355        .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl
    5456};
     
    6466#define BCD_ARGS(a) BCD_INT((a)), BCD_FRAC((a))
    6567
    66 /* FIXME: make this dynamic */
    67 #define MATCH_STRING_MAX 256
    68 
    6968/** Add formatted match id.
    7069 *
     
    7574 */
    7675static int usb_add_match_id(match_id_list_t *matches, int score,
    77     const char *format, ...)
     76    const char *match_str)
    7877{
    79         char *match_str = NULL;
    80         match_id_t *match_id = NULL;
    81         int rc;
    82        
    83         match_str = malloc(MATCH_STRING_MAX + 1);
    84         if (match_str == NULL) {
    85                 rc = ENOMEM;
    86                 goto failure;
    87         }
    88 
    89         /*
    90          * FIXME: replace with dynamic allocation of exact size
    91          */
    92         va_list args;
    93         va_start(args, format   );
    94         vsnprintf(match_str, MATCH_STRING_MAX, format, args);
    95         match_str[MATCH_STRING_MAX] = 0;
    96         va_end(args);
    97 
    98         match_id = create_match_id();
     78        assert(matches);
     79
     80        match_id_t *match_id = create_match_id();
    9981        if (match_id == NULL) {
    100                 rc = ENOMEM;
    101                 goto failure;
     82                return ENOMEM;
    10283        }
    10384
     
    10788
    10889        return EOK;
    109        
    110 failure:
    111         if (match_str != NULL) {
    112                 free(match_str);
    113         }
    114         if (match_id != NULL) {
    115                 match_id->id = NULL;
    116                 delete_match_id(match_id);
    117         }
    118        
    119         return rc;
    12090}
    12191
     
    12999#define ADD_MATCHID_OR_RETURN(match_ids, score, format, ...) \
    130100        do { \
    131                 int __rc = usb_add_match_id((match_ids), (score), \
    132                     format, ##__VA_ARGS__); \
     101                char *str = NULL; \
     102                int __rc = asprintf(&str, format, ##__VA_ARGS__); \
     103                if (__rc > 0) { \
     104                        __rc = usb_add_match_id((match_ids), (score), str); \
     105                } \
    133106                if (__rc != EOK) { \
     107                        free(str); \
    134108                        return __rc; \
    135109                } \
     
    150124    match_id_list_t *matches)
    151125{
    152         if (desc_interface == NULL) {
    153                 return EINVAL;
    154         }
    155         if (matches == NULL) {
     126        if (desc_interface == NULL || matches == NULL) {
    156127                return EINVAL;
    157128        }
     
    314285    match_id_list_t *matches)
    315286{
     287        assert(ctrl_pipe);
    316288        int rc;
    317289        /*
     
    336308/** Probe for device kind and register it in devman.
    337309 *
    338  * @param[in] address Address of the (unknown) attached device.
    339  * @param[in] hc_handle Handle of the host controller.
     310 * @param[in] ctrl_pipe Control pipe to the device.
    340311 * @param[in] parent Parent device.
    341  * @param[in] dev_ops Child device ops.
     312 * @param[in] dev_ops Child device ops. Default child_ops will be used if NULL.
    342313 * @param[in] dev_data Arbitrary pointer to be stored in the child
    343314 *      as @c driver_data.
     
    346317 * @return Error code.
    347318 */
    348 int usb_device_register_child_in_devman(usb_address_t address,
    349     devman_handle_t hc_handle, ddf_dev_t *parent,
    350     ddf_dev_ops_t *dev_ops, void *dev_data, ddf_fun_t **child_fun)
     319int usb_device_register_child_in_devman(usb_pipe_t *ctrl_pipe,
     320    ddf_dev_t *parent, ddf_dev_ops_t *dev_ops, void *dev_data,
     321    ddf_fun_t **child_fun)
    351322{
    352         size_t this_device_name_index;
     323        if (child_fun == NULL || ctrl_pipe == NULL)
     324                return EINVAL;
     325
     326        if (!dev_ops && dev_data) {
     327                usb_log_warning("Using standard fun ops with arbitrary "
     328                    "driver data. This does not have to work.\n");
     329        }
    353330
    354331        fibril_mutex_lock(&device_name_index_mutex);
    355         this_device_name_index = device_name_index;
    356         device_name_index++;
     332        const size_t this_device_name_index = device_name_index++;
    357333        fibril_mutex_unlock(&device_name_index_mutex);
    358334
    359335        ddf_fun_t *child = NULL;
    360         char *child_name = NULL;
    361336        int rc;
    362         usb_device_connection_t dev_connection;
    363         usb_pipe_t ctrl_pipe;
    364 
    365         rc = usb_device_connection_initialize(&dev_connection, hc_handle, address);
    366         if (rc != EOK) {
    367                 goto failure;
    368         }
    369 
    370         rc = usb_pipe_initialize_default_control(&ctrl_pipe,
    371             &dev_connection);
    372         if (rc != EOK) {
    373                 goto failure;
    374         }
    375         rc = usb_pipe_probe_default_control(&ctrl_pipe);
    376         if (rc != EOK) {
    377                 goto failure;
    378         }
    379337
    380338        /*
     
    382340         * naming etc., something more descriptive could be created.
    383341         */
    384         rc = asprintf(&child_name, "usb%02zu_a%d",
    385             this_device_name_index, address);
     342        char child_name[12]; /* The format is: "usbAB_aXYZ", length 11 */
     343        rc = snprintf(child_name, sizeof(child_name),
     344            "usb%02zu_a%d", this_device_name_index, ctrl_pipe->wire->address);
    386345        if (rc < 0) {
    387346                goto failure;
     
    401360
    402361        child->driver_data = dev_data;
    403 
    404         rc = usb_device_create_match_ids(&ctrl_pipe, &child->match_ids);
     362        /* Store the attached device in fun driver data if there is no
     363         * other data */
     364        if (!dev_data) {
     365                usb_hub_attached_device_t *new_device = ddf_fun_data_alloc(
     366                    child, sizeof(usb_hub_attached_device_t));
     367                if (!new_device) {
     368                        rc = ENOMEM;
     369                        goto failure;
     370                }
     371                new_device->address = ctrl_pipe->wire->address;
     372                new_device->fun = child;
     373        }
     374
     375
     376        rc = usb_device_create_match_ids(ctrl_pipe, &child->match_ids);
    405377        if (rc != EOK) {
    406378                goto failure;
     
    412384        }
    413385
    414         if (child_fun != NULL) {
    415                 *child_fun = child;
    416         }
    417 
     386        *child_fun = child;
    418387        return EOK;
    419388
    420389failure:
    421390        if (child != NULL) {
    422                 child->name = NULL;
     391                /* We know nothing about the data if it came from outside. */
     392                if (dev_data) {
     393                        child->driver_data = NULL;
     394                }
    423395                /* This takes care of match_id deallocation as well. */
    424396                ddf_fun_destroy(child);
    425397        }
    426         if (child_name != NULL) {
    427                 free(child_name);
    428         }
    429398
    430399        return rc;
  • uspace/lib/usbdev/src/request.c

    r27ca3a3 rc2245a3  
    250250}
    251251
    252 /** Change address of connected device.
    253  * This function automatically updates the backing connection to point to
    254  * the new address.
    255  *
    256  * @param pipe Control endpoint pipe (session must be already started).
    257  * @param new_address New USB address to be set (in native endianness).
    258  * @return Error code.
    259  */
    260 int usb_request_set_address(usb_pipe_t *pipe,
    261     usb_address_t new_address)
    262 {
    263         if ((new_address < 0) || (new_address >= USB11_ADDRESS_MAX)) {
    264                 return EINVAL;
    265         }
    266 
    267         uint16_t addr = uint16_host2usb((uint16_t)new_address);
    268 
    269         int rc = usb_control_request_set(pipe,
    270             USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE,
    271             USB_DEVREQ_SET_ADDRESS,
    272             addr, 0,
    273             NULL, 0);
    274 
    275         if (rc != EOK) {
    276                 return rc;
    277         }
    278 
    279         assert(pipe->wire != NULL);
    280         /* TODO: prevent other from accessing wire now. */
    281         pipe->wire->address = new_address;
    282 
    283         return EOK;
    284 }
    285 
    286252/** Retrieve USB descriptor of a USB device.
    287253 *
  • uspace/lib/usbhid/include/usb/hid/usages/consumer.h

    r27ca3a3 rc2245a3  
    3737#define LIBUSBHID_CONSUMER_H_
    3838
    39 const char *usbhid_multimedia_usage_to_str(int usage);
     39const char *usbhid_multimedia_usage_to_str(unsigned usage);
    4040
    4141#endif /* LIBUSBHID_CONSUMER_H_ */
  • uspace/lib/usbhid/src/consumer.c

    r27ca3a3 rc2245a3  
    3838#include <usb/hid/usages/consumer.h>
    3939
    40 static const char *usbhid_consumer_usage_str[0x29d] = {
     40static const char *usbhid_consumer_usage_str[] = {
    4141        [0x01] = "Consumer Control",
    4242        [0x02] = "Numeric Key Pad",
     
    358358        [0x13e] = "Reserved",
    359359        [0x13f] = "Reserved",
    360         [0x140] = "Reserved", 
     360        [0x140] = "Reserved",
    361361        [0x141] = "Reserved",
    362362        [0x142] = "Reserved",
     
    717717 * @retval HelenOS key code corresponding to the given USB Consumer Page Usage.
    718718 */
    719 const char *usbhid_multimedia_usage_to_str(int usage)
     719const char *usbhid_multimedia_usage_to_str(unsigned usage)
    720720{
    721         size_t map_length = sizeof(usbhid_consumer_usage_str) / sizeof(char *);
     721        static const size_t map_length =
     722            sizeof(usbhid_consumer_usage_str) / sizeof(char *);
    722723
    723         if ((usage < 0) || ((size_t)usage >= map_length))
     724        if (usage >= map_length)
    724725                return "Unknown usage";
    725726
    726         /*! @todo What if the usage is not in the table? */
    727727        return usbhid_consumer_usage_str[usage];
    728728}
  • uspace/lib/usbhid/src/hiddescriptor.c

    r27ca3a3 rc2245a3  
    135135int usb_hid_report_init(usb_hid_report_t *report)
    136136{
    137         if(report == NULL) {
     137        if (report == NULL) {
    138138                return EINVAL;
    139139        }
     
    144144
    145145        report->use_report_ids = 0;
    146     return EOK;   
     146    return EOK;
    147147}
    148148
  • uspace/lib/usbhid/src/hidpath.c

    r27ca3a3 rc2245a3  
    385385void usb_hid_report_path_free(usb_hid_report_path_t *path)
    386386{
     387        if (path == NULL)
     388                return;
    387389        while(!list_empty(&path->items)){
    388390                usb_hid_report_remove_last_item(path);
  • uspace/lib/usbhid/src/hidreq.c

    r27ca3a3 rc2245a3  
    8484        usb_log_debug("Sending Set Report request to the device.\n");
    8585       
    86         rc = usb_control_request_set(ctrl_pipe, 
    87             USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 
     86        rc = usb_control_request_set(ctrl_pipe,
     87            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE,
    8888            USB_HIDREQ_SET_REPORT, value, iface_no, buffer, buf_size);
    8989
    9090        if (rc != EOK) {
    91                 usb_log_warning("Error sending Set Report request to the "
     91                usb_log_error("Error sending Set Report request to the "
    9292                    "device: %s.\n", str_error(rc));
    9393                return rc;
  • uspace/lib/usbhost/include/usb/host/hcd.h

    r27ca3a3 rc2245a3  
    6868 * @param bw_count Bandwidth compute function, passed to endpoint manager.
    6969 */
    70 static inline void hcd_init(hcd_t *hcd, size_t bandwidth,
     70static inline void hcd_init(hcd_t *hcd, usb_speed_t max_speed, size_t bandwidth,
    7171    size_t (*bw_count)(usb_speed_t, usb_transfer_type_t, size_t, size_t))
    7272{
    7373        assert(hcd);
    74         usb_device_manager_init(&hcd->dev_manager);
     74        usb_device_manager_init(&hcd->dev_manager, max_speed);
    7575        usb_endpoint_manager_init(&hcd->ep_manager, bandwidth, bw_count);
    7676        hcd->private_data = NULL;
  • uspace/lib/usbhost/include/usb/host/usb_device_manager.h

    r27ca3a3 rc2245a3  
    5959                devman_handle_t handle; /**< Devman handle of the device. */
    6060        } devices[USB_ADDRESS_COUNT];
     61        usb_speed_t max_speed;
    6162        fibril_mutex_t guard;
    6263        /** The last reserved address */
     
    6465} usb_device_manager_t;
    6566
    66 void usb_device_manager_init(usb_device_manager_t *instance);
     67void usb_device_manager_init(
     68    usb_device_manager_t *instance, usb_speed_t max_speed);
    6769
    68 usb_address_t usb_device_manager_get_free_address(
    69     usb_device_manager_t *instance, usb_speed_t speed);
     70int usb_device_manager_request_address(usb_device_manager_t *instance,
     71    usb_address_t *address, bool strict, usb_speed_t speed);
    7072
    71 int usb_device_manager_bind(usb_device_manager_t *instance,
     73int usb_device_manager_bind_address(usb_device_manager_t *instance,
    7274    usb_address_t address, devman_handle_t handle);
    7375
    74 int usb_device_manager_release(usb_device_manager_t *instance,
     76int usb_device_manager_release_address(usb_device_manager_t *instance,
    7577    usb_address_t address);
    7678
  • uspace/lib/usbhost/include/usb/host/usb_endpoint_manager.h

    r27ca3a3 rc2245a3  
    9090    usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction,
    9191    void (*callback)(endpoint_t *, void *), void *arg);
     92
     93void usb_endpoint_manager_remove_address(usb_endpoint_manager_t *instance,
     94    usb_address_t address, void (*callback)(endpoint_t *, void *), void *arg);
    9295#endif
    9396/**
  • uspace/lib/usbhost/src/iface.c

    r27ca3a3 rc2245a3  
    8989}
    9090/*----------------------------------------------------------------------------*/
    91 /** Request address interface function
    92  *
    93  * @param[in] fun DDF function that was called.
    94  * @param[in] speed Speed to associate with the new default address.
    95  * @param[out] address Place to write a new address.
    96  * @return Error code.
    97  */
    98 static int request_address(
    99     ddf_fun_t *fun, usb_speed_t speed, usb_address_t *address)
    100 {
    101         assert(fun);
    102         hcd_t *hcd = fun_to_hcd(fun);
    103         assert(hcd);
    104         assert(address);
    105 
    106         usb_log_debug("Address request speed: %s.\n", usb_str_speed(speed));
    107         *address =
    108             usb_device_manager_get_free_address(&hcd->dev_manager, speed);
    109         usb_log_debug("Address request with result: %d.\n", *address);
    110         if (*address <= 0)
    111                 return *address;
    112         return EOK;
    113 }
    114 /*----------------------------------------------------------------------------*/
    115 /** Bind address interface function
    116  *
    117  * @param[in] fun DDF function that was called.
    118  * @param[in] address Address of the device
    119  * @param[in] handle Devman handle of the device driver.
    120  * @return Error code.
    121  */
    122 static int bind_address(
    123   ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
    124 {
    125         assert(fun);
    126         hcd_t *hcd = fun_to_hcd(fun);
    127         assert(hcd);
    128 
    129         usb_log_debug("Address bind %d-%" PRIun ".\n", address, handle);
    130         return usb_device_manager_bind(&hcd->dev_manager, address, handle);
    131 }
    132 /*----------------------------------------------------------------------------*/
    133 /** Find device handle by address interface function.
    134  *
    135  * @param[in] fun DDF function that was called.
    136  * @param[in] address Address in question.
    137  * @param[out] handle Where to store device handle if found.
    138  * @return Error code.
    139  */
    140 static int find_by_address(ddf_fun_t *fun, usb_address_t address,
    141     devman_handle_t *handle)
    142 {
    143         assert(fun);
    144         hcd_t *hcd = fun_to_hcd(fun);
    145         assert(hcd);
    146         return usb_device_manager_get_info_by_address(
    147             &hcd->dev_manager, address, handle, NULL);
    148 }
    149 /*----------------------------------------------------------------------------*/
    150 /** Release address interface function
    151  *
    152  * @param[in] fun DDF function that was called.
    153  * @param[in] address USB address to be released.
    154  * @return Error code.
    155  */
    156 static int release_address(ddf_fun_t *fun, usb_address_t address)
    157 {
    158         assert(fun);
    159         hcd_t *hcd = fun_to_hcd(fun);
    160         assert(hcd);
    161         usb_log_debug("Address release %d.\n", address);
    162         usb_device_manager_release(&hcd->dev_manager, address);
    163         return EOK;
    164 }
    165 /*----------------------------------------------------------------------------*/
    16691static int register_helper(endpoint_t *ep, void *arg)
    16792{
     
    183108}
    184109/*----------------------------------------------------------------------------*/
     110static void unregister_helper_warn(endpoint_t *ep, void *arg)
     111{
     112        hcd_t *hcd = arg;
     113        assert(ep);
     114        assert(hcd);
     115        usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n",
     116            ep->address, ep->endpoint, usb_str_direction(ep->direction));
     117        if (hcd->ep_remove_hook)
     118                hcd->ep_remove_hook(hcd, ep);
     119}
     120/*----------------------------------------------------------------------------*/
     121/** Request address interface function
     122 *
     123 * @param[in] fun DDF function that was called.
     124 * @param[in] speed Speed to associate with the new default address.
     125 * @param[out] address Place to write a new address.
     126 * @return Error code.
     127 */
     128static int request_address(
     129    ddf_fun_t *fun, usb_address_t *address, bool strict, usb_speed_t speed)
     130{
     131        assert(fun);
     132        hcd_t *hcd = fun_to_hcd(fun);
     133        assert(hcd);
     134        assert(address);
     135
     136        usb_log_debug("Address request: speed: %s, address: %d, strict: %s.\n",
     137            usb_str_speed(speed), *address, strict ? "YES" : "NO");
     138        return usb_device_manager_request_address(
     139            &hcd->dev_manager, address, strict, speed);
     140}
     141/*----------------------------------------------------------------------------*/
     142/** Bind address interface function
     143 *
     144 * @param[in] fun DDF function that was called.
     145 * @param[in] address Address of the device
     146 * @param[in] handle Devman handle of the device driver.
     147 * @return Error code.
     148 */
     149static int bind_address(
     150  ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)
     151{
     152        assert(fun);
     153        hcd_t *hcd = fun_to_hcd(fun);
     154        assert(hcd);
     155
     156        usb_log_debug("Address bind %d-%" PRIun ".\n", address, handle);
     157        return usb_device_manager_bind_address(
     158            &hcd->dev_manager, address, handle);
     159}
     160/*----------------------------------------------------------------------------*/
     161/** Find device handle by address interface function.
     162 *
     163 * @param[in] fun DDF function that was called.
     164 * @param[in] address Address in question.
     165 * @param[out] handle Where to store device handle if found.
     166 * @return Error code.
     167 */
     168static int find_by_address(ddf_fun_t *fun, usb_address_t address,
     169    devman_handle_t *handle)
     170{
     171        assert(fun);
     172        hcd_t *hcd = fun_to_hcd(fun);
     173        assert(hcd);
     174        return usb_device_manager_get_info_by_address(
     175            &hcd->dev_manager, address, handle, NULL);
     176}
     177/*----------------------------------------------------------------------------*/
     178/** Release address interface function
     179 *
     180 * @param[in] fun DDF function that was called.
     181 * @param[in] address USB address to be released.
     182 * @return Error code.
     183 */
     184static int release_address(ddf_fun_t *fun, usb_address_t address)
     185{
     186        assert(fun);
     187        hcd_t *hcd = fun_to_hcd(fun);
     188        assert(hcd);
     189        usb_log_debug("Address release %d.\n", address);
     190        usb_device_manager_release_address(&hcd->dev_manager, address);
     191        usb_endpoint_manager_remove_address(&hcd->ep_manager, address,
     192            unregister_helper_warn, hcd);
     193        return EOK;
     194}
     195/*----------------------------------------------------------------------------*/
    185196static int register_endpoint(
    186     ddf_fun_t *fun, usb_address_t address, usb_speed_t ep_speed,
    187     usb_endpoint_t endpoint,
     197    ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint,
    188198    usb_transfer_type_t transfer_type, usb_direction_t direction,
    189199    size_t max_packet_size, unsigned int interval)
     
    193203        assert(hcd);
    194204        const size_t size = max_packet_size;
    195         /* Default address is not bound or registered,
    196          * thus it does not provide speed info. */
    197         usb_speed_t speed = ep_speed;
    198         /* NOTE The function will return EINVAL and won't
    199          * touch speed variable for default address */
    200         usb_device_manager_get_info_by_address(
     205        usb_speed_t speed = USB_SPEED_MAX;
     206        const int ret = usb_device_manager_get_info_by_address(
    201207            &hcd->dev_manager, address, NULL, &speed);
     208        if (ret != EOK) {
     209                return ret;
     210        }
    202211
    203212        usb_log_debug("Register endpoint %d:%d %s-%s %s %zuB %ums.\n",
  • uspace/lib/usbhost/src/usb_device_manager.c

    r27ca3a3 rc2245a3  
    3838#include <usb/host/usb_device_manager.h>
    3939
     40/** Get a free USB address
     41 *
     42 * @param[in] instance Device manager structure to use.
     43 * @param[in] speed Speed of the device requiring address.
     44 * @return Free address, or error code.
     45 */
     46static usb_address_t usb_device_manager_get_free_address(
     47    usb_device_manager_t *instance)
     48{
     49
     50        usb_address_t new_address = instance->last_address;
     51        do {
     52                new_address = (new_address + 1) % USB_ADDRESS_COUNT;
     53                if (new_address == USB_ADDRESS_DEFAULT)
     54                        new_address = 1;
     55                if (new_address == instance->last_address) {
     56                        return ENOSPC;
     57                }
     58        } while (instance->devices[new_address].occupied);
     59
     60        assert(new_address != USB_ADDRESS_DEFAULT);
     61        instance->last_address = new_address;
     62
     63        return new_address;
     64}
     65/*----------------------------------------------------------------------------*/
    4066/** Initialize device manager structure.
    4167 *
    4268 * @param[in] instance Memory place to initialize.
     69 * @param[in] max_speed Maximum allowed USB speed of devices (inclusive).
    4370 *
    4471 * Set all values to false/0.
    4572 */
    46 void usb_device_manager_init(usb_device_manager_t *instance)
     73void usb_device_manager_init(
     74    usb_device_manager_t *instance, usb_speed_t max_speed)
    4775{
    4876        assert(instance);
     
    5280                instance->devices[i].speed = USB_SPEED_MAX;
    5381        }
    54         // TODO: is this hack enough?
    55         // (it is needed to allow smooth registration at default address)
    56         instance->devices[0].occupied = true;
    57         instance->last_address = 0;
     82        instance->last_address = 1;
     83        instance->max_speed = max_speed;
    5884        fibril_mutex_initialize(&instance->guard);
    5985}
    6086/*----------------------------------------------------------------------------*/
    61 /** Get a free USB address
    62  *
    63  * @param[in] instance Device manager structure to use.
    64  * @param[in] speed Speed of the device requiring address.
    65  * @return Free address, or error code.
    66  */
    67 usb_address_t usb_device_manager_get_free_address(
    68     usb_device_manager_t *instance, usb_speed_t speed)
    69 {
    70         assert(instance);
    71         fibril_mutex_lock(&instance->guard);
    72 
    73         usb_address_t new_address = instance->last_address;
    74         do {
    75                 ++new_address;
    76                 if (new_address > USB11_ADDRESS_MAX)
    77                         new_address = 1; // NOTE it should be safe to put 0 here
    78                                          // TODO Use mod
    79                 if (new_address == instance->last_address) {
     87/** Request USB address.
     88 * @param instance usb_device_manager
     89 * @param address Pointer to requested address value, place to store new address
     90 * @parma strict Fail if the requested address is not available.
     91 * @return Error code.
     92 * @note Default address is only available in strict mode.
     93 */
     94int usb_device_manager_request_address(usb_device_manager_t *instance,
     95    usb_address_t *address, bool strict, usb_speed_t speed)
     96{
     97        assert(instance);
     98        assert(address);
     99        if (speed > instance->max_speed)
     100                return ENOTSUP;
     101
     102        if ((*address) < 0 || (*address) >= USB_ADDRESS_COUNT)
     103                return EINVAL;
     104
     105        fibril_mutex_lock(&instance->guard);
     106        /* Only grant default address to strict requests */
     107        if (( (*address) == USB_ADDRESS_DEFAULT) && !strict) {
     108                *address = instance->last_address;
     109        }
     110
     111        if (instance->devices[*address].occupied) {
     112                if (strict) {
    80113                        fibril_mutex_unlock(&instance->guard);
    81                         return ENOSPC;
     114                        return ENOENT;
    82115                }
    83         } while (instance->devices[new_address].occupied);
    84 
    85         assert(new_address != USB_ADDRESS_DEFAULT);
    86         assert(instance->devices[new_address].occupied == false);
    87         assert(instance->devices[new_address].handle == 0);
    88 
    89         instance->devices[new_address].occupied = true;
    90         instance->devices[new_address].speed = speed;
    91         instance->last_address = new_address;
    92 
    93         fibril_mutex_unlock(&instance->guard);
    94         return new_address;
     116                *address = usb_device_manager_get_free_address(instance);
     117        }
     118        assert(instance->devices[*address].occupied == false);
     119        assert(instance->devices[*address].handle == 0);
     120        assert(*address != USB_ADDRESS_DEFAULT || strict);
     121
     122        instance->devices[*address].occupied = true;
     123        instance->devices[*address].speed = speed;
     124
     125        fibril_mutex_unlock(&instance->guard);
     126        return EOK;
    95127}
    96128/*----------------------------------------------------------------------------*/
     
    102134 * @return Error code.
    103135 */
    104 int usb_device_manager_bind(usb_device_manager_t *instance,
     136int usb_device_manager_bind_address(usb_device_manager_t *instance,
    105137    usb_address_t address, devman_handle_t handle)
    106138{
     
    132164 * @return Error code.
    133165 */
    134 int usb_device_manager_release(
     166int usb_device_manager_release_address(
    135167    usb_device_manager_t *instance, usb_address_t address)
    136168{
    137         if ((address <= 0) || (address >= USB_ADDRESS_COUNT)) {
     169        if ((address < 0) || (address >= USB_ADDRESS_COUNT)) {
    138170                return EINVAL;
    139171        }
     
    188220{
    189221        assert(instance);
    190         if ((address <= 0) || (address >= USB_ADDRESS_COUNT)) {
     222        if ((address < 0) || (address >= USB_ADDRESS_COUNT)) {
    191223                return EINVAL;
    192224        }
  • uspace/lib/usbhost/src/usb_endpoint_manager.c

    r27ca3a3 rc2245a3  
    384384        return EOK;
    385385}
     386/*----------------------------------------------------------------------------*/
     387void usb_endpoint_manager_remove_address(usb_endpoint_manager_t *instance,
     388    usb_address_t address, void (*callback)(endpoint_t *, void *), void *arg)
     389{
     390        assert(address >= 0);
     391        assert(instance);
     392        fibril_mutex_lock(&instance->guard);
     393        list_foreach(*get_list(instance, address), iterator) {
     394                endpoint_t *ep = endpoint_get_instance(iterator);
     395                if (ep->address == address) {
     396                        iterator = iterator->next;
     397                        list_remove(&ep->link);
     398                        if (callback)
     399                                callback(ep, arg);
     400                        endpoint_destroy(ep);
     401                }
     402        }
     403        fibril_mutex_unlock(&instance->guard);
     404}
Note: See TracChangeset for help on using the changeset viewer.