Browse Source

Fix delete delete hang on serial ports

Found the issue where it was freeing transfers from the follow up list, that were also on the QH list which also tried to free it again.

Fix was in the first free list, it checks to see if the item is also in the qh list and does not free it then.
main
Kurt Eckhardt 7 years ago
parent
commit
ca070ebcd4
1 changed files with 30 additions and 1 deletions
  1. +30
    -1
      ehci.cpp

+ 30
- 1
ehci.cpp View File

// TODO: does this write interfere UPI & UAI (bits 18 & 19) ?? // TODO: does this write interfere UPI & UAI (bits 18 & 19) ??
} }
// find & free all the transfers which completed // find & free all the transfers which completed
println(" Free transfers");
Transfer_t *t = async_followup_first; Transfer_t *t = async_followup_first;
#if 0
if (t) {
println(" (Look at QH list first)");
Transfer_t *tr = (Transfer_t *)(pipe->qh.next);
while ((uint32_t)tr & 0xFFFFFFE0) {
println(" $ ", (uint32_t)tr);
tr = (Transfer_t *)(tr->qtd.next);
}
}
#endif
while (t) { while (t) {
print(" * ", (uint32_t)t);
Transfer_t *next = t->next_followup; Transfer_t *next = t->next_followup;
if (t->pipe == pipe) { if (t->pipe == pipe) {
print(" * remove");
remove_from_async_followup_list(t); remove_from_async_followup_list(t);
free_Transfer(t);

// Only free if not in QH list
Transfer_t *tr = (Transfer_t *)(pipe->qh.next);
while (((uint32_t)tr & 0xFFFFFFE0) && (tr != t)){
tr = (Transfer_t *)(tr->qtd.next);
}
if (tr == t) {
println(" * defer free until QH");
} else {
println(" * free");
free_Transfer(t); // The later code should actually free it...
}
} else {
println("");
} }
t = next; t = next;
} }
// TODO: do we need to look at pipe->qh.current ?? // TODO: do we need to look at pipe->qh.current ??
// //
// free all the transfers still attached to the QH // free all the transfers still attached to the QH
println(" Free transfers attached to QH");
Transfer_t *tr = (Transfer_t *)(pipe->qh.next); Transfer_t *tr = (Transfer_t *)(pipe->qh.next);
while ((uint32_t)tr & 0xFFFFFFE0) { while ((uint32_t)tr & 0xFFFFFFE0) {
println(" * ", (uint32_t)tr);
Transfer_t *next = (Transfer_t *)(tr->qtd.next); Transfer_t *next = (Transfer_t *)(tr->qtd.next);
free_Transfer(tr); free_Transfer(tr);
tr = next; tr = next;
} }
// hopefully we found everything... // hopefully we found everything...
free_Pipe(pipe); free_Pipe(pipe);
println("* Delete Pipe completed");
} }





Loading…
Cancel
Save