Merge branch 'p-ti-linux-3.14.y-common' into p-ti-linux-3.14.y-android
authorVishal Mahaveer <vishalm@ti.com>
Wed, 6 May 2015 23:49:01 +0000 (18:49 -0500)
committerVishal Mahaveer <vishalm@ti.com>
Wed, 6 May 2015 23:55:31 +0000 (18:55 -0500)
* p-ti-linux-3.14.y-common: (219 commits)
  Revert "usb: dwc3: debugfs: dual role switch through debugfs entries"
  Linux 3.14.41
  nosave: consolidate __nosave_{begin,end} in <asm/sections.h>
  fs: take i_mutex during prepare_binprm for set[ug]id executables
  driver core: bus: Goto appropriate labels on failure in bus_add_device
  memstick: mspro_block: add missing curly braces
  C6x: time: Ensure consistency in __init
  crypto: omap-aes - Fix support for unequal lengths
  wl18xx: show rx_frames_per_rates as an array as it really is
  lib: memzero_explicit: use barrier instead of OPTIMIZER_HIDE_VAR
  e1000: add dummy allocator to fix race condition between mtu change and netpoll
  ksoftirqd: Enable IRQs and call cond_resched() before poking RCU
  RCU pathwalk breakage when running into a symlink overmounting something
  drm/i915: cope with large i2c transfers
  drm/radeon: fix doublescan modes (v2)
  i2c: core: Export bus recovery functions
  IB/mlx4: Fix WQE LSO segment calculation
  IB/core: don't disallow registering region starting at 0x0
  IB/core: disallow registering 0-sized memory region
  stk1160: Make sure current buffer is released
  ...

Conflicts:
drivers/usb/gadget/Kconfig
drivers/usb/gadget/Makefile
drivers/usb/gadget/udc/udc-core.c
drivers/usb/phy/Kconfig
drivers/usb/phy/Makefile
fs/exec.c

Change-Id: I1e169d9d98c508c1965cbdc84e88faf10c8fe777
Signed-off-by: Vishal Mahaveer <vishalm@ti.com>
Signed-off-by: Subramaniam Chanderashekarapuram <subramaniam.ca@ti.com>
27 files changed:
1  2 
arch/arm/boot/dts/dra7-evm.dts
arch/x86/kernel/process.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/Makefile
drivers/usb/gadget/composite.c
drivers/usb/gadget/configfs.c
drivers/usb/gadget/function/Makefile
drivers/usb/gadget/function/f_accessory.c
drivers/usb/gadget/function/f_audio_source.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/function/f_mtp.c
drivers/usb/gadget/function/f_mtp.h
drivers/usb/gadget/function/f_ptp.c
drivers/usb/gadget/function/f_rndis.c
drivers/usb/gadget/function/rndis.c
drivers/usb/gadget/function/rndis.h
drivers/usb/gadget/function/u_ether.c
drivers/usb/gadget/function/u_ether.h
drivers/usb/gadget/function/u_serial.c
drivers/usb/gadget/legacy/Kconfig
drivers/usb/gadget/legacy/Makefile
drivers/usb/gadget/legacy/android.c
drivers/usb/gadget/udc/udc-core.c
drivers/usb/phy/Kconfig
drivers/usb/phy/Makefile
fs/exec.c
net/ipv4/tcp_output.c

Simple merge
Simple merge
index 9501c6bb7ee10f2fbc2caf530eb1b118c1af522b,5c822afb6d70fc1ae2b8308678b1c0a400d70d23..7db95c361f552931bf0b3292c92b77af321adb67
@@@ -728,509 -353,7 +359,28 @@@ config USB_CONFIGFS_F_F
          implemented in kernel space (for instance Ethernet, serial or
          mass storage) and other are implemented in user space.
  
-         boolean "MTP gadget"
-         depends on USB_CONFIGFS
-         select USB_F_MTP
-         help
-           USB gadget MTP support
 +config USB_CONFIGFS_F_MTP
-         boolean "PTP gadget"
-         depends on USB_CONFIGFS && USB_CONFIGFS_F_MTP
-         select USB_F_PTP
-         help
-           USB gadget PTP support
++      boolean "MTP gadget"
++      depends on USB_CONFIGFS
++      select USB_F_MTP
++      help
++       USB gadget MTP support
 +
 +config USB_CONFIGFS_F_PTP
- config USB_ZERO
-       tristate "Gadget Zero (DEVELOPMENT)"
-       select USB_LIBCOMPOSITE
-       select USB_F_SS_LB
-       help
-         Gadget Zero is a two-configuration device.  It either sinks and
-         sources bulk data; or it loops back a configurable number of
-         transfers.  It also implements control requests, for "chapter 9"
-         conformance.  The driver needs only two bulk-capable endpoints, so
-         it can work on top of most device-side usb controllers.  It's
-         useful for testing, and is also a working example showing how
-         USB "gadget drivers" can be written.
-         Make this be the first driver you try using on top of any new
-         USB peripheral controller driver.  Then you can use host-side
-         test software, like the "usbtest" driver, to put your hardware
-         and its driver through a basic set of functional tests.
-         Gadget Zero also works with the host-side "usb-skeleton" driver,
-         and with many kinds of host-side test software.  You may need
-         to tweak product and vendor IDs before host software knows about
-         this device, and arrange to select an appropriate configuration.
-         Say "y" to link the driver statically, or "m" to build a
-         dynamically linked module called "g_zero".
- config USB_ZERO_HNPTEST
-       boolean "HNP Test Device"
-       depends on USB_ZERO && USB_OTG
-       help
-         You can configure this device to enumerate using the device
-         identifiers of the USB-OTG test device.  That means that when
-         this gadget connects to another OTG device, with this one using
-         the "B-Peripheral" role, that device will use HNP to let this
-         one serve as the USB host instead (in the "B-Host" role).
- config USB_AUDIO
-       tristate "Audio Gadget"
-       depends on SND
-       select USB_LIBCOMPOSITE
-       select SND_PCM
-       help
-         This Gadget Audio driver is compatible with USB Audio Class
-         specification 2.0. It implements 1 AudioControl interface,
-         1 AudioStreaming Interface each for USB-OUT and USB-IN.
-         Number of channels, sample rate and sample size can be
-         specified as module parameters.
-         This driver doesn't expect any real Audio codec to be present
-         on the device - the audio streams are simply sinked to and
-         sourced from a virtual ALSA sound card created. The user-space
-         application may choose to do whatever it wants with the data
-         received from the USB Host and choose to provide whatever it
-         wants as audio data to the USB Host.
-         Say "y" to link the driver statically, or "m" to build a
-         dynamically linked module called "g_audio".
- config GADGET_UAC1
-       bool "UAC 1.0 (Legacy)"
-       depends on USB_AUDIO
-       help
-         If you instead want older UAC Spec-1.0 driver that also has audio
-         paths hardwired to the Audio codec chip on-board and doesn't work
-         without one.
- config USB_ETH
-       tristate "Ethernet Gadget (with CDC Ethernet support)"
-       depends on NET
-       select USB_LIBCOMPOSITE
-       select USB_U_ETHER
-       select USB_F_ECM
-       select USB_F_SUBSET
-       select CRC32
-       help
-         This driver implements Ethernet style communication, in one of
-         several ways:
-         
-          - The "Communication Device Class" (CDC) Ethernet Control Model.
-            That protocol is often avoided with pure Ethernet adapters, in
-            favor of simpler vendor-specific hardware, but is widely
-            supported by firmware for smart network devices.
-          - On hardware can't implement that protocol, a simple CDC subset
-            is used, placing fewer demands on USB.
-          - CDC Ethernet Emulation Model (EEM) is a newer standard that has
-            a simpler interface that can be used by more USB hardware.
-         RNDIS support is an additional option, more demanding than than
-         subset.
-         Within the USB device, this gadget driver exposes a network device
-         "usbX", where X depends on what other networking devices you have.
-         Treat it like a two-node Ethernet link:  host, and gadget.
-         The Linux-USB host-side "usbnet" driver interoperates with this
-         driver, so that deep I/O queues can be supported.  On 2.4 kernels,
-         use "CDCEther" instead, if you're using the CDC option. That CDC
-         mode should also interoperate with standard CDC Ethernet class
-         drivers on other host operating systems.
-         Say "y" to link the driver statically, or "m" to build a
-         dynamically linked module called "g_ether".
- config USB_ETH_RNDIS
-       bool "RNDIS support"
-       depends on USB_ETH
-       select USB_LIBCOMPOSITE
-       select USB_F_RNDIS
-       default y
-       help
-          Microsoft Windows XP bundles the "Remote NDIS" (RNDIS) protocol,
-          and Microsoft provides redistributable binary RNDIS drivers for
-          older versions of Windows.
-          If you say "y" here, the Ethernet gadget driver will try to provide
-          a second device configuration, supporting RNDIS to talk to such
-          Microsoft USB hosts.
-          
-          To make MS-Windows work with this, use Documentation/usb/linux.inf
-          as the "driver info file".  For versions of MS-Windows older than
-          XP, you'll need to download drivers from Microsoft's website; a URL
-          is given in comments found in that info file.
- config USB_ETH_EEM
-        bool "Ethernet Emulation Model (EEM) support"
-        depends on USB_ETH
-       select USB_LIBCOMPOSITE
-       select USB_F_EEM
-        default n
-        help
-          CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM
-          and therefore can be supported by more hardware.  Technically ECM and
-          EEM are designed for different applications.  The ECM model extends
-          the network interface to the target (e.g. a USB cable modem), and the
-          EEM model is for mobile devices to communicate with hosts using
-          ethernet over USB.  For Linux gadgets, however, the interface with
-          the host is the same (a usbX device), so the differences are minimal.
-          If you say "y" here, the Ethernet gadget driver will use the EEM
-          protocol rather than ECM.  If unsure, say "n".
- config USB_G_NCM
-       tristate "Network Control Model (NCM) support"
-       depends on NET
-       select USB_LIBCOMPOSITE
-       select USB_U_ETHER
-       select USB_F_NCM
-       select CRC32
-       help
-         This driver implements USB CDC NCM subclass standard. NCM is
-         an advanced protocol for Ethernet encapsulation, allows grouping
-         of several ethernet frames into one USB transfer and different
-         alignment possibilities.
-         Say "y" to link the driver statically, or "m" to build a
-         dynamically linked module called "g_ncm".
- config USB_GADGETFS
-       tristate "Gadget Filesystem"
-       help
-         This driver provides a filesystem based API that lets user mode
-         programs implement a single-configuration USB device, including
-         endpoint I/O and control requests that don't relate to enumeration.
-         All endpoints, transfer speeds, and transfer types supported by
-         the hardware are available, through read() and write() calls.
-         Say "y" to link the driver statically, or "m" to build a
-         dynamically linked module called "gadgetfs".
- config USB_FUNCTIONFS
-       tristate "Function Filesystem"
-       select USB_LIBCOMPOSITE
-       select USB_F_FS
-       select USB_FUNCTIONFS_GENERIC if !(USB_FUNCTIONFS_ETH || USB_FUNCTIONFS_RNDIS)
-       help
-         The Function Filesystem (FunctionFS) lets one create USB
-         composite functions in user space in the same way GadgetFS
-         lets one create USB gadgets in user space.  This allows creation
-         of composite gadgets such that some of the functions are
-         implemented in kernel space (for instance Ethernet, serial or
-         mass storage) and other are implemented in user space.
-         If you say "y" or "m" here you will be able what kind of
-         configurations the gadget will provide.
-         Say "y" to link the driver statically, or "m" to build
-         a dynamically linked module called "g_ffs".
- config USB_FUNCTIONFS_ETH
-       bool "Include configuration with CDC ECM (Ethernet)"
-       depends on USB_FUNCTIONFS && NET
-       select USB_U_ETHER
-       select USB_F_ECM
-       select USB_F_SUBSET
-       help
-         Include a configuration with CDC ECM function (Ethernet) and the
-         Function Filesystem.
- config USB_FUNCTIONFS_RNDIS
-       bool "Include configuration with RNDIS (Ethernet)"
-       depends on USB_FUNCTIONFS && NET
-       select USB_U_ETHER
-       select USB_F_RNDIS
-       help
-         Include a configuration with RNDIS function (Ethernet) and the Filesystem.
- config USB_FUNCTIONFS_GENERIC
-       bool "Include 'pure' configuration"
-       depends on USB_FUNCTIONFS
-       help
-         Include a configuration with the Function Filesystem alone with
-         no Ethernet interface.
- config USB_MASS_STORAGE
-       tristate "Mass Storage Gadget"
-       depends on BLOCK
-       select USB_LIBCOMPOSITE
-       select USB_F_MASS_STORAGE
-       help
-         The Mass Storage Gadget acts as a USB Mass Storage disk drive.
-         As its storage repository it can use a regular file or a block
-         device (in much the same way as the "loop" device driver),
-         specified as a module parameter or sysfs option.
-         This driver is a replacement for now removed File-backed
-         Storage Gadget (g_file_storage).
-         Say "y" to link the driver statically, or "m" to build
-         a dynamically linked module called "g_mass_storage".
- config USB_GADGET_TARGET
-       tristate "USB Gadget Target Fabric Module"
-       depends on TARGET_CORE
-       select USB_LIBCOMPOSITE
-       help
-         This fabric is an USB gadget. Two USB protocols are supported that is
-         BBB or BOT (Bulk Only Transport) and UAS (USB Attached SCSI). BOT is
-         advertised on alternative interface 0 (primary) and UAS is on
-         alternative interface 1. Both protocols can work on USB2.0 and USB3.0.
-         UAS utilizes the USB 3.0 feature called streams support.
- config USB_G_SERIAL
-       tristate "Serial Gadget (with CDC ACM and CDC OBEX support)"
-       depends on TTY
-       select USB_U_SERIAL
-       select USB_F_ACM
-       select USB_F_SERIAL
-       select USB_F_OBEX
-       select USB_LIBCOMPOSITE
-       help
-         The Serial Gadget talks to the Linux-USB generic serial driver.
-         This driver supports a CDC-ACM module option, which can be used
-         to interoperate with MS-Windows hosts or with the Linux-USB
-         "cdc-acm" driver.
-         This driver also supports a CDC-OBEX option.  You will need a
-         user space OBEX server talking to /dev/ttyGS*, since the kernel
-         itself doesn't implement the OBEX protocol.
-         Say "y" to link the driver statically, or "m" to build a
-         dynamically linked module called "g_serial".
-         For more information, see Documentation/usb/gadget_serial.txt
-         which includes instructions and a "driver info file" needed to
-         make MS-Windows work with CDC ACM.
- config USB_MIDI_GADGET
-       tristate "MIDI Gadget"
-       depends on SND
-       select USB_LIBCOMPOSITE
-       select SND_RAWMIDI
-       help
-         The MIDI Gadget acts as a USB Audio device, with one MIDI
-         input and one MIDI output. These MIDI jacks appear as
-         a sound "card" in the ALSA sound system. Other MIDI
-         connections can then be made on the gadget system, using
-         ALSA's aconnect utility etc.
-         Say "y" to link the driver statically, or "m" to build a
-         dynamically linked module called "g_midi".
- config USB_G_PRINTER
-       tristate "Printer Gadget"
-       select USB_LIBCOMPOSITE
-       help
-         The Printer Gadget channels data between the USB host and a
-         userspace program driving the print engine. The user space
-         program reads and writes the device file /dev/g_printer to
-         receive or send printer data. It can use ioctl calls to
-         the device file to get or set printer status.
-         Say "y" to link the driver statically, or "m" to build a
-         dynamically linked module called "g_printer".
-         For more information, see Documentation/usb/gadget_printer.txt
-         which includes sample code for accessing the device file.
- config USB_G_ANDROID
-       boolean "Android Composite Gadget"
-       select USB_F_ACM
-       select USB_LIBCOMPOSITE
-       select USB_U_SERIAL
-       select USB_F_MASS_STORAGE
-       select USB_F_FS
-       select SND_PCM
-       help
-         The Android Composite Gadget supports multiple USB
-         functions: adb, acm, mass storage, mtp, accessory
-         and rndis.
-         Each function can be configured and enabled/disabled
-         dynamically from userspace through a sysfs interface.
- config USB_ANDROID_RNDIS_DWORD_ALIGNED
-       boolean "Use double word aligned"
-       depends on USB_G_ANDROID
-       help
-               Provides dword aligned for DMA controller.
- if TTY
- config USB_CDC_COMPOSITE
-       tristate "CDC Composite Device (Ethernet and ACM)"
-       depends on NET
-       select USB_LIBCOMPOSITE
-       select USB_U_SERIAL
-       select USB_U_ETHER
-       select USB_F_ACM
-       select USB_F_ECM
-       help
-         This driver provides two functions in one configuration:
-         a CDC Ethernet (ECM) link, and a CDC ACM (serial port) link.
-         This driver requires four bulk and two interrupt endpoints,
-         plus the ability to handle altsettings.  Not all peripheral
-         controllers are that capable.
-         Say "y" to link the driver statically, or "m" to build a
-         dynamically linked module.
- config USB_G_NOKIA
-       tristate "Nokia composite gadget"
-       depends on PHONET
-       select USB_LIBCOMPOSITE
-       select USB_U_SERIAL
-       select USB_U_ETHER
-       select USB_F_ACM
-       select USB_F_OBEX
-       select USB_F_PHONET
-       select USB_F_ECM
-       help
-         The Nokia composite gadget provides support for acm, obex
-         and phonet in only one composite gadget driver.
-         It's only really useful for N900 hardware. If you're building
-         a kernel for N900, say Y or M here. If unsure, say N.
- config USB_G_ACM_MS
-       tristate "CDC Composite Device (ACM and mass storage)"
-       depends on BLOCK
-       select USB_LIBCOMPOSITE
-       select USB_U_SERIAL
-       select USB_F_ACM
-       select USB_F_MASS_STORAGE
-       help
-         This driver provides two functions in one configuration:
-         a mass storage, and a CDC ACM (serial port) link.
-         Say "y" to link the driver statically, or "m" to build a
-         dynamically linked module called "g_acm_ms".
- config USB_G_MULTI
-       tristate "Multifunction Composite Gadget"
-       depends on BLOCK && NET
-       select USB_G_MULTI_CDC if !USB_G_MULTI_RNDIS
-       select USB_LIBCOMPOSITE
-       select USB_U_SERIAL
-       select USB_U_ETHER
-       select USB_F_ACM
-       select USB_F_MASS_STORAGE
-       help
-         The Multifunction Composite Gadget provides Ethernet (RNDIS
-         and/or CDC Ethernet), mass storage and ACM serial link
-         interfaces.
-         You will be asked to choose which of the two configurations is
-         to be available in the gadget.  At least one configuration must
-         be chosen to make the gadget usable.  Selecting more than one
-         configuration will prevent Windows from automatically detecting
-         the gadget as a composite gadget, so an INF file will be needed to
-         use the gadget.
-         Say "y" to link the driver statically, or "m" to build a
-         dynamically linked module called "g_multi".
- config USB_G_MULTI_RNDIS
-       bool "RNDIS + CDC Serial + Storage configuration"
-       depends on USB_G_MULTI
-       select USB_F_RNDIS
-       default y
-       help
-         This option enables a configuration with RNDIS, CDC Serial and
-         Mass Storage functions available in the Multifunction Composite
-         Gadget.  This is the configuration dedicated for Windows since RNDIS
-         is Microsoft's protocol.
-         If unsure, say "y".
- config USB_G_MULTI_CDC
-       bool "CDC Ethernet + CDC Serial + Storage configuration"
-       depends on USB_G_MULTI
-       default n
-       select USB_F_ECM
-       help
-         This option enables a configuration with CDC Ethernet (ECM), CDC
-         Serial and Mass Storage functions available in the Multifunction
-         Composite Gadget.
-         If unsure, say "y".
- endif # TTY
- config USB_G_HID
-       tristate "HID Gadget"
-       select USB_LIBCOMPOSITE
-       help
-         The HID gadget driver provides generic emulation of USB
-         Human Interface Devices (HID).
-         For more information, see Documentation/usb/gadget_hid.txt which
-         includes sample code for accessing the device files.
-         Say "y" to link the driver statically, or "m" to build a
-         dynamically linked module called "g_hid".
- # Standalone / single function gadgets
- config USB_G_DBGP
-       tristate "EHCI Debug Device Gadget"
-       depends on TTY
-       select USB_LIBCOMPOSITE
-       help
-         This gadget emulates an EHCI Debug device. This is useful when you want
-         to interact with an EHCI Debug Port.
-         Say "y" to link the driver statically, or "m" to build a
-         dynamically linked module called "g_dbgp".
- if USB_G_DBGP
- choice
-       prompt "EHCI Debug Device mode"
-       default USB_G_DBGP_SERIAL
- config USB_G_DBGP_PRINTK
-       depends on USB_G_DBGP
-       bool "printk"
-       help
-         Directly printk() received data. No interaction.
- config USB_G_DBGP_SERIAL
-       depends on USB_G_DBGP
-       select USB_U_SERIAL
-       bool "serial"
-       help
-         Userland can interact using /dev/ttyGSxxx.
- endchoice
- endif
- # put drivers that need isochronous transfer support (for audio
- # or video class gadget drivers), or specific hardware, here.
- config USB_G_WEBCAM
-       tristate "USB Webcam Gadget"
-       depends on VIDEO_DEV
-       select USB_LIBCOMPOSITE
-       select VIDEOBUF2_VMALLOC
-       help
-         The Webcam Gadget acts as a composite USB Audio and Video Class
-         device. It provides a userspace API to process UVC control requests
-         and stream video data to the host.
-         Say "y" to link the driver statically, or "m" to build a
-         dynamically linked module called "g_webcam".
++      boolean "PTP gadget"
++      depends on USB_CONFIGFS && USB_CONFIGFS_F_MTP
++      select USB_F_PTP
++      help
++       USB gadget PTP support
 +
 +config USB_CONFIGFS_UEVENT
 +      boolean "Uevent notification of Gadget state"
 +      depends on USB_CONFIGFS
 +      help
 +        Enable uevent notifications to userspace when the gadget
 +        state changes. The gadget can be in any of the following
 +        three states: "CONNECTED/DISCONNECTED/CONFIGURED"
