Merge ../linux-2.6
authorPaul Mackerras <paulus@samba.org>
Wed, 2 Nov 2005 04:20:55 +0000 (15:20 +1100)
committerPaul Mackerras <paulus@samba.org>
Wed, 2 Nov 2005 04:20:55 +0000 (15:20 +1100)
241 files changed:
Documentation/filesystems/ntfs.txt
arch/arm/common/locomo.c
arch/arm/common/sa1111.c
arch/arm/common/scoop.c
arch/arm/mach-aaec2000/core.c
arch/arm/mach-h720x/h7202-eval.c
arch/arm/mach-imx/generic.c
arch/arm/mach-imx/mx1ads.c
arch/arm/mach-integrator/integrator_ap.c
arch/arm/mach-integrator/integrator_cp.c
arch/arm/mach-iop3xx/iop321-setup.c
arch/arm/mach-iop3xx/iop331-setup.c
arch/arm/mach-ixp2000/enp2611.c
arch/arm/mach-ixp2000/ixdp2x00.c
arch/arm/mach-ixp2000/ixdp2x01.c
arch/arm/mach-ixp4xx/common.c
arch/arm/mach-lh7a40x/arch-lpd7a40x.c
arch/arm/mach-omap1/board-h2.c
arch/arm/mach-omap1/board-h3.c
arch/arm/mach-omap1/board-innovator.c
arch/arm/mach-omap1/board-netstar.c
arch/arm/mach-omap1/board-osk.c
arch/arm/mach-omap1/board-perseus2.c
arch/arm/mach-omap1/board-voiceblue.c
arch/arm/mach-omap1/devices.c
arch/arm/mach-pxa/corgi.c
arch/arm/mach-pxa/corgi_lcd.c
arch/arm/mach-pxa/corgi_ssp.c
arch/arm/mach-pxa/generic.c
arch/arm/mach-pxa/idp.c
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-pxa/poodle.c
arch/arm/mach-pxa/pxa27x.c
arch/arm/mach-pxa/spitz.c
arch/arm/mach-s3c2410/clock.c
arch/arm/mach-s3c2410/cpu.c
arch/arm/mach-s3c2410/devs.c
arch/arm/mach-s3c2410/devs.h
arch/arm/mach-s3c2410/mach-anubis.c
arch/arm/mach-s3c2410/mach-bast.c
arch/arm/mach-s3c2410/mach-h1940.c
arch/arm/mach-s3c2410/mach-n30.c
arch/arm/mach-s3c2410/mach-nexcoder.c
arch/arm/mach-s3c2410/mach-otom.c
arch/arm/mach-s3c2410/mach-rx3715.c
arch/arm/mach-s3c2410/mach-smdk2410.c
arch/arm/mach-s3c2410/mach-smdk2440.c
arch/arm/mach-s3c2410/s3c2410.c
arch/arm/mach-s3c2410/s3c2440.c
arch/arm/mach-sa1100/badge4.c
arch/arm/mach-sa1100/cerf.c
arch/arm/mach-sa1100/collie.c
arch/arm/mach-sa1100/generic.c
arch/arm/mach-sa1100/jornada720.c
arch/arm/mach-sa1100/neponset.c
arch/arm/mach-sa1100/pleb.c
arch/arm/mach-sa1100/simpad.c
arch/arm/mach-versatile/core.c
arch/arm/plat-omap/usb.c
arch/i386/Kconfig
arch/i386/kernel/apic.c
arch/i386/kernel/i8259.c
arch/i386/kernel/io_apic.c
arch/i386/kernel/smpboot.c
arch/i386/kernel/time.c
arch/m32r/kernel/setup_m32700ut.c
arch/m32r/kernel/setup_mappi.c
arch/m32r/kernel/setup_mappi2.c
arch/m32r/kernel/setup_mappi3.c
arch/m32r/kernel/setup_opsput.c
arch/mips/au1000/common/platform.c
arch/ppc/platforms/4xx/ibm440ep.c
arch/ppc/platforms/4xx/ibmstb4.c
arch/ppc/platforms/4xx/redwood5.c
arch/ppc/platforms/4xx/redwood6.c
arch/ppc/platforms/chrp_pegasos_eth.c
arch/ppc/platforms/cpci690.c
arch/ppc/platforms/ev64260.c
arch/ppc/platforms/ev64360.c
arch/ppc/platforms/hdpu.c
arch/ppc/platforms/katana.c
arch/ppc/platforms/radstone_ppc7d.c
arch/ppc/syslib/mpc52xx_devices.c
arch/ppc/syslib/mv64x60.c
arch/ppc/syslib/pq2_devices.c
arch/sh/boards/superh/microdev/setup.c
arch/um/drivers/net_kern.c
arch/um/drivers/ubd_kern.c
arch/xtensa/platform-iss/network.c
drivers/base/platform.c
drivers/block/cfq-iosched.c
drivers/block/floppy.c
drivers/block/noop-iosched.c
drivers/char/s3c2410-rtc.c
drivers/char/sonypi.c
drivers/char/tb0219.c
drivers/char/vr41xx_giu.c
drivers/char/vr41xx_rtc.c
drivers/char/watchdog/mpcore_wdt.c
drivers/char/watchdog/mv64x60_wdt.c
drivers/char/watchdog/s3c2410_wdt.c
drivers/eisa/virtual_root.c
drivers/firmware/dcdbas.c
drivers/firmware/dell_rbu.c
drivers/hwmon/hdaps.c
drivers/i2c/busses/i2c-iop3xx.c
drivers/i2c/busses/i2c-isa.c
drivers/i2c/busses/i2c-ixp2000.c
drivers/i2c/busses/i2c-ixp4xx.c
drivers/i2c/busses/i2c-mpc.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-pxa.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/chips/isp1301_omap.c
drivers/i2c/i2c-core.c
drivers/i2c/i2c-dev.c
drivers/input/evdev.c
drivers/input/input.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/corgikbd.c
drivers/input/keyboard/lkkbd.c
drivers/input/keyboard/spitzkbd.c
drivers/input/misc/pcspkr.c
drivers/input/mouse/Kconfig
drivers/input/serio/ct82c710.c
drivers/input/serio/i8042.c
drivers/input/serio/maceps2.c
drivers/input/serio/q40kbd.c
drivers/input/serio/rpckbd.c
drivers/input/touchscreen/corgi_ts.c
drivers/macintosh/adbhid.c
drivers/mfd/mcp-sa11x0.c
drivers/misc/hdpuftrs/hdpu_cpustate.c
drivers/misc/hdpuftrs/hdpu_nexus.c
drivers/mmc/pxamci.c
drivers/mmc/wbsd.c
drivers/mtd/maps/bast-flash.c
drivers/mtd/maps/integrator-flash.c
drivers/mtd/maps/ixp2000.c
drivers/mtd/maps/ixp4xx.c
drivers/mtd/maps/omap_nor.c
drivers/mtd/maps/plat-ram.c
drivers/mtd/maps/sa1100-flash.c
drivers/mtd/nand/s3c2410.c
drivers/net/depca.c
drivers/net/dm9000.c
drivers/net/gianfar.c
drivers/net/gianfar_mii.c
drivers/net/irda/pxaficp_ir.c
drivers/net/irda/sa1100_ir.c
drivers/net/irda/smsc-ircc2.c
drivers/net/jazzsonic.c
drivers/net/macsonic.c
drivers/net/mipsnet.c
drivers/net/mv643xx_eth.c
drivers/net/smc91x.c
drivers/net/tokenring/proteon.c
drivers/net/tokenring/skisa.c
drivers/pcmcia/au1000_generic.c
drivers/pcmcia/hd64465_ss.c
drivers/pcmcia/i82365.c
drivers/pcmcia/m32r_cfc.c
drivers/pcmcia/m32r_pcc.c
drivers/pcmcia/omap_cf.c
drivers/pcmcia/pxa2xx_base.c
drivers/pcmcia/pxa2xx_mainstone.c
drivers/pcmcia/pxa2xx_sharpsl.c
drivers/pcmcia/sa1100_generic.c
drivers/pcmcia/tcic.c
drivers/pcmcia/vrc4171_card.c
drivers/scsi/hosts.c
drivers/scsi/ide-scsi.c
drivers/scsi/libata-core.c
drivers/scsi/libata-scsi.c
drivers/scsi/libata.h
drivers/serial/8250.c
drivers/serial/imx.c
drivers/serial/mpc52xx_uart.c
drivers/serial/mpsc.c
drivers/serial/pxa.c
drivers/serial/s3c2410.c
drivers/serial/sa1100.c
drivers/serial/vr41xx_siu.c
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/lh7a40x_udc.c
drivers/usb/gadget/omap_udc.c
drivers/usb/gadget/pxa2xx_udc.c
drivers/usb/host/isp116x-hcd.c
drivers/usb/host/ohci-au1xxx.c
drivers/usb/host/ohci-lh7a404.c
drivers/usb/host/ohci-omap.c
drivers/usb/host/ohci-ppc-soc.c
drivers/usb/host/ohci-pxa27x.c
drivers/usb/host/ohci-s3c2410.c
drivers/usb/host/pci-quirks.c
drivers/usb/host/sl811-hcd.c
drivers/usb/host/sl811_cs.c
drivers/video/acornfb.c
drivers/video/arcfb.c
drivers/video/backlight/corgi_bl.c
drivers/video/dnfb.c
drivers/video/epson1355fb.c
drivers/video/gbefb.c
drivers/video/imxfb.c
drivers/video/pxafb.c
drivers/video/q40fb.c
drivers/video/s1d13xxxfb.c
drivers/video/s3c2410fb.c
drivers/video/sa1100fb.c
drivers/video/sgivwfb.c
drivers/video/vesafb.c
drivers/video/vfb.c
drivers/video/w100fb.c
fs/fs-writeback.c
fs/ntfs/ChangeLog
fs/ntfs/Makefile
fs/ntfs/aops.c
fs/ntfs/attrib.c
fs/ntfs/attrib.h
fs/ntfs/file.c
fs/ntfs/inode.c
fs/ntfs/layout.h
fs/ntfs/lcnalloc.c
fs/ntfs/lcnalloc.h
fs/ntfs/malloc.h
fs/ntfs/mft.c
fs/ntfs/super.c
include/asm-i386/apic.h
include/asm-i386/hw_irq.h
include/asm-i386/mach-default/smpboot_hooks.h
include/asm-i386/mach-visws/smpboot_hooks.h
include/asm-ppc/ppc_sys.h
include/linux/device.h
include/linux/platform_device.h [new file with mode: 0644]
include/linux/serial_8250.h
include/sound/emu10k1.h
init/main.c
sound/arm/pxa2xx-ac97.c
sound/core/init.c
sound/pci/emu10k1/emu10k1_main.c

index a5fbc8e897fa6f2f4a768241c66372de7b3366e7..614de31249019d6ab29d0f59a0fccb90c971e5e1 100644 (file)
@@ -50,9 +50,14 @@ userspace utilities, etc.
 Features
 ========
 
-- This is a complete rewrite of the NTFS driver that used to be in the kernel.
-  This new driver implements NTFS read support and is functionally equivalent
-  to the old ntfs driver.
+- This is a complete rewrite of the NTFS driver that used to be in the 2.4 and
+  earlier kernels.  This new driver implements NTFS read support and is
+  functionally equivalent to the old ntfs driver and it also implements limited
+  write support.  The biggest limitation at present is that files/directories
+  cannot be created or deleted.  See below for the list of write features that
+  are so far supported.  Another limitation is that writing to compressed files
+  is not implemented at all.  Also, neither read nor write access to encrypted
+  files is so far implemented.
 - The new driver has full support for sparse files on NTFS 3.x volumes which
   the old driver isn't happy with.
 - The new driver supports execution of binaries due to mmap() now being
@@ -78,7 +83,20 @@ Features
 - The new driver supports fsync(2), fdatasync(2), and msync(2).
 - The new driver supports readv(2) and writev(2).
 - The new driver supports access time updates (including mtime and ctime).
-
+- The new driver supports truncate(2) and open(2) with O_TRUNC.  But at present
+  only very limited support for highly fragmented files, i.e. ones which have
+  their data attribute split across multiple extents, is included.  Another
+  limitation is that at present truncate(2) will never create sparse files,
+  since to mark a file sparse we need to modify the directory entry for the
+  file and we do not implement directory modifications yet.
+- The new driver supports write(2) which can both overwrite existing data and
+  extend the file size so that you can write beyond the existing data.  Also,
+  writing into sparse regions is supported and the holes are filled in with
+  clusters.  But at present only limited support for highly fragmented files,
+  i.e. ones which have their data attribute split across multiple extents, is
+  included.  Another limitation is that write(2) will never create sparse
+  files, since to mark a file sparse we need to modify the directory entry for
+  the file and we do not implement directory modifications yet.
 
 Supported mount options
 =======================
@@ -439,6 +457,22 @@ ChangeLog
 
 Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
 
+2.1.25:
+       - Write support is now extended with write(2) being able to both
+         overwrite existing file data and to extend files.  Also, if a write
+         to a sparse region occurs, write(2) will fill in the hole.  Note,
+         mmap(2) based writes still do not support writing into holes or
+         writing beyond the initialized size.
+       - Write support has a new feature and that is that truncate(2) and
+         open(2) with O_TRUNC are now implemented thus files can be both made
+         smaller and larger.
+       - Note: Both write(2) and truncate(2)/open(2) with O_TRUNC still have
+         limitations in that they
+         - only provide limited support for highly fragmented files.
+         - only work on regular, i.e. uncompressed and unencrypted files.
+         - never create sparse files although this will change once directory
+           operations are implemented.
+       - Lots of bug fixes and enhancements across the board.
 2.1.24:
        - Support journals ($LogFile) which have been modified by chkdsk.  This
          means users can boot into Windows after we marked the volume dirty.
index 5cdb4122f057ca64874024d50b1750f9375cb649..ad55680726ed5b10fac7efb9852d9294d940cf26 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 
index 21e2a518ad3ab71c85edf68e47468e04666d1866..174aa86ee816b49b2e41dcd2e2cfca64b2c3abbf 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/dma-mapping.h>
index 4af0cf5f3bfbc8d4f8fce84fc508f465c6ddf10a..bb4eff61441307458f92a104b0fa655542e118b7 100644 (file)
@@ -13,8 +13,7 @@
 
 #include <linux/device.h>
 #include <linux/string.h>
-#include <linux/slab.h>
-
+#include <linux/platform_device.h>
 #include <asm/io.h>
 #include <asm/hardware/scoop.h>
 
index 0c53dab8090593028381a6c23cdf265779745eb6..4e706d9ad368ee63950a5cea90684eb50b272a26 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/dma-mapping.h>
index db9078ad008c550a0b5c924684df12f280a359e2..d75c8221d2a595d8fddfbf790826be7226797b45 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/string.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/setup.h>
 #include <asm/types.h>
index 837d7f0bda4c8f9b610064551414e66f1cf5a213..37613ad68366eda2615d384501dbcfc4dbb6ffa7 100644 (file)
@@ -22,7 +22,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  */
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index 4cbdc1fe04b1cff7e0f9315b1367f6a0d24b396d..708e1b3faa1466cddb97867403510c8d301824a3 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/platform_device.h>
 #include <asm/system.h>
 #include <asm/hardware.h>
 #include <asm/irq.h>
index 764ceb49470a88975044d383cfe90e083fd77c70..4c0f7c65facf93f215e510d628b9c17d9cdbcb00 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/list.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/sysdev.h>
index aa34c58b96c411abda5198ffaa7d44ec53f290d2..93f7ccb22c27f4e12ad4dc9ba180baa3ac177aed 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/list.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/string.h>
index bb5091223b638120291b9ee15e78693ff227638f..80770233b8d40d7970eee8eaf54ed9df2e715da4 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/init.h>
 #include <linux/major.h>
 #include <linux/fs.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_core.h>
index a2533c3ab42f6671f26d5d84250b30410e5ac1f7..53f60614498be508777a95ad4fd87f1532b74001 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/init.h>
 #include <linux/major.h>
 #include <linux/fs.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_core.h>
index 9aa54de447407d615211860f693fe6a6879f2f28..643f5e1c3d9311d70a9c589f34ca344cc979760c 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_core.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index 8b4a839b6279baf95c13eef696d4969623f7d418..05dfcb48c2b62839eb66dfb8dec0eed8fe72e3d5 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/bitops.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
index fee1d7b73503f67853e1f86f65879de9c70590b9..b21249908ae4185819ce2f24588a0462371c0332 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_core.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index 6c396447c4e078d8ce7e1807c072edfc8c704bb7..f3c687cf00713dcbcaf20eb4689aac5f05818b98 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/serial.h>
 #include <linux/sched.h>
 #include <linux/tty.h>
+#include <linux/platform_device.h>
 #include <linux/serial_core.h>
 #include <linux/bootmem.h>
 #include <linux/interrupt.h>
index a20eabc132b08464c43d65d8915051316cf91b0a..4eb962fdb3a8554530887966f80d7b71ace4eeb3 100644 (file)
@@ -10,7 +10,7 @@
 
 #include <linux/tty.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/interrupt.h>
 
 #include <asm/hardware.h>
index d46a70063b0c61821088ae2c8f483c6a9356454f..4ee6bd8a50b8b105699e4c5698883bcd4526647f 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
index 2798613696fa7e0781609bb61132858d25089e27..fc824361430d86951f184e8b23f82cee8ee07928 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/init.h>
 #include <linux/major.h>
 #include <linux/kernel.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/errno.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
index fd9183ff2ed53c03252acbb5faa86f687c567ed4..a2eac853b2da863fe0f0a59c4bfc90dafa6c092f 100644 (file)
@@ -18,7 +18,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
index d904e643f5ec2c30fabf5d8438f5e40cdec82ad1..c851c2e4dfcb74cc97f988feb93308f53d159500 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
index 21103df50415a7007428f04224b54c8c2127b023..a88524e7c315ba1f95a423f5408d5250214cf540 100644 (file)
@@ -28,7 +28,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/interrupt.h>
 
 #include <linux/mtd/mtd.h>
index 2ba26e239108f87e9b51f38a6ade736256ffd366..354b157acb3a2071193c450630e846618db69020 100644 (file)
@@ -13,7 +13,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
index bf30b1acda0b97a1c9795a0006622c7db6935265..3f018b296861e4def60cd01df13fb470a4fefd54 100644 (file)
@@ -13,7 +13,7 @@
  */
 
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
index e8b3981444cd0d9da280a58374efa28bd9154bdb..3c5d901efeaa88d94b17be82c029c3ba082dab31 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
index 656f73bbcb5a9d6c80fb130b95c1cf6e954764ce..eb5f6d744a4a77778d290ba063b18cccd01973d5 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/interrupt.h>
index 370df113dc066433640874481e7d055a931a7f39..54162ba954142d615bb47832128e288c90ba023f 100644 (file)
@@ -17,7 +17,7 @@
 
 #include <linux/delay.h>
 #include <linux/kernel.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/module.h>
 #include <asm/arch/akita.h>
 #include <asm/arch/corgi.h>
index 136c269db0b7965c8b2a93e9c4abc326ab56714d..591e5f32dbeccdb726ab491b31d080f60376b54b 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
 
index 9c0289333301e9c5f0c0dc252c9990fbd20a8646..9b48a90aefce9d4a25910f513d190c1e7ae7d8c5 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/ioport.h>
 #include <linux/pm.h>
 #include <linux/string.h>
