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
This commit is contained in:
parent
ca147f2b35
commit
e727f71fcf
@ -113,7 +113,6 @@ static const struct usb2_config usb2_control_ep_cfg[USB_DEFAULT_XFER_MAX] = {
|
|||||||
.endpoint = 0x00, /* Control pipe */
|
.endpoint = 0x00, /* Control pipe */
|
||||||
.direction = UE_DIR_ANY,
|
.direction = UE_DIR_ANY,
|
||||||
.mh.bufsize = sizeof(struct usb2_device_request),
|
.mh.bufsize = sizeof(struct usb2_device_request),
|
||||||
.mh.flags = {},
|
|
||||||
.mh.callback = &usb2_do_clear_stall_callback,
|
.mh.callback = &usb2_do_clear_stall_callback,
|
||||||
.mh.timeout = 1000, /* 1 second */
|
.mh.timeout = 1000, /* 1 second */
|
||||||
.mh.interval = 50, /* 50ms */
|
.mh.interval = 50, /* 50ms */
|
||||||
@ -1251,6 +1250,20 @@ usb2_start_hardware_sub(struct usb2_xfer *xfer)
|
|||||||
/* no longer active */
|
/* no longer active */
|
||||||
xfer->flags_int.control_act = 0;
|
xfer->flags_int.control_act = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check for invalid number of frames */
|
||||||
|
if (xfer->nframes > 2) {
|
||||||
|
/*
|
||||||
|
* If you need to split a control transfer, you
|
||||||
|
* have to do one part at a time. Only with
|
||||||
|
* non-control transfers you can do multiple
|
||||||
|
* parts a time.
|
||||||
|
*/
|
||||||
|
DPRINTFN(0, "Too many frames: %u\n",
|
||||||
|
(unsigned int)xfer->nframes);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if there is a control
|
* Check if there is a control
|
||||||
* transfer in progress:
|
* transfer in progress:
|
||||||
@ -1495,23 +1508,28 @@ usb2_start_hardware(struct usb2_xfer *xfer)
|
|||||||
*/
|
*/
|
||||||
if (USB_GET_DATA_ISREAD(xfer)) {
|
if (USB_GET_DATA_ISREAD(xfer)) {
|
||||||
|
|
||||||
if (xfer->flags_int.control_xfr) {
|
if (xfer->flags.short_frames_ok) {
|
||||||
|
xfer->flags_int.short_xfer_ok = 1;
|
||||||
|
xfer->flags_int.short_frames_ok = 1;
|
||||||
|
} else if (xfer->flags.short_xfer_ok) {
|
||||||
|
xfer->flags_int.short_xfer_ok = 1;
|
||||||
|
|
||||||
/*
|
/* check for control transfer */
|
||||||
* Control transfers do not support reception
|
if (xfer->flags_int.control_xfr) {
|
||||||
* of multiple short USB frames !
|
/*
|
||||||
*/
|
* 1) Control transfers do not support
|
||||||
|
* reception of multiple short USB
|
||||||
if (xfer->flags.short_xfer_ok) {
|
* frames in host mode and device side
|
||||||
xfer->flags_int.short_xfer_ok = 1;
|
* mode, with exception of:
|
||||||
}
|
*
|
||||||
} else {
|
* 2) Due to sometimes buggy device
|
||||||
|
* side firmware we need to do a
|
||||||
if (xfer->flags.short_frames_ok) {
|
* STATUS stage in case of short
|
||||||
xfer->flags_int.short_xfer_ok = 1;
|
* control transfers in USB host mode.
|
||||||
|
* The STATUS stage then becomes the
|
||||||
|
* "alt_next" to the DATA stage.
|
||||||
|
*/
|
||||||
xfer->flags_int.short_frames_ok = 1;
|
xfer->flags_int.short_frames_ok = 1;
|
||||||
} else if (xfer->flags.short_xfer_ok) {
|
|
||||||
xfer->flags_int.short_xfer_ok = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2652,7 +2670,6 @@ usb2_clear_data_toggle(struct usb2_device *udev, struct usb2_pipe *pipe)
|
|||||||
* .interval = 50, //50 milliseconds
|
* .interval = 50, //50 milliseconds
|
||||||
* .bufsize = sizeof(struct usb2_device_request),
|
* .bufsize = sizeof(struct usb2_device_request),
|
||||||
* .mh.timeout = 1000, //1.000 seconds
|
* .mh.timeout = 1000, //1.000 seconds
|
||||||
* .mh.flags = { },
|
|
||||||
* .mh.callback = &my_clear_stall_callback, // **
|
* .mh.callback = &my_clear_stall_callback, // **
|
||||||
* };
|
* };
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user