Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dwc_otg: use align_buf for small IN control transfers #3150

Merged
merged 1 commit into from
Aug 14, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions drivers/usb/host/dwc_otg/dwc_otg_hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1182,6 +1182,7 @@ static void assign_and_init_hc(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh)
dwc_otg_qtd_t *qtd;
dwc_otg_hcd_urb_t *urb;
void* ptr = NULL;
uint16_t wLength;
uint32_t intr_enable;
unsigned long flags;
gintmsk_data_t gintmsk = { .d32 = 0, };
Expand Down Expand Up @@ -1293,6 +1294,23 @@ static void assign_and_init_hc(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh)
break;
case DWC_OTG_CONTROL_DATA:
DWC_DEBUGPL(DBG_HCDV, " Control data transaction\n");
/*
* Hardware bug: small IN packets with length < 4
* cause a 4-byte write to memory. We can only catch
* the case where we know a short packet is going to be
* returned in a control transfer, as the length is
* specified in the setup packet. This is only an issue
* for drivers that insist on packing a device's various
* properties into a struct and querying them one at a
* time (uvcvideo).
* Force the use of align_buf so that the subsequent
* memcpy puts the right number of bytes in the URB's
* buffer.
*/
wLength = ((uint16_t *)urb->setup_packet)[3];
if (hc->ep_is_in && wLength < 4)
ptr = hc->xfer_buff;

hc->data_pid_start = qtd->data_toggle;
break;
case DWC_OTG_CONTROL_STATUS:
Expand Down