index 01a83ab09ac340a8f7fadb0792a948c067c93e08..7de159e2ab42e173b90d3a84d8b2e0b894f812fa 100644 (file)
@@ -18,7 +18,7 @@
 
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/fb.h>
 
 #include <asm/setup.h>
index beccf455f796f5a0b1d3be968ba63e2692ada432..1f6857d7747d8d5ac0ddc777c728bb08a864552a 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/major.h>
 #include <linux/fb.h>
index a48c64026e1fbb4be74321b305874b20ad7828b0..887a8cb7b7219097464a44ab477ff0ae98bce320 100644 (file)
@@ -14,7 +14,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
index 6d413f6701a77ebd8afdeba39ec4a09fd1118081..ad6a13f95a62cfcae51bc94ffc2fd1f243f17be7 100644 (file)
@@ -16,7 +16,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/fb.h>
 
 #include <asm/hardware.h>
index 09a5d593f04b27c2558850e76c0e99dcee861967..c722a9a91fcce243b9fce9a77f2c15f3e50b939a 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/pm.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
index b838842b6a2050438cc351698cbf63a54ae68778..6c6878cd2207db94f3b70343beef634fbb6491f2 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/major.h>
 #include <linux/fs.h>
index 8b3d5dc35de58866dd7ddda31235ac1929c09437..82e8253b1fa04d556c4da51b2db7ca905bb642c3 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/err.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/sysdev.h>
 
 #include <linux/interrupt.h>
index ca366e9e264da5c908b072e49fa3fdd43a995cdd..687fe371369d5e42d01fe5fb988b6f536e86b0f5 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
index 08bc7d95a45d78c0290b8d5c15eef4c934fd8105..f58406e6ef5a69a3d65103597813ecffdd3a587d 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
index d6328f96728bfb68d72ff068300f1fe3f9638fb8..52c4bab5c7615590ec167bfe0658ba2fe1a2e663 100644 (file)
@@ -15,6 +15,7 @@
  *     10-Feb-2005 BJD  Added camera from guillaume.gourat@nexvision.tv
 */
 #include <linux/config.h>
+#include <linux/platform_device.h>
 
 extern struct platform_device *s3c24xx_uart_devs[];
 
index 5ae80f4e3e672ca3dcf187aa4e96fdc1f27a1752..8390b685c2b61853ac7ead39016427e660a79447 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
index c1b5c63ec24a7b31bf7a838158a2e3cb6964a10b..0b71c896bbd1ac5fe5ebb9ae55487cf01992e9d4 100644 (file)
@@ -41,7 +41,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/dm9000.h>
 
 #include <asm/mach/arch.h>
index 7efeaaad2361e71f2b75d4b2beb29ae493a329b1..0aa8760598f74bf0d27404005623a938693dc19d 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/platform_device.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
index 5c0f2b091f95146d850d2ee4197f9b5b6d4dcbf1..378d640ab00bd0029f3e5cb89831319d43eddbfe 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/kthread.h>
 
 #include <asm/mach/arch.h>
index c22f8216032d8d8a5e88c5d7e01bfc51bb580253..42b0eeff2e0f1da322805b24d0941f75f357fa33 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/string.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <linux/mtd/map.h>
 
index ad1459e402e286671dc3ded975a3416b24c6a69e..a2eb9ed48fcdc1e53541a1134c6dd703d3d4361d 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
index 22d9e070fd68f42e0e9275a1f97a0fdc258b96c0..8f2a90bf940bc5178ca40e419bef665ea58cda64 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/tty.h>
 #include <linux/console.h>
+#include <linux/platform_device.h>
 #include <linux/serial_core.h>
 #include <linux/serial.h>
 
index 2eda55a6b678bddd2b5fdb6f7c7f17db9bebeb86..2c91965ee1c89292e104703c6111029234449d2d 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/platform_device.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
index 6950e61b79149022c368beac1a6d2b910c812f9c..d666c621ad064a3811885a792171c1ad82a3e762 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
+#include <linux/platform_device.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
index a8bf5ec826028c44db4b0ef22b81dc11421affdd..0a2013a7654922161631ae5da0043834f9ed7e7e 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
index 833fa36bce057764843e3be433d406fd1ec2f3ed..4d63e7133b48438014250da15e99b79f71637afb 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/sysdev.h>
 
 #include <asm/mach/arch.h>
index c92cebff7f8e758b653b053c612b82cb8041ba92..edccd5eb06be917b257d0ec38f1e135734be7243 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/tty.h>
 #include <linux/mtd/mtd.h>
index 23cb748852751db95f0437e97c4052f2dd1865c4..508593722bc741527ffdc276342550ad7c93f860 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/tty.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 
index 7fd6e29c36b79d6fb1cc7091695a6c5a4b56771a..522abc036d3a35521bc9acfe4721c5e2cbd025ed 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/tty.h>
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/timer.h>
index 83eba8b54816681f217807dd2ef0dccd76d10288..2abdc419e9848a8056918d62cdb72a1841bdb806 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/cpufreq.h>
 #include <linux/ioport.h>
 #include <linux/sched.h>       /* just for sched_clock() - funny that */
+#include <linux/platform_device.h>
 
 #include <asm/div64.h>
 #include <asm/hardware.h>
index 89af0c831e8fde6621856dec34c23dc0dfef774b..2f671cc3cb99f793a1a186ccae7eeffebd699883 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/kernel.h>
 #include <linux/tty.h>
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/ioport.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
index 052e4caedb89322e510d0eba42bc742a9c3850bd..69f1970646c628e3a9e8f68a2adddf511a16297b 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/tty.h>
 #include <linux/ioport.h>
 #include <linux/serial_core.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 
 #include <asm/hardware.h>
index e17b58fb9c9c310aa3cf91b3bb783ecd55e52b1c..58c18f9e9b7bf2a207d2ff03be48820609683980 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/kernel.h>
 #include <linux/tty.h>
 #include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <linux/mtd/partitions.h>
 
index cfb6658e5cdf5fac50e4d9256947d47268483f02..439ddc9b06d6f1dda4159ab73579410df6340bab 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/proc_fs.h>
 #include <linux/string.h> 
 #include <linux/pm.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 
index 7e4bdd07f4afb4c82778a4c3c796d39684587103..a1ca46630dda469140f5ef2b2d33919bc6c9551a 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/interrupt.h>
 
index 14a836d7ac250a4ebee43b3cca8edf1b5e70cba8..205e2d0b826d4f4ff53f24c73a71970b88be10a2 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/usb_otg.h>
 
 #include <asm/io.h>
index 5383e5e2d9b7e564f675516f69b477b280989e02..bac0da731ee3ae98065d5771148648ad1df53940 100644 (file)
@@ -1042,8 +1042,3 @@ config X86_TRAMPOLINE
        bool
        depends on X86_SMP || (X86_VOYAGER && SMP)
        default y
-
-config PC
-       bool
-       depends on X86 && !EMBEDDED
-       default y
index 9204be6eedb3c5e4d25c1add893359de85fda1ab..7c724ffa08bb9617e4a1834fb20e5924565e281f 100644 (file)
@@ -803,7 +803,6 @@ no_apic:
 
 void __init init_apic_mappings(void)
 {
-       unsigned int orig_apicid;
        unsigned long apic_phys;
 
        /*
@@ -825,11 +824,8 @@ void __init init_apic_mappings(void)
         * Fetch the APIC ID of the BSP in case we have a
         * default configuration (or the MP table is broken).
         */
-       orig_apicid = boot_cpu_physical_apicid;
-       boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
-       if ((orig_apicid != -1U) && (orig_apicid != boot_cpu_physical_apicid))
-               printk(KERN_WARNING "Boot APIC ID in local APIC unexpected (%d vs %d)",
-                       orig_apicid, boot_cpu_physical_apicid);
+       if (boot_cpu_physical_apicid == -1U)
+               boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
 
 #ifdef CONFIG_X86_IO_APIC
        {
@@ -1259,81 +1255,40 @@ fastcall void smp_error_interrupt(struct pt_regs *regs)
 }
 
 /*
- * This initializes the IO-APIC and APIC hardware.
+ * This initializes the IO-APIC and APIC hardware if this is
+ * a UP kernel.
  */
-int __init APIC_init(void)
+int __init APIC_init_uniprocessor (void)
 {
-       if (enable_local_apic < 0) {
-               printk(KERN_INFO "APIC disabled\n");
-               return -1;
-       }
+       if (enable_local_apic < 0)
+               clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
 
-       /* See if we have a SMP configuration or have forced enabled
-        * the local apic.
-        */
-       if (!smp_found_config && !acpi_lapic && !cpu_has_apic) {
-               enable_local_apic = -1;
+       if (!smp_found_config && !cpu_has_apic)
                return -1;
-       }
 
        /*
-        * Complain if the BIOS pretends there is an apic.
-        * Then get out because we don't have an a local apic.
+        * Complain if the BIOS pretends there is one.
         */
        if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
                printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
                        boot_cpu_physical_apicid);
-               printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
-               enable_local_apic = -1;
                return -1;
        }
 
        verify_local_APIC();
 
-       /*
-        * Should not be necessary because the MP table should list the boot
-        * CPU too, but we do it for the sake of robustness anyway.
-        * Makes no sense to do this check in clustered apic mode, so skip it
-        */
-       if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
-               printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
-                               boot_cpu_physical_apicid);
-               physid_set(boot_cpu_physical_apicid, phys_cpu_present_map);
-       }
-
-       /*
-        * Switch from PIC to APIC mode.
-        */
        connect_bsp_APIC();
-       setup_local_APIC();
 
-#ifdef CONFIG_X86_IO_APIC
-       /*
-        * Now start the IO-APICs
-        */
-       if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
-               setup_IO_APIC();
-#endif
-       return 0;
-}
+       phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
 
-void __init APIC_late_time_init(void)
-{
-       /* Improve our loops per jiffy estimate */
-       loops_per_jiffy = ((1000 + HZ - 1)/HZ)*cpu_khz;
-       boot_cpu_data.loops_per_jiffy = loops_per_jiffy;
-       cpu_data[0].loops_per_jiffy = loops_per_jiffy;
-
-       /* setup_apic_nmi_watchdog doesn't work properly before cpu_khz is
-        * initialized.  So redo it here to ensure the boot cpu is setup
-        * properly.
-        */
-       if (nmi_watchdog == NMI_LOCAL_APIC)
-               setup_apic_nmi_watchdog();
+       setup_local_APIC();
 
 #ifdef CONFIG_X86_IO_APIC
-       if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
-               IO_APIC_late_time_init();
+       if (smp_found_config)
+               if (!skip_ioapic_setup && nr_ioapics)
+                       setup_IO_APIC();
 #endif
        setup_boot_APIC_clock();
+
+       return 0;
 }
index d86f2490928449ce15acfc8ffff5522e11139453..323ef8ab3244e880c1b32468a12122990ba0ceba 100644 (file)
@@ -435,8 +435,4 @@ void __init init_IRQ(void)
                setup_irq(FPU_IRQ, &fpu_irq);
 
        irq_ctx_init(smp_processor_id());
-
-#ifdef CONFIG_X86_LOCAL_APIC
-       APIC_init();
-#endif
 }
index 5a77c52b20a934d2d9a168ee20a1a965201e1818..cc5d7ac5b2e7dfa5a157bb0dffe57971bc037ed4 100644 (file)
@@ -2387,15 +2387,11 @@ void __init setup_IO_APIC(void)
        sync_Arb_IDs();
        setup_IO_APIC_irqs();
        init_IO_APIC_traps();
+       check_timer();
        if (!acpi_ioapic)
                print_IO_APIC();
 }
 
-void __init IO_APIC_late_time_init(void)
-{
-       check_timer();
-}
-
 /*
  *     Called after all the initialization is done. If we didnt find any
  *     APIC bugs then we can allow the modify fast path
index 5a2bbe0c4ffff7ffcc5344d3d7015bd6651061d8..01b618e73ecd14ba6f9dedea08a718865715d266 100644 (file)
@@ -1078,16 +1078,6 @@ void *xquad_portio;
 EXPORT_SYMBOL(xquad_portio);
 #endif
 
-/*
- * Fall back to non SMP mode after errors.
- *
- */
-static __init void disable_smp(void)
-{
-       cpu_set(0, cpu_sibling_map[0]);
-       cpu_set(0, cpu_core_map[0]);
-}
-
 static void __init smp_boot_cpus(unsigned int max_cpus)
 {
        int apicid, cpu, bit, kicked;
@@ -1100,6 +1090,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
        printk("CPU%d: ", 0);
        print_cpu_info(&cpu_data[0]);
 
+       boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
        boot_cpu_logical_apicid = logical_smp_processor_id();
        x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
 
@@ -1111,27 +1102,68 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
        cpus_clear(cpu_core_map[0]);
        cpu_set(0, cpu_core_map[0]);
 
-       map_cpu_to_logical_apicid();
-
        /*
         * If we couldn't find an SMP configuration at boot time,
         * get out of here now!
         */
        if (!smp_found_config && !acpi_lapic) {
                printk(KERN_NOTICE "SMP motherboard not detected.\n");
-               disable_smp();
+               smpboot_clear_io_apic_irqs();
+               phys_cpu_present_map = physid_mask_of_physid(0);
+               if (APIC_init_uniprocessor())
+                       printk(KERN_NOTICE "Local APIC not detected."
+                                          " Using dummy APIC emulation.\n");
+               map_cpu_to_logical_apicid();
+               cpu_set(0, cpu_sibling_map[0]);
+               cpu_set(0, cpu_core_map[0]);
+               return;
+       }
+
+       /*
+        * Should not be necessary because the MP table should list the boot
+        * CPU too, but we do it for the sake of robustness anyway.
+        * Makes no sense to do this check in clustered apic mode, so skip it
+        */
+       if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
+               printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
+                               boot_cpu_physical_apicid);
+               physid_set(hard_smp_processor_id(), phys_cpu_present_map);
+       }
+
+       /*
+        * If we couldn't find a local APIC, then get out of here now!
+        */
+       if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]) && !cpu_has_apic) {
+               printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
+                       boot_cpu_physical_apicid);
+               printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
+               smpboot_clear_io_apic_irqs();
+               phys_cpu_present_map = physid_mask_of_physid(0);
+               cpu_set(0, cpu_sibling_map[0]);
+               cpu_set(0, cpu_core_map[0]);
                return;
        }
 
+       verify_local_APIC();
+
        /*
         * If SMP should be disabled, then really disable it!
         */
-       if (!max_cpus || (enable_local_apic < 0)) {
-               printk(KERN_INFO "SMP mode deactivated.\n");
-               disable_smp();
+       if (!max_cpus) {
+               smp_found_config = 0;
+               printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
+               smpboot_clear_io_apic_irqs();
+               phys_cpu_present_map = physid_mask_of_physid(0);
+               cpu_set(0, cpu_sibling_map[0]);
+               cpu_set(0, cpu_core_map[0]);
                return;
        }
 
+       connect_bsp_APIC();
+       setup_local_APIC();
+       map_cpu_to_logical_apicid();
+
+
        setup_portio_remap();
 
        /*
@@ -1212,6 +1244,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
        cpu_set(0, cpu_sibling_map[0]);
        cpu_set(0, cpu_core_map[0]);
 
+       smpboot_setup_io_apic();
+
+       setup_boot_APIC_clock();
+
        /*
         * Synchronize the TSC with the AP
         */
index 07471bba2dc6a7d10b28a09ef0c2ae119444f797..41c5b2dc6200b0a600a830f42121e2290d5b29d6 100644 (file)
@@ -440,8 +440,8 @@ static int time_init_device(void)
 
 device_initcall(time_init_device);
 
-extern void (*late_time_init)(void);
 #ifdef CONFIG_HPET_TIMER
+extern void (*late_time_init)(void);
 /* Duplicate of time_init() below, with hpet_enable part added */
 static void __init hpet_time_init(void)
 {
@@ -458,11 +458,6 @@ static void __init hpet_time_init(void)
        printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
 
        time_init_hook();
-
-#ifdef CONFIG_X86_LOCAL_APIC
-       if (enable_local_apic >= 0)
-               APIC_late_time_init();
-#endif
 }
 #endif
 
@@ -487,9 +482,4 @@ void __init time_init(void)
        printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
 
        time_init_hook();
-
-#ifdef CONFIG_X86_LOCAL_APIC
-       if (enable_local_apic >= 0)
-               late_time_init = APIC_late_time_init;
-#endif
 }
index 708634b685e44ff925bb2d4eca7af5de8173e329..cb76916b014dd49fd0b333951931d3f8192c367d 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/system.h>
 #include <asm/m32r.h>
index 4e709809efc5f98ec1a04771a265dd33d2b5ea6d..501d798cf0508811a4d7fd8e1754e36c40aa9895 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/system.h>
 #include <asm/m32r.h>
index a1d801598aa44b8a449196025fb3d551e55a3a9a..7f2db5bfd626de1eefac4a297c4ab45116563e42 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/system.h>
 #include <asm/m32r.h>
index a76412e883e8cecfb79396fe9ab26e6e0d6d7175..9c79341a7b455711c165da735893f61cad8cef37 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/system.h>
 #include <asm/m32r.h>
index d7b7ec6d30f88c3942eec68d520b05b0a66675a7..1fbb140854e7b728d3c7ecc0f8344809010fee0b 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/system.h>
 #include <asm/m32r.h>
index 1f7b465c8038bab56d5d7d1346544eeb9cc6b733..48d3f54f88f88e23bfb4a134cb9a2fd4c12416c8 100644 (file)
@@ -9,6 +9,7 @@
  */
 #include <linux/config.h>
 #include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/resource.h>
index 4712de8ff80fd3b750a7f54b9db95578be418c53..65ac0b9c2d05d8c9ccce0ec77af579d4066205bf 100644 (file)
@@ -14,6 +14,7 @@
  */
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/platform_device.h>
 #include <platforms/4xx/ibm440ep.h>
 #include <asm/ocp.h>
 #include <asm/ppc4xx_pic.h>
index d90627b68faa5580516d0419fcac699fc3a5e3c8..7e33bb635443e8c2ad459d5cb0a605691d23cb9a 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/platform_device.h>
 #include <asm/ocp.h>
 #include <asm/ppc4xx_pic.h>
 #include <platforms/4xx/ibmstb4.h>
index bee8b4ac8afd221ba6c2a1b566249cb934505897..611ac861804d31f814e460a2f86d3bc6e23a317d 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/pagemap.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/ioport.h>
 #include <asm/io.h>
 #include <asm/machdep.h>
index 8b1012994dfc9ffba5297684334ef331e38a7de5..b13116691289fa19171a45803afbb04b538911c5 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/pagemap.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/ioport.h>
 #include <asm/io.h>
 #include <asm/ppc4xx_pic.h>
index a9052305c35debfcaf0c036b0cad037f9e94ea02..108a6e265185b443985e86fe95dced1108e39260 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/mv643xx.h>
 #include <linux/pci.h>
 
index f64ac2acb603e9b41d0b63a09d88c67df8d6ef40..6ca7bcac947421dfbdf52303bfedfdec0ae0d0f9 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/initrd.h>
 #include <linux/root_dev.h>
 #include <linux/mv643xx.h>
+#include <linux/platform_device.h>
 #include <asm/bootinfo.h>
 #include <asm/machdep.h>
 #include <asm/todc.h>
