From: Jonathan Bell Date: Tue, 7 Jan 2020 10:08:19 +0000 (+0000) Subject: dwc_otg: constrain endpoint max packet and transfer size on split IN X-Git-Tag: submit/tizen/20200402.094258~358 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dd1494a4c54ed0bd8c1225457216ebad9467e5a7;p=platform%2Fkernel%2Flinux-rpi.git dwc_otg: constrain endpoint max packet and transfer size on split IN The hcd would unconditionally set the transfer length to the endpoint packet size for non-isoc IN transfers. If the remaining buffer length was less than the length of returned data, random memory would get scribbled over, with bad effects if it crossed a page boundary. Force a babble error if this happens by limiting the max transfer size to the available buffer space. DMA will stop writing to memory on a babble condition. The hardware expects xfersize to be an integer multiple of maxpacket size, so override hcchar.b.mps as well. Signed-off-by: Jonathan Bell --- diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c index 9f2cd51..cba2aa0 100644 --- a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c @@ -1813,7 +1813,7 @@ int fiq_fsm_queue_split_transaction(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh) st->nr_errors = 0; st->hcchar_copy.d32 = 0; - st->hcchar_copy.b.mps = hc->max_packet; + st->hcchar_copy.b.mps = min_t(uint32_t, hc->xfer_len, hc->max_packet); st->hcchar_copy.b.epdir = hc->ep_is_in; st->hcchar_copy.b.devaddr = hc->dev_addr; st->hcchar_copy.b.epnum = hc->ep_num; @@ -1858,7 +1858,7 @@ int fiq_fsm_queue_split_transaction(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh) st->hctsiz_copy.b.pid = hc->data_pid_start; if (hc->ep_is_in || (hc->xfer_len > hc->max_packet)) { - hc->xfer_len = hc->max_packet; + hc->xfer_len = min_t(uint32_t, hc->xfer_len, hc->max_packet); } else if (!hc->ep_is_in && (hc->xfer_len > 188)) { hc->xfer_len = 188; }