Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/usb Improve EHCI isochronous code, fix scheduling.



details:   https://anonhg.NetBSD.org/src/rev/ff5c4695626d
branches:  trunk
changeset: 755356:ff5c4695626d
user:      jakllsch <jakllsch%NetBSD.org@localhost>
date:      Wed Jun 02 18:53:39 2010 +0000

description:
Improve EHCI isochronous code, fix scheduling.

 - Create and use symbolic constants.

 - Convert some switch statements to functionally-similar caculations.

 - Correct scheduling interval of high-speed isochronous transactions.
   Previous calculation produced half the intended rate.

diffstat:

 sys/dev/usb/ehci.c    |  53 ++++++++++++++++----------------------------------
 sys/dev/usb/ehcireg.h |  10 +++++---
 2 files changed, 23 insertions(+), 40 deletions(-)

diffs (176 lines):

diff -r f5bfc8031c25 -r ff5c4695626d sys/dev/usb/ehci.c
--- a/sys/dev/usb/ehci.c        Wed Jun 02 18:15:35 2010 +0000
+++ b/sys/dev/usb/ehci.c        Wed Jun 02 18:53:39 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ehci.c,v 1.167 2010/05/29 16:52:33 jakllsch Exp $ */
+/*     $NetBSD: ehci.c,v 1.168 2010/06/02 18:53:39 jakllsch Exp $ */
 
 /*
  * Copyright (c) 2004-2008 The NetBSD Foundation, Inc.
@@ -52,7 +52,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.167 2010/05/29 16:52:33 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.168 2010/06/02 18:53:39 jakllsch Exp $");
 
 #include "ohci.h"
 #include "uhci.h"
@@ -811,12 +811,12 @@
                    sizeof(itd->itd.itd_ctl), BUS_DMASYNC_POSTWRITE |
                    BUS_DMASYNC_POSTREAD);
 
-       for (i = 0; i < 8; i++) {
+       for (i = 0; i < EHCI_ITD_NUFRAMES; i++) {
                if (le32toh(itd->itd.itd_ctl[i]) & EHCI_ITD_ACTIVE)
                        break;
        }
 
-       if (i == 8) {
+       if (i == EHCI_ITD_NUFRAMES) {
                goto done; /* All 8 descriptors inactive, it's done */
        }
 
@@ -879,21 +879,15 @@
                nframes = 0;
                actlen = 0;
 
-               switch (xfer->pipe->endpoint->edesc->bInterval) {
-               case 0:
-                       panic("ehci: isoc xfer suddenly has 0 bInterval, invalid\n");
-               case 1: uframes = 1; break;
-               case 2: uframes = 2; break;
-               case 3: uframes = 4; break;
-               default: uframes = 8; break;
-               }
+               i = xfer->pipe->endpoint->edesc->bInterval;
+               uframes = min(1 << (i - 1), USB_UFRAMES_PER_FRAME);
 
                for (itd = ex->itdstart; itd != NULL; itd = itd->xfer_next) {
                        usb_syncmem(&itd->dma,itd->offs + offsetof(ehci_itd_t,itd_ctl),
                            sizeof(itd->itd.itd_ctl), BUS_DMASYNC_POSTWRITE |
                            BUS_DMASYNC_POSTREAD);
 
-                       for (i = 0; i < 8; i += uframes) {
+                       for (i = 0; i < EHCI_ITD_NUFRAMES; i += uframes) {
                                /* XXX - driver didn't fill in the frame full
                                 *   of uframes. This leads to scheduling
                                 *   inefficiencies, but working around
@@ -1483,7 +1477,7 @@
 
        printf("ITD: next phys=%X\n", itd->itd.itd_next);
 
-       for (i = 0; i < 8;i++) {
+       for (i = 0; i < EHCI_ITD_NUFRAMES; i++) {
                t = le32toh(itd->itd.itd_ctl[i]);
                printf("ITDctl %d: stat=%X len=%X ioc=%X pg=%X offs=%X\n", i,
                    EHCI_ITD_GET_STATUS(t), EHCI_ITD_GET_LEN(t),
@@ -1491,7 +1485,7 @@
                    EHCI_ITD_GET_OFFS(t));
        }
        printf("ITDbufr: ");
-       for (i = 0; i < 7; i++)
+       for (i = 0; i < EHCI_ITD_NBUFFERS; i++)
                printf("%X,", EHCI_ITD_GET_BPTR(le32toh(itd->itd.itd_bufr[i])));
 
        b = le32toh(itd->itd.itd_bufr[0]);
@@ -3857,22 +3851,9 @@
                return USBD_INVAL;
        }
 
-       switch (i) {
-       case 1:
-               ufrperframe = 8;
-               break;
-       case 2:
-               ufrperframe = 4;
-               break;
-       case 3:
-               ufrperframe = 2;
-               break;
-       default:
-               ufrperframe = 1;
-               break;
-       }
+       ufrperframe = max(1, USB_UFRAMES_PER_FRAME / (1 << (i - 1)));
        frames = (xfer->nframes + (ufrperframe - 1)) / ufrperframe;
-       uframes = 8 / ufrperframe;
+       uframes = USB_UFRAMES_PER_FRAME / ufrperframe;
 
        if (frames == 0) {
                DPRINTF(("ehci_device_isoc_start: frames == 0\n"));
@@ -3901,7 +3882,7 @@
                /*
                 * Step 1.5, initialize uframes
                 */
-               for (j = 0; j < 8; j += uframes) {
+               for (j = 0; j < EHCI_ITD_NUFRAMES; j += uframes) {
                        /* Calculate which page in the list this starts in */
                        int addr = DMAADDR(dma_buf, froffs);
                        addr = EHCI_PAGE_OFFSET(addr);
@@ -3935,7 +3916,7 @@
                 * and what to not.
                 */
 
-               for (j=0; j < 7; j++) {
+               for (j = 0; j < EHCI_ITD_NBUFFERS; j++) {
                        /*
                         * Don't try to lookup a page that's past the end
                         * of buffer
@@ -4006,12 +3987,12 @@
        if (frindex >= sc->sc_flsize)
                frindex &= (sc->sc_flsize - 1);
 
-       /* Whats the frame interval? */
-       i = (1 << epipe->pipe.endpoint->edesc->bInterval);
-       if (i / 8 == 0)
+       /* What's the frame interval? */
+       i = (1 << (epipe->pipe.endpoint->edesc->bInterval - 1));
+       if (i / USB_UFRAMES_PER_FRAME == 0)
                i = 1;
        else
-               i /= 8;
+               i /= USB_UFRAMES_PER_FRAME;
 
        itd = start;
        for (j = 0; j < frames; j++) {
diff -r f5bfc8031c25 -r ff5c4695626d sys/dev/usb/ehcireg.h
--- a/sys/dev/usb/ehcireg.h     Wed Jun 02 18:15:35 2010 +0000
+++ b/sys/dev/usb/ehcireg.h     Wed Jun 02 18:53:39 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ehcireg.h,v 1.30 2010/05/15 20:47:23 jakllsch Exp $    */
+/*     $NetBSD: ehcireg.h,v 1.31 2010/06/02 18:53:39 jakllsch Exp $    */
 
 /*
  * Copyright (c) 2001, 2004 The NetBSD Foundation, Inc.
@@ -192,9 +192,11 @@
 typedef u_int32_t ehci_isoc_bufr_ptr_t;
 
 /* Isochronous Transfer Descriptor */
+#define EHCI_ITD_NUFRAMES USB_UFRAMES_PER_FRAME
+#define EHCI_ITD_NBUFFERS 7
 typedef struct {
        volatile ehci_link_t            itd_next;
-       volatile ehci_isoc_trans_t      itd_ctl[8];
+       volatile ehci_isoc_trans_t      itd_ctl[EHCI_ITD_NUFRAMES];
 #define EHCI_ITD_GET_STATUS(x) (((x) >> 28) & 0xf)
 #define EHCI_ITD_SET_STATUS(x) (((x) & 0xf) << 28)
 #define EHCI_ITD_ACTIVE                0x80000000
@@ -210,7 +212,7 @@
 #define EHCI_ITD_SET_PG(x) (((x) & 0x7) << 12)
 #define EHCI_ITD_GET_OFFS(x) (((x) >> 0) & 0xfff)
 #define EHCI_ITD_SET_OFFS(x) (((x) & 0xfff) << 0)
-       volatile ehci_isoc_bufr_ptr_t   itd_bufr[7];
+       volatile ehci_isoc_bufr_ptr_t   itd_bufr[EHCI_ITD_NBUFFERS];
 #define EHCI_ITD_GET_BPTR(x) ((x) & 0xfffff000)
 #define EHCI_ITD_SET_BPTR(x) ((x) & 0xfffff000)
 #define EHCI_ITD_GET_EP(x) (((x) >> 8) & 0xf)
@@ -223,7 +225,7 @@
 #define EHCI_ITD_SET_MAXPKT(x) ((x) & 0x7ff)
 #define EHCI_ITD_GET_MULTI(x) ((x) & 0x3)
 #define EHCI_ITD_SET_MULTI(x) ((x) & 0x3)
-       volatile ehci_isoc_bufr_ptr_t   itd_bufr_hi[7];
+       volatile ehci_isoc_bufr_ptr_t   itd_bufr_hi[EHCI_ITD_NBUFFERS];
 } ehci_itd_t;
 #define EHCI_ITD_ALIGN 32
 



Home | Main Index | Thread Index | Old Index