/*
 * bdc_ep.c - BRCM BDC USB3.0 device controller endpoint related functions
 *
 * Copyright (C) 2014 Broadcom Corporation
 *
 * Author: Ashwini Pahuja
 *
 * Based on drivers under drivers/usb/
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 */
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/dmapool.h>
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/otg.h>
#include <linux/pm.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <asm/unaligned.h>
#include <linux/platform_device.h>
#include <linux/usb/composite.h>

#include "bdc.h"
#include "bdc_ep.h"
#include "bdc_cmd.h"
#include "bdc_dbg.h"

static const char * const ep0_state_string[] =  {
	"WAIT_FOR_SETUP",
	"WAIT_FOR_DATA_START",
	"WAIT_FOR_DATA_XMIT",
	"WAIT_FOR_STATUS_START",
	"WAIT_FOR_STATUS_XMIT",
	"STATUS_PENDING"
};

/* Free the bdl during ep disable */
static void ep_bd_list_free(struct bdc_ep *ep, u32 num_tabs)
{
	struct bd_list *bd_list = &ep->bd_list;
	struct bdc *bdc = ep->bdc;
	struct bd_table *bd_table;
	int index;

	dev_dbg(bdc->dev, "%s ep:%s num_tabs:%d\n",
				 __func__, ep->name, num_tabs);

	if (!bd_list->bd_table_array) {
		dev_dbg(bdc->dev, "%s already freed\n", ep->name);
		return;
	}
	for (index = 0; index < num_tabs; index++) {
		/*
		 * check if the bd_table struct is allocated ?
		 * if yes, then check if bd memory has been allocated, then
		 * free the dma_pool and also the bd_table struct memory
		*/
		bd_table = bd_list->bd_table_array[index];
		dev_dbg(bdc->dev, "bd_table:%p index:%d\n", bd_table, index);
		if (!bd_table) {
			dev_dbg(bdc->dev, "bd_table not allocated\n");
			continue;
		}
		if (!bd_table->start_bd) {
			dev_dbg(bdc->dev, "bd dma pool not allocted\n");
			continue;
		}

		dev_dbg(bdc->dev,
				"Free dma pool start_bd:%p dma:%llx\n",
				bd_table->start_bd,
				(unsigned long long)bd_table->dma);

		dma_pool_free(bdc->bd_table_pool,
				bd_table->start_bd,
				bd_table->dma);
		/* Free the bd_table structure */
		kfree(bd_table);
	}
	/* Free the bd table array */
	kfree(ep->bd_list.bd_table_array);
}

/*
 * chain the tables, by insteting a chain bd at the end of prev_table, pointing
 * to next_table
 */
static inline void chain_table(struct bd_table *prev_table,
					struct bd_table *next_table,
					u32 bd_p_tab)
{
	/* Chain the prev table to next table */
	prev_table->start_bd[bd_p_tab-1].offset[0] =
				cpu_to_le32(lower_32_bits(next_table->dma));

	prev_table->start_bd[bd_p_tab-1].offset[1] =
				cpu_to_le32(upper_32_bits(next_table->dma));

	prev_table->start_bd[bd_p_tab-1].offset[2] =
				0x0;

	prev_table->start_bd[bd_p_tab-1].offset[3] =
				cpu_to_le32(MARK_CHAIN_BD);
}

/* Allocate the bdl for ep, during config ep */
static int ep_bd_list_alloc(struct bdc_ep *ep)
{
	struct bd_table *prev_table = NULL;
	int index, num_tabs, bd_p_tab;
	struct bdc *bdc = ep->bdc;
	struct bd_table *bd_table;
	dma_addr_t dma;

	if (usb_endpoint_xfer_isoc(ep->desc))
		num_tabs = NUM_TABLES_ISOCH;
	else
		num_tabs = NUM_TABLES;

	bd_p_tab = NUM_BDS_PER_TABLE;
	/* if there is only 1 table in bd list then loop chain to self */
	dev_dbg(bdc->dev,
		"%s ep:%p num_tabs:%d\n",
		__func__, ep, num_tabs);

	/* Allocate memory for table array */
	ep->bd_list.bd_table_array = kzalloc(
					num_tabs * sizeof(struct bd_table *),
					GFP_ATOMIC);
	if (!ep->bd_list.bd_table_array)
		return -ENOMEM;

	/* Allocate memory for each table */
	for (index = 0; index < num_tabs; index++) {
		/* Allocate memory for bd_table structure */
		bd_table = kzalloc(sizeof(struct bd_table), GFP_ATOMIC);
		if (!bd_table)
			goto fail;

		bd_table->start_bd = dma_pool_alloc(bdc->bd_table_pool,
							GFP_ATOMIC,
							&dma);
		if (!bd_table->start_bd)
			goto fail;

		bd_table->dma = dma;

		dev_dbg(bdc->dev,
			"index:%d start_bd:%p dma=%08llx prev_table:%p\n",
			index, bd_table->start_bd,
			(unsigned long long)bd_table->dma, prev_table);

		ep->bd_list.bd_table_array[index] = bd_table;
		memset(bd_table->start_bd, 0, bd_p_tab * sizeof(struct bdc_bd));
		if (prev_table)
			chain_table(prev_table, bd_table, bd_p_tab);

		prev_table = bd_table;
	}
	chain_table(prev_table, ep->bd_list.bd_table_array[0], bd_p_tab);
	/* Memory allocation is successful, now init the internal fields */
	ep->bd_list.num_tabs = num_tabs;
	ep->bd_list.max_bdi  = (num_tabs * bd_p_tab) - 1;
	ep->bd_list.num_tabs = num_tabs;
	ep->bd_list.num_bds_table = bd_p_tab;
	ep->bd_list.eqp_bdi = 0;
	ep->bd_list.hwd_bdi = 0;

	return 0;
fail:
	/* Free the bd_table_array, bd_table struct, bd's */
	ep_bd_list_free(ep, num_tabs);

	return -ENOMEM;
}

/* returns how many bd's are need for this transfer */
static inline int bd_needed_req(struct bdc_req *req)
{
	int bd_needed = 0;
	int remaining;

	/* 1 bd needed for 0 byte transfer */
	if (req->usb_req.length == 0)
		return 1;

	/* remaining bytes after tranfering all max BD size BD's */
	remaining = req->usb_req.length % BD_MAX_BUFF_SIZE;
	if (remaining)
		bd_needed++;

	/* How many maximum BUFF size BD's ? */
	remaining = req->usb_req.length / BD_MAX_BUFF_SIZE;
	bd_needed += remaining;

	return bd_needed;
}

/* returns the bd index(bdi) corresponding to bd dma address */
static int bd_add_to_bdi(struct bdc_ep *ep, dma_addr_t bd_dma_addr)
{
	struct bd_list *bd_list = &ep->bd_list;
	dma_addr_t dma_first_bd, dma_last_bd;
	struct bdc *bdc = ep->bdc;
	struct bd_table *bd_table;
	bool found = false;
	int tbi, bdi;

	dma_first_bd = dma_last_bd = 0;
	dev_dbg(bdc->dev, "%s  %llx\n",
			__func__, (unsigned long long)bd_dma_addr);
	/*
	 * Find in which table this bd_dma_addr belongs?, go through the table
	 * array and compare addresses of first and last address of bd of each
	 * table
	 */
	for (tbi = 0; tbi < bd_list->num_tabs; tbi++) {
		bd_table = bd_list->bd_table_array[tbi];
		dma_first_bd = bd_table->dma;
		dma_last_bd = bd_table->dma +
					(sizeof(struct bdc_bd) *
					(bd_list->num_bds_table - 1));
		dev_dbg(bdc->dev, "dma_first_bd:%llx dma_last_bd:%llx\n",
					(unsigned long long)dma_first_bd,
					(unsigned long long)dma_last_bd);
		if (bd_dma_addr >= dma_first_bd && bd_dma_addr <= dma_last_bd) {
			found = true;
			break;
		}
	}
	if (unlikely(!found)) {
		dev_err(bdc->dev, "%s FATAL err, bd not found\n", __func__);
		return -EINVAL;
	}
	/* Now we know the table, find the bdi */
	bdi = (bd_dma_addr - dma_first_bd) / sizeof(struct bdc_bd);

	/* return the global bdi, to compare with ep eqp_bdi */
	return (bdi + (tbi * bd_list->num_bds_table));
}

/* returns the table index(tbi) of the given bdi */
static int bdi_to_tbi(struct bdc_ep *ep, int bdi)
{
	int tbi;

	tbi = bdi / ep->bd_list.num_bds_table;
	dev_vdbg(ep->bdc->dev,
		"bdi:%d num_bds_table:%d tbi:%d\n",
		bdi, ep->bd_list.num_bds_table, tbi);

	return tbi;
}

