diff options
Diffstat (limited to 'drivers/usb/dwc2/hcd_intr.c')
| -rw-r--r-- | drivers/usb/dwc2/hcd_intr.c | 23 | 
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c index a5dfd9d8bd9a..ed7f05cf4906 100644 --- a/drivers/usb/dwc2/hcd_intr.c +++ b/drivers/usb/dwc2/hcd_intr.c @@ -478,6 +478,12 @@ static u32 dwc2_get_actual_xfer_length(struct dwc2_hsotg *hsotg,   * of the URB based on the number of bytes transferred via the host channel.   * Sets the URB status if the data transfer is finished.   * + * @hsotg: Programming view of the DWC_otg controller + * @chan: Programming view of host channel + * @chnum: Channel number + * @urb: Processing URB + * @qtd: Queue transfer descriptor + *   * Return: 1 if the data transfer specified by the URB is completely finished,   * 0 otherwise   */ @@ -566,6 +572,12 @@ void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg,   * halt_status. Completes the Isochronous URB if all the URB frames have been   * completed.   * + * @hsotg: Programming view of the DWC_otg controller + * @chan: Programming view of host channel + * @chnum: Channel number + * @halt_status: Reason for halting a host channel + * @qtd: Queue transfer descriptor + *   * Return: DWC2_HC_XFER_COMPLETE if there are more frames remaining to be   * transferred in the URB. Otherwise return DWC2_HC_XFER_URB_COMPLETE.   */ @@ -930,14 +942,21 @@ static int dwc2_xfercomp_isoc_split_in(struct dwc2_hsotg *hsotg,  	frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index];  	len = dwc2_get_actual_xfer_length(hsotg, chan, chnum, qtd,  					  DWC2_HC_XFER_COMPLETE, NULL); -	if (!len) { +	if (!len && !qtd->isoc_split_offset) {  		qtd->complete_split = 0; -		qtd->isoc_split_offset = 0;  		return 0;  	}  	frame_desc->actual_length += len; +	if (chan->align_buf) { +		dev_vdbg(hsotg->dev, "non-aligned buffer\n"); +		dma_unmap_single(hsotg->dev, chan->qh->dw_align_buf_dma, +				 DWC2_KMEM_UNALIGNED_BUF_SIZE, DMA_FROM_DEVICE); +		memcpy(qtd->urb->buf + (chan->xfer_dma - qtd->urb->dma), +		       chan->qh->dw_align_buf, len); +	} +  	qtd->isoc_split_offset += len;  	hctsiz = dwc2_readl(hsotg->regs + HCTSIZ(chnum));  |