Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 15 Apr 2012 18:14:54 +0000 (11:14 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 15 Apr 2012 18:14:54 +0000 (11:14 -0700)
Pull "ARM: a few more SoC fixes for 3.4-rc" from Olof Johansson:
 - A handful of warning and build fixes for Qualcomm MSM
 - Build/warning and bug fixes for Samsung Exynos
 - A fix from Rob Herring that removes misplaced interrupt-parent
   properties from a few device trees
 - A fix to OMAP dealing with cpufreq build errors, removing some of the
   offending code since it was redundant anyway

* tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc:
  ARM: OMAP: clock: cleanup CPUfreq leftovers, fix build errors
  ARM: dts: remove blank interrupt-parent properties
  ARM: EXYNOS: Fix Kconfig dependencies for device tree enabled machine files
  ARM: EXYNOS: Remove broken config values for touchscren for NURI board
  ARM: EXYNOS: set fix xusbxti clock for NURI and Universal210 boards
  ARM: EXYNOS: fix regulator name for NURI board
  ARM: SAMSUNG: make SAMSUNG_PM_DEBUG select DEBUG_LL
  ARM: msm: Fix section mismatches in proc_comm.c
  video: msm: Fix section mismatches in mddi.c
  arm: msm: trout: fix compile failure
  arm: msm: halibut: remove unneeded fixup
  ARM: EXYNOS: Add PDMA and MDMA physical base address defines
  ARM: S5PV210: Fix compiler warning in dma.c file
  ARM: EXYNOS: Fix compile error in exynos5250-cpufreq.c
  ARM: EXYNOS: Add missing definition for IRQ_I2S0
  ARM: S5PV210: fix unused LDO supply field from wm8994_pdata

320 files changed:
Documentation/ABI/stable/sysfs-driver-usb-usbtmc
Documentation/ABI/testing/sysfs-block-rssd [new file with mode: 0644]
Documentation/ABI/testing/sysfs-cfq-target-latency [new file with mode: 0644]
Documentation/cgroups/memory.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/vfs.txt
Documentation/sound/alsa/HD-Audio-Models.txt
Documentation/usb/URB.txt
Documentation/usb/usbmon.txt
MAINTAINERS
arch/alpha/include/asm/atomic.h
arch/alpha/include/asm/cmpxchg.h [new file with mode: 0644]
arch/alpha/include/asm/xchg.h
arch/c6x/include/asm/irq.h
arch/c6x/kernel/irq.c
arch/ia64/include/asm/cmpxchg.h
arch/ia64/include/asm/intrinsics.h
arch/powerpc/include/asm/irq.h
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/process.c
arch/powerpc/platforms/cell/axon_msi.c
arch/powerpc/platforms/cell/beat_interrupt.c
arch/powerpc/platforms/powermac/smp.c
arch/powerpc/platforms/ps3/interrupt.c
arch/sparc/kernel/ds.c
arch/sparc/kernel/leon_pci.c
arch/sparc/kernel/rtrap_64.S
arch/sparc/mm/fault_32.c
arch/sparc/mm/fault_64.c
arch/tile/kernel/proc.c
arch/tile/kernel/smpboot.c
arch/um/drivers/cow.h
arch/um/drivers/cow_user.c
arch/um/drivers/mconsole_kern.c
arch/um/include/asm/Kbuild
arch/um/kernel/Makefile
arch/um/kernel/process.c
arch/um/kernel/skas/mmu.c
arch/x86/Makefile.um
arch/x86/include/asm/cmpxchg.h
arch/x86/include/asm/uaccess.h
arch/x86/include/asm/uaccess_32.h
arch/x86/include/asm/uaccess_64.h
arch/x86/kernel/vsyscall_64.c
arch/x86/lib/usercopy.c
arch/x86/lib/usercopy_32.c
arch/x86/lib/usercopy_64.c
arch/x86/um/asm/barrier.h [new file with mode: 0644]
arch/x86/um/asm/system.h [deleted file]
block/blk-core.c
block/blk-throttle.c
block/cfq-iosched.c
crypto/Kconfig
drivers/base/soc.c
drivers/bcma/Kconfig
drivers/bcma/driver_pci_host.c
drivers/block/cciss_scsi.c
drivers/block/mtip32xx/Kconfig
drivers/block/mtip32xx/mtip32xx.c
drivers/block/mtip32xx/mtip32xx.h
drivers/block/virtio_blk.c
drivers/block/xen-blkback/blkback.c
drivers/block/xen-blkback/common.h
drivers/block/xen-blkback/xenbus.c
drivers/block/xen-blkfront.c
drivers/bluetooth/ath3k.c
drivers/bluetooth/btusb.c
drivers/bluetooth/hci_ldisc.c
drivers/char/hpet.c
drivers/char/random.c
drivers/clocksource/acpi_pm.c
drivers/cpufreq/Kconfig.arm
drivers/dma/dmaengine.c
drivers/dma/ioat/dma.c
drivers/dma/ioat/dma.h
drivers/dma/ioat/dma_v2.c
drivers/dma/ioat/dma_v2.h
drivers/dma/ioat/dma_v3.c
drivers/dma/iop-adma.c
drivers/gpio/Kconfig
drivers/gpio/gpio-adp5588.c
drivers/gpio/gpio-samsung.c
drivers/gpio/gpio-sodaville.c
drivers/gpu/drm/exynos/exynos_drm_buf.c
drivers/gpu/drm/exynos/exynos_drm_core.c
drivers/gpu/drm/exynos/exynos_drm_drv.h
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_gem.c
drivers/gpu/drm/exynos/exynos_drm_gem.h
drivers/gpu/drm/exynos/exynos_drm_hdmi.c
drivers/gpu/drm/exynos/exynos_drm_hdmi.h
drivers/gpu/drm/exynos/exynos_drm_plane.c
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/exynos/exynos_hdmi.c
drivers/gpu/drm/exynos/exynos_mixer.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_sprite.c
drivers/gpu/drm/radeon/atombios_encoders.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_cp.c
drivers/gpu/drm/radeon/radeon_clocks.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_i2c.c
drivers/gpu/drm/radeon/radeon_legacy_encoders.c
drivers/gpu/drm/savage/savage_state.c
drivers/hwmon/acpi_power_meter.c
drivers/hwmon/pmbus/pmbus_core.c
drivers/hwmon/smsc47b397.c
drivers/hwmon/smsc47m1.c
drivers/i2c/busses/i2c-designware-pcidrv.c
drivers/infiniband/core/sysfs.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/ulp/srpt/ib_srpt.c
drivers/input/misc/da9052_onkey.c
drivers/input/mouse/elantech.c
drivers/input/mouse/gpio_mouse.c
drivers/input/mouse/sentelic.c
drivers/input/mouse/trackpoint.c
drivers/input/touchscreen/tps6507x-ts.c
drivers/isdn/gigaset/interface.c
drivers/md/bitmap.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/dvb/dvb-usb/it913x.c
drivers/media/video/ivtv/ivtv-ioctl.c
drivers/media/video/uvc/uvc_video.c
drivers/mtd/mtdchar.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rtlwifi/base.c
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/rtl8192de/sw.c
drivers/net/wireless/rtlwifi/usb.c
drivers/net/wireless/rtlwifi/wifi.h
drivers/of/gpio.c
drivers/regulator/anatop-regulator.c
drivers/rtc/rtc-efi.c
drivers/rtc/rtc-pl031.c
drivers/rtc/rtc-r9701.c
drivers/rtc/rtc-s3c.c
drivers/rtc/rtc-twl.c
drivers/scsi/scsi_error.c
drivers/spi/spi-davinci.c
drivers/spi/spi-fsl-spi.c
drivers/spi/spi-imx.c
drivers/staging/android/Kconfig
drivers/staging/android/lowmemorykiller.c
drivers/staging/android/persistent_ram.c
drivers/staging/android/timed_gpio.c
drivers/staging/iio/inkern.c
drivers/staging/iio/magnetometer/ak8975.c
drivers/staging/iio/magnetometer/hmc5843.c
drivers/staging/media/as102/as102_fw.c
drivers/staging/omapdrm/omap_drv.c
drivers/staging/ozwpan/TODO
drivers/staging/ramster/Kconfig
drivers/staging/rts_pstor/ms.c
drivers/staging/rts_pstor/rtsx.c
drivers/staging/rts_pstor/rtsx_transport.c
drivers/staging/sep/sep_main.c
drivers/staging/vme/devices/vme_pio2_core.c
drivers/staging/vt6655/key.c
drivers/staging/vt6656/ioctl.c
drivers/staging/vt6656/key.c
drivers/staging/xgifb/vb_init.c
drivers/staging/xgifb/vb_setmode.c
drivers/staging/xgifb/vb_table.h
drivers/staging/zsmalloc/zsmalloc-main.c
drivers/tty/serial/8250/8250.c
drivers/tty/serial/8250/8250_pci.c
drivers/tty/serial/Kconfig
drivers/tty/serial/altera_uart.c
drivers/tty/serial/amba-pl011.c
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/omap-serial.c
drivers/tty/serial/pch_uart.c
drivers/tty/serial/samsung.c
drivers/tty/vt/vt.c
drivers/usb/Kconfig
drivers/usb/core/driver.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/core/urb.c
drivers/usb/gadget/inode.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-tegra.c
drivers/usb/host/ehci.h
drivers/usb/host/pci-quirks.c
drivers/usb/host/uhci-hub.c
drivers/usb/host/xhci-dbg.c
drivers/usb/host/xhci-ext-caps.h
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/serial/bus.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/metro-usb.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/sierra.c
drivers/usb/serial/usb-serial.c
drivers/usb/storage/usb.c
drivers/video/au1100fb.c
drivers/video/au1200fb.c
drivers/video/kyro/STG4000Reg.h
drivers/video/uvesafb.c
fs/btrfs/compression.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/free-space-cache.c
fs/btrfs/scrub.c
fs/btrfs/transaction.c
fs/btrfs/volumes.c
fs/gfs2/Kconfig
fs/gfs2/aops.c
fs/gfs2/bmap.c
fs/gfs2/dir.c
fs/gfs2/inode.c
fs/gfs2/rgrp.c
fs/gfs2/xattr.c
fs/libfs.c
fs/proc/stat.c
fs/sysfs/dir.c
fs/sysfs/group.c
include/drm/exynos_drm.h
include/linux/amba/pl022.h
include/linux/blkdev.h
include/linux/dmaengine.h
include/linux/irq.h
include/linux/irqdomain.h
include/linux/kconfig.h
include/linux/netfilter_ipv6/ip6_tables.h
include/linux/serial_core.h
include/linux/skbuff.h
include/linux/stddef.h
include/linux/types.h
include/linux/usb/serial.h
include/linux/vgaarb.h
include/net/bluetooth/hci.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/mgmt.h
include/net/mac80211.h
include/scsi/scsi_cmnd.h
include/sound/core.h
kernel/cred.c
kernel/irq/Kconfig
kernel/irq/irqdomain.c
kernel/irq_work.c
kernel/itimer.c
kernel/panic.c
kernel/time/Kconfig
kernel/time/tick-broadcast.c
kernel/time/tick-sched.c
lib/kobject.c
mm/hugetlb.c
mm/memcontrol.c
mm/vmscan.c
net/bluetooth/hci_core.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c
net/bluetooth/mgmt.c
net/bridge/br_multicast.c
net/bridge/br_private.h
net/core/skbuff.c
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/tcp_ipv6.c
net/mac80211/mlme.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_proto_tcp.c
net/nfc/llcp/commands.c
net/wireless/nl80211.c
net/wireless/wext-core.c
scripts/kconfig/confdata.c
scripts/mod/modpost.c
scripts/mod/modpost.h
security/smack/smack_lsm.c
sound/isa/sscape.c
sound/oss/msnd_pinnacle.c
sound/pci/Kconfig
sound/pci/asihpi/hpi_internal.h
sound/pci/asihpi/hpios.c
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_eld.c
sound/pci/hda/hda_proc.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/soc/codecs/ak4642.c
sound/soc/codecs/sgtl5000.c
sound/soc/imx/imx-audmux.c
sound/soc/pxa/pxa2xx-i2s.c
sound/soc/soc-core.c
sound/soc/tegra/tegra_i2s.c
sound/soc/tegra/tegra_spdif.c
tools/perf/builtin-sched.c
tools/perf/builtin-top.c
tools/perf/util/annotate.c
tools/perf/util/hist.c
tools/perf/util/map.c
tools/perf/util/map.h
tools/perf/util/session.c
tools/perf/util/ui/browsers/hists.c

index 2a7f9a00cb0a6a0acef8fc46bbb6f290f4d0dc67..e960cd027e1e9685a83f3275ca859da7a793e116 100644 (file)
@@ -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
 Contact:       Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
@@ -12,8 +12,8 @@ Description:
                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
 Contact:       Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
@@ -27,7 +27,7 @@ Description:
                The files are read only.
 
 
-What:          /sys/bus/usb/drivers/usbtmc/devices/*/TermChar
+What:          /sys/bus/usb/drivers/usbtmc/*/TermChar
 Date:          August 2008
 Contact:       Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
@@ -40,7 +40,7 @@ Description:
                sent to the device or not.
 
 
-What:          /sys/bus/usb/drivers/usbtmc/devices/*/TermCharEnabled
+What:          /sys/bus/usb/drivers/usbtmc/*/TermCharEnabled
 Date:          August 2008
 Contact:       Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
@@ -51,7 +51,7 @@ Description:
                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
 Contact:       Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 Description:
diff --git a/Documentation/ABI/testing/sysfs-block-rssd b/Documentation/ABI/testing/sysfs-block-rssd
new file mode 100644 (file)
index 0000000..d535757
--- /dev/null
@@ -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.
diff --git a/Documentation/ABI/testing/sysfs-cfq-target-latency b/Documentation/ABI/testing/sysfs-cfq-target-latency
new file mode 100644 (file)
index 0000000..df0f782
--- /dev/null
@@ -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.
index 4c95c0034a4bbbffdae12a99ff2ddbd0798ca09c..9b1067afb2245f702d962ca4a93c241af6641a02 100644 (file)
@@ -34,8 +34,7 @@ Current Status: linux-2.6.34-mmotm(development version of 2010/April)
 
 Features:
  - 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.
  - hierarchical accounting
  - soft limit
@@ -154,7 +153,7 @@ updated. page_cgroup has its own LRU on cgroup.
 2.2.1 Accounting details
 
 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.
 
 RSS pages are accounted at page_fault unless they've already been accounted
index 709e08e9a222fd9f89a6eb91edf9f5b3326df536..03ca210406edfcbe90fc58cd006ef0e7d313b42f 100644 (file)
@@ -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
        removed.
 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>
index e916e3d36488d982b4cc1a8580ea5f0529af79d2..0d0492028082c0ecda1a0931cc5100765624a80a 100644 (file)
@@ -114,7 +114,7 @@ members are defined:
 struct file_system_type {
        const char *name;
        int fs_flags;
-        struct dentry (*mount) (struct file_system_type *, int,
+        struct dentry *(*mount) (struct file_system_type *, int,
                        const char *, void *);
         void (*kill_sb) (struct super_block *);
         struct module *owner;
index d97d992ced14f97a5d423f79f1ae9b9f230fc55e..03f7897c641425346e674c360df2ccf97b5b59d3 100644 (file)
@@ -43,7 +43,9 @@ ALC680
 
 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
 ==========
index 8ffce746d496fc41de3cfadf7ad02af5f7fa6637..00d2c644068e9ae5d0e0044150289f0976a0ae9d 100644 (file)
@@ -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
 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?
 
index 5335fa8b06eb4f2b632126bd9fd95878b6efdce0..c42bb9cd3b43749837f1c784a2571cb6d42bf03f 100644 (file)
@@ -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 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 >
 
 * Raw binary format and API
index 2dcfca850639f90b2de9952197b6ae3d05011c2f..b0f1073c40b0d8dc226b5d0efaa44167d801262b 100644 (file)
@@ -1521,8 +1521,8 @@ M:        Gustavo Padovan <gustavo@padovan.org>
 M:     Johan Hedberg <johan.hedberg@gmail.com>
 L:     linux-bluetooth@vger.kernel.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
 F:     drivers/bluetooth/
 
@@ -1532,8 +1532,8 @@ M:        Gustavo Padovan <gustavo@padovan.org>
 M:     Johan Hedberg <johan.hedberg@gmail.com>
 L:     linux-bluetooth@vger.kernel.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
 F:     net/bluetooth/
 F:     include/net/bluetooth/
@@ -4533,8 +4533,7 @@ S:        Supported
 F:     drivers/net/ethernet/myricom/myri10ge/
 
 NATSEMI ETHERNET DRIVER (DP8381x)
-M:     Tim Hockin <thockin@hockin.org>
-S:     Maintained
+S:     Orphan
 F:     drivers/net/ethernet/natsemi/natsemi.c
 
 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
 
 OMAP AUDIO SUPPORT
+M:     Peter Ujfalusi <peter.ujfalusi@ti.com>
 M:     Jarkko Nikula <jarkko.nikula@bitmer.com>
 L:     alsa-devel@alsa-project.org (subscribers-only)
 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-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
 M:     Linas Vepstas <linasvepstas@gmail.com>
 L:     linux-pci@vger.kernel.org
@@ -6466,6 +6471,7 @@ S:        Odd Fixes
 F:     drivers/staging/olpc_dcon/
 
 STAGING - OZMO DEVICES USB OVER WIFI DRIVER
+M:     Rupesh Gujare <rgujare@ozmodevices.com>
 M:     Chris Kelly <ckelly@ozmodevices.com>
 S:     Maintained
 F:     drivers/staging/ozwpan/
@@ -7461,8 +7467,7 @@ F:        include/linux/wm97xx.h
 
 WOLFSON MICROELECTRONICS DRIVERS
 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-audioplus
 W:     http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices
index f62251e82ffac39579e26c0ee6f77f58c1bd9ac5..3bb7ffeae3bc610010bb54a3eaba698c513c0c7d 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/types.h>
 #include <asm/barrier.h>
+#include <asm/cmpxchg.h>
 
 /*
  * 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;
 }
 
-/*
- * 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_xchg(v, new) (xchg(&((v)->counter), new))
 
diff --git a/arch/alpha/include/asm/cmpxchg.h b/arch/alpha/include/asm/cmpxchg.h
new file mode 100644 (file)
index 0000000..429e8cd
--- /dev/null
@@ -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 */
index 1d1b436fbff252bc867c8e577c7b8759bc55cc20..0ca9724597c1603024ff26d366013bc2da92387b 100644 (file)
@@ -1,10 +1,10 @@
-#ifndef _ALPHA_ATOMIC_H
+#ifndef _ALPHA_CMPXCHG_H
 #error Do not include xchg.h directly!
 #else
 /*
  * xchg/xchg_local and cmpxchg/cmpxchg_local share the same code
  * 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.
  */
 
 /*
index f13b78d5e1ca2c8f170357dd39c35d124f445daf..ab4577f93d96c97f347936a33a75dce2825df0c4 100644 (file)
 /* This number is used when no interrupt has been assigned */
 #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_IRQ(void);
index 65b8ddf54b446ca904780dbc02a2e181fde037b1..c90fb5e82ad7b829fb9be3a9d562118374eff901 100644 (file)
@@ -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);
        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);
index 4c96187e204908bb3a9ba7e37a198df61159ff28..4f37dbbb864081cac07e473270f8dd5ec42cf083 100644 (file)
@@ -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 */
index e4076b511829572ad590d36e362f463f93e813d6..d129e367e76448036c4dad8c347cc6a33977f710 100644 (file)
@@ -18,6 +18,7 @@
 #else
 # include <asm/gcc_intrin.h>
 #endif
+#include <asm/cmpxchg.h>
 
 #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 */
 
-/*
- * 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
 
 #ifdef __KERNEL__
index cf417e51073627ff6184f15ddd3a78f7948419c7..e648af92ced18b20384102912fbaeafc903ddfb0 100644 (file)
@@ -33,8 +33,6 @@ extern atomic_t ppc_n_lost_interrupts;
 /* Same thing, used by the generic IRQ code */
 #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);
 
 /**
index 3e57a00b8cba784633d1b0465fd3b47f1b85baf0..ba3aeb4bc06a81453105c6294bd74b81b340ed77 100644 (file)
@@ -206,40 +206,43 @@ reenable_mmu:                             /* re-enable mmu so we can */
        andi.   r10,r10,MSR_EE          /* Did EE change? */
        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.
         * 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
         * 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
-       beq     11f
-       stwu    r1,-16(r1)
+       b       11f
        bl      trace_hardirqs_off
-       addi    r1,r1,16
        b       12f
-
 11:
        bl      trace_hardirqs_off
 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     r3,ORIG_GPR3(r1)
-       lwz     r4,GPR4(r1)
-       lwz     r5,GPR5(r1)
        lwz     r6,GPR6(r1)
        lwz     r7,GPR7(r1)
        lwz     r8,GPR8(r1)
-       lwz     r9,8(r1)
-       lwz     r11,12(r1)
 1:     mtctr   r11
        mtlr    r9
        bctr                            /* jump to handler */
index 243dbabfe74dff0ebbe55fab216a335574c1dc12..5ec1b2354ca62301b83019db2f342bd92c085b80 100644 (file)
@@ -560,12 +560,6 @@ void do_softirq(void)
        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)
 {
        struct irq_data *irq_data = irq_get_irq_data(virq);
index f88698c0f332d2a0c87957d10f1ca32ddd3d5eb0..4937c9690090d0e9bf3809b7ae923ae24d181d93 100644 (file)
@@ -1235,7 +1235,7 @@ void __ppc64_runlatch_on(void)
        ctrl |= CTRL_RUNLATCH;
        mtspr(SPRN_CTRLT, ctrl);
 
-       ti->local_flags |= TLF_RUNLATCH;
+       ti->local_flags |= _TLF_RUNLATCH;
 }
 
 /* Called with hard IRQs off */
