Эх сурвалжийг харах

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 17 жил өмнө
parent
commit
0cfd81031a
100 өөрчлөгдсөн 6271 нэмэгдсэн , 859 устгасан
  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:
 Users:
 		PowerTOP <power@bughost.org>
 		PowerTOP <power@bughost.org>
 		http://www.lesswatts.org/projects/powertop/
 		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>
 </para>
 
 
 !Edrivers/usb/gadget/f_acm.c
 !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
 !Edrivers/usb/gadget/f_serial.c
 
 
 </sect1>
 </sect1>

+ 3 - 0
Documentation/devices.txt

@@ -2571,6 +2571,9 @@ Your cooperation is appreciated.
 		160 = /dev/usb/legousbtower0	1st USB Legotower device
 		160 = /dev/usb/legousbtower0	1st USB Legotower device
 		    ...
 		    ...
 		175 = /dev/usb/legousbtower15	16th 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
 		240 = /dev/usb/dabusb0	First daubusb device
 		    ...
 		    ...
 		243 = /dev/usb/dabusb3	Fourth dabusb 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
 'J'	00-1F	drivers/scsi/gdth_ioctl.h
 'K'	all	linux/kd.h
 'K'	all	linux/kd.h
 'L'	00-1F	linux/loop.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
 'L'	E0-FF	linux/ppdd.h		encrypted disk device driver
 					<http://linux01.gwdg.de/~alatham/ppdd.html>
 					<http://linux01.gwdg.de/~alatham/ppdd.html>
 'M'	all	linux/soundcard.h
 'M'	all	linux/soundcard.h
@@ -110,6 +111,8 @@ Code	Seq#	Include File		Comments
 'W'	00-1F	linux/wanrouter.h	conflict!
 'W'	00-1F	linux/wanrouter.h	conflict!
 'X'	all	linux/xfs_fs.h
 'X'	all	linux/xfs_fs.h
 'Y'	all	linux/cyclades.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
 'a'	all				ATM on linux
 					<http://lrcwww.epfl.ch/linux-atm/magic.html>
 					<http://lrcwww.epfl.ch/linux-atm/magic.html>
 'b'	00-FF				bit3 vme host bridge
 '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
 			autosuspended.  Devices for which the delay is set
 			to a negative value won't be autosuspended at all.
 			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.mousepoll=
 			[USBHID] The interval which mice are to be polled at.
 			[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
 the call returns. They may be unlinked later but will be unlinked in
 finite time.
 finite time.
 
 
+usb_scuttle_anchored_urbs()
+---------------------------
+
+All URBs of an anchor are unanchored en masse.
+
 usb_wait_anchor_empty_timeout()
 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
 or a timeout, whichever comes first. Its return value will tell you
 whether the timeout was reached.
 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:
 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_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
 The conventional usage pattern is that a driver calls
 usb_autopm_get_interface() in its open routine and
 usb_autopm_get_interface() in its open routine and
 usb_autopm_put_interface() in its close or release routine.  But
 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;
 	struct work_struct reset_work;
 	wait_queue_head_t reset_wait;
 	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;
 		goto drop;
 	}
 	}
 	urq->nsg = n_elem;
 	urq->nsg = n_elem;
-	sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
 
 
 	if (blk_pc_request(rq)) {
 	if (blk_pc_request(rq)) {
 		ub_cmd_build_packet(sc, lun, cmd, urq);
 		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);
 		usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC);
 		if (!usbhid->out[usbhid->outhead].raw_report) {
 		if (!usbhid->out[usbhid->outhead].raw_report) {
 			spin_unlock_irqrestore(&usbhid->outlock, flags);
 			spin_unlock_irqrestore(&usbhid->outlock, flags);
-			warn("output queueing failed");
+			dev_warn(&hid->dev, "output queueing failed\n");
 			return;
 			return;
 		}
 		}
 		hid_output_report(report, usbhid->out[usbhid->outhead].raw_report);
 		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);
 		usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC);
 		if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) {
 		if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) {
 			spin_unlock_irqrestore(&usbhid->ctrllock, flags);
 			spin_unlock_irqrestore(&usbhid->ctrllock, flags);
-			warn("control queueing failed");
+			dev_warn(&hid->dev, "control queueing failed\n");
 			return;
 			return;
 		}
 		}
 		hid_output_report(report, usbhid->ctrl[usbhid->ctrlhead].raw_report);
 		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
  * Analyse the changes in an effect, and tell if we need to send an condition
  * parameter packet
  * 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 ret = 0;
 	int i;
 	int i;
 
 
 	if (new->type != FF_SPRING && new->type != FF_FRICTION) {
 	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;
 		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
  * Analyse the changes in an effect, and tell if we need to send a magnitude
  * parameter packet
  * 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) {
 	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;
 		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
  * Analyse the changes in an effect, and tell if we need to send an envelope
  * parameter packet
  * 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) {
 	switch (effect->type) {
 	case FF_CONSTANT:
 	case FF_CONSTANT:
@@ -256,7 +263,8 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec
 		break;
 		break;
 
 
 	default:
 	default:
-		warn("bad effect type in need_envelope_modifier");
+		dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
+			 __func__);
 	}
 	}
 
 
 	return 0;
 	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
  * Analyse the changes in an effect, and tell if we need to send a periodic
  * parameter effect
  * 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) {
 	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 0;
 	}
 	}
 	return (old->u.periodic.period != new->u.periodic.period
 	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 param2_err = 1;
 	int core_err = 0;
 	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,
 		param1_err = make_period_modifier(iforce, mod1_chunk,
 			old != NULL,
 			old != NULL,
 			effect->u.periodic.magnitude, effect->u.periodic.offset,
 			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);
 		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,
 		param2_err = make_envelope_modifier(iforce, mod2_chunk,
 			old !=NULL,
 			old !=NULL,
 			effect->u.periodic.envelope.attack_length,
 			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 param2_err = 1;
 	int core_err = 0;
 	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,
 		param1_err = make_magnitude_modifier(iforce, mod1_chunk,
 			old != NULL,
 			old != NULL,
 			effect->u.constant.level);
 			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);
 		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,
 		param2_err = make_envelope_modifier(iforce, mod2_chunk,
 			old != NULL,
 			old != NULL,
 			effect->u.constant.envelope.attack_length,
 			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;
 		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,
 		param_err = make_condition_modifier(iforce, mod1_chunk,
 			old != NULL,
 			old != NULL,
 			effect->u.condition[0].right_saturation,
 			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 */
 		/* Check: no effects should be present in memory */
 		for (i = 0; i < dev->ff->max_effects; i++) {
 		for (i = 0; i < dev->ff->max_effects; i++) {
 			if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags)) {
 			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;
 				break;
 			}
 			}
 		}
 		}
@@ -335,26 +337,26 @@ int iforce_init_device(struct iforce *iforce)
 	if (!iforce_get_id_packet(iforce, "M"))
 	if (!iforce_get_id_packet(iforce, "M"))
 		input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1];
 		input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1];
 	else
 	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"))
 	if (!iforce_get_id_packet(iforce, "P"))
 		input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1];
 		input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1];
 	else
 	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"))
 	if (!iforce_get_id_packet(iforce, "B"))
 		iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1];
 		iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1];
 	else
 	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"))
 	if (!iforce_get_id_packet(iforce, "N"))
 		ff_effects = iforce->edata[1];
 		ff_effects = iforce->edata[1];
 	else
 	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 */
 	/* Check if the device can store more effects than the driver can really handle */
 	if (ff_effects > IFORCE_EFFECTS_MAX) {
 	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);
 		       IFORCE_EFFECTS_MAX, ff_effects);
 		ff_effects = IFORCE_EFFECTS_MAX;
 		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) {
 	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);
 		spin_unlock_irqrestore(&iforce->xmit_lock, flags);
 		return -1;
 		return -1;
 	}
 	}
@@ -148,7 +149,7 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
 			return 0;
 			return 0;
 		}
 		}
 	}
 	}
-	warn("unused effect %04x updated !!!", addr);
+	dev_warn(&iforce->dev->dev, "unused effect %04x updated !!!\n", addr);
 	return -1;
 	return -1;
 }
 }
 
 
@@ -159,7 +160,8 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
 	static int being_used = 0;
 	static int being_used = 0;
 
 
 	if (being_used)
 	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++;
 	being_used++;
 
 
 #ifdef CONFIG_JOYSTICK_IFORCE_232
 #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)) ) {
 	if ( (n=usb_submit_urb(iforce->out, GFP_ATOMIC)) ) {
 		clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
 		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.
 	/* 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);
 	int result = usb_register(&xpad_driver);
 	if (result == 0)
 	if (result == 0)
-		info(DRIVER_DESC);
+		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
 	return result;
 	return result;
 }
 }
 
 

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

@@ -285,7 +285,6 @@ static const struct {
 };
 };
 
 
 /* Local function prototypes */
 /* 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 int ati_remote_open		(struct input_dev *inputdev);
 static void ati_remote_close		(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);
 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
  *	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))
 	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)
 	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]);
 		     data[0], data[1], data[2], data[3]);
 	else
 	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]);
 		     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 */
 	/* Deal with strange looking inputs */
 	if ( (urb->actual_length != 4) || (data[0] != 0x14) ||
 	if ( (urb->actual_length != 4) || (data[0] != 0x14) ||
 		((data[3] & 0x0f) != 0x00) ) {
 		((data[3] & 0x0f) != 0x00) ) {
-		ati_remote_dump(data, urb->actual_length);
+		ati_remote_dump(&urb->dev->dev, data, urb->actual_length);
 		return;
 		return;
 	}
 	}
 
 
@@ -814,7 +814,7 @@ static void ati_remote_disconnect(struct usb_interface *interface)
 	ati_remote = usb_get_intfdata(interface);
 	ati_remote = usb_get_intfdata(interface);
 	usb_set_intfdata(interface, NULL);
 	usb_set_intfdata(interface, NULL);
 	if (!ati_remote) {
 	if (!ati_remote) {
-		warn("%s - null device?\n", __func__);
+		dev_warn(&interface->dev, "%s - null device?\n", __func__);
 		return;
 		return;
 	}
 	}
 
 
@@ -834,9 +834,11 @@ static int __init ati_remote_init(void)
 
 
 	result = usb_register(&ati_remote_driver);
 	result = usb_register(&ati_remote_driver);
 	if (result)
 	if (result)
-		err("usb_register error #%d\n", result);
+		printk(KERN_ERR KBUILD_MODNAME
+		       ": usb_register error #%d\n", result);
 	else
 	else
-		info("Registered USB driver " DRIVER_DESC " v. " DRIVER_VERSION);
+		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+		       DRIVER_DESC "\n");
 
 
 	return result;
 	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);
 	int ret = usb_register(&yealink_driver);
 	if (ret == 0)
 	if (ret == 0)
-		info(DRIVER_DESC ":" DRIVER_VERSION);
+		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+		       DRIVER_DESC "\n");
 	return ret;
 	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);
 	int result = usb_register(&usb_acecad_driver);
 	if (result == 0)
 	if (result == 0)
-		info(DRIVER_VERSION ":" DRIVER_DESC);
+		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+		       DRIVER_DESC "\n");
 	return result;
 	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);
 	aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL);
 	inputdev = input_allocate_device();
 	inputdev = input_allocate_device();
 	if (!aiptek || !inputdev) {
 	if (!aiptek || !inputdev) {
-		warn("aiptek: cannot allocate memory or input device");
+		dev_warn(&intf->dev,
+			 "cannot allocate memory or input device\n");
 		goto fail1;
 		goto fail1;
         }
         }
 
 
 	aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
 	aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
 					GFP_ATOMIC, &aiptek->data_dma);
 					GFP_ATOMIC, &aiptek->data_dma);
         if (!aiptek->data) {
         if (!aiptek->data) {
-		warn("aiptek: cannot allocate usb buffer");
+		dev_warn(&intf->dev, "cannot allocate usb buffer\n");
 		goto fail1;
 		goto fail1;
 	}
 	}
 
 
 	aiptek->urb = usb_alloc_urb(0, GFP_KERNEL);
 	aiptek->urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!aiptek->urb) {
 	if (!aiptek->urb) {
-	        warn("aiptek: cannot allocate urb");
+	        dev_warn(&intf->dev, "cannot allocate urb\n");
 		goto fail2;
 		goto fail2;
 	}
 	}
 
 
@@ -1843,8 +1844,9 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
 		aiptek->curSetting.programmableDelay = speeds[i];
 		aiptek->curSetting.programmableDelay = speeds[i];
 		(void)aiptek_program_tablet(aiptek);
 		(void)aiptek_program_tablet(aiptek);
 		if (aiptek->inputdev->absmax[ABS_X] > 0) {
 		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;
 			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
 	/* Murphy says that some day someone will have a tablet that fails the
 	   above test. That's you, Frederic Rodrigo */
 	   above test. That's you, Frederic Rodrigo */
 	if (i == ARRAY_SIZE(speeds)) {
 	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;
 		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);
 	err = sysfs_create_group(&intf->dev.kobj, &aiptek_attribute_group);
 	if (err) {
 	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;
 		goto fail3;
         }
         }
 
 
@@ -1872,7 +1876,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	 */
 	 */
 	err = input_register_device(aiptek->inputdev);
 	err = input_register_device(aiptek->inputdev);
 	if (err) {
 	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;
 		goto fail4;
         }
         }
 	return 0;
 	return 0;
@@ -1922,8 +1927,9 @@ static int __init aiptek_init(void)
 {
 {
 	int result = usb_register(&aiptek_driver);
 	int result = usb_register(&aiptek_driver);
 	if (result == 0) {
 	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;
 	return result;
 }
 }

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

@@ -2,7 +2,7 @@
 
 
 GTCO digitizer USB driver
 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?
 TO CHECK:  Is pressure done right on report 5?
 
 
@@ -1010,7 +1010,7 @@ static void gtco_disconnect(struct usb_interface *interface)
 		kfree(gtco);
 		kfree(gtco);
 	}
 	}
 
 
-	info("gtco driver disconnected");
+	dev_info(&interface->dev, "gtco driver disconnected\n");
 }
 }
 
 
 /*   STANDARD MODULE LOAD ROUTINES  */
 /*   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);
 	retval = usb_register(&kbtab_driver);
 	if (retval)
 	if (retval)
 		goto out;
 		goto out;
-	info(DRIVER_VERSION ":" DRIVER_DESC);
+	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+	       DRIVER_DESC "\n");
 out:
 out:
 	return retval;
 	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();
 	wacom_driver.id_table = get_device_table();
 	result = usb_register(&wacom_driver);
 	result = usb_register(&wacom_driver);
 	if (result == 0)
 	if (result == 0)
-		info(DRIVER_VERSION ":" DRIVER_DESC);
+		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+		       DRIVER_DESC "\n");
 	return result;
 	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;
 	radio->curfreq = f->frequency;
 	if (dsbr100_setfreq(radio, radio->curfreq)==-1)
 	if (dsbr100_setfreq(radio, radio->curfreq)==-1)
-		warn("Set frequency failed");
+		dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
 	return 0;
 	return 0;
 }
 }
 
 
@@ -361,12 +361,14 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
 	case V4L2_CID_AUDIO_MUTE:
 	case V4L2_CID_AUDIO_MUTE:
 		if (ctrl->value) {
 		if (ctrl->value) {
 			if (dsbr100_stop(radio) == -1) {
 			if (dsbr100_stop(radio) == -1) {
-				warn("Radio did not respond properly");
+				dev_warn(&radio->usbdev->dev,
+					 "Radio did not respond properly\n");
 				return -EBUSY;
 				return -EBUSY;
 			}
 			}
 		} else {
 		} else {
 			if (dsbr100_start(radio) == -1) {
 			if (dsbr100_start(radio) == -1) {
-				warn("Radio did not respond properly");
+				dev_warn(&radio->usbdev->dev,
+					 "Radio did not respond properly\n");
 				return -EBUSY;
 				return -EBUSY;
 			}
 			}
 		}
 		}
@@ -416,7 +418,8 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file)
 	radio->muted = 1;
 	radio->muted = 1;
 
 
 	if (dsbr100_start(radio)<0) {
 	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;
 		radio->users = 0;
 		unlock_kernel();
 		unlock_kernel();
 		return -EIO;
 		return -EIO;
@@ -501,7 +504,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
 	radio->curfreq = FREQ_MIN*FREQ_MUL;
 	radio->curfreq = FREQ_MIN*FREQ_MUL;
 	video_set_drvdata(radio->videodev, radio);
 	video_set_drvdata(radio->videodev, radio);
 	if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr) < 0) {
 	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);
 		video_device_release(radio->videodev);
 		kfree(radio->transfer_buffer);
 		kfree(radio->transfer_buffer);
 		kfree(radio);
 		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);
 					err("dabusb_iso_complete: invalid len %d", len);
 			}
 			}
 			else
 			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)
 		if (dst != purb->actual_length)
 			err("dst!=purb->actual_length:%d!=%d", 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 ) {
 	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)))
 		if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
 			err("request failed");
 			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, 0x02);
 		reg_w(ov, R51x_SYS_SNAP, 0x00);
 		reg_w(ov, R51x_SYS_SNAP, 0x00);
 	} else if (ov->bclass == BCL_OV518) {
 	} 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 {
 	} 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) {
 	if (ov->bclass == BCL_OV511) {
 		ret = reg_r(ov, R51x_SYS_SNAP);
 		ret = reg_r(ov, R51x_SYS_SNAP);
 		if (ret < 0) {
 		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) {
 		} else if (ret & 0x08) {
 			status = 1;
 			status = 1;
 		}
 		}
 	} else if (ov->bclass == BCL_OV518) {
 	} 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 {
 	} else {
-		err("check snap: invalid bridge type");
+		dev_err(&ov->dev->dev, "clear snap: invalid bridge type\n");
 	}
 	}
 
 
 	return status;
 	return status;
@@ -5217,7 +5220,8 @@ saa7111a_configure(struct usb_ov511 *ov)
 	if (ov->bclass == BCL_OV511)
 	if (ov->bclass == BCL_OV511)
 		reg_w(ov, 0x11, 0x00);
 		reg_w(ov, 0x11, 0x00);
 	else
 	else
-		warn("SAA7111A not yet supported with OV518/OV518+");
+		dev_warn(&ov->dev->dev,
+			 "SAA7111A not yet supported with OV518/OV518+\n");
 
 
 	return 0;
 	return 0;
 }
 }
@@ -5456,7 +5460,8 @@ ov518_configure(struct usb_ov511 *ov)
 	 * required. OV518 has no uncompressed mode, to save RAM. */
 	 * required. OV518 has no uncompressed mode, to save RAM. */
 	if (!dumppix && !ov->compress) {
 	if (!dumppix && !ov->compress) {
 		ov->compress = 1;
 		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) {
 	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();
 	cam->input = input_dev = input_allocate_device();
 	if (!input_dev) {
 	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;
 		return;
 	}
 	}
 
 
@@ -243,8 +244,9 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev
 
 
 	error = input_register_device(cam->input);
 	error = input_register_device(cam->input);
 	if (error) {
 	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);
 		input_free_device(cam->input);
 		cam->input = NULL;
 		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();
 	cam->input = input_dev = input_allocate_device();
 	if (!input_dev) {
 	if (!input_dev) {
-		warn("insufficient mem for cam input device");
+		dev_warn(&dev->dev, "insufficient mem for cam input device\n");
 		return;
 		return;
 	}
 	}
 
 
@@ -107,8 +107,9 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
 
 
 	error = input_register_device(cam->input);
 	error = input_register_device(cam->input);
 	if (error) {
 	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);
 		input_free_device(cam->input);
 		cam->input = NULL;
 		cam->input = NULL;
 	}
 	}
