Changeset 5a2c42b in mainline
- Timestamp:
- 2011-04-13T12:37:20Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 592369ae
- Parents:
- 2759c52
- Location:
- uspace/drv/ohci
- Files:
-
- 3 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/Makefile
r2759c52 r5a2c42b 34 34 SOURCES = \ 35 35 batch.c \ 36 endpoint_list.c \ 36 37 hc.c \ 37 38 hcd_endpoint.c \ … … 41 42 pci.c \ 42 43 root_hub.c \ 43 transfer_list.c \44 44 hw_struct/endpoint_descriptor.c \ 45 45 hw_struct/transfer_descriptor.c -
uspace/drv/ohci/endpoint_list.c
r2759c52 r5a2c42b 35 35 #include <usb/debug.h> 36 36 37 #include "transfer_list.h" 38 39 static void transfer_list_remove_batch( 40 transfer_list_t *instance, usb_transfer_batch_t *batch); 41 /*----------------------------------------------------------------------------*/ 37 #include "endpoint_list.h" 38 42 39 /** Initialize transfer list structures. 43 40 * … … 48 45 * Allocates memory for internal qh_t structure. 49 46 */ 50 int transfer_list_init(transfer_list_t *instance, const char *name)47 int endpoint_list_init(endpoint_list_t *instance, const char *name) 51 48 { 52 49 assert(instance); … … 62 59 63 60 ed_init(instance->list_head, NULL); 64 list_initialize(&instance-> batch_list);61 list_initialize(&instance->endpoint_list); 65 62 fibril_mutex_initialize(&instance->guard); 66 63 return EOK; … … 75 72 * Does not check whether this replaces an existing list . 76 73 */ 77 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next)74 void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next) 78 75 { 79 76 assert(instance); … … 82 79 } 83 80 /*----------------------------------------------------------------------------*/ 84 /** Submit transfer batchto the list and queue.85 * 86 * @param[in] instance List to use. 87 * @param[in] batch Transfer batchto submit.88 * @return Error code 89 * 90 * The batchis added to the end of the list and queue.91 */ 92 void transfer_list_add_batch(93 transfer_list_t *instance, usb_transfer_batch_t *batch) 94 { 95 assert( instance);96 assert(batch);97 usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name, batch);81 /** Submit transfer endpoint to the list and queue. 82 * 83 * @param[in] instance List to use. 84 * @param[in] endpoint Transfer endpoint to submit. 85 * @return Error code 86 * 87 * The endpoint is added to the end of the list and queue. 88 */ 89 void endpoint_list_add_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep) 90 { 91 assert(instance); 92 assert(hcd_ep); 93 usb_log_debug2("Queue %s: Adding endpoint(%p).\n", 94 instance->name, hcd_ep); 98 95 99 96 fibril_mutex_lock(&instance->guard); … … 101 98 ed_t *last_ed = NULL; 102 99 /* Add to the hardware queue. */ 103 if (list_empty(&instance-> batch_list)) {100 if (list_empty(&instance->endpoint_list)) { 104 101 /* There is nothing scheduled */ 105 102 last_ed = instance->list_head; 106 103 } else { 107 104 /* There is something scheduled */ 108 usb_transfer_batch_t *last = list_get_instance(109 instance-> batch_list.prev, usb_transfer_batch_t, link);110 last_ed = batch_ed(last);105 hcd_endpoint_t *last = list_get_instance( 106 instance->endpoint_list.prev, hcd_endpoint_t, link); 107 last_ed = last->ed; 111 108 } 112 109 /* keep link */ 113 batch_ed(batch)->next = last_ed->next;114 ed_append_ed(last_ed, batch_ed(batch));110 hcd_ep->ed->next = last_ed->next; 111 ed_append_ed(last_ed, hcd_ep->ed); 115 112 116 113 asm volatile ("": : :"memory"); 117 114 118 115 /* Add to the driver list */ 119 list_append(& batch->link, &instance->batch_list);120 121 usb_transfer_batch_t *first = list_get_instance(122 instance-> batch_list.next, usb_transfer_batch_t, link);123 usb_log_debug(" Batch(%p) added to list %s, first is %p(%p).\n",124 batch, instance->name, first, batch_ed(first));116 list_append(&hcd_ep->link, &instance->endpoint_list); 117 118 hcd_endpoint_t *first = list_get_instance( 119 instance->endpoint_list.next, hcd_endpoint_t, link); 120 usb_log_debug("HCD EP(%p) added to list %s, first is %p(%p).\n", 121 hcd_ep, instance->name, first, first->ed); 125 122 if (last_ed == instance->list_head) { 126 123 usb_log_debug2("%s head ED(%p-%p): %x:%x:%x:%x.\n", … … 132 129 } 133 130 /*----------------------------------------------------------------------------*/ 134 /** Create list for finished batches. 131 #if 0 132 /** Create list for finished endpoints. 135 133 * 136 134 * @param[in] instance List to use. 137 135 * @param[in] done list to fill 138 136 */ 139 void transfer_list_remove_finished(transfer_list_t *instance, link_t *done)137 void endpoint_list_remove_finished(endpoint_list_t *instance, link_t *done) 140 138 { 141 139 assert(instance); … … 143 141 144 142 fibril_mutex_lock(&instance->guard); 145 usb_log_debug2("Checking list %s for completed batches(%d).\n",146 instance->name, list_count(&instance-> batch_list));147 link_t *current = instance-> batch_list.next;148 while (current != &instance-> batch_list) {143 usb_log_debug2("Checking list %s for completed endpointes(%d).\n", 144 instance->name, list_count(&instance->endpoint_list)); 145 link_t *current = instance->endpoint_list.next; 146 while (current != &instance->endpoint_list) { 149 147 link_t *next = current->next; 150 usb_transfer_batch_t *batch=151 list_get_instance(current, usb_transfer_batch_t, link);152 153 if ( batch_is_complete(batch)) {148 hcd_endpoint_t *endpoint = 149 list_get_instance(current, hcd_endpoint_t, link); 150 151 if (endpoint_is_complete(endpoint)) { 154 152 /* Save for post-processing */ 155 transfer_list_remove_batch(instance, batch);153 endpoint_list_remove_endpoint(instance, endpoint); 156 154 list_append(current, done); 157 155 } … … 161 159 } 162 160 /*----------------------------------------------------------------------------*/ 163 /** Walk the list and abort all batches.164 * 165 * @param[in] instance List to use. 166 */ 167 void transfer_list_abort_all(transfer_list_t *instance)161 /** Walk the list and abort all endpointes. 162 * 163 * @param[in] instance List to use. 164 */ 165 void endpoint_list_abort_all(endpoint_list_t *instance) 168 166 { 169 167 fibril_mutex_lock(&instance->guard); 170 while (!list_empty(&instance-> batch_list)) {171 link_t *current = instance-> batch_list.next;172 usb_transfer_batch_t *batch=173 list_get_instance(current, usb_transfer_batch_t, link);174 transfer_list_remove_batch(instance, batch);175 usb_transfer_batch_finish_error(batch, EIO);168 while (!list_empty(&instance->endpoint_list)) { 169 link_t *current = instance->endpoint_list.next; 170 hcd_endpoint_t *endpoint = 171 list_get_instance(current, hcd_endpoint_t, link); 172 endpoint_list_remove_endpoint(instance, endpoint); 173 hcd_endpoint_finish_error(endpoint, EIO); 176 174 } 177 175 fibril_mutex_unlock(&instance->guard); 178 176 } 179 /*----------------------------------------------------------------------------*/ 180 /** Remove a transfer batch from the list and queue. 181 * 182 * @param[in] instance List to use. 183 * @param[in] batch Transfer batch to remove. 177 #endif 178 /*----------------------------------------------------------------------------*/ 179 /** Remove a transfer endpoint from the list and queue. 180 * 181 * @param[in] instance List to use. 182 * @param[in] endpoint Transfer endpoint to remove. 184 183 * @return Error code 185 184 * 186 185 * Does not lock the transfer list, caller is responsible for that. 187 186 */ 188 void transfer_list_remove_batch( 189 transfer_list_t *instance, usb_transfer_batch_t *batch) 187 void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep) 190 188 { 191 189 assert(instance); 192 190 assert(instance->list_head); 193 assert( batch);194 assert( batch_ed(batch));191 assert(hcd_ep); 192 assert(hcd_ep->ed); 195 193 assert(fibril_mutex_is_locked(&instance->guard)); 196 194 197 195 usb_log_debug2( 198 "Queue %s: removing batch(%p).\n", instance->name, batch);196 "Queue %s: removing endpoint(%p).\n", instance->name, hcd_ep); 199 197 200 198 const char *qpos = NULL; 199 ed_t *prev_ed; 201 200 /* Remove from the hardware queue */ 202 if (instance-> batch_list.next == &batch->link) {201 if (instance->endpoint_list.next == &hcd_ep->link) { 203 202 /* I'm the first one here */ 204 assert((instance->list_head->next & ED_NEXT_PTR_MASK) 205 == addr_to_phys(batch_ed(batch))); 206 instance->list_head->next = batch_ed(batch)->next; 203 prev_ed = instance->list_head; 207 204 qpos = "FIRST"; 208 205 } else { 209 usb_transfer_batch_t *prev = 210 list_get_instance( 211 batch->link.prev, usb_transfer_batch_t, link); 212 assert((batch_ed(prev)->next & ED_NEXT_PTR_MASK) 213 == addr_to_phys(batch_ed(batch))); 214 batch_ed(prev)->next = batch_ed(batch)->next; 206 hcd_endpoint_t *prev = 207 list_get_instance(hcd_ep->link.prev, hcd_endpoint_t, link); 208 prev_ed = prev->ed; 215 209 qpos = "NOT FIRST"; 216 210 } 211 assert((prev_ed->next & ED_NEXT_PTR_MASK) == addr_to_phys(hcd_ep->ed)); 212 prev_ed->next = hcd_ep->ed->next; 213 217 214 asm volatile ("": : :"memory"); 218 usb_log_debug(" Batch(%p) removed (%s) from %s, next %x.\n",219 batch, qpos, instance->name, batch_ed(batch)->next);220 221 /* Remove from the batchlist */222 list_remove(& batch->link);215 usb_log_debug("HCD EP(%p) removed (%s) from %s, next %x.\n", 216 hcd_ep, qpos, instance->name, hcd_ep->ed->next); 217 218 /* Remove from the endpoint list */ 219 list_remove(&hcd_ep->link); 223 220 } 224 221 /** -
uspace/drv/ohci/endpoint_list.h
r2759c52 r5a2c42b 32 32 * @brief OHCI driver transfer list structure 33 33 */ 34 #ifndef DRV_OHCI_ TRANSFER_LIST_H35 #define DRV_OHCI_ TRANSFER_LIST_H34 #ifndef DRV_OHCI_ENDPOINT_LIST_H 35 #define DRV_OHCI_ENDPOINT_LIST_H 36 36 37 37 #include <fibril_synch.h> 38 38 39 #include " batch.h"39 #include "hcd_endpoint.h" 40 40 #include "hw_struct/endpoint_descriptor.h" 41 41 #include "utils/malloc32.h" 42 42 43 typedef struct transfer_list43 typedef struct endpoint_list 44 44 { 45 45 fibril_mutex_t guard; … … 47 47 uint32_t list_head_pa; 48 48 const char *name; 49 link_t batch_list;50 } transfer_list_t;49 link_t endpoint_list; 50 } endpoint_list_t; 51 51 52 52 /** Dispose transfer list structures. … … 56 56 * Frees memory for internal qh_t structure. 57 57 */ 58 static inline void transfer_list_fini(transfer_list_t *instance)58 static inline void endpoint_list_fini(endpoint_list_t *instance) 59 59 { 60 60 assert(instance); … … 62 62 } 63 63 64 int transfer_list_init(transfer_list_t *instance, const char *name);64 int endpoint_list_init(endpoint_list_t *instance, const char *name); 65 65 66 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next);66 void endpoint_list_set_next(endpoint_list_t *instance, endpoint_list_t *next); 67 67 68 void transfer_list_add_batch(transfer_list_t *instance, usb_transfer_batch_t *batch);68 void endpoint_list_add_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep); 69 69 70 void transfer_list_remove_finished(transfer_list_t *instance, link_t *done); 70 void endpoint_list_remove_ep(endpoint_list_t *instance, hcd_endpoint_t *hcd_ep); 71 #if 0 72 void endpoint_list_remove_finished(endpoint_list_t *instance, link_t *done); 71 73 72 void transfer_list_abort_all(transfer_list_t *instance); 74 void endpoint_list_abort_all(endpoint_list_t *instance); 75 #endif 73 76 #endif 74 77 /** -
uspace/drv/ohci/hc.c
r2759c52 r5a2c42b 155 155 return ENOMEM; 156 156 } 157 // TODO: enqueue hcd_ep here!158 157 159 158 ret = usb_endpoint_manager_register_ep(&instance->ep_manager, ep, size); 160 159 if (ret != EOK) { 161 160 endpoint_destroy(ep); 162 } 161 return ret; 162 } 163 164 /* Enqueue hcd_ep */ 165 switch (ep->transfer_type) { 166 case USB_TRANSFER_CONTROL: 167 instance->registers->control &= ~C_CLE; 168 endpoint_list_add_ep( 169 &instance->lists[ep->transfer_type], hcd_ep); 170 instance->registers->control_current = 0; 171 instance->registers->control |= C_CLE; 172 break; 173 case USB_TRANSFER_BULK: 174 instance->registers->control &= ~C_BLE; 175 endpoint_list_add_ep( 176 &instance->lists[ep->transfer_type], hcd_ep); 177 instance->registers->control |= C_BLE; 178 break; 179 case USB_TRANSFER_ISOCHRONOUS: 180 case USB_TRANSFER_INTERRUPT: 181 instance->registers->control &= (~C_PLE & ~C_IE); 182 endpoint_list_add_ep( 183 &instance->lists[ep->transfer_type], hcd_ep); 184 instance->registers->control |= C_PLE | C_IE; 185 break; 186 default: 187 break; 188 } 189 163 190 return ret; 164 191 } … … 176 203 hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep); 177 204 if (hcd_ep) { 178 // TODO: dequeue hcd_ep here! 205 /* Dequeue hcd_ep */ 206 switch (ep->transfer_type) { 207 case USB_TRANSFER_CONTROL: 208 instance->registers->control &= ~C_CLE; 209 endpoint_list_remove_ep( 210 &instance->lists[ep->transfer_type], hcd_ep); 211 instance->registers->control_current = 0; 212 instance->registers->control |= C_CLE; 213 break; 214 case USB_TRANSFER_BULK: 215 instance->registers->control &= ~C_BLE; 216 endpoint_list_remove_ep( 217 &instance->lists[ep->transfer_type], hcd_ep); 218 instance->registers->control |= C_BLE; 219 break; 220 case USB_TRANSFER_ISOCHRONOUS: 221 case USB_TRANSFER_INTERRUPT: 222 instance->registers->control &= (~C_PLE & ~C_IE); 223 endpoint_list_remove_ep( 224 &instance->lists[ep->transfer_type], hcd_ep); 225 instance->registers->control |= C_PLE | C_IE; 226 break; 227 default: 228 break; 229 } 179 230 hcd_endpoint_clear(ep); 180 231 } else { … … 195 246 return rh_request(&instance->rh, batch); 196 247 } 197 248 #if 0 198 249 fibril_mutex_lock(&instance->guard); 199 250 switch (batch->ep->transfer_type) { … … 230 281 } 231 282 fibril_mutex_unlock(&instance->guard); 283 #endif 232 284 return EOK; 233 285 } … … 249 301 usb_log_debug2("Periodic current: %p.\n", 250 302 instance->registers->periodic_current); 303 #if 0 251 304 LIST_INITIALIZE(done); 252 305 transfer_list_remove_finished( … … 267 320 } 268 321 fibril_mutex_unlock(&instance->guard); 322 #endif 269 323 } 270 324 } … … 358 412 359 413 /* Use queues */ 360 instance->registers->bulk_head = instance->transfers_bulk.list_head_pa; 414 instance->registers->bulk_head = 415 instance->lists[USB_TRANSFER_BULK].list_head_pa; 361 416 usb_log_debug2("Bulk HEAD set to: %p(%p).\n", 362 instance-> transfers_bulk.list_head,363 instance-> transfers_bulk.list_head_pa);417 instance->lists[USB_TRANSFER_BULK].list_head, 418 instance->lists[USB_TRANSFER_BULK].list_head_pa); 364 419 365 420 instance->registers->control_head = 366 instance-> transfers_control.list_head_pa;421 instance->lists[USB_TRANSFER_CONTROL].list_head_pa; 367 422 usb_log_debug2("Control HEAD set to: %p(%p).\n", 368 instance-> transfers_control.list_head,369 instance-> transfers_control.list_head_pa);423 instance->lists[USB_TRANSFER_CONTROL].list_head, 424 instance->lists[USB_TRANSFER_CONTROL].list_head_pa); 370 425 371 426 /* Enable queues */ … … 398 453 assert(instance); 399 454 400 #define SETUP_ TRANSFER_LIST(type, name) \455 #define SETUP_ENDPOINT_LIST(type) \ 401 456 do { \ 402 int ret = transfer_list_init(&instance->type, name); \ 457 const char *name = usb_str_transfer_type(type); \ 458 int ret = endpoint_list_init(&instance->lists[type], name); \ 403 459 if (ret != EOK) { \ 404 usb_log_error("Failed(%d) to setup %s transferlist.\n", \460 usb_log_error("Failed(%d) to setup %s endpoint list.\n", \ 405 461 ret, name); \ 406 transfer_list_fini(&instance->transfers_isochronous); \407 transfer_list_fini(&instance->transfers_interrupt); \408 transfer_list_fini(&instance->transfers_control); \409 transfer_list_fini(&instance->transfers_bulk); \462 endpoint_list_fini(&instance->lists[USB_TRANSFER_ISOCHRONOUS]); \ 463 endpoint_list_fini(&instance->lists[USB_TRANSFER_INTERRUPT]); \ 464 endpoint_list_fini(&instance->lists[USB_TRANSFER_CONTROL]); \ 465 endpoint_list_fini(&instance->lists[USB_TRANSFER_BULK]); \ 410 466 } \ 411 467 } while (0) 412 468 413 SETUP_TRANSFER_LIST(transfers_isochronous, "ISOCHRONOUS"); 414 SETUP_TRANSFER_LIST(transfers_interrupt, "INTERRUPT"); 415 SETUP_TRANSFER_LIST(transfers_control, "CONTROL"); 416 SETUP_TRANSFER_LIST(transfers_bulk, "BULK"); 417 #undef SETUP_TRANSFER_LIST 418 transfer_list_set_next(&instance->transfers_interrupt, 419 &instance->transfers_isochronous); 420 421 /* Assign pointers to be used during scheduling */ 422 instance->transfers[USB_TRANSFER_INTERRUPT] = 423 &instance->transfers_interrupt; 424 instance->transfers[USB_TRANSFER_ISOCHRONOUS] = 425 &instance->transfers_interrupt; 426 instance->transfers[USB_TRANSFER_CONTROL] = 427 &instance->transfers_control; 428 instance->transfers[USB_TRANSFER_BULK] = 429 &instance->transfers_bulk; 469 SETUP_ENDPOINT_LIST(USB_TRANSFER_ISOCHRONOUS); 470 SETUP_ENDPOINT_LIST(USB_TRANSFER_INTERRUPT); 471 SETUP_ENDPOINT_LIST(USB_TRANSFER_CONTROL); 472 SETUP_ENDPOINT_LIST(USB_TRANSFER_BULK); 473 #undef SETUP_ENDPOINT_LIST 474 endpoint_list_set_next(&instance->lists[USB_TRANSFER_INTERRUPT], 475 &instance->lists[USB_TRANSFER_ISOCHRONOUS]); 430 476 431 477 return EOK; … … 448 494 for (; i < 32; ++i) { 449 495 instance->hcca->int_ep[i] = 450 instance-> transfers_interrupt.list_head_pa;496 instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa; 451 497 } 452 498 usb_log_debug2("Interrupt HEADs set to: %p(%p).\n", 453 instance-> transfers_interrupt.list_head,454 instance-> transfers_interrupt.list_head_pa);499 instance->lists[USB_TRANSFER_INTERRUPT].list_head, 500 instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa); 455 501 456 502 return EOK; -
uspace/drv/ohci/hc.h
r2759c52 r5a2c42b 48 48 #include "ohci_regs.h" 49 49 #include "root_hub.h" 50 #include " transfer_list.h"50 #include "endpoint_list.h" 51 51 #include "hw_struct/hcca.h" 52 52 … … 58 58 hcca_t *hcca; 59 59 60 transfer_list_t transfers_isochronous; 61 transfer_list_t transfers_interrupt; 62 transfer_list_t transfers_control; 63 transfer_list_t transfers_bulk; 64 65 transfer_list_t *transfers[4]; 60 endpoint_list_t lists[4]; 66 61 67 62 ddf_fun_t *ddf_instance;
Note:
See TracChangeset
for help on using the changeset viewer.