/* Find the bdi last bd in the transfer */
static inline int find_end_bdi(struct bdc_ep *ep, int next_hwd_bdi)
{
	int end_bdi;

	end_bdi = next_hwd_bdi - 1;
	if (end_bdi < 0)
		end_bdi = ep->bd_list.max_bdi - 1;
	 else if ((end_bdi % (ep->bd_list.num_bds_table-1)) == 0)
		end_bdi--;

	return end_bdi;
}

/*
 * How many transfer bd's are available on this ep bdl, chain bds are not
 * counted in available bds
 */
static int bd_available_ep(struct bdc_ep *ep)
{
	struct bd_list *bd_list = &ep->bd_list;
	int available1, available2;
	struct bdc *bdc = ep->bdc;
	int chain_bd1, chain_bd2;
	int available_bd = 0;

	available1 = available2 = chain_bd1 = chain_bd2 = 0;
	/* if empty then we have all bd's available - number of chain bd's */
	if (bd_list->eqp_bdi == bd_list->hwd_bdi)
		return bd_list->max_bdi - bd_list->num_tabs;

	/*
	 * Depending upon where eqp and dqp pointers are, caculate number
	 * of avaialble bd's
	 */
	if (bd_list->hwd_bdi < bd_list->eqp_bdi) {
		/* available bd's are from eqp..max_bds + 0..dqp - chain_bds */
		available1 = bd_list->max_bdi - bd_list->eqp_bdi;
		available2 = bd_list->hwd_bdi;
		chain_bd1 = available1 / bd_list->num_bds_table;
		chain_bd2 = available2 / bd_list->num_bds_table;
		dev_vdbg(bdc->dev, "chain_bd1:%d chain_bd2:%d\n",
						chain_bd1, chain_bd2);
		available_bd = available1 + available2 - chain_bd1 - chain_bd2;
	} else {
		/* available bd's are from eqp..dqp - number of chain bd's */
		available1 = bd_list->hwd_bdi -  bd_list->eqp_bdi;
		/* if gap between eqp and dqp is less than NUM_BDS_PER_TABLE */
		if ((bd_list->hwd_bdi - bd_list->eqp_bdi)
					<= bd_list->num_bds_table) {
			/* If there any chain bd in between */
			if (!(bdi_to_tbi(ep, bd_list->hwd_bdi)
					== bdi_to_tbi(ep, bd_list->eqp_bdi))) {
				available_bd = available1 - 1;
			}
		} else {
			chain_bd1 = available1 / bd_list->num_bds_table;
			available_bd = available1 - chain_bd1;
		}
	}
	/*
	 * we need to keep one extra bd to check if ring is full or empty so
	 * reduce by 1
	 */
	available_bd--;
	dev_vdbg(bdc->dev, "available_bd:%d\n", available_bd);

	return available_bd;
}

/* Notify the hardware after queueing the bd to bdl */
void bdc_notify_xfr(struct bdc *bdc, u32 epnum)
{
	struct bdc_ep *ep = bdc->bdc_ep_array[epnum];

	dev_vdbg(bdc->dev, "%s epnum:%d\n", __func__, epnum);
	/*
	 * We don't have anyway to check if ep state is running,
	 * except the software flags.
	 */
	if (unlikely(ep->flags & BDC_EP_STOP))
		ep->flags &= ~BDC_EP_STOP;

	bdc_writel(bdc->regs, BDC_XSFNTF, epnum);
}

/* returns the bd corresponding to bdi */
static struct bdc_bd *bdi_to_bd(struct bdc_ep *ep, int bdi)
{
	int tbi = bdi_to_tbi(ep, bdi);
	int local_bdi = 0;

	local_bdi = bdi - (tbi * ep->bd_list.num_bds_table);
	dev_vdbg(ep->bdc->dev,
		"%s bdi:%d local_bdi:%d\n",
		 __func__, bdi, local_bdi);

	return (ep->bd_list.bd_table_array[tbi]->start_bd + local_bdi);
}

/* Advance the enqueue pointer */
static void ep_bdlist_eqp_adv(struct bdc_ep *ep)
{
	ep->bd_list.eqp_bdi++;
	/* if it's chain bd, then move to next */
	if (((ep->bd_list.eqp_bdi + 1) % ep->bd_list.num_bds_table) == 0)
		ep->bd_list.eqp_bdi++;

	/* if the eqp is pointing to last + 1 then move back to 0 */
	if (ep->bd_list.eqp_bdi == (ep->bd_list.max_bdi + 1))
		ep->bd_list.eqp_bdi = 0;
}

/* Setup the first bd for ep0 transfer */
static int setup_first_bd_ep0(struct bdc *bdc, struct bdc_req *req, u32 *dword3)
{
	u16 wValue;
	u32 req_len;

	req->ep->dir = 0;
	req_len = req->usb_req.length;
	switch (bdc->ep0_state) {
	case WAIT_FOR_DATA_START:
		*dword3 |= BD_TYPE_DS;
		if (bdc->setup_pkt.bRequestType & USB_DIR_IN)
			*dword3 |= BD_DIR_IN;

		/* check if zlp will be needed */
		wValue = le16_to_cpu(bdc->setup_pkt.wValue);
		if ((wValue > req_len) &&
				(req_len % bdc->gadget.ep0->maxpacket == 0)) {
			dev_dbg(bdc->dev, "ZLP needed wVal:%d len:%d MaxP:%d\n",
					wValue, req_len,
					bdc->gadget.ep0->maxpacket);
			bdc->zlp_needed = true;
		}
		break;

	case WAIT_FOR_STATUS_START:
		*dword3 |= BD_TYPE_SS;
		if (!le16_to_cpu(bdc->setup_pkt.wLength) ||
				!(bdc->setup_pkt.bRequestType & USB_DIR_IN))
			*dword3 |= BD_DIR_IN;
		break;
	default:
		dev_err(bdc->dev,
			"Unknown ep0 state for queueing bd ep0_state:%s\n",
			ep0_state_string[bdc->ep0_state]);
		return -EINVAL;
	}

	return 0;
}

/* Setup the bd dma descriptor for a given request */
static int setup_bd_list_xfr(struct bdc *bdc, struct bdc_req *req, int num_bds)
{
	dma_addr_t buf_add = req->usb_req.dma;
	u32 maxp, tfs, dword2, dword3;
	struct bd_transfer *bd_xfr;
	struct bd_list *bd_list;
	struct bdc_ep *ep;
	struct bdc_bd *bd;
	int ret, bdnum;
	u32 req_len;

	ep = req->ep;
	bd_list = &ep->bd_list;
	bd_xfr = &req->bd_xfr;
	bd_xfr->req = req;
	bd_xfr->start_bdi = bd_list->eqp_bdi;
	bd = bdi_to_bd(ep, bd_list->eqp_bdi);
	req_len = req->usb_req.length;
	maxp = usb_endpoint_maxp(ep->desc) & 0x7ff;
	tfs = roundup(req->usb_req.length, maxp);
	tfs = tfs/maxp;
	dev_vdbg(bdc->dev, "%s ep:%s num_bds:%d tfs:%d r_len:%d bd:%p\n",
				__func__, ep->name, num_bds, tfs, req_len, bd);

	for (bdnum = 0; bdnum < num_bds; bdnum++) {
		dword2 = dword3 = 0;
		/* First bd */
		if (!bdnum) {
			dword3 |= BD_SOT|BD_SBF|(tfs<<BD_TFS_SHIFT);
			dword2 |= BD_LTF;
			/* format of first bd for ep0 is different than other */
			if (ep->ep_num == 1) {
				ret = setup_first_bd_ep0(bdc, req, &dword3);
				if (ret)
					return ret;
			}
		}
		if (!req->ep->dir)
			dword3 |= BD_ISP;

		if (req_len > BD_MAX_BUFF_SIZE) {
			dword2 |= BD_MAX_BUFF_SIZE;
			req_len -= BD_MAX_BUFF_SIZE;
		} else {
			/* this should be the last bd */
			dword2 |= req_len;
			dword3 |= BD_IOC;
			dword3 |= BD_EOT;
		}
		/* Currently only 1 INT target is supported */
		dword2 |= BD_INTR_TARGET(0);
		bd = bdi_to_bd(ep, ep->bd_list.eqp_bdi);
		if (unlikely(!bd)) {
			dev_err(bdc->dev, "Err bd pointing to wrong addr\n");
			return -EINVAL;
		}
		/* write bd */
		bd->offset[0] = cpu_to_le32(lower_32_bits(buf_add));
		bd->offset[1] = cpu_to_le32(upper_32_bits(buf_add));
		bd->offset[2] = cpu_to_le32(dword2);
		bd->offset[3] = cpu_to_le32(dword3);
		/* advance eqp pointer */
		ep_bdlist_eqp_adv(ep);
		/* advance the buff pointer */
		buf_add += BD_MAX_BUFF_SIZE;
		dev_vdbg(bdc->dev, "buf_add:%08llx req_len:%d bd:%p eqp:%d\n",
				(unsigned long long)buf_add, req_len, bd,
							ep->bd_list.eqp_bdi);
		bd = bdi_to_bd(ep, ep->bd_list.eqp_bdi);
		bd->offset[3] = cpu_to_le32(BD_SBF);
	}
	/* clear the STOP BD fetch bit from the first bd of this xfr */
	bd = bdi_to_bd(ep, bd_xfr->start_bdi);
	bd->offset[3] &= cpu_to_le32(~BD_SBF);
	/* the new eqp will be next hw dqp */
	bd_xfr->num_bds  = num_bds;
	bd_xfr->next_hwd_bdi = ep->bd_list.eqp_bdi;
	/* everything is written correctly before notifying the HW */
	wmb();

	return 0;
}

