Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}