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

Merge 3.4-rc3 into tty-next

This allows us to pick up some changes needed for other serial patches.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Greg Kroah-Hartman 13 жил өмнө
parent
commit
665ab0f3c8
100 өөрчлөгдсөн 1432 нэмэгдсэн , 1148 устгасан
  1. 7 7
      Documentation/ABI/stable/sysfs-driver-usb-usbtmc
  2. 18 0
      Documentation/ABI/testing/sysfs-block-rssd
  3. 8 0
      Documentation/ABI/testing/sysfs-cfq-target-latency
  4. 2 3
      Documentation/cgroups/memory.txt
  5. 8 0
      Documentation/feature-removal-schedule.txt
  6. 1 1
      Documentation/filesystems/vfs.txt
  7. 3 1
      Documentation/sound/alsa/HD-Audio-Models.txt
  8. 22 0
      Documentation/usb/URB.txt
  9. 3 3
      Documentation/usb/usbmon.txt
  10. 13 8
      MAINTAINERS
  11. 1 1
      Makefile
  12. 1 67
      arch/alpha/include/asm/atomic.h
  13. 71 0
      arch/alpha/include/asm/cmpxchg.h
  14. 2 2
      arch/alpha/include/asm/xchg.h
  15. 2 0
      arch/arm/boot/compressed/atags_to_fdt.c
  16. 1 1
      arch/arm/boot/compressed/head.S
  17. 0 1
      arch/arm/boot/dts/at91sam9g20.dtsi
  18. 0 1
      arch/arm/boot/dts/at91sam9g45.dtsi
  19. 0 1
      arch/arm/boot/dts/at91sam9x5.dtsi
  20. 0 1
      arch/arm/boot/dts/db8500.dtsi
  21. 0 1
      arch/arm/boot/dts/highbank.dts
  22. 4 5
      arch/arm/common/vic.c
  23. 1 1
      arch/arm/include/asm/jump_label.h
  24. 15 1
      arch/arm/kernel/setup.c
  25. 5 1
      arch/arm/kernel/smp_twd.c
  26. 2 0
      arch/arm/mach-exynos/Kconfig
  27. 2 0
      arch/arm/mach-exynos/include/mach/irqs.h
  28. 4 0
      arch/arm/mach-exynos/include/mach/map.h
  29. 6 0
      arch/arm/mach-exynos/include/mach/regs-clock.h
  30. 1 1
      arch/arm/mach-exynos/mach-exynos5-dt.c
  31. 2 44
      arch/arm/mach-exynos/mach-nuri.c
  32. 2 0
      arch/arm/mach-exynos/mach-universal_c210.c
  33. 0 3
      arch/arm/mach-msm/board-halibut.c
  34. 1 0
      arch/arm/mach-msm/board-trout-panel.c
  35. 1 0
      arch/arm/mach-msm/board-trout.c
  36. 1 1
      arch/arm/mach-msm/proc_comm.c
  37. 0 80
      arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
  38. 0 5
      arch/arm/mach-omap2/clock.c
  39. 0 8
      arch/arm/mach-omap2/clock.h
  40. 0 2
      arch/arm/mach-s5pv210/dma.c
  41. 2 2
      arch/arm/mach-s5pv210/mach-aquila.c
  42. 2 2
      arch/arm/mach-s5pv210/mach-goni.c
  43. 1 1
      arch/arm/mm/Kconfig
  44. 1 1
      arch/arm/mm/fault.c
  45. 2 0
      arch/arm/mm/nommu.c
  46. 12 0
      arch/arm/mm/proc-v7.S
  47. 0 26
      arch/arm/plat-omap/clock.c
  48. 0 10
      arch/arm/plat-omap/include/plat/clock.h
  49. 1 0
      arch/arm/plat-samsung/Kconfig
  50. 0 4
      arch/c6x/include/asm/irq.h
  51. 0 13
      arch/c6x/kernel/irq.c
  52. 147 1
      arch/ia64/include/asm/cmpxchg.h
  53. 1 113
      arch/ia64/include/asm/intrinsics.h
  54. 0 2
      arch/powerpc/include/asm/irq.h
  55. 21 18
      arch/powerpc/kernel/entry_32.S
  56. 0 6
      arch/powerpc/kernel/irq.c
  57. 2 2
      arch/powerpc/kernel/process.c
  58. 1 1
      arch/powerpc/platforms/cell/axon_msi.c
  59. 1 1
      arch/powerpc/platforms/cell/beat_interrupt.c
  60. 1 1
      arch/powerpc/platforms/powermac/smp.c
  61. 1 2
      arch/powerpc/platforms/ps3/interrupt.c
  62. 1 1
      arch/sparc/kernel/ds.c
  63. 0 13
      arch/sparc/kernel/leon_pci.c
  64. 0 7
      arch/sparc/kernel/rtrap_64.S
  65. 30 7
      arch/sparc/mm/fault_32.c
  66. 30 7
      arch/sparc/mm/fault_64.c
  67. 1 3
      arch/tile/kernel/proc.c
  68. 2 0
      arch/tile/kernel/smpboot.c
  69. 0 35
      arch/um/drivers/cow.h
  70. 21 22
      arch/um/drivers/cow_user.c
  71. 1 0
      arch/um/drivers/mconsole_kern.c
  72. 2 1
      arch/um/include/asm/Kbuild
  73. 4 3
      arch/um/kernel/Makefile
  74. 1 5
      arch/um/kernel/process.c
  75. 0 1
      arch/um/kernel/skas/mmu.c
  76. 3 0
      arch/x86/Makefile.um
  77. 2 2
      arch/x86/include/asm/cmpxchg.h
  78. 2 0
      arch/x86/include/asm/uaccess.h
  79. 0 5
      arch/x86/include/asm/uaccess_32.h
  80. 0 4
      arch/x86/include/asm/uaccess_64.h
  81. 3 3
      arch/x86/kernel/vsyscall_64.c
  82. 103 0
      arch/x86/lib/usercopy.c
  83. 0 87
      arch/x86/lib/usercopy_32.c
  84. 0 49
      arch/x86/lib/usercopy_64.c
  85. 75 0
      arch/x86/um/asm/barrier.h
  86. 0 135
      arch/x86/um/asm/system.h
  87. 3 2
      block/blk-core.c
  88. 1 1
      block/blk-throttle.c
  89. 8 2
      block/cfq-iosched.c
  90. 3 3
      crypto/Kconfig
  91. 1 41
      drivers/amba/bus.c
  92. 1 3
      drivers/base/soc.c
  93. 1 1
      drivers/bcma/Kconfig
  94. 1 0
      drivers/bcma/driver_pci_host.c
  95. 2 1
      drivers/block/cciss_scsi.c
  96. 1 1
      drivers/block/mtip32xx/Kconfig
  97. 664 196
      drivers/block/mtip32xx/mtip32xx.c
  98. 45 13
      drivers/block/mtip32xx/mtip32xx.h
  99. 1 0
      drivers/block/virtio_blk.c
  100. 13 37
      drivers/block/xen-blkback/blkback.c

+ 7 - 7
Documentation/ABI/stable/sysfs-driver-usb-usbtmc

@@ -1,5 +1,5 @@
-What:		/sys/bus/usb/drivers/usbtmc/devices/*/interface_capabilities
-What:		/sys/bus/usb/drivers/usbtmc/devices/*/device_capabilities
+What:		/sys/bus/usb/drivers/usbtmc/*/interface_capabilities
+What:		/sys/bus/usb/drivers/usbtmc/*/device_capabilities
 Date:		August 2008
 Date:		August 2008
 Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
 Description:
@@ -12,8 +12,8 @@ Description:
 		The files are read only.
 		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
+What:		/sys/bus/usb/drivers/usbtmc/*/usb488_interface_capabilities
+What:		/sys/bus/usb/drivers/usbtmc/*/usb488_device_capabilities
 Date:		August 2008
 Date:		August 2008
 Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
 Description:
@@ -27,7 +27,7 @@ Description:
 		The files are read only.
 		The files are read only.
 
 
 
 
-What:		/sys/bus/usb/drivers/usbtmc/devices/*/TermChar
+What:		/sys/bus/usb/drivers/usbtmc/*/TermChar
 Date:		August 2008
 Date:		August 2008
 Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
 Description:
@@ -40,7 +40,7 @@ Description:
 		sent to the device or not.
 		sent to the device or not.
 
 
 
 
-What:		/sys/bus/usb/drivers/usbtmc/devices/*/TermCharEnabled
+What:		/sys/bus/usb/drivers/usbtmc/*/TermCharEnabled
 Date:		August 2008
 Date:		August 2008
 Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
 Description:
@@ -51,7 +51,7 @@ Description:
 		published by the USB-IF.
 		published by the USB-IF.
 
 
 
 
-What:		/sys/bus/usb/drivers/usbtmc/devices/*/auto_abort
+What:		/sys/bus/usb/drivers/usbtmc/*/auto_abort
 Date:		August 2008
 Date:		August 2008
 Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Contact:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
 Description:

+ 18 - 0
Documentation/ABI/testing/sysfs-block-rssd

@@ -0,0 +1,18 @@
+What:           /sys/block/rssd*/registers
+Date:           March 2012
+KernelVersion:  3.3
+Contact:        Asai Thambi S P <asamymuthupa@micron.com>
+Description:    This is a read-only file. Dumps below driver information and
+                hardware registers.
+                    - S ACTive
+                    - Command Issue
+                    - Allocated
+                    - Completed
+                    - PORT IRQ STAT
+                    - HOST IRQ STAT
+
+What:           /sys/block/rssd*/status
+Date:           April 2012
+KernelVersion:  3.4
+Contact:        Asai Thambi S P <asamymuthupa@micron.com>
+Description:   This is a read-only file. Indicates the status of the device.

+ 8 - 0
Documentation/ABI/testing/sysfs-cfq-target-latency

@@ -0,0 +1,8 @@
+What:		/sys/block/<device>/iosched/target_latency
+Date:		March 2012
+contact:	Tao Ma <boyu.mt@taobao.com>
+Description:
+		The /sys/block/<device>/iosched/target_latency only exists
+		when the user sets cfq to /sys/block/<device>/scheduler.
+		It contains an estimated latency time for the cfq. cfq will
+		use it to calculate the time slice used for every task.

+ 2 - 3
Documentation/cgroups/memory.txt

@@ -34,8 +34,7 @@ Current Status: linux-2.6.34-mmotm(development version of 2010/April)
 
 
 Features:
 Features:
  - accounting anonymous pages, file caches, swap caches usage and limiting them.
  - accounting anonymous pages, file caches, swap caches usage and limiting them.
- - private LRU and reclaim routine. (system's global LRU and private LRU
-   work independently from each other)
+ - pages are linked to per-memcg LRU exclusively, and there is no global LRU.
  - optionally, memory+swap usage can be accounted and limited.
  - optionally, memory+swap usage can be accounted and limited.
  - hierarchical accounting
  - hierarchical accounting
  - soft limit
  - soft limit
@@ -154,7 +153,7 @@ updated. page_cgroup has its own LRU on cgroup.
 2.2.1 Accounting details
 2.2.1 Accounting details
 
 
 All mapped anon pages (RSS) and cache pages (Page Cache) are accounted.
 All mapped anon pages (RSS) and cache pages (Page Cache) are accounted.
-Some pages which are never reclaimable and will not be on the global LRU
+Some pages which are never reclaimable and will not be on the LRU
 are not accounted. We just account pages under usual VM management.
 are not accounted. We just account pages under usual VM management.
 
 
 RSS pages are accounted at page_fault unless they've already been accounted
 RSS pages are accounted at page_fault unless they've already been accounted

+ 8 - 0
Documentation/feature-removal-schedule.txt

@@ -531,3 +531,11 @@ Why:	There appear to be no production users of the get_robust_list syscall,
 	of ASLR. It was only ever intended for debugging, so it should be
 	of ASLR. It was only ever intended for debugging, so it should be
 	removed.
 	removed.
 Who:	Kees Cook <keescook@chromium.org>
 Who:	Kees Cook <keescook@chromium.org>
+
+----------------------------
+
+What:	setitimer accepts user NULL pointer (value)
+When:	3.6
+Why:	setitimer is not returning -EFAULT if user pointer is NULL. This
+	violates the spec.
+Who:	Sasikantha Babu <sasikanth.v19@gmail.com>

+ 1 - 1
Documentation/filesystems/vfs.txt

@@ -114,7 +114,7 @@ members are defined:
 struct file_system_type {
 struct file_system_type {
 	const char *name;
 	const char *name;
 	int fs_flags;
 	int fs_flags;
-        struct dentry (*mount) (struct file_system_type *, int,
+        struct dentry *(*mount) (struct file_system_type *, int,
                        const char *, void *);
                        const char *, void *);
         void (*kill_sb) (struct super_block *);
         void (*kill_sb) (struct super_block *);
         struct module *owner;
         struct module *owner;

+ 3 - 1
Documentation/sound/alsa/HD-Audio-Models.txt

@@ -43,7 +43,9 @@ ALC680
 
 
 ALC882/883/885/888/889
 ALC882/883/885/888/889
 ======================
 ======================
-  N/A
+  acer-aspire-4930g	Acer Aspire 4930G/5930G/6530G/6930G/7730G
+  acer-aspire-8930g	Acer Aspire 8330G/6935G
+  acer-aspire		Acer Aspire others
 
 
 ALC861/660
 ALC861/660
 ==========
 ==========

+ 22 - 0
Documentation/usb/URB.txt

@@ -168,6 +168,28 @@ that if the completion handler or anyone else tries to resubmit it
 they will get a -EPERM error.  Thus you can be sure that when
 they will get a -EPERM error.  Thus you can be sure that when
 usb_kill_urb() returns, the URB is totally idle.
 usb_kill_urb() returns, the URB is totally idle.
 
 
+There is a lifetime issue to consider.  An URB may complete at any
+time, and the completion handler may free the URB.  If this happens
+while usb_unlink_urb or usb_kill_urb is running, it will cause a
+memory-access violation.  The driver is responsible for avoiding this,
+which often means some sort of lock will be needed to prevent the URB
+from being deallocated while it is still in use.
+
+On the other hand, since usb_unlink_urb may end up calling the
+completion handler, the handler must not take any lock that is held
+when usb_unlink_urb is invoked.  The general solution to this problem
+is to increment the URB's reference count while holding the lock, then
+drop the lock and call usb_unlink_urb or usb_kill_urb, and then
+decrement the URB's reference count.  You increment the reference
+count by calling
+
+	struct urb *usb_get_urb(struct urb *urb)
+
+(ignore the return value; it is the same as the argument) and
+decrement the reference count by calling usb_free_urb.  Of course,
+none of this is necessary if there's no danger of the URB being freed
+by the completion handler.
+
 
 
 1.7. What about the completion handler?
 1.7. What about the completion handler?
 
 

+ 3 - 3
Documentation/usb/usbmon.txt

@@ -183,10 +183,10 @@ An input control transfer to get a port status.
 d5ea89a0 3575914555 S Ci:1:001:0 s a3 00 0000 0003 0004 4 <
 d5ea89a0 3575914555 S Ci:1:001:0 s a3 00 0000 0003 0004 4 <
 d5ea89a0 3575914560 C Ci:1:001:0 0 4 = 01050000
 d5ea89a0 3575914560 C Ci:1:001:0 0 4 = 01050000
 
 
-An output bulk transfer to send a SCSI command 0x5E in a 31-byte Bulk wrapper
-to a storage device at address 5:
+An output bulk transfer to send a SCSI command 0x28 (READ_10) in a 31-byte
+Bulk wrapper to a storage device at address 5:
 
 
-dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 5e000000 00000000 00000600 00000000 00000000 00000000 000000
+dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 ad000000 00800000 80010a28 20000000 20000040 00000000 000000
 dd65f0e8 4128379808 C Bo:1:005:2 0 31 >
 dd65f0e8 4128379808 C Bo:1:005:2 0 31 >
 
 
 * Raw binary format and API
 * Raw binary format and API

+ 13 - 8
MAINTAINERS

@@ -1521,8 +1521,8 @@ M:	Gustavo Padovan <gustavo@padovan.org>
 M:	Johan Hedberg <johan.hedberg@gmail.com>
 M:	Johan Hedberg <johan.hedberg@gmail.com>
 L:	linux-bluetooth@vger.kernel.org
 L:	linux-bluetooth@vger.kernel.org
 W:	http://www.bluez.org/
 W:	http://www.bluez.org/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth.git
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jh/bluetooth.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git
 S:	Maintained
 S:	Maintained
 F:	drivers/bluetooth/
 F:	drivers/bluetooth/
 
 
@@ -1532,8 +1532,8 @@ M:	Gustavo Padovan <gustavo@padovan.org>
 M:	Johan Hedberg <johan.hedberg@gmail.com>
 M:	Johan Hedberg <johan.hedberg@gmail.com>
 L:	linux-bluetooth@vger.kernel.org
 L:	linux-bluetooth@vger.kernel.org
 W:	http://www.bluez.org/
 W:	http://www.bluez.org/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth.git
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jh/bluetooth.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git
 S:	Maintained
 S:	Maintained
 F:	net/bluetooth/
 F:	net/bluetooth/
 F:	include/net/bluetooth/
 F:	include/net/bluetooth/
@@ -4533,8 +4533,7 @@ S:	Supported
 F:	drivers/net/ethernet/myricom/myri10ge/
 F:	drivers/net/ethernet/myricom/myri10ge/
 
 
 NATSEMI ETHERNET DRIVER (DP8381x)
 NATSEMI ETHERNET DRIVER (DP8381x)
-M:	Tim Hockin <thockin@hockin.org>
-S:	Maintained
+S:	Orphan
 F:	drivers/net/ethernet/natsemi/natsemi.c
 F:	drivers/net/ethernet/natsemi/natsemi.c
 
 
 NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER
 NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER
@@ -4803,6 +4802,7 @@ F:	arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
 F:	arch/arm/mach-omap2/clockdomain44xx.c
 F:	arch/arm/mach-omap2/clockdomain44xx.c
 
 
 OMAP AUDIO SUPPORT
 OMAP AUDIO SUPPORT
+M:	Peter Ujfalusi <peter.ujfalusi@ti.com>
 M:	Jarkko Nikula <jarkko.nikula@bitmer.com>
 M:	Jarkko Nikula <jarkko.nikula@bitmer.com>
 L:	alsa-devel@alsa-project.org (subscribers-only)
 L:	alsa-devel@alsa-project.org (subscribers-only)
 L:	linux-omap@vger.kernel.org
 L:	linux-omap@vger.kernel.org
@@ -5117,6 +5117,11 @@ F:	drivers/i2c/busses/i2c-pca-*
 F:	include/linux/i2c-algo-pca.h
 F:	include/linux/i2c-algo-pca.h
 F:	include/linux/i2c-pca-platform.h
 F:	include/linux/i2c-pca-platform.h
 
 
+PCDP - PRIMARY CONSOLE AND DEBUG PORT
+M:	Khalid Aziz <khalid.aziz@hp.com>
+S:	Maintained
+F:	drivers/firmware/pcdp.*
+
 PCI ERROR RECOVERY
 PCI ERROR RECOVERY
 M:     Linas Vepstas <linasvepstas@gmail.com>
 M:     Linas Vepstas <linasvepstas@gmail.com>
 L:	linux-pci@vger.kernel.org
 L:	linux-pci@vger.kernel.org
@@ -6466,6 +6471,7 @@ S:	Odd Fixes
 F:	drivers/staging/olpc_dcon/
 F:	drivers/staging/olpc_dcon/
 
 
 STAGING - OZMO DEVICES USB OVER WIFI DRIVER
 STAGING - OZMO DEVICES USB OVER WIFI DRIVER
+M:	Rupesh Gujare <rgujare@ozmodevices.com>
 M:	Chris Kelly <ckelly@ozmodevices.com>
 M:	Chris Kelly <ckelly@ozmodevices.com>
 S:	Maintained
 S:	Maintained
 F:	drivers/staging/ozwpan/
 F:	drivers/staging/ozwpan/
@@ -7461,8 +7467,7 @@ F:	include/linux/wm97xx.h
 
 
 WOLFSON MICROELECTRONICS DRIVERS
 WOLFSON MICROELECTRONICS DRIVERS
 M:	Mark Brown <broonie@opensource.wolfsonmicro.com>
 M:	Mark Brown <broonie@opensource.wolfsonmicro.com>
-M:	Ian Lartey <ian@opensource.wolfsonmicro.com>
-M:	Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
+L:	patches@opensource.wolfsonmicro.com
 T:	git git://opensource.wolfsonmicro.com/linux-2.6-asoc
 T:	git git://opensource.wolfsonmicro.com/linux-2.6-asoc
 T:	git git://opensource.wolfsonmicro.com/linux-2.6-audioplus
 T:	git git://opensource.wolfsonmicro.com/linux-2.6-audioplus
 W:	http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices
 W:	http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices

+ 1 - 1
Makefile

@@ -1,7 +1,7 @@
 VERSION = 3
 VERSION = 3
 PATCHLEVEL = 4
 PATCHLEVEL = 4
 SUBLEVEL = 0
 SUBLEVEL = 0
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc3
 NAME = Saber-toothed Squirrel
 NAME = Saber-toothed Squirrel
 
 
 # *DOCUMENTATION*
 # *DOCUMENTATION*

+ 1 - 67
arch/alpha/include/asm/atomic.h

@@ -3,6 +3,7 @@
 
 
 #include <linux/types.h>
 #include <linux/types.h>
 #include <asm/barrier.h>
 #include <asm/barrier.h>
+#include <asm/cmpxchg.h>
 
 
 /*
 /*
  * Atomic operations that C can't guarantee us.  Useful for
  * Atomic operations that C can't guarantee us.  Useful for
@@ -168,73 +169,6 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
 	return result;
 	return result;
 }
 }
 
 
-/*
- * Atomic exchange routines.
- */
-
-#define __ASM__MB
-#define ____xchg(type, args...)		__xchg ## type ## _local(args)
-#define ____cmpxchg(type, args...)	__cmpxchg ## type ## _local(args)
-#include <asm/xchg.h>
-
-#define xchg_local(ptr,x)						\
-  ({									\
-     __typeof__(*(ptr)) _x_ = (x);					\
-     (__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_,	\
-				       sizeof(*(ptr)));			\
-  })
-
-#define cmpxchg_local(ptr, o, n)					\
-  ({									\
-     __typeof__(*(ptr)) _o_ = (o);					\
-     __typeof__(*(ptr)) _n_ = (n);					\
-     (__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_,	\
-					  (unsigned long)_n_,		\
-					  sizeof(*(ptr)));		\
-  })
-
-#define cmpxchg64_local(ptr, o, n)					\
-  ({									\
-	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
-	cmpxchg_local((ptr), (o), (n));					\
-  })
-
-#ifdef CONFIG_SMP
-#undef __ASM__MB
-#define __ASM__MB	"\tmb\n"
-#endif
-#undef ____xchg
-#undef ____cmpxchg
-#define ____xchg(type, args...)		__xchg ##type(args)
-#define ____cmpxchg(type, args...)	__cmpxchg ##type(args)
-#include <asm/xchg.h>
-
-#define xchg(ptr,x)							\
-  ({									\
-     __typeof__(*(ptr)) _x_ = (x);					\
-     (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_,		\
-				 sizeof(*(ptr)));			\
-  })
-
-#define cmpxchg(ptr, o, n)						\
-  ({									\
-     __typeof__(*(ptr)) _o_ = (o);					\
-     __typeof__(*(ptr)) _n_ = (n);					\
-     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,		\
-				    (unsigned long)_n_,	sizeof(*(ptr)));\
-  })
-
-#define cmpxchg64(ptr, o, n)						\
-  ({									\
-	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
-	cmpxchg((ptr), (o), (n));					\
-  })
-
-#undef __ASM__MB
-#undef ____cmpxchg
-
-#define __HAVE_ARCH_CMPXCHG 1
-
 #define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
 #define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
 #define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
 #define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
 
 

+ 71 - 0
arch/alpha/include/asm/cmpxchg.h

@@ -0,0 +1,71 @@
+#ifndef _ALPHA_CMPXCHG_H
+#define _ALPHA_CMPXCHG_H
+
+/*
+ * Atomic exchange routines.
+ */
+
+#define __ASM__MB
+#define ____xchg(type, args...)		__xchg ## type ## _local(args)
+#define ____cmpxchg(type, args...)	__cmpxchg ## type ## _local(args)
+#include <asm/xchg.h>
+
+#define xchg_local(ptr, x)						\
+({									\
+	__typeof__(*(ptr)) _x_ = (x);					\
+	(__typeof__(*(ptr))) __xchg_local((ptr), (unsigned long)_x_,	\
+				       sizeof(*(ptr)));			\
+})
+
+#define cmpxchg_local(ptr, o, n)					\
+({									\
+	__typeof__(*(ptr)) _o_ = (o);					\
+	__typeof__(*(ptr)) _n_ = (n);					\
+	(__typeof__(*(ptr))) __cmpxchg_local((ptr), (unsigned long)_o_,	\
+					  (unsigned long)_n_,		\
+					  sizeof(*(ptr)));		\
+})
+
+#define cmpxchg64_local(ptr, o, n)					\
+({									\
+	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
+	cmpxchg_local((ptr), (o), (n));					\
+})
+
+#ifdef CONFIG_SMP
+#undef __ASM__MB
+#define __ASM__MB	"\tmb\n"
+#endif
+#undef ____xchg
+#undef ____cmpxchg
+#define ____xchg(type, args...)		__xchg ##type(args)
+#define ____cmpxchg(type, args...)	__cmpxchg ##type(args)
+#include <asm/xchg.h>
+
+#define xchg(ptr, x)							\
+({									\
+	__typeof__(*(ptr)) _x_ = (x);					\
+	(__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_,		\
+				 sizeof(*(ptr)));			\
+})
+
+#define cmpxchg(ptr, o, n)						\
+({									\
+	__typeof__(*(ptr)) _o_ = (o);					\
+	__typeof__(*(ptr)) _n_ = (n);					\
+	(__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,	\
+				    (unsigned long)_n_,	sizeof(*(ptr)));\
+})
+
+#define cmpxchg64(ptr, o, n)						\
+({									\
+	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
+	cmpxchg((ptr), (o), (n));					\
+})
+
+#undef __ASM__MB
+#undef ____cmpxchg
+
+#define __HAVE_ARCH_CMPXCHG 1
+
+#endif /* _ALPHA_CMPXCHG_H */

+ 2 - 2
arch/alpha/include/asm/xchg.h

@@ -1,10 +1,10 @@
-#ifndef _ALPHA_ATOMIC_H
+#ifndef _ALPHA_CMPXCHG_H
 #error Do not include xchg.h directly!
 #error Do not include xchg.h directly!
 #else
 #else
 /*
 /*
  * xchg/xchg_local and cmpxchg/cmpxchg_local share the same code
  * xchg/xchg_local and cmpxchg/cmpxchg_local share the same code
  * except that local version do not have the expensive memory barrier.
  * except that local version do not have the expensive memory barrier.
- * So this file is included twice from asm/system.h.
+ * So this file is included twice from asm/cmpxchg.h.
  */
  */
 
 
 /*
 /*

+ 2 - 0
arch/arm/boot/compressed/atags_to_fdt.c

@@ -77,6 +77,8 @@ int atags_to_fdt(void *atag_list, void *fdt, int total_space)
 		} else if (atag->hdr.tag == ATAG_MEM) {
 		} else if (atag->hdr.tag == ATAG_MEM) {
 			if (memcount >= sizeof(mem_reg_property)/4)
 			if (memcount >= sizeof(mem_reg_property)/4)
 				continue;
 				continue;
+			if (!atag->u.mem.size)
+				continue;
 			mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start);
 			mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.start);
 			mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size);
 			mem_reg_property[memcount++] = cpu_to_fdt32(atag->u.mem.size);
 		} else if (atag->hdr.tag == ATAG_INITRD2) {
 		} else if (atag->hdr.tag == ATAG_INITRD2) {

+ 1 - 1
arch/arm/boot/compressed/head.S

@@ -273,7 +273,7 @@ restart:	adr	r0, LC0
 		add	r0, r0, #0x100
 		add	r0, r0, #0x100
 		mov	r1, r6
 		mov	r1, r6
 		sub	r2, sp, r6
 		sub	r2, sp, r6
-		blne	atags_to_fdt
+		bleq	atags_to_fdt
 
 
 		ldmfd	sp!, {r0-r3, ip, lr}
 		ldmfd	sp!, {r0-r3, ip, lr}
 		sub	sp, sp, #0x10000
 		sub	sp, sp, #0x10000

+ 0 - 1
arch/arm/boot/dts/at91sam9g20.dtsi

@@ -55,7 +55,6 @@
 				#interrupt-cells = <2>;
 				#interrupt-cells = <2>;
 				compatible = "atmel,at91rm9200-aic";
 				compatible = "atmel,at91rm9200-aic";
 				interrupt-controller;
 				interrupt-controller;
-				interrupt-parent;
 				reg = <0xfffff000 0x200>;
 				reg = <0xfffff000 0x200>;
 			};
 			};
 
 

+ 0 - 1
arch/arm/boot/dts/at91sam9g45.dtsi

@@ -56,7 +56,6 @@
 				#interrupt-cells = <2>;
 				#interrupt-cells = <2>;
 				compatible = "atmel,at91rm9200-aic";
 				compatible = "atmel,at91rm9200-aic";
 				interrupt-controller;
 				interrupt-controller;
-				interrupt-parent;
 				reg = <0xfffff000 0x200>;
 				reg = <0xfffff000 0x200>;
 			};
 			};
 
 

+ 0 - 1
arch/arm/boot/dts/at91sam9x5.dtsi

@@ -54,7 +54,6 @@
 				#interrupt-cells = <2>;
 				#interrupt-cells = <2>;
 				compatible = "atmel,at91rm9200-aic";
 				compatible = "atmel,at91rm9200-aic";
 				interrupt-controller;
 				interrupt-controller;
-				interrupt-parent;
 				reg = <0xfffff000 0x200>;
 				reg = <0xfffff000 0x200>;
 			};
 			};
 
 

+ 0 - 1
arch/arm/boot/dts/db8500.dtsi

@@ -24,7 +24,6 @@
 			#interrupt-cells = <3>;
 			#interrupt-cells = <3>;
 			#address-cells = <1>;
 			#address-cells = <1>;
 			interrupt-controller;
 			interrupt-controller;
-			interrupt-parent;
 			reg = <0xa0411000 0x1000>,
 			reg = <0xa0411000 0x1000>,
 			      <0xa0410100 0x100>;
 			      <0xa0410100 0x100>;
 		};
 		};

+ 0 - 1
arch/arm/boot/dts/highbank.dts

@@ -89,7 +89,6 @@
 			#size-cells = <0>;
 			#size-cells = <0>;
 			#address-cells = <1>;
 			#address-cells = <1>;
 			interrupt-controller;
 			interrupt-controller;
-			interrupt-parent;
 			reg = <0xfff11000 0x1000>,
 			reg = <0xfff11000 0x1000>,
 			      <0xfff10100 0x100>;
 			      <0xfff10100 0x100>;
 		};
 		};

+ 4 - 5
arch/arm/common/vic.c

@@ -427,19 +427,18 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent)
 
 
 /*
 /*
  * Handle each interrupt in a single VIC.  Returns non-zero if we've
  * Handle each interrupt in a single VIC.  Returns non-zero if we've
- * handled at least one interrupt.  This does a single read of the
- * status register and handles all interrupts in order from LSB first.
+ * handled at least one interrupt.  This reads the status register
+ * before handling each interrupt, which is necessary given that
+ * handle_IRQ may briefly re-enable interrupts for soft IRQ handling.
  */
  */
 static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs)
 static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs)
 {
 {
 	u32 stat, irq;
 	u32 stat, irq;
 	int handled = 0;
 	int handled = 0;
 
 
-	stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
-	while (stat) {
+	while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) {
 		irq = ffs(stat) - 1;
 		irq = ffs(stat) - 1;
 		handle_IRQ(irq_find_mapping(vic->domain, irq), regs);
 		handle_IRQ(irq_find_mapping(vic->domain, irq), regs);
-		stat &= ~(1 << irq);
 		handled = 1;
 		handled = 1;
 	}
 	}
 
 

+ 1 - 1
arch/arm/include/asm/jump_label.h

@@ -14,7 +14,7 @@
 #define JUMP_LABEL_NOP	"nop"
 #define JUMP_LABEL_NOP	"nop"
 #endif
 #endif
 
 
-static __always_inline bool arch_static_branch(struct jump_label_key *key)
+static __always_inline bool arch_static_branch(struct static_key *key)
 {
 {
 	asm goto("1:\n\t"
 	asm goto("1:\n\t"
 		 JUMP_LABEL_NOP "\n\t"
 		 JUMP_LABEL_NOP "\n\t"

+ 15 - 1
arch/arm/kernel/setup.c

@@ -523,7 +523,21 @@ int __init arm_add_memory(phys_addr_t start, unsigned long size)
 	 */
 	 */
 	size -= start & ~PAGE_MASK;
 	size -= start & ~PAGE_MASK;
 	bank->start = PAGE_ALIGN(start);
 	bank->start = PAGE_ALIGN(start);
-	bank->size  = size & PAGE_MASK;
+
+#ifndef CONFIG_LPAE
+	if (bank->start + size < bank->start) {
+		printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in "
+			"32-bit physical address space\n", (long long)start);
+		/*
+		 * To ensure bank->start + bank->size is representable in
+		 * 32 bits, we use ULONG_MAX as the upper limit rather than 4GB.
+		 * This means we lose a page after masking.
+		 */
+		size = ULONG_MAX - bank->start;
+	}
+#endif
+
+	bank->size = size & PAGE_MASK;
 
 
 	/*
 	/*
 	 * Check whether this memory region has non-zero size or
 	 * Check whether this memory region has non-zero size or

+ 5 - 1
arch/arm/kernel/smp_twd.c

@@ -118,10 +118,14 @@ static int twd_cpufreq_transition(struct notifier_block *nb,
 	 * The twd clock events must be reprogrammed to account for the new
 	 * The twd clock events must be reprogrammed to account for the new
 	 * frequency.  The timer is local to a cpu, so cross-call to the
 	 * frequency.  The timer is local to a cpu, so cross-call to the
 	 * changing cpu.
 	 * changing cpu.
+	 *
+	 * Only wait for it to finish, if the cpu is active to avoid
+	 * deadlock when cpu1 is spinning on while(!cpu_active(cpu1)) during
+	 * booting of that cpu.
 	 */
 	 */
 	if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE)
 	if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE)
 		smp_call_function_single(freqs->cpu, twd_update_frequency,
 		smp_call_function_single(freqs->cpu, twd_update_frequency,
-			NULL, 1);
+					 NULL, cpu_active(freqs->cpu));
 
 
 	return NOTIFY_OK;
 	return NOTIFY_OK;
 }
 }

+ 2 - 0
arch/arm/mach-exynos/Kconfig

@@ -368,6 +368,7 @@ comment "Flattened Device Tree based board for EXYNOS SoCs"
 
 
 config MACH_EXYNOS4_DT
 config MACH_EXYNOS4_DT
 	bool "Samsung Exynos4 Machine using device tree"
 	bool "Samsung Exynos4 Machine using device tree"
+	depends on ARCH_EXYNOS4
 	select CPU_EXYNOS4210
 	select CPU_EXYNOS4210
 	select USE_OF
 	select USE_OF
 	select ARM_AMBA
 	select ARM_AMBA
@@ -380,6 +381,7 @@ config MACH_EXYNOS4_DT
 
 
 config MACH_EXYNOS5_DT
 config MACH_EXYNOS5_DT
 	bool "SAMSUNG EXYNOS5 Machine using device tree"
 	bool "SAMSUNG EXYNOS5 Machine using device tree"
+	depends on ARCH_EXYNOS5
 	select SOC_EXYNOS5250
 	select SOC_EXYNOS5250
 	select USE_OF
 	select USE_OF
 	select ARM_AMBA
 	select ARM_AMBA

+ 2 - 0
arch/arm/mach-exynos/include/mach/irqs.h

@@ -212,6 +212,8 @@
 #define IRQ_MFC				EXYNOS4_IRQ_MFC
 #define IRQ_MFC				EXYNOS4_IRQ_MFC
 #define IRQ_SDO				EXYNOS4_IRQ_SDO
 #define IRQ_SDO				EXYNOS4_IRQ_SDO
 
 
+#define IRQ_I2S0			EXYNOS4_IRQ_I2S0
+
 #define IRQ_ADC				EXYNOS4_IRQ_ADC0
 #define IRQ_ADC				EXYNOS4_IRQ_ADC0
 #define IRQ_TC				EXYNOS4_IRQ_PEN0
 #define IRQ_TC				EXYNOS4_IRQ_PEN0
 
 

+ 4 - 0
arch/arm/mach-exynos/include/mach/map.h

@@ -89,6 +89,10 @@
 #define EXYNOS4_PA_MDMA1		0x12840000
 #define EXYNOS4_PA_MDMA1		0x12840000
 #define EXYNOS4_PA_PDMA0		0x12680000
 #define EXYNOS4_PA_PDMA0		0x12680000
 #define EXYNOS4_PA_PDMA1		0x12690000
 #define EXYNOS4_PA_PDMA1		0x12690000
+#define EXYNOS5_PA_MDMA0		0x10800000
+#define EXYNOS5_PA_MDMA1		0x11C10000
+#define EXYNOS5_PA_PDMA0		0x121A0000
+#define EXYNOS5_PA_PDMA1		0x121B0000
 
 
 #define EXYNOS4_PA_SYSMMU_MDMA		0x10A40000
 #define EXYNOS4_PA_SYSMMU_MDMA		0x10A40000
 #define EXYNOS4_PA_SYSMMU_SSS		0x10A50000
 #define EXYNOS4_PA_SYSMMU_SSS		0x10A50000

+ 6 - 0
arch/arm/mach-exynos/include/mach/regs-clock.h

@@ -255,9 +255,15 @@
 
 
 /* For EXYNOS5250 */
 /* For EXYNOS5250 */
 
 
+#define EXYNOS5_APLL_LOCK			EXYNOS_CLKREG(0x00000)
 #define EXYNOS5_APLL_CON0			EXYNOS_CLKREG(0x00100)
 #define EXYNOS5_APLL_CON0			EXYNOS_CLKREG(0x00100)
 #define EXYNOS5_CLKSRC_CPU			EXYNOS_CLKREG(0x00200)
 #define EXYNOS5_CLKSRC_CPU			EXYNOS_CLKREG(0x00200)
+#define EXYNOS5_CLKMUX_STATCPU			EXYNOS_CLKREG(0x00400)
 #define EXYNOS5_CLKDIV_CPU0			EXYNOS_CLKREG(0x00500)
 #define EXYNOS5_CLKDIV_CPU0			EXYNOS_CLKREG(0x00500)
+#define EXYNOS5_CLKDIV_CPU1			EXYNOS_CLKREG(0x00504)
+#define EXYNOS5_CLKDIV_STATCPU0			EXYNOS_CLKREG(0x00600)
+#define EXYNOS5_CLKDIV_STATCPU1			EXYNOS_CLKREG(0x00604)
+
 #define EXYNOS5_MPLL_CON0			EXYNOS_CLKREG(0x04100)
 #define EXYNOS5_MPLL_CON0			EXYNOS_CLKREG(0x04100)
 #define EXYNOS5_CLKSRC_CORE1			EXYNOS_CLKREG(0x04204)
 #define EXYNOS5_CLKSRC_CORE1			EXYNOS_CLKREG(0x04204)
 
 

+ 1 - 1
arch/arm/mach-exynos/mach-exynos5-dt.c

@@ -45,7 +45,7 @@ static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
 				"exynos4210-uart.3", NULL),
 				"exynos4210-uart.3", NULL),
 	OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL),
 	OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL),
 	OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL),
 	OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL),
-	OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.2", NULL),
+	OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL),
 	{},
 	{},
 };
 };
 
 

+ 2 - 44
arch/arm/mach-exynos/mach-nuri.c

@@ -307,49 +307,7 @@ static struct i2c_board_info i2c1_devs[] __initdata = {
 };
 };
 
 
 /* TSP */
 /* TSP */