/* Queue the xfr */
static int bdc_queue_xfr(struct bdc *bdc, struct bdc_req *req)
{
	int num_bds, bd_available;
	struct bdc_ep *ep;
	int ret;

	ep = req->ep;
	dev_dbg(bdc->dev, "%s req:%p\n", __func__, req);
	dev_dbg(bdc->dev, "eqp_bdi:%d hwd_bdi:%d\n",
			ep->bd_list.eqp_bdi, ep->bd_list.hwd_bdi);

	num_bds =  bd_needed_req(req);
	bd_available = bd_available_ep(ep);

	/* how many bd's are avaialble on ep */
	if (num_bds > bd_available)
		return -ENOMEM;

	ret = setup_bd_list_xfr(bdc, req, num_bds);
	if (ret)
		return ret;
	list_add_tail(&req->queue, &ep->queue);
	bdc_dbg_bd_list(bdc, ep);
	bdc_notify_xfr(bdc, ep->ep_num);

	return 0;
}

/* callback to gadget layer when xfr completes */
static void bdc_req_complete(struct bdc_ep *ep, struct bdc_req *req,
						int status)
{
	struct bdc *bdc = ep->bdc;

	if (req == NULL  || &req->queue == NULL || &req->usb_req == NULL)
		return;

	dev_dbg(bdc->dev, "%s ep:%s status:%d\n", __func__, ep->name, status);
	list_del(&req->queue);
	req->usb_req.status = status;
	usb_gadget_unmap_request(&bdc->gadget, &req->usb_req, ep->dir);
	if (req->usb_req.complete) {
		spin_unlock(&bdc->lock);
		usb_gadget_giveback_request(&ep->usb_ep, &req->usb_req);
		spin_lock(&bdc->lock);
	}
}

/* Disable the endpoint */
int bdc_ep_disable(struct bdc_ep *ep)
{
	struct bdc_req *req;
	struct bdc *bdc;
	int ret;

	ret = 0;
	bdc = ep->bdc;
	dev_dbg(bdc->dev, "%s() ep->ep_num=%d\n", __func__, ep->ep_num);
	/* Stop the endpoint */
	ret = bdc_stop_ep(bdc, ep->ep_num);

	/*
	 * Intentionally don't check the ret value of stop, it can fail in
	 * disconnect scenarios, continue with dconfig
	 */
	/* de-queue any pending requests */
	while (!list_empty(&ep->queue)) {
		req = list_entry(ep->queue.next, struct bdc_req,
				queue);
		bdc_req_complete(ep, req, -ESHUTDOWN);
	}
	/* deconfigure the endpoint */
	ret = bdc_dconfig_ep(bdc, ep);
	if (ret)
		dev_warn(bdc->dev,
			"dconfig fail but continue with memory free");

	ep->flags = 0;
	/* ep0 memory is not freed, but reused on next connect sr */
	if (ep->ep_num == 1)
		return 0;

	/* Free the bdl memory */
	ep_bd_list_free(ep, ep->bd_list.num_tabs);
	ep->desc = NULL;
	ep->comp_desc = NULL;
	ep->usb_ep.desc = NULL;
	ep->ep_type = 0;

	return ret;
}

/* Enable the ep */
int bdc_ep_enable(struct bdc_ep *ep)
{
	struct bdc *bdc;
	int ret = 0;

	bdc = ep->bdc;
	dev_dbg(bdc->dev, "%s NUM_TABLES:%d %d\n",
					__func__, NUM_TABLES, NUM_TABLES_ISOCH);

	ret = ep_bd_list_alloc(ep);
	if (ret) {
		dev_err(bdc->dev, "ep bd list allocation failed:%d\n", ret);
		return -ENOMEM;
	}
	bdc_dbg_bd_list(bdc, ep);
	/* only for ep0: config ep is called for ep0 from connect event */
	ep->flags |= BDC_EP_ENABLED;
	if (ep->ep_num == 1)
		return ret;

	/* Issue a configure endpoint command */
	ret = bdc_config_ep(bdc, ep);
	if (ret)
		return ret;

	ep->usb_ep.maxpacket = usb_endpoint_maxp(ep->desc);
	ep->usb_ep.desc = ep->desc;
	ep->usb_ep.comp_desc = ep->comp_desc;
	ep->ep_type = usb_endpoint_type(ep->desc);
	ep->flags |= BDC_EP_ENABLED;

	return 0;
}

/* EP0 related code */

/* Queue a status stage BD */
static int ep0_queue_status_stage(struct bdc *bdc)
{
	struct bdc_req *status_req;
	struct bdc_ep *ep;

	status_req = &bdc->status_req;
	ep = bdc->bdc_ep_array[1];
	status_req->ep = ep;
	status_req->usb_req.length = 0;
	status_req->usb_req.status = -EINPROGRESS;
	status_req->usb_req.actual = 0;
	status_req->usb_req.complete = NULL;
	bdc_queue_xfr(bdc, status_req);

	return 0;
}

/* Queue xfr on ep0 */
static int ep0_queue(struct bdc_ep *ep, struct bdc_req *req)
{
	struct bdc *bdc;
	int ret;

	bdc = ep->bdc;
	dev_dbg(bdc->dev, "%s()\n", __func__);
	req->usb_req.actual = 0;
	req->usb_req.status = -EINPROGRESS;
	req->epnum = ep->ep_num;

	if (bdc->delayed_status) {
		bdc->delayed_status = false;
		/* if status stage was delayed? */
		if (bdc->ep0_state == WAIT_FOR_STATUS_START) {
			/* Queue a status stage BD */
			ep0_queue_status_stage(bdc);
			bdc->ep0_state = WAIT_FOR_STATUS_XMIT;
			return 0;
		}
	} else {
		/*
		 * if delayed status is false and 0 length transfer is requested
		 * i.e. for status stage of some setup request, then just
		 * return from here the status stage is queued independently
		 */
		if (req->usb_req.length == 0)
			return 0;

	}
	ret = usb_gadget_map_request(&bdc->gadget, &req->usb_req, ep->dir);
	if (ret) {
		dev_err(bdc->dev, "dma mapping failed %s\n", ep->name);
		return ret;
	}

	return bdc_queue_xfr(bdc, req);
}

/* Queue data stage */
static int ep0_queue_data_stage(struct bdc *bdc)
{
	struct usb_request *ep0_usb_req;
	struct bdc_ep *ep;

	dev_dbg(bdc->dev, "%s\n", __func__);
	ep0_usb_req = &bdc->ep0_req.usb_req;
	ep = bdc->bdc_ep_array[1];
	bdc->ep0_req.ep = ep;
	bdc->ep0_req.usb_req.complete = NULL;

	return ep0_queue(ep, &bdc->ep0_req);
}

/* Queue req on ep */
static int ep_queue(struct bdc_ep *ep, struct bdc_req *req)
{
	struct bdc *bdc;
	int ret = 0;

	if (!req || !ep->usb_ep.desc)
		return -EINVAL;

	bdc = ep->bdc;

	req->usb_req.actual = 0;
	req->usb_req.status = -EINPROGRESS;
	req->epnum = ep->ep_num;

	ret = usb_gadget_map_request(&bdc->gadget, &req->usb_req, ep->dir);
	if (ret) {
		dev_err(bdc->dev, "dma mapping failed\n");
		return ret;
	}

	return bdc_queue_xfr(bdc, req);
}

