Parcourir la source

Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (94 commits)
  USB: remove err() macro from more usb drivers
  USB: remove err() macro from usb misc drivers
  USB: remove err() macro from usb core code
  USB: remove err() macro from usb class drivers
  USB: remove use of err() in drivers/usb/serial
  USB: remove info() macro from usb mtd drivers
  USB: remove info() macro from usb input drivers
  USB: remove info() macro from usb network drivers
  USB: remove info() macro from remaining usb drivers
  USB: remove info() macro from usb/misc drivers
  USB: remove info() macro from usb/serial drivers
  USB: remove warn macro from HID core
  USB: remove warn() macro from usb drivers
  USB: remove warn() macro from usb net drivers
  USB: remove warn() macro from usb media drivers
  USB: remove warn() macro from usb input drivers
  usb/fsl_qe_udc: clear data toggle on clear halt request
  usb/fsl_qe_udc: fix response to get status request
  fsl_usb2_udc: Fix oops on probe failure.
  fsl_usb2_udc: Add a wmb before priming endpoint.
  ...
Linus Torvalds il y a 16 ans
Parent
commit
0cfd81031a
100 fichiers modifiés avec 6271 ajouts et 859 suppressions
  1. 62 0
      Documentation/ABI/stable/sysfs-driver-usb-usbtmc
  2. 16 0
      Documentation/ABI/testing/sysfs-bus-usb
  3. 43 0
      Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg
  4. 3 0
      Documentation/DocBook/gadget.tmpl
  5. 3 0
      Documentation/devices.txt
  6. 3 0
      Documentation/ioctl-number.txt
  7. 19 0
      Documentation/kernel-parameters.txt
  8. 17 0
      Documentation/usb/anchors.txt
  9. 46 0
      Documentation/usb/misc_usbsevseg.txt
  10. 4 4
      Documentation/usb/power-management.txt
  11. 0 3
      drivers/block/ub.c
  12. 2 2
      drivers/hid/usbhid/hid-core.c
  13. 23 13
      drivers/input/joystick/iforce/iforce-ff.c
  14. 8 6
      drivers/input/joystick/iforce/iforce-main.c
  15. 5 3
      drivers/input/joystick/iforce/iforce-packets.c
  16. 1 1
      drivers/input/joystick/iforce/iforce-usb.c
  17. 1 1
      drivers/input/joystick/xpad.c
  18. 11 9
      drivers/input/misc/ati_remote.c
  19. 2 1
      drivers/input/misc/yealink.c
  20. 2 1
      drivers/input/tablet/acecad.c
  21. 16 10
      drivers/input/tablet/aiptek.c
  22. 2 2
      drivers/input/tablet/gtco.c
  23. 2 1
      drivers/input/tablet/kbtab.c
  24. 2 1
      drivers/input/tablet/wacom_sys.c
  25. 8 5
      drivers/media/radio/dsbr100.c
  26. 2 2
      drivers/media/video/dabusb.c
  27. 12 7
      drivers/media/video/ov511.c
  28. 5 3
      drivers/media/video/usbvideo/konicawc.c
  29. 8 6
      drivers/media/video/usbvideo/quickcam_messenger.c
  30. 2 2
      drivers/mtd/nand/alauda.c
  31. 2 1
      drivers/net/irda/kingsun-sir.c
  32. 2 1
      drivers/net/irda/ks959-sir.c
  33. 2 1
      drivers/net/irda/ksdazzle-sir.c
  34. 10 8
      drivers/net/irda/stir4200.c
  35. 5 3
      drivers/net/usb/catc.c
  36. 14 13
      drivers/net/usb/kaweth.c
  37. 17 14
      drivers/net/usb/rtl8150.c
  38. 5 5
      drivers/usb/atm/usbatm.c
  39. 8 2
      drivers/usb/atm/usbatm.h
  40. 1 1
      drivers/usb/atm/xusbatm.c
  41. 10 0
      drivers/usb/class/Kconfig
  42. 1 0
      drivers/usb/class/Makefile
  43. 16 10
      drivers/usb/class/cdc-acm.c
  44. 30 18
      drivers/usb/class/cdc-wdm.c
  45. 13 12
      drivers/usb/class/usblp.c
  46. 1087 0
      drivers/usb/class/usbtmc.c
  47. 1 1
      drivers/usb/core/Kconfig
  48. 8 4
      drivers/usb/core/devio.c
  49. 2 1
      drivers/usb/core/driver.c
  50. 2 1
      drivers/usb/core/endpoint.c
  51. 3 2
      drivers/usb/core/file.c
  52. 4 0
      drivers/usb/core/hcd.c
  53. 6 0
      drivers/usb/core/hcd.h
  54. 91 11
      drivers/usb/core/hub.c
  55. 10 8
      drivers/usb/core/inode.c
  56. 2 1
      drivers/usb/core/message.c
  57. 24 0
      drivers/usb/core/sysfs.c
  58. 161 8
      drivers/usb/core/urb.c
  59. 189 126
      drivers/usb/gadget/Kconfig
  60. 1 0
      drivers/usb/gadget/Makefile
  61. 0 1
      drivers/usb/gadget/cdc2.c
  62. 66 2
      drivers/usb/gadget/composite.c
  63. 27 6
      drivers/usb/gadget/dummy_hcd.c
  64. 0 2
      drivers/usb/gadget/ether.c
  65. 0 1
      drivers/usb/gadget/f_loopback.c
  66. 493 0
      drivers/usb/gadget/f_obex.c
  67. 0 1
      drivers/usb/gadget/f_sourcesink.c
  68. 18 5
      drivers/usb/gadget/file_storage.c
  69. 2760 0
      drivers/usb/gadget/fsl_qe_udc.c
  70. 437 0
      drivers/usb/gadget/fsl_qe_udc.h
  71. 78 98
      drivers/usb/gadget/fsl_usb2_udc.c
  72. 2 19
      drivers/usb/gadget/fsl_usb2_udc.h
  73. 9 0
      drivers/usb/gadget/gadget_chips.h
  74. 1 1
      drivers/usb/gadget/gmidi.c
  75. 34 6
      drivers/usb/gadget/net2280.c
  76. 1 0
      drivers/usb/gadget/net2280.h
  77. 7 0
      drivers/usb/gadget/omap_udc.c
  78. 2 4
      drivers/usb/gadget/printer.c
  79. 0 1
      drivers/usb/gadget/pxa27x_udc.c
  80. 1 1
      drivers/usb/gadget/s3c2410_udc.c
  81. 14 1
      drivers/usb/gadget/serial.c
  82. 7 0
      drivers/usb/gadget/u_ether.c
  83. 1 0
      drivers/usb/gadget/u_serial.h
  84. 32 24
      drivers/usb/host/ehci-dbg.c
  85. 29 19
      drivers/usb/host/ehci-hcd.c
  86. 19 8
      drivers/usb/host/ehci-hub.c
  87. 0 201
      drivers/usb/host/ehci-ppc-soc.c
  88. 9 14
      drivers/usb/host/ehci.h
  89. 9 4
      drivers/usb/host/isp116x-hcd.c
  90. 4 3
      drivers/usb/host/isp1760-if.c
  91. 1 1
      drivers/usb/host/ohci-dbg.c
  92. 5 5
      drivers/usb/host/ohci-hcd.c
  93. 52 35
      drivers/usb/host/ohci-hub.c
  94. 2 2
      drivers/usb/host/ohci-omap.c
  95. 1 1
      drivers/usb/host/ohci-pnx4008.c
  96. 0 8
      drivers/usb/host/ohci.h
  97. 65 36
      drivers/usb/host/r8a66597-hcd.c
  98. 11 4
      drivers/usb/host/sl811-hcd.c
  99. 6 4
      drivers/usb/host/uhci-hcd.c
  100. 11 6
      drivers/usb/host/uhci-q.c

+ 62 - 0
Documentation/ABI/stable/sysfs-driver-usb-usbtmc

@@ -0,0 +1,62 @@
+What:		/sys/bus/usb/drivers/usbtmc/devices/*/interface_capabilities
+What:		/sys/bus/usb/drivers/usbtmc/devices/*/device_capabilities
+Date:		August 2008
+Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Description:
+		These files show the various USB TMC capabilities as described
+		by the device itself.  The full description of the bitfields
+		can be found in the USB TMC documents from the USB-IF entitled
+		"Universal Serial Bus Test and Measurement Class Specification
+		(USBTMC) Revision 1.0" section 4.2.1.8.
+
+		The files are read only.
+
+
+What:		/sys/bus/usb/drivers/usbtmc/devices/*/usb488_interface_capabilities
+What:		/sys/bus/usb/drivers/usbtmc/devices/*/usb488_device_capabilities
+Date:		August 2008
+Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Description:
+		These files show the various USB TMC capabilities as described
+		by the device itself.  The full description of the bitfields
+		can be found in the USB TMC documents from the USB-IF entitled
+		"Universal Serial Bus Test and Measurement Class, Subclass
+		USB488 Specification (USBTMC-USB488) Revision 1.0" section
+		4.2.2.
+
+		The files are read only.
+
+
+What:		/sys/bus/usb/drivers/usbtmc/devices/*/TermChar
+Date:		August 2008
+Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Description:
+		This file is the TermChar value to be sent to the USB TMC
+		device as described by the document, "Universal Serial Bus Test
+		and Measurement Class Specification
+		(USBTMC) Revision 1.0" as published by the USB-IF.
+
+		Note that the TermCharEnabled file determines if this value is
+		sent to the device or not.
+
+
+What:		/sys/bus/usb/drivers/usbtmc/devices/*/TermCharEnabled
+Date:		August 2008
+Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Description:
+		This file determines if the TermChar is to be sent to the
+		device on every transaction or not.  For more details about
+		this, please see the document, "Universal Serial Bus Test and
+		Measurement Class Specification (USBTMC) Revision 1.0" as
+		published by the USB-IF.
+
+
+What:		/sys/bus/usb/drivers/usbtmc/devices/*/auto_abort
+Date:		August 2008
+Contact:	Greg Kroah-Hartman <gregkh@suse.de>
+Description:
+		This file determines if the the transaction of the USB TMC
+		device is to be automatically aborted if there is any error.
+		For more details about this, please see the document,
+		"Universal Serial Bus Test and Measurement Class Specification
+		(USBTMC) Revision 1.0" as published by the USB-IF.

+ 16 - 0
Documentation/ABI/testing/sysfs-bus-usb

@@ -85,3 +85,19 @@ Description:
 Users:
 		PowerTOP <power@bughost.org>
 		http://www.lesswatts.org/projects/powertop/
+
+What:		/sys/bus/usb/device/<busnum>-<devnum>...:<config num>-<interface num>/supports_autosuspend
+Date:		January 2008
+KernelVersion:	2.6.27
+Contact:	Sarah Sharp <sarah.a.sharp@intel.com>
+Description:
+		When read, this file returns 1 if the interface driver
+		for this interface supports autosuspend.  It also
+		returns 1 if no driver has claimed this interface, as an
+		unclaimed interface will not stop the device from being
+		autosuspended if all other interface drivers are idle.
+		The file returns 0 if autosuspend support has not been
+		added to the driver.
+Users:
+		USB PM tool
+		git://git.moblin.org/users/sarah/usb-pm-tool/

+ 43 - 0
Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg

@@ -0,0 +1,43 @@
+Where:		/sys/bus/usb/.../powered
+Date:		August 2008
+Kernel Version:	2.6.26
+Contact:	Harrison Metzger <harrisonmetz@gmail.com>
+Description:	Controls whether the device's display will powered.
+		A value of 0 is off and a non-zero value is on.
+
+Where:		/sys/bus/usb/.../mode_msb
+Where:		/sys/bus/usb/.../mode_lsb
+Date:		August 2008
+Kernel Version:	2.6.26
+Contact:	Harrison Metzger <harrisonmetz@gmail.com>
+Description:	Controls the devices display mode.
+		For a 6 character display the values are
+			MSB 0x06; LSB 0x3F, and
+		for an 8 character display the values are
+			MSB 0x08; LSB 0xFF.
+
+Where:		/sys/bus/usb/.../textmode
+Date:		August 2008
+Kernel Version:	2.6.26
+Contact:	Harrison Metzger <harrisonmetz@gmail.com>
+Description:	Controls the way the device interprets its text buffer.
+		raw:	each character controls its segment manually
+		hex:	each character is between 0-15
+		ascii:	each character is between '0'-'9' and 'A'-'F'.
+
+Where:		/sys/bus/usb/.../text
+Date:		August 2008
+Kernel Version:	2.6.26
+Contact:	Harrison Metzger <harrisonmetz@gmail.com>
+Description:	The text (or data) for the device to display
+
+Where:		/sys/bus/usb/.../decimals
+Date:		August 2008
+Kernel Version:	2.6.26
+Contact:	Harrison Metzger <harrisonmetz@gmail.com>
+Description:	Controls the decimal places on the device.
+		To set the nth decimal place, give this field
+		the value of 10 ** n. Assume this field has
+		the value k and has 1 or more decimal places set,
+		to set the mth place (where m is not already set),
+		change this fields value to k + 10 ** m.

+ 3 - 0
Documentation/DocBook/gadget.tmpl

@@ -557,6 +557,9 @@ Near-term plans include converting all of them, except for "gadgetfs".
 </para>
 
 !Edrivers/usb/gadget/f_acm.c
+!Edrivers/usb/gadget/f_ecm.c
+!Edrivers/usb/gadget/f_subset.c
+!Edrivers/usb/gadget/f_obex.c
 !Edrivers/usb/gadget/f_serial.c
 
 </sect1>

+ 3 - 0
Documentation/devices.txt

@@ -2571,6 +2571,9 @@ Your cooperation is appreciated.
 		160 = /dev/usb/legousbtower0	1st USB Legotower device
 		    ...
 		175 = /dev/usb/legousbtower15	16th USB Legotower device
+		176 = /dev/usb/usbtmc1	First USB TMC device
+		   ...
+		192 = /dev/usb/usbtmc16	16th USB TMC device
 		240 = /dev/usb/dabusb0	First daubusb device
 		    ...
 		243 = /dev/usb/dabusb3	Fourth dabusb device

+ 3 - 0
Documentation/ioctl-number.txt

@@ -92,6 +92,7 @@ Code	Seq#	Include File		Comments
 'J'	00-1F	drivers/scsi/gdth_ioctl.h
 'K'	all	linux/kd.h
 'L'	00-1F	linux/loop.h
+'L'	20-2F	driver/usb/misc/vstusb.h
 'L'	E0-FF	linux/ppdd.h		encrypted disk device driver
 					<http://linux01.gwdg.de/~alatham/ppdd.html>
 'M'	all	linux/soundcard.h
@@ -110,6 +111,8 @@ Code	Seq#	Include File		Comments
 'W'	00-1F	linux/wanrouter.h	conflict!
 'X'	all	linux/xfs_fs.h
 'Y'	all	linux/cyclades.h
+'['	00-07	linux/usb/usbtmc.h	USB Test and Measurement Devices
+					<mailto:gregkh@suse.de>
 'a'	all				ATM on linux
 					<http://lrcwww.epfl.ch/linux-atm/magic.html>
 'b'	00-FF				bit3 vme host bridge

+ 19 - 0
Documentation/kernel-parameters.txt

@@ -2253,6 +2253,25 @@ and is between 256 and 4096 characters. It is defined in the file
 			autosuspended.  Devices for which the delay is set
 			to a negative value won't be autosuspended at all.
 
+	usbcore.usbfs_snoop=
+			[USB] Set to log all usbfs traffic (default 0 = off).
+
+	usbcore.blinkenlights=
+			[USB] Set to cycle leds on hubs (default 0 = off).
+
+	usbcore.old_scheme_first=
+			[USB] Start with the old device initialization
+			scheme (default 0 = off).
+
+	usbcore.use_both_schemes=
+			[USB] Try the other device initialization scheme
+			if the first one fails (default 1 = enabled).
+
+	usbcore.initial_descriptor_timeout=
+			[USB] Specifies timeout for the initial 64-byte
+                        USB_REQ_GET_DESCRIPTOR request in milliseconds
+			(default 5000 = 5.0 seconds).
+
 	usbhid.mousepoll=
 			[USBHID] The interval which mice are to be polled at.
 

+ 17 - 0
Documentation/usb/anchors.txt

@@ -52,6 +52,11 @@ Therefore no guarantee is made that the URBs have been unlinked when
 the call returns. They may be unlinked later but will be unlinked in
 finite time.
 
+usb_scuttle_anchored_urbs()
+---------------------------
+
+All URBs of an anchor are unanchored en masse.
+
 usb_wait_anchor_empty_timeout()
 -------------------------------
 
@@ -59,4 +64,16 @@ This function waits for all URBs associated with an anchor to finish
 or a timeout, whichever comes first. Its return value will tell you
 whether the timeout was reached.
 
+usb_anchor_empty()
+------------------
+
+Returns true if no URBs are associated with an anchor. Locking
+is the caller's responsibility.
+
+usb_get_from_anchor()
+---------------------
 
+Returns the oldest anchored URB of an anchor. The URB is unanchored
+and returned with a reference. As you may mix URBs to several
+destinations in one anchor you have no guarantee the chronologically
+first submitted URB is returned.

+ 46 - 0
Documentation/usb/misc_usbsevseg.txt

@@ -0,0 +1,46 @@
+USB 7-Segment Numeric Display
+Manufactured by Delcom Engineering
+
+Device Information
+------------------
+USB VENDOR_ID	0x0fc5
+USB PRODUCT_ID	0x1227
+Both the 6 character and 8 character displays have PRODUCT_ID,
+and according to Delcom Engineering no queryable information
+can be obtained from the device to tell them apart.
+
+Device Modes
+------------
+By default, the driver assumes the display is only 6 characters
+The mode for 6 characters is:
+	MSB 0x06; LSB 0x3f
+For the 8 character display:
+	MSB 0x08; LSB 0xff
+The device can accept "text" either in raw, hex, or ascii textmode.
+raw controls each segment manually,
+hex expects a value between 0-15 per character,
+ascii expects a value between '0'-'9' and 'A'-'F'.
+The default is ascii.
+
+Device Operation
+----------------
+1.	Turn on the device:
+	echo 1 > /sys/bus/usb/.../powered
+2.	Set the device's mode:
+	echo $mode_msb > /sys/bus/usb/.../mode_msb
+	echo $mode_lsb > /sys/bus/usb/.../mode_lsb
+3.	Set the textmode:
+	echo $textmode > /sys/bus/usb/.../textmode
+4.	set the text (for example):
+	echo "123ABC" > /sys/bus/usb/.../text (ascii)
+	echo "A1B2" > /sys/bus/usb/.../text (ascii)
+	echo -ne "\x01\x02\x03" > /sys/bus/usb/.../text (hex)
+5.	Set the decimal places.
+	The device has either 6 or 8 decimal points.
+	to set the nth decimal place calculate 10 ** n
+	and echo it in to /sys/bus/usb/.../decimals
+	To set multiple decimals points sum up each power.
+	For example, to set the 0th and 3rd decimal place
+	echo 1001 > /sys/bus/usb/.../decimals
+
+

+ 4 - 4
Documentation/usb/power-management.txt

@@ -350,12 +350,12 @@ without holding the mutex.
 
 There also are a couple of utility routines drivers can use:
 
-	usb_autopm_enable() sets pm_usage_cnt to 1 and then calls
-	usb_autopm_set_interface(), which will attempt an autoresume.
-
-	usb_autopm_disable() sets pm_usage_cnt to 0 and then calls
+	usb_autopm_enable() sets pm_usage_cnt to 0 and then calls
 	usb_autopm_set_interface(), which will attempt an autosuspend.
 
+	usb_autopm_disable() sets pm_usage_cnt to 1 and then calls
+	usb_autopm_set_interface(), which will attempt an autoresume.
+
 The conventional usage pattern is that a driver calls
 usb_autopm_get_interface() in its open routine and
 usb_autopm_put_interface() in its close or release routine.  But

+ 0 - 3
drivers/block/ub.c

@@ -349,8 +349,6 @@ struct ub_dev {
 
 	struct work_struct reset_work;
 	wait_queue_head_t reset_wait;
-
-	int sg_stat[6];
 };
 
 /*
@@ -685,7 +683,6 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
 		goto drop;
 	}
 	urq->nsg = n_elem;
-	sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
 
 	if (blk_pc_request(rq)) {
 		ub_cmd_build_packet(sc, lun, cmd, urq);

+ 2 - 2
drivers/hid/usbhid/hid-core.c

@@ -428,7 +428,7 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
 		usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC);
 		if (!usbhid->out[usbhid->outhead].raw_report) {
 			spin_unlock_irqrestore(&usbhid->outlock, flags);
-			warn("output queueing failed");
+			dev_warn(&hid->dev, "output queueing failed\n");
 			return;
 		}
 		hid_output_report(report, usbhid->out[usbhid->outhead].raw_report);
@@ -455,7 +455,7 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
 		usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC);
 		if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) {
 			spin_unlock_irqrestore(&usbhid->ctrllock, flags);
-			warn("control queueing failed");
+			dev_warn(&hid->dev, "control queueing failed\n");
 			return;
 		}
 		hid_output_report(report, usbhid->ctrl[usbhid->ctrlhead].raw_report);

+ 23 - 13
drivers/input/joystick/iforce/iforce-ff.c

@@ -197,13 +197,16 @@ static unsigned char find_button(struct iforce *iforce, signed short button)
  * Analyse the changes in an effect, and tell if we need to send an condition
  * parameter packet
  */
-static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new)
+static int need_condition_modifier(struct iforce *iforce,
+				   struct ff_effect *old,
+				   struct ff_effect *new)
 {
 	int ret = 0;
 	int i;
 
 	if (new->type != FF_SPRING && new->type != FF_FRICTION) {
-		warn("bad effect type in need_condition_modifier");
+		dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
+			 __func__);
 		return 0;
 	}
 
@@ -222,10 +225,13 @@ static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new)
  * Analyse the changes in an effect, and tell if we need to send a magnitude
  * parameter packet
  */
-static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effect)
+static int need_magnitude_modifier(struct iforce *iforce,
+				   struct ff_effect *old,
+				   struct ff_effect *effect)
 {
 	if (effect->type != FF_CONSTANT) {
-		warn("bad effect type in need_envelope_modifier");
+		dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
+			 __func__);
 		return 0;
 	}
 
@@ -236,7 +242,8 @@ static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effe
  * Analyse the changes in an effect, and tell if we need to send an envelope
  * parameter packet
  */
-static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effect)
+static int need_envelope_modifier(struct iforce *iforce, struct ff_effect *old,
+				  struct ff_effect *effect)
 {
 	switch (effect->type) {
 	case FF_CONSTANT:
@@ -256,7 +263,8 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec
 		break;
 
 	default:
-		warn("bad effect type in need_envelope_modifier");
+		dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
+			 __func__);
 	}
 
 	return 0;
@@ -266,10 +274,12 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec
  * Analyse the changes in an effect, and tell if we need to send a periodic
  * parameter effect
  */
-static int need_period_modifier(struct ff_effect *old, struct ff_effect *new)
+static int need_period_modifier(struct iforce *iforce, struct ff_effect *old,
+				struct ff_effect *new)
 {
 	if (new->type != FF_PERIODIC) {
-		warn("bad effect type in need_period_modifier");
+		dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
+			 __func__);
 		return 0;
 	}
 	return (old->u.periodic.period != new->u.periodic.period
@@ -355,7 +365,7 @@ int iforce_upload_periodic(struct iforce *iforce, struct ff_effect *effect, stru
 	int param2_err = 1;
 	int core_err = 0;
 
-	if (!old || need_period_modifier(old, effect)) {
+	if (!old || need_period_modifier(iforce, old, effect)) {
 		param1_err = make_period_modifier(iforce, mod1_chunk,
 			old != NULL,
 			effect->u.periodic.magnitude, effect->u.periodic.offset,
@@ -365,7 +375,7 @@ int iforce_upload_periodic(struct iforce *iforce, struct ff_effect *effect, stru
 		set_bit(FF_MOD1_IS_USED, core_effect->flags);
 	}
 
-	if (!old || need_envelope_modifier(old, effect)) {
+	if (!old || need_envelope_modifier(iforce, old, effect)) {
 		param2_err = make_envelope_modifier(iforce, mod2_chunk,
 			old !=NULL,
 			effect->u.periodic.envelope.attack_length,
@@ -425,7 +435,7 @@ int iforce_upload_constant(struct iforce *iforce, struct ff_effect *effect, stru
 	int param2_err = 1;
 	int core_err = 0;
 
-	if (!old || need_magnitude_modifier(old, effect)) {
+	if (!old || need_magnitude_modifier(iforce, old, effect)) {
 		param1_err = make_magnitude_modifier(iforce, mod1_chunk,
 			old != NULL,
 			effect->u.constant.level);
@@ -434,7 +444,7 @@ int iforce_upload_constant(struct iforce *iforce, struct ff_effect *effect, stru
 		set_bit(FF_MOD1_IS_USED, core_effect->flags);
 	}
 
-	if (!old || need_envelope_modifier(old, effect)) {
+	if (!old || need_envelope_modifier(iforce, old, effect)) {
 		param2_err = make_envelope_modifier(iforce, mod2_chunk,
 			old != NULL,
 			effect->u.constant.envelope.attack_length,
@@ -487,7 +497,7 @@ int iforce_upload_condition(struct iforce *iforce, struct ff_effect *effect, str
 		default: return -1;
 	}
 
-	if (!old || need_condition_modifier(old, effect)) {
+	if (!old || need_condition_modifier(iforce, old, effect)) {
 		param_err = make_condition_modifier(iforce, mod1_chunk,
 			old != NULL,
 			effect->u.condition[0].right_saturation,

+ 8 - 6
drivers/input/joystick/iforce/iforce-main.c

@@ -218,7 +218,9 @@ static void iforce_release(struct input_dev *dev)
 		/* Check: no effects should be present in memory */
 		for (i = 0; i < dev->ff->max_effects; i++) {
 			if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags)) {
-				warn("iforce_release: Device still owns effects");
+				dev_warn(&dev->dev,
+					"%s: Device still owns effects\n",
+					__func__);
 				break;
 			}
 		}
@@ -335,26 +337,26 @@ int iforce_init_device(struct iforce *iforce)
 	if (!iforce_get_id_packet(iforce, "M"))
 		input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1];
 	else
-		warn("Device does not respond to id packet M");
+		dev_warn(&iforce->dev->dev, "Device does not respond to id packet M\n");
 
 	if (!iforce_get_id_packet(iforce, "P"))
 		input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1];
 	else
-		warn("Device does not respond to id packet P");
+		dev_warn(&iforce->dev->dev, "Device does not respond to id packet P\n");
 
 	if (!iforce_get_id_packet(iforce, "B"))
 		iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1];
 	else
-		warn("Device does not respond to id packet B");
+		dev_warn(&iforce->dev->dev, "Device does not respond to id packet B\n");
 
 	if (!iforce_get_id_packet(iforce, "N"))
 		ff_effects = iforce->edata[1];
 	else
-		warn("Device does not respond to id packet N");
+		dev_warn(&iforce->dev->dev, "Device does not respond to id packet N\n");
 
 	/* Check if the device can store more effects than the driver can really handle */
 	if (ff_effects > IFORCE_EFFECTS_MAX) {
-		warn("Limiting number of effects to %d (device reports %d)",
+		dev_warn(&iforce->dev->dev, "Limiting number of effects to %d (device reports %d)\n",
 		       IFORCE_EFFECTS_MAX, ff_effects);
 		ff_effects = IFORCE_EFFECTS_MAX;
 	}

+ 5 - 3
drivers/input/joystick/iforce/iforce-packets.c

@@ -65,7 +65,8 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data)
 
 
 	if (CIRC_SPACE(head, tail, XMIT_SIZE) < n+2) {
-		warn("not enough space in xmit buffer to send new packet");
+		dev_warn(&iforce->dev->dev,
+			 "not enough space in xmit buffer to send new packet\n");
 		spin_unlock_irqrestore(&iforce->xmit_lock, flags);
 		return -1;
 	}
@@ -148,7 +149,7 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
 			return 0;
 		}
 	}
-	warn("unused effect %04x updated !!!", addr);
+	dev_warn(&iforce->dev->dev, "unused effect %04x updated !!!\n", addr);
 	return -1;
 }
 
@@ -159,7 +160,8 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
 	static int being_used = 0;
 
 	if (being_used)
-		warn("re-entrant call to iforce_process %d", being_used);
+		dev_warn(&iforce->dev->dev,
+			 "re-entrant call to iforce_process %d\n", being_used);
 	being_used++;
 
 #ifdef CONFIG_JOYSTICK_IFORCE_232

+ 1 - 1
drivers/input/joystick/iforce/iforce-usb.c

@@ -64,7 +64,7 @@ void iforce_usb_xmit(struct iforce *iforce)
 
 	if ( (n=usb_submit_urb(iforce->out, GFP_ATOMIC)) ) {
 		clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
-		warn("usb_submit_urb failed %d\n", n);
+		dev_warn(&iforce->dev->dev, "usb_submit_urb failed %d\n", n);
 	}
 
 	/* The IFORCE_XMIT_RUNNING bit is not cleared here. That's intended.

+ 1 - 1
drivers/input/joystick/xpad.c

@@ -911,7 +911,7 @@ static int __init usb_xpad_init(void)
 {
 	int result = usb_register(&xpad_driver);
 	if (result == 0)
-		info(DRIVER_DESC);
+		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
 	return result;
 }
 

+ 11 - 9
drivers/input/misc/ati_remote.c

@@ -285,7 +285,6 @@ static const struct {
 };
 
 /* Local function prototypes */
-static void ati_remote_dump		(unsigned char *data, unsigned int actual_length);
 static int ati_remote_open		(struct input_dev *inputdev);
 static void ati_remote_close		(struct input_dev *inputdev);
 static int ati_remote_sendpacket	(struct ati_remote *ati_remote, u16 cmd, unsigned char *data);
@@ -307,15 +306,16 @@ static struct usb_driver ati_remote_driver = {
 /*
  *	ati_remote_dump_input
  */
-static void ati_remote_dump(unsigned char *data, unsigned int len)
+static void ati_remote_dump(struct device *dev, unsigned char *data,
+			    unsigned int len)
 {
 	if ((len == 1) && (data[0] != (unsigned char)0xff) && (data[0] != 0x00))
-		warn("Weird byte 0x%02x", data[0]);
+		dev_warn(dev, "Weird byte 0x%02x\n", data[0]);
 	else if (len == 4)
-		warn("Weird key %02x %02x %02x %02x",
+		dev_warn(dev, "Weird key %02x %02x %02x %02x\n",
 		     data[0], data[1], data[2], data[3]);
 	else
-		warn("Weird data, len=%d %02x %02x %02x %02x %02x %02x ...",
+		dev_warn(dev, "Weird data, len=%d %02x %02x %02x %02x %02x %02x ...\n",
 		     len, data[0], data[1], data[2], data[3], data[4], data[5]);
 }
 
@@ -470,7 +470,7 @@ static void ati_remote_input_report(struct urb *urb)
 	/* Deal with strange looking inputs */
 	if ( (urb->actual_length != 4) || (data[0] != 0x14) ||
 		((data[3] & 0x0f) != 0x00) ) {
-		ati_remote_dump(data, urb->actual_length);
+		ati_remote_dump(&urb->dev->dev, data, urb->actual_length);
 		return;
 	}
 
@@ -814,7 +814,7 @@ static void ati_remote_disconnect(struct usb_interface *interface)
 	ati_remote = usb_get_intfdata(interface);
 	usb_set_intfdata(interface, NULL);
 	if (!ati_remote) {
-		warn("%s - null device?\n", __func__);
+		dev_warn(&interface->dev, "%s - null device?\n", __func__);
 		return;
 	}
 
@@ -834,9 +834,11 @@ static int __init ati_remote_init(void)
 
 	result = usb_register(&ati_remote_driver);
 	if (result)
-		err("usb_register error #%d\n", result);
+		printk(KERN_ERR KBUILD_MODNAME
+		       ": usb_register error #%d\n", result);
 	else
-		info("Registered USB driver " DRIVER_DESC " v. " DRIVER_VERSION);
+		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+		       DRIVER_DESC "\n");
 
 	return result;
 }

+ 2 - 1
drivers/input/misc/yealink.c

@@ -999,7 +999,8 @@ static int __init yealink_dev_init(void)
 {
 	int ret = usb_register(&yealink_driver);
 	if (ret == 0)
-		info(DRIVER_DESC ":" DRIVER_VERSION);
+		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+		       DRIVER_DESC "\n");
 	return ret;
 }
 

+ 2 - 1
drivers/input/tablet/acecad.c

@@ -280,7 +280,8 @@ static int __init usb_acecad_init(void)
 {
 	int result = usb_register(&usb_acecad_driver);
 	if (result == 0)
-		info(DRIVER_VERSION ":" DRIVER_DESC);
+		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+		       DRIVER_DESC "\n");
 	return result;
 }
 

+ 16 - 10
drivers/input/tablet/aiptek.c

@@ -1706,20 +1706,21 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL);
 	inputdev = input_allocate_device();
 	if (!aiptek || !inputdev) {
-		warn("aiptek: cannot allocate memory or input device");
+		dev_warn(&intf->dev,
+			 "cannot allocate memory or input device\n");
 		goto fail1;
         }
 
 	aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
 					GFP_ATOMIC, &aiptek->data_dma);
         if (!aiptek->data) {
-		warn("aiptek: cannot allocate usb buffer");
+		dev_warn(&intf->dev, "cannot allocate usb buffer\n");
 		goto fail1;
 	}
 
 	aiptek->urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!aiptek->urb) {
-	        warn("aiptek: cannot allocate urb");
+	        dev_warn(&intf->dev, "cannot allocate urb\n");
 		goto fail2;
 	}
 
@@ -1843,8 +1844,9 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
 		aiptek->curSetting.programmableDelay = speeds[i];
 		(void)aiptek_program_tablet(aiptek);
 		if (aiptek->inputdev->absmax[ABS_X] > 0) {
-			info("input: Aiptek using %d ms programming speed\n",
-			     aiptek->curSetting.programmableDelay);
+			dev_info(&intf->dev,
+				 "Aiptek using %d ms programming speed\n",
+				 aiptek->curSetting.programmableDelay);
 			break;
 		}
 	}
@@ -1852,7 +1854,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	/* Murphy says that some day someone will have a tablet that fails the
 	   above test. That's you, Frederic Rodrigo */
 	if (i == ARRAY_SIZE(speeds)) {
-		info("input: Aiptek tried all speeds, no sane response");
+		dev_info(&intf->dev,
+			 "Aiptek tried all speeds, no sane response\n");
 		goto fail2;
 	}
 
@@ -1864,7 +1867,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	 */
 	err = sysfs_create_group(&intf->dev.kobj, &aiptek_attribute_group);
 	if (err) {
-		warn("aiptek: cannot create sysfs group err: %d", err);
+		dev_warn(&intf->dev, "cannot create sysfs group err: %d\n",
+			 err);
 		goto fail3;
         }
 
@@ -1872,7 +1876,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	 */
 	err = input_register_device(aiptek->inputdev);
 	if (err) {
-		warn("aiptek: input_register_device returned err: %d", err);
+		dev_warn(&intf->dev,
+			 "input_register_device returned err: %d\n", err);
 		goto fail4;
         }
 	return 0;
@@ -1922,8 +1927,9 @@ static int __init aiptek_init(void)
 {
 	int result = usb_register(&aiptek_driver);
 	if (result == 0) {
-		info(DRIVER_VERSION ": " DRIVER_AUTHOR);
-		info(DRIVER_DESC);
+		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+		       DRIVER_DESC "\n");
+		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_AUTHOR "\n");
 	}
 	return result;
 }

+ 2 - 2
drivers/input/tablet/gtco.c

@@ -2,7 +2,7 @@
 
 GTCO digitizer USB driver
 
-Use the err(), dbg() and info() macros from usb.h for system logging
+Use the err() and dbg() macros from usb.h for system logging
 
 TO CHECK:  Is pressure done right on report 5?
 
@@ -1010,7 +1010,7 @@ static void gtco_disconnect(struct usb_interface *interface)
 		kfree(gtco);
 	}
 
-	info("gtco driver disconnected");
+	dev_info(&interface->dev, "gtco driver disconnected\n");
 }
 
 /*   STANDARD MODULE LOAD ROUTINES  */

+ 2 - 1
drivers/input/tablet/kbtab.c

@@ -215,7 +215,8 @@ static int __init kbtab_init(void)
 	retval = usb_register(&kbtab_driver);
 	if (retval)
 		goto out;
-	info(DRIVER_VERSION ":" DRIVER_DESC);
+	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+	       DRIVER_DESC "\n");
 out:
 	return retval;
 }

+ 2 - 1
drivers/input/tablet/wacom_sys.c

@@ -385,7 +385,8 @@ static int __init wacom_init(void)
 	wacom_driver.id_table = get_device_table();
 	result = usb_register(&wacom_driver);
 	if (result == 0)
-		info(DRIVER_VERSION ":" DRIVER_DESC);
+		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+		       DRIVER_DESC "\n");
 	return result;
 }
 

+ 8 - 5
drivers/media/radio/dsbr100.c

@@ -310,7 +310,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
 
 	radio->curfreq = f->frequency;
 	if (dsbr100_setfreq(radio, radio->curfreq)==-1)
-		warn("Set frequency failed");
+		dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
 	return 0;
 }
 
@@ -361,12 +361,14 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
 	case V4L2_CID_AUDIO_MUTE:
 		if (ctrl->value) {
 			if (dsbr100_stop(radio) == -1) {
-				warn("Radio did not respond properly");
+				dev_warn(&radio->usbdev->dev,
+					 "Radio did not respond properly\n");
 				return -EBUSY;
 			}
 		} else {
 			if (dsbr100_start(radio) == -1) {
-				warn("Radio did not respond properly");
+				dev_warn(&radio->usbdev->dev,
+					 "Radio did not respond properly\n");
 				return -EBUSY;
 			}
 		}
@@ -416,7 +418,8 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file)
 	radio->muted = 1;
 
 	if (dsbr100_start(radio)<0) {
-		warn("Radio did not start up properly");
+		dev_warn(&radio->usbdev->dev,
+			 "Radio did not start up properly\n");
 		radio->users = 0;
 		unlock_kernel();
 		return -EIO;
@@ -501,7 +504,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
 	radio->curfreq = FREQ_MIN*FREQ_MUL;
 	video_set_drvdata(radio->videodev, radio);
 	if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr) < 0) {
-		warn("Could not register video device");
+		dev_warn(&intf->dev, "Could not register video device\n");
 		video_device_release(radio->videodev);
 		kfree(radio->transfer_buffer);
 		kfree(radio);

+ 2 - 2
drivers/media/video/dabusb.c

@@ -192,7 +192,7 @@ static void dabusb_iso_complete (struct urb *purb)
 					err("dabusb_iso_complete: invalid len %d", len);
 			}
 			else
-				warn("dabusb_iso_complete: corrupted packet status: %d", purb->iso_frame_desc[i].status);
+				dev_warn(&purb->dev->dev, "dabusb_iso_complete: corrupted packet status: %d\n", purb->iso_frame_desc[i].status);
 		if (dst != purb->actual_length)
 			err("dst!=purb->actual_length:%d!=%d", dst, purb->actual_length);
 	}
@@ -289,7 +289,7 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
 	}
 
 	if( ret == -EPIPE ) {
-		warn("CLEAR_FEATURE request to remove STALL condition.");
+		dev_warn(&s->usbdev->dev, "CLEAR_FEATURE request to remove STALL condition.\n");
 		if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
 			err("request failed");
 	}

+ 12 - 7
drivers/media/video/ov511.c

@@ -1098,9 +1098,10 @@ ov51x_clear_snapshot(struct usb_ov511 *ov)
 		reg_w(ov, R51x_SYS_SNAP, 0x02);
 		reg_w(ov, R51x_SYS_SNAP, 0x00);
 	} else if (ov->bclass == BCL_OV518) {
-		warn("snapshot reset not supported yet on OV518(+)");
+		dev_warn(&ov->dev->dev,
+			 "snapshot reset not supported yet on OV518(+)\n");
 	} else {
-		err("clear snap: invalid bridge type");
+		dev_err(&ov->dev->dev, "clear snap: invalid bridge type\n");
 	}
 }
 
@@ -1115,14 +1116,16 @@ ov51x_check_snapshot(struct usb_ov511 *ov)
 	if (ov->bclass == BCL_OV511) {
 		ret = reg_r(ov, R51x_SYS_SNAP);
 		if (ret < 0) {
-			err("Error checking snspshot status (%d)", ret);
+			dev_err(&ov->dev->dev,
+				"Error checking snspshot status (%d)\n", ret);
 		} else if (ret & 0x08) {
 			status = 1;
 		}
 	} else if (ov->bclass == BCL_OV518) {
-		warn("snapshot check not supported yet on OV518(+)");
+		dev_warn(&ov->dev->dev,
+			 "snapshot check not supported yet on OV518(+)\n");
 	} else {
-		err("check snap: invalid bridge type");
+		dev_err(&ov->dev->dev, "clear snap: invalid bridge type\n");
 	}
 
 	return status;
@@ -5217,7 +5220,8 @@ saa7111a_configure(struct usb_ov511 *ov)
 	if (ov->bclass == BCL_OV511)
 		reg_w(ov, 0x11, 0x00);
 	else
-		warn("SAA7111A not yet supported with OV518/OV518+");
+		dev_warn(&ov->dev->dev,
+			 "SAA7111A not yet supported with OV518/OV518+\n");
 
 	return 0;
 }
@@ -5456,7 +5460,8 @@ ov518_configure(struct usb_ov511 *ov)
 	 * required. OV518 has no uncompressed mode, to save RAM. */
 	if (!dumppix && !ov->compress) {
 		ov->compress = 1;
-		warn("Compression required with OV518...enabling");
+		dev_warn(&ov->dev->dev,
+			 "Compression required with OV518...enabling\n");
 	}
 
 	if (ov->bridge == BRG_OV518) {

+ 5 - 3
drivers/media/video/usbvideo/konicawc.c

@@ -229,7 +229,8 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev
 
 	cam->input = input_dev = input_allocate_device();
 	if (!input_dev) {
-		warn("Not enough memory for camera's input device\n");
+		dev_warn(&dev->dev,
+			 "Not enough memory for camera's input device\n");
 		return;
 	}
 
@@ -243,8 +244,9 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev
 
 	error = input_register_device(cam->input);
 	if (error) {
-		warn("Failed to register camera's input device, err: %d\n",
-		     error);
+		dev_warn(&dev->dev,
+			 "Failed to register camera's input device, err: %d\n",
+			 error);
 		input_free_device(cam->input);
 		cam->input = NULL;
 	}

+ 8 - 6
drivers/media/video/usbvideo/quickcam_messenger.c

@@ -93,7 +93,7 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
 
 	cam->input = input_dev = input_allocate_device();
 	if (!input_dev) {
-		warn("insufficient mem for cam input device");
+		dev_warn(&dev->dev, "insufficient mem for cam input device\n");
 		return;
 	}
 
@@ -107,8 +107,9 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
 
 	error = input_register_device(cam->input);
 	if (error) {
-		warn("Failed to register camera's input device, err: %d\n",
-		     error);
+		dev_warn(&dev->dev,
+			 "Failed to register camera's input device, err: %d\n",
+			 error);
 		input_free_device(cam->input);
 		cam->input = NULL;
 	}
@@ -587,8 +588,9 @@ static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb)
 			dataurb->iso_frame_desc[i].offset;
 
 		if (st < 0) {
-			warn("Data error: packet=%d. len=%d. status=%d.",
-			      i, n, st);
+			dev_warn(&uvd->dev->dev,
+				 "Data error: packet=%d. len=%d. status=%d.\n",
+				 i, n, st);
 			uvd->stats.iso_err_count++;
 			continue;
 		}
@@ -699,7 +701,7 @@ static void qcm_stop_data(struct uvd *uvd)
 
 	ret = qcm_camera_off(uvd);
 	if (ret)
-		warn("couldn't turn the cam off.");
+		dev_warn(&uvd->dev->dev, "couldn't turn the cam off.\n");
 
 	uvd->streaming = 0;
 

+ 2 - 2
drivers/mtd/nand/alauda.c

@@ -691,7 +691,7 @@ static int alauda_probe(struct usb_interface *interface,
 	al[0].port = ALAUDA_PORT_XD;
 	al[1].port = ALAUDA_PORT_SM;
 
-	info("alauda probed");
+	dev_info(&interface->dev, "alauda probed\n");
 	alauda_check_media(al);
 	alauda_check_media(al+1);
 
@@ -716,7 +716,7 @@ static void alauda_disconnect(struct usb_interface *interface)
 	if (al)
 		kref_put(&al->kref, alauda_delete);
 
-	info("alauda gone");
+	dev_info(&interface->dev, "alauda gone");
 }
 
 static struct usb_driver alauda_driver = {

+ 2 - 1
drivers/net/irda/kingsun-sir.c

@@ -540,7 +540,8 @@ static int kingsun_probe(struct usb_interface *intf,
 	if (ret != 0)
 		goto free_mem;
 
-	info("IrDA: Registered KingSun/DonShine device %s", net->name);
+	dev_info(&net->dev, "IrDA: Registered KingSun/DonShine device %s\n",
+		 net->name);
 
 	usb_set_intfdata(intf, kingsun);
 

+ 2 - 1
drivers/net/irda/ks959-sir.c

@@ -801,7 +801,8 @@ static int ks959_probe(struct usb_interface *intf,
 	if (ret != 0)
 		goto free_mem;
 
-	info("IrDA: Registered KingSun KS-959 device %s", net->name);
+	dev_info(&net->dev, "IrDA: Registered KingSun KS-959 device %s\n",
+		 net->name);
 
 	usb_set_intfdata(intf, kingsun);
 

+ 2 - 1
drivers/net/irda/ksdazzle-sir.c

@@ -705,7 +705,8 @@ static int ksdazzle_probe(struct usb_interface *intf,
 	if (ret != 0)
 		goto free_mem;
 
-	info("IrDA: Registered KingSun/Dazzle device %s", net->name);
+	dev_info(&net->dev, "IrDA: Registered KingSun/Dazzle device %s\n",
+		 net->name);
 
 	usb_set_intfdata(intf, kingsun);
 

+ 10 - 8
drivers/net/irda/stir4200.c

@@ -506,7 +506,7 @@ static int change_speed(struct stir_cb *stir, unsigned speed)
 			goto found;
 	}
 
-	warn("%s: invalid speed %d", stir->netdev->name, speed);
+	dev_warn(&stir->netdev->dev, "invalid speed %d\n", speed);
 	return -EINVAL;
 
  found:
@@ -598,8 +598,8 @@ static int fifo_txwait(struct stir_cb *stir, int space)
 		err = read_reg(stir, REG_FIFOCTL, stir->fifo_status, 
 				   FIFO_REGS_SIZE);
 		if (unlikely(err != FIFO_REGS_SIZE)) {
-			warn("%s: FIFO register read error: %d", 
-			     stir->netdev->name, err);
+			dev_warn(&stir->netdev->dev,
+				 "FIFO register read error: %d\n", err);
 
 			return err;
 		}
@@ -783,8 +783,9 @@ static int stir_transmit_thread(void *arg)
 
 			if (unlikely(receive_start(stir))) {
 				if (net_ratelimit())
-					info("%s: receive usb submit failed",
-					     stir->netdev->name);
+					dev_info(&dev->dev,
+						 "%s: receive usb submit failed\n",
+						 stir->netdev->name);
 				stir->receiving = 0;
 				msleep(10);
 				continue;
@@ -836,8 +837,8 @@ static void stir_rcv_irq(struct urb *urb)
 
 	/* in case of error, the kernel thread will restart us */
 	if (err) {
-		warn("%s: usb receive submit error: %d",
-			stir->netdev->name, err);
+		dev_warn(&stir->netdev->dev, "usb receive submit error: %d\n",
+			 err);
 		stir->receiving = 0;
 		wake_up_process(stir->thread);
 	}
@@ -1073,7 +1074,8 @@ static int stir_probe(struct usb_interface *intf,
 	if (ret != 0)
 		goto err_out2;
 
-	info("IrDA: Registered SigmaTel device %s", net->name);
+	dev_info(&intf->dev, "IrDA: Registered SigmaTel device %s\n",
+		 net->name);
 
 	usb_set_intfdata(intf, stir);
 

+ 5 - 3
drivers/net/usb/catc.c

@@ -456,7 +456,7 @@ static void catc_tx_timeout(struct net_device *netdev)
 {
 	struct catc *catc = netdev_priv(netdev);
 
-	warn("Transmit timed out.");
+	dev_warn(&netdev->dev, "Transmit timed out.\n");
 	usb_unlink_urb(catc->tx_urb);
 }
 
@@ -847,7 +847,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
 			dbg("64k Memory\n");
 			break;
 		default:
-			warn("Couldn't detect memory size, assuming 32k");
+			dev_warn(&intf->dev,
+				 "Couldn't detect memory size, assuming 32k\n");
 		case 0x87654321:
 			catc_set_reg(catc, TxBufCount, 4);
 			catc_set_reg(catc, RxBufCount, 16);
@@ -953,7 +954,8 @@ static int __init catc_init(void)
 {
 	int result = usb_register(&catc_driver);
 	if (result == 0)
-		info(DRIVER_VERSION " " DRIVER_DESC);
+		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+		       DRIVER_DESC "\n");
 	return result;
 }
 

+ 14 - 13
drivers/net/usb/kaweth.c

@@ -832,7 +832,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
 
 	if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC)))
 	{
-		warn("kaweth failed tx_urb %d", res);
+		dev_warn(&net->dev, "kaweth failed tx_urb %d\n", res);
 skip:
 		kaweth->stats.tx_errors++;
 
@@ -924,7 +924,7 @@ static void kaweth_tx_timeout(struct net_device *net)
 {
 	struct kaweth_device *kaweth = netdev_priv(net);
 
-	warn("%s: Tx timed out. Resetting.", net->name);
+	dev_warn(&net->dev, "%s: Tx timed out. Resetting.\n", net->name);
 	kaweth->stats.tx_errors++;
 	net->trans_start = jiffies;
 
@@ -1016,10 +1016,10 @@ static int kaweth_probe(
 	 */
 
 	if (le16_to_cpu(dev->descriptor.bcdDevice) >> 8) {
-		info("Firmware present in device.");
+		dev_info(&intf->dev, "Firmware present in device.\n");
 	} else {
 		/* Download the firmware */
-		info("Downloading firmware...");
+		dev_info(&intf->dev, "Downloading firmware...\n");
 		kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL);
 		if ((result = kaweth_download_firmware(kaweth,
 						      "kaweth/new_code.bin",
@@ -1061,7 +1061,7 @@ static int kaweth_probe(
 		}
 
 		/* Device will now disappear for a moment...  */
-		info("Firmware loaded.  I'll be back...");
+		dev_info(&intf->dev, "Firmware loaded.  I'll be back...\n");
 err_fw:
 		free_page((unsigned long)kaweth->firmware_buf);
 		free_netdev(netdev);
@@ -1075,10 +1075,10 @@ err_fw:
 		goto err_free_netdev;
 	}
 
-	info("Statistics collection: %x", kaweth->configuration.statistics_mask);
-	info("Multicast filter limit: %x", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1));
-	info("MTU: %d", le16_to_cpu(kaweth->configuration.segment_size));
-	info("Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
+	dev_info(&intf->dev, "Statistics collection: %x\n", kaweth->configuration.statistics_mask);
+	dev_info(&intf->dev, "Multicast filter limit: %x\n", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1));
+	dev_info(&intf->dev, "MTU: %d\n", le16_to_cpu(kaweth->configuration.segment_size));
+	dev_info(&intf->dev, "Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
 		 (int)kaweth->configuration.hw_addr[0],
 		 (int)kaweth->configuration.hw_addr[1],
 		 (int)kaweth->configuration.hw_addr[2],
@@ -1174,7 +1174,8 @@ err_fw:
 		goto err_intfdata;
 	}
 
-	info("kaweth interface created at %s", kaweth->net->name);
+	dev_info(&intf->dev, "kaweth interface created at %s\n",
+		 kaweth->net->name);
 
 	dbg("Kaweth probe returning.");
 
@@ -1205,11 +1206,11 @@ static void kaweth_disconnect(struct usb_interface *intf)
 	struct kaweth_device *kaweth = usb_get_intfdata(intf);
 	struct net_device *netdev;
 
-	info("Unregistering");
+	dev_info(&intf->dev, "Unregistering\n");
 
 	usb_set_intfdata(intf, NULL);
 	if (!kaweth) {
-		warn("unregistering non-existant device");
+		dev_warn(&intf->dev, "unregistering non-existant device\n");
 		return;
 	}
 	netdev = kaweth->net;
@@ -1269,7 +1270,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
 
 	if (!wait_event_timeout(awd.wqh, awd.done, timeout)) {
                 // timeout
-                warn("usb_control/bulk_msg: timeout");
+                dev_warn(&urb->dev->dev, "usb_control/bulk_msg: timeout\n");
                 usb_kill_urb(urb);  // remove urb safely
                 status = -ETIMEDOUT;
         }

+ 17 - 14
drivers/net/usb/rtl8150.c

@@ -221,7 +221,7 @@ static void ctrl_callback(struct urb *urb)
 	case -ENOENT:
 		break;
 	default:
-		warn("ctrl urb status %d", urb->status);
+		dev_warn(&urb->dev->dev, "ctrl urb status %d\n", urb->status);
 	}
 	dev = urb->context;
 	clear_bit(RX_REG_SET, &dev->flags);
@@ -441,10 +441,10 @@ static void read_bulk_callback(struct urb *urb)
 	case -ENOENT:
 		return;	/* the urb is in unlink state */
 	case -ETIME:
-		warn("may be reset is needed?..");
+		dev_warn(&urb->dev->dev, "may be reset is needed?..\n");
 		goto goon;
 	default:
-		warn("Rx status %d", urb->status);
+		dev_warn(&urb->dev->dev, "Rx status %d\n", urb->status);
 		goto goon;
 	}
 
@@ -538,7 +538,8 @@ static void write_bulk_callback(struct urb *urb)
 	if (!netif_device_present(dev->netdev))
 		return;
 	if (urb->status)
-		info("%s: Tx status %d", dev->netdev->name, urb->status);
+		dev_info(&urb->dev->dev, "%s: Tx status %d\n",
+			 dev->netdev->name, urb->status);
 	dev->netdev->trans_start = jiffies;
 	netif_wake_queue(dev->netdev);
 }
@@ -561,7 +562,8 @@ static void intr_callback(struct urb *urb)
 		return;
 	/* -EPIPE:  should clear the halt */
 	default:
-		info("%s: intr status %d", dev->netdev->name, urb->status);
+		dev_info(&urb->dev->dev, "%s: intr status %d\n",
+			 dev->netdev->name, urb->status);
 		goto resubmit;
 	}
 
@@ -665,7 +667,7 @@ static int enable_net_traffic(rtl8150_t * dev)
 	u8 cr, tcr, rcr, msr;
 
 	if (!rtl8150_reset(dev)) {
-		warn("%s - device reset failed", __FUNCTION__);
+		dev_warn(&dev->udev->dev, "device reset failed\n");
 	}
 	/* RCR bit7=1 attach Rx info at the end;  =0 HW CRC (which is broken) */
 	rcr = 0x9e;
@@ -699,7 +701,7 @@ static struct net_device_stats *rtl8150_netdev_stats(struct net_device *dev)
 static void rtl8150_tx_timeout(struct net_device *netdev)
 {
 	rtl8150_t *dev = netdev_priv(netdev);
-	warn("%s: Tx timeout.", netdev->name);
+	dev_warn(&netdev->dev, "Tx timeout.\n");
 	usb_unlink_urb(dev->tx_urb);
 	dev->stats.tx_errors++;
 }
@@ -710,12 +712,12 @@ static void rtl8150_set_multicast(struct net_device *netdev)
 	netif_stop_queue(netdev);
 	if (netdev->flags & IFF_PROMISC) {
 		dev->rx_creg |= cpu_to_le16(0x0001);
-		info("%s: promiscuous mode", netdev->name);
+		dev_info(&netdev->dev, "%s: promiscuous mode\n", netdev->name);
 	} else if (netdev->mc_count ||
 		   (netdev->flags & IFF_ALLMULTI)) {
 		dev->rx_creg &= cpu_to_le16(0xfffe);
 		dev->rx_creg |= cpu_to_le16(0x0002);
-		info("%s: allmulti set", netdev->name);
+		dev_info(&netdev->dev, "%s: allmulti set\n", netdev->name);
 	} else {
 		/* ~RX_MULTICAST, ~RX_PROMISCUOUS */
 		dev->rx_creg &= cpu_to_le16(0x00fc);
@@ -740,7 +742,7 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 		if (res == -ENODEV)
 			netif_device_detach(dev->netdev);
 		else {
-			warn("failed tx_urb %d\n", res);
+			dev_warn(&netdev->dev, "failed tx_urb %d\n", res);
 			dev->stats.tx_errors++;
 			netif_start_queue(netdev);
 		}
@@ -783,7 +785,7 @@ static int rtl8150_open(struct net_device *netdev)
 	if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) {
 		if (res == -ENODEV)
 			netif_device_detach(dev->netdev);
-		warn("%s: rx_urb submit failed: %d", __FUNCTION__, res);
+		dev_warn(&netdev->dev, "rx_urb submit failed: %d\n", res);
 		return res;
 	}
 	usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3),
@@ -792,7 +794,7 @@ static int rtl8150_open(struct net_device *netdev)
 	if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) {
 		if (res == -ENODEV)
 			netif_device_detach(dev->netdev);
-		warn("%s: intr_urb submit failed: %d", __FUNCTION__, res);
+		dev_warn(&netdev->dev, "intr_urb submit failed: %d\n", res);
 		usb_kill_urb(dev->rx_urb);
 		return res;
 	}
@@ -947,7 +949,7 @@ static int rtl8150_probe(struct usb_interface *intf,
 		goto out2;
 	}
 
-	info("%s: rtl8150 is detected", netdev->name);
+	dev_info(&intf->dev, "%s: rtl8150 is detected\n", netdev->name);
 
 	return 0;
 
@@ -984,7 +986,8 @@ static void rtl8150_disconnect(struct usb_interface *intf)
 
 static int __init usb_rtl8150_init(void)
 {
-	info(DRIVER_DESC " " DRIVER_VERSION);
+	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+	       DRIVER_DESC "\n");
 	return usb_register(&rtl8150_driver);
 }
 

+ 5 - 5
drivers/usb/atm/usbatm.c

@@ -344,7 +344,7 @@ static void usbatm_extract_one_cell(struct usbatm_data *instance, unsigned char
 				__func__, sarb->len, vcc);
 		/* discard cells already received */
 		skb_trim(sarb, 0);
-		UDSL_ASSERT(sarb->tail + ATM_CELL_PAYLOAD <= sarb->end);
+		UDSL_ASSERT(instance, sarb->tail + ATM_CELL_PAYLOAD <= sarb->end);
 	}
 
 	memcpy(skb_tail_pointer(sarb), source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
@@ -432,7 +432,7 @@ static void usbatm_extract_cells(struct usbatm_data *instance,
 		unsigned char *cell_buf = instance->cell_buf;
 		unsigned int space_left = stride - buf_usage;
 
-		UDSL_ASSERT(buf_usage <= stride);
+		UDSL_ASSERT(instance, buf_usage <= stride);
 
 		if (avail_data >= space_left) {
 			/* add new data and process cell */
@@ -475,7 +475,7 @@ static unsigned int usbatm_write_cells(struct usbatm_data *instance,
 	unsigned int stride = instance->tx_channel.stride;
 
 	vdbg("%s: skb->len=%d, avail_space=%u", __func__, skb->len, avail_space);
-	UDSL_ASSERT(!(avail_space % stride));
+	UDSL_ASSERT(instance, !(avail_space % stride));
 
 	for (bytes_written = 0; bytes_written < avail_space && ctrl->len;
 	     bytes_written += stride, target += stride) {
@@ -547,7 +547,7 @@ static void usbatm_rx_process(unsigned long data)
 				if (!urb->iso_frame_desc[i].status) {
 					unsigned int actual_length = urb->iso_frame_desc[i].actual_length;
 
-					UDSL_ASSERT(actual_length <= packet_size);
+					UDSL_ASSERT(instance, actual_length <= packet_size);
 
 					if (!merge_length)
 						merge_start = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
@@ -1188,7 +1188,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
 		struct urb *urb;
 		unsigned int iso_packets = usb_pipeisoc(channel->endpoint) ? channel->buf_size / channel->packet_size : 0;
 
-		UDSL_ASSERT(!usb_pipeisoc(channel->endpoint) || usb_pipein(channel->endpoint));
+		UDSL_ASSERT(instance, !usb_pipeisoc(channel->endpoint) || usb_pipein(channel->endpoint));
 
 		urb = usb_alloc_urb(iso_packets, GFP_KERNEL);
 		if (!urb) {

+ 8 - 2
drivers/usb/atm/usbatm.h

@@ -40,9 +40,15 @@
 */
 
 #ifdef DEBUG
-#define UDSL_ASSERT(x)	BUG_ON(!(x))
+#define UDSL_ASSERT(instance, x)	BUG_ON(!(x))
 #else
-#define UDSL_ASSERT(x)	do { if (!(x)) warn("failed assertion '%s' at line %d", __stringify(x), __LINE__); } while(0)
+#define UDSL_ASSERT(instance, x)					\
+	do {	\
+		if (!(x))						\
+			dev_warn(&(instance)->usb_intf->dev,		\
+				 "failed assertion '%s' at line %d",	\
+				 __stringify(x), __LINE__);		\
+	} while(0)
 #endif
 
 #define usb_err(instance, format, arg...)	\

+ 1 - 1
drivers/usb/atm/xusbatm.c

@@ -193,7 +193,7 @@ static int __init xusbatm_init(void)
 	    num_vendor != num_product ||
 	    num_vendor != num_rx_endpoint ||
 	    num_vendor != num_tx_endpoint) {
-		warn("malformed module parameters");
+		printk(KERN_WARNING "xusbatm: malformed module parameters\n");
 		return -EINVAL;
 	}
 

+ 10 - 0
drivers/usb/class/Kconfig

@@ -40,3 +40,13 @@ config USB_WDM
 	  To compile this driver as a module, choose M here: the
 	  module will be called cdc-wdm.
 
+config USB_TMC
+	tristate "USB Test and Measurement Class support"
+	depends on USB
+	help
+	  Say Y here if you want to connect a USB device that follows
+	  the USB.org specification for USB Test and Measurement devices
+	  to your computer's USB port.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called usbtmc.

+ 1 - 0
drivers/usb/class/Makefile

@@ -6,3 +6,4 @@
 obj-$(CONFIG_USB_ACM)		+= cdc-acm.o
 obj-$(CONFIG_USB_PRINTER)	+= usblp.o
 obj-$(CONFIG_USB_WDM)		+= cdc-wdm.o
+obj-$(CONFIG_USB_TMC)		+= usbtmc.o

+ 16 - 10
drivers/usb/class/cdc-acm.c

@@ -326,8 +326,8 @@ exit:
 	usb_mark_last_busy(acm->dev);
 	retval = usb_submit_urb (urb, GFP_ATOMIC);
 	if (retval)
-		err ("%s - usb_submit_urb failed with result %d",
-		     __func__, retval);
+		dev_err(&urb->dev->dev, "%s - usb_submit_urb failed with "
+			"result %d", __func__, retval);
 }
 
 /* data interface returns incoming bytes, or we got unthrottled */
@@ -514,7 +514,7 @@ static void acm_waker(struct work_struct *waker)
 
 	rv = usb_autopm_get_interface(acm->control);
 	if (rv < 0) {
-		err("Autopm failure in %s", __func__);
+		dev_err(&acm->dev->dev, "Autopm failure in %s\n", __func__);
 		return;
 	}
 	if (acm->delayed_wb) {
@@ -924,7 +924,7 @@ static int acm_probe (struct usb_interface *intf,
 	
 	/* normal probing*/
 	if (!buffer) {
-		err("Weird descriptor references\n");
+		dev_err(&intf->dev, "Weird descriptor references\n");
 		return -EINVAL;
 	}
 
@@ -934,21 +934,24 @@ static int acm_probe (struct usb_interface *intf,
 			buflen = intf->cur_altsetting->endpoint->extralen;
 			buffer = intf->cur_altsetting->endpoint->extra;
 		} else {
-			err("Zero length descriptor references\n");
+			dev_err(&intf->dev,
+				"Zero length descriptor references\n");
 			return -EINVAL;
 		}
 	}
 
 	while (buflen > 0) {
 		if (buffer [1] != USB_DT_CS_INTERFACE) {
-			err("skipping garbage\n");
+			dev_err(&intf->dev, "skipping garbage\n");
 			goto next_desc;
 		}
 
 		switch (buffer [2]) {
 			case USB_CDC_UNION_TYPE: /* we've found it */
 				if (union_header) {
-					err("More than one union descriptor, skipping ...");
+					dev_err(&intf->dev, "More than one "
+						"union descriptor, "
+						"skipping ...\n");
 					goto next_desc;
 				}
 				union_header = (struct usb_cdc_union_desc *)
@@ -966,7 +969,9 @@ static int acm_probe (struct usb_interface *intf,
 				call_management_function = buffer[3];
 				call_interface_num = buffer[4];
 				if ((call_management_function & 3) != 3)
-					err("This device cannot do calls on its own. It is no modem.");
+					dev_err(&intf->dev, "This device "
+						"cannot do calls on its own. "
+						"It is no modem.\n");
 				break;
 			default:
 				/* there are LOTS more CDC descriptors that
@@ -1051,7 +1056,7 @@ skip_normal_probe:
 	for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
 
 	if (minor == ACM_TTY_MINORS) {
-		err("no more free acm devices");
+		dev_err(&intf->dev, "no more free acm devices\n");
 		return -ENODEV;
 	}
 
@@ -1454,7 +1459,8 @@ static int __init acm_init(void)
 		return retval;
 	}
 
-	info(DRIVER_VERSION ":" DRIVER_DESC);
+	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+	       DRIVER_DESC "\n");
 
 	return 0;
 }

+ 30 - 18
drivers/usb/class/cdc-wdm.c

@@ -132,10 +132,12 @@ static void wdm_in_callback(struct urb *urb)
 				"nonzero urb status received: -ESHUTDOWN");
 			break;
 		case -EPIPE:
-			err("nonzero urb status received: -EPIPE");
+			dev_err(&desc->intf->dev,
+				"nonzero urb status received: -EPIPE\n");
 			break;
 		default:
-			err("Unexpected error %d", status);
+			dev_err(&desc->intf->dev,
+				"Unexpected error %d\n", status);
 			break;
 		}
 	}
@@ -170,16 +172,18 @@ static void wdm_int_callback(struct urb *urb)
 			return; /* unplug */
 		case -EPIPE:
 			set_bit(WDM_INT_STALL, &desc->flags);
-			err("Stall on int endpoint");
+			dev_err(&desc->intf->dev, "Stall on int endpoint\n");
 			goto sw; /* halt is cleared in work */
 		default:
-			err("nonzero urb status received: %d", status);
+			dev_err(&desc->intf->dev,
+				"nonzero urb status received: %d\n", status);
 			break;
 		}
 	}
 
 	if (urb->actual_length < sizeof(struct usb_cdc_notification)) {
-		err("wdm_int_callback - %d bytes", urb->actual_length);
+		dev_err(&desc->intf->dev, "wdm_int_callback - %d bytes\n",
+			urb->actual_length);
 		goto exit;
 	}
 
@@ -198,7 +202,8 @@ static void wdm_int_callback(struct urb *urb)
 		goto exit;
 	default:
 		clear_bit(WDM_POLL_RUNNING, &desc->flags);
-		err("unknown notification %d received: index %d len %d",
+		dev_err(&desc->intf->dev,
+			"unknown notification %d received: index %d len %d\n",
 			dr->bNotificationType, dr->wIndex, dr->wLength);
 		goto exit;
 	}
@@ -236,14 +241,16 @@ static void wdm_int_callback(struct urb *urb)
 sw:
 			rv = schedule_work(&desc->rxwork);
 			if (rv)
-				err("Cannot schedule work");
+				dev_err(&desc->intf->dev,
+					"Cannot schedule work\n");
 		}
 	}
 exit:
 	rv = usb_submit_urb(urb, GFP_ATOMIC);
 	if (rv)
-		err("%s - usb_submit_urb failed with result %d",
-		     __func__, rv);
+		dev_err(&desc->intf->dev,
+			"%s - usb_submit_urb failed with result %d\n",
+			__func__, rv);
 
 }
 
@@ -353,7 +360,7 @@ static ssize_t wdm_write
 	if (rv < 0) {
 		kfree(buf);
 		clear_bit(WDM_IN_USE, &desc->flags);
-		err("Tx URB error: %d", rv);
+		dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);
 	} else {
 		dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d",
 			req->wIndex);
@@ -401,7 +408,8 @@ retry:
 			int t = desc->rerr;
 			desc->rerr = 0;
 			spin_unlock_irq(&desc->iuspin);
-			err("reading had resulted in %d", t);
+			dev_err(&desc->intf->dev,
+				"reading had resulted in %d\n", t);
 			rv = -EIO;
 			goto err;
 		}
@@ -440,7 +448,7 @@ retry:
 err:
 	mutex_unlock(&desc->rlock);
 	if (rv < 0)
-		err("wdm_read: exit error");
+		dev_err(&desc->intf->dev, "wdm_read: exit error\n");
 	return rv;
 }
 
@@ -450,7 +458,8 @@ static int wdm_flush(struct file *file, fl_owner_t id)
 
 	wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags));
 	if (desc->werr < 0)
-		err("Error in flush path: %d", desc->werr);
+		dev_err(&desc->intf->dev, "Error in flush path: %d\n",
+			desc->werr);
 
 	return desc->werr;
 }
@@ -502,7 +511,7 @@ static int wdm_open(struct inode *inode, struct file *file)
 
 	rv = usb_autopm_get_interface(desc->intf);
 	if (rv < 0) {
-		err("Error autopm - %d", rv);
+		dev_err(&desc->intf->dev, "Error autopm - %d\n", rv);
 		goto out;
 	}
 	intf->needs_remote_wakeup = 1;
@@ -512,7 +521,8 @@ static int wdm_open(struct inode *inode, struct file *file)
 		rv = usb_submit_urb(desc->validity, GFP_KERNEL);
 		if (rv < 0) {
 			desc->count--;
-			err("Error submitting int urb - %d", rv);
+			dev_err(&desc->intf->dev,
+				"Error submitting int urb - %d\n", rv);
 		}
 	} else {
 		rv = 0;
@@ -600,7 +610,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
 	while (buflen > 0) {
 		if (buffer [1] != USB_DT_CS_INTERFACE) {
-			err("skipping garbage");
+			dev_err(&intf->dev, "skipping garbage\n");
 			goto next_desc;
 		}
 
@@ -614,7 +624,8 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
 				"Finding maximum buffer length: %d", maxcom);
 			break;
 		default:
-			err("Ignoring extra header, type %d, length %d",
+			dev_err(&intf->dev,
+				"Ignoring extra header, type %d, length %d\n",
 				buffer[2], buffer[0]);
 			break;
 		}
@@ -772,7 +783,8 @@ static int recover_from_urb_loss(struct wdm_device *desc)
 	if (desc->count) {
 		rv = usb_submit_urb(desc->validity, GFP_NOIO);
 		if (rv < 0)
-			err("Error resume submitting int urb - %d", rv);
+			dev_err(&desc->intf->dev,
+				"Error resume submitting int urb - %d\n", rv);
 	}
 	return rv;
 }

+ 13 - 12
drivers/usb/class/usblp.c

@@ -593,8 +593,9 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 				err = usblp_hp_channel_change_request(usblp,
 					arg, &newChannel);
 				if (err < 0) {
-					err("usblp%d: error = %d setting "
-						"HP channel",
+					dev_err(&usblp->dev->dev,
+						"usblp%d: error = %d setting "
+						"HP channel\n",
 						usblp->minor, err);
 					retval = -EIO;
 					goto done;
@@ -1076,15 +1077,16 @@ static int usblp_probe(struct usb_interface *intf,
 		       const struct usb_device_id *id)
 {
 	struct usb_device *dev = interface_to_usbdev (intf);
-	struct usblp *usblp = NULL;
+	struct usblp *usblp;
 	int protocol;
 	int retval;
 
 	/* Malloc and start initializing usblp structure so we can use it
 	 * directly. */
-	if (!(usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL))) {
+	usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL);
+	if (!usblp) {
 		retval = -ENOMEM;
-		goto abort;
+		goto abort_ret;
 	}
 	usblp->dev = dev;
 	mutex_init(&usblp->wmut);
@@ -1179,12 +1181,11 @@ abort_intfdata:
 	usb_set_intfdata (intf, NULL);
 	device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
 abort:
-	if (usblp) {
-		kfree(usblp->readbuf);
-		kfree(usblp->statusbuf);
-		kfree(usblp->device_id_string);
-		kfree(usblp);
-	}
+	kfree(usblp->readbuf);
+	kfree(usblp->statusbuf);
+	kfree(usblp->device_id_string);
+	kfree(usblp);
+abort_ret:
 	return retval;
 }
 
@@ -1345,7 +1346,7 @@ static void usblp_disconnect(struct usb_interface *intf)
 	usb_deregister_dev(intf, &usblp_class);
 
 	if (!usblp || !usblp->dev) {
-		err("bogus disconnect");
+		dev_err(&intf->dev, "bogus disconnect\n");
 		BUG ();
 	}
 

+ 1087 - 0
drivers/usb/class/usbtmc.c

@@ -0,0 +1,1087 @@
+/**
+ * drivers/usb/class/usbtmc.c - USB Test & Measurment class driver
+ *
+ * Copyright (C) 2007 Stefan Kopp, Gechingen, Germany
+ * Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * The GNU General Public License is available at
+ * http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/kref.h>
+#include <linux/mutex.h>
+#include <linux/usb.h>
+#include <linux/usb/tmc.h>
+
+
+#define USBTMC_MINOR_BASE	176
+
+/*
+ * Size of driver internal IO buffer. Must be multiple of 4 and at least as
+ * large as wMaxPacketSize (which is usually 512 bytes).
+ */
+#define USBTMC_SIZE_IOBUFFER	2048
+
+/* Default USB timeout (in milliseconds) */
+#define USBTMC_TIMEOUT		10
+
+/*
+ * Maximum number of read cycles to empty bulk in endpoint during CLEAR and
+ * ABORT_BULK_IN requests. Ends the loop if (for whatever reason) a short
+ * packet is never read.
+ */
+#define USBTMC_MAX_READS_TO_CLEAR_BULK_IN	100
+
+static struct usb_device_id usbtmc_devices[] = {
+	{ USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), },
+	{ 0, } /* terminating entry */
+};
+
+/*
+ * This structure is the capabilities for the device
+ * See section 4.2.1.8 of the USBTMC specification for details.
+ */
+struct usbtmc_dev_capabilities {
+	__u8 interface_capabilities;
+	__u8 device_capabilities;
+	__u8 usb488_interface_capabilities;
+	__u8 usb488_device_capabilities;
+};
+
+/* This structure holds private data for each USBTMC device. One copy is
+ * allocated for each USBTMC device in the driver's probe function.
+ */
+struct usbtmc_device_data {
+	const struct usb_device_id *id;
+	struct usb_device *usb_dev;
+	struct usb_interface *intf;
+
+	unsigned int bulk_in;
+	unsigned int bulk_out;
+
+	u8 bTag;
+	u8 bTag_last_write;	/* needed for abort */
+	u8 bTag_last_read;	/* needed for abort */
+
+	/* attributes from the USB TMC spec for this device */
+	u8 TermChar;
+	bool TermCharEnabled;
+	bool auto_abort;
+
+	struct usbtmc_dev_capabilities	capabilities;
+	struct kref kref;
+	struct mutex io_mutex;	/* only one i/o function running at a time */
+};
+#define to_usbtmc_data(d) container_of(d, struct usbtmc_device_data, kref)
+
+/* Forward declarations */
+static struct usb_driver usbtmc_driver;
+
+static void usbtmc_delete(struct kref *kref)
+{
+	struct usbtmc_device_data *data = to_usbtmc_data(kref);
+
+	usb_put_dev(data->usb_dev);
+	kfree(data);
+}
+
+static int usbtmc_open(struct inode *inode, struct file *filp)
+{
+	struct usb_interface *intf;
+	struct usbtmc_device_data *data;
+	int retval = -ENODEV;
+
+	intf = usb_find_interface(&usbtmc_driver, iminor(inode));
+	if (!intf) {
+		printk(KERN_ERR KBUILD_MODNAME
+		       ": can not find device for minor %d", iminor(inode));
+		goto exit;
+	}
+
+	data = usb_get_intfdata(intf);
+	kref_get(&data->kref);
+
+	/* Store pointer in file structure's private data field */
+	filp->private_data = data;
+
+exit:
+	return retval;
+}
+
+static int usbtmc_release(struct inode *inode, struct file *file)
+{
+	struct usbtmc_device_data *data = file->private_data;
+
+	kref_put(&data->kref, usbtmc_delete);
+	return 0;
+}
+
+static int usbtmc_ioctl_abort_bulk_in(struct usbtmc_device_data *data)
+{
+	char *buffer;
+	struct device *dev;
+	int rv;
+	int n;
+	int actual;
+	struct usb_host_interface *current_setting;
+	int max_size;
+
+	dev = &data->intf->dev;
+	buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	rv = usb_control_msg(data->usb_dev,
+			     usb_rcvctrlpipe(data->usb_dev, 0),
+			     USBTMC_REQUEST_INITIATE_ABORT_BULK_IN,
+			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
+			     data->bTag_last_read, data->bulk_in,
+			     buffer, 2, USBTMC_TIMEOUT);
+
+	if (rv < 0) {
+		dev_err(dev, "usb_control_msg returned %d\n", rv);
+		goto exit;
+	}
+
+	dev_dbg(dev, "INITIATE_ABORT_BULK_IN returned %x\n", buffer[0]);
+
+	if (buffer[0] == USBTMC_STATUS_FAILED) {
+		rv = 0;
+		goto exit;
+	}
+
+	if (buffer[0] != USBTMC_STATUS_SUCCESS) {
+		dev_err(dev, "INITIATE_ABORT_BULK_IN returned %x\n",
+			buffer[0]);
+		rv = -EPERM;
+		goto exit;
+	}
+
+	max_size = 0;
+	current_setting = data->intf->cur_altsetting;
+	for (n = 0; n < current_setting->desc.bNumEndpoints; n++)
+		if (current_setting->endpoint[n].desc.bEndpointAddress ==
+			data->bulk_in)
+			max_size = le16_to_cpu(current_setting->endpoint[n].
+						desc.wMaxPacketSize);
+
+	if (max_size == 0) {
+		dev_err(dev, "Couldn't get wMaxPacketSize\n");
+		rv = -EPERM;
+		goto exit;
+	}
+
+	dev_dbg(&data->intf->dev, "wMaxPacketSize is %d\n", max_size);
+
+	n = 0;
+
+	do {
+		dev_dbg(dev, "Reading from bulk in EP\n");
+
+		rv = usb_bulk_msg(data->usb_dev,
+				  usb_rcvbulkpipe(data->usb_dev,
+						  data->bulk_in),
+				  buffer, USBTMC_SIZE_IOBUFFER,
+				  &actual, USBTMC_TIMEOUT);
+
+		n++;
+
+		if (rv < 0) {
+			dev_err(dev, "usb_bulk_msg returned %d\n", rv);
+			goto exit;
+		}
+	} while ((actual == max_size) &&
+		 (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN));
+
+	if (actual == max_size) {
+		dev_err(dev, "Couldn't clear device buffer within %d cycles\n",
+			USBTMC_MAX_READS_TO_CLEAR_BULK_IN);
+		rv = -EPERM;
+		goto exit;
+	}
+
+	n = 0;
+
+usbtmc_abort_bulk_in_status:
+	rv = usb_control_msg(data->usb_dev,
+			     usb_rcvctrlpipe(data->usb_dev, 0),
+			     USBTMC_REQUEST_CHECK_ABORT_BULK_IN_STATUS,
+			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
+			     0, data->bulk_in, buffer, 0x08,
+			     USBTMC_TIMEOUT);
+
+	if (rv < 0) {
+		dev_err(dev, "usb_control_msg returned %d\n", rv);
+		goto exit;
+	}
+
+	dev_dbg(dev, "INITIATE_ABORT_BULK_IN returned %x\n", buffer[0]);
+
+	if (buffer[0] == USBTMC_STATUS_SUCCESS) {
+		rv = 0;
+		goto exit;
+	}
+
+	if (buffer[0] != USBTMC_STATUS_PENDING) {
+		dev_err(dev, "INITIATE_ABORT_BULK_IN returned %x\n", buffer[0]);
+		rv = -EPERM;
+		goto exit;
+	}
+
+	if (buffer[1] == 1)
+		do {
+			dev_dbg(dev, "Reading from bulk in EP\n");
+
+			rv = usb_bulk_msg(data->usb_dev,
+					  usb_rcvbulkpipe(data->usb_dev,
+							  data->bulk_in),
+					  buffer, USBTMC_SIZE_IOBUFFER,
+					  &actual, USBTMC_TIMEOUT);
+
+			n++;
+
+			if (rv < 0) {
+				dev_err(dev, "usb_bulk_msg returned %d\n", rv);
+				goto exit;
+			}
+		} while ((actual = max_size) &&
+			 (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN));
+
+	if (actual == max_size) {
+		dev_err(dev, "Couldn't clear device buffer within %d cycles\n",
+			USBTMC_MAX_READS_TO_CLEAR_BULK_IN);
+		rv = -EPERM;
+		goto exit;
+	}
+
+	goto usbtmc_abort_bulk_in_status;
+
+exit:
+	kfree(buffer);
+	return rv;
+
+}
+
+static int usbtmc_ioctl_abort_bulk_out(struct usbtmc_device_data *data)
+{
+	struct device *dev;
+	u8 *buffer;
+	int rv;
+	int n;
+
+	dev = &data->intf->dev;
+
+	buffer = kmalloc(8, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	rv = usb_control_msg(data->usb_dev,
+			     usb_rcvctrlpipe(data->usb_dev, 0),
+			     USBTMC_REQUEST_INITIATE_ABORT_BULK_OUT,
+			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
+			     data->bTag_last_write, data->bulk_out,
+			     buffer, 2, USBTMC_TIMEOUT);
+
+	if (rv < 0) {
+		dev_err(dev, "usb_control_msg returned %d\n", rv);
+		goto exit;
+	}
+
+	dev_dbg(dev, "INITIATE_ABORT_BULK_OUT returned %x\n", buffer[0]);
+
+	if (buffer[0] != USBTMC_STATUS_SUCCESS) {
+		dev_err(dev, "INITIATE_ABORT_BULK_OUT returned %x\n",
+			buffer[0]);
+		rv = -EPERM;
+		goto exit;
+	}
+
+	n = 0;
+
+usbtmc_abort_bulk_out_check_status:
+	rv = usb_control_msg(data->usb_dev,
+			     usb_rcvctrlpipe(data->usb_dev, 0),
+			     USBTMC_REQUEST_CHECK_ABORT_BULK_OUT_STATUS,
+			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
+			     0, data->bulk_out, buffer, 0x08,
+			     USBTMC_TIMEOUT);
+	n++;
+	if (rv < 0) {
+		dev_err(dev, "usb_control_msg returned %d\n", rv);
+		goto exit;
+	}
+
+	dev_dbg(dev, "CHECK_ABORT_BULK_OUT returned %x\n", buffer[0]);
+
+	if (buffer[0] == USBTMC_STATUS_SUCCESS)
+		goto usbtmc_abort_bulk_out_clear_halt;
+
+	if ((buffer[0] == USBTMC_STATUS_PENDING) &&
+	    (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN))
+		goto usbtmc_abort_bulk_out_check_status;
+
+	rv = -EPERM;
+	goto exit;
+
+usbtmc_abort_bulk_out_clear_halt:
+	rv = usb_control_msg(data->usb_dev,
+			     usb_sndctrlpipe(data->usb_dev, 0),
+			     USB_REQ_CLEAR_FEATURE,
+			     USB_DIR_OUT | USB_TYPE_STANDARD |
+			     USB_RECIP_ENDPOINT,
+			     USB_ENDPOINT_HALT, data->bulk_out, buffer,
+			     0, USBTMC_TIMEOUT);
+
+	if (rv < 0) {
+		dev_err(dev, "usb_control_msg returned %d\n", rv);
+		goto exit;
+	}
+	rv = 0;
+
+exit:
+	kfree(buffer);
+	return rv;
+}
+
+static ssize_t usbtmc_read(struct file *filp, char __user *buf,
+			   size_t count, loff_t *f_pos)
+{
+	struct usbtmc_device_data *data;
+	struct device *dev;
+	unsigned long int n_characters;
+	u8 *buffer;
+	int actual;
+	int done;
+	int remaining;
+	int retval;
+	int this_part;
+
+	/* Get pointer to private data structure */
+	data = filp->private_data;
+	dev = &data->intf->dev;
+
+	buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	mutex_lock(&data->io_mutex);
+
+	remaining = count;
+	done = 0;
+
+	while (remaining > 0) {
+		if (remaining > USBTMC_SIZE_IOBUFFER - 12 - 3)
+			this_part = USBTMC_SIZE_IOBUFFER - 12 - 3;
+		else
+			this_part = remaining;
+
+		/* Setup IO buffer for DEV_DEP_MSG_IN message
+		 * Refer to class specs for details
+		 */
+		buffer[0] = 2;
+		buffer[1] = data->bTag;
+		buffer[2] = ~(data->bTag);
+		buffer[3] = 0; /* Reserved */
+		buffer[4] = (this_part - 12 - 3) & 255;
+		buffer[5] = ((this_part - 12 - 3) >> 8) & 255;
+		buffer[6] = ((this_part - 12 - 3) >> 16) & 255;
+		buffer[7] = ((this_part - 12 - 3) >> 24) & 255;
+		buffer[8] = data->TermCharEnabled * 2;
+		/* Use term character? */
+		buffer[9] = data->TermChar;
+		buffer[10] = 0; /* Reserved */
+		buffer[11] = 0; /* Reserved */
+
+		/* Send bulk URB */
+		retval = usb_bulk_msg(data->usb_dev,
+				      usb_sndbulkpipe(data->usb_dev,
+						      data->bulk_out),
+				      buffer, 12, &actual, USBTMC_TIMEOUT);
+
+		/* Store bTag (in case we need to abort) */
+		data->bTag_last_write = data->bTag;
+
+		/* Increment bTag -- and increment again if zero */
+		data->bTag++;
+		if (!data->bTag)
+			(data->bTag)++;
+
+		if (retval < 0) {
+			dev_err(dev, "usb_bulk_msg returned %d\n", retval);
+			if (data->auto_abort)
+				usbtmc_ioctl_abort_bulk_out(data);
+			goto exit;
+		}
+
+		/* Send bulk URB */
+		retval = usb_bulk_msg(data->usb_dev,
+				      usb_rcvbulkpipe(data->usb_dev,
+						      data->bulk_in),
+				      buffer, USBTMC_SIZE_IOBUFFER, &actual,
+				      USBTMC_TIMEOUT);
+
+		/* Store bTag (in case we need to abort) */
+		data->bTag_last_read = data->bTag;
+
+		if (retval < 0) {
+			dev_err(dev, "Unable to read data, error %d\n", retval);
+			if (data->auto_abort)
+				usbtmc_ioctl_abort_bulk_in(data);
+			goto exit;
+		}
+
+		/* How many characters did the instrument send? */
+		n_characters = buffer[4] +
+			       (buffer[5] << 8) +
+			       (buffer[6] << 16) +
+			       (buffer[7] << 24);
+
+		/* Copy buffer to user space */
+		if (copy_to_user(buf + done, &buffer[12], n_characters)) {
+			/* There must have been an addressing problem */
+			retval = -EFAULT;
+			goto exit;
+		}
+
+		done += n_characters;
+		if (n_characters < USBTMC_SIZE_IOBUFFER)
+			remaining = 0;
+	}
+
+	/* Update file position value */
+	*f_pos = *f_pos + done;
+	retval = done;
+
+exit:
+	mutex_unlock(&data->io_mutex);
+	kfree(buffer);
+	return retval;
+}
+
+static ssize_t usbtmc_write(struct file *filp, const char __user *buf,
+			    size_t count, loff_t *f_pos)
+{
+	struct usbtmc_device_data *data;
+	u8 *buffer;
+	int retval;
+	int actual;
+	unsigned long int n_bytes;
+	int n;
+	int remaining;
+	int done;
+	int this_part;
+
+	data = filp->private_data;
+
+	buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	mutex_lock(&data->io_mutex);
+
+	remaining = count;
+	done = 0;
+
+	while (remaining > 0) {
+		if (remaining > USBTMC_SIZE_IOBUFFER - 12) {
+			this_part = USBTMC_SIZE_IOBUFFER - 12;
+			buffer[8] = 0;
+		} else {
+			this_part = remaining;
+			buffer[8] = 1;
+		}
+
+		/* Setup IO buffer for DEV_DEP_MSG_OUT message */
+		buffer[0] = 1;
+		buffer[1] = data->bTag;
+		buffer[2] = ~(data->bTag);
+		buffer[3] = 0; /* Reserved */
+		buffer[4] = this_part & 255;
+		buffer[5] = (this_part >> 8) & 255;
+		buffer[6] = (this_part >> 16) & 255;
+		buffer[7] = (this_part >> 24) & 255;
+		/* buffer[8] is set above... */
+		buffer[9] = 0; /* Reserved */
+		buffer[10] = 0; /* Reserved */
+		buffer[11] = 0; /* Reserved */
+
+		if (copy_from_user(&buffer[12], buf + done, this_part)) {
+			retval = -EFAULT;
+			goto exit;
+		}
+
+		n_bytes = 12 + this_part;
+		if (this_part % 4)
+			n_bytes += 4 - this_part % 4;
+			for (n = 12 + this_part; n < n_bytes; n++)
+				buffer[n] = 0;
+
+		retval = usb_bulk_msg(data->usb_dev,
+				      usb_sndbulkpipe(data->usb_dev,
+						      data->bulk_out),
+				      buffer, n_bytes, &actual, USBTMC_TIMEOUT);
+
+		data->bTag_last_write = data->bTag;
+		data->bTag++;
+
+		if (!data->bTag)
+			data->bTag++;
+
+		if (retval < 0) {
+			dev_err(&data->intf->dev,
+				"Unable to send data, error %d\n", retval);
+			if (data->auto_abort)
+				usbtmc_ioctl_abort_bulk_out(data);
+			goto exit;
+		}
+
+		remaining -= this_part;
+		done += this_part;
+	}
+
+	retval = count;
+exit:
+	mutex_unlock(&data->io_mutex);
+	kfree(buffer);
+	return retval;
+}
+
+static int usbtmc_ioctl_clear(struct usbtmc_device_data *data)
+{
+	struct usb_host_interface *current_setting;
+	struct usb_endpoint_descriptor *desc;
+	struct device *dev;
+	u8 *buffer;
+	int rv;
+	int n;
+	int actual;
+	int max_size;
+
+	dev = &data->intf->dev;
+
+	dev_dbg(dev, "Sending INITIATE_CLEAR request\n");
+
+	buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	rv = usb_control_msg(data->usb_dev,
+			     usb_rcvctrlpipe(data->usb_dev, 0),
+			     USBTMC_REQUEST_INITIATE_CLEAR,
+			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+			     0, 0, buffer, 1, USBTMC_TIMEOUT);
+	if (rv < 0) {
+		dev_err(dev, "usb_control_msg returned %d\n", rv);
+		goto exit;
+	}
+
+	dev_dbg(dev, "INITIATE_CLEAR returned %x\n", buffer[0]);
+
+	if (buffer[0] != USBTMC_STATUS_SUCCESS) {
+		dev_err(dev, "INITIATE_CLEAR returned %x\n", buffer[0]);
+		rv = -EPERM;
+		goto exit;
+	}
+
+	max_size = 0;
+	current_setting = data->intf->cur_altsetting;
+	for (n = 0; n < current_setting->desc.bNumEndpoints; n++) {
+		desc = &current_setting->endpoint[n].desc;
+		if (desc->bEndpointAddress == data->bulk_in)
+			max_size = le16_to_cpu(desc->wMaxPacketSize);
+	}
+
+	if (max_size == 0) {
+		dev_err(dev, "Couldn't get wMaxPacketSize\n");
+		rv = -EPERM;
+		goto exit;
+	}
+
+	dev_dbg(dev, "wMaxPacketSize is %d\n", max_size);
+
+	n = 0;
+
+usbtmc_clear_check_status:
+
+	dev_dbg(dev, "Sending CHECK_CLEAR_STATUS request\n");
+
+	rv = usb_control_msg(data->usb_dev,
+			     usb_rcvctrlpipe(data->usb_dev, 0),
+			     USBTMC_REQUEST_CHECK_CLEAR_STATUS,
+			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+			     0, 0, buffer, 2, USBTMC_TIMEOUT);
+	if (rv < 0) {
+		dev_err(dev, "usb_control_msg returned %d\n", rv);
+		goto exit;
+	}
+
+	dev_dbg(dev, "CHECK_CLEAR_STATUS returned %x\n", buffer[0]);
+
+	if (buffer[0] == USBTMC_STATUS_SUCCESS)
+		goto usbtmc_clear_bulk_out_halt;
+
+	if (buffer[0] != USBTMC_STATUS_PENDING) {
+		dev_err(dev, "CHECK_CLEAR_STATUS returned %x\n", buffer[0]);
+		rv = -EPERM;
+		goto exit;
+	}
+
+	if (buffer[1] == 1)
+		do {
+			dev_dbg(dev, "Reading from bulk in EP\n");
+
+			rv = usb_bulk_msg(data->usb_dev,
+					  usb_rcvbulkpipe(data->usb_dev,
+							  data->bulk_in),
+					  buffer, USBTMC_SIZE_IOBUFFER,
+					  &actual, USBTMC_TIMEOUT);
+			n++;
+
+			if (rv < 0) {
+				dev_err(dev, "usb_control_msg returned %d\n",
+					rv);
+				goto exit;
+			}
+		} while ((actual == max_size) &&
+			  (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN));
+
+	if (actual == max_size) {
+		dev_err(dev, "Couldn't clear device buffer within %d cycles\n",
+			USBTMC_MAX_READS_TO_CLEAR_BULK_IN);
+		rv = -EPERM;
+		goto exit;
+	}
+
+	goto usbtmc_clear_check_status;
+
+usbtmc_clear_bulk_out_halt:
+
+	rv = usb_control_msg(data->usb_dev,
+			     usb_sndctrlpipe(data->usb_dev, 0),
+			     USB_REQ_CLEAR_FEATURE,
+			     USB_DIR_OUT | USB_TYPE_STANDARD |
+			     USB_RECIP_ENDPOINT,
+			     USB_ENDPOINT_HALT,
+			     data->bulk_out, buffer, 0,
+			     USBTMC_TIMEOUT);
+	if (rv < 0) {
+		dev_err(dev, "usb_control_msg returned %d\n", rv);
+		goto exit;
+	}
+	rv = 0;
+
+exit:
+	kfree(buffer);
+	return rv;
+}
+
+static int usbtmc_ioctl_clear_out_halt(struct usbtmc_device_data *data)
+{
+	u8 *buffer;
+	int rv;
+
+	buffer = kmalloc(2, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	rv = usb_control_msg(data->usb_dev,
+			     usb_sndctrlpipe(data->usb_dev, 0),
+			     USB_REQ_CLEAR_FEATURE,
+			     USB_DIR_OUT | USB_TYPE_STANDARD |
+			     USB_RECIP_ENDPOINT,
+			     USB_ENDPOINT_HALT, data->bulk_out,
+			     buffer, 0, USBTMC_TIMEOUT);
+
+	if (rv < 0) {
+		dev_err(&data->usb_dev->dev, "usb_control_msg returned %d\n",
+			rv);
+		goto exit;
+	}
+	rv = 0;
+
+exit:
+	kfree(buffer);
+	return rv;
+}
+
+static int usbtmc_ioctl_clear_in_halt(struct usbtmc_device_data *data)
+{
+	u8 *buffer;
+	int rv;
+
+	buffer = kmalloc(2, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	rv = usb_control_msg(data->usb_dev, usb_sndctrlpipe(data->usb_dev, 0),
+			     USB_REQ_CLEAR_FEATURE,
+			     USB_DIR_OUT | USB_TYPE_STANDARD |
+			     USB_RECIP_ENDPOINT,
+			     USB_ENDPOINT_HALT, data->bulk_in, buffer, 0,
+			     USBTMC_TIMEOUT);
+
+	if (rv < 0) {
+		dev_err(&data->usb_dev->dev, "usb_control_msg returned %d\n",
+			rv);
+		goto exit;
+	}
+	rv = 0;
+
+exit:
+	kfree(buffer);
+	return rv;
+}
+
+static int get_capabilities(struct usbtmc_device_data *data)
+{
+	struct device *dev = &data->usb_dev->dev;
+	char *buffer;
+	int rv;
+
+	buffer = kmalloc(0x18, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	rv = usb_control_msg(data->usb_dev, usb_rcvctrlpipe(data->usb_dev, 0),
+			     USBTMC_REQUEST_GET_CAPABILITIES,
+			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+			     0, 0, buffer, 0x18, USBTMC_TIMEOUT);
+	if (rv < 0) {
+		dev_err(dev, "usb_control_msg returned %d\n", rv);
+		return rv;
+	}
+
+	dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]);
+	dev_dbg(dev, "Interface capabilities are %x\n", buffer[4]);
+	dev_dbg(dev, "Device capabilities are %x\n", buffer[5]);
+	dev_dbg(dev, "USB488 interface capabilities are %x\n", buffer[14]);
+	dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]);
+	if (buffer[0] != USBTMC_STATUS_SUCCESS) {
+		dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]);
+		return -EPERM;
+	}
+
+	data->capabilities.interface_capabilities = buffer[4];
+	data->capabilities.device_capabilities = buffer[5];
+	data->capabilities.usb488_interface_capabilities = buffer[14];
+	data->capabilities.usb488_device_capabilities = buffer[15];
+
+	kfree(buffer);
+	return 0;
+}
+
+#define capability_attribute(name)					\
+static ssize_t show_##name(struct device *dev,				\
+			   struct device_attribute *attr, char *buf)	\
+{									\
+	struct usb_interface *intf = to_usb_interface(dev);		\
+	struct usbtmc_device_data *data = usb_get_intfdata(intf);	\
+									\
+	return sprintf(buf, "%d\n", data->capabilities.name);		\
+}									\
+static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+
+capability_attribute(interface_capabilities);
+capability_attribute(device_capabilities);
+capability_attribute(usb488_interface_capabilities);
+capability_attribute(usb488_device_capabilities);
+
+static struct attribute *capability_attrs[] = {
+	&dev_attr_interface_capabilities.attr,
+	&dev_attr_device_capabilities.attr,
+	&dev_attr_usb488_interface_capabilities.attr,
+	&dev_attr_usb488_device_capabilities.attr,
+	NULL,
+};
+
+static struct attribute_group capability_attr_grp = {
+	.attrs = capability_attrs,
+};
+
+static ssize_t show_TermChar(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct usb_interface *intf = to_usb_interface(dev);
+	struct usbtmc_device_data *data = usb_get_intfdata(intf);
+
+	return sprintf(buf, "%c\n", data->TermChar);
+}
+
+static ssize_t store_TermChar(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	struct usb_interface *intf = to_usb_interface(dev);
+	struct usbtmc_device_data *data = usb_get_intfdata(intf);
+
+	if (count < 1)
+		return -EINVAL;
+	data->TermChar = buf[0];
+	return count;
+}
+static DEVICE_ATTR(TermChar, S_IRUGO, show_TermChar, store_TermChar);
+
+#define data_attribute(name)						\
+static ssize_t show_##name(struct device *dev,				\
+			   struct device_attribute *attr, char *buf)	\
+{									\
+	struct usb_interface *intf = to_usb_interface(dev);		\
+	struct usbtmc_device_data *data = usb_get_intfdata(intf);	\
+									\
+	return sprintf(buf, "%d\n", data->name);			\
+}									\
+static ssize_t store_##name(struct device *dev,				\
+			    struct device_attribute *attr,		\
+			    const char *buf, size_t count)		\
+{									\
+	struct usb_interface *intf = to_usb_interface(dev);		\
+	struct usbtmc_device_data *data = usb_get_intfdata(intf);	\
+	ssize_t result;							\
+	unsigned val;							\
+									\
+	result = sscanf(buf, "%u\n", &val);				\
+	if (result != 1)						\
+		result = -EINVAL;					\
+	data->name = val;						\
+	if (result < 0)							\
+		return result;						\
+	else								\
+		return count;						\
+}									\
+static DEVICE_ATTR(name, S_IRUGO, show_##name, store_##name)
+
+data_attribute(TermCharEnabled);
+data_attribute(auto_abort);
+
+static struct attribute *data_attrs[] = {
+	&dev_attr_TermChar.attr,
+	&dev_attr_TermCharEnabled.attr,
+	&dev_attr_auto_abort.attr,
+	NULL,
+};
+
+static struct attribute_group data_attr_grp = {
+	.attrs = data_attrs,
+};
+
+static int usbtmc_ioctl_indicator_pulse(struct usbtmc_device_data *data)
+{
+	struct device *dev;
+	u8 *buffer;
+	int rv;
+
+	dev = &data->intf->dev;
+
+	buffer = kmalloc(2, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	rv = usb_control_msg(data->usb_dev,
+			     usb_rcvctrlpipe(data->usb_dev, 0),
+			     USBTMC_REQUEST_INDICATOR_PULSE,
+			     USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+			     0, 0, buffer, 0x01, USBTMC_TIMEOUT);
+
+	if (rv < 0) {
+		dev_err(dev, "usb_control_msg returned %d\n", rv);
+		goto exit;
+	}
+
+	dev_dbg(dev, "INDICATOR_PULSE returned %x\n", buffer[0]);
+
+	if (buffer[0] != USBTMC_STATUS_SUCCESS) {
+		dev_err(dev, "INDICATOR_PULSE returned %x\n", buffer[0]);
+		rv = -EPERM;
+		goto exit;
+	}
+	rv = 0;
+
+exit:
+	kfree(buffer);
+	return rv;
+}
+
+static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct usbtmc_device_data *data;
+	int retval = -EBADRQC;
+
+	data = file->private_data;
+	mutex_lock(&data->io_mutex);
+
+	switch (cmd) {
+	case USBTMC_IOCTL_CLEAR_OUT_HALT:
+		retval = usbtmc_ioctl_clear_out_halt(data);
+
+	case USBTMC_IOCTL_CLEAR_IN_HALT:
+		retval = usbtmc_ioctl_clear_in_halt(data);
+
+	case USBTMC_IOCTL_INDICATOR_PULSE:
+		retval = usbtmc_ioctl_indicator_pulse(data);
+
+	case USBTMC_IOCTL_CLEAR:
+		retval = usbtmc_ioctl_clear(data);
+
+	case USBTMC_IOCTL_ABORT_BULK_OUT:
+		retval = usbtmc_ioctl_abort_bulk_out(data);
+
+	case USBTMC_IOCTL_ABORT_BULK_IN:
+		retval = usbtmc_ioctl_abort_bulk_in(data);
+	}
+
+	mutex_unlock(&data->io_mutex);
+	return retval;
+}
+
+static struct file_operations fops = {
+	.owner		= THIS_MODULE,
+	.read		= usbtmc_read,
+	.write		= usbtmc_write,
+	.open		= usbtmc_open,
+	.release	= usbtmc_release,
+	.unlocked_ioctl	= usbtmc_ioctl,
+};
+
+static struct usb_class_driver usbtmc_class = {
+	.name =		"usbtmc%d",
+	.fops =		&fops,
+	.minor_base =	USBTMC_MINOR_BASE,
+};
+
+
+static int usbtmc_probe(struct usb_interface *intf,
+			const struct usb_device_id *id)
+{
+	struct usbtmc_device_data *data;
+	struct usb_host_interface *iface_desc;
+	struct usb_endpoint_descriptor *endpoint;
+	int n;
+	int retcode;
+
+	dev_dbg(&intf->dev, "%s called\n", __func__);
+
+	data = kmalloc(sizeof(struct usbtmc_device_data), GFP_KERNEL);
+	if (!data) {
+		dev_err(&intf->dev, "Unable to allocate kernel memory\n");
+		return -ENOMEM;
+	}
+
+	data->intf = intf;
+	data->id = id;
+	data->usb_dev = usb_get_dev(interface_to_usbdev(intf));
+	usb_set_intfdata(intf, data);
+	kref_init(&data->kref);
+	mutex_init(&data->io_mutex);
+
+	/* Initialize USBTMC bTag and other fields */
+	data->bTag	= 1;
+	data->TermCharEnabled = 0;
+	data->TermChar = '\n';
+
+	/* USBTMC devices have only one setting, so use that */
+	iface_desc = data->intf->cur_altsetting;
+
+	/* Find bulk in endpoint */
+	for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) {
+		endpoint = &iface_desc->endpoint[n].desc;
+
+		if (usb_endpoint_is_bulk_in(endpoint)) {
+			data->bulk_in = endpoint->bEndpointAddress;
+			dev_dbg(&intf->dev, "Found bulk in endpoint at %u\n",
+				data->bulk_in);
+			break;
+		}
+	}
+
+	/* Find bulk out endpoint */
+	for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) {
+		endpoint = &iface_desc->endpoint[n].desc;
+
+		if (usb_endpoint_is_bulk_out(endpoint)) {
+			data->bulk_out = endpoint->bEndpointAddress;
+			dev_dbg(&intf->dev, "Found Bulk out endpoint at %u\n",
+				data->bulk_out);
+			break;
+		}
+	}
+
+	retcode = get_capabilities(data);
+	if (retcode)
+		dev_err(&intf->dev, "can't read capabilities\n");
+	else
+		retcode = sysfs_create_group(&intf->dev.kobj,
+					     &capability_attr_grp);
+
+	retcode = sysfs_create_group(&intf->dev.kobj, &data_attr_grp);
+
+	retcode = usb_register_dev(intf, &usbtmc_class);
+	if (retcode) {
+		dev_err(&intf->dev, "Not able to get a minor"
+			" (base %u, slice default): %d\n", USBTMC_MINOR_BASE,
+			retcode);
+		goto error_register;
+	}
+	dev_dbg(&intf->dev, "Using minor number %d\n", intf->minor);
+
+	return 0;
+
+error_register:
+	sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp);
+	sysfs_remove_group(&intf->dev.kobj, &data_attr_grp);
+	kref_put(&data->kref, usbtmc_delete);
+	return retcode;
+}
+
+static void usbtmc_disconnect(struct usb_interface *intf)
+{
+	struct usbtmc_device_data *data;
+
+	dev_dbg(&intf->dev, "usbtmc_disconnect called\n");
+
+	data = usb_get_intfdata(intf);
+	usb_deregister_dev(intf, &usbtmc_class);
+	sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp);
+	sysfs_remove_group(&intf->dev.kobj, &data_attr_grp);
+	kref_put(&data->kref, usbtmc_delete);
+}
+
+static struct usb_driver usbtmc_driver = {
+	.name		= "usbtmc",
+	.id_table	= usbtmc_devices,
+	.probe		= usbtmc_probe,
+	.disconnect	= usbtmc_disconnect
+};
+
+static int __init usbtmc_init(void)
+{
+	int retcode;
+
+	retcode = usb_register(&usbtmc_driver);
+	if (retcode)
+		printk(KERN_ERR KBUILD_MODNAME": Unable to register driver\n");
+	return retcode;
+}
+module_init(usbtmc_init);
+
+static void __exit usbtmc_exit(void)
+{
+	usb_deregister(&usbtmc_driver);
+}
+module_exit(usbtmc_exit);
+
+MODULE_LICENSE("GPL");

+ 1 - 1
drivers/usb/core/Kconfig

@@ -134,5 +134,5 @@ config USB_OTG_BLACKLIST_HUB
 	  If you say Y here, then Linux will refuse to enumerate
 	  external hubs.  OTG hosts are allowed to reduce hardware
 	  and software costs by not supporting external hubs.  So
-	  are "Emedded Hosts" that don't offer OTG support.
+	  are "Embedded Hosts" that don't offer OTG support.
 

+ 8 - 4
drivers/usb/core/devio.c

@@ -413,7 +413,8 @@ static void driver_disconnect(struct usb_interface *intf)
 	if (likely(ifnum < 8*sizeof(ps->ifclaimed)))
 		clear_bit(ifnum, &ps->ifclaimed);
 	else
-		warn("interface number %u out of range", ifnum);
+		dev_warn(&intf->dev, "interface number %u out of range\n",
+			 ifnum);
 
 	usb_set_intfdata(intf, NULL);
 
@@ -624,6 +625,8 @@ static int usbdev_open(struct inode *inode, struct file *file)
 	smp_wmb();
 	list_add_tail(&ps->list, &dev->filelist);
 	file->private_data = ps;
+	snoop(&dev->dev, "opened by process %d: %s\n", task_pid_nr(current),
+			current->comm);
  out:
 	if (ret) {
 		kfree(ps);
@@ -1774,19 +1777,20 @@ int __init usb_devio_init(void)
 	retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX,
 					"usb_device");
 	if (retval) {
-		err("unable to register minors for usb_device");
+		printk(KERN_ERR "Unable to register minors for usb_device\n");
 		goto out;
 	}
 	cdev_init(&usb_device_cdev, &usbdev_file_operations);
 	retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);
 	if (retval) {
-		err("unable to get usb_device major %d", USB_DEVICE_MAJOR);
+		printk(KERN_ERR "Unable to get usb_device major %d\n",
+		       USB_DEVICE_MAJOR);
 		goto error_cdev;
 	}
 #ifdef CONFIG_USB_DEVICE_CLASS
 	usb_classdev_class = class_create(THIS_MODULE, "usb_device");
 	if (IS_ERR(usb_classdev_class)) {
-		err("unable to register usb_device class");
+		printk(KERN_ERR "Unable to register usb_device class\n");
 		retval = PTR_ERR(usb_classdev_class);
 		cdev_del(&usb_device_cdev);
 		usb_classdev_class = NULL;

+ 2 - 1
drivers/usb/core/driver.c

@@ -1070,7 +1070,8 @@ static int autosuspend_check(struct usb_device *udev, int reschedule)
 				struct usb_driver *driver;
 
 				driver = to_usb_driver(intf->dev.driver);
-				if (!driver->reset_resume)
+				if (!driver->reset_resume ||
+				    intf->needs_remote_wakeup)
 					return -EOPNOTSUPP;
 			}
 		}

+ 2 - 1
drivers/usb/core/endpoint.c

@@ -169,7 +169,8 @@ static int usb_endpoint_major_init(void)
 	error = alloc_chrdev_region(&dev, 0, MAX_ENDPOINT_MINORS,
 				    "usb_endpoint");
 	if (error) {
-		err("unable to get a dynamic major for usb endpoints");
+		printk(KERN_ERR "Unable to get a dynamic major for "
+		       "usb endpoints.\n");
 		return error;
 	}
 	usb_endpoint_major = MAJOR(dev);

+ 3 - 2
drivers/usb/core/file.c

@@ -86,7 +86,7 @@ static int init_usb_class(void)
 	usb_class->class = class_create(THIS_MODULE, "usb");
 	if (IS_ERR(usb_class->class)) {
 		result = IS_ERR(usb_class->class);
-		err("class_create failed for usb devices");
+		printk(KERN_ERR "class_create failed for usb devices\n");
 		kfree(usb_class);
 		usb_class = NULL;
 	}
@@ -115,7 +115,8 @@ int usb_major_init(void)
 
 	error = register_chrdev(USB_MAJOR, "usb", &usb_fops);
 	if (error)
-		err("unable to get major %d for usb devices", USB_MAJOR);
+		printk(KERN_ERR "Unable to get major %d for usb devices\n",
+		       USB_MAJOR);
 
 	return error;
 }

+ 4 - 0
drivers/usb/core/hcd.c

@@ -81,6 +81,10 @@
 
 /*-------------------------------------------------------------------------*/
 
+/* Keep track of which host controller drivers are loaded */
+unsigned long usb_hcds_loaded;
+EXPORT_SYMBOL_GPL(usb_hcds_loaded);
+
 /* host controllers we manage */
 LIST_HEAD (usb_bus_list);
 EXPORT_SYMBOL_GPL (usb_bus_list);

+ 6 - 0
drivers/usb/core/hcd.h

@@ -482,4 +482,10 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb,
  */
 extern struct rw_semaphore ehci_cf_port_reset_rwsem;
 
+/* Keep track of which host controller drivers are loaded */
+#define USB_UHCI_LOADED		0
+#define USB_OHCI_LOADED		1
+#define USB_EHCI_LOADED		2
+extern unsigned long usb_hcds_loaded;
+
 #endif /* __KERNEL__ */

+ 91 - 11
drivers/usb/core/hub.c

@@ -77,6 +77,7 @@ struct usb_hub {
 	unsigned		has_indicators:1;
 	u8			indicator[USB_MAXCHILDREN];
 	struct delayed_work	leds;
+	struct delayed_work	init_work;
 };
 
 
@@ -99,6 +100,15 @@ static int blinkenlights = 0;
 module_param (blinkenlights, bool, S_IRUGO);
 MODULE_PARM_DESC (blinkenlights, "true to cycle leds on hubs");
 
+/*
+ * Device SATA8000 FW1.0 from DATAST0R Technology Corp requires about
+ * 10 seconds to send reply for the initial 64-byte descriptor request.
+ */
+/* define initial 64-byte descriptor request timeout in milliseconds */
+static int initial_descriptor_timeout = USB_CTRL_GET_TIMEOUT;
+module_param(initial_descriptor_timeout, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(initial_descriptor_timeout, "initial 64-byte descriptor request timeout in milliseconds (default 5000 - 5.0 seconds)");
+
 /*
  * As of 2.6.10 we introduce a new USB device initialization scheme which
  * closely resembles the way Windows works.  Hopefully it will be compatible
@@ -515,10 +525,14 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
 }
 EXPORT_SYMBOL_GPL(usb_hub_tt_clear_buffer);
 
-static void hub_power_on(struct usb_hub *hub)
+/* If do_delay is false, return the number of milliseconds the caller
+ * needs to delay.
+ */
+static unsigned hub_power_on(struct usb_hub *hub, bool do_delay)
 {
 	int port1;
 	unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2;
+	unsigned delay;
 	u16 wHubCharacteristics =
 			le16_to_cpu(hub->descriptor->wHubCharacteristics);
 
@@ -537,7 +551,10 @@ static void hub_power_on(struct usb_hub *hub)
 		set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER);
 
 	/* Wait at least 100 msec for power to become stable */
-	msleep(max(pgood_delay, (unsigned) 100));
+	delay = max(pgood_delay, (unsigned) 100);
+	if (do_delay)
+		msleep(delay);
+	return delay;
 }
 
 static int hub_hub_status(struct usb_hub *hub,
@@ -599,21 +616,55 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)
 }
 
 enum hub_activation_type {
-	HUB_INIT, HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME
+	HUB_INIT, HUB_INIT2, HUB_INIT3,
+	HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME,
 };
 
+static void hub_init_func2(struct work_struct *ws);
+static void hub_init_func3(struct work_struct *ws);
+
 static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 {
 	struct usb_device *hdev = hub->hdev;
 	int port1;
 	int status;
 	bool need_debounce_delay = false;
+	unsigned delay;
+
+	/* Continue a partial initialization */
+	if (type == HUB_INIT2)
+		goto init2;
+	if (type == HUB_INIT3)
+		goto init3;
 
 	/* After a resume, port power should still be on.
 	 * For any other type of activation, turn it on.
 	 */
-	if (type != HUB_RESUME)
-		hub_power_on(hub);
+	if (type != HUB_RESUME) {
+
+		/* Speed up system boot by using a delayed_work for the
+		 * hub's initial power-up delays.  This is pretty awkward
+		 * and the implementation looks like a home-brewed sort of
+		 * setjmp/longjmp, but it saves at least 100 ms for each
+		 * root hub (assuming usbcore is compiled into the kernel
+		 * rather than as a module).  It adds up.
+		 *
+		 * This can't be done for HUB_RESUME or HUB_RESET_RESUME
+		 * because for those activation types the ports have to be
+		 * operational when we return.  In theory this could be done
+		 * for HUB_POST_RESET, but it's easier not to.
+		 */
+		if (type == HUB_INIT) {
+			delay = hub_power_on(hub, false);
+			PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func2);
+			schedule_delayed_work(&hub->init_work,
+					msecs_to_jiffies(delay));
+			return;		/* Continues at init2: below */
+		} else {
+			hub_power_on(hub, true);
+		}
+	}
+ init2:
 
 	/* Check each port and set hub->change_bits to let khubd know
 	 * which ports need attention.
@@ -692,9 +743,20 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 	 * If any port-status changes do occur during this delay, khubd
 	 * will see them later and handle them normally.
 	 */
-	if (need_debounce_delay)
-		msleep(HUB_DEBOUNCE_STABLE);
-
+	if (need_debounce_delay) {
+		delay = HUB_DEBOUNCE_STABLE;
+
+		/* Don't do a long sleep inside a workqueue routine */
+		if (type == HUB_INIT2) {
+			PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func3);
+			schedule_delayed_work(&hub->init_work,
+					msecs_to_jiffies(delay));
+			return;		/* Continues at init3: below */
+		} else {
+			msleep(delay);
+		}
+	}
+ init3:
 	hub->quiescing = 0;
 
 	status = usb_submit_urb(hub->urb, GFP_NOIO);
@@ -707,6 +769,21 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 	kick_khubd(hub);
 }
 
+/* Implement the continuations for the delays above */
+static void hub_init_func2(struct work_struct *ws)
+{
+	struct usb_hub *hub = container_of(ws, struct usb_hub, init_work.work);
+
+	hub_activate(hub, HUB_INIT2);
+}
+
+static void hub_init_func3(struct work_struct *ws)
+{
+	struct usb_hub *hub = container_of(ws, struct usb_hub, init_work.work);
+
+	hub_activate(hub, HUB_INIT3);
+}
+
 enum hub_quiescing_type {
 	HUB_DISCONNECT, HUB_PRE_RESET, HUB_SUSPEND
 };
@@ -716,6 +793,8 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
 	struct usb_device *hdev = hub->hdev;
 	int i;
 
+	cancel_delayed_work_sync(&hub->init_work);
+
 	/* khubd and related activity won't re-trigger */
 	hub->quiescing = 1;
 
@@ -1099,6 +1178,7 @@ descriptor_error:
 	hub->intfdev = &intf->dev;
 	hub->hdev = hdev;
 	INIT_DELAYED_WORK(&hub->leds, led_work);
+	INIT_DELAYED_WORK(&hub->init_work, NULL);
 	usb_get_intf(intf);
 
 	usb_set_intfdata (intf, hub);
@@ -2467,7 +2547,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
 					USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
 					USB_DT_DEVICE << 8, 0,
 					buf, GET_DESCRIPTOR_BUFSIZE,
-					USB_CTRL_GET_TIMEOUT);
+					initial_descriptor_timeout);
 				switch (buf->bMaxPacketSize0) {
 				case 8: case 16: case 32: case 64: case 255:
 					if (buf->bDescriptorType ==
@@ -3035,7 +3115,7 @@ static void hub_events(void)
 					i);
 				clear_port_feature(hdev, i,
 					USB_PORT_FEAT_C_OVER_CURRENT);
-				hub_power_on(hub);
+				hub_power_on(hub, true);
 			}
 
 			if (portchange & USB_PORT_STAT_C_RESET) {
@@ -3070,7 +3150,7 @@ static void hub_events(void)
 				dev_dbg (hub_dev, "overcurrent change\n");
 				msleep(500);	/* Cool down */
 				clear_hub_feature(hdev, C_HUB_OVER_CURRENT);
-                        	hub_power_on(hub);
+                        	hub_power_on(hub, true);
 			}
 		}
 

+ 10 - 8
drivers/usb/core/inode.c

@@ -180,8 +180,8 @@ static int parse_options(struct super_block *s, char *data)
 			listmode = option & S_IRWXUGO;
 			break;
 		default:
-			err("usbfs: unrecognised mount option \"%s\" "
-			    "or missing value\n", p);
+			printk(KERN_ERR "usbfs: unrecognised mount option "
+			       "\"%s\" or missing value\n", p);
 			return -EINVAL;
 		}
 	}
@@ -240,7 +240,9 @@ static void update_sb(struct super_block *sb)
 				update_special(bus);
 				break;
 			default:
-				warn("Unknown node %s mode %x found on remount!\n",bus->d_name.name,bus->d_inode->i_mode);
+				printk(KERN_WARNING "usbfs: Unknown node %s "
+				       "mode %x found on remount!\n",
+				       bus->d_name.name, bus->d_inode->i_mode);
 				break;
 			}
 		}
@@ -259,7 +261,7 @@ static int remount(struct super_block *sb, int *flags, char *data)
 		return 0;
 
 	if (parse_options(sb, data)) {
-		warn("usbfs: mount parameter error:");
+		printk(KERN_WARNING "usbfs: mount parameter error.\n");
 		return -EINVAL;
 	}
 
@@ -599,7 +601,7 @@ static int create_special_files (void)
 	/* create the devices special file */
 	retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count);
 	if (retval) {
-		err ("Unable to get usbfs mount");
+		printk(KERN_ERR "Unable to get usbfs mount\n");
 		goto exit;
 	}
 
@@ -611,7 +613,7 @@ static int create_special_files (void)
 					       NULL, &usbfs_devices_fops,
 					       listuid, listgid);
 	if (devices_usbfs_dentry == NULL) {
-		err ("Unable to create devices usbfs file");
+		printk(KERN_ERR "Unable to create devices usbfs file\n");
 		retval = -ENODEV;
 		goto error_clean_mounts;
 	}
@@ -663,7 +665,7 @@ static void usbfs_add_bus(struct usb_bus *bus)
 	bus->usbfs_dentry = fs_create_file (name, busmode | S_IFDIR, parent,
 					    bus, NULL, busuid, busgid);
 	if (bus->usbfs_dentry == NULL) {
-		err ("error creating usbfs bus entry");
+		printk(KERN_ERR "Error creating usbfs bus entry\n");
 		return;
 	}
 }
@@ -694,7 +696,7 @@ static void usbfs_add_device(struct usb_device *dev)
 					    &usbdev_file_operations,
 					    devuid, devgid);
 	if (dev->usbfs_dentry == NULL) {
-		err ("error creating usbfs device entry");
+		printk(KERN_ERR "Error creating usbfs device entry\n");
 		return;
 	}
 

+ 2 - 1
drivers/usb/core/message.c

@@ -1204,7 +1204,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
 
 	alt = usb_altnum_to_altsetting(iface, alternate);
 	if (!alt) {
-		warn("selecting invalid altsetting %d", alternate);
+		dev_warn(&dev->dev, "selecting invalid altsetting %d",
+			 alternate);
 		return -EINVAL;
 	}
 

+ 24 - 0
drivers/usb/core/sysfs.c

@@ -743,6 +743,29 @@ static ssize_t show_modalias(struct device *dev,
 }
 static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
 
+static ssize_t show_supports_autosuspend(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct usb_interface *intf;
+	struct usb_device *udev;
+	int ret;
+
+	intf = to_usb_interface(dev);
+	udev = interface_to_usbdev(intf);
+
+	usb_lock_device(udev);
+	/* Devices will be autosuspended even when an interface isn't claimed */
+	if (!intf->dev.driver ||
+			to_usb_driver(intf->dev.driver)->supports_autosuspend)
+		ret = sprintf(buf, "%u\n", 1);
+	else
+		ret = sprintf(buf, "%u\n", 0);
+	usb_unlock_device(udev);
+
+	return ret;
+}
+static DEVICE_ATTR(supports_autosuspend, S_IRUGO, show_supports_autosuspend, NULL);
+
 static struct attribute *intf_attrs[] = {
 	&dev_attr_bInterfaceNumber.attr,
 	&dev_attr_bAlternateSetting.attr,
@@ -751,6 +774,7 @@ static struct attribute *intf_attrs[] = {
 	&dev_attr_bInterfaceSubClass.attr,
 	&dev_attr_bInterfaceProtocol.attr,
 	&dev_attr_modalias.attr,
+	&dev_attr_supports_autosuspend.attr,
 	NULL,
 };
 static struct attribute_group intf_attr_grp = {

+ 161 - 8
drivers/usb/core/urb.c

@@ -10,6 +10,8 @@
 
 #define to_urb(d) container_of(d, struct urb, kref)
 
+static DEFINE_SPINLOCK(usb_reject_lock);
+
 static void urb_destroy(struct kref *kref)
 {
 	struct urb *urb = to_urb(kref);
@@ -68,7 +70,7 @@ struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags)
 		iso_packets * sizeof(struct usb_iso_packet_descriptor),
 		mem_flags);
 	if (!urb) {
-		err("alloc_urb: kmalloc failed");
+		printk(KERN_ERR "alloc_urb: kmalloc failed\n");
 		return NULL;
 	}
 	usb_init_urb(urb);
@@ -127,6 +129,13 @@ void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor)
 	usb_get_urb(urb);
 	list_add_tail(&urb->anchor_list, &anchor->urb_list);
 	urb->anchor = anchor;
+
+	if (unlikely(anchor->poisoned)) {
+		spin_lock(&usb_reject_lock);
+		urb->reject++;
+		spin_unlock(&usb_reject_lock);
+	}
+
 	spin_unlock_irqrestore(&anchor->lock, flags);
 }
 EXPORT_SYMBOL_GPL(usb_anchor_urb);
@@ -398,7 +407,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
 
 	/* fail if submitter gave bogus flags */
 	if (urb->transfer_flags != orig_flags) {
-		err("BOGUS urb flags, %x --> %x",
+		dev_err(&dev->dev, "BOGUS urb flags, %x --> %x\n",
 			orig_flags, urb->transfer_flags);
 		return -EINVAL;
 	}
@@ -544,24 +553,69 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb);
  */
 void usb_kill_urb(struct urb *urb)
 {
-	static DEFINE_MUTEX(reject_mutex);
-
 	might_sleep();
 	if (!(urb && urb->dev && urb->ep))
 		return;
-	mutex_lock(&reject_mutex);
+	spin_lock_irq(&usb_reject_lock);
 	++urb->reject;
-	mutex_unlock(&reject_mutex);
+	spin_unlock_irq(&usb_reject_lock);
 
 	usb_hcd_unlink_urb(urb, -ENOENT);
 	wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0);
 
-	mutex_lock(&reject_mutex);
+	spin_lock_irq(&usb_reject_lock);
 	--urb->reject;
-	mutex_unlock(&reject_mutex);
+	spin_unlock_irq(&usb_reject_lock);
 }
 EXPORT_SYMBOL_GPL(usb_kill_urb);
 
+/**
+ * usb_poison_urb - reliably kill a transfer and prevent further use of an URB
+ * @urb: pointer to URB describing a previously submitted request,
+ *	may be NULL
+ *
+ * This routine cancels an in-progress request.  It is guaranteed that
+ * upon return all completion handlers will have finished and the URB
+ * will be totally idle and cannot be reused.  These features make
+ * this an ideal way to stop I/O in a disconnect() callback.
+ * If the request has not already finished or been unlinked
+ * the completion handler will see urb->status == -ENOENT.
+ *
+ * After and while the routine runs, attempts to resubmit the URB will fail
+ * with error -EPERM.  Thus even if the URB's completion handler always
+ * tries to resubmit, it will not succeed and the URB will become idle.
+ *
+ * This routine may not be used in an interrupt context (such as a bottom
+ * half or a completion handler), or when holding a spinlock, or in other
+ * situations where the caller can't schedule().
+ */
+void usb_poison_urb(struct urb *urb)
+{
+	might_sleep();
+	if (!(urb && urb->dev && urb->ep))
+		return;
+	spin_lock_irq(&usb_reject_lock);
+	++urb->reject;
+	spin_unlock_irq(&usb_reject_lock);
+
+	usb_hcd_unlink_urb(urb, -ENOENT);
+	wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0);
+}
+EXPORT_SYMBOL_GPL(usb_poison_urb);
+
+void usb_unpoison_urb(struct urb *urb)
+{
+	unsigned long flags;
+
+	if (!urb)
+		return;
+
+	spin_lock_irqsave(&usb_reject_lock, flags);
+	--urb->reject;
+	spin_unlock_irqrestore(&usb_reject_lock, flags);
+}
+EXPORT_SYMBOL_GPL(usb_unpoison_urb);
+
 /**
  * usb_kill_anchored_urbs - cancel transfer requests en masse
  * @anchor: anchor the requests are bound to
@@ -589,6 +643,35 @@ void usb_kill_anchored_urbs(struct usb_anchor *anchor)
 }
 EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs);
 
+
+/**
+ * usb_poison_anchored_urbs - cease all traffic from an anchor
+ * @anchor: anchor the requests are bound to
+ *
+ * this allows all outstanding URBs to be poisoned starting
+ * from the back of the queue. Newly added URBs will also be
+ * poisoned
+ */
+void usb_poison_anchored_urbs(struct usb_anchor *anchor)
+{
+	struct urb *victim;
+
+	spin_lock_irq(&anchor->lock);
+	anchor->poisoned = 1;
+	while (!list_empty(&anchor->urb_list)) {
+		victim = list_entry(anchor->urb_list.prev, struct urb,
+				    anchor_list);
+		/* we must make sure the URB isn't freed before we kill it*/
+		usb_get_urb(victim);
+		spin_unlock_irq(&anchor->lock);
+		/* this will unanchor the URB */
+		usb_poison_urb(victim);
+		usb_put_urb(victim);
+		spin_lock_irq(&anchor->lock);
+	}
+	spin_unlock_irq(&anchor->lock);
+}
+EXPORT_SYMBOL_GPL(usb_poison_anchored_urbs);
 /**
  * usb_unlink_anchored_urbs - asynchronously cancel transfer requests en masse
  * @anchor: anchor the requests are bound to
@@ -633,3 +716,73 @@ int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor,
 				  msecs_to_jiffies(timeout));
 }
 EXPORT_SYMBOL_GPL(usb_wait_anchor_empty_timeout);
+
+/**
+ * usb_get_from_anchor - get an anchor's oldest urb
+ * @anchor: the anchor whose urb you want
+ *
+ * this will take the oldest urb from an anchor,
+ * unanchor and return it
+ */
+struct urb *usb_get_from_anchor(struct usb_anchor *anchor)
+{
+	struct urb *victim;
+	unsigned long flags;
+
+	spin_lock_irqsave(&anchor->lock, flags);
+	if (!list_empty(&anchor->urb_list)) {
+		victim = list_entry(anchor->urb_list.next, struct urb,
+				    anchor_list);
+		usb_get_urb(victim);
+		spin_unlock_irqrestore(&anchor->lock, flags);
+		usb_unanchor_urb(victim);
+	} else {
+		spin_unlock_irqrestore(&anchor->lock, flags);
+		victim = NULL;
+	}
+
+	return victim;
+}
+
+EXPORT_SYMBOL_GPL(usb_get_from_anchor);
+
+/**
+ * usb_scuttle_anchored_urbs - unanchor all an anchor's urbs
+ * @anchor: the anchor whose urbs you want to unanchor
+ *
+ * use this to get rid of all an anchor's urbs
+ */
+void usb_scuttle_anchored_urbs(struct usb_anchor *anchor)
+{
+	struct urb *victim;
+	unsigned long flags;
+
+	spin_lock_irqsave(&anchor->lock, flags);
+	while (!list_empty(&anchor->urb_list)) {
+		victim = list_entry(anchor->urb_list.prev, struct urb,
+				    anchor_list);
+		usb_get_urb(victim);
+		spin_unlock_irqrestore(&anchor->lock, flags);
+		/* this may free the URB */
+		usb_unanchor_urb(victim);
+		usb_put_urb(victim);
+		spin_lock_irqsave(&anchor->lock, flags);
+	}
+	spin_unlock_irqrestore(&anchor->lock, flags);
+}
+
+EXPORT_SYMBOL_GPL(usb_scuttle_anchored_urbs);
+
+/**
+ * usb_anchor_empty - is an anchor empty
+ * @anchor: the anchor you want to query
+ *
+ * returns 1 if the anchor has no urbs associated with it
+ */
+int usb_anchor_empty(struct usb_anchor *anchor)
+{
+	return list_empty(&anchor->urb_list);
+}
+
+EXPORT_SYMBOL_GPL(usb_anchor_empty);
+

+ 189 - 126
drivers/usb/gadget/Kconfig

@@ -45,7 +45,7 @@ if USB_GADGET
 
 config USB_GADGET_DEBUG
 	boolean "Debugging messages (DEVELOPMENT)"
-	depends on USB_GADGET && DEBUG_KERNEL
+	depends on DEBUG_KERNEL
 	help
 	   Many controller and gadget drivers will print some debugging
 	   messages if you use this option to ask for those messages.
@@ -59,7 +59,7 @@ config USB_GADGET_DEBUG
 
 config USB_GADGET_DEBUG_FILES
 	boolean "Debugging information files (DEVELOPMENT)"
-	depends on USB_GADGET && PROC_FS
+	depends on PROC_FS
 	help
 	   Some of the drivers in the "gadget" framework can expose
 	   debugging information in files such as /proc/driver/udc
@@ -70,7 +70,7 @@ config USB_GADGET_DEBUG_FILES
 
 config USB_GADGET_DEBUG_FS
 	boolean "Debugging information files in debugfs (DEVELOPMENT)"
-	depends on USB_GADGET && DEBUG_FS
+	depends on DEBUG_FS
 	help
 	   Some of the drivers in the "gadget" framework can expose
 	   debugging information in files under /sys/kernel/debug/.
@@ -79,12 +79,36 @@ config USB_GADGET_DEBUG_FS
 	   Enable these files by choosing "Y" here.  If in doubt, or
 	   to conserve kernel memory, say "N".
 
+config USB_GADGET_VBUS_DRAW
+	int "Maximum VBUS Power usage (2-500 mA)"
+	range 2 500
+	default 2
+	help
+	   Some devices need to draw power from USB when they are
+	   configured, perhaps to operate circuitry or to recharge
+	   batteries.  This is in addition to any local power supply,
+	   such as an AC adapter or batteries.
+
+	   Enter the maximum power your device draws through USB, in
+	   milliAmperes.  The permitted range of values is 2 - 500 mA;
+	   0 mA would be legal, but can make some hosts misbehave.
+
+	   This value will be used except for system-specific gadget
+	   drivers that have more specific information.
+
 config	USB_GADGET_SELECTED
 	boolean
 
 #
 # USB Peripheral Controller Support
 #
+# The order here is alphabetical, except that integrated controllers go
+# before discrete ones so they will be the initial/default value:
+#   - integrated/SOC controllers first
+#   - licensed IP used in both SOC and discrete versions
+#   - discrete ones (including all PCI-only controllers)
+#   - debug/dummy gadget+hcd is last.
+#
 choice
 	prompt "USB Peripheral Controller"
 	depends on USB_GADGET
@@ -94,26 +118,27 @@ choice
 	   Many controller drivers are platform-specific; these
 	   often need board-specific hooks.
 
-config USB_GADGET_AMD5536UDC
-	boolean "AMD5536 UDC"
-	depends on PCI
-	select USB_GADGET_DUALSPEED
+#
+# Integrated controllers
+#
+
+config USB_GADGET_AT91
+	boolean "Atmel AT91 USB Device Port"
+	depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9
+	select USB_GADGET_SELECTED
 	help
-	   The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge.
-	   It is a USB Highspeed DMA capable USB device controller. Beside ep0
-	   it provides 4 IN and 4 OUT endpoints (bulk or interrupt type).
-	   The UDC port supports OTG operation, and may be used as a host port
-	   if it's not being used to implement peripheral or OTG roles.
+	   Many Atmel AT91 processors (such as the AT91RM2000) have a
+	   full speed USB Device Port with support for five configurable
+	   endpoints (plus endpoint zero).
 
 	   Say "y" to link the driver statically, or "m" to build a
-	   dynamically linked module called "amd5536udc" and force all
+	   dynamically linked module called "at91_udc" and force all
 	   gadget drivers to also be dynamically linked.
 
-config USB_AMD5536UDC
+config USB_AT91
 	tristate
-	depends on USB_GADGET_AMD5536UDC
+	depends on USB_GADGET_AT91
 	default USB_GADGET
-	select USB_GADGET_SELECTED
 
 config USB_GADGET_ATMEL_USBA
 	boolean "Atmel USBA"
@@ -150,28 +175,50 @@ config USB_FSL_USB2
 	default USB_GADGET
 	select USB_GADGET_SELECTED
 
-config USB_GADGET_NET2280
-	boolean "NetChip 228x"
-	depends on PCI
-	select USB_GADGET_DUALSPEED
+config USB_GADGET_LH7A40X
+	boolean "LH7A40X"
+	depends on ARCH_LH7A40X
 	help
-	   NetChip 2280 / 2282 is a PCI based USB peripheral controller which
-	   supports both full and high speed USB 2.0 data transfers.  
-	   
-	   It has six configurable endpoints, as well as endpoint zero
-	   (for control transfers) and several endpoints with dedicated
-	   functions.
+	   This driver provides USB Device Controller driver for LH7A40x
+
+config USB_LH7A40X
+	tristate
+	depends on USB_GADGET_LH7A40X
+	default USB_GADGET
+	select USB_GADGET_SELECTED
+
+config USB_GADGET_OMAP
+	boolean "OMAP USB Device Controller"
+	depends on ARCH_OMAP
+	select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG
+	help
+	   Many Texas Instruments OMAP processors have flexible full
+	   speed USB device controllers, with support for up to 30
+	   endpoints (plus endpoint zero).  This driver supports the
+	   controller in the OMAP 1611, and should work with controllers
+	   in other OMAP processors too, given minor tweaks.
 
 	   Say "y" to link the driver statically, or "m" to build a
-	   dynamically linked module called "net2280" and force all
+	   dynamically linked module called "omap_udc" and force all
 	   gadget drivers to also be dynamically linked.
 
-config USB_NET2280
+config USB_OMAP
 	tristate
-	depends on USB_GADGET_NET2280
+	depends on USB_GADGET_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
@@ -203,34 +250,6 @@ config USB_PXA25X_SMALL
 	default y if USB_ETH
 	default y if USB_G_SERIAL
 
-config USB_GADGET_M66592
-	boolean "Renesas M66592 USB Peripheral Controller"
-	select USB_GADGET_DUALSPEED
-	help
-	   M66592 is a discrete USB peripheral controller chip that
-	   supports both full and high speed USB 2.0 data transfers.
-	   It has seven configurable endpoints, and endpoint zero.
-
-	   Say "y" to link the driver statically, or "m" to build a
-	   dynamically linked module called "m66592_udc" and force all
-	   gadget drivers to also be dynamically linked.
-
-config USB_M66592
-	tristate
-	depends on USB_GADGET_M66592
-	default USB_GADGET
-	select USB_GADGET_SELECTED
-
-config SUPERH_BUILT_IN_M66592
-	boolean "Enable SuperH built-in USB like the M66592"
-	depends on USB_GADGET_M66592 && CPU_SUBTYPE_SH7722
-	help
-	   SH7722 has USB like the M66592.
-
-	   The transfer rate is very slow when use "Ethernet Gadget".
-	   However, this problem is improved if change a value of
-	   NET_IP_ALIGN to 4.
-
 config USB_GADGET_PXA27X
 	boolean "PXA 27x"
 	depends on ARCH_PXA && PXA27x
@@ -251,40 +270,32 @@ config USB_PXA27X
 	default USB_GADGET
 	select USB_GADGET_SELECTED
 
-config USB_GADGET_GOKU
-	boolean "Toshiba TC86C001 'Goku-S'"
-	depends on PCI
+config USB_GADGET_S3C2410
+	boolean "S3C2410 USB Device Controller"
+	depends on ARCH_S3C2410
 	help
-	   The Toshiba TC86C001 is a PCI device which includes controllers
-	   for full speed USB devices, IDE, I2C, SIO, plus a USB host (OHCI).
-	   
-	   The device controller has three configurable (bulk or interrupt)
-	   endpoints, plus endpoint zero (for control transfers).
+	  Samsung's S3C2410 is an ARM-4 processor with an integrated
+	  full speed USB 1.1 device controller.  It has 4 configurable
+	  endpoints, as well as endpoint zero (for control transfers).
 
-	   Say "y" to link the driver statically, or "m" to build a
-	   dynamically linked module called "goku_udc" and to force all
-	   gadget drivers to also be dynamically linked.
+	  This driver has been tested on the S3C2410, S3C2412, and
+	  S3C2440 processors.
 
-config USB_GOKU
+config USB_S3C2410
 	tristate
-	depends on USB_GADGET_GOKU
+	depends on USB_GADGET_S3C2410
 	default USB_GADGET
 	select USB_GADGET_SELECTED
 
+config USB_S3C2410_DEBUG
+	boolean "S3C2410 udc debug messages"
+	depends on USB_GADGET_S3C2410
 
-config USB_GADGET_LH7A40X
-	boolean "LH7A40X"
-	depends on ARCH_LH7A40X
-	help
-    This driver provides USB Device Controller driver for LH7A40x
-
-config USB_LH7A40X
-	tristate
-	depends on USB_GADGET_LH7A40X
-	default USB_GADGET
-	select USB_GADGET_SELECTED
+#
+# Controllers available in both integrated and discrete versions
+#
 
-# built in ../musb along with host support
+# musb builds in ../musb along with host support
 config USB_GADGET_MUSB_HDRC
 	boolean "Inventra HDRC USB Peripheral (TI, ...)"
 	depends on USB_MUSB_HDRC && (USB_MUSB_PERIPHERAL || USB_MUSB_OTG)
@@ -294,76 +305,124 @@ config USB_GADGET_MUSB_HDRC
 	  This OTG-capable silicon IP is used in dual designs including
 	  the TI DaVinci, OMAP 243x, OMAP 343x, and TUSB 6010.
 
-config USB_GADGET_OMAP
-	boolean "OMAP USB Device Controller"
-	depends on ARCH_OMAP
-	select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3
+config USB_GADGET_M66592
+	boolean "Renesas M66592 USB Peripheral Controller"
+	select USB_GADGET_DUALSPEED
 	help
-	   Many Texas Instruments OMAP processors have flexible full
-	   speed USB device controllers, with support for up to 30
-	   endpoints (plus endpoint zero).  This driver supports the
-	   controller in the OMAP 1611, and should work with controllers
-	   in other OMAP processors too, given minor tweaks.
+	   M66592 is a discrete USB peripheral controller chip that
+	   supports both full and high speed USB 2.0 data transfers.
+	   It has seven configurable endpoints, and endpoint zero.
 
 	   Say "y" to link the driver statically, or "m" to build a
-	   dynamically linked module called "omap_udc" and force all
+	   dynamically linked module called "m66592_udc" and force all
 	   gadget drivers to also be dynamically linked.
 
-config USB_OMAP
+config USB_M66592
 	tristate
-	depends on USB_GADGET_OMAP
+	depends on USB_GADGET_M66592
 	default USB_GADGET
 	select USB_GADGET_SELECTED
 
-config USB_OTG
-	boolean "OTG Support"
-	depends on USB_GADGET_OMAP && ARCH_OMAP_OTG && USB_OHCI_HCD
+config SUPERH_BUILT_IN_M66592
+	boolean "Enable SuperH built-in USB like the M66592"
+	depends on USB_GADGET_M66592 && CPU_SUBTYPE_SH7722
 	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.
+	   SH7722 has USB like the M66592.
 
-	   Select this only if your OMAP board has a Mini-AB connector.
+	   The transfer rate is very slow when use "Ethernet Gadget".
+	   However, this problem is improved if change a value of
+	   NET_IP_ALIGN to 4.
 
-config USB_GADGET_S3C2410
-	boolean "S3C2410 USB Device Controller"
-	depends on ARCH_S3C2410
+#
+# Controllers available only in discrete form (and all PCI controllers)
+#
+
+config USB_GADGET_AMD5536UDC
+	boolean "AMD5536 UDC"
+	depends on PCI
+	select USB_GADGET_DUALSPEED
 	help
-	  Samsung's S3C2410 is an ARM-4 processor with an integrated
-	  full speed USB 1.1 device controller.  It has 4 configurable
-	  endpoints, as well as endpoint zero (for control transfers).
+	   The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge.
+	   It is a USB Highspeed DMA capable USB device controller. Beside ep0
+	   it provides 4 IN and 4 OUT endpoints (bulk or interrupt type).
+	   The UDC port supports OTG operation, and may be used as a host port
+	   if it's not being used to implement peripheral or OTG roles.
 
-	  This driver has been tested on the S3C2410, S3C2412, and
-	  S3C2440 processors.
+	   Say "y" to link the driver statically, or "m" to build a
+	   dynamically linked module called "amd5536udc" and force all
+	   gadget drivers to also be dynamically linked.
 
-config USB_S3C2410
+config USB_AMD5536UDC
 	tristate
-	depends on USB_GADGET_S3C2410
+	depends on USB_GADGET_AMD5536UDC
 	default USB_GADGET
 	select USB_GADGET_SELECTED
 
-config USB_S3C2410_DEBUG
-	boolean "S3C2410 udc debug messages"
-	depends on USB_GADGET_S3C2410
+config USB_GADGET_FSL_QE
+	boolean "Freescale QE/CPM USB Device Controller"
+	depends on FSL_SOC && (QUICC_ENGINE || CPM)
+	help
+	   Some of Freescale PowerPC processors have a Full Speed
+	   QE/CPM2 USB controller, which support device mode with 4
+	   programmable endpoints. This driver supports the
+	   controller in the MPC8360 and MPC8272, and should work with
+	   controllers having QE or CPM2, given minor tweaks.
 
-config USB_GADGET_AT91
-	boolean "AT91 USB Device Port"
-	depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9
+	   Set CONFIG_USB_GADGET to "m" to build this driver as a
+	   dynmically linked module called "fsl_qe_udc".
+
+config USB_FSL_QE
+	tristate
+	depends on USB_GADGET_FSL_QE
+	default USB_GADGET
 	select USB_GADGET_SELECTED
+
+config USB_GADGET_NET2280
+	boolean "NetChip 228x"
+	depends on PCI
+	select USB_GADGET_DUALSPEED
 	help
-	   Many Atmel AT91 processors (such as the AT91RM2000) have a
-	   full speed USB Device Port with support for five configurable
-	   endpoints (plus endpoint zero).
+	   NetChip 2280 / 2282 is a PCI based USB peripheral controller which
+	   supports both full and high speed USB 2.0 data transfers.
+
+	   It has six configurable endpoints, as well as endpoint zero
+	   (for control transfers) and several endpoints with dedicated
+	   functions.
 
 	   Say "y" to link the driver statically, or "m" to build a
-	   dynamically linked module called "at91_udc" and force all
+	   dynamically linked module called "net2280" and force all
 	   gadget drivers to also be dynamically linked.
 
-config USB_AT91
+config USB_NET2280
 	tristate
-	depends on USB_GADGET_AT91
+	depends on USB_GADGET_NET2280
+	default USB_GADGET
+	select USB_GADGET_SELECTED
+
+config USB_GADGET_GOKU
+	boolean "Toshiba TC86C001 'Goku-S'"
+	depends on PCI
+	help
+	   The Toshiba TC86C001 is a PCI device which includes controllers
+	   for full speed USB devices, IDE, I2C, SIO, plus a USB host (OHCI).
+
+	   The device controller has three configurable (bulk or interrupt)
+	   endpoints, plus endpoint zero (for control transfers).
+
+	   Say "y" to link the driver statically, or "m" to build a
+	   dynamically linked module called "goku_udc" and to force all
+	   gadget drivers to also be dynamically linked.
+
+config USB_GOKU
+	tristate
+	depends on USB_GADGET_GOKU
 	default USB_GADGET
+	select USB_GADGET_SELECTED
+
+
+#
+# LAST -- dummy/emulated controller
+#
 
 config USB_GADGET_DUMMY_HCD
 	boolean "Dummy HCD (DEVELOPMENT)"
@@ -553,19 +612,23 @@ config USB_FILE_STORAGE_TEST
 	  normal operation.
 
 config USB_G_SERIAL
-	tristate "Serial Gadget (with CDC ACM support)"
+	tristate "Serial Gadget (with CDC ACM and CDC OBEX support)"
 	help
 	  The Serial Gadget talks to the Linux-USB generic serial driver.
 	  This driver supports a CDC-ACM module option, which can be used
 	  to interoperate with MS-Windows hosts or with the Linux-USB
 	  "cdc-acm" driver.
 
+	  This driver also supports a CDC-OBEX option.  You will need a
+	  user space OBEX server talking to /dev/ttyGS*, since the kernel
+	  itself doesn't implement the OBEX protocol.
+
 	  Say "y" to link the driver statically, or "m" to build a
 	  dynamically linked module called "g_serial".
 
 	  For more information, see Documentation/usb/gadget_serial.txt
 	  which includes instructions and a "driver info file" needed to
-	  make MS-Windows work with this driver.
+	  make MS-Windows work with CDC ACM.
 
 config USB_MIDI_GADGET
 	tristate "MIDI Gadget (EXPERIMENTAL)"

+ 1 - 0
drivers/usb/gadget/Makefile

@@ -18,6 +18,7 @@ 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
 obj-$(CONFIG_USB_M66592)	+= m66592-udc.o
+obj-$(CONFIG_USB_FSL_QE)	+= fsl_qe_udc.o
 
 #
 # USB gadget drivers

+ 0 - 1
drivers/usb/gadget/cdc2.c

@@ -155,7 +155,6 @@ static struct usb_configuration cdc_config_driver = {
 	.bConfigurationValue	= 1,
 	/* .iConfiguration = DYNAMIC */
 	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
-	.bMaxPower		= 1,	/* 2 mA, minimal */
 };
 
 /*-------------------------------------------------------------------------*/

+ 66 - 2
drivers/usb/gadget/composite.c

@@ -127,6 +127,70 @@ done:
 	return value;
 }
 
+/**
+ * usb_function_deactivate - prevent function and gadget enumeration
+ * @function: the function that isn't yet ready to respond
+ *
+ * Blocks response of the gadget driver to host enumeration by
+ * preventing the data line pullup from being activated.  This is
+ * normally called during @bind() processing to change from the
+ * initial "ready to respond" state, or when a required resource
+ * becomes available.
+ *
+ * For example, drivers that serve as a passthrough to a userspace
+ * daemon can block enumeration unless that daemon (such as an OBEX,
+ * MTP, or print server) is ready to handle host requests.
+ *
+ * Not all systems support software control of their USB peripheral
+ * data pullups.
+ *
+ * Returns zero on success, else negative errno.
+ */
+int usb_function_deactivate(struct usb_function *function)
+{
+	struct usb_composite_dev	*cdev = function->config->cdev;
+	int				status = 0;
+
+	spin_lock(&cdev->lock);
+
+	if (cdev->deactivations == 0)
+		status = usb_gadget_disconnect(cdev->gadget);
+	if (status == 0)
+		cdev->deactivations++;
+
+	spin_unlock(&cdev->lock);
+	return status;
+}
+
+/**
+ * usb_function_activate - allow function and gadget enumeration
+ * @function: function on which usb_function_activate() was called
+ *
+ * Reverses effect of usb_function_deactivate().  If no more functions
+ * are delaying their activation, the gadget driver will respond to
+ * host enumeration procedures.
+ *
+ * Returns zero on success, else negative errno.
+ */
+int usb_function_activate(struct usb_function *function)
+{
+	struct usb_composite_dev	*cdev = function->config->cdev;
+	int				status = 0;
+
+	spin_lock(&cdev->lock);
+
+	if (WARN_ON(cdev->deactivations == 0))
+		status = -EINVAL;
+	else {
+		cdev->deactivations--;
+		if (cdev->deactivations == 0)
+			status = usb_gadget_connect(cdev->gadget);
+	}
+
+	spin_unlock(&cdev->lock);
+	return status;
+}
+
 /**
  * usb_interface_id() - allocate an unused interface ID
  * @config: configuration associated with the interface
@@ -181,7 +245,7 @@ static int config_buf(struct usb_configuration *config,
 	c->bConfigurationValue = config->bConfigurationValue;
 	c->iConfiguration = config->iConfiguration;
 	c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes;
-	c->bMaxPower = config->bMaxPower;
+	c->bMaxPower = config->bMaxPower ? : (CONFIG_USB_GADGET_VBUS_DRAW / 2);
 
 	/* There may be e.g. OTG descriptors */
 	if (config->descriptors) {
@@ -368,7 +432,7 @@ static int set_config(struct usb_composite_dev *cdev,
 	}
 
 	/* when we return, be sure our power usage is valid */
-	power = 2 * c->bMaxPower;
+	power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW;
 done:
 	usb_gadget_vbus_draw(gadget, power);
 	return result;

+ 27 - 6
drivers/usb/gadget/dummy_hcd.c

@@ -82,6 +82,7 @@ struct dummy_ep {
 	const struct usb_endpoint_descriptor *desc;
 	struct usb_ep			ep;
 	unsigned			halted : 1;
+	unsigned			wedged : 1;
 	unsigned			already_seen : 1;
 	unsigned			setup_stage : 1;
 };
@@ -436,6 +437,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
 	/* at this point real hardware should be NAKing transfers
 	 * to that endpoint, until a buffer is queued to it.
 	 */
+	ep->halted = ep->wedged = 0;
 	retval = 0;
 done:
 	return retval;
@@ -597,7 +599,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req)
 }
 
 static int
-dummy_set_halt (struct usb_ep *_ep, int value)
+dummy_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged)
 {
 	struct dummy_ep		*ep;
 	struct dummy		*dum;
@@ -609,16 +611,32 @@ dummy_set_halt (struct usb_ep *_ep, int value)
 	if (!dum->driver)
 		return -ESHUTDOWN;
 	if (!value)
-		ep->halted = 0;
+		ep->halted = ep->wedged = 0;
 	else if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) &&
 			!list_empty (&ep->queue))
 		return -EAGAIN;
-	else
+	else {
 		ep->halted = 1;
+		if (wedged)
+			ep->wedged = 1;
+	}
 	/* FIXME clear emulated data toggle too */
 	return 0;
 }
 
+static int
+dummy_set_halt(struct usb_ep *_ep, int value)
+{
+	return dummy_set_halt_and_wedge(_ep, value, 0);
+}
+
+static int dummy_set_wedge(struct usb_ep *_ep)
+{
+	if (!_ep || _ep->name == ep0name)
+		return -EINVAL;
+	return dummy_set_halt_and_wedge(_ep, 1, 1);
+}
+
 static const struct usb_ep_ops dummy_ep_ops = {
 	.enable		= dummy_enable,
 	.disable	= dummy_disable,
@@ -630,6 +648,7 @@ static const struct usb_ep_ops dummy_ep_ops = {
 	.dequeue	= dummy_dequeue,
 
 	.set_halt	= dummy_set_halt,
+	.set_wedge	= dummy_set_wedge,
 };
 
 /*-------------------------------------------------------------------------*/
@@ -760,7 +779,8 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
 		ep->ep.name = ep_name [i];
 		ep->ep.ops = &dummy_ep_ops;
 		list_add_tail (&ep->ep.ep_list, &dum->gadget.ep_list);
-		ep->halted = ep->already_seen = ep->setup_stage = 0;
+		ep->halted = ep->wedged = ep->already_seen =
+				ep->setup_stage = 0;
 		ep->ep.maxpacket = ~0;
 		ep->last_io = jiffies;
 		ep->gadget = &dum->gadget;
@@ -1351,7 +1371,7 @@ restart:
 				} else if (setup.bRequestType == Ep_Request) {
 					// endpoint halt
 					ep2 = find_endpoint (dum, w_index);
-					if (!ep2) {
+					if (!ep2 || ep2->ep.name == ep0name) {
 						value = -EOPNOTSUPP;
 						break;
 					}
@@ -1380,7 +1400,8 @@ restart:
 						value = -EOPNOTSUPP;
 						break;
 					}
-					ep2->halted = 0;
+					if (!ep2->wedged)
+						ep2->halted = 0;
 					value = 0;
 					status = 0;
 				}

+ 0 - 2
drivers/usb/gadget/ether.c

@@ -242,7 +242,6 @@ static struct usb_configuration rndis_config_driver = {
 	.bConfigurationValue	= 2,
 	/* .iConfiguration = DYNAMIC */
 	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
-	.bMaxPower		= 1,	/* 2 mA, minimal */
 };
 
 /*-------------------------------------------------------------------------*/
@@ -271,7 +270,6 @@ static struct usb_configuration eth_config_driver = {
 	.bConfigurationValue	= 1,
 	/* .iConfiguration = DYNAMIC */
 	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
-	.bMaxPower		= 1,	/* 2 mA, minimal */
 };
 
 /*-------------------------------------------------------------------------*/

+ 0 - 1
drivers/usb/gadget/f_loopback.c

@@ -352,7 +352,6 @@ static struct usb_configuration loopback_driver = {
 	.bind		= loopback_bind_config,
 	.bConfigurationValue = 2,
 	.bmAttributes	= USB_CONFIG_ATT_SELFPOWER,
-	.bMaxPower	= 1,	/* 2 mA, minimal */
 	/* .iConfiguration = DYNAMIC */
 };
 

+ 493 - 0
drivers/usb/gadget/f_obex.c

@@ -0,0 +1,493 @@
+/*
+ * f_obex.c -- USB CDC OBEX function driver
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Contact: Felipe Balbi <felipe.balbi@nokia.com>
+ *
+ * Based on f_acm.c by Al Borchers and David Brownell.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* #define VERBOSE_DEBUG */
+
+#include <linux/kernel.h>
+#include <linux/utsname.h>
+#include <linux/device.h>
+
+#include "u_serial.h"
+#include "gadget_chips.h"
+
+
+/*
+ * This CDC OBEX function support just packages a TTY-ish byte stream.
+ * A user mode server will put it into "raw" mode and handle all the
+ * relevant protocol details ... this is just a kernel passthrough.
+ * When possible, we prevent gadget enumeration until that server is
+ * ready to handle the commands.
+ */
+
+struct obex_ep_descs {
+	struct usb_endpoint_descriptor	*obex_in;
+	struct usb_endpoint_descriptor	*obex_out;
+};
+
+struct f_obex {
+	struct gserial			port;
+	u8				ctrl_id;
+	u8				data_id;
+	u8				port_num;
+	u8				can_activate;
+
+	struct obex_ep_descs		fs;
+	struct obex_ep_descs		hs;
+};
+
+static inline struct f_obex *func_to_obex(struct usb_function *f)
+{
+	return container_of(f, struct f_obex, port.func);
+}
+
+static inline struct f_obex *port_to_obex(struct gserial *p)
+{
+	return container_of(p, struct f_obex, port);
+}
+
+/*-------------------------------------------------------------------------*/
+
+#define OBEX_CTRL_IDX	0
+#define OBEX_DATA_IDX	1
+
+static struct usb_string obex_string_defs[] = {
+	[OBEX_CTRL_IDX].s	= "CDC Object Exchange (OBEX)",
+	[OBEX_DATA_IDX].s	= "CDC OBEX Data",
+	{  },	/* end of list */
+};
+
+static struct usb_gadget_strings obex_string_table = {
+	.language		= 0x0409,	/* en-US */
+	.strings		= obex_string_defs,
+};
+
+static struct usb_gadget_strings *obex_strings[] = {
+	&obex_string_table,
+	NULL,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static struct usb_interface_descriptor obex_control_intf __initdata = {
+	.bLength		= sizeof(obex_control_intf),
+	.bDescriptorType	= USB_DT_INTERFACE,
+	.bInterfaceNumber	= 0,
+
+	.bAlternateSetting	= 0,
+	.bNumEndpoints		= 0,
+	.bInterfaceClass	= USB_CLASS_COMM,
+	.bInterfaceSubClass	= USB_CDC_SUBCLASS_OBEX,
+};
+
+static struct usb_interface_descriptor obex_data_nop_intf __initdata = {
+	.bLength		= sizeof(obex_data_nop_intf),
+	.bDescriptorType	= USB_DT_INTERFACE,
+	.bInterfaceNumber	= 1,
+
+	.bAlternateSetting	= 0,
+	.bNumEndpoints		= 0,
+	.bInterfaceClass	= USB_CLASS_CDC_DATA,
+};
+
+static struct usb_interface_descriptor obex_data_intf __initdata = {
+	.bLength		= sizeof(obex_data_intf),
+	.bDescriptorType	= USB_DT_INTERFACE,
+	.bInterfaceNumber	= 2,
+
+	.bAlternateSetting	= 1,
+	.bNumEndpoints		= 2,
+	.bInterfaceClass	= USB_CLASS_CDC_DATA,
+};
+
+static struct usb_cdc_header_desc obex_cdc_header_desc __initdata = {
+	.bLength		= sizeof(obex_cdc_header_desc),
+	.bDescriptorType	= USB_DT_CS_INTERFACE,
+	.bDescriptorSubType	= USB_CDC_HEADER_TYPE,
+	.bcdCDC			= __constant_cpu_to_le16(0x0120),
+};
+
+static struct usb_cdc_union_desc obex_cdc_union_desc __initdata = {
+	.bLength		= sizeof(obex_cdc_union_desc),
+	.bDescriptorType	= USB_DT_CS_INTERFACE,
+	.bDescriptorSubType	= USB_CDC_UNION_TYPE,
+	.bMasterInterface0	= 1,
+	.bSlaveInterface0	= 2,
+};
+
+static struct usb_cdc_obex_desc obex_desc __initdata = {
+	.bLength		= sizeof(obex_desc),
+	.bDescriptorType	= USB_DT_CS_INTERFACE,
+	.bDescriptorSubType	= USB_CDC_OBEX_TYPE,
+	.bcdVersion		= __constant_cpu_to_le16(0x0100),
+};
+
+/* High-Speed Support */
+
+static struct usb_endpoint_descriptor obex_hs_ep_out_desc __initdata = {
+	.bLength		= USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType	= USB_DT_ENDPOINT,
+
+	.bEndpointAddress	= USB_DIR_OUT,
+	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize		= __constant_cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = {
+	.bLength		= USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType	= USB_DT_ENDPOINT,
+
+	.bEndpointAddress	= USB_DIR_IN,
+	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize		= __constant_cpu_to_le16(512),
+};
+
+static struct usb_descriptor_header *hs_function[] __initdata = {
+	(struct usb_descriptor_header *) &obex_control_intf,
+	(struct usb_descriptor_header *) &obex_cdc_header_desc,
+	(struct usb_descriptor_header *) &obex_desc,
+	(struct usb_descriptor_header *) &obex_cdc_union_desc,
+
+	(struct usb_descriptor_header *) &obex_data_nop_intf,
+	(struct usb_descriptor_header *) &obex_data_intf,
+	(struct usb_descriptor_header *) &obex_hs_ep_in_desc,
+	(struct usb_descriptor_header *) &obex_hs_ep_out_desc,
+	NULL,
+};
+
+/* Full-Speed Support */
+
+static struct usb_endpoint_descriptor obex_fs_ep_in_desc __initdata = {
+	.bLength		= USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType	= USB_DT_ENDPOINT,
+
+	.bEndpointAddress	= USB_DIR_IN,
+	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_endpoint_descriptor obex_fs_ep_out_desc __initdata = {
+	.bLength		= USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType	= USB_DT_ENDPOINT,
+
+	.bEndpointAddress	= USB_DIR_OUT,
+	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_descriptor_header *fs_function[] __initdata = {
+	(struct usb_descriptor_header *) &obex_control_intf,
+	(struct usb_descriptor_header *) &obex_cdc_header_desc,
+	(struct usb_descriptor_header *) &obex_desc,
+	(struct usb_descriptor_header *) &obex_cdc_union_desc,
+
+	(struct usb_descriptor_header *) &obex_data_nop_intf,
+	(struct usb_descriptor_header *) &obex_data_intf,
+	(struct usb_descriptor_header *) &obex_fs_ep_in_desc,
+	(struct usb_descriptor_header *) &obex_fs_ep_out_desc,
+	NULL,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int obex_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+{
+	struct f_obex		*obex = func_to_obex(f);
+	struct usb_composite_dev *cdev = f->config->cdev;
+
+	if (intf == obex->ctrl_id) {
+		if (alt != 0)
+			goto fail;
+		/* NOP */
+		DBG(cdev, "reset obex ttyGS%d control\n", obex->port_num);
+
+	} else if (intf == obex->data_id) {
+		if (alt > 1)
+			goto fail;
+
+		if (obex->port.in->driver_data) {
+			DBG(cdev, "reset obex ttyGS%d\n", obex->port_num);
+			gserial_disconnect(&obex->port);
+		}
+
+		if (!obex->port.in_desc) {
+			DBG(cdev, "init obex ttyGS%d\n", obex->port_num);
+			obex->port.in_desc = ep_choose(cdev->gadget,
+					obex->hs.obex_in, obex->fs.obex_in);
+			obex->port.out_desc = ep_choose(cdev->gadget,
+					obex->hs.obex_out, obex->fs.obex_out);
+		}
+
+		if (alt == 1) {
+			DBG(cdev, "activate obex ttyGS%d\n", obex->port_num);
+			gserial_connect(&obex->port, obex->port_num);
+		}
+
+	} else
+		goto fail;
+
+	return 0;
+
+fail:
+	return -EINVAL;
+}
+
+static int obex_get_alt(struct usb_function *f, unsigned intf)
+{
+	struct f_obex		*obex = func_to_obex(f);
+
+	if (intf == obex->ctrl_id)
+		return 0;
+
+	return obex->port.in->driver_data ? 1 : 0;
+}
+
+static void obex_disable(struct usb_function *f)
+{
+	struct f_obex	*obex = func_to_obex(f);
+	struct usb_composite_dev *cdev = f->config->cdev;
+
+	DBG(cdev, "obex ttyGS%d disable\n", obex->port_num);
+	gserial_disconnect(&obex->port);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void obex_connect(struct gserial *g)
+{
+	struct f_obex		*obex = port_to_obex(g);
+	struct usb_composite_dev *cdev = g->func.config->cdev;
+	int			status;
+
+	if (!obex->can_activate)
+		return;
+
+	status = usb_function_activate(&g->func);
+	if (status)
+		DBG(cdev, "obex ttyGS%d function activate --> %d\n",
+			obex->port_num, status);
+}
+
+static void obex_disconnect(struct gserial *g)
+{
+	struct f_obex		*obex = port_to_obex(g);
+	struct usb_composite_dev *cdev = g->func.config->cdev;
+	int			status;
+
+	if (!obex->can_activate)
+		return;
+
+	status = usb_function_deactivate(&g->func);
+	if (status)
+		DBG(cdev, "obex ttyGS%d function deactivate --> %d\n",
+			obex->port_num, status);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int __init
+obex_bind(struct usb_configuration *c, struct usb_function *f)
+{
+	struct usb_composite_dev *cdev = c->cdev;
+	struct f_obex		*obex = func_to_obex(f);
+	int			status;
+	struct usb_ep		*ep;
+
+	/* allocate instance-specific interface IDs, and patch descriptors */
+
+	status = usb_interface_id(c, f);
+	if (status < 0)
+		goto fail;
+	obex->ctrl_id = status;
+
+	obex_control_intf.bInterfaceNumber = status;
+	obex_cdc_union_desc.bMasterInterface0 = status;
+
+	status = usb_interface_id(c, f);
+	if (status < 0)
+		goto fail;
+	obex->data_id = status;
+
+	obex_data_nop_intf.bInterfaceNumber = status;
+	obex_data_intf.bInterfaceNumber = status;
+	obex_cdc_union_desc.bSlaveInterface0 = status;
+
+	/* allocate instance-specific endpoints */
+
+	ep = usb_ep_autoconfig(cdev->gadget, &obex_fs_ep_in_desc);
+	if (!ep)
+		goto fail;
+	obex->port.in = ep;
+	ep->driver_data = cdev;	/* claim */
+
+	ep = usb_ep_autoconfig(cdev->gadget, &obex_fs_ep_out_desc);
+	if (!ep)
+		goto fail;
+	obex->port.out = ep;
+	ep->driver_data = cdev;	/* claim */
+
+	/* copy descriptors, and track endpoint copies */
+	f->descriptors = usb_copy_descriptors(fs_function);
+
+	obex->fs.obex_in = usb_find_endpoint(fs_function,
+			f->descriptors, &obex_fs_ep_in_desc);
+	obex->fs.obex_out = usb_find_endpoint(fs_function,
+			f->descriptors, &obex_fs_ep_out_desc);
+
+	/* support all relevant hardware speeds... we expect that when
+	 * hardware is dual speed, all bulk-capable endpoints work at
+	 * both speeds
+	 */
+	if (gadget_is_dualspeed(c->cdev->gadget)) {
+
+		obex_hs_ep_in_desc.bEndpointAddress =
+				obex_fs_ep_in_desc.bEndpointAddress;
+		obex_hs_ep_out_desc.bEndpointAddress =
+				obex_fs_ep_out_desc.bEndpointAddress;
+
+		/* copy descriptors, and track endpoint copies */
+		f->hs_descriptors = usb_copy_descriptors(hs_function);
+
+		obex->hs.obex_in = usb_find_endpoint(hs_function,
+				f->descriptors, &obex_hs_ep_in_desc);
+		obex->hs.obex_out = usb_find_endpoint(hs_function,
+				f->descriptors, &obex_hs_ep_out_desc);
+	}
+
+	/* Avoid letting this gadget enumerate until the userspace
+	 * OBEX server is active.
+	 */
+	status = usb_function_deactivate(f);
+	if (status < 0)
+		WARNING(cdev, "obex ttyGS%d: can't prevent enumeration, %d\n",
+			obex->port_num, status);
+	else
+		obex->can_activate = true;
+
+
+	DBG(cdev, "obex ttyGS%d: %s speed IN/%s OUT/%s\n",
+			obex->port_num,
+			gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
+			obex->port.in->name, obex->port.out->name);
+
+	return 0;
+
+fail:
+	/* we might as well release our claims on endpoints */
+	if (obex->port.out)
+		obex->port.out->driver_data = NULL;
+	if (obex->port.in)
+		obex->port.in->driver_data = NULL;
+
+	ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status);
+
+	return status;
+}
+
+static void
+obex_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+	if (gadget_is_dualspeed(c->cdev->gadget))
+		usb_free_descriptors(f->hs_descriptors);
+	usb_free_descriptors(f->descriptors);
+	kfree(func_to_obex(f));
+}
+
+/* Some controllers can't support CDC OBEX ... */
+static inline bool can_support_obex(struct usb_configuration *c)
+{
+	/* Since the first interface is a NOP, we can ignore the
+	 * issue of multi-interface support on most controllers.
+	 *
+	 * Altsettings are mandatory, however...
+	 */
+	if (!gadget_supports_altsettings(c->cdev->gadget))
+		return false;
+
+	/* everything else is *probably* fine ... */
+	return true;
+}
+
+/**
+ * obex_bind_config - add a CDC OBEX function to a configuration
+ * @c: the configuration to support the CDC OBEX instance
+ * @port_num: /dev/ttyGS* port this interface will use
+ * Context: single threaded during gadget setup
+ *
+ * Returns zero on success, else negative errno.
+ *
+ * Caller must have called @gserial_setup() with enough ports to
+ * handle all the ones it binds.  Caller is also responsible
+ * for calling @gserial_cleanup() before module unload.
+ */
+int __init obex_bind_config(struct usb_configuration *c, u8 port_num)
+{
+	struct f_obex	*obex;
+	int		status;
+
+	if (!can_support_obex(c))
+		return -EINVAL;
+
+	/* maybe allocate device-global string IDs, and patch descriptors */
+	if (obex_string_defs[OBEX_CTRL_IDX].id == 0) {
+		status = usb_string_id(c->cdev);
+		if (status < 0)
+			return status;
+		obex_string_defs[OBEX_CTRL_IDX].id = status;
+
+		obex_control_intf.iInterface = status;
+
+		status = usb_string_id(c->cdev);
+		if (status < 0)
+			return status;
+		obex_string_defs[OBEX_DATA_IDX].id = status;
+
+		obex_data_nop_intf.iInterface =
+			obex_data_intf.iInterface = status;
+	}
+
+	/* allocate and initialize one new instance */
+	obex = kzalloc(sizeof *obex, GFP_KERNEL);
+	if (!obex)
+		return -ENOMEM;
+
+	obex->port_num = port_num;
+
+	obex->port.connect = obex_connect;
+	obex->port.disconnect = obex_disconnect;
+
+	obex->port.func.name = "obex";
+	obex->port.func.strings = obex_strings;
+	/* descriptors are per-instance copies */
+	obex->port.func.bind = obex_bind;
+	obex->port.func.unbind = obex_unbind;
+	obex->port.func.set_alt = obex_set_alt;
+	obex->port.func.get_alt = obex_get_alt;
+	obex->port.func.disable = obex_disable;
+
+	status = usb_add_function(c, &obex->port.func);
+	if (status)
+		kfree(obex);
+
+	return status;
+}
+
+MODULE_AUTHOR("Felipe Balbi");
+MODULE_LICENSE("GPL");

+ 0 - 1
drivers/usb/gadget/f_sourcesink.c

@@ -552,7 +552,6 @@ static struct usb_configuration sourcesink_driver = {
 	.setup		= sourcesink_setup,
 	.bConfigurationValue = 3,
 	.bmAttributes	= USB_CONFIG_ATT_SELFPOWER,
-	.bMaxPower	= 1,	/* 2 mA, minimal */
 	/* .iConfiguration = DYNAMIC */
 };
 

+ 18 - 5
drivers/usb/gadget/file_storage.c

@@ -851,7 +851,7 @@ config_desc = {
 	.bConfigurationValue =	CONFIG_VALUE,
 	.iConfiguration =	STRING_CONFIG,
 	.bmAttributes =		USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
-	.bMaxPower =		1,	// self-powered
+	.bMaxPower =		CONFIG_USB_GADGET_VBUS_DRAW / 2,
 };
 
 static struct usb_otg_descriptor
@@ -2676,11 +2676,24 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
 	/* Verify the length of the command itself */
 	if (cmnd_size != fsg->cmnd_size) {
 
-		/* Special case workaround: MS-Windows issues REQUEST SENSE
-		 * with cbw->Length == 12 (it should be 6). */
-		if (fsg->cmnd[0] == SC_REQUEST_SENSE && fsg->cmnd_size == 12)
+		/* Special case workaround: There are plenty of buggy SCSI
+		 * implementations. Many have issues with cbw->Length
+		 * field passing a wrong command size. For those cases we
+		 * always try to work around the problem by using the length
+		 * sent by the host side provided it is at least as large
+		 * as the correct command length.
+		 * Examples of such cases would be MS-Windows, which issues
+		 * REQUEST SENSE with cbw->Length == 12 where it should
+		 * be 6, and xbox360 issuing INQUIRY, TEST UNIT READY and
+		 * REQUEST SENSE with cbw->Length == 10 where it should
+		 * be 6 as well.
+		 */
+		if (cmnd_size <= fsg->cmnd_size) {
+			DBG(fsg, "%s is buggy! Expected length %d "
+					"but we got %d\n", name,
+					cmnd_size, fsg->cmnd_size);
 			cmnd_size = fsg->cmnd_size;
-		else {
+		} else {
 			fsg->phase_error = 1;
 			return -EINVAL;
 		}

+ 2760 - 0
drivers/usb/gadget/fsl_qe_udc.c

@@ -0,0 +1,2760 @@
+/*
+ * driver/usb/gadget/fsl_qe_udc.c
+ *
+ * Copyright (c) 2006-2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * 	Xie Xiaobo <X.Xie@freescale.com>
+ * 	Li Yang <leoli@freescale.com>
+ * 	Based on bareboard code from Shlomi Gridish.
+ *
+ * Description:
+ * Freescle QE/CPM USB Pheripheral Controller Driver
+ * The controller can be found on MPC8360, MPC8272, and etc.
+ * MPC8360 Rev 1.1 may need QE mircocode update
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation;  either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#undef USB_TRACE
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/moduleparam.h>
+#include <linux/of_platform.h>
+#include <linux/dma-mapping.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/otg.h>
+#include <asm/qe.h>
+#include <asm/cpm.h>
+#include <asm/dma.h>
+#include <asm/reg.h>
+#include "fsl_qe_udc.h"
+
+#define DRIVER_DESC     "Freescale QE/CPM USB Device Controller driver"
+#define DRIVER_AUTHOR   "Xie XiaoBo"
+#define DRIVER_VERSION  "1.0"
+
+#define DMA_ADDR_INVALID        (~(dma_addr_t)0)
+
+static const char driver_name[] = "fsl_qe_udc";
+static const char driver_desc[] = DRIVER_DESC;
+
+/*ep name is important in gadget, it should obey the convention of ep_match()*/
+static const char *const ep_name[] = {
+	"ep0-control", /* everyone has ep0 */
+	/* 3 configurable endpoints */
+	"ep1",
+	"ep2",
+	"ep3",
+};
+
+static struct usb_endpoint_descriptor qe_ep0_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	0,
+	.bmAttributes =		USB_ENDPOINT_XFER_CONTROL,
+	.wMaxPacketSize =	USB_MAX_CTRL_PAYLOAD,
+};
+
+/* it is initialized in probe()  */
+static struct qe_udc *udc_controller;
+
+/********************************************************************
+ *      Internal Used Function Start
+********************************************************************/
+/*-----------------------------------------------------------------
+ * done() - retire a request; caller blocked irqs
+ *--------------------------------------------------------------*/
+static void done(struct qe_ep *ep, struct qe_req *req, int status)
+{
+	struct qe_udc *udc = ep->udc;
+	unsigned char stopped = ep->stopped;
+
+	/* the req->queue pointer is used by ep_queue() func, in which
+	 * the request will be added into a udc_ep->queue 'd tail
+	 * so here the req will be dropped from the ep->queue
+	 */
+	list_del_init(&req->queue);
+
+	/* req.status should be set as -EINPROGRESS in ep_queue() */
+	if (req->req.status == -EINPROGRESS)
+		req->req.status = status;
+	else
+		status = req->req.status;
+
+	if (req->mapped) {
+		dma_unmap_single(udc->gadget.dev.parent,
+			req->req.dma, req->req.length,
+			ep_is_in(ep)
+				? DMA_TO_DEVICE
+				: DMA_FROM_DEVICE);
+		req->req.dma = DMA_ADDR_INVALID;
+		req->mapped = 0;
+	} else
+		dma_sync_single_for_cpu(udc->gadget.dev.parent,
+			req->req.dma, req->req.length,
+			ep_is_in(ep)
+				? DMA_TO_DEVICE
+				: DMA_FROM_DEVICE);
+
+	if (status && (status != -ESHUTDOWN))
+		dev_vdbg(udc->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;
+	spin_unlock(&udc->lock);
+
+	/* this complete() should a func implemented by gadget layer,
+	 * eg fsg->bulk_in_complete() */
+	if (req->req.complete)
+		req->req.complete(&ep->ep, &req->req);
+
+	spin_lock(&udc->lock);
+
+	ep->stopped = stopped;
+}
+
+/*-----------------------------------------------------------------
+ * nuke(): delete all requests related to this ep
+ *--------------------------------------------------------------*/
+static void nuke(struct qe_ep *ep, int status)
+{
+	/* Whether this eq has request linked */
+	while (!list_empty(&ep->queue)) {
+		struct qe_req *req = NULL;
+		req = list_entry(ep->queue.next, struct qe_req, queue);
+
+		done(ep, req, status);
+	}
+}
+
+/*---------------------------------------------------------------------------*
+ * USB and Endpoint manipulate process, include parameter and register       *
+ *---------------------------------------------------------------------------*/
+/* @value: 1--set stall 0--clean stall */
+static int qe_eprx_stall_change(struct qe_ep *ep, int value)
+{
+	u16 tem_usep;
+	u8 epnum = ep->epnum;
+	struct qe_udc *udc = ep->udc;
+
+	tem_usep = in_be16(&udc->usb_regs->usb_usep[epnum]);
+	tem_usep = tem_usep & ~USB_RHS_MASK;
+	if (value == 1)
+		tem_usep |= USB_RHS_STALL;
+	else if (ep->dir == USB_DIR_IN)
+		tem_usep |= USB_RHS_IGNORE_OUT;
+
+	out_be16(&udc->usb_regs->usb_usep[epnum], tem_usep);
+	return 0;
+}
+
+static int qe_eptx_stall_change(struct qe_ep *ep, int value)
+{
+	u16 tem_usep;
+	u8 epnum = ep->epnum;
+	struct qe_udc *udc = ep->udc;
+
+	tem_usep = in_be16(&udc->usb_regs->usb_usep[epnum]);
+	tem_usep = tem_usep & ~USB_THS_MASK;
+	if (value == 1)
+		tem_usep |= USB_THS_STALL;
+	else if (ep->dir == USB_DIR_OUT)
+		tem_usep |= USB_THS_IGNORE_IN;
+
+	out_be16(&udc->usb_regs->usb_usep[epnum], tem_usep);
+
+	return 0;
+}
+
+static int qe_ep0_stall(struct qe_udc *udc)
+{
+	qe_eptx_stall_change(&udc->eps[0], 1);
+	qe_eprx_stall_change(&udc->eps[0], 1);
+	udc_controller->ep0_state = WAIT_FOR_SETUP;
+	udc_controller->ep0_dir = 0;
+	return 0;
+}
+
+static int qe_eprx_nack(struct qe_ep *ep)
+{
+	u8 epnum = ep->epnum;
+	struct qe_udc *udc = ep->udc;
+
+	if (ep->state == EP_STATE_IDLE) {
+		/* Set the ep's nack */
+		clrsetbits_be16(&udc->usb_regs->usb_usep[epnum],
+				USB_RHS_MASK, USB_RHS_NACK);
+
+		/* Mask Rx and Busy interrupts */
+		clrbits16(&udc->usb_regs->usb_usbmr,
+				(USB_E_RXB_MASK | USB_E_BSY_MASK));
+
+		ep->state = EP_STATE_NACK;
+	}
+	return 0;
+}
+
+static int qe_eprx_normal(struct qe_ep *ep)
+{
+	struct qe_udc *udc = ep->udc;
+
+	if (ep->state == EP_STATE_NACK) {
+		clrsetbits_be16(&udc->usb_regs->usb_usep[ep->epnum],
+				USB_RTHS_MASK, USB_THS_IGNORE_IN);
+
+		/* Unmask RX interrupts */
+		out_be16(&udc->usb_regs->usb_usber,
+				USB_E_BSY_MASK | USB_E_RXB_MASK);
+		setbits16(&udc->usb_regs->usb_usbmr,
+				(USB_E_RXB_MASK | USB_E_BSY_MASK));
+
+		ep->state = EP_STATE_IDLE;
+		ep->has_data = 0;
+	}
+
+	return 0;
+}
+
+static int qe_ep_cmd_stoptx(struct qe_ep *ep)
+{
+	if (ep->udc->soc_type == PORT_CPM)
+		cpm_command(CPM_USB_STOP_TX | (ep->epnum << CPM_USB_EP_SHIFT),
+				CPM_USB_STOP_TX_OPCODE);
+	else
+		qe_issue_cmd(QE_USB_STOP_TX, QE_CR_SUBBLOCK_USB,
+				ep->epnum, 0);
+
+	return 0;
+}
+
+static int qe_ep_cmd_restarttx(struct qe_ep *ep)
+{
+	if (ep->udc->soc_type == PORT_CPM)
+		cpm_command(CPM_USB_RESTART_TX | (ep->epnum <<
+				CPM_USB_EP_SHIFT), CPM_USB_RESTART_TX_OPCODE);
+	else
+		qe_issue_cmd(QE_USB_RESTART_TX, QE_CR_SUBBLOCK_USB,
+				ep->epnum, 0);
+
+	return 0;
+}
+
+static int qe_ep_flushtxfifo(struct qe_ep *ep)
+{
+	struct qe_udc *udc = ep->udc;
+	int i;
+
+	i = (int)ep->epnum;
+
+	qe_ep_cmd_stoptx(ep);
+	out_8(&udc->usb_regs->usb_uscom,
+		USB_CMD_FLUSH_FIFO | (USB_CMD_EP_MASK & (ep->epnum)));
+	out_be16(&udc->ep_param[i]->tbptr, in_be16(&udc->ep_param[i]->tbase));
+	out_be32(&udc->ep_param[i]->tstate, 0);
+	out_be16(&udc->ep_param[i]->tbcnt, 0);
+
+	ep->c_txbd = ep->txbase;
+	ep->n_txbd = ep->txbase;
+	qe_ep_cmd_restarttx(ep);
+	return 0;
+}
+
+static int qe_ep_filltxfifo(struct qe_ep *ep)
+{
+	struct qe_udc *udc = ep->udc;
+
+	out_8(&udc->usb_regs->usb_uscom,
+			USB_CMD_STR_FIFO | (USB_CMD_EP_MASK & (ep->epnum)));
+	return 0;
+}
+
+static int qe_epbds_reset(struct qe_udc *udc, int pipe_num)
+{
+	struct qe_ep *ep;
+	u32 bdring_len;
+	struct qe_bd __iomem *bd;
+	int i;
+
+	ep = &udc->eps[pipe_num];
+
+	if (ep->dir == USB_DIR_OUT)
+		bdring_len = USB_BDRING_LEN_RX;
+	else
+		bdring_len = USB_BDRING_LEN;
+
+	bd = ep->rxbase;
+	for (i = 0; i < (bdring_len - 1); i++) {
+		out_be32((u32 __iomem *)bd, R_E | R_I);
+		bd++;
+	}
+	out_be32((u32 __iomem *)bd, R_E | R_I | R_W);
+
+	bd = ep->txbase;
+	for (i = 0; i < USB_BDRING_LEN_TX - 1; i++) {
+		out_be32(&bd->buf, 0);
+		out_be32((u32 __iomem *)bd, 0);
+		bd++;
+	}
+	out_be32((u32 __iomem *)bd, T_W);
+
+	return 0;
+}
+
+static int qe_ep_reset(struct qe_udc *udc, int pipe_num)
+{
+	struct qe_ep *ep;
+	u16 tmpusep;
+
+	ep = &udc->eps[pipe_num];
+	tmpusep = in_be16(&udc->usb_regs->usb_usep[pipe_num]);
+	tmpusep &= ~USB_RTHS_MASK;
+
+	switch (ep->dir) {
+	case USB_DIR_BOTH:
+		qe_ep_flushtxfifo(ep);
+		break;
+	case USB_DIR_OUT:
+		tmpusep |= USB_THS_IGNORE_IN;
+		break;
+	case USB_DIR_IN:
+		qe_ep_flushtxfifo(ep);
+		tmpusep |= USB_RHS_IGNORE_OUT;
+		break;
+	default:
+		break;
+	}
+	out_be16(&udc->usb_regs->usb_usep[pipe_num], tmpusep);
+
+	qe_epbds_reset(udc, pipe_num);
+
+	return 0;
+}
+
+static int qe_ep_toggledata01(struct qe_ep *ep)
+{
+	ep->data01 ^= 0x1;
+	return 0;
+}
+
+static int qe_ep_bd_init(struct qe_udc *udc, unsigned char pipe_num)
+{
+	struct qe_ep *ep = &udc->eps[pipe_num];
+	unsigned long tmp_addr = 0;
+	struct usb_ep_para __iomem *epparam;
+	int i;
+	struct qe_bd __iomem *bd;
+	int bdring_len;
+
+	if (ep->dir == USB_DIR_OUT)
+		bdring_len = USB_BDRING_LEN_RX;
+	else
+		bdring_len = USB_BDRING_LEN;
+
+	epparam = udc->ep_param[pipe_num];
+	/* alloc multi-ram for BD rings and set the ep parameters */
+	tmp_addr = cpm_muram_alloc(sizeof(struct qe_bd) * (bdring_len +
+				USB_BDRING_LEN_TX), QE_ALIGNMENT_OF_BD);
+	out_be16(&epparam->rbase, (u16)tmp_addr);
+	out_be16(&epparam->tbase, (u16)(tmp_addr +
+				(sizeof(struct qe_bd) * bdring_len)));
+
+	out_be16(&epparam->rbptr, in_be16(&epparam->rbase));
+	out_be16(&epparam->tbptr, in_be16(&epparam->tbase));
+
+	ep->rxbase = cpm_muram_addr(tmp_addr);
+	ep->txbase = cpm_muram_addr(tmp_addr + (sizeof(struct qe_bd)
+				* bdring_len));
+	ep->n_rxbd = ep->rxbase;
+	ep->e_rxbd = ep->rxbase;
+	ep->n_txbd = ep->txbase;
+	ep->c_txbd = ep->txbase;
+	ep->data01 = 0; /* data0 */
+
+	/* Init TX and RX bds */
+	bd = ep->rxbase;
+	for (i = 0; i < bdring_len - 1; i++) {
+		out_be32(&bd->buf, 0);
+		out_be32((u32 __iomem *)bd, 0);
+		bd++;
+	}
+	out_be32(&bd->buf, 0);
+	out_be32((u32 __iomem *)bd, R_W);
+
+	bd = ep->txbase;
+	for (i = 0; i < USB_BDRING_LEN_TX - 1; i++) {
+		out_be32(&bd->buf, 0);
+		out_be32((u32 __iomem *)bd, 0);
+		bd++;
+	}
+	out_be32(&bd->buf, 0);
+	out_be32((u32 __iomem *)bd, T_W);
+
+	return 0;
+}
+
+static int qe_ep_rxbd_update(struct qe_ep *ep)
+{
+	unsigned int size;
+	int i;
+	unsigned int tmp;
+	struct qe_bd __iomem *bd;
+	unsigned int bdring_len;
+
+	if (ep->rxbase == NULL)
+		return -EINVAL;
+
+	bd = ep->rxbase;
+
+	ep->rxframe = kmalloc(sizeof(*ep->rxframe), GFP_ATOMIC);
+	if (ep->rxframe == NULL) {
+		dev_err(ep->udc->dev, "malloc rxframe failed\n");
+		return -ENOMEM;
+	}
+
+	qe_frame_init(ep->rxframe);
+
+	if (ep->dir == USB_DIR_OUT)
+		bdring_len = USB_BDRING_LEN_RX;
+	else
+		bdring_len = USB_BDRING_LEN;
+
+	size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) * (bdring_len + 1);
+	ep->rxbuffer = kzalloc(size, GFP_ATOMIC);
+	if (ep->rxbuffer == NULL) {
+		dev_err(ep->udc->dev, "malloc rxbuffer failed,size=%d\n",
+				size);
+		kfree(ep->rxframe);
+		return -ENOMEM;
+	}
+
+	ep->rxbuf_d = virt_to_phys((void *)ep->rxbuffer);
+	if (ep->rxbuf_d == DMA_ADDR_INVALID) {
+		ep->rxbuf_d = dma_map_single(udc_controller->gadget.dev.parent,
+					ep->rxbuffer,
+					size,
+					DMA_FROM_DEVICE);
+		ep->rxbufmap = 1;
+	} else {
+		dma_sync_single_for_device(udc_controller->gadget.dev.parent,
+					ep->rxbuf_d, size,
+					DMA_FROM_DEVICE);
+		ep->rxbufmap = 0;
+	}
+
+	size = ep->ep.maxpacket + USB_CRC_SIZE + 2;
+	tmp = ep->rxbuf_d;
+	tmp = (u32)(((tmp >> 2) << 2) + 4);
+
+	for (i = 0; i < bdring_len - 1; i++) {
+		out_be32(&bd->buf, tmp);
+		out_be32((u32 __iomem *)bd, (R_E | R_I));
+		tmp = tmp + size;
+		bd++;
+	}
+	out_be32(&bd->buf, tmp);
+	out_be32((u32 __iomem *)bd, (R_E | R_I | R_W));
+
+	return 0;
+}
+
+static int qe_ep_register_init(struct qe_udc *udc, unsigned char pipe_num)
+{
+	struct qe_ep *ep = &udc->eps[pipe_num];
+	struct usb_ep_para __iomem *epparam;
+	u16 usep, logepnum;
+	u16 tmp;
+	u8 rtfcr = 0;
+
+	epparam = udc->ep_param[pipe_num];
+
+	usep = 0;
+	logepnum = (ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+	usep |= (logepnum << USB_EPNUM_SHIFT);
+
+	switch (ep->desc->bmAttributes & 0x03) {
+	case USB_ENDPOINT_XFER_BULK:
+		usep |= USB_TRANS_BULK;
+		break;
+	case USB_ENDPOINT_XFER_ISOC:
+		usep |=  USB_TRANS_ISO;
+		break;
+	case USB_ENDPOINT_XFER_INT:
+		usep |= USB_TRANS_INT;
+		break;
+	default:
+		usep |= USB_TRANS_CTR;
+		break;
+	}
+
+	switch (ep->dir) {
+	case USB_DIR_OUT:
+		usep |= USB_THS_IGNORE_IN;
+		break;
+	case USB_DIR_IN:
+		usep |= USB_RHS_IGNORE_OUT;
+		break;
+	default:
+		break;
+	}
+	out_be16(&udc->usb_regs->usb_usep[pipe_num], usep);
+
+	rtfcr = 0x30;
+	out_8(&epparam->rbmr, rtfcr);
+	out_8(&epparam->tbmr, rtfcr);
+
+	tmp = (u16)(ep->ep.maxpacket + USB_CRC_SIZE);
+	/* MRBLR must be divisble by 4 */
+	tmp = (u16)(((tmp >> 2) << 2) + 4);
+	out_be16(&epparam->mrblr, tmp);
+
+	return 0;
+}
+
+static int qe_ep_init(struct qe_udc *udc,
+		      unsigned char pipe_num,
+		      const struct usb_endpoint_descriptor *desc)
+{
+	struct qe_ep *ep = &udc->eps[pipe_num];
+	unsigned long flags;
+	int reval = 0;
+	u16 max = 0;
+
+	max = le16_to_cpu(desc->wMaxPacketSize);
+
+	/* check the max package size validate for this endpoint */
+	/* Refer to USB2.0 spec table 9-13,
+	*/
+	if (pipe_num != 0) {
+		switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+		case USB_ENDPOINT_XFER_BULK:
+			if (strstr(ep->ep.name, "-iso")
+					|| strstr(ep->ep.name, "-int"))
+				goto en_done;
+			switch (udc->gadget.speed) {
+			case USB_SPEED_HIGH:
+			if ((max == 128) || (max == 256) || (max == 512))
+				break;
+			default:
+				switch (max) {
+				case 4:
+				case 8:
+				case 16:
+				case 32:
+				case 64:
+					break;
+				default:
+				case USB_SPEED_LOW:
+					goto en_done;
+				}
+			}
+			break;
+		case USB_ENDPOINT_XFER_INT:
+			if (strstr(ep->ep.name, "-iso"))	/* bulk is ok */
+				goto en_done;
+			switch (udc->gadget.speed) {
+			case USB_SPEED_HIGH:
+				if (max <= 1024)
+					break;
+			case USB_SPEED_FULL:
+				if (max <= 64)
+					break;
+			default:
+				if (max <= 8)
+					break;
+				goto en_done;
+			}
+			break;
+		case USB_ENDPOINT_XFER_ISOC:
+			if (strstr(ep->ep.name, "-bulk")
+				|| strstr(ep->ep.name, "-int"))
+				goto en_done;
+			switch (udc->gadget.speed) {
+			case USB_SPEED_HIGH:
+				if (max <= 1024)
+					break;
+			case USB_SPEED_FULL:
+				if (max <= 1023)
+					break;
+			default:
+				goto en_done;
+			}
+			break;
+		case USB_ENDPOINT_XFER_CONTROL:
+			if (strstr(ep->ep.name, "-iso")
+				|| strstr(ep->ep.name, "-int"))
+				goto en_done;
+			switch (udc->gadget.speed) {
+			case USB_SPEED_HIGH:
+			case USB_SPEED_FULL:
+				switch (max) {
+				case 1:
+				case 2:
+				case 4:
+				case 8:
+				case 16:
+				case 32:
+				case 64:
+					break;
+				default:
+					goto en_done;
+				}
+			case USB_SPEED_LOW:
+				switch (max) {
+				case 1:
+				case 2:
+				case 4:
+				case 8:
+					break;
+				default:
+					goto en_done;
+				}
+			default:
+				goto en_done;
+			}
+			break;
+
+		default:
+			goto en_done;
+		}
+	} /* if ep0*/
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	/* initialize ep structure */
+	ep->ep.maxpacket = max;
+	ep->tm = (u8)(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
+	ep->desc = desc;
+	ep->stopped = 0;
+	ep->init = 1;
+
+	if (pipe_num == 0) {
+		ep->dir = USB_DIR_BOTH;
+		udc->ep0_dir = USB_DIR_OUT;
+		udc->ep0_state = WAIT_FOR_SETUP;
+	} else	{
+		switch (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
+		case USB_DIR_OUT:
+			ep->dir = USB_DIR_OUT;
+			break;
+		case USB_DIR_IN:
+			ep->dir = USB_DIR_IN;
+		default:
+			break;
+		}
+	}
+
+	/* hardware special operation */
+	qe_ep_bd_init(udc, pipe_num);
+	if ((ep->tm == USBP_TM_CTL) || (ep->dir == USB_DIR_OUT)) {
+		reval = qe_ep_rxbd_update(ep);
+		if (reval)
+			goto en_done1;
+	}
+
+	if ((ep->tm == USBP_TM_CTL) || (ep->dir == USB_DIR_IN)) {
+		ep->txframe = kmalloc(sizeof(*ep->txframe), GFP_ATOMIC);
+		if (ep->txframe == NULL) {
+			dev_err(udc->dev, "malloc txframe failed\n");
+			goto en_done2;
+		}
+		qe_frame_init(ep->txframe);
+	}
+
+	qe_ep_register_init(udc, pipe_num);
+
+	/* Now HW will be NAKing transfers to that EP,
+	 * until a buffer is queued to it. */
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+en_done2:
+	kfree(ep->rxbuffer);
+	kfree(ep->rxframe);
+en_done1:
+	spin_unlock_irqrestore(&udc->lock, flags);
+en_done:
+	dev_dbg(udc->dev, "failed to initialize %s\n", ep->ep.name);
+	return -ENODEV;
+}
+
+static inline void qe_usb_enable(void)
+{
+	setbits8(&udc_controller->usb_regs->usb_usmod, USB_MODE_EN);
+}
+
+static inline void qe_usb_disable(void)
+{
+	clrbits8(&udc_controller->usb_regs->usb_usmod, USB_MODE_EN);
+}
+
+/*----------------------------------------------------------------------------*
+ *		USB and EP basic manipulate function end		      *
+ *----------------------------------------------------------------------------*/
+
+
+/******************************************************************************
+		UDC transmit and receive process
+ ******************************************************************************/
+static void recycle_one_rxbd(struct qe_ep *ep)
+{
+	u32 bdstatus;
+
+	bdstatus = in_be32((u32 __iomem *)ep->e_rxbd);
+	bdstatus = R_I | R_E | (bdstatus & R_W);
+	out_be32((u32 __iomem *)ep->e_rxbd, bdstatus);
+
+	if (bdstatus & R_W)
+		ep->e_rxbd = ep->rxbase;
+	else
+		ep->e_rxbd++;
+}
+
+static void recycle_rxbds(struct qe_ep *ep, unsigned char stopatnext)
+{
+	u32 bdstatus;
+	struct qe_bd __iomem *bd, *nextbd;
+	unsigned char stop = 0;
+
+	nextbd = ep->n_rxbd;
+	bd = ep->e_rxbd;
+	bdstatus = in_be32((u32 __iomem *)bd);
+
+	while (!(bdstatus & R_E) && !(bdstatus & BD_LENGTH_MASK) && !stop) {
+		bdstatus = R_E | R_I | (bdstatus & R_W);
+		out_be32((u32 __iomem *)bd, bdstatus);
+
+		if (bdstatus & R_W)
+			bd = ep->rxbase;
+		else
+			bd++;
+
+		bdstatus = in_be32((u32 __iomem *)bd);
+		if (stopatnext && (bd == nextbd))
+			stop = 1;
+	}
+
+	ep->e_rxbd = bd;
+}
+
+static void ep_recycle_rxbds(struct qe_ep *ep)
+{
+	struct qe_bd __iomem *bd = ep->n_rxbd;
+	u32 bdstatus;
+	u8 epnum = ep->epnum;
+	struct qe_udc *udc = ep->udc;
+
+	bdstatus = in_be32((u32 __iomem *)bd);
+	if (!(bdstatus & R_E) && !(bdstatus & BD_LENGTH_MASK)) {
+		bd = ep->rxbase +
+				((in_be16(&udc->ep_param[epnum]->rbptr) -
+				  in_be16(&udc->ep_param[epnum]->rbase))
+				 >> 3);
+		bdstatus = in_be32((u32 __iomem *)bd);
+
+		if (bdstatus & R_W)
+			bd = ep->rxbase;
+		else
+			bd++;
+
+		ep->e_rxbd = bd;
+		recycle_rxbds(ep, 0);
+		ep->e_rxbd = ep->n_rxbd;
+	} else
+		recycle_rxbds(ep, 1);
+
+	if (in_be16(&udc->usb_regs->usb_usber) & USB_E_BSY_MASK)
+		out_be16(&udc->usb_regs->usb_usber, USB_E_BSY_MASK);
+
+	if (ep->has_data <= 0 && (!list_empty(&ep->queue)))
+		qe_eprx_normal(ep);
+
+	ep->localnack = 0;
+}
+
+static void setup_received_handle(struct qe_udc *udc,
+					struct usb_ctrlrequest *setup);
+static int qe_ep_rxframe_handle(struct qe_ep *ep);
+static void ep0_req_complete(struct qe_udc *udc, struct qe_req *req);
+/* when BD PID is setup, handle the packet */
+static int ep0_setup_handle(struct qe_udc *udc)
+{
+	struct qe_ep *ep = &udc->eps[0];
+	struct qe_frame *pframe;
+	unsigned int fsize;
+	u8 *cp;
+
+	pframe = ep->rxframe;
+	if ((frame_get_info(pframe) & PID_SETUP)
+			&& (udc->ep0_state == WAIT_FOR_SETUP)) {
+		fsize = frame_get_length(pframe);
+		if (unlikely(fsize != 8))
+			return -EINVAL;
+		cp = (u8 *)&udc->local_setup_buff;
+		memcpy(cp, pframe->data, fsize);
+		ep->data01 = 1;
+
+		/* handle the usb command base on the usb_ctrlrequest */
+		setup_received_handle(udc, &udc->local_setup_buff);
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static int qe_ep0_rx(struct qe_udc *udc)
+{
+	struct qe_ep *ep = &udc->eps[0];
+	struct qe_frame *pframe;
+	struct qe_bd __iomem *bd;
+	u32 bdstatus, length;
+	u32 vaddr;
+
+	pframe = ep->rxframe;
+
+	if (ep->dir == USB_DIR_IN) {
+		dev_err(udc->dev, "ep0 not a control endpoint\n");
+		return -EINVAL;
+	}
+
+	bd = ep->n_rxbd;
+	bdstatus = in_be32((u32 __iomem *)bd);
+	length = bdstatus & BD_LENGTH_MASK;
+
+	while (!(bdstatus & R_E) && length) {
+		if ((bdstatus & R_F) && (bdstatus & R_L)
+			&& !(bdstatus & R_ERROR)) {
+			if (length == USB_CRC_SIZE) {
+				udc->ep0_state = WAIT_FOR_SETUP;
+				dev_vdbg(udc->dev,
+					"receive a ZLP in status phase\n");
+			} else {
+				qe_frame_clean(pframe);
+				vaddr = (u32)phys_to_virt(in_be32(&bd->buf));
+				frame_set_data(pframe, (u8 *)vaddr);
+				frame_set_length(pframe,
+						(length - USB_CRC_SIZE));
+				frame_set_status(pframe, FRAME_OK);
+				switch (bdstatus & R_PID) {
+				case R_PID_SETUP:
+					frame_set_info(pframe, PID_SETUP);
+					break;
+				case R_PID_DATA1:
+					frame_set_info(pframe, PID_DATA1);
+					break;
+				default:
+					frame_set_info(pframe, PID_DATA0);
+					break;
+				}
+
+				if ((bdstatus & R_PID) == R_PID_SETUP)
+					ep0_setup_handle(udc);
+				else
+					qe_ep_rxframe_handle(ep);
+			}
+		} else {
+			dev_err(udc->dev, "The receive frame with error!\n");
+		}
+
+		/* note: don't clear the rxbd's buffer address */
+		recycle_one_rxbd(ep);
+
+		/* Get next BD */
+		if (bdstatus & R_W)
+			bd = ep->rxbase;
+		else
+			bd++;
+
+		bdstatus = in_be32((u32 __iomem *)bd);
+		length = bdstatus & BD_LENGTH_MASK;
+
+	}
+
+	ep->n_rxbd = bd;
+
+	return 0;
+}
+
+static int qe_ep_rxframe_handle(struct qe_ep *ep)
+{
+	struct qe_frame *pframe;
+	u8 framepid = 0;
+	unsigned int fsize;
+	u8 *cp;
+	struct qe_req *req;
+
+	pframe = ep->rxframe;
+
+	if (frame_get_info(pframe) & PID_DATA1)
+		framepid = 0x1;
+
+	if (framepid != ep->data01) {
+		dev_err(ep->udc->dev, "the data01 error!\n");
+		return -EIO;
+	}
+
+	fsize = frame_get_length(pframe);
+	if (list_empty(&ep->queue)) {
+		dev_err(ep->udc->dev, "the %s have no requeue!\n", ep->name);
+	} else {
+		req = list_entry(ep->queue.next, struct qe_req, queue);
+
+		cp = (u8 *)(req->req.buf) + req->req.actual;
+		if (cp) {
+			memcpy(cp, pframe->data, fsize);
+			req->req.actual += fsize;
+			if ((fsize < ep->ep.maxpacket) ||
+					(req->req.actual >= req->req.length)) {
+				if (ep->epnum == 0)
+					ep0_req_complete(ep->udc, req);
+				else
+					done(ep, req, 0);
+				if (list_empty(&ep->queue) && ep->epnum != 0)
+					qe_eprx_nack(ep);
+			}
+		}
+	}
+
+	qe_ep_toggledata01(ep);
+
+	return 0;
+}
+
+static void ep_rx_tasklet(unsigned long data)
+{
+	struct qe_udc *udc = (struct qe_udc *)data;
+	struct qe_ep *ep;
+	struct qe_frame *pframe;
+	struct qe_bd __iomem *bd;
+	unsigned long flags;
+	u32 bdstatus, length;
+	u32 vaddr, i;
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	for (i = 1; i < USB_MAX_ENDPOINTS; i++) {
+		ep = &udc->eps[i];
+
+		if (ep->dir == USB_DIR_IN || ep->enable_tasklet == 0) {
+			dev_dbg(udc->dev,
+				"This is a transmit ep or disable tasklet!\n");
+			continue;
+		}
+
+		pframe = ep->rxframe;
+		bd = ep->n_rxbd;
+		bdstatus = in_be32((u32 __iomem *)bd);
+		length = bdstatus & BD_LENGTH_MASK;
+
+		while (!(bdstatus & R_E) && length) {
+			if (list_empty(&ep->queue)) {
+				qe_eprx_nack(ep);
+				dev_dbg(udc->dev,
+					"The rxep have noreq %d\n",
+					ep->has_data);
+				break;
+			}
+
+			if ((bdstatus & R_F) && (bdstatus & R_L)
+				&& !(bdstatus & R_ERROR)) {
+				qe_frame_clean(pframe);
+				vaddr = (u32)phys_to_virt(in_be32(&bd->buf));
+				frame_set_data(pframe, (u8 *)vaddr);
+				frame_set_length(pframe,
+						(length - USB_CRC_SIZE));
+				frame_set_status(pframe, FRAME_OK);
+				switch (bdstatus & R_PID) {
+				case R_PID_DATA1:
+					frame_set_info(pframe, PID_DATA1);
+					break;
+				case R_PID_SETUP:
+					frame_set_info(pframe, PID_SETUP);
+					break;
+				default:
+					frame_set_info(pframe, PID_DATA0);
+					break;
+				}
+				/* handle the rx frame */
+				qe_ep_rxframe_handle(ep);
+			} else {
+				dev_err(udc->dev,
+					"error in received frame\n");
+			}
+			/* note: don't clear the rxbd's buffer address */
+			/*clear the length */
+			out_be32((u32 __iomem *)bd, bdstatus & BD_STATUS_MASK);
+			ep->has_data--;
+			if (!(ep->localnack))
+				recycle_one_rxbd(ep);
+
+			/* Get next BD */
+			if (bdstatus & R_W)
+				bd = ep->rxbase;
+			else
+				bd++;
+
+			bdstatus = in_be32((u32 __iomem *)bd);
+			length = bdstatus & BD_LENGTH_MASK;
+		}
+
+		ep->n_rxbd = bd;
+
+		if (ep->localnack)
+			ep_recycle_rxbds(ep);
+
+		ep->enable_tasklet = 0;
+	} /* for i=1 */
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+}
+
+static int qe_ep_rx(struct qe_ep *ep)
+{
+	struct qe_udc *udc;
+	struct qe_frame *pframe;
+	struct qe_bd __iomem *bd;
+	u16 swoffs, ucoffs, emptybds;
+
+	udc = ep->udc;
+	pframe = ep->rxframe;
+
+	if (ep->dir == USB_DIR_IN) {
+		dev_err(udc->dev, "transmit ep in rx function\n");
+		return -EINVAL;
+	}
+
+	bd = ep->n_rxbd;
+
+	swoffs = (u16)(bd - ep->rxbase);
+	ucoffs = (u16)((in_be16(&udc->ep_param[ep->epnum]->rbptr) -
+			in_be16(&udc->ep_param[ep->epnum]->rbase)) >> 3);
+	if (swoffs < ucoffs)
+		emptybds = USB_BDRING_LEN_RX - ucoffs + swoffs;
+	else
+		emptybds = swoffs - ucoffs;
+
+	if (emptybds < MIN_EMPTY_BDS) {
+		qe_eprx_nack(ep);
+		ep->localnack = 1;
+		dev_vdbg(udc->dev, "%d empty bds, send NACK\n", emptybds);
+	}
+	ep->has_data = USB_BDRING_LEN_RX - emptybds;
+
+	if (list_empty(&ep->queue)) {
+		qe_eprx_nack(ep);
+		dev_vdbg(udc->dev, "The rxep have no req queued with %d BDs\n",
+				ep->has_data);
+		return 0;
+	}
+
+	tasklet_schedule(&udc->rx_tasklet);
+	ep->enable_tasklet = 1;
+
+	return 0;
+}
+
+/* send data from a frame, no matter what tx_req */
+static int qe_ep_tx(struct qe_ep *ep, struct qe_frame *frame)
+{
+	struct qe_udc *udc = ep->udc;
+	struct qe_bd __iomem *bd;
+	u16 saveusbmr;
+	u32 bdstatus, pidmask;
+	u32 paddr;
+
+	if (ep->dir == USB_DIR_OUT) {
+		dev_err(udc->dev, "receive ep passed to tx function\n");
+		return -EINVAL;
+	}
+
+	/* Disable the Tx interrupt */
+	saveusbmr = in_be16(&udc->usb_regs->usb_usbmr);
+	out_be16(&udc->usb_regs->usb_usbmr,
+			saveusbmr & ~(USB_E_TXB_MASK | USB_E_TXE_MASK));
+
+	bd = ep->n_txbd;
+	bdstatus = in_be32((u32 __iomem *)bd);
+
+	if (!(bdstatus & (T_R | BD_LENGTH_MASK))) {
+		if (frame_get_length(frame) == 0) {
+			frame_set_data(frame, udc->nullbuf);
+			frame_set_length(frame, 2);
+			frame->info |= (ZLP | NO_CRC);
+			dev_vdbg(udc->dev, "the frame size = 0\n");
+		}
+		paddr = virt_to_phys((void *)frame->data);
+		out_be32(&bd->buf, paddr);
+		bdstatus = (bdstatus&T_W);
+		if (!(frame_get_info(frame) & NO_CRC))
+			bdstatus |= T_R | T_I | T_L | T_TC
+					| frame_get_length(frame);
+		else
+			bdstatus |= T_R | T_I | T_L | frame_get_length(frame);
+
+		/* if the packet is a ZLP in status phase */
+		if ((ep->epnum == 0) && (udc->ep0_state == DATA_STATE_NEED_ZLP))
+			ep->data01 = 0x1;
+
+		if (ep->data01) {
+			pidmask = T_PID_DATA1;
+			frame->info |= PID_DATA1;
+		} else {
+			pidmask = T_PID_DATA0;
+			frame->info |= PID_DATA0;
+		}
+		bdstatus |= T_CNF;
+		bdstatus |= pidmask;
+		out_be32((u32 __iomem *)bd, bdstatus);
+		qe_ep_filltxfifo(ep);
+
+		/* enable the TX interrupt */
+		out_be16(&udc->usb_regs->usb_usbmr, saveusbmr);
+
+		qe_ep_toggledata01(ep);
+		if (bdstatus & T_W)
+			ep->n_txbd = ep->txbase;
+		else
+			ep->n_txbd++;
+
+		return 0;
+	} else {
+		out_be16(&udc->usb_regs->usb_usbmr, saveusbmr);
+		dev_vdbg(udc->dev, "The tx bd is not ready!\n");
+		return -EBUSY;
+	}
+}
+
+/* when a bd was transmitted, the function can
+ * handle the tx_req, not include ep0           */
+static int txcomplete(struct qe_ep *ep, unsigned char restart)
+{
+	if (ep->tx_req != NULL) {
+		if (!restart) {
+			int asent = ep->last;
+			ep->sent += asent;
+			ep->last -= asent;
+		} else {
+			ep->last = 0;
+		}
+
+		/* a request already were transmitted completely */
+		if ((ep->tx_req->req.length - ep->sent) <= 0) {
+			ep->tx_req->req.actual = (unsigned int)ep->sent;
+			done(ep, ep->tx_req, 0);
+			ep->tx_req = NULL;
+			ep->last = 0;
+			ep->sent = 0;
+		}
+	}
+
+	/* we should gain a new tx_req fot this endpoint */
+	if (ep->tx_req == NULL) {
+		if (!list_empty(&ep->queue)) {
+			ep->tx_req = list_entry(ep->queue.next,	struct qe_req,
+							queue);
+			ep->last = 0;
+			ep->sent = 0;
+		}
+	}
+
+	return 0;
+}
+
+/* give a frame and a tx_req, send some data */
+static int qe_usb_senddata(struct qe_ep *ep, struct qe_frame *frame)
+{
+	unsigned int size;
+	u8 *buf;
+
+	qe_frame_clean(frame);
+	size = min_t(u32, (ep->tx_req->req.length - ep->sent),
+				ep->ep.maxpacket);
+	buf = (u8 *)ep->tx_req->req.buf + ep->sent;
+	if (buf && size) {
+		ep->last = size;
+		frame_set_data(frame, buf);
+		frame_set_length(frame, size);
+		frame_set_status(frame, FRAME_OK);
+		frame_set_info(frame, 0);
+		return qe_ep_tx(ep, frame);
+	}
+	return -EIO;
+}
+
+/* give a frame struct,send a ZLP */
+static int sendnulldata(struct qe_ep *ep, struct qe_frame *frame, uint infor)
+{
+	struct qe_udc *udc = ep->udc;
+
+	if (frame == NULL)
+		return -ENODEV;
+
+	qe_frame_clean(frame);
+	frame_set_data(frame, (u8 *)udc->nullbuf);
+	frame_set_length(frame, 2);
+	frame_set_status(frame, FRAME_OK);
+	frame_set_info(frame, (ZLP | NO_CRC | infor));
+
+	return qe_ep_tx(ep, frame);
+}
+
+static int frame_create_tx(struct qe_ep *ep, struct qe_frame *frame)
+{
+	struct qe_req *req = ep->tx_req;
+	int reval;
+
+	if (req == NULL)
+		return -ENODEV;
+
+	if ((req->req.length - ep->sent) > 0)
+		reval = qe_usb_senddata(ep, frame);
+	else
+		reval = sendnulldata(ep, frame, 0);
+
+	return reval;
+}
+
+/* if direction is DIR_IN, the status is Device->Host
+ * if direction is DIR_OUT, the status transaction is Device<-Host
+ * in status phase, udc create a request and gain status */
+static int ep0_prime_status(struct qe_udc *udc, int direction)
+{
+
+	struct qe_ep *ep = &udc->eps[0];
+
+	if (direction == USB_DIR_IN) {
+		udc->ep0_state = DATA_STATE_NEED_ZLP;
+		udc->ep0_dir = USB_DIR_IN;
+		sendnulldata(ep, ep->txframe, SETUP_STATUS | NO_REQ);
+	} else {
+		udc->ep0_dir = USB_DIR_OUT;
+		udc->ep0_state = WAIT_FOR_OUT_STATUS;
+	}
+
+	return 0;
+}
+
+/* a request complete in ep0, whether gadget request or udc request */
+static void ep0_req_complete(struct qe_udc *udc, struct qe_req *req)
+{
+	struct qe_ep *ep = &udc->eps[0];
+	/* because usb and ep's status already been set in ch9setaddress() */
+
+	switch (udc->ep0_state) {
+	case DATA_STATE_XMIT:
+		done(ep, req, 0);
+		/* receive status phase */
+		if (ep0_prime_status(udc, USB_DIR_OUT))
+			qe_ep0_stall(udc);
+		break;
+
+	case DATA_STATE_NEED_ZLP:
+		done(ep, req, 0);
+		udc->ep0_state = WAIT_FOR_SETUP;
+		break;
+
+	case DATA_STATE_RECV:
+		done(ep, req, 0);
+		/* send status phase */
+		if (ep0_prime_status(udc, USB_DIR_IN))
+			qe_ep0_stall(udc);
+		break;
+
+	case WAIT_FOR_OUT_STATUS:
+		done(ep, req, 0);
+		udc->ep0_state = WAIT_FOR_SETUP;
+		break;
+
+	case WAIT_FOR_SETUP:
+		dev_vdbg(udc->dev, "Unexpected interrupt\n");
+		break;
+
+	default:
+		qe_ep0_stall(udc);
+		break;
+	}
+}
+
+static int ep0_txcomplete(struct qe_ep *ep, unsigned char restart)
+{
+	struct qe_req *tx_req = NULL;
+	struct qe_frame *frame = ep->txframe;
+
+	if ((frame_get_info(frame) & (ZLP | NO_REQ)) == (ZLP | NO_REQ)) {
+		if (!restart)
+			ep->udc->ep0_state = WAIT_FOR_SETUP;
+		else
+			sendnulldata(ep, ep->txframe, SETUP_STATUS | NO_REQ);
+		return 0;
+	}
+
+	tx_req = ep->tx_req;
+	if (tx_req != NULL) {
+		if (!restart) {
+			int asent = ep->last;
+			ep->sent += asent;
+			ep->last -= asent;
+		} else {
+			ep->last = 0;
+		}
+
+		/* a request already were transmitted completely */
+		if ((ep->tx_req->req.length - ep->sent) <= 0) {
+			ep->tx_req->req.actual = (unsigned int)ep->sent;
+			ep0_req_complete(ep->udc, ep->tx_req);
+			ep->tx_req = NULL;
+			ep->last = 0;
+			ep->sent = 0;
+		}
+	} else {
+		dev_vdbg(ep->udc->dev, "the ep0_controller have no req\n");
+	}
+
+	return 0;
+}
+
+static int ep0_txframe_handle(struct qe_ep *ep)
+{
+	/* if have error, transmit again */
+	if (frame_get_status(ep->txframe) & FRAME_ERROR) {
+		qe_ep_flushtxfifo(ep);
+		dev_vdbg(ep->udc->dev, "The EP0 transmit data have error!\n");
+		if (frame_get_info(ep->txframe) & PID_DATA0)
+			ep->data01 = 0;
+		else
+			ep->data01 = 1;
+
+		ep0_txcomplete(ep, 1);
+	} else
+		ep0_txcomplete(ep, 0);
+
+	frame_create_tx(ep, ep->txframe);
+	return 0;
+}
+
+static int qe_ep0_txconf(struct qe_ep *ep)
+{
+	struct qe_bd __iomem *bd;
+	struct qe_frame *pframe;
+	u32 bdstatus;
+
+	bd = ep->c_txbd;
+	bdstatus = in_be32((u32 __iomem *)bd);
+	while (!(bdstatus & T_R) && (bdstatus & ~T_W)) {
+		pframe = ep->txframe;
+
+		/* clear and recycle the BD */
+		out_be32((u32 __iomem *)bd, bdstatus & T_W);
+		out_be32(&bd->buf, 0);
+		if (bdstatus & T_W)
+			ep->c_txbd = ep->txbase;
+		else
+			ep->c_txbd++;
+
+		if (ep->c_txbd == ep->n_txbd) {
+			if (bdstatus & DEVICE_T_ERROR) {
+				frame_set_status(pframe, FRAME_ERROR);
+				if (bdstatus & T_TO)
+					pframe->status |= TX_ER_TIMEOUT;
+				if (bdstatus & T_UN)
+					pframe->status |= TX_ER_UNDERUN;
+			}
+			ep0_txframe_handle(ep);
+		}
+
+		bd = ep->c_txbd;
+		bdstatus = in_be32((u32 __iomem *)bd);
+	}
+
+	return 0;
+}
+
+static int ep_txframe_handle(struct qe_ep *ep)
+{
+	if (frame_get_status(ep->txframe) & FRAME_ERROR) {
+		qe_ep_flushtxfifo(ep);
+		dev_vdbg(ep->udc->dev, "The EP0 transmit data have error!\n");
+		if (frame_get_info(ep->txframe) & PID_DATA0)
+			ep->data01 = 0;
+		else
+			ep->data01 = 1;
+
+		txcomplete(ep, 1);
+	} else
+		txcomplete(ep, 0);
+
+	frame_create_tx(ep, ep->txframe); /* send the data */
+	return 0;
+}
+
+/* confirm the already trainsmited bd */
+static int qe_ep_txconf(struct qe_ep *ep)
+{
+	struct qe_bd __iomem *bd;
+	struct qe_frame *pframe = NULL;
+	u32 bdstatus;
+	unsigned char breakonrxinterrupt = 0;
+
+	bd = ep->c_txbd;
+	bdstatus = in_be32((u32 __iomem *)bd);
+	while (!(bdstatus & T_R) && (bdstatus & ~T_W)) {
+		pframe = ep->txframe;
+		if (bdstatus & DEVICE_T_ERROR) {
+			frame_set_status(pframe, FRAME_ERROR);
+			if (bdstatus & T_TO)
+				pframe->status |= TX_ER_TIMEOUT;
+			if (bdstatus & T_UN)
+				pframe->status |= TX_ER_UNDERUN;
+		}
+
+		/* clear and recycle the BD */
+		out_be32((u32 __iomem *)bd, bdstatus & T_W);
+		out_be32(&bd->buf, 0);
+		if (bdstatus & T_W)
+			ep->c_txbd = ep->txbase;
+		else
+			ep->c_txbd++;
+
+		/* handle the tx frame */
+		ep_txframe_handle(ep);
+		bd = ep->c_txbd;
+		bdstatus = in_be32((u32 __iomem *)bd);
+	}
+	if (breakonrxinterrupt)
+		return -EIO;
+	else
+		return 0;
+}
+
+/* Add a request in queue, and try to transmit a packet */
+static int ep_req_send(struct qe_ep *ep, struct qe_req *req)
+{
+	int reval = 0;
+
+	if (ep->tx_req == NULL) {
+		ep->sent = 0;
+		ep->last = 0;
+		txcomplete(ep, 0); /* can gain a new tx_req */
+		reval = frame_create_tx(ep, ep->txframe);
+	}
+	return reval;
+}
+
+/* Maybe this is a good ideal */
+static int ep_req_rx(struct qe_ep *ep, struct qe_req *req)
+{
+	struct qe_udc *udc = ep->udc;
+	struct qe_frame *pframe = NULL;
+	struct qe_bd __iomem *bd;
+	u32 bdstatus, length;
+	u32 vaddr, fsize;
+	u8 *cp;
+	u8 finish_req = 0;
+	u8 framepid;
+
+	if (list_empty(&ep->queue)) {
+		dev_vdbg(udc->dev, "the req already finish!\n");
+		return 0;
+	}
+	pframe = ep->rxframe;
+
+	bd = ep->n_rxbd;
+	bdstatus = in_be32((u32 __iomem *)bd);
+	length = bdstatus & BD_LENGTH_MASK;
+
+	while (!(bdstatus & R_E) && length) {
+		if (finish_req)
+			break;
+		if ((bdstatus & R_F) && (bdstatus & R_L)
+					&& !(bdstatus & R_ERROR)) {
+			qe_frame_clean(pframe);
+			vaddr = (u32)phys_to_virt(in_be32(&bd->buf));
+			frame_set_data(pframe, (u8 *)vaddr);
+			frame_set_length(pframe, (length - USB_CRC_SIZE));
+			frame_set_status(pframe, FRAME_OK);
+			switch (bdstatus & R_PID) {
+			case R_PID_DATA1:
+				frame_set_info(pframe, PID_DATA1); break;
+			default:
+				frame_set_info(pframe, PID_DATA0); break;
+			}
+			/* handle the rx frame */
+
+			if (frame_get_info(pframe) & PID_DATA1)
+				framepid = 0x1;
+			else
+				framepid = 0;
+
+			if (framepid != ep->data01) {
+				dev_vdbg(udc->dev, "the data01 error!\n");
+			} else {
+				fsize = frame_get_length(pframe);
+
+				cp = (u8 *)(req->req.buf) + req->req.actual;
+				if (cp) {
+					memcpy(cp, pframe->data, fsize);
+					req->req.actual += fsize;
+					if ((fsize < ep->ep.maxpacket)
+						|| (req->req.actual >=
+							req->req.length)) {
+						finish_req = 1;
+						done(ep, req, 0);
+						if (list_empty(&ep->queue))
+							qe_eprx_nack(ep);
+					}
+				}
+				qe_ep_toggledata01(ep);
+			}
+		} else {
+			dev_err(udc->dev, "The receive frame with error!\n");
+		}
+
+		/* note: don't clear the rxbd's buffer address *
+		 * only Clear the length */
+		out_be32((u32 __iomem *)bd, (bdstatus & BD_STATUS_MASK));
+		ep->has_data--;
+
+		/* Get next BD */
+		if (bdstatus & R_W)
+			bd = ep->rxbase;
+		else
+			bd++;
+
+		bdstatus = in_be32((u32 __iomem *)bd);
+		length = bdstatus & BD_LENGTH_MASK;
+	}
+
+	ep->n_rxbd = bd;
+	ep_recycle_rxbds(ep);
+
+	return 0;
+}
+
+/* only add the request in queue */
+static int ep_req_receive(struct qe_ep *ep, struct qe_req *req)
+{
+	if (ep->state == EP_STATE_NACK) {
+		if (ep->has_data <= 0) {
+			/* Enable rx and unmask rx interrupt */
+			qe_eprx_normal(ep);
+		} else {
+			/* Copy the exist BD data */
+			ep_req_rx(ep, req);
+		}
+	}
+
+	return 0;
+}
+
+/********************************************************************
+	Internal Used Function End
+********************************************************************/
+
+/*-----------------------------------------------------------------------
+	Endpoint Management Functions For Gadget
+ -----------------------------------------------------------------------*/
+static int qe_ep_enable(struct usb_ep *_ep,
+			 const struct usb_endpoint_descriptor *desc)
+{
+	struct qe_udc *udc;
+	struct qe_ep *ep;
+	int retval = 0;
+	unsigned char epnum;
+
+	ep = container_of(_ep, struct qe_ep, ep);
+
+	/* catch various bogus parameters */
+	if (!_ep || !desc || ep->desc || _ep->name == ep_name[0] ||
+			(desc->bDescriptorType != USB_DT_ENDPOINT))
+		return -EINVAL;
+
+	udc = ep->udc;
+	if (!udc->driver || (udc->gadget.speed == USB_SPEED_UNKNOWN))
+		return -ESHUTDOWN;
+
+	epnum = (u8)desc->bEndpointAddress & 0xF;
+
+	retval = qe_ep_init(udc, epnum, desc);
+	if (retval != 0) {
+		cpm_muram_free(cpm_muram_offset(ep->rxbase));
+		dev_dbg(udc->dev, "enable ep%d failed\n", ep->epnum);
+		return -EINVAL;
+	}
+	dev_dbg(udc->dev, "enable ep%d successful\n", ep->epnum);
+	return 0;
+}
+
+static int qe_ep_disable(struct usb_ep *_ep)
+{
+	struct qe_udc *udc;
+	struct qe_ep *ep;
+	unsigned long flags;
+	unsigned int size;
+
+	ep = container_of(_ep, struct qe_ep, ep);
+	udc = ep->udc;
+
+	if (!_ep || !ep->desc) {
+		dev_dbg(udc->dev, "%s not enabled\n", _ep ? ep->ep.name : NULL);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&udc->lock, flags);
+	/* Nuke all pending requests (does flush) */
+	nuke(ep, -ESHUTDOWN);
+	ep->desc = NULL;
+	ep->stopped = 1;
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	cpm_muram_free(cpm_muram_offset(ep->rxbase));
+
+	if (ep->dir == USB_DIR_OUT)
+		size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) *
+				(USB_BDRING_LEN_RX + 1);
+	else
+		size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) *
+				(USB_BDRING_LEN + 1);
+
+	if (ep->dir != USB_DIR_IN) {
+		kfree(ep->rxframe);
+		if (ep->rxbufmap) {
+			dma_unmap_single(udc_controller->gadget.dev.parent,
+					ep->rxbuf_d, size,
+					DMA_FROM_DEVICE);
+			ep->rxbuf_d = DMA_ADDR_INVALID;
+		} else {
+			dma_sync_single_for_cpu(
+					udc_controller->gadget.dev.parent,
+					ep->rxbuf_d, size,
+					DMA_FROM_DEVICE);
+		}
+		kfree(ep->rxbuffer);
+	}
+
+	if (ep->dir != USB_DIR_OUT)
+		kfree(ep->txframe);
+
+	dev_dbg(udc->dev, "disabled %s OK\n", _ep->name);
+	return 0;
+}
+
+static struct usb_request *qe_alloc_request(struct usb_ep *_ep,	gfp_t gfp_flags)
+{
+	struct qe_req *req;
+
+	req = kzalloc(sizeof(*req), gfp_flags);
+	if (!req)
+		return NULL;
+
+	req->req.dma = DMA_ADDR_INVALID;
+
+	INIT_LIST_HEAD(&req->queue);
+
+	return &req->req;
+}
+
+static void qe_free_request(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct qe_req *req;
+
+	req = container_of(_req, struct qe_req, req);
+
+	if (_req)
+		kfree(req);
+}
+
+/* queues (submits) an I/O request to an endpoint */
+static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
+				gfp_t gfp_flags)
+{
+	struct qe_ep *ep = container_of(_ep, struct qe_ep, ep);
+	struct qe_req *req = container_of(_req, struct qe_req, req);
+	struct qe_udc *udc;
+	unsigned long flags;
+	int reval;
+
+	udc = ep->udc;
+	/* catch various bogus parameters */
+	if (!_req || !req->req.complete || !req->req.buf
+			|| !list_empty(&req->queue)) {
+		dev_dbg(udc->dev, "bad params\n");
+		return -EINVAL;
+	}
+	if (!_ep || (!ep->desc && ep_index(ep))) {
+		dev_dbg(udc->dev, "bad ep\n");
+		return -EINVAL;
+	}
+
+	if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)
+		return -ESHUTDOWN;
+
+	req->ep = ep;
+
+	/* map virtual address to hardware */
+	if (req->req.dma == DMA_ADDR_INVALID) {
+		req->req.dma = dma_map_single(ep->udc->gadget.dev.parent,
+					req->req.buf,
+					req->req.length,
+					ep_is_in(ep)
+					? DMA_TO_DEVICE :
+					DMA_FROM_DEVICE);
+		req->mapped = 1;
+	} else {
+		dma_sync_single_for_device(ep->udc->gadget.dev.parent,
+					req->req.dma, req->req.length,
+					ep_is_in(ep)
+					? DMA_TO_DEVICE :
+					DMA_FROM_DEVICE);
+		req->mapped = 0;
+	}
+
+	req->req.status = -EINPROGRESS;
+	req->req.actual = 0;
+
+	list_add_tail(&req->queue, &ep->queue);
+	dev_vdbg(udc->dev, "gadget have request in %s! %d\n",
+			ep->name, req->req.length);
+	spin_lock_irqsave(&udc->lock, flags);
+	/* push the request to device */
+	if (ep_is_in(ep))
+		reval = ep_req_send(ep, req);
+
+	/* EP0 */
+	if (ep_index(ep) == 0 && req->req.length > 0) {
+		if (ep_is_in(ep))
+			udc->ep0_state = DATA_STATE_XMIT;
+		else
+			udc->ep0_state = DATA_STATE_RECV;
+	}
+
+	if (ep->dir == USB_DIR_OUT)
+		reval = ep_req_receive(ep, req);
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return 0;
+}
+
+/* dequeues (cancels, unlinks) an I/O request from an endpoint */
+static int qe_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct qe_ep *ep = container_of(_ep, struct qe_ep, ep);
+	struct qe_req *req;
+	unsigned long flags;
+
+	if (!_ep || !_req)
+		return -EINVAL;
+
+	spin_lock_irqsave(&ep->udc->lock, flags);
+
+	/* make sure it's actually queued on this endpoint */
+	list_for_each_entry(req, &ep->queue, queue) {
+		if (&req->req == _req)
+			break;
+	}
+
+	if (&req->req != _req) {
+		spin_unlock_irqrestore(&ep->udc->lock, flags);
+		return -EINVAL;
+	}
+
+	done(ep, req, -ECONNRESET);
+
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+	return 0;
+}
+
+/*-----------------------------------------------------------------
+ * modify the endpoint halt feature
+ * @ep: the non-isochronous endpoint being stalled
+ * @value: 1--set halt  0--clear halt
+ * Returns zero, or a negative error code.
+*----------------------------------------------------------------*/
+static int qe_ep_set_halt(struct usb_ep *_ep, int value)
+{
+	struct qe_ep *ep;
+	unsigned long flags;
+	int status = -EOPNOTSUPP;
+	struct qe_udc *udc;
+
+	ep = container_of(_ep, struct qe_ep, ep);
+	if (!_ep || !ep->desc) {
+		status = -EINVAL;
+		goto out;
+	}
+
+	udc = ep->udc;
+	/* Attempt to halt IN ep will fail if any transfer requests
+	 * are still queue */
+	if (value && ep_is_in(ep) && !list_empty(&ep->queue)) {
+		status = -EAGAIN;
+		goto out;
+	}
+
+	status = 0;
+	spin_lock_irqsave(&ep->udc->lock, flags);
+	qe_eptx_stall_change(ep, value);
+	qe_eprx_stall_change(ep, value);
+	spin_unlock_irqrestore(&ep->udc->lock, flags);
+
+	if (ep->epnum == 0) {
+		udc->ep0_state = WAIT_FOR_SETUP;
+		udc->ep0_dir = 0;
+	}
+
+	/* set data toggle to DATA0 on clear halt */
+	if (value == 0)
+		ep->data01 = 0;
+out:
+	dev_vdbg(udc->dev, "%s %s halt stat %d\n", ep->ep.name,
+			value ?  "set" : "clear", status);
+
+	return status;
+}
+
+static struct usb_ep_ops qe_ep_ops = {
+	.enable = qe_ep_enable,
+	.disable = qe_ep_disable,
+
+	.alloc_request = qe_alloc_request,
+	.free_request = qe_free_request,
+
+	.queue = qe_ep_queue,
+	.dequeue = qe_ep_dequeue,
+
+	.set_halt = qe_ep_set_halt,
+};
+
+/*------------------------------------------------------------------------
+	Gadget Driver Layer Operations
+ ------------------------------------------------------------------------*/
+
+/* Get the current frame number */
+static int qe_get_frame(struct usb_gadget *gadget)
+{
+	u16 tmp;
+
+	tmp = in_be16(&udc_controller->usb_param->frame_n);
+	if (tmp & 0x8000)
+		tmp = tmp & 0x07ff;
+	else
+		tmp = -EINVAL;
+
+	return (int)tmp;
+}
+
+/* Tries to wake up the host connected to this gadget
+ *
+ * Return : 0-success
+ * Negative-this feature not enabled by host or not supported by device hw
+ */
+static int qe_wakeup(struct usb_gadget *gadget)
+{
+	return -ENOTSUPP;
+}
+
+/* Notify controller that VBUS is powered, Called by whatever
+   detects VBUS sessions */
+static int qe_vbus_session(struct usb_gadget *gadget, int is_active)
+{
+	return -ENOTSUPP;
+}
+
+/* constrain controller's VBUS power usage
+ * This call is used by gadget drivers during SET_CONFIGURATION calls,
+ * reporting how much power the device may consume.  For example, this
+ * could affect how quickly batteries are recharged.
+ *
+ * Returns zero on success, else negative errno.
+ */
+static int qe_vbus_draw(struct usb_gadget *gadget, unsigned mA)
+{
+	return -ENOTSUPP;
+}
+
+/* Change Data+ pullup status
+ * this func is used by usb_gadget_connect/disconnect
+ */
+static int qe_pullup(struct usb_gadget *gadget, int is_on)
+{
+	return -ENOTSUPP;
+}
+
+/* defined in usb_gadget.h */
+static struct usb_gadget_ops qe_gadget_ops = {
+	.get_frame = qe_get_frame,
+	.wakeup = qe_wakeup,
+/*	.set_selfpowered = qe_set_selfpowered,*/ /* always selfpowered */
+	.vbus_session = qe_vbus_session,
+	.vbus_draw = qe_vbus_draw,
+	.pullup = qe_pullup,
+};
+
+/*-------------------------------------------------------------------------
+	USB ep0 Setup process in BUS Enumeration
+ -------------------------------------------------------------------------*/
+static int udc_reset_ep_queue(struct qe_udc *udc, u8 pipe)
+{
+	struct qe_ep *ep = &udc->eps[pipe];
+
+	nuke(ep, -ECONNRESET);
+	ep->tx_req = NULL;
+	return 0;
+}
+
+static int reset_queues(struct qe_udc *udc)
+{
+	u8 pipe;
+
+	for (pipe = 0; pipe < USB_MAX_ENDPOINTS; pipe++)
+		udc_reset_ep_queue(udc, pipe);
+
+	/* report disconnect; the driver is already quiesced */
+	spin_unlock(&udc->lock);
+	udc->driver->disconnect(&udc->gadget);
+	spin_lock(&udc->lock);
+
+	return 0;
+}
+
+static void ch9setaddress(struct qe_udc *udc, u16 value, u16 index,
+			u16 length)
+{
+	/* Save the new address to device struct */
+	udc->device_address = (u8) value;
+	/* Update usb state */
+	udc->usb_state = USB_STATE_ADDRESS;
+
+	/* Status phase , send a ZLP */
+	if (ep0_prime_status(udc, USB_DIR_IN))
+		qe_ep0_stall(udc);
+}
+
+static void ownercomplete(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct qe_req *req = container_of(_req, struct qe_req, req);
+
+	req->req.buf = NULL;
+	kfree(req);
+}
+
+static void ch9getstatus(struct qe_udc *udc, u8 request_type, u16 value,
+			u16 index, u16 length)
+{
+	u16 usb_status = 0;
+	struct qe_req *req;
+	struct qe_ep *ep;
+	int status = 0;
+
+	ep = &udc->eps[0];
+	if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
+		/* Get device status */
+		usb_status = 1 << USB_DEVICE_SELF_POWERED;
+	} else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) {
+		/* Get interface status */
+		/* We don't have interface information in udc driver */
+		usb_status = 0;
+	} else if ((request_type & USB_RECIP_MASK) == USB_RECIP_ENDPOINT) {
+		/* Get endpoint status */
+		int pipe = index & USB_ENDPOINT_NUMBER_MASK;
+		struct qe_ep *target_ep = &udc->eps[pipe];
+		u16 usep;
+
+		/* stall if endpoint doesn't exist */
+		if (!target_ep->desc)
+			goto stall;
+
+		usep = in_be16(&udc->usb_regs->usb_usep[pipe]);
+		if (index & USB_DIR_IN) {
+			if (target_ep->dir != USB_DIR_IN)
+				goto stall;
+			if ((usep & USB_THS_MASK) == USB_THS_STALL)
+				usb_status = 1 << USB_ENDPOINT_HALT;
+		} else {
+			if (target_ep->dir != USB_DIR_OUT)
+				goto stall;
+			if ((usep & USB_RHS_MASK) == USB_RHS_STALL)
+				usb_status = 1 << USB_ENDPOINT_HALT;
+		}
+	}
+
+	req = container_of(qe_alloc_request(&ep->ep, GFP_KERNEL),
+					struct qe_req, req);
+	req->req.length = 2;
+	req->req.buf = udc->statusbuf;
+	*(u16 *)req->req.buf = cpu_to_le16(usb_status);
+	req->req.status = -EINPROGRESS;
+	req->req.actual = 0;
+	req->req.complete = ownercomplete;
+
+	udc->ep0_dir = USB_DIR_IN;
+
+	/* data phase */
+	status = qe_ep_queue(&ep->ep, &req->req, GFP_ATOMIC);
+
+	if (status == 0)
+		return;
+stall:
+	dev_err(udc->dev, "Can't respond to getstatus request \n");
+	qe_ep0_stall(udc);
+}
+
+/* only handle the setup request, suppose the device in normal status */
+static void setup_received_handle(struct qe_udc *udc,
+				struct usb_ctrlrequest *setup)
+{
+	/* Fix Endian (udc->local_setup_buff is cpu Endian now)*/
+	u16 wValue = le16_to_cpu(setup->wValue);
+	u16 wIndex = le16_to_cpu(setup->wIndex);
+	u16 wLength = le16_to_cpu(setup->wLength);
+
+	/* clear the previous request in the ep0 */
+	udc_reset_ep_queue(udc, 0);
+
+	if (setup->bRequestType & USB_DIR_IN)
+		udc->ep0_dir = USB_DIR_IN;
+	else
+		udc->ep0_dir = USB_DIR_OUT;
+
+	switch (setup->bRequest) {
+	case USB_REQ_GET_STATUS:
+		/* Data+Status phase form udc */
+		if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK))
+					!= (USB_DIR_IN | USB_TYPE_STANDARD))
+			break;
+		ch9getstatus(udc, setup->bRequestType, wValue, wIndex,
+					wLength);
+		return;
+
+	case USB_REQ_SET_ADDRESS:
+		/* Status phase from udc */
+		if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD |
+						USB_RECIP_DEVICE))
+			break;
+		ch9setaddress(udc, wValue, wIndex, wLength);
+		return;
+
+	case USB_REQ_CLEAR_FEATURE:
+	case USB_REQ_SET_FEATURE:
+		/* Requests with no data phase, status phase from udc */
+		if ((setup->bRequestType & USB_TYPE_MASK)
+					!= USB_TYPE_STANDARD)
+			break;
+
+		if ((setup->bRequestType & USB_RECIP_MASK)
+				== USB_RECIP_ENDPOINT) {
+			int pipe = wIndex & USB_ENDPOINT_NUMBER_MASK;
+			struct qe_ep *ep;
+
+			if (wValue != 0 || wLength != 0
+				|| pipe > USB_MAX_ENDPOINTS)
+				break;
+			ep = &udc->eps[pipe];
+
+			spin_unlock(&udc->lock);
+			qe_ep_set_halt(&ep->ep,
+					(setup->bRequest == USB_REQ_SET_FEATURE)
+						? 1 : 0);
+			spin_lock(&udc->lock);
+		}
+
+		ep0_prime_status(udc, USB_DIR_IN);
+
+		return;
+
+	default:
+		break;
+	}
+
+	if (wLength) {
+		/* Data phase from gadget, status phase from udc */
+		if (setup->bRequestType & USB_DIR_IN) {
+			udc->ep0_state = DATA_STATE_XMIT;
+			udc->ep0_dir = USB_DIR_IN;
+		} else {
+			udc->ep0_state = DATA_STATE_RECV;
+			udc->ep0_dir = USB_DIR_OUT;
+		}
+		spin_unlock(&udc->lock);
+		if (udc->driver->setup(&udc->gadget,
+					&udc->local_setup_buff) < 0)
+			qe_ep0_stall(udc);
+		spin_lock(&udc->lock);
+	} else {
+		/* No data phase, IN status from gadget */
+		udc->ep0_dir = USB_DIR_IN;
+		spin_unlock(&udc->lock);
+		if (udc->driver->setup(&udc->gadget,
+					&udc->local_setup_buff) < 0)
+			qe_ep0_stall(udc);
+		spin_lock(&udc->lock);
+		udc->ep0_state = DATA_STATE_NEED_ZLP;
+	}
+}
+
+/*-------------------------------------------------------------------------
+	USB Interrupt handlers
+ -------------------------------------------------------------------------*/
+static void suspend_irq(struct qe_udc *udc)
+{
+	udc->resume_state = udc->usb_state;
+	udc->usb_state = USB_STATE_SUSPENDED;
+
+	/* report suspend to the driver ,serial.c not support this*/
+	if (udc->driver->suspend)
+		udc->driver->suspend(&udc->gadget);
+}
+
+static void resume_irq(struct qe_udc *udc)
+{
+	udc->usb_state = udc->resume_state;
+	udc->resume_state = 0;
+
+	/* report resume to the driver , serial.c not support this*/
+	if (udc->driver->resume)
+		udc->driver->resume(&udc->gadget);
+}
+
+static void idle_irq(struct qe_udc *udc)
+{
+	u8 usbs;
+
+	usbs = in_8(&udc->usb_regs->usb_usbs);
+	if (usbs & USB_IDLE_STATUS_MASK) {
+		if ((udc->usb_state) != USB_STATE_SUSPENDED)
+			suspend_irq(udc);
+	} else {
+		if (udc->usb_state == USB_STATE_SUSPENDED)
+			resume_irq(udc);
+	}
+}
+
+static int reset_irq(struct qe_udc *udc)
+{
+	unsigned char i;
+
+	qe_usb_disable();
+	out_8(&udc->usb_regs->usb_usadr, 0);
+
+	for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
+		if (udc->eps[i].init)
+			qe_ep_reset(udc, i);
+	}
+
+	reset_queues(udc);
+	udc->usb_state = USB_STATE_DEFAULT;
+	udc->ep0_state = WAIT_FOR_SETUP;
+	udc->ep0_dir = USB_DIR_OUT;
+	qe_usb_enable();
+	return 0;
+}
+
+static int bsy_irq(struct qe_udc *udc)
+{
+	return 0;
+}
+
+static int txe_irq(struct qe_udc *udc)
+{
+	return 0;
+}
+
+/* ep0 tx interrupt also in here */
+static int tx_irq(struct qe_udc *udc)
+{
+	struct qe_ep *ep;
+	struct qe_bd __iomem *bd;
+	int i, res = 0;
+
+	if ((udc->usb_state == USB_STATE_ADDRESS)
+		&& (in_8(&udc->usb_regs->usb_usadr) == 0))
+		out_8(&udc->usb_regs->usb_usadr, udc->device_address);
+
+	for (i = (USB_MAX_ENDPOINTS-1); ((i >= 0) && (res == 0)); i--) {
+		ep = &udc->eps[i];
+		if (ep && ep->init && (ep->dir != USB_DIR_OUT)) {
+			bd = ep->c_txbd;
+			if (!(in_be32((u32 __iomem *)bd) & T_R)
+						&& (in_be32(&bd->buf))) {
+				/* confirm the transmitted bd */
+				if (ep->epnum == 0)
+					res = qe_ep0_txconf(ep);
+				else
+					res = qe_ep_txconf(ep);
+			}
+		}
+	}
+	return res;
+}
+
+
+/* setup packect's rx is handle in the function too */
+static void rx_irq(struct qe_udc *udc)
+{
+	struct qe_ep *ep;
+	struct qe_bd __iomem *bd;
+	int i;
+
+	for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
+		ep = &udc->eps[i];
+		if (ep && ep->init && (ep->dir != USB_DIR_IN)) {
+			bd = ep->n_rxbd;
+			if (!(in_be32((u32 __iomem *)bd) & R_E)
+						&& (in_be32(&bd->buf))) {
+				if (ep->epnum == 0) {
+					qe_ep0_rx(udc);
+				} else {
+					/*non-setup package receive*/
+					qe_ep_rx(ep);
+				}
+			}
+		}
+	}
+}
+
+static irqreturn_t qe_udc_irq(int irq, void *_udc)
+{
+	struct qe_udc *udc = (struct qe_udc *)_udc;
+	u16 irq_src;
+	irqreturn_t status = IRQ_NONE;
+	unsigned long flags;
+
+	spin_lock_irqsave(&udc->lock, flags);
+
+	irq_src = in_be16(&udc->usb_regs->usb_usber) &
+		in_be16(&udc->usb_regs->usb_usbmr);
+	/* Clear notification bits */
+	out_be16(&udc->usb_regs->usb_usber, irq_src);
+	/* USB Interrupt */
+	if (irq_src & USB_E_IDLE_MASK) {
+		idle_irq(udc);
+		irq_src &= ~USB_E_IDLE_MASK;
+		status = IRQ_HANDLED;
+	}
+
+	if (irq_src & USB_E_TXB_MASK) {
+		tx_irq(udc);
+		irq_src &= ~USB_E_TXB_MASK;
+		status = IRQ_HANDLED;
+	}
+
+	if (irq_src & USB_E_RXB_MASK) {
+		rx_irq(udc);
+		irq_src &= ~USB_E_RXB_MASK;
+		status = IRQ_HANDLED;
+	}
+
+	if (irq_src & USB_E_RESET_MASK) {
+		reset_irq(udc);
+		irq_src &= ~USB_E_RESET_MASK;
+		status = IRQ_HANDLED;
+	}
+
+	if (irq_src & USB_E_BSY_MASK) {
+		bsy_irq(udc);
+		irq_src &= ~USB_E_BSY_MASK;
+		status = IRQ_HANDLED;
+	}
+
+	if (irq_src & USB_E_TXE_MASK) {
+		txe_irq(udc);
+		irq_src &= ~USB_E_TXE_MASK;
+		status = IRQ_HANDLED;
+	}
+
+	spin_unlock_irqrestore(&udc->lock, flags);
+
+	return status;
+}
+
+/*-------------------------------------------------------------------------
+	Gadget driver register and unregister.
+ --------------------------------------------------------------------------*/
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+{
+	int retval;
+	unsigned long flags = 0;
+
+	/* standard operations */
+	if (!udc_controller)
+		return -ENODEV;
+
+	if (!driver || (driver->speed != USB_SPEED_FULL
+			&& driver->speed != USB_SPEED_HIGH)
+			|| !driver->bind || !driver->disconnect
+			|| !driver->setup)
+		return -EINVAL;
+
+	if (udc_controller->driver)
+		return -EBUSY;
+
+	/* lock is needed but whether should use this lock or another */
+	spin_lock_irqsave(&udc_controller->lock, flags);
+
+	driver->driver.bus = NULL;
+	/* hook up the driver */
+	udc_controller->driver = driver;
+	udc_controller->gadget.dev.driver = &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);
+	if (retval) {
+		dev_err(udc_controller->dev, "bind to %s --> %d",
+				driver->driver.name, retval);
+		udc_controller->gadget.dev.driver = NULL;
+		udc_controller->driver = NULL;
+		return retval;
+	}
+
+	/* Enable IRQ reg and Set usbcmd reg EN bit */
+	qe_usb_enable();
+
+	out_be16(&udc_controller->usb_regs->usb_usber, 0xffff);
+	out_be16(&udc_controller->usb_regs->usb_usbmr, USB_E_DEFAULT_DEVICE);
+	udc_controller->usb_state = USB_STATE_ATTACHED;
+	udc_controller->ep0_state = WAIT_FOR_SETUP;
+	udc_controller->ep0_dir = USB_DIR_OUT;
+	dev_info(udc_controller->dev, "%s bind to driver %s \n",
+		udc_controller->gadget.name, driver->driver.name);
+	return 0;
+}
+EXPORT_SYMBOL(usb_gadget_register_driver);
+
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+	struct qe_ep *loop_ep;
+	unsigned long flags;
+
+	if (!udc_controller)
+		return -ENODEV;
+
+	if (!driver || driver != udc_controller->driver)
+		return -EINVAL;
+
+	/* stop usb controller, disable intr */
+	qe_usb_disable();
+
+	/* in fact, no needed */
+	udc_controller->usb_state = USB_STATE_ATTACHED;
+	udc_controller->ep0_state = WAIT_FOR_SETUP;
+	udc_controller->ep0_dir = 0;
+
+	/* stand operation */
+	spin_lock_irqsave(&udc_controller->lock, flags);
+	udc_controller->gadget.speed = USB_SPEED_UNKNOWN;
+	nuke(&udc_controller->eps[0], -ESHUTDOWN);
+	list_for_each_entry(loop_ep, &udc_controller->gadget.ep_list,
+				ep.ep_list)
+		nuke(loop_ep, -ESHUTDOWN);
+	spin_unlock_irqrestore(&udc_controller->lock, flags);
+
+	/* unbind gadget and unhook driver. */
+	driver->unbind(&udc_controller->gadget);
+	udc_controller->gadget.dev.driver = NULL;
+	udc_controller->driver = NULL;
+
+	dev_info(udc_controller->dev, "unregistered gadget driver '%s'\r\n",
+			driver->driver.name);
+	return 0;
+}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
+/* udc structure's alloc and setup, include ep-param alloc */
+static struct qe_udc __devinit *qe_udc_config(struct of_device *ofdev)
+{
+	struct qe_udc *udc;
+	struct device_node *np = ofdev->node;
+	unsigned int tmp_addr = 0;
+	struct usb_device_para __iomem *usbpram;
+	unsigned int i;
+	u64 size;
+	u32 offset;
+
+	udc = kzalloc(sizeof(*udc), GFP_KERNEL);
+	if (udc == NULL) {
+		dev_err(&ofdev->dev, "malloc udc failed\n");
+		goto cleanup;
+	}
+
+	udc->dev = &ofdev->dev;
+
+	/* get default address of usb parameter in MURAM from device tree */
+	offset = *of_get_address(np, 1, &size, NULL);
+	udc->usb_param = cpm_muram_addr(offset);
+	memset_io(udc->usb_param, 0, size);
+
+	usbpram = udc->usb_param;
+	out_be16(&usbpram->frame_n, 0);
+	out_be32(&usbpram->rstate, 0);
+
+	tmp_addr = cpm_muram_alloc((USB_MAX_ENDPOINTS *
+					sizeof(struct usb_ep_para)),
+					   USB_EP_PARA_ALIGNMENT);
+
+	for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
+		out_be16(&usbpram->epptr[i], (u16)tmp_addr);
+		udc->ep_param[i] = cpm_muram_addr(tmp_addr);
+		tmp_addr += 32;
+	}
+
+	memset_io(udc->ep_param[0], 0,
+			USB_MAX_ENDPOINTS * sizeof(struct usb_ep_para));
+
+	udc->resume_state = USB_STATE_NOTATTACHED;
+	udc->usb_state = USB_STATE_POWERED;
+	udc->ep0_dir = 0;
+
+	spin_lock_init(&udc->lock);
+	return udc;
+
+cleanup:
+	kfree(udc);
+	return NULL;
+}
+
+/* USB Controller register init */
+static int __devinit qe_udc_reg_init(struct qe_udc *udc)
+{
+	struct usb_ctlr __iomem *qe_usbregs;
+	qe_usbregs = udc->usb_regs;
+
+	/* Init the usb register */
+	out_8(&qe_usbregs->usb_usmod, 0x01);
+	out_be16(&qe_usbregs->usb_usbmr, 0);
+	out_8(&qe_usbregs->usb_uscom, 0);
+	out_be16(&qe_usbregs->usb_usber, USBER_ALL_CLEAR);
+
+	return 0;
+}
+
+static int __devinit qe_ep_config(struct qe_udc *udc, unsigned char pipe_num)
+{
+	struct qe_ep *ep = &udc->eps[pipe_num];
+
+	ep->udc = udc;
+	strcpy(ep->name, ep_name[pipe_num]);
+	ep->ep.name = ep_name[pipe_num];
+
+	ep->ep.ops = &qe_ep_ops;
+	ep->stopped = 1;
+	ep->ep.maxpacket = (unsigned short) ~0;
+	ep->desc = NULL;
+	ep->dir = 0xff;
+	ep->epnum = (u8)pipe_num;
+	ep->sent = 0;
+	ep->last = 0;
+	ep->init = 0;
+	ep->rxframe = NULL;
+	ep->txframe = NULL;
+	ep->tx_req = NULL;
+	ep->state = EP_STATE_IDLE;
+	ep->has_data = 0;
+
+	/* the queue lists any req for this ep */
+	INIT_LIST_HEAD(&ep->queue);
+
+	/* gagdet.ep_list used for ep_autoconfig so no ep0*/
+	if (pipe_num != 0)
+		list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
+
+	ep->gadget = &udc->gadget;
+
+	return 0;
+}
+
+/*-----------------------------------------------------------------------
+ *	UDC device Driver operation functions				*
+ *----------------------------------------------------------------------*/
+static void qe_udc_release(struct device *dev)
+{
+	int i = 0;
+
+	complete(udc_controller->done);
+	cpm_muram_free(cpm_muram_offset(udc_controller->ep_param[0]));
+	for (i = 0; i < USB_MAX_ENDPOINTS; i++)
+		udc_controller->ep_param[i] = NULL;
+
+	kfree(udc_controller);
+	udc_controller = NULL;
+}
+
+/* Driver probe functions */
+static int __devinit qe_udc_probe(struct of_device *ofdev,
+			const struct of_device_id *match)
+{
+	struct device_node *np = ofdev->node;
+	struct qe_ep *ep;
+	unsigned int ret = 0;
+	unsigned int i;
+	const void *prop;
+
+	prop = of_get_property(np, "mode", NULL);
+	if (!prop || strcmp(prop, "peripheral"))
+		return -ENODEV;
+
+	/* Initialize the udc structure including QH member and other member */
+	udc_controller = qe_udc_config(ofdev);
+	if (!udc_controller) {
+		dev_dbg(&ofdev->dev, "udc_controll is NULL\n");
+		return -ENOMEM;
+	}
+
+	udc_controller->soc_type = (unsigned long)match->data;
+	udc_controller->usb_regs = of_iomap(np, 0);
+	if (!udc_controller->usb_regs) {
+		ret = -ENOMEM;
+		goto err1;
+	}
+
+	/* initialize usb hw reg except for regs for EP,
+	 * leave usbintr reg untouched*/
+	qe_udc_reg_init(udc_controller);
+
+	/* here comes the stand operations for probe
+	 * set the qe_udc->gadget.xxx */
+	udc_controller->gadget.ops = &qe_gadget_ops;
+
+	/* gadget.ep0 is a pointer */
+	udc_controller->gadget.ep0 = &udc_controller->eps[0].ep;
+
+	INIT_LIST_HEAD(&udc_controller->gadget.ep_list);
+
+	/* modify in register gadget process */
+	udc_controller->gadget.speed = USB_SPEED_UNKNOWN;
+
+	/* name: Identifies the controller hardware type. */
+	udc_controller->gadget.name = driver_name;
+
+	device_initialize(&udc_controller->gadget.dev);
+
+	strcpy(udc_controller->gadget.dev.bus_id, "gadget");
+
+	udc_controller->gadget.dev.release = qe_udc_release;
+	udc_controller->gadget.dev.parent = &ofdev->dev;
+
+	/* initialize qe_ep struct */
+	for (i = 0; i < USB_MAX_ENDPOINTS ; i++) {
+		/* because the ep type isn't decide here so
+		 * qe_ep_init() should be called in ep_enable() */
+
+		/* setup the qe_ep struct and link ep.ep.list
+		 * into gadget.ep_list */
+		qe_ep_config(udc_controller, (unsigned char)i);
+	}
+
+	/* ep0 initialization in here */
+	ret = qe_ep_init(udc_controller, 0, &qe_ep0_desc);
+	if (ret)
+		goto err2;
+
+	/* create a buf for ZLP send, need to remain zeroed */
+	udc_controller->nullbuf = kzalloc(256, GFP_KERNEL);
+	if (udc_controller->nullbuf == NULL) {
+		dev_dbg(udc_controller->dev, "cannot alloc nullbuf\n");
+		ret = -ENOMEM;
+		goto err3;
+	}
+
+	/* buffer for data of get_status request */
+	udc_controller->statusbuf = kzalloc(2, GFP_KERNEL);
+	if (udc_controller->statusbuf == NULL) {
+		ret = -ENOMEM;
+		goto err4;
+	}
+
+	udc_controller->nullp = virt_to_phys((void *)udc_controller->nullbuf);
+	if (udc_controller->nullp == DMA_ADDR_INVALID) {
+		udc_controller->nullp = dma_map_single(
+					udc_controller->gadget.dev.parent,
+					udc_controller->nullbuf,
+					256,
+					DMA_TO_DEVICE);
+		udc_controller->nullmap = 1;
+	} else {
+		dma_sync_single_for_device(udc_controller->gadget.dev.parent,
+					udc_controller->nullp, 256,
+					DMA_TO_DEVICE);
+	}
+
+	tasklet_init(&udc_controller->rx_tasklet, ep_rx_tasklet,
+			(unsigned long)udc_controller);
+	/* request irq and disable DR  */
+	udc_controller->usb_irq = irq_of_parse_and_map(np, 0);
+
+	ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0,
+				driver_name, udc_controller);
+	if (ret) {
+		dev_err(udc_controller->dev, "cannot request irq %d err %d \n",
+			udc_controller->usb_irq, ret);
+		goto err5;
+	}
+
+	ret = device_add(&udc_controller->gadget.dev);
+	if (ret)
+		goto err6;
+
+	dev_info(udc_controller->dev,
+			"%s USB controller initialized as device\n",
+			(udc_controller->soc_type == PORT_QE) ? "QE" : "CPM");
+	return 0;
+
+err6:
+	free_irq(udc_controller->usb_irq, udc_controller);
+err5:
+	if (udc_controller->nullmap) {
+		dma_unmap_single(udc_controller->gadget.dev.parent,
+			udc_controller->nullp, 256,
+				DMA_TO_DEVICE);
+			udc_controller->nullp = DMA_ADDR_INVALID;
+	} else {
+		dma_sync_single_for_cpu(udc_controller->gadget.dev.parent,
+			udc_controller->nullp, 256,
+				DMA_TO_DEVICE);
+	}
+	kfree(udc_controller->statusbuf);
+err4:
+	kfree(udc_controller->nullbuf);
+err3:
+	ep = &udc_controller->eps[0];
+	cpm_muram_free(cpm_muram_offset(ep->rxbase));
+	kfree(ep->rxframe);
+	kfree(ep->rxbuffer);
+	kfree(ep->txframe);
+err2:
+	iounmap(udc_controller->usb_regs);
+err1:
+	kfree(udc_controller);
+
+	return ret;
+}
+
+#ifdef CONFIG_PM
+static int qe_udc_suspend(struct of_device *dev, pm_message_t state)
+{
+	return -ENOTSUPP;
+}
+
+static int qe_udc_resume(struct of_device *dev)
+{
+	return -ENOTSUPP;
+}
+#endif
+
+static int __devexit qe_udc_remove(struct of_device *ofdev)
+{
+	struct qe_ep *ep;
+	unsigned int size;
+
+	DECLARE_COMPLETION(done);
+
+	if (!udc_controller)
+		return -ENODEV;
+
+	udc_controller->done = &done;
+	tasklet_disable(&udc_controller->rx_tasklet);
+
+	if (udc_controller->nullmap) {
+		dma_unmap_single(udc_controller->gadget.dev.parent,
+			udc_controller->nullp, 256,
+				DMA_TO_DEVICE);
+			udc_controller->nullp = DMA_ADDR_INVALID;
+	} else {
+		dma_sync_single_for_cpu(udc_controller->gadget.dev.parent,
+			udc_controller->nullp, 256,
+				DMA_TO_DEVICE);
+	}
+	kfree(udc_controller->statusbuf);
+	kfree(udc_controller->nullbuf);
+
+	ep = &udc_controller->eps[0];
+	cpm_muram_free(cpm_muram_offset(ep->rxbase));
+	size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) * (USB_BDRING_LEN + 1);
+
+	kfree(ep->rxframe);
+	if (ep->rxbufmap) {
+		dma_unmap_single(udc_controller->gadget.dev.parent,
+				ep->rxbuf_d, size,
+				DMA_FROM_DEVICE);
+		ep->rxbuf_d = DMA_ADDR_INVALID;
+	} else {
+		dma_sync_single_for_cpu(udc_controller->gadget.dev.parent,
+				ep->rxbuf_d, size,
+				DMA_FROM_DEVICE);
+	}
+
+	kfree(ep->rxbuffer);
+	kfree(ep->txframe);
+
+	free_irq(udc_controller->usb_irq, udc_controller);
+
+	tasklet_kill(&udc_controller->rx_tasklet);
+
+	iounmap(udc_controller->usb_regs);
+
+	device_unregister(&udc_controller->gadget.dev);
+	/* wait for release() of gadget.dev to free udc */
+	wait_for_completion(&done);
+
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static struct of_device_id __devinitdata qe_udc_match[] = {
+	{
+		.compatible = "fsl,mpc8360-qe-usb",
+		.data = (void *)PORT_QE,
+	},
+	{
+		.compatible = "fsl,mpc8272-cpm-usb",
+		.data = (void *)PORT_CPM,
+	},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, qe_udc_match);
+
+static struct of_platform_driver udc_driver = {
+	.name           = (char *)driver_name,
+	.match_table    = qe_udc_match,
+	.probe          = qe_udc_probe,
+	.remove         = __devexit_p(qe_udc_remove),
+#ifdef CONFIG_PM
+	.suspend        = qe_udc_suspend,
+	.resume         = qe_udc_resume,
+#endif
+};
+
+static int __init qe_udc_init(void)
+{
+	printk(KERN_INFO "%s: %s, %s\n", driver_name, driver_desc,
+			DRIVER_VERSION);
+	return of_register_platform_driver(&udc_driver);
+}
+
+static void __exit qe_udc_exit(void)
+{
+	of_unregister_platform_driver(&udc_driver);
+}
+
+module_init(qe_udc_init);
+module_exit(qe_udc_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_LICENSE("GPL");
+

+ 437 - 0
drivers/usb/gadget/fsl_qe_udc.h

@@ -0,0 +1,437 @@
+/*
+ * drivers/usb/gadget/qe_udc.h
+ *
+ * Copyright (C) 2006-2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * 	Xiaobo Xie <X.Xie@freescale.com>
+ * 	Li Yang <leoli@freescale.com>
+ *
+ * Description:
+ * Freescale USB device/endpoint management registers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#ifndef __FSL_QE_UDC_H
+#define __FSL_QE_UDC_H
+
+/* SoC type */
+#define PORT_CPM	0
+#define PORT_QE		1
+
+#define USB_MAX_ENDPOINTS               4
+#define USB_MAX_PIPES                   USB_MAX_ENDPOINTS
+#define USB_EP0_MAX_SIZE		64
+#define USB_MAX_CTRL_PAYLOAD            0x4000
+#define USB_BDRING_LEN			16
+#define USB_BDRING_LEN_RX		256
+#define USB_BDRING_LEN_TX		16
+#define MIN_EMPTY_BDS			128
+#define MAX_DATA_BDS			8
+#define USB_CRC_SIZE			2
+#define USB_DIR_BOTH			0x88
+#define R_BUF_MAXSIZE			0x800
+#define USB_EP_PARA_ALIGNMENT		32
+
+/* USB Mode Register bit define */
+#define USB_MODE_EN		0x01
+#define USB_MODE_HOST		0x02
+#define USB_MODE_TEST		0x04
+#define USB_MODE_SFTE		0x08
+#define USB_MODE_RESUME		0x40
+#define USB_MODE_LSS		0x80
+
+/* USB Slave Address Register Mask */
+#define USB_SLVADDR_MASK	0x7F
+
+/* USB Endpoint register define */
+#define USB_EPNUM_MASK		0xF000
+#define USB_EPNUM_SHIFT		12
+
+#define USB_TRANS_MODE_SHIFT	8
+#define USB_TRANS_CTR		0x0000
+#define USB_TRANS_INT		0x0100
+#define USB_TRANS_BULK		0x0200
+#define USB_TRANS_ISO		0x0300
+
+#define USB_EP_MF		0x0020
+#define USB_EP_RTE		0x0010
+
+#define USB_THS_SHIFT		2
+#define USB_THS_MASK		0x000c
+#define USB_THS_NORMAL		0x0
+#define USB_THS_IGNORE_IN	0x0004
+#define USB_THS_NACK		0x0008
+#define USB_THS_STALL		0x000c
+
+#define USB_RHS_SHIFT   	0
+#define USB_RHS_MASK		0x0003
+#define USB_RHS_NORMAL  	0x0
+#define USB_RHS_IGNORE_OUT	0x0001
+#define USB_RHS_NACK		0x0002
+#define USB_RHS_STALL		0x0003
+
+#define USB_RTHS_MASK		0x000f
+
+/* USB Command Register define */
+#define USB_CMD_STR_FIFO	0x80
+#define USB_CMD_FLUSH_FIFO	0x40
+#define USB_CMD_ISFT		0x20
+#define USB_CMD_DSFT		0x10
+#define USB_CMD_EP_MASK		0x03
+
+/* USB Event and Mask Register define */
+#define USB_E_MSF_MASK		0x0800
+#define USB_E_SFT_MASK		0x0400
+#define USB_E_RESET_MASK	0x0200
+#define USB_E_IDLE_MASK		0x0100
+#define USB_E_TXE4_MASK		0x0080
+#define USB_E_TXE3_MASK		0x0040
+#define USB_E_TXE2_MASK		0x0020
+#define USB_E_TXE1_MASK		0x0010
+#define USB_E_SOF_MASK		0x0008
+#define USB_E_BSY_MASK		0x0004
+#define USB_E_TXB_MASK		0x0002
+#define USB_E_RXB_MASK		0x0001
+#define USBER_ALL_CLEAR 	0x0fff
+
+#define USB_E_DEFAULT_DEVICE   (USB_E_RESET_MASK | USB_E_TXE4_MASK | \
+				USB_E_TXE3_MASK | USB_E_TXE2_MASK | \
+				USB_E_TXE1_MASK | USB_E_BSY_MASK | \
+				USB_E_TXB_MASK | USB_E_RXB_MASK)
+
+#define USB_E_TXE_MASK         (USB_E_TXE4_MASK | USB_E_TXE3_MASK|\
+				 USB_E_TXE2_MASK | USB_E_TXE1_MASK)
+/* USB Status Register define */
+#define USB_IDLE_STATUS_MASK	0x01
+
+/* USB Start of Frame Timer */
+#define USB_USSFT_MASK		0x3FFF
+
+/* USB Frame Number Register */
+#define USB_USFRN_MASK		0xFFFF
+
+struct usb_device_para{
+	u16	epptr[4];
+	u32	rstate;
+	u32	rptr;
+	u16	frame_n;
+	u16	rbcnt;
+	u32	rtemp;
+	u32	rxusb_data;
+	u16	rxuptr;
+	u8	reso[2];
+	u32	softbl;
+	u8	sofucrctemp;
+};
+
+struct usb_ep_para{
+	u16	rbase;
+	u16	tbase;
+	u8	rbmr;
+	u8	tbmr;
+	u16	mrblr;
+	u16	rbptr;
+	u16	tbptr;
+	u32	tstate;
+	u32	tptr;
+	u16	tcrc;
+	u16	tbcnt;
+	u32	ttemp;
+	u16	txusbu_ptr;
+	u8	reserve[2];
+};
+
+#define USB_BUSMODE_GBL		0x20
+#define USB_BUSMODE_BO_MASK	0x18
+#define USB_BUSMODE_BO_SHIFT	0x3
+#define USB_BUSMODE_BE		0x2
+#define USB_BUSMODE_CETM	0x04
+#define USB_BUSMODE_DTB		0x02
+
+/* Endpoint basic handle */
+#define ep_index(EP)		((EP)->desc->bEndpointAddress & 0xF)
+#define ep_maxpacket(EP)	((EP)->ep.maxpacket)
+#define ep_is_in(EP)	((ep_index(EP) == 0) ? (EP->udc->ep0_dir == \
+			USB_DIR_IN) : ((EP)->desc->bEndpointAddress \
+			& USB_DIR_IN) == USB_DIR_IN)
+
+/* ep0 transfer state */
+#define WAIT_FOR_SETUP          0
+#define DATA_STATE_XMIT         1
+#define DATA_STATE_NEED_ZLP     2
+#define WAIT_FOR_OUT_STATUS     3
+#define DATA_STATE_RECV         4
+
+/* ep tramsfer mode */
+#define USBP_TM_CTL	0
+#define USBP_TM_ISO	1
+#define USBP_TM_BULK	2
+#define USBP_TM_INT	3
+
+/*-----------------------------------------------------------------------------
+	USB RX And TX DATA Frame
+ -----------------------------------------------------------------------------*/
+struct qe_frame{
+	u8 *data;
+	u32 len;
+	u32 status;
+	u32 info;
+
+	void *privdata;
+	struct list_head node;
+};
+
+/* Frame structure, info field. */
+#define PID_DATA0              0x80000000 /* Data toggle zero */
+#define PID_DATA1              0x40000000 /* Data toggle one  */
+#define PID_SETUP              0x20000000 /* setup bit */
+#define SETUP_STATUS           0x10000000 /* setup status bit */
+#define SETADDR_STATUS         0x08000000 /* setupup address status bit */
+#define NO_REQ                 0x04000000 /* Frame without request */
+#define HOST_DATA              0x02000000 /* Host data frame */
+#define FIRST_PACKET_IN_FRAME  0x01000000 /* first packet in the frame */
+#define TOKEN_FRAME            0x00800000 /* Host token frame */
+#define ZLP                    0x00400000 /* Zero length packet */
+#define IN_TOKEN_FRAME         0x00200000 /* In token package */
+#define OUT_TOKEN_FRAME        0x00100000 /* Out token package */
+#define SETUP_TOKEN_FRAME      0x00080000 /* Setup token package */
+#define STALL_FRAME            0x00040000 /* Stall handshake */
+#define NACK_FRAME             0x00020000 /* Nack handshake */
+#define NO_PID                 0x00010000 /* No send PID */
+#define NO_CRC                 0x00008000 /* No send CRC */
+#define HOST_COMMAND           0x00004000 /* Host command frame   */
+
+/* Frame status field */
+/* Receive side */
+#define FRAME_OK               0x00000000 /* Frame tranmitted or received OK */
+#define FRAME_ERROR            0x80000000 /* Error occured on frame */
+#define START_FRAME_LOST       0x40000000 /* START_FRAME_LOST */
+#define END_FRAME_LOST         0x20000000 /* END_FRAME_LOST */
+#define RX_ER_NONOCT           0x10000000 /* Rx Non Octet Aligned Packet */
+#define RX_ER_BITSTUFF         0x08000000 /* Frame Aborted --Received packet
+					     with bit stuff error */
+#define RX_ER_CRC              0x04000000 /* Received packet with CRC error */
+#define RX_ER_OVERUN           0x02000000 /* Over-run occured on reception */
+#define RX_ER_PID              0x01000000 /* Wrong PID received */
+/* Tranmit side */
+#define TX_ER_NAK              0x00800000 /* Received NAK handshake */
+#define TX_ER_STALL            0x00400000 /* Received STALL handshake */
+#define TX_ER_TIMEOUT          0x00200000 /* Transmit time out */
+#define TX_ER_UNDERUN          0x00100000 /* Transmit underrun */
+#define FRAME_INPROGRESS       0x00080000 /* Frame is being transmitted */
+#define ER_DATA_UNDERUN        0x00040000 /* Frame is shorter then expected */
+#define ER_DATA_OVERUN         0x00020000 /* Frame is longer then expected */
+
+/* QE USB frame operation functions */
+#define frame_get_length(frm) (frm->len)
+#define frame_set_length(frm, leng) (frm->len = leng)
+#define frame_get_data(frm) (frm->data)
+#define frame_set_data(frm, dat) (frm->data = dat)
+#define frame_get_info(frm) (frm->info)
+#define frame_set_info(frm, inf) (frm->info = inf)
+#define frame_get_status(frm) (frm->status)
+#define frame_set_status(frm, stat) (frm->status = stat)
+#define frame_get_privdata(frm) (frm->privdata)
+#define frame_set_privdata(frm, dat) (frm->privdata = dat)
+
+static inline void qe_frame_clean(struct qe_frame *frm)
+{
+	frame_set_data(frm, NULL);
+	frame_set_length(frm, 0);
+	frame_set_status(frm, FRAME_OK);
+	frame_set_info(frm, 0);
+	frame_set_privdata(frm, NULL);
+}
+
+static inline void qe_frame_init(struct qe_frame *frm)
+{
+	qe_frame_clean(frm);
+	INIT_LIST_HEAD(&(frm->node));
+}
+
+struct qe_req {
+	struct usb_request req;
+	struct list_head queue;
+	/* ep_queue() func will add
+	 a request->queue into a udc_ep->queue 'd tail */
+	struct qe_ep *ep;
+	unsigned mapped:1;
+};
+
+struct qe_ep {
+	struct usb_ep ep;
+	struct list_head queue;
+	struct qe_udc *udc;
+	const struct usb_endpoint_descriptor *desc;
+	struct usb_gadget *gadget;
+
+	u8 state;
+
+	struct qe_bd __iomem *rxbase;
+	struct qe_bd __iomem *n_rxbd;
+	struct qe_bd __iomem *e_rxbd;
+
+	struct qe_bd __iomem *txbase;
+	struct qe_bd __iomem *n_txbd;
+	struct qe_bd __iomem *c_txbd;
+
+	struct qe_frame *rxframe;
+	u8 *rxbuffer;
+	dma_addr_t rxbuf_d;
+	u8 rxbufmap;
+	unsigned char localnack;
+	int has_data;
+
+	struct qe_frame *txframe;
+	struct qe_req *tx_req;
+	int sent;  /*data already sent */
+	int last;  /*data sent in the last time*/
+
+	u8 dir;
+	u8 epnum;
+	u8 tm; /* transfer mode */
+	u8 data01;
+	u8 init;
+
+	u8 already_seen;
+	u8 enable_tasklet;
+	u8 setup_stage;
+	u32 last_io;            /* timestamp */
+
+	char name[14];
+
+	unsigned double_buf:1;
+	unsigned stopped:1;
+	unsigned fnf:1;
+	unsigned has_dma:1;
+
+	u8 ackwait;
+	u8 dma_channel;
+	u16 dma_counter;
+	int lch;
+
+	struct timer_list timer;
+};
+
+struct qe_udc {
+	struct usb_gadget gadget;
+	struct usb_gadget_driver *driver;
+	struct device *dev;
+	struct qe_ep eps[USB_MAX_ENDPOINTS];
+	struct usb_ctrlrequest local_setup_buff;
+	spinlock_t lock;	/* lock for set/config qe_udc */
+	unsigned long soc_type;		/* QE or CPM soc */
+
+	struct qe_req *status_req;	/* ep0 status request */
+
+	/* USB and EP Parameter Block pointer */
+	struct usb_device_para __iomem *usb_param;
+	struct usb_ep_para __iomem *ep_param[4];
+
+	u32 max_pipes;          /* Device max pipes */
+	u32 max_use_endpts;     /* Max endpointes to be used */
+	u32 bus_reset;          /* Device is bus reseting */
+	u32 resume_state;       /* USB state to resume*/
+	u32 usb_state;          /* USB current state */
+	u32 usb_next_state;     /* USB next state */
+	u32 ep0_state;          /* Enpoint zero state */
+	u32 ep0_dir;            /* Enpoint zero direction: can be
+				USB_DIR_IN or USB_DIR_OUT*/
+	u32 usb_sof_count;      /* SOF count */
+	u32 errors;             /* USB ERRORs count */
+
+	u8 *tmpbuf;
+	u32 c_start;
+	u32 c_end;
+
+	u8 *nullbuf;
+	u8 *statusbuf;
+	dma_addr_t nullp;
+	u8 nullmap;
+	u8 device_address;	/* Device USB address */
+
+	unsigned int usb_clock;
+	unsigned int usb_irq;
+	struct usb_ctlr __iomem *usb_regs;
+
+	struct tasklet_struct rx_tasklet;
+
+	struct completion *done;	/* to make sure release() is done */
+};
+
+#define EP_STATE_IDLE	0
+#define EP_STATE_NACK	1
+#define EP_STATE_STALL	2
+
+/*
+ * transmit BD's status
+ */
+#define T_R           0x80000000         /* ready bit */
+#define T_W           0x20000000         /* wrap bit */
+#define T_I           0x10000000         /* interrupt on completion */
+#define T_L           0x08000000         /* last */
+#define T_TC          0x04000000         /* transmit CRC */
+#define T_CNF         0x02000000         /* wait for  transmit confirm */
+#define T_LSP         0x01000000         /* Low-speed transaction */
+#define T_PID         0x00c00000         /* packet id */
+#define T_NAK         0x00100000         /* No ack. */
+#define T_STAL        0x00080000         /* Stall recieved */
+#define T_TO          0x00040000         /* time out */
+#define T_UN          0x00020000         /* underrun */
+
+#define DEVICE_T_ERROR    (T_UN | T_TO)
+#define HOST_T_ERROR      (T_UN | T_TO | T_NAK | T_STAL)
+#define DEVICE_T_BD_MASK  DEVICE_T_ERROR
+#define HOST_T_BD_MASK    HOST_T_ERROR
+
+#define T_PID_SHIFT   6
+#define T_PID_DATA0   0x00800000         /* Data 0 toggle */
+#define T_PID_DATA1   0x00c00000         /* Data 1 toggle */
+
+/*
+ * receive BD's status
+ */
+#define R_E           0x80000000         /* buffer empty */
+#define R_W           0x20000000         /* wrap bit */
+#define R_I           0x10000000         /* interrupt on reception */
+#define R_L           0x08000000         /* last */
+#define R_F           0x04000000         /* first */
+#define R_PID         0x00c00000         /* packet id */
+#define R_NO          0x00100000         /* Rx Non Octet Aligned Packet */
+#define R_AB          0x00080000         /* Frame Aborted */
+#define R_CR          0x00040000         /* CRC Error */
+#define R_OV          0x00020000         /* Overrun */
+
+#define R_ERROR       (R_NO | R_AB | R_CR | R_OV)
+#define R_BD_MASK     R_ERROR
+
+#define R_PID_DATA0   0x00000000
+#define R_PID_DATA1   0x00400000
+#define R_PID_SETUP   0x00800000
+
+#define CPM_USB_STOP_TX 0x2e600000
+#define CPM_USB_RESTART_TX 0x2e600000
+#define CPM_USB_STOP_TX_OPCODE 0x0a
+#define CPM_USB_RESTART_TX_OPCODE 0x0b
+#define CPM_USB_EP_SHIFT 5
+
+#ifndef CONFIG_CPM
+inline int cpm_command(u32 command, u8 opcode)
+{
+	return -EOPNOTSUPP;
+}
+#endif
+
+#ifndef CONFIG_QUICC_ENGINE
+inline int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol,
+	u32 cmd_input)
+{
+	return -EOPNOTSUPP;
+}
+#endif
+
+#endif  /* __FSL_QE_UDC_H */

+ 78 - 98
drivers/usb/gadget/fsl_usb2_udc.c

@@ -23,11 +23,8 @@
 #include <linux/ioport.h>
 #include <linux/types.h>
 #include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/init.h>
-#include <linux/timer.h>
 #include <linux/list.h>
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
@@ -44,11 +41,9 @@
 
 #include <asm/byteorder.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/unaligned.h>
 #include <asm/dma.h>
-#include <asm/cacheflush.h>
 
 #include "fsl_usb2_udc.h"
 
@@ -61,8 +56,8 @@
 static const char driver_name[] = "fsl-usb2-udc";
 static const char driver_desc[] = DRIVER_DESC;
 
-volatile static struct usb_dr_device *dr_regs = NULL;
-volatile static struct usb_sys_interface *usb_sys_regs = NULL;
+static struct usb_dr_device *dr_regs;
+static struct usb_sys_interface *usb_sys_regs;
 
 /* it is initialized in probe()  */
 static struct fsl_udc *udc_controller = NULL;
@@ -76,16 +71,14 @@ fsl_ep0_desc = {
 	.wMaxPacketSize =	USB_MAX_CTRL_PAYLOAD,
 };
 
-static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state);
-static int fsl_udc_resume(struct platform_device *pdev);
 static void fsl_ep_fifo_flush(struct usb_ep *_ep);
 
 #ifdef CONFIG_PPC32
 #define fsl_readl(addr)		in_le32(addr)
-#define fsl_writel(addr, val32) out_le32(val32, addr)
+#define fsl_writel(val32, addr) out_le32(addr, val32)
 #else
 #define fsl_readl(addr)		readl(addr)
-#define fsl_writel(addr, val32) writel(addr, val32)
+#define fsl_writel(val32, addr) writel(val32, addr)
 #endif
 
 /********************************************************************
@@ -185,10 +178,6 @@ static int dr_controller_setup(struct fsl_udc *udc)
 	unsigned long timeout;
 #define FSL_UDC_RESET_TIMEOUT 1000
 
-	/* before here, make sure dr_regs has been initialized */
-	if (!udc)
-		return -EINVAL;
-
 	/* Stop and reset the usb controller */
 	tmp = fsl_readl(&dr_regs->usbcmd);
 	tmp &= ~USB_CMD_RUN_STOP;
@@ -202,7 +191,7 @@ static int dr_controller_setup(struct fsl_udc *udc)
 	timeout = jiffies + FSL_UDC_RESET_TIMEOUT;
 	while (fsl_readl(&dr_regs->usbcmd) & USB_CMD_CTRL_RESET) {
 		if (time_after(jiffies, timeout)) {
-			ERR("udc reset timeout! \n");
+			ERR("udc reset timeout!\n");
 			return -ETIMEDOUT;
 		}
 		cpu_relax();
@@ -315,7 +304,8 @@ static void dr_controller_stop(struct fsl_udc *udc)
 	return;
 }
 
-void dr_ep_setup(unsigned char ep_num, unsigned char dir, unsigned char ep_type)
+static void dr_ep_setup(unsigned char ep_num, unsigned char dir,
+			unsigned char ep_type)
 {
 	unsigned int tmp_epctrl = 0;
 
@@ -563,7 +553,7 @@ static int fsl_ep_disable(struct usb_ep *_ep)
 	/* nuke all pending requests (does flush) */
 	nuke(ep, -ESHUTDOWN);
 
-	ep->desc = 0;
+	ep->desc = NULL;
 	ep->stopped = 1;
 	spin_unlock_irqrestore(&udc->lock, flags);
 
@@ -602,7 +592,7 @@ static void fsl_free_request(struct usb_ep *_ep, struct usb_request *_req)
 }
 
 /*-------------------------------------------------------------------------*/
-static int fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
+static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
 {
 	int i = ep_index(ep) * 2 + ep_is_in(ep);
 	u32 temp, bitmask, tmp_stat;
@@ -653,13 +643,16 @@ static int fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
 			| EP_QUEUE_HEAD_STATUS_HALT));
 	dQH->size_ioc_int_sts &= temp;
 
+	/* Ensure that updates to the QH will occure before priming. */
+	wmb();
+
 	/* Prime endpoint by writing 1 to ENDPTPRIME */
 	temp = ep_is_in(ep)
 		? (1 << (ep_index(ep) + 16))
 		: (1 << (ep_index(ep)));
 	fsl_writel(temp, &dr_regs->endpointprime);
 out:
-	return 0;
+	return;
 }
 
 /* Fill in the dTD structure
@@ -710,7 +703,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
 		*is_last = 0;
 
 	if ((*is_last) == 0)
-		VDBG("multi-dtd request!\n");
+		VDBG("multi-dtd request!");
 	/* Fill in the transfer size; set active bit */
 	swap_temp = ((*length << DTD_LENGTH_BIT_POS) | DTD_STATUS_ACTIVE);
 
@@ -773,11 +766,11 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
 	/* catch various bogus parameters */
 	if (!_req || !req->req.complete || !req->req.buf
 			|| !list_empty(&req->queue)) {
-		VDBG("%s, bad params\n", __func__);
+		VDBG("%s, bad params", __func__);
 		return -EINVAL;
 	}
 	if (unlikely(!_ep || !ep->desc)) {
-		VDBG("%s, bad ep\n", __func__);
+		VDBG("%s, bad ep", __func__);
 		return -EINVAL;
 	}
 	if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
@@ -1069,7 +1062,7 @@ static int fsl_vbus_session(struct usb_gadget *gadget, int is_active)
 
 	udc = container_of(gadget, struct fsl_udc, gadget);
 	spin_lock_irqsave(&udc->lock, flags);
-	VDBG("VBUS %s\n", is_active ? "on" : "off");
+	VDBG("VBUS %s", is_active ? "on" : "off");
 	udc->vbus_active = (is_active != 0);
 	if (can_pullup(udc))
 		fsl_writel((fsl_readl(&dr_regs->usbcmd) | USB_CMD_RUN_STOP),
@@ -1146,7 +1139,6 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
 {
 	struct fsl_req *req = udc->status_req;
 	struct fsl_ep *ep;
-	int status = 0;
 
 	if (direction == EP_DIR_IN)
 		udc->ep0_dir = USB_DIR_IN;
@@ -1164,27 +1156,21 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
 	req->dtd_count = 0;
 
 	if (fsl_req_to_dtd(req) == 0)
-		status = fsl_queue_td(ep, req);
+		fsl_queue_td(ep, req);
 	else
 		return -ENOMEM;
 
-	if (status)
-		ERR("Can't queue ep0 status request \n");
 	list_add_tail(&req->queue, &ep->queue);
 
-	return status;
+	return 0;
 }
 
-static inline int udc_reset_ep_queue(struct fsl_udc *udc, u8 pipe)
+static void udc_reset_ep_queue(struct fsl_udc *udc, u8 pipe)
 {
 	struct fsl_ep *ep = get_ep_by_pipe(udc, pipe);
 
-	if (!ep->name)
-		return 0;
-
-	nuke(ep, -ESHUTDOWN);
-
-	return 0;
+	if (ep->name)
+		nuke(ep, -ESHUTDOWN);
 }
 
 /*
@@ -1208,10 +1194,8 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
 		u16 index, u16 length)
 {
 	u16 tmp = 0;		/* Status, cpu endian */
-
 	struct fsl_req *req;
 	struct fsl_ep *ep;
-	int status = 0;
 
 	ep = &udc->eps[0];
 
@@ -1250,14 +1234,10 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
 
 	/* prime the data phase */
 	if ((fsl_req_to_dtd(req) == 0))
-		status = fsl_queue_td(ep, req);
+		fsl_queue_td(ep, req);
 	else			/* no mem */
 		goto stall;
 
-	if (status) {
-		ERR("Can't respond to getstatus request \n");
-		goto stall;
-	}
 	list_add_tail(&req->queue, &ep->queue);
 	udc->ep0_state = DATA_STATE_XMIT;
 	return;
@@ -1397,7 +1377,7 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0,
 		udc->ep0_state = WAIT_FOR_SETUP;
 		break;
 	case WAIT_FOR_SETUP:
-		ERR("Unexpect ep0 packets \n");
+		ERR("Unexpect ep0 packets\n");
 		break;
 	default:
 		ep0stall(udc);
@@ -1476,7 +1456,7 @@ static int process_ep_req(struct fsl_udc *udc, int pipe,
 				status = -EILSEQ;
 				break;
 			} else
-				ERR("Unknown error has occured (0x%x)!\r\n",
+				ERR("Unknown error has occured (0x%x)!\n",
 					errors);
 
 		} else if (le32_to_cpu(curr_td->size_ioc_sts)
@@ -1495,7 +1475,7 @@ static int process_ep_req(struct fsl_udc *udc, int pipe,
 			}
 		} else {
 			td_complete++;
-			VDBG("dTD transmitted successful ");
+			VDBG("dTD transmitted successful");
 		}
 
 		if (j != curr_req->dtd_count - 1)
@@ -1568,9 +1548,6 @@ static void port_change_irq(struct fsl_udc *udc)
 {
 	u32 speed;
 
-	if (udc->bus_reset)
-		udc->bus_reset = 0;
-
 	/* Bus resetting is finished */
 	if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) {
 		/* Get the speed */
@@ -1678,8 +1655,6 @@ static void reset_irq(struct fsl_udc *udc)
 
 	if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) {
 		VDBG("Bus reset");
-		/* Bus is reseting */
-		udc->bus_reset = 1;
 		/* Reset all the queues, include XD, dTD, EP queue
 		 * head and TR Queue */
 		reset_queues(udc);
@@ -1768,7 +1743,7 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc)
 	}
 
 	if (irq_src & (USB_STS_ERR | USB_STS_SYS_ERR)) {
-		VDBG("Error IRQ %x ", irq_src);
+		VDBG("Error IRQ %x", irq_src);
 	}
 
 	spin_unlock_irqrestore(&udc->lock, flags);
@@ -1799,7 +1774,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 	/* lock is needed but whether should use this lock or another */
 	spin_lock_irqsave(&udc_controller->lock, flags);
 
-	driver->driver.bus = 0;
+	driver->driver.bus = NULL;
 	/* hook up the driver */
 	udc_controller->driver = driver;
 	udc_controller->gadget.dev.driver = &driver->driver;
@@ -1809,8 +1784,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 	retval = driver->bind(&udc_controller->gadget);
 	if (retval) {
 		VDBG("bind to %s --> %d", driver->driver.name, retval);
-		udc_controller->gadget.dev.driver = 0;
-		udc_controller->driver = 0;
+		udc_controller->gadget.dev.driver = NULL;
+		udc_controller->driver = NULL;
 		goto out;
 	}
 
@@ -1819,12 +1794,12 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 	udc_controller->usb_state = USB_STATE_ATTACHED;
 	udc_controller->ep0_state = WAIT_FOR_SETUP;
 	udc_controller->ep0_dir = 0;
-	printk(KERN_INFO "%s: bind to driver %s \n",
+	printk(KERN_INFO "%s: bind to driver %s\n",
 			udc_controller->gadget.name, driver->driver.name);
 
 out:
 	if (retval)
-		printk("retval %d \n", retval);
+		printk("gadget driver register failed %d\n", retval);
 	return retval;
 }
 EXPORT_SYMBOL(usb_gadget_register_driver);
@@ -1842,7 +1817,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 		return -EINVAL;
 
 	if (udc_controller->transceiver)
-		(void)otg_set_peripheral(udc_controller->transceiver, 0);
+		otg_set_peripheral(udc_controller->transceiver, NULL);
 
 	/* stop DR, disable intr */
 	dr_controller_stop(udc_controller);
@@ -1863,10 +1838,10 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 
 	/* unbind gadget and unhook driver. */
 	driver->unbind(&udc_controller->gadget);
-	udc_controller->gadget.dev.driver = 0;
-	udc_controller->driver = 0;
+	udc_controller->gadget.dev.driver = NULL;
+	udc_controller->driver = NULL;
 
-	printk("unregistered gadget driver '%s'\r\n", driver->driver.name);
+	printk("unregistered gadget driver '%s'\n", driver->driver.name);
 	return 0;
 }
 EXPORT_SYMBOL(usb_gadget_unregister_driver);
@@ -1922,7 +1897,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
 	tmp_reg = fsl_readl(&dr_regs->usbsts);
 	t = scnprintf(next, size,
 			"USB Status Reg:\n"
-			"Dr Suspend: %d" "Reset Received: %d" "System Error: %s"
+			"Dr Suspend: %d Reset Received: %d System Error: %s "
 			"USB Error Interrupt: %s\n\n",
 			(tmp_reg & USB_STS_SUSPEND) ? 1 : 0,
 			(tmp_reg & USB_STS_RESET) ? 1 : 0,
@@ -1934,11 +1909,11 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
 	tmp_reg = fsl_readl(&dr_regs->usbintr);
 	t = scnprintf(next, size,
 			"USB Intrrupt Enable Reg:\n"
-			"Sleep Enable: %d" "SOF Received Enable: %d"
+			"Sleep Enable: %d SOF Received Enable: %d "
 			"Reset Enable: %d\n"
-			"System Error Enable: %d"
+			"System Error Enable: %d "
 			"Port Change Dectected Enable: %d\n"
-			"USB Error Intr Enable: %d" "USB Intr Enable: %d\n\n",
+			"USB Error Intr Enable: %d USB Intr Enable: %d\n\n",
 			(tmp_reg & USB_INTR_DEVICE_SUSPEND) ? 1 : 0,
 			(tmp_reg & USB_INTR_SOF_EN) ? 1 : 0,
 			(tmp_reg & USB_INTR_RESET_EN) ? 1 : 0,
@@ -1951,21 +1926,21 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
 
 	tmp_reg = fsl_readl(&dr_regs->frindex);
 	t = scnprintf(next, size,
-			"USB Frame Index Reg:" "Frame Number is 0x%x\n\n",
+			"USB Frame Index Reg: Frame Number is 0x%x\n\n",
 			(tmp_reg & USB_FRINDEX_MASKS));
 	size -= t;
 	next += t;
 
 	tmp_reg = fsl_readl(&dr_regs->deviceaddr);
 	t = scnprintf(next, size,
-			"USB Device Address Reg:" "Device Addr is 0x%x\n\n",
+			"USB Device Address Reg: Device Addr is 0x%x\n\n",
 			(tmp_reg & USB_DEVICE_ADDRESS_MASK));
 	size -= t;
 	next += t;
 
 	tmp_reg = fsl_readl(&dr_regs->endpointlistaddr);
 	t = scnprintf(next, size,
-			"USB Endpoint List Address Reg:"
+			"USB Endpoint List Address Reg: "
 			"Device Addr is 0x%x\n\n",
 			(tmp_reg & USB_EP_LIST_ADDRESS_MASK));
 	size -= t;
@@ -1974,11 +1949,12 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
 	tmp_reg = fsl_readl(&dr_regs->portsc1);
 	t = scnprintf(next, size,
 		"USB Port Status&Control Reg:\n"
-		"Port Transceiver Type : %s" "Port Speed: %s \n"
-		"PHY Low Power Suspend: %s" "Port Reset: %s"
-		"Port Suspend Mode: %s \n" "Over-current Change: %s"
+		"Port Transceiver Type : %s Port Speed: %s\n"
+		"PHY Low Power Suspend: %s Port Reset: %s "
+		"Port Suspend Mode: %s\n"
+		"Over-current Change: %s "
 		"Port Enable/Disable Change: %s\n"
-		"Port Enabled/Disabled: %s"
+		"Port Enabled/Disabled: %s "
 		"Current Connect Status: %s\n\n", ( {
 			char *s;
 			switch (tmp_reg & PORTSCX_PTS_FSLS) {
@@ -2023,7 +1999,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
 
 	tmp_reg = fsl_readl(&dr_regs->usbmode);
 	t = scnprintf(next, size,
-			"USB Mode Reg:" "Controller Mode is : %s\n\n", ( {
+			"USB Mode Reg: Controller Mode is: %s\n\n", ( {
 				char *s;
 				switch (tmp_reg & USB_MODE_CTRL_MODE_HOST) {
 				case USB_MODE_CTRL_MODE_IDLE:
@@ -2042,7 +2018,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
 
 	tmp_reg = fsl_readl(&dr_regs->endptsetupstat);
 	t = scnprintf(next, size,
-			"Endpoint Setup Status Reg:" "SETUP on ep 0x%x\n\n",
+			"Endpoint Setup Status Reg: SETUP on ep 0x%x\n\n",
 			(tmp_reg & EP_SETUP_STATUS_MASK));
 	size -= t;
 	next += t;
@@ -2055,12 +2031,12 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
 		next += t;
 	}
 	tmp_reg = fsl_readl(&dr_regs->endpointprime);
-	t = scnprintf(next, size, "EP Prime Reg = [0x%x]\n", tmp_reg);
+	t = scnprintf(next, size, "EP Prime Reg = [0x%x]\n\n", tmp_reg);
 	size -= t;
 	next += t;
 
 	tmp_reg = usb_sys_regs->snoop1;
-	t = scnprintf(next, size, "\nSnoop1 Reg : = [0x%x]\n\n", tmp_reg);
+	t = scnprintf(next, size, "Snoop1 Reg : = [0x%x]\n\n", tmp_reg);
 	size -= t;
 	next += t;
 
@@ -2084,7 +2060,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
 	} else {
 		list_for_each_entry(req, &ep->queue, queue) {
 			t = scnprintf(next, size,
-				"req %p actual 0x%x length 0x%x  buf %p\n",
+				"req %p actual 0x%x length 0x%x buf %p\n",
 				&req->req, req->req.actual,
 				req->req.length, req->req.buf);
 			size -= t;
@@ -2110,7 +2086,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
 			} else {
 				list_for_each_entry(req, &ep->queue, queue) {
 					t = scnprintf(next, size,
-						"req %p actual 0x%x length"
+						"req %p actual 0x%x length "
 						"0x%x  buf %p\n",
 						&req->req, req->req.actual,
 						req->req.length, req->req.buf);
@@ -2202,7 +2178,6 @@ static int __init struct_udc_setup(struct fsl_udc *udc,
 	udc->usb_state = USB_STATE_POWERED;
 	udc->ep0_dir = 0;
 	udc->remote_wakeup = 0;	/* default to 0 on reset */
-	spin_lock_init(&udc->lock);
 
 	return 0;
 }
@@ -2254,7 +2229,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
 	u32 dccparams;
 
 	if (strcmp(pdev->name, driver_name)) {
-		VDBG("Wrong device\n");
+		VDBG("Wrong device");
 		return -ENODEV;
 	}
 
@@ -2264,23 +2239,26 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	spin_lock_init(&udc_controller->lock);
+	udc_controller->stopped = 1;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
-		kfree(udc_controller);
-		return -ENXIO;
+		ret = -ENXIO;
+		goto err_kfree;
 	}
 
 	if (!request_mem_region(res->start, res->end - res->start + 1,
 				driver_name)) {
-		ERR("request mem region for %s failed \n", pdev->name);
-		kfree(udc_controller);
-		return -EBUSY;
+		ERR("request mem region for %s failed\n", pdev->name);
+		ret = -EBUSY;
+		goto err_kfree;
 	}
 
 	dr_regs = ioremap(res->start, res->end - res->start + 1);
 	if (!dr_regs) {
 		ret = -ENOMEM;
-		goto err1;
+		goto err_release_mem_region;
 	}
 
 	usb_sys_regs = (struct usb_sys_interface *)
@@ -2291,7 +2269,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
 	if (!(dccparams & DCCPARAMS_DC)) {
 		ERR("This SOC doesn't support device role\n");
 		ret = -ENODEV;
-		goto err2;
+		goto err_iounmap;
 	}
 	/* Get max device endpoints */
 	/* DEN is bidirectional ep number, max_ep doubles the number */
@@ -2300,22 +2278,22 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
 	udc_controller->irq = platform_get_irq(pdev, 0);
 	if (!udc_controller->irq) {
 		ret = -ENODEV;
-		goto err2;
+		goto err_iounmap;
 	}
 
 	ret = request_irq(udc_controller->irq, fsl_udc_irq, IRQF_SHARED,
 			driver_name, udc_controller);
 	if (ret != 0) {
-		ERR("cannot request irq %d err %d \n",
+		ERR("cannot request irq %d err %d\n",
 				udc_controller->irq, ret);
-		goto err2;
+		goto err_iounmap;
 	}
 
 	/* Initialize the udc structure including QH member and other member */
 	if (struct_udc_setup(udc_controller, pdev)) {
 		ERR("Can't initialize udc data structure\n");
 		ret = -ENOMEM;
-		goto err3;
+		goto err_free_irq;
 	}
 
 	/* initialize usb hw reg except for regs for EP,
@@ -2336,7 +2314,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
 	udc_controller->gadget.dev.parent = &pdev->dev;
 	ret = device_register(&udc_controller->gadget.dev);
 	if (ret < 0)
-		goto err3;
+		goto err_free_irq;
 
 	/* setup QH and epctrl for ep0 */
 	ep0_setup(udc_controller);
@@ -2366,20 +2344,22 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
 			DTD_ALIGNMENT, UDC_DMA_BOUNDARY);
 	if (udc_controller->td_pool == NULL) {
 		ret = -ENOMEM;
-		goto err4;
+		goto err_unregister;
 	}
 	create_proc_file();
 	return 0;
 
-err4:
+err_unregister:
 	device_unregister(&udc_controller->gadget.dev);
-err3:
+err_free_irq:
 	free_irq(udc_controller->irq, udc_controller);
-err2:
+err_iounmap:
 	iounmap(dr_regs);
-err1:
+err_release_mem_region:
 	release_mem_region(res->start, res->end - res->start + 1);
+err_kfree:
 	kfree(udc_controller);
+	udc_controller = NULL;
 	return ret;
 }
 
@@ -2469,7 +2449,7 @@ module_init(udc_init);
 static void __exit udc_exit(void)
 {
 	platform_driver_unregister(&udc_driver);
-	printk("%s unregistered \n", driver_desc);
+	printk("%s unregistered\n", driver_desc);
 }
 
 module_exit(udc_exit);

+ 2 - 19
drivers/usb/gadget/fsl_usb2_udc.h

@@ -424,16 +424,6 @@ struct ep_td_struct {
 /* Controller dma boundary */
 #define UDC_DMA_BOUNDARY			0x1000
 
-/* -----------------------------------------------------------------------*/
-/* ##### enum data
-*/
-typedef enum {
-	e_ULPI,
-	e_UTMI_8BIT,
-	e_UTMI_16BIT,
-	e_SERIAL
-} e_PhyInterface;
-
 /*-------------------------------------------------------------------------*/
 
 /* ### driver private data
@@ -469,9 +459,9 @@ struct fsl_ep {
 #define EP_DIR_OUT	0
 
 struct fsl_udc {
-
 	struct usb_gadget gadget;
 	struct usb_gadget_driver *driver;
+	struct completion *done;	/* to make sure release() is done */
 	struct fsl_ep *eps;
 	unsigned int max_ep;
 	unsigned int irq;
@@ -492,20 +482,13 @@ struct fsl_udc {
 	size_t ep_qh_size;		/* size after alignment adjustment*/
 	dma_addr_t ep_qh_dma;		/* dma address of QH */
 
-	u32 max_pipes;		/* Device max pipes */
-	u32 max_use_endpts;	/* Max endpointes to be used */
-	u32 bus_reset;		/* Device is bus reseting */
+	u32 max_pipes;          /* Device max pipes */
 	u32 resume_state;	/* USB state to resume */
 	u32 usb_state;		/* USB current state */
-	u32 usb_next_state;	/* USB next state */
 	u32 ep0_state;		/* Endpoint zero state */
 	u32 ep0_dir;		/* Endpoint zero direction: can be
 				   USB_DIR_IN or USB_DIR_OUT */
-	u32 usb_sof_count;	/* SOF count */
-	u32 errors;		/* USB ERRORs count */
 	u8 device_address;	/* Device USB address */
-
-	struct completion *done;	/* to make sure release() is done */
 };
 
 /*-------------------------------------------------------------------------*/

+ 9 - 0
drivers/usb/gadget/gadget_chips.h

@@ -151,6 +151,13 @@
 #define	gadget_is_m66592(g)	0
 #endif
 
+/* Freescale CPM/QE UDC SUPPORT */
+#ifdef CONFIG_USB_GADGET_FSL_QE
+#define gadget_is_fsl_qe(g)	!strcmp("fsl_qe_udc", (g)->name)
+#else
+#define gadget_is_fsl_qe(g)	0
+#endif
+
 
 // CONFIG_USB_GADGET_SX2
 // CONFIG_USB_GADGET_AU1X00
@@ -216,6 +223,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
 		return 0x20;
 	else if (gadget_is_m66592(gadget))
 		return 0x21;
+	else if (gadget_is_fsl_qe(gadget))
+		return 0x22;
 	return -ENOENT;
 }
 

+ 1 - 1
drivers/usb/gadget/gmidi.c

@@ -222,7 +222,7 @@ static struct usb_config_descriptor config_desc = {
 	 * power properties of the device. Is it selfpowered?
 	 */
 	.bmAttributes =		USB_CONFIG_ATT_ONE,
-	.bMaxPower =		1,
+	.bMaxPower =		CONFIG_USB_GADGET_VBUS_DRAW / 2,
 };
 
 /* B.3.1  Standard AC Interface Descriptor */

+ 34 - 6
drivers/usb/gadget/net2280.c

@@ -178,6 +178,7 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
 
 	/* ep_reset() has already been called */
 	ep->stopped = 0;
+	ep->wedged = 0;
 	ep->out_overflow = 0;
 
 	/* set speed-dependent max packet; may kick in high bandwidth */
@@ -1218,7 +1219,7 @@ static int net2280_dequeue (struct usb_ep *_ep, struct usb_request *_req)
 static int net2280_fifo_status (struct usb_ep *_ep);
 
 static int
-net2280_set_halt (struct usb_ep *_ep, int value)
+net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged)
 {
 	struct net2280_ep	*ep;
 	unsigned long		flags;
@@ -1239,16 +1240,21 @@ net2280_set_halt (struct usb_ep *_ep, int value)
 	else if (ep->is_in && value && net2280_fifo_status (_ep) != 0)
 		retval = -EAGAIN;
 	else {
-		VDEBUG (ep->dev, "%s %s halt\n", _ep->name,
-				value ? "set" : "clear");
+		VDEBUG (ep->dev, "%s %s %s\n", _ep->name,
+				value ? "set" : "clear",
+				wedged ? "wedge" : "halt");
 		/* set/clear, then synch memory views with the device */
 		if (value) {
 			if (ep->num == 0)
 				ep->dev->protocol_stall = 1;
 			else
 				set_halt (ep);
-		} else
+			if (wedged)
+				ep->wedged = 1;
+		} else {
 			clear_halt (ep);
+			ep->wedged = 0;
+		}
 		(void) readl (&ep->regs->ep_rsp);
 	}
 	spin_unlock_irqrestore (&ep->dev->lock, flags);
@@ -1256,6 +1262,20 @@ net2280_set_halt (struct usb_ep *_ep, int value)
 	return retval;
 }
 
+static int
+net2280_set_halt(struct usb_ep *_ep, int value)
+{
+	return net2280_set_halt_and_wedge(_ep, value, 0);
+}
+
+static int
+net2280_set_wedge(struct usb_ep *_ep)
+{
+	if (!_ep || _ep->name == ep0name)
+		return -EINVAL;
+	return net2280_set_halt_and_wedge(_ep, 1, 1);
+}
+
 static int
 net2280_fifo_status (struct usb_ep *_ep)
 {
@@ -1302,6 +1322,7 @@ static const struct usb_ep_ops net2280_ep_ops = {
 	.dequeue	= net2280_dequeue,
 
 	.set_halt	= net2280_set_halt,
+	.set_wedge	= net2280_set_wedge,
 	.fifo_status	= net2280_fifo_status,
 	.fifo_flush	= net2280_fifo_flush,
 };
@@ -2410,9 +2431,14 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
 				goto do_stall;
 			if ((e = get_ep_by_addr (dev, w_index)) == 0)
 				goto do_stall;
-			clear_halt (e);
+			if (e->wedged) {
+				VDEBUG(dev, "%s wedged, halt not cleared\n",
+						ep->ep.name);
+			} else {
+				VDEBUG(dev, "%s clear halt\n", ep->ep.name);
+				clear_halt(e);
+			}
 			allow_status (ep);
-			VDEBUG (dev, "%s clear halt\n", ep->ep.name);
 			goto next_endpoints;
 			}
 			break;
@@ -2427,6 +2453,8 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
 				goto do_stall;
 			if ((e = get_ep_by_addr (dev, w_index)) == 0)
 				goto do_stall;
+			if (e->ep.name == ep0name)
+				goto do_stall;
 			set_halt (e);
 			allow_status (ep);
 			VDEBUG (dev, "%s set halt\n", ep->ep.name);

+ 1 - 0
drivers/usb/gadget/net2280.h

@@ -109,6 +109,7 @@ struct net2280_ep {
 						in_fifo_validate : 1,
 						out_overflow : 1,
 						stopped : 1,
+						wedged : 1,
 						is_in : 1,
 						is_iso : 1,
 						responded : 1;

+ 7 - 0
drivers/usb/gadget/omap_udc.c

@@ -2313,6 +2313,13 @@ static int proc_otg_show(struct seq_file *s)
 
 	tmp = omap_readl(OTG_REV);
 	if (cpu_is_omap24xx()) {
+		/*
+		 * REVISIT: Not clear how this works on OMAP2.  trans
+		 * is ANDed to produce bits 7 and 8, which might make
+		 * sense for USB_TRANSCEIVER_CTRL on OMAP1,
+		 * but with CONTROL_DEVCONF, these bits have something to
+		 * do with the frame adjustment counter and McBSP2.
+		 */
 		ctrl_name = "control_devconf";
 		trans = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
 	} else {

+ 2 - 4
drivers/usb/gadget/printer.c

@@ -252,7 +252,7 @@ static struct usb_config_descriptor config_desc = {
 	.bConfigurationValue =	DEV_CONFIG_VALUE,
 	.iConfiguration =	0,
 	.bmAttributes =		USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
-	.bMaxPower =		1	/* Self-Powered */
+	.bMaxPower =		CONFIG_USB_GADGET_VBUS_DRAW / 2,
 };
 
 static struct usb_interface_descriptor intf_desc = {
@@ -1278,8 +1278,7 @@ unknown:
 	/* respond with data transfer before status phase? */
 	if (value >= 0) {
 		req->length = value;
-		req->zero = value < wLength
-				&& (value % gadget->ep0->maxpacket) == 0;
+		req->zero = value < wLength;
 		value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
 		if (value < 0) {
 			DBG(dev, "ep_queue --> %d\n", value);
@@ -1477,7 +1476,6 @@ autoconf_fail:
 	if (gadget->is_otg) {
 		otg_desc.bmAttributes |= USB_OTG_HNP,
 		config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
-		config_desc.bMaxPower = 4;
 	}
 
 	spin_lock_init(&dev->lock);

+ 0 - 1
drivers/usb/gadget/pxa27x_udc.c

@@ -22,7 +22,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/errno.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>

+ 1 - 1
drivers/usb/gadget/s3c2410_udc.c

@@ -1651,7 +1651,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
 		return -EBUSY;
 
 	if (!driver->bind || !driver->setup
-			|| driver->speed != USB_SPEED_FULL) {
+			|| driver->speed < USB_SPEED_FULL) {
 		printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n",
 			driver->bind, driver->setup, driver->speed);
 		return -EINVAL;

+ 14 - 1
drivers/usb/gadget/serial.c

@@ -43,6 +43,7 @@
 #include "epautoconf.c"
 
 #include "f_acm.c"
+#include "f_obex.c"
 #include "f_serial.c"
 #include "u_serial.c"
 
@@ -56,6 +57,7 @@
 #define GS_VENDOR_ID			0x0525	/* NetChip */
 #define GS_PRODUCT_ID			0xa4a6	/* Linux-USB Serial Gadget */
 #define GS_CDC_PRODUCT_ID		0xa4a7	/* ... as CDC-ACM */
+#define GS_CDC_OBEX_PRODUCT_ID		0xa4a9	/* ... as CDC-OBEX */
 
 /* string IDs are assigned dynamically */
 
@@ -125,6 +127,10 @@ static int use_acm = true;
 module_param(use_acm, bool, 0);
 MODULE_PARM_DESC(use_acm, "Use CDC ACM, default=yes");
 
+static int use_obex = false;
+module_param(use_obex, bool, 0);
+MODULE_PARM_DESC(use_obex, "Use CDC OBEX, default=no");
+
 static unsigned n_ports = 1;
 module_param(n_ports, uint, 0);
 MODULE_PARM_DESC(n_ports, "number of ports to create, default=1");
@@ -139,6 +145,8 @@ static int __init serial_bind_config(struct usb_configuration *c)
 	for (i = 0; i < n_ports && status == 0; i++) {
 		if (use_acm)
 			status = acm_bind_config(c, i);
+		else if (use_obex)
+			status = obex_bind_config(c, i);
 		else
 			status = gser_bind_config(c, i);
 	}
@@ -151,7 +159,6 @@ static struct usb_configuration serial_config_driver = {
 	/* .bConfigurationValue = f(use_acm) */
 	/* .iConfiguration = DYNAMIC */
 	.bmAttributes	= USB_CONFIG_ATT_SELFPOWER,
-	.bMaxPower	= 1,	/* 2 mA, minimal */
 };
 
 static int __init gs_bind(struct usb_composite_dev *cdev)
@@ -249,6 +256,12 @@ static int __init init(void)
 		device_desc.bDeviceClass = USB_CLASS_COMM;
 		device_desc.idProduct =
 				__constant_cpu_to_le16(GS_CDC_PRODUCT_ID);
+	} else if (use_obex) {
+		serial_config_driver.label = "CDC OBEX config";
+		serial_config_driver.bConfigurationValue = 3;
+		device_desc.bDeviceClass = USB_CLASS_COMM;
+		device_desc.idProduct =
+			__constant_cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
 	} else {
 		serial_config_driver.label = "Generic Serial config";
 		serial_config_driver.bConfigurationValue = 1;

+ 7 - 0
drivers/usb/gadget/u_ether.c

@@ -873,6 +873,13 @@ struct net_device *gether_connect(struct gether *link)
 		spin_lock(&dev->lock);
 		dev->port_usb = link;
 		link->ioport = dev;
+		if (netif_running(dev->net)) {
+			if (link->open)
+				link->open(link);
+		} else {
+			if (link->close)
+				link->close(link);
+		}
 		spin_unlock(&dev->lock);
 
 		netif_carrier_on(dev->net);

+ 1 - 0
drivers/usb/gadget/u_serial.h

@@ -62,5 +62,6 @@ void gserial_disconnect(struct gserial *);
 /* functions are bound to configurations by a config or gadget driver */
 int acm_bind_config(struct usb_configuration *c, u8 port_num);
 int gser_bind_config(struct usb_configuration *c, u8 port_num);
+int obex_bind_config(struct usb_configuration *c, u8 port_num);
 
 #endif /* __U_SERIAL_H */

+ 32 - 24
drivers/usb/host/ehci-dbg.c

@@ -358,7 +358,8 @@ struct debug_buffer {
 	struct usb_bus *bus;
 	struct mutex mutex;	/* protect filling of buffer */
 	size_t count;		/* number of characters filled into buffer */
-	char *page;
+	char *output_buf;
+	size_t alloc_size;
 };
 
 #define speed_char(info1) ({ char tmp; \
@@ -488,8 +489,8 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
 
 	hcd = bus_to_hcd(buf->bus);
 	ehci = hcd_to_ehci (hcd);
-	next = buf->page;
-	size = PAGE_SIZE;
+	next = buf->output_buf;
+	size = buf->alloc_size;
 
 	*next = 0;
 
@@ -510,7 +511,7 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
 	}
 	spin_unlock_irqrestore (&ehci->lock, flags);
 
-	return strlen(buf->page);
+	return strlen(buf->output_buf);
 }
 
 #define DBG_SCHED_LIMIT 64
@@ -531,8 +532,8 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 
 	hcd = bus_to_hcd(buf->bus);
 	ehci = hcd_to_ehci (hcd);
-	next = buf->page;
-	size = PAGE_SIZE;
+	next = buf->output_buf;
+	size = buf->alloc_size;
 
 	temp = scnprintf (next, size, "size = %d\n", ehci->periodic_size);
 	size -= temp;
@@ -568,14 +569,16 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 				for (temp = 0; temp < seen_count; temp++) {
 					if (seen [temp].ptr != p.ptr)
 						continue;
-					if (p.qh->qh_next.ptr)
+					if (p.qh->qh_next.ptr) {
 						temp = scnprintf (next, size,
 							" ...");
-					p.ptr = NULL;
+						size -= temp;
+						next += temp;
+					}
 					break;
 				}
 				/* show more info the first time around */
-				if (temp == seen_count && p.ptr) {
+				if (temp == seen_count) {
 					u32	scratch = hc32_to_cpup(ehci,
 							&p.qh->hw_info1);
 					struct ehci_qtd	*qtd;
@@ -649,7 +652,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 	spin_unlock_irqrestore (&ehci->lock, flags);
 	kfree (seen);
 
-	return PAGE_SIZE - size;
+	return buf->alloc_size - size;
 }
 #undef DBG_SCHED_LIMIT
 
@@ -665,14 +668,14 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 
 	hcd = bus_to_hcd(buf->bus);
 	ehci = hcd_to_ehci (hcd);
-	next = buf->page;
-	size = PAGE_SIZE;
+	next = buf->output_buf;
+	size = buf->alloc_size;
 
 	spin_lock_irqsave (&ehci->lock, flags);
 
 	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
 		size = scnprintf (next, size,
-			"bus %s, device %s (driver " DRIVER_VERSION ")\n"
+			"bus %s, device %s\n"
 			"%s\n"
 			"SUSPENDED (no register access)\n",
 			hcd->self.controller->bus->name,
@@ -684,7 +687,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 	/* Capability Registers */
 	i = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
 	temp = scnprintf (next, size,
-		"bus %s, device %s (driver " DRIVER_VERSION ")\n"
+		"bus %s, device %s\n"
 		"%s\n"
 		"EHCI %x.%02x, hcd state %d\n",
 		hcd->self.controller->bus->name,
@@ -808,7 +811,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 done:
 	spin_unlock_irqrestore (&ehci->lock, flags);
 
-	return PAGE_SIZE - size;
+	return buf->alloc_size - size;
 }
 
 static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
@@ -822,6 +825,7 @@ static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
 		buf->bus = bus;
 		buf->fill_func = fill_func;
 		mutex_init(&buf->mutex);
+		buf->alloc_size = PAGE_SIZE;
 	}
 
 	return buf;
@@ -831,10 +835,10 @@ static int fill_buffer(struct debug_buffer *buf)
 {
 	int ret = 0;
 
-	if (!buf->page)
-		buf->page = (char *)get_zeroed_page(GFP_KERNEL);
+	if (!buf->output_buf)
+		buf->output_buf = (char *)vmalloc(buf->alloc_size);
 
-	if (!buf->page) {
+	if (!buf->output_buf) {
 		ret = -ENOMEM;
 		goto out;
 	}
@@ -867,7 +871,7 @@ static ssize_t debug_output(struct file *file, char __user *user_buf,
 	mutex_unlock(&buf->mutex);
 
 	ret = simple_read_from_buffer(user_buf, len, offset,
-				      buf->page, buf->count);
+				      buf->output_buf, buf->count);
 
 out:
 	return ret;
@@ -879,8 +883,8 @@ static int debug_close(struct inode *inode, struct file *file)
 	struct debug_buffer *buf = file->private_data;
 
 	if (buf) {
-		if (buf->page)
-			free_page((unsigned long)buf->page);
+		if (buf->output_buf)
+			vfree(buf->output_buf);
 		kfree(buf);
 	}
 
@@ -895,10 +899,14 @@ static int debug_async_open(struct inode *inode, struct file *file)
 
 static int debug_periodic_open(struct inode *inode, struct file *file)
 {
-	file->private_data = alloc_buffer(inode->i_private,
-					  fill_periodic_buffer);
+	struct debug_buffer *buf;
+	buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
+	if (!buf)
+		return -ENOMEM;
 
-	return file->private_data ? 0 : -ENOMEM;
+	buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8)*PAGE_SIZE;
+	file->private_data = buf;
+	return 0;
 }
 
 static int debug_registers_open(struct inode *inode, struct file *file)

+ 29 - 19
drivers/usb/host/ehci-hcd.c

@@ -24,6 +24,7 @@
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/timer.h>
@@ -59,7 +60,6 @@
  * providing early devices for those host controllers to talk to!
  */
 
-#define DRIVER_VERSION "10 Dec 2004"
 #define DRIVER_AUTHOR "David Brownell"
 #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
 
@@ -620,9 +620,9 @@ static int ehci_run (struct usb_hcd *hcd)
 
 	temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
 	ehci_info (ehci,
-		"USB %x.%x started, EHCI %x.%02x, driver %s%s\n",
+		"USB %x.%x started, EHCI %x.%02x%s\n",
 		((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
-		temp >> 8, temp & 0xff, DRIVER_VERSION,
+		temp >> 8, temp & 0xff,
 		ignore_oc ? ", overcurrent ignored" : "");
 
 	ehci_writel(ehci, INTR_MASK,
@@ -706,7 +706,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 		pcd_status = status;
 
 		/* resume root hub? */
-		if (!(ehci_readl(ehci, &ehci->regs->command) & CMD_RUN))
+		if (!(cmd & CMD_RUN))
 			usb_hcd_resume_root_hub(hcd);
 
 		while (i--) {
@@ -715,8 +715,11 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 
 			if (pstatus & PORT_OWNER)
 				continue;
-			if (!(pstatus & PORT_RESUME)
-					|| ehci->reset_done [i] != 0)
+			if (!(test_bit(i, &ehci->suspended_ports) &&
+					((pstatus & PORT_RESUME) ||
+						!(pstatus & PORT_SUSPEND)) &&
+					(pstatus & PORT_PE) &&
+					ehci->reset_done[i] == 0))
 				continue;
 
 			/* start 20 msec resume signaling from this port,
@@ -731,9 +734,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 
 	/* PCI errors [4.15.2.4] */
 	if (unlikely ((status & STS_FATAL) != 0)) {
-		dbg_cmd (ehci, "fatal", ehci_readl(ehci,
-						   &ehci->regs->command));
-		dbg_status (ehci, "fatal", status);
+		dbg_cmd(ehci, "fatal", cmd);
+		dbg_status(ehci, "fatal", status);
 		if (status & STS_HALT) {
 			ehci_err (ehci, "fatal error\n");
 dead:
@@ -994,9 +996,7 @@ static int ehci_get_frame (struct usb_hcd *hcd)
 
 /*-------------------------------------------------------------------------*/
 
-#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
-
-MODULE_DESCRIPTION (DRIVER_INFO);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR (DRIVER_AUTHOR);
 MODULE_LICENSE ("GPL");
 
@@ -1020,11 +1020,6 @@ MODULE_LICENSE ("GPL");
 #define	PS3_SYSTEM_BUS_DRIVER	ps3_ehci_driver
 #endif
 
-#if defined(CONFIG_440EPX) && !defined(CONFIG_PPC_MERGE)
-#include "ehci-ppc-soc.c"
-#define	PLATFORM_DRIVER		ehci_ppc_soc_driver
-#endif
-
 #ifdef CONFIG_USB_EHCI_HCD_PPC_OF
 #include "ehci-ppc-of.c"
 #define OF_PLATFORM_DRIVER	ehci_hcd_ppc_of_driver
@@ -1049,6 +1044,16 @@ static int __init ehci_hcd_init(void)
 {
 	int retval = 0;
 
+	if (usb_disabled())
+		return -ENODEV;
+
+	printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name);
+	set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
+	if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
+			test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
+		printk(KERN_WARNING "Warning! ehci_hcd should always be loaded"
+				" before uhci_hcd and ohci_hcd, not after\n");
+
 	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
 		 hcd_name,
 		 sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
@@ -1056,8 +1061,10 @@ static int __init ehci_hcd_init(void)
 
 #ifdef DEBUG
 	ehci_debug_root = debugfs_create_dir("ehci", NULL);
-	if (!ehci_debug_root)
-		return -ENOENT;
+	if (!ehci_debug_root) {
+		retval = -ENOENT;
+		goto err_debug;
+	}
 #endif
 
 #ifdef PLATFORM_DRIVER
@@ -1105,6 +1112,8 @@ clean0:
 	debugfs_remove(ehci_debug_root);
 	ehci_debug_root = NULL;
 #endif
+err_debug:
+	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
 	return retval;
 }
 module_init(ehci_hcd_init);
@@ -1126,6 +1135,7 @@ static void __exit ehci_hcd_cleanup(void)
 #ifdef DEBUG
 	debugfs_remove(ehci_debug_root);
 #endif
+	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
 }
 module_exit(ehci_hcd_cleanup);
 

+ 19 - 8
drivers/usb/host/ehci-hub.c

@@ -236,10 +236,8 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
 		temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
 		temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
 		if (test_bit(i, &ehci->bus_suspended) &&
-				(temp & PORT_SUSPEND)) {
-			ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
+				(temp & PORT_SUSPEND))
 			temp |= PORT_RESUME;
-		}
 		ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
 	}
 	i = HCS_N_PORTS (ehci->hcs_params);
@@ -482,10 +480,9 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
 		 * controller by the user.
 		 */
 
-		if ((temp & mask) != 0
-				|| ((temp & PORT_RESUME) != 0
-					&& time_after_eq(jiffies,
-						ehci->reset_done[i]))) {
+		if ((temp & mask) != 0 || test_bit(i, &ehci->port_c_suspend)
+				|| (ehci->reset_done[i] && time_after_eq(
+					jiffies, ehci->reset_done[i]))) {
 			if (i < 7)
 			    buf [0] |= 1 << (i + 1);
 			else
@@ -688,6 +685,7 @@ static int ehci_hub_control (
 			/* resume completed? */
 			else if (time_after_eq(jiffies,
 					ehci->reset_done[wIndex])) {
+				clear_bit(wIndex, &ehci->suspended_ports);
 				set_bit(wIndex, &ehci->port_c_suspend);
 				ehci->reset_done[wIndex] = 0;
 
@@ -734,6 +732,9 @@ static int ehci_hub_control (
 					ehci_readl(ehci, status_reg));
 		}
 
+		if (!(temp & (PORT_RESUME|PORT_RESET)))
+			ehci->reset_done[wIndex] = 0;
+
 		/* transfer dedicated ports to the companion hc */
 		if ((temp & PORT_CONNECT) &&
 				test_bit(wIndex, &ehci->companion_ports)) {
@@ -757,8 +758,17 @@ static int ehci_hub_control (
 		}
 		if (temp & PORT_PE)
 			status |= 1 << USB_PORT_FEAT_ENABLE;
-		if (temp & (PORT_SUSPEND|PORT_RESUME))
+
+		/* maybe the port was unsuspended without our knowledge */
+		if (temp & (PORT_SUSPEND|PORT_RESUME)) {
 			status |= 1 << USB_PORT_FEAT_SUSPEND;
+		} else if (test_bit(wIndex, &ehci->suspended_ports)) {
+			clear_bit(wIndex, &ehci->suspended_ports);
+			ehci->reset_done[wIndex] = 0;
+			if (temp & PORT_PE)
+				set_bit(wIndex, &ehci->port_c_suspend);
+		}
+
 		if (temp & PORT_OC)
 			status |= 1 << USB_PORT_FEAT_OVER_CURRENT;
 		if (temp & PORT_RESET)
@@ -803,6 +813,7 @@ static int ehci_hub_control (
 					|| (temp & PORT_RESET) != 0)
 				goto error;
 			ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
+			set_bit(wIndex, &ehci->suspended_ports);
 			break;
 		case USB_PORT_FEAT_POWER:
 			if (HCS_PPC (ehci->hcs_params))

+ 0 - 201
drivers/usb/host/ehci-ppc-soc.c

@@ -1,201 +0,0 @@
-/*
- * EHCI HCD (Host Controller Driver) for USB.
- *
- * (C) Copyright 2006-2007 Stefan Roese <sr@denx.de>, DENX Software Engineering
- *
- * Bus Glue for PPC On-Chip EHCI driver
- * Tested on AMCC 440EPx
- *
- * Based on "ehci-au1xxx.c" by K.Boge <karsten.boge@amd.com>
- *
- * This file is licenced under the GPL.
- */
-
-#include <linux/platform_device.h>
-
-extern int usb_disabled(void);
-
-/* called during probe() after chip reset completes */
-static int ehci_ppc_soc_setup(struct usb_hcd *hcd)
-{
-	struct ehci_hcd	*ehci = hcd_to_ehci(hcd);
-	int		retval;
-
-	retval = ehci_halt(ehci);
-	if (retval)
-		return retval;
-
-	retval = ehci_init(hcd);
-	if (retval)
-		return retval;
-
-	ehci->sbrn = 0x20;
-	return ehci_reset(ehci);
-}
-
-/**
- * usb_ehci_ppc_soc_probe - initialize PPC-SoC-based HCDs
- * Context: !in_interrupt()
- *
- * Allocates basic resources for this USB host controller, and
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
- *
- */
-int usb_ehci_ppc_soc_probe(const struct hc_driver *driver,
-			   struct usb_hcd **hcd_out,
-			   struct platform_device *dev)
-{
-	int retval;
-	struct usb_hcd *hcd;
-	struct ehci_hcd *ehci;
-
-	if (dev->resource[1].flags != IORESOURCE_IRQ) {
-		pr_debug("resource[1] is not IORESOURCE_IRQ");
-		retval = -ENOMEM;
-	}
-	hcd = usb_create_hcd(driver, &dev->dev, "PPC-SOC EHCI");
-	if (!hcd)
-		return -ENOMEM;
-	hcd->rsrc_start = dev->resource[0].start;
-	hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
-
-	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
-		pr_debug("request_mem_region failed");
-		retval = -EBUSY;
-		goto err1;
-	}
-
-	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
-	if (!hcd->regs) {
-		pr_debug("ioremap failed");
-		retval = -ENOMEM;
-		goto err2;
-	}
-
-	ehci = hcd_to_ehci(hcd);
-	ehci->big_endian_mmio = 1;
-	ehci->big_endian_desc = 1;
-	ehci->caps = hcd->regs;
-	ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
-
-	/* cache this readonly data; minimize chip reads */
-	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
-
-#if defined(CONFIG_440EPX)
-	/*
-	 * 440EPx Errata USBH_3
-	 * Fix: Enable Break Memory Transfer (BMT) in INSNREG3
-	 */
-	out_be32((void *)((ulong)(&ehci->regs->command) + 0x8c), (1 << 0));
-	ehci_dbg(ehci, "Break Memory Transfer (BMT) has beed enabled!\n");
-#endif
-
-	retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED);
-	if (retval == 0)
-		return retval;
-
-	iounmap(hcd->regs);
-err2:
-	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-err1:
-	usb_put_hcd(hcd);
-	return retval;
-}
-
-/* may be called without controller electrically present */
-/* may be called with controller, bus, and devices active */
-
-/**
- * usb_ehci_hcd_ppc_soc_remove - shutdown processing for PPC-SoC-based HCDs
- * @dev: USB Host Controller being removed
- * Context: !in_interrupt()
- *
- * Reverses the effect of usb_ehci_hcd_ppc_soc_probe(), first invoking
- * the HCD's stop() method.  It is always called from a thread
- * context, normally "rmmod", "apmd", or something similar.
- *
- */
-void usb_ehci_ppc_soc_remove(struct usb_hcd *hcd, struct platform_device *dev)
-{
-	usb_remove_hcd(hcd);
-	iounmap(hcd->regs);
-	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-	usb_put_hcd(hcd);
-}
-
-static const struct hc_driver ehci_ppc_soc_hc_driver = {
-	.description = hcd_name,
-	.product_desc = "PPC-SOC EHCI",
-	.hcd_priv_size = sizeof(struct ehci_hcd),
-
-	/*
-	 * generic hardware linkage
-	 */
-	.irq = ehci_irq,
-	.flags = HCD_MEMORY | HCD_USB2,
-
-	/*
-	 * basic lifecycle operations
-	 */
-	.reset = ehci_ppc_soc_setup,
-	.start = ehci_run,
-	.stop = ehci_stop,
-	.shutdown = ehci_shutdown,
-
-	/*
-	 * managing i/o requests and associated device resources
-	 */
-	.urb_enqueue = ehci_urb_enqueue,
-	.urb_dequeue = ehci_urb_dequeue,
-	.endpoint_disable = ehci_endpoint_disable,
-
-	/*
-	 * scheduling support
-	 */
-	.get_frame_number = ehci_get_frame,
-
-	/*
-	 * root hub support
-	 */
-	.hub_status_data = ehci_hub_status_data,
-	.hub_control = ehci_hub_control,
-	.bus_suspend = ehci_bus_suspend,
-	.bus_resume = ehci_bus_resume,
-	.relinquish_port = ehci_relinquish_port,
-	.port_handed_over = ehci_port_handed_over,
-};
-
-static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev)
-{
-	struct usb_hcd *hcd = NULL;
-	int ret;
-
-	pr_debug("In ehci_hcd_ppc_soc_drv_probe\n");
-
-	if (usb_disabled())
-		return -ENODEV;
-
-	/* FIXME we only want one one probe() not two */
-	ret = usb_ehci_ppc_soc_probe(&ehci_ppc_soc_hc_driver, &hcd, pdev);
-	return ret;
-}
-
-static int ehci_hcd_ppc_soc_drv_remove(struct platform_device *pdev)
-{
-	struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
-	/* FIXME we only want one one remove() not two */
-	usb_ehci_ppc_soc_remove(hcd, pdev);
-	return 0;
-}
-
-MODULE_ALIAS("platform:ppc-soc-ehci");
-static struct platform_driver ehci_ppc_soc_driver = {
-	.probe = ehci_hcd_ppc_soc_drv_probe,
-	.remove = ehci_hcd_ppc_soc_drv_remove,
-	.shutdown = usb_hcd_platform_shutdown,
-	.driver = {
-		.name = "ppc-soc-ehci",
-	}
-};

+ 9 - 14
drivers/usb/host/ehci.h

@@ -99,6 +99,8 @@ struct ehci_hcd {			/* one per controller */
 			owned by the companion during a bus suspend */
 	unsigned long		port_c_suspend;		/* which ports have
 			the change-suspend feature turned on */
+	unsigned long		suspended_ports;	/* which ports are
+			suspended */
 
 	/* per-HC memory pools (could be per-bus, but ...) */
 	struct dma_pool		*qh_pool;	/* qh per active urb */
@@ -181,14 +183,16 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
 	 * the async ring; just the I/O watchdog.  Note that if a
 	 * SHRINK were pending, OFF would never be requested.
 	 */
-	if (timer_pending(&ehci->watchdog)
-			&& ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
-				& ehci->actions))
-		return;
+	enum ehci_timer_action oldactions = ehci->actions;
 
 	if (!test_and_set_bit (action, &ehci->actions)) {
 		unsigned long t;
 
+		if (timer_pending(&ehci->watchdog)
+			&& ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
+				& oldactions))
+			return;
+
 		switch (action) {
 		case TIMER_IO_WATCHDOG:
 			t = EHCI_IO_JIFFIES;
@@ -204,7 +208,7 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
 			t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
 			break;
 		}
-		mod_timer(&ehci->watchdog, t + jiffies);
+		mod_timer(&ehci->watchdog, round_jiffies(t + jiffies));
 	}
 }
 
@@ -604,16 +608,7 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
 /*
  * Big-endian read/write functions are arch-specific.
  * Other arches can be added if/when they're needed.
- *
- * REVISIT: arch/powerpc now has readl/writel_be, so the
- * definition below can die once the 4xx support is
- * finally ported over.
  */
-#if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE)
-#define readl_be(addr)		in_be32((__force unsigned *)addr)
-#define writel_be(val, addr)	out_be32((__force unsigned *)addr, val)
-#endif
-
 #if defined(CONFIG_ARM) && defined(CONFIG_ARCH_IXP4XX)
 #define readl_be(addr)		__raw_readl((__force unsigned *)addr)
 #define writel_be(val, addr)	__raw_writel(val, (__force unsigned *)addr)

+ 9 - 4
drivers/usb/host/isp116x-hcd.c

@@ -1562,11 +1562,12 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
 {
 	struct usb_hcd *hcd;
 	struct isp116x *isp116x;
-	struct resource *addr, *data;
+	struct resource *addr, *data, *ires;
 	void __iomem *addr_reg;
 	void __iomem *data_reg;
 	int irq;
 	int ret = 0;
+	unsigned long irqflags;
 
 	if (pdev->num_resources < 3) {
 		ret = -ENODEV;
@@ -1575,12 +1576,16 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
 
 	data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	irq = platform_get_irq(pdev, 0);
-	if (!addr || !data || irq < 0) {
+	ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+	if (!addr || !data || !ires) {
 		ret = -ENODEV;
 		goto err1;
 	}
 
+	irq = ires->start;
+	irqflags = ires->flags & IRQF_TRIGGER_MASK;
+
 	if (pdev->dev.dma_mask) {
 		DBG("DMA not supported\n");
 		ret = -EINVAL;
@@ -1634,7 +1639,7 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
 		goto err6;
 	}
 
-	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+	ret = usb_add_hcd(hcd, irq, irqflags | IRQF_DISABLED);
 	if (ret)
 		goto err6;
 

+ 4 - 3
drivers/usb/host/isp1760-if.c

@@ -218,7 +218,7 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev,
 	 * and reading back and checking the contents are same or not
 	 */
 	if (reg_data != 0xFACE) {
-		err("scratch register mismatch %x", reg_data);
+		dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data);
 		goto clean;
 	}
 
@@ -232,9 +232,10 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev,
 	hcd = isp1760_register(pci_mem_phy0, length, dev->irq,
 		IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev),
 		devflags);
-	pci_set_drvdata(dev, hcd);
-	if (!hcd)
+	if (!IS_ERR(hcd)) {
+		pci_set_drvdata(dev, hcd);
 		return 0;
+	}
 clean:
 	status = -ENODEV;
 	iounmap(iobase);

+ 1 - 1
drivers/usb/host/ohci-dbg.c

@@ -649,7 +649,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 	ohci_dbg_sw (ohci, &next, &size,
 		"bus %s, device %s\n"
 		"%s\n"
-		"%s version " DRIVER_VERSION "\n",
+		"%s\n",
 		hcd->self.controller->bus->name,
 		dev_name(hcd->self.controller),
 		hcd->product_desc,

+ 5 - 5
drivers/usb/host/ohci-hcd.c

@@ -46,7 +46,6 @@
 
 #include "../core/hcd.h"
 
-#define DRIVER_VERSION "2006 August 04"
 #define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
 #define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
 
@@ -984,10 +983,8 @@ static int ohci_restart (struct ohci_hcd *ohci)
 
 /*-------------------------------------------------------------------------*/
 
-#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
-
 MODULE_AUTHOR (DRIVER_AUTHOR);
-MODULE_DESCRIPTION (DRIVER_INFO);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE ("GPL");
 
 #ifdef CONFIG_PCI
@@ -1095,9 +1092,10 @@ static int __init ohci_hcd_mod_init(void)
 	if (usb_disabled())
 		return -ENODEV;
 
-	printk (KERN_DEBUG "%s: " DRIVER_INFO "\n", hcd_name);
+	printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name);
 	pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name,
 		sizeof (struct ed), sizeof (struct td));
+	set_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
 
 #ifdef DEBUG
 	ohci_debug_root = debugfs_create_dir("ohci", NULL);
@@ -1184,6 +1182,7 @@ static int __init ohci_hcd_mod_init(void)
  error_debug:
 #endif
 
+	clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
 	return retval;
 }
 module_init(ohci_hcd_mod_init);
@@ -1214,6 +1213,7 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef DEBUG
 	debugfs_remove(ohci_debug_root);
 #endif
+	clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
 }
 module_exit(ohci_hcd_mod_exit);
 

+ 52 - 35
drivers/usb/host/ohci-hub.c

@@ -359,21 +359,24 @@ static void ohci_finish_controller_resume(struct usb_hcd *hcd)
 
 /* Carry out polling-, autostop-, and autoresume-related state changes */
 static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
-		int any_connected)
+		int any_connected, int rhsc_status)
 {
 	int	poll_rh = 1;
-	int	rhsc;
+	int	rhsc_enable;
 
-	rhsc = ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC;
-	switch (ohci->hc_control & OHCI_CTRL_HCFS) {
+	/* Some broken controllers never turn off RHCS in the interrupt
+	 * status register.  For their sake we won't re-enable RHSC
+	 * interrupts if the interrupt bit is already active.
+	 */
+	rhsc_enable = ohci_readl(ohci, &ohci->regs->intrenable) &
+			OHCI_INTR_RHSC;
 
+	switch (ohci->hc_control & OHCI_CTRL_HCFS) {
 	case OHCI_USB_OPER:
-		/* If no status changes are pending, enable status-change
-		 * interrupts.
-		 */
-		if (!rhsc && !changed) {
-			rhsc = OHCI_INTR_RHSC;
-			ohci_writel(ohci, rhsc, &ohci->regs->intrenable);
+		/* If no status changes are pending, enable RHSC interrupts. */
+		if (!rhsc_enable && !rhsc_status && !changed) {
+			rhsc_enable = OHCI_INTR_RHSC;
+			ohci_writel(ohci, rhsc_enable, &ohci->regs->intrenable);
 		}
 
 		/* Keep on polling until we know a device is connected
@@ -383,7 +386,7 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
 			if (any_connected ||
 					!device_may_wakeup(&ohci_to_hcd(ohci)
 						->self.root_hub->dev)) {
-				if (rhsc)
+				if (rhsc_enable)
 					poll_rh = 0;
 			} else {
 				ohci->autostop = 1;
@@ -396,34 +399,45 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
 				ohci->autostop = 0;
 				ohci->next_statechange = jiffies +
 						STATECHANGE_DELAY;
-			} else if (rhsc && time_after_eq(jiffies,
+			} else if (time_after_eq(jiffies,
 						ohci->next_statechange)
 					&& !ohci->ed_rm_list
 					&& !(ohci->hc_control &
 						OHCI_SCHED_ENABLES)) {
 				ohci_rh_suspend(ohci, 1);
-				poll_rh = 0;
+				if (rhsc_enable)
+					poll_rh = 0;
 			}
 		}
 		break;
 
-	/* if there is a port change, autostart or ask to be resumed */
 	case OHCI_USB_SUSPEND:
 	case OHCI_USB_RESUME:
+		/* if there is a port change, autostart or ask to be resumed */
 		if (changed) {
 			if (ohci->autostop)
 				ohci_rh_resume(ohci);
 			else
 				usb_hcd_resume_root_hub(ohci_to_hcd(ohci));
-		} else {
-			if (!rhsc && (ohci->autostop ||
-					ohci_to_hcd(ohci)->self.root_hub->
-						do_remote_wakeup))
-				ohci_writel(ohci, OHCI_INTR_RHSC,
-						&ohci->regs->intrenable);
 
-			/* everything is idle, no need for polling */
+		/* If remote wakeup is disabled, stop polling */
+		} else if (!ohci->autostop &&
+				!ohci_to_hcd(ohci)->self.root_hub->
+					do_remote_wakeup) {
 			poll_rh = 0;
+
+		} else {
+			/* If no status changes are pending,
+			 * enable RHSC interrupts
+			 */
+			if (!rhsc_enable && !rhsc_status) {
+				rhsc_enable = OHCI_INTR_RHSC;
+				ohci_writel(ohci, rhsc_enable,
+						&ohci->regs->intrenable);
+			}
+			/* Keep polling until RHSC is enabled */
+			if (rhsc_enable)
+				poll_rh = 0;
 		}
 		break;
 	}
@@ -441,18 +455,22 @@ static inline int ohci_rh_resume(struct ohci_hcd *ohci)
  * autostop isn't used when CONFIG_PM is turned off.
  */
 static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
-		int any_connected)
+		int any_connected, int rhsc_status)
 {
 	/* If RHSC is enabled, don't poll */
 	if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC)
 		return 0;
 
-	/* If no status changes are pending, enable status-change interrupts */
-	if (!changed) {
-		ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
-		return 0;
-	}
-	return 1;
+	/* If status changes are pending, continue polling.
+	 * Conversely, if no status changes are pending but the RHSC
+	 * status bit was set, then RHSC may be broken so continue polling.
+	 */
+	if (changed || rhsc_status)
+		return 1;
+
+	/* It's safe to re-enable RHSC interrupts */
+	ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
+	return 0;
 }
 
 #endif	/* CONFIG_PM */
@@ -467,6 +485,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
 	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
 	int		i, changed = 0, length = 1;
 	int		any_connected = 0;
+	int		rhsc_status;
 	unsigned long	flags;
 
 	spin_lock_irqsave (&ohci->lock, flags);
@@ -492,12 +511,10 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
 		length++;
 	}
 
-	/* Some broken controllers never turn off RHCS in the interrupt
-	 * status register.  For their sake we won't re-enable RHSC
-	 * interrupts if the flag is already set.
-	 */
-	if (ohci_readl(ohci, &ohci->regs->intrstatus) & OHCI_INTR_RHSC)
-		changed = 1;
+	/* Clear the RHSC status flag before reading the port statuses */
+	ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrstatus);
+	rhsc_status = ohci_readl(ohci, &ohci->regs->intrstatus) &
+			OHCI_INTR_RHSC;
 
 	/* look at each port */
 	for (i = 0; i < ohci->num_ports; i++) {
@@ -517,7 +534,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
 	}
 
 	hcd->poll_rh = ohci_root_hub_state_changes(ohci, changed,
-			any_connected);
+			any_connected, rhsc_status);
 
 done:
 	spin_unlock_irqrestore (&ohci->lock, flags);

+ 2 - 2
drivers/usb/host/ohci-omap.c

@@ -231,7 +231,7 @@ static int ohci_omap_init(struct usb_hcd *hcd)
 
 	omap_ohci_clock_power(1);
 
-	if (cpu_is_omap1510()) {
+	if (cpu_is_omap15xx()) {
 		omap_1510_local_bus_power(1);
 		omap_1510_local_bus_init();
 	}
@@ -319,7 +319,7 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
 	if (IS_ERR(usb_host_ck))
 		return PTR_ERR(usb_host_ck);
 
-	if (!cpu_is_omap1510())
+	if (!cpu_is_omap15xx())
 		usb_dc_ck = clk_get(0, "usb_dc_ck");
 	else
 		usb_dc_ck = clk_get(0, "lb_ck");

+ 1 - 1
drivers/usb/host/ohci-pnx4008.c

@@ -331,7 +331,7 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
 
 	int ret = 0, irq;
 
-	dev_dbg(&pdev->dev, "%s: " DRIVER_INFO " (pnx4008)\n", hcd_name);
+	dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (pnx4008)\n", hcd_name);
 	if (usb_disabled()) {
 		err("USB is disabled");
 		ret = -ENODEV;

+ 0 - 8
drivers/usb/host/ohci.h

@@ -540,15 +540,7 @@ static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci)
  * Big-endian read/write functions are arch-specific.
  * Other arches can be added if/when they're needed.
  *
- * REVISIT: arch/powerpc now has readl/writel_be, so the
- * definition below can die once the STB04xxx support is
- * finally ported over.
  */
-#if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE)
-#define readl_be(addr)		in_be32((__force unsigned *)addr)
-#define writel_be(val, addr)	out_be32((__force unsigned *)addr, val)
-#endif
-
 static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci,
 					__hc32 __iomem * regs)
 {

+ 65 - 36
drivers/usb/host/r8a66597-hcd.c

@@ -66,7 +66,7 @@ static unsigned short endian;
 module_param(endian, ushort, 0644);
 MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)");
 
-static unsigned short irq_sense = INTL;
+static unsigned short irq_sense = 0xff;
 module_param(irq_sense, ushort, 0644);
 MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0 "
 		"(default=32)");
@@ -118,7 +118,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
 		r8a66597_write(r8a66597, SCKE, SYSCFG0);
 		tmp = r8a66597_read(r8a66597, SYSCFG0);
 		if (i++ > 1000) {
-			err("register access fail.");
+			printk(KERN_ERR "r8a66597: register access fail.\n");
 			return -ENXIO;
 		}
 	} while ((tmp & SCKE) != SCKE);
@@ -128,7 +128,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
 		r8a66597_write(r8a66597, USBE, SYSCFG0);
 		tmp = r8a66597_read(r8a66597, SYSCFG0);
 		if (i++ > 1000) {
-			err("register access fail.");
+			printk(KERN_ERR "r8a66597: register access fail.\n");
 			return -ENXIO;
 		}
 	} while ((tmp & USBE) != USBE);
@@ -141,7 +141,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
 		msleep(1);
 		tmp = r8a66597_read(r8a66597, SYSCFG0);
 		if (i++ > 500) {
-			err("register access fail.");
+			printk(KERN_ERR "r8a66597: register access fail.\n");
 			return -ENXIO;
 		}
 	} while ((tmp & SCKE) != SCKE);
@@ -265,7 +265,7 @@ static void get_port_number(char *devpath, u16 *root_port, u16 *hub_port)
 	if (root_port) {
 		*root_port = (devpath[0] & 0x0F) - 1;
 		if (*root_port >= R8A66597_MAX_ROOT_HUB)
-			err("illegal root port number");
+			printk(KERN_ERR "r8a66597: Illegal root port number.\n");
 	}
 	if (hub_port)
 		*hub_port = devpath[2] & 0x0F;
@@ -286,7 +286,7 @@ static u16 get_r8a66597_usb_speed(enum usb_device_speed speed)
 		usbspd = HSMODE;
 		break;
 	default:
-		err("unknown speed");
+		printk(KERN_ERR "r8a66597: unknown speed\n");
 		break;
 	}
 
@@ -385,7 +385,7 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb)
 	struct r8a66597_device *dev;
 
 	if (is_hub_limit(urb->dev->devpath)) {
-		err("Externel hub limit reached.");
+		dev_err(&urb->dev->dev, "External hub limit reached.\n");
 		return 0;
 	}
 
@@ -406,8 +406,9 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb)
 		return addr;
 	}
 
-	err("cannot communicate with a USB device more than 10.(%x)",
-	    r8a66597->address_map);
+	dev_err(&urb->dev->dev,
+		"cannot communicate with a USB device more than 10.(%x)\n",
+		r8a66597->address_map);
 
 	return 0;
 }
@@ -447,7 +448,8 @@ static void r8a66597_reg_wait(struct r8a66597 *r8a66597, unsigned long reg,
 	do {
 		tmp = r8a66597_read(r8a66597, reg);
 		if (i++ > 1000000) {
-			err("register%lx, loop %x is timeout", reg, loop);
+			printk(KERN_ERR "r8a66597: register%lx, loop %x "
+			       "is timeout\n", reg, loop);
 			break;
 		}
 		ndelay(1);
@@ -675,7 +677,7 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597,
 			array[i++] = 1;
 		break;
 	default:
-		err("Illegal type");
+		printk(KERN_ERR "r8a66597: Illegal type\n");
 		return 0;
 	}
 
@@ -705,7 +707,7 @@ static u16 get_r8a66597_type(__u8 type)
 		r8a66597_type = R8A66597_ISO;
 		break;
 	default:
-		err("Illegal type");
+		printk(KERN_ERR "r8a66597: Illegal type\n");
 		r8a66597_type = 0x0000;
 		break;
 	}
@@ -724,7 +726,7 @@ static u16 get_bufnum(u16 pipenum)
 	else if (check_interrupt(pipenum))
 		bufnum = 4 + (pipenum - 6);
 	else
-		err("Illegal pipenum (%d)", pipenum);
+		printk(KERN_ERR "r8a66597: Illegal pipenum (%d)\n", pipenum);
 
 	return bufnum;
 }
@@ -740,7 +742,7 @@ static u16 get_buf_bsize(u16 pipenum)
 	else if (check_interrupt(pipenum))
 		buf_bsize = 0;
 	else
-		err("Illegal pipenum (%d)", pipenum);
+		printk(KERN_ERR "r8a66597: Illegal pipenum (%d)\n", pipenum);
 
 	return buf_bsize;
 }
@@ -760,10 +762,12 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
 			if ((r8a66597->dma_map & (1 << i)) != 0)
 				continue;
 
-			info("address %d, EndpointAddress 0x%02x use DMA FIFO",
-			     usb_pipedevice(urb->pipe),
-			     info->dir_in ? USB_ENDPOINT_DIR_MASK + info->epnum
-					    : info->epnum);
+			dev_info(&dev->udev->dev,
+				 "address %d, EndpointAddress 0x%02x use "
+				 "DMA FIFO\n", usb_pipedevice(urb->pipe),
+				 info->dir_in ?
+				 	USB_ENDPOINT_DIR_MASK + info->epnum
+					: info->epnum);
 
 			r8a66597->dma_map |= 1 << i;
 			dev->dma_map |= 1 << i;
@@ -1187,7 +1191,7 @@ static int start_transfer(struct r8a66597 *r8a66597, struct r8a66597_td *td)
 		prepare_status_packet(r8a66597, td);
 		break;
 	default:
-		err("invalid type.");
+		printk(KERN_ERR "r8a66597: invalid type.\n");
 		break;
 	}
 
@@ -1295,7 +1299,7 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum)
 	if (unlikely((tmp & FRDY) == 0)) {
 		pipe_stop(r8a66597, td->pipe);
 		pipe_irq_disable(r8a66597, pipenum);
-		err("in fifo not ready (%d)", pipenum);
+		printk(KERN_ERR "r8a66597: in fifo not ready (%d)\n", pipenum);
 		finish_request(r8a66597, td, pipenum, td->urb, -EPIPE);
 		return;
 	}
@@ -1370,7 +1374,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum)
 	if (unlikely((tmp & FRDY) == 0)) {
 		pipe_stop(r8a66597, td->pipe);
 		pipe_irq_disable(r8a66597, pipenum);
-		err("out write fifo not ready. (%d)", pipenum);
+		printk(KERN_ERR "r8a66597: out fifo not ready (%d)\n", pipenum);
 		finish_request(r8a66597, td, pipenum, urb, -EPIPE);
 		return;
 	}
@@ -2005,7 +2009,7 @@ static struct r8a66597_device *get_r8a66597_device(struct r8a66597 *r8a66597,
 		return dev;
 	}
 
-	err("get_r8a66597_device fail.(%d)\n", addr);
+	printk(KERN_ERR "r8a66597: get_r8a66597_device fail.(%d)\n", addr);
 	return NULL;
 }
 
@@ -2263,7 +2267,7 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
 #define resource_len(r) (((r)->end - (r)->start) + 1)
 static int __init r8a66597_probe(struct platform_device *pdev)
 {
-	struct resource *res = NULL;
+	struct resource *res = NULL, *ires;
 	int irq = -1;
 	void __iomem *reg = NULL;
 	struct usb_hcd *hcd = NULL;
@@ -2274,7 +2278,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)
 
 	if (pdev->dev.dma_mask) {
 		ret = -EINVAL;
-		err("dma not support");
+		dev_err(&pdev->dev, "dma not supported\n");
 		goto clean_up;
 	}
 
@@ -2282,21 +2286,25 @@ static int __init r8a66597_probe(struct platform_device *pdev)
 					   (char *)hcd_name);
 	if (!res) {
 		ret = -ENODEV;
-		err("platform_get_resource_byname error.");
+		dev_err(&pdev->dev, "platform_get_resource_byname error.\n");
 		goto clean_up;
 	}
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
+	ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!ires) {
 		ret = -ENODEV;
-		err("platform_get_irq error.");
+		dev_err(&pdev->dev,
+			"platform_get_resource IORESOURCE_IRQ error.\n");
 		goto clean_up;
 	}
 
+	irq = ires->start;
+	irq_trigger = ires->flags & IRQF_TRIGGER_MASK;
+
 	reg = ioremap(res->start, resource_len(res));
 	if (reg == NULL) {
 		ret = -ENOMEM;
-		err("ioremap error.");
+		dev_err(&pdev->dev, "ioremap error.\n");
 		goto clean_up;
 	}
 
@@ -2304,7 +2312,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)
 	hcd = usb_create_hcd(&r8a66597_hc_driver, &pdev->dev, (char *)hcd_name);
 	if (!hcd) {
 		ret = -ENOMEM;
-		err("Failed to create hcd");
+		dev_err(&pdev->dev, "Failed to create hcd\n");
 		goto clean_up;
 	}
 	r8a66597 = hcd_to_r8a66597(hcd);
@@ -2329,13 +2337,33 @@ static int __init r8a66597_probe(struct platform_device *pdev)
 	INIT_LIST_HEAD(&r8a66597->child_device);
 
 	hcd->rsrc_start = res->start;
-	if (irq_sense == INTL)
-		irq_trigger = IRQF_TRIGGER_LOW;
-	else
-		irq_trigger = IRQF_TRIGGER_FALLING;
+
+	/* irq_sense setting on cmdline takes precedence over resource
+	 * settings, so the introduction of irqflags in IRQ resourse
+	 * won't disturb existing setups */
+	switch (irq_sense) {
+		case INTL:
+			irq_trigger = IRQF_TRIGGER_LOW;
+			break;
+		case 0:
+			irq_trigger = IRQF_TRIGGER_FALLING;
+			break;
+		case 0xff:
+			if (irq_trigger)
+				irq_sense = (irq_trigger & IRQF_TRIGGER_LOW) ?
+					    INTL : 0;
+			else {
+				irq_sense = INTL;
+				irq_trigger = IRQF_TRIGGER_LOW;
+			}
+			break;
+		default:
+			dev_err(&pdev->dev, "Unknown irq_sense value.\n");
+	}
+
 	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger);
 	if (ret != 0) {
-		err("Failed to add hcd");
+		dev_err(&pdev->dev, "Failed to add hcd\n");
 		goto clean_up;
 	}
 
@@ -2364,7 +2392,8 @@ static int __init r8a66597_init(void)
 	if (usb_disabled())
 		return -ENODEV;
 
-	info("driver %s, %s", hcd_name, DRIVER_VERSION);
+	printk(KERN_INFO KBUILD_MODNAME ": driver %s, %s\n", hcd_name,
+	       DRIVER_VERSION);
 	return platform_driver_register(&r8a66597_driver);
 }
 module_init(r8a66597_init);

+ 11 - 4
drivers/usb/host/sl811-hcd.c

@@ -1620,22 +1620,26 @@ sl811h_probe(struct platform_device *dev)
 {
 	struct usb_hcd		*hcd;
 	struct sl811		*sl811;
-	struct resource		*addr, *data;
+	struct resource		*addr, *data, *ires;
 	int			irq;
 	void __iomem		*addr_reg;
 	void __iomem		*data_reg;
 	int			retval;
 	u8			tmp, ioaddr = 0;
+	unsigned long		irqflags;
 
 	/* basic sanity checks first.  board-specific init logic should
 	 * have initialized these three resources and probably board
 	 * specific platform_data.  we don't probe for IRQs, and do only
 	 * minimal sanity checking.
 	 */
-	irq = platform_get_irq(dev, 0);
-	if (dev->num_resources < 3 || irq < 0)
+	ires = platform_get_resource(dev, IORESOURCE_IRQ, 0);
+	if (dev->num_resources < 3 || !ires)
 		return -ENODEV;
 
+	irq = ires->start;
+	irqflags = ires->flags & IRQF_TRIGGER_MASK;
+
 	/* refuse to confuse usbcore */
 	if (dev->dev.dma_mask) {
 		DBG("no we won't dma\n");
@@ -1717,8 +1721,11 @@ sl811h_probe(struct platform_device *dev)
 	 * triggers (e.g. most ARM CPUs).  Initial driver stress testing
 	 * was on a system with single edge triggering, so most sorts of
 	 * triggering arrangement should work.
+	 *
+	 * Use resource IRQ flags if set by platform device setup.
 	 */
-	retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
+	irqflags |= IRQF_SHARED;
+	retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | irqflags);
 	if (retval != 0)
 		goto err6;
 

+ 6 - 4
drivers/usb/host/uhci-hcd.c

@@ -53,7 +53,6 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v3.0"
 #define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, \
 Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \
 Alan Stern"
@@ -951,12 +950,13 @@ static int __init uhci_hcd_init(void)
 {
 	int retval = -ENOMEM;
 
-	printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "%s\n",
-			ignore_oc ? ", overcurrent ignored" : "");
-
 	if (usb_disabled())
 		return -ENODEV;
 
+	printk(KERN_INFO "uhci_hcd: " DRIVER_DESC "%s\n",
+			ignore_oc ? ", overcurrent ignored" : "");
+	set_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
+
 	if (DEBUG_CONFIGURED) {
 		errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL);
 		if (!errbuf)
@@ -988,6 +988,7 @@ debug_failed:
 
 errbuf_failed:
 
+	clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
 	return retval;
 }
 
@@ -997,6 +998,7 @@ static void __exit uhci_hcd_cleanup(void)
 	kmem_cache_destroy(uhci_up_cachep);
 	debugfs_remove(uhci_debugfs_root);
 	kfree(errbuf);
+	clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
 }
 
 module_init(uhci_hcd_init);

+ 11 - 6
drivers/usb/host/uhci-q.c

@@ -1065,13 +1065,18 @@ static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb,
 		}
 		if (exponent < 0)
 			return -EINVAL;
-		qh->period = 1 << exponent;
-		qh->skel = SKEL_INDEX(exponent);
 
-		/* For now, interrupt phase is fixed by the layout
-		 * of the QH lists. */
-		qh->phase = (qh->period / 2) & (MAX_PHASE - 1);
-		ret = uhci_check_bandwidth(uhci, qh);
+		/* If the slot is full, try a lower period */
+		do {
+			qh->period = 1 << exponent;
+			qh->skel = SKEL_INDEX(exponent);
+
+			/* For now, interrupt phase is fixed by the layout
+			 * of the QH lists.
+			 */
+			qh->phase = (qh->period / 2) & (MAX_PHASE - 1);
+			ret = uhci_check_bandwidth(uhci, qh);
+		} while (ret != 0 && --exponent >= 0);
 		if (ret)
 			return ret;
 	} else if (qh->period > urb->interval)

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff