Changeset c2245a3 in mainline for uspace/lib
- Timestamp:
- 2011-11-10T20:03:48Z (14 years ago)
- 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. - Location:
- uspace/lib
- Files:
-
- 38 edited
-
drv/generic/remote_usb.c (modified) (3 diffs)
-
drv/generic/remote_usbhc.c (modified) (4 diffs)
-
drv/include/usb_iface.h (modified) (2 diffs)
-
drv/include/usbhc_iface.h (modified) (2 diffs)
-
usb/Makefile (modified) (1 diff)
-
usb/include/usb/ddfiface.h (modified) (1 diff)
-
usb/include/usb/hc.h (modified) (1 diff)
-
usb/src/class.c (modified) (1 diff)
-
usb/src/ddfiface.c (modified) (6 diffs)
-
usb/src/hc.c (modified) (2 diffs)
-
usb/src/resolve.c (modified) (1 diff)
-
usbdev/include/usb/dev/dp.h (modified) (1 diff)
-
usbdev/include/usb/dev/driver.h (modified) (4 diffs)
-
usbdev/include/usb/dev/hub.h (modified) (1 diff)
-
usbdev/include/usb/dev/pipes.h (modified) (3 diffs)
-
usbdev/include/usb/dev/poll.h (modified) (1 diff)
-
usbdev/include/usb/dev/recognise.h (modified) (1 diff)
-
usbdev/include/usb/dev/request.h (modified) (2 diffs)
-
usbdev/src/altiface.c (modified) (5 diffs)
-
usbdev/src/devdrv.c (modified) (15 diffs)
-
usbdev/src/devpoll.c (modified) (4 diffs)
-
usbdev/src/dp.c (modified) (1 diff)
-
usbdev/src/hub.c (modified) (15 diffs)
-
usbdev/src/pipes.c (modified) (2 diffs)
-
usbdev/src/pipesinit.c (modified) (5 diffs)
-
usbdev/src/recognise.c (modified) (13 diffs)
-
usbdev/src/request.c (modified) (1 diff)
-
usbhid/include/usb/hid/usages/consumer.h (modified) (1 diff)
-
usbhid/src/consumer.c (modified) (3 diffs)
-
usbhid/src/hiddescriptor.c (modified) (2 diffs)
-
usbhid/src/hidpath.c (modified) (1 diff)
-
usbhid/src/hidreq.c (modified) (1 diff)
-
usbhost/include/usb/host/hcd.h (modified) (1 diff)
-
usbhost/include/usb/host/usb_device_manager.h (modified) (2 diffs)
-
usbhost/include/usb/host/usb_endpoint_manager.h (modified) (1 diff)
-
usbhost/src/iface.c (modified) (3 diffs)
-
usbhost/src/usb_device_manager.c (modified) (5 diffs)
-
usbhost/src/usb_endpoint_manager.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/remote_usb.c
r27ca3a3 rc2245a3 40 40 41 41 42 static void remote_usb_get_ address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);42 static void remote_usb_get_my_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 43 43 static void remote_usb_get_interface(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 44 44 static void remote_usb_get_hc_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); … … 47 47 /** Remote USB interface operations. */ 48 48 static remote_iface_func_ptr_t remote_usb_iface_ops [] = { 49 remote_usb_get_address,50 remote_usb_get_interface,51 remote_usb_get_hc_handle49 [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, 52 52 }; 53 53 … … 61 61 62 62 63 void remote_usb_get_ address(ddf_fun_t *fun, void *iface,63 void remote_usb_get_my_address(ddf_fun_t *fun, void *iface, 64 64 ipc_callid_t callid, ipc_call_t *call) 65 65 { 66 66 usb_iface_t *usb_iface = (usb_iface_t *) iface; 67 67 68 if (usb_iface->get_ address == NULL) {68 if (usb_iface->get_my_address == NULL) { 69 69 async_answer_0(callid, ENOTSUP); 70 70 return; 71 71 } 72 72 73 devman_handle_t handle = DEV_IPC_GET_ARG1(*call);74 75 73 usb_address_t address; 76 int rc = usb_iface->get_ address(fun, handle, &address);74 int rc = usb_iface->get_my_address(fun, &address); 77 75 if (rc != EOK) { 78 76 async_answer_0(callid, rc); -
uspace/lib/drv/generic/remote_usbhc.c
r27ca3a3 rc2245a3 55 55 static remote_iface_func_ptr_t remote_usbhc_iface_ops[] = { 56 56 [IPC_M_USBHC_REQUEST_ADDRESS] = remote_usbhc_request_address, 57 [IPC_M_USBHC_RELEASE_ADDRESS] = remote_usbhc_release_address, 57 58 [IPC_M_USBHC_BIND_ADDRESS] = remote_usbhc_bind_address, 58 59 [IPC_M_USBHC_GET_HANDLE_BY_ADDRESS] = remote_usbhc_find_by_address, 59 [IPC_M_USBHC_RELEASE_ADDRESS] = remote_usbhc_release_address,60 60 61 61 [IPC_M_USBHC_REGISTER_ENDPOINT] = remote_usbhc_register_endpoint, … … 118 118 } 119 119 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); 124 125 if (rc != EOK) { 125 126 async_answer_0(callid, rc); … … 233 234 234 235 #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) 236 237 #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) 244 239 245 240 const usb_target_t target = { .packed = DEV_IPC_GET_ARG1(*call) }; 246 241 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); 250 244 251 245 _INIT_FROM_HIGH_DATA2(size_t, max_packet_size, 3); … … 254 248 #undef _INIT_FROM_HIGH_DATA2 255 249 #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, 261 252 target.endpoint, transfer_type, direction, max_packet_size, interval); 262 253 -
uspace/lib/drv/include/usb_iface.h
r27ca3a3 rc2245a3 65 65 * handle must be resolved by its parent. 66 66 */ 67 IPC_M_USB_GET_ ADDRESS,67 IPC_M_USB_GET_MY_ADDRESS, 68 68 69 69 /** Tell interface number given device can use. … … 90 90 /** USB device communication interface. */ 91 91 typedef 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 *); 93 93 int (*get_interface)(ddf_fun_t *, devman_handle_t, int *); 94 94 int (*get_hc_handle)(ddf_fun_t *, devman_handle_t *); -
uspace/lib/drv/include/usbhc_iface.h
r27ca3a3 rc2245a3 170 170 /** USB host controller communication interface. */ 171 171 typedef 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); 173 173 int (*bind_address)(ddf_fun_t *, usb_address_t, devman_handle_t); 174 174 int (*find_by_address)(ddf_fun_t *, usb_address_t, devman_handle_t *); … … 176 176 177 177 int (*register_endpoint)(ddf_fun_t *, 178 usb_address_t, usb_ speed_t, usb_endpoint_t,178 usb_address_t, usb_endpoint_t, 179 179 usb_transfer_type_t, usb_direction_t, size_t, unsigned int); 180 180 int (*unregister_endpoint)(ddf_fun_t *, usb_address_t, usb_endpoint_t, -
uspace/lib/usb/Makefile
r27ca3a3 rc2245a3 31 31 EXTRA_CFLAGS += \ 32 32 -I$(LIBDRV_PREFIX)/include \ 33 -I$(LIBUSBDEV_PREFIX)/include \ 33 34 -Iinclude 34 35 -
uspace/lib/usb/include/usb/ddfiface.h
r27ca3a3 rc2245a3 39 39 #include <usb_iface.h> 40 40 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 *); 41 int usb_iface_get_hc_handle_device_impl(ddf_fun_t *, devman_handle_t *); 42 int usb_iface_get_my_address_forward_impl(ddf_fun_t *, usb_address_t *); 44 43 extern usb_iface_t usb_iface_hub_impl; 45 44 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 *); 45 int usb_iface_get_my_address_from_device_data(ddf_fun_t *, usb_address_t *); 49 46 extern usb_iface_t usb_iface_hub_child_impl; 50 47 51 48 int usb_iface_get_hc_handle_hc_impl(ddf_fun_t *, devman_handle_t *); 52 53 49 54 50 #endif -
uspace/lib/usb/include/usb/hc.h
r27ca3a3 rc2245a3 62 62 devman_handle_t *); 63 63 64 usb_address_t usb_ hc_get_address_by_handle(devman_handle_t);64 usb_address_t usb_get_address_by_handle(devman_handle_t); 65 65 66 66 int usb_hc_find(devman_handle_t, devman_handle_t *); -
uspace/lib/usb/src/class.c
r27ca3a3 rc2245a3 81 81 return "application"; 82 82 case USB_CLASS_VENDOR_SPECIFIC: 83 return "vendor ";83 return "vendor-specific"; 84 84 default: 85 85 return "unknown"; -
uspace/lib/usb/src/ddfiface.c
r27ca3a3 rc2245a3 39 39 #include <usb/hc.h> 40 40 #include <usb/debug.h> 41 #include <usb/dev/hub.h> 41 42 #include <errno.h> 42 43 #include <assert.h> 43 44 44 45 /** 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_impl46 usb_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, 48 49 }; 49 50 50 51 /** 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_impl52 usb_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, 54 55 }; 55 56 … … 61 62 * @return Error code. 62 63 */ 63 int usb_iface_get_hc_handle_ hub_impl(ddf_fun_t *fun, devman_handle_t *handle)64 int usb_iface_get_hc_handle_device_impl(ddf_fun_t *fun, devman_handle_t *handle) 64 65 { 65 66 assert(fun); 66 67 return usb_hc_find(fun->handle, handle); 67 }68 69 /** Get host controller handle, interface implementation for child of70 * 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;101 68 } 102 69 … … 125 92 * @return Error code. 126 93 */ 127 int usb_iface_get_ address_hub_impl(ddf_fun_t *fun, devman_handle_t handle,94 int usb_iface_get_my_address_forward_impl(ddf_fun_t *fun, 128 95 usb_address_t *address) 129 96 { 130 97 assert(fun); 131 98 132 99 async_sess_t *parent_sess = 133 100 devman_parent_device_connect(EXCHANGE_SERIALIZE, fun->handle, … … 135 102 if (!parent_sess) 136 103 return ENOMEM; 137 104 138 105 async_exch_t *exch = async_exchange_begin(parent_sess); 139 106 140 107 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 144 111 async_exchange_end(exch); 145 112 async_hangup(parent_sess); 146 113 147 114 if (rc != EOK) 148 115 return rc; 149 116 150 117 if (address != NULL) 151 118 *address = (usb_address_t) addr; 152 119 153 120 return EOK; 154 121 } … … 157 124 * a hub driver. 158 125 * 126 * This implementation eccepts 0 as valid handle and replaces it with fun's 127 * handle. 128 * 159 129 * @param[in] fun Device function the operation is running on. 160 130 * @param[in] handle Devman handle of USB device we want address of. … … 162 132 * @return Error code. 163 133 */ 164 int usb_iface_get_ address_hub_child_impl(ddf_fun_t *fun,165 devman_handle_t handle,usb_address_t *address)134 int usb_iface_get_my_address_from_device_data(ddf_fun_t *fun, 135 usb_address_t *address) 166 136 { 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; 171 144 } 172 145 -
uspace/lib/usb/src/hc.c
r27ca3a3 rc2245a3 174 174 * @return USB address or negative error code. 175 175 */ 176 usb_address_t usb_ hc_get_address_by_handle(devman_handle_t dev_handle)176 usb_address_t usb_get_address_by_handle(devman_handle_t dev_handle) 177 177 { 178 178 async_sess_t *parent_sess = … … 185 185 186 186 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); 190 189 191 190 async_exchange_end(exch); -
uspace/lib/usb/src/resolve.c
r27ca3a3 rc2245a3 200 200 /* Try to get its address. */ 201 201 if (!found_addr) { 202 dev_addr = usb_ hc_get_address_by_handle(tmp_handle);202 dev_addr = usb_get_address_by_handle(tmp_handle); 203 203 if (dev_addr >= 0) { 204 204 found_addr = true; -
uspace/lib/usbdev/include/usb/dev/dp.h
r27ca3a3 rc2245a3 54 54 } usb_dp_descriptor_nesting_t; 55 55 56 extern usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[];56 extern const usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[]; 57 57 58 58 /** Descriptor parser structure. */ -
uspace/lib/usbdev/include/usb/dev/driver.h
r27ca3a3 rc2245a3 72 72 /** USB device structure. */ 73 73 typedef 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; 74 78 /** The default control pipe. */ 75 79 usb_pipe_t ctrl_pipe; … … 87 91 int interface_no; 88 92 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; 94 95 95 96 /** Some useful descriptors. */ 96 97 usb_device_descriptors_t descriptors; 97 98 98 /** Generic DDF device backing this one. RO: DO NOT TOUCH!*/99 /** Generic DDF device backing this one. DO NOT TOUCH! */ 99 100 ddf_dev_t *ddf_dev; 100 101 /** Custom driver data. … … 103 104 */ 104 105 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;110 106 } usb_device_t; 111 107 … … 163 159 int usb_driver_main(const usb_driver_t *); 164 160 161 int usb_device_init(usb_device_t *, ddf_dev_t *, 162 const usb_endpoint_description_t **, const char **); 163 void usb_device_deinit(usb_device_t *); 164 165 165 int usb_device_select_interface(usb_device_t *, uint8_t, 166 166 const usb_endpoint_description_t **); 167 167 168 168 int usb_device_retrieve_descriptors(usb_pipe_t *, usb_device_descriptors_t *); 169 void usb_device_release_descriptors(usb_device_descriptors_t *); 170 169 171 int usb_device_create_pipes(const ddf_dev_t *, usb_device_connection_t *, 170 172 const usb_endpoint_description_t **, const uint8_t *, size_t, int, int, 171 173 usb_endpoint_mapping_t **, size_t *); 172 174 int 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 *);176 175 177 176 void * usb_device_data_alloc(usb_device_t *, size_t); 178 177 179 178 size_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_de stroy(usb_alternate_interfaces_t *);179 int usb_alternate_interfaces_init(usb_alternate_interfaces_t *, 180 const uint8_t *, size_t, int); 181 void usb_alternate_interfaces_deinit(usb_alternate_interfaces_t *); 183 182 #endif 184 183 /** -
uspace/lib/usbdev/include/usb/dev/hub.h
r27ca3a3 rc2245a3 59 59 } usb_hub_attached_device_t; 60 60 61 usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_speed_t); 61 usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_address_t, 62 bool, usb_speed_t); 62 63 int usb_hc_register_device(usb_hc_connection_t *, 63 64 const usb_hub_attached_device_t *); -
uspace/lib/usbdev/include/usb/dev/pipes.h
r27ca3a3 rc2245a3 141 141 typedef struct { 142 142 /** Endpoint pipe. */ 143 usb_pipe_t *pipe;143 usb_pipe_t pipe; 144 144 /** Endpoint description. */ 145 145 const usb_endpoint_description_t *description; … … 149 149 int interface_setting; 150 150 /** Found descriptor fitting the description. */ 151 usb_standard_endpoint_descriptor_t *descriptor;151 const usb_standard_endpoint_descriptor_t *descriptor; 152 152 /** Interface descriptor the endpoint belongs to. */ 153 usb_standard_interface_descriptor_t *interface;153 const usb_standard_interface_descriptor_t *interface; 154 154 /** Whether the endpoint was actually found. */ 155 155 bool present; … … 172 172 int usb_pipe_initialize_from_configuration(usb_endpoint_mapping_t *, 173 173 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 *);176 174 int usb_pipe_register(usb_pipe_t *, unsigned int, usb_hc_connection_t *); 177 175 int usb_pipe_unregister(usb_pipe_t *, usb_hc_connection_t *); -
uspace/lib/usbdev/include/usb/dev/poll.h
r27ca3a3 rc2245a3 84 84 } usb_device_auto_polling_t; 85 85 86 int usb_device_auto_polling(usb_device_t *, size_t, usb_device_auto_polling_t *,87 size_t, void *);86 int usb_device_auto_polling(usb_device_t *, size_t, 87 const usb_device_auto_polling_t *, size_t, void *); 88 88 89 89 typedef bool (*usb_polling_callback_t)(usb_device_t *, -
uspace/lib/usbdev/include/usb/dev/recognise.h
r27ca3a3 rc2245a3 50 50 int usb_device_create_match_ids(usb_pipe_t *, match_id_list_t *); 51 51 52 int usb_device_register_child_in_devman(usb_ address_t, devman_handle_t,52 int usb_device_register_child_in_devman(usb_pipe_t *ctrl_pipe, 53 53 ddf_dev_t *, ddf_dev_ops_t *, void *, ddf_fun_t **); 54 54 -
uspace/lib/usbdev/include/usb/dev/request.h
r27ca3a3 rc2245a3 115 115 int usb_request_set_feature(usb_pipe_t *, usb_request_type_t, 116 116 usb_request_recipient_t, uint16_t, uint16_t); 117 int usb_request_set_address(usb_pipe_t *, usb_address_t);118 117 int 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, 120 119 size_t *); 121 120 int usb_request_get_descriptor_alloc(usb_pipe_t *, usb_request_type_t, … … 131 130 int usb_request_set_descriptor(usb_pipe_t *, usb_request_type_t, 132 131 usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t); 132 133 133 int usb_request_get_configuration(usb_pipe_t *, uint8_t *); 134 134 int usb_request_set_configuration(usb_pipe_t *, uint8_t); -
uspace/lib/usbdev/src/altiface.c
r27ca3a3 rc2245a3 90 90 * @return Error code. 91 91 */ 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) 92 int usb_alternate_interfaces_init(usb_alternate_interfaces_t *alternates, 93 const uint8_t *config_descr, size_t config_descr_size, int interface_number) 95 94 { 96 assert(alternates _ptr!= NULL);95 assert(alternates != NULL); 97 96 assert(config_descr != NULL); 98 97 assert(config_descr_size > 0); 99 98 100 *alternates_ptr = NULL; 99 alternates->alternatives = NULL; 100 alternates->alternative_count = 0; 101 alternates->current = 0; 102 101 103 if (interface_number < 0) { 102 104 return EOK; 103 }104 105 usb_alternate_interfaces_t *alternates106 = malloc(sizeof(usb_alternate_interfaces_t));107 if (alternates == NULL) {108 return ENOMEM;109 105 } 110 106 … … 114 110 115 111 if (alternates->alternative_count == 0) { 116 free(alternates);117 112 return ENOENT; 118 113 } … … 121 116 sizeof(usb_alternate_interface_descriptors_t)); 122 117 if (alternates->alternatives == NULL) { 123 free(alternates);124 118 return ENOMEM; 125 119 } 126 120 127 alternates->current = 0; 128 129 usb_dp_parser_t dp_parser = { 121 const usb_dp_parser_t dp_parser = { 130 122 .nesting = usb_dp_standard_descriptor_nesting 131 123 }; 132 usb_dp_parser_data_t dp_data = {124 const usb_dp_parser_data_t dp_data = { 133 125 .data = config_descr, 134 126 .size = config_descr_size, … … 147 139 || (iface->interface_number != interface_number)) { 148 140 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); 151 142 continue; 152 143 } … … 170 161 } 171 162 172 *alternates_ptr = alternates;173 174 163 return EOK; 175 164 } 176 165 177 void usb_alternate_interfaces_de stroy(usb_alternate_interfaces_t *alternate)166 void usb_alternate_interfaces_deinit(usb_alternate_interfaces_t *alternate) 178 167 { 179 168 if (!alternate) 180 169 return; 181 170 free(alternate->alternatives); 182 free(alternate);183 171 } 184 172 /** -
uspace/lib/usbdev/src/devdrv.c
r27ca3a3 rc2245a3 81 81 * @return Number of pipes (excluding default control pipe). 82 82 */ 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 83 static 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); 94 88 return count; 95 89 } … … 104 98 usb_device_t *dev, int alternate_setting) 105 99 { 100 assert(dev); 101 106 102 if (endpoints == NULL) { 107 103 dev->pipes = NULL; … … 300 296 301 297 return rc; 298 } 299 300 /** Cleanup structure initialized via usb_device_retrieve_descriptors. 301 * 302 * @param[in] descriptors Where to store the descriptors. 303 */ 304 void usb_device_release_descriptors(usb_device_descriptors_t *descriptors) 305 { 306 assert(descriptors); 307 free(descriptors->configuration); 308 descriptors->configuration = NULL; 302 309 } 303 310 … … 319 326 * (not NULL terminated). 320 327 * @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). 322 329 * @return Error code. 323 330 */ … … 340 347 const size_t pipe_count = count_other_pipes(endpoints); 341 348 if (pipe_count == 0) { 342 *pipes_count_ptr = pipe_count; 349 if (pipes_count_ptr) 350 *pipes_count_ptr = pipe_count; 343 351 *pipes_ptr = NULL; 344 352 return EOK; … … 346 354 347 355 usb_endpoint_mapping_t *pipes 348 = malloc(sizeof(usb_endpoint_mapping_t) * pipe_count);356 = calloc(pipe_count, sizeof(usb_endpoint_mapping_t)); 349 357 if (pipes == NULL) { 350 358 return ENOMEM; 351 359 } 352 360 353 /* Initialize to NULL to allow smooth rollback. */354 for (i = 0; i < pipe_count; i++) {355 pipes[i].pipe = NULL;356 }357 358 361 /* Now allocate and fully initialize. */ 359 362 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 }365 363 pipes[i].description = endpoints[i]; 366 364 pipes[i].interface_no = interface_no; … … 389 387 for (i = 0; i < pipe_count; i++) { 390 388 if (pipes[i].present) { 391 rc = usb_pipe_register( pipes[i].pipe,389 rc = usb_pipe_register(&pipes[i].pipe, 392 390 pipes[i].descriptor->poll_interval, &hc_conn); 393 391 if (rc != EOK) { … … 398 396 399 397 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__); 402 400 403 401 *pipes_ptr = pipes; … … 417 415 for (i = 0; i < pipe_count; i++) { 418 416 if (pipes[i].present) { 419 usb_pipe_unregister( pipes[i].pipe, &hc_conn);417 usb_pipe_unregister(&pipes[i].pipe, &hc_conn); 420 418 } 421 419 } … … 431 429 */ 432 430 rollback_free_only: 433 for (i = 0; i < pipe_count; i++) {434 if (pipes[i].pipe != NULL) {435 free(pipes[i].pipe);436 }437 }438 431 free(pipes); 439 432 … … 477 470 i, pipes[i].present ? "" : "not "); 478 471 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); 481 473 } 482 474 … … 489 481 return EOK; 490 482 } 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 * @return497 */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 519 483 520 484 /** Initialize new instance of USB device. … … 533 497 assert(ddf_dev != NULL); 534 498 499 *errstr_ptr = NULL; 500 535 501 usb_dev->ddf_dev = ddf_dev; 536 502 usb_dev->driver_data = NULL; 537 503 usb_dev->descriptors.configuration = NULL; 538 usb_dev->alternate_interfaces = NULL;539 504 usb_dev->pipes_count = 0; 540 505 usb_dev->pipes = NULL; 541 506 542 507 /* 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"; 545 521 return rc; 546 522 } … … 553 529 &usb_dev->descriptors); 554 530 if (rc != EOK) { 555 /* Nothing allocated, nothing to free. */556 531 *errstr_ptr = "descriptor retrieval"; 557 532 return rc; 558 533 } 559 534 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); 567 547 if (rc != EOK) { 568 548 /* Full configuration descriptor is allocated. */ 569 free(usb_dev->descriptors.configuration);549 usb_device_release_descriptors(&usb_dev->descriptors); 570 550 /* Alternate interfaces may be allocated */ 571 usb_alternate_interfaces_de stroy(usb_dev->alternate_interfaces);551 usb_alternate_interfaces_deinit(&usb_dev->alternate_interfaces); 572 552 *errstr_ptr = "pipes initialization"; 573 553 return rc; 574 554 } 575 576 *errstr_ptr = NULL;577 555 578 556 return EOK; … … 591 569 destroy_current_pipes(dev); 592 570 593 usb_alternate_interfaces_de stroy(dev->alternate_interfaces);594 free(dev->descriptors.configuration);571 usb_alternate_interfaces_deinit(&dev->alternate_interfaces); 572 usb_device_release_descriptors(&dev->descriptors); 595 573 free(dev->driver_data); 596 574 } -
uspace/lib/usbdev/src/devpoll.c
r27ca3a3 rc2245a3 73 73 74 74 usb_pipe_t *pipe 75 = polling_data->dev->pipes[polling_data->pipe_index].pipe;75 = &polling_data->dev->pipes[polling_data->pipe_index].pipe; 76 76 77 77 if (polling_data->debug > 0) { … … 208 208 return EINVAL; 209 209 } 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)) { 212 212 return EINVAL; 213 213 } 214 214 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, 230 226 request_size, arg); 231 232 free(auto_polling);233 234 return rc;235 227 } 236 228 … … 253 245 */ 254 246 int 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, 256 248 size_t request_size, void *arg) 257 249 { … … 262 254 return EINVAL; 263 255 } 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)) { 266 258 return EINVAL; 267 259 } -
uspace/lib/usbdev/src/dp.c
r27ca3a3 rc2245a3 57 57 58 58 /** Nesting of standard USB descriptors. */ 59 usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[] = {59 const usb_dp_descriptor_nesting_t usb_dp_standard_descriptor_nesting[] = { 60 60 NESTING(CONFIGURATION, INTERFACE), 61 61 NESTING(INTERFACE, ENDPOINT), -
uspace/lib/usbdev/src/hub.c
r27ca3a3 rc2245a3 66 66 * 67 67 * @param connection Opened connection to host controller. 68 * @param preferred Preferred SUB address. 69 * @param strict Fail if the preferred address is not avialable. 68 70 * @param speed Speed of the new device (device that will be assigned 69 71 * the returned address). … … 71 73 */ 72 74 usb_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) 74 76 { 75 77 CHECK_CONNECTION(connection); … … 78 80 79 81 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); 83 84 84 85 async_exchange_end(exch); … … 132 133 } 133 134 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 */ 149 static int usb_request_set_address(usb_pipe_t *pipe, usb_address_t new_address, 150 usb_hc_connection_t *hc_conn) 137 151 { 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; 152 181 } 153 182 … … 171 200 * 172 201 * @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. 174 203 * @param[in] dev_speed New device speed. 175 204 * @param[in] enable_port Function for enabling signaling through the port the … … 177 206 * @param[in] arg Any data argument to @p enable_port. 178 207 * @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. 180 209 * @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. 182 212 * @param[out] new_fun Storage where pointer to allocated child function 183 * will be written. 213 * will be written. Must be non-null. 184 214 * @return Error code. 215 * @retval EINVAL Either connection or new_fun is a NULL pointer. 185 216 * @retval ENOENT Connection to HC not opened. 186 217 * @retval EADDRNOTAVAIL Failed retrieving free address from host controller. … … 195 226 ddf_dev_ops_t *dev_ops, void *new_dev_data, ddf_fun_t **new_fun) 196 227 { 197 assert(connection != NULL); 228 if (new_fun == NULL || connection == NULL) 229 return EINVAL; 230 198 231 // FIXME: this is awful, we are accessing directly the structure. 232 // TODO: Why not use provided connection? 199 233 usb_hc_connection_t hc_conn = { 200 234 .hc_handle = connection->hc_handle, … … 215 249 } 216 250 217 218 251 /* 219 252 * Request new address. 220 253 */ 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); 222 256 if (dev_addr < 0) { 223 257 rc = EADDRNOTAVAIL; … … 240 274 241 275 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); 244 277 if (rc != EOK) { 245 278 rc = ENOTCONN; … … 248 281 249 282 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) { 253 286 /* Do not overheat the CPU ;-). */ 254 287 async_usleep(ENDPOINT_0_0_REGISTER_ATTEMPT_DELAY_USEC); 255 288 } 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 257 301 struct timeval end_time; 258 302 … … 267 311 * above might use much of this time so we should only wait to fill 268 312 * 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); 270 314 if (elapsed < 100000) { 271 315 async_usleep(100000 - elapsed); 272 316 } 273 317 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. */ 278 319 rc = enable_port(arg); 279 320 if (rc != EOK) { … … 287 328 async_usleep(10000); 288 329 330 /* Get max_packet_size value. */ 289 331 rc = usb_pipe_probe_default_control(&ctrl_pipe); 290 332 if (rc != EOK) { … … 293 335 } 294 336 295 rc = usb_request_set_address(&ctrl_pipe, dev_addr );337 rc = usb_request_set_address(&ctrl_pipe, dev_addr, &hc_conn); 296 338 if (rc != EOK) { 297 339 rc = ESTALL; … … 299 341 } 300 342 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. */ 318 348 /* FIXME: create device_register that will get opened ctrl pipe. */ 319 349 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, 321 351 parent, dev_ops, new_dev_data, &child_fun); 322 352 if (rc != EOK) { 323 rc = ESTALL;324 353 goto leave_release_free_address; 325 354 } 326 355 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 = { 331 357 .address = dev_addr, 332 358 .fun = child_fun, 333 359 }; 360 361 362 /* Inform the host controller about the handle. */ 334 363 rc = usb_hc_register_device(&hc_conn, &new_device); 335 364 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); 336 370 rc = EDESTADDRREQ; 337 371 goto leave_release_free_address; 338 372 } 339 373 340 341 /*342 * And we are done.343 */344 374 if (assigned_address != NULL) { 345 375 *assigned_address = dev_addr; 346 376 } 347 if (new_fun != NULL) { 348 *new_fun = child_fun; 349 } 377 378 *new_fun = child_fun; 350 379 351 380 rc = EOK; … … 357 386 */ 358 387 leave_release_default_address: 359 usb_ pipe_unregister(&ctrl_pipe, &hc_conn);388 usb_hc_unregister_device(&hc_conn, USB_ADDRESS_DEFAULT); 360 389 361 390 leave_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__); 363 399 364 400 close_connection: 365 401 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__); 368 404 369 405 return rc; -
uspace/lib/usbdev/src/pipes.c
r27ca3a3 rc2245a3 56 56 async_exch_t *exch = async_exchange_begin(sess); 57 57 58 /*59 * We are sending special value as a handle - zero - to get60 * handle of the parent function (that handle was used61 * when registering our device @p dev.62 */63 58 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); 66 61 67 62 async_exchange_end(exch); … … 80 75 int usb_device_get_assigned_interface(const ddf_dev_t *device) 81 76 { 77 assert(device); 82 78 async_sess_t *parent_sess = 83 79 devman_parent_device_connect(EXCHANGE_ATOMIC, device->handle, -
uspace/lib/usbdev/src/pipesinit.c
r27ca3a3 rc2245a3 192 192 } 193 193 194 if (ep_mapping->pipe == NULL) {195 return EBADMEM;196 }197 194 if (ep_mapping->present) { 198 195 return EEXISTS; 199 196 } 200 197 201 int rc = usb_pipe_initialize( ep_mapping->pipe, wire,198 int rc = usb_pipe_initialize(&ep_mapping->pipe, wire, 202 199 ep_no, description.transfer_type, endpoint->max_packet_size, 203 200 description.direction); … … 254 251 * 255 252 * The mapping array is expected to conform to following rules: 256 * - @c pipe must point to already allocated structure withuninitialized pipe253 * - @c pipe must be uninitialized pipe 257 254 * - @c description must point to prepared endpoint description 258 255 * - @c descriptor does not need to be initialized (will be overwritten) … … 297 294 } 298 295 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++) { 304 298 mapping[i].present = false; 305 299 mapping[i].descriptor = NULL; … … 307 301 } 308 302 309 /* 310 * Prepare the descriptor parser. 311 */ 303 /* Prepare the descriptor parser. */ 312 304 const usb_dp_parser_t dp_parser = { 313 305 .nesting = descriptor_nesting … … 454 446 * @return Error code. 455 447 */ 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, 448 int usb_pipe_register(usb_pipe_t *pipe, unsigned interval, 479 449 usb_hc_connection_t *hc_connection) 480 450 { 481 451 assert(pipe); 482 452 assert(hc_connection); 483 453 484 454 if (!usb_hc_connection_is_opened(hc_connection)) 485 455 return EBADF; 486 456 487 457 const usb_target_t target = 488 458 {{ .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 492 461 async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess); 493 462 int rc = async_req_4_0(exch, DEV_IFACE_ID(USBHC_DEV_IFACE), 494 463 IPC_M_USBHC_REGISTER_ENDPOINT, target.packed, 495 _PACK 3(speed,pipe->transfer_type, pipe->direction),464 _PACK2(pipe->transfer_type, pipe->direction), 496 465 _PACK2(pipe->max_packet_size, interval)); 497 466 async_exchange_end(exch); 498 467 499 468 #undef _PACK2 500 #undef _PACK3501 502 469 return rc; 503 470 } -
uspace/lib/usbdev/src/recognise.c
r27ca3a3 rc2245a3 35 35 #include <sys/types.h> 36 36 #include <fibril_synch.h> 37 #include <usb/debug.h> 38 #include <usb/dev/hub.h> 37 39 #include <usb/dev/pipes.h> 38 40 #include <usb/dev/recognise.h> … … 50 52 51 53 /** DDF operations of child devices. */ 52 ddf_dev_ops_t child_ops = {54 static ddf_dev_ops_t child_ops = { 53 55 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl 54 56 }; … … 64 66 #define BCD_ARGS(a) BCD_INT((a)), BCD_FRAC((a)) 65 67 66 /* FIXME: make this dynamic */67 #define MATCH_STRING_MAX 25668 69 68 /** Add formatted match id. 70 69 * … … 75 74 */ 76 75 static int usb_add_match_id(match_id_list_t *matches, int score, 77 const char * format, ...)76 const char *match_str) 78 77 { 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(); 99 81 if (match_id == NULL) { 100 rc = ENOMEM; 101 goto failure; 82 return ENOMEM; 102 83 } 103 84 … … 107 88 108 89 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;120 90 } 121 91 … … 129 99 #define ADD_MATCHID_OR_RETURN(match_ids, score, format, ...) \ 130 100 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 } \ 133 106 if (__rc != EOK) { \ 107 free(str); \ 134 108 return __rc; \ 135 109 } \ … … 150 124 match_id_list_t *matches) 151 125 { 152 if (desc_interface == NULL) { 153 return EINVAL; 154 } 155 if (matches == NULL) { 126 if (desc_interface == NULL || matches == NULL) { 156 127 return EINVAL; 157 128 } … … 314 285 match_id_list_t *matches) 315 286 { 287 assert(ctrl_pipe); 316 288 int rc; 317 289 /* … … 336 308 /** Probe for device kind and register it in devman. 337 309 * 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. 340 311 * @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. 342 313 * @param[in] dev_data Arbitrary pointer to be stored in the child 343 314 * as @c driver_data. … … 346 317 * @return Error code. 347 318 */ 348 int usb_device_register_child_in_devman(usb_ address_t address,349 d evman_handle_t hc_handle, ddf_dev_t *parent,350 ddf_ dev_ops_t *dev_ops, void *dev_data, ddf_fun_t **child_fun)319 int 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) 351 322 { 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 } 353 330 354 331 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++; 357 333 fibril_mutex_unlock(&device_name_index_mutex); 358 334 359 335 ddf_fun_t *child = NULL; 360 char *child_name = NULL;361 336 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 }379 337 380 338 /* … … 382 340 * naming etc., something more descriptive could be created. 383 341 */ 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); 386 345 if (rc < 0) { 387 346 goto failure; … … 401 360 402 361 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); 405 377 if (rc != EOK) { 406 378 goto failure; … … 412 384 } 413 385 414 if (child_fun != NULL) { 415 *child_fun = child; 416 } 417 386 *child_fun = child; 418 387 return EOK; 419 388 420 389 failure: 421 390 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 } 423 395 /* This takes care of match_id deallocation as well. */ 424 396 ddf_fun_destroy(child); 425 397 } 426 if (child_name != NULL) {427 free(child_name);428 }429 398 430 399 return rc; -
uspace/lib/usbdev/src/request.c
r27ca3a3 rc2245a3 250 250 } 251 251 252 /** Change address of connected device.253 * This function automatically updates the backing connection to point to254 * 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 286 252 /** Retrieve USB descriptor of a USB device. 287 253 * -
uspace/lib/usbhid/include/usb/hid/usages/consumer.h
r27ca3a3 rc2245a3 37 37 #define LIBUSBHID_CONSUMER_H_ 38 38 39 const char *usbhid_multimedia_usage_to_str( intusage);39 const char *usbhid_multimedia_usage_to_str(unsigned usage); 40 40 41 41 #endif /* LIBUSBHID_CONSUMER_H_ */ -
uspace/lib/usbhid/src/consumer.c
r27ca3a3 rc2245a3 38 38 #include <usb/hid/usages/consumer.h> 39 39 40 static const char *usbhid_consumer_usage_str[ 0x29d] = {40 static const char *usbhid_consumer_usage_str[] = { 41 41 [0x01] = "Consumer Control", 42 42 [0x02] = "Numeric Key Pad", … … 358 358 [0x13e] = "Reserved", 359 359 [0x13f] = "Reserved", 360 [0x140] = "Reserved", 360 [0x140] = "Reserved", 361 361 [0x141] = "Reserved", 362 362 [0x142] = "Reserved", … … 717 717 * @retval HelenOS key code corresponding to the given USB Consumer Page Usage. 718 718 */ 719 const char *usbhid_multimedia_usage_to_str( intusage)719 const char *usbhid_multimedia_usage_to_str(unsigned usage) 720 720 { 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 *); 722 723 723 if ( (usage < 0) || ((size_t)usage >= map_length))724 if (usage >= map_length) 724 725 return "Unknown usage"; 725 726 726 /*! @todo What if the usage is not in the table? */727 727 return usbhid_consumer_usage_str[usage]; 728 728 } -
uspace/lib/usbhid/src/hiddescriptor.c
r27ca3a3 rc2245a3 135 135 int usb_hid_report_init(usb_hid_report_t *report) 136 136 { 137 if (report == NULL) {137 if (report == NULL) { 138 138 return EINVAL; 139 139 } … … 144 144 145 145 report->use_report_ids = 0; 146 return EOK; 146 return EOK; 147 147 } 148 148 -
uspace/lib/usbhid/src/hidpath.c
r27ca3a3 rc2245a3 385 385 void usb_hid_report_path_free(usb_hid_report_path_t *path) 386 386 { 387 if (path == NULL) 388 return; 387 389 while(!list_empty(&path->items)){ 388 390 usb_hid_report_remove_last_item(path); -
uspace/lib/usbhid/src/hidreq.c
r27ca3a3 rc2245a3 84 84 usb_log_debug("Sending Set Report request to the device.\n"); 85 85 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, 88 88 USB_HIDREQ_SET_REPORT, value, iface_no, buffer, buf_size); 89 89 90 90 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 " 92 92 "device: %s.\n", str_error(rc)); 93 93 return rc; -
uspace/lib/usbhost/include/usb/host/hcd.h
r27ca3a3 rc2245a3 68 68 * @param bw_count Bandwidth compute function, passed to endpoint manager. 69 69 */ 70 static inline void hcd_init(hcd_t *hcd, size_t bandwidth,70 static inline void hcd_init(hcd_t *hcd, usb_speed_t max_speed, size_t bandwidth, 71 71 size_t (*bw_count)(usb_speed_t, usb_transfer_type_t, size_t, size_t)) 72 72 { 73 73 assert(hcd); 74 usb_device_manager_init(&hcd->dev_manager );74 usb_device_manager_init(&hcd->dev_manager, max_speed); 75 75 usb_endpoint_manager_init(&hcd->ep_manager, bandwidth, bw_count); 76 76 hcd->private_data = NULL; -
uspace/lib/usbhost/include/usb/host/usb_device_manager.h
r27ca3a3 rc2245a3 59 59 devman_handle_t handle; /**< Devman handle of the device. */ 60 60 } devices[USB_ADDRESS_COUNT]; 61 usb_speed_t max_speed; 61 62 fibril_mutex_t guard; 62 63 /** The last reserved address */ … … 64 65 } usb_device_manager_t; 65 66 66 void usb_device_manager_init(usb_device_manager_t *instance); 67 void usb_device_manager_init( 68 usb_device_manager_t *instance, usb_speed_t max_speed); 67 69 68 usb_address_t usb_device_manager_get_free_address( 69 usb_ device_manager_t *instance, usb_speed_t speed);70 int usb_device_manager_request_address(usb_device_manager_t *instance, 71 usb_address_t *address, bool strict, usb_speed_t speed); 70 72 71 int usb_device_manager_bind (usb_device_manager_t *instance,73 int usb_device_manager_bind_address(usb_device_manager_t *instance, 72 74 usb_address_t address, devman_handle_t handle); 73 75 74 int usb_device_manager_release (usb_device_manager_t *instance,76 int usb_device_manager_release_address(usb_device_manager_t *instance, 75 77 usb_address_t address); 76 78 -
uspace/lib/usbhost/include/usb/host/usb_endpoint_manager.h
r27ca3a3 rc2245a3 90 90 usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction, 91 91 void (*callback)(endpoint_t *, void *), void *arg); 92 93 void usb_endpoint_manager_remove_address(usb_endpoint_manager_t *instance, 94 usb_address_t address, void (*callback)(endpoint_t *, void *), void *arg); 92 95 #endif 93 96 /** -
uspace/lib/usbhost/src/iface.c
r27ca3a3 rc2245a3 89 89 } 90 90 /*----------------------------------------------------------------------------*/ 91 /** Request address interface function92 *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 function116 *117 * @param[in] fun DDF function that was called.118 * @param[in] address Address of the device119 * @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 function151 *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 /*----------------------------------------------------------------------------*/166 91 static int register_helper(endpoint_t *ep, void *arg) 167 92 { … … 183 108 } 184 109 /*----------------------------------------------------------------------------*/ 110 static 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 */ 128 static 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 */ 149 static 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 */ 168 static 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 */ 184 static 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 /*----------------------------------------------------------------------------*/ 185 196 static 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, 188 198 usb_transfer_type_t transfer_type, usb_direction_t direction, 189 199 size_t max_packet_size, unsigned int interval) … … 193 203 assert(hcd); 194 204 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( 201 207 &hcd->dev_manager, address, NULL, &speed); 208 if (ret != EOK) { 209 return ret; 210 } 202 211 203 212 usb_log_debug("Register endpoint %d:%d %s-%s %s %zuB %ums.\n", -
uspace/lib/usbhost/src/usb_device_manager.c
r27ca3a3 rc2245a3 38 38 #include <usb/host/usb_device_manager.h> 39 39 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 */ 46 static 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 /*----------------------------------------------------------------------------*/ 40 66 /** Initialize device manager structure. 41 67 * 42 68 * @param[in] instance Memory place to initialize. 69 * @param[in] max_speed Maximum allowed USB speed of devices (inclusive). 43 70 * 44 71 * Set all values to false/0. 45 72 */ 46 void usb_device_manager_init(usb_device_manager_t *instance) 73 void usb_device_manager_init( 74 usb_device_manager_t *instance, usb_speed_t max_speed) 47 75 { 48 76 assert(instance); … … 52 80 instance->devices[i].speed = USB_SPEED_MAX; 53 81 } 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; 58 84 fibril_mutex_initialize(&instance->guard); 59 85 } 60 86 /*----------------------------------------------------------------------------*/ 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 */ 94 int 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) { 80 113 fibril_mutex_unlock(&instance->guard); 81 return ENO SPC;114 return ENOENT; 82 115 } 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; 95 127 } 96 128 /*----------------------------------------------------------------------------*/ … … 102 134 * @return Error code. 103 135 */ 104 int usb_device_manager_bind (usb_device_manager_t *instance,136 int usb_device_manager_bind_address(usb_device_manager_t *instance, 105 137 usb_address_t address, devman_handle_t handle) 106 138 { … … 132 164 * @return Error code. 133 165 */ 134 int usb_device_manager_release (166 int usb_device_manager_release_address( 135 167 usb_device_manager_t *instance, usb_address_t address) 136 168 { 137 if ((address < =0) || (address >= USB_ADDRESS_COUNT)) {169 if ((address < 0) || (address >= USB_ADDRESS_COUNT)) { 138 170 return EINVAL; 139 171 } … … 188 220 { 189 221 assert(instance); 190 if ((address < =0) || (address >= USB_ADDRESS_COUNT)) {222 if ((address < 0) || (address >= USB_ADDRESS_COUNT)) { 191 223 return EINVAL; 192 224 } -
uspace/lib/usbhost/src/usb_endpoint_manager.c
r27ca3a3 rc2245a3 384 384 return EOK; 385 385 } 386 /*----------------------------------------------------------------------------*/ 387 void 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.