+ source "drivers/usb/gadget/legacy/Kconfig"
  
  endchoice
  
index b2b05d5ed08a72460db4c1ed6594e9de100738b7,a186afeaa7001f3f81abb4f95d9edd3099477867..2d66813d8907ae273007fcb3817a9193573ec12b
@@@ -7,106 -8,5 +8,6 @@@ ccflags-y                              += -I$(PWD)/drivers/usb/ga
  obj-$(CONFIG_USB_LIBCOMPOSITE)        += libcomposite.o
  libcomposite-y                        := usbstring.o config.o epautoconf.o
  libcomposite-y                        += composite.o functions.o configfs.o u_f.o
- obj-$(CONFIG_USB_DUMMY_HCD)   += dummy_hcd.o
- obj-$(CONFIG_USB_NET2272)     += net2272.o
- obj-$(CONFIG_USB_NET2280)     += net2280.o
- obj-$(CONFIG_USB_AMD5536UDC)  += amd5536udc.o
- obj-$(CONFIG_USB_PXA25X)      += pxa25x_udc.o
- obj-$(CONFIG_USB_PXA27X)      += pxa27x_udc.o
- obj-$(CONFIG_USB_GOKU)                += goku_udc.o
- obj-$(CONFIG_USB_OMAP)                += omap_udc.o
- obj-$(CONFIG_USB_S3C2410)     += s3c2410_udc.o
- obj-$(CONFIG_USB_AT91)                += at91_udc.o
- obj-$(CONFIG_USB_ATMEL_USBA)  += atmel_usba_udc.o
- obj-$(CONFIG_USB_BCM63XX_UDC) += bcm63xx_udc.o
- obj-$(CONFIG_USB_FSL_USB2)    += fsl_usb2_udc.o
- fsl_usb2_udc-y                        := fsl_udc_core.o
- fsl_usb2_udc-$(CONFIG_ARCH_MXC)       += fsl_mxc_udc.o
- obj-$(CONFIG_USB_M66592)      += m66592-udc.o
- obj-$(CONFIG_USB_R8A66597)    += r8a66597-udc.o
- obj-$(CONFIG_USB_FSL_QE)      += fsl_qe_udc.o
- obj-$(CONFIG_USB_S3C_HSOTG)   += s3c-hsotg.o
- obj-$(CONFIG_USB_S3C_HSUDC)   += s3c-hsudc.o
- obj-$(CONFIG_USB_LPC32XX)     += lpc32xx_udc.o
- obj-$(CONFIG_USB_EG20T)               += pch_udc.o
- obj-$(CONFIG_USB_MV_UDC)      += mv_udc.o
- mv_udc-y                      := mv_udc_core.o
- obj-$(CONFIG_USB_FUSB300)     += fusb300_udc.o
- obj-$(CONFIG_USB_FOTG210_UDC) += fotg210-udc.o
- obj-$(CONFIG_USB_MV_U3D)      += mv_u3d_core.o
- obj-$(CONFIG_USB_GR_UDC)      += gr_udc.o
  
- # USB Functions
- usb_f_acm-y                   := f_acm.o
- obj-$(CONFIG_USB_F_ACM)               += usb_f_acm.o
- usb_f_ss_lb-y                 := f_loopback.o f_sourcesink.o
- obj-$(CONFIG_USB_F_SS_LB)     += usb_f_ss_lb.o
- obj-$(CONFIG_USB_U_SERIAL)    += u_serial.o
- usb_f_serial-y                        := f_serial.o
- obj-$(CONFIG_USB_F_SERIAL)    += usb_f_serial.o
- usb_f_obex-y                  := f_obex.o
- obj-$(CONFIG_USB_F_OBEX)      += usb_f_obex.o
- obj-$(CONFIG_USB_U_ETHER)     += u_ether.o
- usb_f_ncm-y                   := f_ncm.o
- obj-$(CONFIG_USB_F_NCM)               += usb_f_ncm.o
- usb_f_ecm-y                   := f_ecm.o
- obj-$(CONFIG_USB_F_ECM)               += usb_f_ecm.o
- usb_f_phonet-y                        := f_phonet.o
- obj-$(CONFIG_USB_F_PHONET)    += usb_f_phonet.o
- usb_f_eem-y                   := f_eem.o
- obj-$(CONFIG_USB_F_EEM)               += usb_f_eem.o
- usb_f_ecm_subset-y            := f_subset.o
- obj-$(CONFIG_USB_F_SUBSET)    += usb_f_ecm_subset.o
- usb_f_rndis-y                 := f_rndis.o rndis.o
- obj-$(CONFIG_USB_F_RNDIS)     += usb_f_rndis.o
- usb_f_mass_storage-y          := f_mass_storage.o storage_common.o
- obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
- usb_f_fs-y                    := f_fs.o
- obj-$(CONFIG_USB_F_FS)                += usb_f_fs.o
- usb_f_mtp-y                   := f_mtp.o
- obj-$(CONFIG_USB_F_MTP)               += usb_f_mtp.o
- usb_f_ptp-y                   := f_ptp.o
- obj-$(CONFIG_USB_F_PTP)               += usb_f_ptp.o
 +