@@ -1244,7 +1244,7 @@ void __ppc64_runlatch_off(void)
        struct thread_info *ti = current_thread_info();
        unsigned long ctrl;
 
-       ti->local_flags &= ~TLF_RUNLATCH;
+       ti->local_flags &= ~_TLF_RUNLATCH;
 
        ctrl = mfspr(SPRN_CTRLF);
        ctrl &= ~CTRL_RUNLATCH;
index db360fc4cf0e616a9f463c37f197ee04ba4d657d..d09f3e8e68670585230e52d33c28109d9ce6cf8e 100644 (file)
@@ -392,7 +392,7 @@ static int axon_msi_probe(struct platform_device *device)
        }
        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) {
                printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
                       dn->full_name);
index e5c3a2c6090d186b5ddeb5941514bda73d165065..f9a48af335cb8d17b52cb1ed34503175d0772fef 100644 (file)
@@ -239,7 +239,7 @@ void __init beatic_init_IRQ(void)
        ppc_md.get_irq = beatic_get_irq;
 
        /* 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);
        irq_set_default_host(beatic_host);
 }
index a81e5a88fbdf1c49c70cba6ef2699b86ed95d7b5..b4ddaa3fbb298eccc37044f61222d38a688c9f8c 100644 (file)
@@ -192,7 +192,7 @@ static int psurge_secondary_ipi_init(void)
 {
        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)
                psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
index 2a4ff86cc21f72c5c0af0082e4c12c64de5db6cd..5f3b23220b8ee395e0d9e05821a43b98fd8592f1 100644 (file)
@@ -753,9 +753,8 @@ void __init ps3_init_IRQ(void)
        unsigned cpu;
        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_virq_count(PS3_PLUG_MAX + 1);
 
        for_each_possible_cpu(cpu) {
                struct ps3_private *pd = &per_cpu(ps3_private, cpu);
index fea13c7b1aeeddcf206217c935a1b044ae96e215..b93c2c9ccb1d17c250d4a945e0fea06fff38baf6 100644 (file)
@@ -1264,4 +1264,4 @@ static int __init ds_init(void)
        return vio_register_driver(&ds_driver);
 }
 
-subsys_initcall(ds_init);
+fs_initcall(ds_init);
index aba6b958b2a5da25a49adbe76783eca1e5570dc9..19f56058742be945d1a29be0137a683523aa49cd 100644 (file)
@@ -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)
 {
-       struct leon_pci_info *info = pbus->sysdata;
        struct pci_dev *dev;
        int i, has_io, has_mem;
        u16 cmd;
@@ -111,18 +110,6 @@ int pcibios_enable_device(struct pci_dev *dev, int 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)
 {
 #ifdef CONFIG_PCI_DEBUG
index 77f1b95e0806bb92dc19fd421acd6f159e7dfab0..9171fc238def230e6e14e92852f2ee2d9b33a8f2 100644 (file)
 
                .text
                .align                  32
-__handle_softirq:
-               call                    do_softirq
-                nop
-               ba,a,pt                 %xcc, __handle_softirq_continue
-                nop
 __handle_preemption:
                call                    schedule
                 wrpr                   %g0, RTRAP_PSTATE, %pstate
@@ -89,9 +84,7 @@ rtrap:
                cmp                     %l1, 0
 
                /* mm/ultra.S:xcall_report_regs KNOWS about this load. */
