Changeset 3819ce5 in mainline for uspace/lib
- Timestamp:
- 2011-12-25T10:05:28Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ecf823a
- Parents:
- 1440eae (diff), 7e1b130 (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:
-
- 2 added
- 2 deleted
- 31 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/include/device/hw_res.h
r1440eae r3819ce5 40 40 #include <bool.h> 41 41 42 #define DMA_MODE_ON_DEMAND 0 43 #define DMA_MODE_WRITE (1 << 2) 44 #define DMA_MODE_READ (1 << 3) 45 #define DMA_MODE_AUTO (1 << 4) 46 #define DMA_MODE_DOWN (1 << 5) 47 #define DMA_MODE_SINGLE (1 << 6) 48 #define DMA_MODE_BLOCK (1 << 7) 49 42 50 /** HW resource provider interface */ 43 51 typedef enum { 44 52 HW_RES_GET_RESOURCE_LIST = 0, 45 HW_RES_ENABLE_INTERRUPT 53 HW_RES_ENABLE_INTERRUPT, 54 HW_RES_DMA_CHANNEL_SETUP, 46 55 } hw_res_method_t; 47 56 … … 50 59 INTERRUPT, 51 60 IO_RANGE, 52 MEM_RANGE 61 MEM_RANGE, 62 DMA_CHANNEL_8, 63 DMA_CHANNEL_16, 53 64 } hw_res_type_t; 54 65 … … 77 88 int irq; 78 89 } interrupt; 90 91 union { 92 unsigned int dma8; 93 unsigned int dma16; 94 } dma_channel; 79 95 } res; 80 96 } hw_resource_t; … … 98 114 extern bool hw_res_enable_interrupt(async_sess_t *); 99 115 116 extern int hw_res_dma_channel_setup(async_sess_t *, unsigned int, uint32_t, 117 uint16_t, uint8_t); 118 100 119 #endif 101 120 -
uspace/lib/c/include/device/hw_res_parsed.h
r1440eae r3819ce5 72 72 } irq_list_t; 73 73 74 /** List of ISA DMA channels */ 75 typedef struct dma_list { 76 /** Channel count */ 77 size_t count; 78 79 /** Array of channels */ 80 unsigned int *channels; 81 } dma_list_t; 82 74 83 /** List of memory areas */ 75 84 typedef struct addr_range_list { … … 91 100 /** List of IRQs */ 92 101 irq_list_t irqs; 102 103 /** List of DMA channels */ 104 dma_list_t dma_channels; 93 105 94 106 /** List of memory areas */ … … 113 125 free(list->io_ranges.ranges); 114 126 free(list->mem_ranges.ranges); 127 free(list->dma_channels.channels); 115 128 116 129 bzero(list, sizeof(hw_res_list_parsed_t)); -
uspace/lib/drv/include/ops/hw_res.h
r1440eae r3819ce5 1 1 /* 2 * Copyright (c) 2010 Lenka Trochtova 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jan Vesely 3 4 * All rights reserved. 4 5 * … … 42 43 43 44 typedef struct { 44 hw_resource_list_t *(*get_resource_list)(ddf_fun_t *); 45 bool (*enable_interrupt)(ddf_fun_t *); 45 hw_resource_list_t *(*get_resource_list)(ddf_fun_t *); 46 bool (*enable_interrupt)(ddf_fun_t *); 47 int (*dma_channel_setup)(ddf_fun_t *, unsigned, uint32_t, uint16_t, uint8_t); 46 48 } hw_res_ops_t; 47 49 -
uspace/lib/drv/include/usbhc_iface.h
r1440eae r3819ce5 1 1 /* 2 2 * Copyright (c) 2010 Vojtech Horky 3 * Copyright (c) 2011 Jan Vesely 3 4 * All rights reserved. 4 5 * … … 26 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 */ 28 29 29 /** @addtogroup libdrv 30 30 * @addtogroup usb … … 46 46 int usbhc_get_handle(async_exch_t *, usb_address_t, devman_handle_t *); 47 47 int usbhc_release_address(async_exch_t *, usb_address_t); 48 int usbhc_register_endpoint(async_exch_t *, usb_address_t, 48 int usbhc_register_endpoint(async_exch_t *, usb_address_t, usb_endpoint_t, 49 49 usb_transfer_type_t, usb_direction_t, size_t, unsigned int); 50 50 int usbhc_unregister_endpoint(async_exch_t *, usb_address_t, usb_endpoint_t, -
uspace/lib/usb/Makefile
r1440eae r3819ce5 37 37 src/class.c \ 38 38 src/ddfiface.c \ 39 src/dev.c \ 39 40 src/debug.c \ 40 41 src/dump.c \ 41 42 src/hc.c \ 42 src/resolve.c \43 43 src/usb.c 44 44 -
uspace/lib/usb/include/usb/classes/hub.h
r1440eae r3819ce5 84 84 85 85 /** 86 * @brief usb hub descriptor 87 * 88 * For more information see Universal Serial Bus Specification Revision 1.1 chapter 11.16.2 86 * @brief usb hub descriptor 87 * 88 * For more information see Universal Serial Bus Specification Revision 1.1 89 * chapter 11.16.2 89 90 */ 90 91 typedef struct usb_hub_descriptor_type { -
uspace/lib/usb/include/usb/hc.h
r1440eae r3819ce5 1 1 /* 2 2 * Copyright (c) 2011 Vojtech Horky 3 * Copyright (c) 2011 Jan Vesely 3 4 * All rights reserved. 4 5 * … … 26 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 */ 28 29 29 /** @addtogroup libusb 30 30 * @{ 31 31 */ 32 32 /** @file 33 * General communication with host controller driver.33 * General communication with host controller. 34 34 */ 35 35 #ifndef LIBUSB_HC_H_ 36 36 #define LIBUSB_HC_H_ 37 37 38 #include <sys/types.h> 39 #include <ipc/devman.h> 40 #include <ipc/loc.h> 38 #include <async.h> 39 #include <devman.h> 41 40 #include <ddf/driver.h> 42 41 #include <bool.h> 43 #include < async.h>42 #include <fibril_synch.h> 44 43 #include <usb/usb.h> 45 44 46 /** Connection to the host controller driver. */ 45 /** Connection to the host controller driver. 46 * 47 * This is a high level IPC communication wrapper. After the structure has been 48 * initialized using devman handle of an USB host controller, it 49 * will manage all communication to that host controller, including session 50 * creation/destruction and proper IPC protocol. 51 */ 47 52 typedef struct { 48 53 /** Devman handle of the host controller. */ … … 50 55 /** Session to the host controller. */ 51 56 async_sess_t *hc_sess; 57 /** Session guard. */ 58 fibril_mutex_t guard; 59 /** Use counter. */ 60 unsigned ref_count; 52 61 } usb_hc_connection_t; 62 63 /** Initialize connection to USB host controller. 64 * 65 * @param connection Connection to be initialized. 66 * @param hc_handle Devman handle of the host controller. 67 * @return Error code. 68 */ 69 static inline void usb_hc_connection_initialize(usb_hc_connection_t *connection, 70 devman_handle_t hc_handle) 71 { 72 assert(connection); 73 connection->hc_handle = hc_handle; 74 connection->hc_sess = NULL; 75 connection->ref_count = 0; 76 fibril_mutex_initialize(&connection->guard); 77 } 53 78 54 79 int usb_hc_connection_initialize_from_device(usb_hc_connection_t *, 55 80 const ddf_dev_t *); 56 int usb_hc_connection_initialize(usb_hc_connection_t *, devman_handle_t); 81 82 void usb_hc_connection_deinitialize(usb_hc_connection_t *); 57 83 58 84 int usb_hc_connection_open(usb_hc_connection_t *); 59 bool usb_hc_connection_is_opened(const usb_hc_connection_t *);60 85 int usb_hc_connection_close(usb_hc_connection_t *); 86 87 usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_address_t, bool, 88 usb_speed_t); 89 int usb_hc_bind_address(usb_hc_connection_t *, usb_address_t, devman_handle_t); 61 90 int usb_hc_get_handle_by_address(usb_hc_connection_t *, usb_address_t, 62 91 devman_handle_t *); 92 int usb_hc_release_address(usb_hc_connection_t *, usb_address_t); 63 93 64 usb_address_t usb_get_address_by_handle(devman_handle_t); 94 int usb_hc_register_endpoint(usb_hc_connection_t *, usb_address_t, 95 usb_endpoint_t, usb_transfer_type_t, usb_direction_t, size_t, unsigned int); 96 int usb_hc_unregister_endpoint(usb_hc_connection_t *, usb_address_t, 97 usb_endpoint_t, usb_direction_t); 65 98 66 int usb_hc_find(devman_handle_t, devman_handle_t *); 99 int usb_hc_read(usb_hc_connection_t *, usb_address_t, usb_endpoint_t, 100 uint64_t, void *, size_t, size_t *); 101 int usb_hc_write(usb_hc_connection_t *, usb_address_t, usb_endpoint_t, 102 uint64_t, const void *, size_t); 67 103 68 int usb_resolve_device_handle(const char *, devman_handle_t *, usb_address_t *, 69 devman_handle_t *); 70 71 int usb_ddf_get_hc_handle_by_sid(service_id_t, devman_handle_t *); 72 104 /** Get host controller handle by its class index. 105 * 106 * @param sid Service ID of the HC function. 107 * @param hc_handle Where to store the HC handle 108 * (can be NULL for existence test only). 109 * @return Error code. 110 */ 111 static inline int usb_ddf_get_hc_handle_by_sid( 112 service_id_t sid, devman_handle_t *handle) 113 { 114 devman_handle_t h; 115 return devman_fun_sid_to_handle(sid, handle ? handle : &h); 116 } 73 117 74 118 #endif -
uspace/lib/usb/include/usb/usb.h
r1440eae r3819ce5 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 29 28 /** @addtogroup libusb 30 29 * @{ -
uspace/lib/usb/src/ddfiface.c
r1440eae r3819ce5 44 44 #include <assert.h> 45 45 46 #include <usb/dev.h> 47 46 48 /** DDF interface for USB device, implementation for typical hub. */ 47 49 usb_iface_t usb_iface_hub_impl = { … … 66 68 { 67 69 assert(fun); 68 return usb_ hc_find(fun->handle, handle);70 return usb_get_hc_by_handle(fun->handle, handle); 69 71 } 70 72 … … 97 99 { 98 100 assert(fun); 99 100 async_sess_t *parent_sess = 101 devman_parent_device_connect(EXCHANGE_SERIALIZE, fun->handle, 102 IPC_FLAG_BLOCKING); 103 if (!parent_sess) 104 return ENOMEM; 105 106 async_exch_t *exch = async_exchange_begin(parent_sess); 107 if (!exch) { 108 async_hangup(parent_sess); 109 return ENOMEM; 110 } 111 112 const int ret = usb_get_my_address(exch, address); 113 114 async_exchange_end(exch); 115 async_hangup(parent_sess); 116 117 return ret; 101 return usb_get_address_by_handle(fun->handle, address); 118 102 } 119 103 … … 134 118 assert(fun); 135 119 assert(fun->driver_data); 136 usb_hub_attached_device_t *device = fun->driver_data;120 const usb_hub_attached_device_t *device = fun->driver_data; 137 121 assert(device->fun == fun); 138 122 if (address) -
uspace/lib/usb/src/dev.c
r1440eae r3819ce5 1 1 /* 2 * Copyright (c) 2011 Jan Vesely 2 3 * Copyright (c) 2011 Vojtech Horky 3 4 * All rights reserved. … … 27 28 */ 28 29 29 /** @addtogroup libusb 30 * @{ 31 */ 32 /** @file 33 * 34 */ 35 #include <inttypes.h> 30 #include <usb/dev.h> 36 31 #include <usb/hc.h> 37 #include <devman.h>38 32 #include <errno.h> 33 #include <usb_iface.h> 39 34 #include <str.h> 40 35 #include <stdio.h> 41 36 42 37 #define MAX_DEVICE_PATH 1024 38 39 /** Find host controller handle, address and iface number for the device. 40 * 41 * @param[in] device_handle Device devman handle. 42 * @param[out] hc_handle Where to store handle of host controller 43 * controlling device with @p device_handle handle. 44 * @param[out] address Place to store the device's address 45 * @param[out] iface Place to stoer the assigned USB interface number. 46 * @return Error code. 47 */ 48 int usb_get_info_by_handle(devman_handle_t device_handle, 49 devman_handle_t *hc_handle, usb_address_t *address, int *iface) 50 { 51 async_sess_t *parent_sess = 52 devman_parent_device_connect(EXCHANGE_ATOMIC, device_handle, 53 IPC_FLAG_BLOCKING); 54 if (!parent_sess) 55 return ENOMEM; 56 57 async_exch_t *exch = async_exchange_begin(parent_sess); 58 if (!exch) { 59 async_hangup(parent_sess); 60 return ENOMEM; 61 } 62 63 usb_address_t tmp_address; 64 devman_handle_t tmp_handle; 65 int tmp_iface; 66 67 if (address) { 68 const int ret = usb_get_my_address(exch, &tmp_address); 69 if (ret != EOK) { 70 async_exchange_end(exch); 71 async_hangup(parent_sess); 72 return ret; 73 } 74 } 75 76 if (hc_handle) { 77 const int ret = usb_get_hc_handle(exch, &tmp_handle); 78 if (ret != EOK) { 79 async_exchange_end(exch); 80 async_hangup(parent_sess); 81 return ret; 82 } 83 } 84 85 if (iface) { 86 const int ret = usb_get_my_interface(exch, &tmp_iface); 87 switch (ret) { 88 case ENOTSUP: 89 /* Implementing GET_MY_INTERFACE is voluntary. */ 90 tmp_iface = -1; 91 case EOK: 92 break; 93 default: 94 async_exchange_end(exch); 95 async_hangup(parent_sess); 96 return ret; 97 } 98 } 99 100 if (hc_handle) 101 *hc_handle = tmp_handle; 102 103 if (address) 104 *address = tmp_address; 105 106 if (iface) 107 *iface = tmp_iface; 108 109 async_exchange_end(exch); 110 async_hangup(parent_sess); 111 112 return EOK; 113 } 43 114 44 115 static bool try_parse_bus_and_address(const char *path, … … 77 148 devman_handle_t *dev_handle) 78 149 { 79 int rc;80 150 usb_hc_connection_t conn; 81 82 151 usb_hc_connection_initialize(&conn, hc_handle); 83 rc = usb_hc_connection_open(&conn); 84 if (rc != EOK) { 85 return rc; 86 } 87 88 rc = usb_hc_get_handle_by_address(&conn, addr, dev_handle); 89 90 usb_hc_connection_close(&conn); 152 153 const int rc = usb_hc_get_handle_by_address(&conn, addr, dev_handle); 91 154 92 155 return rc; … … 151 214 } 152 215 if (str_length(func_start) > 0) { 153 char tmp_path[MAX_DEVICE_PATH 216 char tmp_path[MAX_DEVICE_PATH]; 154 217 rc = devman_fun_get_path(dev_handle, 155 218 tmp_path, MAX_DEVICE_PATH); … … 192 255 /* Try to find its host controller. */ 193 256 if (!found_hc) { 194 rc = usb_ hc_find(tmp_handle, &hc_handle);257 rc = usb_get_hc_by_handle(tmp_handle, &hc_handle); 195 258 if (rc == EOK) { 196 259 found_hc = true; … … 200 263 /* Try to get its address. */ 201 264 if (!found_addr) { 202 dev_addr = usb_get_address_by_handle(tmp_handle);203 if ( dev_addr >= 0) {265 rc = usb_get_address_by_handle(tmp_handle, &dev_addr); 266 if (rc == 0) { 204 267 found_addr = true; 205 268 } … … 237 300 return EOK; 238 301 } 239 240 241 /**242 * @}243 */244 -
uspace/lib/usb/src/hc.c
r1440eae r3819ce5 1 1 /* 2 2 * Copyright (c) 2011 Vojtech Horky 3 * Copyright (c) 2011 Jan Vesely 3 4 * All rights reserved. 4 5 * … … 26 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 */ 28 29 29 /** @addtogroup libusb 30 30 * @{ … … 33 33 * General communication with host controller driver (implementation). 34 34 */ 35 #include < devman.h>36 #include <async.h> 37 #include < dev_iface.h>38 #include < usb_iface.h>35 #include <usb/debug.h> 36 37 #include <assert.h> 38 #include <errno.h> 39 39 #include <usbhc_iface.h> 40 #include <usb/dev.h> 40 41 #include <usb/hc.h> 41 #include <usb/debug.h> 42 #include <errno.h> 43 #include <assert.h> 42 43 static int usb_hc_connection_add_ref(usb_hc_connection_t *connection) 44 { 45 assert(connection); 46 fibril_mutex_lock(&connection->guard); 47 if (connection->ref_count == 0) { 48 assert(connection->hc_sess == NULL); 49 /* Parallel exchange for us */ 50 connection->hc_sess = devman_device_connect(EXCHANGE_PARALLEL, 51 connection->hc_handle, 0); 52 if (!connection->hc_sess) { 53 fibril_mutex_unlock(&connection->guard); 54 return ENOMEM; 55 } 56 } 57 ++connection->ref_count; 58 fibril_mutex_unlock(&connection->guard); 59 return EOK; 60 } 61 /*----------------------------------------------------------------------------*/ 62 static int usb_hc_connection_del_ref(usb_hc_connection_t *connection) 63 { 64 assert(connection); 65 fibril_mutex_lock(&connection->guard); 66 if (connection->ref_count == 0) { 67 /* Closing already closed connection... */ 68 assert(connection->hc_sess = NULL); 69 fibril_mutex_unlock(&connection->guard); 70 return EOK; 71 } 72 --connection->ref_count; 73 int ret = EOK; 74 if (connection->ref_count == 0) { 75 assert(connection->hc_sess); 76 ret = async_hangup(connection->hc_sess); 77 connection->hc_sess = NULL; 78 } 79 fibril_mutex_unlock(&connection->guard); 80 return ret; 81 } 82 83 #define EXCH_INIT(connection, exch) \ 84 do { \ 85 exch = NULL; \ 86 if (!connection) \ 87 return EBADMEM; \ 88 const int ret = usb_hc_connection_add_ref(connection); \ 89 if (ret != EOK) \ 90 return ret; \ 91 exch = async_exchange_begin(connection->hc_sess); \ 92 if (exch == NULL) { \ 93 usb_hc_connection_del_ref(connection); \ 94 return ENOMEM; \ 95 } \ 96 } while (0) 97 98 #define EXCH_FINI(connection, exch) \ 99 if (exch) { \ 100 async_exchange_end(exch); \ 101 usb_hc_connection_del_ref(connection); \ 102 } else (void)0 44 103 45 104 /** Initialize connection to USB host controller. … … 59 118 60 119 devman_handle_t hc_handle; 61 int rc = usb_hc_find(device->handle, &hc_handle); 62 if (rc != EOK) { 63 return rc; 64 } 65 66 rc = usb_hc_connection_initialize(connection, hc_handle); 120 const int rc = usb_get_hc_by_handle(device->handle, &hc_handle); 121 if (rc == EOK) { 122 usb_hc_connection_initialize(connection, hc_handle); 123 } 67 124 68 125 return rc; 69 126 } 70 71 /** Manually initialize connection to USB host controller. 72 * 73 * @param connection Connection to be initialized. 74 * @param hc_handle Devman handle of the host controller. 75 * @return Error code. 76 */ 77 int usb_hc_connection_initialize(usb_hc_connection_t *connection, 78 devman_handle_t hc_handle) 79 { 80 assert(connection); 81 82 connection->hc_handle = hc_handle; 83 connection->hc_sess = NULL; 84 85 return EOK; 86 } 87 127 /*----------------------------------------------------------------------------*/ 128 void usb_hc_connection_deinitialize(usb_hc_connection_t *connection) 129 { 130 assert(connection); 131 fibril_mutex_lock(&connection->guard); 132 if (connection->ref_count != 0) { 133 usb_log_warning("%u stale reference(s) to HC connection.\n", 134 connection->ref_count); 135 assert(connection->hc_sess); 136 async_hangup(connection->hc_sess); 137 connection->hc_sess = NULL; 138 connection->ref_count = 0; 139 } 140 fibril_mutex_unlock(&connection->guard); 141 } 142 /*----------------------------------------------------------------------------*/ 88 143 /** Open connection to host controller. 89 144 * … … 93 148 int usb_hc_connection_open(usb_hc_connection_t *connection) 94 149 { 95 assert(connection); 96 97 if (usb_hc_connection_is_opened(connection)) 98 return EBUSY; 99 100 async_sess_t *sess = devman_device_connect(EXCHANGE_ATOMIC, 101 connection->hc_handle, 0); 102 if (!sess) 103 return ENOMEM; 104 105 connection->hc_sess = sess; 106 return EOK; 107 } 108 109 /** Tells whether connection to host controller is opened. 150 return usb_hc_connection_add_ref(connection); 151 } 152 /*----------------------------------------------------------------------------*/ 153 /** Close connection to the host controller. 110 154 * 111 155 * @param connection Connection to the host controller. 112 * @return Whether connection is opened.113 */114 bool usb_hc_connection_is_opened(const usb_hc_connection_t *connection)115 {116 assert(connection);117 return (connection->hc_sess != NULL);118 }119 120 /** Close connection to the host controller.121 *122 * @param connection Connection to the host controller.123 156 * @return Error code. 124 157 */ 125 158 int usb_hc_connection_close(usb_hc_connection_t *connection) 126 159 { 127 assert(connection); 128 129 if (!usb_hc_connection_is_opened(connection)) { 130 return ENOENT; 131 } 132 133 int rc = async_hangup(connection->hc_sess); 134 if (rc != EOK) { 135 return rc; 136 } 137 138 connection->hc_sess = NULL; 139 140 return EOK; 141 } 142 160 return usb_hc_connection_del_ref(connection); 161 } 162 /*----------------------------------------------------------------------------*/ 163 /** Ask host controller for free address assignment. 164 * 165 * @param connection Opened connection to host controller. 166 * @param preferred Preferred SUB address. 167 * @param strict Fail if the preferred address is not avialable. 168 * @param speed Speed of the new device (device that will be assigned 169 * the returned address). 170 * @return Assigned USB address or negative error code. 171 */ 172 usb_address_t usb_hc_request_address(usb_hc_connection_t *connection, 173 usb_address_t preferred, bool strict, usb_speed_t speed) 174 { 175 async_exch_t *exch; 176 EXCH_INIT(connection, exch); 177 178 usb_address_t address = preferred; 179 const int ret = usbhc_request_address(exch, &address, strict, speed); 180 181 EXCH_FINI(connection, exch); 182 return ret == EOK ? address : ret; 183 } 184 /*----------------------------------------------------------------------------*/ 185 int usb_hc_bind_address(usb_hc_connection_t * connection, 186 usb_address_t address, devman_handle_t handle) 187 { 188 async_exch_t *exch; 189 EXCH_INIT(connection, exch); 190 191 const int ret = usbhc_bind_address(exch, address, handle); 192 193 EXCH_FINI(connection, exch); 194 return ret; 195 } 196 /*----------------------------------------------------------------------------*/ 143 197 /** Get handle of USB device with given address. 144 198 * … … 151 205 usb_address_t address, devman_handle_t *handle) 152 206 { 153 if (!usb_hc_connection_is_opened(connection)) 154 return ENOENT; 155 156 async_exch_t *exch = async_exchange_begin(connection->hc_sess); 157 if (!exch) 158 return ENOMEM; 207 async_exch_t *exch; 208 EXCH_INIT(connection, exch); 209 159 210 const int ret = usbhc_get_handle(exch, address, handle); 160 async_exchange_end(exch); 161 return ret; 162 } 163 164 /** Tell USB address assigned to device with given handle. 165 * 166 * @param dev_handle Devman handle of the USB device in question. 167 * @return USB address or negative error code. 168 */ 169 usb_address_t usb_get_address_by_handle(devman_handle_t dev_handle) 170 { 171 async_sess_t *parent_sess = 172 devman_parent_device_connect(EXCHANGE_ATOMIC, dev_handle, 173 IPC_FLAG_BLOCKING); 174 if (!parent_sess) 175 return ENOMEM; 176 177 async_exch_t *exch = async_exchange_begin(parent_sess); 178 if (!exch) { 179 async_hangup(parent_sess); 180 return ENOMEM; 181 } 182 usb_address_t address; 183 const int ret = usb_get_my_address(exch, &address); 184 185 async_exchange_end(exch); 186 async_hangup(parent_sess); 187 188 if (ret != EOK) 189 return ret; 190 191 return address; 192 } 193 194 195 /** Get host controller handle by its class index. 196 * 197 * @param sid Service ID of the HC function. 198 * @param hc_handle Where to store the HC handle 199 * (can be NULL for existence test only). 200 * @return Error code. 201 */ 202 int usb_ddf_get_hc_handle_by_sid(service_id_t sid, devman_handle_t *hc_handle) 203 { 204 devman_handle_t handle; 205 int rc; 206 207 rc = devman_fun_sid_to_handle(sid, &handle); 208 if (hc_handle != NULL) 209 *hc_handle = handle; 210 211 return rc; 212 } 213 214 /** Find host controller handle that is ancestor of given device. 215 * 216 * @param[in] device_handle Device devman handle. 217 * @param[out] hc_handle Where to store handle of host controller 218 * controlling device with @p device_handle handle. 219 * @return Error code. 220 */ 221 int usb_hc_find(devman_handle_t device_handle, devman_handle_t *hc_handle) 222 { 223 async_sess_t *parent_sess = 224 devman_parent_device_connect(EXCHANGE_ATOMIC, device_handle, 225 IPC_FLAG_BLOCKING); 226 if (!parent_sess) 227 return ENOMEM; 228 229 async_exch_t *exch = async_exchange_begin(parent_sess); 230 if (!exch) { 231 async_hangup(parent_sess); 232 return ENOMEM; 233 } 234 const int ret = usb_get_hc_handle(exch, hc_handle); 235 236 async_exchange_end(exch); 237 async_hangup(parent_sess); 238 211 212 EXCH_FINI(connection, exch); 213 return ret; 214 } 215 /*----------------------------------------------------------------------------*/ 216 int usb_hc_release_address(usb_hc_connection_t *connection, 217 usb_address_t address) 218 { 219 async_exch_t *exch; 220 EXCH_INIT(connection, exch); 221 222 const int ret = usbhc_release_address(exch, address); 223 224 EXCH_FINI(connection, exch); 225 return ret; 226 } 227 /*----------------------------------------------------------------------------*/ 228 int usb_hc_register_endpoint(usb_hc_connection_t *connection, 229 usb_address_t address, usb_endpoint_t endpoint, usb_transfer_type_t type, 230 usb_direction_t direction, size_t packet_size, unsigned interval) 231 { 232 async_exch_t *exch; 233 EXCH_INIT(connection, exch); 234 235 const int ret = usbhc_register_endpoint(exch, address, endpoint, 236 type, direction, packet_size, interval); 237 238 EXCH_FINI(connection, exch); 239 return ret; 240 } 241 /*----------------------------------------------------------------------------*/ 242 int usb_hc_unregister_endpoint(usb_hc_connection_t *connection, 243 usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction) 244 { 245 async_exch_t *exch; 246 EXCH_INIT(connection, exch); 247 248 const int ret = 249 usbhc_unregister_endpoint(exch, address, endpoint, direction); 250 251 EXCH_FINI(connection, exch); 252 return ret; 253 } 254 /*----------------------------------------------------------------------------*/ 255 int usb_hc_read(usb_hc_connection_t *connection, usb_address_t address, 256 usb_endpoint_t endpoint, uint64_t setup, void *data, size_t size, 257 size_t *real_size) 258 { 259 async_exch_t *exch; 260 EXCH_INIT(connection, exch); 261 262 const int ret = 263 usbhc_read(exch, address, endpoint, setup, data, size, real_size); 264 265 EXCH_FINI(connection, exch); 266 return ret; 267 } 268 /*----------------------------------------------------------------------------*/ 269 int usb_hc_write(usb_hc_connection_t *connection, usb_address_t address, 270 usb_endpoint_t endpoint, uint64_t setup, const void *data, size_t size) 271 { 272 async_exch_t *exch; 273 EXCH_INIT(connection, exch); 274 275 const int ret = usbhc_write(exch, address, endpoint, setup, data, size); 276 277 EXCH_FINI(connection, exch); 239 278 return ret; 240 279 } -
uspace/lib/usb/src/usb.c
r1440eae r3819ce5 39 39 40 40 static const char *str_speed[] = { 41 "low",42 "full",43 "high"41 [USB_SPEED_LOW] = "low", 42 [USB_SPEED_FULL] = "full", 43 [USB_SPEED_HIGH] = "high", 44 44 }; 45 45 46 46 static const char *str_transfer_type[] = { 47 "control",48 "isochronous",49 "bulk",50 "interrupt"47 [USB_TRANSFER_CONTROL] = "control", 48 [USB_TRANSFER_ISOCHRONOUS] = "isochronous", 49 [USB_TRANSFER_BULK] = "bulk", 50 [USB_TRANSFER_INTERRUPT] = "interrupt", 51 51 }; 52 52 53 53 static const char *str_transfer_type_short[] = { 54 "ctrl",55 "iso",56 "bulk",57 "intr"54 [USB_TRANSFER_CONTROL] = "ctrl", 55 [USB_TRANSFER_ISOCHRONOUS] = "iso", 56 [USB_TRANSFER_BULK] = "bulk", 57 [USB_TRANSFER_INTERRUPT] = "intr", 58 58 }; 59 59 60 60 static const char *str_direction[] = { 61 "in",62 "out",63 "both"61 [USB_DIRECTION_IN] = "in", 62 [USB_DIRECTION_OUT] = "out", 63 [USB_DIRECTION_BOTH] = "both", 64 64 }; 65 65 -
uspace/lib/usbdev/Makefile
r1440eae r3819ce5 40 40 src/dp.c \ 41 41 src/hub.c \ 42 src/pipepriv.c \43 src/pipepriv.h \44 42 src/pipes.c \ 45 43 src/pipesinit.c \ 46 src/pipesio.c \47 44 src/recognise.c \ 48 45 src/request.c -
uspace/lib/usbdev/include/usb/dev/driver.h
r1440eae r3819ce5 36 36 #define LIBUSBDEV_DRIVER_H_ 37 37 38 #include <usb/hc.h> 39 #include <usb/dev/usb_device_connection.h> 38 40 #include <usb/dev/pipes.h> 39 41 … … 72 74 /** USB device structure. */ 73 75 typedef struct { 76 /** Connection to USB hc, used by wire and arbitrary requests. */ 77 usb_hc_connection_t hc_conn; 74 78 /** Connection backing the pipes. 75 79 * Typically, you will not need to use this attribute at all. … … 169 173 void usb_device_release_descriptors(usb_device_descriptors_t *); 170 174 171 int usb_device_create_pipes( const ddf_dev_t *,usb_device_connection_t *,175 int usb_device_create_pipes(usb_device_connection_t *, 172 176 const usb_endpoint_description_t **, const uint8_t *, size_t, int, int, 173 177 usb_endpoint_mapping_t **, size_t *); 174 int usb_device_destroy_pipes(const ddf_dev_t *,usb_endpoint_mapping_t *, size_t);178 void usb_device_destroy_pipes(usb_endpoint_mapping_t *, size_t); 175 179 176 180 void * usb_device_data_alloc(usb_device_t *, size_t); -
uspace/lib/usbdev/include/usb/dev/hub.h
r1440eae r3819ce5 40 40 #include <ddf/driver.h> 41 41 #include <sys/types.h> 42 #include <errno.h> 42 43 #include <usb/hc.h> 43 44 … … 59 60 } usb_hub_attached_device_t; 60 61 61 usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_address_t, 62 bool, usb_speed_t); 63 int usb_hc_register_device(usb_hc_connection_t *, 62 int usb_hub_register_device(usb_hc_connection_t *, 64 63 const usb_hub_attached_device_t *); 65 int usb_hc_unregister_device(usb_hc_connection_t *, usb_address_t); 64 65 static inline int usb_hub_unregister_device(usb_hc_connection_t *conn, 66 const usb_hub_attached_device_t *attached_device) 67 { 68 assert(conn); 69 if (attached_device == NULL) 70 return EBADMEM; 71 return usb_hc_release_address(conn, attached_device->address); 72 } 66 73 67 74 #endif -
uspace/lib/usbdev/include/usb/dev/pipes.h
r1440eae r3819ce5 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 29 28 /** @addtogroup libusbdev 30 29 * @{ … … 37 36 38 37 #include <sys/types.h> 39 #include <usb/usb.h>40 #include <usb/hc.h>41 #include <usb/descriptor.h>42 38 #include <ipc/devman.h> 43 39 #include <ddf/driver.h> 44 40 #include <fibril_synch.h> 45 #include <async.h> 41 #include <usb/usb.h> 42 #include <usb/descriptor.h> 43 #include <usb/dev/usb_device_connection.h> 46 44 47 /** Abstraction of a physical connection to the device. 48 * This type is an abstraction of the USB wire that connects the host and 49 * the function (device). 45 #define CTRL_PIPE_MIN_PACKET_SIZE 8 46 /** Abstraction of a logical connection to USB device endpoint. 47 * It encapsulates endpoint attributes (transfer type etc.). 48 * This endpoint must be bound with existing usb_device_connection_t 49 * (i.e. the wire to send data over). 50 50 */ 51 51 typedef struct { 52 /** Handle of the host controller device is connected to. */53 devman_handle_t hc_handle;54 /** Address of the device. */55 usb_address_t address;56 } usb_device_connection_t;57 58 /** Abstraction of a logical connection to USB device endpoint.59 * It encapsulates endpoint attributes (transfer type etc.) as well60 * as information about currently running sessions.61 * This endpoint must be bound with existing usb_device_connection_t62 * (i.e. the wire to send data over).63 *64 * Locking order: if you want to lock both mutexes65 * (@c guard and @c hc_sess_mutex), lock @c guard first.66 * It is not necessary to lock @c guard if you want to lock @c hc_sess_mutex67 * only.68 */69 typedef struct {70 /** Guard of the whole pipe. */71 fibril_mutex_t guard;72 73 52 /** The connection used for sending the data. */ 74 53 usb_device_connection_t *wire; … … 86 65 size_t max_packet_size; 87 66 88 /** Session to the host controller.89 * NULL when no session is active.90 * It is an error to access this member without @c hc_sess_mutex91 * being locked.92 * If call over the phone is to be made, it must be preceeded by93 * call to pipe_add_ref() [internal libusb function].94 */95 async_sess_t *hc_sess;96 97 /** Guard for serialization of requests over the session. */98 fibril_mutex_t hc_sess_mutex;99 100 /** Number of active transfers over the pipe. */101 int refcount;102 /** Number of failed attempts to open the HC phone.103 * When user requests usb_pipe_start_long_transfer() and the operation104 * fails, there is no way to report this to the user.105 * That the soft reference counter is increased to record the attempt.106 * When the user then request e.g. usb_pipe_read(), it will try to107 * add reference as well.108 * If that fails, it is reported to the user. If it is okay, the109 * real reference counter is incremented.110 * The problem might arise when ending the long transfer (since111 * the number of references would be only 1, but logically it shall be112 * two).113 * Decrementing the soft counter first shall solve this.114 */115 int refcount_soft;116 117 67 /** Whether to automatically reset halt on the endpoint. 118 68 * Valid only for control endpoint zero. … … 120 70 bool auto_reset_halt; 121 71 } usb_pipe_t; 122 123 72 124 73 /** Description of endpoint characteristics. */ … … 156 105 } usb_endpoint_mapping_t; 157 106 158 int usb_device_connection_initialize_on_default_address(159 usb_device_connection_t *, usb_hc_connection_t *);160 int usb_device_connection_initialize_from_device(usb_device_connection_t *,161 const ddf_dev_t *);162 int usb_device_connection_initialize(usb_device_connection_t *,163 devman_handle_t, usb_address_t);164 165 int usb_device_get_assigned_interface(const ddf_dev_t *);166 167 107 int usb_pipe_initialize(usb_pipe_t *, usb_device_connection_t *, 168 108 usb_endpoint_t, usb_transfer_type_t, size_t, usb_direction_t); 169 109 int usb_pipe_initialize_default_control(usb_pipe_t *, 170 110 usb_device_connection_t *); 111 171 112 int usb_pipe_probe_default_control(usb_pipe_t *); 172 113 int usb_pipe_initialize_from_configuration(usb_endpoint_mapping_t *, 173 114 size_t, const uint8_t *, size_t, usb_device_connection_t *); 174 int usb_pipe_register(usb_pipe_t *, unsigned int, usb_hc_connection_t *);175 int usb_pipe_unregister(usb_pipe_t *, usb_hc_connection_t *);176 115 177 void usb_pipe_start_long_transfer(usb_pipe_t *); 178 void usb_pipe_end_long_transfer(usb_pipe_t *); 116 int usb_pipe_register(usb_pipe_t *, unsigned); 117 int usb_pipe_unregister(usb_pipe_t *); 118 119 int usb_pipe_start_long_transfer(usb_pipe_t *); 120 int usb_pipe_end_long_transfer(usb_pipe_t *); 179 121 180 122 int usb_pipe_read(usb_pipe_t *, void *, size_t, size_t *); -
uspace/lib/usbdev/include/usb/dev/poll.h
r1440eae r3819ce5 39 39 #include <time.h> 40 40 41 /** Parameters and callbacks for automated polling. */ 41 42 typedef struct { 42 43 /** Level of debugging messages from auto polling. … … 82 83 */ 83 84 bool (*on_error)(usb_device_t *dev, int err_code, void *arg); 85 /** Argument to pass to callbacks. */ 86 void *arg; 84 87 } usb_device_auto_polling_t; 85 88 86 89 int usb_device_auto_polling(usb_device_t *, size_t, 87 const usb_device_auto_polling_t *, size_t , void *);90 const usb_device_auto_polling_t *, size_t); 88 91 89 92 typedef bool (*usb_polling_callback_t)(usb_device_t *, -
uspace/lib/usbdev/include/usb/dev/request.h
r1440eae r3819ce5 83 83 uint8_t request_type; 84 84 #define SETUP_REQUEST_TYPE_DEVICE_TO_HOST (1 << 7) 85 #define SETUP_REQUEST_TYPE_GET_TYPE(rt) ((rt >> 5) & 0x3) 86 #define SETUP_REQUEST_TYPE_GET_RECIPIENT(rec) (rec & 0x1f) 87 #define SETUP_REQUEST_TO_HOST(type, recipient) \ 88 (uint8_t)((1 << 7) | ((type & 0x3) << 5) | (recipient & 0x1f)) 89 #define SETUP_REQUEST_TO_DEVICE(type, recipient) \ 90 (uint8_t)(((type & 0x3) << 5) | (recipient & 0x1f)) 85 91 86 92 /** Request identification. */ -
uspace/lib/usbdev/src/altiface.c
r1440eae r3819ce5 167 167 } 168 168 169 void usb_alternate_interfaces_deinit(usb_alternate_interfaces_t *alternate) 169 /** Clean initialized structure. 170 * @param instance structure do deinitialize. 171 */ 172 void usb_alternate_interfaces_deinit(usb_alternate_interfaces_t *instance) 170 173 { 171 if (! alternate)174 if (!instance) 172 175 return; 173 free(alternate->alternatives); 176 free(instance->alternatives); 177 instance->alternatives = NULL; 174 178 } 175 179 /** -
uspace/lib/usbdev/src/devdrv.c
r1440eae r3819ce5 1 1 /* 2 2 * Copyright (c) 2011 Vojtech Horky 3 * Copyright (c) 2011 Jan Vesely 3 4 * All rights reserved. 4 5 * … … 26 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 */ 28 29 29 /** @addtogroup libusbdev 30 30 * @{ … … 36 36 #include <usb/dev/request.h> 37 37 #include <usb/debug.h> 38 #include <usb/dev /dp.h>38 #include <usb/dev.h> 39 39 #include <errno.h> 40 40 #include <str_error.h> … … 56 56 static const usb_driver_t *driver = NULL; 57 57 58 59 58 /** Main routine of USB device driver. 60 59 * … … 75 74 return ddf_driver_main(&generic_driver); 76 75 } 77 76 /*----------------------------------------------------------------------------*/ 78 77 /** Count number of pipes the driver expects. 79 78 * … … 85 84 { 86 85 size_t count; 87 for (count = 0; endpoints && endpoints[count] != NULL; ++count);86 for (count = 0; endpoints != NULL && endpoints[count] != NULL; ++count); 88 87 return count; 89 }90 91 /** Initialize endpoint pipes, excluding default control one.92 *93 * @param drv The device driver.94 * @param dev Device to be initialized.95 * @return Error code.96 */97 static int initialize_other_pipes(const usb_endpoint_description_t **endpoints,98 usb_device_t *dev, int alternate_setting)99 {100 assert(dev);101 102 if (endpoints == NULL) {103 dev->pipes = NULL;104 dev->pipes_count = 0;105 return EOK;106 }107 108 usb_endpoint_mapping_t *pipes;109 size_t pipes_count;110 111 int rc = usb_device_create_pipes(dev->ddf_dev, &dev->wire, endpoints,112 dev->descriptors.configuration, dev->descriptors.configuration_size,113 dev->interface_no, alternate_setting, &pipes, &pipes_count);114 115 if (rc != EOK) {116 return rc;117 }118 119 dev->pipes = pipes;120 dev->pipes_count = pipes_count;121 122 return EOK;123 88 } 124 89 /*----------------------------------------------------------------------------*/ … … 136 101 assert(driver->ops->device_add); 137 102 103 /* Get place for driver data. */ 138 104 usb_device_t *dev = ddf_dev_data_alloc(gen_dev, sizeof(usb_device_t)); 139 105 if (dev == NULL) { … … 142 108 return ENOMEM; 143 109 } 110 111 /* Initialize generic USB driver data. */ 144 112 const char *err_msg = NULL; 145 113 int rc = usb_device_init(dev, gen_dev, driver->endpoints, &err_msg); … … 150 118 } 151 119 120 /* Start USB driver specific initialization. */ 152 121 rc = driver->ops->device_add(dev); 153 122 if (rc != EOK) … … 169 138 if (driver->ops->device_rem == NULL) 170 139 return ENOTSUP; 171 /* Just tell the driver to stop whatever it is doing, keep structures */ 172 return driver->ops->device_rem(gen_dev->driver_data); 140 /* Just tell the driver to stop whatever it is doing */ 141 usb_device_t *usb_dev = gen_dev->driver_data; 142 const int ret = driver->ops->device_rem(usb_dev); 143 if (ret != EOK) 144 return ret; 145 usb_device_deinit(usb_dev); 146 return EOK; 173 147 } 174 148 /*----------------------------------------------------------------------------*/ … … 197 171 * 198 172 * @param dev Device where to destroy the pipes. 199 * @return Error code. 200 */ 201 static int destroy_current_pipes(usb_device_t *dev) 202 { 203 int rc = usb_device_destroy_pipes(dev->ddf_dev, 204 dev->pipes, dev->pipes_count); 205 if (rc != EOK) { 206 return rc; 207 } 208 173 */ 174 static void destroy_current_pipes(usb_device_t *dev) 175 { 176 usb_device_destroy_pipes(dev->pipes, dev->pipes_count); 209 177 dev->pipes = NULL; 210 178 dev->pipes_count = 0; 211 212 return EOK; 213 } 214 179 } 180 /*----------------------------------------------------------------------------*/ 215 181 /** Change interface setting of a device. 216 182 * This function selects new alternate setting of an interface by issuing … … 242 208 } 243 209 244 int rc;245 246 210 /* Destroy existing pipes. */ 247 rc = destroy_current_pipes(dev); 248 if (rc != EOK) { 249 return rc; 250 } 211 destroy_current_pipes(dev); 251 212 252 213 /* Change the interface itself. */ 253 rc = usb_request_set_interface(&dev->ctrl_pipe, dev->interface_no,214 int rc = usb_request_set_interface(&dev->ctrl_pipe, dev->interface_no, 254 215 alternate_setting); 255 216 if (rc != EOK) { … … 258 219 259 220 /* Create new pipes. */ 260 rc = initialize_other_pipes(endpoints, dev, (int) alternate_setting); 221 rc = usb_device_create_pipes(&dev->wire, endpoints, 222 dev->descriptors.configuration, dev->descriptors.configuration_size, 223 dev->interface_no, (int)alternate_setting, 224 &dev->pipes, &dev->pipes_count); 261 225 262 226 return rc; … … 316 280 * - registers endpoints with the host controller 317 281 * 318 * @param[in] dev Generic DDF device backing the USB one.319 282 * @param[in] wire Initialized backing connection to the host controller. 320 283 * @param[in] endpoints Endpoints description, NULL terminated. … … 329 292 * @return Error code. 330 293 */ 331 int usb_device_create_pipes( const ddf_dev_t *dev,usb_device_connection_t *wire,294 int usb_device_create_pipes(usb_device_connection_t *wire, 332 295 const usb_endpoint_description_t **endpoints, 333 296 const uint8_t *config_descr, size_t config_descr_size, … … 335 298 usb_endpoint_mapping_t **pipes_ptr, size_t *pipes_count_ptr) 336 299 { 337 assert(dev != NULL);338 300 assert(wire != NULL); 339 assert(endpoints != NULL);340 301 assert(config_descr != NULL); 341 302 assert(config_descr_size > 0); … … 359 320 } 360 321 361 /* Now allocate and fullyinitialize. */322 /* Now initialize. */ 362 323 for (i = 0; i < pipe_count; i++) { 363 324 pipes[i].description = endpoints[i]; … … 370 331 config_descr, config_descr_size, wire); 371 332 if (rc != EOK) { 372 goto rollback_free_only; 373 } 374 375 /* Register the endpoints with HC. */ 376 usb_hc_connection_t hc_conn; 377 rc = usb_hc_connection_initialize_from_device(&hc_conn, dev); 378 if (rc != EOK) { 379 goto rollback_free_only; 380 } 381 382 rc = usb_hc_connection_open(&hc_conn); 383 if (rc != EOK) { 384 goto rollback_free_only; 385 } 386 333 free(pipes); 334 return rc; 335 } 336 337 /* Register created pipes. */ 387 338 for (i = 0; i < pipe_count; i++) { 388 339 if (pipes[i].present) { 389 340 rc = usb_pipe_register(&pipes[i].pipe, 390 pipes[i].descriptor->poll_interval , &hc_conn);341 pipes[i].descriptor->poll_interval); 391 342 if (rc != EOK) { 392 343 goto rollback_unregister_endpoints; … … 394 345 } 395 346 } 396 397 if (usb_hc_connection_close(&hc_conn) != EOK)398 usb_log_warning("%s: Failed to close connection.\n",399 __FUNCTION__);400 347 401 348 *pipes_ptr = pipes; … … 415 362 for (i = 0; i < pipe_count; i++) { 416 363 if (pipes[i].present) { 417 usb_pipe_unregister(&pipes[i].pipe , &hc_conn);364 usb_pipe_unregister(&pipes[i].pipe); 418 365 } 419 366 } 420 367 421 if (usb_hc_connection_close(&hc_conn) != EOK)422 usb_log_warning("usb_device_create_pipes(): "423 "Failed to close connection.\n");424 425 /*426 * Jump here if something went wrong before some actual communication427 * with HC. Then the only thing that needs to be done is to free428 * allocated memory.429 */430 rollback_free_only:431 368 free(pipes); 432 433 369 return rc; 434 370 } … … 436 372 /** Destroy pipes previously created by usb_device_create_pipes. 437 373 * 438 * @param[in] dev Generic DDF device backing the USB one.439 374 * @param[in] pipes Endpoint mapping to be destroyed. 440 375 * @param[in] pipes_count Number of endpoints. 441 376 */ 442 int usb_device_destroy_pipes(const ddf_dev_t *dev, 443 usb_endpoint_mapping_t *pipes, size_t pipes_count) 444 { 445 assert(dev != NULL); 446 447 if (pipes_count == 0) { 448 assert(pipes == NULL); 449 return EOK; 450 } 451 assert(pipes != NULL); 452 453 int rc; 454 455 /* Prepare connection to HC to allow endpoint unregistering. */ 456 usb_hc_connection_t hc_conn; 457 rc = usb_hc_connection_initialize_from_device(&hc_conn, dev); 458 if (rc != EOK) { 459 return rc; 460 } 461 rc = usb_hc_connection_open(&hc_conn); 462 if (rc != EOK) { 463 return rc; 464 } 465 377 void usb_device_destroy_pipes(usb_endpoint_mapping_t *pipes, size_t pipes_count) 378 { 466 379 /* Destroy the pipes. */ 467 size_t i;468 for (i = 0; i < pipes_count; i++) {469 usb_log_debug2("Unregistering pipe %zu (%spresent).\n",380 for (size_t i = 0; i < pipes_count; ++i) { 381 assert(pipes); 382 usb_log_debug2("Unregistering pipe %zu: %spresent.\n", 470 383 i, pipes[i].present ? "" : "not "); 471 384 if (pipes[i].present) 472 usb_pipe_unregister(&pipes[i].pipe, &hc_conn); 473 } 474 475 if (usb_hc_connection_close(&hc_conn) != EOK) 476 usb_log_warning("usb_device_destroy_pipes(): " 477 "Failed to close connection.\n"); 478 385 usb_pipe_unregister(&pipes[i].pipe); 386 } 479 387 free(pipes); 480 481 return EOK;482 388 } 483 389 … … 505 411 usb_dev->pipes = NULL; 506 412 413 /* Get assigned params */ 414 devman_handle_t hc_handle; 415 usb_address_t address; 416 417 int rc = usb_get_info_by_handle(ddf_dev->handle, 418 &hc_handle, &address, &usb_dev->interface_no); 419 if (rc != EOK) { 420 *errstr_ptr = "device parameters retrieval"; 421 return rc; 422 } 423 424 /* Initialize hc connection. */ 425 usb_hc_connection_initialize(&usb_dev->hc_conn, hc_handle); 426 507 427 /* Initialize backing wire and control pipe. */ 508 int rc = usb_device_connection_initialize_from_device(509 &usb_dev->wire, ddf_dev);428 rc = usb_device_connection_initialize( 429 &usb_dev->wire, &usb_dev->hc_conn, address); 510 430 if (rc != EOK) { 511 431 *errstr_ptr = "device connection initialization"; … … 515 435 /* This pipe was registered by the hub driver, 516 436 * during device initialization. */ 517 rc = usb_pipe_initialize_default_control( &usb_dev->ctrl_pipe,518 &usb_dev-> wire);437 rc = usb_pipe_initialize_default_control( 438 &usb_dev->ctrl_pipe, &usb_dev->wire); 519 439 if (rc != EOK) { 520 440 *errstr_ptr = "default control pipe initialization"; … … 522 442 } 523 443 524 /* Get our interface. */ 525 usb_dev->interface_no = usb_device_get_assigned_interface(ddf_dev); 444 /* Open hc connection for pipe registration. */ 445 rc = usb_hc_connection_open(&usb_dev->hc_conn); 446 if (rc != EOK) { 447 *errstr_ptr = "hc connection open"; 448 return rc; 449 } 526 450 527 451 /* Retrieve standard descriptors. */ 528 rc = usb_device_retrieve_descriptors( &usb_dev->ctrl_pipe,529 &usb_dev-> descriptors);452 rc = usb_device_retrieve_descriptors( 453 &usb_dev->ctrl_pipe, &usb_dev->descriptors); 530 454 if (rc != EOK) { 531 455 *errstr_ptr = "descriptor retrieval"; 456 usb_hc_connection_close(&usb_dev->hc_conn); 532 457 return rc; 533 458 } … … 543 468 (rc == EOK) ? usb_dev->alternate_interfaces.current : 0; 544 469 545 /* TODO Add comment here. */ 546 rc = initialize_other_pipes(endpoints, usb_dev, alternate_iface); 547 if (rc != EOK) { 470 /* Create and register other pipes than default control (EP 0) */ 471 rc = usb_device_create_pipes(&usb_dev->wire, endpoints, 472 usb_dev->descriptors.configuration, 473 usb_dev->descriptors.configuration_size, 474 usb_dev->interface_no, (int)alternate_iface, 475 &usb_dev->pipes, &usb_dev->pipes_count); 476 if (rc != EOK) { 477 usb_hc_connection_close(&usb_dev->hc_conn); 548 478 /* Full configuration descriptor is allocated. */ 549 479 usb_device_release_descriptors(&usb_dev->descriptors); … … 554 484 } 555 485 486 usb_hc_connection_close(&usb_dev->hc_conn); 556 487 return EOK; 557 488 } … … 566 497 { 567 498 if (dev) { 499 /* Destroy existing pipes. */ 500 destroy_current_pipes(dev); 568 501 /* Ignore errors and hope for the best. */ 569 destroy_current_pipes(dev); 570 502 usb_hc_connection_deinitialize(&dev->hc_conn); 571 503 usb_alternate_interfaces_deinit(&dev->alternate_interfaces); 572 504 usb_device_release_descriptors(&dev->descriptors); 573 505 free(dev->driver_data); 574 } 575 } 576 506 dev->driver_data = NULL; 507 } 508 } 509 510 /** Allocate driver specific data. 511 * @param usb_dev usb_device structure. 512 * @param size requested data size. 513 * @return Pointer to the newly allocated space, NULL on failure. 514 */ 577 515 void * usb_device_data_alloc(usb_device_t *usb_dev, size_t size) 578 516 { -
uspace/lib/usbdev/src/devpoll.c
r1440eae r3819ce5 46 46 /** Data needed for polling. */ 47 47 typedef struct { 48 /** Parameters for automated polling. */ 48 49 usb_device_auto_polling_t auto_polling; 49 50 51 /** USB device to poll. */ 50 52 usb_device_t *dev; 53 /** Device pipe to use for polling. */ 51 54 size_t pipe_index; 55 /** Size of the recieved data. */ 52 56 size_t request_size; 57 /** Data buffer. */ 53 58 uint8_t *buffer; 54 void *custom_arg;55 59 } polling_data_t; 56 60 … … 119 123 ++failed_attempts; 120 124 const bool cont = (params->on_error == NULL) ? true : 121 params->on_error(data->dev, rc, data->custom_arg);125 params->on_error(data->dev, rc, params->arg); 122 126 if (!cont) { 123 127 failed_attempts = params->max_failures; … … 129 133 assert(params->on_data); 130 134 const bool carry_on = params->on_data( 131 data->dev, data->buffer, actual_size, data->custom_arg);135 data->dev, data->buffer, actual_size, params->arg); 132 136 133 137 if (!carry_on) { … … 149 153 150 154 if (params->on_polling_end != NULL) { 151 params->on_polling_end(data->dev, failed, data->custom_arg);155 params->on_polling_end(data->dev, failed, params->arg); 152 156 } 153 157 … … 199 203 .on_polling_end = terminated_callback, 200 204 .on_error = NULL, 205 .arg = arg, 201 206 }; 202 207 203 208 return usb_device_auto_polling(dev, pipe_index, &auto_polling, 204 request_size , arg);209 request_size); 205 210 } 206 211 … … 224 229 int usb_device_auto_polling(usb_device_t *dev, size_t pipe_index, 225 230 const usb_device_auto_polling_t *polling, 226 size_t request_size , void *arg)231 size_t request_size) 227 232 { 228 233 if ((dev == NULL) || (polling == NULL) || (polling->on_data == NULL)) { … … 252 257 polling_data->dev = dev; 253 258 polling_data->pipe_index = pipe_index; 254 polling_data->custom_arg = arg;255 259 256 260 /* Copy provided settings. */ -
uspace/lib/usbdev/src/hub.c
r1440eae r3819ce5 38 38 #include <usb/dev/recognise.h> 39 39 #include <usb/debug.h> 40 #include <usbhc_iface.h>41 40 #include <errno.h> 42 41 #include <assert.h> … … 45 44 #include <async.h> 46 45 47 /** How much time to wait between attempts to register endpoint 0:0.46 /** How much time to wait between attempts to get the default address. 48 47 * The value is based on typical value for port reset + some overhead. 49 48 */ 50 #define ENDPOINT_0_0_REGISTER_ATTEMPT_DELAY_USEC (1000 * (10 + 2)) 51 52 /** Check that HC connection is alright. 53 * 54 * @param conn Connection to be checked. 55 */ 56 #define CHECK_CONNECTION(conn) \ 57 do { \ 58 assert((conn)); \ 59 if (!usb_hc_connection_is_opened((conn))) { \ 60 usb_log_error("Connection not open.\n"); \ 61 return ENOTCONN; \ 62 } \ 63 } while (false) 64 65 /** Ask host controller for free address assignment. 66 * 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. 70 * @param speed Speed of the new device (device that will be assigned 71 * the returned address). 72 * @return Assigned USB address or negative error code. 73 */ 74 usb_address_t usb_hc_request_address(usb_hc_connection_t *connection, 75 usb_address_t preferred, bool strict, usb_speed_t speed) 76 { 77 CHECK_CONNECTION(connection); 78 79 async_exch_t *exch = async_exchange_begin(connection->hc_sess); 80 if (!exch) 81 return (usb_address_t)ENOMEM; 82 83 usb_address_t address = preferred; 84 const int ret = usbhc_request_address(exch, &address, strict, speed); 85 86 async_exchange_end(exch); 87 return ret == EOK ? address : ret; 88 } 49 #define DEFAULT_ADDRESS_ATTEMPT_DELAY_USEC (1000 * (10 + 2)) 89 50 90 51 /** Inform host controller about new device. … … 94 55 * @return Error code. 95 56 */ 96 int usb_h c_register_device(usb_hc_connection_t *connection,57 int usb_hub_register_device(usb_hc_connection_t *connection, 97 58 const usb_hub_attached_device_t *attached_device) 98 59 { 99 CHECK_CONNECTION(connection);60 assert(connection); 100 61 if (attached_device == NULL || attached_device->fun == NULL) 101 return EINVAL; 102 103 async_exch_t *exch = async_exchange_begin(connection->hc_sess); 104 if (!exch) 105 return ENOMEM; 106 const int ret = usbhc_bind_address(exch, 62 return EBADMEM; 63 return usb_hc_bind_address(connection, 107 64 attached_device->address, attached_device->fun->handle); 108 async_exchange_end(exch);109 110 return ret;111 }112 113 /** Inform host controller about device removal.114 *115 * @param connection Opened connection to host controller.116 * @param address Address of the device that is being removed.117 * @return Error code.118 */119 int usb_hc_unregister_device(usb_hc_connection_t *connection,120 usb_address_t address)121 {122 CHECK_CONNECTION(connection);123 124 async_exch_t *exch = async_exchange_begin(connection->hc_sess);125 if (!exch)126 return ENOMEM;127 const int ret = usbhc_release_address(exch, address);128 async_exchange_end(exch);129 130 return ret;131 65 } 132 66 … … 145 79 * @return Error code. 146 80 */ 147 static int usb_request_set_address(usb_pipe_t *pipe, usb_address_t new_address, 148 usb_hc_connection_t *hc_conn) 81 static int usb_request_set_address(usb_pipe_t *pipe, usb_address_t new_address) 149 82 { 150 83 if ((new_address < 0) || (new_address >= USB11_ADDRESS_MAX)) { … … 152 85 } 153 86 assert(pipe); 154 assert(hc_conn);155 87 assert(pipe->wire != NULL); 156 88 … … 166 98 167 99 /* TODO: prevent others from accessing the wire now. */ 168 if (usb_pipe_unregister(pipe , hc_conn) != EOK) {100 if (usb_pipe_unregister(pipe) != EOK) { 169 101 usb_log_warning( 170 102 "Failed to unregister the old pipe on address change.\n"); 171 103 } 104 /* Address changed. We can release the old one, thus 105 * allowing other to us it. */ 106 usb_hc_release_address(pipe->wire->hc_connection, pipe->wire->address); 107 172 108 /* The address is already changed so set it in the wire */ 173 109 pipe->wire->address = new_address; 174 rc = usb_pipe_register(pipe, 0 , hc_conn);110 rc = usb_pipe_register(pipe, 0); 175 111 if (rc != EOK) 176 112 return EADDRNOTAVAIL; … … 220 156 */ 221 157 int usb_hc_new_device_wrapper(ddf_dev_t *parent, 222 usb_hc_connection_t * connection, usb_speed_t dev_speed,158 usb_hc_connection_t *hc_conn, usb_speed_t dev_speed, 223 159 int (*enable_port)(void *arg), void *arg, usb_address_t *assigned_address, 224 160 ddf_dev_ops_t *dev_ops, void *new_dev_data, ddf_fun_t **new_fun) 225 161 { 226 if (new_fun == NULL || connection == NULL)162 if (new_fun == NULL || hc_conn == NULL) 227 163 return EINVAL; 228 229 // TODO: Why not use provided connection?230 usb_hc_connection_t hc_conn;231 usb_hc_connection_initialize(&hc_conn, connection->hc_handle);232 164 233 165 int rc; … … 239 171 } 240 172 241 rc = usb_hc_connection_open(&hc_conn); 173 /* We are gona do a lot of communication better open it in advance. */ 174 rc = usb_hc_connection_open(hc_conn); 242 175 if (rc != EOK) { 243 176 return rc; 244 177 } 245 178 246 /* 247 * Request new address. 248 */ 179 /* Request a new address. */ 249 180 usb_address_t dev_addr = 250 usb_hc_request_address( &hc_conn, 0, false, dev_speed);181 usb_hc_request_address(hc_conn, 0, false, dev_speed); 251 182 if (dev_addr < 0) { 252 183 rc = EADDRNOTAVAIL; … … 254 185 } 255 186 187 /* Initialize connection to device. */ 188 usb_device_connection_t dev_conn; 189 rc = usb_device_connection_initialize( 190 &dev_conn, hc_conn, USB_ADDRESS_DEFAULT); 191 if (rc != EOK) { 192 rc = ENOTCONN; 193 goto leave_release_free_address; 194 } 195 196 /* Initialize control pipe on default address. Don't register yet. */ 197 usb_pipe_t ctrl_pipe; 198 rc = usb_pipe_initialize_default_control(&ctrl_pipe, &dev_conn); 199 if (rc != EOK) { 200 rc = ENOTCONN; 201 goto leave_release_free_address; 202 } 203 256 204 /* 257 * We will not register control pipe on default address.258 * Th e registration might fail. That means that someone else already259 * registered that endpoint.We will simply wait and try again.205 * The default address request might fail. 206 * That means that someone else is already using that address. 207 * We will simply wait and try again. 260 208 * (Someone else already wants to add a new device.) 261 209 */ 262 usb_device_connection_t dev_conn;263 rc = usb_device_connection_initialize_on_default_address(&dev_conn,264 &hc_conn);265 if (rc != EOK) {266 rc = ENOTCONN;267 goto leave_release_free_address;268 }269 270 usb_pipe_t ctrl_pipe;271 rc = usb_pipe_initialize_default_control(&ctrl_pipe, &dev_conn);272 if (rc != EOK) {273 rc = ENOTCONN;274 goto leave_release_free_address;275 }276 277 210 do { 278 rc = usb_hc_request_address( &hc_conn, USB_ADDRESS_DEFAULT,211 rc = usb_hc_request_address(hc_conn, USB_ADDRESS_DEFAULT, 279 212 true, dev_speed); 280 213 if (rc == ENOENT) { 281 214 /* Do not overheat the CPU ;-). */ 282 async_usleep( ENDPOINT_0_0_REGISTER_ATTEMPT_DELAY_USEC);215 async_usleep(DEFAULT_ADDRESS_ATTEMPT_DELAY_USEC); 283 216 } 284 217 } while (rc == ENOENT); … … 287 220 } 288 221 289 /* Register control pipe on default address. */290 rc = usb_pipe_register(&ctrl_pipe, 0 , &hc_conn);222 /* Register control pipe on default address. 0 means no interval. */ 223 rc = usb_pipe_register(&ctrl_pipe, 0); 291 224 if (rc != EOK) { 292 225 rc = ENOTCONN; … … 295 228 296 229 struct timeval end_time; 297 298 230 rc = gettimeofday(&end_time, NULL); 299 231 if (rc != EOK) { … … 330 262 } 331 263 332 rc = usb_request_set_address(&ctrl_pipe, dev_addr , &hc_conn);264 rc = usb_request_set_address(&ctrl_pipe, dev_addr); 333 265 if (rc != EOK) { 334 266 rc = ESTALL; … … 336 268 } 337 269 338 /* Address changed. We can release the default, thus339 * allowing other to access the default address. */340 usb_hc_unregister_device(&hc_conn, USB_ADDRESS_DEFAULT);341 270 342 271 /* Register the device with devman. */ … … 356 285 357 286 /* Inform the host controller about the handle. */ 358 rc = usb_h c_register_device(&hc_conn, &new_device);287 rc = usb_hub_register_device(hc_conn, &new_device); 359 288 if (rc != EOK) { 360 289 /* We know nothing about that data. */ … … 381 310 */ 382 311 leave_release_default_address: 383 usb_hc_unregister_device(&hc_conn, USB_ADDRESS_DEFAULT); 312 if (usb_hc_release_address(hc_conn, USB_ADDRESS_DEFAULT) != EOK) 313 usb_log_warning("%s: Failed to release defaut address.\n", 314 __FUNCTION__); 384 315 385 316 leave_release_free_address: 386 317 /* This might be either 0:0 or dev_addr:0 */ 387 if (usb_pipe_unregister(&ctrl_pipe , &hc_conn) != EOK)318 if (usb_pipe_unregister(&ctrl_pipe) != EOK) 388 319 usb_log_warning("%s: Failed to unregister default pipe.\n", 389 320 __FUNCTION__); 390 321 391 if (usb_hc_ unregister_device(&hc_conn, dev_addr) != EOK)392 usb_log_warning("%s: Failed to unregister device.\n",393 __FUNCTION__ );322 if (usb_hc_release_address(hc_conn, dev_addr) != EOK) 323 usb_log_warning("%s: Failed to release address: %d.\n", 324 __FUNCTION__, dev_addr); 394 325 395 326 close_connection: 396 if (usb_hc_connection_close( &hc_conn) != EOK)327 if (usb_hc_connection_close(hc_conn) != EOK) 397 328 usb_log_warning("%s: Failed to close hc connection.\n", 398 329 __FUNCTION__); -
uspace/lib/usbdev/src/pipes.c
r1440eae r3819ce5 1 1 /* 2 2 * Copyright (c) 2011 Vojtech Horky 3 * Copyright (c) 2011 Jan Vesely 3 4 * All rights reserved. 4 5 * … … 26 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 */ 28 29 29 /** @addtogroup libusbdev 30 30 * @{ 31 31 */ 32 32 /** @file 33 * USB endpoint pipes miscellaneous functions. 34 */ 35 #include <usb/usb.h> 33 * USB endpoint pipes functions. 34 */ 36 35 #include <usb/dev/pipes.h> 37 #include <usb/debug.h> 38 #include <usb/hc.h> 39 #include <usbhc_iface.h> 40 #include <usb_iface.h> 41 #include <devman.h> 36 #include <usb/dev/request.h> 42 37 #include <errno.h> 43 38 #include <assert.h> 44 #include "pipepriv.h" 45 46 #define IPC_AGAIN_DELAY (1000 * 2) /* 2ms */ 47 48 /** Tell USB address assigned to given device. 49 * 50 * @param sess Session to parent device. 51 * @param dev Device in question. 52 * @return USB address or error code. 53 */ 54 static usb_address_t get_my_address(async_sess_t *sess, const ddf_dev_t *dev) 55 { 56 assert(sess); 57 async_exch_t *exch = async_exchange_begin(sess); 58 if (!exch) 59 return ENOMEM; 60 61 usb_address_t address; 62 const int ret = usb_get_my_address(exch, &address); 63 64 async_exchange_end(exch); 65 66 return (ret == EOK) ? address : ret; 67 } 68 69 /** Tell USB interface assigned to given device. 70 * 71 * @param device Device in question. 72 * @return Error code (ENOTSUP means any). 73 */ 74 int usb_device_get_assigned_interface(const ddf_dev_t *device) 75 { 76 assert(device); 77 async_sess_t *parent_sess = 78 devman_parent_device_connect(EXCHANGE_ATOMIC, device->handle, 79 IPC_FLAG_BLOCKING); 80 if (!parent_sess) 81 return ENOMEM; 82 83 async_exch_t *exch = async_exchange_begin(parent_sess); 84 if (!exch) { 85 async_hangup(parent_sess); 86 return ENOMEM; 87 } 88 89 int iface_no; 90 const int ret = usb_get_my_interface(exch, &iface_no); 91 92 return ret == EOK ? iface_no : ret; 93 } 94 95 /** Initialize connection to USB device. 96 * 97 * @param connection Connection structure to be initialized. 98 * @param dev Generic device backing the USB device. 99 * @return Error code. 100 */ 101 int usb_device_connection_initialize_from_device( 102 usb_device_connection_t *connection, const ddf_dev_t *dev) 103 { 39 40 /** Prepare pipe for a long transfer. 41 * 42 * Long transfer is transfer consisting of several requests to the HC. 43 * Calling this function is optional and it has positive effect of 44 * improved performance because IPC session is initiated only once. 45 * 46 * @param pipe Pipe over which the transfer will happen. 47 * @return Error code. 48 */ 49 int usb_pipe_start_long_transfer(usb_pipe_t *pipe) 50 { 51 assert(pipe); 52 assert(pipe->wire); 53 assert(pipe->wire->hc_connection); 54 return usb_hc_connection_open(pipe->wire->hc_connection); 55 } 56 /*----------------------------------------------------------------------------*/ 57 /** Terminate a long transfer on a pipe. 58 * @param pipe Pipe where to end the long transfer. 59 * @return Error code. 60 * @see usb_pipe_start_long_transfer 61 */ 62 int usb_pipe_end_long_transfer(usb_pipe_t *pipe) 63 { 64 assert(pipe); 65 assert(pipe->wire); 66 assert(pipe->wire->hc_connection); 67 return usb_hc_connection_close(pipe->wire->hc_connection); 68 } 69 /*----------------------------------------------------------------------------*/ 70 /** Try to clear endpoint halt of default control pipe. 71 * 72 * @param pipe Pipe for control endpoint zero. 73 */ 74 static void clear_self_endpoint_halt(usb_pipe_t *pipe) 75 { 76 assert(pipe != NULL); 77 78 if (!pipe->auto_reset_halt || (pipe->endpoint_no != 0)) { 79 return; 80 } 81 82 /* Prevent infinite recursion. */ 83 pipe->auto_reset_halt = false; 84 usb_request_clear_endpoint_halt(pipe, 0); 85 pipe->auto_reset_halt = true; 86 } 87 /*----------------------------------------------------------------------------*/ 88 /** Request a control read transfer on an endpoint pipe. 89 * 90 * This function encapsulates all three stages of a control transfer. 91 * 92 * @param[in] pipe Pipe used for the transfer. 93 * @param[in] setup_buffer Buffer with the setup packet. 94 * @param[in] setup_buffer_size Size of the setup packet (in bytes). 95 * @param[out] data_buffer Buffer for incoming data. 96 * @param[in] data_buffer_size Size of the buffer for incoming data (in bytes). 97 * @param[out] data_transfered_size Number of bytes that were actually 98 * transfered during the DATA stage. 99 * @return Error code. 100 */ 101 int usb_pipe_control_read(usb_pipe_t *pipe, 102 const void *setup_buffer, size_t setup_buffer_size, 103 void *buffer, size_t buffer_size, size_t *transfered_size) 104 { 105 assert(pipe); 106 107 if ((setup_buffer == NULL) || (setup_buffer_size != 8)) { 108 return EINVAL; 109 } 110 111 if ((buffer == NULL) || (buffer_size == 0)) { 112 return EINVAL; 113 } 114 115 if ((pipe->direction != USB_DIRECTION_BOTH) 116 || (pipe->transfer_type != USB_TRANSFER_CONTROL)) { 117 return EBADF; 118 } 119 120 uint64_t setup_packet; 121 memcpy(&setup_packet, setup_buffer, 8); 122 123 size_t act_size = 0; 124 const int rc = usb_device_control_read(pipe->wire, 125 pipe->endpoint_no, setup_packet, buffer, buffer_size, &act_size); 126 127 if (rc == ESTALL) { 128 clear_self_endpoint_halt(pipe); 129 } 130 131 if (rc == EOK && transfered_size != NULL) { 132 *transfered_size = act_size; 133 } 134 135 return rc; 136 } 137 /*----------------------------------------------------------------------------*/ 138 /** Request a control write transfer on an endpoint pipe. 139 * 140 * This function encapsulates all three stages of a control transfer. 141 * 142 * @param[in] pipe Pipe used for the transfer. 143 * @param[in] setup_buffer Buffer with the setup packet. 144 * @param[in] setup_buffer_size Size of the setup packet (in bytes). 145 * @param[in] data_buffer Buffer with data to be sent. 146 * @param[in] data_buffer_size Size of the buffer with outgoing data (in bytes). 147 * @return Error code. 148 */ 149 int usb_pipe_control_write(usb_pipe_t *pipe, 150 const void *setup_buffer, size_t setup_buffer_size, 151 const void *buffer, size_t buffer_size) 152 { 153 assert(pipe); 154 155 if ((setup_buffer == NULL) || (setup_buffer_size != 8)) { 156 return EINVAL; 157 } 158 159 if ((buffer == NULL) && (buffer_size > 0)) { 160 return EINVAL; 161 } 162 163 if ((buffer != NULL) && (buffer_size == 0)) { 164 return EINVAL; 165 } 166 167 if ((pipe->direction != USB_DIRECTION_BOTH) 168 || (pipe->transfer_type != USB_TRANSFER_CONTROL)) { 169 return EBADF; 170 } 171 172 uint64_t setup_packet; 173 memcpy(&setup_packet, setup_buffer, 8); 174 175 const int rc = usb_device_control_write(pipe->wire, 176 pipe->endpoint_no, setup_packet, buffer, buffer_size); 177 178 if (rc == ESTALL) { 179 clear_self_endpoint_halt(pipe); 180 } 181 182 return rc; 183 } 184 /*----------------------------------------------------------------------------*/ 185 /** Request a read (in) transfer on an endpoint pipe. 186 * 187 * @param[in] pipe Pipe used for the transfer. 188 * @param[out] buffer Buffer where to store the data. 189 * @param[in] size Size of the buffer (in bytes). 190 * @param[out] size_transfered Number of bytes that were actually transfered. 191 * @return Error code. 192 */ 193 int usb_pipe_read(usb_pipe_t *pipe, 194 void *buffer, size_t size, size_t *size_transfered) 195 { 196 assert(pipe); 197 198 if (buffer == NULL) { 199 return EINVAL; 200 } 201 202 if (size == 0) { 203 return EINVAL; 204 } 205 206 if (pipe->direction != USB_DIRECTION_IN) { 207 return EBADF; 208 } 209 210 if (pipe->transfer_type == USB_TRANSFER_CONTROL) { 211 return EBADF; 212 } 213 214 /* Isochronous transfer are not supported (yet) */ 215 if (pipe->transfer_type != USB_TRANSFER_INTERRUPT && 216 pipe->transfer_type != USB_TRANSFER_BULK) 217 return ENOTSUP; 218 219 size_t act_size = 0; 220 const int rc = usb_device_read(pipe->wire, 221 pipe->endpoint_no, buffer, size, &act_size); 222 223 if (rc == EOK && size_transfered != NULL) { 224 *size_transfered = act_size; 225 } 226 227 return rc; 228 } 229 /*----------------------------------------------------------------------------*/ 230 /** Request a write (out) transfer on an endpoint pipe. 231 * 232 * @param[in] pipe Pipe used for the transfer. 233 * @param[in] buffer Buffer with data to transfer. 234 * @param[in] size Size of the buffer (in bytes). 235 * @return Error code. 236 */ 237 int usb_pipe_write(usb_pipe_t *pipe, const void *buffer, size_t size) 238 { 239 assert(pipe); 240 241 if (buffer == NULL || size == 0) { 242 return EINVAL; 243 } 244 245 if (pipe->direction != USB_DIRECTION_OUT) { 246 return EBADF; 247 } 248 249 if (pipe->transfer_type == USB_TRANSFER_CONTROL) { 250 return EBADF; 251 } 252 253 /* Isochronous transfer are not supported (yet) */ 254 if (pipe->transfer_type != USB_TRANSFER_INTERRUPT && 255 pipe->transfer_type != USB_TRANSFER_BULK) 256 return ENOTSUP; 257 258 return usb_device_write(pipe->wire, 259 pipe->endpoint_no, buffer, size); 260 } 261 /*----------------------------------------------------------------------------*/ 262 /** Initialize USB endpoint pipe. 263 * 264 * @param pipe Endpoint pipe to be initialized. 265 * @param connection Connection to the USB device backing this pipe (the wire). 266 * @param endpoint_no Endpoint number (in USB 1.1 in range 0 to 15). 267 * @param transfer_type Transfer type (e.g. interrupt or bulk). 268 * @param max_packet_size Maximum packet size in bytes. 269 * @param direction Endpoint direction (in/out). 270 * @return Error code. 271 */ 272 int usb_pipe_initialize(usb_pipe_t *pipe, 273 usb_device_connection_t *connection, usb_endpoint_t endpoint_no, 274 usb_transfer_type_t transfer_type, size_t max_packet_size, 275 usb_direction_t direction) 276 { 277 assert(pipe); 104 278 assert(connection); 105 assert(dev); 106 107 int rc; 108 devman_handle_t hc_handle; 109 usb_address_t my_address; 110 111 rc = usb_hc_find(dev->handle, &hc_handle); 112 if (rc != EOK) 113 return rc; 114 115 async_sess_t *parent_sess = 116 devman_parent_device_connect(EXCHANGE_ATOMIC, dev->handle, 117 IPC_FLAG_BLOCKING); 118 if (!parent_sess) 119 return ENOMEM; 120 121 /* 122 * Asking for "my" address may require several attempts. 123 * That is because following scenario may happen: 124 * - parent driver (i.e. driver of parent device) announces new device 125 * and devman launches current driver 126 * - parent driver is preempted and thus does not send address-handle 127 * binding to HC driver 128 * - this driver gets here and wants the binding 129 * - the HC does not know the binding yet and thus it answers ENOENT 130 * So, we need to wait for the HC to learn the binding. 131 */ 132 133 do { 134 my_address = get_my_address(parent_sess, dev); 135 136 if (my_address == ENOENT) { 137 /* Be nice, let other fibrils run and try again. */ 138 async_usleep(IPC_AGAIN_DELAY); 139 } else if (my_address < 0) { 140 /* Some other problem, no sense trying again. */ 141 rc = my_address; 142 goto leave; 143 } 144 145 } while (my_address < 0); 146 147 rc = usb_device_connection_initialize(connection, 148 hc_handle, my_address); 149 150 leave: 151 async_hangup(parent_sess); 279 280 pipe->wire = connection; 281 pipe->endpoint_no = endpoint_no; 282 pipe->transfer_type = transfer_type; 283 pipe->max_packet_size = max_packet_size; 284 pipe->direction = direction; 285 pipe->auto_reset_halt = false; 286 287 return EOK; 288 } 289 /*----------------------------------------------------------------------------*/ 290 /** Initialize USB endpoint pipe as the default zero control pipe. 291 * 292 * @param pipe Endpoint pipe to be initialized. 293 * @param connection Connection to the USB device backing this pipe (the wire). 294 * @return Error code. 295 */ 296 int usb_pipe_initialize_default_control(usb_pipe_t *pipe, 297 usb_device_connection_t *connection) 298 { 299 assert(pipe); 300 assert(connection); 301 302 int rc = usb_pipe_initialize(pipe, connection, 0, USB_TRANSFER_CONTROL, 303 CTRL_PIPE_MIN_PACKET_SIZE, USB_DIRECTION_BOTH); 304 305 pipe->auto_reset_halt = true; 306 152 307 return rc; 153 308 } 154 155 /** Initialize connection to USB device. 156 * 157 * @param connection Connection structure to be initialized. 158 * @param host_controller_handle Devman handle of host controller device is 159 * connected to. 160 * @param device_address Device USB address. 161 * @return Error code. 162 */ 163 int usb_device_connection_initialize(usb_device_connection_t *connection, 164 devman_handle_t host_controller_handle, usb_address_t device_address) 165 { 166 assert(connection); 167 168 if ((device_address < 0) || (device_address >= USB11_ADDRESS_MAX)) { 169 return EINVAL; 170 } 171 172 connection->hc_handle = host_controller_handle; 173 connection->address = device_address; 174 175 return EOK; 176 } 177 178 /** Initialize connection to USB device on default address. 179 * 180 * @param dev_connection Device connection structure to be initialized. 181 * @param hc_connection Initialized connection to host controller. 182 * @return Error code. 183 */ 184 int usb_device_connection_initialize_on_default_address( 185 usb_device_connection_t *dev_connection, 186 usb_hc_connection_t *hc_connection) 187 { 188 assert(dev_connection); 189 190 if (hc_connection == NULL) { 191 return EBADMEM; 192 } 193 194 return usb_device_connection_initialize(dev_connection, 195 hc_connection->hc_handle, (usb_address_t) 0); 196 } 197 198 /** Prepare pipe for a long transfer. 199 * 200 * By a long transfer is mean transfer consisting of several 201 * requests to the HC. 202 * Calling such function is optional and it has positive effect of 203 * improved performance because IPC session is initiated only once. 204 * 205 * @param pipe Pipe over which the transfer will happen. 206 * @return Error code. 207 */ 208 void usb_pipe_start_long_transfer(usb_pipe_t *pipe) 209 { 210 (void) pipe_add_ref(pipe, true); 211 } 212 213 /** Terminate a long transfer on a pipe. 214 * 215 * @see usb_pipe_start_long_transfer 216 * 217 * @param pipe Pipe where to end the long transfer. 218 */ 219 void usb_pipe_end_long_transfer(usb_pipe_t *pipe) 220 { 221 pipe_drop_ref(pipe); 309 /*----------------------------------------------------------------------------*/ 310 /** Register endpoint with the host controller. 311 * 312 * @param pipe Pipe to be registered. 313 * @param interval Polling interval. 314 * @return Error code. 315 */ 316 int usb_pipe_register(usb_pipe_t *pipe, unsigned interval) 317 { 318 assert(pipe); 319 assert(pipe->wire); 320 321 return usb_device_register_endpoint(pipe->wire, 322 pipe->endpoint_no, pipe->transfer_type, 323 pipe->direction, pipe->max_packet_size, interval); 324 } 325 /*----------------------------------------------------------------------------*/ 326 /** Revert endpoint registration with the host controller. 327 * 328 * @param pipe Pipe to be unregistered. 329 * @return Error code. 330 */ 331 int usb_pipe_unregister(usb_pipe_t *pipe) 332 { 333 assert(pipe); 334 assert(pipe->wire); 335 336 return usb_device_unregister_endpoint(pipe->wire, 337 pipe->endpoint_no, pipe->direction); 222 338 } 223 339 -
uspace/lib/usbdev/src/pipesinit.c
r1440eae r3819ce5 31 31 */ 32 32 /** @file 33 * Initialization of endpoint pipes.33 * Non trivial initialization of endpoint pipes. 34 34 * 35 35 */ … … 38 38 #include <usb/dev/dp.h> 39 39 #include <usb/dev/request.h> 40 #include <usbhc_iface.h>41 40 #include <errno.h> 42 41 #include <assert.h> 43 42 44 #define CTRL_PIPE_MIN_PACKET_SIZE 845 43 #define DEV_DESCR_MAX_PACKET_SIZE_OFFSET 7 46 47 44 48 45 #define NESTING(parentname, childname) \ … … 327 324 328 325 return EOK; 329 }330 331 /** Initialize USB endpoint pipe.332 *333 * @param pipe Endpoint pipe to be initialized.334 * @param connection Connection to the USB device backing this pipe (the wire).335 * @param endpoint_no Endpoint number (in USB 1.1 in range 0 to 15).336 * @param transfer_type Transfer type (e.g. interrupt or bulk).337 * @param max_packet_size Maximum packet size in bytes.338 * @param direction Endpoint direction (in/out).339 * @return Error code.340 */341 int usb_pipe_initialize(usb_pipe_t *pipe,342 usb_device_connection_t *connection, usb_endpoint_t endpoint_no,343 usb_transfer_type_t transfer_type, size_t max_packet_size,344 usb_direction_t direction)345 {346 assert(pipe);347 assert(connection);348 349 fibril_mutex_initialize(&pipe->guard);350 pipe->wire = connection;351 pipe->hc_sess = NULL;352 fibril_mutex_initialize(&pipe->hc_sess_mutex);353 pipe->endpoint_no = endpoint_no;354 pipe->transfer_type = transfer_type;355 pipe->max_packet_size = max_packet_size;356 pipe->direction = direction;357 pipe->refcount = 0;358 pipe->refcount_soft = 0;359 pipe->auto_reset_halt = false;360 361 return EOK;362 }363 364 365 /** Initialize USB endpoint pipe as the default zero control pipe.366 *367 * @param pipe Endpoint pipe to be initialized.368 * @param connection Connection to the USB device backing this pipe (the wire).369 * @return Error code.370 */371 int usb_pipe_initialize_default_control(usb_pipe_t *pipe,372 usb_device_connection_t *connection)373 {374 assert(pipe);375 assert(connection);376 377 int rc = usb_pipe_initialize(pipe, connection,378 0, USB_TRANSFER_CONTROL, CTRL_PIPE_MIN_PACKET_SIZE,379 USB_DIRECTION_BOTH);380 381 pipe->auto_reset_halt = true;382 383 return rc;384 326 } 385 327 … … 435 377 } 436 378 437 /** Register endpoint with the host controller.438 *439 * @param pipe Pipe to be registered.440 * @param interval Polling interval.441 * @param hc_connection Connection to the host controller (must be opened).442 * @return Error code.443 */444 int usb_pipe_register(usb_pipe_t *pipe, unsigned interval,445 usb_hc_connection_t *hc_connection)446 {447 assert(pipe);448 assert(pipe->wire);449 assert(hc_connection);450 451 if (!usb_hc_connection_is_opened(hc_connection))452 return EBADF;453 async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess);454 if (!exch)455 return ENOMEM;456 const int ret = usbhc_register_endpoint(exch,457 pipe->wire->address, pipe->endpoint_no, pipe->transfer_type,458 pipe->direction, pipe->max_packet_size, interval);459 460 async_exchange_end(exch);461 return ret;462 }463 464 /** Revert endpoint registration with the host controller.465 *466 * @param pipe Pipe to be unregistered.467 * @param hc_connection Connection to the host controller (must be opened).468 * @return Error code.469 */470 int usb_pipe_unregister(usb_pipe_t *pipe,471 usb_hc_connection_t *hc_connection)472 {473 assert(pipe);474 assert(pipe->wire);475 assert(hc_connection);476 477 if (!usb_hc_connection_is_opened(hc_connection))478 return EBADF;479 480 async_exch_t *exch = async_exchange_begin(hc_connection->hc_sess);481 if (!exch)482 return ENOMEM;483 const int ret = usbhc_unregister_endpoint(exch,484 pipe->wire->address, pipe->endpoint_no, pipe->direction);485 async_exchange_end(exch);486 487 return ret;488 }489 490 379 /** 491 380 * @} -
uspace/lib/usbdev/src/recognise.c
r1440eae r3819ce5 45 45 #include <errno.h> 46 46 #include <assert.h> 47 48 /** Index to append after device name for uniqueness. */49 static size_t device_name_index = 0;50 /** Mutex guard for device_name_index. */51 static FIBRIL_MUTEX_INITIALIZE(device_name_index_mutex);52 47 53 48 /** DDF operations of child devices. */ … … 329 324 } 330 325 331 fibril_mutex_lock(&device_name_index_mutex); 332 const size_t this_device_name_index = device_name_index++; 333 fibril_mutex_unlock(&device_name_index_mutex); 326 /** Index to append after device name for uniqueness. */ 327 static atomic_t device_name_index = {0}; 328 const size_t this_device_name_index = 329 (size_t) atomic_preinc(&device_name_index); 334 330 335 331 ddf_fun_t *child = NULL; -
uspace/lib/usbhost/include/usb/host/endpoint.h
r1440eae r3819ce5 95 95 /** list_get_instance wrapper. 96 96 * @param item Pointer to link member. 97 * @return Pointer to en point_t structure.97 * @return Pointer to endpoint_t structure. 98 98 */ 99 99 static inline endpoint_t * endpoint_get_instance(link_t *item) 100 100 { 101 return list_get_instance(item, endpoint_t, link);101 return item ? list_get_instance(item, endpoint_t, link) : NULL; 102 102 } 103 103 #endif -
uspace/lib/usbhost/include/usb/host/usb_device_manager.h
r1440eae r3819ce5 59 59 devman_handle_t handle; /**< Devman handle of the device. */ 60 60 } devices[USB_ADDRESS_COUNT]; 61 /** Maximum speed allowed. */ 61 62 usb_speed_t max_speed; 63 /** Protect access to members. */ 62 64 fibril_mutex_t guard; 63 65 /** The last reserved address */ -
uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h
r1440eae r3819ce5 65 65 */ 66 66 size_t setup_size; 67 /** Actually used portion of the buffer */68 size_t transfered_size;69 /** Indicates success/failure of the communication */70 int error;71 67 /** Host controller function, passed to callback function */ 72 68 ddf_fun_t *fun; 69 70 /** Actually used portion of the buffer 71 * This member is never accessed by functions provided in this header, 72 * with the exception of usb_transfer_batch_finish. For external use. 73 */ 74 size_t transfered_size; 75 /** Indicates success/failure of the communication 76 * This member is never accessed by functions provided in this header, 77 * with the exception of usb_transfer_batch_finish. For external use. 78 */ 79 int error; 73 80 74 81 /** Driver specific data */ … … 106 113 void usb_transfer_batch_destroy(const usb_transfer_batch_t *instance); 107 114 108 void usb_transfer_batch_finish (const usb_transfer_batch_t *instance,109 const void* data, size_t size );115 void usb_transfer_batch_finish_error(const usb_transfer_batch_t *instance, 116 const void* data, size_t size, int error); 110 117 /*----------------------------------------------------------------------------*/ 111 /** Override error value and finishes transfer.118 /** Finish batch using stored error value and transferred size. 112 119 * 113 120 * @param[in] instance Batch structure to use. 114 121 * @param[in] data Data to copy to the output buffer. 115 * @param[in] size Size of @p data.116 * @param[in] error Set batch status to this error value.117 122 */ 118 static inline void usb_transfer_batch_finish _error(119 usb_transfer_batch_t *instance, const void* data, size_t size, int error)123 static inline void usb_transfer_batch_finish( 124 const usb_transfer_batch_t *instance, const void* data) 120 125 { 121 126 assert(instance); 122 instance->error = error;123 usb_transfer_batch_finish(instance, data, size);127 usb_transfer_batch_finish_error( 128 instance, data, instance->transfered_size, instance->error); 124 129 } 125 130 /*----------------------------------------------------------------------------*/ -
uspace/lib/usbhost/src/iface.c
r1440eae r3819ce5 39 39 #include <usb/host/hcd.h> 40 40 41 /** Prepare generic usb_transfer_batch and schedule it. 42 * @param fun DDF fun 43 * @param target address and endpoint number. 44 * @param setup_data Data to use in setup stage (Control communication type) 45 * @param in Callback for device to host communication. 46 * @param out Callback for host to device communication. 47 * @param arg Callback parameter. 48 * @param name Communication identifier (for nicer output). 49 * @return Error code. 50 */ 41 51 static inline int send_batch( 42 52 ddf_fun_t *fun, usb_target_t target, usb_direction_t direction, … … 89 99 } 90 100 /*----------------------------------------------------------------------------*/ 101 /** Calls ep_add_hook upon endpoint registration. 102 * @param ep Endpoint to be registered. 103 * @param arg hcd_t in disguise. 104 * @return Error code. 105 */ 91 106 static int register_helper(endpoint_t *ep, void *arg) 92 107 { … … 99 114 } 100 115 /*----------------------------------------------------------------------------*/ 116 /** Calls ep_remove_hook upon endpoint removal. 117 * @param ep Endpoint to be unregistered. 118 * @param arg hcd_t in disguise. 119 */ 101 120 static void unregister_helper(endpoint_t *ep, void *arg) 102 121 { … … 108 127 } 109 128 /*----------------------------------------------------------------------------*/ 129 /** Calls ep_remove_hook upon endpoint removal. Prints warning. 130 * @param ep Endpoint to be unregistered. 131 * @param arg hcd_t in disguise. 132 */ 110 133 static void unregister_helper_warn(endpoint_t *ep, void *arg) 111 134 { … … 119 142 } 120 143 /*----------------------------------------------------------------------------*/ 121 /** Request address interface function 144 /** Request address interface function. 122 145 * 123 146 * @param[in] fun DDF function that was called. 147 * @param[in] address Pointer to preferred USB address. 148 * @param[out] address Place to write a new address. 149 * @param[in] strict Fail if the preferred address is not available. 124 150 * @param[in] speed Speed to associate with the new default address. 125 * @param[out] address Place to write a new address.126 151 * @return Error code. 127 152 */ … … 140 165 } 141 166 /*----------------------------------------------------------------------------*/ 142 /** Bind address interface function 167 /** Bind address interface function. 143 168 * 144 169 * @param[in] fun DDF function that was called. … … 148 173 */ 149 174 static int bind_address( 150 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle)175 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle) 151 176 { 152 177 assert(fun); … … 176 201 } 177 202 /*----------------------------------------------------------------------------*/ 178 /** Release address interface function 203 /** Release address interface function. 179 204 * 180 205 * @param[in] fun DDF function that was called. … … 194 219 } 195 220 /*----------------------------------------------------------------------------*/ 221 /** Register endpoint interface function. 222 * @param fun DDF function. 223 * @param address USB address of the device. 224 * @param endpoint USB endpoint number to be registered. 225 * @param transfer_type Endpoint's transfer type. 226 * @param direction USB communication direction the endpoint is capable of. 227 * @param max_packet_size Maximu size of packets the endpoint accepts. 228 * @param interval Preferred timeout between communication. 229 * @return Error code. 230 */ 196 231 static int register_endpoint( 197 232 ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint, 198 233 usb_transfer_type_t transfer_type, usb_direction_t direction, 199 size_t max_packet_size, unsigned int interval)234 size_t max_packet_size, unsigned interval) 200 235 { 201 236 assert(fun); … … 220 255 } 221 256 /*----------------------------------------------------------------------------*/ 257 /** Unregister endpoint interface function. 258 * @param fun DDF function. 259 * @param address USB address of the endpoint. 260 * @param endpoint USB endpoint number. 261 * @param direction Communication direction of the enpdoint to unregister. 262 * @return Error code. 263 */ 222 264 static int unregister_endpoint( 223 265 ddf_fun_t *fun, usb_address_t address, … … 233 275 } 234 276 /*----------------------------------------------------------------------------*/ 277 /** Inbound communication interface function. 278 * @param fun DDF function. 279 * @param target Communication target. 280 * @param setup_data Data to use in setup stage (control transfers). 281 * @param data Pointer to data buffer. 282 * @param size Size of the data buffer. 283 * @param callback Function to call on communication end. 284 * @param arg Argument passed to the callback function. 285 * @return Error code. 286 */ 235 287 static int usb_read(ddf_fun_t *fun, usb_target_t target, uint64_t setup_data, 236 288 uint8_t *data, size_t size, usbhc_iface_transfer_in_callback_t callback, … … 241 293 } 242 294 /*----------------------------------------------------------------------------*/ 295 /** Outbound communication interface function. 296 * @param fun DDF function. 297 * @param target Communication target. 298 * @param setup_data Data to use in setup stage (control transfers). 299 * @param data Pointer to data buffer. 300 * @param size Size of the data buffer. 301 * @param callback Function to call on communication end. 302 * @param arg Argument passed to the callback function. 303 * @return Error code. 304 */ 243 305 static int usb_write(ddf_fun_t *fun, usb_target_t target, uint64_t setup_data, 244 306 const uint8_t *data, size_t size, … … 249 311 } 250 312 /*----------------------------------------------------------------------------*/ 313 /** usbhc Interface implementation using hcd_t from libusbhost library. */ 251 314 usbhc_iface_t hcd_iface = { 252 315 .request_address = request_address, -
uspace/lib/usbhost/src/usb_device_manager.c
r1440eae r3819ce5 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 29 28 /** @addtogroup libusbhost 30 29 * @{ … … 41 40 * 42 41 * @param[in] instance Device manager structure to use. 43 * @param[in] speed Speed of the device requiring address.44 42 * @return Free address, or error code. 45 43 */ … … 133 131 * @param[in] handle Devman handle of the device. 134 132 * @return Error code. 133 * @note Won't accept binding for default address. 135 134 */ 136 135 int usb_device_manager_bind_address(usb_device_manager_t *instance, … … 184 183 } 185 184 /*----------------------------------------------------------------------------*/ 186 /** Find USB address associated with the device 185 /** Find USB address associated with the device. 187 186 * 188 187 * @param[in] instance Device manager structure to use. … … 208 207 /*----------------------------------------------------------------------------*/ 209 208 /** Find devman handle and speed assigned to USB address. 210 * Intentionally refuse to work on default address.211 209 * 212 210 * @param[in] instance Device manager structure to use. -
uspace/lib/usbhost/src/usb_endpoint_manager.c
r1440eae r3819ce5 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup libusbhost 29 * @{ 30 */ 31 /** @file 32 * HC Endpoint management. 33 */ 28 34 29 35 #include <bool.h> … … 56 62 } 57 63 /*----------------------------------------------------------------------------*/ 58 /** Get list that holds endp ints for given address.64 /** Get list that holds endpoints for given address. 59 65 * @param instance usb_endpoint_manager structure, non-null. 60 66 * @param addr USB address, must be >= 0. … … 75 81 * @return Pointer to endpoint_t structure representing given communication 76 82 * target, NULL if there is no such endpoint registered. 83 * @note Assumes that the internal mutex is locked. 77 84 */ 78 85 static endpoint_t * find_locked(usb_endpoint_manager_t *instance, … … 169 176 * 170 177 * Really ugly one. Resets toggle bit on all endpoints that need it. 178 * @TODO Use tools from libusbdev requests.h 171 179 */ 172 180 void usb_endpoint_manager_reset_eps_if_need(usb_endpoint_manager_t *instance, … … 184 192 case 0x01: /* Clear Feature -- resets only cleared ep */ 185 193 /* Recipient is endpoint, value is zero (ENDPOINT_STALL) */ 194 // TODO Use macros in libusbdev requests.h 186 195 if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) { 187 196 fibril_mutex_lock(&instance->guard); … … 202 211 /* Recipient must be device, this resets all endpoints, 203 212 * In fact there should be no endpoints but EP 0 registered 204 * as different interfaces use different endpoints. */ 213 * as different interfaces use different endpoints, 214 * unless you're changing configuration or alternative 215 * interface of an already setup device. */ 205 216 if ((data[0] & 0xf) == 0) { 206 217 fibril_mutex_lock(&instance->guard); … … 385 396 } 386 397 /*----------------------------------------------------------------------------*/ 398 /** Unregister and destroy all endpoints using given address. 399 * @param instance usb_endpoint_manager structure, non-null. 400 * @param address USB address. 401 * @param endpoint USB endpoint number. 402 * @param direction Communication direction. 403 * @param callback Function to call after unregister, before destruction. 404 * @arg Argument to pass to the callback function. 405 * @return Error code. 406 */ 387 407 void usb_endpoint_manager_remove_address(usb_endpoint_manager_t *instance, 388 408 usb_address_t address, void (*callback)(endpoint_t *, void *), void *arg) … … 403 423 fibril_mutex_unlock(&instance->guard); 404 424 } 425 /** 426 * @} 427 */ -
uspace/lib/usbhost/src/usb_transfer_batch.c
r1440eae r3819ce5 33 33 */ 34 34 #include <errno.h> 35 #include < str_error.h>35 #include <macros.h> 36 36 37 37 #include <usb/usb.h> … … 48 48 * @param func_in callback on IN transfer completion. 49 49 * @param func_out callback on OUT transfer completion. 50 * @param fun DDF function (passed to callback function). 50 51 * @param arg Argument to pass to the callback function. 51 52 * @param private_data driver specific per batch data. … … 121 122 * @param[in] data Data to copy to the output buffer. 122 123 * @param[in] size Size of @p data. 124 * @param[in] error Error value to use. 123 125 */ 124 void usb_transfer_batch_finish (125 const usb_transfer_batch_t *instance, const void *data, size_t size)126 void usb_transfer_batch_finish_error(const usb_transfer_batch_t *instance, 127 const void *data, size_t size, int error) 126 128 { 127 129 assert(instance); … … 133 135 /* Check for commands that reset toggle bit */ 134 136 if (instance->ep->transfer_type == USB_TRANSFER_CONTROL 135 && instance->error == EOK) {137 && error == EOK) { 136 138 const usb_target_t target = 137 139 {{ instance->ep->address, instance->ep->endpoint }}; … … 139 141 instance->setup_buffer); 140 142 } 141 instance->callback_out(instance->fun, 142 instance->error, instance->arg); 143 instance->callback_out(instance->fun, error, instance->arg); 143 144 } 144 145 145 146 if (instance->callback_in) { 146 147 /* We care about the data and there are some to copy */ 148 const size_t safe_size = min(size, instance->buffer_size); 147 149 if (data) { 148 const size_t min_size = size < instance->buffer_size 149 ? size : instance->buffer_size; 150 memcpy(instance->buffer, data, min_size); 150 memcpy(instance->buffer, data, safe_size); 151 151 } 152 instance->callback_in(instance->fun, instance->error,153 instance->transfered_size, instance->arg);152 instance->callback_in(instance->fun, error, 153 safe_size, instance->arg); 154 154 } 155 155 }
Note:
See TracChangeset
for help on using the changeset viewer.