-static u8 mxt_init_vals[] = {
-	/* MXT_GEN_COMMAND(6) */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	/* MXT_GEN_POWER(7) */
-	0x20, 0xff, 0x32,
-	/* MXT_GEN_ACQUIRE(8) */
-	0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23,
-	/* MXT_TOUCH_MULTI(9) */
-	0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00,
-	0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00,
-	/* MXT_TOUCH_KEYARRAY(15) */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
-	0x00,
-	/* MXT_SPT_GPIOPWM(19) */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	/* MXT_PROCI_GRIPFACE(20) */
-	0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04,
-	0x0f, 0x0a,
-	/* MXT_PROCG_NOISE(22) */
-	0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00,
-	0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03,
-	/* MXT_TOUCH_PROXIMITY(23) */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00,
-	/* MXT_PROCI_ONETOUCH(24) */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	/* MXT_SPT_SELFTEST(25) */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00,
-	/* MXT_PROCI_TWOTOUCH(27) */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	/* MXT_SPT_CTECONFIG(28) */
-	0x00, 0x00, 0x02, 0x08, 0x10, 0x00,
-};
-
 static struct mxt_platform_data mxt_platform_data = {
 static struct mxt_platform_data mxt_platform_data = {
-	.config			= mxt_init_vals,
-	.config_length		= ARRAY_SIZE(mxt_init_vals),
-
 	.x_line			= 18,
 	.x_line			= 18,
 	.y_line			= 11,
 	.y_line			= 11,
 	.x_size			= 1024,
 	.x_size			= 1024,
@@ -571,7 +529,7 @@ static struct regulator_init_data __initdata max8997_ldo7_data = {
 
 
 static struct regulator_init_data __initdata max8997_ldo8_data = {
 static struct regulator_init_data __initdata max8997_ldo8_data = {
 	.constraints	= {
 	.constraints	= {
-		.name		= "VUSB/VDAC_3.3V_C210",
+		.name		= "VUSB+VDAC_3.3V_C210",
 		.min_uV		= 3300000,
 		.min_uV		= 3300000,
 		.max_uV		= 3300000,
 		.max_uV		= 3300000,
 		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
 		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
@@ -1347,6 +1305,7 @@ static struct platform_device *nuri_devices[] __initdata = {
 
 
 static void __init nuri_map_io(void)
 static void __init nuri_map_io(void)
 {
 {
+	clk_xusbxti.rate = 24000000;
 	exynos_init_io(NULL, 0);
 	exynos_init_io(NULL, 0);
 	s3c24xx_init_clocks(24000000);
 	s3c24xx_init_clocks(24000000);
 	s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
 	s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
@@ -1379,7 +1338,6 @@ static void __init nuri_machine_init(void)
 	nuri_camera_init();
 	nuri_camera_init();
 
 
 	nuri_ehci_init();
 	nuri_ehci_init();
-	clk_xusbxti.rate = 24000000;
 
 
 	/* Last */
 	/* Last */
 	platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
 	platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));

+ 2 - 0
arch/arm/mach-exynos/mach-universal_c210.c

@@ -29,6 +29,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
 
 
 #include <plat/regs-serial.h>
 #include <plat/regs-serial.h>
+#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/devs.h>
 #include <plat/iic.h>
 #include <plat/iic.h>
@@ -1057,6 +1058,7 @@ static struct platform_device *universal_devices[] __initdata = {
 
 
 static void __init universal_map_io(void)
 static void __init universal_map_io(void)
 {
 {
+	clk_xusbxti.rate = 24000000;
 	exynos_init_io(NULL, 0);
 	exynos_init_io(NULL, 0);
 	s3c24xx_init_clocks(24000000);
 	s3c24xx_init_clocks(24000000);
 	s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
 	s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));

+ 0 - 3
arch/arm/mach-msm/board-halibut.c

@@ -86,9 +86,6 @@ static void __init halibut_init(void)
 static void __init halibut_fixup(struct tag *tags, char **cmdline,
 static void __init halibut_fixup(struct tag *tags, char **cmdline,
 				 struct meminfo *mi)
 				 struct meminfo *mi)
 {
 {
-	mi->nr_banks=1;
-	mi->bank[0].start = PHYS_OFFSET;
-	mi->bank[0].size = (101*1024*1024);
 }
 }
 
 
 static void __init halibut_map_io(void)
 static void __init halibut_map_io(void)

+ 1 - 0
arch/arm/mach-msm/board-trout-panel.c

@@ -12,6 +12,7 @@
 
 
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
+#include <asm/system_info.h>
 
 
 #include <mach/msm_fb.h>
 #include <mach/msm_fb.h>
 #include <mach/vreg.h>
 #include <mach/vreg.h>

+ 1 - 0
arch/arm/mach-msm/board-trout.c

@@ -19,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/clkdev.h>
 #include <linux/clkdev.h>
 
 
+#include <asm/system_info.h>
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/map.h>

+ 1 - 1
arch/arm/mach-msm/proc_comm.c

@@ -121,7 +121,7 @@ int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2)
  * and unknown state. This function should be called early to
  * and unknown state. This function should be called early to
  * wait on the ARM9.
  * wait on the ARM9.
  */
  */
-void __init proc_comm_boot_wait(void)
+void __devinit proc_comm_boot_wait(void)
 {
 {
 	void __iomem *base = MSM_SHARED_RAM_BASE;
 	void __iomem *base = MSM_SHARED_RAM_BASE;
  
  

+ 0 - 80
arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c

@@ -165,83 +165,3 @@ int omap2_select_table_rate(struct clk *clk, unsigned long rate)
 
 
 	return 0;
 	return 0;
 }
 }
-
-#ifdef CONFIG_CPU_FREQ
-/*
- * Walk PRCM rate table and fillout cpufreq freq_table
- * XXX This should be replaced by an OPP layer in the near future
- */
-static struct cpufreq_frequency_table *freq_table;
-
-void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
-{
-	const struct prcm_config *prcm;
-	int i = 0;
-	int tbl_sz = 0;
-
-	if (!cpu_is_omap24xx())
-		return;
-
-	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
-		if (!(prcm->flags & cpu_mask))
-			continue;
-		if (prcm->xtal_speed != sclk->rate)
-			continue;
-
-		/* don't put bypass rates in table */
-		if (prcm->dpll_speed == prcm->xtal_speed)
-			continue;
-
-		tbl_sz++;
-	}
-
-	/*
-	 * XXX Ensure that we're doing what CPUFreq expects for this error
-	 * case and the following one
-	 */
-	if (tbl_sz == 0) {
-		pr_warning("%s: no matching entries in rate_table\n",
-			   __func__);
-		return;
-	}
-
-	/* Include the CPUFREQ_TABLE_END terminator entry */
-	tbl_sz++;
-
-	freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz,
-			     GFP_ATOMIC);
-	if (!freq_table) {
-		pr_err("%s: could not kzalloc frequency table\n", __func__);
-		return;
-	}
-
-	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
-		if (!(prcm->flags & cpu_mask))
-			continue;
-		if (prcm->xtal_speed != sclk->rate)
-			continue;
-
-		/* don't put bypass rates in table */
-		if (prcm->dpll_speed == prcm->xtal_speed)
-			continue;
-
-		freq_table[i].index = i;
-		freq_table[i].frequency = prcm->mpu_speed / 1000;
-		i++;
-	}
-
-	freq_table[i].index = i;
-	freq_table[i].frequency = CPUFREQ_TABLE_END;
-
-	*table = &freq_table[0];
-}
-
-void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
-{
-	if (!cpu_is_omap24xx())
-		return;
-
-	kfree(freq_table);
-}
-
-#endif

+ 0 - 5
arch/arm/mach-omap2/clock.c

@@ -536,10 +536,5 @@ struct clk_functions omap2_clk_functions = {
 	.clk_set_rate		= omap2_clk_set_rate,
 	.clk_set_rate		= omap2_clk_set_rate,
 	.clk_set_parent		= omap2_clk_set_parent,
 	.clk_set_parent		= omap2_clk_set_parent,
 	.clk_disable_unused	= omap2_clk_disable_unused,
 	.clk_disable_unused	= omap2_clk_disable_unused,
-#ifdef CONFIG_CPU_FREQ
-	/* These will be removed when the OPP code is integrated */
-	.clk_init_cpufreq_table	= omap2_clk_init_cpufreq_table,
-	.clk_exit_cpufreq_table	= omap2_clk_exit_cpufreq_table,
-#endif
 };
 };
 
 

+ 0 - 8
arch/arm/mach-omap2/clock.h

@@ -146,14 +146,6 @@ extern const struct clksel_rate gpt_sys_rates[];
 extern const struct clksel_rate gfx_l3_rates[];
 extern const struct clksel_rate gfx_l3_rates[];
 extern const struct clksel_rate dsp_ick_rates[];
 extern const struct clksel_rate dsp_ick_rates[];
 
 
-#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ)
-extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
-extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
-#else
-#define omap2_clk_init_cpufreq_table	0
-#define omap2_clk_exit_cpufreq_table	0
-#endif
-
 extern const struct clkops clkops_omap2_iclk_dflt_wait;
 extern const struct clkops clkops_omap2_iclk_dflt_wait;
 extern const struct clkops clkops_omap2_iclk_dflt;
 extern const struct clkops clkops_omap2_iclk_dflt;
 extern const struct clkops clkops_omap2_iclk_idle_only;
 extern const struct clkops clkops_omap2_iclk_idle_only;

+ 0 - 2
arch/arm/mach-s5pv210/dma.c

@@ -33,8 +33,6 @@
 #include <mach/irqs.h>
 #include <mach/irqs.h>
 #include <mach/dma.h>
 #include <mach/dma.h>
 
 
-static u64 dma_dmamask = DMA_BIT_MASK(32);
-
 static u8 pdma0_peri[] = {
 static u8 pdma0_peri[] = {
 	DMACH_UART0_RX,
 	DMACH_UART0_RX,
 	DMACH_UART0_TX,
 	DMACH_UART0_TX,

+ 2 - 2
arch/arm/mach-s5pv210/mach-aquila.c

@@ -484,8 +484,8 @@ static struct wm8994_pdata wm8994_platform_data = {
 	.gpio_defaults[8] = 0x0100,
 	.gpio_defaults[8] = 0x0100,
 	.gpio_defaults[9] = 0x0100,
 	.gpio_defaults[9] = 0x0100,
 	.gpio_defaults[10] = 0x0100,
 	.gpio_defaults[10] = 0x0100,
-	.ldo[0]	= { S5PV210_MP03(6), NULL, &wm8994_ldo1_data },	/* XM0FRNB_2 */
-	.ldo[1]	= { 0, NULL, &wm8994_ldo2_data },
+	.ldo[0]	= { S5PV210_MP03(6), &wm8994_ldo1_data },	/* XM0FRNB_2 */
+	.ldo[1]	= { 0, &wm8994_ldo2_data },
 };
 };
 
 
 /* GPIO I2C PMIC */
 /* GPIO I2C PMIC */

+ 2 - 2
arch/arm/mach-s5pv210/mach-goni.c

@@ -674,8 +674,8 @@ static struct wm8994_pdata wm8994_platform_data = {
 	.gpio_defaults[8] = 0x0100,
 	.gpio_defaults[8] = 0x0100,
 	.gpio_defaults[9] = 0x0100,
 	.gpio_defaults[9] = 0x0100,
 	.gpio_defaults[10] = 0x0100,
 	.gpio_defaults[10] = 0x0100,
-	.ldo[0]	= { S5PV210_MP03(6), NULL, &wm8994_ldo1_data },	/* XM0FRNB_2 */
-	.ldo[1]	= { 0, NULL, &wm8994_ldo2_data },
+	.ldo[0]	= { S5PV210_MP03(6), &wm8994_ldo1_data },	/* XM0FRNB_2 */
+	.ldo[1]	= { 0, &wm8994_ldo2_data },
 };
 };
 
 
 /* GPIO I2C PMIC */
 /* GPIO I2C PMIC */

+ 1 - 1
arch/arm/mm/Kconfig

@@ -723,7 +723,7 @@ config CPU_HIGH_VECTOR
 	bool "Select the High exception vector"
 	bool "Select the High exception vector"
 	help
 	help
 	  Say Y here to select high exception vector(0xFFFF0000~).
 	  Say Y here to select high exception vector(0xFFFF0000~).
-	  The exception vector can be vary depending on the platform
+	  The exception vector can vary depending on the platform
 	  design in nommu mode. If your platform needs to select
 	  design in nommu mode. If your platform needs to select
 	  high exception vector, say Y.
 	  high exception vector, say Y.
 	  Otherwise or if you are unsure, say N, and the low exception
 	  Otherwise or if you are unsure, say N, and the low exception

+ 1 - 1
arch/arm/mm/fault.c

@@ -320,7 +320,7 @@ retry:
 	 */
 	 */
 
 
 	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
 	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, addr);
-	if (flags & FAULT_FLAG_ALLOW_RETRY) {
+	if (!(fault & VM_FAULT_ERROR) && flags & FAULT_FLAG_ALLOW_RETRY) {
 		if (fault & VM_FAULT_MAJOR) {
 		if (fault & VM_FAULT_MAJOR) {
 			tsk->maj_flt++;
 			tsk->maj_flt++;
 			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1,
 			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1,

+ 2 - 0
arch/arm/mm/nommu.c

@@ -13,6 +13,7 @@
 #include <asm/sections.h>
 #include <asm/sections.h>
 #include <asm/page.h>
 #include <asm/page.h>
 #include <asm/setup.h>
 #include <asm/setup.h>
+#include <asm/traps.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/arch.h>
 
 
 #include "mm.h"
 #include "mm.h"
@@ -39,6 +40,7 @@ void __init sanity_check_meminfo(void)
  */
  */
 void __init paging_init(struct machine_desc *mdesc)
 void __init paging_init(struct machine_desc *mdesc)
 {
 {
+	early_trap_init((void *)CONFIG_VECTORS_BASE);
 	bootmem_init();
 	bootmem_init();
 }
 }
 
 

+ 12 - 0
arch/arm/mm/proc-v7.S

@@ -254,6 +254,18 @@ __v7_setup:
 	ldr	r6, =NMRR			@ NMRR
 	ldr	r6, =NMRR			@ NMRR
 	mcr	p15, 0, r5, c10, c2, 0		@ write PRRR
 	mcr	p15, 0, r5, c10, c2, 0		@ write PRRR
 	mcr	p15, 0, r6, c10, c2, 1		@ write NMRR
 	mcr	p15, 0, r6, c10, c2, 1		@ write NMRR
+#endif
+#ifndef CONFIG_ARM_THUMBEE
+	mrc	p15, 0, r0, c0, c1, 0		@ read ID_PFR0 for ThumbEE
+	and	r0, r0, #(0xf << 12)		@ ThumbEE enabled field
+	teq	r0, #(1 << 12)			@ check if ThumbEE is present
+	bne	1f
+	mov	r5, #0
+	mcr	p14, 6, r5, c1, c0, 0		@ Initialize TEEHBR to 0
+	mrc	p14, 6, r0, c0, c0, 0		@ load TEECR
+	orr	r0, r0, #1			@ set the 1st bit in order to
+	mcr	p14, 6, r0, c0, c0, 0		@ stop userspace TEEHBR access
+1:
 #endif
 #endif
 	adr	r5, v7_crval
 	adr	r5, v7_crval
 	ldmia	r5, {r5, r6}
 	ldmia	r5, {r5, r6}

+ 0 - 26
arch/arm/plat-omap/clock.c

@@ -398,32 +398,6 @@ struct clk dummy_ck = {
 	.ops	= &clkops_null,
 	.ops	= &clkops_null,
 };
 };
 
 
-#ifdef CONFIG_CPU_FREQ
-void clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
-{
-	unsigned long flags;
-
-	if (!arch_clock || !arch_clock->clk_init_cpufreq_table)
-		return;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	arch_clock->clk_init_cpufreq_table(table);
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-
-void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
-{
-	unsigned long flags;
-
-	if (!arch_clock || !arch_clock->clk_exit_cpufreq_table)
-		return;
-
-	spin_lock_irqsave(&clockfw_lock, flags);
-	arch_clock->clk_exit_cpufreq_table(table);
-	spin_unlock_irqrestore(&clockfw_lock, flags);
-}
-#endif
-
 /*
 /*
  *
  *
  */
  */

+ 0 - 10
arch/arm/plat-omap/include/plat/clock.h

@@ -272,8 +272,6 @@ struct clk {
 #endif
 #endif
 };
 };
 
 
-struct cpufreq_frequency_table;
-
 struct clk_functions {
 struct clk_functions {
 	int		(*clk_enable)(struct clk *clk);
 	int		(*clk_enable)(struct clk *clk);
 	void		(*clk_disable)(struct clk *clk);
 	void		(*clk_disable)(struct clk *clk);
@@ -283,10 +281,6 @@ struct clk_functions {
 	void		(*clk_allow_idle)(struct clk *clk);
 	void		(*clk_allow_idle)(struct clk *clk);
 	void		(*clk_deny_idle)(struct clk *clk);
 	void		(*clk_deny_idle)(struct clk *clk);
 	void		(*clk_disable_unused)(struct clk *clk);
 	void		(*clk_disable_unused)(struct clk *clk);
-#ifdef CONFIG_CPU_FREQ
-	void		(*clk_init_cpufreq_table)(struct cpufreq_frequency_table **);
-	void		(*clk_exit_cpufreq_table)(struct cpufreq_frequency_table **);
-#endif
 };
 };
 
 
 extern int mpurate;
 extern int mpurate;
@@ -301,10 +295,6 @@ extern void recalculate_root_clocks(void);
 extern unsigned long followparent_recalc(struct clk *clk);
 extern unsigned long followparent_recalc(struct clk *clk);
 extern void clk_enable_init_clocks(void);
 extern void clk_enable_init_clocks(void);
 unsigned long omap_fixed_divisor_recalc(struct clk *clk);
 unsigned long omap_fixed_divisor_recalc(struct clk *clk);
-#ifdef CONFIG_CPU_FREQ
-extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
-extern void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
-#endif
 extern struct clk *omap_clk_get_by_name(const char *name);
 extern struct clk *omap_clk_get_by_name(const char *name);
 extern int omap_clk_enable_autoidle_all(void);
 extern int omap_clk_enable_autoidle_all(void);
 extern int omap_clk_disable_autoidle_all(void);
 extern int omap_clk_disable_autoidle_all(void);

+ 1 - 0
arch/arm/plat-samsung/Kconfig

@@ -302,6 +302,7 @@ comment "Power management"
 config SAMSUNG_PM_DEBUG
 config SAMSUNG_PM_DEBUG
 	bool "S3C2410 PM Suspend debug"
 	bool "S3C2410 PM Suspend debug"
 	depends on PM
 	depends on PM
+	select DEBUG_LL
 	help
 	help
 	  Say Y here if you want verbose debugging from the PM Suspend and
 	  Say Y here if you want verbose debugging from the PM Suspend and
 	  Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
 	  Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>

+ 0 - 4
arch/c6x/include/asm/irq.h

@@ -42,10 +42,6 @@
 /* This number is used when no interrupt has been assigned */
 /* This number is used when no interrupt has been assigned */
 #define NO_IRQ		0
 #define NO_IRQ		0
 
 
-struct irq_data;
-extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
-extern irq_hw_number_t virq_to_hw(unsigned int virq);
-
 extern void __init init_pic_c64xplus(void);
 extern void __init init_pic_c64xplus(void);
 
 
 extern void init_IRQ(void);
 extern void init_IRQ(void);

+ 0 - 13
arch/c6x/kernel/irq.c

@@ -130,16 +130,3 @@ int arch_show_interrupts(struct seq_file *p, int prec)
 	seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
 	seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
 	return 0;
 	return 0;
 }
 }
-
-irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
-{
-	return d->hwirq;
-}
-EXPORT_SYMBOL_GPL(irqd_to_hwirq);
-
-irq_hw_number_t virq_to_hw(unsigned int virq)
-{
-	struct irq_data *irq_data = irq_get_irq_data(virq);
-	return WARN_ON(!irq_data) ? 0 : irq_data->hwirq;
-}
-EXPORT_SYMBOL_GPL(virq_to_hw);

+ 147 - 1
arch/ia64/include/asm/cmpxchg.h

@@ -1 +1,147 @@
-#include <asm/intrinsics.h>
+#ifndef _ASM_IA64_CMPXCHG_H
+#define _ASM_IA64_CMPXCHG_H
+
+/*
+ * Compare/Exchange, forked from asm/intrinsics.h
+ * which was:
+ *
+ *	Copyright (C) 2002-2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+/* include compiler specific intrinsics */
+#include <asm/ia64regs.h>
+#ifdef __INTEL_COMPILER
+# include <asm/intel_intrin.h>
+#else
+# include <asm/gcc_intrin.h>
+#endif
+
+/*
+ * This function doesn't exist, so you'll get a linker error if
+ * something tries to do an invalid xchg().
+ */
+extern void ia64_xchg_called_with_bad_pointer(void);
+
+#define __xchg(x, ptr, size)						\
+({									\
+	unsigned long __xchg_result;					\
+									\
+	switch (size) {							\
+	case 1:								\
+		__xchg_result = ia64_xchg1((__u8 *)ptr, x);		\
+		break;							\
+									\
+	case 2:								\
+		__xchg_result = ia64_xchg2((__u16 *)ptr, x);		\
+		break;							\
+									\
+	case 4:								\
+		__xchg_result = ia64_xchg4((__u32 *)ptr, x);		\
+		break;							\
+									\
+	case 8:								\
+		__xchg_result = ia64_xchg8((__u64 *)ptr, x);		\
+		break;							\
+	default:							\
+		ia64_xchg_called_with_bad_pointer();			\
+	}								\
+	__xchg_result;							\
+})
+
+#define xchg(ptr, x)							\
+((__typeof__(*(ptr))) __xchg((unsigned long) (x), (ptr), sizeof(*(ptr))))
+
+/*
+ * Atomic compare and exchange.  Compare OLD with MEM, if identical,
+ * store NEW in MEM.  Return the initial value in MEM.  Success is
+ * indicated by comparing RETURN with OLD.
+ */
+
+#define __HAVE_ARCH_CMPXCHG 1
+
+/*
+ * This function doesn't exist, so you'll get a linker error
+ * if something tries to do an invalid cmpxchg().
+ */
+extern long ia64_cmpxchg_called_with_bad_pointer(void);
+
+#define ia64_cmpxchg(sem, ptr, old, new, size)				\
+({									\
+	__u64 _o_, _r_;							\
+									\
+	switch (size) {							\
+	case 1:								\
+		_o_ = (__u8) (long) (old);				\
+		break;							\
+	case 2:								\
+		_o_ = (__u16) (long) (old);				\
+		break;							\
+	case 4:								\
+		_o_ = (__u32) (long) (old);				\
+		break;							\
+	case 8:								\
+		_o_ = (__u64) (long) (old);				\
+		break;							\
+	default:							\
+		break;							\
+	}								\
+	switch (size) {							\
+	case 1:								\
+		_r_ = ia64_cmpxchg1_##sem((__u8 *) ptr, new, _o_);	\
+		break;							\
+									\
+	case 2:								\
+		_r_ = ia64_cmpxchg2_##sem((__u16 *) ptr, new, _o_);	\
+		break;							\
+									\
+	case 4:								\
+		_r_ = ia64_cmpxchg4_##sem((__u32 *) ptr, new, _o_);	\
+		break;							\
+									\
+	case 8:								\
+		_r_ = ia64_cmpxchg8_##sem((__u64 *) ptr, new, _o_);	\
+		break;							\
+									\
+	default:							\
+		_r_ = ia64_cmpxchg_called_with_bad_pointer();		\
+		break;							\
+	}								\
+	(__typeof__(old)) _r_;						\
+})
+
+#define cmpxchg_acq(ptr, o, n)	\
+	ia64_cmpxchg(acq, (ptr), (o), (n), sizeof(*(ptr)))
+#define cmpxchg_rel(ptr, o, n)	\
+	ia64_cmpxchg(rel, (ptr), (o), (n), sizeof(*(ptr)))
+
+/* for compatibility with other platforms: */
+#define cmpxchg(ptr, o, n)	cmpxchg_acq((ptr), (o), (n))
+#define cmpxchg64(ptr, o, n)	cmpxchg_acq((ptr), (o), (n))
+
+#define cmpxchg_local		cmpxchg
+#define cmpxchg64_local		cmpxchg64
+
+#ifdef CONFIG_IA64_DEBUG_CMPXCHG
+# define CMPXCHG_BUGCHECK_DECL	int _cmpxchg_bugcheck_count = 128;
+# define CMPXCHG_BUGCHECK(v)						\
+do {									\
+	if (_cmpxchg_bugcheck_count-- <= 0) {				\
+		void *ip;						\
+		extern int printk(const char *fmt, ...);		\
+		ip = (void *) ia64_getreg(_IA64_REG_IP);		\
+		printk("CMPXCHG_BUGCHECK: stuck at %p on word %p\n", ip, (v));\
+		break;							\
+	}								\
+} while (0)
+#else /* !CONFIG_IA64_DEBUG_CMPXCHG */
+# define CMPXCHG_BUGCHECK_DECL
+# define CMPXCHG_BUGCHECK(v)
+#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_IA64_CMPXCHG_H */

+ 1 - 113
arch/ia64/include/asm/intrinsics.h

@@ -18,6 +18,7 @@
 #else
 #else
 # include <asm/gcc_intrin.h>
 # include <asm/gcc_intrin.h>
 #endif
 #endif
+#include <asm/cmpxchg.h>
 
 
 #define ia64_native_get_psr_i()	(ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I)
 #define ia64_native_get_psr_i()	(ia64_native_getreg(_IA64_REG_PSR) & IA64_PSR_I)
 
 
@@ -81,119 +82,6 @@ extern unsigned long __bad_increment_for_ia64_fetch_and_add (void);
 
 
 #define ia64_fetch_and_add(i,v)	(ia64_fetchadd(i, v, rel) + (i)) /* return new value */
 #define ia64_fetch_and_add(i,v)	(ia64_fetchadd(i, v, rel) + (i)) /* return new value */
 
 
-/*
- * This function doesn't exist, so you'll get a linker error if
- * something tries to do an invalid xchg().
- */
-extern void ia64_xchg_called_with_bad_pointer (void);
-
-#define __xchg(x,ptr,size)						\
-({									\
-	unsigned long __xchg_result;					\
-									\
-	switch (size) {							\
-	      case 1:							\
-		__xchg_result = ia64_xchg1((__u8 *)ptr, x);		\
-		break;							\
-									\
-	      case 2:							\
-		__xchg_result = ia64_xchg2((__u16 *)ptr, x);		\
-		break;							\
-									\
-	      case 4:							\
-		__xchg_result = ia64_xchg4((__u32 *)ptr, x);		\
-		break;							\
-									\
-	      case 8:							\
-		__xchg_result = ia64_xchg8((__u64 *)ptr, x);		\
-		break;							\
-	      default:							\
-		ia64_xchg_called_with_bad_pointer();			\
-	}								\
-	__xchg_result;							\
-})
-
-#define xchg(ptr,x)							     \
-  ((__typeof__(*(ptr))) __xchg ((unsigned long) (x), (ptr), sizeof(*(ptr))))
-
-/*
- * Atomic compare and exchange.  Compare OLD with MEM, if identical,
- * store NEW in MEM.  Return the initial value in MEM.  Success is
- * indicated by comparing RETURN with OLD.
- */
-
-#define __HAVE_ARCH_CMPXCHG 1
-
-/*
- * This function doesn't exist, so you'll get a linker error
- * if something tries to do an invalid cmpxchg().
- */
-extern long ia64_cmpxchg_called_with_bad_pointer (void);
-
-#define ia64_cmpxchg(sem,ptr,old,new,size)						\
-({											\
-	__u64 _o_, _r_;									\
-											\
-	switch (size) {									\
-	      case 1: _o_ = (__u8 ) (long) (old); break;				\
-	      case 2: _o_ = (__u16) (long) (old); break;				\
-	      case 4: _o_ = (__u32) (long) (old); break;				\
-	      case 8: _o_ = (__u64) (long) (old); break;				\
-	      default: break;								\
-	}										\
-	switch (size) {									\
-	      case 1:									\
-	      	_r_ = ia64_cmpxchg1_##sem((__u8 *) ptr, new, _o_);			\
-		break;									\
-											\
-	      case 2:									\
-	       _r_ = ia64_cmpxchg2_##sem((__u16 *) ptr, new, _o_);			\
-		break;									\
-											\
-	      case 4:									\
-	      	_r_ = ia64_cmpxchg4_##sem((__u32 *) ptr, new, _o_);			\
-		break;									\
-											\
-	      case 8:									\
-		_r_ = ia64_cmpxchg8_##sem((__u64 *) ptr, new, _o_);			\
-		break;									\
-											\
-	      default:									\
-		_r_ = ia64_cmpxchg_called_with_bad_pointer();				\
-		break;									\
-	}										\
-	(__typeof__(old)) _r_;								\
-})
-
-#define cmpxchg_acq(ptr, o, n)	\
-	ia64_cmpxchg(acq, (ptr), (o), (n), sizeof(*(ptr)))
-#define cmpxchg_rel(ptr, o, n)	\
-	ia64_cmpxchg(rel, (ptr), (o), (n), sizeof(*(ptr)))
-
-/* for compatibility with other platforms: */
-#define cmpxchg(ptr, o, n)	cmpxchg_acq((ptr), (o), (n))
-#define cmpxchg64(ptr, o, n)	cmpxchg_acq((ptr), (o), (n))
-
-#define cmpxchg_local		cmpxchg
-#define cmpxchg64_local		cmpxchg64
-
-#ifdef CONFIG_IA64_DEBUG_CMPXCHG
-# define CMPXCHG_BUGCHECK_DECL	int _cmpxchg_bugcheck_count = 128;
-# define CMPXCHG_BUGCHECK(v)							\
-  do {										\
-	if (_cmpxchg_bugcheck_count-- <= 0) {					\
-		void *ip;							\
-		extern int printk(const char *fmt, ...);			\
-		ip = (void *) ia64_getreg(_IA64_REG_IP);			\
-		printk("CMPXCHG_BUGCHECK: stuck at %p on word %p\n", ip, (v));	\
-		break;								\
-	}									\
-  } while (0)
-#else /* !CONFIG_IA64_DEBUG_CMPXCHG */
-# define CMPXCHG_BUGCHECK_DECL
-# define CMPXCHG_BUGCHECK(v)
-#endif /* !CONFIG_IA64_DEBUG_CMPXCHG */
-
 #endif
 #endif
 
 
 #ifdef __KERNEL__
 #ifdef __KERNEL__

+ 0 - 2
arch/powerpc/include/asm/irq.h

@@ -33,8 +33,6 @@ extern atomic_t ppc_n_lost_interrupts;
 /* Same thing, used by the generic IRQ code */
 /* Same thing, used by the generic IRQ code */
 #define NR_IRQS_LEGACY		NUM_ISA_INTERRUPTS
 #define NR_IRQS_LEGACY		NUM_ISA_INTERRUPTS
 
 
-struct irq_data;
-extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
 extern irq_hw_number_t virq_to_hw(unsigned int virq);
 extern irq_hw_number_t virq_to_hw(unsigned int virq);
 
 
 /**
 /**

+ 21 - 18
arch/powerpc/kernel/entry_32.S

@@ -206,40 +206,43 @@ reenable_mmu:				/* re-enable mmu so we can */
 	andi.	r10,r10,MSR_EE		/* Did EE change? */
 	andi.	r10,r10,MSR_EE		/* Did EE change? */
 	beq	1f
 	beq	1f
 
 
-	/* Save handler and return address into the 2 unused words
-	 * of the STACK_FRAME_OVERHEAD (sneak sneak sneak). Everything
-	 * else can be recovered from the pt_regs except r3 which for
-	 * normal interrupts has been set to pt_regs and for syscalls
-	 * is an argument, so we temporarily use ORIG_GPR3 to save it
-	 */
-	stw	r9,8(r1)
-	stw	r11,12(r1)
-	stw	r3,ORIG_GPR3(r1)
 	/*
 	/*
 	 * The trace_hardirqs_off will use CALLER_ADDR0 and CALLER_ADDR1.
 	 * The trace_hardirqs_off will use CALLER_ADDR0 and CALLER_ADDR1.
 	 * If from user mode there is only one stack frame on the stack, and
 	 * If from user mode there is only one stack frame on the stack, and
 	 * accessing CALLER_ADDR1 will cause oops. So we need create a dummy
 	 * accessing CALLER_ADDR1 will cause oops. So we need create a dummy
 	 * stack frame to make trace_hardirqs_off happy.
 	 * stack frame to make trace_hardirqs_off happy.
+	 *
+	 * This is handy because we also need to save a bunch of GPRs,
+	 * r3 can be different from GPR3(r1) at this point, r9 and r11
+	 * contains the old MSR and handler address respectively,
+	 * r4 & r5 can contain page fault arguments that need to be passed
+	 * along as well. r12, CCR, CTR, XER etc... are left clobbered as
+	 * they aren't useful past this point (aren't syscall arguments),
+	 * the rest is restored from the exception frame.
 	 */
 	 */
+	stwu	r1,-32(r1)
+	stw	r9,8(r1)
+	stw	r11,12(r1)
+	stw	r3,16(r1)
+	stw	r4,20(r1)
+	stw	r5,24(r1)
 	andi.	r12,r12,MSR_PR
 	andi.	r12,r12,MSR_PR
-	beq	11f
-	stwu	r1,-16(r1)
+	b	11f
 	bl	trace_hardirqs_off
 	bl	trace_hardirqs_off
-	addi	r1,r1,16
 	b	12f
 	b	12f
-
 11:
 11:
 	bl	trace_hardirqs_off
 	bl	trace_hardirqs_off
 12:
 12:
+	lwz	r5,24(r1)
+	lwz	r4,20(r1)
+	lwz	r3,16(r1)
+	lwz	r11,12(r1)
+	lwz	r9,8(r1)
+	addi	r1,r1,32
 	lwz	r0,GPR0(r1)
 	lwz	r0,GPR0(r1)
-	lwz	r3,ORIG_GPR3(r1)
-	lwz	r4,GPR4(r1)
-	lwz	r5,GPR5(r1)
 	lwz	r6,GPR6(r1)
 	lwz	r6,GPR6(r1)
 	lwz	r7,GPR7(r1)
 	lwz	r7,GPR7(r1)
 	lwz	r8,GPR8(r1)
 	lwz	r8,GPR8(r1)
-	lwz	r9,8(r1)
-	lwz	r11,12(r1)
 1:	mtctr	r11
 1:	mtctr	r11
 	mtlr	r9
 	mtlr	r9
 	bctr				/* jump to handler */
 	bctr				/* jump to handler */

+ 0 - 6
arch/powerpc/kernel/irq.c

@@ -560,12 +560,6 @@ void do_softirq(void)
 	local_irq_restore(flags);
 	local_irq_restore(flags);
 }
 }
 
 
-irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
-{
-	return d->hwirq;
-}
-EXPORT_SYMBOL_GPL(irqd_to_hwirq);
-
 irq_hw_number_t virq_to_hw(unsigned int virq)
 irq_hw_number_t virq_to_hw(unsigned int virq)
 {
 {
 	struct irq_data *irq_data = irq_get_irq_data(virq);
 	struct irq_data *irq_data = irq_get_irq_data(virq);

+ 2 - 2
arch/powerpc/kernel/process.c

@@ -1235,7 +1235,7 @@ void __ppc64_runlatch_on(void)
 	ctrl |= CTRL_RUNLATCH;
 	ctrl |= CTRL_RUNLATCH;
 	mtspr(SPRN_CTRLT, ctrl);
 	mtspr(SPRN_CTRLT, ctrl);
 
 
-	ti->local_flags |= TLF_RUNLATCH;
+	ti->local_flags |= _TLF_RUNLATCH;
 }
 }
 
 
 /* Called with hard IRQs off */
 /* Called with hard IRQs off */
@@ -1244,7 +1244,7 @@ void __ppc64_runlatch_off(void)
 	struct thread_info *ti = current_thread_info();
 	struct thread_info *ti = current_thread_info();
 	unsigned long ctrl;
 	unsigned long ctrl;
 
 
-	ti->local_flags &= ~TLF_RUNLATCH;
+	ti->local_flags &= ~_TLF_RUNLATCH;
 
 
 	ctrl = mfspr(SPRN_CTRLF);
 	ctrl = mfspr(SPRN_CTRLF);
 	ctrl &= ~CTRL_RUNLATCH;
 	ctrl &= ~CTRL_RUNLATCH;

+ 1 - 1
arch/powerpc/platforms/cell/axon_msi.c

@@ -392,7 +392,7 @@ static int axon_msi_probe(struct platform_device *device)
 	}
 	}
 	memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES);
 	memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES);
 
 
-	msic->irq_domain = irq_domain_add_nomap(dn, &msic_host_ops, msic);
+	msic->irq_domain = irq_domain_add_nomap(dn, 0, &msic_host_ops, msic);
 	if (!msic->irq_domain) {
 	if (!msic->irq_domain) {
 		printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
 		printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
 		       dn->full_name);
 		       dn->full_name);

+ 1 - 1
arch/powerpc/platforms/cell/beat_interrupt.c

@@ -239,7 +239,7 @@ void __init beatic_init_IRQ(void)
 	ppc_md.get_irq = beatic_get_irq;
 	ppc_md.get_irq = beatic_get_irq;
 
 
 	/* Allocate an irq host */
 	/* Allocate an irq host */
-	beatic_host = irq_domain_add_nomap(NULL, &beatic_pic_host_ops, NULL);
+	beatic_host = irq_domain_add_nomap(NULL, 0, &beatic_pic_host_ops, NULL);
 	BUG_ON(beatic_host == NULL);
 	BUG_ON(beatic_host == NULL);
 	irq_set_default_host(beatic_host);
 	irq_set_default_host(beatic_host);
 }
 }

+ 1 - 1
arch/powerpc/platforms/powermac/smp.c

@@ -192,7 +192,7 @@ static int psurge_secondary_ipi_init(void)
 {
 {
 	int rc = -ENOMEM;
 	int rc = -ENOMEM;
 
 
-	psurge_host = irq_domain_add_nomap(NULL, &psurge_host_ops, NULL);
+	psurge_host = irq_domain_add_nomap(NULL, 0, &psurge_host_ops, NULL);
 
 
 	if (psurge_host)
 	if (psurge_host)
 		psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
 		psurge_secondary_virq = irq_create_direct_mapping(psurge_host);

+ 1 - 2
arch/powerpc/platforms/ps3/interrupt.c

@@ -753,9 +753,8 @@ void __init ps3_init_IRQ(void)
 	unsigned cpu;
 	unsigned cpu;
 	struct irq_domain *host;
 	struct irq_domain *host;
 
 
-	host = irq_domain_add_nomap(NULL, &ps3_host_ops, NULL);
+	host = irq_domain_add_nomap(NULL, PS3_PLUG_MAX + 1, &ps3_host_ops, NULL);
 	irq_set_default_host(host);
 	irq_set_default_host(host);
-	irq_set_virq_count(PS3_PLUG_MAX + 1);
 
 
 	for_each_possible_cpu(cpu) {
 	for_each_possible_cpu(cpu) {
 		struct ps3_private *pd = &per_cpu(ps3_private, cpu);
 		struct ps3_private *pd = &per_cpu(ps3_private, cpu);

+ 1 - 1
arch/sparc/kernel/ds.c

@@ -1264,4 +1264,4 @@ static int __init ds_init(void)
 	return vio_register_driver(&ds_driver);
 	return vio_register_driver(&ds_driver);
 }
 }
 
 
-subsys_initcall(ds_init);
+fs_initcall(ds_init);

+ 0 - 13
arch/sparc/kernel/leon_pci.c

@@ -45,7 +45,6 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
 
 
 void __devinit pcibios_fixup_bus(struct pci_bus *pbus)
 void __devinit pcibios_fixup_bus(struct pci_bus *pbus)
 {
 {
-	struct leon_pci_info *info = pbus->sysdata;
 	struct pci_dev *dev;
 	struct pci_dev *dev;
 	int i, has_io, has_mem;
 	int i, has_io, has_mem;
 	u16 cmd;
 	u16 cmd;
@@ -111,18 +110,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 	return pci_enable_resources(dev, mask);
 	return pci_enable_resources(dev, mask);
 }
 }
 
 
-struct device_node *pci_device_to_OF_node(struct pci_dev *pdev)
-{
-	/*
-	 * Currently the OpenBoot nodes are not connected with the PCI device,
-	 * this is because the LEON PROM does not create PCI nodes. Eventually
-	 * this will change and the same approach as pcic.c can be used to
-	 * match PROM nodes with pci devices.
-	 */
-	return NULL;
-}
-EXPORT_SYMBOL(pci_device_to_OF_node);
-
 void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
 void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
 {
 {
 #ifdef CONFIG_PCI_DEBUG
 #ifdef CONFIG_PCI_DEBUG

+ 0 - 7
arch/sparc/kernel/rtrap_64.S

@@ -20,11 +20,6 @@
 
 
 		.text
 		.text
 		.align			32
 		.align			32
-__handle_softirq:
-		call			do_softirq
-		 nop
-		ba,a,pt			%xcc, __handle_softirq_continue
-		 nop
 __handle_preemption:
 __handle_preemption:
 		call			schedule
 		call			schedule
 		 wrpr			%g0, RTRAP_PSTATE, %pstate
 		 wrpr			%g0, RTRAP_PSTATE, %pstate
@@ -89,9 +84,7 @@ rtrap:
 		cmp			%l1, 0
 		cmp			%l1, 0
 
 
 		/* mm/ultra.S:xcall_report_regs KNOWS about this load. */
 		/* mm/ultra.S:xcall_report_regs KNOWS about this load. */
-		bne,pn			%icc, __handle_softirq
 		 ldx			[%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
 		 ldx			[%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
-__handle_softirq_continue:
 rtrap_xcall:
 rtrap_xcall:
 		sethi			%hi(0xf << 20), %l4
 		sethi			%hi(0xf << 20), %l4
 		and			%l1, %l4, %l4
 		and			%l1, %l4, %l4

+ 30 - 7
arch/sparc/mm/fault_32.c

@@ -225,6 +225,8 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
 	unsigned long g2;
 	unsigned long g2;
 	int from_user = !(regs->psr & PSR_PS);
 	int from_user = !(regs->psr & PSR_PS);
 	int fault, code;
 	int fault, code;
+	unsigned int flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
+			      (write ? FAULT_FLAG_WRITE : 0));
 
 
 	if(text_fault)
 	if(text_fault)
 		address = regs->pc;
 		address = regs->pc;
@@ -251,6 +253,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
 
 
 	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
 	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
 
 
+retry:
 	down_read(&mm->mmap_sem);
 	down_read(&mm->mmap_sem);
 
 
 	/*
 	/*
@@ -289,7 +292,11 @@ good_area:
 	 * make sure we exit gracefully rather than endlessly redo
 	 * make sure we exit gracefully rather than endlessly redo
 	 * the fault.
 	 * the fault.
 	 */
 	 */
-	fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0);
+	fault = handle_mm_fault(mm, vma, address, flags);
+
+	if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+		return;
+
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
 			goto out_of_memory;
@@ -297,13 +304,29 @@ good_area:
 			goto do_sigbus;
 			goto do_sigbus;
 		BUG();
 		BUG();
 	}
 	}
-	if (fault & VM_FAULT_MAJOR) {
-		current->maj_flt++;
-		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address);
-	} else {
-		current->min_flt++;
-		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address);
+
+	if (flags & FAULT_FLAG_ALLOW_RETRY) {
+		if (fault & VM_FAULT_MAJOR) {
+			current->maj_flt++;
+			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,
+				      1, regs, address);
+		} else {
+			current->min_flt++;
+			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
+				      1, regs, address);
+		}
+		if (fault & VM_FAULT_RETRY) {
+			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+
+			/* No need to up_read(&mm->mmap_sem) as we would
+			 * have already released it in __lock_page_or_retry
+			 * in mm/filemap.c.
+			 */
+
+			goto retry;
+		}
 	}
 	}