index aa50637a5cfb141fdb7aab84f941488f8557eda7..32358b3fb23654a09ece544b62a9d88b17450013 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/console.h>
 #include <linux/initrd.h>
 #include <linux/root_dev.h>
+#include <linux/platform_device.h>
 #if !defined(CONFIG_SERIAL_MPSC_CONSOLE)
 #include <linux/serial.h>
 #include <linux/tty.h>
index 53388a1c334f7dbe77a8b93c4e2b1d8e9c5ea9e9..b1324564456e80e28c220c113a4608022d9ace2e 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/bootmem.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mv643xx.h>
+#include <linux/platform_device.h>
 #ifdef CONFIG_BOOTIMG
 #include <linux/bootimg.h>
 #endif
index b6a66d5e9d8357177d1701e33b9563ccbc646540..50039a204c2495f739b9e4637ba553a0f3a5f9dd 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/irq.h>
 #include <linux/ide.h>
 #include <linux/seq_file.h>
+#include <linux/platform_device.h>
 
 #include <linux/initrd.h>
 #include <linux/root_dev.h>
index a301c5ac58ddf985244fa5fd8e8fe55f93a614c3..6e58e30ceed101b1aeace5055a19d4a00583b308 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/seq_file.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mv643xx.h>
+#include <linux/platform_device.h>
 #ifdef CONFIG_BOOTIMG
 #include <linux/bootimg.h>
 #endif
index 6f97911c330d4e5d02ff71f12ab2fd1262528b7f..708b8739ecdd97e1fd2d5eaed73f5e475bd6e8f6 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/serial_core.h>
 #include <linux/mv643xx.h>
 #include <linux/netdevice.h>
+#include <linux/platform_device.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
index ad5182efca1dd3fe7e845b2b55016c1208b71940..da3c74bfdc9271cb637c9fb90d09b4f0e93724a4 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/fsl_devices.h>
 #include <linux/resource.h>
+#include <linux/platform_device.h>
 #include <asm/mpc52xx.h>
 #include <asm/ppc_sys.h>
 
index a781c50d2f4caed443aa67d6433d41a8914f32fa..94ea346b7b4b8b7def5f003d5a4dfe8ce74623b4 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/string.h>
 #include <linux/spinlock.h>
 #include <linux/mv643xx.h>
+#include <linux/platform_device.h>
 
 #include <asm/byteorder.h>
 #include <asm/io.h>
index 6f88ba93412b0489e81f01d339b48c8ad4e7d577..e960fe9353256b82e611da8226988d679b2ba433 100644 (file)
@@ -13,7 +13,7 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/ioport.h>
 #include <asm/cpm2.h>
 #include <asm/irq.h>
index c18919941ec0f52d3f4c90e666a1c67c20d05685..1c1d65fb12df8cd1b5266ee4e7554d586af441bd 100644 (file)
@@ -13,7 +13,7 @@
 
 #include <linux/config.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/ioport.h>
 #include <asm/io.h>
 #include <asm/mach/irq.h>
index 1495007bf6c07df5061526d554382287d95e27e2..721e2601a75da2e8b8fbcbb94dc1797831bc0e7c 100644 (file)
@@ -20,6 +20,7 @@
 #include "linux/ctype.h"
 #include "linux/bootmem.h"
 #include "linux/ethtool.h"
+#include "linux/platform_device.h"
 #include "asm/uaccess.h"
 #include "user_util.h"
 #include "kern_util.h"
index f73134333f64ee55c9eb7f87521e89f577400297..b2c86257b0f83cc0f8f254d286db9bf76e4c5e86 100644 (file)
@@ -35,6 +35,7 @@
 #include "linux/blkpg.h"
 #include "linux/genhd.h"
 #include "linux/spinlock.h"
+#include "linux/platform_device.h"
 #include "asm/segment.h"
 #include "asm/uaccess.h"
 #include "asm/irq.h"
index 498d7dced1f486675a55446f96340f84b6d5dff0..0682ffd38175edd2da90dd10da2e71c8bc6d6906 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/ethtool.h>
 #include <linux/rtnetlink.h>
 #include <linux/timer.h>
+#include <linux/platform_device.h>
 
 #include <xtensa/simcall.h>
 
index 08d9cc99c7de134613a92565c9be883ccb194861..d597c922af11969213d3ea8bbe310bc57089d277 100644 (file)
@@ -10,7 +10,7 @@
  * information.
  */
 
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
index 5281f8e70510cda1717f2bd385e0c19353476fdd..ecacca9c877eb286bdc77eb2aea5906cc3235e18 100644 (file)
@@ -2059,10 +2059,8 @@ static void cfq_put_cfqd(struct cfq_data *cfqd)
        if (!atomic_dec_and_test(&cfqd->ref))
                return;
 
-       blk_put_queue(q);
-
        cfq_shutdown_timer_wq(cfqd);
-       q->elevator->elevator_data = NULL;
+       blk_put_queue(q);
 
        mempool_destroy(cfqd->crq_pool);
        kfree(cfqd->crq_hash);
index 00895477155e69aaac17792f253681d0e4c0a2d0..5eadbb9d4d71afdff8d74ae5e5e4f5b00c05a996 100644 (file)
@@ -177,7 +177,7 @@ static int print_unex = 1;
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/devfs_fs_kernel.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/buffer_head.h> /* for invalidate_buffers() */
 
 /*
index f56b8edb06e42b217b46c9556c23ca30ef6a6063..e54f006e7e603475999cc2465278035ab547c0cf 100644 (file)
@@ -9,6 +9,7 @@
 
 static void elevator_noop_add_request(request_queue_t *q, struct request *rq)
 {
+       rq->flags |= REQ_NOMERGE;
        elv_dispatch_add_tail(q, rq);
 }
 
index 887b8b2d7882780d29bd86bfd56f9140daebbce8..d724c0de4f28334ad1de8d84ad54291f570f0a15 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/fs.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
index f86c15587238e3bfeb0d9d145325375f9a9ca94b..d05067dcea01967fa9d645b08dffc982041b91ef 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/dmi.h>
 #include <linux/err.h>
 #include <linux/kfifo.h>
+#include <linux/platform_device.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
index eb7058cbf015545ee032fa9d67128fa505d13599..24355b23b2ca8a3aacf77937dd829e66105fac0b 100644 (file)
@@ -17,7 +17,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/module.h>
index 683278bc5241f1e9a14ab8412ea8368aa4bc8855..94641085faf8b66a93ab1c9add8d2cdf49297c1b 100644 (file)
@@ -19,7 +19,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/init.h>
index a6dbe4da030c7712fa69b90d0f89de618428d55c..5e3292df69d8d794a1a0c4a5ccf5f1becbb38591 100644 (file)
@@ -17,7 +17,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
index 75ca84ed4adf5ea728bfa3c05d23bcdaae4fc72c..47a5f6ab48793ab30566b6965b3ba4e7ad83eda6 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/reboot.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/hardware/arm_twd.h>
 #include <asm/uaccess.h>
index 6d3ff0836c440b90b61697e2bc2c4559f45b085b..04e0d7e9680db15927bd47edbf3c3e8c11829c7e 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/watchdog.h>
+#include <linux/platform_device.h>
+
 #include <asm/mv64x60.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
index b732020acadb1962fa693d5346e97dec33c0acfa..e7e20a6d64b025795b8d578ad3eefae0611f8bac 100644 (file)
@@ -44,7 +44,7 @@
 #include <linux/watchdog.h>
 #include <linux/fs.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/interrupt.h>
 
 #include <asm/uaccess.h>
index 15677f20bd85bd9208a41610eea9a2b7b6e70ee3..0f97a0cb0ff431733f27551ffaa779668143000e 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <linux/config.h>
 #include <linux/kernel.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/eisa.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
index 955537fe9958acd177a6d8dd1f15b9e0b054bcb7..8ed6ddbb9c5d5f1932bb3ff7ca756f37aa39a552 100644 (file)
@@ -20,7 +20,7 @@
  *  GNU General Public License for more details.
  */
 
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/errno.h>
 #include <linux/init.h>
index 4f4ba9b6d1821bce9a53bbdc4470d2caba99c16e..125929c9048f0be47b4e59543d79a5b62a0e0ff6 100644 (file)
@@ -41,7 +41,7 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/blkdev.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
index 0015da5668a181aa8f9956cc59539c49483c3d95..1e5dfc7805e289acf2063f95774bf387e6ab4876 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/input.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index 9888fae1f37a8f90ea34fd658573162e08b0007c..13752bcb2afdb04fcfd143663e3d73bac2e88ebd 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/i2c.h>
 
 #include <asm/io.h>
index 4fdc02411609208310520bf91b7d55875317ad9f..03672c9ca4092ade4a0590d598b38a9fda259147 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/errno.h>
 #include <linux/i2c.h>
 #include <linux/i2c-isa.h>
+#include <linux/platform_device.h>
 
 static u32 isa_func(struct i2c_adapter *adapter);
 
index 42016ee6ef133908f98549199c41a8f6d93f6096..64552a376f2d000291690abe8d4d4d685a768daf 100644 (file)
@@ -28,7 +28,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
index 69303ab65e0488d91799bb509ce95c10e6ae803a..cc652c3508149b73ed03ed3ef990c0365efd3fcc 100644 (file)
@@ -28,7 +28,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
index 8491633005b87f007607e0407a5072e0c2c25c96..65b939a059e9b6fd803cacc7699533b3fd58b559 100644 (file)
@@ -19,6 +19,8 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#include <linux/platform_device.h>
+
 #include <asm/io.h>
 #include <linux/fsl_devices.h>
 #include <linux/i2c.h>
index d0d2a6f1386e03dcd5ea64ec9e83ca2b4d2dfc55..6b48027b2ee340b9cdab8624c03f7c029abea6b2 100644 (file)
@@ -17,6 +17,8 @@
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/mv643xx.h>
+#include <linux/platform_device.h>
+
 #include <asm/io.h>
 
 /* Register defines */
index 44b595d90a4a19cd8554ba9a04ebfbc4af9455c2..67ccbea24ba4b54d546f794b385798d5e193d4a1 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/i2c-pxa.h>
+#include <linux/platform_device.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
index 6ced28e90070a90d6cf3eb7ebd1ad4d9653e30b2..1b582262e677ed89ce68b9277e927d4f61046948 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/err.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
@@ -918,8 +918,11 @@ static int __init i2c_adap_s3c_init(void)
        int ret;
 
        ret = driver_register(&s3c2410_i2c_driver);
-       if (ret == 0)
-               ret = driver_register(&s3c2440_i2c_driver); 
+       if (ret == 0) {
+               ret = driver_register(&s3c2440_i2c_driver);
+               if (ret)
+                       driver_unregister(&s3c2410_i2c_driver);
+       }
 
        return ret;
 }
index eaa4742e04fa661bda29b62992a58a17ce52a6e0..9dbb72fffbe2520fdcc47d220cb272adf4a81be4 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/usb_ch9.h>
 #include <linux/usb_gadget.h>
 #include <linux/usb.h>
index 02e335a04f095ad546c7689a1cb5ad3abfb06fda..82ea1b7ec9145536439467778300e29dd1ac0e1d 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/idr.h>
 #include <linux/seq_file.h>
+#include <linux/platform_device.h>
 #include <asm/uaccess.h>
 
 
index ea14c8f1c82baa58b7df2e12921e36c720c1bf85..8af0bd1424d21574f6c284bcdd6ea79ed2f92c75 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/i2c-dev.h>
+#include <linux/platform_device.h>
 #include <asm/uaccess.h>
 
 static struct i2c_client i2cdev_client_template;
index a4696cd0978ca68c436ad37ceaa66252b4464b68..9f2352bd8348efa34047125a4f72c181dd5d9f93 100644 (file)
@@ -565,6 +565,7 @@ static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned lon
                                                case EV_LED: bits = dev->ledbit; max = LED_MAX; break;
                                                case EV_SND: bits = dev->sndbit; max = SND_MAX; break;
                                                case EV_FF:  bits = dev->ffbit;  max = FF_MAX;  break;
+                                               case EV_SW:  bits = dev->swbit;  max = SW_MAX;  break;
                                                default: return -EINVAL;
                                        }
                                        bit_to_user(bits, max);
@@ -579,6 +580,9 @@ static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned lon
                                if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
                                        bit_to_user(dev->snd, SND_MAX);
 
+                               if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
+                                       bit_to_user(dev->sw, SW_MAX);
+
                                if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
                                        int len;
                                        if (!dev->name) return -ENOENT;
index 3b1685ff9d10b38db94defa977cf1e6c43effc38..1a1654caedd53a2ca59390bae8e97791b41298b6 100644 (file)
@@ -730,7 +730,7 @@ static void input_register_classdevice(struct input_dev *dev)
                 "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
 
        path = kobject_get_path(&dev->cdev.class->subsys.kset.kobj, GFP_KERNEL);