@@ -587,8 +588,9 @@ static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb)
 			dataurb->iso_frame_desc[i].offset;
 			dataurb->iso_frame_desc[i].offset;
 
 
 		if (st < 0) {
 		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++;
 			uvd->stats.iso_err_count++;
 			continue;
 			continue;
 		}
 		}
@@ -699,7 +701,7 @@ static void qcm_stop_data(struct uvd *uvd)
 
 
 	ret = qcm_camera_off(uvd);
 	ret = qcm_camera_off(uvd);
 	if (ret)
 	if (ret)
-		warn("couldn't turn the cam off.");
+		dev_warn(&uvd->dev->dev, "couldn't turn the cam off.\n");
 
 
 	uvd->streaming = 0;
 	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[0].port = ALAUDA_PORT_XD;
 	al[1].port = ALAUDA_PORT_SM;
 	al[1].port = ALAUDA_PORT_SM;
 
 
-	info("alauda probed");
+	dev_info(&interface->dev, "alauda probed\n");
 	alauda_check_media(al);
 	alauda_check_media(al);
 	alauda_check_media(al+1);
 	alauda_check_media(al+1);
 
 
@@ -716,7 +716,7 @@ static void alauda_disconnect(struct usb_interface *interface)
 	if (al)
 	if (al)
 		kref_put(&al->kref, alauda_delete);
 		kref_put(&al->kref, alauda_delete);
 
 
-	info("alauda gone");
+	dev_info(&interface->dev, "alauda gone");
 }
 }
 
 
 static struct usb_driver alauda_driver = {
 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)
 	if (ret != 0)
 		goto free_mem;
 		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);
 	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)
 	if (ret != 0)
 		goto free_mem;
 		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);
 	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)
 	if (ret != 0)
 		goto free_mem;
 		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);
 	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;
 			goto found;
 	}
 	}
 
 
-	warn("%s: invalid speed %d", stir->netdev->name, speed);
+	dev_warn(&stir->netdev->dev, "invalid speed %d\n", speed);
 	return -EINVAL;
 	return -EINVAL;
 
 
  found:
  found:
@@ -598,8 +598,8 @@ static int fifo_txwait(struct stir_cb *stir, int space)
 		err = read_reg(stir, REG_FIFOCTL, stir->fifo_status, 
 		err = read_reg(stir, REG_FIFOCTL, stir->fifo_status, 
 				   FIFO_REGS_SIZE);
 				   FIFO_REGS_SIZE);
 		if (unlikely(err != 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;
 			return err;
 		}
 		}
@@ -783,8 +783,9 @@ static int stir_transmit_thread(void *arg)
 
 
 			if (unlikely(receive_start(stir))) {
 			if (unlikely(receive_start(stir))) {
 				if (net_ratelimit())
 				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;
 				stir->receiving = 0;
 				msleep(10);
 				msleep(10);
 				continue;
 				continue;
@@ -836,8 +837,8 @@ static void stir_rcv_irq(struct urb *urb)
 
 
 	/* in case of error, the kernel thread will restart us */
 	/* in case of error, the kernel thread will restart us */
 	if (err) {
 	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;
 		stir->receiving = 0;
 		wake_up_process(stir->thread);
 		wake_up_process(stir->thread);
 	}
 	}
@@ -1073,7 +1074,8 @@ static int stir_probe(struct usb_interface *intf,
 	if (ret != 0)
 	if (ret != 0)
 		goto err_out2;
 		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);
 	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);
 	struct catc *catc = netdev_priv(netdev);
 
 
-	warn("Transmit timed out.");
+	dev_warn(&netdev->dev, "Transmit timed out.\n");
 	usb_unlink_urb(catc->tx_urb);
 	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");
 			dbg("64k Memory\n");
 			break;
 			break;
 		default:
 		default:
-			warn("Couldn't detect memory size, assuming 32k");
+			dev_warn(&intf->dev,
+				 "Couldn't detect memory size, assuming 32k\n");
 		case 0x87654321:
 		case 0x87654321:
 			catc_set_reg(catc, TxBufCount, 4);
 			catc_set_reg(catc, TxBufCount, 4);
 			catc_set_reg(catc, RxBufCount, 16);
 			catc_set_reg(catc, RxBufCount, 16);
@@ -953,7 +954,8 @@ static int __init catc_init(void)
 {
 {
 	int result = usb_register(&catc_driver);
 	int result = usb_register(&catc_driver);
 	if (result == 0)
 	if (result == 0)
-		info(DRIVER_VERSION " " DRIVER_DESC);
+		printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+		       DRIVER_DESC "\n");
 	return result;
 	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)))
 	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:
 skip:
 		kaweth->stats.tx_errors++;
 		kaweth->stats.tx_errors++;
 
 
@@ -924,7 +924,7 @@ static void kaweth_tx_timeout(struct net_device *net)
 {
 {
 	struct kaweth_device *kaweth = netdev_priv(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++;
 	kaweth->stats.tx_errors++;
 	net->trans_start = jiffies;
 	net->trans_start = jiffies;
 
 
@@ -1016,10 +1016,10 @@ static int kaweth_probe(
 	 */
 	 */
 
 
 	if (le16_to_cpu(dev->descriptor.bcdDevice) >> 8) {
 	if (le16_to_cpu(dev->descriptor.bcdDevice) >> 8) {
-		info("Firmware present in device.");
+		dev_info(&intf->dev, "Firmware present in device.\n");
 	} else {
 	} else {
 		/* Download the firmware */
 		/* Download the firmware */
-		info("Downloading firmware...");
+		dev_info(&intf->dev, "Downloading firmware...\n");
 		kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL);
 		kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL);
 		if ((result = kaweth_download_firmware(kaweth,
 		if ((result = kaweth_download_firmware(kaweth,
 						      "kaweth/new_code.bin",
 						      "kaweth/new_code.bin",
@@ -1061,7 +1061,7 @@ static int kaweth_probe(
 		}
 		}
 
 
 		/* Device will now disappear for a moment...  */
 		/* 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:
 err_fw:
 		free_page((unsigned long)kaweth->firmware_buf);
 		free_page((unsigned long)kaweth->firmware_buf);
 		free_netdev(netdev);
 		free_netdev(netdev);
@@ -1075,10 +1075,10 @@ err_fw:
 		goto err_free_netdev;
 		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[0],
 		 (int)kaweth->configuration.hw_addr[1],
 		 (int)kaweth->configuration.hw_addr[1],
 		 (int)kaweth->configuration.hw_addr[2],
 		 (int)kaweth->configuration.hw_addr[2],
@@ -1174,7 +1174,8 @@ err_fw:
 		goto err_intfdata;
 		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.");
 	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 kaweth_device *kaweth = usb_get_intfdata(intf);
 	struct net_device *netdev;
 	struct net_device *netdev;
 
 
-	info("Unregistering");
+	dev_info(&intf->dev, "Unregistering\n");
 
 
 	usb_set_intfdata(intf, NULL);
 	usb_set_intfdata(intf, NULL);
 	if (!kaweth) {
 	if (!kaweth) {
-		warn("unregistering non-existant device");
+		dev_warn(&intf->dev, "unregistering non-existant device\n");
 		return;
 		return;
 	}
 	}
 	netdev = kaweth->net;
 	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)) {
 	if (!wait_event_timeout(awd.wqh, awd.done, timeout)) {
                 // 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
                 usb_kill_urb(urb);  // remove urb safely
                 status = -ETIMEDOUT;
                 status = -ETIMEDOUT;
         }
         }

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

@@ -221,7 +221,7 @@ static void ctrl_callback(struct urb *urb)
 	case -ENOENT:
 	case -ENOENT:
 		break;
 		break;
 	default:
 	default:
-		warn("ctrl urb status %d", urb->status);
+		dev_warn(&urb->dev->dev, "ctrl urb status %d\n", urb->status);
 	}
 	}
 	dev = urb->context;
 	dev = urb->context;
 	clear_bit(RX_REG_SET, &dev->flags);
 	clear_bit(RX_REG_SET, &dev->flags);
@@ -441,10 +441,10 @@ static void read_bulk_callback(struct urb *urb)
 	case -ENOENT:
 	case -ENOENT:
 		return;	/* the urb is in unlink state */
 		return;	/* the urb is in unlink state */
 	case -ETIME:
 	case -ETIME:
-		warn("may be reset is needed?..");
+		dev_warn(&urb->dev->dev, "may be reset is needed?..\n");
 		goto goon;
 		goto goon;
 	default:
 	default:
-		warn("Rx status %d", urb->status);
+		dev_warn(&urb->dev->dev, "Rx status %d\n", urb->status);
 		goto goon;
 		goto goon;
 	}
 	}
 
 
@@ -538,7 +538,8 @@ static void write_bulk_callback(struct urb *urb)
 	if (!netif_device_present(dev->netdev))
 	if (!netif_device_present(dev->netdev))
 		return;
 		return;
 	if (urb->status)
 	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;
 	dev->netdev->trans_start = jiffies;
 	netif_wake_queue(dev->netdev);
 	netif_wake_queue(dev->netdev);
 }
 }
@@ -561,7 +562,8 @@ static void intr_callback(struct urb *urb)
 		return;
 		return;
 	/* -EPIPE:  should clear the halt */
 	/* -EPIPE:  should clear the halt */
 	default:
 	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;
 		goto resubmit;
 	}
 	}
 
 
@@ -665,7 +667,7 @@ static int enable_net_traffic(rtl8150_t * dev)
 	u8 cr, tcr, rcr, msr;
 	u8 cr, tcr, rcr, msr;
 
 
 	if (!rtl8150_reset(dev)) {
 	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 bit7=1 attach Rx info at the end;  =0 HW CRC (which is broken) */
 	rcr = 0x9e;
 	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)
 static void rtl8150_tx_timeout(struct net_device *netdev)
 {
 {
 	rtl8150_t *dev = netdev_priv(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);
 	usb_unlink_urb(dev->tx_urb);
 	dev->stats.tx_errors++;
 	dev->stats.tx_errors++;
 }
 }
@@ -710,12 +712,12 @@ static void rtl8150_set_multicast(struct net_device *netdev)
 	netif_stop_queue(netdev);
 	netif_stop_queue(netdev);
 	if (netdev->flags & IFF_PROMISC) {
 	if (netdev->flags & IFF_PROMISC) {
 		dev->rx_creg |= cpu_to_le16(0x0001);
 		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 ||
 	} else if (netdev->mc_count ||
 		   (netdev->flags & IFF_ALLMULTI)) {
 		   (netdev->flags & IFF_ALLMULTI)) {
 		dev->rx_creg &= cpu_to_le16(0xfffe);
 		dev->rx_creg &= cpu_to_le16(0xfffe);
 		dev->rx_creg |= cpu_to_le16(0x0002);
 		dev->rx_creg |= cpu_to_le16(0x0002);
-		info("%s: allmulti set", netdev->name);
+		dev_info(&netdev->dev, "%s: allmulti set\n", netdev->name);
 	} else {
 	} else {
 		/* ~RX_MULTICAST, ~RX_PROMISCUOUS */
 		/* ~RX_MULTICAST, ~RX_PROMISCUOUS */
 		dev->rx_creg &= cpu_to_le16(0x00fc);
 		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)
 		if (res == -ENODEV)
 			netif_device_detach(dev->netdev);
 			netif_device_detach(dev->netdev);
 		else {
 		else {
-			warn("failed tx_urb %d\n", res);
+			dev_warn(&netdev->dev, "failed tx_urb %d\n", res);
 			dev->stats.tx_errors++;
 			dev->stats.tx_errors++;
 			netif_start_queue(netdev);
 			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 = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) {
 		if (res == -ENODEV)
 		if (res == -ENODEV)
 			netif_device_detach(dev->netdev);
 			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;
 		return res;
 	}
 	}
 	usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3),
 	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 = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) {
 		if (res == -ENODEV)
 		if (res == -ENODEV)
 			netif_device_detach(dev->netdev);
 			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);
 		usb_kill_urb(dev->rx_urb);
 		return res;
 		return res;
 	}
 	}
@@ -947,7 +949,7 @@ static int rtl8150_probe(struct usb_interface *intf,
 		goto out2;
 		goto out2;
 	}
 	}
 
 
-	info("%s: rtl8150 is detected", netdev->name);
+	dev_info(&intf->dev, "%s: rtl8150 is detected\n", netdev->name);
 
 
 	return 0;
 	return 0;
 
 
@@ -984,7 +986,8 @@ static void rtl8150_disconnect(struct usb_interface *intf)
 
 
 static int __init usb_rtl8150_init(void)
 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);
 	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);
 				__func__, sarb->len, vcc);
 		/* discard cells already received */
 		/* discard cells already received */
 		skb_trim(sarb, 0);
 		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);
 	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 char *cell_buf = instance->cell_buf;
 		unsigned int space_left = stride - buf_usage;
 		unsigned int space_left = stride - buf_usage;
 
 
