Changeset 4c70554 in mainline
- Timestamp:
- 2011-04-13T19:06:11Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9d2d444
- Parents:
- a0a134b
- Location:
- uspace/drv/uhci-hcd
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/hc.c
ra0a134b r4c70554 228 228 /* Set all frames to point to the first queue head */ 229 229 const uint32_t queue = 230 instance->transfers_interrupt.queue_head_pa231 | LINK_POINTER_QUEUE_HEAD_FLAG;230 LINK_POINTER_QH(addr_to_phys( 231 instance->transfers_interrupt.queue_head)); 232 232 233 233 unsigned i = 0; … … 236 236 } 237 237 238 /* Init device keeper */238 /* Init device keeper */ 239 239 usb_device_keeper_init(&instance->manager); 240 240 usb_log_debug("Initialized device manager.\n"); -
uspace/drv/uhci-hcd/hw_struct/queue_head.h
ra0a134b r4c70554 34 34 #ifndef DRV_UHCI_QH_H 35 35 #define DRV_UHCI_QH_H 36 37 /* libc */38 36 #include <assert.h> 39 37 40 38 #include "link_pointer.h" 39 #include "utils/malloc32.h" 41 40 42 41 typedef struct queue_head { … … 67 66 * NULL. 68 67 */ 69 static inline void qh_set_next_qh(qh_t *instance, uint32_t pa)68 static inline void qh_set_next_qh(qh_t *instance, qh_t *next) 70 69 { 71 70 /* Address is valid and not terminal */ 72 if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) { 71 uint32_t pa = addr_to_phys(next); 72 if (pa) { 73 73 instance->next = LINK_POINTER_QH(pa); 74 74 } else { 75 75 instance->next = LINK_POINTER_TERM; 76 }77 }78 /*----------------------------------------------------------------------------*/79 /** Set queue head element pointer80 *81 * @param[in] instance qh_t structure to initialize.82 * @param[in] pa Physical address of the next queue head.83 *84 * Adds proper flag. If the pointer is NULL or terminal, sets element85 * to terminal NULL.86 */87 static inline void qh_set_element_qh(qh_t *instance, uint32_t pa)88 {89 /* Address is valid and not terminal */90 if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) {91 instance->element = LINK_POINTER_QH(pa);92 } else {93 instance->element = LINK_POINTER_TERM;94 76 } 95 77 } -
uspace/drv/uhci-hcd/transfer_list.c
ra0a134b r4c70554 57 57 return ENOMEM; 58 58 } 59 instance->queue_head_pa = addr_to_phys(instance->queue_head);59 uint32_t queue_head_pa = addr_to_phys(instance->queue_head); 60 60 usb_log_debug2("Transfer list %s setup with QH: %p(%p).\n", 61 name, instance->queue_head, instance->queue_head_pa);61 name, instance->queue_head, queue_head_pa); 62 62 63 63 qh_init(instance->queue_head); … … 67 67 } 68 68 /*----------------------------------------------------------------------------*/ 69 /** Dispose transfer list structures. 70 * 71 * @param[in] instance Memory place to use. 72 * 73 * Frees memory for internal qh_t structure. 74 */ 75 void transfer_list_fini(transfer_list_t *instance) 76 { 77 assert(instance); 78 free32(instance->queue_head); 79 } 69 80 /** Set the next list in transfer list chain. 70 81 * … … 81 92 if (!instance->queue_head) 82 93 return; 83 /* Set bothqueue_head.next to point to the follower */84 qh_set_next_qh(instance->queue_head, next->queue_head _pa);85 } 86 /*----------------------------------------------------------------------------*/ 87 /** Submittransfer batch to the list and queue.94 /* Set queue_head.next to point to the follower */ 95 qh_set_next_qh(instance->queue_head, next->queue_head); 96 } 97 /*----------------------------------------------------------------------------*/ 98 /** Add transfer batch to the list and queue. 88 99 * 89 100 * @param[in] instance List to use. 90 101 * @param[in] batch Transfer batch to submit. 91 * @return Error code92 102 * 93 103 * The batch is added to the end of the list and queue. … … 109 119 } else { 110 120 /* There is something scheduled */ 111 usb_transfer_batch_t *last = list_get_instance(112 instance->batch_list.prev, usb_transfer_batch_t, link);121 usb_transfer_batch_t *last = 122 usb_transfer_batch_from_link(instance->batch_list.prev); 113 123 last_qh = batch_qh(last); 114 124 } … … 118 128 /* keep link */ 119 129 batch_qh(batch)->next = last_qh->next; 120 qh_set_next_qh(last_qh, pa);130 qh_set_next_qh(last_qh, batch_qh(batch)); 121 131 122 132 asm volatile ("": : :"memory"); … … 132 142 } 133 143 /*----------------------------------------------------------------------------*/ 134 /** Create list for finished batches.144 /** Add completed bantches to the provided list. 135 145 * 136 146 * @param[in] instance List to use. … … 147 157 link_t *next = current->next; 148 158 usb_transfer_batch_t *batch = 149 list_get_instance(current, usb_transfer_batch_t, link);159 usb_transfer_batch_from_link(current); 150 160 151 161 if (batch_is_complete(batch)) { 152 /* Save for p ost-processing */162 /* Save for processing */ 153 163 transfer_list_remove_batch(instance, batch); 154 164 list_append(current, done); … … 159 169 } 160 170 /*----------------------------------------------------------------------------*/ 161 /** Walk the list and abort all batches.171 /** Walk the list and finish all batches with EINTR. 162 172 * 163 173 * @param[in] instance List to use. … … 169 179 link_t *current = instance->batch_list.next; 170 180 usb_transfer_batch_t *batch = 171 list_get_instance(current, usb_transfer_batch_t, link);181 usb_transfer_batch_from_link(current); 172 182 transfer_list_remove_batch(instance, batch); 173 usb_transfer_batch_finish_error(batch, EI O);183 usb_transfer_batch_finish_error(batch, EINTR); 174 184 } 175 185 fibril_mutex_unlock(&instance->guard); … … 180 190 * @param[in] instance List to use. 181 191 * @param[in] batch Transfer batch to remove. 182 * @return Error code183 192 * 184 193 * Does not lock the transfer list, caller is responsible for that. … … 197 206 198 207 const char *qpos = NULL; 208 qh_t *prev_qh = NULL; 199 209 /* Remove from the hardware queue */ 200 210 if (instance->batch_list.next == &batch->link) { 201 211 /* I'm the first one here */ 202 assert((instance->queue_head->next & LINK_POINTER_ADDRESS_MASK) 203 == addr_to_phys(batch_qh(batch))); 204 instance->queue_head->next = batch_qh(batch)->next; 212 prev_qh = instance->queue_head; 205 213 qpos = "FIRST"; 206 214 } else { 215 /* The thing before me is a batch too */ 207 216 usb_transfer_batch_t *prev = 208 list_get_instance( 209 batch->link.prev, usb_transfer_batch_t, link); 210 assert((batch_qh(prev)->next & LINK_POINTER_ADDRESS_MASK) 211 == addr_to_phys(batch_qh(batch))); 212 batch_qh(prev)->next = batch_qh(batch)->next; 217 usb_transfer_batch_from_link(batch->link.prev); 218 prev_qh = batch_qh(prev); 213 219 qpos = "NOT FIRST"; 214 220 } 221 assert((prev_qh->next & LINK_POINTER_ADDRESS_MASK) 222 == addr_to_phys(batch_qh(batch))); 223 prev_qh->next = batch_qh(batch)->next; 215 224 asm volatile ("": : :"memory"); 216 225 /* Remove from the batch list */ 217 226 list_remove(&batch->link); 218 usb_log_debug("Batch(%p) removed (%s) from %s, next %x.\n",227 usb_log_debug("Batch(%p) removed (%s) from %s, next: %x.\n", 219 228 batch, qpos, instance->name, batch_qh(batch)->next); 220 229 } -
uspace/drv/uhci-hcd/transfer_list.h
ra0a134b r4c70554 39 39 #include "batch.h" 40 40 #include "hw_struct/queue_head.h" 41 #include "utils/malloc32.h"42 41 42 /** Structure maintaining both hw queue and software list 43 * of currently executed transfers 44 */ 43 45 typedef struct transfer_list 44 46 { 47 /** Guard against multiple add/remove races */ 45 48 fibril_mutex_t guard; 49 /** UHCI hw structure represeting this queue */ 46 50 qh_t *queue_head; 47 uint32_t queue_head_pa;51 /** Assigned name, for nicer debug output */ 48 52 const char *name; 53 /** List of all batches in this list */ 49 54 link_t batch_list; 50 55 } transfer_list_t; 51 56 52 /** Dispose transfer list structures. 53 * 54 * @param[in] instance Memory place to use. 55 * 56 * Frees memory for internal qh_t structure. 57 */ 58 static inline void transfer_list_fini(transfer_list_t *instance) 59 { 60 assert(instance); 61 free32(instance->queue_head); 62 } 63 57 void transfer_list_fini(transfer_list_t *instance); 64 58 int transfer_list_init(transfer_list_t *instance, const char *name); 65 66 59 void transfer_list_set_next(transfer_list_t *instance, transfer_list_t *next); 67 68 void transfer_list_add_batch(transfer_list_t *instance, usb_transfer_batch_t *batch); 69 60 void transfer_list_add_batch( 61 transfer_list_t *instance, usb_transfer_batch_t *batch); 70 62 void transfer_list_remove_finished(transfer_list_t *instance, link_t *done); 71 72 63 void transfer_list_abort_all(transfer_list_t *instance); 73 64 #endif
Note:
See TracChangeset
for help on using the changeset viewer.