+
 	up_read(&mm->mmap_sem);
 	up_read(&mm->mmap_sem);
 	return;
 	return;
 
 

+ 30 - 7
arch/sparc/mm/fault_64.c

@@ -279,6 +279,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
 	unsigned int insn = 0;
 	unsigned int insn = 0;
 	int si_code, fault_code, fault;
 	int si_code, fault_code, fault;
 	unsigned long address, mm_rss;
 	unsigned long address, mm_rss;
+	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
 
 	fault_code = get_thread_fault_code();
 	fault_code = get_thread_fault_code();
 
 
@@ -333,6 +334,8 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
 			insn = get_fault_insn(regs, insn);
 			insn = get_fault_insn(regs, insn);
 			goto handle_kernel_fault;
 			goto handle_kernel_fault;
 		}
 		}
+
+retry:
 		down_read(&mm->mmap_sem);
 		down_read(&mm->mmap_sem);
 	}
 	}
 
 
@@ -423,7 +426,12 @@ good_area:
 			goto bad_area;
 			goto bad_area;
 	}
 	}
 
 
-	fault = handle_mm_fault(mm, vma, address, (fault_code & FAULT_CODE_WRITE) ? FAULT_FLAG_WRITE : 0);
+	flags |= ((fault_code & FAULT_CODE_WRITE) ? FAULT_FLAG_WRITE : 0);
+	fault = handle_mm_fault(mm, vma, address, flags);
+
+	if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+		return;
+
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 	if (unlikely(fault & VM_FAULT_ERROR)) {
 		if (fault & VM_FAULT_OOM)
 		if (fault & VM_FAULT_OOM)
 			goto out_of_memory;
 			goto out_of_memory;
@@ -431,12 +439,27 @@ good_area:
 			goto do_sigbus;
 			goto do_sigbus;
 		BUG();
 		BUG();
 	}
 	}
-	if (fault & VM_FAULT_MAJOR) {
-		current->maj_flt++;
-		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address);
-	} else {
-		current->min_flt++;
-		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address);
+
+	if (flags & FAULT_FLAG_ALLOW_RETRY) {
+		if (fault & VM_FAULT_MAJOR) {
+			current->maj_flt++;
+			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,
+				      1, regs, address);
+		} else {
+			current->min_flt++;
+			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
+				      1, regs, address);
+		}
+		if (fault & VM_FAULT_RETRY) {
+			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+
+			/* No need to up_read(&mm->mmap_sem) as we would
+			 * have already released it in __lock_page_or_retry
+			 * in mm/filemap.c.
+			 */
+
+			goto retry;
+		}
 	}
 	}
 	up_read(&mm->mmap_sem);
 	up_read(&mm->mmap_sem);
 
 

+ 1 - 3
arch/tile/kernel/proc.c

@@ -146,7 +146,6 @@ static ctl_table unaligned_table[] = {
 	},
 	},
 	{}
 	{}
 };
 };
-#endif
 
 
 static struct ctl_path tile_path[] = {
 static struct ctl_path tile_path[] = {
 	{ .procname = "tile" },
 	{ .procname = "tile" },
@@ -155,10 +154,9 @@ static struct ctl_path tile_path[] = {
 
 
 static int __init proc_sys_tile_init(void)
 static int __init proc_sys_tile_init(void)
 {
 {
-#ifndef __tilegx__  /* FIXME: GX: no support for unaligned access yet */
 	register_sysctl_paths(tile_path, unaligned_table);
 	register_sysctl_paths(tile_path, unaligned_table);
-#endif
 	return 0;
 	return 0;
 }
 }
 
 
 arch_initcall(proc_sys_tile_init);
 arch_initcall(proc_sys_tile_init);
+#endif

+ 2 - 0
arch/tile/kernel/smpboot.c

@@ -196,6 +196,8 @@ void __cpuinit online_secondary(void)
 	/* This must be done before setting cpu_online_mask */
 	/* This must be done before setting cpu_online_mask */
 	wmb();
 	wmb();
 
 
+	notify_cpu_starting(smp_processor_id());
+
 	/*
 	/*
 	 * We need to hold call_lock, so there is no inconsistency
 	 * We need to hold call_lock, so there is no inconsistency
 	 * between the time smp_call_function() determines number of
 	 * between the time smp_call_function() determines number of

+ 0 - 35
arch/um/drivers/cow.h

@@ -3,41 +3,6 @@
 
 
 #include <asm/types.h>
 #include <asm/types.h>
 
 
-#if defined(__KERNEL__)
-
-# include <asm/byteorder.h>
-
-# if defined(__BIG_ENDIAN)
-#	define ntohll(x) (x)
-#	define htonll(x) (x)
-# elif defined(__LITTLE_ENDIAN)
-#	define ntohll(x)  be64_to_cpu(x)
-#	define htonll(x)  cpu_to_be64(x)
-# else
-#	error "Could not determine byte order"
-# endif
-
-#else
-/* For the definition of ntohl, htonl and __BYTE_ORDER */
-#include <endian.h>
-#include <netinet/in.h>
-#if defined(__BYTE_ORDER)
-
-#  if __BYTE_ORDER == __BIG_ENDIAN
-#	define ntohll(x) (x)
-#	define htonll(x) (x)
-#  elif __BYTE_ORDER == __LITTLE_ENDIAN
-#	define ntohll(x)  bswap_64(x)
-#	define htonll(x)  bswap_64(x)
-#  else
-#	error "Could not determine byte order: __BYTE_ORDER uncorrectly defined"
-#  endif
-
-#else  /* ! defined(__BYTE_ORDER) */
-#	error "Could not determine byte order: __BYTE_ORDER not defined"
-#endif
-#endif /* ! defined(__KERNEL__) */
-
 extern int init_cow_file(int fd, char *cow_file, char *backing_file,
 extern int init_cow_file(int fd, char *cow_file, char *backing_file,
 			 int sectorsize, int alignment, int *bitmap_offset_out,
 			 int sectorsize, int alignment, int *bitmap_offset_out,
 			 unsigned long *bitmap_len_out, int *data_offset_out);
 			 unsigned long *bitmap_len_out, int *data_offset_out);

+ 21 - 22
arch/um/drivers/cow_user.c

@@ -8,11 +8,10 @@
  * that.
  * that.
  */
  */
 #include <unistd.h>
 #include <unistd.h>
-#include <byteswap.h>
 #include <errno.h>
 #include <errno.h>
 #include <string.h>
 #include <string.h>
 #include <arpa/inet.h>
 #include <arpa/inet.h>
-#include <asm/types.h>
+#include <endian.h>
 #include "cow.h"
 #include "cow.h"
 #include "cow_sys.h"
 #include "cow_sys.h"
 
 
@@ -214,8 +213,8 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
 			   "header\n");
 			   "header\n");
 		goto out;
 		goto out;
 	}
 	}
-	header->magic = htonl(COW_MAGIC);
-	header->version = htonl(COW_VERSION);
+	header->magic = htobe32(COW_MAGIC);
+	header->version = htobe32(COW_VERSION);
 
 
 	err = -EINVAL;
 	err = -EINVAL;
 	if (strlen(backing_file) > sizeof(header->backing_file) - 1) {
 	if (strlen(backing_file) > sizeof(header->backing_file) - 1) {
@@ -246,10 +245,10 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
 		goto out_free;
 		goto out_free;
 	}
 	}
 
 
-	header->mtime = htonl(modtime);
-	header->size = htonll(*size);
-	header->sectorsize = htonl(sectorsize);
-	header->alignment = htonl(alignment);
+	header->mtime = htobe32(modtime);
+	header->size = htobe64(*size);
+	header->sectorsize = htobe32(sectorsize);
+	header->alignment = htobe32(alignment);
 	header->cow_format = COW_BITMAP;
 	header->cow_format = COW_BITMAP;
 
 
 	err = cow_write_file(fd, header, sizeof(*header));
 	err = cow_write_file(fd, header, sizeof(*header));
@@ -301,8 +300,8 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
 	magic = header->v1.magic;
 	magic = header->v1.magic;
 	if (magic == COW_MAGIC)
 	if (magic == COW_MAGIC)
 		version = header->v1.version;
 		version = header->v1.version;
-	else if (magic == ntohl(COW_MAGIC))
-		version = ntohl(header->v1.version);
+	else if (magic == be32toh(COW_MAGIC))
+		version = be32toh(header->v1.version);
 	/* No error printed because the non-COW case comes through here */
 	/* No error printed because the non-COW case comes through here */
 	else goto out;
 	else goto out;
 
 
@@ -327,9 +326,9 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
 				   "header\n");
 				   "header\n");
 			goto out;
 			goto out;
 		}
 		}
-		*mtime_out = ntohl(header->v2.mtime);
-		*size_out = ntohll(header->v2.size);
-		*sectorsize_out = ntohl(header->v2.sectorsize);
+		*mtime_out = be32toh(header->v2.mtime);
+		*size_out = be64toh(header->v2.size);
+		*sectorsize_out = be32toh(header->v2.sectorsize);
 		*bitmap_offset_out = sizeof(header->v2);
 		*bitmap_offset_out = sizeof(header->v2);
 		*align_out = *sectorsize_out;
 		*align_out = *sectorsize_out;
 		file = header->v2.backing_file;
 		file = header->v2.backing_file;
@@ -341,10 +340,10 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
 				   "header\n");
 				   "header\n");
 			goto out;
 			goto out;
 		}
 		}
-		*mtime_out = ntohl(header->v3.mtime);
-		*size_out = ntohll(header->v3.size);
-		*sectorsize_out = ntohl(header->v3.sectorsize);
-		*align_out = ntohl(header->v3.alignment);
+		*mtime_out = be32toh(header->v3.mtime);
+		*size_out = be64toh(header->v3.size);
+		*sectorsize_out = be32toh(header->v3.sectorsize);
+		*align_out = be32toh(header->v3.alignment);
 		if (*align_out == 0) {
 		if (*align_out == 0) {
 			cow_printf("read_cow_header - invalid COW header, "
 			cow_printf("read_cow_header - invalid COW header, "
 				   "align == 0\n");
 				   "align == 0\n");
@@ -366,16 +365,16 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
 		 * this was used until Dec2005 - 64bits are needed to represent
 		 * this was used until Dec2005 - 64bits are needed to represent
 		 * 2038+. I.e. we can safely do this truncating cast.
 		 * 2038+. I.e. we can safely do this truncating cast.
 		 *
 		 *
-		 * Additionally, we must use ntohl() instead of ntohll(), since
+		 * Additionally, we must use be32toh() instead of be64toh(), since
 		 * the program used to use the former (tested - I got mtime
 		 * the program used to use the former (tested - I got mtime
 		 * mismatch "0 vs whatever").
 		 * mismatch "0 vs whatever").
 		 *
 		 *
 		 * Ever heard about bug-to-bug-compatibility ? ;-) */
 		 * Ever heard about bug-to-bug-compatibility ? ;-) */
-		*mtime_out = (time32_t) ntohl(header->v3_b.mtime);
+		*mtime_out = (time32_t) be32toh(header->v3_b.mtime);
 
 
-		*size_out = ntohll(header->v3_b.size);
-		*sectorsize_out = ntohl(header->v3_b.sectorsize);
-		*align_out = ntohl(header->v3_b.alignment);
+		*size_out = be64toh(header->v3_b.size);
+		*sectorsize_out = be32toh(header->v3_b.sectorsize);
+		*align_out = be32toh(header->v3_b.alignment);
 		if (*align_out == 0) {
 		if (*align_out == 0) {
 			cow_printf("read_cow_header - invalid COW header, "
 			cow_printf("read_cow_header - invalid COW header, "
 				   "align == 0\n");
 				   "align == 0\n");

+ 1 - 0
arch/um/drivers/mconsole_kern.c

@@ -22,6 +22,7 @@
 #include <linux/workqueue.h>
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
+#include <asm/switch_to.h>
 
 
 #include "init.h"
 #include "init.h"
 #include "irq_kern.h"
 #include "irq_kern.h"

+ 2 - 1
arch/um/include/asm/Kbuild

@@ -1,3 +1,4 @@
 generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h
 generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h
 generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h
 generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h
-generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h
+generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h
+generic-y += switch_to.h

+ 4 - 3
arch/um/kernel/Makefile

@@ -3,9 +3,10 @@
 # Licensed under the GPL
 # Licensed under the GPL
 #
 #
 
 
-CPPFLAGS_vmlinux.lds := -DSTART=$(LDS_START) \
-                        -DELF_ARCH=$(LDS_ELF_ARCH)        \
-                        -DELF_FORMAT=$(LDS_ELF_FORMAT)
+CPPFLAGS_vmlinux.lds := -DSTART=$(LDS_START)		\
+                        -DELF_ARCH=$(LDS_ELF_ARCH)	\
+                        -DELF_FORMAT=$(LDS_ELF_FORMAT)	\
+			$(LDS_EXTRA)
 extra-y := vmlinux.lds
 extra-y := vmlinux.lds
 clean-files :=
 clean-files :=
 
 

+ 1 - 5
arch/um/kernel/process.c

@@ -88,11 +88,8 @@ static inline void set_current(struct task_struct *task)
 
 
 extern void arch_switch_to(struct task_struct *to);
 extern void arch_switch_to(struct task_struct *to);
 
 
-void *_switch_to(void *prev, void *next, void *last)
+void *__switch_to(struct task_struct *from, struct task_struct *to)
 {
 {
-	struct task_struct *from = prev;
-	struct task_struct *to = next;
-
 	to->thread.prev_sched = from;
 	to->thread.prev_sched = from;
 	set_current(to);
 	set_current(to);
 
 
@@ -111,7 +108,6 @@ void *_switch_to(void *prev, void *next, void *last)
 	} while (current->thread.saved_task);
 	} while (current->thread.saved_task);
 
 
 	return current->thread.prev_sched;
 	return current->thread.prev_sched;
-
 }
 }
 
 
 void interrupt_end(void)
 void interrupt_end(void)

+ 0 - 1
arch/um/kernel/skas/mmu.c

@@ -103,7 +103,6 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
 
 
 void uml_setup_stubs(struct mm_struct *mm)
 void uml_setup_stubs(struct mm_struct *mm)
 {
 {
-	struct page **pages;
 	int err, ret;
 	int err, ret;
 
 
 	if (!skas_needs_stub)
 	if (!skas_needs_stub)

+ 3 - 0
arch/x86/Makefile.um

@@ -14,6 +14,9 @@ LINK-y			+= $(call cc-option,-m32)
 
 
 export LDFLAGS
 export LDFLAGS
 
 
+LDS_EXTRA		:= -Ui386
+export LDS_EXTRA
+
 # First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y.
 # First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y.
 include $(srctree)/arch/x86/Makefile_32.cpu
 include $(srctree)/arch/x86/Makefile_32.cpu
 
 

+ 2 - 2
arch/x86/include/asm/cmpxchg.h

@@ -43,7 +43,7 @@ extern void __add_wrong_size(void)
 		switch (sizeof(*(ptr))) {				\
 		switch (sizeof(*(ptr))) {				\
 		case __X86_CASE_B:					\
 		case __X86_CASE_B:					\
 			asm volatile (lock #op "b %b0, %1\n"		\
 			asm volatile (lock #op "b %b0, %1\n"		\
-				      : "+r" (__ret), "+m" (*(ptr))	\
+				      : "+q" (__ret), "+m" (*(ptr))	\
 				      : : "memory", "cc");		\
 				      : : "memory", "cc");		\
 			break;						\
 			break;						\
 		case __X86_CASE_W:					\
 		case __X86_CASE_W:					\
@@ -173,7 +173,7 @@ extern void __add_wrong_size(void)
 		switch (sizeof(*(ptr))) {				\
 		switch (sizeof(*(ptr))) {				\
 		case __X86_CASE_B:					\
 		case __X86_CASE_B:					\
 			asm volatile (lock "addb %b1, %0\n"		\
 			asm volatile (lock "addb %b1, %0\n"		\
-				      : "+m" (*(ptr)) : "ri" (inc)	\
+				      : "+m" (*(ptr)) : "qi" (inc)	\
 				      : "memory", "cc");		\
 				      : "memory", "cc");		\
 			break;						\
 			break;						\
 		case __X86_CASE_W:					\
 		case __X86_CASE_W:					\

+ 2 - 0
arch/x86/include/asm/uaccess.h

@@ -557,6 +557,8 @@ struct __large_struct { unsigned long buf[100]; };
 
 
 extern unsigned long
 extern unsigned long
 copy_from_user_nmi(void *to, const void __user *from, unsigned long n);
 copy_from_user_nmi(void *to, const void __user *from, unsigned long n);
+extern __must_check long
+strncpy_from_user(char *dst, const char __user *src, long count);
 
 
 /*
 /*
  * movsl can be slow when source and dest are not both 8-byte aligned
  * movsl can be slow when source and dest are not both 8-byte aligned

+ 0 - 5
arch/x86/include/asm/uaccess_32.h

@@ -213,11 +213,6 @@ static inline unsigned long __must_check copy_from_user(void *to,
 	return n;
 	return n;
 }
 }
 
 
-long __must_check strncpy_from_user(char *dst, const char __user *src,
-				    long count);
-long __must_check __strncpy_from_user(char *dst,
-				      const char __user *src, long count);
-
 /**
 /**
  * strlen_user: - Get the size of a string in user space.
  * strlen_user: - Get the size of a string in user space.
  * @str: The string to measure.
  * @str: The string to measure.

+ 0 - 4
arch/x86/include/asm/uaccess_64.h

@@ -208,10 +208,6 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
 	}
 	}
 }
 }
 
 
-__must_check long
-strncpy_from_user(char *dst, const char __user *src, long count);
-__must_check long
-__strncpy_from_user(char *dst, const char __user *src, long count);
 __must_check long strnlen_user(const char __user *str, long n);
 __must_check long strnlen_user(const char __user *str, long n);
 __must_check long __strnlen_user(const char __user *str, long n);
 __must_check long __strnlen_user(const char __user *str, long n);
 __must_check long strlen_user(const char __user *str);
 __must_check long strlen_user(const char __user *str);

+ 3 - 3
arch/x86/kernel/vsyscall_64.c

@@ -216,9 +216,9 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
 	current_thread_info()->sig_on_uaccess_error = 1;
 	current_thread_info()->sig_on_uaccess_error = 1;
 
 
 	/*
 	/*
-	 * 0 is a valid user pointer (in the access_ok sense) on 32-bit and
+	 * NULL is a valid user pointer (in the access_ok sense) on 32-bit and
 	 * 64-bit, so we don't need to special-case it here.  For all the
 	 * 64-bit, so we don't need to special-case it here.  For all the
-	 * vsyscalls, 0 means "don't write anything" not "write it at
+	 * vsyscalls, NULL means "don't write anything" not "write it at
 	 * address 0".
 	 * address 0".
 	 */
 	 */
 	ret = -EFAULT;
 	ret = -EFAULT;
@@ -247,7 +247,7 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
 
 
 		ret = sys_getcpu((unsigned __user *)regs->di,
 		ret = sys_getcpu((unsigned __user *)regs->di,
 				 (unsigned __user *)regs->si,
 				 (unsigned __user *)regs->si,
-				 0);
+				 NULL);
 		break;
 		break;
 	}
 	}
 
 

+ 103 - 0
arch/x86/lib/usercopy.c

@@ -7,6 +7,8 @@
 #include <linux/highmem.h>
 #include <linux/highmem.h>
 #include <linux/module.h>
 #include <linux/module.h>
 
 
+#include <asm/word-at-a-time.h>
+
 /*
 /*
  * best effort, GUP based copy_from_user() that is NMI-safe
  * best effort, GUP based copy_from_user() that is NMI-safe
  */
  */
@@ -41,3 +43,104 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
 	return len;
 	return len;
 }
 }
 EXPORT_SYMBOL_GPL(copy_from_user_nmi);
 EXPORT_SYMBOL_GPL(copy_from_user_nmi);
+
+static inline unsigned long count_bytes(unsigned long mask)
+{
+	mask = (mask - 1) & ~mask;
+	mask >>= 7;
+	return count_masked_bytes(mask);
+}
+
+/*
+ * Do a strncpy, return length of string without final '\0'.
+ * 'count' is the user-supplied count (return 'count' if we
+ * hit it), 'max' is the address space maximum (and we return
+ * -EFAULT if we hit it).
+ */
+static inline long do_strncpy_from_user(char *dst, const char __user *src, long count, unsigned long max)
+{
+	long res = 0;
+
+	/*
+	 * Truncate 'max' to the user-specified limit, so that
+	 * we only have one limit we need to check in the loop
+	 */
+	if (max > count)
+		max = count;
+
+	while (max >= sizeof(unsigned long)) {
+		unsigned long c;
+
+		/* Fall back to byte-at-a-time if we get a page fault */
+		if (unlikely(__get_user(c,(unsigned long __user *)(src+res))))
+			break;
+		/* This can write a few bytes past the NUL character, but that's ok */
+		*(unsigned long *)(dst+res) = c;
+		c = has_zero(c);
+		if (c)
+			return res + count_bytes(c);
+		res += sizeof(unsigned long);
+		max -= sizeof(unsigned long);
+	}
+
+	while (max) {
+		char c;
+
+		if (unlikely(__get_user(c,src+res)))
+			return -EFAULT;
+		dst[res] = c;
+		if (!c)
+			return res;
+		res++;
+		max--;
+	}
+
+	/*
+	 * Uhhuh. We hit 'max'. But was that the user-specified maximum
+	 * too? If so, that's ok - we got as much as the user asked for.
+	 */
+	if (res >= count)
+		return res;
+
+	/*
+	 * Nope: we hit the address space limit, and we still had more
+	 * characters the caller would have wanted. That's an EFAULT.
+	 */
+	return -EFAULT;
+}
+
+/**
+ * strncpy_from_user: - Copy a NUL terminated string from userspace.
+ * @dst:   Destination address, in kernel space.  This buffer must be at
+ *         least @count bytes long.
+ * @src:   Source address, in user space.
+ * @count: Maximum number of bytes to copy, including the trailing NUL.
+ *
+ * Copies a NUL-terminated string from userspace to kernel space.
+ *
+ * On success, returns the length of the string (not including the trailing
+ * NUL).
+ *
+ * If access to userspace fails, returns -EFAULT (some data may have been
+ * copied).
+ *
+ * If @count is smaller than the length of the string, copies @count bytes
+ * and returns @count.
+ */
+long
+strncpy_from_user(char *dst, const char __user *src, long count)
+{
+	unsigned long max_addr, src_addr;
+
+	if (unlikely(count <= 0))
+		return 0;
+
+	max_addr = current_thread_info()->addr_limit.seg;
+	src_addr = (unsigned long)src;
+	if (likely(src_addr < max_addr)) {
+		unsigned long max = max_addr - src_addr;
+		return do_strncpy_from_user(dst, src, count, max);
+	}
+	return -EFAULT;
+}
+EXPORT_SYMBOL(strncpy_from_user);

+ 0 - 87
arch/x86/lib/usercopy_32.c

@@ -32,93 +32,6 @@ static inline int __movsl_is_ok(unsigned long a1, unsigned long a2, unsigned lon
 #define movsl_is_ok(a1, a2, n) \
 #define movsl_is_ok(a1, a2, n) \
 	__movsl_is_ok((unsigned long)(a1), (unsigned long)(a2), (n))
 	__movsl_is_ok((unsigned long)(a1), (unsigned long)(a2), (n))
 
 
-/*
- * Copy a null terminated string from userspace.
- */
-
-#define __do_strncpy_from_user(dst, src, count, res)			   \
-do {									   \
-	int __d0, __d1, __d2;						   \
-	might_fault();							   \
-	__asm__ __volatile__(						   \
-		"	testl %1,%1\n"					   \
-		"	jz 2f\n"					   \
-		"0:	lodsb\n"					   \
-		"	stosb\n"					   \
-		"	testb %%al,%%al\n"				   \
-		"	jz 1f\n"					   \
-		"	decl %1\n"					   \
-		"	jnz 0b\n"					   \
-		"1:	subl %1,%0\n"					   \
-		"2:\n"							   \
-		".section .fixup,\"ax\"\n"				   \
-		"3:	movl %5,%0\n"					   \
-		"	jmp 2b\n"					   \
-		".previous\n"						   \
-		_ASM_EXTABLE(0b,3b)					   \
-		: "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1),	   \
-		  "=&D" (__d2)						   \
-		: "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
-		: "memory");						   \
-} while (0)
-
-/**
- * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
- * @dst:   Destination address, in kernel space.  This buffer must be at
- *         least @count bytes long.
- * @src:   Source address, in user space.
- * @count: Maximum number of bytes to copy, including the trailing NUL.
- *
- * Copies a NUL-terminated string from userspace to kernel space.
- * Caller must check the specified block with access_ok() before calling
- * this function.
- *
- * On success, returns the length of the string (not including the trailing
- * NUL).
- *
- * If access to userspace fails, returns -EFAULT (some data may have been
- * copied).
- *
- * If @count is smaller than the length of the string, copies @count bytes
- * and returns @count.
- */
-long
-__strncpy_from_user(char *dst, const char __user *src, long count)
-{
-	long res;
-	__do_strncpy_from_user(dst, src, count, res);
-	return res;
-}
-EXPORT_SYMBOL(__strncpy_from_user);
-
-/**
- * strncpy_from_user: - Copy a NUL terminated string from userspace.
- * @dst:   Destination address, in kernel space.  This buffer must be at
- *         least @count bytes long.
- * @src:   Source address, in user space.
- * @count: Maximum number of bytes to copy, including the trailing NUL.
- *
- * Copies a NUL-terminated string from userspace to kernel space.
- *
- * On success, returns the length of the string (not including the trailing
- * NUL).
- *
- * If access to userspace fails, returns -EFAULT (some data may have been
- * copied).
- *
- * If @count is smaller than the length of the string, copies @count bytes
- * and returns @count.
- */
-long
-strncpy_from_user(char *dst, const char __user *src, long count)
-{
-	long res = -EFAULT;
-	if (access_ok(VERIFY_READ, src, 1))
-		__do_strncpy_from_user(dst, src, count, res);
-	return res;
-}
-EXPORT_SYMBOL(strncpy_from_user);
-
 /*
 /*
  * Zero Userspace
  * Zero Userspace
  */
  */

+ 0 - 49
arch/x86/lib/usercopy_64.c

@@ -8,55 +8,6 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
 
 
-/*
- * Copy a null terminated string from userspace.
- */
-
-#define __do_strncpy_from_user(dst,src,count,res)			   \
-do {									   \
-	long __d0, __d1, __d2;						   \
-	might_fault();							   \
-	__asm__ __volatile__(						   \
-		"	testq %1,%1\n"					   \
-		"	jz 2f\n"					   \
-		"0:	lodsb\n"					   \
-		"	stosb\n"					   \
-		"	testb %%al,%%al\n"				   \
-		"	jz 1f\n"					   \
-		"	decq %1\n"					   \
-		"	jnz 0b\n"					   \
-		"1:	subq %1,%0\n"					   \
-		"2:\n"							   \
-		".section .fixup,\"ax\"\n"				   \
-		"3:	movq %5,%0\n"					   \
-		"	jmp 2b\n"					   \
-		".previous\n"						   \
-		_ASM_EXTABLE(0b,3b)					   \
-		: "=&r"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1),	   \
-		  "=&D" (__d2)						   \
-		: "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
-		: "memory");						   \
-} while (0)
-
-long
-__strncpy_from_user(char *dst, const char __user *src, long count)
-{
-	long res;
-	__do_strncpy_from_user(dst, src, count, res);
-	return res;
-}
-EXPORT_SYMBOL(__strncpy_from_user);
-
-long
-strncpy_from_user(char *dst, const char __user *src, long count)
-{
-	long res = -EFAULT;
-	if (access_ok(VERIFY_READ, src, 1))
-		return __strncpy_from_user(dst, src, count);
-	return res;
-}
-EXPORT_SYMBOL(strncpy_from_user);
-
 /*
 /*
  * Zero Userspace
  * Zero Userspace
  */
  */

+ 75 - 0
arch/x86/um/asm/barrier.h

@@ -0,0 +1,75 @@
+#ifndef _ASM_UM_BARRIER_H_
+#define _ASM_UM_BARRIER_H_
+
+#include <asm/asm.h>
+#include <asm/segment.h>
+#include <asm/cpufeature.h>
+#include <asm/cmpxchg.h>
+#include <asm/nops.h>
+
+#include <linux/kernel.h>
+#include <linux/irqflags.h>
+
+/*
+ * Force strict CPU ordering.
+ * And yes, this is required on UP too when we're talking
+ * to devices.
+ */
+#ifdef CONFIG_X86_32
+
+#define mb()	alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
+#define rmb()	alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
+#define wmb()	alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
+
+#else /* CONFIG_X86_32 */
+
+#define mb()	asm volatile("mfence" : : : "memory")
+#define rmb()	asm volatile("lfence" : : : "memory")
+#define wmb()	asm volatile("sfence" : : : "memory")
+
+#endif /* CONFIG_X86_32 */
+
+#define read_barrier_depends()	do { } while (0)
+
+#ifdef CONFIG_SMP
+
+#define smp_mb()	mb()
+#ifdef CONFIG_X86_PPRO_FENCE
+#define smp_rmb()	rmb()
+#else /* CONFIG_X86_PPRO_FENCE */
+#define smp_rmb()	barrier()
+#endif /* CONFIG_X86_PPRO_FENCE */
+
+#ifdef CONFIG_X86_OOSTORE
+#define smp_wmb()	wmb()
+#else /* CONFIG_X86_OOSTORE */
+#define smp_wmb()	barrier()
+#endif /* CONFIG_X86_OOSTORE */
+
+#define smp_read_barrier_depends()	read_barrier_depends()
+#define set_mb(var, value) do { (void)xchg(&var, value); } while (0)
+
+#else /* CONFIG_SMP */
+
+#define smp_mb()	barrier()
+#define smp_rmb()	barrier()
+#define smp_wmb()	barrier()
+#define smp_read_barrier_depends()	do { } while (0)
+#define set_mb(var, value) do { var = value; barrier(); } while (0)
+
+#endif /* CONFIG_SMP */
+
+/*
+ * Stop RDTSC speculation. This is needed when you need to use RDTSC
+ * (or get_cycles or vread that possibly accesses the TSC) in a defined
+ * code region.
+ *
+ * (Could use an alternative three way for this if there was one.)
+ */
+static inline void rdtsc_barrier(void)
+{
+	alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC);
+	alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC);
+}
+
+#endif