-		UDSL_ASSERT(buf_usage <= stride);
+		UDSL_ASSERT(instance, buf_usage <= stride);
 
 
 		if (avail_data >= space_left) {
 		if (avail_data >= space_left) {
 			/* add new data and process cell */
 			/* 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;
 	unsigned int stride = instance->tx_channel.stride;
 
 
 	vdbg("%s: skb->len=%d, avail_space=%u", __func__, skb->len, avail_space);
 	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;
 	for (bytes_written = 0; bytes_written < avail_space && ctrl->len;
 	     bytes_written += stride, target += stride) {
 	     bytes_written += stride, target += stride) {
@@ -547,7 +547,7 @@ static void usbatm_rx_process(unsigned long data)
 				if (!urb->iso_frame_desc[i].status) {
 				if (!urb->iso_frame_desc[i].status) {
 					unsigned int actual_length = urb->iso_frame_desc[i].actual_length;
 					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)
 					if (!merge_length)
 						merge_start = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
 						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;
 		struct urb *urb;
 		unsigned int iso_packets = usb_pipeisoc(channel->endpoint) ? channel->buf_size / channel->packet_size : 0;
 		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);
 		urb = usb_alloc_urb(iso_packets, GFP_KERNEL);
 		if (!urb) {
 		if (!urb) {

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

@@ -40,9 +40,15 @@
 */
 */
 
 
 #ifdef DEBUG
 #ifdef DEBUG
-#define UDSL_ASSERT(x)	BUG_ON(!(x))
+#define UDSL_ASSERT(instance, x)	BUG_ON(!(x))
 #else
 #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
 #endif
 
 
 #define usb_err(instance, format, arg...)	\
 #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_product ||
 	    num_vendor != num_rx_endpoint ||
 	    num_vendor != num_rx_endpoint ||
 	    num_vendor != num_tx_endpoint) {
 	    num_vendor != num_tx_endpoint) {
-		warn("malformed module parameters");
+		printk(KERN_WARNING "xusbatm: malformed module parameters\n");
 		return -EINVAL;
 		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
 	  To compile this driver as a module, choose M here: the
 	  module will be called cdc-wdm.
 	  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_ACM)		+= cdc-acm.o
 obj-$(CONFIG_USB_PRINTER)	+= usblp.o
 obj-$(CONFIG_USB_PRINTER)	+= usblp.o
 obj-$(CONFIG_USB_WDM)		+= cdc-wdm.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);
 	usb_mark_last_busy(acm->dev);
 	retval = usb_submit_urb (urb, GFP_ATOMIC);
 	retval = usb_submit_urb (urb, GFP_ATOMIC);
 	if (retval)
 	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 */
 /* 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);
 	rv = usb_autopm_get_interface(acm->control);
 	if (rv < 0) {
 	if (rv < 0) {
-		err("Autopm failure in %s", __func__);
+		dev_err(&acm->dev->dev, "Autopm failure in %s\n", __func__);
 		return;
 		return;
 	}
 	}
 	if (acm->delayed_wb) {
 	if (acm->delayed_wb) {
@@ -924,7 +924,7 @@ static int acm_probe (struct usb_interface *intf,
 	
 	
 	/* normal probing*/
 	/* normal probing*/
 	if (!buffer) {
 	if (!buffer) {
-		err("Weird descriptor references\n");
+		dev_err(&intf->dev, "Weird descriptor references\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -934,21 +934,24 @@ static int acm_probe (struct usb_interface *intf,
 			buflen = intf->cur_altsetting->endpoint->extralen;
 			buflen = intf->cur_altsetting->endpoint->extralen;
 			buffer = intf->cur_altsetting->endpoint->extra;
 			buffer = intf->cur_altsetting->endpoint->extra;
 		} else {
 		} else {
-			err("Zero length descriptor references\n");
+			dev_err(&intf->dev,
+				"Zero length descriptor references\n");
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 	}
 	}
 
 
 	while (buflen > 0) {
 	while (buflen > 0) {
 		if (buffer [1] != USB_DT_CS_INTERFACE) {
 		if (buffer [1] != USB_DT_CS_INTERFACE) {
-			err("skipping garbage\n");
+			dev_err(&intf->dev, "skipping garbage\n");
 			goto next_desc;
 			goto next_desc;
 		}
 		}
 
 
 		switch (buffer [2]) {
 		switch (buffer [2]) {
 			case USB_CDC_UNION_TYPE: /* we've found it */
 			case USB_CDC_UNION_TYPE: /* we've found it */
 				if (union_header) {
 				if (union_header) {
-					err("More than one union descriptor, skipping ...");
+					dev_err(&intf->dev, "More than one "
+						"union descriptor, "
+						"skipping ...\n");
 					goto next_desc;
 					goto next_desc;
 				}
 				}
 				union_header = (struct usb_cdc_union_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_management_function = buffer[3];
 				call_interface_num = buffer[4];
 				call_interface_num = buffer[4];
 				if ((call_management_function & 3) != 3)
 				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;
 				break;
 			default:
 			default:
 				/* there are LOTS more CDC descriptors that
 				/* 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++);
 	for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
 
 
 	if (minor == ACM_TTY_MINORS) {
 	if (minor == ACM_TTY_MINORS) {
-		err("no more free acm devices");
+		dev_err(&intf->dev, "no more free acm devices\n");
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
@@ -1454,7 +1459,8 @@ static int __init acm_init(void)
 		return retval;
 		return retval;
 	}
 	}
 
 
-	info(DRIVER_VERSION ":" DRIVER_DESC);
+	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+	       DRIVER_DESC "\n");
 
 
 	return 0;
 	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");
 				"nonzero urb status received: -ESHUTDOWN");
 			break;
 			break;
 		case -EPIPE:
 		case -EPIPE:
-			err("nonzero urb status received: -EPIPE");
+			dev_err(&desc->intf->dev,
+				"nonzero urb status received: -EPIPE\n");
 			break;
 			break;
 		default:
 		default:
-			err("Unexpected error %d", status);
+			dev_err(&desc->intf->dev,
+				"Unexpected error %d\n", status);
 			break;
 			break;
 		}
 		}
 	}
 	}
@@ -170,16 +172,18 @@ static void wdm_int_callback(struct urb *urb)
 			return; /* unplug */
 			return; /* unplug */
 		case -EPIPE:
 		case -EPIPE:
 			set_bit(WDM_INT_STALL, &desc->flags);
 			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 */
 			goto sw; /* halt is cleared in work */
 		default:
 		default:
-			err("nonzero urb status received: %d", status);
+			dev_err(&desc->intf->dev,
+				"nonzero urb status received: %d\n", status);
 			break;
 			break;
 		}
 		}
 	}
 	}
 
 
 	if (urb->actual_length < sizeof(struct usb_cdc_notification)) {
 	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;
 		goto exit;
 	}
 	}
 
 
@@ -198,7 +202,8 @@ static void wdm_int_callback(struct urb *urb)
 		goto exit;
 		goto exit;
 	default:
 	default:
 		clear_bit(WDM_POLL_RUNNING, &desc->flags);
 		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);
 			dr->bNotificationType, dr->wIndex, dr->wLength);
 		goto exit;
 		goto exit;
 	}
 	}
@@ -236,14 +241,16 @@ static void wdm_int_callback(struct urb *urb)
 sw:
 sw:
 			rv = schedule_work(&desc->rxwork);
 			rv = schedule_work(&desc->rxwork);
 			if (rv)
 			if (rv)
-				err("Cannot schedule work");
+				dev_err(&desc->intf->dev,
+					"Cannot schedule work\n");
 		}
 		}
 	}
 	}
 exit:
 exit:
 	rv = usb_submit_urb(urb, GFP_ATOMIC);
 	rv = usb_submit_urb(urb, GFP_ATOMIC);
 	if (rv)
 	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) {
 	if (rv < 0) {
 		kfree(buf);
 		kfree(buf);
 		clear_bit(WDM_IN_USE, &desc->flags);
 		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 {
 	} else {
 		dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d",
 		dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d",
 			req->wIndex);
 			req->wIndex);
@@ -401,7 +408,8 @@ retry:
 			int t = desc->rerr;
 			int t = desc->rerr;
 			desc->rerr = 0;
 			desc->rerr = 0;
 			spin_unlock_irq(&desc->iuspin);
 			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;
 			rv = -EIO;
 			goto err;
 			goto err;
 		}
 		}
@@ -440,7 +448,7 @@ retry:
 err:
 err:
 	mutex_unlock(&desc->rlock);
 	mutex_unlock(&desc->rlock);
 	if (rv < 0)
 	if (rv < 0)
-		err("wdm_read: exit error");
+		dev_err(&desc->intf->dev, "wdm_read: exit error\n");
 	return rv;
 	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));
 	wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags));
 	if (desc->werr < 0)
 	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;
 	return desc->werr;
 }
 }
@@ -502,7 +511,7 @@ static int wdm_open(struct inode *inode, struct file *file)
 
 
 	rv = usb_autopm_get_interface(desc->intf);
 	rv = usb_autopm_get_interface(desc->intf);
 	if (rv < 0) {
 	if (rv < 0) {
-		err("Error autopm - %d", rv);
+		dev_err(&desc->intf->dev, "Error autopm - %d\n", rv);
 		goto out;
 		goto out;
 	}
 	}
 	intf->needs_remote_wakeup = 1;
 	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);
 		rv = usb_submit_urb(desc->validity, GFP_KERNEL);
 		if (rv < 0) {
 		if (rv < 0) {
 			desc->count--;
 			desc->count--;
-			err("Error submitting int urb - %d", rv);
+			dev_err(&desc->intf->dev,
+				"Error submitting int urb - %d\n", rv);
 		}
 		}
 	} else {
 	} else {
 		rv = 0;
 		rv = 0;
@@ -600,7 +610,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
 
 	while (buflen > 0) {
 	while (buflen > 0) {
 		if (buffer [1] != USB_DT_CS_INTERFACE) {
 		if (buffer [1] != USB_DT_CS_INTERFACE) {
-			err("skipping garbage");
+			dev_err(&intf->dev, "skipping garbage\n");
 			goto next_desc;
 			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);
 				"Finding maximum buffer length: %d", maxcom);
 			break;
 			break;
 		default:
 		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]);
 				buffer[2], buffer[0]);
 			break;
 			break;
 		}
 		}
@@ -772,7 +783,8 @@ static int recover_from_urb_loss(struct wdm_device *desc)
 	if (desc->count) {
 	if (desc->count) {
 		rv = usb_submit_urb(desc->validity, GFP_NOIO);
 		rv = usb_submit_urb(desc->validity, GFP_NOIO);
 		if (rv < 0)
 		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;
 	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,
 				err = usblp_hp_channel_change_request(usblp,
 					arg, &newChannel);
 					arg, &newChannel);
 				if (err < 0) {
 				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);
 						usblp->minor, err);
 					retval = -EIO;
 					retval = -EIO;
 					goto done;
 					goto done;
@@ -1076,15 +1077,16 @@ static int usblp_probe(struct usb_interface *intf,
 		       const struct usb_device_id *id)
 		       const struct usb_device_id *id)
 {
 {
 	struct usb_device *dev = interface_to_usbdev (intf);
 	struct usb_device *dev = interface_to_usbdev (intf);
-	struct usblp *usblp = NULL;
+	struct usblp *usblp;
 	int protocol;
 	int protocol;
 	int retval;
 	int retval;
 
 
 	/* Malloc and start initializing usblp structure so we can use it
 	/* Malloc and start initializing usblp structure so we can use it
 	 * directly. */
 	 * directly. */
-	if (!(usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL))) {
+	usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL);
+	if (!usblp) {
 		retval = -ENOMEM;
 		retval = -ENOMEM;
-		goto abort;
+		goto abort_ret;
 	}
 	}
 	usblp->dev = dev;
 	usblp->dev = dev;
 	mutex_init(&usblp->wmut);
 	mutex_init(&usblp->wmut);
@@ -1179,12 +1181,11 @@ abort_intfdata:
 	usb_set_intfdata (intf, NULL);
 	usb_set_intfdata (intf, NULL);
 	device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
 	device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
 abort:
 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;
 	return retval;
 }
 }
 
 
@@ -1345,7 +1346,7 @@ static void usblp_disconnect(struct usb_interface *intf)
 	usb_deregister_dev(intf, &usblp_class);
 	usb_deregister_dev(intf, &usblp_class);
 
 
 	if (!usblp || !usblp->dev) {
 	if (!usblp || !usblp->dev) {
-		err("bogus disconnect");
+		dev_err(&intf->dev, "bogus disconnect\n");
 		BUG ();
 		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
 	  If you say Y here, then Linux will refuse to enumerate
 	  external hubs.  OTG hosts are allowed to reduce hardware
 	  external hubs.  OTG hosts are allowed to reduce hardware
 	  and software costs by not supporting external hubs.  So
 	  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)))
 	if (likely(ifnum < 8*sizeof(ps->ifclaimed)))
 		clear_bit(ifnum, &ps->ifclaimed);
 		clear_bit(ifnum, &ps->ifclaimed);
 	else
 	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);
 	usb_set_intfdata(intf, NULL);
 
 
@@ -624,6 +625,8 @@ static int usbdev_open(struct inode *inode, struct file *file)
 	smp_wmb();
 	smp_wmb();
 	list_add_tail(&ps->list, &dev->filelist);
 	list_add_tail(&ps->list, &dev->filelist);
 	file->private_data = ps;
 	file->private_data = ps;
+	snoop(&dev->dev, "opened by process %d: %s\n", task_pid_nr(current),
+			current->comm);
  out:
  out:
 	if (ret) {
 	if (ret) {
 		kfree(ps);
 		kfree(ps);
@@ -1774,19 +1777,20 @@ int __init usb_devio_init(void)
 	retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX,
 	retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX,
 					"usb_device");
 					"usb_device");
 	if (retval) {
 	if (retval) {
-		err("unable to register minors for usb_device");
+		printk(KERN_ERR "Unable to register minors for usb_device\n");
 		goto out;
 		goto out;
 	}
 	}
 	cdev_init(&usb_device_cdev, &usbdev_file_operations);
 	cdev_init(&usb_device_cdev, &usbdev_file_operations);
 	retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);
 	retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);
 	if (retval) {
 	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;
 		goto error_cdev;
 	}
 	}
 #ifdef CONFIG_USB_DEVICE_CLASS
 #ifdef CONFIG_USB_DEVICE_CLASS
 	usb_classdev_class = class_create(THIS_MODULE, "usb_device");
 	usb_classdev_class = class_create(THIS_MODULE, "usb_device");
 	if (IS_ERR(usb_classdev_class)) {
 	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);
 		retval = PTR_ERR(usb_classdev_class);
 		cdev_del(&usb_device_cdev);
 		cdev_del(&usb_device_cdev);
 		usb_classdev_class = NULL;
 		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;
 				struct usb_driver *driver;
 
 
 				driver = to_usb_driver(intf->dev.driver);
 				driver = to_usb_driver(intf->dev.driver);
-				if (!driver->reset_resume)
+				if (!driver->reset_resume ||
+				    intf->needs_remote_wakeup)
 					return -EOPNOTSUPP;
 					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,
 	error = alloc_chrdev_region(&dev, 0, MAX_ENDPOINT_MINORS,
 				    "usb_endpoint");
 				    "usb_endpoint");
 	if (error) {
 	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;
 		return error;
 	}
 	}
 	usb_endpoint_major = MAJOR(dev);
 	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");
 	usb_class->class = class_create(THIS_MODULE, "usb");
 	if (IS_ERR(usb_class->class)) {
 	if (IS_ERR(usb_class->class)) {
 		result = 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);
 		kfree(usb_class);
 		usb_class = NULL;
 		usb_class = NULL;
 	}
 	}
@@ -115,7 +115,8 @@ int usb_major_init(void)
 
 
 	error = register_chrdev(USB_MAJOR, "usb", &usb_fops);
 	error = register_chrdev(USB_MAJOR, "usb", &usb_fops);
 	if (error)
 	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;
 	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 */
 /* host controllers we manage */
 LIST_HEAD (usb_bus_list);
 LIST_HEAD (usb_bus_list);
 EXPORT_SYMBOL_GPL (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;
 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__ */
 #endif /* __KERNEL__ */

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

@@ -77,6 +77,7 @@ struct usb_hub {
 	unsigned		has_indicators:1;
 	unsigned		has_indicators:1;
 	u8			indicator[USB_MAXCHILDREN];
 	u8			indicator[USB_MAXCHILDREN];
 	struct delayed_work	leds;
 	struct delayed_work	leds;
+	struct delayed_work	init_work;
 };
 };
 
 
 
 
@@ -99,6 +100,15 @@ static int blinkenlights = 0;
 module_param (blinkenlights, bool, S_IRUGO);
 module_param (blinkenlights, bool, S_IRUGO);
 MODULE_PARM_DESC (blinkenlights, "true to cycle leds on hubs");
 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
  * 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
  * 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);
 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;
 	int port1;
 	unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2;
 	unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2;
+	unsigned delay;
 	u16 wHubCharacteristics =
 	u16 wHubCharacteristics =
 			le16_to_cpu(hub->descriptor->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);
 		set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER);
 
 
 	/* Wait at least 100 msec for power to become stable */
 	/* 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,
 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 {
 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)
 static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 {
 {
 	struct usb_device *hdev = hub->hdev;
 	struct usb_device *hdev = hub->hdev;
 	int port1;
 	int port1;
 	int status;
 	int status;
 	bool need_debounce_delay = false;
 	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.
 	/* After a resume, port power should still be on.
 	 * For any other type of activation, turn it 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
 	/* Check each port and set hub->change_bits to let khubd know
 	 * which ports need attention.
 	 * 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
 	 * If any port-status changes do occur during this delay, khubd
 	 * will see them later and handle them normally.
 	 * 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;
 	hub->quiescing = 0;
 
 
 	status = usb_submit_urb(hub->urb, GFP_NOIO);
 	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);
 	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 {
 enum hub_quiescing_type {
 	HUB_DISCONNECT, HUB_PRE_RESET, HUB_SUSPEND
 	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;
 	struct usb_device *hdev = hub->hdev;
 	int i;
 	int i;
 
 
+	cancel_delayed_work_sync(&hub->init_work);
+
 	/* khubd and related activity won't re-trigger */
 	/* khubd and related activity won't re-trigger */
 	hub->quiescing = 1;
 	hub->quiescing = 1;
 
 
@@ -1099,6 +1178,7 @@ descriptor_error:
 	hub->intfdev = &intf->dev;
 	hub->intfdev = &intf->dev;
 	hub->hdev = hdev;
 	hub->hdev = hdev;
 	INIT_DELAYED_WORK(&hub->leds, led_work);
 	INIT_DELAYED_WORK(&hub->leds, led_work);
+	INIT_DELAYED_WORK(&hub->init_work, NULL);
 	usb_get_intf(intf);
 	usb_get_intf(intf);
 
 
 	usb_set_intfdata (intf, hub);
 	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_REQ_GET_DESCRIPTOR, USB_DIR_IN,
 					USB_DT_DEVICE << 8, 0,
 					USB_DT_DEVICE << 8, 0,
 					buf, GET_DESCRIPTOR_BUFSIZE,
 					buf, GET_DESCRIPTOR_BUFSIZE,
