On Sun, Mar 04, 2012 at 10:42:45PM +0100, Nils wrote:
Hi kevin, Op zaterdag 03-03-2012 om 22:33 uur [tijdzone -0500], schreef Kevin O'Connor:
I don't see anything wrong with the above code. (The barrier() should be moved, but I don't see that causing the problems you're seeing.)
Getting more info may help. Something like the below.
See ohci_test2.log
Another thing you could try is forcing the "if (frameexp == 0)" branch (by, for example, changing it to "if (1 || frameexp == 0)".
With that branch forced i get the same timeout as before. See ohci_test3.log
Nothing looks wrong in the code. I suppose one of the transfer descriptors could have confused the controller. You could try the patch below (apply this on top of the "ohci pipe free fix" at the start of this thread). It would help if your logs had timing info (via readserial.py).
I'm really just guessing at this point. I'm pretty much at a loss for why your controller just shuts down.
-Kevin
diff --git a/src/usb-ohci.c b/src/usb-ohci.c index 7a437ad..4e020cb 100644 --- a/src/usb-ohci.c +++ b/src/usb-ohci.c @@ -123,6 +123,8 @@ ohci_waittick(struct usb_ohci_s *cntl) { barrier(); struct ohci_hcca *hcca = (void*)cntl->regs->hcca; + dprintf(1, "ohci wait: c=%x h=%p f=%d s=%x\n" + , cntl->regs->control, hcca, hcca->frame_no, cntl->regs->intrstatus); u32 startframe = hcca->frame_no; u64 end = calc_future_tsc(1000 * 5); for (;;) { @@ -130,6 +132,8 @@ ohci_waittick(struct usb_ohci_s *cntl) break; if (check_tsc(end)) { warn_timeout(); + dprintf(1, "ohci to: c=%x h=%p f=%d s=%x\n" + , cntl->regs->control, hcca, hcca->frame_no, cntl->regs->intrstatus); return; } yield(); @@ -141,11 +145,16 @@ ohci_free_pipes(struct usb_ohci_s *cntl) { dprintf(7, "ohci_free_pipes %p\n", cntl);
+ struct ohci_hcca *hcca = (void*)cntl->regs->hcca; + dprintf(1, "ohci fp: c=%x h=%p f=%d s=%x\n" + , cntl->regs->control, hcca, hcca->frame_no, cntl->regs->intrstatus); u32 creg = readl(&cntl->regs->control); if (creg & (OHCI_CTRL_CLE|OHCI_CTRL_BLE)) { writel(&cntl->regs->control, creg & ~(OHCI_CTRL_CLE|OHCI_CTRL_BLE)); ohci_waittick(cntl); } + dprintf(1, "ohci fp2: c=%x h=%p f=%d s=%x\n" + , cntl->regs->control, hcca, hcca->frame_no, cntl->regs->intrstatus);
u32 *pos = &cntl->regs->ed_controlhead; for (;;) { @@ -214,6 +223,9 @@ start_ohci(struct usb_ohci_s *cntl, struct ohci_hcca *hcca) | OHCI_USB_OPER | oldrwc)); readl(&cntl->regs->control); // flush writes
+ dprintf(1, "ohci init: c=%x h=%p f=%d s=%x\n" + , cntl->regs->control, hcca, hcca->frame_no, cntl->regs->intrstatus); + return 0; }
@@ -322,6 +334,8 @@ wait_ed(struct ohci_ed *ed) void ohci_free_pipe(struct usb_pipe *pipe) { + if (! CONFIG_USB_OHCI) + return; // Add to controller's free list. struct usb_s *cntl = pipe->cntl; pipe->freenext = cntl->freelist; @@ -463,6 +477,7 @@ ohci_alloc_intr_pipe(struct usb_pipe *dummy, int frameexp) if (!pipe || !tds || !data) goto err; memset(pipe, 0, sizeof(*pipe)); + memset(tds, 0, sizeof(*tds) * count); memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe)); pipe->data = data; pipe->count = count; @@ -482,20 +497,33 @@ ohci_alloc_intr_pipe(struct usb_pipe *dummy, int frameexp) }
// Add to interrupt schedule. - barrier(); struct ohci_hcca *hcca = (void*)cntl->regs->hcca; + dprintf(1, "add1: c=%x h=%p f=%d s=%x\n" + , cntl->regs->control, hcca, hcca->frame_no, cntl->regs->intrstatus); if (frameexp == 0) { // Add to existing interrupt entry. struct ohci_ed *intr_ed = (void*)hcca->int_table[0]; ed->hwNextED = intr_ed->hwNextED; + barrier(); intr_ed->hwNextED = (u32)ed; } else { int startpos = 1<<(frameexp-1); ed->hwNextED = hcca->int_table[startpos]; - for (i=startpos; i<ARRAY_SIZE(hcca->int_table); i+=ms) + dprintf(1, "update h=%p s=%d ms=%d ed=%p\n", hcca, startpos, ms, ed); + barrier(); + for (i=startpos; i<ARRAY_SIZE(hcca->int_table); i+=ms) { + dprintf(1, "u i=%d o=%x n=%p\n", i, hcca->int_table[i], ed); hcca->int_table[i] = (u32)ed; + } }
+ msleep(100); + dprintf(1, "add2: c=%x h=%p f=%d s=%x\n" + , cntl->regs->control, hcca, hcca->frame_no, cntl->regs->intrstatus); + for (i=0; i<count; i++) + dprintf(1, "td %d: %08x %08x %08x %08x\n" + , i, tds[i].hwINFO, tds[i].hwCBP, tds[i].hwNextTD, tds[i].hwBE); + return &pipe->pipe;
err: @@ -522,6 +550,9 @@ ohci_poll_intr(struct usb_pipe *p, void *data) if (head == next) // No intrs found. return -1; + dprintf(1, "Got ohci data %d: %08x %08x %08x %08x\n" + , pos, GET_FLATPTR(next->hwINFO), GET_FLATPTR(next->hwCBP) + , GET_FLATPTR(next->hwNextTD), GET_FLATPTR(next->hwBE)); // XXX - check for errors.
// Copy data.