+ 0 - 135
arch/x86/um/asm/system.h

@@ -1,135 +0,0 @@
-#ifndef _ASM_X86_SYSTEM_H_
-#define _ASM_X86_SYSTEM_H_
-
-#include <asm/asm.h>
-#include <asm/segment.h>
-#include <asm/cpufeature.h>
-#include <asm/cmpxchg.h>
-#include <asm/nops.h>
-
-#include <linux/kernel.h>
-#include <linux/irqflags.h>
-
-/* entries in ARCH_DLINFO: */
-#ifdef CONFIG_IA32_EMULATION
-# define AT_VECTOR_SIZE_ARCH 2
-#else
-# define AT_VECTOR_SIZE_ARCH 1
-#endif
-
-extern unsigned long arch_align_stack(unsigned long sp);
-
-void default_idle(void);
-
-/*
- * Force strict CPU ordering.
- * And yes, this is required on UP too when we're talking
- * to devices.
- */
-#ifdef CONFIG_X86_32
-/*
- * Some non-Intel clones support out of order store. wmb() ceases to be a
- * nop for these.
- */
-#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
-#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
-#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
-#else
-#define mb() 	asm volatile("mfence":::"memory")
-#define rmb()	asm volatile("lfence":::"memory")
-#define wmb()	asm volatile("sfence" ::: "memory")
-#endif
-
-/**
- * read_barrier_depends - Flush all pending reads that subsequents reads
- * depend on.
- *
- * No data-dependent reads from memory-like regions are ever reordered
- * over this barrier.  All reads preceding this primitive are guaranteed
- * to access memory (but not necessarily other CPUs' caches) before any
- * reads following this primitive that depend on the data return by
- * any of the preceding reads.  This primitive is much lighter weight than
- * rmb() on most CPUs, and is never heavier weight than is
- * rmb().
- *
- * These ordering constraints are respected by both the local CPU
- * and the compiler.
- *
- * Ordering is not guaranteed by anything other than these primitives,
- * not even by data dependencies.  See the documentation for
- * memory_barrier() for examples and URLs to more information.
- *
- * For example, the following code would force ordering (the initial
- * value of "a" is zero, "b" is one, and "p" is "&a"):
- *
- * <programlisting>
- *	CPU 0				CPU 1
- *
- *	b = 2;
- *	memory_barrier();
- *	p = &b;				q = p;
- *					read_barrier_depends();
- *					d = *q;
- * </programlisting>
- *
- * because the read of "*q" depends on the read of "p" and these
- * two reads are separated by a read_barrier_depends().  However,
- * the following code, with the same initial values for "a" and "b":
- *
- * <programlisting>
- *	CPU 0				CPU 1
- *
- *	a = 2;
- *	memory_barrier();
- *	b = 3;				y = b;
- *					read_barrier_depends();
- *					x = a;
- * </programlisting>
- *
- * does not enforce ordering, since there is no data dependency between
- * the read of "a" and the read of "b".  Therefore, on some CPUs, such
- * as Alpha, "y" could be set to 3 and "x" to 0.  Use rmb()
- * in cases like this where there are no data dependencies.
- **/
-
-#define read_barrier_depends()	do { } while (0)
-
-#ifdef CONFIG_SMP
-#define smp_mb()	mb()
-#ifdef CONFIG_X86_PPRO_FENCE
-# define smp_rmb()	rmb()
-#else
-# define smp_rmb()	barrier()
-#endif
-#ifdef CONFIG_X86_OOSTORE
-# define smp_wmb() 	wmb()
-#else
-# define smp_wmb()	barrier()
-#endif
-#define smp_read_barrier_depends()	read_barrier_depends()
-#define set_mb(var, value) do { (void)xchg(&var, value); } while (0)
-#else
-#define smp_mb()	barrier()
-#define smp_rmb()	barrier()
-#define smp_wmb()	barrier()
-#define smp_read_barrier_depends()	do { } while (0)
-#define set_mb(var, value) do { var = value; barrier(); } while (0)
-#endif
-
-/*
- * Stop RDTSC speculation. This is needed when you need to use RDTSC
- * (or get_cycles or vread that possibly accesses the TSC) in a defined
- * code region.
- *
- * (Could use an alternative three way for this if there was one.)
- */
-static inline void rdtsc_barrier(void)
-{
-	alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC);
-	alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC);
-}
-
-extern void *_switch_to(void *prev, void *next, void *last);
-#define switch_to(prev, next, last) prev = _switch_to(prev, next, last)
-
-#endif

+ 3 - 2
block/blk-core.c

@@ -483,7 +483,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
 	if (!q)
 	if (!q)
 		return NULL;
 		return NULL;
 
 
-	q->id = ida_simple_get(&blk_queue_ida, 0, 0, GFP_KERNEL);
+	q->id = ida_simple_get(&blk_queue_ida, 0, 0, gfp_mask);
 	if (q->id < 0)
 	if (q->id < 0)
 		goto fail_q;
 		goto fail_q;
 
 
@@ -1277,7 +1277,8 @@ static bool attempt_plug_merge(struct request_queue *q, struct bio *bio,
 	list_for_each_entry_reverse(rq, &plug->list, queuelist) {
 	list_for_each_entry_reverse(rq, &plug->list, queuelist) {
 		int el_ret;
 		int el_ret;
 
 
-		(*request_count)++;
+		if (rq->q == q)
+			(*request_count)++;
 
 
 		if (rq->q != q || !blk_rq_merge_ok(rq, bio))
 		if (rq->q != q || !blk_rq_merge_ok(rq, bio))
 			continue;
 			continue;

+ 1 - 1
block/blk-throttle.c

@@ -1218,7 +1218,7 @@ void blk_throtl_drain(struct request_queue *q)
 	struct bio_list bl;
 	struct bio_list bl;
 	struct bio *bio;
 	struct bio *bio;
 
 
-	WARN_ON_ONCE(!queue_is_locked(q));
+	queue_lockdep_assert_held(q);
 
 
 	bio_list_init(&bl);
 	bio_list_init(&bl);
 
 

+ 8 - 2
block/cfq-iosched.c

@@ -295,6 +295,7 @@ struct cfq_data {
 	unsigned int cfq_slice_idle;
 	unsigned int cfq_slice_idle;
 	unsigned int cfq_group_idle;
 	unsigned int cfq_group_idle;
 	unsigned int cfq_latency;
 	unsigned int cfq_latency;
+	unsigned int cfq_target_latency;
 
 
 	/*
 	/*
 	 * Fallback dummy cfqq for extreme OOM conditions
 	 * Fallback dummy cfqq for extreme OOM conditions
@@ -604,7 +605,7 @@ cfq_group_slice(struct cfq_data *cfqd, struct cfq_group *cfqg)
 {
 {
 	struct cfq_rb_root *st = &cfqd->grp_service_tree;
 	struct cfq_rb_root *st = &cfqd->grp_service_tree;
 
 
-	return cfq_target_latency * cfqg->weight / st->total_weight;
+	return cfqd->cfq_target_latency * cfqg->weight / st->total_weight;
 }
 }
 
 
 static inline unsigned
 static inline unsigned
@@ -2271,7 +2272,8 @@ new_workload:
 		 * to have higher weight. A more accurate thing would be to
 		 * to have higher weight. A more accurate thing would be to
 		 * calculate system wide asnc/sync ratio.
 		 * calculate system wide asnc/sync ratio.
 		 */
 		 */
-		tmp = cfq_target_latency * cfqg_busy_async_queues(cfqd, cfqg);
+		tmp = cfqd->cfq_target_latency *
+			cfqg_busy_async_queues(cfqd, cfqg);
 		tmp = tmp/cfqd->busy_queues;
 		tmp = tmp/cfqd->busy_queues;
 		slice = min_t(unsigned, slice, tmp);
 		slice = min_t(unsigned, slice, tmp);
 
 
@@ -3737,6 +3739,7 @@ static void *cfq_init_queue(struct request_queue *q)
 	cfqd->cfq_back_penalty = cfq_back_penalty;
 	cfqd->cfq_back_penalty = cfq_back_penalty;
 	cfqd->cfq_slice[0] = cfq_slice_async;
 	cfqd->cfq_slice[0] = cfq_slice_async;
 	cfqd->cfq_slice[1] = cfq_slice_sync;
 	cfqd->cfq_slice[1] = cfq_slice_sync;
+	cfqd->cfq_target_latency = cfq_target_latency;
 	cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
 	cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
 	cfqd->cfq_slice_idle = cfq_slice_idle;
 	cfqd->cfq_slice_idle = cfq_slice_idle;
 	cfqd->cfq_group_idle = cfq_group_idle;
 	cfqd->cfq_group_idle = cfq_group_idle;
@@ -3788,6 +3791,7 @@ SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1);
 SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1);
 SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1);
 SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0);
 SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0);
 SHOW_FUNCTION(cfq_low_latency_show, cfqd->cfq_latency, 0);
 SHOW_FUNCTION(cfq_low_latency_show, cfqd->cfq_latency, 0);
+SHOW_FUNCTION(cfq_target_latency_show, cfqd->cfq_target_latency, 1);
 #undef SHOW_FUNCTION
 #undef SHOW_FUNCTION
 
 
 #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV)			\
 #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV)			\
@@ -3821,6 +3825,7 @@ STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1);
 STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1,
 STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1,
 		UINT_MAX, 0);
 		UINT_MAX, 0);
 STORE_FUNCTION(cfq_low_latency_store, &cfqd->cfq_latency, 0, 1, 0);
 STORE_FUNCTION(cfq_low_latency_store, &cfqd->cfq_latency, 0, 1, 0);
+STORE_FUNCTION(cfq_target_latency_store, &cfqd->cfq_target_latency, 1, UINT_MAX, 1);
 #undef STORE_FUNCTION
 #undef STORE_FUNCTION
 
 
 #define CFQ_ATTR(name) \
 #define CFQ_ATTR(name) \
@@ -3838,6 +3843,7 @@ static struct elv_fs_entry cfq_attrs[] = {
 	CFQ_ATTR(slice_idle),
 	CFQ_ATTR(slice_idle),
 	CFQ_ATTR(group_idle),
 	CFQ_ATTR(group_idle),
 	CFQ_ATTR(low_latency),
 	CFQ_ATTR(low_latency),
+	CFQ_ATTR(target_latency),
 	__ATTR_NULL
 	__ATTR_NULL
 };
 };
 
 

+ 3 - 3
crypto/Kconfig

@@ -627,7 +627,7 @@ config CRYPTO_BLOWFISH_COMMON
 
 
 config CRYPTO_BLOWFISH_X86_64
 config CRYPTO_BLOWFISH_X86_64
 	tristate "Blowfish cipher algorithm (x86_64)"
 	tristate "Blowfish cipher algorithm (x86_64)"
-	depends on (X86 || UML_X86) && 64BIT
+	depends on X86 && 64BIT
 	select CRYPTO_ALGAPI
 	select CRYPTO_ALGAPI
 	select CRYPTO_BLOWFISH_COMMON
 	select CRYPTO_BLOWFISH_COMMON
 	help
 	help
@@ -657,7 +657,7 @@ config CRYPTO_CAMELLIA
 
 
 config CRYPTO_CAMELLIA_X86_64
 config CRYPTO_CAMELLIA_X86_64
 	tristate "Camellia cipher algorithm (x86_64)"
 	tristate "Camellia cipher algorithm (x86_64)"
-	depends on (X86 || UML_X86) && 64BIT
+	depends on X86 && 64BIT
 	depends on CRYPTO
 	depends on CRYPTO
 	select CRYPTO_ALGAPI
 	select CRYPTO_ALGAPI
 	select CRYPTO_LRW
 	select CRYPTO_LRW
@@ -893,7 +893,7 @@ config CRYPTO_TWOFISH_X86_64
 
 
 config CRYPTO_TWOFISH_X86_64_3WAY
 config CRYPTO_TWOFISH_X86_64_3WAY
 	tristate "Twofish cipher algorithm (x86_64, 3-way parallel)"
 	tristate "Twofish cipher algorithm (x86_64, 3-way parallel)"
-	depends on (X86 || UML_X86) && 64BIT
+	depends on X86 && 64BIT
 	select CRYPTO_ALGAPI
 	select CRYPTO_ALGAPI
 	select CRYPTO_TWOFISH_COMMON
 	select CRYPTO_TWOFISH_COMMON
 	select CRYPTO_TWOFISH_X86_64
 	select CRYPTO_TWOFISH_X86_64

+ 1 - 41
drivers/amba/bus.c

@@ -247,8 +247,7 @@ static int amba_pm_restore(struct device *dev)
 /*
 /*
  * Hooks to provide runtime PM of the pclk (bus clock).  It is safe to
  * Hooks to provide runtime PM of the pclk (bus clock).  It is safe to
  * enable/disable the bus clock at runtime PM suspend/resume as this
  * enable/disable the bus clock at runtime PM suspend/resume as this
- * does not result in loss of context.  However, disabling vcore power
- * would do, so we leave that to the driver.
+ * does not result in loss of context.
  */
  */
 static int amba_pm_runtime_suspend(struct device *dev)
 static int amba_pm_runtime_suspend(struct device *dev)
 {
 {
@@ -354,39 +353,6 @@ static void amba_put_disable_pclk(struct amba_device *pcdev)
 	clk_put(pclk);
 	clk_put(pclk);
 }
 }
 
 
-static int amba_get_enable_vcore(struct amba_device *pcdev)
-{
-	struct regulator *vcore = regulator_get(&pcdev->dev, "vcore");
-	int ret;
-
-	pcdev->vcore = vcore;
-
-	if (IS_ERR(vcore)) {
-		/* It is OK not to supply a vcore regulator */
-		if (PTR_ERR(vcore) == -ENODEV)
-			return 0;
-		return PTR_ERR(vcore);
-	}
-
-	ret = regulator_enable(vcore);
-	if (ret) {
-		regulator_put(vcore);
-		pcdev->vcore = ERR_PTR(-ENODEV);
-	}
-
-	return ret;
-}
-
-static void amba_put_disable_vcore(struct amba_device *pcdev)
-{
-	struct regulator *vcore = pcdev->vcore;
-
-	if (!IS_ERR(vcore)) {
-		regulator_disable(vcore);
-		regulator_put(vcore);
-	}
-}
-
 /*
 /*
  * These are the device model conversion veneers; they convert the
  * These are the device model conversion veneers; they convert the
  * device model structures to our more specific structures.
  * device model structures to our more specific structures.
@@ -399,10 +365,6 @@ static int amba_probe(struct device *dev)
 	int ret;
 	int ret;
 
 
 	do {
 	do {
-		ret = amba_get_enable_vcore(pcdev);
-		if (ret)
-			break;
-
 		ret = amba_get_enable_pclk(pcdev);
 		ret = amba_get_enable_pclk(pcdev);
 		if (ret)
 		if (ret)
 			break;
 			break;
@@ -420,7 +382,6 @@ static int amba_probe(struct device *dev)
 		pm_runtime_put_noidle(dev);
 		pm_runtime_put_noidle(dev);
 
 
 		amba_put_disable_pclk(pcdev);
 		amba_put_disable_pclk(pcdev);
-		amba_put_disable_vcore(pcdev);
 	} while (0);
 	} while (0);
 
 
 	return ret;
 	return ret;
@@ -442,7 +403,6 @@ static int amba_remove(struct device *dev)
 	pm_runtime_put_noidle(dev);
 	pm_runtime_put_noidle(dev);
 
 
 	amba_put_disable_pclk(pcdev);
 	amba_put_disable_pclk(pcdev);
-	amba_put_disable_vcore(pcdev);
 
 
 	return ret;
 	return ret;
 }
 }

+ 1 - 3
drivers/base/soc.c

@@ -15,7 +15,7 @@
 #include <linux/sys_soc.h>
 #include <linux/sys_soc.h>
 #include <linux/err.h>
 #include <linux/err.h>
 
 
-static DEFINE_IDR(soc_ida);
+static DEFINE_IDA(soc_ida);
 static DEFINE_SPINLOCK(soc_lock);
 static DEFINE_SPINLOCK(soc_lock);
 
 
 static ssize_t soc_info_get(struct device *dev,
 static ssize_t soc_info_get(struct device *dev,
@@ -168,8 +168,6 @@ void soc_device_unregister(struct soc_device *soc_dev)
 
 
 static int __init soc_bus_register(void)
 static int __init soc_bus_register(void)
 {
 {
-	spin_lock_init(&soc_lock);
-
 	return bus_register(&soc_bus_type);
 	return bus_register(&soc_bus_type);
 }
 }
 core_initcall(soc_bus_register);
 core_initcall(soc_bus_register);

+ 1 - 1
drivers/bcma/Kconfig

@@ -29,7 +29,7 @@ config BCMA_HOST_PCI
 
 
 config BCMA_DRIVER_PCI_HOSTMODE
 config BCMA_DRIVER_PCI_HOSTMODE
 	bool "Driver for PCI core working in hostmode"
 	bool "Driver for PCI core working in hostmode"
-	depends on BCMA && MIPS
+	depends on BCMA && MIPS && BCMA_HOST_PCI
 	help
 	help
 	  PCI core hostmode operation (external PCI bus).
 	  PCI core hostmode operation (external PCI bus).
 
 

+ 1 - 0
drivers/bcma/driver_pci_host.c

@@ -10,6 +10,7 @@
  */
  */
 
 
 #include "bcma_private.h"
 #include "bcma_private.h"
+#include <linux/pci.h>
 #include <linux/export.h>
 #include <linux/export.h>
 #include <linux/bcma/bcma.h>
 #include <linux/bcma/bcma.h>
 #include <asm/paccess.h>
 #include <asm/paccess.h>

+ 2 - 1
drivers/block/cciss_scsi.c

@@ -866,6 +866,7 @@ cciss_scsi_detect(ctlr_info_t *h)
 	sh->can_queue = cciss_tape_cmds;
 	sh->can_queue = cciss_tape_cmds;
 	sh->sg_tablesize = h->maxsgentries;
 	sh->sg_tablesize = h->maxsgentries;
 	sh->max_cmd_len = MAX_COMMAND_SIZE;
 	sh->max_cmd_len = MAX_COMMAND_SIZE;
+	sh->max_sectors = h->cciss_max_sectors;
 
 
 	((struct cciss_scsi_adapter_data_t *) 
 	((struct cciss_scsi_adapter_data_t *) 
 		h->scsi_ctlr)->scsi_host = sh;
 		h->scsi_ctlr)->scsi_host = sh;
@@ -1410,7 +1411,7 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *c,
 	/* track how many SG entries we are using */
 	/* track how many SG entries we are using */
 	if (request_nsgs > h->maxSG)
 	if (request_nsgs > h->maxSG)
 		h->maxSG = request_nsgs;
 		h->maxSG = request_nsgs;
-	c->Header.SGTotal = (__u8) request_nsgs + chained;
+	c->Header.SGTotal = (u16) request_nsgs + chained;
 	if (request_nsgs > h->max_cmd_sgentries)
 	if (request_nsgs > h->max_cmd_sgentries)
 		c->Header.SGList = h->max_cmd_sgentries;
 		c->Header.SGList = h->max_cmd_sgentries;
 	else
 	else

+ 1 - 1
drivers/block/mtip32xx/Kconfig

@@ -4,6 +4,6 @@
 
 
 config BLK_DEV_PCIESSD_MTIP32XX
 config BLK_DEV_PCIESSD_MTIP32XX
 	tristate "Block Device Driver for Micron PCIe SSDs"
 	tristate "Block Device Driver for Micron PCIe SSDs"
-	depends on HOTPLUG_PCI_PCIE
+	depends on PCI
 	help
 	help
           This enables the block driver for Micron PCIe SSDs.
           This enables the block driver for Micron PCIe SSDs.

+ 664 - 196
drivers/block/mtip32xx/mtip32xx.c

@@ -36,6 +36,7 @@
 #include <linux/idr.h>
 #include <linux/idr.h>
 #include <linux/kthread.h>
 #include <linux/kthread.h>
 #include <../drivers/ata/ahci.h>
 #include <../drivers/ata/ahci.h>
+#include <linux/export.h>
 #include "mtip32xx.h"
 #include "mtip32xx.h"
 
 
 #define HW_CMD_SLOT_SZ		(MTIP_MAX_COMMAND_SLOTS * 32)
 #define HW_CMD_SLOT_SZ		(MTIP_MAX_COMMAND_SLOTS * 32)
@@ -44,6 +45,7 @@
 #define HW_PORT_PRIV_DMA_SZ \
 #define HW_PORT_PRIV_DMA_SZ \
 		(HW_CMD_SLOT_SZ + HW_CMD_TBL_AR_SZ + AHCI_RX_FIS_SZ)
 		(HW_CMD_SLOT_SZ + HW_CMD_TBL_AR_SZ + AHCI_RX_FIS_SZ)
 
 
+#define HOST_CAP_NZDMA		(1 << 19)
 #define HOST_HSORG		0xFC
 #define HOST_HSORG		0xFC
 #define HSORG_DISABLE_SLOTGRP_INTR (1<<24)
 #define HSORG_DISABLE_SLOTGRP_INTR (1<<24)
 #define HSORG_DISABLE_SLOTGRP_PXIS (1<<16)
 #define HSORG_DISABLE_SLOTGRP_PXIS (1<<16)
@@ -139,6 +141,12 @@ static void mtip_command_cleanup(struct driver_data *dd)
 	int group = 0, commandslot = 0, commandindex = 0;
 	int group = 0, commandslot = 0, commandindex = 0;
 	struct mtip_cmd *command;
 	struct mtip_cmd *command;
 	struct mtip_port *port = dd->port;
 	struct mtip_port *port = dd->port;
+	static int in_progress;
+
+	if (in_progress)
+		return;
+
+	in_progress = 1;
 
 
 	for (group = 0; group < 4; group++) {
 	for (group = 0; group < 4; group++) {
 		for (commandslot = 0; commandslot < 32; commandslot++) {
 		for (commandslot = 0; commandslot < 32; commandslot++) {
@@ -165,7 +173,8 @@ static void mtip_command_cleanup(struct driver_data *dd)
 
 
 	up(&port->cmd_slot);
 	up(&port->cmd_slot);
 
 
-	atomic_set(&dd->drv_cleanup_done, true);
+	set_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag);
+	in_progress = 0;
 }
 }
 
 
 /*
 /*
@@ -262,6 +271,9 @@ static int hba_reset_nosleep(struct driver_data *dd)
 		 && time_before(jiffies, timeout))
 		 && time_before(jiffies, timeout))
 		mdelay(1);
 		mdelay(1);
 
 
+	if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))
+		return -1;
+
 	if (readl(dd->mmio + HOST_CTL) & HOST_RESET)
 	if (readl(dd->mmio + HOST_CTL) & HOST_RESET)
 		return -1;
 		return -1;
 
 
@@ -294,6 +306,10 @@ static inline void mtip_issue_ncq_command(struct mtip_port *port, int tag)
 			port->cmd_issue[MTIP_TAG_INDEX(tag)]);
 			port->cmd_issue[MTIP_TAG_INDEX(tag)]);
 
 
 	spin_unlock_irqrestore(&port->cmd_issue_lock, flags);
 	spin_unlock_irqrestore(&port->cmd_issue_lock, flags);
+
+	/* Set the command's timeout value.*/
+	port->commands[tag].comp_time = jiffies + msecs_to_jiffies(
+					MTIP_NCQ_COMMAND_TIMEOUT_MS);
 }
 }
 
 
 /*
 /*
@@ -420,7 +436,12 @@ static void mtip_init_port(struct mtip_port *port)
 		writel(0xFFFFFFFF, port->completed[i]);
 		writel(0xFFFFFFFF, port->completed[i]);
 
 
 	/* Clear any pending interrupts for this port */
 	/* Clear any pending interrupts for this port */
-	writel(readl(port->mmio + PORT_IRQ_STAT), port->mmio + PORT_IRQ_STAT);
+	writel(readl(port->dd->mmio + PORT_IRQ_STAT),
+					port->dd->mmio + PORT_IRQ_STAT);
+
+	/* Clear any pending interrupts on the HBA. */
+	writel(readl(port->dd->mmio + HOST_IRQ_STAT),
+					port->dd->mmio + HOST_IRQ_STAT);
 
 
 	/* Enable port interrupts */
 	/* Enable port interrupts */
 	writel(DEF_PORT_IRQ, port->mmio + PORT_IRQ_MASK);
 	writel(DEF_PORT_IRQ, port->mmio + PORT_IRQ_MASK);
@@ -447,6 +468,9 @@ static void mtip_restart_port(struct mtip_port *port)
 		 && time_before(jiffies, timeout))
 		 && time_before(jiffies, timeout))
 		;
 		;
 
 
+	if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+		return;
+
 	/*
 	/*
 	 * Chip quirk: escalate to hba reset if
 	 * Chip quirk: escalate to hba reset if
 	 * PxCMD.CR not clear after 500 ms
 	 * PxCMD.CR not clear after 500 ms
@@ -475,6 +499,9 @@ static void mtip_restart_port(struct mtip_port *port)
 	while (time_before(jiffies, timeout))
 	while (time_before(jiffies, timeout))
 		;
 		;
 
 
+	if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+		return;
+
 	/* Clear PxSCTL.DET */
 	/* Clear PxSCTL.DET */
 	writel(readl(port->mmio + PORT_SCR_CTL) & ~1,
 	writel(readl(port->mmio + PORT_SCR_CTL) & ~1,
 			 port->mmio + PORT_SCR_CTL);
 			 port->mmio + PORT_SCR_CTL);
@@ -486,15 +513,35 @@ static void mtip_restart_port(struct mtip_port *port)
 			 && time_before(jiffies, timeout))
 			 && time_before(jiffies, timeout))
 		;
 		;
 
 
+	if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+		return;
+
 	if ((readl(port->mmio + PORT_SCR_STAT) & 0x01) == 0)
 	if ((readl(port->mmio + PORT_SCR_STAT) & 0x01) == 0)
 		dev_warn(&port->dd->pdev->dev,
 		dev_warn(&port->dd->pdev->dev,
 			"COM reset failed\n");
 			"COM reset failed\n");
 
 
-	/* Clear SError, the PxSERR.DIAG.x should be set so clear it */
-	writel(readl(port->mmio + PORT_SCR_ERR), port->mmio + PORT_SCR_ERR);
+	mtip_init_port(port);
+	mtip_start_port(port);
 
 
-	/* Enable the DMA engine */
-	mtip_enable_engine(port, 1);
+}
+
+/*
+ * Helper function for tag logging
+ */
+static void print_tags(struct driver_data *dd,
+			char *msg,
+			unsigned long *tagbits,
+			int cnt)
+{
+	unsigned char tagmap[128];
+	int group, tagmap_len = 0;
+
+	memset(tagmap, 0, sizeof(tagmap));
+	for (group = SLOTBITS_IN_LONGS; group > 0; group--)
+		tagmap_len = sprintf(tagmap + tagmap_len, "%016lX ",
+						tagbits[group-1]);
+	dev_warn(&dd->pdev->dev,
+			"%d command(s) %s: tagmap [%s]", cnt, msg, tagmap);
 }
 }
 
 
 /*
 /*
@@ -514,15 +561,18 @@ static void mtip_timeout_function(unsigned long int data)
 	int tag, cmdto_cnt = 0;
 	int tag, cmdto_cnt = 0;
 	unsigned int bit, group;
 	unsigned int bit, group;
 	unsigned int num_command_slots = port->dd->slot_groups * 32;
 	unsigned int num_command_slots = port->dd->slot_groups * 32;
+	unsigned long to, tagaccum[SLOTBITS_IN_LONGS];
 
 
 	if (unlikely(!port))
 	if (unlikely(!port))
 		return;
 		return;
 
 
-	if (atomic_read(&port->dd->resumeflag) == true) {
+	if (test_bit(MTIP_DDF_RESUME_BIT, &port->dd->dd_flag)) {
 		mod_timer(&port->cmd_timer,
 		mod_timer(&port->cmd_timer,
 			jiffies + msecs_to_jiffies(30000));
 			jiffies + msecs_to_jiffies(30000));
 		return;
 		return;
 	}
 	}
+	/* clear the tag accumulator */
+	memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
 
 
 	for (tag = 0; tag < num_command_slots; tag++) {
 	for (tag = 0; tag < num_command_slots; tag++) {
 		/*
 		/*
@@ -540,12 +590,10 @@ static void mtip_timeout_function(unsigned long int data)
 			command = &port->commands[tag];
 			command = &port->commands[tag];
 			fis = (struct host_to_dev_fis *) command->command;
 			fis = (struct host_to_dev_fis *) command->command;
 
 
-			dev_warn(&port->dd->pdev->dev,
-				"Timeout for command tag %d\n", tag);
-
+			set_bit(tag, tagaccum);
 			cmdto_cnt++;
 			cmdto_cnt++;
 			if (cmdto_cnt == 1)
 			if (cmdto_cnt == 1)
-				set_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags);
+				set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
 
 
 			/*
 			/*
 			 * Clear the completed bit. This should prevent
 			 * Clear the completed bit. This should prevent
@@ -578,15 +626,29 @@ static void mtip_timeout_function(unsigned long int data)
 		}
 		}
 	}
 	}
 
 
-	if (cmdto_cnt) {
-		dev_warn(&port->dd->pdev->dev,
-			"%d commands timed out: restarting port",
-			cmdto_cnt);
+	if (cmdto_cnt && !test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) {
+		print_tags(port->dd, "timed out", tagaccum, cmdto_cnt);
+
 		mtip_restart_port(port);
 		mtip_restart_port(port);
-		clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags);
+		clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
 		wake_up_interruptible(&port->svc_wait);
 		wake_up_interruptible(&port->svc_wait);
 	}
 	}
 
 
+	if (port->ic_pause_timer) {
+		to  = port->ic_pause_timer + msecs_to_jiffies(1000);
+		if (time_after(jiffies, to)) {
+			if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) {
+				port->ic_pause_timer = 0;
+				clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
+				clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags);
+				clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
+				wake_up_interruptible(&port->svc_wait);
+			}
+
+
+		}
+	}
+
 	/* Restart the timer */
 	/* Restart the timer */
 	mod_timer(&port->cmd_timer,
 	mod_timer(&port->cmd_timer,
 		jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD));
 		jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD));
@@ -681,23 +743,18 @@ static void mtip_completion(struct mtip_port *port,
 	complete(waiting);
 	complete(waiting);
 }
 }
 
 
-/*
- * Helper function for tag logging
- */
-static void print_tags(struct driver_data *dd,
-			char *msg,
-			unsigned long *tagbits)
+static void mtip_null_completion(struct mtip_port *port,
+			    int tag,
+			    void *data,
+			    int status)
 {
 {
-	unsigned int tag, count = 0;
-
-	for (tag = 0; tag < (dd->slot_groups) * 32; tag++) {
-		if (test_bit(tag, tagbits))
-			count++;
-	}
-	if (count)
-		dev_info(&dd->pdev->dev, "%s [%i tags]\n", msg, count);
+	return;
 }
 }
 
 
+static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer,
+				dma_addr_t buffer_dma, unsigned int sectors);
+static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id,
+						struct smart_attr *attrib);
 /*
 /*
  * Handle an error.
  * Handle an error.
  *
  *
@@ -708,12 +765,16 @@ static void print_tags(struct driver_data *dd,
  */
  */
 static void mtip_handle_tfe(struct driver_data *dd)
 static void mtip_handle_tfe(struct driver_data *dd)
 {
 {
-	int group, tag, bit, reissue;
+	int group, tag, bit, reissue, rv;
 	struct mtip_port *port;
 	struct mtip_port *port;
-	struct mtip_cmd  *command;
+	struct mtip_cmd  *cmd;
 	u32 completed;
 	u32 completed;
 	struct host_to_dev_fis *fis;
 	struct host_to_dev_fis *fis;
 	unsigned long tagaccum[SLOTBITS_IN_LONGS];
 	unsigned long tagaccum[SLOTBITS_IN_LONGS];
+	unsigned int cmd_cnt = 0;
+	unsigned char *buf;
+	char *fail_reason = NULL;
+	int fail_all_ncq_write = 0, fail_all_ncq_cmds = 0;
 
 
 	dev_warn(&dd->pdev->dev, "Taskfile error\n");
 	dev_warn(&dd->pdev->dev, "Taskfile error\n");
 
 
@@ -722,8 +783,11 @@ static void mtip_handle_tfe(struct driver_data *dd)
 	/* Stop the timer to prevent command timeouts. */
 	/* Stop the timer to prevent command timeouts. */
 	del_timer(&port->cmd_timer);
 	del_timer(&port->cmd_timer);
 
 
+	/* clear the tag accumulator */
+	memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
+
 	/* Set eh_active */
 	/* Set eh_active */
-	set_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags);
+	set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
 
 
 	/* Loop through all the groups */
 	/* Loop through all the groups */
 	for (group = 0; group < dd->slot_groups; group++) {
 	for (group = 0; group < dd->slot_groups; group++) {
@@ -732,9 +796,6 @@ static void mtip_handle_tfe(struct driver_data *dd)
 		/* clear completed status register in the hardware.*/
 		/* clear completed status register in the hardware.*/
 		writel(completed, port->completed[group]);
 		writel(completed, port->completed[group]);
 
 
-		/* clear the tag accumulator */
-		memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
-
 		/* Process successfully completed commands */
 		/* Process successfully completed commands */
 		for (bit = 0; bit < 32 && completed; bit++) {
 		for (bit = 0; bit < 32 && completed; bit++) {
 			if (!(completed & (1<<bit)))
 			if (!(completed & (1<<bit)))
@@ -745,13 +806,14 @@ static void mtip_handle_tfe(struct driver_data *dd)
 			if (tag == MTIP_TAG_INTERNAL)
 			if (tag == MTIP_TAG_INTERNAL)
 				continue;
 				continue;
 
 
-			command = &port->commands[tag];
-			if (likely(command->comp_func)) {
+			cmd = &port->commands[tag];
+			if (likely(cmd->comp_func)) {
 				set_bit(tag, tagaccum);
 				set_bit(tag, tagaccum);
-				atomic_set(&port->commands[tag].active, 0);
-				command->comp_func(port,
+				cmd_cnt++;
+				atomic_set(&cmd->active, 0);
+				cmd->comp_func(port,
 					 tag,
 					 tag,
-					 command->comp_data,
+					 cmd->comp_data,
 					 0);
 					 0);
 			} else {
 			} else {
 				dev_err(&port->dd->pdev->dev,
 				dev_err(&port->dd->pdev->dev,
@@ -765,12 +827,45 @@ static void mtip_handle_tfe(struct driver_data *dd)
 			}
 			}
 		}
 		}
 	}
 	}
-	print_tags(dd, "TFE tags completed:", tagaccum);
+
+	print_tags(dd, "completed (TFE)", tagaccum, cmd_cnt);
 
 
 	/* Restart the port */
 	/* Restart the port */
 	mdelay(20);
 	mdelay(20);
 	mtip_restart_port(port);
 	mtip_restart_port(port);
 
 
+	/* Trying to determine the cause of the error */
+	rv = mtip_read_log_page(dd->port, ATA_LOG_SATA_NCQ,
+				dd->port->log_buf,
+				dd->port->log_buf_dma, 1);
+	if (rv) {
+		dev_warn(&dd->pdev->dev,
+			"Error in READ LOG EXT (10h) command\n");
+		/* non-critical error, don't fail the load */
+	} else {
+		buf = (unsigned char *)dd->port->log_buf;
+		if (buf[259] & 0x1) {
+			dev_info(&dd->pdev->dev,
+				"Write protect bit is set.\n");
+			set_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag);
+			fail_all_ncq_write = 1;
+			fail_reason = "write protect";
+		}
+		if (buf[288] == 0xF7) {
+			dev_info(&dd->pdev->dev,
+				"Exceeded Tmax, drive in thermal shutdown.\n");
+			set_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag);
+			fail_all_ncq_cmds = 1;
+			fail_reason = "thermal shutdown";
+		}
+		if (buf[288] == 0xBF) {
+			dev_info(&dd->pdev->dev,
+				"Drive indicates rebuild has failed.\n");
+			fail_all_ncq_cmds = 1;
+			fail_reason = "rebuild failed";
+		}
+	}
+
 	/* clear the tag accumulator */
 	/* clear the tag accumulator */
 	memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
 	memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
 
 
@@ -779,32 +874,47 @@ static void mtip_handle_tfe(struct driver_data *dd)
 		for (bit = 0; bit < 32; bit++) {
 		for (bit = 0; bit < 32; bit++) {
 			reissue = 1;
 			reissue = 1;
 			tag = (group << 5) + bit;
 			tag = (group << 5) + bit;
+			cmd = &port->commands[tag];
 
 
 			/* If the active bit is set re-issue the command */
 			/* If the active bit is set re-issue the command */
-			if (atomic_read(&port->commands[tag].active) == 0)
+			if (atomic_read(&cmd->active) == 0)
 				continue;
 				continue;
 
 
-			fis = (struct host_to_dev_fis *)
-				port->commands[tag].command;
+			fis = (struct host_to_dev_fis *)cmd->command;
 
 
 			/* Should re-issue? */
 			/* Should re-issue? */
 			if (tag == MTIP_TAG_INTERNAL ||
 			if (tag == MTIP_TAG_INTERNAL ||
 			    fis->command == ATA_CMD_SET_FEATURES)
 			    fis->command == ATA_CMD_SET_FEATURES)
 				reissue = 0;
 				reissue = 0;
+			else {
+				if (fail_all_ncq_cmds ||
+					(fail_all_ncq_write &&
+					fis->command == ATA_CMD_FPDMA_WRITE)) {
+					dev_warn(&dd->pdev->dev,
+					"  Fail: %s w/tag %d [%s].\n",
+					fis->command == ATA_CMD_FPDMA_WRITE ?
+						"write" : "read",
+					tag,
+					fail_reason != NULL ?
+						fail_reason : "unknown");
+					atomic_set(&cmd->active, 0);
+					if (cmd->comp_func) {
+						cmd->comp_func(port, tag,
+							cmd->comp_data,
+							-ENODATA);
+					}
+					continue;
+				}
+			}
 
 
 			/*
 			/*
 			 * First check if this command has
 			 * First check if this command has
 			 *  exceeded its retries.
 			 *  exceeded its retries.
 			 */
 			 */
-			if (reissue &&
-			    (port->commands[tag].retries-- > 0)) {
+			if (reissue && (cmd->retries-- > 0)) {
 
 
 				set_bit(tag, tagaccum);
 				set_bit(tag, tagaccum);
 
 
-				/* Update the timeout value. */
-				port->commands[tag].comp_time =
-					jiffies + msecs_to_jiffies(
-					MTIP_NCQ_COMMAND_TIMEOUT_MS);
 				/* Re-issue the command. */
 				/* Re-issue the command. */
 				mtip_issue_ncq_command(port, tag);
 				mtip_issue_ncq_command(port, tag);
 
 
@@ -814,13 +924,13 @@ static void mtip_handle_tfe(struct driver_data *dd)
 			/* Retire a command that will not be reissued */
 			/* Retire a command that will not be reissued */
 			dev_warn(&port->dd->pdev->dev,
 			dev_warn(&port->dd->pdev->dev,
 				"retiring tag %d\n", tag);
 				"retiring tag %d\n", tag);
-			atomic_set(&port->commands[tag].active, 0);
+			atomic_set(&cmd->active, 0);
 
 
-			if (port->commands[tag].comp_func)
-				port->commands[tag].comp_func(
+			if (cmd->comp_func)
+				cmd->comp_func(
 					port,
 					port,
 					tag,
 					tag,
-					port->commands[tag].comp_data,
+					cmd->comp_data,
 					PORT_IRQ_TF_ERR);
 					PORT_IRQ_TF_ERR);
 			else
 			else
 				dev_warn(&port->dd->pdev->dev,
 				dev_warn(&port->dd->pdev->dev,
@@ -828,10 +938,10 @@ static void mtip_handle_tfe(struct driver_data *dd)
 					tag);
 					tag);
 		}
 		}
 	}
 	}
-	print_tags(dd, "TFE tags reissued:", tagaccum);
+	print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt);
 
 
 	/* clear eh_active */
 	/* clear eh_active */
-	clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags);
+	clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
 	wake_up_interruptible(&port->svc_wait);
 	wake_up_interruptible(&port->svc_wait);
 
 
 	mod_timer(&port->cmd_timer,
 	mod_timer(&port->cmd_timer,
@@ -899,7 +1009,7 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat)
 	struct mtip_port *port = dd->port;
 	struct mtip_port *port = dd->port;
 	struct mtip_cmd *cmd = &port->commands[MTIP_TAG_INTERNAL];
 	struct mtip_cmd *cmd = &port->commands[MTIP_TAG_INTERNAL];
 
 
-	if (test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) &&
+	if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags) &&
 	    (cmd != NULL) && !(readl(port->cmd_issue[MTIP_TAG_INTERNAL])
 	    (cmd != NULL) && !(readl(port->cmd_issue[MTIP_TAG_INTERNAL])
 		& (1 << MTIP_TAG_INTERNAL))) {
 		& (1 << MTIP_TAG_INTERNAL))) {
 		if (cmd->comp_func) {
 		if (cmd->comp_func) {
@@ -911,8 +1021,6 @@ static inline void mtip_process_legacy(struct driver_data *dd, u32 port_stat)
 		}
 		}
 	}
 	}
 
 
-	dev_warn(&dd->pdev->dev, "IRQ status 0x%x ignored.\n", port_stat);
-
 	return;
 	return;
 }
 }
 
 
@@ -968,6 +1076,9 @@ static inline irqreturn_t mtip_handle_irq(struct driver_data *data)
 				/* don't proceed further */
 				/* don't proceed further */
 				return IRQ_HANDLED;
 				return IRQ_HANDLED;
 			}
 			}
+			if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+							&dd->dd_flag))
+				return rv;
 
 
 			mtip_process_errors(dd, port_stat & PORT_IRQ_ERR);
 			mtip_process_errors(dd, port_stat & PORT_IRQ_ERR);
 		}
 		}
@@ -1015,6 +1126,39 @@ static void mtip_issue_non_ncq_command(struct mtip_port *port, int tag)
 		port->cmd_issue[MTIP_TAG_INDEX(tag)]);
 		port->cmd_issue[MTIP_TAG_INDEX(tag)]);
 }
 }
 
 
+static bool mtip_pause_ncq(struct mtip_port *port,
+				struct host_to_dev_fis *fis)
+{
+	struct host_to_dev_fis *reply;
+	unsigned long task_file_data;
+
+	reply = port->rxfis + RX_FIS_D2H_REG;
+	task_file_data = readl(port->mmio+PORT_TFDATA);
+
+	if ((task_file_data & 1) || (fis->command == ATA_CMD_SEC_ERASE_UNIT))
+		return false;
+
+	if (fis->command == ATA_CMD_SEC_ERASE_PREP) {
+		set_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
+		port->ic_pause_timer = jiffies;
+		return true;
+	} else if ((fis->command == ATA_CMD_DOWNLOAD_MICRO) &&
+					(fis->features == 0x03)) {
+		set_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags);
+		port->ic_pause_timer = jiffies;
+		return true;
+	} else if ((fis->command == ATA_CMD_SEC_ERASE_UNIT) ||
+		((fis->command == 0xFC) &&
+			(fis->features == 0x27 || fis->features == 0x72 ||
+			 fis->features == 0x62 || fis->features == 0x26))) {
+		/* Com reset after secure erase or lowlevel format */
+		mtip_restart_port(port);
+		return false;
+	}
+
+	return false;
+}
+
 /*
 /*
  * Wait for port to quiesce
  * Wait for port to quiesce
  *
  *
@@ -1033,11 +1177,13 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout)
 
 
 	to = jiffies + msecs_to_jiffies(timeout);
 	to = jiffies + msecs_to_jiffies(timeout);
 	do {
 	do {
-		if (test_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags) &&
-			test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) {
+		if (test_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags) &&
+			test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) {
 			msleep(20);
 			msleep(20);
 			continue; /* svc thd is actively issuing commands */
 			continue; /* svc thd is actively issuing commands */
 		}
 		}
+		if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+			return -EFAULT;
 		/*
 		/*
 		 * Ignore s_active bit 0 of array element 0.
 		 * Ignore s_active bit 0 of array element 0.
 		 * This bit will always be set
 		 * This bit will always be set
@@ -1074,7 +1220,7 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout)
  *	-EAGAIN  Time out waiting for command to complete.
  *	-EAGAIN  Time out waiting for command to complete.
  */
  */
 static int mtip_exec_internal_command(struct mtip_port *port,
 static int mtip_exec_internal_command(struct mtip_port *port,
-					void *fis,
+					struct host_to_dev_fis *fis,
 					int fis_len,
 					int fis_len,
 					dma_addr_t buffer,
 					dma_addr_t buffer,
 					int buf_len,
 					int buf_len,
@@ -1084,8 +1230,9 @@ static int mtip_exec_internal_command(struct mtip_port *port,
 {
 {
 	struct mtip_cmd_sg *command_sg;
 	struct mtip_cmd_sg *command_sg;
 	DECLARE_COMPLETION_ONSTACK(wait);
 	DECLARE_COMPLETION_ONSTACK(wait);
-	int rv = 0;
+	int rv = 0, ready2go = 1;
 	struct mtip_cmd *int_cmd = &port->commands[MTIP_TAG_INTERNAL];
 	struct mtip_cmd *int_cmd = &port->commands[MTIP_TAG_INTERNAL];
+	unsigned long to;
 
 
 	/* Make sure the buffer is 8 byte aligned. This is asic specific. */
 	/* Make sure the buffer is 8 byte aligned. This is asic specific. */
 	if (buffer & 0x00000007) {
 	if (buffer & 0x00000007) {
@@ -1094,23 +1241,38 @@ static int mtip_exec_internal_command(struct mtip_port *port,
 		return -EFAULT;
 		return -EFAULT;
 	}
 	}
 
 
-	/* Only one internal command should be running at a time */
-	if (test_and_set_bit(MTIP_TAG_INTERNAL, port->allocated)) {
+	to = jiffies + msecs_to_jiffies(timeout);
+	do {
+		ready2go = !test_and_set_bit(MTIP_TAG_INTERNAL,
+						port->allocated);
+		if (ready2go)
+			break;
+		mdelay(100);
+	} while (time_before(jiffies, to));
+	if (!ready2go) {
 		dev_warn(&port->dd->pdev->dev,
 		dev_warn(&port->dd->pdev->dev,
-			"Internal command already active\n");
+			"Internal cmd active. new cmd [%02X]\n", fis->command);
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
-	set_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags);
+	set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
+	port->ic_pause_timer = 0;
+
+	if (fis->command == ATA_CMD_SEC_ERASE_UNIT)
+		clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
+	else if (fis->command == ATA_CMD_DOWNLOAD_MICRO)
+		clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags);
 
 
 	if (atomic == GFP_KERNEL) {
 	if (atomic == GFP_KERNEL) {
-		/* wait for io to complete if non atomic */
-		if (mtip_quiesce_io(port, 5000) < 0) {
-			dev_warn(&port->dd->pdev->dev,
-				"Failed to quiesce IO\n");
-			release_slot(port, MTIP_TAG_INTERNAL);
-			clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags);
-			wake_up_interruptible(&port->svc_wait);
-			return -EBUSY;
+		if (fis->command != ATA_CMD_STANDBYNOW1) {
+			/* wait for io to complete if non atomic */
+			if (mtip_quiesce_io(port, 5000) < 0) {
+				dev_warn(&port->dd->pdev->dev,
+					"Failed to quiesce IO\n");
+				release_slot(port, MTIP_TAG_INTERNAL);
+				clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
+				wake_up_interruptible(&port->svc_wait);
+				return -EBUSY;
+			}
 		}
 		}
 
 
 		/* Set the completion function and data for the command. */
 		/* Set the completion function and data for the command. */
@@ -1120,7 +1282,7 @@ static int mtip_exec_internal_command(struct mtip_port *port,
 	} else {
 	} else {
 		/* Clear completion - we're going to poll */
 		/* Clear completion - we're going to poll */
 		int_cmd->comp_data = NULL;
 		int_cmd->comp_data = NULL;
-		int_cmd->comp_func = NULL;
+		int_cmd->comp_func = mtip_null_completion;
 	}
 	}
 
 
 	/* Copy the command to the command table */
 	/* Copy the command to the command table */
@@ -1159,6 +1321,12 @@ static int mtip_exec_internal_command(struct mtip_port *port,
 				"Internal command did not complete [%d] "
 				"Internal command did not complete [%d] "
 				"within timeout of  %lu ms\n",
 				"within timeout of  %lu ms\n",
 				atomic, timeout);
 				atomic, timeout);
+			if (mtip_check_surprise_removal(port->dd->pdev) ||
+				test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+						&port->dd->dd_flag)) {
+				rv = -ENXIO;
+				goto exec_ic_exit;
+			}
 			rv = -EAGAIN;
 			rv = -EAGAIN;
 		}
 		}
 
 
@@ -1166,31 +1334,59 @@ static int mtip_exec_internal_command(struct mtip_port *port,
 			& (1 << MTIP_TAG_INTERNAL)) {
 			& (1 << MTIP_TAG_INTERNAL)) {
 			dev_warn(&port->dd->pdev->dev,
 			dev_warn(&port->dd->pdev->dev,
 				"Retiring internal command but CI is 1.\n");
 				"Retiring internal command but CI is 1.\n");
+			if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+						&port->dd->dd_flag)) {
+				hba_reset_nosleep(port->dd);
+				rv = -ENXIO;
+			} else {
+				mtip_restart_port(port);
+				rv = -EAGAIN;
+			}
+			goto exec_ic_exit;
 		}
 		}
 
 
 	} else {
 	} else {
 		/* Spin for <timeout> checking if command still outstanding */
 		/* Spin for <timeout> checking if command still outstanding */
 		timeout = jiffies + msecs_to_jiffies(timeout);
 		timeout = jiffies + msecs_to_jiffies(timeout);
-
-		while ((readl(
-			port->cmd_issue[MTIP_TAG_INTERNAL])
-			& (1 << MTIP_TAG_INTERNAL))
-			&& time_before(jiffies, timeout))
-			;
+		while ((readl(port->cmd_issue[MTIP_TAG_INTERNAL])
+				& (1 << MTIP_TAG_INTERNAL))
+				&& time_before(jiffies, timeout)) {
+			if (mtip_check_surprise_removal(port->dd->pdev)) {
+				rv = -ENXIO;
+				goto exec_ic_exit;
+			}
+			if ((fis->command != ATA_CMD_STANDBYNOW1) &&
+				test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+						&port->dd->dd_flag)) {
+				rv = -ENXIO;
+				goto exec_ic_exit;
+			}
+		}
 
 
 		if (readl(port->cmd_issue[MTIP_TAG_INTERNAL])
 		if (readl(port->cmd_issue[MTIP_TAG_INTERNAL])
 			& (1 << MTIP_TAG_INTERNAL)) {
 			& (1 << MTIP_TAG_INTERNAL)) {
 			dev_err(&port->dd->pdev->dev,
 			dev_err(&port->dd->pdev->dev,
-				"Internal command did not complete [%d]\n",
-				atomic);
+				"Internal command did not complete [atomic]\n");
 			rv = -EAGAIN;
 			rv = -EAGAIN;
+			if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+						&port->dd->dd_flag)) {
+				hba_reset_nosleep(port->dd);
+				rv = -ENXIO;
+			} else {
+				mtip_restart_port(port);
+				rv = -EAGAIN;
+			}
 		}
 		}
 	}
 	}
-
+exec_ic_exit:
 	/* Clear the allocated and active bits for the internal command. */
 	/* Clear the allocated and active bits for the internal command. */
 	atomic_set(&int_cmd->active, 0);
 	atomic_set(&int_cmd->active, 0);
 	release_slot(port, MTIP_TAG_INTERNAL);
 	release_slot(port, MTIP_TAG_INTERNAL);
-	clear_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags);
+	if (rv >= 0 && mtip_pause_ncq(port, fis)) {
+		/* NCQ paused */
+		return rv;
+	}
+	clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
 	wake_up_interruptible(&port->svc_wait);
 	wake_up_interruptible(&port->svc_wait);
 
 
 	return rv;
 	return rv;
