Merge branch 'for-linus' of git://git.o-hand.com/linux-rpurdie-leds
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 28 May 2010 17:20:59 +0000 (10:20 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 28 May 2010 17:20:59 +0000 (10:20 -0700)
* 'for-linus' of git://git.o-hand.com/linux-rpurdie-leds:
  leds: Fix leds-gpio openfirmware compile issue
  leds: Kconfig fixes

215 files changed:
Documentation/arm/Samsung-S3C24XX/GPIO.txt
Documentation/arm/Samsung-S3C24XX/Overview.txt
Documentation/arm/Samsung/GPIO.txt [new file with mode: 0644]
Documentation/arm/Samsung/Overview.txt
Documentation/filesystems/Locking
Documentation/filesystems/vfs.txt
Documentation/kernel-parameters.txt
arch/arm/configs/s3c2410_defconfig
arch/arm/configs/s3c6400_defconfig
arch/arm/mach-s3c64xx/clock.c
arch/arm/plat-s5p/clock.c
arch/arm/plat-samsung/include/plat/gpio-cfg.h
arch/frv/include/asm/cache.h
arch/frv/include/asm/mem-layout.h
arch/powerpc/platforms/cell/spufs/file.c
arch/powerpc/platforms/cell/spufs/inode.c
arch/powerpc/platforms/pseries/hvCall_inst.c
drivers/ata/Kconfig
drivers/ata/Makefile
drivers/ata/ata_generic.c
drivers/ata/ata_piix.c
drivers/ata/libata-core.c
drivers/ata/libata-sff.c
drivers/ata/pata_acpi.c
drivers/ata/pata_ali.c
drivers/ata/pata_amd.c
drivers/ata/pata_artop.c
drivers/ata/pata_atiixp.c
drivers/ata/pata_atp867x.c
drivers/ata/pata_bf54x.c
drivers/ata/pata_cmd64x.c
drivers/ata/pata_cs5520.c
drivers/ata/pata_cs5530.c
drivers/ata/pata_cs5535.c
drivers/ata/pata_cs5536.c
drivers/ata/pata_cypress.c
drivers/ata/pata_efar.c
drivers/ata/pata_hpt366.c
drivers/ata/pata_hpt37x.c
drivers/ata/pata_hpt3x2n.c
drivers/ata/pata_hpt3x3.c
drivers/ata/pata_icside.c
drivers/ata/pata_it8213.c
drivers/ata/pata_it821x.c
drivers/ata/pata_jmicron.c
drivers/ata/pata_macio.c
drivers/ata/pata_marvell.c
drivers/ata/pata_mpc52xx.c
drivers/ata/pata_netcell.c
drivers/ata/pata_ninja32.c
drivers/ata/pata_ns87415.c
drivers/ata/pata_octeon_cf.c
drivers/ata/pata_oldpiix.c
drivers/ata/pata_optidma.c
drivers/ata/pata_pdc2027x.c
drivers/ata/pata_pdc202xx_old.c
drivers/ata/pata_piccolo.c
drivers/ata/pata_radisys.c
drivers/ata/pata_rdc.c
drivers/ata/pata_sc1200.c
drivers/ata/pata_scc.c
drivers/ata/pata_sch.c
drivers/ata/pata_serverworks.c
drivers/ata/pata_sil680.c
drivers/ata/pata_sis.c
drivers/ata/pata_sl82c105.c
drivers/ata/pata_triflex.c
drivers/ata/pata_via.c
drivers/ata/sata_mv.c
drivers/ata/sata_nv.c
drivers/ata/sata_qstor.c
drivers/ata/sata_sil.c
drivers/ata/sata_sis.c
drivers/ata/sata_svw.c
drivers/ata/sata_uli.c
drivers/ata/sata_via.c
drivers/ata/sata_vsc.c
drivers/char/ps3flash.c
drivers/mtd/ubi/cdev.c
drivers/net/3c507.c
drivers/net/benet/be_cmds.c
drivers/net/benet/be_main.c
drivers/net/cnic.c
drivers/net/cnic_if.h
drivers/net/fec.c
drivers/net/hamradio/yam.c
drivers/net/ll_temac.h
drivers/net/ll_temac_main.c
drivers/serial/s5pv210.c
drivers/staging/pohmelfs/inode.c
drivers/usb/gadget/printer.c
drivers/vhost/net.c
drivers/vhost/vhost.c
drivers/video/fb_defio.c
fs/9p/vfs_file.c
fs/adfs/dir.c
fs/adfs/file.c
fs/adfs/inode.c
fs/affs/affs.h
fs/affs/file.c
fs/afs/internal.h
fs/afs/write.c
fs/aio.c
fs/anon_inodes.c
fs/attr.c
fs/bad_inode.c
fs/bfs/dir.c
fs/block_dev.c
fs/btrfs/ctree.h
fs/btrfs/file.c
fs/buffer.c
fs/ceph/caps.c
fs/ceph/dir.c
fs/ceph/super.h
fs/cifs/cifsfs.h
fs/cifs/file.c
fs/coda/coda_int.h
fs/coda/file.c
fs/configfs/inode.c
fs/direct-io.c
fs/ecryptfs/file.c
fs/ecryptfs/inode.c
fs/exofs/file.c
fs/ext2/ext2.h
fs/ext2/file.c
fs/ext2/inode.c
fs/ext3/fsync.c
fs/ext4/ext4.h
fs/ext4/fsync.c
fs/fat/fat.h
fs/fat/file.c
fs/fat/inode.c
fs/file_table.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/gfs2/aops.c
fs/gfs2/file.c
fs/gfs2/ops_inode.c
fs/hostfs/hostfs_kern.c
fs/hpfs/file.c
fs/hpfs/hpfs_fn.h
fs/hppfs/hppfs.c
fs/hugetlbfs/inode.c
fs/jffs2/file.c
fs/jffs2/fs.c
fs/jffs2/os-linux.h
fs/jfs/file.c
fs/jfs/jfs_inode.h
fs/libfs.c
fs/logfs/file.c
fs/logfs/logfs.h
fs/minix/dir.c
fs/minix/file.c
fs/minix/itree_v2.c
fs/namei.c
fs/ncpfs/file.c
fs/nfs/dir.c
fs/nfs/file.c
fs/nilfs2/file.c
fs/nilfs2/nilfs.h
fs/ntfs/dir.c
fs/ntfs/file.c
fs/ocfs2/file.c
fs/omfs/file.c
fs/pipe.c
fs/qnx4/dir.c
fs/ramfs/file-mmu.c
fs/ramfs/file-nommu.c
fs/reiserfs/dir.c
fs/reiserfs/file.c
fs/smbfs/file.c
fs/smbfs/inode.c
fs/super.c
fs/sync.c
fs/sysfs/inode.c
fs/sysv/dir.c
fs/sysv/file.c
fs/sysv/inode.c
fs/ubifs/file.c
fs/ubifs/ubifs.h
fs/udf/dir.c
fs/udf/file.c
fs/ufs/dir.c
fs/ufs/file.c
fs/ufs/truncate.c
fs/xfs/linux-2.6/xfs_file.c
include/linux/buffer_head.h
include/linux/ext3_fs.h
include/linux/fb.h
include/linux/file.h
include/linux/fs.h
include/linux/libata.h
include/net/cls_cgroup.h
include/net/sctp/structs.h
include/net/sock.h
include/trace/events/ext4.h
ipc/shm.c
kernel/hrtimer.c
kernel/perf_event.c
kernel/posix-timers.c
kernel/timer.c
mm/shmem.c
mm/truncate.c
net/core/datagram.c
net/core/neighbour.c
net/core/rtnetlink.c
net/core/sock.c
net/ipv4/ipmr.c
net/ipv4/udp.c
net/ipv6/ip6_output.c
net/ipv6/ip6mr.c
net/ipv6/udp.c
net/iucv/af_iucv.c
net/netfilter/xt_TEE.c

index 2af2cf3..816d607 100644 (file)
@@ -12,6 +12,8 @@ Introduction
   of the s3c2410 GPIO system, please read the Samsung provided
   data-sheet/users manual to find out the complete list.
 
+  See Documentation/arm/Samsung/GPIO.txt for the core implemetation.
+
 
 GPIOLIB
 -------
@@ -24,8 +26,60 @@ GPIOLIB
   listed below will be removed (they may be marked as __deprecated
   in the near future).
 
-  - s3c2410_gpio_getpin
-  - s3c2410_gpio_setpin
+  The following functions now either have a s3c_ specific variant
+  or are merged into gpiolib. See the definitions in
+  arch/arm/plat-samsung/include/plat/gpio-cfg.h:
+
+  s3c2410_gpio_setpin()                gpio_set_value() or gpio_direction_output()
+  s3c2410_gpio_getpin()                gpio_get_value() or gpio_direction_input()
+  s3c2410_gpio_getirq()                gpio_to_irq()
+  s3c2410_gpio_cfgpin()                s3c_gpio_cfgpin()
+  s3c2410_gpio_getcfg()                s3c_gpio_getcfg()
+  s3c2410_gpio_pullup()                s3c_gpio_setpull()
+
+
+GPIOLIB conversion
+------------------
+
+If you need to convert your board or driver to use gpiolib from the exiting
+s3c2410 api, then here are some notes on the process.
+
+1) If your board is exclusively using an GPIO, say to control peripheral
+   power, then it will require to claim the gpio with gpio_request() before
+   it can use it.
+
+   It is recommended to check the return value, with at least WARN_ON()
+   during initialisation.
+
+2) The s3c2410_gpio_cfgpin() can be directly replaced with s3c_gpio_cfgpin()
+   as they have the same arguments, and can either take the pin specific
+   values, or the more generic special-function-number arguments.
+
+3) s3c2410_gpio_pullup() changs have the problem that whilst the 
+   s3c2410_gpio_pullup(x, 1) can be easily translated to the
+   s3c_gpio_setpull(x, S3C_GPIO_PULL_NONE), the s3c2410_gpio_pullup(x, 0)
+   are not so easy.
+
+   The s3c2410_gpio_pullup(x, 0) case enables the pull-up (or in the case
+   of some of the devices, a pull-down) and as such the new API distinguishes
+   between the UP and DOWN case. There is currently no 'just turn on' setting
+   which may be required if this becomes a problem.
+
+4) s3c2410_gpio_setpin() can be replaced by gpio_set_value(), the old call
+   does not implicitly configure the relevant gpio to output. The gpio
+   direction should be changed before using gpio_set_value().
+
+5) s3c2410_gpio_getpin() is replaceable by gpio_get_value() if the pin
+   has been set to input. It is currently unknown what the behaviour is
+   when using gpio_get_value() on an output pin (s3c2410_gpio_getpin
+   would return the value the pin is supposed to be outputting).
+
+6) s3c2410_gpio_getirq() should be directly replacable with the
+   gpio_to_irq() call.
+
+The s3c2410_gpio and gpio_ calls have always operated on the same gpio
+numberspace, so there is no problem with converting the gpio numbering
+between the calls.
 
 
 Headers
@@ -54,6 +108,11 @@ PIN Numbers
   eg S3C2410_GPA(0) or S3C2410_GPF(1). These defines are used to tell
   the GPIO functions which pin is to be used.
 
+  With the conversion to gpiolib, there is no longer a direct conversion
+  from gpio pin number to register base address as in earlier kernels. This
+  is due to the number space required for newer SoCs where the later
+  GPIOs are not contiguous.
+
 
 Configuring a pin
 -----------------
@@ -71,6 +130,8 @@ Configuring a pin
    which would turn GPA(0) into the lowest Address line A0, and set
    GPE(8) to be connected to the SDIO/MMC controller's SDDAT1 line.
 
+   The s3c_gpio_cfgpin() call is a functional replacement for this call.
+
 
 Reading the current configuration
 ---------------------------------
@@ -82,6 +143,9 @@ Reading the current configuration
   The return value will be from the same set of values which can be
   passed to s3c2410_gpio_cfgpin().
 
+  The s3c_gpio_getcfg() call should be a functional replacement for
+  this call.
+
 
 Configuring a pull-up resistor
 ------------------------------
@@ -95,6 +159,10 @@ Configuring a pull-up resistor
   Where the to value is zero to set the pull-up off, and 1 to enable
   the specified pull-up. Any other values are currently undefined.
 
+  The s3c_gpio_setpull() offers similar functionality, but with the
+  ability to encode whether the pull is up or down. Currently there
+  is no 'just on' state, so up or down must be selected.
+
 
 Getting the state of a PIN
 --------------------------
@@ -106,6 +174,9 @@ Getting the state of a PIN
   This will return either zero or non-zero. Do not count on this
   function returning 1 if the pin is set.
 
+  This call is now implemented by the relevant gpiolib calls, convert
+  your board or driver to use gpiolib.
+
 
 Setting the state of a PIN
 --------------------------
@@ -117,6 +188,9 @@ Setting the state of a PIN
   Which sets the given pin to the value. Use 0 to write 0, and 1 to
   set the output to 1.
 
+  This call is now implemented by the relevant gpiolib calls, convert
+  your board or driver to use gpiolib.
+
 
 Getting the IRQ number associated with a PIN
 --------------------------------------------
@@ -128,6 +202,9 @@ Getting the IRQ number associated with a PIN
 
   Note, not all pins have an IRQ.
 
+  This call is now implemented by the relevant gpiolib calls, convert
+  your board or driver to use gpiolib.
+
 
 Authour
 -------
index 081892d..c12bfc1 100644 (file)
@@ -8,10 +8,16 @@ Introduction
 
   The Samsung S3C24XX range of ARM9 System-on-Chip CPUs are supported
   by the 's3c2410' architecture of ARM Linux. Currently the S3C2410,
-  S3C2412, S3C2413, S3C2440, S3C2442 and S3C2443 devices are supported.
+  S3C2412, S3C2413, S3C2416 S3C2440, S3C2442, S3C2443 and S3C2450 devices
+  are supported.
 
   Support for the S3C2400 and S3C24A0 series are in progress.
 
+  The S3C2416 and S3C2450 devices are very similar and S3C2450 support is
+  included under the arch/arm/mach-s3c2416 directory. Note, whilst core
+  support for these SoCs is in, work on some of the extra peripherals
+  and extra interrupts is still ongoing.
+
 
 Configuration
 -------------
@@ -209,6 +215,13 @@ GPIO
   Newer kernels carry GPIOLIB, and support is being moved towards
   this with some of the older support in line to be removed.
 
+  As of v2.6.34, the move towards using gpiolib support is almost
+  complete, and very little of the old calls are left.
+
+  See Documentation/arm/Samsung-S3C24XX/GPIO.txt for the S3C24XX specific
+  support and Documentation/arm/Samsung/GPIO.txt for the core Samsung
+  implementation.
+
 
 Clock Management
 ----------------
diff --git a/Documentation/arm/Samsung/GPIO.txt b/Documentation/arm/Samsung/GPIO.txt
new file mode 100644 (file)
index 0000000..05850c6
--- /dev/null
@@ -0,0 +1,42 @@
+               Samsung GPIO implementation
+               ===========================
+
+Introduction
+------------
+
+This outlines the Samsung GPIO implementation and the architecture
+specfic calls provided alongisde the drivers/gpio core.
+
+
+S3C24XX (Legacy)
+----------------
+
+See Documentation/arm/Samsung-S3C24XX/GPIO.txt for more information
+about these devices. Their implementation is being brought into line
+with the core samsung implementation described in this document.
+
+
+GPIOLIB integration
+-------------------
+
+The gpio implementation uses gpiolib as much as possible, only providing
+specific calls for the items that require Samsung specific handling, such
+as pin special-function or pull resistor control.
+
+GPIO numbering is synchronised between the Samsung and gpiolib system.
+
+
+PIN configuration
+-----------------
+
+Pin configuration is specific to the Samsung architecutre, with each SoC
+registering the necessary information for the core gpio configuration
+implementation to configure pins as necessary.
+
+The s3c_gpio_cfgpin() and s3c_gpio_setpull() provide the means for a
+driver or machine to change gpio configuration.
+
+See arch/arm/plat-samsung/include/plat/gpio-cfg.h for more information
+on these functions.
+
+
index 7cced1f..c3094ea 100644 (file)
@@ -13,9 +13,10 @@ Introduction
 
   - S3C24XX: See Documentation/arm/Samsung-S3C24XX/Overview.txt for full list
   - S3C64XX: S3C6400 and S3C6410
-  - S5PC6440
-
-  S5PC100 and S5PC110 support is currently being merged
+  - S5P6440
+  - S5P6442
+  - S5PC100
+  - S5PC110 / S5PV210
 
 
 S3C24XX Systems
@@ -35,7 +36,10 @@ Configuration
   unifying all the SoCs into one kernel.
 
   s5p6440_defconfig - S5P6440 specific default configuration
+  s5p6442_defconfig - S5P6442 specific default configuration
   s5pc100_defconfig - S5PC100 specific default configuration
+  s5pc110_defconfig - S5PC110 specific default configuration
+  s5pv210_defconfig - S5PV210 specific default configuration
 
 
 Layout
@@ -50,18 +54,27 @@ Layout
   specific information. It contains the base clock, GPIO and device definitions
   to get the system running.
 
-  plat-s3c is the s3c24xx/s3c64xx platform directory, although it is currently
-  involved in other builds this will be phased out once the relevant code is
-  moved elsewhere.
-
   plat-s3c24xx is for s3c24xx specific builds, see the S3C24XX docs.
 
-  plat-s3c64xx is for the s3c64xx specific bits, see the S3C24XX docs.
+  plat-s5p is for s5p specific builds, and contains common support for the
+  S5P specific systems. Not all S5Ps use all the features in this directory
+  due to differences in the hardware.
+
+
+Layout changes
+--------------
+
+  The old plat-s3c and plat-s5pc1xx directories have been removed, with
+  support moved to either plat-samsung or plat-s5p as necessary. These moves
+  where to simplify the include and dependency issues involved with having
+  so many different platform directories.
 
-  plat-s5p is for s5p specific builds, more to be added.
+  It was decided to remove plat-s5pc1xx as some of the support was already
+  in plat-s5p or plat-samsung, with the S5PC110 support added with S5PV210
+  the only user was the S5PC100. The S5PC100 specific items where moved to
+  arch/arm/mach-s5pc100.
 
 
-  [ to finish ]
 
 
 Port Contributors
index 61c98f0..96d4293 100644 (file)
@@ -380,7 +380,7 @@ prototypes:
        int (*open) (struct inode *, struct file *);
        int (*flush) (struct file *);
        int (*release) (struct inode *, struct file *);
-       int (*fsync) (struct file *, struct dentry *, int datasync);
+       int (*fsync) (struct file *, int datasync);
        int (*aio_fsync) (struct kiocb *, int datasync);
        int (*fasync) (int, struct file *, int);
        int (*lock) (struct file *, int, struct file_lock *);
index b668585..94677e7 100644 (file)
@@ -401,11 +401,16 @@ otherwise noted.
        started might not be in the page cache at the end of the
        walk).
 
-  truncate: called by the VFS to change the size of a file.  The
+  truncate: Deprecated. This will not be called if ->setsize is defined.
+       Called by the VFS to change the size of a file.  The
        i_size field of the inode is set to the desired size by the
        VFS before this method is called.  This method is called by
        the truncate(2) system call and related functionality.
 
+       Note: ->truncate and vmtruncate are deprecated. Do not add new
+       instances/calls of these. Filesystems should be converted to do their
+       truncate sequence via ->setattr().
+
   permission: called by the VFS to check for access rights on a POSIX-like
        filesystem.
 