-					USB_CTRL_GET_TIMEOUT);
+					initial_descriptor_timeout);
 				switch (buf->bMaxPacketSize0) {
 				switch (buf->bMaxPacketSize0) {
 				case 8: case 16: case 32: case 64: case 255:
 				case 8: case 16: case 32: case 64: case 255:
 					if (buf->bDescriptorType ==
 					if (buf->bDescriptorType ==
@@ -3035,7 +3115,7 @@ static void hub_events(void)
 					i);
 					i);
 				clear_port_feature(hdev, i,
 				clear_port_feature(hdev, i,
 					USB_PORT_FEAT_C_OVER_CURRENT);
 					USB_PORT_FEAT_C_OVER_CURRENT);
-				hub_power_on(hub);
+				hub_power_on(hub, true);
 			}
 			}
 
 
 			if (portchange & USB_PORT_STAT_C_RESET) {
 			if (portchange & USB_PORT_STAT_C_RESET) {
@@ -3070,7 +3150,7 @@ static void hub_events(void)
 				dev_dbg (hub_dev, "overcurrent change\n");
 				dev_dbg (hub_dev, "overcurrent change\n");
 				msleep(500);	/* Cool down */
 				msleep(500);	/* Cool down */
 				clear_hub_feature(hdev, C_HUB_OVER_CURRENT);
 				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;
 			listmode = option & S_IRWXUGO;
 			break;
 			break;
 		default:
 		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;
 			return -EINVAL;
 		}
 		}
 	}
 	}
@@ -240,7 +240,9 @@ static void update_sb(struct super_block *sb)
 				update_special(bus);
 				update_special(bus);
 				break;
 				break;
 			default:
 			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;
 				break;
 			}
 			}
 		}
 		}
@@ -259,7 +261,7 @@ static int remount(struct super_block *sb, int *flags, char *data)
 		return 0;
 		return 0;
 
 
 	if (parse_options(sb, data)) {
 	if (parse_options(sb, data)) {
-		warn("usbfs: mount parameter error:");
+		printk(KERN_WARNING "usbfs: mount parameter error.\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
@@ -599,7 +601,7 @@ static int create_special_files (void)
 	/* create the devices special file */
 	/* create the devices special file */
 	retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count);
 	retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count);
 	if (retval) {
 	if (retval) {
-		err ("Unable to get usbfs mount");
+		printk(KERN_ERR "Unable to get usbfs mount\n");
 		goto exit;
 		goto exit;
 	}
 	}
 
 
@@ -611,7 +613,7 @@ static int create_special_files (void)
 					       NULL, &usbfs_devices_fops,
 					       NULL, &usbfs_devices_fops,
 					       listuid, listgid);
 					       listuid, listgid);
 	if (devices_usbfs_dentry == NULL) {
 	if (devices_usbfs_dentry == NULL) {
-		err ("Unable to create devices usbfs file");
+		printk(KERN_ERR "Unable to create devices usbfs file\n");
 		retval = -ENODEV;
 		retval = -ENODEV;
 		goto error_clean_mounts;
 		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->usbfs_dentry = fs_create_file (name, busmode | S_IFDIR, parent,
 					    bus, NULL, busuid, busgid);
 					    bus, NULL, busuid, busgid);
 	if (bus->usbfs_dentry == NULL) {
 	if (bus->usbfs_dentry == NULL) {
-		err ("error creating usbfs bus entry");
+		printk(KERN_ERR "Error creating usbfs bus entry\n");
 		return;
 		return;
 	}
 	}
 }
 }
@@ -694,7 +696,7 @@ static void usbfs_add_device(struct usb_device *dev)
 					    &usbdev_file_operations,
 					    &usbdev_file_operations,
 					    devuid, devgid);
 					    devuid, devgid);
 	if (dev->usbfs_dentry == NULL) {
 	if (dev->usbfs_dentry == NULL) {
-		err ("error creating usbfs device entry");
+		printk(KERN_ERR "Error creating usbfs device entry\n");
 		return;
 		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);
 	alt = usb_altnum_to_altsetting(iface, alternate);
 	if (!alt) {
 	if (!alt) {
-		warn("selecting invalid altsetting %d", alternate);
+		dev_warn(&dev->dev, "selecting invalid altsetting %d",
+			 alternate);
 		return -EINVAL;
 		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 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[] = {
 static struct attribute *intf_attrs[] = {
 	&dev_attr_bInterfaceNumber.attr,
 	&dev_attr_bInterfaceNumber.attr,
 	&dev_attr_bAlternateSetting.attr,
 	&dev_attr_bAlternateSetting.attr,
@@ -751,6 +774,7 @@ static struct attribute *intf_attrs[] = {
 	&dev_attr_bInterfaceSubClass.attr,
 	&dev_attr_bInterfaceSubClass.attr,
 	&dev_attr_bInterfaceProtocol.attr,
 	&dev_attr_bInterfaceProtocol.attr,
 	&dev_attr_modalias.attr,
 	&dev_attr_modalias.attr,
+	&dev_attr_supports_autosuspend.attr,
 	NULL,
 	NULL,
 };
 };
 static struct attribute_group intf_attr_grp = {
 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)
 #define to_urb(d) container_of(d, struct urb, kref)
 
 
+static DEFINE_SPINLOCK(usb_reject_lock);
+
 static void urb_destroy(struct kref *kref)
 static void urb_destroy(struct kref *kref)
 {
 {
 	struct urb *urb = to_urb(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),
 		iso_packets * sizeof(struct usb_iso_packet_descriptor),
 		mem_flags);
 		mem_flags);
 	if (!urb) {
 	if (!urb) {
-		err("alloc_urb: kmalloc failed");
+		printk(KERN_ERR "alloc_urb: kmalloc failed\n");
 		return NULL;
 		return NULL;
 	}
 	}
 	usb_init_urb(urb);
 	usb_init_urb(urb);
@@ -127,6 +129,13 @@ void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor)
 	usb_get_urb(urb);
 	usb_get_urb(urb);
 	list_add_tail(&urb->anchor_list, &anchor->urb_list);
 	list_add_tail(&urb->anchor_list, &anchor->urb_list);
 	urb->anchor = anchor;
 	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);
 	spin_unlock_irqrestore(&anchor->lock, flags);
 }
 }
 EXPORT_SYMBOL_GPL(usb_anchor_urb);
 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 */
 	/* fail if submitter gave bogus flags */
 	if (urb->transfer_flags != orig_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);
 			orig_flags, urb->transfer_flags);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
@@ -544,24 +553,69 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb);
  */
  */
 void usb_kill_urb(struct urb *urb)
 void usb_kill_urb(struct urb *urb)
 {
 {
-	static DEFINE_MUTEX(reject_mutex);
-
 	might_sleep();
 	might_sleep();
 	if (!(urb && urb->dev && urb->ep))
 	if (!(urb && urb->dev && urb->ep))
 		return;
 		return;
-	mutex_lock(&reject_mutex);
+	spin_lock_irq(&usb_reject_lock);
 	++urb->reject;
 	++urb->reject;
-	mutex_unlock(&reject_mutex);
+	spin_unlock_irq(&usb_reject_lock);
 
 
 	usb_hcd_unlink_urb(urb, -ENOENT);
 	usb_hcd_unlink_urb(urb, -ENOENT);
 	wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0);
 	wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0);
 
 
-	mutex_lock(&reject_mutex);
+	spin_lock_irq(&usb_reject_lock);
 	--urb->reject;
 	--urb->reject;
-	mutex_unlock(&reject_mutex);
+	spin_unlock_irq(&usb_reject_lock);
 }
 }
 EXPORT_SYMBOL_GPL(usb_kill_urb);
 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
  * usb_kill_anchored_urbs - cancel transfer requests en masse
  * @anchor: anchor the requests are bound to
  * @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);
 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
  * usb_unlink_anchored_urbs - asynchronously cancel transfer requests en masse
  * @anchor: anchor the requests are bound to
  * @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));
 				  msecs_to_jiffies(timeout));
 }
 }
 EXPORT_SYMBOL_GPL(usb_wait_anchor_empty_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
 config USB_GADGET_DEBUG
 	boolean "Debugging messages (DEVELOPMENT)"
 	boolean "Debugging messages (DEVELOPMENT)"
-	depends on USB_GADGET && DEBUG_KERNEL
+	depends on DEBUG_KERNEL
 	help
 	help
 	   Many controller and gadget drivers will print some debugging
 	   Many controller and gadget drivers will print some debugging
 	   messages if you use this option to ask for those messages.
 	   messages if you use this option to ask for those messages.
@@ -59,7 +59,7 @@ config USB_GADGET_DEBUG
 
 
 config USB_GADGET_DEBUG_FILES
 config USB_GADGET_DEBUG_FILES
 	boolean "Debugging information files (DEVELOPMENT)"
 	boolean "Debugging information files (DEVELOPMENT)"
-	depends on USB_GADGET && PROC_FS
+	depends on PROC_FS
 	help
 	help
 	   Some of the drivers in the "gadget" framework can expose
 	   Some of the drivers in the "gadget" framework can expose
 	   debugging information in files such as /proc/driver/udc
 	   debugging information in files such as /proc/driver/udc
@@ -70,7 +70,7 @@ config USB_GADGET_DEBUG_FILES
 
 
 config USB_GADGET_DEBUG_FS
 config USB_GADGET_DEBUG_FS
 	boolean "Debugging information files in debugfs (DEVELOPMENT)"
 	boolean "Debugging information files in debugfs (DEVELOPMENT)"
-	depends on USB_GADGET && DEBUG_FS
+	depends on DEBUG_FS
 	help
 	help
 	   Some of the drivers in the "gadget" framework can expose
 	   Some of the drivers in the "gadget" framework can expose
 	   debugging information in files under /sys/kernel/debug/.
 	   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
 	   Enable these files by choosing "Y" here.  If in doubt, or
 	   to conserve kernel memory, say "N".
 	   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
 config	USB_GADGET_SELECTED
 	boolean
 	boolean
 
 
 #
 #
 # USB Peripheral Controller Support
 # 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
 choice
 	prompt "USB Peripheral Controller"
 	prompt "USB Peripheral Controller"
 	depends on USB_GADGET
 	depends on USB_GADGET
@@ -94,26 +118,27 @@ choice
 	   Many controller drivers are platform-specific; these
 	   Many controller drivers are platform-specific; these
 	   often need board-specific hooks.
 	   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
 	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
 	   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.
 	   gadget drivers to also be dynamically linked.
 
 
-config USB_AMD5536UDC
+config USB_AT91
 	tristate
 	tristate
-	depends on USB_GADGET_AMD5536UDC
+	depends on USB_GADGET_AT91
 	default USB_GADGET
 	default USB_GADGET
-	select USB_GADGET_SELECTED
 
 
 config USB_GADGET_ATMEL_USBA
 config USB_GADGET_ATMEL_USBA
 	boolean "Atmel USBA"
 	boolean "Atmel USBA"
@@ -150,28 +175,50 @@ config USB_FSL_USB2
 	default USB_GADGET
 	default USB_GADGET
 	select USB_GADGET_SELECTED
 	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
 	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
 	   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.
 	   gadget drivers to also be dynamically linked.
 
 
-config USB_NET2280
+config USB_OMAP
 	tristate
 	tristate
-	depends on USB_GADGET_NET2280
+	depends on USB_GADGET_OMAP
 	default USB_GADGET
 	default USB_GADGET
 	select USB_GADGET_SELECTED
 	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
 config USB_GADGET_PXA25X
 	boolean "PXA 25x or IXP 4xx"
 	boolean "PXA 25x or IXP 4xx"
 	depends on (ARCH_PXA && PXA25x) || ARCH_IXP4XX
 	depends on (ARCH_PXA && PXA25x) || ARCH_IXP4XX
@@ -203,34 +250,6 @@ config USB_PXA25X_SMALL
 	default y if USB_ETH
 	default y if USB_ETH
 	default y if USB_G_SERIAL
 	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
 config USB_GADGET_PXA27X
 	boolean "PXA 27x"
 	boolean "PXA 27x"
 	depends on ARCH_PXA && PXA27x
 	depends on ARCH_PXA && PXA27x
@@ -251,40 +270,32 @@ config USB_PXA27X
 	default USB_GADGET
 	default USB_GADGET
 	select USB_GADGET_SELECTED
 	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
 	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
 	tristate
-	depends on USB_GADGET_GOKU
+	depends on USB_GADGET_S3C2410
 	default USB_GADGET
 	default USB_GADGET
 	select USB_GADGET_SELECTED
 	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
 config USB_GADGET_MUSB_HDRC
 	boolean "Inventra HDRC USB Peripheral (TI, ...)"
 	boolean "Inventra HDRC USB Peripheral (TI, ...)"
 	depends on USB_MUSB_HDRC && (USB_MUSB_PERIPHERAL || USB_MUSB_OTG)
 	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
 	  This OTG-capable silicon IP is used in dual designs including
 	  the TI DaVinci, OMAP 243x, OMAP 343x, and TUSB 6010.
 	  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
 	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
 	   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.
 	   gadget drivers to also be dynamically linked.
 
 
-config USB_OMAP
+config USB_M66592
 	tristate
 	tristate
-	depends on USB_GADGET_OMAP
+	depends on USB_GADGET_M66592
 	default USB_GADGET
 	default USB_GADGET
 	select USB_GADGET_SELECTED
 	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
 	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
 	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
 	tristate
-	depends on USB_GADGET_S3C2410
+	depends on USB_GADGET_AMD5536UDC
 	default USB_GADGET
 	default USB_GADGET
 	select USB_GADGET_SELECTED
 	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
 	select USB_GADGET_SELECTED
+
+config USB_GADGET_NET2280
+	boolean "NetChip 228x"
+	depends on PCI
+	select USB_GADGET_DUALSPEED
 	help
 	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
 	   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.
 	   gadget drivers to also be dynamically linked.
 
 
-config USB_AT91
+config USB_NET2280
 	tristate
 	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
 	default USB_GADGET
+	select USB_GADGET_SELECTED
+
+
+#
+# LAST -- dummy/emulated controller
+#
 
 
 config USB_GADGET_DUMMY_HCD
 config USB_GADGET_DUMMY_HCD
 	boolean "Dummy HCD (DEVELOPMENT)"
 	boolean "Dummy HCD (DEVELOPMENT)"
@@ -553,19 +612,23 @@ config USB_FILE_STORAGE_TEST
 	  normal operation.
 	  normal operation.
 
 
 config USB_G_SERIAL
 config USB_G_SERIAL
-	tristate "Serial Gadget (with CDC ACM support)"
+	tristate "Serial Gadget (with CDC ACM and CDC OBEX support)"
 	help
 	help
 	  The Serial Gadget talks to the Linux-USB generic serial driver.
 	  The Serial Gadget talks to the Linux-USB generic serial driver.
 	  This driver supports a CDC-ACM module option, which can be used
 	  This driver supports a CDC-ACM module option, which can be used
 	  to interoperate with MS-Windows hosts or with the Linux-USB
 	  to interoperate with MS-Windows hosts or with the Linux-USB
 	  "cdc-acm" driver.
 	  "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
 	  Say "y" to link the driver statically, or "m" to build a
 	  dynamically linked module called "g_serial".
 	  dynamically linked module called "g_serial".
 
 
 	  For more information, see Documentation/usb/gadget_serial.txt
 	  For more information, see Documentation/usb/gadget_serial.txt
 	  which includes instructions and a "driver info file" needed to
 	  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
 config USB_MIDI_GADGET
 	tristate "MIDI Gadget (EXPERIMENTAL)"
 	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_ATMEL_USBA)	+= atmel_usba_udc.o
 obj-$(CONFIG_USB_FSL_USB2)	+= fsl_usb2_udc.o
 obj-$(CONFIG_USB_FSL_USB2)	+= fsl_usb2_udc.o
 obj-$(CONFIG_USB_M66592)	+= m66592-udc.o
 obj-$(CONFIG_USB_M66592)	+= m66592-udc.o
+obj-$(CONFIG_USB_FSL_QE)	+= fsl_qe_udc.o
 
 
 #
 #
 # USB gadget drivers
 # USB gadget drivers

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

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

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

@@ -127,6 +127,70 @@ done:
 	return value;
 	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
  * usb_interface_id() - allocate an unused interface ID
  * @config: configuration associated with the interface
  * @config: configuration associated with the interface
@@ -181,7 +245,7 @@ static int config_buf(struct usb_configuration *config,
 	c->bConfigurationValue = config->bConfigurationValue;
 	c->bConfigurationValue = config->bConfigurationValue;
 	c->iConfiguration = config->iConfiguration;
 	c->iConfiguration = config->iConfiguration;
 	c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes;
 	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 */
 	/* There may be e.g. OTG descriptors */
 	if (config->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 */
 	/* 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:
 done:
 	usb_gadget_vbus_draw(gadget, power);
 	usb_gadget_vbus_draw(gadget, power);
 	return result;
 	return result;

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

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

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

@@ -242,7 +242,6 @@ static struct usb_configuration rndis_config_driver = {
 	.bConfigurationValue	= 2,
 	.bConfigurationValue	= 2,
 	/* .iConfiguration = DYNAMIC */
 	/* .iConfiguration = DYNAMIC */
 	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
 	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
-	.bMaxPower		= 1,	/* 2 mA, minimal */
 };
 };
 
 
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
@@ -271,7 +270,6 @@ static struct usb_configuration eth_config_driver = {
 	.bConfigurationValue	= 1,
 	.bConfigurationValue	= 1,
 	/* .iConfiguration = DYNAMIC */
 	/* .iConfiguration = DYNAMIC */
 	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
 	.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,
 	.bind		= loopback_bind_config,
 	.bConfigurationValue = 2,
 	.bConfigurationValue = 2,
 	.bmAttributes	= USB_CONFIG_ATT_SELFPOWER,
 	.bmAttributes	= USB_CONFIG_ATT_SELFPOWER,
-	.bMaxPower	= 1,	/* 2 mA, minimal */
 	/* .iConfiguration = DYNAMIC */
 	/* .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,
 	.setup		= sourcesink_setup,
 	.bConfigurationValue = 3,
 	.bConfigurationValue = 3,
 	.bmAttributes	= USB_CONFIG_ATT_SELFPOWER,
 	.bmAttributes	= USB_CONFIG_ATT_SELFPOWER,
-	.bMaxPower	= 1,	/* 2 mA, minimal */
 	/* .iConfiguration = DYNAMIC */
 	/* .iConfiguration = DYNAMIC */
 };
 };
 
 

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

