summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/controller/musb_otg.c
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2009-03-20 21:57:54 +0000
committerthompsa <thompsa@FreeBSD.org>2009-03-20 21:57:54 +0000
commitca147f2b35e362c05c7b73c7b8b6c6fc58a69744 (patch)
tree6fbd12d5f67db5e9aab7afad8815466e2de7d1f5 /sys/dev/usb/controller/musb_otg.c
parent79c72751b7f97009077ff9f01b67a0794ce358eb (diff)
downloadFreeBSD-src-ca147f2b35e362c05c7b73c7b8b6c6fc58a69744.zip
FreeBSD-src-ca147f2b35e362c05c7b73c7b8b6c6fc58a69744.tar.gz
MFp4 //depot/projects/usb @159479,159502,159516,159522,159529
Workaround for buggy USB hardware not handling new SETUP packet before STATUS stage is complete, this allows xfers to endpoint0 to return a short frame. Submitted by: Hans Petter Selasky Reported by: me
Diffstat (limited to 'sys/dev/usb/controller/musb_otg.c')
-rw-r--r--sys/dev/usb/controller/musb_otg.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/sys/dev/usb/controller/musb_otg.c b/sys/dev/usb/controller/musb_otg.c
index 9ffafa3..6e41bc6 100644
--- a/sys/dev/usb/controller/musb_otg.c
+++ b/sys/dev/usb/controller/musb_otg.c
@@ -1132,8 +1132,8 @@ musbotg_setup_standard_chain(struct usb2_xfer *xfer)
temp.td = NULL;
temp.td_next = xfer->td_start[0];
- temp.setup_alt_next = xfer->flags_int.short_frames_ok;
temp.offset = 0;
+ temp.setup_alt_next = xfer->flags_int.short_frames_ok;
sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
ep_no = (xfer->endpoint & UE_ADDR);
@@ -1180,7 +1180,13 @@ musbotg_setup_standard_chain(struct usb2_xfer *xfer)
x++;
if (x == xfer->nframes) {
- temp.setup_alt_next = 0;
+ if (xfer->flags_int.control_xfr) {
+ if (xfer->flags_int.control_act) {
+ temp.setup_alt_next = 0;
+ }
+ } else {
+ temp.setup_alt_next = 0;
+ }
}
if (temp.len == 0) {
@@ -1205,23 +1211,24 @@ musbotg_setup_standard_chain(struct usb2_xfer *xfer)
}
}
- /* always setup a valid "pc" pointer for status and sync */
- temp.pc = xfer->frbuffers + 0;
-
- /* check if we should append a status stage */
-
- if (xfer->flags_int.control_xfr &&
- !xfer->flags_int.control_act) {
+ /* check for control transfer */
+ if (xfer->flags_int.control_xfr) {
- /*
- * Send a DATA1 message and invert the current
- * endpoint direction.
- */
- temp.func = &musbotg_setup_status;
+ /* always setup a valid "pc" pointer for status and sync */
+ temp.pc = xfer->frbuffers + 0;
temp.len = 0;
temp.short_pkt = 0;
+ temp.setup_alt_next = 0;
- musbotg_setup_standard_chain_sub(&temp);
+ /* check if we should append a status stage */
+ if (!xfer->flags_int.control_act) {
+ /*
+ * Send a DATA1 message and invert the current
+ * endpoint direction.
+ */
+ temp.func = &musbotg_setup_status;
+ musbotg_setup_standard_chain_sub(&temp);
+ }
}
/* must have at least one frame! */
td = temp.td;
OpenPOWER on IntegriCloud