MFC: save and restore the data toggle value when a pipe to an

endpoint is closed and then reopened. This is reported to fix
timeouts with USB scanners and some other USB devices that were
seen since the recent removal of the clear-stall-on-open code.

Approved by:	re (scottl)
This commit is contained in:
iedowse 2006-03-01 01:59:05 +00:00
parent d60341afdc
commit bd3612b266
5 changed files with 12 additions and 3 deletions

View File

@ -1390,7 +1390,7 @@ ehci_open(usbd_pipe_handle pipe)
if (sc->sc_dying) if (sc->sc_dying)
return (USBD_IOERROR); return (USBD_IOERROR);
epipe->nexttoggle = 0; epipe->nexttoggle = pipe->endpoint->savedtoggle;
if (addr == sc->sc_addr) { if (addr == sc->sc_addr) {
switch (ed->bEndpointAddress) { switch (ed->bEndpointAddress) {
@ -2479,6 +2479,8 @@ ehci_close_pipe(usbd_pipe_handle pipe, ehci_soft_qh_t *head)
ehci_rem_qh(sc, sqh, head); ehci_rem_qh(sc, sqh, head);
splx(s); splx(s);
ehci_free_sqh(sc, epipe->sqh); ehci_free_sqh(sc, epipe->sqh);
pipe->endpoint->savedtoggle = epipe->nexttoggle;
} }
/* /*

View File

@ -2161,7 +2161,9 @@ ohci_open(usbd_pipe_handle pipe)
(dev->speed == USB_SPEED_LOW ? OHCI_ED_SPEED : 0) | (dev->speed == USB_SPEED_LOW ? OHCI_ED_SPEED : 0) |
fmt | fmt |
OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize))); OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize)));
sed->ed.ed_headp = sed->ed.ed_tailp = htole32(tdphys); sed->ed.ed_headp = htole32(tdphys |
(pipe->endpoint->savedtoggle ? OHCI_TOGGLECARRY : 0));
sed->ed.ed_tailp = htole32(tdphys);
switch (xfertype) { switch (xfertype) {
case UE_CONTROL: case UE_CONTROL:
@ -2247,6 +2249,8 @@ ohci_close_pipe(usbd_pipe_handle pipe, ohci_soft_ed_t *head)
/* Make sure the host controller is not touching this ED */ /* Make sure the host controller is not touching this ED */
usb_delay_ms(&sc->sc_bus, 1); usb_delay_ms(&sc->sc_bus, 1);
splx(s); splx(s);
pipe->endpoint->savedtoggle =
(le32toh(sed->ed.ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0;
ohci_free_sed(sc, opipe->sed); ohci_free_sed(sc, opipe->sed);
} }

View File

@ -2031,6 +2031,7 @@ uhci_device_bulk_close(usbd_pipe_handle pipe)
uhci_softc_t *sc = (uhci_softc_t *)dev->bus; uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
uhci_free_sqh(sc, upipe->u.bulk.sqh); uhci_free_sqh(sc, upipe->u.bulk.sqh);
pipe->endpoint->savedtoggle = upipe->nexttoggle;
} }
usbd_status usbd_status
@ -2915,7 +2916,7 @@ uhci_open(usbd_pipe_handle pipe)
ed->bEndpointAddress, sc->sc_addr)); ed->bEndpointAddress, sc->sc_addr));
upipe->aborting = 0; upipe->aborting = 0;
upipe->nexttoggle = 0; upipe->nexttoggle = pipe->endpoint->savedtoggle;
if (pipe->device->address == sc->sc_addr) { if (pipe->device->address == sc->sc_addr) {
switch (ed->bEndpointAddress) { switch (ed->bEndpointAddress) {

View File

@ -514,6 +514,7 @@ usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx)
} }
} }
ifc->endpoints[endpt].refcnt = 0; ifc->endpoints[endpt].refcnt = 0;
ifc->endpoints[endpt].savedtoggle = 0;
p += ed->bLength; p += ed->bLength;
} }
#undef ed #undef ed

View File

@ -51,6 +51,7 @@ struct usbd_pipe;
struct usbd_endpoint { struct usbd_endpoint {
usb_endpoint_descriptor_t *edesc; usb_endpoint_descriptor_t *edesc;
int refcnt; int refcnt;
int savedtoggle;
}; };
struct usbd_bus_methods { struct usbd_bus_methods {