@@ -851,7 +851,7 @@ config_desc = {
 	.bConfigurationValue =	CONFIG_VALUE,
 	.bConfigurationValue =	CONFIG_VALUE,
 	.iConfiguration =	STRING_CONFIG,
 	.iConfiguration =	STRING_CONFIG,
 	.bmAttributes =		USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
 	.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
 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 */
 	/* Verify the length of the command itself */
 	if (cmnd_size != fsg->cmnd_size) {
 	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;
 			cmnd_size = fsg->cmnd_size;
-		else {
+		} else {
 			fsg->phase_error = 1;
 			fsg->phase_error = 1;
 			return -EINVAL;
 			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/ioport.h>
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/init.h>
-#include <linux/timer.h>
 #include <linux/list.h>
 #include <linux/list.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
 #include <linux/proc_fs.h>
@@ -44,11 +41,9 @@
 
 
 #include <asm/byteorder.h>
 #include <asm/byteorder.h>
 #include <asm/io.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/system.h>
 #include <asm/unaligned.h>
 #include <asm/unaligned.h>
 #include <asm/dma.h>
 #include <asm/dma.h>
-#include <asm/cacheflush.h>
 
 
 #include "fsl_usb2_udc.h"
 #include "fsl_usb2_udc.h"
 
 
@@ -61,8 +56,8 @@
 static const char driver_name[] = "fsl-usb2-udc";
 static const char driver_name[] = "fsl-usb2-udc";
 static const char driver_desc[] = DRIVER_DESC;
 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()  */
 /* it is initialized in probe()  */
 static struct fsl_udc *udc_controller = NULL;
 static struct fsl_udc *udc_controller = NULL;
@@ -76,16 +71,14 @@ fsl_ep0_desc = {
 	.wMaxPacketSize =	USB_MAX_CTRL_PAYLOAD,
 	.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);
 static void fsl_ep_fifo_flush(struct usb_ep *_ep);
 
 
 #ifdef CONFIG_PPC32
 #ifdef CONFIG_PPC32
 #define fsl_readl(addr)		in_le32(addr)
 #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
 #else
 #define fsl_readl(addr)		readl(addr)
 #define fsl_readl(addr)		readl(addr)
-#define fsl_writel(addr, val32) writel(addr, val32)
+#define fsl_writel(val32, addr) writel(val32, addr)
 #endif
 #endif
 
 
 /********************************************************************
 /********************************************************************
@@ -185,10 +178,6 @@ static int dr_controller_setup(struct fsl_udc *udc)
 	unsigned long timeout;
 	unsigned long timeout;
 #define FSL_UDC_RESET_TIMEOUT 1000
 #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 */
 	/* Stop and reset the usb controller */
 	tmp = fsl_readl(&dr_regs->usbcmd);
 	tmp = fsl_readl(&dr_regs->usbcmd);
 	tmp &= ~USB_CMD_RUN_STOP;
 	tmp &= ~USB_CMD_RUN_STOP;
@@ -202,7 +191,7 @@ static int dr_controller_setup(struct fsl_udc *udc)
 	timeout = jiffies + FSL_UDC_RESET_TIMEOUT;
 	timeout = jiffies + FSL_UDC_RESET_TIMEOUT;
 	while (fsl_readl(&dr_regs->usbcmd) & USB_CMD_CTRL_RESET) {
 	while (fsl_readl(&dr_regs->usbcmd) & USB_CMD_CTRL_RESET) {
 		if (time_after(jiffies, timeout)) {
 		if (time_after(jiffies, timeout)) {
-			ERR("udc reset timeout! \n");
+			ERR("udc reset timeout!\n");
 			return -ETIMEDOUT;
 			return -ETIMEDOUT;
 		}
 		}
 		cpu_relax();
 		cpu_relax();
@@ -315,7 +304,8 @@ static void dr_controller_stop(struct fsl_udc *udc)
 	return;
 	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;
 	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 all pending requests (does flush) */
 	nuke(ep, -ESHUTDOWN);
 	nuke(ep, -ESHUTDOWN);
 
 
-	ep->desc = 0;
+	ep->desc = NULL;
 	ep->stopped = 1;
 	ep->stopped = 1;
 	spin_unlock_irqrestore(&udc->lock, flags);
 	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);
 	int i = ep_index(ep) * 2 + ep_is_in(ep);
 	u32 temp, bitmask, tmp_stat;
 	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));
 			| EP_QUEUE_HEAD_STATUS_HALT));
 	dQH->size_ioc_int_sts &= temp;
 	dQH->size_ioc_int_sts &= temp;
 
 
+	/* Ensure that updates to the QH will occure before priming. */
+	wmb();
+
 	/* Prime endpoint by writing 1 to ENDPTPRIME */
 	/* Prime endpoint by writing 1 to ENDPTPRIME */
 	temp = ep_is_in(ep)
 	temp = ep_is_in(ep)
 		? (1 << (ep_index(ep) + 16))
 		? (1 << (ep_index(ep) + 16))
 		: (1 << (ep_index(ep)));
 		: (1 << (ep_index(ep)));
 	fsl_writel(temp, &dr_regs->endpointprime);
 	fsl_writel(temp, &dr_regs->endpointprime);
 out:
 out:
-	return 0;
+	return;
 }
 }
 
 
 /* Fill in the dTD structure
 /* 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;
 		*is_last = 0;
 
 
 	if ((*is_last) == 0)
 	if ((*is_last) == 0)
-		VDBG("multi-dtd request!\n");
+		VDBG("multi-dtd request!");
 	/* Fill in the transfer size; set active bit */
 	/* Fill in the transfer size; set active bit */
 	swap_temp = ((*length << DTD_LENGTH_BIT_POS) | DTD_STATUS_ACTIVE);
 	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 */
 	/* catch various bogus parameters */
 	if (!_req || !req->req.complete || !req->req.buf
 	if (!_req || !req->req.complete || !req->req.buf
 			|| !list_empty(&req->queue)) {
 			|| !list_empty(&req->queue)) {
-		VDBG("%s, bad params\n", __func__);
+		VDBG("%s, bad params", __func__);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 	if (unlikely(!_ep || !ep->desc)) {
 	if (unlikely(!_ep || !ep->desc)) {
-		VDBG("%s, bad ep\n", __func__);
+		VDBG("%s, bad ep", __func__);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 	if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
 	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);
 	udc = container_of(gadget, struct fsl_udc, gadget);
 	spin_lock_irqsave(&udc->lock, flags);
 	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);
 	udc->vbus_active = (is_active != 0);
 	if (can_pullup(udc))
 	if (can_pullup(udc))
 		fsl_writel((fsl_readl(&dr_regs->usbcmd) | USB_CMD_RUN_STOP),
 		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_req *req = udc->status_req;
 	struct fsl_ep *ep;
 	struct fsl_ep *ep;
-	int status = 0;
 
 
 	if (direction == EP_DIR_IN)
 	if (direction == EP_DIR_IN)
 		udc->ep0_dir = USB_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;
 	req->dtd_count = 0;
 
 
 	if (fsl_req_to_dtd(req) == 0)
 	if (fsl_req_to_dtd(req) == 0)
-		status = fsl_queue_td(ep, req);
+		fsl_queue_td(ep, req);
 	else
 	else
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	if (status)
-		ERR("Can't queue ep0 status request \n");
 	list_add_tail(&req->queue, &ep->queue);
 	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);
 	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 index, u16 length)
 {
 {
 	u16 tmp = 0;		/* Status, cpu endian */
 	u16 tmp = 0;		/* Status, cpu endian */
-
 	struct fsl_req *req;
 	struct fsl_req *req;
 	struct fsl_ep *ep;
 	struct fsl_ep *ep;
-	int status = 0;
 
 
 	ep = &udc->eps[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 */
 	/* prime the data phase */
 	if ((fsl_req_to_dtd(req) == 0))
 	if ((fsl_req_to_dtd(req) == 0))
-		status = fsl_queue_td(ep, req);
+		fsl_queue_td(ep, req);
 	else			/* no mem */
 	else			/* no mem */
 		goto stall;
 		goto stall;
 
 
-	if (status) {
-		ERR("Can't respond to getstatus request \n");
-		goto stall;
-	}
 	list_add_tail(&req->queue, &ep->queue);
 	list_add_tail(&req->queue, &ep->queue);
 	udc->ep0_state = DATA_STATE_XMIT;
 	udc->ep0_state = DATA_STATE_XMIT;
 	return;
 	return;
@@ -1397,7 +1377,7 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0,
 		udc->ep0_state = WAIT_FOR_SETUP;
 		udc->ep0_state = WAIT_FOR_SETUP;
 		break;
 		break;
 	case WAIT_FOR_SETUP:
 	case WAIT_FOR_SETUP:
-		ERR("Unexpect ep0 packets \n");
+		ERR("Unexpect ep0 packets\n");
 		break;
 		break;
 	default:
 	default:
 		ep0stall(udc);
 		ep0stall(udc);
@@ -1476,7 +1456,7 @@ static int process_ep_req(struct fsl_udc *udc, int pipe,
 				status = -EILSEQ;
 				status = -EILSEQ;
 				break;
 				break;
 			} else
 			} else
-				ERR("Unknown error has occured (0x%x)!\r\n",
+				ERR("Unknown error has occured (0x%x)!\n",
 					errors);
 					errors);
 
 
 		} else if (le32_to_cpu(curr_td->size_ioc_sts)
 		} 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 {
 		} else {
 			td_complete++;
 			td_complete++;
-			VDBG("dTD transmitted successful ");
+			VDBG("dTD transmitted successful");
 		}
 		}
 
 
 		if (j != curr_req->dtd_count - 1)
 		if (j != curr_req->dtd_count - 1)
@@ -1568,9 +1548,6 @@ static void port_change_irq(struct fsl_udc *udc)
 {
 {
 	u32 speed;
 	u32 speed;
 
 
-	if (udc->bus_reset)
-		udc->bus_reset = 0;
-
 	/* Bus resetting is finished */
 	/* Bus resetting is finished */
 	if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) {
 	if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) {
 		/* Get the speed */
 		/* Get the speed */
@@ -1678,8 +1655,6 @@ static void reset_irq(struct fsl_udc *udc)
 
 
 	if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) {
 	if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) {
 		VDBG("Bus reset");
 		VDBG("Bus reset");
-		/* Bus is reseting */
-		udc->bus_reset = 1;
 		/* Reset all the queues, include XD, dTD, EP queue
 		/* Reset all the queues, include XD, dTD, EP queue
 		 * head and TR Queue */
 		 * head and TR Queue */
 		reset_queues(udc);
 		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)) {
 	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);
 	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 */
 	/* lock is needed but whether should use this lock or another */
 	spin_lock_irqsave(&udc_controller->lock, flags);
 	spin_lock_irqsave(&udc_controller->lock, flags);
 
 
-	driver->driver.bus = 0;
+	driver->driver.bus = NULL;
 	/* hook up the driver */
 	/* hook up the driver */
 	udc_controller->driver = driver;
 	udc_controller->driver = driver;
 	udc_controller->gadget.dev.driver = &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);
 	retval = driver->bind(&udc_controller->gadget);
 	if (retval) {
 	if (retval) {
 		VDBG("bind to %s --> %d", driver->driver.name, 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;
 		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->usb_state = USB_STATE_ATTACHED;
 	udc_controller->ep0_state = WAIT_FOR_SETUP;
 	udc_controller->ep0_state = WAIT_FOR_SETUP;
 	udc_controller->ep0_dir = 0;
 	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);
 			udc_controller->gadget.name, driver->driver.name);
 
 
 out:
 out:
 	if (retval)
 	if (retval)
-		printk("retval %d \n", retval);
+		printk("gadget driver register failed %d\n", retval);
 	return retval;
 	return retval;
 }
 }
 EXPORT_SYMBOL(usb_gadget_register_driver);
 EXPORT_SYMBOL(usb_gadget_register_driver);
@@ -1842,7 +1817,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	if (udc_controller->transceiver)
 	if (udc_controller->transceiver)
-		(void)otg_set_peripheral(udc_controller->transceiver, 0);
+		otg_set_peripheral(udc_controller->transceiver, NULL);
 
 
 	/* stop DR, disable intr */
 	/* stop DR, disable intr */
 	dr_controller_stop(udc_controller);
 	dr_controller_stop(udc_controller);