-       printk(KERN_INFO "input: %s/%s as %s\n",
+       printk(KERN_INFO "input: %s as %s/%s\n",
                dev->name ? dev->name : "Unspecified device",
                path ? path : "", dev->cdev.class_id);
        kfree(path);
index 571a68691a4ae3f4ce7d27db795696f2491c575d..4a917748fd9ffac79f863675574ffd2155994858 100644 (file)
@@ -13,11 +13,11 @@ menuconfig INPUT_KEYBOARD
 if INPUT_KEYBOARD
 
 config KEYBOARD_ATKBD
-       tristate "AT keyboard" if !PC
+       tristate "AT keyboard" if !X86_PC
        default y
        select SERIO
        select SERIO_LIBPS2
-       select SERIO_I8042 if PC
+       select SERIO_I8042 if X86_PC
        select SERIO_GSCPS2 if GSC
        help
          Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
index 3210d298b3bc01d6e984b89097962876cc27db2e..d00d14bb637a70b9a49125fa308413efd14eca60 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
index 7f06780a437f5d435bfd27ff45e459a0b8d56021..9481132532d017ee42d36cecc789a0007e7bca2b 100644 (file)
@@ -441,7 +441,7 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
                        input_sync (lk->dev);
                        break;
                case LK_METRONOME:
-                       DBG (KERN_INFO "Got %#d and don't "
+                       DBG (KERN_INFO "Got LK_METRONOME and don't "
                                        "know how to handle...\n");
                        break;
                case LK_OUTPUT_ERROR:
index cee9c734a048c9102eaeec0090c99a6e7a8656f0..0fa38a559cdfedc0815a4d91f521f111b08fd86d 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
index e34633c37fddc5fb52ec27c68b7d146032e91a69..68ac97f101b0369a6f7a358829a3d6fd25dc4910 100644 (file)
@@ -71,7 +71,7 @@ static int __init pcspkr_init(void)
                return -ENOMEM;
 
        pcspkr_dev->name = "PC Speaker";
-       pcspkr_dev->name = "isa0061/input0";
+       pcspkr_dev->phys = "isa0061/input0";
        pcspkr_dev->id.bustype = BUS_ISA;
        pcspkr_dev->id.vendor = 0x001f;
        pcspkr_dev->id.product = 0x0001;
index 537154dd7a873cc8e252bc2cf61f87f01395936e..574b18a523af2df86eaedb9def31a9d629ae1aad 100644 (file)
@@ -17,7 +17,7 @@ config MOUSE_PS2
        default y
        select SERIO
        select SERIO_LIBPS2
-       select SERIO_I8042 if PC
+       select SERIO_I8042 if X86_PC
        select SERIO_GSCPS2 if GSC
        ---help---
          Say Y here if you have a PS/2 mouse connected to your system. This
index dd0f5bd902413bf89810c5c727775c58c421efce..4da6c86b5d76a46979104b2dcc87edadd0cde7e8 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/serio.h>
 #include <linux/errno.h>
 #include <linux/err.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 
index 4bc40f15999603c5f30e9184575078d5c5a56fcb..01e186422021d3a5c594f5b59a376543b817b2e5 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/serio.h>
 #include <linux/err.h>
 #include <linux/rcupdate.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 
index 9880fc145d9051c1be9a02b9d4fe7f70ec76e53d..d857f7081adb03e408778dc0f7ce058e79df08e3 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/err.h>
index 46093c507988e002fa8ee8abf198cd397721d396..b44d255596c25db08eb1c184c29f4f4468e08f14 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/interrupt.h>
 #include <linux/err.h>
 #include <linux/bitops.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
index 106f5eefd89a256bae649d02b7c46a853da58f8c..52c49258f8a4e4dc447dd5a98d89182e38d2b395 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/init.h>
 #include <linux/serio.h>
 #include <linux/err.h>
+#include <linux/platform_device.h>
 
 #include <asm/irq.h>
 #include <asm/hardware.h>
index 0ba3e6562bffeb8762230891ed580904a5a6080b..15e88eeae8d6daf1cacd4216080cffbc7b09f258 100644 (file)
@@ -11,7 +11,7 @@
 
 
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
index cdb6d028319577ad6dc0293a66c87ad5538872f2..8f02c155fdc0e26693ce5babe3abe1b5e14221be 100644 (file)
@@ -723,6 +723,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
 
        sprintf(hid->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id);
 
+       hid->input = input_dev;
        hid->id = default_id;
        hid->original_handler_id = original_handler_id;
        hid->current_handler_id = current_handler_id;
index 720e7a3263088b881dce613e958af67f0f243586..7daa0ed7331cd9a46ee537f1939af2bf464e2b0e 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/dma.h>
 #include <asm/hardware.h>
index 46de5c9405557b0ddb1166f397539b94742bc38b..9c4dd682ac74f1fcf92fab62e3b666fd2d54afb9 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/miscdevice.h>
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <asm/uaccess.h>
 #include <linux/hdpu_features.h>
 
index c203b27269ea7278437676d863d17445baebf2d8..165f3405df277f3ffef0f88a3028789b0e76e4b2 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/hdpu_features.h>
 #include <linux/pci.h>
 
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 static int hdpu_nexus_probe(struct device *ddev);
 static int hdpu_nexus_remove(struct device *ddev);
index d575e3a018bc109365d37153b4ecd305b6966789..f31e247b2cbeabf479c912ae896453db70278935 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
index 3ace875decc4475270aa8abc066471a3abd634bf..942668e93a7460603251e1fbaa567a4152d36cb4 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
index 63104c73ca3c8bb7caadb6e3b038318fcffd06ec..bfe994e59265d57772da814b0b08eab199e2e793 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/ioport.h>
 #include <linux/device.h>
 #include <linux/slab.h>
-
+#include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
index e39a98a0171c801b44b0eec73730d2ebb8df5120..d14a0185b8f419f97d14595caee88803c64769d9 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/init.h>
 
 #include <linux/mtd/mtd.h>
index 1e5d6e1d05f318c1f0e45c866ed465a825fe6b6c..00b9f67580f1566550950327479fd59af1ca2a33 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
index da316e543237676e8fdf61a6a98923f06d27adca..733a9297a56263eda2c49bfe7db2545f86ed78d6 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
index fa84566245a7093588a53df13f30774a4d323591..7f370bb794fefae45e192df190d657e7bcd13110 100644 (file)
@@ -30,7 +30,7 @@
  * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
index a0577ea00c3c974bb1121d5a11d9cac0765c82b4..104576b5be3480cf238f1f4c3ac0a6c9bbfeca8f 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/ioport.h>
 #include <linux/device.h>
 #include <linux/slab.h>
+#include <linux/platform_device.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
index c81bec7b14d5565c97deed108be3155beec98fdd..c8d0da19d897e461a18efaace5076bfc12111d59 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/err.h>
 
 #include <linux/mtd/mtd.h>
index b58ba236a9eb8a5ffd479da0b56d88a041acc860..2df5e47d1f5ce2ec7c16a9ab6018d7e4be6c1eff 100644 (file)
@@ -48,7 +48,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/slab.h>
index c4aa5fe2840e721199d1eac7e1bd32978415d480..4d26e5e7d18b39e9dc411e080f1f380c9970296a 100644 (file)
 #include <linux/unistd.h>
 #include <linux/ctype.h>
 #include <linux/moduleparam.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/bitops.h>
 
 #include <asm/uaccess.h>
index abce1f730d00b32df657af0bbbca5525e903eb51..c0af6fb1fbba210c3139bb18f66ad7960afd8780 100644 (file)
@@ -66,6 +66,7 @@
 #include <linux/mii.h>
 #include <linux/dm9000.h>
 #include <linux/delay.h>
+#include <linux/platform_device.h>
 
 #include <asm/delay.h>
 #include <asm/irq.h>
index ae5a2ed3b2640336a656087596206d2e462ee73e..962580f2c4abb2b5fbdcf21e35db626df2400946 100644 (file)
@@ -81,7 +81,7 @@
 #include <linux/if_vlan.h>
 #include <linux/spinlock.h>
 #include <linux/mm.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
index 1eca1dbca7f1a10c94cb5bd6ae95a5cac8f35998..5a74d3d3dbe1763befa68f4823ba4d7797def74d 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/version.h>
+#include <linux/platform_device.h>
 #include <asm/ocp.h>
 #include <linux/crc32.h>
 #include <linux/mii.h>
index b886b07412a67c95f8e64b5203af7ad92722121e..e1aa9910503bf08bf844f8327f26a5419eb9b939 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
 #include <linux/pm.h>
 
 #include <net/irda/irda.h>
index 06883309916d493636097dddc1e5b15e93359cf5..76e0b9fb5e96a906c9a5ba915d02407ef3b5414e 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
 #include <net/irda/irda.h>
index 140b7cdb1f7e8186f43e896a75a0ecf09af9278a..a1d207f2fa68e0c26f54267539ab169dfd40bff0 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/serial_reg.h>
 #include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
index 8423cb6875f06d75ac38f18881199a5f2b8acb41..a74a5cfaf5bc821271e6c1ae2087b1ed6e38a039 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
 #include <asm/bootinfo.h>
index 405e18365edef4c353b681937ebf63eb3971def7..e9c999d7eb390103a26031a5c782065cba883c81 100644 (file)
@@ -47,7 +47,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
 #include <asm/bootinfo.h>
index f79f7ee72ab89488734bcaba2fd9caf4731ab374..bbffb585b3b383a4582c22ab2078dafd471f1f14 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/sched.h>
 #include <linux/etherdevice.h>
 #include <linux/netdevice.h>
+#include <linux/platform_device.h>
 #include <asm/io.h>
 #include <asm/mips-boards/simint.h>
 
index 8fbba21d975bc4ad7cbde8dcb9d1998acf3501a3..71f2c6705bc32ba018788e0283c76e71871af507 100644 (file)
@@ -39,6 +39,8 @@
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/ethtool.h>
+#include <linux/platform_device.h>
+
 #include <asm/io.h>
 #include <asm/types.h>
 #include <asm/pgtable.h>
index c573bb351d4c9bb11ce15876b7b58e98373cc933..74d5f1a6fdea262919736ebd9c86f45cd05d0a6e 100644 (file)
@@ -77,7 +77,7 @@ static const char version[] =
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/crc32.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
index eb1423ede75cae8032a0729fdb115e54fa9e7c86..d04c918ebef811ad60af0bdede6d5d1047ccb446 100644 (file)
@@ -29,6 +29,7 @@ static const char version[] = "proteon.c: v1.00 02/01/2003 by Jochen Friedrich\n
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/trdevice.h>
+#include <linux/platform_device.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
index 3c7c66204f7474d0005021afc7fe740698fc2d3a..72cf708396be3f87e9badd604ee3b5b3ab41c6a2 100644 (file)
@@ -36,6 +36,7 @@ static const char version[] = "skisa.c: v1.03 09/12/2002 by Jochen Friedrich\n";
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/trdevice.h>
+#include <linux/platform_device.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
index ba48cef3a9dc87faeffa7ba3cc7d355176a6a577..87302c548c24d437fa0722a01d2d832c7a7bdf38 100644 (file)
@@ -42,7 +42,7 @@
 #include <linux/notifier.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index b57a0b98b4d6b89c521c9172463b3ffc342f9aec..561706ba4499a8fc99eae63081b88212375d222c 100644 (file)
@@ -37,7 +37,7 @@
 #include <asm/errno.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/hd64465/hd64465.h>
index 4a41f67d185d9f5b181ced34f110d627433f2ce3..7ce455d01cc919a761ecd5de44bfc504c6246714 100644 (file)
@@ -47,7 +47,7 @@
 #include <linux/delay.h>
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/bitops.h>
 #include <asm/irq.h>
 #include <asm/io.h>
index c6ed70ea4812ec557a41d65469e31180c775cfc8..2c22b4b3619d58f6c1c1a5c107597eb724b2a7e5 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/delay.h>
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/bitops.h>
 #include <asm/irq.h>
 #include <asm/io.h>
index 3397ff28de6aa7897963dd3d6a64f8e68483f821..356a6fb416a14010c86c43df9927088038085a50 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/delay.h>
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 #include <asm/bitops.h>
index 2558c3cc91eca9eef0a6239c402a8c1afcbb092e..47b5ade95bde5ae8093997c208f79ed242a4aaa7 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index c2a12d53f6c76e9afd8341174db3bb40b79f47c2..7fa18fb814bc7b862478e38c4d3b3a42f3e79b40 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
+#include <linux/platform_device.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
index bbe69b07ce50406a1ab6fb3b23901cdca40b90ec..5209d8c7764fc13215135a9d6bfb3f0828ca380e 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <pcmcia/ss.h>
 
index bd924336a49fe041333745766c3358a1ecc020d4..fe5ea36e7de3878e63b7819cab7872c89d8acd49 100644 (file)
@@ -16,7 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/mach-types.h>
 #include <asm/hardware.h>
index acf60ffc8a124515dbe4cbd42355c647b8414ff0..6d441ec75c6a14bc1fa34e9b31cd866f1c6a8397 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/config.h>
+#include <linux/platform_device.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
index f158b67f661007c7b9a1ef64fd55a08f9f70d154..e312638643771c27bb75ce8f81c823b809a51a2b 100644 (file)
@@ -44,7 +44,7 @@
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/workqueue.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/bitops.h>
 
 #include <asm/io.h>
index 3d2dca675e02bc9483b8b8828d2ee948f7e6f52c..38a028c725d47e0aaebe529a6a33ff1e24710357 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/spinlock.h>
 #include <linux/sched.h>
 #include <linux/types.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 
index f24d84538fd56ab5c1d2cdd8df3c509fac8e5092..71dd1ebbe58f26b2740cd77a545e31d6c7472a01 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/completion.h>
 #include <linux/transport_class.h>
+#include <linux/platform_device.h>
 
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
index 00d6a6657ebc3ec78f19d28e25edb2e3354513d4..a440ea38efaa473c11ff379b8564604ca64d669c 100644 (file)
@@ -180,12 +180,22 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
                        return;
                }
                count = min(pc->sg->length - pc->b_count, bcount);
-               buf = kmap_atomic(pc->sg->page, KM_IRQ0);
-               drive->hwif->atapi_input_bytes(drive,
-                               buf + pc->b_count + pc->sg->offset, count);
-               kunmap_atomic(buf, KM_IRQ0);
-               bcount -= count;
-               pc->b_count += count;
+               if (PageHighMem(pc->sg->page)) {
+                       unsigned long flags;
+
+                       local_irq_save(flags);
+                       buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+                                       pc->sg->offset;
+                       drive->hwif->atapi_input_bytes(drive,
+                                               buf + pc->b_count, count);
+                       kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
+                       local_irq_restore(flags);
+               } else {
+                       buf = page_address(pc->sg->page) + pc->sg->offset;
+                       drive->hwif->atapi_input_bytes(drive,
+                                               buf + pc->b_count, count);
+               }
+               bcount -= count; pc->b_count += count;
                if (pc->b_count == pc->sg->length) {
                        pc->sg++;
                        pc->b_count = 0;
@@ -205,12 +215,22 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
                        return;
                }
                count = min(pc->sg->length - pc->b_count, bcount);
-               buf = kmap_atomic(pc->sg->page, KM_IRQ0);
-               drive->hwif->atapi_output_bytes(drive,
-                               buf + pc->b_count + pc->sg->offset, count);
-               kunmap_atomic(buf, KM_IRQ0);
-               bcount -= count;
-               pc->b_count += count;
+               if (PageHighMem(pc->sg->page)) {
+                       unsigned long flags;
+
+                       local_irq_save(flags);
+                       buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+                                               pc->sg->offset;
+                       drive->hwif->atapi_output_bytes(drive,
+                                               buf + pc->b_count, count);
+                       kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
+                       local_irq_restore(flags);
+               } else {
+                       buf = page_address(pc->sg->page) + pc->sg->offset;
+                       drive->hwif->atapi_output_bytes(drive,
+                                               buf + pc->b_count, count);
+               }
+               bcount -= count; pc->b_count += count;
                if (pc->b_count == pc->sg->length) {
                        pc->sg++;
                        pc->b_count = 0;
index 8be7dc0b47b849858c8d5b37872e7112fb8e3b31..ff18fa7044c593ebe61ebd184cc45ffbbc91b771 100644 (file)
@@ -294,28 +294,6 @@ void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
                ata_exec_command_pio(ap, tf);
 }
 
-/**
- *     ata_exec - issue ATA command to host controller
- *     @ap: port to which command is being issued
- *     @tf: ATA taskfile register set
- *
- *     Issues PIO/MMIO write to ATA command register, with proper
- *     synchronization with interrupt handler / other threads.
- *
- *     LOCKING:
- *     Obtains host_set lock.
- */
-
-static inline void ata_exec(struct ata_port *ap, const struct ata_taskfile *tf)
-{
-       unsigned long flags;
-
-       DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
-       spin_lock_irqsave(&ap->host_set->lock, flags);
-       ap->ops->exec_command(ap, tf);
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
-}
-
 /**
  *     ata_tf_to_host - issue ATA taskfile to host controller
  *     @ap: port to which command is being issued
@@ -326,30 +304,11 @@ static inline void ata_exec(struct ata_port *ap, const struct ata_taskfile *tf)
  *     other threads.
  *
  *     LOCKING:
- *     Obtains host_set lock.
- */
-
-static void ata_tf_to_host(struct ata_port *ap, const struct ata_taskfile *tf)
-{
-       ap->ops->tf_load(ap, tf);
-
-       ata_exec(ap, tf);
-}
-
-/**
- *     ata_tf_to_host_nolock - issue ATA taskfile to host controller
- *     @ap: port to which command is being issued
- *     @tf: ATA taskfile register set
- *
- *     Issues ATA taskfile register set to ATA host controller,
- *     with proper synchronization with interrupt handler and
- *     other threads.
- *
- *     LOCKING:
  *     spin_lock_irqsave(host_set lock)
  */
 
-void ata_tf_to_host_nolock(struct ata_port *ap, const struct ata_taskfile *tf)
+static inline void ata_tf_to_host(struct ata_port *ap,
+                                 const struct ata_taskfile *tf)
 {
        ap->ops->tf_load(ap, tf);
        ap->ops->exec_command(ap, tf);
@@ -1912,12 +1871,14 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
  *
  *     LOCKING:
  *     PCI/etc. bus probe sem.
+ *     Obtains host_set lock.
  *
  */
 
 static unsigned int ata_bus_edd(struct ata_port *ap)
 {
        struct ata_taskfile tf;
+       unsigned long flags;
 
        /* set up execute-device-diag (bus reset) taskfile */
        /* also, take interrupts to a known state (disabled) */
@@ -1928,7 +1889,9 @@ static unsigned int ata_bus_edd(struct ata_port *ap)
        tf.protocol = ATA_PROT_NODATA;
 
        /* do bus reset */
+       spin_lock_irqsave(&ap->host_set->lock, flags);
        ata_tf_to_host(ap, &tf);
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
 
        /* spec says at least 2ms.  but who knows with those
         * crazy ATAPI devices...
@@ -3555,7 +3518,7 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc)
 
        switch (qc->tf.protocol) {
        case ATA_PROT_NODATA:
-               ata_tf_to_host_nolock(ap, &qc->tf);
+               ata_tf_to_host(ap, &qc->tf);
                break;
 
        case ATA_PROT_DMA:
@@ -3566,20 +3529,20 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc)
 
        case ATA_PROT_PIO: /* load tf registers, initiate polling pio */
                ata_qc_set_polling(qc);
-               ata_tf_to_host_nolock(ap, &qc->tf);
+               ata_tf_to_host(ap, &qc->tf);
                ap->hsm_task_state = HSM_ST;
                queue_work(ata_wq, &ap->pio_task);
                break;
 
        case ATA_PROT_ATAPI:
                ata_qc_set_polling(qc);
-               ata_tf_to_host_nolock(ap, &qc->tf);
+               ata_tf_to_host(ap, &qc->tf);
                queue_work(ata_wq, &ap->packet_task);
                break;
 
        case ATA_PROT_ATAPI_NODATA:
                ap->flags |= ATA_FLAG_NOINTR;
-               ata_tf_to_host_nolock(ap, &qc->tf);
+               ata_tf_to_host(ap, &qc->tf);
                queue_work(ata_wq, &ap->packet_task);
                break;
 
@@ -4126,8 +4089,6 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
        host->unique_id = ata_unique_id++;
        host->max_cmd_len = 12;
 
-       scsi_assign_lock(host, &host_set->lock);
-
        ap->flags = ATA_FLAG_PORT_DISABLED;
        ap->id = host->unique_id;
        ap->host = host;
index 1e3792f86fcf4359171d46b6ac326b099844e905..248baae9648656f762bd3f15436effee84e4511f 100644 (file)
@@ -39,6 +39,7 @@
 #include <scsi/scsi.h>
 #include "scsi.h"
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
 #include <linux/libata.h>
 #include <linux/hdreg.h>
 #include <asm/uaccess.h>
@@ -2405,8 +2406,12 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
        struct ata_port *ap;
        struct ata_device *dev;
        struct scsi_device *scsidev = cmd->device;
+       struct Scsi_Host *shost = scsidev->host;
 
-       ap = (struct ata_port *) &scsidev->host->hostdata[0];
+       ap = (struct ata_port *) &shost->hostdata[0];
+
+       spin_unlock(shost->host_lock);
+       spin_lock(&ap->host_set->lock);
 
        ata_scsi_dump_cdb(ap, cmd);
 
@@ -2429,6 +2434,8 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
                ata_scsi_translate(ap, dev, cmd, done, atapi_xlat);
 
 out_unlock:
+       spin_unlock(&ap->host_set->lock);
+       spin_lock(shost->host_lock);
        return 0;
 }
 
index 10ecd9e15e4fb9296b8a0aa1eeacf99b5aaf2e29..fad051ca4672bf0daf6ed710cf4155f977bb7662 100644 (file)
@@ -48,7 +48,6 @@ extern int ata_qc_issue(struct ata_queued_cmd *qc);
 extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
 extern void ata_dev_select(struct ata_port *ap, unsigned int device,
                            unsigned int wait, unsigned int can_sleep);
-extern void ata_tf_to_host_nolock(struct ata_port *ap, const struct ata_taskfile *tf);
 extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
 extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg);
 extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
index afb7ddf200e082d8ee6032095f50db6b4dcdd771..f47d2c454e331be473b008398ac66a9f0778ab9f 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/sysrq.h>
 #include <linux/mca.h>
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial_reg.h>
index 5b3933b0c997f011897585c3cca97fd8b357c2dc..4a54ff5847003855e7643e3f57f64eb0947bb0eb 100644 (file)
@@ -36,7 +36,7 @@
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/sysrq.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial_core.h>
@@ -995,6 +995,7 @@ static int __init imx_serial_init(void)
 static void __exit imx_serial_exit(void)
 {
        uart_unregister_driver(&imx_reg);
+       driver_unregister(&serial_imx_driver);
 }
 
 module_init(imx_serial_init);
index 8a79968f8ce1f27b337bbdd21dc0b62c14a241d6..0dd08a09e7e693aded568a69ae827ca436534a7d 100644 (file)
@@ -45,7 +45,7 @@
  */
 
 #include <linux/config.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/module.h>
 #include <linux/tty.h>
 #include <linux/serial.h>
index aec83f577ce6c5c8f7be871af58c9db811a2d0b8..ba8838b234da7b89cfa2575a8689034b5b2cb3e9 100644 (file)
@@ -52,6 +52,8 @@
  * 4) AFAICT, hardware flow control isn't supported by the controller --MAG.
  */
 
+#include <linux/platform_device.h>
+
 #include "mpsc.h"
 
 /*
index 8cc4cedadd995066aae68c73681ea18e4827fd46..16b2f9417af9560aa040034357f06a383495b5b6 100644 (file)
@@ -39,7 +39,7 @@
 #include <linux/circ_buf.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial_core.h>
index 06a17dff1a7316d45e2d2f729b98b99e86a8bb29..036792328d499d4f6286174855897e4bb021ece1 100644 (file)
@@ -63,7 +63,7 @@
 
 #include <linux/module.h>
 #include <linux/ioport.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/init.h>
 #include <linux/sysrq.h>
 #include <linux/console.h>
index c4a789e6af447f3c7d111409cc39972f9df1c479..ed618cc7ae96e132ffcb5e9e32cfbe8de2d22675 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/sysrq.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial_core.h>
index 2b623ab0e36ec99f64373133e71ba907fe9b9f1b..01696b3e3f619f5b80aa9fcea4dfe4c4540790bb 100644 (file)
@@ -26,7 +26,7 @@
 #endif
 
 #include <linux/console.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
index 02106bebd5c1ff147dbb070cac83b43d4003758e..975ace3f5b1eac13362d2be4f51c8514ffac5899 100644 (file)
@@ -50,7 +50,7 @@
 #include <linux/list.h>
 #include <linux/interrupt.h>
 #include <linux/version.h>
-
+#include <linux/platform_device.h>
 #include <linux/usb.h>
 #include <linux/usb_gadget.h>
 
index 9b3673904daf33aa4c4575cacac497f8c92cb01f..bc6269f10cbb5d3fd1e1f4a3f0968bea15448c38 100644 (file)
@@ -21,6 +21,8 @@
  *
  */
 
+#include <linux/platform_device.h>
+
 #include "lh7a40x_udc.h"
 
 //#define DEBUG printk
index 41c96b0afbb372b650d26a8503bcaadd2bc9699f..387692a3611e7119560b606611e75d1ac881285f 100644 (file)
@@ -38,7 +38,7 @@
 #include <linux/proc_fs.h>
 #include <linux/mm.h>
 #include <linux/moduleparam.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/usb_ch9.h>
 #include <linux/usb_gadget.h>
 #include <linux/usb_otg.h>
index f83a9262f953364de6b908a733218f67bb7fa564..ee9cd7869d9268723e00451839bb132b6e4f9440 100644 (file)
@@ -43,7 +43,7 @@
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
 #include <linux/mm.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
 #include <asm/byteorder.h>
