X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=usb%2Fhost%2Fohci.c;h=f7501c386613681792e88804e99ab6547022d599;hb=b81baa39a5ef70dfcf5aaa212d5274e4b156c618;hp=d696294a04de06bad11a3a5b151cde5a2a61daf3;hpb=113b79747a3b5c358f1b1f0af5c562ca5a5bd2eb;p=ppcskel.git diff --git a/usb/host/ohci.c b/usb/host/ohci.c index d696294..f7501c3 100644 --- a/usb/host/ohci.c +++ b/usb/host/ohci.c @@ -202,7 +202,10 @@ static void general_td_fill(struct general_td *dest, const usb_transfer_descript case USB_PID_IN: printf("pid_in\n"); dest->flags |= LE(OHCI_TD_DIRECTION_PID_IN); - dest->flags |= LE(OHCI_TD_BUFFER_ROUNDING); + if(src->maxp > src->actlen) { + printf("round buffer!"); + dest->flags |= LE(OHCI_TD_BUFFER_ROUNDING); + } /* * let the endpoint do the togglestuff! * TODO: just temporary solution! @@ -228,6 +231,7 @@ static void dump_address(void *addr, u32 size, const char* str) hexdump(addr, size); } +static struct endpoint_descriptor _edhead; struct endpoint_descriptor *edhead = 0; void hcdi_fire() { @@ -260,16 +264,46 @@ void hcdi_fire() set32(OHCI0_HC_CONTROL, OHCI_CTRL_CLE); write32(OHCI0_HC_COMMAND_STATUS, OHCI_CLF); + struct general_td *n=0, *prev = 0, *next = 0; /* poll until edhead->headp is null */ do { sync_before_read(edhead, sizeof(struct endpoint_descriptor)); printf("edhead->headp: 0x%08X\n", LE(edhead->headp)); + + /* if halted, debug output plz. will break the transfer */ + if((LE(edhead->headp) & OHCI_ENDPOINT_HALTED)) { + n = phys_to_virt(LE(edhead->headp)&~0xf); + prev = phys_to_virt((u32)prev); + printf("halted!\n"); + + sync_before_read((void*) n, sizeof(struct general_td)); + printf("n: 0x%08X\n", n); + dump_address(n, sizeof(struct general_td), "n(after)"); + if(n->buflen > 0) { + sync_before_read((void*) n->bufaddr, n->buflen); + dump_address((void*) n->bufaddr, n->buflen, "n->bufaddr(after)"); + } + dbg_td_flag(LE(n->flags)); + + sync_before_read((void*) prev, sizeof(struct general_td)); + printf("prev: 0x%08X\n", prev); + dump_address(prev, sizeof(struct general_td), "prev(after)"); + if(prev->buflen >0) { + sync_before_read((void*) prev->bufaddr, prev->buflen); + dump_address((void*) prev->bufaddr, prev->buflen, "prev->bufaddr(after)"); + } + dbg_td_flag(LE(prev->flags)); + + printf("halted end!\n"); + return; + } + prev = (struct general_td*) (LE(edhead->headp)&~0xf); } while(LE(edhead->headp)&~0xf); - struct general_td *n = phys_to_virt(read32(OHCI0_HC_DONE_HEAD) & ~1); + n = phys_to_virt(read32(OHCI0_HC_DONE_HEAD) & ~1); printf("hc_done_head: 0x%08X\n", read32(OHCI0_HC_DONE_HEAD)); - struct general_td *prev = 0, *next = 0; + prev = 0; next = 0; /* reverse done queue */ while(virt_to_phys(n) && edhead->tdcount) { sync_before_read((void*) n, sizeof(struct general_td)); @@ -288,10 +322,6 @@ void hcdi_fire() n = next; prev = 0; while(virt_to_phys(n)) { - if(prev) { - free(prev); - } - dump_address(n, sizeof(struct general_td), "n(after)"); if(n->buflen > 0) { @@ -301,8 +331,6 @@ void hcdi_fire() dbg_td_flag(LE(n->flags)); prev = n; n = (struct general_td*) n->nexttd; - } - if(prev) { free(prev); } @@ -311,7 +339,6 @@ void hcdi_fire() write32(OHCI0_HC_CONTROL, read32(OHCI0_HC_CONTROL)&~OHCI_CTRL_CLE); - free(edhead); edhead = 0; printf("<^> <^> <^> hcdi_fire(end)\n"); @@ -323,7 +350,8 @@ void hcdi_fire() u8 hcdi_enqueue(const usb_transfer_descriptor *td) { printf("*()*()*()*()*()*()*() hcdi_enqueue(start)\n"); if(!edhead) { - edhead = allocate_endpoint(); + edhead = &_edhead; + memset(edhead, 0, sizeof(struct endpoint_descriptor)); edhead->flags = LE(OHCI_ENDPOINT_GENERAL_FORMAT); edhead->headp = edhead->tailp = edhead->nexted = LE(0); edhead->flags |= LE(OHCI_ENDPOINT_LOW_SPEED |