Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 23 Oct 2010 03:30:48 +0000 (20:30 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 23 Oct 2010 03:30:48 +0000 (20:30 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (141 commits)
  USB: mct_u232: fix broken close
  USB: gadget: amd5536udc.c: fix error path
  USB: imx21-hcd - fix off by one resource size calculation
  usb: gadget: fix Kconfig warning
  usb: r8a66597-udc: Add processing when USB was removed.
  mxc_udc: add workaround for ENGcm09152 for i.MX35
  USB: ftdi_sio: add device ids for ScienceScope
  USB: musb: AM35x: Workaround for fifo read issue
  USB: musb: add musb support for AM35x
  USB: AM35x: Add musb support
  usb: Fix linker errors with CONFIG_PM=n
  USB: ohci-sh - use resource_size instead of defining its own resource_len macro
  USB: isp1362-hcd - use resource_size instead of defining its own resource_len macro
  USB: isp116x-hcd - use resource_size instead of defining its own resource_len macro
  USB: xhci: Fix compile error when CONFIG_PM=n
  USB: accept some invalid ep0-maxpacket values
  USB: xHCI: PCI power management implementation
  USB: xHCI: bus power management implementation
  USB: xHCI: port remote wakeup implementation
  USB: xHCI: port power management implementation
  ...

Manually fix up (non-data) conflict: the SCSI merge gad renamed the
'hw_sector_size' member to 'physical_block_size', and the USB tree
brought a new use of it.

179 files changed:
Documentation/devices.txt
Documentation/powerpc/dts-bindings/fsl/usb.txt
Documentation/usb/proc_usb_info.txt
MAINTAINERS
arch/arm/mach-mx3/mach-cpuimx35.c
arch/arm/mach-omap2/board-am3517evm.c
arch/arm/mach-omap2/usb-musb.c
arch/arm/plat-omap/include/plat/usb.h
arch/powerpc/sysdev/fsl_soc.c
drivers/block/ub.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/scsi/sd.c
drivers/scsi/sr.c
drivers/usb/Kconfig
drivers/usb/atm/Makefile
drivers/usb/c67x00/Makefile
drivers/usb/class/cdc-acm.c
drivers/usb/core/Makefile
drivers/usb/core/devices.c
drivers/usb/core/driver.c
drivers/usb/core/endpoint.c
drivers/usb/core/hcd-pci.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/core/urb.c
drivers/usb/early/Makefile
drivers/usb/gadget/Kconfig
drivers/usb/gadget/Makefile
drivers/usb/gadget/amd5536udc.c
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/atmel_usba_udc.c
drivers/usb/gadget/audio.c
drivers/usb/gadget/cdc2.c
drivers/usb/gadget/ci13xxx_udc.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/dbgp.c
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/ether.c
drivers/usb/gadget/f_acm.c
drivers/usb/gadget/f_loopback.c
drivers/usb/gadget/f_mass_storage.c
drivers/usb/gadget/f_sourcesink.c
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/fsl_mxc_udc.c
drivers/usb/gadget/fsl_qe_udc.c
drivers/usb/gadget/fsl_udc_core.c
drivers/usb/gadget/g_ffs.c
drivers/usb/gadget/gmidi.c
drivers/usb/gadget/goku_udc.c
drivers/usb/gadget/hid.c
drivers/usb/gadget/imx_udc.c
drivers/usb/gadget/inode.c
drivers/usb/gadget/langwell_udc.c
drivers/usb/gadget/langwell_udc.h
drivers/usb/gadget/lh7a40x_udc.c
drivers/usb/gadget/m66592-udc.c
drivers/usb/gadget/mass_storage.c
drivers/usb/gadget/multi.c
drivers/usb/gadget/net2280.c
drivers/usb/gadget/nokia.c
drivers/usb/gadget/omap_udc.c
drivers/usb/gadget/printer.c
drivers/usb/gadget/pxa25x_udc.c
drivers/usb/gadget/pxa27x_udc.c
drivers/usb/gadget/r8a66597-udc.c
drivers/usb/gadget/r8a66597-udc.h
drivers/usb/gadget/rndis.c
drivers/usb/gadget/s3c-hsotg.c
drivers/usb/gadget/s3c2410_udc.c
drivers/usb/gadget/serial.c
drivers/usb/gadget/storage_common.c
drivers/usb/gadget/webcam.c
drivers/usb/gadget/zero.c
drivers/usb/host/Kconfig
drivers/usb/host/Makefile
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-fsl.h
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-mem.c
drivers/usb/host/ehci-mxc.c
drivers/usb/host/fsl-mph-dr-of.c [new file with mode: 0644]
drivers/usb/host/imx21-hcd.c
drivers/usb/host/imx21-hcd.h
drivers/usb/host/isp116x-hcd.c
drivers/usb/host/isp1362-hcd.c
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-pci.c
drivers/usb/host/ohci-sh.c
drivers/usb/host/ohci-sm501.c
drivers/usb/host/ohci.h
drivers/usb/host/oxu210hp-hcd.c
drivers/usb/host/pci-quirks.c
drivers/usb/host/r8a66597.h
drivers/usb/host/uhci-q.c
drivers/usb/host/whci/Kbuild
drivers/usb/host/xhci-hub.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/misc/Kconfig
drivers/usb/misc/Makefile
drivers/usb/misc/ftdi-elan.c
drivers/usb/misc/iowarrior.c
drivers/usb/misc/sisusbvga/Makefile
drivers/usb/misc/usbtest.c
drivers/usb/misc/yurex.c [new file with mode: 0644]
drivers/usb/mon/Makefile
drivers/usb/musb/Kconfig
drivers/usb/musb/Makefile
drivers/usb/musb/am35x.c [new file with mode: 0644]
drivers/usb/musb/blackfin.c
drivers/usb/musb/cppi_dma.c
drivers/usb/musb/da8xx.c [new file with mode: 0644]
drivers/usb/musb/davinci.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_debug.h
drivers/usb/musb/musb_gadget.c
drivers/usb/musb/musb_gadget.h
drivers/usb/musb/musb_host.c
drivers/usb/musb/musbhsdma.c
drivers/usb/musb/omap2430.c
drivers/usb/musb/tusb6010.c
drivers/usb/otg/Kconfig
drivers/usb/otg/Makefile
drivers/usb/otg/langwell_otg.c [new file with mode: 0644]
drivers/usb/otg/ulpi.c
drivers/usb/serial/Kconfig
drivers/usb/serial/Makefile
drivers/usb/serial/cp210x.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/mct_u232.c
drivers/usb/serial/opticon.c
drivers/usb/serial/option.c
drivers/usb/serial/qcserial.c
drivers/usb/serial/sam-ba.c [new file with mode: 0644]
drivers/usb/serial/visor.c
drivers/usb/storage/Kconfig
drivers/usb/storage/Makefile
drivers/usb/storage/scsiglue.c
drivers/usb/storage/sddr09.c
drivers/usb/storage/transport.c
drivers/usb/storage/uas.c [new file with mode: 0644]
drivers/usb/storage/unusual_alauda.h
drivers/usb/storage/unusual_cypress.h
drivers/usb/storage/unusual_datafab.h
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/unusual_freecom.h
drivers/usb/storage/unusual_isd200.h
drivers/usb/storage/unusual_jumpshot.h
drivers/usb/storage/unusual_karma.h
drivers/usb/storage/unusual_onetouch.h
drivers/usb/storage/unusual_sddr09.h
drivers/usb/storage/unusual_sddr55.h
drivers/usb/storage/unusual_usbat.h
drivers/usb/storage/usb.c
drivers/usb/wusbcore/Makefile
drivers/uwb/address.c
drivers/uwb/wlp/wss-lc.c
include/linux/fsl_devices.h
include/linux/init.h
include/linux/usb/cdc.h
include/linux/usb/ch9.h
include/linux/usb/composite.h
include/linux/usb/gadget.h
include/linux/usb/hcd.h
include/linux/usb/intel_mid_otg.h [new file with mode: 0644]
include/linux/usb/langwell_otg.h [new file with mode: 0644]
include/linux/usb/ncm.h [deleted file]
include/linux/usb/otg.h
include/linux/usb/storage.h [new file with mode: 0644]
include/linux/usb_usual.h
include/scsi/scsi.h
include/scsi/scsi_device.h

index 6a08fd731d2870321ceaa5a68b52b609cc6dced4..c58abf1ccc715cfd729c8ed455fcd7e084e6de5a 100644 (file)
@@ -2554,7 +2554,10 @@ Your cooperation is appreciated.
                175 = /dev/usb/legousbtower15   16th USB Legotower device
                176 = /dev/usb/usbtmc1  First USB TMC device
                   ...
-               192 = /dev/usb/usbtmc16 16th USB TMC device
+               191 = /dev/usb/usbtmc16 16th USB TMC device
+               192 = /dev/usb/yurex1   First USB Yurex device
+                  ...
+               209 = /dev/usb/yurex16  16th USB Yurex device
                240 = /dev/usb/dabusb0  First daubusb device
                    ...
                243 = /dev/usb/dabusb3  Fourth dabusb device
index b001524026943ce0e0cea217767da69d0c6d60c9..bd5723f0b67ecd9f953019fbd2af3c850bbb0433 100644 (file)
@@ -8,6 +8,7 @@ and additions :
 Required properties :
  - compatible : Should be "fsl-usb2-mph" for multi port host USB
    controllers, or "fsl-usb2-dr" for dual role USB controllers
+   or "fsl,mpc5121-usb2-dr" for dual role USB controllers of MPC5121
  - phy_type : For multi port host USB controllers, should be one of
    "ulpi", or "serial". For dual role USB controllers, should be
    one of "ulpi", "utmi", "utmi_wide", or "serial".
@@ -33,6 +34,12 @@ Recommended properties :
  - interrupt-parent : the phandle for the interrupt controller that
    services interrupts for this device.
 
+Optional properties :
+ - fsl,invert-drvvbus : boolean; for MPC5121 USB0 only. Indicates the
+   port power polarity of internal PHY signal DRVVBUS is inverted.
+ - fsl,invert-pwr-fault : boolean; for MPC5121 USB0 only. Indicates
+   the PWR_FAULT signal polarity is inverted.
+
 Example multi port host USB controller device node :
        usb@22000 {
                compatible = "fsl-usb2-mph";
@@ -57,3 +64,18 @@ Example dual role USB controller device node :
                dr_mode = "otg";
                phy = "ulpi";
        };
+
+Example dual role USB controller device node for MPC5121ADS:
+
+       usb@4000 {
+               compatible = "fsl,mpc5121-usb2-dr";
+               reg = <0x4000 0x1000>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               interrupt-parent = < &ipic >;
+               interrupts = <44 0x8>;
+               dr_mode = "otg";
+               phy_type = "utmi_wide";
+               fsl,invert-drvvbus;
+               fsl,invert-pwr-fault;
+       };
index fafcd47232600a1a80351fcd5dfc79492e6ce8e9..afe596d5f201bfa4b7fc5a504a48bd020aaeeca1 100644 (file)
@@ -1,12 +1,17 @@
 /proc/bus/usb filesystem output
 ===============================
-(version 2003.05.30)
+(version 2010.09.13)
 
 
 The usbfs filesystem for USB devices is traditionally mounted at
 /proc/bus/usb.  It provides the /proc/bus/usb/devices file, as well as
 the /proc/bus/usb/BBB/DDD files.
 
+In many modern systems the usbfs filsystem isn't used at all.  Instead
+USB device nodes are created under /dev/usb/ or someplace similar.  The
+"devices" file is available in debugfs, typically as
+/sys/kernel/debug/usb/devices.
+
 
 **NOTE**: If /proc/bus/usb appears empty, and a host controller
          driver has been linked, then you need to mount the
@@ -106,8 +111,8 @@ Legend:
 
 Topology info:
 
-T:  Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd
-|   |      |      |       |       |      |        |       |__MaxChildren
+T:  Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=dddd MxCh=dd
+|   |      |      |       |       |      |        |        |__MaxChildren
 |   |      |      |       |       |      |        |__Device Speed in Mbps
 |   |      |      |       |       |      |__DeviceNumber
 |   |      |      |       |       |__Count of devices at this level
@@ -120,8 +125,13 @@ T:  Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd
     Speed may be:
        1.5     Mbit/s for low speed USB
        12      Mbit/s for full speed USB
-       480     Mbit/s for high speed USB (added for USB 2.0)
+       480     Mbit/s for high speed USB (added for USB 2.0);
+                 also used for Wireless USB, which has no fixed speed
+       5000    Mbit/s for SuperSpeed USB (added for USB 3.0)
 
+    For reasons lost in the mists of time, the Port number is always
+    too low by 1.  For example, a device plugged into port 4 will
+    show up with "Port=03".
 
 Bandwidth info:
 B:  Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd
@@ -291,7 +301,7 @@ Here's an example, from a system which has a UHCI root hub,
 an external hub connected to the root hub, and a mouse and
 a serial converter connected to the external hub.
 
-T:  Bus=00 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=12  MxCh= 2
+T:  Bus=00 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=12   MxCh= 2
 B:  Alloc= 28/900 us ( 3%), #Int=  2, #Iso=  0
 D:  Ver= 1.00 Cls=09(hub  ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
 P:  Vendor=0000 ProdID=0000 Rev= 0.00
@@ -301,21 +311,21 @@ C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr=  0mA
 I:  If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
 E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=255ms
 
-T:  Bus=00 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=12  MxCh= 4
+T:  Bus=00 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=12   MxCh= 4
 D:  Ver= 1.00 Cls=09(hub  ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
 P:  Vendor=0451 ProdID=1446 Rev= 1.00
 C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA
 I:  If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
 E:  Ad=81(I) Atr=03(Int.) MxPS=   1 Ivl=255ms
 
-T:  Bus=00 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#=  3 Spd=1.5 MxCh= 0
+T:  Bus=00 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#=  3 Spd=1.5  MxCh= 0
 D:  Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
 P:  Vendor=04b4 ProdID=0001 Rev= 0.00
 C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA
 I:  If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=02 Driver=mouse
 E:  Ad=81(I) Atr=03(Int.) MxPS=   3 Ivl= 10ms
 
-T:  Bus=00 Lev=02 Prnt=02 Port=02 Cnt=02 Dev#=  4 Spd=12  MxCh= 0
+T:  Bus=00 Lev=02 Prnt=02 Port=02 Cnt=02 Dev#=  4 Spd=12   MxCh= 0
 D:  Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
 P:  Vendor=0565 ProdID=0001 Rev= 1.08
 S:  Manufacturer=Peracom Networks, Inc.
@@ -330,12 +340,12 @@ E:  Ad=82(I) Atr=03(Int.) MxPS=   8 Ivl=  8ms
 Selecting only the "T:" and "I:" lines from this (for example, by using
 "procusb ti"), we have:
 
-T:  Bus=00 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=12  MxCh= 2
-T:  Bus=00 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=12  MxCh= 4
+T:  Bus=00 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=12   MxCh= 2
+T:  Bus=00 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=12   MxCh= 4
 I:  If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
-T:  Bus=00 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#=  3 Spd=1.5 MxCh= 0
+T:  Bus=00 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#=  3 Spd=1.5  MxCh= 0
 I:  If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=02 Driver=mouse
-T:  Bus=00 Lev=02 Prnt=02 Port=02 Cnt=02 Dev#=  4 Spd=12  MxCh= 0
+T:  Bus=00 Lev=02 Prnt=02 Port=02 Cnt=02 Dev#=  4 Spd=12   MxCh= 0
 I:  If#= 0 Alt= 0 #EPs= 3 Cls=00(>ifc ) Sub=00 Prot=00 Driver=serial
 
 
index 060e32ab35fb71c4bbee1303114d79b6b2bf91cb..9a0432de91417ed7729f0cc5729c467954cc4e45 100644 (file)
@@ -5973,6 +5973,14 @@ S:       Maintained
 F:     Documentation/usb/acm.txt
 F:     drivers/usb/class/cdc-acm.*
 
+USB ATTACHED SCSI
+M:     Matthew Wilcox <willy@linux.intel.com>
+M:     Sarah Sharp <sarah.a.sharp@linux.intel.com>
+L:     linux-usb@vger.kernel.org
+L:     linux-scsi@vger.kernel.org
+S:     Supported
+F:     drivers/usb/storage/uas.c
+
 USB BLOCK DRIVER (UB ub)
 M:     Pete Zaitcev <zaitcev@redhat.com>
 L:     linux-usb@vger.kernel.org
index 8533bf04284a1fc682db1a7fc15897a097a61e2d..9fde873f5889c6292ae6ea97f5011bd632d54aa4 100644 (file)
@@ -131,6 +131,7 @@ static struct mxc_usbh_platform_data __maybe_unused usbh1_pdata = {
 static struct fsl_usb2_platform_data otg_device_pdata = {
        .operating_mode = FSL_USB2_DR_DEVICE,
        .phy_mode       = FSL_USB2_PHY_UTMI,
+       .workaround     = FLS_USB2_WORKAROUND_ENGCM09152,
 };
 
 static int otg_mode_host;
index f85c8da17e8bb8bcf69bbf208b2030277c3879be..d547036aff3f2cb640da7905cf75ec8f22f6aff7 100644 (file)
@@ -375,6 +375,31 @@ static void __init am3517_evm_init_irq(void)
        omap_gpio_init();
 }
 
+static struct omap_musb_board_data musb_board_data = {
+       .interface_type         = MUSB_INTERFACE_ULPI,
+       .mode                   = MUSB_OTG,
+       .power                  = 500,
+};
+
+static __init void am3517_evm_musb_init(void)
+{
+       u32 devconf2;
+
+       /*
+        * Set up USB clock/mode in the DEVCONF2 register.
+        */
+       devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
+
+       /* USB2.0 PHY reference clock is 13 MHz */
+       devconf2 &= ~(CONF2_REFFREQ | CONF2_OTGMODE | CONF2_PHY_GPIOMODE);
+       devconf2 |=  CONF2_REFFREQ_13MHZ | CONF2_SESENDEN | CONF2_VBDTCTEN
+                       | CONF2_DATPOL;
+
+       omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
+
+       usb_musb_init(&musb_board_data);
+}
+
 static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
        .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
 #if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \
@@ -393,6 +418,8 @@ static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
 
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux board_mux[] __initdata = {
+       /* USB OTG DRVVBUS offset = 0x212 */
+       OMAP3_MUX(SAD2D_MCAD23, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
        { .reg_offset = OMAP_MUX_TERMINATOR },
 };
 #else
@@ -459,6 +486,9 @@ static void __init am3517_evm_init(void)
                                ARRAY_SIZE(am3517evm_i2c1_boardinfo));
        /*Ethernet*/
        am3517_evm_ethernet_init(&am3517_evm_emac_pdata);
+
+       /* MUSB */
+       am3517_evm_musb_init();
 }
 
 MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
index 33a5cde1c227ab1767ca53e47e3189147a7a61cb..72605584bfff42d0917803ae20657f5ff648899e 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <mach/hardware.h>
 #include <mach/irqs.h>
+#include <mach/am35xx.h>
 #include <plat/usb.h>
 
 #ifdef CONFIG_USB_MUSB_SOC
@@ -89,6 +90,9 @@ void __init usb_musb_init(struct omap_musb_board_data *board_data)
 {
        if (cpu_is_omap243x()) {
                musb_resources[0].start = OMAP243X_HS_BASE;
+       } else if (cpu_is_omap3517() || cpu_is_omap3505()) {
+               musb_resources[0].start = AM35XX_IPSS_USBOTGSS_BASE;
+               musb_resources[1].start = INT_35XX_USBOTG_IRQ;
        } else if (cpu_is_omap34xx()) {
                musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE;
        } else if (cpu_is_omap44xx()) {
index 2a9427c8cc485430a28b4184afc4b20fd654dc7c..9feddacfe8503268c8e92949cc22804bb87f0b6c 100644 (file)
@@ -218,6 +218,27 @@ static inline omap2_usbfs_init(struct omap_usb_config *pdata)
 #      define  USBT2TLL5PI             (1 << 17)
 #      define  USB0PUENACTLOI          (1 << 16)
 #      define  USBSTANDBYCTRL          (1 << 15)
+/* AM35x */
+/* USB 2.0 PHY Control */
+#define CONF2_PHY_GPIOMODE     (1 << 23)
+#define CONF2_OTGMODE          (3 << 14)
+#define CONF2_NO_OVERRIDE      (0 << 14)
+#define CONF2_FORCE_HOST       (1 << 14)
+#define CONF2_FORCE_DEVICE     (2 << 14)
+#define CONF2_FORCE_HOST_VBUS_LOW (3 << 14)
+#define CONF2_SESENDEN         (1 << 13)
+#define CONF2_VBDTCTEN         (1 << 12)
+#define CONF2_REFFREQ_24MHZ    (2 << 8)
+#define CONF2_REFFREQ_26MHZ    (7 << 8)
+#define CONF2_REFFREQ_13MHZ    (6 << 8)
+#define CONF2_REFFREQ          (0xf << 8)
+#define CONF2_PHYCLKGD         (1 << 7)
+#define CONF2_VBUSSENSE                (1 << 6)
+#define CONF2_PHY_PLLON                (1 << 5)
+#define CONF2_RESET            (1 << 4)
+#define CONF2_PHYPWRDN         (1 << 3)
+#define CONF2_OTGPWRDN         (1 << 2)
+#define CONF2_DATPOL           (1 << 1)
 
 #if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_USB)
 u32 omap1_usb0_init(unsigned nwires, unsigned is_device);
index 6c67d9ebf1669e80886614e1e3d3b78528716e62..19e5015e039be1636aad915214a4f938964eb5a2 100644 (file)
@@ -209,169 +209,6 @@ static int __init of_add_fixed_phys(void)
 arch_initcall(of_add_fixed_phys);
 #endif /* CONFIG_FIXED_PHY */
 
-static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
-{
-       if (!phy_type)
-               return FSL_USB2_PHY_NONE;
-       if (!strcasecmp(phy_type, "ulpi"))
-               return FSL_USB2_PHY_ULPI;
-       if (!strcasecmp(phy_type, "utmi"))
-               return FSL_USB2_PHY_UTMI;
-       if (!strcasecmp(phy_type, "utmi_wide"))
-               return FSL_USB2_PHY_UTMI_WIDE;
-       if (!strcasecmp(phy_type, "serial"))
-               return FSL_USB2_PHY_SERIAL;
-
-       return FSL_USB2_PHY_NONE;
-}
-
-static int __init fsl_usb_of_init(void)
-{
-       struct device_node *np;
-       unsigned int i = 0;
-       struct platform_device *usb_dev_mph = NULL, *usb_dev_dr_host = NULL,
-               *usb_dev_dr_client = NULL;
-       int ret;
-
-       for_each_compatible_node(np, NULL, "fsl-usb2-mph") {
-               struct resource r[2];
-               struct fsl_usb2_platform_data usb_data;
-               const unsigned char *prop = NULL;
-
-               memset(&r, 0, sizeof(r));
-               memset(&usb_data, 0, sizeof(usb_data));
-
-               ret = of_address_to_resource(np, 0, &r[0]);
-               if (ret)
-                       goto err;
-
-               of_irq_to_resource(np, 0, &r[1]);
-
-               usb_dev_mph =
-                   platform_device_register_simple("fsl-ehci", i, r, 2);
-               if (IS_ERR(usb_dev_mph)) {
-                       ret = PTR_ERR(usb_dev_mph);
-                       goto err;
-               }
-
-               usb_dev_mph->dev.coherent_dma_mask = 0xffffffffUL;
-               usb_dev_mph->dev.dma_mask = &usb_dev_mph->dev.coherent_dma_mask;
-
-               usb_data.operating_mode = FSL_USB2_MPH_HOST;
-
-               prop = of_get_property(np, "port0", NULL);
-               if (prop)
-                       usb_data.port_enables |= FSL_USB2_PORT0_ENABLED;
-
-               prop = of_get_property(np, "port1", NULL);
-               if (prop)
-                       usb_data.port_enables |= FSL_USB2_PORT1_ENABLED;
-
-               prop = of_get_property(np, "phy_type", NULL);
-               usb_data.phy_mode = determine_usb_phy(prop);
-
-               ret =
-                   platform_device_add_data(usb_dev_mph, &usb_data,
-                                            sizeof(struct
-                                                   fsl_usb2_platform_data));
-               if (ret)
-                       goto unreg_mph;
-               i++;
-       }
-
-       for_each_compatible_node(np, NULL, "fsl-usb2-dr") {
-               struct resource r[2];
-               struct fsl_usb2_platform_data usb_data;
-               const unsigned char *prop = NULL;
-
-               if (!of_device_is_available(np))
-                       continue;
-
-               memset(&r, 0, sizeof(r));
-               memset(&usb_data, 0, sizeof(usb_data));
-
-               ret = of_address_to_resource(np, 0, &r[0]);
-               if (ret)
-                       goto unreg_mph;
-
-               of_irq_to_resource(np, 0, &r[1]);
-
-               prop = of_get_property(np, "dr_mode", NULL);
-
-               if (!prop || !strcmp(prop, "host")) {
-                       usb_data.operating_mode = FSL_USB2_DR_HOST;
-                       usb_dev_dr_host = platform_device_register_simple(
-                                       "fsl-ehci", i, r, 2);
-                       if (IS_ERR(usb_dev_dr_host)) {
-                               ret = PTR_ERR(usb_dev_dr_host);
-                               goto err;
-                       }
-               } else if (prop && !strcmp(prop, "peripheral")) {
-                       usb_data.operating_mode = FSL_USB2_DR_DEVICE;
-                       usb_dev_dr_client = platform_device_register_simple(
-                                       "fsl-usb2-udc", i, r, 2);
-                       if (IS_ERR(usb_dev_dr_client)) {
-                               ret = PTR_ERR(usb_dev_dr_client);
-                               goto err;
-                       }
-               } else if (prop && !strcmp(prop, "otg")) {
-                       usb_data.operating_mode = FSL_USB2_DR_OTG;
-                       usb_dev_dr_host = platform_device_register_simple(
-                                       "fsl-ehci", i, r, 2);
-                       if (IS_ERR(usb_dev_dr_host)) {
-                               ret = PTR_ERR(usb_dev_dr_host);
-                               goto err;
-                       }
-                       usb_dev_dr_client = platform_device_register_simple(
-                                       "fsl-usb2-udc", i, r, 2);
-                       if (IS_ERR(usb_dev_dr_client)) {
-                               ret = PTR_ERR(usb_dev_dr_client);
-                               goto err;
-                       }
-               } else {
-                       ret = -EINVAL;
-                       goto err;
-               }
-
-               prop = of_get_property(np, "phy_type", NULL);
-               usb_data.phy_mode = determine_usb_phy(prop);
-
-               if (usb_dev_dr_host) {
-                       usb_dev_dr_host->dev.coherent_dma_mask = 0xffffffffUL;
-                       usb_dev_dr_host->dev.dma_mask = &usb_dev_dr_host->
-                               dev.coherent_dma_mask;
-                       if ((ret = platform_device_add_data(usb_dev_dr_host,
-                                               &usb_data, sizeof(struct
-                                               fsl_usb2_platform_data))))
-                               goto unreg_dr;
-               }
-               if (usb_dev_dr_client) {
-                       usb_dev_dr_client->dev.coherent_dma_mask = 0xffffffffUL;
-                       usb_dev_dr_client->dev.dma_mask = &usb_dev_dr_client->
-                               dev.coherent_dma_mask;
-                       if ((ret = platform_device_add_data(usb_dev_dr_client,
-                                               &usb_data, sizeof(struct
-                                               fsl_usb2_platform_data))))
-                               goto unreg_dr;
-               }
-               i++;
-       }
-       return 0;
-
-unreg_dr:
-       if (usb_dev_dr_host)
-               platform_device_unregister(usb_dev_dr_host);
-       if (usb_dev_dr_client)
-               platform_device_unregister(usb_dev_dr_client);
-unreg_mph:
-       if (usb_dev_mph)
-               platform_device_unregister(usb_dev_mph);
-err:
-       return ret;
-}
-
-arch_initcall(fsl_usb_of_init);
-
 #if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
 static __be32 __iomem *rstcr;
 
index b5690a045a01076c782a575b4e846af64d0306c5..9ae3bb713286f0d0d3a959a81f7f4b4db5cde1db 100644 (file)
@@ -397,7 +397,7 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum);
 #else
 
 static const struct usb_device_id ub_usb_ids[] = {
-       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
+       { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, USB_SC_SCSI, USB_PR_BULK) },
        { }
 };
 
index a0dea3d1296e65ebc9b84e24ec1aeacd69aa59d7..3cb6632d451890f58361f3fff80385b0e6c69011 100644 (file)
@@ -1662,6 +1662,7 @@ static const struct hid_device_id hid_ignore_list[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) },
        { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_JESS_YUREX) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) },