@@ -729,7 +734,7 @@ struct file_operations {
        int (*open) (struct inode *, struct file *);
        int (*flush) (struct file *);
        int (*release) (struct inode *, struct file *);
-       int (*fsync) (struct file *, struct dentry *, int datasync);
+       int (*fsync) (struct file *, int datasync);
        int (*aio_fsync) (struct kiocb *, int datasync);
        int (*fasync) (int, struct file *, int);
        int (*lock) (struct file *, int, struct file_lock *);
index b56ea86..a5c0550 100644 (file)
@@ -1252,6 +1252,8 @@ and is between 256 and 4096 characters. It is defined in the file
                        * nohrst, nosrst, norst: suppress hard, soft
                           and both resets.
 
+                       * dump_id: dump IDENTIFY data.
+
                        If there are multiple matching configurations changing
                        the same attribute, the last one is used.
 
index 43af89c..44cea2d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.34
-# Wed May 26 19:04:29 2010
+# Fri May 28 19:15:48 2010
 #
 CONFIG_ARM=y
 CONFIG_HAVE_PWM=y
@@ -250,12 +250,15 @@ CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
 CONFIG_S3C_LOWLEVEL_UART_PORT=0
 CONFIG_SAMSUNG_CLKSRC=y
 CONFIG_S3C_GPIO_CFG_S3C24XX=y
+CONFIG_S3C_GPIO_PULL_UPDOWN=y
 CONFIG_S3C_GPIO_PULL_UP=y
 CONFIG_SAMSUNG_GPIO_EXTRA=0
 CONFIG_S3C_GPIO_SPACE=0
 CONFIG_S3C_ADC=y
 CONFIG_S3C_DEV_HSMMC=y
+CONFIG_S3C_DEV_HSMMC1=y
 CONFIG_S3C_DEV_HWMON=y
+CONFIG_S3C_DEV_FB=y
 CONFIG_S3C_DEV_USB_HOST=y
 CONFIG_S3C_DEV_WDT=y
 CONFIG_S3C_DEV_NAND=y
@@ -322,11 +325,13 @@ CONFIG_MACH_SMDK2413=y
 CONFIG_MACH_S3C2413=y
 CONFIG_MACH_SMDK2412=y
 CONFIG_MACH_VSTMS=y
+CONFIG_CPU_S3C2416=y
+CONFIG_S3C2416_DMA=y
 
 #
 # S3C2416 Machines
 #
-# CONFIG_MACH_SMDK2416 is not set
+CONFIG_MACH_SMDK2416=y
 CONFIG_CPU_S3C2440=y
 CONFIG_CPU_S3C2442=y
 CONFIG_CPU_S3C244X=y
@@ -338,9 +343,9 @@ CONFIG_S3C2440_DMA=y
 # S3C2440 and S3C2442 Machines
 #
 CONFIG_MACH_ANUBIS=y
-# CONFIG_MACH_NEO1973_GTA02 is not set
+CONFIG_MACH_NEO1973_GTA02=y
 CONFIG_MACH_OSIRIS=y
-# CONFIG_MACH_OSIRIS_DVS is not set
+CONFIG_MACH_OSIRIS_DVS=m
 CONFIG_MACH_RX3715=y
 CONFIG_ARCH_S3C2440=y
 CONFIG_MACH_NEXCODER_2440=y
@@ -348,7 +353,7 @@ CONFIG_SMDK2440_CPU2440=y
 CONFIG_SMDK2440_CPU2442=y
 CONFIG_MACH_AT2440EVB=y
 CONFIG_MACH_MINI2440=y
-# CONFIG_MACH_RX1950 is not set
+CONFIG_MACH_RX1950=y
 CONFIG_CPU_S3C2443=y
 CONFIG_S3C2443_DMA=y
 
@@ -1302,6 +1307,7 @@ CONFIG_INPUT_POWERMATE=m
 CONFIG_INPUT_YEALINK=m
 CONFIG_INPUT_CM109=m
 CONFIG_INPUT_UINPUT=m
+# CONFIG_INPUT_PCF50633_PMU is not set
 # CONFIG_INPUT_PCF8574 is not set
 CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
 
@@ -1490,7 +1496,16 @@ CONFIG_GPIOLIB=y
 # AC97 GPIO expanders:
 #
 # CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_APM_POWER is not set
+# CONFIG_TEST_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+# CONFIG_CHARGER_PCF50633 is not set
 CONFIG_HWMON=y
 CONFIG_HWMON_VID=m
 # CONFIG_HWMON_DEBUG_CHIP is not set
@@ -1607,7 +1622,7 @@ CONFIG_MFD_SM501=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_HTC_I2CPLD is not set
 # CONFIG_UCB1400_CORE is not set
-# CONFIG_TPS65010 is not set
+CONFIG_TPS65010=m
 # CONFIG_TWL4030_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_T7L66XB is not set
@@ -1620,8 +1635,10 @@ CONFIG_MFD_SM501=y
 # CONFIG_MFD_WM831X is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_WM8994 is not set
-# CONFIG_MFD_PCF50633 is not set
+CONFIG_MFD_PCF50633=y
 # CONFIG_MFD_MC13783 is not set
+# CONFIG_PCF50633_ADC is not set
+CONFIG_PCF50633_GPIO=y
 # CONFIG_AB3100_CORE is not set
 # CONFIG_EZX_PCAP is not set
 # CONFIG_AB4500_CORE is not set
@@ -1737,6 +1754,7 @@ CONFIG_SND_S3C24XX_SOC_I2S=y
 CONFIG_SND_S3C_I2SV2_SOC=m
 CONFIG_SND_S3C2412_SOC_I2S=m
 CONFIG_SND_S3C_SOC_AC97=m
+# CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753 is not set
 CONFIG_SND_S3C24XX_SOC_JIVE_WM8750=m
 CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710=m
 CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650=m
@@ -2045,6 +2063,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_BQ4802 is not set
 # CONFIG_RTC_DRV_RP5C01 is not set
 # CONFIG_RTC_DRV_V3020 is not set
+# CONFIG_RTC_DRV_PCF50633 is not set
 
 #
 # on-CPU RTC drivers
index 7d8b4cf..2b64238 100644 (file)
@@ -1,9 +1,10 @@
 #
 # Automatically generated make config: don't edit
 # Linux kernel version: 2.6.34
-# Wed May 26 19:04:30 2010
+# Fri May 28 19:05:39 2010
 #
 CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
@@ -253,12 +254,15 @@ CONFIG_S3C_GPIO_TRACK=y
 # CONFIG_S3C_ADC is not set
 CONFIG_S3C_DEV_HSMMC=y
 CONFIG_S3C_DEV_HSMMC1=y
+CONFIG_S3C_DEV_HSMMC2=y
+CONFIG_S3C_DEV_HWMON=y
 CONFIG_S3C_DEV_I2C1=y
 CONFIG_S3C_DEV_FB=y
 CONFIG_S3C_DEV_USB_HOST=y
 CONFIG_S3C_DEV_USB_HSOTG=y
 CONFIG_S3C_DEV_WDT=y
 CONFIG_S3C_DEV_NAND=y
+CONFIG_S3C_DEV_RTC=y
 CONFIG_SAMSUNG_DEV_ADC=y
 CONFIG_SAMSUNG_DEV_TS=y
 CONFIG_S3C_DMA=y
@@ -271,6 +275,7 @@ CONFIG_S3C_DMA=y
 # CONFIG_SAMSUNG_PM_CHECK is not set
 CONFIG_SAMSUNG_WAKEMASK=y
 CONFIG_PLAT_S3C64XX=y
+CONFIG_CPU_S3C6400=y
 CONFIG_CPU_S3C6410=y
 CONFIG_S3C64XX_DMA=y
 CONFIG_S3C64XX_SETUP_SDHCI=y
@@ -278,17 +283,18 @@ CONFIG_S3C64XX_SETUP_I2C0=y
 CONFIG_S3C64XX_SETUP_I2C1=y
 CONFIG_S3C64XX_SETUP_FB_24BPP=y
 CONFIG_S3C64XX_SETUP_SDHCI_GPIO=y
-# CONFIG_MACH_SMDK6400 is not set
-# CONFIG_MACH_ANW6410 is not set
+CONFIG_MACH_SMDK6400=y
+CONFIG_MACH_ANW6410=y
 CONFIG_MACH_SMDK6410=y
 CONFIG_SMDK6410_SD_CH0=y
 # CONFIG_SMDK6410_SD_CH1 is not set
 # CONFIG_SMDK6410_WM1190_EV1 is not set
 # CONFIG_SMDK6410_WM1192_EV1 is not set
-# CONFIG_MACH_NCP is not set
-# CONFIG_MACH_HMT is not set
-# CONFIG_MACH_SMARTQ5 is not set
-# CONFIG_MACH_SMARTQ7 is not set
+CONFIG_MACH_NCP=y
+CONFIG_MACH_HMT=y
+CONFIG_MACH_SMARTQ=y
+CONFIG_MACH_SMARTQ5=y
+CONFIG_MACH_SMARTQ7=y
 
 #
 # Processor Type
@@ -475,6 +481,9 @@ CONFIG_MTD_CFI_I2=y
 #
 # Self-contained MTD device drivers
 #
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -501,6 +510,7 @@ CONFIG_MTD_NAND_S3C2410=y
 # CONFIG_MTD_NAND_S3C2410_CLKSTOP is not set
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
@@ -521,6 +531,7 @@ CONFIG_BLK_DEV_LOOP=y
 #
 # DRBD disabled because PROC_FS, INET or CONNECTOR not selected
 #
+# CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
@@ -534,12 +545,14 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_ISL29003 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
 # CONFIG_C2PORT is not set
 
 #
 # EEPROM support
 #
 CONFIG_EEPROM_AT24=y
+# CONFIG_EEPROM_AT25 is not set
 # CONFIG_EEPROM_LEGACY is not set
 # CONFIG_EEPROM_MAX6875 is not set
 # CONFIG_EEPROM_93CX6 is not set
@@ -654,6 +667,7 @@ CONFIG_SERIAL_SAMSUNG_UARTS=4
 # CONFIG_SERIAL_SAMSUNG_DEBUG is not set
 CONFIG_SERIAL_SAMSUNG_CONSOLE=y
 CONFIG_SERIAL_S3C6400=y
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_TIMBERDALE is not set
@@ -694,6 +708,7 @@ CONFIG_I2C_S3C2410=y
 #
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
 
 #
 # Other I2C/SMBus bus drivers
@@ -703,7 +718,24 @@ CONFIG_I2C_S3C2410=y
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_SPI is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=m
+CONFIG_SPI_GPIO=m
+CONFIG_SPI_S3C64XX=m
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
 
 #
 # PPS support
@@ -735,6 +767,9 @@ CONFIG_GPIOLIB=y
 #
 # SPI GPIO expanders:
 #
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
 
 #
 # AC97 GPIO expanders:
@@ -750,6 +785,7 @@ CONFIG_HWMON=y
 #
 # CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
@@ -771,6 +807,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
 # CONFIG_SENSORS_LM73 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM77 is not set
@@ -785,6 +822,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LTC4215 is not set
 # CONFIG_SENSORS_LTC4245 is not set
 # CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX6650 is not set
 # CONFIG_SENSORS_PC87360 is not set
@@ -796,6 +834,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
 # CONFIG_SENSORS_AMC6821 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_TMP401 is not set
@@ -809,6 +848,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
 # CONFIG_SENSORS_LIS3_I2C is not set
 # CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
@@ -845,7 +885,10 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_WM8994 is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_MFD_MC13783 is not set
 # CONFIG_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_AB4500_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
@@ -854,8 +897,47 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_S3C=y
+# CONFIG_FB_S3C_DEBUG_REGWRITE is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_L4F00242T03 is not set
+# CONFIG_LCD_LMS283GF05 is not set
+CONFIG_LCD_LTV350QV=y
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_TDO24M is not set
+# CONFIG_LCD_VGG2432A4 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+CONFIG_BACKLIGHT_PWM=y
 
 #
 # Display device support
@@ -867,6 +949,8 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+# CONFIG_LOGO is not set
 CONFIG_SOUND=y
 CONFIG_SOUND_OSS_CORE=y
 CONFIG_SOUND_OSS_CORE_PRECLAIM=y
@@ -895,6 +979,11 @@ CONFIG_SND_DRIVERS=y
 # CONFIG_SND_SERIAL_U16550 is not set
 # CONFIG_SND_MPU401 is not set
 CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
+# CONFIG_SND_USB_CAIAQ is not set
 CONFIG_SND_SOC=m
 CONFIG_SND_SOC_AC97_BUS=y
 CONFIG_SND_S3C24XX_SOC=m
@@ -909,29 +998,197 @@ CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
 # CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
 
 #
 # Special HID drivers
 #
+# CONFIG_HID_3M_PCT is not set
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+# CONFIG_HID_CANDO is not set
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=y
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EGALAX is not set
+CONFIG_HID_EZKEY=y
+CONFIG_HID_KYE=y
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+CONFIG_HID_MICROSOFT=y
+# CONFIG_HID_MOSART is not set
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT_KONE is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 # CONFIG_USB_ARCH_HAS_EHCI is not set
-# CONFIG_USB is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 
 #
-# Enable Host or Gadget support to see Inventra options
+# Miscellaneous USB options
 #
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_EZUSB is not set
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP210X is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
+# CONFIG_USB_SERIAL_QUALCOMM is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_SYMBOL is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
+# CONFIG_USB_SERIAL_ZIO is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_GADGET is not set
 
 #
 # OTG and related infrastructure
 #
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 CONFIG_MMC_DEBUG=y
 CONFIG_MMC_UNSAFE_RESUME=y
@@ -951,11 +1208,77 @@ CONFIG_MMC_SDHCI=y
 # CONFIG_MMC_SDHCI_PLTFM is not set
 CONFIG_MMC_SDHCI_S3C=y
 # CONFIG_MMC_SDHCI_S3C_DMA is not set
+# CONFIG_MMC_SPI is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_S3C=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
@@ -1052,7 +1375,46 @@ CONFIG_ROMFS_ON_BLOCK=y
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
 
 #
 # Kernel hacking
index 7a4138b..fbd85a9 100644 (file)
@@ -258,6 +258,12 @@ static struct clk init_clocks[] = {
                .parent         = &clk_h,
                .enable         = s3c64xx_hclk_ctrl,
                .ctrlbit        = S3C_CLKCON_HCLK_HSMMC2,
+       }, {
+               .name           = "otg",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c64xx_hclk_ctrl,
+               .ctrlbit        = S3C_CLKCON_HCLK_USB,
        }, {
                .name           = "timers",
                .id             = -1,
index 24a931f..b5e2552 100644 (file)
@@ -148,6 +148,7 @@ static struct clk *s5p_clks[] __initdata = {
        &clk_fout_vpll,
        &clk_arm,
        &clk_vpll,
+       &clk_xusbxti,
 };
 
 void __init s5p_register_clocks(unsigned long xtal_freq)
index 34efdd2..db4112c 100644 (file)
@@ -43,6 +43,11 @@ struct s3c_gpio_chip;
  * layouts. Provide an point to vector control routine and provide any
  * per-bank configuration information that other systems such as the
  * external interrupt code will need.
+ *
+ * @sa s3c_gpio_cfgpin
+ * @sa s3c_gpio_getcfg
+ * @sa s3c_gpio_setpull
+ * @sa s3c_gpio_getpull
  */
 struct s3c_gpio_cfg {
        unsigned int    cfg_eint;
@@ -70,11 +75,25 @@ struct s3c_gpio_cfg {
 /**
  * s3c_gpio_cfgpin() - Change the GPIO function of a pin.
  * @pin pin The pin number to configure.
- * @pin to The configuration for the pin's function.
+ * @to to The configuration for the pin's function.
  *
  * Configure which function is actually connected to the external
  * pin, such as an gpio input, output or some form of special function
  * connected to an internal peripheral block.
+ *
+ * The @to parameter can be one of the generic S3C_GPIO_INPUT, S3C_GPIO_OUTPUT
+ * or S3C_GPIO_SFN() to indicate one of the possible values that the helper
+ * will then generate the correct bit mask and shift for the configuration.
+ *
+ * If a bank of GPIOs all needs to be set to special-function 2, then
+ * the following code will work:
+ *
+ *     for (gpio = start; gpio < end; gpio++)
+ *             s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ *
+ * The @to parameter can also be a specific value already shifted to the
+ * correct position in the control register, although these are discouraged
+ * in newer kernels and are only being kept for compatibility.
  */
 extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
 
@@ -108,6 +127,8 @@ extern unsigned s3c_gpio_getcfg(unsigned int pin);
  * This function sets the state of the pull-{up,down} resistor for the
  * specified pin. It will return 0 if successfull, or a negative error
  * code if the pin cannot support the requested pull setting.
+ *
+ * @pull is one of S3C_GPIO_PULL_NONE, S3C_GPIO_PULL_DOWN or S3C_GPIO_PULL_UP.
 */
 extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
 
index 7dc0f0f..2797163 100644 (file)
@@ -17,8 +17,6 @@
 #define L1_CACHE_SHIFT         (CONFIG_FRV_L1_CACHE_SHIFT)
 #define L1_CACHE_BYTES         (1 << L1_CACHE_SHIFT)
 
-#define ARCH_KMALLOC_MINALIGN  L1_CACHE_BYTES
-
 #define __cacheline_aligned    __attribute__((aligned(L1_CACHE_BYTES)))
 #define ____cacheline_aligned  __attribute__((aligned(L1_CACHE_BYTES)))
 
index 2947764..ccae981 100644 (file)
@@ -35,8 +35,8 @@
  * the slab must be aligned such that load- and store-double instructions don't
  * fault if used
  */
-#define        ARCH_KMALLOC_MINALIGN           8
-#define        ARCH_SLAB_MINALIGN              8
+#define        ARCH_KMALLOC_MINALIGN           L1_CACHE_BYTES
+#define        ARCH_SLAB_MINALIGN              L1_CACHE_BYTES
 
 /*****************************************************************************/
 /*
index 5c28082..1a40da9 100644 (file)
@@ -1849,8 +1849,7 @@ out:
        return ret;
 }
 
-static int spufs_mfc_fsync(struct file *file, struct dentry *dentry,
-                          int datasync)
+static int spufs_mfc_fsync(struct file *file, int datasync)
 {
        return spufs_mfc_flush(file, NULL);
 }
index fc1b1c4..e5e5f82 100644 (file)
@@ -251,7 +251,7 @@ const struct file_operations spufs_context_fops = {
        .llseek         = dcache_dir_lseek,
        .read           = generic_read_dir,
        .readdir        = dcache_readdir,
-       .fsync          = simple_sync_file,
+       .fsync          = noop_fsync,
 };
 EXPORT_SYMBOL_GPL(spufs_context_fops);
 
index 1fefae7..e19ff02 100644 (file)
@@ -102,7 +102,7 @@ static const struct file_operations hcall_inst_seq_fops = {
 #define CPU_NAME_BUF_SIZE      32
 
 
-static void probe_hcall_entry(unsigned long opcode, unsigned long *args)
+static void probe_hcall_entry(void *ignored, unsigned long opcode, unsigned long *args)
 {
        struct hcall_stats *h;
 
@@ -114,7 +114,7 @@ static void probe_hcall_entry(unsigned long opcode, unsigned long *args)
        h->purr_start = mfspr(SPRN_PURR);
 }
 
-static void probe_hcall_exit(unsigned long opcode, unsigned long retval,
+static void probe_hcall_exit(void *ignored, unsigned long opcode, unsigned long retval,
                             unsigned long *retbuf)
 {
        struct hcall_stats *h;
@@ -140,11 +140,11 @@ static int __init hcall_inst_init(void)
        if (!firmware_has_feature(FW_FEATURE_LPAR))
                return 0;
 
-       if (register_trace_hcall_entry(probe_hcall_entry))
+       if (register_trace_hcall_entry(probe_hcall_entry, NULL))
                return -EINVAL;
 
-       if (register_trace_hcall_exit(probe_hcall_exit)) {
-               unregister_trace_hcall_entry(probe_hcall_entry);
+       if (register_trace_hcall_exit(probe_hcall_exit, NULL)) {
+               unregister_trace_hcall_entry(probe_hcall_entry, NULL);
                return -EINVAL;
        }
 
index e68541f..73f8833 100644 (file)
@@ -57,6 +57,8 @@ config SATA_PMP
          This option adds support for SATA Port Multipliers
          (the SATA version of an ethernet hub, or SAS expander).
 
+comment "Controllers with non-SFF native interface"
+
 config SATA_AHCI
        tristate "AHCI SATA support"
        depends on PCI
@@ -73,11 +75,12 @@ config SATA_AHCI_PLATFORM
 
          If unsure, say N.
 
-config SATA_SIL24
-       tristate "Silicon Image 3124/3132 SATA support"
-       depends on PCI
+config SATA_FSL
+       tristate "Freescale 3.0Gbps SATA support"
+       depends on FSL_SOC
        help
-         This option enables support for Silicon Image 3124/3132 Serial ATA.
+         This option enables support for Freescale 3.0Gbps SATA controller.
+         It can be found on MPC837x and MPC8315.
 
          If unsure, say N.
 
@@ -87,12 +90,11 @@ config SATA_INIC162X
        help
          This option enables support for Initio 162x Serial ATA.
 
-config SATA_FSL
-       tristate "Freescale 3.0Gbps SATA support"
-       depends on FSL_SOC
+config SATA_SIL24
+       tristate "Silicon Image 3124/3132 SATA support"
+       depends on PCI
        help
-         This option enables support for Freescale 3.0Gbps SATA controller.
-         It can be found on MPC837x and MPC8315.
+         This option enables support for Silicon Image 3124/3132 Serial ATA.
 
          If unsure, say N.
 
@@ -116,15 +118,65 @@ config ATA_SFF
 
 if ATA_SFF
 
-config SATA_SVW
-       tristate "ServerWorks Frodo / Apple K2 SATA support"
+comment "SFF controllers with custom DMA interface"
+
+config PDC_ADMA
+       tristate "Pacific Digital ADMA support"
        depends on PCI
        help
-         This option enables support for Broadcom/Serverworks/Apple K2
-         SATA support.
+         This option enables support for Pacific Digital ADMA controllers
+
+         If unsure, say N.
+
+config PATA_MPC52xx
+       tristate "Freescale MPC52xx SoC internal IDE"
+       depends on PPC_MPC52xx && PPC_BESTCOMM
+       select PPC_BESTCOMM_ATA
+       help
+         This option enables support for integrated IDE controller
+         of the Freescale MPC52xx SoC.
+
+         If unsure, say N.
+
+config PATA_OCTEON_CF
+       tristate "OCTEON Boot Bus Compact Flash support"
+       depends on CPU_CAVIUM_OCTEON
+       help
+         This option enables a polled compact flash driver for use with
+         compact flash cards attached to the OCTEON boot bus.
+
+         If unsure, say N.
+
+config SATA_QSTOR
+       tristate "Pacific Digital SATA QStor support"
+       depends on PCI
+       help
+         This option enables support for Pacific Digital Serial ATA QStor.
+
+         If unsure, say N.
+
+config SATA_SX4
+       tristate "Promise SATA SX4 support (Experimental)"
+       depends on PCI && EXPERIMENTAL
+       help
+         This option enables support for Promise Serial ATA SX4.
 
          If unsure, say N.
 
+config ATA_BMDMA
+       bool "ATA BMDMA support"
+       default y
+       help
+         This option adds support for SFF ATA controllers with BMDMA
+         capability.  BMDMA stands for bus-master DMA and the
+         de-facto DMA interface for SFF controllers.
+
+         If unuser, say Y.
+
+if ATA_BMDMA
+
+comment "SATA SFF controllers with BMDMA"
+
 config ATA_PIIX
        tristate "Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support"
        depends on PCI
@@ -152,22 +204,6 @@ config SATA_NV
 
          If unsure, say N.
 
-config PDC_ADMA
-       tristate "Pacific Digital ADMA support"
-       depends on PCI
-       help
-         This option enables support for Pacific Digital ADMA controllers
-
-         If unsure, say N.
-
-config SATA_QSTOR
-       tristate "Pacific Digital SATA QStor support"
-       depends on PCI
-       help
-         This option enables support for Pacific Digital Serial ATA QStor.
-
-         If unsure, say N.
-
 config SATA_PROMISE
        tristate "Promise SATA TX2/TX4 support"
        depends on PCI
@@ -176,14 +212,6 @@ config SATA_PROMISE
 
          If unsure, say N.
 
-config SATA_SX4
-       tristate "Promise SATA SX4 support (Experimental)"
-       depends on PCI && EXPERIMENTAL
-       help
-         This option enables support for Promise Serial ATA SX4.
-
-         If unsure, say N.
-
 config SATA_SIL
        tristate "Silicon Image SATA support"
        depends on PCI
@@ -203,6 +231,15 @@ config SATA_SIS
          enable the PATA_SIS driver in the config.
          If unsure, say N.
 
+config SATA_SVW
+       tristate "ServerWorks Frodo / Apple K2 SATA support"
+       depends on PCI
+       help
+         This option enables support for Broadcom/Serverworks/Apple K2
+         SATA support.
+
+         If unsure, say N.
+
 config SATA_ULI
        tristate "ULi Electronics SATA support"
        depends on PCI
@@ -227,14 +264,7 @@ config SATA_VITESSE
 
          If unsure, say N.
 
-config PATA_ACPI
-       tristate "ACPI firmware driver for PATA"
-       depends on ATA_ACPI
-       help
-         This option enables an ACPI method driver which drives
-         motherboard PATA controller interfaces through the ACPI
-         firmware in the BIOS. This driver can sometimes handle
-         otherwise unsupported hardware.
+comment "PATA SFF controllers with BMDMA"
 
 config PATA_ALI
        tristate "ALi PATA support"
@@ -262,40 +292,30 @@ config PATA_ARTOP
 
          If unsure, say N.
 
-config PATA_ATP867X
-       tristate "ARTOP/Acard ATP867X PATA support"
+config PATA_ATIIXP
+       tristate "ATI PATA support"
        depends on PCI
        help
-         This option enables support for ARTOP/Acard ATP867X PATA
-         controllers.
-
-         If unsure, say N.
-
-config PATA_AT32
-       tristate "Atmel AVR32 PATA support (Experimental)"
-       depends on AVR32 && PLATFORM_AT32AP && EXPERIMENTAL
-       help
-         This option enables support for the IDE devices on the
-         Atmel AT32AP platform.
+         This option enables support for the ATI ATA interfaces
+         found on the many ATI chipsets.
 
          If unsure, say N.
 
-config PATA_ATIIXP
-       tristate "ATI PATA support"
+config PATA_ATP867X
+       tristate "ARTOP/Acard ATP867X PATA support"
        depends on PCI
        help
-         This option enables support for the ATI ATA interfaces
-         found on the many ATI chipsets.
+         This option enables support for ARTOP/Acard ATP867X PATA
+         controllers.
 
          If unsure, say N.
 
-config PATA_CMD640_PCI
-       tristate "CMD640 PCI PATA support (Experimental)"
-       depends on PCI && EXPERIMENTAL
+config PATA_BF54X
+       tristate "Blackfin 54x ATAPI support"
+       depends on BF542 || BF548 || BF549
        help
-         This option enables support for the CMD640 PCI IDE
-         interface chip. Only the primary channel is currently
-         supported.
+         This option enables support for the built-in ATAPI controller on
+         Blackfin 54x family chips.
 
          If unsure, say N.
 
@@ -362,15 +382,6 @@ config PATA_EFAR
 
          If unsure, say N.
 
-config ATA_GENERIC
-       tristate "Generic ATA support"
-       depends on PCI
-       help
-         This option enables support for generic BIOS configured
-         ATA controllers via the new ATA layer
-
-         If unsure, say N.
-
 config PATA_HPT366
        tristate "HPT 366/368 PATA support"
        depends on PCI
@@ -415,12 +426,20 @@ config PATA_HPT3X3_DMA
          controllers. Enable with care as there are still some
          problems with DMA on this chipset.
 
-config PATA_ISAPNP
-       tristate "ISA Plug and Play PATA support"
-       depends on ISAPNP
+config PATA_ICSIDE
+       tristate "Acorn ICS PATA support"
+       depends on ARM && ARCH_ACORN
        help
-         This option enables support for ISA plug & play ATA
-         controllers such as those found on old soundcards.
+         On Acorn systems, say Y here if you wish to use the ICS PATA
+         interface card.  This is not required for ICS partition support.
+         If you are unsure, say N to this.
+
+config PATA_IT8213
+       tristate "IT8213 PATA support (Experimental)"
+       depends on PCI && EXPERIMENTAL
+       help
+         This option enables support for the ITE 821 PATA
+          controllers via the new ATA layer.
 
          If unsure, say N.
 
@@ -434,15 +453,6 @@ config PATA_IT821X
 
          If unsure, say N.
 
-config PATA_IT8213
-       tristate "IT8213 PATA support (Experimental)"
-       depends on PCI && EXPERIMENTAL
-       help
-         This option enables support for the ITE 821 PATA
-          controllers via the new ATA layer.
-
-         If unsure, say N.
-
 config PATA_JMICRON
        tristate "JMicron PATA support"
        depends on PCI
@@ -452,23 +462,14 @@ config PATA_JMICRON
 
          If unsure, say N.
 
-config PATA_LEGACY
-       tristate "Legacy ISA PATA support (Experimental)"
-       depends on (ISA || PCI)  && EXPERIMENTAL
-       help
-         This option enables support for ISA/VLB/PCI bus legacy PATA
-         ports and allows them to be accessed via the new ATA layer.
-
-         If unsure, say N.
-
-config PATA_TRIFLEX
-       tristate "Compaq Triflex PATA support"
-       depends on PCI
+config PATA_MACIO
+       tristate "Apple PowerMac/PowerBook internal 'MacIO' IDE"
+       depends on PPC_PMAC
        help
-         Enable support for the Compaq 'Triflex' IDE controller as found
-         on many Compaq Pentium-Pro systems, via the new ATA layer.
-
-         If unsure, say N.
+         Most IDE capable PowerMacs have IDE busses driven by a variant
+          of this controller which is part of the Apple chipset used on
+          most PowerMac models. Some models have multiple busses using
+          different chipsets, though generally, MacIO is one of them.
 
 config PATA_MARVELL
        tristate "Marvell PATA support via legacy mode"
@@ -481,32 +482,6 @@ config PATA_MARVELL
 
          If unsure, say N.
 
-config PATA_MPC52xx
-       tristate "Freescale MPC52xx SoC internal IDE"
-       depends on PPC_MPC52xx && PPC_BESTCOMM
-       select PPC_BESTCOMM_ATA
-       help
-         This option enables support for integrated IDE controller
-         of the Freescale MPC52xx SoC.
-
-         If unsure, say N.
-
-config PATA_MPIIX
-       tristate "Intel PATA MPIIX support"
-       depends on PCI
-       help
-         This option enables support for MPIIX PATA support.
-
-         If unsure, say N.
-
-config PATA_OLDPIIX
-       tristate "Intel PATA old PIIX support"
-       depends on PCI
-       help
-         This option enables support for early PIIX PATA support.
-
-         If unsure, say N.
-
 config PATA_NETCELL
        tristate "NETCELL Revolution RAID support"
        depends on PCI
@@ -525,15 +500,6 @@ config PATA_NINJA32
 
          If unsure, say N.
 
-config PATA_NS87410
-       tristate "Nat Semi NS87410 PATA support"
-       depends on PCI
-       help
-         This option enables support for the National Semiconductor
-         NS87410 PCI-IDE controller.
-
-         If unsure, say N.
-
 config PATA_NS87415
        tristate "Nat Semi NS87415 PATA support"
        depends on PCI
@@ -543,12 +509,11 @@ config PATA_NS87415
 
          If unsure, say N.
 
-config PATA_OPTI
-       tristate "OPTI621/6215 PATA support (Very Experimental)"
-       depends on PCI && EXPERIMENTAL
+config PATA_OLDPIIX
+       tristate "Intel PATA old PIIX support"
+       depends on PCI
        help
-         This option enables full PIO support for the early Opti ATA
-         controllers found on some old motherboards.
+         This option enables support for early PIIX PATA support.
 
          If unsure, say N.
 
@@ -562,24 +527,6 @@ config PATA_OPTIDMA
 
          If unsure, say N.
 
-config PATA_PALMLD
-       tristate "Palm LifeDrive PATA support"
-       depends on MACH_PALMLD
-       help
-         This option enables support for Palm LifeDrive's internal ATA
-         port via the new ATA layer.
-
-         If unsure, say N.
-
-config PATA_PCMCIA
-       tristate "PCMCIA PATA support"
-       depends on PCMCIA
-       help
-         This option enables support for PCMCIA ATA interfaces, including
-         compact flash card adapters via the new ATA layer.
-
-         If unsure, say N.
-
 config PATA_PDC2027X
        tristate "Promise PATA 2027x support"
        depends on PCI
@@ -597,12 +544,6 @@ config PATA_PDC_OLD
 
          If unsure, say N.
 
-config PATA_QDI
-       tristate "QDI VLB PATA support"
-       depends on ISA
-       help
-         Support for QDI 6500 and 6580 PATA controllers on VESA local bus.
-
 config PATA_RADISYS
        tristate "RADISYS 82600 PATA support (Experimental)"
        depends on PCI && EXPERIMENTAL
@@ -612,15 +553,6 @@ config PATA_RADISYS
 
          If unsure, say N.
 
-config PATA_RB532
-       tristate "RouterBoard 532 PATA CompactFlash support"
-       depends on MIKROTIK_RB532
-       help
-         This option enables support for the RouterBoard 532
-         PATA CompactFlash controller.
-
-         If unsure, say N.
-
 config PATA_RDC
        tristate "RDC PATA support"
        depends on PCI
@@ -631,21 +563,30 @@ config PATA_RDC
 
          If unsure, say N.
 
-config PATA_RZ1000
-       tristate "PC Tech RZ1000 PATA support"
+config PATA_SC1200
+       tristate "SC1200 PATA support"
        depends on PCI
        help
-         This option enables basic support for the PC Tech RZ1000/1
-         PATA controllers via the new ATA layer
+         This option enables support for the NatSemi/AMD SC1200 SoC
+         companion chip used with the Geode processor family.
 
          If unsure, say N.
 
-config PATA_SC1200
-       tristate "SC1200 PATA support"
+config PATA_SCC
+       tristate "Toshiba's Cell Reference Set IDE support"
+       depends on PCI && PPC_CELLEB
+       help
+         This option enables support for the built-in IDE controller on
+         Toshiba Cell Reference Board.
+
+         If unsure, say N.
+
+config PATA_SCH
+       tristate "Intel SCH PATA support"
        depends on PCI
        help
-         This option enables support for the NatSemi/AMD SC1200 SoC
-         companion chip used with the Geode processor family.
+         This option enables support for Intel SCH PATA on the Intel
+         SCH (US15W, US15L, UL11L) series host controllers.
 
          If unsure, say N.
 
@@ -683,6 +624,15 @@ config PATA_TOSHIBA
 
          If unsure, say N.
 
+config PATA_TRIFLEX
+       tristate "Compaq Triflex PATA support"
+       depends on PCI
+       help
+         Enable support for the Compaq 'Triflex' IDE controller as found
+         on many Compaq Pentium-Pro systems, via the new ATA layer.
+
+         If unsure, say N.
+
 config PATA_VIA
        tristate "VIA PATA support"
        depends on PCI
@@ -701,12 +651,99 @@ config PATA_WINBOND
 
          If unsure, say N.
 
-config PATA_WINBOND_VLB
-       tristate "Winbond W83759A VLB PATA support (Experimental)"
-       depends on ISA && EXPERIMENTAL
+endif # ATA_BMDMA
+
+comment "PIO-only SFF controllers"
+
+config PATA_AT32
+       tristate "Atmel AVR32 PATA support (Experimental)"
+       depends on AVR32 && PLATFORM_AT32AP && EXPERIMENTAL
        help
-         Support for the Winbond W83759A controller on Vesa Local Bus
-         systems.
+         This option enables support for the IDE devices on the
+         Atmel AT32AP platform.
+
+         If unsure, say N.
+
+config PATA_AT91
+       tristate "PATA support for AT91SAM9260"
+       depends on ARM && ARCH_AT91
+       help
+         This option enables support for IDE devices on the Atmel AT91SAM9260 SoC.
+
+         If unsure, say N.
+
+config PATA_CMD640_PCI
+       tristate "CMD640 PCI PATA support (Experimental)"
+       depends on PCI && EXPERIMENTAL
+       help
+         This option enables support for the CMD640 PCI IDE
+         interface chip. Only the primary channel is currently
+         supported.
+
+         If unsure, say N.
+
+config PATA_ISAPNP
+       tristate "ISA Plug and Play PATA support"
+       depends on ISAPNP
+       help
+         This option enables support for ISA plug & play ATA
+         controllers such as those found on old soundcards.
+
+         If unsure, say N.
+
+config PATA_IXP4XX_CF
+       tristate "IXP4XX Compact Flash support"
+       depends on ARCH_IXP4XX
+       help
+         This option enables support for a Compact Flash connected on
+         the ixp4xx expansion bus. This driver had been written for
+         Loft/Avila boards in mind but can work with others.
+
+         If unsure, say N.
+
+config PATA_MPIIX
+       tristate "Intel PATA MPIIX support"
+       depends on PCI
+       help
+         This option enables support for MPIIX PATA support.
+
+         If unsure, say N.
+
+config PATA_NS87410
+       tristate "Nat Semi NS87410 PATA support"
+       depends on PCI
+       help
+         This option enables support for the National Semiconductor
+         NS87410 PCI-IDE controller.
+
+         If unsure, say N.
+
+config PATA_OPTI
+       tristate "OPTI621/6215 PATA support (Very Experimental)"
+       depends on PCI && EXPERIMENTAL
+       help
+         This option enables full PIO support for the early Opti ATA
+         controllers found on some old motherboards.
+
+         If unsure, say N.
+
+config PATA_PALMLD
+       tristate "Palm LifeDrive PATA support"
+       depends on MACH_PALMLD
+       help
+         This option enables support for Palm LifeDrive's internal ATA
+         port via the new ATA layer.
+
+         If unsure, say N.
+
+config PATA_PCMCIA
+       tristate "PCMCIA PATA support"
+       depends on PCMCIA
+       help
+         This option enables support for PCMCIA ATA interfaces, including
+         compact flash card adapters via the new ATA layer.
+
+         If unsure, say N.
 
 config HAVE_PATA_PLATFORM
        bool
@@ -725,14 +762,6 @@ config PATA_PLATFORM
 
          If unsure, say N.
 
-config PATA_AT91
-       tristate "PATA support for AT91SAM9260"
-       depends on ARM && ARCH_AT91
-       help
-         This option enables support for IDE devices on the Atmel AT91SAM9260 SoC.
-
-         If unsure, say N.
-
 config PATA_OF_PLATFORM
        tristate "OpenFirmware platform device PATA support"
        depends on PATA_PLATFORM && PPC_OF
@@ -743,69 +772,65 @@ config PATA_OF_PLATFORM
 
          If unsure, say N.
 
-config PATA_ICSIDE
-       tristate "Acorn ICS PATA support"
-       depends on ARM && ARCH_ACORN
+config PATA_QDI
+       tristate "QDI VLB PATA support"
+       depends on ISA
        help
-         On Acorn systems, say Y here if you wish to use the ICS PATA
-         interface card.  This is not required for ICS partition support.
-         If you are unsure, say N to this.
+         Support for QDI 6500 and 6580 PATA controllers on VESA local bus.
 
-config PATA_IXP4XX_CF
-       tristate "IXP4XX Compact Flash support"
-       depends on ARCH_IXP4XX
+config PATA_RB532
+       tristate "RouterBoard 532 PATA CompactFlash support"
+       depends on MIKROTIK_RB532
        help
-         This option enables support for a Compact Flash connected on
-         the ixp4xx expansion bus. This driver had been written for
-         Loft/Avila boards in mind but can work with others.
+         This option enables support for the RouterBoard 532
+         PATA CompactFlash controller.
 
          If unsure, say N.
 
-config PATA_OCTEON_CF
-       tristate "OCTEON Boot Bus Compact Flash support"
-       depends on CPU_CAVIUM_OCTEON
+config PATA_RZ1000
+       tristate "PC Tech RZ1000 PATA support"
+       depends on PCI
        help
-         This option enables a polled compact flash driver for use with
-         compact flash cards attached to the OCTEON boot bus.
+         This option enables basic support for the PC Tech RZ1000/1
+         PATA controllers via the new ATA layer
 
          If unsure, say N.
 
-config PATA_SCC
-       tristate "Toshiba's Cell Reference Set IDE support"
-       depends on PCI && PPC_CELLEB
+config PATA_WINBOND_VLB
+       tristate "Winbond W83759A VLB PATA support (Experimental)"
+       depends on ISA && EXPERIMENTAL
        help
-         This option enables support for the built-in IDE controller on
-         Toshiba Cell Reference Board.
+         Support for the Winbond W83759A controller on Vesa Local Bus
+         systems.
 
-         If unsure, say N.
+comment "Generic fallback / legacy drivers"
 
-config PATA_SCH
-       tristate "Intel SCH PATA support"
-       depends on PCI
+config PATA_ACPI
+       tristate "ACPI firmware driver for PATA"
+       depends on ATA_ACPI && ATA_BMDMA
        help
-         This option enables support for Intel SCH PATA on the Intel
-         SCH (US15W, US15L, UL11L) series host controllers.
-
-         If unsure, say N.
+         This option enables an ACPI method driver which drives
+         motherboard PATA controller interfaces through the ACPI
+         firmware in the BIOS. This driver can sometimes handle
+         otherwise unsupported hardware.
 
-config PATA_BF54X
-       tristate "Blackfin 54x ATAPI support"
-       depends on BF542 || BF548 || BF549
+config ATA_GENERIC
+       tristate "Generic ATA support"
+       depends on PCI && ATA_BMDMA
        help
-         This option enables support for the built-in ATAPI controller on
-         Blackfin 54x family chips.
+         This option enables support for generic BIOS configured
+         ATA controllers via the new ATA layer
 
          If unsure, say N.
 
-config PATA_MACIO
-       tristate "Apple PowerMac/PowerBook internal 'MacIO' IDE"
-       depends on PPC_PMAC
+config PATA_LEGACY
+       tristate "Legacy ISA PATA support (Experimental)"
+       depends on (ISA || PCI) && EXPERIMENTAL
        help
-         Most IDE capable PowerMacs have IDE busses driven by a variant
-          of this controller which is part of the Apple chipset used on
-          most PowerMac models. Some models have multiple busses using
-          different chipsets, though generally, MacIO is one of them.
+         This option enables support for ISA/VLB/PCI bus legacy PATA
+         ports and allows them to be accessed via the new ATA layer.
 
+         If unsure, say N.
 
 endif # ATA_SFF
 endif # ATA
index d0a93c4..7ef89d7 100644 (file)
@@ -1,33 +1,39 @@
 
 obj-$(CONFIG_ATA)              += libata.o
 
+# non-SFF interface
 obj-$(CONFIG_SATA_AHCI)                += ahci.o libahci.o
 obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o
-obj-$(CONFIG_SATA_SVW)         += sata_svw.o
+obj-$(CONFIG_SATA_FSL)         += sata_fsl.o
+obj-$(CONFIG_SATA_INIC162X)    += sata_inic162x.o
+obj-$(CONFIG_SATA_SIL24)       += sata_sil24.o
+
+# SFF w/ custom DMA
+obj-$(CONFIG_PDC_ADMA)         += pdc_adma.o
+obj-$(CONFIG_PATA_MPC52xx)     += pata_mpc52xx.o
+obj-$(CONFIG_PATA_OCTEON_CF)   += pata_octeon_cf.o
+obj-$(CONFIG_SATA_QSTOR)       += sata_qstor.o
+obj-$(CONFIG_SATA_SX4)         += sata_sx4.o
+
+# SFF SATA w/ BMDMA
 obj-$(CONFIG_ATA_PIIX)         += ata_piix.o
+obj-$(CONFIG_SATA_MV)          += sata_mv.o
+obj-$(CONFIG_SATA_NV)          += sata_nv.o
 obj-$(CONFIG_SATA_PROMISE)     += sata_promise.o
-obj-$(CONFIG_SATA_QSTOR)       += sata_qstor.o
 obj-$(CONFIG_SATA_SIL)         += sata_sil.o
-obj-$(CONFIG_SATA_SIL24)       += sata_sil24.o
-obj-$(CONFIG_SATA_VIA)         += sata_via.o
-obj-$(CONFIG_SATA_VITESSE)     += sata_vsc.o
 obj-$(CONFIG_SATA_SIS)         += sata_sis.o
-obj-$(CONFIG_SATA_SX4)         += sata_sx4.o
-obj-$(CONFIG_SATA_NV)          += sata_nv.o
+obj-$(CONFIG_SATA_SVW)         += sata_svw.o
 obj-$(CONFIG_SATA_ULI)         += sata_uli.o
-obj-$(CONFIG_SATA_MV)          += sata_mv.o
-obj-$(CONFIG_SATA_INIC162X)    += sata_inic162x.o
-obj-$(CONFIG_PDC_ADMA)         += pdc_adma.o
-obj-$(CONFIG_SATA_FSL)         += sata_fsl.o
-obj-$(CONFIG_PATA_MACIO)       += pata_macio.o
+obj-$(CONFIG_SATA_VIA)         += sata_via.o
+obj-$(CONFIG_SATA_VITESSE)     += sata_vsc.o
 
+# SFF PATA w/ BMDMA
 obj-$(CONFIG_PATA_ALI)         += pata_ali.o
 obj-$(CONFIG_PATA_AMD)         += pata_amd.o
 obj-$(CONFIG_PATA_ARTOP)       += pata_artop.o
-obj-$(CONFIG_PATA_ATP867X)     += pata_atp867x.o
-obj-$(CONFIG_PATA_AT32)                += pata_at32.o
 obj-$(CONFIG_PATA_ATIIXP)      += pata_atiixp.o
-obj-$(CONFIG_PATA_CMD640_PCI)  += pata_cmd640.o
+obj-$(CONFIG_PATA_ATP867X)     += pata_atp867x.o
+obj-$(CONFIG_PATA_BF54X)       += pata_bf54x.o
 obj-$(CONFIG_PATA_CMD64X)      += pata_cmd64x.o
 obj-$(CONFIG_PATA_CS5520)      += pata_cs5520.o
 obj-$(CONFIG_PATA_CS5530)      += pata_cs5530.o
@@ -39,47 +45,50 @@ obj-$(CONFIG_PATA_HPT366)   += pata_hpt366.o
 obj-$(CONFIG_PATA_HPT37X)      += pata_hpt37x.o
 obj-$(CONFIG_PATA_HPT3X2N)     += pata_hpt3x2n.o
 obj-$(CONFIG_PATA_HPT3X3)      += pata_hpt3x3.o
-obj-$(CONFIG_PATA_ISAPNP)      += pata_isapnp.o
-obj-$(CONFIG_PATA_IT821X)      += pata_it821x.o
+obj-$(CONFIG_PATA_ICSIDE)      += pata_icside.o
 obj-$(CONFIG_PATA_IT8213)      += pata_it8213.o
+obj-$(CONFIG_PATA_IT821X)      += pata_it821x.o
 obj-$(CONFIG_PATA_JMICRON)     += pata_jmicron.o
+obj-$(CONFIG_PATA_MACIO)       += pata_macio.o
+obj-$(CONFIG_PATA_MARVELL)     += pata_marvell.o
 obj-$(CONFIG_PATA_NETCELL)     += pata_netcell.o
 obj-$(CONFIG_PATA_NINJA32)     += pata_ninja32.o
-obj-$(CONFIG_PATA_NS87410)     += pata_ns87410.o
 obj-$(CONFIG_PATA_NS87415)     += pata_ns87415.o
-obj-$(CONFIG_PATA_OPTI)                += pata_opti.o
-obj-$(CONFIG_PATA_OPTIDMA)     += pata_optidma.o
-obj-$(CONFIG_PATA_MPC52xx)     += pata_mpc52xx.o
-obj-$(CONFIG_PATA_MARVELL)     += pata_marvell.o
-obj-$(CONFIG_PATA_MPIIX)       += pata_mpiix.o
 obj-$(CONFIG_PATA_OLDPIIX)     += pata_oldpiix.o
-obj-$(CONFIG_PATA_PALMLD)      += pata_palmld.o
-obj-$(CONFIG_PATA_PCMCIA)      += pata_pcmcia.o
+obj-$(CONFIG_PATA_OPTIDMA)     += pata_optidma.o
 obj-$(CONFIG_PATA_PDC2027X)    += pata_pdc2027x.o
 obj-$(CONFIG_PATA_PDC_OLD)     += pata_pdc202xx_old.o
-obj-$(CONFIG_PATA_QDI)         += pata_qdi.o
 obj-$(CONFIG_PATA_RADISYS)     += pata_radisys.o
-obj-$(CONFIG_PATA_RB532)       += pata_rb532_cf.o
 obj-$(CONFIG_PATA_RDC)         += pata_rdc.o
-obj-$(CONFIG_PATA_RZ1000)      += pata_rz1000.o
 obj-$(CONFIG_PATA_SC1200)      += pata_sc1200.o
+obj-$(CONFIG_PATA_SCC)         += pata_scc.o
+obj-$(CONFIG_PATA_SCH)         += pata_sch.o
 obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o
 obj-$(CONFIG_PATA_SIL680)      += pata_sil680.o
+obj-$(CONFIG_PATA_SIS)         += pata_sis.o
 obj-$(CONFIG_PATA_TOSHIBA)     += pata_piccolo.o
+obj-$(CONFIG_PATA_TRIFLEX)     += pata_triflex.o
 obj-$(CONFIG_PATA_VIA)         += pata_via.o
 obj-$(CONFIG_PATA_WINBOND)     += pata_sl82c105.o
-obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o
-obj-$(CONFIG_PATA_SIS)         += pata_sis.o
-obj-$(CONFIG_PATA_TRIFLEX)     += pata_triflex.o
+
+# SFF PIO only
+obj-$(CONFIG_PATA_AT32)                += pata_at32.o
+obj-$(CONFIG_PATA_AT91)                += pata_at91.o
+obj-$(CONFIG_PATA_CMD640_PCI)  += pata_cmd640.o
+obj-$(CONFIG_PATA_ISAPNP)      += pata_isapnp.o
 obj-$(CONFIG_PATA_IXP4XX_CF)   += pata_ixp4xx_cf.o
-obj-$(CONFIG_PATA_SCC)         += pata_scc.o
-obj-$(CONFIG_PATA_SCH)         += pata_sch.o
-obj-$(CONFIG_PATA_BF54X)       += pata_bf54x.o
-obj-$(CONFIG_PATA_OCTEON_CF)   += pata_octeon_cf.o
+obj-$(CONFIG_PATA_MPIIX)       += pata_mpiix.o
+obj-$(CONFIG_PATA_NS87410)     += pata_ns87410.o
+obj-$(CONFIG_PATA_OPTI)                += pata_opti.o
+obj-$(CONFIG_PATA_PCMCIA)      += pata_pcmcia.o
+obj-$(CONFIG_PATA_PALMLD)      += pata_palmld.o
 obj-$(CONFIG_PATA_PLATFORM)    += pata_platform.o
-obj-$(CONFIG_PATA_AT91)        += pata_at91.o
 obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o
-obj-$(CONFIG_PATA_ICSIDE)      += pata_icside.o
+obj-$(CONFIG_PATA_QDI)         += pata_qdi.o
+obj-$(CONFIG_PATA_RB532)       += pata_rb532_cf.o
+obj-$(CONFIG_PATA_RZ1000)      += pata_rz1000.o
+obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o
+
 # Should be last but two libata driver
 obj-$(CONFIG_PATA_ACPI)                += pata_acpi.o
 # Should be last but one libata driver
index 33fb614..573158a 100644 (file)
@@ -155,7 +155,7 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id
                        return rc;
                pcim_pin_device(dev);
        }
-       return ata_pci_sff_init_one(dev, ppi, &generic_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(dev, ppi, &generic_sht, NULL, 0);
 }
 
 static struct pci_device_id ata_generic[] = {
index ec52fc6..7409f98 100644 (file)
@@ -1589,7 +1589,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
                hpriv->map = piix_init_sata_map(pdev, port_info,
                                        piix_map_db_table[ent->driver_data]);
 
-       rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+       rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
        if (rc)
                return rc;
        host->private_data = hpriv;
@@ -1626,7 +1626,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
        host->flags |= ATA_HOST_PARALLEL_SCAN;
 
        pci_set_master(pdev);
-       return ata_pci_sff_activate_host(host, ata_sff_interrupt, &piix_sht);
+       return ata_pci_sff_activate_host(host, ata_bmdma_interrupt, &piix_sht);
 }
 
 static void piix_remove_one(struct pci_dev *pdev)
index c47373f..06b7e49 100644 (file)
@@ -160,6 +160,10 @@ int libata_allow_tpm = 0;
 module_param_named(allow_tpm, libata_allow_tpm, int, 0444);
 MODULE_PARM_DESC(allow_tpm, "Permit the use of TPM commands (0=off [default], 1=on)");
 
+static int atapi_an;
+module_param(atapi_an, int, 0444);
+MODULE_PARM_DESC(atapi_an, "Enable ATAPI AN media presence notification (0=0ff [default], 1=on)");
+
 MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("Library module for ATA devices");
 MODULE_LICENSE("GPL");
@@ -2122,6 +2126,14 @@ retry:
                goto err_out;
        }
 
+       if (dev->horkage & ATA_HORKAGE_DUMP_ID) {
+               ata_dev_printk(dev, KERN_DEBUG, "dumping IDENTIFY data, "
+                              "class=%d may_fallback=%d tried_spinup=%d\n",
+                              class, may_fallback, tried_spinup);
+               print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,
+                              16, 2, id, ATA_ID_WORDS * sizeof(*id), true);
+       }
+
        /* Falling back doesn't make sense if ID data was read
         * successfully at least once.
         */
@@ -2510,7 +2522,8 @@ int ata_dev_configure(struct ata_device *dev)
                 * to enable ATAPI AN to discern between PHY status
                 * changed notifications and ATAPI ANs.
                 */
-               if ((ap->flags & ATA_FLAG_AN) && ata_id_has_atapi_AN(id) &&
+               if (atapi_an &&
+                   (ap->flags & ATA_FLAG_AN) && ata_id_has_atapi_AN(id) &&
                    (!sata_pmp_attached(ap) ||
                     sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf) == 0)) {
                        unsigned int err_mask;
@@ -6372,6 +6385,7 @@ static int __init ata_parse_force_one(char **cur,
                { "3.0Gbps",    .spd_limit      = 2 },
                { "noncq",      .horkage_on     = ATA_HORKAGE_NONCQ },
                { "ncq",        .horkage_off    = ATA_HORKAGE_NONCQ },
+               { "dump_id",    .horkage_on     = ATA_HORKAGE_DUMP_ID },
                { "pio0",       .xfer_mask      = 1 << (ATA_SHIFT_PIO + 0) },
                { "pio1",       .xfer_mask      = 1 << (ATA_SHIFT_PIO + 1) },
                { "pio2",       .xfer_mask      = 1 << (ATA_SHIFT_PIO + 2) },
index 19ddf92..efa4a18 100644 (file)
@@ -63,7 +63,6 @@ const struct ata_port_operations ata_sff_port_ops = {
        .sff_tf_read            = ata_sff_tf_read,
        .sff_exec_command       = ata_sff_exec_command,
        .sff_data_xfer          = ata_sff_data_xfer,
-       .sff_irq_clear          = ata_sff_irq_clear,
        .sff_drain_fifo         = ata_sff_drain_fifo,
 
        .lost_interrupt         = ata_sff_lost_interrupt,
@@ -395,32 +394,11 @@ void ata_sff_irq_on(struct ata_port *ap)
                ata_sff_set_devctl(ap, ap->ctl);
        ata_wait_idle(ap);
 
-       ap->ops->sff_irq_clear(ap);
+       if (ap->ops->sff_irq_clear)
+               ap->ops->sff_irq_clear(ap);
 }
 EXPORT_SYMBOL_GPL(ata_sff_irq_on);
 
-/**
- *     ata_sff_irq_clear - Clear PCI IDE BMDMA interrupt.
- *     @ap: Port associated with this ATA transaction.
- *
- *     Clear interrupt and error flags in DMA status register.
- *
- *     May be used as the irq_clear() entry in ata_port_operations.
- *
- *     LOCKING:
- *     spin_lock_irqsave(host lock)
- */
-void ata_sff_irq_clear(struct ata_port *ap)
-{
-       void __iomem *mmio = ap->ioaddr.bmdma_addr;
-
-       if (!mmio)
-               return;
-
-       iowrite8(ioread8(mmio + ATA_DMA_STATUS), mmio + ATA_DMA_STATUS);
-}
-EXPORT_SYMBOL_GPL(ata_sff_irq_clear);
-
 /**
  *     ata_sff_tf_load - send taskfile registers to host controller
  *     @ap: Port to which output is sent
@@ -820,11 +798,15 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc)
        case ATAPI_PROT_NODATA:
                ap->hsm_task_state = HSM_ST_LAST;
                break;
+#ifdef CONFIG_ATA_BMDMA
        case ATAPI_PROT_DMA:
                ap->hsm_task_state = HSM_ST_LAST;
                /* initiate bmdma */
                ap->ops->bmdma_start(qc);
                break;
+#endif /* CONFIG_ATA_BMDMA */
+       default:
+               BUG();
        }
 }
 
@@ -1491,27 +1473,27 @@ bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc)
 }
 EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf);
 
-/**
- *     ata_sff_host_intr - Handle host interrupt for given (port, task)
- *     @ap: Port on which interrupt arrived (possibly...)
- *     @qc: Taskfile currently active in engine
- *
- *     Handle host interrupt for given queued command.  Currently,
- *     only DMA interrupts are handled.  All other commands are
- *     handled via polling with interrupts disabled (nIEN bit).
- *
- *     LOCKING:
- *     spin_lock_irqsave(host lock)
- *
- *     RETURNS:
- *     One if interrupt was handled, zero if not (shared irq).
- */
-unsigned int ata_sff_host_intr(struct ata_port *ap,
-                                     struct ata_queued_cmd *qc)
+static unsigned int ata_sff_idle_irq(struct ata_port *ap)
 {
-       struct ata_eh_info *ehi = &ap->link.eh_info;
-       u8 status, host_stat = 0;
-       bool bmdma_stopped = false;
+       ap->stats.idle_irq++;
+
+#ifdef ATA_IRQ_TRAP
+       if ((ap->stats.idle_irq % 1000) == 0) {
+               ap->ops->sff_check_status(ap);
+               if (ap->ops->sff_irq_clear)
+                       ap->ops->sff_irq_clear(ap);
+               ata_port_printk(ap, KERN_WARNING, "irq trap\n");
+               return 1;
+       }
+#endif
+       return 0;       /* irq not handled */
+}
+
+static unsigned int __ata_sff_port_intr(struct ata_port *ap,
+                                       struct ata_queued_cmd *qc,
+                                       bool hsmv_on_idle)
+{
+       u8 status;
 
        VPRINTK("ata%u: protocol %d task_state %d\n",
                ap->print_id, qc->tf.protocol, ap->hsm_task_state);
@@ -1528,90 +1510,56 @@ unsigned int ata_sff_host_intr(struct ata_port *ap,
                 * need to check ata_is_atapi(qc->tf.protocol) again.
                 */
                if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
-                       goto idle_irq;
-               break;
-       case HSM_ST_LAST:
-               if (qc->tf.protocol == ATA_PROT_DMA ||
-                   qc->tf.protocol == ATAPI_PROT_DMA) {
-                       /* check status of DMA engine */
-                       host_stat = ap->ops->bmdma_status(ap);
-                       VPRINTK("ata%u: host_stat 0x%X\n",
-                               ap->print_id, host_stat);
-
-                       /* if it's not our irq... */
-                       if (!(host_stat & ATA_DMA_INTR))
-                               goto idle_irq;
-
-                       /* before we do anything else, clear DMA-Start bit */
-                       ap->ops->bmdma_stop(qc);
-                       bmdma_stopped = true;
-
-                       if (unlikely(host_stat & ATA_DMA_ERR)) {
-                               /* error when transfering data to/from memory */
-                               qc->err_mask |= AC_ERR_HOST_BUS;
-                               ap->hsm_task_state = HSM_ST_ERR;
-                       }
-               }
+                       return ata_sff_idle_irq(ap);
                break;
        case HSM_ST:
+       case HSM_ST_LAST:
                break;
        default:
-               goto idle_irq;
+               return ata_sff_idle_irq(ap);
        }
 
-
        /* check main status, clearing INTRQ if needed */
        status = ata_sff_irq_status(ap);
        if (status & ATA_BUSY) {
-               if (bmdma_stopped) {
+               if (hsmv_on_idle) {
                        /* BMDMA engine is already stopped, we're screwed */
                        qc->err_mask |= AC_ERR_HSM;
                        ap->hsm_task_state = HSM_ST_ERR;
                } else
-                       goto idle_irq;
+                       return ata_sff_idle_irq(ap);
        }
 
        /* clear irq events */
-       ap->ops->sff_irq_clear(ap);
+       if (ap->ops->sff_irq_clear)
+               ap->ops->sff_irq_clear(ap);
 
        ata_sff_hsm_move(ap, qc, status, 0);
 
-       if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA ||
-                                      qc->tf.protocol == ATAPI_PROT_DMA))
-               ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat);
-
        return 1;       /* irq handled */