-               bne,pn                  %icc, __handle_softirq
                 ldx                    [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
-__handle_softirq_continue:
 rtrap_xcall:
                sethi                   %hi(0xf << 20), %l4
                and                     %l1, %l4, %l4
index 7705c6731e2843697286e3d045279811d5691ed1..df3155a179918e0ad5e9741eceab601ae93d8abb 100644 (file)
@@ -225,6 +225,8 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
        unsigned long g2;
        int from_user = !(regs->psr & PSR_PS);
        int fault, code;
+       unsigned int flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
+                             (write ? FAULT_FLAG_WRITE : 0));
 
        if(text_fault)
                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);
 
+retry:
        down_read(&mm->mmap_sem);
 
        /*
@@ -289,7 +292,11 @@ good_area:
         * make sure we exit gracefully rather than endlessly redo
         * 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 (fault & VM_FAULT_OOM)
                        goto out_of_memory;
@@ -297,13 +304,29 @@ good_area:
                        goto do_sigbus;
                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);
        return;
 
index 504c0622f7296c42bb09cae18bc487630e6344a4..1fe0429b6314257faa40d80b07f7d4e3b77538c6 100644 (file)
@@ -279,6 +279,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
        unsigned int insn = 0;
        int si_code, fault_code, fault;
        unsigned long address, mm_rss;
+       unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
        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);
                        goto handle_kernel_fault;
                }
+
+retry:
                down_read(&mm->mmap_sem);
        }
 
@@ -423,7 +426,12 @@ good_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 (fault & VM_FAULT_OOM)
                        goto out_of_memory;
@@ -431,12 +439,27 @@ good_area:
                        goto do_sigbus;
                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);
 
index 7a93270464045753c76caa4032716ea6981c082c..446a7f52cc11f3a6380b7e6cfbf2181abca046a0 100644 (file)
@@ -146,7 +146,6 @@ static ctl_table unaligned_table[] = {
        },
        {}
 };
-#endif
 
 static struct ctl_path tile_path[] = {
        { .procname = "tile" },
@@ -155,10 +154,9 @@ static struct ctl_path tile_path[] = {
 
 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);
-#endif
        return 0;
 }
 
 arch_initcall(proc_sys_tile_init);
+#endif
index b949edcec200b60018c7ecf6a9aef049771e0260..172aef7d3159b254e428ccede2a86dca05115716 100644 (file)
@@ -196,6 +196,8 @@ void __cpuinit online_secondary(void)
        /* This must be done before setting cpu_online_mask */
        wmb();
 
+       notify_cpu_starting(smp_processor_id());
+
        /*
         * We need to hold call_lock, so there is no inconsistency
         * between the time smp_call_function() determines number of
index dc36b222100b9abde780f996407a758f336afce4..6673508f342603554c4fbe874511ab6df14af45f 100644 (file)
@@ -3,41 +3,6 @@
 
 #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,
                         int sectorsize, int alignment, int *bitmap_offset_out,
                         unsigned long *bitmap_len_out, int *data_offset_out);
index 9cbb426c0b9183e8a5c65afe47483f47e00da0ec..0ee9cc6cc4c79dfb4d78fd8fa15072294c62568f 100644 (file)
@@ -8,11 +8,10 @@
  * that.
  */
 #include <unistd.h>
-#include <byteswap.h>
 #include <errno.h>
 #include <string.h>
 #include <arpa/inet.h>
-#include <asm/types.h>
+#include <endian.h>
 #include "cow.h"
 #include "cow_sys.h"
 
@@ -214,8 +213,8 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
                           "header\n");
                goto out;
        }
-       header->magic = htonl(COW_MAGIC);
-       header->version = htonl(COW_VERSION);
+       header->magic = htobe32(COW_MAGIC);
+       header->version = htobe32(COW_VERSION);
 
        err = -EINVAL;
        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;
        }
 
-       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;
 
        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;
        if (magic == COW_MAGIC)
                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 */
        else goto out;
 
@@ -327,9 +326,9 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
                                   "header\n");
                        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);
                *align_out = *sectorsize_out;
                file = header->v2.backing_file;
@@ -341,10 +340,10 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
                                   "header\n");
                        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) {
                        cow_printf("read_cow_header - invalid COW header, "
                                   "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
                 * 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
                 * mismatch "0 vs whatever").
                 *
                 * 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) {
                        cow_printf("read_cow_header - invalid COW header, "
                                   "align == 0\n");
index e672bd6d43e3b2aa72b4c1c51029db9510233f52..43b39d61b538698229a23f654b7fb44a335187b3 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
 #include <asm/uaccess.h>
+#include <asm/switch_to.h>
 
 #include "init.h"
 #include "irq_kern.h"
index 8419f5cf2ac7e3586c68677198b2b28321b95221..fff24352255df0b0b448c43f11e287d5011fb836 100644 (file)
@@ -1,3 +1,4 @@
 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 += 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
index 492bc4c1b62bf3516a996d81c24c05c494fcf8d5..65a1c3d690ea01c8af4e2d7ea2c74d95ab415ec2 100644 (file)
@@ -3,9 +3,10 @@
 # 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
 clean-files :=
 
index f386d04a84a526df7a51a13cbc6c1636543071fe..2b73dedb44cacdda741b3e5774346c93b37b1b22 100644 (file)
@@ -88,11 +88,8 @@ static inline void set_current(struct task_struct *task)
 
 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;
        set_current(to);
 
@@ -111,7 +108,6 @@ void *_switch_to(void *prev, void *next, void *last)
        } while (current->thread.saved_task);
 
        return current->thread.prev_sched;
-
 }
 
 void interrupt_end(void)
index 4947b319f53ad7d1359631bf3ae09e0e38731b12..0a49ef0c2bf48995cb063ea425a10b91d11c8c96 100644 (file)
@@ -103,7 +103,6 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
 
 void uml_setup_stubs(struct mm_struct *mm)
 {
-       struct page **pages;
        int err, ret;
 
        if (!skas_needs_stub)
index 4be406abeefde51f1f3dd9419a799256ae1c1e1d..36b62bc52638368c750c250a529995cd8cac80cb 100644 (file)
@@ -14,6 +14,9 @@ LINK-y                        += $(call cc-option,-m32)
 
 export LDFLAGS
 
+LDS_EXTRA              := -Ui386
+export LDS_EXTRA
+
 # First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y.
 include $(srctree)/arch/x86/Makefile_32.cpu
 
index b3b7332629096849d11866c017c4444f8d156f9e..99480e55973d975a6082bf53c6f209591ec3d56c 100644 (file)
@@ -43,7 +43,7 @@ extern void __add_wrong_size(void)
                switch (sizeof(*(ptr))) {                               \
                case __X86_CASE_B:                                      \
                        asm volatile (lock #op "b %b0, %1\n"            \
-                                     : "+r" (__ret), "+m" (*(ptr))     \
+                                     : "+q" (__ret), "+m" (*(ptr))     \
                                      : : "memory", "cc");              \
                        break;                                          \
                case __X86_CASE_W:                                      \
@@ -173,7 +173,7 @@ extern void __add_wrong_size(void)
                switch (sizeof(*(ptr))) {                               \
                case __X86_CASE_B:                                      \
                        asm volatile (lock "addb %b1, %0\n"             \
-                                     : "+m" (*(ptr)) : "ri" (inc)      \
+                                     : "+m" (*(ptr)) : "qi" (inc)      \
                                      : "memory", "cc");                \
                        break;                                          \
                case __X86_CASE_W:                                      \
index 8be5f54d93606a374943cba5080dde65ff5e9e1d..e0544597cfe7b30a0e40d52c9d13cb65a6bf3d6c 100644 (file)
@@ -557,6 +557,8 @@ struct __large_struct { unsigned long buf[100]; };
 
 extern unsigned long
 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
index 566e803cc6026a11a1391fd25051717cef3f5979..8084bc73b18cbf8164f85dc86f7e78c4e1b07c78 100644 (file)
@@ -213,11 +213,6 @@ static inline unsigned long __must_check copy_from_user(void *to,
        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.
  * @str: The string to measure.
index 1c66d30971adedaac940770d701e141ae464e1f4..fcd4b6f3ef02ffcabec9ae5ef815ea7b7fdf80a8 100644 (file)
@@ -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 strlen_user(const char __user *str);
index f386dc49f988d753c5b9f8167c80313d5be72178..7515cf0e1805eae308e1dd0650b1dd33a8d8564d 100644 (file)
@@ -216,9 +216,9 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
        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
-        * vsyscalls, 0 means "don't write anything" not "write it at
+        * vsyscalls, NULL means "don't write anything" not "write it at
         * address 0".
         */
        ret = -EFAULT;
@@ -247,7 +247,7 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
 
                ret = sys_getcpu((unsigned __user *)regs->di,
                                 (unsigned __user *)regs->si,
-                                0);
+                                NULL);
                break;
        }
 
index 97be9cb54483a05f8c5e9510d563f129ea863966..57252c928f562025dffe8abdba4801869bb10f8c 100644 (file)
@@ -7,6 +7,8 @@
 #include <linux/highmem.h>
 #include <linux/module.h>
 
+#include <asm/word-at-a-time.h>
+
 /*
  * 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;
 }
 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, 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 count;
+
+       /*
+        * 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);
index d9b094ca7aaaed9305564228f6d68810d8b8afa1..ef2a6a5d78e39ddc71c2c51d90dc56f9cbcab9ef 100644 (file)
@@ -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) \
        __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
  */
index b7c2849ffb66015ed114a5ab2015956aecd69d7b..0d0326f388c0bdf9778ec2157c6d39cae3ff5c12 100644 (file)
@@ -8,55 +8,6 @@
 #include <linux/module.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
  */
diff --git a/arch/x86/um/asm/barrier.h b/arch/x86/um/asm/barrier.h
new file mode 100644 (file)
index 0000000..7d01b8c
--- /dev/null
@@ -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
diff --git a/arch/x86/um/asm/system.h b/arch/x86/um/asm/system.h
deleted file mode 100644 (file)
index a459fd9..0000000
+++ /dev/null
@@ -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
index 3a78b00edd71cfb7b667d50c9d3fe3265a5dba28..1f61b74867e41d3f74f61aeec539e8b00157dacf 100644 (file)
@@ -483,7 +483,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
        if (!q)
                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)
                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) {
                int el_ret;
 
-               (*request_count)++;
+               if (rq->q == q)
+                       (*request_count)++;
 
                if (rq->q != q || !blk_rq_merge_ok(rq, bio))
                        continue;
index 5eed6a76721d1d78e8105f4bbde30e41f20a66cd..f2ddb94626bd49df5e942591998d19ff8665a0eb 100644 (file)
@@ -1218,7 +1218,7 @@ void blk_throtl_drain(struct request_queue *q)
        struct bio_list bl;
        struct bio *bio;
 
-       WARN_ON_ONCE(!queue_is_locked(q));
+       queue_lockdep_assert_held(q);
 
        bio_list_init(&bl);
 
index 457295253566e97179daca0502c57c320962ed24..3c38536bd52c3e3a25f1b8152e40a6ebe5192d36 100644 (file)
@@ -295,6 +295,7 @@ struct cfq_data {
        unsigned int cfq_slice_idle;
        unsigned int cfq_group_idle;
        unsigned int cfq_latency;
+       unsigned int cfq_target_latency;
 
        /*
         * 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;
 
-       return cfq_target_latency * cfqg->weight / st->total_weight;
+       return cfqd->cfq_target_latency * cfqg->weight / st->total_weight;
 }
 
 static inline unsigned
@@ -2271,7 +2272,8 @@ new_workload:
                 * to have higher weight. A more accurate thing would be to
                 * 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;
                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_slice[0] = cfq_slice_async;
        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_idle = cfq_slice_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_rq_show, cfqd->cfq_slice_async_rq, 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
 
 #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,
                UINT_MAX, 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
 
 #define CFQ_ATTR(name) \
@@ -3838,6 +3843,7 @@ static struct elv_fs_entry cfq_attrs[] = {
        CFQ_ATTR(slice_idle),
        CFQ_ATTR(group_idle),
        CFQ_ATTR(low_latency),
+       CFQ_ATTR(target_latency),
        __ATTR_NULL
 };
 
index 21ff9d015432e2e50737db0278ed7bea41ff601c..8e84225c096b6adfafcde59d08e066e5751af9c2 100644 (file)
@@ -627,7 +627,7 @@ config CRYPTO_BLOWFISH_COMMON
 
 config CRYPTO_BLOWFISH_X86_64
        tristate "Blowfish cipher algorithm (x86_64)"
-       depends on (X86 || UML_X86) && 64BIT
+       depends on X86 && 64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_BLOWFISH_COMMON
        help
@@ -657,7 +657,7 @@ config CRYPTO_CAMELLIA
 
 config CRYPTO_CAMELLIA_X86_64
        tristate "Camellia cipher algorithm (x86_64)"
-       depends on (X86 || UML_X86) && 64BIT
+       depends on X86 && 64BIT
        depends on CRYPTO
        select CRYPTO_ALGAPI
        select CRYPTO_LRW
@@ -893,7 +893,7 @@ config CRYPTO_TWOFISH_X86_64
 
 config CRYPTO_TWOFISH_X86_64_3WAY
        tristate "Twofish cipher algorithm (x86_64, 3-way parallel)"
-       depends on (X86 || UML_X86) && 64BIT
+       depends on X86 && 64BIT
        select CRYPTO_ALGAPI
        select CRYPTO_TWOFISH_COMMON
        select CRYPTO_TWOFISH_X86_64
index 05f150382da86fa70dd161067b26bdf59d33fc94..ba29b2e73d48936ab9a93a028abd0b0d9cd29691 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/sys_soc.h>
 #include <linux/err.h>
 
-static DEFINE_IDR(soc_ida);
+static DEFINE_IDA(soc_ida);
 static DEFINE_SPINLOCK(soc_lock);
 
 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)
 {
-       spin_lock_init(&soc_lock);
-
        return bus_register(&soc_bus_type);
 }
 core_initcall(soc_bus_register);
index c1172dafdffac1c7688155dc20a658628c6934ca..fb7c80fb721e2466d405deedc367967179ea1d80 100644 (file)
@@ -29,7 +29,7 @@ config BCMA_HOST_PCI
 
 config BCMA_DRIVER_PCI_HOSTMODE
        bool "Driver for PCI core working in hostmode"
-       depends on BCMA && MIPS
+       depends on BCMA && MIPS && BCMA_HOST_PCI
        help
          PCI core hostmode operation (external PCI bus).
 
index 4e20bcfa7ec5d3e62bdf34004601c2edca813ddc..d2097a11c3c7ae259f7e18dd4b5ff934c5ee85a9 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include "bcma_private.h"
+#include <linux/pci.h>
 #include <linux/export.h>
 #include <linux/bcma/bcma.h>
 #include <asm/paccess.h>
index e820b68d2f6cd4d74382b85b5e020069294f00f3..acda773b3720878495d14f5ebfbe1a82f50c0f74 100644 (file)
@@ -866,6 +866,7 @@ cciss_scsi_detect(ctlr_info_t *h)
        sh->can_queue = cciss_tape_cmds;
        sh->sg_tablesize = h->maxsgentries;
        sh->max_cmd_len = MAX_COMMAND_SIZE;
+       sh->max_sectors = h->cciss_max_sectors;
 
        ((struct cciss_scsi_adapter_data_t *) 
                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 */
        if (request_nsgs > h->maxSG)
                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)
                c->Header.SGList = h->max_cmd_sgentries;
        else
index b5dd14e072f2859a1c81fc036ffafd2146cc754a..0ba837fc62a874511a910dd077feea2f26dfbd37 100644 (file)
@@ -4,6 +4,6 @@
 
 config BLK_DEV_PCIESSD_MTIP32XX
        tristate "Block Device Driver for Micron PCIe SSDs"
-       depends on HOTPLUG_PCI_PCIE
+       depends on PCI
        help
           This enables the block driver for Micron PCIe SSDs.
index 8eb81c96608fbc47aadc382015a0e44db2b4599a..00f9fc992090099e72e8f753ab9d58fe47154b46 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/idr.h>
 #include <linux/kthread.h>
 #include <../drivers/ata/ahci.h>
+#include <linux/export.h>
 #include "mtip32xx.h"
 
 #define HW_CMD_SLOT_SZ         (MTIP_MAX_COMMAND_SLOTS * 32)
@@ -44,6 +45,7 @@
 #define HW_PORT_PRIV_DMA_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 HSORG_DISABLE_SLOTGRP_INTR (1<<24)
 #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;
        struct mtip_cmd *command;
        struct mtip_port *port = dd->port;
+       static int in_progress;
+
+       if (in_progress)
+               return;
+
+       in_progress = 1;
 
        for (group = 0; group < 4; group++) {
                for (commandslot = 0; commandslot < 32; commandslot++) {
@@ -165,7 +173,8 @@ static void mtip_command_cleanup(struct driver_data *dd)
 
        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))
                mdelay(1);
 
+       if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))
+               return -1;
+
        if (readl(dd->mmio + HOST_CTL) & HOST_RESET)
                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)]);
 
        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]);
 
        /* 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 */
        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))
                ;
 
