Changeset 09ace19 in mainline
- Timestamp:
- 2011-08-25T15:33:41Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f974519
- Parents:
- cc34f5f0
- Location:
- uspace/drv/bus/usb/ohci
- Files:
-
- 2 deleted
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/Makefile
rcc34f5f0 r09ace19 47 47 endpoint_list.c \ 48 48 hc.c \ 49 iface.c \50 49 main.c \ 51 50 ohci.c \ -
uspace/drv/bus/usb/ohci/batch.c
rcc34f5f0 r09ace19 43 43 #include "hw_struct/endpoint_descriptor.h" 44 44 #include "hw_struct/transfer_descriptor.h" 45 /* 45 46 46 static void batch_control_write(usb_transfer_batch_t *instance); 47 47 static void batch_control_read(usb_transfer_batch_t *instance); … … 52 52 static void batch_bulk_in(usb_transfer_batch_t *instance); 53 53 static void batch_bulk_out(usb_transfer_batch_t *instance); 54 */ 54 55 55 static void batch_setup_control(usb_transfer_batch_t *batch) 56 56 { … … 173 173 return EOK; 174 174 #undef CHECK_NULL_DISPOSE_RETURN 175 }176 /*----------------------------------------------------------------------------*/177 /** Allocate memory initialize internal structures178 *179 * @param[in] fun DDF function to pass to callback.180 * @param[in] ep Communication target181 * @param[in] buffer Data source/destination.182 * @param[in] buffer_size Size of the buffer.183 * @param[in] setup_buffer Setup data source (if not NULL)184 * @param[in] setup_size Size of setup_buffer (should be always 8)185 * @param[in] func_in function to call on inbound transfer completion186 * @param[in] func_out function to call on outbound transfer completion187 * @param[in] arg additional parameter to func_in or func_out188 * @return Valid pointer if all structures were successfully created,189 * NULL otherwise.190 *191 * Allocates and initializes structures needed by the OHCI hw for the transfer.192 */193 usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep,194 char *buffer, size_t buffer_size,195 const char *setup_buffer, size_t setup_size,196 usbhc_iface_transfer_in_callback_t func_in,197 usbhc_iface_transfer_out_callback_t func_out, void *arg)198 {199 #define CHECK_NULL_DISPOSE_RETURN(ptr, message...) \200 if (ptr == NULL) { \201 usb_log_error(message); \202 if (instance) { \203 usb_transfer_batch_dispose(instance); \204 } \205 return NULL; \206 } else (void)0207 208 usb_transfer_batch_t *instance = malloc(sizeof(usb_transfer_batch_t));209 CHECK_NULL_DISPOSE_RETURN(instance,210 "Failed to allocate batch instance.\n");211 usb_transfer_batch_init(instance, ep, buffer, NULL, buffer_size,212 NULL, setup_size, func_in, func_out, arg, fun, NULL,213 ohci_batch_dispose);214 215 const ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep);216 assert(ohci_ep);217 218 ohci_transfer_batch_t *data = calloc(sizeof(ohci_transfer_batch_t), 1);219 CHECK_NULL_DISPOSE_RETURN(data, "Failed to allocate batch data.\n");220 instance->private_data = data;221 222 data->td_count =223 ((buffer_size + OHCI_TD_MAX_TRANSFER - 1) / OHCI_TD_MAX_TRANSFER);224 /* Control transfer need Setup and Status stage */225 if (ep->transfer_type == USB_TRANSFER_CONTROL) {226 data->td_count += 2;227 }228 229 /* We need an extra place for TD that is currently assigned to hcd_ep*/230 data->tds = calloc(sizeof(td_t*), data->td_count + 1);231 CHECK_NULL_DISPOSE_RETURN(data->tds,232 "Failed to allocate transfer descriptors.\n");233 234 /* Add TD left over by the previous transfer */235 data->tds[0] = ohci_ep->td;236 data->leave_td = 0;237 unsigned i = 1;238 for (; i <= data->td_count; ++i) {239 data->tds[i] = malloc32(sizeof(td_t));240 CHECK_NULL_DISPOSE_RETURN(data->tds[i],241 "Failed to allocate TD %d.\n", i );242 }243 244 data->ed = ohci_ep->ed;245 246 /* NOTE: OHCI is capable of handling buffer that crosses page boundaries247 * it is, however, not capable of handling buffer that occupies more248 * than two pages (the first page is computed using start pointer, the249 * other using the end pointer) */250 if (setup_size + buffer_size > 0) {251 data->device_buffer = malloc32(setup_size + buffer_size);252 CHECK_NULL_DISPOSE_RETURN(data->device_buffer,253 "Failed to allocate device accessible buffer.\n");254 instance->setup_buffer = data->device_buffer;255 instance->data_buffer = data->device_buffer + setup_size;256 memcpy(instance->setup_buffer, setup_buffer, setup_size);257 }258 259 return instance;260 175 } 261 176 /*----------------------------------------------------------------------------*/ -
uspace/drv/bus/usb/ohci/batch.h
rcc34f5f0 r09ace19 41 41 #include <usb/host/batch.h> 42 42 43 usb_transfer_batch_t * batch_get(44 ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t size,45 const char *setup_buffer, size_t setup_size,46 usbhc_iface_transfer_in_callback_t func_in,47 usbhc_iface_transfer_out_callback_t func_out,48 void *arg);49 50 43 int batch_init_ohci(usb_transfer_batch_t *batch); 51 52 44 bool batch_is_complete(usb_transfer_batch_t *batch); 53 54 void batch_commit(usb_transfer_batch_t *instance); 55 56 void batch_control_write(usb_transfer_batch_t *instance); 57 58 void batch_control_read(usb_transfer_batch_t *instance); 59 60 void batch_interrupt_in(usb_transfer_batch_t *instance); 61 62 void batch_interrupt_out(usb_transfer_batch_t *instance); 63 64 void batch_bulk_in(usb_transfer_batch_t *instance); 65 66 void batch_bulk_out(usb_transfer_batch_t *instance); 45 void batch_commit(usb_transfer_batch_t *batch); 67 46 #endif 68 47 /** -
uspace/drv/bus/usb/ohci/hc.c
rcc34f5f0 r09ace19 61 61 static int hc_init_memory(hc_t *instance); 62 62 static int interrupt_emulator(hc_t *instance); 63 /*----------------------------------------------------------------------------*/ 64 static int schedule(hcd_t *hcd, usb_transfer_batch_t *batch) 65 { 66 assert(hcd); 67 batch_init_ohci(batch); 68 return hc_schedule(hcd->private_data, batch); 69 } 63 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch); 70 64 /*----------------------------------------------------------------------------*/ 71 65 /** Get number of commands used in IRQ code. … … 211 205 212 206 list_initialize(&instance->pending_batches); 213 usb_device_keeper_init(&instance->manager);214 215 ret = usb_endpoint_manager_init(&instance->ep_manager,216 BANDWIDTH_AVAILABLE_USB11);217 CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n",218 str_error(ret));219 207 220 208 ret = hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11); … … 222 210 str_error(ret)); 223 211 instance->generic.private_data = instance; 224 instance->generic.schedule = schedule;212 instance->generic.schedule = hc_schedule; 225 213 instance->generic.ep_add_hook = ohci_endpoint_init; 226 214 … … 302 290 } 303 291 /*----------------------------------------------------------------------------*/ 304 /** Create and register endpoint structures.305 *306 * @param[in] instance OHCI driver structure.307 * @param[in] address USB address of the device.308 * @param[in] endpoint USB endpoint number.309 * @param[in] speed Communication speeed of the device.310 * @param[in] type Endpoint's transfer type.311 * @param[in] direction Endpoint's direction.312 * @param[in] mps Maximum packet size the endpoint accepts.313 * @param[in] size Maximum allowed buffer size.314 * @param[in] interval Time between transfers(interrupt transfers only).315 * @return Error code316 */317 int hc_add_endpoint(318 hc_t *instance, usb_address_t address, usb_endpoint_t endpoint,319 usb_speed_t speed, usb_transfer_type_t type, usb_direction_t direction,320 size_t mps, size_t size, unsigned interval)321 {322 endpoint_t *ep =323 endpoint_get(address, endpoint, direction, type, speed, mps);324 if (ep == NULL)325 return ENOMEM;326 327 int ret = ohci_endpoint_init(&instance->generic, ep);328 if (ret != EOK) {329 endpoint_destroy(ep);330 return ret;331 }332 333 ret = usb_endpoint_manager_register_ep(&instance->ep_manager, ep, size);334 if (ret != EOK) {335 endpoint_destroy(ep);336 return ret;337 }338 hc_enqueue_endpoint(instance, ep);339 340 return EOK;341 }342 /*----------------------------------------------------------------------------*/343 /** Dequeue and delete endpoint structures344 *345 * @param[in] instance OHCI hc driver structure.346 * @param[in] address USB address of the device.347 * @param[in] endpoint USB endpoint number.348 * @param[in] direction Direction of the endpoint.349 * @return Error code350 */351 int hc_remove_endpoint(hc_t *instance, usb_address_t address,352 usb_endpoint_t endpoint, usb_direction_t direction)353 {354 assert(instance);355 fibril_mutex_lock(&instance->guard);356 endpoint_t *ep = usb_endpoint_manager_get_ep(&instance->ep_manager,357 address, endpoint, direction, NULL);358 if (ep == NULL) {359 usb_log_error("Endpoint unregister failed: No such EP.\n");360 fibril_mutex_unlock(&instance->guard);361 return ENOENT;362 }363 364 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep);365 if (ohci_ep) {366 hc_dequeue_endpoint(instance, ep);367 } else {368 usb_log_warning("Endpoint without hcd equivalent structure.\n");369 }370 int ret = usb_endpoint_manager_unregister_ep(&instance->ep_manager,371 address, endpoint, direction);372 fibril_mutex_unlock(&instance->guard);373 return ret;374 }375 /*----------------------------------------------------------------------------*/376 /** Get access to endpoint structures377 *378 * @param[in] instance OHCI hc driver structure.379 * @param[in] address USB address of the device.380 * @param[in] endpoint USB endpoint number.381 * @param[in] direction Direction of the endpoint.382 * @param[out] bw Reserved bandwidth.383 * @return Error code384 */385 endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address,386 usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw)387 {388 assert(instance);389 fibril_mutex_lock(&instance->guard);390 endpoint_t *ep = usb_endpoint_manager_get_ep(&instance->ep_manager,391 address, endpoint, direction, bw);392 fibril_mutex_unlock(&instance->guard);393 return ep;394 }395 /*----------------------------------------------------------------------------*/396 292 /** Add USB transfer to the schedule. 397 293 * … … 400 296 * @return Error code. 401 297 */ 402 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch) 403 { 404 assert(instance); 405 assert(batch); 406 assert(batch->ep); 298 int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch) 299 { 300 assert(hcd); 301 batch_init_ohci(batch); 302 hc_t *instance = hcd->private_data; 303 assert(instance); 407 304 408 305 /* Check for root hub communication */ -
uspace/drv/bus/usb/ohci/hc.h
rcc34f5f0 r09ace19 53 53 /** Main OHCI driver structure */ 54 54 typedef struct hc { 55 /** USB bus driver, devices and addresses */56 usb_device_keeper_t manager;57 /** USB bus driver, endpoints */58 usb_endpoint_manager_t ep_manager;59 60 55 /** Generic USB hc driver */ 61 56 hcd_t generic; … … 91 86 * @param[in] instance Host controller structure to use. 92 87 */ 93 static inline void hc_fini(hc_t *instance) 94 { /* TODO: implement*/ }; 88 static inline void hc_fini(hc_t *instance) { /* TODO: implement*/ }; 95 89 96 90 void hc_enqueue_endpoint(hc_t *instance, endpoint_t *ep); 97 91 void hc_dequeue_endpoint(hc_t *instance, endpoint_t *ep); 98 92 99 int hc_add_endpoint(hc_t *instance, usb_address_t address, usb_endpoint_t ep,100 usb_speed_t speed, usb_transfer_type_t type, usb_direction_t direction,101 size_t max_packet_size, size_t size, unsigned interval);102 int hc_remove_endpoint(hc_t *instance, usb_address_t address,103 usb_endpoint_t endpoint, usb_direction_t direction);104 endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address,105 usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw);106 107 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch);108 93 void hc_interrupt(hc_t *instance, uint32_t status); 109 110 /** Get and cast pointer to the driver data111 *112 * @param[in] fun DDF function pointer113 * @return cast pointer to driver_data114 */115 static inline hc_t * fun_to_hc(ddf_fun_t *fun)116 { return fun->driver_data; }117 94 #endif 118 95 /** -
uspace/drv/bus/usb/ohci/ohci.c
rcc34f5f0 r09ace19 42 42 43 43 #include "ohci.h" 44 #include "iface.h"45 44 #include "pci.h" 46 45 #include "hc.h"
Note:
See TracChangeset
for help on using the changeset viewer.