int wait_for_tds(qtd_t *head) { int result = 0; qtd_t *cur = head; while (1) { if (0) dump_td(virt_to_phys(cur)); while (cur->active && !cur->halted) udelay(60); if (cur->halted) { printf("ERROR with packet\n"); dump_td(virt_to_phys(cur)); printf("-----------------\n"); return 1; } if (cur->next_qtd & 1) { return 0; } if (0) dump_td(virt_to_phys(cur)); /* helps debugging the TD chain */ if (0) printf("\nmoving from %x to %x\n", cur, phys_to_virt(cur->next_qtd)); cur = phys_to_virt(cur->next_qtd); } return result; }
static int wait_for_ed(usbdev_t *dev, ed_t *head) { td_t *cur; /* wait for results */ while (((head->head_pointer & ~3) != head->tail_pointer) && !(head->head_pointer & 1) && ((((td_t*)phys_to_virt(head->head_pointer & ~3))->condition_code & 0xf)>=0xe)) { debug("intst: %x; ctrl: %x; cmdst: %x; head: %x -> %x, tail: %x, condition: %x\n", OHCI_INST(dev->controller)->opreg->HcInterruptStatus, OHCI_INST(dev->controller)->opreg->HcControl, OHCI_INST(dev->controller)->opreg->HcCommandStatus, head->head_pointer, ((td_t*)phys_to_virt(head->head_pointer & ~3))->next_td, head->tail_pointer, ((td_t*)phys_to_virt(head->head_pointer & ~3))->condition_code); mdelay(1); } mdelay(5); if (OHCI_INST(dev->controller)->opreg->HcInterruptStatus & WritebackDoneHead) { debug("done queue:\n"); debug("%x, %x\n", OHCI_INST(dev->controller)->hcca->HccaDoneHead, phys_to_virt(OHCI_INST(dev->controller)->hcca->HccaDoneHead)); if ((OHCI_INST(dev->controller)->hcca->HccaDoneHead & ~1) == 0) { debug("HcInterruptStatus %x\n", OHCI_INST(dev->controller)->opreg->HcInterruptStatus); } td_t *done_queue = NULL; td_t *done_head = (td_t*)phys_to_virt(OHCI_INST(dev->controller)->hcca->HccaDoneHead); while (1) { td_t *oldnext = (td_t*)phys_to_virt(done_head->next_td); if (oldnext == done_queue) break; /* last element refers to second to last, ie. endless loop */ if (oldnext == phys_to_virt(0)) break; /* last element of done list == first element of real list */ debug("head is %x, pointing to %x. requeueing to %x\n", done_head, oldnext, done_queue); done_head->next_td = (u32)done_queue; done_queue = done_head; done_head = oldnext; } for (cur = done_queue; cur != 0; cur = (td_t*)cur->next_td) { dump_td(cur, 1); } OHCI_INST(dev->controller)->opreg->HcInterruptStatus &= ~WritebackDoneHead; } if (head->head_pointer & 1) { debug("HALTED!\n"); return 1; } return 0; }