@@ -1863,10 +1838,10 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 
 
 	/* unbind gadget and unhook driver. */
 	/* unbind gadget and unhook driver. */
 	driver->unbind(&udc_controller->gadget);
 	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;
 	return 0;
 }
 }
 EXPORT_SYMBOL(usb_gadget_unregister_driver);
 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);
 	tmp_reg = fsl_readl(&dr_regs->usbsts);
 	t = scnprintf(next, size,
 	t = scnprintf(next, size,
 			"USB Status Reg:\n"
 			"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",
 			"USB Error Interrupt: %s\n\n",
 			(tmp_reg & USB_STS_SUSPEND) ? 1 : 0,
 			(tmp_reg & USB_STS_SUSPEND) ? 1 : 0,
 			(tmp_reg & USB_STS_RESET) ? 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);
 	tmp_reg = fsl_readl(&dr_regs->usbintr);
 	t = scnprintf(next, size,
 	t = scnprintf(next, size,
 			"USB Intrrupt Enable Reg:\n"
 			"USB Intrrupt Enable Reg:\n"
-			"Sleep Enable: %d" "SOF Received Enable: %d"
+			"Sleep Enable: %d SOF Received Enable: %d "
 			"Reset Enable: %d\n"
 			"Reset Enable: %d\n"
-			"System Error Enable: %d"
+			"System Error Enable: %d "
 			"Port Change Dectected Enable: %d\n"
 			"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_DEVICE_SUSPEND) ? 1 : 0,
 			(tmp_reg & USB_INTR_SOF_EN) ? 1 : 0,
 			(tmp_reg & USB_INTR_SOF_EN) ? 1 : 0,
 			(tmp_reg & USB_INTR_RESET_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);
 	tmp_reg = fsl_readl(&dr_regs->frindex);
 	t = scnprintf(next, size,
 	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));
 			(tmp_reg & USB_FRINDEX_MASKS));
 	size -= t;
 	size -= t;
 	next += t;
 	next += t;
 
 
 	tmp_reg = fsl_readl(&dr_regs->deviceaddr);
 	tmp_reg = fsl_readl(&dr_regs->deviceaddr);
 	t = scnprintf(next, size,
 	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));
 			(tmp_reg & USB_DEVICE_ADDRESS_MASK));
 	size -= t;
 	size -= t;
 	next += t;
 	next += t;
 
 
 	tmp_reg = fsl_readl(&dr_regs->endpointlistaddr);
 	tmp_reg = fsl_readl(&dr_regs->endpointlistaddr);
 	t = scnprintf(next, size,
 	t = scnprintf(next, size,
-			"USB Endpoint List Address Reg:"
+			"USB Endpoint List Address Reg: "
 			"Device Addr is 0x%x\n\n",
 			"Device Addr is 0x%x\n\n",
 			(tmp_reg & USB_EP_LIST_ADDRESS_MASK));
 			(tmp_reg & USB_EP_LIST_ADDRESS_MASK));
 	size -= t;
 	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);
 	tmp_reg = fsl_readl(&dr_regs->portsc1);
 	t = scnprintf(next, size,
 	t = scnprintf(next, size,
 		"USB Port Status&Control Reg:\n"
 		"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 Enable/Disable Change: %s\n"
-		"Port Enabled/Disabled: %s"
+		"Port Enabled/Disabled: %s "
 		"Current Connect Status: %s\n\n", ( {
 		"Current Connect Status: %s\n\n", ( {
 			char *s;
 			char *s;
 			switch (tmp_reg & PORTSCX_PTS_FSLS) {
 			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);
 	tmp_reg = fsl_readl(&dr_regs->usbmode);
 	t = scnprintf(next, size,
 	t = scnprintf(next, size,
-			"USB Mode Reg:" "Controller Mode is : %s\n\n", ( {
+			"USB Mode Reg: Controller Mode is: %s\n\n", ( {
 				char *s;
 				char *s;
 				switch (tmp_reg & USB_MODE_CTRL_MODE_HOST) {
 				switch (tmp_reg & USB_MODE_CTRL_MODE_HOST) {
 				case USB_MODE_CTRL_MODE_IDLE:
 				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);
 	tmp_reg = fsl_readl(&dr_regs->endptsetupstat);
 	t = scnprintf(next, size,
 	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));
 			(tmp_reg & EP_SETUP_STATUS_MASK));
 	size -= t;
 	size -= t;
 	next += t;
 	next += t;
@@ -2055,12 +2031,12 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
 		next += t;
 		next += t;
 	}
 	}
 	tmp_reg = fsl_readl(&dr_regs->endpointprime);
 	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;
 	size -= t;
 	next += t;
 	next += t;
 
 
 	tmp_reg = usb_sys_regs->snoop1;
 	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;
 	size -= t;
 	next += t;
 	next += t;
 
 
@@ -2084,7 +2060,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
 	} else {
 	} else {
 		list_for_each_entry(req, &ep->queue, queue) {
 		list_for_each_entry(req, &ep->queue, queue) {
 			t = scnprintf(next, size,
 			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, req->req.actual,
 				req->req.length, req->req.buf);
 				req->req.length, req->req.buf);
 			size -= t;
 			size -= t;
@@ -2110,7 +2086,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
 			} else {
 			} else {
 				list_for_each_entry(req, &ep->queue, queue) {
 				list_for_each_entry(req, &ep->queue, queue) {
 					t = scnprintf(next, size,
 					t = scnprintf(next, size,
-						"req %p actual 0x%x length"
+						"req %p actual 0x%x length "
 						"0x%x  buf %p\n",
 						"0x%x  buf %p\n",
 						&req->req, req->req.actual,
 						&req->req, req->req.actual,
 						req->req.length, req->req.buf);
 						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->usb_state = USB_STATE_POWERED;
 	udc->ep0_dir = 0;
 	udc->ep0_dir = 0;
 	udc->remote_wakeup = 0;	/* default to 0 on reset */
 	udc->remote_wakeup = 0;	/* default to 0 on reset */
-	spin_lock_init(&udc->lock);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -2254,7 +2229,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
 	u32 dccparams;
 	u32 dccparams;
 
 
 	if (strcmp(pdev->name, driver_name)) {
 	if (strcmp(pdev->name, driver_name)) {
-		VDBG("Wrong device\n");
+		VDBG("Wrong device");
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
@@ -2264,23 +2239,26 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
+	spin_lock_init(&udc_controller->lock);
+	udc_controller->stopped = 1;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 	if (!res) {
-		kfree(udc_controller);
-		return -ENXIO;
+		ret = -ENXIO;
+		goto err_kfree;
 	}
 	}
 
 
 	if (!request_mem_region(res->start, res->end - res->start + 1,
 	if (!request_mem_region(res->start, res->end - res->start + 1,
 				driver_name)) {
 				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);
 	dr_regs = ioremap(res->start, res->end - res->start + 1);
 	if (!dr_regs) {
 	if (!dr_regs) {
 		ret = -ENOMEM;
 		ret = -ENOMEM;
-		goto err1;
+		goto err_release_mem_region;
 	}
 	}
 
 
 	usb_sys_regs = (struct usb_sys_interface *)
 	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)) {
 	if (!(dccparams & DCCPARAMS_DC)) {
 		ERR("This SOC doesn't support device role\n");
 		ERR("This SOC doesn't support device role\n");
 		ret = -ENODEV;
 		ret = -ENODEV;
-		goto err2;
+		goto err_iounmap;
 	}
 	}
 	/* Get max device endpoints */
 	/* Get max device endpoints */
 	/* DEN is bidirectional ep number, max_ep doubles the number */
 	/* 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);
 	udc_controller->irq = platform_get_irq(pdev, 0);
 	if (!udc_controller->irq) {
 	if (!udc_controller->irq) {
 		ret = -ENODEV;
 		ret = -ENODEV;
-		goto err2;
+		goto err_iounmap;
 	}
 	}
 
 
 	ret = request_irq(udc_controller->irq, fsl_udc_irq, IRQF_SHARED,
 	ret = request_irq(udc_controller->irq, fsl_udc_irq, IRQF_SHARED,
 			driver_name, udc_controller);
 			driver_name, udc_controller);
 	if (ret != 0) {
 	if (ret != 0) {
-		ERR("cannot request irq %d err %d \n",
+		ERR("cannot request irq %d err %d\n",
 				udc_controller->irq, ret);
 				udc_controller->irq, ret);
-		goto err2;
+		goto err_iounmap;
 	}
 	}
 
 
 	/* Initialize the udc structure including QH member and other member */
 	/* Initialize the udc structure including QH member and other member */
 	if (struct_udc_setup(udc_controller, pdev)) {
 	if (struct_udc_setup(udc_controller, pdev)) {
 		ERR("Can't initialize udc data structure\n");
 		ERR("Can't initialize udc data structure\n");
 		ret = -ENOMEM;
 		ret = -ENOMEM;
-		goto err3;
+		goto err_free_irq;
 	}
 	}
 
 
 	/* initialize usb hw reg except for regs for EP,
 	/* 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;
 	udc_controller->gadget.dev.parent = &pdev->dev;
 	ret = device_register(&udc_controller->gadget.dev);
 	ret = device_register(&udc_controller->gadget.dev);
 	if (ret < 0)
 	if (ret < 0)
-		goto err3;
+		goto err_free_irq;
 
 
 	/* setup QH and epctrl for ep0 */
 	/* setup QH and epctrl for ep0 */
 	ep0_setup(udc_controller);
 	ep0_setup(udc_controller);
@@ -2366,20 +2344,22 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
 			DTD_ALIGNMENT, UDC_DMA_BOUNDARY);
 			DTD_ALIGNMENT, UDC_DMA_BOUNDARY);
 	if (udc_controller->td_pool == NULL) {
 	if (udc_controller->td_pool == NULL) {
 		ret = -ENOMEM;
 		ret = -ENOMEM;
-		goto err4;
+		goto err_unregister;
 	}
 	}
 	create_proc_file();
 	create_proc_file();
 	return 0;
 	return 0;
 
 
-err4:
+err_unregister:
 	device_unregister(&udc_controller->gadget.dev);
 	device_unregister(&udc_controller->gadget.dev);
-err3:
+err_free_irq:
 	free_irq(udc_controller->irq, udc_controller);
 	free_irq(udc_controller->irq, udc_controller);
-err2:
+err_iounmap:
 	iounmap(dr_regs);
 	iounmap(dr_regs);
-err1:
+err_release_mem_region:
 	release_mem_region(res->start, res->end - res->start + 1);
 	release_mem_region(res->start, res->end - res->start + 1);
+err_kfree:
 	kfree(udc_controller);
 	kfree(udc_controller);
+	udc_controller = NULL;
 	return ret;
 	return ret;
 }
 }
 
 
@@ -2469,7 +2449,7 @@ module_init(udc_init);
 static void __exit udc_exit(void)
 static void __exit udc_exit(void)
 {
 {
 	platform_driver_unregister(&udc_driver);
 	platform_driver_unregister(&udc_driver);
-	printk("%s unregistered \n", driver_desc);
+	printk("%s unregistered\n", driver_desc);
 }
 }
 
 
 module_exit(udc_exit);
 module_exit(udc_exit);

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

@@ -424,16 +424,6 @@ struct ep_td_struct {
 /* Controller dma boundary */
 /* Controller dma boundary */
 #define UDC_DMA_BOUNDARY			0x1000
 #define UDC_DMA_BOUNDARY			0x1000
 
 
-/* -----------------------------------------------------------------------*/
-/* ##### enum data
-*/
-typedef enum {
-	e_ULPI,
-	e_UTMI_8BIT,
-	e_UTMI_16BIT,
-	e_SERIAL
-} e_PhyInterface;
-
 /*-------------------------------------------------------------------------*/
 /*-------------------------------------------------------------------------*/
 
 
 /* ### driver private data
 /* ### driver private data
@@ -469,9 +459,9 @@ struct fsl_ep {
 #define EP_DIR_OUT	0
 #define EP_DIR_OUT	0
 
 
 struct fsl_udc {
 struct fsl_udc {
-
 	struct usb_gadget gadget;
 	struct usb_gadget gadget;
 	struct usb_gadget_driver *driver;
 	struct usb_gadget_driver *driver;
+	struct completion *done;	/* to make sure release() is done */
 	struct fsl_ep *eps;
 	struct fsl_ep *eps;
 	unsigned int max_ep;
 	unsigned int max_ep;
 	unsigned int irq;
 	unsigned int irq;
@@ -492,20 +482,13 @@ struct fsl_udc {
 	size_t ep_qh_size;		/* size after alignment adjustment*/
 	size_t ep_qh_size;		/* size after alignment adjustment*/
 	dma_addr_t ep_qh_dma;		/* dma address of QH */
 	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 resume_state;	/* USB state to resume */
 	u32 usb_state;		/* USB current state */
 	u32 usb_state;		/* USB current state */
-	u32 usb_next_state;	/* USB next state */
 	u32 ep0_state;		/* Endpoint zero state */
 	u32 ep0_state;		/* Endpoint zero state */
 	u32 ep0_dir;		/* Endpoint zero direction: can be
 	u32 ep0_dir;		/* Endpoint zero direction: can be
 				   USB_DIR_IN or USB_DIR_OUT */
 				   USB_DIR_IN or USB_DIR_OUT */
-	u32 usb_sof_count;	/* SOF count */
-	u32 errors;		/* USB ERRORs count */
 	u8 device_address;	/* Device USB address */
 	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
 #define	gadget_is_m66592(g)	0
 #endif
 #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_SX2
 // CONFIG_USB_GADGET_AU1X00
 // CONFIG_USB_GADGET_AU1X00
@@ -216,6 +223,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
 		return 0x20;
 		return 0x20;
 	else if (gadget_is_m66592(gadget))
 	else if (gadget_is_m66592(gadget))
 		return 0x21;
 		return 0x21;
+	else if (gadget_is_fsl_qe(gadget))
+		return 0x22;
 	return -ENOENT;
 	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?
 	 * power properties of the device. Is it selfpowered?
 	 */
 	 */
 	.bmAttributes =		USB_CONFIG_ATT_ONE,
 	.bmAttributes =		USB_CONFIG_ATT_ONE,
-	.bMaxPower =		1,
+	.bMaxPower =		CONFIG_USB_GADGET_VBUS_DRAW / 2,
 };
 };
 
 
 /* B.3.1  Standard AC Interface Descriptor */
 /* 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_reset() has already been called */
 	ep->stopped = 0;
 	ep->stopped = 0;
+	ep->wedged = 0;
 	ep->out_overflow = 0;
 	ep->out_overflow = 0;
 
 
 	/* set speed-dependent max packet; may kick in high bandwidth */
 	/* 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_fifo_status (struct usb_ep *_ep);
 
 
 static int
 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;
 	struct net2280_ep	*ep;
 	unsigned long		flags;
 	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)
 	else if (ep->is_in && value && net2280_fifo_status (_ep) != 0)
 		retval = -EAGAIN;
 		retval = -EAGAIN;
 	else {
 	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 */
 		/* set/clear, then synch memory views with the device */
 		if (value) {
 		if (value) {
 			if (ep->num == 0)
 			if (ep->num == 0)
 				ep->dev->protocol_stall = 1;
 				ep->dev->protocol_stall = 1;
 			else
 			else
 				set_halt (ep);
 				set_halt (ep);
-		} else
+			if (wedged)
+				ep->wedged = 1;
+		} else {
 			clear_halt (ep);
 			clear_halt (ep);
+			ep->wedged = 0;
+		}
 		(void) readl (&ep->regs->ep_rsp);
 		(void) readl (&ep->regs->ep_rsp);
 	}
 	}
 	spin_unlock_irqrestore (&ep->dev->lock, flags);
 	spin_unlock_irqrestore (&ep->dev->lock, flags);
@@ -1256,6 +1262,20 @@ net2280_set_halt (struct usb_ep *_ep, int value)
 	return retval;
 	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
 static int
 net2280_fifo_status (struct usb_ep *_ep)
 net2280_fifo_status (struct usb_ep *_ep)
 {
 {
@@ -1302,6 +1322,7 @@ static const struct usb_ep_ops net2280_ep_ops = {
 	.dequeue	= net2280_dequeue,
 	.dequeue	= net2280_dequeue,
 
 
 	.set_halt	= net2280_set_halt,
 	.set_halt	= net2280_set_halt,
+	.set_wedge	= net2280_set_wedge,
 	.fifo_status	= net2280_fifo_status,
 	.fifo_status	= net2280_fifo_status,
 	.fifo_flush	= net2280_fifo_flush,
 	.fifo_flush	= net2280_fifo_flush,
 };
 };
@@ -2410,9 +2431,14 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
 				goto do_stall;
 				goto do_stall;
 			if ((e = get_ep_by_addr (dev, w_index)) == 0)
 			if ((e = get_ep_by_addr (dev, w_index)) == 0)
 				goto do_stall;
 				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);
 			allow_status (ep);
-			VDEBUG (dev, "%s clear halt\n", ep->ep.name);
 			goto next_endpoints;
 			goto next_endpoints;
 			}
 			}
 			break;
 			break;
@@ -2427,6 +2453,8 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
 				goto do_stall;
 				goto do_stall;
 			if ((e = get_ep_by_addr (dev, w_index)) == 0)
 			if ((e = get_ep_by_addr (dev, w_index)) == 0)
 				goto do_stall;
 				goto do_stall;
+			if (e->ep.name == ep0name)
+				goto do_stall;
 			set_halt (e);
 			set_halt (e);
 			allow_status (ep);
 			allow_status (ep);
 			VDEBUG (dev, "%s set halt\n", ep->ep.name);
 			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,
 						in_fifo_validate : 1,
 						out_overflow : 1,
 						out_overflow : 1,
 						stopped : 1,
 						stopped : 1,
+						wedged : 1,
 						is_in : 1,
 						is_in : 1,
 						is_iso : 1,
 						is_iso : 1,
 						responded : 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);
 	tmp = omap_readl(OTG_REV);
 	if (cpu_is_omap24xx()) {
 	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";
 		ctrl_name = "control_devconf";
 		trans = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
 		trans = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
 	} else {
 	} else {

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

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

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

@@ -22,7 +22,6 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/delay.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;
 		return -EBUSY;
 
 
 	if (!driver->bind || !driver->setup
 	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",
 		printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n",
 			driver->bind, driver->setup, driver->speed);
 			driver->bind, driver->setup, driver->speed);
 		return -EINVAL;
 		return -EINVAL;

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

@@ -43,6 +43,7 @@
 #include "epautoconf.c"
 #include "epautoconf.c"
 
 
 #include "f_acm.c"
 #include "f_acm.c"
+#include "f_obex.c"
 #include "f_serial.c"
 #include "f_serial.c"
 #include "u_serial.c"
 #include "u_serial.c"
 
 
@@ -56,6 +57,7 @@
 #define GS_VENDOR_ID			0x0525	/* NetChip */
 #define GS_VENDOR_ID			0x0525	/* NetChip */
 #define GS_PRODUCT_ID			0xa4a6	/* Linux-USB Serial Gadget */
 #define GS_PRODUCT_ID			0xa4a6	/* Linux-USB Serial Gadget */
 #define GS_CDC_PRODUCT_ID		0xa4a7	/* ... as CDC-ACM */
 #define GS_CDC_PRODUCT_ID		0xa4a7	/* ... as CDC-ACM */
+#define GS_CDC_OBEX_PRODUCT_ID		0xa4a9	/* ... as CDC-OBEX */
 
 
 /* string IDs are assigned dynamically */
 /* string IDs are assigned dynamically */
 
 
@@ -125,6 +127,10 @@ static int use_acm = true;
 module_param(use_acm, bool, 0);
 module_param(use_acm, bool, 0);
 MODULE_PARM_DESC(use_acm, "Use CDC ACM, default=yes");
 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;
 static unsigned n_ports = 1;
 module_param(n_ports, uint, 0);
 module_param(n_ports, uint, 0);
 MODULE_PARM_DESC(n_ports, "number of ports to create, default=1");
 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++) {
 	for (i = 0; i < n_ports && status == 0; i++) {
 		if (use_acm)
 		if (use_acm)
 			status = acm_bind_config(c, i);
 			status = acm_bind_config(c, i);
+		else if (use_obex)
+			status = obex_bind_config(c, i);
 		else
 		else
 			status = gser_bind_config(c, i);
 			status = gser_bind_config(c, i);
 	}
 	}
@@ -151,7 +159,6 @@ static struct usb_configuration serial_config_driver = {
 	/* .bConfigurationValue = f(use_acm) */
 	/* .bConfigurationValue = f(use_acm) */
 	/* .iConfiguration = DYNAMIC */
 	/* .iConfiguration = DYNAMIC */
 	.bmAttributes	= USB_CONFIG_ATT_SELFPOWER,
 	.bmAttributes	= USB_CONFIG_ATT_SELFPOWER,
-	.bMaxPower	= 1,	/* 2 mA, minimal */
 };
 };
 
 
 static int __init gs_bind(struct usb_composite_dev *cdev)
 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.bDeviceClass = USB_CLASS_COMM;
 		device_desc.idProduct =
 		device_desc.idProduct =
 				__constant_cpu_to_le16(GS_CDC_PRODUCT_ID);
 				__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 {
 	} else {
 		serial_config_driver.label = "Generic Serial config";
 		serial_config_driver.label = "Generic Serial config";
 		serial_config_driver.bConfigurationValue = 1;
 		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);
 		spin_lock(&dev->lock);
 		dev->port_usb = link;
 		dev->port_usb = link;
 		link->ioport = dev;
 		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);
 		spin_unlock(&dev->lock);
 
 
 		netif_carrier_on(dev->net);
 		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 */
 /* functions are bound to configurations by a config or gadget driver */
 int acm_bind_config(struct usb_configuration *c, u8 port_num);
 int acm_bind_config(struct usb_configuration *c, u8 port_num);
 int gser_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 */
 #endif /* __U_SERIAL_H */

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

@@ -358,7 +358,8 @@ struct debug_buffer {
 	struct usb_bus *bus;
 	struct usb_bus *bus;
 	struct mutex mutex;	/* protect filling of buffer */
 	struct mutex mutex;	/* protect filling of buffer */
 	size_t count;		/* number of characters filled into 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; \
 #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);
 	hcd = bus_to_hcd(buf->bus);
 	ehci = hcd_to_ehci (hcd);
 	ehci = hcd_to_ehci (hcd);
-	next = buf->page;
-	size = PAGE_SIZE;
+	next = buf->output_buf;
+	size = buf->alloc_size;
 
 
 	*next = 0;
 	*next = 0;
 
 
@@ -510,7 +511,7 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
 	}
 	}
 	spin_unlock_irqrestore (&ehci->lock, flags);
 	spin_unlock_irqrestore (&ehci->lock, flags);
 
 
-	return strlen(buf->page);
+	return strlen(buf->output_buf);
 }
 }
 
 
 #define DBG_SCHED_LIMIT 64
 #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);
 	hcd = bus_to_hcd(buf->bus);
 	ehci = hcd_to_ehci (hcd);
 	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);
 	temp = scnprintf (next, size, "size = %d\n", ehci->periodic_size);
 	size -= temp;
 	size -= temp;
@@ -568,14 +569,16 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 				for (temp = 0; temp < seen_count; temp++) {
 				for (temp = 0; temp < seen_count; temp++) {
 					if (seen [temp].ptr != p.ptr)
 					if (seen [temp].ptr != p.ptr)
 						continue;
 						continue;
-					if (p.qh->qh_next.ptr)
+					if (p.qh->qh_next.ptr) {
 						temp = scnprintf (next, size,
 						temp = scnprintf (next, size,
 							" ...");
 							" ...");
-					p.ptr = NULL;
+						size -= temp;
+						next += temp;
+					}
 					break;
 					break;
 				}
 				}
 				/* show more info the first time around */
 				/* show more info the first time around */
-				if (temp == seen_count && p.ptr) {
+				if (temp == seen_count) {
 					u32	scratch = hc32_to_cpup(ehci,
 					u32	scratch = hc32_to_cpup(ehci,
 							&p.qh->hw_info1);
 							&p.qh->hw_info1);
 					struct ehci_qtd	*qtd;
 					struct ehci_qtd	*qtd;
@@ -649,7 +652,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
 	spin_unlock_irqrestore (&ehci->lock, flags);
 	spin_unlock_irqrestore (&ehci->lock, flags);
 	kfree (seen);
 	kfree (seen);
 
 
-	return PAGE_SIZE - size;
+	return buf->alloc_size - size;
 }
 }
 #undef DBG_SCHED_LIMIT
 #undef DBG_SCHED_LIMIT
 
 
@@ -665,14 +668,14 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 
 
 	hcd = bus_to_hcd(buf->bus);
 	hcd = bus_to_hcd(buf->bus);
 	ehci = hcd_to_ehci (hcd);
 	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);
 	spin_lock_irqsave (&ehci->lock, flags);
 
 
 	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
 	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
 		size = scnprintf (next, size,
 		size = scnprintf (next, size,
-			"bus %s, device %s (driver " DRIVER_VERSION ")\n"
+			"bus %s, device %s\n"
 			"%s\n"
 			"%s\n"
 			"SUSPENDED (no register access)\n",
 			"SUSPENDED (no register access)\n",
 			hcd->self.controller->bus->name,
 			hcd->self.controller->bus->name,
@@ -684,7 +687,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 	/* Capability Registers */
 	/* Capability Registers */
 	i = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
 	i = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
 	temp = scnprintf (next, size,
 	temp = scnprintf (next, size,
-		"bus %s, device %s (driver " DRIVER_VERSION ")\n"
+		"bus %s, device %s\n"
 		"%s\n"
 		"%s\n"
 		"EHCI %x.%02x, hcd state %d\n",
 		"EHCI %x.%02x, hcd state %d\n",
 		hcd->self.controller->bus->name,
 		hcd->self.controller->bus->name,
@@ -808,7 +811,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
 done:
 done:
 	spin_unlock_irqrestore (&ehci->lock, flags);
 	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,
 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->bus = bus;
 		buf->fill_func = fill_func;
 		buf->fill_func = fill_func;
 		mutex_init(&buf->mutex);
 		mutex_init(&buf->mutex);
+		buf->alloc_size = PAGE_SIZE;
 	}
 	}
 
 
 	return buf;
 	return buf;
@@ -831,10 +835,10 @@ static int fill_buffer(struct debug_buffer *buf)
 {
 {
 	int ret = 0;
 	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;
 		ret = -ENOMEM;
 		goto out;
 		goto out;
 	}
 	}
@@ -867,7 +871,7 @@ static ssize_t debug_output(struct file *file, char __user *user_buf,
 	mutex_unlock(&buf->mutex);
 	mutex_unlock(&buf->mutex);
 
 
 	ret = simple_read_from_buffer(user_buf, len, offset,
 	ret = simple_read_from_buffer(user_buf, len, offset,
-				      buf->page, buf->count);
+				      buf->output_buf, buf->count);
 
 
 out:
 out:
 	return ret;
 	return ret;
@@ -879,8 +883,8 @@ static int debug_close(struct inode *inode, struct file *file)
 	struct debug_buffer *buf = file->private_data;
 	struct debug_buffer *buf = file->private_data;
 
 
 	if (buf) {
 	if (buf) {
-		if (buf->page)
-			free_page((unsigned long)buf->page);
+		if (buf->output_buf)
+			vfree(buf->output_buf);
 		kfree(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)
 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)
 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/ioport.h>
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/timer.h>
 #include <linux/timer.h>
@@ -59,7 +60,6 @@
  * providing early devices for those host controllers to talk to!
  * providing early devices for those host controllers to talk to!
  */
  */
 
 
-#define DRIVER_VERSION "10 Dec 2004"
 #define DRIVER_AUTHOR "David Brownell"
 #define DRIVER_AUTHOR "David Brownell"
 #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
 #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));
 	temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
 	ehci_info (ehci,
 	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),
 		((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
-		temp >> 8, temp & 0xff, DRIVER_VERSION,
+		temp >> 8, temp & 0xff,
 		ignore_oc ? ", overcurrent ignored" : "");
 		ignore_oc ? ", overcurrent ignored" : "");
 
 
 	ehci_writel(ehci, INTR_MASK,
 	ehci_writel(ehci, INTR_MASK,
@@ -706,7 +706,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 		pcd_status = status;
 		pcd_status = status;
 
 
 		/* resume root hub? */
 		/* resume root hub? */
-		if (!(ehci_readl(ehci, &ehci->regs->command) & CMD_RUN))
+		if (!(cmd & CMD_RUN))
 			usb_hcd_resume_root_hub(hcd);
 			usb_hcd_resume_root_hub(hcd);
 
 
 		while (i--) {
 		while (i--) {
@@ -715,8 +715,11 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 
 
 			if (pstatus & PORT_OWNER)
 			if (pstatus & PORT_OWNER)
 				continue;
 				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;
 				continue;
 
 
 			/* start 20 msec resume signaling from this port,
 			/* 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] */
 	/* PCI errors [4.15.2.4] */
 	if (unlikely ((status & STS_FATAL) != 0)) {
 	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) {
 		if (status & STS_HALT) {
 			ehci_err (ehci, "fatal error\n");
 			ehci_err (ehci, "fatal error\n");
 dead:
 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_AUTHOR (DRIVER_AUTHOR);
 MODULE_LICENSE ("GPL");
 MODULE_LICENSE ("GPL");
 
 
@@ -1020,11 +1020,6 @@ MODULE_LICENSE ("GPL");
 #define	PS3_SYSTEM_BUS_DRIVER	ps3_ehci_driver
 #define	PS3_SYSTEM_BUS_DRIVER	ps3_ehci_driver
 #endif
 #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
 #ifdef CONFIG_USB_EHCI_HCD_PPC_OF
 #include "ehci-ppc-of.c"
 #include "ehci-ppc-of.c"
 #define OF_PLATFORM_DRIVER	ehci_hcd_ppc_of_driver
 #define OF_PLATFORM_DRIVER	ehci_hcd_ppc_of_driver
@@ -1049,6 +1044,16 @@ static int __init ehci_hcd_init(void)
 {
 {
 	int retval = 0;
 	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",
 	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
 		 hcd_name,
 		 hcd_name,
 		 sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
 		 sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
@@ -1056,8 +1061,10 @@ static int __init ehci_hcd_init(void)
 
 
 #ifdef DEBUG
 #ifdef DEBUG
 	ehci_debug_root = debugfs_create_dir("ehci", NULL);
 	ehci_debug_root = debugfs_create_dir("ehci", NULL);
-	if (!ehci_debug_root)
-		return -ENOENT;
+	if (!ehci_debug_root) {
+		retval = -ENOENT;
+		goto err_debug;
+	}
 #endif
 #endif
 
 
 #ifdef PLATFORM_DRIVER
 #ifdef PLATFORM_DRIVER
@@ -1105,6 +1112,8 @@ clean0:
 	debugfs_remove(ehci_debug_root);
 	debugfs_remove(ehci_debug_root);
 	ehci_debug_root = NULL;
 	ehci_debug_root = NULL;
 #endif
 #endif
+err_debug:
+	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
 	return retval;
 	return retval;
 }
 }
 module_init(ehci_hcd_init);
 module_init(ehci_hcd_init);
@@ -1126,6 +1135,7 @@ static void __exit ehci_hcd_cleanup(void)
 #ifdef DEBUG
 #ifdef DEBUG
 	debugfs_remove(ehci_debug_root);
 	debugfs_remove(ehci_debug_root);
 #endif
 #endif
+	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
 }
 }
 module_exit(ehci_hcd_cleanup);
 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 = ehci_readl(ehci, &ehci->regs->port_status [i]);
 		temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
 		temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
 		if (test_bit(i, &ehci->bus_suspended) &&
 		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;
 			temp |= PORT_RESUME;
-		}
 		ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
 		ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
 	}
 	}
 	i = HCS_N_PORTS (ehci->hcs_params);
 	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.
 		 * 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)
 			if (i < 7)
 			    buf [0] |= 1 << (i + 1);
 			    buf [0] |= 1 << (i + 1);
 			else
 			else
@@ -688,6 +685,7 @@ static int ehci_hub_control (
 			/* resume completed? */
 			/* resume completed? */
 			else if (time_after_eq(jiffies,
 			else if (time_after_eq(jiffies,
 					ehci->reset_done[wIndex])) {
 					ehci->reset_done[wIndex])) {
+				clear_bit(wIndex, &ehci->suspended_ports);
 				set_bit(wIndex, &ehci->port_c_suspend);
 				set_bit(wIndex, &ehci->port_c_suspend);
 				ehci->reset_done[wIndex] = 0;
 				ehci->reset_done[wIndex] = 0;
 
 
@@ -734,6 +732,9 @@ static int ehci_hub_control (
 					ehci_readl(ehci, status_reg));
 					ehci_readl(ehci, status_reg));
 		}
 		}
 
 
+		if (!(temp & (PORT_RESUME|PORT_RESET)))
+			ehci->reset_done[wIndex] = 0;
+
 		/* transfer dedicated ports to the companion hc */
 		/* transfer dedicated ports to the companion hc */
 		if ((temp & PORT_CONNECT) &&
 		if ((temp & PORT_CONNECT) &&
 				test_bit(wIndex, &ehci->companion_ports)) {
 				test_bit(wIndex, &ehci->companion_ports)) {
@@ -757,8 +758,17 @@ static int ehci_hub_control (
 		}
 		}
 		if (temp & PORT_PE)
 		if (temp & PORT_PE)
 			status |= 1 << USB_PORT_FEAT_ENABLE;
 			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;
 			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)
 		if (temp & PORT_OC)
 			status |= 1 << USB_PORT_FEAT_OVER_CURRENT;
 			status |= 1 << USB_PORT_FEAT_OVER_CURRENT;
 		if (temp & PORT_RESET)
 		if (temp & PORT_RESET)
@@ -803,6 +813,7 @@ static int ehci_hub_control (
 					|| (temp & PORT_RESET) != 0)
 					|| (temp & PORT_RESET) != 0)
 				goto error;
 				goto error;
 			ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
 			ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
+			set_bit(wIndex, &ehci->suspended_ports);
 			break;
 			break;
 		case USB_PORT_FEAT_POWER:
 		case USB_PORT_FEAT_POWER:
 			if (HCS_PPC (ehci->hcs_params))
 			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 */
 			owned by the companion during a bus suspend */
 	unsigned long		port_c_suspend;		/* which ports have
 	unsigned long		port_c_suspend;		/* which ports have
 			the change-suspend feature turned on */
 			the change-suspend feature turned on */
+	unsigned long		suspended_ports;	/* which ports are
+			suspended */
 
 
 	/* per-HC memory pools (could be per-bus, but ...) */
 	/* per-HC memory pools (could be per-bus, but ...) */
 	struct dma_pool		*qh_pool;	/* qh per active urb */
 	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
 	 * the async ring; just the I/O watchdog.  Note that if a
 	 * SHRINK were pending, OFF would never be requested.
 	 * 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)) {
 	if (!test_and_set_bit (action, &ehci->actions)) {
 		unsigned long t;
 		unsigned long t;
 
 
+		if (timer_pending(&ehci->watchdog)
+			&& ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
+				& oldactions))
+			return;
+
 		switch (action) {
 		switch (action) {
 		case TIMER_IO_WATCHDOG:
 		case TIMER_IO_WATCHDOG:
 			t = EHCI_IO_JIFFIES;
 			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;
 			t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
 			break;
 			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.
  * Big-endian read/write functions are arch-specific.
  * Other arches can be added if/when they're needed.
  * 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)
 #if defined(CONFIG_ARM) && defined(CONFIG_ARCH_IXP4XX)
 #define readl_be(addr)		__raw_readl((__force unsigned *)addr)
 #define readl_be(addr)		__raw_readl((__force unsigned *)addr)
 #define writel_be(val, addr)	__raw_writel(val, (__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 usb_hcd *hcd;
 	struct isp116x *isp116x;
 	struct isp116x *isp116x;
-	struct resource *addr, *data;
+	struct resource *addr, *data, *ires;
 	void __iomem *addr_reg;
 	void __iomem *addr_reg;
 	void __iomem *data_reg;
 	void __iomem *data_reg;
 	int irq;
 	int irq;
 	int ret = 0;
 	int ret = 0;
+	unsigned long irqflags;
 
 
 	if (pdev->num_resources < 3) {
 	if (pdev->num_resources < 3) {
 		ret = -ENODEV;
 		ret = -ENODEV;
@@ -1575,12 +1576,16 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
 
 
 	data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	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;
 		ret = -ENODEV;
 		goto err1;
 		goto err1;
 	}
 	}
 
 
+	irq = ires->start;
+	irqflags = ires->flags & IRQF_TRIGGER_MASK;
+
 	if (pdev->dev.dma_mask) {
 	if (pdev->dev.dma_mask) {
 		DBG("DMA not supported\n");
 		DBG("DMA not supported\n");
 		ret = -EINVAL;
 		ret = -EINVAL;
@@ -1634,7 +1639,7 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
 		goto err6;
 		goto err6;
 	}
 	}
 
 
-	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+	ret = usb_add_hcd(hcd, irq, irqflags | IRQF_DISABLED);
 	if (ret)
 	if (ret)
 		goto err6;
 		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
 	 * and reading back and checking the contents are same or not
 	 */
 	 */
 	if (reg_data != 0xFACE) {
 	if (reg_data != 0xFACE) {
-		err("scratch register mismatch %x", reg_data);
+		dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data);
 		goto clean;
 		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,
 	hcd = isp1760_register(pci_mem_phy0, length, dev->irq,
 		IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev),
 		IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev),
 		devflags);
 		devflags);
-	pci_set_drvdata(dev, hcd);
-	if (!hcd)
+	if (!IS_ERR(hcd)) {
+		pci_set_drvdata(dev, hcd);
 		return 0;
 		return 0;
+	}
 clean:
 clean:
 	status = -ENODEV;
 	status = -ENODEV;
 	iounmap(iobase);
 	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,
 	ohci_dbg_sw (ohci, &next, &size,
 		"bus %s, device %s\n"
 		"bus %s, device %s\n"
 		"%s\n"
 		"%s\n"
-		"%s version " DRIVER_VERSION "\n",
+		"%s\n",
 		hcd->self.controller->bus->name,
 		hcd->self.controller->bus->name,
 		dev_name(hcd->self.controller),
 		dev_name(hcd->self.controller),
 		hcd->product_desc,
 		hcd->product_desc,

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

@@ -46,7 +46,6 @@
 
 
 #include "../core/hcd.h"
 #include "../core/hcd.h"
 
 
-#define DRIVER_VERSION "2006 August 04"
 #define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
 #define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
 #define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
 #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_AUTHOR (DRIVER_AUTHOR);
-MODULE_DESCRIPTION (DRIVER_INFO);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE ("GPL");
 MODULE_LICENSE ("GPL");
 
 
 #ifdef CONFIG_PCI
 #ifdef CONFIG_PCI
@@ -1095,9 +1092,10 @@ static int __init ohci_hcd_mod_init(void)
 	if (usb_disabled())
 	if (usb_disabled())
 		return -ENODEV;
 		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,
 	pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name,
 		sizeof (struct ed), sizeof (struct td));
 		sizeof (struct ed), sizeof (struct td));
+	set_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
 
 
 #ifdef DEBUG
 #ifdef DEBUG
 	ohci_debug_root = debugfs_create_dir("ohci", NULL);
 	ohci_debug_root = debugfs_create_dir("ohci", NULL);
@@ -1184,6 +1182,7 @@ static int __init ohci_hcd_mod_init(void)
  error_debug:
  error_debug:
 #endif
 #endif
 
 
+	clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
 	return retval;
 	return retval;
 }
 }
 module_init(ohci_hcd_mod_init);
 module_init(ohci_hcd_mod_init);
@@ -1214,6 +1213,7 @@ static void __exit ohci_hcd_mod_exit(void)
 #ifdef DEBUG
 #ifdef DEBUG
 	debugfs_remove(ohci_debug_root);
 	debugfs_remove(ohci_debug_root);
 #endif
 #endif
+	clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
 }
 }
 module_exit(ohci_hcd_mod_exit);
 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 */
 /* Carry out polling-, autostop-, and autoresume-related state changes */
 static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
 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	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:
 	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
 		/* 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 ||
 			if (any_connected ||
 					!device_may_wakeup(&ohci_to_hcd(ohci)
 					!device_may_wakeup(&ohci_to_hcd(ohci)
 						->self.root_hub->dev)) {
 						->self.root_hub->dev)) {
-				if (rhsc)
+				if (rhsc_enable)
 					poll_rh = 0;
 					poll_rh = 0;
 			} else {
 			} else {
 				ohci->autostop = 1;
 				ohci->autostop = 1;
@@ -396,34 +399,45 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
 				ohci->autostop = 0;
 				ohci->autostop = 0;
 				ohci->next_statechange = jiffies +
 				ohci->next_statechange = jiffies +
 						STATECHANGE_DELAY;
 						STATECHANGE_DELAY;
-			} else if (rhsc && time_after_eq(jiffies,
+			} else if (time_after_eq(jiffies,
 						ohci->next_statechange)
 						ohci->next_statechange)
 					&& !ohci->ed_rm_list
 					&& !ohci->ed_rm_list
 					&& !(ohci->hc_control &
 					&& !(ohci->hc_control &
 						OHCI_SCHED_ENABLES)) {
 						OHCI_SCHED_ENABLES)) {
 				ohci_rh_suspend(ohci, 1);
 				ohci_rh_suspend(ohci, 1);
-				poll_rh = 0;
+				if (rhsc_enable)
+					poll_rh = 0;
 			}
 			}
 		}
 		}
 		break;
 		break;
 
 
-	/* if there is a port change, autostart or ask to be resumed */
 	case OHCI_USB_SUSPEND:
 	case OHCI_USB_SUSPEND:
 	case OHCI_USB_RESUME:
 	case OHCI_USB_RESUME:
