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