+static int
+wait_pipe(struct uhci_pipe *pipe, int timeout)
+{
+ u64 end = calc_future_tsc(timeout);
+ for (;;) {
+ u32 el_link = GET_FLATPTR(pipe->qh.element);
+ if (el_link & UHCI_PTR_TERM)
+ return 0;
+ if (check_tsc(end)) {
+ warn_timeout();
+ struct uhci_td *td = (void*)(el_link & ~UHCI_PTR_BITS);
+ dprintf(1, "Timeout on wait_pipe %p (td=%p s=%x c=%x/%x)\n"
+ , pipe, (void*)el_link, GET_FLATPTR(td->status)
+ , inw(pipe->iobase + USBCMD)
+ , inw(pipe->iobase + USBSTS));
+ SET_FLATPTR(pipe->qh.element, UHCI_PTR_TERM);
+ uhci_waittick(pipe->iobase);
+ return -1;
+ }
+ yield();
+ }
+}