Changeset fd07e526 in mainline for uspace/drv/bus/usb/ohci
- Timestamp:
- 2011-09-16T14:50:20Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 432a269, d1e18573
- Parents:
- 47fecbb (diff), 82a31261 (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/drv/bus/usb/ohci
- Files:
-
- 1 added
- 3 deleted
- 11 edited
- 3 moved
-
Makefile (modified) (1 diff)
-
batch.c (deleted)
-
endpoint_list.c (modified) (3 diffs)
-
endpoint_list.h (modified) (2 diffs)
-
hc.c (modified) (12 diffs)
-
hc.h (modified) (4 diffs)
-
hw_struct/transfer_descriptor.c (modified) (1 diff)
-
hw_struct/transfer_descriptor.h (modified) (1 diff)
-
iface.c (deleted)
-
iface.h (deleted)
-
ohci.c (modified) (11 diffs)
-
ohci_batch.c (added)
-
ohci_batch.h (moved) (moved from uspace/drv/bus/usb/ohci/batch.h ) (1 diff)
-
ohci_endpoint.c (moved) (moved from uspace/drv/bus/usb/ohci/hcd_endpoint.c ) (4 diffs)
-
ohci_endpoint.h (moved) (moved from uspace/drv/bus/usb/ohci/hcd_endpoint.h ) (3 diffs)
-
root_hub.c (modified) (9 diffs)
-
root_hub.h (modified) (2 diffs)
-
utils/malloc32.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/Makefile
r47fecbb rfd07e526 44 44 45 45 SOURCES = \ 46 batch.c \47 46 endpoint_list.c \ 48 47 hc.c \ 49 hcd_endpoint.c \50 iface.c \51 48 main.c \ 52 49 ohci.c \ 50 ohci_batch.c \ 51 ohci_endpoint.c \ 53 52 pci.c \ 54 53 root_hub.c \ -
uspace/drv/bus/usb/ohci/endpoint_list.c
r47fecbb rfd07e526 87 87 * The endpoint is added to the end of the list and queue. 88 88 */ 89 void endpoint_list_add_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep)89 void endpoint_list_add_ep(endpoint_list_t *instance, ohci_endpoint_t *ep) 90 90 { 91 91 assert(instance); 92 assert(hcd_ep); 93 usb_log_debug2("Queue %s: Adding endpoint(%p).\n", 94 instance->name, hcd_ep); 92 assert(ep); 93 usb_log_debug2("Queue %s: Adding endpoint(%p).\n", instance->name, ep); 95 94 96 95 fibril_mutex_lock(&instance->guard); … … 103 102 } else { 104 103 /* There are active EDs, get the last one */ 105 hcd_endpoint_t *last = list_get_instance(106 list_last(&instance->endpoint_list), hcd_endpoint_t, link);104 ohci_endpoint_t *last = list_get_instance( 105 list_last(&instance->endpoint_list), ohci_endpoint_t, link); 107 106 last_ed = last->ed; 108 107 } 109 108 /* Keep link */ 110 hcd_ep->ed->next = last_ed->next;109 ep->ed->next = last_ed->next; 111 110 /* Make sure ED is written to the memory */ 112 111 write_barrier(); 113 112 114 113 /* Add ed to the hw queue */ 115 ed_append_ed(last_ed, hcd_ep->ed);114 ed_append_ed(last_ed, ep->ed); 116 115 /* Make sure ED is updated */ 117 116 write_barrier(); 118 117 119 118 /* Add to the sw list */ 120 list_append(& hcd_ep->link, &instance->endpoint_list);119 list_append(&ep->link, &instance->endpoint_list); 121 120 122 hcd_endpoint_t *first = list_get_instance(123 list_first(&instance->endpoint_list), hcd_endpoint_t, link);121 ohci_endpoint_t *first = list_get_instance( 122 list_first(&instance->endpoint_list), ohci_endpoint_t, link); 124 123 usb_log_debug("HCD EP(%p) added to list %s, first is %p(%p).\n", 125 hcd_ep, instance->name, first, first->ed);124 ep, instance->name, first, first->ed); 126 125 if (last_ed == instance->list_head) { 127 126 usb_log_debug2("%s head ED(%p-0x%0" PRIx32 "): %x:%x:%x:%x.\n", … … 138 137 * @param[in] endpoint Endpoint to remove. 139 138 */ 140 void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep)139 void endpoint_list_remove_ep(endpoint_list_t *instance, ohci_endpoint_t *ep) 141 140 { 142 141 assert(instance); 143 142 assert(instance->list_head); 144 assert( hcd_ep);145 assert( hcd_ep->ed);143 assert(ep); 144 assert(ep->ed); 146 145 147 146 fibril_mutex_lock(&instance->guard); 148 147 149 usb_log_debug2( 150 "Queue %s: removing endpoint(%p).\n", instance->name, hcd_ep); 148 usb_log_debug2("Queue %s: removing endpoint(%p).\n", instance->name, ep); 151 149 152 150 const char *qpos = NULL; 153 151 ed_t *prev_ed; 154 152 /* Remove from the hardware queue */ 155 if (list_first(&instance->endpoint_list) == & hcd_ep->link) {153 if (list_first(&instance->endpoint_list) == &ep->link) { 156 154 /* I'm the first one here */ 157 155 prev_ed = instance->list_head; 158 156 qpos = "FIRST"; 159 157 } else { 160 hcd_endpoint_t *prev =161 list_get_instance( hcd_ep->link.prev, hcd_endpoint_t, link);158 ohci_endpoint_t *prev = 159 list_get_instance(ep->link.prev, ohci_endpoint_t, link); 162 160 prev_ed = prev->ed; 163 161 qpos = "NOT FIRST"; 164 162 } 165 assert((prev_ed->next & ED_NEXT_PTR_MASK) == addr_to_phys( hcd_ep->ed));166 prev_ed->next = hcd_ep->ed->next;163 assert((prev_ed->next & ED_NEXT_PTR_MASK) == addr_to_phys(ep->ed)); 164 prev_ed->next = ep->ed->next; 167 165 /* Make sure ED is updated */ 168 166 write_barrier(); 169 167 170 168 usb_log_debug("HCD EP(%p) removed (%s) from %s, next %x.\n", 171 hcd_ep, qpos, instance->name, hcd_ep->ed->next);169 ep, qpos, instance->name, ep->ed->next); 172 170 173 171 /* Remove from the endpoint list */ 174 list_remove(& hcd_ep->link);172 list_remove(&ep->link); 175 173 fibril_mutex_unlock(&instance->guard); 176 174 } -
uspace/drv/bus/usb/ohci/endpoint_list.h
r47fecbb rfd07e526 37 37 #include <fibril_synch.h> 38 38 39 #include " hcd_endpoint.h"39 #include "ohci_endpoint.h" 40 40 #include "hw_struct/endpoint_descriptor.h" 41 41 #include "utils/malloc32.h" … … 69 69 int endpoint_list_init(endpoint_list_t *instance, const char *name); 70 70 void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next); 71 void endpoint_list_add_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep);72 void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep);71 void endpoint_list_add_ep(endpoint_list_t *instance, ohci_endpoint_t *ep); 72 void endpoint_list_remove_ep(endpoint_list_t *instance, ohci_endpoint_t *ep); 73 73 #endif 74 74 /** -
uspace/drv/bus/usb/ohci/hc.c
r47fecbb rfd07e526 42 42 43 43 #include "hc.h" 44 #include " hcd_endpoint.h"44 #include "ohci_endpoint.h" 45 45 46 46 #define OHCI_USED_INTERRUPTS \ … … 61 61 static int hc_init_memory(hc_t *instance); 62 62 static int interrupt_emulator(hc_t *instance); 63 63 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch); 64 64 /*----------------------------------------------------------------------------*/ 65 65 /** Get number of commands used in IRQ code. … … 128 128 129 129 const usb_address_t hub_address = 130 device_keeper_get_free_address(&instance->manager, USB_SPEED_FULL); 130 usb_device_manager_get_free_address( 131 &instance->generic.dev_manager, USB_SPEED_FULL); 131 132 if (hub_address <= 0) { 132 133 usb_log_error("Failed to get OHCI root hub address: %s\n", … … 135 136 } 136 137 instance->rh.address = hub_address; 137 usb_device_ keeper_bind(138 &instance-> manager, hub_address, hub_fun->handle);139 140 #define CHECK_RET_ RELEASE(ret, message...) \138 usb_device_manager_bind( 139 &instance->generic.dev_manager, hub_address, hub_fun->handle); 140 141 #define CHECK_RET_UNREG_RETURN(ret, message...) \ 141 142 if (ret != EOK) { \ 142 143 usb_log_error(message); \ 143 hc_remove_endpoint(instance, hub_address, 0, USB_DIRECTION_BOTH); \ 144 usb_device_keeper_release(&instance->manager, hub_address); \ 144 usb_endpoint_manager_unregister_ep( \ 145 &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH);\ 146 usb_device_manager_release( \ 147 &instance->generic.dev_manager, hub_address); \ 145 148 return ret; \ 146 149 } else (void)0 147 148 int ret = hc_add_endpoint(instance, hub_address, 0, USB_SPEED_FULL, 149 USB_TRANSFER_CONTROL, USB_DIRECTION_BOTH, 64, 0, 0); 150 CHECK_RET_RELEASE(ret, 151 "Failed to add OHCI root hub endpoint 0: %s.\n", str_error(ret)); 150 int ret = usb_endpoint_manager_add_ep( 151 &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH, 152 USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 0); 153 CHECK_RET_UNREG_RETURN(ret, 154 "Failed to register root hub control endpoint: %s.\n", 155 str_error(ret)); 152 156 153 157 ret = ddf_fun_add_match_id(hub_fun, "usb&class=hub", 100); 154 CHECK_RET_ RELEASE(ret,158 CHECK_RET_UNREG_RETURN(ret, 155 159 "Failed to add root hub match-id: %s.\n", str_error(ret)); 156 160 157 161 ret = ddf_fun_bind(hub_fun); 158 CHECK_RET_ RELEASE(ret,162 CHECK_RET_UNREG_RETURN(ret, 159 163 "Failed to bind root hub function: %s.\n", str_error(ret)); 160 164 … … 187 191 188 192 list_initialize(&instance->pending_batches); 189 usb_device_keeper_init(&instance->manager); 190 191 ret = usb_endpoint_manager_init(&instance->ep_manager, 192 BANDWIDTH_AVAILABLE_USB11); 193 CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n", 193 194 ret = hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11, 195 bandwidth_count_usb11); 196 CHECK_RET_RETURN(ret, "Failed to initialize generic driver: %s.\n", 194 197 str_error(ret)); 198 instance->generic.private_data = instance; 199 instance->generic.schedule = hc_schedule; 200 instance->generic.ep_add_hook = ohci_endpoint_init; 195 201 196 202 ret = hc_init_memory(instance); … … 215 221 } 216 222 /*----------------------------------------------------------------------------*/ 217 /** Create and register endpoint structures. 218 * 219 * @param[in] instance OHCI driver structure. 220 * @param[in] address USB address of the device. 221 * @param[in] endpoint USB endpoint number. 222 * @param[in] speed Communication speeed of the device. 223 * @param[in] type Endpoint's transfer type. 224 * @param[in] direction Endpoint's direction. 225 * @param[in] mps Maximum packet size the endpoint accepts. 226 * @param[in] size Maximum allowed buffer size. 227 * @param[in] interval Time between transfers(interrupt transfers only). 228 * @return Error code 229 */ 230 int hc_add_endpoint( 231 hc_t *instance, usb_address_t address, usb_endpoint_t endpoint, 232 usb_speed_t speed, usb_transfer_type_t type, usb_direction_t direction, 233 size_t mps, size_t size, unsigned interval) 234 { 235 endpoint_t *ep = 236 endpoint_get(address, endpoint, direction, type, speed, mps); 237 if (ep == NULL) 238 return ENOMEM; 239 240 hcd_endpoint_t *hcd_ep = hcd_endpoint_assign(ep); 241 if (hcd_ep == NULL) { 242 endpoint_destroy(ep); 243 return ENOMEM; 244 } 245 246 int ret = 247 usb_endpoint_manager_register_ep(&instance->ep_manager, ep, size); 248 if (ret != EOK) { 249 hcd_endpoint_clear(ep); 250 endpoint_destroy(ep); 251 return ret; 252 } 253 254 /* Enqueue hcd_ep */ 223 void hc_enqueue_endpoint(hc_t *instance, endpoint_t *ep) 224 { 225 endpoint_list_t *list = &instance->lists[ep->transfer_type]; 226 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep); 227 /* Enqueue ep */ 255 228 switch (ep->transfer_type) { 256 229 case USB_TRANSFER_CONTROL: 257 230 instance->registers->control &= ~C_CLE; 258 endpoint_list_add_ep( 259 &instance->lists[ep->transfer_type], hcd_ep); 231 endpoint_list_add_ep(list, ohci_ep); 260 232 instance->registers->control_current = 0; 261 233 instance->registers->control |= C_CLE; … … 263 235 case USB_TRANSFER_BULK: 264 236 instance->registers->control &= ~C_BLE; 265 endpoint_list_add_ep( 266 &instance->lists[ep->transfer_type], hcd_ep); 237 endpoint_list_add_ep(list, ohci_ep); 267 238 instance->registers->control |= C_BLE; 268 239 break; … … 270 241 case USB_TRANSFER_INTERRUPT: 271 242 instance->registers->control &= (~C_PLE & ~C_IE); 272 endpoint_list_add_ep( 273 &instance->lists[ep->transfer_type], hcd_ep); 243 endpoint_list_add_ep(list, ohci_ep); 274 244 instance->registers->control |= C_PLE | C_IE; 275 245 break; 276 246 } 277 278 return EOK; 279 } 280 /*----------------------------------------------------------------------------*/ 281 /** Dequeue and delete endpoint structures 282 * 283 * @param[in] instance OHCI hc driver structure. 284 * @param[in] address USB address of the device. 285 * @param[in] endpoint USB endpoint number. 286 * @param[in] direction Direction of the endpoint. 287 * @return Error code 288 */ 289 int hc_remove_endpoint(hc_t *instance, usb_address_t address, 290 usb_endpoint_t endpoint, usb_direction_t direction) 291 { 292 assert(instance); 293 fibril_mutex_lock(&instance->guard); 294 endpoint_t *ep = usb_endpoint_manager_get_ep(&instance->ep_manager, 295 address, endpoint, direction, NULL); 296 if (ep == NULL) { 297 usb_log_error("Endpoint unregister failed: No such EP.\n"); 298 fibril_mutex_unlock(&instance->guard); 299 return ENOENT; 300 } 301 302 hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep); 303 if (hcd_ep) { 304 /* Dequeue hcd_ep */ 305 switch (ep->transfer_type) { 306 case USB_TRANSFER_CONTROL: 307 instance->registers->control &= ~C_CLE; 308 endpoint_list_remove_ep( 309 &instance->lists[ep->transfer_type], hcd_ep); 310 instance->registers->control_current = 0; 311 instance->registers->control |= C_CLE; 312 break; 313 case USB_TRANSFER_BULK: 314 instance->registers->control &= ~C_BLE; 315 endpoint_list_remove_ep( 316 &instance->lists[ep->transfer_type], hcd_ep); 317 instance->registers->control |= C_BLE; 318 break; 319 case USB_TRANSFER_ISOCHRONOUS: 320 case USB_TRANSFER_INTERRUPT: 321 instance->registers->control &= (~C_PLE & ~C_IE); 322 endpoint_list_remove_ep( 323 &instance->lists[ep->transfer_type], hcd_ep); 324 instance->registers->control |= C_PLE | C_IE; 325 break; 326 default: 327 break; 328 } 329 hcd_endpoint_clear(ep); 330 } else { 331 usb_log_warning("Endpoint without hcd equivalent structure.\n"); 332 } 333 int ret = usb_endpoint_manager_unregister_ep(&instance->ep_manager, 334 address, endpoint, direction); 335 fibril_mutex_unlock(&instance->guard); 336 return ret; 337 } 338 /*----------------------------------------------------------------------------*/ 339 /** Get access to endpoint structures 340 * 341 * @param[in] instance OHCI hc driver structure. 342 * @param[in] address USB address of the device. 343 * @param[in] endpoint USB endpoint number. 344 * @param[in] direction Direction of the endpoint. 345 * @param[out] bw Reserved bandwidth. 346 * @return Error code 347 */ 348 endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address, 349 usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw) 350 { 351 assert(instance); 352 fibril_mutex_lock(&instance->guard); 353 endpoint_t *ep = usb_endpoint_manager_get_ep(&instance->ep_manager, 354 address, endpoint, direction, bw); 355 fibril_mutex_unlock(&instance->guard); 356 return ep; 247 } 248 /*----------------------------------------------------------------------------*/ 249 void hc_dequeue_endpoint(hc_t *instance, endpoint_t *ep) 250 { 251 /* Dequeue ep */ 252 endpoint_list_t *list = &instance->lists[ep->transfer_type]; 253 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep); 254 switch (ep->transfer_type) { 255 case USB_TRANSFER_CONTROL: 256 instance->registers->control &= ~C_CLE; 257 endpoint_list_remove_ep(list, ohci_ep); 258 instance->registers->control_current = 0; 259 instance->registers->control |= C_CLE; 260 break; 261 case USB_TRANSFER_BULK: 262 instance->registers->control &= ~C_BLE; 263 endpoint_list_remove_ep(list, ohci_ep); 264 instance->registers->control |= C_BLE; 265 break; 266 case USB_TRANSFER_ISOCHRONOUS: 267 case USB_TRANSFER_INTERRUPT: 268 instance->registers->control &= (~C_PLE & ~C_IE); 269 endpoint_list_remove_ep(list, ohci_ep); 270 instance->registers->control |= C_PLE | C_IE; 271 break; 272 default: 273 break; 274 } 357 275 } 358 276 /*----------------------------------------------------------------------------*/ … … 363 281 * @return Error code. 364 282 */ 365 int hc_schedule(hc _t *instance, usb_transfer_batch_t *batch)366 { 367 assert( instance);368 assert(batch);369 assert( batch->ep);283 int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch) 284 { 285 assert(hcd); 286 hc_t *instance = hcd->private_data; 287 assert(instance); 370 288 371 289 /* Check for root hub communication */ … … 374 292 return EOK; 375 293 } 294 ohci_transfer_batch_t *ohci_batch = ohci_transfer_batch_get(batch); 295 if (!ohci_batch) 296 return ENOMEM; 376 297 377 298 fibril_mutex_lock(&instance->guard); 378 list_append(& batch->link, &instance->pending_batches);379 batch_commit(batch);299 list_append(&ohci_batch->link, &instance->pending_batches); 300 ohci_transfer_batch_commit(ohci_batch); 380 301 381 302 /* Control and bulk schedules need a kick to start working */ … … 417 338 instance->registers->periodic_current); 418 339 419 link_t *current = instance->pending_batches.head.next;420 while (current != &instance->pending_batches.head) {340 link_t *current = list_first(&instance->pending_batches); 341 while (current && current != &instance->pending_batches.head) { 421 342 link_t *next = current->next; 422 usb_transfer_batch_t *batch =423 usb_transfer_batch_from_link(current);424 425 if ( batch_is_complete(batch)) {343 ohci_transfer_batch_t *batch = 344 ohci_transfer_batch_from_link(current); 345 346 if (ohci_transfer_batch_is_complete(batch)) { 426 347 list_remove(current); 427 usb_transfer_batch_finish(batch);348 ohci_transfer_batch_finish_dispose(batch); 428 349 } 429 350 … … 434 355 435 356 if (status & I_UE) { 357 usb_log_fatal("Error like no other!\n"); 436 358 hc_start(instance); 437 359 } -
uspace/drv/bus/usb/ohci/hc.h
r47fecbb rfd07e526 41 41 42 42 #include <usb/usb.h> 43 #include <usb/host/device_keeper.h> 44 #include <usb/host/usb_endpoint_manager.h> 45 #include <usbhc_iface.h> 43 #include <usb/host/hcd.h> 46 44 47 #include " batch.h"45 #include "ohci_batch.h" 48 46 #include "ohci_regs.h" 49 47 #include "root_hub.h" … … 53 51 /** Main OHCI driver structure */ 54 52 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; 53 /** Generic USB hc driver */ 54 hcd_t generic; 59 55 60 56 /** Memory mapped I/O registers area */ … … 81 77 int hc_get_irq_commands( 82 78 irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size); 79 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun); 83 80 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts); 84 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);85 81 86 82 /** Safely dispose host controller internal structures … … 88 84 * @param[in] instance Host controller structure to use. 89 85 */ 90 static inline void hc_fini(hc_t *instance) 91 { /* TODO: implement*/ }; 86 static inline void hc_fini(hc_t *instance) { /* TODO: implement*/ }; 92 87 93 int hc_add_endpoint(hc_t *instance, usb_address_t address, usb_endpoint_t ep, 94 usb_speed_t speed, usb_transfer_type_t type, usb_direction_t direction, 95 size_t max_packet_size, size_t size, unsigned interval); 96 int hc_remove_endpoint(hc_t *instance, usb_address_t address, 97 usb_endpoint_t endpoint, usb_direction_t direction); 98 endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address, 99 usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw); 88 void hc_enqueue_endpoint(hc_t *instance, endpoint_t *ep); 89 void hc_dequeue_endpoint(hc_t *instance, endpoint_t *ep); 100 90 101 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch);102 91 void hc_interrupt(hc_t *instance, uint32_t status); 103 104 /** Get and cast pointer to the driver data105 *106 * @param[in] fun DDF function pointer107 * @return cast pointer to driver_data108 */109 static inline hc_t * fun_to_hc(ddf_fun_t *fun)110 { return fun->driver_data; }111 92 #endif 112 93 /** -
uspace/drv/bus/usb/ohci/hw_struct/transfer_descriptor.c
r47fecbb rfd07e526 39 39 static unsigned togg[2] = { TD_STATUS_T_0, TD_STATUS_T_1 }; 40 40 41 void td_init( 42 td_t *instance, usb_direction_t dir,void *buffer, size_t size, int toggle)41 void td_init(td_t *instance, 42 usb_direction_t dir, const void *buffer, size_t size, int toggle) 43 43 { 44 44 assert(instance); -
uspace/drv/bus/usb/ohci/hw_struct/transfer_descriptor.h
r47fecbb rfd07e526 75 75 } __attribute__((packed)) td_t; 76 76 77 void td_init( 78 td_t *instance, usb_direction_t dir,void *buffer, size_t size, int toggle);77 void td_init(td_t *instance, 78 usb_direction_t dir, const void *buffer, size_t size, int toggle); 79 79 80 80 inline static void td_set_next(td_t *instance, td_t *next) -
uspace/drv/bus/usb/ohci/ohci.c
r47fecbb rfd07e526 42 42 43 43 #include "ohci.h" 44 #include "iface.h"45 44 #include "pci.h" 46 45 #include "hc.h" 47 #include "root_hub.h"48 46 49 47 typedef struct ohci { … … 52 50 53 51 hc_t hc; 54 rh_t rh;55 52 } ohci_t; 56 53 … … 89 86 { 90 87 assert(fun); 91 usb_device_keeper_t *manager = &dev_to_ohci(fun->dev)->hc.manager; 92 93 usb_address_t addr = usb_device_keeper_find(manager, handle); 88 usb_device_manager_t *manager = 89 &dev_to_ohci(fun->dev)->hc.generic.dev_manager; 90 91 const usb_address_t addr = usb_device_manager_find(manager, handle); 94 92 if (addr < 0) { 95 93 return addr; … … 129 127 /** Standard USB HC options (HC interface) */ 130 128 static ddf_dev_ops_t hc_ops = { 131 .interfaces[USBHC_DEV_IFACE] = &hc _iface, /* see iface.h/c */129 .interfaces[USBHC_DEV_IFACE] = &hcd_iface, 132 130 }; 133 131 /*----------------------------------------------------------------------------*/ … … 150 148 int device_setup_ohci(ddf_dev_t *device) 151 149 { 150 assert(device); 151 152 152 ohci_t *instance = malloc(sizeof(ohci_t)); 153 153 if (instance == NULL) { … … 155 155 return ENOMEM; 156 156 } 157 instance->rh_fun = NULL; 158 instance->hc_fun = NULL; 157 159 158 160 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \ 159 161 if (ret != EOK) { \ 160 162 if (instance->hc_fun) { \ 161 instance->hc_fun->ops = NULL; \162 instance->hc_fun->driver_data = NULL; \163 163 ddf_fun_destroy(instance->hc_fun); \ 164 164 } \ 165 165 if (instance->rh_fun) { \ 166 instance->rh_fun->ops = NULL; \167 instance->rh_fun->driver_data = NULL; \168 166 ddf_fun_destroy(instance->rh_fun); \ 169 167 } \ 170 168 free(instance); \ 171 device->driver_data = NULL; \172 169 usb_log_error(message); \ 173 170 return ret; \ 174 171 } else (void)0 175 172 176 instance->rh_fun = NULL;177 173 instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc"); 178 174 int ret = instance->hc_fun ? EOK : ENOMEM; … … 194 190 ret = pci_get_my_registers(device, ®_base, ®_size, &irq); 195 191 CHECK_RET_DEST_FREE_RETURN(ret, 196 "Failed to get memory addresses for %" PRIun ": %s.\n",192 "Failed to get register memory addresses for %" PRIun ": %s.\n", 197 193 device->handle, str_error(ret)); 198 194 usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n", … … 201 197 const size_t cmd_count = hc_irq_cmd_count(); 202 198 irq_cmd_t irq_cmds[cmd_count]; 199 irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = irq_cmds }; 200 203 201 ret = 204 202 hc_get_irq_commands(irq_cmds, sizeof(irq_cmds), reg_base, reg_size); … … 206 204 "Failed to generate IRQ commands: %s.\n", str_error(ret)); 207 205 208 irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = irq_cmds };209 206 210 207 /* Register handler to avoid interrupt lockup */ … … 234 231 #define CHECK_RET_FINI_RETURN(ret, message...) \ 235 232 if (ret != EOK) { \ 233 hc_fini(&instance->hc); \ 236 234 unregister_interrupt_handler(device, irq); \ 237 hc_fini(&instance->hc); \238 235 CHECK_RET_DEST_FREE_RETURN(ret, message); \ 239 236 } else (void)0 … … 248 245 "Failed to add OHCI to HC class: %s.\n", str_error(ret)); 249 246 250 hc_register_hub(&instance->hc, instance->rh_fun); 251 return EOK; 252 253 #undef CHECK_RET_DEST_FUN_RETURN 247 ret = hc_register_hub(&instance->hc, instance->rh_fun); 248 CHECK_RET_FINI_RETURN(ret, 249 "Failed to register OHCI root hub: %s.\n", str_error(ret)); 250 return ret; 251 254 252 #undef CHECK_RET_FINI_RETURN 255 253 } -
uspace/drv/bus/usb/ohci/ohci_batch.h
r47fecbb rfd07e526 35 35 #define DRV_OHCI_BATCH_H 36 36 37 #include <adt/list.h> 37 38 #include <usbhc_iface.h> 38 39 #include <usb/usb.h> 39 #include <usb/host/device_keeper.h> 40 #include <usb/host/endpoint.h> 41 #include <usb/host/batch.h> 40 #include <usb/host/usb_transfer_batch.h> 42 41 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); 42 #include "hw_struct/transfer_descriptor.h" 43 #include "hw_struct/endpoint_descriptor.h" 49 44 50 bool batch_is_complete(usb_transfer_batch_t *instance); 45 /** OHCI specific data required for USB transfer */ 46 typedef struct ohci_transfer_batch { 47 /** Link */ 48 link_t link; 49 /** Endpoint descriptor of the target endpoint. */ 50 ed_t *ed; 51 /** List of TDs needed for the transfer */ 52 td_t **tds; 53 /** Number of TDs used by the transfer */ 54 size_t td_count; 55 /** Dummy TD to be left at the ED and used by the next transfer */ 56 size_t leave_td; 57 /** Data buffer, must be accessible by the OHCI hw. */ 58 char *device_buffer; 59 /** Generic USB transfer structure */ 60 usb_transfer_batch_t *usb_batch; 61 } ohci_transfer_batch_t; 51 62 52 void batch_commit(usb_transfer_batch_t *instance); 53 54 void batch_control_write(usb_transfer_batch_t *instance); 55 56 void batch_control_read(usb_transfer_batch_t *instance); 57 58 void batch_interrupt_in(usb_transfer_batch_t *instance); 59 60 void batch_interrupt_out(usb_transfer_batch_t *instance); 61 62 void batch_bulk_in(usb_transfer_batch_t *instance); 63 64 void batch_bulk_out(usb_transfer_batch_t *instance); 63 ohci_transfer_batch_t * ohci_transfer_batch_get(usb_transfer_batch_t *batch); 64 bool ohci_transfer_batch_is_complete(ohci_transfer_batch_t *batch); 65 void ohci_transfer_batch_commit(ohci_transfer_batch_t *batch); 66 void ohci_transfer_batch_finish_dispose(ohci_transfer_batch_t *batch); 67 /*----------------------------------------------------------------------------*/ 68 static inline ohci_transfer_batch_t *ohci_transfer_batch_from_link(link_t *l) 69 { 70 assert(l); 71 return list_get_instance(l, ohci_transfer_batch_t, link); 72 } 65 73 #endif 66 74 /** -
uspace/drv/bus/usb/ohci/ohci_endpoint.c
r47fecbb rfd07e526 33 33 */ 34 34 #include "utils/malloc32.h" 35 #include "hcd_endpoint.h" 35 #include "ohci_endpoint.h" 36 #include "hc.h" 36 37 37 38 /** Callback to set toggle on ED. … … 40 41 * @param[in] toggle new value of toggle bit 41 42 */ 42 static void hcd_ep_toggle_set(void *hcd_ep, int toggle)43 static void ohci_ep_toggle_set(void *ohci_ep, int toggle) 43 44 { 44 hcd_endpoint_t *instance = hcd_ep;45 ohci_endpoint_t *instance = ohci_ep; 45 46 assert(instance); 46 47 assert(instance->ed); … … 53 54 * @return Current value of toggle bit. 54 55 */ 55 static int hcd_ep_toggle_get(void *hcd_ep)56 static int ohci_ep_toggle_get(void *ohci_ep) 56 57 { 57 hcd_endpoint_t *instance = hcd_ep;58 ohci_endpoint_t *instance = ohci_ep; 58 59 assert(instance); 59 60 assert(instance->ed); 60 61 return ed_toggle_get(instance->ed); 62 } 63 /*----------------------------------------------------------------------------*/ 64 /** Disposes hcd endpoint structure 65 * 66 * @param[in] hcd_ep endpoint structure 67 */ 68 static void ohci_endpoint_fini(endpoint_t *ep) 69 { 70 ohci_endpoint_t *instance = ep->hc_data.data; 71 hc_dequeue_endpoint(instance->hcd->private_data, ep); 72 if (instance) { 73 free32(instance->ed); 74 free32(instance->td); 75 free(instance); 76 } 61 77 } 62 78 /*----------------------------------------------------------------------------*/ … … 66 82 * @return pointer to a new hcd endpoint structure, NULL on failure. 67 83 */ 68 hcd_endpoint_t * hcd_endpoint_assign(endpoint_t *ep)84 int ohci_endpoint_init(hcd_t *hcd, endpoint_t *ep) 69 85 { 70 86 assert(ep); 71 hcd_endpoint_t *hcd_ep = malloc(sizeof(hcd_endpoint_t));72 if ( hcd_ep == NULL)73 return NULL;87 ohci_endpoint_t *ohci_ep = malloc(sizeof(ohci_endpoint_t)); 88 if (ohci_ep == NULL) 89 return ENOMEM; 74 90 75 hcd_ep->ed = malloc32(sizeof(ed_t));76 if ( hcd_ep->ed == NULL) {77 free( hcd_ep);78 return NULL;91 ohci_ep->ed = malloc32(sizeof(ed_t)); 92 if (ohci_ep->ed == NULL) { 93 free(ohci_ep); 94 return ENOMEM; 79 95 } 80 96 81 hcd_ep->td = malloc32(sizeof(td_t));82 if ( hcd_ep->td == NULL) {83 free32( hcd_ep->ed);84 free( hcd_ep);85 return NULL;97 ohci_ep->td = malloc32(sizeof(td_t)); 98 if (ohci_ep->td == NULL) { 99 free32(ohci_ep->ed); 100 free(ohci_ep); 101 return ENOMEM; 86 102 } 87 103 88 ed_init(hcd_ep->ed, ep); 89 ed_set_td(hcd_ep->ed, hcd_ep->td); 90 endpoint_set_hc_data(ep, hcd_ep, hcd_ep_toggle_get, hcd_ep_toggle_set); 91 92 return hcd_ep; 93 } 94 /*----------------------------------------------------------------------------*/ 95 /** Disposes assigned hcd endpoint structure 96 * 97 * @param[in] ep USBD endpoint structure 98 */ 99 void hcd_endpoint_clear(endpoint_t *ep) 100 { 101 assert(ep); 102 hcd_endpoint_t *hcd_ep = ep->hc_data.data; 103 assert(hcd_ep); 104 free32(hcd_ep->ed); 105 free32(hcd_ep->td); 106 free(hcd_ep); 104 ed_init(ohci_ep->ed, ep); 105 ed_set_td(ohci_ep->ed, ohci_ep->td); 106 endpoint_set_hc_data( 107 ep, ohci_ep, ohci_endpoint_fini, ohci_ep_toggle_get, ohci_ep_toggle_set); 108 ohci_ep->hcd = hcd; 109 hc_enqueue_endpoint(hcd->private_data, ep); 110 return EOK; 107 111 } 108 112 /** -
uspace/drv/bus/usb/ohci/ohci_endpoint.h
r47fecbb rfd07e526 38 38 #include <adt/list.h> 39 39 #include <usb/host/endpoint.h> 40 #include <usb/host/hcd.h> 40 41 41 42 #include "hw_struct/endpoint_descriptor.h" … … 43 44 44 45 /** Connector structure linking ED to to prepared TD. */ 45 typedef struct hcd_endpoint {46 typedef struct ohci_endpoint { 46 47 /** OHCI endpoint descriptor */ 47 48 ed_t *ed; … … 50 51 /** Linked list used by driver software */ 51 52 link_t link; 52 } hcd_endpoint_t; 53 /** Device using this ep */ 54 hcd_t *hcd; 55 } ohci_endpoint_t; 53 56 54 hcd_endpoint_t * hcd_endpoint_assign(endpoint_t *ep); 55 void hcd_endpoint_clear(endpoint_t *ep); 57 int ohci_endpoint_init(hcd_t *hcd, endpoint_t *ep); 56 58 57 /** Get and convert assigned hcd_endpoint_t structure59 /** Get and convert assigned ohci_endpoint_t structure 58 60 * @param[in] ep USBD endpoint structure. 59 61 * @return Pointer to assigned hcd endpoint structure 60 62 */ 61 static inline hcd_endpoint_t * hcd_endpoint_get(endpoint_t *ep)63 static inline ohci_endpoint_t * ohci_endpoint_get(endpoint_t *ep) 62 64 { 63 65 assert(ep); -
uspace/drv/bus/usb/ohci/root_hub.c
r47fecbb rfd07e526 121 121 assert(request); 122 122 123 memcpy(request->data_buffer, &mask, size);124 123 request->transfered_size = size; 125 usb_transfer_batch_finish_error(request, EOK);124 usb_transfer_batch_finish_error(request, &mask, size, EOK); 126 125 } 127 126 … … 206 205 usb_log_debug("Root hub got CONTROL packet\n"); 207 206 const int ret = control_request(instance, request); 208 usb_transfer_batch_finish_error(request, ret);207 usb_transfer_batch_finish_error(request, NULL, 0, ret); 209 208 break; 210 209 case USB_TRANSFER_INTERRUPT: … … 215 214 assert(instance->unfinished_interrupt_transfer == NULL); 216 215 instance->unfinished_interrupt_transfer = request; 217 break;216 return; 218 217 } 219 218 usb_log_debug("Processing changes...\n"); … … 223 222 default: 224 223 usb_log_error("Root hub got unsupported request.\n"); 225 usb_transfer_batch_finish_error(request, EINVAL); 226 } 224 usb_transfer_batch_finish_error(request, NULL, 0, EINVAL); 225 } 226 usb_transfer_batch_dispose(request); 227 227 } 228 228 /*----------------------------------------------------------------------------*/ … … 244 244 interrupt_request(instance->unfinished_interrupt_transfer, 245 245 mask, instance->interrupt_mask_size); 246 usb_transfer_batch_dispose(instance->unfinished_interrupt_transfer); 246 247 247 248 instance->unfinished_interrupt_transfer = NULL; … … 389 390 const uint32_t data = instance->registers->rh_status & 390 391 (RHS_LPS_FLAG | RHS_LPSC_FLAG | RHS_OCI_FLAG | RHS_OCIC_FLAG); 391 memcpy(request-> data_buffer, &data, 4);392 TRANSFER_OK( 4);392 memcpy(request->buffer, &data, sizeof(data)); 393 TRANSFER_OK(sizeof(data)); 393 394 } 394 395 … … 402 403 const uint32_t data = 403 404 instance->registers->rh_port_status[port - 1]; 404 memcpy(request-> data_buffer, &data, 4);405 TRANSFER_OK( 4);405 memcpy(request->buffer, &data, sizeof(data)); 406 TRANSFER_OK(sizeof(data)); 406 407 } 407 408 … … 483 484 } 484 485 485 memcpy(request-> data_buffer, descriptor, size);486 memcpy(request->buffer, descriptor, size); 486 487 TRANSFER_OK(size); 487 488 } … … 713 714 if (request->buffer_size != 1) 714 715 return EINVAL; 715 request-> data_buffer[0] = 1;716 request->buffer[0] = 1; 716 717 TRANSFER_OK(1); 717 718 -
uspace/drv/bus/usb/ohci/root_hub.h
r47fecbb rfd07e526 37 37 #include <usb/usb.h> 38 38 #include <usb/dev/driver.h> 39 #include <usb/host/usb_transfer_batch.h> 39 40 40 41 #include "ohci_regs.h" 41 #include "batch.h"42 42 43 43 #define HUB_DESCRIPTOR_MAX_SIZE (7 + 2 + 2) … … 66 66 /** size of hub descriptor */ 67 67 size_t hub_descriptor_size; 68 69 68 } rh_t; 70 69 -
uspace/drv/bus/usb/ohci/utils/malloc32.h
r47fecbb rfd07e526 46 46 * @return Physical address if exists, NULL otherwise. 47 47 */ 48 static inline uintptr_t addr_to_phys( void *addr)48 static inline uintptr_t addr_to_phys(const void *addr) 49 49 { 50 50 uintptr_t result;
Note:
See TracChangeset
for help on using the changeset viewer.
