Changeset d5abaf4 in mainline for uspace/drv/bus/usb/ohci/ohci_batch.c
- Timestamp:
- 2011-10-16T15:16:22Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- dab3112
- Parents:
- 70d72dd
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/ohci_batch.c
r70d72dd rd5abaf4 163 163 ohci_batch->ed->td_tail, ohci_batch->ed->next); 164 164 165 size_t i = 0; 166 for (; i < ohci_batch->td_count; ++i) { 165 if (!ed_inactive(ohci_batch->ed) && ed_transfer_pending(ohci_batch->ed)) 166 return false; 167 168 /* Now we may be sure that either the ED is inactive because of errors 169 * or all transfer descriptors completed successfully */ 170 171 /* Assume all data got through */ 172 ohci_batch->usb_batch->transfered_size = 173 ohci_batch->usb_batch->buffer_size; 174 /* Assume we will leave the last td behind */ 175 ohci_batch->leave_td = ohci_batch->td_count; 176 177 /* Check all TDs */ 178 for (size_t i = 0; i < ohci_batch->td_count; ++i) { 167 179 assert(ohci_batch->tds[i] != NULL); 168 180 usb_log_debug("TD %zu: %08x:%08x:%08x:%08x.\n", i, 169 181 ohci_batch->tds[i]->status, ohci_batch->tds[i]->cbp, 170 182 ohci_batch->tds[i]->next, ohci_batch->tds[i]->be); 171 if (!td_is_finished(ohci_batch->tds[i])) { 172 return false; 173 } 183 184 /* If the TD got all its data through, it will report 0 bytes 185 * remain, the sole exception is INPUT with data rounding flag 186 * (short), i.e. every INPUT. Nice thing is that short packets 187 * will correctly report remaining data, thus making 188 * this computation correct (short packets need to be produced 189 * by the last TD) 190 * NOTE: This also works for CONTROL transfer as 191 * the first TD will return 0 remain. 192 * NOTE: Short packets don't break the assumption that 193 * we leave the very last(unused) TD behind. 194 */ 195 ohci_batch->usb_batch->transfered_size 196 -= td_remain_size(ohci_batch->tds[i]); 197 174 198 ohci_batch->usb_batch->error = td_error(ohci_batch->tds[i]); 175 199 if (ohci_batch->usb_batch->error != EOK) { … … 177 201 ohci_batch->usb_batch, i, 178 202 ohci_batch->tds[i]->status); 179 /* Make sure TD queue is empty (one TD), 180 * ED should be marked as halted */ 181 ohci_batch->ed->td_tail = 182 (ohci_batch->ed->td_head & ED_TDTAIL_PTR_MASK); 183 ++i; 203 204 /* ED should be stopped because of errors */ 205 assert((ohci_batch->ed->td_head & ED_TDHEAD_HALTED_FLAG) != 0); 206 207 /* Now we have a problem: we don't know what TD 208 * the head pointer points to, the retiring rules 209 * described in specs say it should be the one after 210 * the failed one so set the tail pointer accordingly. 211 * It will be the one TD we leave behind. 212 */ 213 ohci_batch->leave_td = i + 1; 214 215 /* Check TD assumption */ 216 const uint32_t pa = addr_to_phys( 217 ohci_batch->tds[ohci_batch->leave_td]); 218 assert((ohci_batch->ed->td_head & ED_TDTAIL_PTR_MASK) 219 == pa); 220 221 ed_set_tail_td(ohci_batch->ed, 222 ohci_batch->tds[ohci_batch->leave_td]); 223 224 /* Clear possible ED HALT */ 225 ohci_batch->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG; 184 226 break; 185 227 } 186 228 } 187 188 assert(i <= ohci_batch->td_count);189 ohci_batch->leave_td = i; 190 229 assert(ohci_batch->usb_batch->transfered_size <= 230 ohci_batch->usb_batch->buffer_size); 231 232 /* Store the remaining TD */ 191 233 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ohci_batch->usb_batch->ep); 192 234 assert(ohci_ep); 193 235 ohci_ep->td = ohci_batch->tds[ohci_batch->leave_td]; 236 #if 0 194 237 assert(i > 0); 195 238 ohci_batch->usb_batch->transfered_size = … … 199 242 -= td_remain_size(ohci_batch->tds[i]); 200 243 } 201 202 /* Clear possible ED HALT */ 203 ohci_batch->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG; 204 /* just make sure that we are leaving the right TD behind */ 244 #endif 245 /* Just make sure that we are leaving the right TD behind */ 205 246 const uint32_t pa = addr_to_phys(ohci_ep->td); 206 247 assert(pa == (ohci_batch->ed->td_head & ED_TDHEAD_PTR_MASK));
Note:
See TracChangeset
for help on using the changeset viewer.