Revert: d7022078269b93dc6ee613a0a8519ce2ebe4a726
Accidentally merged without proper testing.
Change-Id: Iea6c3f7cd383357ac657fd15fde08cbab86bf809
Signed-off-by: David Brown <davidb@codeaurora.org>
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 288b570..48f1781 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -110,8 +110,6 @@
source "drivers/usb/core/Kconfig"
-source "drivers/usb/dwc3/Kconfig"
-
source "drivers/usb/mon/Kconfig"
source "drivers/usb/wusbcore/Kconfig"
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 0fd0bbd..ef69048 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -6,8 +6,6 @@
obj-$(CONFIG_USB) += core/
-obj-$(CONFIG_USB_DWC3) += dwc3/
-
obj-$(CONFIG_USB_MON) += mon/
obj-$(CONFIG_USB_OTG_UTILS) += otg/
diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig
deleted file mode 100644
index 3c1d67d..0000000
--- a/drivers/usb/dwc3/Kconfig
+++ /dev/null
@@ -1,25 +0,0 @@
-config USB_DWC3
- tristate "DesignWare USB3 DRD Core Support"
- depends on (USB || USB_GADGET)
- select USB_OTG_UTILS
- help
- Say Y or M here if your system has a Dual Role SuperSpeed
- USB controller based on the DesignWare USB3 IP Core.
-
- If you choose to build this driver is a dynamically linked
- module, the module will be called dwc3.ko.
-
-if USB_DWC3
-
-config USB_DWC3_DEBUG
- bool "Enable Debugging Messages"
- help
- Say Y here to enable debugging messages on DWC3 Driver.
-
-config USB_DWC3_VERBOSE
- bool "Enable Verbose Debugging Messages"
- depends on USB_DWC3_DEBUG
- help
- Say Y here to enable verbose debugging messages on DWC3 Driver.
-
-endif
diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
deleted file mode 100644
index 593d1db..0000000
--- a/drivers/usb/dwc3/Makefile
+++ /dev/null
@@ -1,36 +0,0 @@
-ccflags-$(CONFIG_USB_DWC3_DEBUG) := -DDEBUG
-ccflags-$(CONFIG_USB_DWC3_VERBOSE) += -DVERBOSE_DEBUG
-
-obj-$(CONFIG_USB_DWC3) += dwc3.o
-
-dwc3-y := core.o
-
-ifneq ($(CONFIG_USB_GADGET_DWC3),)
- dwc3-y += gadget.o ep0.o
-endif
-
-ifneq ($(CONFIG_DEBUG_FS),)
- dwc3-y += debugfs.o
-endif
-
-##
-# Platform-specific glue layers go here
-#
-# NOTICE: Make sure your glue layer doesn't depend on anything
-# which is arch-specific and that it compiles on all situations.
-#
-# We want to keep this requirement in order to be able to compile
-# the entire driver (with all its glue layers) on several architectures
-# and make sure it compiles fine. This will also help with allmodconfig
-# and allyesconfig builds.
-#
-# The only exception is the PCI glue layer, but that's only because
-# PCI doesn't provide nops if CONFIG_PCI isn't enabled.
-##
-
-obj-$(CONFIG_USB_DWC3) += dwc3-omap.o
-
-ifneq ($(CONFIG_PCI),)
- obj-$(CONFIG_USB_DWC3) += dwc3-pci.o
-endif
-
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
deleted file mode 100644
index 717ebc9..0000000
--- a/drivers/usb/dwc3/core.c
+++ /dev/null
@@ -1,484 +0,0 @@
-/**
- * core.c - DesignWare USB3 DRD Controller Core file
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * 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") version 2, as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.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/ioport.h>
-#include <linux/io.h>
-#include <linux/list.h>
-#include <linux/delay.h>
-#include <linux/dma-mapping.h>
-
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-#include <linux/module.h>
-
-#include "core.h"
-#include "gadget.h"
-#include "io.h"
-
-#include "debug.h"
-
-/**
- * dwc3_core_soft_reset - Issues core soft reset and PHY reset
- * @dwc: pointer to our context structure
- */
-static void dwc3_core_soft_reset(struct dwc3 *dwc)
-{
- u32 reg;
-
- /* Before Resetting PHY, put Core in Reset */
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
- reg |= DWC3_GCTL_CORESOFTRESET;
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
-
- /* Assert USB3 PHY reset */
- reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
- reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
-
- /* Assert USB2 PHY reset */
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
- reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
-
- mdelay(100);
-
- /* Clear USB3 PHY reset */
- reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
- reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
-
- /* Clear USB2 PHY reset */
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
- reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
-
- /* After PHYs are stable we can take Core out of reset state */
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
- reg &= ~DWC3_GCTL_CORESOFTRESET;
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
-}
-
-/**
- * dwc3_free_one_event_buffer - Frees one event buffer
- * @dwc: Pointer to our controller context structure
- * @evt: Pointer to event buffer to be freed
- */
-static void dwc3_free_one_event_buffer(struct dwc3 *dwc,
- struct dwc3_event_buffer *evt)
-{
- dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma);
- kfree(evt);
-}
-
-/**
- * dwc3_alloc_one_event_buffer - Allocated one event buffer structure
- * @dwc: Pointer to our controller context structure
- * @length: size of the event buffer
- *
- * Returns a pointer to the allocated event buffer structure on succes
- * otherwise ERR_PTR(errno).
- */
-static struct dwc3_event_buffer *__devinit
-dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length)
-{
- struct dwc3_event_buffer *evt;
-
- evt = kzalloc(sizeof(*evt), GFP_KERNEL);
- if (!evt)
- return ERR_PTR(-ENOMEM);
-
- evt->dwc = dwc;
- evt->length = length;
- evt->buf = dma_alloc_coherent(dwc->dev, length,
- &evt->dma, GFP_KERNEL);
- if (!evt->buf) {
- kfree(evt);
- return ERR_PTR(-ENOMEM);
- }
-
- return evt;
-}
-
-/**
- * dwc3_free_event_buffers - frees all allocated event buffers
- * @dwc: Pointer to our controller context structure
- */
-static void dwc3_free_event_buffers(struct dwc3 *dwc)
-{
- struct dwc3_event_buffer *evt;
- int i;
-
- for (i = 0; i < DWC3_EVENT_BUFFERS_NUM; i++) {
- evt = dwc->ev_buffs[i];
- if (evt) {
- dwc3_free_one_event_buffer(dwc, evt);
- dwc->ev_buffs[i] = NULL;
- }
- }
-}
-
-/**
- * dwc3_alloc_event_buffers - Allocates @num event buffers of size @length
- * @dwc: Pointer to out controller context structure
- * @num: number of event buffers to allocate
- * @length: size of event buffer
- *
- * Returns 0 on success otherwise negative errno. In error the case, dwc
- * may contain some buffers allocated but not all which were requested.
- */
-static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned num,
- unsigned length)
-{
- int i;
-
- for (i = 0; i < num; i++) {
- struct dwc3_event_buffer *evt;
-
- evt = dwc3_alloc_one_event_buffer(dwc, length);
- if (IS_ERR(evt)) {
- dev_err(dwc->dev, "can't allocate event buffer\n");
- return PTR_ERR(evt);
- }
- dwc->ev_buffs[i] = evt;
- }
-
- return 0;
-}
-
-/**
- * dwc3_event_buffers_setup - setup our allocated event buffers
- * @dwc: Pointer to out controller context structure
- *
- * Returns 0 on success otherwise negative errno.
- */
-static int __devinit dwc3_event_buffers_setup(struct dwc3 *dwc)
-{
- struct dwc3_event_buffer *evt;
- int n;
-
- for (n = 0; n < DWC3_EVENT_BUFFERS_NUM; n++) {
- evt = dwc->ev_buffs[n];
- dev_dbg(dwc->dev, "Event buf %p dma %08llx length %d\n",
- evt->buf, (unsigned long long) evt->dma,
- evt->length);
-
- dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n),
- lower_32_bits(evt->dma));
- dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n),
- upper_32_bits(evt->dma));
- dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n),
- evt->length & 0xffff);
- dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0);
- }
-
- return 0;
-}
-
-static void dwc3_event_buffers_cleanup(struct dwc3 *dwc)
-{
- struct dwc3_event_buffer *evt;
- int n;
-
- for (n = 0; n < DWC3_EVENT_BUFFERS_NUM; n++) {
- evt = dwc->ev_buffs[n];
- dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(n), 0);
- dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(n), 0);
- dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(n), 0);
- dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(n), 0);
- }
-}
-
-static void __devinit dwc3_cache_hwparams(struct dwc3 *dwc)
-{
- struct dwc3_hwparams *parms = &dwc->hwparams;
-
- parms->hwparams0 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS0);
- parms->hwparams1 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS1);
- parms->hwparams2 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS2);
- parms->hwparams3 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS3);
- parms->hwparams4 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS4);
- parms->hwparams5 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS5);
- parms->hwparams6 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
- parms->hwparams7 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS7);
- parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
-}
-
-/**
- * dwc3_core_init - Low-level initialization of DWC3 Core
- * @dwc: Pointer to our controller context structure
- *
- * Returns 0 on success otherwise negative errno.
- */
-static int __devinit dwc3_core_init(struct dwc3 *dwc)
-{
- unsigned long timeout;
- u32 reg;
- int ret;
-
- reg = dwc3_readl(dwc->regs, DWC3_GSNPSID);
- /* This should read as U3 followed by revision number */
- if ((reg & DWC3_GSNPSID_MASK) != 0x55330000) {
- dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n");
- ret = -ENODEV;
- goto err0;
- }
- dwc->revision = reg & DWC3_GSNPSREV_MASK;
-
- dwc3_core_soft_reset(dwc);
-
- /* issue device SoftReset too */
- timeout = jiffies + msecs_to_jiffies(500);
- dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_CSFTRST);
- do {
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
- if (!(reg & DWC3_DCTL_CSFTRST))
- break;
-
- if (time_after(jiffies, timeout)) {
- dev_err(dwc->dev, "Reset Timed Out\n");
- ret = -ETIMEDOUT;
- goto err0;
- }
-
- cpu_relax();
- } while (true);
-
- ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_NUM,
- DWC3_EVENT_BUFFERS_SIZE);
- if (ret) {
- dev_err(dwc->dev, "failed to allocate event buffers\n");
- ret = -ENOMEM;
- goto err1;
- }
-
- ret = dwc3_event_buffers_setup(dwc);
- if (ret) {
- dev_err(dwc->dev, "failed to setup event buffers\n");
- goto err1;
- }
-
- dwc3_cache_hwparams(dwc);
-
- return 0;
-
-err1:
- dwc3_free_event_buffers(dwc);
-
-err0:
- return ret;
-}
-
-static void dwc3_core_exit(struct dwc3 *dwc)
-{
- dwc3_event_buffers_cleanup(dwc);
- dwc3_free_event_buffers(dwc);
-}
-
-#define DWC3_ALIGN_MASK (16 - 1)
-
-static int __devinit dwc3_probe(struct platform_device *pdev)
-{
- const struct platform_device_id *id = platform_get_device_id(pdev);
- struct resource *res;
- struct dwc3 *dwc;
- void __iomem *regs;
- unsigned int features = id->driver_data;
- int ret = -ENOMEM;
- int irq;
- void *mem;
-
- mem = kzalloc(sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
- if (!mem) {
- dev_err(&pdev->dev, "not enough memory\n");
- goto err0;
- }
- dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
- dwc->mem = mem;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "missing resource\n");
- goto err1;
- }
-
- res = request_mem_region(res->start, resource_size(res),
- dev_name(&pdev->dev));
- if (!res) {
- dev_err(&pdev->dev, "can't request mem region\n");
- goto err1;
- }
-
- regs = ioremap(res->start, resource_size(res));
- if (!regs) {
- dev_err(&pdev->dev, "ioremap failed\n");
- goto err2;
- }
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "missing IRQ\n");
- goto err3;
- }
-
- spin_lock_init(&dwc->lock);
- platform_set_drvdata(pdev, dwc);
-
- dwc->regs = regs;
- dwc->regs_size = resource_size(res);
- dwc->dev = &pdev->dev;
- dwc->irq = irq;
-
- pm_runtime_enable(&pdev->dev);
- pm_runtime_get_sync(&pdev->dev);
- pm_runtime_forbid(&pdev->dev);
-
- ret = dwc3_core_init(dwc);
- if (ret) {
- dev_err(&pdev->dev, "failed to initialize core\n");
- goto err3;
- }
-
- if (features & DWC3_HAS_PERIPHERAL) {
- ret = dwc3_gadget_init(dwc);
- if (ret) {
- dev_err(&pdev->dev, "failed to initialized gadget\n");
- goto err4;
- }
- }
-
- ret = dwc3_debugfs_init(dwc);
- if (ret) {
- dev_err(&pdev->dev, "failed to initialize debugfs\n");
- goto err5;
- }
-
- pm_runtime_allow(&pdev->dev);
-
- return 0;
-
-err5:
- if (features & DWC3_HAS_PERIPHERAL)
- dwc3_gadget_exit(dwc);
-
-err4:
- dwc3_core_exit(dwc);
-
-err3:
- iounmap(regs);
-
-err2:
- release_mem_region(res->start, resource_size(res));
-
-err1:
- kfree(dwc->mem);
-
-err0:
- return ret;
-}
-
-static int __devexit dwc3_remove(struct platform_device *pdev)
-{
- const struct platform_device_id *id = platform_get_device_id(pdev);
- struct dwc3 *dwc = platform_get_drvdata(pdev);
- struct resource *res;
- unsigned int features = id->driver_data;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
- pm_runtime_put(&pdev->dev);
- pm_runtime_disable(&pdev->dev);
-
- dwc3_debugfs_exit(dwc);
-
- if (features & DWC3_HAS_PERIPHERAL)
- dwc3_gadget_exit(dwc);
-
- dwc3_core_exit(dwc);
- release_mem_region(res->start, resource_size(res));
- iounmap(dwc->regs);
- kfree(dwc->mem);
-
- return 0;
-}
-
-static const struct platform_device_id dwc3_id_table[] __devinitconst = {
- {
- .name = "dwc3-omap",
- .driver_data = (DWC3_HAS_PERIPHERAL
- | DWC3_HAS_XHCI
- | DWC3_HAS_OTG),
- },
- {
- .name = "dwc3-pci",
- .driver_data = DWC3_HAS_PERIPHERAL,
- },
- { }, /* Terminating Entry */
-};
-MODULE_DEVICE_TABLE(platform, dwc3_id_table);
-
-static struct platform_driver dwc3_driver = {
- .probe = dwc3_probe,
- .remove = __devexit_p(dwc3_remove),
- .driver = {
- .name = "dwc3",
- },
- .id_table = dwc3_id_table,
-};
-
-MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
-
-static int __devinit dwc3_init(void)
-{
- return platform_driver_register(&dwc3_driver);
-}
-module_init(dwc3_init);
-
-static void __exit dwc3_exit(void)
-{
- platform_driver_unregister(&dwc3_driver);
-}
-module_exit(dwc3_exit);
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
deleted file mode 100644
index 29a8e16..0000000
--- a/drivers/usb/dwc3/core.h
+++ /dev/null
@@ -1,768 +0,0 @@
-/**
- * core.h - DesignWare USB3 DRD Core Header
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * 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") version 2, as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#ifndef __DRIVERS_USB_DWC3_CORE_H
-#define __DRIVERS_USB_DWC3_CORE_H
-
-#include <linux/device.h>
-#include <linux/spinlock.h>
-#include <linux/list.h>
-#include <linux/dma-mapping.h>
-#include <linux/mm.h>
-#include <linux/debugfs.h>
-
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-
-/* Global constants */
-#define DWC3_ENDPOINTS_NUM 32
-
-#define DWC3_EVENT_BUFFERS_NUM 2
-#define DWC3_EVENT_BUFFERS_SIZE PAGE_SIZE
-#define DWC3_EVENT_TYPE_MASK 0xfe
-
-#define DWC3_EVENT_TYPE_DEV 0
-#define DWC3_EVENT_TYPE_CARKIT 3
-#define DWC3_EVENT_TYPE_I2C 4
-
-#define DWC3_DEVICE_EVENT_DISCONNECT 0
-#define DWC3_DEVICE_EVENT_RESET 1
-#define DWC3_DEVICE_EVENT_CONNECT_DONE 2
-#define DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE 3
-#define DWC3_DEVICE_EVENT_WAKEUP 4
-#define DWC3_DEVICE_EVENT_EOPF 6
-#define DWC3_DEVICE_EVENT_SOF 7
-#define DWC3_DEVICE_EVENT_ERRATIC_ERROR 9
-#define DWC3_DEVICE_EVENT_CMD_CMPL 10
-#define DWC3_DEVICE_EVENT_OVERFLOW 11
-
-#define DWC3_GEVNTCOUNT_MASK 0xfffc
-#define DWC3_GSNPSID_MASK 0xffff0000
-#define DWC3_GSNPSREV_MASK 0xffff
-
-/* Global Registers */
-#define DWC3_GSBUSCFG0 0xc100
-#define DWC3_GSBUSCFG1 0xc104
-#define DWC3_GTXTHRCFG 0xc108
-#define DWC3_GRXTHRCFG 0xc10c
-#define DWC3_GCTL 0xc110
-#define DWC3_GEVTEN 0xc114
-#define DWC3_GSTS 0xc118
-#define DWC3_GSNPSID 0xc120
-#define DWC3_GGPIO 0xc124
-#define DWC3_GUID 0xc128
-#define DWC3_GUCTL 0xc12c
-#define DWC3_GBUSERRADDR0 0xc130
-#define DWC3_GBUSERRADDR1 0xc134
-#define DWC3_GPRTBIMAP0 0xc138
-#define DWC3_GPRTBIMAP1 0xc13c
-#define DWC3_GHWPARAMS0 0xc140
-#define DWC3_GHWPARAMS1 0xc144
-#define DWC3_GHWPARAMS2 0xc148
-#define DWC3_GHWPARAMS3 0xc14c
-#define DWC3_GHWPARAMS4 0xc150
-#define DWC3_GHWPARAMS5 0xc154
-#define DWC3_GHWPARAMS6 0xc158
-#define DWC3_GHWPARAMS7 0xc15c
-#define DWC3_GDBGFIFOSPACE 0xc160
-#define DWC3_GDBGLTSSM 0xc164
-#define DWC3_GPRTBIMAP_HS0 0xc180
-#define DWC3_GPRTBIMAP_HS1 0xc184
-#define DWC3_GPRTBIMAP_FS0 0xc188
-#define DWC3_GPRTBIMAP_FS1 0xc18c
-
-#define DWC3_GUSB2PHYCFG(n) (0xc200 + (n * 0x04))
-#define DWC3_GUSB2I2CCTL(n) (0xc240 + (n * 0x04))
-
-#define DWC3_GUSB2PHYACC(n) (0xc280 + (n * 0x04))
-
-#define DWC3_GUSB3PIPECTL(n) (0xc2c0 + (n * 0x04))
-
-#define DWC3_GTXFIFOSIZ(n) (0xc300 + (n * 0x04))
-#define DWC3_GRXFIFOSIZ(n) (0xc380 + (n * 0x04))
-
-#define DWC3_GEVNTADRLO(n) (0xc400 + (n * 0x10))
-#define DWC3_GEVNTADRHI(n) (0xc404 + (n * 0x10))
-#define DWC3_GEVNTSIZ(n) (0xc408 + (n * 0x10))
-#define DWC3_GEVNTCOUNT(n) (0xc40c + (n * 0x10))
-
-#define DWC3_GHWPARAMS8 0xc600
-
-/* Device Registers */
-#define DWC3_DCFG 0xc700
-#define DWC3_DCTL 0xc704
-#define DWC3_DEVTEN 0xc708
-#define DWC3_DSTS 0xc70c
-#define DWC3_DGCMDPAR 0xc710
-#define DWC3_DGCMD 0xc714
-#define DWC3_DALEPENA 0xc720
-#define DWC3_DEPCMDPAR2(n) (0xc800 + (n * 0x10))
-#define DWC3_DEPCMDPAR1(n) (0xc804 + (n * 0x10))
-#define DWC3_DEPCMDPAR0(n) (0xc808 + (n * 0x10))
-#define DWC3_DEPCMD(n) (0xc80c + (n * 0x10))
-
-/* OTG Registers */
-#define DWC3_OCFG 0xcc00
-#define DWC3_OCTL 0xcc04
-#define DWC3_OEVTEN 0xcc08
-#define DWC3_OSTS 0xcc0C
-
-/* Bit fields */
-
-/* Global Configuration Register */
-#define DWC3_GCTL_PWRDNSCALE(n) (n << 19)
-#define DWC3_GCTL_U2RSTECN (1 << 16)
-#define DWC3_GCTL_RAMCLKSEL(x) ((x & DWC3_GCTL_CLK_MASK) << 6)
-#define DWC3_GCTL_CLK_BUS (0)
-#define DWC3_GCTL_CLK_PIPE (1)
-#define DWC3_GCTL_CLK_PIPEHALF (2)
-#define DWC3_GCTL_CLK_MASK (3)
-
-#define DWC3_GCTL_PRTCAPDIR(n) (n << 12)
-#define DWC3_GCTL_PRTCAP_HOST 1
-#define DWC3_GCTL_PRTCAP_DEVICE 2
-#define DWC3_GCTL_PRTCAP_OTG 3
-
-#define DWC3_GCTL_CORESOFTRESET (1 << 11)
-#define DWC3_GCTL_SCALEDOWN(n) (n << 4)
-#define DWC3_GCTL_DISSCRAMBLE (1 << 3)
-#define DWC3_GCTL_DSBLCLKGTNG (1 << 0)
-
-/* Global USB2 PHY Configuration Register */
-#define DWC3_GUSB2PHYCFG_PHYSOFTRST (1 << 31)
-#define DWC3_GUSB2PHYCFG_SUSPHY (1 << 6)
-
-/* Global USB3 PIPE Control Register */
-#define DWC3_GUSB3PIPECTL_PHYSOFTRST (1 << 31)
-#define DWC3_GUSB3PIPECTL_SUSPHY (1 << 17)
-
-/* Global HWPARAMS1 Register */
-#define DWC3_GHWPARAMS1_EN_PWROPT(n) ((n & (3 << 24)) >> 24)
-#define DWC3_GHWPARAMS1_EN_PWROPT_NO 0
-#define DWC3_GHWPARAMS1_EN_PWROPT_CLK 1
-
-/* Device Configuration Register */
-#define DWC3_DCFG_DEVADDR(addr) ((addr) << 3)
-#define DWC3_DCFG_DEVADDR_MASK DWC3_DCFG_DEVADDR(0x7f)
-
-#define DWC3_DCFG_SPEED_MASK (7 << 0)
-#define DWC3_DCFG_SUPERSPEED (4 << 0)
-#define DWC3_DCFG_HIGHSPEED (0 << 0)
-#define DWC3_DCFG_FULLSPEED2 (1 << 0)
-#define DWC3_DCFG_LOWSPEED (2 << 0)
-#define DWC3_DCFG_FULLSPEED1 (3 << 0)
-
-/* Device Control Register */
-#define DWC3_DCTL_RUN_STOP (1 << 31)
-#define DWC3_DCTL_CSFTRST (1 << 30)
-#define DWC3_DCTL_LSFTRST (1 << 29)
-
-#define DWC3_DCTL_HIRD_THRES_MASK (0x1f << 24)
-#define DWC3_DCTL_HIRD_THRES(n) (((n) & DWC3_DCTL_HIRD_THRES_MASK) >> 24)
-
-#define DWC3_DCTL_APPL1RES (1 << 23)
-
-#define DWC3_DCTL_INITU2ENA (1 << 12)
-#define DWC3_DCTL_ACCEPTU2ENA (1 << 11)
-#define DWC3_DCTL_INITU1ENA (1 << 10)
-#define DWC3_DCTL_ACCEPTU1ENA (1 << 9)
-#define DWC3_DCTL_TSTCTRL_MASK (0xf << 1)
-
-#define DWC3_DCTL_ULSTCHNGREQ_MASK (0x0f << 5)
-#define DWC3_DCTL_ULSTCHNGREQ(n) (((n) << 5) & DWC3_DCTL_ULSTCHNGREQ_MASK)
-
-#define DWC3_DCTL_ULSTCHNG_NO_ACTION (DWC3_DCTL_ULSTCHNGREQ(0))
-#define DWC3_DCTL_ULSTCHNG_SS_DISABLED (DWC3_DCTL_ULSTCHNGREQ(4))
-#define DWC3_DCTL_ULSTCHNG_RX_DETECT (DWC3_DCTL_ULSTCHNGREQ(5))
-#define DWC3_DCTL_ULSTCHNG_SS_INACTIVE (DWC3_DCTL_ULSTCHNGREQ(6))
-#define DWC3_DCTL_ULSTCHNG_RECOVERY (DWC3_DCTL_ULSTCHNGREQ(8))
-#define DWC3_DCTL_ULSTCHNG_COMPLIANCE (DWC3_DCTL_ULSTCHNGREQ(10))
-#define DWC3_DCTL_ULSTCHNG_LOOPBACK (DWC3_DCTL_ULSTCHNGREQ(11))
-
-/* Device Event Enable Register */
-#define DWC3_DEVTEN_VNDRDEVTSTRCVEDEN (1 << 12)
-#define DWC3_DEVTEN_EVNTOVERFLOWEN (1 << 11)
-#define DWC3_DEVTEN_CMDCMPLTEN (1 << 10)
-#define DWC3_DEVTEN_ERRTICERREN (1 << 9)
-#define DWC3_DEVTEN_SOFEN (1 << 7)
-#define DWC3_DEVTEN_EOPFEN (1 << 6)
-#define DWC3_DEVTEN_WKUPEVTEN (1 << 4)
-#define DWC3_DEVTEN_ULSTCNGEN (1 << 3)
-#define DWC3_DEVTEN_CONNECTDONEEN (1 << 2)
-#define DWC3_DEVTEN_USBRSTEN (1 << 1)
-#define DWC3_DEVTEN_DISCONNEVTEN (1 << 0)
-
-/* Device Status Register */
-#define DWC3_DSTS_PWRUPREQ (1 << 24)
-#define DWC3_DSTS_COREIDLE (1 << 23)
-#define DWC3_DSTS_DEVCTRLHLT (1 << 22)
-
-#define DWC3_DSTS_USBLNKST_MASK (0x0f << 18)
-#define DWC3_DSTS_USBLNKST(n) (((n) & DWC3_DSTS_USBLNKST_MASK) >> 18)
-
-#define DWC3_DSTS_RXFIFOEMPTY (1 << 17)
-
-#define DWC3_DSTS_SOFFN_MASK (0x3ff << 3)
-#define DWC3_DSTS_SOFFN(n) (((n) & DWC3_DSTS_SOFFN_MASK) >> 3)
-
-#define DWC3_DSTS_CONNECTSPD (7 << 0)
-
-#define DWC3_DSTS_SUPERSPEED (4 << 0)
-#define DWC3_DSTS_HIGHSPEED (0 << 0)
-#define DWC3_DSTS_FULLSPEED2 (1 << 0)
-#define DWC3_DSTS_LOWSPEED (2 << 0)
-#define DWC3_DSTS_FULLSPEED1 (3 << 0)
-
-/* Device Generic Command Register */
-#define DWC3_DGCMD_SET_LMP 0x01
-#define DWC3_DGCMD_SET_PERIODIC_PAR 0x02
-#define DWC3_DGCMD_XMIT_FUNCTION 0x03
-#define DWC3_DGCMD_SELECTED_FIFO_FLUSH 0x09
-#define DWC3_DGCMD_ALL_FIFO_FLUSH 0x0a
-#define DWC3_DGCMD_SET_ENDPOINT_NRDY 0x0c
-#define DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK 0x10
-
-/* Device Endpoint Command Register */
-#define DWC3_DEPCMD_PARAM_SHIFT 16
-#define DWC3_DEPCMD_PARAM(x) (x << DWC3_DEPCMD_PARAM_SHIFT)
-#define DWC3_DEPCMD_GET_RSC_IDX(x) ((x >> DWC3_DEPCMD_PARAM_SHIFT) & 0x7f)
-#define DWC3_DEPCMD_STATUS_MASK (0x0f << 12)
-#define DWC3_DEPCMD_STATUS(x) ((x & DWC3_DEPCMD_STATUS_MASK) >> 12)
-#define DWC3_DEPCMD_HIPRI_FORCERM (1 << 11)
-#define DWC3_DEPCMD_CMDACT (1 << 10)
-#define DWC3_DEPCMD_CMDIOC (1 << 8)
-
-#define DWC3_DEPCMD_DEPSTARTCFG (0x09 << 0)
-#define DWC3_DEPCMD_ENDTRANSFER (0x08 << 0)
-#define DWC3_DEPCMD_UPDATETRANSFER (0x07 << 0)
-#define DWC3_DEPCMD_STARTTRANSFER (0x06 << 0)
-#define DWC3_DEPCMD_CLEARSTALL (0x05 << 0)
-#define DWC3_DEPCMD_SETSTALL (0x04 << 0)
-#define DWC3_DEPCMD_GETSEQNUMBER (0x03 << 0)
-#define DWC3_DEPCMD_SETTRANSFRESOURCE (0x02 << 0)
-#define DWC3_DEPCMD_SETEPCONFIG (0x01 << 0)
-
-/* The EP number goes 0..31 so ep0 is always out and ep1 is always in */
-#define DWC3_DALEPENA_EP(n) (1 << n)
-
-#define DWC3_DEPCMD_TYPE_CONTROL 0
-#define DWC3_DEPCMD_TYPE_ISOC 1
-#define DWC3_DEPCMD_TYPE_BULK 2
-#define DWC3_DEPCMD_TYPE_INTR 3
-
-/* Structures */
-
-struct dwc3_trb_hw;
-
-/**
- * struct dwc3_event_buffer - Software event buffer representation
- * @list: a list of event buffers
- * @buf: _THE_ buffer
- * @length: size of this buffer
- * @dma: dma_addr_t
- * @dwc: pointer to DWC controller
- */
-struct dwc3_event_buffer {
- void *buf;
- unsigned length;
- unsigned int lpos;
-
- dma_addr_t dma;
-
- struct dwc3 *dwc;
-};
-
-#define DWC3_EP_FLAG_STALLED (1 << 0)
-#define DWC3_EP_FLAG_WEDGED (1 << 1)
-
-#define DWC3_EP_DIRECTION_TX true
-#define DWC3_EP_DIRECTION_RX false
-
-#define DWC3_TRB_NUM 32
-#define DWC3_TRB_MASK (DWC3_TRB_NUM - 1)
-
-/**
- * struct dwc3_ep - device side endpoint representation
- * @endpoint: usb endpoint
- * @request_list: list of requests for this endpoint
- * @req_queued: list of requests on this ep which have TRBs setup
- * @trb_pool: array of transaction buffers
- * @trb_pool_dma: dma address of @trb_pool
- * @free_slot: next slot which is going to be used
- * @busy_slot: first slot which is owned by HW
- * @desc: usb_endpoint_descriptor pointer
- * @dwc: pointer to DWC controller
- * @flags: endpoint flags (wedged, stalled, ...)
- * @current_trb: index of current used trb
- * @number: endpoint number (1 - 15)
- * @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK
- * @res_trans_idx: Resource transfer index
- * @interval: the intervall on which the ISOC transfer is started
- * @name: a human readable name e.g. ep1out-bulk
- * @direction: true for TX, false for RX
- * @stream_capable: true when streams are enabled
- */
-struct dwc3_ep {
- struct usb_ep endpoint;
- struct list_head request_list;
- struct list_head req_queued;
-
- struct dwc3_trb_hw *trb_pool;
- dma_addr_t trb_pool_dma;
- u32 free_slot;
- u32 busy_slot;
- const struct usb_endpoint_descriptor *desc;
- struct dwc3 *dwc;
-
- unsigned flags;
-#define DWC3_EP_ENABLED (1 << 0)
-#define DWC3_EP_STALL (1 << 1)
-#define DWC3_EP_WEDGE (1 << 2)
-#define DWC3_EP_BUSY (1 << 4)
-#define DWC3_EP_PENDING_REQUEST (1 << 5)
-
- /* This last one is specific to EP0 */
-#define DWC3_EP0_DIR_IN (1 << 31)
-
- unsigned current_trb;
-
- u8 number;
- u8 type;
- u8 res_trans_idx;
- u32 interval;
-
- char name[20];
-
- unsigned direction:1;
- unsigned stream_capable:1;
-};
-
-enum dwc3_phy {
- DWC3_PHY_UNKNOWN = 0,
- DWC3_PHY_USB3,
- DWC3_PHY_USB2,
-};
-
-enum dwc3_ep0_next {
- DWC3_EP0_UNKNOWN = 0,
- DWC3_EP0_COMPLETE,
- DWC3_EP0_NRDY_SETUP,
- DWC3_EP0_NRDY_DATA,
- DWC3_EP0_NRDY_STATUS,
-};
-
-enum dwc3_ep0_state {
- EP0_UNCONNECTED = 0,
- EP0_SETUP_PHASE,
- EP0_DATA_PHASE,
- EP0_STATUS_PHASE,
-};
-
-enum dwc3_link_state {
- /* In SuperSpeed */
- DWC3_LINK_STATE_U0 = 0x00, /* in HS, means ON */
- DWC3_LINK_STATE_U1 = 0x01,
- DWC3_LINK_STATE_U2 = 0x02, /* in HS, means SLEEP */
- DWC3_LINK_STATE_U3 = 0x03, /* in HS, means SUSPEND */
- DWC3_LINK_STATE_SS_DIS = 0x04,
- DWC3_LINK_STATE_RX_DET = 0x05, /* in HS, means Early Suspend */
- DWC3_LINK_STATE_SS_INACT = 0x06,
- DWC3_LINK_STATE_POLL = 0x07,
- DWC3_LINK_STATE_RECOV = 0x08,
- DWC3_LINK_STATE_HRESET = 0x09,
- DWC3_LINK_STATE_CMPLY = 0x0a,
- DWC3_LINK_STATE_LPBK = 0x0b,
- DWC3_LINK_STATE_MASK = 0x0f,
-};
-
-enum dwc3_device_state {
- DWC3_DEFAULT_STATE,
- DWC3_ADDRESS_STATE,
- DWC3_CONFIGURED_STATE,
-};
-
-/**
- * struct dwc3_trb - transfer request block
- * @bpl: lower 32bit of the buffer
- * @bph: higher 32bit of the buffer
- * @length: buffer size (up to 16mb - 1)
- * @pcm1: packet count m1
- * @trbsts: trb status
- * 0 = ok
- * 1 = missed isoc
- * 2 = setup pending
- * @hwo: hardware owner of descriptor
- * @lst: last trb
- * @chn: chain buffers
- * @csp: continue on short packets (only supported on isoc eps)
- * @trbctl: trb control
- * 1 = normal
- * 2 = control-setup
- * 3 = control-status-2
- * 4 = control-status-3
- * 5 = control-data (first trb of data stage)
- * 6 = isochronous-first (first trb of service interval)
- * 7 = isochronous
- * 8 = link trb
- * others = reserved
- * @isp_imi: interrupt on short packet / interrupt on missed isoc
- * @ioc: interrupt on complete
- * @sid_sofn: Stream ID / SOF Number
- */
-struct dwc3_trb {
- u64 bplh;
-
- union {
- struct {
- u32 length:24;
- u32 pcm1:2;
- u32 reserved27_26:2;
- u32 trbsts:4;
-#define DWC3_TRB_STS_OKAY 0
-#define DWC3_TRB_STS_MISSED_ISOC 1
-#define DWC3_TRB_STS_SETUP_PENDING 2
- };
- u32 len_pcm;
- };
-
- union {
- struct {
- u32 hwo:1;
- u32 lst:1;
- u32 chn:1;
- u32 csp:1;
- u32 trbctl:6;
- u32 isp_imi:1;
- u32 ioc:1;
- u32 reserved13_12:2;
- u32 sid_sofn:16;
- u32 reserved31_30:2;
- };
- u32 control;
- };
-} __packed;
-
-/**
- * struct dwc3_trb_hw - transfer request block (hw format)
- * @bpl: DW0-3
- * @bph: DW4-7
- * @size: DW8-B
- * @trl: DWC-F
- */
-struct dwc3_trb_hw {
- __le32 bpl;
- __le32 bph;
- __le32 size;
- __le32 ctrl;
-} __packed;
-
-static inline void dwc3_trb_to_hw(struct dwc3_trb *nat, struct dwc3_trb_hw *hw)
-{
- hw->bpl = cpu_to_le32(lower_32_bits(nat->bplh));
- hw->bph = cpu_to_le32(upper_32_bits(nat->bplh));
- hw->size = cpu_to_le32p(&nat->len_pcm);
- /* HWO is written last */
- hw->ctrl = cpu_to_le32p(&nat->control);
-}
-
-static inline void dwc3_trb_to_nat(struct dwc3_trb_hw *hw, struct dwc3_trb *nat)
-{
- u64 bplh;
-
- bplh = le32_to_cpup(&hw->bpl);
- bplh |= (u64) le32_to_cpup(&hw->bph) << 32;
- nat->bplh = bplh;
-
- nat->len_pcm = le32_to_cpup(&hw->size);
- nat->control = le32_to_cpup(&hw->ctrl);
-}
-
-/**
- * dwc3_hwparams - copy of HWPARAMS registers
- * @hwparams0 - GHWPARAMS0
- * @hwparams1 - GHWPARAMS1
- * @hwparams2 - GHWPARAMS2
- * @hwparams3 - GHWPARAMS3
- * @hwparams4 - GHWPARAMS4
- * @hwparams5 - GHWPARAMS5
- * @hwparams6 - GHWPARAMS6
- * @hwparams7 - GHWPARAMS7
- * @hwparams8 - GHWPARAMS8
- */
-struct dwc3_hwparams {
- u32 hwparams0;
- u32 hwparams1;
- u32 hwparams2;
- u32 hwparams3;
- u32 hwparams4;
- u32 hwparams5;
- u32 hwparams6;
- u32 hwparams7;
- u32 hwparams8;
-};
-
-/**
- * struct dwc3 - representation of our controller
- * @ctrl_req: usb control request which is used for ep0
- * @ep0_trb: trb which is used for the ctrl_req
- * @ep0_bounce: bounce buffer for ep0
- * @setup_buf: used while precessing STD USB requests
- * @ctrl_req_addr: dma address of ctrl_req
- * @ep0_trb: dma address of ep0_trb
- * @ep0_usb_req: dummy req used while handling STD USB requests
- * @setup_buf_addr: dma address of setup_buf
- * @ep0_bounce_addr: dma address of ep0_bounce
- * @lock: for synchronizing
- * @dev: pointer to our struct device
- * @event_buffer_list: a list of event buffers
- * @gadget: device side representation of the peripheral controller
- * @gadget_driver: pointer to the gadget driver
- * @regs: base address for our registers
- * @regs_size: address space size
- * @irq: IRQ number
- * @revision: revision register contents
- * @is_selfpowered: true when we are selfpowered
- * @three_stage_setup: set if we perform a three phase setup
- * @ep0_status_pending: ep0 status response without a req is pending
- * @ep0_bounced: true when we used bounce buffer
- * @ep0_expect_in: true when we expect a DATA IN transfer
- * @start_config_issued: true when StartConfig command has been issued
- * @ep0_next_event: hold the next expected event
- * @ep0state: state of endpoint zero
- * @link_state: link state
- * @speed: device speed (super, high, full, low)
- * @mem: points to start of memory which is used for this struct.
- * @hwparams: copy of hwparams registers
- * @root: debugfs root folder pointer
- */
-struct dwc3 {
- struct usb_ctrlrequest *ctrl_req;
- struct dwc3_trb_hw *ep0_trb;
- void *ep0_bounce;
- u8 *setup_buf;
- dma_addr_t ctrl_req_addr;
- dma_addr_t ep0_trb_addr;
- dma_addr_t setup_buf_addr;
- dma_addr_t ep0_bounce_addr;
- struct usb_request ep0_usb_req;
- /* device lock */
- spinlock_t lock;
- struct device *dev;
-
- struct dwc3_event_buffer *ev_buffs[DWC3_EVENT_BUFFERS_NUM];
- struct dwc3_ep *eps[DWC3_ENDPOINTS_NUM];
-
- struct usb_gadget gadget;
- struct usb_gadget_driver *gadget_driver;
-
- void __iomem *regs;
- size_t regs_size;
-
- int irq;
-
- u32 revision;
-
-#define DWC3_REVISION_173A 0x5533173a
-#define DWC3_REVISION_175A 0x5533175a
-#define DWC3_REVISION_180A 0x5533180a
-#define DWC3_REVISION_183A 0x5533183a
-#define DWC3_REVISION_185A 0x5533185a
-#define DWC3_REVISION_188A 0x5533188a
-#define DWC3_REVISION_190A 0x5533190a
-
- unsigned is_selfpowered:1;
- unsigned three_stage_setup:1;
- unsigned ep0_status_pending:1;
- unsigned ep0_bounced:1;
- unsigned ep0_expect_in:1;
- unsigned start_config_issued:1;
-
- enum dwc3_ep0_next ep0_next_event;
- enum dwc3_ep0_state ep0state;
- enum dwc3_link_state link_state;
- enum dwc3_device_state dev_state;
-
- u8 speed;
- void *mem;
-
- struct dwc3_hwparams hwparams;
- struct dentry *root;
-};
-
-/* -------------------------------------------------------------------------- */
-
-#define DWC3_TRBSTS_OK 0
-#define DWC3_TRBSTS_MISSED_ISOC 1
-#define DWC3_TRBSTS_SETUP_PENDING 2
-
-#define DWC3_TRBCTL_NORMAL 1
-#define DWC3_TRBCTL_CONTROL_SETUP 2
-#define DWC3_TRBCTL_CONTROL_STATUS2 3
-#define DWC3_TRBCTL_CONTROL_STATUS3 4
-#define DWC3_TRBCTL_CONTROL_DATA 5
-#define DWC3_TRBCTL_ISOCHRONOUS_FIRST 6
-#define DWC3_TRBCTL_ISOCHRONOUS 7
-#define DWC3_TRBCTL_LINK_TRB 8
-
-/* -------------------------------------------------------------------------- */
-
-struct dwc3_event_type {
- u32 is_devspec:1;
- u32 type:6;
- u32 reserved8_31:25;
-} __packed;
-
-#define DWC3_DEPEVT_XFERCOMPLETE 0x01
-#define DWC3_DEPEVT_XFERINPROGRESS 0x02
-#define DWC3_DEPEVT_XFERNOTREADY 0x03
-#define DWC3_DEPEVT_RXTXFIFOEVT 0x04
-#define DWC3_DEPEVT_STREAMEVT 0x06
-#define DWC3_DEPEVT_EPCMDCMPLT 0x07
-
-/**
- * struct dwc3_event_depvt - Device Endpoint Events
- * @one_bit: indicates this is an endpoint event (not used)
- * @endpoint_number: number of the endpoint
- * @endpoint_event: The event we have:
- * 0x00 - Reserved
- * 0x01 - XferComplete
- * 0x02 - XferInProgress
- * 0x03 - XferNotReady
- * 0x04 - RxTxFifoEvt (IN->Underrun, OUT->Overrun)
- * 0x05 - Reserved
- * 0x06 - StreamEvt
- * 0x07 - EPCmdCmplt
- * @reserved11_10: Reserved, don't use.
- * @status: Indicates the status of the event. Refer to databook for
- * more information.
- * @parameters: Parameters of the current event. Refer to databook for
- * more information.
- */
-struct dwc3_event_depevt {
- u32 one_bit:1;
- u32 endpoint_number:5;
- u32 endpoint_event:4;
- u32 reserved11_10:2;
- u32 status:4;
-#define DEPEVT_STATUS_BUSERR (1 << 0)
-#define DEPEVT_STATUS_SHORT (1 << 1)
-#define DEPEVT_STATUS_IOC (1 << 2)
-#define DEPEVT_STATUS_LST (1 << 3)
-
-/* Stream event only */
-#define DEPEVT_STREAMEVT_FOUND 1
-#define DEPEVT_STREAMEVT_NOTFOUND 2
-
-/* Control-only Status */
-#define DEPEVT_STATUS_CONTROL_SETUP 0
-#define DEPEVT_STATUS_CONTROL_DATA 1
-#define DEPEVT_STATUS_CONTROL_STATUS 2
-
- u32 parameters:16;
-} __packed;
-
-/**
- * struct dwc3_event_devt - Device Events
- * @one_bit: indicates this is a non-endpoint event (not used)
- * @device_event: indicates it's a device event. Should read as 0x00
- * @type: indicates the type of device event.
- * 0 - DisconnEvt
- * 1 - USBRst
- * 2 - ConnectDone
- * 3 - ULStChng
- * 4 - WkUpEvt
- * 5 - Reserved
- * 6 - EOPF
- * 7 - SOF
- * 8 - Reserved
- * 9 - ErrticErr
- * 10 - CmdCmplt
- * 11 - EvntOverflow
- * 12 - VndrDevTstRcved
- * @reserved15_12: Reserved, not used
- * @event_info: Information about this event
- * @reserved31_24: Reserved, not used
- */
-struct dwc3_event_devt {
- u32 one_bit:1;
- u32 device_event:7;
- u32 type:4;
- u32 reserved15_12:4;
- u32 event_info:8;
- u32 reserved31_24:8;
-} __packed;
-
-/**
- * struct dwc3_event_gevt - Other Core Events
- * @one_bit: indicates this is a non-endpoint event (not used)
- * @device_event: indicates it's (0x03) Carkit or (0x04) I2C event.
- * @phy_port_number: self-explanatory
- * @reserved31_12: Reserved, not used.
- */
-struct dwc3_event_gevt {
- u32 one_bit:1;
- u32 device_event:7;
- u32 phy_port_number:4;
- u32 reserved31_12:20;
-} __packed;
-
-/**
- * union dwc3_event - representation of Event Buffer contents
- * @raw: raw 32-bit event
- * @type: the type of the event
- * @depevt: Device Endpoint Event
- * @devt: Device Event
- * @gevt: Global Event
- */
-union dwc3_event {
- u32 raw;
- struct dwc3_event_type type;
- struct dwc3_event_depevt depevt;
- struct dwc3_event_devt devt;
- struct dwc3_event_gevt gevt;
-};
-
-/*
- * DWC3 Features to be used as Driver Data
- */
-
-#define DWC3_HAS_PERIPHERAL BIT(0)
-#define DWC3_HAS_XHCI BIT(1)
-#define DWC3_HAS_OTG BIT(3)
-
-#endif /* __DRIVERS_USB_DWC3_CORE_H */
diff --git a/drivers/usb/dwc3/debug.h b/drivers/usb/dwc3/debug.h
deleted file mode 100644
index 5894ee8..0000000
--- a/drivers/usb/dwc3/debug.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * debug.h - DesignWare USB3 DRD Controller Debug Header
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * 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") version 2, as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#include "core.h"
-
-#ifdef CONFIG_DEBUG_FS
-extern int dwc3_debugfs_init(struct dwc3 *);
-extern void dwc3_debugfs_exit(struct dwc3 *);
-#else
-static inline int dwc3_debugfs_init(struct dwc3 *d)
-{ return 0; }
-static inline void dwc3_debugfs_exit(struct dwc3 *d)
-{ }
-#endif
-
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c
deleted file mode 100644
index da1ad77..0000000
--- a/drivers/usb/dwc3/debugfs.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/**
- * debugfs.c - DesignWare USB3 DRD Controller DebugFS file
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * 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") version 2, as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/ptrace.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/delay.h>
-
-#include <asm/uaccess.h>
-
-#include "core.h"
-#include "gadget.h"
-#include "io.h"
-
-struct dwc3_register {
- const char *name;
- u32 offset;
-};
-
-#define dump_register(nm) \
-{ \
- .name = __stringify(nm), \
- .offset = DWC3_ ##nm, \
-}
-
-static const struct dwc3_register dwc3_regs[] = {
- dump_register(GSBUSCFG0),
- dump_register(GSBUSCFG1),
- dump_register(GTXTHRCFG),
- dump_register(GRXTHRCFG),
- dump_register(GCTL),
- dump_register(GEVTEN),
- dump_register(GSTS),
- dump_register(GSNPSID),
- dump_register(GGPIO),
- dump_register(GUID),
- dump_register(GUCTL),
- dump_register(GBUSERRADDR0),
- dump_register(GBUSERRADDR1),
- dump_register(GPRTBIMAP0),
- dump_register(GPRTBIMAP1),
- dump_register(GHWPARAMS0),
- dump_register(GHWPARAMS1),
- dump_register(GHWPARAMS2),
- dump_register(GHWPARAMS3),
- dump_register(GHWPARAMS4),
- dump_register(GHWPARAMS5),
- dump_register(GHWPARAMS6),
- dump_register(GHWPARAMS7),
- dump_register(GDBGFIFOSPACE),
- dump_register(GDBGLTSSM),
- dump_register(GPRTBIMAP_HS0),
- dump_register(GPRTBIMAP_HS1),
- dump_register(GPRTBIMAP_FS0),
- dump_register(GPRTBIMAP_FS1),
-
- dump_register(GUSB2PHYCFG(0)),
- dump_register(GUSB2PHYCFG(1)),
- dump_register(GUSB2PHYCFG(2)),
- dump_register(GUSB2PHYCFG(3)),
- dump_register(GUSB2PHYCFG(4)),
- dump_register(GUSB2PHYCFG(5)),
- dump_register(GUSB2PHYCFG(6)),
- dump_register(GUSB2PHYCFG(7)),
- dump_register(GUSB2PHYCFG(8)),
- dump_register(GUSB2PHYCFG(9)),
- dump_register(GUSB2PHYCFG(10)),
- dump_register(GUSB2PHYCFG(11)),
- dump_register(GUSB2PHYCFG(12)),
- dump_register(GUSB2PHYCFG(13)),
- dump_register(GUSB2PHYCFG(14)),
- dump_register(GUSB2PHYCFG(15)),
-
- dump_register(GUSB2I2CCTL(0)),
- dump_register(GUSB2I2CCTL(1)),
- dump_register(GUSB2I2CCTL(2)),
- dump_register(GUSB2I2CCTL(3)),
- dump_register(GUSB2I2CCTL(4)),
- dump_register(GUSB2I2CCTL(5)),
- dump_register(GUSB2I2CCTL(6)),
- dump_register(GUSB2I2CCTL(7)),
- dump_register(GUSB2I2CCTL(8)),
- dump_register(GUSB2I2CCTL(9)),
- dump_register(GUSB2I2CCTL(10)),
- dump_register(GUSB2I2CCTL(11)),
- dump_register(GUSB2I2CCTL(12)),
- dump_register(GUSB2I2CCTL(13)),
- dump_register(GUSB2I2CCTL(14)),
- dump_register(GUSB2I2CCTL(15)),
-
- dump_register(GUSB2PHYACC(0)),
- dump_register(GUSB2PHYACC(1)),
- dump_register(GUSB2PHYACC(2)),
- dump_register(GUSB2PHYACC(3)),
- dump_register(GUSB2PHYACC(4)),
- dump_register(GUSB2PHYACC(5)),
- dump_register(GUSB2PHYACC(6)),
- dump_register(GUSB2PHYACC(7)),
- dump_register(GUSB2PHYACC(8)),
- dump_register(GUSB2PHYACC(9)),
- dump_register(GUSB2PHYACC(10)),
- dump_register(GUSB2PHYACC(11)),
- dump_register(GUSB2PHYACC(12)),
- dump_register(GUSB2PHYACC(13)),
- dump_register(GUSB2PHYACC(14)),
- dump_register(GUSB2PHYACC(15)),
-
- dump_register(GUSB3PIPECTL(0)),
- dump_register(GUSB3PIPECTL(1)),
- dump_register(GUSB3PIPECTL(2)),
- dump_register(GUSB3PIPECTL(3)),
- dump_register(GUSB3PIPECTL(4)),
- dump_register(GUSB3PIPECTL(5)),
- dump_register(GUSB3PIPECTL(6)),
- dump_register(GUSB3PIPECTL(7)),
- dump_register(GUSB3PIPECTL(8)),
- dump_register(GUSB3PIPECTL(9)),
- dump_register(GUSB3PIPECTL(10)),
- dump_register(GUSB3PIPECTL(11)),
- dump_register(GUSB3PIPECTL(12)),
- dump_register(GUSB3PIPECTL(13)),
- dump_register(GUSB3PIPECTL(14)),
- dump_register(GUSB3PIPECTL(15)),
-
- dump_register(GTXFIFOSIZ(0)),
- dump_register(GTXFIFOSIZ(1)),
- dump_register(GTXFIFOSIZ(2)),
- dump_register(GTXFIFOSIZ(3)),
- dump_register(GTXFIFOSIZ(4)),
- dump_register(GTXFIFOSIZ(5)),
- dump_register(GTXFIFOSIZ(6)),
- dump_register(GTXFIFOSIZ(7)),
- dump_register(GTXFIFOSIZ(8)),
- dump_register(GTXFIFOSIZ(9)),
- dump_register(GTXFIFOSIZ(10)),
- dump_register(GTXFIFOSIZ(11)),
- dump_register(GTXFIFOSIZ(12)),
- dump_register(GTXFIFOSIZ(13)),
- dump_register(GTXFIFOSIZ(14)),
- dump_register(GTXFIFOSIZ(15)),
- dump_register(GTXFIFOSIZ(16)),
- dump_register(GTXFIFOSIZ(17)),
- dump_register(GTXFIFOSIZ(18)),
- dump_register(GTXFIFOSIZ(19)),
- dump_register(GTXFIFOSIZ(20)),
- dump_register(GTXFIFOSIZ(21)),
- dump_register(GTXFIFOSIZ(22)),
- dump_register(GTXFIFOSIZ(23)),
- dump_register(GTXFIFOSIZ(24)),
- dump_register(GTXFIFOSIZ(25)),
- dump_register(GTXFIFOSIZ(26)),
- dump_register(GTXFIFOSIZ(27)),
- dump_register(GTXFIFOSIZ(28)),
- dump_register(GTXFIFOSIZ(29)),
- dump_register(GTXFIFOSIZ(30)),
- dump_register(GTXFIFOSIZ(31)),
-
- dump_register(GRXFIFOSIZ(0)),
- dump_register(GRXFIFOSIZ(1)),
- dump_register(GRXFIFOSIZ(2)),
- dump_register(GRXFIFOSIZ(3)),
- dump_register(GRXFIFOSIZ(4)),
- dump_register(GRXFIFOSIZ(5)),
- dump_register(GRXFIFOSIZ(6)),
- dump_register(GRXFIFOSIZ(7)),
- dump_register(GRXFIFOSIZ(8)),
- dump_register(GRXFIFOSIZ(9)),
- dump_register(GRXFIFOSIZ(10)),
- dump_register(GRXFIFOSIZ(11)),
- dump_register(GRXFIFOSIZ(12)),
- dump_register(GRXFIFOSIZ(13)),
- dump_register(GRXFIFOSIZ(14)),
- dump_register(GRXFIFOSIZ(15)),
- dump_register(GRXFIFOSIZ(16)),
- dump_register(GRXFIFOSIZ(17)),
- dump_register(GRXFIFOSIZ(18)),
- dump_register(GRXFIFOSIZ(19)),
- dump_register(GRXFIFOSIZ(20)),
- dump_register(GRXFIFOSIZ(21)),
- dump_register(GRXFIFOSIZ(22)),
- dump_register(GRXFIFOSIZ(23)),
- dump_register(GRXFIFOSIZ(24)),
- dump_register(GRXFIFOSIZ(25)),
- dump_register(GRXFIFOSIZ(26)),
- dump_register(GRXFIFOSIZ(27)),
- dump_register(GRXFIFOSIZ(28)),
- dump_register(GRXFIFOSIZ(29)),
- dump_register(GRXFIFOSIZ(30)),
- dump_register(GRXFIFOSIZ(31)),
-
- dump_register(GEVNTADRLO(0)),
- dump_register(GEVNTADRHI(0)),
- dump_register(GEVNTSIZ(0)),
- dump_register(GEVNTCOUNT(0)),
-
- dump_register(GHWPARAMS8),
- dump_register(DCFG),
- dump_register(DCTL),
- dump_register(DEVTEN),
- dump_register(DSTS),
- dump_register(DGCMDPAR),
- dump_register(DGCMD),
- dump_register(DALEPENA),
-
- dump_register(DEPCMDPAR2(0)),
- dump_register(DEPCMDPAR2(1)),
- dump_register(DEPCMDPAR2(2)),
- dump_register(DEPCMDPAR2(3)),
- dump_register(DEPCMDPAR2(4)),
- dump_register(DEPCMDPAR2(5)),
- dump_register(DEPCMDPAR2(6)),
- dump_register(DEPCMDPAR2(7)),
- dump_register(DEPCMDPAR2(8)),
- dump_register(DEPCMDPAR2(9)),
- dump_register(DEPCMDPAR2(10)),
- dump_register(DEPCMDPAR2(11)),
- dump_register(DEPCMDPAR2(12)),
- dump_register(DEPCMDPAR2(13)),
- dump_register(DEPCMDPAR2(14)),
- dump_register(DEPCMDPAR2(15)),
- dump_register(DEPCMDPAR2(16)),
- dump_register(DEPCMDPAR2(17)),
- dump_register(DEPCMDPAR2(18)),
- dump_register(DEPCMDPAR2(19)),
- dump_register(DEPCMDPAR2(20)),
- dump_register(DEPCMDPAR2(21)),
- dump_register(DEPCMDPAR2(22)),
- dump_register(DEPCMDPAR2(23)),
- dump_register(DEPCMDPAR2(24)),
- dump_register(DEPCMDPAR2(25)),
- dump_register(DEPCMDPAR2(26)),
- dump_register(DEPCMDPAR2(27)),
- dump_register(DEPCMDPAR2(28)),
- dump_register(DEPCMDPAR2(29)),
- dump_register(DEPCMDPAR2(30)),
- dump_register(DEPCMDPAR2(31)),
-
- dump_register(DEPCMDPAR1(0)),
- dump_register(DEPCMDPAR1(1)),
- dump_register(DEPCMDPAR1(2)),
- dump_register(DEPCMDPAR1(3)),
- dump_register(DEPCMDPAR1(4)),
- dump_register(DEPCMDPAR1(5)),
- dump_register(DEPCMDPAR1(6)),
- dump_register(DEPCMDPAR1(7)),
- dump_register(DEPCMDPAR1(8)),
- dump_register(DEPCMDPAR1(9)),
- dump_register(DEPCMDPAR1(10)),
- dump_register(DEPCMDPAR1(11)),
- dump_register(DEPCMDPAR1(12)),
- dump_register(DEPCMDPAR1(13)),
- dump_register(DEPCMDPAR1(14)),
- dump_register(DEPCMDPAR1(15)),
- dump_register(DEPCMDPAR1(16)),
- dump_register(DEPCMDPAR1(17)),
- dump_register(DEPCMDPAR1(18)),
- dump_register(DEPCMDPAR1(19)),
- dump_register(DEPCMDPAR1(20)),
- dump_register(DEPCMDPAR1(21)),
- dump_register(DEPCMDPAR1(22)),
- dump_register(DEPCMDPAR1(23)),
- dump_register(DEPCMDPAR1(24)),
- dump_register(DEPCMDPAR1(25)),
- dump_register(DEPCMDPAR1(26)),
- dump_register(DEPCMDPAR1(27)),
- dump_register(DEPCMDPAR1(28)),
- dump_register(DEPCMDPAR1(29)),
- dump_register(DEPCMDPAR1(30)),
- dump_register(DEPCMDPAR1(31)),
-
- dump_register(DEPCMDPAR0(0)),
- dump_register(DEPCMDPAR0(1)),
- dump_register(DEPCMDPAR0(2)),
- dump_register(DEPCMDPAR0(3)),
- dump_register(DEPCMDPAR0(4)),
- dump_register(DEPCMDPAR0(5)),
- dump_register(DEPCMDPAR0(6)),
- dump_register(DEPCMDPAR0(7)),
- dump_register(DEPCMDPAR0(8)),
- dump_register(DEPCMDPAR0(9)),
- dump_register(DEPCMDPAR0(10)),
- dump_register(DEPCMDPAR0(11)),
- dump_register(DEPCMDPAR0(12)),
- dump_register(DEPCMDPAR0(13)),
- dump_register(DEPCMDPAR0(14)),
- dump_register(DEPCMDPAR0(15)),
- dump_register(DEPCMDPAR0(16)),
- dump_register(DEPCMDPAR0(17)),
- dump_register(DEPCMDPAR0(18)),
- dump_register(DEPCMDPAR0(19)),
- dump_register(DEPCMDPAR0(20)),
- dump_register(DEPCMDPAR0(21)),
- dump_register(DEPCMDPAR0(22)),
- dump_register(DEPCMDPAR0(23)),
- dump_register(DEPCMDPAR0(24)),
- dump_register(DEPCMDPAR0(25)),
- dump_register(DEPCMDPAR0(26)),
- dump_register(DEPCMDPAR0(27)),
- dump_register(DEPCMDPAR0(28)),
- dump_register(DEPCMDPAR0(29)),
- dump_register(DEPCMDPAR0(30)),
- dump_register(DEPCMDPAR0(31)),
-
- dump_register(DEPCMD(0)),
- dump_register(DEPCMD(1)),
- dump_register(DEPCMD(2)),
- dump_register(DEPCMD(3)),
- dump_register(DEPCMD(4)),
- dump_register(DEPCMD(5)),
- dump_register(DEPCMD(6)),
- dump_register(DEPCMD(7)),
- dump_register(DEPCMD(8)),
- dump_register(DEPCMD(9)),
- dump_register(DEPCMD(10)),
- dump_register(DEPCMD(11)),
- dump_register(DEPCMD(12)),
- dump_register(DEPCMD(13)),
- dump_register(DEPCMD(14)),
- dump_register(DEPCMD(15)),
- dump_register(DEPCMD(16)),
- dump_register(DEPCMD(17)),
- dump_register(DEPCMD(18)),
- dump_register(DEPCMD(19)),
- dump_register(DEPCMD(20)),
- dump_register(DEPCMD(21)),
- dump_register(DEPCMD(22)),
- dump_register(DEPCMD(23)),
- dump_register(DEPCMD(24)),
- dump_register(DEPCMD(25)),
- dump_register(DEPCMD(26)),
- dump_register(DEPCMD(27)),
- dump_register(DEPCMD(28)),
- dump_register(DEPCMD(29)),
- dump_register(DEPCMD(30)),
- dump_register(DEPCMD(31)),
-
- dump_register(OCFG),
- dump_register(OCTL),
- dump_register(OEVTEN),
- dump_register(OSTS),
-};
-
-static int dwc3_regdump_show(struct seq_file *s, void *unused)
-{
- struct dwc3 *dwc = s->private;
- int i;
-
- seq_printf(s, "DesignWare USB3 Core Register Dump\n");
-
- for (i = 0; i < ARRAY_SIZE(dwc3_regs); i++) {
- seq_printf(s, "%-20s : %08x\n", dwc3_regs[i].name,
- dwc3_readl(dwc->regs, dwc3_regs[i].offset));
- }
-
- return 0;
-}
-
-static int dwc3_regdump_open(struct inode *inode, struct file *file)
-{
- return single_open(file, dwc3_regdump_show, inode->i_private);
-}
-
-static const struct file_operations dwc3_regdump_fops = {
- .open = dwc3_regdump_open,
- .read = seq_read,
- .release = single_release,
-};
-
-int __devinit dwc3_debugfs_init(struct dwc3 *dwc)
-{
- struct dentry *root;
- struct dentry *file;
- int ret;
-
- root = debugfs_create_dir(dev_name(dwc->dev), NULL);
- if (IS_ERR(root)){
- ret = PTR_ERR(root);
- goto err0;
- }
-
- dwc->root = root;
-
- file = debugfs_create_file("regdump", S_IRUGO, root, dwc,
- &dwc3_regdump_fops);
- if (IS_ERR(file)) {
- ret = PTR_ERR(file);
- goto err1;
- }
- return 0;
-
-err1:
- debugfs_remove_recursive(root);
-
-err0:
- return ret;
-}
-
-void __devexit dwc3_debugfs_exit(struct dwc3 *dwc)
-{
- debugfs_remove_recursive(dwc->root);
- dwc->root = NULL;
-}
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
deleted file mode 100644
index 062552b..0000000
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/**
- * dwc3-omap.c - OMAP Specific Glue layer
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * 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") version 2, as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/platform_device.h>
-#include <linux/platform_data/dwc3-omap.h>
-#include <linux/dma-mapping.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-#include <linux/module.h>
-
-#include "io.h"
-
-/*
- * All these registers belong to OMAP's Wrapper around the
- * DesignWare USB3 Core.
- */
-
-#define USBOTGSS_REVISION 0x0000
-#define USBOTGSS_SYSCONFIG 0x0010
-#define USBOTGSS_IRQ_EOI 0x0020
-#define USBOTGSS_IRQSTATUS_RAW_0 0x0024
-#define USBOTGSS_IRQSTATUS_0 0x0028
-#define USBOTGSS_IRQENABLE_SET_0 0x002c
-#define USBOTGSS_IRQENABLE_CLR_0 0x0030
-#define USBOTGSS_IRQSTATUS_RAW_1 0x0034
-#define USBOTGSS_IRQSTATUS_1 0x0038
-#define USBOTGSS_IRQENABLE_SET_1 0x003c
-#define USBOTGSS_IRQENABLE_CLR_1 0x0040
-#define USBOTGSS_UTMI_OTG_CTRL 0x0080
-#define USBOTGSS_UTMI_OTG_STATUS 0x0084
-#define USBOTGSS_MMRAM_OFFSET 0x0100
-#define USBOTGSS_FLADJ 0x0104
-#define USBOTGSS_DEBUG_CFG 0x0108
-#define USBOTGSS_DEBUG_DATA 0x010c
-
-/* SYSCONFIG REGISTER */
-#define USBOTGSS_SYSCONFIG_DMADISABLE (1 << 16)
-#define USBOTGSS_SYSCONFIG_STANDBYMODE(x) ((x) << 4)
-
-#define USBOTGSS_STANDBYMODE_FORCE_STANDBY 0
-#define USBOTGSS_STANDBYMODE_NO_STANDBY 1
-#define USBOTGSS_STANDBYMODE_SMART_STANDBY 2
-#define USBOTGSS_STANDBYMODE_SMART_WAKEUP 3
-
-#define USBOTGSS_STANDBYMODE_MASK (0x03 << 4)
-
-#define USBOTGSS_SYSCONFIG_IDLEMODE(x) ((x) << 2)
-
-#define USBOTGSS_IDLEMODE_FORCE_IDLE 0
-#define USBOTGSS_IDLEMODE_NO_IDLE 1
-#define USBOTGSS_IDLEMODE_SMART_IDLE 2
-#define USBOTGSS_IDLEMODE_SMART_WAKEUP 3
-
-#define USBOTGSS_IDLEMODE_MASK (0x03 << 2)
-
-/* IRQ_EOI REGISTER */
-#define USBOTGSS_IRQ_EOI_LINE_NUMBER (1 << 0)
-
-/* IRQS0 BITS */
-#define USBOTGSS_IRQO_COREIRQ_ST (1 << 0)
-
-/* IRQ1 BITS */
-#define USBOTGSS_IRQ1_DMADISABLECLR (1 << 17)
-#define USBOTGSS_IRQ1_OEVT (1 << 16)
-#define USBOTGSS_IRQ1_DRVVBUS_RISE (1 << 13)
-#define USBOTGSS_IRQ1_CHRGVBUS_RISE (1 << 12)
-#define USBOTGSS_IRQ1_DISCHRGVBUS_RISE (1 << 11)
-#define USBOTGSS_IRQ1_IDPULLUP_RISE (1 << 8)
-#define USBOTGSS_IRQ1_DRVVBUS_FALL (1 << 5)
-#define USBOTGSS_IRQ1_CHRGVBUS_FALL (1 << 4)
-#define USBOTGSS_IRQ1_DISCHRGVBUS_FALL (1 << 3)
-#define USBOTGSS_IRQ1_IDPULLUP_FALL (1 << 0)
-
-/* UTMI_OTG_CTRL REGISTER */
-#define USBOTGSS_UTMI_OTG_CTRL_DRVVBUS (1 << 5)
-#define USBOTGSS_UTMI_OTG_CTRL_CHRGVBUS (1 << 4)
-#define USBOTGSS_UTMI_OTG_CTRL_DISCHRGVBUS (1 << 3)
-#define USBOTGSS_UTMI_OTG_CTRL_IDPULLUP (1 << 0)
-
-/* UTMI_OTG_STATUS REGISTER */
-#define USBOTGSS_UTMI_OTG_STATUS_SW_MODE (1 << 31)
-#define USBOTGSS_UTMI_OTG_STATUS_POWERPRESENT (1 << 9)
-#define USBOTGSS_UTMI_OTG_STATUS_TXBITSTUFFENABLE (1 << 8)
-#define USBOTGSS_UTMI_OTG_STATUS_IDDIG (1 << 4)
-#define USBOTGSS_UTMI_OTG_STATUS_SESSEND (1 << 3)
-#define USBOTGSS_UTMI_OTG_STATUS_SESSVALID (1 << 2)
-#define USBOTGSS_UTMI_OTG_STATUS_VBUSVALID (1 << 1)
-
-struct dwc3_omap {
- /* device lock */
- spinlock_t lock;
-
- struct platform_device *dwc3;
- struct device *dev;
-
- int irq;
- void __iomem *base;
-
- void *context;
- u32 resource_size;
-
- u32 dma_status:1;
-};
-
-static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap)
-{
- struct dwc3_omap *omap = _omap;
- u32 reg;
-
- spin_lock(&omap->lock);
-
- reg = dwc3_readl(omap->base, USBOTGSS_IRQSTATUS_1);
-
- if (reg & USBOTGSS_IRQ1_DMADISABLECLR) {
- dev_dbg(omap->dev, "DMA Disable was Cleared\n");
- omap->dma_status = false;
- }
-
- if (reg & USBOTGSS_IRQ1_OEVT)
- dev_dbg(omap->dev, "OTG Event\n");
-
- if (reg & USBOTGSS_IRQ1_DRVVBUS_RISE)
- dev_dbg(omap->dev, "DRVVBUS Rise\n");
-
- if (reg & USBOTGSS_IRQ1_CHRGVBUS_RISE)
- dev_dbg(omap->dev, "CHRGVBUS Rise\n");
-
- if (reg & USBOTGSS_IRQ1_DISCHRGVBUS_RISE)
- dev_dbg(omap->dev, "DISCHRGVBUS Rise\n");
-
- if (reg & USBOTGSS_IRQ1_IDPULLUP_RISE)
- dev_dbg(omap->dev, "IDPULLUP Rise\n");
-
- if (reg & USBOTGSS_IRQ1_DRVVBUS_FALL)
- dev_dbg(omap->dev, "DRVVBUS Fall\n");
-
- if (reg & USBOTGSS_IRQ1_CHRGVBUS_FALL)
- dev_dbg(omap->dev, "CHRGVBUS Fall\n");
-
- if (reg & USBOTGSS_IRQ1_DISCHRGVBUS_FALL)
- dev_dbg(omap->dev, "DISCHRGVBUS Fall\n");
-
- if (reg & USBOTGSS_IRQ1_IDPULLUP_FALL)
- dev_dbg(omap->dev, "IDPULLUP Fall\n");
-
- dwc3_writel(omap->base, USBOTGSS_IRQSTATUS_1, reg);
-
- reg = dwc3_readl(omap->base, USBOTGSS_IRQSTATUS_0);
- dwc3_writel(omap->base, USBOTGSS_IRQSTATUS_0, reg);
-
- spin_unlock(&omap->lock);
-
- return IRQ_HANDLED;
-}
-
-static int __devinit dwc3_omap_probe(struct platform_device *pdev)
-{
- struct dwc3_omap_data *pdata = pdev->dev.platform_data;
- struct platform_device *dwc3;
- struct dwc3_omap *omap;
- struct resource *res;
-
- int ret = -ENOMEM;
- int irq;
-
- u32 reg;
-
- void __iomem *base;
- void *context;
-
- omap = kzalloc(sizeof(*omap), GFP_KERNEL);
- if (!omap) {
- dev_err(&pdev->dev, "not enough memory\n");
- goto err0;
- }
-
- platform_set_drvdata(pdev, omap);
-
- irq = platform_get_irq(pdev, 1);
- if (irq < 0) {
- dev_err(&pdev->dev, "missing IRQ resource\n");
- ret = -EINVAL;
- goto err1;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!res) {
- dev_err(&pdev->dev, "missing memory base resource\n");
- ret = -EINVAL;
- goto err1;
- }
-
- base = ioremap_nocache(res->start, resource_size(res));
- if (!base) {
- dev_err(&pdev->dev, "ioremap failed\n");
- goto err1;
- }
-
- dwc3 = platform_device_alloc("dwc3-omap", -1);
- if (!dwc3) {
- dev_err(&pdev->dev, "couldn't allocate dwc3 device\n");
- goto err2;
- }
-
- context = kzalloc(resource_size(res), GFP_KERNEL);
- if (!context) {
- dev_err(&pdev->dev, "couldn't allocate dwc3 context memory\n");
- goto err3;
- }
-
- spin_lock_init(&omap->lock);
- dma_set_coherent_mask(&dwc3->dev, pdev->dev.coherent_dma_mask);
-
- dwc3->dev.parent = &pdev->dev;
- dwc3->dev.dma_mask = pdev->dev.dma_mask;
- dwc3->dev.dma_parms = pdev->dev.dma_parms;
- omap->resource_size = resource_size(res);
- omap->context = context;
- omap->dev = &pdev->dev;
- omap->irq = irq;
- omap->base = base;
- omap->dwc3 = dwc3;
-
- reg = dwc3_readl(omap->base, USBOTGSS_UTMI_OTG_STATUS);
-
- if (!pdata) {
- dev_dbg(&pdev->dev, "missing platform data\n");
- } else {
- switch (pdata->utmi_mode) {
- case DWC3_OMAP_UTMI_MODE_SW:
- reg |= USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
- break;
- case DWC3_OMAP_UTMI_MODE_HW:
- reg &= ~USBOTGSS_UTMI_OTG_STATUS_SW_MODE;
- break;
- default:
- dev_dbg(&pdev->dev, "UNKNOWN utmi mode %d\n",
- pdata->utmi_mode);
- }
- }
-
- dwc3_writel(omap->base, USBOTGSS_UTMI_OTG_STATUS, reg);
-
- /* check the DMA Status */
- reg = dwc3_readl(omap->base, USBOTGSS_SYSCONFIG);
- omap->dma_status = !!(reg & USBOTGSS_SYSCONFIG_DMADISABLE);
-
- /* Set No-Idle and No-Standby */
- reg &= ~(USBOTGSS_STANDBYMODE_MASK
- | USBOTGSS_IDLEMODE_MASK);
-
- reg |= (USBOTGSS_SYSCONFIG_STANDBYMODE(USBOTGSS_STANDBYMODE_NO_STANDBY)
- | USBOTGSS_SYSCONFIG_IDLEMODE(USBOTGSS_IDLEMODE_NO_IDLE));
-
- dwc3_writel(omap->base, USBOTGSS_SYSCONFIG, reg);
-
- ret = request_irq(omap->irq, dwc3_omap_interrupt, 0,
- "dwc3-omap", omap);
- if (ret) {
- dev_err(&pdev->dev, "failed to request IRQ #%d --> %d\n",
- omap->irq, ret);
- goto err4;
- }
-
- /* enable all IRQs */
- reg = USBOTGSS_IRQO_COREIRQ_ST;
- dwc3_writel(omap->base, USBOTGSS_IRQENABLE_SET_0, reg);
-
- reg = (USBOTGSS_IRQ1_OEVT |
- USBOTGSS_IRQ1_DRVVBUS_RISE |
- USBOTGSS_IRQ1_CHRGVBUS_RISE |
- USBOTGSS_IRQ1_DISCHRGVBUS_RISE |
- USBOTGSS_IRQ1_IDPULLUP_RISE |
- USBOTGSS_IRQ1_DRVVBUS_FALL |
- USBOTGSS_IRQ1_CHRGVBUS_FALL |
- USBOTGSS_IRQ1_DISCHRGVBUS_FALL |
- USBOTGSS_IRQ1_IDPULLUP_FALL);
-
- dwc3_writel(omap->base, USBOTGSS_IRQENABLE_SET_1, reg);
-
- ret = platform_device_add_resources(dwc3, pdev->resource,
- pdev->num_resources);
- if (ret) {
- dev_err(&pdev->dev, "couldn't add resources to dwc3 device\n");
- goto err5;
- }
-
- ret = platform_device_add(dwc3);
- if (ret) {
- dev_err(&pdev->dev, "failed to register dwc3 device\n");
- goto err5;
- }
-
- return 0;
-
-err5:
- free_irq(omap->irq, omap);
-
-err4:
- kfree(omap->context);
-
-err3:
- platform_device_put(dwc3);
-
-err2:
- iounmap(base);
-
-err1:
- kfree(omap);
-
-err0:
- return ret;
-}
-
-static int __devexit dwc3_omap_remove(struct platform_device *pdev)
-{
- struct dwc3_omap *omap = platform_get_drvdata(pdev);
-
- platform_device_unregister(omap->dwc3);
-
- free_irq(omap->irq, omap);
- iounmap(omap->base);
-
- kfree(omap->context);
- kfree(omap);
-
- return 0;
-}
-
-static const struct of_device_id of_dwc3_matach[] = {
- {
- "ti,dwc3",
- },
- { },
-};
-MODULE_DEVICE_TABLE(of, of_dwc3_matach);
-
-static struct platform_driver dwc3_omap_driver = {
- .probe = dwc3_omap_probe,
- .remove = __devexit_p(dwc3_omap_remove),
- .driver = {
- .name = "omap-dwc3",
- .of_match_table = of_dwc3_matach,
- },
-};
-
-MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_DESCRIPTION("DesignWare USB3 OMAP Glue Layer");
-
-static int __devinit dwc3_omap_init(void)
-{
- return platform_driver_register(&dwc3_omap_driver);
-}
-module_init(dwc3_omap_init);
-
-static void __exit dwc3_omap_exit(void)
-{
- platform_driver_unregister(&dwc3_omap_driver);
-}
-module_exit(dwc3_omap_exit);
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
deleted file mode 100644
index f77c000..0000000
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/**
- * dwc3-pci.c - PCI Specific glue layer
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * 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") version 2, as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/platform_device.h>
-
-/* FIXME define these in <linux/pci_ids.h> */
-#define PCI_VENDOR_ID_SYNOPSYS 0x16c3
-#define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd
-
-#define DWC3_PCI_DEVS_POSSIBLE 32
-
-struct dwc3_pci {
- struct device *dev;
- struct platform_device *dwc3;
-};
-
-static DECLARE_BITMAP(dwc3_pci_devs, DWC3_PCI_DEVS_POSSIBLE);
-
-static int dwc3_pci_get_device_id(struct dwc3_pci *glue)
-{
- int id;
-
-again:
- id = find_first_zero_bit(dwc3_pci_devs, DWC3_PCI_DEVS_POSSIBLE);
- if (id < DWC3_PCI_DEVS_POSSIBLE) {
- int old;
-
- old = test_and_set_bit(id, dwc3_pci_devs);
- if (old)
- goto again;
- } else {
- dev_err(glue->dev, "no space for new device\n");
- id = -ENOMEM;
- }
-
- return 0;
-}
-
-static void dwc3_pci_put_device_id(struct dwc3_pci *glue, int id)
-{
- int ret;
-
- if (id < 0)
- return;
-
- ret = test_bit(id, dwc3_pci_devs);
- WARN(!ret, "Device: %s\nID %d not in use\n",
- dev_driver_string(glue->dev), id);
- clear_bit(id, dwc3_pci_devs);
-}
-
-static int __devinit dwc3_pci_probe(struct pci_dev *pci,
- const struct pci_device_id *id)
-{
- struct resource res[2];
- struct platform_device *dwc3;
- struct dwc3_pci *glue;
- int ret = -ENOMEM;
- int devid;
-
- glue = kzalloc(sizeof(*glue), GFP_KERNEL);
- if (!glue) {
- dev_err(&pci->dev, "not enough memory\n");
- goto err0;
- }
-
- glue->dev = &pci->dev;
-
- ret = pci_enable_device(pci);
- if (ret) {
- dev_err(&pci->dev, "failed to enable pci device\n");
- goto err1;
- }
-
- pci_set_power_state(pci, PCI_D0);
- pci_set_master(pci);
-
- devid = dwc3_pci_get_device_id(glue);
- if (devid < 0)
- goto err2;
-
- dwc3 = platform_device_alloc("dwc3-pci", devid);
- if (!dwc3) {
- dev_err(&pci->dev, "couldn't allocate dwc3 device\n");
- goto err3;
- }
-
- memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
-
- res[0].start = pci_resource_start(pci, 0);
- res[0].end = pci_resource_end(pci, 0);
- res[0].name = "dwc_usb3";
- res[0].flags = IORESOURCE_MEM;
-
- res[1].start = pci->irq;
- res[1].name = "dwc_usb3";
- res[1].flags = IORESOURCE_IRQ;
-
- ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res));
- if (ret) {
- dev_err(&pci->dev, "couldn't add resources to dwc3 device\n");
- goto err4;
- }
-
- pci_set_drvdata(pci, glue);
-
- dma_set_coherent_mask(&dwc3->dev, pci->dev.coherent_dma_mask);
-
- dwc3->dev.dma_mask = pci->dev.dma_mask;
- dwc3->dev.dma_parms = pci->dev.dma_parms;
- dwc3->dev.parent = &pci->dev;
- glue->dwc3 = dwc3;
-
- ret = platform_device_add(dwc3);
- if (ret) {
- dev_err(&pci->dev, "failed to register dwc3 device\n");
- goto err4;
- }
-
- return 0;
-
-err4:
- pci_set_drvdata(pci, NULL);
- platform_device_put(dwc3);
-
-err3:
- dwc3_pci_put_device_id(glue, devid);
-
-err2:
- pci_disable_device(pci);
-
-err1:
- kfree(pci);
-
-err0:
- return ret;
-}
-
-static void __devexit dwc3_pci_remove(struct pci_dev *pci)
-{
- struct dwc3_pci *glue = pci_get_drvdata(pci);
-
- dwc3_pci_put_device_id(glue, glue->dwc3->id);
- platform_device_unregister(glue->dwc3);
- pci_set_drvdata(pci, NULL);
- pci_disable_device(pci);
- kfree(glue);
-}
-
-static DEFINE_PCI_DEVICE_TABLE(dwc3_pci_id_table) = {
- {
- PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS,
- PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3),
- },
- { } /* Terminating Entry */
-};
-MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table);
-
-static struct pci_driver dwc3_pci_driver = {
- .name = "pci-dwc3",
- .id_table = dwc3_pci_id_table,
- .probe = dwc3_pci_probe,
- .remove = __devexit_p(dwc3_pci_remove),
-};
-
-MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_DESCRIPTION("DesignWare USB3 PCI Glue Layer");
-
-static int __devinit dwc3_pci_init(void)
-{
- return pci_register_driver(&dwc3_pci_driver);
-}
-module_init(dwc3_pci_init);
-
-static void __exit dwc3_pci_exit(void)
-{
- pci_unregister_driver(&dwc3_pci_driver);
-}
-module_exit(dwc3_pci_exit);
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
deleted file mode 100644
index 69a4e43..0000000
--- a/drivers/usb/dwc3/ep0.c
+++ /dev/null
@@ -1,804 +0,0 @@
-/**
- * ep0.c - DesignWare USB3 DRD Controller Endpoint 0 Handling
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * 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") version 2, as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#include <linux/kernel.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 <linux/list.h>
-#include <linux/dma-mapping.h>
-
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-
-#include "core.h"
-#include "gadget.h"
-#include "io.h"
-
-static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,
- const struct dwc3_event_depevt *event);
-
-static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state)
-{
- switch (state) {
- case EP0_UNCONNECTED:
- return "Unconnected";
- case EP0_SETUP_PHASE:
- return "Setup Phase";
- case EP0_DATA_PHASE:
- return "Data Phase";
- case EP0_STATUS_PHASE:
- return "Status Phase";
- default:
- return "UNKNOWN";
- }
-}
-
-static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
- u32 len, u32 type)
-{
- struct dwc3_gadget_ep_cmd_params params;
- struct dwc3_trb_hw *trb_hw;
- struct dwc3_trb trb;
- struct dwc3_ep *dep;
-
- int ret;
-
- dep = dwc->eps[epnum];
- if (dep->flags & DWC3_EP_BUSY) {
- dev_vdbg(dwc->dev, "%s: still busy\n", dep->name);
- return 0;
- }
-
- trb_hw = dwc->ep0_trb;
- memset(&trb, 0, sizeof(trb));
-
- trb.trbctl = type;
- trb.bplh = buf_dma;
- trb.length = len;
-
- trb.hwo = 1;
- trb.lst = 1;
- trb.ioc = 1;
- trb.isp_imi = 1;
-
- dwc3_trb_to_hw(&trb, trb_hw);
-
- memset(¶ms, 0, sizeof(params));
- params.param0 = upper_32_bits(dwc->ep0_trb_addr);
- params.param1 = lower_32_bits(dwc->ep0_trb_addr);
-
- ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
- DWC3_DEPCMD_STARTTRANSFER, ¶ms);
- if (ret < 0) {
- dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n");
- return ret;
- }
-
- dep->flags |= DWC3_EP_BUSY;
- dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc,
- dep->number);
-
- dwc->ep0_next_event = DWC3_EP0_COMPLETE;
-
- return 0;
-}
-
-static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,
- struct dwc3_request *req)
-{
- int ret = 0;
-
- req->request.actual = 0;
- req->request.status = -EINPROGRESS;
- req->epnum = dep->number;
-
- list_add_tail(&req->list, &dep->request_list);
-
- /*
- * Gadget driver might not be quick enough to queue a request
- * before we get a Transfer Not Ready event on this endpoint.
- *
- * In that case, we will set DWC3_EP_PENDING_REQUEST. When that
- * flag is set, it's telling us that as soon as Gadget queues the
- * required request, we should kick the transfer here because the
- * IRQ we were waiting for is long gone.
- */
- if (dep->flags & DWC3_EP_PENDING_REQUEST) {
- struct dwc3 *dwc = dep->dwc;
- unsigned direction;
- u32 type;
-
- direction = !!(dep->flags & DWC3_EP0_DIR_IN);
-
- if (dwc->ep0state == EP0_STATUS_PHASE) {
- type = dwc->three_stage_setup
- ? DWC3_TRBCTL_CONTROL_STATUS3
- : DWC3_TRBCTL_CONTROL_STATUS2;
- } else if (dwc->ep0state == EP0_DATA_PHASE) {
- type = DWC3_TRBCTL_CONTROL_DATA;
- } else {
- /* should never happen */
- WARN_ON(1);
- return 0;
- }
-
- ret = dwc3_ep0_start_trans(dwc, direction,
- req->request.dma, req->request.length, type);
- dep->flags &= ~(DWC3_EP_PENDING_REQUEST |
- DWC3_EP0_DIR_IN);
- }
-
- return ret;
-}
-
-int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
- gfp_t gfp_flags)
-{
- struct dwc3_request *req = to_dwc3_request(request);
- struct dwc3_ep *dep = to_dwc3_ep(ep);
- struct dwc3 *dwc = dep->dwc;
-
- unsigned long flags;
-
- int ret;
-
- spin_lock_irqsave(&dwc->lock, flags);
- if (!dep->desc) {
- dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",
- request, dep->name);
- ret = -ESHUTDOWN;
- goto out;
- }
-
- /* we share one TRB for ep0/1 */
- if (!list_empty(&dwc->eps[0]->request_list) ||
- !list_empty(&dwc->eps[1]->request_list) ||
- dwc->ep0_status_pending) {
- ret = -EBUSY;
- goto out;
- }
-
- dev_vdbg(dwc->dev, "queueing request %p to %s length %d, state '%s'\n",
- request, dep->name, request->length,
- dwc3_ep0_state_string(dwc->ep0state));
-
- ret = __dwc3_gadget_ep0_queue(dep, req);
-
-out:
- spin_unlock_irqrestore(&dwc->lock, flags);
-
- return ret;
-}
-
-static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
-{
- struct dwc3_ep *dep = dwc->eps[0];
-
- /* stall is always issued on EP0 */
- __dwc3_gadget_ep_set_halt(dwc->eps[0], 1);
- dwc->eps[0]->flags = DWC3_EP_ENABLED;
-
- if (!list_empty(&dep->request_list)) {
- struct dwc3_request *req;
-
- req = next_request(&dep->request_list);
- dwc3_gadget_giveback(dep, req, -ECONNRESET);
- }
-
- dwc->ep0state = EP0_SETUP_PHASE;
- dwc3_ep0_out_start(dwc);
-}
-
-void dwc3_ep0_out_start(struct dwc3 *dwc)
-{
- int ret;
-
- ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8,
- DWC3_TRBCTL_CONTROL_SETUP);
- WARN_ON(ret < 0);
-}
-
-static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le)
-{
- struct dwc3_ep *dep;
- u32 windex = le16_to_cpu(wIndex_le);
- u32 epnum;
-
- epnum = (windex & USB_ENDPOINT_NUMBER_MASK) << 1;
- if ((windex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
- epnum |= 1;
-
- dep = dwc->eps[epnum];
- if (dep->flags & DWC3_EP_ENABLED)
- return dep;
-
- return NULL;
-}
-
-static void dwc3_ep0_send_status_response(struct dwc3 *dwc)
-{
- dwc3_ep0_start_trans(dwc, 1, dwc->setup_buf_addr,
- dwc->ep0_usb_req.length,
- DWC3_TRBCTL_CONTROL_DATA);
-}
-
-/*
- * ch 9.4.5
- */
-static int dwc3_ep0_handle_status(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
-{
- struct dwc3_ep *dep;
- u32 recip;
- u16 usb_status = 0;
- __le16 *response_pkt;
-
- recip = ctrl->bRequestType & USB_RECIP_MASK;
- switch (recip) {
- case USB_RECIP_DEVICE:
- /*
- * We are self-powered. U1/U2/LTM will be set later
- * once we handle this states. RemoteWakeup is 0 on SS
- */
- usb_status |= dwc->is_selfpowered << USB_DEVICE_SELF_POWERED;
- break;
-
- case USB_RECIP_INTERFACE:
- /*
- * Function Remote Wake Capable D0
- * Function Remote Wakeup D1
- */
- break;
-
- case USB_RECIP_ENDPOINT:
- dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex);
- if (!dep)
- return -EINVAL;
-
- if (dep->flags & DWC3_EP_STALL)
- usb_status = 1 << USB_ENDPOINT_HALT;
- break;
- default:
- return -EINVAL;
- };
-
- response_pkt = (__le16 *) dwc->setup_buf;
- *response_pkt = cpu_to_le16(usb_status);
- dwc->ep0_usb_req.length = sizeof(*response_pkt);
- dwc->ep0_status_pending = 1;
-
- return 0;
-}
-
-static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
- struct usb_ctrlrequest *ctrl, int set)
-{
- struct dwc3_ep *dep;
- u32 recip;
- u32 wValue;
- u32 wIndex;
- u32 reg;
- int ret;
- u32 mode;
-
- wValue = le16_to_cpu(ctrl->wValue);
- wIndex = le16_to_cpu(ctrl->wIndex);
- recip = ctrl->bRequestType & USB_RECIP_MASK;
- switch (recip) {
- case USB_RECIP_DEVICE:
-
- /*
- * 9.4.1 says only only for SS, in AddressState only for
- * default control pipe
- */
- switch (wValue) {
- case USB_DEVICE_U1_ENABLE:
- case USB_DEVICE_U2_ENABLE:
- case USB_DEVICE_LTM_ENABLE:
- if (dwc->dev_state != DWC3_CONFIGURED_STATE)
- return -EINVAL;
- if (dwc->speed != DWC3_DSTS_SUPERSPEED)
- return -EINVAL;
- }
-
- /* XXX add U[12] & LTM */
- switch (wValue) {
- case USB_DEVICE_REMOTE_WAKEUP:
- break;
- case USB_DEVICE_U1_ENABLE:
- break;
- case USB_DEVICE_U2_ENABLE:
- break;
- case USB_DEVICE_LTM_ENABLE:
- break;
-
- case USB_DEVICE_TEST_MODE:
- if ((wIndex & 0xff) != 0)
- return -EINVAL;
- if (!set)
- return -EINVAL;
-
- mode = wIndex >> 8;
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
- reg &= ~DWC3_DCTL_TSTCTRL_MASK;
-
- switch (mode) {
- case TEST_J:
- case TEST_K:
- case TEST_SE0_NAK:
- case TEST_PACKET:
- case TEST_FORCE_EN:
- reg |= mode << 1;
- break;
- default:
- return -EINVAL;
- }
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
- break;
- default:
- return -EINVAL;
- }
- break;
-
- case USB_RECIP_INTERFACE:
- switch (wValue) {
- case USB_INTRF_FUNC_SUSPEND:
- if (wIndex & USB_INTRF_FUNC_SUSPEND_LP)
- /* XXX enable Low power suspend */
- ;
- if (wIndex & USB_INTRF_FUNC_SUSPEND_RW)
- /* XXX enable remote wakeup */
- ;
- break;
- default:
- return -EINVAL;
- }
- break;
-
- case USB_RECIP_ENDPOINT:
- switch (wValue) {
- case USB_ENDPOINT_HALT:
-
- dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex);
- if (!dep)
- return -EINVAL;
- ret = __dwc3_gadget_ep_set_halt(dep, set);
- if (ret)
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
- break;
-
- default:
- return -EINVAL;
- };
-
- return 0;
-}
-
-static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
-{
- u32 addr;
- u32 reg;
-
- addr = le16_to_cpu(ctrl->wValue);
- if (addr > 127)
- return -EINVAL;
-
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
- reg &= ~(DWC3_DCFG_DEVADDR_MASK);
- reg |= DWC3_DCFG_DEVADDR(addr);
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
-
- if (addr)
- dwc->dev_state = DWC3_ADDRESS_STATE;
- else
- dwc->dev_state = DWC3_DEFAULT_STATE;
-
- return 0;
-}
-
-static int dwc3_ep0_delegate_req(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
-{
- int ret;
-
- spin_unlock(&dwc->lock);
- ret = dwc->gadget_driver->setup(&dwc->gadget, ctrl);
- spin_lock(&dwc->lock);
- return ret;
-}
-
-static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
-{
- u32 cfg;
- int ret;
-
- dwc->start_config_issued = false;
- cfg = le16_to_cpu(ctrl->wValue);
-
- switch (dwc->dev_state) {
- case DWC3_DEFAULT_STATE:
- return -EINVAL;
- break;
-
- case DWC3_ADDRESS_STATE:
- ret = dwc3_ep0_delegate_req(dwc, ctrl);
- /* if the cfg matches and the cfg is non zero */
- if (!ret && cfg)
- dwc->dev_state = DWC3_CONFIGURED_STATE;
- break;
-
- case DWC3_CONFIGURED_STATE:
- ret = dwc3_ep0_delegate_req(dwc, ctrl);
- if (!cfg)
- dwc->dev_state = DWC3_ADDRESS_STATE;
- break;
- }
- return 0;
-}
-
-static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
-{
- int ret;
-
- switch (ctrl->bRequest) {
- case USB_REQ_GET_STATUS:
- dev_vdbg(dwc->dev, "USB_REQ_GET_STATUS\n");
- ret = dwc3_ep0_handle_status(dwc, ctrl);
- break;
- case USB_REQ_CLEAR_FEATURE:
- dev_vdbg(dwc->dev, "USB_REQ_CLEAR_FEATURE\n");
- ret = dwc3_ep0_handle_feature(dwc, ctrl, 0);
- break;
- case USB_REQ_SET_FEATURE:
- dev_vdbg(dwc->dev, "USB_REQ_SET_FEATURE\n");
- ret = dwc3_ep0_handle_feature(dwc, ctrl, 1);
- break;
- case USB_REQ_SET_ADDRESS:
- dev_vdbg(dwc->dev, "USB_REQ_SET_ADDRESS\n");
- ret = dwc3_ep0_set_address(dwc, ctrl);
- break;
- case USB_REQ_SET_CONFIGURATION:
- dev_vdbg(dwc->dev, "USB_REQ_SET_CONFIGURATION\n");
- ret = dwc3_ep0_set_config(dwc, ctrl);
- break;
- default:
- dev_vdbg(dwc->dev, "Forwarding to gadget driver\n");
- ret = dwc3_ep0_delegate_req(dwc, ctrl);
- break;
- };
-
- return ret;
-}
-
-static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,
- const struct dwc3_event_depevt *event)
-{
- struct usb_ctrlrequest *ctrl = dwc->ctrl_req;
- int ret;
- u32 len;
-
- if (!dwc->gadget_driver)
- goto err;
-
- len = le16_to_cpu(ctrl->wLength);
- if (!len) {
- dwc->three_stage_setup = false;
- dwc->ep0_expect_in = false;
- dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS;
- } else {
- dwc->three_stage_setup = true;
- dwc->ep0_expect_in = !!(ctrl->bRequestType & USB_DIR_IN);
- dwc->ep0_next_event = DWC3_EP0_NRDY_DATA;
- }
-
- if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
- ret = dwc3_ep0_std_request(dwc, ctrl);
- else
- ret = dwc3_ep0_delegate_req(dwc, ctrl);
-
- if (ret >= 0)
- return;
-
-err:
- dwc3_ep0_stall_and_restart(dwc);
-}
-
-static void dwc3_ep0_complete_data(struct dwc3 *dwc,
- const struct dwc3_event_depevt *event)
-{
- struct dwc3_request *r = NULL;
- struct usb_request *ur;
- struct dwc3_trb trb;
- struct dwc3_ep *dep;
- u32 transferred;
- u8 epnum;
-
- epnum = event->endpoint_number;
- dep = dwc->eps[epnum];
-
- dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS;
-
- if (!dwc->ep0_status_pending) {
- r = next_request(&dwc->eps[0]->request_list);
- ur = &r->request;
- } else {
- ur = &dwc->ep0_usb_req;
- dwc->ep0_status_pending = 0;
- }
-
- dwc3_trb_to_nat(dwc->ep0_trb, &trb);
-
- if (dwc->ep0_bounced) {
- struct dwc3_ep *ep0 = dwc->eps[0];
-
- transferred = min_t(u32, ur->length,
- ep0->endpoint.maxpacket - trb.length);
- memcpy(ur->buf, dwc->ep0_bounce, transferred);
- dwc->ep0_bounced = false;
- } else {
- transferred = ur->length - trb.length;
- ur->actual += transferred;
- }
-
- if ((epnum & 1) && ur->actual < ur->length) {
- /* for some reason we did not get everything out */
-
- dwc3_ep0_stall_and_restart(dwc);
- } else {
- /*
- * handle the case where we have to send a zero packet. This
- * seems to be case when req.length > maxpacket. Could it be?
- */
- if (r)
- dwc3_gadget_giveback(dep, r, 0);
- }
-}
-
-static void dwc3_ep0_complete_req(struct dwc3 *dwc,
- const struct dwc3_event_depevt *event)
-{
- struct dwc3_request *r;
- struct dwc3_ep *dep;
-
- dep = dwc->eps[0];
-
- if (!list_empty(&dep->request_list)) {
- r = next_request(&dep->request_list);
-
- dwc3_gadget_giveback(dep, r, 0);
- }
-
- dwc->ep0state = EP0_SETUP_PHASE;
- dwc3_ep0_out_start(dwc);
-}
-
-static void dwc3_ep0_xfer_complete(struct dwc3 *dwc,
- const struct dwc3_event_depevt *event)
-{
- struct dwc3_ep *dep = dwc->eps[event->endpoint_number];
-
- dep->flags &= ~DWC3_EP_BUSY;
-
- switch (dwc->ep0state) {
- case EP0_SETUP_PHASE:
- dev_vdbg(dwc->dev, "Inspecting Setup Bytes\n");
- dwc3_ep0_inspect_setup(dwc, event);
- break;
-
- case EP0_DATA_PHASE:
- dev_vdbg(dwc->dev, "Data Phase\n");
- dwc3_ep0_complete_data(dwc, event);
- break;
-
- case EP0_STATUS_PHASE:
- dev_vdbg(dwc->dev, "Status Phase\n");
- dwc3_ep0_complete_req(dwc, event);
- break;
- default:
- WARN(true, "UNKNOWN ep0state %d\n", dwc->ep0state);
- }
-}
-
-static void dwc3_ep0_do_control_setup(struct dwc3 *dwc,
- const struct dwc3_event_depevt *event)
-{
- dwc->ep0state = EP0_SETUP_PHASE;
- dwc3_ep0_out_start(dwc);
-}
-
-static void dwc3_ep0_do_control_data(struct dwc3 *dwc,
- const struct dwc3_event_depevt *event)
-{
- struct dwc3_ep *dep;
- struct dwc3_request *req;
- int ret;
-
- dep = dwc->eps[0];
- dwc->ep0state = EP0_DATA_PHASE;
-
- if (dwc->ep0_status_pending) {
- dwc3_ep0_send_status_response(dwc);
- return;
- }
-
- if (list_empty(&dep->request_list)) {
- dev_vdbg(dwc->dev, "pending request for EP0 Data phase\n");
- dep->flags |= DWC3_EP_PENDING_REQUEST;
-
- if (event->endpoint_number)
- dep->flags |= DWC3_EP0_DIR_IN;
- return;
- }
-
- req = next_request(&dep->request_list);
- req->direction = !!event->endpoint_number;
-
- dwc->ep0state = EP0_DATA_PHASE;
- if (req->request.length == 0) {
- ret = dwc3_ep0_start_trans(dwc, event->endpoint_number,
- dwc->ctrl_req_addr, 0,
- DWC3_TRBCTL_CONTROL_DATA);
- } else if ((req->request.length % dep->endpoint.maxpacket)
- && (event->endpoint_number == 0)) {
- dwc3_map_buffer_to_dma(req);
-
- WARN_ON(req->request.length > dep->endpoint.maxpacket);
-
- dwc->ep0_bounced = true;
-
- /*
- * REVISIT in case request length is bigger than EP0
- * wMaxPacketSize, we will need two chained TRBs to handle
- * the transfer.
- */
- ret = dwc3_ep0_start_trans(dwc, event->endpoint_number,
- dwc->ep0_bounce_addr, dep->endpoint.maxpacket,
- DWC3_TRBCTL_CONTROL_DATA);
- } else {
- dwc3_map_buffer_to_dma(req);
-
- ret = dwc3_ep0_start_trans(dwc, event->endpoint_number,
- req->request.dma, req->request.length,
- DWC3_TRBCTL_CONTROL_DATA);
- }
-
- WARN_ON(ret < 0);
-}
-
-static void dwc3_ep0_do_control_status(struct dwc3 *dwc,
- const struct dwc3_event_depevt *event)
-{
- u32 type;
- int ret;
-
- dwc->ep0state = EP0_STATUS_PHASE;
-
- type = dwc->three_stage_setup ? DWC3_TRBCTL_CONTROL_STATUS3
- : DWC3_TRBCTL_CONTROL_STATUS2;
-
- ret = dwc3_ep0_start_trans(dwc, event->endpoint_number,
- dwc->ctrl_req_addr, 0, type);
-
- WARN_ON(ret < 0);
-}
-
-static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
- const struct dwc3_event_depevt *event)
-{
- switch (event->status) {
- case DEPEVT_STATUS_CONTROL_SETUP:
- dev_vdbg(dwc->dev, "Control Setup\n");
- dwc3_ep0_do_control_setup(dwc, event);
- break;
-
- case DEPEVT_STATUS_CONTROL_DATA:
- dev_vdbg(dwc->dev, "Control Data\n");
-
- if (dwc->ep0_next_event != DWC3_EP0_NRDY_DATA) {
- dev_vdbg(dwc->dev, "Expected %d got %d\n",
- dwc->ep0_next_event,
- DWC3_EP0_NRDY_DATA);
-
- dwc3_ep0_stall_and_restart(dwc);
- return;
- }
-
- /*
- * One of the possible error cases is when Host _does_
- * request for Data Phase, but it does so on the wrong
- * direction.
- *
- * Here, we already know ep0_next_event is DATA (see above),
- * so we only need to check for direction.
- */
- if (dwc->ep0_expect_in != event->endpoint_number) {
- dev_vdbg(dwc->dev, "Wrong direction for Data phase\n");
- dwc3_ep0_stall_and_restart(dwc);
- return;
- }
-
- dwc3_ep0_do_control_data(dwc, event);
- break;
-
- case DEPEVT_STATUS_CONTROL_STATUS:
- dev_vdbg(dwc->dev, "Control Status\n");
-
- if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) {
- dev_vdbg(dwc->dev, "Expected %d got %d\n",
- dwc->ep0_next_event,
- DWC3_EP0_NRDY_STATUS);
-
- dwc3_ep0_stall_and_restart(dwc);
- return;
- }
- dwc3_ep0_do_control_status(dwc, event);
- }
-}
-
-void dwc3_ep0_interrupt(struct dwc3 *dwc,
- const const struct dwc3_event_depevt *event)
-{
- u8 epnum = event->endpoint_number;
-
- dev_dbg(dwc->dev, "%s while ep%d%s in state '%s'\n",
- dwc3_ep_event_string(event->endpoint_event),
- epnum >> 1, (epnum & 1) ? "in" : "out",
- dwc3_ep0_state_string(dwc->ep0state));
-
- switch (event->endpoint_event) {
- case DWC3_DEPEVT_XFERCOMPLETE:
- dwc3_ep0_xfer_complete(dwc, event);
- break;
-
- case DWC3_DEPEVT_XFERNOTREADY:
- dwc3_ep0_xfernotready(dwc, event);
- break;
-
- case DWC3_DEPEVT_XFERINPROGRESS:
- case DWC3_DEPEVT_RXTXFIFOEVT:
- case DWC3_DEPEVT_STREAMEVT:
- case DWC3_DEPEVT_EPCMDCMPLT:
- break;
- }
-}
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
deleted file mode 100644
index fa824cf..0000000
--- a/drivers/usb/dwc3/gadget.c
+++ /dev/null
@@ -1,2104 +0,0 @@
-/**
- * gadget.c - DesignWare USB3 DRD Controller Gadget Framework Link
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * 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") version 2, as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#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 <linux/list.h>
-#include <linux/dma-mapping.h>
-
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-
-#include "core.h"
-#include "gadget.h"
-#include "io.h"
-
-#define DMA_ADDR_INVALID (~(dma_addr_t)0)
-
-void dwc3_map_buffer_to_dma(struct dwc3_request *req)
-{
- struct dwc3 *dwc = req->dep->dwc;
-
- if (req->request.length == 0) {
- /* req->request.dma = dwc->setup_buf_addr; */
- return;
- }
-
- if (req->request.dma == DMA_ADDR_INVALID) {
- req->request.dma = dma_map_single(dwc->dev, req->request.buf,
- req->request.length, req->direction
- ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
- req->mapped = true;
- }
-}
-
-void dwc3_unmap_buffer_from_dma(struct dwc3_request *req)
-{
- struct dwc3 *dwc = req->dep->dwc;
-
- if (req->request.length == 0) {
- req->request.dma = DMA_ADDR_INVALID;
- return;
- }
-
- if (req->mapped) {
- dma_unmap_single(dwc->dev, req->request.dma,
- req->request.length, req->direction
- ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
- req->mapped = 0;
- req->request.dma = DMA_ADDR_INVALID;
- }
-}
-
-void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
- int status)
-{
- struct dwc3 *dwc = dep->dwc;
-
- if (req->queued) {
- 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->desc))
- dep->busy_slot++;
- }
- list_del(&req->list);
-
- if (req->request.status == -EINPROGRESS)
- req->request.status = status;
-
- dwc3_unmap_buffer_from_dma(req);
-
- dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n",
- req, dep->name, req->request.actual,
- req->request.length, status);
-
- spin_unlock(&dwc->lock);
- req->request.complete(&req->dep->endpoint, &req->request);
- spin_lock(&dwc->lock);
-}
-
-static const char *dwc3_gadget_ep_cmd_string(u8 cmd)
-{
- switch (cmd) {
- case DWC3_DEPCMD_DEPSTARTCFG:
- return "Start New Configuration";
- case DWC3_DEPCMD_ENDTRANSFER:
- return "End Transfer";
- case DWC3_DEPCMD_UPDATETRANSFER:
- return "Update Transfer";
- case DWC3_DEPCMD_STARTTRANSFER:
- return "Start Transfer";
- case DWC3_DEPCMD_CLEARSTALL:
- return "Clear Stall";
- case DWC3_DEPCMD_SETSTALL:
- return "Set Stall";
- case DWC3_DEPCMD_GETSEQNUMBER:
- return "Get Data Sequence Number";
- case DWC3_DEPCMD_SETTRANSFRESOURCE:
- return "Set Endpoint Transfer Resource";
- case DWC3_DEPCMD_SETEPCONFIG:
- return "Set Endpoint Configuration";
- default:
- return "UNKNOWN command";
- }
-}
-
-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;
-
- dev_vdbg(dwc->dev, "%s: cmd '%s' params %08x %08x %08x\n",
- dep->name,
- dwc3_gadget_ep_cmd_string(cmd), params->param0,
- params->param1, params->param2);
-
- dwc3_writel(dwc->regs, DWC3_DEPCMDPAR0(ep), params->param0);
- dwc3_writel(dwc->regs, DWC3_DEPCMDPAR1(ep), params->param1);
- dwc3_writel(dwc->regs, DWC3_DEPCMDPAR2(ep), params->param2);
-
- dwc3_writel(dwc->regs, DWC3_DEPCMD(ep), cmd | DWC3_DEPCMD_CMDACT);
- do {
- reg = dwc3_readl(dwc->regs, DWC3_DEPCMD(ep));
- if (!(reg & DWC3_DEPCMD_CMDACT)) {
- dev_vdbg(dwc->dev, "Command Complete --> %d\n",
- DWC3_DEPCMD_STATUS(reg));
- return 0;
- }
-
- /*
- * We can't sleep here, because it is also called from
- * interrupt context.
- */
- timeout--;
- if (!timeout)
- return -ETIMEDOUT;
-
- udelay(1);
- } while (1);
-}
-
-static dma_addr_t dwc3_trb_dma_offset(struct dwc3_ep *dep,
- struct dwc3_trb_hw *trb)
-{
- u32 offset = (char *) trb - (char *) dep->trb_pool;
-
- return dep->trb_pool_dma + offset;
-}
-
-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);
- if (!dep->trb_pool) {
- dev_err(dep->dwc->dev, "failed to allocate trb pool for %s\n",
- dep->name);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-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);
-
- dep->trb_pool = NULL;
- dep->trb_pool_dma = 0;
-}
-
-static int dwc3_gadget_start_config(struct dwc3 *dwc, struct dwc3_ep *dep)
-{
- struct dwc3_gadget_ep_cmd_params params;
- u32 cmd;
-
- memset(¶ms, 0x00, sizeof(params));
-
- if (dep->number != 1) {
- cmd = DWC3_DEPCMD_DEPSTARTCFG;
- /* XferRscIdx == 0 for ep0 and 2 for the remaining */
- if (dep->number > 1) {
- if (dwc->start_config_issued)
- return 0;
- dwc->start_config_issued = true;
- cmd |= DWC3_DEPCMD_PARAM(2);
- }
-
- return dwc3_send_gadget_ep_cmd(dwc, 0, cmd, ¶ms);
- }
-
- return 0;
-}
-
-static int dwc3_gadget_set_ep_config(struct dwc3 *dwc, struct dwc3_ep *dep,
- const struct usb_endpoint_descriptor *desc)
-{
- struct dwc3_gadget_ep_cmd_params params;
-
- memset(¶ms, 0x00, sizeof(params));
-
- params.param0 = DWC3_DEPCFG_EP_TYPE(usb_endpoint_type(desc))
- | DWC3_DEPCFG_MAX_PACKET_SIZE(usb_endpoint_maxp(desc))
- | DWC3_DEPCFG_BURST_SIZE(dep->endpoint.maxburst);
-
- params.param1 = DWC3_DEPCFG_XFER_COMPLETE_EN
- | DWC3_DEPCFG_XFER_NOT_READY_EN;
-
- if (usb_endpoint_xfer_bulk(desc) && dep->endpoint.max_streams) {
- params.param1 |= DWC3_DEPCFG_STREAM_CAPABLE
- | DWC3_DEPCFG_STREAM_EVENT_EN;
- dep->stream_capable = true;
- }
-
- if (usb_endpoint_xfer_isoc(desc))
- params.param1 |= DWC3_DEPCFG_XFER_IN_PROGRESS_EN;
-
- /*
- * We are doing 1:1 mapping for endpoints, meaning
- * Physical Endpoints 2 maps to Logical Endpoint 2 and
- * so on. We consider the direction bit as part of the physical
- * endpoint number. So USB endpoint 0x81 is 0x03.
- */
- params.param1 |= DWC3_DEPCFG_EP_NUMBER(dep->number);
-
- /*
- * We must use the lower 16 TX FIFOs even though
- * HW might have more
- */
- if (dep->direction)
- params.param0 |= DWC3_DEPCFG_FIFO_NUMBER(dep->number >> 1);
-
- if (desc->bInterval) {
- params.param1 |= DWC3_DEPCFG_BINTERVAL_M1(desc->bInterval - 1);
- dep->interval = 1 << (desc->bInterval - 1);
- }
-
- return dwc3_send_gadget_ep_cmd(dwc, dep->number,
- DWC3_DEPCMD_SETEPCONFIG, ¶ms);
-}
-
-static int dwc3_gadget_set_xfer_resource(struct dwc3 *dwc, struct dwc3_ep *dep)
-{
- struct dwc3_gadget_ep_cmd_params params;
-
- memset(¶ms, 0x00, sizeof(params));
-
- params.param0 = DWC3_DEPXFERCFG_NUM_XFER_RES(1);
-
- return dwc3_send_gadget_ep_cmd(dwc, dep->number,
- DWC3_DEPCMD_SETTRANSFRESOURCE, ¶ms);
-}
-
-/**
- * __dwc3_gadget_ep_enable - Initializes a HW endpoint
- * @dep: endpoint to be initialized
- * @desc: USB Endpoint Descriptor
- *
- * Caller should take care of locking
- */
-static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
- const struct usb_endpoint_descriptor *desc)
-{
- struct dwc3 *dwc = dep->dwc;
- u32 reg;
- int ret = -ENOMEM;
-
- if (!(dep->flags & DWC3_EP_ENABLED)) {
- ret = dwc3_gadget_start_config(dwc, dep);
- if (ret)
- return ret;
- }
-
- ret = dwc3_gadget_set_ep_config(dwc, dep, desc);
- if (ret)
- return ret;
-
- if (!(dep->flags & DWC3_EP_ENABLED)) {
- struct dwc3_trb_hw *trb_st_hw;
- struct dwc3_trb_hw *trb_link_hw;
- struct dwc3_trb trb_link;
-
- ret = dwc3_gadget_set_xfer_resource(dwc, dep);
- if (ret)
- return ret;
-
- dep->desc = desc;
- dep->type = usb_endpoint_type(desc);
- dep->flags |= DWC3_EP_ENABLED;
-
- reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
- reg |= DWC3_DALEPENA_EP(dep->number);
- dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
-
- if (!usb_endpoint_xfer_isoc(desc))
- return 0;
-
- memset(&trb_link, 0, sizeof(trb_link));
-
- /* Link TRB for ISOC. The HWO but is never reset */
- trb_st_hw = &dep->trb_pool[0];
-
- trb_link.bplh = dwc3_trb_dma_offset(dep, trb_st_hw);
- trb_link.trbctl = DWC3_TRBCTL_LINK_TRB;
- trb_link.hwo = true;
-
- trb_link_hw = &dep->trb_pool[DWC3_TRB_NUM - 1];
- dwc3_trb_to_hw(&trb_link, trb_link_hw);
- }
-
- return 0;
-}
-
-static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum);
-static void dwc3_remove_requests(struct dwc3 *dwc, struct dwc3_ep *dep)
-{
- struct dwc3_request *req;
-
- if (!list_empty(&dep->req_queued))
- dwc3_stop_active_transfer(dwc, dep->number);
-
- while (!list_empty(&dep->request_list)) {
- req = next_request(&dep->request_list);
-
- dwc3_gadget_giveback(dep, req, -ESHUTDOWN);
- }
-}
-
-/**
- * __dwc3_gadget_ep_disable - Disables a HW endpoint
- * @dep: the endpoint to disable
- *
- * This function also removes requests which are currently processed ny the
- * hardware and those which are not yet scheduled.
- * Caller should take care of locking.
- */
-static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
-{
- struct dwc3 *dwc = dep->dwc;
- u32 reg;
-
- dwc3_remove_requests(dwc, dep);
-
- reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
- reg &= ~DWC3_DALEPENA_EP(dep->number);
- dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
-
- dep->stream_capable = false;
- dep->desc = NULL;
- dep->type = 0;
- dep->flags = 0;
-
- return 0;
-}
-
-/* -------------------------------------------------------------------------- */
-
-static int dwc3_gadget_ep0_enable(struct usb_ep *ep,
- const struct usb_endpoint_descriptor *desc)
-{
- return -EINVAL;
-}
-
-static int dwc3_gadget_ep0_disable(struct usb_ep *ep)
-{
- return -EINVAL;
-}
-
-/* -------------------------------------------------------------------------- */
-
-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;
-
- if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) {
- pr_debug("dwc3: invalid parameters\n");
- return -EINVAL;
- }
-
- if (!desc->wMaxPacketSize) {
- pr_debug("dwc3: missing wMaxPacketSize\n");
- return -EINVAL;
- }
-
- dep = to_dwc3_ep(ep);
- dwc = dep->dwc;
-
- switch (usb_endpoint_type(desc)) {
- case USB_ENDPOINT_XFER_CONTROL:
- strncat(dep->name, "-control", sizeof(dep->name));
- break;
- case USB_ENDPOINT_XFER_ISOC:
- strncat(dep->name, "-isoc", sizeof(dep->name));
- break;
- case USB_ENDPOINT_XFER_BULK:
- strncat(dep->name, "-bulk", sizeof(dep->name));
- break;
- case USB_ENDPOINT_XFER_INT:
- strncat(dep->name, "-int", sizeof(dep->name));
- break;
- default:
- dev_err(dwc->dev, "invalid endpoint transfer type\n");
- }
-
- if (dep->flags & DWC3_EP_ENABLED) {
- dev_WARN_ONCE(dwc->dev, true, "%s is already enabled\n",
- dep->name);
- return 0;
- }
-
- dev_vdbg(dwc->dev, "Enabling %s\n", dep->name);
-
- spin_lock_irqsave(&dwc->lock, flags);
- ret = __dwc3_gadget_ep_enable(dep, desc);
- spin_unlock_irqrestore(&dwc->lock, flags);
-
- return ret;
-}
-
-static int dwc3_gadget_ep_disable(struct usb_ep *ep)
-{
- struct dwc3_ep *dep;
- struct dwc3 *dwc;
- unsigned long flags;
- int ret;
-
- if (!ep) {
- pr_debug("dwc3: invalid parameters\n");
- return -EINVAL;
- }
-
- 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",
- dep->name);
- return 0;
- }
-
- snprintf(dep->name, sizeof(dep->name), "ep%d%s",
- dep->number >> 1,
- (dep->number & 1) ? "in" : "out");
-
- spin_lock_irqsave(&dwc->lock, flags);
- ret = __dwc3_gadget_ep_disable(dep);
- spin_unlock_irqrestore(&dwc->lock, flags);
-
- return ret;
-}
-
-static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep,
- gfp_t gfp_flags)
-{
- struct dwc3_request *req;
- struct dwc3_ep *dep = to_dwc3_ep(ep);
- struct dwc3 *dwc = dep->dwc;
-
- req = kzalloc(sizeof(*req), gfp_flags);
- if (!req) {
- dev_err(dwc->dev, "not enough memory\n");
- return NULL;
- }
-
- req->epnum = dep->number;
- req->dep = dep;
- req->request.dma = DMA_ADDR_INVALID;
-
- return &req->request;
-}
-
-static void dwc3_gadget_ep_free_request(struct usb_ep *ep,
- struct usb_request *request)
-{
- struct dwc3_request *req = to_dwc3_request(request);
-
- kfree(req);
-}
-
-/*
- * dwc3_prepare_trbs - setup TRBs from requests
- * @dep: endpoint for which requests are being prepared
- * @starting: true if the endpoint is idle and no requests are queued.
- *
- * The functions goes through the requests list and setups TRBs for the
- * transfers. The functions returns once there are not more TRBs available or
- * it run out of requests.
- */
-static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep,
- bool starting)
-{
- struct dwc3_request *req, *n, *ret = NULL;
- struct dwc3_trb_hw *trb_hw;
- struct dwc3_trb trb;
- u32 trbs_left;
-
- BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);
-
- /* the first request must not be queued */
- trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK;
- /*
- * if busy & slot are equal than it is either full or empty. If we are
- * starting to proceed requests then we are empty. Otherwise we ar
- * full and don't do anything
- */
- if (!trbs_left) {
- if (!starting)
- return NULL;
- trbs_left = DWC3_TRB_NUM;
- /*
- * In case we start from scratch, we queue the ISOC requests
- * starting from slot 1. This is done because we use ring
- * buffer and have no LST bit to stop us. Instead, we place
- * IOC bit TRB_NUM/4. We try to avoid to having an interrupt
- * after the first request so we start at slot 1 and have
- * 7 requests proceed before we hit the first IOC.
- * Other transfer types don't use the ring buffer and are
- * processed from the first TRB until the last one. Since we
- * don't wrap around we have to start at the beginning.
- */
- if (usb_endpoint_xfer_isoc(dep->desc)) {
- dep->busy_slot = 1;
- dep->free_slot = 1;
- } else {
- dep->busy_slot = 0;
- dep->free_slot = 0;
- }
- }
-
- /* The last TRB is a link TRB, not used for xfer */
- if ((trbs_left <= 1) && usb_endpoint_xfer_isoc(dep->desc))
- return NULL;
-
- list_for_each_entry_safe(req, n, &dep->request_list, list) {
- unsigned int last_one = 0;
- unsigned int cur_slot;
-
- trb_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
- cur_slot = dep->free_slot;
- dep->free_slot++;
-
- /* Skip the LINK-TRB on ISOC */
- if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
- usb_endpoint_xfer_isoc(dep->desc))
- continue;
-
- dwc3_gadget_move_request_queued(req);
- memset(&trb, 0, sizeof(trb));
- trbs_left--;
-
- /* Is our TRB pool empty? */
- if (!trbs_left)
- last_one = 1;
- /* Is this the last request? */
- if (list_empty(&dep->request_list))
- last_one = 1;
-
- /*
- * FIXME we shouldn't need to set LST bit always but we are
- * facing some weird problem with the Hardware where it doesn't
- * complete even though it has been previously started.
- *
- * While we're debugging the problem, as a workaround to
- * multiple TRBs handling, use only one TRB at a time.
- */
- last_one = 1;
-
- req->trb = trb_hw;
- if (!ret)
- ret = req;
-
- trb.bplh = req->request.dma;
-
- if (usb_endpoint_xfer_isoc(dep->desc)) {
- trb.isp_imi = true;
- trb.csp = true;
- } else {
- trb.lst = last_one;
- }
-
- if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable)
- trb.sid_sofn = req->request.stream_id;
-
- switch (usb_endpoint_type(dep->desc)) {
- case USB_ENDPOINT_XFER_CONTROL:
- trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP;
- break;
-
- case USB_ENDPOINT_XFER_ISOC:
- trb.trbctl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
-
- /* IOC every DWC3_TRB_NUM / 4 so we can refill */
- if (!(cur_slot % (DWC3_TRB_NUM / 4)))
- trb.ioc = last_one;
- break;
-
- case USB_ENDPOINT_XFER_BULK:
- case USB_ENDPOINT_XFER_INT:
- trb.trbctl = DWC3_TRBCTL_NORMAL;
- break;
- default:
- /*
- * This is only possible with faulty memory because we
- * checked it already :)
- */
- BUG();
- }
-
- trb.length = req->request.length;
- trb.hwo = true;
-
- dwc3_trb_to_hw(&trb, trb_hw);
- req->trb_dma = dwc3_trb_dma_offset(dep, trb_hw);
-
- if (last_one)
- break;
- }
-
- return ret;
-}
-
-static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
- int start_new)
-{
- struct dwc3_gadget_ep_cmd_params params;
- struct dwc3_request *req;
- struct dwc3 *dwc = dep->dwc;
- int ret;
- u32 cmd;
-
- if (start_new && (dep->flags & DWC3_EP_BUSY)) {
- dev_vdbg(dwc->dev, "%s: endpoint busy\n", dep->name);
- return -EBUSY;
- }
- dep->flags &= ~DWC3_EP_PENDING_REQUEST;
-
- /*
- * If we are getting here after a short-out-packet we don't enqueue any
- * new requests as we try to set the IOC bit only on the last request.
- */
- if (start_new) {
- if (list_empty(&dep->req_queued))
- dwc3_prepare_trbs(dep, start_new);
-
- /* req points to the first request which will be sent */
- req = next_request(&dep->req_queued);
- } else {
- /*
- * req points to the first request where HWO changed
- * from 0 to 1
- */
- req = dwc3_prepare_trbs(dep, start_new);
- }
- if (!req) {
- dep->flags |= DWC3_EP_PENDING_REQUEST;
- return 0;
- }
-
- memset(¶ms, 0, sizeof(params));
- params.param0 = upper_32_bits(req->trb_dma);
- params.param1 = lower_32_bits(req->trb_dma);
-
- if (start_new)
- cmd = DWC3_DEPCMD_STARTTRANSFER;
- else
- cmd = DWC3_DEPCMD_UPDATETRANSFER;
-
- cmd |= DWC3_DEPCMD_PARAM(cmd_param);
- ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms);
- if (ret < 0) {
- dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n");
-
- /*
- * FIXME we need to iterate over the list of requests
- * here and stop, unmap, free and del each of the linked
- * requests instead of we do now.
- */
- dwc3_unmap_buffer_from_dma(req);
- list_del(&req->list);
- return ret;
- }
-
- dep->flags |= DWC3_EP_BUSY;
- dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc,
- dep->number);
- if (!dep->res_trans_idx)
- printk_once(KERN_ERR "%s() res_trans_idx is invalid\n", __func__);
- return 0;
-}
-
-static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
-{
- req->request.actual = 0;
- req->request.status = -EINPROGRESS;
- req->direction = dep->direction;
- req->epnum = dep->number;
-
- /*
- * We only add to our list of requests now and
- * start consuming the list once we get XferNotReady
- * IRQ.
- *
- * That way, we avoid doing anything that we don't need
- * to do now and defer it until the point we receive a
- * particular token from the Host side.
- *
- * This will also avoid Host cancelling URBs due to too
- * many NACKs.
- */
- dwc3_map_buffer_to_dma(req);
- list_add_tail(&req->list, &dep->request_list);
-
- /*
- * There is one special case: XferNotReady with
- * empty list of requests. We need to kick the
- * transfer here in that situation, otherwise
- * we will be NAKing forever.
- *
- * If we get XferNotReady before gadget driver
- * has a chance to queue a request, we will ACK
- * the IRQ but won't be able to receive the data
- * until the next request is queued. The following
- * code is handling exactly that.
- */
- if (dep->flags & DWC3_EP_PENDING_REQUEST) {
- int ret;
- int start_trans;
-
- start_trans = 1;
- if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
- dep->flags & DWC3_EP_BUSY)
- start_trans = 0;
-
- ret = __dwc3_gadget_kick_transfer(dep, 0, start_trans);
- if (ret && ret != -EBUSY) {
- struct dwc3 *dwc = dep->dwc;
-
- dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
- dep->name);
- }
- };
-
- return 0;
-}
-
-static int dwc3_gadget_ep_queue(struct usb_ep *ep, struct usb_request *request,
- gfp_t gfp_flags)
-{
- struct dwc3_request *req = to_dwc3_request(request);
- struct dwc3_ep *dep = to_dwc3_ep(ep);
- struct dwc3 *dwc = dep->dwc;
-
- unsigned long flags;
-
- int ret;
-
- if (!dep->desc) {
- dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",
- request, ep->name);
- return -ESHUTDOWN;
- }
-
- dev_vdbg(dwc->dev, "queing request %p to %s length %d\n",
- request, ep->name, request->length);
-
- spin_lock_irqsave(&dwc->lock, flags);
- ret = __dwc3_gadget_ep_queue(dep, req);
- spin_unlock_irqrestore(&dwc->lock, flags);
-
- return ret;
-}
-
-static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
- struct usb_request *request)
-{
- struct dwc3_request *req = to_dwc3_request(request);
- struct dwc3_request *r = NULL;
-
- struct dwc3_ep *dep = to_dwc3_ep(ep);
- struct dwc3 *dwc = dep->dwc;
-
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&dwc->lock, flags);
-
- list_for_each_entry(r, &dep->request_list, list) {
- if (r == req)
- break;
- }
-
- if (r != req) {
- list_for_each_entry(r, &dep->req_queued, list) {
- if (r == req)
- break;
- }
- if (r == req) {
- /* wait until it is processed */
- dwc3_stop_active_transfer(dwc, dep->number);
- goto out0;
- }
- dev_err(dwc->dev, "request %p was not queued to %s\n",
- request, ep->name);
- ret = -EINVAL;
- goto out0;
- }
-
- /* giveback the request */
- dwc3_gadget_giveback(dep, req, -ECONNRESET);
-
-out0:
- spin_unlock_irqrestore(&dwc->lock, flags);
-
- return ret;
-}
-
-int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value)
-{
- struct dwc3_gadget_ep_cmd_params params;
- struct dwc3 *dwc = dep->dwc;
- int ret;
-
- memset(¶ms, 0x00, sizeof(params));
-
- if (value) {
- if (dep->number == 0 || dep->number == 1) {
- /*
- * Whenever EP0 is stalled, we will restart
- * the state machine, thus moving back to
- * Setup Phase
- */
- dwc->ep0state = EP0_SETUP_PHASE;
- }
-
- ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
- DWC3_DEPCMD_SETSTALL, ¶ms);
- if (ret)
- dev_err(dwc->dev, "failed to %s STALL on %s\n",
- value ? "set" : "clear",
- dep->name);
- else
- dep->flags |= DWC3_EP_STALL;
- } else {
- if (dep->flags & DWC3_EP_WEDGE)
- return 0;
-
- ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
- DWC3_DEPCMD_CLEARSTALL, ¶ms);
- if (ret)
- dev_err(dwc->dev, "failed to %s STALL on %s\n",
- value ? "set" : "clear",
- dep->name);
- else
- dep->flags &= ~DWC3_EP_STALL;
- }
-
- return ret;
-}
-
-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;
-
- int ret;
-
- spin_lock_irqsave(&dwc->lock, flags);
-
- if (usb_endpoint_xfer_isoc(dep->desc)) {
- dev_err(dwc->dev, "%s is of Isochronous type\n", dep->name);
- ret = -EINVAL;
- goto out;
- }
-
- ret = __dwc3_gadget_ep_set_halt(dep, value);
-out:
- spin_unlock_irqrestore(&dwc->lock, flags);
-
- return ret;
-}
-
-static int dwc3_gadget_ep_set_wedge(struct usb_ep *ep)
-{
- struct dwc3_ep *dep = to_dwc3_ep(ep);
-
- dep->flags |= DWC3_EP_WEDGE;
-
- return dwc3_gadget_ep_set_halt(ep, 1);
-}
-
-/* -------------------------------------------------------------------------- */
-
-static struct usb_endpoint_descriptor dwc3_gadget_ep0_desc = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
-};
-
-static const struct usb_ep_ops dwc3_gadget_ep0_ops = {
- .enable = dwc3_gadget_ep0_enable,
- .disable = dwc3_gadget_ep0_disable,
- .alloc_request = dwc3_gadget_ep_alloc_request,
- .free_request = dwc3_gadget_ep_free_request,
- .queue = dwc3_gadget_ep0_queue,
- .dequeue = dwc3_gadget_ep_dequeue,
- .set_halt = dwc3_gadget_ep_set_halt,
- .set_wedge = dwc3_gadget_ep_set_wedge,
-};
-
-static const struct usb_ep_ops dwc3_gadget_ep_ops = {
- .enable = dwc3_gadget_ep_enable,
- .disable = dwc3_gadget_ep_disable,
- .alloc_request = dwc3_gadget_ep_alloc_request,
- .free_request = dwc3_gadget_ep_free_request,
- .queue = dwc3_gadget_ep_queue,
- .dequeue = dwc3_gadget_ep_dequeue,
- .set_halt = dwc3_gadget_ep_set_halt,
- .set_wedge = dwc3_gadget_ep_set_wedge,
-};
-
-/* -------------------------------------------------------------------------- */
-
-static int dwc3_gadget_get_frame(struct usb_gadget *g)
-{
- struct dwc3 *dwc = gadget_to_dwc(g);
- u32 reg;
-
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
- return DWC3_DSTS_SOFFN(reg);
-}
-
-static int dwc3_gadget_wakeup(struct usb_gadget *g)
-{
- struct dwc3 *dwc = gadget_to_dwc(g);
-
- unsigned long timeout;
- unsigned long flags;
-
- u32 reg;
-
- int ret = 0;
-
- u8 link_state;
- u8 speed;
-
- spin_lock_irqsave(&dwc->lock, flags);
-
- /*
- * According to the Databook Remote wakeup request should
- * be issued only when the device is in early suspend state.
- *
- * We can check that via USB Link State bits in DSTS register.
- */
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
-
- speed = reg & DWC3_DSTS_CONNECTSPD;
- if (speed == DWC3_DSTS_SUPERSPEED) {
- dev_dbg(dwc->dev, "no wakeup on SuperSpeed\n");
- ret = -EINVAL;
- goto out;
- }
-
- link_state = DWC3_DSTS_USBLNKST(reg);
-
- switch (link_state) {
- case DWC3_LINK_STATE_RX_DET: /* in HS, means Early Suspend */
- case DWC3_LINK_STATE_U3: /* in HS, means SUSPEND */
- break;
- default:
- dev_dbg(dwc->dev, "can't wakeup from link state %d\n",
- link_state);
- ret = -EINVAL;
- goto out;
- }
-
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
-
- /*
- * Switch link state to Recovery. In HS/FS/LS this means
- * RemoteWakeup Request
- */
- reg |= DWC3_DCTL_ULSTCHNG_RECOVERY;
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
-
- /* wait for at least 2000us */
- usleep_range(2000, 2500);
-
- /* write zeroes to Link Change Request */
- reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
-
- /* pool until Link State change to ON */
- timeout = jiffies + msecs_to_jiffies(100);
-
- while (!(time_after(jiffies, timeout))) {
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
-
- /* in HS, means ON */
- if (DWC3_DSTS_USBLNKST(reg) == DWC3_LINK_STATE_U0)
- break;
- }
-
- if (DWC3_DSTS_USBLNKST(reg) != DWC3_LINK_STATE_U0) {
- dev_err(dwc->dev, "failed to send remote wakeup\n");
- ret = -EINVAL;
- }
-
-out:
- spin_unlock_irqrestore(&dwc->lock, flags);
-
- return ret;
-}
-
-static int dwc3_gadget_set_selfpowered(struct usb_gadget *g,
- int is_selfpowered)
-{
- struct dwc3 *dwc = gadget_to_dwc(g);
-
- dwc->is_selfpowered = !!is_selfpowered;
-
- return 0;
-}
-
-static void dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on)
-{
- u32 reg;
- u32 timeout = 500;
-
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
- if (is_on)
- reg |= DWC3_DCTL_RUN_STOP;
- else
- reg &= ~DWC3_DCTL_RUN_STOP;
-
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
-
- do {
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
- if (is_on) {
- if (!(reg & DWC3_DSTS_DEVCTRLHLT))
- break;
- } else {
- if (reg & DWC3_DSTS_DEVCTRLHLT)
- break;
- }
- timeout--;
- if (!timeout)
- break;
- udelay(1);
- } while (1);
-
- dev_vdbg(dwc->dev, "gadget %s data soft-%s\n",
- dwc->gadget_driver
- ? dwc->gadget_driver->function : "no-function",
- is_on ? "connect" : "disconnect");
-}
-
-static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
-{
- struct dwc3 *dwc = gadget_to_dwc(g);
- unsigned long flags;
-
- is_on = !!is_on;
-
- spin_lock_irqsave(&dwc->lock, flags);
- dwc3_gadget_run_stop(dwc, is_on);
- spin_unlock_irqrestore(&dwc->lock, flags);
-
- return 0;
-}
-
-static int dwc3_gadget_start(struct usb_gadget *g,
- struct usb_gadget_driver *driver)
-{
- struct dwc3 *dwc = gadget_to_dwc(g);
- struct dwc3_ep *dep;
- unsigned long flags;
- int ret = 0;
- u32 reg;
-
- 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);
- ret = -EBUSY;
- goto err0;
- }
-
- dwc->gadget_driver = driver;
- dwc->gadget.dev.driver = &driver->driver;
-
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
-
- reg &= ~DWC3_GCTL_SCALEDOWN(3);
- reg &= ~DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG);
- reg &= ~DWC3_GCTL_DISSCRAMBLE;
- reg |= DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_DEVICE);
-
- switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams0)) {
- case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
- reg &= ~DWC3_GCTL_DSBLCLKGTNG;
- break;
- default:
- dev_dbg(dwc->dev, "No power optimization available\n");
- }
-
- /*
- * WORKAROUND: DWC3 revisions <1.90a have a bug
- * when The device fails to connect at SuperSpeed
- * and falls back to high-speed mode which causes
- * the device to enter in a Connect/Disconnect loop
- */
- if (dwc->revision < DWC3_REVISION_190A)
- reg |= DWC3_GCTL_U2RSTECN;
-
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
-
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
- reg &= ~(DWC3_DCFG_SPEED_MASK);
- reg |= DWC3_DCFG_SUPERSPEED;
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
-
- dwc->start_config_issued = false;
-
- /* Start with SuperSpeed Default */
- dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
-
- dep = dwc->eps[0];
- ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc);
- if (ret) {
- dev_err(dwc->dev, "failed to enable %s\n", dep->name);
- goto err0;
- }
-
- dep = dwc->eps[1];
- ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc);
- if (ret) {
- dev_err(dwc->dev, "failed to enable %s\n", dep->name);
- goto err1;
- }
-
- /* begin to receive SETUP packets */
- dwc->ep0state = EP0_SETUP_PHASE;
- dwc3_ep0_out_start(dwc);
-
- spin_unlock_irqrestore(&dwc->lock, flags);
-
- return 0;
-
-err1:
- __dwc3_gadget_ep_disable(dwc->eps[0]);
-
-err0:
- spin_unlock_irqrestore(&dwc->lock, flags);
-
- return ret;
-}
-
-static int dwc3_gadget_stop(struct usb_gadget *g,
- struct usb_gadget_driver *driver)
-{
- struct dwc3 *dwc = gadget_to_dwc(g);
- unsigned long flags;
-
- spin_lock_irqsave(&dwc->lock, flags);
-
- __dwc3_gadget_ep_disable(dwc->eps[0]);
- __dwc3_gadget_ep_disable(dwc->eps[1]);
-
- dwc->gadget_driver = NULL;
- dwc->gadget.dev.driver = NULL;
-
- spin_unlock_irqrestore(&dwc->lock, flags);
-
- return 0;
-}
-static const struct usb_gadget_ops dwc3_gadget_ops = {
- .get_frame = dwc3_gadget_get_frame,
- .wakeup = dwc3_gadget_wakeup,
- .set_selfpowered = dwc3_gadget_set_selfpowered,
- .pullup = dwc3_gadget_pullup,
- .udc_start = dwc3_gadget_start,
- .udc_stop = dwc3_gadget_stop,
-};
-
-/* -------------------------------------------------------------------------- */
-
-static int __devinit dwc3_gadget_init_endpoints(struct dwc3 *dwc)
-{
- struct dwc3_ep *dep;
- u8 epnum;
-
- INIT_LIST_HEAD(&dwc->gadget.ep_list);
-
- for (epnum = 0; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
- dep = kzalloc(sizeof(*dep), GFP_KERNEL);
- if (!dep) {
- dev_err(dwc->dev, "can't allocate endpoint %d\n",
- epnum);
- return -ENOMEM;
- }
-
- dep->dwc = dwc;
- dep->number = epnum;
- dwc->eps[epnum] = dep;
-
- snprintf(dep->name, sizeof(dep->name), "ep%d%s", epnum >> 1,
- (epnum & 1) ? "in" : "out");
- dep->endpoint.name = dep->name;
- dep->direction = (epnum & 1);
-
- if (epnum == 0 || epnum == 1) {
- dep->endpoint.maxpacket = 512;
- dep->endpoint.ops = &dwc3_gadget_ep0_ops;
- if (!epnum)
- dwc->gadget.ep0 = &dep->endpoint;
- } else {
- int ret;
-
- dep->endpoint.maxpacket = 1024;
- dep->endpoint.ops = &dwc3_gadget_ep_ops;
- list_add_tail(&dep->endpoint.ep_list,
- &dwc->gadget.ep_list);
-
- ret = dwc3_alloc_trb_pool(dep);
- if (ret) {
- dev_err(dwc->dev, "%s: failed to allocate TRB pool\n", dep->name);
- return ret;
- }
- }
- INIT_LIST_HEAD(&dep->request_list);
- INIT_LIST_HEAD(&dep->req_queued);
- }
-
- return 0;
-}
-
-static void dwc3_gadget_free_endpoints(struct dwc3 *dwc)
-{
- struct dwc3_ep *dep;
- u8 epnum;
-
- for (epnum = 0; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
- dep = dwc->eps[epnum];
- dwc3_free_trb_pool(dep);
-
- if (epnum != 0 && epnum != 1)
- list_del(&dep->endpoint.ep_list);
-
- kfree(dep);
- }
-}
-
-static void dwc3_gadget_release(struct device *dev)
-{
- dev_dbg(dev, "%s\n", __func__);
-}
-
-/* -------------------------------------------------------------------------- */
-static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
- const struct dwc3_event_depevt *event, int status)
-{
- struct dwc3_request *req;
- struct dwc3_trb trb;
- unsigned int count;
- unsigned int s_pkt = 0;
-
- do {
- req = next_request(&dep->req_queued);
- if (!req)
- break;
-
- dwc3_trb_to_nat(req->trb, &trb);
-
- if (trb.hwo && status != -ESHUTDOWN)
- /*
- * We continue despite the error. There is not much we
- * can do. If we don't clean in up we loop for ever. If
- * we skip the TRB than it gets overwritten reused after
- * a while since we use them in a ring buffer. a BUG()
- * would help. Lets hope that if this occures, someone
- * fixes the root cause instead of looking away :)
- */
- dev_err(dwc->dev, "%s's TRB (%p) still owned by HW\n",
- dep->name, req->trb);
- count = trb.length;
-
- if (dep->direction) {
- if (count) {
- dev_err(dwc->dev, "incomplete IN transfer %s\n",
- dep->name);
- status = -ECONNRESET;
- }
- } else {
- if (count && (event->status & DEPEVT_STATUS_SHORT))
- s_pkt = 1;
- }
-
- /*
- * We assume here we will always receive the entire data block
- * which we should receive. Meaning, if we program RX to
- * receive 4K but we receive only 2K, we assume that's all we
- * should receive and we simply bounce the request back to the
- * gadget driver for further processing.
- */
- req->request.actual += req->request.length - count;
- dwc3_gadget_giveback(dep, req, status);
- if (s_pkt)
- break;
- if ((event->status & DEPEVT_STATUS_LST) && trb.lst)
- break;
- if ((event->status & DEPEVT_STATUS_IOC) && trb.ioc)
- break;
- } while (1);
-
- if ((event->status & DEPEVT_STATUS_IOC) && trb.ioc)
- return 0;
- return 1;
-}
-
-static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc,
- struct dwc3_ep *dep, const struct dwc3_event_depevt *event,
- int start_new)
-{
- unsigned status = 0;
- int clean_busy;
-
- if (event->status & DEPEVT_STATUS_BUSERR)
- status = -ECONNRESET;
-
- clean_busy = dwc3_cleanup_done_reqs(dwc, dep, event, status);
- if (clean_busy) {
- dep->flags &= ~DWC3_EP_BUSY;
- dep->res_trans_idx = 0;
- }
-}
-
-static void dwc3_gadget_start_isoc(struct dwc3 *dwc,
- struct dwc3_ep *dep, const struct dwc3_event_depevt *event)
-{
- u32 uf;
-
- if (list_empty(&dep->request_list)) {
- dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n",
- dep->name);
- return;
- }
-
- if (event->parameters) {
- u32 mask;
-
- mask = ~(dep->interval - 1);
- uf = event->parameters & mask;
- /* 4 micro frames in the future */
- uf += dep->interval * 4;
- } else {
- uf = 0;
- }
-
- __dwc3_gadget_kick_transfer(dep, uf, 1);
-}
-
-static void dwc3_process_ep_cmd_complete(struct dwc3_ep *dep,
- const struct dwc3_event_depevt *event)
-{
- struct dwc3 *dwc = dep->dwc;
- struct dwc3_event_depevt mod_ev = *event;
-
- /*
- * We were asked to remove one requests. It is possible that this
- * request and a few other were started together and have the same
- * transfer index. Since we stopped the complete endpoint we don't
- * know how many requests were already completed (and not yet)
- * reported and how could be done (later). We purge them all until
- * the end of the list.
- */
- mod_ev.status = DEPEVT_STATUS_LST;
- dwc3_cleanup_done_reqs(dwc, dep, &mod_ev, -ESHUTDOWN);
- dep->flags &= ~DWC3_EP_BUSY;
- /* pending requets are ignored and are queued on XferNotReady */
-}
-
-static void dwc3_ep_cmd_compl(struct dwc3_ep *dep,
- const struct dwc3_event_depevt *event)
-{
- u32 param = event->parameters;
- u32 cmd_type = (param >> 8) & ((1 << 5) - 1);
-
- switch (cmd_type) {
- case DWC3_DEPCMD_ENDTRANSFER:
- dwc3_process_ep_cmd_complete(dep, event);
- break;
- case DWC3_DEPCMD_STARTTRANSFER:
- dep->res_trans_idx = param & 0x7f;
- break;
- default:
- printk(KERN_ERR "%s() unknown /unexpected type: %d\n",
- __func__, cmd_type);
- break;
- };
-}
-
-static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
- const struct dwc3_event_depevt *event)
-{
- struct dwc3_ep *dep;
- u8 epnum = event->endpoint_number;
-
- dep = dwc->eps[epnum];
-
- dev_vdbg(dwc->dev, "%s: %s\n", dep->name,
- dwc3_ep_event_string(event->endpoint_event));
-
- if (epnum == 0 || epnum == 1) {
- dwc3_ep0_interrupt(dwc, event);
- return;
- }
-
- switch (event->endpoint_event) {
- case DWC3_DEPEVT_XFERCOMPLETE:
- if (usb_endpoint_xfer_isoc(dep->desc)) {
- dev_dbg(dwc->dev, "%s is an Isochronous endpoint\n",
- dep->name);
- return;
- }
-
- dwc3_endpoint_transfer_complete(dwc, dep, event, 1);
- break;
- case DWC3_DEPEVT_XFERINPROGRESS:
- if (!usb_endpoint_xfer_isoc(dep->desc)) {
- dev_dbg(dwc->dev, "%s is not an Isochronous endpoint\n",
- dep->name);
- return;
- }
-
- dwc3_endpoint_transfer_complete(dwc, dep, event, 0);
- break;
- case DWC3_DEPEVT_XFERNOTREADY:
- if (usb_endpoint_xfer_isoc(dep->desc)) {
- dwc3_gadget_start_isoc(dwc, dep, event);
- } else {
- int ret;
-
- dev_vdbg(dwc->dev, "%s: reason %s\n",
- dep->name, event->status
- ? "Transfer Active"
- : "Transfer Not Active");
-
- ret = __dwc3_gadget_kick_transfer(dep, 0, 1);
- if (!ret || ret == -EBUSY)
- return;
-
- dev_dbg(dwc->dev, "%s: failed to kick transfers\n",
- dep->name);
- }
-
- break;
- case DWC3_DEPEVT_STREAMEVT:
- if (!usb_endpoint_xfer_bulk(dep->desc)) {
- dev_err(dwc->dev, "Stream event for non-Bulk %s\n",
- dep->name);
- return;
- }
-
- switch (event->status) {
- case DEPEVT_STREAMEVT_FOUND:
- dev_vdbg(dwc->dev, "Stream %d found and started\n",
- event->parameters);
-
- break;
- case DEPEVT_STREAMEVT_NOTFOUND:
- /* FALLTHROUGH */
- default:
- dev_dbg(dwc->dev, "Couldn't find suitable stream\n");
- }
- break;
- case DWC3_DEPEVT_RXTXFIFOEVT:
- dev_dbg(dwc->dev, "%s FIFO Overrun\n", dep->name);
- break;
- case DWC3_DEPEVT_EPCMDCMPLT:
- dwc3_ep_cmd_compl(dep, event);
- break;
- }
-}
-
-static void dwc3_disconnect_gadget(struct dwc3 *dwc)
-{
- if (dwc->gadget_driver && dwc->gadget_driver->disconnect) {
- spin_unlock(&dwc->lock);
- dwc->gadget_driver->disconnect(&dwc->gadget);
- spin_lock(&dwc->lock);
- }
-}
-
-static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum)
-{
- struct dwc3_ep *dep;
- struct dwc3_gadget_ep_cmd_params params;
- u32 cmd;
- int ret;
-
- dep = dwc->eps[epnum];
-
- WARN_ON(!dep->res_trans_idx);
- if (dep->res_trans_idx) {
- cmd = DWC3_DEPCMD_ENDTRANSFER;
- cmd |= DWC3_DEPCMD_HIPRI_FORCERM | DWC3_DEPCMD_CMDIOC;
- cmd |= DWC3_DEPCMD_PARAM(dep->res_trans_idx);
- memset(¶ms, 0, sizeof(params));
- ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms);
- WARN_ON_ONCE(ret);
- dep->res_trans_idx = 0;
- }
-}
-
-static void dwc3_stop_active_transfers(struct dwc3 *dwc)
-{
- u32 epnum;
-
- for (epnum = 2; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
- struct dwc3_ep *dep;
-
- dep = dwc->eps[epnum];
- if (!(dep->flags & DWC3_EP_ENABLED))
- continue;
-
- dwc3_remove_requests(dwc, dep);
- }
-}
-
-static void dwc3_clear_stall_all_ep(struct dwc3 *dwc)
-{
- u32 epnum;
-
- for (epnum = 1; epnum < DWC3_ENDPOINTS_NUM; epnum++) {
- struct dwc3_ep *dep;
- struct dwc3_gadget_ep_cmd_params params;
- int ret;
-
- dep = dwc->eps[epnum];
-
- if (!(dep->flags & DWC3_EP_STALL))
- continue;
-
- dep->flags &= ~DWC3_EP_STALL;
-
- memset(¶ms, 0, sizeof(params));
- ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
- DWC3_DEPCMD_CLEARSTALL, ¶ms);
- WARN_ON_ONCE(ret);
- }
-}
-
-static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)
-{
- dev_vdbg(dwc->dev, "%s\n", __func__);
-#if 0
- XXX
- U1/U2 is powersave optimization. Skip it for now. Anyway we need to
- enable it before we can disable it.
-
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
- reg &= ~DWC3_DCTL_INITU1ENA;
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
-
- reg &= ~DWC3_DCTL_INITU2ENA;
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
-#endif
-
- dwc3_stop_active_transfers(dwc);
- dwc3_disconnect_gadget(dwc);
- dwc->start_config_issued = false;
-
- dwc->gadget.speed = USB_SPEED_UNKNOWN;
-}
-
-static void dwc3_gadget_usb3_phy_power(struct dwc3 *dwc, int on)
-{
- u32 reg;
-
- reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
-
- if (on)
- reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
- else
- reg |= DWC3_GUSB3PIPECTL_SUSPHY;
-
- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
-}
-
-static void dwc3_gadget_usb2_phy_power(struct dwc3 *dwc, int on)
-{
- u32 reg;
-
- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
-
- if (on)
- reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
- else
- reg |= DWC3_GUSB2PHYCFG_SUSPHY;
-
- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
-}
-
-static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
-{
- u32 reg;
-
- dev_vdbg(dwc->dev, "%s\n", __func__);
-
- /* Enable PHYs */
- dwc3_gadget_usb2_phy_power(dwc, true);
- dwc3_gadget_usb3_phy_power(dwc, true);
-
- if (dwc->gadget.speed != USB_SPEED_UNKNOWN)
- dwc3_disconnect_gadget(dwc);
-
- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
- reg &= ~DWC3_DCTL_TSTCTRL_MASK;
- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
-
- dwc3_stop_active_transfers(dwc);
- dwc3_clear_stall_all_ep(dwc);
- dwc->start_config_issued = false;
-
- /* Reset device address to zero */
- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
- reg &= ~(DWC3_DCFG_DEVADDR_MASK);
- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
-}
-
-static void dwc3_update_ram_clk_sel(struct dwc3 *dwc, u32 speed)
-{
- u32 reg;
- u32 usb30_clock = DWC3_GCTL_CLK_BUS;
-
- /*
- * We change the clock only at SS but I dunno why I would want to do
- * this. Maybe it becomes part of the power saving plan.
- */
-
- if (speed != DWC3_DSTS_SUPERSPEED)
- return;
-
- /*
- * RAMClkSel is reset to 0 after USB reset, so it must be reprogrammed
- * each time on Connect Done.
- */
- if (!usb30_clock)
- return;
-
- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
- reg |= DWC3_GCTL_RAMCLKSEL(usb30_clock);
- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
-}
-
-static void dwc3_gadget_disable_phy(struct dwc3 *dwc, u8 speed)
-{
- switch (speed) {
- case USB_SPEED_SUPER:
- dwc3_gadget_usb2_phy_power(dwc, false);
- break;
- case USB_SPEED_HIGH:
- case USB_SPEED_FULL:
- case USB_SPEED_LOW:
- dwc3_gadget_usb3_phy_power(dwc, false);
- break;
- }
-}
-
-static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
-{
- struct dwc3_gadget_ep_cmd_params params;
- struct dwc3_ep *dep;
- int ret;
- u32 reg;
- u8 speed;
-
- dev_vdbg(dwc->dev, "%s\n", __func__);
-
- memset(¶ms, 0x00, sizeof(params));
-
- reg = dwc3_readl(dwc->regs, DWC3_DSTS);
- speed = reg & DWC3_DSTS_CONNECTSPD;
- dwc->speed = speed;
-
- dwc3_update_ram_clk_sel(dwc, speed);
-
- switch (speed) {
- case DWC3_DCFG_SUPERSPEED:
- dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
- dwc->gadget.ep0->maxpacket = 512;
- dwc->gadget.speed = USB_SPEED_SUPER;
- break;
- case DWC3_DCFG_HIGHSPEED:
- dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);
- dwc->gadget.ep0->maxpacket = 64;
- dwc->gadget.speed = USB_SPEED_HIGH;
- break;
- case DWC3_DCFG_FULLSPEED2:
- case DWC3_DCFG_FULLSPEED1:
- dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);
- dwc->gadget.ep0->maxpacket = 64;
- dwc->gadget.speed = USB_SPEED_FULL;
- break;
- case DWC3_DCFG_LOWSPEED:
- dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(8);
- dwc->gadget.ep0->maxpacket = 8;
- dwc->gadget.speed = USB_SPEED_LOW;
- break;
- }
-
- /* Disable unneded PHY */
- dwc3_gadget_disable_phy(dwc, dwc->gadget.speed);
-
- dep = dwc->eps[0];
- ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc);
- if (ret) {
- dev_err(dwc->dev, "failed to enable %s\n", dep->name);
- return;
- }
-
- dep = dwc->eps[1];
- ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc);
- if (ret) {
- dev_err(dwc->dev, "failed to enable %s\n", dep->name);
- return;
- }
-
- /*
- * Configure PHY via GUSB3PIPECTLn if required.
- *
- * Update GTXFIFOSIZn
- *
- * In both cases reset values should be sufficient.
- */
-}
-
-static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc)
-{
- dev_vdbg(dwc->dev, "%s\n", __func__);
-
- /*
- * TODO take core out of low power mode when that's
- * implemented.
- */
-
- dwc->gadget_driver->resume(&dwc->gadget);
-}
-
-static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc,
- unsigned int evtinfo)
-{
- /* The fith bit says SuperSpeed yes or no. */
- dwc->link_state = evtinfo & DWC3_LINK_STATE_MASK;
-
- dev_vdbg(dwc->dev, "%s link %d\n", __func__, dwc->link_state);
-}
-
-static void dwc3_gadget_interrupt(struct dwc3 *dwc,
- const struct dwc3_event_devt *event)
-{
- switch (event->type) {
- case DWC3_DEVICE_EVENT_DISCONNECT:
- dwc3_gadget_disconnect_interrupt(dwc);
- break;
- case DWC3_DEVICE_EVENT_RESET:
- dwc3_gadget_reset_interrupt(dwc);
- break;
- case DWC3_DEVICE_EVENT_CONNECT_DONE:
- dwc3_gadget_conndone_interrupt(dwc);
- break;
- case DWC3_DEVICE_EVENT_WAKEUP:
- dwc3_gadget_wakeup_interrupt(dwc);
- break;
- case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
- dwc3_gadget_linksts_change_interrupt(dwc, event->event_info);
- break;
- case DWC3_DEVICE_EVENT_EOPF:
- dev_vdbg(dwc->dev, "End of Periodic Frame\n");
- break;
- case DWC3_DEVICE_EVENT_SOF:
- dev_vdbg(dwc->dev, "Start of Periodic Frame\n");
- break;
- case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
- dev_vdbg(dwc->dev, "Erratic Error\n");
- break;
- case DWC3_DEVICE_EVENT_CMD_CMPL:
- dev_vdbg(dwc->dev, "Command Complete\n");
- break;
- case DWC3_DEVICE_EVENT_OVERFLOW:
- dev_vdbg(dwc->dev, "Overflow\n");
- break;
- default:
- dev_dbg(dwc->dev, "UNKNOWN IRQ %d\n", event->type);
- }
-}
-
-static void dwc3_process_event_entry(struct dwc3 *dwc,
- const union dwc3_event *event)
-{
- /* Endpoint IRQ, handle it and return early */
- if (event->type.is_devspec == 0) {
- /* depevt */
- return dwc3_endpoint_interrupt(dwc, &event->depevt);
- }
-
- switch (event->type.type) {
- case DWC3_EVENT_TYPE_DEV:
- dwc3_gadget_interrupt(dwc, &event->devt);
- break;
- /* REVISIT what to do with Carkit and I2C events ? */
- default:
- dev_err(dwc->dev, "UNKNOWN IRQ type %d\n", event->raw);
- }
-}
-
-static irqreturn_t dwc3_process_event_buf(struct dwc3 *dwc, u32 buf)
-{
- struct dwc3_event_buffer *evt;
- int left;
- u32 count;
-
- count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(buf));
- count &= DWC3_GEVNTCOUNT_MASK;
- if (!count)
- return IRQ_NONE;
-
- evt = dwc->ev_buffs[buf];
- left = count;
-
- while (left > 0) {
- union dwc3_event event;
-
- memcpy(&event.raw, (evt->buf + evt->lpos), sizeof(event.raw));
- dwc3_process_event_entry(dwc, &event);
- /*
- * XXX we wrap around correctly to the next entry as almost all
- * entries are 4 bytes in size. There is one entry which has 12
- * bytes which is a regular entry followed by 8 bytes data. ATM
- * I don't know how things are organized if were get next to the
- * a boundary so I worry about that once we try to handle that.
- */
- evt->lpos = (evt->lpos + 4) % DWC3_EVENT_BUFFERS_SIZE;
- left -= 4;
-
- dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(buf), 4);
- }
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t dwc3_interrupt(int irq, void *_dwc)
-{
- struct dwc3 *dwc = _dwc;
- int i;
- irqreturn_t ret = IRQ_NONE;
-
- spin_lock(&dwc->lock);
-
- for (i = 0; i < DWC3_EVENT_BUFFERS_NUM; i++) {
- irqreturn_t status;
-
- status = dwc3_process_event_buf(dwc, i);
- if (status == IRQ_HANDLED)
- ret = status;
- }
-
- spin_unlock(&dwc->lock);
-
- return ret;
-}
-
-/**
- * dwc3_gadget_init - Initializes gadget related registers
- * @dwc: Pointer to out controller context structure
- *
- * Returns 0 on success otherwise negative errno.
- */
-int __devinit dwc3_gadget_init(struct dwc3 *dwc)
-{
- u32 reg;
- int ret;
- int irq;
-
- dwc->ctrl_req = dma_alloc_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
- &dwc->ctrl_req_addr, GFP_KERNEL);
- 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);
- if (!dwc->ep0_trb) {
- dev_err(dwc->dev, "failed to allocate ep0 trb\n");
- ret = -ENOMEM;
- goto err1;
- }
-
- dwc->setup_buf = dma_alloc_coherent(dwc->dev,
- sizeof(*dwc->setup_buf) * 2,
- &dwc->setup_buf_addr, GFP_KERNEL);
- if (!dwc->setup_buf) {
- dev_err(dwc->dev, "failed to allocate setup buffer\n");
- ret = -ENOMEM;
- goto err2;
- }
-
- dwc->ep0_bounce = dma_alloc_coherent(dwc->dev,
- 512, &dwc->ep0_bounce_addr, GFP_KERNEL);
- if (!dwc->ep0_bounce) {
- dev_err(dwc->dev, "failed to allocate ep0 bounce buffer\n");
- ret = -ENOMEM;
- goto err3;
- }
-
- dev_set_name(&dwc->gadget.dev, "gadget");
-
- dwc->gadget.ops = &dwc3_gadget_ops;
- dwc->gadget.is_dualspeed = true;
- dwc->gadget.speed = USB_SPEED_UNKNOWN;
- dwc->gadget.dev.parent = dwc->dev;
-
- dma_set_coherent_mask(&dwc->gadget.dev, dwc->dev->coherent_dma_mask);
-
- dwc->gadget.dev.dma_parms = dwc->dev->dma_parms;
- dwc->gadget.dev.dma_mask = dwc->dev->dma_mask;
- dwc->gadget.dev.release = dwc3_gadget_release;
- dwc->gadget.name = "dwc3-gadget";
-
- /*
- * REVISIT: Here we should clear all pending IRQs to be
- * sure we're starting from a well known location.
- */
-
- ret = dwc3_gadget_init_endpoints(dwc);
- if (ret)
- goto err4;
-
- irq = platform_get_irq(to_platform_device(dwc->dev), 0);
-
- ret = request_irq(irq, dwc3_interrupt, IRQF_SHARED,
- "dwc3", dwc);
- if (ret) {
- dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
- irq, ret);
- goto err5;
- }
-
- /* Enable all but Start and End of Frame IRQs */
- reg = (DWC3_DEVTEN_VNDRDEVTSTRCVEDEN |
- DWC3_DEVTEN_EVNTOVERFLOWEN |
- DWC3_DEVTEN_CMDCMPLTEN |
- DWC3_DEVTEN_ERRTICERREN |
- DWC3_DEVTEN_WKUPEVTEN |
- DWC3_DEVTEN_ULSTCNGEN |
- DWC3_DEVTEN_CONNECTDONEEN |
- DWC3_DEVTEN_USBRSTEN |
- DWC3_DEVTEN_DISCONNEVTEN);
- dwc3_writel(dwc->regs, DWC3_DEVTEN, reg);
-
- ret = device_register(&dwc->gadget.dev);
- if (ret) {
- dev_err(dwc->dev, "failed to register gadget device\n");
- put_device(&dwc->gadget.dev);
- goto err6;
- }
-
- ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget);
- if (ret) {
- dev_err(dwc->dev, "failed to register udc\n");
- goto err7;
- }
-
- return 0;
-
-err7:
- device_unregister(&dwc->gadget.dev);
-
-err6:
- dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00);
- free_irq(irq, dwc);
-
-err5:
- dwc3_gadget_free_endpoints(dwc);
-
-err4:
- dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce,
- dwc->ep0_bounce_addr);
-
-err3:
- dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2,
- dwc->setup_buf, dwc->setup_buf_addr);
-
-err2:
- dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
- dwc->ep0_trb, dwc->ep0_trb_addr);
-
-err1:
- dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
- dwc->ctrl_req, dwc->ctrl_req_addr);
-
-err0:
- return ret;
-}
-
-void dwc3_gadget_exit(struct dwc3 *dwc)
-{
- int irq;
- int i;
-
- usb_del_gadget_udc(&dwc->gadget);
- irq = platform_get_irq(to_platform_device(dwc->dev), 0);
-
- dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00);
- free_irq(irq, dwc);
-
- for (i = 0; i < ARRAY_SIZE(dwc->eps); i++)
- __dwc3_gadget_ep_disable(dwc->eps[i]);
-
- dwc3_gadget_free_endpoints(dwc);
-
- dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce,
- dwc->ep0_bounce_addr);
-
- dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2,
- dwc->setup_buf, dwc->setup_buf_addr);
-
- dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
- dwc->ep0_trb, dwc->ep0_trb_addr);
-
- dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
- dwc->ctrl_req, dwc->ctrl_req_addr);
-
- device_unregister(&dwc->gadget.dev);
-}
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h
deleted file mode 100644
index 71145a4..0000000
--- a/drivers/usb/dwc3/gadget.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/**
- * gadget.h - DesignWare USB3 DRD Gadget Header
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * 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") version 2, as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#ifndef __DRIVERS_USB_DWC3_GADGET_H
-#define __DRIVERS_USB_DWC3_GADGET_H
-
-#include <linux/list.h>
-#include <linux/usb/gadget.h>
-#include "io.h"
-
-struct dwc3;
-#define to_dwc3_ep(ep) (container_of(ep, struct dwc3_ep, endpoint))
-#define gadget_to_dwc(g) (container_of(g, struct dwc3, gadget))
-
-/* DEPCFG parameter 1 */
-#define DWC3_DEPCFG_INT_NUM(n) ((n) << 0)
-#define DWC3_DEPCFG_XFER_COMPLETE_EN (1 << 8)
-#define DWC3_DEPCFG_XFER_IN_PROGRESS_EN (1 << 9)
-#define DWC3_DEPCFG_XFER_NOT_READY_EN (1 << 10)
-#define DWC3_DEPCFG_FIFO_ERROR_EN (1 << 11)
-#define DWC3_DEPCFG_STREAM_EVENT_EN (1 << 13)
-#define DWC3_DEPCFG_BINTERVAL_M1(n) ((n) << 16)
-#define DWC3_DEPCFG_STREAM_CAPABLE (1 << 24)
-#define DWC3_DEPCFG_EP_NUMBER(n) ((n) << 25)
-#define DWC3_DEPCFG_BULK_BASED (1 << 30)
-#define DWC3_DEPCFG_FIFO_BASED (1 << 31)
-
-/* DEPCFG parameter 0 */
-#define DWC3_DEPCFG_EP_TYPE(n) ((n) << 1)
-#define DWC3_DEPCFG_MAX_PACKET_SIZE(n) ((n) << 3)
-#define DWC3_DEPCFG_FIFO_NUMBER(n) ((n) << 17)
-#define DWC3_DEPCFG_BURST_SIZE(n) ((n) << 22)
-#define DWC3_DEPCFG_DATA_SEQ_NUM(n) ((n) << 26)
-#define DWC3_DEPCFG_IGN_SEQ_NUM (1 << 31)
-
-/* DEPXFERCFG parameter 0 */
-#define DWC3_DEPXFERCFG_NUM_XFER_RES(n) ((n) & 0xffff)
-
-struct dwc3_gadget_ep_cmd_params {
- u32 param2;
- u32 param1;
- u32 param0;
-};
-
-/* -------------------------------------------------------------------------- */
-
-struct dwc3_request {
- struct usb_request request;
- struct list_head list;
- struct dwc3_ep *dep;
-
- u8 epnum;
- struct dwc3_trb_hw *trb;
- dma_addr_t trb_dma;
-
- unsigned direction:1;
- unsigned mapped:1;
- unsigned queued:1;
-};
-#define to_dwc3_request(r) (container_of(r, struct dwc3_request, request))
-
-static inline struct dwc3_request *next_request(struct list_head *list)
-{
- if (list_empty(list))
- return NULL;
-
- return list_first_entry(list, struct dwc3_request, list);
-}
-
-static inline void dwc3_gadget_move_request_queued(struct dwc3_request *req)
-{
- struct dwc3_ep *dep = req->dep;
-
- req->queued = true;
- list_move_tail(&req->list, &dep->req_queued);
-}
-
-#if defined(CONFIG_USB_GADGET_DWC3) || defined(CONFIG_USB_GADGET_DWC3_MODULE)
-int dwc3_gadget_init(struct dwc3 *dwc);
-void dwc3_gadget_exit(struct dwc3 *dwc);
-#else
-static inline int dwc3_gadget_init(struct dwc3 *dwc) { return 0; }
-static inline void dwc3_gadget_exit(struct dwc3 *dwc) { }
-static inline int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
- unsigned cmd, struct dwc3_gadget_ep_cmd_params *params)
-{
- return 0;
-}
-#endif
-
-void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
- int status);
-
-void dwc3_ep0_interrupt(struct dwc3 *dwc, const struct dwc3_event_depevt *event);
-void dwc3_ep0_out_start(struct dwc3 *dwc);
-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 dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
- unsigned cmd, struct dwc3_gadget_ep_cmd_params *params);
-void dwc3_map_buffer_to_dma(struct dwc3_request *req);
-void dwc3_unmap_buffer_from_dma(struct dwc3_request *req);
-
-/**
- * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW
- * @dwc: DesignWare USB3 Pointer
- * @number: DWC endpoint number
- *
- * Caller should take care of locking
- */
-static inline u32 dwc3_gadget_ep_get_transfer_index(struct dwc3 *dwc, u8 number)
-{
- u32 res_id;
-
- res_id = dwc3_readl(dwc->regs, DWC3_DEPCMD(number));
-
- return DWC3_DEPCMD_GET_RSC_IDX(res_id);
-}
-
-/**
- * dwc3_gadget_event_string - returns event name
- * @event: the event code
- */
-static inline const char *dwc3_gadget_event_string(u8 event)
-{
- switch (event) {
- case DWC3_DEVICE_EVENT_DISCONNECT:
- return "Disconnect";
- case DWC3_DEVICE_EVENT_RESET:
- return "Reset";
- case DWC3_DEVICE_EVENT_CONNECT_DONE:
- return "Connection Done";
- case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE:
- return "Link Status Change";
- case DWC3_DEVICE_EVENT_WAKEUP:
- return "WakeUp";
- case DWC3_DEVICE_EVENT_EOPF:
- return "End-Of-Frame";
- case DWC3_DEVICE_EVENT_SOF:
- return "Start-Of-Frame";
- case DWC3_DEVICE_EVENT_ERRATIC_ERROR:
- return "Erratic Error";
- case DWC3_DEVICE_EVENT_CMD_CMPL:
- return "Command Complete";
- case DWC3_DEVICE_EVENT_OVERFLOW:
- return "Overflow";
- }
-
- return "UNKNOWN";
-}
-
-/**
- * dwc3_ep_event_string - returns event name
- * @event: then event code
- */
-static inline const char *dwc3_ep_event_string(u8 event)
-{
- switch (event) {
- case DWC3_DEPEVT_XFERCOMPLETE:
- return "Transfer Complete";
- case DWC3_DEPEVT_XFERINPROGRESS:
- return "Transfer In-Progress";
- case DWC3_DEPEVT_XFERNOTREADY:
- return "Transfer Not Ready";
- case DWC3_DEPEVT_RXTXFIFOEVT:
- return "FIFO";
- case DWC3_DEPEVT_STREAMEVT:
- return "Stream";
- case DWC3_DEPEVT_EPCMDCMPLT:
- return "Endpoint Command Complete";
- }
-
- return "UNKNOWN";
-}
-
-#endif /* __DRIVERS_USB_DWC3_GADGET_H */
diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h
deleted file mode 100644
index bc957db..0000000
--- a/drivers/usb/dwc3/io.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * io.h - DesignWare USB3 DRD IO Header
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- *
- * Authors: Felipe Balbi <balbi@ti.com>,
- * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
- *
- * 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") version 2, as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#ifndef __DRIVERS_USB_DWC3_IO_H
-#define __DRIVERS_USB_DWC3_IO_H
-
-#include <asm/io.h>
-
-static inline u32 dwc3_readl(void __iomem *base, u32 offset)
-{
- return readl(base + offset);
-}
-
-static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value)
-{
- writel(value, base + offset);
-}
-
-#endif /* __DRIVERS_USB_DWC3_IO_H */
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 092e115..97e7aa4 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -386,18 +386,6 @@
default USB_GADGET
select USB_GADGET_SELECTED
-config USB_GADGET_DWC3
- tristate "DesignWare USB3.0 (DRD) Controller"
- depends on USB_DWC3
- select USB_GADGET_DUALSPEED
- select USB_GADGET_SUPERSPEED
- help
- DesignWare USB3.0 controller is a SuperSpeed USB3.0 Controller
- which can be configured for peripheral-only, host-only, hub-only
- and Dual-Role operation. This Controller was first integrated into
- the OMAP5 series of processors. More information about the OMAP5
- version of this controller, refer to http://www.ti.com/omap5.
-
#
# Controllers available in both integrated and discrete versions
#
@@ -685,12 +673,6 @@
bool
depends on USB_GADGET
-# Selected by UDC drivers that support super-speed opperation
-config USB_GADGET_SUPERSPEED
- bool
- depends on USB_GADGET
- depends on USB_GADGET_DUALSPEED
-
#
# USB Gadget Drivers
#
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 655a7ee..141f649 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -3,7 +3,6 @@
#
ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG
-obj-$(CONFIG_USB_GADGET) += udc-core.o
obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o
obj-$(CONFIG_USB_NET2280) += net2280.o
obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c
index 70f2b37..95e8138 100644
--- a/drivers/usb/gadget/amd5536udc.c
+++ b/drivers/usb/gadget/amd5536udc.c
@@ -1438,15 +1438,10 @@
return 0;
}
-static int amd5536_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int amd5536_stop(struct usb_gadget_driver *driver);
/* gadget operations */
static const struct usb_gadget_ops udc_ops = {
.wakeup = udc_wakeup,
.get_frame = udc_get_frame,
- .start = amd5536_start,
- .stop = amd5536_stop,
};
/* Setups endpoint parameters, adds endpoints to linked list */
@@ -1960,7 +1955,7 @@
}
/* Called by gadget driver to register itself */
-static int amd5536_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct udc *dev = udc;
@@ -2007,6 +2002,7 @@
return 0;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
/* shutdown requests and disconnect from gadget */
static void
@@ -2031,7 +2027,7 @@
}
/* Called by gadget driver to unregister itself */
-static int amd5536_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct udc *dev = udc;
unsigned long flags;
@@ -2061,6 +2057,8 @@
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
/* Clear pending NAK bits */
static void udc_process_cnak_queue(struct udc *dev)
@@ -3136,7 +3134,6 @@
dev = pci_get_drvdata(pdev);
- usb_del_gadget_udc(&udc->gadget);
/* gadget driver must not be registered */
BUG_ON(dev->driver != NULL);
@@ -3385,13 +3382,8 @@
"driver version: %s(for Geode5536 B1)\n", tmp);
udc = dev;
- retval = usb_add_gadget_udc(&udc->pdev->dev, &dev->gadget);
- if (retval)
- goto finished;
-
retval = device_register(&dev->gadget.dev);
if (retval) {
- usb_del_gadget_udc(&dev->gadget);
put_device(&dev->gadget.dev);
goto finished;
}
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 98cbc06..f4690ff 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -985,18 +985,12 @@
return 0;
}
-static int at91_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int at91_stop(struct usb_gadget_driver *driver);
-
static const struct usb_gadget_ops at91_udc_ops = {
.get_frame = at91_get_frame,
.wakeup = at91_wakeup,
.set_selfpowered = at91_set_selfpowered,
.vbus_session = at91_vbus_session,
.pullup = at91_pullup,
- .start = at91_start,
- .stop = at91_stop,
/*
* VBUS-powered devices may also also want to support bigger
@@ -1634,7 +1628,7 @@
schedule_work(&udc->vbus_timer_work);
}
-static int at91_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct at91_udc *udc = &controller;
@@ -1678,8 +1672,9 @@
DBG("bound to %s\n", driver->driver.name);
return 0;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
-static int at91_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
{
struct at91_udc *udc = &controller;
unsigned long flags;
@@ -1701,6 +1696,7 @@
DBG("unbound from %s\n", driver->driver.name);
return 0;
}
+EXPORT_SYMBOL (usb_gadget_unregister_driver);
/*-------------------------------------------------------------------------*/
@@ -1858,18 +1854,13 @@
DBG("no VBUS detection, assuming always-on\n");
udc->vbus = 1;
}
- retval = usb_add_gadget_udc(dev, &udc->gadget);
- if (retval)
- goto fail4;
dev_set_drvdata(dev, udc);
device_init_wakeup(dev, 1);
create_debug_file(udc);
INFO("%s version %s\n", driver_name, DRIVER_VERSION);
return 0;
-fail4:
- if (udc->board.vbus_pin > 0 && !udc->board.vbus_polled)
- free_irq(udc->board.vbus_pin, udc);
+
fail3:
if (udc->board.vbus_pin > 0)
gpio_free(udc->board.vbus_pin);
@@ -1896,7 +1887,6 @@
DBG("remove\n");
- usb_del_gadget_udc(&udc->gadget);
if (udc->driver)
return -EBUSY;
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index e6b970a..db1a659 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -1007,16 +1007,10 @@
return 0;
}
-static int atmel_usba_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int atmel_usba_stop(struct usb_gadget_driver *driver);
-
static const struct usb_gadget_ops usba_udc_ops = {
.get_frame = usba_udc_get_frame,
.wakeup = usba_udc_wakeup,
.set_selfpowered = usba_udc_set_selfpowered,
- .start = atmel_usba_start,
- .stop = atmel_usba_stop,
};
static struct usb_endpoint_descriptor usba_ep0_desc = {
@@ -1795,7 +1789,7 @@
return IRQ_HANDLED;
}
-static int atmel_usba_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct usba_udc *udc = &the_udc;
@@ -1848,8 +1842,9 @@
udc->gadget.dev.driver = NULL;
return ret;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
-static int atmel_usba_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct usba_udc *udc = &the_udc;
unsigned long flags;
@@ -1885,6 +1880,7 @@
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
static int __init usba_udc_probe(struct platform_device *pdev)
{
@@ -2025,24 +2021,12 @@
}
}
- ret = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
- if (ret)
- goto err_add_udc;
-
usba_init_debugfs(udc);
for (i = 1; i < pdata->num_ep; i++)
usba_ep_init_debugfs(udc, &usba_ep[i]);
return 0;
-err_add_udc:
- if (gpio_is_valid(pdata->vbus_pin)) {
- free_irq(gpio_to_irq(udc->vbus_pin), udc);
- gpio_free(udc->vbus_pin);
- }
-
- device_unregister(&udc->gadget.dev);
-
err_device_add:
free_irq(irq, udc);
err_request_irq:
@@ -2069,8 +2053,6 @@
udc = platform_get_drvdata(pdev);
- usb_del_gadget_udc(&udc->gadget);
-
for (i = 1; i < pdata->num_ep; i++)
usba_ep_cleanup_debugfs(&usba_ep[i]);
usba_cleanup_debugfs(udc);
diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c
index 9d89ae47..93b999e 100644
--- a/drivers/usb/gadget/audio.c
+++ b/drivers/usb/gadget/audio.c
@@ -165,7 +165,6 @@
.name = "g_audio",
.dev = &device_desc,
.strings = audio_strings,
- .max_speed = USB_SPEED_HIGH,
.unbind = __exit_p(audio_unbind),
};
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
index b1c1afb..2720ab0 100644
--- a/drivers/usb/gadget/cdc2.c
+++ b/drivers/usb/gadget/cdc2.c
@@ -244,7 +244,6 @@
.name = "g_cdc",
.dev = &device_desc,
.strings = dev_strings,
- .max_speed = USB_SPEED_HIGH,
.unbind = __exit_p(cdc_unbind),
};
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 406b238..35327cc 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -2182,7 +2182,7 @@
int type, num, dir, err = -EINVAL;
struct usb_ctrlrequest req;
- if (mEp->ep.desc == NULL)
+ if (mEp->desc == NULL)
continue; /* not configured */
if (hw_test_and_clear_complete(i)) {
@@ -2381,7 +2381,7 @@
/* only internal SW should enable ctrl endpts */
- mEp->ep.desc = desc;
+ mEp->desc = desc;
if (!list_empty(&mEp->qh.queue))
warn("enabling a non-empty endpoint!");
@@ -2436,7 +2436,7 @@
if (ep == NULL)
return -EINVAL;
- else if (mEp->ep.desc == NULL)
+ else if (mEp->desc == NULL)
return -EBUSY;
spin_lock_irqsave(mEp->lock, flags);
@@ -2455,7 +2455,7 @@
} while (mEp->dir != direction);
- mEp->ep.desc = NULL;
+ mEp->desc = NULL;
spin_unlock_irqrestore(mEp->lock, flags);
return retval;
@@ -2543,7 +2543,7 @@
trace("%p, %p, %X", ep, req, gfp_flags);
- if (ep == NULL || req == NULL || mEp->ep.desc == NULL)
+ if (ep == NULL || req == NULL || mEp->desc == NULL)
return -EINVAL;
spin_lock_irqsave(mEp->lock, flags);
@@ -2616,7 +2616,7 @@
trace("%p, %p", ep, req);
if (ep == NULL || req == NULL || mReq->req.status != -EALREADY ||
- mEp->ep.desc == NULL || list_empty(&mReq->queue) ||
+ mEp->desc == NULL || list_empty(&mReq->queue) ||
list_empty(&mEp->qh.queue))
return -EINVAL;
@@ -2662,7 +2662,7 @@
trace("%p, %i", ep, value);
- if (ep == NULL || mEp->ep.desc == NULL)
+ if (ep == NULL || mEp->desc == NULL)
return -EINVAL;
spin_lock_irqsave(mEp->lock, flags);
@@ -2705,7 +2705,7 @@
trace("%p", ep);
- if (ep == NULL || mEp->ep.desc == NULL)
+ if (ep == NULL || mEp->desc == NULL)
return -EINVAL;
spin_lock_irqsave(mEp->lock, flags);
@@ -2828,9 +2828,7 @@
return 0;
}
-static int ci13xxx_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int ci13xxx_stop(struct usb_gadget_driver *driver);
+
/**
* Device operations part of the API to the USB controller hardware,
* which don't involve endpoints (or i/o)
@@ -2841,19 +2839,17 @@
.wakeup = ci13xxx_wakeup,
.vbus_draw = ci13xxx_vbus_draw,
.pullup = ci13xxx_pullup,
- .start = ci13xxx_start,
- .stop = ci13xxx_stop,
};
/**
- * ci13xxx_start: register a gadget driver
+ * usb_gadget_probe_driver: register a gadget driver
* @driver: the driver being registered
* @bind: the driver's bind callback
*
- * Check ci13xxx_start() at <linux/usb/gadget.h> for details.
+ * Check usb_gadget_probe_driver() at <linux/usb/gadget.h> for details.
* Interrupts are enabled here.
*/
-static int ci13xxx_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct ci13xxx *udc = _udc;
@@ -2935,12 +2931,10 @@
if (retval)
goto done;
spin_unlock_irqrestore(udc->lock, flags);
- udc->ep0out.ep.desc = &ctrl_endpt_out_desc;
- retval = usb_ep_enable(&udc->ep0out.ep);
+ retval = usb_ep_enable(&udc->ep0out.ep, &ctrl_endpt_out_desc);
if (retval)
return retval;
- udc->ep0in.ep.desc = &ctrl_endpt_in_desc;
- retval = usb_ep_enable(&udc->ep0in.ep);
+ retval = usb_ep_enable(&udc->ep0in.ep, &ctrl_endpt_in_desc);
if (retval)
return retval;
spin_lock_irqsave(udc->lock, flags);
@@ -2985,13 +2979,14 @@
pm_runtime_put_sync(&udc->gadget.dev);
return retval;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
/**
- * ci13xxx_stop: unregister a gadget driver
+ * usb_gadget_unregister_driver: unregister a gadget driver
*
* Check usb_gadget_unregister_driver() at "usb_gadget.h" for details
*/
-static int ci13xxx_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct ci13xxx *udc = _udc;
unsigned long i, flags;
@@ -3050,6 +3045,7 @@
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
/******************************************************************************
* BUS block
@@ -3224,23 +3220,12 @@
if (retval)
goto remove_dbg;
}
-
- retval = usb_add_gadget_udc(dev, &udc->gadget);
- if (retval)
- goto remove_trans;
-
pm_runtime_no_callbacks(&udc->gadget.dev);
pm_runtime_enable(&udc->gadget.dev);
_udc = udc;
return retval;
-remove_trans:
- if (udc->transceiver) {
- otg_set_peripheral(udc->transceiver, &udc->gadget);
- otg_put_transceiver(udc->transceiver);
- }
-
err("error = %i", retval);
remove_dbg:
#ifdef CONFIG_USB_GADGET_DEBUG_FILES
@@ -3270,7 +3255,6 @@
err("EINVAL");
return;
}
- usb_del_gadget_udc(&udc->gadget);
if (udc->transceiver) {
otg_set_peripheral(udc->transceiver, &udc->gadget);
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h
index 54b8790..fce611a 100644
--- a/drivers/usb/gadget/ci13xxx_udc.h
+++ b/drivers/usb/gadget/ci13xxx_udc.h
@@ -97,6 +97,7 @@
/* Extension of usb_ep */
struct ci13xxx_ep {
struct usb_ep ep;
+ const struct usb_endpoint_descriptor *desc;
u8 dir;
u8 num;
u8 type;
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index daa796e..4c33695 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -27,7 +27,7 @@
#include <linux/utsname.h>
#include <linux/usb/composite.h>
-#include <asm/unaligned.h>
+
/*
* The code in this file is utility code, used to build a gadget driver
@@ -74,130 +74,6 @@
static char composite_manufacturer[50];
/*-------------------------------------------------------------------------*/
-/**
- * next_ep_desc() - advance to the next EP descriptor
- * @t: currect pointer within descriptor array
- *
- * Return: next EP descriptor or NULL
- *
- * Iterate over @t until either EP descriptor found or
- * NULL (that indicates end of list) encountered
- */
-static struct usb_descriptor_header**
-next_ep_desc(struct usb_descriptor_header **t)
-{
- for (; *t; t++) {
- if ((*t)->bDescriptorType == USB_DT_ENDPOINT)
- return t;
- }
- return NULL;
-}
-
-/*
- * for_each_ep_desc()- iterate over endpoint descriptors in the
- * descriptors list
- * @start: pointer within descriptor array.
- * @ep_desc: endpoint descriptor to use as the loop cursor
- */
-#define for_each_ep_desc(start, ep_desc) \
- for (ep_desc = next_ep_desc(start); \
- ep_desc; ep_desc = next_ep_desc(ep_desc+1))
-
-/**
- * config_ep_by_speed() - configures the given endpoint
- * according to gadget speed.
- * @g: pointer to the gadget
- * @f: usb function
- * @_ep: the endpoint to configure
- *
- * Return: error code, 0 on success
- *
- * This function chooses the right descriptors for a given
- * endpoint according to gadget speed and saves it in the
- * endpoint desc field. If the endpoint already has a descriptor
- * assigned to it - overwrites it with currently corresponding
- * descriptor. The endpoint maxpacket field is updated according
- * to the chosen descriptor.
- * Note: the supplied function should hold all the descriptors
- * for supported speeds
- */
-int config_ep_by_speed(struct usb_gadget *g,
- struct usb_function *f,
- struct usb_ep *_ep)
-{
- struct usb_endpoint_descriptor *chosen_desc = NULL;
- struct usb_descriptor_header **speed_desc = NULL;
-
- struct usb_ss_ep_comp_descriptor *comp_desc = NULL;
- int want_comp_desc = 0;
-
- struct usb_descriptor_header **d_spd; /* cursor for speed desc */
-
- if (!g || !f || !_ep)
- return -EIO;
-
- /* select desired speed */
- switch (g->speed) {
- case USB_SPEED_SUPER:
- if (gadget_is_superspeed(g)) {
- speed_desc = f->ss_descriptors;
- want_comp_desc = 1;
- break;
- }
- /* else: Fall trough */
- case USB_SPEED_HIGH:
- if (gadget_is_dualspeed(g)) {
- speed_desc = f->hs_descriptors;
- break;
- }
- /* else: fall through */
- default:
- speed_desc = f->descriptors;
- }
- /* find descriptors */
- for_each_ep_desc(speed_desc, d_spd) {
- chosen_desc = (struct usb_endpoint_descriptor *)*d_spd;
- if (chosen_desc->bEndpointAddress == _ep->address)
- goto ep_found;
- }
- return -EIO;
-
-ep_found:
- /* commit results */
- _ep->maxpacket = le16_to_cpu(chosen_desc->wMaxPacketSize);
- _ep->desc = chosen_desc;
- _ep->comp_desc = NULL;
- _ep->maxburst = 0;
- _ep->mult = 0;
- if (!want_comp_desc)
- return 0;
-
- /*
- * Companion descriptor should follow EP descriptor
- * USB 3.0 spec, #9.6.7
- */
- comp_desc = (struct usb_ss_ep_comp_descriptor *)*(++d_spd);
- if (!comp_desc ||
- (comp_desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP))
- return -EIO;
- _ep->comp_desc = comp_desc;
- if (g->speed == USB_SPEED_SUPER) {
- switch (usb_endpoint_type(_ep->desc)) {
- case USB_ENDPOINT_XFER_BULK:
- case USB_ENDPOINT_XFER_INT:
- _ep->maxburst = comp_desc->bMaxBurst;
- break;
- case USB_ENDPOINT_XFER_ISOC:
- /* mult: bits 1:0 of bmAttributes */
- _ep->mult = comp_desc->bmAttributes & 0x3;
- break;
- default:
- /* Do nothing for control endpoints */
- break;
- }
- }
- return 0;
-}
/**
* usb_add_function() - add a function to a configuration
@@ -247,8 +123,6 @@
config->fullspeed = true;
if (!config->highspeed && function->hs_descriptors)
config->highspeed = true;
- if (!config->superspeed && function->ss_descriptors)
- config->superspeed = true;
done:
if (value)
@@ -392,17 +266,10 @@
list_for_each_entry(f, &config->functions, list) {
struct usb_descriptor_header **descriptors;
- switch (speed) {
- case USB_SPEED_SUPER:
- descriptors = f->ss_descriptors;
- break;
- case USB_SPEED_HIGH:
+ if (speed == USB_SPEED_HIGH)
descriptors = f->hs_descriptors;
- break;
- default:
+ else
descriptors = f->descriptors;
- }
-
if (!descriptors)
continue;
status = usb_descriptor_fillbuf(next, len,
@@ -425,10 +292,9 @@
u8 type = w_value >> 8;
enum usb_device_speed speed = USB_SPEED_UNKNOWN;
- if (gadget->speed == USB_SPEED_SUPER)
- speed = gadget->speed;
- else if (gadget_is_dualspeed(gadget)) {
- int hs = 0;
+ if (gadget_is_dualspeed(gadget)) {
+ int hs = 0;
+
if (gadget->speed == USB_SPEED_HIGH)
hs = 1;
if (type == USB_DT_OTHER_SPEED_CONFIG)
@@ -442,20 +308,13 @@
w_value &= 0xff;
list_for_each_entry(c, &cdev->configs, list) {
/* ignore configs that won't work at this speed */
- switch (speed) {
- case USB_SPEED_SUPER:
- if (!c->superspeed)
- continue;
- break;
- case USB_SPEED_HIGH:
+ if (speed == USB_SPEED_HIGH) {
if (!c->highspeed)
continue;
- break;
- default:
+ } else {
if (!c->fullspeed)
continue;
}
-
if (w_value == 0)
return config_buf(c, speed, cdev->req->buf, type);
w_value--;
@@ -469,22 +328,16 @@
struct usb_configuration *c;
unsigned count = 0;
int hs = 0;
- int ss = 0;
if (gadget_is_dualspeed(gadget)) {
if (gadget->speed == USB_SPEED_HIGH)
hs = 1;
- if (gadget->speed == USB_SPEED_SUPER)
- ss = 1;
if (type == USB_DT_DEVICE_QUALIFIER)
hs = !hs;
}
list_for_each_entry(c, &cdev->configs, list) {
/* ignore configs that won't work at this speed */
- if (ss) {
- if (!c->superspeed)
- continue;
- } else if (hs) {
+ if (hs) {
if (!c->highspeed)
continue;
} else {
@@ -496,71 +349,6 @@
return count;
}
-/**
- * bos_desc() - prepares the BOS descriptor.
- * @cdev: pointer to usb_composite device to generate the bos
- * descriptor for
- *
- * This function generates the BOS (Binary Device Object)
- * descriptor and its device capabilities descriptors. The BOS
- * descriptor should be supported by a SuperSpeed device.
- */
-static int bos_desc(struct usb_composite_dev *cdev)
-{
- struct usb_ext_cap_descriptor *usb_ext;
- struct usb_ss_cap_descriptor *ss_cap;
- struct usb_dcd_config_params dcd_config_params;
- struct usb_bos_descriptor *bos = cdev->req->buf;
-
- bos->bLength = USB_DT_BOS_SIZE;
- bos->bDescriptorType = USB_DT_BOS;
-
- bos->wTotalLength = cpu_to_le16(USB_DT_BOS_SIZE);
- bos->bNumDeviceCaps = 0;
-
- /*
- * A SuperSpeed device shall include the USB2.0 extension descriptor
- * and shall support LPM when operating in USB2.0 HS mode.
- */
- usb_ext = cdev->req->buf + le16_to_cpu(bos->wTotalLength);
- bos->bNumDeviceCaps++;
- le16_add_cpu(&bos->wTotalLength, USB_DT_USB_EXT_CAP_SIZE);
- usb_ext->bLength = USB_DT_USB_EXT_CAP_SIZE;
- usb_ext->bDescriptorType = USB_DT_DEVICE_CAPABILITY;
- usb_ext->bDevCapabilityType = USB_CAP_TYPE_EXT;
- usb_ext->bmAttributes = cpu_to_le32(USB_LPM_SUPPORT);
-
- /*
- * The Superspeed USB Capability descriptor shall be implemented by all
- * SuperSpeed devices.
- */
- ss_cap = cdev->req->buf + le16_to_cpu(bos->wTotalLength);
- bos->bNumDeviceCaps++;
- le16_add_cpu(&bos->wTotalLength, USB_DT_USB_SS_CAP_SIZE);
- ss_cap->bLength = USB_DT_USB_SS_CAP_SIZE;
- ss_cap->bDescriptorType = USB_DT_DEVICE_CAPABILITY;
- ss_cap->bDevCapabilityType = USB_SS_CAP_TYPE;
- ss_cap->bmAttributes = 0; /* LTM is not supported yet */
- ss_cap->wSpeedSupported = cpu_to_le16(USB_LOW_SPEED_OPERATION |
- USB_FULL_SPEED_OPERATION |
- USB_HIGH_SPEED_OPERATION |
- USB_5GBPS_OPERATION);
- ss_cap->bFunctionalitySupport = USB_LOW_SPEED_OPERATION;
-
- /* Get Controller configuration */
- if (cdev->gadget->ops->get_config_params)
- cdev->gadget->ops->get_config_params(&dcd_config_params);
- else {
- dcd_config_params.bU1devExitLat = USB_DEFAULT_U1_DEV_EXIT_LAT;
- dcd_config_params.bU2DevExitLat =
- cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT);
- }
- ss_cap->bU1devExitLat = dcd_config_params.bU1devExitLat;
- ss_cap->bU2DevExitLat = dcd_config_params.bU2DevExitLat;
-
- return le16_to_cpu(bos->wTotalLength);
-}
-
static void device_qual(struct usb_composite_dev *cdev)
{
struct usb_qualifier_descriptor *qual = cdev->req->buf;
@@ -573,7 +361,7 @@
qual->bDeviceSubClass = cdev->desc.bDeviceSubClass;
qual->bDeviceProtocol = cdev->desc.bDeviceProtocol;
/* ASSUME same EP0 fifo size at both speeds */
- qual->bMaxPacketSize0 = cdev->gadget->ep0->maxpacket;
+ qual->bMaxPacketSize0 = cdev->desc.bMaxPacketSize0;
qual->bNumConfigurations = count_configs(cdev, USB_DT_DEVICE_QUALIFIER);
qual->bRESERVED = 0;
}
@@ -604,46 +392,28 @@
unsigned power = gadget_is_otg(gadget) ? 8 : 100;
int tmp;
+ if (cdev->config)
+ reset_config(cdev);
+
if (number) {
list_for_each_entry(c, &cdev->configs, list) {
if (c->bConfigurationValue == number) {
- /*
- * We disable the FDs of the previous
- * configuration only if the new configuration
- * is a valid one
- */
- if (cdev->config)
- reset_config(cdev);
result = 0;
break;
}
}
if (result < 0)
goto done;
- } else { /* Zero configuration value - need to reset the config */
- if (cdev->config)
- reset_config(cdev);
+ } else
result = 0;
- }
INFO(cdev, "%s speed config #%d: %s\n",
({ char *speed;
switch (gadget->speed) {
- case USB_SPEED_LOW:
- speed = "low";
- break;
- case USB_SPEED_FULL:
- speed = "full";
- break;
- case USB_SPEED_HIGH:
- speed = "high";
- break;
- case USB_SPEED_SUPER:
- speed = "super";
- break;
- default:
- speed = "?";
- break;
+ case USB_SPEED_LOW: speed = "low"; break;
+ case USB_SPEED_FULL: speed = "full"; break;
+ case USB_SPEED_HIGH: speed = "high"; break;
+ default: speed = "?"; break;
} ; speed; }), number, c ? c->label : "unconfigured");
if (!c)
@@ -665,16 +435,10 @@
* function's setup callback instead of the current
* configuration's setup callback.
*/
- switch (gadget->speed) {
- case USB_SPEED_SUPER:
- descriptors = f->ss_descriptors;
- break;
- case USB_SPEED_HIGH:
+ if (gadget->speed == USB_SPEED_HIGH)
descriptors = f->hs_descriptors;
- break;
- default:
+ else
descriptors = f->descriptors;
- }
for (; *descriptors; ++descriptors) {
struct usb_endpoint_descriptor *ep;
@@ -769,9 +533,8 @@
} else {
unsigned i;
- DBG(cdev, "cfg %d/%p speeds:%s%s%s\n",
+ DBG(cdev, "cfg %d/%p speeds:%s%s\n",
config->bConfigurationValue, config,
- config->superspeed ? " super" : "",
config->highspeed ? " high" : "",
config->fullspeed
? (gadget_is_dualspeed(cdev->gadget)
@@ -1089,7 +852,6 @@
struct usb_composite_dev *cdev = get_gadget_data(gadget);
struct usb_request *req = cdev->req;
int value = -EOPNOTSUPP;
- int status = 0;
u16 w_index = le16_to_cpu(ctrl->wIndex);
u8 intf = w_index & 0xFF;
u16 w_value = le16_to_cpu(ctrl->wValue);
@@ -1121,29 +883,18 @@
case USB_DT_DEVICE:
cdev->desc.bNumConfigurations =
count_configs(cdev, USB_DT_DEVICE);
- cdev->desc.bMaxPacketSize0 =
- cdev->gadget->ep0->maxpacket;
- if (gadget_is_superspeed(gadget)) {
- if (gadget->speed >= USB_SPEED_SUPER)
- cdev->desc.bcdUSB = cpu_to_le16(0x0300);
- else
- cdev->desc.bcdUSB = cpu_to_le16(0x0210);
- }
-
value = min(w_length, (u16) sizeof cdev->desc);
memcpy(req->buf, &cdev->desc, value);
break;
case USB_DT_DEVICE_QUALIFIER:
- if (!gadget_is_dualspeed(gadget) ||
- gadget->speed >= USB_SPEED_SUPER)
+ if (!gadget_is_dualspeed(gadget))
break;
device_qual(cdev);
value = min_t(int, w_length,
sizeof(struct usb_qualifier_descriptor));
break;
case USB_DT_OTHER_SPEED_CONFIG:
- if (!gadget_is_dualspeed(gadget) ||
- gadget->speed >= USB_SPEED_SUPER)
+ if (!gadget_is_dualspeed(gadget))
break;
/* FALLTHROUGH */
case USB_DT_CONFIG:
@@ -1157,12 +908,6 @@
if (value >= 0)
value = min(w_length, (u16) value);
break;
- case USB_DT_BOS:
- if (gadget_is_superspeed(gadget)) {
- value = bos_desc(cdev);
- value = min(w_length, (u16) value);
- }
- break;
}
break;
@@ -1230,61 +975,6 @@
*((u8 *)req->buf) = value;
value = min(w_length, (u16) 1);
break;
-
- /*
- * USB 3.0 additions:
- * Function driver should handle get_status request. If such cb
- * wasn't supplied we respond with default value = 0
- * Note: function driver should supply such cb only for the first
- * interface of the function
- */
- case USB_REQ_GET_STATUS:
- if (!gadget_is_superspeed(gadget))
- goto unknown;
- if (ctrl->bRequestType != (USB_DIR_IN | USB_RECIP_INTERFACE))
- goto unknown;
- value = 2; /* This is the length of the get_status reply */
- put_unaligned_le16(0, req->buf);
- if (!cdev->config || intf >= MAX_CONFIG_INTERFACES)
- break;
- f = cdev->config->interface[intf];
- if (!f)
- break;
- status = f->get_status ? f->get_status(f) : 0;
- if (status < 0)
- break;
- put_unaligned_le16(status & 0x0000ffff, req->buf);
- break;
- /*
- * Function drivers should handle SetFeature/ClearFeature
- * (FUNCTION_SUSPEND) request. function_suspend cb should be supplied
- * only for the first interface of the function
- */
- case USB_REQ_CLEAR_FEATURE:
- case USB_REQ_SET_FEATURE:
- if (!gadget_is_superspeed(gadget))
- goto unknown;
- if (ctrl->bRequestType != (USB_DIR_OUT | USB_RECIP_INTERFACE))
- goto unknown;
- switch (w_value) {
- case USB_INTRF_FUNC_SUSPEND:
- if (!cdev->config || intf >= MAX_CONFIG_INTERFACES)
- break;
- f = cdev->config->interface[intf];
- if (!f)
- break;
- value = 0;
- if (f->func_suspend)
- value = f->func_suspend(f, w_index >> 8);
- if (value < 0) {
- ERROR(cdev,
- "func_suspend() returned error %d\n",
- value);
- value = 0;
- }
- break;
- }
- break;
default:
unknown:
VDBG(cdev,
@@ -1476,6 +1166,7 @@
goto fail;
cdev->desc = *composite->dev;
+ cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
/* standardized runtime overrides for device ID data */
if (idVendor)
@@ -1582,11 +1273,7 @@
/*-------------------------------------------------------------------------*/
static struct usb_gadget_driver composite_driver = {
-#ifdef CONFIG_USB_GADGET_SUPERSPEED
- .speed = USB_SPEED_SUPER,
-#else
.speed = USB_SPEED_HIGH,
-#endif
.unbind = composite_unbind,
@@ -1632,8 +1319,6 @@
driver->iProduct = driver->name;
composite_driver.function = (char *) driver->name;
composite_driver.driver.name = driver->name;
- composite_driver.speed = min((u8)composite_driver.speed,
- (u8)driver->max_speed);
composite = driver;
composite_gadget_bind = bind;
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c
index 7b3ae76..09084fd 100644
--- a/drivers/usb/gadget/config.c
+++ b/drivers/usb/gadget/config.c
@@ -164,3 +164,29 @@
return ret;
}
+
+/**
+ * usb_find_endpoint - find a copy of an endpoint descriptor
+ * @src: original vector of descriptors
+ * @copy: copy of @src
+ * @match: endpoint descriptor found in @src
+ *
+ * This returns the copy of the @match descriptor made for @copy. Its
+ * intended use is to help remembering the endpoint descriptor to use
+ * when enabling a given endpoint.
+ */
+struct usb_endpoint_descriptor *
+usb_find_endpoint(
+ struct usb_descriptor_header **src,
+ struct usb_descriptor_header **copy,
+ struct usb_endpoint_descriptor *match
+)
+{
+ while (*src) {
+ if (*src == (void *) match)
+ return (void *)*copy;
+ src++;
+ copy++;
+ }
+ return NULL;
+}
diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/dbgp.c
index 8beefdd..dbe92ee 100644
--- a/drivers/usb/gadget/dbgp.c
+++ b/drivers/usb/gadget/dbgp.c
@@ -173,9 +173,7 @@
static int __enable_ep(struct usb_ep *ep, struct usb_endpoint_descriptor *desc)
{
- int err;
- ep->desc = desc;
- err = usb_ep_enable(ep);
+ int err = usb_ep_enable(ep, desc);
ep->driver_data = dbgp.gadget;
return err;
}
@@ -270,8 +268,8 @@
dbgp.serial->in = dbgp.i_ep;
dbgp.serial->out = dbgp.o_ep;
- dbgp.serial->in->desc = &i_desc;
- dbgp.serial->out->desc = &o_desc;
+ dbgp.serial->in_desc = &i_desc;
+ dbgp.serial->out_desc = &o_desc;
if (gserial_setup(gadget, 1) < 0) {
stp = 3;
@@ -314,6 +312,7 @@
dbgp.req->length = DBGP_REQ_EP0_LEN;
gadget->ep0->driver_data = gadget;
+ device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
#ifdef CONFIG_USB_G_DBGP_SERIAL
dbgp.serial = kzalloc(sizeof(struct gserial), GFP_KERNEL);
@@ -364,7 +363,6 @@
dev_dbg(&dbgp.gadget->dev, "setup: desc device\n");
len = sizeof device_desc;
data = &device_desc;
- device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
break;
case USB_DT_DEBUG:
dev_dbg(&dbgp.gadget->dev, "setup: desc debug\n");
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index cbcb4c7..d3dcabc 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -425,18 +425,10 @@
(desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
({ char *val;
switch (desc->bmAttributes & 0x03) {
- case USB_ENDPOINT_XFER_BULK:
- val = "bulk";
- break;
- case USB_ENDPOINT_XFER_ISOC:
- val = "iso";
- break;
- case USB_ENDPOINT_XFER_INT:
- val = "intr";
- break;
- default:
- val = "ctrl";
- break;
+ case USB_ENDPOINT_XFER_BULK: val = "bulk"; break;
+ case USB_ENDPOINT_XFER_ISOC: val = "iso"; break;
+ case USB_ENDPOINT_XFER_INT: val = "intr"; break;
+ default: val = "ctrl"; break;
}; val; }),
max);
@@ -718,17 +710,11 @@
return 0;
}
-static int dummy_udc_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int dummy_udc_stop(struct usb_gadget_driver *driver);
-
static const struct usb_gadget_ops dummy_ops = {
.get_frame = dummy_g_get_frame,
.wakeup = dummy_wakeup,
.set_selfpowered = dummy_set_selfpowered,
.pullup = dummy_pullup,
- .start = dummy_udc_start,
- .stop = dummy_udc_stop,
};
/*-------------------------------------------------------------------------*/
@@ -761,7 +747,8 @@
* for each driver that registers: just add to a big root hub.
*/
-static int dummy_udc_start(struct usb_gadget_driver *driver,
+int
+usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct dummy *dum = the_controller;
@@ -825,8 +812,10 @@
usb_hcd_poll_rh_status (dummy_to_hcd (dum));
return 0;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
-static int dummy_udc_stop(struct usb_gadget_driver *driver)
+int
+usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
{
struct dummy *dum = the_controller;
unsigned long flags;
@@ -856,6 +845,7 @@
usb_hcd_poll_rh_status (dummy_to_hcd (dum));
return 0;
}
+EXPORT_SYMBOL (usb_gadget_unregister_driver);
#undef is_enabled
@@ -902,20 +892,11 @@
return rc;
}
- rc = usb_add_gadget_udc(&pdev->dev, &dum->gadget);
- if (rc < 0)
- goto err_udc;
-
rc = device_create_file (&dum->gadget.dev, &dev_attr_function);
if (rc < 0)
- goto err_dev;
- platform_set_drvdata(pdev, dum);
- return rc;
-
-err_dev:
- usb_del_gadget_udc(&dum->gadget);
-err_udc:
- device_unregister(&dum->gadget.dev);
+ device_unregister (&dum->gadget.dev);
+ else
+ platform_set_drvdata(pdev, dum);
return rc;
}
@@ -923,7 +904,6 @@
{
struct dummy *dum = platform_get_drvdata (pdev);
- usb_del_gadget_udc(&dum->gadget);
platform_set_drvdata (pdev, NULL);
device_remove_file (&dum->gadget.dev, &dev_attr_function);
device_unregister (&dum->gadget.dev);
@@ -1806,34 +1786,18 @@
urb,
({ char *s;
switch (urb->dev->speed) {
- case USB_SPEED_LOW:
- s = "ls";
- break;
- case USB_SPEED_FULL:
- s = "fs";
- break;
- case USB_SPEED_HIGH:
- s = "hs";
- break;
- default:
- s = "?";
- break;
+ case USB_SPEED_LOW: s = "ls"; break;
+ case USB_SPEED_FULL: s = "fs"; break;
+ case USB_SPEED_HIGH: s = "hs"; break;
+ default: s = "?"; break;
}; s; }),
ep, ep ? (usb_pipein (urb->pipe) ? "in" : "out") : "",
({ char *s; \
switch (usb_pipetype (urb->pipe)) { \
- case PIPE_CONTROL: \
- s = ""; \
- break; \
- case PIPE_BULK: \
- s = "-bulk"; \
- break; \
- case PIPE_INTERRUPT: \
- s = "-int"; \
- break; \
- default: \
- s = "-iso"; \
- break; \
+ case PIPE_CONTROL: s = ""; break; \
+ case PIPE_BULK: s = "-bulk"; break; \
+ case PIPE_INTERRUPT: s = "-int"; break; \
+ default: s = "-iso"; break; \
}; s;}),
urb->actual_length, urb->transfer_buffer_length);
}
@@ -1899,6 +1863,7 @@
dum = hcd_to_dummy (hcd);
device_remove_file (dummy_dev(dum), &dev_attr_urbs);
+ usb_gadget_unregister_driver (dum->driver);
dev_info (dummy_dev(dum), "stopped\n");
}
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index 2fcfb9b..9b7360f 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -63,16 +63,13 @@
ep_matches (
struct usb_gadget *gadget,
struct usb_ep *ep,
- struct usb_endpoint_descriptor *desc,
- struct usb_ss_ep_comp_descriptor *ep_comp
+ struct usb_endpoint_descriptor *desc
)
{
u8 type;
const char *tmp;
u16 max;
- int num_req_streams = 0;
-
/* endpoint already claimed? */
if (NULL != ep->driver_data)
return 0;
@@ -132,19 +129,6 @@
}
/*
- * Get the number of required streams from the EP companion
- * descriptor and see if the EP matches it
- */
- if (usb_endpoint_xfer_bulk(desc)) {
- if (ep_comp) {
- num_req_streams = ep_comp->bmAttributes & 0x1f;
- if (num_req_streams > ep->max_streams)
- return 0;
- }
-
- }
-
- /*
* If the protocol driver hasn't yet decided on wMaxPacketSize
* and wants to know the maximum possible, provide the info.
*/
@@ -158,13 +142,13 @@
max = 0x7ff & le16_to_cpu(desc->wMaxPacketSize);
switch (type) {
case USB_ENDPOINT_XFER_INT:
- /* INT: limit 64 bytes full speed, 1024 high/super speed */
+ /* INT: limit 64 bytes full speed, 1024 high speed */
if (!gadget->is_dualspeed && max > 64)
return 0;
/* FALLTHROUGH */
case USB_ENDPOINT_XFER_ISOC:
- /* ISO: limit 1023 bytes full speed, 1024 high/super speed */
+ /* ISO: limit 1023 bytes full speed, 1024 high speed */
if (ep->maxpacket < max)
return 0;
if (!gadget->is_dualspeed && max > 1023)
@@ -199,7 +183,7 @@
}
/* report (variable) full speed bulk maxpacket */
- if ((USB_ENDPOINT_XFER_BULK == type) && !ep_comp) {
+ if (USB_ENDPOINT_XFER_BULK == type) {
int size = ep->maxpacket;
/* min() doesn't work on bitfields with gcc-3.5 */
@@ -207,7 +191,6 @@
size = 64;
desc->wMaxPacketSize = cpu_to_le16(size);
}
- ep->address = desc->bEndpointAddress;
return 1;
}
@@ -224,120 +207,7 @@
}
/**
- * usb_ep_autoconfig_ss() - choose an endpoint matching the ep
- * descriptor and ep companion descriptor
- * @gadget: The device to which the endpoint must belong.
- * @desc: Endpoint descriptor, with endpoint direction and transfer mode
- * initialized. For periodic transfers, the maximum packet
- * size must also be initialized. This is modified on
- * success.
- * @ep_comp: Endpoint companion descriptor, with the required
- * number of streams. Will be modified when the chosen EP
- * supports a different number of streams.
- *
- * This routine replaces the usb_ep_autoconfig when needed
- * superspeed enhancments. If such enhancemnets are required,
- * the FD should call usb_ep_autoconfig_ss directly and provide
- * the additional ep_comp parameter.
- *
- * By choosing an endpoint to use with the specified descriptor,
- * this routine simplifies writing gadget drivers that work with
- * multiple USB device controllers. The endpoint would be
- * passed later to usb_ep_enable(), along with some descriptor.
- *
- * That second descriptor won't always be the same as the first one.
- * For example, isochronous endpoints can be autoconfigured for high
- * bandwidth, and then used in several lower bandwidth altsettings.
- * Also, high and full speed descriptors will be different.
- *
- * Be sure to examine and test the results of autoconfiguration
- * on your hardware. This code may not make the best choices
- * about how to use the USB controller, and it can't know all
- * the restrictions that may apply. Some combinations of driver
- * and hardware won't be able to autoconfigure.
- *
- * On success, this returns an un-claimed usb_ep, and modifies the endpoint
- * descriptor bEndpointAddress. For bulk endpoints, the wMaxPacket value
- * is initialized as if the endpoint were used at full speed and
- * the bmAttribute field in the ep companion descriptor is
- * updated with the assigned number of streams if it is
- * different from the original value. To prevent the endpoint
- * from being returned by a later autoconfig call, claim it by
- * assigning ep->driver_data to some non-null value.
- *
- * On failure, this returns a null endpoint descriptor.
- */
-struct usb_ep *usb_ep_autoconfig_ss(
- struct usb_gadget *gadget,
- struct usb_endpoint_descriptor *desc,
- struct usb_ss_ep_comp_descriptor *ep_comp
-)
-{
- struct usb_ep *ep;
- u8 type;
-
- type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
-
- /* First, apply chip-specific "best usage" knowledge.
- * This might make a good usb_gadget_ops hook ...
- */
- if (gadget_is_net2280 (gadget) && type == USB_ENDPOINT_XFER_INT) {
- /* ep-e, ep-f are PIO with only 64 byte fifos */
- ep = find_ep (gadget, "ep-e");
- if (ep && ep_matches(gadget, ep, desc, ep_comp))
- return ep;
- ep = find_ep (gadget, "ep-f");
- if (ep && ep_matches(gadget, ep, desc, ep_comp))
- return ep;
-
- } else if (gadget_is_goku (gadget)) {
- if (USB_ENDPOINT_XFER_INT == type) {
- /* single buffering is enough */
- ep = find_ep(gadget, "ep3-bulk");
- if (ep && ep_matches(gadget, ep, desc, ep_comp))
- return ep;
- } else if (USB_ENDPOINT_XFER_BULK == type
- && (USB_DIR_IN & desc->bEndpointAddress)) {
- /* DMA may be available */
- ep = find_ep(gadget, "ep2-bulk");
- if (ep && ep_matches(gadget, ep, desc,
- ep_comp))
- return ep;
- }
-
-#ifdef CONFIG_BLACKFIN
- } else if (gadget_is_musbhdrc(gadget)) {
- if ((USB_ENDPOINT_XFER_BULK == type) ||
- (USB_ENDPOINT_XFER_ISOC == type)) {
- if (USB_DIR_IN & desc->bEndpointAddress)
- ep = find_ep (gadget, "ep5in");
- else
- ep = find_ep (gadget, "ep6out");
- } else if (USB_ENDPOINT_XFER_INT == type) {
- if (USB_DIR_IN & desc->bEndpointAddress)
- ep = find_ep(gadget, "ep1in");
- else
- ep = find_ep(gadget, "ep2out");
- } else
- ep = NULL;
- if (ep && ep_matches(gadget, ep, desc, ep_comp))
- return ep;
-#endif
- }
-
- /* Second, look at endpoints until an unclaimed one looks usable */
- list_for_each_entry (ep, &gadget->ep_list, ep_list) {
- if (ep_matches(gadget, ep, desc, ep_comp))
- return ep;
- }
-
- /* Fail */
- return NULL;
-}
-
-/**
- * usb_ep_autoconfig() - choose an endpoint matching the
- * descriptor
+ * usb_ep_autoconfig - choose an endpoint matching the descriptor
* @gadget: The device to which the endpoint must belong.
* @desc: Endpoint descriptor, with endpoint direction and transfer mode
* initialized. For periodic transfers, the maximum packet
@@ -366,14 +236,71 @@
*
* On failure, this returns a null endpoint descriptor.
*/
-struct usb_ep *usb_ep_autoconfig(
+struct usb_ep *usb_ep_autoconfig (
struct usb_gadget *gadget,
struct usb_endpoint_descriptor *desc
)
{
- return usb_ep_autoconfig_ss(gadget, desc, NULL);
-}
+ struct usb_ep *ep;
+ u8 type;
+ type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+
+ /* First, apply chip-specific "best usage" knowledge.
+ * This might make a good usb_gadget_ops hook ...
+ */
+ if (gadget_is_net2280 (gadget) && type == USB_ENDPOINT_XFER_INT) {
+ /* ep-e, ep-f are PIO with only 64 byte fifos */
+ ep = find_ep (gadget, "ep-e");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ ep = find_ep (gadget, "ep-f");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+
+ } else if (gadget_is_goku (gadget)) {
+ if (USB_ENDPOINT_XFER_INT == type) {
+ /* single buffering is enough */
+ ep = find_ep (gadget, "ep3-bulk");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ } else if (USB_ENDPOINT_XFER_BULK == type
+ && (USB_DIR_IN & desc->bEndpointAddress)) {
+ /* DMA may be available */
+ ep = find_ep (gadget, "ep2-bulk");
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+ }
+
+#ifdef CONFIG_BLACKFIN
+ } else if (gadget_is_musbhdrc(gadget)) {
+ if ((USB_ENDPOINT_XFER_BULK == type) ||
+ (USB_ENDPOINT_XFER_ISOC == type)) {
+ if (USB_DIR_IN & desc->bEndpointAddress)
+ ep = find_ep (gadget, "ep5in");
+ else
+ ep = find_ep (gadget, "ep6out");
+ } else if (USB_ENDPOINT_XFER_INT == type) {
+ if (USB_DIR_IN & desc->bEndpointAddress)
+ ep = find_ep(gadget, "ep1in");
+ else
+ ep = find_ep(gadget, "ep2out");
+ } else
+ ep = NULL;
+ if (ep && ep_matches (gadget, ep, desc))
+ return ep;
+#endif
+ }
+
+ /* Second, look at endpoints until an unclaimed one looks usable */
+ list_for_each_entry (ep, &gadget->ep_list, ep_list) {
+ if (ep_matches (gadget, ep, desc))
+ return ep;
+ }
+
+ /* Fail */
+ return NULL;
+}
/**
* usb_ep_autoconfig_reset - reset endpoint autoconfig state
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index ac41858..1690c9d 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -401,7 +401,6 @@
.name = "g_ether",
.dev = &device_desc,
.strings = dev_strings,
- .max_speed = USB_SPEED_HIGH,
.unbind = __exit_p(eth_unbind),
};
diff --git a/drivers/usb/gadget/f_accessory.c b/drivers/usb/gadget/f_accessory.c
index 0187b69..05e65e5 100644
--- a/drivers/usb/gadget/f_accessory.c
+++ b/drivers/usb/gadget/f_accessory.c
@@ -686,33 +686,17 @@
int ret;
DBG(cdev, "acc_function_set_alt intf: %d alt: %d\n", intf, alt);
-
- ret = config_ep_by_speed(cdev->gadget, f, dev->ep_in);
- if (ret) {
- dev->ep_in->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
- dev->ep_in->name, ret);
- return ret;
- }
- ret = usb_ep_enable(dev->ep_in);
- if (ret) {
- ERROR(cdev, "failed to enable ep %s, result %d\n",
- dev->ep_in->name, ret);
+ ret = usb_ep_enable(dev->ep_in,
+ ep_choose(cdev->gadget,
+ &acc_highspeed_in_desc,
+ &acc_fullspeed_in_desc));
+ if (ret)
return ret;
- }
-
- ret = config_ep_by_speed(cdev->gadget, f, dev->ep_out);
+ ret = usb_ep_enable(dev->ep_out,
+ ep_choose(cdev->gadget,
+ &acc_highspeed_out_desc,
+ &acc_fullspeed_out_desc));
if (ret) {
- dev->ep_out->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
- dev->ep_out->name, ret);
- usb_ep_disable(dev->ep_in);
- return ret;
- }
- ret = usb_ep_enable(dev->ep_out);
- if (ret) {
- ERROR(cdev, "failed to enable ep %s, result %d\n",
- dev->ep_out->name, ret);
usb_ep_disable(dev->ep_in);
return ret;
}
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index a30126f..69a36af 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -42,6 +42,12 @@
* descriptors (roughly equivalent to CDC Unions) may sometimes help.
*/
+struct acm_ep_descs {
+ struct usb_endpoint_descriptor *in;
+ struct usb_endpoint_descriptor *out;
+ struct usb_endpoint_descriptor *notify;
+};
+
struct f_acm {
struct gserial port;
u8 ctrl_id, data_id;
@@ -56,7 +62,11 @@
*/
spinlock_t lock;
+ struct acm_ep_descs fs;
+ struct acm_ep_descs hs;
+
struct usb_ep *notify;
+ struct usb_endpoint_descriptor *notify_desc;
struct usb_request *notify_req;
struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */
@@ -487,10 +497,10 @@
} else {
VDBG(cdev, "init acm ctrl interface %d\n", intf);
}
- if (config_ep_by_speed(cdev->gadget, f, acm->notify))
- return -EINVAL;
-
- usb_ep_enable(acm->notify);
+ acm->notify_desc = ep_choose(cdev->gadget,
+ acm->hs.notify,
+ acm->fs.notify);
+ usb_ep_enable(acm->notify, acm->notify_desc);
acm->notify->driver_data = acm;
} else if (intf == acm->data_id) {
@@ -500,15 +510,10 @@
} else {
DBG(cdev, "activate acm ttyGS%d\n", acm->port_num);
}
- if (config_ep_by_speed(cdev->gadget, f,
- acm->port.in) ||
- config_ep_by_speed(cdev->gadget, f,
- acm->port.out)) {
- acm->port.in->desc = NULL;
- acm->port.out->desc = NULL;
- return -EINVAL;
- }
-
+ acm->port.in_desc = ep_choose(cdev->gadget,
+ acm->hs.in, acm->fs.in);
+ acm->port.out_desc = ep_choose(cdev->gadget,
+ acm->hs.out, acm->fs.out);
acm_port_connect(acm);
} else
@@ -724,11 +729,18 @@
acm->notify_req->complete = acm_cdc_notify_complete;
acm->notify_req->context = acm;
- /* copy descriptors */
+ /* copy descriptors, and track endpoint copies */
f->descriptors = usb_copy_descriptors(acm_fs_function);
if (!f->descriptors)
goto fail;
+ acm->fs.in = usb_find_endpoint(acm_fs_function,
+ f->descriptors, &acm_fs_in_desc);
+ acm->fs.out = usb_find_endpoint(acm_fs_function,
+ f->descriptors, &acm_fs_out_desc);
+ acm->fs.notify = usb_find_endpoint(acm_fs_function,
+ f->descriptors, &acm_fs_notify_desc);
+
/* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
@@ -741,8 +753,15 @@
acm_hs_notify_desc.bEndpointAddress =
acm_fs_notify_desc.bEndpointAddress;
- /* copy descriptors */
+ /* copy descriptors, and track endpoint copies */
f->hs_descriptors = usb_copy_descriptors(acm_hs_function);
+
+ acm->hs.in = usb_find_endpoint(acm_hs_function,
+ f->hs_descriptors, &acm_hs_in_desc);
+ acm->hs.out = usb_find_endpoint(acm_hs_function,
+ f->hs_descriptors, &acm_hs_out_desc);
+ acm->hs.notify = usb_find_endpoint(acm_hs_function,
+ f->hs_descriptors, &acm_hs_notify_desc);
}
DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n",
diff --git a/drivers/usb/gadget/f_adb.c b/drivers/usb/gadget/f_adb.c
index 0cf6d48..cae0136 100644
--- a/drivers/usb/gadget/f_adb.c
+++ b/drivers/usb/gadget/f_adb.c
@@ -510,33 +510,17 @@
int ret;
DBG(cdev, "adb_function_set_alt intf: %d alt: %d\n", intf, alt);
-
- ret = config_ep_by_speed(cdev->gadget, f, dev->ep_in);
- if (ret) {
- dev->ep_in->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
- dev->ep_in->name, ret);
+ ret = usb_ep_enable(dev->ep_in,
+ ep_choose(cdev->gadget,
+ &adb_highspeed_in_desc,
+ &adb_fullspeed_in_desc));
+ if (ret)
return ret;
- }
- ret = usb_ep_enable(dev->ep_in);
+ ret = usb_ep_enable(dev->ep_out,
+ ep_choose(cdev->gadget,
+ &adb_highspeed_out_desc,
+ &adb_fullspeed_out_desc));
if (ret) {
- ERROR(cdev, "failed to enable ep %s, result %d\n",
- dev->ep_in->name, ret);
- return ret;
- }
-
- ret = config_ep_by_speed(cdev->gadget, f, dev->ep_out);
- if (ret) {
- dev->ep_out->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
- dev->ep_out->name, ret);
- usb_ep_disable(dev->ep_in);
- return ret;
- }
- ret = usb_ep_enable(dev->ep_out);
- if (ret) {
- ERROR(cdev, "failed to enable ep %s, result %d\n",
- dev->ep_out->name, ret);
usb_ep_disable(dev->ep_in);
return ret;
}
diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c
index 02a0270..8ee330a 100644
--- a/drivers/usb/gadget/f_audio.c
+++ b/drivers/usb/gadget/f_audio.c
@@ -279,6 +279,7 @@
/* endpoints handle full and/or high speeds */
struct usb_ep *out_ep;
+ struct usb_endpoint_descriptor *out_desc;
spinlock_t lock;
struct f_audio_buf *copy_buf;
@@ -574,7 +575,7 @@
if (intf == 1) {
if (alt == 1) {
- usb_ep_enable(out_ep);
+ usb_ep_enable(out_ep, audio->out_desc);
out_ep->driver_data = audio;
audio->copy_buf = f_audio_buffer_alloc(audio_buf_size);
if (IS_ERR(audio->copy_buf))
@@ -676,7 +677,6 @@
if (!ep)
goto fail;
audio->out_ep = ep;
- audio->out_ep->desc = &as_out_ep_desc;
ep->driver_data = cdev; /* claim */
status = -ENOMEM;
@@ -776,6 +776,7 @@
audio->card.func.set_alt = f_audio_set_alt;
audio->card.func.setup = f_audio_setup;
audio->card.func.disable = f_audio_disable;
+ audio->out_desc = &as_out_ep_desc;
control_selector_init(audio);
diff --git a/drivers/usb/gadget/f_ccid.c b/drivers/usb/gadget/f_ccid.c
index c8f144a..a11f439 100644
--- a/drivers/usb/gadget/f_ccid.c
+++ b/drivers/usb/gadget/f_ccid.c
@@ -33,6 +33,12 @@
/* number of tx requests to allocate */
#define TX_REQ_MAX 4
+struct ccid_descs {
+ struct usb_endpoint_descriptor *in;
+ struct usb_endpoint_descriptor *out;
+ struct usb_endpoint_descriptor *notify;
+};
+
struct ccid_ctrl_dev {
atomic_t opened;
struct list_head tx_q;
@@ -58,10 +64,16 @@
int ifc_id;
spinlock_t lock;
atomic_t online;
+ /* usb descriptors */
+ struct ccid_descs fs;
+ struct ccid_descs hs;
/* usb eps*/
struct usb_ep *notify;
struct usb_ep *in;
struct usb_ep *out;
+ struct usb_endpoint_descriptor *in_desc;
+ struct usb_endpoint_descriptor *out_desc;
+ struct usb_endpoint_descriptor *notify_desc;
struct usb_request *notify_req;
struct ccid_ctrl_dev ctrl_dev;
struct ccid_bulk_dev bulk_dev;
@@ -424,14 +436,10 @@
}
/* choose the descriptors and enable endpoints */
- ret = config_ep_by_speed(cdev->gadget, f, ccid_dev->notify);
- if (ret) {
- ccid_dev->notify->desc = NULL;
- pr_err("%s: config_ep_by_speed failed for ep#%s, err#%d\n",
- __func__, ccid_dev->notify->name, ret);
- goto free_bulk_in;
- }
- ret = usb_ep_enable(ccid_dev->notify);
+ ccid_dev->notify_desc = ep_choose(cdev->gadget,
+ ccid_dev->hs.notify,
+ ccid_dev->fs.notify);
+ ret = usb_ep_enable(ccid_dev->notify, ccid_dev->notify_desc);
if (ret) {
pr_err("%s: usb ep#%s enable failed, err#%d\n",
__func__, ccid_dev->notify->name, ret);
@@ -439,28 +447,18 @@
}
ccid_dev->notify->driver_data = ccid_dev;
- ret = config_ep_by_speed(cdev->gadget, f, ccid_dev->in);
- if (ret) {
- ccid_dev->in->desc = NULL;
- pr_err("%s: config_ep_by_speed failed for ep#%s, err#%d\n",
- __func__, ccid_dev->in->name, ret);
- goto disable_ep_notify;
- }
- ret = usb_ep_enable(ccid_dev->in);
+ ccid_dev->in_desc = ep_choose(cdev->gadget,
+ ccid_dev->hs.in, ccid_dev->fs.in);
+ ret = usb_ep_enable(ccid_dev->in, ccid_dev->in_desc);
if (ret) {
pr_err("%s: usb ep#%s enable failed, err#%d\n",
__func__, ccid_dev->in->name, ret);
goto disable_ep_notify;
}
- ret = config_ep_by_speed(cdev->gadget, f, ccid_dev->out);
- if (ret) {
- ccid_dev->out->desc = NULL;
- pr_err("%s: config_ep_by_speed failed for ep#%s, err#%d\n",
- __func__, ccid_dev->out->name, ret);
- goto disable_ep_in;
- }
- ret = usb_ep_enable(ccid_dev->out);
+ ccid_dev->out_desc = ep_choose(cdev->gadget,
+ ccid_dev->hs.out, ccid_dev->fs.out);
+ ret = usb_ep_enable(ccid_dev->out, ccid_dev->out_desc);
if (ret) {
pr_err("%s: usb ep#%s enable failed, err#%d\n",
__func__, ccid_dev->out->name, ret);
@@ -540,6 +538,16 @@
if (!f->descriptors)
goto ep_auto_out_fail;
+ ccid_dev->fs.in = usb_find_endpoint(ccid_fs_descs,
+ f->descriptors,
+ &ccid_fs_in_desc);
+ ccid_dev->fs.out = usb_find_endpoint(ccid_fs_descs,
+ f->descriptors,
+ &ccid_fs_out_desc);
+ ccid_dev->fs.notify = usb_find_endpoint(ccid_fs_descs,
+ f->descriptors,
+ &ccid_fs_notify_desc);
+
if (gadget_is_dualspeed(cdev->gadget)) {
ccid_hs_in_desc.bEndpointAddress =
ccid_fs_in_desc.bEndpointAddress;
@@ -552,6 +560,13 @@
f->hs_descriptors = usb_copy_descriptors(ccid_hs_descs);
if (!f->hs_descriptors)
goto ep_auto_out_fail;
+
+ ccid_dev->hs.in = usb_find_endpoint(ccid_hs_descs,
+ f->hs_descriptors, &ccid_hs_in_desc);
+ ccid_dev->hs.out = usb_find_endpoint(ccid_hs_descs,
+ f->hs_descriptors, &ccid_hs_out_desc);
+ ccid_dev->hs.notify = usb_find_endpoint(ccid_hs_descs,
+ f->hs_descriptors, &ccid_hs_notify_desc);
}
pr_debug("%s: CCID %s Speed, IN:%s OUT:%s\n", __func__,
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index c4c7941..987ae65 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -108,6 +108,8 @@
struct usb_function function;
struct usb_ep *out;
struct usb_ep *in;
+ struct usb_endpoint_descriptor *in_desc;
+ struct usb_endpoint_descriptor *out_desc;
struct list_head read_pool;
struct list_head write_pool;
struct work_struct config_work;
@@ -512,22 +514,21 @@
unsigned long flags;
int rc = 0;
- if (config_ep_by_speed(cdev->gadget, f, dev->in) ||
- config_ep_by_speed(cdev->gadget, f, dev->out)) {
- dev->in->desc = NULL;
- dev->out->desc = NULL;
- return -EINVAL;
- }
-
+ dev->in_desc = ep_choose(cdev->gadget,
+ (struct usb_endpoint_descriptor *)f->hs_descriptors[1],
+ (struct usb_endpoint_descriptor *)f->descriptors[1]);
+ dev->out_desc = ep_choose(cdev->gadget,
+ (struct usb_endpoint_descriptor *)f->hs_descriptors[2],
+ (struct usb_endpoint_descriptor *)f->descriptors[2]);
dev->in->driver_data = dev;
- rc = usb_ep_enable(dev->in);
+ rc = usb_ep_enable(dev->in, dev->in_desc);
if (rc) {
ERROR(dev->cdev, "can't enable %s, result %d\n",
dev->in->name, rc);
return rc;
}
dev->out->driver_data = dev;
- rc = usb_ep_enable(dev->out);
+ rc = usb_ep_enable(dev->out, dev->out_desc);
if (rc) {
ERROR(dev->cdev, "can't enable %s, result %d\n",
dev->out->name, rc);
@@ -629,7 +630,7 @@
/* claim the channel for this USB interface */
_ch->priv_usb = dev;
- dev->update_pid_and_serial_num = update_pid;
+ dev->update_pid_and_serial_num = update_pid;
dev->cdev = c->cdev;
dev->function.name = _ch->name;
dev->function.descriptors = fs_diag_desc;
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
index ddedbc83..544257a 100644
--- a/drivers/usb/gadget/f_ecm.c
+++ b/drivers/usb/gadget/f_ecm.c
@@ -46,6 +46,11 @@
* and also means that a get_alt() method is required.
*/
+struct ecm_ep_descs {
+ struct usb_endpoint_descriptor *in;
+ struct usb_endpoint_descriptor *out;
+ struct usb_endpoint_descriptor *notify;
+};
enum ecm_notify_state {
ECM_NOTIFY_NONE, /* don't notify */
@@ -59,7 +64,11 @@
char ethaddr[14];
+ struct ecm_ep_descs fs;
+ struct ecm_ep_descs hs;
+
struct usb_ep *notify;
+ struct usb_endpoint_descriptor *notify_desc;
struct usb_request *notify_req;
u8 notify_state;
bool is_open;
@@ -455,13 +464,13 @@
if (ecm->notify->driver_data) {
VDBG(cdev, "reset ecm control %d\n", intf);
usb_ep_disable(ecm->notify);
- }
- if (!(ecm->notify->desc)) {
+ } else {
VDBG(cdev, "init ecm ctrl %d\n", intf);
- if (config_ep_by_speed(cdev->gadget, f, ecm->notify))
- goto fail;
+ ecm->notify_desc = ep_choose(cdev->gadget,
+ ecm->hs.notify,
+ ecm->fs.notify);
}
- usb_ep_enable(ecm->notify);
+ usb_ep_enable(ecm->notify, ecm->notify_desc);
ecm->notify->driver_data = ecm;
/* Data interface has two altsettings, 0 and 1 */
@@ -474,17 +483,12 @@
gether_disconnect(&ecm->port);
}
- if (!ecm->port.in_ep->desc ||
- !ecm->port.out_ep->desc) {
+ if (!ecm->port.in) {
DBG(cdev, "init ecm\n");
- if (config_ep_by_speed(cdev->gadget, f,
- ecm->port.in_ep) ||
- config_ep_by_speed(cdev->gadget, f,
- ecm->port.out_ep)) {
- ecm->port.in_ep->desc = NULL;
- ecm->port.out_ep->desc = NULL;
- goto fail;
- }
+ ecm->port.in = ep_choose(cdev->gadget,
+ ecm->hs.in, ecm->fs.in);
+ ecm->port.out = ep_choose(cdev->gadget,
+ ecm->hs.out, ecm->fs.out);
}
/* CDC Ethernet only sends data in non-default altsettings.
@@ -545,7 +549,7 @@
if (ecm->notify->driver_data) {
usb_ep_disable(ecm->notify);
ecm->notify->driver_data = NULL;
- ecm->notify->desc = NULL;
+ ecm->notify_desc = NULL;
}
}
@@ -661,6 +665,13 @@
if (!f->descriptors)
goto fail;
+ ecm->fs.in = usb_find_endpoint(ecm_fs_function,
+ f->descriptors, &fs_ecm_in_desc);
+ ecm->fs.out = usb_find_endpoint(ecm_fs_function,
+ f->descriptors, &fs_ecm_out_desc);
+ ecm->fs.notify = usb_find_endpoint(ecm_fs_function,
+ f->descriptors, &fs_ecm_notify_desc);
+
/* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
@@ -677,6 +688,13 @@
f->hs_descriptors = usb_copy_descriptors(ecm_hs_function);
if (!f->hs_descriptors)
goto fail;
+
+ ecm->hs.in = usb_find_endpoint(ecm_hs_function,
+ f->hs_descriptors, &hs_ecm_in_desc);
+ ecm->hs.out = usb_find_endpoint(ecm_hs_function,
+ f->hs_descriptors, &hs_ecm_out_desc);
+ ecm->hs.notify = usb_find_endpoint(ecm_hs_function,
+ f->hs_descriptors, &hs_ecm_notify_desc);
}
/* NOTE: all that is done without knowing or caring about
@@ -705,9 +723,9 @@
/* we might as well release our claims on endpoints */
if (ecm->notify)
ecm->notify->driver_data = NULL;
- if (ecm->port.out_ep->desc)
+ if (ecm->port.out)
ecm->port.out_ep->driver_data = NULL;
- if (ecm->port.in_ep->desc)
+ if (ecm->port.in)
ecm->port.in_ep->driver_data = NULL;
ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
index 3e41274..b3c3042 100644
--- a/drivers/usb/gadget/f_eem.c
+++ b/drivers/usb/gadget/f_eem.c
@@ -35,9 +35,17 @@
* Ethernet link.
*/
+struct eem_ep_descs {
+ struct usb_endpoint_descriptor *in;
+ struct usb_endpoint_descriptor *out;
+};
+
struct f_eem {
struct gether port;
u8 ctrl_id;
+
+ struct eem_ep_descs fs;
+ struct eem_ep_descs hs;
};
static inline struct f_eem *func_to_eem(struct usb_function *f)
@@ -168,16 +176,12 @@
gether_disconnect(&eem->port);
}
- if (!eem->port.in_ep->desc || !eem->port.out_ep->desc) {
+ if (!eem->port.in) {
DBG(cdev, "init eem\n");
- if (config_ep_by_speed(cdev->gadget, f,
- eem->port.in_ep) ||
- config_ep_by_speed(cdev->gadget, f,
- eem->port.out_ep)) {
- eem->port.in_ep->desc = NULL;
- eem->port.out_ep->desc = NULL;
- goto fail;
- }
+ eem->port.in = ep_choose(cdev->gadget,
+ eem->hs.in, eem->fs.in);
+ eem->port.out = ep_choose(cdev->gadget,
+ eem->hs.out, eem->fs.out);
}
/* zlps should not occur because zero-length EEM packets
@@ -249,6 +253,11 @@
if (!f->descriptors)
goto fail;
+ eem->fs.in = usb_find_endpoint(eem_fs_function,
+ f->descriptors, &eem_fs_in_desc);
+ eem->fs.out = usb_find_endpoint(eem_fs_function,
+ f->descriptors, &eem_fs_out_desc);
+
/* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
@@ -263,6 +272,11 @@
f->hs_descriptors = usb_copy_descriptors(eem_hs_function);
if (!f->hs_descriptors)
goto fail;
+
+ eem->hs.in = usb_find_endpoint(eem_hs_function,
+ f->hs_descriptors, &eem_hs_in_desc);
+ eem->hs.out = usb_find_endpoint(eem_hs_function,
+ f->hs_descriptors, &eem_hs_out_desc);
}
DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n",
@@ -275,9 +289,9 @@
usb_free_descriptors(f->descriptors);
/* we might as well release our claims on endpoints */
- if (eem->port.out_ep->desc)
+ if (eem->port.out)
eem->port.out_ep->driver_data = NULL;
- if (eem->port.in_ep->desc)
+ if (eem->port.in)
eem->port.in_ep->driver_data = NULL;
ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index c161a9a..19fffcc 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -1544,8 +1544,7 @@
ds = ep->descs[ep->descs[1] ? 1 : 0];
ep->ep->driver_data = ep;
- ep->ep->desc = ds;
- ret = usb_ep_enable(ep->ep);
+ ret = usb_ep_enable(ep->ep, ds);
if (likely(!ret)) {
epfile->ep = ep;
epfile->in = usb_endpoint_dir_in(ds);
diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/f_hid.c
index 403a48b..598e7e2 100644
--- a/drivers/usb/gadget/f_hid.c
+++ b/drivers/usb/gadget/f_hid.c
@@ -59,6 +59,8 @@
struct cdev cdev;
struct usb_function func;
struct usb_ep *in_ep;
+ struct usb_endpoint_descriptor *fs_in_ep_desc;
+ struct usb_endpoint_descriptor *hs_in_ep_desc;
};
static inline struct f_hidg *func_to_hidg(struct usb_function *f)
@@ -414,6 +416,7 @@
{
struct usb_composite_dev *cdev = f->config->cdev;
struct f_hidg *hidg = func_to_hidg(f);
+ const struct usb_endpoint_descriptor *ep_desc;
int status = 0;
VDBG(cdev, "hidg_set_alt intf:%d alt:%d\n", intf, alt);
@@ -423,13 +426,9 @@
if (hidg->in_ep->driver_data != NULL)
usb_ep_disable(hidg->in_ep);
- status = config_ep_by_speed(f->config->cdev->gadget, f,
- hidg->in_ep);
- if (status) {
- ERROR(cdev, "config_ep_by_speed FAILED!\n");
- goto fail;
- }
- status = usb_ep_enable(hidg->in_ep);
+ ep_desc = ep_choose(f->config->cdev->gadget,
+ hidg->hs_in_ep_desc, hidg->fs_in_ep_desc);
+ status = usb_ep_enable(hidg->in_ep, ep_desc);
if (status < 0) {
ERROR(cdev, "Enable endpoint FAILED!\n");
goto fail;
@@ -499,12 +498,21 @@
if (!f->descriptors)
goto fail;
+ hidg->fs_in_ep_desc = usb_find_endpoint(hidg_fs_descriptors,
+ f->descriptors,
+ &hidg_fs_in_ep_desc);
+
if (gadget_is_dualspeed(c->cdev->gadget)) {
hidg_hs_in_ep_desc.bEndpointAddress =
hidg_fs_in_ep_desc.bEndpointAddress;
f->hs_descriptors = usb_copy_descriptors(hidg_hs_descriptors);
if (!f->hs_descriptors)
goto fail;
+ hidg->hs_in_ep_desc = usb_find_endpoint(hidg_hs_descriptors,
+ f->hs_descriptors,
+ &hidg_hs_in_ep_desc);
+ } else {
+ hidg->hs_in_ep_desc = NULL;
}
mutex_init(&hidg->lock);
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index 3756326..b37960f 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -250,27 +250,26 @@
enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop)
{
int result = 0;
+ const struct usb_endpoint_descriptor *src, *sink;
struct usb_ep *ep;
struct usb_request *req;
unsigned i;
+ src = ep_choose(cdev->gadget,
+ &hs_loop_source_desc, &fs_loop_source_desc);
+ sink = ep_choose(cdev->gadget,
+ &hs_loop_sink_desc, &fs_loop_sink_desc);
+
/* one endpoint writes data back IN to the host */
ep = loop->in_ep;
- result = config_ep_by_speed(cdev->gadget, &(loop->function), ep);
- if (result)
- return result;
- result = usb_ep_enable(ep);
+ result = usb_ep_enable(ep, src);
if (result < 0)
return result;
ep->driver_data = loop;
/* one endpoint just reads OUT packets */
ep = loop->out_ep;
- result = config_ep_by_speed(cdev->gadget, &(loop->function), ep);
- if (result)
- goto fail0;
-
- result = usb_ep_enable(ep);
+ result = usb_ep_enable(ep, sink);
if (result < 0) {
fail0:
ep = loop->in_ep;
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 3d35c78..55d9a307 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -112,7 +112,8 @@
* is not loaded (an empty string as "filename" in the fsg_config
* structure causes error). The CD-ROM emulation includes a single
* data track and no audio tracks; hence there need be only one
- * backing file per LUN.
+ * backing file per LUN. Note also that the CD-ROM block length is
+ * set to 512 rather than the more common value 2048.
*
*
* MSF includes support for module parameters. If gadget using it
@@ -748,6 +749,7 @@
u32 amount_left;
loff_t file_offset, file_offset_tmp;
unsigned int amount;
+ unsigned int partial_page;
ssize_t nread;
#ifdef CONFIG_USB_MSC_PROFILING
ktime_t start, diff;
@@ -776,7 +778,7 @@
curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
return -EINVAL;
}
- file_offset = ((loff_t) lba) << curlun->blkbits;
+ file_offset = ((loff_t) lba) << 9;
/* Carry out the file reads */
amount_left = common->data_size_from_cmnd;
@@ -789,10 +791,18 @@
* Try to read the remaining amount.
* But don't read more than the buffer size.
* And don't try to read past the end of the file.
+ * Finally, if we're not at a page boundary, don't read past
+ * the next page.
+ * If this means reading 0 then we were asked to read past
+ * the end of file.
*/
amount = min(amount_left, FSG_BUFLEN);
amount = min((loff_t)amount,
curlun->file_length - file_offset);
+ partial_page = file_offset & (PAGE_CACHE_SIZE - 1);
+ if (partial_page > 0)
+ amount = min(amount, (unsigned int)PAGE_CACHE_SIZE -
+ partial_page);
/* Wait for the next buffer to become available */
bh = common->next_buffhd_to_fill;
@@ -809,8 +819,7 @@
if (amount == 0) {
curlun->sense_data =
SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
- curlun->sense_data_info =
- file_offset >> curlun->blkbits;
+ curlun->sense_data_info = file_offset >> 9;
curlun->info_valid = 1;
bh->inreq->length = 0;
bh->state = BUF_STATE_FULL;
@@ -842,25 +851,18 @@
} else if (nread < amount) {
LDBG(curlun, "partial file read: %d/%u\n",
(int)nread, amount);
- nread = round_down(nread, curlun->blksize);
+ nread -= (nread & 511); /* Round down to a block */
}
file_offset += nread;
amount_left -= nread;
common->residue -= nread;
-
- /*
- * Except at the end of the transfer, nread will be
- * equal to the buffer size, which is divisible by the
- * bulk-in maxpacket size.
- */
bh->inreq->length = nread;
bh->state = BUF_STATE_FULL;
/* If an error occurred, report it and its position */
if (nread < amount) {
curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
- curlun->sense_data_info =
- file_offset >> curlun->blkbits;
+ curlun->sense_data_info = file_offset >> 9;
curlun->info_valid = 1;
break;
}
@@ -891,6 +893,7 @@
u32 amount_left_to_req, amount_left_to_write;
loff_t usb_offset, file_offset, file_offset_tmp;
unsigned int amount;
+ unsigned int partial_page;
ssize_t nwritten;
int rc;
@@ -941,7 +944,7 @@
/* Carry out the file writes */
get_some_more = 1;
- file_offset = usb_offset = ((loff_t) lba) << curlun->blkbits;
+ file_offset = usb_offset = ((loff_t) lba) << 9;
amount_left_to_req = common->data_size_from_cmnd;
amount_left_to_write = common->data_size_from_cmnd;
@@ -953,21 +956,41 @@
/*
* Figure out how much we want to get:
- * Try to get the remaining amount,
- * but not more than the buffer size.
+ * Try to get the remaining amount.
+ * But don't get more than the buffer size.
+ * And don't try to go past the end of the file.
+ * If we're not at a page boundary,
+ * don't go past the next page.
+ * If this means getting 0, then we were asked
+ * to write past the end of file.
+ * Finally, round down to a block boundary.
*/
amount = min(amount_left_to_req, FSG_BUFLEN);
+ amount = min((loff_t)amount,
+ curlun->file_length - usb_offset);
+ partial_page = usb_offset & (PAGE_CACHE_SIZE - 1);
+ if (partial_page > 0)
+ amount = min(amount,
+ (unsigned int)PAGE_CACHE_SIZE - partial_page);
- /* Beyond the end of the backing file? */
- if (usb_offset >= curlun->file_length) {
+ if (amount == 0) {
get_some_more = 0;
curlun->sense_data =
SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
- curlun->sense_data_info =
- usb_offset >> curlun->blkbits;
+ curlun->sense_data_info = usb_offset >> 9;
curlun->info_valid = 1;
continue;
}
+ amount -= amount & 511;
+ if (amount == 0) {
+
+ /*
+ * Why were we were asked to transfer a
+ * partial block?
+ */
+ get_some_more = 0;
+ continue;
+ }
/* Get the next buffer */
usb_offset += amount;
@@ -977,11 +1000,12 @@
get_some_more = 0;
/*
- * Except at the end of the transfer, amount will be
- * equal to the buffer size, which is divisible by
- * the bulk-out maxpacket size.
+ * amount is always divisible by 512, hence by
+ * the bulk-out maxpacket size
*/
- set_bulk_out_req_length(common, bh, amount);
+ bh->outreq->length = amount;
+ bh->bulk_out_intended_length = amount;
+ bh->outreq->short_not_ok = 1;
if (!start_out_transfer(common, bh))
/* Dunno what to do if common->fsg is NULL */
return -EIO;
@@ -1011,8 +1035,7 @@
/* Did something go wrong with the transfer? */
if (bh->outreq->status != 0) {
curlun->sense_data = SS_COMMUNICATION_FAILURE;
- curlun->sense_data_info =
- file_offset >> curlun->blkbits;
+ curlun->sense_data_info = file_offset >> 9;
curlun->info_valid = 1;
break;
}
@@ -1026,16 +1049,6 @@
amount = curlun->file_length - file_offset;
}
- /* Don't accept excess data. The spec doesn't say
- * what to do in this case. We'll ignore the error.
- */
- amount = min(amount, bh->bulk_out_intended_length);
-
- /* Don't write a partial block */
- amount = round_down(amount, curlun->blksize);
- if (amount == 0)
- goto empty_write;
-
/* Perform the write */
file_offset_tmp = file_offset;
#ifdef CONFIG_USB_MSC_PROFILING
@@ -1062,7 +1075,8 @@
} else if (nwritten < amount) {
LDBG(curlun, "partial file write: %d/%u\n",
(int)nwritten, amount);
- nwritten = round_down(nwritten, curlun->blksize);
+ nwritten -= (nwritten & 511);
+ /* Round down to a block */
}
file_offset += nwritten;
amount_left_to_write -= nwritten;
@@ -1071,8 +1085,7 @@
/* If an error occurred, report it and its position */
if (nwritten < amount) {
curlun->sense_data = SS_WRITE_ERROR;
- curlun->sense_data_info =
- file_offset >> curlun->blkbits;
+ curlun->sense_data_info = file_offset >> 9;
curlun->info_valid = 1;
#ifdef CONFIG_USB_CSW_HACK
write_error_after_csw_sent = 1;
@@ -1104,10 +1117,8 @@
}
}
#endif
-
- empty_write:
/* Did the host decide to stop early? */
- if (bh->outreq->actual < bh->bulk_out_intended_length) {
+ if (bh->outreq->actual != bh->outreq->length) {
common->short_packet_received = 1;
break;
}
@@ -1187,8 +1198,8 @@
return -EIO; /* No default reply */
/* Prepare to carry out the file verify */
- amount_left = verification_length << curlun->blkbits;
- file_offset = ((loff_t) lba) << curlun->blkbits;
+ amount_left = verification_length << 9;
+ file_offset = ((loff_t) lba) << 9;
/* Write out all the dirty buffers before invalidating them */
fsg_lun_fsync_sub(curlun);
@@ -1206,6 +1217,8 @@
* Try to read the remaining amount, but not more than
* the buffer size.
* And don't try to read past the end of the file.
+ * If this means reading 0 then we were asked to read
+ * past the end of file.
*/
amount = min(amount_left, FSG_BUFLEN);
amount = min((loff_t)amount,
@@ -1213,8 +1226,7 @@
if (amount == 0) {
curlun->sense_data =
SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
- curlun->sense_data_info =
- file_offset >> curlun->blkbits;
+ curlun->sense_data_info = file_offset >> 9;
curlun->info_valid = 1;
break;
}
@@ -1236,12 +1248,11 @@
} else if (nread < amount) {
LDBG(curlun, "partial file verify: %d/%u\n",
(int)nread, amount);
- nread = round_down(nread, curlun->blksize);
+ nread -= nread & 511; /* Round down to a sector */
}
if (nread == 0) {
curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
- curlun->sense_data_info =
- file_offset >> curlun->blkbits;
+ curlun->sense_data_info = file_offset >> 9;
curlun->info_valid = 1;
break;
}
@@ -1347,7 +1358,7 @@
put_unaligned_be32(curlun->num_sectors - 1, &buf[0]);
/* Max logical block */
- put_unaligned_be32(curlun->blksize, &buf[4]);/* Block length */
+ put_unaligned_be32(512, &buf[4]); /* Block length */
return 8;
}
@@ -1584,7 +1595,7 @@
put_unaligned_be32(curlun->num_sectors, &buf[0]);
/* Number of blocks */
- put_unaligned_be32(curlun->blksize, &buf[4]);/* Block length */
+ put_unaligned_be32(512, &buf[4]); /* Block length */
buf[4] = 0x02; /* Current capacity */
return 12;
}
@@ -1664,7 +1675,7 @@
common->next_buffhd_to_drain = bh->next;
/* A short packet or an error ends everything */
- if (bh->outreq->actual < bh->bulk_out_intended_length ||
+ if (bh->outreq->actual != bh->outreq->length ||
bh->outreq->status != 0) {
raise_exception(common,
FSG_STATE_ABORT_BULK_OUT);
@@ -1680,11 +1691,12 @@
amount = min(common->usb_amount_left, FSG_BUFLEN);
/*
- * Except at the end of the transfer, amount will be
- * equal to the buffer size, which is divisible by
+ * amount is always divisible by 512, hence by
* the bulk-out maxpacket size.
*/
- set_bulk_out_req_length(common, bh, amount);
+ bh->outreq->length = amount;
+ bh->bulk_out_intended_length = amount;
+ bh->outreq->short_not_ok = 1;
if (!start_out_transfer(common, bh))
/* Dunno what to do if common->fsg is NULL */
return -EIO;
@@ -2091,8 +2103,7 @@
case READ_6:
i = common->cmnd[4];
- common->data_size_from_cmnd = (i == 0 ? 256 : i) <<
- common->curlun->blkbits;
+ common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
reply = check_command(common, 6, DATA_DIR_TO_HOST,
(7<<1) | (1<<4), 1,
"READ(6)");
@@ -2102,8 +2113,7 @@
case READ_10:
common->data_size_from_cmnd =
- get_unaligned_be16(&common->cmnd[7]) <<
- common->curlun->blkbits;
+ get_unaligned_be16(&common->cmnd[7]) << 9;
reply = check_command(common, 10, DATA_DIR_TO_HOST,
(1<<1) | (0xf<<2) | (3<<7), 1,
"READ(10)");
@@ -2113,8 +2123,7 @@
case READ_12:
common->data_size_from_cmnd =
- get_unaligned_be32(&common->cmnd[6]) <<
- common->curlun->blkbits;
+ get_unaligned_be32(&common->cmnd[6]) << 9;
reply = check_command(common, 12, DATA_DIR_TO_HOST,
(1<<1) | (0xf<<2) | (0xf<<6), 1,
"READ(12)");
@@ -2214,8 +2223,7 @@
case WRITE_6:
i = common->cmnd[4];
- common->data_size_from_cmnd = (i == 0 ? 256 : i) <<
- common->curlun->blkbits;
+ common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
reply = check_command(common, 6, DATA_DIR_FROM_HOST,
(7<<1) | (1<<4), 1,
"WRITE(6)");
@@ -2225,8 +2233,7 @@
case WRITE_10:
common->data_size_from_cmnd =
- get_unaligned_be16(&common->cmnd[7]) <<
- common->curlun->blkbits;
+ get_unaligned_be16(&common->cmnd[7]) << 9;
reply = check_command(common, 10, DATA_DIR_FROM_HOST,
(1<<1) | (0xf<<2) | (3<<7), 1,
"WRITE(10)");
@@ -2236,8 +2243,7 @@
case WRITE_12:
common->data_size_from_cmnd =
- get_unaligned_be32(&common->cmnd[6]) <<
- common->curlun->blkbits;
+ get_unaligned_be32(&common->cmnd[6]) << 9;
reply = check_command(common, 12, DATA_DIR_FROM_HOST,
(1<<1) | (0xf<<2) | (0xf<<6), 1,
"WRITE(12)");
@@ -2372,6 +2378,7 @@
/* Queue a request to read a Bulk-only CBW */
set_bulk_out_req_length(common, bh, USB_BULK_CB_WRAP_LEN);
+ bh->outreq->short_not_ok = 1;
if (!start_out_transfer(common, bh))
/* Don't know what to do if common->fsg is NULL */
return -EIO;
@@ -2398,6 +2405,18 @@
/*-------------------------------------------------------------------------*/
+static int enable_endpoint(struct fsg_common *common, struct usb_ep *ep,
+ const struct usb_endpoint_descriptor *d)
+{
+ int rc;
+
+ ep->driver_data = common;
+ rc = usb_ep_enable(ep, d);
+ if (rc)
+ ERROR(common, "can't enable %s, result %d\n", ep->name, rc);
+ return rc;
+}
+
static int alloc_request(struct fsg_common *common, struct usb_ep *ep,
struct usb_request **preq)
{
@@ -2447,6 +2466,7 @@
common->fsg = new_fsg;
fsg = common->fsg;
+
/* Allocate the requests */
for (i = 0; i < FSG_NUM_BUFFERS; ++i) {
struct fsg_buffhd *bh = &common->buffhds[i];
@@ -2476,37 +2496,31 @@
{
struct fsg_dev *fsg = fsg_from_func(f);
struct fsg_common *common = fsg->common;
+ const struct usb_endpoint_descriptor *d;
int rc;
/* Enable the endpoints */
- rc = config_ep_by_speed(common->gadget, &(fsg->function), fsg->bulk_in);
+ d = fsg_ep_desc(common->gadget,
+ &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc);
+ rc = enable_endpoint(common, fsg->bulk_in, d);
if (rc)
return rc;
- rc = usb_ep_enable(fsg->bulk_in);
- if (rc)
- return rc;
- fsg->bulk_in->driver_data = common;
fsg->bulk_in_enabled = 1;
- rc = config_ep_by_speed(common->gadget, &(fsg->function),
- fsg->bulk_out);
- if (rc)
- goto reset_bulk_int;
- rc = usb_ep_enable(fsg->bulk_out);
- if (rc)
- goto reset_bulk_int;
- fsg->bulk_out->driver_data = common;
+ d = fsg_ep_desc(common->gadget,
+ &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc);
+ rc = enable_endpoint(common, fsg->bulk_out, d);
+ if (rc) {
+ usb_ep_disable(fsg->bulk_in);
+ fsg->bulk_in_enabled = 0;
+ return rc;
+ }
fsg->bulk_out_enabled = 1;
- common->bulk_out_maxpacket = le16_to_cpu(fsg->bulk_in->desc->wMaxPacketSize);
+ common->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize);
clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
fsg->common->new_fsg = fsg;
raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
return USB_GADGET_DELAYED_STATUS;
-
-reset_bulk_int:
- usb_ep_disable(fsg->bulk_in);
- fsg->bulk_in_enabled = 0;
- return rc;
}
static void fsg_disable(struct usb_function *f)
@@ -3073,7 +3087,6 @@
fsg_common_put(common);
usb_free_descriptors(fsg->function.descriptors);
usb_free_descriptors(fsg->function.hs_descriptors);
- usb_free_descriptors(fsg->function.ss_descriptors);
kfree(fsg);
}
@@ -3124,28 +3137,6 @@
}
}
- if (gadget_is_superspeed(gadget)) {
- unsigned max_burst;
-
- /* Calculate bMaxBurst, we know packet size is 1024 */
- max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15);
-
- fsg_ss_bulk_in_desc.bEndpointAddress =
- fsg_fs_bulk_in_desc.bEndpointAddress;
- fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
-
- fsg_ss_bulk_out_desc.bEndpointAddress =
- fsg_fs_bulk_out_desc.bEndpointAddress;
- fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
-
- f->ss_descriptors = usb_copy_descriptors(fsg_ss_function);
- if (unlikely(!f->ss_descriptors)) {
- usb_free_descriptors(f->hs_descriptors);
- usb_free_descriptors(f->descriptors);
- return -ENOMEM;
- }
- }
-
return 0;
autoconf_fail:
diff --git a/drivers/usb/gadget/f_mtp.c b/drivers/usb/gadget/f_mtp.c
index 447e815..2829231 100644
--- a/drivers/usb/gadget/f_mtp.c
+++ b/drivers/usb/gadget/f_mtp.c
@@ -1132,38 +1132,21 @@
int ret;
DBG(cdev, "mtp_function_set_alt intf: %d alt: %d\n", intf, alt);
-
- ret = config_ep_by_speed(cdev->gadget, f, dev->ep_in);
- if (ret) {
- dev->ep_in->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
- dev->ep_in->name, ret);
+ ret = usb_ep_enable(dev->ep_in,
+ ep_choose(cdev->gadget,
+ &mtp_highspeed_in_desc,
+ &mtp_fullspeed_in_desc));
+ if (ret)
return ret;
- }
- ret = usb_ep_enable(dev->ep_in);
+ ret = usb_ep_enable(dev->ep_out,
+ ep_choose(cdev->gadget,
+ &mtp_highspeed_out_desc,
+ &mtp_fullspeed_out_desc));
if (ret) {
- ERROR(cdev, "failed to enable ep %s, result %d\n",
- dev->ep_in->name, ret);
- return ret;
- }
-
- ret = config_ep_by_speed(cdev->gadget, f, dev->ep_out);
- if (ret) {
- dev->ep_out->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
- dev->ep_out->name, ret);
usb_ep_disable(dev->ep_in);
return ret;
}
- ret = usb_ep_enable(dev->ep_out);
- if (ret) {
- ERROR(cdev, "failed to enable ep %s, result %d\n",
- dev->ep_out->name, ret);
- usb_ep_disable(dev->ep_in);
- return ret;
- }
- dev->ep_intr->desc = &mtp_intr_desc;
- ret = usb_ep_enable(dev->ep_intr);
+ ret = usb_ep_enable(dev->ep_intr, &mtp_intr_desc);
if (ret) {
usb_ep_disable(dev->ep_out);
usb_ep_disable(dev->ep_in);
diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c
index ae69ed7..86902a6 100644
--- a/drivers/usb/gadget/f_ncm.c
+++ b/drivers/usb/gadget/f_ncm.c
@@ -48,6 +48,12 @@
#define NCM_NDP_HDR_CRC 0x01000000
#define NCM_NDP_HDR_NOCRC 0x00000000
+struct ncm_ep_descs {
+ struct usb_endpoint_descriptor *in;
+ struct usb_endpoint_descriptor *out;
+ struct usb_endpoint_descriptor *notify;
+};
+
enum ncm_notify_state {
NCM_NOTIFY_NONE, /* don't notify */
NCM_NOTIFY_CONNECT, /* issue CONNECT next */
@@ -60,7 +66,11 @@
char ethaddr[14];
+ struct ncm_ep_descs fs;
+ struct ncm_ep_descs hs;
+
struct usb_ep *notify;
+ struct usb_endpoint_descriptor *notify_desc;
struct usb_request *notify_req;
u8 notify_state;
bool is_open;
@@ -792,14 +802,13 @@
if (ncm->notify->driver_data) {
DBG(cdev, "reset ncm control %d\n", intf);
usb_ep_disable(ncm->notify);
- }
-
- if (!(ncm->notify->desc)) {
+ } else {
DBG(cdev, "init ncm ctrl %d\n", intf);
- if (config_ep_by_speed(cdev->gadget, f, ncm->notify))
- goto fail;
+ ncm->notify_desc = ep_choose(cdev->gadget,
+ ncm->hs.notify,
+ ncm->fs.notify);
}
- usb_ep_enable(ncm->notify);
+ usb_ep_enable(ncm->notify, ncm->notify_desc);
ncm->notify->driver_data = ncm;
/* Data interface has two altsettings, 0 and 1 */
@@ -820,17 +829,14 @@
if (alt == 1) {
struct net_device *net;
- if (!ncm->port.in_ep->desc ||
- !ncm->port.out_ep->desc) {
+ if (!ncm->port.in) {
DBG(cdev, "init ncm\n");
- if (config_ep_by_speed(cdev->gadget, f,
- ncm->port.in_ep) ||
- config_ep_by_speed(cdev->gadget, f,
- ncm->port.out_ep)) {
- ncm->port.in_ep->desc = NULL;
- ncm->port.out_ep->desc = NULL;
- goto fail;
- }
+ ncm->port.in = ep_choose(cdev->gadget,
+ ncm->hs.in,
+ ncm->fs.in);
+ ncm->port.out = ep_choose(cdev->gadget,
+ ncm->hs.out,
+ ncm->fs.out);
}
/* TODO */
@@ -1105,7 +1111,7 @@
if (ncm->notify->driver_data) {
usb_ep_disable(ncm->notify);
ncm->notify->driver_data = NULL;
- ncm->notify->desc = NULL;
+ ncm->notify_desc = NULL;
}
}
@@ -1222,6 +1228,13 @@
if (!f->descriptors)
goto fail;
+ ncm->fs.in = usb_find_endpoint(ncm_fs_function,
+ f->descriptors, &fs_ncm_in_desc);
+ ncm->fs.out = usb_find_endpoint(ncm_fs_function,
+ f->descriptors, &fs_ncm_out_desc);
+ ncm->fs.notify = usb_find_endpoint(ncm_fs_function,
+ f->descriptors, &fs_ncm_notify_desc);
+
/*
* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
@@ -1239,6 +1252,13 @@
f->hs_descriptors = usb_copy_descriptors(ncm_hs_function);
if (!f->hs_descriptors)
goto fail;
+
+ ncm->hs.in = usb_find_endpoint(ncm_hs_function,
+ f->hs_descriptors, &hs_ncm_in_desc);
+ ncm->hs.out = usb_find_endpoint(ncm_hs_function,
+ f->hs_descriptors, &hs_ncm_out_desc);
+ ncm->hs.notify = usb_find_endpoint(ncm_hs_function,
+ f->hs_descriptors, &hs_ncm_notify_desc);
}
/*
@@ -1268,9 +1288,9 @@
/* we might as well release our claims on endpoints */
if (ncm->notify)
ncm->notify->driver_data = NULL;
- if (ncm->port.out_ep->desc)
+ if (ncm->port.out)
ncm->port.out_ep->driver_data = NULL;
- if (ncm->port.in_ep->desc)
+ if (ncm->port.in)
ncm->port.in_ep->driver_data = NULL;
ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c
index 394502a..8f8c643 100644
--- a/drivers/usb/gadget/f_obex.c
+++ b/drivers/usb/gadget/f_obex.c
@@ -39,12 +39,20 @@
* ready to handle the commands.
*/
+struct obex_ep_descs {
+ struct usb_endpoint_descriptor *obex_in;
+ struct usb_endpoint_descriptor *obex_out;
+};
+
struct f_obex {
struct gserial port;
u8 ctrl_id;
u8 data_id;
u8 port_num;
u8 can_activate;
+
+ struct obex_ep_descs fs;
+ struct obex_ep_descs hs;
};
static inline struct f_obex *func_to_obex(struct usb_function *f)
@@ -219,16 +227,12 @@
gserial_disconnect(&obex->port);
}
- if (!obex->port.in->desc || !obex->port.out->desc) {
+ if (!obex->port.in_desc) {
DBG(cdev, "init obex ttyGS%d\n", obex->port_num);
- if (config_ep_by_speed(cdev->gadget, f,
- obex->port.in) ||
- config_ep_by_speed(cdev->gadget, f,
- obex->port.out)) {
- obex->port.out->desc = NULL;
- obex->port.in->desc = NULL;
- goto fail;
- }
+ obex->port.in_desc = ep_choose(cdev->gadget,
+ obex->hs.obex_in, obex->fs.obex_in);
+ obex->port.out_desc = ep_choose(cdev->gadget,
+ obex->hs.obex_out, obex->fs.obex_out);
}
if (alt == 1) {
@@ -342,6 +346,11 @@
/* copy descriptors, and track endpoint copies */
f->descriptors = usb_copy_descriptors(fs_function);
+ obex->fs.obex_in = usb_find_endpoint(fs_function,
+ f->descriptors, &obex_fs_ep_in_desc);
+ obex->fs.obex_out = usb_find_endpoint(fs_function,
+ f->descriptors, &obex_fs_ep_out_desc);
+
/* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
@@ -355,6 +364,11 @@
/* copy descriptors, and track endpoint copies */
f->hs_descriptors = usb_copy_descriptors(hs_function);
+
+ obex->hs.obex_in = usb_find_endpoint(hs_function,
+ f->hs_descriptors, &obex_hs_ep_in_desc);
+ obex->hs.obex_out = usb_find_endpoint(hs_function,
+ f->hs_descriptors, &obex_hs_ep_out_desc);
}
/* Avoid letting this gadget enumerate until the userspace
diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
index 0d6d260..5e14950 100644
--- a/drivers/usb/gadget/f_phonet.c
+++ b/drivers/usb/gadget/f_phonet.c
@@ -427,16 +427,17 @@
spin_lock(&port->lock);
__pn_reset(f);
if (alt == 1) {
+ struct usb_endpoint_descriptor *out, *in;
int i;
- if (config_ep_by_speed(gadget, f, fp->in_ep) ||
- config_ep_by_speed(gadget, f, fp->out_ep)) {
- fp->in_ep->desc = NULL;
- fp->out_ep->desc = NULL;
- return -EINVAL;
- }
- usb_ep_enable(fp->out_ep);
- usb_ep_enable(fp->in_ep);
+ out = ep_choose(gadget,
+ &pn_hs_sink_desc,
+ &pn_fs_sink_desc);
+ in = ep_choose(gadget,
+ &pn_hs_source_desc,
+ &pn_fs_source_desc);
+ usb_ep_enable(fp->out_ep, out);
+ usb_ep_enable(fp->in_ep, in);
port->usb = fp;
fp->out_ep->driver_data = fp;
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index cc26c85..d846c4e 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -25,6 +25,11 @@
#define RMNET_NOTIFY_INTERVAL 5
#define RMNET_MAX_NOTIFY_SIZE sizeof(struct usb_cdc_notification)
+struct rmnet_descs {
+ struct usb_endpoint_descriptor *in;
+ struct usb_endpoint_descriptor *out;
+ struct usb_endpoint_descriptor *notify;
+};
#define ACM_CTRL_DTR (1 << 0)
@@ -41,8 +46,13 @@
spinlock_t lock;
+ /* usb descriptors */
+ struct rmnet_descs fs;
+ struct rmnet_descs hs;
+
/* usb eps*/
struct usb_ep *notify;
+ struct usb_endpoint_descriptor *notify_desc;
struct usb_request *notify_req;
/* control info */
@@ -471,16 +481,10 @@
pr_debug("%s: reset port:%d\n", __func__, dev->port_num);
usb_ep_disable(dev->notify);
}
-
- ret = config_ep_by_speed(cdev->gadget, f, dev->notify);
- if (ret) {
- dev->notify->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
- dev->notify->name, ret);
- return ret;
- }
- ret = usb_ep_enable(dev->notify);
-
+ dev->notify_desc = ep_choose(cdev->gadget,
+ dev->hs.notify,
+ dev->fs.notify);
+ ret = usb_ep_enable(dev->notify, dev->notify_desc);
if (ret) {
pr_err("%s: usb ep#%s enable failed, err#%d\n",
__func__, dev->notify->name, ret);
@@ -493,12 +497,10 @@
gport_rmnet_disconnect(dev);
}
- if (config_ep_by_speed(cdev->gadget, f, dev->port.in) ||
- config_ep_by_speed(cdev->gadget, f, dev->port.out)) {
- dev->port.in->desc = NULL;
- dev->port.out->desc = NULL;
- return -EINVAL;
- }
+ dev->port.in_desc = ep_choose(cdev->gadget,
+ dev->hs.in, dev->fs.in);
+ dev->port.out_desc = ep_choose(cdev->gadget,
+ dev->hs.out, dev->fs.out);
ret = gport_rmnet_connect(dev);
@@ -852,6 +854,16 @@
if (!f->descriptors)
goto fail;
+ dev->fs.in = usb_find_endpoint(rmnet_fs_function,
+ f->descriptors,
+ &rmnet_fs_in_desc);
+ dev->fs.out = usb_find_endpoint(rmnet_fs_function,
+ f->descriptors,
+ &rmnet_fs_out_desc);
+ dev->fs.notify = usb_find_endpoint(rmnet_fs_function,
+ f->descriptors,
+ &rmnet_fs_notify_desc);
+
if (gadget_is_dualspeed(cdev->gadget)) {
rmnet_hs_in_desc.bEndpointAddress =
rmnet_fs_in_desc.bEndpointAddress;
@@ -865,6 +877,13 @@
if (!f->hs_descriptors)
goto fail;
+
+ dev->hs.in = usb_find_endpoint(rmnet_hs_function,
+ f->hs_descriptors, &rmnet_hs_in_desc);
+ dev->hs.out = usb_find_endpoint(rmnet_hs_function,
+ f->hs_descriptors, &rmnet_hs_out_desc);
+ dev->hs.notify = usb_find_endpoint(rmnet_hs_function,
+ f->hs_descriptors, &rmnet_hs_notify_desc);
}
pr_info("%s: RmNet(%d) %s Speed, IN:%s OUT:%s\n",
diff --git a/drivers/usb/gadget/f_rmnet_sdio.c b/drivers/usb/gadget/f_rmnet_sdio.c
index 8019356..f63d939 100644
--- a/drivers/usb/gadget/f_rmnet_sdio.c
+++ b/drivers/usb/gadget/f_rmnet_sdio.c
@@ -1255,58 +1255,17 @@
struct usb_composite_dev *cdev = dev->cdev;
int ret = 0;
- /* Enable epin */
dev->epin->driver_data = dev;
- ret = config_ep_by_speed(cdev->gadget, f, dev->epin);
- if (ret) {
- dev->epin->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
- dev->epin->name, ret);
- return ret;
- }
- ret = usb_ep_enable(dev->epin);
- if (ret) {
- ERROR(cdev, "can't enable %s, result %d\n",
- dev->epin->name, ret);
- return ret;
- }
-
- /* Enable epout */
+ usb_ep_enable(dev->epin, ep_choose(cdev->gadget,
+ &rmnet_sdio_hs_in_desc,
+ &rmnet_sdio_fs_in_desc));
dev->epout->driver_data = dev;
- ret = config_ep_by_speed(cdev->gadget, f, dev->epout);
- if (ret) {
- dev->epout->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
- dev->epout->name, ret);
- usb_ep_disable(dev->epin);
- return ret;
- }
- ret = usb_ep_enable(dev->epout);
- if (ret) {
- ERROR(cdev, "can't enable %s, result %d\n",
- dev->epout->name, ret);
- usb_ep_disable(dev->epin);
- return ret;
- }
-
- /* Enable epnotify */
- ret = config_ep_by_speed(cdev->gadget, f, dev->epnotify);
- if (ret) {
- dev->epnotify->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
- dev->epnotify->name, ret);
- usb_ep_disable(dev->epin);
- usb_ep_disable(dev->epout);
- return ret;
- }
- ret = usb_ep_enable(dev->epnotify);
- if (ret) {
- ERROR(cdev, "can't enable %s, result %d\n",
- dev->epnotify->name, ret);
- usb_ep_disable(dev->epin);
- usb_ep_disable(dev->epout);
- return ret;
- }
+ usb_ep_enable(dev->epout, ep_choose(cdev->gadget,
+ &rmnet_sdio_hs_out_desc,
+ &rmnet_sdio_fs_out_desc));
+ usb_ep_enable(dev->epnotify, ep_choose(cdev->gadget,
+ &rmnet_sdio_hs_notify_desc,
+ &rmnet_sdio_fs_notify_desc));
/* allocate notification */
dev->notify_req = rmnet_sdio_alloc_req(dev->epnotify,
diff --git a/drivers/usb/gadget/f_rmnet_smd.c b/drivers/usb/gadget/f_rmnet_smd.c
index b71f646..2049dc0 100644
--- a/drivers/usb/gadget/f_rmnet_smd.c
+++ b/drivers/usb/gadget/f_rmnet_smd.c
@@ -956,32 +956,17 @@
struct usb_composite_dev *cdev = dev->cdev;
int ret = 0;
- /* Enable epin endpoint */
- ret = config_ep_by_speed(cdev->gadget, f, dev->epin);
- if (ret) {
- dev->epin->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failed for ep %s, result %d\n",
- dev->epin->name, ret);
- return ret;
- }
- ret = usb_ep_enable(dev->epin);
+ ret = usb_ep_enable(dev->epin, ep_choose(cdev->gadget,
+ &rmnet_smd_hs_in_desc,
+ &rmnet_smd_fs_in_desc));
if (ret) {
ERROR(cdev, "can't enable %s, result %d\n",
dev->epin->name, ret);
return ret;
}
-
- /* Enable epout endpoint */
- ret = config_ep_by_speed(cdev->gadget, f, dev->epout);
- if (ret) {
- dev->epout->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failed for ep %s, result %d\n",
- dev->epout->name, ret);
- usb_ep_disable(dev->epin);
- return ret;
- }
- ret = usb_ep_enable(dev->epout);
-
+ ret = usb_ep_enable(dev->epout, ep_choose(cdev->gadget,
+ &rmnet_smd_hs_out_desc,
+ &rmnet_smd_fs_out_desc));
if (ret) {
ERROR(cdev, "can't enable %s, result %d\n",
dev->epout->name, ret);
@@ -989,17 +974,9 @@
return ret;
}
- /* Enable epnotify endpoint */
- ret = config_ep_by_speed(cdev->gadget, f, dev->epnotify);
- if (ret) {
- dev->epnotify->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failed for ep %s, result %d\n",
- dev->epnotify->name, ret);
- usb_ep_disable(dev->epin);
- usb_ep_disable(dev->epout);
- return ret;
- }
- ret = usb_ep_enable(dev->epnotify);
+ ret = usb_ep_enable(dev->epnotify, ep_choose(cdev->gadget,
+ &rmnet_smd_hs_notify_desc,
+ &rmnet_smd_fs_notify_desc));
if (ret) {
ERROR(cdev, "can't enable %s, result %d\n",
dev->epnotify->name, ret);
diff --git a/drivers/usb/gadget/f_rmnet_smd_sdio.c b/drivers/usb/gadget/f_rmnet_smd_sdio.c
index 175afe3..e39125d 100644
--- a/drivers/usb/gadget/f_rmnet_smd_sdio.c
+++ b/drivers/usb/gadget/f_rmnet_smd_sdio.c
@@ -1354,7 +1354,6 @@
function);
struct rmnet_mux_sdio_dev *sdio_dev = &dev->sdio_dev;
struct usb_composite_dev *cdev = dev->cdev;
- int ret = 0;
/* allocate notification */
dev->notify_req = rmnet_mux_alloc_req(dev->epnotify,
@@ -1366,59 +1365,18 @@
dev->notify_req->complete = rmnet_mux_notify_complete;
dev->notify_req->context = dev;
dev->notify_req->length = RMNET_MUX_SDIO_MAX_NFY_SZE;
+ usb_ep_enable(dev->epnotify, ep_choose(cdev->gadget,
+ &rmnet_mux_hs_notify_desc,
+ &rmnet_mux_fs_notify_desc));
- /* Enable epin */
dev->epin->driver_data = dev;
- ret = config_ep_by_speed(cdev->gadget, f, dev->epin);
- if (ret) {
- dev->epin->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
- dev->epin->name, ret);
- return ret;
- }
- ret = usb_ep_enable(dev->epin);
- if (ret) {
- ERROR(cdev, "can't enable %s, result %d\n",
- dev->epin->name, ret);
- return ret;
- }
-
- /* Enable epout */
+ usb_ep_enable(dev->epin, ep_choose(cdev->gadget,
+ &rmnet_mux_hs_in_desc,
+ &rmnet_mux_fs_in_desc));
dev->epout->driver_data = dev;
- ret = config_ep_by_speed(cdev->gadget, f, dev->epout);
- if (ret) {
- dev->epout->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
- dev->epout->name, ret);
- usb_ep_disable(dev->epin);
- return ret;
- }
- ret = usb_ep_enable(dev->epout);
- if (ret) {
- ERROR(cdev, "can't enable %s, result %d\n",
- dev->epout->name, ret);
- usb_ep_disable(dev->epin);
- return ret;
- }
-
- /* Enable epnotify */
- ret = config_ep_by_speed(cdev->gadget, f, dev->epnotify);
- if (ret) {
- dev->epnotify->desc = NULL;
- ERROR(cdev, "config_ep_by_speed failes for ep %s, result %d\n",
- dev->epnotify->name, ret);
- usb_ep_disable(dev->epin);
- usb_ep_disable(dev->epout);
- return ret;
- }
- ret = usb_ep_enable(dev->epnotify);
- if (ret) {
- ERROR(cdev, "can't enable %s, result %d\n",
- dev->epnotify->name, ret);
- usb_ep_disable(dev->epin);
- usb_ep_disable(dev->epout);
- return ret;
- }
+ usb_ep_enable(dev->epout, ep_choose(cdev->gadget,
+ &rmnet_mux_hs_out_desc,
+ &rmnet_mux_fs_out_desc));
dev->dpkts_tolaptop = 0;
dev->cpkts_tolaptop = 0;
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 4a74dcf..d03b11b 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -76,6 +76,12 @@
* - MS-Windows drivers sometimes emit undocumented requests.
*/
+struct rndis_ep_descs {
+ struct usb_endpoint_descriptor *in;
+ struct usb_endpoint_descriptor *out;
+ struct usb_endpoint_descriptor *notify;
+};
+
struct f_rndis {
struct gether port;
u8 ctrl_id, data_id;
@@ -84,7 +90,12 @@
const char *manufacturer;
int config;
+
+ struct rndis_ep_descs fs;
+ struct rndis_ep_descs hs;
+
struct usb_ep *notify;
+ struct usb_endpoint_descriptor *notify_desc;
struct usb_request *notify_req;
atomic_t notify_count;
};
@@ -475,13 +486,13 @@
if (rndis->notify->driver_data) {
VDBG(cdev, "reset rndis control %d\n", intf);
usb_ep_disable(rndis->notify);
- }
- if (!rndis->notify->desc) {
+ } else {
VDBG(cdev, "init rndis ctrl %d\n", intf);
- if (config_ep_by_speed(cdev->gadget, f, rndis->notify))
- goto fail;
}
- usb_ep_enable(rndis->notify);
+ rndis->notify_desc = ep_choose(cdev->gadget,
+ rndis->hs.notify,
+ rndis->fs.notify);
+ usb_ep_enable(rndis->notify, rndis->notify_desc);
rndis->notify->driver_data = rndis;
} else if (intf == rndis->data_id) {
@@ -492,17 +503,13 @@
gether_disconnect(&rndis->port);
}
- if (!rndis->port.in_ep->desc || !rndis->port.out_ep->desc) {
+ if (!rndis->port.in) {
DBG(cdev, "init rndis\n");
- if (config_ep_by_speed(cdev->gadget, f,
- rndis->port.in_ep) ||
- config_ep_by_speed(cdev->gadget, f,
- rndis->port.out_ep)) {
- rndis->port.in_ep->desc = NULL;
- rndis->port.out_ep->desc = NULL;
- goto fail;
- }
}
+ rndis->port.in = ep_choose(cdev->gadget,
+ rndis->hs.in, rndis->fs.in);
+ rndis->port.out = ep_choose(cdev->gadget,
+ rndis->hs.out, rndis->fs.out);
/* Avoid ZLPs; they can be troublesome. */
rndis->port.is_zlp_ok = false;
@@ -657,6 +664,13 @@
if (!f->descriptors)
goto fail;
+ rndis->fs.in = usb_find_endpoint(eth_fs_function,
+ f->descriptors, &fs_in_desc);
+ rndis->fs.out = usb_find_endpoint(eth_fs_function,
+ f->descriptors, &fs_out_desc);
+ rndis->fs.notify = usb_find_endpoint(eth_fs_function,
+ f->descriptors, &fs_notify_desc);
+
/* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
@@ -674,6 +688,13 @@
if (!f->hs_descriptors)
goto fail;
+
+ rndis->hs.in = usb_find_endpoint(eth_hs_function,
+ f->hs_descriptors, &hs_in_desc);
+ rndis->hs.out = usb_find_endpoint(eth_hs_function,
+ f->hs_descriptors, &hs_out_desc);
+ rndis->hs.notify = usb_find_endpoint(eth_hs_function,
+ f->hs_descriptors, &hs_notify_desc);
}
rndis->port.open = rndis_open;
@@ -716,9 +737,9 @@
/* we might as well release our claims on endpoints */
if (rndis->notify)
rndis->notify->driver_data = NULL;
- if (rndis->port.out_ep->desc)
+ if (rndis->port.out)
rndis->port.out_ep->driver_data = NULL;
- if (rndis->port.in_ep->desc)
+ if (rndis->port.in)
rndis->port.in_ep->driver_data = NULL;
ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index ebd1580..de8c8ed 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -29,12 +29,21 @@
*/
#define GSERIAL_NO_PORTS 2
+struct gser_descs {
+ struct usb_endpoint_descriptor *in;
+ struct usb_endpoint_descriptor *out;
+#ifdef CONFIG_MODEM_SUPPORT
+ struct usb_endpoint_descriptor *notify;
+#endif
+};
struct f_gser {
struct gserial port;
u8 data_id;
u8 port_num;
+ struct gser_descs fs;
+ struct gser_descs hs;
u8 online;
enum transport_type transport;
@@ -42,6 +51,7 @@
u8 pending;
spinlock_t lock;
struct usb_ep *notify;
+ struct usb_endpoint_descriptor *notify_desc;
struct usb_request *notify_req;
struct usb_cdc_line_coding port_line_coding;
@@ -468,16 +478,10 @@
DBG(cdev, "reset generic ctl ttyGS%d\n", gser->port_num);
usb_ep_disable(gser->notify);
}
-
- if (!gser->notify->desc) {
- if (config_ep_by_speed(cdev->gadget, f, gser->notify)) {
- gser->notify->desc = NULL;
- return -EINVAL;
- }
- }
-
- rc = usb_ep_enable(gser->notify);
-
+ gser->notify_desc = ep_choose(cdev->gadget,
+ gser->hs.notify,
+ gser->fs.notify);
+ rc = usb_ep_enable(gser->notify, gser->notify_desc);
if (rc) {
ERROR(cdev, "can't enable %s, result %d\n",
gser->notify->name, rc);
@@ -489,16 +493,14 @@
if (gser->port.in->driver_data) {
DBG(cdev, "reset generic data ttyGS%d\n", gser->port_num);
gport_disconnect(gser);
+ } else {
+ DBG(cdev, "activate generic data ttyGS%d\n", gser->port_num);
}
- if (!gser->port.in->desc || !gser->port.out->desc) {
- DBG(cdev, "activate generic ttyGS%d\n", gser->port_num);
- if (config_ep_by_speed(cdev->gadget, f, gser->port.in) ||
- config_ep_by_speed(cdev->gadget, f, gser->port.out)) {
- gser->port.in->desc = NULL;
- gser->port.out->desc = NULL;
- return -EINVAL;
- }
- }
+ gser->port.in_desc = ep_choose(cdev->gadget,
+ gser->hs.in, gser->fs.in);
+ gser->port.out_desc = ep_choose(cdev->gadget,
+ gser->hs.out, gser->fs.out);
+
gport_connect(gser);
gser->online = 1;
@@ -742,6 +744,16 @@
if (!f->descriptors)
goto fail;
+ gser->fs.in = usb_find_endpoint(gser_fs_function,
+ f->descriptors, &gser_fs_in_desc);
+ gser->fs.out = usb_find_endpoint(gser_fs_function,
+ f->descriptors, &gser_fs_out_desc);
+#ifdef CONFIG_MODEM_SUPPORT
+ gser->fs.notify = usb_find_endpoint(gser_fs_function,
+ f->descriptors, &gser_fs_notify_desc);
+#endif
+
+
/* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
@@ -762,6 +774,14 @@
if (!f->hs_descriptors)
goto fail;
+ gser->hs.in = usb_find_endpoint(gser_hs_function,
+ f->hs_descriptors, &gser_hs_in_desc);
+ gser->hs.out = usb_find_endpoint(gser_hs_function,
+ f->hs_descriptors, &gser_hs_out_desc);
+#ifdef CONFIG_MODEM_SUPPORT
+ gser->hs.notify = usb_find_endpoint(gser_hs_function,
+ f->hs_descriptors, &gser_hs_notify_desc);
+#endif
}
DBG(cdev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n",
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
index caf2f95..e403a53 100644
--- a/drivers/usb/gadget/f_sourcesink.c
+++ b/drivers/usb/gadget/f_sourcesink.c
@@ -343,14 +343,15 @@
enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss)
{
int result = 0;
+ const struct usb_endpoint_descriptor *src, *sink;
struct usb_ep *ep;
+ src = ep_choose(cdev->gadget, &hs_source_desc, &fs_source_desc);
+ sink = ep_choose(cdev->gadget, &hs_sink_desc, &fs_sink_desc);
+
/* one endpoint writes (sources) zeroes IN (to the host) */
ep = ss->in_ep;
- result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
- if (result)
- return result;
- result = usb_ep_enable(ep);
+ result = usb_ep_enable(ep, src);
if (result < 0)
return result;
ep->driver_data = ss;
@@ -366,10 +367,7 @@
/* one endpoint reads (sinks) anything OUT (from the host) */
ep = ss->out_ep;
- result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
- if (result)
- goto fail;
- result = usb_ep_enable(ep);
+ result = usb_ep_enable(ep, sink);
if (result < 0)
goto fail;
ep->driver_data = ss;
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
index 93bf676..8675ca4 100644
--- a/drivers/usb/gadget/f_subset.c
+++ b/drivers/usb/gadget/f_subset.c
@@ -57,10 +57,18 @@
* caring about specific product and vendor IDs.
*/
+struct geth_descs {
+ struct usb_endpoint_descriptor *in;
+ struct usb_endpoint_descriptor *out;
+};
+
struct f_gether {
struct gether port;
char ethaddr[14];
+
+ struct geth_descs fs;
+ struct geth_descs hs;
};
static inline struct f_gether *func_to_geth(struct usb_function *f)
@@ -235,12 +243,10 @@
}
DBG(cdev, "init + activate cdc subset\n");
- if (config_ep_by_speed(cdev->gadget, f, geth->port.in_ep) ||
- config_ep_by_speed(cdev->gadget, f, geth->port.out_ep)) {
- geth->port.in_ep->desc = NULL;
- geth->port.out_ep->desc = NULL;
- return -EINVAL;
- }
+ geth->port.in = ep_choose(cdev->gadget,
+ geth->hs.in, geth->fs.in);
+ geth->port.out = ep_choose(cdev->gadget,
+ geth->hs.out, geth->fs.out);
net = gether_connect(&geth->port);
return IS_ERR(net) ? PTR_ERR(net) : 0;
@@ -291,6 +297,12 @@
/* copy descriptors, and track endpoint copies */
f->descriptors = usb_copy_descriptors(fs_eth_function);
+ geth->fs.in = usb_find_endpoint(fs_eth_function,
+ f->descriptors, &fs_subset_in_desc);
+ geth->fs.out = usb_find_endpoint(fs_eth_function,
+ f->descriptors, &fs_subset_out_desc);
+
+
/* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
@@ -303,6 +315,11 @@
/* copy descriptors, and track endpoint copies */
f->hs_descriptors = usb_copy_descriptors(hs_eth_function);
+
+ geth->hs.in = usb_find_endpoint(hs_eth_function,
+ f->hs_descriptors, &hs_subset_in_desc);
+ geth->hs.out = usb_find_endpoint(hs_eth_function,
+ f->hs_descriptors, &hs_subset_out_desc);
}
/* NOTE: all that is done without knowing or caring about
@@ -317,9 +334,9 @@
fail:
/* we might as well release our claims on endpoints */
- if (geth->port.out_ep->desc)
+ if (geth->port.out)
geth->port.out_ep->driver_data = NULL;
- if (geth->port.in_ep->desc)
+ if (geth->port.in)
geth->port.in_ep->driver_data = NULL;
ERROR(cdev, "%s: can't bind, err %d\n", f->name, status);
diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c
index df74d03..be446b7 100644
--- a/drivers/usb/gadget/f_uvc.c
+++ b/drivers/usb/gadget/f_uvc.c
@@ -262,10 +262,8 @@
if (uvc->state != UVC_STATE_CONNECTED)
return 0;
- if (uvc->video.ep) {
- uvc->video.ep->desc = &uvc_streaming_ep;
- usb_ep_enable(uvc->video.ep);
- }
+ if (uvc->video.ep)
+ usb_ep_enable(uvc->video.ep, &uvc_streaming_ep);
memset(&v4l2_event, 0, sizeof(v4l2_event));
v4l2_event.type = UVC_EVENT_STREAMON;
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index b17ecd8..0360f56 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -69,7 +69,8 @@
* each LUN would be settable independently as a disk drive or a CD-ROM
* drive, but currently all LUNs have to be the same type. The CD-ROM
* emulation includes a single data track and no audio tracks; hence there
- * need be only one backing file per LUN.
+ * need be only one backing file per LUN. Note also that the CD-ROM block
+ * length is set to 512 rather than the more common value 2048.
*
* Requirements are modest; only a bulk-in and a bulk-out endpoint are
* needed (an interrupt-out endpoint is also needed for CBI). The memory
@@ -532,18 +533,6 @@
/*-------------------------------------------------------------------------*/
-/* Maxpacket and other transfer characteristics vary by speed. */
-static struct usb_endpoint_descriptor *
-fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
- struct usb_endpoint_descriptor *hs)
-{
- if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
- return hs;
- return fs;
-}
-
-/*-------------------------------------------------------------------------*/
-
/*
* DESCRIPTORS ... most are static, but strings and (full) configuration
* descriptors are built on demand. Also the (static) config and interface
@@ -597,19 +586,7 @@
.bNumConfigurations = 1,
};
-static int populate_bos(struct fsg_dev *fsg, u8 *buf)
-{
- memcpy(buf, &fsg_bos_desc, USB_DT_BOS_SIZE);
- buf += USB_DT_BOS_SIZE;
- memcpy(buf, &fsg_ext_cap_desc, USB_DT_USB_EXT_CAP_SIZE);
- buf += USB_DT_USB_EXT_CAP_SIZE;
-
- memcpy(buf, &fsg_ss_cap_desc, USB_DT_USB_SS_CAP_SIZE);
-
- return USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE
- + USB_DT_USB_EXT_CAP_SIZE;
-}
/*
* Config descriptors must agree with the code that sets configurations
@@ -952,28 +929,20 @@
case USB_DT_DEVICE:
VDBG(fsg, "get device descriptor\n");
- device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket;
value = sizeof device_desc;
memcpy(req->buf, &device_desc, value);
break;
case USB_DT_DEVICE_QUALIFIER:
VDBG(fsg, "get device qualifier\n");
- if (!gadget_is_dualspeed(fsg->gadget) ||
- fsg->gadget->speed == USB_SPEED_SUPER)
+ if (!gadget_is_dualspeed(fsg->gadget))
break;
- /*
- * Assume ep0 uses the same maxpacket value for both
- * speeds
- */
- dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;
value = sizeof dev_qualifier;
memcpy(req->buf, &dev_qualifier, value);
break;
case USB_DT_OTHER_SPEED_CONFIG:
VDBG(fsg, "get other-speed config descriptor\n");
- if (!gadget_is_dualspeed(fsg->gadget) ||
- fsg->gadget->speed == USB_SPEED_SUPER)
+ if (!gadget_is_dualspeed(fsg->gadget))
break;
goto get_config;
case USB_DT_CONFIG:
@@ -992,15 +961,7 @@
value = usb_gadget_get_string(&fsg_stringtab,
w_value & 0xff, req->buf);
break;
-
- case USB_DT_BOS:
- VDBG(fsg, "get bos descriptor\n");
-
- if (gadget_is_superspeed(fsg->gadget))
- value = populate_bos(fsg, req->buf);
- break;
}
-
break;
/* One config, two speeds */
@@ -1169,6 +1130,7 @@
u32 amount_left;
loff_t file_offset, file_offset_tmp;
unsigned int amount;
+ unsigned int partial_page;
ssize_t nread;
/* Get the starting Logical Block Address and check that it's
@@ -1190,7 +1152,7 @@
curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
return -EINVAL;
}
- file_offset = ((loff_t) lba) << curlun->blkbits;
+ file_offset = ((loff_t) lba) << 9;
/* Carry out the file reads */
amount_left = fsg->data_size_from_cmnd;
@@ -1203,10 +1165,17 @@
* Try to read the remaining amount.
* But don't read more than the buffer size.
* And don't try to read past the end of the file.
- */
+ * Finally, if we're not at a page boundary, don't read past
+ * the next page.
+ * If this means reading 0 then we were asked to read past
+ * the end of file. */
amount = min((unsigned int) amount_left, mod_data.buflen);
amount = min((loff_t) amount,
curlun->file_length - file_offset);
+ partial_page = file_offset & (PAGE_CACHE_SIZE - 1);
+ if (partial_page > 0)
+ amount = min(amount, (unsigned int) PAGE_CACHE_SIZE -
+ partial_page);
/* Wait for the next buffer to become available */
bh = fsg->next_buffhd_to_fill;
@@ -1221,7 +1190,7 @@
if (amount == 0) {
curlun->sense_data =
SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
- curlun->sense_data_info = file_offset >> curlun->blkbits;
+ curlun->sense_data_info = file_offset >> 9;
curlun->info_valid = 1;
bh->inreq->length = 0;
bh->state = BUF_STATE_FULL;
@@ -1246,23 +1215,18 @@
} else if (nread < amount) {
LDBG(curlun, "partial file read: %d/%u\n",
(int) nread, amount);
- nread = round_down(nread, curlun->blksize);
+ nread -= (nread & 511); // Round down to a block
}
file_offset += nread;
amount_left -= nread;
fsg->residue -= nread;
-
- /* Except at the end of the transfer, nread will be
- * equal to the buffer size, which is divisible by the
- * bulk-in maxpacket size.
- */
bh->inreq->length = nread;
bh->state = BUF_STATE_FULL;
/* If an error occurred, report it and its position */
if (nread < amount) {
curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
- curlun->sense_data_info = file_offset >> curlun->blkbits;
+ curlun->sense_data_info = file_offset >> 9;
curlun->info_valid = 1;
break;
}
@@ -1292,6 +1256,7 @@
u32 amount_left_to_req, amount_left_to_write;
loff_t usb_offset, file_offset, file_offset_tmp;
unsigned int amount;
+ unsigned int partial_page;
ssize_t nwritten;
int rc;
@@ -1332,7 +1297,7 @@
/* Carry out the file writes */
get_some_more = 1;
- file_offset = usb_offset = ((loff_t) lba) << curlun->blkbits;
+ file_offset = usb_offset = ((loff_t) lba) << 9;
amount_left_to_req = amount_left_to_write = fsg->data_size_from_cmnd;
while (amount_left_to_write > 0) {
@@ -1342,20 +1307,38 @@
if (bh->state == BUF_STATE_EMPTY && get_some_more) {
/* Figure out how much we want to get:
- * Try to get the remaining amount,
- * but not more than the buffer size.
- */
+ * Try to get the remaining amount.
+ * But don't get more than the buffer size.
+ * And don't try to go past the end of the file.
+ * If we're not at a page boundary,
+ * don't go past the next page.
+ * If this means getting 0, then we were asked
+ * to write past the end of file.
+ * Finally, round down to a block boundary. */
amount = min(amount_left_to_req, mod_data.buflen);
+ amount = min((loff_t) amount, curlun->file_length -
+ usb_offset);
+ partial_page = usb_offset & (PAGE_CACHE_SIZE - 1);
+ if (partial_page > 0)
+ amount = min(amount,
+ (unsigned int) PAGE_CACHE_SIZE - partial_page);
- /* Beyond the end of the backing file? */
- if (usb_offset >= curlun->file_length) {
+ if (amount == 0) {
get_some_more = 0;
curlun->sense_data =
SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
- curlun->sense_data_info = usb_offset >> curlun->blkbits;
+ curlun->sense_data_info = usb_offset >> 9;
curlun->info_valid = 1;
continue;
}
+ amount -= (amount & 511);
+ if (amount == 0) {
+
+ /* Why were we were asked to transfer a
+ * partial block? */
+ get_some_more = 0;
+ continue;
+ }
/* Get the next buffer */
usb_offset += amount;
@@ -1364,11 +1347,11 @@
if (amount_left_to_req == 0)
get_some_more = 0;
- /* Except at the end of the transfer, amount will be
- * equal to the buffer size, which is divisible by
- * the bulk-out maxpacket size.
- */
- set_bulk_out_req_length(fsg, bh, amount);
+ /* amount is always divisible by 512, hence by
+ * the bulk-out maxpacket size */
+ bh->outreq->length = bh->bulk_out_intended_length =
+ amount;
+ bh->outreq->short_not_ok = 1;
start_transfer(fsg, fsg->bulk_out, bh->outreq,
&bh->outreq_busy, &bh->state);
fsg->next_buffhd_to_fill = bh->next;
@@ -1387,7 +1370,7 @@
/* Did something go wrong with the transfer? */
if (bh->outreq->status != 0) {
curlun->sense_data = SS_COMMUNICATION_FAILURE;
- curlun->sense_data_info = file_offset >> curlun->blkbits;
+ curlun->sense_data_info = file_offset >> 9;
curlun->info_valid = 1;
break;
}
@@ -1401,16 +1384,6 @@
amount = curlun->file_length - file_offset;
}
- /* Don't accept excess data. The spec doesn't say
- * what to do in this case. We'll ignore the error.
- */
- amount = min(amount, bh->bulk_out_intended_length);
-
- /* Don't write a partial block */
- amount = round_down(amount, curlun->blksize);
- if (amount == 0)
- goto empty_write;
-
/* Perform the write */
file_offset_tmp = file_offset;
nwritten = vfs_write(curlun->filp,
@@ -1429,7 +1402,8 @@
} else if (nwritten < amount) {
LDBG(curlun, "partial file write: %d/%u\n",
(int) nwritten, amount);
- nwritten = round_down(nwritten, curlun->blksize);
+ nwritten -= (nwritten & 511);
+ // Round down to a block
}
file_offset += nwritten;
amount_left_to_write -= nwritten;
@@ -1438,14 +1412,13 @@
/* If an error occurred, report it and its position */
if (nwritten < amount) {
curlun->sense_data = SS_WRITE_ERROR;
- curlun->sense_data_info = file_offset >> curlun->blkbits;
+ curlun->sense_data_info = file_offset >> 9;
curlun->info_valid = 1;
break;
}
- empty_write:
/* Did the host decide to stop early? */
- if (bh->outreq->actual < bh->bulk_out_intended_length) {
+ if (bh->outreq->actual != bh->outreq->length) {
fsg->short_packet_received = 1;
break;
}
@@ -1521,8 +1494,8 @@
return -EIO; // No default reply
/* Prepare to carry out the file verify */
- amount_left = verification_length << curlun->blkbits;
- file_offset = ((loff_t) lba) << curlun->blkbits;
+ amount_left = verification_length << 9;
+ file_offset = ((loff_t) lba) << 9;
/* Write out all the dirty buffers before invalidating them */
fsg_lun_fsync_sub(curlun);
@@ -1540,14 +1513,15 @@
* Try to read the remaining amount, but not more than
* the buffer size.
* And don't try to read past the end of the file.
- */
+ * If this means reading 0 then we were asked to read
+ * past the end of file. */
amount = min((unsigned int) amount_left, mod_data.buflen);
amount = min((loff_t) amount,
curlun->file_length - file_offset);
if (amount == 0) {
curlun->sense_data =
SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
- curlun->sense_data_info = file_offset >> curlun->blkbits;
+ curlun->sense_data_info = file_offset >> 9;
curlun->info_valid = 1;
break;
}
@@ -1570,11 +1544,11 @@
} else if (nread < amount) {
LDBG(curlun, "partial file verify: %d/%u\n",
(int) nread, amount);
- nread = round_down(nread, curlun->blksize);
+ nread -= (nread & 511); // Round down to a sector
}
if (nread == 0) {
curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
- curlun->sense_data_info = file_offset >> curlun->blkbits;
+ curlun->sense_data_info = file_offset >> 9;
curlun->info_valid = 1;
break;
}
@@ -1688,7 +1662,7 @@
put_unaligned_be32(curlun->num_sectors - 1, &buf[0]);
/* Max logical block */
- put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */
+ put_unaligned_be32(512, &buf[4]); /* Block length */
return 8;
}
@@ -1910,7 +1884,7 @@
put_unaligned_be32(curlun->num_sectors, &buf[0]);
/* Number of blocks */
- put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */
+ put_unaligned_be32(512, &buf[4]); /* Block length */
buf[4] = 0x02; /* Current capacity */
return 12;
}
@@ -1989,7 +1963,7 @@
fsg->next_buffhd_to_drain = bh->next;
/* A short packet or an error ends everything */
- if (bh->outreq->actual < bh->bulk_out_intended_length ||
+ if (bh->outreq->actual != bh->outreq->length ||
bh->outreq->status != 0) {
raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT);
return -EINTR;
@@ -2003,11 +1977,11 @@
amount = min(fsg->usb_amount_left,
(u32) mod_data.buflen);
- /* Except at the end of the transfer, amount will be
- * equal to the buffer size, which is divisible by
- * the bulk-out maxpacket size.
- */
- set_bulk_out_req_length(fsg, bh, amount);
+ /* amount is always divisible by 512, hence by
+ * the bulk-out maxpacket size */
+ bh->outreq->length = bh->bulk_out_intended_length =
+ amount;
+ bh->outreq->short_not_ok = 1;
start_transfer(fsg, fsg->bulk_out, bh->outreq,
&bh->outreq_busy, &bh->state);
fsg->next_buffhd_to_fill = bh->next;
@@ -2435,7 +2409,7 @@
case READ_6:
i = fsg->cmnd[4];
- fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << fsg->curlun->blkbits;
+ fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
(7<<1) | (1<<4), 1,
"READ(6)")) == 0)
@@ -2444,7 +2418,7 @@
case READ_10:
fsg->data_size_from_cmnd =
- get_unaligned_be16(&fsg->cmnd[7]) << fsg->curlun->blkbits;
+ get_unaligned_be16(&fsg->cmnd[7]) << 9;
if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
(1<<1) | (0xf<<2) | (3<<7), 1,
"READ(10)")) == 0)
@@ -2453,7 +2427,7 @@
case READ_12:
fsg->data_size_from_cmnd =
- get_unaligned_be32(&fsg->cmnd[6]) << fsg->curlun->blkbits;
+ get_unaligned_be32(&fsg->cmnd[6]) << 9;
if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST,
(1<<1) | (0xf<<2) | (0xf<<6), 1,
"READ(12)")) == 0)
@@ -2539,7 +2513,7 @@
case WRITE_6:
i = fsg->cmnd[4];
- fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << fsg->curlun->blkbits;
+ fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST,
(7<<1) | (1<<4), 1,
"WRITE(6)")) == 0)
@@ -2548,7 +2522,7 @@
case WRITE_10:
fsg->data_size_from_cmnd =
- get_unaligned_be16(&fsg->cmnd[7]) << fsg->curlun->blkbits;
+ get_unaligned_be16(&fsg->cmnd[7]) << 9;
if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST,
(1<<1) | (0xf<<2) | (3<<7), 1,
"WRITE(10)")) == 0)
@@ -2557,7 +2531,7 @@
case WRITE_12:
fsg->data_size_from_cmnd =
- get_unaligned_be32(&fsg->cmnd[6]) << fsg->curlun->blkbits;
+ get_unaligned_be32(&fsg->cmnd[6]) << 9;
if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST,
(1<<1) | (0xf<<2) | (0xf<<6), 1,
"WRITE(12)")) == 0)
@@ -2686,6 +2660,7 @@
/* Queue a request to read a Bulk-only CBW */
set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN);
+ bh->outreq->short_not_ok = 1;
start_transfer(fsg, fsg->bulk_out, bh->outreq,
&bh->outreq_busy, &bh->state);
@@ -2738,8 +2713,7 @@
int rc;
ep->driver_data = fsg;
- ep->desc = d;
- rc = usb_ep_enable(ep);
+ rc = usb_ep_enable(ep, d);
if (rc)
ERROR(fsg, "can't enable %s, result %d\n", ep->name, rc);
return rc;
@@ -2810,15 +2784,13 @@
/* Enable the endpoints */
d = fsg_ep_desc(fsg->gadget,
- &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc,
- &fsg_ss_bulk_in_desc);
+ &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc);
if ((rc = enable_endpoint(fsg, fsg->bulk_in, d)) != 0)
goto reset;
fsg->bulk_in_enabled = 1;
d = fsg_ep_desc(fsg->gadget,
- &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc,
- &fsg_ss_bulk_out_desc);
+ &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc);
if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0)
goto reset;
fsg->bulk_out_enabled = 1;
@@ -2827,8 +2799,7 @@
if (transport_is_cbi()) {
d = fsg_ep_desc(fsg->gadget,
- &fsg_fs_intr_in_desc, &fsg_hs_intr_in_desc,
- &fsg_ss_intr_in_desc);
+ &fsg_fs_intr_in_desc, &fsg_hs_intr_in_desc);
if ((rc = enable_endpoint(fsg, fsg->intr_in, d)) != 0)
goto reset;
fsg->intr_in_enabled = 1;
@@ -3445,6 +3416,7 @@
}
/* Fix up the descriptors */
+ device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket;
device_desc.idVendor = cpu_to_le16(mod_data.vendor);
device_desc.idProduct = cpu_to_le16(mod_data.product);
device_desc.bcdDevice = cpu_to_le16(mod_data.release);
@@ -3458,6 +3430,9 @@
if (gadget_is_dualspeed(gadget)) {
fsg_hs_function[i + FSG_HS_FUNCTION_PRE_EP_ENTRIES] = NULL;
+ /* Assume ep0 uses the same maxpacket value for both speeds */
+ dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;
+
/* Assume endpoint addresses are the same for both speeds */
fsg_hs_bulk_in_desc.bEndpointAddress =
fsg_fs_bulk_in_desc.bEndpointAddress;
@@ -3467,24 +3442,6 @@
fsg_fs_intr_in_desc.bEndpointAddress;
}
- if (gadget_is_superspeed(gadget)) {
- unsigned max_burst;
-
- fsg_ss_function[i + FSG_SS_FUNCTION_PRE_EP_ENTRIES] = NULL;
-
- /* Calculate bMaxBurst, we know packet size is 1024 */
- max_burst = min_t(unsigned, mod_data.buflen / 1024, 15);
-
- /* Assume endpoint addresses are the same for both speeds */
- fsg_ss_bulk_in_desc.bEndpointAddress =
- fsg_fs_bulk_in_desc.bEndpointAddress;
- fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
-
- fsg_ss_bulk_out_desc.bEndpointAddress =
- fsg_fs_bulk_out_desc.bEndpointAddress;
- fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
- }
-
if (gadget_is_otg(gadget))
fsg_otg_desc.bmAttributes |= USB_OTG_HNP;
@@ -3599,7 +3556,11 @@
/*-------------------------------------------------------------------------*/
static struct usb_gadget_driver fsg_driver = {
- .speed = USB_SPEED_SUPER,
+#ifdef CONFIG_USB_GADGET_DUALSPEED
+ .speed = USB_SPEED_HIGH,
+#else
+ .speed = USB_SPEED_FULL,
+#endif
.function = (char *) fsg_string_product,
.unbind = fsg_unbind,
.disconnect = fsg_disconnect,
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c
index 3bf872e..3a68e09 100644
--- a/drivers/usb/gadget/fsl_qe_udc.c
+++ b/drivers/usb/gadget/fsl_qe_udc.c
@@ -1927,10 +1927,6 @@
return -ENOTSUPP;
}
-static int fsl_qe_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int fsl_qe_stop(struct usb_gadget_driver *driver);
-
/* defined in usb_gadget.h */
static struct usb_gadget_ops qe_gadget_ops = {
.get_frame = qe_get_frame,
@@ -1939,8 +1935,6 @@
.vbus_session = qe_vbus_session,
.vbus_draw = qe_vbus_draw,
.pullup = qe_pullup,
- .start = fsl_qe_start,
- .stop = fsl_qe_stop,
};
/*-------------------------------------------------------------------------
@@ -2326,7 +2320,7 @@
/*-------------------------------------------------------------------------
Gadget driver probe and unregister.
--------------------------------------------------------------------------*/
-static int fsl_qe_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
int retval;
@@ -2375,8 +2369,9 @@
udc_controller->gadget.name, driver->driver.name);
return 0;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
-static int fsl_qe_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct qe_ep *loop_ep;
unsigned long flags;
@@ -2416,6 +2411,7 @@
driver->driver.name);
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
/* udc structure's alloc and setup, include ep-param alloc */
static struct qe_udc __devinit *qe_udc_config(struct platform_device *ofdev)
@@ -2666,17 +2662,11 @@
if (ret)
goto err6;
- ret = usb_add_gadget_udc(&ofdev->dev, &udc_controller->gadget);
- if (ret)
- goto err7;
-
dev_info(udc_controller->dev,
"%s USB controller initialized as device\n",
(udc_controller->soc_type == PORT_QE) ? "QE" : "CPM");
return 0;
-err7:
- device_unregister(&udc_controller->gadget.dev);
err6:
free_irq(udc_controller->usb_irq, udc_controller);
err5:
@@ -2731,8 +2721,6 @@
if (!udc_controller)
return -ENODEV;
- usb_del_gadget_udc(&udc_controller->gadget);
-
udc_controller->done = &done;
tasklet_disable(&udc_controller->rx_tasklet);
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 4763cc3..4e48331 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -1244,9 +1244,6 @@
return 0;
}
-static int fsl_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int fsl_stop(struct usb_gadget_driver *driver);
/* defined in gadget.h */
static struct usb_gadget_ops fsl_gadget_ops = {
.get_frame = fsl_get_frame,
@@ -1255,8 +1252,6 @@
.vbus_session = fsl_vbus_session,
.vbus_draw = fsl_vbus_draw,
.pullup = fsl_pullup,
- .start = fsl_start,
- .stop = fsl_stop,
};
/* Set protocol stall on ep0, protocol stall will automatically be cleared
@@ -1932,7 +1927,7 @@
* Hook to gadget drivers
* Called by initialization code of gadget drivers
*----------------------------------------------------------------*/
-static int fsl_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
int retval = -ENODEV;
@@ -2000,9 +1995,10 @@
retval);
return retval;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
/* Disconnect from gadget driver */
-static int fsl_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct fsl_ep *loop_ep;
unsigned long flags;
@@ -2045,6 +2041,7 @@
driver->driver.name);
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
/*-------------------------------------------------------------------------
PROC File System Support
@@ -2593,16 +2590,9 @@
ret = -ENOMEM;
goto err_unregister;
}
-
- ret = usb_add_gadget_udc(&pdev->dev, &udc_controller->gadget);
- if (ret)
- goto err_del_udc;
-
create_proc_file();
return 0;
-err_del_udc:
- dma_pool_destroy(udc_controller->td_pool);
err_unregister:
device_unregister(&udc_controller->gadget.dev);
err_free_irq:
@@ -2634,8 +2624,6 @@
if (!udc_controller)
return -ENODEV;
-
- usb_del_gadget_udc(&udc_controller->gadget);
udc_controller->done = &done;
fsl_udc_clk_release();
diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c
index 9cf53c6..763d462 100644
--- a/drivers/usb/gadget/fusb300_udc.c
+++ b/drivers/usb/gadget/fusb300_udc.c
@@ -1500,7 +1500,7 @@
/*------------------------------------------------------------------------*/
static struct fusb300 *the_controller;
-static int fusb300_udc_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct fusb300 *fusb300 = the_controller;
@@ -1544,8 +1544,9 @@
return retval;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
-static int fusb300_udc_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct fusb300 *fusb300 = the_controller;
@@ -1561,6 +1562,7 @@
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
/*--------------------------------------------------------------------------*/
static int fusb300_udc_pullup(struct usb_gadget *_gadget, int is_active)
@@ -1570,15 +1572,12 @@
static struct usb_gadget_ops fusb300_gadget_ops = {
.pullup = fusb300_udc_pullup,
- .start = fusb300_udc_start,
- .stop = fusb300_udc_stop,
};
static int __exit fusb300_remove(struct platform_device *pdev)
{
struct fusb300 *fusb300 = dev_get_drvdata(&pdev->dev);
- usb_del_gadget_udc(&fusb300->gadget);
iounmap(fusb300->reg);
free_irq(platform_get_irq(pdev, 0), fusb300);
@@ -1703,15 +1702,9 @@
goto clean_up3;
init_controller(fusb300);
- ret = usb_add_gadget_udc(&pdev->dev, &fusb300->gadget);
- if (ret)
- goto err_add_udc;
-
dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
return 0;
-err_add_udc:
- fusb300_free_request(&fusb300->ep[0]->ep, fusb300->ep0_req);
clean_up3:
free_irq(ires->start, fusb300);
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index 704c280..ebf6970 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -162,7 +162,6 @@
.name = DRIVER_NAME,
.dev = &gfs_dev_desc,
.strings = gfs_dev_strings,
- .max_speed = USB_SPEED_HIGH,
.unbind = gfs_unbind,
.iProduct = DRIVER_DESC,
};
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index 7a9d57d..da312d4 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -120,12 +120,6 @@
#define gadget_is_ci13xxx_pci(g) 0
#endif
-#ifdef CONFIG_USB_GADGET_DWC3
-#define gadget_is_dwc3(g) (!strcmp("dwc3-gadget", (g)->name))
-#else
-#define gadget_is_dwc3(g) 0
-#endif
-
#ifdef CONFIG_USB_GADGET_MSM_72K
#define gadget_is_msm72k(g) !strcmp("msm72k_udc", (g)->name)
#else
@@ -246,8 +240,6 @@
return 0x31;
else if (gadget_is_ci13xxx_msm_hsic(gadget))
return 0x32;
- else if (gadget_is_dwc3(gadget))
- return 0x33;
return -ENOENT;
}
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index 8b9220e..47b86b9 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -537,16 +537,14 @@
struct usb_ep *ep;
unsigned i;
- dev->in_ep->desc = &bulk_in_desc;
- err = usb_ep_enable(dev->in_ep);
+ err = usb_ep_enable(dev->in_ep, &bulk_in_desc);
if (err) {
ERROR(dev, "can't start %s: %d\n", dev->in_ep->name, err);
goto fail;
}
dev->in_ep->driver_data = dev;
- dev->out_ep->desc = &bulk_out_desc;
- err = usb_ep_enable(dev->out_ep);
+ err = usb_ep_enable(dev->out_ep, &bulk_out_desc);
if (err) {
ERROR(dev, "can't start %s: %d\n", dev->out_ep->name, err);
goto fail;
@@ -695,7 +693,6 @@
switch (w_value >> 8) {
case USB_DT_DEVICE:
- device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
value = min(w_length, (u16) sizeof(device_desc));
memcpy(req->buf, &device_desc, value);
break;
@@ -1250,6 +1247,8 @@
dev->req->complete = gmidi_setup_complete;
+ device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
+
gadget->ep0->driver_data = dev;
INFO(dev, "%s, version: " DRIVER_VERSION "\n", longname);
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 7f87805..bf6e11c 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -996,14 +996,8 @@
return -EOPNOTSUPP;
}
-static int goku_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int goku_stop(struct usb_gadget_driver *driver);
-
static const struct usb_gadget_ops goku_ops = {
.get_frame = goku_get_frame,
- .start = goku_start,
- .stop = goku_stop,
// no remote wakeup
// not selfpowered
};
@@ -1350,7 +1344,7 @@
* disconnect is reported. then a host may connect again, or
* the driver might get unbound.
*/
-static int goku_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct goku_udc *dev = the_controller;
@@ -1388,6 +1382,7 @@
DBG(dev, "registered gadget driver '%s'\n", driver->driver.name);
return 0;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
static void
stop_activity(struct goku_udc *dev, struct usb_gadget_driver *driver)
@@ -1413,7 +1408,7 @@
udc_enable(dev);
}
-static int goku_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct goku_udc *dev = the_controller;
unsigned long flags;
@@ -1434,6 +1429,8 @@
DBG(dev, "unregistered driver '%s'\n", driver->driver.name);
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
/*-------------------------------------------------------------------------*/
@@ -1733,8 +1730,6 @@
DBG(dev, "%s\n", __func__);
- usb_del_gadget_udc(&dev->gadget);
-
BUG_ON(dev->driver);
#ifdef CONFIG_USB_GADGET_DEBUG_FILES
@@ -1859,10 +1854,6 @@
goto err;
}
dev->registered = 1;
- retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
- if (retval)
- goto err;
-
return 0;
err:
diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c
index 9fb5750..2523e54 100644
--- a/drivers/usb/gadget/hid.c
+++ b/drivers/usb/gadget/hid.c
@@ -255,7 +255,6 @@
.name = "g_hid",
.dev = &device_desc,
.strings = dev_strings,
- .max_speed = USB_SPEED_HIGH,
.unbind = __exit_p(hid_unbind),
};
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c
index 692fd9b..ade4006 100644
--- a/drivers/usb/gadget/imx_udc.c
+++ b/drivers/usb/gadget/imx_udc.c
@@ -1237,14 +1237,9 @@
*******************************************************************************
*/
-static int imx_udc_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int imx_udc_stop(struct usb_gadget_driver *driver);
static const struct usb_gadget_ops imx_udc_ops = {
.get_frame = imx_udc_get_frame,
.wakeup = imx_udc_wakeup,
- .start = imx_udc_start,
- .stop = imx_udc_stop,
};
static struct imx_udc_struct controller = {
@@ -1329,7 +1324,7 @@
* USB gadget driver functions
*******************************************************************************
*/
-static int imx_udc_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct imx_udc_struct *imx_usb = &controller;
@@ -1373,8 +1368,9 @@
imx_usb->gadget.dev.driver = NULL;
return retval;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
-static int imx_udc_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct imx_udc_struct *imx_usb = &controller;
@@ -1398,6 +1394,7 @@
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
/*******************************************************************************
* Module functions
@@ -1507,14 +1504,8 @@
imx_usb->timer.function = handle_config;
imx_usb->timer.data = (unsigned long)imx_usb;
- ret = usb_add_gadget_udc(&pdev->dev, &imx_usb->gadget);
- if (ret)
- goto fail4;
-
return 0;
-fail4:
- for (i = 0; i < IMX_USB_NB_EP + 1; i++)
- free_irq(imx_usb->usbd_int[i], imx_usb);
+
fail3:
clk_put(clk);
clk_disable(clk);
@@ -1534,7 +1525,6 @@
struct imxusb_platform_data *pdata = pdev->dev.platform_data;
int i;
- usb_del_gadget_udc(&imx_usb->gadget);
imx_udc_disable(imx_usb);
del_timer(&imx_usb->timer);
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 1b24099..a56876a 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -832,16 +832,14 @@
switch (data->dev->gadget->speed) {
case USB_SPEED_LOW:
case USB_SPEED_FULL:
- ep->desc = &data->desc;
- value = usb_ep_enable(ep);
+ value = usb_ep_enable (ep, &data->desc);
if (value == 0)
data->state = STATE_EP_ENABLED;
break;
#ifdef CONFIG_USB_GADGET_DUALSPEED
case USB_SPEED_HIGH:
/* fails if caller didn't provide that descriptor... */
- ep->desc = &data->hs_desc;
- value = usb_ep_enable(ep);
+ value = usb_ep_enable (ep, &data->hs_desc);
if (value == 0)
data->state = STATE_EP_ENABLED;
break;
@@ -1347,7 +1345,7 @@
qual.bDeviceProtocol = desc->bDeviceProtocol;
/* assumes ep0 uses the same value for both speeds ... */
- qual.bMaxPacketSize0 = dev->gadget->ep0->maxpacket;
+ qual.bMaxPacketSize0 = desc->bMaxPacketSize0;
qual.bNumConfigurations = 1;
qual.bRESERVED = 0;
@@ -1404,6 +1402,7 @@
}
dev->state = STATE_DEV_CONNECTED;
+ dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket;
INFO (dev, "connected\n");
event = next_event (dev, GADGETFS_CONNECT);
@@ -1431,7 +1430,6 @@
case USB_DT_DEVICE:
value = min (w_length, (u16) sizeof *dev->dev);
- dev->dev->bMaxPacketSize0 = dev->gadget->ep0->maxpacket;
req->buf = dev->dev;
break;
#ifdef CONFIG_USB_GADGET_DUALSPEED
@@ -1712,6 +1710,7 @@
set_gadget_data (gadget, dev);
dev->gadget = gadget;
gadget->ep0->driver_data = dev;
+ dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket;
/* preallocate control response and buffer */
dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL);
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c
index d8403ae..9cee88a 100644
--- a/drivers/usb/gadget/langwell_udc.c
+++ b/drivers/usb/gadget/langwell_udc.c
@@ -1321,9 +1321,7 @@
return 0;
}
-static int langwell_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int langwell_stop(struct usb_gadget_driver *driver);
+
/* device controller usb_gadget_ops structure */
static const struct usb_gadget_ops langwell_ops = {
@@ -1344,9 +1342,6 @@
/* D+ pullup, software-controlled connect/disconnect to USB host */
.pullup = langwell_pullup,
-
- .start = langwell_start,
- .stop = langwell_stop,
};
@@ -1857,7 +1852,7 @@
* the driver might get unbound.
*/
-static int langwell_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct langwell_udc *dev = the_controller;
@@ -1919,9 +1914,11 @@
dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return retval;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
+
/* unregister gadget driver */
-static int langwell_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct langwell_udc *dev = the_controller;
unsigned long flags;
@@ -1968,6 +1965,8 @@
dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
/*-------------------------------------------------------------------------*/
@@ -3374,10 +3373,6 @@
if (retval)
goto error;
- retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
- if (retval)
- goto error;
-
retval = device_create_file(&pdev->dev, &dev_attr_langwell_udc);
if (retval)
goto error;
@@ -3408,7 +3403,6 @@
dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
- usb_del_gadget_udc(&dev->gadget);
/* disable interrupt and set controller to stop state */
langwell_udc_stop(dev);
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c
index 11d3782..084aa08 100644
--- a/drivers/usb/gadget/m66592-udc.c
+++ b/drivers/usb/gadget/m66592-udc.c
@@ -1454,7 +1454,7 @@
/*-------------------------------------------------------------------------*/
static struct m66592 *the_controller;
-static int m66592_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct m66592 *m66592 = the_controller;
@@ -1506,8 +1506,9 @@
return retval;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
-static int m66592_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct m66592 *m66592 = the_controller;
unsigned long flags;
@@ -1532,6 +1533,7 @@
m66592->driver = NULL;
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
/*-------------------------------------------------------------------------*/
static int m66592_get_frame(struct usb_gadget *_gadget)
@@ -1542,16 +1544,12 @@
static struct usb_gadget_ops m66592_gadget_ops = {
.get_frame = m66592_get_frame,
- .start = m66592_start,
- .stop = m66592_stop,
};
static int __exit m66592_remove(struct platform_device *pdev)
{
struct m66592 *m66592 = dev_get_drvdata(&pdev->dev);
- usb_del_gadget_udc(&m66592->gadget);
-
del_timer_sync(&m66592->timer);
iounmap(m66592->reg);
free_irq(platform_get_irq(pdev, 0), m66592);
@@ -1693,16 +1691,9 @@
init_controller(m66592);
- ret = usb_add_gadget_udc(&pdev->dev, &m66592->gadget);
- if (ret)
- goto err_add_udc;
-
dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
return 0;
-err_add_udc:
- m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
-
clean_up3:
#ifdef CONFIG_HAVE_CLK
if (m66592->pdata->on_chip) {
diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c
index 1b2d135..0182242 100644
--- a/drivers/usb/gadget/mass_storage.c
+++ b/drivers/usb/gadget/mass_storage.c
@@ -169,7 +169,6 @@
.name = "g_mass_storage",
.dev = &msg_device_desc,
.iProduct = DRIVER_DESC,
- .max_speed = USB_SPEED_SUPER,
.needs_serial = 1,
};
diff --git a/drivers/usb/gadget/msm72k_udc.c b/drivers/usb/gadget/msm72k_udc.c
index 42c48a5..ea62262 100644
--- a/drivers/usb/gadget/msm72k_udc.c
+++ b/drivers/usb/gadget/msm72k_udc.c
@@ -1453,10 +1453,7 @@
static int usb_free(struct usb_info *ui, int ret)
{
- if (ret)
- dev_dbg(&ui->pdev->dev, "usb_free(%d)\n", ret);
-
- usb_del_gadget_udc(&ui->gadget);
+ dev_dbg(&ui->pdev->dev, "usb_free(%d)\n", ret);
if (ui->xceiv)
otg_put_transceiver(ui->xceiv);
@@ -2388,11 +2385,6 @@
}
-static int msm72k_gadget_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int msm72k_gadget_stop(struct usb_gadget_driver *driver);
-
-
static const struct usb_gadget_ops msm72k_ops = {
.get_frame = msm72k_get_frame,
.vbus_session = msm72k_udc_vbus_session,
@@ -2400,8 +2392,6 @@
.pullup = msm72k_pullup,
.wakeup = msm72k_wakeup,
.set_selfpowered = msm72k_set_selfpowered,
- .start = msm72k_gadget_start,
- .stop = msm72k_gadget_stop,
};
static void usb_do_remote_wakeup(struct work_struct *w)
@@ -2595,10 +2585,6 @@
ui->gadget.is_otg = 1;
#endif
- retval = usb_add_gadget_udc(&pdev->dev, &ui->gadget);
- if (retval)
- return usb_free(ui, retval);
-
ui->sdev.name = DRIVER_NAME;
ui->sdev.print_name = print_switch_name;
ui->sdev.print_state = print_switch_state;
@@ -2643,7 +2629,7 @@
return 0;
}
-static int msm72k_gadget_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct usb_info *ui = the_usb_info;
@@ -2729,8 +2715,9 @@
ui->gadget.dev.driver = NULL;
return retval;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
-static int msm72k_gadget_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct usb_info *dev = the_usb_info;
@@ -2767,6 +2754,7 @@
"unregistered gadget driver '%s'\n", driver->driver.name);
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
static int msm72k_udc_runtime_suspend(struct device *dev)
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index 8c7b747..d9feced 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -351,7 +351,6 @@
.name = "g_multi",
.dev = &device_desc,
.strings = dev_strings,
- .max_speed = USB_SPEED_HIGH,
.unbind = __exit_p(multi_unbind),
.iProduct = DRIVER_DESC,
.needs_serial = 1,
diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c
index 6adf38c..b1a8146 100644
--- a/drivers/usb/gadget/mv_udc_core.c
+++ b/drivers/usb/gadget/mv_udc_core.c
@@ -1128,9 +1128,6 @@
return 0;
}
-static int mv_udc_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int mv_udc_stop(struct usb_gadget_driver *driver);
/* device controller usb_gadget_ops structure */
static const struct usb_gadget_ops mv_ops = {
@@ -1142,8 +1139,6 @@
/* D+ pullup, software-controlled connect/disconnect to USB host */
.pullup = mv_udc_pullup,
- .start = mv_udc_start,
- .stop = mv_udc_stop,
};
static void mv_udc_testmode(struct mv_udc *udc, u16 index, bool enter)
@@ -1235,7 +1230,7 @@
}
}
-static int mv_udc_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct mv_udc *udc = the_controller;
@@ -1275,8 +1270,9 @@
return 0;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
-static int mv_udc_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct mv_udc *udc = the_controller;
unsigned long flags;
@@ -1300,6 +1296,7 @@
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
static int
udc_prime_status(struct mv_udc *udc, u8 direction, u16 status, bool empty)
@@ -1883,9 +1880,8 @@
static int mv_udc_remove(struct platform_device *dev)
{
struct mv_udc *udc = the_controller;
- DECLARE_COMPLETION(done);
- usb_del_gadget_udc(&udc->gadget);
+ DECLARE_COMPLETION(done);
udc->done = &done;
@@ -2078,12 +2074,11 @@
the_controller = udc;
- retval = usb_add_gadget_udc(&dev->dev, &udc->gadget);
- if (!retval)
- return retval;
+ goto out;
error:
if (udc)
mv_udc_remove(udc->dev);
+out:
return retval;
}
diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c
index 62ee508..99c179a 100644
--- a/drivers/usb/gadget/ncm.c
+++ b/drivers/usb/gadget/ncm.c
@@ -228,7 +228,6 @@
.name = "g_ncm",
.dev = &device_desc,
.strings = dev_strings,
- .max_speed = USB_SPEED_HIGH,
.unbind = __exit_p(gncm_unbind),
};
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 1e6ea6f..476d88e 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -1410,17 +1410,11 @@
return 0;
}
-static int net2280_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int net2280_stop(struct usb_gadget_driver *driver);
-
static const struct usb_gadget_ops net2280_ops = {
.get_frame = net2280_get_frame,
.wakeup = net2280_wakeup,
.set_selfpowered = net2280_set_selfpowered,
.pullup = net2280_pullup,
- .start = net2280_start,
- .stop = net2280_stop,
};
/*-------------------------------------------------------------------------*/
@@ -1936,7 +1930,7 @@
* disconnect is reported. then a host may connect again, or
* the driver might get unbound.
*/
-static int net2280_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct net2280 *dev = the_controller;
@@ -2000,6 +1994,7 @@
dev->driver = NULL;
return retval;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
static void
stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver)
@@ -2027,7 +2022,7 @@
usb_reinit (dev);
}
-static int net2280_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
{
struct net2280 *dev = the_controller;
unsigned long flags;
@@ -2054,6 +2049,8 @@
DEBUG (dev, "unregistered driver '%s'\n", driver->driver.name);
return 0;
}
+EXPORT_SYMBOL (usb_gadget_unregister_driver);
+
/*-------------------------------------------------------------------------*/
@@ -2735,8 +2732,6 @@
{
struct net2280 *dev = pci_get_drvdata (pdev);
- usb_del_gadget_udc(&dev->gadget);
-
BUG_ON(dev->driver);
/* then clean up the resources we allocated during probe() */
@@ -2921,9 +2916,6 @@
retval = device_create_file (&pdev->dev, &dev_attr_registers);
if (retval) goto done;
- retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
- if (retval)
- goto done;
return 0;
done:
diff --git a/drivers/usb/gadget/nokia.c b/drivers/usb/gadget/nokia.c
index c7fb772..55ca63a 100644
--- a/drivers/usb/gadget/nokia.c
+++ b/drivers/usb/gadget/nokia.c
@@ -241,7 +241,6 @@
.name = "g_nokia",
.dev = &device_desc,
.strings = dev_strings,
- .max_speed = USB_SPEED_HIGH,
.unbind = __exit_p(nokia_unbind),
};
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 740c7da..82fd249 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -1375,10 +1375,6 @@
return 0;
}
-static int omap_udc_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int omap_udc_stop(struct usb_gadget_driver *driver);
-
static struct usb_gadget_ops omap_gadget_ops = {
.get_frame = omap_get_frame,
.wakeup = omap_wakeup,
@@ -1386,8 +1382,6 @@
.vbus_session = omap_vbus_session,
.vbus_draw = omap_vbus_draw,
.pullup = omap_pullup,
- .start = omap_udc_start,
- .stop = omap_udc_stop,
};
/*-------------------------------------------------------------------------*/
@@ -2108,7 +2102,7 @@
);
}
-static int omap_udc_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
int status = -ENODEV;
@@ -2192,8 +2186,9 @@
omap_udc_enable_clock(0);
return status;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
-static int omap_udc_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
{
unsigned long flags;
int status = -ENODEV;
@@ -2227,6 +2222,8 @@
DBG("unregistered driver '%s'\n", driver->driver.name);
return status;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
/*-------------------------------------------------------------------------*/
@@ -2994,16 +2991,9 @@
create_proc_file();
status = device_add(&udc->gadget.dev);
- if (status)
- goto cleanup4;
-
- status = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
if (!status)
return status;
/* If fail, fall through */
-cleanup4:
- remove_proc_file();
-
#ifdef USE_ISO
cleanup3:
free_irq(pdev->resource[2].start, udc);
@@ -3039,8 +3029,6 @@
if (!udc)
return -ENODEV;
-
- usb_del_gadget_udc(&udc->gadget);
if (udc->driver)
return -EBUSY;
diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c
index f96615a..68dbcc3 100644
--- a/drivers/usb/gadget/pch_udc.c
+++ b/drivers/usb/gadget/pch_udc.c
@@ -1176,9 +1176,6 @@
return -EOPNOTSUPP;
}
-static int pch_udc_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int pch_udc_stop(struct usb_gadget_driver *driver);
static const struct usb_gadget_ops pch_udc_ops = {
.get_frame = pch_udc_pcd_get_frame,
.wakeup = pch_udc_pcd_wakeup,
@@ -1186,8 +1183,6 @@
.pullup = pch_udc_pcd_pullup,
.vbus_session = pch_udc_pcd_vbus_session,
.vbus_draw = pch_udc_pcd_vbus_draw,
- .start = pch_udc_start,
- .stop = pch_udc_stop,
};
/**
@@ -2695,7 +2690,7 @@
return 0;
}
-static int pch_udc_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct pch_udc_dev *dev = pch_udc;
@@ -2738,8 +2733,9 @@
dev->connected = 1;
return 0;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
-static int pch_udc_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct pch_udc_dev *dev = pch_udc;
@@ -2765,6 +2761,7 @@
pch_udc_set_disconnect(dev);
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
static void pch_udc_shutdown(struct pci_dev *pdev)
{
@@ -2781,8 +2778,6 @@
{
struct pch_udc_dev *dev = pci_get_drvdata(pdev);
- usb_del_gadget_udc(&dev->gadget);
-
/* gadget driver must not be registered */
if (dev->driver)
dev_err(&pdev->dev,
@@ -2958,9 +2953,6 @@
/* Put the device in disconnected state till a driver is bound */
pch_udc_set_disconnect(dev);
- retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
- if (retval)
- goto finished;
return 0;
finished:
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index d5df8dd..271ef94 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -89,7 +89,8 @@
u8 config;
s8 interface;
struct usb_ep *in_ep, *out_ep;
-
+ const struct usb_endpoint_descriptor
+ *in, *out;
struct list_head rx_reqs; /* List of free RX structs */
struct list_head rx_reqs_active; /* List of Active RX xfers */
struct list_head rx_buffers; /* List of completed xfers */
@@ -894,20 +895,19 @@
{
int result = 0;
- dev->in_ep->desc = ep_desc(dev->gadget, &hs_ep_in_desc, &fs_ep_in_desc);
+ dev->in = ep_desc(dev->gadget, &hs_ep_in_desc, &fs_ep_in_desc);
dev->in_ep->driver_data = dev;
- dev->out_ep->desc = ep_desc(dev->gadget, &hs_ep_out_desc,
- &fs_ep_out_desc);
+ dev->out = ep_desc(dev->gadget, &hs_ep_out_desc, &fs_ep_out_desc);
dev->out_ep->driver_data = dev;
- result = usb_ep_enable(dev->in_ep);
+ result = usb_ep_enable(dev->in_ep, dev->in);
if (result != 0) {
DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result);
goto done;
}
- result = usb_ep_enable(dev->out_ep);
+ result = usb_ep_enable(dev->out_ep, dev->out);
if (result != 0) {
DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result);
goto done;
@@ -918,8 +918,8 @@
if (result != 0) {
(void) usb_ep_disable(dev->in_ep);
(void) usb_ep_disable(dev->out_ep);
- dev->in_ep->desc = NULL;
- dev->out_ep->desc = NULL;
+ dev->in = NULL;
+ dev->out = NULL;
}
/* caller is responsible for cleanup on error */
@@ -933,14 +933,12 @@
DBG(dev, "%s\n", __func__);
- if (dev->in_ep->desc)
+ if (dev->in)
usb_ep_disable(dev->in_ep);
- if (dev->out_ep->desc)
+ if (dev->out)
usb_ep_disable(dev->out_ep);
- dev->in_ep->desc = NULL;
- dev->out_ep->desc = NULL;
dev->interface = -1;
}
@@ -1106,9 +1104,9 @@
list_add(&req->list, &dev->tx_reqs);
}
- if (usb_ep_enable(dev->in_ep))
+ if (usb_ep_enable(dev->in_ep, dev->in))
DBG(dev, "Failed to enable USB in_ep\n");
- if (usb_ep_enable(dev->out_ep))
+ if (usb_ep_enable(dev->out_ep, dev->out))
DBG(dev, "Failed to enable USB out_ep\n");
wake_up_interruptible(&dev->rx_wait);
@@ -1148,8 +1146,6 @@
switch (wValue >> 8) {
case USB_DT_DEVICE:
- device_desc.bMaxPacketSize0 =
- gadget->ep0->maxpacket;
value = min(wLength, (u16) sizeof device_desc);
memcpy(req->buf, &device_desc, value);
break;
@@ -1157,12 +1153,6 @@
case USB_DT_DEVICE_QUALIFIER:
if (!gadget->is_dualspeed)
break;
- /*
- * assumes ep0 uses the same value for both
- * speeds
- */
- dev_qualifier.bMaxPacketSize0 =
- gadget->ep0->maxpacket;
value = min(wLength,
(u16) sizeof dev_qualifier);
memcpy(req->buf, &dev_qualifier, value);
@@ -1458,11 +1448,15 @@
out_ep->driver_data = out_ep; /* claim */
#ifdef CONFIG_USB_GADGET_DUALSPEED
- /* assumes that all endpoints are dual-speed */
+ /* assumes ep0 uses the same value for both speeds ... */
+ dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0;
+
+ /* and that all endpoints are dual-speed */
hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress;
hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress;
#endif /* DUALSPEED */
+ device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
usb_gadget_set_selfpowered(gadget);
if (gadget->is_otg) {
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c
index e4e59b4..7745454 100644
--- a/drivers/usb/gadget/pxa25x_udc.c
+++ b/drivers/usb/gadget/pxa25x_udc.c
@@ -1011,18 +1011,12 @@
return -EOPNOTSUPP;
}
-static int pxa25x_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int pxa25x_stop(struct usb_gadget_driver *driver);
-
static const struct usb_gadget_ops pxa25x_udc_ops = {
.get_frame = pxa25x_udc_get_frame,
.wakeup = pxa25x_udc_wakeup,
.vbus_session = pxa25x_udc_vbus_session,
.pullup = pxa25x_udc_pullup,
.vbus_draw = pxa25x_udc_vbus_draw,
- .start = pxa25x_start,
- .stop = pxa25x_stop,
};
/*-------------------------------------------------------------------------*/
@@ -1269,7 +1263,7 @@
* disconnect is reported. then a host may connect again, or
* the driver might get unbound.
*/
-static int pxa25x_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct pxa25x_udc *dev = the_controller;
@@ -1328,6 +1322,7 @@
bind_fail:
return retval;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
static void
stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver)
@@ -1356,7 +1351,7 @@
udc_reinit(dev);
}
-static int pxa25x_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct pxa25x_udc *dev = the_controller;
@@ -1384,6 +1379,8 @@
dump_state(dev);
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
/*-------------------------------------------------------------------------*/
@@ -2234,11 +2231,8 @@
#endif
create_debug_files(dev);
- retval = usb_add_gadget_udc(&pdev->dev, &dev->gadget);
- if (!retval)
- return retval;
+ return 0;
- remove_debug_files(dev);
#ifdef CONFIG_ARCH_LUBBOCK
lubbock_fail0:
free_irq(LUBBOCK_USB_DISC_IRQ, dev);
@@ -2267,7 +2261,6 @@
{
struct pxa25x_udc *dev = platform_get_drvdata(pdev);
- usb_del_gadget_udc(&dev->gadget);
if (dev->driver)
return -EBUSY;
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index 85b68c7..5760769 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -1680,18 +1680,12 @@
return -EOPNOTSUPP;
}
-static int pxa27x_udc_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int pxa27x_udc_stop(struct usb_gadget_driver *driver);
-
static const struct usb_gadget_ops pxa_udc_ops = {
.get_frame = pxa_udc_get_frame,
.wakeup = pxa_udc_wakeup,
.pullup = pxa_udc_pullup,
.vbus_session = pxa_udc_vbus_session,
.vbus_draw = pxa_udc_vbus_draw,
- .start = pxa27x_udc_start,
- .stop = pxa27x_udc_stop,
};
/**
@@ -1797,7 +1791,7 @@
}
/**
- * pxa27x_start - Register gadget driver
+ * usb_gadget_probe_driver - Register gadget driver
* @driver: gadget driver
* @bind: bind function
*
@@ -1811,7 +1805,7 @@
*
* Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise
*/
-static int pxa27x_udc_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct pxa_udc *udc = the_controller;
@@ -1866,6 +1860,8 @@
udc->gadget.dev.driver = NULL;
return retval;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
+
/**
* stop_activity - Stops udc endpoints
@@ -1892,12 +1888,12 @@
}
/**
- * pxa27x_udc_stop - Unregister the gadget driver
+ * usb_gadget_unregister_driver - Unregister the gadget driver
* @driver: gadget driver
*
* Returns 0 if no error, -ENODEV, -EINVAL otherwise
*/
-static int pxa27x_udc_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct pxa_udc *udc = the_controller;
@@ -1921,6 +1917,7 @@
return otg_set_peripheral(udc->transceiver, NULL);
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
/**
* handle_ep0_ctrl_req - handle control endpoint control request
@@ -2519,14 +2516,9 @@
driver_name, IRQ_USB, retval);
goto err_irq;
}
- retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
- if (retval)
- goto err_add_udc;
pxa_init_debugfs(udc);
return 0;
-err_add_udc:
- free_irq(udc->irq, udc);
err_irq:
iounmap(udc->regs);
err_map:
@@ -2545,7 +2537,6 @@
struct pxa_udc *udc = platform_get_drvdata(_dev);
int gpio = udc->mach->gpio_pullup;
- usb_del_gadget_udc(&udc->gadget);
usb_gadget_unregister_driver(udc->driver);
free_irq(udc->irq, udc);
pxa_cleanup_debugfs(udc);
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c
index 51b655f..6dcc1f6 100644
--- a/drivers/usb/gadget/r8a66597-udc.c
+++ b/drivers/usb/gadget/r8a66597-udc.c
@@ -1410,7 +1410,7 @@
/*-------------------------------------------------------------------------*/
static struct r8a66597 *the_controller;
-static int r8a66597_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct r8a66597 *r8a66597 = the_controller;
@@ -1462,8 +1462,9 @@
return retval;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
-static int r8a66597_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct r8a66597 *r8a66597 = the_controller;
unsigned long flags;
@@ -1487,6 +1488,7 @@
r8a66597->driver = NULL;
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
/*-------------------------------------------------------------------------*/
static int r8a66597_get_frame(struct usb_gadget *_gadget)
@@ -1497,15 +1499,12 @@
static struct usb_gadget_ops r8a66597_gadget_ops = {
.get_frame = r8a66597_get_frame,
- .start = r8a66597_start,
- .stop = r8a66597_stop,
};
static int __exit r8a66597_remove(struct platform_device *pdev)
{
struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev);
- usb_del_gadget_udc(&r8a66597->gadget);
del_timer_sync(&r8a66597->timer);
iounmap(r8a66597->reg);
free_irq(platform_get_irq(pdev, 0), r8a66597);
@@ -1648,15 +1647,9 @@
init_controller(r8a66597);
- ret = usb_add_gadget_udc(&pdev->dev, &r8a66597->gadget);
- if (ret)
- goto err_add_udc;
-
dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
return 0;
-err_add_udc:
- r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req);
clean_up3:
free_irq(irq, r8a66597);
clean_up2:
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 8bdee67..0dfee28 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -2574,7 +2574,7 @@
return 0;
}
-static int s3c_hsotg_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct s3c_hsotg *hsotg = our_hsotg;
@@ -2745,8 +2745,9 @@
hsotg->gadget.dev.driver = NULL;
return ret;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
-static int s3c_hsotg_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct s3c_hsotg *hsotg = our_hsotg;
int ep;
@@ -2774,6 +2775,7 @@
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
static int s3c_hsotg_gadget_getframe(struct usb_gadget *gadget)
{
@@ -2782,8 +2784,6 @@
static struct usb_gadget_ops s3c_hsotg_gadget_ops = {
.get_frame = s3c_hsotg_gadget_getframe,
- .start = s3c_hsotg_start,
- .stop = s3c_hsotg_stop,
};
/**
@@ -3403,10 +3403,6 @@
for (epnum = 0; epnum < S3C_HSOTG_EPS; epnum++)
s3c_hsotg_initep(hsotg, &hsotg->eps[epnum], epnum);
- ret = usb_add_gadget_udc(&pdev->dev, &hsotg->gadget);
- if (ret)
- goto err_add_udc;
-
s3c_hsotg_create_debug(hsotg);
s3c_hsotg_dump(hsotg);
@@ -3414,11 +3410,6 @@
our_hsotg = hsotg;
return 0;
-err_add_udc:
- s3c_hsotg_gate(pdev, false);
- clk_disable(hsotg->clk);
- clk_put(hsotg->clk);
-
err_regs:
iounmap(hsotg->regs);
@@ -3436,8 +3427,6 @@
{
struct s3c_hsotg *hsotg = platform_get_drvdata(pdev);
- usb_del_gadget_udc(&hsotg->gadget);
-
s3c_hsotg_delete_debug(hsotg);
usb_gadget_unregister_driver(hsotg->driver);
diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c
index dc9f428..d5e3e1e 100644
--- a/drivers/usb/gadget/s3c-hsudc.c
+++ b/drivers/usb/gadget/s3c-hsudc.c
@@ -1133,7 +1133,7 @@
return IRQ_HANDLED;
}
-static int s3c_hsudc_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct s3c_hsudc *hsudc = the_controller;
@@ -1181,8 +1181,9 @@
return 0;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
-static int s3c_hsudc_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct s3c_hsudc *hsudc = the_controller;
unsigned long flags;
@@ -1209,6 +1210,7 @@
driver->driver.name);
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
static inline u32 s3c_hsudc_read_frameno(struct s3c_hsudc *hsudc)
{
@@ -1222,8 +1224,6 @@
static struct usb_gadget_ops s3c_hsudc_gadget_ops = {
.get_frame = s3c_hsudc_gadget_getframe,
- .start = s3c_hsudc_start,
- .stop = s3c_hsudc_stop,
};
static int s3c_hsudc_probe(struct platform_device *pdev)
@@ -1311,15 +1311,7 @@
disable_irq(hsudc->irq);
local_irq_enable();
-
- ret = usb_add_gadget_udc(&pdev->dev, &hsudc->gadget);
- if (ret)
- goto err_add_udc;
-
return 0;
-err_add_udc:
- clk_disable(hsudc->uclk);
- clk_put(hsudc->uclk);
err_clk:
free_irq(hsudc->irq, hsudc);
err_irq:
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
index 1c19cd3..100f263 100644
--- a/drivers/usb/gadget/s3c2410_udc.c
+++ b/drivers/usb/gadget/s3c2410_udc.c
@@ -1552,10 +1552,6 @@
return -ENOTSUPP;
}
-static int s3c2410_udc_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int s3c2410_udc_stop(struct usb_gadget_driver *driver);
-
static const struct usb_gadget_ops s3c2410_ops = {
.get_frame = s3c2410_udc_get_frame,
.wakeup = s3c2410_udc_wakeup,
@@ -1563,8 +1559,6 @@
.pullup = s3c2410_udc_pullup,
.vbus_session = s3c2410_udc_vbus_session,
.vbus_draw = s3c2410_vbus_draw,
- .start = s3c2410_udc_start,
- .stop = s3c2410_udc_stop,
};
static void s3c2410_udc_command(enum s3c2410_udc_cmd_e cmd)
@@ -1678,7 +1672,10 @@
s3c2410_udc_command(S3C2410_UDC_P_ENABLE);
}
-static int s3c2410_udc_start(struct usb_gadget_driver *driver,
+/*
+ * usb_gadget_probe_driver
+ */
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct s3c2410_udc *udc = the_controller;
@@ -1733,8 +1730,12 @@
udc->gadget.dev.driver = NULL;
return retval;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
-static int s3c2410_udc_stop(struct usb_gadget_driver *driver)
+/*
+ * usb_gadget_unregister_driver
+ */
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct s3c2410_udc *udc = the_controller;
@@ -1954,10 +1955,6 @@
goto err_vbus_irq;
}
- retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
- if (retval)
- goto err_add_udc;
-
if (s3c2410_udc_debugfs_root) {
udc->regs_info = debugfs_create_file("registers", S_IRUGO,
s3c2410_udc_debugfs_root,
@@ -1970,10 +1967,6 @@
return 0;
-err_add_udc:
- if (udc_info && !udc_info->udc_command &&
- gpio_is_valid(udc_info->pullup_pin))
- gpio_free(udc_info->pullup_pin);
err_vbus_irq:
if (udc_info && udc_info->vbus_pin > 0)
free_irq(gpio_to_irq(udc_info->vbus_pin), udc);
@@ -1999,8 +1992,6 @@
unsigned int irq;
dev_dbg(&pdev->dev, "%s()\n", __func__);
-
- usb_del_gadget_udc(&udc->gadget);
if (udc->driver)
return -EBUSY;
@@ -2114,6 +2105,8 @@
debugfs_remove(s3c2410_udc_debugfs_root);
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
module_init(udc_init);
module_exit(udc_exit);
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index ed1b816..1ac57a9 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -242,7 +242,6 @@
.name = "g_serial",
.dev = &device_desc,
.strings = dev_strings,
- .max_speed = USB_SPEED_HIGH,
};
static int __init init(void)
diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c
index 43a54f1..1505967 100644
--- a/drivers/usb/gadget/storage_common.c
+++ b/drivers/usb/gadget/storage_common.c
@@ -247,8 +247,6 @@
u32 sense_data_info;
u32 unit_attention_data;
- unsigned int blkbits; /* Bits of logical block size of bound block device */
- unsigned int blksize; /* logical block size of bound block device */
struct device dev;
#ifdef CONFIG_USB_MSC_PROFILING
spinlock_t lock;
@@ -511,128 +509,12 @@
NULL,
};
-static struct usb_endpoint_descriptor
-fsg_ss_bulk_in_desc = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
-
- /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */
- .bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = cpu_to_le16(1024),
-};
-
-static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = {
- .bLength = sizeof(fsg_ss_bulk_in_comp_desc),
- .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
-
- /*.bMaxBurst = DYNAMIC, */
-};
-
-static struct usb_endpoint_descriptor
-fsg_ss_bulk_out_desc = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
-
- /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */
- .bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = cpu_to_le16(1024),
-};
-
-static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = {
- .bLength = sizeof(fsg_ss_bulk_in_comp_desc),
- .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
-
- /*.bMaxBurst = DYNAMIC, */
-};
-
-#ifndef FSG_NO_INTR_EP
-
-static struct usb_endpoint_descriptor
-fsg_ss_intr_in_desc = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
-
- /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */
- .bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = cpu_to_le16(2),
- .bInterval = 9, /* 2**(9-1) = 256 uframes -> 32 ms */
-};
-
-static struct usb_ss_ep_comp_descriptor fsg_ss_intr_in_comp_desc = {
- .bLength = sizeof(fsg_ss_bulk_in_comp_desc),
- .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
-
- .wBytesPerInterval = cpu_to_le16(2),
-};
-
-#ifndef FSG_NO_OTG
-# define FSG_SS_FUNCTION_PRE_EP_ENTRIES 2
-#else
-# define FSG_SS_FUNCTION_PRE_EP_ENTRIES 1
-#endif
-
-#endif
-
-static __maybe_unused struct usb_ext_cap_descriptor fsg_ext_cap_desc = {
- .bLength = USB_DT_USB_EXT_CAP_SIZE,
- .bDescriptorType = USB_DT_DEVICE_CAPABILITY,
- .bDevCapabilityType = USB_CAP_TYPE_EXT,
-
- .bmAttributes = cpu_to_le32(USB_LPM_SUPPORT),
-};
-
-static __maybe_unused struct usb_ss_cap_descriptor fsg_ss_cap_desc = {
- .bLength = USB_DT_USB_SS_CAP_SIZE,
- .bDescriptorType = USB_DT_DEVICE_CAPABILITY,
- .bDevCapabilityType = USB_SS_CAP_TYPE,
-
- /* .bmAttributes = LTM is not supported yet */
-
- .wSpeedSupported = cpu_to_le16(USB_LOW_SPEED_OPERATION
- | USB_FULL_SPEED_OPERATION
- | USB_HIGH_SPEED_OPERATION
- | USB_5GBPS_OPERATION),
- .bFunctionalitySupport = USB_LOW_SPEED_OPERATION,
- .bU1devExitLat = USB_DEFAULT_U1_DEV_EXIT_LAT,
- .bU2DevExitLat = USB_DEFAULT_U2_DEV_EXIT_LAT,
-};
-
-static __maybe_unused struct usb_bos_descriptor fsg_bos_desc = {
- .bLength = USB_DT_BOS_SIZE,
- .bDescriptorType = USB_DT_BOS,
-
- .wTotalLength = USB_DT_BOS_SIZE
- + USB_DT_USB_EXT_CAP_SIZE
- + USB_DT_USB_SS_CAP_SIZE,
-
- .bNumDeviceCaps = 2,
-};
-
-static struct usb_descriptor_header *fsg_ss_function[] = {
-#ifndef FSG_NO_OTG
- (struct usb_descriptor_header *) &fsg_otg_desc,
-#endif
- (struct usb_descriptor_header *) &fsg_intf_desc,
- (struct usb_descriptor_header *) &fsg_ss_bulk_in_desc,
- (struct usb_descriptor_header *) &fsg_ss_bulk_in_comp_desc,
- (struct usb_descriptor_header *) &fsg_ss_bulk_out_desc,
- (struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc,
-#ifndef FSG_NO_INTR_EP
- (struct usb_descriptor_header *) &fsg_ss_intr_in_desc,
- (struct usb_descriptor_header *) &fsg_ss_intr_in_comp_desc,
-#endif
- NULL,
-};
-
/* Maxpacket and other transfer characteristics vary by speed. */
-static __maybe_unused struct usb_endpoint_descriptor *
+static struct usb_endpoint_descriptor *
fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
- struct usb_endpoint_descriptor *hs,
- struct usb_endpoint_descriptor *ss)
+ struct usb_endpoint_descriptor *hs)
{
- if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER)
- return ss;
- else if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
+ if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
return hs;
return fs;
}
@@ -714,24 +596,13 @@
rc = (int) size;
goto out;
}
-
- if (curlun->cdrom) {
- curlun->blksize = 2048;
- curlun->blkbits = 11;
- } else if (inode->i_bdev) {
- curlun->blksize = bdev_logical_block_size(inode->i_bdev);
- curlun->blkbits = blksize_bits(curlun->blksize);
- } else {
- curlun->blksize = 512;
- curlun->blkbits = 9;
- }
-
- num_sectors = size >> curlun->blkbits; /* File size in logic-block-size blocks */
+ num_sectors = size >> 9; /* File size in 512-byte blocks */
min_sectors = 1;
if (curlun->cdrom) {
- min_sectors = 300; /* Smallest track is 300 frames */
- if (num_sectors >= 256*60*75) {
- num_sectors = 256*60*75 - 1;
+ num_sectors &= ~3; /* Reduce to a multiple of 2048 */
+ min_sectors = 300*4; /* Smallest track is 300 frames */
+ if (num_sectors >= 256*60*75*4) {
+ num_sectors = (256*60*75 - 1) * 4;
LINFO(curlun, "file too big: %s\n", filename);
LINFO(curlun, "using only first %d blocks\n",
(int) num_sectors);
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index 36270d4..6299cdd 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -704,7 +704,7 @@
int ret;
unsigned long flags;
- ret = usb_ep_enable(port->gr->in);
+ ret = usb_ep_enable(port->gr->in, port->gr->in_desc);
if (ret) {
pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
__func__, port->gr->in);
@@ -712,7 +712,7 @@
}
port->gr->in->driver_data = port;
- ret = usb_ep_enable(port->gr->out);
+ ret = usb_ep_enable(port->gr->out, port->gr->out_desc);
if (ret) {
pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
__func__, port->gr->out);
@@ -1125,7 +1125,7 @@
d = &port->data_ch;
if (trans == USB_GADGET_XPORT_BAM) {
- ret = usb_ep_enable(gr->in);
+ ret = usb_ep_enable(gr->in, gr->in_desc);
if (ret) {
pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
__func__, gr->in);
@@ -1133,7 +1133,7 @@
}
gr->in->driver_data = port;
- ret = usb_ep_enable(gr->out);
+ ret = usb_ep_enable(gr->out, gr->out_desc);
if (ret) {
pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
__func__, gr->out);
diff --git a/drivers/usb/gadget/u_data_hsic.c b/drivers/usb/gadget/u_data_hsic.c
index a12953b..7b77a1d 100644
--- a/drivers/usb/gadget/u_data_hsic.c
+++ b/drivers/usb/gadget/u_data_hsic.c
@@ -741,6 +741,8 @@
struct gdata_port *port;
struct gserial *gser;
struct grmnet *gr;
+ struct usb_endpoint_descriptor *in_desc;
+ struct usb_endpoint_descriptor *out_desc;
unsigned long flags;
int ret = 0;
@@ -766,6 +768,8 @@
port->rx_q_size = ghsic_data_serial_rx_q_size;
gser->in->driver_data = port;
gser->out->driver_data = port;
+ in_desc = gser->in_desc;
+ out_desc = gser->out_desc;
} else {
gr = gptr;
port->in = gr->in;
@@ -774,16 +778,18 @@
port->rx_q_size = ghsic_data_rmnet_rx_q_size;
gr->in->driver_data = port;
gr->out->driver_data = port;
+ in_desc = gr->in_desc;
+ out_desc = gr->out_desc;
}
- ret = usb_ep_enable(port->in);
+ ret = usb_ep_enable(port->in, in_desc);
if (ret) {
pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
__func__, port->in);
goto fail;
}
- ret = usb_ep_enable(port->out);
+ ret = usb_ep_enable(port->out, out_desc);
if (ret) {
pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
__func__, port->out);
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 39c53da..b5a30fe 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -693,8 +693,8 @@
usb_ep_disable(link->out_ep);
if (netif_carrier_ok(net)) {
DBG(dev, "host still using in/out endpoints\n");
- usb_ep_enable(link->in_ep);
- usb_ep_enable(link->out_ep);
+ usb_ep_enable(link->in_ep, link->in);
+ usb_ep_enable(link->out_ep, link->out);
}
}
spin_unlock_irqrestore(&dev->lock, flags);
@@ -891,7 +891,7 @@
return ERR_PTR(-EINVAL);
link->in_ep->driver_data = dev;
- result = usb_ep_enable(link->in_ep);
+ result = usb_ep_enable(link->in_ep, link->in);
if (result != 0) {
DBG(dev, "enable %s --> %d\n",
link->in_ep->name, result);
@@ -899,7 +899,7 @@
}
link->out_ep->driver_data = dev;
- result = usb_ep_enable(link->out_ep);
+ result = usb_ep_enable(link->out_ep, link->out);
if (result != 0) {
DBG(dev, "enable %s --> %d\n",
link->out_ep->name, result);
@@ -988,7 +988,7 @@
}
spin_unlock(&dev->req_lock);
link->in_ep->driver_data = NULL;
- link->in_ep->desc = NULL;
+ link->in = NULL;
usb_ep_disable(link->out_ep);
spin_lock(&dev->req_lock);
@@ -1003,7 +1003,7 @@
}
spin_unlock(&dev->req_lock);
link->out_ep->driver_data = NULL;
- link->out_ep->desc = NULL;
+ link->out = NULL;
/* finish forgetting about this USB link episode */
dev->header_len = 0;
diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h
index 4677241..64b65f9 100644
--- a/drivers/usb/gadget/u_ether.h
+++ b/drivers/usb/gadget/u_ether.h
@@ -52,6 +52,10 @@
struct usb_ep *in_ep;
struct usb_ep *out_ep;
+ /* descriptors match device speed at gether_connect() time */
+ struct usb_endpoint_descriptor *in;
+ struct usb_endpoint_descriptor *out;
+
bool is_zlp_ok;
u16 cdc_filter;
diff --git a/drivers/usb/gadget/u_rmnet.h b/drivers/usb/gadget/u_rmnet.h
index 386101c..fd1e124 100644
--- a/drivers/usb/gadget/u_rmnet.h
+++ b/drivers/usb/gadget/u_rmnet.h
@@ -29,6 +29,8 @@
struct usb_ep *in;
struct usb_ep *out;
+ struct usb_endpoint_descriptor *in_desc;
+ struct usb_endpoint_descriptor *out_desc;
/* to usb host, aka laptop, windows pc etc. Will
* be filled by usb driver of rmnet functionality
diff --git a/drivers/usb/gadget/u_sdio.c b/drivers/usb/gadget/u_sdio.c
index 14dc73a..9bd4370 100644
--- a/drivers/usb/gadget/u_sdio.c
+++ b/drivers/usb/gadget/u_sdio.c
@@ -931,7 +931,7 @@
gser->notify_modem = gsdio_ctrl_notify_modem;
spin_unlock_irqrestore(&port->port_lock, flags);
- ret = usb_ep_enable(gser->in);
+ ret = usb_ep_enable(gser->in, gser->in_desc);
if (ret) {
pr_err("%s: failed to enable in ep w/ err:%d\n",
__func__, ret);
@@ -940,7 +940,7 @@
}
gser->in->driver_data = port;
- ret = usb_ep_enable(gser->out);
+ ret = usb_ep_enable(gser->out, gser->out_desc);
if (ret) {
pr_err("%s: failed to enable in ep w/ err:%d\n",
__func__, ret);
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index 10a255d..ca5f11b 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -1524,12 +1524,12 @@
port = ports[port_num].port;
/* activate the endpoints */
- status = usb_ep_enable(gser->in);
+ status = usb_ep_enable(gser->in, gser->in_desc);
if (status < 0)
return status;
gser->in->driver_data = port;
- status = usb_ep_enable(gser->out);
+ status = usb_ep_enable(gser->out, gser->out_desc);
if (status < 0)
goto fail_out;
gser->out->driver_data = port;
diff --git a/drivers/usb/gadget/u_serial.h b/drivers/usb/gadget/u_serial.h
index dadc507..c937006 100644
--- a/drivers/usb/gadget/u_serial.h
+++ b/drivers/usb/gadget/u_serial.h
@@ -35,6 +35,8 @@
struct usb_ep *in;
struct usb_ep *out;
+ struct usb_endpoint_descriptor *in_desc;
+ struct usb_endpoint_descriptor *out_desc;
/* REVISIT avoid this CDC-ACM support harder ... */
struct usb_cdc_line_coding port_line_coding; /* 9600-8-N-1 etc */
diff --git a/drivers/usb/gadget/u_smd.c b/drivers/usb/gadget/u_smd.c
index 0e9ad48..95adf5d 100644
--- a/drivers/usb/gadget/u_smd.c
+++ b/drivers/usb/gadget/u_smd.c
@@ -660,7 +660,7 @@
port->nbytes_tolaptop = 0;
spin_unlock_irqrestore(&port->port_lock, flags);
- ret = usb_ep_enable(gser->in);
+ ret = usb_ep_enable(gser->in, gser->in_desc);
if (ret) {
pr_err("%s: usb_ep_enable failed eptype:IN ep:%p",
__func__, gser->in);
@@ -669,7 +669,7 @@
}
gser->in->driver_data = port;
- ret = usb_ep_enable(gser->out);
+ ret = usb_ep_enable(gser->out, gser->out_desc);
if (ret) {
pr_err("%s: usb_ep_enable failed eptype:OUT ep:%p",
__func__, gser->out);
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
deleted file mode 100644
index 2f77e46..0000000
--- a/drivers/usb/gadget/udc-core.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/**
- * udc.c - Core UDC Framework
- *
- * Copyright (C) 2010 Texas Instruments
- * Author: Felipe Balbi <balbi@ti.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 of
- * the License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/err.h>
-
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-
-/**
- * struct usb_udc - describes one usb device controller
- * @driver - the gadget driver pointer. For use by the class code
- * @dev - the child device to the actual controller
- * @gadget - the gadget. For use by the class code
- * @list - for use by the udc class driver
- *
- * This represents the internal data structure which is used by the UDC-class
- * to hold information about udc driver and gadget together.
- */
-struct usb_udc {
- struct usb_gadget_driver *driver;
- struct usb_gadget *gadget;
- struct device dev;
- struct list_head list;
-};
-
-static struct class *udc_class;
-static struct device_type udc_device_type;
-static LIST_HEAD(udc_list);
-static DEFINE_MUTEX(udc_lock);
-
-/* ------------------------------------------------------------------------- */
-
-/**
- * usb_gadget_start - tells usb device controller to start up
- * @gadget: The gadget we want to get started
- * @driver: The driver we want to bind to @gadget
- * @bind: The bind function for @driver
- *
- * This call is issued by the UDC Class driver when it's about
- * to register a gadget driver to the device controller, before
- * calling gadget driver's bind() method.
- *
- * It allows the controller to be powered off until strictly
- * necessary to have it powered on.
- *
- * Returns zero on success, else negative errno.
- */
-static inline int usb_gadget_start(struct usb_gadget *gadget,
- struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *))
-{
- return gadget->ops->start(driver, bind);
-}
-
-/**
- * usb_gadget_udc_start - tells usb device controller to start up
- * @gadget: The gadget we want to get started
- * @driver: The driver we want to bind to @gadget
- *
- * This call is issued by the UDC Class driver when it's about
- * to register a gadget driver to the device controller, before
- * calling gadget driver's bind() method.
- *
- * It allows the controller to be powered off until strictly
- * necessary to have it powered on.
- *
- * Returns zero on success, else negative errno.
- */
-static inline int usb_gadget_udc_start(struct usb_gadget *gadget,
- struct usb_gadget_driver *driver)
-{
- return gadget->ops->udc_start(gadget, driver);
-}
-
-/**
- * usb_gadget_stop - tells usb device controller we don't need it anymore
- * @gadget: The device we want to stop activity
- * @driver: The driver to unbind from @gadget
- *
- * This call is issued by the UDC Class driver after calling
- * gadget driver's unbind() method.
- *
- * The details are implementation specific, but it can go as
- * far as powering off UDC completely and disable its data
- * line pullups.
- */
-static inline void usb_gadget_stop(struct usb_gadget *gadget,
- struct usb_gadget_driver *driver)
-{
- gadget->ops->stop(driver);
-}
-
-/**
- * usb_gadget_udc_stop - tells usb device controller we don't need it anymore
- * @gadget: The device we want to stop activity
- * @driver: The driver to unbind from @gadget
- *
- * This call is issued by the UDC Class driver after calling
- * gadget driver's unbind() method.
- *
- * The details are implementation specific, but it can go as
- * far as powering off UDC completely and disable its data
- * line pullups.
- */
-static inline void usb_gadget_udc_stop(struct usb_gadget *gadget,
- struct usb_gadget_driver *driver)
-{
- gadget->ops->udc_stop(gadget, driver);
-}
-
-/**
- * usb_udc_release - release the usb_udc struct
- * @dev: the dev member within usb_udc
- *
- * This is called by driver's core in order to free memory once the last
- * reference is released.
- */
-static void usb_udc_release(struct device *dev)
-{
- struct usb_udc *udc;
-
- udc = container_of(dev, struct usb_udc, dev);
- dev_dbg(dev, "releasing '%s'\n", dev_name(dev));
- kfree(udc);
-}
-
-/**
- * usb_add_gadget_udc - adds a new gadget to the udc class driver list
- * @parent: the parent device to this udc. Usually the controller
- * driver's device.
- * @gadget: the gadget to be added to the list
- *
- * Returns zero on success, negative errno otherwise.
- */
-int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget)
-{
- struct usb_udc *udc;
- int ret = -ENOMEM;
-
- udc = kzalloc(sizeof(*udc), GFP_KERNEL);
- if (!udc)
- goto err1;
-
- device_initialize(&udc->dev);
- udc->dev.release = usb_udc_release;
- udc->dev.class = udc_class;
- udc->dev.parent = parent;
- ret = dev_set_name(&udc->dev, "%s", kobject_name(&parent->kobj));
- if (ret)
- goto err2;
-
- udc->gadget = gadget;
-
- mutex_lock(&udc_lock);
- list_add_tail(&udc->list, &udc_list);
-
- ret = device_add(&udc->dev);
- if (ret)
- goto err3;
-
- mutex_unlock(&udc_lock);
-
- return 0;
-err3:
- list_del(&udc->list);
- mutex_unlock(&udc_lock);
-
-err2:
- put_device(&udc->dev);
-
-err1:
- return ret;
-}
-EXPORT_SYMBOL_GPL(usb_add_gadget_udc);
-
-static int udc_is_newstyle(struct usb_udc *udc)
-{
- if (udc->gadget->ops->udc_start && udc->gadget->ops->udc_stop)
- return 1;
- return 0;
-}
-
-
-static void usb_gadget_remove_driver(struct usb_udc *udc)
-{
- dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n",
- udc->gadget->name);
-
- kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
-
- if (udc_is_newstyle(udc)) {
- udc->driver->disconnect(udc->gadget);
- udc->driver->unbind(udc->gadget);
- usb_gadget_udc_stop(udc->gadget, udc->driver);
- usb_gadget_disconnect(udc->gadget);
- } else {
- usb_gadget_stop(udc->gadget, udc->driver);
- }
-
- udc->driver = NULL;
- udc->dev.driver = NULL;
-}
-
-/**
- * usb_del_gadget_udc - deletes @udc from udc_list
- * @gadget: the gadget to be removed.
- *
- * This, will call usb_gadget_unregister_driver() if
- * the @udc is still busy.
- */
-void usb_del_gadget_udc(struct usb_gadget *gadget)
-{
- struct usb_udc *udc = NULL;
-
- mutex_lock(&udc_lock);
- list_for_each_entry(udc, &udc_list, list)
- if (udc->gadget == gadget)
- goto found;
-
- dev_err(gadget->dev.parent, "gadget not registered.\n");
- mutex_unlock(&udc_lock);
-
- return;
-
-found:
- dev_vdbg(gadget->dev.parent, "unregistering gadget\n");
-
- list_del(&udc->list);
- mutex_unlock(&udc_lock);
-
- if (udc->driver)
- usb_gadget_remove_driver(udc);
-
- kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE);
- device_unregister(&udc->dev);
-}
-EXPORT_SYMBOL_GPL(usb_del_gadget_udc);
-
-/* ------------------------------------------------------------------------- */
-
-int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *))
-{
- struct usb_udc *udc = NULL;
- int ret;
-
- if (!driver || !bind || !driver->setup)
- return -EINVAL;
-
- mutex_lock(&udc_lock);
- list_for_each_entry(udc, &udc_list, list) {
- /* For now we take the first one */
- if (!udc->driver)
- goto found;
- }
-
- pr_debug("couldn't find an available UDC\n");
- mutex_unlock(&udc_lock);
- return -ENODEV;
-
-found:
- dev_dbg(&udc->dev, "registering UDC driver [%s]\n",
- driver->function);
-
- udc->driver = driver;
- udc->dev.driver = &driver->driver;
-
- if (udc_is_newstyle(udc)) {
- ret = bind(udc->gadget);
- if (ret)
- goto err1;
- ret = usb_gadget_udc_start(udc->gadget, driver);
- if (ret) {
- driver->unbind(udc->gadget);
- goto err1;
- }
- usb_gadget_connect(udc->gadget);
- } else {
-
- ret = usb_gadget_start(udc->gadget, driver, bind);
- if (ret)
- goto err1;
-
- }
-
- kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
- mutex_unlock(&udc_lock);
- return 0;
-
-err1:
- dev_err(&udc->dev, "failed to start %s: %d\n",
- udc->driver->function, ret);
- udc->driver = NULL;
- udc->dev.driver = NULL;
- mutex_unlock(&udc_lock);
- return ret;
-}
-EXPORT_SYMBOL_GPL(usb_gadget_probe_driver);
-
-int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
-{
- struct usb_udc *udc = NULL;
- int ret = -ENODEV;
-
- if (!driver || !driver->unbind)
- return -EINVAL;
-
- mutex_lock(&udc_lock);
- list_for_each_entry(udc, &udc_list, list)
- if (udc->driver == driver) {
- usb_gadget_remove_driver(udc);
- ret = 0;
- break;
- }
-
- mutex_unlock(&udc_lock);
- return ret;
-}
-EXPORT_SYMBOL_GPL(usb_gadget_unregister_driver);
-
-/* ------------------------------------------------------------------------- */
-
-static ssize_t usb_udc_srp_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t n)
-{
- struct usb_udc *udc = dev_get_drvdata(dev);
-
- if (sysfs_streq(buf, "1"))
- usb_gadget_wakeup(udc->gadget);
-
- return n;
-}
-static DEVICE_ATTR(srp, S_IWUSR, NULL, usb_udc_srp_store);
-
-static ssize_t usb_udc_softconn_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t n)
-{
- struct usb_udc *udc = dev_get_drvdata(dev);
-
- if (sysfs_streq(buf, "connect")) {
- usb_gadget_connect(udc->gadget);
- } else if (sysfs_streq(buf, "disconnect")) {
- usb_gadget_disconnect(udc->gadget);
- } else {
- dev_err(dev, "unsupported command '%s'\n", buf);
- return -EINVAL;
- }
-
- return n;
-}
-static DEVICE_ATTR(soft_connect, S_IWUSR, NULL, usb_udc_softconn_store);
-
-static ssize_t usb_udc_speed_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct usb_udc *udc = dev_get_drvdata(dev);
- struct usb_gadget *gadget = udc->gadget;
-
- switch (gadget->speed) {
- case USB_SPEED_LOW:
- return snprintf(buf, PAGE_SIZE, "low-speed\n");
- case USB_SPEED_FULL:
- return snprintf(buf, PAGE_SIZE, "full-speed\n");
- case USB_SPEED_HIGH:
- return snprintf(buf, PAGE_SIZE, "high-speed\n");
- case USB_SPEED_WIRELESS:
- return snprintf(buf, PAGE_SIZE, "wireless\n");
- case USB_SPEED_SUPER:
- return snprintf(buf, PAGE_SIZE, "super-speed\n");
- case USB_SPEED_UNKNOWN: /* FALLTHROUGH */
- default:
- return snprintf(buf, PAGE_SIZE, "UNKNOWN\n");
- }
-}
-static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL);
-
-#define USB_UDC_ATTR(name) \
-ssize_t usb_udc_##name##_show(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- struct usb_udc *udc = dev_get_drvdata(dev); \
- struct usb_gadget *gadget = udc->gadget; \
- \
- return snprintf(buf, PAGE_SIZE, "%d\n", gadget->name); \
-} \
-static DEVICE_ATTR(name, S_IRUSR, usb_udc_##name##_show, NULL)
-
-static USB_UDC_ATTR(is_dualspeed);
-static USB_UDC_ATTR(is_otg);
-static USB_UDC_ATTR(is_a_peripheral);
-static USB_UDC_ATTR(b_hnp_enable);
-static USB_UDC_ATTR(a_hnp_support);
-static USB_UDC_ATTR(a_alt_hnp_support);
-
-static struct attribute *usb_udc_attrs[] = {
- &dev_attr_srp.attr,
- &dev_attr_soft_connect.attr,
- &dev_attr_speed.attr,
-
- &dev_attr_is_dualspeed.attr,
- &dev_attr_is_otg.attr,
- &dev_attr_is_a_peripheral.attr,
- &dev_attr_b_hnp_enable.attr,
- &dev_attr_a_hnp_support.attr,
- &dev_attr_a_alt_hnp_support.attr,
- NULL,
-};
-
-static const struct attribute_group usb_udc_attr_group = {
- .attrs = usb_udc_attrs,
-};
-
-static const struct attribute_group *usb_udc_attr_groups[] = {
- &usb_udc_attr_group,
- NULL,
-};
-
-static int usb_udc_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
- struct usb_udc *udc = container_of(dev, struct usb_udc, dev);
- int ret;
-
- ret = add_uevent_var(env, "USB_UDC_NAME=%s", udc->gadget->name);
- if (ret) {
- dev_err(dev, "failed to add uevent USB_UDC_NAME\n");
- return ret;
- }
-
- if (udc->driver) {
- ret = add_uevent_var(env, "USB_UDC_DRIVER=%s",
- udc->driver->function);
- if (ret) {
- dev_err(dev, "failed to add uevent USB_UDC_DRIVER\n");
- return ret;
- }
- }
-
- return 0;
-}
-
-static int __init usb_udc_init(void)
-{
- udc_class = class_create(THIS_MODULE, "udc");
- if (IS_ERR(udc_class)) {
- pr_err("failed to create udc class --> %ld\n",
- PTR_ERR(udc_class));
- return PTR_ERR(udc_class);
- }
-
- udc_class->dev_uevent = usb_udc_uevent;
- udc_device_type.groups = usb_udc_attr_groups;
-
- return 0;
-}
-subsys_initcall(usb_udc_init);
-
-static void __exit usb_udc_exit(void)
-{
- class_destroy(udc_class);
-}
-module_exit(usb_udc_exit);
-
-MODULE_DESCRIPTION("UDC Framework");
-MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c
index df6882d..a5a0fdb 100644
--- a/drivers/usb/gadget/webcam.c
+++ b/drivers/usb/gadget/webcam.c
@@ -373,7 +373,6 @@
.name = "g_webcam",
.dev = &webcam_device_descriptor,
.strings = webcam_device_strings,
- .max_speed = USB_SPEED_HIGH,
.unbind = webcam_unbind,
};
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index af7e7c3..6d16db9 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -340,7 +340,6 @@
.name = "zero",
.dev = &device_desc,
.strings = dev_strings,
- .max_speed = USB_SPEED_HIGH,
.unbind = zero_unbind,
.suspend = zero_suspend,
.resume = zero_resume,
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 784910a..548338c 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1715,10 +1715,6 @@
return 0;
}
-static int musb_gadget_start(struct usb_gadget_driver *driver,
- int (*bind)(struct usb_gadget *));
-static int musb_gadget_stop(struct usb_gadget_driver *driver);
-
static const struct usb_gadget_ops musb_gadget_operations = {
.get_frame = musb_gadget_get_frame,
.wakeup = musb_gadget_wakeup,
@@ -1726,8 +1722,6 @@
/* .vbus_session = musb_gadget_vbus_session, */
.vbus_draw = musb_gadget_vbus_draw,
.pullup = musb_gadget_pullup,
- .start = musb_gadget_start,
- .stop = musb_gadget_stop,
};
/* ----------------------------------------------------------------------- */
@@ -1852,16 +1846,7 @@
if (status != 0) {
put_device(&musb->g.dev);
the_gadget = NULL;
- return status;
}
- status = usb_add_gadget_udc(musb->controller, &musb->g);
- if (status)
- goto err;
-
- return 0;
-err:
- device_unregister(&musb->g.dev);
- the_gadget = NULL;
return status;
}
@@ -1870,7 +1855,6 @@
if (musb != the_gadget)
return;
- usb_del_gadget_udc(&musb->g);
device_unregister(&musb->g.dev);
the_gadget = NULL;
}
@@ -1887,7 +1871,7 @@
* @param bind the driver's bind function
* @return <0 if error, 0 if everything is fine
*/
-static int musb_gadget_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct musb *musb = the_gadget;
@@ -1989,6 +1973,7 @@
err0:
return retval;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver)
{
@@ -2038,7 +2023,7 @@
*
* @param driver the gadget driver to unregister
*/
-static int musb_gadget_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct musb *musb = the_gadget;
unsigned long flags;
@@ -2097,6 +2082,8 @@
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
/* ----------------------------------------------------------------------- */
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index 486d129..547486c 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -1179,7 +1179,7 @@
*
*/
struct usbhsg_gpriv *the_controller;
-static int usbhsg_gadget_start(struct usb_gadget_driver *driver,
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
int (*bind)(struct usb_gadget *))
{
struct usbhsg_gpriv *gpriv = the_controller;
@@ -1229,8 +1229,9 @@
return ret;
}
+EXPORT_SYMBOL(usb_gadget_probe_driver);
-static int usbhsg_gadget_stop(struct usb_gadget_driver *driver)
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
struct usbhsg_gpriv *gpriv = the_controller;
struct usbhs_priv *priv;
@@ -1259,6 +1260,7 @@
return 0;
}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
/*
* usb gadget ops
@@ -1273,8 +1275,6 @@
static struct usb_gadget_ops usbhsg_gadget_ops = {
.get_frame = usbhsg_get_frame,
- .start = usbhsg_gadget_start,
- .stop = usbhsg_gadget_stop,
};
static int usbhsg_start(struct usbhs_priv *priv)
@@ -1294,7 +1294,6 @@
struct device *dev = usbhs_priv_to_dev(priv);
int pipe_size = usbhs_get_dparam(priv, pipe_size);
int i;
- int ret;
gpriv = kzalloc(sizeof(struct usbhsg_gpriv), GFP_KERNEL);
if (!gpriv) {
@@ -1305,7 +1304,6 @@
uep = kzalloc(sizeof(struct usbhsg_uep) * pipe_size, GFP_KERNEL);
if (!uep) {
dev_err(dev, "Could not allocate ep\n");
- ret = -ENOMEM;
goto usbhs_mod_gadget_probe_err_gpriv;
}
@@ -1368,28 +1366,20 @@
the_controller = gpriv;
- ret = usb_add_gadget_udc(dev, &gpriv->gadget);
- if (ret)
- goto err_add_udc;
-
-
dev_info(dev, "gadget probed\n");
return 0;
-err_add_udc:
- kfree(gpriv->uep);
usbhs_mod_gadget_probe_err_gpriv:
kfree(gpriv);
- return ret;
+ return -ENOMEM;
}
void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv)
{
struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
- usb_del_gadget_udc(&gpriv->gadget);
kfree(gpriv->uep);
kfree(gpriv);
}