summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Pascoe <pascoe@cvs.openbsd.org>2006-05-31 06:18:10 +0000
committerChristopher Pascoe <pascoe@cvs.openbsd.org>2006-05-31 06:18:10 +0000
commitbe8822770de6bb641c77d3f517bbf21f1367b51e (patch)
tree268c3490529fc55fcbbb9ca2f3484d673d4cd896
parentda51c4853286e94d057b950343040e002f1f24e4 (diff)
Save and restore the data toggle value when a pipe to an endpoint
is closed and then reopened. This may be necessary now that we no longer clear endpoint stalls every time a pipe is opened. Previously we could assume an initial toggle value of zero because a clear-stall operation resets the device's toggle state. Derived from work in FreeBSD. This is most likely to affect devices like printers, which open pipes for short periods of time and close them again. ok dlg@
-rw-r--r--sys/dev/usb/ehci.c7
-rw-r--r--sys/dev/usb/ohci.c8
-rw-r--r--sys/dev/usb/uhci.c5
-rw-r--r--sys/dev/usb/usb_subr.c3
-rw-r--r--sys/dev/usb/usbdivar.h3
5 files changed, 18 insertions, 8 deletions
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
index 8289d3ade57..9cc6e99af02 100644
--- a/sys/dev/usb/ehci.c
+++ b/sys/dev/usb/ehci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ehci.c,v 1.57 2006/05/30 19:21:07 pascoe Exp $ */
+/* $OpenBSD: ehci.c,v 1.58 2006/05/31 06:18:09 pascoe Exp $ */
/* $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $ */
/*
@@ -1403,7 +1403,8 @@ ehci_open(usbd_pipe_handle pipe)
/* Fill the overlay qTD */
sqh->qh.qh_qtd.qtd_next = EHCI_NULL;
sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
- sqh->qh.qh_qtd.qtd_status = htole32(0);
+ sqh->qh.qh_qtd.qtd_status =
+ htole32(EHCI_QTD_SET_TOGGLE(pipe->endpoint->savedtoggle));
epipe->sqh = sqh;
@@ -2393,6 +2394,8 @@ ehci_close_pipe(usbd_pipe_handle pipe, ehci_soft_qh_t *head)
s = splusb();
ehci_rem_qh(sc, sqh, head);
splx(s);
+ pipe->endpoint->savedtoggle =
+ EHCI_QTD_GET_TOGGLE(le32toh(sqh->qh.qh_qtd.qtd_status));
ehci_free_sqh(sc, epipe->sqh);
}
diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c
index 6af9669043f..fbcc074bf6a 100644
--- a/sys/dev/usb/ohci.c
+++ b/sys/dev/usb/ohci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ohci.c,v 1.71 2006/05/29 03:49:22 pascoe Exp $ */
+/* $OpenBSD: ohci.c,v 1.72 2006/05/31 06:18:09 pascoe Exp $ */
/* $NetBSD: ohci.c,v 1.139 2003/02/22 05:24:16 tsutsui Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
@@ -2047,7 +2047,9 @@ ohci_open(usbd_pipe_handle pipe)
OHCI_ED_SET_EN(UE_GET_ADDR(ed->bEndpointAddress)) |
(dev->speed == USB_SPEED_LOW ? OHCI_ED_SPEED : 0) |
fmt | 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) {
case UE_CONTROL:
@@ -2133,6 +2135,8 @@ ohci_close_pipe(usbd_pipe_handle pipe, ohci_soft_ed_t *head)
/* Make sure the host controller is not touching this ED */
usb_delay_ms(&sc->sc_bus, 1);
splx(s);
+ pipe->endpoint->savedtoggle =
+ (le32toh(sed->ed.ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0;
ohci_free_sed(sc, opipe->sed);
}
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c
index 983cf6c4a09..8ded2cc3deb 100644
--- a/sys/dev/usb/uhci.c
+++ b/sys/dev/usb/uhci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uhci.c,v 1.46 2006/05/29 04:15:49 pascoe Exp $ */
+/* $OpenBSD: uhci.c,v 1.47 2006/05/31 06:18:09 pascoe Exp $ */
/* $NetBSD: uhci.c,v 1.172 2003/02/23 04:19:26 simonb Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
@@ -1985,6 +1985,7 @@ uhci_device_bulk_close(usbd_pipe_handle pipe)
uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
uhci_free_sqh(sc, upipe->u.bulk.sqh);
+ pipe->endpoint->savedtoggle = upipe->nexttoggle;
}
usbd_status
@@ -2858,7 +2859,7 @@ uhci_open(usbd_pipe_handle pipe)
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) {
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c
index 004c1c49134..7e4da9b9017 100644
--- a/sys/dev/usb/usb_subr.c
+++ b/sys/dev/usb/usb_subr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: usb_subr.c,v 1.42 2006/05/01 01:34:10 krw Exp $ */
+/* $OpenBSD: usb_subr.c,v 1.43 2006/05/31 06:18:09 pascoe Exp $ */
/* $NetBSD: usb_subr.c,v 1.103 2003/01/10 11:19:13 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */
@@ -571,6 +571,7 @@ usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx)
}
}
ifc->endpoints[endpt].refcnt = 0;
+ ifc->endpoints[endpt].savedtoggle = 0;
p += ed->bLength;
}
#undef ed
diff --git a/sys/dev/usb/usbdivar.h b/sys/dev/usb/usbdivar.h
index 78136b3462d..a284581b6ab 100644
--- a/sys/dev/usb/usbdivar.h
+++ b/sys/dev/usb/usbdivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: usbdivar.h,v 1.23 2005/03/13 02:54:04 pascoe Exp $ */
+/* $OpenBSD: usbdivar.h,v 1.24 2006/05/31 06:18:09 pascoe Exp $ */
/* $NetBSD: usbdivar.h,v 1.70 2002/07/11 21:14:36 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.11 1999/11/17 22:33:51 n_hibma Exp $ */
@@ -52,6 +52,7 @@ struct usbd_pipe;
struct usbd_endpoint {
usb_endpoint_descriptor_t *edesc;
int refcnt;
+ int savedtoggle;
};
struct usbd_bus_methods {