index c5ae5f1545bd0a18d516edab6f04b3c18d0fca71..855aa8e355f4556b65e78c057d41d700d3671fe5 100644 (file)
 #define USB_VENDOR_ID_IMATION          0x0718
 #define USB_DEVICE_ID_DISC_STAKKA      0xd000
 
+#define USB_VENDOR_ID_JESS             0x0c45
+#define USB_DEVICE_ID_JESS_YUREX       0x1010
+
 #define USB_VENDOR_ID_KBGEAR           0x084e
 #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
 
index 20295774bf70c8c800ff0cd0eb1fe7b1488ec989..57d1e3e1bd4478548f89ef9f3a472ee4418c71b3 100644 (file)
@@ -1498,6 +1498,9 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
        unsigned long long lba;
        unsigned sector_size;
 
+       if (sdp->no_read_capacity_16)
+               return -EINVAL;
+
        do {
                memset(cmd, 0, 16);
                cmd[0] = SERVICE_ACTION_IN;
@@ -1626,6 +1629,15 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
        sector_size = get_unaligned_be32(&buffer[4]);
        lba = get_unaligned_be32(&buffer[0]);
 
+       if (sdp->no_read_capacity_16 && (lba == 0xffffffff)) {
+               /* Some buggy (usb cardreader) devices return an lba of
+                  0xffffffff when the want to report a size of 0 (with
+                  which they really mean no media is present) */
+               sdkp->capacity = 0;
+               sdkp->physical_block_size = sector_size;
+               return sector_size;
+       }
+
        if ((sizeof(sdkp->capacity) == 4) && (lba == 0xffffffff)) {
                sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a "
                        "kernel compiled with support for large block "
index e148341079b5108f873a4f26d86344984a488292..d7b383c96d5d5811620345e8e4397a9dccbc1ab8 100644 (file)
@@ -862,10 +862,16 @@ static void get_capabilities(struct scsi_cd *cd)
 static int sr_packet(struct cdrom_device_info *cdi,
                struct packet_command *cgc)
 {
+       struct scsi_cd *cd = cdi->handle;
+       struct scsi_device *sdev = cd->device;
+
+       if (cgc->cmd[0] == GPCMD_READ_DISC_INFO && sdev->no_read_disc_info)
+               return -EDRIVE_CANT_DO_THIS;
+
        if (cgc->timeout <= 0)
                cgc->timeout = IOCTL_TIMEOUT;
 
-       sr_do_ioctl(cdi->handle, cgc);
+       sr_do_ioctl(cd, cgc);
 
        return cgc->stat;
 }
index 4aa00e6e57adea87bf52cb2eca4e37b71ba9828e..67eb3770868fbbb09b94ab26c6f0fc1a96ed13c0 100644 (file)
@@ -59,6 +59,7 @@ config USB_ARCH_HAS_OHCI
 config USB_ARCH_HAS_EHCI
        boolean
        default y if PPC_83xx
+       default y if PPC_MPC512x
        default y if SOC_AU1200
        default y if ARCH_IXP4XX
        default y if ARCH_W90X900
index 4c4a776ab1cd3ba3022d6e4574e1f88d450ff549..a5d792ec3ad59328a08f544780acb9a791eef67a 100644 (file)
@@ -2,12 +2,10 @@
 # Makefile for USB ATM/xDSL drivers
 #
 
+ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
+
 obj-$(CONFIG_USB_CXACRU)       += cxacru.o
 obj-$(CONFIG_USB_SPEEDTOUCH)   += speedtch.o
 obj-$(CONFIG_USB_UEAGLEATM)    += ueagle-atm.o
 obj-$(CONFIG_USB_ATM)          += usbatm.o
 obj-$(CONFIG_USB_XUSBATM)      += xusbatm.o
-
-ifeq ($(CONFIG_USB_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
index 868bc41b5980dd05e9f31f65237e04c9344536d8..b1218683c8ecfc893d5313cfc4635ac8020a4a6d 100644 (file)
@@ -2,8 +2,8 @@
 # Makefile for Cypress C67X00 USB Controller
 #
 
-ccflags-$(CONFIG_USB_DEBUG)            += -DDEBUG
+ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
 
-obj-$(CONFIG_USB_C67X00_HCD)           += c67x00.o
+obj-$(CONFIG_USB_C67X00_HCD)   += c67x00.o
 
-c67x00-objs := c67x00-drv.o c67x00-ll-hpi.o c67x00-hcd.o c67x00-sched.o
+c67x00-y := c67x00-drv.o c67x00-ll-hpi.o c67x00-hcd.o c67x00-sched.o
index bc62fae0680fe4bd1ae67e5ef6af8e10374a6b49..d6ede989ff226ceab95c674add29581918aa114c 100644 (file)
@@ -1614,7 +1614,7 @@ static const struct usb_device_id acm_ids[] = {
        /* Support Lego NXT using pbLua firmware */
        { USB_DEVICE(0x0694, 0xff00),
        .driver_info = NOT_A_MODEM,
-               },
+       },
 
        /* control interfaces without any protocol set */
        { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
index ec16e60299050ab046f9a02dfb15e0207e264516..507a4e1b63604a1422497f8f6412fea44be8fd88 100644 (file)
@@ -2,20 +2,13 @@
 # Makefile for USB Core files and filesystem
 #
 
-usbcore-objs   := usb.o hub.o hcd.o urb.o message.o driver.o \
-                       config.o file.o buffer.o sysfs.o endpoint.o \
-                       devio.o notify.o generic.o quirks.o devices.o
+ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
 
-ifeq ($(CONFIG_PCI),y)
-       usbcore-objs    += hcd-pci.o
-endif
+usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o
+usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o
+usbcore-y += devio.o notify.o generic.o quirks.o devices.o
 
-ifeq ($(CONFIG_USB_DEVICEFS),y)
-       usbcore-objs    += inode.o
-endif
+usbcore-$(CONFIG_PCI)          += hcd-pci.o
+usbcore-$(CONFIG_USB_DEVICEFS) += inode.o
 
-obj-$(CONFIG_USB)      += usbcore.o
-
-ifeq ($(CONFIG_USB_DEBUG),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
+obj-$(CONFIG_USB)              += usbcore.o
index 3449742c00e1e3b68a4d062e28b6c056d14f7645..ddb4dc980923e443e9cc2f3e0da30855ca59ff5b 100644 (file)
@@ -66,8 +66,8 @@
 #define ALLOW_SERIAL_NUMBER
 
 static const char *format_topo =
-/* T:  Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */
-"\nT:  Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n";
+/* T:  Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=dddd MxCh=dd */
+"\nT:  Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%-4s MxCh=%2d\n";
 
 static const char *format_string_manufacturer =
 /* S:  Manufacturer=xxxx */
@@ -520,11 +520,14 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
                speed = "1.5"; break;
        case USB_SPEED_UNKNOWN:         /* usb 1.1 root hub code */
        case USB_SPEED_FULL:
-               speed = "12 "; break;
+               speed = "12"; break;
+       case USB_SPEED_WIRELESS:        /* Wireless has no real fixed speed */
        case USB_SPEED_HIGH:
                speed = "480"; break;
+       case USB_SPEED_SUPER:
+               speed = "5000"; break;
        default:
-               speed = "?? ";
+               speed = "??";
        }
        data_end = pages_start + sprintf(pages_start, format_topo,
                        bus->busnum, level, parent_devnum,
index d7a4401ef0192e2a0d4870a5d27bee082b35890a..c0e60fbcb048b245ac2d995fec508f5d654c1363 100644 (file)
@@ -1337,7 +1337,7 @@ int usb_resume(struct device *dev, pm_message_t msg)
        /* Avoid PM error messages for devices disconnected while suspended
         * as we'll display regular disconnect messages just a bit later.
         */
-       if (status == -ENODEV)
+       if (status == -ENODEV || status == -ESHUTDOWN)
                status = 0;
        return status;
 }
index 3788e738e265058ec164368a06fbf6897305aa51..9da250563027630330d92831ac0adbe428feb1cb 100644 (file)
@@ -202,7 +202,7 @@ int usb_create_ep_devs(struct device *parent,
        return retval;
 
 error_register:
-       kfree(ep_dev);
+       put_device(&ep_dev->dev);
 exit:
        return retval;
 }
index c3f98543caaf9d3867fadc756db69346bba32a04..3799573bd385db30aab6db375bab0d506595e9c0 100644 (file)
@@ -329,8 +329,10 @@ void usb_hcd_pci_shutdown(struct pci_dev *dev)
                return;
 
        if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) &&
-                       hcd->driver->shutdown)
+                       hcd->driver->shutdown) {
                hcd->driver->shutdown(hcd);
+               pci_disable_device(dev);
+       }
 }
 EXPORT_SYMBOL_GPL(usb_hcd_pci_shutdown);
 
index 5cca00a6d09d61dfe31859b866463b80091451a3..61800f77dac80f0064cd7184f858241a35e2fc8c 100644 (file)
@@ -1263,10 +1263,8 @@ static void hcd_free_coherent(struct usb_bus *bus, dma_addr_t *dma_handle,
        *dma_handle = 0;
 }
 
-static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
+void unmap_urb_setup_for_dma(struct usb_hcd *hcd, struct urb *urb)
 {
-       enum dma_data_direction dir;
-
        if (urb->transfer_flags & URB_SETUP_MAP_SINGLE)
                dma_unmap_single(hcd->self.controller,
                                urb->setup_dma,
@@ -1279,6 +1277,17 @@ static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
                                sizeof(struct usb_ctrlrequest),
                                DMA_TO_DEVICE);
 
+       /* Make it safe to call this routine more than once */
+       urb->transfer_flags &= ~(URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL);
+}
+EXPORT_SYMBOL_GPL(unmap_urb_setup_for_dma);
+
+void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
+{
+       enum dma_data_direction dir;
+
+       unmap_urb_setup_for_dma(hcd, urb);
+
        dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
        if (urb->transfer_flags & URB_DMA_MAP_SG)
                dma_unmap_sg(hcd->self.controller,
@@ -1303,10 +1312,10 @@ static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
                                dir);
 
        /* Make it safe to call this routine more than once */
-       urb->transfer_flags &= ~(URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL |
-                       URB_DMA_MAP_SG | URB_DMA_MAP_PAGE |
+       urb->transfer_flags &= ~(URB_DMA_MAP_SG | URB_DMA_MAP_PAGE |
                        URB_DMA_MAP_SINGLE | URB_MAP_LOCAL);
 }
+EXPORT_SYMBOL_GPL(unmap_urb_for_dma);
 
 static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
                           gfp_t mem_flags)
index 84c1897188d274bff4b5ade992f45ef34aa35a01..27115b45edc51fa4462147077be9b3de36f6142a 100644 (file)
@@ -758,6 +758,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
                                clear_port_feature(hdev, port1,
                                                   USB_PORT_FEAT_ENABLE);
                                portstatus &= ~USB_PORT_STAT_ENABLE;
+                       } else {
+                               /* Pretend that power was lost for USB3 devs */
+                               portstatus &= ~USB_PORT_STAT_ENABLE;
                        }
                }
 
@@ -2594,16 +2597,14 @@ static int hub_set_address(struct usb_device *udev, int devnum)
                return 0;
        if (udev->state != USB_STATE_DEFAULT)
                return -EINVAL;
-       if (hcd->driver->address_device) {
+       if (hcd->driver->address_device)
                retval = hcd->driver->address_device(hcd, udev);
-       } else {
+       else
                retval = usb_control_msg(udev, usb_sndaddr0pipe(),
                                USB_REQ_SET_ADDRESS, 0, devnum, 0,
                                NULL, 0, USB_CTRL_SET_TIMEOUT);
-               if (retval == 0)
-                       update_address(udev, devnum);
-       }
        if (retval == 0) {
+               update_address(udev, devnum);
                /* Device now using proper address. */
                usb_set_device_state(udev, USB_STATE_ADDRESS);
                usb_ep0_reinit(udev);
@@ -2860,13 +2861,16 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
        else
                i = udev->descriptor.bMaxPacketSize0;
        if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) {
-               if (udev->speed != USB_SPEED_FULL ||
+               if (udev->speed == USB_SPEED_LOW ||
                                !(i == 8 || i == 16 || i == 32 || i == 64)) {
-                       dev_err(&udev->dev, "ep0 maxpacket = %d\n", i);
+                       dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i);
                        retval = -EMSGSIZE;
                        goto fail;
                }
-               dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
+               if (udev->speed == USB_SPEED_FULL)
+                       dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
+               else
+                       dev_warn(&udev->dev, "Using ep0 maxpacket: %d\n", i);
                udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);
                usb_ep0_reinit(udev);
        }
@@ -3097,16 +3101,17 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                        udev->speed = USB_SPEED_UNKNOWN;
 
                /*
-                * xHCI needs to issue an address device command later
-                * in the hub_port_init sequence for SS/HS/FS/LS devices.
+                * Set the address.
+                * Note xHCI needs to issue an address device command later
+                * in the hub_port_init sequence for SS/HS/FS/LS devices,
+                * and xHC will assign an address to the device. But use
+                * kernel assigned address here, to avoid any address conflict
+                * issue.
                 */
-               if (!(hcd->driver->flags & HCD_USB3)) {
-                       /* set the address */
-                       choose_address(udev);
-                       if (udev->devnum <= 0) {
-                               status = -ENOTCONN;     /* Don't retry */
-                               goto loop;
-                       }
+               choose_address(udev);
+               if (udev->devnum <= 0) {
+                       status = -ENOTCONN;     /* Don't retry */
+                       goto loop;
                }
 
                /* reset (non-USB 3.0 devices) and get descriptor */
@@ -3629,7 +3634,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
        }
 
        if (!parent_hdev) {
-               /* this requires hcd-specific logic; see OHCI hc_restart() */
+               /* this requires hcd-specific logic; see ohci_restart() */
                dev_dbg(&udev->dev, "%s for root hub!\n", __func__);
                return -EISDIR;
        }
index 9f0ce7de0e366fb0066dfb92d6a6403aa5f4a2b3..d6e3e410477ec106a7f660b575e94a0bf2cc6fe9 100644 (file)
@@ -1140,13 +1140,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
 {
        int i;
 
-       dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__,
-               skip_ep0 ? "non-ep0" : "all");
-       for (i = skip_ep0; i < 16; ++i) {
-               usb_disable_endpoint(dev, i, true);
-               usb_disable_endpoint(dev, i + USB_DIR_IN, true);
-       }
-
        /* getting rid of interfaces will disconnect
         * any drivers bound to them (a key side effect)
         */
@@ -1176,6 +1169,13 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
                if (dev->state == USB_STATE_CONFIGURED)
                        usb_set_device_state(dev, USB_STATE_ADDRESS);
        }
+
+       dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__,
+               skip_ep0 ? "non-ep0" : "all");
+       for (i = skip_ep0; i < 16; ++i) {
+               usb_disable_endpoint(dev, i, true);
+               usb_disable_endpoint(dev, i + USB_DIR_IN, true);
+       }
 }
 
 /**
index 419e6b34e2fe71c9f79ed79a8e76ef64ffb5c882..c14fc082864f1c26ac71fb94538d7eeca9459f75 100644 (file)
@@ -401,8 +401,11 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
        };
 
        /* Check that the pipe's type matches the endpoint's type */
-       if (usb_pipetype(urb->pipe) != pipetypes[xfertype])
+       if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) {
+               dev_err(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n",
+                       usb_pipetype(urb->pipe), pipetypes[xfertype]);
                return -EPIPE;          /* The most suitable error code :-) */
+       }
 
        /* enforce simple/standard policy */
        allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT | URB_DIR_MASK |
index dfedee8c45b6c374637a5f1ea09817c3a9b3c325..24bbe519c737647b202dfd00c020a32e1721830e 100644 (file)
@@ -2,4 +2,4 @@
 # Makefile for early USB devices
 #
 
-obj-$(CONFIG_EARLY_PRINTK_DBGP)        += ehci-dbgp.o
+obj-$(CONFIG_EARLY_PRINTK_DBGP) += ehci-dbgp.o
index cd27f9bde2c8b5ac84905c5ae2e2c7d00545fed6..b739ca8146511dc96f38d067f139ad79b23e2348 100644 (file)
@@ -158,6 +158,7 @@ config USB_GADGET_FSL_USB2
        boolean "Freescale Highspeed USB DR Peripheral Controller"
        depends on FSL_SOC || ARCH_MXC
        select USB_GADGET_DUALSPEED
+       select USB_FSL_MPH_DR_OF
        help
           Some of Freescale PowerPC processors have a High Speed
           Dual-Role(DR) USB controller, which supports device mode.
@@ -209,17 +210,6 @@ config USB_OMAP
        default USB_GADGET
        select USB_GADGET_SELECTED
 
-config USB_OTG
-       boolean "OTG Support"
-       depends on USB_GADGET_OMAP && ARCH_OMAP_OTG && USB_OHCI_HCD
-       help
-          The most notable feature of USB OTG is support for a
-          "Dual-Role" device, which can act as either a device
-          or a host.  The initial role choice can be changed
-          later, when two dual-role devices talk to each other.
-
-          Select this only if your OMAP board has a Mini-AB connector.
-
 config USB_GADGET_PXA25X
        boolean "PXA 25x or IXP 4xx"
        depends on (ARCH_PXA && PXA25x) || ARCH_IXP4XX
@@ -716,8 +706,8 @@ config USB_FUNCTIONFS
        depends on EXPERIMENTAL
        select USB_FUNCTIONFS_GENERIC if !(USB_FUNCTIONFS_ETH || USB_FUNCTIONFS_RNDIS)
        help
-         The Function Filesystem (FunctioFS) lets one create USB
-         composite functions in user space in the same way as GadgetFS
+         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
@@ -733,14 +723,14 @@ config USB_FUNCTIONFS_ETH
        bool "Include configuration with CDC ECM (Ethernet)"
        depends on USB_FUNCTIONFS && NET
        help
-         Include a configuration with CDC ECM funcion (Ethernet) and the
-         Funcion Filesystem.
+         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
        help
-         Include a configuration with RNDIS funcion (Ethernet) and the Filesystem.
+         Include a configuration with RNDIS function (Ethernet) and the Filesystem.
 
 config USB_FUNCTIONFS_GENERIC
        bool "Include 'pure' configuration"
index 27283df37d092c0a3cd77bd285742e005bfffe27..5780db42417be5063ebdaf838288599e8ece286f 100644 (file)
@@ -1,9 +1,7 @@
 #
 # USB peripheral controller drivers
 #
-ifeq ($(CONFIG_USB_GADGET_DEBUG),y)
-       EXTRA_CFLAGS            += -DDEBUG
-endif
+ccflags-$(CONFIG_USB_GADGET_DEBUG) := -DDEBUG
 
 obj-$(CONFIG_USB_DUMMY_HCD)    += dummy_hcd.o
 obj-$(CONFIG_USB_NET2280)      += net2280.o
@@ -18,10 +16,8 @@ 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_FSL_USB2)     += fsl_usb2_udc.o
-fsl_usb2_udc-objs              := fsl_udc_core.o
-ifeq ($(CONFIG_ARCH_MXC),y)
-fsl_usb2_udc-objs              += fsl_mxc_udc.o
-endif
+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
@@ -32,21 +28,21 @@ obj-$(CONFIG_USB_LANGWELL)  += langwell_udc.o
 #
 # USB gadget drivers
 #
-g_zero-objs                    := zero.o
-g_audio-objs                   := audio.o
-g_ether-objs                   := ether.o
-g_serial-objs                  := serial.o
-g_midi-objs                    := gmidi.o
-gadgetfs-objs                  := inode.o
-g_file_storage-objs            := file_storage.o
-g_mass_storage-objs            := mass_storage.o
-g_printer-objs                 := printer.o
-g_cdc-objs                     := cdc2.o
-g_multi-objs                   := multi.o
-g_hid-objs                     := hid.o
-g_dbgp-objs                    := dbgp.o
-g_nokia-objs                   := nokia.o
-g_webcam-objs                  := webcam.o
+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_file_storage-y               := file_storage.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
 
 obj-$(CONFIG_USB_ZERO)         += g_zero.o
 obj-$(CONFIG_USB_AUDIO)                += g_audio.o
@@ -64,4 +60,3 @@ 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
-
index 731150d4b1d9d0e646e34ca03f7cbaa0ac85e398..9034e03447235bfc5061f60630f1392e38536e2f 100644 (file)
@@ -203,7 +203,7 @@ static void print_regs(struct udc *dev)
                DBG(dev, "DMA mode       = PPBNDU (packet per buffer "
                        "WITHOUT desc. update)\n");
                dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "PPBNDU");
-       } else if (use_dma && use_dma_ppb_du && use_dma_ppb_du) {
+       } else if (use_dma && use_dma_ppb && use_dma_ppb_du) {
                DBG(dev, "DMA mode       = PPBDU (packet per buffer "
                        "WITH desc. update)\n");
                dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "PPBDU");