-
-idle_irq:
-       ap->stats.idle_irq++;
-
-#ifdef ATA_IRQ_TRAP
-       if ((ap->stats.idle_irq % 1000) == 0) {
-               ap->ops->sff_check_status(ap);
-               ap->ops->sff_irq_clear(ap);
-               ata_port_printk(ap, KERN_WARNING, "irq trap\n");
-               return 1;
-       }
-#endif
-       return 0;       /* irq not handled */
 }
-EXPORT_SYMBOL_GPL(ata_sff_host_intr);
 
 /**
- *     ata_sff_interrupt - Default ATA host interrupt handler
- *     @irq: irq line (unused)
- *     @dev_instance: pointer to our ata_host information structure
+ *     ata_sff_port_intr - Handle SFF port interrupt
+ *     @ap: Port on which interrupt arrived (possibly...)
+ *     @qc: Taskfile currently active in engine
  *
- *     Default interrupt handler for PCI IDE devices.  Calls
- *     ata_sff_host_intr() for each port that is not disabled.
+ *     Handle port interrupt for given queued command.
  *
  *     LOCKING:
- *     Obtains host lock during operation.
+ *     spin_lock_irqsave(host lock)
  *
  *     RETURNS:
- *     IRQ_NONE or IRQ_HANDLED.
+ *     One if interrupt was handled, zero if not (shared irq).
  */
-irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
+unsigned int ata_sff_port_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
+{
+       return __ata_sff_port_intr(ap, qc, false);
+}
+EXPORT_SYMBOL_GPL(ata_sff_port_intr);
+
+static inline irqreturn_t __ata_sff_interrupt(int irq, void *dev_instance,
+       unsigned int (*port_intr)(struct ata_port *, struct ata_queued_cmd *))
 {
        struct ata_host *host = dev_instance;
        bool retried = false;
@@ -1631,7 +1579,7 @@ retry:
                qc = ata_qc_from_tag(ap, ap->link.active_tag);
                if (qc) {
                        if (!(qc->tf.flags & ATA_TFLAG_POLLING))
-                               handled |= ata_sff_host_intr(ap, qc);
+                               handled |= port_intr(ap, qc);
                        else
                                polling |= 1 << i;
                } else
@@ -1658,7 +1606,8 @@ retry:
 
                        if (idle & (1 << i)) {
                                ap->ops->sff_check_status(ap);
-                               ap->ops->sff_irq_clear(ap);
+                               if (ap->ops->sff_irq_clear)
+                                       ap->ops->sff_irq_clear(ap);
                        } else {
                                /* clear INTRQ and check if BUSY cleared */
                                if (!(ap->ops->sff_check_status(ap) & ATA_BUSY))
@@ -1680,6 +1629,25 @@ retry:
 
        return IRQ_RETVAL(handled);
 }
+
+/**
+ *     ata_sff_interrupt - Default SFF ATA host interrupt handler
+ *     @irq: irq line (unused)
+ *     @dev_instance: pointer to our ata_host information structure
+ *
+ *     Default interrupt handler for PCI IDE devices.  Calls
+ *     ata_sff_port_intr() for each port that is not disabled.
+ *
+ *     LOCKING:
+ *     Obtains host lock during operation.
+ *
+ *     RETURNS:
+ *     IRQ_NONE or IRQ_HANDLED.
+ */
+irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
+{
+       return __ata_sff_interrupt(irq, dev_instance, ata_sff_port_intr);
+}
 EXPORT_SYMBOL_GPL(ata_sff_interrupt);
 
 /**
@@ -1717,7 +1685,7 @@ void ata_sff_lost_interrupt(struct ata_port *ap)
                                                                status);
        /* Run the host interrupt logic as if the interrupt had not been
           lost */
-       ata_sff_host_intr(ap, qc);
+       ata_sff_port_intr(ap, qc);
 }
 EXPORT_SYMBOL_GPL(ata_sff_lost_interrupt);
 
@@ -1744,7 +1712,8 @@ void ata_sff_freeze(struct ata_port *ap)
         */
        ap->ops->sff_check_status(ap);
 
-       ap->ops->sff_irq_clear(ap);
+       if (ap->ops->sff_irq_clear)
+               ap->ops->sff_irq_clear(ap);
 }
 EXPORT_SYMBOL_GPL(ata_sff_freeze);
 
@@ -1761,7 +1730,8 @@ void ata_sff_thaw(struct ata_port *ap)
 {
        /* clear & re-enable interrupts */
        ap->ops->sff_check_status(ap);
-       ap->ops->sff_irq_clear(ap);
+       if (ap->ops->sff_irq_clear)
+               ap->ops->sff_irq_clear(ap);
        ata_sff_irq_on(ap);
 }
 EXPORT_SYMBOL_GPL(ata_sff_thaw);
@@ -2349,13 +2319,13 @@ int ata_pci_sff_init_host(struct ata_host *host)
 EXPORT_SYMBOL_GPL(ata_pci_sff_init_host);
 
 /**
- *     ata_pci_sff_prepare_host - helper to prepare native PCI ATA host
+ *     ata_pci_sff_prepare_host - helper to prepare PCI PIO-only SFF ATA host
  *     @pdev: target PCI device
  *     @ppi: array of port_info, must be enough for two ports
  *     @r_host: out argument for the initialized ATA host
  *
- *     Helper to allocate ATA host for @pdev, acquire all native PCI
- *     resources and initialize it accordingly in one go.
+ *     Helper to allocate PIO-only SFF ATA host for @pdev, acquire
+ *     all PCI resources and initialize it accordingly in one go.
  *
  *     LOCKING:
  *     Inherited from calling layer (may sleep).
@@ -2385,9 +2355,6 @@ int ata_pci_sff_prepare_host(struct pci_dev *pdev,
        if (rc)
                goto err_out;
 
-       /* init DMA related stuff */
-       ata_pci_bmdma_init(host);
-
        devres_remove_group(&pdev->dev, NULL);
        *r_host = host;
        return 0;
@@ -2492,8 +2459,21 @@ out:
 }
 EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host);
 
+static const struct ata_port_info *ata_sff_find_valid_pi(
+                                       const struct ata_port_info * const *ppi)
+{
+       int i;
+
+       /* look up the first valid port_info */
+       for (i = 0; i < 2 && ppi[i]; i++)
+               if (ppi[i]->port_ops != &ata_dummy_port_ops)
+                       return ppi[i];
+
+       return NULL;
+}
+
 /**
- *     ata_pci_sff_init_one - Initialize/register PCI IDE host controller
+ *     ata_pci_sff_init_one - Initialize/register PIO-only PCI IDE controller
  *     @pdev: Controller to be initialized
  *     @ppi: array of port_info, must be enough for two ports
  *     @sht: scsi_host_template to use when registering the host
@@ -2502,11 +2482,7 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host);
  *
  *     This is a helper function which can be called from a driver's
  *     xxx_init_one() probe function if the hardware uses traditional
- *     IDE taskfile registers.
- *
- *     This function calls pci_enable_device(), reserves its register
- *     regions, sets the dma mask, enables bus master mode, and calls
- *     ata_device_add()
+ *     IDE taskfile registers and is PIO only.
  *
  *     ASSUMPTION:
  *     Nobody makes a single channel controller that appears solely as
@@ -2523,20 +2499,13 @@ int ata_pci_sff_init_one(struct pci_dev *pdev,
                 struct scsi_host_template *sht, void *host_priv, int hflag)
 {
        struct device *dev = &pdev->dev;
-       const struct ata_port_info *pi = NULL;
+       const struct ata_port_info *pi;
        struct ata_host *host = NULL;
-       int i, rc;
+       int rc;
 
        DPRINTK("ENTER\n");
 
-       /* look up the first valid port_info */
-       for (i = 0; i < 2 && ppi[i]; i++) {
-               if (ppi[i]->port_ops != &ata_dummy_port_ops) {
-                       pi = ppi[i];
-                       break;
-               }
-       }
-
+       pi = ata_sff_find_valid_pi(ppi);
        if (!pi) {
                dev_printk(KERN_ERR, &pdev->dev,
                           "no valid port_info specified\n");
@@ -2557,7 +2526,6 @@ int ata_pci_sff_init_one(struct pci_dev *pdev,
        host->private_data = host_priv;
        host->flags |= hflag;
 
-       pci_set_master(pdev);
        rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht);
 out:
        if (rc == 0)
@@ -2571,6 +2539,12 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
 
 #endif /* CONFIG_PCI */
 
+/*
+ *     BMDMA support
+ */
+
+#ifdef CONFIG_ATA_BMDMA
+
 const struct ata_port_operations ata_bmdma_port_ops = {
        .inherits               = &ata_sff_port_ops,
 
@@ -2580,6 +2554,7 @@ const struct ata_port_operations ata_bmdma_port_ops = {
        .qc_prep                = ata_bmdma_qc_prep,
        .qc_issue               = ata_bmdma_qc_issue,
 
+       .sff_irq_clear          = ata_bmdma_irq_clear,
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
        .bmdma_stop             = ata_bmdma_stop,
@@ -2803,6 +2778,75 @@ unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc)
 }
 EXPORT_SYMBOL_GPL(ata_bmdma_qc_issue);
 
+/**
+ *     ata_bmdma_port_intr - Handle BMDMA port interrupt
+ *     @ap: Port on which interrupt arrived (possibly...)
+ *     @qc: Taskfile currently active in engine
+ *
+ *     Handle port interrupt for given queued command.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host lock)
+ *
+ *     RETURNS:
+ *     One if interrupt was handled, zero if not (shared irq).
+ */
+unsigned int ata_bmdma_port_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
+{
+       struct ata_eh_info *ehi = &ap->link.eh_info;
+       u8 host_stat = 0;
+       bool bmdma_stopped = false;
+       unsigned int handled;
+
+       if (ap->hsm_task_state == HSM_ST_LAST && ata_is_dma(qc->tf.protocol)) {
+               /* check status of DMA engine */
+               host_stat = ap->ops->bmdma_status(ap);
+               VPRINTK("ata%u: host_stat 0x%X\n", ap->print_id, host_stat);
+
+               /* if it's not our irq... */
+               if (!(host_stat & ATA_DMA_INTR))
+                       return ata_sff_idle_irq(ap);
+
+               /* before we do anything else, clear DMA-Start bit */
+               ap->ops->bmdma_stop(qc);
+               bmdma_stopped = true;
+
+               if (unlikely(host_stat & ATA_DMA_ERR)) {
+                       /* error when transfering data to/from memory */
+                       qc->err_mask |= AC_ERR_HOST_BUS;
+                       ap->hsm_task_state = HSM_ST_ERR;
+               }
+       }
+
+       handled = __ata_sff_port_intr(ap, qc, bmdma_stopped);
+
+       if (unlikely(qc->err_mask) && ata_is_dma(qc->tf.protocol))
+               ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat);
+
+       return handled;
+}
+EXPORT_SYMBOL_GPL(ata_bmdma_port_intr);
+
+/**
+ *     ata_bmdma_interrupt - Default BMDMA ATA host interrupt handler
+ *     @irq: irq line (unused)
+ *     @dev_instance: pointer to our ata_host information structure
+ *
+ *     Default interrupt handler for PCI IDE devices.  Calls
+ *     ata_bmdma_port_intr() for each port that is not disabled.
+ *
+ *     LOCKING:
+ *     Obtains host lock during operation.
+ *
+ *     RETURNS:
+ *     IRQ_NONE or IRQ_HANDLED.
+ */
+irqreturn_t ata_bmdma_interrupt(int irq, void *dev_instance)
+{
+       return __ata_sff_interrupt(irq, dev_instance, ata_bmdma_port_intr);
+}
+EXPORT_SYMBOL_GPL(ata_bmdma_interrupt);
+
 /**
  *     ata_bmdma_error_handler - Stock error handler for BMDMA controller
  *     @ap: port to handle error for
@@ -2848,7 +2892,8 @@ void ata_bmdma_error_handler(struct ata_port *ap)
                /* if we're gonna thaw, make sure IRQ is clear */
                if (thaw) {
                        ap->ops->sff_check_status(ap);
-                       ap->ops->sff_irq_clear(ap);
+                       if (ap->ops->sff_irq_clear)
+                               ap->ops->sff_irq_clear(ap);
                }
        }
 
@@ -2881,6 +2926,28 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
 }
 EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd);
 
+/**
+ *     ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt.
+ *     @ap: Port associated with this ATA transaction.
+ *
+ *     Clear interrupt and error flags in DMA status register.
+ *
+ *     May be used as the irq_clear() entry in ata_port_operations.
+ *
+ *     LOCKING:
+ *     spin_lock_irqsave(host lock)
+ */
+void ata_bmdma_irq_clear(struct ata_port *ap)
+{
+       void __iomem *mmio = ap->ioaddr.bmdma_addr;
+
+       if (!mmio)
+               return;
+
+       iowrite8(ioread8(mmio + ATA_DMA_STATUS), mmio + ATA_DMA_STATUS);
+}
+EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear);
+
 /**
  *     ata_bmdma_setup - Set up PCI IDE BMDMA transaction
  *     @qc: Info associated with this ATA transaction.
@@ -3137,7 +3204,100 @@ void ata_pci_bmdma_init(struct ata_host *host)
 }
 EXPORT_SYMBOL_GPL(ata_pci_bmdma_init);
 
+/**
+ *     ata_pci_bmdma_prepare_host - helper to prepare PCI BMDMA ATA host
+ *     @pdev: target PCI device
+ *     @ppi: array of port_info, must be enough for two ports
+ *     @r_host: out argument for the initialized ATA host
+ *
+ *     Helper to allocate BMDMA ATA host for @pdev, acquire all PCI
+ *     resources and initialize it accordingly in one go.
+ *
+ *     LOCKING:
+ *     Inherited from calling layer (may sleep).
+ *
+ *     RETURNS:
+ *     0 on success, -errno otherwise.
+ */
+int ata_pci_bmdma_prepare_host(struct pci_dev *pdev,
+                              const struct ata_port_info * const * ppi,
+                              struct ata_host **r_host)
+{
+       int rc;
+
+       rc = ata_pci_sff_prepare_host(pdev, ppi, r_host);
+       if (rc)
+               return rc;
+
+       ata_pci_bmdma_init(*r_host);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ata_pci_bmdma_prepare_host);
+
+/**
+ *     ata_pci_bmdma_init_one - Initialize/register BMDMA PCI IDE controller
+ *     @pdev: Controller to be initialized
+ *     @ppi: array of port_info, must be enough for two ports
+ *     @sht: scsi_host_template to use when registering the host
+ *     @host_priv: host private_data
+ *     @hflags: host flags
+ *
+ *     This function is similar to ata_pci_sff_init_one() but also
+ *     takes care of BMDMA initialization.
+ *
+ *     LOCKING:
+ *     Inherited from PCI layer (may sleep).
+ *
+ *     RETURNS:
+ *     Zero on success, negative on errno-based value on error.
+ */
+int ata_pci_bmdma_init_one(struct pci_dev *pdev,
+                          const struct ata_port_info * const * ppi,
+                          struct scsi_host_template *sht, void *host_priv,
+                          int hflags)
+{
+       struct device *dev = &pdev->dev;
+       const struct ata_port_info *pi;
+       struct ata_host *host = NULL;
+       int rc;
+
+       DPRINTK("ENTER\n");
+
+       pi = ata_sff_find_valid_pi(ppi);
+       if (!pi) {
+               dev_printk(KERN_ERR, &pdev->dev,
+                          "no valid port_info specified\n");
+               return -EINVAL;
+       }
+
+       if (!devres_open_group(dev, NULL, GFP_KERNEL))
+               return -ENOMEM;
+
+       rc = pcim_enable_device(pdev);
+       if (rc)
+               goto out;
+
+       /* prepare and activate BMDMA host */
+       rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
+       if (rc)
+               goto out;
+       host->private_data = host_priv;
+       host->flags |= hflags;
+
+       pci_set_master(pdev);
+       rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht);
+ out:
+       if (rc == 0)
+               devres_remove_group(&pdev->dev, NULL);
+       else
+               devres_release_group(&pdev->dev, NULL);
+
+       return rc;
+}
+EXPORT_SYMBOL_GPL(ata_pci_bmdma_init_one);
+
 #endif /* CONFIG_PCI */
+#endif /* CONFIG_ATA_BMDMA */
 
 /**
  *     ata_sff_port_init - Initialize SFF/BMDMA ATA port
index 066b9f3..c8d4703 100644 (file)
@@ -260,7 +260,7 @@ static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
                        return rc;
                pcim_pin_device(pdev);
        }
-       return ata_pci_sff_init_one(pdev, ppi, &pacpi_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &pacpi_sht, NULL, 0);
 }
 
 static const struct pci_device_id pacpi_pci_tbl[] = {
index f306e10..794ec6e 100644 (file)
@@ -583,7 +583,10 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                        ppi[0] = &info_20_udma;
        }
 
-       return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL, 0);
+       if (!ppi[0]->mwdma_mask && !ppi[0]->udma_mask)
+               return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL, 0);
+       else
+               return ata_pci_bmdma_init_one(pdev, ppi, &ali_sht, NULL, 0);
 }
 
 #ifdef CONFIG_PM
index d95eca9..620a07c 100644 (file)
@@ -574,7 +574,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        }
 
        /* And fire it up */
-       return ata_pci_sff_init_one(pdev, ppi, &amd_sht, hpriv, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &amd_sht, hpriv, 0);
 }
 
 #ifdef CONFIG_PM
index 4d066d6..ba43f0f 100644 (file)
@@ -421,7 +421,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
 
        BUG_ON(ppi[0] == NULL);
 
-       return ata_pci_sff_init_one(pdev, ppi, &artop_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &artop_sht, NULL, 0);
 }
 
 static const struct pci_device_id artop_pci_tbl[] = {
index 44d88b3..4375561 100644 (file)
@@ -246,8 +246,8 @@ static int atiixp_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                if (!pci_test_config_bits(pdev, &atiixp_enable_bits[i]))
                        ppi[i] = &ata_dummy_port_info;
 
-       return ata_pci_sff_init_one(pdev, ppi, &atiixp_sht, NULL,
-                                               ATA_HOST_PARALLEL_SCAN);
+       return ata_pci_bmdma_init_one(pdev, ppi, &atiixp_sht, NULL,
+                                     ATA_HOST_PARALLEL_SCAN);
 }
 
 static const struct pci_device_id atiixp[] = {
index bb6e074..9529593 100644 (file)
@@ -525,7 +525,7 @@ static int atp867x_init_one(struct pci_dev *pdev,
 
        pci_set_master(pdev);
 
-       rc = ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+       rc = ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
                                IRQF_SHARED, &atp867x_sht);
        if (rc)
                dev_printk(KERN_ERR, &pdev->dev, "failed to activate host\n");
index 6422cfd..9cae65d 100644 (file)
@@ -1214,7 +1214,7 @@ static unsigned int bfin_data_xfer(struct ata_device *dev, unsigned char *buf,
  *     bfin_irq_clear - Clear ATAPI interrupt.
  *     @ap: Port associated with this ATA transaction.
  *
- *     Note: Original code is ata_sff_irq_clear().
+ *     Note: Original code is ata_bmdma_irq_clear().
  */
 
 static void bfin_irq_clear(struct ata_port *ap)
index 4c81a71..9f5da1c 100644 (file)
@@ -367,7 +367,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
 #endif
 
-       return ata_pci_sff_init_one(pdev, ppi, &cmd64x_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &cmd64x_sht, NULL, 0);
 }
 
 #ifdef CONFIG_PM
index 17c5f34..030952f 100644 (file)
@@ -221,7 +221,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
                        continue;
 
                rc = devm_request_irq(&pdev->dev, irq[ap->port_no],
-                                     ata_sff_interrupt, 0, DRV_NAME, host);
+                                     ata_bmdma_interrupt, 0, DRV_NAME, host);
                if (rc)
                        return rc;
 
index e809a42..f792330 100644 (file)
@@ -324,7 +324,7 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                ppi[1] = &info_palmax_secondary;
 
        /* Now kick off ATA set up */
-       return ata_pci_sff_init_one(pdev, ppi, &cs5530_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &cs5530_sht, NULL, 0);
 }
 
 #ifdef CONFIG_PM
index a02e645..03a9318 100644 (file)
@@ -198,7 +198,7 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        rdmsr(ATAC_CH0D1_PIO, timings, dummy);
        if (CS5535_BAD_PIO(timings))
                wrmsr(ATAC_CH0D1_PIO, 0xF7F4F7F4UL, 0);
-       return ata_pci_sff_init_one(dev, ppi, &cs5535_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(dev, ppi, &cs5535_sht, NULL, 0);
 }
 
 static const struct pci_device_id cs5535[] = {
index 914ae35..21ee23f 100644 (file)
@@ -260,7 +260,7 @@ static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                return -ENODEV;
        }
 
