From 1d7490cce6aa06997082a2db7e76e173d1c29fc8 Mon Sep 17 00:00:00 2001 From: Nick Hibma Date: Thu, 2 Dec 1999 16:43:18 +0000 Subject: [PATCH] In one queue all the TDs (transfer descriptor, packets) for one transfer are queued. Traverse the queues vertically and then horizontally. This means that TDs for one xfer are transmitted back to back until the first NAK or error condition. Up to now we transmitted a TD per frame and transmitted the next TD in the next frame. The old approach is more fair if you have the end of the queue point at the beginning of the control transfer queue, but also a lot more overhead due to the fact that the QHs have to be read more often. The new approach squirts the packets down the line as fast as possible for one transfer and then does the next one. In the current situation, with fairly empty USB buses, this is a more sensible approach. We might have to revisit the scheduler later however. It speeds up large transfers (Zip drive, Host-To-Host adapters) on UHCI by a factor of 5 and makes it as fast as OHCI on the bus. The next problem to solve is the question why the limit is 300kb/s and not 1000/kb/s (kb == kilobyte). --- sys/dev/usb/uhci.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index 92fd1af9338b..3e5be72b8e64 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -1401,7 +1401,10 @@ uhci_alloc_std_chain(upipe, sc, len, rd, shortok, dma, sp, ep) return (USBD_NOMEM); } p->link.std = lastp; - p->td.td_link = LE(lastlink); + if (lastlink == UHCI_PTR_T) + p->td.td_link = LE(lastlink); + else + p->td.td_link = LE(lastlink|UHCI_PTR_VF); lastp = p; lastlink = p->physaddr; p->td.td_status = LE(status); @@ -1846,7 +1849,7 @@ uhci_device_request(xfer) return (err); next = data; dataend->link.std = stat; - dataend->td.td_link = LE(stat->physaddr); + dataend->td.td_link = LE(stat->physaddr|UHCI_PTR_VF); } else { next = stat; } @@ -1855,7 +1858,7 @@ uhci_device_request(xfer) memcpy(KERNADDR(&upipe->u.ctl.reqdma), req, sizeof *req); setup->link.std = next; - setup->td.td_link = LE(next->physaddr); + setup->td.td_link = LE(next->physaddr|UHCI_PTR_VF); setup->td.td_status = LE(UHCI_TD_SET_ERRCNT(3) | ls | UHCI_TD_ACTIVE); setup->td.td_token = LE(UHCI_TD_SETUP(sizeof *req, endpt, addr)); setup->td.td_buffer = LE(DMAADDR(&upipe->u.ctl.reqdma));