/* Dequeue a request from ep */
static int ep_dequeue(struct bdc_ep *ep, struct bdc_req *req)
{
	int start_bdi, end_bdi, tbi, eqp_bdi, curr_hw_dqpi;
	bool start_pending, end_pending;
	bool first_remove = false;
	struct bdc_req *first_req;
	struct bdc_bd *bd_start;
	struct bd_table *table;
	dma_addr_t next_bd_dma;
	u64   deq_ptr_64 = 0;
	struct bdc  *bdc;
	u32    tmp_32;
	int ret;

	bdc = ep->bdc;
	start_pending = end_pending = false;
	eqp_bdi = ep->bd_list.eqp_bdi - 1;

	if (eqp_bdi < 0)
		eqp_bdi = ep->bd_list.max_bdi;

	start_bdi = req->bd_xfr.start_bdi;
	end_bdi = find_end_bdi(ep, req->bd_xfr.next_hwd_bdi);

	dev_dbg(bdc->dev, "%s ep:%s start:%d end:%d\n",
					__func__, ep->name, start_bdi, end_bdi);
	dev_dbg(bdc->dev, "ep_dequeue ep=%p ep->desc=%p\n",
						ep, (void *)ep->usb_ep.desc);
	/* Stop the ep to see where the HW is ? */
	ret = bdc_stop_ep(bdc, ep->ep_num);
	/* if there is an issue with stopping ep, then no need to go further */
	if (ret)
		return 0;

	/*
	 * After endpoint is stopped, there can be 3 cases, the request
	 * is processed, pending or in the middle of processing
	 */

	/* The current hw dequeue pointer */
	tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS0(0));
	deq_ptr_64 = tmp_32;
	tmp_32 = bdc_readl(bdc->regs, BDC_EPSTS0(1));
	deq_ptr_64 |= ((u64)tmp_32 << 32);

	/* we have the dma addr of next bd that will be fetched by hardware */
	curr_hw_dqpi = bd_add_to_bdi(ep, deq_ptr_64);
	if (curr_hw_dqpi < 0)
		return curr_hw_dqpi;

	/*
	 * curr_hw_dqpi points to actual dqp of HW and HW owns bd's from
	 * curr_hw_dqbdi..eqp_bdi.
	 */

	/* Check if start_bdi and end_bdi are in range of HW owned BD's */
	if (curr_hw_dqpi > eqp_bdi) {
		/* there is a wrap from last to 0 */
		if (start_bdi >= curr_hw_dqpi || start_bdi <= eqp_bdi) {
			start_pending = true;
			end_pending = true;
		} else if (end_bdi >= curr_hw_dqpi || end_bdi <= eqp_bdi) {
				end_pending = true;
		}
	} else {
		if (start_bdi >= curr_hw_dqpi) {
			start_pending = true;
			end_pending = true;
		} else if (end_bdi >= curr_hw_dqpi) {
			end_pending = true;
		}
	}
	dev_dbg(bdc->dev,
		"start_pending:%d end_pending:%d speed:%d\n",
		start_pending, end_pending, bdc->gadget.speed);

	/* If both start till end are processes, we cannot deq req */
	if (!start_pending && !end_pending)
		return -EINVAL;

	/*
	 * if ep_dequeue is called after disconnect then just return
	 * success from here
	 */
	if (bdc->gadget.speed == USB_SPEED_UNKNOWN)
		return 0;
	tbi = bdi_to_tbi(ep, req->bd_xfr.next_hwd_bdi);
	table = ep->bd_list.bd_table_array[tbi];
	next_bd_dma =  table->dma +
			sizeof(struct bdc_bd)*(req->bd_xfr.next_hwd_bdi -
					tbi * ep->bd_list.num_bds_table);

	first_req = list_first_entry(&ep->queue, struct bdc_req,
			queue);

	if (req == first_req)
		first_remove = true;

	/*
	 * Due to HW limitation we need to bypadd chain bd's and issue ep_bla,
	 * incase if start is pending this is the first request in the list
	 * then issue ep_bla instead of marking as chain bd
	 */
	if (start_pending && !first_remove) {
		/*
		 * Mark the start bd as Chain bd, and point the chain
		 * bd to next_bd_dma
		 */
		bd_start = bdi_to_bd(ep, start_bdi);
		bd_start->offset[0] = cpu_to_le32(lower_32_bits(next_bd_dma));
		bd_start->offset[1] = cpu_to_le32(upper_32_bits(next_bd_dma));
		bd_start->offset[2] = 0x0;
		bd_start->offset[3] = cpu_to_le32(MARK_CHAIN_BD);
		bdc_dbg_bd_list(bdc, ep);
	} else if (end_pending) {
		/*
		 * The transfer is stopped in the middle, move the
		 * HW deq pointer to next_bd_dma
		 */
		ret = bdc_ep_bla(bdc, ep, next_bd_dma);
		if (ret) {
			dev_err(bdc->dev, "error in ep_bla:%d\n", ret);
			return ret;
		}
	}

	return 0;
}

/* Halt/Clear the ep based on value */
static int ep_set_halt(struct bdc_ep *ep, u32 value)
{
	struct bdc *bdc;
	int ret;

	bdc = ep->bdc;
	dev_dbg(bdc->dev, "%s ep:%s value=%d\n", __func__, ep->name, value);

	if (value) {
		dev_dbg(bdc->dev, "Halt\n");
		if (ep->ep_num == 1)
			bdc->ep0_state = WAIT_FOR_SETUP;

		ret = bdc_ep_set_stall(bdc, ep->ep_num);
		if (ret)
			dev_err(bdc->dev, "failed to set STALL on %s\n",
				ep->name);
		else
			ep->flags |= BDC_EP_STALL;
	} else {
		/* Clear */
		dev_dbg(bdc->dev, "Before Clear\n");
		ret = bdc_ep_clear_stall(bdc, ep->ep_num);
		if (ret)
			dev_err(bdc->dev, "failed to clear STALL on %s\n",
				ep->name);
		else
			ep->flags &= ~BDC_EP_STALL;
		dev_dbg(bdc->dev, "After  Clear\n");
	}

	return ret;
}

/* Free all the ep */
void bdc_free_ep(struct bdc *bdc)
{
	struct bdc_ep *ep;
	u8	epnum;

	dev_dbg(bdc->dev, "%s\n", __func__);
	for (epnum = 1; epnum < bdc->num_eps; epnum++) {
		ep = bdc->bdc_ep_array[epnum];
		if (!ep)
			continue;

		if (ep->flags & BDC_EP_ENABLED)
			ep_bd_list_free(ep, ep->bd_list.num_tabs);

		/* ep0 is not in this gadget list */
		if (epnum != 1)
			list_del(&ep->usb_ep.ep_list);

		kfree(ep);
	}
}

/* USB2 spec, section 7.1.20 */
static int bdc_set_test_mode(struct bdc *bdc)
{
	u32 usb2_pm;

	usb2_pm = bdc_readl(bdc->regs, BDC_USPPM2);
	usb2_pm &= ~BDC_PTC_MASK;
	dev_dbg(bdc->dev, "%s\n", __func__);
	switch (bdc->test_mode) {
	case TEST_J:
	case TEST_K:
	case TEST_SE0_NAK:
	case TEST_PACKET:
	case TEST_FORCE_EN:
		usb2_pm |= bdc->test_mode << 28;
		break;
	default:
		return -EINVAL;
	}
	dev_dbg(bdc->dev, "usb2_pm=%08x", usb2_pm);
	bdc_writel(bdc->regs, BDC_USPPM2, usb2_pm);

	return 0;
}

/*
 * Helper function to handle Transfer status report with status as either
 * success or short
 */
static void handle_xsr_succ_status(struct bdc *bdc, struct bdc_ep *ep,
							struct bdc_sr *sreport)
{
	int short_bdi, start_bdi, end_bdi, max_len_bds, chain_bds;
	struct bd_list *bd_list = &ep->bd_list;
	int actual_length, length_short;
	struct bd_transfer *bd_xfr;
	struct bdc_bd *short_bd;
	struct bdc_req *req;
	u64   deq_ptr_64 = 0;
	int status = 0;
	int sr_status;
	u32    tmp_32;

	dev_dbg(bdc->dev, "%s  ep:%p\n", __func__, ep);
	bdc_dbg_srr(bdc, 0);
	/* do not process thie sr if ignore flag is set */
	if (ep->ignore_next_sr) {
		ep->ignore_next_sr = false;
		return;
	}

	if (unlikely(list_empty(&ep->queue))) {
		dev_warn(bdc->dev, "xfr srr with no BD's queued\n");
		return;
	}
	req = list_entry(ep->queue.next, struct bdc_req,
			queue);

	bd_xfr = &req->bd_xfr;
	sr_status = XSF_STS(le32_to_cpu(sreport->offset[3]));

