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:
parent
d60341afdc
commit
bd3612b266
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user