Move the code to setup the ehci specific queue head fields to the ehci code. Also, setup the ehci queue head fields once during pipe allocation instead of on each transfer.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/usb-ehci.c | 85 +++++++++++++++++++++++++++----------------------------- src/usb.c | 13 -------- src/usb.h | 2 - 3 files changed, 41 insertions(+), 59 deletions(-)
diff --git a/src/usb-ehci.c b/src/usb-ehci.c index da5ed6f..a99ac35 100644 --- a/src/usb-ehci.c +++ b/src/usb-ehci.c @@ -380,6 +380,40 @@ ehci_init(struct pci_device *pci, int busid, struct pci_device *comppci) * End point communication ****************************************************************/
+// Setup fields in qh +static void +ehci_desc2pipe(struct ehci_pipe *pipe, struct usbdevice_s *usbdev + , struct usb_endpoint_descriptor *epdesc) +{ + usb_desc2pipe(&pipe->pipe, usbdev, epdesc); + + pipe->qh.info1 = ( + (1 << QH_MULT_SHIFT) + | (pipe->pipe.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); + struct usbdevice_s *hubdev = usbdev->hub->usbdev; + if (hubdev) { + struct ehci_pipe *hpipe = container_of( + hubdev->defpipe, struct ehci_pipe, pipe); + if (hpipe->pipe.speed == USB_HIGHSPEED) + pipe->qh.info2 |= ((usbdev->port << QH_HUBPORT_SHIFT) + | (hpipe->pipe.devaddr << QH_HUBADDR_SHIFT)); + else + pipe->qh.info2 = hpipe->qh.info2; + } + + u8 eptype = epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; + if (eptype == USB_ENDPOINT_XFER_CONTROL) + pipe->qh.info1 |= ((pipe->pipe.speed != USB_HIGHSPEED ? QH_CONTROL : 0) + | QH_TOGGLECONTROL); + else if (eptype == USB_ENDPOINT_XFER_INT) + pipe->qh.info2 |= (0x01 << QH_SMASK_SHIFT) | (0x1c << QH_CMASK_SHIFT); +} + static struct usb_pipe * ehci_alloc_intr_pipe(struct usbdevice_s *usbdev , struct usb_endpoint_descriptor *epdesc) @@ -403,21 +437,9 @@ ehci_alloc_intr_pipe(struct usbdevice_s *usbdev goto fail; } memset(pipe, 0, sizeof(*pipe)); - usb_desc2pipe(&pipe->pipe, usbdev, epdesc); + ehci_desc2pipe(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; @@ -470,7 +492,8 @@ ehci_alloc_pipe(struct usbdevice_s *usbdev struct usb_pipe *usbpipe = usb_getFreePipe(&cntl->usb, eptype); if (usbpipe) { // Use previously allocated pipe. - usb_desc2pipe(usbpipe, usbdev, epdesc); + struct ehci_pipe *pipe = container_of(usbpipe, struct ehci_pipe, pipe); + ehci_desc2pipe(pipe, usbdev, epdesc); return usbpipe; }
@@ -485,7 +508,7 @@ ehci_alloc_pipe(struct usbdevice_s *usbdev return NULL; } memset(pipe, 0, sizeof(*pipe)); - usb_desc2pipe(&pipe->pipe, usbdev, epdesc); + ehci_desc2pipe(pipe, usbdev, epdesc); pipe->qh.qtd_next = pipe->qh.alt_next = EHCI_PTR_TERM;
// Add queue head to controller list. @@ -575,21 +598,6 @@ ehci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize } struct ehci_pipe *pipe = container_of(p, struct ehci_pipe, pipe);
- u16 maxpacket = pipe->pipe.maxpacket; - int speed = pipe->pipe.speed; - - // Setup fields in qh - pipe->qh.info1 = ( - (1 << QH_MULT_SHIFT) | (speed != USB_HIGHSPEED ? QH_CONTROL : 0) - | (maxpacket << QH_MAXPACKET_SHIFT) - | QH_TOGGLECONTROL - | (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)); - // Setup transfer descriptors struct ehci_qtd *tds = memalign_tmphigh(EHCI_QTD_ALIGN, sizeof(*tds) * 3); if (!tds) { @@ -603,6 +611,7 @@ ehci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize td->alt_next = EHCI_PTR_TERM; td->token = (ehci_explen(cmdsize) | QTD_STS_ACTIVE | QTD_PID_SETUP | ehci_maxerr(3)); + u16 maxpacket = pipe->pipe.maxpacket; fillTDbuffer(td, maxpacket, cmd, cmdsize); td++;
@@ -645,26 +654,14 @@ ehci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize) dprintf(7, "ehci_send_bulk qh=%p dir=%d data=%p size=%d\n" , &pipe->qh, dir, data, datasize);
- // Allocate 4 tds on stack (16byte aligned) + // Allocate 4 tds on stack (with required alignment) u8 tdsbuf[sizeof(struct ehci_qtd) * STACKQTDS + EHCI_QTD_ALIGN - 1]; struct ehci_qtd *tds = (void*)ALIGN((u32)tdsbuf, EHCI_QTD_ALIGN); memset(tds, 0, sizeof(*tds) * STACKQTDS); - - // Setup fields in qh - u16 maxpacket = GET_FLATPTR(pipe->pipe.maxpacket); - SET_FLATPTR(pipe->qh.info1 - , ((1 << QH_MULT_SHIFT) - | (maxpacket << QH_MAXPACKET_SHIFT) - | (GET_FLATPTR(pipe->pipe.speed) << QH_SPEED_SHIFT) - | (GET_FLATPTR(pipe->pipe.ep) << QH_EP_SHIFT) - | (GET_FLATPTR(pipe->pipe.devaddr) << QH_DEVADDR_SHIFT))); - SET_FLATPTR(pipe->qh.info2 - , ((1 << QH_MULT_SHIFT) - | (GET_FLATPTR(pipe->pipe.tt_port) << QH_HUBPORT_SHIFT) - | (GET_FLATPTR(pipe->pipe.tt_devaddr) << QH_HUBADDR_SHIFT))); barrier(); SET_FLATPTR(pipe->qh.qtd_next, (u32)MAKE_FLATPTR(GET_SEG(SS), tds));
+ u16 maxpacket = GET_FLATPTR(pipe->pipe.maxpacket); int tdpos = 0; while (datasize) { struct ehci_qtd *td = &tds[tdpos++ % STACKQTDS]; diff --git a/src/usb.c b/src/usb.c index 69231d5..aaa2c8e 100644 --- a/src/usb.c +++ b/src/usb.c @@ -140,19 +140,6 @@ usb_desc2pipe(struct usb_pipe *pipe, struct usbdevice_s *usbdev pipe->speed = usbdev->speed; pipe->maxpacket = epdesc->wMaxPacketSize; pipe->eptype = epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; - - struct usbdevice_s *hubdev = usbdev->hub->usbdev; - if (hubdev) { - if (hubdev->defpipe->speed == USB_HIGHSPEED) { - pipe->tt_devaddr = usbdev->devaddr; - pipe->tt_port = usbdev->port; - } else { - pipe->tt_devaddr = hubdev->defpipe->tt_devaddr; - pipe->tt_port = hubdev->defpipe->tt_port; - } - } else { - pipe->tt_devaddr = pipe->tt_port = 0; - } }
// Find the exponential period of the requested interrupt end point. diff --git a/src/usb.h b/src/usb.h index 72f2a7c..2c961e6 100644 --- a/src/usb.h +++ b/src/usb.h @@ -15,8 +15,6 @@ struct usb_pipe { u8 devaddr; u8 speed; u16 maxpacket; - u8 tt_devaddr; - u8 tt_port; u8 eptype; };