@@ -1954,13 +1954,14 @@ static int setup_ep0(struct udc *dev)
 }
 
 /* Called by gadget driver to register itself */
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *))
 {
        struct udc              *dev = udc;
        int                     retval;
        u32 tmp;
 
-       if (!driver || !driver->bind || !driver->setup
+       if (!driver || !bind || !driver->setup
                        || driver->speed != USB_SPEED_HIGH)
                return -EINVAL;
        if (!dev)
@@ -1972,7 +1973,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
        dev->driver = driver;
        dev->gadget.dev.driver = &driver->driver;
 
-       retval = driver->bind(&dev->gadget);
+       retval = bind(&dev->gadget);
 
        /* Some gadget drivers use both ep0 directions.
         * NOTE: to gadget driver, ep0 is just one endpoint...
@@ -2000,7 +2001,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 /* shutdown requests and disconnect from gadget */
 static void
@@ -3382,8 +3383,10 @@ static int udc_probe(struct udc *dev)
        udc = dev;
 
        retval = device_register(&dev->gadget.dev);
-       if (retval)
+       if (retval) {
+               put_device(&dev->gadget.dev);
                goto finished;
+       }
 
        /* timer init */
        init_timer(&udc_timer);
index 93ead19507b632c20095980fd5b0350d6407d23d..387e503b9d14a1dc9fac7627bcbbf6f17d8c3637 100644 (file)
@@ -1628,7 +1628,8 @@ static void at91_vbus_timer(unsigned long data)
                schedule_work(&udc->vbus_timer_work);
 }
 
-int usb_gadget_register_driver (struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *))
 {
        struct at91_udc *udc = &controller;
        int             retval;
@@ -1636,7 +1637,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
 
        if (!driver
                        || driver->speed < USB_SPEED_FULL
-                       || !driver->bind
+                       || !bind
                        || !driver->setup) {
                DBG("bad parameter.\n");
                return -EINVAL;
@@ -1653,9 +1654,9 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
        udc->enabled = 1;
        udc->selfpowered = 1;
 
-       retval = driver->bind(&udc->gadget);
+       retval = bind(&udc->gadget);
        if (retval) {
-               DBG("driver->bind() returned %d\n", retval);
+               DBG("bind() returned %d\n", retval);
                udc->driver = NULL;
                udc->gadget.dev.driver = NULL;
                dev_set_drvdata(&udc->gadget.dev, NULL);
@@ -1671,7 +1672,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
        DBG("bound to %s\n", driver->driver.name);
        return 0;
 }
-EXPORT_SYMBOL (usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
 {
index d623c7bda1f610741dce00ee3ab0216cccc19303..b5e20e873cbad09bbebb7134929cf97880532bea 100644 (file)
@@ -1789,7 +1789,8 @@ out:
        return IRQ_HANDLED;
 }
 
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *))
 {
        struct usba_udc *udc = &the_udc;
        unsigned long flags;
@@ -1812,7 +1813,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
        clk_enable(udc->pclk);
        clk_enable(udc->hclk);
 
-       ret = driver->bind(&udc->gadget);
+       ret = bind(&udc->gadget);
        if (ret) {
                DBG(DBG_ERR, "Could not bind to driver %s: error %d\n",
                        driver->driver.name, ret);
@@ -1841,7 +1842,7 @@ err_driver_bind:
        udc->gadget.dev.driver = NULL;
        return ret;
 }
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
@@ -2014,6 +2015,9 @@ static int __init usba_udc_probe(struct platform_device *pdev)
                        } else {
                                disable_irq(gpio_to_irq(udc->vbus_pin));
                        }
+               } else {
+                       /* gpio_request fail so use -EINVAL for gpio_is_valid */
+                       ubc->vbus_pin = -EINVAL;
                }
        }
 
