NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/42979 (Data toggle issues in usb(4), slhci(4), uhci(4) and ehci(4))
The slhci patch should use USB_MAX_ENDPOINTS instead of 16.
The patch below should replace the slhci part originally submitted.
I could rewrite it more in the style of the UHCI changes, if that
is preferred.
This patch is still untested (I don't have the hardware).
--
Kind regards,
Yorick Hardy
Index: sys/dev/ic/sl811hs.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/sl811hs.c,v
retrieving revision 1.25
diff -u -r1.25 sl811hs.c
--- sys/dev/ic/sl811hs.c 25 Nov 2009 14:28:50 -0000 1.25
+++ sys/dev/ic/sl811hs.c 16 Mar 2010 23:20:12 -0000
@@ -280,7 +280,7 @@
struct gcq ap; /* All pipes */
struct gcq to; /* Timeout list */
struct gcq xq; /* Xfer queues */
- unsigned int pflags; /* Pipe flags */
+ unsigned int *pflags; /* Pipe flags */
#define PF_GONE (0x01) /* Pipe is on disabled device */
#define PF_TOGGLE (0x02) /* Data toggle status */
#define PF_LS (0x04) /* Pipe is low speed */
@@ -433,6 +433,7 @@
void slhci_freem(struct usbd_bus *, usb_dma_t *);
struct usbd_xfer * slhci_allocx(struct usbd_bus *);
void slhci_freex(struct usbd_bus *, struct usbd_xfer *);
+void slhci_clear_all_toggle(struct usbd_bus *);
usbd_status slhci_transfer(struct usbd_xfer *);
usbd_status slhci_start(struct usbd_xfer *);
@@ -685,6 +686,7 @@
slhci_freem,
slhci_allocx,
slhci_freex,
+ slhci_clear_all_toggle,
};
const struct usbd_pipe_methods slhci_pipe_methods = {
@@ -849,6 +851,15 @@
free(xfer, M_USB);
}
+void slhci_clear_all_toggle(struct usbd_bus *bus)
+{
+ struct slhci_softc *sc = bus->hci_private;
+ int i;
+
+ for (i = 0; i < 32; i++)
+ sc->pflags[i] &= ~PF_TOGGLE;
+}
+
usbd_status
slhci_transfer(struct usbd_xfer *xfer)
{
@@ -923,7 +934,7 @@
spipe->newlen[1] = min(xfer->length, max_packet);
if (spipe->ptype == PT_BULK || spipe->ptype == PT_INTR) {
- if (spipe->pflags & PF_TOGGLE)
+ if (*(spipe->pflags) & PF_TOGGLE)
spipe->control |= SL11_EPCTRL_DATATOGGLE;
spipe->tregs[LEN] = spipe->newlen[1];
if (spipe->tregs[LEN])
@@ -971,10 +982,10 @@
* same place shares constants. Index 0 is "short length" for bulk and
* ctrl data and 1 is "full length" for ctrl data (bulk/intr are
* already set to full length). */
- if (spipe->pflags & PF_LS) {
+ if (*(spipe->pflags) & PF_LS) {
/* Setting PREAMBLE for directly connnected LS devices will
* lock up the chip. */
- if (spipe->pflags & PF_PREAMBLE)
+ if (*(spipe->pflags) & PF_PREAMBLE)
spipe->control |= SL11_EPCTRL_PREAMBLE;
if (max_packet <= 8) {
spipe->bustime = SLHCI_LS_CONST +
@@ -1031,6 +1042,7 @@
usb_endpoint_descriptor_t *ed;
struct slhci_transfers *t;
unsigned int max_packet, pmaxpkt;
+ int epaddr;
dev = pipe->device;
sc = dev->bus->hci_private;
@@ -1041,7 +1053,13 @@
DLOG(D_TRACE, "slhci_open(addr=%d,ep=%d,rootaddr=%d)",
dev->address, ed->bEndpointAddress, t->rootaddr, 0);
- spipe->pflags = 0;
+ epaddr = UE_GET_ADDR(ed->bEndpointAddress);
+ if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT)
+ spipe->pflags = &(sc->pflags[epaddr]);
+ else
+ spipe->pflags = &(sc->pflags[epaddr + USB_MAX_ENDPOINTS]);
+
+ *(spipe->pflags) &= PF_TOGGLE; /* clear all flags except toggle */
spipe->frame = 0;
spipe->lastframe = 0;
spipe->xfer = NULL;
@@ -1058,9 +1076,9 @@
max_packet = UGETW(ed->wMaxPacketSize);
if (dev->speed == USB_SPEED_LOW) {
- spipe->pflags |= PF_LS;
+ *(spipe->pflags) |= PF_LS;
if (dev->myhub->address != t->rootaddr) {
- spipe->pflags |= PF_PREAMBLE;
+ *(spipe->pflags) |= PF_PREAMBLE;
if (!slhci_try_lsvh)
return slhci_lock_call(sc, &slhci_lsvh_warn,
spipe, NULL);
@@ -1291,7 +1309,7 @@
DLOG(D_TRACE, "%s toggle spipe %p", pnames(spipe->ptype),
spipe,0,0);
- spipe->pflags &= ~PF_TOGGLE;
+ *(spipe->pflags) &= ~PF_TOGGLE;
#ifdef DIAGNOSTIC
if (spipe->xfer != NULL) {
@@ -2085,7 +2103,7 @@
status_setup:
/* CTRL_DATA swaps direction in PID then jumps here */
spipe->tregs[LEN] = 0;
- if (spipe->pflags & PF_LS)
+ if (*(spipe->pflags) & PF_LS)
spipe->bustime = SLHCI_LS_CONST;
else
spipe->bustime = SLHCI_FS_CONST;
@@ -2140,9 +2158,9 @@
* current setting will apply to the next
* transfer. */
if (spipe->control & SL11_EPCTRL_DATATOGGLE)
- spipe->pflags |= PF_TOGGLE;
+ *(spipe->pflags) |= PF_TOGGLE;
else
- spipe->pflags &= ~PF_TOGGLE;
+ *(spipe->pflags) &= ~PF_TOGGLE;
head = Q_CALLBACKS;
}
@@ -2373,7 +2391,7 @@
SLHCI_MAINLOCKASSERT(sc);
if (__predict_false(t->flags & F_DISABLED) ||
- __predict_false(spipe->pflags & PF_GONE)) {
+ __predict_false(*(spipe->pflags) & PF_GONE)) {
DLOG(D_MSG, "slhci_enter_xfer: DISABLED or GONE", 0,0,0,0);
spipe->xfer->status = USBD_CANCELLED;
}
@@ -2799,7 +2817,7 @@
/* Cancel all pipes. Note that not all of these may be on the
* callback queue yet; some could be in slhci_start, for example. */
FOREACH_AP(q, t, spipe) {
- spipe->pflags = PF_GONE;
+ *(spipe->pflags) = PF_GONE;
spipe->pipe.repeat = 0;
spipe->pipe.aborting = 1;
if (spipe->xfer != NULL)
@@ -2928,7 +2946,7 @@
t = &sc->sc_transfers;
max_packet = UGETW(spipe->pipe.endpoint->edesc->wMaxPacketSize);
- if (spipe->pflags & PF_LS)
+ if (*(spipe->pflags) & PF_LS)
bustime = SLHCI_LS_CONST + SLHCI_LS_DATA_TIME(max_packet);
else
bustime = SLHCI_FS_CONST + SLHCI_FS_DATA_TIME(max_packet);
@@ -3612,7 +3630,7 @@
"AP" : "", gcq_onlist(&spipe->to) ? "TO" : "",
gcq_onlist(&spipe->xq) ? "XQ" : "");
DDOLOG("spipe: xfer %p buffer %p pflags %#x ptype %s",
- spipe->xfer, spipe->buffer, spipe->pflags, pnames(spipe->ptype));
+ spipe->xfer, spipe->buffer, *(spipe->pflags), pnames(spipe->ptype));
}
void
Index: sys/dev/ic/sl811hsvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/sl811hsvar.h,v
retrieving revision 1.6
diff -u -r1.6 sl811hsvar.h
--- sys/dev/ic/sl811hsvar.h 12 May 2009 14:25:18 -0000 1.6
+++ sys/dev/ic/sl811hsvar.h 16 Mar 2010 23:20:13 -0000
@@ -83,6 +83,8 @@
uint8_t sc_ier; /* enabled interrupts */
uint8_t sc_stride; /* port stride */
+
+ unsigned int pflags[2*USB_MAX_ENDPOINTS]; /* Pipe flags
for each endpoint */
};
/* last preinit arguments are: max current (in mA, not mA/2), port stride */
Home |
Main Index |
Thread Index |
Old Index