Merge branch 'for-3.10/drivers' of git://git.kernel.dk/linux-block
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 8 May 2013 18:51:05 +0000 (11:51 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 8 May 2013 18:51:05 +0000 (11:51 -0700)
Pull block driver updates from Jens Axboe:
 "It might look big in volume, but when categorized, not a lot of
  drivers are touched.  The pull request contains:

   - mtip32xx fixes from Micron.

   - A slew of drbd updates, this time in a nicer series.

   - bcache, a flash/ssd caching framework from Kent.

   - Fixes for cciss"

* 'for-3.10/drivers' of git://git.kernel.dk/linux-block: (66 commits)
  bcache: Use bd_link_disk_holder()
  bcache: Allocator cleanup/fixes
  cciss: bug fix to prevent cciss from loading in kdump crash kernel
  cciss: add cciss_allow_hpsa module parameter
  drivers/block/mg_disk.c: add CONFIG_PM_SLEEP to suspend/resume functions
  mtip32xx: Workaround for unaligned writes
  bcache: Make sure blocksize isn't smaller than device blocksize
  bcache: Fix merge_bvec_fn usage for when it modifies the bvm
  bcache: Correctly check against BIO_MAX_PAGES
  bcache: Hack around stuff that clones up to bi_max_vecs
  bcache: Set ra_pages based on backing device's ra_pages
  bcache: Take data offset from the bdev superblock.
  mtip32xx: mtip32xx: Disable TRIM support
  mtip32xx: fix a smatch warning
  bcache: Disable broken btree fuzz tester
  bcache: Fix a format string overflow
  bcache: Fix a minor memory leak on device teardown
  bcache: Documentation updates
  bcache: Use WARN_ONCE() instead of __WARN()
  bcache: Add missing #include <linux/prefetch.h>
  ...

14 files changed:
1  2 
MAINTAINERS
drivers/block/aoe/aoecmd.c
drivers/block/cciss.c
drivers/block/drbd/drbd_main.c
drivers/block/drbd/drbd_proc.c
drivers/block/drbd/drbd_receiver.c
drivers/block/mg_disk.c
drivers/block/mtip32xx/mtip32xx.c
drivers/block/mtip32xx/mtip32xx.h
include/linux/idr.h
include/linux/sched.h
kernel/fork.c
kernel/lockdep.c
kernel/trace/blktrace.c

diff --combined MAINTAINERS
@@@ -90,9 -90,6 +90,9 @@@ Descriptions of section entries
           F:   drivers/net/*   all files in drivers/net, but not below
           F:   */net/*         all files in "any top level directory"/net
           One pattern per line.  Multiple F: lines acceptable.
 +      N: Files and directories with regex patterns.
 +         N:   [^a-z]tegra     all files whose path contains the word tegra
 +         One pattern per line.  Multiple N: lines acceptable.
        X: Files and directories that are NOT maintained, same rules as F:
           Files exclusions are tested before file matches.
           Can be useful for excluding a specific subdirectory, for instance:
           X:   net/ipv6/
           matches all files in and below net excluding net/ipv6/
        K: Keyword perl extended regex pattern to match content in a
 -         patch or file, or an affected filename.  For instance:
 +         patch or file.  For instance:
           K: of_get_profile
 -            matches patch or file content, or filenames, that contain
 -            "of_get_profile"
 +            matches patches or files that contain "of_get_profile"
           K: \b(printk|pr_(info|err))\b
 -            matches patch or file content, or filenames, that contain one or
 -            more of the words printk, pr_info or pr_err
 +            matches patches or files that contain one or more of the words
 +            printk, pr_info or pr_err
           One regex pattern per line.  Multiple K: lines acceptable.
  
  Note: For the hard of thinking, this list is meant to remain in alphabetical
@@@ -801,7 -799,6 +801,7 @@@ S: Maintaine
  F:    arch/arm/mach-prima2/
  F:    drivers/dma/sirf-dma.c
  F:    drivers/i2c/busses/i2c-sirf.c
 +F:    drivers/mmc/host/sdhci-sirf.c
  F:    drivers/pinctrl/pinctrl-sirf.c
  F:    drivers/spi/spi-sirf.c
  
@@@ -1034,7 -1031,6 +1034,7 @@@ F:      drivers/mmc/host/msm_sdcc.
  F:    drivers/tty/serial/msm_serial.h
  F:    drivers/tty/serial/msm_serial.c
  F:    drivers/*/pm8???-*
 +F:    drivers/ssbi/
  F:    include/linux/mfd/pm8xxx/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/davidb/linux-msm.git
  S:    Maintained
@@@ -1342,6 -1338,12 +1342,6 @@@ S:     Maintaine
  F:    drivers/platform/x86/asus*.c
  F:    drivers/platform/x86/eeepc*.c
  
 -ASUS ASB100 HARDWARE MONITOR DRIVER
 -M:    "Mark M. Hoffman" <mhoffman@lightlink.com>
 -L:    lm-sensors@lm-sensors.org
 -S:    Maintained
 -F:    drivers/hwmon/asb100.c
 -
  ASYNCHRONOUS TRANSFERS/TRANSFORMS (IOAT) API
  M:    Dan Williams <djbw@fb.com>
  W:    http://sourceforge.net/projects/xscaleiop
@@@ -1465,12 -1467,6 +1465,12 @@@ F:    drivers/dma/at_hdmac.
  F:    drivers/dma/at_hdmac_regs.h
  F:    include/linux/platform_data/dma-atmel.h
  
 +ATMEL I2C DRIVER
 +M:    Ludovic Desroches <ludovic.desroches@atmel.com>
 +L:    linux-i2c@vger.kernel.org
 +S:    Supported
 +F:    drivers/i2c/busses/i2c-at91.c
 +
  ATMEL ISI DRIVER
  M:    Josh Wu <josh.wu@atmel.com>
  L:    linux-media@vger.kernel.org
@@@ -1620,6 -1616,13 +1620,13 @@@ W:    http://www.baycom.org/~tom/ham/ham.h
  S:    Maintained
  F:    drivers/net/hamradio/baycom*
  
+ BCACHE (BLOCK LAYER CACHE)
+ M:    Kent Overstreet <koverstreet@google.com>
+ L:    linux-bcache@vger.kernel.org
+ W:    http://bcache.evilpiepirate.org
+ S:    Maintained:
+ F:    drivers/md/bcache/
  BEFS FILE SYSTEM
  S:    Orphan
  F:    Documentation/filesystems/befs.txt
@@@ -1768,7 -1771,7 +1775,7 @@@ F:      arch/arm/configs/bcm2835_defconfi
  F:    drivers/*/*bcm2835*
  
  BROADCOM TG3 GIGABIT ETHERNET DRIVER
 -M:    Matt Carlson <mcarlson@broadcom.com>
 +M:    Nithin Nayak Sujir <nsujir@broadcom.com>
  M:    Michael Chan <mchan@broadcom.com>
  L:    netdev@vger.kernel.org
  S:    Supported
@@@ -1890,7 -1893,7 +1897,7 @@@ F:      Documentation/video4linux/cafe_cci
  F:    drivers/media/platform/marvell-ccic/
  
  CAIF NETWORK LAYER
 -M:    Sjur Braendeland <sjur.brandeland@stericsson.com>
 +M:    Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
  L:    netdev@vger.kernel.org
  S:    Supported
  F:    Documentation/networking/caif/
@@@ -2204,34 -2207,12 +2211,34 @@@ F:   drivers/net/ethernet/ti/cpmac.
  
  CPU FREQUENCY DRIVERS
  M:    Rafael J. Wysocki <rjw@sisk.pl>
 +M:    Viresh Kumar <viresh.kumar@linaro.org>
  L:    cpufreq@vger.kernel.org
  L:    linux-pm@vger.kernel.org
  S:    Maintained
 +T:    git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
  F:    drivers/cpufreq/
  F:    include/linux/cpufreq.h
  
 +CPU FREQUENCY DRIVERS - ARM BIG LITTLE
 +M:    Viresh Kumar <viresh.kumar@linaro.org>
 +M:    Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
 +L:    cpufreq@vger.kernel.org
 +L:    linux-pm@vger.kernel.org
 +W:    http://www.arm.com/products/processors/technologies/biglittleprocessing.php
 +S:    Maintained
 +F:    drivers/cpufreq/arm_big_little.h
 +F:    drivers/cpufreq/arm_big_little.c
 +F:    drivers/cpufreq/arm_big_little_dt.c
 +
 +CPUIDLE DRIVERS
 +M:    Rafael J. Wysocki <rjw@sisk.pl>
 +M:    Daniel Lezcano <daniel.lezcano@linaro.org>
 +L:    linux-pm@vger.kernel.org
 +S:    Maintained
 +T:    git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
 +F:    drivers/cpuidle/*
 +F:    include/linux/cpuidle.h
 +
  CPUID/MSR DRIVER
  M:    "H. Peter Anvin" <hpa@zytor.com>
  S:    Maintained
@@@ -2310,7 -2291,7 +2317,7 @@@ L:      linux-media@vger.kernel.or
  T:    git git://linuxtv.org/media_tree.git
  W:    http://linuxtv.org
  S:    Maintained
 -F:    drivers/media/i2c/cx2341x*
 +F:    drivers/media/common/cx2341x*
  F:    include/media/cx2341x*
  
  CX88 VIDEO4LINUX DRIVER
@@@ -2393,16 -2374,6 +2400,16 @@@ W:    http://www.cyclades.com
  S:    Orphan
  F:    drivers/net/wan/pc300*
  
 +CYPRESS_FIRMWARE MEDIA DRIVER
 +M:    Antti Palosaari <crope@iki.fi>
 +L:    linux-media@vger.kernel.org
 +W:    http://linuxtv.org/
 +W:    http://palosaari.fi/linux/
 +Q:    http://patchwork.linuxtv.org/project/linux-media/list/
 +T:    git git://linuxtv.org/anttip/media_tree.git
 +S:    Maintained
 +F:    drivers/media/common/cypress_firmware*
 +
  CYTTSP TOUCHSCREEN DRIVER
  M:    Javier Martinez Canillas <javier@dowhile0.org>
  L:    linux-input@vger.kernel.org
@@@ -2477,7 -2448,9 +2484,7 @@@ S:      Maintaine
  F:    drivers/platform/x86/dell-laptop.c
  
  DELL LAPTOP SMM DRIVER
 -M:    Massimo Dal Zotto <dz@debian.org>
 -W:    http://www.debian.org/~dz/i8k/
 -S:    Maintained
 +S:    Orphan
  F:    drivers/char/i8k.c
  F:    include/uapi/linux/i8k.h
  
@@@ -2492,12 -2465,6 +2499,12 @@@ M:    Matthew Garrett <mjg59@srcf.ucam.org
  S:    Maintained
  F:    drivers/platform/x86/dell-wmi.c
  
 +DESIGNWARE USB2 DRD IP DRIVER
 +M:    Paul Zimmerman <paulz@synopsys.com>
 +L:    linux-usb@vger.kernel.org
 +S:    Maintained
 +F:    drivers/staging/dwc2/
 +
  DESIGNWARE USB3 DRD IP DRIVER
  M:    Felipe Balbi <balbi@ti.com>
  L:    linux-usb@vger.kernel.org
@@@ -2669,7 -2636,7 +2676,7 @@@ F:      include/uapi/drm
  
  INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
  M:    Daniel Vetter <daniel.vetter@ffwll.ch>
 -L:    intel-gfx@lists.freedesktop.org (subscribers-only)
 +L:    intel-gfx@lists.freedesktop.org
  L:    dri-devel@lists.freedesktop.org
  T:    git git://people.freedesktop.org/~danvet/drm-intel
  S:    Supported
@@@ -2771,7 -2738,7 +2778,7 @@@ T:      git git://linuxtv.org/media_tree.gi
  S:    Maintained
  F:    drivers/media/usb/dvb-usb/cxusb*
  
 -DVB_USB_CYPRESS_FIRMWARE MEDIA DRIVER
 +DVB_USB_EC168 MEDIA DRIVER
  M:    Antti Palosaari <crope@iki.fi>
  L:    linux-media@vger.kernel.org
  W:    http://linuxtv.org/
@@@ -2779,16 -2746,17 +2786,16 @@@ W:   http://palosaari.fi/linux
  Q:    http://patchwork.linuxtv.org/project/linux-media/list/
  T:    git git://linuxtv.org/anttip/media_tree.git
  S:    Maintained
 -F:    drivers/media/usb/dvb-usb-v2/cypress_firmware*
 +F:    drivers/media/usb/dvb-usb-v2/ec168*
  
 -DVB_USB_EC168 MEDIA DRIVER
 +DVB_USB_GL861 MEDIA DRIVER
  M:    Antti Palosaari <crope@iki.fi>
  L:    linux-media@vger.kernel.org
  W:    http://linuxtv.org/
 -W:    http://palosaari.fi/linux/
  Q:    http://patchwork.linuxtv.org/project/linux-media/list/
  T:    git git://linuxtv.org/anttip/media_tree.git
  S:    Maintained
 -F:    drivers/media/usb/dvb-usb-v2/ec168*
 +F:    drivers/media/usb/dvb-usb-v2/gl861*
  
  DVB_USB_MXL111SF MEDIA DRIVER
  M:    Michael Krufky <mkrufky@linuxtv.org>
@@@ -3026,18 -2994,9 +3033,18 @@@ F:    arch/ia64/kernel/efi.
  F:    arch/x86/boot/compressed/eboot.[ch]
  F:    arch/x86/include/asm/efi.h
  F:    arch/x86/platform/efi/*
 -F:    drivers/firmware/efivars.c
 +F:    drivers/firmware/efi/*
  F:    include/linux/efi*.h
  
 +EFI VARIABLE FILESYSTEM
 +M:    Matthew Garrett <matthew.garrett@nebula.com>
 +M:    Jeremy Kerr <jk@ozlabs.org>
 +M:    Matt Fleming <matt.fleming@intel.com>
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
 +L:    linux-efi@vger.kernel.org
 +S:    Maintained
 +F:    fs/efivarfs/
 +
  EFIFB FRAMEBUFFER DRIVER
  L:    linux-fbdev@vger.kernel.org
  M:    Peter Jones <pjones@redhat.com>
@@@ -3290,12 -3249,6 +3297,12 @@@ F:    Documentation/firmware_class
  F:    drivers/base/firmware*.c
  F:    include/linux/firmware.h
  
 +FLASHSYSTEM DRIVER (IBM FlashSystem 70/80 PCI SSD Flash Card)
 +M:    Joshua Morris <josh.h.morris@us.ibm.com>
 +M:    Philip Kelleher <pjk1939@linux.vnet.ibm.com>
 +S:    Maintained
 +F:    drivers/block/rsxx/
 +
  FLOPPY DRIVER
  M:    Jiri Kosina <jkosina@suse.cz>
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/floppy.git
@@@ -3556,7 -3509,7 +3563,7 @@@ F:      drivers/isdn/gigaset
  F:    include/uapi/linux/gigaset_dev.h
  
  GPIO SUBSYSTEM
 -M:    Grant Likely <grant.likely@secretlab.ca>
 +M:    Grant Likely <grant.likely@linaro.org>
  M:    Linus Walleij <linus.walleij@linaro.org>
  S:    Maintained
  T:    git git://git.secretlab.ca/git/linux-2.6.git
@@@ -3641,14 -3594,6 +3648,14 @@@ W:    http://www.kernel.org/pub/linux/kern
  S:    Maintained
  F:    drivers/platform/x86/hdaps.c
  
 +HDPVR USB VIDEO ENCODER DRIVER
 +M:    Hans Verkuil <hverkuil@xs4all.nl>
 +L:    linux-media@vger.kernel.org
 +T:    git git://linuxtv.org/media_tree.git
 +W:    http://linuxtv.org
 +S:    Odd Fixes
 +F:    drivers/media/usb/hdpvr
 +
  HWPOISON MEMORY FAILURE HANDLING
  M:    Andi Kleen <andi@firstfloor.org>
  L:    linux-mm@kvack.org
@@@ -3913,13 -3858,14 +3920,13 @@@ F:   drivers/i2c/busses/i2c-ismt.
  F:    Documentation/i2c/busses/i2c-ismt
  
  I2C/SMBUS STUB DRIVER
 -M:    "Mark M. Hoffman" <mhoffman@lightlink.com>
 +M:    Jean Delvare <khali@linux-fr.org>
  L:    linux-i2c@vger.kernel.org
  S:    Maintained
  F:    drivers/i2c/i2c-stub.c
  
  I2C SUBSYSTEM
  M:    Wolfram Sang <wsa@the-dreams.de>
 -M:    "Ben Dooks (embedded platforms)" <ben-linux@fluff.org>
  L:    linux-i2c@vger.kernel.org
  W:    http://i2c.wiki.kernel.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git
@@@ -4396,7 -4342,7 +4403,7 @@@ F:      drivers/irqchip
  
  IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
  M:    Benjamin Herrenschmidt <benh@kernel.crashing.org>
 -M:    Grant Likely <grant.likely@secretlab.ca>
 +M:    Grant Likely <grant.likely@linaro.org>
  T:    git git://git.secretlab.ca/git/linux-2.6.git irqdomain/next
  S:    Maintained
  F:    Documentation/IRQ-domain.txt
@@@ -4477,16 -4423,6 +4484,16 @@@ Q:    http://patchwork.linuxtv.org/project
  S:    Maintained
  F:    drivers/media/dvb-frontends/it913x-fe*
  
 +IT913X MEDIA DRIVER
 +M:    Antti Palosaari <crope@iki.fi>
 +L:    linux-media@vger.kernel.org
 +W:    http://linuxtv.org/
 +W:    http://palosaari.fi/linux/
 +Q:    http://patchwork.linuxtv.org/project/linux-media/list/
 +T:    git git://linuxtv.org/anttip/media_tree.git
 +S:    Maintained
 +F:    drivers/media/tuners/it913x*
 +
  IVTV VIDEO4LINUX DRIVER
  M:    Andy Walls <awalls@md.metrocast.net>
  L:    ivtv-devel@ivtvdriver.org (moderated for non-subscribers)
@@@ -4893,8 -4829,11 +4900,8 @@@ F:     arch/powerpc/platforms/40x
  F:    arch/powerpc/platforms/44x/
  
  LINUX FOR POWERPC EMBEDDED XILINX VIRTEX
 -M:    Grant Likely <grant.likely@secretlab.ca>
 -W:    http://wiki.secretlab.ca/index.php/Linux_on_Xilinx_Virtex
  L:    linuxppc-dev@lists.ozlabs.org
 -T:    git git://git.secretlab.ca/git/linux-2.6.git
 -S:    Maintained
 +S:    Unmaintained
  F:    arch/powerpc/*/*virtex*
  F:    arch/powerpc/*/*/*virtex*
  
@@@ -5003,12 -4942,6 +5010,12 @@@ W:    logfs.or
  S:    Maintained
  F:    fs/logfs/
  
 +LPC32XX MACHINE SUPPORT
 +M:    Roland Stigge <stigge@antcom.de>
 +L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 +S:    Maintained
 +F:    arch/arm/mach-lpc32xx/
 +
  LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
  M:    Nagalakshmi Nandigama <Nagalakshmi.Nandigama@lsi.com>
  M:    Sreekanth Reddy <Sreekanth.Reddy@lsi.com>
@@@ -5133,8 -5066,9 +5140,8 @@@ S:      Maintaine
  F:    drivers/net/ethernet/marvell/sk*
  
  MARVELL LIBERTAS WIRELESS DRIVER
 -M:    Dan Williams <dcbw@redhat.com>
  L:    libertas-dev@lists.infradead.org
 -S:    Maintained
 +S:    Orphan
  F:    drivers/net/wireless/libertas/
  
  MARVELL MV643XX ETHERNET DRIVER
@@@ -5474,13 -5408,6 +5481,13 @@@ L:    linux-scsi@vger.kernel.or
  S:    Maintained
  F:    drivers/scsi/NCR_D700.*
  
 +NCT6775 HARDWARE MONITOR DRIVER
 +M:    Guenter Roeck <linux@roeck-us.net>
 +L:    lm-sensors@lm-sensors.org
 +S:    Maintained
 +F:    Documentation/hwmon/nct6775
 +F:    drivers/hwmon/nct6775.c
 +
  NETEFFECT IWARP RNIC DRIVER (IW_NES)
  M:    Faisal Latif <faisal.latif@intel.com>
  L:    linux-rdma@vger.kernel.org
@@@ -5643,7 -5570,6 +5650,7 @@@ F:      include/uapi/linux/if_
  F:    include/uapi/linux/netdevice.h
  
  NETXEN (1/10) GbE SUPPORT
 +M:    Manish Chopra <manish.chopra@qlogic.com>
  M:    Sony Chacko <sony.chacko@qlogic.com>
  M:    Rajesh Borundia <rajesh.borundia@qlogic.com>
  L:    netdev@vger.kernel.org
@@@ -5728,14 -5654,6 +5735,14 @@@ S:    Maintaine
  F:    drivers/video/riva/
  F:    drivers/video/nvidia/
  
 +NVM EXPRESS DRIVER
 +M:    Matthew Wilcox <willy@linux.intel.com>
 +L:    linux-nvme@lists.infradead.org
 +T:    git git://git.infradead.org/users/willy/linux-nvme.git
 +S:    Supported
 +F:    drivers/block/nvme.c
 +F:    include/linux/nvme.h
 +
  OMAP SUPPORT
  M:    Tony Lindgren <tony@atomide.com>
  L:    linux-omap@vger.kernel.org
@@@ -5764,7 -5682,7 +5771,7 @@@ S:      Maintaine
  F:    arch/arm/*omap*/*clock*
  
  OMAP POWER MANAGEMENT SUPPORT
 -M:    Kevin Hilman <khilman@ti.com>
 +M:    Kevin Hilman <khilman@deeprootsystems.com>
  L:    linux-omap@vger.kernel.org
  S:    Maintained
  F:    arch/arm/*omap*/*pm*
@@@ -5858,7 -5776,7 +5865,7 @@@ F:      arch/arm/*omap*/usb
  
  OMAP GPIO DRIVER
  M:    Santosh Shilimkar <santosh.shilimkar@ti.com>
 -M:    Kevin Hilman <khilman@ti.com>
 +M:    Kevin Hilman <khilman@deeprootsystems.com>
  L:    linux-omap@vger.kernel.org
  S:    Maintained
  F:    drivers/gpio/gpio-omap.c
@@@ -5912,7 -5830,7 +5919,7 @@@ F:      Documentation/i2c/busses/i2c-ocore
  F:    drivers/i2c/busses/i2c-ocores.c
  
  OPEN FIRMWARE AND FLATTENED DEVICE TREE
 -M:    Grant Likely <grant.likely@secretlab.ca>
 +M:    Grant Likely <grant.likely@linaro.org>
  M:    Rob Herring <rob.herring@calxeda.com>
  L:    devicetree-discuss@lists.ozlabs.org (moderated for non-subscribers)
  W:    http://fdt.secretlab.ca
@@@ -6267,7 -6185,7 +6274,7 @@@ S:      Supporte
  F:    drivers/scsi/pmcraid.*
  
  PMC SIERRA PM8001 DRIVER
 -M:    jack_wang@usish.com
 +M:    xjtuwjp@gmail.com
  M:    lindar_liu@usish.com
  L:    linux-scsi@vger.kernel.org
  S:    Supported
@@@ -6290,7 -6208,7 +6297,7 @@@ F:      include/linux/power_supply.
  F:    drivers/power/
  
  PNP SUPPORT
 -M:    Adam Belay <abelay@mit.edu>
 +M:    Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  M:    Bjorn Helgaas <bhelgaas@google.com>
  S:    Maintained
  F:    drivers/pnp/
@@@ -6400,12 -6318,11 +6407,12 @@@ S:   Maintaine
  T:    git git://git.infradead.org/users/cbou/linux-pstore.git
  F:    fs/pstore/
  F:    include/linux/pstore*
 -F:    drivers/firmware/efivars.c
 +F:    drivers/firmware/efi/efi-pstore.c
  F:    drivers/acpi/apei/erst.c
  
  PTP HARDWARE CLOCK SUPPORT
  M:    Richard Cochran <richardcochran@gmail.com>
 +L:    netdev@vger.kernel.org
  S:    Maintained
  W:    http://linuxptp.sourceforge.net/
  F:    Documentation/ABI/testing/sysfs-ptp
@@@ -6537,7 -6454,6 +6544,7 @@@ S:      Supporte
  F:    drivers/net/ethernet/qlogic/qlcnic/
  
  QLOGIC QLGE 10Gb ETHERNET DRIVER
 +M:    Shahed Shaikh <shahed.shaikh@qlogic.com>
  M:    Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
  M:    Ron Mercer <ron.mercer@qlogic.com>
  M:    linux-driver@qlogic.com
@@@ -6634,6 -6550,12 +6641,6 @@@ S:     Maintaine
  F:    Documentation/blockdev/ramdisk.txt
  F:    drivers/block/brd.c
  
 -RAMSAM DRIVER (IBM RamSan 70/80 PCI SSD Flash Card)
 -M:    Joshua Morris <josh.h.morris@us.ibm.com>
 -M:    Philip Kelleher <pjk1939@linux.vnet.ibm.com>
 -S:    Maintained
 -F:    drivers/block/rsxx/
 -
  RANDOM NUMBER DRIVER
  M:    Theodore Ts'o" <tytso@mit.edu>
  S:    Maintained
@@@ -6702,7 -6624,7 +6709,7 @@@ S:      Supporte
  F:    fs/reiserfs/
  
  REGISTER MAP ABSTRACTION
 -M:    Mark Brown <broonie@opensource.wolfsonmicro.com>
 +M:    Mark Brown <broonie@kernel.org>
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git
  S:    Supported
  F:    drivers/base/regmap/
@@@ -6716,14 -6638,6 +6723,14 @@@ F:    drivers/remoteproc
  F:    Documentation/remoteproc.txt
  F:    include/linux/remoteproc.h
  
 +REMOTE PROCESSOR MESSAGING (RPMSG) SUBSYSTEM
 +M:    Ohad Ben-Cohen <ohad@wizery.com>
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/ohad/rpmsg.git
 +S:    Maintained
 +F:    drivers/rpmsg/
 +F:    Documentation/rpmsg.txt
 +F:    include/linux/rpmsg.h
 +
  RFKILL
  M:    Johannes Berg <johannes@sipsolutions.net>
  L:    linux-wireless@vger.kernel.org
@@@ -6771,16 -6685,6 +6778,16 @@@ T:    git git://linuxtv.org/anttip/media_t
  S:    Maintained
  F:    drivers/media/dvb-frontends/rtl2830*
  
 +RTL2832 MEDIA DRIVER
 +M:    Antti Palosaari <crope@iki.fi>
 +L:    linux-media@vger.kernel.org
 +W:    http://linuxtv.org/
 +W:    http://palosaari.fi/linux/
 +Q:    http://patchwork.linuxtv.org/project/linux-media/list/
 +T:    git git://linuxtv.org/anttip/media_tree.git
 +S:    Maintained
 +F:    drivers/media/dvb-frontends/rtl2832*
 +
  RTL8180 WIRELESS DRIVER
  M:    "John W. Linville" <linville@tuxdriver.com>
  L:    linux-wireless@vger.kernel.org
@@@ -6883,7 -6787,7 +6890,7 @@@ L:      linux-media@vger.kernel.or
  W:    http://linuxtv.org
  T:    git git://linuxtv.org/media_tree.git
  S:    Odd fixes
 -F:    Documentation/video4linux/saa7134/
 +F:    Documentation/video4linux/*.saa7134
  F:    drivers/media/pci/saa7134/
  
  SAA7146 VIDEO4LINUX-2 DRIVER
@@@ -6976,8 -6880,9 +6983,8 @@@ F:      drivers/clocksourc
  
  TLG2300 VIDEO4LINUX-2 DRIVER
  M:    Huang Shijie <shijie8@gmail.com>
 -M:    Kang Yong <kangyong@telegent.com>
 -M:    Zhang Xiaobing <xbzhang@telegent.com>
 -S:    Supported
 +M:    Hans Verkuil <hverkuil@xs4all.nl>
 +S:    Odd Fixes
  F:    drivers/media/usb/tlg2300
  
  SC1200 WDT DRIVER
@@@ -7045,6 -6950,7 +7052,6 @@@ F:      drivers/scsi/st
  
  SCTP PROTOCOL
  M:    Vlad Yasevich <vyasevich@gmail.com>
 -M:    Sridhar Samudrala <sri@us.ibm.com>
  M:    Neil Horman <nhorman@tuxdriver.com>
  L:    linux-sctp@vger.kernel.org
  W:    http://lksctp.sourceforge.net
@@@ -7148,9 -7054,9 +7155,9 @@@ F:      drivers/misc/phantom.
  F:    include/uapi/linux/phantom.h
  
  SERIAL ATA (SATA) SUBSYSTEM
 -M:    Jeff Garzik <jgarzik@pobox.com>
 +M:    Tejun Heo <tj@kernel.org>
  L:    linux-ide@vger.kernel.org
 -T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
  S:    Supported
  F:    drivers/ata/
  F:    include/linux/ata.h
@@@ -7223,43 -7129,17 +7230,43 @@@ F:   drivers/media/radio/si470x/radio-si4
  F:    drivers/media/radio/si470x/radio-si470x.h
  F:    drivers/media/radio/si470x/radio-si470x-usb.c
  
 +SI4713 FM RADIO TRANSMITTER I2C DRIVER
 +M:    Eduardo Valentin <edubezval@gmail.com>
 +L:    linux-media@vger.kernel.org
 +T:    git git://linuxtv.org/media_tree.git
 +W:    http://linuxtv.org
 +S:    Odd Fixes
 +F:    drivers/media/radio/si4713-i2c.?
 +
 +SI4713 FM RADIO TRANSMITTER PLATFORM DRIVER
 +M:    Eduardo Valentin <edubezval@gmail.com>
 +L:    linux-media@vger.kernel.org
 +T:    git git://linuxtv.org/media_tree.git
 +W:    http://linuxtv.org
 +S:    Odd Fixes
 +F:    drivers/media/radio/radio-si4713.h
 +
 +SIANO DVB DRIVER
 +M:    Mauro Carvalho Chehab <mchehab@redhat.com>
 +L:    linux-media@vger.kernel.org
 +W:    http://linuxtv.org
 +T:    git git://linuxtv.org/media_tree.git
 +S:    Odd fixes
 +F:    drivers/media/common/siano/
 +F:    drivers/media/dvb/siano/
 +F:    drivers/media/usb/siano/
 +F:    drivers/media/mmc/siano
 +
  SH_VEU V4L2 MEM2MEM DRIVER
  M:    Guennadi Liakhovetski <g.liakhovetski@gmx.de>
  L:    linux-media@vger.kernel.org
  S:    Maintained
  F:    drivers/media/platform/sh_veu.c
 -F:    include/media/sh_veu.h
  
  SH_VOU V4L2 OUTPUT DRIVER
  M:    Guennadi Liakhovetski <g.liakhovetski@gmx.de>
  L:    linux-media@vger.kernel.org
 -S:    Maintained
 +S:    Odd Fixes
  F:    drivers/media/platform/sh_vou.c
  F:    include/media/sh_vou.h
  
@@@ -7292,7 -7172,7 +7299,7 @@@ F:      arch/arm/mach-s3c2410/bast-irq.
  
  TI DAVINCI MACHINE SUPPORT
  M:    Sekhar Nori <nsekhar@ti.com>
 -M:    Kevin Hilman <khilman@ti.com>
 +M:    Kevin Hilman <khilman@deeprootsystems.com>
  L:    davinci-linux-open-source@linux.davincidsp.com (moderated for non-subscribers)
  T:    git git://gitorious.org/linux-davinci/linux-davinci.git
  Q:    http://patchwork.kernel.org/project/linux-davinci/list/
@@@ -7301,13 -7181,14 +7308,13 @@@ F:   arch/arm/mach-davinc
  F:    drivers/i2c/busses/i2c-davinci.c
  
  TI DAVINCI SERIES MEDIA DRIVER
 -M:    Manjunath Hadli <manjunath.hadli@ti.com>
 -M:    Prabhakar Lad <prabhakar.lad@ti.com>
 +M:    Lad, Prabhakar <prabhakar.csengg@gmail.com>
  L:    linux-media@vger.kernel.org
  L:    davinci-linux-open-source@linux.davincidsp.com (moderated for non-subscribers)
  W:    http://linuxtv.org/
  Q:    http://patchwork.linuxtv.org/project/linux-media/list/
  T:    git git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git
 -S:    Supported
 +S:    Maintained
  F:    drivers/media/platform/davinci/
  F:    include/media/davinci/
  
@@@ -7324,6 -7205,13 +7331,6 @@@ L:     netdev@vger.kernel.or
  S:    Maintained
  F:    drivers/net/ethernet/sis/sis900.*
  
 -SIS 96X I2C/SMBUS DRIVER
 -M:    "Mark M. Hoffman" <mhoffman@lightlink.com>
 -L:    linux-i2c@vger.kernel.org
 -S:    Maintained
 -F:    Documentation/i2c/busses/i2c-sis96x
 -F:    drivers/i2c/busses/i2c-sis96x.c
 -
  SIS FRAMEBUFFER DRIVER
  M:    Thomas Winischhofer <thomas@winischhofer.net>
  W:    http://www.winischhofer.net/linuxsisvga.shtml
@@@ -7401,7 -7289,7 +7408,7 @@@ F:      Documentation/hwmon/sch562
  F:    drivers/hwmon/sch5627.c
  
  SMSC47B397 HARDWARE MONITOR DRIVER
 -M:    "Mark M. Hoffman" <mhoffman@lightlink.com>
 +M:    Jean Delvare <khali@linux-fr.org>
  L:    lm-sensors@lm-sensors.org
  S:    Maintained
  F:    Documentation/hwmon/smsc47b397
@@@ -7492,7 -7380,7 +7499,7 @@@ F:      sound
  
  SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC)
  M:    Liam Girdwood <lgirdwood@gmail.com>
 -M:    Mark Brown <broonie@opensource.wolfsonmicro.com>
 +M:    Mark Brown <broonie@kernel.org>
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
  L:    alsa-devel@alsa-project.org (moderated for non-subscribers)
  W:    http://alsa-project.org/main/index.php/ASoC
@@@ -7580,11 -7468,11 +7587,11 @@@ S:   Maintaine
  F:    drivers/clk/spear/
  
  SPI SUBSYSTEM
 -M:    Grant Likely <grant.likely@secretlab.ca>
 -M:    Mark Brown <broonie@opensource.wolfsonmicro.com>
 +M:    Mark Brown <broonie@kernel.org>
 +M:    Grant Likely <grant.likely@linaro.org>
  L:    spi-devel-general@lists.sourceforge.net
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git
  Q:    http://patchwork.kernel.org/project/spi-devel-general/list/
 -T:    git git://git.secretlab.ca/git/linux-2.6.git
  S:    Maintained
  F:    Documentation/spi/
  F:    drivers/spi/
@@@ -7679,11 -7567,6 +7686,11 @@@ M:    David Täht <d@teklibre.com
  S:    Odd Fixes
  F:    drivers/staging/frontier/
  
 +STAGING - GO7007 MPEG CODEC
 +M:    Hans Verkuil <hans.verkuil@cisco.com>
 +S:    Maintained
 +F:    drivers/staging/media/go7007/
 +
  STAGING - INDUSTRIAL IO
  M:    Jonathan Cameron <jic23@cam.ac.uk>
  L:    linux-iio@vger.kernel.org
@@@ -7734,8 -7617,8 +7741,8 @@@ S:      Odd Fixe
  F:    drivers/staging/sm7xxfb/
  
  STAGING - SOFTLOGIC 6x10 MPEG CODEC
 -M:    Ben Collins <bcollins@bluecherry.net>
 -S:    Odd Fixes
 +M:    Ismael Luceno <ismael.luceno@corp.bluecherry.net>
 +S:    Supported
  F:    drivers/staging/media/solo6x10/
  
  STAGING - SPEAKUP CONSOLE SPEECH DRIVER
@@@ -7829,10 -7712,9 +7836,10 @@@ F:    include/linux/swiotlb.
  
  SYNOPSYS ARC ARCHITECTURE
  M:    Vineet Gupta <vgupta@synopsys.com>
 -L:    linux-snps-arc@vger.kernel.org
  S:    Supported
  F:    arch/arc/
 +F:    Documentation/devicetree/bindings/arc/
 +F:    drivers/tty/serial/arc-uart.c
  
  SYSV FILESYSTEM
  M:    Christoph Hellwig <hch@infradead.org>
@@@ -8000,7 -7882,7 +8007,7 @@@ L:      linux-tegra@vger.kernel.or
  Q:    http://patchwork.ozlabs.org/project/linux-tegra/list/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra.git
  S:    Supported
 -K:    (?i)[^a-z]tegra
 +N:    [^a-z]tegra
  
  TEHUTI ETHERNET DRIVER
  M:    Andy Gospodarek <andy@greyhouse.net>
@@@ -8043,12 -7925,6 +8050,12 @@@ T:    git git://repo.or.cz/linux-2.6/linux
  S:    Maintained
  F:    drivers/platform/x86/thinkpad_acpi.c
  
 +TI BANDGAP AND THERMAL DRIVER
 +M:    Eduardo Valentin <eduardo.valentin@ti.com>
 +L:    linux-pm@vger.kernel.org
 +S:    Maintained
 +F:    drivers/staging/omap-thermal/
 +
  TI FLASH MEDIA INTERFACE DRIVER
  M:    Alex Dubov <oakad@yahoo.com>
  S:    Maintained
@@@ -8486,10 -8362,9 +8493,10 @@@ S:    Maintaine
  F:    drivers/usb/serial/option.c
  
  USB PEGASUS DRIVER
 -M:    Petko Manolov <petkan@users.sourceforge.net>
 +M:    Petko Manolov <petkan@nucleusys.com>
  L:    linux-usb@vger.kernel.org
  L:    netdev@vger.kernel.org
 +T:    git git://git.code.sf.net/p/pegasus2/git
  W:    http://pegasus2.sourceforge.net/
  S:    Maintained
  F:    drivers/net/usb/pegasus.*
@@@ -8509,10 -8384,9 +8516,10 @@@ S:    Supporte
  F:    drivers/usb/class/usblp.c
  
  USB RTL8150 DRIVER
 -M:    Petko Manolov <petkan@users.sourceforge.net>
 +M:    Petko Manolov <petkan@nucleusys.com>
  L:    linux-usb@vger.kernel.org
  L:    netdev@vger.kernel.org
 +T:    git git://git.code.sf.net/p/pegasus2/git
  W:    http://pegasus2.sourceforge.net/
  S:    Maintained
  F:    drivers/net/usb/rtl8150.c
@@@ -8646,7 -8520,7 +8653,7 @@@ F:      drivers/usb/gadget/*uvc*.
  F:    drivers/usb/gadget/webcam.c
  
  USB WIRELESS RNDIS DRIVER (rndis_wlan)
 -M:    Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
 +M:    Jussi Kivilinna <jussi.kivilinna@iki.fi>
  L:    linux-wireless@vger.kernel.org
  S:    Maintained
  F:    drivers/net/wireless/rndis_wlan.c
@@@ -8751,7 -8625,6 +8758,7 @@@ F:      drivers/virtio
  F:    drivers/net/virtio_net.c
  F:    drivers/block/virtio_blk.c
  F:    include/linux/virtio_*.h
 +F:    include/uapi/linux/virtio_*.h
  
  VIRTIO HOST (VHOST)
  M:    "Michael S. Tsirkin" <mst@redhat.com>
@@@ -8839,8 -8712,8 +8846,8 @@@ F:      drivers/scsi/vmw_pvscsi.
  F:    drivers/scsi/vmw_pvscsi.h
  
  VOLTAGE AND CURRENT REGULATOR FRAMEWORK
 -M:    Liam Girdwood <lrg@ti.com>
 -M:    Mark Brown <broonie@opensource.wolfsonmicro.com>
 +M:    Liam Girdwood <lgirdwood@gmail.com>
 +M:    Mark Brown <broonie@kernel.org>
  W:    http://opensource.wolfsonmicro.com/node/15
  W:    http://www.slimlogic.co.uk/?p=48
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/lrg/regulator.git
@@@ -9103,7 -8976,9 +9110,7 @@@ S:      Maintaine
  F:    drivers/net/ethernet/xilinx/xilinx_axienet*
  
  XILINX SYSTEMACE DRIVER
 -M:    Grant Likely <grant.likely@secretlab.ca>
 -W:    http://www.secretlab.ca/
 -S:    Maintained
 +S:    Unmaintained
  F:    drivers/block/xsysace.c
  
  XILINX UARTLITE SERIAL DRIVER
@@@ -51,9 -51,8 +51,9 @@@ new_skb(ulong len
  {
        struct sk_buff *skb;
  
 -      skb = alloc_skb(len, GFP_ATOMIC);
 +      skb = alloc_skb(len + MAX_HEADER, GFP_ATOMIC);
        if (skb) {
 +              skb_reserve(skb, MAX_HEADER);
                skb_reset_mac_header(skb);
                skb_reset_network_header(skb);
                skb->protocol = __constant_htons(ETH_P_AOE);
@@@ -920,16 -919,14 +920,14 @@@ bio_pagedec(struct bio *bio
  static void
  bufinit(struct buf *buf, struct request *rq, struct bio *bio)
  {
-       struct bio_vec *bv;
        memset(buf, 0, sizeof(*buf));
        buf->rq = rq;
        buf->bio = bio;
        buf->resid = bio->bi_size;
        buf->sector = bio->bi_sector;
        bio_pageinc(bio);
-       buf->bv = bv = bio_iovec(bio);
-       buf->bv_resid = bv->bv_len;
 -      buf->bv = &bio->bi_io_vec[bio->bi_idx];
++      buf->bv = bio_iovec(bio);
+       buf->bv_resid = buf->bv->bv_len;
        WARN_ON(buf->bv_resid == 0);
  }
  
diff --combined drivers/block/cciss.c
@@@ -75,6 -75,12 +75,12 @@@ module_param(cciss_simple_mode, int, S_
  MODULE_PARM_DESC(cciss_simple_mode,
        "Use 'simple mode' rather than 'performant mode'");
  
+ static int cciss_allow_hpsa;
+ module_param(cciss_allow_hpsa, int, S_IRUGO|S_IWUSR);
+ MODULE_PARM_DESC(cciss_allow_hpsa,
+       "Prevent cciss driver from accessing hardware known to be "
+       " supported by the hpsa driver");
  static DEFINE_MUTEX(cciss_mutex);
  static struct proc_dir_entry *proc_cciss;
  
@@@ -161,7 -167,7 +167,7 @@@ static irqreturn_t do_cciss_intx(int ir
  static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id);
  static int cciss_open(struct block_device *bdev, fmode_t mode);
  static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode);
 -static int cciss_release(struct gendisk *disk, fmode_t mode);
 +static void cciss_release(struct gendisk *disk, fmode_t mode);
  static int do_ioctl(struct block_device *bdev, fmode_t mode,
                    unsigned int cmd, unsigned long arg);
  static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
@@@ -493,7 -499,7 +499,7 @@@ static int cciss_seq_open(struct inode 
        struct seq_file *seq = file->private_data;
  
        if (!ret)
 -              seq->private = PDE(inode)->data;
 +              seq->private = PDE_DATA(inode);
  
        return ret;
  }
@@@ -1123,7 -1129,7 +1129,7 @@@ static int cciss_unlocked_open(struct b
  /*
   * Close.  Sync first.
   */
 -static int cciss_release(struct gendisk *disk, fmode_t mode)
 +static void cciss_release(struct gendisk *disk, fmode_t mode)
  {
        ctlr_info_t *h;
        drive_info_struct *drv;
        drv->usage_count--;
        h->usage_count--;
        mutex_unlock(&cciss_mutex);
 -      return 0;
  }
  
  static int do_ioctl(struct block_device *bdev, fmode_t mode,
@@@ -4115,9 -4122,13 +4121,13 @@@ static int cciss_lookup_board_id(struc
        *board_id = ((subsystem_device_id << 16) & 0xffff0000) |
                        subsystem_vendor_id;
  
-       for (i = 0; i < ARRAY_SIZE(products); i++)
+       for (i = 0; i < ARRAY_SIZE(products); i++) {
+               /* Stand aside for hpsa driver on request */
+               if (cciss_allow_hpsa)
+                       return -ENODEV;
                if (*board_id == products[i].board_id)
                        return i;
+       }
        dev_warn(&pdev->dev, "unrecognized board ID: 0x%08x, ignoring.\n",
                *board_id);
        return -ENODEV;
@@@ -4205,7 -4216,7 +4215,7 @@@ static int cciss_find_cfgtables(ctlr_in
        if (rc)
                return rc;
        h->cfgtable = remap_pci_mem(pci_resource_start(h->pdev,
 -              cfg_base_addr_index) + cfg_offset, sizeof(h->cfgtable));
 +              cfg_base_addr_index) + cfg_offset, sizeof(*h->cfgtable));
        if (!h->cfgtable)
                return -ENOMEM;
        rc = write_driver_ver_to_cfgtable(h->cfgtable);
@@@ -4959,6 -4970,16 +4969,16 @@@ static int cciss_init_one(struct pci_de
        ctlr_info_t *h;
        unsigned long flags;
  
+       /*
+        * By default the cciss driver is used for all older HP Smart Array
+        * controllers. There are module paramaters that allow a user to
+        * override this behavior and instead use the hpsa SCSI driver. If
+        * this is the case cciss may be loaded first from the kdump initrd
+        * image and cause a kernel panic. So if reset_devices is true and
+        * cciss_allow_hpsa is set just bail.
+        */
+       if ((reset_devices) && (cciss_allow_hpsa == 1))
+               return -ENODEV;
        rc = cciss_init_reset_devices(pdev);
        if (rc) {
                if (rc != -ENOTSUPP)
@@@ -45,7 -45,7 +45,7 @@@
  #include <linux/reboot.h>
  #include <linux/notifier.h>
  #include <linux/kthread.h>
+ #include <linux/workqueue.h>
  #define __KERNEL_SYSCALLS__
  #include <linux/unistd.h>
  #include <linux/vmalloc.h>
@@@ -63,7 -63,7 +63,7 @@@ int drbd_asender(struct drbd_thread *)
  
  int drbd_init(void);
  static int drbd_open(struct block_device *bdev, fmode_t mode);
 -static int drbd_release(struct gendisk *gd, fmode_t mode);
 +static void drbd_release(struct gendisk *gd, fmode_t mode);
  static int w_md_sync(struct drbd_work *w, int unused);
  static void md_sync_timer_fn(unsigned long data);
  static int w_bitmap_io(struct drbd_work *w, int unused);
@@@ -1849,12 -1849,13 +1849,12 @@@ static int drbd_open(struct block_devic
        return rv;
  }
  
 -static int drbd_release(struct gendisk *gd, fmode_t mode)
 +static void drbd_release(struct gendisk *gd, fmode_t mode)
  {
        struct drbd_conf *mdev = gd->private_data;
        mutex_lock(&drbd_main_mutex);
        mdev->open_cnt--;
        mutex_unlock(&drbd_main_mutex);
 -      return 0;
  }
  
  static void drbd_set_defaults(struct drbd_conf *mdev)
@@@ -2299,6 -2300,7 +2299,7 @@@ static void drbd_cleanup(void
        idr_for_each_entry(&minors, mdev, i) {
                idr_remove(&minors, mdev_to_minor(mdev));
                idr_remove(&mdev->tconn->volumes, mdev->vnr);
+               destroy_workqueue(mdev->submit.wq);
                del_gendisk(mdev->vdisk);
                /* synchronize_rcu(); No other threads running at this point */
                kref_put(&mdev->kref, &drbd_minor_destroy);
@@@ -2588,6 -2590,21 +2589,21 @@@ void conn_destroy(struct kref *kref
        kfree(tconn);
  }
  
+ int init_submitter(struct drbd_conf *mdev)
+ {
+       /* opencoded create_singlethread_workqueue(),
+        * to be able to say "drbd%d", ..., minor */
+       mdev->submit.wq = alloc_workqueue("drbd%u_submit",
+                       WQ_UNBOUND | WQ_MEM_RECLAIM, 1, mdev->minor);
+       if (!mdev->submit.wq)
+               return -ENOMEM;
+       INIT_WORK(&mdev->submit.worker, do_submit);
+       spin_lock_init(&mdev->submit.lock);
+       INIT_LIST_HEAD(&mdev->submit.writes);
+       return 0;
+ }
  enum drbd_ret_code conn_new_minor(struct drbd_tconn *tconn, unsigned int minor, int vnr)
  {
        struct drbd_conf *mdev;
                goto out_idr_remove_minor;
        }
  
+       if (init_submitter(mdev)) {
+               err = ERR_NOMEM;
+               drbd_msg_put_info("unable to create submit workqueue");
+               goto out_idr_remove_vol;
+       }
        add_disk(disk);
        kref_init(&mdev->kref); /* one ref for both idrs and the the add_disk */
  
  
        return NO_ERROR;
  
+ out_idr_remove_vol:
+       idr_remove(&tconn->volumes, vnr_got);
  out_idr_remove_minor:
        idr_remove(&minors, minor_got);
        synchronize_rcu();
@@@ -2794,6 -2819,7 +2818,7 @@@ void drbd_free_bc(struct drbd_backing_d
        blkdev_put(ldev->backing_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
        blkdev_put(ldev->md_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
  
+       kfree(ldev->disk_conf);
        kfree(ldev);
  }
  
@@@ -2833,8 -2859,9 +2858,9 @@@ void conn_md_sync(struct drbd_tconn *tc
        rcu_read_unlock();
  }
  
+ /* aligned 4kByte */
  struct meta_data_on_disk {
-       u64 la_size;           /* last agreed size. */
+       u64 la_size_sect;      /* last agreed size. */
        u64 uuid[UI_SIZE];   /* UUIDs. */
        u64 device_uuid;
        u64 reserved_u64_1;
        u32 magic;
        u32 md_size_sect;
        u32 al_offset;         /* offset to this block */
-       u32 al_nr_extents;     /* important for restoring the AL */
+       u32 al_nr_extents;     /* important for restoring the AL (userspace) */
              /* `-- act_log->nr_elements <-- ldev->dc.al_extents */
        u32 bm_offset;         /* offset to the bitmap, from here */
        u32 bm_bytes_per_bit;  /* BM_BLOCK_SIZE */
        u32 la_peer_max_bio_size;   /* last peer max_bio_size */
-       u32 reserved_u32[3];
  
+       /* see al_tr_number_to_on_disk_sector() */
+       u32 al_stripes;
+       u32 al_stripe_size_4k;
+       u8 reserved_u8[4096 - (7*8 + 10*4)];
  } __packed;
  
  /**
@@@ -2861,6 -2892,10 +2891,10 @@@ void drbd_md_sync(struct drbd_conf *mde
        sector_t sector;
        int i;
  
+       /* Don't accidentally change the DRBD meta data layout. */
+       BUILD_BUG_ON(UI_SIZE != 4);
+       BUILD_BUG_ON(sizeof(struct meta_data_on_disk) != 4096);
        del_timer(&mdev->md_sync_timer);
        /* timer may be rearmed by drbd_md_mark_dirty() now. */
        if (!test_and_clear_bit(MD_DIRTY, &mdev->flags))
        if (!buffer)
                goto out;
  
-       memset(buffer, 0, 512);
+       memset(buffer, 0, sizeof(*buffer));
  
-       buffer->la_size = cpu_to_be64(drbd_get_capacity(mdev->this_bdev));
+       buffer->la_size_sect = cpu_to_be64(drbd_get_capacity(mdev->this_bdev));
        for (i = UI_CURRENT; i < UI_SIZE; i++)
                buffer->uuid[i] = cpu_to_be64(mdev->ldev->md.uuid[i]);
        buffer->flags = cpu_to_be32(mdev->ldev->md.flags);
        buffer->bm_offset = cpu_to_be32(mdev->ldev->md.bm_offset);
        buffer->la_peer_max_bio_size = cpu_to_be32(mdev->peer_max_bio_size);
  
-       D_ASSERT(drbd_md_ss__(mdev, mdev->ldev) == mdev->ldev->md.md_offset);
+       buffer->al_stripes = cpu_to_be32(mdev->ldev->md.al_stripes);
+       buffer->al_stripe_size_4k = cpu_to_be32(mdev->ldev->md.al_stripe_size_4k);
+       D_ASSERT(drbd_md_ss(mdev->ldev) == mdev->ldev->md.md_offset);
        sector = mdev->ldev->md.md_offset;
  
        if (drbd_md_sync_page_io(mdev, mdev->ldev, sector, WRITE)) {
        put_ldev(mdev);
  }
  
+ static int check_activity_log_stripe_size(struct drbd_conf *mdev,
+               struct meta_data_on_disk *on_disk,
+               struct drbd_md *in_core)
+ {
+       u32 al_stripes = be32_to_cpu(on_disk->al_stripes);
+       u32 al_stripe_size_4k = be32_to_cpu(on_disk->al_stripe_size_4k);
+       u64 al_size_4k;
+       /* both not set: default to old fixed size activity log */
+       if (al_stripes == 0 && al_stripe_size_4k == 0) {
+               al_stripes = 1;
+               al_stripe_size_4k = MD_32kB_SECT/8;
+       }
+       /* some paranoia plausibility checks */
+       /* we need both values to be set */
+       if (al_stripes == 0 || al_stripe_size_4k == 0)
+               goto err;
+       al_size_4k = (u64)al_stripes * al_stripe_size_4k;
+       /* Upper limit of activity log area, to avoid potential overflow
+        * problems in al_tr_number_to_on_disk_sector(). As right now, more
+        * than 72 * 4k blocks total only increases the amount of history,
+        * limiting this arbitrarily to 16 GB is not a real limitation ;-)  */
+       if (al_size_4k > (16 * 1024 * 1024/4))
+               goto err;
+       /* Lower limit: we need at least 8 transaction slots (32kB)
+        * to not break existing setups */
+       if (al_size_4k < MD_32kB_SECT/8)
+               goto err;
+       in_core->al_stripe_size_4k = al_stripe_size_4k;
+       in_core->al_stripes = al_stripes;
+       in_core->al_size_4k = al_size_4k;
+       return 0;
+ err:
+       dev_err(DEV, "invalid activity log striping: al_stripes=%u, al_stripe_size_4k=%u\n",
+                       al_stripes, al_stripe_size_4k);
+       return -EINVAL;
+ }
+ static int check_offsets_and_sizes(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
+ {
+       sector_t capacity = drbd_get_capacity(bdev->md_bdev);
+       struct drbd_md *in_core = &bdev->md;
+       s32 on_disk_al_sect;
+       s32 on_disk_bm_sect;
+       /* The on-disk size of the activity log, calculated from offsets, and
+        * the size of the activity log calculated from the stripe settings,
+        * should match.
+        * Though we could relax this a bit: it is ok, if the striped activity log
+        * fits in the available on-disk activity log size.
+        * Right now, that would break how resize is implemented.
+        * TODO: make drbd_determine_dev_size() (and the drbdmeta tool) aware
+        * of possible unused padding space in the on disk layout. */
+       if (in_core->al_offset < 0) {
+               if (in_core->bm_offset > in_core->al_offset)
+                       goto err;
+               on_disk_al_sect = -in_core->al_offset;
+               on_disk_bm_sect = in_core->al_offset - in_core->bm_offset;
+       } else {
+               if (in_core->al_offset != MD_4kB_SECT)
+                       goto err;
+               if (in_core->bm_offset < in_core->al_offset + in_core->al_size_4k * MD_4kB_SECT)
+                       goto err;
+               on_disk_al_sect = in_core->bm_offset - MD_4kB_SECT;
+               on_disk_bm_sect = in_core->md_size_sect - in_core->bm_offset;
+       }
+       /* old fixed size meta data is exactly that: fixed. */
+       if (in_core->meta_dev_idx >= 0) {
+               if (in_core->md_size_sect != MD_128MB_SECT
+               ||  in_core->al_offset != MD_4kB_SECT
+               ||  in_core->bm_offset != MD_4kB_SECT + MD_32kB_SECT
+               ||  in_core->al_stripes != 1
+               ||  in_core->al_stripe_size_4k != MD_32kB_SECT/8)
+                       goto err;
+       }
+       if (capacity < in_core->md_size_sect)
+               goto err;
+       if (capacity - in_core->md_size_sect < drbd_md_first_sector(bdev))
+               goto err;
+       /* should be aligned, and at least 32k */
+       if ((on_disk_al_sect & 7) || (on_disk_al_sect < MD_32kB_SECT))
+               goto err;
+       /* should fit (for now: exactly) into the available on-disk space;
+        * overflow prevention is in check_activity_log_stripe_size() above. */
+       if (on_disk_al_sect != in_core->al_size_4k * MD_4kB_SECT)
+               goto err;
+       /* again, should be aligned */
+       if (in_core->bm_offset & 7)
+               goto err;
+       /* FIXME check for device grow with flex external meta data? */
+       /* can the available bitmap space cover the last agreed device size? */
+       if (on_disk_bm_sect < (in_core->la_size_sect+7)/MD_4kB_SECT/8/512)
+               goto err;
+       return 0;
+ err:
+       dev_err(DEV, "meta data offsets don't make sense: idx=%d "
+                       "al_s=%u, al_sz4k=%u, al_offset=%d, bm_offset=%d, "
+                       "md_size_sect=%u, la_size=%llu, md_capacity=%llu\n",
+                       in_core->meta_dev_idx,
+                       in_core->al_stripes, in_core->al_stripe_size_4k,
+                       in_core->al_offset, in_core->bm_offset, in_core->md_size_sect,
+                       (unsigned long long)in_core->la_size_sect,
+                       (unsigned long long)capacity);
+       return -EINVAL;
+ }
  /**
   * drbd_md_read() - Reads in the meta data super block
   * @mdev:     DRBD device.
   * @bdev:     Device from which the meta data should be read in.
   *
-  * Return 0 (NO_ERROR) on success, and an enum drbd_ret_code in case
+  * Return NO_ERROR on success, and an enum drbd_ret_code in case
   * something goes wrong.
+  *
+  * Called exactly once during drbd_adm_attach(), while still being D_DISKLESS,
+  * even before @bdev is assigned to @mdev->ldev.
   */
  int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
  {
        u32 magic, flags;
        int i, rv = NO_ERROR;
  
-       if (!get_ldev_if_state(mdev, D_ATTACHING))
-               return ERR_IO_MD_DISK;
+       if (mdev->state.disk != D_DISKLESS)
+               return ERR_DISK_CONFIGURED;
  
        buffer = drbd_md_get_buffer(mdev);
        if (!buffer)
-               goto out;
+               return ERR_NOMEM;
+       /* First, figure out where our meta data superblock is located,
+        * and read it. */
+       bdev->md.meta_dev_idx = bdev->disk_conf->meta_dev_idx;
+       bdev->md.md_offset = drbd_md_ss(bdev);
  
        if (drbd_md_sync_page_io(mdev, bdev, bdev->md.md_offset, READ)) {
                /* NOTE: can't do normal error processing here as this is
                rv = ERR_MD_UNCLEAN;
                goto err;
        }
+       rv = ERR_MD_INVALID;
        if (magic != DRBD_MD_MAGIC_08) {
                if (magic == DRBD_MD_MAGIC_07)
                        dev_err(DEV, "Found old (0.7) meta data magic. Did you \"drbdadm create-md\"?\n");
                else
                        dev_err(DEV, "Meta data magic not found. Did you \"drbdadm create-md\"?\n");
-               rv = ERR_MD_INVALID;
                goto err;
        }
-       if (be32_to_cpu(buffer->al_offset) != bdev->md.al_offset) {
-               dev_err(DEV, "unexpected al_offset: %d (expected %d)\n",
-                   be32_to_cpu(buffer->al_offset), bdev->md.al_offset);
-               rv = ERR_MD_INVALID;
+       if (be32_to_cpu(buffer->bm_bytes_per_bit) != BM_BLOCK_SIZE) {
+               dev_err(DEV, "unexpected bm_bytes_per_bit: %u (expected %u)\n",
+                   be32_to_cpu(buffer->bm_bytes_per_bit), BM_BLOCK_SIZE);
                goto err;
        }
+       /* convert to in_core endian */
+       bdev->md.la_size_sect = be64_to_cpu(buffer->la_size_sect);
+       for (i = UI_CURRENT; i < UI_SIZE; i++)
+               bdev->md.uuid[i] = be64_to_cpu(buffer->uuid[i]);
+       bdev->md.flags = be32_to_cpu(buffer->flags);
+       bdev->md.device_uuid = be64_to_cpu(buffer->device_uuid);
+       bdev->md.md_size_sect = be32_to_cpu(buffer->md_size_sect);
+       bdev->md.al_offset = be32_to_cpu(buffer->al_offset);
+       bdev->md.bm_offset = be32_to_cpu(buffer->bm_offset);
+       if (check_activity_log_stripe_size(mdev, buffer, &bdev->md))
+               goto err;
+       if (check_offsets_and_sizes(mdev, bdev))
+               goto err;
        if (be32_to_cpu(buffer->bm_offset) != bdev->md.bm_offset) {
                dev_err(DEV, "unexpected bm_offset: %d (expected %d)\n",
                    be32_to_cpu(buffer->bm_offset), bdev->md.bm_offset);
-               rv = ERR_MD_INVALID;
                goto err;
        }
        if (be32_to_cpu(buffer->md_size_sect) != bdev->md.md_size_sect) {
                dev_err(DEV, "unexpected md_size: %u (expected %u)\n",
                    be32_to_cpu(buffer->md_size_sect), bdev->md.md_size_sect);
-               rv = ERR_MD_INVALID;
                goto err;
        }
  
-       if (be32_to_cpu(buffer->bm_bytes_per_bit) != BM_BLOCK_SIZE) {
-               dev_err(DEV, "unexpected bm_bytes_per_bit: %u (expected %u)\n",
-                   be32_to_cpu(buffer->bm_bytes_per_bit), BM_BLOCK_SIZE);
-               rv = ERR_MD_INVALID;
-               goto err;
-       }
-       bdev->md.la_size_sect = be64_to_cpu(buffer->la_size);
-       for (i = UI_CURRENT; i < UI_SIZE; i++)
-               bdev->md.uuid[i] = be64_to_cpu(buffer->uuid[i]);
-       bdev->md.flags = be32_to_cpu(buffer->flags);
-       bdev->md.device_uuid = be64_to_cpu(buffer->device_uuid);
+       rv = NO_ERROR;
  
        spin_lock_irq(&mdev->tconn->req_lock);
        if (mdev->state.conn < C_CONNECTED) {
  
   err:
        drbd_md_put_buffer(mdev);
-  out:
-       put_ldev(mdev);
  
        return rv;
  }
@@@ -3238,8 -3413,12 +3412,12 @@@ static int w_go_diskless(struct drbd_wo
         * end up here after a failed attach, before ldev was even assigned.
         */
        if (mdev->bitmap && mdev->ldev) {
+               /* An interrupted resync or similar is allowed to recounts bits
+                * while we detach.
+                * Any modifications would not be expected anymore, though.
+                */
                if (drbd_bitmap_io_from_worker(mdev, drbd_bm_write,
-                                       "detach", BM_LOCKED_MASK)) {
+                                       "detach", BM_LOCKED_TEST_ALLOWED)) {
                        if (test_bit(WAS_READ_ERROR, &mdev->flags)) {
                                drbd_md_set_flag(mdev, MDF_FULL_SYNC);
                                drbd_md_sync(mdev);
        return 0;
  }
  
- void drbd_go_diskless(struct drbd_conf *mdev)
- {
-       D_ASSERT(mdev->state.disk == D_FAILED);
-       if (!test_and_set_bit(GO_DISKLESS, &mdev->flags))
-               drbd_queue_work(&mdev->tconn->sender_work, &mdev->go_diskless);
- }
  /**
   * drbd_queue_bitmap_io() - Queues an IO operation on the whole bitmap
   * @mdev:     DRBD device.
@@@ -313,8 -313,14 +313,14 @@@ static int drbd_seq_show(struct seq_fil
  
  static int drbd_proc_open(struct inode *inode, struct file *file)
  {
-       if (try_module_get(THIS_MODULE))
-               return single_open(file, drbd_seq_show, PDE_DATA(inode));
+       int err;
+       if (try_module_get(THIS_MODULE)) {
 -              err = single_open(file, drbd_seq_show, PDE(inode)->data);
++              err = single_open(file, drbd_seq_show, PDE_DATA(inode));
+               if (err)
+                       module_put(THIS_MODULE);
+               return err;
+       }
        return -ENODEV;
  }
  
@@@ -757,8 -757,7 +757,8 @@@ static struct socket *drbd_wait_for_con
        rcu_read_unlock();
  
        timeo = connect_int * HZ;
 -      timeo += (random32() & 1) ? timeo / 7 : -timeo / 7; /* 28.5% random jitter */
 +      /* 28.5% random jitter */
 +      timeo += (prandom_u32() & 1) ? timeo / 7 : -timeo / 7;
  
        err = wait_for_completion_interruptible_timeout(&ad->door_bell, timeo);
        if (err <= 0)
@@@ -850,6 -849,7 +850,7 @@@ int drbd_connected(struct drbd_conf *md
                err = drbd_send_current_state(mdev);
        clear_bit(USE_DEGR_WFC_T, &mdev->flags);
        clear_bit(RESIZE_PENDING, &mdev->flags);
+       atomic_set(&mdev->ap_in_flight, 0);
        mod_timer(&mdev->request_timer, jiffies + HZ); /* just start it here. */
        return err;
  }
@@@ -954,7 -954,7 +955,7 @@@ retry
                                conn_warn(tconn, "Error receiving initial packet\n");
                                sock_release(s);
  randomize:
 -                              if (random32() & 1)
 +                              if (prandom_u32() & 1)
                                        goto retry;
                        }
                }
@@@ -2266,7 -2266,7 +2267,7 @@@ static int receive_Data(struct drbd_tco
                drbd_set_out_of_sync(mdev, peer_req->i.sector, peer_req->i.size);
                peer_req->flags |= EE_CALL_AL_COMPLETE_IO;
                peer_req->flags &= ~EE_MAY_SET_IN_SYNC;
-               drbd_al_begin_io(mdev, &peer_req->i);
+               drbd_al_begin_io(mdev, &peer_req->i, true);
        }
  
        err = drbd_submit_peer_request(mdev, peer_req, rw, DRBD_FAULT_DT_WR);
@@@ -2662,7 -2662,6 +2663,6 @@@ static int drbd_asb_recover_1p(struct d
                if (hg == -1 && mdev->state.role == R_PRIMARY) {
                        enum drbd_state_rv rv2;
  
-                       drbd_set_role(mdev, R_SECONDARY, 0);
                         /* drbd_change_state() does not sleep while in SS_IN_TRANSIENT_STATE,
                          * we might be here in C_WF_REPORT_PARAMS which is transient.
                          * we do not need to wait for the after state change work either. */
@@@ -3993,7 -3992,7 +3993,7 @@@ static int receive_state(struct drbd_tc
  
        clear_bit(DISCARD_MY_DATA, &mdev->flags);
  
-       drbd_md_sync(mdev); /* update connected indicator, la_size, ... */
+       drbd_md_sync(mdev); /* update connected indicator, la_size_sect, ... */
  
        return 0;
  }
@@@ -4660,8 -4659,8 +4660,8 @@@ static int drbd_do_features(struct drbd
  #if !defined(CONFIG_CRYPTO_HMAC) && !defined(CONFIG_CRYPTO_HMAC_MODULE)
  static int drbd_do_auth(struct drbd_tconn *tconn)
  {
-       dev_err(DEV, "This kernel was build without CONFIG_CRYPTO_HMAC.\n");
-       dev_err(DEV, "You need to disable 'cram-hmac-alg' in drbd.conf.\n");
+       conn_err(tconn, "This kernel was build without CONFIG_CRYPTO_HMAC.\n");
+       conn_err(tconn, "You need to disable 'cram-hmac-alg' in drbd.conf.\n");
        return -1;
  }
  #else
@@@ -5258,9 -5257,11 +5258,11 @@@ int drbd_asender(struct drbd_thread *th
        bool ping_timeout_active = false;
        struct net_conf *nc;
        int ping_timeo, tcp_cork, ping_int;
+       struct sched_param param = { .sched_priority = 2 };
  
-       current->policy = SCHED_RR;  /* Make this a realtime task! */
-       current->rt_priority = 2;    /* more important than all other tasks */
+       rv = sched_setscheduler(current, SCHED_RR, &param);
+       if (rv < 0)
+               conn_err(tconn, "drbd_asender: ERROR set priority, ret=%d\n", rv);
  
        while (get_t_state(thi) == RUNNING) {
                drbd_thread_current_set_cpu(thi);
diff --combined drivers/block/mg_disk.c
@@@ -780,6 -780,7 +780,7 @@@ static const struct block_device_operat
        .getgeo = mg_getgeo
  };
  
+ #ifdef CONFIG_PM_SLEEP
  static int mg_suspend(struct device *dev)
  {
        struct mg_drv_data *prv_data = dev->platform_data;
@@@ -824,6 -825,7 +825,7 @@@ static int mg_resume(struct device *dev
  
        return 0;
  }
+ #endif
  
  static SIMPLE_DEV_PM_OPS(mg_pm, mg_suspend, mg_resume);
  
@@@ -890,10 -892,8 +892,10 @@@ static int mg_probe(struct platform_dev
        gpio_direction_output(host->rst, 1);
  
        /* reset out pin */
 -      if (!(prv_data->dev_attr & MG_DEV_MASK))
 +      if (!(prv_data->dev_attr & MG_DEV_MASK)) {
 +              err = -EINVAL;
                goto probe_err_3a;
 +      }
  
        if (prv_data->dev_attr != MG_BOOT_DEV) {
                rsc = platform_get_resource_byname(plat_dev, IORESOURCE_IO,
  /* Device instance number, incremented each time a device is probed. */
  static int instance;
  
 +struct list_head online_list;
 +struct list_head removing_list;
 +spinlock_t dev_lock;
 +
  /*
   * Global variable used to hold the major block device number
   * allocated in mtip_init().
   */
  static int mtip_major;
  static struct dentry *dfs_parent;
 +static struct dentry *dfs_device_status;
  
  static u32 cpu_use[NR_CPUS];
  
@@@ -248,31 -243,40 +248,31 @@@ static inline void release_slot(struct 
  /*
   * Reset the HBA (without sleeping)
   *
 - * Just like hba_reset, except does not call sleep, so can be
 - * run from interrupt/tasklet context.
 - *
   * @dd Pointer to the driver data structure.
   *
   * return value
   *    0       The reset was successful.
   *    -1      The HBA Reset bit did not clear.
   */
 -static int hba_reset_nosleep(struct driver_data *dd)
 +static int mtip_hba_reset(struct driver_data *dd)
  {
        unsigned long timeout;
  
 -      /* Chip quirk: quiesce any chip function */
 -      mdelay(10);
 -
        /* Set the reset bit */
        writel(HOST_RESET, dd->mmio + HOST_CTL);
  
        /* Flush */
        readl(dd->mmio + HOST_CTL);
  
 -      /*
 -       * Wait 10ms then spin for up to 1 second
 -       * waiting for reset acknowledgement
 -       */
 -      timeout = jiffies + msecs_to_jiffies(1000);
 -      mdelay(10);
 -      while ((readl(dd->mmio + HOST_CTL) & HOST_RESET)
 -               && time_before(jiffies, timeout))
 -              mdelay(1);
 +      /* Spin for up to 2 seconds, waiting for reset acknowledgement */
 +      timeout = jiffies + msecs_to_jiffies(2000);
 +      do {
 +              mdelay(10);
 +              if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))
 +                      return -1;
  
 -      if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))
 -              return -1;
 +      } while ((readl(dd->mmio + HOST_CTL) & HOST_RESET)
 +               && time_before(jiffies, timeout));
  
        if (readl(dd->mmio + HOST_CTL) & HOST_RESET)
                return -1;
@@@ -477,7 -481,7 +477,7 @@@ static void mtip_restart_port(struct mt
                dev_warn(&port->dd->pdev->dev,
                        "PxCMD.CR not clear, escalating reset\n");
  
 -              if (hba_reset_nosleep(port->dd))
 +              if (mtip_hba_reset(port->dd))
                        dev_err(&port->dd->pdev->dev,
                                "HBA reset escalation failed.\n");
  
  
  }
  
 +static int mtip_device_reset(struct driver_data *dd)
 +{
 +      int rv = 0;
 +
 +      if (mtip_check_surprise_removal(dd->pdev))
 +              return 0;
 +
 +      if (mtip_hba_reset(dd) < 0)
 +              rv = -EFAULT;
 +
 +      mdelay(1);
 +      mtip_init_port(dd->port);
 +      mtip_start_port(dd->port);
 +
 +      /* Enable interrupts on the HBA. */
 +      writel(readl(dd->mmio + HOST_CTL) | HOST_IRQ_EN,
 +                                      dd->mmio + HOST_CTL);
 +      return rv;
 +}
 +
  /*
   * Helper function for tag logging
   */
@@@ -648,7 -632,7 +648,7 @@@ static void mtip_timeout_function(unsig
        if (cmdto_cnt) {
                print_tags(port->dd, "timed out", tagaccum, cmdto_cnt);
                if (!test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) {
 -                      mtip_restart_port(port);
 +                      mtip_device_reset(port->dd);
                        wake_up_interruptible(&port->svc_wait);
                }
                clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags);
@@@ -728,7 -712,10 +728,10 @@@ static void mtip_async_complete(struct 
        atomic_set(&port->commands[tag].active, 0);
        release_slot(port, tag);
  
-       up(&port->cmd_slot);
+       if (unlikely(command->unaligned))
+               up(&port->cmd_slot_unal);
+       else
+               up(&port->cmd_slot);
  }
  
  /*
@@@ -1299,11 -1286,11 +1302,11 @@@ static int mtip_exec_internal_command(s
        int rv = 0, ready2go = 1;
        struct mtip_cmd *int_cmd = &port->commands[MTIP_TAG_INTERNAL];
        unsigned long to;
 +      struct driver_data *dd = port->dd;
  
        /* Make sure the buffer is 8 byte aligned. This is asic specific. */
        if (buffer & 0x00000007) {
 -              dev_err(&port->dd->pdev->dev,
 -                      "SG buffer is not 8 byte aligned\n");
 +              dev_err(&dd->pdev->dev, "SG buffer is not 8 byte aligned\n");
                return -EFAULT;
        }
  
                mdelay(100);
        } while (time_before(jiffies, to));
        if (!ready2go) {
 -              dev_warn(&port->dd->pdev->dev,
 +              dev_warn(&dd->pdev->dev,
                        "Internal cmd active. new cmd [%02X]\n", fis->command);
                return -EBUSY;
        }
        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);
 +      clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags);
 +      clear_bit(MTIP_PF_DM_ACTIVE_BIT, &port->flags);
  
        if (atomic == GFP_KERNEL) {
                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,
 +                              dev_warn(&dd->pdev->dev,
                                        "Failed to quiesce IO\n");
                                release_slot(port, MTIP_TAG_INTERNAL);
                                clear_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags);
        /* Issue the command to the hardware */
        mtip_issue_non_ncq_command(port, MTIP_TAG_INTERNAL);
  
 -      /* Poll if atomic, wait_for_completion otherwise */
        if (atomic == GFP_KERNEL) {
                /* Wait for the command to complete or timeout. */
 -              if (wait_for_completion_timeout(
 +              if (wait_for_completion_interruptible_timeout(
                                &wait,
 -                              msecs_to_jiffies(timeout)) == 0) {
 -                      dev_err(&port->dd->pdev->dev,
 -                              "Internal command did not complete [%d] "
 -                              "within timeout of  %lu ms\n",
 -                              atomic, timeout);
 -                      if (mtip_check_surprise_removal(port->dd->pdev) ||
 +                              msecs_to_jiffies(timeout)) <= 0) {
 +                      if (rv == -ERESTARTSYS) { /* interrupted */
 +                              dev_err(&dd->pdev->dev,
 +                                      "Internal command [%02X] was interrupted after %lu ms\n",
 +                                      fis->command, timeout);
 +                              rv = -EINTR;
 +                              goto exec_ic_exit;
 +                      } else if (rv == 0) /* timeout */
 +                              dev_err(&dd->pdev->dev,
 +                                      "Internal command did not complete [%02X] within timeout of  %lu ms\n",
 +                                      fis->command, timeout);
 +                      else
 +                              dev_err(&dd->pdev->dev,
 +                                      "Internal command [%02X] wait returned code [%d] after %lu ms - unhandled\n",
 +                                      fis->command, rv, timeout);
 +
 +                      if (mtip_check_surprise_removal(dd->pdev) ||
                                test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
 -                                              &port->dd->dd_flag)) {
 +                                              &dd->dd_flag)) {
 +                              dev_err(&dd->pdev->dev,
 +                                      "Internal command [%02X] wait returned due to SR\n",
 +                                      fis->command);
                                rv = -ENXIO;
                                goto exec_ic_exit;
                        }
 +                      mtip_device_reset(dd); /* recover from timeout issue */
                        rv = -EAGAIN;
 +                      goto exec_ic_exit;
                }
        } else {
 +              u32 hba_stat, port_stat;
 +
                /* 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)) {
 -                      if (mtip_check_surprise_removal(port->dd->pdev)) {
 +                      if (mtip_check_surprise_removal(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)) {
 +                                              &dd->dd_flag)) {
                                rv = -ENXIO;
                                goto exec_ic_exit;
                        }
 -                      if (readl(port->mmio + PORT_IRQ_STAT) & PORT_IRQ_ERR) {
 -                              atomic_inc(&int_cmd->active); /* error */
 -                              break;
 +                      port_stat = readl(port->mmio + PORT_IRQ_STAT);
 +                      if (!port_stat)
 +                              continue;
 +
 +                      if (port_stat & PORT_IRQ_ERR) {
 +                              dev_err(&dd->pdev->dev,
 +                                      "Internal command [%02X] failed\n",
 +                                      fis->command);
 +                              mtip_device_reset(dd);
 +                              rv = -EIO;
 +                              goto exec_ic_exit;
 +                      } else {
 +                              writel(port_stat, port->mmio + PORT_IRQ_STAT);
 +                              hba_stat = readl(dd->mmio + HOST_IRQ_STAT);
 +                              if (hba_stat)
 +                                      writel(hba_stat,
 +                                              dd->mmio + HOST_IRQ_STAT);
                        }
 +                      break;
                }
        }
  
 -      if (atomic_read(&int_cmd->active) > 1) {
 -              dev_err(&port->dd->pdev->dev,
 -                      "Internal command [%02X] failed\n", fis->command);
 -              rv = -EIO;
 -      }
        if (readl(port->cmd_issue[MTIP_TAG_INTERNAL])
                        & (1 << MTIP_TAG_INTERNAL)) {
                rv = -ENXIO;
 -              if (!test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
 -                                      &port->dd->dd_flag)) {
 -                      mtip_restart_port(port);
 +              if (!test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag)) {
 +                      mtip_device_reset(dd);
                        rv = -EAGAIN;
                }
        }
@@@ -1560,10 -1523,12 +1563,12 @@@ static int mtip_get_identify(struct mti
        }
  #endif
  
+ #ifdef MTIP_TRIM /* Disabling TRIM support temporarily */
        /* Demux ID.DRAT & ID.RZAT to determine trim support */
        if (port->identify[69] & (1 << 14) && port->identify[69] & (1 << 5))
                port->dd->trim_supp = true;
        else
+ #endif
                port->dd->trim_supp = false;
  
        /* Set the identify buffer as valid. */
@@@ -1764,8 -1729,7 +1769,8 @@@ static int mtip_get_smart_attr(struct m
   *      -EINVAL               Invalid parameters passed in, trim not supported
   *      -EIO          Error submitting trim request to hw
   */
 -static int mtip_send_trim(struct driver_data *dd, unsigned int lba, unsigned int len)
 +static int mtip_send_trim(struct driver_data *dd, unsigned int lba,
 +                              unsigned int len)
  {
        int i, rv = 0;
        u64 tlba, tlen, sect_left;
@@@ -1852,6 -1816,45 +1857,6 @@@ static bool mtip_hw_get_capacity(struc
  }
  
  /*
 - * Reset the HBA.
 - *
 - * Resets the HBA by setting the HBA Reset bit in the Global
 - * HBA Control register. After setting the HBA Reset bit the
 - * function waits for 1 second before reading the HBA Reset
 - * bit to make sure it has cleared. If HBA Reset is not clear
 - * an error is returned. Cannot be used in non-blockable
 - * context.
 - *
 - * @dd Pointer to the driver data structure.
 - *
 - * return value
 - *    0  The reset was successful.
 - *    -1 The HBA Reset bit did not clear.
 - */
 -static int mtip_hba_reset(struct driver_data *dd)
 -{
 -      mtip_deinit_port(dd->port);
 -
 -      /* Set the reset bit */
 -      writel(HOST_RESET, dd->mmio + HOST_CTL);
 -
 -      /* Flush */
 -      readl(dd->mmio + HOST_CTL);
 -
 -      /* Wait for reset to clear */
 -      ssleep(1);
 -
 -      /* Check the bit has cleared */
 -      if (readl(dd->mmio + HOST_CTL) & HOST_RESET) {
 -              dev_err(&dd->pdev->dev,
 -                      "Reset bit did not clear.\n");
 -              return -1;
 -      }
 -
 -      return 0;
 -}
 -
 -/*
   * Display the identify command data.
   *
   * @port Pointer to the port data structure.
@@@ -2557,7 -2560,7 +2562,7 @@@ static int mtip_hw_ioctl(struct driver_
   */
  static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector,
                              int nsect, int nents, int tag, void *callback,
-                             void *data, int dir)
+                             void *data, int dir, int unaligned)
  {
        struct host_to_dev_fis  *fis;
        struct mtip_port *port = dd->port;
  
        command->scatter_ents = nents;
  
+       command->unaligned = unaligned;
        /*
         * The number of retries for this command before it is
         * reported as a failure to the upper layers.
        fis->res3        = 0;
        fill_command_sg(dd, command, nents);
  
+       if (unaligned)
+               fis->device |= 1 << 7;
        /* Populate the command header */
        command->command_header->opts =
                        __force_bit2int cpu_to_le32(
   * return value
   *      None
   */
- static void mtip_hw_release_scatterlist(struct driver_data *dd, int tag)
+ static void mtip_hw_release_scatterlist(struct driver_data *dd, int tag,
+                                                               int unaligned)
  {
+       struct semaphore *sem = unaligned ? &dd->port->cmd_slot_unal :
+                                                       &dd->port->cmd_slot;
        release_slot(dd->port, tag);
+       up(sem);
  }
  
  /*
   *    or NULL if no command slots are available.
   */
  static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd,
-                                                  int *tag)
+                                                  int *tag, int unaligned)
  {
+       struct semaphore *sem = unaligned ? &dd->port->cmd_slot_unal :
+                                                       &dd->port->cmd_slot;
        /*
         * It is possible that, even with this semaphore, a thread
         * may think that no command slots are available. Therefore, we
         * need to make an attempt to get_slot().
         */
-       down(&dd->port->cmd_slot);
+       down(sem);
        *tag = get_slot(dd->port);
  
        if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) {
-               up(&dd->port->cmd_slot);
+               up(sem);
                return NULL;
        }
        if (unlikely(*tag < 0)) {
-               up(&dd->port->cmd_slot);
+               up(sem);
                return NULL;
        }
  
@@@ -2712,100 -2726,6 +2728,100 @@@ static ssize_t mtip_hw_show_status(stru
  
  static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL);
  
 +/* debugsfs entries */
 +
 +static ssize_t show_device_status(struct device_driver *drv, char *buf)
 +{
 +      int size = 0;
 +      struct driver_data *dd, *tmp;
 +      unsigned long flags;
 +      char id_buf[42];
 +      u16 status = 0;
 +
 +      spin_lock_irqsave(&dev_lock, flags);
 +      size += sprintf(&buf[size], "Devices Present:\n");
 +      list_for_each_entry_safe(dd, tmp, &online_list, online_list) {
 +              if (dd->pdev) {
 +                      if (dd->port &&
 +                          dd->port->identify &&
 +                          dd->port->identify_valid) {
 +                              strlcpy(id_buf,
 +                                      (char *) (dd->port->identify + 10), 21);
 +                              status = *(dd->port->identify + 141);
 +                      } else {
 +                              memset(id_buf, 0, 42);
 +                              status = 0;
 +                      }
 +
 +                      if (dd->port &&
 +                          test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags)) {
 +                              size += sprintf(&buf[size],
 +                                      " device %s %s (ftl rebuild %d %%)\n",
 +                                      dev_name(&dd->pdev->dev),
 +                                      id_buf,
 +                                      status);
 +                      } else {
 +                              size += sprintf(&buf[size],
 +                                      " device %s %s\n",
 +                                      dev_name(&dd->pdev->dev),
 +                                      id_buf);
 +                      }
 +              }
 +      }
 +
 +      size += sprintf(&buf[size], "Devices Being Removed:\n");
 +      list_for_each_entry_safe(dd, tmp, &removing_list, remove_list) {
 +              if (dd->pdev) {
 +                      if (dd->port &&
 +                          dd->port->identify &&
 +                          dd->port->identify_valid) {
 +                              strlcpy(id_buf,
 +                                      (char *) (dd->port->identify+10), 21);
 +                              status = *(dd->port->identify + 141);
 +                      } else {
 +                              memset(id_buf, 0, 42);
 +                              status = 0;
 +                      }
 +
 +                      if (dd->port &&
 +                          test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags)) {
 +                              size += sprintf(&buf[size],
 +                                      " device %s %s (ftl rebuild %d %%)\n",
 +                                      dev_name(&dd->pdev->dev),
 +                                      id_buf,
 +                                      status);
 +                      } else {
 +                              size += sprintf(&buf[size],
 +                                      " device %s %s\n",
 +                                      dev_name(&dd->pdev->dev),
 +                                      id_buf);
 +                      }
 +              }
 +      }
 +      spin_unlock_irqrestore(&dev_lock, flags);
 +
 +      return size;
 +}
 +
 +static ssize_t mtip_hw_read_device_status(struct file *f, char __user *ubuf,
 +                                              size_t len, loff_t *offset)
 +{
 +      int size = *offset;
 +      char buf[MTIP_DFS_MAX_BUF_SIZE];
 +
 +      if (!len || *offset)
 +              return 0;
 +
 +      size += show_device_status(NULL, buf);
 +
 +      *offset = size <= len ? size : len;
 +      size = copy_to_user(ubuf, buf, *offset);
 +      if (size)
 +              return -EFAULT;
 +
 +      return *offset;
 +}
 +
  static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf,
                                  size_t len, loff_t *offset)
  {
@@@ -2900,13 -2820,6 +2916,13 @@@ static ssize_t mtip_hw_read_flags(struc
        return *offset;
  }
  
 +static const struct file_operations mtip_device_status_fops = {
 +      .owner  = THIS_MODULE,
 +      .open   = simple_open,
 +      .read   = mtip_hw_read_device_status,
 +      .llseek = no_llseek,
 +};
 +
  static const struct file_operations mtip_regs_fops = {
        .owner  = THIS_MODULE,
        .open   = simple_open,
@@@ -3010,6 -2923,11 +3026,11 @@@ static inline void hba_setup(struct dri
                dd->mmio + HOST_HSORG);
  }
  
+ static int mtip_device_unaligned_constrained(struct driver_data *dd)
+ {
+       return (dd->pdev->device == P420M_DEVICE_ID ? 1 : 0);
+ }
  /*
   * Detect the details of the product, and store anything needed
   * into the driver data structure.  This includes product type and
@@@ -3232,8 -3150,15 +3253,15 @@@ static int mtip_hw_init(struct driver_d
        for (i = 0; i < MTIP_MAX_SLOT_GROUPS; i++)
                dd->work[i].port = dd->port;
  
+       /* Enable unaligned IO constraints for some devices */
+       if (mtip_device_unaligned_constrained(dd))
+               dd->unal_qdepth = MTIP_MAX_UNALIGNED_SLOTS;
+       else
+               dd->unal_qdepth = 0;
        /* Counting semaphore to track command slot usage */
-       sema_init(&dd->port->cmd_slot, num_command_slots - 1);
+       sema_init(&dd->port->cmd_slot, num_command_slots - 1 - dd->unal_qdepth);
+       sema_init(&dd->port->cmd_slot_unal, dd->unal_qdepth);
  
        /* Spinlock to prevent concurrent issue */
        for (i = 0; i < MTIP_MAX_SLOT_GROUPS; i++)
@@@ -3836,7 -3761,7 +3864,7 @@@ static void mtip_make_request(struct re
        struct scatterlist *sg;
        struct bio_vec *bvec;
        int nents = 0;
-       int tag = 0;
+       int tag = 0, unaligned = 0;
  
        if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) {
                if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
                return;
        }
  
-       sg = mtip_hw_get_scatterlist(dd, &tag);
+       if (bio_data_dir(bio) == WRITE && bio_sectors(bio) <= 64 &&
+                                                       dd->unal_qdepth) {
+               if (bio->bi_sector % 8 != 0) /* Unaligned on 4k boundaries */
+                       unaligned = 1;
+               else if (bio_sectors(bio) % 8 != 0) /* Aligned but not 4k/8k */
+                       unaligned = 1;
+       }
+       sg = mtip_hw_get_scatterlist(dd, &tag, unaligned);
        if (likely(sg != NULL)) {
                blk_queue_bounce(queue, &bio);
  
                        dev_warn(&dd->pdev->dev,
                                "Maximum number of SGL entries exceeded\n");
                        bio_io_error(bio);
-                       mtip_hw_release_scatterlist(dd, tag);
+                       mtip_hw_release_scatterlist(dd, tag, unaligned);
                        return;
                }
  
                                tag,
                                bio_endio,
                                bio,
-                               bio_data_dir(bio));
+                               bio_data_dir(bio),
+                               unaligned);
        } else
                bio_io_error(bio);
  }
@@@ -4156,26 -4090,24 +4193,24 @@@ static int mtip_block_remove(struct dri
   */
  static int mtip_block_shutdown(struct driver_data *dd)
  {
-       dev_info(&dd->pdev->dev,
-               "Shutting down %s ...\n", dd->disk->disk_name);
        /* Delete our gendisk structure, and cleanup the blk queue. */
        if (dd->disk) {
-               if (dd->disk->queue)
+               dev_info(&dd->pdev->dev,
+                       "Shutting down %s ...\n", dd->disk->disk_name);
+               if (dd->disk->queue) {
                        del_gendisk(dd->disk);
-               else
+                       blk_cleanup_queue(dd->queue);
+               } else
                        put_disk(dd->disk);
+               dd->disk  = NULL;
+               dd->queue = NULL;
        }
  
        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;
        mtip_hw_shutdown(dd);
        return 0;
  }
@@@ -4264,7 -4196,6 +4299,7 @@@ static int mtip_pci_probe(struct pci_de
        const struct cpumask *node_mask;
        int cpu, i = 0, j = 0;
        int my_node = NUMA_NO_NODE;
 +      unsigned long flags;
  
        /* Allocate memory for this devices private data. */
        my_node = pcibus_to_node(pdev->bus);
        dd->pdev        = pdev;
        dd->numa_node   = my_node;
  
 +      INIT_LIST_HEAD(&dd->online_list);
 +      INIT_LIST_HEAD(&dd->remove_list);
 +
        memset(dd->workq_name, 0, 32);
        snprintf(dd->workq_name, 31, "mtipq%d", dd->instance);
  
        dd->isr_workq = create_workqueue(dd->workq_name);
        if (!dd->isr_workq) {
                dev_warn(&pdev->dev, "Can't create wq %d\n", dd->instance);
 +              rv = -ENOMEM;
                goto block_initialize_err;
        }
  
        INIT_WORK(&dd->work[7].work, mtip_workq_sdbf7);
  
        pci_set_master(pdev);
 -      if (pci_enable_msi(pdev)) {
 +      rv = pci_enable_msi(pdev);
 +      if (rv) {
                dev_warn(&pdev->dev,
                        "Unable to enable MSI interrupt.\n");
                goto block_initialize_err;
        instance++;
        if (rv != MTIP_FTL_REBUILD_MAGIC)
                set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag);
 +      else
 +              rv = 0; /* device in rebuild state, return 0 from probe */
 +
 +      /* Add to online list even if in ftl rebuild */
 +      spin_lock_irqsave(&dev_lock, flags);
 +      list_add(&dd->online_list, &online_list);
 +      spin_unlock_irqrestore(&dev_lock, flags);
 +
        goto done;
  
  block_initialize_err:
@@@ -4453,15 -4371,9 +4488,15 @@@ static void mtip_pci_remove(struct pci_
  {
        struct driver_data *dd = pci_get_drvdata(pdev);
        int counter = 0;
 +      unsigned long flags;
  
        set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag);
  
 +      spin_lock_irqsave(&dev_lock, flags);
 +      list_del_init(&dd->online_list);
 +      list_add(&dd->remove_list, &removing_list);
 +      spin_unlock_irqrestore(&dev_lock, flags);
 +
        if (mtip_check_surprise_removal(pdev)) {
                while (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) {
                        counter++;
  
        pci_disable_msi(pdev);
  
 +      spin_lock_irqsave(&dev_lock, flags);
 +      list_del_init(&dd->remove_list);
 +      spin_unlock_irqrestore(&dev_lock, flags);
 +
        kfree(dd);
        pcim_iounmap_regions(pdev, 1 << MTIP_ABAR);
  }
@@@ -4638,11 -4546,6 +4673,11 @@@ static int __init mtip_init(void
  
        pr_info(MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n");
  
 +      spin_lock_init(&dev_lock);
 +
 +      INIT_LIST_HEAD(&online_list);
 +      INIT_LIST_HEAD(&removing_list);
 +
        /* Allocate a major block device number to use with this driver. */
        error = register_blkdev(0, MTIP_DRV_NAME);
        if (error <= 0) {
        }
        mtip_major = error;
  
 -      if (!dfs_parent) {
 -              dfs_parent = debugfs_create_dir("rssd", NULL);
 -              if (IS_ERR_OR_NULL(dfs_parent)) {
 -                      pr_warn("Error creating debugfs parent\n");
 -                      dfs_parent = NULL;
 +      dfs_parent = debugfs_create_dir("rssd", NULL);
 +      if (IS_ERR_OR_NULL(dfs_parent)) {
 +              pr_warn("Error creating debugfs parent\n");
 +              dfs_parent = NULL;
 +      }
 +      if (dfs_parent) {
 +              dfs_device_status = debugfs_create_file("device_status",
 +                                      S_IRUGO, dfs_parent, NULL,
 +                                      &mtip_device_status_fops);
 +              if (IS_ERR_OR_NULL(dfs_device_status)) {
 +                      pr_err("Error creating device_status node\n");
 +                      dfs_device_status = NULL;
                }
        }
  
@@@ -52,6 -52,9 +52,9 @@@
  #define MTIP_FTL_REBUILD_MAGIC                0xED51
  #define MTIP_FTL_REBUILD_TIMEOUT_MS   2400000
  
+ /* unaligned IO handling */
+ #define MTIP_MAX_UNALIGNED_SLOTS      8
  /* Macro to extract the tag bit number from a tag value. */
  #define MTIP_TAG_BIT(tag)     (tag & 0x1F)
  
@@@ -129,9 -132,9 +132,9 @@@ enum 
        MTIP_PF_EH_ACTIVE_BIT       = 1, /* error handling */
        MTIP_PF_SE_ACTIVE_BIT       = 2, /* secure erase */
        MTIP_PF_DM_ACTIVE_BIT       = 3, /* download microcde */
 -      MTIP_PF_PAUSE_IO      = ((1 << MTIP_PF_IC_ACTIVE_BIT) | \
 -                              (1 << MTIP_PF_EH_ACTIVE_BIT) | \
 -                              (1 << MTIP_PF_SE_ACTIVE_BIT) | \
 +      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)),
  
        MTIP_PF_SVC_THD_ACTIVE_BIT  = 4,
        MTIP_DDF_REMOVE_PENDING_BIT = 1,
        MTIP_DDF_OVER_TEMP_BIT      = 2,
        MTIP_DDF_WRITE_PROTECT_BIT  = 3,
 -      MTIP_DDF_STOP_IO      = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \
 -                              (1 << MTIP_DDF_SEC_LOCK_BIT) | \
 -                              (1 << MTIP_DDF_OVER_TEMP_BIT) | \
 +      MTIP_DDF_STOP_IO      = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) |
 +                              (1 << MTIP_DDF_SEC_LOCK_BIT) |
 +                              (1 << MTIP_DDF_OVER_TEMP_BIT) |
                                (1 << MTIP_DDF_WRITE_PROTECT_BIT)),
  
        MTIP_DDF_CLEANUP_BIT        = 5,
@@@ -180,7 -183,7 +183,7 @@@ struct mtip_work 
  
  #define MTIP_TRIM_TIMEOUT_MS          240000
  #define MTIP_MAX_TRIM_ENTRIES         8
 -#define MTIP_MAX_TRIM_ENTRY_LEN       0xfff8
 +#define MTIP_MAX_TRIM_ENTRY_LEN               0xfff8
  
  struct mtip_trim_entry {
        u32 lba;   /* starting lba of region */
@@@ -333,6 -336,8 +336,8 @@@ struct mtip_cmd 
  
        int scatter_ents; /* Number of scatter list entries used */
  
+       int unaligned; /* command is unaligned on 4k boundary */
        struct scatterlist sg[MTIP_MAX_SG]; /* Scatter list entries */
  
        int retries; /* The number of retries left for this command. */
@@@ -452,6 -457,10 +457,10 @@@ struct mtip_port 
         * command slots available.
         */
        struct semaphore cmd_slot;
+       /* Semaphore to control queue depth of unaligned IOs */
+       struct semaphore cmd_slot_unal;
        /* Spinlock for working around command-issue bug. */
        spinlock_t cmd_issue_lock[MTIP_MAX_SLOT_GROUPS];
  };
@@@ -502,9 -511,7 +511,11 @@@ struct driver_data 
  
        int isr_binding;
  
+       int unal_qdepth; /* qdepth of unaligned IO queue */
++
 +      struct list_head online_list; /* linkage for online list */
 +
 +      struct list_head remove_list; /* linkage for removing list */
  };
  
  #endif
diff --combined include/linux/idr.h
@@@ -42,7 -42,6 +42,7 @@@ struct idr 
        struct idr_layer        *id_free;
        int                     layers; /* only valid w/o concurrent changes */
        int                     id_free_cnt;
 +      int                     cur;    /* current pos for cyclic allocation */
        spinlock_t              lock;
  };
  
@@@ -76,7 -75,6 +76,7 @@@
  void *idr_find_slowpath(struct idr *idp, int id);
  void idr_preload(gfp_t gfp_mask);
  int idr_alloc(struct idr *idp, void *ptr, int start, int end, gfp_t gfp_mask);
 +int idr_alloc_cyclic(struct idr *idr, void *ptr, int start, int end, gfp_t gfp_mask);
  int idr_for_each(struct idr *idp,
                 int (*fn)(int id, void *p, void *data), void *data);
  void *idr_get_next(struct idr *idp, int *nextid);
@@@ -124,11 -122,13 +124,13 @@@ static inline void *idr_find(struct id
   * @idp:     idr handle
   * @entry:   the type * to use as cursor
   * @id:      id entry's key
+  *
+  * @entry and @id do not need to be initialized before the loop, and
+  * after normal terminatinon @entry is left with the value NULL.  This
+  * is convenient for a "not found" value.
   */
- #define idr_for_each_entry(idp, entry, id)                            \
-       for (id = 0, entry = (typeof(entry))idr_get_next((idp), &(id)); \
-            entry != NULL;                                             \
-            ++id, entry = (typeof(entry))idr_get_next((idp), &(id)))
+ #define idr_for_each_entry(idp, entry, id)                    \
+       for (id = 0; ((entry) = idr_get_next(idp, &(id))) != NULL; ++id)
  
  /*
   * Don't use the following functions.  These exist only to suppress
diff --combined include/linux/sched.h
@@@ -127,6 -127,18 +127,6 @@@ extern void proc_sched_show_task(struc
  extern void proc_sched_set_task(struct task_struct *p);
  extern void
  print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq);
 -#else
 -static inline void
 -proc_sched_show_task(struct task_struct *p, struct seq_file *m)
 -{
 -}
 -static inline void proc_sched_set_task(struct task_struct *p)
 -{
 -}
 -static inline void
 -print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
 -{
 -}
  #endif
  
  /*
  #define TASK_DEAD             64
  #define TASK_WAKEKILL         128
  #define TASK_WAKING           256
 -#define TASK_STATE_MAX                512
 +#define TASK_PARKED           512
 +#define TASK_STATE_MAX                1024
  
 -#define TASK_STATE_TO_CHAR_STR "RSDTtZXxKW"
 +#define TASK_STATE_TO_CHAR_STR "RSDTtZXxKWP"
  
  extern char ___assert_task_state[1 - 2*!!(
                sizeof(TASK_STATE_TO_CHAR_STR)-1 != ilog2(TASK_STATE_MAX)+1)];
@@@ -231,7 -242,7 +231,7 @@@ extern void init_idle_bootup_task(struc
  
  extern int runqueue_is_locked(int cpu);
  
 -#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ)
 +#if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ_COMMON)
  extern void nohz_balance_enter_idle(int cpu);
  extern void set_cpu_sd_state_idle(void);
  extern int get_nohz_timer_target(void);
@@@ -309,10 -320,13 +309,10 @@@ extern signed long schedule_timeout_kil
  extern signed long schedule_timeout_uninterruptible(signed long timeout);
  asmlinkage void schedule(void);
  extern void schedule_preempt_disabled(void);
 -extern int mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner);
  
  struct nsproxy;
  struct user_namespace;
  
 -#include <linux/aio.h>
 -
  #ifdef CONFIG_MMU
  extern void arch_pick_mmap_layout(struct mm_struct *mm);
  extern unsigned long
@@@ -512,8 -526,7 +512,8 @@@ struct signal_struct 
        unsigned int            has_child_subreaper:1;
  
        /* POSIX.1b Interval Timers */
 -      struct list_head posix_timers;
 +      int                     posix_timer_id;
 +      struct list_head        posix_timers;
  
        /* ITIMER_REAL timer for the process */
        struct hrtimer real_timer;
        cputime_t utime, stime, cutime, cstime;
        cputime_t gtime;
        cputime_t cgtime;
 -#ifndef CONFIG_VIRT_CPU_ACCOUNTING
 +#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
        struct cputime prev_cputime;
  #endif
        unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
  #define SIGNAL_STOP_STOPPED   0x00000001 /* job control stop in effect */
  #define SIGNAL_STOP_CONTINUED 0x00000002 /* SIGCONT since WCONTINUED reap */
  #define SIGNAL_GROUP_EXIT     0x00000004 /* group exit in progress */
 +#define SIGNAL_GROUP_COREDUMP 0x00000008 /* coredump in progress */
  /*
   * Pending notifications to parent.
   */
@@@ -756,6 -768,31 +756,6 @@@ enum cpu_idle_type 
  };
  
  /*
 - * Increase resolution of nice-level calculations for 64-bit architectures.
 - * The extra resolution improves shares distribution and load balancing of
 - * low-weight task groups (eg. nice +19 on an autogroup), deeper taskgroup
 - * hierarchies, especially on larger systems. This is not a user-visible change
 - * and does not change the user-interface for setting shares/weights.
 - *
 - * We increase resolution only if we have enough bits to allow this increased
 - * resolution (i.e. BITS_PER_LONG > 32). The costs for increasing resolution
 - * when BITS_PER_LONG <= 32 are pretty high and the returns do not justify the
 - * increased costs.
 - */
 -#if 0 /* BITS_PER_LONG > 32 -- currently broken: it increases power usage under light load  */
 -# define SCHED_LOAD_RESOLUTION        10
 -# define scale_load(w)                ((w) << SCHED_LOAD_RESOLUTION)
 -# define scale_load_down(w)   ((w) >> SCHED_LOAD_RESOLUTION)
 -#else
 -# define SCHED_LOAD_RESOLUTION        0
 -# define scale_load(w)                (w)
 -# define scale_load_down(w)   (w)
 -#endif
 -
 -#define SCHED_LOAD_SHIFT      (10 + SCHED_LOAD_RESOLUTION)
 -#define SCHED_LOAD_SCALE      (1L << SCHED_LOAD_SHIFT)
 -
 -/*
   * Increase resolution of cpu_power calculations
   */
  #define SCHED_POWER_SHIFT     10
  
  extern int __weak arch_sd_sibiling_asym_packing(void);
  
 -struct sched_group_power {
 -      atomic_t ref;
 -      /*
 -       * CPU power of this group, SCHED_LOAD_SCALE being max power for a
 -       * single CPU.
 -       */
 -      unsigned int power, power_orig;
 -      unsigned long next_update;
 -      /*
 -       * Number of busy cpus in this group.
 -       */
 -      atomic_t nr_busy_cpus;
 -
 -      unsigned long cpumask[0]; /* iteration mask */
 -};
 -
 -struct sched_group {
 -      struct sched_group *next;       /* Must be a circular list */
 -      atomic_t ref;
 -
 -      unsigned int group_weight;
 -      struct sched_group_power *sgp;
 -
 -      /*
 -       * The CPUs this group covers.
 -       *
 -       * NOTE: this field is variable length. (Allocated dynamically
 -       * by attaching extra space to the end of the structure,
 -       * depending on how many CPUs the kernel has booted up with)
 -       */
 -      unsigned long cpumask[0];
 -};
 -
 -static inline struct cpumask *sched_group_cpus(struct sched_group *sg)
 -{
 -      return to_cpumask(sg->cpumask);
 -}
 -
 -/*
 - * cpumask masking which cpus in the group are allowed to iterate up the domain
 - * tree.
 - */
 -static inline struct cpumask *sched_group_mask(struct sched_group *sg)
 -{
 -      return to_cpumask(sg->sgp->cpumask);
 -}
 -
 -/**
 - * group_first_cpu - Returns the first cpu in the cpumask of a sched_group.
 - * @group: The group whose first cpu is to be returned.
 - */
 -static inline unsigned int group_first_cpu(struct sched_group *group)
 -{
 -      return cpumask_first(sched_group_cpus(group));
 -}
 -
  struct sched_domain_attr {
        int relax_domain_level;
  };
  
  extern int sched_domain_level_max;
  
 +struct sched_group;
 +
  struct sched_domain {
        /* These fields must be setup */
        struct sched_domain *parent;    /* top domain must be null terminated */
        unsigned int wake_idx;
        unsigned int forkexec_idx;
        unsigned int smt_gain;
 +
 +      int nohz_idle;                  /* NOHZ IDLE status */
        int flags;                      /* See SD_* */
        int level;
  
@@@ -882,6 -971,18 +882,6 @@@ extern void partition_sched_domains(in
  cpumask_var_t *alloc_sched_domains(unsigned int ndoms);
  void free_sched_domains(cpumask_var_t doms[], unsigned int ndoms);
  
 -/* Test a flag in parent sched domain */
 -static inline int test_sd_parent(struct sched_domain *sd, int flag)
 -{
 -      if (sd->parent && (sd->parent->flags & flag))
 -              return 1;
 -
 -      return 0;
 -}
 -
 -unsigned long default_scale_freq_power(struct sched_domain *sd, int cpu);
 -unsigned long default_scale_smt_power(struct sched_domain *sd, int cpu);
 -
  bool cpus_share_cache(int this_cpu, int that_cpu);
  
  #else /* CONFIG_SMP */
@@@ -916,6 -1017,72 +916,6 @@@ struct mempolicy
  struct pipe_inode_info;
  struct uts_namespace;
  
 -struct rq;
 -struct sched_domain;
 -
 -/*
 - * wake flags
 - */
 -#define WF_SYNC               0x01            /* waker goes to sleep after wakup */
 -#define WF_FORK               0x02            /* child wakeup after fork */
 -#define WF_MIGRATED   0x04            /* internal use, task got migrated */
 -
 -#define ENQUEUE_WAKEUP                1
 -#define ENQUEUE_HEAD          2
 -#ifdef CONFIG_SMP
 -#define ENQUEUE_WAKING                4       /* sched_class::task_waking was called */
 -#else
 -#define ENQUEUE_WAKING                0
 -#endif
 -
 -#define DEQUEUE_SLEEP         1
 -
 -struct sched_class {
 -      const struct sched_class *next;
 -
 -      void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags);
 -      void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags);
 -      void (*yield_task) (struct rq *rq);
 -      bool (*yield_to_task) (struct rq *rq, struct task_struct *p, bool preempt);
 -
 -      void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int flags);
 -
 -      struct task_struct * (*pick_next_task) (struct rq *rq);
 -      void (*put_prev_task) (struct rq *rq, struct task_struct *p);
 -
 -#ifdef CONFIG_SMP
 -      int  (*select_task_rq)(struct task_struct *p, int sd_flag, int flags);
 -      void (*migrate_task_rq)(struct task_struct *p, int next_cpu);
 -
 -      void (*pre_schedule) (struct rq *this_rq, struct task_struct *task);
 -      void (*post_schedule) (struct rq *this_rq);
 -      void (*task_waking) (struct task_struct *task);
 -      void (*task_woken) (struct rq *this_rq, struct task_struct *task);
 -
 -      void (*set_cpus_allowed)(struct task_struct *p,
 -                               const struct cpumask *newmask);
 -
 -      void (*rq_online)(struct rq *rq);
 -      void (*rq_offline)(struct rq *rq);
 -#endif
 -
 -      void (*set_curr_task) (struct rq *rq);
 -      void (*task_tick) (struct rq *rq, struct task_struct *p, int queued);
 -      void (*task_fork) (struct task_struct *p);
 -
 -      void (*switched_from) (struct rq *this_rq, struct task_struct *task);
 -      void (*switched_to) (struct rq *this_rq, struct task_struct *task);
 -      void (*prio_changed) (struct rq *this_rq, struct task_struct *task,
 -                           int oldprio);
 -
 -      unsigned int (*get_rr_interval) (struct rq *rq,
 -                                       struct task_struct *task);
 -
 -#ifdef CONFIG_FAIR_GROUP_SCHED
 -      void (*task_move_group) (struct task_struct *p, int on_rq);
 -#endif
 -};
 -
  struct load_weight {
        unsigned long weight, inv_weight;
  };
@@@ -1107,10 -1274,8 +1107,10 @@@ struct task_struct 
        int exit_code, exit_signal;
        int pdeath_signal;  /*  The signal sent when the parent dies  */
        unsigned int jobctl;    /* JOBCTL_*, siglock protected */
 -      /* ??? */
 +
 +      /* Used for emulating ABI behavior of previous Linux versions */
        unsigned int personality;
 +
        unsigned did_exec:1;
        unsigned in_execve:1;   /* Tell the LSMs that the process is doing an
                                 * execve */
  
        cputime_t utime, stime, utimescaled, stimescaled;
        cputime_t gtime;
 -#ifndef CONFIG_VIRT_CPU_ACCOUNTING
 +#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
        struct cputime prev_cputime;
  #endif
  #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
  #ifdef CONFIG_UPROBES
        struct uprobe_task *utask;
  #endif
+ #if defined(CONFIG_BCACHE) || defined(CONFIG_BCACHE_MODULE)
+       unsigned int    sequential_io;
+       unsigned int    sequential_io_avg;
+ #endif
  };
  
  /* Future-safe accessor for struct task_struct's cpus_allowed. */
@@@ -1628,7 -1797,7 +1632,7 @@@ extern void thread_group_cputime_adjust
  #define PF_SWAPWRITE  0x00800000      /* Allowed to write to swap */
  #define PF_SPREAD_PAGE        0x01000000      /* Spread page cache over cpuset */
  #define PF_SPREAD_SLAB        0x02000000      /* Spread some slab caches over cpuset */
 -#define PF_THREAD_BOUND       0x04000000      /* Thread bound to specific cpu */
 +#define PF_NO_SETAFFINITY 0x04000000  /* Userland is not allowed to meddle with cpus_allowed */
  #define PF_MCE_EARLY    0x08000000      /* Early kill for mce process policy */
  #define PF_MEMPOLICY  0x10000000      /* Non-default NUMA mempolicy */
  #define PF_MUTEX_TESTER       0x20000000      /* Thread belongs to the rt mutex tester */
@@@ -1762,13 -1931,13 +1766,13 @@@ static inline int set_cpus_allowed_ptr(
  }
  #endif
  
 -#ifdef CONFIG_NO_HZ
 +#ifdef CONFIG_NO_HZ_COMMON
  void calc_load_enter_idle(void);
  void calc_load_exit_idle(void);
  #else
  static inline void calc_load_enter_idle(void) { }
  static inline void calc_load_exit_idle(void) { }
 -#endif /* CONFIG_NO_HZ */
 +#endif /* CONFIG_NO_HZ_COMMON */
  
  #ifndef CONFIG_CPUMASK_OFFSTACK
  static inline int set_cpus_allowed(struct task_struct *p, cpumask_t new_mask)
@@@ -1854,17 -2023,10 +1858,17 @@@ extern void idle_task_exit(void)
  static inline void idle_task_exit(void) {}
  #endif
  
 -#if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP)
 -extern void wake_up_idle_cpu(int cpu);
 +#if defined(CONFIG_NO_HZ_COMMON) && defined(CONFIG_SMP)
 +extern void wake_up_nohz_cpu(int cpu);
 +#else
 +static inline void wake_up_nohz_cpu(int cpu) { }
 +#endif
 +
 +#ifdef CONFIG_NO_HZ_FULL
 +extern bool sched_can_stop_tick(void);
 +extern u64 scheduler_tick_max_deferment(void);
  #else
 -static inline void wake_up_idle_cpu(int cpu) { }
 +static inline bool sched_can_stop_tick(void) { return false; }
  #endif
  
  #ifdef CONFIG_SCHED_AUTOGROUP
@@@ -2254,18 -2416,27 +2258,18 @@@ static inline void threadgroup_change_e
   *
   * Lock the threadgroup @tsk belongs to.  No new task is allowed to enter
   * and member tasks aren't allowed to exit (as indicated by PF_EXITING) or
 - * perform exec.  This is useful for cases where the threadgroup needs to
 - * stay stable across blockable operations.
 + * change ->group_leader/pid.  This is useful for cases where the threadgroup
 + * needs to stay stable across blockable operations.
   *
   * fork and exit paths explicitly call threadgroup_change_{begin|end}() for
   * synchronization.  While held, no new task will be added to threadgroup
   * and no existing live task will have its PF_EXITING set.
   *
 - * During exec, a task goes and puts its thread group through unusual
 - * changes.  After de-threading, exclusive access is assumed to resources
 - * which are usually shared by tasks in the same group - e.g. sighand may
 - * be replaced with a new one.  Also, the exec'ing task takes over group
 - * leader role including its pid.  Exclude these changes while locked by
 - * grabbing cred_guard_mutex which is used to synchronize exec path.
 + * de_thread() does threadgroup_change_{begin|end}() when a non-leader
 + * sub-thread becomes a new leader.
   */
  static inline void threadgroup_lock(struct task_struct *tsk)
  {
 -      /*
 -       * exec uses exit for de-threading nesting group_rwsem inside
 -       * cred_guard_mutex. Grab cred_guard_mutex first.
 -       */
 -      mutex_lock(&tsk->signal->cred_guard_mutex);
        down_write(&tsk->signal->group_rwsem);
  }
  
  static inline void threadgroup_unlock(struct task_struct *tsk)
  {
        up_write(&tsk->signal->group_rwsem);
 -      mutex_unlock(&tsk->signal->cred_guard_mutex);
  }
  #else
  static inline void threadgroup_change_begin(struct task_struct *tsk) {}
@@@ -2454,47 -2626,6 +2458,47 @@@ static inline int spin_needbreak(spinlo
  }
  
  /*
 + * Idle thread specific functions to determine the need_resched
 + * polling state. We have two versions, one based on TS_POLLING in
 + * thread_info.status and one based on TIF_POLLING_NRFLAG in
 + * thread_info.flags
 + */
 +#ifdef TS_POLLING
 +static inline int tsk_is_polling(struct task_struct *p)
 +{
 +      return task_thread_info(p)->status & TS_POLLING;
 +}
 +static inline void current_set_polling(void)
 +{
 +      current_thread_info()->status |= TS_POLLING;
 +}
 +
 +static inline void current_clr_polling(void)
 +{
 +      current_thread_info()->status &= ~TS_POLLING;
 +      smp_mb__after_clear_bit();
 +}
 +#elif defined(TIF_POLLING_NRFLAG)
 +static inline int tsk_is_polling(struct task_struct *p)
 +{
 +      return test_tsk_thread_flag(p, TIF_POLLING_NRFLAG);
 +}
 +static inline void current_set_polling(void)
 +{
 +      set_thread_flag(TIF_POLLING_NRFLAG);
 +}
 +
 +static inline void current_clr_polling(void)
 +{
 +      clear_thread_flag(TIF_POLLING_NRFLAG);
 +}
 +#else
 +static inline int tsk_is_polling(struct task_struct *p) { return 0; }
 +static inline void current_set_polling(void) { }
 +static inline void current_clr_polling(void) { }
 +#endif
 +
 +/*
   * Thread group CPU time accounting.
   */
  void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times);
@@@ -2554,7 -2685,28 +2558,7 @@@ extern long sched_setaffinity(pid_t pid
  extern long sched_getaffinity(pid_t pid, struct cpumask *mask);
  
  #ifdef CONFIG_CGROUP_SCHED
 -
  extern struct task_group root_task_group;
 -
 -extern struct task_group *sched_create_group(struct task_group *parent);
 -extern void sched_online_group(struct task_group *tg,
 -                             struct task_group *parent);
 -extern void sched_destroy_group(struct task_group *tg);
 -extern void sched_offline_group(struct task_group *tg);
 -extern void sched_move_task(struct task_struct *tsk);
 -#ifdef CONFIG_FAIR_GROUP_SCHED
 -extern int sched_group_set_shares(struct task_group *tg, unsigned long shares);
 -extern unsigned long sched_group_shares(struct task_group *tg);
 -#endif
 -#ifdef CONFIG_RT_GROUP_SCHED
 -extern int sched_group_set_rt_runtime(struct task_group *tg,
 -                                    long rt_runtime_us);
 -extern long sched_group_rt_runtime(struct task_group *tg);
 -extern int sched_group_set_rt_period(struct task_group *tg,
 -                                    long rt_period_us);
 -extern long sched_group_rt_period(struct task_group *tg);
 -extern int sched_rt_can_attach(struct task_group *tg, struct task_struct *tsk);
 -#endif
  #endif /* CONFIG_CGROUP_SCHED */
  
  extern int task_can_switch_user(struct user_struct *up,
diff --combined kernel/fork.c
@@@ -70,7 -70,6 +70,7 @@@
  #include <linux/khugepaged.h>
  #include <linux/signalfd.h>
  #include <linux/uprobes.h>
 +#include <linux/aio.h>
  
  #include <asm/pgtable.h>
  #include <asm/pgalloc.h>
@@@ -1234,7 -1233,7 +1234,7 @@@ static struct task_struct *copy_process
  
        p->utime = p->stime = p->gtime = 0;
        p->utimescaled = p->stimescaled = 0;
 -#ifndef CONFIG_VIRT_CPU_ACCOUNTING
 +#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
        p->prev_cputime.utime = p->prev_cputime.stime = 0;
  #endif
  #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
        p->memcg_batch.do_batch = 0;
        p->memcg_batch.memcg = NULL;
  #endif
+ #ifdef CONFIG_BCACHE
+       p->sequential_io        = 0;
+       p->sequential_io_avg    = 0;
+ #endif
  
        /* Perform scheduler related setup. Assign this task to a CPU. */
        sched_fork(p);
@@@ -1678,7 -1681,10 +1682,7 @@@ SYSCALL_DEFINE5(clone, unsigned long, c
                 int, tls_val)
  #endif
  {
 -      long ret = do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr);
 -      asmlinkage_protect(5, ret, clone_flags, newsp,
 -                      parent_tidptr, child_tidptr, tls_val);
 -      return ret;
 +      return do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr);
  }
  #endif
  
diff --combined kernel/lockdep.c
@@@ -380,13 -380,6 +380,13 @@@ static int verbose(struct lock_class *c
  unsigned long nr_stack_trace_entries;
  static unsigned long stack_trace[MAX_STACK_TRACE_ENTRIES];
  
 +static void print_lockdep_off(const char *bug_msg)
 +{
 +      printk(KERN_DEBUG "%s\n", bug_msg);
 +      printk(KERN_DEBUG "turning off the locking correctness validator.\n");
 +      printk(KERN_DEBUG "Please attach the output of /proc/lock_stat to the bug report\n");
 +}
 +
  static int save_trace(struct stack_trace *trace)
  {
        trace->nr_entries = 0;
                if (!debug_locks_off_graph_unlock())
                        return 0;
  
 -              printk("BUG: MAX_STACK_TRACE_ENTRIES too low!\n");
 -              printk("turning off the locking correctness validator.\n");
 +              print_lockdep_off("BUG: MAX_STACK_TRACE_ENTRIES too low!");
                dump_stack();
  
                return 0;
@@@ -769,7 -763,8 +769,7 @@@ register_lock_class(struct lockdep_map 
                }
                raw_local_irq_restore(flags);
  
 -              printk("BUG: MAX_LOCKDEP_KEYS too low!\n");
 -              printk("turning off the locking correctness validator.\n");
 +              print_lockdep_off("BUG: MAX_LOCKDEP_KEYS too low!");
                dump_stack();
                return NULL;
        }
@@@ -839,7 -834,8 +839,7 @@@ static struct lock_list *alloc_list_ent
                if (!debug_locks_off_graph_unlock())
                        return NULL;
  
 -              printk("BUG: MAX_LOCKDEP_ENTRIES too low!\n");
 -              printk("turning off the locking correctness validator.\n");
 +              print_lockdep_off("BUG: MAX_LOCKDEP_ENTRIES too low!");
                dump_stack();
                return NULL;
        }
@@@ -2004,7 -2000,7 +2004,7 @@@ static inline int lookup_chain_cache(st
        struct lock_class *class = hlock_class(hlock);
        struct list_head *hash_head = chainhashentry(chain_key);
        struct lock_chain *chain;
 -      struct held_lock *hlock_curr, *hlock_next;
 +      struct held_lock *hlock_curr;
        int i, j;
  
        /*
@@@ -2052,7 -2048,8 +2052,7 @@@ cache_hit
                if (!debug_locks_off_graph_unlock())
                        return 0;
  
 -              printk("BUG: MAX_LOCKDEP_CHAINS too low!\n");
 -              printk("turning off the locking correctness validator.\n");
 +              print_lockdep_off("BUG: MAX_LOCKDEP_CHAINS too low!");
                dump_stack();
                return 0;
        }
        chain->chain_key = chain_key;
        chain->irq_context = hlock->irq_context;
        /* Find the first held_lock of current chain */
 -      hlock_next = hlock;
        for (i = curr->lockdep_depth - 1; i >= 0; i--) {
                hlock_curr = curr->held_locks + i;
 -              if (hlock_curr->irq_context != hlock_next->irq_context)
 +              if (hlock_curr->irq_context != hlock->irq_context)
                        break;
 -              hlock_next = hlock;
        }
        i++;
        chain->depth = curr->lockdep_depth + 1 - i;
@@@ -2998,6 -2997,7 +2998,7 @@@ void lockdep_init_map(struct lockdep_ma
  EXPORT_SYMBOL_GPL(lockdep_init_map);
  
  struct lock_class_key __lockdep_no_validate__;
+ EXPORT_SYMBOL_GPL(__lockdep_no_validate__);
  
  static int
  print_lock_nested_lock_not_held(struct task_struct *curr,
@@@ -3191,9 -3191,9 +3192,9 @@@ static int __lock_acquire(struct lockde
  #endif
        if (unlikely(curr->lockdep_depth >= MAX_LOCK_DEPTH)) {
                debug_locks_off();
 -              printk("BUG: MAX_LOCK_DEPTH too low, depth: %i  max: %lu!\n",
 +              print_lockdep_off("BUG: MAX_LOCK_DEPTH too low!");
 +              printk(KERN_DEBUG "depth: %i  max: %lu!\n",
                       curr->lockdep_depth, MAX_LOCK_DEPTH);
 -              printk("turning off the locking correctness validator.\n");
  
                lockdep_print_held_locks(current);
                debug_show_all_locks();
@@@ -4089,7 -4089,7 +4090,7 @@@ void debug_check_no_locks_freed(const v
  }
  EXPORT_SYMBOL_GPL(debug_check_no_locks_freed);
  
 -static void print_held_locks_bug(void)
 +static void print_held_locks_bug(struct task_struct *curr)
  {
        if (!debug_locks_off())
                return;
  
        printk("\n");
        printk("=====================================\n");
 -      printk("[ BUG: %s/%d still has locks held! ]\n",
 -             current->comm, task_pid_nr(current));
 +      printk("[ BUG: lock held at task exit time! ]\n");
        print_kernel_ident();
        printk("-------------------------------------\n");
 -      lockdep_print_held_locks(current);
 +      printk("%s/%d is exiting with locks still held!\n",
 +              curr->comm, task_pid_nr(curr));
 +      lockdep_print_held_locks(curr);
 +
        printk("\nstack backtrace:\n");
        dump_stack();
  }
  
 -void debug_check_no_locks_held(void)
 +void debug_check_no_locks_held(struct task_struct *task)
  {
 -      if (unlikely(current->lockdep_depth > 0))
 -              print_held_locks_bug();
 +      if (unlikely(task->lockdep_depth > 0))
 +              print_held_locks_bug(task);
  }
 -EXPORT_SYMBOL_GPL(debug_check_no_locks_held);
  
  void debug_show_all_locks(void)
  {
diff --combined kernel/trace/blktrace.c
@@@ -72,7 -72,7 +72,7 @@@ static void trace_note(struct blk_trac
        bool blk_tracer = blk_tracer_enabled;
  
        if (blk_tracer) {
 -              buffer = blk_tr->buffer;
 +              buffer = blk_tr->trace_buffer.buffer;
                pc = preempt_count();
                event = trace_buffer_lock_reserve(buffer, TRACE_BLK,
                                                  sizeof(*t) + len,
@@@ -218,7 -218,7 +218,7 @@@ static void __blk_add_trace(struct blk_
        if (blk_tracer) {
                tracing_record_cmdline(current);
  
 -              buffer = blk_tr->buffer;
 +              buffer = blk_tr->trace_buffer.buffer;
                pc = preempt_count();
                event = trace_buffer_lock_reserve(buffer, TRACE_BLK,
                                                  sizeof(*t) + pdu_len,
@@@ -739,6 -739,12 +739,6 @@@ static void blk_add_trace_rq_complete(v
                                      struct request_queue *q,
                                      struct request *rq)
  {
 -      struct blk_trace *bt = q->blk_trace;
 -
 -      /* if control ever passes through here, it's a request based driver */
 -      if (unlikely(bt && !bt->rq_based))
 -              bt->rq_based = true;
 -
        blk_add_trace_rq(q, rq, BLK_TA_COMPLETE);
  }
  
@@@ -774,10 -780,24 +774,10 @@@ static void blk_add_trace_bio_bounce(vo
        blk_add_trace_bio(q, bio, BLK_TA_BOUNCE, 0);
  }
  
 -static void blk_add_trace_bio_complete(void *ignore, struct bio *bio, int error)
 +static void blk_add_trace_bio_complete(void *ignore,
 +                                     struct request_queue *q, struct bio *bio,
 +                                     int error)
  {
 -      struct request_queue *q;
 -      struct blk_trace *bt;
 -
 -      if (!bio->bi_bdev)
 -              return;
 -
 -      q = bdev_get_queue(bio->bi_bdev);
 -      bt = q->blk_trace;
 -
 -      /*
 -       * Request based drivers will generate both rq and bio completions.
 -       * Ignore bio ones.
 -       */
 -      if (likely(!bt) || bt->rq_based)
 -              return;
 -
        blk_add_trace_bio(q, bio, BLK_TA_COMPLETE, error);
  }
  
@@@ -1808,6 -1828,7 +1808,7 @@@ void blk_fill_rwbs(char *rwbs, u32 rw, 
  
        rwbs[i] = '\0';
  }
+ EXPORT_SYMBOL_GPL(blk_fill_rwbs);
  
  #endif /* CONFIG_EVENT_TRACING */