@@ -1240,6 +1436,9 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer)
 	int rv = 0;
 	int rv = 0;
 	struct host_to_dev_fis fis;
 	struct host_to_dev_fis fis;
 
 
+	if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+		return -EFAULT;
+
 	/* Build the FIS. */
 	/* Build the FIS. */
 	memset(&fis, 0, sizeof(struct host_to_dev_fis));
 	memset(&fis, 0, sizeof(struct host_to_dev_fis));
 	fis.type	= 0x27;
 	fis.type	= 0x27;
@@ -1313,6 +1512,7 @@ static int mtip_standby_immediate(struct mtip_port *port)
 {
 {
 	int rv;
 	int rv;
 	struct host_to_dev_fis	fis;
 	struct host_to_dev_fis	fis;
+	unsigned long start;
 
 
 	/* Build the FIS. */
 	/* Build the FIS. */
 	memset(&fis, 0, sizeof(struct host_to_dev_fis));
 	memset(&fis, 0, sizeof(struct host_to_dev_fis));
@@ -1320,15 +1520,150 @@ static int mtip_standby_immediate(struct mtip_port *port)
 	fis.opts	= 1 << 7;
 	fis.opts	= 1 << 7;
 	fis.command	= ATA_CMD_STANDBYNOW1;
 	fis.command	= ATA_CMD_STANDBYNOW1;
 
 
-	/* Execute the command.  Use a 15-second timeout for large drives. */
+	start = jiffies;
 	rv = mtip_exec_internal_command(port,
 	rv = mtip_exec_internal_command(port,
 					&fis,
 					&fis,
 					5,
 					5,
 					0,
 					0,
 					0,
 					0,
 					0,
 					0,
-					GFP_KERNEL,
+					GFP_ATOMIC,
 					15000);
 					15000);
+	dbg_printk(MTIP_DRV_NAME "Time taken to complete standby cmd: %d ms\n",
+			jiffies_to_msecs(jiffies - start));
+	if (rv)
+		dev_warn(&port->dd->pdev->dev,
+			"STANDBY IMMEDIATE command failed.\n");
+
+	return rv;
+}
+
+/*
+ * Issue a READ LOG EXT command to the device.
+ *
+ * @port	pointer to the port structure.
+ * @page	page number to fetch
+ * @buffer	pointer to buffer
+ * @buffer_dma	dma address corresponding to @buffer
+ * @sectors	page length to fetch, in sectors
+ *
+ * return value
+ *	@rv	return value from mtip_exec_internal_command()
+ */
+static int mtip_read_log_page(struct mtip_port *port, u8 page, u16 *buffer,
+				dma_addr_t buffer_dma, unsigned int sectors)
+{
+	struct host_to_dev_fis fis;
+
+	memset(&fis, 0, sizeof(struct host_to_dev_fis));
+	fis.type	= 0x27;
+	fis.opts	= 1 << 7;
+	fis.command	= ATA_CMD_READ_LOG_EXT;
+	fis.sect_count	= sectors & 0xFF;
+	fis.sect_cnt_ex	= (sectors >> 8) & 0xFF;
+	fis.lba_low	= page;
+	fis.lba_mid	= 0;
+	fis.device	= ATA_DEVICE_OBS;
+
+	memset(buffer, 0, sectors * ATA_SECT_SIZE);
+
+	return mtip_exec_internal_command(port,
+					&fis,
+					5,
+					buffer_dma,
+					sectors * ATA_SECT_SIZE,
+					0,
+					GFP_ATOMIC,
+					MTIP_INTERNAL_COMMAND_TIMEOUT_MS);
+}
+
+/*
+ * Issue a SMART READ DATA command to the device.
+ *
+ * @port	pointer to the port structure.
+ * @buffer	pointer to buffer
+ * @buffer_dma	dma address corresponding to @buffer
+ *
+ * return value
+ *	@rv	return value from mtip_exec_internal_command()
+ */
+static int mtip_get_smart_data(struct mtip_port *port, u8 *buffer,
+					dma_addr_t buffer_dma)
+{
+	struct host_to_dev_fis fis;
+
+	memset(&fis, 0, sizeof(struct host_to_dev_fis));
+	fis.type	= 0x27;
+	fis.opts	= 1 << 7;
+	fis.command	= ATA_CMD_SMART;
+	fis.features	= 0xD0;
+	fis.sect_count	= 1;
+	fis.lba_mid	= 0x4F;
+	fis.lba_hi	= 0xC2;
+	fis.device	= ATA_DEVICE_OBS;
+
+	return mtip_exec_internal_command(port,
+					&fis,
+					5,
+					buffer_dma,
+					ATA_SECT_SIZE,
+					0,
+					GFP_ATOMIC,
+					15000);
+}
+
+/*
+ * Get the value of a smart attribute
+ *
+ * @port	pointer to the port structure
+ * @id		attribute number
+ * @attrib	pointer to return attrib information corresponding to @id
+ *
+ * return value
+ *	-EINVAL	NULL buffer passed or unsupported attribute @id.
+ *	-EPERM	Identify data not valid, SMART not supported or not enabled
+ */
+static int mtip_get_smart_attr(struct mtip_port *port, unsigned int id,
+						struct smart_attr *attrib)
+{
+	int rv, i;
+	struct smart_attr *pattr;
+
+	if (!attrib)
+		return -EINVAL;
+
+	if (!port->identify_valid) {
+		dev_warn(&port->dd->pdev->dev, "IDENTIFY DATA not valid\n");
+		return -EPERM;
+	}
+	if (!(port->identify[82] & 0x1)) {
+		dev_warn(&port->dd->pdev->dev, "SMART not supported\n");
+		return -EPERM;
+	}
+	if (!(port->identify[85] & 0x1)) {
+		dev_warn(&port->dd->pdev->dev, "SMART not enabled\n");
+		return -EPERM;
+	}
+
+	memset(port->smart_buf, 0, ATA_SECT_SIZE);
+	rv = mtip_get_smart_data(port, port->smart_buf, port->smart_buf_dma);
+	if (rv) {
+		dev_warn(&port->dd->pdev->dev, "Failed to ge SMART data\n");
+		return rv;
+	}
+
+	pattr = (struct smart_attr *)(port->smart_buf + 2);
+	for (i = 0; i < 29; i++, pattr++)
+		if (pattr->attr_id == id) {
+			memcpy(attrib, pattr, sizeof(struct smart_attr));
+			break;
+		}
+
+	if (i == 29) {
+		dev_warn(&port->dd->pdev->dev,
+			"Query for invalid SMART attribute ID\n");
+		rv = -EINVAL;
+	}
 
 
 	return rv;
 	return rv;
 }
 }
@@ -1504,10 +1839,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command)
 	fis.cyl_hi	= command[5];
 	fis.cyl_hi	= command[5];
 	fis.device	= command[6] & ~0x10; /* Clear the dev bit*/
 	fis.device	= command[6] & ~0x10; /* Clear the dev bit*/
 
 
-
-	dbg_printk(MTIP_DRV_NAME "%s: User Command: cmd %x, feat %x, "
-		"nsect %x, sect %x, lcyl %x, "
-		"hcyl %x, sel %x\n",
+	dbg_printk(MTIP_DRV_NAME " %s: User Command: cmd %x, feat %x, nsect %x, sect %x, lcyl %x, hcyl %x, sel %x\n",
 		__func__,
 		__func__,
 		command[0],
 		command[0],
 		command[1],
 		command[1],
@@ -1534,8 +1866,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command)
 	command[4] = reply->cyl_low;
 	command[4] = reply->cyl_low;
 	command[5] = reply->cyl_hi;
 	command[5] = reply->cyl_hi;
 
 
-	dbg_printk(MTIP_DRV_NAME "%s: Completion Status: stat %x, "
-		"err %x , cyl_lo %x cyl_hi %x\n",
+	dbg_printk(MTIP_DRV_NAME " %s: Completion Status: stat %x, err %x , cyl_lo %x cyl_hi %x\n",
 		__func__,
 		__func__,
 		command[0],
 		command[0],
 		command[1],
 		command[1],
@@ -1578,7 +1909,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command,
 	}
 	}
 
 
 	dbg_printk(MTIP_DRV_NAME
 	dbg_printk(MTIP_DRV_NAME
-		"%s: User Command: cmd %x, sect %x, "
+		" %s: User Command: cmd %x, sect %x, "
 		"feat %x, sectcnt %x\n",
 		"feat %x, sectcnt %x\n",
 		__func__,
 		__func__,
 		command[0],
 		command[0],
@@ -1607,7 +1938,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command,
 	command[2] = command[3];
 	command[2] = command[3];
 
 
 	dbg_printk(MTIP_DRV_NAME
 	dbg_printk(MTIP_DRV_NAME
-		"%s: Completion Status: stat %x, "
+		" %s: Completion Status: stat %x, "
 		"err %x, cmd %x\n",
 		"err %x, cmd %x\n",
 		__func__,
 		__func__,
 		command[0],
 		command[0],
@@ -1810,9 +2141,10 @@ static int exec_drive_taskfile(struct driver_data *dd,
 	}
 	}
 
 
 	dbg_printk(MTIP_DRV_NAME
 	dbg_printk(MTIP_DRV_NAME
-		"taskfile: cmd %x, feat %x, nsect %x,"
+		" %s: cmd %x, feat %x, nsect %x,"
 		" sect/lbal %x, lcyl/lbam %x, hcyl/lbah %x,"
 		" sect/lbal %x, lcyl/lbam %x, hcyl/lbah %x,"
 		" head/dev %x\n",
 		" head/dev %x\n",
+		__func__,
 		fis.command,
 		fis.command,
 		fis.features,
 		fis.features,
 		fis.sect_count,
 		fis.sect_count,
@@ -1823,8 +2155,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
 
 
 	switch (fis.command) {
 	switch (fis.command) {
 	case ATA_CMD_DOWNLOAD_MICRO:
 	case ATA_CMD_DOWNLOAD_MICRO:
-		/* Change timeout for Download Microcode to 60 seconds.*/
-		timeout = 60000;
+		/* Change timeout for Download Microcode to 2 minutes */
+		timeout = 120000;
 		break;
 		break;
 	case ATA_CMD_SEC_ERASE_UNIT:
 	case ATA_CMD_SEC_ERASE_UNIT:
 		/* Change timeout for Security Erase Unit to 4 minutes.*/
 		/* Change timeout for Security Erase Unit to 4 minutes.*/
@@ -1840,8 +2172,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
 		timeout = 10000;
 		timeout = 10000;
 		break;
 		break;
 	case ATA_CMD_SMART:
 	case ATA_CMD_SMART:
-		/* Change timeout for vendor unique command to 10 secs */
-		timeout = 10000;
+		/* Change timeout for vendor unique command to 15 secs */
+		timeout = 15000;
 		break;
 		break;
 	default:
 	default:
 		timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS;
 		timeout = MTIP_IOCTL_COMMAND_TIMEOUT_MS;
@@ -1903,18 +2235,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
 		req_task->hob_ports[1] = reply->features_ex;
 		req_task->hob_ports[1] = reply->features_ex;
 		req_task->hob_ports[2] = reply->sect_cnt_ex;
 		req_task->hob_ports[2] = reply->sect_cnt_ex;
 	}
 	}
-
-	/* Com rest after secure erase or lowlevel format */
-	if (((fis.command == ATA_CMD_SEC_ERASE_UNIT) ||
-		((fis.command == 0xFC) &&
-			(fis.features == 0x27 || fis.features == 0x72 ||
-			 fis.features == 0x62 || fis.features == 0x26))) &&
-			 !(reply->command & 1)) {
-		mtip_restart_port(dd->port);
-	}
-
 	dbg_printk(MTIP_DRV_NAME
 	dbg_printk(MTIP_DRV_NAME
-		"%s: Completion: stat %x,"
+		" %s: Completion: stat %x,"
 		"err %x, sect_cnt %x, lbalo %x,"
 		"err %x, sect_cnt %x, lbalo %x,"
 		"lbamid %x, lbahi %x, dev %x\n",
 		"lbamid %x, lbahi %x, dev %x\n",
 		__func__,
 		__func__,
@@ -2080,14 +2402,10 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
 	struct host_to_dev_fis	*fis;
 	struct host_to_dev_fis	*fis;
 	struct mtip_port *port = dd->port;
 	struct mtip_port *port = dd->port;
 	struct mtip_cmd *command = &port->commands[tag];
 	struct mtip_cmd *command = &port->commands[tag];
+	int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
 
 
 	/* Map the scatter list for DMA access */
 	/* Map the scatter list for DMA access */
-	if (dir == READ)
-		nents = dma_map_sg(&dd->pdev->dev, command->sg,
-					nents, DMA_FROM_DEVICE);
-	else
-		nents = dma_map_sg(&dd->pdev->dev, command->sg,
-					nents, DMA_TO_DEVICE);
+	nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir);
 
 
 	command->scatter_ents = nents;
 	command->scatter_ents = nents;
 
 
@@ -2127,7 +2445,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
 	 */
 	 */
 	command->comp_data = dd;
 	command->comp_data = dd;
 	command->comp_func = mtip_async_complete;
 	command->comp_func = mtip_async_complete;
-	command->direction = (dir == READ ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+	command->direction = dma_dir;
 
 
 	/*
 	/*
 	 * Set the completion function and data for the command passed
 	 * Set the completion function and data for the command passed
@@ -2140,19 +2458,16 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
 	 * To prevent this command from being issued
 	 * To prevent this command from being issued
 	 * if an internal command is in progress or error handling is active.
 	 * if an internal command is in progress or error handling is active.
 	 */
 	 */
-	if (unlikely(test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) ||
-			test_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags))) {
+	if (port->flags & MTIP_PF_PAUSE_IO) {
 		set_bit(tag, port->cmds_to_issue);
 		set_bit(tag, port->cmds_to_issue);
-		set_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags);
+		set_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags);
 		return;
 		return;
 	}
 	}
 
 
 	/* Issue the command to the hardware */
 	/* Issue the command to the hardware */
 	mtip_issue_ncq_command(port, tag);
 	mtip_issue_ncq_command(port, tag);
 
 
-	/* Set the command's timeout value.*/
-	port->commands[tag].comp_time = jiffies + msecs_to_jiffies(
-					MTIP_NCQ_COMMAND_TIMEOUT_MS);
+	return;
 }
 }
 
 
 /*
 /*
@@ -2191,6 +2506,10 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd,
 	down(&dd->port->cmd_slot);
 	down(&dd->port->cmd_slot);
 	*tag = get_slot(dd->port);
 	*tag = get_slot(dd->port);
 
 
+	if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) {
+		up(&dd->port->cmd_slot);
+		return NULL;
+	}
 	if (unlikely(*tag < 0))
 	if (unlikely(*tag < 0))
 		return NULL;
 		return NULL;
 
 
@@ -2207,7 +2526,7 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd,
  * return value
  * return value
  *	The size, in bytes, of the data copied into buf.
  *	The size, in bytes, of the data copied into buf.
  */
  */
-static ssize_t hw_show_registers(struct device *dev,
+static ssize_t mtip_hw_show_registers(struct device *dev,
 				struct device_attribute *attr,
 				struct device_attribute *attr,
 				char *buf)
 				char *buf)
 {
 {
@@ -2216,7 +2535,7 @@ static ssize_t hw_show_registers(struct device *dev,
 	int size = 0;
 	int size = 0;
 	int n;
 	int n;
 
 
-	size += sprintf(&buf[size], "%s:\ns_active:\n", __func__);
+	size += sprintf(&buf[size], "S ACTive:\n");
 
 
 	for (n = 0; n < dd->slot_groups; n++)
 	for (n = 0; n < dd->slot_groups; n++)
 		size += sprintf(&buf[size], "0x%08x\n",
 		size += sprintf(&buf[size], "0x%08x\n",
@@ -2240,20 +2559,39 @@ static ssize_t hw_show_registers(struct device *dev,
 				 group_allocated);
 				 group_allocated);
 	}
 	}
 
 
-	size += sprintf(&buf[size], "completed:\n");
+	size += sprintf(&buf[size], "Completed:\n");
 
 
 	for (n = 0; n < dd->slot_groups; n++)
 	for (n = 0; n < dd->slot_groups; n++)
 		size += sprintf(&buf[size], "0x%08x\n",
 		size += sprintf(&buf[size], "0x%08x\n",
 				readl(dd->port->completed[n]));
 				readl(dd->port->completed[n]));
 
 
-	size += sprintf(&buf[size], "PORT_IRQ_STAT 0x%08x\n",
+	size += sprintf(&buf[size], "PORT IRQ STAT : 0x%08x\n",
 				readl(dd->port->mmio + PORT_IRQ_STAT));
 				readl(dd->port->mmio + PORT_IRQ_STAT));
-	size += sprintf(&buf[size], "HOST_IRQ_STAT 0x%08x\n",
+	size += sprintf(&buf[size], "HOST IRQ STAT : 0x%08x\n",
 				readl(dd->mmio + HOST_IRQ_STAT));
 				readl(dd->mmio + HOST_IRQ_STAT));
 
 
 	return size;
 	return size;
 }
 }
-static DEVICE_ATTR(registers, S_IRUGO, hw_show_registers, NULL);
+
+static ssize_t mtip_hw_show_status(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct driver_data *dd = dev_to_disk(dev)->private_data;
+	int size = 0;
+
+	if (test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag))
+		size += sprintf(buf, "%s", "thermal_shutdown\n");
+	else if (test_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag))
+		size += sprintf(buf, "%s", "write_protect\n");
+	else
+		size += sprintf(buf, "%s", "online\n");
+
+	return size;
+}
+
+static DEVICE_ATTR(registers, S_IRUGO, mtip_hw_show_registers, NULL);
+static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL);
 
 
 /*
 /*
  * Create the sysfs related attributes.
  * Create the sysfs related attributes.
@@ -2272,7 +2610,10 @@ static int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj)
 
 
 	if (sysfs_create_file(kobj, &dev_attr_registers.attr))
 	if (sysfs_create_file(kobj, &dev_attr_registers.attr))
 		dev_warn(&dd->pdev->dev,
 		dev_warn(&dd->pdev->dev,
-			"Error creating registers sysfs entry\n");
+			"Error creating 'registers' sysfs entry\n");
+	if (sysfs_create_file(kobj, &dev_attr_status.attr))
+		dev_warn(&dd->pdev->dev,
+			"Error creating 'status' sysfs entry\n");
 	return 0;
 	return 0;
 }
 }
 
 
@@ -2292,6 +2633,7 @@ static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	sysfs_remove_file(kobj, &dev_attr_registers.attr);
 	sysfs_remove_file(kobj, &dev_attr_registers.attr);
+	sysfs_remove_file(kobj, &dev_attr_status.attr);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -2384,10 +2726,12 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd)
 		"FTL rebuild in progress. Polling for completion.\n");
 		"FTL rebuild in progress. Polling for completion.\n");
 
 
 	start = jiffies;
 	start = jiffies;
-	dd->ftlrebuildflag = 1;
 	timeout = jiffies + msecs_to_jiffies(MTIP_FTL_REBUILD_TIMEOUT_MS);
 	timeout = jiffies + msecs_to_jiffies(MTIP_FTL_REBUILD_TIMEOUT_MS);
 
 
 	do {
 	do {
+		if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+				&dd->dd_flag)))
+			return -EFAULT;
 		if (mtip_check_surprise_removal(dd->pdev))
 		if (mtip_check_surprise_removal(dd->pdev))
 			return -EFAULT;
 			return -EFAULT;
 
 
@@ -2408,22 +2752,17 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd)
 			dev_warn(&dd->pdev->dev,
 			dev_warn(&dd->pdev->dev,
 				"FTL rebuild complete (%d secs).\n",
 				"FTL rebuild complete (%d secs).\n",
 			jiffies_to_msecs(jiffies - start) / 1000);
 			jiffies_to_msecs(jiffies - start) / 1000);
-			dd->ftlrebuildflag = 0;
 			mtip_block_initialize(dd);
 			mtip_block_initialize(dd);
-			break;
+			return 0;
 		}
 		}
 		ssleep(10);
 		ssleep(10);
 	} while (time_before(jiffies, timeout));
 	} while (time_before(jiffies, timeout));
 
 
 	/* Check for timeout */
 	/* Check for timeout */
-	if (dd->ftlrebuildflag) {
-		dev_err(&dd->pdev->dev,
+	dev_err(&dd->pdev->dev,
 		"Timed out waiting for FTL rebuild to complete (%d secs).\n",
 		"Timed out waiting for FTL rebuild to complete (%d secs).\n",
 		jiffies_to_msecs(jiffies - start) / 1000);
 		jiffies_to_msecs(jiffies - start) / 1000);
-		return -EFAULT;
-	}
-
-	return 0;
+	return -EFAULT;
 }
 }
 
 
 /*
 /*
@@ -2448,14 +2787,17 @@ static int mtip_service_thread(void *data)
 		 * is in progress nor error handling is active
 		 * is in progress nor error handling is active
 		 */
 		 */
 		wait_event_interruptible(port->svc_wait, (port->flags) &&
 		wait_event_interruptible(port->svc_wait, (port->flags) &&
-			!test_bit(MTIP_FLAG_IC_ACTIVE_BIT, &port->flags) &&
-			!test_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags));
+			!(port->flags & MTIP_PF_PAUSE_IO));
 
 
 		if (kthread_should_stop())
 		if (kthread_should_stop())
 			break;
 			break;
 
 
-		set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags);
-		if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) {
+		if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+				&dd->dd_flag)))
+			break;
+
+		set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags);
+		if (test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) {
 			slot = 1;
 			slot = 1;
 			/* used to restrict the loop to one iteration */
 			/* used to restrict the loop to one iteration */
 			slot_start = num_cmd_slots;
 			slot_start = num_cmd_slots;
@@ -2480,21 +2822,19 @@ static int mtip_service_thread(void *data)
 				/* Issue the command to the hardware */
 				/* Issue the command to the hardware */
 				mtip_issue_ncq_command(port, slot);
 				mtip_issue_ncq_command(port, slot);
 
 
-				/* Set the command's timeout value.*/
-				port->commands[slot].comp_time = jiffies +
-				msecs_to_jiffies(MTIP_NCQ_COMMAND_TIMEOUT_MS);
-
 				clear_bit(slot, port->cmds_to_issue);
 				clear_bit(slot, port->cmds_to_issue);
 			}
 			}
 
 
-			clear_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags);
-		} else if (test_bit(MTIP_FLAG_REBUILD_BIT, &port->flags)) {
-			mtip_ftl_rebuild_poll(dd);
-			clear_bit(MTIP_FLAG_REBUILD_BIT, &port->flags);
+			clear_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags);
+		} else if (test_bit(MTIP_PF_REBUILD_BIT, &port->flags)) {
+			if (!mtip_ftl_rebuild_poll(dd))
+				set_bit(MTIP_DDF_REBUILD_FAILED_BIT,
+							&dd->dd_flag);
+			clear_bit(MTIP_PF_REBUILD_BIT, &port->flags);
 		}
 		}
-		clear_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags);
+		clear_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags);
 
 
-		if (test_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &port->flags))
+		if (test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags))
 			break;
 			break;
 	}
 	}
 	return 0;
 	return 0;
@@ -2513,6 +2853,9 @@ static int mtip_hw_init(struct driver_data *dd)
 	int i;
 	int i;
 	int rv;
 	int rv;
 	unsigned int num_command_slots;
 	unsigned int num_command_slots;
+	unsigned long timeout, timetaken;
+	unsigned char *buf;
+	struct smart_attr attr242;
 
 
 	dd->mmio = pcim_iomap_table(dd->pdev)[MTIP_ABAR];
 	dd->mmio = pcim_iomap_table(dd->pdev)[MTIP_ABAR];
 
 
@@ -2547,7 +2890,7 @@ static int mtip_hw_init(struct driver_data *dd)
 	/* Allocate memory for the command list. */
 	/* Allocate memory for the command list. */
 	dd->port->command_list =
 	dd->port->command_list =
 		dmam_alloc_coherent(&dd->pdev->dev,
 		dmam_alloc_coherent(&dd->pdev->dev,
-			HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2),
+			HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4),
 			&dd->port->command_list_dma,
 			&dd->port->command_list_dma,
 			GFP_KERNEL);
 			GFP_KERNEL);
 	if (!dd->port->command_list) {
 	if (!dd->port->command_list) {
@@ -2560,7 +2903,7 @@ static int mtip_hw_init(struct driver_data *dd)
 	/* Clear the memory we have allocated. */
 	/* Clear the memory we have allocated. */
 	memset(dd->port->command_list,
 	memset(dd->port->command_list,
 		0,
 		0,
-		HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2));
+		HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4));
 
 
 	/* Setup the addresse of the RX FIS. */
 	/* Setup the addresse of the RX FIS. */
 	dd->port->rxfis	    = dd->port->command_list + HW_CMD_SLOT_SZ;
 	dd->port->rxfis	    = dd->port->command_list + HW_CMD_SLOT_SZ;
@@ -2576,10 +2919,19 @@ static int mtip_hw_init(struct driver_data *dd)
 	dd->port->identify_dma = dd->port->command_tbl_dma +
 	dd->port->identify_dma = dd->port->command_tbl_dma +
 					HW_CMD_TBL_AR_SZ;
 					HW_CMD_TBL_AR_SZ;
 
 
-	/* Setup the address of the sector buffer. */
+	/* Setup the address of the sector buffer - for some non-ncq cmds */
 	dd->port->sector_buffer	= (void *) dd->port->identify + ATA_SECT_SIZE;
 	dd->port->sector_buffer	= (void *) dd->port->identify + ATA_SECT_SIZE;
 	dd->port->sector_buffer_dma = dd->port->identify_dma + ATA_SECT_SIZE;
 	dd->port->sector_buffer_dma = dd->port->identify_dma + ATA_SECT_SIZE;
 
 
+	/* Setup the address of the log buf - for read log command */
+	dd->port->log_buf = (void *)dd->port->sector_buffer  + ATA_SECT_SIZE;
+	dd->port->log_buf_dma = dd->port->sector_buffer_dma + ATA_SECT_SIZE;
+
+	/* Setup the address of the smart buf - for smart read data command */
+	dd->port->smart_buf = (void *)dd->port->log_buf  + ATA_SECT_SIZE;
+	dd->port->smart_buf_dma = dd->port->log_buf_dma + ATA_SECT_SIZE;
+
+
 	/* Point the command headers at the command tables. */
 	/* Point the command headers at the command tables. */
 	for (i = 0; i < num_command_slots; i++) {
 	for (i = 0; i < num_command_slots; i++) {
 		dd->port->commands[i].command_header =
 		dd->port->commands[i].command_header =
@@ -2623,14 +2975,43 @@ static int mtip_hw_init(struct driver_data *dd)
 			dd->port->mmio + i*0x80 + PORT_SDBV;
 			dd->port->mmio + i*0x80 + PORT_SDBV;
 	}
 	}
 
 
-	/* Reset the HBA. */
-	if (mtip_hba_reset(dd) < 0) {
-		dev_err(&dd->pdev->dev,
-			"Card did not reset within timeout\n");
-		rv = -EIO;
+	timetaken = jiffies;
+	timeout = jiffies + msecs_to_jiffies(30000);
+	while (((readl(dd->port->mmio + PORT_SCR_STAT) & 0x0F) != 0x03) &&
+		 time_before(jiffies, timeout)) {
+		mdelay(100);
+	}
+	if (unlikely(mtip_check_surprise_removal(dd->pdev))) {
+		timetaken = jiffies - timetaken;
+		dev_warn(&dd->pdev->dev,
+			"Surprise removal detected at %u ms\n",
+			jiffies_to_msecs(timetaken));
+		rv = -ENODEV;
+		goto out2 ;
+	}
+	if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) {
+		timetaken = jiffies - timetaken;
+		dev_warn(&dd->pdev->dev,
+			"Removal detected at %u ms\n",
+			jiffies_to_msecs(timetaken));
+		rv = -EFAULT;
 		goto out2;
 		goto out2;
 	}
 	}
 
 