-       return ata_pci_sff_init_one(dev, ppi, &cs5536_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(dev, ppi, &cs5536_sht, NULL, 0);
 }
 
 static const struct pci_device_id cs5536[] = {
index 0fcc096..6d915b0 100644 (file)
@@ -138,7 +138,7 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i
        if (PCI_FUNC(pdev->devfn) != 1)
                return -ENODEV;
 
-       return ata_pci_sff_init_one(pdev, ppi, &cy82c693_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &cy82c693_sht, NULL, 0);
 }
 
 static const struct pci_device_id cy82c693[] = {
index 3bac0e0..a088347 100644 (file)
@@ -277,8 +277,8 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                dev_printk(KERN_DEBUG, &pdev->dev,
                           "version " DRV_VERSION "\n");
 
-       return ata_pci_sff_init_one(pdev, ppi, &efar_sht, NULL,
-                                       ATA_HOST_PARALLEL_SCAN);
+       return ata_pci_bmdma_init_one(pdev, ppi, &efar_sht, NULL,
+                                     ATA_HOST_PARALLEL_SCAN);
 }
 
 static const struct pci_device_id efar_pci_tbl[] = {
index 8580eb3..7688868 100644 (file)
@@ -361,7 +361,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                        break;
        }
        /* Now kick off ATA set up */
-       return ata_pci_sff_init_one(dev, ppi, &hpt36x_sht, hpriv, 0);
+       return ata_pci_bmdma_init_one(dev, ppi, &hpt36x_sht, hpriv, 0);
 }
 
 #ifdef CONFIG_PM
index 98b498b..9ae4c08 100644 (file)
@@ -987,7 +987,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        }
 
        /* Now kick off ATA set up */
-       return ata_pci_sff_init_one(dev, ppi, &hpt37x_sht, private_data, 0);
+       return ata_pci_bmdma_init_one(dev, ppi, &hpt37x_sht, private_data, 0);
 }
 
 static const struct pci_device_id hpt37x[] = {
index 8b95aeb..32f3463 100644 (file)
@@ -548,7 +548,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c);
 
        /* Now kick off ATA set up */
-       return ata_pci_sff_init_one(dev, ppi, &hpt3x2n_sht, hpriv, 0);
+       return ata_pci_bmdma_init_one(dev, ppi, &hpt3x2n_sht, hpriv, 0);
 }
 
 static const struct pci_device_id hpt3x2n[] = {
index 727a81c..b63d5e2 100644 (file)
@@ -248,7 +248,7 @@ static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                ata_port_pbar_desc(ap, 4, offset_cmd[i], "cmd");
        }
        pci_set_master(pdev);
-       return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+       return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
                                 IRQF_SHARED, &hpt3x3_sht);
 }
 
index b56e8f7..9f2889f 100644 (file)
@@ -470,7 +470,7 @@ static int __devinit pata_icside_add_ports(struct pata_icside_info *info)
                pata_icside_setup_ioaddr(ap, info->base, info, info->port[i]);
        }
 
-       return ata_host_activate(host, ec->irq, ata_sff_interrupt, 0,
+       return ata_host_activate(host, ec->irq, ata_bmdma_interrupt, 0,
                                 &pata_icside_sht);
 }
 
index f971f0d..4d142a2 100644 (file)
@@ -273,7 +273,7 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en
                dev_printk(KERN_DEBUG, &pdev->dev,
                           "version " DRV_VERSION "\n");
 
-       return ata_pci_sff_init_one(pdev, ppi, &it8213_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &it8213_sht, NULL, 0);
 }
 
 static const struct pci_device_id it8213_pci_tbl[] = {
index 2bd2b00..bf88f71 100644 (file)
@@ -933,7 +933,7 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                else
                        ppi[0] = &info_smart;
        }
-       return ata_pci_sff_init_one(pdev, ppi, &it821x_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &it821x_sht, NULL, 0);
 }
 
 #ifdef CONFIG_PM
index 565e01e..cb3babb 100644 (file)
@@ -144,7 +144,7 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
        };
        const struct ata_port_info *ppi[] = { &info, NULL };
 
-       return ata_pci_sff_init_one(pdev, ppi, &jmicron_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &jmicron_sht, NULL, 0);
 }
 
 static const struct pci_device_id jmicron_pci_tbl[] = {
index b5b48e7..76640ac 100644 (file)
@@ -1110,7 +1110,7 @@ static int __devinit pata_macio_common_init(struct pata_macio_priv        *priv,
 
        /* Start it up */
        priv->irq = irq;
-       return ata_host_activate(priv->host, irq, ata_sff_interrupt, 0,
+       return ata_host_activate(priv->host, irq, ata_bmdma_interrupt, 0,
                                 &pata_macio_sht);
 }
 
index e8ca02e..dd38083 100644 (file)
@@ -153,7 +153,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
                return -ENODEV;
        }
 #endif
-       return ata_pci_sff_init_one(pdev, ppi, &marvell_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &marvell_sht, NULL, 0);
 }
 
 static const struct pci_device_id marvell_pci_tbl[] = {
index 36afe2c..f087ab5 100644 (file)
@@ -659,7 +659,7 @@ mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv,
        ata_port_desc(ap, "ata_regs 0x%lx", raw_ata_regs);
 
        /* activate host */
-       return ata_host_activate(host, priv->ata_irq, ata_sff_interrupt, 0,
+       return ata_host_activate(host, priv->ata_irq, ata_bmdma_interrupt, 0,
                                 &mpc52xx_ata_sht);
 }
 
index 94f979a..3eb921c 100644 (file)
@@ -82,7 +82,7 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e
        ata_pci_bmdma_clear_simplex(pdev);
 
        /* And let the library code do the work */
-       return ata_pci_sff_init_one(pdev, port_info, &netcell_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(pdev, port_info, &netcell_sht, NULL, 0);
 }
 
 static const struct pci_device_id netcell_pci_tbl[] = {
index dd53a66..cc50bd0 100644 (file)
@@ -149,7 +149,7 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 
        ninja32_program(base);
        /* FIXME: Should we disable them at remove ? */
-       return ata_host_activate(host, dev->irq, ata_sff_interrupt,
+       return ata_host_activate(host, dev->irq, ata_bmdma_interrupt,
                                 IRQF_SHARED, &ninja32_sht);
 }
 
index fdbba2d..605f198 100644 (file)
@@ -380,7 +380,7 @@ static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *e
 
        ns87415_fixup(pdev);
 
-       return ata_pci_sff_init_one(pdev, ppi, &ns87415_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &ns87415_sht, NULL, 0);
 }
 
 static const struct pci_device_id ns87415_pci_tbl[] = {
index 3001109..06ddd91 100644 (file)
@@ -749,20 +749,6 @@ static void octeon_cf_dev_config(struct ata_device *dev)
        dev->max_sectors = min(dev->max_sectors, 4095U);
 }
 
-/*
- * Trap if driver tries to do standard bmdma commands.  They are not
- * supported.
- */
-static void unreachable_qc(struct ata_queued_cmd *qc)
-{
-       BUG();
-}
-
-static u8 unreachable_port(struct ata_port *ap)
-{
-       BUG();
-}
-
 /*
  * We don't do ATAPI DMA so return 0.
  */
@@ -804,10 +790,6 @@ static struct ata_port_operations octeon_cf_ops = {
        .sff_dev_select         = octeon_cf_dev_select,
        .sff_irq_on             = octeon_cf_irq_on,
        .sff_irq_clear          = octeon_cf_irq_clear,
-       .bmdma_setup            = unreachable_qc,
-       .bmdma_start            = unreachable_qc,
-       .bmdma_stop             = unreachable_qc,
-       .bmdma_status           = unreachable_port,
        .cable_detect           = ata_cable_40wire,
        .set_piomode            = octeon_cf_set_piomode,
        .set_dmamode            = octeon_cf_set_dmamode,
index 988ef26..b811c16 100644 (file)
@@ -248,7 +248,7 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *e
                dev_printk(KERN_DEBUG, &pdev->dev,
                           "version " DRV_VERSION "\n");
 
-       return ata_pci_sff_init_one(pdev, ppi, &oldpiix_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &oldpiix_sht, NULL, 0);
 }
 
 static const struct pci_device_id oldpiix_pci_tbl[] = {
index 76b7d12..0852cd0 100644 (file)
@@ -429,7 +429,7 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        if (optiplus_with_udma(dev))
                ppi[0] = &info_82c700_udma;
 
-       return ata_pci_sff_init_one(dev, ppi, &optidma_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(dev, ppi, &optidma_sht, NULL, 0);
 }
 
 static const struct pci_device_id optidma[] = {
index 09f1f22..b183511 100644 (file)
@@ -754,7 +754,7 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
                return -EIO;
 
        pci_set_master(pdev);
-       return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+       return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
                                 IRQF_SHARED, &pdc2027x_sht);
 }
 
index fa1e2f3..c39f213 100644 (file)
@@ -337,7 +337,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
                                return -ENODEV;
                }
        }
-       return ata_pci_sff_init_one(dev, ppi, &pdc202xx_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(dev, ppi, &pdc202xx_sht, NULL, 0);
 }
 
 static const struct pci_device_id pdc202xx[] = {
index 9816154..cb01bf9 100644 (file)
@@ -95,7 +95,7 @@ static int ata_tosh_init_one(struct pci_dev *dev, const struct pci_device_id *id
        };
        const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
        /* Just one port for the moment */
-       return ata_pci_sff_init_one(dev, ppi, &tosh_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(dev, ppi, &tosh_sht, NULL, 0);
 }
 
 static struct pci_device_id ata_tosh[] = {
index a5fa388..8574b31 100644 (file)
@@ -227,7 +227,7 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e
                dev_printk(KERN_DEBUG, &pdev->dev,
                           "version " DRV_VERSION "\n");
 
-       return ata_pci_sff_init_one(pdev, ppi, &radisys_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &radisys_sht, NULL, 0);
 }
 
 static const struct pci_device_id radisys_pci_tbl[] = {
index 37092cf..5fbe9b1 100644 (file)
@@ -344,7 +344,7 @@ static int __devinit rdc_init_one(struct pci_dev *pdev,
         */
        pci_read_config_dword(pdev, 0x54, &hpriv->saved_iocfg);
 
-       rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+       rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
        if (rc)
                return rc;
        host->private_data = hpriv;
@@ -354,7 +354,7 @@ static int __devinit rdc_init_one(struct pci_dev *pdev,
        host->flags |= ATA_HOST_PARALLEL_SCAN;
 
        pci_set_master(pdev);
-       return ata_pci_sff_activate_host(host, ata_sff_interrupt, &rdc_sht);
+       return ata_pci_sff_activate_host(host, ata_bmdma_interrupt, &rdc_sht);
 }
 
 static void rdc_remove_one(struct pci_dev *pdev)
index 6b5b63a..e2c1825 100644 (file)
@@ -237,7 +237,7 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        };
        const struct ata_port_info *ppi[] = { &info, NULL };
 
-       return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(dev, ppi, &sc1200_sht, NULL, 0);
 }
 
 static const struct pci_device_id sc1200[] = {
index 6f6193b..d9db3f8 100644 (file)
@@ -875,7 +875,7 @@ static void scc_postreset(struct ata_link *link, unsigned int *classes)
  *     scc_irq_clear - Clear PCI IDE BMDMA interrupt.
  *     @ap: Port associated with this ATA transaction.
  *
- *     Note: Original code is ata_sff_irq_clear().
+ *     Note: Original code is ata_bmdma_irq_clear().
  */
 
 static void scc_irq_clear (struct ata_port *ap)
@@ -1105,7 +1105,7 @@ static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc)
                return rc;
 
-       return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+       return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
                                 IRQF_SHARED, &scc_sht);
 }
 
index 86b3d01..e97b32f 100644 (file)
@@ -179,7 +179,7 @@ static int __devinit sch_init_one(struct pci_dev *pdev,
                dev_printk(KERN_DEBUG, &pdev->dev,
                           "version " DRV_VERSION "\n");
 
-       return ata_pci_sff_init_one(pdev, ppi, &sch_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &sch_sht, NULL, 0);
 }
 
 static int __init sch_init(void)
index 43ea389..86dd714 100644 (file)
@@ -460,7 +460,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
        if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
                ata_pci_bmdma_clear_simplex(pdev);
 
-       return ata_pci_sff_init_one(pdev, ppi, &serverworks_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &serverworks_sht, NULL, 0);
 }
 
 #ifdef CONFIG_PM
index 43faf10..d3190d7 100644 (file)
@@ -374,11 +374,11 @@ static int __devinit sil680_init_one(struct pci_dev *pdev,
        ata_sff_std_ports(&host->ports[1]->ioaddr);
 
        /* Register & activate */
-       return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+       return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
                                 IRQF_SHARED, &sil680_sht);
 
 use_ioports:
-       return ata_pci_sff_init_one(pdev, ppi, &sil680_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &sil680_sht, NULL, 0);
 }
 
 #ifdef CONFIG_PM
index b670803..60cea13 100644 (file)
@@ -826,7 +826,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 
        sis_fixup(pdev, chipset);
 
-       return ata_pci_sff_init_one(pdev, ppi, &sis_sht, chipset, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &sis_sht, chipset, 0);
 }
 
 #ifdef CONFIG_PM
index 733b042..98548f6 100644 (file)
@@ -316,7 +316,7 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id
        val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
        pci_write_config_dword(dev, 0x40, val);
 
-       return ata_pci_sff_init_one(dev, ppi, &sl82c105_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(dev, ppi, &sl82c105_sht, NULL, 0);
 }
 
 static const struct pci_device_id sl82c105[] = {
index 48f5060..0d1f89e 100644 (file)
@@ -201,7 +201,7 @@ static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");
 
-       return ata_pci_sff_init_one(dev, ppi, &triflex_sht, NULL, 0);
+       return ata_pci_bmdma_init_one(dev, ppi, &triflex_sht, NULL, 0);
 }
 
 static const struct pci_device_id triflex[] = {
index 7e3e0a5..5e65988 100644 (file)
@@ -627,7 +627,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        }
 
        /* We have established the device type, now fire it up */
-       return ata_pci_sff_init_one(pdev, ppi, &via_sht, (void *)config, 0);
+       return ata_pci_bmdma_init_one(pdev, ppi, &via_sht, (void *)config, 0);
 }
 
 #ifdef CONFIG_PM
index f3471bc..a476cd9 100644 (file)
@@ -675,8 +675,6 @@ static struct ata_port_operations mv5_ops = {
        .freeze                 = mv_eh_freeze,
        .thaw                   = mv_eh_thaw,
        .hardreset              = mv_hardreset,
-       .error_handler          = ata_std_error_handler, /* avoid SFF EH */
-       .post_internal_cmd      = ATA_OP_NULL,
 
        .scr_read               = mv5_scr_read,
        .scr_write              = mv5_scr_write,
@@ -2813,7 +2811,7 @@ static void mv_port_intr(struct ata_port *ap, u32 port_cause)
        } else if (!edma_was_enabled) {
                struct ata_queued_cmd *qc = mv_get_active_qc(ap);
                if (qc)
-                       ata_sff_host_intr(ap, qc);
+                       ata_bmdma_port_intr(ap, qc);
                else
                        mv_unexpected_intr(ap, edma_was_enabled);
        }
index baa8f0d..6fd1147 100644 (file)
@@ -920,7 +920,7 @@ static int nv_host_intr(struct ata_port *ap, u8 irq_stat)
        }
 
        /* handle interrupt */
-       return ata_sff_host_intr(ap, qc);
+       return ata_bmdma_port_intr(ap, qc);
 }
 
 static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
@@ -1100,7 +1100,7 @@ static void nv_adma_irq_clear(struct ata_port *ap)
        u32 notifier_clears[2];
 
        if (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) {
-               ata_sff_irq_clear(ap);
+               ata_bmdma_irq_clear(ap);
                return;
        }
 
@@ -1505,7 +1505,7 @@ static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance)
 
                qc = ata_qc_from_tag(ap, ap->link.active_tag);
                if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
-                       handled += ata_sff_host_intr(ap, qc);
+                       handled += ata_bmdma_port_intr(ap, qc);
                } else {
                        /*
                         * No request pending?  Clear interrupt status
@@ -2430,7 +2430,7 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        ppi[0] = &nv_port_info[type];
        ipriv = ppi[0]->private_data;
-       rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+       rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
        if (rc)
                return rc;
 
index d533b3d..daeebf1 100644 (file)
@@ -120,8 +120,6 @@ static void qs_host_stop(struct ata_host *host);
 static void qs_qc_prep(struct ata_queued_cmd *qc);
 static unsigned int qs_qc_issue(struct ata_queued_cmd *qc);
 static int qs_check_atapi_dma(struct ata_queued_cmd *qc);
-static void qs_bmdma_stop(struct ata_queued_cmd *qc);
-static u8 qs_bmdma_status(struct ata_port *ap);
 static void qs_freeze(struct ata_port *ap);
 static void qs_thaw(struct ata_port *ap);
 static int qs_prereset(struct ata_link *link, unsigned long deadline);
@@ -137,8 +135,6 @@ static struct ata_port_operations qs_ata_ops = {
        .inherits               = &ata_sff_port_ops,
 
        .check_atapi_dma        = qs_check_atapi_dma,
-       .bmdma_stop             = qs_bmdma_stop,
-       .bmdma_status           = qs_bmdma_status,
        .qc_prep                = qs_qc_prep,
        .qc_issue               = qs_qc_issue,
 
@@ -190,16 +186,6 @@ static int qs_check_atapi_dma(struct ata_queued_cmd *qc)
        return 1;       /* ATAPI DMA not supported */
 }
 
-static void qs_bmdma_stop(struct ata_queued_cmd *qc)
-{
-       /* nothing */
-}
-
-static u8 qs_bmdma_status(struct ata_port *ap)
-{
-       return 0;
-}
-
 static inline void qs_enter_reg_mode(struct ata_port *ap)
 {
        u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000);
@@ -454,7 +440,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host)
                if (!pp || pp->state != qs_state_mmio)
                        continue;
                if (!(qc->tf.flags & ATA_TFLAG_POLLING))
-                       handled |= ata_sff_host_intr(ap, qc);
+                       handled |= ata_sff_port_intr(ap, qc);
        }
        return handled;
 }
index 2dda312..3a4f842 100644 (file)
@@ -503,7 +503,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
                goto err_hsm;
 
        /* ack bmdma irq events */
-       ata_sff_irq_clear(ap);
+       ata_bmdma_irq_clear(ap);
 
        /* kick HSM in the ass */
        ata_sff_hsm_move(ap, qc, status, 0);
@@ -584,7 +584,7 @@ static void sil_thaw(struct ata_port *ap)
 
        /* clear IRQ */
        ap->ops->sff_check_status(ap);
-       ata_sff_irq_clear(ap);
+       ata_bmdma_irq_clear(ap);
 
        /* turn on SATA IRQ if supported */
        if (!(ap->flags & SIL_FLAG_NO_SATA_IRQ))
index f8a91bf..2bfe3ae 100644 (file)
@@ -279,7 +279,7 @@ static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                break;
        }
 
-       rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+       rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
        if (rc)
                return rc;
 
@@ -308,7 +308,7 @@ static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        pci_set_master(pdev);
        pci_intx(pdev, 1);
-       return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+       return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
                                 IRQF_SHARED, &sis_sht);
 }
 
index 101fd6a..7d9db4a 100644 (file)
@@ -502,7 +502,7 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
        writel(0x0, mmio_base + K2_SATA_SIM_OFFSET);
 
        pci_set_master(pdev);
-       return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+       return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
                                 IRQF_SHARED, &k2_sata_sht);
 }
 
index d8dac17..b8578c3 100644 (file)
@@ -242,7 +242,7 @@ static int uli_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        pci_set_master(pdev);
        pci_intx(pdev, 1);
-       return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+       return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
                                 IRQF_SHARED, &uli_sht);
 }
 
index 08f6549..101d8c2 100644 (file)
@@ -308,7 +308,7 @@ static void svia_noop_freeze(struct ata_port *ap)
         * certain way.  Leave it alone and just clear pending IRQ.
         */
        ap->ops->sff_check_status(ap);
-       ata_sff_irq_clear(ap);
+       ata_bmdma_irq_clear(ap);
 }
 
 /**
@@ -463,7 +463,7 @@ static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
        struct ata_host *host;
        int rc;
 
-       rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+       rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
        if (rc)
                return rc;
        *r_host = host;
@@ -520,7 +520,7 @@ static int vt8251_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
        struct ata_host *host;
        int i, rc;
 
-       rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+       rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
        if (rc)
                return rc;
        *r_host = host;
@@ -628,7 +628,7 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        svia_configure(pdev);
 
        pci_set_master(pdev);
-       return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+       return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
                                 IRQF_SHARED, &svia_sht);
 }
 
index 2107952..b777176 100644 (file)
@@ -245,7 +245,7 @@ static void vsc_port_intr(u8 port_status, struct ata_port *ap)
 
        qc = ata_qc_from_tag(ap, ap->link.active_tag);
        if (qc && likely(!(qc->tf.flags & ATA_TFLAG_POLLING)))
-               handled = ata_sff_host_intr(ap, qc);
+               handled = ata_bmdma_port_intr(ap, qc);
 
        /* We received an interrupt during a polled command,
         * or some other spurious condition.  Interrupt reporting
index 606048b..85c004a 100644 (file)
@@ -305,8 +305,7 @@ static int ps3flash_flush(struct file *file, fl_owner_t id)
        return ps3flash_writeback(ps3flash_dev);
 }
 
-static int ps3flash_fsync(struct file *file, struct dentry *dentry,
-                         int datasync)
+static int ps3flash_fsync(struct file *file, int datasync)
 {
        return ps3flash_writeback(ps3flash_dev);
 }
index 72ebb3f..4dfa6b9 100644 (file)
@@ -189,8 +189,7 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin)
        return new_offset;
 }
 
-static int vol_cdev_fsync(struct file *file, struct dentry *dentry,
-                         int datasync)
+static int vol_cdev_fsync(struct file *file, int datasync)
 {
        struct ubi_volume_desc *desc = file->private_data;
        struct ubi_device *ubi = desc->vol->ubi;
index 82eaf65..ea9b7a0 100644 (file)
@@ -551,8 +551,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
        void __iomem *shmem;
 
        if (dev == NULL) {
-               pr_err("%s: net_interrupt(): irq %d for unknown device.\n",
-                       dev->name, irq);
+               pr_err("net_interrupt(): irq %d for unknown device.\n", irq);
                return IRQ_NONE;
        }
 
index c911bfb..9d11dbf 100644 (file)
@@ -294,7 +294,7 @@ int be_cmd_POST(struct be_adapter *adapter)
                } else {
                        return 0;
                }
-       } while (timeout < 20);
+       } while (timeout < 40);
 
        dev_err(&adapter->pdev->dev, "POST timeout; stage=0x%x\n", stage);
        return -1;
index aa065c7..54b1427 100644 (file)
@@ -1861,7 +1861,7 @@ static int be_setup(struct be_adapter *adapter)
                                goto if_destroy;
                        }
                        vf++;
-               } while (vf < num_vfs);
+               }
        } else if (!be_physfn(adapter)) {
                status = be_cmd_mac_addr_query(adapter, mac,
                        MAC_ADDRESS_TYPE_NETWORK, false, adapter->if_handle);
index be90d35..fe92566 100644 (file)
@@ -3367,13 +3367,9 @@ static int cnic_cm_shutdown(struct cnic_dev *dev)
 
 static void cnic_init_context(struct cnic_dev *dev, u32 cid)
 {
-       struct cnic_local *cp = dev->cnic_priv;
        u32 cid_addr;
        int i;
 
-       if (CHIP_NUM(cp) == CHIP_NUM_5709)
-               return;
-
        cid_addr = GET_CID_ADDR(cid);
 
        for (i = 0; i < CTX_SIZE; i += 4)
@@ -3530,14 +3526,11 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev)
 
        sb_id = cp->status_blk_num;
        tx_cid = 20;
-       cnic_init_context(dev, tx_cid);
-       cnic_init_context(dev, tx_cid + 1);
        cp->tx_cons_ptr = &s_blk->status_tx_quick_consumer_index2;
        if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) {
                struct status_block_msix *sblk = cp->status_blk.bnx2;
 
                tx_cid = TX_TSS_CID + sb_id - 1;
-               cnic_init_context(dev, tx_cid);
                CNIC_WR(dev, BNX2_TSCH_TSS_CFG, (sb_id << 24) |
                        (TX_TSS_CID << 7));
                cp->tx_cons_ptr = &sblk->status_tx_quick_consumer_index;
@@ -3556,6 +3549,9 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev)
                offset2 = BNX2_L2CTX_TBDR_BHADDR_HI_XI;
                offset3 = BNX2_L2CTX_TBDR_BHADDR_LO_XI;
        } else {
+               cnic_init_context(dev, tx_cid);
+               cnic_init_context(dev, tx_cid + 1);
+
                offset0 = BNX2_L2CTX_TYPE;
                offset1 = BNX2_L2CTX_CMD_TYPE;
                offset2 = BNX2_L2CTX_TBDR_BHADDR_HI;
index 110c620..0c55177 100644 (file)
@@ -12,8 +12,8 @@
 #ifndef CNIC_IF_H
 #define CNIC_IF_H
 
-#define CNIC_MODULE_VERSION    "2.1.1"
-#define CNIC_MODULE_RELDATE    "Feb 22, 2010"
+#define CNIC_MODULE_VERSION    "2.1.2"
+#define CNIC_MODULE_RELDATE    "May 26, 2010"
 
 #define CNIC_ULP_RDMA          0
 #define CNIC_ULP_ISCSI         1
index 326465f..ddf7a86 100644 (file)
@@ -681,6 +681,8 @@ static int fec_enet_mii_probe(struct net_device *dev)
        struct phy_device *phy_dev = NULL;
        int phy_addr;
 
+       fep->phy_dev = NULL;
+
        /* find the first phy */
        for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
                if (fep->mii_bus->phy_map[phy_addr]) {
@@ -711,6 +713,11 @@ static int fec_enet_mii_probe(struct net_device *dev)
        fep->link = 0;
        fep->full_duplex = 0;
 
+       printk(KERN_INFO "%s: Freescale FEC PHY driver [%s] "
+               "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name,
+               fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev),
+               fep->phy_dev->irq);
+
        return 0;
 }
 
@@ -756,13 +763,8 @@ static int fec_enet_mii_init(struct platform_device *pdev)
        if (mdiobus_register(fep->mii_bus))
                goto err_out_free_mdio_irq;
 
-       if (fec_enet_mii_probe(dev) != 0)
-               goto err_out_unregister_bus;
-
        return 0;
 
-err_out_unregister_bus:
-       mdiobus_unregister(fep->mii_bus);
 err_out_free_mdio_irq:
        kfree(fep->mii_bus->irq);
 err_out_free_mdiobus:
@@ -915,7 +917,12 @@ fec_enet_open(struct net_device *dev)
        if (ret)
                return ret;
 
-       /* schedule a link state check */
+       /* Probe and connect to PHY when open the interface */
+       ret = fec_enet_mii_probe(dev);
+       if (ret) {
+               fec_enet_free_buffers(dev);
+               return ret;
+       }
        phy_start(fep->phy_dev);
        netif_start_queue(dev);
        fep->opened = 1;
@@ -929,10 +936,12 @@ fec_enet_close(struct net_device *dev)
 
        /* Don't know what to do yet. */
        fep->opened = 0;
-       phy_stop(fep->phy_dev);
        netif_stop_queue(dev);
        fec_stop(dev);
 
+       if (fep->phy_dev)
+               phy_disconnect(fep->phy_dev);
+
         fec_enet_free_buffers(dev);
 
        return 0;
@@ -1316,11 +1325,6 @@ fec_probe(struct platform_device *pdev)
        if (ret)
                goto failed_register;
 
-       printk(KERN_INFO "%s: Freescale FEC PHY driver [%s] "
-               "(mii_bus:phy_addr=%s, irq=%d)\n", ndev->name,
-               fep->phy_dev->drv->name, dev_name(&fep->phy_dev->dev),
-               fep->phy_dev->irq);
-
        return 0;
 
 failed_register:
index 694132e..4e7d1d0 100644 (file)
@@ -1151,8 +1151,7 @@ static int __init yam_init_driver(void)
                dev = alloc_netdev(sizeof(struct yam_port), name,
                                   yam_setup);
                if (!dev) {
-                       printk(KERN_ERR "yam: cannot allocate net device %s\n",
-                              dev->name);
+                       pr_err("yam: cannot allocate net device\n");
                        err = -ENOMEM;
                        goto error;
                }
index c033584..522abe2 100644 (file)
@@ -295,6 +295,10 @@ This option defaults to enabled (set) */
 
 #define MULTICAST_CAM_TABLE_NUM 4
 
+/* TEMAC Synthesis features */
+#define TEMAC_FEATURE_RX_CSUM  (1 << 0)
+#define TEMAC_FEATURE_TX_CSUM  (1 << 1)
+
 /* TX/RX CURDESC_PTR points to first descriptor */
 /* TX/RX TAILDESC_PTR points to last descriptor in linked list */
 
@@ -353,6 +357,7 @@ struct temac_local {
        struct mutex indirect_mutex;
        u32 options;                    /* Current options word */
        int last_link;
+       unsigned int temac_features;
 
        /* Buffer descriptors */
        struct cdmac_bd *tx_bd_v;
index fa7620e..52dcc84 100644 (file)
@@ -245,7 +245,7 @@ static int temac_dma_bd_init(struct net_device *ndev)
                                          CHNL_CTRL_IRQ_COAL_EN);
        /* 0x10220483 */
        /* 0x00100483 */
-       lp->dma_out(lp, RX_CHNL_CTRL, 0xff010000 |
+       lp->dma_out(lp, RX_CHNL_CTRL, 0xff070000 |
                                          CHNL_CTRL_IRQ_EN |
                                          CHNL_CTRL_IRQ_DLY_EN |
                                          CHNL_CTRL_IRQ_COAL_EN |
@@ -574,6 +574,10 @@ static void temac_start_xmit_done(struct net_device *ndev)
                if (cur_p->app4)
                        dev_kfree_skb_irq((struct sk_buff *)cur_p->app4);
                cur_p->app0 = 0;
+               cur_p->app1 = 0;
+               cur_p->app2 = 0;
+               cur_p->app3 = 0;
+               cur_p->app4 = 0;
 
                ndev->stats.tx_packets++;
                ndev->stats.tx_bytes += cur_p->len;
@@ -589,6 +593,29 @@ static void temac_start_xmit_done(struct net_device *ndev)
        netif_wake_queue(ndev);
 }
 
+static inline int temac_check_tx_bd_space(struct temac_local *lp, int num_frag)
+{
+       struct cdmac_bd *cur_p;
+       int tail;
+
+       tail = lp->tx_bd_tail;
+       cur_p = &lp->tx_bd_v[tail];
+
+       do {
+               if (cur_p->app0)
+                       return NETDEV_TX_BUSY;
+
+               tail++;
+               if (tail >= TX_BD_NUM)
+                       tail = 0;
+
+               cur_p = &lp->tx_bd_v[tail];
+               num_frag--;
+       } while (num_frag >= 0);
+
+       return 0;
+}
+
 static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
        struct temac_local *lp = netdev_priv(ndev);
@@ -603,7 +630,7 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;
        cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
 
-       if (cur_p->app0 & STS_CTRL_APP0_CMPLT) {
+       if (temac_check_tx_bd_space(lp, num_frag)) {
                if (!netif_queue_stopped(ndev)) {
                        netif_stop_queue(ndev);
                        return NETDEV_TX_BUSY;
@@ -613,29 +640,14 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 
        cur_p->app0 = 0;
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
-               const struct iphdr *ip = ip_hdr(skb);
-               int length = 0, start = 0, insert = 0;
-
-               switch (ip->protocol) {
-               case IPPROTO_TCP:
-                       start = sizeof(struct iphdr) + ETH_HLEN;
-                       insert = sizeof(struct iphdr) + ETH_HLEN + 16;
-                       length = ip->tot_len - sizeof(struct iphdr);
-                       break;
-               case IPPROTO_UDP:
-                       start = sizeof(struct iphdr) + ETH_HLEN;
-                       insert = sizeof(struct iphdr) + ETH_HLEN + 6;
-                       length = ip->tot_len - sizeof(struct iphdr);
-                       break;
-               default:
-                       break;
-               }
-               cur_p->app1 = ((start << 16) | insert);
-               cur_p->app2 = csum_tcpudp_magic(ip->saddr, ip->daddr,
-                                               length, ip->protocol, 0);
-               skb->data[insert] = 0;
-               skb->data[insert + 1] = 0;
+               unsigned int csum_start_off = skb_transport_offset(skb);
+               unsigned int csum_index_off = csum_start_off + skb->csum_offset;
+
+               cur_p->app0 |= 1; /* TX Checksum Enabled */
+               cur_p->app1 = (csum_start_off << 16) | csum_index_off;
+               cur_p->app2 = 0;  /* initial checksum seed */
        }
+
        cur_p->app0 |= STS_CTRL_APP0_SOP;
        cur_p->len = skb_headlen(skb);
        cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len,
@@ -699,6 +711,15 @@ static void ll_temac_recv(struct net_device *ndev)
                skb->protocol = eth_type_trans(skb, ndev);
                skb->ip_summed = CHECKSUM_NONE;
 
+               /* if we're doing rx csum offload, set it up */
+               if (((lp->temac_features & TEMAC_FEATURE_RX_CSUM) != 0) &&
+                       (skb->protocol == __constant_htons(ETH_P_IP)) &&
+                       (skb->len > 64)) {
+
+                       skb->csum = cur_p->app3 & 0xFFFF;
+                       skb->ip_summed = CHECKSUM_COMPLETE;
+               }
+
                netif_rx(skb);
 
                ndev->stats.rx_packets++;
@@ -883,6 +904,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match)
        struct temac_local *lp;
        struct net_device *ndev;
        const void *addr;
+       __be32 *p;
        int size, rc = 0;
 
        /* Init network device structure */
@@ -926,6 +948,18 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match)
                goto nodev;
        }
 
