aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/usb/controller/uss820dci.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/controller/uss820dci.c')
-rw-r--r--sys/dev/usb/controller/uss820dci.c62
1 files changed, 38 insertions, 24 deletions
diff --git a/sys/dev/usb/controller/uss820dci.c b/sys/dev/usb/controller/uss820dci.c
index 8d8e0e431c37..0b0a07411094 100644
--- a/sys/dev/usb/controller/uss820dci.c
+++ b/sys/dev/usb/controller/uss820dci.c
@@ -836,8 +836,8 @@ uss820dci_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 = USS820_DCI_BUS2SC(xfer->xroot->bus);
ep_no = (xfer->endpoint & UE_ADDR);
@@ -851,6 +851,12 @@ uss820dci_setup_standard_chain(struct usb2_xfer *xfer)
temp.len = xfer->frlengths[0];
temp.pc = xfer->frbuffers + 0;
temp.short_pkt = temp.len ? 1 : 0;
+ /* check for last frame */
+ if (xfer->nframes == 1) {
+ /* no STATUS stage yet, SETUP is last */
+ if (xfer->flags_int.control_act)
+ temp.setup_alt_next = 0;
+ }
uss820dci_setup_standard_chain_sub(&temp);
}
@@ -878,7 +884,13 @@ uss820dci_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) {
@@ -903,37 +915,39 @@ uss820dci_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) {
uint8_t need_sync;
- /*
- * Send a DATA1 message and invert the current
- * endpoint direction.
- */
- if (xfer->endpoint & UE_DIR_IN) {
- temp.func = &uss820dci_data_rx;
- need_sync = 0;
- } else {
- temp.func = &uss820dci_data_tx;
- need_sync = 1;
- }
+ /* 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;
- uss820dci_setup_standard_chain_sub(&temp);
- if (need_sync) {
- /* we need a SYNC point after TX */
- temp.func = &uss820dci_data_tx_sync;
+ /* check if we should append a status stage */
+ if (!xfer->flags_int.control_act) {
+
+ /*
+ * Send a DATA1 message and invert the current
+ * endpoint direction.
+ */
+ if (xfer->endpoint & UE_DIR_IN) {
+ temp.func = &uss820dci_data_rx;
+ need_sync = 0;
+ } else {
+ temp.func = &uss820dci_data_tx;
+ need_sync = 1;
+ }
temp.len = 0;
temp.short_pkt = 0;
uss820dci_setup_standard_chain_sub(&temp);
+ if (need_sync) {
+ /* we need a SYNC point after TX */
+ temp.func = &uss820dci_data_tx_sync;
+ uss820dci_setup_standard_chain_sub(&temp);
+ }
}
}
/* must have at least one frame! */