diff options
author | thompsa <thompsa@FreeBSD.org> | 2009-03-20 21:57:54 +0000 |
---|---|---|
committer | thompsa <thompsa@FreeBSD.org> | 2009-03-20 21:57:54 +0000 |
commit | ca147f2b35e362c05c7b73c7b8b6c6fc58a69744 (patch) | |
tree | 6fbd12d5f67db5e9aab7afad8815466e2de7d1f5 /sys/dev/usb/controller/musb_otg.c | |
parent | 79c72751b7f97009077ff9f01b67a0794ce358eb (diff) | |
download | FreeBSD-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.c | 37 |
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; |