aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/arm/Samsung-S3C24XX/Overview.txt41
-rw-r--r--Documentation/filesystems/ntfs.txt42
-rw-r--r--arch/arm/Kconfig9
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/common/locomo.c2
-rw-r--r--arch/arm/common/sa1111.c2
-rw-r--r--arch/arm/common/scoop.c3
-rw-r--r--arch/arm/configs/ixp4xx_defconfig2
-rw-r--r--arch/arm/lib/Makefile22
-rw-r--r--arch/arm/lib/clear_user.S52
-rw-r--r--arch/arm/lib/copy_from_user.S101
-rw-r--r--arch/arm/lib/copy_template.S255
-rw-r--r--arch/arm/lib/copy_to_user.S101
-rw-r--r--arch/arm/lib/memcpy.S410
-rw-r--r--arch/arm/lib/memmove.S206
-rw-r--r--arch/arm/lib/uaccess.S38
-rw-r--r--arch/arm/mach-aaec2000/core.c2
-rw-r--r--arch/arm/mach-ebsa110/core.c26
-rw-r--r--arch/arm/mach-h720x/h7202-eval.c2
-rw-r--r--arch/arm/mach-imx/generic.c2
-rw-r--r--arch/arm/mach-imx/mx1ads.c1
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c2
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c2
-rw-r--r--arch/arm/mach-iop3xx/iop321-setup.c2
-rw-r--r--arch/arm/mach-iop3xx/iop331-setup.c2
-rw-r--r--arch/arm/mach-ixp2000/Makefile2
-rw-r--r--arch/arm/mach-ixp2000/core.c33
-rw-r--r--arch/arm/mach-ixp2000/enp2611.c33
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x00.c6
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x01.c11
-rw-r--r--arch/arm/mach-ixp2000/pci.c6
-rw-r--r--arch/arm/mach-ixp2000/uengine.c474
-rw-r--r--arch/arm/mach-ixp4xx/common.c1
-rw-r--r--arch/arm/mach-lh7a40x/arch-lpd7a40x.c2
-rw-r--r--arch/arm/mach-omap1/board-h2.c2
-rw-r--r--arch/arm/mach-omap1/board-h3.c2
-rw-r--r--arch/arm/mach-omap1/board-innovator.c2
-rw-r--r--arch/arm/mach-omap1/board-netstar.c2
-rw-r--r--arch/arm/mach-omap1/board-osk.c2
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c2
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c2
-rw-r--r--arch/arm/mach-omap1/devices.c2
-rw-r--r--arch/arm/mach-pxa/corgi.c2
-rw-r--r--arch/arm/mach-pxa/corgi_lcd.c2
-rw-r--r--arch/arm/mach-pxa/corgi_ssp.c2
-rw-r--r--arch/arm/mach-pxa/generic.c2
-rw-r--r--arch/arm/mach-pxa/idp.c2
-rw-r--r--arch/arm/mach-pxa/lubbock.c65
-rw-r--r--arch/arm/mach-pxa/mainstone.c2
-rw-r--r--arch/arm/mach-pxa/poodle.c2
-rw-r--r--arch/arm/mach-pxa/pxa27x.c2
-rw-r--r--arch/arm/mach-pxa/spitz.c2
-rw-r--r--arch/arm/mach-realview/Kconfig11
-rw-r--r--arch/arm/mach-realview/Makefile6
-rw-r--r--arch/arm/mach-realview/Makefile.boot4
-rw-r--r--arch/arm/mach-realview/clock.c145
-rw-r--r--arch/arm/mach-realview/clock.h25
-rw-r--r--arch/arm/mach-realview/core.c605
-rw-r--r--arch/arm/mach-realview/core.h118
-rw-r--r--arch/arm/mach-realview/realview_eb.c142
-rw-r--r--arch/arm/mach-s3c2410/clock.c2
-rw-r--r--arch/arm/mach-s3c2410/cpu.c2
-rw-r--r--arch/arm/mach-s3c2410/devs.c2
-rw-r--r--arch/arm/mach-s3c2410/devs.h1
-rw-r--r--arch/arm/mach-s3c2410/mach-anubis.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c1
-rw-r--r--arch/arm/mach-s3c2410/mach-n30.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-nexcoder.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-otom.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-rx3715.c71
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2410.c1
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2440.c1
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c2
-rw-r--r--arch/arm/mach-s3c2410/s3c2440.c2
-rw-r--r--arch/arm/mach-sa1100/badge4.c2
-rw-r--r--arch/arm/mach-sa1100/cerf.c2
-rw-r--r--arch/arm/mach-sa1100/collie.c2
-rw-r--r--arch/arm/mach-sa1100/generic.c1
-rw-r--r--arch/arm/mach-sa1100/jornada720.c2
-rw-r--r--arch/arm/mach-sa1100/neponset.c2
-rw-r--r--arch/arm/mach-sa1100/pleb.c2
-rw-r--r--arch/arm/mach-sa1100/simpad.c2
-rw-r--r--arch/arm/mach-versatile/core.c1
-rw-r--r--arch/arm/mm/Kconfig6
-rw-r--r--arch/arm/plat-omap/usb.c2
-rw-r--r--arch/i386/Kconfig5
-rw-r--r--arch/i386/kernel/apic.c77
-rw-r--r--arch/i386/kernel/i8259.c4
-rw-r--r--arch/i386/kernel/io_apic.c6
-rw-r--r--arch/i386/kernel/smpboot.c68
-rw-r--r--arch/i386/kernel/time.c12
-rw-r--r--arch/i386/pci/fixup.c2
-rw-r--r--arch/m32r/kernel/setup_m32700ut.c2
-rw-r--r--arch/m32r/kernel/setup_mappi.c2
-rw-r--r--arch/m32r/kernel/setup_mappi2.c2
-rw-r--r--arch/m32r/kernel/setup_mappi3.c2
-rw-r--r--arch/m32r/kernel/setup_opsput.c2
-rw-r--r--arch/mips/au1000/common/platform.c1
-rw-r--r--arch/ppc/platforms/4xx/ibm440ep.c1
-rw-r--r--arch/ppc/platforms/4xx/ibmstb4.c1
-rw-r--r--arch/ppc/platforms/4xx/redwood5.c2
-rw-r--r--arch/ppc/platforms/4xx/redwood6.c2
-rw-r--r--arch/ppc/platforms/chrp_pegasos_eth.c2
-rw-r--r--arch/ppc/platforms/cpci690.c1
-rw-r--r--arch/ppc/platforms/ev64260.c1
-rw-r--r--arch/ppc/platforms/ev64360.c1
-rw-r--r--arch/ppc/platforms/hdpu.c1
-rw-r--r--arch/ppc/platforms/katana.c1
-rw-r--r--arch/ppc/platforms/radstone_ppc7d.c1
-rw-r--r--arch/ppc/syslib/mpc52xx_devices.c1
-rw-r--r--arch/ppc/syslib/mv64x60.c1
-rw-r--r--arch/ppc/syslib/pq2_devices.c2
-rw-r--r--arch/sh/boards/superh/microdev/setup.c2
-rw-r--r--arch/um/drivers/net_kern.c1
-rw-r--r--arch/um/drivers/ubd_kern.c1
-rw-r--r--arch/xtensa/platform-iss/network.c1
-rw-r--r--drivers/base/platform.c2
-rw-r--r--drivers/block/cfq-iosched.c4
-rw-r--r--drivers/block/floppy.c2
-rw-r--r--drivers/block/noop-iosched.c1
-rw-r--r--drivers/char/s3c2410-rtc.c2
-rw-r--r--drivers/char/sonypi.c1
-rw-r--r--drivers/char/tb0219.c2
-rw-r--r--drivers/char/vr41xx_giu.c2
-rw-r--r--drivers/char/vr41xx_rtc.c2
-rw-r--r--drivers/char/watchdog/mpcore_wdt.c3
-rw-r--r--drivers/char/watchdog/mv64x60_wdt.c3
-rw-r--r--drivers/char/watchdog/pcwd_pci.c6
-rw-r--r--drivers/char/watchdog/s3c2410_wdt.c3
-rw-r--r--drivers/char/watchdog/w83627hf_wdt.c2
-rw-r--r--drivers/eisa/virtual_root.c2
-rw-r--r--drivers/firmware/dcdbas.c2
-rw-r--r--drivers/firmware/dell_rbu.c2
-rw-r--r--drivers/hwmon/hdaps.c2
-rw-r--r--drivers/i2c/busses/i2c-iop3xx.c11
-rw-r--r--drivers/i2c/busses/i2c-isa.c1
-rw-r--r--drivers/i2c/busses/i2c-ixp2000.c2
-rw-r--r--drivers/i2c/busses/i2c-ixp4xx.c2
-rw-r--r--drivers/i2c/busses/i2c-mpc.c2
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c2
-rw-r--r--drivers/i2c/busses/i2c-pxa.c1
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c9
-rw-r--r--drivers/i2c/chips/isp1301_omap.c2
-rw-r--r--drivers/i2c/i2c-core.c1
-rw-r--r--drivers/i2c/i2c-dev.c1
-rw-r--r--drivers/input/evdev.c4
-rw-r--r--drivers/input/input.c2
-rw-r--r--drivers/input/keyboard/Kconfig4
-rw-r--r--drivers/input/keyboard/corgikbd.c2
-rw-r--r--drivers/input/keyboard/lkkbd.c2
-rw-r--r--drivers/input/keyboard/spitzkbd.c2
-rw-r--r--drivers/input/misc/pcspkr.c2
-rw-r--r--drivers/input/mouse/Kconfig2
-rw-r--r--drivers/input/serio/ct82c710.c1
-rw-r--r--drivers/input/serio/i8042.c1
-rw-r--r--drivers/input/serio/maceps2.c2
-rw-r--r--drivers/input/serio/q40kbd.c1
-rw-r--r--drivers/input/serio/rpckbd.c1
-rw-r--r--drivers/input/touchscreen/corgi_ts.c2
-rw-r--r--drivers/macintosh/adbhid.c1
-rw-r--r--drivers/mfd/mcp-sa11x0.c2
-rw-r--r--drivers/misc/hdpuftrs/hdpu_cpustate.c2
-rw-r--r--drivers/misc/hdpuftrs/hdpu_nexus.c2
-rw-r--r--drivers/mmc/pxamci.c2
-rw-r--r--drivers/mmc/wbsd.c2
-rw-r--r--drivers/mtd/maps/bast-flash.c2
-rw-r--r--drivers/mtd/maps/integrator-flash.c2
-rw-r--r--drivers/mtd/maps/ixp2000.c1
-rw-r--r--drivers/mtd/maps/ixp4xx.c1
-rw-r--r--drivers/mtd/maps/omap_nor.c2
-rw-r--r--drivers/mtd/maps/plat-ram.c1
-rw-r--r--drivers/mtd/maps/sa1100-flash.c2
-rw-r--r--drivers/mtd/nand/s3c2410.c2
-rw-r--r--drivers/net/arm/am79c961a.c41
-rw-r--r--drivers/net/arm/am79c961a.h2
-rw-r--r--drivers/net/depca.c2
-rw-r--r--drivers/net/dm9000.c1
-rw-r--r--drivers/net/gianfar.c2
-rw-r--r--drivers/net/gianfar_mii.c1
-rw-r--r--drivers/net/irda/pxaficp_ir.c1
-rw-r--r--drivers/net/irda/sa1100_ir.c2
-rw-r--r--drivers/net/irda/smsc-ircc2.c1
-rw-r--r--drivers/net/jazzsonic.c2
-rw-r--r--drivers/net/macsonic.c2
-rw-r--r--drivers/net/mipsnet.c1
-rw-r--r--drivers/net/mv643xx_eth.c2
-rw-r--r--drivers/net/smc91x.c2
-rw-r--r--drivers/net/tokenring/proteon.c1
-rw-r--r--drivers/net/tokenring/skisa.c1
-rw-r--r--drivers/pcmcia/au1000_generic.c2
-rw-r--r--drivers/pcmcia/hd64465_ss.c2
-rw-r--r--drivers/pcmcia/i82365.c2
-rw-r--r--drivers/pcmcia/m32r_cfc.c2
-rw-r--r--drivers/pcmcia/m32r_pcc.c2
-rw-r--r--drivers/pcmcia/omap_cf.c2
-rw-r--r--drivers/pcmcia/pxa2xx_base.c1
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c2
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c2
-rw-r--r--drivers/pcmcia/sa1100_generic.c1
-rw-r--r--drivers/pcmcia/tcic.c2
-rw-r--r--drivers/pcmcia/vrc4171_card.c1
-rw-r--r--drivers/scsi/hosts.c1
-rw-r--r--drivers/scsi/ide-scsi.c44
-rw-r--r--drivers/scsi/libata-core.c59
-rw-r--r--drivers/scsi/libata-scsi.c9
-rw-r--r--drivers/scsi/libata.h1
-rw-r--r--drivers/serial/8250.c2
-rw-r--r--drivers/serial/imx.c3
-rw-r--r--drivers/serial/mpc52xx_uart.c2
-rw-r--r--drivers/serial/mpsc.c2
-rw-r--r--drivers/serial/pxa.c2
-rw-r--r--drivers/serial/s3c2410.c2
-rw-r--r--drivers/serial/sa1100.c2
-rw-r--r--drivers/serial/vr41xx_siu.c2
-rw-r--r--drivers/usb/gadget/dummy_hcd.c2
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.c2
-rw-r--r--drivers/usb/gadget/omap_udc.c2
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c2
-rw-r--r--drivers/usb/host/isp116x-hcd.c1
-rw-r--r--drivers/usb/host/ohci-au1xxx.c2
-rw-r--r--drivers/usb/host/ohci-lh7a404.c2
-rw-r--r--drivers/usb/host/ohci-omap.c1
-rw-r--r--drivers/usb/host/ohci-ppc-soc.c2
-rw-r--r--drivers/usb/host/ohci-pxa27x.c2
-rw-r--r--drivers/usb/host/ohci-s3c2410.c2
-rw-r--r--drivers/usb/host/pci-quirks.c23
-rw-r--r--drivers/usb/host/sl811-hcd.c1
-rw-r--r--drivers/usb/host/sl811_cs.c1
-rw-r--r--drivers/video/acornfb.c2
-rw-r--r--drivers/video/arcfb.c1
-rw-r--r--drivers/video/backlight/corgi_bl.c2
-rw-r--r--drivers/video/dnfb.c2
-rw-r--r--drivers/video/epson1355fb.c2
-rw-r--r--drivers/video/gbefb.c2
-rw-r--r--drivers/video/imxfb.c2
-rw-r--r--drivers/video/pxafb.c2
-rw-r--r--drivers/video/q40fb.c1
-rw-r--r--drivers/video/s1d13xxxfb.c2
-rw-r--r--drivers/video/s3c2410fb.c1
-rw-r--r--drivers/video/sa1100fb.c2
-rw-r--r--drivers/video/sgivwfb.c2
-rw-r--r--drivers/video/vesafb.c2
-rw-r--r--drivers/video/vfb.c2
-rw-r--r--drivers/video/w100fb.c2
-rw-r--r--fs/cifs/AUTHORS4
-rw-r--r--fs/cifs/CHANGES60
-rw-r--r--fs/cifs/README24
-rw-r--r--fs/cifs/TODO50
-rw-r--r--fs/cifs/asn1.c3
-rw-r--r--fs/cifs/cifs_debug.c103
-rw-r--r--fs/cifs/cifs_debug.h5
-rw-r--r--fs/cifs/cifs_fs_sb.h3
-rw-r--r--fs/cifs/cifsfs.c80
-rw-r--r--fs/cifs/cifsfs.h3
-rw-r--r--fs/cifs/cifsglob.h98
-rw-r--r--fs/cifs/cifspdu.h499
-rw-r--r--fs/cifs/cifsproto.h32
-rw-r--r--fs/cifs/cifssmb.c659
-rw-r--r--fs/cifs/connect.c219
-rw-r--r--fs/cifs/dir.c108
-rw-r--r--fs/cifs/fcntl.c12
-rw-r--r--fs/cifs/file.c466
-rw-r--r--fs/cifs/inode.c150
-rw-r--r--fs/cifs/link.c5
-rw-r--r--fs/cifs/misc.c123
-rw-r--r--fs/cifs/netmisc.c15
-rw-r--r--fs/cifs/ntlmssp.h12
-rw-r--r--fs/cifs/readdir.c84
-rw-r--r--fs/cifs/rfc1002pdu.h13
-rw-r--r--fs/cifs/transport.c331
-rw-r--r--fs/fs-writeback.c2
-rw-r--r--fs/ntfs/ChangeLog85
-rw-r--r--fs/ntfs/Makefile2
-rw-r--r--fs/ntfs/aops.c832
-rw-r--r--fs/ntfs/attrib.c983
-rw-r--r--fs/ntfs/attrib.h10
-rw-r--r--fs/ntfs/file.c2256
-rw-r--r--fs/ntfs/inode.c514
-rw-r--r--fs/ntfs/layout.h31
-rw-r--r--fs/ntfs/lcnalloc.c56
-rw-r--r--fs/ntfs/lcnalloc.h43
-rw-r--r--fs/ntfs/malloc.h3
-rw-r--r--fs/ntfs/mft.c26
-rw-r--r--fs/ntfs/super.c2
-rw-r--r--include/asm-arm/arch-ixp2000/enp2611.h16
-rw-r--r--include/asm-arm/arch-ixp2000/ixp2000-regs.h7
-rw-r--r--include/asm-arm/arch-ixp2000/system.h23
-rw-r--r--include/asm-arm/arch-ixp2000/uengine.h62
-rw-r--r--include/asm-arm/arch-realview/debug-macro.S38
-rw-r--r--include/asm-arm/arch-realview/dma.h27
-rw-r--r--include/asm-arm/arch-realview/entry-macro.S49
-rw-r--r--include/asm-arm/arch-realview/hardware.h31
-rw-r--r--include/asm-arm/arch-realview/io.h34
-rw-r--r--include/asm-arm/arch-realview/irqs.h103
-rw-r--r--include/asm-arm/arch-realview/memory.h38
-rw-r--r--include/asm-arm/arch-realview/param.h19
-rw-r--r--include/asm-arm/arch-realview/platform.h395
-rw-r--r--include/asm-arm/arch-realview/system.h51
-rw-r--r--include/asm-arm/arch-realview/timex.h23
-rw-r--r--include/asm-arm/arch-realview/uncompress.h54
-rw-r--r--include/asm-arm/arch-realview/vmalloc.h21
-rw-r--r--include/asm-arm/arch-s3c2410/regs-iis.h1
-rw-r--r--include/asm-arm/hardware/amba_clcd.h2
-rw-r--r--include/asm-i386/apic.h3
-rw-r--r--include/asm-i386/hw_irq.h1
-rw-r--r--include/asm-i386/mach-default/smpboot_hooks.h15
-rw-r--r--include/asm-i386/mach-visws/smpboot_hooks.h7
-rw-r--r--include/asm-ppc/ppc_sys.h2
-rw-r--r--include/linux/device.h26
-rw-r--r--include/linux/platform_device.h40
-rw-r--r--include/linux/serial_8250.h2
-rw-r--r--include/sound/emu10k1.h1
-rw-r--r--init/main.c11
-rw-r--r--mm/swap.c3
-rw-r--r--sound/arm/pxa2xx-ac97.c2
-rw-r--r--sound/core/init.c2
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c39
318 files changed, 10357 insertions, 2594 deletions
diff --git a/Documentation/arm/Samsung-S3C24XX/Overview.txt b/Documentation/arm/Samsung-S3C24XX/Overview.txt
index 3af4d29a8938..89aa89d526ac 100644
--- a/Documentation/arm/Samsung-S3C24XX/Overview.txt
+++ b/Documentation/arm/Samsung-S3C24XX/Overview.txt
@@ -81,7 +81,8 @@ Adding New Machines
81 81
82 Any large scale modifications, or new drivers should be discussed 82 Any large scale modifications, or new drivers should be discussed
83 on the ARM kernel mailing list (linux-arm-kernel) before being 83 on the ARM kernel mailing list (linux-arm-kernel) before being
84 attempted. 84 attempted. See http://www.arm.linux.org.uk/mailinglists/ for the
85 mailing list information.
85 86
86 87
87NAND 88NAND
@@ -120,6 +121,43 @@ Clock Management
120 various clock units 121 various clock units
121 122
122 123
124Platform Data
125-------------
126
127 Whenever a device has platform specific data that is specified
128 on a per-machine basis, care should be taken to ensure the
129 following:
130
131 1) that default data is not left in the device to confuse the
132 driver if a machine does not set it at startup
133
134 2) the data should (if possible) be marked as __initdata,
135 to ensure that the data is thrown away if the machine is
136 not the one currently in use.
137
138 The best way of doing this is to make a function that
139 kmalloc()s an area of memory, and copies the __initdata
140 and then sets the relevant device's platform data. Making
141 the function `__init` takes care of ensuring it is discarded
142 with the rest of the initialisation code
143
144 static __init void s3c24xx_xxx_set_platdata(struct xxx_data *pd)
145 {
146 struct s3c2410_xxx_mach_info *npd;
147
148 npd = kmalloc(sizeof(struct s3c2410_xxx_mach_info), GFP_KERNEL);
149 if (npd) {
150 memcpy(npd, pd, sizeof(struct s3c2410_xxx_mach_info));
151 s3c_device_xxx.dev.platform_data = npd;
152 } else {
153 printk(KERN_ERR "no memory for xxx platform data\n");
154 }
155 }
156
157 Note, since the code is marked as __init, it should not be
158 exported outside arch/arm/mach-s3c2410/, or exported to
159 modules via EXPORT_SYMBOL() and related functions.
160
123Port Contributors 161Port Contributors
124----------------- 162-----------------
125 163
@@ -149,6 +187,7 @@ Document Changes
149 06 Mar 2005 - BJD - Added Christer Weinigel 187 06 Mar 2005 - BJD - Added Christer Weinigel
150 08 Mar 2005 - BJD - Added LCVR to list of people, updated introduction 188 08 Mar 2005 - BJD - Added LCVR to list of people, updated introduction
151 08 Mar 2005 - BJD - Added section on adding machines 189 08 Mar 2005 - BJD - Added section on adding machines
190 09 Sep 2005 - BJD - Added section on platform data
152 191
153Document Author 192Document Author
154--------------- 193---------------
diff --git a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt
index a5fbc8e897fa..614de3124901 100644
--- a/Documentation/filesystems/ntfs.txt
+++ b/Documentation/filesystems/ntfs.txt
@@ -50,9 +50,14 @@ userspace utilities, etc.
50Features 50Features
51======== 51========
52 52
53- This is a complete rewrite of the NTFS driver that used to be in the kernel. 53- This is a complete rewrite of the NTFS driver that used to be in the 2.4 and
54 This new driver implements NTFS read support and is functionally equivalent 54 earlier kernels. This new driver implements NTFS read support and is
55 to the old ntfs driver. 55 functionally equivalent to the old ntfs driver and it also implements limited
56 write support. The biggest limitation at present is that files/directories
57 cannot be created or deleted. See below for the list of write features that
58 are so far supported. Another limitation is that writing to compressed files
59 is not implemented at all. Also, neither read nor write access to encrypted
60 files is so far implemented.
56- The new driver has full support for sparse files on NTFS 3.x volumes which 61- The new driver has full support for sparse files on NTFS 3.x volumes which
57 the old driver isn't happy with. 62 the old driver isn't happy with.
58- The new driver supports execution of binaries due to mmap() now being 63- The new driver supports execution of binaries due to mmap() now being
@@ -78,7 +83,20 @@ Features
78- The new driver supports fsync(2), fdatasync(2), and msync(2). 83- The new driver supports fsync(2), fdatasync(2), and msync(2).
79- The new driver supports readv(2) and writev(2). 84- The new driver supports readv(2) and writev(2).
80- The new driver supports access time updates (including mtime and ctime). 85- The new driver supports access time updates (including mtime and ctime).
81 86- The new driver supports truncate(2) and open(2) with O_TRUNC. But at present
87 only very limited support for highly fragmented files, i.e. ones which have
88 their data attribute split across multiple extents, is included. Another
89 limitation is that at present truncate(2) will never create sparse files,
90 since to mark a file sparse we need to modify the directory entry for the
91 file and we do not implement directory modifications yet.
92- The new driver supports write(2) which can both overwrite existing data and
93 extend the file size so that you can write beyond the existing data. Also,
94 writing into sparse regions is supported and the holes are filled in with
95 clusters. But at present only limited support for highly fragmented files,
96 i.e. ones which have their data attribute split across multiple extents, is
97 included. Another limitation is that write(2) will never create sparse
98 files, since to mark a file sparse we need to modify the directory entry for
99 the file and we do not implement directory modifications yet.
82 100
83Supported mount options 101Supported mount options
84======================= 102=======================
@@ -439,6 +457,22 @@ ChangeLog
439 457
440Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. 458Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
441 459
4602.1.25:
461 - Write support is now extended with write(2) being able to both
462 overwrite existing file data and to extend files. Also, if a write
463 to a sparse region occurs, write(2) will fill in the hole. Note,
464 mmap(2) based writes still do not support writing into holes or
465 writing beyond the initialized size.
466 - Write support has a new feature and that is that truncate(2) and
467 open(2) with O_TRUNC are now implemented thus files can be both made
468 smaller and larger.
469 - Note: Both write(2) and truncate(2)/open(2) with O_TRUNC still have
470 limitations in that they
471 - only provide limited support for highly fragmented files.
472 - only work on regular, i.e. uncompressed and unencrypted files.
473 - never create sparse files although this will change once directory
474 operations are implemented.
475 - Lots of bug fixes and enhancements across the board.
4422.1.24: 4762.1.24:
443 - Support journals ($LogFile) which have been modified by chkdsk. This 477 - Support journals ($LogFile) which have been modified by chkdsk. This
444 means users can boot into Windows after we marked the volume dirty. 478 means users can boot into Windows after we marked the volume dirty.
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 682367bd0f65..dc6d8342e5e6 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -194,6 +194,13 @@ config ARCH_VERSATILE
194 help 194 help
195 This enables support for ARM Ltd Versatile board. 195 This enables support for ARM Ltd Versatile board.
196 196
197config ARCH_REALVIEW
198 bool "RealView"
199 select ARM_AMBA
200 select ICST307
201 help
202 This enables support for ARM Ltd RealView boards.
203
197config ARCH_IMX 204config ARCH_IMX
198 bool "IMX" 205 bool "IMX"
199 206
@@ -244,6 +251,8 @@ source "arch/arm/mach-versatile/Kconfig"
244 251
245source "arch/arm/mach-aaec2000/Kconfig" 252source "arch/arm/mach-aaec2000/Kconfig"
246 253
254source "arch/arm/mach-realview/Kconfig"
255
247# Definitions to make life easier 256# Definitions to make life easier
248config ARCH_ACORN 257config ARCH_ACORN
249 bool 258 bool
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 64cf480b0b02..d80749ae2a7e 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -99,6 +99,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000
99 machine-$(CONFIG_ARCH_IMX) := imx 99 machine-$(CONFIG_ARCH_IMX) := imx
100 machine-$(CONFIG_ARCH_H720X) := h720x 100 machine-$(CONFIG_ARCH_H720X) := h720x
101 machine-$(CONFIG_ARCH_AAEC2000) := aaec2000 101 machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
102 machine-$(CONFIG_ARCH_REALVIEW) := realview
102 103
103ifeq ($(CONFIG_ARCH_EBSA110),y) 104ifeq ($(CONFIG_ARCH_EBSA110),y)
104# This is what happens if you forget the IOCS16 line. 105# This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index 5cdb4122f057..ad55680726ed 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -22,7 +22,7 @@
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/ioport.h> 24#include <linux/ioport.h>
25#include <linux/device.h> 25#include <linux/platform_device.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28 28
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 21e2a518ad3a..174aa86ee816 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -22,7 +22,7 @@
22#include <linux/ptrace.h> 22#include <linux/ptrace.h>
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/ioport.h> 24#include <linux/ioport.h>
25#include <linux/device.h> 25#include <linux/platform_device.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28#include <linux/dma-mapping.h> 28#include <linux/dma-mapping.h>
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index 4af0cf5f3bfb..bb4eff614413 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -13,8 +13,7 @@
13 13
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/string.h> 15#include <linux/string.h>
16#include <linux/slab.h> 16#include <linux/platform_device.h>
17
18#include <asm/io.h> 17#include <asm/io.h>
19#include <asm/hardware/scoop.h> 18#include <asm/hardware/scoop.h>
20 19
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index c279e41ed10e..f74c926beb42 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -104,7 +104,7 @@ CONFIG_ARCH_IXCDP1100=y
104CONFIG_ARCH_PRPMC1100=y 104CONFIG_ARCH_PRPMC1100=y
105CONFIG_ARCH_IXDP4XX=y 105CONFIG_ARCH_IXDP4XX=y
106CONFIG_CPU_IXP46X=y 106CONFIG_CPU_IXP46X=y
107CONFIG_MACH_GTWX5715=y 107# CONFIG_MACH_GTWX5715 is not set
108 108
109# 109#
110# IXP4xx Options 110# IXP4xx Options
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 71e5b99e519e..391f3ab3ff32 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -7,13 +7,27 @@
7lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ 7lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
8 csumpartialcopy.o csumpartialcopyuser.o clearbit.o \ 8 csumpartialcopy.o csumpartialcopyuser.o clearbit.o \
9 copy_page.o delay.o findbit.o memchr.o memcpy.o \ 9 copy_page.o delay.o findbit.o memchr.o memcpy.o \
10 memset.o memzero.o setbit.o strncpy_from_user.o \ 10 memmove.o memset.o memzero.o setbit.o \
11 strnlen_user.o strchr.o strrchr.o testchangebit.o \ 11 strncpy_from_user.o strnlen_user.o \
12 testclearbit.o testsetbit.o uaccess.o getuser.o \ 12 strchr.o strrchr.o \
13 putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ 13 testchangebit.o testclearbit.o testsetbit.o \
14 getuser.o putuser.o clear_user.o \
15 ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
14 ucmpdi2.o lib1funcs.o div64.o sha1.o \ 16 ucmpdi2.o lib1funcs.o div64.o sha1.o \
15 io-readsb.o io-writesb.o io-readsl.o io-writesl.o 17 io-readsb.o io-writesb.o io-readsl.o io-writesl.o
16 18
19# the code in uaccess.S is not preemption safe and
20# probably faster on ARMv3 only
21ifeq ($CONFIG_PREEMPT,y)
22 lib-y += copy_from_user.o copy_to_user.o
23else
24ifneq ($(CONFIG_CPU_32v3),y)
25 lib-y += copy_from_user.o copy_to_user.o
26else
27 lib-y += uaccess.o
28endif
29endif
30
17ifeq ($(CONFIG_CPU_32v3),y) 31ifeq ($(CONFIG_CPU_32v3),y)
18 lib-y += io-readsw-armv3.o io-writesw-armv3.o 32 lib-y += io-readsw-armv3.o io-writesw-armv3.o
19else 33else
diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
new file mode 100644
index 000000000000..7ff9f831b3f9
--- /dev/null
+++ b/arch/arm/lib/clear_user.S
@@ -0,0 +1,52 @@
1/*
2 * linux/arch/arm/lib/clear_user.S
3 *
4 * Copyright (C) 1995, 1996,1997,1998 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11#include <asm/assembler.h>
12
13 .text
14
15/* Prototype: int __arch_clear_user(void *addr, size_t sz)
16 * Purpose : clear some user memory
17 * Params : addr - user memory address to clear
18 * : sz - number of bytes to clear
19 * Returns : number of bytes NOT cleared
20 */
21ENTRY(__arch_clear_user)
22 stmfd sp!, {r1, lr}
23 mov r2, #0
24 cmp r1, #4
25 blt 2f
26 ands ip, r0, #3
27 beq 1f
28 cmp ip, #2
29USER( strbt r2, [r0], #1)
30USER( strlebt r2, [r0], #1)
31USER( strltbt r2, [r0], #1)
32 rsb ip, ip, #4
33 sub r1, r1, ip @ 7 6 5 4 3 2 1
341: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7
35USER( strplt r2, [r0], #4)
36USER( strplt r2, [r0], #4)
37 bpl 1b
38 adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3
39USER( strplt r2, [r0], #4)
402: tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x
41USER( strnebt r2, [r0], #1)
42USER( strnebt r2, [r0], #1)
43 tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1
44USER( strnebt r2, [r0], #1)
45 mov r0, #0
46 LOADREGS(fd,sp!, {r1, pc})
47
48 .section .fixup,"ax"
49 .align 0
509001: LOADREGS(fd,sp!, {r0, pc})
51 .previous
52
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
new file mode 100644
index 000000000000..7497393a0e81
--- /dev/null
+++ b/arch/arm/lib/copy_from_user.S
@@ -0,0 +1,101 @@
1/*
2 * linux/arch/arm/lib/copy_from_user.S
3 *
4 * Author: Nicolas Pitre
5 * Created: Sep 29, 2005
6 * Copyright: MontaVista Software, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/linkage.h>
14#include <asm/assembler.h>
15
16/*
17 * Prototype:
18 *
19 * size_t __arch_copy_from_user(void *to, const void *from, size_t n)
20 *
21 * Purpose:
22 *
23 * copy a block to kernel memory from user memory
24 *
25 * Params:
26 *
27 * to = kernel memory
28 * from = user memory
29 * n = number of bytes to copy
30 *
31 * Return value:
32 *
33 * Number of bytes NOT copied.
34 */
35
36 .macro ldr1w ptr reg abort
37100: ldrt \reg, [\ptr], #4
38 .section __ex_table, "a"
39 .long 100b, \abort
40 .previous
41 .endm
42
43 .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
44 ldr1w \ptr, \reg1, \abort
45 ldr1w \ptr, \reg2, \abort
46 ldr1w \ptr, \reg3, \abort
47 ldr1w \ptr, \reg4, \abort
48 .endm
49
50 .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
51 ldr4w \ptr, \reg1, \reg2, \reg3, \reg4, \abort
52 ldr4w \ptr, \reg5, \reg6, \reg7, \reg8, \abort
53 .endm
54
55 .macro ldr1b ptr reg cond=al abort
56100: ldr\cond\()bt \reg, [\ptr], #1
57 .section __ex_table, "a"
58 .long 100b, \abort
59 .previous
60 .endm
61
62 .macro str1w ptr reg abort
63 str \reg, [\ptr], #4
64 .endm
65
66 .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
67 stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
68 .endm
69
70 .macro str1b ptr reg cond=al abort
71 str\cond\()b \reg, [\ptr], #1
72 .endm
73
74 .macro enter reg1 reg2
75 mov r3, #0
76 stmdb sp!, {r0, r2, r3, \reg1, \reg2}
77 .endm
78
79 .macro exit reg1 reg2
80 add sp, sp, #8
81 ldmfd sp!, {r0, \reg1, \reg2}
82 .endm
83
84 .text
85
86ENTRY(__arch_copy_from_user)
87
88#include "copy_template.S"
89
90 .section .fixup,"ax"
91 .align 0
92 copy_abort_preamble
93 ldmfd sp!, {r1, r2}
94 sub r3, r0, r1
95 rsb r1, r3, r2
96 str r1, [sp]
97 bl __memzero
98 ldr r0, [sp], #4
99 copy_abort_end
100 .previous
101
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S
new file mode 100644
index 000000000000..838e435e4922
--- /dev/null
+++ b/arch/arm/lib/copy_template.S
@@ -0,0 +1,255 @@
1/*
2 * linux/arch/arm/lib/copy_template.s
3 *
4 * Code template for optimized memory copy functions
5 *
6 * Author: Nicolas Pitre
7 * Created: Sep 28, 2005
8 * Copyright: MontaVista Software, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15/*
16 * This can be used to enable code to cacheline align the source pointer.
17 * Experiments on tested architectures (StrongARM and XScale) didn't show
18 * this a worthwhile thing to do. That might be different in the future.
19 */
20//#define CALGN(code...) code
21#define CALGN(code...)
22
23/*
24 * Theory of operation
25 * -------------------
26 *
27 * This file provides the core code for a forward memory copy used in
28 * the implementation of memcopy(), copy_to_user() and copy_from_user().
29 *
30 * The including file must define the following accessor macros
31 * according to the need of the given function:
32 *
33 * ldr1w ptr reg abort
34 *
35 * This loads one word from 'ptr', stores it in 'reg' and increments
36 * 'ptr' to the next word. The 'abort' argument is used for fixup tables.
37 *
38 * ldr4w ptr reg1 reg2 reg3 reg4 abort
39 * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
40 *
41 * This loads four or eight words starting from 'ptr', stores them
42 * in provided registers and increments 'ptr' past those words.
43 * The'abort' argument is used for fixup tables.
44 *
45 * ldr1b ptr reg cond abort
46 *
47 * Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
48 * It also must apply the condition code if provided, otherwise the
49 * "al" condition is assumed by default.
50 *
51 * str1w ptr reg abort
52 * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
53 * str1b ptr reg cond abort
54 *
55 * Same as their ldr* counterparts, but data is stored to 'ptr' location
56 * rather than being loaded.
57 *
58 * enter reg1 reg2
59 *
60 * Preserve the provided registers on the stack plus any additional
61 * data as needed by the implementation including this code. Called
62 * upon code entry.
63 *
64 * exit reg1 reg2
65 *
66 * Restore registers with the values previously saved with the
67 * 'preserv' macro. Called upon code termination.
68 */
69
70
71 enter r4, lr
72
73 subs r2, r2, #4
74 blt 8f
75 ands ip, r0, #3
76 PLD( pld [r1, #0] )
77 bne 9f
78 ands ip, r1, #3
79 bne 10f
80
811: subs r2, r2, #(28)
82 stmfd sp!, {r5 - r8}
83 blt 5f
84
85 CALGN( ands ip, r1, #31 )
86 CALGN( rsb r3, ip, #32 )
87 CALGN( sbcnes r4, r3, r2 ) @ C is always set here
88 CALGN( bcs 2f )
89 CALGN( adr r4, 6f )
90 CALGN( subs r2, r2, r3 ) @ C gets set
91 CALGN( add pc, r4, ip )
92
93 PLD( pld [r1, #0] )
942: PLD( subs r2, r2, #96 )
95 PLD( pld [r1, #28] )
96 PLD( blt 4f )
97 PLD( pld [r1, #60] )
98 PLD( pld [r1, #92] )
99
1003: PLD( pld [r1, #124] )
1014: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
102 subs r2, r2, #32
103 str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
104 bge 3b
105 PLD( cmn r2, #96 )
106 PLD( bge 4b )
107
1085: ands ip, r2, #28
109 rsb ip, ip, #32
110 addne pc, pc, ip @ C is always clear here
111 b 7f
1126: nop
113 ldr1w r1, r3, abort=20f
114 ldr1w r1, r4, abort=20f
115 ldr1w r1, r5, abort=20f
116 ldr1w r1, r6, abort=20f
117 ldr1w r1, r7, abort=20f
118 ldr1w r1, r8, abort=20f
119 ldr1w r1, lr, abort=20f
120
121 add pc, pc, ip
122 nop
123 nop
124 str1w r0, r3, abort=20f
125 str1w r0, r4, abort=20f
126 str1w r0, r5, abort=20f
127 str1w r0, r6, abort=20f
128 str1w r0, r7, abort=20f
129 str1w r0, r8, abort=20f
130 str1w r0, lr, abort=20f
131
132 CALGN( bcs 2b )
133
1347: ldmfd sp!, {r5 - r8}
135
1368: movs r2, r2, lsl #31
137 ldr1b r1, r3, ne, abort=21f
138 ldr1b r1, r4, cs, abort=21f
139 ldr1b r1, ip, cs, abort=21f
140 str1b r0, r3, ne, abort=21f
141 str1b r0, r4, cs, abort=21f
142 str1b r0, ip, cs, abort=21f
143
144 exit r4, pc
145
1469: rsb ip, ip, #4
147 cmp ip, #2
148 ldr1b r1, r3, gt, abort=21f
149 ldr1b r1, r4, ge, abort=21f
150 ldr1b r1, lr, abort=21f
151 str1b r0, r3, gt, abort=21f
152 str1b r0, r4, ge, abort=21f
153 subs r2, r2, ip
154 str1b r0, lr, abort=21f
155 blt 8b
156 ands ip, r1, #3
157 beq 1b
158
15910: bic r1, r1, #3
160 cmp ip, #2
161 ldr1w r1, lr, abort=21f
162 beq 17f
163 bgt 18f
164
165
166 .macro forward_copy_shift pull push
167
168 subs r2, r2, #28
169 blt 14f
170
171 CALGN( ands ip, r1, #31 )
172 CALGN( rsb ip, ip, #32 )
173 CALGN( sbcnes r4, ip, r2 ) @ C is always set here
174 CALGN( subcc r2, r2, ip )
175 CALGN( bcc 15f )
176
17711: stmfd sp!, {r5 - r9}
178
179 PLD( pld [r1, #0] )
180 PLD( subs r2, r2, #96 )
181 PLD( pld [r1, #28] )
182 PLD( blt 13f )
183 PLD( pld [r1, #60] )
184 PLD( pld [r1, #92] )
185
18612: PLD( pld [r1, #124] )
18713: ldr4w r1, r4, r5, r6, r7, abort=19f
188 mov r3, lr, pull #\pull
189 subs r2, r2, #32
190 ldr4w r1, r8, r9, ip, lr, abort=19f
191 orr r3, r3, r4, push #\push
192 mov r4, r4, pull #\pull
193 orr r4, r4, r5, push #\push
194 mov r5, r5, pull #\pull
195 orr r5, r5, r6, push #\push
196 mov r6, r6, pull #\pull
197 orr r6, r6, r7, push #\push
198 mov r7, r7, pull #\pull
199 orr r7, r7, r8, push #\push
200 mov r8, r8, pull #\pull
201 orr r8, r8, r9, push #\push
202 mov r9, r9, pull #\pull
203 orr r9, r9, ip, push #\push
204 mov ip, ip, pull #\pull
205 orr ip, ip, lr, push #\push
206 str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
207 bge 12b
208 PLD( cmn r2, #96 )
209 PLD( bge 13b )
210
211 ldmfd sp!, {r5 - r9}
212
21314: ands ip, r2, #28
214 beq 16f
215
21615: mov r3, lr, pull #\pull
217 ldr1w r1, lr, abort=21f
218 subs ip, ip, #4
219 orr r3, r3, lr, push #\push
220 str1w r0, r3, abort=21f
221 bgt 15b
222 CALGN( cmp r2, #0 )
223 CALGN( bge 11b )
224
22516: sub r1, r1, #(\push / 8)
226 b 8b
227
228 .endm
229
230
231 forward_copy_shift pull=8 push=24
232
23317: forward_copy_shift pull=16 push=16
234
23518: forward_copy_shift pull=24 push=8
236
237
238/*
239 * Abort preanble and completion macros.
240 * If a fixup handler is required then those macros must surround it.
241 * It is assumed that the fixup code will handle the private part of
242 * the exit macro.
243 */
244
245 .macro copy_abort_preamble
24619: ldmfd sp!, {r5 - r9}
247 b 21f
24820: ldmfd sp!, {r5 - r8}
24921:
250 .endm
251
252 .macro copy_abort_end
253 ldmfd sp!, {r4, pc}
254 .endm
255
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
new file mode 100644
index 000000000000..4a6d8ea14022
--- /dev/null
+++ b/arch/arm/lib/copy_to_user.S
@@ -0,0 +1,101 @@
1/*
2 * linux/arch/arm/lib/copy_to_user.S
3 *
4 * Author: Nicolas Pitre
5 * Created: Sep 29, 2005
6 * Copyright: MontaVista Software, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/linkage.h>
14#include <asm/assembler.h>
15
16/*
17 * Prototype:
18 *
19 * size_t __arch_copy_to_user(void *to, const void *from, size_t n)
20 *
21 * Purpose:
22 *
23 * copy a block to user memory from kernel memory
24 *
25 * Params:
26 *
27 * to = user memory
28 * from = kernel memory
29 * n = number of bytes to copy
30 *
31 * Return value:
32 *
33 * Number of bytes NOT copied.
34 */
35
36 .macro ldr1w ptr reg abort
37 ldr \reg, [\ptr], #4
38 .endm
39
40 .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
41 ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
42 .endm
43
44 .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
45 ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
46 .endm
47
48 .macro ldr1b ptr reg cond=al abort
49 ldr\cond\()b \reg, [\ptr], #1
50 .endm
51
52 .macro str1w ptr reg abort
53100: strt \reg, [\ptr], #4
54 .section __ex_table, "a"
55 .long 100b, \abort
56 .previous
57 .endm
58
59 .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
60 str1w \ptr, \reg1, \abort
61 str1w \ptr, \reg2, \abort
62 str1w \ptr, \reg3, \abort
63 str1w \ptr, \reg4, \abort
64 str1w \ptr, \reg5, \abort
65 str1w \ptr, \reg6, \abort
66 str1w \ptr, \reg7, \abort
67 str1w \ptr, \reg8, \abort
68 .endm
69
70 .macro str1b ptr reg cond=al abort
71100: str\cond\()bt \reg, [\ptr], #1
72 .section __ex_table, "a"
73 .long 100b, \abort
74 .previous
75 .endm
76
77 .macro enter reg1 reg2
78 mov r3, #0
79 stmdb sp!, {r0, r2, r3, \reg1, \reg2}
80 .endm
81
82 .macro exit reg1 reg2
83 add sp, sp, #8
84 ldmfd sp!, {r0, \reg1, \reg2}
85 .endm
86
87 .text
88
89ENTRY(__arch_copy_to_user)
90
91#include "copy_template.S"
92
93 .section .fixup,"ax"
94 .align 0
95 copy_abort_preamble
96 ldmfd sp!, {r1, r2, r3}
97 sub r0, r0, r1
98 rsb r0, r0, r2
99 copy_abort_end
100 .previous
101
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
index f5a593ceb8cc..7e71d6708a8d 100644
--- a/arch/arm/lib/memcpy.S
+++ b/arch/arm/lib/memcpy.S
@@ -1,393 +1,59 @@
1/* 1/*
2 * linux/arch/arm/lib/memcpy.S 2 * linux/arch/arm/lib/memcpy.S
3 * 3 *
4 * Copyright (C) 1995-1999 Russell King 4 * Author: Nicolas Pitre
5 * Created: Sep 28, 2005
6 * Copyright: MontaVista Software, Inc.
5 * 7 *
6 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
9 *
10 * ASM optimised string functions
11 */ 11 */
12
12#include <linux/linkage.h> 13#include <linux/linkage.h>
13#include <asm/assembler.h> 14#include <asm/assembler.h>
14 15
15 .text 16 .macro ldr1w ptr reg abort
16 17 ldr \reg, [\ptr], #4
17#define ENTER \ 18 .endm
18 mov ip,sp ;\
19 stmfd sp!,{r0,r4-r9,fp,ip,lr,pc} ;\
20 sub fp,ip,#4
21
22#define EXIT \
23 LOADREGS(ea, fp, {r0, r4 - r9, fp, sp, pc})
24
25#define EXITEQ \
26 LOADREGS(eqea, fp, {r0, r4 - r9, fp, sp, pc})
27
28/*
29 * Prototype: void memcpy(void *to,const void *from,unsigned long n);
30 */
31ENTRY(memcpy)
32ENTRY(memmove)
33 ENTER
34 cmp r1, r0
35 bcc 23f
36 subs r2, r2, #4
37 blt 6f
38 PLD( pld [r1, #0] )
39 ands ip, r0, #3
40 bne 7f
41 ands ip, r1, #3
42 bne 8f
43 19
441: subs r2, r2, #8 20 .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
45 blt 5f 21 ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
46 subs r2, r2, #20 22 .endm
47 blt 4f
48 PLD( pld [r1, #28] )
49 PLD( subs r2, r2, #64 )
50 PLD( blt 3f )
512: PLD( pld [r1, #60] )
52 PLD( pld [r1, #92] )
53 ldmia r1!, {r3 - r9, ip}
54 subs r2, r2, #32
55 stmgeia r0!, {r3 - r9, ip}
56 ldmgeia r1!, {r3 - r9, ip}
57 subges r2, r2, #32
58 stmia r0!, {r3 - r9, ip}
59 bge 2b
603: PLD( ldmia r1!, {r3 - r9, ip} )
61 PLD( adds r2, r2, #32 )
62 PLD( stmgeia r0!, {r3 - r9, ip} )
63 PLD( ldmgeia r1!, {r3 - r9, ip} )
64 PLD( subges r2, r2, #32 )
65 PLD( stmia r0!, {r3 - r9, ip} )
664: cmn r2, #16
67 ldmgeia r1!, {r3 - r6}
68 subge r2, r2, #16
69 stmgeia r0!, {r3 - r6}
70 adds r2, r2, #20
71 ldmgeia r1!, {r3 - r5}
72 subge r2, r2, #12
73 stmgeia r0!, {r3 - r5}
745: adds r2, r2, #8
75 blt 6f
76 subs r2, r2, #4
77 ldrlt r3, [r1], #4
78 ldmgeia r1!, {r4, r5}
79 subge r2, r2, #4
80 strlt r3, [r0], #4
81 stmgeia r0!, {r4, r5}
82 23
836: adds r2, r2, #4 24 .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
84 EXITEQ 25 ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
85 cmp r2, #2 26 .endm
86 ldrb r3, [r1], #1
87 ldrgeb r4, [r1], #1
88 ldrgtb r5, [r1], #1
89 strb r3, [r0], #1
90 strgeb r4, [r0], #1
91 strgtb r5, [r0], #1
92 EXIT
93 27
947: rsb ip, ip, #4 28 .macro ldr1b ptr reg cond=al abort
95 cmp ip, #2 29 ldr\cond\()b \reg, [\ptr], #1
96 ldrb r3, [r1], #1 30 .endm
97 ldrgeb r4, [r1], #1
98 ldrgtb r5, [r1], #1
99 strb r3, [r0], #1
100 strgeb r4, [r0], #1
101 strgtb r5, [r0], #1
102 subs r2, r2, ip
103 blt 6b
104 ands ip, r1, #3
105 beq 1b
106 31
1078: bic r1, r1, #3 32 .macro str1w ptr reg abort
108 ldr r7, [r1], #4 33 str \reg, [\ptr], #4
109 cmp ip, #2 34 .endm
110 bgt 18f
111 beq 13f
112 cmp r2, #12
113 blt 11f
114 PLD( pld [r1, #12] )
115 sub r2, r2, #12
116 PLD( subs r2, r2, #32 )
117 PLD( blt 10f )
118 PLD( pld [r1, #28] )
1199: PLD( pld [r1, #44] )
12010: mov r3, r7, pull #8
121 ldmia r1!, {r4 - r7}
122 subs r2, r2, #16
123 orr r3, r3, r4, push #24
124 mov r4, r4, pull #8
125 orr r4, r4, r5, push #24
126 mov r5, r5, pull #8
127 orr r5, r5, r6, push #24
128 mov r6, r6, pull #8
129 orr r6, r6, r7, push #24
130 stmia r0!, {r3 - r6}
131 bge 9b
132 PLD( cmn r2, #32 )
133 PLD( bge 10b )
134 PLD( add r2, r2, #32 )
135 adds r2, r2, #12
136 blt 12f
13711: mov r3, r7, pull #8
138 ldr r7, [r1], #4
139 subs r2, r2, #4
140 orr r3, r3, r7, push #24
141 str r3, [r0], #4
142 bge 11b
14312: sub r1, r1, #3
144 b 6b
145 35
14613: cmp r2, #12 36 .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
147 blt 16f 37 stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
148 PLD( pld [r1, #12] ) 38 .endm
149 sub r2, r2, #12
150 PLD( subs r2, r2, #32 )
151 PLD( blt 15f )
152 PLD( pld [r1, #28] )
15314: PLD( pld [r1, #44] )
15415: mov r3, r7, pull #16
155 ldmia r1!, {r4 - r7}
156 subs r2, r2, #16
157 orr r3, r3, r4, push #16
158 mov r4, r4, pull #16
159 orr r4, r4, r5, push #16
160 mov r5, r5, pull #16
161 orr r5, r5, r6, push #16
162 mov r6, r6, pull #16
163 orr r6, r6, r7, push #16
164 stmia r0!, {r3 - r6}
165 bge 14b
166 PLD( cmn r2, #32 )
167 PLD( bge 15b )
168 PLD( add r2, r2, #32 )
169 adds r2, r2, #12
170 blt 17f
17116: mov r3, r7, pull #16
172 ldr r7, [r1], #4
173 subs r2, r2, #4
174 orr r3, r3, r7, push #16
175 str r3, [r0], #4
176 bge 16b
17717: sub r1, r1, #2
178 b 6b
179 39
18018: cmp r2, #12 40 .macro str1b ptr reg cond=al abort
181 blt 21f 41 str\cond\()b \reg, [\ptr], #1
182 PLD( pld [r1, #12] ) 42 .endm
183 sub r2, r2, #12
184 PLD( subs r2, r2, #32 )
185 PLD( blt 20f )
186 PLD( pld [r1, #28] )
18719: PLD( pld [r1, #44] )
18820: mov r3, r7, pull #24
189 ldmia r1!, {r4 - r7}
190 subs r2, r2, #16
191 orr r3, r3, r4, push #8
192 mov r4, r4, pull #24
193 orr r4, r4, r5, push #8
194 mov r5, r5, pull #24
195 orr r5, r5, r6, push #8
196 mov r6, r6, pull #24
197 orr r6, r6, r7, push #8
198 stmia r0!, {r3 - r6}
199 bge 19b
200 PLD( cmn r2, #32 )
201 PLD( bge 20b )
202 PLD( add r2, r2, #32 )
203 adds r2, r2, #12
204 blt 22f
20521: mov r3, r7, pull #24
206 ldr r7, [r1], #4
207 subs r2, r2, #4
208 orr r3, r3, r7, push #8
209 str r3, [r0], #4
210 bge 21b
21122: sub r1, r1, #1
212 b 6b
213 43
44 .macro enter reg1 reg2
45 stmdb sp!, {r0, \reg1, \reg2}
46 .endm
214 47
21523: add r1, r1, r2 48 .macro exit reg1 reg2
216 add r0, r0, r2 49 ldmfd sp!, {r0, \reg1, \reg2}
217 subs r2, r2, #4 50 .endm
218 blt 29f
219 PLD( pld [r1, #-4] )
220 ands ip, r0, #3
221 bne 30f
222 ands ip, r1, #3
223 bne 31f
224 51
22524: subs r2, r2, #8 52 .text
226 blt 28f
227 subs r2, r2, #20
228 blt 27f
229 PLD( pld [r1, #-32] )
230 PLD( subs r2, r2, #64 )
231 PLD( blt 26f )
23225: PLD( pld [r1, #-64] )
233 PLD( pld [r1, #-96] )
234 ldmdb r1!, {r3 - r9, ip}
235 subs r2, r2, #32
236 stmgedb r0!, {r3 - r9, ip}
237 ldmgedb r1!, {r3 - r9, ip}
238 subges r2, r2, #32
239 stmdb r0!, {r3 - r9, ip}
240 bge 25b
24126: PLD( ldmdb r1!, {r3 - r9, ip} )
242 PLD( adds r2, r2, #32 )
243 PLD( stmgedb r0!, {r3 - r9, ip} )
244 PLD( ldmgedb r1!, {r3 - r9, ip} )
245 PLD( subges r2, r2, #32 )
246 PLD( stmdb r0!, {r3 - r9, ip} )
24727: cmn r2, #16
248 ldmgedb r1!, {r3 - r6}
249 subge r2, r2, #16
250 stmgedb r0!, {r3 - r6}
251 adds r2, r2, #20
252 ldmgedb r1!, {r3 - r5}
253 subge r2, r2, #12
254 stmgedb r0!, {r3 - r5}
25528: adds r2, r2, #8
256 blt 29f
257 subs r2, r2, #4
258 ldrlt r3, [r1, #-4]!
259 ldmgedb r1!, {r4, r5}
260 subge r2, r2, #4
261 strlt r3, [r0, #-4]!
262 stmgedb r0!, {r4, r5}
263 53
26429: adds r2, r2, #4 54/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
265 EXITEQ
266 cmp r2, #2
267 ldrb r3, [r1, #-1]!
268 ldrgeb r4, [r1, #-1]!
269 ldrgtb r5, [r1, #-1]!
270 strb r3, [r0, #-1]!
271 strgeb r4, [r0, #-1]!
272 strgtb r5, [r0, #-1]!
273 EXIT
274 55
27530: cmp ip, #2 56ENTRY(memcpy)
276 ldrb r3, [r1, #-1]!
277 ldrgeb r4, [r1, #-1]!
278 ldrgtb r5, [r1, #-1]!
279 strb r3, [r0, #-1]!
280 strgeb r4, [r0, #-1]!
281 strgtb r5, [r0, #-1]!
282 subs r2, r2, ip
283 blt 29b
284 ands ip, r1, #3
285 beq 24b
286
28731: bic r1, r1, #3
288 ldr r3, [r1], #0
289 cmp ip, #2
290 blt 41f
291 beq 36f
292 cmp r2, #12
293 blt 34f
294 PLD( pld [r1, #-16] )
295 sub r2, r2, #12
296 PLD( subs r2, r2, #32 )
297 PLD( blt 33f )
298 PLD( pld [r1, #-32] )
29932: PLD( pld [r1, #-48] )
30033: mov r7, r3, push #8
301 ldmdb r1!, {r3, r4, r5, r6}
302 subs r2, r2, #16
303 orr r7, r7, r6, pull #24
304 mov r6, r6, push #8
305 orr r6, r6, r5, pull #24
306 mov r5, r5, push #8
307 orr r5, r5, r4, pull #24
308 mov r4, r4, push #8
309 orr r4, r4, r3, pull #24
310 stmdb r0!, {r4, r5, r6, r7}
311 bge 32b
312 PLD( cmn r2, #32 )
313 PLD( bge 33b )
314 PLD( add r2, r2, #32 )
315 adds r2, r2, #12
316 blt 35f
31734: mov ip, r3, push #8
318 ldr r3, [r1, #-4]!
319 subs r2, r2, #4
320 orr ip, ip, r3, pull #24
321 str ip, [r0, #-4]!
322 bge 34b
32335: add r1, r1, #3
324 b 29b
325
32636: cmp r2, #12
327 blt 39f
328 PLD( pld [r1, #-16] )
329 sub r2, r2, #12
330 PLD( subs r2, r2, #32 )
331 PLD( blt 38f )
332 PLD( pld [r1, #-32] )
33337: PLD( pld [r1, #-48] )
33438: mov r7, r3, push #16
335 ldmdb r1!, {r3, r4, r5, r6}
336 subs r2, r2, #16
337 orr r7, r7, r6, pull #16
338 mov r6, r6, push #16
339 orr r6, r6, r5, pull #16
340 mov r5, r5, push #16
341 orr r5, r5, r4, pull #16
342 mov r4, r4, push #16
343 orr r4, r4, r3, pull #16
344 stmdb r0!, {r4, r5, r6, r7}
345 bge 37b
346 PLD( cmn r2, #32 )
347 PLD( bge 38b )
348 PLD( add r2, r2, #32 )
349 adds r2, r2, #12
350 blt 40f
35139: mov ip, r3, push #16
352 ldr r3, [r1, #-4]!
353 subs r2, r2, #4
354 orr ip, ip, r3, pull #16
355 str ip, [r0, #-4]!
356 bge 39b
35740: add r1, r1, #2
358 b 29b
359 57
36041: cmp r2, #12 58#include "copy_template.S"
361 blt 44f
362 PLD( pld [r1, #-16] )
363 sub r2, r2, #12
364 PLD( subs r2, r2, #32 )
365 PLD( blt 43f )
366 PLD( pld [r1, #-32] )
36742: PLD( pld [r1, #-48] )
36843: mov r7, r3, push #24
369 ldmdb r1!, {r3, r4, r5, r6}
370 subs r2, r2, #16
371 orr r7, r7, r6, pull #8
372 mov r6, r6, push #24
373 orr r6, r6, r5, pull #8
374 mov r5, r5, push #24
375 orr r5, r5, r4, pull #8
376 mov r4, r4, push #24
377 orr r4, r4, r3, pull #8
378 stmdb r0!, {r4, r5, r6, r7}
379 bge 42b
380 PLD( cmn r2, #32 )
381 PLD( bge 43b )
382 PLD( add r2, r2, #32 )
383 adds r2, r2, #12
384 blt 45f
38544: mov ip, r3, push #24
386 ldr r3, [r1, #-4]!
387 subs r2, r2, #4
388 orr ip, ip, r3, pull #8
389 str ip, [r0, #-4]!
390 bge 44b
39145: add r1, r1, #1
392 b 29b
393 59
diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S
new file mode 100644
index 000000000000..ef7fddc14ac9
--- /dev/null
+++ b/arch/arm/lib/memmove.S
@@ -0,0 +1,206 @@
1/*
2 * linux/arch/arm/lib/memmove.S
3 *
4 * Author: Nicolas Pitre
5 * Created: Sep 28, 2005
6 * Copyright: (C) MontaVista Software Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/linkage.h>
14#include <asm/assembler.h>
15
16/*
17 * This can be used to enable code to cacheline align the source pointer.
18 * Experiments on tested architectures (StrongARM and XScale) didn't show
19 * this a worthwhile thing to do. That might be different in the future.
20 */
21//#define CALGN(code...) code
22#define CALGN(code...)
23
24 .text
25
26/*
27 * Prototype: void *memmove(void *dest, const void *src, size_t n);
28 *
29 * Note:
30 *
31 * If the memory regions don't overlap, we simply branch to memcpy which is
32 * normally a bit faster. Otherwise the copy is done going downwards. This
33 * is a transposition of the code from copy_template.S but with the copy
34 * occurring in the opposite direction.
35 */
36
37ENTRY(memmove)
38
39 subs ip, r0, r1
40 cmphi r2, ip
41 bls memcpy
42
43 stmfd sp!, {r0, r4, lr}
44 add r1, r1, r2
45 add r0, r0, r2
46 subs r2, r2, #4
47 blt 8f
48 ands ip, r0, #3
49 PLD( pld [r1, #-4] )
50 bne 9f
51 ands ip, r1, #3
52 bne 10f
53
541: subs r2, r2, #(28)
55 stmfd sp!, {r5 - r8}
56 blt 5f
57
58 CALGN( ands ip, r1, #31 )
59 CALGN( sbcnes r4, ip, r2 ) @ C is always set here
60 CALGN( bcs 2f )
61 CALGN( adr r4, 6f )
62 CALGN( subs r2, r2, ip ) @ C is set here
63 CALGN( add pc, r4, ip )
64
65 PLD( pld [r1, #-4] )
662: PLD( subs r2, r2, #96 )
67 PLD( pld [r1, #-32] )
68 PLD( blt 4f )
69 PLD( pld [r1, #-64] )
70 PLD( pld [r1, #-96] )
71
723: PLD( pld [r1, #-128] )
734: ldmdb r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
74 subs r2, r2, #32
75 stmdb r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
76 bge 3b
77 PLD( cmn r2, #96 )
78 PLD( bge 4b )
79
805: ands ip, r2, #28
81 rsb ip, ip, #32
82 addne pc, pc, ip @ C is always clear here
83 b 7f
846: nop
85 ldr r3, [r1, #-4]!
86 ldr r4, [r1, #-4]!
87 ldr r5, [r1, #-4]!
88 ldr r6, [r1, #-4]!
89 ldr r7, [r1, #-4]!
90 ldr r8, [r1, #-4]!
91 ldr lr, [r1, #-4]!
92
93 add pc, pc, ip
94 nop
95 nop
96 str r3, [r0, #-4]!
97 str r4, [r0, #-4]!
98 str r5, [r0, #-4]!
99 str r6, [r0, #-4]!
100 str r7, [r0, #-4]!
101 str r8, [r0, #-4]!
102 str lr, [r0, #-4]!
103
104 CALGN( bcs 2b )
105
1067: ldmfd sp!, {r5 - r8}
107
1088: movs r2, r2, lsl #31
109 ldrneb r3, [r1, #-1]!
110 ldrcsb r4, [r1, #-1]!
111 ldrcsb ip, [r1, #-1]
112 strneb r3, [r0, #-1]!
113 strcsb r4, [r0, #-1]!
114 strcsb ip, [r0, #-1]
115 ldmfd sp!, {r0, r4, pc}
116
1179: cmp ip, #2
118 ldrgtb r3, [r1, #-1]!
119 ldrgeb r4, [r1, #-1]!
120 ldrb lr, [r1, #-1]!
121 strgtb r3, [r0, #-1]!
122 strgeb r4, [r0, #-1]!
123 subs r2, r2, ip
124 strb lr, [r0, #-1]!
125 blt 8b
126 ands ip, r1, #3
127 beq 1b
128
12910: bic r1, r1, #3
130 cmp ip, #2
131 ldr r3, [r1, #0]
132 beq 17f
133 blt 18f
134
135
136 .macro backward_copy_shift push pull
137
138 subs r2, r2, #28
139 blt 14f
140
141 CALGN( ands ip, r1, #31 )
142 CALGN( rsb ip, ip, #32 )
143 CALGN( sbcnes r4, ip, r2 ) @ C is always set here
144 CALGN( subcc r2, r2, ip )
145 CALGN( bcc 15f )
146
14711: stmfd sp!, {r5 - r9}
148
149 PLD( pld [r1, #-4] )
150 PLD( subs r2, r2, #96 )
151 PLD( pld [r1, #-32] )
152 PLD( blt 13f )
153 PLD( pld [r1, #-64] )
154 PLD( pld [r1, #-96] )
155
15612: PLD( pld [r1, #-128] )
15713: ldmdb r1!, {r7, r8, r9, ip}
158 mov lr, r3, push #\push
159 subs r2, r2, #32
160 ldmdb r1!, {r3, r4, r5, r6}
161 orr lr, lr, ip, pull #\pull
162 mov ip, ip, push #\push
163 orr ip, ip, r9, pull #\pull
164 mov r9, r9, push #\push
165 orr r9, r9, r8, pull #\pull
166 mov r8, r8, push #\push
167 orr r8, r8, r7, pull #\pull
168 mov r7, r7, push #\push
169 orr r7, r7, r6, pull #\pull
170 mov r6, r6, push #\push
171 orr r6, r6, r5, pull #\pull
172 mov r5, r5, push #\push
173 orr r5, r5, r4, pull #\pull
174 mov r4, r4, push #\push
175 orr r4, r4, r3, pull #\pull
176 stmdb r0!, {r4 - r9, ip, lr}
177 bge 12b
178 PLD( cmn r2, #96 )
179 PLD( bge 13b )
180
181 ldmfd sp!, {r5 - r9}
182
18314: ands ip, r2, #28
184 beq 16f
185
18615: mov lr, r3, push #\push
187 ldr r3, [r1, #-4]!
188 subs ip, ip, #4
189 orr lr, lr, r3, pull #\pull
190 str lr, [r0, #-4]!
191 bgt 15b
192 CALGN( cmp r2, #0 )
193 CALGN( bge 11b )
194
19516: add r1, r1, #(\pull / 8)
196 b 8b
197
198 .endm
199
200
201 backward_copy_shift push=8 pull=24
202
20317: backward_copy_shift push=16 pull=16
204
20518: backward_copy_shift push=24 pull=8
206
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
index d3ed0636c008..c28449157bea 100644
--- a/arch/arm/lib/uaccess.S
+++ b/arch/arm/lib/uaccess.S
@@ -657,41 +657,3 @@ USER( ldrgtbt r3, [r1], #1) @ May fault
657 LOADREGS(fd,sp!, {r4 - r7, pc}) 657 LOADREGS(fd,sp!, {r4 - r7, pc})
658 .previous 658 .previous
659 659
660/* Prototype: int __arch_clear_user(void *addr, size_t sz)
661 * Purpose : clear some user memory
662 * Params : addr - user memory address to clear
663 * : sz - number of bytes to clear
664 * Returns : number of bytes NOT cleared
665 */
666ENTRY(__arch_clear_user)
667 stmfd sp!, {r1, lr}
668 mov r2, #0
669 cmp r1, #4
670 blt 2f
671 ands ip, r0, #3
672 beq 1f
673 cmp ip, #2
674USER( strbt r2, [r0], #1)
675USER( strlebt r2, [r0], #1)
676USER( strltbt r2, [r0], #1)
677 rsb ip, ip, #4
678 sub r1, r1, ip @ 7 6 5 4 3 2 1
6791: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7
680USER( strplt r2, [r0], #4)
681USER( strplt r2, [r0], #4)
682 bpl 1b
683 adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3
684USER( strplt r2, [r0], #4)
6852: tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x
686USER( strnebt r2, [r0], #1)
687USER( strnebt r2, [r0], #1)
688 tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1
689USER( strnebt r2, [r0], #1)
690 mov r0, #0
691 LOADREGS(fd,sp!, {r1, pc})
692
693 .section .fixup,"ax"
694 .align 0
6959001: LOADREGS(fd,sp!, {r0, pc})
696 .previous
697
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
index 0c53dab80905..4e706d9ad368 100644
--- a/arch/arm/mach-aaec2000/core.c
+++ b/arch/arm/mach-aaec2000/core.c
@@ -13,7 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/device.h> 16#include <linux/platform_device.h>
17#include <linux/list.h> 17#include <linux/list.h>
18#include <linux/errno.h> 18#include <linux/errno.h>
19#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 15261646dcdd..ed4614983adb 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -251,9 +251,33 @@ static struct platform_device serial_device = {
251 }, 251 },
252}; 252};
253 253
254static struct resource am79c961_resources[] = {
255 {
256 .start = 0x220,
257 .end = 0x238,
258 .flags = IORESOURCE_IO,
259 }, {
260 .start = IRQ_EBSA110_ETHERNET,
261 .end = IRQ_EBSA110_ETHERNET,
262 .flags = IORESOURCE_IRQ,
263 },
264};
265
266static struct platform_device am79c961_device = {
267 .name = "am79c961",
268 .id = -1,
269 .num_resources = ARRAY_SIZE(am79c961_resources),
270 .resource = am79c961_resources,
271};
272
273static struct platform_device *ebsa110_devices[] = {
274 &serial_device,
275 &am79c961_device,
276};
277
254static int __init ebsa110_init(void) 278static int __init ebsa110_init(void)
255{ 279{
256 return platform_device_register(&serial_device); 280 return platform_add_devices(ebsa110_devices, ARRAY_SIZE(ebsa110_devices));
257} 281}
258 282
259arch_initcall(ebsa110_init); 283arch_initcall(ebsa110_init);
diff --git a/arch/arm/mach-h720x/h7202-eval.c b/arch/arm/mach-h720x/h7202-eval.c
index db9078ad008c..d75c8221d2a5 100644
--- a/arch/arm/mach-h720x/h7202-eval.c
+++ b/arch/arm/mach-h720x/h7202-eval.c
@@ -18,7 +18,7 @@
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/types.h> 19#include <linux/types.h>
20#include <linux/string.h> 20#include <linux/string.h>
21#include <linux/device.h> 21#include <linux/platform_device.h>
22 22
23#include <asm/setup.h> 23#include <asm/setup.h>
24#include <asm/types.h> 24#include <asm/types.h>
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c
index 837d7f0bda4c..37613ad68366 100644
--- a/arch/arm/mach-imx/generic.c
+++ b/arch/arm/mach-imx/generic.c
@@ -22,7 +22,7 @@
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * 23 *
24 */ 24 */
25#include <linux/device.h> 25#include <linux/platform_device.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/module.h> 28#include <linux/module.h>
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c
index 4cbdc1fe04b1..708e1b3faa14 100644
--- a/arch/arm/mach-imx/mx1ads.c
+++ b/arch/arm/mach-imx/mx1ads.c
@@ -14,6 +14,7 @@
14 14
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/platform_device.h>
17#include <asm/system.h> 18#include <asm/system.h>
18#include <asm/hardware.h> 19#include <asm/hardware.h>
19#include <asm/irq.h> 20#include <asm/irq.h>
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 764ceb49470a..4c0f7c65facf 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -21,7 +21,7 @@
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/list.h> 23#include <linux/list.h>
24#include <linux/device.h> 24#include <linux/platform_device.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/string.h> 26#include <linux/string.h>
27#include <linux/sysdev.h> 27#include <linux/sysdev.h>
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index aa34c58b96c4..93f7ccb22c27 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -11,7 +11,7 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/list.h> 13#include <linux/list.h>
14#include <linux/device.h> 14#include <linux/platform_device.h>
15#include <linux/dma-mapping.h> 15#include <linux/dma-mapping.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/string.h> 17#include <linux/string.h>
diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c
index bb5091223b63..80770233b8d4 100644
--- a/arch/arm/mach-iop3xx/iop321-setup.c
+++ b/arch/arm/mach-iop3xx/iop321-setup.c
@@ -16,7 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/major.h> 17#include <linux/major.h>
18#include <linux/fs.h> 18#include <linux/fs.h>
19#include <linux/device.h> 19#include <linux/platform_device.h>
20#include <linux/serial.h> 20#include <linux/serial.h>
21#include <linux/tty.h> 21#include <linux/tty.h>
22#include <linux/serial_core.h> 22#include <linux/serial_core.h>
diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c
index a2533c3ab42f..53f60614498b 100644
--- a/arch/arm/mach-iop3xx/iop331-setup.c
+++ b/arch/arm/mach-iop3xx/iop331-setup.c
@@ -15,7 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/major.h> 16#include <linux/major.h>
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/device.h> 18#include <linux/platform_device.h>
19#include <linux/serial.h> 19#include <linux/serial.h>
20#include <linux/tty.h> 20#include <linux/tty.h>
21#include <linux/serial_core.h> 21#include <linux/serial_core.h>
diff --git a/arch/arm/mach-ixp2000/Makefile b/arch/arm/mach-ixp2000/Makefile
index 1e6139d42a92..9621aeb61f46 100644
--- a/arch/arm/mach-ixp2000/Makefile
+++ b/arch/arm/mach-ixp2000/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4obj-y := core.o pci.o 4obj-y := core.o pci.o uengine.o
5obj-m := 5obj-m :=
6obj-n := 6obj-n :=
7obj- := 7obj- :=
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index 01c393c504d0..c93a98b2a32c 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/mach-ixp2000/common.c 2 * arch/arm/mach-ixp2000/core.c
3 * 3 *
4 * Common routines used by all IXP2400/2800 based platforms. 4 * Common routines used by all IXP2400/2800 based platforms.
5 * 5 *
@@ -49,7 +49,6 @@ static unsigned long ixp2000_slowport_irq_flags;
49 *************************************************************************/ 49 *************************************************************************/
50void ixp2000_acquire_slowport(struct slowport_cfg *new_cfg, struct slowport_cfg *old_cfg) 50void ixp2000_acquire_slowport(struct slowport_cfg *new_cfg, struct slowport_cfg *old_cfg)
51{ 51{
52
53 spin_lock_irqsave(&ixp2000_slowport_lock, ixp2000_slowport_irq_flags); 52 spin_lock_irqsave(&ixp2000_slowport_lock, ixp2000_slowport_irq_flags);
54 53
55 old_cfg->CCR = *IXP2000_SLOWPORT_CCR; 54 old_cfg->CCR = *IXP2000_SLOWPORT_CCR;
@@ -62,7 +61,7 @@ void ixp2000_acquire_slowport(struct slowport_cfg *new_cfg, struct slowport_cfg
62 ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, new_cfg->WTC); 61 ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, new_cfg->WTC);
63 ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, new_cfg->RTC); 62 ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, new_cfg->RTC);
64 ixp2000_reg_write(IXP2000_SLOWPORT_PCR, new_cfg->PCR); 63 ixp2000_reg_write(IXP2000_SLOWPORT_PCR, new_cfg->PCR);
65 ixp2000_reg_write(IXP2000_SLOWPORT_ADC, new_cfg->ADC); 64 ixp2000_reg_wrb(IXP2000_SLOWPORT_ADC, new_cfg->ADC);
66} 65}
67 66
68void ixp2000_release_slowport(struct slowport_cfg *old_cfg) 67void ixp2000_release_slowport(struct slowport_cfg *old_cfg)
@@ -71,7 +70,7 @@ void ixp2000_release_slowport(struct slowport_cfg *old_cfg)
71 ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, old_cfg->WTC); 70 ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, old_cfg->WTC);
72 ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, old_cfg->RTC); 71 ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, old_cfg->RTC);
73 ixp2000_reg_write(IXP2000_SLOWPORT_PCR, old_cfg->PCR); 72 ixp2000_reg_write(IXP2000_SLOWPORT_PCR, old_cfg->PCR);
74 ixp2000_reg_write(IXP2000_SLOWPORT_ADC, old_cfg->ADC); 73 ixp2000_reg_wrb(IXP2000_SLOWPORT_ADC, old_cfg->ADC);
75 74
76 spin_unlock_irqrestore(&ixp2000_slowport_lock, 75 spin_unlock_irqrestore(&ixp2000_slowport_lock,
77 ixp2000_slowport_irq_flags); 76 ixp2000_slowport_irq_flags);
@@ -145,7 +144,7 @@ void __init ixp2000_map_io(void)
145 iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc)); 144 iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc));
146 145
147 /* Set slowport to 8-bit mode. */ 146 /* Set slowport to 8-bit mode. */
148 ixp2000_reg_write(IXP2000_SLOWPORT_FRM, 1); 147 ixp2000_reg_wrb(IXP2000_SLOWPORT_FRM, 1);
149} 148}
150 149
151 150
@@ -209,7 +208,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
209 write_seqlock(&xtime_lock); 208 write_seqlock(&xtime_lock);
210 209
211 /* clear timer 1 */ 210 /* clear timer 1 */
212 ixp2000_reg_write(IXP2000_T1_CLR, 1); 211 ixp2000_reg_wrb(IXP2000_T1_CLR, 1);
213 212
214 while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) { 213 while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) {
215 timer_tick(regs); 214 timer_tick(regs);
@@ -252,12 +251,12 @@ void __init ixp2000_init_time(unsigned long tick_rate)
252 251
253 ixp2000_reg_write(IXP2000_T4_CLR, 0); 252 ixp2000_reg_write(IXP2000_T4_CLR, 0);
254 ixp2000_reg_write(IXP2000_T4_CLD, -1); 253 ixp2000_reg_write(IXP2000_T4_CLD, -1);
255 ixp2000_reg_write(IXP2000_T4_CTL, (1 << 7)); 254 ixp2000_reg_wrb(IXP2000_T4_CTL, (1 << 7));
256 missing_jiffy_timer_csr = IXP2000_T4_CSR; 255 missing_jiffy_timer_csr = IXP2000_T4_CSR;
257 } else { 256 } else {
258 ixp2000_reg_write(IXP2000_T2_CLR, 0); 257 ixp2000_reg_write(IXP2000_T2_CLR, 0);
259 ixp2000_reg_write(IXP2000_T2_CLD, -1); 258 ixp2000_reg_write(IXP2000_T2_CLD, -1);
260 ixp2000_reg_write(IXP2000_T2_CTL, (1 << 7)); 259 ixp2000_reg_wrb(IXP2000_T2_CTL, (1 << 7));
261 missing_jiffy_timer_csr = IXP2000_T2_CSR; 260 missing_jiffy_timer_csr = IXP2000_T2_CSR;
262 } 261 }
263 next_jiffy_time = 0xffffffff; 262 next_jiffy_time = 0xffffffff;
@@ -279,7 +278,7 @@ static void update_gpio_int_csrs(void)
279 ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge); 278 ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge);
280 ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge); 279 ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge);
281 ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low); 280 ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low);
282 ixp2000_reg_write(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high); 281 ixp2000_reg_wrb(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
283} 282}
284 283
285void gpio_line_config(int line, int direction) 284void gpio_line_config(int line, int direction)
@@ -297,9 +296,9 @@ void gpio_line_config(int line, int direction)
297 GPIO_IRQ_level_high &= ~(1 << line); 296 GPIO_IRQ_level_high &= ~(1 << line);
298 update_gpio_int_csrs(); 297 update_gpio_int_csrs();
299 298
300 ixp2000_reg_write(IXP2000_GPIO_PDSR, 1 << line); 299 ixp2000_reg_wrb(IXP2000_GPIO_PDSR, 1 << line);
301 } else if (direction == GPIO_IN) { 300 } else if (direction == GPIO_IN) {
302 ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line); 301 ixp2000_reg_wrb(IXP2000_GPIO_PDCR, 1 << line);
303 } 302 }
304 local_irq_restore(flags); 303 local_irq_restore(flags);
305} 304}
@@ -365,12 +364,12 @@ static void ixp2000_GPIO_irq_mask_ack(unsigned int irq)
365 364
366 ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0))); 365 ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
367 ixp2000_reg_write(IXP2000_GPIO_LDSR, (1 << (irq - IRQ_IXP2000_GPIO0))); 366 ixp2000_reg_write(IXP2000_GPIO_LDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
368 ixp2000_reg_write(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0))); 367 ixp2000_reg_wrb(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0)));
369} 368}
370 369
371static void ixp2000_GPIO_irq_mask(unsigned int irq) 370static void ixp2000_GPIO_irq_mask(unsigned int irq)
372{ 371{
373 ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0))); 372 ixp2000_reg_wrb(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
374} 373}
375 374
376static void ixp2000_GPIO_irq_unmask(unsigned int irq) 375static void ixp2000_GPIO_irq_unmask(unsigned int irq)
@@ -389,9 +388,9 @@ static void ixp2000_pci_irq_mask(unsigned int irq)
389{ 388{
390 unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE; 389 unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE;
391 if (irq == IRQ_IXP2000_PCIA) 390 if (irq == IRQ_IXP2000_PCIA)
392 ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 26))); 391 ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 26)));
393 else if (irq == IRQ_IXP2000_PCIB) 392 else if (irq == IRQ_IXP2000_PCIB)
394 ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 27))); 393 ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 27)));
395} 394}
396 395
397static void ixp2000_pci_irq_unmask(unsigned int irq) 396static void ixp2000_pci_irq_unmask(unsigned int irq)
@@ -411,7 +410,7 @@ static struct irqchip ixp2000_pci_irq_chip = {
411 410
412static void ixp2000_irq_mask(unsigned int irq) 411static void ixp2000_irq_mask(unsigned int irq)
413{ 412{
414 ixp2000_reg_write(IXP2000_IRQ_ENABLE_CLR, (1 << irq)); 413 ixp2000_reg_wrb(IXP2000_IRQ_ENABLE_CLR, (1 << irq));
415} 414}
416 415
417static void ixp2000_irq_unmask(unsigned int irq) 416static void ixp2000_irq_unmask(unsigned int irq)
@@ -443,7 +442,7 @@ void __init ixp2000_init_irq(void)
443 ixp2000_reg_write(IXP2000_GPIO_INCR, -1); 442 ixp2000_reg_write(IXP2000_GPIO_INCR, -1);
444 443
445 /* clear PCI interrupt sources */ 444 /* clear PCI interrupt sources */
446 ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, 0); 445 ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, 0);
447 446
448 /* 447 /*
449 * Certain bits in the IRQ status register of the 448 * Certain bits in the IRQ status register of the
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c
index 9aa54de44740..7719c478aa84 100644
--- a/arch/arm/mach-ixp2000/enp2611.c
+++ b/arch/arm/mach-ixp2000/enp2611.c
@@ -32,7 +32,7 @@
32#include <linux/serial.h> 32#include <linux/serial.h>
33#include <linux/tty.h> 33#include <linux/tty.h>
34#include <linux/serial_core.h> 34#include <linux/serial_core.h>
35#include <linux/device.h> 35#include <linux/platform_device.h>
36 36
37#include <asm/io.h> 37#include <asm/io.h>
38#include <asm/irq.h> 38#include <asm/irq.h>
@@ -64,6 +64,35 @@ static struct sys_timer enp2611_timer = {
64 64
65 65
66/************************************************************************* 66/*************************************************************************
67 * ENP-2611 I/O
68 *************************************************************************/
69static struct map_desc enp2611_io_desc[] __initdata = {
70 {
71 .virtual = ENP2611_CALEB_VIRT_BASE,
72 .physical = ENP2611_CALEB_PHYS_BASE,
73 .length = ENP2611_CALEB_SIZE,
74 .type = MT_IXP2000_DEVICE
75 }, {
76 .virtual = ENP2611_PM3386_0_VIRT_BASE,
77 .physical = ENP2611_PM3386_0_PHYS_BASE,
78 .length = ENP2611_PM3386_0_SIZE,
79 .type = MT_IXP2000_DEVICE
80 }, {
81 .virtual = ENP2611_PM3386_1_VIRT_BASE,
82 .physical = ENP2611_PM3386_1_PHYS_BASE,
83 .length = ENP2611_PM3386_1_SIZE,
84 .type = MT_IXP2000_DEVICE
85 }
86};
87
88void __init enp2611_map_io(void)
89{
90 ixp2000_map_io();
91 iotable_init(enp2611_io_desc, ARRAY_SIZE(enp2611_io_desc));
92}
93
94
95/*************************************************************************
67 * ENP-2611 PCI 96 * ENP-2611 PCI
68 *************************************************************************/ 97 *************************************************************************/
69static int enp2611_pci_setup(int nr, struct pci_sys_data *sys) 98static int enp2611_pci_setup(int nr, struct pci_sys_data *sys)
@@ -229,7 +258,7 @@ MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board")
229 .phys_io = IXP2000_UART_PHYS_BASE, 258 .phys_io = IXP2000_UART_PHYS_BASE,
230 .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, 259 .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc,
231 .boot_params = 0x00000100, 260 .boot_params = 0x00000100,
232 .map_io = ixp2000_map_io, 261 .map_io = enp2611_map_io,
233 .init_irq = ixp2000_init_irq, 262 .init_irq = ixp2000_init_irq,
234 .timer = &enp2611_timer, 263 .timer = &enp2611_timer,
235 .init_machine = enp2611_init_machine, 264 .init_machine = enp2611_init_machine,
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
index 8b4a839b6279..d628da56b4bc 100644
--- a/arch/arm/mach-ixp2000/ixdp2x00.c
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -20,7 +20,7 @@
20#include <linux/mm.h> 20#include <linux/mm.h>
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/device.h> 23#include <linux/platform_device.h>
24#include <linux/bitops.h> 24#include <linux/bitops.h>
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/ioport.h> 26#include <linux/ioport.h>
@@ -81,7 +81,7 @@ static void ixdp2x00_irq_mask(unsigned int irq)
81 81
82 dummy = *board_irq_mask; 82 dummy = *board_irq_mask;
83 dummy |= IXP2000_BOARD_IRQ_MASK(irq); 83 dummy |= IXP2000_BOARD_IRQ_MASK(irq);
84 ixp2000_reg_write(board_irq_mask, dummy); 84 ixp2000_reg_wrb(board_irq_mask, dummy);
85 85
86#ifdef CONFIG_ARCH_IXDP2400 86#ifdef CONFIG_ARCH_IXDP2400
87 if (machine_is_ixdp2400()) 87 if (machine_is_ixdp2400())
@@ -101,7 +101,7 @@ static void ixdp2x00_irq_unmask(unsigned int irq)
101 101
102 dummy = *board_irq_mask; 102 dummy = *board_irq_mask;
103 dummy &= ~IXP2000_BOARD_IRQ_MASK(irq); 103 dummy &= ~IXP2000_BOARD_IRQ_MASK(irq);
104 ixp2000_reg_write(board_irq_mask, dummy); 104 ixp2000_reg_wrb(board_irq_mask, dummy);
105 105
106 if (machine_is_ixdp2400()) 106 if (machine_is_ixdp2400())
107 ixp2000_release_slowport(&old_cfg); 107 ixp2000_release_slowport(&old_cfg);
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
index fee1d7b73503..e6a882f35da2 100644
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -29,7 +29,7 @@
29#include <linux/serial.h> 29#include <linux/serial.h>
30#include <linux/tty.h> 30#include <linux/tty.h>
31#include <linux/serial_core.h> 31#include <linux/serial_core.h>
32#include <linux/device.h> 32#include <linux/platform_device.h>
33 33
34#include <asm/io.h> 34#include <asm/io.h>
35#include <asm/irq.h> 35#include <asm/irq.h>
@@ -51,7 +51,7 @@
51 *************************************************************************/ 51 *************************************************************************/
52static void ixdp2x01_irq_mask(unsigned int irq) 52static void ixdp2x01_irq_mask(unsigned int irq)
53{ 53{
54 ixp2000_reg_write(IXDP2X01_INT_MASK_SET_REG, 54 ixp2000_reg_wrb(IXDP2X01_INT_MASK_SET_REG,
55 IXP2000_BOARD_IRQ_MASK(irq)); 55 IXP2000_BOARD_IRQ_MASK(irq));
56} 56}
57 57
@@ -114,7 +114,7 @@ void __init ixdp2x01_init_irq(void)
114 114
115 /* Mask all interrupts from CPLD, disable simulation */ 115 /* Mask all interrupts from CPLD, disable simulation */
116 ixp2000_reg_write(IXDP2X01_INT_MASK_SET_REG, 0xffffffff); 116 ixp2000_reg_write(IXDP2X01_INT_MASK_SET_REG, 0xffffffff);
117 ixp2000_reg_write(IXDP2X01_INT_SIM_REG, 0); 117 ixp2000_reg_wrb(IXDP2X01_INT_SIM_REG, 0);
118 118
119 for (irq = NR_IXP2000_IRQS; irq < NR_IXDP2X01_IRQS; irq++) { 119 for (irq = NR_IXP2000_IRQS; irq < NR_IXDP2X01_IRQS; irq++) {
120 if (irq & valid_irq_mask) { 120 if (irq & valid_irq_mask) {
@@ -299,7 +299,6 @@ struct hw_pci ixdp2x01_pci __initdata = {
299 299
300int __init ixdp2x01_pci_init(void) 300int __init ixdp2x01_pci_init(void)
301{ 301{
302
303 pci_common_init(&ixdp2x01_pci); 302 pci_common_init(&ixdp2x01_pci);
304 return 0; 303 return 0;
305} 304}
@@ -316,7 +315,7 @@ static struct flash_platform_data ixdp2x01_flash_platform_data = {
316 315
317static unsigned long ixdp2x01_flash_bank_setup(unsigned long ofs) 316static unsigned long ixdp2x01_flash_bank_setup(unsigned long ofs)
318{ 317{
319 ixp2000_reg_write(IXDP2X01_CPLD_FLASH_REG, 318 ixp2000_reg_wrb(IXDP2X01_CPLD_FLASH_REG,
320 ((ofs >> IXDP2X01_FLASH_WINDOW_BITS) | IXDP2X01_CPLD_FLASH_INTERN)); 319 ((ofs >> IXDP2X01_FLASH_WINDOW_BITS) | IXDP2X01_CPLD_FLASH_INTERN));
321 return (ofs & IXDP2X01_FLASH_WINDOW_MASK); 320 return (ofs & IXDP2X01_FLASH_WINDOW_MASK);
322} 321}
@@ -363,7 +362,7 @@ static struct platform_device *ixdp2x01_devices[] __initdata = {
363 362
364static void __init ixdp2x01_init_machine(void) 363static void __init ixdp2x01_init_machine(void)
365{ 364{
366 ixp2000_reg_write(IXDP2X01_CPLD_FLASH_REG, 365 ixp2000_reg_wrb(IXDP2X01_CPLD_FLASH_REG,
367 (IXDP2X01_CPLD_FLASH_BANK_MASK | IXDP2X01_CPLD_FLASH_INTERN)); 366 (IXDP2X01_CPLD_FLASH_BANK_MASK | IXDP2X01_CPLD_FLASH_INTERN));
368 367
369 ixdp2x01_flash_data.nr_banks = 368 ixdp2x01_flash_data.nr_banks =
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
index 522205acb316..d4bf1e1c0031 100644
--- a/arch/arm/mach-ixp2000/pci.c
+++ b/arch/arm/mach-ixp2000/pci.c
@@ -148,7 +148,7 @@ int ixp2000_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_re
148 local_irq_save(flags); 148 local_irq_save(flags);
149 temp = *(IXP2000_PCI_CONTROL); 149 temp = *(IXP2000_PCI_CONTROL);
150 if (temp & ((1 << 8) | (1 << 5))) { 150 if (temp & ((1 << 8) | (1 << 5))) {
151 ixp2000_reg_write(IXP2000_PCI_CONTROL, temp); 151 ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp);
152 } 152 }
153 153
154 temp = *(IXP2000_PCI_CMDSTAT); 154 temp = *(IXP2000_PCI_CMDSTAT);
@@ -178,8 +178,8 @@ clear_master_aborts(void)
178 178
179 local_irq_save(flags); 179 local_irq_save(flags);
180 temp = *(IXP2000_PCI_CONTROL); 180 temp = *(IXP2000_PCI_CONTROL);
181 if (temp & ((1 << 8) | (1 << 5))) { 181 if (temp & ((1 << 8) | (1 << 5))) {
182 ixp2000_reg_write(IXP2000_PCI_CONTROL, temp); 182 ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp);
183 } 183 }
184 184
185 temp = *(IXP2000_PCI_CMDSTAT); 185 temp = *(IXP2000_PCI_CMDSTAT);
diff --git a/arch/arm/mach-ixp2000/uengine.c b/arch/arm/mach-ixp2000/uengine.c
new file mode 100644
index 000000000000..43e234349d4a
--- /dev/null
+++ b/arch/arm/mach-ixp2000/uengine.c
@@ -0,0 +1,474 @@
1/*
2 * Generic library functions for the microengines found on the Intel
3 * IXP2000 series of network processors.
4 *
5 * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
6 * Dedicated to Marija Kulikova.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as
10 * published by the Free Software Foundation; either version 2.1 of the
11 * License, or (at your option) any later version.
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/module.h>
19#include <linux/string.h>
20#include <asm/hardware.h>
21#include <asm/arch/ixp2000-regs.h>
22#include <asm/arch/uengine.h>
23#include <asm/io.h>
24
25#define USTORE_ADDRESS 0x000
26#define USTORE_DATA_LOWER 0x004
27#define USTORE_DATA_UPPER 0x008
28#define CTX_ENABLES 0x018
29#define CC_ENABLE 0x01c
30#define CSR_CTX_POINTER 0x020
31#define INDIRECT_CTX_STS 0x040
32#define ACTIVE_CTX_STS 0x044
33#define INDIRECT_CTX_SIG_EVENTS 0x048
34#define INDIRECT_CTX_WAKEUP_EVENTS 0x050
35#define NN_PUT 0x080
36#define NN_GET 0x084
37#define TIMESTAMP_LOW 0x0c0
38#define TIMESTAMP_HIGH 0x0c4
39#define T_INDEX_BYTE_INDEX 0x0f4
40#define LOCAL_CSR_STATUS 0x180
41
42u32 ixp2000_uengine_mask;
43
44static void *ixp2000_uengine_csr_area(int uengine)
45{
46 return ((void *)IXP2000_UENGINE_CSR_VIRT_BASE) + (uengine << 10);
47}
48
49/*
50 * LOCAL_CSR_STATUS=1 after a read or write to a microengine's CSR
51 * space means that the microengine we tried to access was also trying
52 * to access its own CSR space on the same clock cycle as we did. When
53 * this happens, we lose the arbitration process by default, and the
54 * read or write we tried to do was not actually performed, so we try
55 * again until it succeeds.
56 */
57u32 ixp2000_uengine_csr_read(int uengine, int offset)
58{
59 void *uebase;
60 u32 *local_csr_status;
61 u32 *reg;
62 u32 value;
63
64 uebase = ixp2000_uengine_csr_area(uengine);
65
66 local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS);
67 reg = (u32 *)(uebase + offset);
68 do {
69 value = ixp2000_reg_read(reg);
70 } while (ixp2000_reg_read(local_csr_status) & 1);
71
72 return value;
73}
74EXPORT_SYMBOL(ixp2000_uengine_csr_read);
75
76void ixp2000_uengine_csr_write(int uengine, int offset, u32 value)
77{
78 void *uebase;
79 u32 *local_csr_status;
80 u32 *reg;
81
82 uebase = ixp2000_uengine_csr_area(uengine);
83
84 local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS);
85 reg = (u32 *)(uebase + offset);
86 do {
87 ixp2000_reg_write(reg, value);
88 } while (ixp2000_reg_read(local_csr_status) & 1);
89}
90EXPORT_SYMBOL(ixp2000_uengine_csr_write);
91
92void ixp2000_uengine_reset(u32 uengine_mask)
93{
94 ixp2000_reg_write(IXP2000_RESET1, uengine_mask & ixp2000_uengine_mask);
95 ixp2000_reg_write(IXP2000_RESET1, 0);
96}
97EXPORT_SYMBOL(ixp2000_uengine_reset);
98
99void ixp2000_uengine_set_mode(int uengine, u32 mode)
100{
101 /*
102 * CTL_STR_PAR_EN: unconditionally enable parity checking on
103 * control store.
104 */
105 mode |= 0x10000000;
106 ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mode);
107
108 /*
109 * Enable updating of condition codes.
110 */
111 ixp2000_uengine_csr_write(uengine, CC_ENABLE, 0x00002000);
112
113 /*
114 * Initialise other per-microengine registers.
115 */
116 ixp2000_uengine_csr_write(uengine, NN_PUT, 0x00);
117 ixp2000_uengine_csr_write(uengine, NN_GET, 0x00);
118 ixp2000_uengine_csr_write(uengine, T_INDEX_BYTE_INDEX, 0);
119}
120EXPORT_SYMBOL(ixp2000_uengine_set_mode);
121
122static int make_even_parity(u32 x)
123{
124 return hweight32(x) & 1;
125}
126
127static void ustore_write(int uengine, u64 insn)
128{
129 /*
130 * Generate even parity for top and bottom 20 bits.
131 */
132 insn |= (u64)make_even_parity((insn >> 20) & 0x000fffff) << 41;
133 insn |= (u64)make_even_parity(insn & 0x000fffff) << 40;
134
135 /*
136 * Write to microstore. The second write auto-increments
137 * the USTORE_ADDRESS index register.
138 */
139 ixp2000_uengine_csr_write(uengine, USTORE_DATA_LOWER, (u32)insn);
140 ixp2000_uengine_csr_write(uengine, USTORE_DATA_UPPER, (u32)(insn >> 32));
141}
142
143void ixp2000_uengine_load_microcode(int uengine, u8 *ucode, int insns)
144{
145 int i;
146
147 /*
148 * Start writing to microstore at address 0.
149 */
150 ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x80000000);
151 for (i = 0; i < insns; i++) {
152 u64 insn;
153
154 insn = (((u64)ucode[0]) << 32) |
155 (((u64)ucode[1]) << 24) |
156 (((u64)ucode[2]) << 16) |
157 (((u64)ucode[3]) << 8) |
158 ((u64)ucode[4]);
159 ucode += 5;
160
161 ustore_write(uengine, insn);
162 }
163
164 /*
165 * Pad with a few NOPs at the end (to avoid the microengine
166 * aborting as it prefetches beyond the last instruction), unless
167 * we run off the end of the instruction store first, at which
168 * point the address register will wrap back to zero.
169 */
170 for (i = 0; i < 4; i++) {
171 u32 addr;
172
173 addr = ixp2000_uengine_csr_read(uengine, USTORE_ADDRESS);
174 if (addr == 0x80000000)
175 break;
176 ustore_write(uengine, 0xf0000c0300ULL);
177 }
178
179 /*
180 * End programming.
181 */
182 ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x00000000);
183}
184EXPORT_SYMBOL(ixp2000_uengine_load_microcode);
185
186void ixp2000_uengine_init_context(int uengine, int context, int pc)
187{
188 /*
189 * Select the right context for indirect access.
190 */
191 ixp2000_uengine_csr_write(uengine, CSR_CTX_POINTER, context);
192
193 /*
194 * Initialise signal masks to immediately go to Ready state.
195 */
196 ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_SIG_EVENTS, 1);
197 ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_WAKEUP_EVENTS, 1);
198
199 /*
200 * Set program counter.
201 */
202 ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_STS, pc);
203}
204EXPORT_SYMBOL(ixp2000_uengine_init_context);
205
206void ixp2000_uengine_start_contexts(int uengine, u8 ctx_mask)
207{
208 u32 mask;
209
210 /*
211 * Enable the specified context to go to Executing state.
212 */
213 mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES);
214 mask |= ctx_mask << 8;
215 ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask);
216}
217EXPORT_SYMBOL(ixp2000_uengine_start_contexts);
218
219void ixp2000_uengine_stop_contexts(int uengine, u8 ctx_mask)
220{
221 u32 mask;
222
223 /*
224 * Disable the Ready->Executing transition. Note that this
225 * does not stop the context until it voluntarily yields.
226 */
227 mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES);
228 mask &= ~(ctx_mask << 8);
229 ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask);
230}
231EXPORT_SYMBOL(ixp2000_uengine_stop_contexts);
232
233static int check_ixp_type(struct ixp2000_uengine_code *c)
234{
235 u32 product_id;
236 u32 rev;
237
238 product_id = ixp2000_reg_read(IXP2000_PRODUCT_ID);
239 if (((product_id >> 16) & 0x1f) != 0)
240 return 0;
241
242 switch ((product_id >> 8) & 0xff) {
243 case 0: /* IXP2800 */
244 if (!(c->cpu_model_bitmask & 4))
245 return 0;
246 break;
247
248 case 1: /* IXP2850 */
249 if (!(c->cpu_model_bitmask & 8))
250 return 0;
251 break;
252
253 case 2: /* IXP2400 */
254 if (!(c->cpu_model_bitmask & 2))
255 return 0;
256 break;
257
258 default:
259 return 0;
260 }
261
262 rev = product_id & 0xff;
263 if (rev < c->cpu_min_revision || rev > c->cpu_max_revision)
264 return 0;
265
266 return 1;
267}
268
269static void generate_ucode(u8 *ucode, u32 *gpr_a, u32 *gpr_b)
270{
271 int offset;
272 int i;
273
274 offset = 0;
275
276 for (i = 0; i < 128; i++) {
277 u8 b3;
278 u8 b2;
279 u8 b1;
280 u8 b0;
281
282 b3 = (gpr_a[i] >> 24) & 0xff;
283 b2 = (gpr_a[i] >> 16) & 0xff;
284 b1 = (gpr_a[i] >> 8) & 0xff;
285 b0 = gpr_a[i] & 0xff;
286
287 // immed[@ai, (b1 << 8) | b0]
288 // 11110000 0000VVVV VVVV11VV VVVVVV00 1IIIIIII
289 ucode[offset++] = 0xf0;
290 ucode[offset++] = (b1 >> 4);
291 ucode[offset++] = (b1 << 4) | 0x0c | (b0 >> 6);
292 ucode[offset++] = (b0 << 2);
293 ucode[offset++] = 0x80 | i;
294
295 // immed_w1[@ai, (b3 << 8) | b2]
296 // 11110100 0100VVVV VVVV11VV VVVVVV00 1IIIIIII
297 ucode[offset++] = 0xf4;
298 ucode[offset++] = 0x40 | (b3 >> 4);
299 ucode[offset++] = (b3 << 4) | 0x0c | (b2 >> 6);
300 ucode[offset++] = (b2 << 2);
301 ucode[offset++] = 0x80 | i;
302 }
303
304 for (i = 0; i < 128; i++) {
305 u8 b3;
306 u8 b2;
307 u8 b1;
308 u8 b0;
309
310 b3 = (gpr_b[i] >> 24) & 0xff;
311 b2 = (gpr_b[i] >> 16) & 0xff;
312 b1 = (gpr_b[i] >> 8) & 0xff;
313 b0 = gpr_b[i] & 0xff;
314
315 // immed[@bi, (b1 << 8) | b0]
316 // 11110000 0000VVVV VVVV001I IIIIII11 VVVVVVVV
317 ucode[offset++] = 0xf0;
318 ucode[offset++] = (b1 >> 4);
319 ucode[offset++] = (b1 << 4) | 0x02 | (i >> 6);
320 ucode[offset++] = (i << 2) | 0x03;
321 ucode[offset++] = b0;
322
323 // immed_w1[@bi, (b3 << 8) | b2]
324 // 11110100 0100VVVV VVVV001I IIIIII11 VVVVVVVV
325 ucode[offset++] = 0xf4;
326 ucode[offset++] = 0x40 | (b3 >> 4);
327 ucode[offset++] = (b3 << 4) | 0x02 | (i >> 6);
328 ucode[offset++] = (i << 2) | 0x03;
329 ucode[offset++] = b2;
330 }
331
332 // ctx_arb[kill]
333 ucode[offset++] = 0xe0;
334 ucode[offset++] = 0x00;
335 ucode[offset++] = 0x01;
336 ucode[offset++] = 0x00;
337 ucode[offset++] = 0x00;
338}
339
340static int set_initial_registers(int uengine, struct ixp2000_uengine_code *c)
341{
342 int per_ctx_regs;
343 u32 *gpr_a;
344 u32 *gpr_b;
345 u8 *ucode;
346 int i;
347
348 gpr_a = kmalloc(128 * sizeof(u32), GFP_KERNEL);
349 gpr_b = kmalloc(128 * sizeof(u32), GFP_KERNEL);
350 ucode = kmalloc(513 * 5, GFP_KERNEL);
351 if (gpr_a == NULL || gpr_b == NULL || ucode == NULL) {
352 kfree(ucode);
353 kfree(gpr_b);
354 kfree(gpr_a);
355 return 1;
356 }
357
358 per_ctx_regs = 16;
359 if (c->uengine_parameters & IXP2000_UENGINE_4_CONTEXTS)
360 per_ctx_regs = 32;
361
362 memset(gpr_a, 0, sizeof(gpr_a));
363 memset(gpr_b, 0, sizeof(gpr_b));
364 for (i = 0; i < 256; i++) {
365 struct ixp2000_reg_value *r = c->initial_reg_values + i;
366 u32 *bank;
367 int inc;
368 int j;
369
370 if (r->reg == -1)
371 break;
372
373 bank = (r->reg & 0x400) ? gpr_b : gpr_a;
374 inc = (r->reg & 0x80) ? 128 : per_ctx_regs;
375
376 j = r->reg & 0x7f;
377 while (j < 128) {
378 bank[j] = r->value;
379 j += inc;
380 }
381 }
382
383 generate_ucode(ucode, gpr_a, gpr_b);
384 ixp2000_uengine_load_microcode(uengine, ucode, 513);
385 ixp2000_uengine_init_context(uengine, 0, 0);
386 ixp2000_uengine_start_contexts(uengine, 0x01);
387 for (i = 0; i < 100; i++) {
388 u32 status;
389
390 status = ixp2000_uengine_csr_read(uengine, ACTIVE_CTX_STS);
391 if (!(status & 0x80000000))
392 break;
393 }
394 ixp2000_uengine_stop_contexts(uengine, 0x01);
395
396 kfree(ucode);
397 kfree(gpr_b);
398 kfree(gpr_a);
399
400 return !!(i == 100);
401}
402
403int ixp2000_uengine_load(int uengine, struct ixp2000_uengine_code *c)
404{
405 int ctx;
406
407 if (!check_ixp_type(c))
408 return 1;
409
410 if (!(ixp2000_uengine_mask & (1 << uengine)))
411 return 1;
412
413 ixp2000_uengine_reset(1 << uengine);
414 ixp2000_uengine_set_mode(uengine, c->uengine_parameters);
415 if (set_initial_registers(uengine, c))
416 return 1;
417 ixp2000_uengine_load_microcode(uengine, c->insns, c->num_insns);
418
419 for (ctx = 0; ctx < 8; ctx++)
420 ixp2000_uengine_init_context(uengine, ctx, 0);
421
422 return 0;
423}
424EXPORT_SYMBOL(ixp2000_uengine_load);
425
426
427static int __init ixp2000_uengine_init(void)
428{
429 int uengine;
430 u32 value;
431
432 /*
433 * Determine number of microengines present.
434 */
435 switch ((ixp2000_reg_read(IXP2000_PRODUCT_ID) >> 8) & 0x1fff) {
436 case 0: /* IXP2800 */
437 case 1: /* IXP2850 */
438 ixp2000_uengine_mask = 0x00ff00ff;
439 break;
440
441 case 2: /* IXP2400 */
442 ixp2000_uengine_mask = 0x000f000f;
443 break;
444
445 default:
446 printk(KERN_INFO "Detected unknown IXP2000 model (%.8x)\n",
447 (unsigned int)ixp2000_reg_read(IXP2000_PRODUCT_ID));
448 ixp2000_uengine_mask = 0x00000000;
449 break;
450 }
451
452 /*
453 * Reset microengines.
454 */
455 ixp2000_reg_write(IXP2000_RESET1, ixp2000_uengine_mask);
456 ixp2000_reg_write(IXP2000_RESET1, 0);
457
458 /*
459 * Synchronise timestamp counters across all microengines.
460 */
461 value = ixp2000_reg_read(IXP2000_MISC_CONTROL);
462 ixp2000_reg_write(IXP2000_MISC_CONTROL, value & ~0x80);
463 for (uengine = 0; uengine < 32; uengine++) {
464 if (ixp2000_uengine_mask & (1 << uengine)) {
465 ixp2000_uengine_csr_write(uengine, TIMESTAMP_LOW, 0);
466 ixp2000_uengine_csr_write(uengine, TIMESTAMP_HIGH, 0);
467 }
468 }
469 ixp2000_reg_write(IXP2000_MISC_CONTROL, value | 0x80);
470
471 return 0;
472}
473
474subsys_initcall(ixp2000_uengine_init);
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 6c396447c4e0..f3c687cf0071 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -20,6 +20,7 @@
20#include <linux/serial.h> 20#include <linux/serial.h>
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <linux/tty.h> 22#include <linux/tty.h>
23#include <linux/platform_device.h>
23#include <linux/serial_core.h> 24#include <linux/serial_core.h>
24#include <linux/bootmem.h> 25#include <linux/bootmem.h>
25#include <linux/interrupt.h> 26#include <linux/interrupt.h>
diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
index a20eabc132b0..4eb962fdb3a8 100644
--- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
+++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c
@@ -10,7 +10,7 @@
10 10
11#include <linux/tty.h> 11#include <linux/tty.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/device.h> 13#include <linux/platform_device.h>
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15 15
16#include <asm/hardware.h> 16#include <asm/hardware.h>
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index d46a70063b0c..4ee6bd8a50b8 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -21,7 +21,7 @@
21 21
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/device.h> 24#include <linux/platform_device.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/mtd/mtd.h> 26#include <linux/mtd/mtd.h>
27#include <linux/mtd/partitions.h> 27#include <linux/mtd/partitions.h>
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index 2798613696fa..fc824361430d 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -19,7 +19,7 @@
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/major.h> 20#include <linux/major.h>
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/device.h> 22#include <linux/platform_device.h>
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/mtd/mtd.h> 24#include <linux/mtd/mtd.h>
25#include <linux/mtd/partitions.h> 25#include <linux/mtd/partitions.h>
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index fd9183ff2ed5..a2eac853b2da 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -18,7 +18,7 @@
18 18
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/device.h> 21#include <linux/platform_device.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/mtd/mtd.h> 23#include <linux/mtd/mtd.h>
24#include <linux/mtd/partitions.h> 24#include <linux/mtd/partitions.h>
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c
index d904e643f5ec..c851c2e4dfcb 100644
--- a/arch/arm/mach-omap1/board-netstar.c
+++ b/arch/arm/mach-omap1/board-netstar.c
@@ -11,7 +11,7 @@
11 */ 11 */
12 12
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/device.h> 14#include <linux/platform_device.h>
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 21103df50415..a88524e7c315 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -28,7 +28,7 @@
28 28
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/device.h> 31#include <linux/platform_device.h>
32#include <linux/interrupt.h> 32#include <linux/interrupt.h>
33 33
34#include <linux/mtd/mtd.h> 34#include <linux/mtd/mtd.h>
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index 2ba26e239108..354b157acb3a 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -13,7 +13,7 @@
13 13
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/device.h> 16#include <linux/platform_device.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/mtd/mtd.h> 18#include <linux/mtd/mtd.h>
19#include <linux/mtd/partitions.h> 19#include <linux/mtd/partitions.h>
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index bf30b1acda0b..3f018b296861 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -13,7 +13,7 @@
13 */ 13 */
14 14
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/device.h> 16#include <linux/platform_device.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/kernel.h> 19#include <linux/kernel.h>
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index e8b3981444cd..3c5d901efeaa 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -13,7 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/device.h> 16#include <linux/platform_device.h>
17 17
18#include <asm/hardware.h> 18#include <asm/hardware.h>
19#include <asm/io.h> 19#include <asm/io.h>
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 656f73bbcb5a..eb5f6d744a4a 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -14,7 +14,7 @@
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/device.h> 17#include <linux/platform_device.h>
18#include <linux/major.h> 18#include <linux/major.h>
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c
index 370df113dc06..54162ba95414 100644
--- a/arch/arm/mach-pxa/corgi_lcd.c
+++ b/arch/arm/mach-pxa/corgi_lcd.c
@@ -17,7 +17,7 @@
17 17
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/device.h> 20#include <linux/platform_device.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <asm/arch/akita.h> 22#include <asm/arch/akita.h>
23#include <asm/arch/corgi.h> 23#include <asm/arch/corgi.h>
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index 136c269db0b7..591e5f32dbec 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -15,7 +15,7 @@
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/device.h> 18#include <linux/platform_device.h>
19#include <asm/hardware.h> 19#include <asm/hardware.h>
20#include <asm/mach-types.h> 20#include <asm/mach-types.h>
21 21
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 9c0289333301..9b48a90aefce 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -20,7 +20,7 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/device.h> 23#include <linux/platform_device.h>
24#include <linux/ioport.h> 24#include <linux/ioport.h>
25#include <linux/pm.h> 25#include <linux/pm.h>
26#include <linux/string.h> 26#include <linux/string.h>
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 01a83ab09ac3..7de159e2ab42 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -18,7 +18,7 @@
18 18
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/device.h> 21#include <linux/platform_device.h>
22#include <linux/fb.h> 22#include <linux/fb.h>
23 23
24#include <asm/setup.h> 24#include <asm/setup.h>
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index beccf455f796..9c6e77faec5b 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -14,7 +14,7 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/device.h> 17#include <linux/platform_device.h>
18#include <linux/sysdev.h> 18#include <linux/sysdev.h>
19#include <linux/major.h> 19#include <linux/major.h>
20#include <linux/fb.h> 20#include <linux/fb.h>
@@ -175,7 +175,7 @@ static struct platform_device sa1111_device = {
175static struct resource smc91x_resources[] = { 175static struct resource smc91x_resources[] = {
176 [0] = { 176 [0] = {
177 .name = "smc91x-regs", 177 .name = "smc91x-regs",
178 .start = 0x0c000000, 178 .start = 0x0c000c00,
179 .end = 0x0c0fffff, 179 .end = 0x0c0fffff,
180 .flags = IORESOURCE_MEM, 180 .flags = IORESOURCE_MEM,
181 }, 181 },
@@ -224,18 +224,75 @@ static struct pxafb_mach_info sharp_lm8v31 __initdata = {
224 .lccr3 = LCCR3_PCP | LCCR3_Acb(255), 224 .lccr3 = LCCR3_PCP | LCCR3_Acb(255),
225}; 225};
226 226
227static int lubbock_mci_init(struct device *dev, irqreturn_t (*lubbock_detect_int)(int, void *, struct pt_regs *), void *data) 227#define MMC_POLL_RATE msecs_to_jiffies(1000)
228
229static void lubbock_mmc_poll(unsigned long);
230static irqreturn_t (*mmc_detect_int)(int, void *, struct pt_regs *);
231
232static struct timer_list mmc_timer = {
233 .function = lubbock_mmc_poll,
234};
235
236static void lubbock_mmc_poll(unsigned long data)
237{
238 unsigned long flags;
239
240 /* clear any previous irq state, then ... */
241 local_irq_save(flags);
242 LUB_IRQ_SET_CLR &= ~(1 << 0);
243 local_irq_restore(flags);
244
245 /* poll until mmc/sd card is removed */
246 if (LUB_IRQ_SET_CLR & (1 << 0))
247 mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
248 else {
249 (void) mmc_detect_int(LUBBOCK_SD_IRQ, (void *)data, NULL);
250 enable_irq(LUBBOCK_SD_IRQ);
251 }
252}
253
254static irqreturn_t lubbock_detect_int(int irq, void *data, struct pt_regs *regs)
255{
256 /* IRQ is level triggered; disable, and poll for removal */
257 disable_irq(irq);
258 mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
259
260 return mmc_detect_int(irq, data, regs);
261}
262
263static int lubbock_mci_init(struct device *dev,
264 irqreturn_t (*detect_int)(int, void *, struct pt_regs *),
265 void *data)
228{ 266{
229 /* setup GPIO for PXA25x MMC controller */ 267 /* setup GPIO for PXA25x MMC controller */
230 pxa_gpio_mode(GPIO6_MMCCLK_MD); 268 pxa_gpio_mode(GPIO6_MMCCLK_MD);
231 pxa_gpio_mode(GPIO8_MMCCS0_MD); 269 pxa_gpio_mode(GPIO8_MMCCS0_MD);
232 270
233 return 0; 271 /* detect card insert/eject */
272 mmc_detect_int = detect_int;
273 init_timer(&mmc_timer);
274 mmc_timer.data = (unsigned long) data;
275 return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int,
276 SA_SAMPLE_RANDOM, "lubbock-sd-detect", data);
277}
278
279static int lubbock_mci_get_ro(struct device *dev)
280{
281 return (LUB_MISC_RD & (1 << 2)) != 0;
282}
283
284static void lubbock_mci_exit(struct device *dev, void *data)
285{
286 free_irq(LUBBOCK_SD_IRQ, data);
287 del_timer_sync(&mmc_timer);
234} 288}
235 289
236static struct pxamci_platform_data lubbock_mci_platform_data = { 290static struct pxamci_platform_data lubbock_mci_platform_data = {
237 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 291 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
292 .detect_delay = 1,
238 .init = lubbock_mci_init, 293 .init = lubbock_mci_init,
294 .get_ro = lubbock_mci_get_ro,
295 .exit = lubbock_mci_exit,
239}; 296};
240 297
241static void lubbock_irda_transceiver_mode(struct device *dev, int mode) 298static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index a48c64026e1f..887a8cb7b721 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/device.h> 17#include <linux/platform_device.h>
18#include <linux/sysdev.h> 18#include <linux/sysdev.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/sched.h> 20#include <linux/sched.h>
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 6d413f6701a7..ad6a13f95a62 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -16,7 +16,7 @@
16 */ 16 */
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/device.h> 19#include <linux/platform_device.h>
20#include <linux/fb.h> 20#include <linux/fb.h>
21 21
22#include <asm/hardware.h> 22#include <asm/hardware.h>
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 09a5d593f04b..c722a9a91fcc 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -16,7 +16,7 @@
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/device.h> 19#include <linux/platform_device.h>
20 20
21#include <asm/hardware.h> 21#include <asm/hardware.h>
22#include <asm/irq.h> 22#include <asm/irq.h>
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index b838842b6a20..6c6878cd2207 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -14,7 +14,7 @@
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/device.h> 17#include <linux/platform_device.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/major.h> 19#include <linux/major.h>
20#include <linux/fs.h> 20#include <linux/fs.h>
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
new file mode 100644
index 000000000000..4b63dc9eabfe
--- /dev/null
+++ b/arch/arm/mach-realview/Kconfig
@@ -0,0 +1,11 @@
1menu "RealView platform type"
2 depends on ARCH_REALVIEW
3
4config MACH_REALVIEW_EB
5 bool "Support RealView/EB platform"
6 default n
7 select ARM_GIC
8 help
9 Include support for the ARM(R) RealView Emulation Baseboard platform.
10
11endmenu
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile
new file mode 100644
index 000000000000..8d37ea1605fd
--- /dev/null
+++ b/arch/arm/mach-realview/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the linux kernel.
3#
4
5obj-y := core.o clock.o
6obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o
diff --git a/arch/arm/mach-realview/Makefile.boot b/arch/arm/mach-realview/Makefile.boot
new file mode 100644
index 000000000000..c7e75acfe6c9
--- /dev/null
+++ b/arch/arm/mach-realview/Makefile.boot
@@ -0,0 +1,4 @@
1 zreladdr-y := 0x00008000
2params_phys-y := 0x00000100
3initrd_phys-y := 0x00800000
4
diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c
new file mode 100644
index 000000000000..002635c97bb6
--- /dev/null
+++ b/arch/arm/mach-realview/clock.c
@@ -0,0 +1,145 @@
1/*
2 * linux/arch/arm/mach-realview/clock.c
3 *
4 * Copyright (C) 2004 ARM Limited.
5 * Written by Deep Blue Solutions Limited.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/module.h>
12#include <linux/kernel.h>
13#include <linux/list.h>
14#include <linux/errno.h>
15#include <linux/err.h>
16
17#include <asm/semaphore.h>
18#include <asm/hardware/clock.h>
19#include <asm/hardware/icst307.h>
20
21#include "clock.h"
22
23static LIST_HEAD(clocks);
24static DECLARE_MUTEX(clocks_sem);
25
26struct clk *clk_get(struct device *dev, const char *id)
27{
28 struct clk *p, *clk = ERR_PTR(-ENOENT);
29
30 down(&clocks_sem);
31 list_for_each_entry(p, &clocks, node) {
32 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
33 clk = p;
34 break;
35 }
36 }
37 up(&clocks_sem);
38
39 return clk;
40}
41EXPORT_SYMBOL(clk_get);
42
43void clk_put(struct clk *clk)
44{
45 module_put(clk->owner);
46}
47EXPORT_SYMBOL(clk_put);
48
49int clk_enable(struct clk *clk)
50{
51 return 0;
52}
53EXPORT_SYMBOL(clk_enable);
54
55void clk_disable(struct clk *clk)
56{
57}
58EXPORT_SYMBOL(clk_disable);
59
60int clk_use(struct clk *clk)
61{
62 return 0;
63}
64EXPORT_SYMBOL(clk_use);
65
66void clk_unuse(struct clk *clk)
67{
68}
69EXPORT_SYMBOL(clk_unuse);
70
71unsigned long clk_get_rate(struct clk *clk)
72{
73 return clk->rate;
74}
75EXPORT_SYMBOL(clk_get_rate);
76
77long clk_round_rate(struct clk *clk, unsigned long rate)
78{
79 return rate;
80}
81EXPORT_SYMBOL(clk_round_rate);
82
83int clk_set_rate(struct clk *clk, unsigned long rate)
84{
85 int ret = -EIO;
86
87 if (clk->setvco) {
88 struct icst307_vco vco;
89
90 vco = icst307_khz_to_vco(clk->params, rate / 1000);
91 clk->rate = icst307_khz(clk->params, vco) * 1000;
92
93 printk("Clock %s: setting VCO reg params: S=%d R=%d V=%d\n",
94 clk->name, vco.s, vco.r, vco.v);
95
96 clk->setvco(clk, vco);
97 ret = 0;
98 }
99 return ret;
100}
101EXPORT_SYMBOL(clk_set_rate);
102
103/*
104 * These are fixed clocks.
105 */
106static struct clk kmi_clk = {
107 .name = "KMIREFCLK",
108 .rate = 24000000,
109};
110
111static struct clk uart_clk = {
112 .name = "UARTCLK",
113 .rate = 24000000,
114};
115
116static struct clk mmci_clk = {
117 .name = "MCLK",
118 .rate = 33000000,
119};
120
121int clk_register(struct clk *clk)
122{
123 down(&clocks_sem);
124 list_add(&clk->node, &clocks);
125 up(&clocks_sem);
126 return 0;
127}
128EXPORT_SYMBOL(clk_register);
129
130void clk_unregister(struct clk *clk)
131{
132 down(&clocks_sem);
133 list_del(&clk->node);
134 up(&clocks_sem);
135}
136EXPORT_SYMBOL(clk_unregister);
137
138static int __init clk_init(void)
139{
140 clk_register(&kmi_clk);
141 clk_register(&uart_clk);
142 clk_register(&mmci_clk);
143 return 0;
144}
145arch_initcall(clk_init);
diff --git a/arch/arm/mach-realview/clock.h b/arch/arm/mach-realview/clock.h
new file mode 100644
index 000000000000..dadba695e181
--- /dev/null
+++ b/arch/arm/mach-realview/clock.h
@@ -0,0 +1,25 @@
1/*
2 * linux/arch/arm/mach-realview/clock.h
3 *
4 * Copyright (C) 2004 ARM Limited.
5 * Written by Deep Blue Solutions Limited.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11struct module;
12struct icst307_params;
13
14struct clk {
15 struct list_head node;
16 unsigned long rate;
17 struct module *owner;
18 const char *name;
19 const struct icst307_params *params;
20 void *data;
21 void (*setvco)(struct clk *, struct icst307_vco vco);
22};
23
24int clk_register(struct clk *clk);
25void clk_unregister(struct clk *clk);
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
new file mode 100644
index 000000000000..482eb512ebe8
--- /dev/null
+++ b/arch/arm/mach-realview/core.c
@@ -0,0 +1,605 @@
1/*
2 * linux/arch/arm/mach-realview/core.c
3 *
4 * Copyright (C) 1999 - 2003 ARM Limited
5 * Copyright (C) 2000 Deep Blue Solutions Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#include <linux/config.h>
22#include <linux/init.h>
23#include <linux/platform_device.h>
24#include <linux/dma-mapping.h>
25#include <linux/sysdev.h>
26#include <linux/interrupt.h>
27
28#include <asm/system.h>
29#include <asm/hardware.h>
30#include <asm/io.h>
31#include <asm/irq.h>
32#include <asm/leds.h>
33#include <asm/mach-types.h>
34#include <asm/hardware/amba.h>
35#include <asm/hardware/amba_clcd.h>
36#include <asm/hardware/arm_timer.h>
37#include <asm/hardware/icst307.h>
38
39#include <asm/mach/arch.h>
40#include <asm/mach/flash.h>
41#include <asm/mach/irq.h>
42#include <asm/mach/time.h>
43#include <asm/mach/map.h>
44#include <asm/mach/mmc.h>
45
46#include <asm/hardware/gic.h>
47
48#include "core.h"
49#include "clock.h"
50
51#define REALVIEW_REFCOUNTER (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_24MHz_OFFSET)
52
53/*
54 * This is the RealView sched_clock implementation. This has
55 * a resolution of 41.7ns, and a maximum value of about 179s.
56 */
57unsigned long long sched_clock(void)
58{
59 unsigned long long v;
60
61 v = (unsigned long long)readl(REALVIEW_REFCOUNTER) * 125;
62 do_div(v, 3);
63
64 return v;
65}
66
67
68#define REALVIEW_FLASHCTRL (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_FLASH_OFFSET)
69
70static int realview_flash_init(void)
71{
72 u32 val;
73
74 val = __raw_readl(REALVIEW_FLASHCTRL);
75 val &= ~REALVIEW_FLASHPROG_FLVPPEN;
76 __raw_writel(val, REALVIEW_FLASHCTRL);
77
78 return 0;
79}
80
81static void realview_flash_exit(void)
82{
83 u32 val;
84
85 val = __raw_readl(REALVIEW_FLASHCTRL);
86 val &= ~REALVIEW_FLASHPROG_FLVPPEN;
87 __raw_writel(val, REALVIEW_FLASHCTRL);
88}
89
90static void realview_flash_set_vpp(int on)
91{
92 u32 val;
93
94 val = __raw_readl(REALVIEW_FLASHCTRL);
95 if (on)
96 val |= REALVIEW_FLASHPROG_FLVPPEN;
97 else
98 val &= ~REALVIEW_FLASHPROG_FLVPPEN;
99 __raw_writel(val, REALVIEW_FLASHCTRL);
100}
101
102static struct flash_platform_data realview_flash_data = {
103 .map_name = "cfi_probe",
104 .width = 4,
105 .init = realview_flash_init,
106 .exit = realview_flash_exit,
107 .set_vpp = realview_flash_set_vpp,
108};
109
110static struct resource realview_flash_resource = {
111 .start = REALVIEW_FLASH_BASE,
112 .end = REALVIEW_FLASH_BASE + REALVIEW_FLASH_SIZE,
113 .flags = IORESOURCE_MEM,
114};
115
116struct platform_device realview_flash_device = {
117 .name = "armflash",
118 .id = 0,
119 .dev = {
120 .platform_data = &realview_flash_data,
121 },
122 .num_resources = 1,
123 .resource = &realview_flash_resource,
124};
125
126static struct resource realview_smc91x_resources[] = {
127 [0] = {
128 .start = REALVIEW_ETH_BASE,
129 .end = REALVIEW_ETH_BASE + SZ_64K - 1,
130 .flags = IORESOURCE_MEM,
131 },
132 [1] = {
133 .start = IRQ_ETH,
134 .end = IRQ_ETH,
135 .flags = IORESOURCE_IRQ,
136 },
137};
138
139struct platform_device realview_smc91x_device = {
140 .name = "smc91x",
141 .id = 0,
142 .num_resources = ARRAY_SIZE(realview_smc91x_resources),
143 .resource = realview_smc91x_resources,
144};
145
146#define REALVIEW_SYSMCI (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET)
147
148static unsigned int realview_mmc_status(struct device *dev)
149{
150 struct amba_device *adev = container_of(dev, struct amba_device, dev);
151 u32 mask;
152
153 if (adev->res.start == REALVIEW_MMCI0_BASE)
154 mask = 1;
155 else
156 mask = 2;
157
158 return readl(REALVIEW_SYSMCI) & mask;
159}
160
161struct mmc_platform_data realview_mmc0_plat_data = {
162 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
163 .status = realview_mmc_status,
164};
165
166struct mmc_platform_data realview_mmc1_plat_data = {
167 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
168 .status = realview_mmc_status,
169};
170
171/*
172 * Clock handling
173 */
174static const struct icst307_params realview_oscvco_params = {
175 .ref = 24000,
176 .vco_max = 200000,
177 .vd_min = 4 + 8,
178 .vd_max = 511 + 8,
179 .rd_min = 1 + 2,
180 .rd_max = 127 + 2,
181};
182
183static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco)
184{
185 void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET;
186 void __iomem *sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC1_OFFSET;
187 u32 val;
188
189 val = readl(sys_osc) & ~0x7ffff;
190 val |= vco.v | (vco.r << 9) | (vco.s << 16);
191
192 writel(0xa05f, sys_lock);
193 writel(val, sys_osc);
194 writel(0, sys_lock);
195}
196
197struct clk realview_clcd_clk = {
198 .name = "CLCDCLK",
199 .params = &realview_oscvco_params,
200 .setvco = realview_oscvco_set,
201};
202
203/*
204 * CLCD support.
205 */
206#define SYS_CLCD_MODE_MASK (3 << 0)
207#define SYS_CLCD_MODE_888 (0 << 0)
208#define SYS_CLCD_MODE_5551 (1 << 0)
209#define SYS_CLCD_MODE_565_RLSB (2 << 0)
210#define SYS_CLCD_MODE_565_BLSB (3 << 0)
211#define SYS_CLCD_NLCDIOON (1 << 2)
212#define SYS_CLCD_VDDPOSSWITCH (1 << 3)
213#define SYS_CLCD_PWR3V5SWITCH (1 << 4)
214#define SYS_CLCD_ID_MASK (0x1f << 8)
215#define SYS_CLCD_ID_SANYO_3_8 (0x00 << 8)
216#define SYS_CLCD_ID_UNKNOWN_8_4 (0x01 << 8)
217#define SYS_CLCD_ID_EPSON_2_2 (0x02 << 8)
218#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8)
219#define SYS_CLCD_ID_VGA (0x1f << 8)
220
221static struct clcd_panel vga = {
222 .mode = {
223 .name = "VGA",
224 .refresh = 60,
225 .xres = 640,
226 .yres = 480,
227 .pixclock = 39721,
228 .left_margin = 40,
229 .right_margin = 24,
230 .upper_margin = 32,
231 .lower_margin = 11,
232 .hsync_len = 96,
233 .vsync_len = 2,
234 .sync = 0,
235 .vmode = FB_VMODE_NONINTERLACED,
236 },
237 .width = -1,
238 .height = -1,
239 .tim2 = TIM2_BCD | TIM2_IPC,
240 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
241 .bpp = 16,
242};
243
244static struct clcd_panel sanyo_3_8_in = {
245 .mode = {
246 .name = "Sanyo QVGA",
247 .refresh = 116,
248 .xres = 320,
249 .yres = 240,
250 .pixclock = 100000,
251 .left_margin = 6,
252 .right_margin = 6,
253 .upper_margin = 5,
254 .lower_margin = 5,
255 .hsync_len = 6,
256 .vsync_len = 6,
257 .sync = 0,
258 .vmode = FB_VMODE_NONINTERLACED,
259 },
260 .width = -1,
261 .height = -1,
262 .tim2 = TIM2_BCD,
263 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
264 .bpp = 16,
265};
266
267static struct clcd_panel sanyo_2_5_in = {
268 .mode = {
269 .name = "Sanyo QVGA Portrait",
270 .refresh = 116,
271 .xres = 240,
272 .yres = 320,
273 .pixclock = 100000,
274 .left_margin = 20,
275 .right_margin = 10,
276 .upper_margin = 2,
277 .lower_margin = 2,
278 .hsync_len = 10,
279 .vsync_len = 2,
280 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
281 .vmode = FB_VMODE_NONINTERLACED,
282 },
283 .width = -1,
284 .height = -1,
285 .tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC,
286 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
287 .bpp = 16,
288};
289
290static struct clcd_panel epson_2_2_in = {
291 .mode = {
292 .name = "Epson QCIF",
293 .refresh = 390,
294 .xres = 176,
295 .yres = 220,
296 .pixclock = 62500,
297 .left_margin = 3,
298 .right_margin = 2,
299 .upper_margin = 1,
300 .lower_margin = 0,
301 .hsync_len = 3,
302 .vsync_len = 2,
303 .sync = 0,
304 .vmode = FB_VMODE_NONINTERLACED,
305 },
306 .width = -1,
307 .height = -1,
308 .tim2 = TIM2_BCD | TIM2_IPC,
309 .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
310 .bpp = 16,
311};
312
313/*
314 * Detect which LCD panel is connected, and return the appropriate
315 * clcd_panel structure. Note: we do not have any information on
316 * the required timings for the 8.4in panel, so we presently assume
317 * VGA timings.
318 */
319static struct clcd_panel *realview_clcd_panel(void)
320{
321 void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
322 struct clcd_panel *panel = &vga;
323 u32 val;
324
325 val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
326 if (val == SYS_CLCD_ID_SANYO_3_8)
327 panel = &sanyo_3_8_in;
328 else if (val == SYS_CLCD_ID_SANYO_2_5)
329 panel = &sanyo_2_5_in;
330 else if (val == SYS_CLCD_ID_EPSON_2_2)
331 panel = &epson_2_2_in;
332 else if (val == SYS_CLCD_ID_VGA)
333 panel = &vga;
334 else {
335 printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
336 val);
337 panel = &vga;
338 }
339
340 return panel;
341}
342
343/*
344 * Disable all display connectors on the interface module.
345 */
346static void realview_clcd_disable(struct clcd_fb *fb)
347{
348 void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
349 u32 val;
350
351 val = readl(sys_clcd);
352 val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
353 writel(val, sys_clcd);
354}
355
356/*
357 * Enable the relevant connector on the interface module.
358 */
359static void realview_clcd_enable(struct clcd_fb *fb)
360{
361 void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
362 u32 val;
363
364 val = readl(sys_clcd);
365 val &= ~SYS_CLCD_MODE_MASK;
366
367 switch (fb->fb.var.green.length) {
368 case 5:
369 val |= SYS_CLCD_MODE_5551;
370 break;
371 case 6:
372 val |= SYS_CLCD_MODE_565_RLSB;
373 break;
374 case 8:
375 val |= SYS_CLCD_MODE_888;
376 break;
377 }
378
379 /*
380 * Set the MUX
381 */
382 writel(val, sys_clcd);
383
384 /*
385 * And now enable the PSUs
386 */
387 val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
388 writel(val, sys_clcd);
389}
390
391static unsigned long framesize = SZ_1M;
392
393static int realview_clcd_setup(struct clcd_fb *fb)
394{
395 dma_addr_t dma;
396
397 fb->panel = realview_clcd_panel();
398
399 fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
400 &dma, GFP_KERNEL);
401 if (!fb->fb.screen_base) {
402 printk(KERN_ERR "CLCD: unable to map framebuffer\n");
403 return -ENOMEM;
404 }
405
406 fb->fb.fix.smem_start = dma;
407 fb->fb.fix.smem_len = framesize;
408
409 return 0;
410}
411
412static int realview_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
413{
414 return dma_mmap_writecombine(&fb->dev->dev, vma,
415 fb->fb.screen_base,
416 fb->fb.fix.smem_start,
417 fb->fb.fix.smem_len);
418}
419
420static void realview_clcd_remove(struct clcd_fb *fb)
421{
422 dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
423 fb->fb.screen_base, fb->fb.fix.smem_start);
424}
425
426struct clcd_board clcd_plat_data = {
427 .name = "RealView",
428 .check = clcdfb_check,
429 .decode = clcdfb_decode,
430 .disable = realview_clcd_disable,
431 .enable = realview_clcd_enable,
432 .setup = realview_clcd_setup,
433 .mmap = realview_clcd_mmap,
434 .remove = realview_clcd_remove,
435};
436
437#ifdef CONFIG_LEDS
438#define VA_LEDS_BASE (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET)
439
440void realview_leds_event(led_event_t ledevt)
441{
442 unsigned long flags;
443 u32 val;
444
445 local_irq_save(flags);
446 val = readl(VA_LEDS_BASE);
447
448 switch (ledevt) {
449 case led_idle_start:
450 val = val & ~REALVIEW_SYS_LED0;
451 break;
452
453 case led_idle_end:
454 val = val | REALVIEW_SYS_LED0;
455 break;
456
457 case led_timer:
458 val = val ^ REALVIEW_SYS_LED1;
459 break;
460
461 case led_halted:
462 val = 0;
463 break;
464
465 default:
466 break;
467 }
468
469 writel(val, VA_LEDS_BASE);
470 local_irq_restore(flags);
471}
472#endif /* CONFIG_LEDS */
473
474/*
475 * Where is the timer (VA)?
476 */
477#define TIMER0_VA_BASE __io_address(REALVIEW_TIMER0_1_BASE)
478#define TIMER1_VA_BASE (__io_address(REALVIEW_TIMER0_1_BASE) + 0x20)
479#define TIMER2_VA_BASE __io_address(REALVIEW_TIMER2_3_BASE)
480#define TIMER3_VA_BASE (__io_address(REALVIEW_TIMER2_3_BASE) + 0x20)
481
482/*
483 * How long is the timer interval?
484 */
485#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
486#if TIMER_INTERVAL >= 0x100000
487#define TIMER_RELOAD (TIMER_INTERVAL >> 8)
488#define TIMER_DIVISOR (TIMER_CTRL_DIV256)
489#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
490#elif TIMER_INTERVAL >= 0x10000
491#define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */
492#define TIMER_DIVISOR (TIMER_CTRL_DIV16)
493#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
494#else
495#define TIMER_RELOAD (TIMER_INTERVAL)
496#define TIMER_DIVISOR (TIMER_CTRL_DIV1)
497#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
498#endif
499
500/*
501 * Returns number of ms since last clock interrupt. Note that interrupts
502 * will have been disabled by do_gettimeoffset()
503 */
504static unsigned long realview_gettimeoffset(void)
505{
506 unsigned long ticks1, ticks2, status;
507
508 /*
509 * Get the current number of ticks. Note that there is a race
510 * condition between us reading the timer and checking for
511 * an interrupt. We get around this by ensuring that the
512 * counter has not reloaded between our two reads.
513 */
514 ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
515 do {
516 ticks1 = ticks2;
517 status = __raw_readl(__io_address(REALVIEW_GIC_DIST_BASE + GIC_DIST_PENDING_SET)
518 + ((IRQ_TIMERINT0_1 >> 5) << 2));
519 ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
520 } while (ticks2 > ticks1);
521
522 /*
523 * Number of ticks since last interrupt.
524 */
525 ticks1 = TIMER_RELOAD - ticks2;
526
527 /*
528 * Interrupt pending? If so, we've reloaded once already.
529 *
530 * FIXME: Need to check this is effectively timer 0 that expires
531 */
532 if (status & IRQMASK_TIMERINT0_1)
533 ticks1 += TIMER_RELOAD;
534
535 /*
536 * Convert the ticks to usecs
537 */
538 return TICKS2USECS(ticks1);
539}
540
541/*
542 * IRQ handler for the timer
543 */
544static irqreturn_t realview_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
545{
546 write_seqlock(&xtime_lock);
547
548 // ...clear the interrupt
549 writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
550
551 timer_tick(regs);
552
553 write_sequnlock(&xtime_lock);
554
555 return IRQ_HANDLED;
556}
557
558static struct irqaction realview_timer_irq = {
559 .name = "RealView Timer Tick",
560 .flags = SA_INTERRUPT | SA_TIMER,
561 .handler = realview_timer_interrupt,
562};
563
564/*
565 * Set up timer interrupt, and return the current time in seconds.
566 */
567static void __init realview_timer_init(void)
568{
569 u32 val;
570
571 /*
572 * set clock frequency:
573 * REALVIEW_REFCLK is 32KHz
574 * REALVIEW_TIMCLK is 1MHz
575 */
576 val = readl(__io_address(REALVIEW_SCTL_BASE));
577 writel((REALVIEW_TIMCLK << REALVIEW_TIMER1_EnSel) |
578 (REALVIEW_TIMCLK << REALVIEW_TIMER2_EnSel) |
579 (REALVIEW_TIMCLK << REALVIEW_TIMER3_EnSel) |
580 (REALVIEW_TIMCLK << REALVIEW_TIMER4_EnSel) | val,
581 __io_address(REALVIEW_SCTL_BASE));
582
583 /*
584 * Initialise to a known state (all timers off)
585 */
586 writel(0, TIMER0_VA_BASE + TIMER_CTRL);
587 writel(0, TIMER1_VA_BASE + TIMER_CTRL);
588 writel(0, TIMER2_VA_BASE + TIMER_CTRL);
589 writel(0, TIMER3_VA_BASE + TIMER_CTRL);
590
591 writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
592 writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE);
593 writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC |
594 TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL);
595
596 /*
597 * Make irqs happen for the system timer
598 */
599 setup_irq(IRQ_TIMERINT0_1, &realview_timer_irq);
600}
601
602struct sys_timer realview_timer = {
603 .init = realview_timer_init,
604 .offset = realview_gettimeoffset,
605};
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
new file mode 100644
index 000000000000..575599db74db
--- /dev/null
+++ b/arch/arm/mach-realview/core.h
@@ -0,0 +1,118 @@
1/*
2 * linux/arch/arm/mach-realview/core.h
3 *
4 * Copyright (C) 2004 ARM Limited
5 * Copyright (C) 2000 Deep Blue Solutions Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#ifndef __ASM_ARCH_REALVIEW_H
23#define __ASM_ARCH_REALVIEW_H
24
25#include <asm/hardware/amba.h>
26#include <asm/io.h>
27
28#define __io_address(n) __io(IO_ADDRESS(n))
29
30extern struct sys_timer realview_timer;
31
32#define AMBA_DEVICE(name,busid,base,plat) \
33static struct amba_device name##_device = { \
34 .dev = { \
35 .coherent_dma_mask = ~0, \
36 .bus_id = busid, \
37 .platform_data = plat, \
38 }, \
39 .res = { \
40 .start = REALVIEW_##base##_BASE, \
41 .end = (REALVIEW_##base##_BASE) + SZ_4K - 1,\
42 .flags = IORESOURCE_MEM, \
43 }, \
44 .dma_mask = ~0, \
45 .irq = base##_IRQ, \
46 /* .dma = base##_DMA,*/ \
47}
48
49/*
50 * These devices are connected via the core APB bridge
51 */
52#define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ }
53#define GPIO2_DMA { 0, 0 }
54#define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ }
55#define GPIO3_DMA { 0, 0 }
56
57#define AACI_IRQ { IRQ_AACI, NO_IRQ }
58#define AACI_DMA { 0x80, 0x81 }
59#define MMCI0_IRQ { IRQ_MMCI0A,IRQ_MMCI0B }
60#define MMCI0_DMA { 0x84, 0 }
61#define KMI0_IRQ { IRQ_KMI0, NO_IRQ }
62#define KMI0_DMA { 0, 0 }
63#define KMI1_IRQ { IRQ_KMI1, NO_IRQ }
64#define KMI1_DMA { 0, 0 }
65
66/*
67 * These devices are connected directly to the multi-layer AHB switch
68 */
69#define SMC_IRQ { NO_IRQ, NO_IRQ }
70#define SMC_DMA { 0, 0 }
71#define MPMC_IRQ { NO_IRQ, NO_IRQ }
72#define MPMC_DMA { 0, 0 }
73#define CLCD_IRQ { IRQ_CLCDINT, NO_IRQ }
74#define CLCD_DMA { 0, 0 }
75#define DMAC_IRQ { IRQ_DMAINT, NO_IRQ }
76#define DMAC_DMA { 0, 0 }
77
78/*
79 * These devices are connected via the core APB bridge
80 */
81#define SCTL_IRQ { NO_IRQ, NO_IRQ }
82#define SCTL_DMA { 0, 0 }
83#define WATCHDOG_IRQ { IRQ_WDOGINT, NO_IRQ }
84#define WATCHDOG_DMA { 0, 0 }
85#define GPIO0_IRQ { IRQ_GPIOINT0, NO_IRQ }
86#define GPIO0_DMA { 0, 0 }
87#define GPIO1_IRQ { IRQ_GPIOINT1, NO_IRQ }
88#define GPIO1_DMA { 0, 0 }
89#define RTC_IRQ { IRQ_RTCINT, NO_IRQ }
90#define RTC_DMA { 0, 0 }
91
92/*
93 * These devices are connected via the DMA APB bridge
94 */
95#define SCI_IRQ { IRQ_SCIINT, NO_IRQ }
96#define SCI_DMA { 7, 6 }
97#define UART0_IRQ { IRQ_UARTINT0, NO_IRQ }
98#define UART0_DMA { 15, 14 }
99#define UART1_IRQ { IRQ_UARTINT1, NO_IRQ }
100#define UART1_DMA { 13, 12 }
101#define UART2_IRQ { IRQ_UARTINT2, NO_IRQ }
102#define UART2_DMA { 11, 10 }
103#define UART3_IRQ { IRQ_UART3, NO_IRQ }
104#define UART3_DMA { 0x86, 0x87 }
105#define SSP_IRQ { IRQ_SSPINT, NO_IRQ }
106#define SSP_DMA { 9, 8 }
107
108
109extern struct platform_device realview_flash_device;
110extern struct platform_device realview_smc91x_device;
111extern struct mmc_platform_data realview_mmc0_plat_data;
112extern struct mmc_platform_data realview_mmc1_plat_data;
113extern struct clk realview_clcd_clk;
114extern struct clcd_board clcd_plat_data;
115
116extern void realview_leds_event(led_event_t ledevt);
117
118#endif
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
new file mode 100644
index 000000000000..01b264be5029
--- /dev/null
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -0,0 +1,142 @@
1/*
2 * linux/arch/arm/mach-realview/realview_eb.c
3 *
4 * Copyright (C) 2004 ARM Limited
5 * Copyright (C) 2000 Deep Blue Solutions Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/config.h>
23#include <linux/init.h>
24#include <linux/platform_device.h>
25#include <linux/sysdev.h>
26
27#include <asm/hardware.h>
28#include <asm/io.h>
29#include <asm/irq.h>
30#include <asm/leds.h>
31#include <asm/mach-types.h>
32#include <asm/hardware/gic.h>
33#include <asm/hardware/amba.h>
34#include <asm/hardware/icst307.h>
35
36#include <asm/mach/arch.h>
37#include <asm/mach/map.h>
38#include <asm/mach/mmc.h>
39
40#include <asm/arch/irqs.h>
41
42#include "core.h"
43#include "clock.h"
44
45static struct map_desc realview_eb_io_desc[] __initdata = {
46 { IO_ADDRESS(REALVIEW_SYS_BASE), REALVIEW_SYS_BASE, SZ_4K, MT_DEVICE },
47 { IO_ADDRESS(REALVIEW_GIC_CPU_BASE), REALVIEW_GIC_CPU_BASE, SZ_4K, MT_DEVICE },
48 { IO_ADDRESS(REALVIEW_GIC_DIST_BASE), REALVIEW_GIC_DIST_BASE, SZ_4K, MT_DEVICE },
49 { IO_ADDRESS(REALVIEW_SCTL_BASE), REALVIEW_SCTL_BASE, SZ_4K, MT_DEVICE },
50 { IO_ADDRESS(REALVIEW_TIMER0_1_BASE), REALVIEW_TIMER0_1_BASE, SZ_4K, MT_DEVICE },
51 { IO_ADDRESS(REALVIEW_TIMER2_3_BASE), REALVIEW_TIMER2_3_BASE, SZ_4K, MT_DEVICE },
52#ifdef CONFIG_DEBUG_LL
53 { IO_ADDRESS(REALVIEW_UART0_BASE), REALVIEW_UART0_BASE, SZ_4K, MT_DEVICE },
54#endif
55};
56
57static void __init realview_eb_map_io(void)
58{
59 iotable_init(realview_eb_io_desc, ARRAY_SIZE(realview_eb_io_desc));
60}
61
62/* FPGA Primecells */
63AMBA_DEVICE(aaci, "fpga:04", AACI, NULL);
64AMBA_DEVICE(mmc0, "fpga:05", MMCI0, &realview_mmc0_plat_data);
65AMBA_DEVICE(kmi0, "fpga:06", KMI0, NULL);
66AMBA_DEVICE(kmi1, "fpga:07", KMI1, NULL);
67AMBA_DEVICE(uart3, "fpga:09", UART3, NULL);
68
69/* DevChip Primecells */
70AMBA_DEVICE(smc, "dev:00", SMC, NULL);
71AMBA_DEVICE(clcd, "dev:20", CLCD, &clcd_plat_data);
72AMBA_DEVICE(dmac, "dev:30", DMAC, NULL);
73AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL);
74AMBA_DEVICE(wdog, "dev:e1", WATCHDOG, NULL);
75AMBA_DEVICE(gpio0, "dev:e4", GPIO0, NULL);
76AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL);
77AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL);
78AMBA_DEVICE(rtc, "dev:e8", RTC, NULL);
79AMBA_DEVICE(sci0, "dev:f0", SCI, NULL);
80AMBA_DEVICE(uart0, "dev:f1", UART0, NULL);
81AMBA_DEVICE(uart1, "dev:f2", UART1, NULL);
82AMBA_DEVICE(uart2, "dev:f3", UART2, NULL);
83AMBA_DEVICE(ssp0, "dev:f4", SSP, NULL);
84
85static struct amba_device *amba_devs[] __initdata = {
86 &dmac_device,
87 &uart0_device,
88 &uart1_device,
89 &uart2_device,
90 &uart3_device,
91 &smc_device,
92 &clcd_device,
93 &sctl_device,
94 &wdog_device,
95 &gpio0_device,
96 &gpio1_device,
97 &gpio2_device,
98 &rtc_device,
99 &sci0_device,
100 &ssp0_device,
101 &aaci_device,
102 &mmc0_device,
103 &kmi0_device,
104 &kmi1_device,
105};
106
107static void __init gic_init_irq(void)
108{
109 gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE));
110 gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE));
111}
112
113static void __init realview_eb_init(void)
114{
115 int i;
116
117 clk_register(&realview_clcd_clk);
118
119 platform_device_register(&realview_flash_device);
120 platform_device_register(&realview_smc91x_device);
121
122 for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
123 struct amba_device *d = amba_devs[i];
124 amba_device_register(d, &iomem_resource);
125 }
126
127#ifdef CONFIG_LEDS
128 leds_event = realview_leds_event;
129#endif
130}
131
132MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
133 /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
134 .phys_ram = 0x00000000,
135 .phys_io = REALVIEW_UART0_BASE,
136 .io_pg_offst = (IO_ADDRESS(REALVIEW_UART0_BASE) >> 18) & 0xfffc,
137 .boot_params = 0x00000100,
138 .map_io = realview_eb_map_io,
139 .init_irq = gic_init_irq,
140 .timer = &realview_timer,
141 .init_machine = realview_eb_init,
142MACHINE_END
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index 8b3d5dc35de5..82e8253b1fa0 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -32,7 +32,7 @@
32#include <linux/list.h> 32#include <linux/list.h>
33#include <linux/errno.h> 33#include <linux/errno.h>
34#include <linux/err.h> 34#include <linux/err.h>
35#include <linux/device.h> 35#include <linux/platform_device.h>
36#include <linux/sysdev.h> 36#include <linux/sysdev.h>
37 37
38#include <linux/interrupt.h> 38#include <linux/interrupt.h>
diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c
index ca366e9e264d..687fe371369d 100644
--- a/arch/arm/mach-s3c2410/cpu.c
+++ b/arch/arm/mach-s3c2410/cpu.c
@@ -26,7 +26,7 @@
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/ioport.h> 28#include <linux/ioport.h>
29#include <linux/device.h> 29#include <linux/platform_device.h>
30 30
31#include <asm/hardware.h> 31#include <asm/hardware.h>
32#include <asm/irq.h> 32#include <asm/irq.h>
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c
index 08bc7d95a45d..f58406e6ef5a 100644
--- a/arch/arm/mach-s3c2410/devs.c
+++ b/arch/arm/mach-s3c2410/devs.c
@@ -24,7 +24,7 @@
24#include <linux/list.h> 24#include <linux/list.h>
25#include <linux/timer.h> 25#include <linux/timer.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/device.h> 27#include <linux/platform_device.h>
28 28
29#include <asm/mach/arch.h> 29#include <asm/mach/arch.h>
30#include <asm/mach/map.h> 30#include <asm/mach/map.h>
diff --git a/arch/arm/mach-s3c2410/devs.h b/arch/arm/mach-s3c2410/devs.h
index d6328f96728b..52c4bab5c761 100644
--- a/arch/arm/mach-s3c2410/devs.h
+++ b/arch/arm/mach-s3c2410/devs.h
@@ -15,6 +15,7 @@
15 * 10-Feb-2005 BJD Added camera from guillaume.gourat@nexvision.tv 15 * 10-Feb-2005 BJD Added camera from guillaume.gourat@nexvision.tv
16*/ 16*/
17#include <linux/config.h> 17#include <linux/config.h>
18#include <linux/platform_device.h>
18 19
19extern struct platform_device *s3c24xx_uart_devs[]; 20extern struct platform_device *s3c24xx_uart_devs[];
20 21
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c
index 5ae80f4e3e67..8390b685c2b6 100644
--- a/arch/arm/mach-s3c2410/mach-anubis.c
+++ b/arch/arm/mach-s3c2410/mach-anubis.c
@@ -21,7 +21,7 @@
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/timer.h> 22#include <linux/timer.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/device.h> 24#include <linux/platform_device.h>
25 25
26#include <asm/mach/arch.h> 26#include <asm/mach/arch.h>
27#include <asm/mach/map.h> 27#include <asm/mach/map.h>
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index c1b5c63ec24a..0b71c896bbd1 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -41,7 +41,7 @@
41#include <linux/list.h> 41#include <linux/list.h>
42#include <linux/timer.h> 42#include <linux/timer.h>
43#include <linux/init.h> 43#include <linux/init.h>
44#include <linux/device.h> 44#include <linux/platform_device.h>
45#include <linux/dm9000.h> 45#include <linux/dm9000.h>
46 46
47#include <asm/mach/arch.h> 47#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 7efeaaad2361..0aa8760598f7 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -34,6 +34,7 @@
34#include <linux/list.h> 34#include <linux/list.h>
35#include <linux/timer.h> 35#include <linux/timer.h>
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/platform_device.h>
37 38
38#include <asm/mach/arch.h> 39#include <asm/mach/arch.h>
39#include <asm/mach/map.h> 40#include <asm/mach/map.h>
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 5c0f2b091f95..378d640ab00b 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -20,7 +20,7 @@
20#include <linux/timer.h> 20#include <linux/timer.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/device.h> 23#include <linux/platform_device.h>
24#include <linux/kthread.h> 24#include <linux/kthread.h>
25 25
26#include <asm/mach/arch.h> 26#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2410/mach-nexcoder.c
index c22f8216032d..42b0eeff2e0f 100644
--- a/arch/arm/mach-s3c2410/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2410/mach-nexcoder.c
@@ -19,7 +19,7 @@
19#include <linux/timer.h> 19#include <linux/timer.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/device.h> 22#include <linux/platform_device.h>
23 23
24#include <linux/mtd/map.h> 24#include <linux/mtd/map.h>
25 25
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
index ad1459e402e2..a2eb9ed48fcd 100644
--- a/arch/arm/mach-s3c2410/mach-otom.c
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -15,7 +15,7 @@
15#include <linux/list.h> 15#include <linux/list.h>
16#include <linux/timer.h> 16#include <linux/timer.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/device.h> 18#include <linux/platform_device.h>
19 19
20#include <asm/mach/arch.h> 20#include <asm/mach/arch.h>
21#include <asm/mach/map.h> 21#include <asm/mach/map.h>
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c
index 22d9e070fd68..24d69019a843 100644
--- a/arch/arm/mach-s3c2410/mach-rx3715.c
+++ b/arch/arm/mach-s3c2410/mach-rx3715.c
@@ -17,6 +17,7 @@
17 * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA 17 * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA
18 * 14-Mar-2005 BJD Fixed __iomem warnings 18 * 14-Mar-2005 BJD Fixed __iomem warnings
19 * 20-Sep-2005 BJD Added static to non-exported items 19 * 20-Sep-2005 BJD Added static to non-exported items
20 * 31-Oct-2005 BJD Added LCD setup for framebuffer
20*/ 21*/
21 22
22#include <linux/kernel.h> 23#include <linux/kernel.h>
@@ -27,6 +28,7 @@
27#include <linux/init.h> 28#include <linux/init.h>
28#include <linux/tty.h> 29#include <linux/tty.h>
29#include <linux/console.h> 30#include <linux/console.h>
31#include <linux/platform_device.h>
30#include <linux/serial_core.h> 32#include <linux/serial_core.h>
31#include <linux/serial.h> 33#include <linux/serial.h>
32 34
@@ -42,6 +44,9 @@
42 44
43#include <asm/arch/regs-serial.h> 45#include <asm/arch/regs-serial.h>
44#include <asm/arch/regs-gpio.h> 46#include <asm/arch/regs-gpio.h>
47#include <asm/arch/regs-lcd.h>
48
49#include <asm/arch/fb.h>
45 50
46#include "clock.h" 51#include "clock.h"
47#include "devs.h" 52#include "devs.h"
@@ -96,6 +101,66 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
96 } 101 }
97}; 102};
98 103
104/* framebuffer lcd controller information */
105
106static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = {
107 .regs = {
108 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | \
109 S3C2410_LCDCON1_TFT | \
110 S3C2410_LCDCON1_CLKVAL(0x0C),
111
112 .lcdcon2 = S3C2410_LCDCON2_VBPD(5) | \
113 S3C2410_LCDCON2_LINEVAL(319) | \
114 S3C2410_LCDCON2_VFPD(6) | \
115 S3C2410_LCDCON2_VSPW(2),
116
117 .lcdcon3 = S3C2410_LCDCON3_HBPD(35) | \
118 S3C2410_LCDCON3_HOZVAL(239) | \
119 S3C2410_LCDCON3_HFPD(35),
120
121 .lcdcon4 = S3C2410_LCDCON4_MVAL(0) | \
122 S3C2410_LCDCON4_HSPW(7),
123
124 .lcdcon5 = S3C2410_LCDCON5_INVVLINE |
125 S3C2410_LCDCON5_FRM565 |
126 S3C2410_LCDCON5_HWSWP,
127 },
128
129 .lpcsel = 0xf82,
130
131 .gpccon = 0xaa955699,
132 .gpccon_mask = 0xffc003cc,
133 .gpcup = 0x0000ffff,
134 .gpcup_mask = 0xffffffff,
135
136 .gpdcon = 0xaa95aaa1,
137 .gpdcon_mask = 0xffc0fff0,
138 .gpdup = 0x0000faff,
139 .gpdup_mask = 0xffffffff,
140
141 .fixed_syncs = 1,
142 .width = 240,
143 .height = 320,
144
145 .xres = {
146 .min = 240,
147 .max = 240,
148 .defval = 240,
149 },
150
151 .yres = {
152 .max = 320,
153 .min = 320,
154 .defval = 320,
155 },
156
157 .bpp = {
158 .min = 16,
159 .max = 16,
160 .defval = 16,
161 },
162};
163
99static struct platform_device *rx3715_devices[] __initdata = { 164static struct platform_device *rx3715_devices[] __initdata = {
100 &s3c_device_usb, 165 &s3c_device_usb,
101 &s3c_device_lcd, 166 &s3c_device_lcd,
@@ -122,14 +187,12 @@ static void __init rx3715_init_irq(void)
122 s3c24xx_init_irq(); 187 s3c24xx_init_irq();
123} 188}
124 189
125#ifdef CONFIG_PM
126static void __init rx3715_init_machine(void) 190static void __init rx3715_init_machine(void)
127{ 191{
128 s3c2410_pm_init(); 192 s3c2410_pm_init();
193 s3c24xx_fb_set_platdata(&rx3715_lcdcfg);
129} 194}
130#else 195
131#define rx3715_init_machine NULL
132#endif
133 196
134MACHINE_START(RX3715, "IPAQ-RX3715") 197MACHINE_START(RX3715, "IPAQ-RX3715")
135 /* Maintainer: Ben Dooks <ben@fluff.org> */ 198 /* Maintainer: Ben Dooks <ben@fluff.org> */
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index 2eda55a6b678..2c91965ee1c8 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -38,6 +38,7 @@
38#include <linux/list.h> 38#include <linux/list.h>
39#include <linux/timer.h> 39#include <linux/timer.h>
40#include <linux/init.h> 40#include <linux/init.h>
41#include <linux/platform_device.h>
41 42
42#include <asm/mach/arch.h> 43#include <asm/mach/arch.h>
43#include <asm/mach/map.h> 44#include <asm/mach/map.h>
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c
index 6950e61b7914..d666c621ad06 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2440.c
@@ -28,6 +28,7 @@
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/timer.h> 29#include <linux/timer.h>
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/platform_device.h>
31 32
32#include <asm/mach/arch.h> 33#include <asm/mach/arch.h>
33#include <asm/mach/map.h> 34#include <asm/mach/map.h>
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index a8bf5ec82602..0a2013a76549 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -27,7 +27,7 @@
27#include <linux/list.h> 27#include <linux/list.h>
28#include <linux/timer.h> 28#include <linux/timer.h>
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/device.h> 30#include <linux/platform_device.h>
31 31
32#include <asm/mach/arch.h> 32#include <asm/mach/arch.h>
33#include <asm/mach/map.h> 33#include <asm/mach/map.h>
diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c
index 833fa36bce05..4d63e7133b48 100644
--- a/arch/arm/mach-s3c2410/s3c2440.c
+++ b/arch/arm/mach-s3c2410/s3c2440.c
@@ -26,7 +26,7 @@
26#include <linux/list.h> 26#include <linux/list.h>
27#include <linux/timer.h> 27#include <linux/timer.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/device.h> 29#include <linux/platform_device.h>
30#include <linux/sysdev.h> 30#include <linux/sysdev.h>
31 31
32#include <asm/mach/arch.h> 32#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
index c92cebff7f8e..edccd5eb06be 100644
--- a/arch/arm/mach-sa1100/badge4.c
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -16,7 +16,7 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/device.h> 19#include <linux/platform_device.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/tty.h> 21#include <linux/tty.h>
22#include <linux/mtd/mtd.h> 22#include <linux/mtd/mtd.h>
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index 23cb74885275..508593722bc7 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -14,7 +14,7 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/tty.h> 16#include <linux/tty.h>
17#include <linux/device.h> 17#include <linux/platform_device.h>
18#include <linux/mtd/mtd.h> 18#include <linux/mtd/mtd.h>
19#include <linux/mtd/partitions.h> 19#include <linux/mtd/partitions.h>
20 20
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 7fd6e29c36b7..522abc036d3a 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -21,7 +21,7 @@
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/tty.h> 22#include <linux/tty.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/device.h> 24#include <linux/platform_device.h>
25#include <linux/mtd/mtd.h> 25#include <linux/mtd/mtd.h>
26#include <linux/mtd/partitions.h> 26#include <linux/mtd/partitions.h>
27#include <linux/timer.h> 27#include <linux/timer.h>
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 83eba8b54816..2abdc419e984 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -18,6 +18,7 @@
18#include <linux/cpufreq.h> 18#include <linux/cpufreq.h>
19#include <linux/ioport.h> 19#include <linux/ioport.h>
20#include <linux/sched.h> /* just for sched_clock() - funny that */ 20#include <linux/sched.h> /* just for sched_clock() - funny that */
21#include <linux/platform_device.h>
21 22
22#include <asm/div64.h> 23#include <asm/div64.h>
23#include <asm/hardware.h> 24#include <asm/hardware.h>
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index 89af0c831e8f..2f671cc3cb99 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -6,7 +6,7 @@
6#include <linux/kernel.h> 6#include <linux/kernel.h>
7#include <linux/tty.h> 7#include <linux/tty.h>
8#include <linux/delay.h> 8#include <linux/delay.h>
9#include <linux/device.h> 9#include <linux/platform_device.h>
10#include <linux/ioport.h> 10#include <linux/ioport.h>
11#include <linux/mtd/mtd.h> 11#include <linux/mtd/mtd.h>
12#include <linux/mtd/partitions.h> 12#include <linux/mtd/partitions.h>
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 052e4caedb89..69f1970646c6 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -8,7 +8,7 @@
8#include <linux/tty.h> 8#include <linux/tty.h>
9#include <linux/ioport.h> 9#include <linux/ioport.h>
10#include <linux/serial_core.h> 10#include <linux/serial_core.h>
11#include <linux/device.h> 11#include <linux/platform_device.h>
12#include <linux/slab.h> 12#include <linux/slab.h>
13 13
14#include <asm/hardware.h> 14#include <asm/hardware.h>
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c
index e17b58fb9c9c..58c18f9e9b7b 100644
--- a/arch/arm/mach-sa1100/pleb.c
+++ b/arch/arm/mach-sa1100/pleb.c
@@ -6,7 +6,7 @@
6#include <linux/kernel.h> 6#include <linux/kernel.h>
7#include <linux/tty.h> 7#include <linux/tty.h>
8#include <linux/ioport.h> 8#include <linux/ioport.h>
9#include <linux/device.h> 9#include <linux/platform_device.h>
10 10
11#include <linux/mtd/partitions.h> 11#include <linux/mtd/partitions.h>
12 12
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index cfb6658e5cdf..439ddc9b06d6 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -10,7 +10,7 @@
10#include <linux/proc_fs.h> 10#include <linux/proc_fs.h>
11#include <linux/string.h> 11#include <linux/string.h>
12#include <linux/pm.h> 12#include <linux/pm.h>
13#include <linux/device.h> 13#include <linux/platform_device.h>
14#include <linux/mtd/mtd.h> 14#include <linux/mtd/mtd.h>
15#include <linux/mtd/partitions.h> 15#include <linux/mtd/partitions.h>
16 16
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 7e4bdd07f4af..a1ca46630dda 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -22,6 +22,7 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/device.h> 23#include <linux/device.h>
24#include <linux/dma-mapping.h> 24#include <linux/dma-mapping.h>
25#include <linux/platform_device.h>
25#include <linux/sysdev.h> 26#include <linux/sysdev.h>
26#include <linux/interrupt.h> 27#include <linux/interrupt.h>
27 28
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index c54e04c995ee..5568403e984d 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -120,8 +120,8 @@ config CPU_ARM925T
120 120
121# ARM926T 121# ARM926T
122config CPU_ARM926T 122config CPU_ARM926T
123 bool "Support ARM926T processor" if ARCH_INTEGRATOR 123 bool "Support ARM926T processor"
124 depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX 124 depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB
125 default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX 125 default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX
126 select CPU_32v5 126 select CPU_32v5
127 select CPU_ABRT_EV5TJ 127 select CPU_ABRT_EV5TJ
@@ -242,7 +242,7 @@ config CPU_XSCALE
242# ARMv6 242# ARMv6
243config CPU_V6 243config CPU_V6
244 bool "Support ARM V6 processor" 244 bool "Support ARM V6 processor"
245 depends on ARCH_INTEGRATOR 245 depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB
246 select CPU_32v6 246 select CPU_32v6
247 select CPU_ABRT_EV6 247 select CPU_ABRT_EV6
248 select CPU_CACHE_V6 248 select CPU_CACHE_V6
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
index 14a836d7ac25..205e2d0b826d 100644
--- a/arch/arm/plat-omap/usb.c
+++ b/arch/arm/plat-omap/usb.c
@@ -26,7 +26,7 @@
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/errno.h> 27#include <linux/errno.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/device.h> 29#include <linux/platform_device.h>
30#include <linux/usb_otg.h> 30#include <linux/usb_otg.h>
31 31
32#include <asm/io.h> 32#include <asm/io.h>
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 5383e5e2d9b7..bac0da731ee3 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -1042,8 +1042,3 @@ config X86_TRAMPOLINE
1042 bool 1042 bool
1043 depends on X86_SMP || (X86_VOYAGER && SMP) 1043 depends on X86_SMP || (X86_VOYAGER && SMP)
1044 default y 1044 default y
1045
1046config PC
1047 bool
1048 depends on X86 && !EMBEDDED
1049 default y
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 9204be6eedb3..7c724ffa08bb 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -803,7 +803,6 @@ no_apic:
803 803
804void __init init_apic_mappings(void) 804void __init init_apic_mappings(void)
805{ 805{
806 unsigned int orig_apicid;
807 unsigned long apic_phys; 806 unsigned long apic_phys;
808 807
809 /* 808 /*
@@ -825,11 +824,8 @@ void __init init_apic_mappings(void)
825 * Fetch the APIC ID of the BSP in case we have a 824 * Fetch the APIC ID of the BSP in case we have a
826 * default configuration (or the MP table is broken). 825 * default configuration (or the MP table is broken).
827 */ 826 */
828 orig_apicid = boot_cpu_physical_apicid; 827 if (boot_cpu_physical_apicid == -1U)
829 boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); 828 boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
830 if ((orig_apicid != -1U) && (orig_apicid != boot_cpu_physical_apicid))
831 printk(KERN_WARNING "Boot APIC ID in local APIC unexpected (%d vs %d)",
832 orig_apicid, boot_cpu_physical_apicid);
833 829
834#ifdef CONFIG_X86_IO_APIC 830#ifdef CONFIG_X86_IO_APIC
835 { 831 {
@@ -1259,81 +1255,40 @@ fastcall void smp_error_interrupt(struct pt_regs *regs)
1259} 1255}
1260 1256
1261/* 1257/*
1262 * This initializes the IO-APIC and APIC hardware. 1258 * This initializes the IO-APIC and APIC hardware if this is
1259 * a UP kernel.
1263 */ 1260 */
1264int __init APIC_init(void) 1261int __init APIC_init_uniprocessor (void)
1265{ 1262{
1266 if (enable_local_apic < 0) { 1263 if (enable_local_apic < 0)
1267 printk(KERN_INFO "APIC disabled\n"); 1264 clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
1268 return -1;
1269 }
1270 1265
1271 /* See if we have a SMP configuration or have forced enabled 1266 if (!smp_found_config && !cpu_has_apic)
1272 * the local apic.
1273 */
1274 if (!smp_found_config && !acpi_lapic && !cpu_has_apic) {
1275 enable_local_apic = -1;
1276 return -1; 1267 return -1;
1277 }
1278 1268
1279 /* 1269 /*
1280 * Complain if the BIOS pretends there is an apic. 1270 * Complain if the BIOS pretends there is one.
1281 * Then get out because we don't have an a local apic.
1282 */ 1271 */
1283 if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { 1272 if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
1284 printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", 1273 printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
1285 boot_cpu_physical_apicid); 1274 boot_cpu_physical_apicid);
1286 printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
1287 enable_local_apic = -1;
1288 return -1; 1275 return -1;
1289 } 1276 }
1290 1277
1291 verify_local_APIC(); 1278 verify_local_APIC();
1292 1279
1293 /*
1294 * Should not be necessary because the MP table should list the boot
1295 * CPU too, but we do it for the sake of robustness anyway.
1296 * Makes no sense to do this check in clustered apic mode, so skip it
1297 */
1298 if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
1299 printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
1300 boot_cpu_physical_apicid);
1301 physid_set(boot_cpu_physical_apicid, phys_cpu_present_map);
1302 }
1303
1304 /*
1305 * Switch from PIC to APIC mode.
1306 */
1307 connect_bsp_APIC(); 1280 connect_bsp_APIC();
1308 setup_local_APIC();
1309 1281
1310#ifdef CONFIG_X86_IO_APIC 1282 phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
1311 /*
1312 * Now start the IO-APICs
1313 */
1314 if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
1315 setup_IO_APIC();
1316#endif
1317 return 0;
1318}
1319 1283
1320void __init APIC_late_time_init(void) 1284 setup_local_APIC();
1321{
1322 /* Improve our loops per jiffy estimate */
1323 loops_per_jiffy = ((1000 + HZ - 1)/HZ)*cpu_khz;
1324 boot_cpu_data.loops_per_jiffy = loops_per_jiffy;
1325 cpu_data[0].loops_per_jiffy = loops_per_jiffy;
1326
1327 /* setup_apic_nmi_watchdog doesn't work properly before cpu_khz is
1328 * initialized. So redo it here to ensure the boot cpu is setup
1329 * properly.
1330 */
1331 if (nmi_watchdog == NMI_LOCAL_APIC)
1332 setup_apic_nmi_watchdog();
1333 1285
1334#ifdef CONFIG_X86_IO_APIC 1286#ifdef CONFIG_X86_IO_APIC
1335 if (smp_found_config && !skip_ioapic_setup && nr_ioapics) 1287 if (smp_found_config)
1336 IO_APIC_late_time_init(); 1288 if (!skip_ioapic_setup && nr_ioapics)
1289 setup_IO_APIC();
1337#endif 1290#endif
1338 setup_boot_APIC_clock(); 1291 setup_boot_APIC_clock();
1292
1293 return 0;
1339} 1294}
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
index d86f24909284..323ef8ab3244 100644
--- a/arch/i386/kernel/i8259.c
+++ b/arch/i386/kernel/i8259.c
@@ -435,8 +435,4 @@ void __init init_IRQ(void)
435 setup_irq(FPU_IRQ, &fpu_irq); 435 setup_irq(FPU_IRQ, &fpu_irq);
436 436
437 irq_ctx_init(smp_processor_id()); 437 irq_ctx_init(smp_processor_id());
438
439#ifdef CONFIG_X86_LOCAL_APIC
440 APIC_init();
441#endif
442} 438}
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 5a77c52b20a9..cc5d7ac5b2e7 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -2387,15 +2387,11 @@ void __init setup_IO_APIC(void)
2387 sync_Arb_IDs(); 2387 sync_Arb_IDs();
2388 setup_IO_APIC_irqs(); 2388 setup_IO_APIC_irqs();
2389 init_IO_APIC_traps(); 2389 init_IO_APIC_traps();
2390 check_timer();
2390 if (!acpi_ioapic) 2391 if (!acpi_ioapic)
2391 print_IO_APIC(); 2392 print_IO_APIC();
2392} 2393}
2393 2394
2394void __init IO_APIC_late_time_init(void)
2395{
2396 check_timer();
2397}
2398
2399/* 2395/*
2400 * Called after all the initialization is done. If we didnt find any 2396 * Called after all the initialization is done. If we didnt find any
2401 * APIC bugs then we can allow the modify fast path 2397 * APIC bugs then we can allow the modify fast path
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 5a2bbe0c4fff..01b618e73ecd 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -1078,16 +1078,6 @@ void *xquad_portio;
1078EXPORT_SYMBOL(xquad_portio); 1078EXPORT_SYMBOL(xquad_portio);
1079#endif 1079#endif
1080 1080
1081/*
1082 * Fall back to non SMP mode after errors.
1083 *
1084 */
1085static __init void disable_smp(void)
1086{
1087 cpu_set(0, cpu_sibling_map[0]);
1088 cpu_set(0, cpu_core_map[0]);
1089}
1090
1091static void __init smp_boot_cpus(unsigned int max_cpus) 1081static void __init smp_boot_cpus(unsigned int max_cpus)
1092{ 1082{
1093 int apicid, cpu, bit, kicked; 1083 int apicid, cpu, bit, kicked;
@@ -1100,6 +1090,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1100 printk("CPU%d: ", 0); 1090 printk("CPU%d: ", 0);
1101 print_cpu_info(&cpu_data[0]); 1091 print_cpu_info(&cpu_data[0]);
1102 1092
1093 boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
1103 boot_cpu_logical_apicid = logical_smp_processor_id(); 1094 boot_cpu_logical_apicid = logical_smp_processor_id();
1104 x86_cpu_to_apicid[0] = boot_cpu_physical_apicid; 1095 x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
1105 1096
@@ -1111,27 +1102,68 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1111 cpus_clear(cpu_core_map[0]); 1102 cpus_clear(cpu_core_map[0]);
1112 cpu_set(0, cpu_core_map[0]); 1103 cpu_set(0, cpu_core_map[0]);
1113 1104
1114 map_cpu_to_logical_apicid();
1115
1116 /* 1105 /*
1117 * If we couldn't find an SMP configuration at boot time, 1106 * If we couldn't find an SMP configuration at boot time,
1118 * get out of here now! 1107 * get out of here now!
1119 */ 1108 */
1120 if (!smp_found_config && !acpi_lapic) { 1109 if (!smp_found_config && !acpi_lapic) {
1121 printk(KERN_NOTICE "SMP motherboard not detected.\n"); 1110 printk(KERN_NOTICE "SMP motherboard not detected.\n");
1122 disable_smp(); 1111 smpboot_clear_io_apic_irqs();
1112 phys_cpu_present_map = physid_mask_of_physid(0);
1113 if (APIC_init_uniprocessor())
1114 printk(KERN_NOTICE "Local APIC not detected."
1115 " Using dummy APIC emulation.\n");
1116 map_cpu_to_logical_apicid();
1117 cpu_set(0, cpu_sibling_map[0]);
1118 cpu_set(0, cpu_core_map[0]);
1119 return;
1120 }
1121
1122 /*
1123 * Should not be necessary because the MP table should list the boot
1124 * CPU too, but we do it for the sake of robustness anyway.
1125 * Makes no sense to do this check in clustered apic mode, so skip it
1126 */
1127 if (!check_phys_apicid_present(boot_cpu_physical_apicid)) {
1128 printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
1129 boot_cpu_physical_apicid);
1130 physid_set(hard_smp_processor_id(), phys_cpu_present_map);
1131 }
1132
1133 /*
1134 * If we couldn't find a local APIC, then get out of here now!
1135 */
1136 if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]) && !cpu_has_apic) {
1137 printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
1138 boot_cpu_physical_apicid);
1139 printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
1140 smpboot_clear_io_apic_irqs();
1141 phys_cpu_present_map = physid_mask_of_physid(0);
1142 cpu_set(0, cpu_sibling_map[0]);
1143 cpu_set(0, cpu_core_map[0]);
1123 return; 1144 return;
1124 } 1145 }
1125 1146
1147 verify_local_APIC();
1148
1126 /* 1149 /*
1127 * If SMP should be disabled, then really disable it! 1150 * If SMP should be disabled, then really disable it!
1128 */ 1151 */
1129 if (!max_cpus || (enable_local_apic < 0)) { 1152 if (!max_cpus) {
1130 printk(KERN_INFO "SMP mode deactivated.\n"); 1153 smp_found_config = 0;
1131 disable_smp(); 1154 printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
1155 smpboot_clear_io_apic_irqs();
1156 phys_cpu_present_map = physid_mask_of_physid(0);
1157 cpu_set(0, cpu_sibling_map[0]);
1158 cpu_set(0, cpu_core_map[0]);
1132 return; 1159 return;
1133 } 1160 }
1134 1161
1162 connect_bsp_APIC();
1163 setup_local_APIC();
1164 map_cpu_to_logical_apicid();
1165
1166
1135 setup_portio_remap(); 1167 setup_portio_remap();
1136 1168
1137 /* 1169 /*
@@ -1212,6 +1244,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1212 cpu_set(0, cpu_sibling_map[0]); 1244 cpu_set(0, cpu_sibling_map[0]);
1213 cpu_set(0, cpu_core_map[0]); 1245 cpu_set(0, cpu_core_map[0]);
1214 1246
1247 smpboot_setup_io_apic();
1248
1249 setup_boot_APIC_clock();
1250
1215 /* 1251 /*
1216 * Synchronize the TSC with the AP 1252 * Synchronize the TSC with the AP
1217 */ 1253 */
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index 07471bba2dc6..41c5b2dc6200 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -440,8 +440,8 @@ static int time_init_device(void)
440 440
441device_initcall(time_init_device); 441device_initcall(time_init_device);
442 442
443extern void (*late_time_init)(void);
444#ifdef CONFIG_HPET_TIMER 443#ifdef CONFIG_HPET_TIMER
444extern void (*late_time_init)(void);
445/* Duplicate of time_init() below, with hpet_enable part added */ 445/* Duplicate of time_init() below, with hpet_enable part added */
446static void __init hpet_time_init(void) 446static void __init hpet_time_init(void)
447{ 447{
@@ -458,11 +458,6 @@ static void __init hpet_time_init(void)
458 printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name); 458 printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
459 459
460 time_init_hook(); 460 time_init_hook();
461
462#ifdef CONFIG_X86_LOCAL_APIC
463 if (enable_local_apic >= 0)
464 APIC_late_time_init();
465#endif
466} 461}
467#endif 462#endif
468 463
@@ -487,9 +482,4 @@ void __init time_init(void)
487 printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name); 482 printk(KERN_INFO "Using %s for high-res timesource\n",cur_timer->name);
488 483
489 time_init_hook(); 484 time_init_hook();
490
491#ifdef CONFIG_X86_LOCAL_APIC
492 if (enable_local_apic >= 0)
493 late_time_init = APIC_late_time_init;
494#endif
495} 485}
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index 330fd2b68075..3984226a8b98 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -398,7 +398,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
398 */ 398 */
399static u16 toshiba_line_size; 399static u16 toshiba_line_size;
400 400
401static struct dmi_system_id __devinit toshiba_ohci1394_dmi_table[] = { 401static struct dmi_system_id __devinitdata toshiba_ohci1394_dmi_table[] = {
402 { 402 {
403 .ident = "Toshiba PS5 based laptop", 403 .ident = "Toshiba PS5 based laptop",
404 .matches = { 404 .matches = {
diff --git a/arch/m32r/kernel/setup_m32700ut.c b/arch/m32r/kernel/setup_m32700ut.c
index 708634b685e4..cb76916b014d 100644
--- a/arch/m32r/kernel/setup_m32700ut.c
+++ b/arch/m32r/kernel/setup_m32700ut.c
@@ -15,7 +15,7 @@
15#include <linux/irq.h> 15#include <linux/irq.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/device.h> 18#include <linux/platform_device.h>
19 19
20#include <asm/system.h> 20#include <asm/system.h>
21#include <asm/m32r.h> 21#include <asm/m32r.h>
diff --git a/arch/m32r/kernel/setup_mappi.c b/arch/m32r/kernel/setup_mappi.c
index 4e709809efc5..501d798cf050 100644
--- a/arch/m32r/kernel/setup_mappi.c
+++ b/arch/m32r/kernel/setup_mappi.c
@@ -11,7 +11,7 @@
11#include <linux/irq.h> 11#include <linux/irq.h>
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/device.h> 14#include <linux/platform_device.h>
15 15
16#include <asm/system.h> 16#include <asm/system.h>
17#include <asm/m32r.h> 17#include <asm/m32r.h>
diff --git a/arch/m32r/kernel/setup_mappi2.c b/arch/m32r/kernel/setup_mappi2.c
index a1d801598aa4..7f2db5bfd626 100644
--- a/arch/m32r/kernel/setup_mappi2.c
+++ b/arch/m32r/kernel/setup_mappi2.c
@@ -11,7 +11,7 @@
11#include <linux/irq.h> 11#include <linux/irq.h>
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/device.h> 14#include <linux/platform_device.h>
15 15
16#include <asm/system.h> 16#include <asm/system.h>
17#include <asm/m32r.h> 17#include <asm/m32r.h>
diff --git a/arch/m32r/kernel/setup_mappi3.c b/arch/m32r/kernel/setup_mappi3.c
index a76412e883e8..9c79341a7b45 100644
--- a/arch/m32r/kernel/setup_mappi3.c
+++ b/arch/m32r/kernel/setup_mappi3.c
@@ -11,7 +11,7 @@
11#include <linux/irq.h> 11#include <linux/irq.h>
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/device.h> 14#include <linux/platform_device.h>
15 15
16#include <asm/system.h> 16#include <asm/system.h>
17#include <asm/m32r.h> 17#include <asm/m32r.h>
diff --git a/arch/m32r/kernel/setup_opsput.c b/arch/m32r/kernel/setup_opsput.c
index d7b7ec6d30f8..1fbb140854e7 100644
--- a/arch/m32r/kernel/setup_opsput.c
+++ b/arch/m32r/kernel/setup_opsput.c
@@ -16,7 +16,7 @@
16#include <linux/irq.h> 16#include <linux/irq.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/device.h> 19#include <linux/platform_device.h>
20 20
21#include <asm/system.h> 21#include <asm/system.h>
22#include <asm/m32r.h> 22#include <asm/m32r.h>
diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c
index 1f7b465c8038..48d3f54f88f8 100644
--- a/arch/mips/au1000/common/platform.c
+++ b/arch/mips/au1000/common/platform.c
@@ -9,6 +9,7 @@
9 */ 9 */
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/device.h> 11#include <linux/device.h>
12#include <linux/platform_device.h>
12#include <linux/kernel.h> 13#include <linux/kernel.h>
13#include <linux/init.h> 14#include <linux/init.h>
14#include <linux/resource.h> 15#include <linux/resource.h>
diff --git a/arch/ppc/platforms/4xx/ibm440ep.c b/arch/ppc/platforms/4xx/ibm440ep.c
index 4712de8ff80f..65ac0b9c2d05 100644
--- a/arch/ppc/platforms/4xx/ibm440ep.c
+++ b/arch/ppc/platforms/4xx/ibm440ep.c
@@ -14,6 +14,7 @@
14 */ 14 */
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/platform_device.h>
17#include <platforms/4xx/ibm440ep.h> 18#include <platforms/4xx/ibm440ep.h>
18#include <asm/ocp.h> 19#include <asm/ocp.h>
19#include <asm/ppc4xx_pic.h> 20#include <asm/ppc4xx_pic.h>
diff --git a/arch/ppc/platforms/4xx/ibmstb4.c b/arch/ppc/platforms/4xx/ibmstb4.c
index d90627b68faa..7e33bb635443 100644
--- a/arch/ppc/platforms/4xx/ibmstb4.c
+++ b/arch/ppc/platforms/4xx/ibmstb4.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/platform_device.h>
13#include <asm/ocp.h> 14#include <asm/ocp.h>
14#include <asm/ppc4xx_pic.h> 15#include <asm/ppc4xx_pic.h>
15#include <platforms/4xx/ibmstb4.h> 16#include <platforms/4xx/ibmstb4.h>
diff --git a/arch/ppc/platforms/4xx/redwood5.c b/arch/ppc/platforms/4xx/redwood5.c
index bee8b4ac8afd..611ac861804d 100644
--- a/arch/ppc/platforms/4xx/redwood5.c
+++ b/arch/ppc/platforms/4xx/redwood5.c
@@ -14,7 +14,7 @@
14#include <linux/config.h> 14#include <linux/config.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/pagemap.h> 16#include <linux/pagemap.h>
17#include <linux/device.h> 17#include <linux/platform_device.h>
18#include <linux/ioport.h> 18#include <linux/ioport.h>
19#include <asm/io.h> 19#include <asm/io.h>
20#include <asm/machdep.h> 20#include <asm/machdep.h>
diff --git a/arch/ppc/platforms/4xx/redwood6.c b/arch/ppc/platforms/4xx/redwood6.c
index 8b1012994dfc..b13116691289 100644
--- a/arch/ppc/platforms/4xx/redwood6.c
+++ b/arch/ppc/platforms/4xx/redwood6.c
@@ -12,7 +12,7 @@
12#include <linux/config.h> 12#include <linux/config.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/pagemap.h> 14#include <linux/pagemap.h>
15#include <linux/device.h> 15#include <linux/platform_device.h>
16#include <linux/ioport.h> 16#include <linux/ioport.h>
17#include <asm/io.h> 17#include <asm/io.h>
18#include <asm/ppc4xx_pic.h> 18#include <asm/ppc4xx_pic.h>
diff --git a/arch/ppc/platforms/chrp_pegasos_eth.c b/arch/ppc/platforms/chrp_pegasos_eth.c
index a9052305c35d..108a6e265185 100644
--- a/arch/ppc/platforms/chrp_pegasos_eth.c
+++ b/arch/ppc/platforms/chrp_pegasos_eth.c
@@ -13,7 +13,7 @@
13#include <linux/types.h> 13#include <linux/types.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/ioport.h> 15#include <linux/ioport.h>
16#include <linux/device.h> 16#include <linux/platform_device.h>
17#include <linux/mv643xx.h> 17#include <linux/mv643xx.h>
18#include <linux/pci.h> 18#include <linux/pci.h>
19 19
diff --git a/arch/ppc/platforms/cpci690.c b/arch/ppc/platforms/cpci690.c
index f64ac2acb603..6ca7bcac9474 100644
--- a/arch/ppc/platforms/cpci690.c
+++ b/arch/ppc/platforms/cpci690.c
@@ -21,6 +21,7 @@
21#include <linux/initrd.h> 21#include <linux/initrd.h>
22#include <linux/root_dev.h> 22#include <linux/root_dev.h>
23#include <linux/mv643xx.h> 23#include <linux/mv643xx.h>
24#include <linux/platform_device.h>
24#include <asm/bootinfo.h> 25#include <asm/bootinfo.h>
25#include <asm/machdep.h> 26#include <asm/machdep.h>
26#include <asm/todc.h> 27#include <asm/todc.h>
diff --git a/arch/ppc/platforms/ev64260.c b/arch/ppc/platforms/ev64260.c
index aa50637a5cfb..32358b3fb236 100644
--- a/arch/ppc/platforms/ev64260.c
+++ b/arch/ppc/platforms/ev64260.c
@@ -33,6 +33,7 @@
33#include <linux/console.h> 33#include <linux/console.h>
34#include <linux/initrd.h> 34#include <linux/initrd.h>
35#include <linux/root_dev.h> 35#include <linux/root_dev.h>
36#include <linux/platform_device.h>
36#if !defined(CONFIG_SERIAL_MPSC_CONSOLE) 37#if !defined(CONFIG_SERIAL_MPSC_CONSOLE)
37#include <linux/serial.h> 38#include <linux/serial.h>
38#include <linux/tty.h> 39#include <linux/tty.h>
diff --git a/arch/ppc/platforms/ev64360.c b/arch/ppc/platforms/ev64360.c
index 53388a1c334f..b1324564456e 100644
--- a/arch/ppc/platforms/ev64360.c
+++ b/arch/ppc/platforms/ev64360.c
@@ -25,6 +25,7 @@
25#include <linux/bootmem.h> 25#include <linux/bootmem.h>
26#include <linux/mtd/physmap.h> 26#include <linux/mtd/physmap.h>
27#include <linux/mv643xx.h> 27#include <linux/mv643xx.h>
28#include <linux/platform_device.h>
28#ifdef CONFIG_BOOTIMG 29#ifdef CONFIG_BOOTIMG
29#include <linux/bootimg.h> 30#include <linux/bootimg.h>
30#endif 31#endif
diff --git a/arch/ppc/platforms/hdpu.c b/arch/ppc/platforms/hdpu.c
index b6a66d5e9d83..50039a204c24 100644
--- a/arch/ppc/platforms/hdpu.c
+++ b/arch/ppc/platforms/hdpu.c
@@ -22,6 +22,7 @@
22#include <linux/irq.h> 22#include <linux/irq.h>
23#include <linux/ide.h> 23#include <linux/ide.h>
24#include <linux/seq_file.h> 24#include <linux/seq_file.h>
25#include <linux/platform_device.h>
25 26
26#include <linux/initrd.h> 27#include <linux/initrd.h>
27#include <linux/root_dev.h> 28#include <linux/root_dev.h>
diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c
index a301c5ac58dd..6e58e30ceed1 100644
--- a/arch/ppc/platforms/katana.c
+++ b/arch/ppc/platforms/katana.c
@@ -29,6 +29,7 @@
29#include <linux/seq_file.h> 29#include <linux/seq_file.h>
30#include <linux/mtd/physmap.h> 30#include <linux/mtd/physmap.h>
31#include <linux/mv643xx.h> 31#include <linux/mv643xx.h>
32#include <linux/platform_device.h>
32#ifdef CONFIG_BOOTIMG 33#ifdef CONFIG_BOOTIMG
33#include <linux/bootimg.h> 34#include <linux/bootimg.h>
34#endif 35#endif
diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c
index 6f97911c330d..708b8739ecdd 100644
--- a/arch/ppc/platforms/radstone_ppc7d.c
+++ b/arch/ppc/platforms/radstone_ppc7d.c
@@ -40,6 +40,7 @@
40#include <linux/serial_core.h> 40#include <linux/serial_core.h>
41#include <linux/mv643xx.h> 41#include <linux/mv643xx.h>
42#include <linux/netdevice.h> 42#include <linux/netdevice.h>
43#include <linux/platform_device.h>
43 44
44#include <asm/system.h> 45#include <asm/system.h>
45#include <asm/pgtable.h> 46#include <asm/pgtable.h>
diff --git a/arch/ppc/syslib/mpc52xx_devices.c b/arch/ppc/syslib/mpc52xx_devices.c
index ad5182efca1d..da3c74bfdc92 100644
--- a/arch/ppc/syslib/mpc52xx_devices.c
+++ b/arch/ppc/syslib/mpc52xx_devices.c
@@ -15,6 +15,7 @@
15 15
16#include <linux/fsl_devices.h> 16#include <linux/fsl_devices.h>
17#include <linux/resource.h> 17#include <linux/resource.h>
18#include <linux/platform_device.h>
18#include <asm/mpc52xx.h> 19#include <asm/mpc52xx.h>
19#include <asm/ppc_sys.h> 20#include <asm/ppc_sys.h>
20 21
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
index a781c50d2f4c..94ea346b7b4b 100644
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -19,6 +19,7 @@
19#include <linux/string.h> 19#include <linux/string.h>
20#include <linux/spinlock.h> 20#include <linux/spinlock.h>
21#include <linux/mv643xx.h> 21#include <linux/mv643xx.h>
22#include <linux/platform_device.h>
22 23
23#include <asm/byteorder.h> 24#include <asm/byteorder.h>
24#include <asm/io.h> 25#include <asm/io.h>
diff --git a/arch/ppc/syslib/pq2_devices.c b/arch/ppc/syslib/pq2_devices.c
index 6f88ba93412b..e960fe935325 100644
--- a/arch/ppc/syslib/pq2_devices.c
+++ b/arch/ppc/syslib/pq2_devices.c
@@ -13,7 +13,7 @@
13 13
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/device.h> 16#include <linux/platform_device.h>
17#include <linux/ioport.h> 17#include <linux/ioport.h>
18#include <asm/cpm2.h> 18#include <asm/cpm2.h>
19#include <asm/irq.h> 19#include <asm/irq.h>
diff --git a/arch/sh/boards/superh/microdev/setup.c b/arch/sh/boards/superh/microdev/setup.c
index c18919941ec0..1c1d65fb12df 100644
--- a/arch/sh/boards/superh/microdev/setup.c
+++ b/arch/sh/boards/superh/microdev/setup.c
@@ -13,7 +13,7 @@
13 13
14#include <linux/config.h> 14#include <linux/config.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/device.h> 16#include <linux/platform_device.h>
17#include <linux/ioport.h> 17#include <linux/ioport.h>
18#include <asm/io.h> 18#include <asm/io.h>
19#include <asm/mach/irq.h> 19#include <asm/mach/irq.h>
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 1495007bf6c0..721e2601a75d 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -20,6 +20,7 @@
20#include "linux/ctype.h" 20#include "linux/ctype.h"
21#include "linux/bootmem.h" 21#include "linux/bootmem.h"
22#include "linux/ethtool.h" 22#include "linux/ethtool.h"
23#include "linux/platform_device.h"
23#include "asm/uaccess.h" 24#include "asm/uaccess.h"
24#include "user_util.h" 25#include "user_util.h"
25#include "kern_util.h" 26#include "kern_util.h"
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index f73134333f64..b2c86257b0f8 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -35,6 +35,7 @@
35#include "linux/blkpg.h" 35#include "linux/blkpg.h"
36#include "linux/genhd.h" 36#include "linux/genhd.h"
37#include "linux/spinlock.h" 37#include "linux/spinlock.h"
38#include "linux/platform_device.h"
38#include "asm/segment.h" 39#include "asm/segment.h"
39#include "asm/uaccess.h" 40#include "asm/uaccess.h"
40#include "asm/irq.h" 41#include "asm/irq.h"
diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c
index 498d7dced1f4..0682ffd38175 100644
--- a/arch/xtensa/platform-iss/network.c
+++ b/arch/xtensa/platform-iss/network.c
@@ -33,6 +33,7 @@
33#include <linux/ethtool.h> 33#include <linux/ethtool.h>
34#include <linux/rtnetlink.h> 34#include <linux/rtnetlink.h>
35#include <linux/timer.h> 35#include <linux/timer.h>
36#include <linux/platform_device.h>
36 37
37#include <xtensa/simcall.h> 38#include <xtensa/simcall.h>
38 39
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 08d9cc99c7de..d597c922af11 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -10,7 +10,7 @@
10 * information. 10 * information.
11 */ 11 */
12 12
13#include <linux/device.h> 13#include <linux/platform_device.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/dma-mapping.h> 16#include <linux/dma-mapping.h>
diff --git a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c
index 5281f8e70510..ecacca9c877e 100644
--- a/drivers/block/cfq-iosched.c
+++ b/drivers/block/cfq-iosched.c
@@ -2059,10 +2059,8 @@ static void cfq_put_cfqd(struct cfq_data *cfqd)
2059 if (!atomic_dec_and_test(&cfqd->ref)) 2059 if (!atomic_dec_and_test(&cfqd->ref))
2060 return; 2060 return;
2061 2061
2062 blk_put_queue(q);
2063
2064 cfq_shutdown_timer_wq(cfqd); 2062 cfq_shutdown_timer_wq(cfqd);
2065 q->elevator->elevator_data = NULL; 2063 blk_put_queue(q);
2066 2064
2067 mempool_destroy(cfqd->crq_pool); 2065 mempool_destroy(cfqd->crq_pool);
2068 kfree(cfqd->crq_hash); 2066 kfree(cfqd->crq_hash);
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 00895477155e..5eadbb9d4d71 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -177,7 +177,7 @@ static int print_unex = 1;
177#include <linux/interrupt.h> 177#include <linux/interrupt.h>
178#include <linux/init.h> 178#include <linux/init.h>
179#include <linux/devfs_fs_kernel.h> 179#include <linux/devfs_fs_kernel.h>
180#include <linux/device.h> 180#include <linux/platform_device.h>
181#include <linux/buffer_head.h> /* for invalidate_buffers() */ 181#include <linux/buffer_head.h> /* for invalidate_buffers() */
182 182
183/* 183/*
diff --git a/drivers/block/noop-iosched.c b/drivers/block/noop-iosched.c
index f56b8edb06e4..e54f006e7e60 100644
--- a/drivers/block/noop-iosched.c
+++ b/drivers/block/noop-iosched.c
@@ -9,6 +9,7 @@
9 9
10static void elevator_noop_add_request(request_queue_t *q, struct request *rq) 10static void elevator_noop_add_request(request_queue_t *q, struct request *rq)
11{ 11{
12 rq->flags |= REQ_NOMERGE;
12 elv_dispatch_add_tail(q, rq); 13 elv_dispatch_add_tail(q, rq);
13} 14}
14 15
diff --git a/drivers/char/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c
index 887b8b2d7882..d724c0de4f28 100644
--- a/drivers/char/s3c2410-rtc.c
+++ b/drivers/char/s3c2410-rtc.c
@@ -20,7 +20,7 @@
20#include <linux/fs.h> 20#include <linux/fs.h>
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/device.h> 23#include <linux/platform_device.h>
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/rtc.h> 25#include <linux/rtc.h>
26#include <linux/bcd.h> 26#include <linux/bcd.h>
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index f86c15587238..d05067dcea01 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -48,6 +48,7 @@
48#include <linux/dmi.h> 48#include <linux/dmi.h>
49#include <linux/err.h> 49#include <linux/err.h>
50#include <linux/kfifo.h> 50#include <linux/kfifo.h>
51#include <linux/platform_device.h>
51 52
52#include <asm/uaccess.h> 53#include <asm/uaccess.h>
53#include <asm/io.h> 54#include <asm/io.h>
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c
index eb7058cbf015..24355b23b2ca 100644
--- a/drivers/char/tb0219.c
+++ b/drivers/char/tb0219.c
@@ -17,7 +17,7 @@
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20#include <linux/device.h> 20#include <linux/platform_device.h>
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/module.h> 23#include <linux/module.h>
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
index 683278bc5241..94641085faf8 100644
--- a/drivers/char/vr41xx_giu.c
+++ b/drivers/char/vr41xx_giu.c
@@ -19,7 +19,7 @@
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 21 */
22#include <linux/device.h> 22#include <linux/platform_device.h>
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/fs.h> 24#include <linux/fs.h>
25#include <linux/init.h> 25#include <linux/init.h>
diff --git a/drivers/char/vr41xx_rtc.c b/drivers/char/vr41xx_rtc.c
index a6dbe4da030c..5e3292df69d8 100644
--- a/drivers/char/vr41xx_rtc.c
+++ b/drivers/char/vr41xx_rtc.c
@@ -17,7 +17,7 @@
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20#include <linux/device.h> 20#include <linux/platform_device.h>
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/ioport.h> 23#include <linux/ioport.h>
diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c
index 75ca84ed4adf..da631c114fd1 100644
--- a/drivers/char/watchdog/mpcore_wdt.c
+++ b/drivers/char/watchdog/mpcore_wdt.c
@@ -29,7 +29,7 @@
29#include <linux/reboot.h> 29#include <linux/reboot.h>
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/device.h> 32#include <linux/platform_device.h>
33 33
34#include <asm/hardware/arm_twd.h> 34#include <asm/hardware/arm_twd.h>
35#include <asm/uaccess.h> 35#include <asm/uaccess.h>
@@ -396,6 +396,7 @@ static int __devexit mpcore_wdt_remove(struct device *dev)
396} 396}
397 397
398static struct device_driver mpcore_wdt_driver = { 398static struct device_driver mpcore_wdt_driver = {
399 .owner = THIS_MODULE,
399 .name = "mpcore_wdt", 400 .name = "mpcore_wdt",
400 .bus = &platform_bus_type, 401 .bus = &platform_bus_type,
401 .probe = mpcore_wdt_probe, 402 .probe = mpcore_wdt_probe,
diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/char/watchdog/mv64x60_wdt.c
index 6d3ff0836c44..119b3c541d95 100644
--- a/drivers/char/watchdog/mv64x60_wdt.c
+++ b/drivers/char/watchdog/mv64x60_wdt.c
@@ -22,6 +22,8 @@
22#include <linux/miscdevice.h> 22#include <linux/miscdevice.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/watchdog.h> 24#include <linux/watchdog.h>
25#include <linux/platform_device.h>
26
25#include <asm/mv64x60.h> 27#include <asm/mv64x60.h>
26#include <asm/uaccess.h> 28#include <asm/uaccess.h>
27#include <asm/io.h> 29#include <asm/io.h>
@@ -211,6 +213,7 @@ static int __devexit mv64x60_wdt_remove(struct device *dev)
211} 213}
212 214
213static struct device_driver mv64x60_wdt_driver = { 215static struct device_driver mv64x60_wdt_driver = {
216 .owner = THIS_MODULE,
214 .name = MV64x60_WDT_NAME, 217 .name = MV64x60_WDT_NAME,
215 .bus = &platform_bus_type, 218 .bus = &platform_bus_type,
216 .probe = mv64x60_wdt_probe, 219 .probe = mv64x60_wdt_probe,
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index 5308e5c8f29a..d9ef55bdf88a 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Berkshire PCI-PC Watchdog Card Driver 2 * Berkshire PCI-PC Watchdog Card Driver
3 * 3 *
4 * (c) Copyright 2003 Wim Van Sebroeck <wim@iguana.be>. 4 * (c) Copyright 2003-2005 Wim Van Sebroeck <wim@iguana.be>.
5 * 5 *
6 * Based on source code of the following authors: 6 * Based on source code of the following authors:
7 * Ken Hollis <kenji@bitgate.com>, 7 * Ken Hollis <kenji@bitgate.com>,
@@ -21,7 +21,9 @@
21 */ 21 */
22 22
23/* 23/*
24 * A bells and whistles driver is available from http://www.pcwd.de/ 24 * A bells and whistles driver is available from:
25 * http://www.kernel.org/pub/linux/kernel/people/wim/pcwd/pcwd_pci/
26 *
25 * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/ 27 * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/
26 */ 28 */
27 29
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index b732020acadb..751cb77b0715 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -44,7 +44,7 @@
44#include <linux/watchdog.h> 44#include <linux/watchdog.h>
45#include <linux/fs.h> 45#include <linux/fs.h>
46#include <linux/init.h> 46#include <linux/init.h>
47#include <linux/device.h> 47#include <linux/platform_device.h>
48#include <linux/interrupt.h> 48#include <linux/interrupt.h>
49 49
50#include <asm/uaccess.h> 50#include <asm/uaccess.h>
@@ -497,6 +497,7 @@ static int s3c2410wdt_resume(struct device *dev)
497 497
498 498
499static struct device_driver s3c2410wdt_driver = { 499static struct device_driver s3c2410wdt_driver = {
500 .owner = THIS_MODULE,
500 .name = "s3c2410-wdt", 501 .name = "s3c2410-wdt",
501 .bus = &platform_bus_type, 502 .bus = &platform_bus_type,
502 .probe = s3c2410wdt_probe, 503 .probe = s3c2410wdt_probe,
diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c
index b5d821015421..d15ca9a3986f 100644
--- a/drivers/char/watchdog/w83627hf_wdt.c
+++ b/drivers/char/watchdog/w83627hf_wdt.c
@@ -359,5 +359,5 @@ module_exit(wdt_exit);
359 359
360MODULE_LICENSE("GPL"); 360MODULE_LICENSE("GPL");
361MODULE_AUTHOR("Pádraig Brady <P@draigBrady.com>"); 361MODULE_AUTHOR("Pádraig Brady <P@draigBrady.com>");
362MODULE_DESCRIPTION("w38627hf WDT driver"); 362MODULE_DESCRIPTION("w83627hf WDT driver");
363MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); 363MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/eisa/virtual_root.c b/drivers/eisa/virtual_root.c
index 15677f20bd85..0f97a0cb0ff4 100644
--- a/drivers/eisa/virtual_root.c
+++ b/drivers/eisa/virtual_root.c
@@ -9,7 +9,7 @@
9 9
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/device.h> 12#include <linux/platform_device.h>
13#include <linux/eisa.h> 13#include <linux/eisa.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/moduleparam.h> 15#include <linux/moduleparam.h>
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 955537fe9958..8ed6ddbb9c5d 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -20,7 +20,7 @@
20 * GNU General Public License for more details. 20 * GNU General Public License for more details.
21 */ 21 */
22 22
23#include <linux/device.h> 23#include <linux/platform_device.h>
24#include <linux/dma-mapping.h> 24#include <linux/dma-mapping.h>
25#include <linux/errno.h> 25#include <linux/errno.h>
26#include <linux/init.h> 26#include <linux/init.h>
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index 4f4ba9b6d182..125929c9048f 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -41,7 +41,7 @@
41#include <linux/string.h> 41#include <linux/string.h>
42#include <linux/errno.h> 42#include <linux/errno.h>
43#include <linux/blkdev.h> 43#include <linux/blkdev.h>
44#include <linux/device.h> 44#include <linux/platform_device.h>
45#include <linux/spinlock.h> 45#include <linux/spinlock.h>
46#include <linux/moduleparam.h> 46#include <linux/moduleparam.h>
47#include <linux/firmware.h> 47#include <linux/firmware.h>
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index 0015da5668a1..1e5dfc7805e2 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -27,7 +27,7 @@
27 */ 27 */
28 28
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/device.h> 30#include <linux/platform_device.h>
31#include <linux/input.h> 31#include <linux/input.h>
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/module.h> 33#include <linux/module.h>
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index 9888fae1f37a..cfae4ad00fae 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -11,7 +11,7 @@
11 * 11 *
12 * Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund 12 * Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund
13 * 13 *
14 * And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>, 14 * And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>,
15 * Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com> 15 * Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com>
16 * 16 *
17 * Major cleanup by Deepak Saxena <dsaxena@plexity.net>, 01/2005: 17 * Major cleanup by Deepak Saxena <dsaxena@plexity.net>, 01/2005:
@@ -35,7 +35,7 @@
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/errno.h> 36#include <linux/errno.h>
37#include <linux/sched.h> 37#include <linux/sched.h>
38#include <linux/device.h> 38#include <linux/platform_device.h>
39#include <linux/i2c.h> 39#include <linux/i2c.h>
40 40
41#include <asm/io.h> 41#include <asm/io.h>
@@ -184,7 +184,7 @@ iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap,
184 do { 184 do {
185 interrupted = wait_event_interruptible_timeout ( 185 interrupted = wait_event_interruptible_timeout (
186 iop3xx_adap->waitq, 186 iop3xx_adap->waitq,
187 (done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap) ,flags )), 187 (done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap) ,flags )),
188 1 * HZ; 188 1 * HZ;
189 ); 189 );
190 if ((rc = iop3xx_i2c_error(sr)) < 0) { 190 if ((rc = iop3xx_i2c_error(sr)) < 0) {
@@ -472,9 +472,10 @@ iop3xx_i2c_probe(struct device *dev)
472 goto release_region; 472 goto release_region;
473 } 473 }
474 474
475 res = request_irq(platform_get_irq(pdev, 0), iop3xx_i2c_irq_handler, 0, 475 ret = request_irq(platform_get_irq(pdev, 0), iop3xx_i2c_irq_handler, 0,
476 pdev->name, adapter_data); 476 pdev->name, adapter_data);
477 if (res) { 477
478 if (ret) {
478 ret = -EIO; 479 ret = -EIO;
479 goto unmap; 480 goto unmap;
480 } 481 }
diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c
index 4fdc02411609..03672c9ca409 100644
--- a/drivers/i2c/busses/i2c-isa.c
+++ b/drivers/i2c/busses/i2c-isa.c
@@ -38,6 +38,7 @@
38#include <linux/errno.h> 38#include <linux/errno.h>
39#include <linux/i2c.h> 39#include <linux/i2c.h>
40#include <linux/i2c-isa.h> 40#include <linux/i2c-isa.h>
41#include <linux/platform_device.h>
41 42
42static u32 isa_func(struct i2c_adapter *adapter); 43static u32 isa_func(struct i2c_adapter *adapter);
43 44
diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c
index 42016ee6ef13..64552a376f2d 100644
--- a/drivers/i2c/busses/i2c-ixp2000.c
+++ b/drivers/i2c/busses/i2c-ixp2000.c
@@ -28,7 +28,7 @@
28 28
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/device.h> 31#include <linux/platform_device.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/i2c.h> 33#include <linux/i2c.h>
34#include <linux/i2c-algo-bit.h> 34#include <linux/i2c-algo-bit.h>
diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c
index 69303ab65e04..cc652c350814 100644
--- a/drivers/i2c/busses/i2c-ixp4xx.c
+++ b/drivers/i2c/busses/i2c-ixp4xx.c
@@ -28,7 +28,7 @@
28 28
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/device.h> 31#include <linux/platform_device.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/i2c.h> 33#include <linux/i2c.h>
34#include <linux/i2c-algo-bit.h> 34#include <linux/i2c-algo-bit.h>
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 8491633005b8..65b939a059e9 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -19,6 +19,8 @@
19#include <linux/sched.h> 19#include <linux/sched.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/pci.h> 21#include <linux/pci.h>
22#include <linux/platform_device.h>
23
22#include <asm/io.h> 24#include <asm/io.h>
23#include <linux/fsl_devices.h> 25#include <linux/fsl_devices.h>
24#include <linux/i2c.h> 26#include <linux/i2c.h>
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index d0d2a6f1386e..6b48027b2ee3 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -17,6 +17,8 @@
17#include <linux/i2c.h> 17#include <linux/i2c.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/mv643xx.h> 19#include <linux/mv643xx.h>
20#include <linux/platform_device.h>
21
20#include <asm/io.h> 22#include <asm/io.h>
21 23
22/* Register defines */ 24/* Register defines */
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 44b595d90a4a..67ccbea24ba4 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -30,6 +30,7 @@
30#include <linux/errno.h> 30#include <linux/errno.h>
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/i2c-pxa.h> 32#include <linux/i2c-pxa.h>
33#include <linux/platform_device.h>
33 34
34#include <asm/hardware.h> 35#include <asm/hardware.h>
35#include <asm/irq.h> 36#include <asm/irq.h>
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 6ced28e90070..1b582262e677 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -33,7 +33,7 @@
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/errno.h> 34#include <linux/errno.h>
35#include <linux/err.h> 35#include <linux/err.h>
36#include <linux/device.h> 36#include <linux/platform_device.h>
37 37
38#include <asm/hardware.h> 38#include <asm/hardware.h>
39#include <asm/irq.h> 39#include <asm/irq.h>
@@ -918,8 +918,11 @@ static int __init i2c_adap_s3c_init(void)
918 int ret; 918 int ret;
919 919
920 ret = driver_register(&s3c2410_i2c_driver); 920 ret = driver_register(&s3c2410_i2c_driver);
921 if (ret == 0) 921 if (ret == 0) {
922 ret = driver_register(&s3c2440_i2c_driver); 922 ret = driver_register(&s3c2440_i2c_driver);
923 if (ret)
924 driver_unregister(&s3c2410_i2c_driver);
925 }
923 926
924 return ret; 927 return ret;
925} 928}
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c
index eaa4742e04fa..9dbb72fffbe2 100644
--- a/drivers/i2c/chips/isp1301_omap.c
+++ b/drivers/i2c/chips/isp1301_omap.c
@@ -27,7 +27,7 @@
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/interrupt.h> 29#include <linux/interrupt.h>
30#include <linux/device.h> 30#include <linux/platform_device.h>
31#include <linux/usb_ch9.h> 31#include <linux/usb_ch9.h>
32#include <linux/usb_gadget.h> 32#include <linux/usb_gadget.h>
33#include <linux/usb.h> 33#include <linux/usb.h>
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 02e335a04f09..82ea1b7ec914 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -30,6 +30,7 @@
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/idr.h> 31#include <linux/idr.h>
32#include <linux/seq_file.h> 32#include <linux/seq_file.h>
33#include <linux/platform_device.h>
33#include <asm/uaccess.h> 34#include <asm/uaccess.h>
34 35
35 36
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index ea14c8f1c82b..8af0bd1424d2 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -34,6 +34,7 @@
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/i2c.h> 35#include <linux/i2c.h>
36#include <linux/i2c-dev.h> 36#include <linux/i2c-dev.h>
37#include <linux/platform_device.h>
37#include <asm/uaccess.h> 38#include <asm/uaccess.h>
38 39
39static struct i2c_client i2cdev_client_template; 40static struct i2c_client i2cdev_client_template;
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index a4696cd0978c..9f2352bd8348 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -565,6 +565,7 @@ static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned lon
565 case EV_LED: bits = dev->ledbit; max = LED_MAX; break; 565 case EV_LED: bits = dev->ledbit; max = LED_MAX; break;
566 case EV_SND: bits = dev->sndbit; max = SND_MAX; break; 566 case EV_SND: bits = dev->sndbit; max = SND_MAX; break;
567 case EV_FF: bits = dev->ffbit; max = FF_MAX; break; 567 case EV_FF: bits = dev->ffbit; max = FF_MAX; break;
568 case EV_SW: bits = dev->swbit; max = SW_MAX; break;
568 default: return -EINVAL; 569 default: return -EINVAL;
569 } 570 }
570 bit_to_user(bits, max); 571 bit_to_user(bits, max);
@@ -579,6 +580,9 @@ static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned lon
579 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) 580 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
580 bit_to_user(dev->snd, SND_MAX); 581 bit_to_user(dev->snd, SND_MAX);
581 582
583 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
584 bit_to_user(dev->sw, SW_MAX);
585
582 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) { 586 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
583 int len; 587 int len;
584 if (!dev->name) return -ENOENT; 588 if (!dev->name) return -ENOENT;
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 3b1685ff9d10..1a1654caedd5 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -730,7 +730,7 @@ static void input_register_classdevice(struct input_dev *dev)
730 "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1); 730 "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
731 731
732 path = kobject_get_path(&dev->cdev.class->subsys.kset.kobj, GFP_KERNEL); 732 path = kobject_get_path(&dev->cdev.class->subsys.kset.kobj, GFP_KERNEL);
733 printk(KERN_INFO "input: %s/%s as %s\n", 733 printk(KERN_INFO "input: %s as %s/%s\n",
734 dev->name ? dev->name : "Unspecified device", 734 dev->name ? dev->name : "Unspecified device",
735 path ? path : "", dev->cdev.class_id); 735 path ? path : "", dev->cdev.class_id);
736 kfree(path); 736 kfree(path);
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 571a68691a4a..4a917748fd9f 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -13,11 +13,11 @@ menuconfig INPUT_KEYBOARD
13if INPUT_KEYBOARD 13if INPUT_KEYBOARD
14 14
15config KEYBOARD_ATKBD 15config KEYBOARD_ATKBD
16 tristate "AT keyboard" if !PC 16 tristate "AT keyboard" if !X86_PC
17 default y 17 default y
18 select SERIO 18 select SERIO
19 select SERIO_LIBPS2 19 select SERIO_LIBPS2
20 select SERIO_I8042 if PC 20 select SERIO_I8042 if X86_PC
21 select SERIO_GSCPS2 if GSC 21 select SERIO_GSCPS2 if GSC
22 help 22 help
23 Say Y here if you want to use a standard AT or PS/2 keyboard. Usually 23 Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
index 3210d298b3bc..d00d14bb637a 100644
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/device.h> 15#include <linux/platform_device.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/input.h> 17#include <linux/input.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
index 7f06780a437f..9481132532d0 100644
--- a/drivers/input/keyboard/lkkbd.c
+++ b/drivers/input/keyboard/lkkbd.c
@@ -441,7 +441,7 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
441 input_sync (lk->dev); 441 input_sync (lk->dev);
442 break; 442 break;
443 case LK_METRONOME: 443 case LK_METRONOME:
444 DBG (KERN_INFO "Got %#d and don't " 444 DBG (KERN_INFO "Got LK_METRONOME and don't "
445 "know how to handle...\n"); 445 "know how to handle...\n");
446 break; 446 break;
447 case LK_OUTPUT_ERROR: 447 case LK_OUTPUT_ERROR:
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
index cee9c734a048..0fa38a559cdf 100644
--- a/drivers/input/keyboard/spitzkbd.c
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/device.h> 15#include <linux/platform_device.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/input.h> 17#include <linux/input.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
index e34633c37fdd..68ac97f101b0 100644
--- a/drivers/input/misc/pcspkr.c
+++ b/drivers/input/misc/pcspkr.c
@@ -71,7 +71,7 @@ static int __init pcspkr_init(void)
71 return -ENOMEM; 71 return -ENOMEM;
72 72
73 pcspkr_dev->name = "PC Speaker"; 73 pcspkr_dev->name = "PC Speaker";
74 pcspkr_dev->name = "isa0061/input0"; 74 pcspkr_dev->phys = "isa0061/input0";
75 pcspkr_dev->id.bustype = BUS_ISA; 75 pcspkr_dev->id.bustype = BUS_ISA;
76 pcspkr_dev->id.vendor = 0x001f; 76 pcspkr_dev->id.vendor = 0x001f;
77 pcspkr_dev->id.product = 0x0001; 77 pcspkr_dev->id.product = 0x0001;
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 537154dd7a87..574b18a523af 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -17,7 +17,7 @@ config MOUSE_PS2
17 default y 17 default y
18 select SERIO 18 select SERIO
19 select SERIO_LIBPS2 19 select SERIO_LIBPS2
20 select SERIO_I8042 if PC 20 select SERIO_I8042 if X86_PC
21 select SERIO_GSCPS2 if GSC 21 select SERIO_GSCPS2 if GSC
22 ---help--- 22 ---help---
23 Say Y here if you have a PS/2 mouse connected to your system. This 23 Say Y here if you have a PS/2 mouse connected to your system. This
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
index dd0f5bd90241..4da6c86b5d76 100644
--- a/drivers/input/serio/ct82c710.c
+++ b/drivers/input/serio/ct82c710.c
@@ -37,6 +37,7 @@
37#include <linux/serio.h> 37#include <linux/serio.h>
38#include <linux/errno.h> 38#include <linux/errno.h>
39#include <linux/err.h> 39#include <linux/err.h>
40#include <linux/platform_device.h>
40 41
41#include <asm/io.h> 42#include <asm/io.h>
42 43
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 4bc40f159996..01e186422021 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -20,6 +20,7 @@
20#include <linux/serio.h> 20#include <linux/serio.h>
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/rcupdate.h> 22#include <linux/rcupdate.h>
23#include <linux/platform_device.h>
23 24
24#include <asm/io.h> 25#include <asm/io.h>
25 26
diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
index 9880fc145d90..d857f7081adb 100644
--- a/drivers/input/serio/maceps2.c
+++ b/drivers/input/serio/maceps2.c
@@ -14,7 +14,7 @@
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/ioport.h> 15#include <linux/ioport.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/device.h> 17#include <linux/platform_device.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/spinlock.h> 19#include <linux/spinlock.h>
20#include <linux/err.h> 20#include <linux/err.h>
diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
index 46093c507988..b44d255596c2 100644
--- a/drivers/input/serio/q40kbd.c
+++ b/drivers/input/serio/q40kbd.c
@@ -37,6 +37,7 @@
37#include <linux/interrupt.h> 37#include <linux/interrupt.h>
38#include <linux/err.h> 38#include <linux/err.h>
39#include <linux/bitops.h> 39#include <linux/bitops.h>
40#include <linux/platform_device.h>
40 41
41#include <asm/io.h> 42#include <asm/io.h>
42#include <asm/uaccess.h> 43#include <asm/uaccess.h>
diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c
index 106f5eefd89a..52c49258f8a4 100644
--- a/drivers/input/serio/rpckbd.c
+++ b/drivers/input/serio/rpckbd.c
@@ -34,6 +34,7 @@
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/serio.h> 35#include <linux/serio.h>
36#include <linux/err.h> 36#include <linux/err.h>
37#include <linux/platform_device.h>
37 38
38#include <asm/irq.h> 39#include <asm/irq.h>
39#include <asm/hardware.h> 40#include <asm/hardware.h>
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
index 0ba3e6562bff..15e88eeae8d6 100644
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -11,7 +11,7 @@
11 11
12 12
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/device.h> 14#include <linux/platform_device.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/input.h> 16#include <linux/input.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index cdb6d0283195..8f02c155fdc0 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -723,6 +723,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
723 723
724 sprintf(hid->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id); 724 sprintf(hid->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id);
725 725
726 hid->input = input_dev;
726 hid->id = default_id; 727 hid->id = default_id;
727 hid->original_handler_id = original_handler_id; 728 hid->original_handler_id = original_handler_id;
728 hid->current_handler_id = current_handler_id; 729 hid->current_handler_id = current_handler_id;
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c
index 720e7a326308..7daa0ed7331c 100644
--- a/drivers/mfd/mcp-sa11x0.c
+++ b/drivers/mfd/mcp-sa11x0.c
@@ -18,7 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/spinlock.h> 19#include <linux/spinlock.h>
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/device.h> 21#include <linux/platform_device.h>
22 22
23#include <asm/dma.h> 23#include <asm/dma.h>
24#include <asm/hardware.h> 24#include <asm/hardware.h>
diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c
index 46de5c940555..9c4dd682ac74 100644
--- a/drivers/misc/hdpuftrs/hdpu_cpustate.c
+++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c
@@ -21,7 +21,7 @@
21#include <linux/miscdevice.h> 21#include <linux/miscdevice.h>
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <linux/proc_fs.h> 23#include <linux/proc_fs.h>
24#include <linux/device.h> 24#include <linux/platform_device.h>
25#include <asm/uaccess.h> 25#include <asm/uaccess.h>
26#include <linux/hdpu_features.h> 26#include <linux/hdpu_features.h>
27 27
diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c
index c203b27269ea..165f3405df27 100644
--- a/drivers/misc/hdpuftrs/hdpu_nexus.c
+++ b/drivers/misc/hdpuftrs/hdpu_nexus.c
@@ -21,7 +21,7 @@
21#include <linux/hdpu_features.h> 21#include <linux/hdpu_features.h>
22#include <linux/pci.h> 22#include <linux/pci.h>
23 23
24#include <linux/device.h> 24#include <linux/platform_device.h>
25 25
26static int hdpu_nexus_probe(struct device *ddev); 26static int hdpu_nexus_probe(struct device *ddev);
27static int hdpu_nexus_remove(struct device *ddev); 27static int hdpu_nexus_remove(struct device *ddev);
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
index d575e3a018bc..f31e247b2cbe 100644
--- a/drivers/mmc/pxamci.c
+++ b/drivers/mmc/pxamci.c
@@ -20,7 +20,7 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/ioport.h> 22#include <linux/ioport.h>
23#include <linux/device.h> 23#include <linux/platform_device.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/dma-mapping.h> 26#include <linux/dma-mapping.h>
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index 3ace875decc4..942668e93a74 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -26,7 +26,7 @@
26#include <linux/moduleparam.h> 26#include <linux/moduleparam.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/ioport.h> 28#include <linux/ioport.h>
29#include <linux/device.h> 29#include <linux/platform_device.h>
30#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c
index 63104c73ca3c..bfe994e59265 100644
--- a/drivers/mtd/maps/bast-flash.c
+++ b/drivers/mtd/maps/bast-flash.c
@@ -34,7 +34,7 @@
34#include <linux/ioport.h> 34#include <linux/ioport.h>
35#include <linux/device.h> 35#include <linux/device.h>
36#include <linux/slab.h> 36#include <linux/slab.h>
37 37#include <linux/platform_device.h>
38#include <linux/mtd/mtd.h> 38#include <linux/mtd/mtd.h>
39#include <linux/mtd/map.h> 39#include <linux/mtd/map.h>
40#include <linux/mtd/partitions.h> 40#include <linux/mtd/partitions.h>
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c
index e39a98a0171c..d14a0185b8f4 100644
--- a/drivers/mtd/maps/integrator-flash.c
+++ b/drivers/mtd/maps/integrator-flash.c
@@ -32,7 +32,7 @@
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/ioport.h> 34#include <linux/ioport.h>
35#include <linux/device.h> 35#include <linux/platform_device.h>
36#include <linux/init.h> 36#include <linux/init.h>
37 37
38#include <linux/mtd/mtd.h> 38#include <linux/mtd/mtd.h>
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
index 1e5d6e1d05f3..00b9f67580f1 100644
--- a/drivers/mtd/maps/ixp2000.c
+++ b/drivers/mtd/maps/ixp2000.c
@@ -25,6 +25,7 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/ioport.h> 26#include <linux/ioport.h>
27#include <linux/device.h> 27#include <linux/device.h>
28#include <linux/platform_device.h>
28 29
29#include <linux/mtd/mtd.h> 30#include <linux/mtd/mtd.h>
30#include <linux/mtd/map.h> 31#include <linux/mtd/map.h>
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c
index da316e543237..733a9297a562 100644
--- a/drivers/mtd/maps/ixp4xx.c
+++ b/drivers/mtd/maps/ixp4xx.c
@@ -23,6 +23,7 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/ioport.h> 24#include <linux/ioport.h>
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/platform_device.h>
26 27
27#include <linux/mtd/mtd.h> 28#include <linux/mtd/mtd.h>
28#include <linux/mtd/map.h> 29#include <linux/mtd/map.h>
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
index fa84566245a7..7f370bb794fe 100644
--- a/drivers/mtd/maps/omap_nor.c
+++ b/drivers/mtd/maps/omap_nor.c
@@ -30,7 +30,7 @@
30 * 675 Mass Ave, Cambridge, MA 02139, USA. 30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 */ 31 */
32 32
33#include <linux/device.h> 33#include <linux/platform_device.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/types.h> 35#include <linux/types.h>
36#include <linux/kernel.h> 36#include <linux/kernel.h>
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
index a0577ea00c3c..104576b5be34 100644
--- a/drivers/mtd/maps/plat-ram.c
+++ b/drivers/mtd/maps/plat-ram.c
@@ -31,6 +31,7 @@
31#include <linux/ioport.h> 31#include <linux/ioport.h>
32#include <linux/device.h> 32#include <linux/device.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/platform_device.h>
34 35
35#include <linux/mtd/mtd.h> 36#include <linux/mtd/mtd.h>
36#include <linux/mtd/map.h> 37#include <linux/mtd/map.h>
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index c81bec7b14d5..c8d0da19d897 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -13,7 +13,7 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/errno.h> 14#include <linux/errno.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/device.h> 16#include <linux/platform_device.h>
17#include <linux/err.h> 17#include <linux/err.h>
18 18
19#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index b58ba236a9eb..2df5e47d1f5c 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -48,7 +48,7 @@
48#include <linux/kernel.h> 48#include <linux/kernel.h>
49#include <linux/string.h> 49#include <linux/string.h>
50#include <linux/ioport.h> 50#include <linux/ioport.h>
51#include <linux/device.h> 51#include <linux/platform_device.h>
52#include <linux/delay.h> 52#include <linux/delay.h>
53#include <linux/err.h> 53#include <linux/err.h>
54#include <linux/slab.h> 54#include <linux/slab.h>
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index 3d50e953faaa..877891a29aaa 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -26,11 +26,11 @@
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/crc32.h> 27#include <linux/crc32.h>
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include <linux/platform_device.h>
29 30
30#include <asm/system.h>
31#include <asm/irq.h>
32#include <asm/hardware.h> 31#include <asm/hardware.h>
33#include <asm/io.h> 32#include <asm/io.h>
33#include <asm/system.h>
34 34
35#define TX_BUFFERS 15 35#define TX_BUFFERS 15
36#define RX_BUFFERS 25 36#define RX_BUFFERS 25
@@ -280,10 +280,13 @@ static void am79c961_timer(unsigned long data)
280 lnkstat = read_ireg(dev->base_addr, ISALED0) & ISALED0_LNKST; 280 lnkstat = read_ireg(dev->base_addr, ISALED0) & ISALED0_LNKST;
281 carrier = netif_carrier_ok(dev); 281 carrier = netif_carrier_ok(dev);
282 282
283 if (lnkstat && !carrier) 283 if (lnkstat && !carrier) {
284 netif_carrier_on(dev); 284 netif_carrier_on(dev);
285 else if (!lnkstat && carrier) 285 printk("%s: link up\n", dev->name);
286 } else if (!lnkstat && carrier) {
286 netif_carrier_off(dev); 287 netif_carrier_off(dev);
288 printk("%s: link down\n", dev->name);
289 }
287 290
288 mod_timer(&priv->timer, jiffies + msecs_to_jiffies(500)); 291 mod_timer(&priv->timer, jiffies + msecs_to_jiffies(500));
289} 292}
@@ -665,17 +668,25 @@ static void __init am79c961_banner(void)
665 printk(KERN_INFO "%s", version); 668 printk(KERN_INFO "%s", version);
666} 669}
667 670
668static int __init am79c961_init(void) 671static int __init am79c961_probe(struct device *_dev)
669{ 672{
673 struct platform_device *pdev = to_platform_device(_dev);
674 struct resource *res;
670 struct net_device *dev; 675 struct net_device *dev;
671 struct dev_priv *priv; 676 struct dev_priv *priv;
672 int i, ret; 677 int i, ret;
673 678
679 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
680 if (!res)
681 return -ENODEV;
682
674 dev = alloc_etherdev(sizeof(struct dev_priv)); 683 dev = alloc_etherdev(sizeof(struct dev_priv));
675 ret = -ENOMEM; 684 ret = -ENOMEM;
676 if (!dev) 685 if (!dev)
677 goto out; 686 goto out;
678 687
688 SET_NETDEV_DEV(dev, &pdev->dev);
689
679 priv = netdev_priv(dev); 690 priv = netdev_priv(dev);
680 691
681 /* 692 /*
@@ -683,8 +694,8 @@ static int __init am79c961_init(void)
683 * The PNP initialisation should have been 694 * The PNP initialisation should have been
684 * done by the ether bootp loader. 695 * done by the ether bootp loader.
685 */ 696 */
686 dev->base_addr = 0x220; 697 dev->base_addr = res->start;
687 dev->irq = IRQ_EBSA110_ETHERNET; 698 dev->irq = platform_get_irq(pdev, 0);
688 699
689 ret = -ENODEV; 700 ret = -ENODEV;
690 if (!request_region(dev->base_addr, 0x18, dev->name)) 701 if (!request_region(dev->base_addr, 0x18, dev->name))
@@ -705,11 +716,11 @@ static int __init am79c961_init(void)
705 inb(dev->base_addr + 4) != 0x2b) 716 inb(dev->base_addr + 4) != 0x2b)
706 goto release; 717 goto release;
707 718
708 am79c961_banner();
709
710 for (i = 0; i < 6; i++) 719 for (i = 0; i < 6; i++)
711 dev->dev_addr[i] = inb(dev->base_addr + i * 2) & 0xff; 720 dev->dev_addr[i] = inb(dev->base_addr + i * 2) & 0xff;
712 721
722 am79c961_banner();
723
713 spin_lock_init(&priv->chip_lock); 724 spin_lock_init(&priv->chip_lock);
714 init_timer(&priv->timer); 725 init_timer(&priv->timer);
715 priv->timer.data = (unsigned long)dev; 726 priv->timer.data = (unsigned long)dev;
@@ -732,6 +743,7 @@ static int __init am79c961_init(void)
732 if (ret == 0) { 743 if (ret == 0) {
733 printk(KERN_INFO "%s: ether address ", dev->name); 744 printk(KERN_INFO "%s: ether address ", dev->name);
734 745
746 /* Retrive and print the ethernet address. */
735 for (i = 0; i < 6; i++) 747 for (i = 0; i < 6; i++)
736 printk (i == 5 ? "%02x\n" : "%02x:", dev->dev_addr[i]); 748 printk (i == 5 ? "%02x\n" : "%02x:", dev->dev_addr[i]);
737 749
@@ -746,4 +758,15 @@ out:
746 return ret; 758 return ret;
747} 759}
748 760
761static struct device_driver am79c961_driver = {
762 .name = "am79c961",
763 .bus = &platform_bus_type,
764 .probe = am79c961_probe,
765};
766
767static int __init am79c961_init(void)
768{
769 return driver_register(&am79c961_driver);
770}
771
749__initcall(am79c961_init); 772__initcall(am79c961_init);
diff --git a/drivers/net/arm/am79c961a.h b/drivers/net/arm/am79c961a.h
index 1e9b05050cbe..6a49ac7f6d46 100644
--- a/drivers/net/arm/am79c961a.h
+++ b/drivers/net/arm/am79c961a.h
@@ -143,6 +143,4 @@ struct dev_priv {
143 struct timer_list timer; 143 struct timer_list timer;
144}; 144};
145 145
146extern int am79c961_probe (struct net_device *dev);
147
148#endif 146#endif
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index c4aa5fe2840e..4d26e5e7d18b 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -254,7 +254,7 @@
254#include <linux/unistd.h> 254#include <linux/unistd.h>
255#include <linux/ctype.h> 255#include <linux/ctype.h>
256#include <linux/moduleparam.h> 256#include <linux/moduleparam.h>
257#include <linux/device.h> 257#include <linux/platform_device.h>
258#include <linux/bitops.h> 258#include <linux/bitops.h>
259 259
260#include <asm/uaccess.h> 260#include <asm/uaccess.h>
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index abce1f730d00..c0af6fb1fbba 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -66,6 +66,7 @@
66#include <linux/mii.h> 66#include <linux/mii.h>
67#include <linux/dm9000.h> 67#include <linux/dm9000.h>
68#include <linux/delay.h> 68#include <linux/delay.h>
69#include <linux/platform_device.h>
69 70
70#include <asm/delay.h> 71#include <asm/delay.h>
71#include <asm/irq.h> 72#include <asm/irq.h>
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index ae5a2ed3b264..962580f2c4ab 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -81,7 +81,7 @@
81#include <linux/if_vlan.h> 81#include <linux/if_vlan.h>
82#include <linux/spinlock.h> 82#include <linux/spinlock.h>
83#include <linux/mm.h> 83#include <linux/mm.h>
84#include <linux/device.h> 84#include <linux/platform_device.h>
85#include <linux/ip.h> 85#include <linux/ip.h>
86#include <linux/tcp.h> 86#include <linux/tcp.h>
87#include <linux/udp.h> 87#include <linux/udp.h>
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index 1eca1dbca7f1..5a74d3d3dbe1 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -33,6 +33,7 @@
33#include <linux/mm.h> 33#include <linux/mm.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/version.h> 35#include <linux/version.h>
36#include <linux/platform_device.h>
36#include <asm/ocp.h> 37#include <asm/ocp.h>
37#include <linux/crc32.h> 38#include <linux/crc32.h>
38#include <linux/mii.h> 39#include <linux/mii.h>
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index b886b07412a6..e1aa9910503b 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -22,6 +22,7 @@
22#include <linux/rtnetlink.h> 22#include <linux/rtnetlink.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/dma-mapping.h> 24#include <linux/dma-mapping.h>
25#include <linux/platform_device.h>
25#include <linux/pm.h> 26#include <linux/pm.h>
26 27
27#include <net/irda/irda.h> 28#include <net/irda/irda.h>
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index 06883309916d..76e0b9fb5e96 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -29,7 +29,7 @@
29#include <linux/rtnetlink.h> 29#include <linux/rtnetlink.h>
30#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/device.h> 32#include <linux/platform_device.h>
33#include <linux/dma-mapping.h> 33#include <linux/dma-mapping.h>
34 34
35#include <net/irda/irda.h> 35#include <net/irda/irda.h>
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index 140b7cdb1f7e..a1d207f2fa68 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -53,6 +53,7 @@
53#include <linux/rtnetlink.h> 53#include <linux/rtnetlink.h>
54#include <linux/serial_reg.h> 54#include <linux/serial_reg.h>
55#include <linux/dma-mapping.h> 55#include <linux/dma-mapping.h>
56#include <linux/platform_device.h>
56 57
57#include <asm/io.h> 58#include <asm/io.h>
58#include <asm/dma.h> 59#include <asm/dma.h>
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index 8423cb6875f0..a74a5cfaf5bc 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -33,7 +33,7 @@
33#include <linux/netdevice.h> 33#include <linux/netdevice.h>
34#include <linux/etherdevice.h> 34#include <linux/etherdevice.h>
35#include <linux/skbuff.h> 35#include <linux/skbuff.h>
36#include <linux/device.h> 36#include <linux/platform_device.h>
37#include <linux/dma-mapping.h> 37#include <linux/dma-mapping.h>
38 38
39#include <asm/bootinfo.h> 39#include <asm/bootinfo.h>
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
index 405e18365ede..e9c999d7eb39 100644
--- a/drivers/net/macsonic.c
+++ b/drivers/net/macsonic.c
@@ -47,7 +47,7 @@
47#include <linux/netdevice.h> 47#include <linux/netdevice.h>
48#include <linux/etherdevice.h> 48#include <linux/etherdevice.h>
49#include <linux/skbuff.h> 49#include <linux/skbuff.h>
50#include <linux/device.h> 50#include <linux/platform_device.h>
51#include <linux/dma-mapping.h> 51#include <linux/dma-mapping.h>
52 52
53#include <asm/bootinfo.h> 53#include <asm/bootinfo.h>
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
index f79f7ee72ab8..bbffb585b3b3 100644
--- a/drivers/net/mipsnet.c
+++ b/drivers/net/mipsnet.c
@@ -13,6 +13,7 @@
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/etherdevice.h> 14#include <linux/etherdevice.h>
15#include <linux/netdevice.h> 15#include <linux/netdevice.h>
16#include <linux/platform_device.h>
16#include <asm/io.h> 17#include <asm/io.h>
17#include <asm/mips-boards/simint.h> 18#include <asm/mips-boards/simint.h>
18 19
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 8fbba21d975b..71f2c6705bc3 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -39,6 +39,8 @@
39#include <linux/bitops.h> 39#include <linux/bitops.h>
40#include <linux/delay.h> 40#include <linux/delay.h>
41#include <linux/ethtool.h> 41#include <linux/ethtool.h>
42#include <linux/platform_device.h>
43
42#include <asm/io.h> 44#include <asm/io.h>
43#include <asm/types.h> 45#include <asm/types.h>
44#include <asm/pgtable.h> 46#include <asm/pgtable.h>
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index c573bb351d4c..74d5f1a6fdea 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -77,7 +77,7 @@ static const char version[] =
77#include <linux/errno.h> 77#include <linux/errno.h>
78#include <linux/ioport.h> 78#include <linux/ioport.h>
79#include <linux/crc32.h> 79#include <linux/crc32.h>
80#include <linux/device.h> 80#include <linux/platform_device.h>
81#include <linux/spinlock.h> 81#include <linux/spinlock.h>
82#include <linux/ethtool.h> 82#include <linux/ethtool.h>
83#include <linux/mii.h> 83#include <linux/mii.h>
diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c
index eb1423ede75c..d04c918ebef8 100644
--- a/drivers/net/tokenring/proteon.c
+++ b/drivers/net/tokenring/proteon.c
@@ -29,6 +29,7 @@ static const char version[] = "proteon.c: v1.00 02/01/2003 by Jochen Friedrich\n
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/netdevice.h> 30#include <linux/netdevice.h>
31#include <linux/trdevice.h> 31#include <linux/trdevice.h>
32#include <linux/platform_device.h>
32 33
33#include <asm/system.h> 34#include <asm/system.h>
34#include <asm/io.h> 35#include <asm/io.h>
diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c
index 3c7c66204f74..72cf708396be 100644
--- a/drivers/net/tokenring/skisa.c
+++ b/drivers/net/tokenring/skisa.c
@@ -36,6 +36,7 @@ static const char version[] = "skisa.c: v1.03 09/12/2002 by Jochen Friedrich\n";
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/netdevice.h> 37#include <linux/netdevice.h>
38#include <linux/trdevice.h> 38#include <linux/trdevice.h>
39#include <linux/platform_device.h>
39 40
40#include <asm/system.h> 41#include <asm/system.h>
41#include <asm/io.h> 42#include <asm/io.h>
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index ba48cef3a9dc..87302c548c24 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -42,7 +42,7 @@
42#include <linux/notifier.h> 42#include <linux/notifier.h>
43#include <linux/interrupt.h> 43#include <linux/interrupt.h>
44#include <linux/spinlock.h> 44#include <linux/spinlock.h>
45#include <linux/device.h> 45#include <linux/platform_device.h>
46 46
47#include <asm/io.h> 47#include <asm/io.h>
48#include <asm/irq.h> 48#include <asm/irq.h>
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
index b57a0b98b4d6..561706ba4499 100644
--- a/drivers/pcmcia/hd64465_ss.c
+++ b/drivers/pcmcia/hd64465_ss.c
@@ -37,7 +37,7 @@
37#include <asm/errno.h> 37#include <asm/errno.h>
38#include <linux/irq.h> 38#include <linux/irq.h>
39#include <linux/interrupt.h> 39#include <linux/interrupt.h>
40#include <linux/device.h> 40#include <linux/platform_device.h>
41 41
42#include <asm/io.h> 42#include <asm/io.h>
43#include <asm/hd64465/hd64465.h> 43#include <asm/hd64465/hd64465.h>
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 4a41f67d185d..7ce455d01cc9 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -47,7 +47,7 @@
47#include <linux/delay.h> 47#include <linux/delay.h>
48#include <linux/workqueue.h> 48#include <linux/workqueue.h>
49#include <linux/interrupt.h> 49#include <linux/interrupt.h>
50#include <linux/device.h> 50#include <linux/platform_device.h>
51#include <linux/bitops.h> 51#include <linux/bitops.h>
52#include <asm/irq.h> 52#include <asm/irq.h>
53#include <asm/io.h> 53#include <asm/io.h>
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index c6ed70ea4812..2c22b4b3619d 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -23,7 +23,7 @@
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/workqueue.h> 24#include <linux/workqueue.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/device.h> 26#include <linux/platform_device.h>
27#include <linux/bitops.h> 27#include <linux/bitops.h>
28#include <asm/irq.h> 28#include <asm/irq.h>
29#include <asm/io.h> 29#include <asm/io.h>
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index 3397ff28de6a..356a6fb416a1 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -23,7 +23,7 @@
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/workqueue.h> 24#include <linux/workqueue.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/device.h> 26#include <linux/platform_device.h>
27#include <asm/irq.h> 27#include <asm/irq.h>
28#include <asm/io.h> 28#include <asm/io.h>
29#include <asm/bitops.h> 29#include <asm/bitops.h>
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index 2558c3cc91ec..47b5ade95bde 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -12,7 +12,7 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/device.h> 15#include <linux/platform_device.h>
16#include <linux/errno.h> 16#include <linux/errno.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index c2a12d53f6c7..7fa18fb814bc 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -23,6 +23,7 @@
23#include <linux/ioport.h> 23#include <linux/ioport.h>
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/spinlock.h> 25#include <linux/spinlock.h>
26#include <linux/platform_device.h>
26 27
27#include <asm/hardware.h> 28#include <asm/hardware.h>
28#include <asm/io.h> 29#include <asm/io.h>
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index bbe69b07ce50..5209d8c7764f 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -17,7 +17,7 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/errno.h> 18#include <linux/errno.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/device.h> 20#include <linux/platform_device.h>
21 21
22#include <pcmcia/ss.h> 22#include <pcmcia/ss.h>
23 23
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index bd924336a49f..fe5ea36e7de3 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -16,7 +16,7 @@
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/device.h> 19#include <linux/platform_device.h>
20 20
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
22#include <asm/hardware.h> 22#include <asm/hardware.h>
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index acf60ffc8a12..6d441ec75c6a 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -33,6 +33,7 @@
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/config.h> 35#include <linux/config.h>
36#include <linux/platform_device.h>
36 37
37#include <pcmcia/cs_types.h> 38#include <pcmcia/cs_types.h>
38#include <pcmcia/cs.h> 39#include <pcmcia/cs.h>
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index f158b67f6610..e31263864377 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -44,7 +44,7 @@
44#include <linux/ioport.h> 44#include <linux/ioport.h>
45#include <linux/delay.h> 45#include <linux/delay.h>
46#include <linux/workqueue.h> 46#include <linux/workqueue.h>
47#include <linux/device.h> 47#include <linux/platform_device.h>
48#include <linux/bitops.h> 48#include <linux/bitops.h>
49 49
50#include <asm/io.h> 50#include <asm/io.h>
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index 3d2dca675e02..38a028c725d4 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -24,6 +24,7 @@
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/sched.h> 25#include <linux/sched.h>
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/platform_device.h>
27 28
28#include <asm/io.h> 29#include <asm/io.h>
29 30
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index f24d84538fd5..71dd1ebbe58f 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -30,6 +30,7 @@
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/completion.h> 31#include <linux/completion.h>
32#include <linux/transport_class.h> 32#include <linux/transport_class.h>
33#include <linux/platform_device.h>
33 34
34#include <scsi/scsi_device.h> 35#include <scsi/scsi_device.h>
35#include <scsi/scsi_host.h> 36#include <scsi/scsi_host.h>
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 00d6a6657ebc..a440ea38efaa 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -180,12 +180,22 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
180 return; 180 return;
181 } 181 }
182 count = min(pc->sg->length - pc->b_count, bcount); 182 count = min(pc->sg->length - pc->b_count, bcount);
183 buf = kmap_atomic(pc->sg->page, KM_IRQ0); 183 if (PageHighMem(pc->sg->page)) {
184 drive->hwif->atapi_input_bytes(drive, 184 unsigned long flags;
185 buf + pc->b_count + pc->sg->offset, count); 185
186 kunmap_atomic(buf, KM_IRQ0); 186 local_irq_save(flags);
187 bcount -= count; 187 buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
188 pc->b_count += count; 188 pc->sg->offset;
189 drive->hwif->atapi_input_bytes(drive,
190 buf + pc->b_count, count);
191 kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
192 local_irq_restore(flags);
193 } else {
194 buf = page_address(pc->sg->page) + pc->sg->offset;
195 drive->hwif->atapi_input_bytes(drive,
196 buf + pc->b_count, count);
197 }
198 bcount -= count; pc->b_count += count;
189 if (pc->b_count == pc->sg->length) { 199 if (pc->b_count == pc->sg->length) {
190 pc->sg++; 200 pc->sg++;
191 pc->b_count = 0; 201 pc->b_count = 0;
@@ -205,12 +215,22 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
205 return; 215 return;
206 } 216 }
207 count = min(pc->sg->length - pc->b_count, bcount); 217 count = min(pc->sg->length - pc->b_count, bcount);
208 buf = kmap_atomic(pc->sg->page, KM_IRQ0); 218 if (PageHighMem(pc->sg->page)) {
209 drive->hwif->atapi_output_bytes(drive, 219 unsigned long flags;
210 buf + pc->b_count + pc->sg->offset, count); 220
211 kunmap_atomic(buf, KM_IRQ0); 221 local_irq_save(flags);
212 bcount -= count; 222 buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
213 pc->b_count += count; 223 pc->sg->offset;
224 drive->hwif->atapi_output_bytes(drive,
225 buf + pc->b_count, count);
226 kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
227 local_irq_restore(flags);
228 } else {
229 buf = page_address(pc->sg->page) + pc->sg->offset;
230 drive->hwif->atapi_output_bytes(drive,
231 buf + pc->b_count, count);
232 }
233 bcount -= count; pc->b_count += count;
214 if (pc->b_count == pc->sg->length) { 234 if (pc->b_count == pc->sg->length) {
215 pc->sg++; 235 pc->sg++;
216 pc->b_count = 0; 236 pc->b_count = 0;
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 8be7dc0b47b8..ff18fa7044c5 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -295,28 +295,6 @@ void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
295} 295}
296 296
297/** 297/**
298 * ata_exec - issue ATA command to host controller
299 * @ap: port to which command is being issued
300 * @tf: ATA taskfile register set
301 *
302 * Issues PIO/MMIO write to ATA command register, with proper
303 * synchronization with interrupt handler / other threads.
304 *
305 * LOCKING:
306 * Obtains host_set lock.
307 */
308
309static inline void ata_exec(struct ata_port *ap, const struct ata_taskfile *tf)
310{
311 unsigned long flags;
312
313 DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
314 spin_lock_irqsave(&ap->host_set->lock, flags);
315 ap->ops->exec_command(ap, tf);
316 spin_unlock_irqrestore(&ap->host_set->lock, flags);
317}
318
319/**
320 * ata_tf_to_host - issue ATA taskfile to host controller 298 * ata_tf_to_host - issue ATA taskfile to host controller
321 * @ap: port to which command is being issued 299 * @ap: port to which command is being issued
322 * @tf: ATA taskfile register set 300 * @tf: ATA taskfile register set
@@ -326,30 +304,11 @@ static inline void ata_exec(struct ata_port *ap, const struct ata_taskfile *tf)
326 * other threads. 304 * other threads.
327 * 305 *
328 * LOCKING: 306 * LOCKING:
329 * Obtains host_set lock.
330 */
331
332static void ata_tf_to_host(struct ata_port *ap, const struct ata_taskfile *tf)
333{
334 ap->ops->tf_load(ap, tf);
335
336 ata_exec(ap, tf);
337}
338
339/**
340 * ata_tf_to_host_nolock - issue ATA taskfile to host controller
341 * @ap: port to which command is being issued
342 * @tf: ATA taskfile register set
343 *
344 * Issues ATA taskfile register set to ATA host controller,
345 * with proper synchronization with interrupt handler and
346 * other threads.
347 *
348 * LOCKING:
349 * spin_lock_irqsave(host_set lock) 307 * spin_lock_irqsave(host_set lock)
350 */ 308 */
351 309
352void ata_tf_to_host_nolock(struct ata_port *ap, const struct ata_taskfile *tf) 310static inline void ata_tf_to_host(struct ata_port *ap,
311 const struct ata_taskfile *tf)
353{ 312{
354 ap->ops->tf_load(ap, tf); 313 ap->ops->tf_load(ap, tf);
355 ap->ops->exec_command(ap, tf); 314 ap->ops->exec_command(ap, tf);
@@ -1912,12 +1871,14 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
1912 * 1871 *
1913 * LOCKING: 1872 * LOCKING:
1914 * PCI/etc. bus probe sem. 1873 * PCI/etc. bus probe sem.
1874 * Obtains host_set lock.
1915 * 1875 *
1916 */ 1876 */
1917 1877
1918static unsigned int ata_bus_edd(struct ata_port *ap) 1878static unsigned int ata_bus_edd(struct ata_port *ap)
1919{ 1879{
1920 struct ata_taskfile tf; 1880 struct ata_taskfile tf;
1881 unsigned long flags;
1921 1882
1922 /* set up execute-device-diag (bus reset) taskfile */ 1883 /* set up execute-device-diag (bus reset) taskfile */
1923 /* also, take interrupts to a known state (disabled) */ 1884 /* also, take interrupts to a known state (disabled) */
@@ -1928,7 +1889,9 @@ static unsigned int ata_bus_edd(struct ata_port *ap)
1928 tf.protocol = ATA_PROT_NODATA; 1889 tf.protocol = ATA_PROT_NODATA;
1929 1890
1930 /* do bus reset */ 1891 /* do bus reset */
1892 spin_lock_irqsave(&ap->host_set->lock, flags);
1931 ata_tf_to_host(ap, &tf); 1893 ata_tf_to_host(ap, &tf);
1894 spin_unlock_irqrestore(&ap->host_set->lock, flags);
1932 1895
1933 /* spec says at least 2ms. but who knows with those 1896 /* spec says at least 2ms. but who knows with those
1934 * crazy ATAPI devices... 1897 * crazy ATAPI devices...
@@ -3555,7 +3518,7 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc)
3555 3518
3556 switch (qc->tf.protocol) { 3519 switch (qc->tf.protocol) {
3557 case ATA_PROT_NODATA: 3520 case ATA_PROT_NODATA:
3558 ata_tf_to_host_nolock(ap, &qc->tf); 3521 ata_tf_to_host(ap, &qc->tf);
3559 break; 3522 break;
3560 3523
3561 case ATA_PROT_DMA: 3524 case ATA_PROT_DMA:
@@ -3566,20 +3529,20 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc)
3566 3529
3567 case ATA_PROT_PIO: /* load tf registers, initiate polling pio */ 3530 case ATA_PROT_PIO: /* load tf registers, initiate polling pio */
3568 ata_qc_set_polling(qc); 3531 ata_qc_set_polling(qc);
3569 ata_tf_to_host_nolock(ap, &qc->tf); 3532 ata_tf_to_host(ap, &qc->tf);
3570 ap->hsm_task_state = HSM_ST; 3533 ap->hsm_task_state = HSM_ST;
3571 queue_work(ata_wq, &ap->pio_task); 3534 queue_work(ata_wq, &ap->pio_task);
3572 break; 3535 break;
3573 3536
3574 case ATA_PROT_ATAPI: 3537 case ATA_PROT_ATAPI:
3575 ata_qc_set_polling(qc); 3538 ata_qc_set_polling(qc);
3576 ata_tf_to_host_nolock(ap, &qc->tf); 3539 ata_tf_to_host(ap, &qc->tf);
3577 queue_work(ata_wq, &ap->packet_task); 3540 queue_work(ata_wq, &ap->packet_task);
3578 break; 3541 break;
3579 3542
3580 case ATA_PROT_ATAPI_NODATA: 3543 case ATA_PROT_ATAPI_NODATA:
3581 ap->flags |= ATA_FLAG_NOINTR; 3544 ap->flags |= ATA_FLAG_NOINTR;
3582 ata_tf_to_host_nolock(ap, &qc->tf); 3545 ata_tf_to_host(ap, &qc->tf);
3583 queue_work(ata_wq, &ap->packet_task); 3546 queue_work(ata_wq, &ap->packet_task);
3584 break; 3547 break;
3585 3548
@@ -4126,8 +4089,6 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
4126 host->unique_id = ata_unique_id++; 4089 host->unique_id = ata_unique_id++;
4127 host->max_cmd_len = 12; 4090 host->max_cmd_len = 12;
4128 4091
4129 scsi_assign_lock(host, &host_set->lock);
4130
4131 ap->flags = ATA_FLAG_PORT_DISABLED; 4092 ap->flags = ATA_FLAG_PORT_DISABLED;
4132 ap->id = host->unique_id; 4093 ap->id = host->unique_id;
4133 ap->host = host; 4094 ap->host = host;
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 1e3792f86fcf..248baae96486 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -39,6 +39,7 @@
39#include <scsi/scsi.h> 39#include <scsi/scsi.h>
40#include "scsi.h" 40#include "scsi.h"
41#include <scsi/scsi_host.h> 41#include <scsi/scsi_host.h>
42#include <scsi/scsi_device.h>
42#include <linux/libata.h> 43#include <linux/libata.h>
43#include <linux/hdreg.h> 44#include <linux/hdreg.h>
44#include <asm/uaccess.h> 45#include <asm/uaccess.h>
@@ -2405,8 +2406,12 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
2405 struct ata_port *ap; 2406 struct ata_port *ap;
2406 struct ata_device *dev; 2407 struct ata_device *dev;
2407 struct scsi_device *scsidev = cmd->device; 2408 struct scsi_device *scsidev = cmd->device;
2409 struct Scsi_Host *shost = scsidev->host;
2408 2410
2409 ap = (struct ata_port *) &scsidev->host->hostdata[0]; 2411 ap = (struct ata_port *) &shost->hostdata[0];
2412
2413 spin_unlock(shost->host_lock);
2414 spin_lock(&ap->host_set->lock);
2410 2415
2411 ata_scsi_dump_cdb(ap, cmd); 2416 ata_scsi_dump_cdb(ap, cmd);
2412 2417
@@ -2429,6 +2434,8 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
2429 ata_scsi_translate(ap, dev, cmd, done, atapi_xlat); 2434 ata_scsi_translate(ap, dev, cmd, done, atapi_xlat);
2430 2435
2431out_unlock: 2436out_unlock:
2437 spin_unlock(&ap->host_set->lock);
2438 spin_lock(shost->host_lock);
2432 return 0; 2439 return 0;
2433} 2440}
2434 2441
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index 10ecd9e15e4f..fad051ca4672 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -48,7 +48,6 @@ extern int ata_qc_issue(struct ata_queued_cmd *qc);
48extern int ata_check_atapi_dma(struct ata_queued_cmd *qc); 48extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
49extern void ata_dev_select(struct ata_port *ap, unsigned int device, 49extern void ata_dev_select(struct ata_port *ap, unsigned int device,
50 unsigned int wait, unsigned int can_sleep); 50 unsigned int wait, unsigned int can_sleep);
51extern void ata_tf_to_host_nolock(struct ata_port *ap, const struct ata_taskfile *tf);
52extern void swap_buf_le16(u16 *buf, unsigned int buf_words); 51extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
53extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); 52extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg);
54extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); 53extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index afb7ddf200e0..f47d2c454e33 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -33,7 +33,7 @@
33#include <linux/sysrq.h> 33#include <linux/sysrq.h>
34#include <linux/mca.h> 34#include <linux/mca.h>
35#include <linux/delay.h> 35#include <linux/delay.h>
36#include <linux/device.h> 36#include <linux/platform_device.h>
37#include <linux/tty.h> 37#include <linux/tty.h>
38#include <linux/tty_flip.h> 38#include <linux/tty_flip.h>
39#include <linux/serial_reg.h> 39#include <linux/serial_reg.h>
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 5b3933b0c997..4a54ff584700 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -36,7 +36,7 @@
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/console.h> 37#include <linux/console.h>
38#include <linux/sysrq.h> 38#include <linux/sysrq.h>
39#include <linux/device.h> 39#include <linux/platform_device.h>
40#include <linux/tty.h> 40#include <linux/tty.h>
41#include <linux/tty_flip.h> 41#include <linux/tty_flip.h>
42#include <linux/serial_core.h> 42#include <linux/serial_core.h>
@@ -995,6 +995,7 @@ static int __init imx_serial_init(void)
995static void __exit imx_serial_exit(void) 995static void __exit imx_serial_exit(void)
996{ 996{
997 uart_unregister_driver(&imx_reg); 997 uart_unregister_driver(&imx_reg);
998 driver_unregister(&serial_imx_driver);
998} 999}
999 1000
1000module_init(imx_serial_init); 1001module_init(imx_serial_init);
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 8a79968f8ce1..0dd08a09e7e6 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -45,7 +45,7 @@
45 */ 45 */
46 46
47#include <linux/config.h> 47#include <linux/config.h>
48#include <linux/device.h> 48#include <linux/platform_device.h>
49#include <linux/module.h> 49#include <linux/module.h>
50#include <linux/tty.h> 50#include <linux/tty.h>
51#include <linux/serial.h> 51#include <linux/serial.h>
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index aec83f577ce6..ba8838b234da 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -52,6 +52,8 @@
52 * 4) AFAICT, hardware flow control isn't supported by the controller --MAG. 52 * 4) AFAICT, hardware flow control isn't supported by the controller --MAG.
53 */ 53 */
54 54
55#include <linux/platform_device.h>
56
55#include "mpsc.h" 57#include "mpsc.h"
56 58
57/* 59/*
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 8cc4cedadd99..16b2f9417af9 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -39,7 +39,7 @@
39#include <linux/circ_buf.h> 39#include <linux/circ_buf.h>
40#include <linux/delay.h> 40#include <linux/delay.h>
41#include <linux/interrupt.h> 41#include <linux/interrupt.h>
42#include <linux/device.h> 42#include <linux/platform_device.h>
43#include <linux/tty.h> 43#include <linux/tty.h>
44#include <linux/tty_flip.h> 44#include <linux/tty_flip.h>
45#include <linux/serial_core.h> 45#include <linux/serial_core.h>
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 06a17dff1a73..036792328d49 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -63,7 +63,7 @@
63 63
64#include <linux/module.h> 64#include <linux/module.h>
65#include <linux/ioport.h> 65#include <linux/ioport.h>
66#include <linux/device.h> 66#include <linux/platform_device.h>
67#include <linux/init.h> 67#include <linux/init.h>
68#include <linux/sysrq.h> 68#include <linux/sysrq.h>
69#include <linux/console.h> 69#include <linux/console.h>
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index c4a789e6af44..ed618cc7ae96 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -35,7 +35,7 @@
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/console.h> 36#include <linux/console.h>
37#include <linux/sysrq.h> 37#include <linux/sysrq.h>
38#include <linux/device.h> 38#include <linux/platform_device.h>
39#include <linux/tty.h> 39#include <linux/tty.h>
40#include <linux/tty_flip.h> 40#include <linux/tty_flip.h>
41#include <linux/serial_core.h> 41#include <linux/serial_core.h>
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index 2b623ab0e36e..01696b3e3f61 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -26,7 +26,7 @@
26#endif 26#endif
27 27
28#include <linux/console.h> 28#include <linux/console.h>
29#include <linux/device.h> 29#include <linux/platform_device.h>
30#include <linux/err.h> 30#include <linux/err.h>
31#include <linux/ioport.h> 31#include <linux/ioport.h>
32#include <linux/init.h> 32#include <linux/init.h>
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 02106bebd5c1..975ace3f5b1e 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -50,7 +50,7 @@
50#include <linux/list.h> 50#include <linux/list.h>
51#include <linux/interrupt.h> 51#include <linux/interrupt.h>
52#include <linux/version.h> 52#include <linux/version.h>
53 53#include <linux/platform_device.h>
54#include <linux/usb.h> 54#include <linux/usb.h>
55#include <linux/usb_gadget.h> 55#include <linux/usb_gadget.h>
56 56
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index 9b3673904daf..bc6269f10cbb 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -21,6 +21,8 @@
21 * 21 *
22 */ 22 */
23 23
24#include <linux/platform_device.h>
25
24#include "lh7a40x_udc.h" 26#include "lh7a40x_udc.h"
25 27
26//#define DEBUG printk 28//#define DEBUG printk
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 41c96b0afbb3..387692a3611e 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -38,7 +38,7 @@
38#include <linux/proc_fs.h> 38#include <linux/proc_fs.h>
39#include <linux/mm.h> 39#include <linux/mm.h>
40#include <linux/moduleparam.h> 40#include <linux/moduleparam.h>
41#include <linux/device.h> 41#include <linux/platform_device.h>
42#include <linux/usb_ch9.h> 42#include <linux/usb_ch9.h>
43#include <linux/usb_gadget.h> 43#include <linux/usb_gadget.h>
44#include <linux/usb_otg.h> 44#include <linux/usb_otg.h>
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index f83a9262f953..ee9cd7869d92 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -43,7 +43,7 @@
43#include <linux/interrupt.h> 43#include <linux/interrupt.h>
44#include <linux/proc_fs.h> 44#include <linux/proc_fs.h>
45#include <linux/mm.h> 45#include <linux/mm.h>
46#include <linux/device.h> 46#include <linux/platform_device.h>
47#include <linux/dma-mapping.h> 47#include <linux/dma-mapping.h>
48 48
49#include <asm/byteorder.h> 49#include <asm/byteorder.h>
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index ddb8fc591466..f9c3f5b8dd1c 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -70,6 +70,7 @@
70#include <linux/interrupt.h> 70#include <linux/interrupt.h>
71#include <linux/usb.h> 71#include <linux/usb.h>
72#include <linux/usb_isp116x.h> 72#include <linux/usb_isp116x.h>
73#include <linux/platform_device.h>
73 74
74#include <asm/io.h> 75#include <asm/io.h>
75#include <asm/irq.h> 76#include <asm/irq.h>
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
index a277e258eb6c..f0c78cf14b6c 100644
--- a/drivers/usb/host/ohci-au1xxx.c
+++ b/drivers/usb/host/ohci-au1xxx.c
@@ -18,6 +18,8 @@
18 * This file is licenced under the GPL. 18 * This file is licenced under the GPL.
19 */ 19 */
20 20
21#include <linux/platform_device.h>
22
21#include <asm/mach-au1x00/au1000.h> 23#include <asm/mach-au1x00/au1000.h>
22 24
23#define USBH_ENABLE_BE (1<<0) 25#define USBH_ENABLE_BE (1<<0)
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c
index 238fa4ade615..336c766c6e29 100644
--- a/drivers/usb/host/ohci-lh7a404.c
+++ b/drivers/usb/host/ohci-lh7a404.c
@@ -16,6 +16,8 @@
16 * This file is licenced under the GPL. 16 * This file is licenced under the GPL.
17 */ 17 */
18 18
19#include <linux/platform_device.h>
20
19#include <asm/hardware.h> 21#include <asm/hardware.h>
20 22
21 23
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 49815ec4b842..e46cc540cf4d 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/signal.h> /* SA_INTERRUPT */ 17#include <linux/signal.h> /* SA_INTERRUPT */
18#include <linux/jiffies.h> 18#include <linux/jiffies.h>
19#include <linux/platform_device.h>
19 20
20#include <asm/hardware.h> 21#include <asm/hardware.h>
21#include <asm/io.h> 22#include <asm/io.h>
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
index 4832e57ae579..92cf6f4a1374 100644
--- a/drivers/usb/host/ohci-ppc-soc.c
+++ b/drivers/usb/host/ohci-ppc-soc.c
@@ -14,6 +14,8 @@
14 * This file is licenced under the GPL. 14 * This file is licenced under the GPL.
15 */ 15 */
16 16
17#include <linux/platform_device.h>
18
17/* configure so an HC device and id are always provided */ 19/* configure so an HC device and id are always provided */
18/* always called with process context; sleeping is OK */ 20/* always called with process context; sleeping is OK */
19 21
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index f4a4aeda40b7..59e20568e8f9 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -21,6 +21,8 @@
21 21
22#include <linux/device.h> 22#include <linux/device.h>
23#include <linux/signal.h> 23#include <linux/signal.h>
24#include <linux/platform_device.h>
25
24#include <asm/mach-types.h> 26#include <asm/mach-types.h>
25#include <asm/hardware.h> 27#include <asm/hardware.h>
26#include <asm/arch/pxa-regs.h> 28#include <asm/arch/pxa-regs.h>
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index fab420a2ce71..ee1fc605b402 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -19,6 +19,8 @@
19 * This file is licenced under the GPL. 19 * This file is licenced under the GPL.
20*/ 20*/
21 21
22#include <linux/platform_device.h>
23
22#include <asm/hardware.h> 24#include <asm/hardware.h>
23#include <asm/hardware/clock.h> 25#include <asm/hardware/clock.h>
24#include <asm/arch/usb-control.h> 26#include <asm/arch/usb-control.h>
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index b7fd3f644e1e..b1aa350fd32f 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -138,11 +138,23 @@ reset_needed:
138} 138}
139EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); 139EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc);
140 140
141static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
142{
143 u16 cmd;
144 return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask);
145}
146
147#define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO)
148#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY)
149
141static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) 150static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
142{ 151{
143 unsigned long base = 0; 152 unsigned long base = 0;
144 int i; 153 int i;
145 154
155 if (!pio_enabled(pdev))
156 return;
157
146 for (i = 0; i < PCI_ROM_RESOURCE; i++) 158 for (i = 0; i < PCI_ROM_RESOURCE; i++)
147 if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) { 159 if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) {
148 base = pci_resource_start(pdev, i); 160 base = pci_resource_start(pdev, i);
@@ -153,12 +165,20 @@ static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev)
153 uhci_check_and_reset_hc(pdev, base); 165 uhci_check_and_reset_hc(pdev, base);
154} 166}
155 167
168static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx)
169{
170 return pci_resource_start(pdev, idx) && mmio_enabled(pdev);
171}
172
156static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) 173static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
157{ 174{
158 void __iomem *base; 175 void __iomem *base;
159 int wait_time; 176 int wait_time;
160 u32 control; 177 u32 control;
161 178
179 if (!mmio_resource_enabled(pdev, 0))
180 return;
181
162 base = ioremap_nocache(pci_resource_start(pdev, 0), 182 base = ioremap_nocache(pci_resource_start(pdev, 0),
163 pci_resource_len(pdev, 0)); 183 pci_resource_len(pdev, 0));
164 if (base == NULL) return; 184 if (base == NULL) return;
@@ -201,6 +221,9 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
201 u32 hcc_params, val, temp; 221 u32 hcc_params, val, temp;
202 u8 cap_length; 222 u8 cap_length;
203 223
224 if (!mmio_resource_enabled(pdev, 0))
225 return;
226
204 base = ioremap_nocache(pci_resource_start(pdev, 0), 227 base = ioremap_nocache(pci_resource_start(pdev, 0),
205 pci_resource_len(pdev, 0)); 228 pci_resource_len(pdev, 0));
206 if (base == NULL) return; 229 if (base == NULL) return;
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index 40169d9cf2b1..5607c0ae6835 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -54,6 +54,7 @@
54#include <linux/interrupt.h> 54#include <linux/interrupt.h>
55#include <linux/usb.h> 55#include <linux/usb.h>
56#include <linux/usb_sl811.h> 56#include <linux/usb_sl811.h>
57#include <linux/platform_device.h>
57 58
58#include <asm/io.h> 59#include <asm/io.h>
59#include <asm/irq.h> 60#include <asm/irq.h>
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index 38aebe361ca1..e73faf831b24 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -19,6 +19,7 @@
19#include <linux/string.h> 19#include <linux/string.h>
20#include <linux/timer.h> 20#include <linux/timer.h>
21#include <linux/ioport.h> 21#include <linux/ioport.h>
22#include <linux/platform_device.h>
22 23
23#include <pcmcia/cs_types.h> 24#include <pcmcia/cs_types.h>
24#include <pcmcia/cs.h> 25#include <pcmcia/cs.h>
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index f02965f39501..9b6a39348f81 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -26,7 +26,7 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/fb.h> 28#include <linux/fb.h>
29#include <linux/device.h> 29#include <linux/platform_device.h>
30#include <linux/dma-mapping.h> 30#include <linux/dma-mapping.h>
31 31
32#include <asm/hardware.h> 32#include <asm/hardware.h>
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index d28457e0c063..126daff1c848 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -47,6 +47,7 @@
47#include <linux/fb.h> 47#include <linux/fb.h>
48#include <linux/init.h> 48#include <linux/init.h>
49#include <linux/arcfb.h> 49#include <linux/arcfb.h>
50#include <linux/platform_device.h>
50 51
51#include <asm/uaccess.h> 52#include <asm/uaccess.h>
52 53
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
index 1991fdb32dfb..4867498f68e8 100644
--- a/drivers/video/backlight/corgi_bl.c
+++ b/drivers/video/backlight/corgi_bl.c
@@ -14,7 +14,7 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/device.h> 17#include <linux/platform_device.h>
18#include <linux/spinlock.h> 18#include <linux/spinlock.h>
19#include <linux/fb.h> 19#include <linux/fb.h>
20#include <linux/backlight.h> 20#include <linux/backlight.h>
diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c
index 1dbb82dca40b..1785686a7f11 100644
--- a/drivers/video/dnfb.c
+++ b/drivers/video/dnfb.c
@@ -6,6 +6,8 @@
6#include <linux/slab.h> 6#include <linux/slab.h>
7#include <linux/delay.h> 7#include <linux/delay.h>
8#include <linux/interrupt.h> 8#include <linux/interrupt.h>
9#include <linux/platform_device.h>
10
9#include <asm/setup.h> 11#include <asm/setup.h>
10#include <asm/system.h> 12#include <asm/system.h>
11#include <asm/irq.h> 13#include <asm/irq.h>
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 116e808d71cd..7363d0b25fdf 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -54,6 +54,8 @@
54#include <linux/fb.h> 54#include <linux/fb.h>
55#include <linux/init.h> 55#include <linux/init.h>
56#include <linux/ioport.h> 56#include <linux/ioport.h>
57#include <linux/platform_device.h>
58
57#include <asm/types.h> 59#include <asm/types.h>
58#include <asm/io.h> 60#include <asm/io.h>
59#include <asm/uaccess.h> 61#include <asm/uaccess.h>
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index 485604cd4462..316bfe994811 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -11,7 +11,7 @@
11 11
12#include <linux/config.h> 12#include <linux/config.h>
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/device.h> 14#include <linux/platform_device.h>
15#include <linux/dma-mapping.h> 15#include <linux/dma-mapping.h>
16#include <linux/errno.h> 16#include <linux/errno.h>
17#include <linux/fb.h> 17#include <linux/fb.h>
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 0b9301facbd3..64d9bcc38da3 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -31,7 +31,7 @@
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/ioport.h> 32#include <linux/ioport.h>
33#include <linux/cpufreq.h> 33#include <linux/cpufreq.h>
34#include <linux/device.h> 34#include <linux/platform_device.h>
35#include <linux/dma-mapping.h> 35#include <linux/dma-mapping.h>
36 36
37#include <asm/hardware.h> 37#include <asm/hardware.h>
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 6206da9dd5da..efd9333b05c2 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -36,7 +36,7 @@
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/ioport.h> 37#include <linux/ioport.h>
38#include <linux/cpufreq.h> 38#include <linux/cpufreq.h>
39#include <linux/device.h> 39#include <linux/platform_device.h>
40#include <linux/dma-mapping.h> 40#include <linux/dma-mapping.h>
41 41
42#include <asm/hardware.h> 42#include <asm/hardware.h>
diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c
index 162012bb9264..8416b2e2b501 100644
--- a/drivers/video/q40fb.c
+++ b/drivers/video/q40fb.c
@@ -18,6 +18,7 @@
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/delay.h> 19#include <linux/delay.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/platform_device.h>
21 22
22#include <asm/uaccess.h> 23#include <asm/uaccess.h>
23#include <asm/setup.h> 24#include <asm/setup.h>
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index cb2f7a1de947..f4437430dc5f 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -30,7 +30,7 @@
30 30
31#include <linux/config.h> 31#include <linux/config.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/device.h> 33#include <linux/platform_device.h>
34#include <linux/delay.h> 34#include <linux/delay.h>
35 35
36#include <linux/types.h> 36#include <linux/types.h>
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 3862d3cb1fb2..3cef90456a4b 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -86,6 +86,7 @@
86#include <linux/interrupt.h> 86#include <linux/interrupt.h>
87#include <linux/workqueue.h> 87#include <linux/workqueue.h>
88#include <linux/wait.h> 88#include <linux/wait.h>
89#include <linux/platform_device.h>
89 90
90#include <asm/io.h> 91#include <asm/io.h>
91#include <asm/uaccess.h> 92#include <asm/uaccess.h>
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 78e5f194b0df..3d35b28aaac7 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -173,7 +173,7 @@
173#include <linux/init.h> 173#include <linux/init.h>
174#include <linux/ioport.h> 174#include <linux/ioport.h>
175#include <linux/cpufreq.h> 175#include <linux/cpufreq.h>
176#include <linux/device.h> 176#include <linux/platform_device.h>
177#include <linux/dma-mapping.h> 177#include <linux/dma-mapping.h>
178 178
179#include <asm/hardware.h> 179#include <asm/hardware.h>
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index 8413907b379a..cf5106eab2d5 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -18,6 +18,8 @@
18#include <linux/fb.h> 18#include <linux/fb.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/ioport.h> 20#include <linux/ioport.h>
21#include <linux/platform_device.h>
22
21#include <asm/io.h> 23#include <asm/io.h>
22#include <asm/mtrr.h> 24#include <asm/mtrr.h>
23 25
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index b1243da55fc5..3cc23106641d 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -19,6 +19,8 @@
19#include <linux/fb.h> 19#include <linux/fb.h>
20#include <linux/ioport.h> 20#include <linux/ioport.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/platform_device.h>
23
22#include <video/vga.h> 24#include <video/vga.h>
23#include <asm/io.h> 25#include <asm/io.h>
24#include <asm/mtrr.h> 26#include <asm/mtrr.h>
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index b137a3fe0752..92d46555dd86 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -20,6 +20,8 @@
20#include <linux/vmalloc.h> 20#include <linux/vmalloc.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/platform_device.h>
24
23#include <asm/uaccess.h> 25#include <asm/uaccess.h>
24#include <linux/fb.h> 26#include <linux/fb.h>
25#include <linux/init.h> 27#include <linux/init.h>
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index 752bf88906a9..cf8cdb108fd9 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -25,7 +25,7 @@
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/device.h> 28#include <linux/platform_device.h>
29#include <linux/string.h> 29#include <linux/string.h>
30#include <linux/vmalloc.h> 30#include <linux/vmalloc.h>
31#include <asm/io.h> 31#include <asm/io.h>
diff --git a/fs/cifs/AUTHORS b/fs/cifs/AUTHORS
index 72fdc10dfdd7..8848e4dfa026 100644
--- a/fs/cifs/AUTHORS
+++ b/fs/cifs/AUTHORS
@@ -32,6 +32,10 @@ Domen Puncer
32Jesper Juhl (in particular for lots of whitespace/formatting cleanup) 32Jesper Juhl (in particular for lots of whitespace/formatting cleanup)
33Vince Negri and Dave Stahl (for finding an important caching bug) 33Vince Negri and Dave Stahl (for finding an important caching bug)
34Adrian Bunk (kcalloc cleanups) 34Adrian Bunk (kcalloc cleanups)
35Miklos Szeredi
36Kazeon team for various fixes especially for 2.4 version.
37Asser Ferno (Change Notify support)
38Shaggy (Dave Kleikamp) for inumerable small fs suggestions and some good cleanup
35 39
36Test case and Bug Report contributors 40Test case and Bug Report contributors
37------------------------------------- 41-------------------------------------
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 3196d4c4eed3..5bab24f59053 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,8 +1,52 @@
1Version 1.39
2------------
3Defer close of a file handle slightly if pending writes depend on that file handle
4(this reduces the EBADF bad file handle errors that can be logged under heavy
5stress on writes).
6
7Version 1.38
8------------
9Fix tcp socket retransmission timeouts (e.g. on ENOSPACE from the socket)
10to be smaller at first (but increasing) so large write performance performance
11over GigE is better. Do not hang thread on illegal byte range lock response
12from Windows (Windows can send an RFC1001 size which does not match smb size) by
13allowing an SMBs TCP length to be up to a few bytes longer than it should be.
14wsize and rsize can now be larger than negotiated buffer size if server
15supports large readx/writex, even when directio mount flag not specified.
16Write size will in many cases now be 16K instead of 4K which greatly helps
17file copy performance on lightly loaded networks. Fix oops in dnotify
18when experimental config flag enabled. Make cifsFYI more granular.
19
20Version 1.37
21------------
22Fix readdir caching when unlink removes file in current search buffer,
23and this is followed by a rewind search to just before the deleted entry.
24Do not attempt to set ctime unless atime and/or mtime change requested
25(most servers throw it away anyway). Fix length check of received smbs
26to be more accurate. Fix big endian problem with mapchars mount option,
27and with a field returned by statfs.
28
29Version 1.36
30------------
31Add support for mounting to older pre-CIFS servers such as Windows9x and ME.
32For these older servers, add option for passing netbios name of server in
33on mount (servernetbiosname). Add suspend support for power management, to
34avoid cifsd thread preventing software suspend from working.
35Add mount option for disabling the default behavior of sending byte range lock
36requests to the server (necessary for certain applications which break with
37mandatory lock behavior such as Evolution), and also mount option for
38requesting case insensitive matching for path based requests (requesting
39case sensitive is the default).
40
1Version 1.35 41Version 1.35
2------------ 42------------
3Add writepage performance improvements. Fix path name conversions 43Add writepage performance improvements. Fix path name conversions
4for long filenames on mounts which were done with "mapchars" mount option 44for long filenames on mounts which were done with "mapchars" mount option
5specified. 45specified. Ensure multiplex ids do not collide. Fix case in which
46rmmod can oops if done soon after last unmount. Fix truncated
47search (readdir) output when resume filename was a long filename.
48Fix filename conversion when mapchars mount option was specified and
49filename was a long filename.
6 50
7Version 1.34 51Version 1.34
8------------ 52------------
@@ -11,7 +55,7 @@ Do not oops if root user kills cifs oplock kernel thread or
11kills the cifsd thread (NB: killing the cifs kernel threads is not 55kills the cifsd thread (NB: killing the cifs kernel threads is not
12recommended, unmount and rmmod cifs will kill them when they are 56recommended, unmount and rmmod cifs will kill them when they are
13no longer needed). Fix readdir to ASCII servers (ie older servers 57no longer needed). Fix readdir to ASCII servers (ie older servers
14which do not support Unicode) and also require asterik. 58which do not support Unicode) and also require asterisk.
15Fix out of memory case in which data could be written one page 59Fix out of memory case in which data could be written one page
16off in the page cache. 60off in the page cache.
17 61
@@ -101,7 +145,7 @@ improperly zeroed buffer in CIFS Unix extensions set times call.
101 145
102Version 1.25 146Version 1.25
103------------ 147------------
104Fix internationlization problem in cifs readdir with filenames that map to 148Fix internationalization problem in cifs readdir with filenames that map to
105longer UTF8 strings than the string on the wire was in Unicode. Add workaround 149longer UTF8 strings than the string on the wire was in Unicode. Add workaround
106for readdir to netapp servers. Fix search rewind (seek into readdir to return 150for readdir to netapp servers. Fix search rewind (seek into readdir to return
107non-consecutive entries). Do not do readdir when server negotiates 151non-consecutive entries). Do not do readdir when server negotiates
@@ -276,7 +320,7 @@ Fix caching problem when files opened by multiple clients in which
276page cache could contain stale data, and write through did 320page cache could contain stale data, and write through did
277not occur often enough while file was still open when read ahead 321not occur often enough while file was still open when read ahead
278(read oplock) not allowed. Treat "sep=" when first mount option 322(read oplock) not allowed. Treat "sep=" when first mount option
279as an overrride of comma as the default separator between mount 323as an override of comma as the default separator between mount
280options. 324options.
281 325
282Version 1.01 326Version 1.01
@@ -286,7 +330,7 @@ Allow passwords longer than 16 bytes. Allow null password string.
286Version 1.00 330Version 1.00
287------------ 331------------
288Gracefully clean up failed mounts when attempting to mount to servers such as 332Gracefully clean up failed mounts when attempting to mount to servers such as
289Windows 98 that terminate tcp sessions during prototocol negotiation. Handle 333Windows 98 that terminate tcp sessions during protocol negotiation. Handle
290embedded commas in mount parsing of passwords. 334embedded commas in mount parsing of passwords.
291 335
292Version 0.99 336Version 0.99
@@ -295,7 +339,7 @@ Invalidate local inode cached pages on oplock break and when last file
295instance is closed so that the client does not continue using stale local 339instance is closed so that the client does not continue using stale local
296copy rather than later modified server copy of file. Do not reconnect 340copy rather than later modified server copy of file. Do not reconnect
297when server drops the tcp session prematurely before negotiate 341when server drops the tcp session prematurely before negotiate
298protocol response. Fix oops in roepen_file when dentry freed. Allow 342protocol response. Fix oops in reopen_file when dentry freed. Allow
299the support for CIFS Unix Extensions to be disabled via proc interface. 343the support for CIFS Unix Extensions to be disabled via proc interface.
300 344
301Version 0.98 345Version 0.98
@@ -637,7 +681,7 @@ versions of 2.4 kernel (now builds and works again on kernels at least as early
637Version 0.41 681Version 0.41
638------------ 682------------
639Various minor fixes for Connectathon Posix "basic" file i/o test suite. Directory caching fixed so hardlinked 683Various minor fixes for Connectathon Posix "basic" file i/o test suite. Directory caching fixed so hardlinked
640files now return the correct rumber of links on fstat as they are repeatedly linked and unlinked. 684files now return the correct number of links on fstat as they are repeatedly linked and unlinked.
641 685
642Version 0.40 686Version 0.40
643------------ 687------------
@@ -704,7 +748,7 @@ session)
704and cleaned them up and made them more consistent with other cifs functions. 748and cleaned them up and made them more consistent with other cifs functions.
705 749
7067) Server support for Unix extensions is now fully detected and FindFirst is implemented both ways 7507) Server support for Unix extensions is now fully detected and FindFirst is implemented both ways
707(with or without Unix exentions) but FindNext and QueryPathInfo with the Unix extensions are not completed, 751(with or without Unix extensions) but FindNext and QueryPathInfo with the Unix extensions are not completed,
708nor is the symlink support using the Unix extensions 752nor is the symlink support using the Unix extensions
709 753
7108) Started adding the readlink and follow_link code 7548) Started adding the readlink and follow_link code
diff --git a/fs/cifs/README b/fs/cifs/README
index 34b0cf7111f3..bb90941826ad 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -294,8 +294,10 @@ A partial list of the supported mount options follows:
294 during the local client kernel build will be used. 294 during the local client kernel build will be used.
295 If server does not support Unicode, this parameter is 295 If server does not support Unicode, this parameter is
296 unused. 296 unused.
297 rsize default read size 297 rsize default read size (usually 16K)
298 wsize default write size 298 wsize default write size (usually 16K, 32K is often better over GigE)
299 maximum wsize currently allowed by CIFS is 57344 (14 4096 byte
300 pages)
299 rw mount the network share read-write (note that the 301 rw mount the network share read-write (note that the
300 server may still consider the share read-only) 302 server may still consider the share read-only)
301 ro mount network share read-only 303 ro mount network share read-only
@@ -407,6 +409,13 @@ A partial list of the supported mount options follows:
407 This has no effect if the server does not support 409 This has no effect if the server does not support
408 Unicode on the wire. 410 Unicode on the wire.
409 nomapchars Do not translate any of these seven characters (default). 411 nomapchars Do not translate any of these seven characters (default).
412 nocase Request case insensitive path name matching (case
413 sensitive is the default if the server suports it).
414 nobrl Do not send byte range lock requests to the server.
415 This is necessary for certain applications that break
416 with cifs style mandatory byte range locks (and most
417 cifs servers do not yet support requesting advisory
418 byte range locks).
410 remount remount the share (often used to change from ro to rw mounts 419 remount remount the share (often used to change from ro to rw mounts
411 or vice versa) 420 or vice versa)
412 421
@@ -473,9 +482,16 @@ These experimental features and tracing can be enabled by changing flags in
473kernel, e.g. insmod cifs). To enable a feature set it to 1 e.g. to enable 482kernel, e.g. insmod cifs). To enable a feature set it to 1 e.g. to enable
474tracing to the kernel message log type: 483tracing to the kernel message log type:
475 484
476 echo 1 > /proc/fs/cifs/cifsFYI 485 echo 7 > /proc/fs/cifs/cifsFYI
477 486
478and for more extensive tracing including the start of smb requests and responses 487cifsFYI functions as a bit mask. Setting it to 1 enables additional kernel
488logging of various informational messages. 2 enables logging of non-zero
489SMB return codes while 4 enables logging of requests that take longer
490than one second to complete (except for byte range lock requests).
491Setting it to 4 requires defining CONFIG_CIFS_STATS2 manually in the
492source code (typically by setting it in the beginning of cifsglob.h),
493and setting it to seven enables all three. Finally, tracing
494the start of smb requests and responses can be enabled via:
479 495
480 echo 1 > /proc/fs/cifs/traceSMB 496 echo 1 > /proc/fs/cifs/traceSMB
481 497
diff --git a/fs/cifs/TODO b/fs/cifs/TODO
index 8cc881694e29..c909298d11ed 100644
--- a/fs/cifs/TODO
+++ b/fs/cifs/TODO
@@ -1,4 +1,4 @@
1version 1.34 April 29, 2005 1version 1.37 October 9, 2005
2 2
3A Partial List of Missing Features 3A Partial List of Missing Features
4================================== 4==================================
@@ -7,14 +7,14 @@ Contributions are welcome. There are plenty of opportunities
7for visible, important contributions to this module. Here 7for visible, important contributions to this module. Here
8is a partial list of the known problems and missing features: 8is a partial list of the known problems and missing features:
9 9
10a) Support for SecurityDescriptors for chmod/chgrp/chown so 10a) Support for SecurityDescriptors(Windows/CIFS ACLs) for chmod/chgrp/chown
11these can be supported for Windows servers 11so that these operations can be supported to Windows servers
12 12
13b) Better pam/winbind integration (e.g. to handle uid mapping 13b) Mapping POSIX ACLs (and eventually NFSv4 ACLs) to CIFS
14better) 14SecurityDescriptors
15 15
16c) multi-user mounts - multiplexed sessionsetups over single vc 16c) Better pam/winbind integration (e.g. to handle uid mapping
17(ie tcp session) - more testing needed 17better)
18 18
19d) Kerberos/SPNEGO session setup support - (started) 19d) Kerberos/SPNEGO session setup support - (started)
20 20
@@ -29,12 +29,17 @@ f) Directory entry caching relies on a 1 second timer, rather than
29using FindNotify or equivalent. - (started) 29using FindNotify or equivalent. - (started)
30 30
31g) A few byte range testcases fail due to POSIX vs. Windows/CIFS 31g) A few byte range testcases fail due to POSIX vs. Windows/CIFS
32style byte range lock differences 32style byte range lock differences. Save byte range locks so
33reconnect can replay them.
33 34
34h) quota support 35h) Support unlock all (unlock 0,MAX_OFFSET)
36by unlocking all known byte range locks that we locked on the file.
35 37
36j) finish writepages support (multi-page write behind for improved 38i) quota support (needs minor kernel change since quota calls
37performance) and syncpage 39to make it to network filesystems or deviceless filesystems)
40
41j) investigate sync behavior (including syncpage) and check
42for proper behavior of intr/nointr
38 43
39k) hook lower into the sockets api (as NFS/SunRPC does) to avoid the 44k) hook lower into the sockets api (as NFS/SunRPC does) to avoid the
40extra copy in/out of the socket buffers in some cases. 45extra copy in/out of the socket buffers in some cases.
@@ -57,20 +62,18 @@ p) Add support for storing symlink and fifo info to Windows servers
57in the Extended Attribute format their SFU clients would recognize. 62in the Extended Attribute format their SFU clients would recognize.
58 63
59q) Finish fcntl D_NOTIFY support so kde and gnome file list windows 64q) Finish fcntl D_NOTIFY support so kde and gnome file list windows
60will autorefresh (started) 65will autorefresh (partially complete by Asser). Needs minor kernel
66vfs change to support removing D_NOTIFY on a file.
61 67
62r) Add GUI tool to configure /proc/fs/cifs settings and for display of 68r) Add GUI tool to configure /proc/fs/cifs settings and for display of
63the CIFS statistics (started) 69the CIFS statistics (started)
64 70
65q) implement support for security and trusted categories of xattrs 71s) implement support for security and trusted categories of xattrs
66(requires minor protocol extension) to enable better support for SELINUX 72(requires minor protocol extension) to enable better support for SELINUX
67 73
68r) Implement O_DIRECT flag on open (already supported on mount) 74t) Implement O_DIRECT flag on open (already supported on mount)
69
70s) Allow remapping of last remaining character (\) to +0xF000 which
71(this character is valid for POSIX but not for Windows)
72 75
73t) Create UID mapping facility so server UIDs can be mapped on a per 76u) Create UID mapping facility so server UIDs can be mapped on a per
74mount or a per server basis to client UIDs or nobody if no mapping 77mount or a per server basis to client UIDs or nobody if no mapping
75exists. This is helpful when Unix extensions are negotiated to 78exists. This is helpful when Unix extensions are negotiated to
76allow better permission checking when UIDs differ on the server 79allow better permission checking when UIDs differ on the server
@@ -78,6 +81,17 @@ and client. Add new protocol request to the CIFS protocol
78standard for asking the server for the corresponding name of a 81standard for asking the server for the corresponding name of a
79particular uid. 82particular uid.
80 83
84v) Add support for CIFS Unix and also the newer POSIX extensions to the
85server side for Samba 4.
86
87w) Finish up the dos time conversion routines needed to return old server
88time to the client (default time, of now or time 0 is used now for these
89very old servers)
90
91x) Add support for OS/2 (LANMAN 1.2 and LANMAN2.1 based SMB servers)
92
93y) Finish testing of Windows 9x/Windows ME server support (started).
94
81KNOWN BUGS (updated April 29, 2005) 95KNOWN BUGS (updated April 29, 2005)
82==================================== 96====================================
83See http://bugzilla.samba.org - search on product "CifsVFS" for 97See http://bugzilla.samba.org - search on product "CifsVFS" for
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index e02010dd73ec..98539e2afe81 100644
--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -191,7 +191,8 @@ asn1_header_decode(struct asn1_ctx *ctx,
191 unsigned char **eoc, 191 unsigned char **eoc,
192 unsigned int *cls, unsigned int *con, unsigned int *tag) 192 unsigned int *cls, unsigned int *con, unsigned int *tag)
193{ 193{
194 unsigned int def, len; 194 unsigned int def = 0;
195 unsigned int len = 0;
195 196
196 if (!asn1_id_decode(ctx, cls, con, tag)) 197 if (!asn1_id_decode(ctx, cls, con, tag))
197 return 0; 198 return 0;
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 4061e43471c1..22a444a3fe4c 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -81,6 +81,8 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
81 buf += length; 81 buf += length;
82 length = sprintf(buf,"CIFS Version %s\n",CIFS_VERSION); 82 length = sprintf(buf,"CIFS Version %s\n",CIFS_VERSION);
83 buf += length; 83 buf += length;
84 length = sprintf(buf,"Active VFS Requests: %d\n", GlobalTotalActiveXid);
85 buf += length;
84 length = sprintf(buf, "Servers:"); 86 length = sprintf(buf, "Servers:");
85 buf += length; 87 buf += length;
86 88
@@ -97,7 +99,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
97 } else { 99 } else {
98 length = 100 length =
99 sprintf(buf, 101 sprintf(buf,
100 "\n%d) Name: %s Domain: %s Mounts: %d ServerOS: %s \n\tServerNOS: %s\tCapabilities: 0x%x\n\tSMB session status: %d\t", 102 "\n%d) Name: %s Domain: %s Mounts: %d OS: %s \n\tNOS: %s\tCapability: 0x%x\n\tSMB session status: %d\t",
101 i, ses->serverName, ses->serverDomain, 103 i, ses->serverName, ses->serverDomain,
102 atomic_read(&ses->inUse), 104 atomic_read(&ses->inUse),
103 ses->serverOS, ses->serverNOS, 105 ses->serverOS, ses->serverNOS,
@@ -105,12 +107,18 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
105 buf += length; 107 buf += length;
106 } 108 }
107 if(ses->server) { 109 if(ses->server) {
108 buf += sprintf(buf, "TCP status: %d\n\tLocal Users To Server: %d SecMode: 0x%x Req Active: %d", 110 buf += sprintf(buf, "TCP status: %d\n\tLocal Users To Server: %d SecMode: 0x%x Req On Wire: %d",
109 ses->server->tcpStatus, 111 ses->server->tcpStatus,
110 atomic_read(&ses->server->socketUseCount), 112 atomic_read(&ses->server->socketUseCount),
111 ses->server->secMode, 113 ses->server->secMode,
112 atomic_read(&ses->server->inFlight)); 114 atomic_read(&ses->server->inFlight));
113 115
116#ifdef CONFIG_CIFS_STATS2
117 buf += sprintf(buf, " In Send: %d In MaxReq Wait: %d",
118 atomic_read(&ses->server->inSend),
119 atomic_read(&ses->server->num_waiters));
120#endif
121
114 length = sprintf(buf, "\nMIDs:\n"); 122 length = sprintf(buf, "\nMIDs:\n");
115 buf += length; 123 buf += length;
116 124
@@ -149,7 +157,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
149 dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); 157 dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
150 length = 158 length =
151 sprintf(buf, 159 sprintf(buf,
152 "\n%d) %s Uses: %d Type: %s Characteristics: 0x%x Attributes: 0x%x\nPathComponentMax: %d Status: %d", 160 "\n%d) %s Uses: %d Type: %s DevInfo: 0x%x Attributes: 0x%x\nPathComponentMax: %d Status: %d",
153 i, tcon->treeName, 161 i, tcon->treeName,
154 atomic_read(&tcon->useCount), 162 atomic_read(&tcon->useCount),
155 tcon->nativeFileSystem, 163 tcon->nativeFileSystem,
@@ -195,6 +203,49 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
195} 203}
196 204
197#ifdef CONFIG_CIFS_STATS 205#ifdef CONFIG_CIFS_STATS
206
207static int
208cifs_stats_write(struct file *file, const char __user *buffer,
209 unsigned long count, void *data)
210{
211 char c;
212 int rc;
213 struct list_head *tmp;
214 struct cifsTconInfo *tcon;
215
216 rc = get_user(c, buffer);
217 if (rc)
218 return rc;
219
220 if (c == '1' || c == 'y' || c == 'Y' || c == '0') {
221 read_lock(&GlobalSMBSeslock);
222 list_for_each(tmp, &GlobalTreeConnectionList) {
223 tcon = list_entry(tmp, struct cifsTconInfo,
224 cifsConnectionList);
225 atomic_set(&tcon->num_smbs_sent, 0);
226 atomic_set(&tcon->num_writes, 0);
227 atomic_set(&tcon->num_reads, 0);
228 atomic_set(&tcon->num_oplock_brks, 0);
229 atomic_set(&tcon->num_opens, 0);
230 atomic_set(&tcon->num_closes, 0);
231 atomic_set(&tcon->num_deletes, 0);
232 atomic_set(&tcon->num_mkdirs, 0);
233 atomic_set(&tcon->num_rmdirs, 0);
234 atomic_set(&tcon->num_renames, 0);
235 atomic_set(&tcon->num_t2renames, 0);
236 atomic_set(&tcon->num_ffirst, 0);
237 atomic_set(&tcon->num_fnext, 0);
238 atomic_set(&tcon->num_fclose, 0);
239 atomic_set(&tcon->num_hardlinks, 0);
240 atomic_set(&tcon->num_symlinks, 0);
241 atomic_set(&tcon->num_locks, 0);
242 }
243 read_unlock(&GlobalSMBSeslock);
244 }
245
246 return count;
247}
248
198static int 249static int
199cifs_stats_read(char *buf, char **beginBuffer, off_t offset, 250cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
200 int count, int *eof, void *data) 251 int count, int *eof, void *data)
@@ -254,35 +305,51 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
254 buf += sprintf(buf, "\tDISCONNECTED "); 305 buf += sprintf(buf, "\tDISCONNECTED ");
255 length += 14; 306 length += 14;
256 } 307 }
257 item_length = sprintf(buf,"\nSMBs: %d Oplock Breaks: %d", 308 item_length = sprintf(buf, "\nSMBs: %d Oplock Breaks: %d",
258 atomic_read(&tcon->num_smbs_sent), 309 atomic_read(&tcon->num_smbs_sent),
259 atomic_read(&tcon->num_oplock_brks)); 310 atomic_read(&tcon->num_oplock_brks));
260 buf += item_length; 311 buf += item_length;
261 length += item_length; 312 length += item_length;
262 item_length = sprintf(buf,"\nReads: %d Bytes %lld", 313 item_length = sprintf(buf, "\nReads: %d Bytes: %lld",
263 atomic_read(&tcon->num_reads), 314 atomic_read(&tcon->num_reads),
264 (long long)(tcon->bytes_read)); 315 (long long)(tcon->bytes_read));
265 buf += item_length; 316 buf += item_length;
266 length += item_length; 317 length += item_length;
267 item_length = sprintf(buf,"\nWrites: %d Bytes: %lld", 318 item_length = sprintf(buf, "\nWrites: %d Bytes: %lld",
268 atomic_read(&tcon->num_writes), 319 atomic_read(&tcon->num_writes),
269 (long long)(tcon->bytes_written)); 320 (long long)(tcon->bytes_written));
321 buf += item_length;
322 length += item_length;
323 item_length = sprintf(buf,
324 "\nLocks: %d HardLinks: %d Symlinks: %d",
325 atomic_read(&tcon->num_locks),
326 atomic_read(&tcon->num_hardlinks),
327 atomic_read(&tcon->num_symlinks));
328 buf += item_length;
329 length += item_length;
330
331 item_length = sprintf(buf, "\nOpens: %d Closes: %d Deletes: %d",
332 atomic_read(&tcon->num_opens),
333 atomic_read(&tcon->num_closes),
334 atomic_read(&tcon->num_deletes));
270 buf += item_length; 335 buf += item_length;
271 length += item_length; 336 length += item_length;
272 item_length = sprintf(buf, 337 item_length = sprintf(buf, "\nMkdirs: %d Rmdirs: %d",
273 "\nOpens: %d Deletes: %d\nMkdirs: %d Rmdirs: %d",
274 atomic_read(&tcon->num_opens),
275 atomic_read(&tcon->num_deletes),
276 atomic_read(&tcon->num_mkdirs), 338 atomic_read(&tcon->num_mkdirs),
277 atomic_read(&tcon->num_rmdirs)); 339 atomic_read(&tcon->num_rmdirs));
278 buf += item_length; 340 buf += item_length;
279 length += item_length; 341 length += item_length;
280 item_length = sprintf(buf, 342 item_length = sprintf(buf, "\nRenames: %d T2 Renames %d",
281 "\nRenames: %d T2 Renames %d",
282 atomic_read(&tcon->num_renames), 343 atomic_read(&tcon->num_renames),
283 atomic_read(&tcon->num_t2renames)); 344 atomic_read(&tcon->num_t2renames));
284 buf += item_length; 345 buf += item_length;
285 length += item_length; 346 length += item_length;
347 item_length = sprintf(buf, "\nFindFirst: %d FNext %d FClose %d",
348 atomic_read(&tcon->num_ffirst),
349 atomic_read(&tcon->num_fnext),
350 atomic_read(&tcon->num_fclose));
351 buf += item_length;
352 length += item_length;
286 } 353 }
287 read_unlock(&GlobalSMBSeslock); 354 read_unlock(&GlobalSMBSeslock);
288 355
@@ -341,8 +408,10 @@ cifs_proc_init(void)
341 cifs_debug_data_read, NULL); 408 cifs_debug_data_read, NULL);
342 409
343#ifdef CONFIG_CIFS_STATS 410#ifdef CONFIG_CIFS_STATS
344 create_proc_read_entry("Stats", 0, proc_fs_cifs, 411 pde = create_proc_read_entry("Stats", 0, proc_fs_cifs,
345 cifs_stats_read, NULL); 412 cifs_stats_read, NULL);
413 if (pde)
414 pde->write_proc = cifs_stats_write;
346#endif 415#endif
347 pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs, 416 pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs,
348 cifsFYI_read, NULL); 417 cifsFYI_read, NULL);
@@ -360,7 +429,7 @@ cifs_proc_init(void)
360 if (pde) 429 if (pde)
361 pde->write_proc = oplockEnabled_write; 430 pde->write_proc = oplockEnabled_write;
362 431
363 pde = create_proc_read_entry("ReenableOldCifsReaddirCode", 0, proc_fs_cifs, 432 pde = create_proc_read_entry("Experimental", 0, proc_fs_cifs,
364 quotaEnabled_read, NULL); 433 quotaEnabled_read, NULL);
365 if (pde) 434 if (pde)
366 pde->write_proc = quotaEnabled_write; 435 pde->write_proc = quotaEnabled_write;
@@ -419,7 +488,7 @@ cifs_proc_clean(void)
419 remove_proc_entry("ExtendedSecurity",proc_fs_cifs); 488 remove_proc_entry("ExtendedSecurity",proc_fs_cifs);
420 remove_proc_entry("PacketSigningEnabled",proc_fs_cifs); 489 remove_proc_entry("PacketSigningEnabled",proc_fs_cifs);
421 remove_proc_entry("LinuxExtensionsEnabled",proc_fs_cifs); 490 remove_proc_entry("LinuxExtensionsEnabled",proc_fs_cifs);
422 remove_proc_entry("ReenableOldCifsReaddirCode",proc_fs_cifs); 491 remove_proc_entry("Experimental",proc_fs_cifs);
423 remove_proc_entry("LookupCacheEnabled",proc_fs_cifs); 492 remove_proc_entry("LookupCacheEnabled",proc_fs_cifs);
424 remove_proc_entry("cifs", proc_root_fs); 493 remove_proc_entry("cifs", proc_root_fs);
425} 494}
@@ -459,6 +528,8 @@ cifsFYI_write(struct file *file, const char __user *buffer,
459 cifsFYI = 0; 528 cifsFYI = 0;
460 else if (c == '1' || c == 'y' || c == 'Y') 529 else if (c == '1' || c == 'y' || c == 'Y')
461 cifsFYI = 1; 530 cifsFYI = 1;
531 else if((c > '1') && (c <= '9'))
532 cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */
462 533
463 return count; 534 return count;
464} 535}
diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h
index bf24d2828f68..4304d9dcfb6c 100644
--- a/fs/cifs/cifs_debug.h
+++ b/fs/cifs/cifs_debug.h
@@ -26,6 +26,9 @@
26void cifs_dump_mem(char *label, void *data, int length); 26void cifs_dump_mem(char *label, void *data, int length);
27extern int traceSMB; /* flag which enables the function below */ 27extern int traceSMB; /* flag which enables the function below */
28void dump_smb(struct smb_hdr *, int); 28void dump_smb(struct smb_hdr *, int);
29#define CIFS_INFO 0x01
30#define CIFS_RC 0x02
31#define CIFS_TIMER 0x04
29 32
30/* 33/*
31 * debug ON 34 * debug ON
@@ -36,7 +39,7 @@ void dump_smb(struct smb_hdr *, int);
36 39
37/* information message: e.g., configuration, major event */ 40/* information message: e.g., configuration, major event */
38extern int cifsFYI; 41extern int cifsFYI;
39#define cifsfyi(format,arg...) if (cifsFYI) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg) 42#define cifsfyi(format,arg...) if (cifsFYI & CIFS_INFO) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg)
40 43
41#define cFYI(button,prspec) if (button) cifsfyi prspec 44#define cFYI(button,prspec) if (button) cifsfyi prspec
42 45
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index ec00d61d5308..f799f6f0e729 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -24,6 +24,9 @@
24#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ 24#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */
25#define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ 25#define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */
26#define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ 26#define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */
27#define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */
28#define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */
29#define CIFS_MOUNT_NO_BRL 0x100 /* No sending byte range locks to srv */
27 30
28struct cifs_sb_info { 31struct cifs_sb_info {
29 struct cifsTconInfo *tcon; /* primary mount */ 32 struct cifsTconInfo *tcon; /* primary mount */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 1ebf7dafc1d7..877095a1192a 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -59,6 +59,8 @@ unsigned int ntlmv2_support = 0;
59unsigned int sign_CIFS_PDUs = 1; 59unsigned int sign_CIFS_PDUs = 1;
60extern struct task_struct * oplockThread; /* remove sparse warning */ 60extern struct task_struct * oplockThread; /* remove sparse warning */
61struct task_struct * oplockThread = NULL; 61struct task_struct * oplockThread = NULL;
62extern struct task_struct * dnotifyThread; /* remove sparse warning */
63struct task_struct * dnotifyThread = NULL;
62unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; 64unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
63module_param(CIFSMaxBufSize, int, 0); 65module_param(CIFSMaxBufSize, int, 0);
64MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048"); 66MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048");
@@ -73,6 +75,7 @@ module_param(cifs_max_pending, int, 0);
73MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256"); 75MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256");
74 76
75static DECLARE_COMPLETION(cifs_oplock_exited); 77static DECLARE_COMPLETION(cifs_oplock_exited);
78static DECLARE_COMPLETION(cifs_dnotify_exited);
76 79
77extern mempool_t *cifs_sm_req_poolp; 80extern mempool_t *cifs_sm_req_poolp;
78extern mempool_t *cifs_req_poolp; 81extern mempool_t *cifs_req_poolp;
@@ -202,6 +205,10 @@ cifs_statfs(struct super_block *sb, struct kstatfs *buf)
202#endif /* CIFS_EXPERIMENTAL */ 205#endif /* CIFS_EXPERIMENTAL */
203 rc = CIFSSMBQFSInfo(xid, pTcon, buf); 206 rc = CIFSSMBQFSInfo(xid, pTcon, buf);
204 207
208 /* Old Windows servers do not support level 103, retry with level
209 one if old server failed the previous call */
210 if(rc)
211 rc = SMBOldQFSInfo(xid, pTcon, buf);
205 /* 212 /*
206 int f_type; 213 int f_type;
207 __fsid_t f_fsid; 214 __fsid_t f_fsid;
@@ -253,7 +260,7 @@ cifs_alloc_inode(struct super_block *sb)
253 cifs_inode->clientCanCacheAll = FALSE; 260 cifs_inode->clientCanCacheAll = FALSE;
254 cifs_inode->vfs_inode.i_blksize = CIFS_MAX_MSGSIZE; 261 cifs_inode->vfs_inode.i_blksize = CIFS_MAX_MSGSIZE;
255 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ 262 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
256 263 cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;
257 INIT_LIST_HEAD(&cifs_inode->openFileList); 264 INIT_LIST_HEAD(&cifs_inode->openFileList);
258 return &cifs_inode->vfs_inode; 265 return &cifs_inode->vfs_inode;
259} 266}
@@ -398,6 +405,34 @@ static struct quotactl_ops cifs_quotactl_ops = {
398}; 405};
399#endif 406#endif
400 407
408static void cifs_umount_begin(struct super_block * sblock)
409{
410 struct cifs_sb_info *cifs_sb;
411 struct cifsTconInfo * tcon;
412
413 cifs_sb = CIFS_SB(sblock);
414 if(cifs_sb == NULL)
415 return;
416
417 tcon = cifs_sb->tcon;
418 if(tcon == NULL)
419 return;
420 down(&tcon->tconSem);
421 if (atomic_read(&tcon->useCount) == 1)
422 tcon->tidStatus = CifsExiting;
423 up(&tcon->tconSem);
424
425 if(tcon->ses && tcon->ses->server)
426 {
427 cERROR(1,("wake up tasks now - umount begin not complete"));
428 wake_up_all(&tcon->ses->server->request_q);
429 }
430/* BB FIXME - finish add checks for tidStatus BB */
431
432 return;
433}
434
435
401static int cifs_remount(struct super_block *sb, int *flags, char *data) 436static int cifs_remount(struct super_block *sb, int *flags, char *data)
402{ 437{
403 *flags |= MS_NODIRATIME; 438 *flags |= MS_NODIRATIME;
@@ -415,7 +450,7 @@ struct super_operations cifs_super_ops = {
415 unless later we add lazy close of inodes or unless the kernel forgets to call 450 unless later we add lazy close of inodes or unless the kernel forgets to call
416 us with the same number of releases (closes) as opens */ 451 us with the same number of releases (closes) as opens */
417 .show_options = cifs_show_options, 452 .show_options = cifs_show_options,
418/* .umount_begin = cifs_umount_begin, *//* consider adding in the future */ 453/* .umount_begin = cifs_umount_begin, */ /* BB finish in the future */
419 .remount_fs = cifs_remount, 454 .remount_fs = cifs_remount,
420}; 455};
421 456
@@ -783,9 +818,7 @@ static int cifs_oplock_thread(void * dummyarg)
783 do { 818 do {
784 if (try_to_freeze()) 819 if (try_to_freeze())
785 continue; 820 continue;
786 set_current_state(TASK_INTERRUPTIBLE);
787 821
788 schedule_timeout(1*HZ);
789 spin_lock(&GlobalMid_Lock); 822 spin_lock(&GlobalMid_Lock);
790 if(list_empty(&GlobalOplock_Q)) { 823 if(list_empty(&GlobalOplock_Q)) {
791 spin_unlock(&GlobalMid_Lock); 824 spin_unlock(&GlobalMid_Lock);
@@ -834,10 +867,27 @@ static int cifs_oplock_thread(void * dummyarg)
834 } 867 }
835 } else 868 } else
836 spin_unlock(&GlobalMid_Lock); 869 spin_unlock(&GlobalMid_Lock);
870 set_current_state(TASK_INTERRUPTIBLE);
871 schedule_timeout(1); /* yield in case q were corrupt */
837 } 872 }
838 } while(!signal_pending(current)); 873 } while(!signal_pending(current));
839 complete_and_exit (&cifs_oplock_exited, 0);
840 oplockThread = NULL; 874 oplockThread = NULL;
875 complete_and_exit (&cifs_oplock_exited, 0);
876}
877
878static int cifs_dnotify_thread(void * dummyarg)
879{
880 daemonize("cifsdnotifyd");
881 allow_signal(SIGTERM);
882
883 dnotifyThread = current;
884 do {
885 if(try_to_freeze())
886 continue;
887 set_current_state(TASK_INTERRUPTIBLE);
888 schedule_timeout(39*HZ);
889 } while(!signal_pending(current));
890 complete_and_exit (&cifs_dnotify_exited, 0);
841} 891}
842 892
843static int __init 893static int __init
@@ -851,6 +901,10 @@ init_cifs(void)
851 INIT_LIST_HEAD(&GlobalSMBSessionList); 901 INIT_LIST_HEAD(&GlobalSMBSessionList);
852 INIT_LIST_HEAD(&GlobalTreeConnectionList); 902 INIT_LIST_HEAD(&GlobalTreeConnectionList);
853 INIT_LIST_HEAD(&GlobalOplock_Q); 903 INIT_LIST_HEAD(&GlobalOplock_Q);
904#ifdef CONFIG_CIFS_EXPERIMENTAL
905 INIT_LIST_HEAD(&GlobalDnotifyReqList);
906 INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
907#endif
854/* 908/*
855 * Initialize Global counters 909 * Initialize Global counters
856 */ 910 */
@@ -886,10 +940,16 @@ init_cifs(void)
886 if (!rc) { 940 if (!rc) {
887 rc = (int)kernel_thread(cifs_oplock_thread, NULL, 941 rc = (int)kernel_thread(cifs_oplock_thread, NULL,
888 CLONE_FS | CLONE_FILES | CLONE_VM); 942 CLONE_FS | CLONE_FILES | CLONE_VM);
889 if(rc > 0) 943 if(rc > 0) {
890 return 0; 944 rc = (int)kernel_thread(cifs_dnotify_thread, NULL,
891 else 945 CLONE_FS | CLONE_FILES | CLONE_VM);
946 if(rc > 0)
947 return 0;
948 else
949 cERROR(1,("error %d create dnotify thread", rc));
950 } else {
892 cERROR(1,("error %d create oplock thread",rc)); 951 cERROR(1,("error %d create oplock thread",rc));
952 }
893 } 953 }
894 cifs_destroy_request_bufs(); 954 cifs_destroy_request_bufs();
895 } 955 }
@@ -918,6 +978,10 @@ exit_cifs(void)
918 send_sig(SIGTERM, oplockThread, 1); 978 send_sig(SIGTERM, oplockThread, 1);
919 wait_for_completion(&cifs_oplock_exited); 979 wait_for_completion(&cifs_oplock_exited);
920 } 980 }
981 if(dnotifyThread) {
982 send_sig(SIGTERM, dnotifyThread, 1);
983 wait_for_completion(&cifs_dnotify_exited);
984 }
921} 985}
922 986
923MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); 987MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 1fd21f66f243..1223fa81dbd2 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -81,6 +81,7 @@ extern int cifs_dir_notify(struct file *, unsigned long arg);
81 81
82/* Functions related to dir entries */ 82/* Functions related to dir entries */
83extern struct dentry_operations cifs_dentry_ops; 83extern struct dentry_operations cifs_dentry_ops;
84extern struct dentry_operations cifs_ci_dentry_ops;
84 85
85/* Functions related to symlinks */ 86/* Functions related to symlinks */
86extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd); 87extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
@@ -96,5 +97,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
96extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 97extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
97extern int cifs_ioctl (struct inode * inode, struct file * filep, 98extern int cifs_ioctl (struct inode * inode, struct file * filep,
98 unsigned int command, unsigned long arg); 99 unsigned int command, unsigned long arg);
99#define CIFS_VERSION "1.35" 100#define CIFS_VERSION "1.39"
100#endif /* _CIFSFS_H */ 101#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 81babab265e1..1ba08f8c5bc4 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -110,8 +110,9 @@ enum protocolEnum {
110 */ 110 */
111 111
112struct TCP_Server_Info { 112struct TCP_Server_Info {
113 char server_Name[SERVER_NAME_LEN_WITH_NULL]; /* 15 chars + X'20'in 16th */ 113 /* 15 character server name + 0x20 16th byte indicating type = srv */
114 char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2]; /* Unicode version of server_Name */ 114 char server_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
115 char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2];
115 struct socket *ssocket; 116 struct socket *ssocket;
116 union { 117 union {
117 struct sockaddr_in sockAddr; 118 struct sockaddr_in sockAddr;
@@ -122,13 +123,17 @@ struct TCP_Server_Info {
122 struct list_head pending_mid_q; 123 struct list_head pending_mid_q;
123 void *Server_NlsInfo; /* BB - placeholder for future NLS info */ 124 void *Server_NlsInfo; /* BB - placeholder for future NLS info */
124 unsigned short server_codepage; /* codepage for the server */ 125 unsigned short server_codepage; /* codepage for the server */
125 unsigned long ip_address; /* IP addr for the server if known */ 126 unsigned long ip_address; /* IP addr for the server if known */
126 enum protocolEnum protocolType; 127 enum protocolEnum protocolType;
127 char versionMajor; 128 char versionMajor;
128 char versionMinor; 129 char versionMinor;
129 unsigned svlocal:1; /* local server or remote */ 130 unsigned svlocal:1; /* local server or remote */
130 atomic_t socketUseCount; /* number of open cifs sessions on socket */ 131 atomic_t socketUseCount; /* number of open cifs sessions on socket */
131 atomic_t inFlight; /* number of requests on the wire to server */ 132 atomic_t inFlight; /* number of requests on the wire to server */
133#ifdef CONFIG_CIFS_STATS2
134 atomic_t inSend; /* requests trying to send */
135 atomic_t num_waiters; /* blocked waiting to get in sendrecv */
136#endif
132 enum statusEnum tcpStatus; /* what we think the status is */ 137 enum statusEnum tcpStatus; /* what we think the status is */
133 struct semaphore tcpSem; 138 struct semaphore tcpSem;
134 struct task_struct *tsk; 139 struct task_struct *tsk;
@@ -147,8 +152,10 @@ struct TCP_Server_Info {
147 /* (returned on Negotiate */ 152 /* (returned on Negotiate */
148 int capabilities; /* allow selective disabling of caps by smb sess */ 153 int capabilities; /* allow selective disabling of caps by smb sess */
149 __u16 timeZone; 154 __u16 timeZone;
155 __u16 CurrentMid; /* multiplex id - rotating counter */
150 char cryptKey[CIFS_CRYPTO_KEY_SIZE]; 156 char cryptKey[CIFS_CRYPTO_KEY_SIZE];
151 char workstation_RFC1001_name[16]; /* 16th byte is always zero */ 157 /* 16th byte of RFC1001 workstation name is always null */
158 char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
152 __u32 sequence_number; /* needed for CIFS PDU signature */ 159 __u32 sequence_number; /* needed for CIFS PDU signature */
153 char mac_signing_key[CIFS_SESSION_KEY_SIZE + 16]; 160 char mac_signing_key[CIFS_SESSION_KEY_SIZE + 16];
154}; 161};
@@ -214,19 +221,41 @@ struct cifsTconInfo {
214 atomic_t num_reads; 221 atomic_t num_reads;
215 atomic_t num_oplock_brks; 222 atomic_t num_oplock_brks;
216 atomic_t num_opens; 223 atomic_t num_opens;
224 atomic_t num_closes;
217 atomic_t num_deletes; 225 atomic_t num_deletes;
218 atomic_t num_mkdirs; 226 atomic_t num_mkdirs;
219 atomic_t num_rmdirs; 227 atomic_t num_rmdirs;
220 atomic_t num_renames; 228 atomic_t num_renames;
221 atomic_t num_t2renames; 229 atomic_t num_t2renames;
230 atomic_t num_ffirst;
231 atomic_t num_fnext;
232 atomic_t num_fclose;
233 atomic_t num_hardlinks;
234 atomic_t num_symlinks;
235 atomic_t num_locks;
236#ifdef CONFIG_CIFS_STATS2
237 unsigned long long time_writes;
238 unsigned long long time_reads;
239 unsigned long long time_opens;
240 unsigned long long time_deletes;
241 unsigned long long time_closes;
242 unsigned long long time_mkdirs;
243 unsigned long long time_rmdirs;
244 unsigned long long time_renames;
245 unsigned long long time_t2renames;
246 unsigned long long time_ffirst;
247 unsigned long long time_fnext;
248 unsigned long long time_fclose;
249#endif /* CONFIG_CIFS_STATS2 */
222 __u64 bytes_read; 250 __u64 bytes_read;
223 __u64 bytes_written; 251 __u64 bytes_written;
224 spinlock_t stat_lock; 252 spinlock_t stat_lock;
225#endif 253#endif /* CONFIG_CIFS_STATS */
226 FILE_SYSTEM_DEVICE_INFO fsDevInfo; 254 FILE_SYSTEM_DEVICE_INFO fsDevInfo;
227 FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if file system name truncated */ 255 FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if file system name truncated */
228 FILE_SYSTEM_UNIX_INFO fsUnixInfo; 256 FILE_SYSTEM_UNIX_INFO fsUnixInfo;
229 unsigned retry:1; 257 unsigned retry:1;
258 unsigned nocase:1;
230 /* BB add field for back pointer to sb struct? */ 259 /* BB add field for back pointer to sb struct? */
231}; 260};
232 261
@@ -270,6 +299,7 @@ struct cifsFileInfo {
270 struct inode * pInode; /* needed for oplock break */ 299 struct inode * pInode; /* needed for oplock break */
271 unsigned closePend:1; /* file is marked to close */ 300 unsigned closePend:1; /* file is marked to close */
272 unsigned invalidHandle:1; /* file closed via session abend */ 301 unsigned invalidHandle:1; /* file closed via session abend */
302 atomic_t wrtPending; /* handle in use - defer close */
273 struct semaphore fh_sem; /* prevents reopen race after dead ses*/ 303 struct semaphore fh_sem; /* prevents reopen race after dead ses*/
274 char * search_resume_name; /* BB removeme BB */ 304 char * search_resume_name; /* BB removeme BB */
275 unsigned int resume_name_length; /* BB removeme - field renamed and moved BB */ 305 unsigned int resume_name_length; /* BB removeme - field renamed and moved BB */
@@ -306,6 +336,41 @@ CIFS_SB(struct super_block *sb)
306 return sb->s_fs_info; 336 return sb->s_fs_info;
307} 337}
308 338
339static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
340{
341 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
342 return '/';
343 else
344 return '\\';
345}
346
347#ifdef CONFIG_CIFS_STATS
348#define cifs_stats_inc atomic_inc
349
350static inline void cifs_stats_bytes_written(struct cifsTconInfo *tcon,
351 unsigned int bytes)
352{
353 if (bytes) {
354 spin_lock(&tcon->stat_lock);
355 tcon->bytes_written += bytes;
356 spin_unlock(&tcon->stat_lock);
357 }
358}
359
360static inline void cifs_stats_bytes_read(struct cifsTconInfo *tcon,
361 unsigned int bytes)
362{
363 spin_lock(&tcon->stat_lock);
364 tcon->bytes_read += bytes;
365 spin_unlock(&tcon->stat_lock);
366}
367#else
368
369#define cifs_stats_inc(field) do {} while(0)
370#define cifs_stats_bytes_written(tcon, bytes) do {} while(0)
371#define cifs_stats_bytes_read(tcon, bytes) do {} while(0)
372
373#endif
309 374
310/* one of these for every pending CIFS request to the server */ 375/* one of these for every pending CIFS request to the server */
311struct mid_q_entry { 376struct mid_q_entry {
@@ -313,7 +378,11 @@ struct mid_q_entry {
313 __u16 mid; /* multiplex id */ 378 __u16 mid; /* multiplex id */
314 __u16 pid; /* process id */ 379 __u16 pid; /* process id */
315 __u32 sequence_number; /* for CIFS signing */ 380 __u32 sequence_number; /* for CIFS signing */
316 struct timeval when_sent; /* time when smb sent */ 381 unsigned long when_alloc; /* when mid was created */
382#ifdef CONFIG_CIFS_STATS2
383 unsigned long when_sent; /* time when smb send finished */
384 unsigned long when_received; /* when demux complete (taken off wire) */
385#endif
317 struct cifsSesInfo *ses; /* smb was sent to this server */ 386 struct cifsSesInfo *ses; /* smb was sent to this server */
318 struct task_struct *tsk; /* task waiting for response */ 387 struct task_struct *tsk; /* task waiting for response */
319 struct smb_hdr *resp_buf; /* response buffer */ 388 struct smb_hdr *resp_buf; /* response buffer */
@@ -331,6 +400,20 @@ struct oplock_q_entry {
331 __u16 netfid; 400 __u16 netfid;
332}; 401};
333 402
403/* for pending dnotify requests */
404struct dir_notify_req {
405 struct list_head lhead;
406 __le16 Pid;
407 __le16 PidHigh;
408 __u16 Mid;
409 __u16 Tid;
410 __u16 Uid;
411 __u16 netfid;
412 __u32 filter; /* CompletionFilter (for multishot) */
413 int multishot;
414 struct file * pfile;
415};
416
334#define MID_FREE 0 417#define MID_FREE 0
335#define MID_REQUEST_ALLOCATED 1 418#define MID_REQUEST_ALLOCATED 1
336#define MID_REQUEST_SUBMITTED 2 419#define MID_REQUEST_SUBMITTED 2
@@ -399,6 +482,9 @@ GLOBAL_EXTERN rwlock_t GlobalSMBSeslock; /* protects list inserts on 3 above */
399 482
400GLOBAL_EXTERN struct list_head GlobalOplock_Q; 483GLOBAL_EXTERN struct list_head GlobalOplock_Q;
401 484
485GLOBAL_EXTERN struct list_head GlobalDnotifyReqList; /* Outstanding dir notify requests */
486GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q; /* Dir notify response queue */
487
402/* 488/*
403 * Global transaction id (XID) information 489 * Global transaction id (XID) information
404 */ 490 */
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index aede6a813167..48a05b9df7eb 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -36,9 +36,11 @@
36#define SMB_COM_CLOSE 0x04 /* triv req/rsp, timestamp ignored */ 36#define SMB_COM_CLOSE 0x04 /* triv req/rsp, timestamp ignored */
37#define SMB_COM_DELETE 0x06 /* trivial response */ 37#define SMB_COM_DELETE 0x06 /* trivial response */
38#define SMB_COM_RENAME 0x07 /* trivial response */ 38#define SMB_COM_RENAME 0x07 /* trivial response */
39#define SMB_COM_QUERY_INFORMATION 0x08 /* aka getattr */
39#define SMB_COM_SETATTR 0x09 /* trivial response */ 40#define SMB_COM_SETATTR 0x09 /* trivial response */
40#define SMB_COM_LOCKING_ANDX 0x24 /* trivial response */ 41#define SMB_COM_LOCKING_ANDX 0x24 /* trivial response */
41#define SMB_COM_COPY 0x29 /* trivial rsp, fail filename ignrd*/ 42#define SMB_COM_COPY 0x29 /* trivial rsp, fail filename ignrd*/
43#define SMB_COM_OPEN_ANDX 0x2D /* Legacy open for old servers */
42#define SMB_COM_READ_ANDX 0x2E 44#define SMB_COM_READ_ANDX 0x2E
43#define SMB_COM_WRITE_ANDX 0x2F 45#define SMB_COM_WRITE_ANDX 0x2F
44#define SMB_COM_TRANSACTION2 0x32 46#define SMB_COM_TRANSACTION2 0x32
@@ -52,6 +54,7 @@
52#define SMB_COM_NT_TRANSACT 0xA0 54#define SMB_COM_NT_TRANSACT 0xA0
53#define SMB_COM_NT_TRANSACT_SECONDARY 0xA1 55#define SMB_COM_NT_TRANSACT_SECONDARY 0xA1
54#define SMB_COM_NT_CREATE_ANDX 0xA2 56#define SMB_COM_NT_CREATE_ANDX 0xA2
57#define SMB_COM_NT_CANCEL 0xA4 /* no response */
55#define SMB_COM_NT_RENAME 0xA5 /* trivial response */ 58#define SMB_COM_NT_RENAME 0xA5 /* trivial response */
56 59
57/* Transact2 subcommand codes */ 60/* Transact2 subcommand codes */
@@ -59,6 +62,7 @@
59#define TRANS2_FIND_FIRST 0x01 62#define TRANS2_FIND_FIRST 0x01
60#define TRANS2_FIND_NEXT 0x02 63#define TRANS2_FIND_NEXT 0x02
61#define TRANS2_QUERY_FS_INFORMATION 0x03 64#define TRANS2_QUERY_FS_INFORMATION 0x03
65#define TRANS2_SET_FS_INFORMATION 0x04
62#define TRANS2_QUERY_PATH_INFORMATION 0x05 66#define TRANS2_QUERY_PATH_INFORMATION 0x05
63#define TRANS2_SET_PATH_INFORMATION 0x06 67#define TRANS2_SET_PATH_INFORMATION 0x06
64#define TRANS2_QUERY_FILE_INFORMATION 0x07 68#define TRANS2_QUERY_FILE_INFORMATION 0x07
@@ -76,7 +80,7 @@
76#define NT_TRANSACT_GET_USER_QUOTA 0x07 80#define NT_TRANSACT_GET_USER_QUOTA 0x07
77#define NT_TRANSACT_SET_USER_QUOTA 0x08 81#define NT_TRANSACT_SET_USER_QUOTA 0x08
78 82
79#define MAX_CIFS_HDR_SIZE 256 /* chained NTCreateXReadX will probably be biggest */ 83#define MAX_CIFS_HDR_SIZE 256 /* is future chained NTCreateXReadX bigger? */
80 84
81/* internal cifs vfs structures */ 85/* internal cifs vfs structures */
82/***************************************************************** 86/*****************************************************************
@@ -129,10 +133,11 @@
129/* 133/*
130 * SMB flag definitions 134 * SMB flag definitions
131 */ 135 */
132#define SMBFLG_EXTD_LOCK 0x01 /* server supports lock-read write-unlock primitives */ 136#define SMBFLG_EXTD_LOCK 0x01 /* server supports lock-read write-unlock smb */
133#define SMBFLG_RCV_POSTED 0x02 /* obsolete */ 137#define SMBFLG_RCV_POSTED 0x02 /* obsolete */
134#define SMBFLG_RSVD 0x04 138#define SMBFLG_RSVD 0x04
135#define SMBFLG_CASELESS 0x08 /* all pathnames treated as caseless (off implies case sensitive file handling requested) */ 139#define SMBFLG_CASELESS 0x08 /* all pathnames treated as caseless (off
140 implies case sensitive file handling request) */
136#define SMBFLG_CANONICAL_PATH_FORMAT 0x10 /* obsolete */ 141#define SMBFLG_CANONICAL_PATH_FORMAT 0x10 /* obsolete */
137#define SMBFLG_OLD_OPLOCK 0x20 /* obsolete */ 142#define SMBFLG_OLD_OPLOCK 0x20 /* obsolete */
138#define SMBFLG_OLD_OPLOCK_NOTIFY 0x40 /* obsolete */ 143#define SMBFLG_OLD_OPLOCK_NOTIFY 0x40 /* obsolete */
@@ -141,7 +146,8 @@
141/* 146/*
142 * SMB flag2 definitions 147 * SMB flag2 definitions
143 */ 148 */
144#define SMBFLG2_KNOWS_LONG_NAMES cpu_to_le16(1) /* can send long (non-8.3) path names in response */ 149#define SMBFLG2_KNOWS_LONG_NAMES cpu_to_le16(1) /* can send long (non-8.3)
150 path names in response */
145#define SMBFLG2_KNOWS_EAS cpu_to_le16(2) 151#define SMBFLG2_KNOWS_EAS cpu_to_le16(2)
146#define SMBFLG2_SECURITY_SIGNATURE cpu_to_le16(4) 152#define SMBFLG2_SECURITY_SIGNATURE cpu_to_le16(4)
147#define SMBFLG2_IS_LONG_NAME cpu_to_le16(0x40) 153#define SMBFLG2_IS_LONG_NAME cpu_to_le16(0x40)
@@ -160,32 +166,32 @@
160 * file and can have any suitable combination of the following values: 166 * file and can have any suitable combination of the following values:
161 */ 167 */
162 168
163#define FILE_READ_DATA 0x00000001 /* Data can be read from the file */ 169#define FILE_READ_DATA 0x00000001 /* Data can be read from the file */
164#define FILE_WRITE_DATA 0x00000002 /* Data can be written to the file */ 170#define FILE_WRITE_DATA 0x00000002 /* Data can be written to the file */
165#define FILE_APPEND_DATA 0x00000004 /* Data can be appended to the file */ 171#define FILE_APPEND_DATA 0x00000004 /* Data can be appended to the file */
166#define FILE_READ_EA 0x00000008 /* Extended attributes associated */ 172#define FILE_READ_EA 0x00000008 /* Extended attributes associated */
167 /* with the file can be read */ 173 /* with the file can be read */
168#define FILE_WRITE_EA 0x00000010 /* Extended attributes associated */ 174#define FILE_WRITE_EA 0x00000010 /* Extended attributes associated */
169 /* with the file can be written */ 175 /* with the file can be written */
170#define FILE_EXECUTE 0x00000020 /*Data can be read into memory from */ 176#define FILE_EXECUTE 0x00000020 /*Data can be read into memory from */
171 /* the file using system paging I/O */ 177 /* the file using system paging I/O */
172#define FILE_DELETE_CHILD 0x00000040 178#define FILE_DELETE_CHILD 0x00000040
173#define FILE_READ_ATTRIBUTES 0x00000080 /* Attributes associated with the */ 179#define FILE_READ_ATTRIBUTES 0x00000080 /* Attributes associated with the */
174 /* file can be read */ 180 /* file can be read */
175#define FILE_WRITE_ATTRIBUTES 0x00000100 /* Attributes associated with the */ 181#define FILE_WRITE_ATTRIBUTES 0x00000100 /* Attributes associated with the */
176 /* file can be written */ 182 /* file can be written */
177#define DELETE 0x00010000 /* The file can be deleted */ 183#define DELETE 0x00010000 /* The file can be deleted */
178#define READ_CONTROL 0x00020000 /* The access control list and */ 184#define READ_CONTROL 0x00020000 /* The access control list and */
179 /* ownership associated with the */ 185 /* ownership associated with the */
180 /* file can be read */ 186 /* file can be read */
181#define WRITE_DAC 0x00040000 /* The access control list and */ 187#define WRITE_DAC 0x00040000 /* The access control list and */
182 /* ownership associated with the */ 188 /* ownership associated with the */
183 /* file can be written. */ 189 /* file can be written. */
184#define WRITE_OWNER 0x00080000 /* Ownership information associated */ 190#define WRITE_OWNER 0x00080000 /* Ownership information associated */
185 /* with the file can be written */ 191 /* with the file can be written */
186#define SYNCHRONIZE 0x00100000 /* The file handle can waited on to */ 192#define SYNCHRONIZE 0x00100000 /* The file handle can waited on to */
187 /* synchronize with the completion */ 193 /* synchronize with the completion */
188 /* of an input/output request */ 194 /* of an input/output request */
189#define GENERIC_ALL 0x10000000 195#define GENERIC_ALL 0x10000000
190#define GENERIC_EXECUTE 0x20000000 196#define GENERIC_EXECUTE 0x20000000
191#define GENERIC_WRITE 0x40000000 197#define GENERIC_WRITE 0x40000000
@@ -193,7 +199,7 @@
193 /* In summary - Relevant file */ 199 /* In summary - Relevant file */
194 /* access flags from CIFS are */ 200 /* access flags from CIFS are */
195 /* file_read_data, file_write_data */ 201 /* file_read_data, file_write_data */
196 /* file_execute, file_read_attributes */ 202 /* file_execute, file_read_attributes*/
197 /* write_dac, and delete. */ 203 /* write_dac, and delete. */
198 204
199/* 205/*
@@ -238,7 +244,8 @@
238#define ATTR_SPARSE 0x0200 244#define ATTR_SPARSE 0x0200
239#define ATTR_REPARSE 0x0400 245#define ATTR_REPARSE 0x0400
240#define ATTR_COMPRESSED 0x0800 246#define ATTR_COMPRESSED 0x0800
241#define ATTR_OFFLINE 0x1000 /* ie file not immediately available - offline storage */ 247#define ATTR_OFFLINE 0x1000 /* ie file not immediately available -
248 on offline storage */
242#define ATTR_NOT_CONTENT_INDEXED 0x2000 249#define ATTR_NOT_CONTENT_INDEXED 0x2000
243#define ATTR_ENCRYPTED 0x4000 250#define ATTR_ENCRYPTED 0x4000
244#define ATTR_POSIX_SEMANTICS 0x01000000 251#define ATTR_POSIX_SEMANTICS 0x01000000
@@ -267,10 +274,18 @@
267/* CreateOptions */ 274/* CreateOptions */
268#define CREATE_NOT_FILE 0x00000001 /* if set must not be file */ 275#define CREATE_NOT_FILE 0x00000001 /* if set must not be file */
269#define CREATE_WRITE_THROUGH 0x00000002 276#define CREATE_WRITE_THROUGH 0x00000002
270#define CREATE_NOT_DIR 0x00000040 /* if set must not be directory */ 277#define CREATE_SEQUENTIAL 0x00000004
278#define CREATE_SYNC_ALERT 0x00000010
279#define CREATE_ASYNC_ALERT 0x00000020
280#define CREATE_NOT_DIR 0x00000040 /* if set must not be directory */
281#define CREATE_NO_EA_KNOWLEDGE 0x00000200
282#define CREATE_EIGHT_DOT_THREE 0x00000400
271#define CREATE_RANDOM_ACCESS 0x00000800 283#define CREATE_RANDOM_ACCESS 0x00000800
272#define CREATE_DELETE_ON_CLOSE 0x00001000 284#define CREATE_DELETE_ON_CLOSE 0x00001000
285#define CREATE_OPEN_BY_ID 0x00002000
273#define OPEN_REPARSE_POINT 0x00200000 286#define OPEN_REPARSE_POINT 0x00200000
287#define CREATE_OPTIONS_MASK 0x007FFFFF
288#define CREATE_OPTION_SPECIAL 0x20000000 /* system. NB not sent over wire */
274 289
275/* ImpersonationLevel flags */ 290/* ImpersonationLevel flags */
276#define SECURITY_ANONYMOUS 0 291#define SECURITY_ANONYMOUS 0
@@ -297,10 +312,10 @@
297#define GETU16(var) (*((__u16 *)var)) /* BB check for endian issues */ 312#define GETU16(var) (*((__u16 *)var)) /* BB check for endian issues */
298#define GETU32(var) (*((__u32 *)var)) /* BB check for endian issues */ 313#define GETU32(var) (*((__u32 *)var)) /* BB check for endian issues */
299 314
300#pragma pack(1)
301
302struct smb_hdr { 315struct smb_hdr {
303 __u32 smb_buf_length; /* big endian on wire *//* BB length is only two or three bytes - with one or two byte type preceding it but that is always zero - we could mask the type byte off just in case BB */ 316 __u32 smb_buf_length; /* big endian on wire *//* BB length is only two
317 or three bytes - with one or two byte type preceding it that are
318 zero - we could mask the type byte off just in case BB */
304 __u8 Protocol[4]; 319 __u8 Protocol[4];
305 __u8 Command; 320 __u8 Command;
306 union { 321 union {
@@ -308,9 +323,9 @@ struct smb_hdr {
308 __u8 ErrorClass; 323 __u8 ErrorClass;
309 __u8 Reserved; 324 __u8 Reserved;
310 __le16 Error; 325 __le16 Error;
311 } DosError; 326 } __attribute__((packed)) DosError;
312 __le32 CifsError; 327 __le32 CifsError;
313 } Status; 328 } __attribute__((packed)) Status;
314 __u8 Flags; 329 __u8 Flags;
315 __le16 Flags2; /* note: le */ 330 __le16 Flags2; /* note: le */
316 __le16 PidHigh; 331 __le16 PidHigh;
@@ -318,16 +333,16 @@ struct smb_hdr {
318 struct { 333 struct {
319 __le32 SequenceNumber; /* le */ 334 __le32 SequenceNumber; /* le */
320 __u32 Reserved; /* zero */ 335 __u32 Reserved; /* zero */
321 } Sequence; 336 } __attribute__((packed)) Sequence;
322 __u8 SecuritySignature[8]; /* le */ 337 __u8 SecuritySignature[8]; /* le */
323 } Signature; 338 } __attribute__((packed)) Signature;
324 __u8 pad[2]; 339 __u8 pad[2];
325 __u16 Tid; 340 __u16 Tid;
326 __le16 Pid; 341 __le16 Pid;
327 __u16 Uid; 342 __u16 Uid;
328 __u16 Mid; 343 __u16 Mid;
329 __u8 WordCount; 344 __u8 WordCount;
330}; 345} __attribute__((packed));
331/* given a pointer to an smb_hdr retrieve the value of byte count */ 346/* given a pointer to an smb_hdr retrieve the value of byte count */
332#define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) ) 347#define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) )
333#define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) ) 348#define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) )
@@ -379,7 +394,7 @@ typedef struct negotiate_req {
379 struct smb_hdr hdr; /* wct = 0 */ 394 struct smb_hdr hdr; /* wct = 0 */
380 __le16 ByteCount; 395 __le16 ByteCount;
381 unsigned char DialectsArray[1]; 396 unsigned char DialectsArray[1];
382} NEGOTIATE_REQ; 397} __attribute__((packed)) NEGOTIATE_REQ;
383 398
384typedef struct negotiate_rsp { 399typedef struct negotiate_rsp {
385 struct smb_hdr hdr; /* wct = 17 */ 400 struct smb_hdr hdr; /* wct = 17 */
@@ -397,16 +412,16 @@ typedef struct negotiate_rsp {
397 __u8 EncryptionKeyLength; 412 __u8 EncryptionKeyLength;
398 __u16 ByteCount; 413 __u16 ByteCount;
399 union { 414 union {
400 unsigned char EncryptionKey[1]; /* if cap extended security is off */ 415 unsigned char EncryptionKey[1]; /* cap extended security off */
401 /* followed by Domain name - if extended security is off */ 416 /* followed by Domain name - if extended security is off */
402 /* followed by 16 bytes of server GUID */ 417 /* followed by 16 bytes of server GUID */
403 /* followed by security blob if cap_extended_security negotiated */ 418 /* then security blob if cap_extended_security negotiated */
404 struct { 419 struct {
405 unsigned char GUID[16]; 420 unsigned char GUID[16];
406 unsigned char SecurityBlob[1]; 421 unsigned char SecurityBlob[1];
407 } extended_response; 422 } __attribute__((packed)) extended_response;
408 } u; 423 } __attribute__((packed)) u;
409} NEGOTIATE_RSP; 424} __attribute__((packed)) NEGOTIATE_RSP;
410 425
411/* SecurityMode bits */ 426/* SecurityMode bits */
412#define SECMODE_USER 0x01 /* off indicates share level security */ 427#define SECMODE_USER 0x01 /* off indicates share level security */
@@ -452,7 +467,8 @@ typedef union smb_com_session_setup_andx {
452 unsigned char SecurityBlob[1]; /* followed by */ 467 unsigned char SecurityBlob[1]; /* followed by */
453 /* STRING NativeOS */ 468 /* STRING NativeOS */
454 /* STRING NativeLanMan */ 469 /* STRING NativeLanMan */
455 } req; /* NTLM request format (with extended security */ 470 } __attribute__((packed)) req; /* NTLM request format (with
471 extended security */
456 472
457 struct { /* request format */ 473 struct { /* request format */
458 struct smb_hdr hdr; /* wct = 13 */ 474 struct smb_hdr hdr; /* wct = 13 */
@@ -463,18 +479,19 @@ typedef union smb_com_session_setup_andx {
463 __le16 MaxMpxCount; 479 __le16 MaxMpxCount;
464 __le16 VcNumber; 480 __le16 VcNumber;
465 __u32 SessionKey; 481 __u32 SessionKey;
466 __le16 CaseInsensitivePasswordLength; /* ASCII password length */ 482 __le16 CaseInsensitivePasswordLength; /* ASCII password len */
467 __le16 CaseSensitivePasswordLength; /* Unicode password length */ 483 __le16 CaseSensitivePasswordLength; /* Unicode password length*/
468 __u32 Reserved; /* see below */ 484 __u32 Reserved; /* see below */
469 __le32 Capabilities; 485 __le32 Capabilities;
470 __le16 ByteCount; 486 __le16 ByteCount;
471 unsigned char CaseInsensitivePassword[1]; /* followed by: */ 487 unsigned char CaseInsensitivePassword[1]; /* followed by: */
472 /* unsigned char * CaseSensitivePassword; */ 488 /* unsigned char * CaseSensitivePassword; */
473 /* STRING AccountName */ 489 /* STRING AccountName */
474 /* STRING PrimaryDomain */ 490 /* STRING PrimaryDomain */
475 /* STRING NativeOS */ 491 /* STRING NativeOS */
476 /* STRING NativeLanMan */ 492 /* STRING NativeLanMan */
477 } req_no_secext; /* NTLM request format (without extended security */ 493 } __attribute__((packed)) req_no_secext; /* NTLM request format (without
494 extended security */
478 495
479 struct { /* default (NTLM) response format */ 496 struct { /* default (NTLM) response format */
480 struct smb_hdr hdr; /* wct = 4 */ 497 struct smb_hdr hdr; /* wct = 4 */
@@ -488,7 +505,7 @@ typedef union smb_com_session_setup_andx {
488/* unsigned char * NativeOS; */ 505/* unsigned char * NativeOS; */
489/* unsigned char * NativeLanMan; */ 506/* unsigned char * NativeLanMan; */
490/* unsigned char * PrimaryDomain; */ 507/* unsigned char * PrimaryDomain; */
491 } resp; /* NTLM response format (with or without extended security */ 508 } __attribute__((packed)) resp; /* NTLM response format (with or without extended security */
492 509
493 struct { /* request format */ 510 struct { /* request format */
494 struct smb_hdr hdr; /* wct = 10 */ 511 struct smb_hdr hdr; /* wct = 10 */
@@ -507,7 +524,7 @@ typedef union smb_com_session_setup_andx {
507 /* STRING PrimaryDomain */ 524 /* STRING PrimaryDomain */
508 /* STRING NativeOS */ 525 /* STRING NativeOS */
509 /* STRING NativeLanMan */ 526 /* STRING NativeLanMan */
510 } old_req; /* pre-NTLM (LANMAN2.1) request format */ 527 } __attribute__((packed)) old_req; /* pre-NTLM (LANMAN2.1) request format */
511 528
512 struct { /* default (NTLM) response format */ 529 struct { /* default (NTLM) response format */
513 struct smb_hdr hdr; /* wct = 3 */ 530 struct smb_hdr hdr; /* wct = 3 */
@@ -519,8 +536,8 @@ typedef union smb_com_session_setup_andx {
519 unsigned char NativeOS[1]; /* followed by */ 536 unsigned char NativeOS[1]; /* followed by */
520/* unsigned char * NativeLanMan; */ 537/* unsigned char * NativeLanMan; */
521/* unsigned char * PrimaryDomain; */ 538/* unsigned char * PrimaryDomain; */
522 } old_resp; /* pre-NTLM (LANMAN2.1) response format */ 539 } __attribute__((packed)) old_resp; /* pre-NTLM (LANMAN2.1) response format */
523} SESSION_SETUP_ANDX; 540} __attribute__((packed)) SESSION_SETUP_ANDX;
524 541
525#define CIFS_NETWORK_OPSYS "CIFS VFS Client for Linux" 542#define CIFS_NETWORK_OPSYS "CIFS VFS Client for Linux"
526 543
@@ -530,7 +547,8 @@ typedef union smb_com_session_setup_andx {
530#define CAP_NT_SMBS 0x00000010 547#define CAP_NT_SMBS 0x00000010
531#define CAP_STATUS32 0x00000040 548#define CAP_STATUS32 0x00000040
532#define CAP_LEVEL_II_OPLOCKS 0x00000080 549#define CAP_LEVEL_II_OPLOCKS 0x00000080
533#define CAP_NT_FIND 0x00000200 /* reserved should be zero (presumably because NT_SMBs implies the same thing) */ 550#define CAP_NT_FIND 0x00000200 /* reserved should be zero
551 (because NT_SMBs implies the same thing?) */
534#define CAP_BULK_TRANSFER 0x20000000 552#define CAP_BULK_TRANSFER 0x20000000
535#define CAP_EXTENDED_SECURITY 0x80000000 553#define CAP_EXTENDED_SECURITY 0x80000000
536 554
@@ -548,7 +566,7 @@ typedef struct smb_com_tconx_req {
548 unsigned char Password[1]; /* followed by */ 566 unsigned char Password[1]; /* followed by */
549/* STRING Path *//* \\server\share name */ 567/* STRING Path *//* \\server\share name */
550 /* STRING Service */ 568 /* STRING Service */
551} TCONX_REQ; 569} __attribute__((packed)) TCONX_REQ;
552 570
553typedef struct smb_com_tconx_rsp { 571typedef struct smb_com_tconx_rsp {
554 struct smb_hdr hdr; /* wct = 3 *//* note that Win2000 has sent wct=7 in some cases on responses. Four unspecified words followed OptionalSupport */ 572 struct smb_hdr hdr; /* wct = 3 *//* note that Win2000 has sent wct=7 in some cases on responses. Four unspecified words followed OptionalSupport */
@@ -559,13 +577,14 @@ typedef struct smb_com_tconx_rsp {
559 __u16 ByteCount; 577 __u16 ByteCount;
560 unsigned char Service[1]; /* always ASCII, not Unicode */ 578 unsigned char Service[1]; /* always ASCII, not Unicode */
561 /* STRING NativeFileSystem */ 579 /* STRING NativeFileSystem */
562} TCONX_RSP; 580} __attribute__((packed)) TCONX_RSP;
563 581
564/* tree connect Flags */ 582/* tree connect Flags */
565#define DISCONNECT_TID 0x0001 583#define DISCONNECT_TID 0x0001
566#define TCON_EXTENDED_SECINFO 0x0008 584#define TCON_EXTENDED_SECINFO 0x0008
567/* OptionalSupport bits */ 585/* OptionalSupport bits */
568#define SMB_SUPPORT_SEARCH_BITS 0x0001 /* must have bits (exclusive searches suppt. */ 586#define SMB_SUPPORT_SEARCH_BITS 0x0001 /* "must have" directory search bits
587 (exclusive searches supported) */
569#define SMB_SHARE_IS_IN_DFS 0x0002 588#define SMB_SHARE_IS_IN_DFS 0x0002
570 589
571typedef struct smb_com_logoff_andx_req { 590typedef struct smb_com_logoff_andx_req {
@@ -574,7 +593,7 @@ typedef struct smb_com_logoff_andx_req {
574 __u8 AndXReserved; 593 __u8 AndXReserved;
575 __u16 AndXOffset; 594 __u16 AndXOffset;
576 __u16 ByteCount; 595 __u16 ByteCount;
577} LOGOFF_ANDX_REQ; 596} __attribute__((packed)) LOGOFF_ANDX_REQ;
578 597
579typedef struct smb_com_logoff_andx_rsp { 598typedef struct smb_com_logoff_andx_rsp {
580 struct smb_hdr hdr; /* wct = 2 */ 599 struct smb_hdr hdr; /* wct = 2 */
@@ -582,38 +601,39 @@ typedef struct smb_com_logoff_andx_rsp {
582 __u8 AndXReserved; 601 __u8 AndXReserved;
583 __u16 AndXOffset; 602 __u16 AndXOffset;
584 __u16 ByteCount; 603 __u16 ByteCount;
585} LOGOFF_ANDX_RSP; 604} __attribute__((packed)) LOGOFF_ANDX_RSP;
586 605
587typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on tree_connect PDU to effect disconnect *//* probably the simplest SMB PDU */ 606typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on tree_connect PDU to effect disconnect *//* probably the simplest SMB PDU */
588 struct { 607 struct {
589 struct smb_hdr hdr; /* wct = 0 */ 608 struct smb_hdr hdr; /* wct = 0 */
590 __u16 ByteCount; /* bcc = 0 */ 609 __u16 ByteCount; /* bcc = 0 */
591 } req; 610 } __attribute__((packed)) req;
592 struct { 611 struct {
593 struct smb_hdr hdr; /* wct = 0 */ 612 struct smb_hdr hdr; /* wct = 0 */
594 __u16 ByteCount; /* bcc = 0 */ 613 __u16 ByteCount; /* bcc = 0 */
595 } resp; 614 } __attribute__((packed)) resp;
596} TREE_DISCONNECT; 615} __attribute__((packed)) TREE_DISCONNECT;
597 616
598typedef struct smb_com_close_req { 617typedef struct smb_com_close_req {
599 struct smb_hdr hdr; /* wct = 3 */ 618 struct smb_hdr hdr; /* wct = 3 */
600 __u16 FileID; 619 __u16 FileID;
601 __u32 LastWriteTime; /* should be zero */ 620 __u32 LastWriteTime; /* should be zero */
602 __u16 ByteCount; /* 0 */ 621 __u16 ByteCount; /* 0 */
603} CLOSE_REQ; 622} __attribute__((packed)) CLOSE_REQ;
604 623
605typedef struct smb_com_close_rsp { 624typedef struct smb_com_close_rsp {
606 struct smb_hdr hdr; /* wct = 0 */ 625 struct smb_hdr hdr; /* wct = 0 */
607 __u16 ByteCount; /* bct = 0 */ 626 __u16 ByteCount; /* bct = 0 */
608} CLOSE_RSP; 627} __attribute__((packed)) CLOSE_RSP;
609 628
610typedef struct smb_com_findclose_req { 629typedef struct smb_com_findclose_req {
611 struct smb_hdr hdr; /* wct = 1 */ 630 struct smb_hdr hdr; /* wct = 1 */
612 __u16 FileID; 631 __u16 FileID;
613 __u16 ByteCount; /* 0 */ 632 __u16 ByteCount; /* 0 */
614} FINDCLOSE_REQ; 633} __attribute__((packed)) FINDCLOSE_REQ;
615 634
616/* OpenFlags */ 635/* OpenFlags */
636#define REQ_MORE_INFO 0x00000001 /* legacy (OPEN_AND_X) only */
617#define REQ_OPLOCK 0x00000002 637#define REQ_OPLOCK 0x00000002
618#define REQ_BATCHOPLOCK 0x00000004 638#define REQ_BATCHOPLOCK 0x00000004
619#define REQ_OPENDIRONLY 0x00000008 639#define REQ_OPENDIRONLY 0x00000008
@@ -637,7 +657,7 @@ typedef struct smb_com_open_req { /* also handles create */
637 __u8 SecurityFlags; 657 __u8 SecurityFlags;
638 __le16 ByteCount; 658 __le16 ByteCount;
639 char fileName[1]; 659 char fileName[1];
640} OPEN_REQ; 660} __attribute__((packed)) OPEN_REQ;
641 661
642/* open response: oplock levels */ 662/* open response: oplock levels */
643#define OPLOCK_NONE 0 663#define OPLOCK_NONE 0
@@ -667,7 +687,63 @@ typedef struct smb_com_open_rsp {
667 __le16 DeviceState; 687 __le16 DeviceState;
668 __u8 DirectoryFlag; 688 __u8 DirectoryFlag;
669 __u16 ByteCount; /* bct = 0 */ 689 __u16 ByteCount; /* bct = 0 */
670} OPEN_RSP; 690} __attribute__((packed)) OPEN_RSP;
691
692/* format of legacy open request */
693typedef struct smb_com_openx_req {
694 struct smb_hdr hdr; /* wct = 15 */
695 __u8 AndXCommand;
696 __u8 AndXReserved;
697 __le16 AndXOffset;
698 __le16 OpenFlags;
699 __le16 Mode;
700 __le16 Sattr; /* search attributes */
701 __le16 FileAttributes; /* dos attrs */
702 __le32 CreateTime; /* os2 format */
703 __le16 OpenFunction;
704 __le32 EndOfFile;
705 __le32 Timeout;
706 __le32 Reserved;
707 __le16 ByteCount; /* file name follows */
708 char fileName[1];
709} __attribute__((packed)) OPENX_REQ;
710
711typedef struct smb_com_openx_rsp {
712 struct smb_hdr hdr; /* wct = 15 */
713 __u8 AndXCommand;
714 __u8 AndXReserved;
715 __le16 AndXOffset;
716 __u16 Fid;
717 __le16 FileAttributes;
718 __le32 LastWriteTime; /* os2 format */
719 __le32 EndOfFile;
720 __le16 Access;
721 __le16 FileType;
722 __le16 IPCState;
723 __le16 Action;
724 __u32 FileId;
725 __u16 Reserved;
726 __u16 ByteCount;
727} __attribute__((packed)) OPENX_RSP;
728
729/* Legacy write request for older servers */
730typedef struct smb_com_writex_req {
731 struct smb_hdr hdr; /* wct = 12 */
732 __u8 AndXCommand;
733 __u8 AndXReserved;
734 __le16 AndXOffset;
735 __u16 Fid;
736 __le32 OffsetLow;
737 __u32 Reserved; /* Timeout */
738 __le16 WriteMode; /* 1 = write through */
739 __le16 Remaining;
740 __le16 Reserved2;
741 __le16 DataLengthLow;
742 __le16 DataOffset;
743 __le16 ByteCount;
744 __u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */
745 char Data[0];
746} __attribute__((packed)) WRITEX_REQ;
671 747
672typedef struct smb_com_write_req { 748typedef struct smb_com_write_req {
673 struct smb_hdr hdr; /* wct = 14 */ 749 struct smb_hdr hdr; /* wct = 14 */
@@ -686,7 +762,7 @@ typedef struct smb_com_write_req {
686 __le16 ByteCount; 762 __le16 ByteCount;
687 __u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */ 763 __u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */
688 char Data[0]; 764 char Data[0];
689} WRITE_REQ; 765} __attribute__((packed)) WRITE_REQ;
690 766
691typedef struct smb_com_write_rsp { 767typedef struct smb_com_write_rsp {
692 struct smb_hdr hdr; /* wct = 6 */ 768 struct smb_hdr hdr; /* wct = 6 */
@@ -698,7 +774,22 @@ typedef struct smb_com_write_rsp {
698 __le16 CountHigh; 774 __le16 CountHigh;
699 __u16 Reserved; 775 __u16 Reserved;
700 __u16 ByteCount; 776 __u16 ByteCount;
701} WRITE_RSP; 777} __attribute__((packed)) WRITE_RSP;
778
779/* legacy read request for older servers */
780typedef struct smb_com_readx_req {
781 struct smb_hdr hdr; /* wct = 10 */
782 __u8 AndXCommand;
783 __u8 AndXReserved;
784 __le16 AndXOffset;
785 __u16 Fid;
786 __le32 OffsetLow;
787 __le16 MaxCount;
788 __le16 MinCount; /* obsolete */
789 __le32 Reserved;
790 __le16 Remaining;
791 __le16 ByteCount;
792} __attribute__((packed)) READX_REQ;
702 793
703typedef struct smb_com_read_req { 794typedef struct smb_com_read_req {
704 struct smb_hdr hdr; /* wct = 12 */ 795 struct smb_hdr hdr; /* wct = 12 */
@@ -713,7 +804,7 @@ typedef struct smb_com_read_req {
713 __le16 Remaining; 804 __le16 Remaining;
714 __le32 OffsetHigh; 805 __le32 OffsetHigh;
715 __le16 ByteCount; 806 __le16 ByteCount;
716} READ_REQ; 807} __attribute__((packed)) READ_REQ;
717 808
718typedef struct smb_com_read_rsp { 809typedef struct smb_com_read_rsp {
719 struct smb_hdr hdr; /* wct = 12 */ 810 struct smb_hdr hdr; /* wct = 12 */
@@ -730,7 +821,7 @@ typedef struct smb_com_read_rsp {
730 __u16 ByteCount; 821 __u16 ByteCount;
731 __u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */ 822 __u8 Pad; /* BB check for whether padded to DWORD boundary and optimum performance here */
732 char Data[1]; 823 char Data[1];
733} READ_RSP; 824} __attribute__((packed)) READ_RSP;
734 825
735typedef struct locking_andx_range { 826typedef struct locking_andx_range {
736 __le16 Pid; 827 __le16 Pid;
@@ -739,7 +830,7 @@ typedef struct locking_andx_range {
739 __le32 OffsetLow; 830 __le32 OffsetLow;
740 __le32 LengthHigh; 831 __le32 LengthHigh;
741 __le32 LengthLow; 832 __le32 LengthLow;
742} LOCKING_ANDX_RANGE; 833} __attribute__((packed)) LOCKING_ANDX_RANGE;
743 834
744#define LOCKING_ANDX_SHARED_LOCK 0x01 835#define LOCKING_ANDX_SHARED_LOCK 0x01
745#define LOCKING_ANDX_OPLOCK_RELEASE 0x02 836#define LOCKING_ANDX_OPLOCK_RELEASE 0x02
@@ -760,7 +851,7 @@ typedef struct smb_com_lock_req {
760 __le16 NumberOfLocks; 851 __le16 NumberOfLocks;
761 __le16 ByteCount; 852 __le16 ByteCount;
762 LOCKING_ANDX_RANGE Locks[1]; 853 LOCKING_ANDX_RANGE Locks[1];
763} LOCK_REQ; 854} __attribute__((packed)) LOCK_REQ;
764 855
765 856
766typedef struct cifs_posix_lock { 857typedef struct cifs_posix_lock {
@@ -770,7 +861,7 @@ typedef struct cifs_posix_lock {
770 __le64 start; 861 __le64 start;
771 __le64 length; 862 __le64 length;
772 /* BB what about additional owner info to identify network client */ 863 /* BB what about additional owner info to identify network client */
773} CIFS_POSIX_LOCK; 864} __attribute__((packed)) CIFS_POSIX_LOCK;
774 865
775typedef struct smb_com_lock_rsp { 866typedef struct smb_com_lock_rsp {
776 struct smb_hdr hdr; /* wct = 2 */ 867 struct smb_hdr hdr; /* wct = 2 */
@@ -778,7 +869,7 @@ typedef struct smb_com_lock_rsp {
778 __u8 AndXReserved; 869 __u8 AndXReserved;
779 __le16 AndXOffset; 870 __le16 AndXOffset;
780 __u16 ByteCount; 871 __u16 ByteCount;
781} LOCK_RSP; 872} __attribute__((packed)) LOCK_RSP;
782 873
783typedef struct smb_com_rename_req { 874typedef struct smb_com_rename_req {
784 struct smb_hdr hdr; /* wct = 1 */ 875 struct smb_hdr hdr; /* wct = 1 */
@@ -788,7 +879,7 @@ typedef struct smb_com_rename_req {
788 unsigned char OldFileName[1]; 879 unsigned char OldFileName[1];
789 /* followed by __u8 BufferFormat2 */ 880 /* followed by __u8 BufferFormat2 */
790 /* followed by NewFileName */ 881 /* followed by NewFileName */
791} RENAME_REQ; 882} __attribute__((packed)) RENAME_REQ;
792 883
793 /* copy request flags */ 884 /* copy request flags */
794#define COPY_MUST_BE_FILE 0x0001 885#define COPY_MUST_BE_FILE 0x0001
@@ -808,7 +899,7 @@ typedef struct smb_com_copy_req {
808 unsigned char OldFileName[1]; 899 unsigned char OldFileName[1];
809 /* followed by __u8 BufferFormat2 */ 900 /* followed by __u8 BufferFormat2 */
810 /* followed by NewFileName string */ 901 /* followed by NewFileName string */
811} COPY_REQ; 902} __attribute__((packed)) COPY_REQ;
812 903
813typedef struct smb_com_copy_rsp { 904typedef struct smb_com_copy_rsp {
814 struct smb_hdr hdr; /* wct = 1 */ 905 struct smb_hdr hdr; /* wct = 1 */
@@ -816,7 +907,7 @@ typedef struct smb_com_copy_rsp {
816 __u16 ByteCount; /* may be zero */ 907 __u16 ByteCount; /* may be zero */
817 __u8 BufferFormat; /* 0x04 - only present if errored file follows */ 908 __u8 BufferFormat; /* 0x04 - only present if errored file follows */
818 unsigned char ErrorFileName[1]; /* only present if error in copy */ 909 unsigned char ErrorFileName[1]; /* only present if error in copy */
819} COPY_RSP; 910} __attribute__((packed)) COPY_RSP;
820 911
821#define CREATE_HARD_LINK 0x103 912#define CREATE_HARD_LINK 0x103
822#define MOVEFILE_COPY_ALLOWED 0x0002 913#define MOVEFILE_COPY_ALLOWED 0x0002
@@ -832,12 +923,12 @@ typedef struct smb_com_nt_rename_req { /* A5 - also used for create hardlink */
832 unsigned char OldFileName[1]; 923 unsigned char OldFileName[1];
833 /* followed by __u8 BufferFormat2 */ 924 /* followed by __u8 BufferFormat2 */
834 /* followed by NewFileName */ 925 /* followed by NewFileName */
835} NT_RENAME_REQ; 926} __attribute__((packed)) NT_RENAME_REQ;
836 927
837typedef struct smb_com_rename_rsp { 928typedef struct smb_com_rename_rsp {
838 struct smb_hdr hdr; /* wct = 0 */ 929 struct smb_hdr hdr; /* wct = 0 */
839 __u16 ByteCount; /* bct = 0 */ 930 __u16 ByteCount; /* bct = 0 */
840} RENAME_RSP; 931} __attribute__((packed)) RENAME_RSP;
841 932
842typedef struct smb_com_delete_file_req { 933typedef struct smb_com_delete_file_req {
843 struct smb_hdr hdr; /* wct = 1 */ 934 struct smb_hdr hdr; /* wct = 1 */
@@ -845,36 +936,52 @@ typedef struct smb_com_delete_file_req {
845 __le16 ByteCount; 936 __le16 ByteCount;
846 __u8 BufferFormat; /* 4 = ASCII */ 937 __u8 BufferFormat; /* 4 = ASCII */
847 unsigned char fileName[1]; 938 unsigned char fileName[1];
848} DELETE_FILE_REQ; 939} __attribute__((packed)) DELETE_FILE_REQ;
849 940
850typedef struct smb_com_delete_file_rsp { 941typedef struct smb_com_delete_file_rsp {
851 struct smb_hdr hdr; /* wct = 0 */ 942 struct smb_hdr hdr; /* wct = 0 */
852 __u16 ByteCount; /* bct = 0 */ 943 __u16 ByteCount; /* bct = 0 */
853} DELETE_FILE_RSP; 944} __attribute__((packed)) DELETE_FILE_RSP;
854 945
855typedef struct smb_com_delete_directory_req { 946typedef struct smb_com_delete_directory_req {
856 struct smb_hdr hdr; /* wct = 0 */ 947 struct smb_hdr hdr; /* wct = 0 */
857 __le16 ByteCount; 948 __le16 ByteCount;
858 __u8 BufferFormat; /* 4 = ASCII */ 949 __u8 BufferFormat; /* 4 = ASCII */
859 unsigned char DirName[1]; 950 unsigned char DirName[1];
860} DELETE_DIRECTORY_REQ; 951} __attribute__((packed)) DELETE_DIRECTORY_REQ;
861 952
862typedef struct smb_com_delete_directory_rsp { 953typedef struct smb_com_delete_directory_rsp {
863 struct smb_hdr hdr; /* wct = 0 */ 954 struct smb_hdr hdr; /* wct = 0 */
864 __u16 ByteCount; /* bct = 0 */ 955 __u16 ByteCount; /* bct = 0 */
865} DELETE_DIRECTORY_RSP; 956} __attribute__((packed)) DELETE_DIRECTORY_RSP;
866 957
867typedef struct smb_com_create_directory_req { 958typedef struct smb_com_create_directory_req {
868 struct smb_hdr hdr; /* wct = 0 */ 959 struct smb_hdr hdr; /* wct = 0 */
869 __le16 ByteCount; 960 __le16 ByteCount;
870 __u8 BufferFormat; /* 4 = ASCII */ 961 __u8 BufferFormat; /* 4 = ASCII */
871 unsigned char DirName[1]; 962 unsigned char DirName[1];
872} CREATE_DIRECTORY_REQ; 963} __attribute__((packed)) CREATE_DIRECTORY_REQ;
873 964
874typedef struct smb_com_create_directory_rsp { 965typedef struct smb_com_create_directory_rsp {
875 struct smb_hdr hdr; /* wct = 0 */ 966 struct smb_hdr hdr; /* wct = 0 */
876 __u16 ByteCount; /* bct = 0 */ 967 __u16 ByteCount; /* bct = 0 */
877} CREATE_DIRECTORY_RSP; 968} __attribute__((packed)) CREATE_DIRECTORY_RSP;
969
970typedef struct smb_com_query_information_req {
971 struct smb_hdr hdr; /* wct = 0 */
972 __le16 ByteCount; /* 1 + namelen + 1 */
973 __u8 BufferFormat; /* 4 = ASCII */
974 unsigned char FileName[1];
975} __attribute__((packed)) QUERY_INFORMATION_REQ;
976
977typedef struct smb_com_query_information_rsp {
978 struct smb_hdr hdr; /* wct = 10 */
979 __le16 attr;
980 __le32 last_write_time;
981 __le32 size;
982 __u16 reserved[5];
983 __le16 ByteCount; /* bcc = 0 */
984} __attribute__((packed)) QUERY_INFORMATION_RSP;
878 985
879typedef struct smb_com_setattr_req { 986typedef struct smb_com_setattr_req {
880 struct smb_hdr hdr; /* wct = 8 */ 987 struct smb_hdr hdr; /* wct = 8 */
@@ -885,12 +992,12 @@ typedef struct smb_com_setattr_req {
885 __u16 ByteCount; 992 __u16 ByteCount;
886 __u8 BufferFormat; /* 4 = ASCII */ 993 __u8 BufferFormat; /* 4 = ASCII */
887 unsigned char fileName[1]; 994 unsigned char fileName[1];
888} SETATTR_REQ; 995} __attribute__((packed)) SETATTR_REQ;
889 996
890typedef struct smb_com_setattr_rsp { 997typedef struct smb_com_setattr_rsp {
891 struct smb_hdr hdr; /* wct = 0 */ 998 struct smb_hdr hdr; /* wct = 0 */
892 __u16 ByteCount; /* bct = 0 */ 999 __u16 ByteCount; /* bct = 0 */
893} SETATTR_RSP; 1000} __attribute__((packed)) SETATTR_RSP;
894 1001
895/* empty wct response to setattr */ 1002/* empty wct response to setattr */
896 1003
@@ -920,7 +1027,7 @@ typedef struct smb_com_transaction_ioctl_req {
920 __le16 ByteCount; 1027 __le16 ByteCount;
921 __u8 Pad[3]; 1028 __u8 Pad[3];
922 __u8 Data[1]; 1029 __u8 Data[1];
923} TRANSACT_IOCTL_REQ; 1030} __attribute__((packed)) TRANSACT_IOCTL_REQ;
924 1031
925typedef struct smb_com_transaction_ioctl_rsp { 1032typedef struct smb_com_transaction_ioctl_rsp {
926 struct smb_hdr hdr; /* wct = 19 */ 1033 struct smb_hdr hdr; /* wct = 19 */
@@ -937,7 +1044,7 @@ typedef struct smb_com_transaction_ioctl_rsp {
937 __le16 ReturnedDataLen; 1044 __le16 ReturnedDataLen;
938 __u16 ByteCount; 1045 __u16 ByteCount;
939 __u8 Pad[3]; 1046 __u8 Pad[3];
940} TRANSACT_IOCTL_RSP; 1047} __attribute__((packed)) TRANSACT_IOCTL_RSP;
941 1048
942typedef struct smb_com_transaction_change_notify_req { 1049typedef struct smb_com_transaction_change_notify_req {
943 struct smb_hdr hdr; /* wct = 23 */ 1050 struct smb_hdr hdr; /* wct = 23 */
@@ -961,7 +1068,7 @@ typedef struct smb_com_transaction_change_notify_req {
961 __le16 ByteCount; 1068 __le16 ByteCount;
962/* __u8 Pad[3];*/ 1069/* __u8 Pad[3];*/
963/* __u8 Data[1];*/ 1070/* __u8 Data[1];*/
964} TRANSACT_CHANGE_NOTIFY_REQ; 1071} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ;
965 1072
966typedef struct smb_com_transaction_change_notify_rsp { 1073typedef struct smb_com_transaction_change_notify_rsp {
967 struct smb_hdr hdr; /* wct = 18 */ 1074 struct smb_hdr hdr; /* wct = 18 */
@@ -977,7 +1084,7 @@ typedef struct smb_com_transaction_change_notify_rsp {
977 __u8 SetupCount; /* 0 */ 1084 __u8 SetupCount; /* 0 */
978 __u16 ByteCount; 1085 __u16 ByteCount;
979 /* __u8 Pad[3]; */ 1086 /* __u8 Pad[3]; */
980} TRANSACT_CHANGE_NOTIFY_RSP; 1087} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_RSP;
981/* Completion Filter flags for Notify */ 1088/* Completion Filter flags for Notify */
982#define FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001 1089#define FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001
983#define FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002 1090#define FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002
@@ -1008,7 +1115,7 @@ struct file_notify_information {
1008 __le32 Action; 1115 __le32 Action;
1009 __le32 FileNameLength; 1116 __le32 FileNameLength;
1010 __u8 FileName[0]; 1117 __u8 FileName[0];
1011}; 1118} __attribute__((packed));
1012 1119
1013struct reparse_data { 1120struct reparse_data {
1014 __u32 ReparseTag; 1121 __u32 ReparseTag;
@@ -1019,7 +1126,7 @@ struct reparse_data {
1019 __u16 TargetNameOffset; 1126 __u16 TargetNameOffset;
1020 __u16 TargetNameLen; 1127 __u16 TargetNameLen;
1021 char LinkNamesBuf[1]; 1128 char LinkNamesBuf[1];
1022}; 1129} __attribute__((packed));
1023 1130
1024struct cifs_quota_data { 1131struct cifs_quota_data {
1025 __u32 rsrvd1; /* 0 */ 1132 __u32 rsrvd1; /* 0 */
@@ -1029,7 +1136,7 @@ struct cifs_quota_data {
1029 __u64 soft_limit; 1136 __u64 soft_limit;
1030 __u64 hard_limit; 1137 __u64 hard_limit;
1031 char sid[1]; /* variable size? */ 1138 char sid[1]; /* variable size? */
1032}; 1139} __attribute__((packed));
1033 1140
1034/* quota sub commands */ 1141/* quota sub commands */
1035#define QUOTA_LIST_CONTINUE 0 1142#define QUOTA_LIST_CONTINUE 0
@@ -1055,12 +1162,12 @@ struct trans2_req {
1055 __u8 Reserved3; 1162 __u8 Reserved3;
1056 __le16 SubCommand; /* 1st setup word - SetupCount words follow */ 1163 __le16 SubCommand; /* 1st setup word - SetupCount words follow */
1057 __le16 ByteCount; 1164 __le16 ByteCount;
1058}; 1165} __attribute__((packed));
1059 1166
1060struct smb_t2_req { 1167struct smb_t2_req {
1061 struct smb_hdr hdr; 1168 struct smb_hdr hdr;
1062 struct trans2_req t2_req; 1169 struct trans2_req t2_req;
1063}; 1170} __attribute__((packed));
1064 1171
1065struct trans2_resp { 1172struct trans2_resp {
1066 /* struct smb_hdr hdr precedes. Note wct = 10 + setup count */ 1173 /* struct smb_hdr hdr precedes. Note wct = 10 + setup count */
@@ -1079,12 +1186,12 @@ struct trans2_resp {
1079 __u16 ByteCount; 1186 __u16 ByteCount;
1080 __u16 Reserved2;*/ 1187 __u16 Reserved2;*/
1081 /* data area follows */ 1188 /* data area follows */
1082}; 1189} __attribute__((packed));
1083 1190
1084struct smb_t2_rsp { 1191struct smb_t2_rsp {
1085 struct smb_hdr hdr; 1192 struct smb_hdr hdr;
1086 struct trans2_resp t2_rsp; 1193 struct trans2_resp t2_rsp;
1087}; 1194} __attribute__((packed));
1088 1195
1089/* PathInfo/FileInfo infolevels */ 1196/* PathInfo/FileInfo infolevels */
1090#define SMB_INFO_STANDARD 1 1197#define SMB_INFO_STANDARD 1
@@ -1171,14 +1278,14 @@ typedef struct smb_com_transaction2_qpi_req {
1171 __le16 InformationLevel; 1278 __le16 InformationLevel;
1172 __u32 Reserved4; 1279 __u32 Reserved4;
1173 char FileName[1]; 1280 char FileName[1];
1174} TRANSACTION2_QPI_REQ; 1281} __attribute__((packed)) TRANSACTION2_QPI_REQ;
1175 1282
1176typedef struct smb_com_transaction2_qpi_rsp { 1283typedef struct smb_com_transaction2_qpi_rsp {
1177 struct smb_hdr hdr; /* wct = 10 + SetupCount */ 1284 struct smb_hdr hdr; /* wct = 10 + SetupCount */
1178 struct trans2_resp t2; 1285 struct trans2_resp t2;
1179 __u16 ByteCount; 1286 __u16 ByteCount;
1180 __u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */ 1287 __u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */
1181} TRANSACTION2_QPI_RSP; 1288} __attribute__((packed)) TRANSACTION2_QPI_RSP;
1182 1289
1183typedef struct smb_com_transaction2_spi_req { 1290typedef struct smb_com_transaction2_spi_req {
1184 struct smb_hdr hdr; /* wct = 15 */ 1291 struct smb_hdr hdr; /* wct = 15 */
@@ -1204,21 +1311,21 @@ typedef struct smb_com_transaction2_spi_req {
1204 __le16 InformationLevel; 1311 __le16 InformationLevel;
1205 __u32 Reserved4; 1312 __u32 Reserved4;
1206 char FileName[1]; 1313 char FileName[1];
1207} TRANSACTION2_SPI_REQ; 1314} __attribute__((packed)) TRANSACTION2_SPI_REQ;
1208 1315
1209typedef struct smb_com_transaction2_spi_rsp { 1316typedef struct smb_com_transaction2_spi_rsp {
1210 struct smb_hdr hdr; /* wct = 10 + SetupCount */ 1317 struct smb_hdr hdr; /* wct = 10 + SetupCount */
1211 struct trans2_resp t2; 1318 struct trans2_resp t2;
1212 __u16 ByteCount; 1319 __u16 ByteCount;
1213 __u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */ 1320 __u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */
1214} TRANSACTION2_SPI_RSP; 1321} __attribute__((packed)) TRANSACTION2_SPI_RSP;
1215 1322
1216struct set_file_rename { 1323struct set_file_rename {
1217 __le32 overwrite; /* 1 = overwrite dest */ 1324 __le32 overwrite; /* 1 = overwrite dest */
1218 __u32 root_fid; /* zero */ 1325 __u32 root_fid; /* zero */
1219 __le32 target_name_len; 1326 __le32 target_name_len;
1220 char target_name[0]; /* Must be unicode */ 1327 char target_name[0]; /* Must be unicode */
1221}; 1328} __attribute__((packed));
1222 1329
1223struct smb_com_transaction2_sfi_req { 1330struct smb_com_transaction2_sfi_req {
1224 struct smb_hdr hdr; /* wct = 15 */ 1331 struct smb_hdr hdr; /* wct = 15 */
@@ -1244,7 +1351,7 @@ struct smb_com_transaction2_sfi_req {
1244 __u16 Fid; 1351 __u16 Fid;
1245 __le16 InformationLevel; 1352 __le16 InformationLevel;
1246 __u16 Reserved4; 1353 __u16 Reserved4;
1247}; 1354} __attribute__((packed));
1248 1355
1249struct smb_com_transaction2_sfi_rsp { 1356struct smb_com_transaction2_sfi_rsp {
1250 struct smb_hdr hdr; /* wct = 10 + SetupCount */ 1357 struct smb_hdr hdr; /* wct = 10 + SetupCount */
@@ -1252,7 +1359,7 @@ struct smb_com_transaction2_sfi_rsp {
1252 __u16 ByteCount; 1359 __u16 ByteCount;
1253 __u16 Reserved2; /* parameter word reserved - 1360 __u16 Reserved2; /* parameter word reserved -
1254 present for infolevels > 100 */ 1361 present for infolevels > 100 */
1255}; 1362} __attribute__((packed));
1256 1363
1257struct smb_t2_qfi_req { 1364struct smb_t2_qfi_req {
1258 struct smb_hdr hdr; 1365 struct smb_hdr hdr;
@@ -1260,7 +1367,7 @@ struct smb_t2_qfi_req {
1260 __u8 Pad; 1367 __u8 Pad;
1261 __u16 Fid; 1368 __u16 Fid;
1262 __le16 InformationLevel; 1369 __le16 InformationLevel;
1263}; 1370} __attribute__((packed));
1264 1371
1265struct smb_t2_qfi_rsp { 1372struct smb_t2_qfi_rsp {
1266 struct smb_hdr hdr; /* wct = 10 + SetupCount */ 1373 struct smb_hdr hdr; /* wct = 10 + SetupCount */
@@ -1268,7 +1375,7 @@ struct smb_t2_qfi_rsp {
1268 __u16 ByteCount; 1375 __u16 ByteCount;
1269 __u16 Reserved2; /* parameter word reserved - 1376 __u16 Reserved2; /* parameter word reserved -
1270 present for infolevels > 100 */ 1377 present for infolevels > 100 */
1271}; 1378} __attribute__((packed));
1272 1379
1273/* 1380/*
1274 * Flags on T2 FINDFIRST and FINDNEXT 1381 * Flags on T2 FINDFIRST and FINDNEXT
@@ -1310,13 +1417,13 @@ typedef struct smb_com_transaction2_ffirst_req {
1310 __le16 InformationLevel; 1417 __le16 InformationLevel;
1311 __le32 SearchStorageType; 1418 __le32 SearchStorageType;
1312 char FileName[1]; 1419 char FileName[1];
1313} TRANSACTION2_FFIRST_REQ; 1420} __attribute__((packed)) TRANSACTION2_FFIRST_REQ;
1314 1421
1315typedef struct smb_com_transaction2_ffirst_rsp { 1422typedef struct smb_com_transaction2_ffirst_rsp {
1316 struct smb_hdr hdr; /* wct = 10 */ 1423 struct smb_hdr hdr; /* wct = 10 */
1317 struct trans2_resp t2; 1424 struct trans2_resp t2;
1318 __u16 ByteCount; 1425 __u16 ByteCount;
1319} TRANSACTION2_FFIRST_RSP; 1426} __attribute__((packed)) TRANSACTION2_FFIRST_RSP;
1320 1427
1321typedef struct smb_com_transaction2_ffirst_rsp_parms { 1428typedef struct smb_com_transaction2_ffirst_rsp_parms {
1322 __u16 SearchHandle; 1429 __u16 SearchHandle;
@@ -1324,7 +1431,7 @@ typedef struct smb_com_transaction2_ffirst_rsp_parms {
1324 __le16 EndofSearch; 1431 __le16 EndofSearch;
1325 __le16 EAErrorOffset; 1432 __le16 EAErrorOffset;
1326 __le16 LastNameOffset; 1433 __le16 LastNameOffset;
1327} T2_FFIRST_RSP_PARMS; 1434} __attribute__((packed)) T2_FFIRST_RSP_PARMS;
1328 1435
1329typedef struct smb_com_transaction2_fnext_req { 1436typedef struct smb_com_transaction2_fnext_req {
1330 struct smb_hdr hdr; /* wct = 15 */ 1437 struct smb_hdr hdr; /* wct = 15 */
@@ -1352,20 +1459,20 @@ typedef struct smb_com_transaction2_fnext_req {
1352 __u32 ResumeKey; 1459 __u32 ResumeKey;
1353 __le16 SearchFlags; 1460 __le16 SearchFlags;
1354 char ResumeFileName[1]; 1461 char ResumeFileName[1];
1355} TRANSACTION2_FNEXT_REQ; 1462} __attribute__((packed)) TRANSACTION2_FNEXT_REQ;
1356 1463
1357typedef struct smb_com_transaction2_fnext_rsp { 1464typedef struct smb_com_transaction2_fnext_rsp {
1358 struct smb_hdr hdr; /* wct = 10 */ 1465 struct smb_hdr hdr; /* wct = 10 */
1359 struct trans2_resp t2; 1466 struct trans2_resp t2;
1360 __u16 ByteCount; 1467 __u16 ByteCount;
1361} TRANSACTION2_FNEXT_RSP; 1468} __attribute__((packed)) TRANSACTION2_FNEXT_RSP;
1362 1469
1363typedef struct smb_com_transaction2_fnext_rsp_parms { 1470typedef struct smb_com_transaction2_fnext_rsp_parms {
1364 __le16 SearchCount; 1471 __le16 SearchCount;
1365 __le16 EndofSearch; 1472 __le16 EndofSearch;
1366 __le16 EAErrorOffset; 1473 __le16 EAErrorOffset;
1367 __le16 LastNameOffset; 1474 __le16 LastNameOffset;
1368} T2_FNEXT_RSP_PARMS; 1475} __attribute__((packed)) T2_FNEXT_RSP_PARMS;
1369 1476
1370/* QFSInfo Levels */ 1477/* QFSInfo Levels */
1371#define SMB_INFO_ALLOCATION 1 1478#define SMB_INFO_ALLOCATION 1
@@ -1402,14 +1509,51 @@ typedef struct smb_com_transaction2_qfsi_req {
1402 __le16 ByteCount; 1509 __le16 ByteCount;
1403 __u8 Pad; 1510 __u8 Pad;
1404 __le16 InformationLevel; 1511 __le16 InformationLevel;
1405} TRANSACTION2_QFSI_REQ; 1512} __attribute__((packed)) TRANSACTION2_QFSI_REQ;
1406 1513
1407typedef struct smb_com_transaction_qfsi_rsp { 1514typedef struct smb_com_transaction_qfsi_rsp {
1408 struct smb_hdr hdr; /* wct = 10 + SetupCount */ 1515 struct smb_hdr hdr; /* wct = 10 + SetupCount */
1409 struct trans2_resp t2; 1516 struct trans2_resp t2;
1410 __u16 ByteCount; 1517 __u16 ByteCount;
1411 __u8 Pad; /* may be three bytes *//* followed by data area */ 1518 __u8 Pad; /* may be three bytes *//* followed by data area */
1412} TRANSACTION2_QFSI_RSP; 1519} __attribute__((packed)) TRANSACTION2_QFSI_RSP;
1520
1521
1522/* SETFSInfo Levels */
1523#define SMB_SET_CIFS_UNIX_INFO 0x200
1524typedef struct smb_com_transaction2_setfsi_req {
1525 struct smb_hdr hdr; /* wct = 15 */
1526 __le16 TotalParameterCount;
1527 __le16 TotalDataCount;
1528 __le16 MaxParameterCount;
1529 __le16 MaxDataCount;
1530 __u8 MaxSetupCount;
1531 __u8 Reserved;
1532 __le16 Flags;
1533 __le32 Timeout;
1534 __u16 Reserved2;
1535 __le16 ParameterCount; /* 4 */
1536 __le16 ParameterOffset;
1537 __le16 DataCount; /* 12 */
1538 __le16 DataOffset;
1539 __u8 SetupCount; /* one */
1540 __u8 Reserved3;
1541 __le16 SubCommand; /* TRANS2_SET_FS_INFORMATION */
1542 __le16 ByteCount;
1543 __u8 Pad;
1544 __u16 FileNum; /* Parameters start. */
1545 __le16 InformationLevel;/* Parameters end. */
1546 __le16 ClientUnixMajor; /* Data start. */
1547 __le16 ClientUnixMinor;
1548 __le64 ClientUnixCap; /* Data end */
1549} __attribute__((packed)) TRANSACTION2_SETFSI_REQ;
1550
1551typedef struct smb_com_transaction2_setfsi_rsp {
1552 struct smb_hdr hdr; /* wct = 10 */
1553 struct trans2_resp t2;
1554 __u16 ByteCount;
1555} __attribute__((packed)) TRANSACTION2_SETFSI_RSP;
1556
1413 1557
1414typedef struct smb_com_transaction2_get_dfs_refer_req { 1558typedef struct smb_com_transaction2_get_dfs_refer_req {
1415 struct smb_hdr hdr; /* wct = 15 */ 1559 struct smb_hdr hdr; /* wct = 15 */
@@ -1433,7 +1577,7 @@ typedef struct smb_com_transaction2_get_dfs_refer_req {
1433 __u8 Pad[3]; /* Win2K has sent 0x0F01 (max resp length perhaps?) followed by one byte pad - doesn't seem to matter though */ 1577 __u8 Pad[3]; /* Win2K has sent 0x0F01 (max resp length perhaps?) followed by one byte pad - doesn't seem to matter though */
1434 __le16 MaxReferralLevel; 1578 __le16 MaxReferralLevel;
1435 char RequestFileName[1]; 1579 char RequestFileName[1];
1436} TRANSACTION2_GET_DFS_REFER_REQ; 1580} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_REQ;
1437 1581
1438typedef struct dfs_referral_level_3 { 1582typedef struct dfs_referral_level_3 {
1439 __le16 VersionNumber; 1583 __le16 VersionNumber;
@@ -1445,7 +1589,7 @@ typedef struct dfs_referral_level_3 {
1445 __le16 DfsPathOffset; 1589 __le16 DfsPathOffset;
1446 __le16 DfsAlternatePathOffset; 1590 __le16 DfsAlternatePathOffset;
1447 __le16 NetworkAddressOffset; 1591 __le16 NetworkAddressOffset;
1448} REFERRAL3; 1592} __attribute__((packed)) REFERRAL3;
1449 1593
1450typedef struct smb_com_transaction_get_dfs_refer_rsp { 1594typedef struct smb_com_transaction_get_dfs_refer_rsp {
1451 struct smb_hdr hdr; /* wct = 10 */ 1595 struct smb_hdr hdr; /* wct = 10 */
@@ -1458,7 +1602,7 @@ typedef struct smb_com_transaction_get_dfs_refer_rsp {
1458 __u16 Pad2; 1602 __u16 Pad2;
1459 REFERRAL3 referrals[1]; /* array of level 3 dfs_referral structures */ 1603 REFERRAL3 referrals[1]; /* array of level 3 dfs_referral structures */
1460 /* followed by the strings pointed to by the referral structures */ 1604 /* followed by the strings pointed to by the referral structures */
1461} TRANSACTION2_GET_DFS_REFER_RSP; 1605} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_RSP;
1462 1606
1463/* DFS Flags */ 1607/* DFS Flags */
1464#define DFSREF_REFERRAL_SERVER 0x0001 1608#define DFSREF_REFERRAL_SERVER 0x0001
@@ -1512,7 +1656,7 @@ struct serverInfo {
1512 unsigned char versionMinor; 1656 unsigned char versionMinor;
1513 unsigned long type; 1657 unsigned long type;
1514 unsigned int commentOffset; 1658 unsigned int commentOffset;
1515}; 1659} __attribute__((packed));
1516 1660
1517/* 1661/*
1518 * The following structure is the format of the data returned on a NetShareEnum 1662 * The following structure is the format of the data returned on a NetShareEnum
@@ -1524,39 +1668,55 @@ struct shareInfo {
1524 char pad; 1668 char pad;
1525 unsigned short type; 1669 unsigned short type;
1526 unsigned int commentOffset; 1670 unsigned int commentOffset;
1527}; 1671} __attribute__((packed));
1528 1672
1529struct aliasInfo { 1673struct aliasInfo {
1530 char aliasName[9]; 1674 char aliasName[9];
1531 char pad; 1675 char pad;
1532 unsigned int commentOffset; 1676 unsigned int commentOffset;
1533 unsigned char type[2]; 1677 unsigned char type[2];
1534}; 1678} __attribute__((packed));
1535 1679
1536struct aliasInfo92 { 1680struct aliasInfo92 {
1537 int aliasNameOffset; 1681 int aliasNameOffset;
1538 int serverNameOffset; 1682 int serverNameOffset;
1539 int shareNameOffset; 1683 int shareNameOffset;
1540}; 1684} __attribute__((packed));
1541 1685
1542typedef struct { 1686typedef struct {
1543 __le64 TotalAllocationUnits; 1687 __le64 TotalAllocationUnits;
1544 __le64 FreeAllocationUnits; 1688 __le64 FreeAllocationUnits;
1545 __le32 SectorsPerAllocationUnit; 1689 __le32 SectorsPerAllocationUnit;
1546 __le32 BytesPerSector; 1690 __le32 BytesPerSector;
1547} FILE_SYSTEM_INFO; /* size info, level 0x103 */ 1691} __attribute__((packed)) FILE_SYSTEM_INFO; /* size info, level 0x103 */
1692
1693typedef struct {
1694 __le32 fsid;
1695 __le32 SectorsPerAllocationUnit;
1696 __le32 TotalAllocationUnits;
1697 __le32 FreeAllocationUnits;
1698 __le16 BytesPerSector;
1699} __attribute__((packed)) FILE_SYSTEM_ALLOC_INFO;
1548 1700
1549typedef struct { 1701typedef struct {
1550 __le16 MajorVersionNumber; 1702 __le16 MajorVersionNumber;
1551 __le16 MinorVersionNumber; 1703 __le16 MinorVersionNumber;
1552 __le64 Capability; 1704 __le64 Capability;
1553} FILE_SYSTEM_UNIX_INFO; /* Unix extensions info, level 0x200 */ 1705} __attribute__((packed)) FILE_SYSTEM_UNIX_INFO; /* Unix extensions info, level 0x200 */
1706
1707/* Version numbers for CIFS UNIX major and minor. */
1708#define CIFS_UNIX_MAJOR_VERSION 1
1709#define CIFS_UNIX_MINOR_VERSION 0
1710
1554/* Linux/Unix extensions capability flags */ 1711/* Linux/Unix extensions capability flags */
1555#define CIFS_UNIX_FCNTL_CAP 0x00000001 /* support for fcntl locks */ 1712#define CIFS_UNIX_FCNTL_CAP 0x00000001 /* support for fcntl locks */
1556#define CIFS_UNIX_POSIX_ACL_CAP 0x00000002 /* support getfacl/setfacl */ 1713#define CIFS_UNIX_POSIX_ACL_CAP 0x00000002 /* support getfacl/setfacl */
1557#define CIFS_UNIX_XATTR_CAP 0x00000004 /* support new namespace */ 1714#define CIFS_UNIX_XATTR_CAP 0x00000004 /* support new namespace */
1558#define CIFS_UNIX_EXTATTR_CAP 0x00000008 /* support chattr/chflag */ 1715#define CIFS_UNIX_EXTATTR_CAP 0x00000008 /* support chattr/chflag */
1716#define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Use POSIX pathnames on the wire. */
1717
1559#define CIFS_POSIX_EXTENSIONS 0x00000010 /* support for new QFSInfo */ 1718#define CIFS_POSIX_EXTENSIONS 0x00000010 /* support for new QFSInfo */
1719
1560typedef struct { 1720typedef struct {
1561 /* For undefined recommended transfer size return -1 in that field */ 1721 /* For undefined recommended transfer size return -1 in that field */
1562 __le32 OptimalTransferSize; /* bsize on some os, iosize on other os */ 1722 __le32 OptimalTransferSize; /* bsize on some os, iosize on other os */
@@ -1577,7 +1737,7 @@ typedef struct {
1577 __le64 FileSysIdentifier; /* fsid */ 1737 __le64 FileSysIdentifier; /* fsid */
1578 /* NB Namelen comes from FILE_SYSTEM_ATTRIBUTE_INFO call */ 1738 /* NB Namelen comes from FILE_SYSTEM_ATTRIBUTE_INFO call */
1579 /* NB flags can come from FILE_SYSTEM_DEVICE_INFO call */ 1739 /* NB flags can come from FILE_SYSTEM_DEVICE_INFO call */
1580} FILE_SYSTEM_POSIX_INFO; 1740} __attribute__((packed)) FILE_SYSTEM_POSIX_INFO;
1581 1741
1582/* DeviceType Flags */ 1742/* DeviceType Flags */
1583#define FILE_DEVICE_CD_ROM 0x00000002 1743#define FILE_DEVICE_CD_ROM 0x00000002
@@ -1602,14 +1762,14 @@ typedef struct {
1602typedef struct { 1762typedef struct {
1603 __le32 DeviceType; 1763 __le32 DeviceType;
1604 __le32 DeviceCharacteristics; 1764 __le32 DeviceCharacteristics;
1605} FILE_SYSTEM_DEVICE_INFO; /* device info, level 0x104 */ 1765} __attribute__((packed)) FILE_SYSTEM_DEVICE_INFO; /* device info, level 0x104 */
1606 1766
1607typedef struct { 1767typedef struct {
1608 __le32 Attributes; 1768 __le32 Attributes;
1609 __le32 MaxPathNameComponentLength; 1769 __le32 MaxPathNameComponentLength;
1610 __le32 FileSystemNameLen; 1770 __le32 FileSystemNameLen;
1611 char FileSystemName[52]; /* do not really need to save this - so potentially get only subset of name */ 1771 char FileSystemName[52]; /* do not really need to save this - so potentially get only subset of name */
1612} FILE_SYSTEM_ATTRIBUTE_INFO; 1772} __attribute__((packed)) FILE_SYSTEM_ATTRIBUTE_INFO;
1613 1773
1614/******************************************************************************/ 1774/******************************************************************************/
1615/* QueryFileInfo/QueryPathinfo (also for SetPath/SetFile) data buffer formats */ 1775/* QueryFileInfo/QueryPathinfo (also for SetPath/SetFile) data buffer formats */
@@ -1636,7 +1796,7 @@ typedef struct { /* data block encoding of response to level 263 QPathInfo */
1636 __le32 AlignmentRequirement; 1796 __le32 AlignmentRequirement;
1637 __le32 FileNameLength; 1797 __le32 FileNameLength;
1638 char FileName[1]; 1798 char FileName[1];
1639} FILE_ALL_INFO; /* level 0x107 QPathInfo */ 1799} __attribute__((packed)) FILE_ALL_INFO; /* level 0x107 QPathInfo */
1640 1800
1641/* defines for enumerating possible values of the Unix type field below */ 1801/* defines for enumerating possible values of the Unix type field below */
1642#define UNIX_FILE 0 1802#define UNIX_FILE 0
@@ -1660,11 +1820,11 @@ typedef struct {
1660 __u64 UniqueId; 1820 __u64 UniqueId;
1661 __le64 Permissions; 1821 __le64 Permissions;
1662 __le64 Nlinks; 1822 __le64 Nlinks;
1663} FILE_UNIX_BASIC_INFO; /* level 0x200 QPathInfo */ 1823} __attribute__((packed)) FILE_UNIX_BASIC_INFO; /* level 0x200 QPathInfo */
1664 1824
1665typedef struct { 1825typedef struct {
1666 char LinkDest[1]; 1826 char LinkDest[1];
1667} FILE_UNIX_LINK_INFO; /* level 0x201 QPathInfo */ 1827} __attribute__((packed)) FILE_UNIX_LINK_INFO; /* level 0x201 QPathInfo */
1668 1828
1669/* The following three structures are needed only for 1829/* The following three structures are needed only for
1670 setting time to NT4 and some older servers via 1830 setting time to NT4 and some older servers via
@@ -1673,13 +1833,13 @@ typedef struct {
1673 __u16 Day:5; 1833 __u16 Day:5;
1674 __u16 Month:4; 1834 __u16 Month:4;
1675 __u16 Year:7; 1835 __u16 Year:7;
1676} SMB_DATE; 1836} __attribute__((packed)) SMB_DATE;
1677 1837
1678typedef struct { 1838typedef struct {
1679 __u16 TwoSeconds:5; 1839 __u16 TwoSeconds:5;
1680 __u16 Minutes:6; 1840 __u16 Minutes:6;
1681 __u16 Hours:5; 1841 __u16 Hours:5;
1682} SMB_TIME; 1842} __attribute__((packed)) SMB_TIME;
1683 1843
1684typedef struct { 1844typedef struct {
1685 __le16 CreationDate; /* SMB Date see above */ 1845 __le16 CreationDate; /* SMB Date see above */
@@ -1692,7 +1852,7 @@ typedef struct {
1692 __le32 AllocationSize; 1852 __le32 AllocationSize;
1693 __le16 Attributes; /* verify not u32 */ 1853 __le16 Attributes; /* verify not u32 */
1694 __le32 EASize; 1854 __le32 EASize;
1695} FILE_INFO_STANDARD; /* level 1 SetPath/FileInfo */ 1855} __attribute__((packed)) FILE_INFO_STANDARD; /* level 1 SetPath/FileInfo */
1696 1856
1697typedef struct { 1857typedef struct {
1698 __le64 CreationTime; 1858 __le64 CreationTime;
@@ -1701,19 +1861,19 @@ typedef struct {
1701 __le64 ChangeTime; 1861 __le64 ChangeTime;
1702 __le32 Attributes; 1862 __le32 Attributes;
1703 __u32 Pad; 1863 __u32 Pad;
1704} FILE_BASIC_INFO; /* size info, level 0x101 */ 1864} __attribute__((packed)) FILE_BASIC_INFO; /* size info, level 0x101 */
1705 1865
1706struct file_allocation_info { 1866struct file_allocation_info {
1707 __le64 AllocationSize; /* Note old Samba srvr rounds this up too much */ 1867 __le64 AllocationSize; /* Note old Samba srvr rounds this up too much */
1708}; /* size used on disk, level 0x103 for set, 0x105 for query */ 1868} __attribute__((packed)); /* size used on disk, level 0x103 for set, 0x105 for query */
1709 1869
1710struct file_end_of_file_info { 1870struct file_end_of_file_info {
1711 __le64 FileSize; /* offset to end of file */ 1871 __le64 FileSize; /* offset to end of file */
1712}; /* size info, level 0x104 for set, 0x106 for query */ 1872} __attribute__((packed)); /* size info, level 0x104 for set, 0x106 for query */
1713 1873
1714struct file_alt_name_info { 1874struct file_alt_name_info {
1715 __u8 alt_name[1]; 1875 __u8 alt_name[1];
1716}; /* level 0x0108 */ 1876} __attribute__((packed)); /* level 0x0108 */
1717 1877
1718struct file_stream_info { 1878struct file_stream_info {
1719 __le32 number_of_streams; /* BB check sizes and verify location */ 1879 __le32 number_of_streams; /* BB check sizes and verify location */
@@ -1730,7 +1890,7 @@ struct file_compression_info {
1730 __u8 ch_shift; 1890 __u8 ch_shift;
1731 __u8 cl_shift; 1891 __u8 cl_shift;
1732 __u8 pad[3]; 1892 __u8 pad[3];
1733}; /* level 0x10b */ 1893} __attribute__((packed)); /* level 0x10b */
1734 1894
1735/* POSIX ACL set/query path info structures */ 1895/* POSIX ACL set/query path info structures */
1736#define CIFS_ACL_VERSION 1 1896#define CIFS_ACL_VERSION 1
@@ -1738,7 +1898,7 @@ struct cifs_posix_ace { /* access control entry (ACE) */
1738 __u8 cifs_e_tag; 1898 __u8 cifs_e_tag;
1739 __u8 cifs_e_perm; 1899 __u8 cifs_e_perm;
1740 __le64 cifs_uid; /* or gid */ 1900 __le64 cifs_uid; /* or gid */
1741}; 1901} __attribute__((packed));
1742 1902
1743struct cifs_posix_acl { /* access conrol list (ACL) */ 1903struct cifs_posix_acl { /* access conrol list (ACL) */
1744 __le16 version; 1904 __le16 version;
@@ -1747,7 +1907,7 @@ struct cifs_posix_acl { /* access conrol list (ACL) */
1747 struct cifs_posix_ace ace_array[0]; 1907 struct cifs_posix_ace ace_array[0];
1748 /* followed by 1908 /* followed by
1749 struct cifs_posix_ace default_ace_arraay[] */ 1909 struct cifs_posix_ace default_ace_arraay[] */
1750}; /* level 0x204 */ 1910} __attribute__((packed)); /* level 0x204 */
1751 1911
1752/* types of access control entries already defined in posix_acl.h */ 1912/* types of access control entries already defined in posix_acl.h */
1753/* #define CIFS_POSIX_ACL_USER_OBJ 0x01 1913/* #define CIFS_POSIX_ACL_USER_OBJ 0x01
@@ -1766,15 +1926,15 @@ struct cifs_posix_acl { /* access conrol list (ACL) */
1766 1926
1767struct file_internal_info { 1927struct file_internal_info {
1768 __u64 UniqueId; /* inode number */ 1928 __u64 UniqueId; /* inode number */
1769}; /* level 0x3ee */ 1929} __attribute__((packed)); /* level 0x3ee */
1770struct file_mode_info { 1930struct file_mode_info {
1771 __le32 Mode; 1931 __le32 Mode;
1772}; /* level 0x3f8 */ 1932} __attribute__((packed)); /* level 0x3f8 */
1773 1933
1774struct file_attrib_tag { 1934struct file_attrib_tag {
1775 __le32 Attribute; 1935 __le32 Attribute;
1776 __le32 ReparseTag; 1936 __le32 ReparseTag;
1777}; /* level 0x40b */ 1937} __attribute__((packed)); /* level 0x40b */
1778 1938
1779 1939
1780/********************************************************/ 1940/********************************************************/
@@ -1798,7 +1958,7 @@ typedef struct {
1798 __le64 Permissions; 1958 __le64 Permissions;
1799 __le64 Nlinks; 1959 __le64 Nlinks;
1800 char FileName[1]; 1960 char FileName[1];
1801} FILE_UNIX_INFO; /* level 0x202 */ 1961} __attribute__((packed)) FILE_UNIX_INFO; /* level 0x202 */
1802 1962
1803typedef struct { 1963typedef struct {
1804 __le32 NextEntryOffset; 1964 __le32 NextEntryOffset;
@@ -1812,7 +1972,7 @@ typedef struct {
1812 __le32 ExtFileAttributes; 1972 __le32 ExtFileAttributes;
1813 __le32 FileNameLength; 1973 __le32 FileNameLength;
1814 char FileName[1]; 1974 char FileName[1];
1815} FILE_DIRECTORY_INFO; /* level 0x101 FF response data area */ 1975} __attribute__((packed)) FILE_DIRECTORY_INFO; /* level 0x101 FF response data area */
1816 1976
1817typedef struct { 1977typedef struct {
1818 __le32 NextEntryOffset; 1978 __le32 NextEntryOffset;
@@ -1827,7 +1987,7 @@ typedef struct {
1827 __le32 FileNameLength; 1987 __le32 FileNameLength;
1828 __le32 EaSize; /* length of the xattrs */ 1988 __le32 EaSize; /* length of the xattrs */
1829 char FileName[1]; 1989 char FileName[1];
1830} FILE_FULL_DIRECTORY_INFO; /* level 0x102 FF response data area */ 1990} __attribute__((packed)) FILE_FULL_DIRECTORY_INFO; /* level 0x102 FF response data area */
1831 1991
1832typedef struct { 1992typedef struct {
1833 __le32 NextEntryOffset; 1993 __le32 NextEntryOffset;
@@ -1844,7 +2004,7 @@ typedef struct {
1844 __le32 Reserved; 2004 __le32 Reserved;
1845 __u64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/ 2005 __u64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/
1846 char FileName[1]; 2006 char FileName[1];
1847} SEARCH_ID_FULL_DIR_INFO; /* level 0x105 FF response data area */ 2007} __attribute__((packed)) SEARCH_ID_FULL_DIR_INFO; /* level 0x105 FF response data area */
1848 2008
1849typedef struct { 2009typedef struct {
1850 __le32 NextEntryOffset; 2010 __le32 NextEntryOffset;
@@ -1862,18 +2022,18 @@ typedef struct {
1862 __u8 Reserved; 2022 __u8 Reserved;
1863 __u8 ShortName[12]; 2023 __u8 ShortName[12];
1864 char FileName[1]; 2024 char FileName[1];
1865} FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FF response data area */ 2025} __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FF response data area */
1866 2026
1867 2027
1868struct gea { 2028struct gea {
1869 unsigned char name_len; 2029 unsigned char name_len;
1870 char name[1]; 2030 char name[1];
1871}; 2031} __attribute__((packed));
1872 2032
1873struct gealist { 2033struct gealist {
1874 unsigned long list_len; 2034 unsigned long list_len;
1875 struct gea list[1]; 2035 struct gea list[1];
1876}; 2036} __attribute__((packed));
1877 2037
1878struct fea { 2038struct fea {
1879 unsigned char EA_flags; 2039 unsigned char EA_flags;
@@ -1881,21 +2041,21 @@ struct fea {
1881 __le16 value_len; 2041 __le16 value_len;
1882 char name[1]; 2042 char name[1];
1883 /* optionally followed by value */ 2043 /* optionally followed by value */
1884}; 2044} __attribute__((packed));
1885/* flags for _FEA.fEA */ 2045/* flags for _FEA.fEA */
1886#define FEA_NEEDEA 0x80 /* need EA bit */ 2046#define FEA_NEEDEA 0x80 /* need EA bit */
1887 2047
1888struct fealist { 2048struct fealist {
1889 __le32 list_len; 2049 __le32 list_len;
1890 struct fea list[1]; 2050 struct fea list[1];
1891}; 2051} __attribute__((packed));
1892 2052
1893/* used to hold an arbitrary blob of data */ 2053/* used to hold an arbitrary blob of data */
1894struct data_blob { 2054struct data_blob {
1895 __u8 *data; 2055 __u8 *data;
1896 size_t length; 2056 size_t length;
1897 void (*free) (struct data_blob * data_blob); 2057 void (*free) (struct data_blob * data_blob);
1898}; 2058} __attribute__((packed));
1899 2059
1900 2060
1901#ifdef CONFIG_CIFS_POSIX 2061#ifdef CONFIG_CIFS_POSIX
@@ -1907,18 +2067,17 @@ struct data_blob {
1907 perhaps add a CreateDevice - to create Pipes and other special .inodes 2067 perhaps add a CreateDevice - to create Pipes and other special .inodes
1908 Also note POSIX open flags 2068 Also note POSIX open flags
1909 2) Close - to return the last write time to do cache across close more safely 2069 2) Close - to return the last write time to do cache across close more safely
1910 3) PosixQFSInfo - to return statfs info 2070 3) FindFirst return unique inode number - what about resume key, two
1911 4) FindFirst return unique inode number - what about resume key, two forms short (matches readdir) and full (enough info to cache inodes) 2071 forms short (matches readdir) and full (enough info to cache inodes)
1912 5) Mkdir - set mode 2072 4) Mkdir - set mode
1913 2073
1914 And under consideration: 2074 And under consideration:
1915 6) FindClose2 (return nanosecond timestamp ??) 2075 5) FindClose2 (return nanosecond timestamp ??)
1916 7) Use nanosecond timestamps throughout all time fields if 2076 6) Use nanosecond timestamps throughout all time fields if
1917 corresponding attribute flag is set 2077 corresponding attribute flag is set
1918 8) sendfile - handle based copy 2078 7) sendfile - handle based copy
1919 9) Direct i/o 2079 8) Direct i/o
1920 10) "POSIX ACL" support 2080 9) Misc fcntls?
1921 11) Misc fcntls?
1922 2081
1923 what about fixing 64 bit alignment 2082 what about fixing 64 bit alignment
1924 2083
@@ -1974,7 +2133,7 @@ struct data_blob {
1974 2133
1975 */ 2134 */
1976 2135
1977/* xsymlink is a symlink format that can be used 2136/* xsymlink is a symlink format (used by MacOS) that can be used
1978 to save symlink info in a regular file when 2137 to save symlink info in a regular file when
1979 mounted to operating systems that do not 2138 mounted to operating systems that do not
1980 support the cifs Unix extensions or EAs (for xattr 2139 support the cifs Unix extensions or EAs (for xattr
@@ -1999,7 +2158,7 @@ struct xsymlink {
1999 char cr2; /* \n */ 2158 char cr2; /* \n */
2000/* if room left, then end with \n then 0x20s by convention but not required */ 2159/* if room left, then end with \n then 0x20s by convention but not required */
2001 char path[1024]; 2160 char path[1024];
2002}; 2161} __attribute__((packed));
2003 2162
2004typedef struct file_xattr_info { 2163typedef struct file_xattr_info {
2005 /* BB do we need another field for flags? BB */ 2164 /* BB do we need another field for flags? BB */
@@ -2007,7 +2166,7 @@ typedef struct file_xattr_info {
2007 __u32 xattr_value_len; 2166 __u32 xattr_value_len;
2008 char xattr_name[0]; 2167 char xattr_name[0];
2009 /* followed by xattr_value[xattr_value_len], no pad */ 2168 /* followed by xattr_value[xattr_value_len], no pad */
2010} FILE_XATTR_INFO; /* extended attribute, info level 0x205 */ 2169} __attribute__((packed)) FILE_XATTR_INFO; /* extended attribute, info level 0x205 */
2011 2170
2012 2171
2013/* flags for chattr command */ 2172/* flags for chattr command */
@@ -2033,10 +2192,8 @@ typedef struct file_xattr_info {
2033typedef struct file_chattr_info { 2192typedef struct file_chattr_info {
2034 __le64 mask; /* list of all possible attribute bits */ 2193 __le64 mask; /* list of all possible attribute bits */
2035 __le64 mode; /* list of actual attribute bits on this inode */ 2194 __le64 mode; /* list of actual attribute bits on this inode */
2036} FILE_CHATTR_INFO; /* ext attributes (chattr, chflags) level 0x206 */ 2195} __attribute__((packed)) FILE_CHATTR_INFO; /* ext attributes (chattr, chflags) level 0x206 */
2037 2196
2038#endif 2197#endif
2039 2198
2040#pragma pack() /* resume default structure packing */
2041
2042#endif /* _CIFSPDU_H */ 2199#endif /* _CIFSPDU_H */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index ea239dea571e..d301149b1bb0 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -47,19 +47,24 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
47 struct smb_hdr * /* input */ , 47 struct smb_hdr * /* input */ ,
48 struct smb_hdr * /* out */ , 48 struct smb_hdr * /* out */ ,
49 int * /* bytes returned */ , const int long_op); 49 int * /* bytes returned */ , const int long_op);
50extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
51 struct kvec *, int /* nvec */,
52 int * /* bytes returned */ , const int long_op);
50extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid); 53extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid);
51extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); 54extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
52extern int is_valid_oplock_break(struct smb_hdr *smb); 55extern int is_valid_oplock_break(struct smb_hdr *smb);
53extern int is_size_safe_to_change(struct cifsInodeInfo *); 56extern int is_size_safe_to_change(struct cifsInodeInfo *);
57extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *);
54extern unsigned int smbCalcSize(struct smb_hdr *ptr); 58extern unsigned int smbCalcSize(struct smb_hdr *ptr);
59extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
55extern int decode_negTokenInit(unsigned char *security_blob, int length, 60extern int decode_negTokenInit(unsigned char *security_blob, int length,
56 enum securityEnum *secType); 61 enum securityEnum *secType);
57extern int cifs_inet_pton(int, char * source, void *dst); 62extern int cifs_inet_pton(int, char * source, void *dst);
58extern int map_smb_to_linux_error(struct smb_hdr *smb); 63extern int map_smb_to_linux_error(struct smb_hdr *smb);
59extern void header_assemble(struct smb_hdr *, char /* command */ , 64extern void header_assemble(struct smb_hdr *, char /* command */ ,
60 const struct cifsTconInfo *, int /* specifies length 65 const struct cifsTconInfo *, int /* length of
61 of fixed section (word count) in two byte units */ 66 fixed section (word count) in two byte units */);
62 ); 67extern __u16 GetNextMid(struct TCP_Server_Info *server);
63extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, 68extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16,
64 struct cifsTconInfo *); 69 struct cifsTconInfo *);
65extern void DeleteOplockQEntry(struct oplock_q_entry *); 70extern void DeleteOplockQEntry(struct oplock_q_entry *);
@@ -89,7 +94,7 @@ extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
89 94
90extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, 95extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
91 const char *searchName, const struct nls_table *nls_codepage, 96 const char *searchName, const struct nls_table *nls_codepage,
92 __u16 *searchHandle, struct cifs_search_info * psrch_inf, int map); 97 __u16 *searchHandle, struct cifs_search_info * psrch_inf, int map, const char dirsep);
93 98
94extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, 99extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
95 __u16 searchHandle, struct cifs_search_info * psrch_inf); 100 __u16 searchHandle, struct cifs_search_info * psrch_inf);
@@ -101,6 +106,10 @@ extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
101 const unsigned char *searchName, 106 const unsigned char *searchName,
102 FILE_ALL_INFO * findData, 107 FILE_ALL_INFO * findData,
103 const struct nls_table *nls_codepage, int remap); 108 const struct nls_table *nls_codepage, int remap);
109extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
110 const unsigned char *searchName,
111 FILE_ALL_INFO * findData,
112 const struct nls_table *nls_codepage, int remap);
104 113
105extern int CIFSSMBUnixQPathInfo(const int xid, 114extern int CIFSSMBUnixQPathInfo(const int xid,
106 struct cifsTconInfo *tcon, 115 struct cifsTconInfo *tcon,
@@ -125,6 +134,11 @@ extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
125 int remap); 134 int remap);
126extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, 135extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
127 struct kstatfs *FSData); 136 struct kstatfs *FSData);
137extern int SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon,
138 struct kstatfs *FSData);
139extern int CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon,
140 __u64 cap);
141
128extern int CIFSSMBQFSAttributeInfo(const int xid, 142extern int CIFSSMBQFSAttributeInfo(const int xid,
129 struct cifsTconInfo *tcon); 143 struct cifsTconInfo *tcon);
130extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon); 144extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon);
@@ -207,6 +221,11 @@ extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
207 const int access_flags, const int omode, 221 const int access_flags, const int omode,
208 __u16 * netfid, int *pOplock, FILE_ALL_INFO *, 222 __u16 * netfid, int *pOplock, FILE_ALL_INFO *,
209 const struct nls_table *nls_codepage, int remap); 223 const struct nls_table *nls_codepage, int remap);
224extern int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
225 const char *fileName, const int disposition,
226 const int access_flags, const int omode,
227 __u16 * netfid, int *pOplock, FILE_ALL_INFO *,
228 const struct nls_table *nls_codepage, int remap);
210extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, 229extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
211 const int smb_file_id); 230 const int smb_file_id);
212 231
@@ -222,7 +241,7 @@ extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
222extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, 241extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
223 const int netfid, const unsigned int count, 242 const int netfid, const unsigned int count,
224 const __u64 offset, unsigned int *nbytes, 243 const __u64 offset, unsigned int *nbytes,
225 const char __user *buf,const int long_op); 244 struct kvec *iov, const int nvec, const int long_op);
226extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, 245extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
227 const unsigned char *searchName, __u64 * inode_number, 246 const unsigned char *searchName, __u64 * inode_number,
228 const struct nls_table *nls_codepage, 247 const struct nls_table *nls_codepage,
@@ -264,7 +283,8 @@ extern int CIFSSMBCopy(int xid,
264 int remap_special_chars); 283 int remap_special_chars);
265extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 284extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
266 const int notify_subdirs,const __u16 netfid, 285 const int notify_subdirs,const __u16 netfid,
267 __u32 filter, const struct nls_table *nls_codepage); 286 __u32 filter, struct file * file, int multishot,
287 const struct nls_table *nls_codepage);
268extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, 288extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
269 const unsigned char *searchName, char * EAData, 289 const unsigned char *searchName, char * EAData,
270 size_t bufsize, const struct nls_table *nls_codepage, 290 size_t bufsize, const struct nls_table *nls_codepage,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 0db0b313d715..9312bfc56682 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -125,6 +125,9 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
125 rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon 125 rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon
126 , nls_codepage); 126 , nls_codepage);
127 up(&tcon->ses->sesSem); 127 up(&tcon->ses->sesSem);
128 /* BB FIXME add code to check if wsize needs
129 update due to negotiated smb buffer size
130 shrinking */
128 if(rc == 0) 131 if(rc == 0)
129 atomic_inc(&tconInfoReconnectCount); 132 atomic_inc(&tconInfoReconnectCount);
130 133
@@ -166,11 +169,9 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
166 169
167 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,wct); 170 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,wct);
168 171
169#ifdef CONFIG_CIFS_STATS 172 if(tcon != NULL)
170 if(tcon != NULL) { 173 cifs_stats_inc(&tcon->num_smbs_sent);
171 atomic_inc(&tcon->num_smbs_sent); 174
172 }
173#endif /* CONFIG_CIFS_STATS */
174 return rc; 175 return rc;
175} 176}
176 177
@@ -222,6 +223,9 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
222 rc = CIFSTCon(0, tcon->ses, tcon->treeName, 223 rc = CIFSTCon(0, tcon->ses, tcon->treeName,
223 tcon, nls_codepage); 224 tcon, nls_codepage);
224 up(&tcon->ses->sesSem); 225 up(&tcon->ses->sesSem);
226 /* BB FIXME add code to check if wsize needs
227 update due to negotiated smb buffer size
228 shrinking */
225 if(rc == 0) 229 if(rc == 0)
226 atomic_inc(&tconInfoReconnectCount); 230 atomic_inc(&tconInfoReconnectCount);
227 231
@@ -269,11 +273,9 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
269 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon, 273 header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
270 wct /*wct */ ); 274 wct /*wct */ );
271 275
272#ifdef CONFIG_CIFS_STATS 276 if(tcon != NULL)
273 if(tcon != NULL) { 277 cifs_stats_inc(&tcon->num_smbs_sent);
274 atomic_inc(&tcon->num_smbs_sent); 278
275 }
276#endif /* CONFIG_CIFS_STATS */
277 return rc; 279 return rc;
278} 280}
279 281
@@ -330,7 +332,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
330 (void **) &pSMB, (void **) &pSMBr); 332 (void **) &pSMB, (void **) &pSMBr);
331 if (rc) 333 if (rc)
332 return rc; 334 return rc;
333 335 pSMB->hdr.Mid = GetNextMid(server);
334 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; 336 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
335 if (extended_security) 337 if (extended_security)
336 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 338 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
@@ -422,8 +424,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
422 } 424 }
423 425
424 } 426 }
425 if (pSMB) 427
426 cifs_buf_release(pSMB); 428 cifs_buf_release(pSMB);
427 return rc; 429 return rc;
428} 430}
429 431
@@ -518,6 +520,8 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
518 smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */ 520 smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */
519 521
520 if(ses->server) { 522 if(ses->server) {
523 pSMB->hdr.Mid = GetNextMid(ses->server);
524
521 if(ses->server->secMode & 525 if(ses->server->secMode &
522 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 526 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
523 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 527 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
@@ -537,9 +541,8 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
537 rc = -ESHUTDOWN; 541 rc = -ESHUTDOWN;
538 } 542 }
539 } 543 }
540 if (pSMB)
541 cifs_small_buf_release(pSMB);
542 up(&ses->sesSem); 544 up(&ses->sesSem);
545 cifs_small_buf_release(pSMB);
543 546
544 /* if session dead then we do not need to do ulogoff, 547 /* if session dead then we do not need to do ulogoff,
545 since server closed smb session, no sense reporting 548 since server closed smb session, no sense reporting
@@ -583,14 +586,10 @@ DelFileRetry:
583 pSMB->ByteCount = cpu_to_le16(name_len + 1); 586 pSMB->ByteCount = cpu_to_le16(name_len + 1);
584 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 587 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
585 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 588 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
589 cifs_stats_inc(&tcon->num_deletes);
586 if (rc) { 590 if (rc) {
587 cFYI(1, ("Error in RMFile = %d", rc)); 591 cFYI(1, ("Error in RMFile = %d", rc));
588 } 592 }
589#ifdef CONFIG_CIFS_STATS
590 else {
591 atomic_inc(&tcon->num_deletes);
592 }
593#endif
594 593
595 cifs_buf_release(pSMB); 594 cifs_buf_release(pSMB);
596 if (rc == -EAGAIN) 595 if (rc == -EAGAIN)
@@ -632,14 +631,10 @@ RmDirRetry:
632 pSMB->ByteCount = cpu_to_le16(name_len + 1); 631 pSMB->ByteCount = cpu_to_le16(name_len + 1);
633 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 632 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
634 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 633 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
634 cifs_stats_inc(&tcon->num_rmdirs);
635 if (rc) { 635 if (rc) {
636 cFYI(1, ("Error in RMDir = %d", rc)); 636 cFYI(1, ("Error in RMDir = %d", rc));
637 } 637 }
638#ifdef CONFIG_CIFS_STATS
639 else {
640 atomic_inc(&tcon->num_rmdirs);
641 }
642#endif
643 638
644 cifs_buf_release(pSMB); 639 cifs_buf_release(pSMB);
645 if (rc == -EAGAIN) 640 if (rc == -EAGAIN)
@@ -680,20 +675,161 @@ MkDirRetry:
680 pSMB->ByteCount = cpu_to_le16(name_len + 1); 675 pSMB->ByteCount = cpu_to_le16(name_len + 1);
681 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 676 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
682 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 677 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
678 cifs_stats_inc(&tcon->num_mkdirs);
683 if (rc) { 679 if (rc) {
684 cFYI(1, ("Error in Mkdir = %d", rc)); 680 cFYI(1, ("Error in Mkdir = %d", rc));
685 } 681 }
686#ifdef CONFIG_CIFS_STATS 682
687 else {
688 atomic_inc(&tcon->num_mkdirs);
689 }
690#endif
691 cifs_buf_release(pSMB); 683 cifs_buf_release(pSMB);
692 if (rc == -EAGAIN) 684 if (rc == -EAGAIN)
693 goto MkDirRetry; 685 goto MkDirRetry;
694 return rc; 686 return rc;
695} 687}
696 688
689static __u16 convert_disposition(int disposition)
690{
691 __u16 ofun = 0;
692
693 switch (disposition) {
694 case FILE_SUPERSEDE:
695 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
696 break;
697 case FILE_OPEN:
698 ofun = SMBOPEN_OAPPEND;
699 break;
700 case FILE_CREATE:
701 ofun = SMBOPEN_OCREATE;
702 break;
703 case FILE_OPEN_IF:
704 ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
705 break;
706 case FILE_OVERWRITE:
707 ofun = SMBOPEN_OTRUNC;
708 break;
709 case FILE_OVERWRITE_IF:
710 ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
711 break;
712 default:
713 cFYI(1,("unknown disposition %d",disposition));
714 ofun = SMBOPEN_OAPPEND; /* regular open */
715 }
716 return ofun;
717}
718
719int
720SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
721 const char *fileName, const int openDisposition,
722 const int access_flags, const int create_options, __u16 * netfid,
723 int *pOplock, FILE_ALL_INFO * pfile_info,
724 const struct nls_table *nls_codepage, int remap)
725{
726 int rc = -EACCES;
727 OPENX_REQ *pSMB = NULL;
728 OPENX_RSP *pSMBr = NULL;
729 int bytes_returned;
730 int name_len;
731 __u16 count;
732
733OldOpenRetry:
734 rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
735 (void **) &pSMBr);
736 if (rc)
737 return rc;
738
739 pSMB->AndXCommand = 0xFF; /* none */
740
741 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
742 count = 1; /* account for one byte pad to word boundary */
743 name_len =
744 cifsConvertToUCS((__le16 *) (pSMB->fileName + 1),
745 fileName, PATH_MAX, nls_codepage, remap);
746 name_len++; /* trailing null */
747 name_len *= 2;
748 } else { /* BB improve check for buffer overruns BB */
749 count = 0; /* no pad */
750 name_len = strnlen(fileName, PATH_MAX);
751 name_len++; /* trailing null */
752 strncpy(pSMB->fileName, fileName, name_len);
753 }
754 if (*pOplock & REQ_OPLOCK)
755 pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
756 else if (*pOplock & REQ_BATCHOPLOCK) {
757 pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
758 }
759 pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
760 /* BB fixme add conversion for access_flags to bits 0 - 2 of mode */
761 /* 0 = read
762 1 = write
763 2 = rw
764 3 = execute
765 */
766 pSMB->Mode = cpu_to_le16(2);
767 pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
768 /* set file as system file if special file such
769 as fifo and server expecting SFU style and
770 no Unix extensions */
771
772 if(create_options & CREATE_OPTION_SPECIAL)
773 pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
774 else
775 pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); /* BB FIXME */
776
777 /* if ((omode & S_IWUGO) == 0)
778 pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
779 /* Above line causes problems due to vfs splitting create into two
780 pieces - need to set mode after file created not while it is
781 being created */
782
783 /* BB FIXME BB */
784/* pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); */
785 /* BB FIXME END BB */
786
787 pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
788 pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
789 count += name_len;
790 pSMB->hdr.smb_buf_length += count;
791
792 pSMB->ByteCount = cpu_to_le16(count);
793 /* long_op set to 1 to allow for oplock break timeouts */
794 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
795 (struct smb_hdr *) pSMBr, &bytes_returned, 1);
796 cifs_stats_inc(&tcon->num_opens);
797 if (rc) {
798 cFYI(1, ("Error in Open = %d", rc));
799 } else {
800 /* BB verify if wct == 15 */
801
802/* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field BB */
803
804 *netfid = pSMBr->Fid; /* cifs fid stays in le */
805 /* Let caller know file was created so we can set the mode. */
806 /* Do we care about the CreateAction in any other cases? */
807 /* BB FIXME BB */
808/* if(cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
809 *pOplock |= CIFS_CREATE_ACTION; */
810 /* BB FIXME END */
811
812 if(pfile_info) {
813 pfile_info->CreationTime = 0; /* BB convert CreateTime*/
814 pfile_info->LastAccessTime = 0; /* BB fixme */
815 pfile_info->LastWriteTime = 0; /* BB fixme */
816 pfile_info->ChangeTime = 0; /* BB fixme */
817 pfile_info->Attributes =
818 cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
819 /* the file_info buf is endian converted by caller */
820 pfile_info->AllocationSize =
821 cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
822 pfile_info->EndOfFile = pfile_info->AllocationSize;
823 pfile_info->NumberOfLinks = cpu_to_le32(1);
824 }
825 }
826
827 cifs_buf_release(pSMB);
828 if (rc == -EAGAIN)
829 goto OldOpenRetry;
830 return rc;
831}
832
697int 833int
698CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, 834CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
699 const char *fileName, const int openDisposition, 835 const char *fileName, const int openDisposition,
@@ -738,7 +874,13 @@ openRetry:
738 } 874 }
739 pSMB->DesiredAccess = cpu_to_le32(access_flags); 875 pSMB->DesiredAccess = cpu_to_le32(access_flags);
740 pSMB->AllocationSize = 0; 876 pSMB->AllocationSize = 0;
741 pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL); 877 /* set file as system file if special file such
878 as fifo and server expecting SFU style and
879 no Unix extensions */
880 if(create_options & CREATE_OPTION_SPECIAL)
881 pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
882 else
883 pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
742 /* XP does not handle ATTR_POSIX_SEMANTICS */ 884 /* XP does not handle ATTR_POSIX_SEMANTICS */
743 /* but it helps speed up case sensitive checks for other 885 /* but it helps speed up case sensitive checks for other
744 servers such as Samba */ 886 servers such as Samba */
@@ -752,7 +894,7 @@ openRetry:
752 being created */ 894 being created */
753 pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL); 895 pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
754 pSMB->CreateDisposition = cpu_to_le32(openDisposition); 896 pSMB->CreateDisposition = cpu_to_le32(openDisposition);
755 pSMB->CreateOptions = cpu_to_le32(create_options); 897 pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
756 /* BB Expirement with various impersonation levels and verify */ 898 /* BB Expirement with various impersonation levels and verify */
757 pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION); 899 pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
758 pSMB->SecurityFlags = 900 pSMB->SecurityFlags =
@@ -765,6 +907,7 @@ openRetry:
765 /* long_op set to 1 to allow for oplock break timeouts */ 907 /* long_op set to 1 to allow for oplock break timeouts */
766 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 908 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
767 (struct smb_hdr *) pSMBr, &bytes_returned, 1); 909 (struct smb_hdr *) pSMBr, &bytes_returned, 1);
910 cifs_stats_inc(&tcon->num_opens);
768 if (rc) { 911 if (rc) {
769 cFYI(1, ("Error in Open = %d", rc)); 912 cFYI(1, ("Error in Open = %d", rc));
770 } else { 913 } else {
@@ -782,11 +925,8 @@ openRetry:
782 pfile_info->EndOfFile = pSMBr->EndOfFile; 925 pfile_info->EndOfFile = pSMBr->EndOfFile;
783 pfile_info->NumberOfLinks = cpu_to_le32(1); 926 pfile_info->NumberOfLinks = cpu_to_le32(1);
784 } 927 }
785
786#ifdef CONFIG_CIFS_STATS
787 atomic_inc(&tcon->num_opens);
788#endif
789 } 928 }
929
790 cifs_buf_release(pSMB); 930 cifs_buf_release(pSMB);
791 if (rc == -EAGAIN) 931 if (rc == -EAGAIN)
792 goto openRetry; 932 goto openRetry;
@@ -807,11 +947,16 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
807 READ_RSP *pSMBr = NULL; 947 READ_RSP *pSMBr = NULL;
808 char *pReadData = NULL; 948 char *pReadData = NULL;
809 int bytes_returned; 949 int bytes_returned;
950 int wct;
810 951
811 cFYI(1,("Reading %d bytes on fid %d",count,netfid)); 952 cFYI(1,("Reading %d bytes on fid %d",count,netfid));
953 if(tcon->ses->capabilities & CAP_LARGE_FILES)
954 wct = 12;
955 else
956 wct = 10; /* old style read */
812 957
813 *nbytes = 0; 958 *nbytes = 0;
814 rc = smb_init(SMB_COM_READ_ANDX, 12, tcon, (void **) &pSMB, 959 rc = smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB,
815 (void **) &pSMBr); 960 (void **) &pSMBr);
816 if (rc) 961 if (rc)
817 return rc; 962 return rc;
@@ -823,14 +968,26 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
823 pSMB->AndXCommand = 0xFF; /* none */ 968 pSMB->AndXCommand = 0xFF; /* none */
824 pSMB->Fid = netfid; 969 pSMB->Fid = netfid;
825 pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); 970 pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
826 pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); 971 if(wct == 12)
972 pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
973 else if((lseek >> 32) > 0) /* can not handle this big offset for old */
974 return -EIO;
975
827 pSMB->Remaining = 0; 976 pSMB->Remaining = 0;
828 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); 977 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
829 pSMB->MaxCountHigh = cpu_to_le32(count >> 16); 978 pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
830 pSMB->ByteCount = 0; /* no need to do le conversion since it is 0 */ 979 if(wct == 12)
831 980 pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
981 else {
982 /* old style read */
983 struct smb_com_readx_req * pSMBW =
984 (struct smb_com_readx_req *)pSMB;
985 pSMBW->ByteCount = 0;
986 }
987
832 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 988 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
833 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 989 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
990 cifs_stats_inc(&tcon->num_reads);
834 if (rc) { 991 if (rc) {
835 cERROR(1, ("Send error in read = %d", rc)); 992 cERROR(1, ("Send error in read = %d", rc));
836 } else { 993 } else {
@@ -876,12 +1033,20 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
876 int rc = -EACCES; 1033 int rc = -EACCES;
877 WRITE_REQ *pSMB = NULL; 1034 WRITE_REQ *pSMB = NULL;
878 WRITE_RSP *pSMBr = NULL; 1035 WRITE_RSP *pSMBr = NULL;
879 int bytes_returned; 1036 int bytes_returned, wct;
880 __u32 bytes_sent; 1037 __u32 bytes_sent;
881 __u16 byte_count; 1038 __u16 byte_count;
882 1039
883 /* cFYI(1,("write at %lld %d bytes",offset,count));*/ 1040 /* cFYI(1,("write at %lld %d bytes",offset,count));*/
884 rc = smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB, 1041 if(tcon->ses == NULL)
1042 return -ECONNABORTED;
1043
1044 if(tcon->ses->capabilities & CAP_LARGE_FILES)
1045 wct = 14;
1046 else
1047 wct = 12;
1048
1049 rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
885 (void **) &pSMBr); 1050 (void **) &pSMBr);
886 if (rc) 1051 if (rc)
887 return rc; 1052 return rc;
@@ -892,7 +1057,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
892 pSMB->AndXCommand = 0xFF; /* none */ 1057 pSMB->AndXCommand = 0xFF; /* none */
893 pSMB->Fid = netfid; 1058 pSMB->Fid = netfid;
894 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1059 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
895 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1060 if(wct == 14)
1061 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1062 else if((offset >> 32) > 0) /* can not handle this big offset for old */
1063 return -EIO;
1064
896 pSMB->Reserved = 0xFFFFFFFF; 1065 pSMB->Reserved = 0xFFFFFFFF;
897 pSMB->WriteMode = 0; 1066 pSMB->WriteMode = 0;
898 pSMB->Remaining = 0; 1067 pSMB->Remaining = 0;
@@ -911,7 +1080,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
911 if (bytes_sent > count) 1080 if (bytes_sent > count)
912 bytes_sent = count; 1081 bytes_sent = count;
913 pSMB->DataOffset = 1082 pSMB->DataOffset =
914 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4); 1083 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
915 if(buf) 1084 if(buf)
916 memcpy(pSMB->Data,buf,bytes_sent); 1085 memcpy(pSMB->Data,buf,bytes_sent);
917 else if(ubuf) { 1086 else if(ubuf) {
@@ -919,20 +1088,31 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
919 cifs_buf_release(pSMB); 1088 cifs_buf_release(pSMB);
920 return -EFAULT; 1089 return -EFAULT;
921 } 1090 }
922 } else { 1091 } else if (count != 0) {
923 /* No buffer */ 1092 /* No buffer */
924 cifs_buf_release(pSMB); 1093 cifs_buf_release(pSMB);
925 return -EINVAL; 1094 return -EINVAL;
1095 } /* else setting file size with write of zero bytes */
1096 if(wct == 14)
1097 byte_count = bytes_sent + 1; /* pad */
1098 else /* wct == 12 */ {
1099 byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
926 } 1100 }
927
928 byte_count = bytes_sent + 1 /* pad */ ; /* BB fix this for sends > 64K */
929 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); 1101 pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
930 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); 1102 pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
931 pSMB->hdr.smb_buf_length += bytes_sent+1; 1103 pSMB->hdr.smb_buf_length += byte_count;
932 pSMB->ByteCount = cpu_to_le16(byte_count); 1104
1105 if(wct == 14)
1106 pSMB->ByteCount = cpu_to_le16(byte_count);
1107 else { /* old style write has byte count 4 bytes earlier so 4 bytes pad */
1108 struct smb_com_writex_req * pSMBW =
1109 (struct smb_com_writex_req *)pSMB;
1110 pSMBW->ByteCount = cpu_to_le16(byte_count);
1111 }
933 1112
934 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1113 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
935 (struct smb_hdr *) pSMBr, &bytes_returned, long_op); 1114 (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
1115 cifs_stats_inc(&tcon->num_writes);
936 if (rc) { 1116 if (rc) {
937 cFYI(1, ("Send error in write = %d", rc)); 1117 cFYI(1, ("Send error in write = %d", rc));
938 *nbytes = 0; 1118 *nbytes = 0;
@@ -951,56 +1131,72 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
951} 1131}
952 1132
953#ifdef CONFIG_CIFS_EXPERIMENTAL 1133#ifdef CONFIG_CIFS_EXPERIMENTAL
954int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, 1134int
1135CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
955 const int netfid, const unsigned int count, 1136 const int netfid, const unsigned int count,
956 const __u64 offset, unsigned int *nbytes, const char __user *buf, 1137 const __u64 offset, unsigned int *nbytes, struct kvec *iov,
957 const int long_op) 1138 int n_vec, const int long_op)
958{ 1139{
959 int rc = -EACCES; 1140 int rc = -EACCES;
960 WRITE_REQ *pSMB = NULL; 1141 WRITE_REQ *pSMB = NULL;
961 WRITE_RSP *pSMBr = NULL; 1142 int bytes_returned, wct;
962 /*int bytes_returned;*/ 1143 int smb_hdr_len;
963 unsigned bytes_sent;
964 __u16 byte_count;
965 1144
966 rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB); 1145 cFYI(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */
967 1146 if(tcon->ses->capabilities & CAP_LARGE_FILES)
1147 wct = 14;
1148 else
1149 wct = 12;
1150 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
968 if (rc) 1151 if (rc)
969 return rc; 1152 return rc;
970
971 pSMBr = (WRITE_RSP *)pSMB; /* BB removeme BB */
972
973 /* tcon and ses pointer are checked in smb_init */ 1153 /* tcon and ses pointer are checked in smb_init */
974 if (tcon->ses->server == NULL) 1154 if (tcon->ses->server == NULL)
975 return -ECONNABORTED; 1155 return -ECONNABORTED;
976 1156
977 pSMB->AndXCommand = 0xFF; /* none */ 1157 pSMB->AndXCommand = 0xFF; /* none */
978 pSMB->Fid = netfid; 1158 pSMB->Fid = netfid;
979 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); 1159 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
980 pSMB->OffsetHigh = cpu_to_le32(offset >> 32); 1160 if(wct == 14)
1161 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1162 else if((offset >> 32) > 0) /* can not handle this big offset for old */
1163 return -EIO;
981 pSMB->Reserved = 0xFFFFFFFF; 1164 pSMB->Reserved = 0xFFFFFFFF;
982 pSMB->WriteMode = 0; 1165 pSMB->WriteMode = 0;
983 pSMB->Remaining = 0; 1166 pSMB->Remaining = 0;
984 bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & ~0xFF; 1167
985 if (bytes_sent > count)
986 bytes_sent = count;
987 pSMB->DataLengthHigh = 0;
988 pSMB->DataOffset = 1168 pSMB->DataOffset =
989 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4); 1169 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
990 1170
991 byte_count = bytes_sent + 1 /* pad */ ; 1171 pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
992 pSMB->DataLengthLow = cpu_to_le16(bytes_sent); 1172 pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
993 pSMB->DataLengthHigh = 0; 1173 smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */
994 pSMB->hdr.smb_buf_length += byte_count; 1174 if(wct == 14)
995 pSMB->ByteCount = cpu_to_le16(byte_count); 1175 pSMB->hdr.smb_buf_length += count+1;
1176 else /* wct == 12 */
1177 pSMB->hdr.smb_buf_length += count+5; /* smb data starts later */
1178 if(wct == 14)
1179 pSMB->ByteCount = cpu_to_le16(count + 1);
1180 else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
1181 struct smb_com_writex_req * pSMBW =
1182 (struct smb_com_writex_req *)pSMB;
1183 pSMBW->ByteCount = cpu_to_le16(count + 5);
1184 }
1185 iov[0].iov_base = pSMB;
1186 iov[0].iov_len = smb_hdr_len + 4;
996 1187
997/* rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB, 1188 rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &bytes_returned,
998 (struct smb_hdr *) pSMBr, buf, buflen, &bytes_returned, long_op); */ /* BB fixme BB */ 1189 long_op);
1190 cifs_stats_inc(&tcon->num_writes);
999 if (rc) { 1191 if (rc) {
1000 cFYI(1, ("Send error in write2 (large write) = %d", rc)); 1192 cFYI(1, ("Send error Write2 = %d", rc));
1001 *nbytes = 0; 1193 *nbytes = 0;
1002 } else 1194 } else {
1003 *nbytes = le16_to_cpu(pSMBr->Count); 1195 WRITE_RSP * pSMBr = (WRITE_RSP *)pSMB;
1196 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1197 *nbytes = (*nbytes) << 16;
1198 *nbytes += le16_to_cpu(pSMBr->Count);
1199 }
1004 1200
1005 cifs_small_buf_release(pSMB); 1201 cifs_small_buf_release(pSMB);
1006 1202
@@ -1009,6 +1205,8 @@ int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1009 1205
1010 return rc; 1206 return rc;
1011} 1207}
1208
1209
1012#endif /* CIFS_EXPERIMENTAL */ 1210#endif /* CIFS_EXPERIMENTAL */
1013 1211
1014int 1212int
@@ -1065,7 +1263,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1065 1263
1066 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1264 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1067 (struct smb_hdr *) pSMBr, &bytes_returned, timeout); 1265 (struct smb_hdr *) pSMBr, &bytes_returned, timeout);
1068 1266 cifs_stats_inc(&tcon->num_locks);
1069 if (rc) { 1267 if (rc) {
1070 cFYI(1, ("Send error in Lock = %d", rc)); 1268 cFYI(1, ("Send error in Lock = %d", rc));
1071 } 1269 }
@@ -1099,6 +1297,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1099 pSMB->ByteCount = 0; 1297 pSMB->ByteCount = 0;
1100 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1298 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1101 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1299 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1300 cifs_stats_inc(&tcon->num_closes);
1102 if (rc) { 1301 if (rc) {
1103 if(rc!=-EINTR) { 1302 if(rc!=-EINTR) {
1104 /* EINTR is expected when user ctl-c to kill app */ 1303 /* EINTR is expected when user ctl-c to kill app */
@@ -1171,16 +1370,11 @@ renameRetry:
1171 1370
1172 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1371 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1173 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1372 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1373 cifs_stats_inc(&tcon->num_renames);
1174 if (rc) { 1374 if (rc) {
1175 cFYI(1, ("Send error in rename = %d", rc)); 1375 cFYI(1, ("Send error in rename = %d", rc));
1176 } 1376 }
1177 1377
1178#ifdef CONFIG_CIFS_STATS
1179 else {
1180 atomic_inc(&tcon->num_renames);
1181 }
1182#endif
1183
1184 cifs_buf_release(pSMB); 1378 cifs_buf_release(pSMB);
1185 1379
1186 if (rc == -EAGAIN) 1380 if (rc == -EAGAIN)
@@ -1255,14 +1449,11 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
1255 pSMB->ByteCount = cpu_to_le16(byte_count); 1449 pSMB->ByteCount = cpu_to_le16(byte_count);
1256 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB, 1450 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
1257 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1451 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1452 cifs_stats_inc(&pTcon->num_t2renames);
1258 if (rc) { 1453 if (rc) {
1259 cFYI(1,("Send error in Rename (by file handle) = %d", rc)); 1454 cFYI(1,("Send error in Rename (by file handle) = %d", rc));
1260 } 1455 }
1261#ifdef CONFIG_CIFS_STATS 1456
1262 else {
1263 atomic_inc(&pTcon->num_t2renames);
1264 }
1265#endif
1266 cifs_buf_release(pSMB); 1457 cifs_buf_release(pSMB);
1267 1458
1268 /* Note: On -EAGAIN error only caller can retry on handle based calls 1459 /* Note: On -EAGAIN error only caller can retry on handle based calls
@@ -1416,6 +1607,7 @@ createSymLinkRetry:
1416 pSMB->ByteCount = cpu_to_le16(byte_count); 1607 pSMB->ByteCount = cpu_to_le16(byte_count);
1417 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1608 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1418 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1609 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1610 cifs_stats_inc(&tcon->num_symlinks);
1419 if (rc) { 1611 if (rc) {
1420 cFYI(1, 1612 cFYI(1,
1421 ("Send error in SetPathInfo (create symlink) = %d", 1613 ("Send error in SetPathInfo (create symlink) = %d",
@@ -1505,6 +1697,7 @@ createHardLinkRetry:
1505 pSMB->ByteCount = cpu_to_le16(byte_count); 1697 pSMB->ByteCount = cpu_to_le16(byte_count);
1506 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1698 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1507 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1699 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1700 cifs_stats_inc(&tcon->num_hardlinks);
1508 if (rc) { 1701 if (rc) {
1509 cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc)); 1702 cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc));
1510 } 1703 }
@@ -1575,6 +1768,7 @@ winCreateHardLinkRetry:
1575 1768
1576 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1769 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1577 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1770 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1771 cifs_stats_inc(&tcon->num_hardlinks);
1578 if (rc) { 1772 if (rc) {
1579 cFYI(1, ("Send error in hard link (NT rename) = %d", rc)); 1773 cFYI(1, ("Send error in hard link (NT rename) = %d", rc));
1580 } 1774 }
@@ -1775,8 +1969,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
1775 } 1969 }
1776 } 1970 }
1777qreparse_out: 1971qreparse_out:
1778 if (pSMB) 1972 cifs_buf_release(pSMB);
1779 cifs_buf_release(pSMB);
1780 1973
1781 /* Note: On -EAGAIN error only caller can retry on handle based calls 1974 /* Note: On -EAGAIN error only caller can retry on handle based calls
1782 since file handle passed in no longer valid */ 1975 since file handle passed in no longer valid */
@@ -2165,6 +2358,67 @@ GetExtAttrOut:
2165 2358
2166#endif /* CONFIG_POSIX */ 2359#endif /* CONFIG_POSIX */
2167 2360
2361/* Legacy Query Path Information call for lookup to old servers such
2362 as Win9x/WinME */
2363int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
2364 const unsigned char *searchName,
2365 FILE_ALL_INFO * pFinfo,
2366 const struct nls_table *nls_codepage, int remap)
2367{
2368 QUERY_INFORMATION_REQ * pSMB;
2369 QUERY_INFORMATION_RSP * pSMBr;
2370 int rc = 0;
2371 int bytes_returned;
2372 int name_len;
2373
2374 cFYI(1, ("In SMBQPath path %s", searchName));
2375QInfRetry:
2376 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
2377 (void **) &pSMBr);
2378 if (rc)
2379 return rc;
2380
2381 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2382 name_len =
2383 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
2384 PATH_MAX, nls_codepage, remap);
2385 name_len++; /* trailing null */
2386 name_len *= 2;
2387 } else {
2388 name_len = strnlen(searchName, PATH_MAX);
2389 name_len++; /* trailing null */
2390 strncpy(pSMB->FileName, searchName, name_len);
2391 }
2392 pSMB->BufferFormat = 0x04;
2393 name_len++; /* account for buffer type byte */
2394 pSMB->hdr.smb_buf_length += (__u16) name_len;
2395 pSMB->ByteCount = cpu_to_le16(name_len);
2396
2397 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2398 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2399 if (rc) {
2400 cFYI(1, ("Send error in QueryInfo = %d", rc));
2401 } else if (pFinfo) { /* decode response */
2402 memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
2403 pFinfo->AllocationSize =
2404 cpu_to_le64(le32_to_cpu(pSMBr->size));
2405 pFinfo->EndOfFile = pFinfo->AllocationSize;
2406 pFinfo->Attributes =
2407 cpu_to_le32(le16_to_cpu(pSMBr->attr));
2408 } else
2409 rc = -EIO; /* bad buffer passed in */
2410
2411 cifs_buf_release(pSMB);
2412
2413 if (rc == -EAGAIN)
2414 goto QInfRetry;
2415
2416 return rc;
2417}
2418
2419
2420
2421
2168int 2422int
2169CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 2423CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
2170 const unsigned char *searchName, 2424 const unsigned char *searchName,
@@ -2396,7 +2650,7 @@ findUniqueRetry:
2396 if (rc) { 2650 if (rc) {
2397 cFYI(1, ("Send error in FindFileDirInfo = %d", rc)); 2651 cFYI(1, ("Send error in FindFileDirInfo = %d", rc));
2398 } else { /* decode response */ 2652 } else { /* decode response */
2399 2653 cifs_stats_inc(&tcon->num_ffirst);
2400 /* BB fill in */ 2654 /* BB fill in */
2401 } 2655 }
2402 2656
@@ -2414,7 +2668,7 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
2414 const char *searchName, 2668 const char *searchName,
2415 const struct nls_table *nls_codepage, 2669 const struct nls_table *nls_codepage,
2416 __u16 * pnetfid, 2670 __u16 * pnetfid,
2417 struct cifs_search_info * psrch_inf, int remap) 2671 struct cifs_search_info * psrch_inf, int remap, const char dirsep)
2418{ 2672{
2419/* level 257 SMB_ */ 2673/* level 257 SMB_ */
2420 TRANSACTION2_FFIRST_REQ *pSMB = NULL; 2674 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
@@ -2441,7 +2695,7 @@ findFirstRetry:
2441 it got remapped to 0xF03A as if it were part of the 2695 it got remapped to 0xF03A as if it were part of the
2442 directory name instead of a wildcard */ 2696 directory name instead of a wildcard */
2443 name_len *= 2; 2697 name_len *= 2;
2444 pSMB->FileName[name_len] = '\\'; 2698 pSMB->FileName[name_len] = dirsep;
2445 pSMB->FileName[name_len+1] = 0; 2699 pSMB->FileName[name_len+1] = 0;
2446 pSMB->FileName[name_len+2] = '*'; 2700 pSMB->FileName[name_len+2] = '*';
2447 pSMB->FileName[name_len+3] = 0; 2701 pSMB->FileName[name_len+3] = 0;
@@ -2455,7 +2709,7 @@ findFirstRetry:
2455 if(name_len > buffersize-header) 2709 if(name_len > buffersize-header)
2456 free buffer exit; BB */ 2710 free buffer exit; BB */
2457 strncpy(pSMB->FileName, searchName, name_len); 2711 strncpy(pSMB->FileName, searchName, name_len);
2458 pSMB->FileName[name_len] = '\\'; 2712 pSMB->FileName[name_len] = dirsep;
2459 pSMB->FileName[name_len+1] = '*'; 2713 pSMB->FileName[name_len+1] = '*';
2460 pSMB->FileName[name_len+2] = 0; 2714 pSMB->FileName[name_len+2] = 0;
2461 name_len += 3; 2715 name_len += 3;
@@ -2496,6 +2750,7 @@ findFirstRetry:
2496 2750
2497 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2751 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2498 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2752 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2753 cifs_stats_inc(&tcon->num_ffirst);
2499 2754
2500 if (rc) {/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */ 2755 if (rc) {/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */
2501 /* BB Add code to handle unsupported level rc */ 2756 /* BB Add code to handle unsupported level rc */
@@ -2617,7 +2872,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
2617 2872
2618 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 2873 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2619 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 2874 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2620 2875 cifs_stats_inc(&tcon->num_fnext);
2621 if (rc) { 2876 if (rc) {
2622 if (rc == -EBADF) { 2877 if (rc == -EBADF) {
2623 psrch_inf->endOfSearch = TRUE; 2878 psrch_inf->endOfSearch = TRUE;
@@ -2694,6 +2949,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle
2694 if (rc) { 2949 if (rc) {
2695 cERROR(1, ("Send error in FindClose = %d", rc)); 2950 cERROR(1, ("Send error in FindClose = %d", rc));
2696 } 2951 }
2952 cifs_stats_inc(&tcon->num_fclose);
2697 cifs_small_buf_release(pSMB); 2953 cifs_small_buf_release(pSMB);
2698 2954
2699 /* Since session is dead, search handle closed on server already */ 2955 /* Since session is dead, search handle closed on server already */
@@ -2827,7 +3083,10 @@ getDFSRetry:
2827 (void **) &pSMBr); 3083 (void **) &pSMBr);
2828 if (rc) 3084 if (rc)
2829 return rc; 3085 return rc;
2830 3086
3087 /* server pointer checked in called function,
3088 but should never be null here anyway */
3089 pSMB->hdr.Mid = GetNextMid(ses->server);
2831 pSMB->hdr.Tid = ses->ipc_tid; 3090 pSMB->hdr.Tid = ses->ipc_tid;
2832 pSMB->hdr.Uid = ses->Suid; 3091 pSMB->hdr.Uid = ses->Suid;
2833 if (ses->capabilities & CAP_STATUS32) { 3092 if (ses->capabilities & CAP_STATUS32) {
@@ -2968,6 +3227,92 @@ GetDFSRefExit:
2968 return rc; 3227 return rc;
2969} 3228}
2970 3229
3230/* Query File System Info such as free space to old servers such as Win 9x */
3231int
3232SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
3233{
3234/* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
3235 TRANSACTION2_QFSI_REQ *pSMB = NULL;
3236 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
3237 FILE_SYSTEM_ALLOC_INFO *response_data;
3238 int rc = 0;
3239 int bytes_returned = 0;
3240 __u16 params, byte_count;
3241
3242 cFYI(1, ("OldQFSInfo"));
3243oldQFSInfoRetry:
3244 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3245 (void **) &pSMBr);
3246 if (rc)
3247 return rc;
3248 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3249 (void **) &pSMBr);
3250 if (rc)
3251 return rc;
3252
3253 params = 2; /* level */
3254 pSMB->TotalDataCount = 0;
3255 pSMB->MaxParameterCount = cpu_to_le16(2);
3256 pSMB->MaxDataCount = cpu_to_le16(1000);
3257 pSMB->MaxSetupCount = 0;
3258 pSMB->Reserved = 0;
3259 pSMB->Flags = 0;
3260 pSMB->Timeout = 0;
3261 pSMB->Reserved2 = 0;
3262 byte_count = params + 1 /* pad */ ;
3263 pSMB->TotalParameterCount = cpu_to_le16(params);
3264 pSMB->ParameterCount = pSMB->TotalParameterCount;
3265 pSMB->ParameterOffset = cpu_to_le16(offsetof(
3266 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
3267 pSMB->DataCount = 0;
3268 pSMB->DataOffset = 0;
3269 pSMB->SetupCount = 1;
3270 pSMB->Reserved3 = 0;
3271 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
3272 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
3273 pSMB->hdr.smb_buf_length += byte_count;
3274 pSMB->ByteCount = cpu_to_le16(byte_count);
3275
3276 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3277 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3278 if (rc) {
3279 cFYI(1, ("Send error in QFSInfo = %d", rc));
3280 } else { /* decode response */
3281 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3282
3283 if (rc || (pSMBr->ByteCount < 18))
3284 rc = -EIO; /* bad smb */
3285 else {
3286 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3287 cFYI(1,("qfsinf resp BCC: %d Offset %d",
3288 pSMBr->ByteCount, data_offset));
3289
3290 response_data =
3291 (FILE_SYSTEM_ALLOC_INFO *)
3292 (((char *) &pSMBr->hdr.Protocol) + data_offset);
3293 FSData->f_bsize =
3294 le16_to_cpu(response_data->BytesPerSector) *
3295 le32_to_cpu(response_data->
3296 SectorsPerAllocationUnit);
3297 FSData->f_blocks =
3298 le32_to_cpu(response_data->TotalAllocationUnits);
3299 FSData->f_bfree = FSData->f_bavail =
3300 le32_to_cpu(response_data->FreeAllocationUnits);
3301 cFYI(1,
3302 ("Blocks: %lld Free: %lld Block size %ld",
3303 (unsigned long long)FSData->f_blocks,
3304 (unsigned long long)FSData->f_bfree,
3305 FSData->f_bsize));
3306 }
3307 }
3308 cifs_buf_release(pSMB);
3309
3310 if (rc == -EAGAIN)
3311 goto oldQFSInfoRetry;
3312
3313 return rc;
3314}
3315
2971int 3316int
2972CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData) 3317CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
2973{ 3318{
@@ -2989,7 +3334,7 @@ QFSInfoRetry:
2989 params = 2; /* level */ 3334 params = 2; /* level */
2990 pSMB->TotalDataCount = 0; 3335 pSMB->TotalDataCount = 0;
2991 pSMB->MaxParameterCount = cpu_to_le16(2); 3336 pSMB->MaxParameterCount = cpu_to_le16(2);
2992 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ 3337 pSMB->MaxDataCount = cpu_to_le16(1000);
2993 pSMB->MaxSetupCount = 0; 3338 pSMB->MaxSetupCount = 0;
2994 pSMB->Reserved = 0; 3339 pSMB->Reserved = 0;
2995 pSMB->Flags = 0; 3340 pSMB->Flags = 0;
@@ -3012,17 +3357,14 @@ QFSInfoRetry:
3012 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 3357 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3013 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3358 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3014 if (rc) { 3359 if (rc) {
3015 cERROR(1, ("Send error in QFSInfo = %d", rc)); 3360 cFYI(1, ("Send error in QFSInfo = %d", rc));
3016 } else { /* decode response */ 3361 } else { /* decode response */
3017 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3362 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3018 3363
3019 if (rc || (pSMBr->ByteCount < 24)) /* BB alsO CHEck enough total bytes returned */ 3364 if (rc || (pSMBr->ByteCount < 24))
3020 rc = -EIO; /* bad smb */ 3365 rc = -EIO; /* bad smb */
3021 else { 3366 else {
3022 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3367 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3023 cFYI(1,
3024 ("Decoding qfsinfo response. BCC: %d Offset %d",
3025 pSMBr->ByteCount, data_offset));
3026 3368
3027 response_data = 3369 response_data =
3028 (FILE_SYSTEM_INFO 3370 (FILE_SYSTEM_INFO
@@ -3257,6 +3599,77 @@ QFSUnixRetry:
3257 return rc; 3599 return rc;
3258} 3600}
3259 3601
3602int
3603CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap)
3604{
3605/* level 0x200 SMB_SET_CIFS_UNIX_INFO */
3606 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
3607 TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
3608 int rc = 0;
3609 int bytes_returned = 0;
3610 __u16 params, param_offset, offset, byte_count;
3611
3612 cFYI(1, ("In SETFSUnixInfo"));
3613SETFSUnixRetry:
3614 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3615 (void **) &pSMBr);
3616 if (rc)
3617 return rc;
3618
3619 params = 4; /* 2 bytes zero followed by info level. */
3620 pSMB->MaxSetupCount = 0;
3621 pSMB->Reserved = 0;
3622 pSMB->Flags = 0;
3623 pSMB->Timeout = 0;
3624 pSMB->Reserved2 = 0;
3625 param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum) - 4;
3626 offset = param_offset + params;
3627
3628 pSMB->MaxParameterCount = cpu_to_le16(4);
3629 pSMB->MaxDataCount = cpu_to_le16(100); /* BB find exact max SMB PDU from sess structure BB */
3630 pSMB->SetupCount = 1;
3631 pSMB->Reserved3 = 0;
3632 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
3633 byte_count = 1 /* pad */ + params + 12;
3634
3635 pSMB->DataCount = cpu_to_le16(12);
3636 pSMB->ParameterCount = cpu_to_le16(params);
3637 pSMB->TotalDataCount = pSMB->DataCount;
3638 pSMB->TotalParameterCount = pSMB->ParameterCount;
3639 pSMB->ParameterOffset = cpu_to_le16(param_offset);
3640 pSMB->DataOffset = cpu_to_le16(offset);
3641
3642 /* Params. */
3643 pSMB->FileNum = 0;
3644 pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
3645
3646 /* Data. */
3647 pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
3648 pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
3649 pSMB->ClientUnixCap = cpu_to_le64(cap);
3650
3651 pSMB->hdr.smb_buf_length += byte_count;
3652 pSMB->ByteCount = cpu_to_le16(byte_count);
3653
3654 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3655 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3656 if (rc) {
3657 cERROR(1, ("Send error in SETFSUnixInfo = %d", rc));
3658 } else { /* decode response */
3659 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3660 if (rc) {
3661 rc = -EIO; /* bad smb */
3662 }
3663 }
3664 cifs_buf_release(pSMB);
3665
3666 if (rc == -EAGAIN)
3667 goto SETFSUnixRetry;
3668
3669 return rc;
3670}
3671
3672
3260 3673
3261int 3674int
3262CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, 3675CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
@@ -3321,16 +3734,16 @@ QFSPosixRetry:
3321 le64_to_cpu(response_data->TotalBlocks); 3734 le64_to_cpu(response_data->TotalBlocks);
3322 FSData->f_bfree = 3735 FSData->f_bfree =
3323 le64_to_cpu(response_data->BlocksAvail); 3736 le64_to_cpu(response_data->BlocksAvail);
3324 if(response_data->UserBlocksAvail == -1) { 3737 if(response_data->UserBlocksAvail == cpu_to_le64(-1)) {
3325 FSData->f_bavail = FSData->f_bfree; 3738 FSData->f_bavail = FSData->f_bfree;
3326 } else { 3739 } else {
3327 FSData->f_bavail = 3740 FSData->f_bavail =
3328 le64_to_cpu(response_data->UserBlocksAvail); 3741 le64_to_cpu(response_data->UserBlocksAvail);
3329 } 3742 }
3330 if(response_data->TotalFileNodes != -1) 3743 if(response_data->TotalFileNodes != cpu_to_le64(-1))
3331 FSData->f_files = 3744 FSData->f_files =
3332 le64_to_cpu(response_data->TotalFileNodes); 3745 le64_to_cpu(response_data->TotalFileNodes);
3333 if(response_data->FreeFileNodes != -1) 3746 if(response_data->FreeFileNodes != cpu_to_le64(-1))
3334 FSData->f_ffree = 3747 FSData->f_ffree =
3335 le64_to_cpu(response_data->FreeFileNodes); 3748 le64_to_cpu(response_data->FreeFileNodes);
3336 } 3749 }
@@ -3376,7 +3789,7 @@ SetEOFRetry:
3376 PATH_MAX, nls_codepage, remap); 3789 PATH_MAX, nls_codepage, remap);
3377 name_len++; /* trailing null */ 3790 name_len++; /* trailing null */
3378 name_len *= 2; 3791 name_len *= 2;
3379 } else { /* BB improve the check for buffer overruns BB */ 3792 } else { /* BB improve the check for buffer overruns BB */
3380 name_len = strnlen(fileName, PATH_MAX); 3793 name_len = strnlen(fileName, PATH_MAX);
3381 name_len++; /* trailing null */ 3794 name_len++; /* trailing null */
3382 strncpy(pSMB->FileName, fileName, name_len); 3795 strncpy(pSMB->FileName, fileName, name_len);
@@ -3384,7 +3797,7 @@ SetEOFRetry:
3384 params = 6 + name_len; 3797 params = 6 + name_len;
3385 data_count = sizeof (struct file_end_of_file_info); 3798 data_count = sizeof (struct file_end_of_file_info);
3386 pSMB->MaxParameterCount = cpu_to_le16(2); 3799 pSMB->MaxParameterCount = cpu_to_le16(2);
3387 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */ 3800 pSMB->MaxDataCount = cpu_to_le16(4100);
3388 pSMB->MaxSetupCount = 0; 3801 pSMB->MaxSetupCount = 0;
3389 pSMB->Reserved = 0; 3802 pSMB->Reserved = 0;
3390 pSMB->Flags = 0; 3803 pSMB->Flags = 0;
@@ -3766,7 +4179,7 @@ setPermsRetry:
3766 PATH_MAX, nls_codepage, remap); 4179 PATH_MAX, nls_codepage, remap);
3767 name_len++; /* trailing null */ 4180 name_len++; /* trailing null */
3768 name_len *= 2; 4181 name_len *= 2;
3769 } else { /* BB improve the check for buffer overruns BB */ 4182 } else { /* BB improve the check for buffer overruns BB */
3770 name_len = strnlen(fileName, PATH_MAX); 4183 name_len = strnlen(fileName, PATH_MAX);
3771 name_len++; /* trailing null */ 4184 name_len++; /* trailing null */
3772 strncpy(pSMB->FileName, fileName, name_len); 4185 strncpy(pSMB->FileName, fileName, name_len);
@@ -3839,12 +4252,14 @@ setPermsRetry:
3839} 4252}
3840 4253
3841int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 4254int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
3842 const int notify_subdirs, const __u16 netfid, 4255 const int notify_subdirs, const __u16 netfid,
3843 __u32 filter, const struct nls_table *nls_codepage) 4256 __u32 filter, struct file * pfile, int multishot,
4257 const struct nls_table *nls_codepage)
3844{ 4258{
3845 int rc = 0; 4259 int rc = 0;
3846 struct smb_com_transaction_change_notify_req * pSMB = NULL; 4260 struct smb_com_transaction_change_notify_req * pSMB = NULL;
3847 struct smb_com_transaction_change_notify_rsp * pSMBr = NULL; 4261 struct smb_com_transaction_change_notify_rsp * pSMBr = NULL;
4262 struct dir_notify_req *dnotify_req;
3848 int bytes_returned; 4263 int bytes_returned;
3849 4264
3850 cFYI(1, ("In CIFSSMBNotify for file handle %d",(int)netfid)); 4265 cFYI(1, ("In CIFSSMBNotify for file handle %d",(int)netfid));
@@ -3877,6 +4292,28 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
3877 (struct smb_hdr *) pSMBr, &bytes_returned, -1); 4292 (struct smb_hdr *) pSMBr, &bytes_returned, -1);
3878 if (rc) { 4293 if (rc) {
3879 cFYI(1, ("Error in Notify = %d", rc)); 4294 cFYI(1, ("Error in Notify = %d", rc));
4295 } else {
4296 /* Add file to outstanding requests */
4297 /* BB change to kmem cache alloc */
4298 dnotify_req = (struct dir_notify_req *) kmalloc(
4299 sizeof(struct dir_notify_req),
4300 GFP_KERNEL);
4301 if(dnotify_req) {
4302 dnotify_req->Pid = pSMB->hdr.Pid;
4303 dnotify_req->PidHigh = pSMB->hdr.PidHigh;
4304 dnotify_req->Mid = pSMB->hdr.Mid;
4305 dnotify_req->Tid = pSMB->hdr.Tid;
4306 dnotify_req->Uid = pSMB->hdr.Uid;
4307 dnotify_req->netfid = netfid;
4308 dnotify_req->pfile = pfile;
4309 dnotify_req->filter = filter;
4310 dnotify_req->multishot = multishot;
4311 spin_lock(&GlobalMid_Lock);
4312 list_add_tail(&dnotify_req->lhead,
4313 &GlobalDnotifyReqList);
4314 spin_unlock(&GlobalMid_Lock);
4315 } else
4316 rc = -ENOMEM;
3880 } 4317 }
3881 cifs_buf_release(pSMB); 4318 cifs_buf_release(pSMB);
3882 return rc; 4319 return rc;
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 47360156cc54..d74367a08d51 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -29,6 +29,8 @@
29#include <linux/utsname.h> 29#include <linux/utsname.h>
30#include <linux/mempool.h> 30#include <linux/mempool.h>
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/completion.h>
33#include <linux/pagevec.h>
32#include <asm/uaccess.h> 34#include <asm/uaccess.h>
33#include <asm/processor.h> 35#include <asm/processor.h>
34#include "cifspdu.h" 36#include "cifspdu.h"
@@ -44,6 +46,8 @@
44#define CIFS_PORT 445 46#define CIFS_PORT 445
45#define RFC1001_PORT 139 47#define RFC1001_PORT 139
46 48
49static DECLARE_COMPLETION(cifsd_complete);
50
47extern void SMBencrypt(unsigned char *passwd, unsigned char *c8, 51extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
48 unsigned char *p24); 52 unsigned char *p24);
49extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, 53extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
@@ -60,6 +64,7 @@ struct smb_vol {
60 char *in6_addr; /* ipv6 address as human readable form of in6_addr */ 64 char *in6_addr; /* ipv6 address as human readable form of in6_addr */
61 char *iocharset; /* local code page for mapping to and from Unicode */ 65 char *iocharset; /* local code page for mapping to and from Unicode */
62 char source_rfc1001_name[16]; /* netbios name of client */ 66 char source_rfc1001_name[16]; /* netbios name of client */
67 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
63 uid_t linux_uid; 68 uid_t linux_uid;
64 gid_t linux_gid; 69 gid_t linux_gid;
65 mode_t file_mode; 70 mode_t file_mode;
@@ -74,6 +79,10 @@ struct smb_vol {
74 unsigned server_ino:1; /* use inode numbers from server ie UniqueId */ 79 unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
75 unsigned direct_io:1; 80 unsigned direct_io:1;
76 unsigned remap:1; /* set to remap seven reserved chars in filenames */ 81 unsigned remap:1; /* set to remap seven reserved chars in filenames */
82 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */
83 unsigned sfu_emul:1;
84 unsigned nocase; /* request case insensitive filenames */
85 unsigned nobrl; /* disable sending byte range locks to srv */
77 unsigned int rsize; 86 unsigned int rsize;
78 unsigned int wsize; 87 unsigned int wsize;
79 unsigned int sockopt; 88 unsigned int sockopt;
@@ -82,7 +91,8 @@ struct smb_vol {
82 91
83static int ipv4_connect(struct sockaddr_in *psin_server, 92static int ipv4_connect(struct sockaddr_in *psin_server,
84 struct socket **csocket, 93 struct socket **csocket,
85 char * netb_name); 94 char * netb_name,
95 char * server_netb_name);
86static int ipv6_connect(struct sockaddr_in6 *psin_server, 96static int ipv6_connect(struct sockaddr_in6 *psin_server,
87 struct socket **csocket); 97 struct socket **csocket);
88 98
@@ -175,9 +185,11 @@ cifs_reconnect(struct TCP_Server_Info *server)
175 } else { 185 } else {
176 rc = ipv4_connect(&server->addr.sockAddr, 186 rc = ipv4_connect(&server->addr.sockAddr,
177 &server->ssocket, 187 &server->ssocket,
178 server->workstation_RFC1001_name); 188 server->workstation_RFC1001_name,
189 server->server_RFC1001_name);
179 } 190 }
180 if(rc) { 191 if(rc) {
192 cFYI(1,("reconnect error %d",rc));
181 msleep(3000); 193 msleep(3000);
182 } else { 194 } else {
183 atomic_inc(&tcpSesReconnectCount); 195 atomic_inc(&tcpSesReconnectCount);
@@ -293,12 +305,12 @@ static int coalesce_t2(struct smb_hdr * psecond, struct smb_hdr *pTargetSMB)
293 byte_count += total_in_buf2; 305 byte_count += total_in_buf2;
294 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count); 306 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
295 307
296 byte_count = be32_to_cpu(pTargetSMB->smb_buf_length); 308 byte_count = pTargetSMB->smb_buf_length;
297 byte_count += total_in_buf2; 309 byte_count += total_in_buf2;
298 310
299 /* BB also add check that we are not beyond maximum buffer size */ 311 /* BB also add check that we are not beyond maximum buffer size */
300 312
301 pTargetSMB->smb_buf_length = cpu_to_be32(byte_count); 313 pTargetSMB->smb_buf_length = byte_count;
302 314
303 if(remaining == total_in_buf2) { 315 if(remaining == total_in_buf2) {
304 cFYI(1,("found the last secondary response")); 316 cFYI(1,("found the last secondary response"));
@@ -323,7 +335,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
323 struct cifsSesInfo *ses; 335 struct cifsSesInfo *ses;
324 struct task_struct *task_to_wake = NULL; 336 struct task_struct *task_to_wake = NULL;
325 struct mid_q_entry *mid_entry; 337 struct mid_q_entry *mid_entry;
326 char *temp; 338 char temp;
327 int isLargeBuf = FALSE; 339 int isLargeBuf = FALSE;
328 int isMultiRsp; 340 int isMultiRsp;
329 int reconnect; 341 int reconnect;
@@ -337,6 +349,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
337 atomic_inc(&tcpSesAllocCount); 349 atomic_inc(&tcpSesAllocCount);
338 length = tcpSesAllocCount.counter; 350 length = tcpSesAllocCount.counter;
339 write_unlock(&GlobalSMBSeslock); 351 write_unlock(&GlobalSMBSeslock);
352 complete(&cifsd_complete);
340 if(length > 1) { 353 if(length > 1) {
341 mempool_resize(cifs_req_poolp, 354 mempool_resize(cifs_req_poolp,
342 length + cifs_min_rcv, 355 length + cifs_min_rcv,
@@ -424,22 +437,32 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
424 continue; 437 continue;
425 } 438 }
426 439
427 /* the right amount was read from socket - 4 bytes */ 440 /* The right amount was read from socket - 4 bytes */
441 /* so we can now interpret the length field */
442
443 /* the first byte big endian of the length field,
444 is actually not part of the length but the type
445 with the most common, zero, as regular data */
446 temp = *((char *) smb_buffer);
428 447
448 /* Note that FC 1001 length is big endian on the wire,
449 but we convert it here so it is always manipulated
450 as host byte order */
429 pdu_length = ntohl(smb_buffer->smb_buf_length); 451 pdu_length = ntohl(smb_buffer->smb_buf_length);
430 cFYI(1,("rfc1002 length(big endian)0x%x)", pdu_length+4)); 452 smb_buffer->smb_buf_length = pdu_length;
453
454 cFYI(1,("rfc1002 length 0x%x)", pdu_length+4));
431 455
432 temp = (char *) smb_buffer; 456 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
433 if (temp[0] == (char) RFC1002_SESSION_KEEP_ALIVE) {
434 continue; 457 continue;
435 } else if (temp[0] == (char)RFC1002_POSITIVE_SESSION_RESPONSE) { 458 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
436 cFYI(1,("Good RFC 1002 session rsp")); 459 cFYI(1,("Good RFC 1002 session rsp"));
437 continue; 460 continue;
438 } else if (temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) { 461 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
439 /* we get this from Windows 98 instead of 462 /* we get this from Windows 98 instead of
440 an error on SMB negprot response */ 463 an error on SMB negprot response */
441 cFYI(1,("Negative RFC1002 Session Response Error 0x%x)", 464 cFYI(1,("Negative RFC1002 Session Response Error 0x%x)",
442 temp[4])); 465 pdu_length));
443 if(server->tcpStatus == CifsNew) { 466 if(server->tcpStatus == CifsNew) {
444 /* if nack on negprot (rather than 467 /* if nack on negprot (rather than
445 ret of smb negprot error) reconnecting 468 ret of smb negprot error) reconnecting
@@ -461,9 +484,10 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
461 wake_up(&server->response_q); 484 wake_up(&server->response_q);
462 continue; 485 continue;
463 } 486 }
464 } else if (temp[0] != (char) 0) { 487 } else if (temp != (char) 0) {
465 cERROR(1,("Unknown RFC 1002 frame")); 488 cERROR(1,("Unknown RFC 1002 frame"));
466 cifs_dump_mem(" Received Data: ", temp, length); 489 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
490 length);
467 cifs_reconnect(server); 491 cifs_reconnect(server);
468 csocket = server->ssocket; 492 csocket = server->ssocket;
469 continue; 493 continue;
@@ -533,7 +557,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
533 557
534 dump_smb(smb_buffer, length); 558 dump_smb(smb_buffer, length);
535 if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) { 559 if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) {
536 cERROR(1, ("Bad SMB Received ")); 560 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
537 continue; 561 continue;
538 } 562 }
539 563
@@ -581,6 +605,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
581multi_t2_fnd: 605multi_t2_fnd:
582 task_to_wake = mid_entry->tsk; 606 task_to_wake = mid_entry->tsk;
583 mid_entry->midState = MID_RESPONSE_RECEIVED; 607 mid_entry->midState = MID_RESPONSE_RECEIVED;
608#ifdef CONFIG_CIFS_STATS2
609 mid_entry->when_received = jiffies;
610#endif
584 break; 611 break;
585 } 612 }
586 } 613 }
@@ -598,7 +625,8 @@ multi_t2_fnd:
598 } else if ((is_valid_oplock_break(smb_buffer) == FALSE) 625 } else if ((is_valid_oplock_break(smb_buffer) == FALSE)
599 && (isMultiRsp == FALSE)) { 626 && (isMultiRsp == FALSE)) {
600 cERROR(1, ("No task to wake, unknown frame rcvd!")); 627 cERROR(1, ("No task to wake, unknown frame rcvd!"));
601 cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr)); 628 cifs_dump_mem("Received Data is: ",(char *)smb_buffer,
629 sizeof(struct smb_hdr));
602 } 630 }
603 } /* end while !EXITING */ 631 } /* end while !EXITING */
604 632
@@ -676,7 +704,7 @@ multi_t2_fnd:
676 msleep(125); 704 msleep(125);
677 } 705 }
678 706
679 if (list_empty(&server->pending_mid_q)) { 707 if (!list_empty(&server->pending_mid_q)) {
680 /* mpx threads have not exited yet give them 708 /* mpx threads have not exited yet give them
681 at least the smb send timeout time for long ops */ 709 at least the smb send timeout time for long ops */
682 /* due to delays on oplock break requests, we need 710 /* due to delays on oplock break requests, we need
@@ -713,7 +741,7 @@ multi_t2_fnd:
713 GFP_KERNEL); 741 GFP_KERNEL);
714 } 742 }
715 743
716 msleep(250); 744 complete_and_exit(&cifsd_complete, 0);
717 return 0; 745 return 0;
718} 746}
719 747
@@ -737,7 +765,9 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
737 toupper(system_utsname.nodename[i]); 765 toupper(system_utsname.nodename[i]);
738 } 766 }
739 vol->source_rfc1001_name[15] = 0; 767 vol->source_rfc1001_name[15] = 0;
740 768 /* null target name indicates to use *SMBSERVR default called name
769 if we end up sending RFC1001 session initialize */
770 vol->target_rfc1001_name[0] = 0;
741 vol->linux_uid = current->uid; /* current->euid instead? */ 771 vol->linux_uid = current->uid; /* current->euid instead? */
742 vol->linux_gid = current->gid; 772 vol->linux_gid = current->gid;
743 vol->dir_mode = S_IRWXUGO; 773 vol->dir_mode = S_IRWXUGO;
@@ -747,6 +777,9 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
747 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ 777 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
748 vol->rw = TRUE; 778 vol->rw = TRUE;
749 779
780 /* default is always to request posix paths. */
781 vol->posix_paths = 1;
782
750 if (!options) 783 if (!options)
751 return 1; 784 return 1;
752 785
@@ -987,7 +1020,31 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
987 /* The string has 16th byte zero still from 1020 /* The string has 16th byte zero still from
988 set at top of the function */ 1021 set at top of the function */
989 if((i==15) && (value[i] != 0)) 1022 if((i==15) && (value[i] != 0))
990 printk(KERN_WARNING "CIFS: netbiosname longer than 15 and was truncated.\n"); 1023 printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n");
1024 }
1025 } else if (strnicmp(data, "servern", 7) == 0) {
1026 /* servernetbiosname specified override *SMBSERVER */
1027 if (!value || !*value || (*value == ' ')) {
1028 cFYI(1,("empty server netbiosname specified"));
1029 } else {
1030 /* last byte, type, is 0x20 for servr type */
1031 memset(vol->target_rfc1001_name,0x20,16);
1032
1033 for(i=0;i<15;i++) {
1034 /* BB are there cases in which a comma can be
1035 valid in this workstation netbios name (and need
1036 special handling)? */
1037
1038 /* user or mount helper must uppercase netbiosname */
1039 if (value[i]==0)
1040 break;
1041 else
1042 vol->target_rfc1001_name[i] = value[i];
1043 }
1044 /* The string has 16th byte zero still from
1045 set at top of the function */
1046 if((i==15) && (value[i] != 0))
1047 printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n");
991 } 1048 }
992 } else if (strnicmp(data, "credentials", 4) == 0) { 1049 } else if (strnicmp(data, "credentials", 4) == 0) {
993 /* ignore */ 1050 /* ignore */
@@ -1025,6 +1082,27 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1025 vol->remap = 1; 1082 vol->remap = 1;
1026 } else if (strnicmp(data, "nomapchars", 10) == 0) { 1083 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1027 vol->remap = 0; 1084 vol->remap = 0;
1085 } else if (strnicmp(data, "sfu", 3) == 0) {
1086 vol->sfu_emul = 1;
1087 } else if (strnicmp(data, "nosfu", 5) == 0) {
1088 vol->sfu_emul = 0;
1089 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1090 vol->posix_paths = 1;
1091 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1092 vol->posix_paths = 0;
1093 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1094 (strnicmp(data, "ignorecase", 10) == 0)) {
1095 vol->nocase = 1;
1096 } else if (strnicmp(data, "brl", 3) == 0) {
1097 vol->nobrl = 0;
1098 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1099 (strnicmp(data, "nolock", 6) == 0)) {
1100 vol->nobrl = 1;
1101 /* turn off mandatory locking in mode
1102 if remote locking is turned off since the
1103 local vfs will do advisory */
1104 if(vol->file_mode == (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1105 vol->file_mode = S_IALLUGO;
1028 } else if (strnicmp(data, "setuids", 7) == 0) { 1106 } else if (strnicmp(data, "setuids", 7) == 0) {
1029 vol->setuids = 1; 1107 vol->setuids = 1;
1030 } else if (strnicmp(data, "nosetuids", 9) == 0) { 1108 } else if (strnicmp(data, "nosetuids", 9) == 0) {
@@ -1244,7 +1322,7 @@ static void rfc1002mangle(char * target,char * source, unsigned int length)
1244 1322
1245static int 1323static int
1246ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, 1324ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1247 char * netbios_name) 1325 char * netbios_name, char * target_name)
1248{ 1326{
1249 int rc = 0; 1327 int rc = 0;
1250 int connected = 0; 1328 int connected = 0;
@@ -1309,10 +1387,16 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1309 /* Eventually check for other socket options to change from 1387 /* Eventually check for other socket options to change from
1310 the default. sock_setsockopt not used because it expects 1388 the default. sock_setsockopt not used because it expects
1311 user space buffer */ 1389 user space buffer */
1390 cFYI(1,("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",(*csocket)->sk->sk_sndbuf,
1391 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1312 (*csocket)->sk->sk_rcvtimeo = 7 * HZ; 1392 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1393 /* make the bufsizes depend on wsize/rsize and max requests */
1394 if((*csocket)->sk->sk_sndbuf < (200 * 1024))
1395 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1396 if((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1397 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1313 1398
1314 /* send RFC1001 sessinit */ 1399 /* send RFC1001 sessinit */
1315
1316 if(psin_server->sin_port == htons(RFC1001_PORT)) { 1400 if(psin_server->sin_port == htons(RFC1001_PORT)) {
1317 /* some servers require RFC1001 sessinit before sending 1401 /* some servers require RFC1001 sessinit before sending
1318 negprot - BB check reconnection in case where second 1402 negprot - BB check reconnection in case where second
@@ -1322,8 +1406,14 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1322 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet), GFP_KERNEL); 1406 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet), GFP_KERNEL);
1323 if(ses_init_buf) { 1407 if(ses_init_buf) {
1324 ses_init_buf->trailer.session_req.called_len = 32; 1408 ses_init_buf->trailer.session_req.called_len = 32;
1325 rfc1002mangle(ses_init_buf->trailer.session_req.called_name, 1409 if(target_name && (target_name[0] != 0)) {
1326 DEFAULT_CIFS_CALLED_NAME,16); 1410 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1411 target_name, 16);
1412 } else {
1413 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1414 DEFAULT_CIFS_CALLED_NAME,16);
1415 }
1416
1327 ses_init_buf->trailer.session_req.calling_len = 32; 1417 ses_init_buf->trailer.session_req.calling_len = 32;
1328 /* calling name ends in null (byte 16) from old smb 1418 /* calling name ends in null (byte 16) from old smb
1329 convention. */ 1419 convention. */
@@ -1556,7 +1646,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1556 sin_server.sin_port = htons(volume_info.port); 1646 sin_server.sin_port = htons(volume_info.port);
1557 else 1647 else
1558 sin_server.sin_port = 0; 1648 sin_server.sin_port = 0;
1559 rc = ipv4_connect(&sin_server,&csocket,volume_info.source_rfc1001_name); 1649 rc = ipv4_connect(&sin_server,&csocket,
1650 volume_info.source_rfc1001_name,
1651 volume_info.target_rfc1001_name);
1560 if (rc < 0) { 1652 if (rc < 0) {
1561 cERROR(1, 1653 cERROR(1,
1562 ("Error connecting to IPv4 socket. Aborting operation")); 1654 ("Error connecting to IPv4 socket. Aborting operation"));
@@ -1606,9 +1698,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1606 kfree(volume_info.password); 1698 kfree(volume_info.password);
1607 FreeXid(xid); 1699 FreeXid(xid);
1608 return rc; 1700 return rc;
1609 } else 1701 }
1610 rc = 0; 1702 wait_for_completion(&cifsd_complete);
1703 rc = 0;
1611 memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16); 1704 memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16);
1705 memcpy(srvTcp->server_RFC1001_name, volume_info.target_rfc1001_name,16);
1612 srvTcp->sequence_number = 0; 1706 srvTcp->sequence_number = 0;
1613 } 1707 }
1614 } 1708 }
@@ -1653,17 +1747,27 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1653 1747
1654 /* search for existing tcon to this server share */ 1748 /* search for existing tcon to this server share */
1655 if (!rc) { 1749 if (!rc) {
1656 if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize)) 1750 if(volume_info.rsize > CIFSMaxBufSize) {
1751 cERROR(1,("rsize %d too large, using MaxBufSize",
1752 volume_info.rsize));
1753 cifs_sb->rsize = CIFSMaxBufSize;
1754 } else if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize))
1657 cifs_sb->rsize = volume_info.rsize; 1755 cifs_sb->rsize = volume_info.rsize;
1658 else 1756 else /* default */
1659 cifs_sb->rsize = srvTcp->maxBuf - MAX_CIFS_HDR_SIZE; /* default */ 1757 cifs_sb->rsize = CIFSMaxBufSize;
1660 if((volume_info.wsize) && (volume_info.wsize <= CIFSMaxBufSize)) 1758
1759 if(volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
1760 cERROR(1,("wsize %d too large using 4096 instead",
1761 volume_info.wsize));
1762 cifs_sb->wsize = 4096;
1763 } else if(volume_info.wsize)
1661 cifs_sb->wsize = volume_info.wsize; 1764 cifs_sb->wsize = volume_info.wsize;
1662 else 1765 else
1663 cifs_sb->wsize = CIFSMaxBufSize; /* default */ 1766 cifs_sb->wsize = CIFSMaxBufSize; /* default */
1664 if(cifs_sb->rsize < PAGE_CACHE_SIZE) { 1767 if(cifs_sb->rsize < PAGE_CACHE_SIZE) {
1665 cifs_sb->rsize = PAGE_CACHE_SIZE; 1768 cifs_sb->rsize = PAGE_CACHE_SIZE;
1666 cERROR(1,("Attempt to set readsize for mount to less than one page (4096)")); 1769 /* Windows ME does this */
1770 cFYI(1,("Attempt to set readsize for mount to less than one page (4096)"));
1667 } 1771 }
1668 cifs_sb->mnt_uid = volume_info.linux_uid; 1772 cifs_sb->mnt_uid = volume_info.linux_uid;
1669 cifs_sb->mnt_gid = volume_info.linux_gid; 1773 cifs_sb->mnt_gid = volume_info.linux_gid;
@@ -1681,8 +1785,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1681 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR; 1785 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
1682 if(volume_info.no_xattr) 1786 if(volume_info.no_xattr)
1683 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; 1787 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
1788 if(volume_info.sfu_emul)
1789 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
1790 if(volume_info.nobrl)
1791 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
1792
1684 if(volume_info.direct_io) { 1793 if(volume_info.direct_io) {
1685 cERROR(1,("mounting share using direct i/o")); 1794 cFYI(1,("mounting share using direct i/o"));
1686 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; 1795 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
1687 } 1796 }
1688 1797
@@ -1696,6 +1805,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1696 to the same server share the last value passed in 1805 to the same server share the last value passed in
1697 for the retry flag is used */ 1806 for the retry flag is used */
1698 tcon->retry = volume_info.retry; 1807 tcon->retry = volume_info.retry;
1808 tcon->nocase = volume_info.nocase;
1699 } else { 1809 } else {
1700 tcon = tconInfoAlloc(); 1810 tcon = tconInfoAlloc();
1701 if (tcon == NULL) 1811 if (tcon == NULL)
@@ -1724,6 +1834,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1724 if (!rc) { 1834 if (!rc) {
1725 atomic_inc(&pSesInfo->inUse); 1835 atomic_inc(&pSesInfo->inUse);
1726 tcon->retry = volume_info.retry; 1836 tcon->retry = volume_info.retry;
1837 tcon->nocase = volume_info.nocase;
1727 } 1838 }
1728 } 1839 }
1729 } 1840 }
@@ -1745,8 +1856,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1745 spin_lock(&GlobalMid_Lock); 1856 spin_lock(&GlobalMid_Lock);
1746 srvTcp->tcpStatus = CifsExiting; 1857 srvTcp->tcpStatus = CifsExiting;
1747 spin_unlock(&GlobalMid_Lock); 1858 spin_unlock(&GlobalMid_Lock);
1748 if(srvTcp->tsk) 1859 if(srvTcp->tsk) {
1749 send_sig(SIGKILL,srvTcp->tsk,1); 1860 send_sig(SIGKILL,srvTcp->tsk,1);
1861 wait_for_completion(&cifsd_complete);
1862 }
1750 } 1863 }
1751 /* If find_unc succeeded then rc == 0 so we can not end */ 1864 /* If find_unc succeeded then rc == 0 so we can not end */
1752 if (tcon) /* up accidently freeing someone elses tcon struct */ 1865 if (tcon) /* up accidently freeing someone elses tcon struct */
@@ -1759,8 +1872,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1759 temp_rc = CIFSSMBLogoff(xid, pSesInfo); 1872 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
1760 /* if the socketUseCount is now zero */ 1873 /* if the socketUseCount is now zero */
1761 if((temp_rc == -ESHUTDOWN) && 1874 if((temp_rc == -ESHUTDOWN) &&
1762 (pSesInfo->server->tsk)) 1875 (pSesInfo->server->tsk)) {
1763 send_sig(SIGKILL,pSesInfo->server->tsk,1); 1876 send_sig(SIGKILL,pSesInfo->server->tsk,1);
1877 wait_for_completion(&cifsd_complete);
1878 }
1764 } else 1879 } else
1765 cFYI(1, ("No session or bad tcon")); 1880 cFYI(1, ("No session or bad tcon"));
1766 sesInfoFree(pSesInfo); 1881 sesInfoFree(pSesInfo);
@@ -1783,8 +1898,27 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1783 cFYI(1,("server negotiated posix acl support")); 1898 cFYI(1,("server negotiated posix acl support"));
1784 sb->s_flags |= MS_POSIXACL; 1899 sb->s_flags |= MS_POSIXACL;
1785 } 1900 }
1901
1902 /* Try and negotiate POSIX pathnames if we can. */
1903 if (volume_info.posix_paths && (CIFS_UNIX_POSIX_PATHNAMES_CAP &
1904 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
1905 if (!CIFSSMBSetFSUnixInfo(xid, tcon, CIFS_UNIX_POSIX_PATHNAMES_CAP)) {
1906 cFYI(1,("negotiated posix pathnames support"));
1907 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;
1908 } else {
1909 cFYI(1,("posix pathnames support requested but not supported"));
1910 }
1911 }
1786 } 1912 }
1787 } 1913 }
1914 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
1915 cifs_sb->wsize = min(cifs_sb->wsize,
1916 (tcon->ses->server->maxBuf -
1917 MAX_CIFS_HDR_SIZE));
1918 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
1919 cifs_sb->rsize = min(cifs_sb->rsize,
1920 (tcon->ses->server->maxBuf -
1921 MAX_CIFS_HDR_SIZE));
1788 } 1922 }
1789 1923
1790 /* volume_info.password is freed above when existing session found 1924 /* volume_info.password is freed above when existing session found
@@ -1832,6 +1966,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
1832 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, 1966 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
1833 NULL /* no tCon exists yet */ , 13 /* wct */ ); 1967 NULL /* no tCon exists yet */ , 13 /* wct */ );
1834 1968
1969 smb_buffer->Mid = GetNextMid(ses->server);
1835 pSMB->req_no_secext.AndXCommand = 0xFF; 1970 pSMB->req_no_secext.AndXCommand = 0xFF;
1836 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); 1971 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
1837 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq); 1972 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
@@ -2107,6 +2242,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2107 /* send SMBsessionSetup here */ 2242 /* send SMBsessionSetup here */
2108 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, 2243 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2109 NULL /* no tCon exists yet */ , 12 /* wct */ ); 2244 NULL /* no tCon exists yet */ , 12 /* wct */ );
2245
2246 smb_buffer->Mid = GetNextMid(ses->server);
2110 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 2247 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2111 pSMB->req.AndXCommand = 0xFF; 2248 pSMB->req.AndXCommand = 0xFF;
2112 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); 2249 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
@@ -2373,6 +2510,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2373 /* send SMBsessionSetup here */ 2510 /* send SMBsessionSetup here */
2374 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, 2511 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2375 NULL /* no tCon exists yet */ , 12 /* wct */ ); 2512 NULL /* no tCon exists yet */ , 12 /* wct */ );
2513
2514 smb_buffer->Mid = GetNextMid(ses->server);
2376 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 2515 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2377 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT); 2516 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2378 2517
@@ -2715,6 +2854,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2715 /* send SMBsessionSetup here */ 2854 /* send SMBsessionSetup here */
2716 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, 2855 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2717 NULL /* no tCon exists yet */ , 12 /* wct */ ); 2856 NULL /* no tCon exists yet */ , 12 /* wct */ );
2857
2858 smb_buffer->Mid = GetNextMid(ses->server);
2718 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT); 2859 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2719 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 2860 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2720 pSMB->req.AndXCommand = 0xFF; 2861 pSMB->req.AndXCommand = 0xFF;
@@ -3086,6 +3227,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3086 3227
3087 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, 3228 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3088 NULL /*no tid */ , 4 /*wct */ ); 3229 NULL /*no tid */ , 4 /*wct */ );
3230
3231 smb_buffer->Mid = GetNextMid(ses->server);
3089 smb_buffer->Uid = ses->Suid; 3232 smb_buffer->Uid = ses->Suid;
3090 pSMB = (TCONX_REQ *) smb_buffer; 3233 pSMB = (TCONX_REQ *) smb_buffer;
3091 pSMBr = (TCONX_RSP *) smb_buffer_response; 3234 pSMBr = (TCONX_RSP *) smb_buffer_response;
@@ -3207,8 +3350,10 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3207 return 0; 3350 return 0;
3208 } else if (rc == -ESHUTDOWN) { 3351 } else if (rc == -ESHUTDOWN) {
3209 cFYI(1,("Waking up socket by sending it signal")); 3352 cFYI(1,("Waking up socket by sending it signal"));
3210 if(cifsd_task) 3353 if(cifsd_task) {
3211 send_sig(SIGKILL,cifsd_task,1); 3354 send_sig(SIGKILL,cifsd_task,1);
3355 wait_for_completion(&cifsd_complete);
3356 }
3212 rc = 0; 3357 rc = 0;
3213 } /* else - we have an smb session 3358 } /* else - we have an smb session
3214 left on this socket do not kill cifsd */ 3359 left on this socket do not kill cifsd */
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index d335269bd91c..8dfe717a332a 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -48,6 +48,7 @@ build_path_from_dentry(struct dentry *direntry)
48 struct dentry *temp; 48 struct dentry *temp;
49 int namelen = 0; 49 int namelen = 0;
50 char *full_path; 50 char *full_path;
51 char dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb));
51 52
52 if(direntry == NULL) 53 if(direntry == NULL)
53 return NULL; /* not much we can do if dentry is freed and 54 return NULL; /* not much we can do if dentry is freed and
@@ -74,7 +75,7 @@ cifs_bp_rename_retry:
74 if (namelen < 0) { 75 if (namelen < 0) {
75 break; 76 break;
76 } else { 77 } else {
77 full_path[namelen] = '\\'; 78 full_path[namelen] = dirsep;
78 strncpy(full_path + namelen + 1, temp->d_name.name, 79 strncpy(full_path + namelen + 1, temp->d_name.name,
79 temp->d_name.len); 80 temp->d_name.len);
80 cFYI(0, (" name: %s ", full_path + namelen)); 81 cFYI(0, (" name: %s ", full_path + namelen));
@@ -183,6 +184,13 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
183 desiredAccess, CREATE_NOT_DIR, 184 desiredAccess, CREATE_NOT_DIR,
184 &fileHandle, &oplock, buf, cifs_sb->local_nls, 185 &fileHandle, &oplock, buf, cifs_sb->local_nls,
185 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 186 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
187 if(rc == -EIO) {
188 /* old server, retry the open legacy style */
189 rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
190 desiredAccess, CREATE_NOT_DIR,
191 &fileHandle, &oplock, buf, cifs_sb->local_nls,
192 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
193 }
186 if (rc) { 194 if (rc) {
187 cFYI(1, ("cifs_create returned 0x%x ", rc)); 195 cFYI(1, ("cifs_create returned 0x%x ", rc));
188 } else { 196 } else {
@@ -208,7 +216,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
208 CIFS_MOUNT_MAP_SPECIAL_CHR); 216 CIFS_MOUNT_MAP_SPECIAL_CHR);
209 } 217 }
210 else { 218 else {
211 /* BB implement via Windows security descriptors */ 219 /* BB implement mode setting via Windows security descriptors */
212 /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/ 220 /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
213 /* could set r/o dos attribute if mode & 0222 == 0 */ 221 /* could set r/o dos attribute if mode & 0222 == 0 */
214 } 222 }
@@ -225,10 +233,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
225 } 233 }
226 234
227 if (rc != 0) { 235 if (rc != 0) {
228 cFYI(1,("Create worked but get_inode_info failed with rc = %d", 236 cFYI(1,
237 ("Create worked but get_inode_info failed rc = %d",
229 rc)); 238 rc));
230 } else { 239 } else {
231 direntry->d_op = &cifs_dentry_ops; 240 if (pTcon->nocase)
241 direntry->d_op = &cifs_ci_dentry_ops;
242 else
243 direntry->d_op = &cifs_dentry_ops;
232 d_instantiate(direntry, newinode); 244 d_instantiate(direntry, newinode);
233 } 245 }
234 if((nd->flags & LOOKUP_OPEN) == FALSE) { 246 if((nd->flags & LOOKUP_OPEN) == FALSE) {
@@ -302,8 +314,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
302 up(&direntry->d_sb->s_vfs_rename_sem); 314 up(&direntry->d_sb->s_vfs_rename_sem);
303 if(full_path == NULL) 315 if(full_path == NULL)
304 rc = -ENOMEM; 316 rc = -ENOMEM;
305 317 else if (pTcon->ses->capabilities & CAP_UNIX) {
306 if (full_path && (pTcon->ses->capabilities & CAP_UNIX)) {
307 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 318 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
308 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, 319 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path,
309 mode,(__u64)current->euid,(__u64)current->egid, 320 mode,(__u64)current->euid,(__u64)current->egid,
@@ -321,10 +332,49 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
321 if(!rc) { 332 if(!rc) {
322 rc = cifs_get_inode_info_unix(&newinode, full_path, 333 rc = cifs_get_inode_info_unix(&newinode, full_path,
323 inode->i_sb,xid); 334 inode->i_sb,xid);
324 direntry->d_op = &cifs_dentry_ops; 335 if (pTcon->nocase)
336 direntry->d_op = &cifs_ci_dentry_ops;
337 else
338 direntry->d_op = &cifs_dentry_ops;
325 if(rc == 0) 339 if(rc == 0)
326 d_instantiate(direntry, newinode); 340 d_instantiate(direntry, newinode);
327 } 341 }
342 } else {
343 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
344 int oplock = 0;
345 u16 fileHandle;
346 FILE_ALL_INFO * buf;
347
348 cFYI(1,("sfu compat create special file"));
349
350 buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
351 if(buf == NULL) {
352 kfree(full_path);
353 FreeXid(xid);
354 return -ENOMEM;
355 }
356
357 rc = CIFSSMBOpen(xid, pTcon, full_path,
358 FILE_CREATE, /* fail if exists */
359 GENERIC_WRITE /* BB would
360 WRITE_OWNER | WRITE_DAC be better? */,
361 /* Create a file and set the
362 file attribute to SYSTEM */
363 CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
364 &fileHandle, &oplock, buf,
365 cifs_sb->local_nls,
366 cifs_sb->mnt_cifs_flags &
367 CIFS_MOUNT_MAP_SPECIAL_CHR);
368
369 if(!rc) {
370 /* BB Do not bother to decode buf since no
371 local inode yet to put timestamps in */
372 CIFSSMBClose(xid, pTcon, fileHandle);
373 d_drop(direntry);
374 }
375 kfree(buf);
376 /* add code here to set EAs */
377 }
328 } 378 }
329 379
330 kfree(full_path); 380 kfree(full_path);
@@ -381,7 +431,10 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
381 parent_dir_inode->i_sb,xid); 431 parent_dir_inode->i_sb,xid);
382 432
383 if ((rc == 0) && (newInode != NULL)) { 433 if ((rc == 0) && (newInode != NULL)) {
384 direntry->d_op = &cifs_dentry_ops; 434 if (pTcon->nocase)
435 direntry->d_op = &cifs_ci_dentry_ops;
436 else
437 direntry->d_op = &cifs_dentry_ops;
385 d_add(direntry, newInode); 438 d_add(direntry, newInode);
386 439
387 /* since paths are not looked up by component - the parent directories are presumed to be good here */ 440 /* since paths are not looked up by component - the parent directories are presumed to be good here */
@@ -440,3 +493,42 @@ struct dentry_operations cifs_dentry_ops = {
440/* d_delete: cifs_d_delete, *//* not needed except for debugging */ 493/* d_delete: cifs_d_delete, *//* not needed except for debugging */
441 /* no need for d_hash, d_compare, d_release, d_iput ... yet. BB confirm this BB */ 494 /* no need for d_hash, d_compare, d_release, d_iput ... yet. BB confirm this BB */
442}; 495};
496
497static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
498{
499 struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
500 unsigned long hash;
501 int i;
502
503 hash = init_name_hash();
504 for (i = 0; i < q->len; i++)
505 hash = partial_name_hash(nls_tolower(codepage, q->name[i]),
506 hash);
507 q->hash = end_name_hash(hash);
508
509 return 0;
510}
511
512static int cifs_ci_compare(struct dentry *dentry, struct qstr *a,
513 struct qstr *b)
514{
515 struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
516
517 if ((a->len == b->len) &&
518 (nls_strnicmp(codepage, a->name, b->name, a->len) == 0)) {
519 /*
520 * To preserve case, don't let an existing negative dentry's
521 * case take precedence. If a is not a negative dentry, this
522 * should have no side effects
523 */
524 memcpy((unsigned char *)a->name, b->name, a->len);
525 return 0;
526 }
527 return 1;
528}
529
530struct dentry_operations cifs_ci_dentry_ops = {
531 .d_revalidate = cifs_d_revalidate,
532 .d_hash = cifs_ci_hash,
533 .d_compare = cifs_ci_compare,
534};
diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c
index 7d2a9202c39a..a7a47bb36bf3 100644
--- a/fs/cifs/fcntl.c
+++ b/fs/cifs/fcntl.c
@@ -78,6 +78,10 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
78 __u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES; 78 __u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES;
79 __u16 netfid; 79 __u16 netfid;
80 80
81
82 if(experimEnabled == 0)
83 return 0;
84
81 xid = GetXid(); 85 xid = GetXid();
82 cifs_sb = CIFS_SB(file->f_dentry->d_sb); 86 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
83 pTcon = cifs_sb->tcon; 87 pTcon = cifs_sb->tcon;
@@ -100,8 +104,10 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
100 } else { 104 } else {
101 filter = convert_to_cifs_notify_flags(arg); 105 filter = convert_to_cifs_notify_flags(arg);
102 if(filter != 0) { 106 if(filter != 0) {
103 rc = CIFSSMBNotify(xid, pTcon, 0 /* no subdirs */, netfid, 107 rc = CIFSSMBNotify(xid, pTcon,
104 filter, cifs_sb->local_nls); 108 0 /* no subdirs */, netfid,
109 filter, file, arg & DN_MULTISHOT,
110 cifs_sb->local_nls);
105 } else { 111 } else {
106 rc = -EINVAL; 112 rc = -EINVAL;
107 } 113 }
@@ -109,7 +115,7 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
109 it would close automatically but may be a way 115 it would close automatically but may be a way
110 to do it easily when inode freed or when 116 to do it easily when inode freed or when
111 notify info is cleared/changed */ 117 notify info is cleared/changed */
112 cERROR(1,("notify rc %d",rc)); 118 cFYI(1,("notify rc %d",rc));
113 } 119 }
114 } 120 }
115 121
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 3497125189df..da4f5e10b3cc 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -21,11 +21,15 @@
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */ 22 */
23#include <linux/fs.h> 23#include <linux/fs.h>
24#include <linux/backing-dev.h>
24#include <linux/stat.h> 25#include <linux/stat.h>
25#include <linux/fcntl.h> 26#include <linux/fcntl.h>
27#include <linux/mpage.h>
26#include <linux/pagemap.h> 28#include <linux/pagemap.h>
27#include <linux/pagevec.h> 29#include <linux/pagevec.h>
28#include <linux/smp_lock.h> 30#include <linux/smp_lock.h>
31#include <linux/writeback.h>
32#include <linux/delay.h>
29#include <asm/div64.h> 33#include <asm/div64.h>
30#include "cifsfs.h" 34#include "cifsfs.h"
31#include "cifspdu.h" 35#include "cifspdu.h"
@@ -47,6 +51,11 @@ static inline struct cifsFileInfo *cifs_init_private(
47 private_data->pInode = inode; 51 private_data->pInode = inode;
48 private_data->invalidHandle = FALSE; 52 private_data->invalidHandle = FALSE;
49 private_data->closePend = FALSE; 53 private_data->closePend = FALSE;
54 /* we have to track num writers to the inode, since writepages
55 does not tell us which handle the write is for so there can
56 be a close (overlapping with write) of the filehandle that
57 cifs_writepages chose to use */
58 atomic_set(&private_data->wrtPending,0);
50 59
51 return private_data; 60 return private_data;
52} 61}
@@ -256,6 +265,13 @@ int cifs_open(struct inode *inode, struct file *file)
256 CREATE_NOT_DIR, &netfid, &oplock, buf, 265 CREATE_NOT_DIR, &netfid, &oplock, buf,
257 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags 266 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
258 & CIFS_MOUNT_MAP_SPECIAL_CHR); 267 & CIFS_MOUNT_MAP_SPECIAL_CHR);
268 if (rc == -EIO) {
269 /* Old server, try legacy style OpenX */
270 rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
271 desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
272 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
273 & CIFS_MOUNT_MAP_SPECIAL_CHR);
274 }
259 if (rc) { 275 if (rc) {
260 cFYI(1, ("cifs_open returned 0x%x ", rc)); 276 cFYI(1, ("cifs_open returned 0x%x ", rc));
261 goto out; 277 goto out;
@@ -463,6 +479,20 @@ int cifs_close(struct inode *inode, struct file *file)
463 /* no sense reconnecting to close a file that is 479 /* no sense reconnecting to close a file that is
464 already closed */ 480 already closed */
465 if (pTcon->tidStatus != CifsNeedReconnect) { 481 if (pTcon->tidStatus != CifsNeedReconnect) {
482 int timeout = 2;
483 while((atomic_read(&pSMBFile->wrtPending) != 0)
484 && (timeout < 1000) ) {
485 /* Give write a better chance to get to
486 server ahead of the close. We do not
487 want to add a wait_q here as it would
488 increase the memory utilization as
489 the struct would be in each open file,
490 but this should give enough time to
491 clear the socket */
492 cERROR(1,("close with pending writes"));
493 msleep(timeout);
494 timeout *= 4;
495 }
466 write_unlock(&file->f_owner.lock); 496 write_unlock(&file->f_owner.lock);
467 rc = CIFSSMBClose(xid, pTcon, 497 rc = CIFSSMBClose(xid, pTcon,
468 pSMBFile->netfid); 498 pSMBFile->netfid);
@@ -744,14 +774,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
744 15 seconds is plenty */ 774 15 seconds is plenty */
745 } 775 }
746 776
747#ifdef CONFIG_CIFS_STATS 777 cifs_stats_bytes_written(pTcon, total_written);
748 if (total_written > 0) {
749 atomic_inc(&pTcon->num_writes);
750 spin_lock(&pTcon->stat_lock);
751 pTcon->bytes_written += total_written;
752 spin_unlock(&pTcon->stat_lock);
753 }
754#endif
755 778
756 /* since the write may have blocked check these pointers again */ 779 /* since the write may have blocked check these pointers again */
757 if (file->f_dentry) { 780 if (file->f_dentry) {
@@ -791,9 +814,8 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
791 814
792 pTcon = cifs_sb->tcon; 815 pTcon = cifs_sb->tcon;
793 816
794 /* cFYI(1, 817 cFYI(1,("write %zd bytes to offset %lld of %s", write_size,
795 (" write %d bytes to offset %lld of %s", write_size, 818 *poffset, file->f_dentry->d_name.name));
796 *poffset, file->f_dentry->d_name.name)); */
797 819
798 if (file->private_data == NULL) 820 if (file->private_data == NULL)
799 return -EBADF; 821 return -EBADF;
@@ -846,7 +868,26 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
846 if (rc != 0) 868 if (rc != 0)
847 break; 869 break;
848 } 870 }
849 871#ifdef CONFIG_CIFS_EXPERIMENTAL
872 /* BB FIXME We can not sign across two buffers yet */
873 if((experimEnabled) && ((pTcon->ses->server->secMode &
874 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0)) {
875 struct kvec iov[2];
876 unsigned int len;
877
878 len = min((size_t)cifs_sb->wsize,
879 write_size - total_written);
880 /* iov[0] is reserved for smb header */
881 iov[1].iov_base = (char *)write_data +
882 total_written;
883 iov[1].iov_len = len;
884 rc = CIFSSMBWrite2(xid, pTcon,
885 open_file->netfid, len,
886 *poffset, &bytes_written,
887 iov, 1, long_op);
888 } else
889 /* BB FIXME fixup indentation of line below */
890#endif
850 rc = CIFSSMBWrite(xid, pTcon, 891 rc = CIFSSMBWrite(xid, pTcon,
851 open_file->netfid, 892 open_file->netfid,
852 min_t(const int, cifs_sb->wsize, 893 min_t(const int, cifs_sb->wsize,
@@ -867,14 +908,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
867 15 seconds is plenty */ 908 15 seconds is plenty */
868 } 909 }
869 910
870#ifdef CONFIG_CIFS_STATS 911 cifs_stats_bytes_written(pTcon, total_written);
871 if (total_written > 0) {
872 atomic_inc(&pTcon->num_writes);
873 spin_lock(&pTcon->stat_lock);
874 pTcon->bytes_written += total_written;
875 spin_unlock(&pTcon->stat_lock);
876 }
877#endif
878 912
879 /* since the write may have blocked check these pointers again */ 913 /* since the write may have blocked check these pointers again */
880 if (file->f_dentry) { 914 if (file->f_dentry) {
@@ -893,6 +927,43 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
893 return total_written; 927 return total_written;
894} 928}
895 929
930struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
931{
932 struct cifsFileInfo *open_file;
933 int rc;
934
935 read_lock(&GlobalSMBSeslock);
936 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
937 if (open_file->closePend)
938 continue;
939 if (open_file->pfile &&
940 ((open_file->pfile->f_flags & O_RDWR) ||
941 (open_file->pfile->f_flags & O_WRONLY))) {
942 atomic_inc(&open_file->wrtPending);
943 read_unlock(&GlobalSMBSeslock);
944 if((open_file->invalidHandle) &&
945 (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) {
946 rc = cifs_reopen_file(&cifs_inode->vfs_inode,
947 open_file->pfile, FALSE);
948 /* if it fails, try another handle - might be */
949 /* dangerous to hold up writepages with retry */
950 if(rc) {
951 cFYI(1,("failed on reopen file in wp"));
952 read_lock(&GlobalSMBSeslock);
953 /* can not use this handle, no write
954 pending on this one after all */
955 atomic_dec
956 (&open_file->wrtPending);
957 continue;
958 }
959 }
960 return open_file;
961 }
962 }
963 read_unlock(&GlobalSMBSeslock);
964 return NULL;
965}
966
896static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) 967static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
897{ 968{
898 struct address_space *mapping = page->mapping; 969 struct address_space *mapping = page->mapping;
@@ -903,10 +974,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
903 struct cifs_sb_info *cifs_sb; 974 struct cifs_sb_info *cifs_sb;
904 struct cifsTconInfo *pTcon; 975 struct cifsTconInfo *pTcon;
905 struct inode *inode; 976 struct inode *inode;
906 struct cifsInodeInfo *cifsInode; 977 struct cifsFileInfo *open_file;
907 struct cifsFileInfo *open_file = NULL;
908 struct list_head *tmp;
909 struct list_head *tmp1;
910 978
911 if (!mapping || !mapping->host) 979 if (!mapping || !mapping->host)
912 return -EFAULT; 980 return -EFAULT;
@@ -934,49 +1002,20 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
934 if (mapping->host->i_size - offset < (loff_t)to) 1002 if (mapping->host->i_size - offset < (loff_t)to)
935 to = (unsigned)(mapping->host->i_size - offset); 1003 to = (unsigned)(mapping->host->i_size - offset);
936 1004
937 cifsInode = CIFS_I(mapping->host); 1005 open_file = find_writable_file(CIFS_I(mapping->host));
938 read_lock(&GlobalSMBSeslock); 1006 if (open_file) {
939 /* BB we should start at the end */ 1007 bytes_written = cifs_write(open_file->pfile, write_data,
940 list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) { 1008 to-from, &offset);
941 open_file = list_entry(tmp, struct cifsFileInfo, flist); 1009 atomic_dec(&open_file->wrtPending);
942 if (open_file->closePend)
943 continue;
944 /* We check if file is open for writing first */
945 if ((open_file->pfile) &&
946 ((open_file->pfile->f_flags & O_RDWR) ||
947 (open_file->pfile->f_flags & O_WRONLY))) {
948 read_unlock(&GlobalSMBSeslock);
949 bytes_written = cifs_write(open_file->pfile,
950 write_data, to-from,
951 &offset);
952 read_lock(&GlobalSMBSeslock);
953 /* Does mm or vfs already set times? */ 1010 /* Does mm or vfs already set times? */
954 inode->i_atime = 1011 inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
955 inode->i_mtime = current_fs_time(inode->i_sb); 1012 if ((bytes_written > 0) && (offset)) {
956 if ((bytes_written > 0) && (offset)) { 1013 rc = 0;
957 rc = 0; 1014 } else if (bytes_written < 0) {
958 } else if (bytes_written < 0) { 1015 if (rc != -EBADF)
959 if (rc == -EBADF) { 1016 rc = bytes_written;
960 /* have seen a case in which kernel seemed to
961 have closed/freed a file even with writes
962 active so we might as well see if there are
963 other file structs to try for the same
964 inode before giving up */
965 continue;
966 } else
967 rc = bytes_written;
968 }
969 break; /* now that we found a valid file handle and
970 tried to write to it we are done, no sense
971 continuing to loop looking for another */
972 }
973 if (tmp->next == NULL) {
974 cFYI(1, ("File instance %p removed", tmp));
975 break;
976 } 1017 }
977 } 1018 } else {
978 read_unlock(&GlobalSMBSeslock);
979 if (open_file == NULL) {
980 cFYI(1, ("No writeable filehandles for inode")); 1019 cFYI(1, ("No writeable filehandles for inode"));
981 rc = -EIO; 1020 rc = -EIO;
982 } 1021 }
@@ -985,20 +1024,207 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
985 return rc; 1024 return rc;
986} 1025}
987 1026
988#if 0 1027#ifdef CONFIG_CIFS_EXPERIMENTAL
989static int cifs_writepages(struct address_space *mapping, 1028static int cifs_writepages(struct address_space *mapping,
990 struct writeback_control *wbc) 1029 struct writeback_control *wbc)
991{ 1030{
992 int rc = -EFAULT; 1031 struct backing_dev_info *bdi = mapping->backing_dev_info;
1032 unsigned int bytes_to_write;
1033 unsigned int bytes_written;
1034 struct cifs_sb_info *cifs_sb;
1035 int done = 0;
1036 pgoff_t end = -1;
1037 pgoff_t index;
1038 int is_range = 0;
1039 struct kvec iov[32];
1040 int len;
1041 int n_iov = 0;
1042 pgoff_t next;
1043 int nr_pages;
1044 __u64 offset = 0;
1045 struct cifsFileInfo *open_file;
1046 struct page *page;
1047 struct pagevec pvec;
1048 int rc = 0;
1049 int scanned = 0;
993 int xid; 1050 int xid;
994 1051
1052 cifs_sb = CIFS_SB(mapping->host->i_sb);
1053
1054 /*
1055 * If wsize is smaller that the page cache size, default to writing
1056 * one page at a time via cifs_writepage
1057 */
1058 if (cifs_sb->wsize < PAGE_CACHE_SIZE)
1059 return generic_writepages(mapping, wbc);
1060
1061 /* BB FIXME we do not have code to sign across multiple buffers yet,
1062 so go to older writepage style write which we can sign if needed */
1063 if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server))
1064 if(cifs_sb->tcon->ses->server->secMode &
1065 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1066 return generic_writepages(mapping, wbc);
1067
1068 /*
1069 * BB: Is this meaningful for a non-block-device file system?
1070 * If it is, we should test it again after we do I/O
1071 */
1072 if (wbc->nonblocking && bdi_write_congested(bdi)) {
1073 wbc->encountered_congestion = 1;
1074 return 0;
1075 }
1076
995 xid = GetXid(); 1077 xid = GetXid();
996 1078
997 /* Find contiguous pages then iterate through repeating 1079 pagevec_init(&pvec, 0);
998 call 16K write then Setpageuptodate or if LARGE_WRITE_X 1080 if (wbc->sync_mode == WB_SYNC_NONE)
999 support then send larger writes via kevec so as to eliminate 1081 index = mapping->writeback_index; /* Start from prev offset */
1000 a memcpy */ 1082 else {
1083 index = 0;
1084 scanned = 1;
1085 }
1086 if (wbc->start || wbc->end) {
1087 index = wbc->start >> PAGE_CACHE_SHIFT;
1088 end = wbc->end >> PAGE_CACHE_SHIFT;
1089 is_range = 1;
1090 scanned = 1;
1091 }
1092retry:
1093 while (!done && (index <= end) &&
1094 (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
1095 PAGECACHE_TAG_DIRTY,
1096 min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1))) {
1097 int first;
1098 unsigned int i;
1099
1100 first = -1;
1101 next = 0;
1102 n_iov = 0;
1103 bytes_to_write = 0;
1104
1105 for (i = 0; i < nr_pages; i++) {
1106 page = pvec.pages[i];
1107 /*
1108 * At this point we hold neither mapping->tree_lock nor
1109 * lock on the page itself: the page may be truncated or
1110 * invalidated (changing page->mapping to NULL), or even
1111 * swizzled back from swapper_space to tmpfs file
1112 * mapping
1113 */
1114
1115 if (first < 0)
1116 lock_page(page);
1117 else if (TestSetPageLocked(page))
1118 break;
1119
1120 if (unlikely(page->mapping != mapping)) {
1121 unlock_page(page);
1122 break;
1123 }
1124
1125 if (unlikely(is_range) && (page->index > end)) {
1126 done = 1;
1127 unlock_page(page);
1128 break;
1129 }
1130
1131 if (next && (page->index != next)) {
1132 /* Not next consecutive page */
1133 unlock_page(page);
1134 break;
1135 }
1136
1137 if (wbc->sync_mode != WB_SYNC_NONE)
1138 wait_on_page_writeback(page);
1139
1140 if (PageWriteback(page) ||
1141 !test_clear_page_dirty(page)) {
1142 unlock_page(page);
1143 break;
1144 }
1145
1146 if (page_offset(page) >= mapping->host->i_size) {
1147 done = 1;
1148 unlock_page(page);
1149 break;
1150 }
1151
1152 /*
1153 * BB can we get rid of this? pages are held by pvec
1154 */
1155 page_cache_get(page);
1156
1157 len = min(mapping->host->i_size - page_offset(page),
1158 (loff_t)PAGE_CACHE_SIZE);
1159
1160 /* reserve iov[0] for the smb header */
1161 n_iov++;
1162 iov[n_iov].iov_base = kmap(page);
1163 iov[n_iov].iov_len = len;
1164 bytes_to_write += len;
1165
1166 if (first < 0) {
1167 first = i;
1168 offset = page_offset(page);
1169 }
1170 next = page->index + 1;
1171 if (bytes_to_write + PAGE_CACHE_SIZE > cifs_sb->wsize)
1172 break;
1173 }
1174 if (n_iov) {
1175 /* Search for a writable handle every time we call
1176 * CIFSSMBWrite2. We can't rely on the last handle
1177 * we used to still be valid
1178 */
1179 open_file = find_writable_file(CIFS_I(mapping->host));
1180 if (!open_file) {
1181 cERROR(1, ("No writable handles for inode"));
1182 rc = -EBADF;
1183 } else {
1184 rc = CIFSSMBWrite2(xid, cifs_sb->tcon,
1185 open_file->netfid,
1186 bytes_to_write, offset,
1187 &bytes_written, iov, n_iov,
1188 1);
1189 atomic_dec(&open_file->wrtPending);
1190 if (rc || bytes_written < bytes_to_write) {
1191 cERROR(1,("Write2 ret %d, written = %d",
1192 rc, bytes_written));
1193 /* BB what if continued retry is
1194 requested via mount flags? */
1195 set_bit(AS_EIO, &mapping->flags);
1196 SetPageError(page);
1197 } else {
1198 cifs_stats_bytes_written(cifs_sb->tcon,
1199 bytes_written);
1200 }
1201 }
1202 for (i = 0; i < n_iov; i++) {
1203 page = pvec.pages[first + i];
1204 kunmap(page);
1205 unlock_page(page);
1206 page_cache_release(page);
1207 }
1208 if ((wbc->nr_to_write -= n_iov) <= 0)
1209 done = 1;
1210 index = next;
1211 }
1212 pagevec_release(&pvec);
1213 }
1214 if (!scanned && !done) {
1215 /*
1216 * We hit the last page and there is more work to be done: wrap
1217 * back to the start of the file
1218 */
1219 scanned = 1;
1220 index = 0;
1221 goto retry;
1222 }
1223 if (!is_range)
1224 mapping->writeback_index = index;
1225
1001 FreeXid(xid); 1226 FreeXid(xid);
1227
1002 return rc; 1228 return rc;
1003} 1229}
1004#endif 1230#endif
@@ -1207,12 +1433,10 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1207 if (rc != 0) 1433 if (rc != 0)
1208 break; 1434 break;
1209 } 1435 }
1210
1211 rc = CIFSSMBRead(xid, pTcon, 1436 rc = CIFSSMBRead(xid, pTcon,
1212 open_file->netfid, 1437 open_file->netfid,
1213 current_read_size, *poffset, 1438 current_read_size, *poffset,
1214 &bytes_read, &smb_read_data); 1439 &bytes_read, &smb_read_data);
1215
1216 pSMBr = (struct smb_com_read_rsp *)smb_read_data; 1440 pSMBr = (struct smb_com_read_rsp *)smb_read_data;
1217 if (copy_to_user(current_offset, 1441 if (copy_to_user(current_offset,
1218 smb_read_data + 4 /* RFC1001 hdr */ 1442 smb_read_data + 4 /* RFC1001 hdr */
@@ -1235,12 +1459,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
1235 return rc; 1459 return rc;
1236 } 1460 }
1237 } else { 1461 } else {
1238#ifdef CONFIG_CIFS_STATS 1462 cifs_stats_bytes_read(pTcon, bytes_read);
1239 atomic_inc(&pTcon->num_reads);
1240 spin_lock(&pTcon->stat_lock);
1241 pTcon->bytes_read += total_read;
1242 spin_unlock(&pTcon->stat_lock);
1243#endif
1244 *poffset += bytes_read; 1463 *poffset += bytes_read;
1245 } 1464 }
1246 } 1465 }
@@ -1280,6 +1499,13 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1280 total_read += bytes_read, current_offset += bytes_read) { 1499 total_read += bytes_read, current_offset += bytes_read) {
1281 current_read_size = min_t(const int, read_size - total_read, 1500 current_read_size = min_t(const int, read_size - total_read,
1282 cifs_sb->rsize); 1501 cifs_sb->rsize);
1502 /* For windows me and 9x we do not want to request more
1503 than it negotiated since it will refuse the read then */
1504 if((pTcon->ses) &&
1505 !(pTcon->ses->capabilities & CAP_LARGE_FILES)) {
1506 current_read_size = min_t(const int, current_read_size,
1507 pTcon->ses->server->maxBuf - 128);
1508 }
1283 rc = -EAGAIN; 1509 rc = -EAGAIN;
1284 while (rc == -EAGAIN) { 1510 while (rc == -EAGAIN) {
1285 if ((open_file->invalidHandle) && 1511 if ((open_file->invalidHandle) &&
@@ -1289,11 +1515,10 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1289 if (rc != 0) 1515 if (rc != 0)
1290 break; 1516 break;
1291 } 1517 }
1292
1293 rc = CIFSSMBRead(xid, pTcon, 1518 rc = CIFSSMBRead(xid, pTcon,
1294 open_file->netfid, 1519 open_file->netfid,
1295 current_read_size, *poffset, 1520 current_read_size, *poffset,
1296 &bytes_read, &current_offset); 1521 &bytes_read, &current_offset);
1297 } 1522 }
1298 if (rc || (bytes_read == 0)) { 1523 if (rc || (bytes_read == 0)) {
1299 if (total_read) { 1524 if (total_read) {
@@ -1303,12 +1528,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1303 return rc; 1528 return rc;
1304 } 1529 }
1305 } else { 1530 } else {
1306#ifdef CONFIG_CIFS_STATS 1531 cifs_stats_bytes_read(pTcon, total_read);
1307 atomic_inc(&pTcon->num_reads);
1308 spin_lock(&pTcon->stat_lock);
1309 pTcon->bytes_read += total_read;
1310 spin_unlock(&pTcon->stat_lock);
1311#endif
1312 *poffset += bytes_read; 1532 *poffset += bytes_read;
1313 } 1533 }
1314 } 1534 }
@@ -1452,10 +1672,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1452 } 1672 }
1453 1673
1454 rc = CIFSSMBRead(xid, pTcon, 1674 rc = CIFSSMBRead(xid, pTcon,
1455 open_file->netfid, 1675 open_file->netfid,
1456 read_size, offset, 1676 read_size, offset,
1457 &bytes_read, &smb_read_data); 1677 &bytes_read, &smb_read_data);
1458 /* BB need to check return code here */ 1678
1679 /* BB more RC checks ? */
1459 if (rc== -EAGAIN) { 1680 if (rc== -EAGAIN) {
1460 if (smb_read_data) { 1681 if (smb_read_data) {
1461 cifs_buf_release(smb_read_data); 1682 cifs_buf_release(smb_read_data);
@@ -1480,12 +1701,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1480 le16_to_cpu(pSMBr->DataOffset), &lru_pvec); 1701 le16_to_cpu(pSMBr->DataOffset), &lru_pvec);
1481 1702
1482 i += bytes_read >> PAGE_CACHE_SHIFT; 1703 i += bytes_read >> PAGE_CACHE_SHIFT;
1483#ifdef CONFIG_CIFS_STATS 1704 cifs_stats_bytes_read(pTcon, bytes_read);
1484 atomic_inc(&pTcon->num_reads);
1485 spin_lock(&pTcon->stat_lock);
1486 pTcon->bytes_read += bytes_read;
1487 spin_unlock(&pTcon->stat_lock);
1488#endif
1489 if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) { 1705 if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) {
1490 i++; /* account for partial page */ 1706 i++; /* account for partial page */
1491 1707
@@ -1603,40 +1819,21 @@ static int cifs_readpage(struct file *file, struct page *page)
1603 page caching in the current Linux kernel design */ 1819 page caching in the current Linux kernel design */
1604int is_size_safe_to_change(struct cifsInodeInfo *cifsInode) 1820int is_size_safe_to_change(struct cifsInodeInfo *cifsInode)
1605{ 1821{
1606 struct list_head *tmp;
1607 struct list_head *tmp1;
1608 struct cifsFileInfo *open_file = NULL; 1822 struct cifsFileInfo *open_file = NULL;
1609 int rc = TRUE;
1610 1823
1611 if (cifsInode == NULL) 1824 if (cifsInode)
1612 return rc; 1825 open_file = find_writable_file(cifsInode);
1613 1826
1614 read_lock(&GlobalSMBSeslock); 1827 if(open_file) {
1615 list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) { 1828 /* there is not actually a write pending so let
1616 open_file = list_entry(tmp, struct cifsFileInfo, flist); 1829 this handle go free and allow it to
1617 if (open_file == NULL) 1830 be closable if needed */
1618 break; 1831 atomic_dec(&open_file->wrtPending);
1619 if (open_file->closePend) 1832 return 0;
1620 continue; 1833 } else
1621 /* We check if file is open for writing, 1834 return 1;
1622 BB we could supplement this with a check to see if file size
1623 changes have been flushed to server - ie inode metadata dirty */
1624 if ((open_file->pfile) &&
1625 ((open_file->pfile->f_flags & O_RDWR) ||
1626 (open_file->pfile->f_flags & O_WRONLY))) {
1627 rc = FALSE;
1628 break;
1629 }
1630 if (tmp->next == NULL) {
1631 cFYI(1, ("File instance %p removed", tmp));
1632 break;
1633 }
1634 }
1635 read_unlock(&GlobalSMBSeslock);
1636 return rc;
1637} 1835}
1638 1836
1639
1640static int cifs_prepare_write(struct file *file, struct page *page, 1837static int cifs_prepare_write(struct file *file, struct page *page,
1641 unsigned from, unsigned to) 1838 unsigned from, unsigned to)
1642{ 1839{
@@ -1676,6 +1873,9 @@ struct address_space_operations cifs_addr_ops = {
1676 .readpage = cifs_readpage, 1873 .readpage = cifs_readpage,
1677 .readpages = cifs_readpages, 1874 .readpages = cifs_readpages,
1678 .writepage = cifs_writepage, 1875 .writepage = cifs_writepage,
1876#ifdef CONFIG_CIFS_EXPERIMENTAL
1877 .writepages = cifs_writepages,
1878#endif
1679 .prepare_write = cifs_prepare_write, 1879 .prepare_write = cifs_prepare_write,
1680 .commit_write = cifs_commit_write, 1880 .commit_write = cifs_commit_write,
1681 .set_page_dirty = __set_page_dirty_nobuffers, 1881 .set_page_dirty = __set_page_dirty_nobuffers,
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 8d336a900255..912d401600f6 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -166,7 +166,13 @@ int cifs_get_inode_info_unix(struct inode **pinode,
166 inode->i_fop = &cifs_file_direct_ops; 166 inode->i_fop = &cifs_file_direct_ops;
167 else 167 else
168 inode->i_fop = &cifs_file_ops; 168 inode->i_fop = &cifs_file_ops;
169 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
170 inode->i_fop->lock = NULL;
169 inode->i_data.a_ops = &cifs_addr_ops; 171 inode->i_data.a_ops = &cifs_addr_ops;
172 /* check if server can support readpages */
173 if(pTcon->ses->server->maxBuf <
174 4096 + MAX_CIFS_HDR_SIZE)
175 inode->i_data.a_ops->readpages = NULL;
170 } else if (S_ISDIR(inode->i_mode)) { 176 } else if (S_ISDIR(inode->i_mode)) {
171 cFYI(1, (" Directory inode")); 177 cFYI(1, (" Directory inode"));
172 inode->i_op = &cifs_dir_inode_ops; 178 inode->i_op = &cifs_dir_inode_ops;
@@ -213,8 +219,18 @@ int cifs_get_inode_info(struct inode **pinode,
213 pfindData = (FILE_ALL_INFO *)buf; 219 pfindData = (FILE_ALL_INFO *)buf;
214 /* could do find first instead but this returns more info */ 220 /* could do find first instead but this returns more info */
215 rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData, 221 rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
216 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 222 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
217 CIFS_MOUNT_MAP_SPECIAL_CHR); 223 CIFS_MOUNT_MAP_SPECIAL_CHR);
224 /* BB optimize code so we do not make the above call
225 when server claims no NT SMB support and the above call
226 failed at least once - set flag in tcon or mount */
227 if((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
228 rc = SMBQueryInformation(xid, pTcon, search_path,
229 pfindData, cifs_sb->local_nls,
230 cifs_sb->mnt_cifs_flags &
231 CIFS_MOUNT_MAP_SPECIAL_CHR);
232 }
233
218 } 234 }
219 /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ 235 /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
220 if (rc) { 236 if (rc) {
@@ -320,6 +336,16 @@ int cifs_get_inode_info(struct inode **pinode,
320 on dirs */ 336 on dirs */
321 inode->i_mode = cifs_sb->mnt_dir_mode; 337 inode->i_mode = cifs_sb->mnt_dir_mode;
322 inode->i_mode |= S_IFDIR; 338 inode->i_mode |= S_IFDIR;
339 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
340 (cifsInfo->cifsAttrs & ATTR_SYSTEM) &&
341 /* No need to le64 convert size of zero */
342 (pfindData->EndOfFile == 0)) {
343 inode->i_mode = cifs_sb->mnt_file_mode;
344 inode->i_mode |= S_IFIFO;
345/* BB Finish for SFU style symlinks and devies */
346/* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
347 (cifsInfo->cifsAttrs & ATTR_SYSTEM) && ) */
348
323 } else { 349 } else {
324 inode->i_mode |= S_IFREG; 350 inode->i_mode |= S_IFREG;
325 /* treat the dos attribute of read-only as read-only 351 /* treat the dos attribute of read-only as read-only
@@ -359,7 +385,12 @@ int cifs_get_inode_info(struct inode **pinode,
359 inode->i_fop = &cifs_file_direct_ops; 385 inode->i_fop = &cifs_file_direct_ops;
360 else 386 else
361 inode->i_fop = &cifs_file_ops; 387 inode->i_fop = &cifs_file_ops;
388 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
389 inode->i_fop->lock = NULL;
362 inode->i_data.a_ops = &cifs_addr_ops; 390 inode->i_data.a_ops = &cifs_addr_ops;
391 if(pTcon->ses->server->maxBuf <
392 4096 + MAX_CIFS_HDR_SIZE)
393 inode->i_data.a_ops->readpages = NULL;
363 } else if (S_ISDIR(inode->i_mode)) { 394 } else if (S_ISDIR(inode->i_mode)) {
364 cFYI(1, (" Directory inode ")); 395 cFYI(1, (" Directory inode "));
365 inode->i_op = &cifs_dir_inode_ops; 396 inode->i_op = &cifs_dir_inode_ops;
@@ -577,7 +608,10 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
577 rc = cifs_get_inode_info(&newinode, full_path, NULL, 608 rc = cifs_get_inode_info(&newinode, full_path, NULL,
578 inode->i_sb,xid); 609 inode->i_sb,xid);
579 610
580 direntry->d_op = &cifs_dentry_ops; 611 if (pTcon->nocase)
612 direntry->d_op = &cifs_ci_dentry_ops;
613 else
614 direntry->d_op = &cifs_dentry_ops;
581 d_instantiate(direntry, newinode); 615 d_instantiate(direntry, newinode);
582 if (direntry->d_inode) 616 if (direntry->d_inode)
583 direntry->d_inode->i_nlink = 2; 617 direntry->d_inode->i_nlink = 2;
@@ -928,7 +962,6 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
928 struct cifsTconInfo *pTcon; 962 struct cifsTconInfo *pTcon;
929 char *full_path = NULL; 963 char *full_path = NULL;
930 int rc = -EACCES; 964 int rc = -EACCES;
931 int found = FALSE;
932 struct cifsFileInfo *open_file = NULL; 965 struct cifsFileInfo *open_file = NULL;
933 FILE_BASIC_INFO time_buf; 966 FILE_BASIC_INFO time_buf;
934 int set_time = FALSE; 967 int set_time = FALSE;
@@ -936,7 +969,6 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
936 __u64 uid = 0xFFFFFFFFFFFFFFFFULL; 969 __u64 uid = 0xFFFFFFFFFFFFFFFFULL;
937 __u64 gid = 0xFFFFFFFFFFFFFFFFULL; 970 __u64 gid = 0xFFFFFFFFFFFFFFFFULL;
938 struct cifsInodeInfo *cifsInode; 971 struct cifsInodeInfo *cifsInode;
939 struct list_head *tmp;
940 972
941 xid = GetXid(); 973 xid = GetXid();
942 974
@@ -961,7 +993,6 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
961 filemap_fdatawait(direntry->d_inode->i_mapping); 993 filemap_fdatawait(direntry->d_inode->i_mapping);
962 994
963 if (attrs->ia_valid & ATTR_SIZE) { 995 if (attrs->ia_valid & ATTR_SIZE) {
964 read_lock(&GlobalSMBSeslock);
965 /* To avoid spurious oplock breaks from server, in the case of 996 /* To avoid spurious oplock breaks from server, in the case of
966 inodes that we already have open, avoid doing path based 997 inodes that we already have open, avoid doing path based
967 setting of file size if we can do it by handle. 998 setting of file size if we can do it by handle.
@@ -969,40 +1000,23 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
969 when the local oplock break takes longer to flush 1000 when the local oplock break takes longer to flush
970 writebehind data than the SMB timeout for the SetPathInfo 1001 writebehind data than the SMB timeout for the SetPathInfo
971 request would allow */ 1002 request would allow */
972 list_for_each(tmp, &cifsInode->openFileList) { 1003 open_file = find_writable_file(cifsInode);
973 open_file = list_entry(tmp, struct cifsFileInfo, 1004 if (open_file) {
974 flist); 1005 __u16 nfid = open_file->netfid;
975 /* We check if file is open for writing first */ 1006 __u32 npid = open_file->pid;
976 if ((open_file->pfile) && 1007 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
977 ((open_file->pfile->f_flags & O_RDWR) || 1008 nfid, npid, FALSE);
978 (open_file->pfile->f_flags & O_WRONLY))) { 1009 atomic_dec(&open_file->wrtPending);
979 if (open_file->invalidHandle == FALSE) { 1010 cFYI(1,("SetFSize for attrs rc = %d", rc));
980 /* we found a valid, writeable network 1011 if(rc == -EINVAL) {
981 file handle to use to try to set the 1012 int bytes_written;
982 file size */ 1013 rc = CIFSSMBWrite(xid, pTcon,
983 __u16 nfid = open_file->netfid; 1014 nfid, 0, attrs->ia_size,
984 __u32 npid = open_file->pid; 1015 &bytes_written, NULL, NULL,
985 read_unlock(&GlobalSMBSeslock); 1016 1 /* 45 seconds */);
986 found = TRUE; 1017 cFYI(1,("Wrt seteof rc %d", rc));
987 rc = CIFSSMBSetFileSize(xid, pTcon,
988 attrs->ia_size, nfid, npid,
989 FALSE);
990 cFYI(1, ("SetFileSize by handle "
991 "(setattrs) rc = %d", rc));
992 /* Do not need reopen and retry on
993 EAGAIN since we will retry by
994 pathname below */
995
996 /* now that we found one valid file
997 handle no sense continuing to loop
998 trying others, so break here */
999 break;
1000 }
1001 } 1018 }
1002 } 1019 }
1003 if (found == FALSE)
1004 read_unlock(&GlobalSMBSeslock);
1005
1006 if (rc != 0) { 1020 if (rc != 0) {
1007 /* Set file size by pathname rather than by handle 1021 /* Set file size by pathname rather than by handle
1008 either because no valid, writeable file handle for 1022 either because no valid, writeable file handle for
@@ -1013,7 +1027,30 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1013 cifs_sb->local_nls, 1027 cifs_sb->local_nls,
1014 cifs_sb->mnt_cifs_flags & 1028 cifs_sb->mnt_cifs_flags &
1015 CIFS_MOUNT_MAP_SPECIAL_CHR); 1029 CIFS_MOUNT_MAP_SPECIAL_CHR);
1016 cFYI(1, (" SetEOF by path (setattrs) rc = %d", rc)); 1030 cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
1031 if(rc == -EINVAL) {
1032 __u16 netfid;
1033 int oplock = FALSE;
1034
1035 rc = SMBLegacyOpen(xid, pTcon, full_path,
1036 FILE_OPEN,
1037 SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
1038 CREATE_NOT_DIR, &netfid, &oplock,
1039 NULL, cifs_sb->local_nls,
1040 cifs_sb->mnt_cifs_flags &
1041 CIFS_MOUNT_MAP_SPECIAL_CHR);
1042 if (rc==0) {
1043 int bytes_written;
1044 rc = CIFSSMBWrite(xid, pTcon,
1045 netfid, 0,
1046 attrs->ia_size,
1047 &bytes_written, NULL,
1048 NULL, 1 /* 45 sec */);
1049 cFYI(1,("wrt seteof rc %d",rc));
1050 CIFSSMBClose(xid, pTcon, netfid);
1051 }
1052
1053 }
1017 } 1054 }
1018 1055
1019 /* Server is ok setting allocation size implicitly - no need 1056 /* Server is ok setting allocation size implicitly - no need
@@ -1026,24 +1063,22 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1026 rc = vmtruncate(direntry->d_inode, attrs->ia_size); 1063 rc = vmtruncate(direntry->d_inode, attrs->ia_size);
1027 cifs_truncate_page(direntry->d_inode->i_mapping, 1064 cifs_truncate_page(direntry->d_inode->i_mapping,
1028 direntry->d_inode->i_size); 1065 direntry->d_inode->i_size);
1029 } 1066 } else
1067 goto cifs_setattr_exit;
1030 } 1068 }
1031 if (attrs->ia_valid & ATTR_UID) { 1069 if (attrs->ia_valid & ATTR_UID) {
1032 cFYI(1, (" CIFS - UID changed to %d", attrs->ia_uid)); 1070 cFYI(1, ("UID changed to %d", attrs->ia_uid));
1033 uid = attrs->ia_uid; 1071 uid = attrs->ia_uid;
1034 /* entry->uid = cpu_to_le16(attr->ia_uid); */
1035 } 1072 }
1036 if (attrs->ia_valid & ATTR_GID) { 1073 if (attrs->ia_valid & ATTR_GID) {
1037 cFYI(1, (" CIFS - GID changed to %d", attrs->ia_gid)); 1074 cFYI(1, ("GID changed to %d", attrs->ia_gid));
1038 gid = attrs->ia_gid; 1075 gid = attrs->ia_gid;
1039 /* entry->gid = cpu_to_le16(attr->ia_gid); */
1040 } 1076 }
1041 1077
1042 time_buf.Attributes = 0; 1078 time_buf.Attributes = 0;
1043 if (attrs->ia_valid & ATTR_MODE) { 1079 if (attrs->ia_valid & ATTR_MODE) {
1044 cFYI(1, (" CIFS - Mode changed to 0x%x", attrs->ia_mode)); 1080 cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode));
1045 mode = attrs->ia_mode; 1081 mode = attrs->ia_mode;
1046 /* entry->mode = cpu_to_le16(attr->ia_mode); */
1047 } 1082 }
1048 1083
1049 if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) 1084 if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX)
@@ -1083,18 +1118,24 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1083 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime)); 1118 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
1084 } else 1119 } else
1085 time_buf.LastWriteTime = 0; 1120 time_buf.LastWriteTime = 0;
1086 1121 /* Do not set ctime explicitly unless other time
1087 if (attrs->ia_valid & ATTR_CTIME) { 1122 stamps are changed explicitly (i.e. by utime()
1123 since we would then have a mix of client and
1124 server times */
1125
1126 if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
1088 set_time = TRUE; 1127 set_time = TRUE;
1089 cFYI(1, (" CIFS - CTIME changed ")); /* BB probably no need */ 1128 /* Although Samba throws this field away
1129 it may be useful to Windows - but we do
1130 not want to set ctime unless some other
1131 timestamp is changing */
1132 cFYI(1, ("CIFS - CTIME changed "));
1090 time_buf.ChangeTime = 1133 time_buf.ChangeTime =
1091 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime)); 1134 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
1092 } else 1135 } else
1093 time_buf.ChangeTime = 0; 1136 time_buf.ChangeTime = 0;
1094 1137
1095 if (set_time || time_buf.Attributes) { 1138 if (set_time || time_buf.Attributes) {
1096 /* BB what if setting one attribute fails (such as size) but
1097 time setting works? */
1098 time_buf.CreationTime = 0; /* do not change */ 1139 time_buf.CreationTime = 0; /* do not change */
1099 /* In the future we should experiment - try setting timestamps 1140 /* In the future we should experiment - try setting timestamps
1100 via Handle (SetFileInfo) instead of by path */ 1141 via Handle (SetFileInfo) instead of by path */
@@ -1133,12 +1174,21 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1133 &time_buf, cifs_sb->local_nls); */ 1174 &time_buf, cifs_sb->local_nls); */
1134 } 1175 }
1135 } 1176 }
1177 /* Even if error on time set, no sense failing the call if
1178 the server would set the time to a reasonable value anyway,
1179 and this check ensures that we are not being called from
1180 sys_utimes in which case we ought to fail the call back to
1181 the user when the server rejects the call */
1182 if((rc) && (attrs->ia_valid &&
1183 (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
1184 rc = 0;
1136 } 1185 }
1137 1186
1138 /* do not need local check to inode_check_ok since the server does 1187 /* do not need local check to inode_check_ok since the server does
1139 that */ 1188 that */
1140 if (!rc) 1189 if (!rc)
1141 rc = inode_setattr(direntry->d_inode, attrs); 1190 rc = inode_setattr(direntry->d_inode, attrs);
1191cifs_setattr_exit:
1142 kfree(full_path); 1192 kfree(full_path);
1143 FreeXid(xid); 1193 FreeXid(xid);
1144 return rc; 1194 return rc;
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index ab925ef4f863..b43e071fe110 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -198,7 +198,10 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
198 ("Create symlink worked but get_inode_info failed with rc = %d ", 198 ("Create symlink worked but get_inode_info failed with rc = %d ",
199 rc)); 199 rc));
200 } else { 200 } else {
201 direntry->d_op = &cifs_dentry_ops; 201 if (pTcon->nocase)
202 direntry->d_op = &cifs_ci_dentry_ops;
203 else
204 direntry->d_op = &cifs_dentry_ops;
202 d_instantiate(direntry, newinode); 205 d_instantiate(direntry, newinode);
203 } 206 }
204 } 207 }
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 20ae4153f791..eba1de917f2a 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -34,8 +34,6 @@ extern mempool_t *cifs_sm_req_poolp;
34extern mempool_t *cifs_req_poolp; 34extern mempool_t *cifs_req_poolp;
35extern struct task_struct * oplockThread; 35extern struct task_struct * oplockThread;
36 36
37static __u16 GlobalMid; /* multiplex id - rotating counter */
38
39/* The xid serves as a useful identifier for each incoming vfs request, 37/* The xid serves as a useful identifier for each incoming vfs request,
40 in a similar way to the mid which is useful to track each sent smb, 38 in a similar way to the mid which is useful to track each sent smb,
41 and CurrentXid can also provide a running counter (although it 39 and CurrentXid can also provide a running counter (although it
@@ -51,6 +49,8 @@ _GetXid(void)
51 GlobalTotalActiveXid++; 49 GlobalTotalActiveXid++;
52 if (GlobalTotalActiveXid > GlobalMaxActiveXid) 50 if (GlobalTotalActiveXid > GlobalMaxActiveXid)
53 GlobalMaxActiveXid = GlobalTotalActiveXid; /* keep high water mark for number of simultaneous vfs ops in our filesystem */ 51 GlobalMaxActiveXid = GlobalTotalActiveXid; /* keep high water mark for number of simultaneous vfs ops in our filesystem */
52 if(GlobalTotalActiveXid > 65000)
53 cFYI(1,("warning: more than 65000 requests active"));
54 xid = GlobalCurrentXid++; 54 xid = GlobalCurrentXid++;
55 spin_unlock(&GlobalMid_Lock); 55 spin_unlock(&GlobalMid_Lock);
56 return xid; 56 return xid;
@@ -218,6 +218,76 @@ cifs_small_buf_release(void *buf_to_free)
218 return; 218 return;
219} 219}
220 220
221/*
222 Find a free multiplex id (SMB mid). Otherwise there could be
223 mid collisions which might cause problems, demultiplexing the
224 wrong response to this request. Multiplex ids could collide if
225 one of a series requests takes much longer than the others, or
226 if a very large number of long lived requests (byte range
227 locks or FindNotify requests) are pending. No more than
228 64K-1 requests can be outstanding at one time. If no
229 mids are available, return zero. A future optimization
230 could make the combination of mids and uid the key we use
231 to demultiplex on (rather than mid alone).
232 In addition to the above check, the cifs demultiplex
233 code already used the command code as a secondary
234 check of the frame and if signing is negotiated the
235 response would be discarded if the mid were the same
236 but the signature was wrong. Since the mid is not put in the
237 pending queue until later (when it is about to be dispatched)
238 we do have to limit the number of outstanding requests
239 to somewhat less than 64K-1 although it is hard to imagine
240 so many threads being in the vfs at one time.
241*/
242__u16 GetNextMid(struct TCP_Server_Info *server)
243{
244 __u16 mid = 0;
245 __u16 last_mid;
246 int collision;
247
248 if(server == NULL)
249 return mid;
250
251 spin_lock(&GlobalMid_Lock);
252 last_mid = server->CurrentMid; /* we do not want to loop forever */
253 server->CurrentMid++;
254 /* This nested loop looks more expensive than it is.
255 In practice the list of pending requests is short,
256 fewer than 50, and the mids are likely to be unique
257 on the first pass through the loop unless some request
258 takes longer than the 64 thousand requests before it
259 (and it would also have to have been a request that
260 did not time out) */
261 while(server->CurrentMid != last_mid) {
262 struct list_head *tmp;
263 struct mid_q_entry *mid_entry;
264
265 collision = 0;
266 if(server->CurrentMid == 0)
267 server->CurrentMid++;
268
269 list_for_each(tmp, &server->pending_mid_q) {
270 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
271
272 if ((mid_entry->mid == server->CurrentMid) &&
273 (mid_entry->midState == MID_REQUEST_SUBMITTED)) {
274 /* This mid is in use, try a different one */
275 collision = 1;
276 break;
277 }
278 }
279 if(collision == 0) {
280 mid = server->CurrentMid;
281 break;
282 }
283 server->CurrentMid++;
284 }
285 spin_unlock(&GlobalMid_Lock);
286 return mid;
287}
288
289/* NB: MID can not be set if treeCon not passed in, in that
290 case it is responsbility of caller to set the mid */
221void 291void
222header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , 292header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
223 const struct cifsTconInfo *treeCon, int word_count 293 const struct cifsTconInfo *treeCon, int word_count
@@ -233,7 +303,8 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
233 (2 * word_count) + sizeof (struct smb_hdr) - 303 (2 * word_count) + sizeof (struct smb_hdr) -
234 4 /* RFC 1001 length field does not count */ + 304 4 /* RFC 1001 length field does not count */ +
235 2 /* for bcc field itself */ ; 305 2 /* for bcc field itself */ ;
236 /* Note that this is the only network field that has to be converted to big endian and it is done just before we send it */ 306 /* Note that this is the only network field that has to be converted
307 to big endian and it is done just before we send it */
237 308
238 buffer->Protocol[0] = 0xFF; 309 buffer->Protocol[0] = 0xFF;
239 buffer->Protocol[1] = 'S'; 310 buffer->Protocol[1] = 'S';
@@ -245,8 +316,6 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
245 buffer->Pid = cpu_to_le16((__u16)current->tgid); 316 buffer->Pid = cpu_to_le16((__u16)current->tgid);
246 buffer->PidHigh = cpu_to_le16((__u16)(current->tgid >> 16)); 317 buffer->PidHigh = cpu_to_le16((__u16)(current->tgid >> 16));
247 spin_lock(&GlobalMid_Lock); 318 spin_lock(&GlobalMid_Lock);
248 GlobalMid++;
249 buffer->Mid = GlobalMid;
250 spin_unlock(&GlobalMid_Lock); 319 spin_unlock(&GlobalMid_Lock);
251 if (treeCon) { 320 if (treeCon) {
252 buffer->Tid = treeCon->tid; 321 buffer->Tid = treeCon->tid;
@@ -256,8 +325,9 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
256 if (treeCon->ses->capabilities & CAP_STATUS32) { 325 if (treeCon->ses->capabilities & CAP_STATUS32) {
257 buffer->Flags2 |= SMBFLG2_ERR_STATUS; 326 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
258 } 327 }
259 328 /* Uid is not converted */
260 buffer->Uid = treeCon->ses->Suid; /* always in LE format */ 329 buffer->Uid = treeCon->ses->Suid;
330 buffer->Mid = GetNextMid(treeCon->ses->server);
261 if(multiuser_mount != 0) { 331 if(multiuser_mount != 0) {
262 /* For the multiuser case, there are few obvious technically */ 332 /* For the multiuser case, there are few obvious technically */
263 /* possible mechanisms to match the local linux user (uid) */ 333 /* possible mechanisms to match the local linux user (uid) */
@@ -305,6 +375,8 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
305 } 375 }
306 if (treeCon->Flags & SMB_SHARE_IS_IN_DFS) 376 if (treeCon->Flags & SMB_SHARE_IS_IN_DFS)
307 buffer->Flags2 |= SMBFLG2_DFS; 377 buffer->Flags2 |= SMBFLG2_DFS;
378 if (treeCon->nocase)
379 buffer->Flags |= SMBFLG_CASELESS;
308 if((treeCon->ses) && (treeCon->ses->server)) 380 if((treeCon->ses) && (treeCon->ses->server))
309 if(treeCon->ses->server->secMode & 381 if(treeCon->ses->server->secMode &
310 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 382 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
@@ -347,7 +419,8 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid)
347int 419int
348checkSMB(struct smb_hdr *smb, __u16 mid, int length) 420checkSMB(struct smb_hdr *smb, __u16 mid, int length)
349{ 421{
350 __u32 len = be32_to_cpu(smb->smb_buf_length); 422 __u32 len = smb->smb_buf_length;
423 __u32 clc_len; /* calculated length */
351 cFYI(0, 424 cFYI(0,
352 ("Entering checkSMB with Length: %x, smb_buf_length: %x ", 425 ("Entering checkSMB with Length: %x, smb_buf_length: %x ",
353 length, len)); 426 length, len));
@@ -368,23 +441,29 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
368 cERROR(1, 441 cERROR(1,
369 ("smb_buf_length greater than MaxBufSize")); 442 ("smb_buf_length greater than MaxBufSize"));
370 cERROR(1, 443 cERROR(1,
371 ("bad smb detected. Illegal length. The mid=%d", 444 ("bad smb detected. Illegal length. mid=%d",
372 smb->Mid)); 445 smb->Mid));
373 return 1; 446 return 1;
374 } 447 }
375 448
376 if (checkSMBhdr(smb, mid)) 449 if (checkSMBhdr(smb, mid))
377 return 1; 450 return 1;
378 451 clc_len = smbCalcSize_LE(smb);
379 if ((4 + len != smbCalcSize(smb)) 452 if ((4 + len != clc_len)
380 || (4 + len != (unsigned int)length)) { 453 || (4 + len != (unsigned int)length)) {
381 return 0; 454 cERROR(1, ("Calculated size 0x%x vs actual length 0x%x",
382 } else { 455 clc_len, 4 + len));
383 cERROR(1, ("smbCalcSize %x ", smbCalcSize(smb))); 456 cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid));
384 cERROR(1, 457 /* Windows XP can return a few bytes too much, presumably
385 ("bad smb size detected. The Mid=%d", smb->Mid)); 458 an illegal pad, at the end of byte range lock responses
386 return 1; 459 so we allow for up to eight byte pad, as long as actual
460 received length is as long or longer than calculated length */
461 if((4+len > clc_len) && (len <= clc_len + 3))
462 return 0;
463 else
464 return 1;
387 } 465 }
466 return 0;
388} 467}
389int 468int
390is_valid_oplock_break(struct smb_hdr *buf) 469is_valid_oplock_break(struct smb_hdr *buf)
@@ -448,9 +527,7 @@ is_valid_oplock_break(struct smb_hdr *buf)
448 list_for_each(tmp, &GlobalTreeConnectionList) { 527 list_for_each(tmp, &GlobalTreeConnectionList) {
449 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); 528 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
450 if (tcon->tid == buf->Tid) { 529 if (tcon->tid == buf->Tid) {
451#ifdef CONFIG_CIFS_STATS 530 cifs_stats_inc(&tcon->num_oplock_brks);
452 atomic_inc(&tcon->num_oplock_brks);
453#endif
454 list_for_each(tmp1,&tcon->openFileList){ 531 list_for_each(tmp1,&tcon->openFileList){
455 netfile = list_entry(tmp1,struct cifsFileInfo, 532 netfile = list_entry(tmp1,struct cifsFileInfo,
456 tlist); 533 tlist);
@@ -603,6 +680,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
603 int i,j,charlen; 680 int i,j,charlen;
604 int len_remaining = maxlen; 681 int len_remaining = maxlen;
605 char src_char; 682 char src_char;
683 __u16 temp;
606 684
607 if(!mapChars) 685 if(!mapChars)
608 return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp); 686 return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp);
@@ -639,13 +717,14 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
639 break;*/ 717 break;*/
640 default: 718 default:
641 charlen = cp->char2uni(source+i, 719 charlen = cp->char2uni(source+i,
642 len_remaining, target+j); 720 len_remaining, &temp);
643 /* if no match, use question mark, which 721 /* if no match, use question mark, which
644 at least in some cases servers as wild card */ 722 at least in some cases servers as wild card */
645 if(charlen < 1) { 723 if(charlen < 1) {
646 target[j] = cpu_to_le16(0x003f); 724 target[j] = cpu_to_le16(0x003f);
647 charlen = 1; 725 charlen = 1;
648 } 726 } else
727 target[j] = cpu_to_le16(temp);
649 len_remaining -= charlen; 728 len_remaining -= charlen;
650 /* character may take more than one byte in the 729 /* character may take more than one byte in the
651 the source string, but will take exactly two 730 the source string, but will take exactly two
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index a92af41d4411..f7814689844b 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -133,7 +133,6 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = {
133int 133int
134cifs_inet_pton(int address_family, char *cp,void *dst) 134cifs_inet_pton(int address_family, char *cp,void *dst)
135{ 135{
136 struct in_addr address;
137 int value; 136 int value;
138 int digit; 137 int digit;
139 int i; 138 int i;
@@ -190,8 +189,7 @@ cifs_inet_pton(int address_family, char *cp,void *dst)
190 if (value > addr_class_max[end - bytes]) 189 if (value > addr_class_max[end - bytes])
191 return 0; 190 return 0;
192 191
193 address.s_addr = *((__be32 *) bytes) | htonl(value); 192 *((__be32 *)dst) = *((__be32 *) bytes) | htonl(value);
194 *((__be32 *)dst) = address.s_addr;
195 return 1; /* success */ 193 return 1; /* success */
196} 194}
197 195
@@ -815,7 +813,7 @@ map_smb_to_linux_error(struct smb_hdr *smb)
815 if (smb->Flags2 & SMBFLG2_ERR_STATUS) { 813 if (smb->Flags2 & SMBFLG2_ERR_STATUS) {
816 /* translate the newer STATUS codes to old style errors and then to POSIX errors */ 814 /* translate the newer STATUS codes to old style errors and then to POSIX errors */
817 __u32 err = le32_to_cpu(smb->Status.CifsError); 815 __u32 err = le32_to_cpu(smb->Status.CifsError);
818 if(cifsFYI) 816 if(cifsFYI & CIFS_RC)
819 cifs_print_status(err); 817 cifs_print_status(err);
820 ntstatus_to_dos(err, &smberrclass, &smberrcode); 818 ntstatus_to_dos(err, &smberrclass, &smberrcode);
821 } else { 819 } else {
@@ -870,7 +868,14 @@ unsigned int
870smbCalcSize(struct smb_hdr *ptr) 868smbCalcSize(struct smb_hdr *ptr)
871{ 869{
872 return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) + 870 return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) +
873 BCC(ptr)); 871 2 /* size of the bcc field */ + BCC(ptr));
872}
873
874unsigned int
875smbCalcSize_LE(struct smb_hdr *ptr)
876{
877 return (sizeof (struct smb_hdr) + (2 * ptr->WordCount) +
878 2 /* size of the bcc field */ + le16_to_cpu(BCC_LE(ptr)));
874} 879}
875 880
876/* The following are taken from fs/ntfs/util.c */ 881/* The following are taken from fs/ntfs/util.c */
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
index 6facb41117a3..803389b64a2c 100644
--- a/fs/cifs/ntlmssp.h
+++ b/fs/cifs/ntlmssp.h
@@ -19,8 +19,6 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#pragma pack(1)
23
24#define NTLMSSP_SIGNATURE "NTLMSSP" 22#define NTLMSSP_SIGNATURE "NTLMSSP"
25/* Message Types */ 23/* Message Types */
26#define NtLmNegotiate cpu_to_le32(1) 24#define NtLmNegotiate cpu_to_le32(1)
@@ -63,7 +61,7 @@ typedef struct _SECURITY_BUFFER {
63 __le16 Length; 61 __le16 Length;
64 __le16 MaximumLength; 62 __le16 MaximumLength;
65 __le32 Buffer; /* offset to buffer */ 63 __le32 Buffer; /* offset to buffer */
66} SECURITY_BUFFER; 64} __attribute__((packed)) SECURITY_BUFFER;
67 65
68typedef struct _NEGOTIATE_MESSAGE { 66typedef struct _NEGOTIATE_MESSAGE {
69 __u8 Signature[sizeof (NTLMSSP_SIGNATURE)]; 67 __u8 Signature[sizeof (NTLMSSP_SIGNATURE)];
@@ -73,7 +71,7 @@ typedef struct _NEGOTIATE_MESSAGE {
73 SECURITY_BUFFER WorkstationName; /* RFC 1001 and ASCII */ 71 SECURITY_BUFFER WorkstationName; /* RFC 1001 and ASCII */
74 char DomainString[0]; 72 char DomainString[0];
75 /* followed by WorkstationString */ 73 /* followed by WorkstationString */
76} NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE; 74} __attribute__((packed)) NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE;
77 75
78typedef struct _CHALLENGE_MESSAGE { 76typedef struct _CHALLENGE_MESSAGE {
79 __u8 Signature[sizeof (NTLMSSP_SIGNATURE)]; 77 __u8 Signature[sizeof (NTLMSSP_SIGNATURE)];
@@ -83,7 +81,7 @@ typedef struct _CHALLENGE_MESSAGE {
83 __u8 Challenge[CIFS_CRYPTO_KEY_SIZE]; 81 __u8 Challenge[CIFS_CRYPTO_KEY_SIZE];
84 __u8 Reserved[8]; 82 __u8 Reserved[8];
85 SECURITY_BUFFER TargetInfoArray; 83 SECURITY_BUFFER TargetInfoArray;
86} CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE; 84} __attribute__((packed)) CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE;
87 85
88typedef struct _AUTHENTICATE_MESSAGE { 86typedef struct _AUTHENTICATE_MESSAGE {
89 __u8 Signature[sizeof (NTLMSSP_SIGNATURE)]; 87 __u8 Signature[sizeof (NTLMSSP_SIGNATURE)];
@@ -96,6 +94,4 @@ typedef struct _AUTHENTICATE_MESSAGE {
96 SECURITY_BUFFER SessionKey; 94 SECURITY_BUFFER SessionKey;
97 __le32 NegotiateFlags; 95 __le32 NegotiateFlags;
98 char UserString[0]; 96 char UserString[0];
99} AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE; 97} __attribute__((packed)) AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
100
101#pragma pack() /* resume default structure packing */
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 22557716f9af..a86bd1c07602 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -91,7 +91,10 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
91 } 91 }
92 92
93 *ptmp_inode = new_inode(file->f_dentry->d_sb); 93 *ptmp_inode = new_inode(file->f_dentry->d_sb);
94 tmp_dentry->d_op = &cifs_dentry_ops; 94 if (pTcon->nocase)
95 tmp_dentry->d_op = &cifs_ci_dentry_ops;
96 else
97 tmp_dentry->d_op = &cifs_dentry_ops;
95 if(*ptmp_inode == NULL) 98 if(*ptmp_inode == NULL)
96 return rc; 99 return rc;
97 rc = 1; 100 rc = 1;
@@ -148,6 +151,13 @@ static void fill_in_inode(struct inode *tmp_inode,
148 tmp_inode->i_mode = cifs_sb->mnt_dir_mode; 151 tmp_inode->i_mode = cifs_sb->mnt_dir_mode;
149 } 152 }
150 tmp_inode->i_mode |= S_IFDIR; 153 tmp_inode->i_mode |= S_IFDIR;
154 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
155 (attr & ATTR_SYSTEM) && (end_of_file == 0)) {
156 *pobject_type = DT_FIFO;
157 tmp_inode->i_mode |= S_IFIFO;
158/* BB Finish for SFU style symlinks and devies */
159/* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
160 (attr & ATTR_SYSTEM) && ) { */
151/* we no longer mark these because we could not follow them */ 161/* we no longer mark these because we could not follow them */
152/* } else if (attr & ATTR_REPARSE) { 162/* } else if (attr & ATTR_REPARSE) {
153 *pobject_type = DT_LNK; 163 *pobject_type = DT_LNK;
@@ -187,11 +197,17 @@ static void fill_in_inode(struct inode *tmp_inode,
187 tmp_inode->i_fop = &cifs_file_direct_ops; 197 tmp_inode->i_fop = &cifs_file_direct_ops;
188 else 198 else
189 tmp_inode->i_fop = &cifs_file_ops; 199 tmp_inode->i_fop = &cifs_file_ops;
200 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
201 tmp_inode->i_fop->lock = NULL;
190 tmp_inode->i_data.a_ops = &cifs_addr_ops; 202 tmp_inode->i_data.a_ops = &cifs_addr_ops;
191 203 if((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
204 (cifs_sb->tcon->ses->server->maxBuf <
205 4096 + MAX_CIFS_HDR_SIZE))
206 tmp_inode->i_data.a_ops->readpages = NULL;
192 if(isNewInode) 207 if(isNewInode)
193 return; /* No sense invalidating pages for new inode since we 208 return; /* No sense invalidating pages for new inode
194 have not started caching readahead file data yet */ 209 since have not started caching readahead file
210 data yet */
195 211
196 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && 212 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
197 (local_size == tmp_inode->i_size)) { 213 (local_size == tmp_inode->i_size)) {
@@ -290,7 +306,13 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
290 tmp_inode->i_fop = &cifs_file_direct_ops; 306 tmp_inode->i_fop = &cifs_file_direct_ops;
291 else 307 else
292 tmp_inode->i_fop = &cifs_file_ops; 308 tmp_inode->i_fop = &cifs_file_ops;
309 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
310 tmp_inode->i_fop->lock = NULL;
293 tmp_inode->i_data.a_ops = &cifs_addr_ops; 311 tmp_inode->i_data.a_ops = &cifs_addr_ops;
312 if((cifs_sb->tcon) && (cifs_sb->tcon->ses) &&
313 (cifs_sb->tcon->ses->server->maxBuf <
314 4096 + MAX_CIFS_HDR_SIZE))
315 tmp_inode->i_data.a_ops->readpages = NULL;
294 316
295 if(isNewInode) 317 if(isNewInode)
296 return; /* No sense invalidating pages for new inode since we 318 return; /* No sense invalidating pages for new inode since we
@@ -374,7 +396,8 @@ ffirst_retry:
374 396
375 rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls, 397 rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls,
376 &cifsFile->netfid, &cifsFile->srch_inf, 398 &cifsFile->netfid, &cifsFile->srch_inf,
377 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 399 cifs_sb->mnt_cifs_flags &
400 CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
378 if(rc == 0) 401 if(rc == 0)
379 cifsFile->invalidHandle = FALSE; 402 cifsFile->invalidHandle = FALSE;
380 if((rc == -EOPNOTSUPP) && 403 if((rc == -EOPNOTSUPP) &&
@@ -491,6 +514,30 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
491 return rc; 514 return rc;
492} 515}
493 516
517/* Check if directory that we are searching has changed so we can decide
518 whether we can use the cached search results from the previous search */
519static int is_dir_changed(struct file * file)
520{
521 struct inode * inode;
522 struct cifsInodeInfo *cifsInfo;
523
524 if(file->f_dentry == NULL)
525 return 0;
526
527 inode = file->f_dentry->d_inode;
528
529 if(inode == NULL)
530 return 0;
531
532 cifsInfo = CIFS_I(inode);
533
534 if(cifsInfo->time == 0)
535 return 1; /* directory was changed, perhaps due to unlink */
536 else
537 return 0;
538
539}
540
494/* find the corresponding entry in the search */ 541/* find the corresponding entry in the search */
495/* Note that the SMB server returns search entries for . and .. which 542/* Note that the SMB server returns search entries for . and .. which
496 complicates logic here if we choose to parse for them and we do not 543 complicates logic here if we choose to parse for them and we do not
@@ -507,7 +554,8 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
507 struct cifsFileInfo * cifsFile = file->private_data; 554 struct cifsFileInfo * cifsFile = file->private_data;
508 /* check if index in the buffer */ 555 /* check if index in the buffer */
509 556
510 if((cifsFile == NULL) || (ppCurrentEntry == NULL) || (num_to_ret == NULL)) 557 if((cifsFile == NULL) || (ppCurrentEntry == NULL) ||
558 (num_to_ret == NULL))
511 return -ENOENT; 559 return -ENOENT;
512 560
513 *ppCurrentEntry = NULL; 561 *ppCurrentEntry = NULL;
@@ -515,7 +563,9 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
515 cifsFile->srch_inf.index_of_last_entry - 563 cifsFile->srch_inf.index_of_last_entry -
516 cifsFile->srch_inf.entries_in_buffer; 564 cifsFile->srch_inf.entries_in_buffer;
517/* dump_cifs_file_struct(file, "In fce ");*/ 565/* dump_cifs_file_struct(file, "In fce ");*/
518 if(index_to_find < first_entry_in_buffer) { 566 if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) &&
567 is_dir_changed(file)) ||
568 (index_to_find < first_entry_in_buffer)) {
519 /* close and restart search */ 569 /* close and restart search */
520 cFYI(1,("search backing up - close and restart search")); 570 cFYI(1,("search backing up - close and restart search"));
521 cifsFile->invalidHandle = TRUE; 571 cifsFile->invalidHandle = TRUE;
@@ -536,7 +586,8 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
536 while((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && 586 while((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
537 (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)){ 587 (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)){
538 cFYI(1,("calling findnext2")); 588 cFYI(1,("calling findnext2"));
539 rc = CIFSFindNext(xid,pTcon,cifsFile->netfid, &cifsFile->srch_inf); 589 rc = CIFSFindNext(xid,pTcon,cifsFile->netfid,
590 &cifsFile->srch_inf);
540 if(rc) 591 if(rc)
541 return -ENOENT; 592 return -ENOENT;
542 } 593 }
@@ -548,14 +599,13 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
548 char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + 599 char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
549 smbCalcSize((struct smb_hdr *) 600 smbCalcSize((struct smb_hdr *)
550 cifsFile->srch_inf.ntwrk_buf_start); 601 cifsFile->srch_inf.ntwrk_buf_start);
551/* dump_cifs_file_struct(file,"found entry in fce "); */
552 first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry 602 first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
553 - cifsFile->srch_inf.entries_in_buffer; 603 - cifsFile->srch_inf.entries_in_buffer;
554 pos_in_buf = index_to_find - first_entry_in_buffer; 604 pos_in_buf = index_to_find - first_entry_in_buffer;
555 cFYI(1,("found entry - pos_in_buf %d",pos_in_buf)); 605 cFYI(1,("found entry - pos_in_buf %d",pos_in_buf));
556 current_entry = cifsFile->srch_inf.srch_entries_start; 606 current_entry = cifsFile->srch_inf.srch_entries_start;
557 for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) { 607 for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) {
558 /* go entry to next entry figuring out which we need to start with */ 608 /* go entry by entry figuring out which is first */
559 /* if( . or ..) 609 /* if( . or ..)
560 skip */ 610 skip */
561 rc = cifs_entry_is_dot(current_entry,cifsFile); 611 rc = cifs_entry_is_dot(current_entry,cifsFile);
@@ -582,11 +632,10 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
582 } 632 }
583 633
584 if(pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) { 634 if(pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) {
585 cFYI(1,("can not return entries when pos_in_buf beyond last entry")); 635 cFYI(1,("can not return entries pos_in_buf beyond last entry"));
586 *num_to_ret = 0; 636 *num_to_ret = 0;
587 } else 637 } else
588 *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf; 638 *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf;
589/* dump_cifs_file_struct(file, "end fce ");*/
590 639
591 return rc; 640 return rc;
592} 641}
@@ -721,7 +770,8 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
721 (FILE_DIRECTORY_INFO *)pfindEntry,&obj_type, rc); 770 (FILE_DIRECTORY_INFO *)pfindEntry,&obj_type, rc);
722 } 771 }
723 772
724 rc = filldir(direntry,qstring.name,qstring.len,file->f_pos,tmp_inode->i_ino,obj_type); 773 rc = filldir(direntry,qstring.name,qstring.len,file->f_pos,
774 tmp_inode->i_ino,obj_type);
725 if(rc) { 775 if(rc) {
726 cFYI(1,("filldir rc = %d",rc)); 776 cFYI(1,("filldir rc = %d",rc));
727 } 777 }
@@ -805,15 +855,12 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
805 FreeXid(xid); 855 FreeXid(xid);
806 return -EIO; 856 return -EIO;
807 } 857 }
808/* dump_cifs_file_struct(file, "Begin rdir "); */
809 858
810 cifs_sb = CIFS_SB(file->f_dentry->d_sb); 859 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
811 pTcon = cifs_sb->tcon; 860 pTcon = cifs_sb->tcon;
812 if(pTcon == NULL) 861 if(pTcon == NULL)
813 return -EINVAL; 862 return -EINVAL;
814 863
815/* cFYI(1,("readdir2 pos: %lld",file->f_pos)); */
816
817 switch ((int) file->f_pos) { 864 switch ((int) file->f_pos) {
818 case 0: 865 case 0:
819 /*if (filldir(direntry, ".", 1, file->f_pos, 866 /*if (filldir(direntry, ".", 1, file->f_pos,
@@ -866,7 +913,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
866 cifsFile->search_resume_name = NULL; */ 913 cifsFile->search_resume_name = NULL; */
867 914
868 /* BB account for . and .. in f_pos as special case */ 915 /* BB account for . and .. in f_pos as special case */
869 /* dump_cifs_file_struct(file, "rdir after default ");*/
870 916
871 rc = find_cifs_entry(xid,pTcon, file, 917 rc = find_cifs_entry(xid,pTcon, file,
872 &current_entry,&num_to_fill); 918 &current_entry,&num_to_fill);
@@ -906,14 +952,14 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
906 cifs_save_resume_key(current_entry,cifsFile); 952 cifs_save_resume_key(current_entry,cifsFile);
907 break; 953 break;
908 } else 954 } else
909 current_entry = nxt_dir_entry(current_entry,end_of_smb); 955 current_entry = nxt_dir_entry(current_entry,
956 end_of_smb);
910 } 957 }
911 kfree(tmp_buf); 958 kfree(tmp_buf);
912 break; 959 break;
913 } /* end switch */ 960 } /* end switch */
914 961
915rddir2_exit: 962rddir2_exit:
916 /* dump_cifs_file_struct(file, "end rdir "); */
917 FreeXid(xid); 963 FreeXid(xid);
918 return rc; 964 return rc;
919} 965}
diff --git a/fs/cifs/rfc1002pdu.h b/fs/cifs/rfc1002pdu.h
index 806c0ed06da9..9222033cad8e 100644
--- a/fs/cifs/rfc1002pdu.h
+++ b/fs/cifs/rfc1002pdu.h
@@ -21,8 +21,6 @@
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */ 22 */
23 23
24#pragma pack(1)
25
26/* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */ 24/* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */
27 25
28 /* RFC 1002 session packet types */ 26 /* RFC 1002 session packet types */
@@ -48,17 +46,17 @@ struct rfc1002_session_packet {
48 __u8 calling_len; 46 __u8 calling_len;
49 __u8 calling_name[32]; 47 __u8 calling_name[32];
50 __u8 scope2; /* null */ 48 __u8 scope2; /* null */
51 } session_req; 49 } __attribute__((packed)) session_req;
52 struct { 50 struct {
53 __u32 retarget_ip_addr; 51 __u32 retarget_ip_addr;
54 __u16 port; 52 __u16 port;
55 } retarget_resp; 53 } __attribute__((packed)) retarget_resp;
56 __u8 neg_ses_resp_error_code; 54 __u8 neg_ses_resp_error_code;
57 /* POSITIVE_SESSION_RESPONSE packet does not include trailer. 55 /* POSITIVE_SESSION_RESPONSE packet does not include trailer.
58 SESSION_KEEP_ALIVE packet also does not include a trailer. 56 SESSION_KEEP_ALIVE packet also does not include a trailer.
59 Trailer for the SESSION_MESSAGE packet is SMB/CIFS header */ 57 Trailer for the SESSION_MESSAGE packet is SMB/CIFS header */
60 } trailer; 58 } __attribute__((packed)) trailer;
61}; 59} __attribute__((packed));
62 60
63/* Negative Session Response error codes */ 61/* Negative Session Response error codes */
64#define RFC1002_NOT_LISTENING_CALLED 0x80 /* not listening on called name */ 62#define RFC1002_NOT_LISTENING_CALLED 0x80 /* not listening on called name */
@@ -74,6 +72,3 @@ server netbios name). Currently server names are resolved only via DNS
74(tcp name) or ip address or an /etc/hosts equivalent mapping to ip address.*/ 72(tcp name) or ip address or an /etc/hosts equivalent mapping to ip address.*/
75 73
76#define DEFAULT_CIFS_CALLED_NAME "*SMBSERVER " 74#define DEFAULT_CIFS_CALLED_NAME "*SMBSERVER "
77
78#pragma pack() /* resume default structure packing */
79
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 0046c219833d..981ea0d8b9cd 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -49,7 +49,8 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
49 return NULL; 49 return NULL;
50 } 50 }
51 51
52 temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp,SLAB_KERNEL | SLAB_NOFS); 52 temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp,
53 SLAB_KERNEL | SLAB_NOFS);
53 if (temp == NULL) 54 if (temp == NULL)
54 return temp; 55 return temp;
55 else { 56 else {
@@ -58,7 +59,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
58 temp->pid = current->pid; 59 temp->pid = current->pid;
59 temp->command = smb_buffer->Command; 60 temp->command = smb_buffer->Command;
60 cFYI(1, ("For smb_command %d", temp->command)); 61 cFYI(1, ("For smb_command %d", temp->command));
61 do_gettimeofday(&temp->when_sent); 62 /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
63 /* when mid allocated can be before when sent */
64 temp->when_alloc = jiffies;
62 temp->ses = ses; 65 temp->ses = ses;
63 temp->tsk = current; 66 temp->tsk = current;
64 } 67 }
@@ -74,6 +77,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
74static void 77static void
75DeleteMidQEntry(struct mid_q_entry *midEntry) 78DeleteMidQEntry(struct mid_q_entry *midEntry)
76{ 79{
80#ifdef CONFIG_CIFS_STATS2
81 unsigned long now;
82#endif
77 spin_lock(&GlobalMid_Lock); 83 spin_lock(&GlobalMid_Lock);
78 midEntry->midState = MID_FREE; 84 midEntry->midState = MID_FREE;
79 list_del(&midEntry->qhead); 85 list_del(&midEntry->qhead);
@@ -83,6 +89,22 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
83 cifs_buf_release(midEntry->resp_buf); 89 cifs_buf_release(midEntry->resp_buf);
84 else 90 else
85 cifs_small_buf_release(midEntry->resp_buf); 91 cifs_small_buf_release(midEntry->resp_buf);
92#ifdef CONFIG_CIFS_STATS2
93 now = jiffies;
94 /* commands taking longer than one second are indications that
95 something is wrong, unless it is quite a slow link or server */
96 if((now - midEntry->when_alloc) > HZ) {
97 if((cifsFYI & CIFS_TIMER) &&
98 (midEntry->command != SMB_COM_LOCKING_ANDX)) {
99 printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %d",
100 midEntry->command, midEntry->mid);
101 printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
102 now - midEntry->when_alloc,
103 now - midEntry->when_sent,
104 now - midEntry->when_received);
105 }
106 }
107#endif
86 mempool_free(midEntry, cifs_mid_poolp); 108 mempool_free(midEntry, cifs_mid_poolp);
87} 109}
88 110
@@ -146,32 +168,37 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
146 Flags2 is converted in SendReceive */ 168 Flags2 is converted in SendReceive */
147 169
148 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); 170 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
149 cFYI(1, ("Sending smb of length %d ", smb_buf_length)); 171 cFYI(1, ("Sending smb of length %d", smb_buf_length));
150 dump_smb(smb_buffer, len); 172 dump_smb(smb_buffer, len);
151 173
152 while (len > 0) { 174 while (len > 0) {
153 rc = kernel_sendmsg(ssocket, &smb_msg, &iov, 1, len); 175 rc = kernel_sendmsg(ssocket, &smb_msg, &iov, 1, len);
154 if ((rc == -ENOSPC) || (rc == -EAGAIN)) { 176 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
155 i++; 177 i++;
156 if(i > 60) { 178 /* smaller timeout here than send2 since smaller size */
179 /* Although it may not be required, this also is smaller
180 oplock break time */
181 if(i > 12) {
157 cERROR(1, 182 cERROR(1,
158 ("sends on sock %p stuck for 30 seconds", 183 ("sends on sock %p stuck for 7 seconds",
159 ssocket)); 184 ssocket));
160 rc = -EAGAIN; 185 rc = -EAGAIN;
161 break; 186 break;
162 } 187 }
163 msleep(500); 188 msleep(1 << i);
164 continue; 189 continue;
165 } 190 }
166 if (rc < 0) 191 if (rc < 0)
167 break; 192 break;
193 else
194 i = 0; /* reset i after each successful send */
168 iov.iov_base += rc; 195 iov.iov_base += rc;
169 iov.iov_len -= rc; 196 iov.iov_len -= rc;
170 len -= rc; 197 len -= rc;
171 } 198 }
172 199
173 if (rc < 0) { 200 if (rc < 0) {
174 cERROR(1,("Error %d sending data on socket to server.", rc)); 201 cERROR(1,("Error %d sending data on socket to server", rc));
175 } else { 202 } else {
176 rc = 0; 203 rc = 0;
177 } 204 }
@@ -179,26 +206,21 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
179 return rc; 206 return rc;
180} 207}
181 208
182#ifdef CIFS_EXPERIMENTAL 209#ifdef CONFIG_CIFS_EXPERIMENTAL
183/* BB finish off this function, adding support for writing set of pages as iovec */ 210static int
184/* and also adding support for operations that need to parse the response smb */ 211smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
185 212 struct sockaddr *sin)
186int
187smb_sendv(struct socket *ssocket, struct smb_hdr *smb_buffer,
188 unsigned int smb_buf_length, struct kvec * write_vector
189 /* page list */, struct sockaddr *sin)
190{ 213{
191 int rc = 0; 214 int rc = 0;
192 int i = 0; 215 int i = 0;
193 struct msghdr smb_msg; 216 struct msghdr smb_msg;
194 number_of_pages += 1; /* account for SMB header */ 217 struct smb_hdr *smb_buffer = iov[0].iov_base;
195 struct kvec * piov = kmalloc(number_of_pages * sizeof(struct kvec)); 218 unsigned int len = iov[0].iov_len;
196 unsigned len = smb_buf_length + 4; 219 unsigned int total_len;
197 220 int first_vec = 0;
221
198 if(ssocket == NULL) 222 if(ssocket == NULL)
199 return -ENOTSOCK; /* BB eventually add reconnect code here */ 223 return -ENOTSOCK; /* BB eventually add reconnect code here */
200 iov.iov_base = smb_buffer;
201 iov.iov_len = len;
202 224
203 smb_msg.msg_name = sin; 225 smb_msg.msg_name = sin;
204 smb_msg.msg_namelen = sizeof (struct sockaddr); 226 smb_msg.msg_namelen = sizeof (struct sockaddr);
@@ -211,49 +233,80 @@ smb_sendv(struct socket *ssocket, struct smb_hdr *smb_buffer,
211 cifssmb.c and RFC1001 len is converted to bigendian in smb_send 233 cifssmb.c and RFC1001 len is converted to bigendian in smb_send
212 Flags2 is converted in SendReceive */ 234 Flags2 is converted in SendReceive */
213 235
236
237 total_len = 0;
238 for (i = 0; i < n_vec; i++)
239 total_len += iov[i].iov_len;
240
214 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); 241 smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
215 cFYI(1, ("Sending smb of length %d ", smb_buf_length)); 242 cFYI(1, ("Sending smb: total_len %d", total_len));
216 dump_smb(smb_buffer, len); 243 dump_smb(smb_buffer, len);
217 244
218 while (len > 0) { 245 while (total_len) {
219 rc = kernel_sendmsg(ssocket, &smb_msg, &iov, number_of_pages, 246 rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
220 len); 247 n_vec - first_vec, total_len);
221 if ((rc == -ENOSPC) || (rc == -EAGAIN)) { 248 if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
222 i++; 249 i++;
223 if(i > 60) { 250 if(i >= 14) {
224 cERROR(1, 251 cERROR(1,
225 ("sends on sock %p stuck for 30 seconds", 252 ("sends on sock %p stuck for 15 seconds",
226 ssocket)); 253 ssocket));
227 rc = -EAGAIN; 254 rc = -EAGAIN;
228 break; 255 break;
229 } 256 }
230 msleep(500); 257 msleep(1 << i);
231 continue; 258 continue;
232 } 259 }
233 if (rc < 0) 260 if (rc < 0)
234 break; 261 break;
235 iov.iov_base += rc; 262
236 iov.iov_len -= rc; 263 if (rc >= total_len) {
237 len -= rc; 264 WARN_ON(rc > total_len);
265 break;
266 }
267 if(rc == 0) {
268 /* should never happen, letting socket clear before
269 retrying is our only obvious option here */
270 cERROR(1,("tcp sent no data"));
271 msleep(500);
272 continue;
273 }
274 total_len -= rc;
275 /* the line below resets i */
276 for (i = first_vec; i < n_vec; i++) {
277 if (iov[i].iov_len) {
278 if (rc > iov[i].iov_len) {
279 rc -= iov[i].iov_len;
280 iov[i].iov_len = 0;
281 } else {
282 iov[i].iov_base += rc;
283 iov[i].iov_len -= rc;
284 first_vec = i;
285 break;
286 }
287 }
288 }
289 i = 0; /* in case we get ENOSPC on the next send */
238 } 290 }
239 291
240 if (rc < 0) { 292 if (rc < 0) {
241 cERROR(1,("Error %d sending data on socket to server.", rc)); 293 cERROR(1,("Error %d sending data on socket to server", rc));
242 } else { 294 } else
243 rc = 0; 295 rc = 0;
244 }
245 296
246 return rc; 297 return rc;
247} 298}
248 299
249
250int 300int
251CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses, 301SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
252 struct smb_hdr *in_buf, struct kvec * write_vector /* page list */, int *pbytes_returned, const int long_op) 302 struct kvec *iov, int n_vec, int *pbytes_returned,
303 const int long_op)
253{ 304{
254 int rc = 0; 305 int rc = 0;
255 unsigned long timeout = 15 * HZ; 306 unsigned int receive_len;
256 struct mid_q_entry *midQ = NULL; 307 unsigned long timeout;
308 struct mid_q_entry *midQ;
309 struct smb_hdr *in_buf = iov[0].iov_base;
257 310
258 if (ses == NULL) { 311 if (ses == NULL) {
259 cERROR(1,("Null smb session")); 312 cERROR(1,("Null smb session"));
@@ -263,14 +316,8 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses,
263 cERROR(1,("Null tcp session")); 316 cERROR(1,("Null tcp session"));
264 return -EIO; 317 return -EIO;
265 } 318 }
266 if(pbytes_returned == NULL)
267 return -EIO;
268 else
269 *pbytes_returned = 0;
270 319
271 320 if(ses->server->tcpStatus == CifsExiting)
272
273 if(ses->server->tcpStatus == CIFS_EXITING)
274 return -ENOENT; 321 return -ENOENT;
275 322
276 /* Ensure that we do not send more than 50 overlapping requests 323 /* Ensure that we do not send more than 50 overlapping requests
@@ -282,11 +329,18 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses,
282 } else { 329 } else {
283 spin_lock(&GlobalMid_Lock); 330 spin_lock(&GlobalMid_Lock);
284 while(1) { 331 while(1) {
285 if(atomic_read(&ses->server->inFlight) >= cifs_max_pending){ 332 if(atomic_read(&ses->server->inFlight) >=
333 cifs_max_pending){
286 spin_unlock(&GlobalMid_Lock); 334 spin_unlock(&GlobalMid_Lock);
335#ifdef CONFIG_CIFS_STATS2
336 atomic_inc(&ses->server->num_waiters);
337#endif
287 wait_event(ses->server->request_q, 338 wait_event(ses->server->request_q,
288 atomic_read(&ses->server->inFlight) 339 atomic_read(&ses->server->inFlight)
289 < cifs_max_pending); 340 < cifs_max_pending);
341#ifdef CONFIG_CIFS_STATS2
342 atomic_dec(&ses->server->num_waiters);
343#endif
290 spin_lock(&GlobalMid_Lock); 344 spin_lock(&GlobalMid_Lock);
291 } else { 345 } else {
292 if(ses->server->tcpStatus == CifsExiting) { 346 if(ses->server->tcpStatus == CifsExiting) {
@@ -314,17 +368,17 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses,
314 368
315 if (ses->server->tcpStatus == CifsExiting) { 369 if (ses->server->tcpStatus == CifsExiting) {
316 rc = -ENOENT; 370 rc = -ENOENT;
317 goto cifs_out_label; 371 goto out_unlock2;
318 } else if (ses->server->tcpStatus == CifsNeedReconnect) { 372 } else if (ses->server->tcpStatus == CifsNeedReconnect) {
319 cFYI(1,("tcp session dead - return to caller to retry")); 373 cFYI(1,("tcp session dead - return to caller to retry"));
320 rc = -EAGAIN; 374 rc = -EAGAIN;
321 goto cifs_out_label; 375 goto out_unlock2;
322 } else if (ses->status != CifsGood) { 376 } else if (ses->status != CifsGood) {
323 /* check if SMB session is bad because we are setting it up */ 377 /* check if SMB session is bad because we are setting it up */
324 if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && 378 if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
325 (in_buf->Command != SMB_COM_NEGOTIATE)) { 379 (in_buf->Command != SMB_COM_NEGOTIATE)) {
326 rc = -EAGAIN; 380 rc = -EAGAIN;
327 goto cifs_out_label; 381 goto out_unlock2;
328 } /* else ok - we are setting up session */ 382 } /* else ok - we are setting up session */
329 } 383 }
330 midQ = AllocMidQEntry(in_buf, ses); 384 midQ = AllocMidQEntry(in_buf, ses);
@@ -338,51 +392,162 @@ CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses,
338 return -ENOMEM; 392 return -ENOMEM;
339 } 393 }
340 394
341 if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { 395/* BB FIXME */
342 up(&ses->server->tcpSem); 396/* rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); */
343 cERROR(1, 397
344 ("Illegal length, greater than maximum frame, %d ", 398 midQ->midState = MID_REQUEST_SUBMITTED;
345 in_buf->smb_buf_length)); 399#ifdef CONFIG_CIFS_STATS2
400 atomic_inc(&ses->server->inSend);
401#endif
402 rc = smb_send2(ses->server->ssocket, iov, n_vec,
403 (struct sockaddr *) &(ses->server->addr.sockAddr));
404#ifdef CONFIG_CIFS_STATS2
405 atomic_dec(&ses->server->inSend);
406 midQ->when_sent = jiffies;
407#endif
408 if(rc < 0) {
346 DeleteMidQEntry(midQ); 409 DeleteMidQEntry(midQ);
410 up(&ses->server->tcpSem);
347 /* If not lock req, update # of requests on wire to server */ 411 /* If not lock req, update # of requests on wire to server */
348 if(long_op < 3) { 412 if(long_op < 3) {
349 atomic_dec(&ses->server->inFlight); 413 atomic_dec(&ses->server->inFlight);
350 wake_up(&ses->server->request_q); 414 wake_up(&ses->server->request_q);
351 } 415 }
352 return -EIO; 416 return rc;
417 } else
418 up(&ses->server->tcpSem);
419 if (long_op == -1)
420 goto cifs_no_response_exit2;
421 else if (long_op == 2) /* writes past end of file can take loong time */
422 timeout = 180 * HZ;
423 else if (long_op == 1)
424 timeout = 45 * HZ; /* should be greater than
425 servers oplock break timeout (about 43 seconds) */
426 else if (long_op > 2) {
427 timeout = MAX_SCHEDULE_TIMEOUT;
428 } else
429 timeout = 15 * HZ;
430 /* wait for 15 seconds or until woken up due to response arriving or
431 due to last connection to this server being unmounted */
432 if (signal_pending(current)) {
433 /* if signal pending do not hold up user for full smb timeout
434 but we still give response a change to complete */
435 timeout = 2 * HZ;
436 }
437
438 /* No user interrupts in wait - wreaks havoc with performance */
439 if(timeout != MAX_SCHEDULE_TIMEOUT) {
440 timeout += jiffies;
441 wait_event(ses->server->response_q,
442 (!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
443 time_after(jiffies, timeout) ||
444 ((ses->server->tcpStatus != CifsGood) &&
445 (ses->server->tcpStatus != CifsNew)));
446 } else {
447 wait_event(ses->server->response_q,
448 (!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
449 ((ses->server->tcpStatus != CifsGood) &&
450 (ses->server->tcpStatus != CifsNew)));
353 } 451 }
354 452
355 /* BB can we sign efficiently in this path? */ 453 spin_lock(&GlobalMid_Lock);
356 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); 454 if (midQ->resp_buf) {
455 spin_unlock(&GlobalMid_Lock);
456 receive_len = midQ->resp_buf->smb_buf_length;
457 } else {
458 cERROR(1,("No response to cmd %d mid %d",
459 midQ->command, midQ->mid));
460 if(midQ->midState == MID_REQUEST_SUBMITTED) {
461 if(ses->server->tcpStatus == CifsExiting)
462 rc = -EHOSTDOWN;
463 else {
464 ses->server->tcpStatus = CifsNeedReconnect;
465 midQ->midState = MID_RETRY_NEEDED;
466 }
467 }
357 468
358 midQ->midState = MID_REQUEST_SUBMITTED; 469 if (rc != -EHOSTDOWN) {
359/* rc = smb_sendv(ses->server->ssocket, in_buf, in_buf->smb_buf_length, 470 if(midQ->midState == MID_RETRY_NEEDED) {
360 piovec, 471 rc = -EAGAIN;
361 (struct sockaddr *) &(ses->server->addr.sockAddr));*/ 472 cFYI(1,("marking request for retry"));
362 if(rc < 0) { 473 } else {
474 rc = -EIO;
475 }
476 }
477 spin_unlock(&GlobalMid_Lock);
363 DeleteMidQEntry(midQ); 478 DeleteMidQEntry(midQ);
364 up(&ses->server->tcpSem);
365 /* If not lock req, update # of requests on wire to server */ 479 /* If not lock req, update # of requests on wire to server */
366 if(long_op < 3) { 480 if(long_op < 3) {
367 atomic_dec(&ses->server->inFlight); 481 atomic_dec(&ses->server->inFlight);
368 wake_up(&ses->server->request_q); 482 wake_up(&ses->server->request_q);
369 } 483 }
370 return rc; 484 return rc;
371 } else 485 }
372 up(&ses->server->tcpSem); 486
373cifs_out_label: 487 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
374 if(midQ) 488 cERROR(1, ("Frame too large received. Length: %d Xid: %d",
375 DeleteMidQEntry(midQ); 489 receive_len, xid));
376 490 rc = -EIO;
491 } else { /* rcvd frame is ok */
492
493 if (midQ->resp_buf &&
494 (midQ->midState == MID_RESPONSE_RECEIVED)) {
495 in_buf->smb_buf_length = receive_len;
496 /* BB verify that length would not overrun small buf */
497 memcpy((char *)in_buf + 4,
498 (char *)midQ->resp_buf + 4,
499 receive_len);
500
501 dump_smb(in_buf, 80);
502 /* convert the length into a more usable form */
503 if((receive_len > 24) &&
504 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
505 SECMODE_SIGN_ENABLED))) {
506 rc = cifs_verify_signature(in_buf,
507 ses->server->mac_signing_key,
508 midQ->sequence_number+1);
509 if(rc) {
510 cERROR(1,("Unexpected SMB signature"));
511 /* BB FIXME add code to kill session */
512 }
513 }
514
515 *pbytes_returned = in_buf->smb_buf_length;
516
517 /* BB special case reconnect tid and uid here? */
518 rc = map_smb_to_linux_error(in_buf);
519
520 /* convert ByteCount if necessary */
521 if (receive_len >=
522 sizeof (struct smb_hdr) -
523 4 /* do not count RFC1001 header */ +
524 (2 * in_buf->WordCount) + 2 /* bcc */ )
525 BCC(in_buf) = le16_to_cpu(BCC(in_buf));
526 } else {
527 rc = -EIO;
528 cFYI(1,("Bad MID state?"));
529 }
530 }
531cifs_no_response_exit2:
532 DeleteMidQEntry(midQ);
533
377 if(long_op < 3) { 534 if(long_op < 3) {
378 atomic_dec(&ses->server->inFlight); 535 atomic_dec(&ses->server->inFlight);
379 wake_up(&ses->server->request_q); 536 wake_up(&ses->server->request_q);
380 } 537 }
381 538
382 return rc; 539 return rc;
383}
384 540
541out_unlock2:
542 up(&ses->server->tcpSem);
543 /* If not lock req, update # of requests on wire to server */
544 if(long_op < 3) {
545 atomic_dec(&ses->server->inFlight);
546 wake_up(&ses->server->request_q);
547 }
385 548
549 return rc;
550}
386#endif /* CIFS_EXPERIMENTAL */ 551#endif /* CIFS_EXPERIMENTAL */
387 552
388int 553int
@@ -419,9 +584,15 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
419 if(atomic_read(&ses->server->inFlight) >= 584 if(atomic_read(&ses->server->inFlight) >=
420 cifs_max_pending){ 585 cifs_max_pending){
421 spin_unlock(&GlobalMid_Lock); 586 spin_unlock(&GlobalMid_Lock);
587#ifdef CONFIG_CIFS_STATS2
588 atomic_inc(&ses->server->num_waiters);
589#endif
422 wait_event(ses->server->request_q, 590 wait_event(ses->server->request_q,
423 atomic_read(&ses->server->inFlight) 591 atomic_read(&ses->server->inFlight)
424 < cifs_max_pending); 592 < cifs_max_pending);
593#ifdef CONFIG_CIFS_STATS2
594 atomic_dec(&ses->server->num_waiters);
595#endif
425 spin_lock(&GlobalMid_Lock); 596 spin_lock(&GlobalMid_Lock);
426 } else { 597 } else {
427 if(ses->server->tcpStatus == CifsExiting) { 598 if(ses->server->tcpStatus == CifsExiting) {
@@ -490,8 +661,15 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
490 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); 661 rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
491 662
492 midQ->midState = MID_REQUEST_SUBMITTED; 663 midQ->midState = MID_REQUEST_SUBMITTED;
664#ifdef CONFIG_CIFS_STATS2
665 atomic_inc(&ses->server->inSend);
666#endif
493 rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, 667 rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
494 (struct sockaddr *) &(ses->server->addr.sockAddr)); 668 (struct sockaddr *) &(ses->server->addr.sockAddr));
669#ifdef CONFIG_CIFS_STATS2
670 atomic_dec(&ses->server->inSend);
671 midQ->when_sent = jiffies;
672#endif
495 if(rc < 0) { 673 if(rc < 0) {
496 DeleteMidQEntry(midQ); 674 DeleteMidQEntry(midQ);
497 up(&ses->server->tcpSem); 675 up(&ses->server->tcpSem);
@@ -506,7 +684,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
506 if (long_op == -1) 684 if (long_op == -1)
507 goto cifs_no_response_exit; 685 goto cifs_no_response_exit;
508 else if (long_op == 2) /* writes past end of file can take loong time */ 686 else if (long_op == 2) /* writes past end of file can take loong time */
509 timeout = 300 * HZ; 687 timeout = 180 * HZ;
510 else if (long_op == 1) 688 else if (long_op == 1)
511 timeout = 45 * HZ; /* should be greater than 689 timeout = 45 * HZ; /* should be greater than
512 servers oplock break timeout (about 43 seconds) */ 690 servers oplock break timeout (about 43 seconds) */
@@ -540,9 +718,10 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
540 spin_lock(&GlobalMid_Lock); 718 spin_lock(&GlobalMid_Lock);
541 if (midQ->resp_buf) { 719 if (midQ->resp_buf) {
542 spin_unlock(&GlobalMid_Lock); 720 spin_unlock(&GlobalMid_Lock);
543 receive_len = be32_to_cpu(*(__be32 *)midQ->resp_buf); 721 receive_len = midQ->resp_buf->smb_buf_length;
544 } else { 722 } else {
545 cERROR(1,("No response buffer")); 723 cERROR(1,("No response for cmd %d mid %d",
724 midQ->command, midQ->mid));
546 if(midQ->midState == MID_REQUEST_SUBMITTED) { 725 if(midQ->midState == MID_REQUEST_SUBMITTED) {
547 if(ses->server->tcpStatus == CifsExiting) 726 if(ses->server->tcpStatus == CifsExiting)
548 rc = -EHOSTDOWN; 727 rc = -EHOSTDOWN;
@@ -610,7 +789,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
610 BCC(out_buf) = le16_to_cpu(BCC(out_buf)); 789 BCC(out_buf) = le16_to_cpu(BCC(out_buf));
611 } else { 790 } else {
612 rc = -EIO; 791 rc = -EIO;
613 cFYI(1,("Bad MID state? ")); 792 cERROR(1,("Bad MID state? "));
614 } 793 }
615 } 794 }
616cifs_no_response_exit: 795cifs_no_response_exit:
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index ffab4783ac64..c27f8d4098be 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -247,7 +247,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
247 wait_queue_head_t *wqh; 247 wait_queue_head_t *wqh;
248 248
249 if (!atomic_read(&inode->i_count)) 249 if (!atomic_read(&inode->i_count))
250 WARN_ON(!(inode->i_state & I_WILL_FREE)); 250 WARN_ON(!(inode->i_state & (I_WILL_FREE|I_FREEING)));
251 else 251 else
252 WARN_ON(inode->i_state & I_WILL_FREE); 252 WARN_ON(inode->i_state & I_WILL_FREE);
253 253
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
index de58579a1d0e..50a7749cfca1 100644
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -1,18 +1,15 @@
1ToDo/Notes: 1ToDo/Notes:
2 - Find and fix bugs. 2 - Find and fix bugs.
3 - In between ntfs_prepare/commit_write, need exclusion between 3 - The only places in the kernel where a file is resized are
4 simultaneous file extensions. This is given to us by holding i_sem 4 ntfs_file_write*() and ntfs_truncate() for both of which i_sem is
5 on the inode. The only places in the kernel when a file is resized 5 held. Just have to be careful in read-/writepage and other helpers
6 are prepare/commit write and truncate for both of which i_sem is 6 not running under i_sem that we play nice... Also need to be careful
7 held. Just have to be careful in readpage/writepage and all other 7 with initialized_size extension in ntfs_file_write*() and writepage.
8 helpers not running under i_sem that we play nice... 8 UPDATE: The only things that need to be checked are the compressed
9 Also need to be careful with initialized_size extention in 9 write and the other attribute resize/write cases like index
10 ntfs_prepare_write. Basically, just be _very_ careful in this code... 10 attributes, etc. For now none of these are implemented so are safe.
11 UPDATE: The only things that need to be checked are read/writepage 11 - Implement filling in of holes in aops.c::ntfs_writepage() and its
12 which do not hold i_sem. Note writepage cannot change i_size but it 12 helpers.
13 needs to cope with a concurrent i_size change, just like readpage.
14 Also both need to cope with concurrent changes to the other sizes,
15 i.e. initialized/allocated/compressed size, as well.
16 - Implement mft.c::sync_mft_mirror_umount(). We currently will just 13 - Implement mft.c::sync_mft_mirror_umount(). We currently will just
17 leave the volume dirty on umount if the final iput(vol->mft_ino) 14 leave the volume dirty on umount if the final iput(vol->mft_ino)
18 causes a write of any mirrored mft records due to the mft mirror 15 causes a write of any mirrored mft records due to the mft mirror
@@ -22,6 +19,68 @@ ToDo/Notes:
22 - Enable the code for setting the NT4 compatibility flag when we start 19 - Enable the code for setting the NT4 compatibility flag when we start
23 making NTFS 1.2 specific modifications. 20 making NTFS 1.2 specific modifications.
24 21
222.1.25 - (Almost) fully implement write(2) and truncate(2).
23
24 - Change ntfs_map_runlist_nolock(), ntfs_attr_find_vcn_nolock() and
25 {__,}ntfs_cluster_free() to also take an optional attribute search
26 context as argument. This allows calling these functions with the
27 mft record mapped. Update all callers.
28 - Fix potential deadlock in ntfs_mft_data_extend_allocation_nolock()
29 error handling by passing in the active search context when calling
30 ntfs_cluster_free().
31 - Change ntfs_cluster_alloc() to take an extra boolean parameter
32 specifying whether the cluster are being allocated to extend an
33 attribute or to fill a hole.
34 - Change ntfs_attr_make_non_resident() to call ntfs_cluster_alloc()
35 with @is_extension set to TRUE and remove the runlist terminator
36 fixup code as this is now done by ntfs_cluster_alloc().
37 - Change ntfs_attr_make_non_resident to take the attribute value size
38 as an extra parameter. This is needed since we need to know the size
39 before we can map the mft record and our callers always know it. The
40 reason we cannot simply read the size from the vfs inode i_size is
41 that this is not necessarily uptodate. This happens when
42 ntfs_attr_make_non_resident() is called in the ->truncate call path.
43 - Fix ntfs_attr_make_non_resident() to update the vfs inode i_blocks
44 which is zero for a resident attribute but should no longer be zero
45 once the attribute is non-resident as it then has real clusters
46 allocated.
47 - Add fs/ntfs/attrib.[hc]::ntfs_attr_extend_allocation(), a function to
48 extend the allocation of an attributes. Optionally, the data size,
49 but not the initialized size can be extended, too.
50 - Implement fs/ntfs/inode.[hc]::ntfs_truncate(). It only supports
51 uncompressed and unencrypted files and it never creates sparse files
52 at least for the moment (making a file sparse requires us to modify
53 its directory entries and we do not support directory operations at
54 the moment). Also, support for highly fragmented files, i.e. ones
55 whose data attribute is split across multiple extents, is severly
56 limited. When such a case is encountered, EOPNOTSUPP is returned.
57 - Enable ATTR_SIZE attribute changes in ntfs_setattr(). This completes
58 the initial implementation of file truncation. Now both open(2)ing
59 a file with the O_TRUNC flag and the {,f}truncate(2) system calls
60 will resize a file appropriately. The limitations are that only
61 uncompressed and unencrypted files are supported. Also, there is
62 only very limited support for highly fragmented files (the ones whose
63 $DATA attribute is split into multiple attribute extents).
64 - In attrib.c::ntfs_attr_set() call balance_dirty_pages_ratelimited()
65 and cond_resched() in the main loop as we could be dirtying a lot of
66 pages and this ensures we play nice with the VM and the system as a
67 whole.
68 - Implement file operations ->write, ->aio_write, ->writev for regular
69 files. This replaces the old use of generic_file_write(), et al and
70 the address space operations ->prepare_write and ->commit_write.
71 This means that both sparse and non-sparse (unencrypted and
72 uncompressed) files can now be extended using the normal write(2)
73 code path. There are two limitations at present and these are that
74 we never create sparse files and that we only have limited support
75 for highly fragmented files, i.e. ones whose data attribute is split
76 across multiple extents. When such a case is encountered,
77 EOPNOTSUPP is returned.
78 - $EA attributes can be both resident and non-resident.
79 - Use %z for size_t to fix compilation warnings. (Andrew Morton)
80 - Fix compilation warnings with gcc-4.0.2 on SUSE 10.0.
81 - Document extended attribute ($EA) NEED_EA flag. (Based on libntfs
82 patch by Yura Pakhuchiy.)
83
252.1.24 - Lots of bug fixes and support more clean journal states. 842.1.24 - Lots of bug fixes and support more clean journal states.
26 85
27 - Support journals ($LogFile) which have been modified by chkdsk. This 86 - Support journals ($LogFile) which have been modified by chkdsk. This
diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile
index 894b2b876d35..d0d45d1c853a 100644
--- a/fs/ntfs/Makefile
+++ b/fs/ntfs/Makefile
@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \
6 index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \ 6 index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \
7 unistr.o upcase.o 7 unistr.o upcase.o
8 8
9EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.24\" 9EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.25\"
10 10
11ifeq ($(CONFIG_NTFS_DEBUG),y) 11ifeq ($(CONFIG_NTFS_DEBUG),y)
12EXTRA_CFLAGS += -DDEBUG 12EXTRA_CFLAGS += -DDEBUG
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index 5e80c07c6a4d..1c0a4315876a 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -1391,8 +1391,7 @@ retry_writepage:
1391 if (NInoEncrypted(ni)) { 1391 if (NInoEncrypted(ni)) {
1392 unlock_page(page); 1392 unlock_page(page);
1393 BUG_ON(ni->type != AT_DATA); 1393 BUG_ON(ni->type != AT_DATA);
1394 ntfs_debug("Denying write access to encrypted " 1394 ntfs_debug("Denying write access to encrypted file.");
1395 "file.");
1396 return -EACCES; 1395 return -EACCES;
1397 } 1396 }
1398 /* Compressed data streams are handled in compress.c. */ 1397 /* Compressed data streams are handled in compress.c. */
@@ -1508,8 +1507,8 @@ retry_writepage:
1508 /* Zero out of bounds area in the page cache page. */ 1507 /* Zero out of bounds area in the page cache page. */
1509 memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len); 1508 memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len);
1510 kunmap_atomic(kaddr, KM_USER0); 1509 kunmap_atomic(kaddr, KM_USER0);
1511 flush_dcache_mft_record_page(ctx->ntfs_ino);
1512 flush_dcache_page(page); 1510 flush_dcache_page(page);
1511 flush_dcache_mft_record_page(ctx->ntfs_ino);
1513 /* We are done with the page. */ 1512 /* We are done with the page. */
1514 end_page_writeback(page); 1513 end_page_writeback(page);
1515 /* Finally, mark the mft record dirty, so it gets written back. */ 1514 /* Finally, mark the mft record dirty, so it gets written back. */
@@ -1542,830 +1541,6 @@ err_out:
1542 return err; 1541 return err;
1543} 1542}
1544 1543
1545/**
1546 * ntfs_prepare_nonresident_write -
1547 *
1548 */
1549static int ntfs_prepare_nonresident_write(struct page *page,
1550 unsigned from, unsigned to)
1551{
1552 VCN vcn;
1553 LCN lcn;
1554 s64 initialized_size;
1555 loff_t i_size;
1556 sector_t block, ablock, iblock;
1557 struct inode *vi;
1558 ntfs_inode *ni;
1559 ntfs_volume *vol;
1560 runlist_element *rl;
1561 struct buffer_head *bh, *head, *wait[2], **wait_bh = wait;
1562 unsigned long flags;
1563 unsigned int vcn_ofs, block_start, block_end, blocksize;
1564 int err;
1565 BOOL is_retry;
1566 unsigned char blocksize_bits;
1567
1568 vi = page->mapping->host;
1569 ni = NTFS_I(vi);
1570 vol = ni->vol;
1571
1572 ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
1573 "0x%lx, from = %u, to = %u.", ni->mft_no, ni->type,
1574 page->index, from, to);
1575
1576 BUG_ON(!NInoNonResident(ni));
1577
1578 blocksize_bits = vi->i_blkbits;
1579 blocksize = 1 << blocksize_bits;
1580
1581 /*
1582 * create_empty_buffers() will create uptodate/dirty buffers if the
1583 * page is uptodate/dirty.
1584 */
1585 if (!page_has_buffers(page))
1586 create_empty_buffers(page, blocksize, 0);
1587 bh = head = page_buffers(page);
1588 if (unlikely(!bh))
1589 return -ENOMEM;
1590
1591 /* The first block in the page. */
1592 block = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);
1593
1594 read_lock_irqsave(&ni->size_lock, flags);
1595 /*
1596 * The first out of bounds block for the allocated size. No need to
1597 * round up as allocated_size is in multiples of cluster size and the
1598 * minimum cluster size is 512 bytes, which is equal to the smallest
1599 * blocksize.
1600 */
1601 ablock = ni->allocated_size >> blocksize_bits;
1602 i_size = i_size_read(vi);
1603 initialized_size = ni->initialized_size;
1604 read_unlock_irqrestore(&ni->size_lock, flags);
1605
1606 /* The last (fully or partially) initialized block. */
1607 iblock = initialized_size >> blocksize_bits;
1608
1609 /* Loop through all the buffers in the page. */
1610 block_start = 0;
1611 rl = NULL;
1612 err = 0;
1613 do {
1614 block_end = block_start + blocksize;
1615 /*
1616 * If buffer @bh is outside the write, just mark it uptodate
1617 * if the page is uptodate and continue with the next buffer.
1618 */
1619 if (block_end <= from || block_start >= to) {
1620 if (PageUptodate(page)) {
1621 if (!buffer_uptodate(bh))
1622 set_buffer_uptodate(bh);
1623 }
1624 continue;
1625 }
1626 /*
1627 * @bh is at least partially being written to.
1628 * Make sure it is not marked as new.
1629 */
1630 //if (buffer_new(bh))
1631 // clear_buffer_new(bh);
1632
1633 if (block >= ablock) {
1634 // TODO: block is above allocated_size, need to
1635 // allocate it. Best done in one go to accommodate not
1636 // only block but all above blocks up to and including:
1637 // ((page->index << PAGE_CACHE_SHIFT) + to + blocksize
1638 // - 1) >> blobksize_bits. Obviously will need to round
1639 // up to next cluster boundary, too. This should be
1640 // done with a helper function, so it can be reused.
1641 ntfs_error(vol->sb, "Writing beyond allocated size "
1642 "is not supported yet. Sorry.");
1643 err = -EOPNOTSUPP;
1644 goto err_out;
1645 // Need to update ablock.
1646 // Need to set_buffer_new() on all block bhs that are
1647 // newly allocated.
1648 }
1649 /*
1650 * Now we have enough allocated size to fulfill the whole
1651 * request, i.e. block < ablock is true.
1652 */
1653 if (unlikely((block >= iblock) &&
1654 (initialized_size < i_size))) {
1655 /*
1656 * If this page is fully outside initialized size, zero
1657 * out all pages between the current initialized size
1658 * and the current page. Just use ntfs_readpage() to do
1659 * the zeroing transparently.
1660 */
1661 if (block > iblock) {
1662 // TODO:
1663 // For each page do:
1664 // - read_cache_page()
1665 // Again for each page do:
1666 // - wait_on_page_locked()
1667 // - Check (PageUptodate(page) &&
1668 // !PageError(page))
1669 // Update initialized size in the attribute and
1670 // in the inode.
1671 // Again, for each page do:
1672 // __set_page_dirty_buffers();
1673 // page_cache_release()
1674 // We don't need to wait on the writes.
1675 // Update iblock.
1676 }
1677 /*
1678 * The current page straddles initialized size. Zero
1679 * all non-uptodate buffers and set them uptodate (and
1680 * dirty?). Note, there aren't any non-uptodate buffers
1681 * if the page is uptodate.
1682 * FIXME: For an uptodate page, the buffers may need to
1683 * be written out because they were not initialized on
1684 * disk before.
1685 */
1686 if (!PageUptodate(page)) {
1687 // TODO:
1688 // Zero any non-uptodate buffers up to i_size.
1689 // Set them uptodate and dirty.
1690 }
1691 // TODO:
1692 // Update initialized size in the attribute and in the
1693 // inode (up to i_size).
1694 // Update iblock.
1695 // FIXME: This is inefficient. Try to batch the two
1696 // size changes to happen in one go.
1697 ntfs_error(vol->sb, "Writing beyond initialized size "
1698 "is not supported yet. Sorry.");
1699 err = -EOPNOTSUPP;
1700 goto err_out;
1701 // Do NOT set_buffer_new() BUT DO clear buffer range
1702 // outside write request range.
1703 // set_buffer_uptodate() on complete buffers as well as
1704 // set_buffer_dirty().
1705 }
1706
1707 /* Need to map unmapped buffers. */
1708 if (!buffer_mapped(bh)) {
1709 /* Unmapped buffer. Need to map it. */
1710 bh->b_bdev = vol->sb->s_bdev;
1711
1712 /* Convert block into corresponding vcn and offset. */
1713 vcn = (VCN)block << blocksize_bits >>
1714 vol->cluster_size_bits;
1715 vcn_ofs = ((VCN)block << blocksize_bits) &
1716 vol->cluster_size_mask;
1717
1718 is_retry = FALSE;
1719 if (!rl) {
1720lock_retry_remap:
1721 down_read(&ni->runlist.lock);
1722 rl = ni->runlist.rl;
1723 }
1724 if (likely(rl != NULL)) {
1725 /* Seek to element containing target vcn. */
1726 while (rl->length && rl[1].vcn <= vcn)
1727 rl++;
1728 lcn = ntfs_rl_vcn_to_lcn(rl, vcn);
1729 } else
1730 lcn = LCN_RL_NOT_MAPPED;
1731 if (unlikely(lcn < 0)) {
1732 /*
1733 * We extended the attribute allocation above.
1734 * If we hit an ENOENT here it means that the
1735 * allocation was insufficient which is a bug.
1736 */
1737 BUG_ON(lcn == LCN_ENOENT);
1738
1739 /* It is a hole, need to instantiate it. */
1740 if (lcn == LCN_HOLE) {
1741 // TODO: Instantiate the hole.
1742 // clear_buffer_new(bh);
1743 // unmap_underlying_metadata(bh->b_bdev,
1744 // bh->b_blocknr);
1745 // For non-uptodate buffers, need to
1746 // zero out the region outside the
1747 // request in this bh or all bhs,
1748 // depending on what we implemented
1749 // above.
1750 // Need to flush_dcache_page().
1751 // Or could use set_buffer_new()
1752 // instead?
1753 ntfs_error(vol->sb, "Writing into "
1754 "sparse regions is "
1755 "not supported yet. "
1756 "Sorry.");
1757 err = -EOPNOTSUPP;
1758 if (!rl)
1759 up_read(&ni->runlist.lock);
1760 goto err_out;
1761 } else if (!is_retry &&
1762 lcn == LCN_RL_NOT_MAPPED) {
1763 is_retry = TRUE;
1764 /*
1765 * Attempt to map runlist, dropping
1766 * lock for the duration.
1767 */
1768 up_read(&ni->runlist.lock);
1769 err = ntfs_map_runlist(ni, vcn);
1770 if (likely(!err))
1771 goto lock_retry_remap;
1772 rl = NULL;
1773 } else if (!rl)
1774 up_read(&ni->runlist.lock);
1775 /*
1776 * Failed to map the buffer, even after
1777 * retrying.
1778 */
1779 if (!err)
1780 err = -EIO;
1781 bh->b_blocknr = -1;
1782 ntfs_error(vol->sb, "Failed to write to inode "
1783 "0x%lx, attribute type 0x%x, "
1784 "vcn 0x%llx, offset 0x%x "
1785 "because its location on disk "
1786 "could not be determined%s "
1787 "(error code %i).",
1788 ni->mft_no, ni->type,
1789 (unsigned long long)vcn,
1790 vcn_ofs, is_retry ? " even "
1791 "after retrying" : "", err);
1792 goto err_out;
1793 }
1794 /* We now have a successful remap, i.e. lcn >= 0. */
1795
1796 /* Setup buffer head to correct block. */
1797 bh->b_blocknr = ((lcn << vol->cluster_size_bits)
1798 + vcn_ofs) >> blocksize_bits;
1799 set_buffer_mapped(bh);
1800
1801 // FIXME: Something analogous to this is needed for
1802 // each newly allocated block, i.e. BH_New.
1803 // FIXME: Might need to take this out of the
1804 // if (!buffer_mapped(bh)) {}, depending on how we
1805 // implement things during the allocated_size and
1806 // initialized_size extension code above.
1807 if (buffer_new(bh)) {
1808 clear_buffer_new(bh);
1809 unmap_underlying_metadata(bh->b_bdev,
1810 bh->b_blocknr);
1811 if (PageUptodate(page)) {
1812 set_buffer_uptodate(bh);
1813 continue;
1814 }
1815 /*
1816 * Page is _not_ uptodate, zero surrounding
1817 * region. NOTE: This is how we decide if to
1818 * zero or not!
1819 */
1820 if (block_end > to || block_start < from) {
1821 void *kaddr;
1822
1823 kaddr = kmap_atomic(page, KM_USER0);
1824 if (block_end > to)
1825 memset(kaddr + to, 0,
1826 block_end - to);
1827 if (block_start < from)
1828 memset(kaddr + block_start, 0,
1829 from -
1830 block_start);
1831 flush_dcache_page(page);
1832 kunmap_atomic(kaddr, KM_USER0);
1833 }
1834 continue;
1835 }
1836 }
1837 /* @bh is mapped, set it uptodate if the page is uptodate. */
1838 if (PageUptodate(page)) {
1839 if (!buffer_uptodate(bh))
1840 set_buffer_uptodate(bh);
1841 continue;
1842 }
1843 /*
1844 * The page is not uptodate. The buffer is mapped. If it is not
1845 * uptodate, and it is only partially being written to, we need
1846 * to read the buffer in before the write, i.e. right now.
1847 */
1848 if (!buffer_uptodate(bh) &&
1849 (block_start < from || block_end > to)) {
1850 ll_rw_block(READ, 1, &bh);
1851 *wait_bh++ = bh;
1852 }
1853 } while (block++, block_start = block_end,
1854 (bh = bh->b_this_page) != head);
1855
1856 /* Release the lock if we took it. */
1857 if (rl) {
1858 up_read(&ni->runlist.lock);
1859 rl = NULL;
1860 }
1861
1862 /* If we issued read requests, let them complete. */
1863 while (wait_bh > wait) {
1864 wait_on_buffer(*--wait_bh);
1865 if (!buffer_uptodate(*wait_bh))
1866 return -EIO;
1867 }
1868
1869 ntfs_debug("Done.");
1870 return 0;
1871err_out:
1872 /*
1873 * Zero out any newly allocated blocks to avoid exposing stale data.
1874 * If BH_New is set, we know that the block was newly allocated in the
1875 * above loop.
1876 * FIXME: What about initialized_size increments? Have we done all the
1877 * required zeroing above? If not this error handling is broken, and
1878 * in particular the if (block_end <= from) check is completely bogus.
1879 */
1880 bh = head;
1881 block_start = 0;
1882 is_retry = FALSE;
1883 do {
1884 block_end = block_start + blocksize;
1885 if (block_end <= from)
1886 continue;
1887 if (block_start >= to)
1888 break;
1889 if (buffer_new(bh)) {
1890 void *kaddr;
1891
1892 clear_buffer_new(bh);
1893 kaddr = kmap_atomic(page, KM_USER0);
1894 memset(kaddr + block_start, 0, bh->b_size);
1895 kunmap_atomic(kaddr, KM_USER0);
1896 set_buffer_uptodate(bh);
1897 mark_buffer_dirty(bh);
1898 is_retry = TRUE;
1899 }
1900 } while (block_start = block_end, (bh = bh->b_this_page) != head);
1901 if (is_retry)
1902 flush_dcache_page(page);
1903 if (rl)
1904 up_read(&ni->runlist.lock);
1905 return err;
1906}
1907
1908/**
1909 * ntfs_prepare_write - prepare a page for receiving data
1910 *
1911 * This is called from generic_file_write() with i_sem held on the inode
1912 * (@page->mapping->host). The @page is locked but not kmap()ped. The source
1913 * data has not yet been copied into the @page.
1914 *
1915 * Need to extend the attribute/fill in holes if necessary, create blocks and
1916 * make partially overwritten blocks uptodate,
1917 *
1918 * i_size is not to be modified yet.
1919 *
1920 * Return 0 on success or -errno on error.
1921 *
1922 * Should be using block_prepare_write() [support for sparse files] or
1923 * cont_prepare_write() [no support for sparse files]. Cannot do that due to
1924 * ntfs specifics but can look at them for implementation guidance.
1925 *
1926 * Note: In the range, @from is inclusive and @to is exclusive, i.e. @from is
1927 * the first byte in the page that will be written to and @to is the first byte
1928 * after the last byte that will be written to.
1929 */
1930static int ntfs_prepare_write(struct file *file, struct page *page,
1931 unsigned from, unsigned to)
1932{
1933 s64 new_size;
1934 loff_t i_size;
1935 struct inode *vi = page->mapping->host;
1936 ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi);
1937 ntfs_volume *vol = ni->vol;
1938 ntfs_attr_search_ctx *ctx = NULL;
1939 MFT_RECORD *m = NULL;
1940 ATTR_RECORD *a;
1941 u8 *kaddr;
1942 u32 attr_len;
1943 int err;
1944
1945 ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
1946 "0x%lx, from = %u, to = %u.", vi->i_ino, ni->type,
1947 page->index, from, to);
1948 BUG_ON(!PageLocked(page));
1949 BUG_ON(from > PAGE_CACHE_SIZE);
1950 BUG_ON(to > PAGE_CACHE_SIZE);
1951 BUG_ON(from > to);
1952 BUG_ON(NInoMstProtected(ni));
1953 /*
1954 * If a previous ntfs_truncate() failed, repeat it and abort if it
1955 * fails again.
1956 */
1957 if (unlikely(NInoTruncateFailed(ni))) {
1958 down_write(&vi->i_alloc_sem);
1959 err = ntfs_truncate(vi);
1960 up_write(&vi->i_alloc_sem);
1961 if (err || NInoTruncateFailed(ni)) {
1962 if (!err)
1963 err = -EIO;
1964 goto err_out;
1965 }
1966 }
1967 /* If the attribute is not resident, deal with it elsewhere. */
1968 if (NInoNonResident(ni)) {
1969 /*
1970 * Only unnamed $DATA attributes can be compressed, encrypted,
1971 * and/or sparse.
1972 */
1973 if (ni->type == AT_DATA && !ni->name_len) {
1974 /* If file is encrypted, deny access, just like NT4. */
1975 if (NInoEncrypted(ni)) {
1976 ntfs_debug("Denying write access to encrypted "
1977 "file.");
1978 return -EACCES;
1979 }
1980 /* Compressed data streams are handled in compress.c. */
1981 if (NInoCompressed(ni)) {
1982 // TODO: Implement and replace this check with
1983 // return ntfs_write_compressed_block(page);
1984 ntfs_error(vi->i_sb, "Writing to compressed "
1985 "files is not supported yet. "
1986 "Sorry.");
1987 return -EOPNOTSUPP;
1988 }
1989 // TODO: Implement and remove this check.
1990 if (NInoSparse(ni)) {
1991 ntfs_error(vi->i_sb, "Writing to sparse files "
1992 "is not supported yet. Sorry.");
1993 return -EOPNOTSUPP;
1994 }
1995 }
1996 /* Normal data stream. */
1997 return ntfs_prepare_nonresident_write(page, from, to);
1998 }
1999 /*
2000 * Attribute is resident, implying it is not compressed, encrypted, or
2001 * sparse.
2002 */
2003 BUG_ON(page_has_buffers(page));
2004 new_size = ((s64)page->index << PAGE_CACHE_SHIFT) + to;
2005 /* If we do not need to resize the attribute allocation we are done. */
2006 if (new_size <= i_size_read(vi))
2007 goto done;
2008 /* Map, pin, and lock the (base) mft record. */
2009 if (!NInoAttr(ni))
2010 base_ni = ni;
2011 else
2012 base_ni = ni->ext.base_ntfs_ino;
2013 m = map_mft_record(base_ni);
2014 if (IS_ERR(m)) {
2015 err = PTR_ERR(m);
2016 m = NULL;
2017 ctx = NULL;
2018 goto err_out;
2019 }
2020 ctx = ntfs_attr_get_search_ctx(base_ni, m);
2021 if (unlikely(!ctx)) {
2022 err = -ENOMEM;
2023 goto err_out;
2024 }
2025 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
2026 CASE_SENSITIVE, 0, NULL, 0, ctx);
2027 if (unlikely(err)) {
2028 if (err == -ENOENT)
2029 err = -EIO;
2030 goto err_out;
2031 }
2032 m = ctx->mrec;
2033 a = ctx->attr;
2034 /* The total length of the attribute value. */
2035 attr_len = le32_to_cpu(a->data.resident.value_length);
2036 /* Fix an eventual previous failure of ntfs_commit_write(). */
2037 i_size = i_size_read(vi);
2038 if (unlikely(attr_len > i_size)) {
2039 attr_len = i_size;
2040 a->data.resident.value_length = cpu_to_le32(attr_len);
2041 }
2042 /* If we do not need to resize the attribute allocation we are done. */
2043 if (new_size <= attr_len)
2044 goto done_unm;
2045 /* Check if new size is allowed in $AttrDef. */
2046 err = ntfs_attr_size_bounds_check(vol, ni->type, new_size);
2047 if (unlikely(err)) {
2048 if (err == -ERANGE) {
2049 ntfs_error(vol->sb, "Write would cause the inode "
2050 "0x%lx to exceed the maximum size for "
2051 "its attribute type (0x%x). Aborting "
2052 "write.", vi->i_ino,
2053 le32_to_cpu(ni->type));
2054 } else {
2055 ntfs_error(vol->sb, "Inode 0x%lx has unknown "
2056 "attribute type 0x%x. Aborting "
2057 "write.", vi->i_ino,
2058 le32_to_cpu(ni->type));
2059 err = -EIO;
2060 }
2061 goto err_out2;
2062 }
2063 /*
2064 * Extend the attribute record to be able to store the new attribute
2065 * size.
2066 */
2067 if (new_size >= vol->mft_record_size || ntfs_attr_record_resize(m, a,
2068 le16_to_cpu(a->data.resident.value_offset) +
2069 new_size)) {
2070 /* Not enough space in the mft record. */
2071 ntfs_error(vol->sb, "Not enough space in the mft record for "
2072 "the resized attribute value. This is not "
2073 "supported yet. Aborting write.");
2074 err = -EOPNOTSUPP;
2075 goto err_out2;
2076 }
2077 /*
2078 * We have enough space in the mft record to fit the write. This
2079 * implies the attribute is smaller than the mft record and hence the
2080 * attribute must be in a single page and hence page->index must be 0.
2081 */
2082 BUG_ON(page->index);
2083 /*
2084 * If the beginning of the write is past the old size, enlarge the
2085 * attribute value up to the beginning of the write and fill it with
2086 * zeroes.
2087 */
2088 if (from > attr_len) {
2089 memset((u8*)a + le16_to_cpu(a->data.resident.value_offset) +
2090 attr_len, 0, from - attr_len);
2091 a->data.resident.value_length = cpu_to_le32(from);
2092 /* Zero the corresponding area in the page as well. */
2093 if (PageUptodate(page)) {
2094 kaddr = kmap_atomic(page, KM_USER0);
2095 memset(kaddr + attr_len, 0, from - attr_len);
2096 kunmap_atomic(kaddr, KM_USER0);
2097 flush_dcache_page(page);
2098 }
2099 }
2100 flush_dcache_mft_record_page(ctx->ntfs_ino);
2101 mark_mft_record_dirty(ctx->ntfs_ino);
2102done_unm:
2103 ntfs_attr_put_search_ctx(ctx);
2104 unmap_mft_record(base_ni);
2105 /*
2106 * Because resident attributes are handled by memcpy() to/from the
2107 * corresponding MFT record, and because this form of i/o is byte
2108 * aligned rather than block aligned, there is no need to bring the
2109 * page uptodate here as in the non-resident case where we need to
2110 * bring the buffers straddled by the write uptodate before
2111 * generic_file_write() does the copying from userspace.
2112 *
2113 * We thus defer the uptodate bringing of the page region outside the
2114 * region written to to ntfs_commit_write(), which makes the code
2115 * simpler and saves one atomic kmap which is good.
2116 */
2117done:
2118 ntfs_debug("Done.");
2119 return 0;
2120err_out:
2121 if (err == -ENOMEM)
2122 ntfs_warning(vi->i_sb, "Error allocating memory required to "
2123 "prepare the write.");
2124 else {
2125 ntfs_error(vi->i_sb, "Resident attribute prepare write failed "
2126 "with error %i.", err);
2127 NVolSetErrors(vol);
2128 make_bad_inode(vi);
2129 }
2130err_out2:
2131 if (ctx)
2132 ntfs_attr_put_search_ctx(ctx);
2133 if (m)
2134 unmap_mft_record(base_ni);
2135 return err;
2136}
2137
2138/**
2139 * ntfs_commit_nonresident_write -
2140 *
2141 */
2142static int ntfs_commit_nonresident_write(struct page *page,
2143 unsigned from, unsigned to)
2144{
2145 s64 pos = ((s64)page->index << PAGE_CACHE_SHIFT) + to;
2146 struct inode *vi = page->mapping->host;
2147 struct buffer_head *bh, *head;
2148 unsigned int block_start, block_end, blocksize;
2149 BOOL partial;
2150
2151 ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
2152 "0x%lx, from = %u, to = %u.", vi->i_ino,
2153 NTFS_I(vi)->type, page->index, from, to);
2154 blocksize = 1 << vi->i_blkbits;
2155
2156 // FIXME: We need a whole slew of special cases in here for compressed
2157 // files for example...
2158 // For now, we know ntfs_prepare_write() would have failed so we can't
2159 // get here in any of the cases which we have to special case, so we
2160 // are just a ripped off, unrolled generic_commit_write().
2161
2162 bh = head = page_buffers(page);
2163 block_start = 0;
2164 partial = FALSE;
2165 do {
2166 block_end = block_start + blocksize;
2167 if (block_end <= from || block_start >= to) {
2168 if (!buffer_uptodate(bh))
2169 partial = TRUE;
2170 } else {
2171 set_buffer_uptodate(bh);
2172 mark_buffer_dirty(bh);
2173 }
2174 } while (block_start = block_end, (bh = bh->b_this_page) != head);
2175 /*
2176 * If this is a partial write which happened to make all buffers
2177 * uptodate then we can optimize away a bogus ->readpage() for the next
2178 * read(). Here we 'discover' whether the page went uptodate as a
2179 * result of this (potentially partial) write.
2180 */
2181 if (!partial)
2182 SetPageUptodate(page);
2183 /*
2184 * Not convinced about this at all. See disparity comment above. For
2185 * now we know ntfs_prepare_write() would have failed in the write
2186 * exceeds i_size case, so this will never trigger which is fine.
2187 */
2188 if (pos > i_size_read(vi)) {
2189 ntfs_error(vi->i_sb, "Writing beyond the existing file size is "
2190 "not supported yet. Sorry.");
2191 return -EOPNOTSUPP;
2192 // vi->i_size = pos;
2193 // mark_inode_dirty(vi);
2194 }
2195 ntfs_debug("Done.");
2196 return 0;
2197}
2198
2199/**
2200 * ntfs_commit_write - commit the received data
2201 *
2202 * This is called from generic_file_write() with i_sem held on the inode
2203 * (@page->mapping->host). The @page is locked but not kmap()ped. The source
2204 * data has already been copied into the @page. ntfs_prepare_write() has been
2205 * called before the data copied and it returned success so we can take the
2206 * results of various BUG checks and some error handling for granted.
2207 *
2208 * Need to mark modified blocks dirty so they get written out later when
2209 * ntfs_writepage() is invoked by the VM.
2210 *
2211 * Return 0 on success or -errno on error.
2212 *
2213 * Should be using generic_commit_write(). This marks buffers uptodate and
2214 * dirty, sets the page uptodate if all buffers in the page are uptodate, and
2215 * updates i_size if the end of io is beyond i_size. In that case, it also
2216 * marks the inode dirty.
2217 *
2218 * Cannot use generic_commit_write() due to ntfs specialities but can look at
2219 * it for implementation guidance.
2220 *
2221 * If things have gone as outlined in ntfs_prepare_write(), then we do not
2222 * need to do any page content modifications here at all, except in the write
2223 * to resident attribute case, where we need to do the uptodate bringing here
2224 * which we combine with the copying into the mft record which means we save
2225 * one atomic kmap.
2226 */
2227static int ntfs_commit_write(struct file *file, struct page *page,
2228 unsigned from, unsigned to)
2229{
2230 struct inode *vi = page->mapping->host;
2231 ntfs_inode *base_ni, *ni = NTFS_I(vi);
2232 char *kaddr, *kattr;
2233 ntfs_attr_search_ctx *ctx;
2234 MFT_RECORD *m;
2235 ATTR_RECORD *a;
2236 u32 attr_len;
2237 int err;
2238
2239 ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "
2240 "0x%lx, from = %u, to = %u.", vi->i_ino, ni->type,
2241 page->index, from, to);
2242 /* If the attribute is not resident, deal with it elsewhere. */
2243 if (NInoNonResident(ni)) {
2244 /* Only unnamed $DATA attributes can be compressed/encrypted. */
2245 if (ni->type == AT_DATA && !ni->name_len) {
2246 /* Encrypted files need separate handling. */
2247 if (NInoEncrypted(ni)) {
2248 // We never get here at present!
2249 BUG();
2250 }
2251 /* Compressed data streams are handled in compress.c. */
2252 if (NInoCompressed(ni)) {
2253 // TODO: Implement this!
2254 // return ntfs_write_compressed_block(page);
2255 // We never get here at present!
2256 BUG();
2257 }
2258 }
2259 /* Normal data stream. */
2260 return ntfs_commit_nonresident_write(page, from, to);
2261 }
2262 /*
2263 * Attribute is resident, implying it is not compressed, encrypted, or
2264 * sparse.
2265 */
2266 if (!NInoAttr(ni))
2267 base_ni = ni;
2268 else
2269 base_ni = ni->ext.base_ntfs_ino;
2270 /* Map, pin, and lock the mft record. */
2271 m = map_mft_record(base_ni);
2272 if (IS_ERR(m)) {
2273 err = PTR_ERR(m);
2274 m = NULL;
2275 ctx = NULL;
2276 goto err_out;
2277 }
2278 ctx = ntfs_attr_get_search_ctx(base_ni, m);
2279 if (unlikely(!ctx)) {
2280 err = -ENOMEM;
2281 goto err_out;
2282 }
2283 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
2284 CASE_SENSITIVE, 0, NULL, 0, ctx);
2285 if (unlikely(err)) {
2286 if (err == -ENOENT)
2287 err = -EIO;
2288 goto err_out;
2289 }
2290 a = ctx->attr;
2291 /* The total length of the attribute value. */
2292 attr_len = le32_to_cpu(a->data.resident.value_length);
2293 BUG_ON(from > attr_len);
2294 kattr = (u8*)a + le16_to_cpu(a->data.resident.value_offset);
2295 kaddr = kmap_atomic(page, KM_USER0);
2296 /* Copy the received data from the page to the mft record. */
2297 memcpy(kattr + from, kaddr + from, to - from);
2298 /* Update the attribute length if necessary. */
2299 if (to > attr_len) {
2300 attr_len = to;
2301 a->data.resident.value_length = cpu_to_le32(attr_len);
2302 }
2303 /*
2304 * If the page is not uptodate, bring the out of bounds area(s)
2305 * uptodate by copying data from the mft record to the page.
2306 */
2307 if (!PageUptodate(page)) {
2308 if (from > 0)
2309 memcpy(kaddr, kattr, from);
2310 if (to < attr_len)
2311 memcpy(kaddr + to, kattr + to, attr_len - to);
2312 /* Zero the region outside the end of the attribute value. */
2313 if (attr_len < PAGE_CACHE_SIZE)
2314 memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len);
2315 /*
2316 * The probability of not having done any of the above is
2317 * extremely small, so we just flush unconditionally.
2318 */
2319 flush_dcache_page(page);
2320 SetPageUptodate(page);
2321 }
2322 kunmap_atomic(kaddr, KM_USER0);
2323 /* Update i_size if necessary. */
2324 if (i_size_read(vi) < attr_len) {
2325 unsigned long flags;
2326
2327 write_lock_irqsave(&ni->size_lock, flags);
2328 ni->allocated_size = ni->initialized_size = attr_len;
2329 i_size_write(vi, attr_len);
2330 write_unlock_irqrestore(&ni->size_lock, flags);
2331 }
2332 /* Mark the mft record dirty, so it gets written back. */
2333 flush_dcache_mft_record_page(ctx->ntfs_ino);
2334 mark_mft_record_dirty(ctx->ntfs_ino);
2335 ntfs_attr_put_search_ctx(ctx);
2336 unmap_mft_record(base_ni);
2337 ntfs_debug("Done.");
2338 return 0;
2339err_out:
2340 if (err == -ENOMEM) {
2341 ntfs_warning(vi->i_sb, "Error allocating memory required to "
2342 "commit the write.");
2343 if (PageUptodate(page)) {
2344 ntfs_warning(vi->i_sb, "Page is uptodate, setting "
2345 "dirty so the write will be retried "
2346 "later on by the VM.");
2347 /*
2348 * Put the page on mapping->dirty_pages, but leave its
2349 * buffers' dirty state as-is.
2350 */
2351 __set_page_dirty_nobuffers(page);
2352 err = 0;
2353 } else
2354 ntfs_error(vi->i_sb, "Page is not uptodate. Written "
2355 "data has been lost.");
2356 } else {
2357 ntfs_error(vi->i_sb, "Resident attribute commit write failed "
2358 "with error %i.", err);
2359 NVolSetErrors(ni->vol);
2360 make_bad_inode(vi);
2361 }
2362 if (ctx)
2363 ntfs_attr_put_search_ctx(ctx);
2364 if (m)
2365 unmap_mft_record(base_ni);
2366 return err;
2367}
2368
2369#endif /* NTFS_RW */ 1544#endif /* NTFS_RW */
2370 1545
2371/** 1546/**
@@ -2377,9 +1552,6 @@ struct address_space_operations ntfs_aops = {
2377 disk request queue. */ 1552 disk request queue. */
2378#ifdef NTFS_RW 1553#ifdef NTFS_RW
2379 .writepage = ntfs_writepage, /* Write dirty page to disk. */ 1554 .writepage = ntfs_writepage, /* Write dirty page to disk. */
2380 .prepare_write = ntfs_prepare_write, /* Prepare page and buffers
2381 ready to receive data. */
2382 .commit_write = ntfs_commit_write, /* Commit received data. */
2383#endif /* NTFS_RW */ 1555#endif /* NTFS_RW */
2384}; 1556};
2385 1557
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 3f9a4ff42ee5..eda056bac256 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -21,7 +21,9 @@
21 */ 21 */
22 22
23#include <linux/buffer_head.h> 23#include <linux/buffer_head.h>
24#include <linux/sched.h>
24#include <linux/swap.h> 25#include <linux/swap.h>
26#include <linux/writeback.h>
25 27
26#include "attrib.h" 28#include "attrib.h"
27#include "debug.h" 29#include "debug.h"
@@ -36,9 +38,27 @@
36 * ntfs_map_runlist_nolock - map (a part of) a runlist of an ntfs inode 38 * ntfs_map_runlist_nolock - map (a part of) a runlist of an ntfs inode
37 * @ni: ntfs inode for which to map (part of) a runlist 39 * @ni: ntfs inode for which to map (part of) a runlist
38 * @vcn: map runlist part containing this vcn 40 * @vcn: map runlist part containing this vcn
41 * @ctx: active attribute search context if present or NULL if not
39 * 42 *
40 * Map the part of a runlist containing the @vcn of the ntfs inode @ni. 43 * Map the part of a runlist containing the @vcn of the ntfs inode @ni.
41 * 44 *
45 * If @ctx is specified, it is an active search context of @ni and its base mft
46 * record. This is needed when ntfs_map_runlist_nolock() encounters unmapped
47 * runlist fragments and allows their mapping. If you do not have the mft
48 * record mapped, you can specify @ctx as NULL and ntfs_map_runlist_nolock()
49 * will perform the necessary mapping and unmapping.
50 *
51 * Note, ntfs_map_runlist_nolock() saves the state of @ctx on entry and
52 * restores it before returning. Thus, @ctx will be left pointing to the same
53 * attribute on return as on entry. However, the actual pointers in @ctx may
54 * point to different memory locations on return, so you must remember to reset
55 * any cached pointers from the @ctx, i.e. after the call to
56 * ntfs_map_runlist_nolock(), you will probably want to do:
57 * m = ctx->mrec;
58 * a = ctx->attr;
59 * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
60 * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
61 *
42 * Return 0 on success and -errno on error. There is one special error code 62 * Return 0 on success and -errno on error. There is one special error code
43 * which is not an error as such. This is -ENOENT. It means that @vcn is out 63 * which is not an error as such. This is -ENOENT. It means that @vcn is out
44 * of bounds of the runlist. 64 * of bounds of the runlist.
@@ -46,19 +66,32 @@
46 * Note the runlist can be NULL after this function returns if @vcn is zero and 66 * Note the runlist can be NULL after this function returns if @vcn is zero and
47 * the attribute has zero allocated size, i.e. there simply is no runlist. 67 * the attribute has zero allocated size, i.e. there simply is no runlist.
48 * 68 *
49 * Locking: - The runlist must be locked for writing. 69 * WARNING: If @ctx is supplied, regardless of whether success or failure is
50 * - This function modifies the runlist. 70 * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
71 * is no longer valid, i.e. you need to either call
72 * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
73 * In that case PTR_ERR(@ctx->mrec) will give you the error code for
74 * why the mapping of the old inode failed.
75 *
76 * Locking: - The runlist described by @ni must be locked for writing on entry
77 * and is locked on return. Note the runlist will be modified.
78 * - If @ctx is NULL, the base mft record of @ni must not be mapped on
79 * entry and it will be left unmapped on return.
80 * - If @ctx is not NULL, the base mft record must be mapped on entry
81 * and it will be left mapped on return.
51 */ 82 */
52int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn) 83int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx)
53{ 84{
54 VCN end_vcn; 85 VCN end_vcn;
86 unsigned long flags;
55 ntfs_inode *base_ni; 87 ntfs_inode *base_ni;
56 MFT_RECORD *m; 88 MFT_RECORD *m;
57 ATTR_RECORD *a; 89 ATTR_RECORD *a;
58 ntfs_attr_search_ctx *ctx;
59 runlist_element *rl; 90 runlist_element *rl;
60 unsigned long flags; 91 struct page *put_this_page = NULL;
61 int err = 0; 92 int err = 0;
93 BOOL ctx_is_temporary, ctx_needs_reset;
94 ntfs_attr_search_ctx old_ctx = { NULL, };
62 95
63 ntfs_debug("Mapping runlist part containing vcn 0x%llx.", 96 ntfs_debug("Mapping runlist part containing vcn 0x%llx.",
64 (unsigned long long)vcn); 97 (unsigned long long)vcn);
@@ -66,20 +99,77 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
66 base_ni = ni; 99 base_ni = ni;
67 else 100 else
68 base_ni = ni->ext.base_ntfs_ino; 101 base_ni = ni->ext.base_ntfs_ino;
69 m = map_mft_record(base_ni); 102 if (!ctx) {
70 if (IS_ERR(m)) 103 ctx_is_temporary = ctx_needs_reset = TRUE;
71 return PTR_ERR(m); 104 m = map_mft_record(base_ni);
72 ctx = ntfs_attr_get_search_ctx(base_ni, m); 105 if (IS_ERR(m))
73 if (unlikely(!ctx)) { 106 return PTR_ERR(m);
74 err = -ENOMEM; 107 ctx = ntfs_attr_get_search_ctx(base_ni, m);
75 goto err_out; 108 if (unlikely(!ctx)) {
109 err = -ENOMEM;
110 goto err_out;
111 }
112 } else {
113 VCN allocated_size_vcn;
114
115 BUG_ON(IS_ERR(ctx->mrec));
116 a = ctx->attr;
117 BUG_ON(!a->non_resident);
118 ctx_is_temporary = FALSE;
119 end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn);
120 read_lock_irqsave(&ni->size_lock, flags);
121 allocated_size_vcn = ni->allocated_size >>
122 ni->vol->cluster_size_bits;
123 read_unlock_irqrestore(&ni->size_lock, flags);
124 if (!a->data.non_resident.lowest_vcn && end_vcn <= 0)
125 end_vcn = allocated_size_vcn - 1;
126 /*
127 * If we already have the attribute extent containing @vcn in
128 * @ctx, no need to look it up again. We slightly cheat in
129 * that if vcn exceeds the allocated size, we will refuse to
130 * map the runlist below, so there is definitely no need to get
131 * the right attribute extent.
132 */
133 if (vcn >= allocated_size_vcn || (a->type == ni->type &&
134 a->name_length == ni->name_len &&
135 !memcmp((u8*)a + le16_to_cpu(a->name_offset),
136 ni->name, ni->name_len) &&
137 sle64_to_cpu(a->data.non_resident.lowest_vcn)
138 <= vcn && end_vcn >= vcn))
139 ctx_needs_reset = FALSE;
140 else {
141 /* Save the old search context. */
142 old_ctx = *ctx;
143 /*
144 * If the currently mapped (extent) inode is not the
145 * base inode we will unmap it when we reinitialize the
146 * search context which means we need to get a
147 * reference to the page containing the mapped mft
148 * record so we do not accidentally drop changes to the
149 * mft record when it has not been marked dirty yet.
150 */
151 if (old_ctx.base_ntfs_ino && old_ctx.ntfs_ino !=
152 old_ctx.base_ntfs_ino) {
153 put_this_page = old_ctx.ntfs_ino->page;
154 page_cache_get(put_this_page);
155 }
156 /*
157 * Reinitialize the search context so we can lookup the
158 * needed attribute extent.
159 */
160 ntfs_attr_reinit_search_ctx(ctx);
161 ctx_needs_reset = TRUE;
162 }
76 } 163 }
77 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, 164 if (ctx_needs_reset) {
78 CASE_SENSITIVE, vcn, NULL, 0, ctx); 165 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
79 if (unlikely(err)) { 166 CASE_SENSITIVE, vcn, NULL, 0, ctx);
80 if (err == -ENOENT) 167 if (unlikely(err)) {
81 err = -EIO; 168 if (err == -ENOENT)
82 goto err_out; 169 err = -EIO;
170 goto err_out;
171 }
172 BUG_ON(!ctx->attr->non_resident);
83 } 173 }
84 a = ctx->attr; 174 a = ctx->attr;
85 /* 175 /*
@@ -89,11 +179,9 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
89 * ntfs_mapping_pairs_decompress() fails. 179 * ntfs_mapping_pairs_decompress() fails.
90 */ 180 */
91 end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1; 181 end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1;
92 if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1)) { 182 if (!a->data.non_resident.lowest_vcn && end_vcn == 1)
93 read_lock_irqsave(&ni->size_lock, flags); 183 end_vcn = sle64_to_cpu(a->data.non_resident.allocated_size) >>
94 end_vcn = ni->allocated_size >> ni->vol->cluster_size_bits; 184 ni->vol->cluster_size_bits;
95 read_unlock_irqrestore(&ni->size_lock, flags);
96 }
97 if (unlikely(vcn >= end_vcn)) { 185 if (unlikely(vcn >= end_vcn)) {
98 err = -ENOENT; 186 err = -ENOENT;
99 goto err_out; 187 goto err_out;
@@ -104,9 +192,93 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)
104 else 192 else
105 ni->runlist.rl = rl; 193 ni->runlist.rl = rl;
106err_out: 194err_out:
107 if (likely(ctx)) 195 if (ctx_is_temporary) {
108 ntfs_attr_put_search_ctx(ctx); 196 if (likely(ctx))
109 unmap_mft_record(base_ni); 197 ntfs_attr_put_search_ctx(ctx);
198 unmap_mft_record(base_ni);
199 } else if (ctx_needs_reset) {
200 /*
201 * If there is no attribute list, restoring the search context
202 * is acomplished simply by copying the saved context back over
203 * the caller supplied context. If there is an attribute list,
204 * things are more complicated as we need to deal with mapping
205 * of mft records and resulting potential changes in pointers.
206 */
207 if (NInoAttrList(base_ni)) {
208 /*
209 * If the currently mapped (extent) inode is not the
210 * one we had before, we need to unmap it and map the
211 * old one.
212 */
213 if (ctx->ntfs_ino != old_ctx.ntfs_ino) {
214 /*
215 * If the currently mapped inode is not the
216 * base inode, unmap it.
217 */
218 if (ctx->base_ntfs_ino && ctx->ntfs_ino !=
219 ctx->base_ntfs_ino) {
220 unmap_extent_mft_record(ctx->ntfs_ino);
221 ctx->mrec = ctx->base_mrec;
222 BUG_ON(!ctx->mrec);
223 }
224 /*
225 * If the old mapped inode is not the base
226 * inode, map it.
227 */
228 if (old_ctx.base_ntfs_ino &&
229 old_ctx.ntfs_ino !=
230 old_ctx.base_ntfs_ino) {
231retry_map:
232 ctx->mrec = map_mft_record(
233 old_ctx.ntfs_ino);
234 /*
235 * Something bad has happened. If out
236 * of memory retry till it succeeds.
237 * Any other errors are fatal and we
238 * return the error code in ctx->mrec.
239 * Let the caller deal with it... We
240 * just need to fudge things so the
241 * caller can reinit and/or put the
242 * search context safely.
243 */
244 if (IS_ERR(ctx->mrec)) {
245 if (PTR_ERR(ctx->mrec) ==
246 -ENOMEM) {
247 schedule();
248 goto retry_map;
249 } else
250 old_ctx.ntfs_ino =
251 old_ctx.
252 base_ntfs_ino;
253 }
254 }
255 }
256 /* Update the changed pointers in the saved context. */
257 if (ctx->mrec != old_ctx.mrec) {
258 if (!IS_ERR(ctx->mrec))
259 old_ctx.attr = (ATTR_RECORD*)(
260 (u8*)ctx->mrec +
261 ((u8*)old_ctx.attr -
262 (u8*)old_ctx.mrec));
263 old_ctx.mrec = ctx->mrec;
264 }
265 }
266 /* Restore the search context to the saved one. */
267 *ctx = old_ctx;
268 /*
269 * We drop the reference on the page we took earlier. In the
270 * case that IS_ERR(ctx->mrec) is true this means we might lose
271 * some changes to the mft record that had been made between
272 * the last time it was marked dirty/written out and now. This
273 * at this stage is not a problem as the mapping error is fatal
274 * enough that the mft record cannot be written out anyway and
275 * the caller is very likely to shutdown the whole inode
276 * immediately and mark the volume dirty for chkdsk to pick up
277 * the pieces anyway.
278 */
279 if (put_this_page)
280 page_cache_release(put_this_page);
281 }
110 return err; 282 return err;
111} 283}
112 284
@@ -122,8 +294,8 @@ err_out:
122 * of bounds of the runlist. 294 * of bounds of the runlist.
123 * 295 *
124 * Locking: - The runlist must be unlocked on entry and is unlocked on return. 296 * Locking: - The runlist must be unlocked on entry and is unlocked on return.
125 * - This function takes the runlist lock for writing and modifies the 297 * - This function takes the runlist lock for writing and may modify
126 * runlist. 298 * the runlist.
127 */ 299 */
128int ntfs_map_runlist(ntfs_inode *ni, VCN vcn) 300int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)
129{ 301{
@@ -133,7 +305,7 @@ int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)
133 /* Make sure someone else didn't do the work while we were sleeping. */ 305 /* Make sure someone else didn't do the work while we were sleeping. */
134 if (likely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) <= 306 if (likely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) <=
135 LCN_RL_NOT_MAPPED)) 307 LCN_RL_NOT_MAPPED))
136 err = ntfs_map_runlist_nolock(ni, vcn); 308 err = ntfs_map_runlist_nolock(ni, vcn, NULL);
137 up_write(&ni->runlist.lock); 309 up_write(&ni->runlist.lock);
138 return err; 310 return err;
139} 311}
@@ -212,7 +384,7 @@ retry_remap:
212 goto retry_remap; 384 goto retry_remap;
213 } 385 }
214 } 386 }
215 err = ntfs_map_runlist_nolock(ni, vcn); 387 err = ntfs_map_runlist_nolock(ni, vcn, NULL);
216 if (!write_locked) { 388 if (!write_locked) {
217 up_write(&ni->runlist.lock); 389 up_write(&ni->runlist.lock);
218 down_read(&ni->runlist.lock); 390 down_read(&ni->runlist.lock);
@@ -236,9 +408,9 @@ retry_remap:
236 408
237/** 409/**
238 * ntfs_attr_find_vcn_nolock - find a vcn in the runlist of an ntfs inode 410 * ntfs_attr_find_vcn_nolock - find a vcn in the runlist of an ntfs inode
239 * @ni: ntfs inode describing the runlist to search 411 * @ni: ntfs inode describing the runlist to search
240 * @vcn: vcn to find 412 * @vcn: vcn to find
241 * @write_locked: true if the runlist is locked for writing 413 * @ctx: active attribute search context if present or NULL if not
242 * 414 *
243 * Find the virtual cluster number @vcn in the runlist described by the ntfs 415 * Find the virtual cluster number @vcn in the runlist described by the ntfs
244 * inode @ni and return the address of the runlist element containing the @vcn. 416 * inode @ni and return the address of the runlist element containing the @vcn.
@@ -246,9 +418,22 @@ retry_remap:
246 * If the @vcn is not mapped yet, the attempt is made to map the attribute 418 * If the @vcn is not mapped yet, the attempt is made to map the attribute
247 * extent containing the @vcn and the vcn to lcn conversion is retried. 419 * extent containing the @vcn and the vcn to lcn conversion is retried.
248 * 420 *
249 * If @write_locked is true the caller has locked the runlist for writing and 421 * If @ctx is specified, it is an active search context of @ni and its base mft
250 * if false for reading. 422 * record. This is needed when ntfs_attr_find_vcn_nolock() encounters unmapped
251 * 423 * runlist fragments and allows their mapping. If you do not have the mft
424 * record mapped, you can specify @ctx as NULL and ntfs_attr_find_vcn_nolock()
425 * will perform the necessary mapping and unmapping.
426 *
427 * Note, ntfs_attr_find_vcn_nolock() saves the state of @ctx on entry and
428 * restores it before returning. Thus, @ctx will be left pointing to the same
429 * attribute on return as on entry. However, the actual pointers in @ctx may
430 * point to different memory locations on return, so you must remember to reset
431 * any cached pointers from the @ctx, i.e. after the call to
432 * ntfs_attr_find_vcn_nolock(), you will probably want to do:
433 * m = ctx->mrec;
434 * a = ctx->attr;
435 * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
436 * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
252 * Note you need to distinguish between the lcn of the returned runlist element 437 * Note you need to distinguish between the lcn of the returned runlist element
253 * being >= 0 and LCN_HOLE. In the later case you have to return zeroes on 438 * being >= 0 and LCN_HOLE. In the later case you have to return zeroes on
254 * read and allocate clusters on write. 439 * read and allocate clusters on write.
@@ -263,22 +448,31 @@ retry_remap:
263 * -ENOMEM - Not enough memory to map runlist. 448 * -ENOMEM - Not enough memory to map runlist.
264 * -EIO - Critical error (runlist/file is corrupt, i/o error, etc). 449 * -EIO - Critical error (runlist/file is corrupt, i/o error, etc).
265 * 450 *
266 * Locking: - The runlist must be locked on entry and is left locked on return. 451 * WARNING: If @ctx is supplied, regardless of whether success or failure is
267 * - If @write_locked is FALSE, i.e. the runlist is locked for reading, 452 * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
268 * the lock may be dropped inside the function so you cannot rely on 453 * is no longer valid, i.e. you need to either call
269 * the runlist still being the same when this function returns. 454 * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
455 * In that case PTR_ERR(@ctx->mrec) will give you the error code for
456 * why the mapping of the old inode failed.
457 *
458 * Locking: - The runlist described by @ni must be locked for writing on entry
459 * and is locked on return. Note the runlist may be modified when
460 * needed runlist fragments need to be mapped.
461 * - If @ctx is NULL, the base mft record of @ni must not be mapped on
462 * entry and it will be left unmapped on return.
463 * - If @ctx is not NULL, the base mft record must be mapped on entry
464 * and it will be left mapped on return.
270 */ 465 */
271runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn, 466runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
272 const BOOL write_locked) 467 ntfs_attr_search_ctx *ctx)
273{ 468{
274 unsigned long flags; 469 unsigned long flags;
275 runlist_element *rl; 470 runlist_element *rl;
276 int err = 0; 471 int err = 0;
277 BOOL is_retry = FALSE; 472 BOOL is_retry = FALSE;
278 473
279 ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.", 474 ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, with%s ctx.",
280 ni->mft_no, (unsigned long long)vcn, 475 ni->mft_no, (unsigned long long)vcn, ctx ? "" : "out");
281 write_locked ? "write" : "read");
282 BUG_ON(!ni); 476 BUG_ON(!ni);
283 BUG_ON(!NInoNonResident(ni)); 477 BUG_ON(!NInoNonResident(ni));
284 BUG_ON(vcn < 0); 478 BUG_ON(vcn < 0);
@@ -312,33 +506,22 @@ retry_remap:
312 } 506 }
313 if (!err && !is_retry) { 507 if (!err && !is_retry) {
314 /* 508 /*
315 * The @vcn is in an unmapped region, map the runlist and 509 * If the search context is invalid we cannot map the unmapped
316 * retry. 510 * region.
317 */ 511 */
318 if (!write_locked) { 512 if (IS_ERR(ctx->mrec))
319 up_read(&ni->runlist.lock); 513 err = PTR_ERR(ctx->mrec);
320 down_write(&ni->runlist.lock); 514 else {
321 if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) != 515 /*
322 LCN_RL_NOT_MAPPED)) { 516 * The @vcn is in an unmapped region, map the runlist
323 up_write(&ni->runlist.lock); 517 * and retry.
324 down_read(&ni->runlist.lock); 518 */
519 err = ntfs_map_runlist_nolock(ni, vcn, ctx);
520 if (likely(!err)) {
521 is_retry = TRUE;
325 goto retry_remap; 522 goto retry_remap;
326 } 523 }
327 } 524 }
328 err = ntfs_map_runlist_nolock(ni, vcn);
329 if (!write_locked) {
330 up_write(&ni->runlist.lock);
331 down_read(&ni->runlist.lock);
332 }
333 if (likely(!err)) {
334 is_retry = TRUE;
335 goto retry_remap;
336 }
337 /*
338 * -EINVAL coming from a failed mapping attempt is equivalent
339 * to i/o error for us as it should not happen in our code
340 * paths.
341 */
342 if (err == -EINVAL) 525 if (err == -EINVAL)
343 err = -EIO; 526 err = -EIO;
344 } else if (!err) 527 } else if (!err)
@@ -1011,6 +1194,7 @@ int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name,
1011 ntfs_inode *base_ni; 1194 ntfs_inode *base_ni;
1012 1195
1013 ntfs_debug("Entering."); 1196 ntfs_debug("Entering.");
1197 BUG_ON(IS_ERR(ctx->mrec));
1014 if (ctx->base_ntfs_ino) 1198 if (ctx->base_ntfs_ino)
1015 base_ni = ctx->base_ntfs_ino; 1199 base_ni = ctx->base_ntfs_ino;
1016 else 1200 else
@@ -1227,7 +1411,7 @@ int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPE type)
1227 */ 1411 */
1228int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type) 1412int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type)
1229{ 1413{
1230 if (type == AT_INDEX_ALLOCATION || type == AT_EA) 1414 if (type == AT_INDEX_ALLOCATION)
1231 return -EPERM; 1415 return -EPERM;
1232 return 0; 1416 return 0;
1233} 1417}
@@ -1319,10 +1503,17 @@ int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
1319/** 1503/**
1320 * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute 1504 * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
1321 * @ni: ntfs inode describing the attribute to convert 1505 * @ni: ntfs inode describing the attribute to convert
1506 * @data_size: size of the resident data to copy to the non-resident attribute
1322 * 1507 *
1323 * Convert the resident ntfs attribute described by the ntfs inode @ni to a 1508 * Convert the resident ntfs attribute described by the ntfs inode @ni to a
1324 * non-resident one. 1509 * non-resident one.
1325 * 1510 *
1511 * @data_size must be equal to the attribute value size. This is needed since
1512 * we need to know the size before we can map the mft record and our callers
1513 * always know it. The reason we cannot simply read the size from the vfs
1514 * inode i_size is that this is not necessarily uptodate. This happens when
1515 * ntfs_attr_make_non_resident() is called in the ->truncate call path(s).
1516 *
1326 * Return 0 on success and -errno on error. The following error return codes 1517 * Return 0 on success and -errno on error. The following error return codes
1327 * are defined: 1518 * are defined:
1328 * -EPERM - The attribute is not allowed to be non-resident. 1519 * -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,
1343 * 1534 *
1344 * Locking: - The caller must hold i_sem on the inode. 1535 * Locking: - The caller must hold i_sem on the inode.
1345 */ 1536 */
1346int ntfs_attr_make_non_resident(ntfs_inode *ni) 1537int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size)
1347{ 1538{
1348 s64 new_size; 1539 s64 new_size;
1349 struct inode *vi = VFS_I(ni); 1540 struct inode *vi = VFS_I(ni);
@@ -1381,11 +1572,9 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1381 * The size needs to be aligned to a cluster boundary for allocation 1572 * The size needs to be aligned to a cluster boundary for allocation
1382 * purposes. 1573 * purposes.
1383 */ 1574 */
1384 new_size = (i_size_read(vi) + vol->cluster_size - 1) & 1575 new_size = (data_size + vol->cluster_size - 1) &
1385 ~(vol->cluster_size - 1); 1576 ~(vol->cluster_size - 1);
1386 if (new_size > 0) { 1577 if (new_size > 0) {
1387 runlist_element *rl2;
1388
1389 /* 1578 /*
1390 * Will need the page later and since the page lock nests 1579 * Will need the page later and since the page lock nests
1391 * outside all ntfs locks, we need to get the page now. 1580 * outside all ntfs locks, we need to get the page now.
@@ -1396,7 +1585,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1396 return -ENOMEM; 1585 return -ENOMEM;
1397 /* Start by allocating clusters to hold the attribute value. */ 1586 /* Start by allocating clusters to hold the attribute value. */
1398 rl = ntfs_cluster_alloc(vol, 0, new_size >> 1587 rl = ntfs_cluster_alloc(vol, 0, new_size >>
1399 vol->cluster_size_bits, -1, DATA_ZONE); 1588 vol->cluster_size_bits, -1, DATA_ZONE, TRUE);
1400 if (IS_ERR(rl)) { 1589 if (IS_ERR(rl)) {
1401 err = PTR_ERR(rl); 1590 err = PTR_ERR(rl);
1402 ntfs_debug("Failed to allocate cluster%s, error code " 1591 ntfs_debug("Failed to allocate cluster%s, error code "
@@ -1405,12 +1594,6 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1405 err); 1594 err);
1406 goto page_err_out; 1595 goto page_err_out;
1407 } 1596 }
1408 /* Change the runlist terminator to LCN_ENOENT. */
1409 rl2 = rl;
1410 while (rl2->length)
1411 rl2++;
1412 BUG_ON(rl2->lcn != LCN_RL_NOT_MAPPED);
1413 rl2->lcn = LCN_ENOENT;
1414 } else { 1597 } else {
1415 rl = NULL; 1598 rl = NULL;
1416 page = NULL; 1599 page = NULL;
@@ -1473,7 +1656,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1473 * attribute value. 1656 * attribute value.
1474 */ 1657 */
1475 attr_size = le32_to_cpu(a->data.resident.value_length); 1658 attr_size = le32_to_cpu(a->data.resident.value_length);
1476 BUG_ON(attr_size != i_size_read(vi)); 1659 BUG_ON(attr_size != data_size);
1477 if (page && !PageUptodate(page)) { 1660 if (page && !PageUptodate(page)) {
1478 kaddr = kmap_atomic(page, KM_USER0); 1661 kaddr = kmap_atomic(page, KM_USER0);
1479 memcpy(kaddr, (u8*)a + 1662 memcpy(kaddr, (u8*)a +
@@ -1538,7 +1721,9 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni)
1538 ffs(ni->itype.compressed.block_size) - 1; 1721 ffs(ni->itype.compressed.block_size) - 1;
1539 ni->itype.compressed.block_clusters = 1U << 1722 ni->itype.compressed.block_clusters = 1U <<
1540 a->data.non_resident.compression_unit; 1723 a->data.non_resident.compression_unit;
1541 } 1724 vi->i_blocks = ni->itype.compressed.size >> 9;
1725 } else
1726 vi->i_blocks = ni->allocated_size >> 9;
1542 write_unlock_irqrestore(&ni->size_lock, flags); 1727 write_unlock_irqrestore(&ni->size_lock, flags);
1543 /* 1728 /*
1544 * This needs to be last since the address space operations ->readpage 1729 * This needs to be last since the address space operations ->readpage
@@ -1652,6 +1837,640 @@ page_err_out:
1652} 1837}
1653 1838
1654/** 1839/**
1840 * ntfs_attr_extend_allocation - extend the allocated space of an attribute
1841 * @ni: ntfs inode of the attribute whose allocation to extend
1842 * @new_alloc_size: new size in bytes to which to extend the allocation to
1843 * @new_data_size: new size in bytes to which to extend the data to
1844 * @data_start: beginning of region which is required to be non-sparse
1845 *
1846 * Extend the allocated space of an attribute described by the ntfs inode @ni
1847 * to @new_alloc_size bytes. If @data_start is -1, the whole extension may be
1848 * implemented as a hole in the file (as long as both the volume and the ntfs
1849 * inode @ni have sparse support enabled). If @data_start is >= 0, then the
1850 * region between the old allocated size and @data_start - 1 may be made sparse
1851 * but the regions between @data_start and @new_alloc_size must be backed by
1852 * actual clusters.
1853 *
1854 * If @new_data_size is -1, it is ignored. If it is >= 0, then the data size
1855 * of the attribute is extended to @new_data_size. Note that the i_size of the
1856 * vfs inode is not updated. Only the data size in the base attribute record
1857 * is updated. The caller has to update i_size separately if this is required.
1858 * WARNING: It is a BUG() for @new_data_size to be smaller than the old data
1859 * size as well as for @new_data_size to be greater than @new_alloc_size.
1860 *
1861 * For resident attributes this involves resizing the attribute record and if
1862 * necessary moving it and/or other attributes into extent mft records and/or
1863 * converting the attribute to a non-resident attribute which in turn involves
1864 * extending the allocation of a non-resident attribute as described below.
1865 *
1866 * For non-resident attributes this involves allocating clusters in the data
1867 * zone on the volume (except for regions that are being made sparse) and
1868 * extending the run list to describe the allocated clusters as well as
1869 * updating the mapping pairs array of the attribute. This in turn involves
1870 * resizing the attribute record and if necessary moving it and/or other
1871 * attributes into extent mft records and/or splitting the attribute record
1872 * into multiple extent attribute records.
1873 *
1874 * Also, the attribute list attribute is updated if present and in some of the
1875 * above cases (the ones where extent mft records/attributes come into play),
1876 * an attribute list attribute is created if not already present.
1877 *
1878 * Return the new allocated size on success and -errno on error. In the case
1879 * that an error is encountered but a partial extension at least up to
1880 * @data_start (if present) is possible, the allocation is partially extended
1881 * and this is returned. This means the caller must check the returned size to
1882 * determine if the extension was partial. If @data_start is -1 then partial
1883 * allocations are not performed.
1884 *
1885 * WARNING: Do not call ntfs_attr_extend_allocation() for $MFT/$DATA.
1886 *
1887 * Locking: This function takes the runlist lock of @ni for writing as well as
1888 * locking the mft record of the base ntfs inode. These locks are maintained
1889 * throughout execution of the function. These locks are required so that the
1890 * attribute can be resized safely and so that it can for example be converted
1891 * from resident to non-resident safely.
1892 *
1893 * TODO: At present attribute list attribute handling is not implemented.
1894 *
1895 * TODO: At present it is not safe to call this function for anything other
1896 * than the $DATA attribute(s) of an uncompressed and unencrypted file.
1897 */
1898s64 ntfs_attr_extend_allocation(ntfs_inode *ni, s64 new_alloc_size,
1899 const s64 new_data_size, const s64 data_start)
1900{
1901 VCN vcn;
1902 s64 ll, allocated_size, start = data_start;
1903 struct inode *vi = VFS_I(ni);
1904 ntfs_volume *vol = ni->vol;
1905 ntfs_inode *base_ni;
1906 MFT_RECORD *m;
1907 ATTR_RECORD *a;
1908 ntfs_attr_search_ctx *ctx;
1909 runlist_element *rl, *rl2;
1910 unsigned long flags;
1911 int err, mp_size;
1912 u32 attr_len = 0; /* Silence stupid gcc warning. */
1913 BOOL mp_rebuilt;
1914
1915#ifdef NTFS_DEBUG
1916 read_lock_irqsave(&ni->size_lock, flags);
1917 allocated_size = ni->allocated_size;
1918 read_unlock_irqrestore(&ni->size_lock, flags);
1919 ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, "
1920 "old_allocated_size 0x%llx, "
1921 "new_allocated_size 0x%llx, new_data_size 0x%llx, "
1922 "data_start 0x%llx.", vi->i_ino,
1923 (unsigned)le32_to_cpu(ni->type),
1924 (unsigned long long)allocated_size,
1925 (unsigned long long)new_alloc_size,
1926 (unsigned long long)new_data_size,
1927 (unsigned long long)start);
1928#endif
1929retry_extend:
1930 /*
1931 * For non-resident attributes, @start and @new_size need to be aligned
1932 * to cluster boundaries for allocation purposes.
1933 */
1934 if (NInoNonResident(ni)) {
1935 if (start > 0)
1936 start &= ~(s64)vol->cluster_size_mask;
1937 new_alloc_size = (new_alloc_size + vol->cluster_size - 1) &
1938 ~(s64)vol->cluster_size_mask;
1939 }
1940 BUG_ON(new_data_size >= 0 && new_data_size > new_alloc_size);
1941 /* Check if new size is allowed in $AttrDef. */
1942 err = ntfs_attr_size_bounds_check(vol, ni->type, new_alloc_size);
1943 if (unlikely(err)) {
1944 /* Only emit errors when the write will fail completely. */
1945 read_lock_irqsave(&ni->size_lock, flags);
1946 allocated_size = ni->allocated_size;
1947 read_unlock_irqrestore(&ni->size_lock, flags);
1948 if (start < 0 || start >= allocated_size) {
1949 if (err == -ERANGE) {
1950 ntfs_error(vol->sb, "Cannot extend allocation "
1951 "of inode 0x%lx, attribute "
1952 "type 0x%x, because the new "
1953 "allocation would exceed the "
1954 "maximum allowed size for "
1955 "this attribute type.",
1956 vi->i_ino, (unsigned)
1957 le32_to_cpu(ni->type));
1958 } else {
1959 ntfs_error(vol->sb, "Cannot extend allocation "
1960 "of inode 0x%lx, attribute "
1961 "type 0x%x, because this "
1962 "attribute type is not "
1963 "defined on the NTFS volume. "
1964 "Possible corruption! You "
1965 "should run chkdsk!",
1966 vi->i_ino, (unsigned)
1967 le32_to_cpu(ni->type));
1968 }
1969 }
1970 /* Translate error code to be POSIX conformant for write(2). */
1971 if (err == -ERANGE)
1972 err = -EFBIG;
1973 else
1974 err = -EIO;
1975 return err;
1976 }
1977 if (!NInoAttr(ni))
1978 base_ni = ni;
1979 else
1980 base_ni = ni->ext.base_ntfs_ino;
1981 /*
1982 * We will be modifying both the runlist (if non-resident) and the mft
1983 * record so lock them both down.
1984 */
1985 down_write(&ni->runlist.lock);
1986 m = map_mft_record(base_ni);
1987 if (IS_ERR(m)) {
1988 err = PTR_ERR(m);
1989 m = NULL;
1990 ctx = NULL;
1991 goto err_out;
1992 }
1993 ctx = ntfs_attr_get_search_ctx(base_ni, m);
1994 if (unlikely(!ctx)) {
1995 err = -ENOMEM;
1996 goto err_out;
1997 }
1998 read_lock_irqsave(&ni->size_lock, flags);
1999 allocated_size = ni->allocated_size;
2000 read_unlock_irqrestore(&ni->size_lock, flags);
2001 /*
2002 * If non-resident, seek to the last extent. If resident, there is
2003 * only one extent, so seek to that.
2004 */
2005 vcn = NInoNonResident(ni) ? allocated_size >> vol->cluster_size_bits :
2006 0;
2007 /*
2008 * Abort if someone did the work whilst we waited for the locks. If we
2009 * just converted the attribute from resident to non-resident it is
2010 * likely that exactly this has happened already. We cannot quite
2011 * abort if we need to update the data size.
2012 */
2013 if (unlikely(new_alloc_size <= allocated_size)) {
2014 ntfs_debug("Allocated size already exceeds requested size.");
2015 new_alloc_size = allocated_size;
2016 if (new_data_size < 0)
2017 goto done;
2018 /*
2019 * We want the first attribute extent so that we can update the
2020 * data size.
2021 */
2022 vcn = 0;
2023 }
2024 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
2025 CASE_SENSITIVE, vcn, NULL, 0, ctx);
2026 if (unlikely(err)) {
2027 if (err == -ENOENT)
2028 err = -EIO;
2029 goto err_out;
2030 }
2031 m = ctx->mrec;
2032 a = ctx->attr;
2033 /* Use goto to reduce indentation. */
2034 if (a->non_resident)
2035 goto do_non_resident_extend;
2036 BUG_ON(NInoNonResident(ni));
2037 /* The total length of the attribute value. */
2038 attr_len = le32_to_cpu(a->data.resident.value_length);
2039 /*
2040 * Extend the attribute record to be able to store the new attribute
2041 * size. ntfs_attr_record_resize() will not do anything if the size is
2042 * not changing.
2043 */
2044 if (new_alloc_size < vol->mft_record_size &&
2045 !ntfs_attr_record_resize(m, a,
2046 le16_to_cpu(a->data.resident.value_offset) +
2047 new_alloc_size)) {
2048 /* The resize succeeded! */
2049 write_lock_irqsave(&ni->size_lock, flags);
2050 ni->allocated_size = le32_to_cpu(a->length) -
2051 le16_to_cpu(a->data.resident.value_offset);
2052 write_unlock_irqrestore(&ni->size_lock, flags);
2053 if (new_data_size >= 0) {
2054 BUG_ON(new_data_size < attr_len);
2055 a->data.resident.value_length =
2056 cpu_to_le32((u32)new_data_size);
2057 }
2058 goto flush_done;
2059 }
2060 /*
2061 * We have to drop all the locks so we can call
2062 * ntfs_attr_make_non_resident(). This could be optimised by try-
2063 * locking the first page cache page and only if that fails dropping
2064 * the locks, locking the page, and redoing all the locking and
2065 * lookups. While this would be a huge optimisation, it is not worth
2066 * it as this is definitely a slow code path.
2067 */
2068 ntfs_attr_put_search_ctx(ctx);
2069 unmap_mft_record(base_ni);
2070 up_write(&ni->runlist.lock);
2071 /*
2072 * Not enough space in the mft record, try to make the attribute
2073 * non-resident and if successful restart the extension process.
2074 */
2075 err = ntfs_attr_make_non_resident(ni, attr_len);
2076 if (likely(!err))
2077 goto retry_extend;
2078 /*
2079 * Could not make non-resident. If this is due to this not being
2080 * permitted for this attribute type or there not being enough space,
2081 * try to make other attributes non-resident. Otherwise fail.
2082 */
2083 if (unlikely(err != -EPERM && err != -ENOSPC)) {
2084 /* Only emit errors when the write will fail completely. */
2085 read_lock_irqsave(&ni->size_lock, flags);
2086 allocated_size = ni->allocated_size;
2087 read_unlock_irqrestore(&ni->size_lock, flags);
2088 if (start < 0 || start >= allocated_size)
2089 ntfs_error(vol->sb, "Cannot extend allocation of "
2090 "inode 0x%lx, attribute type 0x%x, "
2091 "because the conversion from resident "
2092 "to non-resident attribute failed "
2093 "with error code %i.", vi->i_ino,
2094 (unsigned)le32_to_cpu(ni->type), err);
2095 if (err != -ENOMEM)
2096 err = -EIO;
2097 goto conv_err_out;
2098 }
2099 /* TODO: Not implemented from here, abort. */
2100 read_lock_irqsave(&ni->size_lock, flags);
2101 allocated_size = ni->allocated_size;
2102 read_unlock_irqrestore(&ni->size_lock, flags);
2103 if (start < 0 || start >= allocated_size) {
2104 if (err == -ENOSPC)
2105 ntfs_error(vol->sb, "Not enough space in the mft "
2106 "record/on disk for the non-resident "
2107 "attribute value. This case is not "
2108 "implemented yet.");
2109 else /* if (err == -EPERM) */
2110 ntfs_error(vol->sb, "This attribute type may not be "
2111 "non-resident. This case is not "
2112 "implemented yet.");
2113 }
2114 err = -EOPNOTSUPP;
2115 goto conv_err_out;
2116#if 0
2117 // TODO: Attempt to make other attributes non-resident.
2118 if (!err)
2119 goto do_resident_extend;
2120 /*
2121 * Both the attribute list attribute and the standard information
2122 * attribute must remain in the base inode. Thus, if this is one of
2123 * these attributes, we have to try to move other attributes out into
2124 * extent mft records instead.
2125 */
2126 if (ni->type == AT_ATTRIBUTE_LIST ||
2127 ni->type == AT_STANDARD_INFORMATION) {
2128 // TODO: Attempt to move other attributes into extent mft
2129 // records.
2130 err = -EOPNOTSUPP;
2131 if (!err)
2132 goto do_resident_extend;
2133 goto err_out;
2134 }
2135 // TODO: Attempt to move this attribute to an extent mft record, but
2136 // only if it is not already the only attribute in an mft record in
2137 // which case there would be nothing to gain.
2138 err = -EOPNOTSUPP;
2139 if (!err)
2140 goto do_resident_extend;
2141 /* There is nothing we can do to make enough space. )-: */
2142 goto err_out;
2143#endif
2144do_non_resident_extend:
2145 BUG_ON(!NInoNonResident(ni));
2146 if (new_alloc_size == allocated_size) {
2147 BUG_ON(vcn);
2148 goto alloc_done;
2149 }
2150 /*
2151 * If the data starts after the end of the old allocation, this is a
2152 * $DATA attribute and sparse attributes are enabled on the volume and
2153 * for this inode, then create a sparse region between the old
2154 * allocated size and the start of the data. Otherwise simply proceed
2155 * with filling the whole space between the old allocated size and the
2156 * new allocated size with clusters.
2157 */
2158 if ((start >= 0 && start <= allocated_size) || ni->type != AT_DATA ||
2159 !NVolSparseEnabled(vol) || NInoSparseDisabled(ni))
2160 goto skip_sparse;
2161 // TODO: This is not implemented yet. We just fill in with real
2162 // clusters for now...
2163 ntfs_debug("Inserting holes is not-implemented yet. Falling back to "
2164 "allocating real clusters instead.");
2165skip_sparse:
2166 rl = ni->runlist.rl;
2167 if (likely(rl)) {
2168 /* Seek to the end of the runlist. */
2169 while (rl->length)
2170 rl++;
2171 }
2172 /* If this attribute extent is not mapped, map it now. */
2173 if (unlikely(!rl || rl->lcn == LCN_RL_NOT_MAPPED ||
2174 (rl->lcn == LCN_ENOENT && rl > ni->runlist.rl &&
2175 (rl-1)->lcn == LCN_RL_NOT_MAPPED))) {
2176 if (!rl && !allocated_size)
2177 goto first_alloc;
2178 rl = ntfs_mapping_pairs_decompress(vol, a, ni->runlist.rl);
2179 if (IS_ERR(rl)) {
2180 err = PTR_ERR(rl);
2181 if (start < 0 || start >= allocated_size)
2182 ntfs_error(vol->sb, "Cannot extend allocation "
2183 "of inode 0x%lx, attribute "
2184 "type 0x%x, because the "
2185 "mapping of a runlist "
2186 "fragment failed with error "
2187 "code %i.", vi->i_ino,
2188 (unsigned)le32_to_cpu(ni->type),
2189 err);
2190 if (err != -ENOMEM)
2191 err = -EIO;
2192 goto err_out;
2193 }
2194 ni->runlist.rl = rl;
2195 /* Seek to the end of the runlist. */
2196 while (rl->length)
2197 rl++;
2198 }
2199 /*
2200 * We now know the runlist of the last extent is mapped and @rl is at
2201 * the end of the runlist. We want to begin allocating clusters
2202 * starting at the last allocated cluster to reduce fragmentation. If
2203 * there are no valid LCNs in the attribute we let the cluster
2204 * allocator choose the starting cluster.
2205 */
2206 /* If the last LCN is a hole or simillar seek back to last real LCN. */
2207 while (rl->lcn < 0 && rl > ni->runlist.rl)
2208 rl--;
2209first_alloc:
2210 // FIXME: Need to implement partial allocations so at least part of the
2211 // write can be performed when start >= 0. (Needed for POSIX write(2)
2212 // conformance.)
2213 rl2 = ntfs_cluster_alloc(vol, allocated_size >> vol->cluster_size_bits,
2214 (new_alloc_size - allocated_size) >>
2215 vol->cluster_size_bits, (rl && (rl->lcn >= 0)) ?
2216 rl->lcn + rl->length : -1, DATA_ZONE, TRUE);
2217 if (IS_ERR(rl2)) {
2218 err = PTR_ERR(rl2);
2219 if (start < 0 || start >= allocated_size)
2220 ntfs_error(vol->sb, "Cannot extend allocation of "
2221 "inode 0x%lx, attribute type 0x%x, "
2222 "because the allocation of clusters "
2223 "failed with error code %i.", vi->i_ino,
2224 (unsigned)le32_to_cpu(ni->type), err);
2225 if (err != -ENOMEM && err != -ENOSPC)
2226 err = -EIO;
2227 goto err_out;
2228 }
2229 rl = ntfs_runlists_merge(ni->runlist.rl, rl2);
2230 if (IS_ERR(rl)) {
2231 err = PTR_ERR(rl);
2232 if (start < 0 || start >= allocated_size)
2233 ntfs_error(vol->sb, "Cannot extend allocation of "
2234 "inode 0x%lx, attribute type 0x%x, "
2235 "because the runlist merge failed "
2236 "with error code %i.", vi->i_ino,
2237 (unsigned)le32_to_cpu(ni->type), err);
2238 if (err != -ENOMEM)
2239 err = -EIO;
2240 if (ntfs_cluster_free_from_rl(vol, rl2)) {
2241 ntfs_error(vol->sb, "Failed to release allocated "
2242 "cluster(s) in error code path. Run "
2243 "chkdsk to recover the lost "
2244 "cluster(s).");
2245 NVolSetErrors(vol);
2246 }
2247 ntfs_free(rl2);
2248 goto err_out;
2249 }
2250 ni->runlist.rl = rl;
2251 ntfs_debug("Allocated 0x%llx clusters.", (long long)(new_alloc_size -
2252 allocated_size) >> vol->cluster_size_bits);
2253 /* Find the runlist element with which the attribute extent starts. */
2254 ll = sle64_to_cpu(a->data.non_resident.lowest_vcn);
2255 rl2 = ntfs_rl_find_vcn_nolock(rl, ll);
2256 BUG_ON(!rl2);
2257 BUG_ON(!rl2->length);
2258 BUG_ON(rl2->lcn < LCN_HOLE);
2259 mp_rebuilt = FALSE;
2260 /* Get the size for the new mapping pairs array for this extent. */
2261 mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1);
2262 if (unlikely(mp_size <= 0)) {
2263 err = mp_size;
2264 if (start < 0 || start >= allocated_size)
2265 ntfs_error(vol->sb, "Cannot extend allocation of "
2266 "inode 0x%lx, attribute type 0x%x, "
2267 "because determining the size for the "
2268 "mapping pairs failed with error code "
2269 "%i.", vi->i_ino,
2270 (unsigned)le32_to_cpu(ni->type), err);
2271 err = -EIO;
2272 goto undo_alloc;
2273 }
2274 /* Extend the attribute record to fit the bigger mapping pairs array. */
2275 attr_len = le32_to_cpu(a->length);
2276 err = ntfs_attr_record_resize(m, a, mp_size +
2277 le16_to_cpu(a->data.non_resident.mapping_pairs_offset));
2278 if (unlikely(err)) {
2279 BUG_ON(err != -ENOSPC);
2280 // TODO: Deal with this by moving this extent to a new mft
2281 // record or by starting a new extent in a new mft record,
2282 // possibly by extending this extent partially and filling it
2283 // and creating a new extent for the remainder, or by making
2284 // other attributes non-resident and/or by moving other
2285 // attributes out of this mft record.
2286 if (start < 0 || start >= allocated_size)
2287 ntfs_error(vol->sb, "Not enough space in the mft "
2288 "record for the extended attribute "
2289 "record. This case is not "
2290 "implemented yet.");
2291 err = -EOPNOTSUPP;
2292 goto undo_alloc;
2293 }
2294 mp_rebuilt = TRUE;
2295 /* Generate the mapping pairs array directly into the attr record. */
2296 err = ntfs_mapping_pairs_build(vol, (u8*)a +
2297 le16_to_cpu(a->data.non_resident.mapping_pairs_offset),
2298 mp_size, rl2, ll, -1, NULL);
2299 if (unlikely(err)) {
2300 if (start < 0 || start >= allocated_size)
2301 ntfs_error(vol->sb, "Cannot extend allocation of "
2302 "inode 0x%lx, attribute type 0x%x, "
2303 "because building the mapping pairs "
2304 "failed with error code %i.", vi->i_ino,
2305 (unsigned)le32_to_cpu(ni->type), err);
2306 err = -EIO;
2307 goto undo_alloc;
2308 }
2309 /* Update the highest_vcn. */
2310 a->data.non_resident.highest_vcn = cpu_to_sle64((new_alloc_size >>
2311 vol->cluster_size_bits) - 1);
2312 /*
2313 * We now have extended the allocated size of the attribute. Reflect
2314 * this in the ntfs_inode structure and the attribute record.
2315 */
2316 if (a->data.non_resident.lowest_vcn) {
2317 /*
2318 * We are not in the first attribute extent, switch to it, but
2319 * first ensure the changes will make it to disk later.
2320 */
2321 flush_dcache_mft_record_page(ctx->ntfs_ino);
2322 mark_mft_record_dirty(ctx->ntfs_ino);
2323 ntfs_attr_reinit_search_ctx(ctx);
2324 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
2325 CASE_SENSITIVE, 0, NULL, 0, ctx);
2326 if (unlikely(err))
2327 goto restore_undo_alloc;
2328 /* @m is not used any more so no need to set it. */
2329 a = ctx->attr;
2330 }
2331 write_lock_irqsave(&ni->size_lock, flags);
2332 ni->allocated_size = new_alloc_size;
2333 a->data.non_resident.allocated_size = cpu_to_sle64(new_alloc_size);
2334 /*
2335 * FIXME: This would fail if @ni is a directory, $MFT, or an index,
2336 * since those can have sparse/compressed set. For example can be
2337 * set compressed even though it is not compressed itself and in that
2338 * case the bit means that files are to be created compressed in the
2339 * directory... At present this is ok as this code is only called for
2340 * regular files, and only for their $DATA attribute(s).
2341 * FIXME: The calculation is wrong if we created a hole above. For now
2342 * it does not matter as we never create holes.
2343 */
2344 if (NInoSparse(ni) || NInoCompressed(ni)) {
2345 ni->itype.compressed.size += new_alloc_size - allocated_size;
2346 a->data.non_resident.compressed_size =
2347 cpu_to_sle64(ni->itype.compressed.size);
2348 vi->i_blocks = ni->itype.compressed.size >> 9;
2349 } else
2350 vi->i_blocks = new_alloc_size >> 9;
2351 write_unlock_irqrestore(&ni->size_lock, flags);
2352alloc_done:
2353 if (new_data_size >= 0) {
2354 BUG_ON(new_data_size <
2355 sle64_to_cpu(a->data.non_resident.data_size));
2356 a->data.non_resident.data_size = cpu_to_sle64(new_data_size);
2357 }
2358flush_done:
2359 /* Ensure the changes make it to disk. */
2360 flush_dcache_mft_record_page(ctx->ntfs_ino);
2361 mark_mft_record_dirty(ctx->ntfs_ino);
2362done:
2363 ntfs_attr_put_search_ctx(ctx);
2364 unmap_mft_record(base_ni);
2365 up_write(&ni->runlist.lock);
2366 ntfs_debug("Done, new_allocated_size 0x%llx.",
2367 (unsigned long long)new_alloc_size);
2368 return new_alloc_size;
2369restore_undo_alloc:
2370 if (start < 0 || start >= allocated_size)
2371 ntfs_error(vol->sb, "Cannot complete extension of allocation "
2372 "of inode 0x%lx, attribute type 0x%x, because "
2373 "lookup of first attribute extent failed with "
2374 "error code %i.", vi->i_ino,
2375 (unsigned)le32_to_cpu(ni->type), err);
2376 if (err == -ENOENT)
2377 err = -EIO;
2378 ntfs_attr_reinit_search_ctx(ctx);
2379 if (ntfs_attr_lookup(ni->type, ni->name, ni->name_len, CASE_SENSITIVE,
2380 allocated_size >> vol->cluster_size_bits, NULL, 0,
2381 ctx)) {
2382 ntfs_error(vol->sb, "Failed to find last attribute extent of "
2383 "attribute in error code path. Run chkdsk to "
2384 "recover.");
2385 write_lock_irqsave(&ni->size_lock, flags);
2386 ni->allocated_size = new_alloc_size;
2387 /*
2388 * FIXME: This would fail if @ni is a directory... See above.
2389 * FIXME: The calculation is wrong if we created a hole above.
2390 * For now it does not matter as we never create holes.
2391 */
2392 if (NInoSparse(ni) || NInoCompressed(ni)) {
2393 ni->itype.compressed.size += new_alloc_size -
2394 allocated_size;
2395 vi->i_blocks = ni->itype.compressed.size >> 9;
2396 } else
2397 vi->i_blocks = new_alloc_size >> 9;
2398 write_unlock_irqrestore(&ni->size_lock, flags);
2399 ntfs_attr_put_search_ctx(ctx);
2400 unmap_mft_record(base_ni);
2401 up_write(&ni->runlist.lock);
2402 /*
2403 * The only thing that is now wrong is the allocated size of the
2404 * base attribute extent which chkdsk should be able to fix.
2405 */
2406 NVolSetErrors(vol);
2407 return err;
2408 }
2409 ctx->attr->data.non_resident.highest_vcn = cpu_to_sle64(
2410 (allocated_size >> vol->cluster_size_bits) - 1);
2411undo_alloc:
2412 ll = allocated_size >> vol->cluster_size_bits;
2413 if (ntfs_cluster_free(ni, ll, -1, ctx) < 0) {
2414 ntfs_error(vol->sb, "Failed to release allocated cluster(s) "
2415 "in error code path. Run chkdsk to recover "
2416 "the lost cluster(s).");
2417 NVolSetErrors(vol);
2418 }
2419 m = ctx->mrec;
2420 a = ctx->attr;
2421 /*
2422 * If the runlist truncation fails and/or the search context is no
2423 * longer valid, we cannot resize the attribute record or build the
2424 * mapping pairs array thus we mark the inode bad so that no access to
2425 * the freed clusters can happen.
2426 */
2427 if (ntfs_rl_truncate_nolock(vol, &ni->runlist, ll) || IS_ERR(m)) {
2428 ntfs_error(vol->sb, "Failed to %s in error code path. Run "
2429 "chkdsk to recover.", IS_ERR(m) ?
2430 "restore attribute search context" :
2431 "truncate attribute runlist");
2432 make_bad_inode(vi);
2433 make_bad_inode(VFS_I(base_ni));
2434 NVolSetErrors(vol);
2435 } else if (mp_rebuilt) {
2436 if (ntfs_attr_record_resize(m, a, attr_len)) {
2437 ntfs_error(vol->sb, "Failed to restore attribute "
2438 "record in error code path. Run "
2439 "chkdsk to recover.");
2440 make_bad_inode(vi);
2441 make_bad_inode(VFS_I(base_ni));
2442 NVolSetErrors(vol);
2443 } else /* if (success) */ {
2444 if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(
2445 a->data.non_resident.
2446 mapping_pairs_offset), attr_len -
2447 le16_to_cpu(a->data.non_resident.
2448 mapping_pairs_offset), rl2, ll, -1,
2449 NULL)) {
2450 ntfs_error(vol->sb, "Failed to restore "
2451 "mapping pairs array in error "
2452 "code path. Run chkdsk to "
2453 "recover.");
2454 make_bad_inode(vi);
2455 make_bad_inode(VFS_I(base_ni));
2456 NVolSetErrors(vol);
2457 }
2458 flush_dcache_mft_record_page(ctx->ntfs_ino);
2459 mark_mft_record_dirty(ctx->ntfs_ino);
2460 }
2461 }
2462err_out:
2463 if (ctx)
2464 ntfs_attr_put_search_ctx(ctx);
2465 if (m)
2466 unmap_mft_record(base_ni);
2467 up_write(&ni->runlist.lock);
2468conv_err_out:
2469 ntfs_debug("Failed. Returning error code %i.", err);
2470 return err;
2471}
2472
2473/**
1655 * ntfs_attr_set - fill (a part of) an attribute with a byte 2474 * ntfs_attr_set - fill (a part of) an attribute with a byte
1656 * @ni: ntfs inode describing the attribute to fill 2475 * @ni: ntfs inode describing the attribute to fill
1657 * @ofs: offset inside the attribute at which to start to fill 2476 * @ofs: offset inside the attribute at which to start to fill
@@ -1773,6 +2592,8 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val)
1773 /* Finally unlock and release the page. */ 2592 /* Finally unlock and release the page. */
1774 unlock_page(page); 2593 unlock_page(page);
1775 page_cache_release(page); 2594 page_cache_release(page);
2595 balance_dirty_pages_ratelimited(mapping);
2596 cond_resched();
1776 } 2597 }
1777 /* If there is a last partial page, need to do it the slow way. */ 2598 /* If there is a last partial page, need to do it the slow way. */
1778 if (end_ofs) { 2599 if (end_ofs) {
diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h
index 0618ed6fd7b3..9074886b44ba 100644
--- a/fs/ntfs/attrib.h
+++ b/fs/ntfs/attrib.h
@@ -60,14 +60,15 @@ typedef struct {
60 ATTR_RECORD *base_attr; 60 ATTR_RECORD *base_attr;
61} ntfs_attr_search_ctx; 61} ntfs_attr_search_ctx;
62 62
63extern int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn); 63extern int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn,
64 ntfs_attr_search_ctx *ctx);
64extern int ntfs_map_runlist(ntfs_inode *ni, VCN vcn); 65extern int ntfs_map_runlist(ntfs_inode *ni, VCN vcn);
65 66
66extern LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn, 67extern LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
67 const BOOL write_locked); 68 const BOOL write_locked);
68 69
69extern runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, 70extern runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni,
70 const VCN vcn, const BOOL write_locked); 71 const VCN vcn, ntfs_attr_search_ctx *ctx);
71 72
72int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name, 73int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name,
73 const u32 name_len, const IGNORE_CASE_BOOL ic, 74 const u32 name_len, const IGNORE_CASE_BOOL ic,
@@ -102,7 +103,10 @@ extern int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size);
102extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a, 103extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
103 const u32 new_size); 104 const u32 new_size);
104 105
105extern int ntfs_attr_make_non_resident(ntfs_inode *ni); 106extern int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size);
107
108extern s64 ntfs_attr_extend_allocation(ntfs_inode *ni, s64 new_alloc_size,
109 const s64 new_data_size, const s64 data_start);
106 110
107extern int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, 111extern int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt,
108 const u8 val); 112 const u8 val);
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index be9fd1dd423d..727533891813 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -19,11 +19,24 @@
19 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <linux/pagemap.h>
23#include <linux/buffer_head.h> 22#include <linux/buffer_head.h>
23#include <linux/pagemap.h>
24#include <linux/pagevec.h>
25#include <linux/sched.h>
26#include <linux/swap.h>
27#include <linux/uio.h>
28#include <linux/writeback.h>
24 29
30#include <asm/page.h>
31#include <asm/uaccess.h>
32
33#include "attrib.h"
34#include "bitmap.h"
25#include "inode.h" 35#include "inode.h"
26#include "debug.h" 36#include "debug.h"
37#include "lcnalloc.h"
38#include "malloc.h"
39#include "mft.h"
27#include "ntfs.h" 40#include "ntfs.h"
28 41
29/** 42/**
@@ -56,6 +69,2185 @@ static int ntfs_file_open(struct inode *vi, struct file *filp)
56#ifdef NTFS_RW 69#ifdef NTFS_RW
57 70
58/** 71/**
72 * ntfs_attr_extend_initialized - extend the initialized size of an attribute
73 * @ni: ntfs inode of the attribute to extend
74 * @new_init_size: requested new initialized size in bytes
75 * @cached_page: store any allocated but unused page here
76 * @lru_pvec: lru-buffering pagevec of the caller
77 *
78 * Extend the initialized size of an attribute described by the ntfs inode @ni
79 * to @new_init_size bytes. This involves zeroing any non-sparse space between
80 * the old initialized size and @new_init_size both in the page cache and on
81 * disk (if relevant complete pages are already uptodate in the page cache then
82 * these are simply marked dirty).
83 *
84 * As a side-effect, the file size (vfs inode->i_size) may be incremented as,
85 * in the resident attribute case, it is tied to the initialized size and, in
86 * the non-resident attribute case, it may not fall below the initialized size.
87 *
88 * Note that if the attribute is resident, we do not need to touch the page
89 * cache at all. This is because if the page cache page is not uptodate we
90 * bring it uptodate later, when doing the write to the mft record since we
91 * then already have the page mapped. And if the page is uptodate, the
92 * non-initialized region will already have been zeroed when the page was
93 * brought uptodate and the region may in fact already have been overwritten
94 * with new data via mmap() based writes, so we cannot just zero it. And since
95 * POSIX specifies that the behaviour of resizing a file whilst it is mmap()ped
96 * is unspecified, we choose not to do zeroing and thus we do not need to touch
97 * the page at all. For a more detailed explanation see ntfs_truncate() in
98 * fs/ntfs/inode.c.
99 *
100 * @cached_page and @lru_pvec are just optimizations for dealing with multiple
101 * pages.
102 *
103 * Return 0 on success and -errno on error. In the case that an error is
104 * encountered it is possible that the initialized size will already have been
105 * incremented some way towards @new_init_size but it is guaranteed that if
106 * this is the case, the necessary zeroing will also have happened and that all
107 * metadata is self-consistent.
108 *
109 * Locking: i_sem on the vfs inode corrseponsind to the ntfs inode @ni must be
110 * held by the caller.
111 */
112static int ntfs_attr_extend_initialized(ntfs_inode *ni, const s64 new_init_size,
113 struct page **cached_page, struct pagevec *lru_pvec)
114{
115 s64 old_init_size;
116 loff_t old_i_size;
117 pgoff_t index, end_index;
118 unsigned long flags;
119 struct inode *vi = VFS_I(ni);
120 ntfs_inode *base_ni;
121 MFT_RECORD *m = NULL;
122 ATTR_RECORD *a;
123 ntfs_attr_search_ctx *ctx = NULL;
124 struct address_space *mapping;
125 struct page *page = NULL;
126 u8 *kattr;
127 int err;
128 u32 attr_len;
129
130 read_lock_irqsave(&ni->size_lock, flags);
131 old_init_size = ni->initialized_size;
132 old_i_size = i_size_read(vi);
133 BUG_ON(new_init_size > ni->allocated_size);
134 read_unlock_irqrestore(&ni->size_lock, flags);
135 ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, "
136 "old_initialized_size 0x%llx, "
137 "new_initialized_size 0x%llx, i_size 0x%llx.",
138 vi->i_ino, (unsigned)le32_to_cpu(ni->type),
139 (unsigned long long)old_init_size,
140 (unsigned long long)new_init_size, old_i_size);
141 if (!NInoAttr(ni))
142 base_ni = ni;
143 else
144 base_ni = ni->ext.base_ntfs_ino;
145 /* Use goto to reduce indentation and we need the label below anyway. */
146 if (NInoNonResident(ni))
147 goto do_non_resident_extend;
148 BUG_ON(old_init_size != old_i_size);
149 m = map_mft_record(base_ni);
150 if (IS_ERR(m)) {
151 err = PTR_ERR(m);
152 m = NULL;
153 goto err_out;
154 }
155 ctx = ntfs_attr_get_search_ctx(base_ni, m);
156 if (unlikely(!ctx)) {
157 err = -ENOMEM;
158 goto err_out;
159 }
160 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
161 CASE_SENSITIVE, 0, NULL, 0, ctx);
162 if (unlikely(err)) {
163 if (err == -ENOENT)
164 err = -EIO;
165 goto err_out;
166 }
167 m = ctx->mrec;
168 a = ctx->attr;
169 BUG_ON(a->non_resident);
170 /* The total length of the attribute value. */
171 attr_len = le32_to_cpu(a->data.resident.value_length);
172 BUG_ON(old_i_size != (loff_t)attr_len);
173 /*
174 * Do the zeroing in the mft record and update the attribute size in
175 * the mft record.
176 */
177 kattr = (u8*)a + le16_to_cpu(a->data.resident.value_offset);
178 memset(kattr + attr_len, 0, new_init_size - attr_len);
179 a->data.resident.value_length = cpu_to_le32((u32)new_init_size);
180 /* Finally, update the sizes in the vfs and ntfs inodes. */
181 write_lock_irqsave(&ni->size_lock, flags);
182 i_size_write(vi, new_init_size);
183 ni->initialized_size = new_init_size;
184 write_unlock_irqrestore(&ni->size_lock, flags);
185 goto done;
186do_non_resident_extend:
187 /*
188 * If the new initialized size @new_init_size exceeds the current file
189 * size (vfs inode->i_size), we need to extend the file size to the
190 * new initialized size.
191 */
192 if (new_init_size > old_i_size) {
193 m = map_mft_record(base_ni);
194 if (IS_ERR(m)) {
195 err = PTR_ERR(m);
196 m = NULL;
197 goto err_out;
198 }
199 ctx = ntfs_attr_get_search_ctx(base_ni, m);
200 if (unlikely(!ctx)) {
201 err = -ENOMEM;
202 goto err_out;
203 }
204 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
205 CASE_SENSITIVE, 0, NULL, 0, ctx);
206 if (unlikely(err)) {
207 if (err == -ENOENT)
208 err = -EIO;
209 goto err_out;
210 }
211 m = ctx->mrec;
212 a = ctx->attr;
213 BUG_ON(!a->non_resident);
214 BUG_ON(old_i_size != (loff_t)
215 sle64_to_cpu(a->data.non_resident.data_size));
216 a->data.non_resident.data_size = cpu_to_sle64(new_init_size);
217 flush_dcache_mft_record_page(ctx->ntfs_ino);
218 mark_mft_record_dirty(ctx->ntfs_ino);
219 /* Update the file size in the vfs inode. */
220 i_size_write(vi, new_init_size);
221 ntfs_attr_put_search_ctx(ctx);
222 ctx = NULL;
223 unmap_mft_record(base_ni);
224 m = NULL;
225 }
226 mapping = vi->i_mapping;
227 index = old_init_size >> PAGE_CACHE_SHIFT;
228 end_index = (new_init_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
229 do {
230 /*
231 * Read the page. If the page is not present, this will zero
232 * the uninitialized regions for us.
233 */
234 page = read_cache_page(mapping, index,
235 (filler_t*)mapping->a_ops->readpage, NULL);
236 if (IS_ERR(page)) {
237 err = PTR_ERR(page);
238 goto init_err_out;
239 }
240 wait_on_page_locked(page);
241 if (unlikely(!PageUptodate(page) || PageError(page))) {
242 page_cache_release(page);
243 err = -EIO;
244 goto init_err_out;
245 }
246 /*
247 * Update the initialized size in the ntfs inode. This is
248 * enough to make ntfs_writepage() work.
249 */
250 write_lock_irqsave(&ni->size_lock, flags);
251 ni->initialized_size = (index + 1) << PAGE_CACHE_SHIFT;
252 if (ni->initialized_size > new_init_size)
253 ni->initialized_size = new_init_size;
254 write_unlock_irqrestore(&ni->size_lock, flags);
255 /* Set the page dirty so it gets written out. */
256 set_page_dirty(page);
257 page_cache_release(page);
258 /*
259 * Play nice with the vm and the rest of the system. This is
260 * very much needed as we can potentially be modifying the
261 * initialised size from a very small value to a really huge
262 * value, e.g.
263 * f = open(somefile, O_TRUNC);
264 * truncate(f, 10GiB);
265 * seek(f, 10GiB);
266 * write(f, 1);
267 * And this would mean we would be marking dirty hundreds of
268 * thousands of pages or as in the above example more than
269 * two and a half million pages!
270 *
271 * TODO: For sparse pages could optimize this workload by using
272 * the FsMisc / MiscFs page bit as a "PageIsSparse" bit. This
273 * would be set in readpage for sparse pages and here we would
274 * not need to mark dirty any pages which have this bit set.
275 * The only caveat is that we have to clear the bit everywhere
276 * where we allocate any clusters that lie in the page or that
277 * contain the page.
278 *
279 * TODO: An even greater optimization would be for us to only
280 * call readpage() on pages which are not in sparse regions as
281 * determined from the runlist. This would greatly reduce the
282 * number of pages we read and make dirty in the case of sparse
283 * files.
284 */
285 balance_dirty_pages_ratelimited(mapping);
286 cond_resched();
287 } while (++index < end_index);
288 read_lock_irqsave(&ni->size_lock, flags);
289 BUG_ON(ni->initialized_size != new_init_size);
290 read_unlock_irqrestore(&ni->size_lock, flags);
291 /* Now bring in sync the initialized_size in the mft record. */
292 m = map_mft_record(base_ni);
293 if (IS_ERR(m)) {
294 err = PTR_ERR(m);
295 m = NULL;
296 goto init_err_out;
297 }
298 ctx = ntfs_attr_get_search_ctx(base_ni, m);
299 if (unlikely(!ctx)) {
300 err = -ENOMEM;
301 goto init_err_out;
302 }
303 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
304 CASE_SENSITIVE, 0, NULL, 0, ctx);
305 if (unlikely(err)) {
306 if (err == -ENOENT)
307 err = -EIO;
308 goto init_err_out;
309 }
310 m = ctx->mrec;
311 a = ctx->attr;
312 BUG_ON(!a->non_resident);
313 a->data.non_resident.initialized_size = cpu_to_sle64(new_init_size);
314done:
315 flush_dcache_mft_record_page(ctx->ntfs_ino);
316 mark_mft_record_dirty(ctx->ntfs_ino);
317 if (ctx)
318 ntfs_attr_put_search_ctx(ctx);
319 if (m)
320 unmap_mft_record(base_ni);
321 ntfs_debug("Done, initialized_size 0x%llx, i_size 0x%llx.",
322 (unsigned long long)new_init_size, i_size_read(vi));
323 return 0;
324init_err_out:
325 write_lock_irqsave(&ni->size_lock, flags);
326 ni->initialized_size = old_init_size;
327 write_unlock_irqrestore(&ni->size_lock, flags);
328err_out:
329 if (ctx)
330 ntfs_attr_put_search_ctx(ctx);
331 if (m)
332 unmap_mft_record(base_ni);
333 ntfs_debug("Failed. Returning error code %i.", err);
334 return err;
335}
336
337/**
338 * ntfs_fault_in_pages_readable -
339 *
340 * Fault a number of userspace pages into pagetables.
341 *
342 * Unlike include/linux/pagemap.h::fault_in_pages_readable(), this one copes
343 * with more than two userspace pages as well as handling the single page case
344 * elegantly.
345 *
346 * If you find this difficult to understand, then think of the while loop being
347 * the following code, except that we do without the integer variable ret:
348 *
349 * do {
350 * ret = __get_user(c, uaddr);
351 * uaddr += PAGE_SIZE;
352 * } while (!ret && uaddr < end);
353 *
354 * Note, the final __get_user() may well run out-of-bounds of the user buffer,
355 * but _not_ out-of-bounds of the page the user buffer belongs to, and since
356 * this is only a read and not a write, and since it is still in the same page,
357 * it should not matter and this makes the code much simpler.
358 */
359static inline void ntfs_fault_in_pages_readable(const char __user *uaddr,
360 int bytes)
361{
362 const char __user *end;
363 volatile char c;
364
365 /* Set @end to the first byte outside the last page we care about. */
366 end = (const char __user*)PAGE_ALIGN((ptrdiff_t __user)uaddr + bytes);
367
368 while (!__get_user(c, uaddr) && (uaddr += PAGE_SIZE, uaddr < end))
369 ;
370}
371
372/**
373 * ntfs_fault_in_pages_readable_iovec -
374 *
375 * Same as ntfs_fault_in_pages_readable() but operates on an array of iovecs.
376 */
377static inline void ntfs_fault_in_pages_readable_iovec(const struct iovec *iov,
378 size_t iov_ofs, int bytes)
379{
380 do {
381 const char __user *buf;
382 unsigned len;
383
384 buf = iov->iov_base + iov_ofs;
385 len = iov->iov_len - iov_ofs;
386 if (len > bytes)
387 len = bytes;
388 ntfs_fault_in_pages_readable(buf, len);
389 bytes -= len;
390 iov++;
391 iov_ofs = 0;
392 } while (bytes);
393}
394
395/**
396 * __ntfs_grab_cache_pages - obtain a number of locked pages
397 * @mapping: address space mapping from which to obtain page cache pages
398 * @index: starting index in @mapping at which to begin obtaining pages
399 * @nr_pages: number of page cache pages to obtain
400 * @pages: array of pages in which to return the obtained page cache pages
401 * @cached_page: allocated but as yet unused page
402 * @lru_pvec: lru-buffering pagevec of caller
403 *
404 * Obtain @nr_pages locked page cache pages from the mapping @maping and
405 * starting at index @index.
406 *
407 * If a page is newly created, increment its refcount and add it to the
408 * caller's lru-buffering pagevec @lru_pvec.
409 *
410 * This is the same as mm/filemap.c::__grab_cache_page(), except that @nr_pages
411 * are obtained at once instead of just one page and that 0 is returned on
412 * success and -errno on error.
413 *
414 * Note, the page locks are obtained in ascending page index order.
415 */
416static inline int __ntfs_grab_cache_pages(struct address_space *mapping,
417 pgoff_t index, const unsigned nr_pages, struct page **pages,
418 struct page **cached_page, struct pagevec *lru_pvec)
419{
420 int err, nr;
421
422 BUG_ON(!nr_pages);
423 err = nr = 0;
424 do {
425 pages[nr] = find_lock_page(mapping, index);
426 if (!pages[nr]) {
427 if (!*cached_page) {
428 *cached_page = page_cache_alloc(mapping);
429 if (unlikely(!*cached_page)) {
430 err = -ENOMEM;
431 goto err_out;
432 }
433 }
434 err = add_to_page_cache(*cached_page, mapping, index,
435 GFP_KERNEL);
436 if (unlikely(err)) {
437 if (err == -EEXIST)
438 continue;
439 goto err_out;
440 }
441 pages[nr] = *cached_page;
442 page_cache_get(*cached_page);
443 if (unlikely(!pagevec_add(lru_pvec, *cached_page)))
444 __pagevec_lru_add(lru_pvec);
445 *cached_page = NULL;
446 }
447 index++;
448 nr++;
449 } while (nr < nr_pages);
450out:
451 return err;
452err_out:
453 while (nr > 0) {
454 unlock_page(pages[--nr]);
455 page_cache_release(pages[nr]);
456 }
457 goto out;
458}
459
460static inline int ntfs_submit_bh_for_read(struct buffer_head *bh)
461{
462 lock_buffer(bh);
463 get_bh(bh);
464 bh->b_end_io = end_buffer_read_sync;
465 return submit_bh(READ, bh);
466}
467
468/**
469 * ntfs_prepare_pages_for_non_resident_write - prepare pages for receiving data
470 * @pages: array of destination pages
471 * @nr_pages: number of pages in @pages
472 * @pos: byte position in file at which the write begins
473 * @bytes: number of bytes to be written
474 *
475 * This is called for non-resident attributes from ntfs_file_buffered_write()
476 * with i_sem held on the inode (@pages[0]->mapping->host). There are
477 * @nr_pages pages in @pages which are locked but not kmap()ped. The source
478 * data has not yet been copied into the @pages.
479 *
480 * Need to fill any holes with actual clusters, allocate buffers if necessary,
481 * ensure all the buffers are mapped, and bring uptodate any buffers that are
482 * only partially being written to.
483 *
484 * If @nr_pages is greater than one, we are guaranteed that the cluster size is
485 * greater than PAGE_CACHE_SIZE, that all pages in @pages are entirely inside
486 * the same cluster and that they are the entirety of that cluster, and that
487 * the cluster is sparse, i.e. we need to allocate a cluster to fill the hole.
488 *
489 * i_size is not to be modified yet.
490 *
491 * Return 0 on success or -errno on error.
492 */
493static int ntfs_prepare_pages_for_non_resident_write(struct page **pages,
494 unsigned nr_pages, s64 pos, size_t bytes)
495{
496 VCN vcn, highest_vcn = 0, cpos, cend, bh_cpos, bh_cend;
497 LCN lcn;
498 s64 bh_pos, vcn_len, end, initialized_size;
499 sector_t lcn_block;
500 struct page *page;
501 struct inode *vi;
502 ntfs_inode *ni, *base_ni = NULL;
503 ntfs_volume *vol;
504 runlist_element *rl, *rl2;
505 struct buffer_head *bh, *head, *wait[2], **wait_bh = wait;
506 ntfs_attr_search_ctx *ctx = NULL;
507 MFT_RECORD *m = NULL;
508 ATTR_RECORD *a = NULL;
509 unsigned long flags;
510 u32 attr_rec_len = 0;
511 unsigned blocksize, u;
512 int err, mp_size;
513 BOOL rl_write_locked, was_hole, is_retry;
514 unsigned char blocksize_bits;
515 struct {
516 u8 runlist_merged:1;
517 u8 mft_attr_mapped:1;
518 u8 mp_rebuilt:1;
519 u8 attr_switched:1;
520 } status = { 0, 0, 0, 0 };
521
522 BUG_ON(!nr_pages);
523 BUG_ON(!pages);
524 BUG_ON(!*pages);
525 vi = pages[0]->mapping->host;
526 ni = NTFS_I(vi);
527 vol = ni->vol;
528 ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, start page "
529 "index 0x%lx, nr_pages 0x%x, pos 0x%llx, bytes 0x%zx.",
530 vi->i_ino, ni->type, pages[0]->index, nr_pages,
531 (long long)pos, bytes);
532 blocksize_bits = vi->i_blkbits;
533 blocksize = 1 << blocksize_bits;
534 u = 0;
535 do {
536 struct page *page = pages[u];
537 /*
538 * create_empty_buffers() will create uptodate/dirty buffers if
539 * the page is uptodate/dirty.
540 */
541 if (!page_has_buffers(page)) {
542 create_empty_buffers(page, blocksize, 0);
543 if (unlikely(!page_has_buffers(page)))
544 return -ENOMEM;
545 }
546 } while (++u < nr_pages);
547 rl_write_locked = FALSE;
548 rl = NULL;
549 err = 0;
550 vcn = lcn = -1;
551 vcn_len = 0;
552 lcn_block = -1;
553 was_hole = FALSE;
554 cpos = pos >> vol->cluster_size_bits;
555 end = pos + bytes;
556 cend = (end + vol->cluster_size - 1) >> vol->cluster_size_bits;
557 /*
558 * Loop over each page and for each page over each buffer. Use goto to
559 * reduce indentation.
560 */
561 u = 0;
562do_next_page:
563 page = pages[u];
564 bh_pos = (s64)page->index << PAGE_CACHE_SHIFT;
565 bh = head = page_buffers(page);
566 do {
567 VCN cdelta;
568 s64 bh_end;
569 unsigned bh_cofs;
570
571 /* Clear buffer_new on all buffers to reinitialise state. */
572 if (buffer_new(bh))
573 clear_buffer_new(bh);
574 bh_end = bh_pos + blocksize;
575 bh_cpos = bh_pos >> vol->cluster_size_bits;
576 bh_cofs = bh_pos & vol->cluster_size_mask;
577 if (buffer_mapped(bh)) {
578 /*
579 * The buffer is already mapped. If it is uptodate,
580 * ignore it.
581 */
582 if (buffer_uptodate(bh))
583 continue;
584 /*
585 * The buffer is not uptodate. If the page is uptodate
586 * set the buffer uptodate and otherwise ignore it.
587 */
588 if (PageUptodate(page)) {
589 set_buffer_uptodate(bh);
590 continue;
591 }
592 /*
593 * Neither the page nor the buffer are uptodate. If
594 * the buffer is only partially being written to, we
595 * need to read it in before the write, i.e. now.
596 */
597 if ((bh_pos < pos && bh_end > pos) ||
598 (bh_pos < end && bh_end > end)) {
599 /*
600 * If the buffer is fully or partially within
601 * the initialized size, do an actual read.
602 * Otherwise, simply zero the buffer.
603 */
604 read_lock_irqsave(&ni->size_lock, flags);
605 initialized_size = ni->initialized_size;
606 read_unlock_irqrestore(&ni->size_lock, flags);
607 if (bh_pos < initialized_size) {
608 ntfs_submit_bh_for_read(bh);
609 *wait_bh++ = bh;
610 } else {
611 u8 *kaddr = kmap_atomic(page, KM_USER0);
612 memset(kaddr + bh_offset(bh), 0,
613 blocksize);
614 kunmap_atomic(kaddr, KM_USER0);
615 flush_dcache_page(page);
616 set_buffer_uptodate(bh);
617 }
618 }
619 continue;
620 }
621 /* Unmapped buffer. Need to map it. */
622 bh->b_bdev = vol->sb->s_bdev;
623 /*
624 * If the current buffer is in the same clusters as the map
625 * cache, there is no need to check the runlist again. The
626 * map cache is made up of @vcn, which is the first cached file
627 * cluster, @vcn_len which is the number of cached file
628 * clusters, @lcn is the device cluster corresponding to @vcn,
629 * and @lcn_block is the block number corresponding to @lcn.
630 */
631 cdelta = bh_cpos - vcn;
632 if (likely(!cdelta || (cdelta > 0 && cdelta < vcn_len))) {
633map_buffer_cached:
634 BUG_ON(lcn < 0);
635 bh->b_blocknr = lcn_block +
636 (cdelta << (vol->cluster_size_bits -
637 blocksize_bits)) +
638 (bh_cofs >> blocksize_bits);
639 set_buffer_mapped(bh);
640 /*
641 * If the page is uptodate so is the buffer. If the
642 * buffer is fully outside the write, we ignore it if
643 * it was already allocated and we mark it dirty so it
644 * gets written out if we allocated it. On the other
645 * hand, if we allocated the buffer but we are not
646 * marking it dirty we set buffer_new so we can do
647 * error recovery.
648 */
649 if (PageUptodate(page)) {
650 if (!buffer_uptodate(bh))
651 set_buffer_uptodate(bh);
652 if (unlikely(was_hole)) {
653 /* We allocated the buffer. */
654 unmap_underlying_metadata(bh->b_bdev,
655 bh->b_blocknr);
656 if (bh_end <= pos || bh_pos >= end)
657 mark_buffer_dirty(bh);
658 else
659 set_buffer_new(bh);
660 }
661 continue;
662 }
663 /* Page is _not_ uptodate. */
664 if (likely(!was_hole)) {
665 /*
666 * Buffer was already allocated. If it is not
667 * uptodate and is only partially being written
668 * to, we need to read it in before the write,
669 * i.e. now.
670 */
671 if (!buffer_uptodate(bh) && bh_pos < end &&
672 bh_end > pos &&
673 (bh_pos < pos ||
674 bh_end > end)) {
675 /*
676 * If the buffer is fully or partially
677 * within the initialized size, do an
678 * actual read. Otherwise, simply zero
679 * the buffer.
680 */
681 read_lock_irqsave(&ni->size_lock,
682 flags);
683 initialized_size = ni->initialized_size;
684 read_unlock_irqrestore(&ni->size_lock,
685 flags);
686 if (bh_pos < initialized_size) {
687 ntfs_submit_bh_for_read(bh);
688 *wait_bh++ = bh;
689 } else {
690 u8 *kaddr = kmap_atomic(page,
691 KM_USER0);
692 memset(kaddr + bh_offset(bh),
693 0, blocksize);
694 kunmap_atomic(kaddr, KM_USER0);
695 flush_dcache_page(page);
696 set_buffer_uptodate(bh);
697 }
698 }
699 continue;
700 }
701 /* We allocated the buffer. */
702 unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);
703 /*
704 * If the buffer is fully outside the write, zero it,
705 * set it uptodate, and mark it dirty so it gets
706 * written out. If it is partially being written to,
707 * zero region surrounding the write but leave it to
708 * commit write to do anything else. Finally, if the
709 * buffer is fully being overwritten, do nothing.
710 */
711 if (bh_end <= pos || bh_pos >= end) {
712 if (!buffer_uptodate(bh)) {
713 u8 *kaddr = kmap_atomic(page, KM_USER0);
714 memset(kaddr + bh_offset(bh), 0,
715 blocksize);
716 kunmap_atomic(kaddr, KM_USER0);
717 flush_dcache_page(page);
718 set_buffer_uptodate(bh);
719 }
720 mark_buffer_dirty(bh);
721 continue;
722 }
723 set_buffer_new(bh);
724 if (!buffer_uptodate(bh) &&
725 (bh_pos < pos || bh_end > end)) {
726 u8 *kaddr;
727 unsigned pofs;
728
729 kaddr = kmap_atomic(page, KM_USER0);
730 if (bh_pos < pos) {
731 pofs = bh_pos & ~PAGE_CACHE_MASK;
732 memset(kaddr + pofs, 0, pos - bh_pos);
733 }
734 if (bh_end > end) {
735 pofs = end & ~PAGE_CACHE_MASK;
736 memset(kaddr + pofs, 0, bh_end - end);
737 }
738 kunmap_atomic(kaddr, KM_USER0);
739 flush_dcache_page(page);
740 }
741 continue;
742 }
743 /*
744 * Slow path: this is the first buffer in the cluster. If it
745 * is outside allocated size and is not uptodate, zero it and
746 * set it uptodate.
747 */
748 read_lock_irqsave(&ni->size_lock, flags);
749 initialized_size = ni->allocated_size;
750 read_unlock_irqrestore(&ni->size_lock, flags);
751 if (bh_pos > initialized_size) {
752 if (PageUptodate(page)) {
753 if (!buffer_uptodate(bh))
754 set_buffer_uptodate(bh);
755 } else if (!buffer_uptodate(bh)) {
756 u8 *kaddr = kmap_atomic(page, KM_USER0);
757 memset(kaddr + bh_offset(bh), 0, blocksize);
758 kunmap_atomic(kaddr, KM_USER0);
759 flush_dcache_page(page);
760 set_buffer_uptodate(bh);
761 }
762 continue;
763 }
764 is_retry = FALSE;
765 if (!rl) {
766 down_read(&ni->runlist.lock);
767retry_remap:
768 rl = ni->runlist.rl;
769 }
770 if (likely(rl != NULL)) {
771 /* Seek to element containing target cluster. */
772 while (rl->length && rl[1].vcn <= bh_cpos)
773 rl++;
774 lcn = ntfs_rl_vcn_to_lcn(rl, bh_cpos);
775 if (likely(lcn >= 0)) {
776 /*
777 * Successful remap, setup the map cache and
778 * use that to deal with the buffer.
779 */
780 was_hole = FALSE;
781 vcn = bh_cpos;
782 vcn_len = rl[1].vcn - vcn;
783 lcn_block = lcn << (vol->cluster_size_bits -
784 blocksize_bits);
785 cdelta = 0;
786 /*
787 * If the number of remaining clusters touched
788 * by the write is smaller or equal to the
789 * number of cached clusters, unlock the
790 * runlist as the map cache will be used from
791 * now on.
792 */
793 if (likely(vcn + vcn_len >= cend)) {
794 if (rl_write_locked) {
795 up_write(&ni->runlist.lock);
796 rl_write_locked = FALSE;
797 } else
798 up_read(&ni->runlist.lock);
799 rl = NULL;
800 }
801 goto map_buffer_cached;
802 }
803 } else
804 lcn = LCN_RL_NOT_MAPPED;
805 /*
806 * If it is not a hole and not out of bounds, the runlist is
807 * probably unmapped so try to map it now.
808 */
809 if (unlikely(lcn != LCN_HOLE && lcn != LCN_ENOENT)) {
810 if (likely(!is_retry && lcn == LCN_RL_NOT_MAPPED)) {
811 /* Attempt to map runlist. */
812 if (!rl_write_locked) {
813 /*
814 * We need the runlist locked for
815 * writing, so if it is locked for
816 * reading relock it now and retry in
817 * case it changed whilst we dropped
818 * the lock.
819 */
820 up_read(&ni->runlist.lock);
821 down_write(&ni->runlist.lock);
822 rl_write_locked = TRUE;
823 goto retry_remap;
824 }
825 err = ntfs_map_runlist_nolock(ni, bh_cpos,
826 NULL);
827 if (likely(!err)) {
828 is_retry = TRUE;
829 goto retry_remap;
830 }
831 /*
832 * If @vcn is out of bounds, pretend @lcn is
833 * LCN_ENOENT. As long as the buffer is out
834 * of bounds this will work fine.
835 */
836 if (err == -ENOENT) {
837 lcn = LCN_ENOENT;
838 err = 0;
839 goto rl_not_mapped_enoent;
840 }
841 } else
842 err = -EIO;
843 /* Failed to map the buffer, even after retrying. */
844 bh->b_blocknr = -1;
845 ntfs_error(vol->sb, "Failed to write to inode 0x%lx, "
846 "attribute type 0x%x, vcn 0x%llx, "
847 "vcn offset 0x%x, because its "
848 "location on disk could not be "
849 "determined%s (error code %i).",
850 ni->mft_no, ni->type,
851 (unsigned long long)bh_cpos,
852 (unsigned)bh_pos &
853 vol->cluster_size_mask,
854 is_retry ? " even after retrying" : "",
855 err);
856 break;
857 }
858rl_not_mapped_enoent:
859 /*
860 * The buffer is in a hole or out of bounds. We need to fill
861 * the hole, unless the buffer is in a cluster which is not
862 * touched by the write, in which case we just leave the buffer
863 * unmapped. This can only happen when the cluster size is
864 * less than the page cache size.
865 */
866 if (unlikely(vol->cluster_size < PAGE_CACHE_SIZE)) {
867 bh_cend = (bh_end + vol->cluster_size - 1) >>
868 vol->cluster_size_bits;
869 if ((bh_cend <= cpos || bh_cpos >= cend)) {
870 bh->b_blocknr = -1;
871 /*
872 * If the buffer is uptodate we skip it. If it
873 * is not but the page is uptodate, we can set
874 * the buffer uptodate. If the page is not
875 * uptodate, we can clear the buffer and set it
876 * uptodate. Whether this is worthwhile is
877 * debatable and this could be removed.
878 */
879 if (PageUptodate(page)) {
880 if (!buffer_uptodate(bh))
881 set_buffer_uptodate(bh);
882 } else if (!buffer_uptodate(bh)) {
883 u8 *kaddr = kmap_atomic(page, KM_USER0);
884 memset(kaddr + bh_offset(bh), 0,
885 blocksize);
886 kunmap_atomic(kaddr, KM_USER0);
887 flush_dcache_page(page);
888 set_buffer_uptodate(bh);
889 }
890 continue;
891 }
892 }
893 /*
894 * Out of bounds buffer is invalid if it was not really out of
895 * bounds.
896 */
897 BUG_ON(lcn != LCN_HOLE);
898 /*
899 * We need the runlist locked for writing, so if it is locked
900 * for reading relock it now and retry in case it changed
901 * whilst we dropped the lock.
902 */
903 BUG_ON(!rl);
904 if (!rl_write_locked) {
905 up_read(&ni->runlist.lock);
906 down_write(&ni->runlist.lock);
907 rl_write_locked = TRUE;
908 goto retry_remap;
909 }
910 /* Find the previous last allocated cluster. */
911 BUG_ON(rl->lcn != LCN_HOLE);
912 lcn = -1;
913 rl2 = rl;
914 while (--rl2 >= ni->runlist.rl) {
915 if (rl2->lcn >= 0) {
916 lcn = rl2->lcn + rl2->length;
917 break;
918 }
919 }
920 rl2 = ntfs_cluster_alloc(vol, bh_cpos, 1, lcn, DATA_ZONE,
921 FALSE);
922 if (IS_ERR(rl2)) {
923 err = PTR_ERR(rl2);
924 ntfs_debug("Failed to allocate cluster, error code %i.",
925 err);
926 break;
927 }
928 lcn = rl2->lcn;
929 rl = ntfs_runlists_merge(ni->runlist.rl, rl2);
930 if (IS_ERR(rl)) {
931 err = PTR_ERR(rl);
932 if (err != -ENOMEM)
933 err = -EIO;
934 if (ntfs_cluster_free_from_rl(vol, rl2)) {
935 ntfs_error(vol->sb, "Failed to release "
936 "allocated cluster in error "
937 "code path. Run chkdsk to "
938 "recover the lost cluster.");
939 NVolSetErrors(vol);
940 }
941 ntfs_free(rl2);
942 break;
943 }
944 ni->runlist.rl = rl;
945 status.runlist_merged = 1;
946 ntfs_debug("Allocated cluster, lcn 0x%llx.", lcn);
947 /* Map and lock the mft record and get the attribute record. */
948 if (!NInoAttr(ni))
949 base_ni = ni;
950 else
951 base_ni = ni->ext.base_ntfs_ino;
952 m = map_mft_record(base_ni);
953 if (IS_ERR(m)) {
954 err = PTR_ERR(m);
955 break;
956 }
957 ctx = ntfs_attr_get_search_ctx(base_ni, m);
958 if (unlikely(!ctx)) {
959 err = -ENOMEM;
960 unmap_mft_record(base_ni);
961 break;
962 }
963 status.mft_attr_mapped = 1;
964 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
965 CASE_SENSITIVE, bh_cpos, NULL, 0, ctx);
966 if (unlikely(err)) {
967 if (err == -ENOENT)
968 err = -EIO;
969 break;
970 }
971 m = ctx->mrec;
972 a = ctx->attr;
973 /*
974 * Find the runlist element with which the attribute extent
975 * starts. Note, we cannot use the _attr_ version because we
976 * have mapped the mft record. That is ok because we know the
977 * runlist fragment must be mapped already to have ever gotten
978 * here, so we can just use the _rl_ version.
979 */
980 vcn = sle64_to_cpu(a->data.non_resident.lowest_vcn);
981 rl2 = ntfs_rl_find_vcn_nolock(rl, vcn);
982 BUG_ON(!rl2);
983 BUG_ON(!rl2->length);
984 BUG_ON(rl2->lcn < LCN_HOLE);
985 highest_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn);
986 /*
987 * If @highest_vcn is zero, calculate the real highest_vcn
988 * (which can really be zero).
989 */
990 if (!highest_vcn)
991 highest_vcn = (sle64_to_cpu(
992 a->data.non_resident.allocated_size) >>
993 vol->cluster_size_bits) - 1;
994 /*
995 * Determine the size of the mapping pairs array for the new
996 * extent, i.e. the old extent with the hole filled.
997 */
998 mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, vcn,
999 highest_vcn);
1000 if (unlikely(mp_size <= 0)) {
1001 if (!(err = mp_size))
1002 err = -EIO;
1003 ntfs_debug("Failed to get size for mapping pairs "
1004 "array, error code %i.", err);
1005 break;
1006 }
1007 /*
1008 * Resize the attribute record to fit the new mapping pairs
1009 * array.
1010 */
1011 attr_rec_len = le32_to_cpu(a->length);
1012 err = ntfs_attr_record_resize(m, a, mp_size + le16_to_cpu(
1013 a->data.non_resident.mapping_pairs_offset));
1014 if (unlikely(err)) {
1015 BUG_ON(err != -ENOSPC);
1016 // TODO: Deal with this by using the current attribute
1017 // and fill it with as much of the mapping pairs
1018 // array as possible. Then loop over each attribute
1019 // extent rewriting the mapping pairs arrays as we go
1020 // along and if when we reach the end we have not
1021 // enough space, try to resize the last attribute
1022 // extent and if even that fails, add a new attribute
1023 // extent.
1024 // We could also try to resize at each step in the hope
1025 // that we will not need to rewrite every single extent.
1026 // Note, we may need to decompress some extents to fill
1027 // the runlist as we are walking the extents...
1028 ntfs_error(vol->sb, "Not enough space in the mft "
1029 "record for the extended attribute "
1030 "record. This case is not "
1031 "implemented yet.");
1032 err = -EOPNOTSUPP;
1033 break ;
1034 }
1035 status.mp_rebuilt = 1;
1036 /*
1037 * Generate the mapping pairs array directly into the attribute
1038 * record.
1039 */
1040 err = ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(
1041 a->data.non_resident.mapping_pairs_offset),
1042 mp_size, rl2, vcn, highest_vcn, NULL);
1043 if (unlikely(err)) {
1044 ntfs_error(vol->sb, "Cannot fill hole in inode 0x%lx, "
1045 "attribute type 0x%x, because building "
1046 "the mapping pairs failed with error "
1047 "code %i.", vi->i_ino,
1048 (unsigned)le32_to_cpu(ni->type), err);
1049 err = -EIO;
1050 break;
1051 }
1052 /* Update the highest_vcn but only if it was not set. */
1053 if (unlikely(!a->data.non_resident.highest_vcn))
1054 a->data.non_resident.highest_vcn =
1055 cpu_to_sle64(highest_vcn);
1056 /*
1057 * If the attribute is sparse/compressed, update the compressed
1058 * size in the ntfs_inode structure and the attribute record.
1059 */
1060 if (likely(NInoSparse(ni) || NInoCompressed(ni))) {
1061 /*
1062 * If we are not in the first attribute extent, switch
1063 * to it, but first ensure the changes will make it to
1064 * disk later.
1065 */
1066 if (a->data.non_resident.lowest_vcn) {
1067 flush_dcache_mft_record_page(ctx->ntfs_ino);
1068 mark_mft_record_dirty(ctx->ntfs_ino);
1069 ntfs_attr_reinit_search_ctx(ctx);
1070 err = ntfs_attr_lookup(ni->type, ni->name,
1071 ni->name_len, CASE_SENSITIVE,
1072 0, NULL, 0, ctx);
1073 if (unlikely(err)) {
1074 status.attr_switched = 1;
1075 break;
1076 }
1077 /* @m is not used any more so do not set it. */
1078 a = ctx->attr;
1079 }
1080 write_lock_irqsave(&ni->size_lock, flags);
1081 ni->itype.compressed.size += vol->cluster_size;
1082 a->data.non_resident.compressed_size =
1083 cpu_to_sle64(ni->itype.compressed.size);
1084 write_unlock_irqrestore(&ni->size_lock, flags);
1085 }
1086 /* Ensure the changes make it to disk. */
1087 flush_dcache_mft_record_page(ctx->ntfs_ino);
1088 mark_mft_record_dirty(ctx->ntfs_ino);
1089 ntfs_attr_put_search_ctx(ctx);
1090 unmap_mft_record(base_ni);
1091 /* Successfully filled the hole. */
1092 status.runlist_merged = 0;
1093 status.mft_attr_mapped = 0;
1094 status.mp_rebuilt = 0;
1095 /* Setup the map cache and use that to deal with the buffer. */
1096 was_hole = TRUE;
1097 vcn = bh_cpos;
1098 vcn_len = 1;
1099 lcn_block = lcn << (vol->cluster_size_bits - blocksize_bits);
1100 cdelta = 0;
1101 /*
1102 * If the number of remaining clusters in the @pages is smaller
1103 * or equal to the number of cached clusters, unlock the
1104 * runlist as the map cache will be used from now on.
1105 */
1106 if (likely(vcn + vcn_len >= cend)) {
1107 up_write(&ni->runlist.lock);
1108 rl_write_locked = FALSE;
1109 rl = NULL;
1110 }
1111 goto map_buffer_cached;
1112 } while (bh_pos += blocksize, (bh = bh->b_this_page) != head);
1113 /* If there are no errors, do the next page. */
1114 if (likely(!err && ++u < nr_pages))
1115 goto do_next_page;
1116 /* If there are no errors, release the runlist lock if we took it. */
1117 if (likely(!err)) {
1118 if (unlikely(rl_write_locked)) {
1119 up_write(&ni->runlist.lock);
1120 rl_write_locked = FALSE;
1121 } else if (unlikely(rl))
1122 up_read(&ni->runlist.lock);
1123 rl = NULL;
1124 }
1125 /* If we issued read requests, let them complete. */
1126 read_lock_irqsave(&ni->size_lock, flags);
1127 initialized_size = ni->initialized_size;
1128 read_unlock_irqrestore(&ni->size_lock, flags);
1129 while (wait_bh > wait) {
1130 bh = *--wait_bh;
1131 wait_on_buffer(bh);
1132 if (likely(buffer_uptodate(bh))) {
1133 page = bh->b_page;
1134 bh_pos = ((s64)page->index << PAGE_CACHE_SHIFT) +
1135 bh_offset(bh);
1136 /*
1137 * If the buffer overflows the initialized size, need
1138 * to zero the overflowing region.
1139 */
1140 if (unlikely(bh_pos + blocksize > initialized_size)) {
1141 u8 *kaddr;
1142 int ofs = 0;
1143
1144 if (likely(bh_pos < initialized_size))
1145 ofs = initialized_size - bh_pos;
1146 kaddr = kmap_atomic(page, KM_USER0);
1147 memset(kaddr + bh_offset(bh) + ofs, 0,
1148 blocksize - ofs);
1149 kunmap_atomic(kaddr, KM_USER0);
1150 flush_dcache_page(page);
1151 }
1152 } else /* if (unlikely(!buffer_uptodate(bh))) */
1153 err = -EIO;
1154 }
1155 if (likely(!err)) {
1156 /* Clear buffer_new on all buffers. */
1157 u = 0;
1158 do {
1159 bh = head = page_buffers(pages[u]);
1160 do {
1161 if (buffer_new(bh))
1162 clear_buffer_new(bh);
1163 } while ((bh = bh->b_this_page) != head);
1164 } while (++u < nr_pages);
1165 ntfs_debug("Done.");
1166 return err;
1167 }
1168 if (status.attr_switched) {
1169 /* Get back to the attribute extent we modified. */
1170 ntfs_attr_reinit_search_ctx(ctx);
1171 if (ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
1172 CASE_SENSITIVE, bh_cpos, NULL, 0, ctx)) {
1173 ntfs_error(vol->sb, "Failed to find required "
1174 "attribute extent of attribute in "
1175 "error code path. Run chkdsk to "
1176 "recover.");
1177 write_lock_irqsave(&ni->size_lock, flags);
1178 ni->itype.compressed.size += vol->cluster_size;
1179 write_unlock_irqrestore(&ni->size_lock, flags);
1180 flush_dcache_mft_record_page(ctx->ntfs_ino);
1181 mark_mft_record_dirty(ctx->ntfs_ino);
1182 /*
1183 * The only thing that is now wrong is the compressed
1184 * size of the base attribute extent which chkdsk
1185 * should be able to fix.
1186 */
1187 NVolSetErrors(vol);
1188 } else {
1189 m = ctx->mrec;
1190 a = ctx->attr;
1191 status.attr_switched = 0;
1192 }
1193 }
1194 /*
1195 * If the runlist has been modified, need to restore it by punching a
1196 * hole into it and we then need to deallocate the on-disk cluster as
1197 * well. Note, we only modify the runlist if we are able to generate a
1198 * new mapping pairs array, i.e. only when the mapped attribute extent
1199 * is not switched.
1200 */
1201 if (status.runlist_merged && !status.attr_switched) {
1202 BUG_ON(!rl_write_locked);
1203 /* Make the file cluster we allocated sparse in the runlist. */
1204 if (ntfs_rl_punch_nolock(vol, &ni->runlist, bh_cpos, 1)) {
1205 ntfs_error(vol->sb, "Failed to punch hole into "
1206 "attribute runlist in error code "
1207 "path. Run chkdsk to recover the "
1208 "lost cluster.");
1209 make_bad_inode(vi);
1210 make_bad_inode(VFS_I(base_ni));
1211 NVolSetErrors(vol);
1212 } else /* if (success) */ {
1213 status.runlist_merged = 0;
1214 /*
1215 * Deallocate the on-disk cluster we allocated but only
1216 * if we succeeded in punching its vcn out of the
1217 * runlist.
1218 */
1219 down_write(&vol->lcnbmp_lock);
1220 if (ntfs_bitmap_clear_bit(vol->lcnbmp_ino, lcn)) {
1221 ntfs_error(vol->sb, "Failed to release "
1222 "allocated cluster in error "
1223 "code path. Run chkdsk to "
1224 "recover the lost cluster.");
1225 NVolSetErrors(vol);
1226 }
1227 up_write(&vol->lcnbmp_lock);
1228 }
1229 }
1230 /*
1231 * Resize the attribute record to its old size and rebuild the mapping
1232 * pairs array. Note, we only can do this if the runlist has been
1233 * restored to its old state which also implies that the mapped
1234 * attribute extent is not switched.
1235 */
1236 if (status.mp_rebuilt && !status.runlist_merged) {
1237 if (ntfs_attr_record_resize(m, a, attr_rec_len)) {
1238 ntfs_error(vol->sb, "Failed to restore attribute "
1239 "record in error code path. Run "
1240 "chkdsk to recover.");
1241 make_bad_inode(vi);
1242 make_bad_inode(VFS_I(base_ni));
1243 NVolSetErrors(vol);
1244 } else /* if (success) */ {
1245 if (ntfs_mapping_pairs_build(vol, (u8*)a +
1246 le16_to_cpu(a->data.non_resident.
1247 mapping_pairs_offset), attr_rec_len -
1248 le16_to_cpu(a->data.non_resident.
1249 mapping_pairs_offset), ni->runlist.rl,
1250 vcn, highest_vcn, NULL)) {
1251 ntfs_error(vol->sb, "Failed to restore "
1252 "mapping pairs array in error "
1253 "code path. Run chkdsk to "
1254 "recover.");
1255 make_bad_inode(vi);
1256 make_bad_inode(VFS_I(base_ni));
1257 NVolSetErrors(vol);
1258 }
1259 flush_dcache_mft_record_page(ctx->ntfs_ino);
1260 mark_mft_record_dirty(ctx->ntfs_ino);
1261 }
1262 }
1263 /* Release the mft record and the attribute. */
1264 if (status.mft_attr_mapped) {
1265 ntfs_attr_put_search_ctx(ctx);
1266 unmap_mft_record(base_ni);
1267 }
1268 /* Release the runlist lock. */
1269 if (rl_write_locked)
1270 up_write(&ni->runlist.lock);
1271 else if (rl)
1272 up_read(&ni->runlist.lock);
1273 /*
1274 * Zero out any newly allocated blocks to avoid exposing stale data.
1275 * If BH_New is set, we know that the block was newly allocated above
1276 * and that it has not been fully zeroed and marked dirty yet.
1277 */
1278 nr_pages = u;
1279 u = 0;
1280 end = bh_cpos << vol->cluster_size_bits;
1281 do {
1282 page = pages[u];
1283 bh = head = page_buffers(page);
1284 do {
1285 if (u == nr_pages &&
1286 ((s64)page->index << PAGE_CACHE_SHIFT) +
1287 bh_offset(bh) >= end)
1288 break;
1289 if (!buffer_new(bh))
1290 continue;
1291 clear_buffer_new(bh);
1292 if (!buffer_uptodate(bh)) {
1293 if (PageUptodate(page))
1294 set_buffer_uptodate(bh);
1295 else {
1296 u8 *kaddr = kmap_atomic(page, KM_USER0);
1297 memset(kaddr + bh_offset(bh), 0,
1298 blocksize);
1299 kunmap_atomic(kaddr, KM_USER0);
1300 flush_dcache_page(page);
1301 set_buffer_uptodate(bh);
1302 }
1303 }
1304 mark_buffer_dirty(bh);
1305 } while ((bh = bh->b_this_page) != head);
1306 } while (++u <= nr_pages);
1307 ntfs_error(vol->sb, "Failed. Returning error code %i.", err);
1308 return err;
1309}
1310
1311/*
1312 * Copy as much as we can into the pages and return the number of bytes which
1313 * were sucessfully copied. If a fault is encountered then clear the pages
1314 * out to (ofs + bytes) and return the number of bytes which were copied.
1315 */
1316static inline size_t ntfs_copy_from_user(struct page **pages,
1317 unsigned nr_pages, unsigned ofs, const char __user *buf,
1318 size_t bytes)
1319{
1320 struct page **last_page = pages + nr_pages;
1321 char *kaddr;
1322 size_t total = 0;
1323 unsigned len;
1324 int left;
1325
1326 do {
1327 len = PAGE_CACHE_SIZE - ofs;
1328 if (len > bytes)
1329 len = bytes;
1330 kaddr = kmap_atomic(*pages, KM_USER0);
1331 left = __copy_from_user_inatomic(kaddr + ofs, buf, len);
1332 kunmap_atomic(kaddr, KM_USER0);
1333 if (unlikely(left)) {
1334 /* Do it the slow way. */
1335 kaddr = kmap(*pages);
1336 left = __copy_from_user(kaddr + ofs, buf, len);
1337 kunmap(*pages);
1338 if (unlikely(left))
1339 goto err_out;
1340 }
1341 total += len;
1342 bytes -= len;
1343 if (!bytes)
1344 break;
1345 buf += len;
1346 ofs = 0;
1347 } while (++pages < last_page);
1348out:
1349 return total;
1350err_out:
1351 total += len - left;
1352 /* Zero the rest of the target like __copy_from_user(). */
1353 while (++pages < last_page) {
1354 bytes -= len;
1355 if (!bytes)
1356 break;
1357 len = PAGE_CACHE_SIZE;
1358 if (len > bytes)
1359 len = bytes;
1360 kaddr = kmap_atomic(*pages, KM_USER0);
1361 memset(kaddr, 0, len);
1362 kunmap_atomic(kaddr, KM_USER0);
1363 }
1364 goto out;
1365}
1366
1367static size_t __ntfs_copy_from_user_iovec(char *vaddr,
1368 const struct iovec *iov, size_t iov_ofs, size_t bytes)
1369{
1370 size_t total = 0;
1371
1372 while (1) {
1373 const char __user *buf = iov->iov_base + iov_ofs;
1374 unsigned len;
1375 size_t left;
1376
1377 len = iov->iov_len - iov_ofs;
1378 if (len > bytes)
1379 len = bytes;
1380 left = __copy_from_user_inatomic(vaddr, buf, len);
1381 total += len;
1382 bytes -= len;
1383 vaddr += len;
1384 if (unlikely(left)) {
1385 /*
1386 * Zero the rest of the target like __copy_from_user().
1387 */
1388 memset(vaddr, 0, bytes);
1389 total -= left;
1390 break;
1391 }
1392 if (!bytes)
1393 break;
1394 iov++;
1395 iov_ofs = 0;
1396 }
1397 return total;
1398}
1399
1400static inline void ntfs_set_next_iovec(const struct iovec **iovp,
1401 size_t *iov_ofsp, size_t bytes)
1402{
1403 const struct iovec *iov = *iovp;
1404 size_t iov_ofs = *iov_ofsp;
1405
1406 while (bytes) {
1407 unsigned len;
1408
1409 len = iov->iov_len - iov_ofs;
1410 if (len > bytes)
1411 len = bytes;
1412 bytes -= len;
1413 iov_ofs += len;
1414 if (iov->iov_len == iov_ofs) {
1415 iov++;
1416 iov_ofs = 0;
1417 }
1418 }
1419 *iovp = iov;
1420 *iov_ofsp = iov_ofs;
1421}
1422
1423/*
1424 * This has the same side-effects and return value as ntfs_copy_from_user().
1425 * The difference is that on a fault we need to memset the remainder of the
1426 * pages (out to offset + bytes), to emulate ntfs_copy_from_user()'s
1427 * single-segment behaviour.
1428 *
1429 * We call the same helper (__ntfs_copy_from_user_iovec()) both when atomic and
1430 * when not atomic. This is ok because __ntfs_copy_from_user_iovec() calls
1431 * __copy_from_user_inatomic() and it is ok to call this when non-atomic. In
1432 * fact, the only difference between __copy_from_user_inatomic() and
1433 * __copy_from_user() is that the latter calls might_sleep(). And on many
1434 * architectures __copy_from_user_inatomic() is just defined to
1435 * __copy_from_user() so it makes no difference at all on those architectures.
1436 */
1437static inline size_t ntfs_copy_from_user_iovec(struct page **pages,
1438 unsigned nr_pages, unsigned ofs, const struct iovec **iov,
1439 size_t *iov_ofs, size_t bytes)
1440{
1441 struct page **last_page = pages + nr_pages;
1442 char *kaddr;
1443 size_t copied, len, total = 0;
1444
1445 do {
1446 len = PAGE_CACHE_SIZE - ofs;
1447 if (len > bytes)
1448 len = bytes;
1449 kaddr = kmap_atomic(*pages, KM_USER0);
1450 copied = __ntfs_copy_from_user_iovec(kaddr + ofs,
1451 *iov, *iov_ofs, len);
1452 kunmap_atomic(kaddr, KM_USER0);
1453 if (unlikely(copied != len)) {
1454 /* Do it the slow way. */
1455 kaddr = kmap(*pages);
1456 copied = __ntfs_copy_from_user_iovec(kaddr + ofs,
1457 *iov, *iov_ofs, len);
1458 kunmap(*pages);
1459 if (unlikely(copied != len))
1460 goto err_out;
1461 }
1462 total += len;
1463 bytes -= len;
1464 if (!bytes)
1465 break;
1466 ntfs_set_next_iovec(iov, iov_ofs, len);
1467 ofs = 0;
1468 } while (++pages < last_page);
1469out:
1470 return total;
1471err_out:
1472 total += copied;
1473 /* Zero the rest of the target like __copy_from_user(). */
1474 while (++pages < last_page) {
1475 bytes -= len;
1476 if (!bytes)
1477 break;
1478 len = PAGE_CACHE_SIZE;
1479 if (len > bytes)
1480 len = bytes;
1481 kaddr = kmap_atomic(*pages, KM_USER0);
1482 memset(kaddr, 0, len);
1483 kunmap_atomic(kaddr, KM_USER0);
1484 }
1485 goto out;
1486}
1487
1488static inline void ntfs_flush_dcache_pages(struct page **pages,
1489 unsigned nr_pages)
1490{
1491 BUG_ON(!nr_pages);
1492 do {
1493 /*
1494 * Warning: Do not do the decrement at the same time as the
1495 * call because flush_dcache_page() is a NULL macro on i386
1496 * and hence the decrement never happens.
1497 */
1498 flush_dcache_page(pages[nr_pages]);
1499 } while (--nr_pages > 0);
1500}
1501
1502/**
1503 * ntfs_commit_pages_after_non_resident_write - commit the received data
1504 * @pages: array of destination pages
1505 * @nr_pages: number of pages in @pages
1506 * @pos: byte position in file at which the write begins
1507 * @bytes: number of bytes to be written
1508 *
1509 * See description of ntfs_commit_pages_after_write(), below.
1510 */
1511static inline int ntfs_commit_pages_after_non_resident_write(
1512 struct page **pages, const unsigned nr_pages,
1513 s64 pos, size_t bytes)
1514{
1515 s64 end, initialized_size;
1516 struct inode *vi;
1517 ntfs_inode *ni, *base_ni;
1518 struct buffer_head *bh, *head;
1519 ntfs_attr_search_ctx *ctx;
1520 MFT_RECORD *m;
1521 ATTR_RECORD *a;
1522 unsigned long flags;
1523 unsigned blocksize, u;
1524 int err;
1525
1526 vi = pages[0]->mapping->host;
1527 ni = NTFS_I(vi);
1528 blocksize = 1 << vi->i_blkbits;
1529 end = pos + bytes;
1530 u = 0;
1531 do {
1532 s64 bh_pos;
1533 struct page *page;
1534 BOOL partial;
1535
1536 page = pages[u];
1537 bh_pos = (s64)page->index << PAGE_CACHE_SHIFT;
1538 bh = head = page_buffers(page);
1539 partial = FALSE;
1540 do {
1541 s64 bh_end;
1542
1543 bh_end = bh_pos + blocksize;
1544 if (bh_end <= pos || bh_pos >= end) {
1545 if (!buffer_uptodate(bh))
1546 partial = TRUE;
1547 } else {
1548 set_buffer_uptodate(bh);
1549 mark_buffer_dirty(bh);
1550 }
1551 } while (bh_pos += blocksize, (bh = bh->b_this_page) != head);
1552 /*
1553 * If all buffers are now uptodate but the page is not, set the
1554 * page uptodate.
1555 */
1556 if (!partial && !PageUptodate(page))
1557 SetPageUptodate(page);
1558 } while (++u < nr_pages);
1559 /*
1560 * Finally, if we do not need to update initialized_size or i_size we
1561 * are finished.
1562 */
1563 read_lock_irqsave(&ni->size_lock, flags);
1564 initialized_size = ni->initialized_size;
1565 read_unlock_irqrestore(&ni->size_lock, flags);
1566 if (end <= initialized_size) {
1567 ntfs_debug("Done.");
1568 return 0;
1569 }
1570 /*
1571 * Update initialized_size/i_size as appropriate, both in the inode and
1572 * the mft record.
1573 */
1574 if (!NInoAttr(ni))
1575 base_ni = ni;
1576 else
1577 base_ni = ni->ext.base_ntfs_ino;
1578 /* Map, pin, and lock the mft record. */
1579 m = map_mft_record(base_ni);
1580 if (IS_ERR(m)) {
1581 err = PTR_ERR(m);
1582 m = NULL;
1583 ctx = NULL;
1584 goto err_out;
1585 }
1586 BUG_ON(!NInoNonResident(ni));
1587 ctx = ntfs_attr_get_search_ctx(base_ni, m);
1588 if (unlikely(!ctx)) {
1589 err = -ENOMEM;
1590 goto err_out;
1591 }
1592 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
1593 CASE_SENSITIVE, 0, NULL, 0, ctx);
1594 if (unlikely(err)) {
1595 if (err == -ENOENT)
1596 err = -EIO;
1597 goto err_out;
1598 }
1599 a = ctx->attr;
1600 BUG_ON(!a->non_resident);
1601 write_lock_irqsave(&ni->size_lock, flags);
1602 BUG_ON(end > ni->allocated_size);
1603 ni->initialized_size = end;
1604 a->data.non_resident.initialized_size = cpu_to_sle64(end);
1605 if (end > i_size_read(vi)) {
1606 i_size_write(vi, end);
1607 a->data.non_resident.data_size =
1608 a->data.non_resident.initialized_size;
1609 }
1610 write_unlock_irqrestore(&ni->size_lock, flags);
1611 /* Mark the mft record dirty, so it gets written back. */
1612 flush_dcache_mft_record_page(ctx->ntfs_ino);
1613 mark_mft_record_dirty(ctx->ntfs_ino);
1614 ntfs_attr_put_search_ctx(ctx);
1615 unmap_mft_record(base_ni);
1616 ntfs_debug("Done.");
1617 return 0;
1618err_out:
1619 if (ctx)
1620 ntfs_attr_put_search_ctx(ctx);
1621 if (m)
1622 unmap_mft_record(base_ni);
1623 ntfs_error(vi->i_sb, "Failed to update initialized_size/i_size (error "
1624 "code %i).", err);
1625 if (err != -ENOMEM) {
1626 NVolSetErrors(ni->vol);
1627 make_bad_inode(VFS_I(base_ni));
1628 make_bad_inode(vi);
1629 }
1630 return err;
1631}
1632
1633/**
1634 * ntfs_commit_pages_after_write - commit the received data
1635 * @pages: array of destination pages
1636 * @nr_pages: number of pages in @pages
1637 * @pos: byte position in file at which the write begins
1638 * @bytes: number of bytes to be written
1639 *
1640 * This is called from ntfs_file_buffered_write() with i_sem held on the inode
1641 * (@pages[0]->mapping->host). There are @nr_pages pages in @pages which are
1642 * locked but not kmap()ped. The source data has already been copied into the
1643 * @page. ntfs_prepare_pages_for_non_resident_write() has been called before
1644 * the data was copied (for non-resident attributes only) and it returned
1645 * success.
1646 *
1647 * Need to set uptodate and mark dirty all buffers within the boundary of the
1648 * write. If all buffers in a page are uptodate we set the page uptodate, too.
1649 *
1650 * Setting the buffers dirty ensures that they get written out later when
1651 * ntfs_writepage() is invoked by the VM.
1652 *
1653 * Finally, we need to update i_size and initialized_size as appropriate both
1654 * in the inode and the mft record.
1655 *
1656 * This is modelled after fs/buffer.c::generic_commit_write(), which marks
1657 * buffers uptodate and dirty, sets the page uptodate if all buffers in the
1658 * page are uptodate, and updates i_size if the end of io is beyond i_size. In
1659 * that case, it also marks the inode dirty.
1660 *
1661 * If things have gone as outlined in
1662 * ntfs_prepare_pages_for_non_resident_write(), we do not need to do any page
1663 * content modifications here for non-resident attributes. For resident
1664 * attributes we need to do the uptodate bringing here which we combine with
1665 * the copying into the mft record which means we save one atomic kmap.
1666 *
1667 * Return 0 on success or -errno on error.
1668 */
1669static int ntfs_commit_pages_after_write(struct page **pages,
1670 const unsigned nr_pages, s64 pos, size_t bytes)
1671{
1672 s64 end, initialized_size;
1673 loff_t i_size;
1674 struct inode *vi;
1675 ntfs_inode *ni, *base_ni;
1676 struct page *page;
1677 ntfs_attr_search_ctx *ctx;
1678 MFT_RECORD *m;
1679 ATTR_RECORD *a;
1680 char *kattr, *kaddr;
1681 unsigned long flags;
1682 u32 attr_len;
1683 int err;
1684
1685 BUG_ON(!nr_pages);
1686 BUG_ON(!pages);
1687 page = pages[0];
1688 BUG_ON(!page);
1689 vi = page->mapping->host;
1690 ni = NTFS_I(vi);
1691 ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, start page "
1692 "index 0x%lx, nr_pages 0x%x, pos 0x%llx, bytes 0x%zx.",
1693 vi->i_ino, ni->type, page->index, nr_pages,
1694 (long long)pos, bytes);
1695 if (NInoNonResident(ni))
1696 return ntfs_commit_pages_after_non_resident_write(pages,
1697 nr_pages, pos, bytes);
1698 BUG_ON(nr_pages > 1);
1699 /*
1700 * Attribute is resident, implying it is not compressed, encrypted, or
1701 * sparse.
1702 */
1703 if (!NInoAttr(ni))
1704 base_ni = ni;
1705 else
1706 base_ni = ni->ext.base_ntfs_ino;
1707 BUG_ON(NInoNonResident(ni));
1708 /* Map, pin, and lock the mft record. */
1709 m = map_mft_record(base_ni);
1710 if (IS_ERR(m)) {
1711 err = PTR_ERR(m);
1712 m = NULL;
1713 ctx = NULL;
1714 goto err_out;
1715 }
1716 ctx = ntfs_attr_get_search_ctx(base_ni, m);
1717 if (unlikely(!ctx)) {
1718 err = -ENOMEM;
1719 goto err_out;
1720 }
1721 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
1722 CASE_SENSITIVE, 0, NULL, 0, ctx);
1723 if (unlikely(err)) {
1724 if (err == -ENOENT)
1725 err = -EIO;
1726 goto err_out;
1727 }
1728 a = ctx->attr;
1729 BUG_ON(a->non_resident);
1730 /* The total length of the attribute value. */
1731 attr_len = le32_to_cpu(a->data.resident.value_length);
1732 i_size = i_size_read(vi);
1733 BUG_ON(attr_len != i_size);
1734 BUG_ON(pos > attr_len);
1735 end = pos + bytes;
1736 BUG_ON(end > le32_to_cpu(a->length) -
1737 le16_to_cpu(a->data.resident.value_offset));
1738 kattr = (u8*)a + le16_to_cpu(a->data.resident.value_offset);
1739 kaddr = kmap_atomic(page, KM_USER0);
1740 /* Copy the received data from the page to the mft record. */
1741 memcpy(kattr + pos, kaddr + pos, bytes);
1742 /* Update the attribute length if necessary. */
1743 if (end > attr_len) {
1744 attr_len = end;
1745 a->data.resident.value_length = cpu_to_le32(attr_len);
1746 }
1747 /*
1748 * If the page is not uptodate, bring the out of bounds area(s)
1749 * uptodate by copying data from the mft record to the page.
1750 */
1751 if (!PageUptodate(page)) {
1752 if (pos > 0)
1753 memcpy(kaddr, kattr, pos);
1754 if (end < attr_len)
1755 memcpy(kaddr + end, kattr + end, attr_len - end);
1756 /* Zero the region outside the end of the attribute value. */
1757 memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len);
1758 flush_dcache_page(page);
1759 SetPageUptodate(page);
1760 }
1761 kunmap_atomic(kaddr, KM_USER0);
1762 /* Update initialized_size/i_size if necessary. */
1763 read_lock_irqsave(&ni->size_lock, flags);
1764 initialized_size = ni->initialized_size;
1765 BUG_ON(end > ni->allocated_size);
1766 read_unlock_irqrestore(&ni->size_lock, flags);
1767 BUG_ON(initialized_size != i_size);
1768 if (end > initialized_size) {
1769 unsigned long flags;
1770
1771 write_lock_irqsave(&ni->size_lock, flags);
1772 ni->initialized_size = end;
1773 i_size_write(vi, end);
1774 write_unlock_irqrestore(&ni->size_lock, flags);
1775 }
1776 /* Mark the mft record dirty, so it gets written back. */
1777 flush_dcache_mft_record_page(ctx->ntfs_ino);
1778 mark_mft_record_dirty(ctx->ntfs_ino);
1779 ntfs_attr_put_search_ctx(ctx);
1780 unmap_mft_record(base_ni);
1781 ntfs_debug("Done.");
1782 return 0;
1783err_out:
1784 if (err == -ENOMEM) {
1785 ntfs_warning(vi->i_sb, "Error allocating memory required to "
1786 "commit the write.");
1787 if (PageUptodate(page)) {
1788 ntfs_warning(vi->i_sb, "Page is uptodate, setting "
1789 "dirty so the write will be retried "
1790 "later on by the VM.");
1791 /*
1792 * Put the page on mapping->dirty_pages, but leave its
1793 * buffers' dirty state as-is.
1794 */
1795 __set_page_dirty_nobuffers(page);
1796 err = 0;
1797 } else
1798 ntfs_error(vi->i_sb, "Page is not uptodate. Written "
1799 "data has been lost.");
1800 } else {
1801 ntfs_error(vi->i_sb, "Resident attribute commit write failed "
1802 "with error %i.", err);
1803 NVolSetErrors(ni->vol);
1804 make_bad_inode(VFS_I(base_ni));
1805 make_bad_inode(vi);
1806 }
1807 if (ctx)
1808 ntfs_attr_put_search_ctx(ctx);
1809 if (m)
1810 unmap_mft_record(base_ni);
1811 return err;
1812}
1813
1814/**
1815 * ntfs_file_buffered_write -
1816 *
1817 * Locking: The vfs is holding ->i_sem on the inode.
1818 */
1819static ssize_t ntfs_file_buffered_write(struct kiocb *iocb,
1820 const struct iovec *iov, unsigned long nr_segs,
1821 loff_t pos, loff_t *ppos, size_t count)
1822{
1823 struct file *file = iocb->ki_filp;
1824 struct address_space *mapping = file->f_mapping;
1825 struct inode *vi = mapping->host;
1826 ntfs_inode *ni = NTFS_I(vi);
1827 ntfs_volume *vol = ni->vol;
1828 struct page *pages[NTFS_MAX_PAGES_PER_CLUSTER];
1829 struct page *cached_page = NULL;
1830 char __user *buf = NULL;
1831 s64 end, ll;
1832 VCN last_vcn;
1833 LCN lcn;
1834 unsigned long flags;
1835 size_t bytes, iov_ofs = 0; /* Offset in the current iovec. */
1836 ssize_t status, written;
1837 unsigned nr_pages;
1838 int err;
1839 struct pagevec lru_pvec;
1840
1841 ntfs_debug("Entering for i_ino 0x%lx, attribute type 0x%x, "
1842 "pos 0x%llx, count 0x%lx.",
1843 vi->i_ino, (unsigned)le32_to_cpu(ni->type),
1844 (unsigned long long)pos, (unsigned long)count);
1845 if (unlikely(!count))
1846 return 0;
1847 BUG_ON(NInoMstProtected(ni));
1848 /*
1849 * If the attribute is not an index root and it is encrypted or
1850 * compressed, we cannot write to it yet. Note we need to check for
1851 * AT_INDEX_ALLOCATION since this is the type of both directory and
1852 * index inodes.
1853 */
1854 if (ni->type != AT_INDEX_ALLOCATION) {
1855 /* If file is encrypted, deny access, just like NT4. */
1856 if (NInoEncrypted(ni)) {
1857 /*
1858 * Reminder for later: Encrypted files are _always_
1859 * non-resident so that the content can always be
1860 * encrypted.
1861 */
1862 ntfs_debug("Denying write access to encrypted file.");
1863 return -EACCES;
1864 }
1865 if (NInoCompressed(ni)) {
1866 /* Only unnamed $DATA attribute can be compressed. */
1867 BUG_ON(ni->type != AT_DATA);
1868 BUG_ON(ni->name_len);
1869 /*
1870 * Reminder for later: If resident, the data is not
1871 * actually compressed. Only on the switch to non-
1872 * resident does compression kick in. This is in
1873 * contrast to encrypted files (see above).
1874 */
1875 ntfs_error(vi->i_sb, "Writing to compressed files is "
1876 "not implemented yet. Sorry.");
1877 return -EOPNOTSUPP;
1878 }
1879 }
1880 /*
1881 * If a previous ntfs_truncate() failed, repeat it and abort if it
1882 * fails again.
1883 */
1884 if (unlikely(NInoTruncateFailed(ni))) {
1885 down_write(&vi->i_alloc_sem);
1886 err = ntfs_truncate(vi);
1887 up_write(&vi->i_alloc_sem);
1888 if (err || NInoTruncateFailed(ni)) {
1889 if (!err)
1890 err = -EIO;
1891 ntfs_error(vol->sb, "Cannot perform write to inode "
1892 "0x%lx, attribute type 0x%x, because "
1893 "ntfs_truncate() failed (error code "
1894 "%i).", vi->i_ino,
1895 (unsigned)le32_to_cpu(ni->type), err);
1896 return err;
1897 }
1898 }
1899 /* The first byte after the write. */
1900 end = pos + count;
1901 /*
1902 * If the write goes beyond the allocated size, extend the allocation
1903 * to cover the whole of the write, rounded up to the nearest cluster.
1904 */
1905 read_lock_irqsave(&ni->size_lock, flags);
1906 ll = ni->allocated_size;
1907 read_unlock_irqrestore(&ni->size_lock, flags);
1908 if (end > ll) {
1909 /* Extend the allocation without changing the data size. */
1910 ll = ntfs_attr_extend_allocation(ni, end, -1, pos);
1911 if (likely(ll >= 0)) {
1912 BUG_ON(pos >= ll);
1913 /* If the extension was partial truncate the write. */
1914 if (end > ll) {
1915 ntfs_debug("Truncating write to inode 0x%lx, "
1916 "attribute type 0x%x, because "
1917 "the allocation was only "
1918 "partially extended.",
1919 vi->i_ino, (unsigned)
1920 le32_to_cpu(ni->type));
1921 end = ll;
1922 count = ll - pos;
1923 }
1924 } else {
1925 err = ll;
1926 read_lock_irqsave(&ni->size_lock, flags);
1927 ll = ni->allocated_size;
1928 read_unlock_irqrestore(&ni->size_lock, flags);
1929 /* Perform a partial write if possible or fail. */
1930 if (pos < ll) {
1931 ntfs_debug("Truncating write to inode 0x%lx, "
1932 "attribute type 0x%x, because "
1933 "extending the allocation "
1934 "failed (error code %i).",
1935 vi->i_ino, (unsigned)
1936 le32_to_cpu(ni->type), err);
1937 end = ll;
1938 count = ll - pos;
1939 } else {
1940 ntfs_error(vol->sb, "Cannot perform write to "
1941 "inode 0x%lx, attribute type "
1942 "0x%x, because extending the "
1943 "allocation failed (error "
1944 "code %i).", vi->i_ino,
1945 (unsigned)
1946 le32_to_cpu(ni->type), err);
1947 return err;
1948 }
1949 }
1950 }
1951 pagevec_init(&lru_pvec, 0);
1952 written = 0;
1953 /*
1954 * If the write starts beyond the initialized size, extend it up to the
1955 * beginning of the write and initialize all non-sparse space between
1956 * the old initialized size and the new one. This automatically also
1957 * increments the vfs inode->i_size to keep it above or equal to the
1958 * initialized_size.
1959 */
1960 read_lock_irqsave(&ni->size_lock, flags);
1961 ll = ni->initialized_size;
1962 read_unlock_irqrestore(&ni->size_lock, flags);
1963 if (pos > ll) {
1964 err = ntfs_attr_extend_initialized(ni, pos, &cached_page,
1965 &lru_pvec);
1966 if (err < 0) {
1967 ntfs_error(vol->sb, "Cannot perform write to inode "
1968 "0x%lx, attribute type 0x%x, because "
1969 "extending the initialized size "
1970 "failed (error code %i).", vi->i_ino,
1971 (unsigned)le32_to_cpu(ni->type), err);
1972 status = err;
1973 goto err_out;
1974 }
1975 }
1976 /*
1977 * Determine the number of pages per cluster for non-resident
1978 * attributes.
1979 */
1980 nr_pages = 1;
1981 if (vol->cluster_size > PAGE_CACHE_SIZE && NInoNonResident(ni))
1982 nr_pages = vol->cluster_size >> PAGE_CACHE_SHIFT;
1983 /* Finally, perform the actual write. */
1984 last_vcn = -1;
1985 if (likely(nr_segs == 1))
1986 buf = iov->iov_base;
1987 do {
1988 VCN vcn;
1989 pgoff_t idx, start_idx;
1990 unsigned ofs, do_pages, u;
1991 size_t copied;
1992
1993 start_idx = idx = pos >> PAGE_CACHE_SHIFT;
1994 ofs = pos & ~PAGE_CACHE_MASK;
1995 bytes = PAGE_CACHE_SIZE - ofs;
1996 do_pages = 1;
1997 if (nr_pages > 1) {
1998 vcn = pos >> vol->cluster_size_bits;
1999 if (vcn != last_vcn) {
2000 last_vcn = vcn;
2001 /*
2002 * Get the lcn of the vcn the write is in. If
2003 * it is a hole, need to lock down all pages in
2004 * the cluster.
2005 */
2006 down_read(&ni->runlist.lock);
2007 lcn = ntfs_attr_vcn_to_lcn_nolock(ni, pos >>
2008 vol->cluster_size_bits, FALSE);
2009 up_read(&ni->runlist.lock);
2010 if (unlikely(lcn < LCN_HOLE)) {
2011 status = -EIO;
2012 if (lcn == LCN_ENOMEM)
2013 status = -ENOMEM;
2014 else
2015 ntfs_error(vol->sb, "Cannot "
2016 "perform write to "
2017 "inode 0x%lx, "
2018 "attribute type 0x%x, "
2019 "because the attribute "
2020 "is corrupt.",
2021 vi->i_ino, (unsigned)
2022 le32_to_cpu(ni->type));
2023 break;
2024 }
2025 if (lcn == LCN_HOLE) {
2026 start_idx = (pos & ~(s64)
2027 vol->cluster_size_mask)
2028 >> PAGE_CACHE_SHIFT;
2029 bytes = vol->cluster_size - (pos &
2030 vol->cluster_size_mask);
2031 do_pages = nr_pages;
2032 }
2033 }
2034 }
2035 if (bytes > count)
2036 bytes = count;
2037 /*
2038 * Bring in the user page(s) that we will copy from _first_.
2039 * Otherwise there is a nasty deadlock on copying from the same
2040 * page(s) as we are writing to, without it/them being marked
2041 * up-to-date. Note, at present there is nothing to stop the
2042 * pages being swapped out between us bringing them into memory
2043 * and doing the actual copying.
2044 */
2045 if (likely(nr_segs == 1))
2046 ntfs_fault_in_pages_readable(buf, bytes);
2047 else
2048 ntfs_fault_in_pages_readable_iovec(iov, iov_ofs, bytes);
2049 /* Get and lock @do_pages starting at index @start_idx. */
2050 status = __ntfs_grab_cache_pages(mapping, start_idx, do_pages,
2051 pages, &cached_page, &lru_pvec);
2052 if (unlikely(status))
2053 break;
2054 /*
2055 * For non-resident attributes, we need to fill any holes with
2056 * actual clusters and ensure all bufferes are mapped. We also
2057 * need to bring uptodate any buffers that are only partially
2058 * being written to.
2059 */
2060 if (NInoNonResident(ni)) {
2061 status = ntfs_prepare_pages_for_non_resident_write(
2062 pages, do_pages, pos, bytes);
2063 if (unlikely(status)) {
2064 loff_t i_size;
2065
2066 do {
2067 unlock_page(pages[--do_pages]);
2068 page_cache_release(pages[do_pages]);
2069 } while (do_pages);
2070 /*
2071 * The write preparation may have instantiated
2072 * allocated space outside i_size. Trim this
2073 * off again. We can ignore any errors in this
2074 * case as we will just be waisting a bit of
2075 * allocated space, which is not a disaster.
2076 */
2077 i_size = i_size_read(vi);
2078 if (pos + bytes > i_size)
2079 vmtruncate(vi, i_size);
2080 break;
2081 }
2082 }
2083 u = (pos >> PAGE_CACHE_SHIFT) - pages[0]->index;
2084 if (likely(nr_segs == 1)) {
2085 copied = ntfs_copy_from_user(pages + u, do_pages - u,
2086 ofs, buf, bytes);
2087 buf += copied;
2088 } else
2089 copied = ntfs_copy_from_user_iovec(pages + u,
2090 do_pages - u, ofs, &iov, &iov_ofs,
2091 bytes);
2092 ntfs_flush_dcache_pages(pages + u, do_pages - u);
2093 status = ntfs_commit_pages_after_write(pages, do_pages, pos,
2094 bytes);
2095 if (likely(!status)) {
2096 written += copied;
2097 count -= copied;
2098 pos += copied;
2099 if (unlikely(copied != bytes))
2100 status = -EFAULT;
2101 }
2102 do {
2103 unlock_page(pages[--do_pages]);
2104 mark_page_accessed(pages[do_pages]);
2105 page_cache_release(pages[do_pages]);
2106 } while (do_pages);
2107 if (unlikely(status))
2108 break;
2109 balance_dirty_pages_ratelimited(mapping);
2110 cond_resched();
2111 } while (count);
2112err_out:
2113 *ppos = pos;
2114 if (cached_page)
2115 page_cache_release(cached_page);
2116 /* For now, when the user asks for O_SYNC, we actually give O_DSYNC. */
2117 if (likely(!status)) {
2118 if (unlikely((file->f_flags & O_SYNC) || IS_SYNC(vi))) {
2119 if (!mapping->a_ops->writepage || !is_sync_kiocb(iocb))
2120 status = generic_osync_inode(vi, mapping,
2121 OSYNC_METADATA|OSYNC_DATA);
2122 }
2123 }
2124 pagevec_lru_add(&lru_pvec);
2125 ntfs_debug("Done. Returning %s (written 0x%lx, status %li).",
2126 written ? "written" : "status", (unsigned long)written,
2127 (long)status);
2128 return written ? written : status;
2129}
2130
2131/**
2132 * ntfs_file_aio_write_nolock -
2133 */
2134static ssize_t ntfs_file_aio_write_nolock(struct kiocb *iocb,
2135 const struct iovec *iov, unsigned long nr_segs, loff_t *ppos)
2136{
2137 struct file *file = iocb->ki_filp;
2138 struct address_space *mapping = file->f_mapping;
2139 struct inode *inode = mapping->host;
2140 loff_t pos;
2141 unsigned long seg;
2142 size_t count; /* after file limit checks */
2143 ssize_t written, err;
2144
2145 count = 0;
2146 for (seg = 0; seg < nr_segs; seg++) {
2147 const struct iovec *iv = &iov[seg];
2148 /*
2149 * If any segment has a negative length, or the cumulative
2150 * length ever wraps negative then return -EINVAL.
2151 */
2152 count += iv->iov_len;
2153 if (unlikely((ssize_t)(count|iv->iov_len) < 0))
2154 return -EINVAL;
2155 if (access_ok(VERIFY_READ, iv->iov_base, iv->iov_len))
2156 continue;
2157 if (!seg)
2158 return -EFAULT;
2159 nr_segs = seg;
2160 count -= iv->iov_len; /* This segment is no good */
2161 break;
2162 }
2163 pos = *ppos;
2164 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
2165 /* We can write back this queue in page reclaim. */
2166 current->backing_dev_info = mapping->backing_dev_info;
2167 written = 0;
2168 err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
2169 if (err)
2170 goto out;
2171 if (!count)
2172 goto out;
2173 err = remove_suid(file->f_dentry);
2174 if (err)
2175 goto out;
2176 inode_update_time(inode, 1);
2177 written = ntfs_file_buffered_write(iocb, iov, nr_segs, pos, ppos,
2178 count);
2179out:
2180 current->backing_dev_info = NULL;
2181 return written ? written : err;
2182}
2183
2184/**
2185 * ntfs_file_aio_write -
2186 */
2187static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const char __user *buf,
2188 size_t count, loff_t pos)
2189{
2190 struct file *file = iocb->ki_filp;
2191 struct address_space *mapping = file->f_mapping;
2192 struct inode *inode = mapping->host;
2193 ssize_t ret;
2194 struct iovec local_iov = { .iov_base = (void __user *)buf,
2195 .iov_len = count };
2196
2197 BUG_ON(iocb->ki_pos != pos);
2198
2199 down(&inode->i_sem);
2200 ret = ntfs_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos);
2201 up(&inode->i_sem);
2202 if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
2203 int err = sync_page_range(inode, mapping, pos, ret);
2204 if (err < 0)
2205 ret = err;
2206 }
2207 return ret;
2208}
2209
2210/**
2211 * ntfs_file_writev -
2212 *
2213 * Basically the same as generic_file_writev() except that it ends up calling
2214 * ntfs_file_aio_write_nolock() instead of __generic_file_aio_write_nolock().
2215 */
2216static ssize_t ntfs_file_writev(struct file *file, const struct iovec *iov,
2217 unsigned long nr_segs, loff_t *ppos)
2218{
2219 struct address_space *mapping = file->f_mapping;
2220 struct inode *inode = mapping->host;
2221 struct kiocb kiocb;
2222 ssize_t ret;
2223
2224 down(&inode->i_sem);
2225 init_sync_kiocb(&kiocb, file);
2226 ret = ntfs_file_aio_write_nolock(&kiocb, iov, nr_segs, ppos);
2227 if (ret == -EIOCBQUEUED)
2228 ret = wait_on_sync_kiocb(&kiocb);
2229 up(&inode->i_sem);
2230 if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
2231 int err = sync_page_range(inode, mapping, *ppos - ret, ret);
2232 if (err < 0)
2233 ret = err;
2234 }
2235 return ret;
2236}
2237
2238/**
2239 * ntfs_file_write - simple wrapper for ntfs_file_writev()
2240 */
2241static ssize_t ntfs_file_write(struct file *file, const char __user *buf,
2242 size_t count, loff_t *ppos)
2243{
2244 struct iovec local_iov = { .iov_base = (void __user *)buf,
2245 .iov_len = count };
2246
2247 return ntfs_file_writev(file, &local_iov, 1, ppos);
2248}
2249
2250/**
59 * ntfs_file_fsync - sync a file to disk 2251 * ntfs_file_fsync - sync a file to disk
60 * @filp: file to be synced 2252 * @filp: file to be synced
61 * @dentry: dentry describing the file to sync 2253 * @dentry: dentry describing the file to sync
@@ -113,39 +2305,39 @@ static int ntfs_file_fsync(struct file *filp, struct dentry *dentry,
113#endif /* NTFS_RW */ 2305#endif /* NTFS_RW */
114 2306
115struct file_operations ntfs_file_ops = { 2307struct file_operations ntfs_file_ops = {
116 .llseek = generic_file_llseek, /* Seek inside file. */ 2308 .llseek = generic_file_llseek, /* Seek inside file. */
117 .read = generic_file_read, /* Read from file. */ 2309 .read = generic_file_read, /* Read from file. */
118 .aio_read = generic_file_aio_read, /* Async read from file. */ 2310 .aio_read = generic_file_aio_read, /* Async read from file. */
119 .readv = generic_file_readv, /* Read from file. */ 2311 .readv = generic_file_readv, /* Read from file. */
120#ifdef NTFS_RW 2312#ifdef NTFS_RW
121 .write = generic_file_write, /* Write to file. */ 2313 .write = ntfs_file_write, /* Write to file. */
122 .aio_write = generic_file_aio_write, /* Async write to file. */ 2314 .aio_write = ntfs_file_aio_write, /* Async write to file. */
123 .writev = generic_file_writev, /* Write to file. */ 2315 .writev = ntfs_file_writev, /* Write to file. */
124 /*.release = ,*/ /* Last file is closed. See 2316 /*.release = ,*/ /* Last file is closed. See
125 fs/ext2/file.c:: 2317 fs/ext2/file.c::
126 ext2_release_file() for 2318 ext2_release_file() for
127 how to use this to discard 2319 how to use this to discard
128 preallocated space for 2320 preallocated space for
129 write opened files. */ 2321 write opened files. */
130 .fsync = ntfs_file_fsync, /* Sync a file to disk. */ 2322 .fsync = ntfs_file_fsync, /* Sync a file to disk. */
131 /*.aio_fsync = ,*/ /* Sync all outstanding async 2323 /*.aio_fsync = ,*/ /* Sync all outstanding async
132 i/o operations on a 2324 i/o operations on a
133 kiocb. */ 2325 kiocb. */
134#endif /* NTFS_RW */ 2326#endif /* NTFS_RW */
135 /*.ioctl = ,*/ /* Perform function on the 2327 /*.ioctl = ,*/ /* Perform function on the
136 mounted filesystem. */ 2328 mounted filesystem. */
137 .mmap = generic_file_mmap, /* Mmap file. */ 2329 .mmap = generic_file_mmap, /* Mmap file. */
138 .open = ntfs_file_open, /* Open file. */ 2330 .open = ntfs_file_open, /* Open file. */
139 .sendfile = generic_file_sendfile, /* Zero-copy data send with 2331 .sendfile = generic_file_sendfile, /* Zero-copy data send with
140 the data source being on 2332 the data source being on
141 the ntfs partition. We 2333 the ntfs partition. We do
142 do not need to care about 2334 not need to care about the
143 the data destination. */ 2335 data destination. */
144 /*.sendpage = ,*/ /* Zero-copy data send with 2336 /*.sendpage = ,*/ /* Zero-copy data send with
145 the data destination being 2337 the data destination being
146 on the ntfs partition. We 2338 on the ntfs partition. We
147 do not need to care about 2339 do not need to care about
148 the data source. */ 2340 the data source. */
149}; 2341};
150 2342
151struct inode_operations ntfs_file_inode_ops = { 2343struct inode_operations ntfs_file_inode_ops = {
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 7ec045131808..b24f4c4b2c5c 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -30,6 +30,7 @@
30#include "debug.h" 30#include "debug.h"
31#include "inode.h" 31#include "inode.h"
32#include "attrib.h" 32#include "attrib.h"
33#include "lcnalloc.h"
33#include "malloc.h" 34#include "malloc.h"
34#include "mft.h" 35#include "mft.h"
35#include "time.h" 36#include "time.h"
@@ -2291,11 +2292,16 @@ int ntfs_show_options(struct seq_file *sf, struct vfsmount *mnt)
2291 2292
2292#ifdef NTFS_RW 2293#ifdef NTFS_RW
2293 2294
2295static const char *es = " Leaving inconsistent metadata. Unmount and run "
2296 "chkdsk.";
2297
2294/** 2298/**
2295 * ntfs_truncate - called when the i_size of an ntfs inode is changed 2299 * ntfs_truncate - called when the i_size of an ntfs inode is changed
2296 * @vi: inode for which the i_size was changed 2300 * @vi: inode for which the i_size was changed
2297 * 2301 *
2298 * We do not support i_size changes yet. 2302 * We only support i_size changes for normal files at present, i.e. not
2303 * compressed and not encrypted. This is enforced in ntfs_setattr(), see
2304 * below.
2299 * 2305 *
2300 * The kernel guarantees that @vi is a regular file (S_ISREG() is true) and 2306 * The kernel guarantees that @vi is a regular file (S_ISREG() is true) and
2301 * that the change is allowed. 2307 * that the change is allowed.
@@ -2306,80 +2312,499 @@ int ntfs_show_options(struct seq_file *sf, struct vfsmount *mnt)
2306 * Returns 0 on success or -errno on error. 2312 * Returns 0 on success or -errno on error.
2307 * 2313 *
2308 * Called with ->i_sem held. In all but one case ->i_alloc_sem is held for 2314 * Called with ->i_sem held. In all but one case ->i_alloc_sem is held for
2309 * writing. The only case where ->i_alloc_sem is not held is 2315 * writing. The only case in the kernel where ->i_alloc_sem is not held is
2310 * mm/filemap.c::generic_file_buffered_write() where vmtruncate() is called 2316 * mm/filemap.c::generic_file_buffered_write() where vmtruncate() is called
2311 * with the current i_size as the offset which means that it is a noop as far 2317 * with the current i_size as the offset. The analogous place in NTFS is in
2312 * as ntfs_truncate() is concerned. 2318 * fs/ntfs/file.c::ntfs_file_buffered_write() where we call vmtruncate() again
2319 * without holding ->i_alloc_sem.
2313 */ 2320 */
2314int ntfs_truncate(struct inode *vi) 2321int ntfs_truncate(struct inode *vi)
2315{ 2322{
2316 ntfs_inode *ni = NTFS_I(vi); 2323 s64 new_size, old_size, nr_freed, new_alloc_size, old_alloc_size;
2324 VCN highest_vcn;
2325 unsigned long flags;
2326 ntfs_inode *base_ni, *ni = NTFS_I(vi);
2317 ntfs_volume *vol = ni->vol; 2327 ntfs_volume *vol = ni->vol;
2318 ntfs_attr_search_ctx *ctx; 2328 ntfs_attr_search_ctx *ctx;
2319 MFT_RECORD *m; 2329 MFT_RECORD *m;
2320 ATTR_RECORD *a; 2330 ATTR_RECORD *a;
2321 const char *te = " Leaving file length out of sync with i_size."; 2331 const char *te = " Leaving file length out of sync with i_size.";
2322 int err; 2332 int err, mp_size, size_change, alloc_change;
2333 u32 attr_len;
2323 2334
2324 ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); 2335 ntfs_debug("Entering for inode 0x%lx.", vi->i_ino);
2325 BUG_ON(NInoAttr(ni)); 2336 BUG_ON(NInoAttr(ni));
2337 BUG_ON(S_ISDIR(vi->i_mode));
2338 BUG_ON(NInoMstProtected(ni));
2326 BUG_ON(ni->nr_extents < 0); 2339 BUG_ON(ni->nr_extents < 0);
2327 m = map_mft_record(ni); 2340retry_truncate:
2341 /*
2342 * Lock the runlist for writing and map the mft record to ensure it is
2343 * safe to mess with the attribute runlist and sizes.
2344 */
2345 down_write(&ni->runlist.lock);
2346 if (!NInoAttr(ni))
2347 base_ni = ni;
2348 else
2349 base_ni = ni->ext.base_ntfs_ino;
2350 m = map_mft_record(base_ni);
2328 if (IS_ERR(m)) { 2351 if (IS_ERR(m)) {
2329 err = PTR_ERR(m); 2352 err = PTR_ERR(m);
2330 ntfs_error(vi->i_sb, "Failed to map mft record for inode 0x%lx " 2353 ntfs_error(vi->i_sb, "Failed to map mft record for inode 0x%lx "
2331 "(error code %d).%s", vi->i_ino, err, te); 2354 "(error code %d).%s", vi->i_ino, err, te);
2332 ctx = NULL; 2355 ctx = NULL;
2333 m = NULL; 2356 m = NULL;
2334 goto err_out; 2357 goto old_bad_out;
2335 } 2358 }
2336 ctx = ntfs_attr_get_search_ctx(ni, m); 2359 ctx = ntfs_attr_get_search_ctx(base_ni, m);
2337 if (unlikely(!ctx)) { 2360 if (unlikely(!ctx)) {
2338 ntfs_error(vi->i_sb, "Failed to allocate a search context for " 2361 ntfs_error(vi->i_sb, "Failed to allocate a search context for "
2339 "inode 0x%lx (not enough memory).%s", 2362 "inode 0x%lx (not enough memory).%s",
2340 vi->i_ino, te); 2363 vi->i_ino, te);
2341 err = -ENOMEM; 2364 err = -ENOMEM;
2342 goto err_out; 2365 goto old_bad_out;
2343 } 2366 }
2344 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, 2367 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
2345 CASE_SENSITIVE, 0, NULL, 0, ctx); 2368 CASE_SENSITIVE, 0, NULL, 0, ctx);
2346 if (unlikely(err)) { 2369 if (unlikely(err)) {
2347 if (err == -ENOENT) 2370 if (err == -ENOENT) {
2348 ntfs_error(vi->i_sb, "Open attribute is missing from " 2371 ntfs_error(vi->i_sb, "Open attribute is missing from "
2349 "mft record. Inode 0x%lx is corrupt. " 2372 "mft record. Inode 0x%lx is corrupt. "
2350 "Run chkdsk.", vi->i_ino); 2373 "Run chkdsk.%s", vi->i_ino, te);
2351 else 2374 err = -EIO;
2375 } else
2352 ntfs_error(vi->i_sb, "Failed to lookup attribute in " 2376 ntfs_error(vi->i_sb, "Failed to lookup attribute in "
2353 "inode 0x%lx (error code %d).", 2377 "inode 0x%lx (error code %d).%s",
2354 vi->i_ino, err); 2378 vi->i_ino, err, te);
2355 goto err_out; 2379 goto old_bad_out;
2356 } 2380 }
2381 m = ctx->mrec;
2357 a = ctx->attr; 2382 a = ctx->attr;
2358 /* If the size has not changed there is nothing to do. */ 2383 /*
2359 if (ntfs_attr_size(a) == i_size_read(vi)) 2384 * The i_size of the vfs inode is the new size for the attribute value.
2360 goto done; 2385 */
2361 // TODO: Implement the truncate... 2386 new_size = i_size_read(vi);
2362 ntfs_error(vi->i_sb, "Inode size has changed but this is not " 2387 /* The current size of the attribute value is the old size. */
2363 "implemented yet. Resetting inode size to old value. " 2388 old_size = ntfs_attr_size(a);
2364 " This is most likely a bug in the ntfs driver!"); 2389 /* Calculate the new allocated size. */
2365 i_size_write(vi, ntfs_attr_size(a)); 2390 if (NInoNonResident(ni))
2366done: 2391 new_alloc_size = (new_size + vol->cluster_size - 1) &
2392 ~(s64)vol->cluster_size_mask;
2393 else
2394 new_alloc_size = (new_size + 7) & ~7;
2395 /* The current allocated size is the old allocated size. */
2396 read_lock_irqsave(&ni->size_lock, flags);
2397 old_alloc_size = ni->allocated_size;
2398 read_unlock_irqrestore(&ni->size_lock, flags);
2399 /*
2400 * The change in the file size. This will be 0 if no change, >0 if the
2401 * size is growing, and <0 if the size is shrinking.
2402 */
2403 size_change = -1;
2404 if (new_size - old_size >= 0) {
2405 size_change = 1;
2406 if (new_size == old_size)
2407 size_change = 0;
2408 }
2409 /* As above for the allocated size. */
2410 alloc_change = -1;
2411 if (new_alloc_size - old_alloc_size >= 0) {
2412 alloc_change = 1;
2413 if (new_alloc_size == old_alloc_size)
2414 alloc_change = 0;
2415 }
2416 /*
2417 * If neither the size nor the allocation are being changed there is
2418 * nothing to do.
2419 */
2420 if (!size_change && !alloc_change)
2421 goto unm_done;
2422 /* If the size is changing, check if new size is allowed in $AttrDef. */
2423 if (size_change) {
2424 err = ntfs_attr_size_bounds_check(vol, ni->type, new_size);
2425 if (unlikely(err)) {
2426 if (err == -ERANGE) {
2427 ntfs_error(vol->sb, "Truncate would cause the "
2428 "inode 0x%lx to %simum size "
2429 "for its attribute type "
2430 "(0x%x). Aborting truncate.",
2431 vi->i_ino,
2432 new_size > old_size ? "exceed "
2433 "the max" : "go under the min",
2434 le32_to_cpu(ni->type));
2435 err = -EFBIG;
2436 } else {
2437 ntfs_error(vol->sb, "Inode 0x%lx has unknown "
2438 "attribute type 0x%x. "
2439 "Aborting truncate.",
2440 vi->i_ino,
2441 le32_to_cpu(ni->type));
2442 err = -EIO;
2443 }
2444 /* Reset the vfs inode size to the old size. */
2445 i_size_write(vi, old_size);
2446 goto err_out;
2447 }
2448 }
2449 if (NInoCompressed(ni) || NInoEncrypted(ni)) {
2450 ntfs_warning(vi->i_sb, "Changes in inode size are not "
2451 "supported yet for %s files, ignoring.",
2452 NInoCompressed(ni) ? "compressed" :
2453 "encrypted");
2454 err = -EOPNOTSUPP;
2455 goto bad_out;
2456 }
2457 if (a->non_resident)
2458 goto do_non_resident_truncate;
2459 BUG_ON(NInoNonResident(ni));
2460 /* Resize the attribute record to best fit the new attribute size. */
2461 if (new_size < vol->mft_record_size &&
2462 !ntfs_resident_attr_value_resize(m, a, new_size)) {
2463 unsigned long flags;
2464
2465 /* The resize succeeded! */
2466 flush_dcache_mft_record_page(ctx->ntfs_ino);
2467 mark_mft_record_dirty(ctx->ntfs_ino);
2468 write_lock_irqsave(&ni->size_lock, flags);
2469 /* Update the sizes in the ntfs inode and all is done. */
2470 ni->allocated_size = le32_to_cpu(a->length) -
2471 le16_to_cpu(a->data.resident.value_offset);
2472 /*
2473 * Note ntfs_resident_attr_value_resize() has already done any
2474 * necessary data clearing in the attribute record. When the
2475 * file is being shrunk vmtruncate() will already have cleared
2476 * the top part of the last partial page, i.e. since this is
2477 * the resident case this is the page with index 0. However,
2478 * when the file is being expanded, the page cache page data
2479 * between the old data_size, i.e. old_size, and the new_size
2480 * has not been zeroed. Fortunately, we do not need to zero it
2481 * either since on one hand it will either already be zero due
2482 * to both readpage and writepage clearing partial page data
2483 * beyond i_size in which case there is nothing to do or in the
2484 * case of the file being mmap()ped at the same time, POSIX
2485 * specifies that the behaviour is unspecified thus we do not
2486 * have to do anything. This means that in our implementation
2487 * in the rare case that the file is mmap()ped and a write
2488 * occured into the mmap()ped region just beyond the file size
2489 * and writepage has not yet been called to write out the page
2490 * (which would clear the area beyond the file size) and we now
2491 * extend the file size to incorporate this dirty region
2492 * outside the file size, a write of the page would result in
2493 * this data being written to disk instead of being cleared.
2494 * Given both POSIX and the Linux mmap(2) man page specify that
2495 * this corner case is undefined, we choose to leave it like
2496 * that as this is much simpler for us as we cannot lock the
2497 * relevant page now since we are holding too many ntfs locks
2498 * which would result in a lock reversal deadlock.
2499 */
2500 ni->initialized_size = new_size;
2501 write_unlock_irqrestore(&ni->size_lock, flags);
2502 goto unm_done;
2503 }
2504 /* If the above resize failed, this must be an attribute extension. */
2505 BUG_ON(size_change < 0);
2506 /*
2507 * We have to drop all the locks so we can call
2508 * ntfs_attr_make_non_resident(). This could be optimised by try-
2509 * locking the first page cache page and only if that fails dropping
2510 * the locks, locking the page, and redoing all the locking and
2511 * lookups. While this would be a huge optimisation, it is not worth
2512 * it as this is definitely a slow code path as it only ever can happen
2513 * once for any given file.
2514 */
2367 ntfs_attr_put_search_ctx(ctx); 2515 ntfs_attr_put_search_ctx(ctx);
2368 unmap_mft_record(ni); 2516 unmap_mft_record(base_ni);
2369 NInoClearTruncateFailed(ni); 2517 up_write(&ni->runlist.lock);
2370 ntfs_debug("Done."); 2518 /*
2371 return 0; 2519 * Not enough space in the mft record, try to make the attribute
2372err_out: 2520 * non-resident and if successful restart the truncation process.
2373 if (err != -ENOMEM) { 2521 */
2522 err = ntfs_attr_make_non_resident(ni, old_size);
2523 if (likely(!err))
2524 goto retry_truncate;
2525 /*
2526 * Could not make non-resident. If this is due to this not being
2527 * permitted for this attribute type or there not being enough space,
2528 * try to make other attributes non-resident. Otherwise fail.
2529 */
2530 if (unlikely(err != -EPERM && err != -ENOSPC)) {
2531 ntfs_error(vol->sb, "Cannot truncate inode 0x%lx, attribute "
2532 "type 0x%x, because the conversion from "
2533 "resident to non-resident attribute failed "
2534 "with error code %i.", vi->i_ino,
2535 (unsigned)le32_to_cpu(ni->type), err);
2536 if (err != -ENOMEM)
2537 err = -EIO;
2538 goto conv_err_out;
2539 }
2540 /* TODO: Not implemented from here, abort. */
2541 if (err == -ENOSPC)
2542 ntfs_error(vol->sb, "Not enough space in the mft record/on "
2543 "disk for the non-resident attribute value. "
2544 "This case is not implemented yet.");
2545 else /* if (err == -EPERM) */
2546 ntfs_error(vol->sb, "This attribute type may not be "
2547 "non-resident. This case is not implemented "
2548 "yet.");
2549 err = -EOPNOTSUPP;
2550 goto conv_err_out;
2551#if 0
2552 // TODO: Attempt to make other attributes non-resident.
2553 if (!err)
2554 goto do_resident_extend;
2555 /*
2556 * Both the attribute list attribute and the standard information
2557 * attribute must remain in the base inode. Thus, if this is one of
2558 * these attributes, we have to try to move other attributes out into
2559 * extent mft records instead.
2560 */
2561 if (ni->type == AT_ATTRIBUTE_LIST ||
2562 ni->type == AT_STANDARD_INFORMATION) {
2563 // TODO: Attempt to move other attributes into extent mft
2564 // records.
2565 err = -EOPNOTSUPP;
2566 if (!err)
2567 goto do_resident_extend;
2568 goto err_out;
2569 }
2570 // TODO: Attempt to move this attribute to an extent mft record, but
2571 // only if it is not already the only attribute in an mft record in
2572 // which case there would be nothing to gain.
2573 err = -EOPNOTSUPP;
2574 if (!err)
2575 goto do_resident_extend;
2576 /* There is nothing we can do to make enough space. )-: */
2577 goto err_out;
2578#endif
2579do_non_resident_truncate:
2580 BUG_ON(!NInoNonResident(ni));
2581 if (alloc_change < 0) {
2582 highest_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn);
2583 if (highest_vcn > 0 &&
2584 old_alloc_size >> vol->cluster_size_bits >
2585 highest_vcn + 1) {
2586 /*
2587 * This attribute has multiple extents. Not yet
2588 * supported.
2589 */
2590 ntfs_error(vol->sb, "Cannot truncate inode 0x%lx, "
2591 "attribute type 0x%x, because the "
2592 "attribute is highly fragmented (it "
2593 "consists of multiple extents) and "
2594 "this case is not implemented yet.",
2595 vi->i_ino,
2596 (unsigned)le32_to_cpu(ni->type));
2597 err = -EOPNOTSUPP;
2598 goto bad_out;
2599 }
2600 }
2601 /*
2602 * If the size is shrinking, need to reduce the initialized_size and
2603 * the data_size before reducing the allocation.
2604 */
2605 if (size_change < 0) {
2606 /*
2607 * Make the valid size smaller (i_size is already up-to-date).
2608 */
2609 write_lock_irqsave(&ni->size_lock, flags);
2610 if (new_size < ni->initialized_size) {
2611 ni->initialized_size = new_size;
2612 a->data.non_resident.initialized_size =
2613 cpu_to_sle64(new_size);
2614 }
2615 a->data.non_resident.data_size = cpu_to_sle64(new_size);
2616 write_unlock_irqrestore(&ni->size_lock, flags);
2617 flush_dcache_mft_record_page(ctx->ntfs_ino);
2618 mark_mft_record_dirty(ctx->ntfs_ino);
2619 /* If the allocated size is not changing, we are done. */
2620 if (!alloc_change)
2621 goto unm_done;
2622 /*
2623 * If the size is shrinking it makes no sense for the
2624 * allocation to be growing.
2625 */
2626 BUG_ON(alloc_change > 0);
2627 } else /* if (size_change >= 0) */ {
2628 /*
2629 * The file size is growing or staying the same but the
2630 * allocation can be shrinking, growing or staying the same.
2631 */
2632 if (alloc_change > 0) {
2633 /*
2634 * We need to extend the allocation and possibly update
2635 * the data size. If we are updating the data size,
2636 * since we are not touching the initialized_size we do
2637 * not need to worry about the actual data on disk.
2638 * And as far as the page cache is concerned, there
2639 * will be no pages beyond the old data size and any
2640 * partial region in the last page between the old and
2641 * new data size (or the end of the page if the new
2642 * data size is outside the page) does not need to be
2643 * modified as explained above for the resident
2644 * attribute truncate case. To do this, we simply drop
2645 * the locks we hold and leave all the work to our
2646 * friendly helper ntfs_attr_extend_allocation().
2647 */
2648 ntfs_attr_put_search_ctx(ctx);
2649 unmap_mft_record(base_ni);
2650 up_write(&ni->runlist.lock);
2651 err = ntfs_attr_extend_allocation(ni, new_size,
2652 size_change > 0 ? new_size : -1, -1);
2653 /*
2654 * ntfs_attr_extend_allocation() will have done error
2655 * output already.
2656 */
2657 goto done;
2658 }
2659 if (!alloc_change)
2660 goto alloc_done;
2661 }
2662 /* alloc_change < 0 */
2663 /* Free the clusters. */
2664 nr_freed = ntfs_cluster_free(ni, new_alloc_size >>
2665 vol->cluster_size_bits, -1, ctx);
2666 m = ctx->mrec;
2667 a = ctx->attr;
2668 if (unlikely(nr_freed < 0)) {
2669 ntfs_error(vol->sb, "Failed to release cluster(s) (error code "
2670 "%lli). Unmount and run chkdsk to recover "
2671 "the lost cluster(s).", (long long)nr_freed);
2374 NVolSetErrors(vol); 2672 NVolSetErrors(vol);
2673 nr_freed = 0;
2674 }
2675 /* Truncate the runlist. */
2676 err = ntfs_rl_truncate_nolock(vol, &ni->runlist,
2677 new_alloc_size >> vol->cluster_size_bits);
2678 /*
2679 * If the runlist truncation failed and/or the search context is no
2680 * longer valid, we cannot resize the attribute record or build the
2681 * mapping pairs array thus we mark the inode bad so that no access to
2682 * the freed clusters can happen.
2683 */
2684 if (unlikely(err || IS_ERR(m))) {
2685 ntfs_error(vol->sb, "Failed to %s (error code %li).%s",
2686 IS_ERR(m) ?
2687 "restore attribute search context" :
2688 "truncate attribute runlist",
2689 IS_ERR(m) ? PTR_ERR(m) : err, es);
2690 err = -EIO;
2691 goto bad_out;
2692 }
2693 /* Get the size for the shrunk mapping pairs array for the runlist. */
2694 mp_size = ntfs_get_size_for_mapping_pairs(vol, ni->runlist.rl, 0, -1);
2695 if (unlikely(mp_size <= 0)) {
2696 ntfs_error(vol->sb, "Cannot shrink allocation of inode 0x%lx, "
2697 "attribute type 0x%x, because determining the "
2698 "size for the mapping pairs failed with error "
2699 "code %i.%s", vi->i_ino,
2700 (unsigned)le32_to_cpu(ni->type), mp_size, es);
2701 err = -EIO;
2702 goto bad_out;
2703 }
2704 /*
2705 * Shrink the attribute record for the new mapping pairs array. Note,
2706 * this cannot fail since we are making the attribute smaller thus by
2707 * definition there is enough space to do so.
2708 */
2709 attr_len = le32_to_cpu(a->length);
2710 err = ntfs_attr_record_resize(m, a, mp_size +
2711 le16_to_cpu(a->data.non_resident.mapping_pairs_offset));
2712 BUG_ON(err);
2713 /*
2714 * Generate the mapping pairs array directly into the attribute record.
2715 */
2716 err = ntfs_mapping_pairs_build(vol, (u8*)a +
2717 le16_to_cpu(a->data.non_resident.mapping_pairs_offset),
2718 mp_size, ni->runlist.rl, 0, -1, NULL);
2719 if (unlikely(err)) {
2720 ntfs_error(vol->sb, "Cannot shrink allocation of inode 0x%lx, "
2721 "attribute type 0x%x, because building the "
2722 "mapping pairs failed with error code %i.%s",
2723 vi->i_ino, (unsigned)le32_to_cpu(ni->type),
2724 err, es);
2725 err = -EIO;
2726 goto bad_out;
2727 }
2728 /* Update the allocated/compressed size as well as the highest vcn. */
2729 a->data.non_resident.highest_vcn = cpu_to_sle64((new_alloc_size >>
2730 vol->cluster_size_bits) - 1);
2731 write_lock_irqsave(&ni->size_lock, flags);
2732 ni->allocated_size = new_alloc_size;
2733 a->data.non_resident.allocated_size = cpu_to_sle64(new_alloc_size);
2734 if (NInoSparse(ni) || NInoCompressed(ni)) {
2735 if (nr_freed) {
2736 ni->itype.compressed.size -= nr_freed <<
2737 vol->cluster_size_bits;
2738 BUG_ON(ni->itype.compressed.size < 0);
2739 a->data.non_resident.compressed_size = cpu_to_sle64(
2740 ni->itype.compressed.size);
2741 vi->i_blocks = ni->itype.compressed.size >> 9;
2742 }
2743 } else
2744 vi->i_blocks = new_alloc_size >> 9;
2745 write_unlock_irqrestore(&ni->size_lock, flags);
2746 /*
2747 * We have shrunk the allocation. If this is a shrinking truncate we
2748 * have already dealt with the initialized_size and the data_size above
2749 * and we are done. If the truncate is only changing the allocation
2750 * and not the data_size, we are also done. If this is an extending
2751 * truncate, need to extend the data_size now which is ensured by the
2752 * fact that @size_change is positive.
2753 */
2754alloc_done:
2755 /*
2756 * If the size is growing, need to update it now. If it is shrinking,
2757 * we have already updated it above (before the allocation change).
2758 */
2759 if (size_change > 0)
2760 a->data.non_resident.data_size = cpu_to_sle64(new_size);
2761 /* Ensure the modified mft record is written out. */
2762 flush_dcache_mft_record_page(ctx->ntfs_ino);
2763 mark_mft_record_dirty(ctx->ntfs_ino);
2764unm_done:
2765 ntfs_attr_put_search_ctx(ctx);
2766 unmap_mft_record(base_ni);
2767 up_write(&ni->runlist.lock);
2768done:
2769 /* Update the mtime and ctime on the base inode. */
2770 inode_update_time(VFS_I(base_ni), 1);
2771 if (likely(!err)) {
2772 NInoClearTruncateFailed(ni);
2773 ntfs_debug("Done.");
2774 }
2775 return err;
2776old_bad_out:
2777 old_size = -1;
2778bad_out:
2779 if (err != -ENOMEM && err != -EOPNOTSUPP) {
2375 make_bad_inode(vi); 2780 make_bad_inode(vi);
2781 make_bad_inode(VFS_I(base_ni));
2782 NVolSetErrors(vol);
2376 } 2783 }
2784 if (err != -EOPNOTSUPP)
2785 NInoSetTruncateFailed(ni);
2786 else if (old_size >= 0)
2787 i_size_write(vi, old_size);
2788err_out:
2377 if (ctx) 2789 if (ctx)
2378 ntfs_attr_put_search_ctx(ctx); 2790 ntfs_attr_put_search_ctx(ctx);
2379 if (m) 2791 if (m)
2380 unmap_mft_record(ni); 2792 unmap_mft_record(base_ni);
2381 NInoSetTruncateFailed(ni); 2793 up_write(&ni->runlist.lock);
2794out:
2795 ntfs_debug("Failed. Returning error code %i.", err);
2382 return err; 2796 return err;
2797conv_err_out:
2798 if (err != -ENOMEM && err != -EOPNOTSUPP) {
2799 make_bad_inode(vi);
2800 make_bad_inode(VFS_I(base_ni));
2801 NVolSetErrors(vol);
2802 }
2803 if (err != -EOPNOTSUPP)
2804 NInoSetTruncateFailed(ni);
2805 else
2806 i_size_write(vi, old_size);
2807 goto out;
2383} 2808}
2384 2809
2385/** 2810/**
@@ -2420,8 +2845,7 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr)
2420 2845
2421 err = inode_change_ok(vi, attr); 2846 err = inode_change_ok(vi, attr);
2422 if (err) 2847 if (err)
2423 return err; 2848 goto out;
2424
2425 /* We do not support NTFS ACLs yet. */ 2849 /* We do not support NTFS ACLs yet. */
2426 if (ia_valid & (ATTR_UID | ATTR_GID | ATTR_MODE)) { 2850 if (ia_valid & (ATTR_UID | ATTR_GID | ATTR_MODE)) {
2427 ntfs_warning(vi->i_sb, "Changes in user/group/mode are not " 2851 ntfs_warning(vi->i_sb, "Changes in user/group/mode are not "
@@ -2429,14 +2853,22 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr)
2429 err = -EOPNOTSUPP; 2853 err = -EOPNOTSUPP;
2430 goto out; 2854 goto out;
2431 } 2855 }
2432
2433 if (ia_valid & ATTR_SIZE) { 2856 if (ia_valid & ATTR_SIZE) {
2434 if (attr->ia_size != i_size_read(vi)) { 2857 if (attr->ia_size != i_size_read(vi)) {
2435 ntfs_warning(vi->i_sb, "Changes in inode size are not " 2858 ntfs_inode *ni = NTFS_I(vi);
2436 "supported yet, ignoring."); 2859 /*
2437 err = -EOPNOTSUPP; 2860 * FIXME: For now we do not support resizing of
2438 // TODO: Implement... 2861 * compressed or encrypted files yet.
2439 // err = vmtruncate(vi, attr->ia_size); 2862 */
2863 if (NInoCompressed(ni) || NInoEncrypted(ni)) {
2864 ntfs_warning(vi->i_sb, "Changes in inode size "
2865 "are not supported yet for "
2866 "%s files, ignoring.",
2867 NInoCompressed(ni) ?
2868 "compressed" : "encrypted");
2869 err = -EOPNOTSUPP;
2870 } else
2871 err = vmtruncate(vi, attr->ia_size);
2440 if (err || ia_valid == ATTR_SIZE) 2872 if (err || ia_valid == ATTR_SIZE)
2441 goto out; 2873 goto out;
2442 } else { 2874 } else {
diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h
index 5c248d404f05..f5678d5d7919 100644
--- a/fs/ntfs/layout.h
+++ b/fs/ntfs/layout.h
@@ -1021,10 +1021,17 @@ enum {
1021 FILE_NAME_POSIX = 0x00, 1021 FILE_NAME_POSIX = 0x00,
1022 /* This is the largest namespace. It is case sensitive and allows all 1022 /* This is the largest namespace. It is case sensitive and allows all
1023 Unicode characters except for: '\0' and '/'. Beware that in 1023 Unicode characters except for: '\0' and '/'. Beware that in
1024 WinNT/2k files which eg have the same name except for their case 1024 WinNT/2k/2003 by default files which eg have the same name except
1025 will not be distinguished by the standard utilities and thus a "del 1025 for their case will not be distinguished by the standard utilities
1026 filename" will delete both "filename" and "fileName" without 1026 and thus a "del filename" will delete both "filename" and "fileName"
1027 warning. */ 1027 without warning. However if for example Services For Unix (SFU) are
1028 installed and the case sensitive option was enabled at installation
1029 time, then you can create/access/delete such files.
1030 Note that even SFU places restrictions on the filenames beyond the
1031 '\0' and '/' and in particular the following set of characters is
1032 not allowed: '"', '/', '<', '>', '\'. All other characters,
1033 including the ones no allowed in WIN32 namespace are allowed.
1034 Tested with SFU 3.5 (this is now free) running on Windows XP. */
1028 FILE_NAME_WIN32 = 0x01, 1035 FILE_NAME_WIN32 = 0x01,
1029 /* The standard WinNT/2k NTFS long filenames. Case insensitive. All 1036 /* The standard WinNT/2k NTFS long filenames. Case insensitive. All
1030 Unicode chars except: '\0', '"', '*', '/', ':', '<', '>', '?', '\', 1037 Unicode chars except: '\0', '"', '*', '/', ':', '<', '>', '?', '\',
@@ -2367,7 +2374,9 @@ typedef struct {
2367 * Extended attribute flags (8-bit). 2374 * Extended attribute flags (8-bit).
2368 */ 2375 */
2369enum { 2376enum {
2370 NEED_EA = 0x80 2377 NEED_EA = 0x80 /* If set the file to which the EA belongs
2378 cannot be interpreted without understanding
2379 the associates extended attributes. */
2371} __attribute__ ((__packed__)); 2380} __attribute__ ((__packed__));
2372 2381
2373typedef u8 EA_FLAGS; 2382typedef u8 EA_FLAGS;
@@ -2375,20 +2384,20 @@ typedef u8 EA_FLAGS;
2375/* 2384/*
2376 * Attribute: Extended attribute (EA) (0xe0). 2385 * Attribute: Extended attribute (EA) (0xe0).
2377 * 2386 *
2378 * NOTE: Always non-resident. (Is this true?) 2387 * NOTE: Can be resident or non-resident.
2379 * 2388 *
2380 * Like the attribute list and the index buffer list, the EA attribute value is 2389 * Like the attribute list and the index buffer list, the EA attribute value is
2381 * a sequence of EA_ATTR variable length records. 2390 * a sequence of EA_ATTR variable length records.
2382 *
2383 * FIXME: It appears weird that the EA name is not unicode. Is it true?
2384 */ 2391 */
2385typedef struct { 2392typedef struct {
2386 le32 next_entry_offset; /* Offset to the next EA_ATTR. */ 2393 le32 next_entry_offset; /* Offset to the next EA_ATTR. */
2387 EA_FLAGS flags; /* Flags describing the EA. */ 2394 EA_FLAGS flags; /* Flags describing the EA. */
2388 u8 ea_name_length; /* Length of the name of the EA in bytes. */ 2395 u8 ea_name_length; /* Length of the name of the EA in bytes
2396 excluding the '\0' byte terminator. */
2389 le16 ea_value_length; /* Byte size of the EA's value. */ 2397 le16 ea_value_length; /* Byte size of the EA's value. */
2390 u8 ea_name[0]; /* Name of the EA. */ 2398 u8 ea_name[0]; /* Name of the EA. Note this is ASCII, not
2391 u8 ea_value[0]; /* The value of the EA. Immediately follows 2399 Unicode and it is zero terminated. */
2400 u8 ea_value[0]; /* The value of the EA. Immediately follows
2392 the name. */ 2401 the name. */
2393} __attribute__ ((__packed__)) EA_ATTR; 2402} __attribute__ ((__packed__)) EA_ATTR;
2394 2403
diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c
index 5af3bf0b7eee..29cabf93d2d2 100644
--- a/fs/ntfs/lcnalloc.c
+++ b/fs/ntfs/lcnalloc.c
@@ -76,6 +76,7 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
76 * @count: number of clusters to allocate 76 * @count: number of clusters to allocate
77 * @start_lcn: starting lcn at which to allocate the clusters (or -1 if none) 77 * @start_lcn: starting lcn at which to allocate the clusters (or -1 if none)
78 * @zone: zone from which to allocate the clusters 78 * @zone: zone from which to allocate the clusters
79 * @is_extension: if TRUE, this is an attribute extension
79 * 80 *
80 * Allocate @count clusters preferably starting at cluster @start_lcn or at the 81 * Allocate @count clusters preferably starting at cluster @start_lcn or at the
81 * current allocator position if @start_lcn is -1, on the mounted ntfs volume 82 * current allocator position if @start_lcn is -1, on the mounted ntfs volume
@@ -86,6 +87,13 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
86 * @start_vcn specifies the vcn of the first allocated cluster. This makes 87 * @start_vcn specifies the vcn of the first allocated cluster. This makes
87 * merging the resulting runlist with the old runlist easier. 88 * merging the resulting runlist with the old runlist easier.
88 * 89 *
90 * If @is_extension is TRUE, the caller is allocating clusters to extend an
91 * attribute and if it is FALSE, the caller is allocating clusters to fill a
92 * hole in an attribute. Practically the difference is that if @is_extension
93 * is TRUE the returned runlist will be terminated with LCN_ENOENT and if
94 * @is_extension is FALSE the runlist will be terminated with
95 * LCN_RL_NOT_MAPPED.
96 *
89 * You need to check the return value with IS_ERR(). If this is false, the 97 * You need to check the return value with IS_ERR(). If this is false, the
90 * function was successful and the return value is a runlist describing the 98 * function was successful and the return value is a runlist describing the
91 * allocated cluster(s). If IS_ERR() is true, the function failed and 99 * allocated cluster(s). If IS_ERR() is true, the function failed and
@@ -137,7 +145,8 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
137 */ 145 */
138runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn, 146runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
139 const s64 count, const LCN start_lcn, 147 const s64 count, const LCN start_lcn,
140 const NTFS_CLUSTER_ALLOCATION_ZONES zone) 148 const NTFS_CLUSTER_ALLOCATION_ZONES zone,
149 const BOOL is_extension)
141{ 150{
142 LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn; 151 LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn;
143 LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size; 152 LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size;
@@ -310,7 +319,7 @@ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
310 continue; 319 continue;
311 } 320 }
312 bit = 1 << (lcn & 7); 321 bit = 1 << (lcn & 7);
313 ntfs_debug("bit %i.", bit); 322 ntfs_debug("bit 0x%x.", bit);
314 /* If the bit is already set, go onto the next one. */ 323 /* If the bit is already set, go onto the next one. */
315 if (*byte & bit) { 324 if (*byte & bit) {
316 lcn++; 325 lcn++;
@@ -729,7 +738,7 @@ out:
729 /* Add runlist terminator element. */ 738 /* Add runlist terminator element. */
730 if (likely(rl)) { 739 if (likely(rl)) {
731 rl[rlpos].vcn = rl[rlpos - 1].vcn + rl[rlpos - 1].length; 740 rl[rlpos].vcn = rl[rlpos - 1].vcn + rl[rlpos - 1].length;
732 rl[rlpos].lcn = LCN_RL_NOT_MAPPED; 741 rl[rlpos].lcn = is_extension ? LCN_ENOENT : LCN_RL_NOT_MAPPED;
733 rl[rlpos].length = 0; 742 rl[rlpos].length = 0;
734 } 743 }
735 if (likely(page && !IS_ERR(page))) { 744 if (likely(page && !IS_ERR(page))) {
@@ -782,6 +791,7 @@ out:
782 * @ni: ntfs inode whose runlist describes the clusters to free 791 * @ni: ntfs inode whose runlist describes the clusters to free
783 * @start_vcn: vcn in the runlist of @ni at which to start freeing clusters 792 * @start_vcn: vcn in the runlist of @ni at which to start freeing clusters
784 * @count: number of clusters to free or -1 for all clusters 793 * @count: number of clusters to free or -1 for all clusters
794 * @ctx: active attribute search context if present or NULL if not
785 * @is_rollback: true if this is a rollback operation 795 * @is_rollback: true if this is a rollback operation
786 * 796 *
787 * Free @count clusters starting at the cluster @start_vcn in the runlist 797 * Free @count clusters starting at the cluster @start_vcn in the runlist
@@ -791,15 +801,39 @@ out:
791 * deallocated. Thus, to completely free all clusters in a runlist, use 801 * deallocated. Thus, to completely free all clusters in a runlist, use
792 * @start_vcn = 0 and @count = -1. 802 * @start_vcn = 0 and @count = -1.
793 * 803 *
804 * If @ctx is specified, it is an active search context of @ni and its base mft
805 * record. This is needed when __ntfs_cluster_free() encounters unmapped
806 * runlist fragments and allows their mapping. If you do not have the mft
807 * record mapped, you can specify @ctx as NULL and __ntfs_cluster_free() will
808 * perform the necessary mapping and unmapping.
809 *
810 * Note, __ntfs_cluster_free() saves the state of @ctx on entry and restores it
811 * before returning. Thus, @ctx will be left pointing to the same attribute on
812 * return as on entry. However, the actual pointers in @ctx may point to
813 * different memory locations on return, so you must remember to reset any
814 * cached pointers from the @ctx, i.e. after the call to __ntfs_cluster_free(),
815 * you will probably want to do:
816 * m = ctx->mrec;
817 * a = ctx->attr;
818 * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
819 * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
820 *
794 * @is_rollback should always be FALSE, it is for internal use to rollback 821 * @is_rollback should always be FALSE, it is for internal use to rollback
795 * errors. You probably want to use ntfs_cluster_free() instead. 822 * errors. You probably want to use ntfs_cluster_free() instead.
796 * 823 *
797 * Note, ntfs_cluster_free() does not modify the runlist at all, so the caller 824 * Note, __ntfs_cluster_free() does not modify the runlist, so you have to
798 * has to deal with it later. 825 * remove from the runlist or mark sparse the freed runs later.
799 * 826 *
800 * Return the number of deallocated clusters (not counting sparse ones) on 827 * Return the number of deallocated clusters (not counting sparse ones) on
801 * success and -errno on error. 828 * success and -errno on error.
802 * 829 *
830 * WARNING: If @ctx is supplied, regardless of whether success or failure is
831 * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
832 * is no longer valid, i.e. you need to either call
833 * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
834 * In that case PTR_ERR(@ctx->mrec) will give you the error code for
835 * why the mapping of the old inode failed.
836 *
803 * Locking: - The runlist described by @ni must be locked for writing on entry 837 * Locking: - The runlist described by @ni must be locked for writing on entry
804 * and is locked on return. Note the runlist may be modified when 838 * and is locked on return. Note the runlist may be modified when
805 * needed runlist fragments need to be mapped. 839 * needed runlist fragments need to be mapped.
@@ -807,9 +841,13 @@ out:
807 * on return. 841 * on return.
808 * - This function takes the volume lcn bitmap lock for writing and 842 * - This function takes the volume lcn bitmap lock for writing and
809 * modifies the bitmap contents. 843 * modifies the bitmap contents.
844 * - If @ctx is NULL, the base mft record of @ni must not be mapped on
845 * entry and it will be left unmapped on return.
846 * - If @ctx is not NULL, the base mft record must be mapped on entry
847 * and it will be left mapped on return.
810 */ 848 */
811s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count, 849s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count,
812 const BOOL is_rollback) 850 ntfs_attr_search_ctx *ctx, const BOOL is_rollback)
813{ 851{
814 s64 delta, to_free, total_freed, real_freed; 852 s64 delta, to_free, total_freed, real_freed;
815 ntfs_volume *vol; 853 ntfs_volume *vol;
@@ -839,7 +877,7 @@ s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count,
839 877
840 total_freed = real_freed = 0; 878 total_freed = real_freed = 0;
841 879
842 rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, TRUE); 880 rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, ctx);
843 if (IS_ERR(rl)) { 881 if (IS_ERR(rl)) {
844 if (!is_rollback) 882 if (!is_rollback)
845 ntfs_error(vol->sb, "Failed to find first runlist " 883 ntfs_error(vol->sb, "Failed to find first runlist "
@@ -893,7 +931,7 @@ s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count,
893 931
894 /* Attempt to map runlist. */ 932 /* Attempt to map runlist. */
895 vcn = rl->vcn; 933 vcn = rl->vcn;
896 rl = ntfs_attr_find_vcn_nolock(ni, vcn, TRUE); 934 rl = ntfs_attr_find_vcn_nolock(ni, vcn, ctx);
897 if (IS_ERR(rl)) { 935 if (IS_ERR(rl)) {
898 err = PTR_ERR(rl); 936 err = PTR_ERR(rl);
899 if (!is_rollback) 937 if (!is_rollback)
@@ -961,7 +999,7 @@ err_out:
961 * If rollback fails, set the volume errors flag, emit an error 999 * If rollback fails, set the volume errors flag, emit an error
962 * message, and return the error code. 1000 * message, and return the error code.
963 */ 1001 */
964 delta = __ntfs_cluster_free(ni, start_vcn, total_freed, TRUE); 1002 delta = __ntfs_cluster_free(ni, start_vcn, total_freed, ctx, TRUE);
965 if (delta < 0) { 1003 if (delta < 0) {
966 ntfs_error(vol->sb, "Failed to rollback (error %i). Leaving " 1004 ntfs_error(vol->sb, "Failed to rollback (error %i). Leaving "
967 "inconsistent metadata! Unmount and run " 1005 "inconsistent metadata! Unmount and run "
diff --git a/fs/ntfs/lcnalloc.h b/fs/ntfs/lcnalloc.h
index a6a8827882e7..72cbca7003b2 100644
--- a/fs/ntfs/lcnalloc.h
+++ b/fs/ntfs/lcnalloc.h
@@ -27,6 +27,7 @@
27 27
28#include <linux/fs.h> 28#include <linux/fs.h>
29 29
30#include "attrib.h"
30#include "types.h" 31#include "types.h"
31#include "inode.h" 32#include "inode.h"
32#include "runlist.h" 33#include "runlist.h"
@@ -41,16 +42,18 @@ typedef enum {
41 42
42extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, 43extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol,
43 const VCN start_vcn, const s64 count, const LCN start_lcn, 44 const VCN start_vcn, const s64 count, const LCN start_lcn,
44 const NTFS_CLUSTER_ALLOCATION_ZONES zone); 45 const NTFS_CLUSTER_ALLOCATION_ZONES zone,
46 const BOOL is_extension);
45 47
46extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, 48extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
47 s64 count, const BOOL is_rollback); 49 s64 count, ntfs_attr_search_ctx *ctx, const BOOL is_rollback);
48 50
49/** 51/**
50 * ntfs_cluster_free - free clusters on an ntfs volume 52 * ntfs_cluster_free - free clusters on an ntfs volume
51 * @ni: ntfs inode whose runlist describes the clusters to free 53 * @ni: ntfs inode whose runlist describes the clusters to free
52 * @start_vcn: vcn in the runlist of @ni at which to start freeing clusters 54 * @start_vcn: vcn in the runlist of @ni at which to start freeing clusters
53 * @count: number of clusters to free or -1 for all clusters 55 * @count: number of clusters to free or -1 for all clusters
56 * @ctx: active attribute search context if present or NULL if not
54 * 57 *
55 * Free @count clusters starting at the cluster @start_vcn in the runlist 58 * Free @count clusters starting at the cluster @start_vcn in the runlist
56 * described by the ntfs inode @ni. 59 * described by the ntfs inode @ni.
@@ -59,12 +62,36 @@ extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
59 * deallocated. Thus, to completely free all clusters in a runlist, use 62 * deallocated. Thus, to completely free all clusters in a runlist, use
60 * @start_vcn = 0 and @count = -1. 63 * @start_vcn = 0 and @count = -1.
61 * 64 *
62 * Note, ntfs_cluster_free() does not modify the runlist at all, so the caller 65 * If @ctx is specified, it is an active search context of @ni and its base mft
63 * has to deal with it later. 66 * record. This is needed when ntfs_cluster_free() encounters unmapped runlist
67 * fragments and allows their mapping. If you do not have the mft record
68 * mapped, you can specify @ctx as NULL and ntfs_cluster_free() will perform
69 * the necessary mapping and unmapping.
70 *
71 * Note, ntfs_cluster_free() saves the state of @ctx on entry and restores it
72 * before returning. Thus, @ctx will be left pointing to the same attribute on
73 * return as on entry. However, the actual pointers in @ctx may point to
74 * different memory locations on return, so you must remember to reset any
75 * cached pointers from the @ctx, i.e. after the call to ntfs_cluster_free(),
76 * you will probably want to do:
77 * m = ctx->mrec;
78 * a = ctx->attr;
79 * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
80 * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
81 *
82 * Note, ntfs_cluster_free() does not modify the runlist, so you have to remove
83 * from the runlist or mark sparse the freed runs later.
64 * 84 *
65 * Return the number of deallocated clusters (not counting sparse ones) on 85 * Return the number of deallocated clusters (not counting sparse ones) on
66 * success and -errno on error. 86 * success and -errno on error.
67 * 87 *
88 * WARNING: If @ctx is supplied, regardless of whether success or failure is
89 * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx
90 * is no longer valid, i.e. you need to either call
91 * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
92 * In that case PTR_ERR(@ctx->mrec) will give you the error code for
93 * why the mapping of the old inode failed.
94 *
68 * Locking: - The runlist described by @ni must be locked for writing on entry 95 * Locking: - The runlist described by @ni must be locked for writing on entry
69 * and is locked on return. Note the runlist may be modified when 96 * and is locked on return. Note the runlist may be modified when
70 * needed runlist fragments need to be mapped. 97 * needed runlist fragments need to be mapped.
@@ -72,11 +99,15 @@ extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
72 * on return. 99 * on return.
73 * - This function takes the volume lcn bitmap lock for writing and 100 * - This function takes the volume lcn bitmap lock for writing and
74 * modifies the bitmap contents. 101 * modifies the bitmap contents.
102 * - If @ctx is NULL, the base mft record of @ni must not be mapped on
103 * entry and it will be left unmapped on return.
104 * - If @ctx is not NULL, the base mft record must be mapped on entry
105 * and it will be left mapped on return.
75 */ 106 */
76static inline s64 ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, 107static inline s64 ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn,
77 s64 count) 108 s64 count, ntfs_attr_search_ctx *ctx)
78{ 109{
79 return __ntfs_cluster_free(ni, start_vcn, count, FALSE); 110 return __ntfs_cluster_free(ni, start_vcn, count, ctx, FALSE);
80} 111}
81 112
82extern int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol, 113extern int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
diff --git a/fs/ntfs/malloc.h b/fs/ntfs/malloc.h
index 590887b943f5..e38e402e4103 100644
--- a/fs/ntfs/malloc.h
+++ b/fs/ntfs/malloc.h
@@ -39,8 +39,7 @@
39 * If there was insufficient memory to complete the request, return NULL. 39 * If there was insufficient memory to complete the request, return NULL.
40 * Depending on @gfp_mask the allocation may be guaranteed to succeed. 40 * Depending on @gfp_mask the allocation may be guaranteed to succeed.
41 */ 41 */
42static inline void *__ntfs_malloc(unsigned long size, 42static inline void *__ntfs_malloc(unsigned long size, gfp_t gfp_mask)
43 gfp_t gfp_mask)
44{ 43{
45 if (likely(size <= PAGE_SIZE)) { 44 if (likely(size <= PAGE_SIZE)) {
46 BUG_ON(!size); 45 BUG_ON(!size);
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index b011369b5956..0c65cbb8c5cf 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -49,7 +49,8 @@ static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni)
49 ntfs_volume *vol = ni->vol; 49 ntfs_volume *vol = ni->vol;
50 struct inode *mft_vi = vol->mft_ino; 50 struct inode *mft_vi = vol->mft_ino;
51 struct page *page; 51 struct page *page;
52 unsigned long index, ofs, end_index; 52 unsigned long index, end_index;
53 unsigned ofs;
53 54
54 BUG_ON(ni->page); 55 BUG_ON(ni->page);
55 /* 56 /*
@@ -1308,7 +1309,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
1308 ll = mftbmp_ni->allocated_size; 1309 ll = mftbmp_ni->allocated_size;
1309 read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); 1310 read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
1310 rl = ntfs_attr_find_vcn_nolock(mftbmp_ni, 1311 rl = ntfs_attr_find_vcn_nolock(mftbmp_ni,
1311 (ll - 1) >> vol->cluster_size_bits, TRUE); 1312 (ll - 1) >> vol->cluster_size_bits, NULL);
1312 if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) { 1313 if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) {
1313 up_write(&mftbmp_ni->runlist.lock); 1314 up_write(&mftbmp_ni->runlist.lock);
1314 ntfs_error(vol->sb, "Failed to determine last allocated " 1315 ntfs_error(vol->sb, "Failed to determine last allocated "
@@ -1354,7 +1355,8 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
1354 up_write(&vol->lcnbmp_lock); 1355 up_write(&vol->lcnbmp_lock);
1355 ntfs_unmap_page(page); 1356 ntfs_unmap_page(page);
1356 /* Allocate a cluster from the DATA_ZONE. */ 1357 /* Allocate a cluster from the DATA_ZONE. */
1357 rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE); 1358 rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE,
1359 TRUE);
1358 if (IS_ERR(rl2)) { 1360 if (IS_ERR(rl2)) {
1359 up_write(&mftbmp_ni->runlist.lock); 1361 up_write(&mftbmp_ni->runlist.lock);
1360 ntfs_error(vol->sb, "Failed to allocate a cluster for " 1362 ntfs_error(vol->sb, "Failed to allocate a cluster for "
@@ -1738,7 +1740,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
1738 ll = mft_ni->allocated_size; 1740 ll = mft_ni->allocated_size;
1739 read_unlock_irqrestore(&mft_ni->size_lock, flags); 1741 read_unlock_irqrestore(&mft_ni->size_lock, flags);
1740 rl = ntfs_attr_find_vcn_nolock(mft_ni, 1742 rl = ntfs_attr_find_vcn_nolock(mft_ni,
1741 (ll - 1) >> vol->cluster_size_bits, TRUE); 1743 (ll - 1) >> vol->cluster_size_bits, NULL);
1742 if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) { 1744 if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) {
1743 up_write(&mft_ni->runlist.lock); 1745 up_write(&mft_ni->runlist.lock);
1744 ntfs_error(vol->sb, "Failed to determine last allocated " 1746 ntfs_error(vol->sb, "Failed to determine last allocated "
@@ -1779,7 +1781,8 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
1779 nr > min_nr ? "default" : "minimal", (long long)nr); 1781 nr > min_nr ? "default" : "minimal", (long long)nr);
1780 old_last_vcn = rl[1].vcn; 1782 old_last_vcn = rl[1].vcn;
1781 do { 1783 do {
1782 rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE); 1784 rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE,
1785 TRUE);
1783 if (likely(!IS_ERR(rl2))) 1786 if (likely(!IS_ERR(rl2)))
1784 break; 1787 break;
1785 if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) { 1788 if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) {
@@ -1951,20 +1954,21 @@ restore_undo_alloc:
1951 NVolSetErrors(vol); 1954 NVolSetErrors(vol);
1952 return ret; 1955 return ret;
1953 } 1956 }
1954 a = ctx->attr; 1957 ctx->attr->data.non_resident.highest_vcn =
1955 a->data.non_resident.highest_vcn = cpu_to_sle64(old_last_vcn - 1); 1958 cpu_to_sle64(old_last_vcn - 1);
1956undo_alloc: 1959undo_alloc:
1957 if (ntfs_cluster_free(mft_ni, old_last_vcn, -1) < 0) { 1960 if (ntfs_cluster_free(mft_ni, old_last_vcn, -1, ctx) < 0) {
1958 ntfs_error(vol->sb, "Failed to free clusters from mft data " 1961 ntfs_error(vol->sb, "Failed to free clusters from mft data "
1959 "attribute.%s", es); 1962 "attribute.%s", es);
1960 NVolSetErrors(vol); 1963 NVolSetErrors(vol);
1961 } 1964 }
1965 a = ctx->attr;
1962 if (ntfs_rl_truncate_nolock(vol, &mft_ni->runlist, old_last_vcn)) { 1966 if (ntfs_rl_truncate_nolock(vol, &mft_ni->runlist, old_last_vcn)) {
1963 ntfs_error(vol->sb, "Failed to truncate mft data attribute " 1967 ntfs_error(vol->sb, "Failed to truncate mft data attribute "
1964 "runlist.%s", es); 1968 "runlist.%s", es);
1965 NVolSetErrors(vol); 1969 NVolSetErrors(vol);
1966 } 1970 }
1967 if (mp_rebuilt) { 1971 if (mp_rebuilt && !IS_ERR(ctx->mrec)) {
1968 if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu( 1972 if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(
1969 a->data.non_resident.mapping_pairs_offset), 1973 a->data.non_resident.mapping_pairs_offset),
1970 old_alen - le16_to_cpu( 1974 old_alen - le16_to_cpu(
@@ -1981,6 +1985,10 @@ undo_alloc:
1981 } 1985 }
1982 flush_dcache_mft_record_page(ctx->ntfs_ino); 1986 flush_dcache_mft_record_page(ctx->ntfs_ino);
1983 mark_mft_record_dirty(ctx->ntfs_ino); 1987 mark_mft_record_dirty(ctx->ntfs_ino);
1988 } else if (IS_ERR(ctx->mrec)) {
1989 ntfs_error(vol->sb, "Failed to restore attribute search "
1990 "context.%s", es);
1991 NVolSetErrors(vol);
1984 } 1992 }
1985 if (ctx) 1993 if (ctx)
1986 ntfs_attr_put_search_ctx(ctx); 1994 ntfs_attr_put_search_ctx(ctx);
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 453d0d51ea4b..6c16db9e1a8a 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1447,7 +1447,7 @@ not_enabled:
1447 if (unlikely(i_size_read(tmp_ino) < sizeof(USN_HEADER))) { 1447 if (unlikely(i_size_read(tmp_ino) < sizeof(USN_HEADER))) {
1448 ntfs_error(vol->sb, "Found corrupt $UsnJrnl/$DATA/$Max " 1448 ntfs_error(vol->sb, "Found corrupt $UsnJrnl/$DATA/$Max "
1449 "attribute (size is 0x%llx but should be at " 1449 "attribute (size is 0x%llx but should be at "
1450 "least 0x%x bytes).", i_size_read(tmp_ino), 1450 "least 0x%zx bytes).", i_size_read(tmp_ino),
1451 sizeof(USN_HEADER)); 1451 sizeof(USN_HEADER));
1452 return FALSE; 1452 return FALSE;
1453 } 1453 }
diff --git a/include/asm-arm/arch-ixp2000/enp2611.h b/include/asm-arm/arch-ixp2000/enp2611.h
index 31ae88674968..95128d9f5026 100644
--- a/include/asm-arm/arch-ixp2000/enp2611.h
+++ b/include/asm-arm/arch-ixp2000/enp2611.h
@@ -21,8 +21,20 @@
21#ifndef __ENP2611_H 21#ifndef __ENP2611_H
22#define __ENP2611_H 22#define __ENP2611_H
23 23
24#define ENP2611_GPIO_SCL 0x07 24#define ENP2611_CALEB_PHYS_BASE 0xc5000000
25#define ENP2611_GPIO_SDA 0x06 25#define ENP2611_CALEB_VIRT_BASE 0xfe000000
26#define ENP2611_CALEB_SIZE 0x00100000
27
28#define ENP2611_PM3386_0_PHYS_BASE 0xc6000000
29#define ENP2611_PM3386_0_VIRT_BASE 0xfe100000
30#define ENP2611_PM3386_0_SIZE 0x00100000
31
32#define ENP2611_PM3386_1_PHYS_BASE 0xc6400000
33#define ENP2611_PM3386_1_VIRT_BASE 0xfe200000
34#define ENP2611_PM3386_1_SIZE 0x00100000
35
36#define ENP2611_GPIO_SCL 7
37#define ENP2611_GPIO_SDA 6
26 38
27 39
28#endif 40#endif
diff --git a/include/asm-arm/arch-ixp2000/ixp2000-regs.h b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
index def089d693d2..fc5ac6aec4f2 100644
--- a/include/asm-arm/arch-ixp2000/ixp2000-regs.h
+++ b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
@@ -59,14 +59,15 @@
59#define IXP2000_CAP_SIZE 0x00100000 59#define IXP2000_CAP_SIZE 0x00100000
60 60
61/* 61/*
62 * Addresses for specific on-chip peripherals 62 * Addresses for specific on-chip peripherals.
63 */ 63 */
64#define IXP2000_SLOWPORT_CSR_VIRT_BASE 0xfef80000 64#define IXP2000_SLOWPORT_CSR_VIRT_BASE 0xfef80000
65#define IXP2000_GLOBAL_REG_VIRT_BASE 0xfef04000 65#define IXP2000_GLOBAL_REG_VIRT_BASE 0xfef04000
66#define IXP2000_UART_PHYS_BASE 0xc0030000 66#define IXP2000_UART_PHYS_BASE 0xc0030000
67#define IXP2000_UART_VIRT_BASE 0xfef30000 67#define IXP2000_UART_VIRT_BASE 0xfef30000
68#define IXP2000_TIMER_VIRT_BASE 0xfef20000 68#define IXP2000_TIMER_VIRT_BASE 0xfef20000
69#define IXP2000_GPIO_VIRT_BASE 0Xfef10000 69#define IXP2000_UENGINE_CSR_VIRT_BASE 0xfef18000
70#define IXP2000_GPIO_VIRT_BASE 0xfef10000
70 71
71/* 72/*
72 * Devices outside of the 0xc0000000 -> 0xc0100000 range. The virtual 73 * Devices outside of the 0xc0000000 -> 0xc0100000 range. The virtual
@@ -252,7 +253,7 @@
252#define IXP2000_PCI_XSCALE_INT_ENABLE IXP2000_PCI_CSR(0x15C) 253#define IXP2000_PCI_XSCALE_INT_ENABLE IXP2000_PCI_CSR(0x15C)
253 254
254#define IXP2000_PCICNTL_PNR (1<<17) /* PCI not Reset bit of PCI_CONTROL */ 255#define IXP2000_PCICNTL_PNR (1<<17) /* PCI not Reset bit of PCI_CONTROL */
255#define IXP2000_PCICNTL_PCF (1<<28) /* PCI Centrolfunction bit */ 256#define IXP2000_PCICNTL_PCF (1<<28) /* PCI Central function bit */
256#define IXP2000_XSCALE_INT (1<<1) /* Interrupt from XScale to PCI */ 257#define IXP2000_XSCALE_INT (1<<1) /* Interrupt from XScale to PCI */
257 258
258/* These are from the IRQ register in the PCI ISR register */ 259/* These are from the IRQ register in the PCI ISR register */
diff --git a/include/asm-arm/arch-ixp2000/system.h b/include/asm-arm/arch-ixp2000/system.h
index 4f489cc0dfa5..ddbbb34b5f95 100644
--- a/include/asm-arm/arch-ixp2000/system.h
+++ b/include/asm-arm/arch-ixp2000/system.h
@@ -26,29 +26,24 @@ static inline void arch_reset(char mode)
26 * RedBoot bank. 26 * RedBoot bank.
27 */ 27 */
28 if (machine_is_ixdp2401()) { 28 if (machine_is_ixdp2401()) {
29 *IXDP2X01_CPLD_FLASH_REG = ((0 >> IXDP2X01_FLASH_WINDOW_BITS) 29 ixp2000_reg_write(IXDP2X01_CPLD_FLASH_REG,
30 | IXDP2X01_CPLD_FLASH_INTERN); 30 ((0 >> IXDP2X01_FLASH_WINDOW_BITS)
31 *IXDP2X01_CPLD_RESET_REG = 0xffffffff; 31 | IXDP2X01_CPLD_FLASH_INTERN));
32 ixp2000_reg_wrb(IXDP2X01_CPLD_RESET_REG, 0xffffffff);
32 } 33 }
33 34
34 /* 35 /*
35 * On IXDP2801 we need to write this magic sequence to the CPLD 36 * On IXDP2801 we need to write this magic sequence to the CPLD
36 * to cause a complete reset of the CPU and all external devices 37 * to cause a complete reset of the CPU and all external devices
37 * and moves the flash bank register back to 0. 38 * and move the flash bank register back to 0.
38 */ 39 */
39 if (machine_is_ixdp2801()) { 40 if (machine_is_ixdp2801()) {
40 unsigned long reset_reg = *IXDP2X01_CPLD_RESET_REG; 41 unsigned long reset_reg = *IXDP2X01_CPLD_RESET_REG;
42
41 reset_reg = 0x55AA0000 | (reset_reg & 0x0000FFFF); 43 reset_reg = 0x55AA0000 | (reset_reg & 0x0000FFFF);
42 *IXDP2X01_CPLD_RESET_REG = reset_reg; 44 ixp2000_reg_write(IXDP2X01_CPLD_RESET_REG, reset_reg);
43 mb(); 45 ixp2000_reg_wrb(IXDP2X01_CPLD_RESET_REG, 0x80000000);
44 *IXDP2X01_CPLD_RESET_REG = 0x80000000;
45 } 46 }
46 47
47 /* 48 ixp2000_reg_wrb(IXP2000_RESET0, RSTALL);
48 * We do a reset all if we are PCI master. We could be a slave and we
49 * don't want to do anything funky on the PCI bus.
50 */
51 if (*IXP2000_STRAP_OPTIONS & CFG_PCI_BOOT_HOST) {
52 *(IXP2000_RESET0) |= (RSTALL);
53 }
54} 49}
diff --git a/include/asm-arm/arch-ixp2000/uengine.h b/include/asm-arm/arch-ixp2000/uengine.h
new file mode 100644
index 000000000000..b442d65c6593
--- /dev/null
+++ b/include/asm-arm/arch-ixp2000/uengine.h
@@ -0,0 +1,62 @@
1/*
2 * Generic library functions for the microengines found on the Intel
3 * IXP2000 series of network processors.
4 *
5 * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
6 * Dedicated to Marija Kulikova.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as
10 * published by the Free Software Foundation; either version 2.1 of the
11 * License, or (at your option) any later version.
12 */
13
14#ifndef __IXP2000_UENGINE_H
15#define __IXP2000_UENGINE_H
16
17extern u32 ixp2000_uengine_mask;
18
19struct ixp2000_uengine_code
20{
21 u32 cpu_model_bitmask;
22 u8 cpu_min_revision;
23 u8 cpu_max_revision;
24
25 u32 uengine_parameters;
26
27 struct ixp2000_reg_value {
28 int reg;
29 u32 value;
30 } *initial_reg_values;
31
32 int num_insns;
33 u8 *insns;
34};
35
36u32 ixp2000_uengine_csr_read(int uengine, int offset);
37void ixp2000_uengine_csr_write(int uengine, int offset, u32 value);
38void ixp2000_uengine_reset(u32 uengine_mask);
39void ixp2000_uengine_set_mode(int uengine, u32 mode);
40void ixp2000_uengine_load_microcode(int uengine, u8 *ucode, int insns);
41void ixp2000_uengine_init_context(int uengine, int context, int pc);
42void ixp2000_uengine_start_contexts(int uengine, u8 ctx_mask);
43void ixp2000_uengine_stop_contexts(int uengine, u8 ctx_mask);
44int ixp2000_uengine_load(int uengine, struct ixp2000_uengine_code *c);
45
46#define IXP2000_UENGINE_8_CONTEXTS 0x00000000
47#define IXP2000_UENGINE_4_CONTEXTS 0x80000000
48#define IXP2000_UENGINE_PRN_UPDATE_EVERY 0x40000000
49#define IXP2000_UENGINE_PRN_UPDATE_ON_ACCESS 0x00000000
50#define IXP2000_UENGINE_NN_FROM_SELF 0x00100000
51#define IXP2000_UENGINE_NN_FROM_PREVIOUS 0x00000000
52#define IXP2000_UENGINE_ASSERT_EMPTY_AT_3 0x000c0000
53#define IXP2000_UENGINE_ASSERT_EMPTY_AT_2 0x00080000
54#define IXP2000_UENGINE_ASSERT_EMPTY_AT_1 0x00040000
55#define IXP2000_UENGINE_ASSERT_EMPTY_AT_0 0x00000000
56#define IXP2000_UENGINE_LM_ADDR1_GLOBAL 0x00020000
57#define IXP2000_UENGINE_LM_ADDR1_PER_CONTEXT 0x00000000
58#define IXP2000_UENGINE_LM_ADDR0_GLOBAL 0x00010000
59#define IXP2000_UENGINE_LM_ADDR0_PER_CONTEXT 0x00000000
60
61
62#endif
diff --git a/include/asm-arm/arch-realview/debug-macro.S b/include/asm-arm/arch-realview/debug-macro.S
new file mode 100644
index 000000000000..ed28bd012236
--- /dev/null
+++ b/include/asm-arm/arch-realview/debug-macro.S
@@ -0,0 +1,38 @@
1/* linux/include/asm-arm/arch-realview/debug-macro.S
2 *
3 * Debugging macro include header
4 *
5 * Copyright (C) 1994-1999 Russell King
6 * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12*/
13
14#include <asm/hardware/amba_serial.h>
15
16 .macro addruart,rx
17 mrc p15, 0, \rx, c1, c0
18 tst \rx, #1 @ MMU enabled?
19 moveq \rx, #0x10000000
20 movne \rx, #0xf1000000 @ virtual base
21 orr \rx, \rx, #0x00009000
22 .endm
23
24 .macro senduart,rd,rx
25 strb \rd, [\rx, #UART01x_DR]
26 .endm
27
28 .macro waituart,rd,rx
291001: ldr \rd, [\rx, #0x18] @ UARTFLG
30 tst \rd, #1 << 5 @ UARTFLGUTXFF - 1 when full
31 bne 1001b
32 .endm
33
34 .macro busyuart,rd,rx
351001: ldr \rd, [\rx, #0x18] @ UARTFLG
36 tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy
37 bne 1001b
38 .endm
diff --git a/include/asm-arm/arch-realview/dma.h b/include/asm-arm/arch-realview/dma.h
new file mode 100644
index 000000000000..744491a74bd9
--- /dev/null
+++ b/include/asm-arm/arch-realview/dma.h
@@ -0,0 +1,27 @@
1/*
2 * linux/include/asm-arm/arch-realview/dma.h
3 *
4 * Copyright (C) 2003 ARM Limited.
5 * Copyright (C) 1997,1998 Russell King
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#ifndef __ASM_ARCH_DMA_H
22#define __ASM_ARCH_DMA_H
23
24#define MAX_DMA_ADDRESS 0xffffffff
25#define MAX_DMA_CHANNELS 0
26
27#endif /* _ASM_ARCH_DMA_H */
diff --git a/include/asm-arm/arch-realview/entry-macro.S b/include/asm-arm/arch-realview/entry-macro.S
new file mode 100644
index 000000000000..2712ba77bb3a
--- /dev/null
+++ b/include/asm-arm/arch-realview/entry-macro.S
@@ -0,0 +1,49 @@
1/*
2 * include/asm-arm/arch-realview/entry-macro.S
3 *
4 * Low-level IRQ helper macros for RealView platforms
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#include <asm/hardware/gic.h>
12
13 .macro disable_fiq
14 .endm
15
16 /*
17 * The interrupt numbering scheme is defined in the
18 * interrupt controller spec. To wit:
19 *
20 * Interrupts 0-15 are IPI
21 * 16-28 are reserved
22 * 29-31 are local. We allow 30 to be used for the watchdog.
23 * 32-1020 are global
24 * 1021-1022 are reserved
25 * 1023 is "spurious" (no interrupt)
26 *
27 * For now, we ignore all local interrupts so only return an interrupt if it's
28 * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
29 *
30 * A simple read from the controller will tell us the number of the highest
31 * priority enabled interrupt. We then just need to check whether it is in the
32 * valid range for an IRQ (30-1020 inclusive).
33 */
34
35 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
36
37 ldr \base, =IO_ADDRESS(REALVIEW_GIC_CPU_BASE)
38 ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
39
40 ldr \tmp, =1021
41
42 bic \irqnr, \irqstat, #0x1c00
43
44 cmp \irqnr, #29
45 cmpcc \irqnr, \irqnr
46 cmpne \irqnr, \tmp
47 cmpcs \irqnr, \irqnr
48
49 .endm
diff --git a/include/asm-arm/arch-realview/hardware.h b/include/asm-arm/arch-realview/hardware.h
new file mode 100644
index 000000000000..67879cdb6ef2
--- /dev/null
+++ b/include/asm-arm/arch-realview/hardware.h
@@ -0,0 +1,31 @@
1/*
2 * linux/include/asm-arm/arch-realview/hardware.h
3 *
4 * This file contains the hardware definitions of the RealView boards.
5 *
6 * Copyright (C) 2003 ARM Limited.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22#ifndef __ASM_ARCH_HARDWARE_H
23#define __ASM_ARCH_HARDWARE_H
24
25#include <asm/sizes.h>
26#include <asm/arch/platform.h>
27
28/* macro to get at IO space when running virtually */
29#define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
30
31#endif
diff --git a/include/asm-arm/arch-realview/io.h b/include/asm-arm/arch-realview/io.h
new file mode 100644
index 000000000000..d444a68ac330
--- /dev/null
+++ b/include/asm-arm/arch-realview/io.h
@@ -0,0 +1,34 @@
1/*
2 * linux/include/asm-arm/arch-realview/io.h
3 *
4 * Copyright (C) 2003 ARM Limited
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#ifndef __ASM_ARM_ARCH_IO_H
21#define __ASM_ARM_ARCH_IO_H
22
23#define IO_SPACE_LIMIT 0xffffffff
24
25static inline void __iomem *__io(unsigned long addr)
26{
27 return (void __iomem *)addr;
28}
29
30#define __io(a) __io(a)
31#define __mem_pci(a) (a)
32#define __mem_isa(a) (a)
33
34#endif
diff --git a/include/asm-arm/arch-realview/irqs.h b/include/asm-arm/arch-realview/irqs.h
new file mode 100644
index 000000000000..ff376494e5b1
--- /dev/null
+++ b/include/asm-arm/arch-realview/irqs.h
@@ -0,0 +1,103 @@
1/*
2 * linux/include/asm-arm/arch-realview/irqs.h
3 *
4 * Copyright (C) 2003 ARM Limited
5 * Copyright (C) 2000 Deep Blue Solutions Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <asm/arch/platform.h>
23
24/*
25 * IRQ interrupts definitions are the same the INT definitions
26 * held within platform.h
27 */
28#define IRQ_GIC_START 32
29#define IRQ_WDOGINT (IRQ_GIC_START + INT_WDOGINT)
30#define IRQ_SOFTINT (IRQ_GIC_START + INT_SOFTINT)
31#define IRQ_COMMRx (IRQ_GIC_START + INT_COMMRx)
32#define IRQ_COMMTx (IRQ_GIC_START + INT_COMMTx)
33#define IRQ_TIMERINT0_1 (IRQ_GIC_START + INT_TIMERINT0_1)
34#define IRQ_TIMERINT2_3 (IRQ_GIC_START + INT_TIMERINT2_3)
35#define IRQ_GPIOINT0 (IRQ_GIC_START + INT_GPIOINT0)
36#define IRQ_GPIOINT1 (IRQ_GIC_START + INT_GPIOINT1)
37#define IRQ_GPIOINT2 (IRQ_GIC_START + INT_GPIOINT2)
38#define IRQ_GPIOINT3 (IRQ_GIC_START + INT_GPIOINT3)
39#define IRQ_RTCINT (IRQ_GIC_START + INT_RTCINT)
40#define IRQ_SSPINT (IRQ_GIC_START + INT_SSPINT)
41#define IRQ_UARTINT0 (IRQ_GIC_START + INT_UARTINT0)
42#define IRQ_UARTINT1 (IRQ_GIC_START + INT_UARTINT1)
43#define IRQ_UARTINT2 (IRQ_GIC_START + INT_UARTINT2)
44#define IRQ_UART3 (IRQ_GIC_START + INT_UARTINT3)
45#define IRQ_SCIINT (IRQ_GIC_START + INT_SCIINT)
46#define IRQ_CLCDINT (IRQ_GIC_START + INT_CLCDINT)
47#define IRQ_DMAINT (IRQ_GIC_START + INT_DMAINT)
48#define IRQ_PWRFAILINT (IRQ_GIC_START + INT_PWRFAILINT)
49#define IRQ_MBXINT (IRQ_GIC_START + INT_MBXINT)
50#define IRQ_GNDINT (IRQ_GIC_START + INT_GNDINT)
51#define IRQ_MMCI0B (IRQ_GIC_START + INT_MMCI0B)
52#define IRQ_MMCI1B (IRQ_GIC_START + INT_MMCI1B)
53#define IRQ_KMI0 (IRQ_GIC_START + INT_KMI0)
54#define IRQ_KMI1 (IRQ_GIC_START + INT_KMI1)
55#define IRQ_SCI3 (IRQ_GIC_START + INT_SCI3)
56#define IRQ_CLCD (IRQ_GIC_START + INT_CLCD)
57#define IRQ_TOUCH (IRQ_GIC_START + INT_TOUCH)
58#define IRQ_KEYPAD (IRQ_GIC_START + INT_KEYPAD)
59#define IRQ_DoC (IRQ_GIC_START + INT_DoC)
60#define IRQ_MMCI0A (IRQ_GIC_START + INT_MMCI0A)
61#define IRQ_MMCI1A (IRQ_GIC_START + INT_MMCI1A)
62#define IRQ_AACI (IRQ_GIC_START + INT_AACI)
63#define IRQ_ETH (IRQ_GIC_START + INT_ETH)
64#define IRQ_USB (IRQ_GIC_START + INT_USB)
65
66#define IRQMASK_WDOGINT INTMASK_WDOGINT
67#define IRQMASK_SOFTINT INTMASK_SOFTINT
68#define IRQMASK_COMMRx INTMASK_COMMRx
69#define IRQMASK_COMMTx INTMASK_COMMTx
70#define IRQMASK_TIMERINT0_1 INTMASK_TIMERINT0_1
71#define IRQMASK_TIMERINT2_3 INTMASK_TIMERINT2_3
72#define IRQMASK_GPIOINT0 INTMASK_GPIOINT0
73#define IRQMASK_GPIOINT1 INTMASK_GPIOINT1
74#define IRQMASK_GPIOINT2 INTMASK_GPIOINT2
75#define IRQMASK_GPIOINT3 INTMASK_GPIOINT3
76#define IRQMASK_RTCINT INTMASK_RTCINT
77#define IRQMASK_SSPINT INTMASK_SSPINT
78#define IRQMASK_UARTINT0 INTMASK_UARTINT0
79#define IRQMASK_UARTINT1 INTMASK_UARTINT1
80#define IRQMASK_UARTINT2 INTMASK_UARTINT2
81#define IRQMASK_SCIINT INTMASK_SCIINT
82#define IRQMASK_CLCDINT INTMASK_CLCDINT
83#define IRQMASK_DMAINT INTMASK_DMAINT
84#define IRQMASK_PWRFAILINT INTMASK_PWRFAILINT
85#define IRQMASK_MBXINT INTMASK_MBXINT
86#define IRQMASK_GNDINT INTMASK_GNDINT
87#define IRQMASK_MMCI0B INTMASK_MMCI0B
88#define IRQMASK_MMCI1B INTMASK_MMCI1B
89#define IRQMASK_KMI0 INTMASK_KMI0
90#define IRQMASK_KMI1 INTMASK_KMI1
91#define IRQMASK_SCI3 INTMASK_SCI3
92#define IRQMASK_UART3 INTMASK_UART3
93#define IRQMASK_CLCD INTMASK_CLCD
94#define IRQMASK_TOUCH INTMASK_TOUCH
95#define IRQMASK_KEYPAD INTMASK_KEYPAD
96#define IRQMASK_DoC INTMASK_DoC
97#define IRQMASK_MMCI0A INTMASK_MMCI0A
98#define IRQMASK_MMCI1A INTMASK_MMCI1A
99#define IRQMASK_AACI INTMASK_AACI
100#define IRQMASK_ETH INTMASK_ETH
101#define IRQMASK_USB INTMASK_USB
102
103#define NR_IRQS (IRQ_GIC_START + 64)
diff --git a/include/asm-arm/arch-realview/memory.h b/include/asm-arm/arch-realview/memory.h
new file mode 100644
index 000000000000..99667d5cc617
--- /dev/null
+++ b/include/asm-arm/arch-realview/memory.h
@@ -0,0 +1,38 @@
1/*
2 * linux/include/asm-arm/arch-realview/memory.h
3 *
4 * Copyright (C) 2003 ARM Limited
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#ifndef __ASM_ARCH_MEMORY_H
21#define __ASM_ARCH_MEMORY_H
22
23/*
24 * Physical DRAM offset.
25 */
26#define PHYS_OFFSET (0x00000000UL)
27
28/*
29 * Virtual view <-> DMA view memory address translations
30 * virt_to_bus: Used to translate the virtual address to an
31 * address suitable to be passed to set_dma_addr
32 * bus_to_virt: Used to convert an address for DMA operations
33 * to an address that the kernel can use.
34 */
35#define __virt_to_bus(x) ((x) - PAGE_OFFSET)
36#define __bus_to_virt(x) ((x) + PAGE_OFFSET)
37
38#endif
diff --git a/include/asm-arm/arch-realview/param.h b/include/asm-arm/arch-realview/param.h
new file mode 100644
index 000000000000..89b1235d32bd
--- /dev/null
+++ b/include/asm-arm/arch-realview/param.h
@@ -0,0 +1,19 @@
1/*
2 * linux/include/asm-arm/arch-realview/param.h
3 *
4 * Copyright (C) 2002 ARM Limited
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
diff --git a/include/asm-arm/arch-realview/platform.h b/include/asm-arm/arch-realview/platform.h
new file mode 100644
index 000000000000..4b6de13a6b9a
--- /dev/null
+++ b/include/asm-arm/arch-realview/platform.h
@@ -0,0 +1,395 @@
1/*
2 * linux/include/asm-arm/arch-realview/platform.h
3 *
4 * Copyright (c) ARM Limited 2003. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef __address_h
22#define __address_h 1
23
24/*
25 * Memory definitions
26 */
27#define REALVIEW_BOOT_ROM_LO 0x30000000 /* DoC Base (64Mb)...*/
28#define REALVIEW_BOOT_ROM_HI 0x30000000
29#define REALVIEW_BOOT_ROM_BASE REALVIEW_BOOT_ROM_HI /* Normal position */
30#define REALVIEW_BOOT_ROM_SIZE SZ_64M
31
32#define REALVIEW_SSRAM_BASE /* REALVIEW_SSMC_BASE ? */
33#define REALVIEW_SSRAM_SIZE SZ_2M
34
35#define REALVIEW_FLASH_BASE 0x40000000
36#define REALVIEW_FLASH_SIZE SZ_64M
37
38/*
39 * SDRAM
40 */
41#define REALVIEW_SDRAM_BASE 0x00000000
42
43/*
44 * Logic expansion modules
45 *
46 */
47
48
49/* ------------------------------------------------------------------------
50 * RealView Registers
51 * ------------------------------------------------------------------------
52 *
53 */
54#define REALVIEW_SYS_ID_OFFSET 0x00
55#define REALVIEW_SYS_SW_OFFSET 0x04
56#define REALVIEW_SYS_LED_OFFSET 0x08
57#define REALVIEW_SYS_OSC0_OFFSET 0x0C
58
59#define REALVIEW_SYS_OSC1_OFFSET 0x10
60#define REALVIEW_SYS_OSC2_OFFSET 0x14
61#define REALVIEW_SYS_OSC3_OFFSET 0x18
62#define REALVIEW_SYS_OSC4_OFFSET 0x1C /* OSC1 for RealView/AB */
63
64#define REALVIEW_SYS_LOCK_OFFSET 0x20
65#define REALVIEW_SYS_100HZ_OFFSET 0x24
66#define REALVIEW_SYS_CFGDATA1_OFFSET 0x28
67#define REALVIEW_SYS_CFGDATA2_OFFSET 0x2C
68#define REALVIEW_SYS_FLAGS_OFFSET 0x30
69#define REALVIEW_SYS_FLAGSSET_OFFSET 0x30
70#define REALVIEW_SYS_FLAGSCLR_OFFSET 0x34
71#define REALVIEW_SYS_NVFLAGS_OFFSET 0x38
72#define REALVIEW_SYS_NVFLAGSSET_OFFSET 0x38
73#define REALVIEW_SYS_NVFLAGSCLR_OFFSET 0x3C
74#define REALVIEW_SYS_RESETCTL_OFFSET 0x40
75#define REALVIEW_SYS_PCICTL_OFFSET 0x44
76#define REALVIEW_SYS_MCI_OFFSET 0x48
77#define REALVIEW_SYS_FLASH_OFFSET 0x4C
78#define REALVIEW_SYS_CLCD_OFFSET 0x50
79#define REALVIEW_SYS_CLCDSER_OFFSET 0x54
80#define REALVIEW_SYS_BOOTCS_OFFSET 0x58
81#define REALVIEW_SYS_24MHz_OFFSET 0x5C
82#define REALVIEW_SYS_MISC_OFFSET 0x60
83#define REALVIEW_SYS_IOSEL_OFFSET 0x70
84#define REALVIEW_SYS_TEST_OSC0_OFFSET 0x80
85#define REALVIEW_SYS_TEST_OSC1_OFFSET 0x84
86#define REALVIEW_SYS_TEST_OSC2_OFFSET 0x88
87#define REALVIEW_SYS_TEST_OSC3_OFFSET 0x8C
88#define REALVIEW_SYS_TEST_OSC4_OFFSET 0x90
89
90#define REALVIEW_SYS_BASE 0x10000000
91#define REALVIEW_SYS_ID (REALVIEW_SYS_BASE + REALVIEW_SYS_ID_OFFSET)
92#define REALVIEW_SYS_SW (REALVIEW_SYS_BASE + REALVIEW_SYS_SW_OFFSET)
93#define REALVIEW_SYS_LED (REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET)
94#define REALVIEW_SYS_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC0_OFFSET)
95#define REALVIEW_SYS_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC1_OFFSET)
96
97#define REALVIEW_SYS_LOCK (REALVIEW_SYS_BASE + REALVIEW_SYS_LOCK_OFFSET)
98#define REALVIEW_SYS_100HZ (REALVIEW_SYS_BASE + REALVIEW_SYS_100HZ_OFFSET)
99#define REALVIEW_SYS_CFGDATA1 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA1_OFFSET)
100#define REALVIEW_SYS_CFGDATA2 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA2_OFFSET)
101#define REALVIEW_SYS_FLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGS_OFFSET)
102#define REALVIEW_SYS_FLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSSET_OFFSET)
103#define REALVIEW_SYS_FLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSCLR_OFFSET)
104#define REALVIEW_SYS_NVFLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGS_OFFSET)
105#define REALVIEW_SYS_NVFLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSSET_OFFSET)
106#define REALVIEW_SYS_NVFLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSCLR_OFFSET)
107#define REALVIEW_SYS_RESETCTL (REALVIEW_SYS_BASE + REALVIEW_SYS_RESETCTL_OFFSET)
108#define REALVIEW_SYS_PCICTL (REALVIEW_SYS_BASE + REALVIEW_SYS_PCICTL_OFFSET)
109#define REALVIEW_SYS_MCI (REALVIEW_SYS_BASE + REALVIEW_SYS_MCI_OFFSET)
110#define REALVIEW_SYS_FLASH (REALVIEW_SYS_BASE + REALVIEW_SYS_FLASH_OFFSET)
111#define REALVIEW_SYS_CLCD (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCD_OFFSET)
112#define REALVIEW_SYS_CLCDSER (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCDSER_OFFSET)
113#define REALVIEW_SYS_BOOTCS (REALVIEW_SYS_BASE + REALVIEW_SYS_BOOTCS_OFFSET)
114#define REALVIEW_SYS_24MHz (REALVIEW_SYS_BASE + REALVIEW_SYS_24MHz_OFFSET)
115#define REALVIEW_SYS_MISC (REALVIEW_SYS_BASE + REALVIEW_SYS_MISC_OFFSET)
116#define REALVIEW_SYS_IOSEL (REALVIEW_SYS_BASE + REALVIEW_SYS_IOSEL_OFFSET)
117#define REALVIEW_SYS_TEST_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC0_OFFSET)
118#define REALVIEW_SYS_TEST_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC1_OFFSET)
119#define REALVIEW_SYS_TEST_OSC2 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC2_OFFSET)
120#define REALVIEW_SYS_TEST_OSC3 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET)
121#define REALVIEW_SYS_TEST_OSC4 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET)
122
123/*
124 * Values for REALVIEW_SYS_RESET_CTRL
125 */
126#define REALVIEW_SYS_CTRL_RESET_CONFIGCLR 0x01
127#define REALVIEW_SYS_CTRL_RESET_CONFIGINIT 0x02
128#define REALVIEW_SYS_CTRL_RESET_DLLRESET 0x03
129#define REALVIEW_SYS_CTRL_RESET_PLLRESET 0x04
130#define REALVIEW_SYS_CTRL_RESET_POR 0x05
131#define REALVIEW_SYS_CTRL_RESET_DoC 0x06
132
133#define REALVIEW_SYS_CTRL_LED (1 << 0)
134
135
136/* ------------------------------------------------------------------------
137 * RealView control registers
138 * ------------------------------------------------------------------------
139 */
140
141/*
142 * REALVIEW_IDFIELD
143 *
144 * 31:24 = manufacturer (0x41 = ARM)
145 * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus)
146 * 15:12 = FPGA (0x3 = XVC600 or XVC600E)
147 * 11:4 = build value
148 * 3:0 = revision number (0x1 = rev B (AHB))
149 */
150
151/*
152 * REALVIEW_SYS_LOCK
153 * control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL,
154 * SYS_CLD, SYS_BOOTCS
155 */
156#define REALVIEW_SYS_LOCK_LOCKED (1 << 16)
157#define REALVIEW_SYS_LOCKVAL_MASK 0xFFFF /* write 0xA05F to enable write access */
158
159/*
160 * REALVIEW_SYS_FLASH
161 */
162#define REALVIEW_FLASHPROG_FLVPPEN (1 << 0) /* Enable writing to flash */
163
164/*
165 * REALVIEW_INTREG
166 * - used to acknowledge and control MMCI and UART interrupts
167 */
168#define REALVIEW_INTREG_WPROT 0x00 /* MMC protection status (no interrupt generated) */
169#define REALVIEW_INTREG_RI0 0x01 /* Ring indicator UART0 is asserted, */
170#define REALVIEW_INTREG_CARDIN 0x08 /* MMCI card in detect */
171 /* write 1 to acknowledge and clear */
172#define REALVIEW_INTREG_RI1 0x02 /* Ring indicator UART1 is asserted, */
173#define REALVIEW_INTREG_CARDINSERT 0x03 /* Signal insertion of MMC card */
174
175/*
176 * REALVIEW peripheral addresses
177 */
178#define REALVIEW_SCTL_BASE 0x10001000 /* System controller */
179#define REALVIEW_I2C_BASE 0x10002000 /* I2C control */
180 /* Reserved 0x10003000 */
181#define REALVIEW_AACI_BASE 0x10004000 /* Audio */
182#define REALVIEW_MMCI0_BASE 0x10005000 /* MMC interface */
183#define REALVIEW_KMI0_BASE 0x10006000 /* KMI interface */
184#define REALVIEW_KMI1_BASE 0x10007000 /* KMI 2nd interface */
185#define REALVIEW_CHAR_LCD_BASE 0x10008000 /* Character LCD */
186#define REALVIEW_UART0_BASE 0x10009000 /* UART 0 */
187#define REALVIEW_UART1_BASE 0x1000A000 /* UART 1 */
188#define REALVIEW_UART2_BASE 0x1000B000 /* UART 2 */
189#define REALVIEW_UART3_BASE 0x1000C000 /* UART 3 */
190#define REALVIEW_SSP_BASE 0x1000D000 /* Synchronous Serial Port */
191#define REALVIEW_SCI_BASE 0x1000E000 /* Smart card controller */
192 /* Reserved 0x1000F000 */
193#define REALVIEW_WATCHDOG_BASE 0x10010000 /* watchdog interface */
194#define REALVIEW_TIMER0_1_BASE 0x10011000 /* Timer 0 and 1 */
195#define REALVIEW_TIMER2_3_BASE 0x10012000 /* Timer 2 and 3 */
196#define REALVIEW_GPIO0_BASE 0x10013000 /* GPIO port 0 */
197#define REALVIEW_GPIO1_BASE 0x10014000 /* GPIO port 1 */
198#define REALVIEW_GPIO2_BASE 0x10015000 /* GPIO port 2 */
199 /* Reserved 0x10016000 */
200#define REALVIEW_RTC_BASE 0x10017000 /* Real Time Clock */
201#define REALVIEW_DMC_BASE 0x10018000 /* DMC configuration */
202#define REALVIEW_PCI_CORE_BASE 0x10019000 /* PCI configuration */
203 /* Reserved 0x1001A000 - 0x1001FFFF */
204#define REALVIEW_CLCD_BASE 0x10020000 /* CLCD */
205#define REALVIEW_DMAC_BASE 0x10030000 /* DMA controller */
206#define REALVIEW_GIC_CPU_BASE 0x10040000 /* Generic interrupt controller CPU interface */
207#define REALVIEW_GIC_DIST_BASE 0x10041000 /* Generic interrupt controller distributor */
208#define REALVIEW_SMC_BASE 0x10080000 /* SMC */
209 /* Reserved 0x10090000 - 0x100EFFFF */
210
211#define REALVIEW_ETH_BASE 0x4E000000 /* Ethernet */
212
213/* PCI space */
214#define REALVIEW_PCI_BASE 0x41000000 /* PCI Interface */
215#define REALVIEW_PCI_CFG_BASE 0x42000000
216#define REALVIEW_PCI_MEM_BASE0 0x44000000
217#define REALVIEW_PCI_MEM_BASE1 0x50000000
218#define REALVIEW_PCI_MEM_BASE2 0x60000000
219/* Sizes of above maps */
220#define REALVIEW_PCI_BASE_SIZE 0x01000000
221#define REALVIEW_PCI_CFG_BASE_SIZE 0x02000000
222#define REALVIEW_PCI_MEM_BASE0_SIZE 0x0c000000 /* 32Mb */
223#define REALVIEW_PCI_MEM_BASE1_SIZE 0x10000000 /* 256Mb */
224#define REALVIEW_PCI_MEM_BASE2_SIZE 0x10000000 /* 256Mb */
225
226#define REALVIEW_SDRAM67_BASE 0x70000000 /* SDRAM banks 6 and 7 */
227#define REALVIEW_LT_BASE 0x80000000 /* Logic Tile expansion */
228
229/*
230 * Disk on Chip
231 */
232#define REALVIEW_DOC_BASE 0x2C000000
233#define REALVIEW_DOC_SIZE (16 << 20)
234#define REALVIEW_DOC_PAGE_SIZE 512
235#define REALVIEW_DOC_TOTAL_PAGES (DOC_SIZE / PAGE_SIZE)
236
237#define ERASE_UNIT_PAGES 32
238#define START_PAGE 0x80
239
240/*
241 * LED settings, bits [7:0]
242 */
243#define REALVIEW_SYS_LED0 (1 << 0)
244#define REALVIEW_SYS_LED1 (1 << 1)
245#define REALVIEW_SYS_LED2 (1 << 2)
246#define REALVIEW_SYS_LED3 (1 << 3)
247#define REALVIEW_SYS_LED4 (1 << 4)
248#define REALVIEW_SYS_LED5 (1 << 5)
249#define REALVIEW_SYS_LED6 (1 << 6)
250#define REALVIEW_SYS_LED7 (1 << 7)
251
252#define ALL_LEDS 0xFF
253
254#define LED_BANK REALVIEW_SYS_LED
255
256/*
257 * Control registers
258 */
259#define REALVIEW_IDFIELD_OFFSET 0x0 /* RealView build information */
260#define REALVIEW_FLASHPROG_OFFSET 0x4 /* Flash devices */
261#define REALVIEW_INTREG_OFFSET 0x8 /* Interrupt control */
262#define REALVIEW_DECODE_OFFSET 0xC /* Fitted logic modules */
263
264/* ------------------------------------------------------------------------
265 * Interrupts - bit assignment (primary)
266 * ------------------------------------------------------------------------
267 */
268#define INT_WDOGINT 0 /* Watchdog timer */
269#define INT_SOFTINT 1 /* Software interrupt */
270#define INT_COMMRx 2 /* Debug Comm Rx interrupt */
271#define INT_COMMTx 3 /* Debug Comm Tx interrupt */
272#define INT_TIMERINT0_1 4 /* Timer 0 and 1 */
273#define INT_TIMERINT2_3 5 /* Timer 2 and 3 */
274#define INT_GPIOINT0 6 /* GPIO 0 */
275#define INT_GPIOINT1 7 /* GPIO 1 */
276#define INT_GPIOINT2 8 /* GPIO 2 */
277/* 9 reserved */
278#define INT_RTCINT 10 /* Real Time Clock */
279#define INT_SSPINT 11 /* Synchronous Serial Port */
280#define INT_UARTINT0 12 /* UART 0 on development chip */
281#define INT_UARTINT1 13 /* UART 1 on development chip */
282#define INT_UARTINT2 14 /* UART 2 on development chip */
283#define INT_UARTINT3 15 /* UART 3 on development chip */
284#define INT_SCIINT 16 /* Smart Card Interface */
285#define INT_MMCI0A 17 /* Multimedia Card 0A */
286#define INT_MMCI0B 18 /* Multimedia Card 0B */
287#define INT_AACI 19 /* Audio Codec */
288#define INT_KMI0 20 /* Keyboard/Mouse port 0 */
289#define INT_KMI1 21 /* Keyboard/Mouse port 1 */
290#define INT_CHARLCD 22 /* Character LCD */
291#define INT_CLCDINT 23 /* CLCD controller */
292#define INT_DMAINT 24 /* DMA controller */
293#define INT_PWRFAILINT 25 /* Power failure */
294#define INT_PISMO 26
295#define INT_DoC 27 /* Disk on Chip memory controller */
296#define INT_ETH 28 /* Ethernet controller */
297#define INT_USB 29 /* USB controller */
298#define INT_TSPENINT 30 /* Touchscreen pen */
299#define INT_TSKPADINT 31 /* Touchscreen keypad */
300
301/*
302 * Interrupt bit positions
303 *
304 */
305#define INTMASK_WDOGINT (1 << INT_WDOGINT)
306#define INTMASK_SOFTINT (1 << INT_SOFTINT)
307#define INTMASK_COMMRx (1 << INT_COMMRx)
308#define INTMASK_COMMTx (1 << INT_COMMTx)
309#define INTMASK_TIMERINT0_1 (1 << INT_TIMERINT0_1)
310#define INTMASK_TIMERINT2_3 (1 << INT_TIMERINT2_3)
311#define INTMASK_GPIOINT0 (1 << INT_GPIOINT0)
312#define INTMASK_GPIOINT1 (1 << INT_GPIOINT1)
313#define INTMASK_GPIOINT2 (1 << INT_GPIOINT2)
314#define INTMASK_RTCINT (1 << INT_RTCINT)
315#define INTMASK_SSPINT (1 << INT_SSPINT)
316#define INTMASK_UARTINT0 (1 << INT_UARTINT0)
317#define INTMASK_UARTINT1 (1 << INT_UARTINT1)
318#define INTMASK_UARTINT2 (1 << INT_UARTINT2)
319#define INTMASK_UARTINT3 (1 << INT_UARTINT3)
320#define INTMASK_SCIINT (1 << INT_SCIINT)
321#define INTMASK_MMCI0A (1 << INT_MMCI0A)
322#define INTMASK_MMCI0B (1 << INT_MMCI0B)
323#define INTMASK_AACI (1 << INT_AACI)
324#define INTMASK_KMI0 (1 << INT_KMI0)
325#define INTMASK_KMI1 (1 << INT_KMI1)
326#define INTMASK_CHARLCD (1 << INT_CHARLCD)
327#define INTMASK_CLCDINT (1 << INT_CLCDINT)
328#define INTMASK_DMAINT (1 << INT_DMAINT)
329#define INTMASK_PWRFAILINT (1 << INT_PWRFAILINT)
330#define INTMASK_PISMO (1 << INT_PISMO)
331#define INTMASK_DoC (1 << INT_DoC)
332#define INTMASK_ETH (1 << INT_ETH)
333#define INTMASK_USB (1 << INT_USB)
334#define INTMASK_TSPENINT (1 << INT_TSPENINT)
335#define INTMASK_TSKPADINT (1 << INT_TSKPADINT)
336
337#define MAXIRQNUM 31
338#define MAXFIQNUM 31
339#define MAXSWINUM 31
340
341/*
342 * Application Flash
343 *
344 */
345#define FLASH_BASE REALVIEW_FLASH_BASE
346#define FLASH_SIZE REALVIEW_FLASH_SIZE
347#define FLASH_END (FLASH_BASE + FLASH_SIZE - 1)
348#define FLASH_BLOCK_SIZE SZ_128K
349
350/*
351 * Boot Flash
352 *
353 */
354#define EPROM_BASE REALVIEW_BOOT_ROM_HI
355#define EPROM_SIZE REALVIEW_BOOT_ROM_SIZE
356#define EPROM_END (EPROM_BASE + EPROM_SIZE - 1)
357
358/*
359 * Clean base - dummy
360 *
361 */
362#define CLEAN_BASE EPROM_BASE
363
364/*
365 * System controller bit assignment
366 */
367#define REALVIEW_REFCLK 0
368#define REALVIEW_TIMCLK 1
369
370#define REALVIEW_TIMER1_EnSel 15
371#define REALVIEW_TIMER2_EnSel 17
372#define REALVIEW_TIMER3_EnSel 19
373#define REALVIEW_TIMER4_EnSel 21
374
375
376#define MAX_TIMER 2
377#define MAX_PERIOD 699050
378#define TICKS_PER_uSEC 1
379
380/*
381 * These are useconds NOT ticks.
382 *
383 */
384#define mSEC_1 1000
385#define mSEC_5 (mSEC_1 * 5)
386#define mSEC_10 (mSEC_1 * 10)
387#define mSEC_25 (mSEC_1 * 25)
388#define SEC_1 (mSEC_1 * 1000)
389
390#define REALVIEW_CSR_BASE 0x10000000
391#define REALVIEW_CSR_SIZE 0x10000000
392
393#endif
394
395/* END */
diff --git a/include/asm-arm/arch-realview/system.h b/include/asm-arm/arch-realview/system.h
new file mode 100644
index 000000000000..9f8fcbca0869
--- /dev/null
+++ b/include/asm-arm/arch-realview/system.h
@@ -0,0 +1,51 @@
1/*
2 * linux/include/asm-arm/arch-realview/system.h
3 *
4 * Copyright (C) 2003 ARM Limited
5 * Copyright (C) 2000 Deep Blue Solutions Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#ifndef __ASM_ARCH_SYSTEM_H
22#define __ASM_ARCH_SYSTEM_H
23
24#include <asm/hardware.h>
25#include <asm/io.h>
26#include <asm/arch/platform.h>
27
28static inline void arch_idle(void)
29{
30 /*
31 * This should do all the clock switching
32 * and wait for interrupt tricks
33 */
34 cpu_do_idle();
35}
36
37static inline void arch_reset(char mode)
38{
39 unsigned int hdr_ctrl = (IO_ADDRESS(REALVIEW_SYS_BASE) + REALVIEW_SYS_RESETCTL_OFFSET);
40 unsigned int val;
41
42 /*
43 * To reset, we hit the on-board reset register
44 * in the system FPGA
45 */
46 val = __raw_readl(hdr_ctrl);
47 val |= REALVIEW_SYS_CTRL_RESET_CONFIGCLR;
48 __raw_writel(val, hdr_ctrl);
49}
50
51#endif
diff --git a/include/asm-arm/arch-realview/timex.h b/include/asm-arm/arch-realview/timex.h
new file mode 100644
index 000000000000..5b9d82d0a5e0
--- /dev/null
+++ b/include/asm-arm/arch-realview/timex.h
@@ -0,0 +1,23 @@
1/*
2 * linux/include/asm-arm/arch-realview/timex.h
3 *
4 * RealView architecture timex specifications
5 *
6 * Copyright (C) 2003 ARM Limited
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#define CLOCK_TICK_RATE (50000000 / 16)
diff --git a/include/asm-arm/arch-realview/uncompress.h b/include/asm-arm/arch-realview/uncompress.h
new file mode 100644
index 000000000000..b5e4d360665b
--- /dev/null
+++ b/include/asm-arm/arch-realview/uncompress.h
@@ -0,0 +1,54 @@
1/*
2 * linux/include/asm-arm/arch-realview/uncompress.h
3 *
4 * Copyright (C) 2003 ARM Limited
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include <asm/hardware.h>
21
22#define AMBA_UART_DR (*(volatile unsigned char *) (REALVIEW_UART0_BASE + 0x00))
23#define AMBA_UART_LCRH (*(volatile unsigned char *) (REALVIEW_UART0_BASE + 0x2c))
24#define AMBA_UART_CR (*(volatile unsigned char *) (REALVIEW_UART0_BASE + 0x30))
25#define AMBA_UART_FR (*(volatile unsigned char *) (REALVIEW_UART0_BASE + 0x18))
26
27/*
28 * This does not append a newline
29 */
30static void putstr(const char *s)
31{
32 while (*s) {
33 while (AMBA_UART_FR & (1 << 5))
34 barrier();
35
36 AMBA_UART_DR = *s;
37
38 if (*s == '\n') {
39 while (AMBA_UART_FR & (1 << 5))
40 barrier();
41
42 AMBA_UART_DR = '\r';
43 }
44 s++;
45 }
46 while (AMBA_UART_FR & (1 << 3))
47 barrier();
48}
49
50/*
51 * nothing to do
52 */
53#define arch_decomp_setup()
54#define arch_decomp_wdog()
diff --git a/include/asm-arm/arch-realview/vmalloc.h b/include/asm-arm/arch-realview/vmalloc.h
new file mode 100644
index 000000000000..0ad49af186af
--- /dev/null
+++ b/include/asm-arm/arch-realview/vmalloc.h
@@ -0,0 +1,21 @@
1/*
2 * linux/include/asm-arm/arch-realview/vmalloc.h
3 *
4 * Copyright (C) 2003 ARM Limited
5 * Copyright (C) 2000 Russell King.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21#define VMALLOC_END (PAGE_OFFSET + 0x18000000)
diff --git a/include/asm-arm/arch-s3c2410/regs-iis.h b/include/asm-arm/arch-s3c2410/regs-iis.h
index fdd62e8cd6cb..7fdde9b91cb4 100644
--- a/include/asm-arm/arch-s3c2410/regs-iis.h
+++ b/include/asm-arm/arch-s3c2410/regs-iis.h
@@ -55,6 +55,7 @@
55#define S3C2410_IISMOD_16FS (0<<0) 55#define S3C2410_IISMOD_16FS (0<<0)
56#define S3C2410_IISMOD_32FS (1<<0) 56#define S3C2410_IISMOD_32FS (1<<0)
57#define S3C2410_IISMOD_48FS (2<<0) 57#define S3C2410_IISMOD_48FS (2<<0)
58#define S3C2410_IISMOD_FS_MASK (3<<0)
58 59
59#define S3C2410_IISPSR (0x08) 60#define S3C2410_IISPSR (0x08)
60#define S3C2410_IISPSR_INTMASK (31<<5) 61#define S3C2410_IISPSR_INTMASK (31<<5)
diff --git a/include/asm-arm/hardware/amba_clcd.h b/include/asm-arm/hardware/amba_clcd.h
index ce4cf5c1c05d..6b8d73dc1ab0 100644
--- a/include/asm-arm/hardware/amba_clcd.h
+++ b/include/asm-arm/hardware/amba_clcd.h
@@ -22,7 +22,7 @@
22#define CLCD_UBAS 0x00000010 22#define CLCD_UBAS 0x00000010
23#define CLCD_LBAS 0x00000014 23#define CLCD_LBAS 0x00000014
24 24
25#ifndef CONFIG_ARCH_VERSATILE 25#if !defined(CONFIG_ARCH_VERSATILE) && !defined(CONFIG_ARCH_REALVIEW)
26#define CLCD_IENB 0x00000018 26#define CLCD_IENB 0x00000018
27#define CLCD_CNTL 0x0000001c 27#define CLCD_CNTL 0x0000001c
28#else 28#else
diff --git a/include/asm-i386/apic.h b/include/asm-i386/apic.h
index a515e2aed829..8c454aa58ac6 100644
--- a/include/asm-i386/apic.h
+++ b/include/asm-i386/apic.h
@@ -118,8 +118,7 @@ extern void release_lapic_nmi(void);
118extern void disable_timer_nmi_watchdog(void); 118extern void disable_timer_nmi_watchdog(void);
119extern void enable_timer_nmi_watchdog(void); 119extern void enable_timer_nmi_watchdog(void);
120extern void nmi_watchdog_tick (struct pt_regs * regs); 120extern void nmi_watchdog_tick (struct pt_regs * regs);
121extern int APIC_init(void); 121extern int APIC_init_uniprocessor (void);
122extern void APIC_late_time_init(void);
123extern void disable_APIC_timer(void); 122extern void disable_APIC_timer(void);
124extern void enable_APIC_timer(void); 123extern void enable_APIC_timer(void);
125 124
diff --git a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h
index 9139b89497a1..622815bf3243 100644
--- a/include/asm-i386/hw_irq.h
+++ b/include/asm-i386/hw_irq.h
@@ -55,7 +55,6 @@ void init_8259A(int aeoi);
55void FASTCALL(send_IPI_self(int vector)); 55void FASTCALL(send_IPI_self(int vector));
56void init_VISWS_APIC_irqs(void); 56void init_VISWS_APIC_irqs(void);
57void setup_IO_APIC(void); 57void setup_IO_APIC(void);
58void IO_APIC_late_time_init(void);
59void disable_IO_APIC(void); 58void disable_IO_APIC(void);
60void print_IO_APIC(void); 59void print_IO_APIC(void);
61int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn); 60int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
diff --git a/include/asm-i386/mach-default/smpboot_hooks.h b/include/asm-i386/mach-default/smpboot_hooks.h
index d7c70c144f9f..7f45f6311059 100644
--- a/include/asm-i386/mach-default/smpboot_hooks.h
+++ b/include/asm-i386/mach-default/smpboot_hooks.h
@@ -1,6 +1,11 @@
1/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws 1/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws
2 * which needs to alter them. */ 2 * which needs to alter them. */
3 3
4static inline void smpboot_clear_io_apic_irqs(void)
5{
6 io_apic_irqs = 0;
7}
8
4static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) 9static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
5{ 10{
6 CMOS_WRITE(0xa, 0xf); 11 CMOS_WRITE(0xa, 0xf);
@@ -27,3 +32,13 @@ static inline void smpboot_restore_warm_reset_vector(void)
27 32
28 *((volatile long *) phys_to_virt(0x467)) = 0; 33 *((volatile long *) phys_to_virt(0x467)) = 0;
29} 34}
35
36static inline void smpboot_setup_io_apic(void)
37{
38 /*
39 * Here we can be sure that there is an IO-APIC in the system. Let's
40 * go and set it up:
41 */
42 if (!skip_ioapic_setup && nr_ioapics)
43 setup_IO_APIC();
44}
diff --git a/include/asm-i386/mach-visws/smpboot_hooks.h b/include/asm-i386/mach-visws/smpboot_hooks.h
index 14d8e0375f7a..d926471fa359 100644
--- a/include/asm-i386/mach-visws/smpboot_hooks.h
+++ b/include/asm-i386/mach-visws/smpboot_hooks.h
@@ -11,7 +11,14 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
11 11
12/* for visws do nothing for any of these */ 12/* for visws do nothing for any of these */
13 13
14static inline void smpboot_clear_io_apic_irqs(void)
15{
16}
17
14static inline void smpboot_restore_warm_reset_vector(void) 18static inline void smpboot_restore_warm_reset_vector(void)
15{ 19{
16} 20}
17 21
22static inline void smpboot_setup_io_apic(void)
23{
24}
diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
index 549f44843c5e..bba5305c29ed 100644
--- a/include/asm-ppc/ppc_sys.h
+++ b/include/asm-ppc/ppc_sys.h
@@ -18,7 +18,7 @@
18#define __ASM_PPC_SYS_H 18#define __ASM_PPC_SYS_H
19 19
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/device.h> 21#include <linux/platform_device.h>
22#include <linux/types.h> 22#include <linux/types.h>
23 23
24#if defined(CONFIG_8260) 24#if defined(CONFIG_8260)
diff --git a/include/linux/device.h b/include/linux/device.h
index a9e72ac3fb9f..17cbc6db67b4 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -396,32 +396,6 @@ extern struct device * get_device(struct device * dev);
396extern void put_device(struct device * dev); 396extern void put_device(struct device * dev);
397 397
398 398
399/* drivers/base/platform.c */
400
401struct platform_device {
402 const char * name;
403 u32 id;
404 struct device dev;
405 u32 num_resources;
406 struct resource * resource;
407};
408
409#define to_platform_device(x) container_of((x), struct platform_device, dev)
410
411extern int platform_device_register(struct platform_device *);
412extern void platform_device_unregister(struct platform_device *);
413
414extern struct bus_type platform_bus_type;
415extern struct device platform_bus;
416
417extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int);
418extern int platform_get_irq(struct platform_device *, unsigned int);
419extern struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, char *);
420extern int platform_get_irq_byname(struct platform_device *, char *);
421extern int platform_add_devices(struct platform_device **, int);
422
423extern struct platform_device *platform_device_register_simple(char *, unsigned int, struct resource *, unsigned int);
424
425/* drivers/base/power.c */ 399/* drivers/base/power.c */
426extern void device_shutdown(void); 400extern void device_shutdown(void);
427 401
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
new file mode 100644
index 000000000000..a726225e0afe
--- /dev/null
+++ b/include/linux/platform_device.h
@@ -0,0 +1,40 @@
1/*
2 * platform_device.h - generic, centralized driver model
3 *
4 * Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org>
5 *
6 * This file is released under the GPLv2
7 *
8 * See Documentation/driver-model/ for more information.
9 */
10
11#ifndef _PLATFORM_DEVICE_H_
12#define _PLATFORM_DEVICE_H_
13
14#include <linux/device.h>
15
16struct platform_device {
17 const char * name;
18 u32 id;
19 struct device dev;
20 u32 num_resources;
21 struct resource * resource;
22};
23
24#define to_platform_device(x) container_of((x), struct platform_device, dev)
25
26extern int platform_device_register(struct platform_device *);
27extern void platform_device_unregister(struct platform_device *);
28
29extern struct bus_type platform_bus_type;
30extern struct device platform_bus;
31
32extern struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int);
33extern int platform_get_irq(struct platform_device *, unsigned int);
34extern struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, char *);
35extern int platform_get_irq_byname(struct platform_device *, char *);
36extern int platform_add_devices(struct platform_device **, int);
37
38extern struct platform_device *platform_device_register_simple(char *, unsigned int, struct resource *, unsigned int);
39
40#endif /* _PLATFORM_DEVICE_H_ */
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 317a979b24de..2b799d40d669 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -12,7 +12,7 @@
12#define _LINUX_SERIAL_8250_H 12#define _LINUX_SERIAL_8250_H
13 13
14#include <linux/serial_core.h> 14#include <linux/serial_core.h>
15#include <linux/device.h> 15#include <linux/platform_device.h>
16 16
17/* 17/*
18 * This is the platform device platform_data structure 18 * This is the platform device platform_data structure
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 14cb2718cb77..46e3c0bf3c94 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -1055,6 +1055,7 @@ typedef struct {
1055 unsigned char emu10k2_chip; /* Audigy 1 or Audigy 2. */ 1055 unsigned char emu10k2_chip; /* Audigy 1 or Audigy 2. */
1056 unsigned char ca0102_chip; /* Audigy 1 or Audigy 2. Not SB Audigy 2 Value. */ 1056 unsigned char ca0102_chip; /* Audigy 1 or Audigy 2. Not SB Audigy 2 Value. */
1057 unsigned char ca0108_chip; /* Audigy 2 Value */ 1057 unsigned char ca0108_chip; /* Audigy 2 Value */
1058 unsigned char ca_cardbus_chip; /* Audigy 2 ZS Notebook */
1058 unsigned char ca0151_chip; /* P16V */ 1059 unsigned char ca0151_chip; /* P16V */
1059 unsigned char spk71; /* Has 7.1 speakers */ 1060 unsigned char spk71; /* Has 7.1 speakers */
1060 unsigned char sblive51; /* SBLive! 5.1 - extout 0x11 -> center, 0x12 -> lfe */ 1061 unsigned char sblive51; /* SBLive! 5.1 - extout 0x11 -> center, 0x12 -> lfe */
diff --git a/init/main.c b/init/main.c
index 4075d97e94b1..f142d4035341 100644
--- a/init/main.c
+++ b/init/main.c
@@ -64,6 +64,10 @@
64#endif 64#endif
65#endif 65#endif
66 66
67#ifdef CONFIG_X86_LOCAL_APIC
68#include <asm/smp.h>
69#endif
70
67/* 71/*
68 * Versions of gcc older than that listed below may actually compile 72 * Versions of gcc older than that listed below may actually compile
69 * and link okay, but the end product can have subtle run time bugs. 73 * and link okay, but the end product can have subtle run time bugs.
@@ -310,7 +314,14 @@ extern void setup_arch(char **);
310 314
311#ifndef CONFIG_SMP 315#ifndef CONFIG_SMP
312 316
317#ifdef CONFIG_X86_LOCAL_APIC
318static void __init smp_init(void)
319{
320 APIC_init_uniprocessor();
321}
322#else
313#define smp_init() do { } while (0) 323#define smp_init() do { } while (0)
324#endif
314 325
315static inline void setup_per_cpu_areas(void) { } 326static inline void setup_per_cpu_areas(void) { }
316static inline void smp_prepare_cpus(unsigned int maxcpus) { } 327static inline void smp_prepare_cpus(unsigned int maxcpus) { }
diff --git a/mm/swap.c b/mm/swap.c
index 96387e20184a..154ae13d8b7e 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -259,6 +259,8 @@ void __pagevec_release(struct pagevec *pvec)
259 pagevec_reinit(pvec); 259 pagevec_reinit(pvec);
260} 260}
261 261
262EXPORT_SYMBOL(__pagevec_release);
263
262/* 264/*
263 * pagevec_release() for pages which are known to not be on the LRU 265 * pagevec_release() for pages which are known to not be on the LRU
264 * 266 *
@@ -387,6 +389,7 @@ unsigned pagevec_lookup_tag(struct pagevec *pvec, struct address_space *mapping,
387 return pagevec_count(pvec); 389 return pagevec_count(pvec);
388} 390}
389 391
392EXPORT_SYMBOL(pagevec_lookup_tag);
390 393
391#ifdef CONFIG_SMP 394#ifdef CONFIG_SMP
392/* 395/*
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index 877bb00d3295..d1f9da498729 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -13,7 +13,7 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/device.h> 16#include <linux/platform_device.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/wait.h> 18#include <linux/wait.h>
19#include <linux/delay.h> 19#include <linux/delay.h>
diff --git a/sound/core/init.c b/sound/core/init.c
index 59202de1d2ce..41e224986f35 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -28,6 +28,8 @@
28#include <linux/ctype.h> 28#include <linux/ctype.h>
29#include <linux/pci.h> 29#include <linux/pci.h>
30#include <linux/pm.h> 30#include <linux/pm.h>
31#include <linux/platform_device.h>
32
31#include <sound/core.h> 33#include <sound/core.h>
32#include <sound/control.h> 34#include <sound/control.h>
33#include <sound/info.h> 35#include <sound/info.h>
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index e9cd8e054f25..53aeff0b783a 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -579,6 +579,30 @@ static int __devinit snd_emu10k1_ecard_init(emu10k1_t * emu)
579 return 0; 579 return 0;
580} 580}
581 581
582static int __devinit snd_emu10k1_cardbus_init(emu10k1_t * emu)
583{
584 unsigned long special_port;
585 unsigned int value;
586
587 /* Special initialisation routine
588 * before the rest of the IO-Ports become active.
589 */
590 special_port = emu->port + 0x38;
591 value = inl(special_port);
592 outl(0x00d00000, special_port);
593 value = inl(special_port);
594 outl(0x00d00001, special_port);
595 value = inl(special_port);
596 outl(0x00d0005f, special_port);
597 value = inl(special_port);
598 outl(0x00d0007f, special_port);
599 value = inl(special_port);
600 outl(0x0090007f, special_port);
601 value = inl(special_port);
602
603 return 0;
604}
605
582/* 606/*
583 * Create the EMU10K1 instance 607 * Create the EMU10K1 instance
584 */ 608 */
@@ -624,6 +648,16 @@ static emu_chip_details_t emu_chip_details[] = {
624 .ca0108_chip = 1, 648 .ca0108_chip = 1,
625 .spk71 = 1, 649 .spk71 = 1,
626 .ac97_chip = 1} , 650 .ac97_chip = 1} ,
651 /* Audigy 2 ZS Notebook Cardbus card.*/
652 /* Tested by James@superbug.co.uk 30th October 2005 */
653 /* Not working yet, but progressing. */
654 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
655 .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]",
656 .id = "Audigy2",
657 .emu10k2_chip = 1,
658 .ca0108_chip = 1,
659 .ca_cardbus_chip = 1,
660 .spk71 = 1} ,
627 {.vendor = 0x1102, .device = 0x0008, 661 {.vendor = 0x1102, .device = 0x0008,
628 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", 662 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]",
629 .id = "Audigy2", 663 .id = "Audigy2",
@@ -1011,6 +1045,11 @@ int __devinit snd_emu10k1_create(snd_card_t * card,
1011 snd_emu10k1_free(emu); 1045 snd_emu10k1_free(emu);
1012 return err; 1046 return err;
1013 } 1047 }
1048 } else if (emu->card_capabilities->ca_cardbus_chip) {
1049 if ((err = snd_emu10k1_cardbus_init(emu)) < 0) {
1050 snd_emu10k1_free(emu);
1051 return err;
1052 }
1014 } else { 1053 } else {
1015 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version 1054 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
1016 does not support this, it shouldn't do any harm */ 1055 does not support this, it shouldn't do any harm */