- #
- # USB gadget drivers
- #
- g_zero-y                      := zero.o
- g_audio-y                     := audio.o
- g_ether-y                     := ether.o
- g_serial-y                    := serial.o
- g_midi-y                      := gmidi.o
- gadgetfs-y                    := inode.o
- g_mass_storage-y              := mass_storage.o
- g_printer-y                   := printer.o
- g_cdc-y                               := cdc2.o
- g_multi-y                     := multi.o
- g_hid-y                               := hid.o
- g_dbgp-y                      := dbgp.o
- g_nokia-y                     := nokia.o
- g_webcam-y                    := webcam.o
- g_ncm-y                               := ncm.o
- g_acm_ms-y                    := acm_ms.o
- g_android-y                   := android.o
- g_tcm_usb_gadget-y            := tcm_usb_gadget.o
- obj-$(CONFIG_USB_ZERO)                += g_zero.o
- obj-$(CONFIG_USB_AUDIO)               += g_audio.o
- obj-$(CONFIG_USB_ETH)         += g_ether.o
- obj-$(CONFIG_USB_GADGETFS)    += gadgetfs.o
- obj-$(CONFIG_USB_FUNCTIONFS)  += g_ffs.o
- obj-$(CONFIG_USB_MASS_STORAGE)        += g_mass_storage.o
- obj-$(CONFIG_USB_G_SERIAL)    += g_serial.o
- obj-$(CONFIG_USB_G_PRINTER)   += g_printer.o
- obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o
- obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o
- obj-$(CONFIG_USB_G_HID)               += g_hid.o
- obj-$(CONFIG_USB_G_DBGP)      += g_dbgp.o
- obj-$(CONFIG_USB_G_MULTI)     += g_multi.o
- obj-$(CONFIG_USB_G_NOKIA)     += g_nokia.o
- obj-$(CONFIG_USB_G_WEBCAM)    += g_webcam.o
- obj-$(CONFIG_USB_G_NCM)               += g_ncm.o
- obj-$(CONFIG_USB_G_ACM_MS)    += g_acm_ms.o
- obj-$(CONFIG_USB_G_ANDROID)   += g_android.o
- obj-$(CONFIG_USB_GADGET_TARGET)       += tcm_usb_gadget.o
+ obj-$(CONFIG_USB_GADGET)      += udc/ function/ legacy/
Simple merge
Simple merge
index 0000000000000000000000000000000000000000,6d91f21b52a6301c303aac0a4f62e572d83c02aa..3a0544146bc3e14c512979ca928337959b40026e
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,34 +1,38 @@@
+ #
+ # USB peripheral controller drivers
+ #
+ ccflags-y                     := -I$(PWD)/drivers/usb/gadget/
+ ccflags-y                     += -I$(PWD)/drivers/usb/gadget/udc/
+ # USB Functions
+ usb_f_acm-y                   := f_acm.o
+ obj-$(CONFIG_USB_F_ACM)               += usb_f_acm.o
+ usb_f_ss_lb-y                 := f_loopback.o f_sourcesink.o
+ obj-$(CONFIG_USB_F_SS_LB)     += usb_f_ss_lb.o
+ obj-$(CONFIG_USB_U_SERIAL)    += u_serial.o
+ usb_f_serial-y                        := f_serial.o
+ obj-$(CONFIG_USB_F_SERIAL)    += usb_f_serial.o
+ usb_f_obex-y                  := f_obex.o
+ obj-$(CONFIG_USB_F_OBEX)      += usb_f_obex.o
+ obj-$(CONFIG_USB_U_ETHER)     += u_ether.o
+ usb_f_ncm-y                   := f_ncm.o
+ obj-$(CONFIG_USB_F_NCM)               += usb_f_ncm.o
+ usb_f_ecm-y                   := f_ecm.o
+ obj-$(CONFIG_USB_F_ECM)               += usb_f_ecm.o
+ usb_f_phonet-y                        := f_phonet.o
+ obj-$(CONFIG_USB_F_PHONET)    += usb_f_phonet.o
+ usb_f_eem-y                   := f_eem.o
+ obj-$(CONFIG_USB_F_EEM)               += usb_f_eem.o
+ usb_f_ecm_subset-y            := f_subset.o
+ obj-$(CONFIG_USB_F_SUBSET)    += usb_f_ecm_subset.o
+ usb_f_rndis-y                 := f_rndis.o rndis.o
+ obj-$(CONFIG_USB_F_RNDIS)     += usb_f_rndis.o
+ usb_f_mass_storage-y          := f_mass_storage.o storage_common.o
+ obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o
+ usb_f_fs-y                    := f_fs.o
+ obj-$(CONFIG_USB_F_FS)                += usb_f_fs.o
++usb_f_mtp-y                   := f_mtp.o
++obj-$(CONFIG_USB_F_MTP)               += usb_f_mtp.o
++usb_f_ptp-y                   := f_ptp.o
++obj-$(CONFIG_USB_F_PTP)               += usb_f_ptp.o
index dcedeb4b2fefeccf5722d9dda55fd9a17a3eb9e9,0000000000000000000000000000000000000000..dcedeb4b2fefeccf5722d9dda55fd9a17a3eb9e9
mode 100644,000000..100644
--- /dev/null
index 21ced13c83d801b39c3bbb564bb5005706d3f42c,0000000000000000000000000000000000000000..21ced13c83d801b39c3bbb564bb5005706d3f42c
mode 100644,000000..100644
--- /dev/null
Simple merge
index d260d071ab9efa740f217e92a9e277e9627f95d5,0000000000000000000000000000000000000000..d260d071ab9efa740f217e92a9e277e9627f95d5
mode 100644,000000..100644
--- /dev/null
index 7adb1ff08eff1236dfe069dea9fbde05865313b6,0000000000000000000000000000000000000000..7adb1ff08eff1236dfe069dea9fbde05865313b6
mode 100644,000000..100644
--- /dev/null
index da3e4d53e085bc3a767d6f81da166fdd51c8032d,0000000000000000000000000000000000000000..da3e4d53e085bc3a767d6f81da166fdd51c8032d
mode 100644,000000..100644
--- /dev/null
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 0000000000000000000000000000000000000000,aa376f006333f4232998bed29a1594b2ee747dc8..f7a264eba8e5f19ba979513a801ca047ce1e25b5
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,475 +1,496 @@@
+ #
+ # USB Gadget support on a system involves
+ #    (a) a peripheral controller, and
+ #    (b) the gadget driver using it.
+ #
+ # NOTE:  Gadget support ** DOES NOT ** depend on host-side CONFIG_USB !!
+ #
+ #  - Host systems (like PCs) need CONFIG_USB (with "A" jacks).
+ #  - Peripherals (like PDAs) need CONFIG_USB_GADGET (with "B" jacks).
+ #  - Some systems have both kinds of controllers.
+ #
+ # With help from a special transceiver and a "Mini-AB" jack, systems with
+ # both kinds of controller can also support "USB On-the-Go" (CONFIG_USB_OTG).
+ #
+ config USB_ZERO
+       tristate "Gadget Zero (DEVELOPMENT)"
+       select USB_LIBCOMPOSITE
+       select USB_F_SS_LB
+       help
+         Gadget Zero is a two-configuration device.  It either sinks and
+         sources bulk data; or it loops back a configurable number of
+         transfers.  It also implements control requests, for "chapter 9"
+         conformance.  The driver needs only two bulk-capable endpoints, so
+         it can work on top of most device-side usb controllers.  It's
+         useful for testing, and is also a working example showing how
+         USB "gadget drivers" can be written.
+         Make this be the first driver you try using on top of any new
+         USB peripheral controller driver.  Then you can use host-side
+         test software, like the "usbtest" driver, to put your hardware
+         and its driver through a basic set of functional tests.
+         Gadget Zero also works with the host-side "usb-skeleton" driver,
+         and with many kinds of host-side test software.  You may need
+         to tweak product and vendor IDs before host software knows about
+         this device, and arrange to select an appropriate configuration.
+         Say "y" to link the driver statically, or "m" to build a
+         dynamically linked module called "g_zero".
+ config USB_ZERO_HNPTEST
+       boolean "HNP Test Device"
+       depends on USB_ZERO && USB_OTG
+       help
+         You can configure this device to enumerate using the device
+         identifiers of the USB-OTG test device.  That means that when
+         this gadget connects to another OTG device, with this one using
+         the "B-Peripheral" role, that device will use HNP to let this
+         one serve as the USB host instead (in the "B-Host" role).
+ config USB_AUDIO
+       tristate "Audio Gadget"
+       depends on SND
+       select USB_LIBCOMPOSITE
+       select SND_PCM
+       help
+         This Gadget Audio driver is compatible with USB Audio Class
+         specification 2.0. It implements 1 AudioControl interface,
+         1 AudioStreaming Interface each for USB-OUT and USB-IN.
+         Number of channels, sample rate and sample size can be
+         specified as module parameters.
+         This driver doesn't expect any real Audio codec to be present
+         on the device - the audio streams are simply sinked to and
+         sourced from a virtual ALSA sound card created. The user-space
+         application may choose to do whatever it wants with the data
+         received from the USB Host and choose to provide whatever it
+         wants as audio data to the USB Host.
+         Say "y" to link the driver statically, or "m" to build a
+         dynamically linked module called "g_audio".
+ config GADGET_UAC1
+       bool "UAC 1.0 (Legacy)"
+       depends on USB_AUDIO
+       help
+         If you instead want older UAC Spec-1.0 driver that also has audio
+         paths hardwired to the Audio codec chip on-board and doesn't work
+         without one.
+ config USB_ETH
+       tristate "Ethernet Gadget (with CDC Ethernet support)"
+       depends on NET
+       select USB_LIBCOMPOSITE
+       select USB_U_ETHER
+       select USB_F_ECM
+       select USB_F_SUBSET
+       select CRC32
+       help
+         This driver implements Ethernet style communication, in one of
+         several ways:
+          - The "Communication Device Class" (CDC) Ethernet Control Model.
+            That protocol is often avoided with pure Ethernet adapters, in
+            favor of simpler vendor-specific hardware, but is widely
+            supported by firmware for smart network devices.
+          - On hardware can't implement that protocol, a simple CDC subset
+            is used, placing fewer demands on USB.
+          - CDC Ethernet Emulation Model (EEM) is a newer standard that has
+            a simpler interface that can be used by more USB hardware.
+         RNDIS support is an additional option, more demanding than than
+         subset.
+         Within the USB device, this gadget driver exposes a network device
+         "usbX", where X depends on what other networking devices you have.
+         Treat it like a two-node Ethernet link:  host, and gadget.
+         The Linux-USB host-side "usbnet" driver interoperates with this
+         driver, so that deep I/O queues can be supported.  On 2.4 kernels,
+         use "CDCEther" instead, if you're using the CDC option. That CDC
+         mode should also interoperate with standard CDC Ethernet class
+         drivers on other host operating systems.
+         Say "y" to link the driver statically, or "m" to build a
+         dynamically linked module called "g_ether".
+ config USB_ETH_RNDIS
+       bool "RNDIS support"
+       depends on USB_ETH
+       select USB_LIBCOMPOSITE
+       select USB_F_RNDIS
+       default y
+       help
+          Microsoft Windows XP bundles the "Remote NDIS" (RNDIS) protocol,
+          and Microsoft provides redistributable binary RNDIS drivers for
+          older versions of Windows.
+          If you say "y" here, the Ethernet gadget driver will try to provide
+          a second device configuration, supporting RNDIS to talk to such
+          Microsoft USB hosts.
+          To make MS-Windows work with this, use Documentation/usb/linux.inf
+          as the "driver info file".  For versions of MS-Windows older than
+          XP, you'll need to download drivers from Microsoft's website; a URL
+          is given in comments found in that info file.
+ config USB_ETH_EEM
+        bool "Ethernet Emulation Model (EEM) support"
+        depends on USB_ETH
+       select USB_LIBCOMPOSITE
+       select USB_F_EEM
+        default n
+        help
+          CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM
+          and therefore can be supported by more hardware.  Technically ECM and
+          EEM are designed for different applications.  The ECM model extends
+          the network interface to the target (e.g. a USB cable modem), and the
+          EEM model is for mobile devices to communicate with hosts using
+          ethernet over USB.  For Linux gadgets, however, the interface with
+          the host is the same (a usbX device), so the differences are minimal.
+          If you say "y" here, the Ethernet gadget driver will use the EEM
+          protocol rather than ECM.  If unsure, say "n".
+ config USB_G_NCM
+       tristate "Network Control Model (NCM) support"
+       depends on NET
+       select USB_LIBCOMPOSITE
+       select USB_U_ETHER
+       select USB_F_NCM
+       select CRC32
+       help
+         This driver implements USB CDC NCM subclass standard. NCM is
+         an advanced protocol for Ethernet encapsulation, allows grouping
+         of several ethernet frames into one USB transfer and different
+         alignment possibilities.
+         Say "y" to link the driver statically, or "m" to build a
+         dynamically linked module called "g_ncm".
+ config USB_GADGETFS
+       tristate "Gadget Filesystem"
+       help
+         This driver provides a filesystem based API that lets user mode
+         programs implement a single-configuration USB device, including
+         endpoint I/O and control requests that don't relate to enumeration.
+         All endpoints, transfer speeds, and transfer types supported by
+         the hardware are available, through read() and write() calls.
+         Say "y" to link the driver statically, or "m" to build a
+         dynamically linked module called "gadgetfs".
+ config USB_FUNCTIONFS
+       tristate "Function Filesystem"
+       select USB_LIBCOMPOSITE
+       select USB_F_FS
+       select USB_FUNCTIONFS_GENERIC if !(USB_FUNCTIONFS_ETH || USB_FUNCTIONFS_RNDIS)
+       help
+         The Function Filesystem (FunctionFS) lets one create USB
+         composite functions in user space in the same way GadgetFS
+         lets one create USB gadgets in user space.  This allows creation
+         of composite gadgets such that some of the functions are
+         implemented in kernel space (for instance Ethernet, serial or
+         mass storage) and other are implemented in user space.
+         If you say "y" or "m" here you will be able what kind of
+         configurations the gadget will provide.
+         Say "y" to link the driver statically, or "m" to build
+         a dynamically linked module called "g_ffs".
+ config USB_FUNCTIONFS_ETH
+       bool "Include configuration with CDC ECM (Ethernet)"
+       depends on USB_FUNCTIONFS && NET
+       select USB_U_ETHER
+       select USB_F_ECM
+       select USB_F_SUBSET
+       help
+         Include a configuration with CDC ECM function (Ethernet) and the
+         Function Filesystem.
+ config USB_FUNCTIONFS_RNDIS
+       bool "Include configuration with RNDIS (Ethernet)"
+       depends on USB_FUNCTIONFS && NET
+       select USB_U_ETHER
+       select USB_F_RNDIS
+       help
+         Include a configuration with RNDIS function (Ethernet) and the Filesystem.
+ config USB_FUNCTIONFS_GENERIC
+       bool "Include 'pure' configuration"
+       depends on USB_FUNCTIONFS
+       help
+         Include a configuration with the Function Filesystem alone with
+         no Ethernet interface.
+ config USB_MASS_STORAGE
+       tristate "Mass Storage Gadget"
+       depends on BLOCK
+       select USB_LIBCOMPOSITE
+       select USB_F_MASS_STORAGE
+       help
+         The Mass Storage Gadget acts as a USB Mass Storage disk drive.
+         As its storage repository it can use a regular file or a block
+         device (in much the same way as the "loop" device driver),
+         specified as a module parameter or sysfs option.
+         This driver is a replacement for now removed File-backed
+         Storage Gadget (g_file_storage).
+         Say "y" to link the driver statically, or "m" to build
+         a dynamically linked module called "g_mass_storage".
+ config USB_GADGET_TARGET
+       tristate "USB Gadget Target Fabric Module"
+       depends on TARGET_CORE
+       select USB_LIBCOMPOSITE
+       help
+         This fabric is an USB gadget. Two USB protocols are supported that is
+         BBB or BOT (Bulk Only Transport) and UAS (USB Attached SCSI). BOT is
+         advertised on alternative interface 0 (primary) and UAS is on
+         alternative interface 1. Both protocols can work on USB2.0 and USB3.0.
+         UAS utilizes the USB 3.0 feature called streams support.
+ config USB_G_SERIAL
+       tristate "Serial Gadget (with CDC ACM and CDC OBEX support)"
+       depends on TTY
+       select USB_U_SERIAL
+       select USB_F_ACM
+       select USB_F_SERIAL
+       select USB_F_OBEX
+       select USB_LIBCOMPOSITE
+       help
+         The Serial Gadget talks to the Linux-USB generic serial driver.
+         This driver supports a CDC-ACM module option, which can be used
+         to interoperate with MS-Windows hosts or with the Linux-USB
+         "cdc-acm" driver.
+         This driver also supports a CDC-OBEX option.  You will need a
+         user space OBEX server talking to /dev/ttyGS*, since the kernel
+         itself doesn't implement the OBEX protocol.
+         Say "y" to link the driver statically, or "m" to build a
+         dynamically linked module called "g_serial".
+         For more information, see Documentation/usb/gadget_serial.txt
+         which includes instructions and a "driver info file" needed to
+         make MS-Windows work with CDC ACM.
+ config USB_MIDI_GADGET
+       tristate "MIDI Gadget"
+       depends on SND
+       select USB_LIBCOMPOSITE
+       select SND_RAWMIDI
+       help
+         The MIDI Gadget acts as a USB Audio device, with one MIDI
+         input and one MIDI output. These MIDI jacks appear as
+         a sound "card" in the ALSA sound system. Other MIDI
+         connections can then be made on the gadget system, using
+         ALSA's aconnect utility etc.
+         Say "y" to link the driver statically, or "m" to build a
+         dynamically linked module called "g_midi".
+ config USB_G_PRINTER
+       tristate "Printer Gadget"
+       select USB_LIBCOMPOSITE
+       help
+         The Printer Gadget channels data between the USB host and a
+         userspace program driving the print engine. The user space
+         program reads and writes the device file /dev/g_printer to
+         receive or send printer data. It can use ioctl calls to
+         the device file to get or set printer status.
+         Say "y" to link the driver statically, or "m" to build a
+         dynamically linked module called "g_printer".
+         For more information, see Documentation/usb/gadget_printer.txt
+         which includes sample code for accessing the device file.
+ if TTY
+ config USB_CDC_COMPOSITE
+       tristate "CDC Composite Device (Ethernet and ACM)"
+       depends on NET
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
+       select USB_U_ETHER
+       select USB_F_ACM
+       select USB_F_ECM
+       help
+         This driver provides two functions in one configuration:
+         a CDC Ethernet (ECM) link, and a CDC ACM (serial port) link.
+         This driver requires four bulk and two interrupt endpoints,
+         plus the ability to handle altsettings.  Not all peripheral
+         controllers are that capable.
+         Say "y" to link the driver statically, or "m" to build a
+         dynamically linked module.
+ config USB_G_NOKIA
+       tristate "Nokia composite gadget"
+       depends on PHONET
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
+       select USB_U_ETHER
+       select USB_F_ACM
+       select USB_F_OBEX
+       select USB_F_PHONET
+       select USB_F_ECM
+       help
+         The Nokia composite gadget provides support for acm, obex
+         and phonet in only one composite gadget driver.
+         It's only really useful for N900 hardware. If you're building
+         a kernel for N900, say Y or M here. If unsure, say N.
+ config USB_G_ACM_MS
+       tristate "CDC Composite Device (ACM and mass storage)"
+       depends on BLOCK
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
+       select USB_F_ACM
+       select USB_F_MASS_STORAGE
+       help
+         This driver provides two functions in one configuration:
+         a mass storage, and a CDC ACM (serial port) link.
+         Say "y" to link the driver statically, or "m" to build a
+         dynamically linked module called "g_acm_ms".
+ config USB_G_MULTI
+       tristate "Multifunction Composite Gadget"
+       depends on BLOCK && NET
+       select USB_G_MULTI_CDC if !USB_G_MULTI_RNDIS
+       select USB_LIBCOMPOSITE
+       select USB_U_SERIAL
+       select USB_U_ETHER
+       select USB_F_ACM
+       select USB_F_MASS_STORAGE
+       help
+         The Multifunction Composite Gadget provides Ethernet (RNDIS
+         and/or CDC Ethernet), mass storage and ACM serial link
+         interfaces.
+         You will be asked to choose which of the two configurations is
+         to be available in the gadget.  At least one configuration must
+         be chosen to make the gadget usable.  Selecting more than one
+         configuration will prevent Windows from automatically detecting
+         the gadget as a composite gadget, so an INF file will be needed to
+         use the gadget.
+         Say "y" to link the driver statically, or "m" to build a
+         dynamically linked module called "g_multi".
+ config USB_G_MULTI_RNDIS
+       bool "RNDIS + CDC Serial + Storage configuration"
+       depends on USB_G_MULTI
+       select USB_F_RNDIS
+       default y
+       help
+         This option enables a configuration with RNDIS, CDC Serial and
+         Mass Storage functions available in the Multifunction Composite
+         Gadget.  This is the configuration dedicated for Windows since RNDIS
+         is Microsoft's protocol.
+         If unsure, say "y".
+ config USB_G_MULTI_CDC
+       bool "CDC Ethernet + CDC Serial + Storage configuration"
+       depends on USB_G_MULTI
+       default n
+       select USB_F_ECM
+       help
+         This option enables a configuration with CDC Ethernet (ECM), CDC
+         Serial and Mass Storage functions available in the Multifunction
+         Composite Gadget.
+         If unsure, say "y".
+ endif # TTY
+ config USB_G_HID
+       tristate "HID Gadget"
+       select USB_LIBCOMPOSITE
+       help
+         The HID gadget driver provides generic emulation of USB
+         Human Interface Devices (HID).
+         For more information, see Documentation/usb/gadget_hid.txt which
+         includes sample code for accessing the device files.
+         Say "y" to link the driver statically, or "m" to build a
+         dynamically linked module called "g_hid".
+ # Standalone / single function gadgets
+ config USB_G_DBGP
+       tristate "EHCI Debug Device Gadget"
+       depends on TTY
+       select USB_LIBCOMPOSITE
+       help
+         This gadget emulates an EHCI Debug device. This is useful when you want
+         to interact with an EHCI Debug Port.
+         Say "y" to link the driver statically, or "m" to build a
+         dynamically linked module called "g_dbgp".
+ if USB_G_DBGP
+ choice
+       prompt "EHCI Debug Device mode"
+       default USB_G_DBGP_SERIAL
+ config USB_G_DBGP_PRINTK
+       depends on USB_G_DBGP
+       bool "printk"
+       help
+         Directly printk() received data. No interaction.
+ config USB_G_DBGP_SERIAL
+       depends on USB_G_DBGP
+       select USB_U_SERIAL
+       bool "serial"
+       help
+         Userland can interact using /dev/ttyGSxxx.
+ endchoice
+ endif
+ # put drivers that need isochronous transfer support (for audio
+ # or video class gadget drivers), or specific hardware, here.
+ config USB_G_WEBCAM
+       tristate "USB Webcam Gadget"
+       depends on VIDEO_DEV
+       select USB_LIBCOMPOSITE
+       select VIDEOBUF2_VMALLOC
+       help
+         The Webcam Gadget acts as a composite USB Audio and Video Class
+         device. It provides a userspace API to process UVC control requests
+         and stream video data to the host.
+         Say "y" to link the driver statically, or "m" to build a
+         dynamically linked module called "g_webcam".
++
++config USB_G_ANDROID
++      boolean "Android Composite Gadget"
++      select USB_F_ACM
++      select USB_LIBCOMPOSITE
++      select USB_U_SERIAL
++      select USB_F_MASS_STORAGE
++      select USB_F_FS
++      select SND_PCM
++      help
++        The Android Composite Gadget supports multiple USB
++        functions: adb, acm, mass storage, mtp, accessory
++        and rndis.
++        Each function can be configured and enabled/disabled
++        dynamically from userspace through a sysfs interface.
++
++config USB_ANDROID_RNDIS_DWORD_ALIGNED
++      boolean "Use double word aligned"
++      depends on USB_G_ANDROID
++      help
++              Provides dword aligned for DMA controller.
index 0000000000000000000000000000000000000000,a11aad5635df415422feb5f0a32d8d269cc14b6d..45a3f026ec3dfe4c400b3b6a37546ed9fedb1f9c
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,44 +1,46 @@@
+ #
+ # USB gadget drivers
+ #
+ ccflags-y                     := -I$(PWD)/drivers/usb/gadget/
+ ccflags-y                     += -I$(PWD)/drivers/usb/gadget/udc/
+ ccflags-y                     += -I$(PWD)/drivers/usb/gadget/function/
+ g_zero-y                      := zero.o
+ g_audio-y                     := audio.o
+ g_ether-y                     := ether.o
+ g_serial-y                    := serial.o
+ g_midi-y                      := gmidi.o
+ gadgetfs-y                    := inode.o
+ g_mass_storage-y              := mass_storage.o
+ g_printer-y                   := printer.o
+ g_cdc-y                               := cdc2.o
+ g_multi-y                     := multi.o
+ g_hid-y                               := hid.o
+ g_dbgp-y                      := dbgp.o
+ g_nokia-y                     := nokia.o
+ g_webcam-y                    := webcam.o
+ g_ncm-y                               := ncm.o
+ g_acm_ms-y                    := acm_ms.o
++g_android-y                   := android.o
+ g_tcm_usb_gadget-y            := tcm_usb_gadget.o
+ obj-$(CONFIG_USB_ZERO)                += g_zero.o
+ obj-$(CONFIG_USB_AUDIO)               += g_audio.o
+ obj-$(CONFIG_USB_ETH)         += g_ether.o
+ obj-$(CONFIG_USB_GADGETFS)    += gadgetfs.o
+ obj-$(CONFIG_USB_FUNCTIONFS)  += g_ffs.o
+ obj-$(CONFIG_USB_MASS_STORAGE)        += g_mass_storage.o
+ obj-$(CONFIG_USB_G_SERIAL)    += g_serial.o
+ obj-$(CONFIG_USB_G_PRINTER)   += g_printer.o
+ obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o
+ obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o
+ obj-$(CONFIG_USB_G_HID)               += g_hid.o
+ obj-$(CONFIG_USB_G_DBGP)      += g_dbgp.o
+ obj-$(CONFIG_USB_G_MULTI)     += g_multi.o
+ obj-$(CONFIG_USB_G_NOKIA)     += g_nokia.o
+ obj-$(CONFIG_USB_G_WEBCAM)    += g_webcam.o
+ obj-$(CONFIG_USB_G_NCM)               += g_ncm.o
+ obj-$(CONFIG_USB_G_ACM_MS)    += g_acm_ms.o
++obj-$(CONFIG_USB_G_ANDROID)   += g_android.o
+ obj-$(CONFIG_USB_GADGET_TARGET)       += tcm_usb_gadget.o
index 99ebe8aa6f53d80a078e5b74bab79828d4e6c3d0,0000000000000000000000000000000000000000..ce2070f40987e3c32ff64416c59ee0efc2d8814c
mode 100644,000000..100644
--- /dev/null
@@@ -1,1669 -1,0 +1,1669 @@@
- #include "gadget_chips.h"
- #include "u_fs.h"
 +/*
 + * Gadget Driver for Android
 + *
 + * Copyright (C) 2008 Google, Inc.
 + * Author: Mike Lockwood <lockwood@android.com>
 + *         Benoit Goby <benoit@android.com>
 + *
 + * This software is licensed under the terms of the GNU General Public
 + * License version 2, as published by the Free Software Foundation, and
 + * may be copied, distributed, and modified under those terms.
 + *
 + * 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.
 + *
 + */
 +
 +#include <linux/init.h>
 +#include <linux/module.h>
 +#include <linux/fs.h>
 +#include <linux/delay.h>
 +#include <linux/kernel.h>
 +#include <linux/utsname.h>
 +#include <linux/platform_device.h>
 +
 +#include <linux/usb/ch9.h>
 +#include <linux/usb/composite.h>
 +#include <linux/usb/gadget.h>
 +