+		/* if there is a port change, autostart or ask to be resumed */
 		if (changed) {
 		if (changed) {
 			if (ohci->autostop)
 			if (ohci->autostop)
 				ohci_rh_resume(ohci);
 				ohci_rh_resume(ohci);
 			else
 			else
 				usb_hcd_resume_root_hub(ohci_to_hcd(ohci));
 				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;
 			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;
 		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.
  * autostop isn't used when CONFIG_PM is turned off.
  */
  */
 static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
 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 RHSC is enabled, don't poll */
 	if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC)
 	if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC)
 		return 0;
 		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 */
 #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);
 	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
 	int		i, changed = 0, length = 1;
 	int		i, changed = 0, length = 1;
 	int		any_connected = 0;
 	int		any_connected = 0;
+	int		rhsc_status;
 	unsigned long	flags;
 	unsigned long	flags;
 
 
 	spin_lock_irqsave (&ohci->lock, flags);
 	spin_lock_irqsave (&ohci->lock, flags);
@@ -492,12 +511,10 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
 		length++;
 		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 */
 	/* look at each port */
 	for (i = 0; i < ohci->num_ports; i++) {
 	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,
 	hcd->poll_rh = ohci_root_hub_state_changes(ohci, changed,
-			any_connected);
+			any_connected, rhsc_status);
 
 
 done:
 done:
 	spin_unlock_irqrestore (&ohci->lock, flags);
 	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);
 	omap_ohci_clock_power(1);
 
 
