Changeset e50cd7f in mainline for uspace/drv/uhci-hcd/transfer_list.c
- Timestamp:
- 2011-04-17T19:17:55Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 63517c2, cfbbe1d3
- Parents:
- ef354b6 (diff), 8595577b (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/uhci-hcd/transfer_list.c
ref354b6 re50cd7f 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 /** Check list for finished batches. 135 * 136 * @param[in] instance List to use. 137 * @return Error code 138 * 139 * Creates a local list of finished batches and calls next_step on each and 140 * every one. This is safer because next_step may theoretically access 141 * this transfer list leading to the deadlock if its done inline. 144 /** Add completed bantches to the provided list. 145 * 146 * @param[in] instance List to use. 147 * @param[in] done list to fill 142 148 */ 143 149 void transfer_list_remove_finished(transfer_list_t *instance, link_t *done) … … 151 157 link_t *next = current->next; 152 158 usb_transfer_batch_t *batch = 153 list_get_instance(current, usb_transfer_batch_t, link);159 usb_transfer_batch_from_link(current); 154 160 155 161 if (batch_is_complete(batch)) { 156 /* Save for p ost-processing */162 /* Save for processing */ 157 163 transfer_list_remove_batch(instance, batch); 158 164 list_append(current, done); … … 161 167 } 162 168 fibril_mutex_unlock(&instance->guard); 163 164 } 165 /*----------------------------------------------------------------------------*/ 166 /** Walk the list and abort all batches. 169 } 170 /*----------------------------------------------------------------------------*/ 171 /** Walk the list and finish all batches with EINTR. 167 172 * 168 173 * @param[in] instance List to use. … … 174 179 link_t *current = instance->batch_list.next; 175 180 usb_transfer_batch_t *batch = 176 list_get_instance(current, usb_transfer_batch_t, link);181 usb_transfer_batch_from_link(current); 177 182 transfer_list_remove_batch(instance, batch); 178 usb_transfer_batch_finish (batch, EIO);183 usb_transfer_batch_finish_error(batch, EINTR); 179 184 } 180 185 fibril_mutex_unlock(&instance->guard); … … 185 190 * @param[in] instance List to use. 186 191 * @param[in] batch Transfer batch to remove. 187 * @return Error code188 192 * 189 193 * Does not lock the transfer list, caller is responsible for that. … … 202 206 203 207 const char *qpos = NULL; 208 qh_t *prev_qh = NULL; 204 209 /* Remove from the hardware queue */ 205 210 if (instance->batch_list.next == &batch->link) { 206 211 /* I'm the first one here */ 207 assert((instance->queue_head->next & LINK_POINTER_ADDRESS_MASK) 208 == addr_to_phys(batch_qh(batch))); 209 instance->queue_head->next = batch_qh(batch)->next; 212 prev_qh = instance->queue_head; 210 213 qpos = "FIRST"; 211 214 } else { 215 /* The thing before me is a batch too */ 212 216 usb_transfer_batch_t *prev = 213 list_get_instance( 214 batch->link.prev, usb_transfer_batch_t, link); 215 assert((batch_qh(prev)->next & LINK_POINTER_ADDRESS_MASK) 216 == addr_to_phys(batch_qh(batch))); 217 batch_qh(prev)->next = batch_qh(batch)->next; 217 usb_transfer_batch_from_link(batch->link.prev); 218 prev_qh = batch_qh(prev); 218 219 qpos = "NOT FIRST"; 219 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; 220 224 asm volatile ("": : :"memory"); 221 225 /* Remove from the batch list */ 222 226 list_remove(&batch->link); 223 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", 224 228 batch, qpos, instance->name, batch_qh(batch)->next); 225 229 }
Note:
See TracChangeset
for help on using the changeset viewer.