From: Kevin O'Connor Date: Sat, 10 Mar 2012 13:53:58 +0000 (-0500) Subject: usb: Move code around in usb controller code. X-Git-Tag: rel-1.7.0~21 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=6152c32d63a6cf5864274b3056985169be9b60e5;p=seabios.git usb: Move code around in usb controller code. No code changes - just movement of code to place pipe allocater functions next to each other. Signed-off-by: Kevin O'Connor --- diff --git a/src/usb-ehci.c b/src/usb-ehci.c index 477b1cf..67b8450 100644 --- a/src/usb-ehci.c +++ b/src/usb-ehci.c @@ -380,45 +380,80 @@ ehci_init(struct pci_device *pci, int busid, struct pci_device *comppci) * End point communication ****************************************************************/ -static void -ehci_reset_pipe(struct ehci_pipe *pipe) +struct usb_pipe * +ehci_alloc_intr_pipe(struct usbdevice_s *usbdev + , struct usb_endpoint_descriptor *epdesc) { - SET_FLATPTR(pipe->qh.qtd_next, EHCI_PTR_TERM); - SET_FLATPTR(pipe->qh.alt_next, EHCI_PTR_TERM); - barrier(); - SET_FLATPTR(pipe->qh.token, GET_FLATPTR(pipe->qh.token) & QTD_TOGGLE); -} + if (! CONFIG_USB_EHCI) + return NULL; + struct usb_ehci_s *cntl = container_of( + usbdev->hub->cntl, struct usb_ehci_s, usb); + int frameexp = usb_getFrameExp(usbdev, epdesc); + dprintf(7, "ehci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp); -static int -ehci_wait_td(struct ehci_pipe *pipe, struct ehci_qtd *td, int timeout) -{ - u64 end = calc_future_tsc(timeout); - u32 status; - for (;;) { - status = td->token; - if (!(status & QTD_STS_ACTIVE)) - break; - if (check_tsc(end)) { - u32 cur = GET_FLATPTR(pipe->qh.current); - u32 tok = GET_FLATPTR(pipe->qh.token); - u32 next = GET_FLATPTR(pipe->qh.qtd_next); - warn_timeout(); - dprintf(1, "ehci pipe=%p cur=%08x tok=%08x next=%x td=%p status=%x\n" - , pipe, cur, tok, next, td, status); - ehci_reset_pipe(pipe); - struct usb_ehci_s *cntl = container_of( - GET_FLATPTR(pipe->pipe.cntl), struct usb_ehci_s, usb); - ehci_waittick(cntl); - return -1; - } - yield(); + if (frameexp > 10) + frameexp = 10; + int maxpacket = epdesc->wMaxPacketSize; + // Determine number of entries needed for 2 timer ticks. + int ms = 1<pipe, usbdev, epdesc); + pipe->next_td = pipe->tds = tds; + pipe->data = data; + + pipe->qh.info1 = ( + (1 << QH_MULT_SHIFT) + | (maxpacket << QH_MAXPACKET_SHIFT) + | (pipe->pipe.speed << QH_SPEED_SHIFT) + | (pipe->pipe.ep << QH_EP_SHIFT) + | (pipe->pipe.devaddr << QH_DEVADDR_SHIFT)); + pipe->qh.info2 = ((1 << QH_MULT_SHIFT) + | (pipe->pipe.tt_port << QH_HUBPORT_SHIFT) + | (pipe->pipe.tt_devaddr << QH_HUBADDR_SHIFT) + | (0x01 << QH_SMASK_SHIFT) + | (0x1c << QH_CMASK_SHIFT)); + pipe->qh.qtd_next = (u32)tds; + + int i; + for (i=0; iqtd_next = (i==count-1 ? (u32)tds : (u32)&td[1]); + td->alt_next = EHCI_PTR_TERM; + td->token = (ehci_explen(maxpacket) | QTD_STS_ACTIVE + | QTD_PID_IN | ehci_maxerr(3)); + td->buf[0] = (u32)data + maxpacket * i; } - return 0; + + // Add to interrupt schedule. + struct ehci_framelist *fl = (void*)readl(&cntl->regs->periodiclistbase); + if (frameexp == 0) { + // Add to existing interrupt entry. + struct ehci_qh *intr_qh = (void*)(fl->links[0] & ~EHCI_PTR_BITS); + pipe->qh.next = intr_qh->next; + barrier(); + intr_qh->next = (u32)&pipe->qh | EHCI_PTR_QH; + } else { + int startpos = 1<<(frameexp-1); + pipe->qh.next = fl->links[startpos]; + barrier(); + for (i=startpos; ilinks); i+=ms) + fl->links[i] = (u32)&pipe->qh | EHCI_PTR_QH; + } + + return &pipe->pipe; +fail: + free(pipe); + free(tds); + free(data); + return NULL; } struct usb_pipe * @@ -461,6 +496,47 @@ ehci_alloc_async_pipe(struct usbdevice_s *usbdev return &pipe->pipe; } +static void +ehci_reset_pipe(struct ehci_pipe *pipe) +{ + SET_FLATPTR(pipe->qh.qtd_next, EHCI_PTR_TERM); + SET_FLATPTR(pipe->qh.alt_next, EHCI_PTR_TERM); + barrier(); + SET_FLATPTR(pipe->qh.token, GET_FLATPTR(pipe->qh.token) & QTD_TOGGLE); +} + +static int +ehci_wait_td(struct ehci_pipe *pipe, struct ehci_qtd *td, int timeout) +{ + u64 end = calc_future_tsc(timeout); + u32 status; + for (;;) { + status = td->token; + if (!(status & QTD_STS_ACTIVE)) + break; + if (check_tsc(end)) { + u32 cur = GET_FLATPTR(pipe->qh.current); + u32 tok = GET_FLATPTR(pipe->qh.token); + u32 next = GET_FLATPTR(pipe->qh.qtd_next); + warn_timeout(); + dprintf(1, "ehci pipe=%p cur=%08x tok=%08x next=%x td=%p status=%x\n" + , pipe, cur, tok, next, td, status); + ehci_reset_pipe(pipe); + struct usb_ehci_s *cntl = container_of( + GET_FLATPTR(pipe->pipe.cntl), struct usb_ehci_s, usb); + ehci_waittick(cntl); + return -1; + } + yield(); + } + if (status & QTD_STS_HALT) { + dprintf(1, "ehci_wait_td error - status=%x\n", status); + ehci_reset_pipe(pipe); + return -2; + } + return 0; +} + static int fillTDbuffer(struct ehci_qtd *td, u16 maxpacket, const void *buf, int bytes) { @@ -620,82 +696,6 @@ ehci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize) return 0; } -struct usb_pipe * -ehci_alloc_intr_pipe(struct usbdevice_s *usbdev - , struct usb_endpoint_descriptor *epdesc) -{ - if (! CONFIG_USB_EHCI) - return NULL; - struct usb_ehci_s *cntl = container_of( - usbdev->hub->cntl, struct usb_ehci_s, usb); - int frameexp = usb_getFrameExp(usbdev, epdesc); - dprintf(7, "ehci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp); - - if (frameexp > 10) - frameexp = 10; - int maxpacket = epdesc->wMaxPacketSize; - // Determine number of entries needed for 2 timer ticks. - int ms = 1<pipe, usbdev, epdesc); - pipe->next_td = pipe->tds = tds; - pipe->data = data; - - pipe->qh.info1 = ( - (1 << QH_MULT_SHIFT) - | (maxpacket << QH_MAXPACKET_SHIFT) - | (pipe->pipe.speed << QH_SPEED_SHIFT) - | (pipe->pipe.ep << QH_EP_SHIFT) - | (pipe->pipe.devaddr << QH_DEVADDR_SHIFT)); - pipe->qh.info2 = ((1 << QH_MULT_SHIFT) - | (pipe->pipe.tt_port << QH_HUBPORT_SHIFT) - | (pipe->pipe.tt_devaddr << QH_HUBADDR_SHIFT) - | (0x01 << QH_SMASK_SHIFT) - | (0x1c << QH_CMASK_SHIFT)); - pipe->qh.qtd_next = (u32)tds; - - int i; - for (i=0; iqtd_next = (i==count-1 ? (u32)tds : (u32)&td[1]); - td->alt_next = EHCI_PTR_TERM; - td->token = (ehci_explen(maxpacket) | QTD_STS_ACTIVE - | QTD_PID_IN | ehci_maxerr(3)); - td->buf[0] = (u32)data + maxpacket * i; - } - - // Add to interrupt schedule. - struct ehci_framelist *fl = (void*)readl(&cntl->regs->periodiclistbase); - if (frameexp == 0) { - // Add to existing interrupt entry. - struct ehci_qh *intr_qh = (void*)(fl->links[0] & ~EHCI_PTR_BITS); - pipe->qh.next = intr_qh->next; - barrier(); - intr_qh->next = (u32)&pipe->qh | EHCI_PTR_QH; - } else { - int startpos = 1<<(frameexp-1); - pipe->qh.next = fl->links[startpos]; - barrier(); - for (i=startpos; ilinks); i+=ms) - fl->links[i] = (u32)&pipe->qh | EHCI_PTR_QH; - } - - return &pipe->pipe; -fail: - free(pipe); - free(tds); - free(data); - return NULL; -} - int ehci_poll_intr(struct usb_pipe *p, void *data) { diff --git a/src/usb-ohci.c b/src/usb-ohci.c index a012c6c..39ed92a 100644 --- a/src/usb-ohci.c +++ b/src/usb-ohci.c @@ -302,20 +302,71 @@ ohci_init(struct pci_device *pci, int busid) * End point communication ****************************************************************/ -static int -wait_ed(struct ohci_ed *ed) +struct usb_pipe * +ohci_alloc_intr_pipe(struct usbdevice_s *usbdev + , struct usb_endpoint_descriptor *epdesc) { - // XXX - 500ms just a guess - u64 end = calc_future_tsc(500); - for (;;) { - if (ed->hwHeadP == ed->hwTailP) - return 0; - if (check_tsc(end)) { - warn_timeout(); - return -1; - } - yield(); + if (! CONFIG_USB_OHCI) + return NULL; + struct usb_ohci_s *cntl = container_of( + usbdev->hub->cntl, struct usb_ohci_s, usb); + int frameexp = usb_getFrameExp(usbdev, epdesc); + dprintf(7, "ohci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp); + + if (frameexp > 5) + frameexp = 5; + int maxpacket = epdesc->wMaxPacketSize; + // Determine number of entries needed for 2 timer ticks. + int ms = 1<pipe, usbdev, epdesc); + int lowspeed = pipe->pipe.speed; + int devaddr = pipe->pipe.devaddr | (pipe->pipe.ep << 7); + pipe->data = data; + pipe->count = count; + pipe->tds = tds; + + struct ohci_ed *ed = &pipe->ed; + ed->hwHeadP = (u32)&tds[0]; + ed->hwTailP = (u32)&tds[count-1]; + ed->hwINFO = devaddr | (maxpacket << 16) | (lowspeed ? ED_LOWSPEED : 0); + + int i; + for (i=0; iregs->hcca; + if (frameexp == 0) { + // Add to existing interrupt entry. + struct ohci_ed *intr_ed = (void*)hcca->int_table[0]; + ed->hwNextED = intr_ed->hwNextED; + intr_ed->hwNextED = (u32)ed; + } else { + int startpos = 1<<(frameexp-1); + ed->hwNextED = hcca->int_table[startpos]; + for (i=startpos; iint_table); i+=ms) + hcca->int_table[i] = (u32)ed; + } + + return &pipe->pipe; + +err: + free(pipe); + free(tds); + free(data); + return NULL; } struct usb_pipe * @@ -357,6 +408,22 @@ ohci_alloc_async_pipe(struct usbdevice_s *usbdev return &pipe->pipe; } +static int +wait_ed(struct ohci_ed *ed) +{ + // XXX - 500ms just a guess + u64 end = calc_future_tsc(500); + for (;;) { + if (ed->hwHeadP == ed->hwTailP) + return 0; + if (check_tsc(end)) { + warn_timeout(); + return -1; + } + yield(); + } +} + int ohci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize , void *data, int datasize) @@ -424,73 +491,6 @@ ohci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize) return -1; } -struct usb_pipe * -ohci_alloc_intr_pipe(struct usbdevice_s *usbdev - , struct usb_endpoint_descriptor *epdesc) -{ - if (! CONFIG_USB_OHCI) - return NULL; - struct usb_ohci_s *cntl = container_of( - usbdev->hub->cntl, struct usb_ohci_s, usb); - int frameexp = usb_getFrameExp(usbdev, epdesc); - dprintf(7, "ohci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp); - - if (frameexp > 5) - frameexp = 5; - int maxpacket = epdesc->wMaxPacketSize; - // Determine number of entries needed for 2 timer ticks. - int ms = 1<pipe, usbdev, epdesc); - int lowspeed = pipe->pipe.speed; - int devaddr = pipe->pipe.devaddr | (pipe->pipe.ep << 7); - pipe->data = data; - pipe->count = count; - pipe->tds = tds; - - struct ohci_ed *ed = &pipe->ed; - ed->hwHeadP = (u32)&tds[0]; - ed->hwTailP = (u32)&tds[count-1]; - ed->hwINFO = devaddr | (maxpacket << 16) | (lowspeed ? ED_LOWSPEED : 0); - - int i; - for (i=0; iregs->hcca; - if (frameexp == 0) { - // Add to existing interrupt entry. - struct ohci_ed *intr_ed = (void*)hcca->int_table[0]; - ed->hwNextED = intr_ed->hwNextED; - intr_ed->hwNextED = (u32)ed; - } else { - int startpos = 1<<(frameexp-1); - ed->hwNextED = hcca->int_table[startpos]; - for (i=startpos; iint_table); i+=ms) - hcca->int_table[i] = (u32)ed; - } - - return &pipe->pipe; - -err: - free(pipe); - free(tds); - free(data); - return NULL; -} - int ohci_poll_intr(struct usb_pipe *p, void *data) { diff --git a/src/usb-uhci.c b/src/usb-uhci.c index 50d98fc..aa49681 100644 --- a/src/usb-uhci.c +++ b/src/usb-uhci.c @@ -268,28 +268,76 @@ uhci_init(struct pci_device *pci, int busid) * End point communication ****************************************************************/ -static int -wait_pipe(struct uhci_pipe *pipe, int timeout) +struct usb_pipe * +uhci_alloc_intr_pipe(struct usbdevice_s *usbdev + , struct usb_endpoint_descriptor *epdesc) { - 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(); - u16 iobase = GET_FLATPTR(pipe->iobase); - 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(iobase + USBCMD) - , inw(iobase + USBSTS)); - SET_FLATPTR(pipe->qh.element, UHCI_PTR_TERM); - uhci_waittick(iobase); - return -1; - } - yield(); + if (! CONFIG_USB_UHCI) + return NULL; + struct usb_uhci_s *cntl = container_of( + usbdev->hub->cntl, struct usb_uhci_s, usb); + int frameexp = usb_getFrameExp(usbdev, epdesc); + dprintf(7, "uhci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp); + + if (frameexp > 10) + frameexp = 10; + int maxpacket = epdesc->wMaxPacketSize; + // Determine number of entries needed for 2 timer ticks. + int ms = 1<pipe, usbdev, epdesc); + int lowspeed = pipe->pipe.speed; + int devaddr = pipe->pipe.devaddr | (pipe->pipe.ep << 7); + pipe->qh.element = (u32)tds; + pipe->next_td = &tds[0]; + pipe->iobase = cntl->iobase; + + int toggle = 0; + int i; + for (i=0; iframelist; + if (frameexp == 0) { + // Add to existing interrupt entry. + struct uhci_qh *intr_qh = (void*)(fl->links[0] & ~UHCI_PTR_BITS); + pipe->qh.link = intr_qh->link; + barrier(); + intr_qh->link = (u32)&pipe->qh | UHCI_PTR_QH; + if (cntl->control_qh == intr_qh) + cntl->control_qh = &pipe->qh; + } else { + int startpos = 1<<(frameexp-1); + pipe->qh.link = fl->links[startpos]; + barrier(); + for (i=startpos; ilinks); i+=ms) + fl->links[i] = (u32)&pipe->qh | UHCI_PTR_QH; + } + + return &pipe->pipe; +fail: + free(pipe); + free(tds); + free(data); + return NULL; } struct usb_pipe * @@ -335,6 +383,52 @@ uhci_alloc_async_pipe(struct usbdevice_s *usbdev return &pipe->pipe; } +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(); + u16 iobase = GET_FLATPTR(pipe->iobase); + 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(iobase + USBCMD) + , inw(iobase + USBSTS)); + SET_FLATPTR(pipe->qh.element, UHCI_PTR_TERM); + uhci_waittick(iobase); + return -1; + } + yield(); + } +} + +static int +wait_td(struct uhci_td *td) +{ + u64 end = calc_future_tsc(5000); // XXX - lookup real time. + u32 status; + for (;;) { + status = td->status; + if (!(status & TD_CTRL_ACTIVE)) + break; + if (check_tsc(end)) { + warn_timeout(); + return -1; + } + yield(); + } + if (status & TD_CTRL_ANY_ERROR) { + dprintf(1, "wait_td error - status=%x\n", status); + return -2; + } + return 0; +} + int uhci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize , void *data, int datasize) @@ -392,28 +486,6 @@ uhci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize return ret; } -static int -wait_td(struct uhci_td *td) -{ - u64 end = calc_future_tsc(5000); // XXX - lookup real time. - u32 status; - for (;;) { - status = td->status; - if (!(status & TD_CTRL_ACTIVE)) - break; - if (check_tsc(end)) { - warn_timeout(); - return -1; - } - yield(); - } - if (status & TD_CTRL_ANY_ERROR) { - dprintf(1, "wait_td error - status=%x\n", status); - return -2; - } - return 0; -} - #define STACKTDS 4 #define TDALIGN 16 @@ -474,78 +546,6 @@ fail: return -1; } -struct usb_pipe * -uhci_alloc_intr_pipe(struct usbdevice_s *usbdev - , struct usb_endpoint_descriptor *epdesc) -{ - if (! CONFIG_USB_UHCI) - return NULL; - struct usb_uhci_s *cntl = container_of( - usbdev->hub->cntl, struct usb_uhci_s, usb); - int frameexp = usb_getFrameExp(usbdev, epdesc); - dprintf(7, "uhci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp); - - if (frameexp > 10) - frameexp = 10; - int maxpacket = epdesc->wMaxPacketSize; - // Determine number of entries needed for 2 timer ticks. - int ms = 1<pipe, usbdev, epdesc); - int lowspeed = pipe->pipe.speed; - int devaddr = pipe->pipe.devaddr | (pipe->pipe.ep << 7); - pipe->qh.element = (u32)tds; - pipe->next_td = &tds[0]; - pipe->iobase = cntl->iobase; - - int toggle = 0; - int i; - for (i=0; iframelist; - if (frameexp == 0) { - // Add to existing interrupt entry. - struct uhci_qh *intr_qh = (void*)(fl->links[0] & ~UHCI_PTR_BITS); - pipe->qh.link = intr_qh->link; - barrier(); - intr_qh->link = (u32)&pipe->qh | UHCI_PTR_QH; - if (cntl->control_qh == intr_qh) - cntl->control_qh = &pipe->qh; - } else { - int startpos = 1<<(frameexp-1); - pipe->qh.link = fl->links[startpos]; - barrier(); - for (i=startpos; ilinks); i+=ms) - fl->links[i] = (u32)&pipe->qh | UHCI_PTR_QH; - } - - return &pipe->pipe; -fail: - free(pipe); - free(tds); - free(data); - return NULL; -} - int uhci_poll_intr(struct usb_pipe *p, void *data) {