+       /* Setup checksum offload, but default to off if not specified */
+       lp->temac_features = 0;
+       p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,txcsum", NULL);
+       if (p && be32_to_cpu(*p)) {
+               lp->temac_features |= TEMAC_FEATURE_TX_CSUM;
+               /* Can checksum TCP/UDP over IPv4. */
+               ndev->features |= NETIF_F_IP_CSUM;
+       }
+       p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,rxcsum", NULL);
+       if (p && be32_to_cpu(*p))
+               lp->temac_features |= TEMAC_FEATURE_RX_CSUM;
+
        /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */
        np = of_parse_phandle(op->dev.of_node, "llink-connected", 0);
        if (!np) {
@@ -950,7 +984,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match)
 
        lp->rx_irq = irq_of_parse_and_map(np, 0);
        lp->tx_irq = irq_of_parse_and_map(np, 1);
-       if (!lp->rx_irq || !lp->tx_irq) {
+       if ((lp->rx_irq == NO_IRQ) || (lp->tx_irq == NO_IRQ)) {
                dev_err(&op->dev, "could not determine irqs\n");
                rc = -ENOMEM;
                goto nodev;
index 8dc0383..4a789e5 100644 (file)
@@ -119,7 +119,7 @@ static int s5p_serial_probe(struct platform_device *pdev)
        return s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]);
 }
 
-static struct platform_driver s5p_serial_drv = {
+static struct platform_driver s5p_serial_driver = {
        .probe          = s5p_serial_probe,
        .remove         = __devexit_p(s3c24xx_serial_remove),
        .driver         = {
@@ -130,19 +130,19 @@ static struct platform_driver s5p_serial_drv = {
 
 static int __init s5pv210_serial_console_init(void)
 {
-       return s3c24xx_serial_initconsole(&s5p_serial_drv, s5p_uart_inf);
+       return s3c24xx_serial_initconsole(&s5p_serial_driver, s5p_uart_inf);
 }
 
 console_initcall(s5pv210_serial_console_init);
 
 static int __init s5p_serial_init(void)
 {
-       return s3c24xx_serial_init(&s5p_serial_drv, *s5p_uart_inf);
+       return s3c24xx_serial_init(&s5p_serial_driver, *s5p_uart_inf);
 }
 
 static void __exit s5p_serial_exit(void)
 {
-       platform_driver_unregister(&s5p_serial_drv);
+       platform_driver_unregister(&s5p_serial_driver);
 }
 
 module_init(s5p_serial_init);
index 9286e86..e92595e 100644 (file)
@@ -880,7 +880,7 @@ static struct inode *pohmelfs_alloc_inode(struct super_block *sb)
 /*
  * We want fsync() to work on POHMELFS.
  */
-static int pohmelfs_fsync(struct file *file, struct dentry *dentry, int datasync)
+static int pohmelfs_fsync(struct file *file, int datasync)
 {
        struct inode *inode = file->f_mapping->host;
        struct writeback_control wbc = {
index 6b8bf8c..43abf55 100644 (file)
@@ -794,7 +794,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
 }
 
 static int
-printer_fsync(struct file *fd, struct dentry *dentry, int datasync)
+printer_fsync(struct file *fd, int datasync)
 {
        struct printer_dev      *dev = fd->private_data;
        unsigned long           flags;
index aa88911..0f41c91 100644 (file)
@@ -593,17 +593,17 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl,
        int r;
        switch (ioctl) {
        case VHOST_NET_SET_BACKEND:
-               r = copy_from_user(&backend, argp, sizeof backend);
-               if (r < 0)
-                       return r;
+               if (copy_from_user(&backend, argp, sizeof backend))
+                       return -EFAULT;
                return vhost_net_set_backend(n, backend.index, backend.fd);
        case VHOST_GET_FEATURES:
                features = VHOST_FEATURES;
-               return copy_to_user(featurep, &features, sizeof features);
+               if (copy_to_user(featurep, &features, sizeof features))
+                       return -EFAULT;
+               return 0;
        case VHOST_SET_FEATURES:
-               r = copy_from_user(&features, featurep, sizeof features);
-               if (r < 0)
-                       return r;
+               if (copy_from_user(&features, featurep, sizeof features))
+                       return -EFAULT;
                if (features & ~VHOST_FEATURES)
                        return -EOPNOTSUPP;
                return vhost_net_set_features(n, features);
index c6fb8e9..3b83382 100644 (file)
@@ -320,10 +320,8 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
 {
        struct vhost_memory mem, *newmem, *oldmem;
        unsigned long size = offsetof(struct vhost_memory, regions);
-       long r;
-       r = copy_from_user(&mem, m, size);
-       if (r)
-               return r;
+       if (copy_from_user(&mem, m, size))
+               return -EFAULT;
        if (mem.padding)
                return -EOPNOTSUPP;
        if (mem.nregions > VHOST_MEMORY_MAX_NREGIONS)
@@ -333,15 +331,16 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m)
                return -ENOMEM;
 
        memcpy(newmem, &mem, size);
-       r = copy_from_user(newmem->regions, m->regions,
-                          mem.nregions * sizeof *m->regions);
-       if (r) {
+       if (copy_from_user(newmem->regions, m->regions,
+                          mem.nregions * sizeof *m->regions)) {
                kfree(newmem);
-               return r;
+               return -EFAULT;
        }
 
-       if (!memory_access_ok(d, newmem, vhost_has_feature(d, VHOST_F_LOG_ALL)))
+       if (!memory_access_ok(d, newmem, vhost_has_feature(d, VHOST_F_LOG_ALL))) {
+               kfree(newmem);
                return -EFAULT;
+       }
        oldmem = d->memory;
        rcu_assign_pointer(d->memory, newmem);
        synchronize_rcu();
@@ -374,7 +373,7 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
        r = get_user(idx, idxp);
        if (r < 0)
                return r;
-       if (idx > d->nvqs)
+       if (idx >= d->nvqs)
                return -ENOBUFS;
 
        vq = d->vqs + idx;
@@ -389,9 +388,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
                        r = -EBUSY;
                        break;
                }
-               r = copy_from_user(&s, argp, sizeof s);
-               if (r < 0)
+               if (copy_from_user(&s, argp, sizeof s)) {
+                       r = -EFAULT;
                        break;
+               }
                if (!s.num || s.num > 0xffff || (s.num & (s.num - 1))) {
                        r = -EINVAL;
                        break;
@@ -405,9 +405,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
                        r = -EBUSY;
                        break;
                }
-               r = copy_from_user(&s, argp, sizeof s);
-               if (r < 0)
+               if (copy_from_user(&s, argp, sizeof s)) {
+                       r = -EFAULT;
                        break;
+               }
                if (s.num > 0xffff) {
                        r = -EINVAL;
                        break;
@@ -419,12 +420,14 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
        case VHOST_GET_VRING_BASE:
                s.index = idx;
                s.num = vq->last_avail_idx;
-               r = copy_to_user(argp, &s, sizeof s);
+               if (copy_to_user(argp, &s, sizeof s))
+                       r = -EFAULT;
                break;
        case VHOST_SET_VRING_ADDR:
-               r = copy_from_user(&a, argp, sizeof a);
-               if (r < 0)
+               if (copy_from_user(&a, argp, sizeof a)) {
+                       r = -EFAULT;
                        break;
+               }
                if (a.flags & ~(0x1 << VHOST_VRING_F_LOG)) {
                        r = -EOPNOTSUPP;
                        break;
@@ -477,9 +480,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
                vq->used = (void __user *)(unsigned long)a.used_user_addr;
                break;
        case VHOST_SET_VRING_KICK:
-               r = copy_from_user(&f, argp, sizeof f);
-               if (r < 0)
+               if (copy_from_user(&f, argp, sizeof f)) {
+                       r = -EFAULT;
                        break;
+               }
                eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd);
                if (IS_ERR(eventfp)) {
                        r = PTR_ERR(eventfp);
@@ -492,9 +496,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
                        filep = eventfp;
                break;
        case VHOST_SET_VRING_CALL:
-               r = copy_from_user(&f, argp, sizeof f);
-               if (r < 0)
+               if (copy_from_user(&f, argp, sizeof f)) {
+                       r = -EFAULT;
                        break;
+               }
                eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd);
                if (IS_ERR(eventfp)) {
                        r = PTR_ERR(eventfp);
@@ -510,9 +515,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp)
                        filep = eventfp;
                break;
        case VHOST_SET_VRING_ERR:
-               r = copy_from_user(&f, argp, sizeof f);
-               if (r < 0)
+               if (copy_from_user(&f, argp, sizeof f)) {
+                       r = -EFAULT;
                        break;
+               }
                eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd);
                if (IS_ERR(eventfp)) {
                        r = PTR_ERR(eventfp);
@@ -575,9 +581,10 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, unsigned long arg)
                r = vhost_set_memory(d, argp);
                break;
        case VHOST_SET_LOG_BASE:
-               r = copy_from_user(&p, argp, sizeof p);
-               if (r < 0)
+               if (copy_from_user(&p, argp, sizeof p)) {
+                       r = -EFAULT;
                        break;
+               }
                if ((u64)(unsigned long)p != p) {
                        r = -EFAULT;
                        break;
index 1105a59..073c9b4 100644 (file)
@@ -66,7 +66,7 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma,
        return 0;
 }
 
-int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync)
+int fb_deferred_io_fsync(struct file *file, int datasync)
 {
        struct fb_info *info = file->private_data;
 
index 25b300e..2bedc6c 100644 (file)
@@ -257,15 +257,13 @@ v9fs_file_write(struct file *filp, const char __user * data,
        return total;
 }
 
-static int v9fs_file_fsync(struct file *filp, struct dentry *dentry,
-                                       int datasync)
+static int v9fs_file_fsync(struct file *filp, int datasync)
 {
        struct p9_fid *fid;
        struct p9_wstat wstat;
        int retval;
 
-       P9_DPRINTK(P9_DEBUG_VFS, "filp %p dentry %p datasync %x\n", filp,
-                                               dentry, datasync);
+       P9_DPRINTK(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync);
 
        fid = filp->private_data;
        v9fs_blank_wstat(&wstat);
index 23aa52f..f4287e4 100644 (file)
@@ -197,7 +197,7 @@ const struct file_operations adfs_dir_operations = {
        .read           = generic_read_dir,
        .llseek         = generic_file_llseek,
        .readdir        = adfs_readdir,
-       .fsync          = simple_fsync,
+       .fsync          = generic_file_fsync,
 };
 
 static int
index 005ea34..a36da53 100644 (file)
@@ -26,7 +26,7 @@ const struct file_operations adfs_file_operations = {
        .read           = do_sync_read,
        .aio_read       = generic_file_aio_read,
        .mmap           = generic_file_mmap,
-       .fsync          = simple_fsync,
+       .fsync          = generic_file_fsync,
        .write          = do_sync_write,
        .aio_write      = generic_file_aio_write,
        .splice_read    = generic_file_splice_read,
index 0f5e309..6f850b0 100644 (file)
@@ -322,8 +322,9 @@ adfs_notify_change(struct dentry *dentry, struct iattr *attr)
        if (error)
                goto out;
 
+       /* XXX: this is missing some actual on-disk truncation.. */
        if (ia_valid & ATTR_SIZE)
-               error = vmtruncate(inode, attr->ia_size);
+               error = simple_setsize(inode, attr->ia_size);
 
        if (error)
                goto out;
index 861dae6..f05b615 100644 (file)
@@ -183,7 +183,7 @@ extern int                   affs_add_entry(struct inode *dir, struct inode *inode, struct dent
 
 void           affs_free_prealloc(struct inode *inode);
 extern void    affs_truncate(struct inode *);
-int            affs_file_fsync(struct file *, struct dentry *, int);
+int            affs_file_fsync(struct file *, int);
 
 /* dir.c */
 
index 184e55c..322710c 100644 (file)
@@ -916,9 +916,9 @@ affs_truncate(struct inode *inode)
        affs_free_prealloc(inode);
 }
 
-int affs_file_fsync(struct file *filp, struct dentry *dentry, int datasync)
+int affs_file_fsync(struct file *filp, int datasync)
 {
-       struct inode * inode = dentry->d_inode;
+       struct inode *inode = filp->f_mapping->host;
        int ret, err;
 
        ret = write_inode_now(inode, 0);
index 807f284..5f679b7 100644 (file)
@@ -740,7 +740,7 @@ extern void afs_pages_written_back(struct afs_vnode *, struct afs_call *);
 extern ssize_t afs_file_write(struct kiocb *, const struct iovec *,
                              unsigned long, loff_t);
 extern int afs_writeback_all(struct afs_vnode *);
-extern int afs_fsync(struct file *, struct dentry *, int);
+extern int afs_fsync(struct file *, int);
 
 
 /*****************************************************************************/
index 3bed54a..3dab9e9 100644 (file)
@@ -701,8 +701,9 @@ int afs_writeback_all(struct afs_vnode *vnode)
  * - the return status from this call provides a reliable indication of
  *   whether any write errors occurred for this process.
  */
-int afs_fsync(struct file *file, struct dentry *dentry, int datasync)
+int afs_fsync(struct file *file, int datasync)
 {
+       struct dentry *dentry = file->f_path.dentry;
        struct afs_writeback *wb, *xwb;
        struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode);
        int ret;
index 48fdeeb..1ccf25c 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -527,7 +527,7 @@ static void aio_fput_routine(struct work_struct *data)
 
                /* Complete the fput(s) */
                if (req->ki_filp != NULL)
-                       __fput(req->ki_filp);
+                       fput(req->ki_filp);
 
                /* Link the iocb into the context's free list */
                spin_lock_irq(&ctx->ctx_lock);
@@ -560,11 +560,11 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req)
 
        /*
         * Try to optimize the aio and eventfd file* puts, by avoiding to
-        * schedule work in case it is not __fput() time. In normal cases,
+        * schedule work in case it is not final fput() time. In normal cases,
         * we would not be holding the last reference to the file*, so
         * this function will be executed w/out any aio kthread wakeup.
         */
-       if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) {
+       if (unlikely(!fput_atomic(req->ki_filp))) {
                get_ioctx(ctx);
                spin_lock(&fput_lock);
                list_add(&req->ki_list, &fput_head);
index 9bd4b38..e4b75d6 100644 (file)
@@ -205,7 +205,7 @@ static struct inode *anon_inode_mkinode(void)
         * that it already _is_ on the dirty list.
         */
        inode->i_state = I_DIRTY;
-       inode->i_mode = S_IFREG | S_IRUSR | S_IWUSR;
+       inode->i_mode = S_IRUSR | S_IWUSR;
        inode->i_uid = current_fsuid();
        inode->i_gid = current_fsgid();
        inode->i_flags |= S_PRIVATE;
index 0815e93..b4fa3b0 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -67,14 +67,14 @@ EXPORT_SYMBOL(inode_change_ok);
  * @offset:    the new size to assign to the inode
  * @Returns:   0 on success, -ve errno on failure
  *
+ * inode_newsize_ok must be called with i_mutex held.
+ *
  * inode_newsize_ok will check filesystem limits and ulimits to check that the
  * new inode size is within limits. inode_newsize_ok will also send SIGXFSZ
  * when necessary. Caller must not proceed with inode size change if failure is
  * returned. @inode must be a file (not directory), with appropriate
  * permissions to allow truncate (inode_newsize_ok does NOT check these
  * conditions).
- *
- * inode_newsize_ok must be called with i_mutex held.
  */
 int inode_newsize_ok(const struct inode *inode, loff_t offset)
 {
@@ -104,17 +104,25 @@ out_big:
 }
 EXPORT_SYMBOL(inode_newsize_ok);
 
-int inode_setattr(struct inode * inode, struct iattr * attr)
+/**
+ * generic_setattr - copy simple metadata updates into the generic inode
+ * @inode:     the inode to be updated
+ * @attr:      the new attributes
+ *
+ * generic_setattr must be called with i_mutex held.
+ *
+ * generic_setattr updates the inode's metadata with that specified
+ * in attr. Noticably missing is inode size update, which is more complex
+ * as it requires pagecache updates. See simple_setsize.
+ *
+ * The inode is not marked as dirty after this operation. The rationale is
+ * that for "simple" filesystems, the struct inode is the inode storage.
+ * The caller is free to mark the inode dirty afterwards if needed.
+ */
+void generic_setattr(struct inode *inode, const struct iattr *attr)
 {
        unsigned int ia_valid = attr->ia_valid;
 
-       if (ia_valid & ATTR_SIZE &&
-           attr->ia_size != i_size_read(inode)) {
-               int error = vmtruncate(inode, attr->ia_size);
-               if (error)
-                       return error;
-       }
-
        if (ia_valid & ATTR_UID)
                inode->i_uid = attr->ia_uid;
        if (ia_valid & ATTR_GID)
@@ -135,6 +143,28 @@ int inode_setattr(struct inode * inode, struct iattr * attr)
                        mode &= ~S_ISGID;
                inode->i_mode = mode;
        }
+}
+EXPORT_SYMBOL(generic_setattr);
+
+/*
+ * note this function is deprecated, the new truncate sequence should be
+ * used instead -- see eg. simple_setsize, generic_setattr.
+ */
+int inode_setattr(struct inode *inode, const struct iattr *attr)
+{
+       unsigned int ia_valid = attr->ia_valid;
+
+       if (ia_valid & ATTR_SIZE &&
+           attr->ia_size != i_size_read(inode)) {
+               int error;
+
+               error = vmtruncate(inode, attr->ia_size);
+               if (error)
+                       return error;
+       }
+
+       generic_setattr(inode, attr);
+
        mark_inode_dirty(inode);
 
        return 0;
index a05287a..52e59bf 100644 (file)
@@ -93,8 +93,7 @@ static int bad_file_release(struct inode *inode, struct file *filp)
        return -EIO;
 }
 
-static int bad_file_fsync(struct file *file, struct dentry *dentry,
-                       int datasync)
+static int bad_file_fsync(struct file *file, int datasync)
 {
        return -EIO;
 }
index 8f73841..d967e05 100644 (file)
@@ -78,7 +78,7 @@ static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir)
 const struct file_operations bfs_dir_operations = {
        .read           = generic_read_dir,
        .readdir        = bfs_readdir,
-       .fsync          = simple_fsync,
+       .fsync          = generic_file_fsync,
        .llseek         = generic_file_llseek,
 };
 
index 26e5f50..7346c96 100644 (file)
@@ -172,8 +172,9 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
        struct file *file = iocb->ki_filp;
        struct inode *inode = file->f_mapping->host;
 
-       return blockdev_direct_IO_no_locking(rw, iocb, inode, I_BDEV(inode),
-                               iov, offset, nr_segs, blkdev_get_blocks, NULL);
+       return blockdev_direct_IO_no_locking_newtrunc(rw, iocb, inode,
+                               I_BDEV(inode), iov, offset, nr_segs,
+                               blkdev_get_blocks, NULL);
 }
 
 int __sync_blockdev(struct block_device *bdev, int wait)
@@ -309,8 +310,8 @@ static int blkdev_write_begin(struct file *file, struct address_space *mapping,
                        struct page **pagep, void **fsdata)
 {
        *pagep = NULL;
-       return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
-                               blkdev_get_block);
+       return block_write_begin_newtrunc(file, mapping, pos, len, flags,
+                               pagep, fsdata, blkdev_get_block);
 }
 
 static int blkdev_write_end(struct file *file, struct address_space *mapping,
@@ -358,12 +359,7 @@ static loff_t block_llseek(struct file *file, loff_t offset, int origin)
        return retval;
 }
        
-/*
- *     Filp is never NULL; the only case when ->fsync() is called with
- *     NULL first argument is nfsd_sync_dir() and that's not a directory.
- */
-int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync)
+int blkdev_fsync(struct file *filp, int datasync)
 {
        struct inode *bd_inode = filp->f_mapping->host;
        struct block_device *bdev = I_BDEV(bd_inode);
index e9bf864..29c2009 100644 (file)
@@ -2434,7 +2434,7 @@ void btrfs_update_iflags(struct inode *inode);
 void btrfs_inherit_iflags(struct inode *inode, struct inode *dir);
 
 /* file.c */
-int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync);
+int btrfs_sync_file(struct file *file, int datasync);
 int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
                            int skip_pinned);
 int btrfs_check_file(struct btrfs_root *root, struct inode *inode);
index 79437c5..787b50a 100644 (file)
@@ -1101,8 +1101,9 @@ int btrfs_release_file(struct inode *inode, struct file *filp)
  * important optimization for directories because holding the mutex prevents
  * new operations on the dir while we write to disk.
  */
-int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
+int btrfs_sync_file(struct file *file, int datasync)
 {
+       struct dentry *dentry = file->f_path.dentry;
        struct inode *inode = dentry->d_inode;
        struct btrfs_root *root = BTRFS_I(inode)->root;
        int ret = 0;
index e8aa708..d54812b 100644 (file)
@@ -1949,14 +1949,11 @@ static int __block_commit_write(struct inode *inode, struct page *page,
 }
 
 /*
- * block_write_begin takes care of the basic task of block allocation and
- * bringing partial write blocks uptodate first.
- *
- * If *pagep is not NULL, then block_write_begin uses the locked page
- * at *pagep rather than allocating its own. In this case, the page will
- * not be unlocked or deallocated on failure.
+ * Filesystems implementing the new truncate sequence should use the
+ * _newtrunc postfix variant which won't incorrectly call vmtruncate.
+ * The filesystem needs to handle block truncation upon failure.
  */
-int block_write_begin(struct file *file, struct address_space *mapping,
+int block_write_begin_newtrunc(struct file *file, struct address_space *mapping,
                        loff_t pos, unsigned len, unsigned flags,
                        struct page **pagep, void **fsdata,
                        get_block_t *get_block)
@@ -1992,20 +1989,50 @@ int block_write_begin(struct file *file, struct address_space *mapping,
                        unlock_page(page);
                        page_cache_release(page);
                        *pagep = NULL;
-
-                       /*
-                        * prepare_write() may have instantiated a few blocks
-                        * outside i_size.  Trim these off again. Don't need
-                        * i_size_read because we hold i_mutex.
-                        */
-                       if (pos + len > inode->i_size)
-                               vmtruncate(inode, inode->i_size);
                }
        }
 
 out:
        return status;
 }
+EXPORT_SYMBOL(block_write_begin_newtrunc);
+
+/*
+ * block_write_begin takes care of the basic task of block allocation and
+ * bringing partial write blocks uptodate first.
+ *
+ * If *pagep is not NULL, then block_write_begin uses the locked page
+ * at *pagep rather than allocating its own. In this case, the page will
+ * not be unlocked or deallocated on failure.
+ */
+int block_write_begin(struct file *file, struct address_space *mapping,
+                       loff_t pos, unsigned len, unsigned flags,
+                       struct page **pagep, void **fsdata,
+                       get_block_t *get_block)
+{
+       int ret;
+
+       ret = block_write_begin_newtrunc(file, mapping, pos, len, flags,
+                                       pagep, fsdata, get_block);
+
+       /*
+        * prepare_write() may have instantiated a few blocks
+        * outside i_size.  Trim these off again. Don't need
+        * i_size_read because we hold i_mutex.
+        *
+        * Filesystems which pass down their own page also cannot
+        * call into vmtruncate here because it would lead to lock
+        * inversion problems (*pagep is locked). This is a further
+        * example of where the old truncate sequence is inadequate.
+        */
+       if (unlikely(ret) && *pagep == NULL) {
+               loff_t isize = mapping->host->i_size;
+               if (pos + len > isize)
+                       vmtruncate(mapping->host, isize);
+       }
+
+       return ret;
+}
 EXPORT_SYMBOL(block_write_begin);
 
 int block_write_end(struct file *file, struct address_space *mapping,
@@ -2324,7 +2351,7 @@ out:
  * For moronic filesystems that do not allow holes in file.
  * We may have to extend the file.
  */
-int cont_write_begin(struct file *file, struct address_space *mapping,
+int cont_write_begin_newtrunc(struct file *file, struct address_space *mapping,
                        loff_t pos, unsigned len, unsigned flags,
                        struct page **pagep, void **fsdata,
                        get_block_t *get_block, loff_t *bytes)
@@ -2345,11 +2372,30 @@ int cont_write_begin(struct file *file, struct address_space *mapping,
        }
 
        *pagep = NULL;
-       err = block_write_begin(file, mapping, pos, len,
+       err = block_write_begin_newtrunc(file, mapping, pos, len,
                                flags, pagep, fsdata, get_block);
 out:
        return err;
 }
+EXPORT_SYMBOL(cont_write_begin_newtrunc);
+
+int cont_write_begin(struct file *file, struct address_space *mapping,
+                       loff_t pos, unsigned len, unsigned flags,
+                       struct page **pagep, void **fsdata,
+                       get_block_t *get_block, loff_t *bytes)
+{
+       int ret;
+
+       ret = cont_write_begin_newtrunc(file, mapping, pos, len, flags,
+                                       pagep, fsdata, get_block, bytes);
+       if (unlikely(ret)) {
+               loff_t isize = mapping->host->i_size;
+               if (pos + len > isize)
+                       vmtruncate(mapping->host, isize);
+       }
+
+       return ret;
+}
 EXPORT_SYMBOL(cont_write_begin);
 
 int block_prepare_write(struct page *page, unsigned from, unsigned to,
@@ -2381,7 +2427,7 @@ EXPORT_SYMBOL(block_commit_write);
  *
  * We are not allowed to take the i_mutex here so we have to play games to
  * protect against truncate races as the page could now be beyond EOF.  Because
- * vmtruncate() writes the inode size before removing pages, once we have the
+ * truncate writes the inode size before removing pages, once we have the
  * page lock we can determine safely if the page is beyond EOF. If it is not
  * beyond EOF, then the page is guaranteed safe against truncation until we
  * unlock the page.
@@ -2464,10 +2510,11 @@ static void attach_nobh_buffers(struct page *page, struct buffer_head *head)
 }
 
 /*
- * On entry, the page is fully not uptodate.
- * On exit the page is fully uptodate in the areas outside (from,to)
+ * Filesystems implementing the new truncate sequence should use the
+ * _newtrunc postfix variant which won't incorrectly call vmtruncate.
+ * The filesystem needs to handle block truncation upon failure.
  */
-int nobh_write_begin(struct file *file, struct address_space *mapping,
+int nobh_write_begin_newtrunc(struct file *file, struct address_space *mapping,
                        loff_t pos, unsigned len, unsigned flags,
                        struct page **pagep, void **fsdata,
                        get_block_t *get_block)
@@ -2500,8 +2547,8 @@ int nobh_write_begin(struct file *file, struct address_space *mapping,
                unlock_page(page);
                page_cache_release(page);
                *pagep = NULL;
-               return block_write_begin(file, mapping, pos, len, flags, pagep,
-                                       fsdata, get_block);
+               return block_write_begin_newtrunc(file, mapping, pos, len,
+                                       flags, pagep, fsdata, get_block);
        }
 
        if (PageMappedToDisk(page))
@@ -2605,8 +2652,34 @@ out_release:
        page_cache_release(page);
        *pagep = NULL;
 
-       if (pos + len > inode->i_size)
-               vmtruncate(inode, inode->i_size);
+       return ret;
+}
+EXPORT_SYMBOL(nobh_write_begin_newtrunc);
+
+/*
+ * On entry, the page is fully not uptodate.
+ * On exit the page is fully uptodate in the areas outside (from,to)
+ */
+int nobh_write_begin(struct file *file, struct address_space *mapping,
+                       loff_t pos, unsigned len, unsigned flags,
+                       struct page **pagep, void **fsdata,
+                       get_block_t *get_block)
+{
+       int ret;
+
+       ret = nobh_write_begin_newtrunc(file, mapping, pos, len, flags,
+                                       pagep, fsdata, get_block);
+
+       /*
+        * prepare_write() may have instantiated a few blocks
+        * outside i_size.  Trim these off again. Don't need
+        * i_size_read because we hold i_mutex.
+        */
+       if (unlikely(ret)) {
+               loff_t isize = mapping->host->i_size;
+               if (pos + len > isize)
+                       vmtruncate(mapping->host, isize);
+       }
 
        return ret;
 }
index 0dd0b81..ae3e3a3 100644 (file)
@@ -1776,9 +1776,9 @@ out:
        spin_unlock(&ci->i_unsafe_lock);
 }
 
-int ceph_fsync(struct file *file, struct dentry *dentry, int datasync)
+int ceph_fsync(struct file *file, int datasync)
 {
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = file->f_mapping->host;
        struct ceph_inode_info *ci = ceph_inode(inode);
        unsigned flush_tid;
        int ret;
index 4fd3090..0057f4a 100644 (file)
@@ -1107,10 +1107,9 @@ static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size,
  * an fsync() on a dir will wait for any uncommitted directory
  * operations to commit.
  */
-static int ceph_dir_fsync(struct file *file, struct dentry *dentry,
-                         int datasync)
+static int ceph_dir_fsync(struct file *file, int datasync)
 {
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = file->f_path.dentry->d_inode;
        struct ceph_inode_info *ci = ceph_inode(inode);
        struct list_head *head = &ci->i_unsafe_dirops;
        struct ceph_mds_request *req;
index 3725c9e..dd1e7ad 100644 (file)
@@ -811,7 +811,7 @@ extern void ceph_put_cap(struct ceph_cap *cap);
 
 extern void ceph_queue_caps_release(struct inode *inode);
 extern int ceph_write_inode(struct inode *inode, struct writeback_control *wbc);
-extern int ceph_fsync(struct file *file, struct dentry *dentry, int datasync);
+extern int ceph_fsync(struct file *file, int datasync);
 extern void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,
                                    struct ceph_mds_session *session);
 extern int ceph_get_cap_mds(struct inode *inode);
index 0242ff9..a7eb65c 100644 (file)
@@ -84,7 +84,7 @@ extern ssize_t cifs_user_read(struct file *file, char __user *read_data,
 extern ssize_t cifs_user_write(struct file *file, const char __user *write_data,
                         size_t write_size, loff_t *poffset);
 extern int cifs_lock(struct file *, int, struct file_lock *);
-extern int cifs_fsync(struct file *, struct dentry *, int);
+extern int cifs_fsync(struct file *, int);
 extern int cifs_flush(struct file *, fl_owner_t id);
 extern int cifs_file_mmap(struct file * , struct vm_area_struct *);
 extern const struct file_operations cifs_dir_ops;
index a83541e..f1ff785 100644 (file)
@@ -1676,7 +1676,7 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
        return rc;
 }
 
-int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
+int cifs_fsync(struct file *file, int datasync)
 {
        int xid;
        int rc = 0;
@@ -1688,7 +1688,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
        xid = GetXid();
 
        cFYI(1, "Sync file - name: %s datasync: 0x%x",
-               dentry->d_name.name, datasync);
+               file->f_path.dentry->d_name.name, datasync);
 
        rc = filemap_write_and_wait(inode->i_mapping);
        if (rc == 0) {
index d99860a..6b443ff 100644 (file)
@@ -11,8 +11,7 @@ extern int coda_fake_statfs;
 
 void coda_destroy_inodecache(void);
 int coda_init_inodecache(void);
-int coda_fsync(struct file *coda_file, struct dentry *coda_dentry,
-              int datasync);
+int coda_fsync(struct file *coda_file, int datasync);
 void coda_sysctl_init(void);
 void coda_sysctl_clean(void);
 
index 7196077..ad3cd2a 100644 (file)
@@ -202,10 +202,10 @@ int coda_release(struct inode *coda_inode, struct file *coda_file)
        return 0;
 }
 
-int coda_fsync(struct file *coda_file, struct dentry *coda_dentry, int datasync)
+int coda_fsync(struct file *coda_file, int datasync)
 {
        struct file *host_file;
-       struct inode *coda_inode = coda_dentry->d_inode;
+       struct inode *coda_inode = coda_file->f_path.dentry->d_inode;
        struct coda_file_info *cfi;
        int err = 0;
 
index c8af2d9..4164514 100644 (file)
@@ -72,16 +72,11 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr)
        if (!sd)
                return -EINVAL;
 
-       sd_iattr = sd->s_iattr;
-
-       error = inode_change_ok(inode, iattr);
-       if (error)
-               return error;
-
-       error = inode_setattr(inode, iattr);
+       error = simple_setattr(dentry, iattr);
        if (error)
                return error;
 
+       sd_iattr = sd->s_iattr;
        if (!sd_iattr) {
                /* setting attributes for the first time, allocate now */
                sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL);
index da111aa..7600aac 100644 (file)
@@ -1134,27 +1134,8 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
        return ret;
 }
 
-/*
- * This is a library function for use by filesystem drivers.
- *
- * The locking rules are governed by the flags parameter:
- *  - if the flags value contains DIO_LOCKING we use a fancy locking
- *    scheme for dumb filesystems.
- *    For writes this function is called under i_mutex and returns with
- *    i_mutex held, for reads, i_mutex is not held on entry, but it is
- *    taken and dropped again before returning.
- *    For reads and writes i_alloc_sem is taken in shared mode and released
- *    on I/O completion (which may happen asynchronously after returning to
- *    the caller).
- *
- *  - if the flags value does NOT contain DIO_LOCKING we don't use any
- *    internal locking but rather rely on the filesystem to synchronize
- *    direct I/O reads/writes versus each other and truncate.
- *    For reads and writes both i_mutex and i_alloc_sem are not held on
- *    entry and are never taken.
- */
 ssize_t
-__blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
+__blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb, struct inode *inode,
        struct block_device *bdev, const struct iovec *iov, loff_t offset, 
        unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
        dio_submit_t submit_io, int flags)
@@ -1247,9 +1228,46 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
                                nr_segs, blkbits, get_block, end_io,
                                submit_io, dio);
 
+out:
+       return retval;
+}
+EXPORT_SYMBOL(__blockdev_direct_IO_newtrunc);
+
+/*
+ * This is a library function for use by filesystem drivers.
+ *
+ * The locking rules are governed by the flags parameter:
+ *  - if the flags value contains DIO_LOCKING we use a fancy locking
+ *    scheme for dumb filesystems.
+ *    For writes this function is called under i_mutex and returns with
+ *    i_mutex held, for reads, i_mutex is not held on entry, but it is
+ *    taken and dropped again before returning.
+ *    For reads and writes i_alloc_sem is taken in shared mode and released
+ *    on I/O completion (which may happen asynchronously after returning to
+ *    the caller).
+ *
+ *  - if the flags value does NOT contain DIO_LOCKING we don't use any
+ *    internal locking but rather rely on the filesystem to synchronize
+ *    direct I/O reads/writes versus each other and truncate.
+ *    For reads and writes both i_mutex and i_alloc_sem are not held on
+ *    entry and are never taken.
+ */
+ssize_t
+__blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
+       struct block_device *bdev, const struct iovec *iov, loff_t offset,
+       unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
+       dio_submit_t submit_io, int flags)
+{
+       ssize_t retval;
+
+       retval = __blockdev_direct_IO_newtrunc(rw, iocb, inode, bdev, iov,
+                       offset, nr_segs, get_block, end_io, submit_io, flags);
        /*
         * In case of error extending write may have instantiated a few
         * blocks outside i_size. Trim these off again for DIO_LOCKING.
+        * NOTE: DIO_NO_LOCK/DIO_OWN_LOCK callers have to handle this in
+        * their own manner. This is a further example of where the old
+        * truncate sequence is inadequate.
         *
         * NOTE: filesystems with their own locking have to handle this
         * on their own.
@@ -1257,12 +1275,13 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
        if (flags & DIO_LOCKING) {
                if (unlikely((rw & WRITE) && retval < 0)) {
                        loff_t isize = i_size_read(inode);
+                       loff_t end = offset + iov_length(iov, nr_segs);
+
                        if (end > isize)
                                vmtruncate(inode, isize);
                }
        }
 
-out:
        return retval;
 }
 EXPORT_SYMBOL(__blockdev_direct_IO);
index 3bdddbc..e8fcf4e 100644 (file)
@@ -274,7 +274,7 @@ static int ecryptfs_release(struct inode *inode, struct file *file)
 }
 
 static int
-ecryptfs_fsync(struct file *file, struct dentry *dentry, int datasync)
+ecryptfs_fsync(struct file *file, int datasync)
 {
        return vfs_fsync(ecryptfs_file_to_lower(file), datasync);
 }
index 65dee2f..31ef525 100644 (file)
@@ -805,7 +805,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
                                    - (ia->ia_size & ~PAGE_CACHE_MASK));
 
                if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
-                       rc = vmtruncate(inode, ia->ia_size);
+                       rc = simple_setsize(inode, ia->ia_size);
                        if (rc)
                                goto out;
                        lower_ia->ia_size = ia->ia_size;
@@ -830,7 +830,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
                                goto out;
                        }
                }
-               vmtruncate(inode, ia->ia_size);
+               simple_setsize(inode, ia->ia_size);
                rc = ecryptfs_write_inode_size_to_metadata(inode);
                if (rc) {
                        printk(KERN_ERR "Problem with "
index 839b9dc..fef6899 100644 (file)
@@ -40,12 +40,11 @@ static int exofs_release_file(struct inode *inode, struct file *filp)
        return 0;
 }
 
-static int exofs_file_fsync(struct file *filp, struct dentry *dentry,
-                           int datasync)
+static int exofs_file_fsync(struct file *filp, int datasync)
 {
        int ret;
        struct address_space *mapping = filp->f_mapping;
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = mapping->host;
        struct super_block *sb;
 
        ret = filemap_write_and_wait(mapping);
@@ -66,7 +65,7 @@ static int exofs_file_fsync(struct file *filp, struct dentry *dentry,
 
 static int exofs_flush(struct file *file, fl_owner_t id)
 {
-       exofs_file_fsync(file, file->f_path.dentry, 1);
+       exofs_file_fsync(file, 1);
        /* TODO: Flush the OSD target */
        return 0;
 }
index 0b038e4..52b34f1 100644 (file)
@@ -122,7 +122,6 @@ extern int ext2_write_inode (struct inode *, struct writeback_control *);
 extern void ext2_delete_inode (struct inode *);
 extern int ext2_sync_inode (struct inode *);
 extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int);
