Changeset 1102eca in mainline
- Timestamp:
- 2018-01-08T17:17:38Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- bdd8842c
- Parents:
- eb928c4
- Location:
- uspace/lib/usbhost/src
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/bandwidth.c
reb928c4 r1102eca 42 42 #include "bandwidth.h" 43 43 44 /** Calculate bandwidth that needs to be reserved for communication with EP. 44 /** 45 * Calculate bandwidth that needs to be reserved for communication with EP. 45 46 * Calculation follows USB 1.1 specification. 46 47 * @param ep Registered endpoint … … 95 96 } 96 97 97 /** Calculate bandwidth that needs to be reserved for communication with EP. 98 /** 99 * Calculate bandwidth that needs to be reserved for communication with EP. 98 100 * Calculation follows USB 2.0 specification, chapter 5.11.3. 99 101 * -
uspace/lib/usbhost/src/bus.c
reb928c4 r1102eca 32 32 /** @file 33 33 * 34 * The Bus is a structure that serves as an interface of the HC driver 35 * implementation for the usbhost library. Every HC driver that uses libusbhost 36 * must use a bus_t (or its child), fill it with bus_ops and present it to the 37 * library. The library then handles the DDF interface and translates it to the 38 * bus callbacks. 34 39 */ 35 40 … … 44 49 45 50 /** 46 * Initializes the b us structure.51 * Initializes the base bus structure. 47 52 */ 48 53 void bus_init(bus_t *bus, size_t device_size) … … 57 62 } 58 63 64 /** 65 * Initialize the device_t structure belonging to a bus. 66 */ 59 67 int bus_device_init(device_t *dev, bus_t *bus) 60 68 { … … 72 80 } 73 81 82 /** 83 * Create a name of the ddf function node. 84 */ 74 85 int bus_device_set_default_name(device_t *dev) 75 86 { … … 84 95 } 85 96 97 /** 98 * Invoke the device_enumerate bus operation. 99 */ 86 100 int bus_device_enumerate(device_t *dev) 87 101 { … … 95 109 } 96 110 111 /** 112 * Invoke the device_remove bus operation. 113 */ 97 114 int bus_device_remove(device_t *dev) 98 115 { … … 106 123 } 107 124 125 /** 126 * Invoke the device_online bus operation. 127 */ 108 128 int bus_device_online(device_t *dev) 109 129 { … … 117 137 } 118 138 139 /** 140 * Invoke the device_offline bus operation. 141 */ 119 142 int bus_device_offline(device_t *dev) 120 143 { … … 128 151 } 129 152 153 /** 154 * Create and register new endpoint to the bus. 155 * 156 * @param[in] device The device of which the endpoint shall be created 157 * @param[in] desc Endpoint descriptors as reported by the device 158 * @param[out] out_ep The resulting new endpoint reference, if any. Can be NULL. 159 */ 130 160 int bus_endpoint_add(device_t *device, const usb_endpoint_descriptors_t *desc, endpoint_t **out_ep) 131 161 { … … 135 165 bus_t *bus = device->bus; 136 166 167 const bus_ops_t *register_ops = BUS_OPS_LOOKUP(bus->ops, endpoint_register); 168 if (!register_ops) 169 return ENOTSUP; 170 137 171 const bus_ops_t *create_ops = BUS_OPS_LOOKUP(bus->ops, endpoint_create); 138 const bus_ops_t *register_ops = BUS_OPS_LOOKUP(bus->ops, endpoint_register); 139 if (!create_ops || !register_ops) 140 return ENOTSUP; 141 142 endpoint_t *ep = create_ops->endpoint_create(device, desc); 143 if (!ep) 144 return ENOMEM; 172 endpoint_t *ep; 173 if (create_ops) { 174 ep = create_ops->endpoint_create(device, desc); 175 if (!ep) 176 return ENOMEM; 177 } else { 178 ep = calloc(1, sizeof(endpoint_t)); 179 if (!ep) 180 return ENOMEM; 181 endpoint_init(ep, device, desc); 182 } 145 183 146 184 /* Bus reference */ … … 186 224 } 187 225 188 /** Searches for an endpoint. Returns a reference. 226 /** 227 * Search for an endpoint. Returns a reference. 189 228 */ 190 229 endpoint_t *bus_find_endpoint(device_t *device, usb_endpoint_t endpoint) … … 204 243 } 205 244 245 /** 246 * Remove an endpoint from the device. Consumes a reference. 247 */ 206 248 int bus_endpoint_remove(endpoint_t *ep) 207 249 { … … 233 275 endpoint_del_ref(ep); 234 276 277 /* Given reference */ 278 endpoint_del_ref(ep); 279 235 280 return EOK; 236 281 } 237 282 283 /** 284 * Reserve the default address on the bus. Also, report the speed of the device 285 * that is listening on the default address. 286 * 287 * The speed is then used for devices enumerated while the address is reserved. 288 */ 238 289 int bus_reserve_default_address(bus_t *bus, usb_speed_t speed) 239 290 { … … 251 302 } 252 303 304 /** 305 * Release the default address. 306 */ 253 307 void bus_release_default_address(bus_t *bus) 254 308 { … … 257 311 } 258 312 259 /** Prepare generic usb_transfer_batch and schedule it. 313 /** 314 * Initiate a transfer on the bus. Finds the target endpoint, creates 315 * a transfer batch and schedules it. 316 * 260 317 * @param device Device for which to send the batch 261 * @param target address and endpoint number. 262 * @param setup_data Data to use in setup stage (Control communication type) 263 * @param in Callback for device to host communication. 264 * @param out Callback for host to device communication. 318 * @param target The target of the transfer. 319 * @param direction A direction of the transfer. 320 * @param data A pointer to the data buffer. 321 * @param size Size of the data buffer. 322 * @param setup_data Data to use in the setup stage (Control communication type) 323 * @param on_complete Callback which is called after the batch is complete 265 324 * @param arg Callback parameter. 266 325 * @param name Communication identifier (for nicer output). … … 301 360 } sync_data_t; 302 361 362 /** 363 * Callback for finishing the transfer. Wake the issuing thread. 364 */ 303 365 static int sync_transfer_complete(void *arg, int error, size_t transfered_size) 304 366 { … … 314 376 } 315 377 378 /** 379 * Issue a transfer on the bus, wait for result. 380 * 381 * @param device Device for which to send the batch 382 * @param target The target of the transfer. 383 * @param direction A direction of the transfer. 384 * @param data A pointer to the data buffer. 385 * @param size Size of the data buffer. 386 * @param setup_data Data to use in the setup stage (Control communication type) 387 * @param name Communication identifier (for nicer output). 388 */ 316 389 ssize_t bus_device_send_batch_sync(device_t *device, usb_target_t target, 317 390 usb_direction_t direction, char *data, size_t size, uint64_t setup_data, … … 330 403 fibril_mutex_lock(&sd.done_mtx); 331 404 while (!sd.done) { 332 fibril_condvar_wait_timeout(&sd.done_cv, &sd.done_mtx, 3000000); 333 if (!sd.done) 334 usb_log_debug2("Still waiting..."); 405 fibril_condvar_wait(&sd.done_cv, &sd.done_mtx); 335 406 } 336 407 fibril_mutex_unlock(&sd.done_mtx); -
uspace/lib/usbhost/src/ddf_helpers.c
reb928c4 r1102eca 31 31 */ 32 32 /** @file 33 * 33 * Helpers to work with the DDF interface. 34 34 */ 35 35 … … 59 59 60 60 61 /* DDF INTERFACE */ 62 63 /** Register endpoint interface function. 64 * @param fun DDF function. 65 * @param endpoint_desc Endpoint description. 61 /** 62 * DDF usbhc_iface callback. Passes the endpoint descriptors, fills the pipe 63 * descriptor according to the contents of the endpoint. 64 * 65 * @param[in] fun DDF function of the device in question. 66 * @param[out] pipe_desc The pipe descriptor to be filled. 67 * @param[in] endpoint_desc Endpoint descriptors from the device. 66 68 * @return Error code. 67 69 */ … … 92 94 } 93 95 94 /** Unregister endpoint interface function. 95 * @param fun DDF function. 96 * @param endpoint_desc Endpoint description. 96 /** 97 * DDF usbhc_iface callback. Unregister endpoint that makes the other end of 98 * the pipe described. 99 * 100 * @param fun DDF function of the device in question. 101 * @param pipe_desc Pipe description. 97 102 * @return Error code. 98 103 */ 99 static int unregister_endpoint(ddf_fun_t *fun, const usb_pipe_desc_t * endpoint_desc)104 static int unregister_endpoint(ddf_fun_t *fun, const usb_pipe_desc_t *pipe_desc) 100 105 { 101 106 assert(fun); … … 106 111 assert(dev); 107 112 108 endpoint_t *ep = bus_find_endpoint(dev, endpoint_desc->endpoint_no);113 endpoint_t *ep = bus_find_endpoint(dev, pipe_desc->endpoint_no); 109 114 if (!ep) 110 115 return ENOENT; … … 113 118 } 114 119 120 /** 121 * DDF usbhc_iface callback. Calls the bus operation directly. 122 * 123 * @param fun DDF function of the device (hub) requesting the address. 124 * @param speed An USB speed of the device for which the address is reserved. 125 */ 115 126 static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed) 116 127 { … … 127 138 } 128 139 140 /** 141 * DDF usbhc_iface callback. Calls the bus operation directly. 142 * 143 * @param fun DDF function of the device (hub) releasing the address. 144 */ 129 145 static int release_default_address(ddf_fun_t *fun) 130 146 { … … 142 158 } 143 159 160 /** 161 * DDF usbhc_iface callback. Calls the bus operation directly. 162 * 163 * @param fun DDF function of the device (hub) requesting the address. 164 */ 144 165 static int device_enumerate(ddf_fun_t *fun, unsigned port) 145 166 { -
uspace/lib/usbhost/src/dma_buffer.c
reb928c4 r1102eca 45 45 }; 46 46 47 /** Allocate a DMA buffer. 47 /** 48 * Allocate a DMA buffer. 48 49 * 49 50 * @param[in] db dma_buffer_t structure to fill … … 80 81 } 81 82 82 /** Allocate a DMA buffer using the default policy. 83 /** 84 * Allocate a DMA buffer using the default policy. 83 85 * 84 86 * @param[in] db dma_buffer_t structure to fill … … 92 94 93 95 94 /** Free a DMA buffer. 96 /** 97 * Free a DMA buffer. 95 98 * 96 99 * @param[in] db dma_buffer_t structure buffer of which will be freed … … 105 108 } 106 109 107 /** Convert a pointer inside a buffer to physical address. 110 /** 111 * Convert a pointer inside a buffer to physical address. 108 112 * 109 113 * @param[in] db Buffer at which virt is pointing -
uspace/lib/usbhost/src/endpoint.c
reb928c4 r1102eca 49 49 #include "endpoint.h" 50 50 51 /** Initialize provided endpoint structure. 51 /** 52 * Initialize provided endpoint structure. 52 53 */ 53 54 void endpoint_init(endpoint_t *ep, device_t *dev, const usb_endpoint_descriptors_t *desc) … … 78 79 } 79 80 81 /** 82 * Get the bus endpoint belongs to. 83 */ 80 84 static inline const bus_ops_t *get_bus_ops(endpoint_t *ep) 81 85 { … … 83 87 } 84 88 89 /** 90 * Increase the reference count on endpoint. 91 */ 85 92 void endpoint_add_ref(endpoint_t *ep) 86 93 { … … 88 95 } 89 96 97 /** 98 * Call the desctruction callback. Default behavior is to free the memory directly. 99 */ 90 100 static inline void endpoint_destroy(endpoint_t *ep) 91 101 { … … 101 111 } 102 112 113 /** 114 * Decrease the reference count. 115 */ 103 116 void endpoint_del_ref(endpoint_t *ep) 104 117 { … … 110 123 static void endpoint_toggle_reset(endpoint_t *ep, toggle_reset_mode_t mode); 111 124 112 /** Mark the endpoint as active and block access for further fibrils. 125 /** 126 * Mark the endpoint as active and block access for further fibrils. If the 127 * endpoint is already active, it will block on ep->avail condvar. 128 * 129 * Call only under endpoint guard. After you activate the endpoint and release 130 * the guard, you must assume that particular transfer is already finished/aborted. 131 * 113 132 * @param ep endpoint_t structure. 133 * @param batch Transfer batch this endpoint is bocked by. 114 134 */ 115 135 void endpoint_activate_locked(endpoint_t *ep, usb_transfer_batch_t *batch) … … 125 145 } 126 146 127 /** Mark the endpoint as inactive and allow access for further fibrils. 147 /** 148 * Mark the endpoint as inactive and allow access for further fibrils. 149 * 128 150 * @param ep endpoint_t structure. 129 151 */ … … 140 162 } 141 163 142 /** Abort an active batch on endpoint, if any. 164 /** 165 * Abort an active batch on endpoint, if any. 143 166 * 144 167 * @param[in] ep endpoint_t structure. … … 157 180 } 158 181 182 /** 183 * The transfer on an endpoint can trigger a reset of the toggle bit. This 184 * function calls the respective bus callbacks to resolve it. 185 * 186 * @param ep The endpoint that triggered the reset 187 * @param mode Whether to reset no, one or all endpoints on a device. 188 */ 159 189 static void endpoint_toggle_reset(endpoint_t *ep, toggle_reset_mode_t mode) 160 190 { … … 168 198 return; 169 199 170 device_t *dev = ep->device;171 200 172 201 if (mode == RESET_ALL) { 202 const device_t *dev = ep->device; 173 203 for (usb_endpoint_t i = 0; i < USB_ENDPOINT_MAX; ++i) { 174 204 if (dev->endpoints[i]) … … 180 210 } 181 211 182 ssize_t endpoint_count_bw(endpoint_t *ep, size_t packet_size) 212 /** 213 * Call the bus operation to count bandwidth. 214 * 215 * @param ep Endpoint on which the transfer will take place. 216 * @param size The payload size. 217 */ 218 ssize_t endpoint_count_bw(endpoint_t *ep, size_t size) 183 219 { 184 220 assert(ep); … … 188 224 return 0; 189 225 190 return ops->endpoint_count_bw(ep, packet_size); 191 } 192 193 /** Prepare generic usb_transfer_batch and schedule it. 194 * @param ep Endpoint for which the batch shall be created. 195 * @param target address and endpoint number. 196 * @param setup_data Data to use in setup stage (Control communication type) 197 * @param in Callback for device to host communication. 198 * @param out Callback for host to device communication. 226 return ops->endpoint_count_bw(ep, size); 227 } 228 229 /** 230 * Initiate a transfer on an endpoint. Creates a transfer batch, checks the 231 * bandwidth requirements and schedules the batch. 232 * 233 * @param endpoint Endpoint for which to send the batch 234 * @param target The target of the transfer. 235 * @param direction A direction of the transfer. 236 * @param data A pointer to the data buffer. 237 * @param size Size of the data buffer. 238 * @param setup_data Data to use in the setup stage (Control communication type) 239 * @param on_complete Callback which is called after the batch is complete 199 240 * @param arg Callback parameter. 200 241 * @param name Communication identifier (for nicer output). 201 * @return Error code.202 242 */ 203 243 int endpoint_send_batch(endpoint_t *ep, usb_target_t target, -
uspace/lib/usbhost/src/hcd.c
reb928c4 r1102eca 32 32 /** @file 33 33 * 34 * Host controller driver framework. Encapsulates DDF device of HC to an 35 * hc_device_t, which is passed to driver implementing hc_driver_t. 34 36 */ 35 37 … … 68 70 static const hc_driver_t *hc_driver; 69 71 72 /** 73 * The main HC driver routine. 74 */ 70 75 int hc_driver_main(const hc_driver_t *driver) 71 76 { … … 81 86 } 82 87 83 /** IRQ handling callback, forward status from call to diver structure. 84 * 85 * @param[in] dev DDF instance of the device to use. 86 * @param[in] iid (Unused). 87 * @param[in] call Pointer to the call from kernel. 88 /** 89 * IRQ handling callback. Call the bus operation. 90 * 91 * Currently, there is a bus ops lookup to find the interrupt handler. So far, 92 * the mechanism is too flexible, as it allows different instances of HC to 93 * have different IRQ handlers, disallowing us to optimize the lookup here. 94 * TODO: Make the bus mechanism less flexible in irq handling and remove the 95 * lookup. 88 96 */ 89 97 static void irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev) … … 99 107 } 100 108 101 /** Worker for the HW interrupt replacement fibril. 109 /** 110 * Worker for the HW interrupt replacement fibril. 102 111 */ 103 112 static int interrupt_polling(void *arg) … … 123 132 } 124 133 134 /** 135 * Clean the IRQ code bottom-half. 136 */ 125 137 static inline void irq_code_clean(irq_code_t *code) 126 138 { … … 135 147 } 136 148 137 /** Register interrupt handler 138 * 139 * @param[in] device Host controller DDF device 140 * @param[in] regs Register range 141 * @param[in] irq Interrupt number 142 * @paran[in] handler Interrupt handler 143 * @param[in] gen_irq_code IRQ code generator. 149 /** 150 * Register an interrupt handler. If there is a callback to setup the bottom half, 151 * invoke it and register it. Register for notifications. 152 * 153 * If this method fails, a polling fibril is started instead. 154 * 155 * @param[in] hcd Host controller device. 156 * @param[in] hw_res Resources to be used. 144 157 * 145 158 * @return IRQ capability handle on success. … … 181 194 } 182 195 183 /** Initialize HC in memory of the driver. 184 * 185 * @param device DDF instance of the device to use 186 * @return Error code 196 /** 197 * Initialize HC in memory of the driver. 187 198 * 188 199 * This function does all the preparatory work for hc and rh drivers: … … 192 203 * - calls driver specific initialization 193 204 * - registers root hub 205 * 206 * @param device DDF instance of the device to use 207 * @return Error code 194 208 */ 195 209 int hc_dev_add(ddf_dev_t *device) -
uspace/lib/usbhost/src/usb2_bus.c
reb928c4 r1102eca 31 31 */ 32 32 /** @file 33 * HC Endpoint management. 33 * 34 * A bus_t implementation for USB 2 and lower. Implements USB 2 enumeration and 35 * configurable bandwidth counting. 34 36 */ 35 37 … … 50 52 #include "usb2_bus.h" 51 53 52 /** Ops receive generic bus_t pointer. */ 54 /** 55 * Ops receive generic bus_t pointer. 56 */ 53 57 static inline usb2_bus_t *bus_to_usb2_bus(bus_t *bus_base) 54 58 { … … 57 61 } 58 62 59 /** Unregister and destroy all endpoints using given address. 60 * @param bus usb_bus structure, non-null. 61 * @param address USB address. 62 * @param endpoint USB endpoint number. 63 * @param direction Communication direction. 64 * @return Error code. 65 */ 66 static int release_address(usb2_bus_t *bus, usb_address_t address) 67 { 68 if (!usb_address_is_valid(address)) 69 return EINVAL; 70 71 const int ret = bus->address_occupied[address] ? EOK : ENOENT; 72 bus->address_occupied[address] = false; 73 return ret; 74 } 75 76 /** Request USB address. 63 /** 64 * Request a new address. A free address is found and marked as occupied. 65 * 66 * There's no need to synchronize this method, because it is called only with 67 * default address reserved. 68 * 77 69 * @param bus usb_device_manager 78 70 * @param addr Pointer to requested address value, place to store new address 79 * @return Error code.80 * @note Default address is only available in strict mode.81 71 */ 82 72 static int request_address(usb2_bus_t *bus, usb_address_t *addr) … … 99 89 } 100 90 91 /** 92 * Mark address as free. 93 */ 94 static void release_address(usb2_bus_t *bus, usb_address_t address) 95 { 96 bus->address_occupied[address] = false; 97 } 98 101 99 static const usb_target_t usb2_default_target = {{ 102 100 .address = USB_ADDRESS_DEFAULT, … … 104 102 }}; 105 103 104 /** 105 * Transition the device to the addressed state. 106 * 107 * Reserve address, configure the control EP, issue a SET_ADDRESS command. 108 * Configure the device with the new address, mark the device as online. 109 */ 106 110 static int address_device(device_t *dev) 107 111 { … … 184 188 } 185 189 186 /** Enumerate a new USB device 190 /** 191 * Enumerate a USB device. Move it to the addressed state, then explore it 192 * to create a DDF function node with proper characteristics. 187 193 */ 188 194 static int usb2_bus_device_enumerate(device_t *dev) … … 223 229 } 224 230 225 static endpoint_t *usb2_bus_create_ep(device_t *dev, const usb_endpoint_descriptors_t *desc) 226 { 227 endpoint_t *ep = malloc(sizeof(endpoint_t)); 228 if (!ep) 229 return NULL; 230 231 endpoint_init(ep, dev, desc); 232 return ep; 233 } 234 235 /** Register an endpoint to the bus. Reserves bandwidth. 236 * @param bus usb_bus structure, non-null. 237 * @param endpoint USB endpoint number. 231 /** 232 * Register an endpoint to the bus. Reserves bandwidth. 238 233 */ 239 234 static int usb2_bus_register_ep(endpoint_t *ep) … … 252 247 } 253 248 254 /** Release bandwidth reserved by the given endpoint. 249 /** 250 * Release bandwidth reserved by the given endpoint. 255 251 */ 256 252 static int usb2_bus_unregister_ep(endpoint_t *ep) … … 266 262 const bus_ops_t usb2_bus_ops = { 267 263 .device_enumerate = usb2_bus_device_enumerate, 268 .endpoint_create = usb2_bus_create_ep,269 264 .endpoint_register = usb2_bus_register_ep, 270 265 .endpoint_unregister = usb2_bus_unregister_ep, … … 275 270 * @param bus usb_bus structure, non-null. 276 271 * @param available_bandwidth Size of the bandwidth pool. 277 * @param bw_count function to use to calculate endpoint bw requirements.278 * @return Error code.279 272 */ 280 273 void usb2_bus_init(usb2_bus_t *bus, size_t available_bandwidth) … … 287 280 bus->free_bw = available_bandwidth; 288 281 } 282 289 283 /** 290 284 * @} -
uspace/lib/usbhost/src/usb_transfer_batch.c
reb928c4 r1102eca 44 44 #include "usb_transfer_batch.h" 45 45 46 /** Create a batch on given endpoint. 46 /** 47 * Create a batch on a given endpoint. 48 * 49 * If the bus callback is not defined, it just creates a default batch. 47 50 */ 48 51 usb_transfer_batch_t *usb_transfer_batch_create(endpoint_t *ep) … … 55 58 if (!ops) { 56 59 usb_transfer_batch_t *batch = calloc(1, sizeof(usb_transfer_batch_t)); 60 if (!batch) 61 return NULL; 57 62 usb_transfer_batch_init(batch, ep); 58 63 return batch; … … 62 67 } 63 68 64 /** Initialize given batch structure. 69 /** 70 * Initialize given batch structure. 65 71 */ 66 72 void usb_transfer_batch_init(usb_transfer_batch_t *batch, endpoint_t *ep) 67 73 { 68 74 assert(ep); 75 /* Batch reference */ 69 76 endpoint_add_ref(ep); 70 77 batch->ep = ep; 71 78 } 72 79 73 /** Destroy the batch. 74 * 75 * @param[in] batch Batch structure to use. 80 /** 81 * Destroy the batch. If there's no bus callback, just free it. 76 82 */ 77 83 void usb_transfer_batch_destroy(usb_transfer_batch_t *batch) … … 83 89 const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, batch_destroy); 84 90 91 /* Batch reference */ 85 92 endpoint_del_ref(batch->ep); 86 93 … … 97 104 } 98 105 99 /** Finish a transfer batch: call handler, destroy batch, release endpoint. 106 /** 107 * Finish a transfer batch: call handler, destroy batch, release endpoint. 100 108 * 101 109 * Call only after the batch have been scheduled && completed! 102 *103 * @param[in] batch Batch structure to use.104 110 */ 105 111 void usb_transfer_batch_finish(usb_transfer_batch_t *batch) … … 121 127 } 122 128 123 /** Finish a transfer batch as an aborted one. 124 * 125 * @param[in] batch Batch structure to use. 129 /** 130 * Finish a transfer batch as an aborted one. 126 131 */ 127 132 void usb_transfer_batch_abort(usb_transfer_batch_t *batch)
Note:
See TracChangeset
for help on using the changeset viewer.