index ddb8fc5914663536d45b1c3be6b056f3630e2e88..f9c3f5b8dd1c3adcdcc79dc2f129bf2278b14796 100644 (file)
@@ -70,6 +70,7 @@
 #include <linux/interrupt.h>
 #include <linux/usb.h>
 #include <linux/usb_isp116x.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index a277e258eb6c5863337a267ea1a46a50cef6caa4..f0c78cf14b6ca6b11ec98010986d54179c41a5b6 100644 (file)
@@ -18,6 +18,8 @@
  * This file is licenced under the GPL.
  */
 
+#include <linux/platform_device.h>
+
 #include <asm/mach-au1x00/au1000.h>
 
 #define USBH_ENABLE_BE (1<<0)
index 238fa4ade615cb1578853f19bda97024479515bc..336c766c6e29f0334b52da96bc72103c4b0e8767 100644 (file)
@@ -16,6 +16,8 @@
  * This file is licenced under the GPL.
  */
 
+#include <linux/platform_device.h>
+
 #include <asm/hardware.h>
 
 
index 49815ec4b842374959f3aab35fa388d290196168..e46cc540cf4d3153fb49d9b942dfdf5652dc4f76 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/signal.h>      /* SA_INTERRUPT */
 #include <linux/jiffies.h>
+#include <linux/platform_device.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
index 4832e57ae579e4d17f1361298cb54e218c75128a..92cf6f4a13748ad9535e47d2ce827c6618aa3f75 100644 (file)
@@ -14,6 +14,8 @@
  * This file is licenced under the GPL.
  */
 
+#include <linux/platform_device.h>
+
 /* configure so an HC device and id are always provided */
 /* always called with process context; sleeping is OK */
 
index f4a4aeda40b7e3f1876f20dfa7371adeaba70db7..59e20568e8f947381753f590fdebf8b5467267bb 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <linux/device.h>
 #include <linux/signal.h>
+#include <linux/platform_device.h>
+
 #include <asm/mach-types.h>
 #include <asm/hardware.h>
 #include <asm/arch/pxa-regs.h>
index fab420a2ce712b4bcbcbb6ed38a6ba32b0e18f5c..ee1fc605b402c438729871c87c536ee4b2343200 100644 (file)
@@ -19,6 +19,8 @@
  * This file is licenced under the GPL.
 */
 
+#include <linux/platform_device.h>
+
 #include <asm/hardware.h>
 #include <asm/hardware/clock.h>
 #include <asm/arch/usb-control.h>
index b7fd3f644e1e557bb6924987181eced909f28cd7..b1aa350fd32f04d5b59322bfb0ea946c00c25083 100644 (file)
@@ -138,11 +138,23 @@ reset_needed:
 }
 EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc);
 
+static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
+{
+       u16 cmd;
+       return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask);
+}
+
+#define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO)
+#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY)
+
 static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
 {
        unsigned long base = 0;
        int i;
 
+       if (!pio_enabled(pdev))
+               return;
+
        for (i = 0; i < PCI_ROM_RESOURCE; i++)
                if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
                        base = pci_resource_start(pdev, i);
@@ -153,12 +165,20 @@ static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
                uhci_check_and_reset_hc(pdev, base);
 }
 
+static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx)
+{
+       return pci_resource_start(pdev, idx) && mmio_enabled(pdev);
+}
+
 static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
 {
        void __iomem *base;
        int wait_time;
        u32 control;
 
+       if (!mmio_resource_enabled(pdev, 0))
+               return;
+
        base = ioremap_nocache(pci_resource_start(pdev, 0),
                                     pci_resource_len(pdev, 0));
        if (base == NULL) return;
@@ -201,6 +221,9 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
        u32 hcc_params, val, temp;
        u8 cap_length;
 
+       if (!mmio_resource_enabled(pdev, 0))
+               return;
+
        base = ioremap_nocache(pci_resource_start(pdev, 0),
                                pci_resource_len(pdev, 0));
        if (base == NULL) return;
index 40169d9cf2b1855c6b5bdd060e16291423af8aad..5607c0ae683569525358ed5eabeec8c47781eb6d 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/interrupt.h>
 #include <linux/usb.h>
 #include <linux/usb_sl811.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
index 38aebe361ca140cb8e0255a474a0c5c87144dd8c..e73faf831b24bce4c1a0a16a9b017cdaae274f16 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/ioport.h>
+#include <linux/platform_device.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
index f02965f39501666fa9edc28b61a24b47fe2e3561..9b6a39348f81ab4415f01d8837c0990219b88efb 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/fb.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
 #include <asm/hardware.h>
index d28457e0c06373c34dfea3dfea8ec916b86bc489..126daff1c848fafba595223580ffbd847322118a 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/arcfb.h>
+#include <linux/platform_device.h>
 
 #include <asm/uaccess.h>
 
index 1991fdb32dfbc7b0d2592f2337c7265755d89d32..4867498f68e8e0b073157e472ce033e725251b60 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/fb.h>
 #include <linux/backlight.h>
index 1dbb82dca40b915649a288bec2f36f9cd8bd9999..1785686a7f11cc8a6120323a6106bc327eb6f345 100644 (file)
@@ -6,6 +6,8 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
 #include <asm/setup.h>
 #include <asm/system.h>
 #include <asm/irq.h>
index 116e808d71cd1819512e197af5aed5efd9b1346c..7363d0b25fdfc12fda931d845e24321e346a82b4 100644 (file)
@@ -54,6 +54,8 @@
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/platform_device.h>
+
 #include <asm/types.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
index 485604cd446268661ee82aa2bfc6d44bad0d8ae9..316bfe994811f54deadf88da8371b4da2bfbce8d 100644 (file)
@@ -11,7 +11,7 @@
 
 #include <linux/config.h>
 #include <linux/delay.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/errno.h>
 #include <linux/fb.h>
index 0b9301facbd356885f2ec2c8727a427358638b37..64d9bcc38da387fee71f375a0cfde75ce2d9bc4b 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/cpufreq.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
 #include <asm/hardware.h>
index 6206da9dd5dad23a61c8b901e4bb0e70c7c0c36a..efd9333b05c24001b13a8212be03a91215dbcdaf 100644 (file)
@@ -36,7 +36,7 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/cpufreq.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
 #include <asm/hardware.h>
index 162012bb9264edd2bb58af8b4d9b609e4b940697..8416b2e2b501f7cc723f95f55525f21196a429bd 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/platform_device.h>
 
 #include <asm/uaccess.h>
 #include <asm/setup.h>
index cb2f7a1de947795f3910dbac1794f65d2e496cb8..f4437430dc5f1bf1633ebd1e00f2d152ce31f452 100644 (file)
@@ -30,7 +30,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/delay.h>
 
 #include <linux/types.h>
index 3862d3cb1fb2d9b1511ef94a80d2b9b72e8c08d8..3cef90456a4b3fb341c10defa60043aad77404b8 100644 (file)
@@ -86,6 +86,7 @@
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
 #include <linux/wait.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
index 78e5f194b0df3969daba87721acb30b2b370ec28..3d35b28aaac7140affeedd874c4e9e3093b82204 100644 (file)
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/cpufreq.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 
 #include <asm/hardware.h>
index 8413907b379a147c1ac112604d7f897ed64a43ce..cf5106eab2d583ee387a9496bae2bc2373739f62 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/platform_device.h>
+
 #include <asm/io.h>
 #include <asm/mtrr.h>
 
index b1243da55fc5b9c53e96a1d3a6ddbfc802926e2e..3cc23106641db10e1a7787f52c5f9c3ee6d4dcf1 100644 (file)
@@ -19,6 +19,8 @@
 #include <linux/fb.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
+#include <linux/platform_device.h>
+
 #include <video/vga.h>
 #include <asm/io.h>
 #include <asm/mtrr.h>
index b137a3fe07525afed563ff99075adc57deb1d1b2..92d46555dd86e2fd02ee7985ef8ba41ca44d1b48 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
 #include <asm/uaccess.h>
 #include <linux/fb.h>
 #include <linux/init.h>
index 752bf88906a9de13b6578c8c0f2d989af87e795a..cf8cdb108fd95c0d1eb2f3be7e947804e6a5abb8 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/string.h>
 #include <linux/vmalloc.h>
 #include <asm/io.h>
index ffab4783ac644a984b6c0ff7a529b43720e6bc53..c27f8d4098be3cd713b2934f6eefdc8d03bb4a68 100644 (file)
@@ -247,7 +247,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
        wait_queue_head_t *wqh;
 
        if (!atomic_read(&inode->i_count))
-               WARN_ON(!(inode->i_state & I_WILL_FREE));
+               WARN_ON(!(inode->i_state & (I_WILL_FREE|I_FREEING)));
        else
                WARN_ON(inode->i_state & I_WILL_FREE);
 
index de58579a1d0e77a84e4f7d5fcc63c8eadcbb494d..50a7749cfca1bc73c0331ca032db93adaf5f348f 100644 (file)
@@ -1,18 +1,15 @@
 ToDo/Notes:
        - Find and fix bugs.
-       - In between ntfs_prepare/commit_write, need exclusion between
-         simultaneous file extensions.  This is given to us by holding i_sem
-         on the inode.  The only places in the kernel when a file is resized
-         are prepare/commit write and truncate for both of which i_sem is
-         held.  Just have to be careful in readpage/writepage and all other
-         helpers not running under i_sem that we play nice...
-         Also need to be careful with initialized_size extention in
-         ntfs_prepare_write. Basically, just be _very_ careful in this code...
-         UPDATE: The only things that need to be checked are read/writepage
-         which do not hold i_sem.  Note writepage cannot change i_size but it
-         needs to cope with a concurrent i_size change, just like readpage.
-         Also both need to cope with concurrent changes to the other sizes,
-         i.e. initialized/allocated/compressed size, as well.
+       - The only places in the kernel where a file is resized are
+         ntfs_file_write*() and ntfs_truncate() for both of which i_sem is
+         held.  Just have to be careful in read-/writepage and other helpers
+         not running under i_sem that we play nice...  Also need to be careful
+         with initialized_size extension in ntfs_file_write*() and writepage.
+         UPDATE: The only things that need to be checked are the compressed
+         write and the other attribute resize/write cases like index
+         attributes, etc.  For now none of these are implemented so are safe.
+       - Implement filling in of holes in aops.c::ntfs_writepage() and its
+         helpers.
        - Implement mft.c::sync_mft_mirror_umount().  We currently will just
          leave the volume dirty on umount if the final iput(vol->mft_ino)
          causes a write of any mirrored mft records due to the mft mirror
@@ -22,6 +19,68 @@ ToDo/Notes:
        - Enable the code for setting the NT4 compatibility flag when we start
          making NTFS 1.2 specific modifications.
 
+2.1.25 - (Almost) fully implement write(2) and truncate(2).
+
+       - Change ntfs_map_runlist_nolock(), ntfs_attr_find_vcn_nolock() and
+         {__,}ntfs_cluster_free() to also take an optional attribute search
+         context as argument.  This allows calling these functions with the
+         mft record mapped.  Update all callers.
+       - Fix potential deadlock in ntfs_mft_data_extend_allocation_nolock()
+         error handling by passing in the active search context when calling
+         ntfs_cluster_free().
+       - Change ntfs_cluster_alloc() to take an extra boolean parameter
+         specifying whether the cluster are being allocated to extend an
+         attribute or to fill a hole.
+       - Change ntfs_attr_make_non_resident() to call ntfs_cluster_alloc()
+         with @is_extension set to TRUE and remove the runlist terminator
+         fixup code as this is now done by ntfs_cluster_alloc().
+       - Change ntfs_attr_make_non_resident to take the attribute value size
+         as an extra parameter.  This is needed since we need to know the size
+         before we can map the mft record and our callers always know it.  The
+         reason we cannot simply read the size from the vfs inode i_size is
+         that this is not necessarily uptodate.  This happens when
+         ntfs_attr_make_non_resident() is called in the ->truncate call path.
+       - Fix ntfs_attr_make_non_resident() to update the vfs inode i_blocks
+         which is zero for a resident attribute but should no longer be zero
+         once the attribute is non-resident as it then has real clusters
+         allocated.
+       - Add fs/ntfs/attrib.[hc]::ntfs_attr_extend_allocation(), a function to
+         extend the allocation of an attributes.  Optionally, the data size,
+         but not the initialized size can be extended, too.
+       - Implement fs/ntfs/inode.[hc]::ntfs_truncate().  It only supports
+         uncompressed and unencrypted files and it never creates sparse files
+         at least for the moment (making a file sparse requires us to modify
+         its directory entries and we do not support directory operations at
+         the moment).  Also, support for highly fragmented files, i.e. ones
+         whose data attribute is split across multiple extents, is severly
+         limited.  When such a case is encountered, EOPNOTSUPP is returned.
+       - Enable ATTR_SIZE attribute changes in ntfs_setattr().  This completes
+         the initial implementation of file truncation.  Now both open(2)ing
+         a file with the O_TRUNC flag and the {,f}truncate(2) system calls
+         will resize a file appropriately.  The limitations are that only
+         uncompressed and unencrypted files are supported.  Also, there is
+         only very limited support for highly fragmented files (the ones whose
+         $DATA attribute is split into multiple attribute extents).
+       - In attrib.c::ntfs_attr_set() call balance_dirty_pages_ratelimited()
+         and cond_resched() in the main loop as we could be dirtying a lot of
+         pages and this ensures we play nice with the VM and the system as a
+         whole.
+       - Implement file operations ->write, ->aio_write, ->writev for regular
+         files.  This replaces the old use of generic_file_write(), et al and
+         the address space operations ->prepare_write and ->commit_write.
+         This means that both sparse and non-sparse (unencrypted and
+         uncompressed) files can now be extended using the normal write(2)
+         code path.  There are two limitations at present and these are that
+         we never create sparse files and that we only have limited support
+         for highly fragmented files, i.e. ones whose data attribute is split
+         across multiple extents.   When such a case is encountered,
+         EOPNOTSUPP is returned.
+       - $EA attributes can be both resident and non-resident.
+       - Use %z for size_t to fix compilation warnings.  (Andrew Morton)
+       - Fix compilation warnings with gcc-4.0.2 on SUSE 10.0.
+       - Document extended attribute ($EA) NEED_EA flag.  (Based on libntfs
+         patch by Yura Pakhuchiy.)
+
 2.1.24 - Lots of bug fixes and support more clean journal states.
 
        - Support journals ($LogFile) which have been modified by chkdsk.  This
index 894b2b876d353b5c61a81e30d39ef608993f9000..d0d45d1c853a95f495755d9339b92f23b489ee13 100644 (file)
@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \
             index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \
             unistr.o upcase.o
 
-EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.24\"
+EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.25\"
 
 ifeq ($(CONFIG_NTFS_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
index 5e80c07c6a4d2b0a9c141602efeac6f9b5b59614..1c0a4315876aec7ecd7f2e8a42c603562e916f01 100644 (file)
@@ -1391,8 +1391,7 @@ retry_writepage:
                if (NInoEncrypted(ni)) {
                        unlock_page(page);
                        BUG_ON(ni->type != AT_DATA);
-                       ntfs_debug("Denying write access to encrypted "
-                                       "file.");
+                       ntfs_debug("Denying write access to encrypted file.");
                        return -EACCES;
                }
                /* Compressed data streams are handled in compress.c. */
@@ -1508,8 +1507,8 @@ retry_writepage:
        /* Zero out of bounds area in the page cache page. */
        memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len);
        kunmap_atomic(kaddr, KM_USER0);
-       flush_dcache_mft_record_page(ctx->ntfs_ino);
        flush_dcache_page(page);
+       flush_dcache_mft_record_page(ctx->ntfs_ino);
        /* We are done with the page. */
        end_page_writeback(page);
        /* Finally, mark the mft record dirty, so it gets written back. */
@@ -1542,830 +1541,6 @@ err_out:
        return err;
 }
 
-/**
- * ntfs_prepare_nonresident_write -
- *
- */
-static int ntfs_prepare_nonresident_write(struct page *page,
-               unsigned from, unsigned to)
-{
-       VCN vcn;
-       LCN lcn;
-       s64 initialized_size;
-       loff_t i_size;
-       sector_t block, ablock, iblock;
-       struct inode *vi;
-       ntfs_inode *ni;
-       ntfs_volume *vol;
-       runlist_element *rl;
-       struct buffer_head *bh, *head, *wait[2], **wait_bh = wait;
-       unsigned long flags;
-       unsigned int vcn_ofs, block_start, block_end, blocksize;
-       int err;
-       BOOL is_retry;
-       unsigned char blocksize_bits;
-
-       vi = page->mapping->host;
-       ni = NTFS_I(vi);
-       vol = ni->vol;
-
-       ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
-                       "0x%lx, from = %u, to = %u.", ni->mft_no, ni->type,
-                       page->index, from, to);
-
-       BUG_ON(!NInoNonResident(ni));
-
-       blocksize_bits = vi->i_blkbits;
-       blocksize = 1 << blocksize_bits;
-
-       /*
-        * create_empty_buffers() will create uptodate/dirty buffers if the
-        * page is uptodate/dirty.
-        */
-       if (!page_has_buffers(page))
-               create_empty_buffers(page, blocksize, 0);
-       bh = head = page_buffers(page);
-       if (unlikely(!bh))
-               return -ENOMEM;
-
-       /* The first block in the page. */
-       block = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);
-
-       read_lock_irqsave(&ni->size_lock, flags);
-       /*
-        * The first out of bounds block for the allocated size.  No need to
-        * round up as allocated_size is in multiples of cluster size and the
-        * minimum cluster size is 512 bytes, which is equal to the smallest
-        * blocksize.
-        */
-       ablock = ni->allocated_size >> blocksize_bits;
-       i_size = i_size_read(vi);
-       initialized_size = ni->initialized_size;
-       read_unlock_irqrestore(&ni->size_lock, flags);
-
-       /* The last (fully or partially) initialized block. */
-       iblock = initialized_size >> blocksize_bits;
-
-       /* Loop through all the buffers in the page. */
-       block_start = 0;
-       rl = NULL;
-       err = 0;
-       do {
-               block_end = block_start + blocksize;
-               /*
-                * If buffer @bh is outside the write, just mark it uptodate
-                * if the page is uptodate and continue with the next buffer.
-                */
-               if (block_end <= from || block_start >= to) {
-                       if (PageUptodate(page)) {
-                               if (!buffer_uptodate(bh))
-                                       set_buffer_uptodate(bh);
-                       }
-                       continue;
-               }
-               /*
-                * @bh is at least partially being written to.
-                * Make sure it is not marked as new.
-                */
-               //if (buffer_new(bh))
-               //      clear_buffer_new(bh);
-
-               if (block >= ablock) {
-                       // TODO: block is above allocated_size, need to
-                       // allocate it. Best done in one go to accommodate not
-                       // only block but all above blocks up to and including:
-                       // ((page->index << PAGE_CACHE_SHIFT) + to + blocksize
-                       // - 1) >> blobksize_bits. Obviously will need to round
-                       // up to next cluster boundary, too. This should be
-                       // done with a helper function, so it can be reused.
-                       ntfs_error(vol->sb, "Writing beyond allocated size "
-                                       "is not supported yet. Sorry.");
-                       err = -EOPNOTSUPP;
-                       goto err_out;
-                       // Need to update ablock.
-                       // Need to set_buffer_new() on all block bhs that are
-                       // newly allocated.
-               }
-               /*
-                * Now we have enough allocated size to fulfill the whole
-                * request, i.e. block < ablock is true.
-                */
-               if (unlikely((block >= iblock) &&
-                               (initialized_size < i_size))) {
-                       /*
-                        * If this page is fully outside initialized size, zero
-                        * out all pages between the current initialized size
-                        * and the current page. Just use ntfs_readpage() to do
-                        * the zeroing transparently.
-                        */
-                       if (block > iblock) {
-                               // TODO:
-                               // For each page do:
-                               // - read_cache_page()
-                               // Again for each page do:
-                               // - wait_on_page_locked()
-                               // - Check (PageUptodate(page) &&
-                               //                      !PageError(page))
-                               // Update initialized size in the attribute and
-                               // in the inode.
-                               // Again, for each page do:
-                               //      __set_page_dirty_buffers();
-                               // page_cache_release()
-                               // We don't need to wait on the writes.
-                               // Update iblock.
-                       }
-                       /*
-                        * The current page straddles initialized size. Zero
-                        * all non-uptodate buffers and set them uptodate (and
-                        * dirty?). Note, there aren't any non-uptodate buffers
-                        * if the page is uptodate.
-                        * FIXME: For an uptodate page, the buffers may need to
-                        * be written out because they were not initialized on
-                        * disk before.
-                        */
-                       if (!PageUptodate(page)) {
-                               // TODO:
-                               // Zero any non-uptodate buffers up to i_size.
-                               // Set them uptodate and dirty.
-                       }
-                       // TODO:
-                       // Update initialized size in the attribute and in the
-                       // inode (up to i_size).
-                       // Update iblock.
-                       // FIXME: This is inefficient. Try to batch the two
-                       // size changes to happen in one go.
-                       ntfs_error(vol->sb, "Writing beyond initialized size "
-                                       "is not supported yet. Sorry.");
-                       err = -EOPNOTSUPP;
-                       goto err_out;
-                       // Do NOT set_buffer_new() BUT DO clear buffer range
-                       // outside write request range.
-                       // set_buffer_uptodate() on complete buffers as well as
-                       // set_buffer_dirty().
-               }
-
-               /* Need to map unmapped buffers. */
-               if (!buffer_mapped(bh)) {
-                       /* Unmapped buffer. Need to map it. */
-                       bh->b_bdev = vol->sb->s_bdev;
-
-                       /* Convert block into corresponding vcn and offset. */
-                       vcn = (VCN)block << blocksize_bits >>
-                                       vol->cluster_size_bits;
-                       vcn_ofs = ((VCN)block << blocksize_bits) &
-                                       vol->cluster_size_mask;
-
-                       is_retry = FALSE;
-                       if (!rl) {
-lock_retry_remap:
-                               down_read(&ni->runlist.lock);
-                               rl = ni->runlist.rl;
-                       }
-                       if (likely(rl != NULL)) {
-                               /* Seek to element containing target vcn. */
-                               while (rl->length && rl[1].vcn <= vcn)
-                                       rl++;
-                               lcn = ntfs_rl_vcn_to_lcn(rl, vcn);
-                       } else
-                               lcn = LCN_RL_NOT_MAPPED;
-                       if (unlikely(lcn < 0)) {
-                               /*
-                                * We extended the attribute allocation above.
-                                * If we hit an ENOENT here it means that the
-                                * allocation was insufficient which is a bug.
-                                */
-                               BUG_ON(lcn == LCN_ENOENT);
-
-                               /* It is a hole, need to instantiate it. */
-                               if (lcn == LCN_HOLE) {
-                                       // TODO: Instantiate the hole.
-                                       // clear_buffer_new(bh);
-                                       // unmap_underlying_metadata(bh->b_bdev,
-                                       //              bh->b_blocknr);
-                                       // For non-uptodate buffers, need to
-                                       // zero out the region outside the
-                                       // request in this bh or all bhs,
-                                       // depending on what we implemented
-                                       // above.
-                                       // Need to flush_dcache_page().
-                                       // Or could use set_buffer_new()
-                                       // instead?
-                                       ntfs_error(vol->sb, "Writing into "
-                                                       "sparse regions is "
-                                                       "not supported yet. "
-                                                       "Sorry.");
-                                       err = -EOPNOTSUPP;
-                                       if (!rl)
-                                               up_read(&ni->runlist.lock);
-                                       goto err_out;
-                               } else if (!is_retry &&
-                                               lcn == LCN_RL_NOT_MAPPED) {
-                                       is_retry = TRUE;
-                                       /*
-                                        * Attempt to map runlist, dropping
-                                        * lock for the duration.
-                                        */
-                                       up_read(&ni->runlist.lock);
-                                       err = ntfs_map_runlist(ni, vcn);
-                                       if (likely(!err))
-                                               goto lock_retry_remap;
-                                       rl = NULL;
-                               } else if (!rl)
-                                       up_read(&ni->runlist.lock);
-                               /*
-                                * Failed to map the buffer, even after
-                                * retrying.
-                                */
-                               if (!err)
-                                       err = -EIO;
-                               bh->b_blocknr = -1;
-                               ntfs_error(vol->sb, "Failed to write to inode "
-                                               "0x%lx, attribute type 0x%x, "
-                                               "vcn 0x%llx, offset 0x%x "
-                                               "because its location on disk "
-                                               "could not be determined%s "
-                                               "(error code %i).",
-                                               ni->mft_no, ni->type,
-                                               (unsigned long long)vcn,
-                                               vcn_ofs, is_retry ? " even "
-                                               "after retrying" : "", err);
-                               goto err_out;
-                       }
-                       /* We now have a successful remap, i.e. lcn >= 0. */
-
-                       /* Setup buffer head to correct block. */
-                       bh->b_blocknr = ((lcn << vol->cluster_size_bits)
-                                       + vcn_ofs) >> blocksize_bits;
-                       set_buffer_mapped(bh);
-
-                       // FIXME: Something analogous to this is needed for
-                       // each newly allocated block, i.e. BH_New.
-                       // FIXME: Might need to take this out of the
-                       // if (!buffer_mapped(bh)) {}, depending on how we
-                       // implement things during the allocated_size and
-                       // initialized_size extension code above.
-                       if (buffer_new(bh)) {
-                               clear_buffer_new(bh);
-                               unmap_underlying_metadata(bh->b_bdev,
-                                               bh->b_blocknr);
-                               if (PageUptodate(page)) {
-                                       set_buffer_uptodate(bh);
-                                       continue;
-                               }
-                               /*
-                                * Page is _not_ uptodate, zero surrounding
-                                * region. NOTE: This is how we decide if to
-                                * zero or not!
-                                */
-                               if (block_end > to || block_start < from) {
-                                       void *kaddr;
-
-                                       kaddr = kmap_atomic(page, KM_USER0);
-                                       if (block_end > to)
-                                               memset(kaddr + to, 0,
-                                                               block_end - to);
-                                       if (block_start < from)
-                                               memset(kaddr + block_start, 0,
-                                                               from -
-                                                               block_start);
-                                       flush_dcache_page(page);
-                                       kunmap_atomic(kaddr, KM_USER0);
-                               }
-                               continue;
-                       }
-               }
-               /* @bh is mapped, set it uptodate if the page is uptodate. */
-               if (PageUptodate(page)) {
-                       if (!buffer_uptodate(bh))
-                               set_buffer_uptodate(bh);
-                       continue;
-               }
-               /*
-                * The page is not uptodate. The buffer is mapped. If it is not
-                * uptodate, and it is only partially being written to, we need
-                * to read the buffer in before the write, i.e. right now.
-                */
-               if (!buffer_uptodate(bh) &&
-                               (block_start < from || block_end > to)) {
-                       ll_rw_block(READ, 1, &bh);
-                       *wait_bh++ = bh;
-               }
-       } while (block++, block_start = block_end,
-                       (bh = bh->b_this_page) != head);
-
-       /* Release the lock if we took it. */
-       if (rl) {
-               up_read(&ni->runlist.lock);
-               rl = NULL;
-       }
-
-       /* If we issued read requests, let them complete. */
-       while (wait_bh > wait) {
-               wait_on_buffer(*--wait_bh);
-               if (!buffer_uptodate(*wait_bh))
-                       return -EIO;
-       }
-
-       ntfs_debug("Done.");
-       return 0;
-err_out:
-       /*
-        * Zero out any newly allocated blocks to avoid exposing stale data.
-        * If BH_New is set, we know that the block was newly allocated in the
-        * above loop.
-        * FIXME: What about initialized_size increments? Have we done all the
-        * required zeroing above? If not this error handling is broken, and
-        * in particular the if (block_end <= from) check is completely bogus.
-        */
-       bh = head;
-       block_start = 0;
-       is_retry = FALSE;
-       do {
-               block_end = block_start + blocksize;
-               if (block_end <= from)
-                       continue;
-               if (block_start >= to)
-                       break;
-               if (buffer_new(bh)) {
-                       void *kaddr;
-
-                       clear_buffer_new(bh);
-                       kaddr = kmap_atomic(page, KM_USER0);
-                       memset(kaddr + block_start, 0, bh->b_size);
-                       kunmap_atomic(kaddr, KM_USER0);
-                       set_buffer_uptodate(bh);
-                       mark_buffer_dirty(bh);
-                       is_retry = TRUE;
-               }
-       } while (block_start = block_end, (bh = bh->b_this_page) != head);
-       if (is_retry)
-               flush_dcache_page(page);
-       if (rl)
-               up_read(&ni->runlist.lock);
-       return err;
-}
-
-/**
- * ntfs_prepare_write - prepare a page for receiving data
- *
- * This is called from generic_file_write() with i_sem held on the inode
- * (@page->mapping->host).  The @page is locked but not kmap()ped.  The source
- * data has not yet been copied into the @page.
- *
- * Need to extend the attribute/fill in holes if necessary, create blocks and
- * make partially overwritten blocks uptodate,
- *
- * i_size is not to be modified yet.
- *
- * Return 0 on success or -errno on error.
- *
- * Should be using block_prepare_write() [support for sparse files] or
- * cont_prepare_write() [no support for sparse files].  Cannot do that due to
- * ntfs specifics but can look at them for implementation guidance.
- *
- * Note: In the range, @from is inclusive and @to is exclusive, i.e. @from is
- * the first byte in the page that will be written to and @to is the first byte
- * after the last byte that will be written to.
- */
-static int ntfs_prepare_write(struct file *file, struct page *page,
-               unsigned from, unsigned to)
-{
-       s64 new_size;
-       loff_t i_size;
-       struct inode *vi = page->mapping->host;
-       ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi);
-       ntfs_volume *vol = ni->vol;
-       ntfs_attr_search_ctx *ctx = NULL;
-       MFT_RECORD *m = NULL;
-       ATTR_RECORD *a;
-       u8 *kaddr;
-       u32 attr_len;
-       int err;
-
-       ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
-                       "0x%lx, from = %u, to = %u.", vi->i_ino, ni->type,
-                       page->index, from, to);
-       BUG_ON(!PageLocked(page));
-       BUG_ON(from > PAGE_CACHE_SIZE);
-       BUG_ON(to > PAGE_CACHE_SIZE);
-       BUG_ON(from > to);
-       BUG_ON(NInoMstProtected(ni));
-       /*
-        * If a previous ntfs_truncate() failed, repeat it and abort if it
-        * fails again.
-        */
-       if (unlikely(NInoTruncateFailed(ni))) {
-               down_write(&vi->i_alloc_sem);
-               err = ntfs_truncate(vi);
-               up_write(&vi->i_alloc_sem);
-               if (err || NInoTruncateFailed(ni)) {
-                       if (!err)
-                               err = -EIO;
-                       goto err_out;
-               }
-       }
-       /* If the attribute is not resident, deal with it elsewhere. */
-       if (NInoNonResident(ni)) {
-               /*
-                * Only unnamed $DATA attributes can be compressed, encrypted,
-                * and/or sparse.
-                */
-               if (ni->type == AT_DATA && !ni->name_len) {
-                       /* If file is encrypted, deny access, just like NT4. */
-                       if (NInoEncrypted(ni)) {
-                               ntfs_debug("Denying write access to encrypted "
-                                               "file.");
-                               return -EACCES;
-                       }
-                       /* Compressed data streams are handled in compress.c. */
-                       if (NInoCompressed(ni)) {
-                               // TODO: Implement and replace this check with
-                               // return ntfs_write_compressed_block(page);
-                               ntfs_error(vi->i_sb, "Writing to compressed "
-                                               "files is not supported yet. "
-                                               "Sorry.");
-                               return -EOPNOTSUPP;
-                       }
-                       // TODO: Implement and remove this check.
-                       if (NInoSparse(ni)) {
-                               ntfs_error(vi->i_sb, "Writing to sparse files "
-                                               "is not supported yet. Sorry.");
-                               return -EOPNOTSUPP;
-                       }
-               }
-               /* Normal data stream. */
-               return ntfs_prepare_nonresident_write(page, from, to);
-       }
-       /*
-        * Attribute is resident, implying it is not compressed, encrypted, or
-        * sparse.
-        */
-       BUG_ON(page_has_buffers(page));
-       new_size = ((s64)page->index << PAGE_CACHE_SHIFT) + to;
-       /* If we do not need to resize the attribute allocation we are done. */
-       if (new_size <= i_size_read(vi))
-               goto done;
-       /* Map, pin, and lock the (base) mft record. */
-       if (!NInoAttr(ni))
-               base_ni = ni;
-       else
-               base_ni = ni->ext.base_ntfs_ino;
-       m = map_mft_record(base_ni);
-       if (IS_ERR(m)) {
-               err = PTR_ERR(m);
-               m = NULL;
-               ctx = NULL;
-               goto err_out;
-       }
-       ctx = ntfs_attr_get_search_ctx(base_ni, m);
-       if (unlikely(!ctx)) {
-               err = -ENOMEM;
-               goto err_out;
-       }
-       err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
-                       CASE_SENSITIVE, 0, NULL, 0, ctx);
-       if (unlikely(err)) {
-               if (err == -ENOENT)
-                       err = -EIO;
-               goto err_out;
-       }
-       m = ctx->mrec;
-       a = ctx->attr;
-       /* The total length of the attribute value. */
-       attr_len = le32_to_cpu(a->data.resident.value_length);
-       /* Fix an eventual previous failure of ntfs_commit_write(). */
-       i_size = i_size_read(vi);
-       if (unlikely(attr_len > i_size)) {
-               attr_len = i_size;
-               a->data.resident.value_length = cpu_to_le32(attr_len);
-       }
-       /* If we do not need to resize the attribute allocation we are done. */
-       if (new_size <= attr_len)
-               goto done_unm;
-       /* Check if new size is allowed in $AttrDef. */
-       err = ntfs_attr_size_bounds_check(vol, ni->type, new_size);
-       if (unlikely(err)) {
-               if (err == -ERANGE) {
-                       ntfs_error(vol->sb, "Write would cause the inode "
-                                       "0x%lx to exceed the maximum size for "
-                                       "its attribute type (0x%x).  Aborting "
-                                       "write.", vi->i_ino,
-                                       le32_to_cpu(ni->type));
-               } else {
-                       ntfs_error(vol->sb, "Inode 0x%lx has unknown "
-                                       "attribute type 0x%x.  Aborting "
-                                       "write.", vi->i_ino,
-                                       le32_to_cpu(ni->type));
-                       err = -EIO;
-               }
-               goto err_out2;
-       }
-       /*
-        * Extend the attribute record to be able to store the new attribute
-        * size.
-        */
-       if (new_size >= vol->mft_record_size || ntfs_attr_record_resize(m, a,
-                       le16_to_cpu(a->data.resident.value_offset) +
-                       new_size)) {
-               /* Not enough space in the mft record. */
-               ntfs_error(vol->sb, "Not enough space in the mft record for "
-                               "the resized attribute value.  This is not "
-                               "supported yet.  Aborting write.");
-               err = -EOPNOTSUPP;
-               goto err_out2;
-       }
-       /*
-        * We have enough space in the mft record to fit the write.  This
-        * implies the attribute is smaller than the mft record and hence the
-        * attribute must be in a single page and hence page->index must be 0.
-        */
-       BUG_ON(page->index);
-       /*
-        * If the beginning of the write is past the old size, enlarge the
-        * attribute value up to the beginning of the write and fill it with
-        * zeroes.
-        */
-       if (from > attr_len) {
-               memset((u8*)a + le16_to_cpu(a->data.resident.value_offset) +
-                               attr_len, 0, from - attr_len);
-               a->data.resident.value_length = cpu_to_le32(from);
-               /* Zero the corresponding area in the page as well. */
-               if (PageUptodate(page)) {
-                       kaddr = kmap_atomic(page, KM_USER0);
-                       memset(kaddr + attr_len, 0, from - attr_len);
-                       kunmap_atomic(kaddr, KM_USER0);
-                       flush_dcache_page(page);
-               }
-       }
-       flush_dcache_mft_record_page(ctx->ntfs_ino);
-       mark_mft_record_dirty(ctx->ntfs_ino);
-done_unm:
-       ntfs_attr_put_search_ctx(ctx);
-       unmap_mft_record(base_ni);
-       /*
-        * Because resident attributes are handled by memcpy() to/from the
-        * corresponding MFT record, and because this form of i/o is byte
-        * aligned rather than block aligned, there is no need to bring the
-        * page uptodate here as in the non-resident case where we need to
-        * bring the buffers straddled by the write uptodate before
-        * generic_file_write() does the copying from userspace.
-        *
-        * We thus defer the uptodate bringing of the page region outside the
-        * region written to to ntfs_commit_write(), which makes the code
-        * simpler and saves one atomic kmap which is good.
-        */
-done:
-       ntfs_debug("Done.");
-       return 0;
-err_out:
-       if (err == -ENOMEM)
-               ntfs_warning(vi->i_sb, "Error allocating memory required to "
-                               "prepare the write.");
-       else {
-               ntfs_error(vi->i_sb, "Resident attribute prepare write failed "
-                               "with error %i.", err);
-               NVolSetErrors(vol);
-               make_bad_inode(vi);
-       }
-err_out2:
-       if (ctx)
-               ntfs_attr_put_search_ctx(ctx);
-       if (m)
-               unmap_mft_record(base_ni);
-       return err;
-}
-
-/**
- * ntfs_commit_nonresident_write -
- *
- */
-static int ntfs_commit_nonresident_write(struct page *page,
-               unsigned from, unsigned to)
-{
-       s64 pos = ((s64)page->index << PAGE_CACHE_SHIFT) + to;
-       struct inode *vi = page->mapping->host;
-       struct buffer_head *bh, *head;
-       unsigned int block_start, block_end, blocksize;
-       BOOL partial;
-
-       ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
-                       "0x%lx, from = %u, to = %u.", vi->i_ino,
-                       NTFS_I(vi)->type, page->index, from, to);
-       blocksize = 1 << vi->i_blkbits;
-
-       // FIXME: We need a whole slew of special cases in here for compressed
-       // files for example...
-       // For now, we know ntfs_prepare_write() would have failed so we can't
-       // get here in any of the cases which we have to special case, so we
-       // are just a ripped off, unrolled generic_commit_write().
-
-       bh = head = page_buffers(page);
-       block_start = 0;
-       partial = FALSE;
-       do {
-               block_end = block_start + blocksize;
-               if (block_end <= from || block_start >= to) {
-                       if (!buffer_uptodate(bh))
-                               partial = TRUE;
-               } else {
-                       set_buffer_uptodate(bh);
-                       mark_buffer_dirty(bh);
-               }
-       } while (block_start = block_end, (bh = bh->b_this_page) != head);
-       /*
-        * If this is a partial write which happened to make all buffers
-        * uptodate then we can optimize away a bogus ->readpage() for the next
-        * read().  Here we 'discover' whether the page went uptodate as a
-        * result of this (potentially partial) write.
-        */
-       if (!partial)
-               SetPageUptodate(page);
-       /*
-        * Not convinced about this at all.  See disparity comment above.  For
-        * now we know ntfs_prepare_write() would have failed in the write
-        * exceeds i_size case, so this will never trigger which is fine.
-        */
-       if (pos > i_size_read(vi)) {
-               ntfs_error(vi->i_sb, "Writing beyond the existing file size is "
-                               "not supported yet.  Sorry.");
-               return -EOPNOTSUPP;
-               // vi->i_size = pos;
-               // mark_inode_dirty(vi);
-       }
-       ntfs_debug("Done.");
-       return 0;
-}
-
-/**
- * ntfs_commit_write - commit the received data
- *
- * This is called from generic_file_write() with i_sem held on the inode
- * (@page->mapping->host).  The @page is locked but not kmap()ped.  The source
- * data has already been copied into the @page.  ntfs_prepare_write() has been
- * called before the data copied and it returned success so we can take the
- * results of various BUG checks and some error handling for granted.
- *
- * Need to mark modified blocks dirty so they get written out later when
- * ntfs_writepage() is invoked by the VM.
- *
- * Return 0 on success or -errno on error.
- *
- * Should be using generic_commit_write().  This marks buffers uptodate and
- * dirty, sets the page uptodate if all buffers in the page are uptodate, and
- * updates i_size if the end of io is beyond i_size.  In that case, it also
- * marks the inode dirty.
- *
- * Cannot use generic_commit_write() due to ntfs specialities but can look at
- * it for implementation guidance.
- *
- * If things have gone as outlined in ntfs_prepare_write(), then we do not
- * need to do any page content modifications here at all, except in the write
- * to resident attribute case, where we need to do the uptodate bringing here
- * which we combine with the copying into the mft record which means we save
- * one atomic kmap.
- */
-static int ntfs_commit_write(struct file *file, struct page *page,
-               unsigned from, unsigned to)
-{
-       struct inode *vi = page->mapping->host;
-       ntfs_inode *base_ni, *ni = NTFS_I(vi);
-       char *kaddr, *kattr;
-       ntfs_attr_search_ctx *ctx;
-       MFT_RECORD *m;
-       ATTR_RECORD *a;
-       u32 attr_len;
-       int err;
-
-       ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
-                       "0x%lx, from = %u, to = %u.", vi->i_ino, ni->type,
-                       page->index, from, to);
-       /* If the attribute is not resident, deal with it elsewhere. */
-       if (NInoNonResident(ni)) {
-               /* Only unnamed $DATA attributes can be compressed/encrypted. */
-               if (ni->type == AT_DATA && !ni->name_len) {
-                       /* Encrypted files need separate handling. */
-                       if (NInoEncrypted(ni)) {
-                               // We never get here at present!
-                               BUG();
-                       }
-                       /* Compressed data streams are handled in compress.c. */
-                       if (NInoCompressed(ni)) {
-                               // TODO: Implement this!
-                               // return ntfs_write_compressed_block(page);
-                               // We never get here at present!
-                               BUG();
-                       }
-               }
-               /* Normal data stream. */
-               return ntfs_commit_nonresident_write(page, from, to);
-       }
-       /*
-        * Attribute is resident, implying it is not compressed, encrypted, or
-        * sparse.
-        */
-       if (!NInoAttr(ni))
-               base_ni = ni;
-       else
-               base_ni = ni->ext.base_ntfs_ino;
-       /* Map, pin, and lock the mft record. */
-       m = map_mft_record(base_ni);
-       if (IS_ERR(m)) {
-               err = PTR_ERR(m);
-               m = NULL;
-               ctx = NULL;
-               goto err_out;
-       }
-       ctx = ntfs_attr_get_search_ctx(base_ni, m);
-       if (unlikely(!ctx)) {
-               err = -ENOMEM;
-               goto err_out;
-       }
-       err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
-                       CASE_SENSITIVE, 0, NULL, 0, ctx);
-       if (unlikely(err)) {
-               if (err == -ENOENT)
-                       err = -EIO;
-               goto err_out;
-       }
-       a = ctx->attr;
-       /* The total length of the attribute value. */
-       attr_len = le32_to_cpu(a->data.resident.value_length);
-       BUG_ON(from > attr_len);
-       kattr = (u8*)a + le16_to_cpu(a->data.resident.value_offset);
-       kaddr = kmap_atomic(page, KM_USER0);
-       /* Copy the received data from the page to the mft record. */
-       memcpy(kattr + from, kaddr + from, to - from);
-       /* Update the attribute length if necessary. */
-       if (to > attr_len) {
-               attr_len = to;
-               a->data.resident.value_length = cpu_to_le32(attr_len);
-       }
-       /*
-        * If the page is not uptodate, bring the out of bounds area(s)
-        * uptodate by copying data from the mft record to the page.
-        */
-       if (!PageUptodate(page)) {
-               if (from > 0)
-                       memcpy(kaddr, kattr, from);
-               if (to < attr_len)
-                       memcpy(kaddr + to, kattr + to, attr_len - to);
-               /* Zero the region outside the end of the attribute value. */
-               if (attr_len < PAGE_CACHE_SIZE)
-                       memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len);
-               /*
-                * The probability of not having done any of the above is
-                * extremely small, so we just flush unconditionally.
-                */
-               flush_dcache_page(page);
-               SetPageUptodate(page);
-       }
-       kunmap_atomic(kaddr, KM_USER0);
-       /* Update i_size if necessary. */
-       if (i_size_read(vi) < attr_len) {
-               unsigned long flags;
-
-               write_lock_irqsave(&ni->size_lock, flags);
-               ni->allocated_size = ni->initialized_size = attr_len;
-               i_size_write(vi, attr_len);
-               write_unlock_irqrestore(&ni->size_lock, flags);
-       }
-       /* Mark the mft record dirty, so it gets written back. */
-       flush_dcache_mft_record_page(ctx->ntfs_ino);
-       mark_mft_record_dirty(ctx->ntfs_ino);
-       ntfs_attr_put_search_ctx(ctx);
-       unmap_mft_record(base_ni);
-       ntfs_debug("Done.");
-       return 0;
-err_out:
-       if (err == -ENOMEM) {
-               ntfs_warning(vi->i_sb, "Error allocating memory required to "
-                               "commit the write.");
-               if (PageUptodate(page)) {
-                       ntfs_warning(vi->i_sb, "Page is uptodate, setting "
-                                       "dirty so the write will be retried "
-                                       "later on by the VM.");
-                       /*
-                        * Put the page on mapping->dirty_pages, but leave its
-                        * buffers' dirty state as-is.
-                        */
-                       __set_page_dirty_nobuffers(page);
-                       err = 0;
-               } else
-                       ntfs_error(vi->i_sb, "Page is not uptodate.  Written "
-                                       "data has been lost.");
-       } else {
-               ntfs_error(vi->i_sb, "Resident attribute commit write failed "
-                               "with error %i.", err);
-               NVolSetErrors(ni->vol);
-               make_bad_inode(vi);
-       }
-       if (ctx)
-               ntfs_attr_put_search_ctx(ctx);
-       if (m)
-               unmap_mft_record(base_ni);
-       return err;
-}
-
 #endif /* NTFS_RW */
 
 /**
@@ -2377,9 +1552,6 @@ struct address_space_operations ntfs_aops = {
                                                   disk request queue. */
 #ifdef NTFS_RW
        .writepage      = ntfs_writepage,       /* Write dirty page to disk. */
-       .prepare_write  = ntfs_prepare_write,   /* Prepare page and buffers
-                                                  ready to receive data. */
-       .commit_write   = ntfs_commit_write,    /* Commit received data. */
 #endif /* NTFS_RW */
 };
 
index 3f9a4ff42ee51b07b75e57691997087df11a181d..eda056bac2567a51c99ef521347e066ac04f86a5 100644 (file)
@@ -21,7 +21,9 @@
  */
 
 #include <linux/buffer_head.h>
+#include <linux/sched.h>
 #include <linux/swap.h>
+#include <linux/writeback.h>
 
 #include "attrib.h"
 #include "debug.h"
  * ntfs_map_runlist_nolock - map (a part of) a runlist of an ntfs inode
  * @ni:                ntfs inode for which to map (part of) a runlist
  * @vcn:       map runlist part containing this vcn
+ * @ctx:       active attribute search context if present or NULL if not
  *
  * Map the part of a runlist containing the @vcn of the ntfs inode @ni.
  *
+ * If @ctx is specified, it is an active search context of @ni and its base mft
+ * record.  This is needed when ntfs_map_runlist_nolock() encounters unmapped
+ * runlist fragments and allows their mapping.  If you do not have the mft
+ * record mapped, you can specify @ctx as NULL and ntfs_map_runlist_nolock()
+ * will perform the necessary mapping and unmapping.
+ *
+ * Note, ntfs_map_runlist_nolock() saves the state of @ctx on entry and
+ * restores it before returning.  Thus, @ctx will be left pointing to the same
+ * attribute on return as on entry.  However, the actual pointers in @ctx may
+ * point to different memory locations on return, so you must remember to reset
+ * any cached pointers from the @ctx, i.e. after the call to
+ * ntfs_map_runlist_nolock(), you will probably want to do:
+ *     m = ctx->mrec;
+ *     a = ctx->attr;
+ * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
+ * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
+ *
  * Return 0 on success and -errno on error.  There is one special error code
  * which is not an error as such.  This is -ENOENT.  It means that @vcn is out
  * of bounds of the runlist.
  * Note the runlist can be NULL after this function returns if @vcn is zero and
  * the attribute has zero allocated size, i.e. there simply is no runlist.
  *
- * Locking: - The runlist must be locked for writing.
- *         - This function modifies the runlist.
+ * WARNING: If @ctx is supplied, regardless of whether success or failure is
+ *         returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
+ *         is no longer valid, i.e. you need to either call
+ *         ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
+ *         In that case PTR_ERR(@ctx->mrec) will give you the error code for
+ *         why the mapping of the old inode failed.
+ *
+ * Locking: - The runlist described by @ni must be locked for writing on entry
+ *           and is locked on return.  Note the runlist will be modified.
+ *         - If @ctx is NULL, the base mft record of @ni must not be mapped on
+ *           entry and it will be left unmapped on return.
+ *         - If @ctx is not NULL, the base mft record must be mapped on entry
+ *           and it will be left mapped on return.
  */
-int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
+int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx)
 {
        VCN end_vcn;
+       unsigned long flags;
        ntfs_inode *base_ni;
        MFT_RECORD *m;
        ATTR_RECORD *a;
-       ntfs_attr_search_ctx *ctx;
        runlist_element *rl;
-       unsigned long flags;
+       struct page *put_this_page = NULL;
        int err = 0;
+       BOOL ctx_is_temporary, ctx_needs_reset;
+       ntfs_attr_search_ctx old_ctx = { NULL, };
 
        ntfs_debug("Mapping runlist part containing vcn 0x%llx.",
                        (unsigned long long)vcn);
@@ -66,20 +99,77 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
                base_ni = ni;
        else
                base_ni = ni->ext.base_ntfs_ino;
-       m = map_mft_record(base_ni);
-       if (IS_ERR(m))
-               return PTR_ERR(m);
-       ctx = ntfs_attr_get_search_ctx(base_ni, m);
-       if (unlikely(!ctx)) {
-               err = -ENOMEM;
-               goto err_out;
+       if (!ctx) {
+               ctx_is_temporary = ctx_needs_reset = TRUE;
+               m = map_mft_record(base_ni);
+               if (IS_ERR(m))
+                       return PTR_ERR(m);
+               ctx = ntfs_attr_get_search_ctx(base_ni, m);
+               if (unlikely(!ctx)) {
+                       err = -ENOMEM;
+                       goto err_out;
+               }
+       } else {
+               VCN allocated_size_vcn;
+
+               BUG_ON(IS_ERR(ctx->mrec));
+               a = ctx->attr;
+               BUG_ON(!a->non_resident);
+               ctx_is_temporary = FALSE;
+               end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn);
+               read_lock_irqsave(&ni->size_lock, flags);
+               allocated_size_vcn = ni->allocated_size >>
+                               ni->vol->cluster_size_bits;
+               read_unlock_irqrestore(&ni->size_lock, flags);
+               if (!a->data.non_resident.lowest_vcn && end_vcn <= 0)
+                       end_vcn = allocated_size_vcn - 1;
+               /*
+                * If we already have the attribute extent containing @vcn in
+                * @ctx, no need to look it up again.  We slightly cheat in
+                * that if vcn exceeds the allocated size, we will refuse to
+                * map the runlist below, so there is definitely no need to get
+                * the right attribute extent.
+                */
+               if (vcn >= allocated_size_vcn || (a->type == ni->type &&
+                               a->name_length == ni->name_len &&
+                               !memcmp((u8*)a + le16_to_cpu(a->name_offset),
+                               ni->name, ni->name_len) &&
+                               sle64_to_cpu(a->data.non_resident.lowest_vcn)
+                               <= vcn && end_vcn >= vcn))
+                       ctx_needs_reset = FALSE;
+               else {
+                       /* Save the old search context. */
+                       old_ctx = *ctx;
+                       /*
+                        * If the currently mapped (extent) inode is not the
+                        * base inode we will unmap it when we reinitialize the
+                        * search context which means we need to get a
+                        * reference to the page containing the mapped mft
+                        * record so we do not accidentally drop changes to the
+                        * mft record when it has not been marked dirty yet.
+                        */
+                       if (old_ctx.base_ntfs_ino && old_ctx.ntfs_ino !=
+                                       old_ctx.base_ntfs_ino) {
+                               put_this_page = old_ctx.ntfs_ino->page;
+                               page_cache_get(put_this_page);
+                       }
+                       /*
+                        * Reinitialize the search context so we can lookup the
+                        * needed attribute extent.
+                        */
+                       ntfs_attr_reinit_search_ctx(ctx);
+                       ctx_needs_reset = TRUE;
+               }
        }
-       err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
-                       CASE_SENSITIVE, vcn, NULL, 0, ctx);
-       if (unlikely(err)) {
-               if (err == -ENOENT)
-                       err = -EIO;
-               goto err_out;
+       if (ctx_needs_reset) {
+               err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+                               CASE_SENSITIVE, vcn, NULL, 0, ctx);
+               if (unlikely(err)) {
+                       if (err == -ENOENT)
+                               err = -EIO;
+                       goto err_out;
+               }
+               BUG_ON(!ctx->attr->non_resident);
        }
        a = ctx->attr;
        /*
@@ -89,11 +179,9 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
         * ntfs_mapping_pairs_decompress() fails.
         */
        end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1;
-       if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1)) {
-               read_lock_irqsave(&ni->size_lock, flags);
-               end_vcn = ni->allocated_size >> ni->vol->cluster_size_bits;
-               read_unlock_irqrestore(&ni->size_lock, flags);
-       }
+       if (!a->data.non_resident.lowest_vcn && end_vcn == 1)
+               end_vcn = sle64_to_cpu(a->data.non_resident.allocated_size) >>
+                               ni->vol->cluster_size_bits;
        if (unlikely(vcn >= end_vcn)) {
                err = -ENOENT;
                goto err_out;
@@ -104,9 +192,93 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
        else
                ni->runlist.rl = rl;
 err_out:
-       if (likely(ctx))
-               ntfs_attr_put_search_ctx(ctx);
-       unmap_mft_record(base_ni);
+       if (ctx_is_temporary) {
+               if (likely(ctx))
+                       ntfs_attr_put_search_ctx(ctx);
+               unmap_mft_record(base_ni);
+       } else if (ctx_needs_reset) {
+               /*
+                * If there is no attribute list, restoring the search context
+                * is acomplished simply by copying the saved context back over
+                * the caller supplied context.  If there is an attribute list,
+                * things are more complicated as we need to deal with mapping
+                * of mft records and resulting potential changes in pointers.
+                */
+               if (NInoAttrList(base_ni)) {
+                       /*
+                        * If the currently mapped (extent) inode is not the
+                        * one we had before, we need to unmap it and map the
+                        * old one.
+                        */
+                       if (ctx->ntfs_ino != old_ctx.ntfs_ino) {
+                               /*
+                                * If the currently mapped inode is not the
+                                * base inode, unmap it.
+                                */
+                               if (ctx->base_ntfs_ino && ctx->ntfs_ino !=
+                                               ctx->base_ntfs_ino) {
+                                       unmap_extent_mft_record(ctx->ntfs_ino);
+                                       ctx->mrec = ctx->base_mrec;
+                                       BUG_ON(!ctx->mrec);
+                               }
+                               /*
+                                * If the old mapped inode is not the base
+                                * inode, map it.
+                                */
+                               if (old_ctx.base_ntfs_ino &&
+                                               old_ctx.ntfs_ino !=
+                                               old_ctx.base_ntfs_ino) {
+retry_map:
+                                       ctx->mrec = map_mft_record(
+                                                       old_ctx.ntfs_ino);
+                                       /*
+                                        * Something bad has happened.  If out
+                                        * of memory retry till it succeeds.
+                                        * Any other errors are fatal and we
+                                        * return the error code in ctx->mrec.
+                                        * Let the caller deal with it...  We
+                                        * just need to fudge things so the
+                                        * caller can reinit and/or put the
+                                        * search context safely.
+                                        */
+                                       if (IS_ERR(ctx->mrec)) {
+                                               if (PTR_ERR(ctx->mrec) ==
+                                                               -ENOMEM) {
+                                                       schedule();
+                                                       goto retry_map;
+                                               } else
+                                                       old_ctx.ntfs_ino =
+                                                               old_ctx.
+                                                               base_ntfs_ino;
+                                       }
+                               }
+                       }
+                       /* Update the changed pointers in the saved context. */
+                       if (ctx->mrec != old_ctx.mrec) {
+                               if (!IS_ERR(ctx->mrec))
+                                       old_ctx.attr = (ATTR_RECORD*)(
+                                                       (u8*)ctx->mrec +
+                                                       ((u8*)old_ctx.attr -
+                                                       (u8*)old_ctx.mrec));
+                               old_ctx.mrec = ctx->mrec;
+                       }
+               }
+               /* Restore the search context to the saved one. */
+               *ctx = old_ctx;
+               /*
+                * We drop the reference on the page we took earlier.  In the
+                * case that IS_ERR(ctx->mrec) is true this means we might lose
+                * some changes to the mft record that had been made between
+                * the last time it was marked dirty/written out and now.  This
+                * at this stage is not a problem as the mapping error is fatal
+                * enough that the mft record cannot be written out anyway and
+                * the caller is very likely to shutdown the whole inode
+                * immediately and mark the volume dirty for chkdsk to pick up
+                * the pieces anyway.
+                */
+               if (put_this_page)
+                       page_cache_release(put_this_page);
+       }
        return err;
 }
 
@@ -122,8 +294,8 @@ err_out:
  * of bounds of the runlist.
  *
  * Locking: - The runlist must be unlocked on entry and is unlocked on return.