+       if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+               return;
+
        /*
         * Chip quirk: escalate to hba reset if
         * 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))
                ;
 
+       if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+               return;
+
        /* Clear PxSCTL.DET */
        writel(readl(port->mmio + PORT_SCR_CTL) & ~1,
                         port->mmio + PORT_SCR_CTL);
@@ -486,15 +513,35 @@ static void mtip_restart_port(struct mtip_port *port)
                         && 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)
                dev_warn(&port->dd->pdev->dev,
                        "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;
        unsigned int bit, group;
        unsigned int num_command_slots = port->dd->slot_groups * 32;
+       unsigned long to, tagaccum[SLOTBITS_IN_LONGS];
 
        if (unlikely(!port))
                return;
 
-       if (atomic_read(&port->dd->resumeflag) == true) {
+       if (test_bit(MTIP_DDF_RESUME_BIT, &port->dd->dd_flag)) {
                mod_timer(&port->cmd_timer,
                        jiffies + msecs_to_jiffies(30000));
                return;
        }
+       /* clear the tag accumulator */
+       memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
 
        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];
                        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++;
                        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
@@ -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);
-               clear_bit(MTIP_FLAG_EH_ACTIVE_BIT, &port->flags);
+               clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
                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 */
        mod_timer(&port->cmd_timer,
                jiffies + msecs_to_jiffies(MTIP_TIMEOUT_CHECK_PERIOD));
@@ -681,23 +743,18 @@ static void mtip_completion(struct mtip_port *port,
        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.
  *
@@ -708,12 +765,16 @@ static void print_tags(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_cmd  *command;
+       struct mtip_cmd  *cmd;
        u32 completed;
        struct host_to_dev_fis *fis;
        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");
 
@@ -722,8 +783,11 @@ static void mtip_handle_tfe(struct driver_data *dd)
        /* Stop the timer to prevent command timeouts. */
        del_timer(&port->cmd_timer);
 
+       /* clear the tag accumulator */
+       memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
+
        /* 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 */
        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.*/
                writel(completed, port->completed[group]);
 
-               /* clear the tag accumulator */
-               memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
-
                /* Process successfully completed commands */
                for (bit = 0; bit < 32 && completed; bit++) {
                        if (!(completed & (1<<bit)))
@@ -745,13 +806,14 @@ static void mtip_handle_tfe(struct driver_data *dd)
                        if (tag == MTIP_TAG_INTERNAL)
                                continue;
 
-                       command = &port->commands[tag];
-                       if (likely(command->comp_func)) {
+                       cmd = &port->commands[tag];
+                       if (likely(cmd->comp_func)) {
                                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,
-                                        command->comp_data,
+                                        cmd->comp_data,
                                         0);
                        } else {
                                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 */
        mdelay(20);
        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 */
        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++) {
                        reissue = 1;
                        tag = (group << 5) + bit;
+                       cmd = &port->commands[tag];
 
                        /* 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;
 
-                       fis = (struct host_to_dev_fis *)
-                               port->commands[tag].command;
+                       fis = (struct host_to_dev_fis *)cmd->command;
 
                        /* Should re-issue? */
                        if (tag == MTIP_TAG_INTERNAL ||
                            fis->command == ATA_CMD_SET_FEATURES)
                                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
                         *  exceeded its retries.
                         */
-                       if (reissue &&
-                           (port->commands[tag].retries-- > 0)) {
+                       if (reissue && (cmd->retries-- > 0)) {
 
                                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. */
                                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 */
                        dev_warn(&port->dd->pdev->dev,
                                "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,
                                        tag,
-                                       port->commands[tag].comp_data,
+                                       cmd->comp_data,
                                        PORT_IRQ_TF_ERR);
                        else
                                dev_warn(&port->dd->pdev->dev,
@@ -828,10 +938,10 @@ static void mtip_handle_tfe(struct driver_data *dd)
                                        tag);
                }
        }
-       print_tags(dd, "TFE tags reissued:", tagaccum);
+       print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt);
 
        /* 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);
 
        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_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])
                & (1 << MTIP_TAG_INTERNAL))) {
                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;
 }
 
@@ -968,6 +1076,9 @@ static inline irqreturn_t mtip_handle_irq(struct driver_data *data)
                                /* don't proceed further */
                                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);
                }
@@ -1015,6 +1126,39 @@ static void mtip_issue_non_ncq_command(struct mtip_port *port, int 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
  *
@@ -1033,11 +1177,13 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout)
 
        to = jiffies + msecs_to_jiffies(timeout);
        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);
                        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.
                 * 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.
  */
 static int mtip_exec_internal_command(struct mtip_port *port,
-                                       void *fis,
+                                       struct host_to_dev_fis *fis,
                                        int fis_len,
                                        dma_addr_t buffer,
                                        int buf_len,
@@ -1084,8 +1230,9 @@ static int mtip_exec_internal_command(struct mtip_port *port,
 {
        struct mtip_cmd_sg *command_sg;
        DECLARE_COMPLETION_ONSTACK(wait);
-       int rv = 0;
+       int rv = 0, ready2go = 1;
        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. */
        if (buffer & 0x00000007) {
@@ -1094,23 +1241,38 @@ static int mtip_exec_internal_command(struct mtip_port *port,
                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,
-                       "Internal command already active\n");
+                       "Internal cmd active. new cmd [%02X]\n", fis->command);
                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) {
-               /* 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. */
@@ -1120,7 +1282,7 @@ static int mtip_exec_internal_command(struct mtip_port *port,
        } else {
                /* Clear completion - we're going to poll */
                int_cmd->comp_data = NULL;
-               int_cmd->comp_func = NULL;
+               int_cmd->comp_func = mtip_null_completion;
        }
 
        /* 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] "
                                "within timeout of  %lu ms\n",
                                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;
                }
 
@@ -1166,31 +1334,59 @@ static int mtip_exec_internal_command(struct mtip_port *port,
                        & (1 << MTIP_TAG_INTERNAL)) {
                        dev_warn(&port->dd->pdev->dev,
                                "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 {
                /* Spin for <timeout> checking if command still outstanding */
                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])
                        & (1 << MTIP_TAG_INTERNAL)) {
                        dev_err(&port->dd->pdev->dev,
-                               "Internal command did not complete [%d]\n",
-                               atomic);
+                               "Internal command did not complete [atomic]\n");
                        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. */
        atomic_set(&int_cmd->active, 0);
        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);
 
        return rv;
@@ -1240,6 +1436,9 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer)
        int rv = 0;
        struct host_to_dev_fis fis;
 
+       if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag))
+               return -EFAULT;
+
        /* Build the FIS. */
        memset(&fis, 0, sizeof(struct host_to_dev_fis));
        fis.type        = 0x27;
@@ -1313,6 +1512,7 @@ static int mtip_standby_immediate(struct mtip_port *port)
 {
        int rv;
        struct host_to_dev_fis  fis;
+       unsigned long start;
 
        /* Build the 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.command     = ATA_CMD_STANDBYNOW1;
 
-       /* Execute the command.  Use a 15-second timeout for large drives. */
+       start = jiffies;
        rv = mtip_exec_internal_command(port,
                                        &fis,
                                        5,
                                        0,
                                        0,
                                        0,
-                                       GFP_KERNEL,
+                                       GFP_ATOMIC,
                                        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;
 }
@@ -1504,10 +1839,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command)
        fis.cyl_hi      = command[5];
        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__,
                command[0],
                command[1],
@@ -1534,8 +1866,7 @@ static int exec_drive_task(struct mtip_port *port, u8 *command)
        command[4] = reply->cyl_low;
        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__,
                command[0],
                command[1],
@@ -1578,7 +1909,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command,
        }
 
        dbg_printk(MTIP_DRV_NAME
-               "%s: User Command: cmd %x, sect %x, "
+               " %s: User Command: cmd %x, sect %x, "
                "feat %x, sectcnt %x\n",
                __func__,
                command[0],
@@ -1607,7 +1938,7 @@ static int exec_drive_command(struct mtip_port *port, u8 *command,
        command[2] = command[3];
 
        dbg_printk(MTIP_DRV_NAME
-               "%s: Completion Status: stat %x, "
+               " %s: Completion Status: stat %x, "
                "err %x, cmd %x\n",
                __func__,
                command[0],
@@ -1810,9 +2141,10 @@ static int exec_drive_taskfile(struct driver_data *dd,
        }
 
        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,"
                " head/dev %x\n",
+               __func__,
                fis.command,
                fis.features,
                fis.sect_count,
@@ -1823,8 +2155,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
 
        switch (fis.command) {
        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;
        case ATA_CMD_SEC_ERASE_UNIT:
                /* Change timeout for Security Erase Unit to 4 minutes.*/
@@ -1840,8 +2172,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
                timeout = 10000;
                break;
        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;
        default:
                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[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
-               "%s: Completion: stat %x,"
+               " %s: Completion: stat %x,"
                "err %x, sect_cnt %x, lbalo %x,"
                "lbamid %x, lbahi %x, dev %x\n",
                __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 mtip_port *port = dd->port;
        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 */
-       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;
 
@@ -2127,7 +2445,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
         */
        command->comp_data = dd;
        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
@@ -2140,19 +2458,16 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
         * To prevent this command from being issued
         * 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(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags);
+               set_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags);
                return;
        }
 
        /* Issue the command to the hardware */
        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);
        *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))
                return NULL;
 
@@ -2207,7 +2526,7 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd,
  * return value
  *     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,
                                char *buf)
 {
@@ -2216,7 +2535,7 @@ static ssize_t hw_show_registers(struct device *dev,
        int size = 0;
        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++)
                size += sprintf(&buf[size], "0x%08x\n",
@@ -2240,20 +2559,39 @@ static ssize_t hw_show_registers(struct device *dev,
                                 group_allocated);
        }
 
-       size += sprintf(&buf[size], "completed:\n");
+       size += sprintf(&buf[size], "Completed:\n");
 
        for (n = 0; n < dd->slot_groups; n++)
                size += sprintf(&buf[size], "0x%08x\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));
-       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));
 
        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.
@@ -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))
                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;
 }
 
@@ -2292,6 +2633,7 @@ static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj)
                return -EINVAL;
 
        sysfs_remove_file(kobj, &dev_attr_registers.attr);
+       sysfs_remove_file(kobj, &dev_attr_status.attr);
 
        return 0;
 }
@@ -2384,10 +2726,12 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd)
                "FTL rebuild in progress. Polling for completion.\n");
 
        start = jiffies;
-       dd->ftlrebuildflag = 1;
        timeout = jiffies + msecs_to_jiffies(MTIP_FTL_REBUILD_TIMEOUT_MS);
 
        do {
+               if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
+                               &dd->dd_flag)))
+                       return -EFAULT;
                if (mtip_check_surprise_removal(dd->pdev))
                        return -EFAULT;
 