-extern void ext2_truncate (struct inode *);
 extern int ext2_setattr (struct dentry *, struct iattr *);
 extern void ext2_set_inode_flags(struct inode *inode);
 extern void ext2_get_inode_flags(struct ext2_inode_info *);
@@ -155,7 +154,7 @@ extern void ext2_write_super (struct super_block *);
 extern const struct file_operations ext2_dir_operations;
 
 /* file.c */
-extern int ext2_fsync(struct file *file, struct dentry *dentry, int datasync);
+extern int ext2_fsync(struct file *file, int datasync);
 extern const struct inode_operations ext2_file_inode_operations;
 extern const struct file_operations ext2_file_operations;
 extern const struct file_operations ext2_xip_file_operations;
index 5d198d0..49eec94 100644 (file)
@@ -40,13 +40,13 @@ static int ext2_release_file (struct inode * inode, struct file * filp)
        return 0;
 }
 
-int ext2_fsync(struct file *file, struct dentry *dentry, int datasync)
+int ext2_fsync(struct file *file, int datasync)
 {
        int ret;
-       struct super_block *sb = dentry->d_inode->i_sb;
+       struct super_block *sb = file->f_mapping->host->i_sb;
        struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
 
-       ret = simple_fsync(file, dentry, datasync);
+       ret = generic_file_fsync(file, datasync);
        if (ret == -EIO || test_and_clear_bit(AS_EIO, &mapping->flags)) {
                /* We don't really know where the IO error happened... */
                ext2_error(sb, __func__,
@@ -95,7 +95,6 @@ const struct file_operations ext2_xip_file_operations = {
 #endif
 
 const struct inode_operations ext2_file_inode_operations = {
-       .truncate       = ext2_truncate,
 #ifdef CONFIG_EXT2_FS_XATTR
        .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
index 527c46d..1921443 100644 (file)
@@ -54,6 +54,18 @@ static inline int ext2_inode_is_fast_symlink(struct inode *inode)
                inode->i_blocks - ea_blocks == 0);
 }
 
+static void ext2_truncate_blocks(struct inode *inode, loff_t offset);
+
+static void ext2_write_failed(struct address_space *mapping, loff_t to)
+{
+       struct inode *inode = mapping->host;
+
+       if (to > inode->i_size) {
+               truncate_pagecache(inode, to, inode->i_size);
+               ext2_truncate_blocks(inode, inode->i_size);
+       }
+}
+
 /*
  * Called at the last iput() if i_nlink is zero.
  */
@@ -71,7 +83,7 @@ void ext2_delete_inode (struct inode * inode)
 
        inode->i_size = 0;
        if (inode->i_blocks)
-               ext2_truncate (inode);
+               ext2_truncate_blocks(inode, 0);
        ext2_free_inode (inode);
 
        return;
@@ -757,8 +769,8 @@ int __ext2_write_begin(struct file *file, struct address_space *mapping,
                loff_t pos, unsigned len, unsigned flags,
                struct page **pagep, void **fsdata)
 {
-       return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
-                                                       ext2_get_block);
+       return block_write_begin_newtrunc(file, mapping, pos, len, flags,
+                                       pagep, fsdata, ext2_get_block);
 }
 
 static int
@@ -766,8 +778,25 @@ ext2_write_begin(struct file *file, struct address_space *mapping,
                loff_t pos, unsigned len, unsigned flags,
                struct page **pagep, void **fsdata)
 {
+       int ret;
+
        *pagep = NULL;
-       return __ext2_write_begin(file, mapping, pos, len, flags, pagep,fsdata);
+       ret = __ext2_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
+       if (ret < 0)
+               ext2_write_failed(mapping, pos + len);
+       return ret;
+}
+
+static int ext2_write_end(struct file *file, struct address_space *mapping,
+                       loff_t pos, unsigned len, unsigned copied,
+                       struct page *page, void *fsdata)
+{
+       int ret;
+
+       ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
+       if (ret < len)
+               ext2_write_failed(mapping, pos + len);
+       return ret;
 }
 
 static int
@@ -775,13 +804,18 @@ ext2_nobh_write_begin(struct file *file, struct address_space *mapping,
                loff_t pos, unsigned len, unsigned flags,
                struct page **pagep, void **fsdata)
 {
+       int ret;
+
        /*
         * Dir-in-pagecache still uses ext2_write_begin. Would have to rework
         * directory handling code to pass around offsets rather than struct
         * pages in order to make this work easily.
         */
-       return nobh_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
-                                                       ext2_get_block);
+       ret = nobh_write_begin_newtrunc(file, mapping, pos, len, flags, pagep,
+                                               fsdata, ext2_get_block);
+       if (ret < 0)
+               ext2_write_failed(mapping, pos + len);
+       return ret;
 }
 
 static int ext2_nobh_writepage(struct page *page,
@@ -800,10 +834,15 @@ ext2_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
                        loff_t offset, unsigned long nr_segs)
 {
        struct file *file = iocb->ki_filp;
-       struct inode *inode = file->f_mapping->host;
-
-       return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
-                               offset, nr_segs, ext2_get_block, NULL);
+       struct address_space *mapping = file->f_mapping;
+       struct inode *inode = mapping->host;
+       ssize_t ret;
+
+       ret = blockdev_direct_IO_newtrunc(rw, iocb, inode, inode->i_sb->s_bdev,
+                               iov, offset, nr_segs, ext2_get_block, NULL);
+       if (ret < 0 && (rw & WRITE))
+               ext2_write_failed(mapping, offset + iov_length(iov, nr_segs));
+       return ret;
 }
 
 static int
@@ -818,7 +857,7 @@ const struct address_space_operations ext2_aops = {
        .writepage              = ext2_writepage,
        .sync_page              = block_sync_page,
        .write_begin            = ext2_write_begin,
-       .write_end              = generic_write_end,
+       .write_end              = ext2_write_end,
        .bmap                   = ext2_bmap,
        .direct_IO              = ext2_direct_IO,
        .writepages             = ext2_writepages,
@@ -1027,7 +1066,7 @@ static void ext2_free_branches(struct inode *inode, __le32 *p, __le32 *q, int de
                ext2_free_data(inode, p, q);
 }
 
-void ext2_truncate(struct inode *inode)
+static void __ext2_truncate_blocks(struct inode *inode, loff_t offset)
 {
        __le32 *i_data = EXT2_I(inode)->i_data;
        struct ext2_inode_info *ei = EXT2_I(inode);
@@ -1039,27 +1078,8 @@ void ext2_truncate(struct inode *inode)
        int n;
        long iblock;
        unsigned blocksize;
-
-       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
-           S_ISLNK(inode->i_mode)))
-               return;
-       if (ext2_inode_is_fast_symlink(inode))
-               return;
-       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
-               return;
-
        blocksize = inode->i_sb->s_blocksize;
-       iblock = (inode->i_size + blocksize-1)
-                                       >> EXT2_BLOCK_SIZE_BITS(inode->i_sb);
-
-       if (mapping_is_xip(inode->i_mapping))
-               xip_truncate_page(inode->i_mapping, inode->i_size);
-       else if (test_opt(inode->i_sb, NOBH))
-               nobh_truncate_page(inode->i_mapping,
-                               inode->i_size, ext2_get_block);
-       else
-               block_truncate_page(inode->i_mapping,
-                               inode->i_size, ext2_get_block);
+       iblock = (offset + blocksize-1) >> EXT2_BLOCK_SIZE_BITS(inode->i_sb);
 
        n = ext2_block_to_path(inode, iblock, offsets, NULL);
        if (n == 0)
@@ -1127,6 +1147,62 @@ do_indirects:
        ext2_discard_reservation(inode);
 
        mutex_unlock(&ei->truncate_mutex);
+}
+
+static void ext2_truncate_blocks(struct inode *inode, loff_t offset)
+{
+       /*
+        * XXX: it seems like a bug here that we don't allow
+        * IS_APPEND inode to have blocks-past-i_size trimmed off.
+        * review and fix this.
+        *
+        * Also would be nice to be able to handle IO errors and such,
+        * but that's probably too much to ask.
+        */
+       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+           S_ISLNK(inode->i_mode)))
+               return;
+       if (ext2_inode_is_fast_symlink(inode))
+               return;
+       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+               return;
+       __ext2_truncate_blocks(inode, offset);
+}
+
+int ext2_setsize(struct inode *inode, loff_t newsize)
+{
+       loff_t oldsize;
+       int error;
+
+       error = inode_newsize_ok(inode, newsize);
+       if (error)
+               return error;
+
+       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+           S_ISLNK(inode->i_mode)))
+               return -EINVAL;
+       if (ext2_inode_is_fast_symlink(inode))
+               return -EINVAL;
+       if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+               return -EPERM;
+
+       if (mapping_is_xip(inode->i_mapping))
+               error = xip_truncate_page(inode->i_mapping, newsize);
+       else if (test_opt(inode->i_sb, NOBH))
+               error = nobh_truncate_page(inode->i_mapping,
+                               newsize, ext2_get_block);
+       else
+               error = block_truncate_page(inode->i_mapping,
+                               newsize, ext2_get_block);
+       if (error)
+               return error;
+
+       oldsize = inode->i_size;
+       i_size_write(inode, newsize);
+       truncate_pagecache(inode, oldsize, newsize);
+
+       __ext2_truncate_blocks(inode, newsize);
+
        inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
        if (inode_needs_sync(inode)) {
                sync_mapping_buffers(inode->i_mapping);
@@ -1134,6 +1210,8 @@ do_indirects:
        } else {
                mark_inode_dirty(inode);
        }
+
+       return 0;
 }
 
 static struct ext2_inode *ext2_get_inode(struct super_block *sb, ino_t ino,
@@ -1474,8 +1552,15 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
                if (error)
                        return error;
        }
-       error = inode_setattr(inode, iattr);
-       if (!error && (iattr->ia_valid & ATTR_MODE))
+       if (iattr->ia_valid & ATTR_SIZE) {
+               error = ext2_setsize(inode, iattr->ia_size);
+               if (error)
+                       return error;
+       }
+       generic_setattr(inode, iattr);
+       if (iattr->ia_valid & ATTR_MODE)
                error = ext2_acl_chmod(inode);
+       mark_inode_dirty(inode);
+
        return error;
 }
index fcf7487..d7e9f74 100644 (file)
@@ -43,9 +43,9 @@
  * inode to disk.
  */
 
-int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync)
+int ext3_sync_file(struct file *file, int datasync)
 {
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = file->f_mapping->host;
        struct ext3_inode_info *ei = EXT3_I(inode);
        journal_t *journal = EXT3_SB(inode->i_sb)->s_journal;
        int ret, needs_barrier = 0;
index 60bd310..19a4de5 100644 (file)
@@ -1519,7 +1519,7 @@ extern int ext4_htree_store_dirent(struct file *dir_file, __u32 hash,
 extern void ext4_htree_free_dir_info(struct dir_private_info *p);
 
 /* fsync.c */
-extern int ext4_sync_file(struct file *, struct dentry *, int);
+extern int ext4_sync_file(struct file *, int);
 
 /* hash.c */
 extern int ext4fs_dirhash(const char *name, int len, struct
index b6a74f9..592adf2 100644 (file)
@@ -71,9 +71,9 @@ static void ext4_sync_parent(struct inode *inode)
  * i_mutex lock is held when entering and exiting this function
  */
 
-int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
+int ext4_sync_file(struct file *file, int datasync)
 {
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = file->f_mapping->host;
        struct ext4_inode_info *ei = EXT4_I(inode);
        journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
        int ret;
@@ -81,7 +81,7 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
 
        J_ASSERT(ext4_journal_current_handle() == NULL);
 
-       trace_ext4_sync_file(file, dentry, datasync);
+       trace_ext4_sync_file(file, datasync);
 
        if (inode->i_sb->s_flags & MS_RDONLY)
                return 0;
@@ -91,7 +91,7 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
                return ret;
 
        if (!journal) {
-               ret = simple_fsync(file, dentry, datasync);
+               ret = generic_file_fsync(file, datasync);
                if (!ret && !list_empty(&inode->i_dentry))
                        ext4_sync_parent(inode);
                return ret;
index 53dba57..27ac257 100644 (file)
@@ -306,11 +306,11 @@ extern long fat_generic_ioctl(struct file *filp, unsigned int cmd,
 extern const struct file_operations fat_file_operations;
 extern const struct inode_operations fat_file_inode_operations;
 extern int fat_setattr(struct dentry * dentry, struct iattr * attr);
-extern void fat_truncate(struct inode *inode);
+extern int fat_setsize(struct inode *inode, loff_t offset);
+extern void fat_truncate_blocks(struct inode *inode, loff_t offset);
 extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry,
                       struct kstat *stat);
-extern int fat_file_fsync(struct file *file, struct dentry *dentry,
-                         int datasync);
+extern int fat_file_fsync(struct file *file, int datasync);
 
 /* fat/inode.c */
 extern void fat_attach(struct inode *inode, loff_t i_pos);
index a14c2f6..990dfae 100644 (file)
@@ -149,12 +149,12 @@ static int fat_file_release(struct inode *inode, struct file *filp)
        return 0;
 }
 
-int fat_file_fsync(struct file *filp, struct dentry *dentry, int datasync)
+int fat_file_fsync(struct file *filp, int datasync)
 {
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = filp->f_mapping->host;
        int res, err;
 
-       res = simple_fsync(filp, dentry, datasync);
+       res = generic_file_fsync(filp, datasync);
        err = sync_mapping_buffers(MSDOS_SB(inode->i_sb)->fat_inode->i_mapping);
 
        return res ? res : err;
@@ -283,7 +283,7 @@ static int fat_free(struct inode *inode, int skip)
        return fat_free_clusters(inode, free_start);
 }
 
-void fat_truncate(struct inode *inode)
+void fat_truncate_blocks(struct inode *inode, loff_t offset)
 {
        struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
        const unsigned int cluster_size = sbi->cluster_size;
@@ -293,10 +293,10 @@ void fat_truncate(struct inode *inode)
         * This protects against truncating a file bigger than it was then
         * trying to write into the hole.
         */
-       if (MSDOS_I(inode)->mmu_private > inode->i_size)
-               MSDOS_I(inode)->mmu_private = inode->i_size;
+       if (MSDOS_I(inode)->mmu_private > offset)
+               MSDOS_I(inode)->mmu_private = offset;
 
-       nr_clusters = (inode->i_size + (cluster_size - 1)) >> sbi->cluster_bits;
+       nr_clusters = (offset + (cluster_size - 1)) >> sbi->cluster_bits;
 
        fat_free(inode, nr_clusters);
        fat_flush_inodes(inode->i_sb, inode, NULL);
@@ -364,6 +364,18 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode)
        return 0;
 }
 
+int fat_setsize(struct inode *inode, loff_t offset)
+{
+       int error;
+
+       error = simple_setsize(inode, offset);
+       if (error)
+               return error;
+       fat_truncate_blocks(inode, offset);
+
+       return error;
+}
+
 #define TIMES_SET_FLAGS        (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)
 /* valid file mode bits */
 #define FAT_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXUGO)
@@ -378,7 +390,8 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
        /*
         * Expand the file. Since inode_setattr() updates ->i_size
         * before calling the ->truncate(), but FAT needs to fill the
-        * hole before it.
+        * hole before it. XXX: this is no longer true with new truncate
+        * sequence.
         */
        if (attr->ia_valid & ATTR_SIZE) {
                if (attr->ia_size > inode->i_size) {
@@ -427,15 +440,20 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
                        attr->ia_valid &= ~ATTR_MODE;
        }
 
-       if (attr->ia_valid)
-               error = inode_setattr(inode, attr);
+       if (attr->ia_valid & ATTR_SIZE) {
+               error = fat_setsize(inode, attr->ia_size);
+               if (error)
+                       goto out;
+       }
+
+       generic_setattr(inode, attr);
+       mark_inode_dirty(inode);
 out:
        return error;
 }
 EXPORT_SYMBOL_GPL(fat_setattr);
 
 const struct inode_operations fat_file_inode_operations = {
-       .truncate       = fat_truncate,
        .setattr        = fat_setattr,
        .getattr        = fat_getattr,
 };
index ed33904..7bf45ae 100644 (file)
@@ -142,14 +142,29 @@ static int fat_readpages(struct file *file, struct address_space *mapping,
        return mpage_readpages(mapping, pages, nr_pages, fat_get_block);
 }
 
+static void fat_write_failed(struct address_space *mapping, loff_t to)
+{
+       struct inode *inode = mapping->host;
+
+       if (to > inode->i_size) {
+               truncate_pagecache(inode, to, inode->i_size);
+               fat_truncate_blocks(inode, inode->i_size);
+       }
+}
+
 static int fat_write_begin(struct file *file, struct address_space *mapping,
                        loff_t pos, unsigned len, unsigned flags,
                        struct page **pagep, void **fsdata)
 {
+       int err;
+
        *pagep = NULL;
-       return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
-                               fat_get_block,
+       err = cont_write_begin_newtrunc(file, mapping, pos, len, flags,
+                               pagep, fsdata, fat_get_block,
                                &MSDOS_I(mapping->host)->mmu_private);
+       if (err < 0)
+               fat_write_failed(mapping, pos + len);
+       return err;
 }
 
 static int fat_write_end(struct file *file, struct address_space *mapping,
@@ -159,6 +174,8 @@ static int fat_write_end(struct file *file, struct address_space *mapping,
        struct inode *inode = mapping->host;
        int err;
        err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata);
+       if (err < len)
+               fat_write_failed(mapping, pos + len);
        if (!(err < 0) && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) {
                inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
                MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
@@ -172,7 +189,9 @@ static ssize_t fat_direct_IO(int rw, struct kiocb *iocb,
                             loff_t offset, unsigned long nr_segs)
 {
        struct file *file = iocb->ki_filp;
-       struct inode *inode = file->f_mapping->host;
+       struct address_space *mapping = file->f_mapping;
+       struct inode *inode = mapping->host;
+       ssize_t ret;
 
        if (rw == WRITE) {
                /*
@@ -193,8 +212,12 @@ static ssize_t fat_direct_IO(int rw, struct kiocb *iocb,
         * FAT need to use the DIO_LOCKING for avoiding the race
         * condition of fat_get_block() and ->truncate().
         */
-       return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
-                                 offset, nr_segs, fat_get_block, NULL);
+       ret = blockdev_direct_IO_newtrunc(rw, iocb, inode, inode->i_sb->s_bdev,
+                               iov, offset, nr_segs, fat_get_block, NULL);
+       if (ret < 0 && (rw & WRITE))
+               fat_write_failed(mapping, offset + iov_length(iov, nr_segs));
+
+       return ret;
 }
 
 static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
@@ -429,7 +452,7 @@ static void fat_delete_inode(struct inode *inode)
 {
        truncate_inode_pages(&inode->i_data, 0);
        inode->i_size = 0;
-       fat_truncate(inode);
+       fat_truncate_blocks(inode, 0);
        clear_inode(inode);
 }
 
index 32d12b7..5c7d10e 100644 (file)
@@ -194,14 +194,6 @@ struct file *alloc_file(struct path *path, fmode_t mode,
 }
 EXPORT_SYMBOL(alloc_file);
 
-void fput(struct file *file)
-{
-       if (atomic_long_dec_and_test(&file->f_count))
-               __fput(file);
-}
-
-EXPORT_SYMBOL(fput);
-
 /**
  * drop_file_write_access - give up ability to write to a file
  * @file: the file to which we will stop writing
@@ -227,10 +219,9 @@ void drop_file_write_access(struct file *file)
 }
 EXPORT_SYMBOL_GPL(drop_file_write_access);
 
-/* __fput is called from task context when aio completion releases the last
- * last use of a struct file *.  Do not use otherwise.
+/* the real guts of fput() - releasing the last reference to file
  */
-void __fput(struct file *file)
+static void __fput(struct file *file)
 {
        struct dentry *dentry = file->f_path.dentry;
        struct vfsmount *mnt = file->f_path.mnt;
@@ -268,6 +259,14 @@ void __fput(struct file *file)
        mntput(mnt);
 }
 
+void fput(struct file *file)
+{
+       if (atomic_long_dec_and_test(&file->f_count))
+               __fput(file);
+}
+
+EXPORT_SYMBOL(fput);
+
 struct file *fget(unsigned int fd)
 {
        struct file *file;
index 4787ae6..3cdc5f7 100644 (file)
@@ -1156,10 +1156,9 @@ static int fuse_dir_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
+static int fuse_dir_fsync(struct file *file, int datasync)
 {
-       /* nfsd can call this with no file */
-       return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
+       return fuse_fsync_common(file, datasync, 1);
 }
 
 static bool update_mtime(unsigned ivalid)
index a9f5e13..b5fd6f9 100644 (file)
@@ -351,10 +351,9 @@ static void fuse_sync_writes(struct inode *inode)
        fuse_release_nowrite(inode);
 }
 
-int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
-                     int isdir)
+int fuse_fsync_common(struct file *file, int datasync, int isdir)
 {
-       struct inode *inode = de->d_inode;
+       struct inode *inode = file->f_mapping->host;
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_file *ff = file->private_data;
        struct fuse_req *req;
@@ -403,9 +402,9 @@ int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
        return err;
 }
 
-static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
+static int fuse_fsync(struct file *file, int datasync)
 {
-       return fuse_fsync_common(file, de, datasync, 0);
+       return fuse_fsync_common(file, datasync, 0);
 }
 
 void fuse_read_fill(struct fuse_req *req, struct file *file, loff_t pos,
index 01cc462..2c0d14a 100644 (file)
@@ -568,8 +568,7 @@ void fuse_release_common(struct file *file, int opcode);
 /**
  * Send FSYNC or FSYNCDIR request
  */
-int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
-                     int isdir);
+int fuse_fsync_common(struct file *file, int datasync, int isdir);
 
 /**
  * Notify poll wakeup
index a739a0a..9f8b525 100644 (file)
@@ -700,8 +700,14 @@ out:
                return 0;
 
        page_cache_release(page);
+
+       /*
+        * XXX(hch): the call below should probably be replaced with
+        * a call to the gfs2-specific truncate blocks helper to actually
+        * release disk blocks..
+        */
        if (pos + len > ip->i_inode.i_size)
-               vmtruncate(&ip->i_inode, ip->i_inode.i_size);
+               simple_setsize(&ip->i_inode, ip->i_inode.i_size);
 out_endtrans:
        gfs2_trans_end(sdp);
 out_trans_fail:
index b20bfcc..ed9a94f 100644 (file)
@@ -554,9 +554,9 @@ static int gfs2_close(struct inode *inode, struct file *file)
  * Returns: errno
  */
 
-static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync)
+static int gfs2_fsync(struct file *file, int datasync)
 {
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = file->f_mapping->host;
        int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC);
        int ret = 0;
 
index 4e64352..98cdd05 100644 (file)
@@ -1071,6 +1071,9 @@ int gfs2_permission(struct inode *inode, int mask)
        return error;
 }
 
+/*
+ * XXX: should be changed to have proper ordering by opencoding simple_setsize
+ */
 static int setattr_size(struct inode *inode, struct iattr *attr)
 {
        struct gfs2_inode *ip = GFS2_I(inode);
@@ -1081,7 +1084,7 @@ static int setattr_size(struct inode *inode, struct iattr *attr)
                error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks);
                if (error)
                        return error;
-               error = vmtruncate(inode, attr->ia_size);
+               error = simple_setsize(inode, attr->ia_size);
                gfs2_trans_end(sdp);
                if (error) 
                        return error;
index 3a029d8..87ac189 100644 (file)
@@ -411,9 +411,9 @@ int hostfs_file_open(struct inode *ino, struct file *file)
        return 0;
 }
 
-int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
+int hostfs_fsync(struct file *file, int datasync)
 {
-       return fsync_file(HOSTFS_I(dentry->d_inode)->fd, datasync);
+       return fsync_file(HOSTFS_I(file->f_mapping->host)->fd, datasync);
 }
 
 static const struct file_operations hostfs_file_fops = {
index 3efabff..a9ae9bf 100644 (file)
@@ -19,9 +19,9 @@ static int hpfs_file_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-int hpfs_file_fsync(struct file *file, struct dentry *dentry, int datasync)
+int hpfs_file_fsync(struct file *file, int datasync)
 {
-       /*return file_fsync(file, dentry);*/
+       /*return file_fsync(file, datasync);*/
        return 0; /* Don't fsync :-) */
 }
 
index 97bf738..75f9d43 100644 (file)
@@ -268,7 +268,7 @@ void hpfs_set_ea(struct inode *, struct fnode *, const char *,
 
 /* file.c */
 
-int hpfs_file_fsync(struct file *, struct dentry *, int);
+int hpfs_file_fsync(struct file *, int);
 extern const struct file_operations hpfs_file_ops;
 extern const struct inode_operations hpfs_file_iops;
 extern const struct address_space_operations hpfs_aops;
index 2e4dfa8..826c3f9 100644 (file)
@@ -587,7 +587,7 @@ static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
        return err;
 }
 
-static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
+static int hppfs_fsync(struct file *file, int datasync)
 {
        return 0;
 }
index a0bbd3d..a4e9a7e 100644 (file)
@@ -688,7 +688,7 @@ static void init_once(void *foo)
 const struct file_operations hugetlbfs_file_operations = {
        .read                   = hugetlbfs_read,
        .mmap                   = hugetlbfs_file_mmap,
-       .fsync                  = simple_sync_file,
+       .fsync                  = noop_fsync,
        .get_unmapped_area      = hugetlb_get_unmapped_area,
 };
 
index e7291c1..8134970 100644 (file)
@@ -26,9 +26,9 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
                        struct page **pagep, void **fsdata);
 static int jffs2_readpage (struct file *filp, struct page *pg);
 
-int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync)
+int jffs2_fsync(struct file *filp, int datasync)
 {
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = filp->f_mapping->host;
        struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
 
        /* Trigger GC to flush any pending writes for this inode */
index 86e0821..8bc2c80 100644 (file)
@@ -169,13 +169,13 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
        mutex_unlock(&f->sem);
        jffs2_complete_reservation(c);
 
-       /* We have to do the vmtruncate() without f->sem held, since
+       /* We have to do the simple_setsize() without f->sem held, since
           some pages may be locked and waiting for it in readpage().
           We are protected from a simultaneous write() extending i_size
           back past iattr->ia_size, because do_truncate() holds the
           generic inode semaphore. */
        if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) {
-               vmtruncate(inode, iattr->ia_size);      
+               simple_setsize(inode, iattr->ia_size);
                inode->i_blocks = (inode->i_size + 511) >> 9;
        }       
 
index 035a767..4791aac 100644 (file)
@@ -158,7 +158,7 @@ extern const struct inode_operations jffs2_dir_inode_operations;
 extern const struct file_operations jffs2_file_operations;
 extern const struct inode_operations jffs2_file_inode_operations;
 extern const struct address_space_operations jffs2_file_address_operations;
-int jffs2_fsync(struct file *, struct dentry *, int);
+int jffs2_fsync(struct file *, int);
 int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg);
 
 /* ioctl.c */
index 85d9ec6..127263c 100644 (file)
@@ -27,9 +27,9 @@
 #include "jfs_acl.h"
 #include "jfs_debug.h"
 
-int jfs_fsync(struct file *file, struct dentry *dentry, int datasync)
+int jfs_fsync(struct file *file, int datasync)
 {
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = file->f_mapping->host;
        int rc = 0;
 
        if (!(inode->i_state & I_DIRTY) ||
index 9e6bda3..11042b1 100644 (file)
@@ -21,7 +21,7 @@
 struct fid;
 
 extern struct inode *ialloc(struct inode *, umode_t);
-extern int jfs_fsync(struct file *, struct dentry *, int);
+extern int jfs_fsync(struct file *, int);
 extern long jfs_ioctl(struct file *, unsigned int, unsigned long);
 extern long jfs_compat_ioctl(struct file *, unsigned int, unsigned long);
 extern struct inode *jfs_iget(struct super_block *, unsigned long);
index 232bea4..09e1016 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/slab.h>
 #include <linux/mount.h>
 #include <linux/vfs.h>
+#include <linux/quotaops.h>
 #include <linux/mutex.h>
 #include <linux/exportfs.h>
 #include <linux/writeback.h>
@@ -58,11 +59,6 @@ struct dentry *simple_lookup(struct inode *dir, struct dentry *dentry, struct na
        return NULL;
 }
 
-int simple_sync_file(struct file * file, struct dentry *dentry, int datasync)
-{
-       return 0;
-}
 int dcache_dir_open(struct inode *inode, struct file *file)
 {
        static struct qstr cursor_name = {.len = 1, .name = "."};
@@ -190,7 +186,7 @@ const struct file_operations simple_dir_operations = {
        .llseek         = dcache_dir_lseek,
        .read           = generic_read_dir,
        .readdir        = dcache_readdir,
-       .fsync          = simple_sync_file,
+       .fsync          = noop_fsync,
 };
 
 const struct inode_operations simple_dir_inode_operations = {
@@ -330,6 +326,81 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry,
        return 0;
 }
 
+/**
+ * simple_setsize - handle core mm and vfs requirements for file size change
+ * @inode: inode
+ * @newsize: new file size
+ *
+ * Returns 0 on success, -error on failure.
+ *
+ * simple_setsize must be called with inode_mutex held.
+ *
+ * simple_setsize will check that the requested new size is OK (see
+ * inode_newsize_ok), and then will perform the necessary i_size update
+ * and pagecache truncation (if necessary). It will be typically be called
+ * from the filesystem's setattr function when ATTR_SIZE is passed in.
+ *
+ * The inode itself must have correct permissions and attributes to allow
+ * i_size to be changed, this function then just checks that the new size
+ * requested is valid.
+ *
+ * In the case of simple in-memory filesystems with inodes stored solely
+ * in the inode cache, and file data in the pagecache, nothing more needs
+ * to be done to satisfy a truncate request. Filesystems with on-disk
+ * blocks for example will need to free them in the case of truncate, in
+ * that case it may be easier not to use simple_setsize (but each of its
+ * components will likely be required at some point to update pagecache
+ * and inode etc).
+ */
+int simple_setsize(struct inode *inode, loff_t newsize)
+{
+       loff_t oldsize;
+       int error;
+
+       error = inode_newsize_ok(inode, newsize);
+       if (error)
+               return error;
+
+       oldsize = inode->i_size;
+       i_size_write(inode, newsize);
+       truncate_pagecache(inode, oldsize, newsize);
+
+       return error;
+}
+EXPORT_SYMBOL(simple_setsize);
+
+/**
+ * simple_setattr - setattr for simple in-memory filesystem
+ * @dentry: dentry
+ * @iattr: iattr structure
+ *
+ * Returns 0 on success, -error on failure.
+ *
+ * simple_setattr implements setattr for an in-memory filesystem which
+ * does not store its own file data or metadata (eg. uses the page cache
+ * and inode cache as its data store).
+ */
+int simple_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+       struct inode *inode = dentry->d_inode;
+       int error;
+
+       error = inode_change_ok(inode, iattr);
+       if (error)
+               return error;
+
+       if (iattr->ia_valid & ATTR_SIZE) {
+               error = simple_setsize(inode, iattr->ia_size);
+               if (error)
+                       return error;
+       }
+
+       generic_setattr(inode, iattr);
+
+       return error;
+}
+EXPORT_SYMBOL(simple_setattr);
+
 int simple_readpage(struct file *file, struct page *page)
 {
        clear_highpage(page);
@@ -851,13 +922,22 @@ struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid,
 }
 EXPORT_SYMBOL_GPL(generic_fh_to_parent);
 
-int simple_fsync(struct file *file, struct dentry *dentry, int datasync)
+/**
+ * generic_file_fsync - generic fsync implementation for simple filesystems
+ * @file:      file to synchronize
+ * @datasync:  only synchronize essential metadata if true
+ *
+ * This is a generic implementation of the fsync method for simple
+ * filesystems which track all non-inode metadata in the buffers list
+ * hanging off the address_space structure.
+ */
+int generic_file_fsync(struct file *file, int datasync)
 {
        struct writeback_control wbc = {
                .sync_mode = WB_SYNC_ALL,
                .nr_to_write = 0, /* metadata-only; caller takes care of data */
        };
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = file->f_mapping->host;
        int err;
        int ret;
 
@@ -872,7 +952,15 @@ int simple_fsync(struct file *file, struct dentry *dentry, int datasync)
                ret = err;
        return ret;
 }
-EXPORT_SYMBOL(simple_fsync);
+EXPORT_SYMBOL(generic_file_fsync);
+
+/*
+ * No-op implementation of ->fsync for in-memory filesystems.
+ */
+int noop_fsync(struct file *file, int datasync)
+{
+       return 0;
+}
 
 EXPORT_SYMBOL(dcache_dir_close);
 EXPORT_SYMBOL(dcache_dir_lseek);
@@ -895,7 +983,7 @@ EXPORT_SYMBOL(simple_release_fs);
 EXPORT_SYMBOL(simple_rename);
 EXPORT_SYMBOL(simple_rmdir);
 EXPORT_SYMBOL(simple_statfs);
-EXPORT_SYMBOL(simple_sync_file);
+EXPORT_SYMBOL(noop_fsync);
 EXPORT_SYMBOL(simple_unlink);
 EXPORT_SYMBOL(simple_read_from_buffer);
 EXPORT_SYMBOL(simple_write_to_buffer);
index 0de5240..abe1caf 100644 (file)
@@ -219,9 +219,9 @@ int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        }
 }
 