- #include "f_audio_source.c"
- #include "f_mtp.c"
- #include "f_accessory.c"
++#include "../udc/gadget_chips.h"
++#include "../function/u_fs.h"
 +
- #include "f_rndis.c"
- #include "rndis.c"
- #include "u_ether.c"
++#include "../function/f_audio_source.c"
++#include "../function/f_mtp.c"
++#include "../function/f_accessory.c"
 +#define USB_ETH_RNDIS y
++#include "../function/f_rndis.c"
++#include "../function/rndis.c"
++#include "../function/u_ether.c"
 +
 +USB_ETHERNET_MODULE_PARAMETERS();
 +
 +MODULE_AUTHOR("Mike Lockwood");
 +MODULE_DESCRIPTION("Android Composite USB Driver");
 +MODULE_LICENSE("GPL");
 +MODULE_VERSION("1.0");
 +
 +static const char longname[] = "Gadget Android";
 +
 +/* Default vendor and product IDs, overridden by userspace */
 +#define VENDOR_ID             0x18D1
 +#define PRODUCT_ID            0x0001
 +
 +struct android_usb_function {
 +      char *name;
 +      void *config;
 +
 +      struct device *dev;
 +      char *dev_name;
 +      struct device_attribute **attributes;
 +
 +      /* for android_dev.enabled_functions */
 +      struct list_head enabled_list;
 +
 +      /* Optional: initialization during gadget bind */
 +      int (*init)(struct android_usb_function *, struct usb_composite_dev *);
 +      /* Optional: cleanup during gadget unbind */
 +      void (*cleanup)(struct android_usb_function *);
 +      /* Optional: called when the function is added the list of
 +       *              enabled functions */
 +      void (*enable)(struct android_usb_function *);
 +      /* Optional: called when it is removed */
 +      void (*disable)(struct android_usb_function *);
 +
 +      int (*bind_config)(struct android_usb_function *,
 +                         struct usb_configuration *);
 +
 +      /* Optional: called when the configuration is removed */
 +      void (*unbind_config)(struct android_usb_function *,
 +                            struct usb_configuration *);
 +      /* Optional: handle ctrl requests before the device is configured */
 +      int (*ctrlrequest)(struct android_usb_function *,
 +                                      struct usb_composite_dev *,
 +                                      const struct usb_ctrlrequest *);
 +};
 +
 +struct android_dev {
 +      struct android_usb_function **functions;
 +      struct list_head enabled_functions;
 +      struct usb_composite_dev *cdev;
 +      struct device *dev;
 +
 +      void (*setup_complete)(struct usb_ep *ep,
 +                              struct usb_request *req);
 +
 +      bool enabled;
 +      int disable_depth;
 +      struct mutex mutex;
 +      bool connected;
 +      bool sw_connected;
 +      struct work_struct work;
 +      char ffs_aliases[256];
 +};
 +
 +static struct class *android_class;
 +static struct android_dev *_android_dev;
 +static int android_bind_config(struct usb_configuration *c);
 +static void android_unbind_config(struct usb_configuration *c);
 +
 +/* string IDs are assigned dynamically */
 +#define STRING_MANUFACTURER_IDX               0
 +#define STRING_PRODUCT_IDX            1
 +#define STRING_SERIAL_IDX             2
 +
 +static char manufacturer_string[256];
 +static char product_string[256];
 +static char serial_string[256];
 +
 +/* String Table */
 +static struct usb_string strings_dev[] = {
 +      [STRING_MANUFACTURER_IDX].s = manufacturer_string,
 +      [STRING_PRODUCT_IDX].s = product_string,
 +      [STRING_SERIAL_IDX].s = serial_string,
 +      {  }                    /* end of list */
 +};
 +
 +static struct usb_gadget_strings stringtab_dev = {
 +      .language       = 0x0409,       /* en-us */
 +      .strings        = strings_dev,
 +};
 +
 +static struct usb_gadget_strings *dev_strings[] = {
 +      &stringtab_dev,
 +      NULL,
 +};
 +
 +static struct usb_device_descriptor device_desc = {
 +      .bLength              = sizeof(device_desc),
 +      .bDescriptorType      = USB_DT_DEVICE,
 +      .bcdUSB               = __constant_cpu_to_le16(0x0200),
 +      .bDeviceClass         = USB_CLASS_PER_INTERFACE,
 +      .idVendor             = __constant_cpu_to_le16(VENDOR_ID),
 +      .idProduct            = __constant_cpu_to_le16(PRODUCT_ID),
 +      .bcdDevice            = __constant_cpu_to_le16(0xffff),
 +      .bNumConfigurations   = 1,
 +};
 +
 +static struct usb_configuration android_config_driver = {
 +      .label          = "android",
 +      .unbind         = android_unbind_config,
 +      .bConfigurationValue = 1,
 +      .bmAttributes   = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
 +      .MaxPower       = 500, /* 500ma */
 +};
 +
 +static void android_work(struct work_struct *data)
 +{
 +      struct android_dev *dev = container_of(data, struct android_dev, work);
 +      struct usb_composite_dev *cdev = dev->cdev;
 +      char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL };
 +      char *connected[2]    = { "USB_STATE=CONNECTED", NULL };
 +      char *configured[2]   = { "USB_STATE=CONFIGURED", NULL };
 +      char **uevent_envp = NULL;
 +      unsigned long flags;
 +
 +      spin_lock_irqsave(&cdev->lock, flags);
 +      if (cdev->config)
 +              uevent_envp = configured;
 +      else if (dev->connected != dev->sw_connected)
 +              uevent_envp = dev->connected ? connected : disconnected;
 +      dev->sw_connected = dev->connected;
 +      spin_unlock_irqrestore(&cdev->lock, flags);
 +
 +      if (uevent_envp) {
 +              kobject_uevent_env(&dev->dev->kobj, KOBJ_CHANGE, uevent_envp);
 +              pr_info("%s: sent uevent %s\n", __func__, uevent_envp[0]);
 +      } else {
 +              pr_info("%s: did not send uevent (%d %d %p)\n", __func__,
 +                       dev->connected, dev->sw_connected, cdev->config);
 +      }
 +}
 +
 +static void android_enable(struct android_dev *dev)
 +{
 +      struct usb_composite_dev *cdev = dev->cdev;
 +
 +      if (WARN_ON(!dev->disable_depth))
 +              return;
 +
 +      if (--dev->disable_depth == 0) {
 +              usb_add_config(cdev, &android_config_driver,
 +                                      android_bind_config);
 +              usb_gadget_connect(cdev->gadget);
 +      }
 +}
 +
 +static void android_disable(struct android_dev *dev)
 +{
 +      struct usb_composite_dev *cdev = dev->cdev;
 +
 +      if (dev->disable_depth++ == 0) {
 +              usb_gadget_disconnect(cdev->gadget);
 +              /* Cancel pending control requests */
 +              usb_ep_dequeue(cdev->gadget->ep0, cdev->req);
 +              usb_remove_config(cdev, &android_config_driver);
 +      }
 +}
 +
 +/*-------------------------------------------------------------------------*/
 +/* Supported functions initialization */
 +
 +static int functionfs_ready_callback(struct ffs_data *ffs);
 +static void functionfs_closed_callback(struct ffs_data *ffs);
 +static void *functionfs_acquire_dev_callback(struct ffs_dev *dev);
 +static void functionfs_release_dev_callback(struct ffs_dev *dev);
 +
 +#define MAX_FFS_INSTANCES 1
 +struct functionfs_config {
 +      bool opened;
 +      bool enabled;
 +      int instances;
 +      int instances_on;
 +      struct ffs_data *data;
 +      struct usb_function *f_ffs[MAX_FFS_INSTANCES];
 +      struct usb_function_instance *f_ffs_inst[MAX_FFS_INSTANCES];
 +};
 +
 +static int ffs_function_init(struct android_usb_function *f,
 +                           struct usb_composite_dev *cdev)
 +{
 +      int i;
 +      int ret;
 +      struct functionfs_config *config;
 +      struct f_fs_opts *opts;
 +
 +      config = kzalloc(sizeof(struct functionfs_config), GFP_KERNEL);
 +      if (!config)
 +              return -ENOMEM;
 +      f->config = config;
 +
 +      for (i = 0; i < MAX_FFS_INSTANCES; i++) {
 +              config->f_ffs_inst[i] = usb_get_function_instance("ffs");
 +              if (IS_ERR(config->f_ffs_inst[i])) {
 +                      ret = PTR_ERR(config->f_ffs_inst[i]);
 +                      goto err_usb_get_function_instance;
 +              }
 +              config->f_ffs[i] = usb_get_function(config->f_ffs_inst[i]);
 +              if (IS_ERR(config->f_ffs[i])) {
 +                      ret = PTR_ERR(config->f_ffs[i]);
 +                      goto err_usb_get_function;
 +              }
 +              /* set ops */
 +              opts = to_f_fs_opts(config->f_ffs_inst[i]);
 +              ret = ffs_single_dev(opts->dev);
 +              if (ret)
 +                      goto err_usb_get_function;
 +              opts->dev->ffs_ready_callback = functionfs_ready_callback;
 +              opts->dev->ffs_closed_callback = functionfs_closed_callback;
 +              opts->dev->ffs_acquire_dev_callback =
 +                                              functionfs_acquire_dev_callback;
 +              opts->dev->ffs_release_dev_callback =
 +                                              functionfs_release_dev_callback;
 +              opts->no_configfs = true;
 +      }
 +      return 0;
 +err_usb_get_function_instance:
 +      while (i-- > 0) {
 +              usb_put_function(config->f_ffs[i]);
 +err_usb_get_function:
 +              usb_put_function_instance(config->f_ffs_inst[i]);
 +      }
 +      return ret;
 +}
 +
 +static void ffs_function_cleanup(struct android_usb_function *f)
 +{
 +      int i;
 +      struct functionfs_config *config = f->config;
 +
 +      for (i = 0; i < MAX_FFS_INSTANCES; i++) {
 +              usb_put_function(config->f_ffs[i]);
 +              usb_put_function_instance(config->f_ffs_inst[i]);
 +      }
 +      kfree(f->config);
 +      f->config = NULL;
 +}
 +
 +static void ffs_function_enable(struct android_usb_function *f)
 +{
 +      struct android_dev *dev = _android_dev;
 +      struct functionfs_config *config = f->config;
 +
 +      config->enabled = true;
 +
 +      /* Disable the gadget until the function is ready */
 +      if (!config->opened)
 +              android_disable(dev);
 +}
 +
 +static void ffs_function_disable(struct android_usb_function *f)
 +{
 +      struct android_dev *dev = _android_dev;
 +      struct functionfs_config *config = f->config;
 +
 +      config->enabled = false;
 +
 +      /* Balance the disable that was called in closed_callback */
 +      if (!config->opened)
 +              android_enable(dev);
 +}
 +
 +static int ffs_function_bind_config(struct android_usb_function *f,
 +                                  struct usb_configuration *c)
 +{
 +      int i;
 +      int ret = 0;
 +      struct functionfs_config *config = f->config;
 +
 +      config->instances_on = config->instances;
 +      for (i = 0; i < config->instances_on; i++) {
 +              ret = usb_add_function(c, config->f_ffs[i]);
 +              if (ret) {
 +                      pr_err("Could not bind ffs%u config\n", i);
 +                      goto err_usb_add_function;
 +              }
 +      }
 +
 +      return 0;
 +
 +err_usb_add_function:
 +      while (i-- > 0)
 +              usb_remove_function(c, config->f_ffs[i]);
 +      return ret;
 +}
 +
 +static ssize_t
 +ffs_aliases_show(struct device *pdev, struct device_attribute *attr, char *buf)
 +{
 +      struct android_dev *dev = _android_dev;
 +      int ret;
 +
 +      mutex_lock(&dev->mutex);
 +      ret = sprintf(buf, "%s\n", dev->ffs_aliases);
 +      mutex_unlock(&dev->mutex);
 +
 +      return ret;
 +}
 +
 +static ssize_t
 +ffs_aliases_store(struct device *pdev, struct device_attribute *attr,
 +                                      const char *buf, size_t size)
 +{
 +      struct android_dev *dev = _android_dev;
 +      char buff[256];
 +
 +      mutex_lock(&dev->mutex);
 +
 +      if (dev->enabled) {
 +              mutex_unlock(&dev->mutex);
 +              return -EBUSY;
 +      }
 +
 +      strlcpy(buff, buf, sizeof(buff));
 +      strlcpy(dev->ffs_aliases, strim(buff), sizeof(dev->ffs_aliases));
 +
 +      mutex_unlock(&dev->mutex);
 +
 +      return size;
 +}
 +
 +static ssize_t ffs_instances_show(struct device *dev,
 +              struct device_attribute *attr, char *buf)
 +{
 +      struct android_usb_function *f = dev_get_drvdata(dev);
 +      struct functionfs_config *config = f->config;
 +      return sprintf(buf, "%d\n", config->instances);
 +}
 +
 +static ssize_t ffs_instances_store(struct device *dev,
 +              struct device_attribute *attr, const char *buf, size_t size)
 +{
 +      struct android_usb_function *f = dev_get_drvdata(dev);
 +      struct functionfs_config *config = f->config;
 +      int value;
 +
 +      if (sscanf(buf, "%d", &value) != -1)
 +              return -EINVAL;
 +
 +      if (value > MAX_FFS_INSTANCES)
 +              value = MAX_FFS_INSTANCES;
 +      config->instances = value;
 +      return size;
 +}
 +
 +static DEVICE_ATTR(aliases, S_IRUGO | S_IWUSR, ffs_aliases_show,
 +                                             ffs_aliases_store);
 +static DEVICE_ATTR(ffs_instances, S_IRUGO | S_IWUSR, ffs_instances_show,
 +                                               ffs_instances_store);
 +static struct device_attribute *ffs_function_attributes[] = {
 +      &dev_attr_aliases,
 +      &dev_attr_ffs_instances,
 +      NULL
 +};
 +
 +static struct android_usb_function ffs_function = {
 +      .name           = "ffs",
 +      .init           = ffs_function_init,
 +      .enable         = ffs_function_enable,
 +      .disable        = ffs_function_disable,
 +      .cleanup        = ffs_function_cleanup,
 +      .bind_config    = ffs_function_bind_config,
 +      .attributes     = ffs_function_attributes,
 +};
 +
 +static int __maybe_unused functionfs_ready_callback(struct ffs_data *ffs)
 +{
 +      struct android_dev *dev = _android_dev;
 +      struct functionfs_config *config = ffs_function.config;
 +      int ret = 0;
 +
 +      mutex_lock(&dev->mutex);
 +
 +      config->instances++;
 +      config->data = ffs;
 +      config->opened = true;
 +
 +      if (config->enabled)
 +              android_enable(dev);
 +
 +err:
 +      mutex_unlock(&dev->mutex);
 +      return ret;
 +}
 +
 +static void __maybe_unused functionfs_closed_callback(struct ffs_data *ffs)
 +{
 +      struct android_dev *dev = _android_dev;
 +      struct functionfs_config *config = ffs_function.config;
 +
 +      mutex_lock(&dev->mutex);
 +
 +      if (config->enabled)
 +              android_disable(dev);
 +
 +      --config->instances;
 +      config->opened = false;
 +      config->data = NULL;
 +
 +      mutex_unlock(&dev->mutex);
 +}
 +
 +static void *functionfs_acquire_dev_callback(struct ffs_dev *dev)
 +{
 +      return 0;
 +}
 +
 +static void functionfs_release_dev_callback(struct ffs_dev *dev)
 +{
 +}
 +
 +#define MAX_ACM_INSTANCES 4
 +struct acm_function_config {
 +      int instances;
 +      int instances_on;
 +      struct usb_function *f_acm[MAX_ACM_INSTANCES];
 +      struct usb_function_instance *f_acm_inst[MAX_ACM_INSTANCES];
 +};
 +
 +static int
 +acm_function_init(struct android_usb_function *f,
 +              struct usb_composite_dev *cdev)
 +{
 +      int i;
 +      int ret;
 +      struct acm_function_config *config;
 +
 +      config = kzalloc(sizeof(struct acm_function_config), GFP_KERNEL);
 +      if (!config)
 +              return -ENOMEM;
 +      f->config = config;
 +
 +      for (i = 0; i < MAX_ACM_INSTANCES; i++) {
 +              config->f_acm_inst[i] = usb_get_function_instance("acm");
 +              if (IS_ERR(config->f_acm_inst[i])) {
 +                      ret = PTR_ERR(config->f_acm_inst[i]);
 +                      goto err_usb_get_function_instance;
 +              }
 +              config->f_acm[i] = usb_get_function(config->f_acm_inst[i]);
 +              if (IS_ERR(config->f_acm[i])) {
 +                      ret = PTR_ERR(config->f_acm[i]);
 +                      goto err_usb_get_function;
 +              }
 +      }
 +      return 0;
 +err_usb_get_function_instance:
 +      while (i-- > 0) {
 +              usb_put_function(config->f_acm[i]);
 +err_usb_get_function:
 +              usb_put_function_instance(config->f_acm_inst[i]);
 +      }
 +      return ret;
 +}
 +
 +static void acm_function_cleanup(struct android_usb_function *f)
 +{
 +      int i;
 +      struct acm_function_config *config = f->config;
 +
 +      for (i = 0; i < MAX_ACM_INSTANCES; i++) {
 +              usb_put_function(config->f_acm[i]);
 +              usb_put_function_instance(config->f_acm_inst[i]);
 +      }
 +      kfree(f->config);
 +      f->config = NULL;
 +}
 +
 +static int
 +acm_function_bind_config(struct android_usb_function *f,
 +              struct usb_configuration *c)
 +{
 +      int i;
 +      int ret = 0;
 +      struct acm_function_config *config = f->config;
 +
 +      config->instances_on = config->instances;
 +      for (i = 0; i < config->instances_on; i++) {
 +              ret = usb_add_function(c, config->f_acm[i]);
 +              if (ret) {
 +                      pr_err("Could not bind acm%u config\n", i);
 +                      goto err_usb_add_function;
 +              }
 +      }
 +
 +      return 0;
 +
 +err_usb_add_function:
 +      while (i-- > 0)
 +              usb_remove_function(c, config->f_acm[i]);
 +      return ret;
 +}
 +
 +static void acm_function_unbind_config(struct android_usb_function *f,
 +                                     struct usb_configuration *c)
 +{
 +      int i;
 +      struct acm_function_config *config = f->config;
 +
 +      for (i = 0; i < config->instances_on; i++)
 +              usb_remove_function(c, config->f_acm[i]);
 +}
 +
 +static ssize_t acm_instances_show(struct device *dev,
 +              struct device_attribute *attr, char *buf)
 +{
 +      struct android_usb_function *f = dev_get_drvdata(dev);
 +      struct acm_function_config *config = f->config;
 +      return sprintf(buf, "%d\n", config->instances);
 +}
 +
 +static ssize_t acm_instances_store(struct device *dev,
 +              struct device_attribute *attr, const char *buf, size_t size)
 +{
 +      struct android_usb_function *f = dev_get_drvdata(dev);
 +      struct acm_function_config *config = f->config;
 +      int value;
 +
 +      if (sscanf(buf, "%d", &value) != 1)
 +              return -EINVAL;
 +
 +      if (value > MAX_ACM_INSTANCES)
 +              value = MAX_ACM_INSTANCES;
 +      config->instances = value;
 +      return size;
 +}
 +
 +static DEVICE_ATTR(instances, S_IRUGO | S_IWUSR, acm_instances_show,
 +                                               acm_instances_store);
 +static struct device_attribute *acm_function_attributes[] = {
 +      &dev_attr_instances,
 +      NULL
 +};
 +
 +static struct android_usb_function acm_function = {
 +      .name           = "acm",
 +      .init           = acm_function_init,
 +      .cleanup        = acm_function_cleanup,
 +      .bind_config    = acm_function_bind_config,
 +      .unbind_config  = acm_function_unbind_config,
 +      .attributes     = acm_function_attributes,
 +};
 +
 +
 +static int
 +mtp_function_init(struct android_usb_function *f,
 +              struct usb_composite_dev *cdev)
 +{
 +      return mtp_setup();
 +}
 +
 +static void mtp_function_cleanup(struct android_usb_function *f)
 +{
 +      mtp_cleanup();
 +}
 +
 +static int
 +mtp_function_bind_config(struct android_usb_function *f,
 +              struct usb_configuration *c)
 +{
 +      return mtp_bind_config(c, false);
 +}
 +
 +static int
 +ptp_function_init(struct android_usb_function *f,
 +              struct usb_composite_dev *cdev)
 +{
 +      /* nothing to do - initialization is handled by mtp_function_init */
 +      return 0;
 +}
 +
 +static void ptp_function_cleanup(struct android_usb_function *f)
 +{
 +      /* nothing to do - cleanup is handled by mtp_function_cleanup */
 +}
 +
 +static int
 +ptp_function_bind_config(struct android_usb_function *f,
 +              struct usb_configuration *c)
 +{
 +      return mtp_bind_config(c, true);
 +}
 +
 +static int mtp_function_ctrlrequest(struct android_usb_function *f,
 +                                      struct usb_composite_dev *cdev,
 +                                      const struct usb_ctrlrequest *c)
 +{
 +      return mtp_ctrlrequest(cdev, c);
 +}
 +
 +static struct android_usb_function mtp_function = {
 +      .name           = "mtp",
 +      .init           = mtp_function_init,
 +      .cleanup        = mtp_function_cleanup,
 +      .bind_config    = mtp_function_bind_config,
 +      .ctrlrequest    = mtp_function_ctrlrequest,
 +};
 +
 +/* PTP function is same as MTP with slightly different interface descriptor */
 +static struct android_usb_function ptp_function = {
 +      .name           = "ptp",
 +      .init           = ptp_function_init,
 +      .cleanup        = ptp_function_cleanup,
 +      .bind_config    = ptp_function_bind_config,
 +};
 +
 +
 +struct rndis_function_config {
 +      u8      ethaddr[ETH_ALEN];
 +      u32     vendorID;
 +      char    manufacturer[256];
 +      /* "Wireless" RNDIS; auto-detected by Windows */
 +      bool    wceis;
 +      struct eth_dev *dev;
 +};
 +
 +static int
 +rndis_function_init(struct android_usb_function *f,
 +              struct usb_composite_dev *cdev)
 +{
 +      f->config = kzalloc(sizeof(struct rndis_function_config), GFP_KERNEL);
 +      if (!f->config)
 +              return -ENOMEM;
 +      return 0;
 +}
 +
 +static void rndis_function_cleanup(struct android_usb_function *f)
 +{
 +      kfree(f->config);
 +      f->config = NULL;
 +}
 +
 +static int
 +rndis_function_bind_config(struct android_usb_function *f,
 +              struct usb_configuration *c)
 +{
 +      int ret;
 +      struct eth_dev *dev;
 +      struct rndis_function_config *rndis = f->config;
 +
 +      if (!rndis) {
 +              pr_err("%s: rndis_pdata\n", __func__);
 +              return -1;
 +      }
 +
 +      pr_info("%s MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
 +              rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
 +              rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
 +
 +      dev = gether_setup_name(c->cdev->gadget, dev_addr, host_addr,
 +                                      rndis->ethaddr, qmult, "rndis");
 +      if (IS_ERR(dev)) {
 +              ret = PTR_ERR(dev);
 +              pr_err("%s: gether_setup failed\n", __func__);
 +              return ret;
 +      }
 +      rndis->dev = dev;
 +
 +      if (rndis->wceis) {
 +              /* "Wireless" RNDIS; auto-detected by Windows */
 +              rndis_iad_descriptor.bFunctionClass =
 +                                              USB_CLASS_WIRELESS_CONTROLLER;
 +              rndis_iad_descriptor.bFunctionSubClass = 0x01;
 +              rndis_iad_descriptor.bFunctionProtocol = 0x03;
 +              rndis_control_intf.bInterfaceClass =
 +                                              USB_CLASS_WIRELESS_CONTROLLER;
 +              rndis_control_intf.bInterfaceSubClass =  0x01;
 +              rndis_control_intf.bInterfaceProtocol =  0x03;
 +      }
 +
 +      return rndis_bind_config_vendor(c, rndis->ethaddr, rndis->vendorID,
 +                                         rndis->manufacturer, rndis->dev);
 +}
 +
 +static void rndis_function_unbind_config(struct android_usb_function *f,
 +                                              struct usb_configuration *c)
 +{
 +      struct rndis_function_config *rndis = f->config;
 +      gether_cleanup(rndis->dev);
 +}
 +
 +static ssize_t rndis_manufacturer_show(struct device *dev,
 +              struct device_attribute *attr, char *buf)
 +{
 +      struct android_usb_function *f = dev_get_drvdata(dev);
 +      struct rndis_function_config *config = f->config;
 +      return sprintf(buf, "%s\n", config->manufacturer);
 +}
 +
 +static ssize_t rndis_manufacturer_store(struct device *dev,
 +              struct device_attribute *attr, const char *buf, size_t size)
 +{
 +      struct android_usb_function *f = dev_get_drvdata(dev);
 +      struct rndis_function_config *config = f->config;
 +
 +      if (size >= sizeof(config->manufacturer))
 +              return -EINVAL;
 +      if (sscanf(buf, "%s", config->manufacturer) == 1)
 +              return size;
 +      return -1;
 +}
 +
 +static DEVICE_ATTR(manufacturer, S_IRUGO | S_IWUSR, rndis_manufacturer_show,
 +                                                  rndis_manufacturer_store);
 +
 +static ssize_t rndis_wceis_show(struct device *dev,
 +              struct device_attribute *attr, char *buf)
 +{
 +      struct android_usb_function *f = dev_get_drvdata(dev);
 +      struct rndis_function_config *config = f->config;
 +      return sprintf(buf, "%d\n", config->wceis);
 +}
 +
 +static ssize_t rndis_wceis_store(struct device *dev,
 +              struct device_attribute *attr, const char *buf, size_t size)
 +{
 +      struct android_usb_function *f = dev_get_drvdata(dev);
 +      struct rndis_function_config *config = f->config;
 +      int value;
 +
 +      if (sscanf(buf, "%d", &value) == 1) {
 +              config->wceis = value;
 +              return size;
 +      }
 +      return -EINVAL;
 +}
 +
 +static DEVICE_ATTR(wceis, S_IRUGO | S_IWUSR, rndis_wceis_show,
 +                                           rndis_wceis_store);
 +
 +static ssize_t rndis_ethaddr_show(struct device *dev,
 +              struct device_attribute *attr, char *buf)
 +{
 +      struct android_usb_function *f = dev_get_drvdata(dev);
 +      struct rndis_function_config *rndis = f->config;
 +      return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
 +              rndis->ethaddr[0], rndis->ethaddr[1], rndis->ethaddr[2],
 +              rndis->ethaddr[3], rndis->ethaddr[4], rndis->ethaddr[5]);
 +}
 +
 +static ssize_t rndis_ethaddr_store(struct device *dev,
 +              struct device_attribute *attr, const char *buf, size_t size)
 +{
 +      struct android_usb_function *f = dev_get_drvdata(dev);
 +      struct rndis_function_config *rndis = f->config;
 +
 +      if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
 +                  (int *)&rndis->ethaddr[0], (int *)&rndis->ethaddr[1],
 +                  (int *)&rndis->ethaddr[2], (int *)&rndis->ethaddr[3],
 +                  (int *)&rndis->ethaddr[4], (int *)&rndis->ethaddr[5]) == 6)
 +              return size;
 +      return -EINVAL;
 +}
 +
 +static DEVICE_ATTR(ethaddr, S_IRUGO | S_IWUSR, rndis_ethaddr_show,
 +                                             rndis_ethaddr_store);
 +
 +static ssize_t rndis_vendorID_show(struct device *dev,
 +              struct device_attribute *attr, char *buf)
 +{
 +      struct android_usb_function *f = dev_get_drvdata(dev);
 +      struct rndis_function_config *config = f->config;
 +      return sprintf(buf, "%04x\n", config->vendorID);
 +}
 +
 +static ssize_t rndis_vendorID_store(struct device *dev,
 +              struct device_attribute *attr, const char *buf, size_t size)
 +{
 +      struct android_usb_function *f = dev_get_drvdata(dev);
 +      struct rndis_function_config *config = f->config;
 +      int value;
 +
 +      if (sscanf(buf, "%04x", &value) == 1) {
 +              config->vendorID = value;
 +              return size;
 +      }
 +      return -EINVAL;
 +}
 +
 +static DEVICE_ATTR(vendorID, S_IRUGO | S_IWUSR, rndis_vendorID_show,
 +                                              rndis_vendorID_store);
 +
 +static struct device_attribute *rndis_function_attributes[] = {
 +      &dev_attr_manufacturer,
 +      &dev_attr_wceis,
 +      &dev_attr_ethaddr,
 +      &dev_attr_vendorID,
 +      NULL
 +};
 +
 +static struct android_usb_function rndis_function = {
 +      .name           = "rndis",
 +      .init           = rndis_function_init,
 +      .cleanup        = rndis_function_cleanup,
 +      .bind_config    = rndis_function_bind_config,
 +      .unbind_config  = rndis_function_unbind_config,
 +      .attributes     = rndis_function_attributes,
 +};
 +
 +
 +#define MAX_MS_INSTANCES 1
 +struct mass_storage_function_config {
 +      int instances;
 +      int instances_on;
 +      struct usb_function *f_ms[MAX_MS_INSTANCES];
 +      struct usb_function_instance *f_ms_inst[MAX_MS_INSTANCES];
 +};
 +
 +static int mass_storage_function_init(struct android_usb_function *f,
 +                                      struct usb_composite_dev *cdev)
 +{
 +      struct mass_storage_function_config *config;
 +      int i;
 +      int ret;
 +
 +      config = kzalloc(sizeof(struct mass_storage_function_config),
 +                                                              GFP_KERNEL);
 +      if (!config)
 +              return -ENOMEM;
 +      f->config = config;
 +
 +      for (i = 0; i < MAX_MS_INSTANCES; i++) {
 +              config->f_ms_inst[i] =
 +                              usb_get_function_instance("mass_storage");
 +              if (IS_ERR(config->f_ms_inst[i])) {
 +                      ret = PTR_ERR(config->f_ms_inst[i]);
 +                      goto err_usb_get_function_instance;
 +              }
 +              config->f_ms[i] = usb_get_function(config->f_ms_inst[i]);
 +              if (IS_ERR(config->f_ms[i])) {
 +                      ret = PTR_ERR(config->f_ms[i]);
 +                      goto err_usb_get_function;
 +              }
 +      }
 +      return 0;
 +err_usb_get_function_instance:
 +      while (i-- > 0) {
 +              usb_put_function(config->f_ms[i]);
 +err_usb_get_function:
 +              usb_put_function_instance(config->f_ms_inst[i]);
 +      }
 +      return ret;
 +}
 +
 +static void mass_storage_function_cleanup(struct android_usb_function *f)
 +{
 +      struct mass_storage_function_config *config = f->config;
 +      int i;
 +
 +      for (i = 0; i < MAX_MS_INSTANCES; i++) {
 +              usb_put_function(config->f_ms[i]);
 +              usb_put_function_instance(config->f_ms_inst[i]);
 +      }
 +      kfree(f->config);
 +      f->config = NULL;
 +}
 +
 +static int mass_storage_function_bind_config(struct android_usb_function *f,
 +                                              struct usb_configuration *c)
 +{
 +      struct mass_storage_function_config *config = f->config;
 +      int ret = 0;
 +      int i;
 +
 +      config->instances_on = config->instances;
 +      for (i = 0; i < config->instances_on; i++) {
 +              ret = usb_add_function(c, config->f_ms[i]);
 +              if (ret) {
 +                      pr_err("Could not bind ms%u config\n", i);
 +                      goto err_usb_add_function;
 +              }
 +      }
 +
 +      return 0;
 +
 +err_usb_add_function:
 +      while (i-- > 0)
 +              usb_remove_function(c, config->f_ms[i]);
 +      return ret;
 +}
 +
 +static void __maybe_unused mass_storage_function_unbind_config(struct android_usb_function *f,
 +                                             struct usb_configuration *c)
 +{
 +      int i;
 +      struct mass_storage_function_config *config = f->config;
 +
 +      for (i = 0; i < config->instances_on; i++)
 +              usb_remove_function(c, config->f_ms[i]);
 +}
 +
 +static ssize_t mass_storage_inquiry_show(struct device *dev,
 +                              struct device_attribute *attr, char *buf)
 +{
 +      struct android_usb_function *f = dev_get_drvdata(dev);
 +      struct mass_storage_function_config *config = f->config;
 +      return sprintf(buf, "%d\n", config->instances);
 +}
 +
 +static ssize_t mass_storage_inquiry_store(struct device *dev,
 +              struct device_attribute *attr, const char *buf, size_t size)
 +{
 +      struct android_usb_function *f = dev_get_drvdata(dev);
 +      struct mass_storage_function_config *config = f->config;
 +      int value;
 +
 +      if (sscanf(buf, "%d", &value) != 1)
 +              return -EINVAL;
 +
 +      if (value > MAX_MS_INSTANCES)
 +              value = MAX_MS_INSTANCES;
 +      config->instances = value;
 +      return size;
 +}
 +
 +static DEVICE_ATTR(inquiry_string, S_IRUGO | S_IWUSR,
 +                                      mass_storage_inquiry_show,
 +                                      mass_storage_inquiry_store);
 +
 +static struct device_attribute *mass_storage_function_attributes[] = {
 +      &dev_attr_inquiry_string,
 +      NULL
 +};
 +
 +static struct android_usb_function mass_storage_function = {
 +      .name           = "mass_storage",
 +      .init           = mass_storage_function_init,
 +      .cleanup        = mass_storage_function_cleanup,
 +      .bind_config    = mass_storage_function_bind_config,
 +      .unbind_config  = mass_storage_function_unbind_config,
 +      .attributes     = mass_storage_function_attributes,
 +};
 +
 +
 +static int accessory_function_init(struct android_usb_function *f,
 +                                      struct usb_composite_dev *cdev)
 +{
 +      return acc_setup();
 +}
 +
 +static void accessory_function_cleanup(struct android_usb_function *f)
 +{
 +      acc_cleanup();
 +}
 +
 +static int accessory_function_bind_config(struct android_usb_function *f,
 +                                              struct usb_configuration *c)
 +{
 +      return acc_bind_config(c);
 +}
 +
 +static int accessory_function_ctrlrequest(struct android_usb_function *f,
 +                                              struct usb_composite_dev *cdev,
 +                                              const struct usb_ctrlrequest *c)
 +{
 +      return acc_ctrlrequest(cdev, c);
 +}
 +
 +static struct android_usb_function accessory_function = {
 +      .name           = "accessory",
 +      .init           = accessory_function_init,
 +      .cleanup        = accessory_function_cleanup,
 +      .bind_config    = accessory_function_bind_config,
 +      .ctrlrequest    = accessory_function_ctrlrequest,
 +};
 +
 +static int audio_source_function_init(struct android_usb_function *f,
 +                      struct usb_composite_dev *cdev)
 +{
 +      struct audio_source_config *config;
 +
 +      config = kzalloc(sizeof(struct audio_source_config), GFP_KERNEL);
 +      if (!config)
 +              return -ENOMEM;
 +      config->card = -1;
 +      config->device = -1;
 +      f->config = config;
 +      return 0;
 +}
 +
 +static void audio_source_function_cleanup(struct android_usb_function *f)
 +{
 +      kfree(f->config);
 +}
 +
 +static int audio_source_function_bind_config(struct android_usb_function *f,
 +                                              struct usb_configuration *c)
 +{
 +      struct audio_source_config *config = f->config;
 +
 +      return audio_source_bind_config(c, config);
 +}
 +
 +static void audio_source_function_unbind_config(struct android_usb_function *f,
 +                                              struct usb_configuration *c)
 +{
 +      struct audio_source_config *config = f->config;
 +
 +      config->card = -1;
 +      config->device = -1;
 +}
 +
 +static ssize_t audio_source_pcm_show(struct device *dev,
 +              struct device_attribute *attr, char *buf)
 +{
 +      struct android_usb_function *f = dev_get_drvdata(dev);
 +      struct audio_source_config *config = f->config;
 +
 +      /* print PCM card and device numbers */
 +      return sprintf(buf, "%d %d\n", config->card, config->device);
 +}
 +
 +static DEVICE_ATTR(pcm, S_IRUGO, audio_source_pcm_show, NULL);
 +
 +static struct device_attribute *audio_source_function_attributes[] = {
 +      &dev_attr_pcm,
 +      NULL
 +};
 +
 +static struct android_usb_function audio_source_function = {
 +      .name           = "audio_source",
 +      .init           = audio_source_function_init,
 +      .cleanup        = audio_source_function_cleanup,
 +      .bind_config    = audio_source_function_bind_config,
 +      .unbind_config  = audio_source_function_unbind_config,
 +      .attributes     = audio_source_function_attributes,
 +};
 +
 +static struct android_usb_function *supported_functions[] = {
 +      &ffs_function,
 +      &acm_function,
 +      &mtp_function,
 +      &ptp_function,
 +      &rndis_function,
 +      &mass_storage_function,
 +      &accessory_function,
 +      &audio_source_function,
 +      NULL
 +};
 +
 +
 +static int android_init_functions(struct android_usb_function **functions,
 +                                struct usb_composite_dev *cdev)
 +{
 +      struct android_dev *dev = _android_dev;
 +      struct android_usb_function *f;
 +      struct device_attribute **attrs;
 +      struct device_attribute *attr;
 +      int err;
 +      int index = 0;
 +
 +      for (; (f = *functions++); index++) {
 +              f->dev_name = kasprintf(GFP_KERNEL, "f_%s", f->name);
 +              f->dev = device_create(android_class, dev->dev,
 +                              MKDEV(0, index), f, f->dev_name);
 +              if (IS_ERR(f->dev)) {
 +                      pr_err("%s: Failed to create dev %s", __func__,
 +                                                      f->dev_name);
 +                      err = PTR_ERR(f->dev);
 +                      goto err_create;
 +              }
 +
 +              if (f->init) {
 +                      err = f->init(f, cdev);
 +                      if (err) {
 +                              pr_err("%s: Failed to init %s", __func__,
 +                                                              f->name);
 +                              goto err_out;
 +                      }
 +              }
 +
 +              attrs = f->attributes;
 +              if (attrs) {
 +                      while ((attr = *attrs++) && !err)
 +                              err = device_create_file(f->dev, attr);
 +              }
 +              if (err) {
 +                      pr_err("%s: Failed to create function %s attributes",
 +                                      __func__, f->name);
 +                      goto err_out;
 +              }
 +      }
 +      return 0;
 +
 +err_out:
 +      device_destroy(android_class, f->dev->devt);
 +err_create:
 +      kfree(f->dev_name);
 +      return err;
 +}
 +
 +static void android_cleanup_functions(struct android_usb_function **functions)
 +{
 +      struct android_usb_function *f;
 +
 +      while (*functions) {
 +              f = *functions++;
 +
 +              if (f->dev) {
 +                      device_destroy(android_class, f->dev->devt);
 +                      kfree(f->dev_name);
 +              }
 +
 +              if (f->cleanup)
 +                      f->cleanup(f);
 +      }
 +}
 +
 +static int
 +android_bind_enabled_functions(struct android_dev *dev,
 +                             struct usb_configuration *c)
 +{
 +      struct android_usb_function *f;
 +      int ret;
 +
 +      list_for_each_entry(f, &dev->enabled_functions, enabled_list) {
 +              ret = f->bind_config(f, c);
 +              if (ret) {
 +                      pr_err("%s: %s failed", __func__, f->name);
 +                      return ret;
 +              }
 +      }
 +      return 0;
 +}
 +
 +static void
 +android_unbind_enabled_functions(struct android_dev *dev,
 +                             struct usb_configuration *c)
 +{
 +      struct android_usb_function *f;
 +
 +      list_for_each_entry(f, &dev->enabled_functions, enabled_list) {
 +              if (f->unbind_config)
 +                      f->unbind_config(f, c);
 +      }
 +}
 +
 +static int android_enable_function(struct android_dev *dev, char *name)
 +{
 +      struct android_usb_function **functions = dev->functions;
 +      struct android_usb_function *f;
 +      while ((f = *functions++)) {
 +              if (!strcmp(name, f->name)) {
 +                      list_add_tail(&f->enabled_list,
 +                                              &dev->enabled_functions);
 +                      return 0;
 +              }
 +      }
 +      return -EINVAL;
 +}
 +
 +/*-------------------------------------------------------------------------*/
 +/* /sys/class/android_usb/android%d/ interface */
 +
 +static ssize_t
 +functions_show(struct device *pdev, struct device_attribute *attr, char *buf)
 +{
 +      struct android_dev *dev = dev_get_drvdata(pdev);
 +      struct android_usb_function *f;
 +      char *buff = buf;
 +
 +      mutex_lock(&dev->mutex);
 +
 +      list_for_each_entry(f, &dev->enabled_functions, enabled_list)
 +              buff += sprintf(buff, "%s,", f->name);
 +
 +      mutex_unlock(&dev->mutex);
 +
 +      if (buff != buf)
 +              *(buff-1) = '\n';
 +      return buff - buf;
 +}
 +
 +static ssize_t
 +functions_store(struct device *pdev, struct device_attribute *attr,
 +                             const char *buff, size_t size)
 +{
 +      struct android_dev *dev = dev_get_drvdata(pdev);
 +      char *name;
 +      char buf[256], *b;
 +      char aliases[256], *a;
 +      int err;
 +      int is_ffs;
 +      int ffs_enabled = 0;
 +
 +      mutex_lock(&dev->mutex);
 +
 +      if (dev->enabled) {
 +              mutex_unlock(&dev->mutex);
 +              return -EBUSY;
 +      }
 +
 +      INIT_LIST_HEAD(&dev->enabled_functions);
 +
 +      strlcpy(buf, buff, sizeof(buf));
 +      b = strim(buf);
 +
 +      while (b) {
 +              name = strsep(&b, ",");
 +              if (!name)
 +                      continue;
 +
 +              is_ffs = 0;
 +              strlcpy(aliases, dev->ffs_aliases, sizeof(aliases));
 +              a = aliases;
 +
 +              while (a) {
 +                      char *alias = strsep(&a, ",");
 +                      if (alias && !strcmp(name, alias)) {
 +                              is_ffs = 1;
 +                              break;
 +                      }
 +              }
 +
 +              if (is_ffs) {
 +                      if (ffs_enabled)
 +                              continue;
 +                      err = android_enable_function(dev, "ffs");
 +                      if (err)
 +                              pr_err("android_usb: Cannot enable ffs (%d)",
 +                                                                      err);
 +                      else
 +                              ffs_enabled = 1;
 +                      continue;
 +              }
 +
 +              err = android_enable_function(dev, name);
 +              if (err)
 +                      pr_err("android_usb: Cannot enable '%s' (%d)",
 +                                                         name, err);
 +      }
 +
 +      mutex_unlock(&dev->mutex);
 +
 +      return size;
 +}
 +
 +static ssize_t enable_show(struct device *pdev, struct device_attribute *attr,
 +                         char *buf)
 +{
 +      struct android_dev *dev = dev_get_drvdata(pdev);
 +      return sprintf(buf, "%d\n", dev->enabled);
 +}
 +
 +static ssize_t enable_store(struct device *pdev, struct device_attribute *attr,
 +                          const char *buff, size_t size)
 +{
 +      struct android_dev *dev = dev_get_drvdata(pdev);
 +      struct usb_composite_dev *cdev = dev->cdev;
 +      struct android_usb_function *f;
 +      int enabled = 0;
 +
 +
 +      if (!cdev)
 +              return -ENODEV;
 +
 +      mutex_lock(&dev->mutex);
 +
 +      sscanf(buff, "%d", &enabled);
 +      if (enabled && !dev->enabled) {
 +              cdev->next_string_id = 0;
 +              /*
 +               * Update values in composite driver's copy of
 +               * device descriptor.
 +               */
 +              cdev->desc.idVendor = device_desc.idVendor;
 +              cdev->desc.idProduct = device_desc.idProduct;
 +              cdev->desc.bcdDevice = device_desc.bcdDevice;
 +              cdev->desc.bDeviceClass = device_desc.bDeviceClass;
 +              cdev->desc.bDeviceSubClass = device_desc.bDeviceSubClass;
 +              cdev->desc.bDeviceProtocol = device_desc.bDeviceProtocol;
 +              list_for_each_entry(f, &dev->enabled_functions, enabled_list) {
 +                      if (f->enable)
 +                              f->enable(f);
 +              }
 +              android_enable(dev);
 +              dev->enabled = true;
 +      } else if (!enabled && dev->enabled) {
 +              android_disable(dev);
 +              list_for_each_entry(f, &dev->enabled_functions, enabled_list) {
 +                      if (f->disable)
 +                              f->disable(f);
 +              }
 +              dev->enabled = false;
 +      } else {
 +              pr_err("android_usb: already %s\n",
 +                              dev->enabled ? "enabled" : "disabled");
 +      }
 +
 +      mutex_unlock(&dev->mutex);
 +      return size;
 +}
 +
 +static ssize_t state_show(struct device *pdev, struct device_attribute *attr,
 +                         char *buf)
 +{
 +      struct android_dev *dev = dev_get_drvdata(pdev);
 +      struct usb_composite_dev *cdev = dev->cdev;
 +      char *state = "DISCONNECTED";
 +      unsigned long flags;
 +
 +      if (!cdev)
 +              goto out;
 +
 +      spin_lock_irqsave(&cdev->lock, flags);
 +      if (cdev->config)
 +              state = "CONFIGURED";
 +      else if (dev->connected)
 +              state = "CONNECTED";
 +      spin_unlock_irqrestore(&cdev->lock, flags);
 +out:
 +      return sprintf(buf, "%s\n", state);
 +}
 +
 +#define DESCRIPTOR_ATTR(field, format_string)                         \
 +static ssize_t                                                                \
 +field ## _show(struct device *dev, struct device_attribute *attr,     \
 +              char *buf)                                              \
 +{                                                                     \
 +      return sprintf(buf, format_string, device_desc.field);          \
 +}                                                                     \
 +static ssize_t                                                                \
 +field ## _store(struct device *dev, struct device_attribute *attr,    \
 +              const char *buf, size_t size)                           \
 +{                                                                     \
 +      int value;                                                      \
 +      if (sscanf(buf, format_string, &value) == 1) {                  \
 +              device_desc.field = value;                              \
 +              return size;                                            \
 +      }                                                               \
 +      return -1;                                                      \
 +}                                                                     \
 +static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
 +
 +#define DESCRIPTOR_STRING_ATTR(field, buffer)                         \
 +static ssize_t                                                                \
 +field ## _show(struct device *dev, struct device_attribute *attr,     \
 +              char *buf)                                              \
 +{                                                                     \
 +      return sprintf(buf, "%s", buffer);                              \
 +}                                                                     \
 +static ssize_t                                                                \
 +field ## _store(struct device *dev, struct device_attribute *attr,    \
 +              const char *buf, size_t size)                           \
 +{                                                                     \
 +      if (size >= sizeof(buffer))                                     \
 +              return -EINVAL;                                         \
 +      return strlcpy(buffer, buf, sizeof(buffer));                    \
 +}                                                                     \
 +static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, field ## _show, field ## _store);
 +
 +
 +DESCRIPTOR_ATTR(idVendor, "%04x\n")
 +DESCRIPTOR_ATTR(idProduct, "%04x\n")
 +DESCRIPTOR_ATTR(bcdDevice, "%04x\n")
 +DESCRIPTOR_ATTR(bDeviceClass, "%d\n")
 +DESCRIPTOR_ATTR(bDeviceSubClass, "%d\n")
 +DESCRIPTOR_ATTR(bDeviceProtocol, "%d\n")
 +DESCRIPTOR_STRING_ATTR(iManufacturer, manufacturer_string)
 +DESCRIPTOR_STRING_ATTR(iProduct, product_string)
 +DESCRIPTOR_STRING_ATTR(iSerial, serial_string)
 +
 +static DEVICE_ATTR(functions, S_IRUGO | S_IWUSR, functions_show,
 +                                               functions_store);
 +static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store);
 +static DEVICE_ATTR(state, S_IRUGO, state_show, NULL);
 +
 +static struct device_attribute *android_usb_attributes[] = {
 +      &dev_attr_idVendor,
 +      &dev_attr_idProduct,
 +      &dev_attr_bcdDevice,
 +      &dev_attr_bDeviceClass,
 +      &dev_attr_bDeviceSubClass,
 +      &dev_attr_bDeviceProtocol,
 +      &dev_attr_iManufacturer,
 +      &dev_attr_iProduct,
 +      &dev_attr_iSerial,
 +      &dev_attr_functions,
 +      &dev_attr_enable,
 +      &dev_attr_state,
 +      NULL
 +};
 +
 +/*-------------------------------------------------------------------------*/
 +/* Composite driver */
 +
 +static int android_bind_config(struct usb_configuration *c)
 +{
 +      struct android_dev *dev = _android_dev;
 +      int ret = 0;
 +
 +      ret = android_bind_enabled_functions(dev, c);
 +      if (ret)
 +              return ret;
 +
 +      return 0;
 +}
 +
 +static void android_unbind_config(struct usb_configuration *c)
 +{
 +      struct android_dev *dev = _android_dev;
 +
 +      android_unbind_enabled_functions(dev, c);
 +}
 +
 +static int android_bind(struct usb_composite_dev *cdev)
 +{
 +      struct android_dev *dev = _android_dev;
 +      struct usb_gadget       *gadget = cdev->gadget;
 +      int                     id, ret;
 +
 +      /* Save the default handler */
 +      dev->setup_complete = cdev->req->complete;
 +
 +      /*
 +       * Start disconnected. Userspace will connect the gadget once
 +       * it is done configuring the functions.
 +       */
 +      usb_gadget_disconnect(gadget);
 +
 +      ret = android_init_functions(dev->functions, cdev);
 +      if (ret)
 +              return ret;
 +
 +      /* Allocate string descriptor numbers ... note that string
 +       * contents can be overridden by the composite_dev glue.
 +       */
 +      id = usb_string_id(cdev);
 +      if (id < 0)
 +              return id;
 +      strings_dev[STRING_MANUFACTURER_IDX].id = id;
 +      device_desc.iManufacturer = id;
 +
 +      id = usb_string_id(cdev);
 +      if (id < 0)
 +              return id;
 +      strings_dev[STRING_PRODUCT_IDX].id = id;
 +      device_desc.iProduct = id;
 +
 +      /* Default strings - should be updated by userspace */
 +      strncpy(manufacturer_string, "Android", sizeof(manufacturer_string)-1);
 +      strncpy(product_string, "Android", sizeof(product_string) - 1);
 +      strncpy(serial_string, "0123456789ABCDEF", sizeof(serial_string) - 1);
 +
 +      id = usb_string_id(cdev);
 +      if (id < 0)
 +              return id;
 +      strings_dev[STRING_SERIAL_IDX].id = id;
 +      device_desc.iSerialNumber = id;
 +
 +      usb_gadget_set_selfpowered(gadget);
 +      dev->cdev = cdev;
 +
 +      return 0;
 +}
 +
 +static int android_usb_unbind(struct usb_composite_dev *cdev)
 +{
 +      struct android_dev *dev = _android_dev;
 +
 +      cancel_work_sync(&dev->work);
 +      android_cleanup_functions(dev->functions);
 +      return 0;
 +}
 +
 +/* HACK: android needs to override setup for accessory to work */
 +static int (*composite_setup_func)(struct usb_gadget *gadget, const struct usb_ctrlrequest *c);
 +
 +static int
 +android_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c)
 +{
 +      struct android_dev              *dev = _android_dev;
 +      struct usb_composite_dev        *cdev = get_gadget_data(gadget);
 +      struct usb_request              *req = cdev->req;
 +      struct android_usb_function     *f;
 +      int value = -EOPNOTSUPP;
 +      unsigned long flags;
 +
 +      req->zero = 0;
 +      req->length = 0;
 +      req->complete = dev->setup_complete;
 +      gadget->ep0->driver_data = cdev;
 +
 +      list_for_each_entry(f, &dev->enabled_functions, enabled_list) {
 +              if (f->ctrlrequest) {
 +                      value = f->ctrlrequest(f, cdev, c);
 +                      if (value >= 0)
 +                              break;
 +              }
 +      }
 +
 +      /* Special case the accessory function.
 +       * It needs to handle control requests before it is enabled.
 +       */
 +      if (value < 0)
 +              value = acc_ctrlrequest(cdev, c);
 +
 +      if (value < 0)
 +              value = composite_setup_func(gadget, c);
 +
 +      spin_lock_irqsave(&cdev->lock, flags);
 +      if (!dev->connected) {
 +              dev->connected = 1;
 +              schedule_work(&dev->work);
 +      } else if (c->bRequest == USB_REQ_SET_CONFIGURATION &&
 +                                              cdev->config) {
 +              schedule_work(&dev->work);
 +      }
 +      spin_unlock_irqrestore(&cdev->lock, flags);
 +
 +      return value;
 +}
 +
 +static void android_disconnect(struct usb_composite_dev *cdev)
 +{
 +      struct android_dev *dev = _android_dev;
 +
 +      /* accessory HID support can be active while the
 +         accessory function is not actually enabled,
 +         so we need to inform it when we are disconnected.
 +       */
 +      acc_disconnect();
 +
 +      dev->connected = 0;
 +      schedule_work(&dev->work);
 +}
 +
 +static struct usb_composite_driver android_usb_driver = {
 +      .name           = "android_usb",
 +      .dev            = &device_desc,
 +      .strings        = dev_strings,
 +      .bind           = android_bind,
 +      .unbind         = android_usb_unbind,
 +      .disconnect     = android_disconnect,
 +      .max_speed      = USB_SPEED_HIGH,
 +};
 +
 +static int android_create_device(struct android_dev *dev)
 +{
 +      struct device_attribute **attrs = android_usb_attributes;
 +      struct device_attribute *attr;
 +      int err;
 +
 +      dev->dev = device_create(android_class, NULL,
 +                                      MKDEV(0, 0), NULL, "android0");
 +      if (IS_ERR(dev->dev))
 +              return PTR_ERR(dev->dev);
 +
 +      dev_set_drvdata(dev->dev, dev);
 +
 +      while ((attr = *attrs++)) {
 +              err = device_create_file(dev->dev, attr);
 +              if (err) {
 +                      device_destroy(android_class, dev->dev->devt);
 +                      return err;
 +              }
 +      }
 +      return 0;
 +}
 +
 +
 +static int __init init(void)
 +{
 +      struct android_dev *dev;
 +      int err;
 +
 +      android_class = class_create(THIS_MODULE, "android_usb");
 +      if (IS_ERR(android_class))
 +              return PTR_ERR(android_class);
 +
 +      dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 +      if (!dev) {
 +              err = -ENOMEM;
 +              goto err_dev;
 +      }
 +
 +      dev->disable_depth = 1;
 +      dev->functions = supported_functions;
 +      INIT_LIST_HEAD(&dev->enabled_functions);
 +      INIT_WORK(&dev->work, android_work);
 +      mutex_init(&dev->mutex);
 +
 +      err = android_create_device(dev);
 +      if (err) {
 +              pr_err("%s: failed to create android device %d", __func__, err);
 +              goto err_create;
 +      }
 +
 +      _android_dev = dev;
 +
 +      err = usb_composite_probe(&android_usb_driver);
 +      if (err) {
 +              pr_err("%s: failed to probe driver %d", __func__, err);
 +              goto err_probe;
 +      }
 +
 +      /* HACK: exchange composite's setup with ours */
 +      composite_setup_func = android_usb_driver.gadget_driver.setup;
 +      android_usb_driver.gadget_driver.setup = android_setup;
 +
 +      return 0;
 +
 +err_probe:
 +      device_destroy(android_class, dev->dev->devt);
 +err_create:
 +      kfree(dev);
 +err_dev:
 +      class_destroy(android_class);
 +      return err;
 +}
 +late_initcall(init);
 +
 +static void __exit cleanup(void)
 +{
 +      usb_composite_unregister(&android_usb_driver);
 +      class_destroy(android_class);
 +      kfree(_android_dev);
 +      _android_dev = NULL;
 +}
 +module_exit(cleanup);
index 73bdc827abcc35410d86a2116500383fe7223ffd,154eca7dbb5e331250ad6bbc0681d0e8cb273334..17117083f0740b50d4f05de9c50c324401a9b7d6
@@@ -346,20 -483,19 +483,27 @@@ static int udc_bind_to_driver(struct us
        ret = driver->bind(udc->gadget, driver);
        if (ret)
                goto err1;
-       ret = usb_gadget_udc_start(udc->gadget, driver);
-       if (ret) {
-               driver->unbind(udc->gadget);
-               goto err1;
+       /* If OTG, the otg core starts the UDC when needed */
+       mutex_unlock(&udc_lock);
+       udc->is_otg = !usb_otg_register_gadget(udc->gadget, &otg_gadget_intf);
+       mutex_lock(&udc_lock);
+       if (!udc->is_otg) {
+               ret = usb_gadget_udc_start(udc);
+               if (ret) {
+                       driver->unbind(udc->gadget);
+                       goto err1;
+               }
 -              usb_gadget_connect(udc->gadget);
++              /*
++               * HACK: The Android gadget driver disconnects the gadget
++               * on bind and expects the gadget to stay disconnected until
++               * it calls usb_gadget_connect when userspace is ready. Remove
++               * the call to usb_gadget_connect bellow to avoid enabling the
++               * pullup before userspace is ready.
++               *
++               * usb_gadget_connect(udc->gadget);
++               */
        }
-       /*
-        * HACK: The Android gadget driver disconnects the gadget
-        * on bind and expects the gadget to stay disconnected until
-        * it calls usb_gadget_connect when userspace is ready. Remove
-        * the call to usb_gadget_connect bellow to avoid enabling the
-        * pullup before userspace is ready.
-        *
-        * usb_gadget_connect(udc->gadget);
-        */
  
        kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
        return 0;
index bff15ca9eb6ee33c7ee176e352ba0cd4d4da0434,b7b4410bbf5b5ec70e8e958889a5123f63b204c5..430b510323e16210c81ae129f49ecf1c7522ba71
@@@ -6,23 -6,6 +6,14 @@@ menu "USB Physical Layer drivers
  config USB_PHY
        def_bool n
  
- config USB_OTG_FSM
-       tristate "USB 2.0 OTG FSM implementation"
-       depends on USB
-       select USB_OTG
-       select USB_PHY
-       help
-         Implements OTG Final State Machine as specified in On-The-Go
-         and Embedded Host Supplement to the USB Revision 2.0 Specification.
 +config USB_OTG_WAKELOCK
 +      bool "Hold a wakelock when USB connected"
 +      depends on WAKELOCK
 +      select USB_OTG_UTILS
 +      help
 +        Select this to automatically hold a wakelock when USB is
 +        connected, preventing suspend.
 +
  #
  # USB Transceiver Drivers
  #
index 0b041b75bdc4456610789d6864e8056624762692,068f35da291dee5f570984f208b8bf1586c59f56..cfd260627e8251f23f7e1d4730f362302634fab3
@@@ -3,8 -3,6 +3,7 @@@
  #
  obj-$(CONFIG_USB_PHY)                 += phy.o
  obj-$(CONFIG_OF)                      += of.o
- obj-$(CONFIG_USB_OTG_FSM)             += phy-fsm-usb.o
 +obj-$(CONFIG_USB_OTG_WAKELOCK)                += otg-wakelock.o
  
  # transceiver drivers, keep the list sorted
  
diff --cc fs/exec.c
index 327f5cefcda27c5b212fcc1d75908ee300b58543,05f1942d7edba5e4086562c7beea27389b4d99ca..0b274a3cdd4f0acb979a62fe5c48436179972019
+++ b/fs/exec.c
@@@ -1268,6 -1268,53 +1268,53 @@@ static void check_unsafe_exec(struct li
        spin_unlock(&p->fs->lock);
  }
  
 -      if (current->no_new_privs)
+ static void bprm_fill_uid(struct linux_binprm *bprm)
+ {
+       struct inode *inode;
+       unsigned int mode;
+       kuid_t uid;
+       kgid_t gid;
+       /* clear any previous set[ug]id data from a previous binary */
+       bprm->cred->euid = current_euid();
+       bprm->cred->egid = current_egid();
+       if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
+               return;
++      if (task_no_new_privs(current))
+               return;
+       inode = file_inode(bprm->file);
+       mode = ACCESS_ONCE(inode->i_mode);
+       if (!(mode & (S_ISUID|S_ISGID)))
+               return;
+       /* Be careful if suid/sgid is set */
+       mutex_lock(&inode->i_mutex);
+       /* reload atomically mode/uid/gid now that lock held */
+       mode = inode->i_mode;
+       uid = inode->i_uid;
+       gid = inode->i_gid;
+       mutex_unlock(&inode->i_mutex);
+       /* We ignore suid/sgid if there are no mappings for them in the ns */
+       if (!kuid_has_mapping(bprm->cred->user_ns, uid) ||
+                !kgid_has_mapping(bprm->cred->user_ns, gid))
+               return;
+       if (mode & S_ISUID) {
+               bprm->per_clear |= PER_CLEAR_ON_SETID;
+               bprm->cred->euid = uid;
+       }
+       if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
+               bprm->per_clear |= PER_CLEAR_ON_SETID;
+               bprm->cred->egid = gid;
+       }
+ }
  /*
   * Fill the binprm structure from the inode.
   * Check permissions, then read the first 128 (BINPRM_BUF_SIZE) bytes
Simple merge