@@ -2408,22 +2752,17 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd)
                        dev_warn(&dd->pdev->dev,
                                "FTL rebuild complete (%d secs).\n",
                        jiffies_to_msecs(jiffies - start) / 1000);
-                       dd->ftlrebuildflag = 0;
                        mtip_block_initialize(dd);
-                       break;
+                       return 0;
                }
                ssleep(10);
        } while (time_before(jiffies, 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",
                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
                 */
                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())
                        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;
                        /* used to restrict the loop to one iteration */
                        slot_start = num_cmd_slots;
@@ -2480,21 +2822,19 @@ static int mtip_service_thread(void *data)
                                /* Issue the command to the hardware */
                                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(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;
        }
        return 0;
@@ -2513,6 +2853,9 @@ static int mtip_hw_init(struct driver_data *dd)
        int i;
        int rv;
        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];
 
@@ -2547,7 +2890,7 @@ static int mtip_hw_init(struct driver_data *dd)
        /* Allocate memory for the command list. */
        dd->port->command_list =
                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,
                        GFP_KERNEL);
        if (!dd->port->command_list) {
@@ -2560,7 +2903,7 @@ static int mtip_hw_init(struct driver_data *dd)
        /* Clear the memory we have allocated. */
        memset(dd->port->command_list,
                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. */
        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 +
                                        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_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. */
        for (i = 0; i < num_command_slots; i++) {
                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;
        }
 
-       /* 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;
        }
 
+       /* 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_start_port(dd->port);
 
@@ -2660,6 +3041,12 @@ static int mtip_hw_init(struct driver_data *dd)
        mod_timer(&dd->port->cmd_timer,
                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) {
                rv = -EFAULT;
                goto out3;
@@ -2667,10 +3054,47 @@ static int mtip_hw_init(struct driver_data *dd)
 
        if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) ==
                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;
        }
        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;
 
 out3:
@@ -2688,7 +3112,7 @@ out2:
 
        /* Free the command/command header memory. */
        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_dma);
 out1:
@@ -2712,9 +3136,12 @@ static int mtip_hw_exit(struct driver_data *dd)
         * Send standby immediate (E0h) to the drive so that it
         * 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. */
                mtip_deinit_port(dd->port);
@@ -2734,7 +3161,7 @@ static int mtip_hw_exit(struct driver_data *dd)
 
        /* Free the command/command header memory. */
        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_dma);
        /* Free the memory allocated for the for structure. */
@@ -2892,6 +3319,9 @@ static int mtip_block_ioctl(struct block_device *dev,
        if (!dd)
                return -ENOTTY;
 
+       if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)))
+               return -ENOTTY;
+
        switch (cmd) {
        case BLKFLSBUF:
                return -ENOTTY;
@@ -2927,6 +3357,9 @@ static int mtip_block_compat_ioctl(struct block_device *dev,
        if (!dd)
                return -ENOTTY;
 
+       if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)))
+               return -ENOTTY;
+
        switch (cmd) {
        case BLKFLSBUF:
                return -ENOTTY;
@@ -3049,6 +3482,24 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
        int nents = 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))) {
                blk_queue_flush(queue, 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)) {
                        dev_warn(&dd->pdev->dev,
-                               "Maximum number of SGL entries exceeded");
+                               "Maximum number of SGL entries exceeded\n");
                        bio_io_error(bio);
                        mtip_hw_release_scatterlist(dd, tag);
                        return;
@@ -3210,8 +3661,10 @@ skip_create_disk:
                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 */
+       }
 
 start_service_thread:
        sprintf(thd_name, "mtip_svc_thd_%02d", index);
@@ -3220,12 +3673,15 @@ start_service_thread:
                                                dd, thd_name);
 
        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;
                rv = -EFAULT;
                goto kthread_run_error;
        }
 
+       if (wait_for_rebuild == MTIP_FTL_REBUILD_MAGIC)
+               rv = wait_for_rebuild;
+
        return rv;
 
 kthread_run_error:
@@ -3266,16 +3722,18 @@ static int mtip_block_remove(struct driver_data *dd)
        struct kobject *kobj;
 
        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);
                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
         */
        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);
        dd->disk  = 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. */
        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);
        dd->disk  = NULL;
        dd->queue = NULL;
@@ -3359,11 +3827,6 @@ static int mtip_pci_probe(struct pci_dev *pdev,
                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.  */
        pci_set_drvdata(pdev, dd);
 
@@ -3420,7 +3883,8 @@ static int mtip_pci_probe(struct pci_dev *pdev,
         * instance number.
         */
        instance++;
-
+       if (rv != MTIP_FTL_REBUILD_MAGIC)
+               set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag);
        goto done;
 
 block_initialize_err:
@@ -3434,9 +3898,6 @@ iomap_err:
        pci_set_drvdata(pdev, NULL);
        return rv;
 done:
-       /* Set the atomic variable as 0 in case of SRSI */
-       atomic_set(&dd->drv_cleanup_done, true);
-
        return rv;
 }
 
@@ -3452,8 +3913,10 @@ static void mtip_pci_remove(struct pci_dev *pdev)
        struct driver_data *dd = pci_get_drvdata(pdev);
        int counter = 0;
 
+       set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag);
+
        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++;
                        msleep(20);
                        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. */
        mtip_block_remove(dd);
@@ -3493,7 +3954,7 @@ static int mtip_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
                return -EFAULT;
        }
 
-       atomic_set(&dd->resumeflag, true);
+       set_bit(MTIP_DDF_RESUME_BIT, &dd->dd_flag);
 
        /* Disable ports & interrupts then send standby immediate */
        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");
 
 err:
-       atomic_set(&dd->resumeflag, false);
+       clear_bit(MTIP_DDF_RESUME_BIT, &dd->dd_flag);
 
        return rv;
 }
@@ -3608,18 +4069,25 @@ MODULE_DEVICE_TABLE(pci, mtip_pci_tbl);
  */
 static int __init mtip_init(void)
 {
+       int error;
+
        printk(KERN_INFO MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n");
 
        /* 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",
-               mtip_major);
+               error);
                return -EBUSY;
        }
+       mtip_major = error;
 
        /* 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;
 }
 
 /*
index e0554a8f2233faf85c8f98409fdf83c9cdd5cae7..4ef58336310a126af9b4d0847dc4099e4af23610 100644 (file)
@@ -34,8 +34,8 @@
 /* offset of Device Control register in PCIe extended capabilites space */
 #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 */
 #define MTIP_NCQ_COMMAND_TIMEOUT_MS       5000
 #define __force_bit2int (unsigned int __force)
 
 /* 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. */
 struct host_to_dev_fis {
@@ -345,6 +374,12 @@ struct mtip_port {
         * when the command slot and all associated data structures
         * 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];
        /*
         * 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.
         */
        struct timer_list cmd_timer;
+       unsigned long ic_pause_timer;
        /*
         * Semaphore used to block threads if there are no
         * command slots available.
@@ -404,13 +440,9 @@ struct driver_data {
 
        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 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 */
 };
index c4a60badf252caee7bffff38cc0cf115d0bd81a4..0e4ef3de9d5deb6fab10c5ef0fb5678ec610a3be 100644 (file)
@@ -351,6 +351,7 @@ static void virtblk_config_changed_work(struct work_struct *work)
                  cap_str_10, cap_str_2);
 
        set_capacity(vblk->disk, capacity);
+       revalidate_disk(vblk->disk);
 done:
        mutex_unlock(&vblk->config_lock);
 }
index 0088bf60f3689db6a704c1856c4f94a682d7db44..73f196ca713f20e037e22adccba64d0e00c936b1 100644 (file)
@@ -321,6 +321,7 @@ struct seg_buf {
 static void xen_blkbk_unmap(struct pending_req *req)
 {
        struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+       struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];
        unsigned int i, invcount = 0;
        grant_handle_t handle;
        int ret;
@@ -332,25 +333,12 @@ static void xen_blkbk_unmap(struct pending_req *req)
                gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i),
                                    GNTMAP_host_map, handle);
                pending_handle(req, i) = BLKBACK_INVALID_HANDLE;
+               pages[invcount] = virt_to_page(vaddr(req, i));
                invcount++;
        }
 
-       ret = HYPERVISOR_grant_table_op(
-               GNTTABOP_unmap_grant_ref, unmap, invcount);
+       ret = gnttab_unmap_refs(unmap, pages, invcount, false);
        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,
@@ -378,7 +366,7 @@ static int xen_blkbk_map(struct blkif_request *req,
                                  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);
 
        /*
@@ -398,15 +386,6 @@ static int xen_blkbk_map(struct blkif_request *req,
                if (ret)
                        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 |
                        (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 status = BLKIF_RSP_OKAY;
        struct block_device *bdev = blkif->vbd.bdev;
+       unsigned long secure;
 
        blkif->st_ds_req++;
 
        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) {
                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 rc = 0;
 
-       if (!xen_pv_domain())
+       if (!xen_domain())
                return -ENODEV;
 
        blkbk = kzalloc(sizeof(struct xen_blkbk), GFP_KERNEL);
index d0ee7edc9be8ad1819a91a491eb907f18d545fbf..773cf27dc23fc595d6fca48ea8ec6c4992438d18 100644 (file)
@@ -146,11 +146,6 @@ enum blkif_protocol {
        BLKIF_PROTOCOL_X86_64 = 3,
 };
 
-enum blkif_backend_type {
-       BLKIF_BACKEND_PHY  = 1,
-       BLKIF_BACKEND_FILE = 2,
-};
-
 struct xen_vbd {
        /* What the domain refers to this vbd as. */
        blkif_vdev_t            handle;
@@ -177,7 +172,6 @@ struct xen_blkif {
        unsigned int            irq;
        /* Comms information. */
        enum blkif_protocol     blk_protocol;
-       enum blkif_backend_type blk_backend_type;
        union blkif_back_rings  blk_rings;
        void                    *blk_ring;
        /* The VBD attached to this interface. */
index 24a2fb57e5d012d57c5d3e1fc1929f27ac3998ee..89860f34a7ece7c890f3f45925e8dd8cd613d912 100644 (file)
@@ -381,72 +381,49 @@ int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt,
        err = xenbus_printf(xbt, dev->nodename, "feature-flush-cache",
                            "%d", state);
        if (err)
-               xenbus_dev_fatal(dev, err, "writing feature-flush-cache");
+               dev_warn(&dev->dev, "writing feature-flush-cache (%d)", err);
 
        return err;
 }
 
