Current-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Call for testing of ehci(4), ohci(4), slhci(4), uhci(4) data toggle patch
On 2010-04-27, Yorick Hardy wrote:
> On 2010-04-27, Yorick Hardy wrote:
> > On 2010-04-27, Matthias Drochner wrote:
> > >
> > > yorickhardy%gmail.com@localhost said:
> > > > Can you try the patch below?
> > >
> > > I didn't test yet, but wouldn't it look better to avoid the
> > > array which will be used only sparsely, and use some
> > > linked list or so instead? The per-device bitfield could be
> > > put into something device-specific, perhaps close to
> > > the default control pipe.
> >
> > Yes, I had thought to do that. I was looking for an easy
> > solution to make sure that all problems are resolved first.
> >
> > Perhaps the best place is in struct usbd_device?
> > Storing the toggle status here may be misleading
> > since for example uhci and ehci update the toggle
> > after transferring a number of packets, not
> > necessarily for each one, and ohci would only update
> > the toggle status on closing a pipe (assuming the
> > last patch is correct).
>
> Perhaps something like this?
The OpenBSD solution seems better.
I am currently using the patch below.
--
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 14 May 2010 22:56:36 -0000
@@ -1041,7 +1041,7 @@
DLOG(D_TRACE, "slhci_open(addr=%d,ep=%d,rootaddr=%d)",
dev->address, ed->bEndpointAddress, t->rootaddr, 0);
- spipe->pflags = 0;
+ spipe->pflags = (pipe->endpoint->savedtoggle) ? PF_TOGGLE : 0;
spipe->frame = 0;
spipe->lastframe = 0;
spipe->xfer = NULL;
@@ -1279,6 +1279,7 @@
pnames(spipe->ptype), spipe, spipe->xfer, 0);
slhci_lock_call(sc, &slhci_close_pipe, spipe, NULL);
+ pipe->endpoint->savedtoggle = (spipe->pflags & PF_TOGGLE) ? 1 : 0;
}
void
Index: sys/dev/usb/ehci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/ehci.c,v
retrieving revision 1.166
diff -u -r1.166 ehci.c
--- sys/dev/usb/ehci.c 24 Feb 2010 22:38:09 -0000 1.166
+++ sys/dev/usb/ehci.c 14 May 2010 22:57:17 -0000
@@ -1549,7 +1549,7 @@
if (sc->sc_dying)
return (USBD_IOERROR);
- epipe->nexttoggle = 0;
+ epipe->nexttoggle = pipe->endpoint->savedtoggle;
if (addr == sc->sc_addr) {
switch (ed->bEndpointAddress) {
@@ -2823,6 +2823,7 @@
ehci_rem_qh(sc, sqh, head);
splx(s);
ehci_free_sqh(sc, epipe->sqh);
+ pipe->endpoint->savedtoggle = epipe->nexttoggle;
}
/*
@@ -2846,9 +2847,11 @@
ehci_soft_qtd_t *sqtd;
ehci_physaddr_t cur;
u_int32_t qhstatus;
+ u_int32_t nstatus;
int s;
int hit;
int wake;
+ int fixdt;
DPRINTF(("ehci_abort_xfer: xfer=%p pipe=%p\n", xfer, epipe));
@@ -2902,11 +2905,18 @@
sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status),
sizeof(sqh->qh.qh_qtd.qtd_status),
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
- for (sqtd = exfer->sqtdstart; ; sqtd = sqtd->nextqtd) {
+ for (sqtd = exfer->sqtdstart, fixdt = 1; ; sqtd = sqtd->nextqtd) {
usb_syncmem(&sqtd->dma,
sqtd->offs + offsetof(ehci_qtd_t, qtd_status),
sizeof(sqtd->qtd.qtd_status),
BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
+ nstatus = le32toh(sqtd->qtd.qtd_status);
+ if (fixdt && (nstatus & EHCI_QTD_ACTIVE)
+ && ((sqtd != exfer->sqtdend->nextqtd)
+ || EHCI_QTD_GET_BYTES(nstatus))) {
+ epipe->nexttoggle = (EHCI_QTD_GET_TOGGLE(nstatus)) ? 1
: 0;
+ fixdt = 0;
+ }
sqtd->qtd.qtd_status |= htole32(EHCI_QTD_HALTED);
usb_syncmem(&sqtd->dma,
sqtd->offs + offsetof(ehci_qtd_t, qtd_status),
Index: sys/dev/usb/ohci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/ohci.c,v
retrieving revision 1.206
diff -u -r1.206 ohci.c
--- sys/dev/usb/ohci.c 24 Feb 2010 22:38:09 -0000 1.206
+++ sys/dev/usb/ohci.c 14 May 2010 22:57:22 -0000
@@ -2119,6 +2119,10 @@
fmt |
OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize)));
sed->ed.ed_headp = sed->ed.ed_tailp = HTOO32(tdphys);
+ if (pipe->endpoint->savedtoggle) {
+ sed->ed.ed_headp |= HTOO32(OHCI_TOGGLECARRY);
+ sed->ed.ed_tailp |= HTOO32(OHCI_TOGGLECARRY);
+ }
usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
@@ -2206,6 +2210,10 @@
/* Make sure the host controller is not touching this ED */
usb_delay_ms(&sc->sc_bus, 1);
splx(s);
+ if (opipe->sed->ed.ed_headp & HTOO32(OHCI_TOGGLECARRY))
+ pipe->endpoint->savedtoggle = 1;
+ else
+ pipe->endpoint->savedtoggle = 0;
ohci_free_sed(sc, opipe->sed);
}
@@ -3193,6 +3201,10 @@
for (j = 0; j < nslots; j++)
--sc->sc_bws[(pos * nslots + j) % OHCI_NO_INTRS];
+ if (opipe->sed->ed.ed_headp & HTOO32(OHCI_TOGGLECARRY))
+ pipe->endpoint->savedtoggle = 1;
+ else
+ pipe->endpoint->savedtoggle = 0;
ohci_free_std(sc, opipe->tail.td);
ohci_free_sed(sc, opipe->sed);
}
Index: sys/dev/usb/uhci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/uhci.c,v
retrieving revision 1.232
diff -u -r1.232 uhci.c
--- sys/dev/usb/uhci.c 24 Feb 2010 22:38:09 -0000 1.232
+++ sys/dev/usb/uhci.c 14 May 2010 22:57:27 -0000
@@ -2075,8 +2075,10 @@
struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
uhci_softc_t *sc = upipe->pipe.device->bus->hci_private;
uhci_soft_td_t *std;
+ u_int32_t dt;
int s;
int wake;
+ int fixdt;
DPRINTFN(1,("uhci_abort_xfer: xfer=%p, status=%d\n", xfer, status));
@@ -2120,11 +2122,16 @@
xfer->status = status; /* make software ignore it */
usb_uncallout(xfer->timeout_handle, uhci_timeout, ii);
DPRINTFN(1,("uhci_abort_xfer: stop ii=%p\n", ii));
- for (std = ii->stdstart; std != NULL; std = std->link.std) {
+ for (std = ii->stdstart, fixdt = 1; std != NULL; std = std->link.std) {
usb_syncmem(&std->dma,
std->offs + offsetof(uhci_td_t, td_status),
sizeof(std->td.td_status),
BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
+ if (fixdt && (le32toh(std->td.td_status) & UHCI_TD_ACTIVE)) {
+ dt = UHCI_TD_GET_DT(le32toh(std->td.td_token));
+ upipe->nexttoggle = (dt) ? 1 : 0;
+ fixdt = 0;
+ }
std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC));
usb_syncmem(&std->dma,
std->offs + offsetof(uhci_td_t, td_status),
@@ -2175,6 +2182,7 @@
uhci_softc_t *sc = dev->bus->hci_private;
uhci_free_sqh(sc, upipe->u.bulk.sqh);
+ pipe->endpoint->savedtoggle = upipe->nexttoggle;
}
usbd_status
@@ -2372,6 +2380,7 @@
uhci_free_sqh(sc, upipe->u.intr.qhs[i]);
free(upipe->u.intr.qhs, M_USBHC);
+ pipe->endpoint->savedtoggle = upipe->nexttoggle;
/* XXX free other resources */
}
@@ -2784,6 +2793,7 @@
}
splx(s);
+ pipe->endpoint->savedtoggle = upipe->nexttoggle;
free(iso->stds, M_USBHC);
}
@@ -3183,7 +3193,7 @@
ed->bEndpointAddress, sc->sc_addr));
upipe->aborting = 0;
- upipe->nexttoggle = 0;
+ upipe->nexttoggle = pipe->endpoint->savedtoggle;
if (pipe->device->address == sc->sc_addr) {
switch (ed->bEndpointAddress) {
Index: sys/dev/usb/usb_subr.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/usb_subr.c,v
retrieving revision 1.167
diff -u -r1.167 usb_subr.c
--- sys/dev/usb/usb_subr.c 12 Nov 2009 20:11:35 -0000 1.167
+++ sys/dev/usb/usb_subr.c 14 May 2010 22:57:31 -0000
@@ -486,6 +486,7 @@
}
}
ifc->endpoints[endpt].refcnt = 0;
+ ifc->endpoints[endpt].savedtoggle = 0;
p += ed->bLength;
}
#undef ed
Index: sys/dev/usb/usbdivar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/usbdivar.h,v
retrieving revision 1.91
diff -u -r1.91 usbdivar.h
--- sys/dev/usb/usbdivar.h 12 Nov 2009 20:11:35 -0000 1.91
+++ sys/dev/usb/usbdivar.h 14 May 2010 22:57:59 -0000
@@ -46,6 +46,7 @@
struct usbd_endpoint {
usb_endpoint_descriptor_t *edesc;
int refcnt;
+ int savedtoggle;
};
struct usbd_bus_methods {
- References:
- Call for testing of ehci(4), ohci(4), slhci(4), uhci(4) data toggle patch
- Re: Call for testing of ehci(4), ohci(4), slhci(4), uhci(4) data toggle patch
- From: Jonathan A. Kollasch
- Re: Call for testing of ehci(4), ohci(4), slhci(4), uhci(4) data toggle patch
- From: Jonathan A. Kollasch
- Re: Call for testing of ehci(4), ohci(4), slhci(4), uhci(4) data toggle patch
- Re: Call for testing of ehci(4), ohci(4), slhci(4), uhci(4) data toggle patch
- Re: Call for testing of ehci(4), ohci(4), slhci(4), uhci(4) data toggle patch
- Re: Call for testing of ehci(4), ohci(4), slhci(4), uhci(4) data toggle patch
Home |
Main Index |
Thread Index |
Old Index