	/*
	 * sr_status is short and this transfer has more than 1 bd then it needs
	 * special handling,  this is only applicable for bulk and ctrl
	 */
	if (sr_status == XSF_SHORT &&  bd_xfr->num_bds > 1) {
		/*
		 * This is multi bd xfr, lets see which bd
		 * caused short transfer and how many bytes have been
		 * transferred so far.
		 */
		tmp_32 = le32_to_cpu(sreport->offset[0]);
		deq_ptr_64 = tmp_32;
		tmp_32 = le32_to_cpu(sreport->offset[1]);
		deq_ptr_64 |= ((u64)tmp_32 << 32);
		short_bdi = bd_add_to_bdi(ep, deq_ptr_64);
		if (unlikely(short_bdi < 0))
			dev_warn(bdc->dev, "bd doesn't exist?\n");

		start_bdi =  bd_xfr->start_bdi;
		/*
		 * We know the start_bdi and short_bdi, how many xfr
		 * bds in between
		 */
		if (start_bdi <= short_bdi) {
			max_len_bds = short_bdi - start_bdi;
			if (max_len_bds <= bd_list->num_bds_table) {
				if (!(bdi_to_tbi(ep, start_bdi) ==
						bdi_to_tbi(ep, short_bdi)))
					max_len_bds--;
			} else {
				chain_bds = max_len_bds/bd_list->num_bds_table;
				max_len_bds -= chain_bds;
			}
		} else {
			/* there is a wrap in the ring within a xfr */
			chain_bds = (bd_list->max_bdi - start_bdi)/
							bd_list->num_bds_table;
			chain_bds += short_bdi/bd_list->num_bds_table;
			max_len_bds = bd_list->max_bdi - start_bdi;
			max_len_bds += short_bdi;
			max_len_bds -= chain_bds;
		}
		/* max_len_bds is the number of full length bds */
		end_bdi = find_end_bdi(ep, bd_xfr->next_hwd_bdi);
		if (!(end_bdi == short_bdi))
			ep->ignore_next_sr = true;

		actual_length = max_len_bds * BD_MAX_BUFF_SIZE;
		short_bd = bdi_to_bd(ep, short_bdi);
		/* length queued */
		length_short = le32_to_cpu(short_bd->offset[2]) & 0x1FFFFF;
		/* actual length trensfered */
		length_short -= SR_BD_LEN(le32_to_cpu(sreport->offset[2]));
		actual_length += length_short;
		req->usb_req.actual = actual_length;
	} else {
		req->usb_req.actual = req->usb_req.length -
			SR_BD_LEN(le32_to_cpu(sreport->offset[2]));
		dev_dbg(bdc->dev,
			"len=%d actual=%d bd_xfr->next_hwd_bdi:%d\n",
			req->usb_req.length, req->usb_req.actual,
			bd_xfr->next_hwd_bdi);
	}

	/* Update the dequeue pointer */
	ep->bd_list.hwd_bdi = bd_xfr->next_hwd_bdi;
	if (req->usb_req.actual < req->usb_req.length) {
		dev_dbg(bdc->dev, "short xfr on %d\n", ep->ep_num);
		if (req->usb_req.short_not_ok)
			status = -EREMOTEIO;
	}
	bdc_req_complete(ep, bd_xfr->req, status);
}

/* EP0 setup related packet handlers */

/*
 * Setup packet received, just store the packet and process on next DS or SS
 * started SR
 */
void bdc_xsf_ep0_setup_recv(struct bdc *bdc, struct bdc_sr *sreport)
{
	struct usb_ctrlrequest *setup_pkt;
	u32 len;

	dev_dbg(bdc->dev,
		"%s ep0_state:%s\n",
		__func__, ep0_state_string[bdc->ep0_state]);
	/* Store received setup packet */
	setup_pkt = &bdc->setup_pkt;
	memcpy(setup_pkt, &sreport->offset[0], sizeof(*setup_pkt));
	len = le16_to_cpu(setup_pkt->wLength);
	if (!len)
		bdc->ep0_state = WAIT_FOR_STATUS_START;
	else
		bdc->ep0_state = WAIT_FOR_DATA_START;


	dev_dbg(bdc->dev,
		"%s exit ep0_state:%s\n",
		__func__, ep0_state_string[bdc->ep0_state]);
}

/* Stall ep0 */
static void ep0_stall(struct bdc *bdc)
{
	struct bdc_ep	*ep = bdc->bdc_ep_array[1];
	struct bdc_req *req;

	dev_dbg(bdc->dev, "%s\n", __func__);
	bdc->delayed_status = false;
	ep_set_halt(ep, 1);

	/* de-queue any pendig requests */
	while (!list_empty(&ep->queue)) {
		req = list_entry(ep->queue.next, struct bdc_req,
				queue);
		bdc_req_complete(ep, req, -ESHUTDOWN);
	}
}

/* SET_ADD handlers */
static int ep0_set_address(struct bdc *bdc, struct usb_ctrlrequest *ctrl)
{
	enum usb_device_state state = bdc->gadget.state;
	int ret = 0;
	u32 addr;

	addr = le16_to_cpu(ctrl->wValue);
	dev_dbg(bdc->dev,
		"%s addr:%d dev state:%d\n",
		__func__, addr, state);

	if (addr > 127)
		return -EINVAL;

	switch (state) {
	case USB_STATE_DEFAULT:
	case USB_STATE_ADDRESS:
		/* Issue Address device command */
		ret = bdc_address_device(bdc, addr);
		if (ret)
			return ret;

		if (addr)
			usb_gadget_set_state(&bdc->gadget, USB_STATE_ADDRESS);
		else
			usb_gadget_set_state(&bdc->gadget, USB_STATE_DEFAULT);

		bdc->dev_addr = addr;
		break;
	default:
		dev_warn(bdc->dev,
			"SET Address in wrong device state %d\n",
			state);
		ret = -EINVAL;
	}

	return ret;
}

/* Handler for SET/CLEAR FEATURE requests for device */
static int ep0_handle_feature_dev(struct bdc *bdc, u16 wValue,
							u16 wIndex, bool set)
{
	enum usb_device_state state = bdc->gadget.state;
	u32	usppms = 0;

	dev_dbg(bdc->dev, "%s set:%d dev state:%d\n",
					__func__, set, state);
	switch (wValue) {
	case USB_DEVICE_REMOTE_WAKEUP:
		dev_dbg(bdc->dev, "USB_DEVICE_REMOTE_WAKEUP\n");
		if (set)
			bdc->devstatus |= REMOTE_WAKE_ENABLE;
		else
			bdc->devstatus &= ~REMOTE_WAKE_ENABLE;
		break;

	case USB_DEVICE_TEST_MODE:
		dev_dbg(bdc->dev, "USB_DEVICE_TEST_MODE\n");
		if ((wIndex & 0xFF) ||
				(bdc->gadget.speed != USB_SPEED_HIGH) || !set)
			return -EINVAL;

		bdc->test_mode = wIndex >> 8;
		break;

	case USB_DEVICE_U1_ENABLE:
		dev_dbg(bdc->dev, "USB_DEVICE_U1_ENABLE\n");

		if (bdc->gadget.speed != USB_SPEED_SUPER ||
						state != USB_STATE_CONFIGURED)
			return -EINVAL;

		usppms =  bdc_readl(bdc->regs, BDC_USPPMS);
		if (set) {
			/* clear previous u1t */
			usppms &= ~BDC_U1T(BDC_U1T_MASK);
			usppms |= BDC_U1T(U1_TIMEOUT);
			usppms |= BDC_U1E | BDC_PORT_W1S;
			bdc->devstatus |= (1 << USB_DEV_STAT_U1_ENABLED);
		} else {
			usppms &= ~BDC_U1E;
			usppms |= BDC_PORT_W1S;
			bdc->devstatus &= ~(1 << USB_DEV_STAT_U1_ENABLED);
		}
		bdc_writel(bdc->regs, BDC_USPPMS, usppms);
		break;

	case USB_DEVICE_U2_ENABLE:
		dev_dbg(bdc->dev, "USB_DEVICE_U2_ENABLE\n");

		if (bdc->gadget.speed != USB_SPEED_SUPER ||
						state != USB_STATE_CONFIGURED)
			return -EINVAL;

		usppms = bdc_readl(bdc->regs, BDC_USPPMS);
		if (set) {
			usppms |= BDC_U2E;
			usppms |= BDC_U2A;
			bdc->devstatus |= (1 << USB_DEV_STAT_U2_ENABLED);
		} else {
			usppms &= ~BDC_U2E;
			usppms &= ~BDC_U2A;
			bdc->devstatus &= ~(1 << USB_DEV_STAT_U2_ENABLED);
		}
		bdc_writel(bdc->regs, BDC_USPPMS, usppms);
		break;

	case USB_DEVICE_LTM_ENABLE:
		dev_dbg(bdc->dev, "USB_DEVICE_LTM_ENABLE?\n");
		if (bdc->gadget.speed != USB_SPEED_SUPER ||
						state != USB_STATE_CONFIGURED)
			return -EINVAL;
		break;
	default:
		dev_err(bdc->dev, "Unknown wValue:%d\n", wValue);
		return -EOPNOTSUPP;
	} /* USB_RECIP_DEVICE end */

	return 0;
}

/* SET/CLEAR FEATURE handler */
static int ep0_handle_feature(struct bdc *bdc,
			      struct usb_ctrlrequest *setup_pkt, bool set)
{
	enum usb_device_state state = bdc->gadget.state;
	struct bdc_ep *ep;
	u16 wValue;
	u16 wIndex;
	int epnum;

	wValue = le16_to_cpu(setup_pkt->wValue);
	wIndex = le16_to_cpu(setup_pkt->wIndex);

	dev_dbg(bdc->dev,
		"%s wValue=%d wIndex=%d	devstate=%08x speed=%d set=%d",
		__func__, wValue, wIndex, state,
		bdc->gadget.speed, set);

	switch (setup_pkt->bRequestType & USB_RECIP_MASK) {
	case USB_RECIP_DEVICE:
		return ep0_handle_feature_dev(bdc, wValue, wIndex, set);
	case USB_RECIP_INTERFACE:
		dev_dbg(bdc->dev, "USB_RECIP_INTERFACE\n");
		/* USB3 spec, sec 9.4.9 */
		if (wValue != USB_INTRF_FUNC_SUSPEND)
			return -EINVAL;
		/* USB3 spec, Table 9-8 */
		if (set) {
			if (wIndex & USB_INTRF_FUNC_SUSPEND_RW) {
				dev_dbg(bdc->dev, "SET REMOTE_WAKEUP\n");
				bdc->devstatus |= REMOTE_WAKE_ENABLE;
			} else {
				dev_dbg(bdc->dev, "CLEAR REMOTE_WAKEUP\n");
				bdc->devstatus &= ~REMOTE_WAKE_ENABLE;
			}
		}
		break;

	case USB_RECIP_ENDPOINT:
		dev_dbg(bdc->dev, "USB_RECIP_ENDPOINT\n");
		if (wValue != USB_ENDPOINT_HALT)
			return -EINVAL;

		epnum = wIndex & USB_ENDPOINT_NUMBER_MASK;
		if (epnum) {
			if ((wIndex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
				epnum = epnum * 2 + 1;
			else
				epnum *= 2;
		} else {
			epnum = 1; /*EP0*/
		}
		/*
		 * If CLEAR_FEATURE on ep0 then don't do anything as the stall
		 * condition on ep0 has already been cleared when SETUP packet
		 * was received.
		 */
		if (epnum == 1 && !set) {
			dev_dbg(bdc->dev, "ep0 stall already cleared\n");
			return 0;
		}
		dev_dbg(bdc->dev, "epnum=%d\n", epnum);
		ep = bdc->bdc_ep_array[epnum];
		if (!ep)
			return -EINVAL;

		return ep_set_halt(ep, set);
	default:
		dev_err(bdc->dev, "Unknown recipient\n");
		return -EINVAL;
	}

	return 0;
}

/* GET_STATUS request handler */
static int ep0_handle_status(struct bdc *bdc,
			     struct usb_ctrlrequest *setup_pkt)
{
	enum usb_device_state state = bdc->gadget.state;
	struct bdc_ep *ep;
	u16 usb_status = 0;
	u32 epnum;
	u16 wIndex;

	/* USB2.0 spec sec 9.4.5 */
	if (state == USB_STATE_DEFAULT)
		return -EINVAL;
	wIndex = le16_to_cpu(setup_pkt->wIndex);
	dev_dbg(bdc->dev, "%s\n", __func__);
	usb_status = bdc->devstatus;
	switch (setup_pkt->bRequestType & USB_RECIP_MASK) {
	case USB_RECIP_DEVICE:
		dev_dbg(bdc->dev,
			"USB_RECIP_DEVICE devstatus:%08x\n",
			bdc->devstatus);
		/* USB3 spec, sec 9.4.5 */
		if (bdc->gadget.speed == USB_SPEED_SUPER)
			usb_status &= ~REMOTE_WAKE_ENABLE;
		break;

	case USB_RECIP_INTERFACE:
		dev_dbg(bdc->dev, "USB_RECIP_INTERFACE\n");
		if (bdc->gadget.speed == USB_SPEED_SUPER) {
			/*
			 * This should come from func for Func remote wkup
			 * usb_status |=1;
			 */
			if (bdc->devstatus & REMOTE_WAKE_ENABLE)
				usb_status |= REMOTE_WAKE_ENABLE;
		} else {
			usb_status = 0;
		}

		break;

	case USB_RECIP_ENDPOINT:
		dev_dbg(bdc->dev, "USB_RECIP_ENDPOINT\n");
		epnum = wIndex & USB_ENDPOINT_NUMBER_MASK;
		if (epnum) {
			if ((wIndex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
				epnum = epnum*2 + 1;
			else
				epnum *= 2;
		} else {
			epnum = 1; /* EP0 */
		}

		ep = bdc->bdc_ep_array[epnum];
		if (!ep) {
			dev_err(bdc->dev, "ISSUE, GET_STATUS for invalid EP ?");
			return -EINVAL;
		}
		if (ep->flags & BDC_EP_STALL)
			usb_status |= 1 << USB_ENDPOINT_HALT;

		break;
	default:
		dev_err(bdc->dev, "Unknown recipient for get_status\n");
		return -EINVAL;
	}
	/* prepare a data stage for GET_STATUS */
	dev_dbg(bdc->dev, "usb_status=%08x\n", usb_status);
	*(__le16 *)bdc->ep0_response_buff = cpu_to_le16(usb_status);
	bdc->ep0_req.usb_req.length = 2;
	bdc->ep0_req.usb_req.buf = &bdc->ep0_response_buff;
	ep0_queue_data_stage(bdc);

	return 0;
}

static void ep0_set_sel_cmpl(struct usb_ep *_ep, struct usb_request *_req)
{
	/* ep0_set_sel_cmpl */
}

/* Queue data stage to handle 6 byte SET_SEL request */
static int ep0_set_sel(struct bdc *bdc,
			     struct usb_ctrlrequest *setup_pkt)
{
	struct bdc_ep	*ep;
	u16	wLength;
	u16	wValue;

	dev_dbg(bdc->dev, "%s\n", __func__);
	wValue = le16_to_cpu(setup_pkt->wValue);
	wLength = le16_to_cpu(setup_pkt->wLength);
	if (unlikely(wLength != 6)) {
		dev_err(bdc->dev, "%s Wrong wLength:%d\n", __func__, wLength);
		return -EINVAL;
	}
	ep = bdc->bdc_ep_array[1];
	bdc->ep0_req.ep = ep;
	bdc->ep0_req.usb_req.length = 6;
	bdc->ep0_req.usb_req.buf = bdc->ep0_response_buff;
	bdc->ep0_req.usb_req.complete = ep0_set_sel_cmpl;
	ep0_queue_data_stage(bdc);

	return 0;
}

/*
 * Queue a 0 byte bd only if wLength is more than the length and and length is
 * a multiple of MaxPacket then queue 0 byte BD
 */
static int ep0_queue_zlp(struct bdc *bdc)
{
	int ret;

	dev_dbg(bdc->dev, "%s\n", __func__);
	bdc->ep0_req.ep = bdc->bdc_ep_array[1];
	bdc->ep0_req.usb_req.length = 0;
	bdc->ep0_req.usb_req.complete = NULL;
	bdc->ep0_state = WAIT_FOR_DATA_START;
	ret = bdc_queue_xfr(bdc, &bdc->ep0_req);
	if (ret) {
		dev_err(bdc->dev, "err queueing zlp :%d\n", ret);
		return ret;
	}
	bdc->ep0_state = WAIT_FOR_DATA_XMIT;

	return 0;
}

/* Control request handler */
static int handle_control_request(struct bdc *bdc)
{
	enum usb_device_state state = bdc->gadget.state;
	struct usb_ctrlrequest *setup_pkt;
	int delegate_setup = 0;
	int ret = 0;
	int config = 0;

	setup_pkt = &bdc->setup_pkt;
	dev_dbg(bdc->dev, "%s\n", __func__);
	if ((setup_pkt->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
		switch (setup_pkt->bRequest) {
		case USB_REQ_SET_ADDRESS:
			dev_dbg(bdc->dev, "USB_REQ_SET_ADDRESS\n");
			ret = ep0_set_address(bdc, setup_pkt);
			bdc->devstatus &= DEVSTATUS_CLEAR;
			break;

		case USB_REQ_SET_CONFIGURATION:
			dev_dbg(bdc->dev, "USB_REQ_SET_CONFIGURATION\n");
			if (state == USB_STATE_ADDRESS) {
				usb_gadget_set_state(&bdc->gadget,
							USB_STATE_CONFIGURED);
			} else if (state == USB_STATE_CONFIGURED) {
				/*
				 * USB2 spec sec 9.4.7, if wValue is 0 then dev
				 * is moved to addressed state
				 */
				config = le16_to_cpu(setup_pkt->wValue);
				if (!config)
					usb_gadget_set_state(
							&bdc->gadget,
							USB_STATE_ADDRESS);
			}
			delegate_setup = 1;
			break;

		case USB_REQ_SET_FEATURE:
			dev_dbg(bdc->dev, "USB_REQ_SET_FEATURE\n");
			ret = ep0_handle_feature(bdc, setup_pkt, 1);
			break;

		case USB_REQ_CLEAR_FEATURE:
			dev_dbg(bdc->dev, "USB_REQ_CLEAR_FEATURE\n");
			ret = ep0_handle_feature(bdc, setup_pkt, 0);
			break;

		case USB_REQ_GET_STATUS:
			dev_dbg(bdc->dev, "USB_REQ_GET_STATUS\n");
			ret = ep0_handle_status(bdc, setup_pkt);
			break;

		case USB_REQ_SET_SEL:
			dev_dbg(bdc->dev, "USB_REQ_SET_SEL\n");
			ret = ep0_set_sel(bdc, setup_pkt);
			break;

		case USB_REQ_SET_ISOCH_DELAY:
			dev_warn(bdc->dev,
			"USB_REQ_SET_ISOCH_DELAY not handled\n");
			ret = 0;
			break;
		default:
			delegate_setup = 1;
		}
	} else {
		delegate_setup = 1;
	}

	if (delegate_setup) {
		spin_unlock(&bdc->lock);
		ret = bdc->gadget_driver->setup(&bdc->gadget, setup_pkt);
		spin_lock(&bdc->lock);
	}

	return ret;
}

/* EP0: Data stage started */
void bdc_xsf_ep0_data_start(struct bdc *bdc, struct bdc_sr *sreport)
{
	struct bdc_ep *ep;
	int ret = 0;

	dev_dbg(bdc->dev, "%s\n", __func__);
	ep = bdc->bdc_ep_array[1];
	/* If ep0 was stalled, the clear it first */
	if (ep->flags & BDC_EP_STALL) {
		ret = ep_set_halt(ep, 0);
		if (ret)
			goto err;
	}
	if (bdc->ep0_state != WAIT_FOR_DATA_START)
		dev_warn(bdc->dev,
			"Data stage not expected ep0_state:%s\n",
			ep0_state_string[bdc->ep0_state]);

	ret = handle_control_request(bdc);
	if (ret == USB_GADGET_DELAYED_STATUS) {
		/*
		 * The ep0 state will remain WAIT_FOR_DATA_START till
		 * we received ep_queue on ep0
		 */
		bdc->delayed_status = true;
		return;
	}
	if (!ret) {
		bdc->ep0_state = WAIT_FOR_DATA_XMIT;
		dev_dbg(bdc->dev,
			"ep0_state:%s", ep0_state_string[bdc->ep0_state]);
		return;
	}
err:
	ep0_stall(bdc);
}

/* EP0: status stage started */
void bdc_xsf_ep0_status_start(struct bdc *bdc, struct bdc_sr *sreport)
{
	struct usb_ctrlrequest *setup_pkt;
	struct bdc_ep *ep;
	int ret = 0;

	dev_dbg(bdc->dev,
		"%s ep0_state:%s",
		__func__, ep0_state_string[bdc->ep0_state]);
	ep = bdc->bdc_ep_array[1];

	/* check if ZLP was queued? */
	if (bdc->zlp_needed)
		bdc->zlp_needed = false;

	if (ep->flags & BDC_EP_STALL) {
		ret = ep_set_halt(ep, 0);
		if (ret)
			goto err;
	}

	if ((bdc->ep0_state != WAIT_FOR_STATUS_START) &&
				(bdc->ep0_state != WAIT_FOR_DATA_XMIT))
		dev_err(bdc->dev,
			"Status stage recv but ep0_state:%s\n",
			ep0_state_string[bdc->ep0_state]);

	/* check if data stage is in progress ? */
	if (bdc->ep0_state == WAIT_FOR_DATA_XMIT) {
		bdc->ep0_state = STATUS_PENDING;
		/* Status stage will be queued upon Data stage transmit event */
		dev_dbg(bdc->dev,
			"status started but data  not transmitted yet\n");
		return;
	}
	setup_pkt = &bdc->setup_pkt;

	/*
	 * 2 stage setup then only process the setup, for 3 stage setup the date
	 * stage is already handled
	 */
	if (!le16_to_cpu(setup_pkt->wLength)) {
		ret = handle_control_request(bdc);
		if (ret == USB_GADGET_DELAYED_STATUS) {
			bdc->delayed_status = true;
			/* ep0_state will remain WAIT_FOR_STATUS_START */
			return;
		}
	}
	if (!ret) {
		/* Queue a status stage BD */
		ep0_queue_status_stage(bdc);
		bdc->ep0_state = WAIT_FOR_STATUS_XMIT;
		dev_dbg(bdc->dev,
			"ep0_state:%s", ep0_state_string[bdc->ep0_state]);
		return;
	}
err:
	ep0_stall(bdc);
}

/* Helper function to update ep0 upon SR with xsf_succ or xsf_short */
static void ep0_xsf_complete(struct bdc *bdc, struct bdc_sr *sreport)
{
	dev_dbg(bdc->dev, "%s\n", __func__);
	switch (bdc->ep0_state) {
	case WAIT_FOR_DATA_XMIT:
		bdc->ep0_state = WAIT_FOR_STATUS_START;
		break;
	case WAIT_FOR_STATUS_XMIT:
		bdc->ep0_state = WAIT_FOR_SETUP;
		if (bdc->test_mode) {
			int ret;

			dev_dbg(bdc->dev, "test_mode:%d\n", bdc->test_mode);
			ret = bdc_set_test_mode(bdc);
			if (ret < 0) {
				dev_err(bdc->dev, "Err in setting Test mode\n");
				return;
			}
			bdc->test_mode = 0;
		}
		break;
	case STATUS_PENDING:
		bdc_xsf_ep0_status_start(bdc, sreport);
		break;

	default:
		dev_err(bdc->dev,
			"Unknown ep0_state:%s\n",
			ep0_state_string[bdc->ep0_state]);

	}
}

/* xfr completion status report handler */
void bdc_sr_xsf(struct bdc *bdc, struct bdc_sr *sreport)
{
	struct bdc_ep *ep;
	u32 sr_status;
	u8 ep_num;

	ep_num = (le32_to_cpu(sreport->offset[3])>>4) & 0x1f;
	ep = bdc->bdc_ep_array[ep_num];
	if (!ep || !(ep->flags & BDC_EP_ENABLED)) {
		dev_err(bdc->dev, "xsf for ep not enabled\n");
		return;
	}
	/*
	 * check if this transfer is after link went from U3->U0 due
	 * to remote wakeup
	 */
	if (bdc->devstatus & FUNC_WAKE_ISSUED) {
		bdc->devstatus &= ~(FUNC_WAKE_ISSUED);
		dev_dbg(bdc->dev, "%s clearing FUNC_WAKE_ISSUED flag\n",
								__func__);
	}
	sr_status = XSF_STS(le32_to_cpu(sreport->offset[3]));
	dev_dbg_ratelimited(bdc->dev, "%s sr_status=%d ep:%s\n",
					__func__, sr_status, ep->name);

	switch (sr_status) {
	case XSF_SUCC:
	case XSF_SHORT:
		handle_xsr_succ_status(bdc, ep, sreport);
		if (ep_num == 1)
			ep0_xsf_complete(bdc, sreport);
		break;

	case XSF_SETUP_RECV:
	case XSF_DATA_START:
	case XSF_STATUS_START:
		if (ep_num != 1) {
			dev_err(bdc->dev,
				"ep0 related packets on non ep0 endpoint");
			return;
		}
		bdc->sr_xsf_ep0[sr_status - XSF_SETUP_RECV](bdc, sreport);
		break;

	case XSF_BABB:
		if (ep_num == 1) {
			dev_dbg(bdc->dev, "Babble on ep0 zlp_need:%d\n",
							bdc->zlp_needed);
			/*
			 * If the last completed transfer had wLength >Data Len,
			 * and Len is multiple of MaxPacket,then queue ZLP
			 */
			if (bdc->zlp_needed) {
				/* queue 0 length bd */
				ep0_queue_zlp(bdc);
				return;
			}
		}
		dev_warn(bdc->dev, "Babble on ep not handled\n");
		break;
	default:
		dev_warn(bdc->dev, "sr status not handled:%x\n", sr_status);
		break;
	}
}

static int bdc_gadget_ep_queue(struct usb_ep *_ep,
				struct usb_request *_req, gfp_t gfp_flags)
{
	struct bdc_req *req;
	unsigned long flags;
	struct bdc_ep *ep;
	struct bdc *bdc;
	int ret;

	if (!_ep || !_ep->desc)
		return -ESHUTDOWN;

	if (!_req || !_req->complete || !_req->buf)
		return -EINVAL;

	ep = to_bdc_ep(_ep);
	req = to_bdc_req(_req);
	bdc = ep->bdc;
	dev_dbg(bdc->dev, "%s ep:%p req:%p\n", __func__, ep, req);
	dev_dbg(bdc->dev, "queuing request %p to %s length %d zero:%d\n",
				_req, ep->name, _req->length, _req->zero);

	if (!ep->usb_ep.desc) {
		dev_warn(bdc->dev,
			"trying to queue req %p to disabled %s\n",
			_req, ep->name);
		return -ESHUTDOWN;
	}

	if (_req->length > MAX_XFR_LEN) {
		dev_warn(bdc->dev,
			"req length > supported MAX:%d requested:%d\n",
			MAX_XFR_LEN, _req->length);
		return -EOPNOTSUPP;
	}
	spin_lock_irqsave(&bdc->lock, flags);
	if (ep == bdc->bdc_ep_array[1])
		ret = ep0_queue(ep, req);
	else
		ret = ep_queue(ep, req);

	spin_unlock_irqrestore(&bdc->lock, flags);

	return ret;
}

static int bdc_gadget_ep_dequeue(struct usb_ep *_ep,
				  struct usb_request *_req)
{
	struct bdc_req *req;
	unsigned long flags;
	struct bdc_ep *ep;
	struct bdc *bdc;
	int ret;

	if (!_ep || !_req)
		return -EINVAL;

	ep = to_bdc_ep(_ep);
	req = to_bdc_req(_req);
	bdc = ep->bdc;
	dev_dbg(bdc->dev, "%s ep:%s req:%p\n", __func__, ep->name, req);
	bdc_dbg_bd_list(bdc, ep);
	spin_lock_irqsave(&bdc->lock, flags);
	/* make sure it's still queued on this endpoint */
	list_for_each_entry(req, &ep->queue, queue) {
		if (&req->usb_req == _req)
			break;
	}
	if (&req->usb_req != _req) {
		spin_unlock_irqrestore(&bdc->lock, flags);
		dev_err(bdc->dev, "usb_req !=req n");
		return -EINVAL;
	}
	ret = ep_dequeue(ep, req);
	if (ret) {
		ret = -EOPNOTSUPP;
		goto err;
	}
	bdc_req_complete(ep, req, -ECONNRESET);

err:
	bdc_dbg_bd_list(bdc, ep);
	spin_unlock_irqrestore(&bdc->lock, flags);

	return ret;
}

static int bdc_gadget_ep_set_halt(struct usb_ep *_ep, int value)
{
	unsigned long flags;
	struct bdc_ep *ep;
	struct bdc *bdc;
	int ret;

	ep = to_bdc_ep(_ep);
	bdc = ep->bdc;
	dev_dbg(bdc->dev, "%s ep:%s value=%d\n", __func__, ep->name, value);
	spin_lock_irqsave(&bdc->lock, flags);
	if (usb_endpoint_xfer_isoc(ep->usb_ep.desc))
		ret = -EINVAL;
	else if (!list_empty(&ep->queue))
		ret = -EAGAIN;
	else
		ret = ep_set_halt(ep, value);

	spin_unlock_irqrestore(&bdc->lock, flags);

	return ret;
}

static struct usb_request *bdc_gadget_alloc_request(struct usb_ep *_ep,
						     gfp_t gfp_flags)
{
	struct bdc_req *req;
	struct bdc_ep *ep;

	req = kzalloc(sizeof(*req), gfp_flags);
	if (!req)
		return NULL;

	ep = to_bdc_ep(_ep);
	req->ep = ep;
	req->epnum = ep->ep_num;
	req->usb_req.dma = DMA_ADDR_INVALID;
	dev_dbg(ep->bdc->dev, "%s ep:%s req:%p\n", __func__, ep->name, req);

	return &req->usb_req;
}

static void bdc_gadget_free_request(struct usb_ep *_ep,
				     struct usb_request *_req)
{
	struct bdc_req *req;

	req = to_bdc_req(_req);
	kfree(req);
}

/* endpoint operations */

/* configure endpoint and also allocate resources */
static int bdc_gadget_ep_enable(struct usb_ep *_ep,
				 const struct usb_endpoint_descriptor *desc)
{
	unsigned long flags;
	struct bdc_ep *ep;
	struct bdc *bdc;
	int ret;

	if (!_ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) {
		pr_debug("bdc_gadget_ep_enable invalid parameters\n");
		return -EINVAL;
	}

	if (!desc->wMaxPacketSize) {
		pr_debug("bdc_gadget_ep_enable missing wMaxPacketSize\n");
		return -EINVAL;
	}

	ep = to_bdc_ep(_ep);
	bdc = ep->bdc;

	/* Sanity check, upper layer will not send enable for ep0 */
	if (ep == bdc->bdc_ep_array[1])
		return -EINVAL;

	if (!bdc->gadget_driver
	    || bdc->gadget.speed == USB_SPEED_UNKNOWN) {
		return -ESHUTDOWN;
	}

	dev_dbg(bdc->dev, "%s Enabling %s\n", __func__, ep->name);
	spin_lock_irqsave(&bdc->lock, flags);
	ep->desc = desc;
	ep->comp_desc = _ep->comp_desc;
	ret = bdc_ep_enable(ep);
	spin_unlock_irqrestore(&bdc->lock, flags);

	return ret;
}

static int bdc_gadget_ep_disable(struct usb_ep *_ep)
{
	unsigned long flags;
	struct bdc_ep *ep;
	struct bdc *bdc;
	int ret;

	if (!_ep) {
		pr_debug("bdc: invalid parameters\n");
		return -EINVAL;
	}
	ep = to_bdc_ep(_ep);
	bdc = ep->bdc;

	/* Upper layer will not call this for ep0, but do a sanity check */
	if (ep == bdc->bdc_ep_array[1]) {
		dev_warn(bdc->dev, "%s called for ep0\n", __func__);
		return -EINVAL;
	}
	dev_dbg(bdc->dev,
		"%s() ep:%s ep->flags:%08x\n",
		__func__, ep->name, ep->flags);

	if (!(ep->flags & BDC_EP_ENABLED)) {
		dev_warn(bdc->dev, "%s is already disabled\n", ep->name);
		return 0;
	}
	spin_lock_irqsave(&bdc->lock, flags);
	ret = bdc_ep_disable(ep);
	spin_unlock_irqrestore(&bdc->lock, flags);

	return ret;
}

static const struct usb_ep_ops bdc_gadget_ep_ops = {
	.enable = bdc_gadget_ep_enable,
	.disable = bdc_gadget_ep_disable,
	.alloc_request = bdc_gadget_alloc_request,
	.free_request = bdc_gadget_free_request,
	.queue = bdc_gadget_ep_queue,
	.dequeue = bdc_gadget_ep_dequeue,
	.set_halt = bdc_gadget_ep_set_halt
};

/* dir = 1 is IN */
static int init_ep(struct bdc *bdc, u32 epnum, u32 dir)
{
	struct bdc_ep *ep;

	dev_dbg(bdc->dev, "%s epnum=%d dir=%d\n", __func__, epnum, dir);
	ep = kzalloc(sizeof(*ep), GFP_KERNEL);
	if (!ep)
		return -ENOMEM;

	ep->bdc = bdc;
	ep->dir = dir;

	/* ep->ep_num is the index inside bdc_ep */
	if (epnum == 1) {
		ep->ep_num = 1;
		bdc->bdc_ep_array[ep->ep_num] = ep;
		snprintf(ep->name, sizeof(ep->name), "ep%d", epnum - 1);
		usb_ep_set_maxpacket_limit(&ep->usb_ep, EP0_MAX_PKT_SIZE);
		ep->comp_desc = NULL;
		bdc->gadget.ep0 = &ep->usb_ep;
	} else {
		if (dir)
			ep->ep_num = epnum * 2 - 1;
		else
			ep->ep_num = epnum * 2 - 2;

		bdc->bdc_ep_array[ep->ep_num] = ep;
		snprintf(ep->name, sizeof(ep->name), "ep%d%s", epnum - 1,
			 dir & 1 ? "in" : "out");

		usb_ep_set_maxpacket_limit(&ep->usb_ep, 1024);
		ep->usb_ep.max_streams = 0;
		list_add_tail(&ep->usb_ep.ep_list, &bdc->gadget.ep_list);
	}
	ep->usb_ep.ops = &bdc_gadget_ep_ops;
	ep->usb_ep.name = ep->name;
	ep->flags = 0;
	ep->ignore_next_sr = false;
	dev_dbg(bdc->dev, "ep=%p ep->usb_ep.name=%s epnum=%d ep->epnum=%d\n",
				ep, ep->usb_ep.name, epnum, ep->ep_num);

	INIT_LIST_HEAD(&ep->queue);

	return 0;
}

/* Init all ep */
int bdc_init_ep(struct bdc *bdc)
{
	u8 epnum;
	int ret;

	dev_dbg(bdc->dev, "%s()\n", __func__);
	INIT_LIST_HEAD(&bdc->gadget.ep_list);
	/* init ep0 */
	ret = init_ep(bdc, 1, 0);
	if (ret) {
		dev_err(bdc->dev, "init ep ep0 fail %d\n", ret);
		return ret;
	}

	for (epnum = 2; epnum <= bdc->num_eps / 2; epnum++) {
		/* OUT */
		ret = init_ep(bdc, epnum, 0);
		if (ret) {
			dev_err(bdc->dev,
				"init ep failed for:%d error: %d\n",
				epnum, ret);
			return ret;
		}

		/* IN */
		ret = init_ep(bdc, epnum, 1);
		if (ret) {
			dev_err(bdc->dev,
				"init ep failed for:%d error: %d\n",
				epnum, ret);
			return ret;
		}
	}

	return 0;
}