-int logfs_fsync(struct file *file, struct dentry *dentry, int datasync)
+int logfs_fsync(struct file *file, int datasync)
 {
-       struct super_block *sb = dentry->d_inode->i_sb;
+       struct super_block *sb = file->f_mapping->host->i_sb;
 
        logfs_write_anchor(sb);
        return 0;
index 1a9db84..c838c4d 100644 (file)
@@ -506,7 +506,7 @@ extern const struct address_space_operations logfs_reg_aops;
 int logfs_readpage(struct file *file, struct page *page);
 int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                unsigned long arg);
-int logfs_fsync(struct file *file, struct dentry *dentry, int datasync);
+int logfs_fsync(struct file *file, int datasync);
 
 /* gc.c */
 u32 get_best_cand(struct super_block *sb, struct candidate_list *list, u32 *ec);
index 6198731..9196958 100644 (file)
@@ -22,7 +22,7 @@ const struct file_operations minix_dir_operations = {
        .llseek         = generic_file_llseek,
        .read           = generic_read_dir,
        .readdir        = minix_readdir,
-       .fsync          = simple_fsync,
+       .fsync          = generic_file_fsync,
 };
 
 static inline void dir_put_page(struct page *page)
@@ -72,11 +72,8 @@ static struct page * dir_get_page(struct inode *dir, unsigned long n)
 {
        struct address_space *mapping = dir->i_mapping;
        struct page *page = read_mapping_page(mapping, n, NULL);
-       if (!IS_ERR(page)) {
+       if (!IS_ERR(page))
                kmap(page);
-               if (!PageUptodate(page))
-                       goto fail;
-       }
        return page;
 
 fail:
index 3eec3e6..d5320ff 100644 (file)
@@ -19,7 +19,7 @@ const struct file_operations minix_file_operations = {
        .write          = do_sync_write,
        .aio_write      = generic_file_aio_write,
        .mmap           = generic_file_mmap,
-       .fsync          = simple_fsync,
+       .fsync          = generic_file_fsync,
        .splice_read    = generic_file_splice_read,
 };
 
index f230109..13487ad 100644 (file)
@@ -20,6 +20,9 @@ static inline block_t *i_data(struct inode *inode)
        return (block_t *)minix_i(inode)->u.i2_data;
 }
 
+#define DIRCOUNT 7
+#define INDIRCOUNT(sb) (1 << ((sb)->s_blocksize_bits - 2))
+
 static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
 {
        int n = 0;
@@ -34,21 +37,21 @@ static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
                        printk("MINIX-fs: block_to_path: "
                               "block %ld too big on dev %s\n",
                                block, bdevname(sb->s_bdev, b));
-       } else if (block < 7) {
+       } else if (block < DIRCOUNT) {
                offsets[n++] = block;
-       } else if ((block -= 7) < 256) {
-               offsets[n++] = 7;
+       } else if ((block -= DIRCOUNT) < INDIRCOUNT(sb)) {
+               offsets[n++] = DIRCOUNT;
                offsets[n++] = block;
-       } else if ((block -= 256) < 256*256) {
-               offsets[n++] = 8;
-               offsets[n++] = block>>8;
-               offsets[n++] = block & 255;
+       } else if ((block -= INDIRCOUNT(sb)) < INDIRCOUNT(sb) * INDIRCOUNT(sb)) {
+               offsets[n++] = DIRCOUNT + 1;
+               offsets[n++] = block / INDIRCOUNT(sb);
+               offsets[n++] = block % INDIRCOUNT(sb);
        } else {
-               block -= 256*256;
-               offsets[n++] = 9;
-               offsets[n++] = block>>16;
-               offsets[n++] = (block>>8) & 255;
-               offsets[n++] = block & 255;
+               block -= INDIRCOUNT(sb) * INDIRCOUNT(sb);
+               offsets[n++] = DIRCOUNT + 2;
+               offsets[n++] = (block / INDIRCOUNT(sb)) / INDIRCOUNT(sb);
+               offsets[n++] = (block / INDIRCOUNT(sb)) % INDIRCOUNT(sb);
+               offsets[n++] = block % INDIRCOUNT(sb);
        }
        return n;
 }
index 48e1f60..868d0cb 100644 (file)
@@ -1621,6 +1621,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
        case LAST_DOTDOT:
                follow_dotdot(nd);
                dir = nd->path.dentry;
+       case LAST_DOT:
                if (nd->path.mnt->mnt_sb->s_type->fs_flags & FS_REVAL_DOT) {
                        if (!dir->d_op->d_revalidate(dir, nd)) {
                                error = -ESTALE;
@@ -1628,7 +1629,6 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
                        }
                }
                /* fallthrough */
-       case LAST_DOT:
        case LAST_ROOT:
                if (open_flag & O_CREAT)
                        goto exit;
index b938708..3639cc5 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/ncp_fs.h>
 #include "ncplib_kernel.h"
 
-static int ncp_fsync(struct file *file, struct dentry *dentry, int datasync)
+static int ncp_fsync(struct file *file, int datasync)
 {
        return 0;
 }
index db64854..782b431 100644 (file)
@@ -53,7 +53,7 @@ static int nfs_link(struct dentry *, struct inode *, struct dentry *);
 static int nfs_mknod(struct inode *, struct dentry *, int, dev_t);
 static int nfs_rename(struct inode *, struct dentry *,
                      struct inode *, struct dentry *);
-static int nfs_fsync_dir(struct file *, struct dentry *, int);
+static int nfs_fsync_dir(struct file *, int);
 static loff_t nfs_llseek_dir(struct file *, loff_t, int);
 
 const struct file_operations nfs_dir_operations = {
@@ -641,8 +641,10 @@ out:
  * All directory operations under NFS are synchronous, so fsync()
  * is a dummy operation.
  */
-static int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync)
+static int nfs_fsync_dir(struct file *filp, int datasync)
 {
+       struct dentry *dentry = filp->f_path.dentry;
+
        dfprintk(FILE, "NFS: fsync dir(%s/%s) datasync %d\n",
                        dentry->d_parent->d_name.name, dentry->d_name.name,
                        datasync);
index cac96bc..36a5e74 100644 (file)
@@ -53,7 +53,7 @@ static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
 static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov,
                                unsigned long nr_segs, loff_t pos);
 static int  nfs_file_flush(struct file *, fl_owner_t id);
-static int  nfs_file_fsync(struct file *, struct dentry *dentry, int datasync);
+static int  nfs_file_fsync(struct file *, int datasync);
 static int nfs_check_flags(int flags);
 static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
 static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
@@ -322,8 +322,9 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
  * whether any write errors occurred for this process.
  */
 static int