-	if (cpu_is_omap1510()) {
+	if (cpu_is_omap15xx()) {
 		omap_1510_local_bus_power(1);
 		omap_1510_local_bus_power(1);
 		omap_1510_local_bus_init();
 		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))
 	if (IS_ERR(usb_host_ck))
 		return PTR_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");
 		usb_dc_ck = clk_get(0, "usb_dc_ck");
 	else
 	else
 		usb_dc_ck = clk_get(0, "lb_ck");
 		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;
 	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()) {
 	if (usb_disabled()) {
 		err("USB is disabled");
 		err("USB is disabled");
 		ret = -ENODEV;
 		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.
  * Big-endian read/write functions are arch-specific.
  * Other arches can be added if/when they're needed.
  * 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,
 static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci,
 					__hc32 __iomem * regs)
 					__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_param(endian, ushort, 0644);
 MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)");
 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_param(irq_sense, ushort, 0644);
 MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0 "
 MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0 "
 		"(default=32)");
 		"(default=32)");
@@ -118,7 +118,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
 		r8a66597_write(r8a66597, SCKE, SYSCFG0);
 		r8a66597_write(r8a66597, SCKE, SYSCFG0);
 		tmp = r8a66597_read(r8a66597, SYSCFG0);
 		tmp = r8a66597_read(r8a66597, SYSCFG0);
 		if (i++ > 1000) {
 		if (i++ > 1000) {
-			err("register access fail.");
+			printk(KERN_ERR "r8a66597: register access fail.\n");
 			return -ENXIO;
 			return -ENXIO;
 		}
 		}
 	} while ((tmp & SCKE) != SCKE);
 	} while ((tmp & SCKE) != SCKE);
@@ -128,7 +128,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
 		r8a66597_write(r8a66597, USBE, SYSCFG0);
 		r8a66597_write(r8a66597, USBE, SYSCFG0);
 		tmp = r8a66597_read(r8a66597, SYSCFG0);
 		tmp = r8a66597_read(r8a66597, SYSCFG0);
 		if (i++ > 1000) {
 		if (i++ > 1000) {
-			err("register access fail.");
+			printk(KERN_ERR "r8a66597: register access fail.\n");
 			return -ENXIO;
 			return -ENXIO;
 		}
 		}
 	} while ((tmp & USBE) != USBE);
 	} while ((tmp & USBE) != USBE);
@@ -141,7 +141,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
 		msleep(1);
 		msleep(1);
 		tmp = r8a66597_read(r8a66597, SYSCFG0);
 		tmp = r8a66597_read(r8a66597, SYSCFG0);
 		if (i++ > 500) {
 		if (i++ > 500) {
-			err("register access fail.");
+			printk(KERN_ERR "r8a66597: register access fail.\n");
 			return -ENXIO;
 			return -ENXIO;
 		}
 		}
 	} while ((tmp & SCKE) != SCKE);
 	} while ((tmp & SCKE) != SCKE);
@@ -265,7 +265,7 @@ static void get_port_number(char *devpath, u16 *root_port, u16 *hub_port)
 	if (root_port) {
 	if (root_port) {
 		*root_port = (devpath[0] & 0x0F) - 1;
 		*root_port = (devpath[0] & 0x0F) - 1;
 		if (*root_port >= R8A66597_MAX_ROOT_HUB)
 		if (*root_port >= R8A66597_MAX_ROOT_HUB)
-			err("illegal root port number");
+			printk(KERN_ERR "r8a66597: Illegal root port number.\n");
 	}
 	}
 	if (hub_port)
 	if (hub_port)
 		*hub_port = devpath[2] & 0x0F;
 		*hub_port = devpath[2] & 0x0F;
@@ -286,7 +286,7 @@ static u16 get_r8a66597_usb_speed(enum usb_device_speed speed)
 		usbspd = HSMODE;
 		usbspd = HSMODE;
 		break;
 		break;
 	default:
 	default:
-		err("unknown speed");
+		printk(KERN_ERR "r8a66597: unknown speed\n");
 		break;
 		break;
 	}
 	}
 
 
@@ -385,7 +385,7 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb)
 	struct r8a66597_device *dev;
 	struct r8a66597_device *dev;
 
 
 	if (is_hub_limit(urb->dev->devpath)) {
 	if (is_hub_limit(urb->dev->devpath)) {
-		err("Externel hub limit reached.");
+		dev_err(&urb->dev->dev, "External hub limit reached.\n");
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -406,8 +406,9 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb)
 		return addr;
 		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;
 	return 0;
 }
 }
@@ -447,7 +448,8 @@ static void r8a66597_reg_wait(struct r8a66597 *r8a66597, unsigned long reg,
 	do {
 	do {
 		tmp = r8a66597_read(r8a66597, reg);
 		tmp = r8a66597_read(r8a66597, reg);
 		if (i++ > 1000000) {
 		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;
 			break;
 		}
 		}
 		ndelay(1);
 		ndelay(1);
@@ -675,7 +677,7 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597,
 			array[i++] = 1;
 			array[i++] = 1;
 		break;
 		break;
 	default:
 	default:
-		err("Illegal type");
+		printk(KERN_ERR "r8a66597: Illegal type\n");
 		return 0;
 		return 0;
 	}
 	}
 
 
@@ -705,7 +707,7 @@ static u16 get_r8a66597_type(__u8 type)
 		r8a66597_type = R8A66597_ISO;
 		r8a66597_type = R8A66597_ISO;
 		break;
 		break;
 	default:
 	default:
-		err("Illegal type");
+		printk(KERN_ERR "r8a66597: Illegal type\n");
 		r8a66597_type = 0x0000;
 		r8a66597_type = 0x0000;
 		break;
 		break;
 	}
 	}
@@ -724,7 +726,7 @@ static u16 get_bufnum(u16 pipenum)
 	else if (check_interrupt(pipenum))
 	else if (check_interrupt(pipenum))
 		bufnum = 4 + (pipenum - 6);
 		bufnum = 4 + (pipenum - 6);
 	else
 	else
-		err("Illegal pipenum (%d)", pipenum);
+		printk(KERN_ERR "r8a66597: Illegal pipenum (%d)\n", pipenum);
 
 
 	return bufnum;
 	return bufnum;
 }
 }
@@ -740,7 +742,7 @@ static u16 get_buf_bsize(u16 pipenum)
 	else if (check_interrupt(pipenum))
 	else if (check_interrupt(pipenum))
 		buf_bsize = 0;
 		buf_bsize = 0;
 	else
 	else
-		err("Illegal pipenum (%d)", pipenum);
+		printk(KERN_ERR "r8a66597: Illegal pipenum (%d)\n", pipenum);
 
 
 	return buf_bsize;
 	return buf_bsize;
 }
 }
@@ -760,10 +762,12 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
 			if ((r8a66597->dma_map & (1 << i)) != 0)
 			if ((r8a66597->dma_map & (1 << i)) != 0)
 				continue;
 				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;
 			r8a66597->dma_map |= 1 << i;
 			dev->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);
 		prepare_status_packet(r8a66597, td);
 		break;
 		break;
 	default:
 	default:
-		err("invalid type.");
+		printk(KERN_ERR "r8a66597: invalid type.\n");
 		break;
 		break;
 	}
 	}
 
 
@@ -1295,7 +1299,7 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum)
 	if (unlikely((tmp & FRDY) == 0)) {
 	if (unlikely((tmp & FRDY) == 0)) {
 		pipe_stop(r8a66597, td->pipe);
 		pipe_stop(r8a66597, td->pipe);
 		pipe_irq_disable(r8a66597, pipenum);
 		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);
 		finish_request(r8a66597, td, pipenum, td->urb, -EPIPE);
 		return;
 		return;
 	}
 	}
@@ -1370,7 +1374,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum)
 	if (unlikely((tmp & FRDY) == 0)) {
 	if (unlikely((tmp & FRDY) == 0)) {
 		pipe_stop(r8a66597, td->pipe);
 		pipe_stop(r8a66597, td->pipe);
 		pipe_irq_disable(r8a66597, pipenum);
 		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);
 		finish_request(r8a66597, td, pipenum, urb, -EPIPE);
 		return;
 		return;
 	}
 	}
@@ -2005,7 +2009,7 @@ static struct r8a66597_device *get_r8a66597_device(struct r8a66597 *r8a66597,
 		return dev;
 		return dev;
 	}
 	}
 
 
-	err("get_r8a66597_device fail.(%d)\n", addr);
+	printk(KERN_ERR "r8a66597: get_r8a66597_device fail.(%d)\n", addr);
 	return NULL;
 	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)
 #define resource_len(r) (((r)->end - (r)->start) + 1)
 static int __init r8a66597_probe(struct platform_device *pdev)
 static int __init r8a66597_probe(struct platform_device *pdev)
 {
 {
-	struct resource *res = NULL;
+	struct resource *res = NULL, *ires;
 	int irq = -1;
 	int irq = -1;
 	void __iomem *reg = NULL;
 	void __iomem *reg = NULL;
 	struct usb_hcd *hcd = NULL;
 	struct usb_hcd *hcd = NULL;
@@ -2274,7 +2278,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)
 
 
 	if (pdev->dev.dma_mask) {
 	if (pdev->dev.dma_mask) {
 		ret = -EINVAL;
 		ret = -EINVAL;
-		err("dma not support");
+		dev_err(&pdev->dev, "dma not supported\n");
 		goto clean_up;
 		goto clean_up;
 	}
 	}
 
 
@@ -2282,21 +2286,25 @@ static int __init r8a66597_probe(struct platform_device *pdev)
 					   (char *)hcd_name);
 					   (char *)hcd_name);
 	if (!res) {
 	if (!res) {
 		ret = -ENODEV;
 		ret = -ENODEV;
-		err("platform_get_resource_byname error.");
+		dev_err(&pdev->dev, "platform_get_resource_byname error.\n");
 		goto clean_up;
 		goto clean_up;
 	}
 	}
 
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
+	ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!ires) {
 		ret = -ENODEV;
 		ret = -ENODEV;
-		err("platform_get_irq error.");
+		dev_err(&pdev->dev,
+			"platform_get_resource IORESOURCE_IRQ error.\n");
 		goto clean_up;
 		goto clean_up;
 	}
 	}
 
 
+	irq = ires->start;
+	irq_trigger = ires->flags & IRQF_TRIGGER_MASK;
+
 	reg = ioremap(res->start, resource_len(res));
 	reg = ioremap(res->start, resource_len(res));
 	if (reg == NULL) {
 	if (reg == NULL) {
 		ret = -ENOMEM;
 		ret = -ENOMEM;
-		err("ioremap error.");
+		dev_err(&pdev->dev, "ioremap error.\n");
 		goto clean_up;
 		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);
 	hcd = usb_create_hcd(&r8a66597_hc_driver, &pdev->dev, (char *)hcd_name);
 	if (!hcd) {
 	if (!hcd) {
 		ret = -ENOMEM;
 		ret = -ENOMEM;
-		err("Failed to create hcd");
+		dev_err(&pdev->dev, "Failed to create hcd\n");
 		goto clean_up;
 		goto clean_up;
 	}
 	}
 	r8a66597 = hcd_to_r8a66597(hcd);
 	r8a66597 = hcd_to_r8a66597(hcd);
@@ -2329,13 +2337,33 @@ static int __init r8a66597_probe(struct platform_device *pdev)
 	INIT_LIST_HEAD(&r8a66597->child_device);
 	INIT_LIST_HEAD(&r8a66597->child_device);
 
 
 	hcd->rsrc_start = res->start;
 	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);
 	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger);
 	if (ret != 0) {
 	if (ret != 0) {
-		err("Failed to add hcd");
+		dev_err(&pdev->dev, "Failed to add hcd\n");
 		goto clean_up;
 		goto clean_up;
 	}
 	}
 
 
@@ -2364,7 +2392,8 @@ static int __init r8a66597_init(void)
 	if (usb_disabled())
 	if (usb_disabled())
 		return -ENODEV;
 		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);
 	return platform_driver_register(&r8a66597_driver);
 }
 }
 module_init(r8a66597_init);
 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 usb_hcd		*hcd;
 	struct sl811		*sl811;
 	struct sl811		*sl811;
-	struct resource		*addr, *data;
+	struct resource		*addr, *data, *ires;
 	int			irq;
 	int			irq;
 	void __iomem		*addr_reg;
 	void __iomem		*addr_reg;
 	void __iomem		*data_reg;
 	void __iomem		*data_reg;
 	int			retval;
 	int			retval;
 	u8			tmp, ioaddr = 0;
 	u8			tmp, ioaddr = 0;
+	unsigned long		irqflags;
 
 
 	/* basic sanity checks first.  board-specific init logic should
 	/* basic sanity checks first.  board-specific init logic should
 	 * have initialized these three resources and probably board
 	 * have initialized these three resources and probably board
 	 * specific platform_data.  we don't probe for IRQs, and do only
 	 * specific platform_data.  we don't probe for IRQs, and do only
 	 * minimal sanity checking.
 	 * 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;
 		return -ENODEV;
 
 
+	irq = ires->start;
+	irqflags = ires->flags & IRQF_TRIGGER_MASK;
+
 	/* refuse to confuse usbcore */
 	/* refuse to confuse usbcore */
 	if (dev->dev.dma_mask) {
 	if (dev->dev.dma_mask) {
 		DBG("no we won't dma\n");
 		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
 	 * triggers (e.g. most ARM CPUs).  Initial driver stress testing
 	 * was on a system with single edge triggering, so most sorts of
 	 * was on a system with single edge triggering, so most sorts of
 	 * triggering arrangement should work.
 	 * 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)
 	if (retval != 0)
 		goto err6;
 		goto err6;
 
 

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

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

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно