[U-Boot] [u-boot 15/40] usb: dwc3: gadget: make dwc3 gadget build in uboot
Lukasz Majewski
l.majewski at samsung.com
Mon Feb 16 11:52:11 CET 2015
Hi Kishon,
> Did a bunch of things to get dwc3/gadget.c compile in u-boot without
> build errors and warnings
> *) Changed the included header files to that used in u-boot.
> *) Used dma_alloc_coherent and dma_free_coherent APIs of u-boot
> *) removed sg support
> *) remove jiffies and used a simple while loop
> *) removed irq support and added a function to call these interrupt
> handler.
>
> Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
> ---
> drivers/usb/dwc3/gadget.c | 244
> ++++++++++++++-------------------------
> drivers/usb/dwc3/gadget.h | 1 +
> drivers/usb/dwc3/linux-compat.h | 3 -
> include/linux/compat.h | 1 +
> include/linux/usb/gadget.h | 39 +++++++ 5 files changed, 125
> insertions(+), 163 deletions(-)
>
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index 7c932c6..1f97729 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -14,25 +14,22 @@
> * SPDX-License-Identifier: GPL-2.0
> */
>
> -#include <linux/kernel.h>
> -#include <linux/delay.h>
> -#include <linux/slab.h>
> -#include <linux/spinlock.h>
> -#include <linux/platform_device.h>
> -#include <linux/pm_runtime.h>
> -#include <linux/interrupt.h>
> -#include <linux/io.h>
> +#include <common.h>
> +#include <malloc.h>
> +#include <asm/dma-mapping.h>
> +#include <usb/lin_gadget_compat.h>
> #include <linux/list.h>
> -#include <linux/dma-mapping.h>
>
> #include <linux/usb/ch9.h>
> #include <linux/usb/gadget.h>
> +#include <asm/arch/sys_proto.h>
>
> -#include "debug.h"
> #include "core.h"
> #include "gadget.h"
> #include "io.h"
>
> +#include "linux-compat.h"
> +
> /**
> * dwc3_gadget_set_test_mode - Enables USB2 Test Modes
> * @dwc: pointer to our context structure
> @@ -166,7 +163,6 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc,
> enum dwc3_link_state state) int dwc3_gadget_resize_tx_fifos(struct
> dwc3 *dwc) {
> int last_fifo_depth = 0;
> - int ram1_depth;
> int fifo_size;
> int mdwidth;
> int num;
> @@ -174,7 +170,6 @@ int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc)
> if (!dwc->needs_fifo_resize)
> return 0;
>
> - ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7);
> mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0);
>
> /* MDWIDTH is represented in bits, we need it in bytes */
> @@ -232,24 +227,21 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep,
> struct dwc3_request *req, int status)
> {
> struct dwc3 *dwc = dep->dwc;
> - int i;
>
> if (req->queued) {
> - i = 0;
> - do {
> + dep->busy_slot++;
> + /*
> + * Skip LINK TRB. We can't use req->trb and check for
> + * DWC3_TRBCTL_LINK_TRB because it points the TRB we
> + * just completed (not the LINK TRB).
> + */
> + if (((dep->busy_slot & DWC3_TRB_MASK) ==
> + DWC3_TRB_NUM- 1) &&
> + usb_endpoint_xfer_isoc(dep->endpoint.desc))
> dep->busy_slot++;
> - /*
> - * Skip LINK TRB. We can't use req->trb and
> check for
> - * DWC3_TRBCTL_LINK_TRB because it points
> the TRB we
> - * just completed (not the LINK TRB).
> - */
> - if (((dep->busy_slot & DWC3_TRB_MASK) ==
> - DWC3_TRB_NUM- 1) &&
> -
> usb_endpoint_xfer_isoc(dep->endpoint.desc))
> - dep->busy_slot++;
> - } while(++i < req->request.num_mapped_sgs);
> req->queued = false;
> }
> +
> list_del(&req->list);
> req->trb = NULL;
>
> @@ -301,7 +293,6 @@ int dwc3_send_gadget_generic_command(struct dwc3
> *dwc, unsigned cmd, u32 param) int dwc3_send_gadget_ep_cmd(struct
> dwc3 *dwc, unsigned ep, unsigned cmd, struct
> dwc3_gadget_ep_cmd_params *params) {
> - struct dwc3_ep *dep = dwc->eps[ep];
> u32 timeout = 500;
> u32 reg;
>
> @@ -340,17 +331,15 @@ static dma_addr_t dwc3_trb_dma_offset(struct
> dwc3_ep *dep,
> static int dwc3_alloc_trb_pool(struct dwc3_ep *dep)
> {
> - struct dwc3 *dwc = dep->dwc;
> -
> if (dep->trb_pool)
> return 0;
>
> if (dep->number == 0 || dep->number == 1)
> return 0;
>
> - dep->trb_pool = dma_alloc_coherent(dwc->dev,
> - sizeof(struct dwc3_trb) * DWC3_TRB_NUM,
> - &dep->trb_pool_dma, GFP_KERNEL);
> + dep->trb_pool = dma_alloc_coherent(sizeof(struct dwc3_trb) *
> + DWC3_TRB_NUM,
> + (unsigned long
> *)&dep->trb_pool_dma); if (!dep->trb_pool) {
> dev_err(dep->dwc->dev, "failed to allocate trb pool
> for %s\n", dep->name);
> @@ -362,10 +351,7 @@ static int dwc3_alloc_trb_pool(struct dwc3_ep
> *dep)
> static void dwc3_free_trb_pool(struct dwc3_ep *dep)
> {
> - struct dwc3 *dwc = dep->dwc;
> -
> - dma_free_coherent(dwc->dev, sizeof(struct dwc3_trb) *
> DWC3_TRB_NUM,
> - dep->trb_pool, dep->trb_pool_dma);
> + dma_free_coherent(dep->trb_pool);
>
> dep->trb_pool = NULL;
> dep->trb_pool_dma = 0;
> @@ -607,7 +593,6 @@ static int dwc3_gadget_ep_enable(struct usb_ep
> *ep, const struct usb_endpoint_descriptor *desc)
> {
> struct dwc3_ep *dep;
> - struct dwc3 *dwc;
> unsigned long flags;
> int ret;
>
> @@ -622,10 +607,9 @@ static int dwc3_gadget_ep_enable(struct usb_ep
> *ep, }
>
> dep = to_dwc3_ep(ep);
> - dwc = dep->dwc;
>
> if (dep->flags & DWC3_EP_ENABLED) {
> - dev_WARN_ONCE(dwc->dev, true, "%s is already
> enabled\n",
> + WARN(true, "%s is already enabled\n",
> dep->name);
> return 0;
> }
> @@ -657,7 +641,6 @@ static int dwc3_gadget_ep_enable(struct usb_ep
> *ep, static int dwc3_gadget_ep_disable(struct usb_ep *ep)
> {
> struct dwc3_ep *dep;
> - struct dwc3 *dwc;
> unsigned long flags;
> int ret;
>
> @@ -667,10 +650,9 @@ static int dwc3_gadget_ep_disable(struct usb_ep
> *ep) }
>
> dep = to_dwc3_ep(ep);
> - dwc = dep->dwc;
>
> if (!(dep->flags & DWC3_EP_ENABLED)) {
> - dev_WARN_ONCE(dwc->dev, true, "%s is already
> disabled\n",
> + WARN(true, "%s is already disabled\n",
> dep->name);
> return 0;
> }
> @@ -719,7 +701,6 @@ static void dwc3_prepare_one_trb(struct dwc3_ep
> *dep, struct dwc3_request *req, dma_addr_t dma,
> unsigned length, unsigned last, unsigned chain,
> unsigned node) {
> - struct dwc3 *dwc = dep->dwc;
> struct dwc3_trb *trb;
>
> dev_vdbg(dwc->dev, "%s: req %p dma %08llx length %d%s%s\n",
> @@ -856,57 +837,22 @@ static void dwc3_prepare_trbs(struct dwc3_ep
> *dep, bool starting) dma_addr_t dma;
> last_one = false;
>
> - if (req->request.num_mapped_sgs > 0) {
> - struct usb_request *request = &req->request;
> - struct scatterlist *sg = request->sg;
> - struct scatterlist *s;
> - int i;
> -
> - for_each_sg(sg, s, request->num_mapped_sgs,
> i) {
> - unsigned chain = true;
> + dma = req->request.dma;
> + length = req->request.length;
> + trbs_left--;
>
> - length = sg_dma_len(s);
> - dma = sg_dma_address(s);
> + if (!trbs_left)
> + last_one = 1;
>
> - if (i == (request->num_mapped_sgs -
> 1) ||
> - sg_is_last(s)) {
> - if (list_is_last(&req->list,
> -
> &dep->request_list))
> - last_one = true;
> - chain = false;
> - }
> + /* Is this the last request? */
> + if (list_is_last(&req->list, &dep->request_list))
> + last_one = 1;
>
> - trbs_left--;
> - if (!trbs_left)
> - last_one = true;
> + dwc3_prepare_one_trb(dep, req, dma, length,
> + last_one, false, 0);
>
> - if (last_one)
> - chain = false;
> -
> - dwc3_prepare_one_trb(dep, req, dma,
> length,
> - last_one, chain, i);
> -
> - if (last_one)
> - break;
> - }
> - } else {
> - dma = req->request.dma;
> - length = req->request.length;
> - trbs_left--;
> -
> - if (!trbs_left)
> - last_one = 1;
> -
> - /* Is this the last request? */
> - if (list_is_last(&req->list,
> &dep->request_list))
> - last_one = 1;
> -
> - dwc3_prepare_one_trb(dep, req, dma, length,
> - last_one, false, 0);
> -
> - if (last_one)
> - break;
> - }
> + if (last_one)
> + break;
> }
> }
>
> @@ -1103,8 +1049,6 @@ static int __dwc3_gadget_ep_queue(struct
> dwc3_ep *dep, struct dwc3_request *req)
> ret = __dwc3_gadget_kick_transfer(dep, 0, true);
> if (ret && ret != -EBUSY) {
> - struct dwc3 *dwc = dep->dwc;
> -
> dev_dbg(dwc->dev, "%s: failed to kick
> transfers\n", dep->name);
> }
> @@ -1118,7 +1062,6 @@ static int dwc3_gadget_ep_queue(struct usb_ep
> *ep, struct usb_request *request, {
> struct dwc3_request *req =
> to_dwc3_request(request); struct dwc3_ep *dep
> = to_dwc3_ep(ep);
> - struct dwc3 *dwc = dep->dwc;
>
> unsigned long flags;
>
> @@ -1132,8 +1075,9 @@ static int dwc3_gadget_ep_queue(struct usb_ep
> *ep, struct usb_request *request, goto out;
> }
>
> - if (WARN(req->dep != dep, "request %p belongs to '%s'\n",
> - request, req->dep->name)) {
> + if (req->dep != dep) {
> + WARN(true, "request %p belongs to '%s'\n",
> + request, req->dep->name);
> ret = -EINVAL;
> goto out;
> }
> @@ -1239,7 +1183,6 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep
> *dep, int value, int protocol) static int
> dwc3_gadget_ep_set_halt(struct usb_ep *ep, int value) {
> struct dwc3_ep *dep = to_dwc3_ep(ep);
> - struct dwc3 *dwc = dep->dwc;
>
> unsigned long flags;
>
> @@ -1255,7 +1198,6 @@ static int dwc3_gadget_ep_set_halt(struct
> usb_ep *ep, int value) static int dwc3_gadget_ep_set_wedge(struct
> usb_ep *ep) {
> struct dwc3_ep *dep = to_dwc3_ep(ep);
> - struct dwc3 *dwc = dep->dwc;
> unsigned long flags;
> int ret;
>
> @@ -1371,9 +1313,9 @@ static int dwc3_gadget_wakeup(struct usb_gadget
> *g) }
>
> /* poll until Link State changes to ON */
> - timeout = jiffies + msecs_to_jiffies(100);
> + timeout = 1000;
>
> - while (!time_after(jiffies, timeout)) {
> + while (timeout--) {
> reg = dwc3_readl(dwc->regs, DWC3_DSTS);
>
> /* in HS, means ON */
> @@ -1498,9 +1440,6 @@ static void dwc3_gadget_disable_irq(struct dwc3
> *dwc) dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00);
> }
>
> -static irqreturn_t dwc3_interrupt(int irq, void *_dwc);
> -static irqreturn_t dwc3_thread_interrupt(int irq, void *_dwc);
> -
> static int dwc3_gadget_start(struct usb_gadget *g,
> struct usb_gadget_driver *driver)
> {
> @@ -1508,24 +1447,14 @@ static int dwc3_gadget_start(struct
> usb_gadget *g, struct dwc3_ep *dep;
> unsigned long flags;
> int ret = 0;
> - int irq;
> u32 reg;
>
> - irq = platform_get_irq(to_platform_device(dwc->dev), 0);
> - ret = request_threaded_irq(irq, dwc3_interrupt,
> dwc3_thread_interrupt,
> - IRQF_SHARED, "dwc3", dwc);
> - if (ret) {
> - dev_err(dwc->dev, "failed to request irq #%d -->
> %d\n",
> - irq, ret);
> - goto err0;
> - }
> -
> spin_lock_irqsave(&dwc->lock, flags);
>
> if (dwc->gadget_driver) {
> dev_err(dwc->dev, "%s is already bound to %s\n",
> dwc->gadget.name,
> - dwc->gadget_driver->driver.name);
> + dwc->gadget_driver->function);
> ret = -EBUSY;
> goto err1;
> }
> @@ -1609,9 +1538,6 @@ err2:
> err1:
> spin_unlock_irqrestore(&dwc->lock, flags);
>
> - free_irq(irq, dwc);
> -
> -err0:
> return ret;
> }
>
> @@ -1619,7 +1545,6 @@ static int dwc3_gadget_stop(struct usb_gadget
> *g) {
> struct dwc3 *dwc = gadget_to_dwc(g);
> unsigned long flags;
> - int irq;
>
> spin_lock_irqsave(&dwc->lock, flags);
>
> @@ -1631,9 +1556,6 @@ static int dwc3_gadget_stop(struct usb_gadget
> *g)
> spin_unlock_irqrestore(&dwc->lock, flags);
>
> - irq = platform_get_irq(to_platform_device(dwc->dev), 0);
> - free_irq(irq, dwc);
> -
> return 0;
> }
>
> @@ -1832,7 +1754,6 @@ static int dwc3_cleanup_done_reqs(struct dwc3
> *dwc, struct dwc3_ep *dep, struct dwc3_request *req;
> struct dwc3_trb *trb;
> unsigned int slot;
> - unsigned int i;
> int ret;
>
> do {
> @@ -1841,20 +1762,18 @@ static int dwc3_cleanup_done_reqs(struct dwc3
> *dwc, struct dwc3_ep *dep, WARN_ON_ONCE(1);
> return 1;
> }
> - i = 0;
> - do {
> - slot = req->start_slot + i;
> - if ((slot == DWC3_TRB_NUM - 1) &&
> -
> usb_endpoint_xfer_isoc(dep->endpoint.desc))
> - slot++;
> - slot %= DWC3_TRB_NUM;
> - trb = &dep->trb_pool[slot];
> -
> - ret = __dwc3_cleanup_done_trbs(dwc, dep,
> req, trb,
> - event, status);
> - if (ret)
> - break;
> - }while (++i < req->request.num_mapped_sgs);
> +
> + slot = req->start_slot;
> + if ((slot == DWC3_TRB_NUM - 1) &&
> + usb_endpoint_xfer_isoc(dep->endpoint.desc))
> + slot++;
> + slot %= DWC3_TRB_NUM;
> + trb = &dep->trb_pool[slot];
> +
> + ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb,
> + event, status);
> + if (ret)
> + break;
>
> dwc3_gadget_giveback(dep, req, status);
>
> @@ -2293,9 +2212,8 @@ static void
> dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
> * BESL value in the LPM token is less than or equal
> to LPM
> * NYET threshold.
> */
> - WARN_ONCE(dwc->revision < DWC3_REVISION_240A
> - && dwc->has_lpm_erratum,
> - "LPM Erratum not available on dwc3
> revisisions < 2.40a\n");
> + if (dwc->revision < DWC3_REVISION_240A &&
> dwc->has_lpm_erratum)
> + WARN(true, "LPM Erratum not available on
> dwc3 revisisions < 2.40a\n");
> if (dwc->has_lpm_erratum && dwc->revision >=
> DWC3_REVISION_240A) reg |=
> DWC3_DCTL_LPM_ERRATA(dwc->lpm_nyet_threshold); @@ -2482,10 +2400,10
> @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc,
> dwc3_gadget_wakeup_interrupt(dwc); break;
> case DWC3_DEVICE_EVENT_HIBER_REQ:
> - if (dev_WARN_ONCE(dwc->dev, !dwc->has_hibernation,
> - "unexpected hibernation
> event\n"))
> + if (!dwc->has_hibernation) {
> + WARN(1 ,"unexpected hibernation event\n");
> break;
> -
> + }
> dwc3_gadget_hibernation_interrupt(dwc,
> event->event_info); break;
> case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
> @@ -2649,16 +2567,16 @@ int dwc3_gadget_init(struct dwc3 *dwc)
> {
> int ret;
>
> - dwc->ctrl_req = dma_alloc_coherent(dwc->dev,
> sizeof(*dwc->ctrl_req),
> - &dwc->ctrl_req_addr, GFP_KERNEL);
> + dwc->ctrl_req = dma_alloc_coherent(sizeof(*dwc->ctrl_req),
> + (unsigned long
> *)&dwc->ctrl_req_addr); if (!dwc->ctrl_req) {
> dev_err(dwc->dev, "failed to allocate ctrl
> request\n"); ret = -ENOMEM;
> goto err0;
> }
>
> - dwc->ep0_trb = dma_alloc_coherent(dwc->dev,
> sizeof(*dwc->ep0_trb),
> - &dwc->ep0_trb_addr, GFP_KERNEL);
> + dwc->ep0_trb = dma_alloc_coherent(sizeof(*dwc->ep0_trb),
> + (unsigned long
> *)&dwc->ep0_trb_addr); if (!dwc->ep0_trb) {
> dev_err(dwc->dev, "failed to allocate ep0 trb\n");
> ret = -ENOMEM;
> @@ -2671,9 +2589,8 @@ int dwc3_gadget_init(struct dwc3 *dwc)
> goto err2;
> }
>
> - dwc->ep0_bounce = dma_alloc_coherent(dwc->dev,
> - DWC3_EP0_BOUNCE_SIZE, &dwc->ep0_bounce_addr,
> - GFP_KERNEL);
> + dwc->ep0_bounce = dma_alloc_coherent(DWC3_EP0_BOUNCE_SIZE,
> + (unsigned long
> *)&dwc->ep0_bounce_addr); if (!dwc->ep0_bounce) {
> dev_err(dwc->dev, "failed to allocate ep0 bounce
> buffer\n"); ret = -ENOMEM;
> @@ -2683,7 +2600,6 @@ int dwc3_gadget_init(struct dwc3 *dwc)
> dwc->gadget.ops = &dwc3_gadget_ops;
> dwc->gadget.max_speed = USB_SPEED_SUPER;
> dwc->gadget.speed = USB_SPEED_UNKNOWN;
> - dwc->gadget.sg_supported = true;
> dwc->gadget.name = "dwc3-gadget";
>
> /*
> @@ -2711,19 +2627,16 @@ int dwc3_gadget_init(struct dwc3 *dwc)
>
> err4:
> dwc3_gadget_free_endpoints(dwc);
> - dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
> - dwc->ep0_bounce, dwc->ep0_bounce_addr);
> + dma_free_coherent(dwc->ep0_bounce);
>
> err3:
> kfree(dwc->setup_buf);
>
> err2:
> - dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
> - dwc->ep0_trb, dwc->ep0_trb_addr);
> + dma_free_coherent(dwc->ep0_trb);
>
> err1:
> - dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
> - dwc->ctrl_req, dwc->ctrl_req_addr);
> + dma_free_coherent(dwc->ctrl_req);
>
> err0:
> return ret;
> @@ -2737,14 +2650,25 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
>
> dwc3_gadget_free_endpoints(dwc);
>
> - dma_free_coherent(dwc->dev, DWC3_EP0_BOUNCE_SIZE,
> - dwc->ep0_bounce, dwc->ep0_bounce_addr);
> + dma_free_coherent(dwc->ep0_bounce);
>
> kfree(dwc->setup_buf);
>
> - dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
> - dwc->ep0_trb, dwc->ep0_trb_addr);
> + dma_free_coherent(dwc->ep0_trb);
>
> - dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
> - dwc->ctrl_req, dwc->ctrl_req_addr);
> + dma_free_coherent(dwc->ctrl_req);
> +}
> +
> +/**
> + * dwc3_gadget_uboot_handle_interrupt - handle dwc3 gadget interrupt
> + * @dwc: struct dwce *
> + *
> + * Handles ep0 and gadget interrupt
> + *
> + * Should be called from dwc3 core.
> + */
> +void dwc3_gadget_uboot_handle_interrupt(struct dwc3 *dwc)
> +{
> + dwc3_interrupt(0, dwc);
> + dwc3_thread_interrupt(0, dwc);
> }
> diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
> index 042e247..c7db219 100644
> --- a/drivers/usb/dwc3/gadget.h
> +++ b/drivers/usb/dwc3/gadget.h
> @@ -87,6 +87,7 @@ int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int
> value); int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct
> usb_request *request, gfp_t gfp_flags);
> int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int
> protocol); +void dwc3_gadget_uboot_handle_interrupt(struct dwc3 *dwc);
>
> /**
> * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW
> diff --git a/drivers/usb/dwc3/linux-compat.h
> b/drivers/usb/dwc3/linux-compat.h index 58c4716..719e82e 100644
> --- a/drivers/usb/dwc3/linux-compat.h
> +++ b/drivers/usb/dwc3/linux-compat.h
> @@ -5,9 +5,6 @@
> *
> * Authors: Kishon Vijay Abraham I <kishon at ti.com>
> *
> - * Taken from Linux Kernel v3.16 (drivers/usb/dwc3/core.c) and ported
> - * to uboot.
> - *
> * SPDX-License-Identifier: GPL-2.0
> *
> */
> diff --git a/include/linux/compat.h b/include/linux/compat.h
> index b40133c..904425a 100644
> --- a/include/linux/compat.h
> +++ b/include/linux/compat.h
> @@ -327,6 +327,7 @@ typedef unsigned long dmaaddr_t;
>
> #define IRQ_NONE 0
> #define IRQ_HANDLED 1
> +#define IRQ_WAKE_THREAD 2
>
> #define dev_set_drvdata(dev, data) do {} while (0)
>
> diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
> index 1960958..93a5ffc 100644
> --- a/include/linux/usb/gadget.h
> +++ b/include/linux/usb/gadget.h
> @@ -31,6 +31,7 @@ struct usb_ep;
> * @dma: DMA address corresponding to 'buf'. If you don't set this
> * field, and the usb controller needs one, it is responsible
> * for mapping and unmapping the buffer.
> + * @stream_id: The stream id, when USB3.0 bulk streams are being used
> * @length: Length of that data
> * @no_interrupt: If true, hints that no completion irq is needed.
> * Helpful sometimes with deep request queues that are handled
> @@ -85,6 +86,7 @@ struct usb_request {
> unsigned length;
> dma_addr_t dma;
>
> + unsigned stream_id:16;
> unsigned no_interrupt:1;
> unsigned zero:1;
> unsigned short_not_ok:1;
> @@ -121,6 +123,7 @@ struct usb_ep_ops {
> int (*dequeue) (struct usb_ep *ep, struct usb_request *req);
>
> int (*set_halt) (struct usb_ep *ep, int value);
> + int (*set_wedge)(struct usb_ep *ep);
> int (*fifo_status) (struct usb_ep *ep);
> void (*fifo_flush) (struct usb_ep *ep);
> };
> @@ -133,8 +136,18 @@ struct usb_ep_ops {
> * @maxpacket:The maximum packet size used on this endpoint. The
> initial
> * value can sometimes be reduced (hardware allowing),
> according to
> * the endpoint descriptor used to configure the endpoint.
> + * @maxpacket_limit:The maximum packet size value which can be
> handled by this
> + * endpoint. It's set once by UDC driver when endpoint is
> initialized, and
> + * should not be changed. Should not be confused with
> maxpacket.
> + * @max_streams: The maximum number of streams supported
> + * by this EP (0 - 16, actual number is 2^n)
> + * @maxburst: the maximum number of bursts supported by this EP (for
> usb3)
> * @driver_data:for use by the gadget driver. all other fields are
> * read-only to gadget drivers.
> + * @desc: endpoint descriptor. This pointer is set before the
> endpoint is
> + * enabled and remains valid until the endpoint is disabled.
> + * @comp_desc: In case of SuperSpeed support, this is the endpoint
> companion
> + * descriptor that is used to configure the endpoint
> *
> * the bus controller driver lists all the general purpose endpoints
> in
> * gadget->ep_list. the control endpoint (gadget->ep0) is not in
> that list, @@ -146,11 +159,31 @@ struct usb_ep {
> const struct usb_ep_ops *ops;
> struct list_head ep_list;
> unsigned maxpacket:16;
> + unsigned maxpacket_limit:16;
> + unsigned max_streams:16;
> + unsigned maxburst:5;
> + const struct usb_endpoint_descriptor *desc;
> + const struct usb_ss_ep_comp_descriptor *comp_desc;
> };
>
> /*-------------------------------------------------------------------------*/
>
> /**
> + * usb_ep_set_maxpacket_limit - set maximum packet size limit for
> endpoint
> + * @ep:the endpoint being configured
> + * @maxpacket_limit:value of maximum packet size limit
> + *
> + * This function shoud be used only in UDC drivers to initialize
> endpoint
> + * (usually in probe function).
> + */
> +static inline void usb_ep_set_maxpacket_limit(struct usb_ep *ep,
> + unsigned
> maxpacket_limit) +{
> + ep->maxpacket_limit = maxpacket_limit;
> + ep->maxpacket = maxpacket_limit;
> +}
> +
> +/**
> * usb_ep_enable - configure endpoint, making it usable
> * @ep:the endpoint being configured. may not be the endpoint named
> "ep0".
> * drivers discover endpoints through the ep_list of a
> usb_gadget. @@ -422,6 +455,8 @@ struct usb_gadget_ops {
> * driver setup() requests
> * @ep_list: List of other endpoints supported by the device.
> * @speed: Speed of current connection to USB host.
> + * @max_speed: Maximal speed the UDC can handle. UDC must support
> this
> + * and all slower speeds.
> * @is_dualspeed: true if the controller supports both high and full
> speed
> * operation. If it does, the gadget driver must also
> support both.
> * @is_otg: true if the USB device port uses a Mini-AB jack, so that
> the @@ -438,6 +473,8 @@ struct usb_gadget_ops {
> * @name: Identifies the controller hardware type. Used in
> diagnostics
> * and sometimes configuration.
> * @dev: Driver model state for this abstract device.
> + * @quirk_ep_out_aligned_size: epout requires buffer size to be
> aligned to
> + * MaxPacketSize.
> *
> * Gadgets have a mostly-portable "gadget driver" implementing device
> * functions, handling all usb configurations and interfaces. Gadget
> @@ -463,6 +500,7 @@ struct usb_gadget {
> struct usb_ep *ep0;
> struct list_head ep_list; /* of usb_ep
> */ enum usb_device_speed speed;
> + enum usb_device_speed max_speed;
> enum usb_device_state state;
> unsigned is_dualspeed:1;
> unsigned is_otg:1;
> @@ -472,6 +510,7 @@ struct usb_gadget {
> unsigned a_alt_hnp_support:1;
> const char *name;
> struct device dev;
> + unsigned quirk_ep_out_aligned_size:1;
> };
>
> static inline void set_gadget_data(struct usb_gadget *gadget, void
> *data)
Reviewed-by: Lukasz Majewski <l.majewski at samsung.com>
--
Best regards,
Lukasz Majewski
Samsung R&D Institute Poland (SRPOL) | Linux Platform Group
More information about the U-Boot
mailing list