- *         - This function takes the runlist lock for writing and modifies the
- *           runlist.
+ *         - This function takes the runlist lock for writing and may modify
+ *           the runlist.
  */
 int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)
 {
@@ -133,7 +305,7 @@ int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)
        /* Make sure someone else didn't do the work while we were sleeping. */
        if (likely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) <=
                        LCN_RL_NOT_MAPPED))
-               err = ntfs_map_runlist_nolock(ni, vcn);
+               err = ntfs_map_runlist_nolock(ni, vcn, NULL);
        up_write(&ni->runlist.lock);
        return err;
 }
@@ -212,7 +384,7 @@ retry_remap:
                                goto retry_remap;
                        }
                }
-               err = ntfs_map_runlist_nolock(ni, vcn);
+               err = ntfs_map_runlist_nolock(ni, vcn, NULL);
                if (!write_locked) {
                        up_write(&ni->runlist.lock);
                        down_read(&ni->runlist.lock);
@@ -236,9 +408,9 @@ retry_remap:
 
 /**
  * ntfs_attr_find_vcn_nolock - find a vcn in the runlist of an ntfs inode
- * @ni:                        ntfs inode describing the runlist to search
- * @vcn:               vcn to find
- * @write_locked:      true if the runlist is locked for writing
+ * @ni:                ntfs inode describing the runlist to search
+ * @vcn:       vcn to find
+ * @ctx:       active attribute search context if present or NULL if not
  *
  * Find the virtual cluster number @vcn in the runlist described by the ntfs
  * inode @ni and return the address of the runlist element containing the @vcn.
@@ -246,9 +418,22 @@ retry_remap:
  * If the @vcn is not mapped yet, the attempt is made to map the attribute
  * extent containing the @vcn and the vcn to lcn conversion is retried.
  *
- * If @write_locked is true the caller has locked the runlist for writing and
- * if false for reading.
- *
+ * If @ctx is specified, it is an active search context of @ni and its base mft
+ * record.  This is needed when ntfs_attr_find_vcn_nolock() encounters unmapped
+ * runlist fragments and allows their mapping.  If you do not have the mft
+ * record mapped, you can specify @ctx as NULL and ntfs_attr_find_vcn_nolock()
+ * will perform the necessary mapping and unmapping.
+ *
+ * Note, ntfs_attr_find_vcn_nolock() saves the state of @ctx on entry and
+ * restores it before returning.  Thus, @ctx will be left pointing to the same
+ * attribute on return as on entry.  However, the actual pointers in @ctx may
+ * point to different memory locations on return, so you must remember to reset
+ * any cached pointers from the @ctx, i.e. after the call to
+ * ntfs_attr_find_vcn_nolock(), you will probably want to do:
+ *     m = ctx->mrec;
+ *     a = ctx->attr;
+ * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
+ * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
  * Note you need to distinguish between the lcn of the returned runlist element
  * being >= 0 and LCN_HOLE.  In the later case you have to return zeroes on
  * read and allocate clusters on write.
@@ -263,22 +448,31 @@ retry_remap:
  *     -ENOMEM - Not enough memory to map runlist.
  *     -EIO    - Critical error (runlist/file is corrupt, i/o error, etc).
  *
- * Locking: - The runlist must be locked on entry and is left locked on return.
- *         - If @write_locked is FALSE, i.e. the runlist is locked for reading,
- *           the lock may be dropped inside the function so you cannot rely on
- *           the runlist still being the same when this function returns.
+ * WARNING: If @ctx is supplied, regardless of whether success or failure is
+ *         returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
+ *         is no longer valid, i.e. you need to either call
+ *         ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
+ *         In that case PTR_ERR(@ctx->mrec) will give you the error code for
+ *         why the mapping of the old inode failed.
+ *
+ * Locking: - The runlist described by @ni must be locked for writing on entry
+ *           and is locked on return.  Note the runlist may be modified when
+ *           needed runlist fragments need to be mapped.
+ *         - If @ctx is NULL, the base mft record of @ni must not be mapped on
+ *           entry and it will be left unmapped on return.
+ *         - If @ctx is not NULL, the base mft record must be mapped on entry
+ *           and it will be left mapped on return.
  */
 runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
-               const BOOL write_locked)
+               ntfs_attr_search_ctx *ctx)
 {
        unsigned long flags;
        runlist_element *rl;
        int err = 0;
        BOOL is_retry = FALSE;
 
-       ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
-                       ni->mft_no, (unsigned long long)vcn,
-                       write_locked ? "write" : "read");
+       ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, with%s ctx.",
+                       ni->mft_no, (unsigned long long)vcn, ctx ? "" : "out");
        BUG_ON(!ni);
        BUG_ON(!NInoNonResident(ni));
        BUG_ON(vcn < 0);
@@ -312,33 +506,22 @@ retry_remap:
        }
        if (!err && !is_retry) {
                /*
-                * The @vcn is in an unmapped region, map the runlist and
-                * retry.
+                * If the search context is invalid we cannot map the unmapped
+                * region.
                 */
-               if (!write_locked) {
-                       up_read(&ni->runlist.lock);
-                       down_write(&ni->runlist.lock);
-                       if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) !=
-                                       LCN_RL_NOT_MAPPED)) {
-                               up_write(&ni->runlist.lock);
-                               down_read(&ni->runlist.lock);
+               if (IS_ERR(ctx->mrec))
+                       err = PTR_ERR(ctx->mrec);
+               else {
+                       /*
+                        * The @vcn is in an unmapped region, map the runlist
+                        * and retry.
+                        */
+                       err = ntfs_map_runlist_nolock(ni, vcn, ctx);
+                       if (likely(!err)) {
+                               is_retry = TRUE;
                                goto retry_remap;
                        }
                }
-               err = ntfs_map_runlist_nolock(ni, vcn);
-               if (!write_locked) {
-                       up_write(&ni->runlist.lock);
-                       down_read(&ni->runlist.lock);
-               }
-               if (likely(!err)) {
-                       is_retry = TRUE;
-                       goto retry_remap;
-               }
-               /*
-                * -EINVAL coming from a failed mapping attempt is equivalent
-                * to i/o error for us as it should not happen in our code
-                * paths.
-                */
                if (err == -EINVAL)
                        err = -EIO;
        } else if (!err)
@@ -1011,6 +1194,7 @@ int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name,
        ntfs_inode *base_ni;
 
        ntfs_debug("Entering.");
+       BUG_ON(IS_ERR(ctx->mrec));
        if (ctx->base_ntfs_ino)
                base_ni = ctx->base_ntfs_ino;
        else
@@ -1227,7 +1411,7 @@ int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPE type)
  */
 int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type)
 {
-       if (type == AT_INDEX_ALLOCATION || type == AT_EA)
+       if (type == AT_INDEX_ALLOCATION)
                return -EPERM;
        return 0;
 }
@@ -1319,10 +1503,17 @@ int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
 /**
  * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
  * @ni:                ntfs inode describing the attribute to convert
+ * @data_size: size of the resident data to copy to the non-resident attribute
  *
  * Convert the resident ntfs attribute described by the ntfs inode @ni to a
  * non-resident one.
  *
+ * @data_size must be equal to the attribute value size.  This is needed since
+ * we need to know the size before we can map the mft record and our callers
+ * always know it.  The reason we cannot simply read the size from the vfs
+ * inode i_size is that this is not necessarily uptodate.  This happens when
+ * ntfs_attr_make_non_resident() is called in the ->truncate call path(s).
+ *
  * Return 0 on success and -errno on error.  The following error return codes
  * are defined:
  *     -EPERM  - The attribute is not allowed to be non-resident.
@@ -1343,7 +1534,7 @@ int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
  *
  * Locking: - The caller must hold i_sem on the inode.
  */
-int ntfs_attr_make_non_resident(ntfs_inode *ni)
+int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size)
 {
        s64 new_size;
        struct inode *vi = VFS_I(ni);
@@ -1381,11 +1572,9 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
         * The size needs to be aligned to a cluster boundary for allocation
         * purposes.
         */
-       new_size = (i_size_read(vi) + vol->cluster_size - 1) &
+       new_size = (data_size + vol->cluster_size - 1) &
                        ~(vol->cluster_size - 1);
        if (new_size > 0) {
-               runlist_element *rl2;
-
                /*
                 * Will need the page later and since the page lock nests
                 * outside all ntfs locks, we need to get the page now.
@@ -1396,7 +1585,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
                        return -ENOMEM;
                /* Start by allocating clusters to hold the attribute value. */
                rl = ntfs_cluster_alloc(vol, 0, new_size >>
-                               vol->cluster_size_bits, -1, DATA_ZONE);
+                               vol->cluster_size_bits, -1, DATA_ZONE, TRUE);
                if (IS_ERR(rl)) {
                        err = PTR_ERR(rl);
                        ntfs_debug("Failed to allocate cluster%s, error code "
@@ -1405,12 +1594,6 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
                                        err);
                        goto page_err_out;
                }
-               /* Change the runlist terminator to LCN_ENOENT. */
-               rl2 = rl;
-               while (rl2->length)
-                       rl2++;
-               BUG_ON(rl2->lcn != LCN_RL_NOT_MAPPED);
-               rl2->lcn = LCN_ENOENT;
        } else {
                rl = NULL;
                page = NULL;
@@ -1473,7 +1656,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
         * attribute value.
         */
        attr_size = le32_to_cpu(a->data.resident.value_length);
-       BUG_ON(attr_size != i_size_read(vi));
+       BUG_ON(attr_size != data_size);
        if (page && !PageUptodate(page)) {
                kaddr = kmap_atomic(page, KM_USER0);
                memcpy(kaddr, (u8*)a +
@@ -1538,7 +1721,9 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
                                ffs(ni->itype.compressed.block_size) - 1;
                ni->itype.compressed.block_clusters = 1U <<
                                a->data.non_resident.compression_unit;
-       }
+               vi->i_blocks = ni->itype.compressed.size >> 9;
+       } else
+               vi->i_blocks = ni->allocated_size >> 9;
        write_unlock_irqrestore(&ni->size_lock, flags);
        /*
         * This needs to be last since the address space operations ->readpage
@@ -1651,6 +1836,640 @@ page_err_out:
        return err;
 }
 
+/**
+ * ntfs_attr_extend_allocation - extend the allocated space of an attribute
+ * @ni:                        ntfs inode of the attribute whose allocation to extend
+ * @new_alloc_size:    new size in bytes to which to extend the allocation to
+ * @new_data_size:     new size in bytes to which to extend the data to
+ * @data_start:                beginning of region which is required to be non-sparse
+ *
+ * Extend the allocated space of an attribute described by the ntfs inode @ni
+ * to @new_alloc_size bytes.  If @data_start is -1, the whole extension may be
+ * implemented as a hole in the file (as long as both the volume and the ntfs
+ * inode @ni have sparse support enabled).  If @data_start is >= 0, then the
+ * region between the old allocated size and @data_start - 1 may be made sparse
+ * but the regions between @data_start and @new_alloc_size must be backed by
+ * actual clusters.
+ *
+ * If @new_data_size is -1, it is ignored.  If it is >= 0, then the data size
+ * of the attribute is extended to @new_data_size.  Note that the i_size of the
+ * vfs inode is not updated.  Only the data size in the base attribute record
+ * is updated.  The caller has to update i_size separately if this is required.
+ * WARNING: It is a BUG() for @new_data_size to be smaller than the old data
+ * size as well as for @new_data_size to be greater than @new_alloc_size.
+ *
+ * For resident attributes this involves resizing the attribute record and if
+ * necessary moving it and/or other attributes into extent mft records and/or
+ * converting the attribute to a non-resident attribute which in turn involves
+ * extending the allocation of a non-resident attribute as described below.
+ *
+ * For non-resident attributes this involves allocating clusters in the data
+ * zone on the volume (except for regions that are being made sparse) and
+ * extending the run list to describe the allocated clusters as well as
+ * updating the mapping pairs array of the attribute.  This in turn involves
+ * resizing the attribute record and if necessary moving it and/or other
+ * attributes into extent mft records and/or splitting the attribute record
+ * into multiple extent attribute records.
+ *
+ * Also, the attribute list attribute is updated if present and in some of the
+ * above cases (the ones where extent mft records/attributes come into play),
+ * an attribute list attribute is created if not already present.
+ *
+ * Return the new allocated size on success and -errno on error.  In the case
+ * that an error is encountered but a partial extension at least up to
+ * @data_start (if present) is possible, the allocation is partially extended
+ * and this is returned.  This means the caller must check the returned size to
+ * determine if the extension was partial.  If @data_start is -1 then partial
+ * allocations are not performed.
+ *
+ * WARNING: Do not call ntfs_attr_extend_allocation() for $MFT/$DATA.
+ *
+ * Locking: This function takes the runlist lock of @ni for writing as well as
+ * locking the mft record of the base ntfs inode.  These locks are maintained
+ * throughout execution of the function.  These locks are required so that the
+ * attribute can be resized safely and so that it can for example be converted
+ * from resident to non-resident safely.
+ *
+ * TODO: At present attribute list attribute handling is not implemented.
+ *
+ * TODO: At present it is not safe to call this function for anything other
+ * than the $DATA attribute(s) of an uncompressed and unencrypted file.
+ */
+s64 ntfs_attr_extend_allocation(ntfs_inode *ni, s64 new_alloc_size,
+               const s64 new_data_size, const s64 data_start)
+{
+       VCN vcn;
+       s64 ll, allocated_size, start = data_start;
+       struct inode *vi = VFS_I(ni);
+       ntfs_volume *vol = ni->vol;
+       ntfs_inode *base_ni;
+       MFT_RECORD *m;
+       ATTR_RECORD *a;
+       ntfs_attr_search_ctx *ctx;
+       runlist_element *rl, *rl2;
+       unsigned long flags;
+       int err, mp_size;
+       u32 attr_len = 0; /* Silence stupid gcc warning. */
+       BOOL mp_rebuilt;
+
+#ifdef NTFS_DEBUG
+       read_lock_irqsave(&ni->size_lock, flags);
+       allocated_size = ni->allocated_size;
+       read_unlock_irqrestore(&ni->size_lock, flags);
+       ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, "
+                       "old_allocated_size 0x%llx, "
+                       "new_allocated_size 0x%llx, new_data_size 0x%llx, "
+                       "data_start 0x%llx.", vi->i_ino,
+                       (unsigned)le32_to_cpu(ni->type),
+                       (unsigned long long)allocated_size,
+                       (unsigned long long)new_alloc_size,
+                       (unsigned long long)new_data_size,
+                       (unsigned long long)start);
+#endif
+retry_extend:
+       /*
+        * For non-resident attributes, @start and @new_size need to be aligned
+        * to cluster boundaries for allocation purposes.
+        */
+       if (NInoNonResident(ni)) {
+               if (start > 0)
+                       start &= ~(s64)vol->cluster_size_mask;
+               new_alloc_size = (new_alloc_size + vol->cluster_size - 1) &
+                               ~(s64)vol->cluster_size_mask;
+       }
+       BUG_ON(new_data_size >= 0 && new_data_size > new_alloc_size);
+       /* Check if new size is allowed in $AttrDef. */
+       err = ntfs_attr_size_bounds_check(vol, ni->type, new_alloc_size);
+       if (unlikely(err)) {
+               /* Only emit errors when the write will fail completely. */
+               read_lock_irqsave(&ni->size_lock, flags);
+               allocated_size = ni->allocated_size;
+               read_unlock_irqrestore(&ni->size_lock, flags);
+               if (start < 0 || start >= allocated_size) {
+                       if (err == -ERANGE) {
+                               ntfs_error(vol->sb, "Cannot extend allocation "
+                                               "of inode 0x%lx, attribute "
+                                               "type 0x%x, because the new "
+                                               "allocation would exceed the "
+                                               "maximum allowed size for "
+                                               "this attribute type.",
+                                               vi->i_ino, (unsigned)
+                                               le32_to_cpu(ni->type));
+                       } else {
+                               ntfs_error(vol->sb, "Cannot extend allocation "
+                                               "of inode 0x%lx, attribute "
+                                               "type 0x%x, because this "
+                                               "attribute type is not "
+                                               "defined on the NTFS volume.  "
+                                               "Possible corruption!  You "
+                                               "should run chkdsk!",
+                                               vi->i_ino, (unsigned)
+                                               le32_to_cpu(ni->type));
+                       }
+               }
+               /* Translate error code to be POSIX conformant for write(2). */
+               if (err == -ERANGE)
+                       err = -EFBIG;
+               else
+                       err = -EIO;
+               return err;
+       }
+       if (!NInoAttr(ni))
+               base_ni = ni;
+       else
+               base_ni = ni->ext.base_ntfs_ino;
+       /*
+        * We will be modifying both the runlist (if non-resident) and the mft
+        * record so lock them both down.
+        */
+       down_write(&ni->runlist.lock);
+       m = map_mft_record(base_ni);
+       if (IS_ERR(m)) {
+               err = PTR_ERR(m);
+               m = NULL;
+               ctx = NULL;
+               goto err_out;
+       }
+       ctx = ntfs_attr_get_search_ctx(base_ni, m);
+       if (unlikely(!ctx)) {
+               err = -ENOMEM;
+               goto err_out;
+       }
+       read_lock_irqsave(&ni->size_lock, flags);
+       allocated_size = ni->allocated_size;
+       read_unlock_irqrestore(&ni->size_lock, flags);
+       /*
+        * If non-resident, seek to the last extent.  If resident, there is
+        * only one extent, so seek to that.
+        */
+       vcn = NInoNonResident(ni) ? allocated_size >> vol->cluster_size_bits :
+                       0;
+       /*
+        * Abort if someone did the work whilst we waited for the locks.  If we
+        * just converted the attribute from resident to non-resident it is
+        * likely that exactly this has happened already.  We cannot quite
+        * abort if we need to update the data size.
+        */
+       if (unlikely(new_alloc_size <= allocated_size)) {
+               ntfs_debug("Allocated size already exceeds requested size.");
+               new_alloc_size = allocated_size;
+               if (new_data_size < 0)
+                       goto done;
+               /*
+                * We want the first attribute extent so that we can update the
+                * data size.
+                */
+               vcn = 0;
+       }
+       err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
+                       CASE_SENSITIVE, vcn, NULL, 0, ctx);
+       if (unlikely(err)) {
+               if (err == -ENOENT)
+                       err = -EIO;
+               goto err_out;
+       }
+       m = ctx->mrec;
+       a = ctx->attr;
+       /* Use goto to reduce indentation. */
+       if (a->non_resident)
+               goto do_non_resident_extend;
+       BUG_ON(NInoNonResident(ni));
+       /* The total length of the attribute value. */
+       attr_len = le32_to_cpu(a->data.resident.value_length);
+       /*
+        * Extend the attribute record to be able to store the new attribute
+        * size.  ntfs_attr_record_resize() will not do anything if the size is
+        * not changing.
+        */
+       if (new_alloc_size < vol->mft_record_size &&
+                       !ntfs_attr_record_resize(m, a,
+                       le16_to_cpu(a->data.resident.value_offset) +
+                       new_alloc_size)) {
+               /* The resize succeeded! */
+               write_lock_irqsave(&ni->size_lock, flags);
+               ni->allocated_size = le32_to_cpu(a->length) -
+                               le16_to_cpu(a->data.resident.value_offset);
+               write_unlock_irqrestore(&ni->size_lock, flags);
+               if (new_data_size >= 0) {
+                       BUG_ON(new_data_size < attr_len);
+                       a->data.resident.value_length =
+                                       cpu_to_le32((u32)new_data_size);
+               }
+               goto flush_done;
+&nbs