+	/* Conditionally reset the HBA. */
+	if (!(readl(dd->mmio + HOST_CAP) & HOST_CAP_NZDMA)) {
+		if (mtip_hba_reset(dd) < 0) {
+			dev_err(&dd->pdev->dev,
+				"Card did not reset within timeout\n");
+			rv = -EIO;
+			goto out2;
+		}
+	} else {
+		/* Clear any pending interrupts on the HBA */
+		writel(readl(dd->mmio + HOST_IRQ_STAT),
+			dd->mmio + HOST_IRQ_STAT);
+	}
+
 	mtip_init_port(dd->port);
 	mtip_init_port(dd->port);
 	mtip_start_port(dd->port);
 	mtip_start_port(dd->port);
 
 
@@ -2660,6 +3041,12 @@ static int mtip_hw_init(struct driver_data *dd)
 	mod_timer(&dd->port->cmd_timer,
 	mod_timer(&dd->port->cmd_timer,
 		jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD));
 		jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD));
 
 
+
+	if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) {
+		rv = -EFAULT;
+		goto out3;
+	}
+
 	if (mtip_get_identify(dd->port, NULL) < 0) {
 	if (mtip_get_identify(dd->port, NULL) < 0) {
 		rv = -EFAULT;
 		rv = -EFAULT;
 		goto out3;
 		goto out3;
@@ -2667,10 +3054,47 @@ static int mtip_hw_init(struct driver_data *dd)
 
 
 	if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) ==
 	if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) ==
 		MTIP_FTL_REBUILD_MAGIC) {
 		MTIP_FTL_REBUILD_MAGIC) {
-		set_bit(MTIP_FLAG_REBUILD_BIT, &dd->port->flags);
+		set_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags);
 		return MTIP_FTL_REBUILD_MAGIC;
 		return MTIP_FTL_REBUILD_MAGIC;
 	}
 	}
 	mtip_dump_identify(dd->port);
 	mtip_dump_identify(dd->port);
+
+	/* check write protect, over temp and rebuild statuses */
+	rv = mtip_read_log_page(dd->port, ATA_LOG_SATA_NCQ,
+				dd->port->log_buf,
+				dd->port->log_buf_dma, 1);
+	if (rv) {
+		dev_warn(&dd->pdev->dev,
+			"Error in READ LOG EXT (10h) command\n");
+		/* non-critical error, don't fail the load */
+	} else {
+		buf = (unsigned char *)dd->port->log_buf;
+		if (buf[259] & 0x1) {
+			dev_info(&dd->pdev->dev,
+				"Write protect bit is set.\n");
+			set_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag);
+		}
+		if (buf[288] == 0xF7) {
+			dev_info(&dd->pdev->dev,
+				"Exceeded Tmax, drive in thermal shutdown.\n");
+			set_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag);
+		}
+		if (buf[288] == 0xBF) {
+			dev_info(&dd->pdev->dev,
+				"Drive indicates rebuild has failed.\n");
+			/* TODO */
+		}
+	}
+
+	/* get write protect progess */
+	memset(&attr242, 0, sizeof(struct smart_attr));
+	if (mtip_get_smart_attr(dd->port, 242, &attr242))
+		dev_warn(&dd->pdev->dev,
+				"Unable to check write protect progress\n");
+	else
+		dev_info(&dd->pdev->dev,
+				"Write protect progress: %d%% (%d blocks)\n",
+				attr242.cur, attr242.data);
 	return rv;
 	return rv;
 
 
 out3:
 out3:
@@ -2688,7 +3112,7 @@ out2:
 
 
 	/* Free the command/command header memory. */
 	/* Free the command/command header memory. */
 	dmam_free_coherent(&dd->pdev->dev,
 	dmam_free_coherent(&dd->pdev->dev,
-				HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2),
+				HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4),
 				dd->port->command_list,
 				dd->port->command_list,
 				dd->port->command_list_dma);
 				dd->port->command_list_dma);
 out1:
 out1:
@@ -2712,9 +3136,12 @@ static int mtip_hw_exit(struct driver_data *dd)
 	 * Send standby immediate (E0h) to the drive so that it
 	 * Send standby immediate (E0h) to the drive so that it
 	 * saves its state.
 	 * saves its state.
 	 */
 	 */
-	if (atomic_read(&dd->drv_cleanup_done) != true) {
+	if (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) {
 
 
-		mtip_standby_immediate(dd->port);
+		if (!test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags))
+			if (mtip_standby_immediate(dd->port))
+				dev_warn(&dd->pdev->dev,
+					"STANDBY IMMEDIATE failed\n");
 
 
 		/* de-initialize the port. */
 		/* de-initialize the port. */
 		mtip_deinit_port(dd->port);
 		mtip_deinit_port(dd->port);
@@ -2734,7 +3161,7 @@ static int mtip_hw_exit(struct driver_data *dd)
 
 
 	/* Free the command/command header memory. */
 	/* Free the command/command header memory. */
 	dmam_free_coherent(&dd->pdev->dev,
 	dmam_free_coherent(&dd->pdev->dev,
-			HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 2),
+			HW_PORT_PRIV_DMA_SZ + (ATA_SECT_SIZE * 4),
 			dd->port->command_list,
 			dd->port->command_list,
 			dd->port->command_list_dma);
 			dd->port->command_list_dma);
 	/* Free the memory allocated for the for structure. */
 	/* Free the memory allocated for the for structure. */
@@ -2892,6 +3319,9 @@ static int mtip_block_ioctl(struct block_device *dev,
 	if (!dd)
 	if (!dd)
 		return -ENOTTY;
 		return -ENOTTY;
 
 
+	if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)))
+		return -ENOTTY;
+
 	switch (cmd) {
 	switch (cmd) {
 	case BLKFLSBUF:
 	case BLKFLSBUF:
 		return -ENOTTY;
 		return -ENOTTY;
@@ -2927,6 +3357,9 @@ static int mtip_block_compat_ioctl(struct block_device *dev,
 	if (!dd)
 	if (!dd)
 		return -ENOTTY;
 		return -ENOTTY;
 
 
+	if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)))
+		return -ENOTTY;
+
 	switch (cmd) {
 	switch (cmd) {
 	case BLKFLSBUF:
 	case BLKFLSBUF:
 		return -ENOTTY;
 		return -ENOTTY;
@@ -3049,6 +3482,24 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
 	int nents = 0;
 	int nents = 0;
 	int tag = 0;
 	int tag = 0;
 
 
+	if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) {
+		if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+							&dd->dd_flag))) {
+			bio_endio(bio, -ENXIO);
+			return;
+		}
+		if (unlikely(test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag))) {
+			bio_endio(bio, -ENODATA);
+			return;
+		}
+		if (unlikely(test_bit(MTIP_DDF_WRITE_PROTECT_BIT,
+							&dd->dd_flag) &&
+				bio_data_dir(bio))) {
+			bio_endio(bio, -ENODATA);
+			return;
+		}
+	}
+
 	if (unlikely(!bio_has_data(bio))) {
 	if (unlikely(!bio_has_data(bio))) {
 		blk_queue_flush(queue, 0);
 		blk_queue_flush(queue, 0);
 		bio_endio(bio, 0);
 		bio_endio(bio, 0);
@@ -3061,7 +3512,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
 
 
 		if (unlikely((bio)->bi_vcnt > MTIP_MAX_SG)) {
 		if (unlikely((bio)->bi_vcnt > MTIP_MAX_SG)) {
 			dev_warn(&dd->pdev->dev,
 			dev_warn(&dd->pdev->dev,
-				"Maximum number of SGL entries exceeded");
+				"Maximum number of SGL entries exceeded\n");
 			bio_io_error(bio);
 			bio_io_error(bio);
 			mtip_hw_release_scatterlist(dd, tag);
 			mtip_hw_release_scatterlist(dd, tag);
 			return;
 			return;
@@ -3210,8 +3661,10 @@ skip_create_disk:
 		kobject_put(kobj);
 		kobject_put(kobj);
 	}
 	}
 
 
-	if (dd->mtip_svc_handler)
+	if (dd->mtip_svc_handler) {
+		set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag);
 		return rv; /* service thread created for handling rebuild */
 		return rv; /* service thread created for handling rebuild */
+	}
 
 
 start_service_thread:
 start_service_thread:
 	sprintf(thd_name, "mtip_svc_thd_%02d", index);
 	sprintf(thd_name, "mtip_svc_thd_%02d", index);
@@ -3220,12 +3673,15 @@ start_service_thread:
 						dd, thd_name);
 						dd, thd_name);
 
 
 	if (IS_ERR(dd->mtip_svc_handler)) {
 	if (IS_ERR(dd->mtip_svc_handler)) {
-		printk(KERN_ERR "mtip32xx: service thread failed to start\n");
+		dev_err(&dd->pdev->dev, "service thread failed to start\n");
 		dd->mtip_svc_handler = NULL;
 		dd->mtip_svc_handler = NULL;
 		rv = -EFAULT;
 		rv = -EFAULT;
 		goto kthread_run_error;
 		goto kthread_run_error;
 	}
 	}
 
 
+	if (wait_for_rebuild == MTIP_FTL_REBUILD_MAGIC)
+		rv = wait_for_rebuild;
+
 	return rv;
 	return rv;
 
 
 kthread_run_error:
 kthread_run_error:
@@ -3266,16 +3722,18 @@ static int mtip_block_remove(struct driver_data *dd)
 	struct kobject *kobj;
 	struct kobject *kobj;
 
 
 	if (dd->mtip_svc_handler) {
 	if (dd->mtip_svc_handler) {
-		set_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &dd->port->flags);
+		set_bit(MTIP_PF_SVC_THD_STOP_BIT, &dd->port->flags);
 		wake_up_interruptible(&dd->port->svc_wait);
 		wake_up_interruptible(&dd->port->svc_wait);
 		kthread_stop(dd->mtip_svc_handler);
 		kthread_stop(dd->mtip_svc_handler);
 	}
 	}
 
 
-	/* Clean up the sysfs attributes managed by the protocol layer. */
-	kobj = kobject_get(&disk_to_dev(dd->disk)->kobj);
-	if (kobj) {
-		mtip_hw_sysfs_exit(dd, kobj);
-		kobject_put(kobj);
+	/* Clean up the sysfs attributes, if created */
+	if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag)) {
+		kobj = kobject_get(&disk_to_dev(dd->disk)->kobj);
+		if (kobj) {
+			mtip_hw_sysfs_exit(dd, kobj);
+			kobject_put(kobj);
+		}
 	}
 	}
 
 
 	/*
 	/*
@@ -3283,6 +3741,11 @@ static int mtip_block_remove(struct driver_data *dd)
 	 * from /dev
 	 * from /dev
 	 */
 	 */
 	del_gendisk(dd->disk);
 	del_gendisk(dd->disk);
+
+	spin_lock(&rssd_index_lock);
+	ida_remove(&rssd_index_ida, dd->index);
+	spin_unlock(&rssd_index_lock);
+
 	blk_cleanup_queue(dd->queue);
 	blk_cleanup_queue(dd->queue);
 	dd->disk  = NULL;
 	dd->disk  = NULL;
 	dd->queue = NULL;
 	dd->queue = NULL;
@@ -3312,6 +3775,11 @@ static int mtip_block_shutdown(struct driver_data *dd)
 
 
 	/* Delete our gendisk structure, and cleanup the blk queue. */
 	/* Delete our gendisk structure, and cleanup the blk queue. */
 	del_gendisk(dd->disk);
 	del_gendisk(dd->disk);
+
+	spin_lock(&rssd_index_lock);
+	ida_remove(&rssd_index_ida, dd->index);
+	spin_unlock(&rssd_index_lock);
+
 	blk_cleanup_queue(dd->queue);
 	blk_cleanup_queue(dd->queue);
 	dd->disk  = NULL;
 	dd->disk  = NULL;
 	dd->queue = NULL;
 	dd->queue = NULL;
@@ -3359,11 +3827,6 @@ static int mtip_pci_probe(struct pci_dev *pdev,
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
-	/* Set the atomic variable as 1 in case of SRSI */
-	atomic_set(&dd->drv_cleanup_done, true);
-
-	atomic_set(&dd->resumeflag, false);
-
 	/* Attach the private data to this PCI device.  */
 	/* Attach the private data to this PCI device.  */
 	pci_set_drvdata(pdev, dd);
 	pci_set_drvdata(pdev, dd);
 
 
@@ -3420,7 +3883,8 @@ static int mtip_pci_probe(struct pci_dev *pdev,
 	 * instance number.
 	 * instance number.
 	 */
 	 */
 	instance++;
 	instance++;
-
+	if (rv != MTIP_FTL_REBUILD_MAGIC)
+		set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag);
 	goto done;
 	goto done;
 
 
 block_initialize_err:
 block_initialize_err:
@@ -3434,9 +3898,6 @@ iomap_err:
 	pci_set_drvdata(pdev, NULL);
 	pci_set_drvdata(pdev, NULL);
 	return rv;
 	return rv;
 done:
 done:
-	/* Set the atomic variable as 0 in case of SRSI */
-	atomic_set(&dd->drv_cleanup_done, true);
-
 	return rv;
 	return rv;
 }
 }
 
 
@@ -3452,8 +3913,10 @@ static void mtip_pci_remove(struct pci_dev *pdev)
 	struct driver_data *dd = pci_get_drvdata(pdev);
 	struct driver_data *dd = pci_get_drvdata(pdev);
 	int counter = 0;
 	int counter = 0;
 
 
+	set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag);
+
 	if (mtip_check_surprise_removal(pdev)) {
 	if (mtip_check_surprise_removal(pdev)) {
-		while (atomic_read(&dd->drv_cleanup_done) == false) {
+		while (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) {
 			counter++;
 			counter++;
 			msleep(20);
 			msleep(20);
 			if (counter == 10) {
 			if (counter == 10) {
@@ -3463,8 +3926,6 @@ static void mtip_pci_remove(struct pci_dev *pdev)
 			}
 			}
 		}
 		}
 	}
 	}
-	/* Set the atomic variable as 1 in case of SRSI */
-	atomic_set(&dd->drv_cleanup_done, true);
 
 
 	/* Clean up the block layer. */
 	/* Clean up the block layer. */
 	mtip_block_remove(dd);
 	mtip_block_remove(dd);
@@ -3493,7 +3954,7 @@ static int mtip_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
 		return -EFAULT;
 		return -EFAULT;
 	}
 	}
 
 
-	atomic_set(&dd->resumeflag, true);
+	set_bit(MTIP_DDF_RESUME_BIT, &dd->dd_flag);
 
 
 	/* Disable ports & interrupts then send standby immediate */
 	/* Disable ports & interrupts then send standby immediate */
 	rv = mtip_block_suspend(dd);
 	rv = mtip_block_suspend(dd);
@@ -3559,7 +4020,7 @@ static int mtip_pci_resume(struct pci_dev *pdev)
 		dev_err(&pdev->dev, "Unable to resume\n");
 		dev_err(&pdev->dev, "Unable to resume\n");
 
 
 err:
 err:
-	atomic_set(&dd->resumeflag, false);
+	clear_bit(MTIP_DDF_RESUME_BIT, &dd->dd_flag);
 
 
 	return rv;
 	return rv;
 }
 }
@@ -3608,18 +4069,25 @@ MODULE_DEVICE_TABLE(pci, mtip_pci_tbl);
  */
  */
 static int __init mtip_init(void)
 static int __init mtip_init(void)
 {
 {
+	int error;
+
 	printk(KERN_INFO MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n");
 	printk(KERN_INFO MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n");
 
 
 	/* Allocate a major block device number to use with this driver. */
 	/* Allocate a major block device number to use with this driver. */
-	mtip_major = register_blkdev(0, MTIP_DRV_NAME);
-	if (mtip_major < 0) {
+	error = register_blkdev(0, MTIP_DRV_NAME);
+	if (error <= 0) {
 		printk(KERN_ERR "Unable to register block device (%d)\n",
 		printk(KERN_ERR "Unable to register block device (%d)\n",
-		mtip_major);
+		error);
 		return -EBUSY;
 		return -EBUSY;
 	}
 	}
+	mtip_major = error;
 
 
 	/* Register our PCI operations. */
 	/* Register our PCI operations. */
-	return pci_register_driver(&mtip_pci_driver);
+	error = pci_register_driver(&mtip_pci_driver);
+	if (error)
+		unregister_blkdev(mtip_major, MTIP_DRV_NAME);
+
+	return error;
 }
 }
 
 
 /*
 /*

+ 45 - 13
drivers/block/mtip32xx/mtip32xx.h

@@ -34,8 +34,8 @@
 /* offset of Device Control register in PCIe extended capabilites space */
 /* offset of Device Control register in PCIe extended capabilites space */
 #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET	0x48
 #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET	0x48
 
 
-/* # of times to retry timed out IOs */
-#define MTIP_MAX_RETRIES	5
+/* # of times to retry timed out/failed IOs */
+#define MTIP_MAX_RETRIES	2
 
 
 /* Various timeout values in ms */
 /* Various timeout values in ms */
 #define MTIP_NCQ_COMMAND_TIMEOUT_MS       5000
 #define MTIP_NCQ_COMMAND_TIMEOUT_MS       5000
@@ -114,12 +114,41 @@
 #define __force_bit2int (unsigned int __force)
 #define __force_bit2int (unsigned int __force)
 
 
 /* below are bit numbers in 'flags' defined in mtip_port */
 /* below are bit numbers in 'flags' defined in mtip_port */
-#define MTIP_FLAG_IC_ACTIVE_BIT			0
-#define MTIP_FLAG_EH_ACTIVE_BIT			1
-#define MTIP_FLAG_SVC_THD_ACTIVE_BIT		2
-#define MTIP_FLAG_ISSUE_CMDS_BIT		4
-#define MTIP_FLAG_REBUILD_BIT			5
-#define MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT	8
+#define MTIP_PF_IC_ACTIVE_BIT		0 /* pio/ioctl */
+#define MTIP_PF_EH_ACTIVE_BIT		1 /* error handling */
+#define MTIP_PF_SE_ACTIVE_BIT		2 /* secure erase */
+#define MTIP_PF_DM_ACTIVE_BIT		3 /* download microcde */
+#define MTIP_PF_PAUSE_IO	((1 << MTIP_PF_IC_ACTIVE_BIT) | \
+				(1 << MTIP_PF_EH_ACTIVE_BIT) | \
+				(1 << MTIP_PF_SE_ACTIVE_BIT) | \
+				(1 << MTIP_PF_DM_ACTIVE_BIT))
+
+#define MTIP_PF_SVC_THD_ACTIVE_BIT	4
+#define MTIP_PF_ISSUE_CMDS_BIT		5
+#define MTIP_PF_REBUILD_BIT		6
+#define MTIP_PF_SVC_THD_STOP_BIT	8
+
+/* below are bit numbers in 'dd_flag' defined in driver_data */
+#define MTIP_DDF_REMOVE_PENDING_BIT	1
+#define MTIP_DDF_OVER_TEMP_BIT		2
+#define MTIP_DDF_WRITE_PROTECT_BIT	3
+#define MTIP_DDF_STOP_IO	((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \
+				(1 << MTIP_DDF_OVER_TEMP_BIT) | \
+				(1 << MTIP_DDF_WRITE_PROTECT_BIT))
+
+#define MTIP_DDF_CLEANUP_BIT		5
+#define MTIP_DDF_RESUME_BIT		6
+#define MTIP_DDF_INIT_DONE_BIT		7
+#define MTIP_DDF_REBUILD_FAILED_BIT	8
+
+__packed struct smart_attr{
+	u8 attr_id;
+	u16 flags;
+	u8 cur;
+	u8 worst;
+	u32 data;
+	u8 res[3];
+};
 
 
 /* Register Frame Information Structure (FIS), host to device. */
 /* Register Frame Information Structure (FIS), host to device. */
 struct host_to_dev_fis {
 struct host_to_dev_fis {
@@ -345,6 +374,12 @@ struct mtip_port {
 	 * when the command slot and all associated data structures
 	 * when the command slot and all associated data structures
 	 * are no longer needed.
 	 * are no longer needed.
 	 */
 	 */
+	u16 *log_buf;
+	dma_addr_t log_buf_dma;
+
+	u8 *smart_buf;
+	dma_addr_t smart_buf_dma;
+
 	unsigned long allocated[SLOTBITS_IN_LONGS];
 	unsigned long allocated[SLOTBITS_IN_LONGS];
 	/*
 	/*
 	 * used to queue commands when an internal command is in progress
 	 * used to queue commands when an internal command is in progress
@@ -368,6 +403,7 @@ struct mtip_port {
 	 * Timer used to complete commands that have been active for too long.
 	 * Timer used to complete commands that have been active for too long.
 	 */
 	 */
 	struct timer_list cmd_timer;
 	struct timer_list cmd_timer;
+	unsigned long ic_pause_timer;
 	/*
 	/*
 	 * Semaphore used to block threads if there are no
 	 * Semaphore used to block threads if there are no
 	 * command slots available.
 	 * command slots available.
@@ -404,13 +440,9 @@ struct driver_data {
 
 
 	unsigned slot_groups; /* number of slot groups the product supports */
 	unsigned slot_groups; /* number of slot groups the product supports */
 
 
-	atomic_t drv_cleanup_done; /* Atomic variable for SRSI */
-
 	unsigned long index; /* Index to determine the disk name */
 	unsigned long index; /* Index to determine the disk name */
 
 
-	unsigned int ftlrebuildflag; /* FTL rebuild flag */
-
-	atomic_t resumeflag; /* Atomic variable to track suspend/resume */
+	unsigned long dd_flag; /* NOTE: use atomic bit operations on this */
 
 
 	struct task_struct *mtip_svc_handler; /* task_struct of svc thd */
 	struct task_struct *mtip_svc_handler; /* task_struct of svc thd */
 };
 };

+ 1 - 0
drivers/block/virtio_blk.c

@@ -351,6 +351,7 @@ static void virtblk_config_changed_work(struct work_struct *work)
 		  cap_str_10, cap_str_2);
 		  cap_str_10, cap_str_2);
 
 
 	set_capacity(vblk->disk, capacity);
 	set_capacity(vblk->disk, capacity);
+	revalidate_disk(vblk->disk);
 done:
 done:
 	mutex_unlock(&vblk->config_lock);
 	mutex_unlock(&vblk->config_lock);
 }
 }

+ 13 - 37
drivers/block/xen-blkback/blkback.c

@@ -321,6 +321,7 @@ struct seg_buf {
 static void xen_blkbk_unmap(struct pending_req *req)
 static void xen_blkbk_unmap(struct pending_req *req)
 {
 {
 	struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 	struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+	struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 	unsigned int i, invcount = 0;
 	unsigned int i, invcount = 0;
 	grant_handle_t handle;
 	grant_handle_t handle;
 	int ret;
 	int ret;
@@ -332,25 +333,12 @@ static void xen_blkbk_unmap(struct pending_req *req)
 		gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i),
 		gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i),
 				    GNTMAP_host_map, handle);
 				    GNTMAP_host_map, handle);
 		pending_handle(req, i) = BLKBACK_INVALID_HANDLE;
 		pending_handle(req, i) = BLKBACK_INVALID_HANDLE;
+		pages[invcount] = virt_to_page(vaddr(req, i));
 		invcount++;
 		invcount++;
 	}
 	}
 
 
-	ret = HYPERVISOR_grant_table_op(
-		GNTTABOP_unmap_grant_ref, unmap, invcount);
+	ret = gnttab_unmap_refs(unmap, pages, invcount, false);
 	BUG_ON(ret);
 	BUG_ON(ret);
-	/*
-	 * Note, we use invcount, so nr->pages, so we can't index
-	 * using vaddr(req, i).
-	 */
-	for (i = 0; i < invcount; i++) {
-		ret = m2p_remove_override(
-			virt_to_page(unmap[i].host_addr), false);
-		if (ret) {
-			pr_alert(DRV_PFX "Failed to remove M2P override for %lx\n",
-				 (unsigned long)unmap[i].host_addr);
-			continue;
-		}
-	}
 }
 }
 
 
 static int xen_blkbk_map(struct blkif_request *req,
 static int xen_blkbk_map(struct blkif_request *req,
@@ -378,7 +366,7 @@ static int xen_blkbk_map(struct blkif_request *req,
 				  pending_req->blkif->domid);
 				  pending_req->blkif->domid);
 	}
 	}
 
 
-	ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg);
+	ret = gnttab_map_refs(map, NULL, &blkbk->pending_page(pending_req, 0), nseg);
 	BUG_ON(ret);
 	BUG_ON(ret);
 
 
 	/*
 	/*
@@ -398,15 +386,6 @@ static int xen_blkbk_map(struct blkif_request *req,
 		if (ret)
 		if (ret)
 			continue;
 			continue;
 
 
-		ret = m2p_add_override(PFN_DOWN(map[i].dev_bus_addr),
-			blkbk->pending_page(pending_req, i), NULL);
-		if (ret) {
-			pr_alert(DRV_PFX "Failed to install M2P override for %lx (ret: %d)\n",
-				 (unsigned long)map[i].dev_bus_addr, ret);
-			/* We could switch over to GNTTABOP_copy */
-			continue;
-		}
-
 		seg[i].buf  = map[i].dev_bus_addr |
 		seg[i].buf  = map[i].dev_bus_addr |
 			(req->u.rw.seg[i].first_sect << 9);
 			(req->u.rw.seg[i].first_sect << 9);
 	}
 	}
@@ -419,21 +398,18 @@ static int dispatch_discard_io(struct xen_blkif *blkif,
 	int err = 0;
 	int err = 0;
 	int status = BLKIF_RSP_OKAY;
 	int status = BLKIF_RSP_OKAY;
 	struct block_device *bdev = blkif->vbd.bdev;
 	struct block_device *bdev = blkif->vbd.bdev;
+	unsigned long secure;
 
 
 	blkif->st_ds_req++;
 	blkif->st_ds_req++;
 
 
 	xen_blkif_get(blkif);
 	xen_blkif_get(blkif);
-	if (blkif->blk_backend_type == BLKIF_BACKEND_PHY ||
-	    blkif->blk_backend_type == BLKIF_BACKEND_FILE) {
-		unsigned long secure = (blkif->vbd.discard_secure &&
-			(req->u.discard.flag & BLKIF_DISCARD_SECURE)) ?
-			BLKDEV_DISCARD_SECURE : 0;
-		err = blkdev_issue_discard(bdev,
-				req->u.discard.sector_number,
-				req->u.discard.nr_sectors,
-				GFP_KERNEL, secure);
-	} else
-		err = -EOPNOTSUPP;
+	secure = (blkif->vbd.discard_secure &&
+		 (req->u.discard.flag & BLKIF_DISCARD_SECURE)) ?
+		 BLKDEV_DISCARD_SECURE : 0;
+
+	err = blkdev_issue_discard(bdev, req->u.discard.sector_number,
+				   req->u.discard.nr_sectors,
+				   GFP_KERNEL, secure);
 
 
 	if (err == -EOPNOTSUPP) {
 	if (err == -EOPNOTSUPP) {
 		pr_debug(DRV_PFX "discard op failed, not supported\n");
 		pr_debug(DRV_PFX "discard op failed, not supported\n");
@@ -830,7 +806,7 @@ static int __init xen_blkif_init(void)
 	int i, mmap_pages;
 	int i, mmap_pages;
 	int rc = 0;
 	int rc = 0;
 
 
-	if (!xen_pv_domain())
+	if (!xen_domain())
 		return -ENODEV;
 		return -ENODEV;
 
 
 	blkbk = kzalloc(sizeof(struct xen_blkbk), GFP_KERNEL);
 	blkbk = kzalloc(sizeof(struct xen_blkbk), GFP_KERNEL);

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