index b744ccd0f34d67e996aee533e836a77f3a4054a5..93b999e49ef39559e1dab1bb3d3abfe2e2b33b59 100644 (file)
@@ -89,7 +89,7 @@ static const struct usb_descriptor_header *otg_desc[] = {
 
 /*-------------------------------------------------------------------------*/
 
-static int __ref audio_do_config(struct usb_configuration *c)
+static int __init audio_do_config(struct usb_configuration *c)
 {
        /* FIXME alloc iConfiguration string, set it in c->strings */
 
@@ -105,7 +105,6 @@ static int __ref audio_do_config(struct usb_configuration *c)
 
 static struct usb_configuration audio_config_driver = {
        .label                  = DRIVER_DESC,
-       .bind                   = audio_do_config,
        .bConfigurationValue    = 1,
        /* .iConfiguration = DYNAMIC */
        .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
@@ -113,7 +112,7 @@ static struct usb_configuration audio_config_driver = {
 
 /*-------------------------------------------------------------------------*/
 
-static int __ref audio_bind(struct usb_composite_dev *cdev)
+static int __init audio_bind(struct usb_composite_dev *cdev)
 {
        int                     gcnum;
        int                     status;
@@ -145,7 +144,7 @@ static int __ref audio_bind(struct usb_composite_dev *cdev)
        strings_dev[STRING_PRODUCT_IDX].id = status;
        device_desc.iProduct = status;
 
-       status = usb_add_config(cdev, &audio_config_driver);
+       status = usb_add_config(cdev, &audio_config_driver, audio_do_config);
        if (status < 0)
                goto fail;
 
@@ -166,13 +165,12 @@ static struct usb_composite_driver audio_driver = {
        .name           = "g_audio",
        .dev            = &device_desc,
        .strings        = audio_strings,
-       .bind           = audio_bind,
        .unbind         = __exit_p(audio_unbind),
 };
 
 static int __init init(void)
 {
-       return usb_composite_register(&audio_driver);
+       return usb_composite_probe(&audio_driver, audio_bind);
 }
 module_init(init);
 
index 1f5ba2fd4c1f2a8059127c27c13581de2ff6a8aa..2720ab07ef1a4da3fd1ca2c45ebe61d677aee788 100644 (file)
@@ -129,7 +129,7 @@ static u8 hostaddr[ETH_ALEN];
 /*
  * We _always_ have both CDC ECM and CDC ACM functions.
  */
-static int __ref cdc_do_config(struct usb_configuration *c)
+static int __init cdc_do_config(struct usb_configuration *c)
 {
        int     status;
 
@@ -151,7 +151,6 @@ static int __ref cdc_do_config(struct usb_configuration *c)
 
 static struct usb_configuration cdc_config_driver = {
        .label                  = "CDC Composite (ECM + ACM)",
-       .bind                   = cdc_do_config,
        .bConfigurationValue    = 1,
        /* .iConfiguration = DYNAMIC */
        .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
@@ -159,7 +158,7 @@ static struct usb_configuration cdc_config_driver = {
 
 /*-------------------------------------------------------------------------*/
 
-static int __ref cdc_bind(struct usb_composite_dev *cdev)
+static int __init cdc_bind(struct usb_composite_dev *cdev)
 {
        int                     gcnum;
        struct usb_gadget       *gadget = cdev->gadget;
@@ -218,7 +217,7 @@ static int __ref cdc_bind(struct usb_composite_dev *cdev)
        device_desc.iProduct = status;
 
        /* register our configuration */
-       status = usb_add_config(cdev, &cdc_config_driver);
+       status = usb_add_config(cdev, &cdc_config_driver, cdc_do_config);
        if (status < 0)
                goto fail1;
 
@@ -245,7 +244,6 @@ static struct usb_composite_driver cdc_driver = {
        .name           = "g_cdc",
        .dev            = &device_desc,
        .strings        = dev_strings,
-       .bind           = cdc_bind,
        .unbind         = __exit_p(cdc_unbind),
 };
 
@@ -255,7 +253,7 @@ MODULE_LICENSE("GPL");
 
 static int __init init(void)
 {
-       return usb_composite_register(&cdc_driver);
+       return usb_composite_probe(&cdc_driver, cdc_bind);
 }
 module_init(init);
 
index 699695128e33de185f743afa8f26ed51f38f9295..98b36fc88c77d298bf4f8efb4c9dc2f773f1931a 100644 (file)
@@ -2340,12 +2340,15 @@ static const struct usb_ep_ops usb_ep_ops = {
 static const struct usb_gadget_ops usb_gadget_ops;
 
 /**
- * usb_gadget_register_driver: register a gadget driver
+ * usb_gadget_probe_driver: register a gadget driver
+ * @driver: the driver being registered
+ * @bind: the driver's bind callback
  *
- * Check usb_gadget_register_driver() at "usb_gadget.h" for details
- * Interrupts are enabled here
+ * Check usb_gadget_probe_driver() at <linux/usb/gadget.h> for details.
+ * Interrupts are enabled here.
  */
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *))
 {
        struct ci13xxx *udc = _udc;
        unsigned long i, k, flags;
@@ -2354,7 +2357,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
        trace("%p", driver);
 
        if (driver             == NULL ||
-           driver->bind       == NULL ||
+           bind               == NULL ||
            driver->unbind     == NULL ||
            driver->setup      == NULL ||
            driver->disconnect == NULL ||
@@ -2430,7 +2433,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
        udc->gadget.dev.driver = &driver->driver;
 
        spin_unlock_irqrestore(udc->lock, flags);
-       retval = driver->bind(&udc->gadget);                /* MAY SLEEP */
+       retval = bind(&udc->gadget);                /* MAY SLEEP */
        spin_lock_irqsave(udc->lock, flags);
 
        if (retval) {
@@ -2447,7 +2450,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
                usb_gadget_unregister_driver(driver);
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 /**
  * usb_gadget_unregister_driver: unregister a gadget driver
@@ -2462,7 +2465,6 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
        trace("%p", driver);
 
        if (driver             == NULL ||
-           driver->bind       == NULL ||
            driver->unbind     == NULL ||
            driver->setup      == NULL ||
            driver->disconnect == NULL ||
index 1160c55de7f280122038aa21ee063ac1cfa06cb3..7b5cc16e4a0bbc4b61e0627df7bee1479fbda2f4 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/device.h>
+#include <linux/utsname.h>
 
 #include <linux/usb/composite.h>
 
@@ -39,6 +40,7 @@
 #define USB_BUFSIZ     1024
 
 static struct usb_composite_driver *composite;
+static int (*composite_gadget_bind)(struct usb_composite_dev *cdev);
 
 /* Some systems will need runtime overrides for the  product identifers
  * published in the device descriptor, either numbers or strings or both.
@@ -69,6 +71,8 @@ static char *iSerialNumber;
 module_param(iSerialNumber, charp, 0);
 MODULE_PARM_DESC(iSerialNumber, "SerialNumber string");
 
+static char composite_manufacturer[50];
+
 /*-------------------------------------------------------------------------*/
 
 /**
@@ -470,18 +474,20 @@ done:
  * usb_add_config() - add a configuration to a device.
  * @cdev: wraps the USB gadget
  * @config: the configuration, with bConfigurationValue assigned
+ * @bind: the configuration's bind function
  * Context: single threaded during gadget setup
  *
- * One of the main tasks of a composite driver's bind() routine is to
+ * One of the main tasks of a composite @bind() routine is to
  * add each of the configurations it supports, using this routine.
  *
- * This function returns the value of the configuration's bind(), which
+ * This function returns the value of the configuration's @bind(), which
  * is zero for success else a negative errno value.  Binding configurations
  * assigns global resources including string IDs, and per-configuration
  * resources such as interface IDs and endpoints.
  */
 int usb_add_config(struct usb_composite_dev *cdev,
-               struct usb_configuration *config)
+               struct usb_configuration *config,
+               int (*bind)(struct usb_configuration *))
 {
        int                             status = -EINVAL;
        struct usb_configuration        *c;
@@ -490,7 +496,7 @@ int usb_add_config(struct usb_composite_dev *cdev,
                        config->bConfigurationValue,
                        config->label, config);
 
-       if (!config->bConfigurationValue || !config->bind)
+       if (!config->bConfigurationValue || !bind)
                goto done;
 
        /* Prevent duplicate configuration identifiers */
@@ -507,7 +513,7 @@ int usb_add_config(struct usb_composite_dev *cdev,
        INIT_LIST_HEAD(&config->functions);
        config->next_interface_id = 0;
 
-       status = config->bind(config);
+       status = bind(config);
        if (status < 0) {
                list_del(&config->list);
                config->cdev = NULL;
@@ -533,7 +539,7 @@ int usb_add_config(struct usb_composite_dev *cdev,
                }
        }
 
-       /* set_alt(), or next config->bind(), sets up
+       /* set_alt(), or next bind(), sets up
         * ep->driver_data as needed.
         */
        usb_ep_autoconfig_reset(cdev->gadget);
@@ -599,6 +605,7 @@ static int get_string(struct usb_composite_dev *cdev,
        struct usb_configuration        *c;
        struct usb_function             *f;
        int                             len;
+       const char                      *str;
 
        /* Yes, not only is USB's I18N support probably more than most
         * folk will ever care about ... also, it's all supported here.
@@ -638,9 +645,29 @@ static int get_string(struct usb_composite_dev *cdev,
                return s->bLength;
        }
 
-       /* Otherwise, look up and return a specified string.  String IDs
-        * are device-scoped, so we look up each string table we're told
-        * about.  These lookups are infrequent; simpler-is-better here.
+       /* Otherwise, look up and return a specified string.  First
+        * check if the string has not been overridden.
+        */
+       if (cdev->manufacturer_override == id)
+               str = iManufacturer ?: composite->iManufacturer ?:
+                       composite_manufacturer;
+       else if (cdev->product_override == id)
+               str = iProduct ?: composite->iProduct;
+       else if (cdev->serial_override == id)
+               str = iSerialNumber;
+       else
+               str = NULL;
+       if (str) {
+               struct usb_gadget_strings strings = {
+                       .language = language,
+                       .strings  = &(struct usb_string) { 0xff, str }
+               };
+               return usb_gadget_get_string(&strings, 0xff, buf);
+       }
+
+       /* String IDs are device-scoped, so we look up each string
+        * table we're told about.  These lookups are infrequent;
+        * simpler-is-better here.
         */
        if (composite->strings) {
                len = lookup_string(composite->strings, buf, language, id);
@@ -901,7 +928,8 @@ unknown:
                 */
                switch (ctrl->bRequestType & USB_RECIP_MASK) {
                case USB_RECIP_INTERFACE:
-                       f = cdev->config->interface[intf];
+                       if (cdev->config)
+                               f = cdev->config->interface[intf];
                        break;
 
                case USB_RECIP_ENDPOINT:
@@ -1025,26 +1053,17 @@ composite_unbind(struct usb_gadget *gadget)
        composite = NULL;
 }
 
-static void
-string_override_one(struct usb_gadget_strings *tab, u8 id, const char *s)
+static u8 override_id(struct usb_composite_dev *cdev, u8 *desc)
 {
-       struct usb_string               *str = tab->strings;
-
-       for (str = tab->strings; str->s; str++) {
-               if (str->id == id) {
-                       str->s = s;
-                       return;
-               }
+       if (!*desc) {
+               int ret = usb_string_id(cdev);
+               if (unlikely(ret < 0))
+                       WARNING(cdev, "failed to override string ID\n");
+               else
+                       *desc = ret;
        }
-}
 
-static void
-string_override(struct usb_gadget_strings **tab, u8 id, const char *s)
-{
-       while (*tab) {
-               string_override_one(*tab, id, s);
-               tab++;
-       }
+       return *desc;
 }
 
 static int composite_bind(struct usb_gadget *gadget)
@@ -1074,7 +1093,13 @@ static int composite_bind(struct usb_gadget *gadget)
        cdev->bufsiz = USB_BUFSIZ;
        cdev->driver = composite;
 
-       usb_gadget_set_selfpowered(gadget);
+       /*
+        * As per USB compliance update, a device that is actively drawing
+        * more than 100mA from USB must report itself as bus-powered in
+        * the GetStatus(DEVICE) call.
+        */
+       if (CONFIG_USB_GADGET_VBUS_DRAW <= USB_SELF_POWER_VBUS_MAX_DRAW)
+               usb_gadget_set_selfpowered(gadget);
 
        /* interface and string IDs start at zero via kzalloc.
         * we force endpoints to start unassigned; few controller
@@ -1094,26 +1119,41 @@ static int composite_bind(struct usb_gadget *gadget)
         * serial number), register function drivers, potentially update
         * power state and consumption, etc
         */
-       status = composite->bind(cdev);
+       status = composite_gadget_bind(cdev);
        if (status < 0)
                goto fail;
 
        cdev->desc = *composite->dev;
        cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
 
-       /* strings can't be assigned before bind() allocates the
-        * releavnt identifiers
-        */
-       if (cdev->desc.iManufacturer && iManufacturer)
-               string_override(composite->strings,
-                       cdev->desc.iManufacturer, iManufacturer);
-       if (cdev->desc.iProduct && iProduct)
-               string_override(composite->strings,
-                       cdev->desc.iProduct, iProduct);
-       if (cdev->desc.iSerialNumber && iSerialNumber)
-               string_override(composite->strings,
-                       cdev->desc.iSerialNumber, iSerialNumber);
+       /* stirng overrides */
+       if (iManufacturer || !cdev->desc.iManufacturer) {
+               if (!iManufacturer && !composite->iManufacturer &&
+                   !*composite_manufacturer)
+                       snprintf(composite_manufacturer,
+                                sizeof composite_manufacturer,
+                                "%s %s with %s",
+                                init_utsname()->sysname,
+                                init_utsname()->release,
+                                gadget->name);
+
+               cdev->manufacturer_override =
+                       override_id(cdev, &cdev->desc.iManufacturer);
+       }
+
+       if (iProduct || (!cdev->desc.iProduct && composite->iProduct))
+               cdev->product_override =
+                       override_id(cdev, &cdev->desc.iProduct);
+
+       if (iSerialNumber)
+               cdev->serial_override =
+                       override_id(cdev, &cdev->desc.iSerialNumber);
+
+       /* has userspace failed to provide a serial number? */
+       if (composite->needs_serial && !cdev->desc.iSerialNumber)
+               WARNING(cdev, "userspace failed to provide iSerialNumber\n");
 
+       /* finish up */
        status = device_create_file(&gadget->dev, &dev_attr_suspended);
        if (status)
                goto fail;
@@ -1177,7 +1217,6 @@ composite_resume(struct usb_gadget *gadget)
 static struct usb_gadget_driver composite_driver = {
        .speed          = USB_SPEED_HIGH,
 
-       .bind           = composite_bind,
        .unbind         = composite_unbind,
 
        .setup          = composite_setup,
@@ -1192,8 +1231,12 @@ static struct usb_gadget_driver composite_driver = {
 };
 
 /**
- * usb_composite_register() - register a composite driver
+ * usb_composite_probe() - register a composite driver
  * @driver: the driver to register
+ * @bind: the callback used to allocate resources that are shared across the
+ *     whole device, such as string IDs, and add its configurations using
+ *     @usb_add_config().  This may fail by returning a negative errno
+ *     value; it should return zero on successful initialization.
  * Context: single threaded during gadget setup
  *
  * This function is used to register drivers using the composite driver
@@ -1206,18 +1249,22 @@ static struct usb_gadget_driver composite_driver = {
  * while it was binding.  That would usually be done in order to wait for
  * some userspace participation.
  */
-int usb_composite_register(struct usb_composite_driver *driver)
+extern int usb_composite_probe(struct usb_composite_driver *driver,
+                              int (*bind)(struct usb_composite_dev *cdev))
 {
-       if (!driver || !driver->dev || !driver->bind || composite)
+       if (!driver || !driver->dev || !bind || composite)
                return -EINVAL;
 
+       if (!driver->iProduct)
+               driver->iProduct = driver->name;
        if (!driver->name)
                driver->name = "composite";
        composite_driver.function =  (char *) driver->name;
        composite_driver.driver.name = driver->name;
        composite = driver;
+       composite_gadget_bind = bind;
 
-       return usb_gadget_register_driver(&composite_driver);
+       return usb_gadget_probe_driver(&composite_driver, composite_bind);
 }
 
 /**
index 0ed50a2c0a361eee66f606430655065147a15c8c..e5ac8a316fecb7a7899c996b6f57f57089028f98 100644 (file)
@@ -386,15 +386,13 @@ static int dbgp_setup(struct usb_gadget *gadget,
        } else
                goto fail;
 
-       if (len >= 0) {
-               req->length = min(length, len);
-               req->zero = len < req->length;
-               if (data && req->length)
-                       memcpy(req->buf, data, req->length);
-
-               req->complete = dbgp_setup_complete;
-               return usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
-       }
+       req->length = min(length, len);
+       req->zero = len < req->length;
+       if (data && req->length)
+               memcpy(req->buf, data, req->length);
+
+       req->complete = dbgp_setup_complete;
+       return usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
 
 fail:
        dev_dbg(&dbgp.gadget->dev,
@@ -405,7 +403,6 @@ fail:
 static struct usb_gadget_driver dbgp_driver = {
        .function = "dbgp",
        .speed = USB_SPEED_HIGH,
-       .bind = dbgp_bind,
        .unbind = dbgp_unbind,
        .setup = dbgp_setup,
        .disconnect = dbgp_disconnect,
@@ -417,7 +414,7 @@ static struct usb_gadget_driver dbgp_driver = {
 
 static int __init dbgp_init(void)
 {
-       return usb_gadget_register_driver(&dbgp_driver);
+       return usb_gadget_probe_driver(&dbgp_driver, dbgp_bind);
 }
 
 static void __exit dbgp_exit(void)
index dc6546248ed99407eefef93ef850b9a5980b23e5..1d2a2abbfa803e16ba5cb0d4a7f1bd010eca268e 100644 (file)
@@ -748,7 +748,8 @@ static DEVICE_ATTR (function, S_IRUGO, show_function, NULL);
  */
 
 int
-usb_gadget_register_driver (struct usb_gadget_driver *driver)
+usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *))
 {
        struct dummy    *dum = the_controller;
        int             retval, i;
@@ -757,8 +758,7 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
                return -EINVAL;
        if (dum->driver)
                return -EBUSY;
-       if (!driver->bind || !driver->setup
-                       || driver->speed == USB_SPEED_UNKNOWN)
+       if (!bind || !driver->setup || driver->speed == USB_SPEED_UNKNOWN)
                return -EINVAL;
 
        /*
@@ -796,7 +796,7 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
        dum->gadget.dev.driver = &driver->driver;
        dev_dbg (udc_dev(dum), "binding gadget driver '%s'\n",
                        driver->driver.name);
-       retval = driver->bind(&dum->gadget);
+       retval = bind(&dum->gadget);
        if (retval) {
                dum->driver = NULL;
                dum->gadget.dev.driver = NULL;
@@ -812,7 +812,7 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
        usb_hcd_poll_rh_status (dummy_to_hcd (dum));
        return 0;
 }
-EXPORT_SYMBOL (usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 int
 usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
@@ -874,6 +874,8 @@ static int dummy_udc_probe (struct platform_device *pdev)
        struct dummy    *dum = the_controller;
        int             rc;
 
+       usb_get_hcd(dummy_to_hcd(dum));
+
        dum->gadget.name = gadget_name;
        dum->gadget.ops = &dummy_ops;
        dum->gadget.is_dualspeed = 1;
@@ -885,10 +887,10 @@ static int dummy_udc_probe (struct platform_device *pdev)
        dum->gadget.dev.parent = &pdev->dev;
        dum->gadget.dev.release = dummy_gadget_release;
        rc = device_register (&dum->gadget.dev);
-       if (rc < 0)
+       if (rc < 0) {
+               put_device(&dum->gadget.dev);
                return rc;
-
-       usb_get_hcd (dummy_to_hcd (dum));
+       }
 
        platform_set_drvdata (pdev, dum);
        rc = device_create_file (&dum->gadget.dev, &dev_attr_function);
index 114fa024c22c81571c6c2aa49a0b80303b4bd6f8..1690c9d68256c167cba61a5f5fb1c796e279e1b1 100644 (file)
@@ -237,7 +237,7 @@ static u8 hostaddr[ETH_ALEN];
  * the first one present.  That's to make Microsoft's drivers happy,
  * and to follow DOCSIS 1.0 (cable modem standard).
  */
-static int __ref rndis_do_config(struct usb_configuration *c)
+static int __init rndis_do_config(struct usb_configuration *c)
 {
        /* FIXME alloc iConfiguration string, set it in c->strings */
 
@@ -251,7 +251,6 @@ static int __ref rndis_do_config(struct usb_configuration *c)
 
 static struct usb_configuration rndis_config_driver = {
        .label                  = "RNDIS",
-       .bind                   = rndis_do_config,
        .bConfigurationValue    = 2,
        /* .iConfiguration = DYNAMIC */
        .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
@@ -270,7 +269,7 @@ MODULE_PARM_DESC(use_eem, "use CDC EEM mode");
 /*
  * We _always_ have an ECM, CDC Subset, or EEM configuration.
  */
-static int __ref eth_do_config(struct usb_configuration *c)
+static int __init eth_do_config(struct usb_configuration *c)
 {
        /* FIXME alloc iConfiguration string, set it in c->strings */
 
@@ -289,7 +288,6 @@ static int __ref eth_do_config(struct usb_configuration *c)
 
 static struct usb_configuration eth_config_driver = {
        /* .label = f(hardware) */
-       .bind                   = eth_do_config,
        .bConfigurationValue    = 1,
        /* .iConfiguration = DYNAMIC */
        .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
@@ -297,7 +295,7 @@ static struct usb_configuration eth_config_driver = {
 
 /*-------------------------------------------------------------------------*/
 
-static int __ref eth_bind(struct usb_composite_dev *cdev)
+static int __init eth_bind(struct usb_composite_dev *cdev)
 {
        int                     gcnum;
        struct usb_gadget       *gadget = cdev->gadget;
@@ -373,12 +371,13 @@ static int __ref eth_bind(struct usb_composite_dev *cdev)
 
        /* register our configuration(s); RNDIS first, if it's used */
        if (has_rndis()) {
-               status = usb_add_config(cdev, &rndis_config_driver);
+               status = usb_add_config(cdev, &rndis_config_driver,
+                               rndis_do_config);
                if (status < 0)
                        goto fail;
        }
 
-       status = usb_add_config(cdev, &eth_config_driver);
+       status = usb_add_config(cdev, &eth_config_driver, eth_do_config);
        if (status < 0)
                goto fail;
 
@@ -402,7 +401,6 @@ static struct usb_composite_driver eth_driver = {
        .name           = "g_ether",
        .dev            = &device_desc,
        .strings        = dev_strings,
-       .bind           = eth_bind,
        .unbind         = __exit_p(eth_unbind),
 };
 
@@ -412,7 +410,7 @@ MODULE_LICENSE("GPL");
 
 static int __init init(void)
 {
-       return usb_composite_register(&eth_driver);
+       return usb_composite_probe(&eth_driver, eth_bind);
 }
 module_init(init);
 
index d47a123f15abec4689bb020875da0da785766585..bd6226cbae86fa4b1b201ef8ac88df3942d9858f 100644 (file)
@@ -111,7 +111,7 @@ acm_iad_descriptor = {
        .bInterfaceCount =      2,      // control + data
        .bFunctionClass =       USB_CLASS_COMM,
        .bFunctionSubClass =    USB_CDC_SUBCLASS_ACM,
-       .bFunctionProtocol =    USB_CDC_PROTO_NONE,
+       .bFunctionProtocol =    USB_CDC_ACM_PROTO_AT_V25TER,
        /* .iFunction =         DYNAMIC */
 };
 
index 43225879c3cdb13f857e9ce85f595976ea269092..b37960f9e75312a106f5b8d969e3ba151072553f 100644 (file)
@@ -324,7 +324,7 @@ static void loopback_disable(struct usb_function *f)
 
 /*-------------------------------------------------------------------------*/
 
-static int __ref loopback_bind_config(struct usb_configuration *c)
+static int __init loopback_bind_config(struct usb_configuration *c)
 {
        struct f_loopback       *loop;
        int                     status;
@@ -346,10 +346,9 @@ static int __ref loopback_bind_config(struct usb_configuration *c)
        return status;
 }
 
-static  struct usb_configuration loopback_driver = {
+static struct usb_configuration loopback_driver = {
        .label          = "loopback",
        .strings        = loopback_strings,
-       .bind           = loopback_bind_config,
        .bConfigurationValue = 2,
        .bmAttributes   = USB_CONFIG_ATT_SELFPOWER,
        /* .iConfiguration = DYNAMIC */
@@ -382,5 +381,5 @@ int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume)
                loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
        }
 
-       return usb_add_config(cdev, &loopback_driver);
+       return usb_add_config(cdev, &loopback_driver, loopback_bind_config);
 }
index 32cce029f65c8ea366d1789e54067948fea6f509..838286b1cd140aaf282a5017db304cce3b8ad7db 100644 (file)
@@ -73,6 +73,8 @@
  *                             being removable.
  *     ->cdrom         Flag specifying that LUN shall be reported as
  *                             being a CD-ROM.
+ *     ->nofua         Flag specifying that FUA flag in SCSI WRITE(10,12)
+ *                             commands for this LUN shall be ignored.
  *
  *     lun_name_format A printf-like format for names of the LUN
  *                             devices.  This determines how the
  *                     Default true, boolean for removable media.
  *     cdrom=b[,b...]  Default false, boolean for whether to emulate
  *                             a CD-ROM drive.
+ *     nofua=b[,b...]  Default false, booleans for ignore FUA flag
+ *                             in SCSI WRITE(10,12) commands
  *     luns=N          Default N = number of filenames, number of
  *                             LUNs to support.
  *     stall           Default determined according to the type of
@@ -409,6 +413,7 @@ struct fsg_config {
                char ro;
                char removable;
                char cdrom;
+               char nofua;
        } luns[FSG_MAX_LUNS];
 
        const char              *lun_name_format;
@@ -736,7 +741,7 @@ static int do_read(struct fsg_common *common)
 
        /* Get the starting Logical Block Address and check that it's
         * not too big */
-       if (common->cmnd[0] == SC_READ_6)
+       if (common->cmnd[0] == READ_6)
                lba = get_unaligned_be24(&common->cmnd[1]);
        else {
                lba = get_unaligned_be32(&common->cmnd[2]);
@@ -874,7 +879,7 @@ static int do_write(struct fsg_common *common)
 
        /* Get the starting Logical Block Address and check that it's
         * not too big */
-       if (common->cmnd[0] == SC_WRITE_6)
+       if (common->cmnd[0] == WRITE_6)
                lba = get_unaligned_be24(&common->cmnd[1]);
        else {
                lba = get_unaligned_be32(&common->cmnd[2]);
@@ -887,7 +892,7 @@ static int do_write(struct fsg_common *common)
                        curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
                        return -EINVAL;
                }
-               if (common->cmnd[1] & 0x08) {   /* FUA */
+               if (!curlun->nofua && (common->cmnd[1] & 0x08)) { /* FUA */
                        spin_lock(&curlun->filp->f_lock);
                        curlun->filp->f_flags |= O_SYNC;
                        spin_unlock(&curlun->filp->f_lock);
@@ -1181,7 +1186,7 @@ static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh)
                return 36;
        }
 
-       buf[0] = curlun->cdrom ? TYPE_CDROM : TYPE_DISK;
+       buf[0] = curlun->cdrom ? TYPE_ROM : TYPE_DISK;
        buf[1] = curlun->removable ? 0x80 : 0;
        buf[2] = 2;             /* ANSI SCSI level 2 */
        buf[3] = 2;             /* SCSI-2 INQUIRY data format */
@@ -1348,11 +1353,11 @@ static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh)
         * The only variable value is the WriteProtect bit.  We will fill in
         * the mode data length later. */
        memset(buf, 0, 8);
-       if (mscmnd == SC_MODE_SENSE_6) {
+       if (mscmnd == MODE_SENSE) {
                buf[2] = (curlun->ro ? 0x80 : 0x00);            /* WP, DPOFUA */
                buf += 4;
                limit = 255;
-       } else {                        /* SC_MODE_SENSE_10 */
+       } else {                        /* MODE_SENSE_10 */
                buf[3] = (curlun->ro ? 0x80 : 0x00);            /* WP, DPOFUA */
                buf += 8;
                limit = 65535;          /* Should really be FSG_BUFLEN */
@@ -1392,7 +1397,7 @@ static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh)
        }
 
        /*  Store the mode data length */
-       if (mscmnd == SC_MODE_SENSE_6)
+       if (mscmnd == MODE_SENSE)
                buf0[0] = len - 1;
        else
                put_unaligned_be16(len - 2, buf0);
@@ -1881,7 +1886,7 @@ static int check_command(struct fsg_common *common, int cmnd_size,
        if (common->lun >= 0 && common->lun < common->nluns) {
                curlun = &common->luns[common->lun];
                common->curlun = curlun;
-               if (common->cmnd[0] != SC_REQUEST_SENSE) {
+               if (common->cmnd[0] != REQUEST_SENSE) {
                        curlun->sense_data = SS_NO_SENSE;
                        curlun->sense_data_info = 0;
                        curlun->info_valid = 0;
@@ -1893,8 +1898,8 @@ static int check_command(struct fsg_common *common, int cmnd_size,
 
                /* INQUIRY and REQUEST SENSE commands are explicitly allowed
                 * to use unsupported LUNs; all others may not. */
-               if (common->cmnd[0] != SC_INQUIRY &&
-                   common->cmnd[0] != SC_REQUEST_SENSE) {
+               if (common->cmnd[0] != INQUIRY &&
+                   common->cmnd[0] != REQUEST_SENSE) {
                        DBG(common, "unsupported LUN %d\n", common->lun);
                        return -EINVAL;
                }
@@ -1903,8 +1908,8 @@ static int check_command(struct fsg_common *common, int cmnd_size,
        /* If a unit attention condition exists, only INQUIRY and
         * REQUEST SENSE commands are allowed; anything else must fail. */
        if (curlun && curlun->unit_attention_data != SS_NO_SENSE &&
-                       common->cmnd[0] != SC_INQUIRY &&
-                       common->cmnd[0] != SC_REQUEST_SENSE) {
+                       common->cmnd[0] != INQUIRY &&
+                       common->cmnd[0] != REQUEST_SENSE) {
                curlun->sense_data = curlun->unit_attention_data;
                curlun->unit_attention_data = SS_NO_SENSE;
                return -EINVAL;
@@ -1955,7 +1960,7 @@ static int do_scsi_command(struct fsg_common *common)
        down_read(&common->filesem);    /* We're using the backing file */
        switch (common->cmnd[0]) {
 
-       case SC_INQUIRY:
+       case INQUIRY:
                common->data_size_from_cmnd = common->cmnd[4];
                reply = check_command(common, 6, DATA_DIR_TO_HOST,
                                      (1<<4), 0,
@@ -1964,7 +1969,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_inquiry(common, bh);
                break;
 
-       case SC_MODE_SELECT_6:
+       case MODE_SELECT:
                common->data_size_from_cmnd = common->cmnd[4];
                reply = check_command(common, 6, DATA_DIR_FROM_HOST,
                                      (1<<1) | (1<<4), 0,
@@ -1973,7 +1978,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_mode_select(common, bh);
                break;
 
-       case SC_MODE_SELECT_10:
+       case MODE_SELECT_10:
                common->data_size_from_cmnd =
                        get_unaligned_be16(&common->cmnd[7]);
                reply = check_command(common, 10, DATA_DIR_FROM_HOST,
@@ -1983,7 +1988,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_mode_select(common, bh);
                break;
 
-       case SC_MODE_SENSE_6:
+       case MODE_SENSE:
                common->data_size_from_cmnd = common->cmnd[4];
                reply = check_command(common, 6, DATA_DIR_TO_HOST,
                                      (1<<1) | (1<<2) | (1<<4), 0,
@@ -1992,7 +1997,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_mode_sense(common, bh);
                break;
 
-       case SC_MODE_SENSE_10:
+       case MODE_SENSE_10:
                common->data_size_from_cmnd =
                        get_unaligned_be16(&common->cmnd[7]);
                reply = check_command(common, 10, DATA_DIR_TO_HOST,
@@ -2002,7 +2007,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_mode_sense(common, bh);
                break;
 
-       case SC_PREVENT_ALLOW_MEDIUM_REMOVAL:
+       case ALLOW_MEDIUM_REMOVAL:
                common->data_size_from_cmnd = 0;
                reply = check_command(common, 6, DATA_DIR_NONE,
                                      (1<<4), 0,
@@ -2011,7 +2016,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_prevent_allow(common);
                break;
 
-       case SC_READ_6:
+       case READ_6:
                i = common->cmnd[4];
                common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
                reply = check_command(common, 6, DATA_DIR_TO_HOST,
@@ -2021,7 +2026,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_read(common);
                break;
 
-       case SC_READ_10:
+       case READ_10:
                common->data_size_from_cmnd =
                                get_unaligned_be16(&common->cmnd[7]) << 9;
                reply = check_command(common, 10, DATA_DIR_TO_HOST,
@@ -2031,7 +2036,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_read(common);
                break;
 
-       case SC_READ_12:
+       case READ_12:
                common->data_size_from_cmnd =
                                get_unaligned_be32(&common->cmnd[6]) << 9;
                reply = check_command(common, 12, DATA_DIR_TO_HOST,
@@ -2041,7 +2046,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_read(common);
                break;
 
-       case SC_READ_CAPACITY:
+       case READ_CAPACITY:
                common->data_size_from_cmnd = 8;
                reply = check_command(common, 10, DATA_DIR_TO_HOST,
                                      (0xf<<2) | (1<<8), 1,
@@ -2050,7 +2055,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_read_capacity(common, bh);
                break;
 
-       case SC_READ_HEADER:
+       case READ_HEADER:
                if (!common->curlun || !common->curlun->cdrom)
                        goto unknown_cmnd;
                common->data_size_from_cmnd =
@@ -2062,7 +2067,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_read_header(common, bh);
                break;
 
-       case SC_READ_TOC:
+       case READ_TOC:
                if (!common->curlun || !common->curlun->cdrom)
                        goto unknown_cmnd;
                common->data_size_from_cmnd =
@@ -2074,7 +2079,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_read_toc(common, bh);
                break;
 
-       case SC_READ_FORMAT_CAPACITIES:
+       case READ_FORMAT_CAPACITIES:
                common->data_size_from_cmnd =
                        get_unaligned_be16(&common->cmnd[7]);
                reply = check_command(common, 10, DATA_DIR_TO_HOST,
@@ -2084,7 +2089,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_read_format_capacities(common, bh);
                break;
 
-       case SC_REQUEST_SENSE:
+       case REQUEST_SENSE:
                common->data_size_from_cmnd = common->cmnd[4];
                reply = check_command(common, 6, DATA_DIR_TO_HOST,
                                      (1<<4), 0,
@@ -2093,7 +2098,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_request_sense(common, bh);
                break;
 
-       case SC_START_STOP_UNIT:
+       case START_STOP:
                common->data_size_from_cmnd = 0;
                reply = check_command(common, 6, DATA_DIR_NONE,
                                      (1<<1) | (1<<4), 0,
@@ -2102,7 +2107,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_start_stop(common);
                break;
 
-       case SC_SYNCHRONIZE_CACHE:
+       case SYNCHRONIZE_CACHE:
                common->data_size_from_cmnd = 0;
                reply = check_command(common, 10, DATA_DIR_NONE,
                                      (0xf<<2) | (3<<7), 1,
@@ -2111,7 +2116,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_synchronize_cache(common);
                break;
 
-       case SC_TEST_UNIT_READY:
+       case TEST_UNIT_READY:
                common->data_size_from_cmnd = 0;
                reply = check_command(common, 6, DATA_DIR_NONE,
                                0, 1,
@@ -2120,7 +2125,7 @@ static int do_scsi_command(struct fsg_common *common)
 
        /* Although optional, this command is used by MS-Windows.  We
         * support a minimal version: BytChk must be 0. */
-       case SC_VERIFY:
+       case VERIFY:
                common->data_size_from_cmnd = 0;
                reply = check_command(common, 10, DATA_DIR_NONE,
                                      (1<<1) | (0xf<<2) | (3<<7), 1,
@@ -2129,7 +2134,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_verify(common);
                break;
 
-       case SC_WRITE_6:
+       case WRITE_6:
                i = common->cmnd[4];
                common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
                reply = check_command(common, 6, DATA_DIR_FROM_HOST,
@@ -2139,7 +2144,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_write(common);
                break;
 
-       case SC_WRITE_10:
+       case WRITE_10:
                common->data_size_from_cmnd =
                                get_unaligned_be16(&common->cmnd[7]) << 9;
                reply = check_command(common, 10, DATA_DIR_FROM_HOST,
@@ -2149,7 +2154,7 @@ static int do_scsi_command(struct fsg_common *common)
                        reply = do_write(common);
                break;
 
-       case SC_WRITE_12:
+       case WRITE_12:
                common->data_size_from_cmnd =
                                get_unaligned_be32(&common->cmnd[6]) << 9;
                reply = check_command(common, 12, DATA_DIR_FROM_HOST,
@@ -2163,10 +2168,10 @@ static int do_scsi_command(struct fsg_common *common)
         * They don't mean much in this setting.  It's left as an exercise
         * for anyone interested to implement RESERVE and RELEASE in terms
         * of Posix locks. */
-       case SC_FORMAT_UNIT:
-       case SC_RELEASE:
-       case SC_RESERVE:
-       case SC_SEND_DIAGNOSTIC:
+       case FORMAT_UNIT:
+       case RELEASE:
+       case RESERVE:
+       case SEND_DIAGNOSTIC:
                /* Fall through */
 
        default:
@@ -2662,6 +2667,7 @@ static int fsg_main_thread(void *common_)
 
 /* Write permission is checked per LUN in store_*() functions. */
 static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro);
+static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, fsg_store_nofua);
 static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file);
 
 
@@ -2766,6 +2772,9 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
                if (rc)
                        goto error_luns;
                rc = device_create_file(&curlun->dev, &dev_attr_file);
+               if (rc)
+                       goto error_luns;
+               rc = device_create_file(&curlun->dev, &dev_attr_nofua);
                if (rc)
                        goto error_luns;
 
@@ -2911,6 +2920,7 @@ static void fsg_common_release(struct kref *ref)
 
                /* In error recovery common->nluns may be zero. */
                for (; i; --i, ++lun) {
+                       device_remove_file(&lun->dev, &dev_attr_nofua);
                        device_remove_file(&lun->dev, &dev_attr_ro);
                        device_remove_file(&lun->dev, &dev_attr_file);
                        fsg_lun_close(lun);
@@ -3069,8 +3079,10 @@ struct fsg_module_parameters {
        int             ro[FSG_MAX_LUNS];
        int             removable[FSG_MAX_LUNS];
        int             cdrom[FSG_MAX_LUNS];
+       int             nofua[FSG_MAX_LUNS];
 
        unsigned int    file_count, ro_count, removable_count, cdrom_count;
+       unsigned int    nofua_count;
        unsigned int    luns;   /* nluns */
        int             stall;  /* can_stall */
 };
@@ -3096,6 +3108,8 @@ struct fsg_module_parameters {
                                "true to simulate removable media");    \
        _FSG_MODULE_PARAM_ARRAY(prefix, params, cdrom, bool,            \
                                "true to simulate CD-ROM instead of disk"); \
+       _FSG_MODULE_PARAM_ARRAY(prefix, params, nofua, bool,            \
+                               "true to ignore SCSI WRITE(10,12) FUA bit"); \
        _FSG_MODULE_PARAM(prefix, params, luns, uint,                   \
                          "number of LUNs");                            \
        _FSG_MODULE_PARAM(prefix, params, stall, bool,                  \
index 685d768f336e4024ba020b29b9e5436e5b1fffd2..e403a534dd5530f2d485808680f4329b13276dc3 100644 (file)
@@ -404,7 +404,7 @@ static void sourcesink_disable(struct usb_function *f)
 
 /*-------------------------------------------------------------------------*/
 
-static int __ref sourcesink_bind_config(struct usb_configuration *c)
+static int __init sourcesink_bind_config(struct usb_configuration *c)
 {
        struct f_sourcesink     *ss;
        int                     status;
@@ -498,7 +498,6 @@ unknown:
 static struct usb_configuration sourcesink_driver = {
        .label          = "source/sink",
        .strings        = sourcesink_strings,
-       .bind           = sourcesink_bind_config,
        .setup          = sourcesink_setup,
        .bConfigurationValue = 3,
        .bmAttributes   = USB_CONFIG_ATT_SELFPOWER,
@@ -532,5 +531,5 @@ int __init sourcesink_add(struct usb_composite_dev *cdev, bool autoresume)
                sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
        }
 
-       return usb_add_config(cdev, &sourcesink_driver);
+       return usb_add_config(cdev, &sourcesink_driver, sourcesink_bind_config);
 }
index a857b7ac238c6145d8d3c265c420c6890ee63cb0..d4fdf65fb9253fc1c9375d7c7a5885ee27915fe2 100644 (file)
@@ -89,6 +89,7 @@
  *                             Required if "removable" is not set, names of
  *                                     the files or block devices used for
  *                                     backing storage
+ *     serial=HHHH...          Required serial number (string of hex chars)
  *     ro=b[,b...]             Default false, booleans for read-only access
  *     removable               Default false, boolean for removable media
  *     luns=N                  Default N = number of filenames, number of
  *     vendor=0xVVVV           Default 0x0525 (NetChip), USB Vendor ID
  *     product=0xPPPP          Default 0xa4a5 (FSG), USB Product ID
  *     release=0xRRRR          Override the USB release number (bcdDevice)
- *     serial=HHHH...          Override serial number (string of hex chars)
  *     buflen=N                Default N=16384, buffer size used (will be
  *                                     rounded down to a multiple of
  *                                     PAGE_CACHE_SIZE)
  *
- * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "ro",
+ * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "serial", "ro",
  * "removable", "luns", "nofua", "stall", and "cdrom" options are available;
  * default values are used for everything else.
  *
 
 #define DRIVER_DESC            "File-backed Storage Gadget"
 #define DRIVER_NAME            "g_file_storage"
-/* DRIVER_VERSION must be at least 6 characters long, as it is used
- * to generate a fallback serial number. */
-#define DRIVER_VERSION         "20 November 2008"
+#define DRIVER_VERSION         "1 September 2010"
 
 static       char fsg_string_manufacturer[64];
 static const char fsg_string_product[] = DRIVER_DESC;
-static       char fsg_string_serial[13];
 static const char fsg_string_config[] = "Self-powered";
 static const char fsg_string_interface[] = "Mass Storage";
 
@@ -305,6 +302,7 @@ MODULE_LICENSE("Dual BSD/GPL");
 
 static struct {
        char            *file[FSG_MAX_LUNS];
+       char            *serial;
        int             ro[FSG_MAX_LUNS];
        int             nofua[FSG_MAX_LUNS];
        unsigned int    num_filenames;
@@ -321,7 +319,6 @@ static struct {
        unsigned short  vendor;
        unsigned short  product;
        unsigned short  release;
-       char            *serial;
        unsigned int    buflen;
 
        int             transport_type;
@@ -346,6 +343,9 @@ module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames,
                S_IRUGO);
 MODULE_PARM_DESC(file, "names of backing files or devices");
 
+module_param_named(serial, mod_data.serial, charp, S_IRUGO);
+MODULE_PARM_DESC(serial, "USB serial number");
+
 module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO);
 MODULE_PARM_DESC(ro, "true to force read-only");
 
@@ -365,9 +365,6 @@ MODULE_PARM_DESC(stall, "false to prevent bulk stalls");
 module_param_named(cdrom, mod_data.cdrom, bool, S_IRUGO);
 MODULE_PARM_DESC(cdrom, "true to emulate cdrom instead of disk");
 
-module_param_named(serial, mod_data.serial, charp, S_IRUGO);
-MODULE_PARM_DESC(serial, "USB serial number");
-
 /* In the non-TEST version, only the module parameters listed above
  * are available. */
 #ifdef CONFIG_USB_FILE_STORAGE_TEST
@@ -786,7 +783,7 @@ static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
 {
        struct usb_request      *req = fsg->ep0req;
        static u8               cbi_reset_cmnd[6] = {
-                       SC_SEND_DIAGNOSTIC, 4, 0xff, 0xff, 0xff, 0xff};
+                       SEND_DIAGNOSTIC, 4, 0xff, 0xff, 0xff, 0xff};
 
        /* Error in command transfer? */
        if (req->status || req->length != req->actual ||
@@ -1138,7 +1135,7 @@ static int do_read(struct fsg_dev *fsg)
 
        /* Get the starting Logical Block Address and check that it's
         * not too big */
-       if (fsg->cmnd[0] == SC_READ_6)
+       if (fsg->cmnd[0] == READ_6)
                lba = get_unaligned_be24(&fsg->cmnd[1]);
        else {
                lba = get_unaligned_be32(&fsg->cmnd[2]);
@@ -1273,7 +1270,7 @@ static int do_write(struct fsg_dev *fsg)
 
        /* Get the starting Logical Block Address and check that it's
         * not too big */
-       if (fsg->cmnd[0] == SC_WRITE_6)
+       if (fsg->cmnd[0] == WRITE_6)
                lba = get_unaligned_be24(&fsg->cmnd[1]);
        else {
                lba = get_unaligned_be32(&fsg->cmnd[2]);
@@ -1581,7 +1578,7 @@ static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh)
        }
 
        memset(buf, 0, 8);
-       buf[0] = (mod_data.cdrom ? TYPE_CDROM : TYPE_DISK);
+       buf[0] = (mod_data.cdrom ? TYPE_ROM : TYPE_DISK);
        if (mod_data.removable)
                buf[1] = 0x80;
        buf[2] = 2;             // ANSI SCSI level 2
@@ -1750,11 +1747,11 @@ static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
         * The only variable value is the WriteProtect bit.  We will fill in
         * the mode data length later. */
        memset(buf, 0, 8);
-       if (mscmnd == SC_MODE_SENSE_6) {
+       if (mscmnd == MODE_SENSE) {
                buf[2] = (curlun->ro ? 0x80 : 0x00);            // WP, DPOFUA
                buf += 4;
                limit = 255;
-       } else {                        // SC_MODE_SENSE_10
+       } else {                        // MODE_SENSE_10
                buf[3] = (curlun->ro ? 0x80 : 0x00);            // WP, DPOFUA
                buf += 8;
                limit = 65535;          // Should really be mod_data.buflen
@@ -1794,7 +1791,7 @@ static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
        }
 
        /*  Store the mode data length */
-       if (mscmnd == SC_MODE_SENSE_6)
+       if (mscmnd == MODE_SENSE)
                buf0[0] = len - 1;
        else
                put_unaligned_be16(len - 2, buf0);
@@ -2319,7 +2316,7 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
        /* Check the LUN */
        if (fsg->lun >= 0 && fsg->lun < fsg->nluns) {
                fsg->curlun = curlun = &fsg->luns[fsg->lun];
-               if (fsg->cmnd[0] != SC_REQUEST_SENSE) {
+               if (fsg->cmnd[0] != REQUEST_SENSE) {
                        curlun->sense_data = SS_NO_SENSE;
                        curlun->sense_data_info = 0;
                        curlun->info_valid = 0;
@@ -2330,8 +2327,8 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
 
                /* INQUIRY and REQUEST SENSE commands are explicitly allowed
                 * to use unsupported LUNs; all others may not. */
-               if (fsg->cmnd[0] != SC_INQUIRY &&
-                               fsg->cmnd[0] != SC_REQUEST_SENSE) {
+               if (fsg->cmnd[0] != INQUIRY &&
+                               fsg->cmnd[0] != REQUEST_SENSE) {
                        DBG(fsg, "unsupported LUN %d\n", fsg->lun);
                        return -EINVAL;
                }
@@ -2340,8 +2337,8 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
        /* If a unit attention condition exists, only INQUIRY and
         * REQUEST SENSE commands are allowed; anything else must fail. */
        if (curlun && curlun->unit_attention_data != SS_NO_SENSE &&
-                       fsg->cmnd[0] != SC_INQUIRY &&
-                       fsg->cmnd[0] != SC_REQUEST_SENSE) {
+                       fsg->cmnd[0] != INQUIRY &&
+                       fsg->cmnd[0] != REQUEST_SENSE) {
                curlun->sense_data = curlun->unit_attention_data;
                curlun->unit_attention_data = SS_NO_SENSE;
                return -EINVAL;
@@ -2391,7 +2388,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
        down_read(&fsg->filesem);       // We're using the backing file
        switch (fsg->cmnd[0]) {
 
-       case SC_INQUIRY:
+       case INQUIRY:
                fsg->data_size_from_cmnd = fsg->cmnd[4];
                if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
                                (1<<4), 0,
@@ -2399,7 +2396,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_inquiry(fsg, bh);
                break;
 
-       case SC_MODE_SELECT_6:
+       case MODE_SELECT:
                fsg->data_size_from_cmnd = fsg->cmnd[4];
                if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST,
                                (1<<1) | (1<<4), 0,
@@ -2407,7 +2404,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_mode_select(fsg, bh);
                break;
 
-       case SC_MODE_SELECT_10:
+       case MODE_SELECT_10:
                fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
                if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST,
                                (1<<1) | (3<<7), 0,
@@ -2415,7 +2412,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_mode_select(fsg, bh);
                break;
 
-       case SC_MODE_SENSE_6:
+       case MODE_SENSE:
                fsg->data_size_from_cmnd = fsg->cmnd[4];
                if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
                                (1<<1) | (1<<2) | (1<<4), 0,
@@ -2423,7 +2420,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_mode_sense(fsg, bh);
                break;
 
-       case SC_MODE_SENSE_10:
+       case MODE_SENSE_10:
                fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
                if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
                                (1<<1) | (1<<2) | (3<<7), 0,
@@ -2431,7 +2428,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_mode_sense(fsg, bh);
                break;
 
-       case SC_PREVENT_ALLOW_MEDIUM_REMOVAL:
+       case ALLOW_MEDIUM_REMOVAL:
                fsg->data_size_from_cmnd = 0;
                if ((reply = check_command(fsg, 6, DATA_DIR_NONE,
                                (1<<4), 0,
@@ -2439,7 +2436,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_prevent_allow(fsg);
                break;
 
-       case SC_READ_6:
+       case READ_6:
                i = fsg->cmnd[4];
                fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
                if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
@@ -2448,7 +2445,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_read(fsg);
                break;
 
-       case SC_READ_10:
+       case READ_10:
                fsg->data_size_from_cmnd =
                                get_unaligned_be16(&fsg->cmnd[7]) << 9;
                if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
@@ -2457,7 +2454,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_read(fsg);
                break;
 
-       case SC_READ_12:
+       case READ_12:
                fsg->data_size_from_cmnd =
                                get_unaligned_be32(&fsg->cmnd[6]) << 9;
                if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST,
@@ -2466,7 +2463,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_read(fsg);
                break;
 
-       case SC_READ_CAPACITY:
+       case READ_CAPACITY:
                fsg->data_size_from_cmnd = 8;
                if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
                                (0xf<<2) | (1<<8), 1,
@@ -2474,7 +2471,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_read_capacity(fsg, bh);
                break;
 
-       case SC_READ_HEADER:
+       case READ_HEADER:
                if (!mod_data.cdrom)
                        goto unknown_cmnd;
                fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
@@ -2484,7 +2481,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_read_header(fsg, bh);
                break;
 
-       case SC_READ_TOC:
+       case READ_TOC:
                if (!mod_data.cdrom)
                        goto unknown_cmnd;
                fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
@@ -2494,7 +2491,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_read_toc(fsg, bh);
                break;
 
-       case SC_READ_FORMAT_CAPACITIES:
+       case READ_FORMAT_CAPACITIES:
                fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
                if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
                                (3<<7), 1,
@@ -2502,7 +2499,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_read_format_capacities(fsg, bh);
                break;
 
-       case SC_REQUEST_SENSE:
+       case REQUEST_SENSE:
                fsg->data_size_from_cmnd = fsg->cmnd[4];
                if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
                                (1<<4), 0,
@@ -2510,7 +2507,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_request_sense(fsg, bh);
                break;
 
-       case SC_START_STOP_UNIT:
+       case START_STOP:
                fsg->data_size_from_cmnd = 0;
                if ((reply = check_command(fsg, 6, DATA_DIR_NONE,
                                (1<<1) | (1<<4), 0,
@@ -2518,7 +2515,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_start_stop(fsg);
                break;
 
-       case SC_SYNCHRONIZE_CACHE:
+       case SYNCHRONIZE_CACHE:
                fsg->data_size_from_cmnd = 0;
                if ((reply = check_command(fsg, 10, DATA_DIR_NONE,
                                (0xf<<2) | (3<<7), 1,
@@ -2526,7 +2523,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_synchronize_cache(fsg);
                break;
 
-       case SC_TEST_UNIT_READY:
+       case TEST_UNIT_READY:
                fsg->data_size_from_cmnd = 0;
                reply = check_command(fsg, 6, DATA_DIR_NONE,
                                0, 1,
@@ -2535,7 +2532,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
 
        /* Although optional, this command is used by MS-Windows.  We
         * support a minimal version: BytChk must be 0. */
-       case SC_VERIFY:
+       case VERIFY:
                fsg->data_size_from_cmnd = 0;
                if ((reply = check_command(fsg, 10, DATA_DIR_NONE,
                                (1<<1) | (0xf<<2) | (3<<7), 1,
@@ -2543,7 +2540,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_verify(fsg);
                break;
 
-       case SC_WRITE_6:
+       case WRITE_6:
                i = fsg->cmnd[4];
                fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
                if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST,
@@ -2552,7 +2549,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_write(fsg);
                break;
 
-       case SC_WRITE_10:
+       case WRITE_10:
                fsg->data_size_from_cmnd =
                                get_unaligned_be16(&fsg->cmnd[7]) << 9;
                if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST,
@@ -2561,7 +2558,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
                        reply = do_write(fsg);
                break;
 
-       case SC_WRITE_12:
+       case WRITE_12:
                fsg->data_size_from_cmnd =
                                get_unaligned_be32(&fsg->cmnd[6]) << 9;
                if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST,
@@ -2574,10 +2571,10 @@ static int do_scsi_command(struct fsg_dev *fsg)
         * They don't mean much in this setting.  It's left as an exercise
         * for anyone interested to implement RESERVE and RELEASE in terms
         * of Posix locks. */
-       case SC_FORMAT_UNIT:
-       case SC_RELEASE:
-       case SC_RESERVE:
-       case SC_SEND_DIAGNOSTIC:
+       case FORMAT_UNIT:
+       case RELEASE:
+       case RESERVE:
+       case SEND_DIAGNOSTIC:
                // Fall through
 
        default:
@@ -3178,6 +3175,7 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
        for (i = 0; i < fsg->nluns; ++i) {
                curlun = &fsg->luns[i];
                if (curlun->registered) {
+                       device_remove_file(&curlun->dev, &dev_attr_nofua);
                        device_remove_file(&curlun->dev, &dev_attr_ro);
                        device_remove_file(&curlun->dev, &dev_attr_file);
                        fsg_lun_close(curlun);
@@ -3213,7 +3211,6 @@ static int __init check_parameters(struct fsg_dev *fsg)
 {
        int     prot;
        int     gcnum;
-       int     i;
 
        /* Store the default values */
        mod_data.transport_type = USB_PR_BULK;
@@ -3309,45 +3306,29 @@ static int __init check_parameters(struct fsg_dev *fsg)
                        if ((*ch < '0' || *ch > '9') &&
                            (*ch < 'A' || *ch > 'F')) { /* not uppercase hex */
                                WARNING(fsg,
-                                       "Invalid serial string character: %c; "
-                                       "Failing back to default\n",
+                                       "Invalid serial string character: %c\n",
                                        *ch);
-                               goto fill_serial;
+                               goto no_serial;
                        }
                }
                if (len > 126 ||
                    (mod_data.transport_type == USB_PR_BULK && len < 12) ||
                    (mod_data.transport_type != USB_PR_BULK && len > 12)) {
-                       WARNING(fsg,
-                               "Invalid serial string length; "
-                               "Failing back to default\n");
-                       goto fill_serial;
+                       WARNING(fsg, "Invalid serial string length!\n");
+                       goto no_serial;
                }
                fsg_strings[FSG_STRING_SERIAL - 1].s = mod_data.serial;
        } else {
-               WARNING(fsg,
-                       "Userspace failed to provide serial number; "
-                       "Failing back to default\n");
-fill_serial:
-               /* Serial number not specified or invalid, make our own.
-                * We just encode it from the driver version string,
-                * 12 characters to comply with both CB[I] and BBB spec.
-                * Warning : Two devices running the same kernel will have
-                * the same fallback serial number. */
-               for (i = 0; i < 12; i += 2) {
-                       unsigned char   c = DRIVER_VERSION[i / 2];
-
-                       if (!c)
-                               break;
-                       sprintf(&fsg_string_serial[i], "%02X", c);
-               }
+               WARNING(fsg, "No serial-number string provided!\n");
+ no_serial:
+               device_desc.iSerialNumber = 0;
        }
 
        return 0;
 }
 
 
-static int __ref fsg_bind(struct usb_gadget *gadget)
+static int __init fsg_bind(struct usb_gadget *gadget)
 {
        struct fsg_dev          *fsg = the_fsg;
        int                     rc;
@@ -3607,7 +3588,6 @@ static struct usb_gadget_driver           fsg_driver = {
        .speed          = USB_SPEED_FULL,
 #endif
        .function       = (char *) fsg_string_product,
-       .bind           = fsg_bind,
        .unbind         = fsg_unbind,
        .disconnect     = fsg_disconnect,
        .setup          = fsg_setup,
@@ -3649,7 +3629,7 @@ static int __init fsg_init(void)
        if ((rc = fsg_alloc()) != 0)
                return rc;
        fsg = the_fsg;
-       if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0)
+       if ((rc = usb_gadget_probe_driver(&fsg_driver, fsg_bind)) != 0)
                kref_put(&fsg->ref, fsg_release);
        return rc;
 }
index eafa6d2c5ed734b278eaf1d34c69ab8f3290e383..5bdbfe6198537d76da36d6077e9d1ac786c5a7fc 100644 (file)
 static struct clk *mxc_ahb_clk;
 static struct clk *mxc_usb_clk;
 
+/* workaround ENGcm09152 for i.MX35 */
+#define USBPHYCTRL_OTGBASE_OFFSET      0x608
+#define USBPHYCTRL_EVDO                        (1 << 23)
+
 int fsl_udc_clk_init(struct platform_device *pdev)
 {
        struct fsl_usb2_platform_data *pdata;
@@ -84,6 +88,17 @@ eenahb:
 void fsl_udc_clk_finalize(struct platform_device *pdev)
 {
        struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+#if defined(CONFIG_ARCH_MX35)
+       unsigned int v;
+
+       /* workaround ENGcm09152 for i.MX35 */
+       if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) {
+               v = readl(MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR +
+                               USBPHYCTRL_OTGBASE_OFFSET));
+               writel(v | USBPHYCTRL_EVDO, MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR +
+                               USBPHYCTRL_OTGBASE_OFFSET));
+       }
+#endif
 
        /* ULPI transceivers don't need usbpll */
        if (pdata->phy_mode == FSL_USB2_PHY_ULPI) {
index a5ea2c1d8c93353d68dfe5ef2dbfff597acb5dfe..792d5ef4013737ab4ec48971b5985a3af3aad549 100644 (file)
@@ -2302,9 +2302,10 @@ static irqreturn_t qe_udc_irq(int irq, void *_udc)
 }
 
 /*-------------------------------------------------------------------------
-       Gadget driver register and unregister.
+       Gadget driver probe and unregister.
  --------------------------------------------------------------------------*/
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *))
 {
        int retval;
        unsigned long flags = 0;
@@ -2315,8 +2316,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 
        if (!driver || (driver->speed != USB_SPEED_FULL
                        && driver->speed != USB_SPEED_HIGH)
-                       || !driver->bind || !driver->disconnect
-                       || !driver->setup)
+                       || !bind || !driver->disconnect || !driver->setup)
                return -EINVAL;
 
        if (udc_controller->driver)
@@ -2332,7 +2332,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
        udc_controller->gadget.speed = (enum usb_device_speed)(driver->speed);
        spin_unlock_irqrestore(&udc_controller->lock, flags);
 
-       retval = driver->bind(&udc_controller->gadget);
+       retval = bind(&udc_controller->gadget);
        if (retval) {
                dev_err(udc_controller->dev, "bind to %s --> %d",
                                driver->driver.name, retval);
@@ -2353,7 +2353,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
                udc_controller->gadget.name, driver->driver.name);
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
index 08a9a62a39e34910ecbcb3fdb8381c044fa851e4..c16b402a876b6008357cd0852b11d2c79af34b2b 100644 (file)
@@ -1765,7 +1765,8 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc)
  * Hook to gadget drivers
  * Called by initialization code of gadget drivers
 *----------------------------------------------------------------*/
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *))
 {
        int retval = -ENODEV;
        unsigned long flags = 0;
@@ -1775,8 +1776,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 
        if (!driver || (driver->speed != USB_SPEED_FULL
                                && driver->speed != USB_SPEED_HIGH)
-                       || !driver->bind || !driver->disconnect
-                       || !driver->setup)
+                       || !bind || !driver->disconnect || !driver->setup)
                return -EINVAL;
 
        if (udc_controller->driver)
@@ -1792,7 +1792,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
        spin_unlock_irqrestore(&udc_controller->lock, flags);
 
        /* bind udc driver to gadget driver */
-       retval = driver->bind(&udc_controller->gadget);
+       retval = bind(&udc_controller->gadget);
        if (retval) {
                VDBG("bind to %s --> %d", driver->driver.name, retval);
                udc_controller->gadget.dev.driver = NULL;
@@ -1814,7 +1814,7 @@ out:
                       retval);
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 /* Disconnect from gadget driver */
 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
index a9474f8d5325520d728cce52314a39cb91669185..af75e3620849661f297f1cbd6059bbc82bdac043 100644 (file)
@@ -52,9 +52,8 @@ MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR("Michal Nazarewicz");
 MODULE_LICENSE("GPL");
 
-
-static unsigned short gfs_vendor_id    = 0x0525;       /* XXX NetChip */
-static unsigned short gfs_product_id   = 0xa4ac;       /* XXX */
+#define GFS_VENDOR_ID  0x1d6b  /* Linux Foundation */
+#define GFS_PRODUCT_ID 0x0105  /* FunctionFS Gadget */
 
 static struct usb_device_descriptor gfs_dev_desc = {
        .bLength                = sizeof gfs_dev_desc,
@@ -63,29 +62,16 @@ static struct usb_device_descriptor gfs_dev_desc = {
        .bcdUSB                 = cpu_to_le16(0x0200),
        .bDeviceClass           = USB_CLASS_PER_INTERFACE,
 
-       /* Vendor and product id can be overridden by module parameters.  */
-       /* .idVendor            = cpu_to_le16(gfs_vendor_id), */
-       /* .idProduct           = cpu_to_le16(gfs_product_id), */
-       /* .bcdDevice           = f(hardware) */
-       /* .iManufacturer       = DYNAMIC */
-       /* .iProduct            = DYNAMIC */
-       /* NO SERIAL NUMBER */
-       .bNumConfigurations     = 1,
+       .idVendor               = cpu_to_le16(GFS_VENDOR_ID),
+       .idProduct              = cpu_to_le16(GFS_PRODUCT_ID),
 };
 
-#define GFS_MODULE_PARAM_DESC(name, field) \
-       MODULE_PARM_DESC(name, "Value of the " #field " field of the device descriptor sent to the host.  Takes effect only prior to the user-space driver registering to the FunctionFS.")
-
-module_param_named(usb_class,    gfs_dev_desc.bDeviceClass,    byte,   0644);
-GFS_MODULE_PARAM_DESC(usb_class, bDeviceClass);
-module_param_named(usb_subclass, gfs_dev_desc.bDeviceSubClass, byte,   0644);
-GFS_MODULE_PARAM_DESC(usb_subclass, bDeviceSubClass);
-module_param_named(usb_protocol, gfs_dev_desc.bDeviceProtocol, byte,   0644);
-GFS_MODULE_PARAM_DESC(usb_protocol, bDeviceProtocol);
-module_param_named(usb_vendor,   gfs_vendor_id,                ushort, 0644);
-GFS_MODULE_PARAM_DESC(usb_vendor, idVendor);
-module_param_named(usb_product,  gfs_product_id,               ushort, 0644);
-GFS_MODULE_PARAM_DESC(usb_product, idProduct);
+module_param_named(bDeviceClass,    gfs_dev_desc.bDeviceClass,    byte,   0644);
+MODULE_PARM_DESC(bDeviceClass, "USB Device class");
+module_param_named(bDeviceSubClass, gfs_dev_desc.bDeviceSubClass, byte,   0644);
+MODULE_PARM_DESC(bDeviceSubClass, "USB Device subclass");
+module_param_named(bDeviceProtocol, gfs_dev_desc.bDeviceProtocol, byte,   0644);
+MODULE_PARM_DESC(bDeviceProtocol, "USB Device protocol");
 
 
 
@@ -95,8 +81,10 @@ static const struct usb_descriptor_header *gfs_otg_desc[] = {
                .bLength                = sizeof(struct usb_otg_descriptor),
                .bDescriptorType        = USB_DT_OTG,
 
-               /* REVISIT SRP-only hardware is possible, although
-                * it would not be called "OTG" ... */
+               /*
+                * REVISIT SRP-only hardware is possible, although
+                * it would not be called "OTG" ...
+                */
                .bmAttributes           = USB_OTG_SRP | USB_OTG_HNP,
        },
 
@@ -105,19 +93,7 @@ static const struct usb_descriptor_header *gfs_otg_desc[] = {
 
 /* string IDs are assigned dynamically */
 
-enum {
-       GFS_STRING_MANUFACTURER_IDX,
-       GFS_STRING_PRODUCT_IDX,
-       GFS_STRING_FIRST_CONFIG_IDX,
-};
-
-static       char gfs_manufacturer[50];
-static const char gfs_driver_desc[] = DRIVER_DESC;
-static const char gfs_short_name[]  = DRIVER_NAME;
-
 static struct usb_string gfs_strings[] = {
-       [GFS_STRING_MANUFACTURER_IDX].s = gfs_manufacturer,
-       [GFS_STRING_PRODUCT_IDX].s = gfs_driver_desc,
 #ifdef CONFIG_USB_FUNCTIONFS_RNDIS
        { .s = "FunctionFS + RNDIS" },
 #endif
@@ -168,11 +144,11 @@ static int gfs_unbind(struct usb_composite_dev *cdev);
 static int gfs_do_config(struct usb_configuration *c);
 
 static struct usb_composite_driver gfs_driver = {
-       .name           = gfs_short_name,
+       .name           = DRIVER_NAME,
        .dev            = &gfs_dev_desc,
        .strings        = gfs_dev_strings,
-       .bind           = gfs_bind,
        .unbind         = gfs_unbind,
+       .iProduct       = DRIVER_DESC,
 };
 
 
@@ -210,7 +186,7 @@ static int functionfs_ready_callback(struct ffs_data *ffs)
                return -EBUSY;
 
        gfs_ffs_data = ffs;
-       ret = usb_composite_register(&gfs_driver);
+       ret = usb_composite_probe(&gfs_driver, gfs_bind);
        if (unlikely(ret < 0))
                clear_bit(0, &gfs_registered);
        return ret;
@@ -245,20 +221,10 @@ static int gfs_bind(struct usb_composite_dev *cdev)
        if (unlikely(ret < 0))
                goto error_quick;
 
-       gfs_dev_desc.idVendor  = cpu_to_le16(gfs_vendor_id);
-       gfs_dev_desc.idProduct = cpu_to_le16(gfs_product_id);
-
-       snprintf(gfs_manufacturer, sizeof gfs_manufacturer, "%s %s with %s",
-                init_utsname()->sysname, init_utsname()->release,
-                cdev->gadget->name);
-
        ret = usb_string_ids_tab(cdev, gfs_strings);
        if (unlikely(ret < 0))
                goto error;
 
-       gfs_dev_desc.iManufacturer = gfs_strings[GFS_STRING_MANUFACTURER_IDX].id;
-       gfs_dev_desc.iProduct      = gfs_strings[GFS_STRING_PRODUCT_IDX].id;
-
        ret = functionfs_bind(gfs_ffs_data, cdev);
        if (unlikely(ret < 0))
                goto error;
@@ -266,14 +232,12 @@ static int gfs_bind(struct usb_composite_dev *cdev)
        for (i = 0; i < ARRAY_SIZE(gfs_configurations); ++i) {
                struct gfs_configuration *c = gfs_configurations + i;
 
-               ret = GFS_STRING_FIRST_CONFIG_IDX + i;
-               c->c.label                      = gfs_strings[ret].s;
-               c->c.iConfiguration             = gfs_strings[ret].id;
-               c->c.bind                       = gfs_do_config;
+               c->c.label                      = gfs_strings[i].s;
+               c->c.iConfiguration             = gfs_strings[i].id;
                c->c.bConfigurationValue        = 1 + i;
                c->c.bmAttributes               = USB_CONFIG_ATT_SELFPOWER;
 
-               ret = usb_add_config(cdev, &c->c);
+               ret = usb_add_config(cdev, &c->c, gfs_do_config);
                if (unlikely(ret < 0))
                        goto error_unbind;
        }
@@ -293,13 +257,14 @@ static int gfs_unbind(struct usb_composite_dev *cdev)
 {
        ENTER();
 
-       /* We may have been called in an error recovery frem
+       /*
+        * We may have been called in an error recovery from
         * composite_bind() after gfs_unbind() failure so we need to
         * check if gfs_ffs_data is not NULL since gfs_bind() handles
         * all error recovery itself.  I'd rather we werent called
         * from composite on orror recovery, but what you're gonna
-        * do...? */
-
+        * do...?
+        */
        if (gfs_ffs_data) {
                gether_cleanup();
                functionfs_unbind(gfs_ffs_data);
@@ -334,14 +299,16 @@ static int gfs_do_config(struct usb_configuration *c)
        if (unlikely(ret < 0))
                return ret;
 
-       /* After previous do_configs there may be some invalid
+       /*
+        * After previous do_configs there may be some invalid
         * pointers in c->interface array.  This happens every time
         * a user space function with fewer interfaces than a user
         * space function that was run before the new one is run.  The
         * compasit's set_config() assumes that if there is no more
         * then MAX_CONFIG_INTERFACES interfaces in a configuration
         * then there is a NULL pointer after the last interface in
-        * c->interface array.  We need to make sure this is true. */
+        * c->interface array.  We need to make sure this is true.
+        */
        if (c->next_interface_id < ARRAY_SIZE(c->interface))
                c->interface[c->next_interface_id] = NULL;
 
@@ -350,10 +317,12 @@ static int gfs_do_config(struct usb_configuration *c)
 
 
 #ifdef CONFIG_USB_FUNCTIONFS_ETH
+
 static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
 {
        return can_support_ecm(c->cdev->gadget)
                ? ecm_bind_config(c, ethaddr)
                : geth_bind_config(c, ethaddr);
 }
+
 #endif
index 1b413a5cc3f6db1aca64e7d4b2f9d518c744a9f2..0ab7e141d4940061f489b8862479a3e58d19df16 100644 (file)
@@ -1157,7 +1157,7 @@ fail:
 /*
  * Creates an output endpoint, and initializes output ports.
  */
-static int __ref gmidi_bind(struct usb_gadget *gadget)
+static int __init gmidi_bind(struct usb_gadget *gadget)
 {
        struct gmidi_device *dev;
        struct usb_ep *in_ep, *out_ep;
@@ -1292,7 +1292,6 @@ static void gmidi_resume(struct usb_gadget *gadget)
 static struct usb_gadget_driver gmidi_driver = {
        .speed          = USB_SPEED_FULL,
        .function       = (char *)longname,
-       .bind           = gmidi_bind,
        .unbind         = gmidi_unbind,
 
        .setup          = gmidi_setup,
@@ -1309,7 +1308,7 @@ static struct usb_gadget_driver gmidi_driver = {
 
 static int __init gmidi_init(void)
 {
-       return usb_gadget_register_driver(&gmidi_driver);
+       return usb_gadget_probe_driver(&gmidi_driver, gmidi_bind);
 }
 module_init(gmidi_init);
 
index 1088d08c7ed8fac07146bd8d6fbde9d59a1897ca..48a760220baf992c48541f2cae822943690bae5c 100644 (file)
@@ -1343,14 +1343,15 @@ static struct goku_udc  *the_controller;
  * disconnect is reported.  then a host may connect again, or
  * the driver might get unbound.
  */
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *))
 {
        struct goku_udc *dev = the_controller;
        int                     retval;
 
        if (!driver
                        || driver->speed < USB_SPEED_FULL
-                       || !driver->bind
+                       || !bind
                        || !driver->disconnect
                        || !driver->setup)
                return -EINVAL;
@@ -1363,7 +1364,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
        driver->driver.bus = NULL;
        dev->driver = driver;
        dev->gadget.dev.driver = &driver->driver;
-       retval = driver->bind(&dev->gadget);
+       retval = bind(&dev->gadget);
        if (retval) {
                DBG(dev, "bind to driver %s --> error %d\n",
                                driver->driver.name, retval);
@@ -1380,7 +1381,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
        DBG(dev, "registered gadget driver '%s'\n", driver->driver.name);
        return 0;
 }
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 static void
 stop_activity(struct goku_udc *dev, struct usb_gadget_driver *driver)
@@ -1744,7 +1745,8 @@ static void goku_remove(struct pci_dev *pdev)
                                pci_resource_len (pdev, 0));
        if (dev->enabled)
                pci_disable_device(pdev);
-       device_unregister(&dev->gadget.dev);
+       if (dev->registered)
+               device_unregister(&dev->gadget.dev);
 
        pci_set_drvdata(pdev, NULL);
        dev->regs = NULL;
@@ -1774,7 +1776,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (!pdev->irq) {
                printk(KERN_ERR "Check PCI %s IRQ setup!\n", pci_name(pdev));
                retval = -ENODEV;
-               goto done;
+               goto err;
        }
 
        /* alloc, and start init */
@@ -1782,7 +1784,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (dev == NULL){
                pr_debug("enomem %s\n", pci_name(pdev));
                retval = -ENOMEM;
-               goto done;
+               goto err;
        }
 
        spin_lock_init(&dev->lock);
@@ -1800,7 +1802,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        retval = pci_enable_device(pdev);
        if (retval < 0) {
                DBG(dev, "can't enable, %d\n", retval);
-               goto done;
+               goto err;
        }
        dev->enabled = 1;
 
@@ -1809,7 +1811,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (!request_mem_region(resource, len, driver_name)) {
                DBG(dev, "controller already in use\n");
                retval = -EBUSY;
-               goto done;
+               goto err;
        }
        dev->got_region = 1;
 
@@ -1817,7 +1819,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (base == NULL) {
                DBG(dev, "can't map memory\n");
                retval = -EFAULT;
-               goto done;
+               goto err;
        }
        dev->regs = (struct goku_udc_regs __iomem *) base;
 
@@ -1833,7 +1835,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                        driver_name, dev) != 0) {
                DBG(dev, "request interrupt %d failed\n", pdev->irq);
                retval = -EBUSY;
-               goto done;
+               goto err;
        }
        dev->got_irq = 1;
        if (use_dma)
@@ -1844,13 +1846,16 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev);
 #endif
 
-       /* done */
        the_controller = dev;
        retval = device_register(&dev->gadget.dev);
-       if (retval == 0)
-               return 0;
+       if (retval) {
+               put_device(&dev->gadget.dev);
+               goto err;
+       }
+       dev->registered = 1;
+       return 0;
 
-done:
+err:
        if (dev)
                goku_remove (pdev);
        return retval;
index 735495bf8411b81c5ee7ff1ab4a38177dadd78dc..2523e54097bd3529dce275c9a8ef1f0cebff57c9 100644 (file)
@@ -127,7 +127,7 @@ static struct usb_gadget_strings *dev_strings[] = {
 
 /****************************** Configurations ******************************/
 
-static int __ref do_config(struct usb_configuration *c)
+static int __init do_config(struct usb_configuration *c)
 {
        struct hidg_func_node *e;
        int func = 0, status = 0;
@@ -148,7 +148,6 @@ static int __ref do_config(struct usb_configuration *c)
 
 static struct usb_configuration config_driver = {
        .label                  = "HID Gadget",
-       .bind                   = do_config,
        .bConfigurationValue    = 1,
        /* .iConfiguration = DYNAMIC */
        .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
@@ -156,7 +155,7 @@ static struct usb_configuration config_driver = {
 
 /****************************** Gadget Bind ******************************/
 
-static int __ref hid_bind(struct usb_composite_dev *cdev)
+static int __init hid_bind(struct usb_composite_dev *cdev)
 {
        struct usb_gadget *gadget = cdev->gadget;
        struct list_head *tmp;
@@ -201,7 +200,7 @@ static int __ref hid_bind(struct usb_composite_dev *cdev)
        device_desc.iProduct = status;
 
        /* register our configuration */
-       status = usb_add_config(cdev, &config_driver);
+       status = usb_add_config(cdev, &config_driver, do_config);
        if (status < 0)
                return status;
 
@@ -256,7 +255,6 @@ static struct usb_composite_driver hidg_driver = {
        .name           = "g_hid",
        .dev            = &device_desc,
        .strings        = dev_strings,
-       .bind           = hid_bind,
        .unbind         = __exit_p(hid_unbind),
 };
 
@@ -282,7 +280,7 @@ static int __init hidg_init(void)
        if (status < 0)
                return status;
 
-       status = usb_composite_register(&hidg_driver);
+       status = usb_composite_probe(&hidg_driver, hid_bind);
        if (status < 0)
                platform_driver_unregister(&hidg_plat_driver);
 
index e743122fcd93e0f74ec23f8b1f0efa050d9a5f10..ed0266462c5736628f40a7570566b583f6dd7d81 100644 (file)
@@ -1319,14 +1319,15 @@ static struct imx_udc_struct controller = {
  * USB gadged driver functions
  *******************************************************************************
  */
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *))
 {
        struct imx_udc_struct *imx_usb = &controller;
        int retval;
 
        if (!driver
                || driver->speed < USB_SPEED_FULL
-               || !driver->bind
+               || !bind
                || !driver->disconnect
                || !driver->setup)
                        return -EINVAL;
@@ -1342,7 +1343,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
        retval = device_add(&imx_usb->gadget.dev);
        if (retval)
                goto fail;
-       retval = driver->bind(&imx_usb->gadget);
+       retval = bind(&imx_usb->gadget);
        if (retval) {
                D_ERR(imx_usb->dev, "<%s> bind to driver %s --> error %d\n",
                        __func__, driver->driver.name, retval);
@@ -1362,7 +1363,7 @@ fail:
        imx_usb->gadget.dev.driver = NULL;
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
index 3f1d771c8be584c28c54d356e8238de954626c32..d1d72d946b04d465014b593e7cd6c39604a57f4e 100644 (file)
@@ -1774,7 +1774,6 @@ static struct usb_gadget_driver gadgetfs_driver = {
        .speed          = USB_SPEED_FULL,
 #endif
        .function       = (char *) driver_desc,
-       .bind           = gadgetfs_bind,
        .unbind         = gadgetfs_unbind,
        .setup          = gadgetfs_setup,
        .disconnect     = gadgetfs_disconnect,
@@ -1797,7 +1796,6 @@ static int gadgetfs_probe (struct usb_gadget *gadget)
 
 static struct usb_gadget_driver probe_driver = {
        .speed          = USB_SPEED_HIGH,
-       .bind           = gadgetfs_probe,
        .unbind         = gadgetfs_nop,
        .setup          = (void *)gadgetfs_nop,
        .disconnect     = gadgetfs_nop,
@@ -1907,7 +1905,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
 
        /* triggers gadgetfs_bind(); then we can enumerate. */
        spin_unlock_irq (&dev->lock);
-       value = usb_gadget_register_driver (&gadgetfs_driver);
+       value = usb_gadget_probe_driver(&gadgetfs_driver, gadgetfs_bind);
        if (value != 0) {
                kfree (dev->buf);
                dev->buf = NULL;
@@ -2046,7 +2044,7 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent)
                return -ESRCH;
 
        /* fake probe to determine $CHIP */
-       (void) usb_gadget_register_driver (&probe_driver);
+       (void) usb_gadget_probe_driver(&probe_driver, gadgetfs_probe);
        if (!CHIP)
                return -ENODEV;
 
index c2d2a201f84bc65759cbec099b7daf63a8b925bc..b8ec954c06926a4c4a6e02d5ff7913f2315d35ba 100644 (file)
@@ -19,7 +19,7 @@
 
 
 /* #undef      DEBUG */
-/* #undef      VERBOSE */
+/* #undef      VERBOSE_DEBUG */
 
 #if defined(CONFIG_USB_LANGWELL_OTG)
 #define        OTG_TRANSCEIVER
@@ -77,141 +77,110 @@ langwell_ep0_desc = {
 /*-------------------------------------------------------------------------*/
 /* debugging */
 
-#ifdef DEBUG
-#define        DBG(dev, fmt, args...) \
-       pr_debug("%s %s: " fmt , driver_name, \
-                       pci_name(dev->pdev), ## args)
-#else
-#define        DBG(dev, fmt, args...) \
-       do { } while (0)
-#endif /* DEBUG */
-
-
-#ifdef VERBOSE
-#define        VDBG DBG
-#else
-#define        VDBG(dev, fmt, args...) \
-       do { } while (0)
-#endif /* VERBOSE */
-
-
-#define        ERROR(dev, fmt, args...) \
-       pr_err("%s %s: " fmt , driver_name, \
-                       pci_name(dev->pdev), ## args)
-
-#define        WARNING(dev, fmt, args...) \
-       pr_warning("%s %s: " fmt , driver_name, \
-                       pci_name(dev->pdev), ## args)
-
-#define        INFO(dev, fmt, args...) \
-       pr_info("%s %s: " fmt , driver_name, \
-                       pci_name(dev->pdev), ## args)
-
-
-#ifdef VERBOSE
+#ifdef VERBOSE_DEBUG
 static inline void print_all_registers(struct langwell_udc *dev)
 {
        int     i;
 
        /* Capability Registers */
-       printk(KERN_DEBUG "Capability Registers (offset: "
-                       "0x%04x, length: 0x%08x)\n",
-                       CAP_REG_OFFSET,
-                       (u32)sizeof(struct langwell_cap_regs));
-       printk(KERN_DEBUG "caplength=0x%02x\n",
+       dev_dbg(&dev->pdev->dev,
+               "Capability Registers (offset: 0x%04x, length: 0x%08x)\n",
+               CAP_REG_OFFSET, (u32)sizeof(struct langwell_cap_regs));
+       dev_dbg(&dev->pdev->dev, "caplength=0x%02x\n",
                        readb(&dev->cap_regs->caplength));
-       printk(KERN_DEBUG "hciversion=0x%04x\n",
+       dev_dbg(&dev->pdev->dev, "hciversion=0x%04x\n",
                        readw(&dev->cap_regs->hciversion));
-       printk(KERN_DEBUG "hcsparams=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "hcsparams=0x%08x\n",
                        readl(&dev->cap_regs->hcsparams));
-       printk(KERN_DEBUG "hccparams=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "hccparams=0x%08x\n",
                        readl(&dev->cap_regs->hccparams));
-       printk(KERN_DEBUG "dciversion=0x%04x\n",
+       dev_dbg(&dev->pdev->dev, "dciversion=0x%04x\n",
                        readw(&dev->cap_regs->dciversion));
-       printk(KERN_DEBUG "dccparams=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "dccparams=0x%08x\n",
                        readl(&dev->cap_regs->dccparams));
 
        /* Operational Registers */
-       printk(KERN_DEBUG "Operational Registers (offset: "
-                       "0x%04x, length: 0x%08x)\n",
-                       OP_REG_OFFSET,
-                       (u32)sizeof(struct langwell_op_regs));
-       printk(KERN_DEBUG "extsts=0x%08x\n",
+       dev_dbg(&dev->pdev->dev,
+               "Operational Registers (offset: 0x%04x, length: 0x%08x)\n",
+               OP_REG_OFFSET, (u32)sizeof(struct langwell_op_regs));
+       dev_dbg(&dev->pdev->dev, "extsts=0x%08x\n",
                        readl(&dev->op_regs->extsts));
-       printk(KERN_DEBUG "extintr=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "extintr=0x%08x\n",
                        readl(&dev->op_regs->extintr));
-       printk(KERN_DEBUG "usbcmd=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "usbcmd=0x%08x\n",
                        readl(&dev->op_regs->usbcmd));
-       printk(KERN_DEBUG "usbsts=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "usbsts=0x%08x\n",
                        readl(&dev->op_regs->usbsts));
-       printk(KERN_DEBUG "usbintr=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "usbintr=0x%08x\n",
                        readl(&dev->op_regs->usbintr));
-       printk(KERN_DEBUG "frindex=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "frindex=0x%08x\n",
                        readl(&dev->op_regs->frindex));
-       printk(KERN_DEBUG "ctrldssegment=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "ctrldssegment=0x%08x\n",
                        readl(&dev->op_regs->ctrldssegment));
-       printk(KERN_DEBUG "deviceaddr=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "deviceaddr=0x%08x\n",
                        readl(&dev->op_regs->deviceaddr));
-       printk(KERN_DEBUG "endpointlistaddr=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "endpointlistaddr=0x%08x\n",
                        readl(&dev->op_regs->endpointlistaddr));
-       printk(KERN_DEBUG "ttctrl=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "ttctrl=0x%08x\n",
                        readl(&dev->op_regs->ttctrl));
-       printk(KERN_DEBUG "burstsize=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "burstsize=0x%08x\n",
                        readl(&dev->op_regs->burstsize));
-       printk(KERN_DEBUG "txfilltuning=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "txfilltuning=0x%08x\n",
                        readl(&dev->op_regs->txfilltuning));
-       printk(KERN_DEBUG "txttfilltuning=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "txttfilltuning=0x%08x\n",
                        readl(&dev->op_regs->txttfilltuning));
-       printk(KERN_DEBUG "ic_usb=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "ic_usb=0x%08x\n",
                        readl(&dev->op_regs->ic_usb));
-       printk(KERN_DEBUG "ulpi_viewport=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "ulpi_viewport=0x%08x\n",
                        readl(&dev->op_regs->ulpi_viewport));
-       printk(KERN_DEBUG "configflag=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "configflag=0x%08x\n",
                        readl(&dev->op_regs->configflag));
-       printk(KERN_DEBUG "portsc1=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "portsc1=0x%08x\n",
                        readl(&dev->op_regs->portsc1));
-       printk(KERN_DEBUG "devlc=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "devlc=0x%08x\n",
                        readl(&dev->op_regs->devlc));
-       printk(KERN_DEBUG "otgsc=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "otgsc=0x%08x\n",
                        readl(&dev->op_regs->otgsc));
-       printk(KERN_DEBUG "usbmode=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "usbmode=0x%08x\n",
                        readl(&dev->op_regs->usbmode));
-       printk(KERN_DEBUG "endptnak=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "endptnak=0x%08x\n",
                        readl(&dev->op_regs->endptnak));
-       printk(KERN_DEBUG "endptnaken=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "endptnaken=0x%08x\n",
                        readl(&dev->op_regs->endptnaken));
-       printk(KERN_DEBUG "endptsetupstat=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "endptsetupstat=0x%08x\n",
                        readl(&dev->op_regs->endptsetupstat));
-       printk(KERN_DEBUG "endptprime=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "endptprime=0x%08x\n",
                        readl(&dev->op_regs->endptprime));
-       printk(KERN_DEBUG "endptflush=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "endptflush=0x%08x\n",
                        readl(&dev->op_regs->endptflush));
-       printk(KERN_DEBUG "endptstat=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "endptstat=0x%08x\n",
                        readl(&dev->op_regs->endptstat));
-       printk(KERN_DEBUG "endptcomplete=0x%08x\n",
+       dev_dbg(&dev->pdev->dev, "endptcomplete=0x%08x\n",
                        readl(&dev->op_regs->endptcomplete));
 
        for (i = 0; i < dev->ep_max / 2; i++) {
-               printk(KERN_DEBUG "endptctrl[%d]=0x%08x\n",
+               dev_dbg(&dev->pdev->dev, "endptctrl[%d]=0x%08x\n",
                                i, readl(&dev->op_regs->endptctrl[i]));
        }
 }
-#endif /* VERBOSE */
+#else
+
+#define        print_all_registers(dev)        do { } while (0)
+
+#endif /* VERBOSE_DEBUG */
 
 
 /*-------------------------------------------------------------------------*/
 
-#define        DIR_STRING(bAddress)    (((bAddress) & USB_DIR_IN) ? "in" : "out")
+#define        is_in(ep)       (((ep)->ep_num == 0) ? ((ep)->dev->ep0_dir ==   \
+                       USB_DIR_IN) : (usb_endpoint_dir_in((ep)->desc)))
 
-#define is_in(ep)      (((ep)->ep_num == 0) ? ((ep)->dev->ep0_dir == \
-                       USB_DIR_IN) : ((ep)->desc->bEndpointAddress \
-                       & USB_DIR_IN) == USB_DIR_IN)
+#define        DIR_STRING(ep)  (is_in(ep) ? "in" : "out")
 
 
-#ifdef DEBUG
-static char *type_string(u8 bmAttributes)
+static char *type_string(const struct usb_endpoint_descriptor *desc)
 {
-       switch ((bmAttributes) & USB_ENDPOINT_XFERTYPE_MASK) {
+       switch (usb_endpoint_type(desc)) {
        case USB_ENDPOINT_XFER_BULK:
                return "bulk";
        case USB_ENDPOINT_XFER_ISOC:
@@ -222,7 +191,6 @@ static char *type_string(u8 bmAttributes)
 
        return "control";
 }
-#endif
 
 
 /* configure endpoint control registers */
@@ -233,7 +201,7 @@ static void ep_reset(struct langwell_ep *ep, unsigned char ep_num,
        u32                     endptctrl;
 
        dev = ep->dev;
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        endptctrl = readl(&dev->op_regs->endptctrl[ep_num]);
        if (is_in) {    /* TX */
@@ -250,7 +218,7 @@ static void ep_reset(struct langwell_ep *ep, unsigned char ep_num,
 
        writel(endptctrl, &dev->op_regs->endptctrl[ep_num]);
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
 
@@ -260,7 +228,7 @@ static void ep0_reset(struct langwell_udc *dev)
        struct langwell_ep      *ep;
        int                     i;
 
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        /* ep0 in and out */
        for (i = 0; i < 2; i++) {
@@ -274,17 +242,18 @@ static void ep0_reset(struct langwell_udc *dev)
                ep->dqh->dqh_ios = 1;
                ep->dqh->dqh_mpl = EP0_MAX_PKT_SIZE;
 
-               /* FIXME: enable ep0-in HW zero length termination select */
+               /* enable ep0-in HW zero length termination select */
                if (is_in(ep))
                        ep->dqh->dqh_zlt = 0;
                ep->dqh->dqh_mult = 0;
 
+               ep->dqh->dtd_next = DTD_TERM;
+
                /* configure ep0 control registers */
                ep_reset(&dev->ep[0], 0, i, USB_ENDPOINT_XFER_CONTROL);
        }
 
-       VDBG(dev, "<--- %s()\n", __func__);
-       return;
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
 
@@ -300,12 +269,12 @@ static int langwell_ep_enable(struct usb_ep *_ep,
        struct langwell_ep      *ep;
        u16                     max = 0;
        unsigned long           flags;
-       int                     retval = 0;
+       int                     i, retval = 0;
        unsigned char           zlt, ios = 0, mult = 0;
 
        ep = container_of(_ep, struct langwell_ep, ep);
        dev = ep->dev;
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        if (!_ep || !desc || ep->desc
                        || desc->bDescriptorType != USB_DT_ENDPOINT)
@@ -326,7 +295,7 @@ static int langwell_ep_enable(struct usb_ep *_ep,
         * sanity check type, direction, address, and then
         * initialize the endpoint capabilities fields in dQH
         */
-       switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+       switch (usb_endpoint_type(desc)) {
        case USB_ENDPOINT_XFER_CONTROL:
                ios = 1;
                break;
@@ -386,33 +355,36 @@ static int langwell_ep_enable(struct usb_ep *_ep,
 
        spin_lock_irqsave(&dev->lock, flags);
 
-       /* configure endpoint capabilities in dQH */
-       ep->dqh->dqh_ios = ios;
-       ep->dqh->dqh_mpl = cpu_to_le16(max);
-       ep->dqh->dqh_zlt = zlt;
-       ep->dqh->dqh_mult = mult;
-
        ep->ep.maxpacket = max;
        ep->desc = desc;
        ep->stopped = 0;
-       ep->ep_num = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+       ep->ep_num = usb_endpoint_num(desc);
 
        /* ep_type */
-       ep->ep_type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+       ep->ep_type = usb_endpoint_type(desc);
 
        /* configure endpoint control registers */
        ep_reset(ep, ep->ep_num, is_in(ep), ep->ep_type);
 
-       DBG(dev, "enabled %s (ep%d%s-%s), max %04x\n",
+       /* configure endpoint capabilities in dQH */
+       i = ep->ep_num * 2 + is_in(ep);
+       ep->dqh = &dev->ep_dqh[i];
+       ep->dqh->dqh_ios = ios;
+       ep->dqh->dqh_mpl = cpu_to_le16(max);
+       ep->dqh->dqh_zlt = zlt;
+       ep->dqh->dqh_mult = mult;
+       ep->dqh->dtd_next = DTD_TERM;
+
+       dev_dbg(&dev->pdev->dev, "enabled %s (ep%d%s-%s), max %04x\n",
                        _ep->name,
                        ep->ep_num,
-                       DIR_STRING(desc->bEndpointAddress),
-                       type_string(desc->bmAttributes),
+                       DIR_STRING(ep),
+                       type_string(desc),
                        max);
 
        spin_unlock_irqrestore(&dev->lock, flags);
 done:
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return retval;
 }
 
@@ -428,7 +400,7 @@ static void done(struct langwell_ep *ep, struct langwell_request *req,
        struct langwell_dtd     *curr_dtd, *next_dtd;
        int                     i;
 
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        /* remove the req from ep->queue */
        list_del_init(&req->queue);
@@ -448,7 +420,8 @@ static void done(struct langwell_ep *ep, struct langwell_request *req,
        }
 
        if (req->mapped) {
-               dma_unmap_single(&dev->pdev->dev, req->req.dma, req->req.length,
+               dma_unmap_single(&dev->pdev->dev,
+                       req->req.dma, req->req.length,
                        is_in(ep) ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
                req->req.dma = DMA_ADDR_INVALID;
                req->mapped = 0;
@@ -458,9 +431,10 @@ static void done(struct langwell_ep *ep, struct langwell_request *req,
                                is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
 
        if (status != -ESHUTDOWN)
-               DBG(dev, "complete %s, req %p, stat %d, len %u/%u\n",
-                       ep->ep.name, &req->req, status,
-                       req->req.actual, req->req.length);
+               dev_dbg(&dev->pdev->dev,
+                               "complete %s, req %p, stat %d, len %u/%u\n",
+                               ep->ep.name, &req->req, status,
+                               req->req.actual, req->req.length);
 
        /* don't modify queue heads during completion callback */
        ep->stopped = 1;
@@ -473,7 +447,7 @@ static void done(struct langwell_ep *ep, struct langwell_request *req,
        spin_lock(&dev->lock);
        ep->stopped = stopped;
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
 
@@ -511,7 +485,7 @@ static int langwell_ep_disable(struct usb_ep *_ep)
 
        ep = container_of(_ep, struct langwell_ep, ep);
        dev = ep->dev;
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        if (!_ep || !ep->desc)
                return -EINVAL;
@@ -535,8 +509,8 @@ static int langwell_ep_disable(struct usb_ep *_ep)
 
        spin_unlock_irqrestore(&dev->lock, flags);
 
-       DBG(dev, "disabled %s\n", _ep->name);
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_dbg(&dev->pdev->dev, "disabled %s\n", _ep->name);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 
        return 0;
 }
@@ -555,7 +529,7 @@ static struct usb_request *langwell_alloc_request(struct usb_ep *_ep,
 
        ep = container_of(_ep, struct langwell_ep, ep);
        dev = ep->dev;
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        req = kzalloc(sizeof(*req), gfp_flags);
        if (!req)
@@ -564,8 +538,8 @@ static struct usb_request *langwell_alloc_request(struct usb_ep *_ep,
        req->req.dma = DMA_ADDR_INVALID;
        INIT_LIST_HEAD(&req->queue);
 
-       VDBG(dev, "alloc request for %s\n", _ep->name);
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "alloc request for %s\n", _ep->name);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return &req->req;
 }
 
@@ -580,7 +554,7 @@ static void langwell_free_request(struct usb_ep *_ep,
 
        ep = container_of(_ep, struct langwell_ep, ep);
        dev = ep->dev;
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        if (!_ep || !_req)
                return;
@@ -591,8 +565,8 @@ static void langwell_free_request(struct usb_ep *_ep,
        if (_req)
                kfree(req);
 
-       VDBG(dev, "free request for %s\n", _ep->name);
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "free request for %s\n", _ep->name);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
 
@@ -608,23 +582,24 @@ static int queue_dtd(struct langwell_ep *ep, struct langwell_request *req)
        struct langwell_udc     *dev;
 
        dev = ep->dev;
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        i = ep->ep_num * 2 + is_in(ep);
        dqh = &dev->ep_dqh[i];
 
        if (ep->ep_num)
-               VDBG(dev, "%s\n", ep->name);
+               dev_vdbg(&dev->pdev->dev, "%s\n", ep->name);
        else
                /* ep0 */
-               VDBG(dev, "%s-%s\n", ep->name, is_in(ep) ? "in" : "out");
+               dev_vdbg(&dev->pdev->dev, "%s-%s\n", ep->name, DIR_STRING(ep));
 
-       VDBG(dev, "ep_dqh[%d] addr: 0x%08x\n", i, (u32)&(dev->ep_dqh[i]));
+       dev_vdbg(&dev->pdev->dev, "ep_dqh[%d] addr: 0x%08x\n",
+                       i, (u32)&(dev->ep_dqh[i]));
 
        bit_mask = is_in(ep) ?
                (1 << (ep->ep_num + 16)) : (1 << (ep->ep_num));
 
-       VDBG(dev, "bit_mask = 0x%08x\n", bit_mask);
+       dev_vdbg(&dev->pdev->dev, "bit_mask = 0x%08x\n", bit_mask);
 
        /* check if the pipe is empty */
        if (!(list_empty(&ep->queue))) {
@@ -665,14 +640,17 @@ static int queue_dtd(struct langwell_ep *ep, struct langwell_request *req)
        /* clear active and halt bit */
        dtd_status = (u8) ~(DTD_STS_ACTIVE | DTD_STS_HALTED);
        dqh->dtd_status &= dtd_status;
-       VDBG(dev, "dqh->dtd_status = 0x%x\n", dqh->dtd_status);
+       dev_vdbg(&dev->pdev->dev, "dqh->dtd_status = 0x%x\n", dqh->dtd_status);
+
+       /* ensure that updates to the dQH will occure before priming */
+       wmb();
 
        /* write 1 to endptprime register to PRIME endpoint */
        bit_mask = is_in(ep) ? (1 << (ep->ep_num + 16)) : (1 << ep->ep_num);
-       VDBG(dev, "endprime bit_mask = 0x%08x\n", bit_mask);
+       dev_vdbg(&dev->pdev->dev, "endprime bit_mask = 0x%08x\n", bit_mask);
        writel(bit_mask, &dev->op_regs->endptprime);
 out:
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return 0;
 }
 
@@ -687,7 +665,7 @@ static struct langwell_dtd *build_dtd(struct langwell_request *req,
        int                     i;
 
        dev = req->ep->dev;
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        /* the maximum transfer length, up to 16k bytes */
        *length = min(req->req.length - req->req.actual,
@@ -708,7 +686,7 @@ static struct langwell_dtd *build_dtd(struct langwell_request *req,
 
        /* fill in total bytes with transfer size */
        dtd->dtd_total = cpu_to_le16(*length);
-       VDBG(dev, "dtd->dtd_total = %d\n", dtd->dtd_total);
+       dev_vdbg(&dev->pdev->dev, "dtd->dtd_total = %d\n", dtd->dtd_total);
 
        /* set is_last flag if req->req.zero is set or not */
        if (req->req.zero) {
@@ -722,7 +700,7 @@ static struct langwell_dtd *build_dtd(struct langwell_request *req,
                *is_last = 0;
 
        if (*is_last == 0)
-               VDBG(dev, "multi-dtd request!\n");
+               dev_vdbg(&dev->pdev->dev, "multi-dtd request!\n");
 
        /* set interrupt on complete bit for the last dTD */
        if (*is_last && !req->req.no_interrupt)
@@ -733,10 +711,12 @@ static struct langwell_dtd *build_dtd(struct langwell_request *req,
 
        /* set the active bit of status field to 1 */
        dtd->dtd_status = DTD_STS_ACTIVE;
-       VDBG(dev, "dtd->dtd_status = 0x%02x\n", dtd->dtd_status);
+       dev_vdbg(&dev->pdev->dev, "dtd->dtd_status = 0x%02x\n",
+                       dtd->dtd_status);
 
-       VDBG(dev, "length = %d, dma addr= 0x%08x\n", *length, (int)*dma);
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "length = %d, dma addr= 0x%08x\n",
+                       *length, (int)*dma);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return dtd;
 }
 
@@ -751,7 +731,7 @@ static int req_to_dtd(struct langwell_request *req)
        dma_addr_t              dma;
 
        dev = req->ep->dev;
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
        do {
                dtd = build_dtd(req, &count, &dma, &is_last);
                if (dtd == NULL)
@@ -773,7 +753,7 @@ static int req_to_dtd(struct langwell_request *req)
 
        req->tail = dtd;
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return 0;
 }
 
@@ -803,9 +783,9 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
 
        dev = ep->dev;
        req->ep = ep;
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
-       if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
+       if (usb_endpoint_xfer_isoc(ep->desc)) {
                if (req->req.length > ep->ep.maxpacket)
                        return -EMSGSIZE;
                is_iso = 1;
@@ -818,7 +798,7 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
        if (_req->dma == DMA_ADDR_INVALID) {
                /* WORKAROUND: WARN_ON(size == 0) */
                if (_req->length == 0) {
-                       VDBG(dev, "req->length: 0->1\n");
+                       dev_vdbg(&dev->pdev->dev, "req->length: 0->1\n");
                        zlflag = 1;
                        _req->length++;
                }
@@ -827,24 +807,25 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
                                _req->buf, _req->length,
                                is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
                if (zlflag && (_req->length == 1)) {
-                       VDBG(dev, "req->length: 1->0\n");
+                       dev_vdbg(&dev->pdev->dev, "req->length: 1->0\n");
                        zlflag = 0;
                        _req->length = 0;
                }
 
                req->mapped = 1;
-               VDBG(dev, "req->mapped = 1\n");
+               dev_vdbg(&dev->pdev->dev, "req->mapped = 1\n");
        } else {
                dma_sync_single_for_device(&dev->pdev->dev,
                                _req->dma, _req->length,
                                is_in(ep) ?  DMA_TO_DEVICE : DMA_FROM_DEVICE);
                req->mapped = 0;
-               VDBG(dev, "req->mapped = 0\n");
+               dev_vdbg(&dev->pdev->dev, "req->mapped = 0\n");
        }
 
-       DBG(dev, "%s queue req %p, len %u, buf %p, dma 0x%08llx\n",
-           _ep->name,
-           _req, _req->length, _req->buf, (unsigned long long)_req->dma);
+       dev_dbg(&dev->pdev->dev,
+                       "%s queue req %p, len %u, buf %p, dma 0x%08x\n",
+                       _ep->name,
+                       _req, _req->length, _req->buf, (int)_req->dma);
 
        _req->status = -EINPROGRESS;
        _req->actual = 0;
@@ -866,12 +847,12 @@ static int langwell_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
 
        if (likely(req != NULL)) {
                list_add_tail(&req->queue, &ep->queue);
-               VDBG(dev, "list_add_tail() \n");
+               dev_vdbg(&dev->pdev->dev, "list_add_tail()\n");
        }
 
        spin_unlock_irqrestore(&dev->lock, flags);
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return 0;
 }
 
@@ -888,7 +869,7 @@ static int langwell_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
 
        ep = container_of(_ep, struct langwell_ep, ep);
        dev = ep->dev;
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        if (!_ep || !ep->desc || !_req)
                return -EINVAL;
@@ -924,7 +905,7 @@ static int langwell_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
 
        /* queue head may be partially complete. */
        if (ep->queue.next == &req->queue) {
-               DBG(dev, "unlink (%s) dma\n", _ep->name);
+               dev_dbg(&dev->pdev->dev, "unlink (%s) dma\n", _ep->name);
                _req->status = -ECONNRESET;
                langwell_ep_fifo_flush(&ep->ep);
 
@@ -963,7 +944,7 @@ done:
        ep->stopped = stopped;
        spin_unlock_irqrestore(&dev->lock, flags);
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return retval;
 }
 
@@ -976,7 +957,7 @@ static void ep_set_halt(struct langwell_ep *ep, int value)
        u32                     endptctrl = 0;
        int                     ep_num;
        struct langwell_udc     *dev = ep->dev;
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        ep_num = ep->ep_num;
        endptctrl = readl(&dev->op_regs->endptctrl[ep_num]);
@@ -1001,7 +982,7 @@ static void ep_set_halt(struct langwell_ep *ep, int value)
 
        writel(endptctrl, &dev->op_regs->endptctrl[ep_num]);
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
 
@@ -1016,7 +997,7 @@ static int langwell_ep_set_halt(struct usb_ep *_ep, int value)
        ep = container_of(_ep, struct langwell_ep, ep);
        dev = ep->dev;
 
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        if (!_ep || !ep->desc)
                return -EINVAL;
@@ -1024,8 +1005,7 @@ static int langwell_ep_set_halt(struct usb_ep *_ep, int value)
        if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
                return -ESHUTDOWN;
 
-       if (ep->desc && (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
-                       == USB_ENDPOINT_XFER_ISOC)
+       if (usb_endpoint_xfer_isoc(ep->desc))
                return  -EOPNOTSUPP;
 
        spin_lock_irqsave(&dev->lock, flags);
@@ -1036,7 +1016,7 @@ static int langwell_ep_set_halt(struct usb_ep *_ep, int value)
         */
        if (!list_empty(&ep->queue) && is_in(ep) && value) {
                /* IN endpoint FIFO holds bytes */
-               DBG(dev, "%s FIFO holds bytes\n", _ep->name);
+               dev_dbg(&dev->pdev->dev, "%s FIFO holds bytes\n", _ep->name);
                retval = -EAGAIN;
                goto done;
        }
@@ -1050,8 +1030,9 @@ static int langwell_ep_set_halt(struct usb_ep *_ep, int value)
        }
 done:
        spin_unlock_irqrestore(&dev->lock, flags);
-       DBG(dev, "%s %s halt\n", _ep->name, value ? "set" : "clear");
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_dbg(&dev->pdev->dev, "%s %s halt\n",
+                       _ep->name, value ? "set" : "clear");
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return retval;
 }
 
@@ -1065,12 +1046,12 @@ static int langwell_ep_set_wedge(struct usb_ep *_ep)
        ep = container_of(_ep, struct langwell_ep, ep);
        dev = ep->dev;
 
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        if (!_ep || !ep->desc)
                return -EINVAL;
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return usb_ep_set_halt(_ep);
 }
 
@@ -1086,15 +1067,16 @@ static void langwell_ep_fifo_flush(struct usb_ep *_ep)
        ep = container_of(_ep, struct langwell_ep, ep);
        dev = ep->dev;
 
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        if (!_ep || !ep->desc) {
-               VDBG(dev, "ep or ep->desc is NULL\n");
-               VDBG(dev, "<--- %s()\n", __func__);
+               dev_vdbg(&dev->pdev->dev, "ep or ep->desc is NULL\n");
+               dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
                return;
        }
 
-       VDBG(dev, "%s-%s fifo flush\n", _ep->name, is_in(ep) ? "in" : "out");
+       dev_vdbg(&dev->pdev->dev, "%s-%s fifo flush\n",
+                       _ep->name, DIR_STRING(ep));
 
        /* flush endpoint buffer */
        if (ep->ep_num == 0)
@@ -1110,14 +1092,14 @@ static void langwell_ep_fifo_flush(struct usb_ep *_ep)
                writel(flush_bit, &dev->op_regs->endptflush);
                while (readl(&dev->op_regs->endptflush)) {
                        if (time_after(jiffies, timeout)) {
-                               ERROR(dev, "ep flush timeout\n");
+                               dev_err(&dev->pdev->dev, "ep flush timeout\n");
                                goto done;
                        }
                        cpu_relax();
                }
        } while (readl(&dev->op_regs->endptstat) & flush_bit);
 done:
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
 
@@ -1167,31 +1149,59 @@ static int langwell_get_frame(struct usb_gadget *_gadget)
                return -ENODEV;
 
        dev = container_of(_gadget, struct langwell_udc, gadget);
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        retval = readl(&dev->op_regs->frindex) & FRINDEX_MASK;
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return retval;
 }
 
 
+/* enter or exit PHY low power state */
+static void langwell_phy_low_power(struct langwell_udc *dev, bool flag)
+{
+       u32             devlc;
+       u8              devlc_byte2;
+       dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
+
+       devlc = readl(&dev->op_regs->devlc);
+       dev_vdbg(&dev->pdev->dev, "devlc = 0x%08x\n", devlc);
+
+       if (flag)
+               devlc |= LPM_PHCD;
+       else
+               devlc &= ~LPM_PHCD;
+
+       /* FIXME: workaround for Langwell A1/A2/A3 sighting */
+       devlc_byte2 = (devlc >> 16) & 0xff;
+       writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
+
+       devlc = readl(&dev->op_regs->devlc);
+       dev_vdbg(&dev->pdev->dev,
+                       "%s PHY low power suspend, devlc = 0x%08x\n",
+                       flag ? "enter" : "exit", devlc);
+}
+
+
 /* tries to wake up the host connected to this gadget */
 static int langwell_wakeup(struct usb_gadget *_gadget)
 {
        struct langwell_udc     *dev;
-       u32                     portsc1, devlc;
-       unsigned long           flags;
+       u32                     portsc1;
+       unsigned long           flags;
 
        if (!_gadget)
                return 0;
 
        dev = container_of(_gadget, struct langwell_udc, gadget);
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
-       /* Remote Wakeup feature not enabled by host */
-       if (!dev->remote_wakeup)
+       /* remote wakeup feature not enabled by host */
+       if (!dev->remote_wakeup) {
+               dev_info(&dev->pdev->dev, "remote wakeup is disabled\n");
                return -ENOTSUPP;
+       }
 
        spin_lock_irqsave(&dev->lock, flags);
 
@@ -1201,27 +1211,23 @@ static int langwell_wakeup(struct usb_gadget *_gadget)
                return 0;
        }
 
-       /* LPM L1 to L0, remote wakeup */
-       if (dev->lpm && dev->lpm_state == LPM_L1) {
-               portsc1 |= PORTS_SLP;
-               writel(portsc1, &dev->op_regs->portsc1);
-       }
-
-       /* force port resume */
-       if (dev->usb_state == USB_STATE_SUSPENDED) {
-               portsc1 |= PORTS_FPR;
-               writel(portsc1, &dev->op_regs->portsc1);
-       }
+       /* LPM L1 to L0 or legacy remote wakeup */
+       if (dev->lpm && dev->lpm_state == LPM_L1)
+               dev_info(&dev->pdev->dev, "LPM L1 to L0 remote wakeup\n");
+       else
+               dev_info(&dev->pdev->dev, "device remote wakeup\n");
 
        /* exit PHY low power suspend */
-       devlc = readl(&dev->op_regs->devlc);
-       VDBG(dev, "devlc = 0x%08x\n", devlc);
-       devlc &= ~LPM_PHCD;
-       writel(devlc, &dev->op_regs->devlc);
+       if (dev->pdev->device != 0x0829)
+               langwell_phy_low_power(dev, 0);
+
+       /* force port resume */
+       portsc1 |= PORTS_FPR;
+       writel(portsc1, &dev->op_regs->portsc1);
 
        spin_unlock_irqrestore(&dev->lock, flags);
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return 0;
 }
 
@@ -1231,16 +1237,17 @@ static int langwell_vbus_session(struct usb_gadget *_gadget, int is_active)
 {
        struct langwell_udc     *dev;
        unsigned long           flags;
-       u32                     usbcmd;
+       u32                     usbcmd;
 
        if (!_gadget)
                return -ENODEV;
 
        dev = container_of(_gadget, struct langwell_udc, gadget);
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        spin_lock_irqsave(&dev->lock, flags);
-       VDBG(dev, "VBUS status: %s\n", is_active ? "on" : "off");
+       dev_vdbg(&dev->pdev->dev, "VBUS status: %s\n",
+                       is_active ? "on" : "off");
 
        dev->vbus_active = (is_active != 0);
        if (dev->driver && dev->softconnected && dev->vbus_active) {
@@ -1255,7 +1262,7 @@ static int langwell_vbus_session(struct usb_gadget *_gadget, int is_active)
 
        spin_unlock_irqrestore(&dev->lock, flags);
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return 0;
 }
 
@@ -1269,15 +1276,15 @@ static int langwell_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
                return -ENODEV;
 
        dev = container_of(_gadget, struct langwell_udc, gadget);
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        if (dev->transceiver) {
-               VDBG(dev, "otg_set_power\n");
-               VDBG(dev, "<--- %s()\n", __func__);
+               dev_vdbg(&dev->pdev->dev, "otg_set_power\n");
+               dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
                return otg_set_power(dev->transceiver, mA);
        }
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return -ENOTSUPP;
 }
 
@@ -1286,15 +1293,15 @@ static int langwell_vbus_draw(struct usb_gadget *_gadget, unsigned mA)
 static int langwell_pullup(struct usb_gadget *_gadget, int is_on)
 {
        struct langwell_udc     *dev;
-       u32                     usbcmd;
-       unsigned long           flags;
+       u32                     usbcmd;
+       unsigned long           flags;
 
        if (!_gadget)
                return -ENODEV;
 
        dev = container_of(_gadget, struct langwell_udc, gadget);
 
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        spin_lock_irqsave(&dev->lock, flags);
        dev->softconnected = (is_on != 0);
@@ -1310,7 +1317,7 @@ static int langwell_pullup(struct usb_gadget *_gadget, int is_on)
        }
        spin_unlock_irqrestore(&dev->lock, flags);
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return 0;
 }
 
@@ -1346,12 +1353,13 @@ static const struct usb_gadget_ops langwell_ops = {
 static int langwell_udc_reset(struct langwell_udc *dev)
 {
        u32             usbcmd, usbmode, devlc, endpointlistaddr;
+       u8              devlc_byte0, devlc_byte2;
        unsigned long   timeout;
 
        if (!dev)
                return -EINVAL;
 
-       DBG(dev, "---> %s()\n", __func__);
+       dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        /* set controller to stop state */
        usbcmd = readl(&dev->op_regs->usbcmd);
@@ -1367,7 +1375,7 @@ static int langwell_udc_reset(struct langwell_udc *dev)
        timeout = jiffies + RESET_TIMEOUT;
        while (readl(&dev->op_regs->usbcmd) & CMD_RST) {
                if (time_after(jiffies, timeout)) {
-                       ERROR(dev, "device reset timeout\n");
+                       dev_err(&dev->pdev->dev, "device reset timeout\n");
                        return -ETIMEDOUT;
                }
                cpu_relax();
@@ -1382,7 +1390,7 @@ static int langwell_udc_reset(struct langwell_udc *dev)
 
        writel(usbmode, &dev->op_regs->usbmode);
        usbmode = readl(&dev->op_regs->usbmode);
-       VDBG(dev, "usbmode=0x%08x\n", usbmode);
+       dev_vdbg(&dev->pdev->dev, "usbmode=0x%08x\n", usbmode);
 
        /* Write-Clear setup status */
        writel(0, &dev->op_regs->usbsts);
@@ -1390,9 +1398,17 @@ static int langwell_udc_reset(struct langwell_udc *dev)
        /* if support USB LPM, ACK all LPM token */
        if (dev->lpm) {
                devlc = readl(&dev->op_regs->devlc);
+               dev_vdbg(&dev->pdev->dev, "devlc = 0x%08x\n", devlc);
+               /* FIXME: workaround for Langwell A1/A2/A3 sighting */
                devlc &= ~LPM_STL;      /* don't STALL LPM token */
                devlc &= ~LPM_NYT_ACK;  /* ACK LPM token */
-               writel(devlc, &dev->op_regs->devlc);
+               devlc_byte0 = devlc & 0xff;
+               devlc_byte2 = (devlc >> 16) & 0xff;
+               writeb(devlc_byte0, (u8 *)&dev->op_regs->devlc);
+               writeb(devlc_byte2, (u8 *)&dev->op_regs->devlc + 2);
+               devlc = readl(&dev->op_regs->devlc);
+               dev_vdbg(&dev->pdev->dev,
+                               "ACK LPM token, devlc = 0x%08x\n", devlc);
        }
 
        /* fill endpointlistaddr register */
@@ -1400,10 +1416,11 @@ static int langwell_udc_reset(struct langwell_udc *dev)
        endpointlistaddr &= ENDPOINTLISTADDR_MASK;
        writel(endpointlistaddr, &dev->op_regs->endpointlistaddr);
 
-       VDBG(dev, "dQH base (vir: %p, phy: 0x%08x), endpointlistaddr=0x%08x\n",
-                       dev->ep_dqh, endpointlistaddr,
-                       readl(&dev->op_regs->endpointlistaddr));
-       DBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev,
+               "dQH base (vir: %p, phy: 0x%08x), endpointlistaddr=0x%08x\n",
+               dev->ep_dqh, endpointlistaddr,
+               readl(&dev->op_regs->endpointlistaddr));
+       dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return 0;
 }
 
@@ -1415,7 +1432,7 @@ static int eps_reinit(struct langwell_udc *dev)
        char                    name[14];
        int                     i;
 
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        /* initialize ep0 */
        ep = &dev->ep[0];
@@ -1449,11 +1466,9 @@ static int eps_reinit(struct langwell_udc *dev)
 
                INIT_LIST_HEAD(&ep->queue);
                list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list);
-
-               ep->dqh = &dev->ep_dqh[i];
        }
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return 0;
 }
 
@@ -1462,7 +1477,7 @@ static int eps_reinit(struct langwell_udc *dev)
 static void langwell_udc_start(struct langwell_udc *dev)
 {
        u32     usbintr, usbcmd;
-       DBG(dev, "---> %s()\n", __func__);
+       dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        /* enable interrupts */
        usbintr = INTR_ULPIE    /* ULPI */
@@ -1485,8 +1500,7 @@ static void langwell_udc_start(struct langwell_udc *dev)
        usbcmd |= CMD_RUNSTOP;
        writel(usbcmd, &dev->op_regs->usbcmd);
 
-       DBG(dev, "<--- %s()\n", __func__);
-       return;
+       dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
 
@@ -1495,7 +1509,7 @@ static void langwell_udc_stop(struct langwell_udc *dev)
 {
        u32     usbcmd;
 
-       DBG(dev, "---> %s()\n", __func__);
+       dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        /* disable all interrupts */
        writel(0, &dev->op_regs->usbintr);
@@ -1508,8 +1522,7 @@ static void langwell_udc_stop(struct langwell_udc *dev)
        usbcmd &= ~CMD_RUNSTOP;
        writel(usbcmd, &dev->op_regs->usbcmd);
 
-       DBG(dev, "<--- %s()\n", __func__);
-       return;
+       dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
 
@@ -1518,7 +1531,7 @@ static void stop_activity(struct langwell_udc *dev,
                struct usb_gadget_driver *driver)
 {
        struct langwell_ep      *ep;
-       DBG(dev, "---> %s()\n", __func__);
+       dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        nuke(&dev->ep[0], -ESHUTDOWN);
 
@@ -1533,7 +1546,7 @@ static void stop_activity(struct langwell_udc *dev,
                spin_lock(&dev->lock);
        }
 
-       DBG(dev, "<--- %s()\n", __func__);
+       dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
 
@@ -1659,13 +1672,15 @@ static ssize_t show_langwell_udc(struct device *_dev,
                "Over-current Change: %s\n"
                "Port Enable/Disable Change: %s\n"
                "Port Enabled/Disabled: %s\n"
-               "Current Connect Status: %s\n\n",
+               "Current Connect Status: %s\n"
+               "LPM Suspend Status: %s\n\n",
                (tmp_reg & PORTS_PR) ? "Reset" : "Not Reset",
                (tmp_reg & PORTS_SUSP) ? "Suspend " : "Not Suspend",
                (tmp_reg & PORTS_OCC) ? "Detected" : "No",
                (tmp_reg & PORTS_PEC) ? "Changed" : "Not Changed",
                (tmp_reg & PORTS_PE) ? "Enable" : "Not Correct",
-               (tmp_reg & PORTS_CCS) ?  "Attached" : "Not Attached");
+               (tmp_reg & PORTS_CCS) ?  "Attached" : "Not Attached",
+               (tmp_reg & PORTS_SLP) ? "LPM L1" : "LPM L0");
        size -= t;
        next += t;
 
@@ -1676,7 +1691,7 @@ static ssize_t show_langwell_udc(struct device *_dev,
                "Serial Transceiver : %d\n"
                "Port Speed: %s\n"
                "Port Force Full Speed Connenct: %s\n"
-               "PHY Low Power Suspend Clock Disable: %s\n"
+               "PHY Low Power Suspend Clock: %s\n"
                "BmAttributes: %d\n\n",
                LPM_PTS(tmp_reg),
                (tmp_reg & LPM_STS) ? 1 : 0,
@@ -1797,6 +1812,36 @@ static ssize_t show_langwell_udc(struct device *_dev,
 static DEVICE_ATTR(langwell_udc, S_IRUGO, show_langwell_udc, NULL);
 
 
+/* device "remote_wakeup" sysfs attribute file */
+static ssize_t store_remote_wakeup(struct device *_dev,
+               struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct langwell_udc     *dev = the_controller;
+       unsigned long           flags;
+       ssize_t                 rc = count;
+
+       if (count > 2)
+               return -EINVAL;
+
+       if (count > 0 && buf[count-1] == '\n')
+               ((char *) buf)[count-1] = 0;
+
+       if (buf[0] != '1')
+               return -EINVAL;
+
+       /* force remote wakeup enabled in case gadget driver doesn't support */
+       spin_lock_irqsave(&dev->lock, flags);
+       dev->remote_wakeup = 1;
+       dev->dev_status |= (1 << USB_DEVICE_REMOTE_WAKEUP);
+       spin_unlock_irqrestore(&dev->lock, flags);
+
+       langwell_wakeup(&dev->gadget);
+
+       return rc;
+}
+static DEVICE_ATTR(remote_wakeup, S_IWUSR, NULL, store_remote_wakeup);
+
+
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -1807,7 +1852,8 @@ static DEVICE_ATTR(langwell_udc, S_IRUGO, show_langwell_udc, NULL);
  * the driver might get unbound.
  */
 
-int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
+               int (*bind)(struct usb_gadget *))
 {
        struct langwell_udc     *dev = the_controller;
        unsigned long           flags;
@@ -1816,7 +1862,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
        if (!dev)
                return -ENODEV;
 
-       DBG(dev, "---> %s()\n", __func__);
+       dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        if (dev->driver)
                return -EBUSY;
@@ -1830,9 +1876,9 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 
        spin_unlock_irqrestore(&dev->lock, flags);
 
-       retval = driver->bind(&dev->gadget);
+       retval = bind(&dev->gadget);
        if (retval) {
-               DBG(dev, "bind to driver %s --> %d\n",
+               dev_dbg(&dev->pdev->dev, "bind to driver %s --> %d\n",
                                driver->driver.name, retval);
                dev->driver = NULL;
                dev->gadget.dev.driver = NULL;
@@ -1851,13 +1897,13 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
        if (dev->got_irq)
                langwell_udc_start(dev);
 
-       VDBG(dev, "After langwell_udc_start(), print all registers:\n");
-#ifdef VERBOSE
+       dev_vdbg(&dev->pdev->dev,
+                       "After langwell_udc_start(), print all registers:\n");
        print_all_registers(dev);
-#endif
 
-       INFO(dev, "register driver: %s\n", driver->driver.name);
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_info(&dev->pdev->dev, "register driver: %s\n",
+                       driver->driver.name);
+       dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return 0;
 
 err_unbind:
@@ -1865,10 +1911,10 @@ err_unbind:
        dev->gadget.dev.driver = NULL;
        dev->driver = NULL;
 
-       DBG(dev, "<--- %s()\n", __func__);
+       dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return retval;
 }
-EXPORT_SYMBOL(usb_gadget_register_driver);
+EXPORT_SYMBOL(usb_gadget_probe_driver);
 
 
 /* unregister gadget driver */
@@ -1880,11 +1926,15 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
        if (!dev)
                return -ENODEV;
 
-       DBG(dev, "---> %s()\n", __func__);
+       dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
-       if (unlikely(!driver || !driver->bind || !driver->unbind))
+       if (unlikely(!driver || !driver->unbind))
                return -EINVAL;
 
+       /* exit PHY low power suspend */
+       if (dev->pdev->device != 0x0829)
+               langwell_phy_low_power(dev, 0);
+
        /* unbind OTG transceiver */
        if (dev->transceiver)
                (void)otg_set_peripheral(dev->transceiver, 0);
@@ -1910,8 +1960,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 
        device_remove_file(&dev->pdev->dev, &dev_attr_function);
 
-       INFO(dev, "unregistered driver '%s'\n", driver->driver.name);
-       DBG(dev, "<--- %s()\n", __func__);
+       dev_info(&dev->pdev->dev, "unregistered driver '%s'\n",
+                       driver->driver.name);
+       dev_dbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return 0;
 }
 EXPORT_SYMBOL(usb_gadget_unregister_driver);
@@ -1930,7 +1981,7 @@ static void setup_tripwire(struct langwell_udc *dev)
        unsigned long           timeout;
        struct langwell_dqh     *dqh;
 
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        /* ep0 OUT dQH */
        dqh = &dev->ep_dqh[EP_DIR_OUT];
@@ -1943,7 +1994,7 @@ static void setup_tripwire(struct langwell_udc *dev)
        timeout = jiffies + SETUPSTAT_TIMEOUT;
        while (readl(&dev->op_regs->endptsetupstat)) {
                if (time_after(jiffies, timeout)) {
-                       ERROR(dev, "setup_tripwire timeout\n");
+                       dev_err(&dev->pdev->dev, "setup_tripwire timeout\n");
                        break;
                }
                cpu_relax();
@@ -1963,7 +2014,7 @@ static void setup_tripwire(struct langwell_udc *dev)
        usbcmd = readl(&dev->op_regs->usbcmd);
        writel(usbcmd & ~CMD_SUTW, &dev->op_regs->usbcmd);
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
 
@@ -1972,7 +2023,7 @@ static void ep0_stall(struct langwell_udc *dev)
 {
        u32     endptctrl;
 
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        /* set TX and RX to stall */
        endptctrl = readl(&dev->op_regs->endptctrl[0]);
@@ -1983,7 +2034,7 @@ static void ep0_stall(struct langwell_udc *dev)
        dev->ep0_state = WAIT_FOR_SETUP;
        dev->ep0_dir = USB_DIR_OUT;
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
 
@@ -1994,7 +2045,7 @@ static int prime_status_phase(struct langwell_udc *dev, int dir)
        struct langwell_ep      *ep;
        int                     status = 0;
 
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        if (dir == EP_DIR_IN)
                dev->ep0_dir = USB_DIR_IN;
@@ -2019,11 +2070,11 @@ static int prime_status_phase(struct langwell_udc *dev, int dir)
                return -ENOMEM;
 
        if (status)
-               ERROR(dev, "can't queue ep0 status request\n");
+               dev_err(&dev->pdev->dev, "can't queue ep0 status request\n");
 
        list_add_tail(&req->queue, &ep->queue);
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return status;
 }
 
@@ -2032,11 +2083,11 @@ static int prime_status_phase(struct langwell_udc *dev, int dir)
 static void set_address(struct langwell_udc *dev, u16 value,
                u16 index, u16 length)
 {
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        /* save the new address to device struct */
        dev->dev_addr = (u8) value;
-       VDBG(dev, "dev->dev_addr = %d\n", dev->dev_addr);
+       dev_vdbg(&dev->pdev->dev, "dev->dev_addr = %d\n", dev->dev_addr);
 
        /* update usb state */
        dev->usb_state = USB_STATE_ADDRESS;
@@ -2045,7 +2096,7 @@ static void set_address(struct langwell_udc *dev, u16 value,
        if (prime_status_phase(dev, EP_DIR_IN))
                ep0_stall(dev);
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
 
@@ -2054,7 +2105,7 @@ static struct langwell_ep *get_ep_by_windex(struct langwell_udc *dev,
                u16 wIndex)
 {
        struct langwell_ep              *ep;
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0)
                return &dev->ep[0];
@@ -2073,7 +2124,7 @@ static struct langwell_ep *get_ep_by_windex(struct langwell_udc *dev,
                        return ep;
        }
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return NULL;
 }
 
@@ -2085,7 +2136,7 @@ static int ep_is_stall(struct langwell_ep *ep)
        u32                     endptctrl;
        int                     retval;
 
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        endptctrl = readl(&dev->op_regs->endptctrl[ep->ep_num]);
        if (is_in(ep))
@@ -2093,7 +2144,7 @@ static int ep_is_stall(struct langwell_ep *ep)
        else
                retval = endptctrl & EPCTRL_RXS ? 1 : 0;
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return retval;
 }
 
@@ -2107,14 +2158,13 @@ static void get_status(struct langwell_udc *dev, u8 request_type, u16 value,
        u16     status_data = 0;        /* 16 bits cpu view status data */
        int     status = 0;
 
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        ep = &dev->ep[0];
 
        if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
                /* get device status */
-               status_data = 1 << USB_DEVICE_SELF_POWERED;
-               status_data |= dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP;
+               status_data = dev->dev_status;
        } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) {
                /* get interface status */
                status_data = 0;
@@ -2129,6 +2179,8 @@ static void get_status(struct langwell_udc *dev, u8 request_type, u16 value,
                status_data = ep_is_stall(epn) << USB_ENDPOINT_HALT;
        }
 
+       dev_dbg(&dev->pdev->dev, "get status data: 0x%04x\n", status_data);
+
        dev->ep0_dir = USB_DIR_IN;
 
        /* borrow the per device status_req */
@@ -2150,18 +2202,19 @@ static void get_status(struct langwell_udc *dev, u8 request_type, u16 value,
                goto stall;
 
        if (status) {
-               ERROR(dev, "response error on GET_STATUS request\n");
+               dev_err(&dev->pdev->dev,
+                               "response error on GET_STATUS request\n");
                goto stall;
        }
 
        list_add_tail(&req->queue, &ep->queue);
        dev->ep0_state = DATA_STATE_XMIT;
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return;
 stall:
        ep0_stall(dev);
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
 
@@ -2173,12 +2226,12 @@ static void handle_setup_packet(struct langwell_udc *dev,
        u16     wIndex = le16_to_cpu(setup->wIndex);
        u16     wLength = le16_to_cpu(setup->wLength);
 
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        /* ep0 fifo flush */
        nuke(&dev->ep[0], -ESHUTDOWN);
 
-       DBG(dev, "SETUP %02x.%02x v%04x i%04x l%04x\n",
+       dev_dbg(&dev->pdev->dev, "SETUP %02x.%02x v%04x i%04x l%04x\n",
                        setup->bRequestType, setup->bRequest,
                        wValue, wIndex, wLength);
 
@@ -2197,7 +2250,7 @@ static void handle_setup_packet(struct langwell_udc *dev,
        /* We process some stardard setup requests here */
        switch (setup->bRequest) {
        case USB_REQ_GET_STATUS:
-               DBG(dev, "SETUP: USB_REQ_GET_STATUS\n");
+               dev_dbg(&dev->pdev->dev, "SETUP: USB_REQ_GET_STATUS\n");
                /* get status, DATA and STATUS phase */
                if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK))
                                        != (USB_DIR_IN | USB_TYPE_STANDARD))
@@ -2206,7 +2259,7 @@ static void handle_setup_packet(struct langwell_udc *dev,
                goto end;
 
        case USB_REQ_SET_ADDRESS:
-               DBG(dev, "SETUP: USB_REQ_SET_ADDRESS\n");
+               dev_dbg(&dev->pdev->dev, "SETUP: USB_REQ_SET_ADDRESS\n");
                /* STATUS phase */
                if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD
                                                | USB_RECIP_DEVICE))
@@ -2220,9 +2273,11 @@ static void handle_setup_packet(struct langwell_udc *dev,
        {
                int rc = -EOPNOTSUPP;
                if (setup->bRequest == USB_REQ_SET_FEATURE)
-                       DBG(dev, "SETUP: USB_REQ_SET_FEATURE\n");
+                       dev_dbg(&dev->pdev->dev,
+                                       "SETUP: USB_REQ_SET_FEATURE\n");
                else if (setup->bRequest == USB_REQ_CLEAR_FEATURE)
-                       DBG(dev, "SETUP: USB_REQ_CLEAR_FEATURE\n");
+                       dev_dbg(&dev->pdev->dev,
+                                       "SETUP: USB_REQ_CLEAR_FEATURE\n");
 
                if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK))
                                == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) {
@@ -2240,13 +2295,29 @@ static void handle_setup_packet(struct langwell_udc *dev,
 
                        spin_unlock(&dev->lock);
                        rc = langwell_ep_set_halt(&epn->ep,
-                                       (setup->bRequest == USB_REQ_SET_FEATURE)
-                                               ? 1 : 0);
+                               (setup->bRequest == USB_REQ_SET_FEATURE)
+                               ? 1 : 0);
                        spin_lock(&dev->lock);
 
                } else if ((setup->bRequestType & (USB_RECIP_MASK
                                | USB_TYPE_MASK)) == (USB_RECIP_DEVICE
                                | USB_TYPE_STANDARD)) {
+                       rc = 0;
+                       switch (wValue) {
+                       case USB_DEVICE_REMOTE_WAKEUP:
+                               if (setup->bRequest == USB_REQ_SET_FEATURE) {
+                                       dev->remote_wakeup = 1;
+                                       dev->dev_status |= (1 << wValue);
+                               } else {
+                                       dev->remote_wakeup = 0;
+                                       dev->dev_status &= ~(1 << wValue);
+                               }
+                               break;
+                       default:
+                               rc = -EOPNOTSUPP;
+                               break;
+                       }
+
                        if (!gadget_is_otg(&dev->gadget))
                                break;
                        else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) {
@@ -2262,7 +2333,6 @@ static void handle_setup_packet(struct langwell_udc *dev,
                                dev->gadget.a_alt_hnp_support = 1;
                        else
                                break;
-                       rc = 0;
                } else
                        break;
 
@@ -2274,31 +2344,38 @@ static void handle_setup_packet(struct langwell_udc *dev,
        }
 
        case USB_REQ_GET_DESCRIPTOR:
-               DBG(dev, "SETUP: USB_REQ_GET_DESCRIPTOR\n");
+               dev_dbg(&dev->pdev->dev,
+                               "SETUP: USB_REQ_GET_DESCRIPTOR\n");
                goto delegate;
 
        case USB_REQ_SET_DESCRIPTOR:
-               DBG(dev, "SETUP: USB_REQ_SET_DESCRIPTOR unsupported\n");
+               dev_dbg(&dev->pdev->dev,
+                               "SETUP: USB_REQ_SET_DESCRIPTOR unsupported\n");
                goto delegate;
 
        case USB_REQ_GET_CONFIGURATION:
-               DBG(dev, "SETUP: USB_REQ_GET_CONFIGURATION\n");
+               dev_dbg(&dev->pdev->dev,
+                               "SETUP: USB_REQ_GET_CONFIGURATION\n");
                goto delegate;
 
        case USB_REQ_SET_CONFIGURATION:
-               DBG(dev, "SETUP: USB_REQ_SET_CONFIGURATION\n");
+               dev_dbg(&dev->pdev->dev,
+                               "SETUP: USB_REQ_SET_CONFIGURATION\n");
                goto delegate;
 
        case USB_REQ_GET_INTERFACE:
-               DBG(dev, "SETUP: USB_REQ_GET_INTERFACE\n");
+               dev_dbg(&dev->pdev->dev,
+                               "SETUP: USB_REQ_GET_INTERFACE\n");
                goto delegate;
 
        case USB_REQ_SET_INTERFACE:
-               DBG(dev, "SETUP: USB_REQ_SET_INTERFACE\n");
+               dev_dbg(&dev->pdev->dev,
+                               "SETUP: USB_REQ_SET_INTERFACE\n");
                goto delegate;
 
        case USB_REQ_SYNCH_FRAME:
-               DBG(dev, "SETUP: USB_REQ_SYNCH_FRAME unsupported\n");
+               dev_dbg(&dev->pdev->dev,
+                               "SETUP: USB_REQ_SYNCH_FRAME unsupported\n");
                goto delegate;
 
        default:
@@ -2310,7 +2387,8 @@ delegate:
                        /* DATA phase from gadget, STATUS phase from udc */
                        dev->ep0_dir = (setup->bRequestType & USB_DIR_IN)
                                        ?  USB_DIR_IN : USB_DIR_OUT;
-                       VDBG(dev, "dev->ep0_dir = 0x%x, wLength = %d\n",
+                       dev_vdbg(&dev->pdev->dev,
+                                       "dev->ep0_dir = 0x%x, wLength = %d\n",
                                        dev->ep0_dir, wLength);
                        spin_unlock(&dev->lock);
                        if (dev->driver->setup(&dev->gadget,
@@ -2322,7 +2400,8 @@ delegate:
                } else {
                        /* no DATA phase, IN STATUS phase from gadget */
                        dev->ep0_dir = USB_DIR_IN;
-                       VDBG(dev, "dev->ep0_dir = 0x%x, wLength = %d\n",
+                       dev_vdbg(&dev->pdev->dev,
+                                       "dev->ep0_dir = 0x%x, wLength = %d\n",
                                        dev->ep0_dir, wLength);
                        spin_unlock(&dev->lock);
                        if (dev->driver->setup(&dev->gadget,
@@ -2334,8 +2413,7 @@ delegate:
                break;
        }
 end:
-       VDBG(dev, "<--- %s()\n", __func__);
-       return;
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
 
@@ -2359,23 +2437,27 @@ static int process_ep_req(struct langwell_udc *dev, int index,
        td_complete = 0;
        actual = curr_req->req.length;
 
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        for (i = 0; i < curr_req->dtd_count; i++) {
-               remaining_length = le16_to_cpu(curr_dtd->dtd_total);
-               actual -= remaining_length;
 
                /* command execution states by dTD */
                dtd_status = curr_dtd->dtd_status;
 
+               barrier();
+               remaining_length = le16_to_cpu(curr_dtd->dtd_total);
+               actual -= remaining_length;
+
                if (!dtd_status) {
                        /* transfers completed successfully */
                        if (!remaining_length) {
                                td_complete++;
-                               VDBG(dev, "dTD transmitted successfully\n");
+                               dev_vdbg(&dev->pdev->dev,
+                                       "dTD transmitted successfully\n");
                        } else {
                                if (dir) {
-                                       VDBG(dev, "TX dTD remains data\n");
+                                       dev_vdbg(&dev->pdev->dev,
+                                               "TX dTD remains data\n");
                                        retval = -EPROTO;
                                        break;
 
@@ -2387,27 +2469,32 @@ static int process_ep_req(struct langwell_udc *dev, int index,
                } else {
                        /* transfers completed with errors */
                        if (dtd_status & DTD_STS_ACTIVE) {
-                               DBG(dev, "request not completed\n");
+                               dev_dbg(&dev->pdev->dev,
+                                       "dTD status ACTIVE dQH[%d]\n", index);
                                retval = 1;
                                return retval;
                        } else if (dtd_status & DTD_STS_HALTED) {
-                               ERROR(dev, "dTD error %08x dQH[%d]\n",
-                                               dtd_status, index);
+                               dev_err(&dev->pdev->dev,
+                                       "dTD error %08x dQH[%d]\n",
+                                       dtd_status, index);
                                /* clear the errors and halt condition */
                                curr_dqh->dtd_status = 0;
                                retval = -EPIPE;
                                break;
                        } else if (dtd_status & DTD_STS_DBE) {
-                               DBG(dev, "data buffer (overflow) error\n");
+                               dev_dbg(&dev->pdev->dev,
+                                       "data buffer (overflow) error\n");
                                retval = -EPROTO;
                                break;
                        } else if (dtd_status & DTD_STS_TRE) {
-                               DBG(dev, "transaction(ISO) error\n");
+                               dev_dbg(&dev->pdev->dev,
+                                       "transaction(ISO) error\n");
                                retval = -EILSEQ;
                                break;
                        } else
-                               ERROR(dev, "unknown error (0x%x)!\n",
-                                               dtd_status);
+                               dev_err(&dev->pdev->dev,
+                                       "unknown error (0x%x)!\n",
+                                       dtd_status);
                }
 
                if (i != curr_req->dtd_count - 1)
@@ -2420,7 +2507,7 @@ static int process_ep_req(struct langwell_udc *dev, int index,
 
        curr_req->req.actual = actual;
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
        return 0;
 }
 
@@ -2430,7 +2517,7 @@ static void ep0_req_complete(struct langwell_udc *dev,
                struct langwell_ep *ep0, struct langwell_request *req)
 {
        u32     new_addr;
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        if (dev->usb_state == USB_STATE_ADDRESS) {
                /* set the new address */
@@ -2438,7 +2525,7 @@ static void ep0_req_complete(struct langwell_udc *dev,
                writel(new_addr << USBADR_SHIFT, &dev->op_regs->deviceaddr);
 
                new_addr = USBADR(readl(&dev->op_regs->deviceaddr));
-               VDBG(dev, "new_addr = %d\n", new_addr);
+               dev_vdbg(&dev->pdev->dev, "new_addr = %d\n", new_addr);
        }
 
        done(ep0, req, 0);
@@ -2458,14 +2545,14 @@ static void ep0_req_complete(struct langwell_udc *dev,
                dev->ep0_state = WAIT_FOR_SETUP;
                break;
        case WAIT_FOR_SETUP:
-               ERROR(dev, "unexpect ep0 packets\n");
+               dev_err(&dev->pdev->dev, "unexpect ep0 packets\n");
                break;
        default:
                ep0_stall(dev);
                break;
        }
 
-       VDBG(dev, "<--- %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
 
@@ -2477,16 +2564,17 @@ static void handle_trans_complete(struct langwell_udc *dev)
        struct langwell_ep      *epn;
        struct langwell_request *curr_req, *temp_req;
 
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        complete_bits = readl(&dev->op_regs->endptcomplete);
-       VDBG(dev, "endptcomplete register: 0x%08x\n", complete_bits);
+       dev_vdbg(&dev->pdev->dev, "endptcomplete register: 0x%08x\n",
+                       complete_bits);
 
        /* Write-Clear the bits in endptcomplete register */
        writel(complete_bits, &dev->op_regs->endptcomplete);
 
        if (!complete_bits) {
-               DBG(dev, "complete_bits = 0\n");
+               dev_dbg(&dev->pdev->dev, "complete_bits = 0\n");
                goto done;
        }
 
@@ -2506,23 +2594,25 @@ static void handle_trans_complete(struct langwell_udc *dev)
                        epn = &dev->ep[i];
 
                if (epn->name == NULL) {
-                       WARNING(dev, "invalid endpoint\n");
+                       dev_warn(&dev->pdev->dev, "invalid endpoint\n");
                        continue;
                }
 
                if (i < 2)
                        /* ep0 in and out */
-                       DBG(dev, "%s-%s transfer completed\n",
+                       dev_dbg(&dev->pdev->dev, "%s-%s transfer completed\n",
                                        epn->name,
                                        is_in(epn) ? "in" : "out");
                else
-                       DBG(dev, "%s transfer completed\n", epn->name);
+                       dev_dbg(&dev->pdev->dev, "%s transfer completed\n",
+                                       epn->name);
 
                /* process the req queue until an uncomplete request */
                list_for_each_entry_safe(curr_req, temp_req,
                                &epn->queue, queue) {
                        status = process_ep_req(dev, i, curr_req);
-                       VDBG(dev, "%s req status: %d\n", epn->name, status);
+                       dev_vdbg(&dev->pdev->dev, "%s req status: %d\n",
+                                       epn->name, status);
 
                        if (status)
                                break;
@@ -2540,8 +2630,7 @@ static void handle_trans_complete(struct langwell_udc *dev)
                }
        }
 done:
-       VDBG(dev, "<--- %s()\n", __func__);
-       return;
+       dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__);
 }
 
 
@@ -2551,14 +2640,14 @@ static void handle_port_change(struct langwell_udc *dev)
        u32     portsc1, devlc;
        u32     speed;
 
-       VDBG(dev, "---> %s()\n", __func__);
+       dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__);
 
        if (dev->bus_reset)
                dev->bus_reset = 0;
 
        portsc1 = readl(&dev->op_regs->portsc1);
        devlc = readl(&dev->op_regs->devlc);
-       VDBG(dev, "portsc1 = 0x%08x, devlc = 0x%08x\n",
+       dev_vdbg(&dev->pdev->dev, "portsc1 = 0x%08x, devlc = 0x%08x\n",
                        portsc1, devlc);
 
        /* bus reset is finished */
@@ -2579,25 +2668,22 @@ static void handle_port_change(struct langwell_udc *dev)
                        dev->gadget.speed = USB_SPEED_UNKNOWN;
                        break;
                }
-               VDBG(dev, "speed = %d, dev->gadget.speed = %d\n",
+               dev_vdbg(&dev->pdev->dev,
+                               "speed = %d, dev->gadget.speed = %d\n",
                                speed, dev->gadget.speed);
        }
 
        /* LPM L0 to L1 */
        if (dev->lpm && dev->lpm_state == LPM_L0)
                if (portsc1 & PORTS_SUSP && portsc1 & PORTS_SLP) {
-                               INFO(dev, "LPM L0 to L1\n");
-                               dev->lpm_state = LPM_L1;
+                       dev_info(&dev->pdev->dev, "LPM L0 to L1\n");
+                       dev->lpm_state = LPM_L1;
                }
 
        /* LPM L1 to L0, force resume or remote wakeup finished */
        if (dev->lpm && dev->lpm_state == LPM_L1)
                if (!(portsc1 & PORTS_SUSP)) {
-                       if (portsc1 & PORTS_SLP)
-                               INFO(dev, "LPM L1 to L0, force resume\n");
-                       else
-                               INFO(dev, "LPM L1 to L0, remote wakeup\n");
-
+                       dev_info(&dev->pdev->dev, "LPM L1 to L0\n");
                        dev->lpm_state = LPM_L0;
                }