| /* | 
 |  * hcd_ddma.c - DesignWare HS OTG Controller descriptor DMA routines | 
 |  * | 
 |  * Copyright (C) 2004-2013 Synopsys, Inc. | 
 |  * | 
 |  * Redistribution and use in source and binary forms, with or without | 
 |  * modification, are permitted provided that the following conditions | 
 |  * are met: | 
 |  * 1. Redistributions of source code must retain the above copyright | 
 |  *    notice, this list of conditions, and the following disclaimer, | 
 |  *    without modification. | 
 |  * 2. Redistributions in binary form must reproduce the above copyright | 
 |  *    notice, this list of conditions and the following disclaimer in the | 
 |  *    documentation and/or other materials provided with the distribution. | 
 |  * 3. The names of the above-listed copyright holders may not be used | 
 |  *    to endorse or promote products derived from this software without | 
 |  *    specific prior written permission. | 
 |  * | 
 |  * ALTERNATIVELY, this software may be distributed under the terms of the | 
 |  * GNU General Public License ("GPL") as published by the Free Software | 
 |  * Foundation; either version 2 of the License, or (at your option) any | 
 |  * later version. | 
 |  * | 
 |  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | 
 |  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | 
 |  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 
 |  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | 
 |  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 
 |  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 
 |  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 
 |  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | 
 |  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | 
 |  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 
 |  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
 |  */ | 
 |  | 
 | /* | 
 |  * This file contains the Descriptor DMA implementation for Host mode | 
 |  */ | 
 | #include <linux/kernel.h> | 
 | #include <linux/module.h> | 
 | #include <linux/spinlock.h> | 
 | #include <linux/interrupt.h> | 
 | #include <linux/dma-mapping.h> | 
 | #include <linux/io.h> | 
 | #include <linux/slab.h> | 
 | #include <linux/usb.h> | 
 |  | 
 | #include <linux/usb/hcd.h> | 
 | #include <linux/usb/ch11.h> | 
 |  | 
 | #include "core.h" | 
 | #include "hcd.h" | 
 |  | 
 | static u16 dwc2_frame_list_idx(u16 frame) | 
 | { | 
 | 	return frame & (FRLISTEN_64_SIZE - 1); | 
 | } | 
 |  | 
 | static u16 dwc2_desclist_idx_inc(u16 idx, u16 inc, u8 speed) | 
 | { | 
 | 	return (idx + inc) & | 
 | 		((speed == USB_SPEED_HIGH ? MAX_DMA_DESC_NUM_HS_ISOC : | 
 | 		  MAX_DMA_DESC_NUM_GENERIC) - 1); | 
 | } | 
 |  | 
 | static u16 dwc2_desclist_idx_dec(u16 idx, u16 inc, u8 speed) | 
 | { | 
 | 	return (idx - inc) & | 
 | 		((speed == USB_SPEED_HIGH ? MAX_DMA_DESC_NUM_HS_ISOC : | 
 | 		  MAX_DMA_DESC_NUM_GENERIC) - 1); | 
 | } | 
 |  | 
 | static u16 dwc2_max_desc_num(struct dwc2_qh *qh) | 
 | { | 
 | 	return (qh->ep_type == USB_ENDPOINT_XFER_ISOC && | 
 | 		qh->dev_speed == USB_SPEED_HIGH) ? | 
 | 		MAX_DMA_DESC_NUM_HS_ISOC : MAX_DMA_DESC_NUM_GENERIC; | 
 | } | 
 |  | 
 | static u16 dwc2_frame_incr_val(struct dwc2_qh *qh) | 
 | { | 
 | 	return qh->dev_speed == USB_SPEED_HIGH ? | 
 | 	       (qh->host_interval + 8 - 1) / 8 : qh->host_interval; | 
 | } | 
 |  | 
 | static int dwc2_desc_list_alloc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, | 
 | 				gfp_t flags) | 
 | { | 
 | 	struct kmem_cache *desc_cache; | 
 |  | 
 | 	if (qh->ep_type == USB_ENDPOINT_XFER_ISOC | 
 | 	    && qh->dev_speed == USB_SPEED_HIGH) | 
 | 		desc_cache = hsotg->desc_hsisoc_cache; | 
 | 	else | 
 | 		desc_cache = hsotg->desc_gen_cache; | 
 |  | 
 | 	qh->desc_list_sz = sizeof(struct dwc2_hcd_dma_desc) * | 
 | 						dwc2_max_desc_num(qh); | 
 |  | 
 | 	qh->desc_list = kmem_cache_zalloc(desc_cache, flags | GFP_DMA); | 
 | 	if (!qh->desc_list) | 
 | 		return -ENOMEM; | 
 |  | 
 | 	qh->desc_list_dma = dma_map_single(hsotg->dev, qh->desc_list, | 
 | 					   qh->desc_list_sz, | 
 | 					   DMA_TO_DEVICE); | 
 |  | 
 | 	qh->n_bytes = kzalloc(sizeof(u32) * dwc2_max_desc_num(qh), flags); | 
 | 	if (!qh->n_bytes) { | 
 | 		dma_unmap_single(hsotg->dev, qh->desc_list_dma, | 
 | 				 qh->desc_list_sz, | 
 | 				 DMA_FROM_DEVICE); | 
 | 		kmem_cache_free(desc_cache, qh->desc_list); | 
 | 		qh->desc_list = NULL; | 
 | 		return -ENOMEM; | 
 | 	} | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | static void dwc2_desc_list_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) | 
 | { | 
 | 	struct kmem_cache *desc_cache; | 
 |  | 
 | 	if (qh->ep_type == USB_ENDPOINT_XFER_ISOC | 
 | 	    && qh->dev_speed == USB_SPEED_HIGH) | 
 | 		desc_cache = hsotg->desc_hsisoc_cache; | 
 | 	else | 
 | 		desc_cache = hsotg->desc_gen_cache; | 
 |  | 
 | 	if (qh->desc_list) { | 
 | 		dma_unmap_single(hsotg->dev, qh->desc_list_dma, | 
 | 				 qh->desc_list_sz, DMA_FROM_DEVICE); | 
 | 		kmem_cache_free(desc_cache, qh->desc_list); | 
 | 		qh->desc_list = NULL; | 
 | 	} | 
 |  | 
 | 	kfree(qh->n_bytes); | 
 | 	qh->n_bytes = NULL; | 
 | } | 
 |  | 
 | static int dwc2_frame_list_alloc(struct dwc2_hsotg *hsotg, gfp_t mem_flags) | 
 | { | 
 | 	if (hsotg->frame_list) | 
 | 		return 0; | 
 |  | 
 | 	hsotg->frame_list_sz = 4 * FRLISTEN_64_SIZE; | 
 | 	hsotg->frame_list = kzalloc(hsotg->frame_list_sz, GFP_ATOMIC | GFP_DMA); | 
 | 	if (!hsotg->frame_list) | 
 | 		return -ENOMEM; | 
 |  | 
 | 	hsotg->frame_list_dma = dma_map_single(hsotg->dev, hsotg->frame_list, | 
 | 					       hsotg->frame_list_sz, | 
 | 					       DMA_TO_DEVICE); | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | static void dwc2_frame_list_free(struct dwc2_hsotg *hsotg) | 
 | { | 
 | 	unsigned long flags; | 
 |  | 
 | 	spin_lock_irqsave(&hsotg->lock, flags); | 
 |  | 
 | 	if (!hsotg->frame_list) { | 
 | 		spin_unlock_irqrestore(&hsotg->lock, flags); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	dma_unmap_single(hsotg->dev, hsotg->frame_list_dma, | 
 | 			 hsotg->frame_list_sz, DMA_FROM_DEVICE); | 
 |  | 
 | 	kfree(hsotg->frame_list); | 
 | 	hsotg->frame_list = NULL; | 
 |  | 
 | 	spin_unlock_irqrestore(&hsotg->lock, flags); | 
 |  | 
 | } | 
 |  | 
 | static void dwc2_per_sched_enable(struct dwc2_hsotg *hsotg, u32 fr_list_en) | 
 | { | 
 | 	u32 hcfg; | 
 | 	unsigned long flags; | 
 |  | 
 | 	spin_lock_irqsave(&hsotg->lock, flags); | 
 |  | 
 | 	hcfg = dwc2_readl(hsotg->regs + HCFG); | 
 | 	if (hcfg & HCFG_PERSCHEDENA) { | 
 | 		/* already enabled */ | 
 | 		spin_unlock_irqrestore(&hsotg->lock, flags); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	dwc2_writel(hsotg->frame_list_dma, hsotg->regs + HFLBADDR); | 
 |  | 
 | 	hcfg &= ~HCFG_FRLISTEN_MASK; | 
 | 	hcfg |= fr_list_en | HCFG_PERSCHEDENA; | 
 | 	dev_vdbg(hsotg->dev, "Enabling Periodic schedule\n"); | 
 | 	dwc2_writel(hcfg, hsotg->regs + HCFG); | 
 |  | 
 | 	spin_unlock_irqrestore(&hsotg->lock, flags); | 
 | } | 
 |  | 
 | static void dwc2_per_sched_disable(struct dwc2_hsotg *hsotg) | 
 | { | 
 | 	u32 hcfg; | 
 | 	unsigned long flags; | 
 |  | 
 | 	spin_lock_irqsave(&hsotg->lock, flags); | 
 |  | 
 | 	hcfg = dwc2_readl(hsotg->regs + HCFG); | 
 | 	if (!(hcfg & HCFG_PERSCHEDENA)) { | 
 | 		/* already disabled */ | 
 | 		spin_unlock_irqrestore(&hsotg->lock, flags); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	hcfg &= ~HCFG_PERSCHEDENA; | 
 | 	dev_vdbg(hsotg->dev, "Disabling Periodic schedule\n"); | 
 | 	dwc2_writel(hcfg, hsotg->regs + HCFG); | 
 |  | 
 | 	spin_unlock_irqrestore(&hsotg->lock, flags); | 
 | } | 
 |  | 
 | /* | 
 |  * Activates/Deactivates FrameList entries for the channel based on endpoint | 
 |  * servicing period | 
 |  */ | 
 | static void dwc2_update_frame_list(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, | 
 | 				   int enable) | 
 | { | 
 | 	struct dwc2_host_chan *chan; | 
 | 	u16 i, j, inc; | 
 |  | 
 | 	if (!hsotg) { | 
 | 		pr_err("hsotg = %p\n", hsotg); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	if (!qh->channel) { | 
 | 		dev_err(hsotg->dev, "qh->channel = %p\n", qh->channel); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	if (!hsotg->frame_list) { | 
 | 		dev_err(hsotg->dev, "hsotg->frame_list = %p\n", | 
 | 			hsotg->frame_list); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	chan = qh->channel; | 
 | 	inc = dwc2_frame_incr_val(qh); | 
 | 	if (qh->ep_type == USB_ENDPOINT_XFER_ISOC) | 
 | 		i = dwc2_frame_list_idx(qh->next_active_frame); | 
 | 	else | 
 | 		i = 0; | 
 |  | 
 | 	j = i; | 
 | 	do { | 
 | 		if (enable) | 
 | 			hsotg->frame_list[j] |= 1 << chan->hc_num; | 
 | 		else | 
 | 			hsotg->frame_list[j] &= ~(1 << chan->hc_num); | 
 | 		j = (j + inc) & (FRLISTEN_64_SIZE - 1); | 
 | 	} while (j != i); | 
 |  | 
 | 	/* | 
 | 	 * Sync frame list since controller will access it if periodic | 
 | 	 * channel is currently enabled. | 
 | 	 */ | 
 | 	dma_sync_single_for_device(hsotg->dev, | 
 | 				   hsotg->frame_list_dma, | 
 | 				   hsotg->frame_list_sz, | 
 | 				   DMA_TO_DEVICE); | 
 |  | 
 | 	if (!enable) | 
 | 		return; | 
 |  | 
 | 	chan->schinfo = 0; | 
 | 	if (chan->speed == USB_SPEED_HIGH && qh->host_interval) { | 
 | 		j = 1; | 
 | 		/* TODO - check this */ | 
 | 		inc = (8 + qh->host_interval - 1) / qh->host_interval; | 
 | 		for (i = 0; i < inc; i++) { | 
 | 			chan->schinfo |= j; | 
 | 			j = j << qh->host_interval; | 
 | 		} | 
 | 	} else { | 
 | 		chan->schinfo = 0xff; | 
 | 	} | 
 | } | 
 |  | 
 | static void dwc2_release_channel_ddma(struct dwc2_hsotg *hsotg, | 
 | 				      struct dwc2_qh *qh) | 
 | { | 
 | 	struct dwc2_host_chan *chan = qh->channel; | 
 |  | 
 | 	if (dwc2_qh_is_non_per(qh)) { | 
 | 		if (hsotg->core_params->uframe_sched > 0) | 
 | 			hsotg->available_host_channels++; | 
 | 		else | 
 | 			hsotg->non_periodic_channels--; | 
 | 	} else { | 
 | 		dwc2_update_frame_list(hsotg, qh, 0); | 
 | 		hsotg->available_host_channels++; | 
 | 	} | 
 |  | 
 | 	/* | 
 | 	 * The condition is added to prevent double cleanup try in case of | 
 | 	 * device disconnect. See channel cleanup in dwc2_hcd_disconnect(). | 
 | 	 */ | 
 | 	if (chan->qh) { | 
 | 		if (!list_empty(&chan->hc_list_entry)) | 
 | 			list_del(&chan->hc_list_entry); | 
 | 		dwc2_hc_cleanup(hsotg, chan); | 
 | 		list_add_tail(&chan->hc_list_entry, &hsotg->free_hc_list); | 
 | 		chan->qh = NULL; | 
 | 	} | 
 |  | 
 | 	qh->channel = NULL; | 
 | 	qh->ntd = 0; | 
 |  | 
 | 	if (qh->desc_list) | 
 | 		memset(qh->desc_list, 0, sizeof(struct dwc2_hcd_dma_desc) * | 
 | 		       dwc2_max_desc_num(qh)); | 
 | } | 
 |  | 
 | /** | 
 |  * dwc2_hcd_qh_init_ddma() - Initializes a QH structure's Descriptor DMA | 
 |  * related members | 
 |  * | 
 |  * @hsotg: The HCD state structure for the DWC OTG controller | 
 |  * @qh:    The QH to init | 
 |  * | 
 |  * Return: 0 if successful, negative error code otherwise | 
 |  * | 
 |  * Allocates memory for the descriptor list. For the first periodic QH, | 
 |  * allocates memory for the FrameList and enables periodic scheduling. | 
 |  */ | 
 | int dwc2_hcd_qh_init_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, | 
 | 			  gfp_t mem_flags) | 
 | { | 
 | 	int retval; | 
 |  | 
 | 	if (qh->do_split) { | 
 | 		dev_err(hsotg->dev, | 
 | 			"SPLIT Transfers are not supported in Descriptor DMA mode.\n"); | 
 | 		retval = -EINVAL; | 
 | 		goto err0; | 
 | 	} | 
 |  | 
 | 	retval = dwc2_desc_list_alloc(hsotg, qh, mem_flags); | 
 | 	if (retval) | 
 | 		goto err0; | 
 |  | 
 | 	if (qh->ep_type == USB_ENDPOINT_XFER_ISOC || | 
 | 	    qh->ep_type == USB_ENDPOINT_XFER_INT) { | 
 | 		if (!hsotg->frame_list) { | 
 | 			retval = dwc2_frame_list_alloc(hsotg, mem_flags); | 
 | 			if (retval) | 
 | 				goto err1; | 
 | 			/* Enable periodic schedule on first periodic QH */ | 
 | 			dwc2_per_sched_enable(hsotg, HCFG_FRLISTEN_64); | 
 | 		} | 
 | 	} | 
 |  | 
 | 	qh->ntd = 0; | 
 | 	return 0; | 
 |  | 
 | err1: | 
 | 	dwc2_desc_list_free(hsotg, qh); | 
 | err0: | 
 | 	return retval; | 
 | } | 
 |  | 
 | /** | 
 |  * dwc2_hcd_qh_free_ddma() - Frees a QH structure's Descriptor DMA related | 
 |  * members | 
 |  * | 
 |  * @hsotg: The HCD state structure for the DWC OTG controller | 
 |  * @qh:    The QH to free | 
 |  * | 
 |  * Frees descriptor list memory associated with the QH. If QH is periodic and | 
 |  * the last, frees FrameList memory and disables periodic scheduling. | 
 |  */ | 
 | void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) | 
 | { | 
 | 	unsigned long flags; | 
 |  | 
 | 	dwc2_desc_list_free(hsotg, qh); | 
 |  | 
 | 	/* | 
 | 	 * Channel still assigned due to some reasons. | 
 | 	 * Seen on Isoc URB dequeue. Channel halted but no subsequent | 
 | 	 * ChHalted interrupt to release the channel. Afterwards | 
 | 	 * when it comes here from endpoint disable routine | 
 | 	 * channel remains assigned. | 
 | 	 */ | 
 | 	spin_lock_irqsave(&hsotg->lock, flags); | 
 | 	if (qh->channel) | 
 | 		dwc2_release_channel_ddma(hsotg, qh); | 
 | 	spin_unlock_irqrestore(&hsotg->lock, flags); | 
 |  | 
 | 	if ((qh->ep_type == USB_ENDPOINT_XFER_ISOC || | 
 | 	     qh->ep_type == USB_ENDPOINT_XFER_INT) && | 
 | 	    (hsotg->core_params->uframe_sched > 0 || | 
 | 	     !hsotg->periodic_channels) && hsotg->frame_list) { | 
 | 		dwc2_per_sched_disable(hsotg); | 
 | 		dwc2_frame_list_free(hsotg); | 
 | 	} | 
 | } | 
 |  | 
 | static u8 dwc2_frame_to_desc_idx(struct dwc2_qh *qh, u16 frame_idx) | 
 | { | 
 | 	if (qh->dev_speed == USB_SPEED_HIGH) | 
 | 		/* Descriptor set (8 descriptors) index which is 8-aligned */ | 
 | 		return (frame_idx & ((MAX_DMA_DESC_NUM_HS_ISOC / 8) - 1)) * 8; | 
 | 	else | 
 | 		return frame_idx & (MAX_DMA_DESC_NUM_GENERIC - 1); | 
 | } | 
 |  | 
 | /* | 
 |  * Determine starting frame for Isochronous transfer. | 
 |  * Few frames skipped to prevent race condition with HC. | 
 |  */ | 
 | static u16 dwc2_calc_starting_frame(struct dwc2_hsotg *hsotg, | 
 | 				    struct dwc2_qh *qh, u16 *skip_frames) | 
 | { | 
 | 	u16 frame; | 
 |  | 
 | 	hsotg->frame_number = dwc2_hcd_get_frame_number(hsotg); | 
 |  | 
 | 	/* | 
 | 	 * next_active_frame is always frame number (not uFrame) both in FS | 
 | 	 * and HS! | 
 | 	 */ | 
 |  | 
 | 	/* | 
 | 	 * skip_frames is used to limit activated descriptors number | 
 | 	 * to avoid the situation when HC services the last activated | 
 | 	 * descriptor firstly. | 
 | 	 * Example for FS: | 
 | 	 * Current frame is 1, scheduled frame is 3. Since HC always fetches | 
 | 	 * the descriptor corresponding to curr_frame+1, the descriptor | 
 | 	 * corresponding to frame 2 will be fetched. If the number of | 
 | 	 * descriptors is max=64 (or greather) the list will be fully programmed | 
 | 	 * with Active descriptors and it is possible case (rare) that the | 
 | 	 * latest descriptor(considering rollback) corresponding to frame 2 will | 
 | 	 * be serviced first. HS case is more probable because, in fact, up to | 
 | 	 * 11 uframes (16 in the code) may be skipped. | 
 | 	 */ | 
 | 	if (qh->dev_speed == USB_SPEED_HIGH) { | 
 | 		/* | 
 | 		 * Consider uframe counter also, to start xfer asap. If half of | 
 | 		 * the frame elapsed skip 2 frames otherwise just 1 frame. | 
 | 		 * Starting descriptor index must be 8-aligned, so if the | 
 | 		 * current frame is near to complete the next one is skipped as | 
 | 		 * well. | 
 | 		 */ | 
 | 		if (dwc2_micro_frame_num(hsotg->frame_number) >= 5) { | 
 | 			*skip_frames = 2 * 8; | 
 | 			frame = dwc2_frame_num_inc(hsotg->frame_number, | 
 | 						   *skip_frames); | 
 | 		} else { | 
 | 			*skip_frames = 1 * 8; | 
 | 			frame = dwc2_frame_num_inc(hsotg->frame_number, | 
 | 						   *skip_frames); | 
 | 		} | 
 |  | 
 | 		frame = dwc2_full_frame_num(frame); | 
 | 	} else { | 
 | 		/* | 
 | 		 * Two frames are skipped for FS - the current and the next. | 
 | 		 * But for descriptor programming, 1 frame (descriptor) is | 
 | 		 * enough, see example above. | 
 | 		 */ | 
 | 		*skip_frames = 1; | 
 | 		frame = dwc2_frame_num_inc(hsotg->frame_number, 2); | 
 | 	} | 
 |  | 
 | 	return frame; | 
 | } | 
 |  | 
 | /* | 
 |  * Calculate initial descriptor index for isochronous transfer based on | 
 |  * scheduled frame | 
 |  */ | 
 | static u16 dwc2_recalc_initial_desc_idx(struct dwc2_hsotg *hsotg, | 
 | 					struct dwc2_qh *qh) | 
 | { | 
 | 	u16 frame, fr_idx, fr_idx_tmp, skip_frames; | 
 |  | 
 | 	/* | 
 | 	 * With current ISOC processing algorithm the channel is being released | 
 | 	 * when no more QTDs in the list (qh->ntd == 0). Thus this function is | 
 | 	 * called only when qh->ntd == 0 and qh->channel == 0. | 
 | 	 * | 
 | 	 * So qh->channel != NULL branch is not used and just not removed from | 
 | 	 * the source file. It is required for another possible approach which | 
 | 	 * is, do not disable and release the channel when ISOC session | 
 | 	 * completed, just move QH to inactive schedule until new QTD arrives. | 
 | 	 * On new QTD, the QH moved back to 'ready' schedule, starting frame and | 
 | 	 * therefore starting desc_index are recalculated. In this case channel | 
 | 	 * is released only on ep_disable. | 
 | 	 */ | 
 |  | 
 | 	/* | 
 | 	 * Calculate starting descriptor index. For INTERRUPT endpoint it is | 
 | 	 * always 0. | 
 | 	 */ | 
 | 	if (qh->channel) { | 
 | 		frame = dwc2_calc_starting_frame(hsotg, qh, &skip_frames); | 
 | 		/* | 
 | 		 * Calculate initial descriptor index based on FrameList current | 
 | 		 * bitmap and servicing period | 
 | 		 */ | 
 | 		fr_idx_tmp = dwc2_frame_list_idx(frame); | 
 | 		fr_idx = (FRLISTEN_64_SIZE + | 
 | 			  dwc2_frame_list_idx(qh->next_active_frame) - | 
 | 			  fr_idx_tmp) % dwc2_frame_incr_val(qh); | 
 | 		fr_idx = (fr_idx + fr_idx_tmp) % FRLISTEN_64_SIZE; | 
 | 	} else { | 
 | 		qh->next_active_frame = dwc2_calc_starting_frame(hsotg, qh, | 
 | 							   &skip_frames); | 
 | 		fr_idx = dwc2_frame_list_idx(qh->next_active_frame); | 
 | 	} | 
 |  | 
 | 	qh->td_first = qh->td_last = dwc2_frame_to_desc_idx(qh, fr_idx); | 
 |  | 
 | 	return skip_frames; | 
 | } | 
 |  | 
 | #define ISOC_URB_GIVEBACK_ASAP | 
 |  | 
 | #define MAX_ISOC_XFER_SIZE_FS	1023 | 
 | #define MAX_ISOC_XFER_SIZE_HS	3072 | 
 | #define DESCNUM_THRESHOLD	4 | 
 |  | 
 | static void dwc2_fill_host_isoc_dma_desc(struct dwc2_hsotg *hsotg, | 
 | 					 struct dwc2_qtd *qtd, | 
 | 					 struct dwc2_qh *qh, u32 max_xfer_size, | 
 | 					 u16 idx) | 
 | { | 
 | 	struct dwc2_hcd_dma_desc *dma_desc = &qh->desc_list[idx]; | 
 | 	struct dwc2_hcd_iso_packet_desc *frame_desc; | 
 |  | 
 | 	memset(dma_desc, 0, sizeof(*dma_desc)); | 
 | 	frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index_last]; | 
 |  | 
 | 	if (frame_desc->length > max_xfer_size) | 
 | 		qh->n_bytes[idx] = max_xfer_size; | 
 | 	else | 
 | 		qh->n_bytes[idx] = frame_desc->length; | 
 |  | 
 | 	dma_desc->buf = (u32)(qtd->urb->dma + frame_desc->offset); | 
 | 	dma_desc->status = qh->n_bytes[idx] << HOST_DMA_ISOC_NBYTES_SHIFT & | 
 | 			   HOST_DMA_ISOC_NBYTES_MASK; | 
 |  | 
 | 	/* Set active bit */ | 
 | 	dma_desc->status |= HOST_DMA_A; | 
 |  | 
 | 	qh->ntd++; | 
 | 	qtd->isoc_frame_index_last++; | 
 |  | 
 | #ifdef ISOC_URB_GIVEBACK_ASAP | 
 | 	/* Set IOC for each descriptor corresponding to last frame of URB */ | 
 | 	if (qtd->isoc_frame_index_last == qtd->urb->packet_count) | 
 | 		dma_desc->status |= HOST_DMA_IOC; | 
 | #endif | 
 |  | 
 | 	dma_sync_single_for_device(hsotg->dev, | 
 | 			qh->desc_list_dma + | 
 | 			(idx * sizeof(struct dwc2_hcd_dma_desc)), | 
 | 			sizeof(struct dwc2_hcd_dma_desc), | 
 | 			DMA_TO_DEVICE); | 
 | } | 
 |  | 
 | static void dwc2_init_isoc_dma_desc(struct dwc2_hsotg *hsotg, | 
 | 				    struct dwc2_qh *qh, u16 skip_frames) | 
 | { | 
 | 	struct dwc2_qtd *qtd; | 
 | 	u32 max_xfer_size; | 
 | 	u16 idx, inc, n_desc = 0, ntd_max = 0; | 
 | 	u16 cur_idx; | 
 | 	u16 next_idx; | 
 |  | 
 | 	idx = qh->td_last; | 
 | 	inc = qh->host_interval; | 
 | 	hsotg->frame_number = dwc2_hcd_get_frame_number(hsotg); | 
 | 	cur_idx = dwc2_frame_list_idx(hsotg->frame_number); | 
 | 	next_idx = dwc2_desclist_idx_inc(qh->td_last, inc, qh->dev_speed); | 
 |  | 
 | 	/* | 
 | 	 * Ensure current frame number didn't overstep last scheduled | 
 | 	 * descriptor. If it happens, the only way to recover is to move | 
 | 	 * qh->td_last to current frame number + 1. | 
 | 	 * So that next isoc descriptor will be scheduled on frame number + 1 | 
 | 	 * and not on a past frame. | 
 | 	 */ | 
 | 	if (dwc2_frame_idx_num_gt(cur_idx, next_idx) || (cur_idx == next_idx)) { | 
 | 		if (inc < 32) { | 
 | 			dev_vdbg(hsotg->dev, | 
 | 				 "current frame number overstep last descriptor\n"); | 
 | 			qh->td_last = dwc2_desclist_idx_inc(cur_idx, inc, | 
 | 							    qh->dev_speed); | 
 | 			idx = qh->td_last; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	if (qh->host_interval) { | 
 | 		ntd_max = (dwc2_max_desc_num(qh) + qh->host_interval - 1) / | 
 | 				qh->host_interval; | 
 | 		if (skip_frames && !qh->channel) | 
 | 			ntd_max -= skip_frames / qh->host_interval; | 
 | 	} | 
 |  | 
 | 	max_xfer_size = qh->dev_speed == USB_SPEED_HIGH ? | 
 | 			MAX_ISOC_XFER_SIZE_HS : MAX_ISOC_XFER_SIZE_FS; | 
 |  | 
 | 	list_for_each_entry(qtd, &qh->qtd_list, qtd_list_entry) { | 
 | 		if (qtd->in_process && | 
 | 		    qtd->isoc_frame_index_last == | 
 | 		    qtd->urb->packet_count) | 
 | 			continue; | 
 |  | 
 | 		qtd->isoc_td_first = idx; | 
 | 		while (qh->ntd < ntd_max && qtd->isoc_frame_index_last < | 
 | 						qtd->urb->packet_count) { | 
 | 			dwc2_fill_host_isoc_dma_desc(hsotg, qtd, qh, | 
 | 						     max_xfer_size, idx); | 
 | 			idx = dwc2_desclist_idx_inc(idx, inc, qh->dev_speed); | 
 | 			n_desc++; | 
 | 		} | 
 | 		qtd->isoc_td_last = idx; | 
 | 		qtd->in_process = 1; | 
 | 	} | 
 |  | 
 | 	qh->td_last = idx; | 
 |  | 
 | #ifdef ISOC_URB_GIVEBACK_ASAP | 
 | 	/* Set IOC for last descriptor if descriptor list is full */ | 
 | 	if (qh->ntd == ntd_max) { | 
 | 		idx = dwc2_desclist_idx_dec(qh->td_last, inc, qh->dev_speed); | 
 | 		qh->desc_list[idx].status |= HOST_DMA_IOC; | 
 | 		dma_sync_single_for_device(hsotg->dev, | 
 | 					   qh->desc_list_dma + (idx * | 
 | 					   sizeof(struct dwc2_hcd_dma_desc)), | 
 | 					   sizeof(struct dwc2_hcd_dma_desc), | 
 | 					   DMA_TO_DEVICE); | 
 | 	} | 
 | #else | 
 | 	/* | 
 | 	 * Set IOC bit only for one descriptor. Always try to be ahead of HW | 
 | 	 * processing, i.e. on IOC generation driver activates next descriptor | 
 | 	 * but core continues to process descriptors following the one with IOC | 
 | 	 * set. | 
 | 	 */ | 
 |  | 
 | 	if (n_desc > DESCNUM_THRESHOLD) | 
 | 		/* | 
 | 		 * Move IOC "up". Required even if there is only one QTD | 
 | 		 * in the list, because QTDs might continue to be queued, | 
 | 		 * but during the activation it was only one queued. | 
 | 		 * Actually more than one QTD might be in the list if this | 
 | 		 * function called from XferCompletion - QTDs was queued during | 
 | 		 * HW processing of the previous descriptor chunk. | 
 | 		 */ | 
 | 		idx = dwc2_desclist_idx_dec(idx, inc * ((qh->ntd + 1) / 2), | 
 | 					    qh->dev_speed); | 
 | 	else | 
 | 		/* | 
 | 		 * Set the IOC for the latest descriptor if either number of | 
 | 		 * descriptors is not greater than threshold or no more new | 
 | 		 * descriptors activated | 
 | 		 */ | 
 | 		idx = dwc2_desclist_idx_dec(qh->td_last, inc, qh->dev_speed); | 
 |  | 
 | 	qh->desc_list[idx].status |= HOST_DMA_IOC; | 
 | 	dma_sync_single_for_device(hsotg->dev, | 
 | 				   qh->desc_list_dma + | 
 | 				   (idx * sizeof(struct dwc2_hcd_dma_desc)), | 
 | 				   sizeof(struct dwc2_hcd_dma_desc), | 
 | 				   DMA_TO_DEVICE); | 
 | #endif | 
 | } | 
 |  | 
 | static void dwc2_fill_host_dma_desc(struct dwc2_hsotg *hsotg, | 
 | 				    struct dwc2_host_chan *chan, | 
 | 				    struct dwc2_qtd *qtd, struct dwc2_qh *qh, | 
 | 				    int n_desc) | 
 | { | 
 | 	struct dwc2_hcd_dma_desc *dma_desc = &qh->desc_list[n_desc]; | 
 | 	int len = chan->xfer_len; | 
 |  | 
 | 	if (len > MAX_DMA_DESC_SIZE - (chan->max_packet - 1)) | 
 | 		len = MAX_DMA_DESC_SIZE - (chan->max_packet - 1); | 
 |  | 
 | 	if (chan->ep_is_in) { | 
 | 		int num_packets; | 
 |  | 
 | 		if (len > 0 && chan->max_packet) | 
 | 			num_packets = (len + chan->max_packet - 1) | 
 | 					/ chan->max_packet; | 
 | 		else | 
 | 			/* Need 1 packet for transfer length of 0 */ | 
 | 			num_packets = 1; | 
 |  | 
 | 		/* Always program an integral # of packets for IN transfers */ | 
 | 		len = num_packets * chan->max_packet; | 
 | 	} | 
 |  | 
 | 	dma_desc->status = len << HOST_DMA_NBYTES_SHIFT & HOST_DMA_NBYTES_MASK; | 
 | 	qh->n_bytes[n_desc] = len; | 
 |  | 
 | 	if (qh->ep_type == USB_ENDPOINT_XFER_CONTROL && | 
 | 	    qtd->control_phase == DWC2_CONTROL_SETUP) | 
 | 		dma_desc->status |= HOST_DMA_SUP; | 
 |  | 
 | 	dma_desc->buf = (u32)chan->xfer_dma; | 
 |  | 
 | 	dma_sync_single_for_device(hsotg->dev, | 
 | 				   qh->desc_list_dma + | 
 | 				   (n_desc * sizeof(struct dwc2_hcd_dma_desc)), | 
 | 				   sizeof(struct dwc2_hcd_dma_desc), | 
 | 				   DMA_TO_DEVICE); | 
 |  | 
 | 	/* | 
 | 	 * Last (or only) descriptor of IN transfer with actual size less | 
 | 	 * than MaxPacket | 
 | 	 */ | 
 | 	if (len > chan->xfer_len) { | 
 | 		chan->xfer_len = 0; | 
 | 	} else { | 
 | 		chan->xfer_dma += len; | 
 | 		chan->xfer_len -= len; | 
 | 	} | 
 | } | 
 |  | 
 | static void dwc2_init_non_isoc_dma_desc(struct dwc2_hsotg *hsotg, | 
 | 					struct dwc2_qh *qh) | 
 | { | 
 | 	struct dwc2_qtd *qtd; | 
 | 	struct dwc2_host_chan *chan = qh->channel; | 
 | 	int n_desc = 0; | 
 |  | 
 | 	dev_vdbg(hsotg->dev, "%s(): qh=%p dma=%08lx len=%d\n", __func__, qh, | 
 | 		 (unsigned long)chan->xfer_dma, chan->xfer_len); | 
 |  | 
 | 	/* | 
 | 	 * Start with chan->xfer_dma initialized in assign_and_init_hc(), then | 
 | 	 * if SG transfer consists of multiple URBs, this pointer is re-assigned | 
 | 	 * to the buffer of the currently processed QTD. For non-SG request | 
 | 	 * there is always one QTD active. | 
 | 	 */ | 
 |  | 
 | 	list_for_each_entry(qtd, &qh->qtd_list, qtd_list_entry) { | 
 | 		dev_vdbg(hsotg->dev, "qtd=%p\n", qtd); | 
 |  | 
 | 		if (n_desc) { | 
 | 			/* SG request - more than 1 QTD */ | 
 | 			chan->xfer_dma = qtd->urb->dma + | 
 | 					qtd->urb->actual_length; | 
 | 			chan->xfer_len = qtd->urb->length - | 
 | 					qtd->urb->actual_length; | 
 | 			dev_vdbg(hsotg->dev, "buf=%08lx len=%d\n", | 
 | 				 (unsigned long)chan->xfer_dma, chan->xfer_len); | 
 | 		} | 
 |  | 
 | 		qtd->n_desc = 0; | 
 | 		do { | 
 | 			if (n_desc > 1) { | 
 | 				qh->desc_list[n_desc - 1].status |= HOST_DMA_A; | 
 | 				dev_vdbg(hsotg->dev, | 
 | 					 "set A bit in desc %d (%p)\n", | 
 | 					 n_desc - 1, | 
 | 					 &qh->desc_list[n_desc - 1]); | 
 | 				dma_sync_single_for_device(hsotg->dev, | 
 | 					qh->desc_list_dma + | 
 | 					((n_desc - 1) * | 
 | 					sizeof(struct dwc2_hcd_dma_desc)), | 
 | 					sizeof(struct dwc2_hcd_dma_desc), | 
 | 					DMA_TO_DEVICE); | 
 | 			} | 
 | 			dwc2_fill_host_dma_desc(hsotg, chan, qtd, qh, n_desc); | 
 | 			dev_vdbg(hsotg->dev, | 
 | 				 "desc %d (%p) buf=%08x status=%08x\n", | 
 | 				 n_desc, &qh->desc_list[n_desc], | 
 | 				 qh->desc_list[n_desc].buf, | 
 | 				 qh->desc_list[n_desc].status); | 
 | 			qtd->n_desc++; | 
 | 			n_desc++; | 
 | 		} while (chan->xfer_len > 0 && | 
 | 			 n_desc != MAX_DMA_DESC_NUM_GENERIC); | 
 |  | 
 | 		dev_vdbg(hsotg->dev, "n_desc=%d\n", n_desc); | 
 | 		qtd->in_process = 1; | 
 | 		if (qh->ep_type == USB_ENDPOINT_XFER_CONTROL) | 
 | 			break; | 
 | 		if (n_desc == MAX_DMA_DESC_NUM_GENERIC) | 
 | 			break; | 
 | 	} | 
 |  | 
 | 	if (n_desc) { | 
 | 		qh->desc_list[n_desc - 1].status |= | 
 | 				HOST_DMA_IOC | HOST_DMA_EOL | HOST_DMA_A; | 
 | 		dev_vdbg(hsotg->dev, "set IOC/EOL/A bits in desc %d (%p)\n", | 
 | 			 n_desc - 1, &qh->desc_list[n_desc - 1]); | 
 | 		dma_sync_single_for_device(hsotg->dev, | 
 | 					   qh->desc_list_dma + (n_desc - 1) * | 
 | 					   sizeof(struct dwc2_hcd_dma_desc), | 
 | 					   sizeof(struct dwc2_hcd_dma_desc), | 
 | 					   DMA_TO_DEVICE); | 
 | 		if (n_desc > 1) { | 
 | 			qh->desc_list[0].status |= HOST_DMA_A; | 
 | 			dev_vdbg(hsotg->dev, "set A bit in desc 0 (%p)\n", | 
 | 				 &qh->desc_list[0]); | 
 | 			dma_sync_single_for_device(hsotg->dev, | 
 | 					qh->desc_list_dma, | 
 | 					sizeof(struct dwc2_hcd_dma_desc), | 
 | 					DMA_TO_DEVICE); | 
 | 		} | 
 | 		chan->ntd = n_desc; | 
 | 	} | 
 | } | 
 |  | 
 | /** | 
 |  * dwc2_hcd_start_xfer_ddma() - Starts a transfer in Descriptor DMA mode | 
 |  * | 
 |  * @hsotg: The HCD state structure for the DWC OTG controller | 
 |  * @qh:    The QH to init | 
 |  * | 
 |  * Return: 0 if successful, negative error code otherwise | 
 |  * | 
 |  * For Control and Bulk endpoints, initializes descriptor list and starts the | 
 |  * transfer. For Interrupt and Isochronous endpoints, initializes descriptor | 
 |  * list then updates FrameList, marking appropriate entries as active. | 
 |  * | 
 |  * For Isochronous endpoints the starting descriptor index is calculated based | 
 |  * on the scheduled frame, but only on the first transfer descriptor within a | 
 |  * session. Then the transfer is started via enabling the channel. | 
 |  * | 
 |  * For Isochronous endpoints the channel is not halted on XferComplete | 
 |  * interrupt so remains assigned to the endpoint(QH) until session is done. | 
 |  */ | 
 | void dwc2_hcd_start_xfer_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) | 
 | { | 
 | 	/* Channel is already assigned */ | 
 | 	struct dwc2_host_chan *chan = qh->channel; | 
 | 	u16 skip_frames = 0; | 
 |  | 
 | 	switch (chan->ep_type) { | 
 | 	case USB_ENDPOINT_XFER_CONTROL: | 
 | 	case USB_ENDPOINT_XFER_BULK: | 
 | 		dwc2_init_non_isoc_dma_desc(hsotg, qh); | 
 | 		dwc2_hc_start_transfer_ddma(hsotg, chan); | 
 | 		break; | 
 | 	case USB_ENDPOINT_XFER_INT: | 
 | 		dwc2_init_non_isoc_dma_desc(hsotg, qh); | 
 | 		dwc2_update_frame_list(hsotg, qh, 1); | 
 | 		dwc2_hc_start_transfer_ddma(hsotg, chan); | 
 | 		break; | 
 | 	case USB_ENDPOINT_XFER_ISOC: | 
 | 		if (!qh->ntd) | 
 | 			skip_frames = dwc2_recalc_initial_desc_idx(hsotg, qh); | 
 | 		dwc2_init_isoc_dma_desc(hsotg, qh, skip_frames); | 
 |  | 
 | 		if (!chan->xfer_started) { | 
 | 			dwc2_update_frame_list(hsotg, qh, 1); | 
 |  | 
 | 			/* | 
 | 			 * Always set to max, instead of actual size. Otherwise | 
 | 			 * ntd will be changed with channel being enabled. Not | 
 | 			 * recommended. | 
 | 			 */ | 
 | 			chan->ntd = dwc2_max_desc_num(qh); | 
 |  | 
 | 			/* Enable channel only once for ISOC */ | 
 | 			dwc2_hc_start_transfer_ddma(hsotg, chan); | 
 | 		} | 
 |  | 
 | 		break; | 
 | 	default: | 
 | 		break; | 
 | 	} | 
 | } | 
 |  | 
 | #define DWC2_CMPL_DONE		1 | 
 | #define DWC2_CMPL_STOP		2 | 
 |  | 
 | static int dwc2_cmpl_host_isoc_dma_desc(struct dwc2_hsotg *hsotg, | 
 | 					struct dwc2_host_chan *chan, | 
 | 					struct dwc2_qtd *qtd, | 
 | 					struct dwc2_qh *qh, u16 idx) | 
 | { | 
 | 	struct dwc2_hcd_dma_desc *dma_desc; | 
 | 	struct dwc2_hcd_iso_packet_desc *frame_desc; | 
 | 	u16 remain = 0; | 
 | 	int rc = 0; | 
 |  | 
 | 	if (!qtd->urb) | 
 | 		return -EINVAL; | 
 |  | 
 | 	dma_sync_single_for_cpu(hsotg->dev, qh->desc_list_dma + (idx * | 
 | 				sizeof(struct dwc2_hcd_dma_desc)), | 
 | 				sizeof(struct dwc2_hcd_dma_desc), | 
 | 				DMA_FROM_DEVICE); | 
 |  | 
 | 	dma_desc = &qh->desc_list[idx]; | 
 |  | 
 | 	frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index_last]; | 
 | 	dma_desc->buf = (u32)(qtd->urb->dma + frame_desc->offset); | 
 | 	if (chan->ep_is_in) | 
 | 		remain = (dma_desc->status & HOST_DMA_ISOC_NBYTES_MASK) >> | 
 | 			 HOST_DMA_ISOC_NBYTES_SHIFT; | 
 |  | 
 | 	if ((dma_desc->status & HOST_DMA_STS_MASK) == HOST_DMA_STS_PKTERR) { | 
 | 		/* | 
 | 		 * XactError, or unable to complete all the transactions | 
 | 		 * in the scheduled micro-frame/frame, both indicated by | 
 | 		 * HOST_DMA_STS_PKTERR | 
 | 		 */ | 
 | 		qtd->urb->error_count++; | 
 | 		frame_desc->actual_length = qh->n_bytes[idx] - remain; | 
 | 		frame_desc->status = -EPROTO; | 
 | 	} else { | 
 | 		/* Success */ | 
 | 		frame_desc->actual_length = qh->n_bytes[idx] - remain; | 
 | 		frame_desc->status = 0; | 
 | 	} | 
 |  | 
 | 	if (++qtd->isoc_frame_index == qtd->urb->packet_count) { | 
 | 		/* | 
 | 		 * urb->status is not used for isoc transfers here. The | 
 | 		 * individual frame_desc status are used instead. | 
 | 		 */ | 
 | 		dwc2_host_complete(hsotg, qtd, 0); | 
 | 		dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); | 
 |  | 
 | 		/* | 
 | 		 * This check is necessary because urb_dequeue can be called | 
 | 		 * from urb complete callback (sound driver for example). All | 
 | 		 * pending URBs are dequeued there, so no need for further | 
 | 		 * processing. | 
 | 		 */ | 
 | 		if (chan->halt_status == DWC2_HC_XFER_URB_DEQUEUE) | 
 | 			return -1; | 
 | 		rc = DWC2_CMPL_DONE; | 
 | 	} | 
 |  | 
 | 	qh->ntd--; | 
 |  | 
 | 	/* Stop if IOC requested descriptor reached */ | 
 | 	if (dma_desc->status & HOST_DMA_IOC) | 
 | 		rc = DWC2_CMPL_STOP; | 
 |  | 
 | 	return rc; | 
 | } | 
 |  | 
 | static void dwc2_complete_isoc_xfer_ddma(struct dwc2_hsotg *hsotg, | 
 | 					 struct dwc2_host_chan *chan, | 
 | 					 enum dwc2_halt_status halt_status) | 
 | { | 
 | 	struct dwc2_hcd_iso_packet_desc *frame_desc; | 
 | 	struct dwc2_qtd *qtd, *qtd_tmp; | 
 | 	struct dwc2_qh *qh; | 
 | 	u16 idx; | 
 | 	int rc; | 
 |  | 
 | 	qh = chan->qh; | 
 | 	idx = qh->td_first; | 
 |  | 
 | 	if (chan->halt_status == DWC2_HC_XFER_URB_DEQUEUE) { | 
 | 		list_for_each_entry(qtd, &qh->qtd_list, qtd_list_entry) | 
 | 			qtd->in_process = 0; | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	if (halt_status == DWC2_HC_XFER_AHB_ERR || | 
 | 	    halt_status == DWC2_HC_XFER_BABBLE_ERR) { | 
 | 		/* | 
 | 		 * Channel is halted in these error cases, considered as serious | 
 | 		 * issues. | 
 | 		 * Complete all URBs marking all frames as failed, irrespective | 
 | 		 * whether some of the descriptors (frames) succeeded or not. | 
 | 		 * Pass error code to completion routine as well, to update | 
 | 		 * urb->status, some of class drivers might use it to stop | 
 | 		 * queing transfer requests. | 
 | 		 */ | 
 | 		int err = halt_status == DWC2_HC_XFER_AHB_ERR ? | 
 | 			  -EIO : -EOVERFLOW; | 
 |  | 
 | 		list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list, | 
 | 					 qtd_list_entry) { | 
 | 			if (qtd->urb) { | 
 | 				for (idx = 0; idx < qtd->urb->packet_count; | 
 | 				     idx++) { | 
 | 					frame_desc = &qtd->urb->iso_descs[idx]; | 
 | 					frame_desc->status = err; | 
 | 				} | 
 |  | 
 | 				dwc2_host_complete(hsotg, qtd, err); | 
 | 			} | 
 |  | 
 | 			dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); | 
 | 		} | 
 |  | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list, qtd_list_entry) { | 
 | 		if (!qtd->in_process) | 
 | 			break; | 
 |  | 
 | 		/* | 
 | 		 * Ensure idx corresponds to descriptor where first urb of this | 
 | 		 * qtd was added. In fact, during isoc desc init, dwc2 may skip | 
 | 		 * an index if current frame number is already over this index. | 
 | 		 */ | 
 | 		if (idx != qtd->isoc_td_first) { | 
 | 			dev_vdbg(hsotg->dev, | 
 | 				 "try to complete %d instead of %d\n", | 
 | 				 idx, qtd->isoc_td_first); | 
 | 			idx = qtd->isoc_td_first; | 
 | 		} | 
 |  | 
 | 		do { | 
 | 			struct dwc2_qtd *qtd_next; | 
 | 			u16 cur_idx; | 
 |  | 
 | 			rc = dwc2_cmpl_host_isoc_dma_desc(hsotg, chan, qtd, qh, | 
 | 							  idx); | 
 | 			if (rc < 0) | 
 | 				return; | 
 | 			idx = dwc2_desclist_idx_inc(idx, qh->host_interval, | 
 | 						    chan->speed); | 
 | 			if (!rc) | 
 | 				continue; | 
 |  | 
 | 			if (rc == DWC2_CMPL_DONE) | 
 | 				break; | 
 |  | 
 | 			/* rc == DWC2_CMPL_STOP */ | 
 |  | 
 | 			if (qh->host_interval >= 32) | 
 | 				goto stop_scan; | 
 |  | 
 | 			qh->td_first = idx; | 
 | 			cur_idx = dwc2_frame_list_idx(hsotg->frame_number); | 
 | 			qtd_next = list_first_entry(&qh->qtd_list, | 
 | 						    struct dwc2_qtd, | 
 | 						    qtd_list_entry); | 
 | 			if (dwc2_frame_idx_num_gt(cur_idx, | 
 | 						  qtd_next->isoc_td_last)) | 
 | 				break; | 
 |  | 
 | 			goto stop_scan; | 
 |  | 
 | 		} while (idx != qh->td_first); | 
 | 	} | 
 |  | 
 | stop_scan: | 
 | 	qh->td_first = idx; | 
 | } | 
 |  | 
 | static int dwc2_update_non_isoc_urb_state_ddma(struct dwc2_hsotg *hsotg, | 
 | 					struct dwc2_host_chan *chan, | 
 | 					struct dwc2_qtd *qtd, | 
 | 					struct dwc2_hcd_dma_desc *dma_desc, | 
 | 					enum dwc2_halt_status halt_status, | 
 | 					u32 n_bytes, int *xfer_done) | 
 | { | 
 | 	struct dwc2_hcd_urb *urb = qtd->urb; | 
 | 	u16 remain = 0; | 
 |  | 
 | 	if (chan->ep_is_in) | 
 | 		remain = (dma_desc->status & HOST_DMA_NBYTES_MASK) >> | 
 | 			 HOST_DMA_NBYTES_SHIFT; | 
 |  | 
 | 	dev_vdbg(hsotg->dev, "remain=%d dwc2_urb=%p\n", remain, urb); | 
 |  | 
 | 	if (halt_status == DWC2_HC_XFER_AHB_ERR) { | 
 | 		dev_err(hsotg->dev, "EIO\n"); | 
 | 		urb->status = -EIO; | 
 | 		return 1; | 
 | 	} | 
 |  | 
 | 	if ((dma_desc->status & HOST_DMA_STS_MASK) == HOST_DMA_STS_PKTERR) { | 
 | 		switch (halt_status) { | 
 | 		case DWC2_HC_XFER_STALL: | 
 | 			dev_vdbg(hsotg->dev, "Stall\n"); | 
 | 			urb->status = -EPIPE; | 
 | 			break; | 
 | 		case DWC2_HC_XFER_BABBLE_ERR: | 
 | 			dev_err(hsotg->dev, "Babble\n"); | 
 | 			urb->status = -EOVERFLOW; | 
 | 			break; | 
 | 		case DWC2_HC_XFER_XACT_ERR: | 
 | 			dev_err(hsotg->dev, "XactErr\n"); | 
 | 			urb->status = -EPROTO; | 
 | 			break; | 
 | 		default: | 
 | 			dev_err(hsotg->dev, | 
 | 				"%s: Unhandled descriptor error status (%d)\n", | 
 | 				__func__, halt_status); | 
 | 			break; | 
 | 		} | 
 | 		return 1; | 
 | 	} | 
 |  | 
 | 	if (dma_desc->status & HOST_DMA_A) { | 
 | 		dev_vdbg(hsotg->dev, | 
 | 			 "Active descriptor encountered on channel %d\n", | 
 | 			 chan->hc_num); | 
 | 		return 0; | 
 | 	} | 
 |  | 
 | 	if (chan->ep_type == USB_ENDPOINT_XFER_CONTROL) { | 
 | 		if (qtd->control_phase == DWC2_CONTROL_DATA) { | 
 | 			urb->actual_length += n_bytes - remain; | 
 | 			if (remain || urb->actual_length >= urb->length) { | 
 | 				/* | 
 | 				 * For Control Data stage do not set urb->status | 
 | 				 * to 0, to prevent URB callback. Set it when | 
 | 				 * Status phase is done. See below. | 
 | 				 */ | 
 | 				*xfer_done = 1; | 
 | 			} | 
 | 		} else if (qtd->control_phase == DWC2_CONTROL_STATUS) { | 
 | 			urb->status = 0; | 
 | 			*xfer_done = 1; | 
 | 		} | 
 | 		/* No handling for SETUP stage */ | 
 | 	} else { | 
 | 		/* BULK and INTR */ | 
 | 		urb->actual_length += n_bytes - remain; | 
 | 		dev_vdbg(hsotg->dev, "length=%d actual=%d\n", urb->length, | 
 | 			 urb->actual_length); | 
 | 		if (remain || urb->actual_length >= urb->length) { | 
 | 			urb->status = 0; | 
 | 			*xfer_done = 1; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | static int dwc2_process_non_isoc_desc(struct dwc2_hsotg *hsotg, | 
 | 				      struct dwc2_host_chan *chan, | 
 | 				      int chnum, struct dwc2_qtd *qtd, | 
 | 				      int desc_num, | 
 | 				      enum dwc2_halt_status halt_status, | 
 | 				      int *xfer_done) | 
 | { | 
 | 	struct dwc2_qh *qh = chan->qh; | 
 | 	struct dwc2_hcd_urb *urb = qtd->urb; | 
 | 	struct dwc2_hcd_dma_desc *dma_desc; | 
 | 	u32 n_bytes; | 
 | 	int failed; | 
 |  | 
 | 	dev_vdbg(hsotg->dev, "%s()\n", __func__); | 
 |  | 
 | 	if (!urb) | 
 | 		return -EINVAL; | 
 |  | 
 | 	dma_sync_single_for_cpu(hsotg->dev, | 
 | 				qh->desc_list_dma + (desc_num * | 
 | 				sizeof(struct dwc2_hcd_dma_desc)), | 
 | 				sizeof(struct dwc2_hcd_dma_desc), | 
 | 				DMA_FROM_DEVICE); | 
 |  | 
 | 	dma_desc = &qh->desc_list[desc_num]; | 
 | 	n_bytes = qh->n_bytes[desc_num]; | 
 | 	dev_vdbg(hsotg->dev, | 
 | 		 "qtd=%p dwc2_urb=%p desc_num=%d desc=%p n_bytes=%d\n", | 
 | 		 qtd, urb, desc_num, dma_desc, n_bytes); | 
 | 	failed = dwc2_update_non_isoc_urb_state_ddma(hsotg, chan, qtd, dma_desc, | 
 | 						     halt_status, n_bytes, | 
 | 						     xfer_done); | 
 | 	if (failed || (*xfer_done && urb->status != -EINPROGRESS)) { | 
 | 		dwc2_host_complete(hsotg, qtd, urb->status); | 
 | 		dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); | 
 | 		dev_vdbg(hsotg->dev, "failed=%1x xfer_done=%1x\n", | 
 | 			 failed, *xfer_done); | 
 | 		return failed; | 
 | 	} | 
 |  | 
 | 	if (qh->ep_type == USB_ENDPOINT_XFER_CONTROL) { | 
 | 		switch (qtd->control_phase) { | 
 | 		case DWC2_CONTROL_SETUP: | 
 | 			if (urb->length > 0) | 
 | 				qtd->control_phase = DWC2_CONTROL_DATA; | 
 | 			else | 
 | 				qtd->control_phase = DWC2_CONTROL_STATUS; | 
 | 			dev_vdbg(hsotg->dev, | 
 | 				 "  Control setup transaction done\n"); | 
 | 			break; | 
 | 		case DWC2_CONTROL_DATA: | 
 | 			if (*xfer_done) { | 
 | 				qtd->control_phase = DWC2_CONTROL_STATUS; | 
 | 				dev_vdbg(hsotg->dev, | 
 | 					 "  Control data transfer done\n"); | 
 | 			} else if (desc_num + 1 == qtd->n_desc) { | 
 | 				/* | 
 | 				 * Last descriptor for Control data stage which | 
 | 				 * is not completed yet | 
 | 				 */ | 
 | 				dwc2_hcd_save_data_toggle(hsotg, chan, chnum, | 
 | 							  qtd); | 
 | 			} | 
 | 			break; | 
 | 		default: | 
 | 			break; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | static void dwc2_complete_non_isoc_xfer_ddma(struct dwc2_hsotg *hsotg, | 
 | 					     struct dwc2_host_chan *chan, | 
 | 					     int chnum, | 
 | 					     enum dwc2_halt_status halt_status) | 
 | { | 
 | 	struct list_head *qtd_item, *qtd_tmp; | 
 | 	struct dwc2_qh *qh = chan->qh; | 
 | 	struct dwc2_qtd *qtd = NULL; | 
 | 	int xfer_done; | 
 | 	int desc_num = 0; | 
 |  | 
 | 	if (chan->halt_status == DWC2_HC_XFER_URB_DEQUEUE) { | 
 | 		list_for_each_entry(qtd, &qh->qtd_list, qtd_list_entry) | 
 | 			qtd->in_process = 0; | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	list_for_each_safe(qtd_item, qtd_tmp, &qh->qtd_list) { | 
 | 		int i; | 
 | 		int qtd_desc_count; | 
 |  | 
 | 		qtd = list_entry(qtd_item, struct dwc2_qtd, qtd_list_entry); | 
 | 		xfer_done = 0; | 
 | 		qtd_desc_count = qtd->n_desc; | 
 |  | 
 | 		for (i = 0; i < qtd_desc_count; i++) { | 
 | 			if (dwc2_process_non_isoc_desc(hsotg, chan, chnum, qtd, | 
 | 						       desc_num, halt_status, | 
 | 						       &xfer_done)) { | 
 | 				qtd = NULL; | 
 | 				goto stop_scan; | 
 | 			} | 
 |  | 
 | 			desc_num++; | 
 | 		} | 
 | 	} | 
 |  | 
 | stop_scan: | 
 | 	if (qh->ep_type != USB_ENDPOINT_XFER_CONTROL) { | 
 | 		/* | 
 | 		 * Resetting the data toggle for bulk and interrupt endpoints | 
 | 		 * in case of stall. See handle_hc_stall_intr(). | 
 | 		 */ | 
 | 		if (halt_status == DWC2_HC_XFER_STALL) | 
 | 			qh->data_toggle = DWC2_HC_PID_DATA0; | 
 | 		else | 
 | 			dwc2_hcd_save_data_toggle(hsotg, chan, chnum, NULL); | 
 | 	} | 
 |  | 
 | 	if (halt_status == DWC2_HC_XFER_COMPLETE) { | 
 | 		if (chan->hcint & HCINTMSK_NYET) { | 
 | 			/* | 
 | 			 * Got a NYET on the last transaction of the transfer. | 
 | 			 * It means that the endpoint should be in the PING | 
 | 			 * state at the beginning of the next transfer. | 
 | 			 */ | 
 | 			qh->ping_state = 1; | 
 | 		} | 
 | 	} | 
 | } | 
 |  | 
 | /** | 
 |  * dwc2_hcd_complete_xfer_ddma() - Scans the descriptor list, updates URB's | 
 |  * status and calls completion routine for the URB if it's done. Called from | 
 |  * interrupt handlers. | 
 |  * | 
 |  * @hsotg:       The HCD state structure for the DWC OTG controller | 
 |  * @chan:        Host channel the transfer is completed on | 
 |  * @chnum:       Index of Host channel registers | 
 |  * @halt_status: Reason the channel is being halted or just XferComplete | 
 |  *               for isochronous transfers | 
 |  * | 
 |  * Releases the channel to be used by other transfers. | 
 |  * In case of Isochronous endpoint the channel is not halted until the end of | 
 |  * the session, i.e. QTD list is empty. | 
 |  * If periodic channel released the FrameList is updated accordingly. | 
 |  * Calls transaction selection routines to activate pending transfers. | 
 |  */ | 
 | void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg, | 
 | 				 struct dwc2_host_chan *chan, int chnum, | 
 | 				 enum dwc2_halt_status halt_status) | 
 | { | 
 | 	struct dwc2_qh *qh = chan->qh; | 
 | 	int continue_isoc_xfer = 0; | 
 | 	enum dwc2_transaction_type tr_type; | 
 |  | 
 | 	if (chan->ep_type == USB_ENDPOINT_XFER_ISOC) { | 
 | 		dwc2_complete_isoc_xfer_ddma(hsotg, chan, halt_status); | 
 |  | 
 | 		/* Release the channel if halted or session completed */ | 
 | 		if (halt_status != DWC2_HC_XFER_COMPLETE || | 
 | 		    list_empty(&qh->qtd_list)) { | 
 | 			struct dwc2_qtd *qtd, *qtd_tmp; | 
 |  | 
 | 			/* | 
 | 			 * Kill all remainings QTDs since channel has been | 
 | 			 * halted. | 
 | 			 */ | 
 | 			list_for_each_entry_safe(qtd, qtd_tmp, | 
 | 						 &qh->qtd_list, | 
 | 						 qtd_list_entry) { | 
 | 				dwc2_host_complete(hsotg, qtd, | 
 | 						   -ECONNRESET); | 
 | 				dwc2_hcd_qtd_unlink_and_free(hsotg, | 
 | 							     qtd, qh); | 
 | 			} | 
 |  | 
 | 			/* Halt the channel if session completed */ | 
 | 			if (halt_status == DWC2_HC_XFER_COMPLETE) | 
 | 				dwc2_hc_halt(hsotg, chan, halt_status); | 
 | 			dwc2_release_channel_ddma(hsotg, qh); | 
 | 			dwc2_hcd_qh_unlink(hsotg, qh); | 
 | 		} else { | 
 | 			/* Keep in assigned schedule to continue transfer */ | 
 | 			list_move_tail(&qh->qh_list_entry, | 
 | 				       &hsotg->periodic_sched_assigned); | 
 | 			/* | 
 | 			 * If channel has been halted during giveback of urb | 
 | 			 * then prevent any new scheduling. | 
 | 			 */ | 
 | 			if (!chan->halt_status) | 
 | 				continue_isoc_xfer = 1; | 
 | 		} | 
 | 		/* | 
 | 		 * Todo: Consider the case when period exceeds FrameList size. | 
 | 		 * Frame Rollover interrupt should be used. | 
 | 		 */ | 
 | 	} else { | 
 | 		/* | 
 | 		 * Scan descriptor list to complete the URB(s), then release | 
 | 		 * the channel | 
 | 		 */ | 
 | 		dwc2_complete_non_isoc_xfer_ddma(hsotg, chan, chnum, | 
 | 						 halt_status); | 
 | 		dwc2_release_channel_ddma(hsotg, qh); | 
 | 		dwc2_hcd_qh_unlink(hsotg, qh); | 
 |  | 
 | 		if (!list_empty(&qh->qtd_list)) { | 
 | 			/* | 
 | 			 * Add back to inactive non-periodic schedule on normal | 
 | 			 * completion | 
 | 			 */ | 
 | 			dwc2_hcd_qh_add(hsotg, qh); | 
 | 		} | 
 | 	} | 
 |  | 
 | 	tr_type = dwc2_hcd_select_transactions(hsotg); | 
 | 	if (tr_type != DWC2_TRANSACTION_NONE || continue_isoc_xfer) { | 
 | 		if (continue_isoc_xfer) { | 
 | 			if (tr_type == DWC2_TRANSACTION_NONE) | 
 | 				tr_type = DWC2_TRANSACTION_PERIODIC; | 
 | 			else if (tr_type == DWC2_TRANSACTION_NON_PERIODIC) | 
 | 				tr_type = DWC2_TRANSACTION_ALL; | 
 | 		} | 
 | 		dwc2_hcd_queue_transactions(hsotg, tr_type); | 
 | 	} | 
 | } |