-int xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be)
+static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info *be)
 {
        struct xenbus_device *dev = be->dev;
        struct xen_blkif *blkif = be->blkif;
-       char *type;
        int err;
        int state = 0;
+       struct block_device *bdev = be->blkif->vbd.bdev;
+       struct request_queue *q = bdev_get_queue(bdev);
 
-       type = xenbus_read(XBT_NIL, dev->nodename, "type", NULL);
-       if (!IS_ERR(type)) {
-               if (strncmp(type, "file", 4) == 0) {
-                       state = 1;
-                       blkif->blk_backend_type = BLKIF_BACKEND_FILE;
+       if (blk_queue_discard(q)) {
+               err = xenbus_printf(xbt, dev->nodename,
+                       "discard-granularity", "%u",
+                       q->limits.discard_granularity);
+               if (err) {
+                       dev_warn(&dev->dev, "writing discard-granularity (%d)", err);
+                       return;
                }
-               if (strncmp(type, "phy", 3) == 0) {
-                       struct block_device *bdev = be->blkif->vbd.bdev;
-                       struct request_queue *q = bdev_get_queue(bdev);
-                       if (blk_queue_discard(q)) {
-                               err = xenbus_printf(xbt, dev->nodename,
-                                       "discard-granularity", "%u",
-                                       q->limits.discard_granularity);
-                               if (err) {
-                                       xenbus_dev_fatal(dev, err,
-                                               "writing discard-granularity");
-                                       goto kfree;
-                               }
-                               err = xenbus_printf(xbt, dev->nodename,
-                                       "discard-alignment", "%u",
-                                       q->limits.discard_alignment);
-                               if (err) {
-                                       xenbus_dev_fatal(dev, err,
-                                               "writing discard-alignment");
-                                       goto kfree;
-                               }
-                               state = 1;
-                               blkif->blk_backend_type = BLKIF_BACKEND_PHY;
-                       }
-                       /* Optional. */
-                       err = xenbus_printf(xbt, dev->nodename,
-                               "discard-secure", "%d",
-                               blkif->vbd.discard_secure);
-                       if (err) {
-                               xenbus_dev_fatal(dev, err,
-                                       "writting discard-secure");
-                               goto kfree;
-                       }
+               err = xenbus_printf(xbt, dev->nodename,
+                       "discard-alignment", "%u",
+                       q->limits.discard_alignment);
+               if (err) {
+                       dev_warn(&dev->dev, "writing discard-alignment (%d)", err);
+                       return;
+               }
+               state = 1;
+               /* Optional. */
+               err = xenbus_printf(xbt, dev->nodename,
+                                   "discard-secure", "%d",
+                                   blkif->vbd.discard_secure);
+               if (err) {
+                       dev_warn(dev-dev, "writing discard-secure (%d)", err);
+                       return;
                }
-       } else {
-               err = PTR_ERR(type);
-               xenbus_dev_fatal(dev, err, "reading type");
-               goto out;
        }
-
        err = xenbus_printf(xbt, dev->nodename, "feature-discard",
                            "%d", state);
        if (err)
-               xenbus_dev_fatal(dev, err, "writing feature-discard");
-kfree:
-       kfree(type);
-out:
-       return err;
+               dev_warn(&dev->dev, "writing feature-discard (%d)", err);
 }
 int xen_blkbk_barrier(struct xenbus_transaction xbt,
                      struct backend_info *be, int state)
@@ -457,7 +434,7 @@ int xen_blkbk_barrier(struct xenbus_transaction xbt,
        err = xenbus_printf(xbt, dev->nodename, "feature-barrier",
                            "%d", state);
        if (err)
-               xenbus_dev_fatal(dev, err, "writing feature-barrier");
+               dev_warn(&dev->dev, "writing feature-barrier (%d)", err);
 
        return err;
 }
@@ -689,14 +666,12 @@ again:
                return;
        }
 
-       err = xen_blkbk_flush_diskcache(xbt, be, be->blkif->vbd.flush_support);
-       if (err)
-               goto abort;
+       /* If we can't advertise it is OK. */
+       xen_blkbk_flush_diskcache(xbt, be, be->blkif->vbd.flush_support);
 
-       err = xen_blkbk_discard(xbt, be);
+       xen_blkbk_discard(xbt, be);
 
-       /* If we can't advertise it is OK. */
-       err = xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support);
+       xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support);
 
        err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu",
                            (unsigned long long)vbd_sz(&be->blkif->vbd));
index 98cbeba8cd5358ca026b2e4b692a4aa55704c739..4e86393a09cf5c880917fd81d3e67e507a83c0f6 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/scatterlist.h>
+#include <linux/bitmap.h>
 
 #include <xen/xen.h>
 #include <xen/xenbus.h>
@@ -81,6 +82,7 @@ static const struct block_device_operations xlvbd_block_fops;
  */
 struct blkfront_info
 {
+       spinlock_t io_lock;
        struct mutex mutex;
        struct xenbus_device *xbdev;
        struct gendisk *gd;
@@ -105,8 +107,6 @@ struct blkfront_info
        int is_ready;
 };
 
-static DEFINE_SPINLOCK(blkif_io_lock);
-
 static unsigned int nr_minors;
 static unsigned long *minors;
 static DEFINE_SPINLOCK(minor_lock);
@@ -177,8 +177,7 @@ static int xlbd_reserve_minors(unsigned int minor, unsigned int nr)
 
        spin_lock(&minor_lock);
        if (find_next_bit(minors, end, minor) >= end) {
-               for (; minor < end; ++minor)
-                       __set_bit(minor, minors);
+               bitmap_set(minors, minor, nr);
                rc = 0;
        } else
                rc = -EBUSY;
@@ -193,8 +192,7 @@ static void xlbd_release_minors(unsigned int minor, unsigned int nr)
 
        BUG_ON(end > nr_minors);
        spin_lock(&minor_lock);
-       for (; minor < end; ++minor)
-               __clear_bit(minor, minors);
+       bitmap_clear(minors,  minor, nr);
        spin_unlock(&minor_lock);
 }
 
@@ -419,7 +417,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
        struct request_queue *rq;
        struct blkfront_info *info = gd->private_data;
 
-       rq = blk_init_queue(do_blkif_request, &blkif_io_lock);
+       rq = blk_init_queue(do_blkif_request, &info->io_lock);
        if (rq == NULL)
                return -1;
 
@@ -636,14 +634,14 @@ static void xlvbd_release_gendisk(struct blkfront_info *info)
        if (info->rq == NULL)
                return;
 
-       spin_lock_irqsave(&blkif_io_lock, flags);
+       spin_lock_irqsave(&info->io_lock, flags);
 
        /* No more blkif_request(). */
        blk_stop_queue(info->rq);
 
        /* No more gnttab callback work. */
        gnttab_cancel_free_callback(&info->callback);
-       spin_unlock_irqrestore(&blkif_io_lock, flags);
+       spin_unlock_irqrestore(&info->io_lock, flags);
 
        /* Flush gnttab callback work. Must be done with no locks held. */
        flush_work_sync(&info->work);
@@ -675,16 +673,16 @@ static void blkif_restart_queue(struct work_struct *work)
 {
        struct blkfront_info *info = container_of(work, struct blkfront_info, work);
 
-       spin_lock_irq(&blkif_io_lock);
+       spin_lock_irq(&info->io_lock);
        if (info->connected == BLKIF_STATE_CONNECTED)
                kick_pending_request_queues(info);
-       spin_unlock_irq(&blkif_io_lock);
+       spin_unlock_irq(&info->io_lock);
 }
 
 static void blkif_free(struct blkfront_info *info, int suspend)
 {
        /* Prevent new requests being issued until we fix things up. */
-       spin_lock_irq(&blkif_io_lock);
+       spin_lock_irq(&info->io_lock);
        info->connected = suspend ?
                BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
        /* No more blkif_request(). */
@@ -692,7 +690,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
                blk_stop_queue(info->rq);
        /* No more gnttab callback work. */
        gnttab_cancel_free_callback(&info->callback);
-       spin_unlock_irq(&blkif_io_lock);
+       spin_unlock_irq(&info->io_lock);
 
        /* Flush gnttab callback work. Must be done with no locks held. */
        flush_work_sync(&info->work);
@@ -728,10 +726,10 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
        struct blkfront_info *info = (struct blkfront_info *)dev_id;
        int error;
 
-       spin_lock_irqsave(&blkif_io_lock, flags);
+       spin_lock_irqsave(&info->io_lock, flags);
 
        if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) {
-               spin_unlock_irqrestore(&blkif_io_lock, flags);
+               spin_unlock_irqrestore(&info->io_lock, flags);
                return IRQ_HANDLED;
        }
 
@@ -816,7 +814,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
 
        kick_pending_request_queues(info);
 
-       spin_unlock_irqrestore(&blkif_io_lock, flags);
+       spin_unlock_irqrestore(&info->io_lock, flags);
 
        return IRQ_HANDLED;
 }
@@ -991,6 +989,7 @@ static int blkfront_probe(struct xenbus_device *dev,
        }
 
        mutex_init(&info->mutex);
+       spin_lock_init(&info->io_lock);
        info->xbdev = dev;
        info->vdevice = vdevice;
        info->connected = BLKIF_STATE_DISCONNECTED;
@@ -1068,7 +1067,7 @@ static int blkif_recover(struct blkfront_info *info)
 
        xenbus_switch_state(info->xbdev, XenbusStateConnected);
 
-       spin_lock_irq(&blkif_io_lock);
+       spin_lock_irq(&info->io_lock);
 
        /* Now safe for us to use the shared ring */
        info->connected = BLKIF_STATE_CONNECTED;
@@ -1079,7 +1078,7 @@ static int blkif_recover(struct blkfront_info *info)
        /* Kick any other new requests queued since we resumed */
        kick_pending_request_queues(info);
 
-       spin_unlock_irq(&blkif_io_lock);
+       spin_unlock_irq(&info->io_lock);
 
        return 0;
 }
@@ -1277,10 +1276,10 @@ static void blkfront_connect(struct blkfront_info *info)
        xenbus_switch_state(info->xbdev, XenbusStateConnected);
 
        /* Kick pending requests. */
-       spin_lock_irq(&blkif_io_lock);
+       spin_lock_irq(&info->io_lock);
        info->connected = BLKIF_STATE_CONNECTED;
        kick_pending_request_queues(info);
-       spin_unlock_irq(&blkif_io_lock);
+       spin_unlock_irq(&info->io_lock);
 
        add_disk(info->gd);
 
@@ -1410,7 +1409,6 @@ static int blkif_release(struct gendisk *disk, fmode_t mode)
        mutex_lock(&blkfront_mutex);
 
        bdev = bdget_disk(disk, 0);
-       bdput(bdev);
 
        if (bdev->bd_openers)
                goto out;
@@ -1441,6 +1439,7 @@ static int blkif_release(struct gendisk *disk, fmode_t mode)
        }
 
 out:
+       bdput(bdev);
        mutex_unlock(&blkfront_mutex);
        return 0;
 }
index 48442476ec005415ec0d51c79c48e305ed31fb69..ae9edca7b56dc474a140c8f0eb579f556dc8e308 100644 (file)
@@ -72,7 +72,9 @@ static struct usb_device_id ath3k_table[] = {
 
        /* Atheros AR3012 with sflash firmware*/
        { USB_DEVICE(0x0CF3, 0x3004) },
+       { USB_DEVICE(0x0CF3, 0x311D) },
        { USB_DEVICE(0x13d3, 0x3375) },
+       { USB_DEVICE(0x04CA, 0x3005) },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE02C) },
@@ -89,7 +91,9 @@ static struct usb_device_id ath3k_blist_tbl[] = {
 
        /* Atheros AR3012 with sflash firmware*/
        { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
 
        { }     /* Terminating entry */
 };
index 480cad9200481fb0ad2eb9a91c5b9b55d2dea5c5..3311b812a0c68a37c9728c7bef3af2c050af587b 100644 (file)
@@ -61,7 +61,7 @@ static struct usb_device_id btusb_table[] = {
        { USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
 
        /* Broadcom SoftSailing reporting vendor specific */
-       { USB_DEVICE(0x05ac, 0x21e1) },
+       { USB_DEVICE(0x0a5c, 0x21e1) },
 
        /* Apple MacBookPro 7,1 */
        { USB_DEVICE(0x05ac, 0x8213) },
@@ -103,6 +103,7 @@ static struct usb_device_id btusb_table[] = {
        /* Broadcom BCM20702A0 */
        { USB_DEVICE(0x0a5c, 0x21e3) },
        { USB_DEVICE(0x0a5c, 0x21e6) },
+       { USB_DEVICE(0x0a5c, 0x21e8) },
        { USB_DEVICE(0x0a5c, 0x21f3) },
        { USB_DEVICE(0x413c, 0x8197) },
 
@@ -129,7 +130,9 @@ static struct usb_device_id blacklist_table[] = {
 
        /* Atheros 3012 with sflash firmware */
        { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
index fd5adb408f447a4a08b9dbece913e111d3fe9906..98a8c05d4f23a038dfa020cd98930c9d52283844 100644 (file)
@@ -299,11 +299,11 @@ static void hci_uart_tty_close(struct tty_struct *tty)
                        hci_uart_close(hdev);
 
                if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
-                       hu->proto->close(hu);
                        if (hdev) {
                                hci_unregister_dev(hdev);
                                hci_free_dev(hdev);
                        }
+                       hu->proto->close(hu);
                }
 
                kfree(hu);
index 3845ab44c3304e1d2e4ce0f8bfc7455cd5ef6717..dfd7876f127c0d23c9d45bc2922ccefe85ff3181 100644 (file)
@@ -906,8 +906,8 @@ int hpet_alloc(struct hpet_data *hdp)
                hpetp->hp_which, hdp->hd_phys_address,
                hpetp->hp_ntimer > 1 ? "s" : "");
        for (i = 0; i < hpetp->hp_ntimer; i++)
-               printk("%s %d", i > 0 ? "," : "", hdp->hd_irq[i]);
-       printk("\n");
+               printk(KERN_CONT "%s %d", i > 0 ? "," : "", hdp->hd_irq[i]);
+       printk(KERN_CONT "\n");
 
        temp = hpetp->hp_tick_freq;
        remainder = do_div(temp, 1000000);
index 54ca8b23cde3f1aa5550d2806087300227531070..4ec04a754733baed5dd8595256a9c7998965d323 100644 (file)
@@ -1260,10 +1260,15 @@ static int proc_do_uuid(ctl_table *table, int write,
        uuid = table->data;
        if (!uuid) {
                uuid = tmp_uuid;
-               uuid[8] = 0;
-       }
-       if (uuid[8] == 0)
                generate_random_uuid(uuid);
+       } else {
+               static DEFINE_SPINLOCK(bootid_spinlock);
+
+               spin_lock(&bootid_spinlock);
+               if (!uuid[8])
+                       generate_random_uuid(uuid);
+               spin_unlock(&bootid_spinlock);
+       }
 
        sprintf(buf, "%pU", uuid);
 
index 82e882028fcf2172e7a1faaf5aec0f125238a952..6b5cf02c35c88147970c69cd19048650bff7610d 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
-#include <linux/async.h>
 #include <asm/io.h>
 
 /*
@@ -180,15 +179,17 @@ static int verify_pmtmr_rate(void)
 /* Number of reads we try to get two different values */
 #define ACPI_PM_READ_CHECKS 10000
 
-static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie)
+static int __init init_acpi_pm_clocksource(void)
 {
        cycle_t value1, value2;
        unsigned int i, j = 0;
 
+       if (!pmtmr_ioport)
+               return -ENODEV;
 
        /* "verify" this timing source: */
        for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
-               usleep_range(100 * j, 100 * j + 100);
+               udelay(100 * j);
                value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
                for (i = 0; i < ACPI_PM_READ_CHECKS; i++) {
                        value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
@@ -202,34 +203,25 @@ static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie
                               " 0x%#llx, 0x%#llx - aborting.\n",
                               value1, value2);
                        pmtmr_ioport = 0;
-                       return;
+                       return -EINVAL;
                }
                if (i == ACPI_PM_READ_CHECKS) {
                        printk(KERN_INFO "PM-Timer failed consistency check "
                               " (0x%#llx) - aborting.\n", value1);
                        pmtmr_ioport = 0;
-                       return;
+                       return -ENODEV;
                }
        }
 
        if (verify_pmtmr_rate() != 0){
                pmtmr_ioport = 0;
-               return;
+               return -ENODEV;
        }
 
-       clocksource_register_hz(&clocksource_acpi_pm,
+       return clocksource_register_hz(&clocksource_acpi_pm,
                                                PMTMR_TICKS_PER_SEC);
 }
 
-static int __init init_acpi_pm_clocksource(void)
-{
-       if (!pmtmr_ioport)
-               return -ENODEV;
-
-       async_schedule(acpi_pm_clocksource_async, NULL);
-       return 0;
-}
-
 /* We use fs_initcall because we want the PCI fixups to have run
  * but we still need to load before device_initcall
  */
index ffbb446859152e232f48099c8e57b8797502ed76..5961e6415f082a54e4a29a0980d48857a724cc7c 100644 (file)
@@ -4,6 +4,7 @@
 
 config ARM_OMAP2PLUS_CPUFREQ
        bool "TI OMAP2+"
+       depends on ARCH_OMAP2PLUS
        default ARCH_OMAP2PLUS
        select CPU_FREQ_TABLE
 
index 767bcc31b3653b7813a9acbde71f2fcd1f3a0130..2397f6f451b15ccb274d367c9955cefa27c56013 100644 (file)
@@ -332,6 +332,20 @@ struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type)
 }
 EXPORT_SYMBOL(dma_find_channel);
 
+/*
+ * net_dma_find_channel - find a channel for net_dma
+ * net_dma has alignment requirements
+ */
+struct dma_chan *net_dma_find_channel(void)
+{
+       struct dma_chan *chan = dma_find_channel(DMA_MEMCPY);
+       if (chan && !is_dma_copy_aligned(chan->device, 1, 1, 1))
+               return NULL;
+
+       return chan;
+}
+EXPORT_SYMBOL(net_dma_find_channel);
+
 /**
  * dma_issue_pending_all - flush all pending operations across all channels
  */
index 31493d80e0e9dd0538546703317dbf60abe2247e..73b2b65cb1deed2ccfb16d5f3e81dbeaa47f7ec1 100644 (file)
@@ -546,9 +546,9 @@ void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags,
                           PCI_DMA_TODEVICE, flags, 0);
 }
 
-unsigned long ioat_get_current_completion(struct ioat_chan_common *chan)
+dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan)
 {
-       unsigned long phys_complete;
+       dma_addr_t phys_complete;
        u64 completion;
 
        completion = *chan->completion;
@@ -569,7 +569,7 @@ unsigned long ioat_get_current_completion(struct ioat_chan_common *chan)
 }
 
 bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
-                          unsigned long *phys_complete)
+                          dma_addr_t *phys_complete)
 {
        *phys_complete = ioat_get_current_completion(chan);
        if (*phys_complete == chan->last_completion)
@@ -580,14 +580,14 @@ bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
        return true;
 }
 
-static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete)
+static void __cleanup(struct ioat_dma_chan *ioat, dma_addr_t phys_complete)
 {
        struct ioat_chan_common *chan = &ioat->base;
        struct list_head *_desc, *n;
        struct dma_async_tx_descriptor *tx;
 
-       dev_dbg(to_dev(chan), "%s: phys_complete: %lx\n",
-                __func__, phys_complete);
+       dev_dbg(to_dev(chan), "%s: phys_complete: %llx\n",
+                __func__, (unsigned long long) phys_complete);
        list_for_each_safe(_desc, n, &ioat->used_desc) {
                struct ioat_desc_sw *desc;
 
@@ -652,7 +652,7 @@ static void __cleanup(struct ioat_dma_chan *ioat, unsigned long phys_complete)
 static void ioat1_cleanup(struct ioat_dma_chan *ioat)
 {
        struct ioat_chan_common *chan = &ioat->base;
-       unsigned long phys_complete;
+       dma_addr_t phys_complete;
 
        prefetch(chan->completion);
 
@@ -698,7 +698,7 @@ static void ioat1_timer_event(unsigned long data)
                mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT);
                spin_unlock_bh(&ioat->desc_lock);
        } else if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) {
-               unsigned long phys_complete;
+               dma_addr_t phys_complete;
 
                spin_lock_bh(&ioat->desc_lock);
                /* if we haven't made progress and we have already
index c7888bccd9740c6cefba7719c1e33cc724a7152d..5e8fe01ba69d574c3eef5cf0cb8f3ab765fb7c72 100644 (file)
@@ -88,7 +88,7 @@ struct ioatdma_device {
 struct ioat_chan_common {
        struct dma_chan common;
        void __iomem *reg_base;
-       unsigned long last_completion;
+       dma_addr_t last_completion;
        spinlock_t cleanup_lock;
        unsigned long state;
        #define IOAT_COMPLETION_PENDING 0
@@ -310,7 +310,7 @@ int __devinit ioat_dma_self_test(struct ioatdma_device *device);
 void __devexit ioat_dma_remove(struct ioatdma_device *device);
 struct dca_provider * __devinit ioat_dca_init(struct pci_dev *pdev,
                                              void __iomem *iobase);
-unsigned long ioat_get_current_completion(struct ioat_chan_common *chan);