-nfs_file_fsync(struct file *file, struct dentry *dentry, int datasync)
+nfs_file_fsync(struct file *file, int datasync)
 {
+       struct dentry *dentry = file->f_path.dentry;
        struct nfs_open_context *ctx = nfs_file_open_context(file);
        struct inode *inode = dentry->d_inode;
 
index 30292df..c9a30d7 100644 (file)
@@ -27,7 +27,7 @@
 #include "nilfs.h"
 #include "segment.h"
 
-int nilfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
+int nilfs_sync_file(struct file *file, int datasync)
 {
        /*
         * Called from fsync() system call
@@ -37,7 +37,7 @@ int nilfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
         * This function should be implemented when the writeback function
         * will be implemented.
         */
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = file->f_mapping->host;
        int err;
 
        if (!nilfs_inode_dirty(inode))
index 8723e5b..47d6d79 100644 (file)
@@ -228,7 +228,7 @@ extern void nilfs_set_link(struct inode *, struct nilfs_dir_entry *,
                           struct page *, struct inode *);
 
 /* file.c */
-extern int nilfs_sync_file(struct file *, struct dentry *, int);
+extern int nilfs_sync_file(struct file *, int);
 
 /* ioctl.c */
 long nilfs_ioctl(struct file *, unsigned int, unsigned long);
index fe44d3f..0f48e7c 100644 (file)
@@ -1527,10 +1527,9 @@ static int ntfs_dir_open(struct inode *vi, struct file *filp)
  * this problem for now.  We do write the $BITMAP attribute if it is present
  * which is the important one for a directory so things are not too bad.
  */
-static int ntfs_dir_fsync(struct file *filp, struct dentry *dentry,
-               int datasync)
+static int ntfs_dir_fsync(struct file *filp, int datasync)
 {
-       struct inode *bmp_vi, *vi = dentry->d_inode;
+       struct inode *bmp_vi, *vi = filp->f_mapping->host;
        int err, ret;
        ntfs_attr na;
 
index a1924a0..113ebd9 100644 (file)
@@ -2133,7 +2133,6 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 /**
  * ntfs_file_fsync - sync a file to disk
  * @filp:      file to be synced
- * @dentry:    dentry describing the file to sync
  * @datasync:  if non-zero only flush user data and not metadata
  *
  * Data integrity sync of a file to disk.  Used for fsync, fdatasync, and msync
@@ -2149,19 +2148,15 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
  * Also, if @datasync is true, we do not wait on the inode to be written out
  * but we always wait on the page cache pages to be written out.
  *
- * Note: In the past @filp could be NULL so we ignore it as we don't need it
- * anyway.
- *
  * Locking: Caller must hold i_mutex on the inode.
  *
  * TODO: We should probably also write all attribute/index inodes associated
  * with this inode but since we have no simple way of getting to them we ignore
  * this problem for now.
  */
-static int ntfs_file_fsync(struct file *filp, struct dentry *dentry,
-               int datasync)
+static int ntfs_file_fsync(struct file *filp, int datasync)
 {
-       struct inode *vi = dentry->d_inode;
+       struct inode *vi = filp->f_mapping->host;
        int err, ret = 0;
 
        ntfs_debug("Entering for inode 0x%lx.", vi->i_ino);
index 97e54b9..6a13ea6 100644 (file)
@@ -175,13 +175,12 @@ static int ocfs2_dir_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static int ocfs2_sync_file(struct file *file,
-                          struct dentry *dentry,
-                          int datasync)
+static int ocfs2_sync_file(struct file *file, int datasync)
 {
        int err = 0;
        journal_t *journal;
-       struct inode *inode = dentry->d_inode;
+       struct dentry *dentry = file->f_path.dentry;
+       struct inode *inode = file->f_mapping->host;
        struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
 
        mlog_entry("(0x%p, 0x%p, %d, '%.*s')\n", file, dentry, datasync,
@@ -1053,7 +1052,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
        }
 
        /*
-        * This will intentionally not wind up calling vmtruncate(),
+        * This will intentionally not wind up calling simple_setsize(),
         * since all the work for a size change has been done above.
         * Otherwise, we could get into problems with truncate as
         * ip_alloc_sem is used there to protect against i_size
@@ -2119,9 +2118,13 @@ relock:
                         * direct write may have instantiated a few
                         * blocks outside i_size. Trim these off again.
                         * Don't need i_size_read because we hold i_mutex.
+                        *
+                        * XXX(hch): this looks buggy because ocfs2 did not
+                        * actually implement ->truncate.  Take a look at
+                        * the new truncate sequence and update this accordingly
                         */
                        if (*ppos + count > inode->i_size)
-                               vmtruncate(inode, inode->i_size);
+                               simple_setsize(inode, inode->i_size);
                        ret = written;
                        goto out_dio;
                }
index 399487c..6e7a329 100644 (file)
@@ -329,7 +329,7 @@ const struct file_operations omfs_file_operations = {
        .aio_read = generic_file_aio_read,
        .aio_write = generic_file_aio_write,
        .mmap = generic_file_mmap,
-       .fsync = simple_fsync,
+       .fsync = generic_file_fsync,
        .splice_read = generic_file_splice_read,
 };
 
index d79872e..60da077 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1169,14 +1169,18 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
 
        switch (cmd) {
        case F_SETPIPE_SZ:
-               if (!capable(CAP_SYS_ADMIN) && arg > pipe_max_pages)
-                       return -EINVAL;
+               if (!capable(CAP_SYS_ADMIN) && arg > pipe_max_pages) {
+                       ret = -EINVAL;
+                       goto out;
+               }
                /*
                 * The pipe needs to be at least 2 pages large to
                 * guarantee POSIX behaviour.
                 */
-               if (arg < 2)
-                       return -EINVAL;
+               if (arg < 2) {
+                       ret = -EINVAL;
+                       goto out;
+               }
                ret = pipe_set_size(pipe, arg);
                break;
        case F_GETPIPE_SZ:
@@ -1187,6 +1191,7 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
                break;
        }
 
+out:
        mutex_unlock(&pipe->inode->i_mutex);
        return ret;
 }
index 3d3fd46..6e8fc62 100644 (file)
@@ -80,7 +80,7 @@ const struct file_operations qnx4_dir_operations =
        .llseek         = generic_file_llseek,
        .read           = generic_read_dir,
        .readdir        = qnx4_readdir,
-       .fsync          = simple_fsync,
+       .fsync          = generic_file_fsync,
 };
 
 const struct inode_operations qnx4_dir_inode_operations =
index 78f613c..4884ac5 100644 (file)
@@ -43,12 +43,13 @@ const struct file_operations ramfs_file_operations = {
        .write          = do_sync_write,
        .aio_write      = generic_file_aio_write,
        .mmap           = generic_file_mmap,
-       .fsync          = simple_sync_file,
+       .fsync          = noop_fsync,
        .splice_read    = generic_file_splice_read,
        .splice_write   = generic_file_splice_write,
        .llseek         = generic_file_llseek,
 };
 
 const struct inode_operations ramfs_file_inode_operations = {
+       .setattr        = simple_setattr,
        .getattr        = simple_getattr,
 };
index 5ea4ad8..d532c20 100644 (file)
@@ -42,7 +42,7 @@ const struct file_operations ramfs_file_operations = {
        .aio_read               = generic_file_aio_read,
        .write                  = do_sync_write,
        .aio_write              = generic_file_aio_write,
-       .fsync                  = simple_sync_file,
+       .fsync                  = noop_fsync,
        .splice_read            = generic_file_splice_read,
        .splice_write           = generic_file_splice_write,
        .llseek                 = generic_file_llseek,
@@ -146,7 +146,7 @@ static int ramfs_nommu_resize(struct inode *inode, loff_t newsize, loff_t size)
                        return ret;
        }
 
-       ret = vmtruncate(inode, newsize);
+       ret = simple_setsize(inode, newsize);
 
        return ret;
 }
@@ -169,7 +169,8 @@ static int ramfs_nommu_setattr(struct dentry *dentry, struct iattr *ia)
 
        /* pick out size-changing events */
        if (ia->ia_valid & ATTR_SIZE) {
-               loff_t size = i_size_read(inode);
+               loff_t size = inode->i_size;
+
                if (ia->ia_size != size) {
                        ret = ramfs_nommu_resize(inode, ia->ia_size, size);
                        if (ret < 0 || ia->ia_valid == ATTR_SIZE)
@@ -182,7 +183,7 @@ static int ramfs_nommu_setattr(struct dentry *dentry, struct iattr *ia)
                }
        }
 
-       ret = inode_setattr(inode, ia);
+       generic_setattr(inode, ia);
  out:
        ia->ia_valid = old_ia_valid;
        return ret;
index 4455fbe..198dabf 100644 (file)
@@ -14,8 +14,7 @@
 extern const struct reiserfs_key MIN_KEY;
 
 static int reiserfs_readdir(struct file *, void *, filldir_t);
-static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry,
-                             int datasync);
+static int reiserfs_dir_fsync(struct file *filp, int datasync);
 
 const struct file_operations reiserfs_dir_operations = {
        .llseek = generic_file_llseek,
@@ -28,10 +27,9 @@ const struct file_operations reiserfs_dir_operations = {
 #endif
 };
 
-static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry,
-                             int datasync)
+static int reiserfs_dir_fsync(struct file *filp, int datasync)
 {
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = filp->f_mapping->host;
        int err;
        reiserfs_write_lock(inode->i_sb);
        err = reiserfs_commit_for_inode(inode);
index 9977df9..b82cdd8 100644 (file)
@@ -134,10 +134,9 @@ static void reiserfs_vfs_truncate_file(struct inode *inode)
  * be removed...
  */
 
-static int reiserfs_sync_file(struct file *filp,
-                             struct dentry *dentry, int datasync)
+static int reiserfs_sync_file(struct file *filp, int datasync)
 {
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = filp->f_mapping->host;
        int err;
        int barrier_done;
 
index 84ecf0e..8e187a0 100644 (file)
@@ -28,8 +28,9 @@
 #include "proto.h"
 
 static int
-smb_fsync(struct file *file, struct dentry * dentry, int datasync)
+smb_fsync(struct file *file, int datasync)
 {
+       struct dentry *dentry = file->f_path.dentry;
        struct smb_sb_info *server = server_from_dentry(dentry);
        int result;
 
index dfa1d67..9551cb6 100644 (file)
@@ -714,7 +714,7 @@ smb_notify_change(struct dentry *dentry, struct iattr *attr)
                error = server->ops->truncate(inode, attr->ia_size);
                if (error)
                        goto out;
-               error = vmtruncate(inode, attr->ia_size);
+               error = simple_setsize(inode, attr->ia_size);
                if (error)
                        goto out;
                refresh = 1;
index 69688b1..a67409e 100644 (file)
@@ -946,8 +946,8 @@ out:
 EXPORT_SYMBOL_GPL(vfs_kern_mount);
 
 /**
- * freeze_super -- lock the filesystem and force it into a consistent state
- * @super: the super to lock
+ * freeze_super - lock the filesystem and force it into a consistent state
+ * @sb: the super to lock
  *
  * Syncs the super to make sure the filesystem is consistent and calls the fs's
  * freeze_fs.  Subsequent calls to this without first thawing the fs will return
index e8cbd41..c9f83f4 100644 (file)
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -130,12 +130,10 @@ void emergency_sync(void)
 
 /*
  * Generic function to fsync a file.
- *
- * filp may be NULL if called via the msync of a vma.
  */
-int file_fsync(struct file *filp, struct dentry *dentry, int datasync)
+int file_fsync(struct file *filp, int datasync)
 {
-       struct inode * inode = dentry->d_inode;
+       struct inode *inode = filp->f_mapping->host;
        struct super_block * sb;
        int ret, err;
 
@@ -183,7 +181,7 @@ int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync)
         * livelocks in fsync_buffers_list().
         */
        mutex_lock(&mapping->host->i_mutex);
-       err = file->f_op->fsync(file, file->f_path.dentry, datasync);
+       err = file->f_op->fsync(file, datasync);
        if (!ret)
                ret = err;
        mutex_unlock(&mapping->host->i_mutex);
index bbd77e9..bde1a4c 100644 (file)
@@ -117,13 +117,11 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr)
        if (error)
                goto out;
 
-       iattr->ia_valid &= ~ATTR_SIZE; /* ignore size changes */
-
-       error = inode_setattr(inode, iattr);
-       if (error)
-               goto out;
+       /* this ignores size changes */
+       generic_setattr(inode, iattr);
 
        error = sysfs_sd_setattr(sd, iattr);
+
 out:
        mutex_unlock(&sysfs_mutex);
        return error;
index 1dabed2..79941e4 100644 (file)
@@ -24,7 +24,7 @@ const struct file_operations sysv_dir_operations = {
        .llseek         = generic_file_llseek,
        .read           = generic_read_dir,
        .readdir        = sysv_readdir,
-       .fsync          = simple_fsync,
+       .fsync          = generic_file_fsync,
 };
 
 static inline void dir_put_page(struct page *page)
index 96340c0..750cc22 100644 (file)
@@ -26,7 +26,7 @@ const struct file_operations sysv_file_operations = {
        .write          = do_sync_write,
        .aio_write      = generic_file_aio_write,
        .mmap           = generic_file_mmap,
-       .fsync          = simple_fsync,
+       .fsync          = generic_file_fsync,
        .splice_read    = generic_file_splice_read,
 };
 
index 4573734..d4a5380 100644 (file)
@@ -43,6 +43,7 @@ static int sysv_sync_fs(struct super_block *sb, int wait)
         * then attach current time stamp.
         * But if the filesystem was marked clean, keep it clean.
         */
+       sb->s_dirt = 0;
        old_time = fs32_to_cpu(sbi, *sbi->s_sb_time);
        if (sbi->s_type == FSTYPE_SYSV4) {
                if (*sbi->s_sb_state == cpu_to_fs32(sbi, 0x7c269d38 - old_time))
index 5692cf7..12f445c 100644 (file)
@@ -967,12 +967,15 @@ static int do_writepage(struct page *page, int len)
  * the page locked, and it locks @ui_mutex. However, write-back does take inode
  * @i_mutex, which means other VFS operations may be run on this inode at the
  * same time. And the problematic one is truncation to smaller size, from where
- * we have to call 'vmtruncate()', which first changes @inode->i_size, then
+ * we have to call 'simple_setsize()', which first changes @inode->i_size, then
  * drops the truncated pages. And while dropping the pages, it takes the page
- * lock. This means that 'do_truncation()' cannot call 'vmtruncate()' with
+ * lock. This means that 'do_truncation()' cannot call 'simple_setsize()' with
  * @ui_mutex locked, because it would deadlock with 'ubifs_writepage()'. This
  * means that @inode->i_size is changed while @ui_mutex is unlocked.
  *
+ * XXX: with the new truncate the above is not true anymore, the simple_setsize
+ * calls can be replaced with the individual components.
+ *
  * But in 'ubifs_writepage()' we have to guarantee that we do not write beyond
  * inode size. How do we do this if @inode->i_size may became smaller while we
  * are in the middle of 'ubifs_writepage()'? The UBIFS solution is the
@@ -1125,7 +1128,7 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode,
                budgeted = 0;
        }
 
-       err = vmtruncate(inode, new_size);
+       err = simple_setsize(inode, new_size);
        if (err)
                goto out_budg;
 
@@ -1214,7 +1217,7 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode,
 
        if (attr->ia_valid & ATTR_SIZE) {
                dbg_gen("size %lld -> %lld", inode->i_size, new_size);
-               err = vmtruncate(inode, new_size);
+               err = simple_setsize(inode, new_size);
                if (err)
                        goto out;
        }
@@ -1223,7 +1226,7 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode,
        if (attr->ia_valid & ATTR_SIZE) {
                /* Truncation changes inode [mc]time */
                inode->i_mtime = inode->i_ctime = ubifs_current_time(inode);
-               /* 'vmtruncate()' changed @i_size, update @ui_size */
+               /* 'simple_setsize()' changed @i_size, update @ui_size */
                ui->ui_size = inode->i_size;
        }
 
@@ -1304,9 +1307,9 @@ static void *ubifs_follow_link(struct dentry *dentry, struct nameidata *nd)
        return NULL;
 }
 
-int ubifs_fsync(struct file *file, struct dentry *dentry, int datasync)
+int ubifs_fsync(struct file *file, int datasync)
 {
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = file->f_mapping->host;
        struct ubifs_info *c = inode->i_sb->s_fs_info;
        int err;
 
index bd2542d..2eef553 100644 (file)
@@ -379,7 +379,7 @@ struct ubifs_gced_idx_leb {
  * The @ui_size is a "shadow" variable for @inode->i_size and UBIFS uses
  * @ui_size instead of @inode->i_size. The reason for this is that UBIFS cannot
  * make sure @inode->i_size is always changed under @ui_mutex, because it
- * cannot call 'vmtruncate()' with @ui_mutex locked, because it would deadlock
+ * cannot call 'simple_setsize()' with @ui_mutex locked, because it would deadlock
  * with 'ubifs_writepage()' (see file.c). All the other inode fields are
  * changed under @ui_mutex, so they do not need "shadow" fields. Note, one
  * could consider to rework locking and base it on "shadow" fields.
@@ -1678,7 +1678,7 @@ const struct ubifs_lprops *ubifs_fast_find_frdi_idx(struct ubifs_info *c);
 int ubifs_calc_dark(const struct ubifs_info *c, int spc);
 
 /* file.c */
-int ubifs_fsync(struct file *file, struct dentry *dentry, int datasync);
+int ubifs_fsync(struct file *file, int datasync);
 int ubifs_setattr(struct dentry *dentry, struct iattr *attr);
 
 /* dir.c */
index 1660c81..51552bf 100644 (file)
@@ -211,5 +211,5 @@ const struct file_operations udf_dir_operations = {
        .read                   = generic_read_dir,
        .readdir                = udf_readdir,
        .unlocked_ioctl         = udf_ioctl,
-       .fsync                  = simple_fsync,
+       .fsync                  = generic_file_fsync,
 };
index baae3a7..0660280 100644 (file)
@@ -224,7 +224,7 @@ const struct file_operations udf_file_operations = {
        .write                  = do_sync_write,
        .aio_write              = udf_file_aio_write,
        .release                = udf_release_file,
-       .fsync                  = simple_fsync,
+       .fsync                  = generic_file_fsync,
        .splice_read            = generic_file_splice_read,
        .llseek                 = generic_file_llseek,
 };
index 317a0d4..ec78475 100644 (file)
@@ -666,6 +666,6 @@ not_empty:
 const struct file_operations ufs_dir_operations = {
        .read           = generic_read_dir,
        .readdir        = ufs_readdir,
-       .fsync          = simple_fsync,
+       .fsync          = generic_file_fsync,
        .llseek         = generic_file_llseek,
 };
index a8962ce..d4c30d1 100644 (file)
@@ -42,6 +42,6 @@ const struct file_operations ufs_file_operations = {
        .aio_write      = generic_file_aio_write,
        .mmap           = generic_file_mmap,
        .open           = dquot_file_open,
-       .fsync          = simple_fsync,
+       .fsync          = generic_file_fsync,
        .splice_read    = generic_file_splice_read,
 };
index f294c44..3733057 100644 (file)
@@ -501,12 +501,10 @@ out:
        return err;
 }
 
-
 /*
- * We don't define our `inode->i_op->truncate', and call it here,
- * because of:
- * - there is no way to know old size
- * - there is no way inform user about error, if it happens in `truncate'
+ * TODO:
+ *     - truncate case should use proper ordering instead of using
+ *       simple_setsize
  */
 int ufs_setattr(struct dentry *dentry, struct iattr *attr)
 {
@@ -530,7 +528,7 @@ int ufs_setattr(struct dentry *dentry, struct iattr *attr)
        if (ia_valid & ATTR_SIZE && attr->ia_size != inode->i_size) {
                loff_t old_i_size = inode->i_size;
 
-               error = vmtruncate(inode, attr->ia_size);
+               error = simple_setsize(inode, attr->ia_size);
                if (error)
                        return error;
                error = ufs_truncate(inode, old_i_size);
index d8fb1b5..257a56b 100644 (file)
@@ -100,10 +100,10 @@ xfs_iozero(
 STATIC int
 xfs_file_fsync(
        struct file             *file,
-       struct dentry           *dentry,
        int                     datasync)
 {
-       struct xfs_inode        *ip = XFS_I(dentry->d_inode);
+       struct inode            *inode = file->f_mapping->host;
+       struct xfs_inode        *ip = XFS_I(inode);
        struct xfs_trans        *tp;
        int                     error = 0;
        int                     log_flushed = 0;
@@ -140,8 +140,8 @@ xfs_file_fsync(
         * might gets cleared when the inode gets written out via the AIL
         * or xfs_iflush_cluster.
         */
-       if (((dentry->d_inode->i_state & I_DIRTY_DATASYNC) ||
-           ((dentry->d_inode->i_state & I_DIRTY_SYNC) && !datasync)) &&
+       if (((inode->i_state & I_DIRTY_DATASYNC) ||
+           ((inode->i_state & I_DIRTY_SYNC) && !datasync)) &&
            ip->i_update_core) {
                /*
                 * Kick off a transaction to log the inode core to get the
@@ -868,7 +868,7 @@ write_retry:
                        mutex_lock(&inode->i_mutex);
                xfs_ilock(ip, iolock);
 
-               error2 = -xfs_file_fsync(file, file->f_path.dentry,
+               error2 = -xfs_file_fsync(file,
                                         (file->f_flags & __O_SYNC) ? 0 : 1);
                if (!error)
                        error = error2;
index 16ed028..1b9ba19 100644 (file)
@@ -203,6 +203,9 @@ int block_write_full_page_endio(struct page *page, get_block_t *get_block,
 int block_read_full_page(struct page*, get_block_t*);
 int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc,
                                unsigned long from);
+int block_write_begin_newtrunc(struct file *, struct address_space *,
+                               loff_t, unsigned, unsigned,
+                               struct page **, void **, get_block_t*);
 int block_write_begin(struct file *, struct address_space *,
                                loff_t, unsigned, unsigned,
                                struct page **, void **, get_block_t*);
@@ -214,6 +217,9 @@ int generic_write_end(struct file *, struct address_space *,
                                struct page *, void *);
 void page_zero_new_buffers(struct page *page, unsigned from, unsigned to);
 int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*);
+int cont_write_begin_newtrunc(struct file *, struct address_space *, loff_t,
+                       unsigned, unsigned, struct page **, void **,
+                       get_block_t *, loff_t *);
 int cont_write_begin(struct file *, struct address_space *, loff_t,
                        unsigned, unsigned, struct page **, void **,
                        get_block_t *, loff_t *);
@@ -224,7 +230,10 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
 void block_sync_page(struct page *);
 sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *);
 int block_truncate_page(struct address_space *, loff_t, get_block_t *);
-int file_fsync(struct file *, struct dentry *, int);
+int file_fsync(struct file *, int);
+int nobh_write_begin_newtrunc(struct file *, struct address_space *,
+                               loff_t, unsigned, unsigned,
+                               struct page **, void **, get_block_t*);
 int nobh_write_begin(struct file *, struct address_space *,
                                loff_t, unsigned, unsigned,
                                struct page **, void **, get_block_t*);
index 5f494b4..7fc62d4 100644 (file)
@@ -868,7 +868,7 @@ extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
 extern void ext3_htree_free_dir_info(struct dir_private_info *p);
 
 /* fsync.c */
-extern int ext3_sync_file (struct file *, struct dentry *, int);
+extern int ext3_sync_file(struct file *, int);
 
 /* hash.c */
 extern int ext3fs_dirhash(const char *name, int len, struct
index f3793eb..907ace3 100644 (file)
@@ -4,8 +4,6 @@
 #include <linux/types.h>
 #include <linux/i2c.h>
 
-struct dentry;
-
 /* Definitions of frame buffers                                                */
 
 #define FB_MAX                 32      /* sufficient for now */
@@ -1017,8 +1015,7 @@ extern void fb_deferred_io_open(struct fb_info *info,
                                struct inode *inode,
                                struct file *file);
 extern void fb_deferred_io_cleanup(struct fb_info *info);
-extern int fb_deferred_io_fsync(struct file *file, struct dentry *dentry,
-                               int datasync);
+extern int fb_deferred_io_fsync(struct file *file, int datasync);
 
 static inline bool fb_be_math(struct fb_info *info)
 {
index 5555508..b1e1297 100644 (file)
@@ -11,7 +11,6 @@
 
 struct file;
 
-extern void __fput(struct file *);
 extern void fput(struct file *);
 extern void drop_file_write_access(struct file *file);
 
index 85e823a..3428393 100644 (file)
@@ -954,6 +954,7 @@ extern spinlock_t files_lock;
 #define file_list_unlock() spin_unlock(&files_lock);
 
 #define get_file(x)    atomic_long_inc(&(x)->f_count)
+#define fput_atomic(x) atomic_long_add_unless(&(x)->f_count, -1, 1)
 #define file_count(x)  atomic_long_read(&(x)->f_count)
 
 #ifdef CONFIG_DEBUG_WRITECOUNT
@@ -1497,7 +1498,7 @@ struct file_operations {
        int (*open) (struct inode *, struct file *);
        int (*flush) (struct file *, fl_owner_t id);
        int (*release) (struct inode *, struct file *);
-       int (*fsync) (struct file *, struct dentry *, int datasync);
+       int (*fsync) (struct file *, int datasync);
        int (*aio_fsync) (struct kiocb *, int datasync);
        int (*fasync) (int, struct file *, int);
        int (*lock) (struct file *, int, struct file_lock *);
@@ -2212,7 +2213,7 @@ extern int generic_segment_checks(const struct iovec *iov,
 /* fs/block_dev.c */
 extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
                                unsigned long nr_segs, loff_t pos);
-extern int blkdev_fsync(struct file *filp, struct dentry *dentry, int datasync);
+extern int blkdev_fsync(struct file *filp, int datasync);
 
 /* fs/splice.c */
 extern ssize_t generic_file_splice_read(struct file *, loff_t *,
@@ -2256,6 +2257,10 @@ typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode,
                            loff_t file_offset);
 void dio_end_io(struct bio *bio, int error);
 
+ssize_t __blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb, struct inode *inode,
+       struct block_device *bdev, const struct iovec *iov, loff_t offset,
+       unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
+       dio_submit_t submit_io, int lock_type);
 ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
        struct block_device *bdev, const struct iovec *iov, loff_t offset,
        unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
@@ -2269,6 +2274,24 @@ enum {
        DIO_SKIP_HOLES  = 0x02,
 };
 
+static inline ssize_t blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb,
+       struct inode *inode, struct block_device *bdev, const struct iovec *iov,
+       loff_t offset, unsigned long nr_segs, get_block_t get_block,
+       dio_iodone_t end_io)
+{
+       return __blockdev_direct_IO_newtrunc(rw, iocb, inode, bdev, iov, offset,
+                                   nr_segs, get_block, end_io, NULL,
+                                   DIO_LOCKING | DIO_SKIP_HOLES);
+}
+
+static inline ssize_t blockdev_direct_IO_no_locking_newtrunc(int rw, struct kiocb *iocb,
+       struct inode *inode, struct block_device *bdev, const struct iovec *iov,
+       loff_t offset, unsigned long nr_segs, get_block_t get_block,
+       dio_iodone_t end_io)
+{
+       return __blockdev_direct_IO_newtrunc(rw, iocb, inode, bdev, iov, offset,
+                               nr_segs, get_block, end_io, NULL, 0);
+}
 static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb,
        struct inode *inode, struct block_device *bdev, const struct iovec *iov,
        loff_t offset, unsigned long nr_segs, get_block_t get_block,
@@ -2341,13 +2364,15 @@ extern int dcache_dir_open(struct inode *, struct file *);
 extern int dcache_dir_close(struct inode *, struct file *);
 extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
 extern int dcache_readdir(struct file *, void *, filldir_t);
+extern int simple_setattr(struct dentry *, struct iattr *);
 extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
 extern int simple_statfs(struct dentry *, struct kstatfs *);
 extern int simple_link(struct dentry *, struct inode *, struct dentry *);
 extern int simple_unlink(struct inode *, struct dentry *);
 extern int simple_rmdir(struct inode *, struct dentry *);
 extern int simple_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
-extern int simple_sync_file(struct file *, struct dentry *, int);
+extern int simple_setsize(struct inode *, loff_t);
+extern int noop_fsync(struct file *, int);
 extern int simple_empty(struct dentry *);
 extern int simple_readpage(struct file *file, struct page *page);
 extern int simple_write_begin(struct file *file, struct address_space *mapping,
@@ -2372,7 +2397,7 @@ extern ssize_t simple_read_from_buffer(void __user *to, size_t count,
 extern ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos,
                const void __user *from, size_t count);
 
-extern int simple_fsync(struct file *, struct dentry *, int);
+extern int generic_file_fsync(struct file *, int);
 
 #ifdef CONFIG_MIGRATION
 extern int buffer_migrate_page(struct address_space *,
@@ -2383,7 +2408,8 @@ extern int buffer_migrate_page(struct address_space *,
 
 extern int inode_change_ok(const struct inode *, struct iattr *);
 extern int inode_newsize_ok(const struct inode *, loff_t offset);
-extern int __must_check inode_setattr(struct inode *, struct iattr *);
+extern int __must_check inode_setattr(struct inode *, const struct iattr *);
+extern void generic_setattr(struct inode *inode, const struct iattr *attr);
 
 extern void file_update_time(struct file *file);
 
index ee84e7e..3bad270 100644 (file)
@@ -386,6 +386,7 @@ enum {
        ATA_HORKAGE_1_5_GBPS    = (1 << 13),    /* force 1.5 Gbps */
        ATA_HORKAGE_NOSETXFER   = (1 << 14),    /* skip SETXFER, SATA only */
        ATA_HORKAGE_BROKEN_FPDMA_AA     = (1 << 15),    /* skip AA */
+       ATA_HORKAGE_DUMP_ID     = (1 << 16),    /* dump IDENTIFY data */
 
         /* DMA mask for user DMA control: User visible values; DO NOT
            renumber */
@@ -513,7 +514,9 @@ struct ata_ioports {
        void __iomem            *command_addr;
        void __iomem            *altstatus_addr;
        void __iomem            *ctl_addr;
+#ifdef CONFIG_ATA_BMDMA
        void __iomem            *bmdma_addr;
+#endif /* CONFIG_ATA_BMDMA */
        void __iomem            *scr_addr;
 };
 #endif /* CONFIG_ATA_SFF */
@@ -721,8 +724,10 @@ struct ata_port {
        u8                      ctl;    /* cache of ATA control register */
        u8                      last_ctl;       /* Cache last written value */
        struct delayed_work     sff_pio_task;
+#ifdef CONFIG_ATA_BMDMA
        struct ata_bmdma_prd    *bmdma_prd;     /* BMDMA SG list */
        dma_addr_t              bmdma_prd_dma;  /* and its DMA mapping */
+#endif /* CONFIG_ATA_BMDMA */
 #endif /* CONFIG_ATA_SFF */
 
        unsigned int            pio_mask;
@@ -856,10 +861,12 @@ struct ata_port_operations {
        void (*sff_irq_clear)(struct ata_port *);
        void (*sff_drain_fifo)(struct ata_queued_cmd *qc);
 
+#ifdef CONFIG_ATA_BMDMA
        void (*bmdma_setup)(struct ata_queued_cmd *qc);
        void (*bmdma_start)(struct ata_queued_cmd *qc);
        void (*bmdma_stop)(struct ata_queued_cmd *qc);
        u8   (*bmdma_status)(struct ata_port *ap);
+#endif /* CONFIG_ATA_BMDMA */
 #endif /* CONFIG_ATA_SFF */
 
        ssize_t (*em_show)(struct ata_port *ap, char *buf);
@@ -1555,7 +1562,6 @@ extern void sata_pmp_error_handler(struct ata_port *ap);
 #ifdef CONFIG_ATA_SFF
 
 extern const struct ata_port_operations ata_sff_port_ops;
-extern const struct ata_port_operations ata_bmdma_port_ops;
 extern const struct ata_port_operations ata_bmdma32_port_ops;
 
 /* PIO only, sg_tablesize and dma_boundary limits can be removed */
@@ -1564,11 +1570,6 @@ extern const struct ata_port_operations ata_bmdma32_port_ops;
        .sg_tablesize           = LIBATA_MAX_PRD,               \
        .dma_boundary           = ATA_DMA_BOUNDARY
 
-#define ATA_BMDMA_SHT(drv_name)                                        \
-       ATA_BASE_SHT(drv_name),                                 \
-       .sg_tablesize           = LIBATA_MAX_PRD,               \
-       .dma_boundary           = ATA_DMA_BOUNDARY
-
 extern void ata_sff_dev_select(struct ata_port *ap, unsigned int device);
 extern u8 ata_sff_check_status(struct ata_port *ap);
 extern void ata_sff_pause(struct ata_port *ap);
@@ -1593,7 +1594,7 @@ extern int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
 extern void ata_sff_queue_pio_task(struct ata_port *ap, unsigned long delay);
 extern unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc);
 extern bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc);
-extern unsigned int ata_sff_host_intr(struct ata_port *ap,
+extern unsigned int ata_sff_port_intr(struct ata_port *ap,
                                      struct ata_queued_cmd *qc);
 extern irqreturn_t ata_sff_interrupt(int irq, void *dev_instance);
 extern void ata_sff_lost_interrupt(struct ata_port *ap);
@@ -1625,11 +1626,24 @@ extern int ata_pci_sff_init_one(struct pci_dev *pdev,
                struct scsi_host_template *sht, void *host_priv, int hflags);
 #endif /* CONFIG_PCI */
 
+#ifdef CONFIG_ATA_BMDMA
+
+extern const struct ata_port_operations ata_bmdma_port_ops;
+
+#define ATA_BMDMA_SHT(drv_name)                                        \
+       ATA_BASE_SHT(drv_name),                                 \
+       .sg_tablesize           = LIBATA_MAX_PRD,               \
+       .dma_boundary           = ATA_DMA_BOUNDARY
+
 extern void ata_bmdma_qc_prep(struct ata_queued_cmd *qc);
 extern unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc);
 extern void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc);
+extern unsigned int ata_bmdma_port_intr(struct ata_port *ap,
+                                     struct ata_queued_cmd *qc);
+extern irqreturn_t ata_bmdma_interrupt(int irq, void *dev_instance);
 extern void ata_bmdma_error_handler(struct ata_port *ap);
 extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc);
+extern void ata_bmdma_irq_clear(struct ata_port *ap);
 extern void ata_bmdma_setup(struct ata_queued_cmd *qc);
 extern void ata_bmdma_start(struct ata_queued_cmd *qc);
 extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
@@ -1640,7 +1654,15 @@ extern int ata_bmdma_port_start32(struct ata_port *ap);
 #ifdef CONFIG_PCI
 extern int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev);
 extern void ata_pci_bmdma_init(struct ata_host *host);
+extern int ata_pci_bmdma_prepare_host(struct pci_dev *pdev,
+                                     const struct ata_port_info * const * ppi,
+                                     struct ata_host **r_host);
+extern int ata_pci_bmdma_init_one(struct pci_dev *pdev,
+                                 const struct ata_port_info * const * ppi,
+                                 struct scsi_host_template *sht,
+                                 void *host_priv, int hflags);
 #endif /* CONFIG_PCI */
+#endif /* CONFIG_ATA_BMDMA */
 
 /**
  *     ata_sff_busy_wait - Wait for a port status register
index 6cf4486..726cc35 100644 (file)
@@ -39,7 +39,7 @@ extern int net_cls_subsys_id;
 static inline u32 task_cls_classid(struct task_struct *p)
 {
        int id;
-       u32 classid;
+       u32 classid = 0;
 
        if (in_interrupt())
                return 0;
index 6173c61..4b86011 100644 (file)
@@ -876,7 +876,7 @@ struct sctp_transport {
 
        /* Reference counting. */
        atomic_t refcnt;
-       int      dead:1,
+       __u32    dead:1,
                /* RTO-Pending : A flag used to track if one of the DATA
                 *              chunks sent to this address is currently being
                 *              used to compute a RTT. If this flag is 0,
index d2a71b0..ca241ea 100644 (file)
@@ -1026,15 +1026,23 @@ extern void release_sock(struct sock *sk);
                                SINGLE_DEPTH_NESTING)
 #define bh_unlock_sock(__sk)   spin_unlock(&((__sk)->sk_lock.slock))
 
-static inline void lock_sock_bh(struct sock *sk)
+extern bool lock_sock_fast(struct sock *sk);
+/**
+ * unlock_sock_fast - complement of lock_sock_fast
+ * @sk: socket
+ * @slow: slow mode
+ *
+ * fast unlock socket for user context.
+ * If slow mode is on, we call regular release_sock()
+ */
+static inline void unlock_sock_fast(struct sock *sk, bool slow)
 {
-       spin_lock_bh(&sk->sk_lock.slock);
+       if (slow)
+               release_sock(sk);
+       else
+               spin_unlock_bh(&sk->sk_lock.slock);
 }
 
-static inline void unlock_sock_bh(struct sock *sk)
-{
-       spin_unlock_bh(&sk->sk_lock.slock);
-}
 
 extern struct sock             *sk_alloc(struct net *net, int family,
                                          gfp_t priority,
index 5d60ad4..f5b1ba9 100644 (file)
@@ -606,9 +606,9 @@ TRACE_EVENT(ext4_free_blocks,
 );
 
 TRACE_EVENT(ext4_sync_file,
-       TP_PROTO(struct file *file, struct dentry *dentry, int datasync),
+       TP_PROTO(struct file *file, int datasync),
 
-       TP_ARGS(file, dentry, datasync),
+       TP_ARGS(file, datasync),
 
        TP_STRUCT__entry(
                __field(        dev_t,  dev                     )
@@ -618,6 +618,8 @@ TRACE_EVENT(ext4_sync_file,
        ),
 
        TP_fast_assign(
+               struct dentry *dentry = file->f_path.dentry;
+
                __entry->dev            = dentry->d_inode->i_sb->s_dev;
                __entry->ino            = dentry->d_inode->i_ino;
                __entry->datasync       = datasync;
index 1a314c8..52ed77e 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -273,16 +273,13 @@ static int shm_release(struct inode *ino, struct file *file)
        return 0;
 }
 
-static int shm_fsync(struct file *file, struct dentry *dentry, int datasync)
+static int shm_fsync(struct file *file, int datasync)
 {
-       int (*fsync) (struct file *, struct dentry *, int datasync);
        struct shm_file_data *sfd = shm_file_data(file);
-       int ret = -EINVAL;
 
-       fsync = sfd->file->f_op->fsync;
-       if (fsync)
-               ret = fsync(sfd->file, sfd->file->f_path.dentry, datasync);
-       return ret;
+       if (!sfd->file->f_op->fsync)
+               return -EINVAL;
+       return sfd->file->f_op->fsync(sfd->file, datasync);
 }
 
 static unsigned long shm_get_unmapped_area(struct file *file,
index b9b134b..5c69e99 100644 (file)
@@ -89,7 +89,7 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base)
 
        do {
                seq = read_seqbegin(&xtime_lock);
-               xts = current_kernel_time();
+               xts = __current_kernel_time();
                tom = wall_to_monotonic;
        } while (read_seqretry(&xtime_lock, seq));
 
index e099650..bd7ce8c 100644 (file)
@@ -4999,8 +4999,8 @@ SYSCALL_DEFINE5(perf_event_open,
        struct perf_event_context *ctx;
        struct file *event_file = NULL;
        struct file *group_file = NULL;
+       int event_fd;
        int fput_needed = 0;
-       int fput_needed2 = 0;
        int err;
 
        /* for future expandability... */
@@ -5021,12 +5021,18 @@ SYSCALL_DEFINE5(perf_event_open,
                        return -EINVAL;
        }
 
+       event_fd = get_unused_fd_flags(O_RDWR);
+       if (event_fd < 0)
+               return event_fd;
+
        /*
         * Get the target context (task or percpu):
         */
        ctx = find_get_context(pid, cpu);
-       if (IS_ERR(ctx))
-               return PTR_ERR(ctx);
+       if (IS_ERR(ctx)) {
+               err = PTR_ERR(ctx);
+               goto err_fd;
+       }
 
        /*
         * Look up the group leader (we will attach this event to it):
@@ -5066,13 +5072,11 @@ SYSCALL_DEFINE5(perf_event_open,
        if (IS_ERR(event))
                goto err_put_context;
 
-       err = anon_inode_getfd("[perf_event]", &perf_fops, event, O_RDWR);
-       if (err < 0)
-               goto err_free_put_context;
-
-       event_file = fget_light(err, &fput_needed2);
-       if (!event_file)
+       event_file = anon_inode_getfile("[perf_event]", &perf_fops, event, O_RDWR);
+       if (IS_ERR(event_file)) {
+               err = PTR_ERR(event_file);
                goto err_free_put_context;
+       }
 
        if (flags & PERF_FLAG_FD_OUTPUT) {
                err = perf_event_set_output(event, group_fd);
@@ -5093,19 +5097,19 @@ SYSCALL_DEFINE5(perf_event_open,
        list_add_tail(&event->owner_entry, &current->perf_event_list);
        mutex_unlock(&current->perf_event_mutex);
 
-err_fput_free_put_context:
-       fput_light(event_file, fput_needed2);
+       fput_light(group_file, fput_needed);
+       fd_install(event_fd, event_file);
+       return event_fd;
 
+err_fput_free_put_context:
+       fput(event_file);
 err_free_put_context:
-       if (err < 0)
-               free_event(event);
-
+       free_event(event);
 err_put_context:
-       if (err < 0)
-               put_ctx(ctx);
-
        fput_light(group_file, fput_needed);
-
+       put_ctx(ctx);
+err_fd:
+       put_unused_fd(event_fd);
        return err;
 }
 
index 00d1fda..ad72342 100644 (file)
@@ -559,14 +559,7 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
        new_timer->it_id = (timer_t) new_timer_id;
        new_timer->it_clock = which_clock;
        new_timer->it_overrun = -1;
-       error = CLOCK_DISPATCH(which_clock, timer_create, (new_timer));
-       if (error)
-               goto out;
 
-       /*
-        * return the timer_id now.  The next step is hard to
-        * back out if there is an error.
-        */
        if (copy_to_user(created_timer_id,
                         &new_timer_id, sizeof (new_timer_id))) {
                error = -EFAULT;
@@ -597,6 +590,10 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
        new_timer->sigq->info.si_tid   = new_timer->it_id;
        new_timer->sigq->info.si_code  = SI_TIMER;
 
+       error = CLOCK_DISPATCH(which_clock, timer_create, (new_timer));
+       if (error)
+               goto out;
+
        spin_lock_irq(&current->sighand->siglock);
        new_timer->it_signal = current->signal;
        list_add(&new_timer->list, &current->signal->posix_timers);
index e3b8c69..2454172 100644 (file)
@@ -752,11 +752,15 @@ unsigned long apply_slack(struct timer_list *timer, unsigned long expires)
 
        expires_limit = expires;
 
-       if (timer->slack > -1)
+       if (timer->slack >= 0) {
                expires_limit = expires + timer->slack;
-       else if (time_after(expires, jiffies)) /* auto slack: use 0.4% */
-               expires_limit = expires + (expires - jiffies)/256;
+       } else {
+               unsigned long now = jiffies;
 
+               /* No slack, if already expired else auto slack 0.4% */
+               if (time_after(expires, now))
+                       expires_limit = expires + (expires - now)/256;
+       }
        mask = expires ^ expires_limit;
        if (mask == 0)
                return expires;
index 855eaf5..7e5030a 100644 (file)
@@ -727,10 +727,11 @@ done2:
        if (inode->i_mapping->nrpages && (info->flags & SHMEM_PAGEIN)) {
                /*
                 * Call truncate_inode_pages again: racing shmem_unuse_inode
-                * may have swizzled a page in from swap since vmtruncate or
-                * generic_delete_inode did it, before we lowered next_index.
-                * Also, though shmem_getpage checks i_size before adding to
-                * cache, no recheck after: so fix the narrow window there too.
+                * may have swizzled a page in from swap since
+                * truncate_pagecache or generic_delete_inode did it, before we
+                * lowered next_index.  Also, though shmem_getpage checks
+                * i_size before adding to cache, no recheck after: so fix the
+                * narrow window there too.
                 *
                 * Recalling truncate_inode_pages_range and unmap_mapping_range
                 * every time for punch_hole (which never got a chance to clear
@@ -760,19 +761,16 @@ done2:
        }
 }
 
-static void shmem_truncate(struct inode *inode)
-{
-       shmem_truncate_range(inode, inode->i_size, (loff_t)-1);
-}
-
 static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
 {
        struct inode *inode = dentry->d_inode;
-       struct page *page = NULL;
        int error;
 
        if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) {
-               if (attr->ia_size < inode->i_size) {
+               loff_t newsize = attr->ia_size;
+               struct page *page = NULL;
+
+               if (newsize < inode->i_size) {
                        /*
                         * If truncating down to a partial page, then
                         * if that page is already allocated, hold it
@@ -780,9 +778,9 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
                         * truncate_partial_page cannnot miss it were
                         * it assigned to swap.
                         */
-                       if (attr->ia_size & (PAGE_CACHE_SIZE-1)) {
+                       if (newsize & (PAGE_CACHE_SIZE-1)) {
                                (void) shmem_getpage(inode,
-                                       attr->ia_size>>PAGE_CACHE_SHIFT,
+                                       newsize >> PAGE_CACHE_SHIFT,
                                                &page, SGP_READ, NULL);
                                if (page)
                                        unlock_page(page);
@@ -794,24 +792,29 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
                         * if it's being fully truncated to zero-length: the
                         * nrpages check is efficient enough in that case.
                         */
-                       if (attr->ia_size) {
+                       if (newsize) {
                                struct shmem_inode_info *info = SHMEM_I(inode);
                                spin_lock(&info->lock);
                                info->flags &= ~SHMEM_PAGEIN;
                                spin_unlock(&info->lock);
                        }
                }
+
+               error = simple_setsize(inode, newsize);
+               if (page)
+                       page_cache_release(page);
+               if (error)
+                       return error;
+               shmem_truncate_range(inode, newsize, (loff_t)-1);
        }
 
        error = inode_change_ok(inode, attr);
        if (!error)
-               error = inode_setattr(inode, attr);
+               generic_setattr(inode, attr);
 #ifdef CONFIG_TMPFS_POSIX_ACL
        if (!error && (attr->ia_valid & ATTR_MODE))
                error = generic_acl_chmod(inode);
 #endif
-       if (page)
-               page_cache_release(page);
        return error;
 }
 
@@ -819,11 +822,11 @@ static void shmem_delete_inode(struct inode *inode)
 {
        struct shmem_inode_info *info = SHMEM_I(inode);
 
-       if (inode->i_op->truncate == shmem_truncate) {
+       if (inode->i_mapping->a_ops == &shmem_aops) {
                truncate_inode_pages(inode->i_mapping, 0);
                shmem_unacct_size(info->flags, inode->i_size);
                inode->i_size = 0;
-               shmem_truncate(inode);
+               shmem_truncate_range(inode, 0, (loff_t)-1);
                if (!list_empty(&info->swaplist)) {
                        mutex_lock(&shmem_swaplist_mutex);
                        list_del_init(&info->swaplist);
@@ -2022,7 +2025,6 @@ static const struct inode_operations shmem_symlink_inline_operations = {
 };
 
 static const struct inode_operations shmem_symlink_inode_operations = {
-       .truncate       = shmem_truncate,
        .readlink       = generic_readlink,
        .follow_link    = shmem_follow_link,
        .put_link       = shmem_put_link,
@@ -2433,14 +2435,13 @@ static const struct file_operations shmem_file_operations = {
        .write          = do_sync_write,
        .aio_read       = shmem_file_aio_read,
        .aio_write      = generic_file_aio_write,
-       .fsync          = simple_sync_file,
+       .fsync          = noop_fsync,
        .splice_read    = generic_file_splice_read,
        .splice_write   = generic_file_splice_write,
 #endif
 };
 
 static const struct inode_operations shmem_inode_operations = {
-       .truncate       = shmem_truncate,
        .setattr        = shmem_notify_change,
        .truncate_range = shmem_truncate_range,
 #ifdef CONFIG_TMPFS_POSIX_ACL
index f42675a..937571b 100644 (file)
@@ -548,18 +548,18 @@ EXPORT_SYMBOL(truncate_pagecache);
  * NOTE! We have to be ready to update the memory sharing
  * between the file and the memory map for a potential last
  * incomplete page.  Ugly, but necessary.
+ *
+ * This function is deprecated and simple_setsize or truncate_pagecache
+ * should be used instead.
  */
 int vmtruncate(struct inode *inode, loff_t offset)
 {
-       loff_t oldsize;
        int error;
 
-       error = inode_newsize_ok(inode, offset);
+       error = simple_setsize(inode, offset);
        if (error)
                return error;
-       oldsize = inode->i_size;
-       i_size_write(inode, offset);
-       truncate_pagecache(inode, oldsize, offset);
+
        if (inode->i_op->truncate)
                inode->i_op->truncate(inode);
 
index e009753..f5b6f43 100644 (file)
@@ -229,15 +229,17 @@ EXPORT_SYMBOL(skb_free_datagram);
 
 void skb_free_datagram_locked(struct sock *sk, struct sk_buff *skb)
 {
+       bool slow;
+
        if (likely(atomic_read(&skb->users) == 1))
                smp_rmb();
        else if (likely(!atomic_dec_and_test(&skb->users)))
                return;
 
-       lock_sock_bh(sk);
+       slow = lock_sock_fast(sk);
        skb_orphan(skb);
        sk_mem_reclaim_partial(sk);
-       unlock_sock_bh(sk);
+       unlock_sock_fast(sk, slow);
 
        /* skb is now orphaned, can be freed outside of locked section */
        __kfree_skb(skb);
index bff3790..6ba1c0e 100644 (file)
@@ -934,6 +934,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
                                kfree_skb(buff);
                                NEIGH_CACHE_STAT_INC(neigh->tbl, unres_discards);
                        }
+                       skb_dst_force(skb);
                        __skb_queue_tail(&neigh->arp_queue, skb);
                }
                rc = 1;
index 7ab86f3..1a2af24 100644 (file)
@@ -650,11 +650,12 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev)
        if (dev->dev.parent && dev_is_pci(dev->dev.parent)) {
 
                int num_vfs = dev_num_vf(dev->dev.parent);
-               size_t size = nlmsg_total_size(sizeof(struct nlattr));
-               size += nlmsg_total_size(num_vfs * sizeof(struct nlattr));
-               size += num_vfs * (sizeof(struct ifla_vf_mac) +
-                                 sizeof(struct ifla_vf_vlan) +
-                                 sizeof(struct ifla_vf_tx_rate));
+               size_t size = nla_total_size(sizeof(struct nlattr));
+               size += nla_total_size(num_vfs * sizeof(struct nlattr));
+               size += num_vfs *
+                       (nla_total_size(sizeof(struct ifla_vf_mac)) +
+                        nla_total_size(sizeof(struct ifla_vf_vlan)) +
+                        nla_total_size(sizeof(struct ifla_vf_tx_rate)));
                return size;
        } else
                return 0;
@@ -722,14 +723,13 @@ static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev)
 
        for (vf = 0; vf < dev_num_vf(dev->dev.parent); vf++) {
                vf_port = nla_nest_start(skb, IFLA_VF_PORT);
-               if (!vf_port) {
-                       nla_nest_cancel(skb, vf_ports);
-                       return -EMSGSIZE;
-               }
+               if (!vf_port)
+                       goto nla_put_failure;
                NLA_PUT_U32(skb, IFLA_PORT_VF, vf);
                err = dev->netdev_ops->ndo_get_vf_port(dev, vf, skb);
+               if (err == -EMSGSIZE)
+                       goto nla_put_failure;
                if (err) {
-nla_put_failure:
                        nla_nest_cancel(skb, vf_port);
                        continue;
                }
@@ -739,6 +739,10 @@ nla_put_failure:
        nla_nest_end(skb, vf_ports);
 
        return 0;
+
+nla_put_failure:
+       nla_nest_cancel(skb, vf_ports);
+       return -EMSGSIZE;
 }
 
 static int rtnl_port_self_fill(struct sk_buff *skb, struct net_device *dev)
@@ -753,7 +757,7 @@ static int rtnl_port_self_fill(struct sk_buff *skb, struct net_device *dev)
        err = dev->netdev_ops->ndo_get_vf_port(dev, PORT_SELF_VF, skb);
        if (err) {
                nla_nest_cancel(skb, port_self);
-               return err;
+               return (err == -EMSGSIZE) ? err : 0;
        }
 
        nla_nest_end(skb, port_self);
index 37fe9b6..2cf7f9f 100644 (file)
@@ -2007,6 +2007,39 @@ void release_sock(struct sock *sk)
 }
 EXPORT_SYMBOL(release_sock);
 
+/**
+ * lock_sock_fast - fast version of lock_sock
+ * @sk: socket
+ *
+ * This version should be used for very small section, where process wont block
+ * return false if fast path is taken
+ *   sk_lock.slock locked, owned = 0, BH disabled
+ * return true if slow path is taken
+ *   sk_lock.slock unlocked, owned = 1, BH enabled
+ */
+bool lock_sock_fast(struct sock *sk)
+{
+       might_sleep();
+       spin_lock_bh(&sk->sk_lock.slock);
+
+       if (!sk->sk_lock.owned)
+               /*
+                * Note : We must disable BH
+                */
+               return false;
+
+       __lock_sock(sk);
+       sk->sk_lock.owned = 1;
+       spin_unlock(&sk->sk_lock.slock);
+       /*
+        * The sk_lock has mutex_lock() semantics here:
+        */
+       mutex_acquire(&sk->sk_lock.dep_map, 0, 0, _RET_IP_);
+       local_bh_enable();
+       return true;
+}
+EXPORT_SYMBOL(lock_sock_fast);
+
 int sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)
 {
        struct timeval tv;
index 4588910..856123f 100644 (file)
@@ -1911,7 +1911,7 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
        struct rtattr *mp_head;
 
        /* If cache is unresolved, don't try to parse IIF and OIF */
-       if (c->mfc_parent > MAXVIFS)
+       if (c->mfc_parent >= MAXVIFS)
                return -ENOENT;
 
        if (VIF_EXISTS(mrt, c->mfc_parent))
index baeec29..5858574 100644 (file)
@@ -1063,10 +1063,11 @@ static unsigned int first_packet_length(struct sock *sk)
        spin_unlock_bh(&rcvq->lock);
 
        if (!skb_queue_empty(&list_kill)) {
-               lock_sock_bh(sk);
+               bool slow = lock_sock_fast(sk);
+
                __skb_queue_purge(&list_kill);
                sk_mem_reclaim_partial(sk);
-               unlock_sock_bh(sk);
+               unlock_sock_fast(sk, slow);
        }
        return res;
 }
@@ -1123,6 +1124,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        int peeked;
        int err;
        int is_udplite = IS_UDPLITE(sk);
+       bool slow;
 
        /*
         *      Check any passed addresses
@@ -1197,10 +1199,10 @@ out:
        return err;
 
 csum_copy_err:
-       lock_sock_bh(sk);
+       slow = lock_sock_fast(sk);
        if (!skb_kill_datagram(sk, skb, flags))
                UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
-       unlock_sock_bh(sk);
+       unlock_sock_fast(sk, slow);
 
        if (noblock)
                return -EAGAIN;
@@ -1625,9 +1627,9 @@ int udp_rcv(struct sk_buff *skb)
 
 void udp_destroy_sock(struct sock *sk)
 {
-       lock_sock_bh(sk);
+       bool slow = lock_sock_fast(sk);
        udp_flush_pending_frames(sk);
-       unlock_sock_bh(sk);
+       unlock_sock_fast(sk, slow);
 }
 
 /*
index cd963f6..89425af 100644 (file)
@@ -507,7 +507,7 @@ int ip6_forward(struct sk_buff *skb)
        if (mtu < IPV6_MIN_MTU)
                mtu = IPV6_MIN_MTU;
 
-       if (skb->len > mtu) {
+       if (skb->len > mtu && !skb_is_gso(skb)) {
                /* Again, force OUTPUT device used as source address */
                skb->dev = dst->dev;
                icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
index bd9e7d3..073071f 100644 (file)
@@ -2017,7 +2017,7 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
        struct rtattr *mp_head;
 
        /* If cache is unresolved, don't try to parse IIF and OIF */
-       if (c->mf6c_parent > MAXMIFS)
+       if (c->mf6c_parent >= MAXMIFS)
                return -ENOENT;
 
        if (MIF_EXISTS(mrt, c->mf6c_parent))
index 3d7a2c0..87be586 100644 (file)
@@ -328,6 +328,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
        int err;
        int is_udplite = IS_UDPLITE(sk);
        int is_udp4;
+       bool slow;
 
        if (addr_len)
                *addr_len=sizeof(struct sockaddr_in6);
@@ -424,7 +425,7 @@ out:
        return err;
 
 csum_copy_err:
-       lock_sock_bh(sk);
+       slow = lock_sock_fast(sk);
        if (!skb_kill_datagram(sk, skb, flags)) {
                if (is_udp4)
                        UDP_INC_STATS_USER(sock_net(sk),
@@ -433,7 +434,7 @@ csum_copy_err:
                        UDP6_INC_STATS_USER(sock_net(sk),
                                        UDP_MIB_INERRORS, is_udplite);
        }
-       unlock_sock_bh(sk);
+       unlock_sock_fast(sk, slow);
 
        if (flags & MSG_DONTWAIT)
                return -EAGAIN;
index c8b4599..9637e45 100644 (file)
@@ -1619,7 +1619,7 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg)
 save_message:
        save_msg = kzalloc(sizeof(struct sock_msg_q), GFP_ATOMIC | GFP_DMA);
        if (!save_msg)
-               return;
+               goto out_unlock;
        save_msg->path = path;
        save_msg->msg = *msg;
 
index d7920d9..859d9fd 100644 (file)
@@ -76,7 +76,7 @@ tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info)
        if (ip_route_output_key(net, &rt, &fl) != 0)
                return false;
 
-       dst_release(skb_dst(skb));
+       skb_dst_drop(skb);
        skb_dst_set(skb, &rt->u.dst);
        skb->dev      = rt->u.dst.dev;
        skb->protocol = htons(ETH_P_IP);
@@ -157,7 +157,7 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info)
        if (dst == NULL)
                return false;
 
-       dst_release(skb_dst(skb));
+       skb_dst_drop(skb);
        skb_dst_set(skb, dst);
        skb->dev      = dst->dev;
        skb->protocol = htons(ETH_P_IPV6);