]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'next/cleanup-s3c' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorArnd Bergmann <arnd@arndb.de>
Fri, 15 Mar 2013 21:39:46 +0000 (22:39 +0100)
committerArnd Bergmann <arnd@arndb.de>
Fri, 15 Mar 2013 21:39:46 +0000 (22:39 +0100)
From Kukjin Kim <kgene.kim@samsung.com>:

Cleanups for the Samsung S3C24XX platforms.

* 'next/cleanup-s3c' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung:
  ARM: S3C24XX: cleanup the included soc init functions in common.h
  ARM: S3C24XX: move plat-samsung/s3c24XX headers to local common.h
  ARM: S3C24XX: remove plat/irq.h in plat-samsung
  ARM: S3C24XX: plat/common-smdk.h local
  mmc: s3cmci: moved mach/regs-sdi.h into s3cmci device driver

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
312 files changed:
CREDITS
Documentation/SubmittingPatches
Documentation/device-mapper/dm-raid.txt
Documentation/hwmon/adm1275
Documentation/hwmon/adt7410
Documentation/hwmon/jc42
Documentation/hwmon/lineage-pem
Documentation/hwmon/lm25066
Documentation/hwmon/ltc2978
Documentation/hwmon/ltc4261
Documentation/hwmon/max16064
Documentation/hwmon/max16065
Documentation/hwmon/max34440
Documentation/hwmon/max8688
Documentation/hwmon/pmbus
Documentation/hwmon/smm665
Documentation/hwmon/ucd9000
Documentation/hwmon/ucd9200
Documentation/hwmon/zl6100
Documentation/power/opp.txt
Documentation/printk-formats.txt
MAINTAINERS
Makefile
arch/alpha/boot/head.S
arch/arm/boot/compressed/Makefile
arch/arm/include/asm/mmu.h
arch/arm/include/asm/mmu_context.h
arch/arm/include/asm/tlbflush.h
arch/arm/include/uapi/asm/unistd.h
arch/arm/kernel/asm-offsets.c
arch/arm/kernel/calls.S
arch/arm/kernel/head.S
arch/arm/kernel/hw_breakpoint.c
arch/arm/kernel/perf_event.c
arch/arm/kernel/perf_event_v7.c
arch/arm/kernel/smp.c
arch/arm/kernel/smp_tlb.c
arch/arm/kernel/smp_twd.c
arch/arm/kernel/suspend.c
arch/arm/lib/memset.S
arch/arm/mach-netx/generic.c
arch/arm/mach-netx/include/mach/irqs.h
arch/arm/mm/context.c
arch/arm/mm/idmap.c
arch/arm/mm/proc-v7-3level.S
arch/ia64/kernel/perfmon.c
arch/metag/include/asm/elf.h
arch/metag/mm/Kconfig
arch/powerpc/crypto/sha1-powerpc-asm.S
arch/powerpc/include/asm/bitops.h
arch/powerpc/include/asm/reg.h
arch/powerpc/include/asm/systbl.h
arch/powerpc/include/asm/unistd.h
arch/powerpc/include/uapi/asm/unistd.h
arch/powerpc/kernel/cpu_setup_power.S
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/platforms/cell/spufs/inode.c
arch/powerpc/platforms/pseries/hvcserver.c
arch/s390/hypfs/inode.c
arch/tile/include/asm/compat.h
arch/tile/kernel/compat.c
arch/x86/include/asm/bootparam_utils.h
arch/x86/kernel/setup.c
arch/x86/kernel/smpboot.c
arch/x86/mm/init.c
arch/x86/mm/pat.c
drivers/acpi/glue.c
drivers/acpi/processor_core.c
drivers/acpi/processor_driver.c
drivers/acpi/sleep.c
drivers/ata/libata-acpi.c
drivers/base/power/main.c
drivers/base/power/power.h
drivers/base/power/qos.c
drivers/base/power/sysfs.c
drivers/base/regmap/regmap-irq.c
drivers/bcma/driver_pci_host.c
drivers/char/hw_random/core.c
drivers/char/random.c
drivers/connector/cn_proc.c
drivers/cpufreq/cpufreq_governor.h
drivers/cpufreq/highbank-cpufreq.c
drivers/cpufreq/intel_pstate.c
drivers/firmware/dmi_scan.c
drivers/firmware/efivars.c
drivers/gpio/gpio-ich.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/mgag200/mgag200_drv.h
drivers/gpu/drm/mgag200/mgag200_i2c.c
drivers/gpu/drm/mgag200/mgag200_mode.c
drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
drivers/gpu/drm/nouveau/core/subdev/bios/init.c
drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
drivers/gpu/drm/nouveau/nouveau_agp.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_cs.c
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_irq_kms.c
drivers/gpu/drm/radeon/si.c
drivers/gpu/drm/tegra/Kconfig
drivers/hid/hid-logitech-dj.c
drivers/hwmon/pmbus/ltc2978.c
drivers/hwmon/sht15.c
drivers/infiniband/hw/ipath/ipath_fs.c
drivers/infiniband/hw/qib/qib_fs.c
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/iommu/dmar.c
drivers/isdn/hisax/st5481_usb.c
drivers/mailbox/pl320-ipc.c
drivers/md/Kconfig
drivers/md/dm-raid.c
drivers/md/md.c
drivers/md/raid0.c
drivers/md/raid1.c
drivers/md/raid10.c
drivers/md/raid10.h
drivers/md/raid5.c
drivers/misc/ibmasm/ibmasmfs.c
drivers/mtd/mtdchar.c
drivers/net/bonding/bond_main.c
drivers/net/ethernet/broadcom/bgmac.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
drivers/net/ethernet/freescale/fec.c
drivers/net/ethernet/freescale/fec.h
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/net_driver.h
drivers/net/ethernet/sfc/rx.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/phy/micrel.c
drivers/net/phy/phy_device.c
drivers/net/usb/Kconfig
drivers/net/usb/Makefile
drivers/net/usb/asix_devices.c
drivers/net/usb/ax88179_178a.c [new file with mode: 0644]
drivers/net/usb/cdc_ncm.c
drivers/net/wireless/ath/ath9k/common.h
drivers/net/wireless/ath/ath9k/htc.h
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/iwlwifi/iwl-devtrace.h
drivers/net/wireless/iwlwifi/iwl-phy-db.c
drivers/net/wireless/iwlwifi/mvm/d3.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/pcie/internal.h
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/mwifiex/pcie.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/oprofile/oprofilefs.c
drivers/pci/pci-acpi.c
drivers/platform/x86/chromeos_laptop.c
drivers/pnp/pnpacpi/core.c
drivers/regulator/core.c
drivers/regulator/db8500-prcmu.c
drivers/regulator/palmas-regulator.c
drivers/regulator/twl-regulator.c
drivers/scsi/scsi_lib.c
drivers/staging/ccg/f_fs.c
drivers/tty/hvc/hvcs.c
drivers/usb/core/usb-acpi.c
drivers/usb/gadget/f_fs.c
drivers/usb/gadget/inode.c
drivers/xen/xenfs/super.c
fs/9p/vfs_super.c
fs/adfs/super.c
fs/affs/super.c
fs/afs/super.c
fs/autofs4/init.c
fs/befs/linuxvfs.c
fs/bfs/inode.c
fs/binfmt_misc.c
fs/btrfs/delayed-inode.c
fs/btrfs/delayed-inode.h
fs/btrfs/disk-io.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/relocation.c
fs/btrfs/super.c
fs/btrfs/transaction.c
fs/btrfs/tree-log.c
fs/btrfs/volumes.c
fs/ceph/super.c
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/inode.c
fs/cifs/smb2ops.c
fs/coda/inode.c
fs/configfs/mount.c
fs/cramfs/inode.c
fs/debugfs/inode.c
fs/ecryptfs/Kconfig
fs/ecryptfs/Makefile
fs/ecryptfs/crypto.c
fs/ecryptfs/dentry.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/file.c
fs/ecryptfs/inode.c
fs/ecryptfs/keystore.c
fs/ecryptfs/main.c
fs/ecryptfs/messaging.c
fs/efs/super.c
fs/exofs/super.c
fs/ext2/super.c
fs/ext3/super.c
fs/ext4/super.c
fs/f2fs/super.c
fs/fat/namei_msdos.c
fs/fat/namei_vfat.c
fs/filesystems.c
fs/freevxfs/vxfs_super.c
fs/fuse/control.c
fs/fuse/inode.c
fs/gfs2/ops_fstype.c
fs/hfs/super.c
fs/hfsplus/super.c
fs/hppfs/hppfs.c
fs/hugetlbfs/inode.c
fs/isofs/inode.c
fs/jffs2/super.c
fs/jfs/super.c
fs/logfs/super.c
fs/minix/inode.c
fs/namei.c
fs/ncpfs/inode.c
fs/nfs/super.c
fs/nfsd/nfsctl.c
fs/nilfs2/super.c
fs/ntfs/super.c
fs/ocfs2/dlmfs/dlmfs.c
fs/ocfs2/super.c
fs/omfs/inode.c
fs/openpromfs/inode.c
fs/proc/namespaces.c
fs/qnx4/inode.c
fs/qnx6/inode.c
fs/reiserfs/super.c
fs/romfs/super.c
fs/sysv/super.c
fs/ubifs/super.c
fs/ufs/super.c
fs/xfs/xfs_super.c
include/acpi/acpi_bus.h
include/drm/drm_crtc.h
include/linux/ecryptfs.h
include/linux/fs.h
include/linux/hardirq.h
include/linux/i2c/atmel_mxt_ts.h
include/linux/netfilter/ipset/ip_set_ahash.h
include/linux/regulator/driver.h
include/linux/smpboot.h
include/net/tcp.h
ipc/msg.c
ipc/msgutil.c
kernel/smpboot.c
kernel/softirq.c
kernel/stop_machine.c
lib/idr.c
mm/ksm.c
mm/memcontrol.c
mm/mempolicy.c
net/9p/trans_virtio.c
net/caif/caif_dev.c
net/caif/caif_usb.c
net/ipv4/ip_input.c
net/ipv4/tcp_input.c
net/ipv6/ip6_input.c
net/ipv6/route.c
net/irda/iriap.c
net/l2tp/l2tp_ppp.c
net/mac80211/cfg.c
net/mac80211/iface.c
net/mac80211/tx.c
net/netfilter/ipset/ip_set_core.c
net/rds/message.c
net/sctp/endpointola.c
net/sctp/socket.c
net/sctp/ssnmap.c
net/sctp/tsnmap.c
net/sctp/ulpqueue.c
net/sunrpc/rpc_pipe.c
net/wireless/nl80211.c
security/keys/process_keys.c
sound/core/seq/oss/seq_oss_event.c
sound/core/vmaster.c
sound/pci/hda/hda_codec.c
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_realtek.c
sound/pci/ice1712/ice1712.c
sound/soc/codecs/wm5102.c
sound/soc/codecs/wm5110.c
sound/soc/codecs/wm8350.c
sound/soc/codecs/wm8960.c
sound/soc/tegra/tegra20_i2s.h
sound/soc/tegra/tegra30_i2s.h
tools/testing/selftests/efivarfs/efivarfs.sh

diff --git a/CREDITS b/CREDITS
index 948e0fb9a70e570c383dd9ec016118f8ff128568..78163cb3eb6ad9d0b2c3372ef0d6305b48e95981 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -953,11 +953,11 @@ S: Blacksburg, Virginia 24061
 S: USA
 
 N: Randy Dunlap
-E: rdunlap@xenotime.net
-W: http://www.xenotime.net/linux/linux.html
-W: http://www.linux-usb.org
+E: rdunlap@infradead.org
+W: http://www.infradead.org/~rdunlap/
 D: Linux-USB subsystem, USB core/UHCI/printer/storage drivers
 D: x86 SMP, ACPI, bootflag hacking
+D: documentation, builds
 S: (ask for current address)
 S: USA
 
index c379a2a6949f1c1cac04fb6f185c633512f37061..aa0c1e63f05028e7e0e5ee2054bb5353c29be196 100644 (file)
@@ -60,8 +60,7 @@ own source tree.  For example:
 "dontdiff" is a list of files which are generated by the kernel during
 the build process, and should be ignored in any diff(1)-generated
 patch.  The "dontdiff" file is included in the kernel tree in
-2.6.12 and later.  For earlier kernel versions, you can get it
-from <http://www.xenotime.net/linux/doc/dontdiff>.
+2.6.12 and later.
 
 Make sure your patch does not include any extra files which do not
 belong in a patch submission.  Make sure to review your patch -after-
index 56fb62b09fc59ad757fc81de6ad6e478b3b0184b..b428556197c99a0eea19d3b040bfbe3c0ffcf06e 100644 (file)
@@ -30,6 +30,7 @@ The target is named "raid" and it accepts the following parameters:
   raid10        Various RAID10 inspired algorithms chosen by additional params
                - RAID10: Striped Mirrors (aka 'Striping on top of mirrors')
                - RAID1E: Integrated Adjacent Stripe Mirroring
+               - RAID1E: Integrated Offset Stripe Mirroring
                -  and other similar RAID10 variants
 
   Reference: Chapter 4 of
@@ -64,15 +65,15 @@ The target is named "raid" and it accepts the following parameters:
                synchronisation state for each region.
 
         [raid10_copies   <# copies>]
-        [raid10_format   near]
+        [raid10_format   <near|far|offset>]
                These two options are used to alter the default layout of
                a RAID10 configuration.  The number of copies is can be
-               specified, but the default is 2.  There are other variations
-               to how the copies are laid down - the default and only current
-               option is "near".  Near copies are what most people think of
-               with respect to mirroring.  If these options are left
-               unspecified, or 'raid10_copies 2' and/or 'raid10_format near'
-               are given, then the layouts for 2, 3 and 4 devices are:
+               specified, but the default is 2.  There are also three
+               variations to how the copies are laid down - the default
+               is "near".  Near copies are what most people think of with
+               respect to mirroring.  If these options are left unspecified,
+               or 'raid10_copies 2' and/or 'raid10_format near' are given,
+               then the layouts for 2, 3 and 4 devices are:
                2 drives         3 drives          4 drives
                --------         ----------        --------------
                A1  A1           A1  A1  A2        A1  A1  A2  A2
@@ -85,6 +86,33 @@ The target is named "raid" and it accepts the following parameters:
                3-device layout is what might be called a 'RAID1E - Integrated
                Adjacent Stripe Mirroring'.
 
+               If 'raid10_copies 2' and 'raid10_format far', then the layouts
+               for 2, 3 and 4 devices are:
+               2 drives             3 drives             4 drives
+               --------             --------------       --------------------
+               A1  A2               A1   A2   A3         A1   A2   A3   A4
+               A3  A4               A4   A5   A6         A5   A6   A7   A8
+               A5  A6               A7   A8   A9         A9   A10  A11  A12
+               ..  ..               ..   ..   ..         ..   ..   ..   ..
+               A2  A1               A3   A1   A2         A2   A1   A4   A3
+               A4  A3               A6   A4   A5         A6   A5   A8   A7
+               A6  A5               A9   A7   A8         A10  A9   A12  A11
+               ..  ..               ..   ..   ..         ..   ..   ..   ..
+
+               If 'raid10_copies 2' and 'raid10_format offset', then the
+               layouts for 2, 3 and 4 devices are:
+               2 drives       3 drives           4 drives
+               --------       ------------       -----------------
+               A1  A2         A1  A2  A3         A1  A2  A3  A4
+               A2  A1         A3  A1  A2         A2  A1  A4  A3
+               A3  A4         A4  A5  A6         A5  A6  A7  A8
+               A4  A3         A6  A4  A5         A6  A5  A8  A7
+               A5  A6         A7  A8  A9         A9  A10 A11 A12
+               A6  A5         A9  A7  A8         A10 A9  A12 A11
+               ..  ..         ..  ..  ..         ..  ..  ..  ..
+               Here we see layouts closely akin to 'RAID1E - Integrated
+               Offset Stripe Mirroring'.
+
 <#raid_devs>: The number of devices composing the array.
        Each device consists of two entries.  The first is the device
        containing the metadata (if any); the second is the one containing the
@@ -142,3 +170,5 @@ Version History
 1.3.0  Added support for RAID 10
 1.3.1  Allow device replacement/rebuild for RAID 10
 1.3.2   Fix/improve redundancy checking for RAID10
+1.4.0  Non-functional change.  Removes arg from mapping function.
+1.4.1   Add RAID10 "far" and "offset" algorithm support.
index 2cfa256671235745f3433bec2e0c0a18e93041bf..15b4a20d5062f4e3872135557f6740da6c9408cf 100644 (file)
@@ -15,7 +15,7 @@ Supported chips:
     Addresses scanned: -
     Datasheet: www.analog.com/static/imported-files/data_sheets/ADM1276.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index 96004000dc2a3ef0d622cbccb6c48aa422a0ed9f..58150c480e5694668c32f6348dab6ae1bcd168bf 100644 (file)
@@ -4,9 +4,14 @@ Kernel driver adt7410
 Supported chips:
   * Analog Devices ADT7410
     Prefix: 'adt7410'
-    Addresses scanned: I2C 0x48 - 0x4B
+    Addresses scanned: None
     Datasheet: Publicly available at the Analog Devices website
                http://www.analog.com/static/imported-files/data_sheets/ADT7410.pdf
+  * Analog Devices ADT7420
+    Prefix: 'adt7420'
+    Addresses scanned: None
+    Datasheet: Publicly available at the Analog Devices website
+               http://www.analog.com/static/imported-files/data_sheets/ADT7420.pdf
 
 Author: Hartmut Knaack <knaack.h@gmx.de>
 
@@ -27,6 +32,10 @@ value per second or even justget one sample on demand for power saving.
 Besides, it can completely power down its ADC, if power management is
 required.
 
+The ADT7420 is register compatible, the only differences being the package,
+a slightly narrower operating temperature range (-40°C to +150°C), and a
+better accuracy (0.25°C instead of 0.50°C.)
+
 Configuration Notes
 -------------------
 
index 1650771212382296f6a63b321fce6b322dcba27e..868d74d6b773bfcf902b5d45d0827f3f3482197f 100644 (file)
@@ -49,7 +49,7 @@ Supported chips:
     Addresses scanned: I2C 0x18 - 0x1f
 
 Author:
-       Guenter Roeck <guenter.roeck@ericsson.com>
+       Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index 2ba5ed126858e467b46380319a0b5876ecc91d18..83b2ddc160c898714ce967aaa90098950db95059 100644 (file)
@@ -8,7 +8,7 @@ Supported devices:
     Documentation:
         http://www.lineagepower.com/oem/pdf/CPLI2C.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index a21db81c4591fa48212e08d08ac88c0e24bbe3e2..26025e419d357c5e078e96a3f831be67f5b4e289 100644 (file)
@@ -19,7 +19,7 @@ Supported chips:
     Datasheet:
        http://www.national.com/pf/LM/LM5066.html
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index c365f9beb5dd6a1657fbcbbb38f2298aba204b73..e4d75c606c97e88f9a45c2dfd956931b568b28e7 100644 (file)
@@ -5,13 +5,13 @@ Supported chips:
   * Linear Technology LTC2978
     Prefix: 'ltc2978'
     Addresses scanned: -
-    Datasheet: http://cds.linear.com/docs/Datasheet/2978fa.pdf
+    Datasheet: http://www.linear.com/product/ltc2978
   * Linear Technology LTC3880
     Prefix: 'ltc3880'
     Addresses scanned: -
-    Datasheet: http://cds.linear.com/docs/Datasheet/3880f.pdf
+    Datasheet: http://www.linear.com/product/ltc3880
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index eba2e2c4b94d89e2f3eb06006ab763ce874233ff..9378a75c61340850b4d0cb47273252e6a3a41be6 100644 (file)
@@ -8,7 +8,7 @@ Supported chips:
     Datasheet:
         http://cds.linear.com/docs/Datasheet/42612fb.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index f8b478076f6dfda9e2fdbd47e2a4b843ca13bc51..d59cc7829bec1b223a8e3b577741624d9cc4ee6a 100644 (file)
@@ -7,7 +7,7 @@ Supported chips:
     Addresses scanned: -
     Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX16064.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index c11f64a1f2adb61077f5910215981d589503aa0f..208a29e430105fa78fd86f2e548e19690d91fbb2 100644 (file)
@@ -24,7 +24,7 @@ Supported chips:
        http://datasheets.maxim-ic.com/en/ds/MAX16070-MAX16071.pdf
 
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index 47651ff341aed4cc7ad95d20c052c57250e5c827..37cbf472a19d19aef7aea0217d008943eb28909f 100644 (file)
@@ -27,7 +27,7 @@ Supported chips:
     Addresses scanned: -
     Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX34461.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index fe849871df32dbe81af61fca76c300794047a1fe..e78078638b9142906b8308c4700f25d2f8a2ef88 100644 (file)
@@ -7,7 +7,7 @@ Supported chips:
     Addresses scanned: -
     Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX8688.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index 3d3a0f97f966f677e76a5d9685036edc43022ca6..cf756ed48ff9458d7cc6f8137d239f376ef2a154 100644 (file)
@@ -34,7 +34,7 @@ Supported chips:
     Addresses scanned: -
     Datasheet: n.a.
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index 59e316140542017517be09171448fc4e6e16d28e..a341eeedab75f5b10e12991d1927652d8c52dc5e 100644 (file)
@@ -29,7 +29,7 @@ Supported chips:
       http://www.summitmicro.com/prod_select/summary/SMM766/SMM766_2086.pdf
       http://www.summitmicro.com/prod_select/summary/SMM766B/SMM766B_2122.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Module Parameters
index 0df5f276505b6470e28f00c86c6bd1d76aad5b4d..805e33edb978b7f21c92f2d1ee001431a8ee9ac0 100644 (file)
@@ -11,7 +11,7 @@ Supported chips:
        http://focus.ti.com/lit/ds/symlink/ucd9090.pdf
        http://focus.ti.com/lit/ds/symlink/ucd90910.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index fd7d07b1908a9d0c5dfd3c38f3bb73c6cf980210..1e8060e631bdcd4f6126f35243a2ad96d23959c7 100644 (file)
@@ -15,7 +15,7 @@ Supported chips:
        http://focus.ti.com/lit/ds/symlink/ucd9246.pdf
        http://focus.ti.com/lit/ds/symlink/ucd9248.pdf
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index 3d924b6b59e915ff043e933209d7d449b6f889ce..756b57c6b73e8683308641aaad38887d7c4797d0 100644 (file)
@@ -54,7 +54,7 @@ http://archive.ericsson.net/service/internet/picov/get?DocNo=28701-EN/LZT146401
 http://archive.ericsson.net/service/internet/picov/get?DocNo=28701-EN/LZT146256
 
 
-Author: Guenter Roeck <guenter.roeck@ericsson.com>
+Author: Guenter Roeck <linux@roeck-us.net>
 
 
 Description
index 3035d00757ad53d857418a3d6196866b7460f357..425c51d56aefb8b991b3d97b5d3f01564f9baaf6 100644 (file)
@@ -1,6 +1,5 @@
-*=============*
-* OPP Library *
-*=============*
+Operating Performance Points (OPP) Library
+==========================================
 
 (C) 2009-2010 Nishanth Menon <nm@ti.com>, Texas Instruments Incorporated
 
@@ -16,15 +15,31 @@ Contents
 
 1. Introduction
 ===============
+1.1 What is an Operating Performance Point (OPP)?
+
 Complex SoCs of today consists of a multiple sub-modules working in conjunction.
 In an operational system executing varied use cases, not all modules in the SoC
 need to function at their highest performing frequency all the time. To
 facilitate this, sub-modules in a SoC are grouped into domains, allowing some
-domains to run at lower voltage and frequency while other domains are loaded
-more. The set of discrete tuples consisting of frequency and voltage pairs that
+domains to run at lower voltage and frequency while other domains run at
+voltage/frequency pairs that are higher.
+
+The set of discrete tuples consisting of frequency and voltage pairs that
 the device will support per domain are called Operating Performance Points or
 OPPs.
 
+As an example:
+Let us consider an MPU device which supports the following:
+{300MHz at minimum voltage of 1V}, {800MHz at minimum voltage of 1.2V},
+{1GHz at minimum voltage of 1.3V}
+
+We can represent these as three OPPs as the following {Hz, uV} tuples:
+{300000000, 1000000}
+{800000000, 1200000}
+{1000000000, 1300000}
+
+1.2 Operating Performance Points Library
+
 OPP library provides a set of helper functions to organize and query the OPP
 information. The library is located in drivers/base/power/opp.c and the header
 is located in include/linux/opp.h. OPP library can be enabled by enabling
index e8a6aa473babbedc1df224c250cd0f28f8ecb061..6e953564de03013d5059d7dc7616c91d3aea0b43 100644 (file)
@@ -170,5 +170,5 @@ Reminder: sizeof() result is of type size_t.
 Thank you for your cooperation and attention.
 
 
-By Randy Dunlap <rdunlap@xenotime.net> and
+By Randy Dunlap <rdunlap@infradead.org> and
 Andrew Murray <amurray@mpc-data.co.uk>
index e95b1e944eb7d26e19b712af2ffa3788d47be2ec..95616582c728566eaa1e24592f645ece61f6b501 100644 (file)
@@ -114,12 +114,6 @@ Maintainers List (try to look for most precise areas first)
 
                -----------------------------------
 
-3C505 NETWORK DRIVER
-M:     Philip Blundell <philb@gnu.org>
-L:     netdev@vger.kernel.org
-S:     Maintained
-F:     drivers/net/ethernet/i825xx/3c505*
-
 3C59X NETWORK DRIVER
 M:     Steffen Klassert <klassert@mathematik.tu-chemnitz.de>
 L:     netdev@vger.kernel.org
@@ -2361,12 +2355,6 @@ W:       http://www.arm.linux.org.uk/
 S:     Maintained
 F:     drivers/video/cyber2000fb.*
 
-CYCLADES 2X SYNC CARD DRIVER
-M:     Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
-W:     http://oops.ghostprotocols.net:81/blog
-S:     Maintained
-F:     drivers/net/wan/cycx*
-
 CYCLADES ASYNC MUX DRIVER
 W:     http://www.cyclades.com/
 S:     Orphan
@@ -3067,12 +3055,6 @@ T:       git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git
 F:     drivers/video/s1d13xxxfb.c
 F:     include/video/s1d13xxxfb.h
 
-ETHEREXPRESS-16 NETWORK DRIVER
-M:     Philip Blundell <philb@gnu.org>
-L:     netdev@vger.kernel.org
-S:     Maintained
-F:     drivers/net/ethernet/i825xx/eexpress.*
-
 ETHERNET BRIDGE
 M:     Stephen Hemminger <stephen@networkplumber.org>
 L:     bridge@lists.linux-foundation.org
index 5bd9f7700eb9582a59cc7d75bf6e55a82ce587b3..a05ea42c5f185d66692be18747e9e90b9633cd20 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 9
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 NAME = Unicycling Gorilla
 
 # *DOCUMENTATION*
index b06812bcac83b911cf43613cba8f1d6619fd380d..8efb26686d4789e2afbfc910921b2327e8fbe2c1 100644 (file)
@@ -4,6 +4,7 @@
  * initial bootloader stuff..
  */
 
+#include <asm/pal.h>
 
        .set noreorder
        .globl  __start
index 5cad8a6dadb021fd2aef0a4ef1a77c40173041e7..afed28e37ea5776073c9bace41d644b4bd6dda44 100644 (file)
@@ -120,7 +120,7 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS)
 KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
 endif
 
-ccflags-y := -fpic -fno-builtin -I$(obj)
+ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj)
 asflags-y := -Wa,-march=all -DZIMAGE
 
 # Supply kernel BSS size to the decompressor via a linker symbol.
index 9f77e7804f3b66e7c08e7ece91780b2df178c9ca..e3d55547e75592a9eb98fa1704ee8df9e872c2c5 100644 (file)
@@ -5,15 +5,15 @@
 
 typedef struct {
 #ifdef CONFIG_CPU_HAS_ASID
-       u64 id;
+       atomic64_t      id;
 #endif
-       unsigned int vmalloc_seq;
+       unsigned int    vmalloc_seq;
 } mm_context_t;
 
 #ifdef CONFIG_CPU_HAS_ASID
 #define ASID_BITS      8
 #define ASID_MASK      ((~0ULL) << ASID_BITS)
-#define ASID(mm)       ((mm)->context.id & ~ASID_MASK)
+#define ASID(mm)       ((mm)->context.id.counter & ~ASID_MASK)
 #else
 #define ASID(mm)       (0)
 #endif
@@ -26,7 +26,7 @@ typedef struct {
  *  modified for 2.6 by Hyok S. Choi <hyok.choi@samsung.com>
  */
 typedef struct {
-       unsigned long           end_brk;
+       unsigned long   end_brk;
 } mm_context_t;
 
 #endif
index e1f644bc7cc504412613a08489dffbfc4ecc63bd..863a6611323c70077a9428b198a10d59758ff919 100644 (file)
@@ -25,7 +25,7 @@ void __check_vmalloc_seq(struct mm_struct *mm);
 #ifdef CONFIG_CPU_HAS_ASID
 
 void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk);
-#define init_new_context(tsk,mm)       ({ mm->context.id = 0; })
+#define init_new_context(tsk,mm)       ({ atomic64_set(&mm->context.id, 0); 0; })
 
 #else  /* !CONFIG_CPU_HAS_ASID */
 
index 6e924d3a77ebc168cb8359e7cf79f21b8890146d..4db8c8820f0d1c832bf9efd5e81a69d32b4fc7d7 100644 (file)
 #define TLB_V6_D_ASID  (1 << 17)
 #define TLB_V6_I_ASID  (1 << 18)
 
+#define TLB_V6_BP      (1 << 19)
+
 /* Unified Inner Shareable TLB operations (ARMv7 MP extensions) */
-#define TLB_V7_UIS_PAGE        (1 << 19)
-#define TLB_V7_UIS_FULL (1 << 20)
-#define TLB_V7_UIS_ASID (1 << 21)
+#define TLB_V7_UIS_PAGE        (1 << 20)
+#define TLB_V7_UIS_FULL (1 << 21)
+#define TLB_V7_UIS_ASID (1 << 22)
+#define TLB_V7_UIS_BP  (1 << 23)
 
 #define TLB_BARRIER    (1 << 28)
 #define TLB_L2CLEAN_FR (1 << 29)               /* Feroceon */
 #define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \
                         TLB_V6_I_FULL | TLB_V6_D_FULL | \
                         TLB_V6_I_PAGE | TLB_V6_D_PAGE | \
-                        TLB_V6_I_ASID | TLB_V6_D_ASID)
+                        TLB_V6_I_ASID | TLB_V6_D_ASID | \
+                        TLB_V6_BP)
 
 #ifdef CONFIG_CPU_TLB_V6
 # define v6wbi_possible_flags  v6wbi_tlb_flags
 #endif
 
 #define v7wbi_tlb_flags_smp    (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \
-                        TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID)
+                                TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | \
+                                TLB_V7_UIS_ASID | TLB_V7_UIS_BP)
 #define v7wbi_tlb_flags_up     (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \
-                        TLB_V6_U_FULL | TLB_V6_U_PAGE | TLB_V6_U_ASID)
+                                TLB_V6_U_FULL | TLB_V6_U_PAGE | \
+                                TLB_V6_U_ASID | TLB_V6_BP)
 
 #ifdef CONFIG_CPU_TLB_V7
 
@@ -430,6 +436,20 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
        }
 }
 
+static inline void local_flush_bp_all(void)
+{
+       const int zero = 0;
+       const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+       if (tlb_flag(TLB_V7_UIS_BP))
+               asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero));
+       else if (tlb_flag(TLB_V6_BP))
+               asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero));
+
+       if (tlb_flag(TLB_BARRIER))
+               isb();
+}
+
 /*
  *     flush_pmd_entry
  *
@@ -480,6 +500,7 @@ static inline void clean_pmd_entry(void *pmd)
 #define flush_tlb_kernel_page  local_flush_tlb_kernel_page
 #define flush_tlb_range                local_flush_tlb_range
 #define flush_tlb_kernel_range local_flush_tlb_kernel_range
+#define flush_bp_all           local_flush_bp_all
 #else
 extern void flush_tlb_all(void);
 extern void flush_tlb_mm(struct mm_struct *mm);
@@ -487,6 +508,7 @@ extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr);
 extern void flush_tlb_kernel_page(unsigned long kaddr);
 extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
 extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
+extern void flush_bp_all(void);
 #endif
 
 /*
index 4da7cde70b5d3fac435bdbf13b3dcc9c298be4c7..af33b44990ed4a395662f0c5e7021049e5755a78 100644 (file)
 #define __NR_setns                     (__NR_SYSCALL_BASE+375)
 #define __NR_process_vm_readv          (__NR_SYSCALL_BASE+376)
 #define __NR_process_vm_writev         (__NR_SYSCALL_BASE+377)
-                                       /* 378 for kcmp */
+#define __NR_kcmp                      (__NR_SYSCALL_BASE+378)
 #define __NR_finit_module              (__NR_SYSCALL_BASE+379)
 
 /*
index 5ce738b435081254652ed3abdcbdfa2dcf5c88c2..923eec7105cff3cbb5f1eccd7e044a25e4cfdbf3 100644 (file)
@@ -110,7 +110,7 @@ int main(void)
   BLANK();
 #endif
 #ifdef CONFIG_CPU_HAS_ASID
-  DEFINE(MM_CONTEXT_ID,                offsetof(struct mm_struct, context.id));
+  DEFINE(MM_CONTEXT_ID,                offsetof(struct mm_struct, context.id.counter));
   BLANK();
 #endif
   DEFINE(VMA_VM_MM,            offsetof(struct vm_area_struct, vm_mm));
index 0cc57611fc4f379b1e6087d4f8d6492dede8156f..c6ca7e376773fcc73ef619e1c5a97793d97b41b4 100644 (file)
 /* 375 */      CALL(sys_setns)
                CALL(sys_process_vm_readv)
                CALL(sys_process_vm_writev)
-               CALL(sys_ni_syscall)    /* reserved for sys_kcmp */
+               CALL(sys_kcmp)
                CALL(sys_finit_module)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
index 486a15ae901192fa3e26539b3d2b7003a1528e0f..e0eb9a1cae774fc714548c3e11ad5141cc82190e 100644 (file)
@@ -184,13 +184,22 @@ __create_page_tables:
        orr     r3, r3, #3                      @ PGD block type
        mov     r6, #4                          @ PTRS_PER_PGD
        mov     r7, #1 << (55 - 32)             @ L_PGD_SWAPPER
-1:     str     r3, [r0], #4                    @ set bottom PGD entry bits
+1:
+#ifdef CONFIG_CPU_ENDIAN_BE8
        str     r7, [r0], #4                    @ set top PGD entry bits
+       str     r3, [r0], #4                    @ set bottom PGD entry bits
+#else
+       str     r3, [r0], #4                    @ set bottom PGD entry bits
+       str     r7, [r0], #4                    @ set top PGD entry bits
+#endif
        add     r3, r3, #0x1000                 @ next PMD table
        subs    r6, r6, #1
        bne     1b
 
        add     r4, r4, #0x1000                 @ point to the PMD tables
+#ifdef CONFIG_CPU_ENDIAN_BE8
+       add     r4, r4, #4                      @ we only write the bottom word
+#endif
 #endif
 
        ldr     r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
@@ -258,6 +267,11 @@ __create_page_tables:
        addne   r6, r6, #1 << SECTION_SHIFT
        strne   r6, [r3]
 
+#if defined(CONFIG_LPAE) && defined(CONFIG_CPU_ENDIAN_BE8)
+       sub     r4, r4, #4                      @ Fixup page table pointer
+                                               @ for 64-bit descriptors
+#endif
+
 #ifdef CONFIG_DEBUG_LL
 #if !defined(CONFIG_DEBUG_ICEDCC) && !defined(CONFIG_DEBUG_SEMIHOSTING)
        /*
@@ -276,13 +290,17 @@ __create_page_tables:
        orr     r3, r7, r3, lsl #SECTION_SHIFT
 #ifdef CONFIG_ARM_LPAE
        mov     r7, #1 << (54 - 32)             @ XN
+#ifdef CONFIG_CPU_ENDIAN_BE8
+       str     r7, [r0], #4
+       str     r3, [r0], #4
 #else
-       orr     r3, r3, #PMD_SECT_XN
-#endif
        str     r3, [r0], #4
-#ifdef CONFIG_ARM_LPAE
        str     r7, [r0], #4
 #endif
+#else
+       orr     r3, r3, #PMD_SECT_XN
+       str     r3, [r0], #4
+#endif
 
 #else /* CONFIG_DEBUG_ICEDCC || CONFIG_DEBUG_SEMIHOSTING */
        /* we don't need any serial debugging mappings */
index 5eae53e7a2e1619c5d128b20b5337e727fc43864..96093b75ab90dc134d7232e3f6a1e3c5f41e7902 100644 (file)
@@ -1023,7 +1023,7 @@ out_mdbgen:
 static int __cpuinit dbg_reset_notify(struct notifier_block *self,
                                      unsigned long action, void *cpu)
 {
-       if (action == CPU_ONLINE)
+       if ((action & ~CPU_TASKS_FROZEN) == CPU_ONLINE)
                smp_call_function_single((int)cpu, reset_ctrl_regs, NULL, 1);
 
        return NOTIFY_OK;
index 31e0eb353cd80a1bf3c02dfe6c4b7c5b1112bec4..146157dfe27c6c991b8507c2c3f248d810754cc0 100644 (file)
@@ -400,7 +400,7 @@ __hw_perf_event_init(struct perf_event *event)
        }
 
        if (event->group_leader != event) {
-               if (validate_group(event) != 0);
+               if (validate_group(event) != 0)
                        return -EINVAL;
        }
 
@@ -484,7 +484,7 @@ const struct dev_pm_ops armpmu_dev_pm_ops = {
        SET_RUNTIME_PM_OPS(armpmu_runtime_suspend, armpmu_runtime_resume, NULL)
 };
 
-static void __init armpmu_init(struct arm_pmu *armpmu)
+static void armpmu_init(struct arm_pmu *armpmu)
 {
        atomic_set(&armpmu->active_events, 0);
        mutex_init(&armpmu->reserve_mutex);
index 8c79a9e70b83d1dd31afdca93addae57c7c9c0cb..039cffb053a7ec017a552013fc6eff5c17ca1d50 100644 (file)
@@ -774,7 +774,7 @@ static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
 /*
  * PMXEVTYPER: Event selection reg
  */
-#define        ARMV7_EVTYPE_MASK       0xc00000ff      /* Mask for writable bits */
+#define        ARMV7_EVTYPE_MASK       0xc80000ff      /* Mask for writable bits */
 #define        ARMV7_EVTYPE_EVENT      0xff            /* Mask for EVENT bits */
 
 /*
index 1bdfd87c8e41d026bcaf9fe1893c2645e6dce6dd..31644f1978d56d8e6fad053804ed8d730bff9003 100644 (file)
@@ -285,6 +285,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
         * switch away from it before attempting any exclusive accesses.
         */
        cpu_switch_mm(mm->pgd, mm);
+       local_flush_bp_all();
        enter_lazy_tlb(mm, current);
        local_flush_tlb_all();
 
index 02c5d2ce23bf121f17479bba2b52460419481930..bd0300531399e5eeb066a45f3c29b0d897c23b42 100644 (file)
@@ -64,6 +64,11 @@ static inline void ipi_flush_tlb_kernel_range(void *arg)
        local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
 }
 
+static inline void ipi_flush_bp_all(void *ignored)
+{
+       local_flush_bp_all();
+}
+
 void flush_tlb_all(void)
 {
        if (tlb_ops_need_broadcast())
@@ -127,3 +132,10 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end)
                local_flush_tlb_kernel_range(start, end);
 }
 
+void flush_bp_all(void)
+{
+       if (tlb_ops_need_broadcast())
+               on_each_cpu(ipi_flush_bp_all, NULL, 1);
+       else
+               local_flush_bp_all();
+}
index c092115d903a8ad4e4c789398a7c444064ff273a..3f256503748005346d5f1388aa1ed30978433b03 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
 
+#include <asm/smp_plat.h>
 #include <asm/smp_twd.h>
 #include <asm/localtimer.h>
 
@@ -373,6 +374,9 @@ void __init twd_local_timer_of_register(void)
        struct device_node *np;
        int err;
 
+       if (!is_smp() || !setup_max_cpus)
+               return;
+
        np = of_find_matching_node(NULL, twd_of_match);
        if (!np)
                return;
index 358bca3a995ed37ec66da93ec40841abd99fa804..c59c97ea8268b461b45b8d46066b2f4208f9afe5 100644 (file)
@@ -68,6 +68,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
        ret = __cpu_suspend(arg, fn);
        if (ret == 0) {
                cpu_switch_mm(mm->pgd, mm);
+               local_flush_bp_all();
                local_flush_tlb_all();
        }
 
index 650d5923ab83cd849c38db3a64c55fccf36a631a..d912e7397ecc94a190a132b649f667b94774c1b9 100644 (file)
@@ -19,9 +19,9 @@
 1:     subs    r2, r2, #4              @ 1 do we have enough
        blt     5f                      @ 1 bytes to align with?
        cmp     r3, #2                  @ 1
-       strltb  r1, [r0], #1            @ 1
-       strleb  r1, [r0], #1            @ 1
-       strb    r1, [r0], #1            @ 1
+       strltb  r1, [ip], #1            @ 1
+       strleb  r1, [ip], #1            @ 1
+       strb    r1, [ip], #1            @ 1
        add     r2, r2, r3              @ 1 (r2 = r2 - (4 - r3))
 /*
  * The pointer is now aligned and the length is adjusted.  Try doing the
  */
 
 ENTRY(memset)
-       ands    r3, r0, #3              @ 1 unaligned?
+/*
+ * Preserve the contents of r0 for the return value.
+ */
+       mov     ip, r0
+       ands    r3, ip, #3              @ 1 unaligned?
        bne     1b                      @ 1
 /*
- * we know that the pointer in r0 is aligned to a word boundary.
+ * we know that the pointer in ip is aligned to a word boundary.
  */
        orr     r1, r1, r1, lsl #8
        orr     r1, r1, r1, lsl #16
@@ -43,29 +47,28 @@ ENTRY(memset)
 #if ! CALGN(1)+0
 
 /*
- * We need an extra register for this loop - save the return address and
- * use the LR
+ * We need 2 extra registers for this loop - use r8 and the LR
  */
-       str     lr, [sp, #-4]!
-       mov     ip, r1
+       stmfd   sp!, {r8, lr}
+       mov     r8, r1
        mov     lr, r1
 
 2:     subs    r2, r2, #64
-       stmgeia r0!, {r1, r3, ip, lr}   @ 64 bytes at a time.
-       stmgeia r0!, {r1, r3, ip, lr}
-       stmgeia r0!, {r1, r3, ip, lr}
-       stmgeia r0!, {r1, r3, ip, lr}
+       stmgeia ip!, {r1, r3, r8, lr}   @ 64 bytes at a time.
+       stmgeia ip!, {r1, r3, r8, lr}
+       stmgeia ip!, {r1, r3, r8, lr}
+       stmgeia ip!, {r1, r3, r8, lr}
        bgt     2b
-       ldmeqfd sp!, {pc}               @ Now <64 bytes to go.
+       ldmeqfd sp!, {r8, pc}           @ Now <64 bytes to go.
 /*
  * No need to correct the count; we're only testing bits from now on
  */
        tst     r2, #32
-       stmneia r0!, {r1, r3, ip, lr}
-       stmneia r0!, {r1, r3, ip, lr}
+       stmneia ip!, {r1, r3, r8, lr}
+       stmneia ip!, {r1, r3, r8, lr}
        tst     r2, #16
-       stmneia r0!, {r1, r3, ip, lr}
-       ldr     lr, [sp], #4
+       stmneia ip!, {r1, r3, r8, lr}
+       ldmfd   sp!, {r8, lr}
 
 #else
 
@@ -74,54 +77,54 @@ ENTRY(memset)
  * whole cache lines at once.
  */
 
-       stmfd   sp!, {r4-r7, lr}
+       stmfd   sp!, {r4-r8, lr}
        mov     r4, r1
        mov     r5, r1
        mov     r6, r1
        mov     r7, r1
-       mov     ip, r1
+       mov     r8, r1
        mov     lr, r1
 
        cmp     r2, #96
-       tstgt   r0, #31
+       tstgt   ip, #31
        ble     3f
 
-       and     ip, r0, #31
-       rsb     ip, ip, #32
-       sub     r2, r2, ip
-       movs    ip, ip, lsl #(32 - 4)
-       stmcsia r0!, {r4, r5, r6, r7}
-       stmmiia r0!, {r4, r5}
-       tst     ip, #(1 << 30)
-       mov     ip, r1
-       strne   r1, [r0], #4
+       and     r8, ip, #31
+       rsb     r8, r8, #32
+       sub     r2, r2, r8
+       movs    r8, r8, lsl #(32 - 4)
+       stmcsia ip!, {r4, r5, r6, r7}
+       stmmiia ip!, {r4, r5}
+       tst     r8, #(1 << 30)
+       mov     r8, r1
+       strne   r1, [ip], #4
 
 3:     subs    r2, r2, #64
-       stmgeia r0!, {r1, r3-r7, ip, lr}
-       stmgeia r0!, {r1, r3-r7, ip, lr}
+       stmgeia ip!, {r1, r3-r8, lr}
+       stmgeia ip!, {r1, r3-r8, lr}
        bgt     3b
-       ldmeqfd sp!, {r4-r7, pc}
+       ldmeqfd sp!, {r4-r8, pc}
 
        tst     r2, #32
-       stmneia r0!, {r1, r3-r7, ip, lr}
+       stmneia ip!, {r1, r3-r8, lr}
        tst     r2, #16
-       stmneia r0!, {r4-r7}
-       ldmfd   sp!, {r4-r7, lr}
+       stmneia ip!, {r4-r7}
+       ldmfd   sp!, {r4-r8, lr}
 
 #endif
 
 4:     tst     r2, #8
-       stmneia r0!, {r1, r3}
+       stmneia ip!, {r1, r3}
        tst     r2, #4
-       strne   r1, [r0], #4
+       strne   r1, [ip], #4
 /*
  * When we get here, we've got less than 4 bytes to zero.  We
  * may have an unaligned pointer as well.
  */
 5:     tst     r2, #2
-       strneb  r1, [r0], #1
-       strneb  r1, [r0], #1
+       strneb  r1, [ip], #1
+       strneb  r1, [ip], #1
        tst     r2, #1
-       strneb  r1, [r0], #1
+       strneb  r1, [ip], #1
        mov     pc, lr
 ENDPROC(memset)
index 27c2cb7ab8130bc606b82d25c5c457bb8a3959e8..1504b68f4c6672d132628307d97ee0aab534800f 100644 (file)
@@ -168,7 +168,7 @@ void __init netx_init_irq(void)
 {
        int irq;
 
-       vic_init(io_p2v(NETX_PA_VIC), 0, ~0, 0);
+       vic_init(io_p2v(NETX_PA_VIC), NETX_IRQ_VIC_START, ~0, 0);
 
        for (irq = NETX_IRQ_HIF_CHAINED(0); irq <= NETX_IRQ_HIF_LAST; irq++) {
                irq_set_chip_and_handler(irq, &netx_hif_chip,
index 6ce914d54a30f922034074a2e8d487ea27f014d7..8f74a844a775568edd1a22ea423e6f705c3f6e9b 100644 (file)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#define NETX_IRQ_VIC_START   0
-#define NETX_IRQ_SOFTINT     0
-#define NETX_IRQ_TIMER0      1
-#define NETX_IRQ_TIMER1      2
-#define NETX_IRQ_TIMER2      3
-#define NETX_IRQ_SYSTIME_NS  4
-#define NETX_IRQ_SYSTIME_S   5
-#define NETX_IRQ_GPIO_15     6
-#define NETX_IRQ_WATCHDOG    7
-#define NETX_IRQ_UART0       8
-#define NETX_IRQ_UART1       9
-#define NETX_IRQ_UART2      10
-#define NETX_IRQ_USB        11
-#define NETX_IRQ_SPI        12
-#define NETX_IRQ_I2C        13
-#define NETX_IRQ_LCD        14
-#define NETX_IRQ_HIF        15
-#define NETX_IRQ_GPIO_0_14  16
-#define NETX_IRQ_XPEC0      17
-#define NETX_IRQ_XPEC1      18
-#define NETX_IRQ_XPEC2      19
-#define NETX_IRQ_XPEC3      20
-#define NETX_IRQ_XPEC(no)   (17 + (no))
-#define NETX_IRQ_MSYNC0     21
-#define NETX_IRQ_MSYNC1     22
-#define NETX_IRQ_MSYNC2     23
-#define NETX_IRQ_MSYNC3     24
-#define NETX_IRQ_IRQ_PHY    25
-#define NETX_IRQ_ISO_AREA   26
+#define NETX_IRQ_VIC_START     64
+#define NETX_IRQ_SOFTINT       (NETX_IRQ_VIC_START + 0)
+#define NETX_IRQ_TIMER0                (NETX_IRQ_VIC_START + 1)
+#define NETX_IRQ_TIMER1                (NETX_IRQ_VIC_START + 2)
+#define NETX_IRQ_TIMER2                (NETX_IRQ_VIC_START + 3)
+#define NETX_IRQ_SYSTIME_NS    (NETX_IRQ_VIC_START + 4)
+#define NETX_IRQ_SYSTIME_S     (NETX_IRQ_VIC_START + 5)
+#define NETX_IRQ_GPIO_15       (NETX_IRQ_VIC_START + 6)
+#define NETX_IRQ_WATCHDOG      (NETX_IRQ_VIC_START + 7)
+#define NETX_IRQ_UART0         (NETX_IRQ_VIC_START + 8)
+#define NETX_IRQ_UART1         (NETX_IRQ_VIC_START + 9)
+#define NETX_IRQ_UART2         (NETX_IRQ_VIC_START + 10)
+#define NETX_IRQ_USB           (NETX_IRQ_VIC_START + 11)
+#define NETX_IRQ_SPI           (NETX_IRQ_VIC_START + 12)
+#define NETX_IRQ_I2C           (NETX_IRQ_VIC_START + 13)
+#define NETX_IRQ_LCD           (NETX_IRQ_VIC_START + 14)
+#define NETX_IRQ_HIF           (NETX_IRQ_VIC_START + 15)
+#define NETX_IRQ_GPIO_0_14     (NETX_IRQ_VIC_START + 16)
+#define NETX_IRQ_XPEC0         (NETX_IRQ_VIC_START + 17)
+#define NETX_IRQ_XPEC1         (NETX_IRQ_VIC_START + 18)
+#define NETX_IRQ_XPEC2         (NETX_IRQ_VIC_START + 19)
+#define NETX_IRQ_XPEC3         (NETX_IRQ_VIC_START + 20)
+#define NETX_IRQ_XPEC(no)      (NETX_IRQ_VIC_START + 17 + (no))
+#define NETX_IRQ_MSYNC0                (NETX_IRQ_VIC_START + 21)
+#define NETX_IRQ_MSYNC1                (NETX_IRQ_VIC_START + 22)
+#define NETX_IRQ_MSYNC2                (NETX_IRQ_VIC_START + 23)
+#define NETX_IRQ_MSYNC3                (NETX_IRQ_VIC_START + 24)
+#define NETX_IRQ_IRQ_PHY       (NETX_IRQ_VIC_START + 25)
+#define NETX_IRQ_ISO_AREA      (NETX_IRQ_VIC_START + 26)
 /* int 27 is reserved */
 /* int 28 is reserved */
-#define NETX_IRQ_TIMER3     29
-#define NETX_IRQ_TIMER4     30
+#define NETX_IRQ_TIMER3                (NETX_IRQ_VIC_START + 29)
+#define NETX_IRQ_TIMER4                (NETX_IRQ_VIC_START + 30)
 /* int 31 is reserved */
 
-#define NETX_IRQS 32
+#define NETX_IRQS              (NETX_IRQ_VIC_START + 32)
 
 /* for multiplexed irqs on gpio 0..14 */
 #define NETX_IRQ_GPIO(x) (NETX_IRQS + (x))
index 7a0511191f6bb0c3d6bf8c8148db973ce48c973d..a5a4b2bc42ba353e7e0ae94461cf4d8691b2b68a 100644 (file)
@@ -152,9 +152,9 @@ static int is_reserved_asid(u64 asid)
        return 0;
 }
 
-static void new_context(struct mm_struct *mm, unsigned int cpu)
+static u64 new_context(struct mm_struct *mm, unsigned int cpu)
 {
-       u64 asid = mm->context.id;
+       u64 asid = atomic64_read(&mm->context.id);
        u64 generation = atomic64_read(&asid_generation);
 
        if (asid != 0 && is_reserved_asid(asid)) {
@@ -181,13 +181,14 @@ static void new_context(struct mm_struct *mm, unsigned int cpu)
                cpumask_clear(mm_cpumask(mm));
        }
 
-       mm->context.id = asid;
+       return asid;
 }
 
 void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
 {
        unsigned long flags;
        unsigned int cpu = smp_processor_id();
+       u64 asid;
 
        if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq))
                __check_vmalloc_seq(mm);
@@ -198,20 +199,26 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
         */
        cpu_set_reserved_ttbr0();
 
-       if (!((mm->context.id ^ atomic64_read(&asid_generation)) >> ASID_BITS)
-           && atomic64_xchg(&per_cpu(active_asids, cpu), mm->context.id))
+       asid = atomic64_read(&mm->context.id);
+       if (!((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS)
+           && atomic64_xchg(&per_cpu(active_asids, cpu), asid))
                goto switch_mm_fastpath;
 
        raw_spin_lock_irqsave(&cpu_asid_lock, flags);
        /* Check that our ASID belongs to the current generation. */
-       if ((mm->context.id ^ atomic64_read(&asid_generation)) >> ASID_BITS)
-               new_context(mm, cpu);
-
-       atomic64_set(&per_cpu(active_asids, cpu), mm->context.id);
-       cpumask_set_cpu(cpu, mm_cpumask(mm));
+       asid = atomic64_read(&mm->context.id);
+       if ((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS) {
+               asid = new_context(mm, cpu);
+               atomic64_set(&mm->context.id, asid);
+       }
 
-       if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending))
+       if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) {
+               local_flush_bp_all();
                local_flush_tlb_all();
+       }
+
+       atomic64_set(&per_cpu(active_asids, cpu), asid);
+       cpumask_set_cpu(cpu, mm_cpumask(mm));
        raw_spin_unlock_irqrestore(&cpu_asid_lock, flags);
 
 switch_mm_fastpath:
index 2dffc010cc41b930f28a07f1dfb2b88045fc3049..5ee505c937d171902839369f3cd98c13b93b11ca 100644 (file)
@@ -141,6 +141,7 @@ void setup_mm_for_reboot(void)
 {
        /* Switch to the identity mapping. */
        cpu_switch_mm(idmap_pgd, &init_mm);
+       local_flush_bp_all();
 
 #ifdef CONFIG_CPU_HAS_ASID
        /*
index 50bf1dafc9eafca49cf80a32ffbf5b529cb0cf40..6ffd78c0f9abeeacf0295dd888a9b537e9249604 100644 (file)
@@ -48,7 +48,7 @@
 ENTRY(cpu_v7_switch_mm)
 #ifdef CONFIG_MMU
        mmid    r1, r1                          @ get mm->context.id
-       and     r3, r1, #0xff
+       asid    r3, r1
        mov     r3, r3, lsl #(48 - 32)          @ ASID
        mcrr    p15, 0, r0, r3, c2              @ set TTB 0
        isb
index 433f5e8a2cd147cd7ae696d3e42b0123f6b4f306..2eda28414abb5a557e559387f6a6b46a76ae6819 100644 (file)
@@ -619,6 +619,7 @@ static struct file_system_type pfm_fs_type = {
        .mount    = pfmfs_mount,
        .kill_sb  = kill_anon_super,
 };
+MODULE_ALIAS_FS("pfmfs");
 
 DEFINE_PER_CPU(unsigned long, pfm_syst_info);
 DEFINE_PER_CPU(struct task_struct *, pmu_owner);
index d63b9d0e57dd1ca83e384c0221162cc6cac827ba..d2baf69617940d68399775a3030269ead857dc14 100644 (file)
@@ -100,9 +100,6 @@ typedef unsigned long elf_fpregset_t;
 
 #define ELF_PLATFORM  (NULL)
 
-#define SET_PERSONALITY(ex) \
-       set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
-
 #define STACK_RND_MASK (0)
 
 #ifdef CONFIG_METAG_USER_TCM
index cd7f2f2ad416b9bf91fd7206c29117f753d1041f..975f2f4e3ecf55f17521a3605c883bfd434fe554 100644 (file)
@@ -40,6 +40,7 @@ endchoice
 
 config NUMA
        bool "Non Uniform Memory Access (NUMA) Support"
+       select ARCH_WANT_NUMA_VARIABLE_LOCALITY
        help
          Some Meta systems have MMU-mappable on-chip memories with
          lower latencies than main memory. This enables support for
index a5f8264d2d3c3c58d5755af56d5e911fc3670212..125e16520061289aff815417fd7aa18ec41e3df7 100644 (file)
        STEPUP4((t)+16, fn)
 
 _GLOBAL(powerpc_sha_transform)
-       PPC_STLU r1,-STACKFRAMESIZE(r1)
+       PPC_STLU r1,-INT_FRAME_SIZE(r1)
        SAVE_8GPRS(14, r1)
        SAVE_10GPRS(22, r1)
 
@@ -175,5 +175,5 @@ _GLOBAL(powerpc_sha_transform)
 
        REST_8GPRS(14, r1)
        REST_10GPRS(22, r1)
-       addi    r1,r1,STACKFRAMESIZE
+       addi    r1,r1,INT_FRAME_SIZE
        blr
index ef918a2328bba044173e61a799d23f8ae3cf2576..08bd299c75b113d1dd55ea827853bb616fdb5899 100644 (file)
@@ -52,8 +52,6 @@
 #define smp_mb__before_clear_bit()     smp_mb()
 #define smp_mb__after_clear_bit()      smp_mb()
 
-#define BITOP_LE_SWIZZLE       ((BITS_PER_LONG-1) & ~0x7)
-
 /* Macro for generating the ***_bits() functions */
 #define DEFINE_BITOP(fn, op, prefix, postfix)  \
 static __inline__ void fn(unsigned long mask,  \
index e6658612203010aec0d3ba6ebb1f9c646e639575..c9c67fc888c93d229b23a617d0fd9c2aa7a71e79 100644 (file)
 #define SPRN_HSRR0     0x13A   /* Hypervisor Save/Restore 0 */
 #define SPRN_HSRR1     0x13B   /* Hypervisor Save/Restore 1 */
 #define SPRN_FSCR      0x099   /* Facility Status & Control Register */
-#define FSCR_TAR       (1<<8)  /* Enable Target Adress Register */
+#define   FSCR_TAR     (1 << (63-55)) /* Enable Target Address Register */
+#define   FSCR_DSCR    (1 << (63-61)) /* Enable Data Stream Control Register */
 #define SPRN_TAR       0x32f   /* Target Address Register */
 #define SPRN_LPCR      0x13E   /* LPAR Control Register */
 #define   LPCR_VPM0    (1ul << (63-0))
index 535b6d8a41ccae912590c0ec14d2fb355f0f4800..ebbec52d21bd69c634a547a82d707f1d7244b2e0 100644 (file)
@@ -358,3 +358,4 @@ SYSCALL_SPU(setns)
 COMPAT_SYS(process_vm_readv)
 COMPAT_SYS(process_vm_writev)
 SYSCALL(finit_module)
+SYSCALL(ni_syscall) /* sys_kcmp */
index f25b5c45c4359632d2b5259438173f493bfb6810..1487f0f12293bfd31ecdc1816072c52fc12d1b11 100644 (file)
@@ -12,7 +12,7 @@
 #include <uapi/asm/unistd.h>
 
 
-#define __NR_syscalls          354
+#define __NR_syscalls          355
 
 #define __NR__exit __NR_exit
 #define NR_syscalls    __NR_syscalls
index 8c478c6c6b1e41c7090b06a8b52815f7d537ff89..74cb4d72d6739baafba86eeb4fe1d591f5dd99fd 100644 (file)
 #define __NR_process_vm_readv  351
 #define __NR_process_vm_writev 352
 #define __NR_finit_module      353
+#define __NR_kcmp              354
 
 
 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
index d29facbf9a288490a7552331e498eea259eb713f..ea847abb0d0a5fae6738c1bed0dc863d78358ded 100644 (file)
@@ -48,6 +48,7 @@ _GLOBAL(__restore_cpu_power7)
 
 _GLOBAL(__setup_cpu_power8)
        mflr    r11
+       bl      __init_FSCR
        bl      __init_hvmode_206
        mtlr    r11
        beqlr
@@ -56,13 +57,13 @@ _GLOBAL(__setup_cpu_power8)
        mfspr   r3,SPRN_LPCR
        oris    r3, r3, LPCR_AIL_3@h
        bl      __init_LPCR
-       bl      __init_FSCR
        bl      __init_TLB
        mtlr    r11
        blr
 
 _GLOBAL(__restore_cpu_power8)
        mflr    r11
+       bl      __init_FSCR
        mfmsr   r3
        rldicl. r0,r3,4,63
        beqlr
@@ -115,7 +116,7 @@ __init_LPCR:
 
 __init_FSCR:
        mfspr   r3,SPRN_FSCR
-       ori     r3,r3,FSCR_TAR
+       ori     r3,r3,FSCR_TAR|FSCR_DSCR
        mtspr   SPRN_FSCR,r3
        blr
 
index a8a5361fb70c716b74fe6abd880ce877be52c10a..87ef8f5ee5bc52242af82aec893b274a6a8ec47d 100644 (file)
@@ -74,13 +74,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)                              \
        mflr    r10 ;                                           \
        ld      r12,PACAKBASE(r13) ;                            \
        LOAD_HANDLER(r12, system_call_entry_direct) ;           \
-       mtlr    r12 ;                                           \
+       mtctr   r12 ;                                           \
        mfspr   r12,SPRN_SRR1 ;                                 \
        /* Re-use of r13... No spare regs to do this */ \
        li      r13,MSR_RI ;                                    \
        mtmsrd  r13,1 ;                                         \
        GET_PACA(r13) ; /* get r13 back */                      \
-       blr ;
+       bctr ;
 #else
        /* We can branch directly */
 #define SYSCALL_PSERIES_2_DIRECT                               \
index 863184b182f47c09e0626d8147ebcd1e508af328..3f3bb4cdbbecb9f5a92b4ab662a8fd234a5443ac 100644 (file)
@@ -749,6 +749,7 @@ static struct file_system_type spufs_type = {
        .mount = spufs_mount,
        .kill_sb = kill_litter_super,
 };
+MODULE_ALIAS_FS("spufs");
 
 static int __init spufs_init(void)
 {
index fcf4b4cbeaf331aa7986b0b705bc4bbe2148ee7b..4557e91626c43bd58d95a1730456557eab3aee2f 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 
 #include <asm/hvcall.h>
 #include <asm/hvcserver.h>
@@ -188,9 +189,9 @@ int hvcs_get_partner_info(uint32_t unit_address, struct list_head *head,
                        = (unsigned int)last_p_partition_ID;
 
                /* copy the Null-term char too */
-               strncpy(&next_partner_info->location_code[0],
+               strlcpy(&next_partner_info->location_code[0],
                        (char *)&pi_buff[2],
-                       strlen((char *)&pi_buff[2]) + 1);
+                       sizeof(next_partner_info->location_code));
 
                list_add_tail(&(next_partner_info->node), head);
                next_partner_info = NULL;
index 8538015ed4a0487c52b80be2035b8e301cc94f5e..5f7d7ba2874c8a6fa14b49bcefc7ef09ef59dc6b 100644 (file)
@@ -456,6 +456,7 @@ static struct file_system_type hypfs_type = {
        .mount          = hypfs_mount,
        .kill_sb        = hypfs_kill_super
 };
+MODULE_ALIAS_FS("s390_hypfs");
 
 static const struct super_operations hypfs_s_ops = {
        .statfs         = simple_statfs,
index 001d418a8957721c99c41947b1e54bdb2dfd10f2..78f1f2ded86c7ae6dac3c156f1aa393653058b33 100644 (file)
@@ -288,6 +288,9 @@ long compat_sys_sync_file_range2(int fd, unsigned int flags,
 long compat_sys_fallocate(int fd, int mode,
                          u32 offset_lo, u32 offset_hi,
                          u32 len_lo, u32 len_hi);
+long compat_sys_llseek(unsigned int fd, unsigned int offset_high,
+                      unsigned int offset_low, loff_t __user * result,
+                      unsigned int origin);
 
 /* Assembly trampoline to avoid clobbering r0. */
 long _compat_sys_rt_sigreturn(void);
index 7f72401b4f458347d8cba0cc7fd4ab637a61b616..6ea4cdb3c6a03e3ab5991969bd485047cac23bc3 100644 (file)
  * adapt the usual convention.
  */
 
-long compat_sys_truncate64(char __user *filename, u32 dummy, u32 low, u32 high)
+COMPAT_SYSCALL_DEFINE4(truncate64, char __user *, filename, u32, dummy,
+                       u32, low, u32, high)
 {
        return sys_truncate(filename, ((loff_t)high << 32) | low);
 }
 
-long compat_sys_ftruncate64(unsigned int fd, u32 dummy, u32 low, u32 high)
+COMPAT_SYSCALL_DEFINE4(ftruncate64, unsigned int, fd, u32, dummy,
+                       u32, low, u32, high)
 {
        return sys_ftruncate(fd, ((loff_t)high << 32) | low);
 }
 
-long compat_sys_pread64(unsigned int fd, char __user *ubuf, size_t count,
-                       u32 dummy, u32 low, u32 high)
+COMPAT_SYSCALL_DEFINE6(pread64, unsigned int, fd, char __user *, ubuf,
+                       size_t, count, u32, dummy, u32, low, u32, high)
 {
        return sys_pread64(fd, ubuf, count, ((loff_t)high << 32) | low);
 }
 
-long compat_sys_pwrite64(unsigned int fd, char __user *ubuf, size_t count,
-                        u32 dummy, u32 low, u32 high)
+COMPAT_SYSCALL_DEFINE6(pwrite64, unsigned int, fd, char __user *, ubuf,
+                       size_t, count, u32, dummy, u32, low, u32, high)
 {
        return sys_pwrite64(fd, ubuf, count, ((loff_t)high << 32) | low);
 }
 
-long compat_sys_lookup_dcookie(u32 low, u32 high, char __user *buf, size_t len)
+COMPAT_SYSCALL_DEFINE4(lookup_dcookie, u32, low, u32, high,
+                       char __user *, buf, size_t, len)
 {
        return sys_lookup_dcookie(((loff_t)high << 32) | low, buf, len);
 }
 
-long compat_sys_sync_file_range2(int fd, unsigned int flags,
-                                u32 offset_lo, u32 offset_hi,
-                                u32 nbytes_lo, u32 nbytes_hi)
+COMPAT_SYSCALL_DEFINE6(sync_file_range2, int, fd, unsigned int, flags,
+                       u32, offset_lo, u32, offset_hi,
+                       u32, nbytes_lo, u32, nbytes_hi)
 {
        return sys_sync_file_range(fd, ((loff_t)offset_hi << 32) | offset_lo,
                                   ((loff_t)nbytes_hi << 32) | nbytes_lo,
                                   flags);
 }
 
-long compat_sys_fallocate(int fd, int mode,
-                         u32 offset_lo, u32 offset_hi,
-                         u32 len_lo, u32 len_hi)
+COMPAT_SYSCALL_DEFINE6(fallocate, int, fd, int, mode,
+                       u32, offset_lo, u32, offset_hi,
+                       u32, len_lo, u32, len_hi)
 {
        return sys_fallocate(fd, mode, ((loff_t)offset_hi << 32) | offset_lo,
                             ((loff_t)len_hi << 32) | len_lo);
 }
 
+/*
+ * Avoid bug in generic sys_llseek() that specifies offset_high and
+ * offset_low as "unsigned long", thus making it possible to pass
+ * a sign-extended high 32 bits in offset_low.
+ */
+COMPAT_SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned int, offset_high,
+                      unsigned int, offset_low, loff_t __user *, result,
+                      unsigned int, origin)
+{
+       return sys_llseek(fd, offset_high, offset_low, result, origin);
+}
 /* Provide the compat syscall number to call mapping. */
 #undef __SYSCALL
 #define __SYSCALL(nr, call) [nr] = (call),
@@ -83,6 +98,7 @@ long compat_sys_fallocate(int fd, int mode,
 /* See comments in sys.c */
 #define compat_sys_fadvise64_64 sys32_fadvise64_64
 #define compat_sys_readahead sys32_readahead
+#define sys_llseek compat_sys_llseek
 
 /* Call the assembly trampolines where necessary. */
 #define compat_sys_rt_sigreturn _compat_sys_rt_sigreturn
index 5b5e9cb774b59c27471126091424d2b0a8eb50d9..653668d140f994e543ad52e46d0c8402d5fe9259 100644 (file)
  * analysis of kexec-tools; if other broken bootloaders initialize a
  * different set of fields we will need to figure out how to disambiguate.
  *
+ * Note: efi_info is commonly left uninitialized, but that field has a
+ * private magic, so it is better to leave it unchanged.
  */
 static void sanitize_boot_params(struct boot_params *boot_params)
 {
+       /* 
+        * IMPORTANT NOTE TO BOOTLOADER AUTHORS: do not simply clear
+        * this field.  The purpose of this field is to guarantee
+        * compliance with the x86 boot spec located in
+        * Documentation/x86/boot.txt .  That spec says that the
+        * *whole* structure should be cleared, after which only the
+        * portion defined by struct setup_header (boot_params->hdr)
+        * should be copied in.
+        *
+        * If you're having an issue because the sentinel is set, you
+        * need to change the whole structure to be cleared, not this
+        * (or any other) individual field, or you will soon have
+        * problems again.
+        */
        if (boot_params->sentinel) {
-               /*fields in boot_params are not valid, clear them */
+               /* fields in boot_params are left uninitialized, clear them */
                memset(&boot_params->olpc_ofw_header, 0,
-                      (char *)&boot_params->alt_mem_k -
+                      (char *)&boot_params->efi_info -
                        (char *)&boot_params->olpc_ofw_header);
                memset(&boot_params->kbd_status, 0,
                       (char *)&boot_params->hdr -
index 84d32855f65c329c04dae97d4cd77bd2053e824e..90d8cc930f5ed134735f7697e016a83e5657dcb8 100644 (file)
@@ -171,9 +171,15 @@ static struct resource bss_resource = {
 
 #ifdef CONFIG_X86_32
 /* cpu data as detected by the assembly code in head.S */
-struct cpuinfo_x86 new_cpu_data __cpuinitdata = {0, 0, 0, 0, -1, 1, 0, 0, -1};
+struct cpuinfo_x86 new_cpu_data __cpuinitdata = {
+       .wp_works_ok = -1,
+       .fdiv_bug = -1,
+};
 /* common cpu data for all cpus */
-struct cpuinfo_x86 boot_cpu_data __read_mostly = {0, 0, 0, 0, -1, 1, 0, 0, -1};
+struct cpuinfo_x86 boot_cpu_data __read_mostly = {
+       .wp_works_ok = -1,
+       .fdiv_bug = -1,
+};
 EXPORT_SYMBOL(boot_cpu_data);
 
 unsigned int def_to_bigsmp;
index a6ceaedc396a2d67f3514e3f162a614b5444cd74..9f190a2a00e9916e2369e571a5eca8bf2b22d56c 100644 (file)
@@ -1365,9 +1365,8 @@ static inline void mwait_play_dead(void)
        unsigned int eax, ebx, ecx, edx;
        unsigned int highest_cstate = 0;
        unsigned int highest_subcstate = 0;
-       int i;
        void *mwait_ptr;
-       struct cpuinfo_x86 *c = __this_cpu_ptr(&cpu_info);
+       int i;
 
        if (!this_cpu_has(X86_FEATURE_MWAIT))
                return;
index 4903a03ae876338c2ad351f5db5988f35bb35d08..59b7fc453277399bd574dbde43b0bd8d295c9414 100644 (file)
@@ -410,9 +410,8 @@ void __init init_mem_mapping(void)
        /* the ISA range is always mapped regardless of memory holes */
        init_memory_mapping(0, ISA_END_ADDRESS);
 
-       /* xen has big range in reserved near end of ram, skip it at first */
-       addr = memblock_find_in_range(ISA_END_ADDRESS, end, PMD_SIZE,
-                        PAGE_SIZE);
+       /* xen has big range in reserved near end of ram, skip it at first.*/
+       addr = memblock_find_in_range(ISA_END_ADDRESS, end, PMD_SIZE, PMD_SIZE);
        real_end = addr + PMD_SIZE;
 
        /* step_size need to be small so pgt_buf from BRK could cover it */
index 2610bd93c896871936caaa970abd414d039ff790..657438858e8358745484c828158634fba41a5b1c 100644 (file)
@@ -563,6 +563,13 @@ int kernel_map_sync_memtype(u64 base, unsigned long size, unsigned long flags)
        if (base > __pa(high_memory-1))
                return 0;
 
+       /*
+        * some areas in the middle of the kernel identity range
+        * are not mapped, like the PCI space.
+        */
+       if (!page_is_ram(base >> PAGE_SHIFT))
+               return 0;
+
        id_sz = (__pa(high_memory-1) <= base + size) ?
                                __pa(high_memory) - base :
                                size;
index ef6f155469b58ed370aa9d1232d5c2e6bb14c29a..40a84cc6740c6c6522afc6bac6d5d5d2178a86bd 100644 (file)
@@ -36,12 +36,11 @@ int register_acpi_bus_type(struct acpi_bus_type *type)
 {
        if (acpi_disabled)
                return -ENODEV;
-       if (type && type->bus && type->find_device) {
+       if (type && type->match && type->find_device) {
                down_write(&bus_type_sem);
                list_add_tail(&type->list, &bus_type_list);
                up_write(&bus_type_sem);
-               printk(KERN_INFO PREFIX "bus type %s registered\n",
-                      type->bus->name);
+               printk(KERN_INFO PREFIX "bus type %s registered\n", type->name);
                return 0;
        }
        return -ENODEV;
@@ -56,24 +55,21 @@ int unregister_acpi_bus_type(struct acpi_bus_type *type)
                down_write(&bus_type_sem);
                list_del_init(&type->list);
                up_write(&bus_type_sem);
-               printk(KERN_INFO PREFIX "ACPI bus type %s unregistered\n",
-                      type->bus->name);
+               printk(KERN_INFO PREFIX "bus type %s unregistered\n",
+                      type->name);
                return 0;
        }
        return -ENODEV;
 }
 EXPORT_SYMBOL_GPL(unregister_acpi_bus_type);
 
-static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type)
+static struct acpi_bus_type *acpi_get_bus_type(struct device *dev)
 {
        struct acpi_bus_type *tmp, *ret = NULL;
 
-       if (!type)
-               return NULL;
-
        down_read(&bus_type_sem);
        list_for_each_entry(tmp, &bus_type_list, list) {
-               if (tmp->bus == type) {
+               if (tmp->match(dev)) {
                        ret = tmp;
                        break;
                }
@@ -82,22 +78,6 @@ static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type)
        return ret;
 }
 
-static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle)
-{
-       struct acpi_bus_type *tmp;
-       int ret = -ENODEV;
-
-       down_read(&bus_type_sem);
-       list_for_each_entry(tmp, &bus_type_list, list) {
-               if (tmp->find_bridge && !tmp->find_bridge(dev, handle)) {
-                       ret = 0;
-                       break;
-               }
-       }
-       up_read(&bus_type_sem);
-       return ret;
-}
-
 static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used,
                                      void *addr_p, void **ret_p)
 {
@@ -261,29 +241,12 @@ err:
 
 static int acpi_platform_notify(struct device *dev)
 {
-       struct acpi_bus_type *type;
+       struct acpi_bus_type *type = acpi_get_bus_type(dev);
        acpi_handle handle;
        int ret;
 
        ret = acpi_bind_one(dev, NULL);
-       if (ret && (!dev->bus || !dev->parent)) {
-               /* bridge devices genernally haven't bus or parent */
-               ret = acpi_find_bridge_device(dev, &handle);
-               if (!ret) {
-                       ret = acpi_bind_one(dev, handle);
-                       if (ret)
-                               goto out;
-               }
-       }
-
-       type = acpi_get_bus_type(dev->bus);
-       if (ret) {
-               if (!type || !type->find_device) {
-                       DBG("No ACPI bus support for %s\n", dev_name(dev));
-                       ret = -EINVAL;
-                       goto out;
-               }
-
+       if (ret && type) {
                ret = type->find_device(dev, &handle);
                if (ret) {
                        DBG("Unable to get handle for %s\n", dev_name(dev));
@@ -316,7 +279,7 @@ static int acpi_platform_notify_remove(struct device *dev)
 {
        struct acpi_bus_type *type;
 
-       type = acpi_get_bus_type(dev->bus);
+       type = acpi_get_bus_type(dev);
        if (type && type->cleanup)
                type->cleanup(dev);
 
index eff722278ff539535bec85d5f5f6f4f2b04b79bf..164d49569aebfbd3e15991bf68aa2eb13c42fe6a 100644 (file)
@@ -158,8 +158,7 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
        }
 
 exit:
-       if (buffer.pointer)
-               kfree(buffer.pointer);
+       kfree(buffer.pointer);
        return apic_id;
 }
 
index df34bd04ae62ba88e4acc6735515e41af03aff7d..bec717ffd25f5ff7c016f57365a380dc8e91b7fb 100644 (file)
@@ -559,7 +559,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
                return 0;
 #endif
 
-       BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
+       BUG_ON(pr->id >= nr_cpu_ids);
 
        /*
         * Buggy BIOS check
index 6d3a06a629a1f8e1627f1218d88053cf7857053d..24213033fbae2aee5f033c2a776d2b37084fc88e 100644 (file)
@@ -599,7 +599,6 @@ static void acpi_sleep_suspend_setup(void)
                status = acpi_get_sleep_type_data(i, &type_a, &type_b);
                if (ACPI_SUCCESS(status)) {
                        sleep_states[i] = 1;
-                       pr_cont(" S%d", i);
                }
        }
 
@@ -742,7 +741,6 @@ static void acpi_sleep_hibernate_setup(void)
        hibernation_set_ops(old_suspend_ordering ?
                        &acpi_hibernation_ops_old : &acpi_hibernation_ops);
        sleep_states[ACPI_STATE_S4] = 1;
-       pr_cont(KERN_CONT " S4");
        if (nosigcheck)
                return;
 
@@ -788,6 +786,9 @@ int __init acpi_sleep_init(void)
 {
        acpi_status status;
        u8 type_a, type_b;
+       char supported[ACPI_S_STATE_COUNT * 3 + 1];
+       char *pos = supported;
+       int i;
 
        if (acpi_disabled)
                return 0;
@@ -795,7 +796,6 @@ int __init acpi_sleep_init(void)
        acpi_sleep_dmi_check();
 
        sleep_states[ACPI_STATE_S0] = 1;
-       pr_info(PREFIX "(supports S0");
 
        acpi_sleep_suspend_setup();
        acpi_sleep_hibernate_setup();
@@ -803,11 +803,17 @@ int __init acpi_sleep_init(void)
        status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
        if (ACPI_SUCCESS(status)) {
                sleep_states[ACPI_STATE_S5] = 1;
-               pr_cont(" S5");
                pm_power_off_prepare = acpi_power_off_prepare;
                pm_power_off = acpi_power_off;
        }
-       pr_cont(")\n");
+
+       supported[0] = 0;
+       for (i = 0; i < ACPI_S_STATE_COUNT; i++) {
+               if (sleep_states[i])
+                       pos += sprintf(pos, " S%d", i);
+       }
+       pr_info(PREFIX "(supports%s)\n", supported);
+
        /*
         * Register the tts_notifier to reboot notifier list so that the _TTS
         * object can also be evaluated when the system enters S5.
index 0ea1018280bd5b3ee5f6bc60da2421e376fbb510..beea3115577e31a687532cbc1cd3319d900e34a6 100644 (file)
@@ -1144,13 +1144,8 @@ static int ata_acpi_find_device(struct device *dev, acpi_handle *handle)
                return -ENODEV;
 }
 
-static int ata_acpi_find_dummy(struct device *dev, acpi_handle *handle)
-{
-       return -ENODEV;
-}
-
 static struct acpi_bus_type ata_acpi_bus = {
-       .find_bridge = ata_acpi_find_dummy,
+       .name = "ATA",
        .find_device = ata_acpi_find_device,
 };
 
index 2b7f77d3fcb0d518d2a1f4e041f29b61d6e4521b..15beb500a4e4c1a837092e75554ea368dbb1ea1f 100644 (file)
@@ -99,7 +99,6 @@ void device_pm_add(struct device *dev)
                dev_warn(dev, "parent %s should not be sleeping\n",
                        dev_name(dev->parent));
        list_add_tail(&dev->power.entry, &dpm_list);
-       dev_pm_qos_constraints_init(dev);
        mutex_unlock(&dpm_list_mtx);
 }
 
@@ -113,7 +112,6 @@ void device_pm_remove(struct device *dev)
                 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
        complete_all(&dev->power.completion);
        mutex_lock(&dpm_list_mtx);
-       dev_pm_qos_constraints_destroy(dev);
        list_del_init(&dev->power.entry);
        mutex_unlock(&dpm_list_mtx);
        device_wakeup_disable(dev);
index b16686a0a5a29b0d56a253c406a1e54b8b826228..cfc3226ec4928dee99ff95540eed87af1058d5af 100644 (file)
@@ -4,7 +4,7 @@ static inline void device_pm_init_common(struct device *dev)
 {
        if (!dev->power.early_init) {
                spin_lock_init(&dev->power.lock);
-               dev->power.power_state = PMSG_INVALID;
+               dev->power.qos = NULL;
                dev->power.early_init = true;
        }
 }
@@ -56,14 +56,10 @@ extern void device_pm_move_last(struct device *);
 
 static inline void device_pm_sleep_init(struct device *dev) {}
 
-static inline void device_pm_add(struct device *dev)
-{
-       dev_pm_qos_constraints_init(dev);
-}
+static inline void device_pm_add(struct device *dev) {}
 
 static inline void device_pm_remove(struct device *dev)
 {
-       dev_pm_qos_constraints_destroy(dev);
        pm_runtime_remove(dev);
 }
 
index 3d4d1f8aac5c3aa126dd1045f4d2eda48907c29e..5f74587ef258f4598e16c37bf9284d108c475ead 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/mutex.h>
 #include <linux/export.h>
 #include <linux/pm_runtime.h>
+#include <linux/err.h>
 
 #include "power.h"
 
@@ -61,7 +62,7 @@ enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev, s32 mask)
        struct pm_qos_flags *pqf;
        s32 val;
 
-       if (!qos)
+       if (IS_ERR_OR_NULL(qos))
                return PM_QOS_FLAGS_UNDEFINED;
 
        pqf = &qos->flags;
@@ -101,7 +102,8 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_flags);
  */
 s32 __dev_pm_qos_read_value(struct device *dev)
 {
-       return dev->power.qos ? pm_qos_read_value(&dev->power.qos->latency) : 0;
+       return IS_ERR_OR_NULL(dev->power.qos) ?
+               0 : pm_qos_read_value(&dev->power.qos->latency);
 }
 
 /**
@@ -198,20 +200,8 @@ static int dev_pm_qos_constraints_allocate(struct device *dev)
        return 0;
 }
 
-/**
- * dev_pm_qos_constraints_init - Initalize device's PM QoS constraints pointer.
- * @dev: target device
- *
- * Called from the device PM subsystem during device insertion under
- * device_pm_lock().
- */
-void dev_pm_qos_constraints_init(struct device *dev)
-{
-       mutex_lock(&dev_pm_qos_mtx);
-       dev->power.qos = NULL;
-       dev->power.power_state = PMSG_ON;
-       mutex_unlock(&dev_pm_qos_mtx);
-}
+static void __dev_pm_qos_hide_latency_limit(struct device *dev);
+static void __dev_pm_qos_hide_flags(struct device *dev);
 
 /**
  * dev_pm_qos_constraints_destroy
@@ -226,16 +216,15 @@ void dev_pm_qos_constraints_destroy(struct device *dev)
        struct pm_qos_constraints *c;
        struct pm_qos_flags *f;
 
+       mutex_lock(&dev_pm_qos_mtx);
+
        /*
         * If the device's PM QoS resume latency limit or PM QoS flags have been
         * exposed to user space, they have to be hidden at this point.
         */
-       dev_pm_qos_hide_latency_limit(dev);
-       dev_pm_qos_hide_flags(dev);
+       __dev_pm_qos_hide_latency_limit(dev);
+       __dev_pm_qos_hide_flags(dev);
 
-       mutex_lock(&dev_pm_qos_mtx);
-
-       dev->power.power_state = PMSG_INVALID;
        qos = dev->power.qos;
        if (!qos)
                goto out;
@@ -257,7 +246,7 @@ void dev_pm_qos_constraints_destroy(struct device *dev)
        }
 
        spin_lock_irq(&dev->power.lock);
-       dev->power.qos = NULL;
+       dev->power.qos = ERR_PTR(-ENODEV);
        spin_unlock_irq(&dev->power.lock);
 
        kfree(c->notifiers);
@@ -301,32 +290,19 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
                 "%s() called for already added request\n", __func__))
                return -EINVAL;
 
-       req->dev = dev;
-
        mutex_lock(&dev_pm_qos_mtx);
 
-       if (!dev->power.qos) {
-               if (dev->power.power_state.event == PM_EVENT_INVALID) {
-                       /* The device has been removed from the system. */
-                       req->dev = NULL;
-                       ret = -ENODEV;
-                       goto out;
-               } else {
-                       /*
-                        * Allocate the constraints data on the first call to
-                        * add_request, i.e. only if the data is not already
-                        * allocated and if the device has not been removed.
-                        */
-                       ret = dev_pm_qos_constraints_allocate(dev);
-               }
-       }
+       if (IS_ERR(dev->power.qos))
+               ret = -ENODEV;
+       else if (!dev->power.qos)
+               ret = dev_pm_qos_constraints_allocate(dev);
 
        if (!ret) {
+               req->dev = dev;
                req->type = type;
                ret = apply_constraint(req, PM_QOS_ADD_REQ, value);
        }
 
- out:
        mutex_unlock(&dev_pm_qos_mtx);
 
        return ret;
@@ -344,7 +320,14 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req,
        s32 curr_value;
        int ret = 0;
 
-       if (!req->dev->power.qos)
+       if (!req) /*guard against callers passing in null */
+               return -EINVAL;
+
+       if (WARN(!dev_pm_qos_request_active(req),
+                "%s() called for unknown object\n", __func__))
+               return -EINVAL;
+
+       if (IS_ERR_OR_NULL(req->dev->power.qos))
                return -ENODEV;
 
        switch(req->type) {
@@ -386,6 +369,17 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value)
 {
        int ret;
 
+       mutex_lock(&dev_pm_qos_mtx);
+       ret = __dev_pm_qos_update_request(req, new_value);
+       mutex_unlock(&dev_pm_qos_mtx);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_qos_update_request);
+
+static int __dev_pm_qos_remove_request(struct dev_pm_qos_request *req)
+{
+       int ret;
+
        if (!req) /*guard against callers passing in null */
                return -EINVAL;
 
@@ -393,13 +387,13 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value)
                 "%s() called for unknown object\n", __func__))
                return -EINVAL;
 
-       mutex_lock(&dev_pm_qos_mtx);
-       ret = __dev_pm_qos_update_request(req, new_value);
-       mutex_unlock(&dev_pm_qos_mtx);
+       if (IS_ERR_OR_NULL(req->dev->power.qos))
+               return -ENODEV;
 
+       ret = apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
+       memset(req, 0, sizeof(*req));
        return ret;
 }
-EXPORT_SYMBOL_GPL(dev_pm_qos_update_request);
 
 /**
  * dev_pm_qos_remove_request - modifies an existing qos request
@@ -418,26 +412,10 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_update_request);
  */
 int dev_pm_qos_remove_request(struct dev_pm_qos_request *req)
 {
-       int ret = 0;
-
-       if (!req) /*guard against callers passing in null */
-               return -EINVAL;
-
-       if (WARN(!dev_pm_qos_request_active(req),
-                "%s() called for unknown object\n", __func__))
-               return -EINVAL;
+       int ret;
 
        mutex_lock(&dev_pm_qos_mtx);
-
-       if (req->dev->power.qos) {
-               ret = apply_constraint(req, PM_QOS_REMOVE_REQ,
-                                      PM_QOS_DEFAULT_VALUE);
-               memset(req, 0, sizeof(*req));
-       } else {
-               /* Return if the device has been removed */
-               ret = -ENODEV;
-       }
-
+       ret = __dev_pm_qos_remove_request(req);
        mutex_unlock(&dev_pm_qos_mtx);
        return ret;
 }
@@ -462,9 +440,10 @@ int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier)
 
        mutex_lock(&dev_pm_qos_mtx);
 
-       if (!dev->power.qos)
-               ret = dev->power.power_state.event != PM_EVENT_INVALID ?
-                       dev_pm_qos_constraints_allocate(dev) : -ENODEV;
+       if (IS_ERR(dev->power.qos))
+               ret = -ENODEV;
+       else if (!dev->power.qos)
+               ret = dev_pm_qos_constraints_allocate(dev);
 
        if (!ret)
                ret = blocking_notifier_chain_register(
@@ -493,7 +472,7 @@ int dev_pm_qos_remove_notifier(struct device *dev,
        mutex_lock(&dev_pm_qos_mtx);
 
        /* Silently return if the constraints object is not present. */
-       if (dev->power.qos)
+       if (!IS_ERR_OR_NULL(dev->power.qos))
                retval = blocking_notifier_chain_unregister(
                                dev->power.qos->latency.notifiers,
                                notifier);
@@ -563,16 +542,20 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request);
 static void __dev_pm_qos_drop_user_request(struct device *dev,
                                           enum dev_pm_qos_req_type type)
 {
+       struct dev_pm_qos_request *req = NULL;
+
        switch(type) {
        case DEV_PM_QOS_LATENCY:
-               dev_pm_qos_remove_request(dev->power.qos->latency_req);
+               req = dev->power.qos->latency_req;
                dev->power.qos->latency_req = NULL;
                break;
        case DEV_PM_QOS_FLAGS:
-               dev_pm_qos_remove_request(dev->power.qos->flags_req);
+               req = dev->power.qos->flags_req;
                dev->power.qos->flags_req = NULL;
                break;
        }
+       __dev_pm_qos_remove_request(req);
+       kfree(req);
 }
 
 /**
@@ -588,36 +571,57 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value)
        if (!device_is_registered(dev) || value < 0)
                return -EINVAL;
 
-       if (dev->power.qos && dev->power.qos->latency_req)
-               return -EEXIST;
-
        req = kzalloc(sizeof(*req), GFP_KERNEL);
        if (!req)
                return -ENOMEM;
 
        ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_LATENCY, value);
-       if (ret < 0)
+       if (ret < 0) {
+               kfree(req);
                return ret;
+       }
+
+       mutex_lock(&dev_pm_qos_mtx);
+
+       if (IS_ERR_OR_NULL(dev->power.qos))
+               ret = -ENODEV;
+       else if (dev->power.qos->latency_req)
+               ret = -EEXIST;
+
+       if (ret < 0) {
+               __dev_pm_qos_remove_request(req);
+               kfree(req);
+               goto out;
+       }
 
        dev->power.qos->latency_req = req;
        ret = pm_qos_sysfs_add_latency(dev);
        if (ret)
                __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY);
 
+ out:
+       mutex_unlock(&dev_pm_qos_mtx);
        return ret;
 }
 EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit);
 
+static void __dev_pm_qos_hide_latency_limit(struct device *dev)
+{
+       if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->latency_req) {
+               pm_qos_sysfs_remove_latency(dev);
+               __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY);
+       }
+}
+
 /**
  * dev_pm_qos_hide_latency_limit - Hide PM QoS latency limit from user space.
  * @dev: Device whose PM QoS latency limit is to be hidden from user space.
  */
 void dev_pm_qos_hide_latency_limit(struct device *dev)
 {
-       if (dev->power.qos && dev->power.qos->latency_req) {
-               pm_qos_sysfs_remove_latency(dev);
-               __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY);
-       }
+       mutex_lock(&dev_pm_qos_mtx);
+       __dev_pm_qos_hide_latency_limit(dev);
+       mutex_unlock(&dev_pm_qos_mtx);
 }
 EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_limit);
 
@@ -634,41 +638,61 @@ int dev_pm_qos_expose_flags(struct device *dev, s32 val)
        if (!device_is_registered(dev))
                return -EINVAL;
 
-       if (dev->power.qos && dev->power.qos->flags_req)
-               return -EEXIST;
-
        req = kzalloc(sizeof(*req), GFP_KERNEL);
        if (!req)
                return -ENOMEM;
 
-       pm_runtime_get_sync(dev);
        ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_FLAGS, val);
-       if (ret < 0)
-               goto fail;
+       if (ret < 0) {
+               kfree(req);
+               return ret;
+       }
+
+       pm_runtime_get_sync(dev);
+       mutex_lock(&dev_pm_qos_mtx);
+
+       if (IS_ERR_OR_NULL(dev->power.qos))
+               ret = -ENODEV;
+       else if (dev->power.qos->flags_req)
+               ret = -EEXIST;
+
+       if (ret < 0) {
+               __dev_pm_qos_remove_request(req);
+               kfree(req);
+               goto out;
+       }
 
        dev->power.qos->flags_req = req;
        ret = pm_qos_sysfs_add_flags(dev);
        if (ret)
                __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS);
 
-fail:
+ out:
+       mutex_unlock(&dev_pm_qos_mtx);
        pm_runtime_put(dev);
        return ret;
 }
 EXPORT_SYMBOL_GPL(dev_pm_qos_expose_flags);
 
+static void __dev_pm_qos_hide_flags(struct device *dev)
+{
+       if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->flags_req) {
+               pm_qos_sysfs_remove_flags(dev);
+               __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS);
+       }
+}
+
 /**
  * dev_pm_qos_hide_flags - Hide PM QoS flags of a device from user space.
  * @dev: Device whose PM QoS flags are to be hidden from user space.
  */
 void dev_pm_qos_hide_flags(struct device *dev)
 {
-       if (dev->power.qos && dev->power.qos->flags_req) {
-               pm_qos_sysfs_remove_flags(dev);
-               pm_runtime_get_sync(dev);
-               __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS);
-               pm_runtime_put(dev);
-       }
+       pm_runtime_get_sync(dev);
+       mutex_lock(&dev_pm_qos_mtx);
+       __dev_pm_qos_hide_flags(dev);
+       mutex_unlock(&dev_pm_qos_mtx);
+       pm_runtime_put(dev);
 }
 EXPORT_SYMBOL_GPL(dev_pm_qos_hide_flags);
 
@@ -683,12 +707,14 @@ int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set)
        s32 value;
        int ret;
 
-       if (!dev->power.qos || !dev->power.qos->flags_req)
-               return -EINVAL;
-
        pm_runtime_get_sync(dev);
        mutex_lock(&dev_pm_qos_mtx);
 
+       if (IS_ERR_OR_NULL(dev->power.qos) || !dev->power.qos->flags_req) {
+               ret = -EINVAL;
+               goto out;
+       }
+
        value = dev_pm_qos_requested_flags(dev);
        if (set)
                value |= mask;
@@ -697,9 +723,12 @@ int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set)
 
        ret = __dev_pm_qos_update_request(dev->power.qos->flags_req, value);
 
+ out:
        mutex_unlock(&dev_pm_qos_mtx);
        pm_runtime_put(dev);
-
        return ret;
 }
+#else /* !CONFIG_PM_RUNTIME */
+static void __dev_pm_qos_hide_latency_limit(struct device *dev) {}
+static void __dev_pm_qos_hide_flags(struct device *dev) {}
 #endif /* CONFIG_PM_RUNTIME */
index 50d16e3cb0a91ad637124472ac6b570403e86229..a53ebd265701674e98901f2ba36c97a6e1954302 100644 (file)
@@ -708,6 +708,7 @@ void rpm_sysfs_remove(struct device *dev)
 
 void dpm_sysfs_remove(struct device *dev)
 {
+       dev_pm_qos_constraints_destroy(dev);
        rpm_sysfs_remove(dev);
        sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group);
        sysfs_remove_group(&dev->kobj, &pm_attr_group);
index 4706c63d0bc63fdc8d9bdba1e96d3e1cb543a806..020ea2b9fd2f347a0ac71119a9213bb1c655ae33 100644 (file)
@@ -184,6 +184,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
                if (ret < 0) {
                        dev_err(map->dev, "IRQ thread failed to resume: %d\n",
                                ret);
+                       pm_runtime_put(map->dev);
                        return IRQ_NONE;
                }
        }
index d3bde6cec927643bdf02445e387e97d4d5f29d69..30629a3d44cc517b62ea2fff5f8a65e505266b81 100644 (file)
@@ -404,6 +404,8 @@ void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
                return;
        }
 
+       spin_lock_init(&pc_host->cfgspace_lock);
+
        pc->host_controller = pc_host;
        pc_host->pci_controller.io_resource = &pc_host->io_resource;
        pc_host->pci_controller.mem_resource = &pc_host->mem_resource;
index 1bafb40ec8a213480f355b480819f092fdfebd08..69ae5972713cf814e968c3c9d9ad8743d3dd240d 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 #include <asm/uaccess.h>
 
 
@@ -52,8 +53,12 @@ static struct hwrng *current_rng;
 static LIST_HEAD(rng_list);
 static DEFINE_MUTEX(rng_mutex);
 static int data_avail;
-static u8 rng_buffer[SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES]
-       __cacheline_aligned;
+static u8 *rng_buffer;
+
+static size_t rng_buffer_size(void)
+{
+       return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES;
+}
 
 static inline int hwrng_init(struct hwrng *rng)
 {
@@ -116,7 +121,7 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf,
 
                if (!data_avail) {
                        bytes_read = rng_get_data(current_rng, rng_buffer,
-                               sizeof(rng_buffer),
+                               rng_buffer_size(),
                                !(filp->f_flags & O_NONBLOCK));
                        if (bytes_read < 0) {
                                err = bytes_read;
@@ -307,6 +312,14 @@ int hwrng_register(struct hwrng *rng)
 
        mutex_lock(&rng_mutex);
 
+       /* kmalloc makes this safe for virt_to_page() in virtio_rng.c */
+       err = -ENOMEM;
+       if (!rng_buffer) {
+               rng_buffer = kmalloc(rng_buffer_size(), GFP_KERNEL);
+               if (!rng_buffer)
+                       goto out_unlock;
+       }
+
        /* Must not register two RNGs with the same name. */
        err = -EEXIST;
        list_for_each_entry(tmp, &rng_list, list) {
index 594bda9dcfc8ef847b725f44b3bd2604a784375a..32a6c5764950f642d12ae884aa7eb95d9cd1ccc2 100644 (file)
@@ -852,6 +852,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
                      int reserved)
 {
        unsigned long flags;
+       int wakeup_write = 0;
 
        /* Hold lock while accounting */
        spin_lock_irqsave(&r->lock, flags);
@@ -873,10 +874,8 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
                else
                        r->entropy_count = reserved;
 
-               if (r->entropy_count < random_write_wakeup_thresh) {
-                       wake_up_interruptible(&random_write_wait);
-                       kill_fasync(&fasync, SIGIO, POLL_OUT);
-               }
+               if (r->entropy_count < random_write_wakeup_thresh)
+                       wakeup_write = 1;
        }
 
        DEBUG_ENT("debiting %zu entropy credits from %s%s\n",
@@ -884,6 +883,11 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min,
 
        spin_unlock_irqrestore(&r->lock, flags);
 
+       if (wakeup_write) {
+               wake_up_interruptible(&random_write_wait);
+               kill_fasync(&fasync, SIGIO, POLL_OUT);
+       }
+
        return nbytes;
 }
 
index fce2000eec31d658efb52251b7f6df60822d1798..1110478dd0fdb83b6bbdbae5fa1f40c0a2406655 100644 (file)
@@ -313,6 +313,12 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
            (task_active_pid_ns(current) != &init_pid_ns))
                return;
 
+       /* Can only change if privileged. */
+       if (!capable(CAP_NET_ADMIN)) {
+               err = EPERM;
+               goto out;
+       }
+
        mc_op = (enum proc_cn_mcast_op *)msg->data;
        switch (*mc_op) {
        case PROC_CN_MCAST_LISTEN:
@@ -325,6 +331,8 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg,
                err = EINVAL;
                break;
        }
+
+out:
        cn_proc_ack(err, msg->seq, msg->ack);
 }
 
index d2ac911506006be9e1c77b1e57853828c33fd99a..46bde01eee623bd443d582013425257fbd11ec50 100644 (file)
@@ -64,7 +64,7 @@ static void *get_cpu_dbs_info_s(int cpu)                              \
  * dbs: used as a shortform for demand based switching It helps to keep variable
  *     names smaller, simpler
  * cdbs: common dbs
- * on_*: On-demand governor
+ * od_*: On-demand governor
  * cs_*: Conservative governor
  */
 
index 66e3a71b81a32f5c71242aca6bdfe4961b16587b..b61b5a3fad64983cc1681f89dc599649bf129bde 100644 (file)
 
 static int hb_voltage_change(unsigned int freq)
 {
-       int i;
-       u32 msg[HB_CPUFREQ_IPC_LEN];
-
-       msg[0] = HB_CPUFREQ_CHANGE_NOTE;
-       msg[1] = freq / 1000000;
-       for (i = 2; i < HB_CPUFREQ_IPC_LEN; i++)
-               msg[i] = 0;
+       u32 msg[HB_CPUFREQ_IPC_LEN] = {HB_CPUFREQ_CHANGE_NOTE, freq / 1000000};
 
        return pl320_ipc_transmit(msg);
 }
index 096fde0ebcb5b9e2fb2d411f62e12b0702a319d0..f6dd1e7611293bf5a66531f2acb285713439430c 100644 (file)
@@ -662,6 +662,9 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
 
        cpu = all_cpu_data[policy->cpu];
 
+       if (!policy->cpuinfo.max_freq)
+               return -ENODEV;
+
        intel_pstate_get_min_max(cpu, &min, &max);
 
        limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq;
@@ -747,37 +750,11 @@ static struct cpufreq_driver intel_pstate_driver = {
        .owner          = THIS_MODULE,
 };
 
-static void intel_pstate_exit(void)
-{
-       int cpu;
-
-       sysfs_remove_group(intel_pstate_kobject,
-                               &intel_pstate_attr_group);
-       debugfs_remove_recursive(debugfs_parent);
-
-       cpufreq_unregister_driver(&intel_pstate_driver);
-
-       if (!all_cpu_data)
-               return;
-
-       get_online_cpus();
-       for_each_online_cpu(cpu) {
-               if (all_cpu_data[cpu]) {
-                       del_timer_sync(&all_cpu_data[cpu]->timer);
-                       kfree(all_cpu_data[cpu]);
-               }
-       }
-
-       put_online_cpus();
-       vfree(all_cpu_data);
-}
-module_exit(intel_pstate_exit);
-
 static int __initdata no_load;
 
 static int __init intel_pstate_init(void)
 {
-       int rc = 0;
+       int cpu, rc = 0;
        const struct x86_cpu_id *id;
 
        if (no_load)
@@ -802,7 +779,16 @@ static int __init intel_pstate_init(void)
        intel_pstate_sysfs_expose_params();
        return rc;
 out:
-       intel_pstate_exit();
+       get_online_cpus();
+       for_each_online_cpu(cpu) {
+               if (all_cpu_data[cpu]) {
+                       del_timer_sync(&all_cpu_data[cpu]->timer);
+                       kfree(all_cpu_data[cpu]);
+               }
+       }
+
+       put_online_cpus();
+       vfree(all_cpu_data);
        return -ENODEV;
 }
 device_initcall(intel_pstate_init);
index 982f1f5f5742f21da9206f62fa622ce17adefe9f..4cd392dbf115075740cb546f4875f220517c7896 100644 (file)
@@ -442,7 +442,6 @@ static int __init dmi_present(const char __iomem *p)
 static int __init smbios_present(const char __iomem *p)
 {
        u8 buf[32];
-       int offset = 0;
 
        memcpy_fromio(buf, p, 32);
        if ((buf[5] < 32) && dmi_checksum(buf, buf[5])) {
@@ -461,9 +460,9 @@ static int __init smbios_present(const char __iomem *p)
                        dmi_ver = 0x0206;
                        break;
                }
-               offset = 16;
+               return memcmp(p + 16, "_DMI_", 5) || dmi_present(p + 16);
        }
-       return dmi_present(buf + offset);
+       return 1;
 }
 
 void __init dmi_scan_machine(void)
index 7320bf891706abaeb299c4bf976bf027aba5ec3b..fe62aa3922398ebc52e7f61b586a71814a4b9dfe 100644 (file)
@@ -426,6 +426,44 @@ get_var_data(struct efivars *efivars, struct efi_variable *var)
        return status;
 }
 
+static efi_status_t
+check_var_size_locked(struct efivars *efivars, u32 attributes,
+                       unsigned long size)
+{
+       u64 storage_size, remaining_size, max_size;
+       efi_status_t status;
+       const struct efivar_operations *fops = efivars->ops;
+
+       if (!efivars->ops->query_variable_info)
+               return EFI_UNSUPPORTED;
+
+       status = fops->query_variable_info(attributes, &storage_size,
+                                          &remaining_size, &max_size);
+
+       if (status != EFI_SUCCESS)
+               return status;
+
+       if (!storage_size || size > remaining_size || size > max_size ||
+           (remaining_size - size) < (storage_size / 2))
+               return EFI_OUT_OF_RESOURCES;
+
+       return status;
+}
+
+
+static efi_status_t
+check_var_size(struct efivars *efivars, u32 attributes, unsigned long size)
+{
+       efi_status_t status;
+       unsigned long flags;
+
+       spin_lock_irqsave(&efivars->lock, flags);
+       status = check_var_size_locked(efivars, attributes, size);
+       spin_unlock_irqrestore(&efivars->lock, flags);
+
+       return status;
+}
+
 static ssize_t
 efivar_guid_read(struct efivar_entry *entry, char *buf)
 {
@@ -547,11 +585,16 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
        }
 
        spin_lock_irq(&efivars->lock);
-       status = efivars->ops->set_variable(new_var->VariableName,
-                                           &new_var->VendorGuid,
-                                           new_var->Attributes,
-                                           new_var->DataSize,
-                                           new_var->Data);
+
+       status = check_var_size_locked(efivars, new_var->Attributes,
+              new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
+
+       if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED)
+               status = efivars->ops->set_variable(new_var->VariableName,
+                                                   &new_var->VendorGuid,
+                                                   new_var->Attributes,
+                                                   new_var->DataSize,
+                                                   new_var->Data);
 
        spin_unlock_irq(&efivars->lock);
 
@@ -702,8 +745,7 @@ static ssize_t efivarfs_file_write(struct file *file,
        u32 attributes;
        struct inode *inode = file->f_mapping->host;
        unsigned long datasize = count - sizeof(attributes);
-       unsigned long newdatasize;
-       u64 storage_size, remaining_size, max_size;
+       unsigned long newdatasize, varsize;
        ssize_t bytes = 0;
 
        if (count < sizeof(attributes))
@@ -722,28 +764,18 @@ static ssize_t efivarfs_file_write(struct file *file,
         * amounts of memory. Pick a default size of 64K if
         * QueryVariableInfo() isn't supported by the firmware.
         */
-       spin_lock_irq(&efivars->lock);
-
-       if (!efivars->ops->query_variable_info)
-               status = EFI_UNSUPPORTED;
-       else {
-               const struct efivar_operations *fops = efivars->ops;
-               status = fops->query_variable_info(attributes, &storage_size,
-                                                  &remaining_size, &max_size);
-       }
 
-       spin_unlock_irq(&efivars->lock);
+       varsize = datasize + utf16_strsize(var->var.VariableName, 1024);
+       status = check_var_size(efivars, attributes, varsize);
 
        if (status != EFI_SUCCESS) {
                if (status != EFI_UNSUPPORTED)
                        return efi_status_to_err(status);
 
-               remaining_size = 65536;
+               if (datasize > 65536)
+                       return -ENOSPC;
        }
 
-       if (datasize > remaining_size)
-               return -ENOSPC;
-
        data = kmalloc(datasize, GFP_KERNEL);
        if (!data)
                return -ENOMEM;
@@ -765,6 +797,19 @@ static ssize_t efivarfs_file_write(struct file *file,
         */
        spin_lock_irq(&efivars->lock);
 
+       /*
+        * Ensure that the available space hasn't shrunk below the safe level
+        */
+
+       status = check_var_size_locked(efivars, attributes, varsize);
+
+       if (status != EFI_SUCCESS && status != EFI_UNSUPPORTED) {
+               spin_unlock_irq(&efivars->lock);
+               kfree(data);
+
+               return efi_status_to_err(status);
+       }
+
        status = efivars->ops->set_variable(var->var.VariableName,
                                            &var->var.VendorGuid,
                                            attributes, datasize,
@@ -929,8 +974,8 @@ static bool efivarfs_valid_name(const char *str, int len)
        if (len < GUID_LEN + 2)
                return false;
 
-       /* GUID should be right after the first '-' */
-       if (s - 1 != strchr(str, '-'))
+       /* GUID must be preceded by a '-' */
+       if (*(s - 1) != '-')
                return false;
 
        /*
@@ -1118,15 +1163,22 @@ static struct dentry_operations efivarfs_d_ops = {
 
 static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name)
 {
+       struct dentry *d;
        struct qstr q;
+       int err;
 
        q.name = name;
        q.len = strlen(name);
 
-       if (efivarfs_d_hash(NULL, NULL, &q))
-               return NULL;
+       err = efivarfs_d_hash(NULL, NULL, &q);
+       if (err)
+               return ERR_PTR(err);
+
+       d = d_alloc(parent, &q);
+       if (d)
+               return d;
 
-       return d_alloc(parent, &q);
+       return ERR_PTR(-ENOMEM);
 }
 
 static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
@@ -1136,6 +1188,7 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
        struct efivar_entry *entry, *n;
        struct efivars *efivars = &__efivars;
        char *name;
+       int err = -ENOMEM;
 
        efivarfs_sb = sb;
 
@@ -1186,8 +1239,10 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
                        goto fail_name;
 
                dentry = efivarfs_alloc_dentry(root, name);
-               if (!dentry)
+               if (IS_ERR(dentry)) {
+                       err = PTR_ERR(dentry);
                        goto fail_inode;
+               }
 
                /* copied by the above to local storage in the dentry. */
                kfree(name);
@@ -1214,7 +1269,7 @@ fail_inode:
 fail_name:
        kfree(name);
 fail:
-       return -ENOMEM;
+       return err;
 }
 
 static struct dentry *efivarfs_mount(struct file_system_type *fs_type,
@@ -1234,6 +1289,7 @@ static struct file_system_type efivarfs_type = {
        .mount   = efivarfs_mount,
        .kill_sb = efivarfs_kill_sb,
 };
+MODULE_ALIAS_FS("efivarfs");
 
 /*
  * Handle negative dentry.
@@ -1345,7 +1401,6 @@ static int efi_pstore_write(enum pstore_type_id type,
        efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
        struct efivars *efivars = psi->data;
        int i, ret = 0;
-       u64 storage_space, remaining_space, max_variable_size;
        efi_status_t status = EFI_NOT_FOUND;
        unsigned long flags;
 
@@ -1365,11 +1420,11 @@ static int efi_pstore_write(enum pstore_type_id type,
         * size: a size of logging data
         * DUMP_NAME_LEN * 2: a maximum size of variable name
         */
-       status = efivars->ops->query_variable_info(PSTORE_EFI_ATTRIBUTES,
-                                                  &storage_space,
-                                                  &remaining_space,
-                                                  &max_variable_size);
-       if (status || remaining_space < size + DUMP_NAME_LEN * 2) {
+
+       status = check_var_size_locked(efivars, PSTORE_EFI_ATTRIBUTES,
+                                        size + DUMP_NAME_LEN * 2);
+
+       if (status) {
                spin_unlock_irqrestore(&efivars->lock, flags);
                *id = part;
                return -ENOSPC;
@@ -1544,6 +1599,14 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
                return -EINVAL;
        }
 
+       status = check_var_size_locked(efivars, new_var->Attributes,
+              new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
+
+       if (status && status != EFI_UNSUPPORTED) {
+               spin_unlock_irq(&efivars->lock);
+               return efi_status_to_err(status);
+       }
+
        /* now *really* create the variable via EFI */
        status = efivars->ops->set_variable(new_var->VariableName,
                                            &new_var->VendorGuid,
index 6f2306db85915eca2690895eda7e8f6b375091ab..f9dbd503fc40fb0f1bccd0fa8f0995816a06b538 100644 (file)
@@ -128,9 +128,9 @@ static int ichx_read_bit(int reg, unsigned nr)
        return data & (1 << bit) ? 1 : 0;
 }
 
-static int ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr)
+static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr)
 {
-       return (ichx_priv.use_gpio & (1 << (nr / 32))) ? 0 : -ENXIO;
+       return ichx_priv.use_gpio & (1 << (nr / 32));
 }
 
 static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
index fff9786cdc643120f933154366237a8d6b332e8d..c2534d62911cfd18434c9b2bb172cad265603e0d 100644 (file)
@@ -88,13 +88,14 @@ static int gpiod_request(struct gpio_desc *desc, const char *label);
 static void gpiod_free(struct gpio_desc *desc);
 static int gpiod_direction_input(struct gpio_desc *desc);
 static int gpiod_direction_output(struct gpio_desc *desc, int value);
+static int gpiod_get_direction(const struct gpio_desc *desc);
 static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce);
-static int gpiod_get_value_cansleep(struct gpio_desc *desc);
+static int gpiod_get_value_cansleep(const struct gpio_desc *desc);
 static void gpiod_set_value_cansleep(struct gpio_desc *desc, int value);
-static int gpiod_get_value(struct gpio_desc *desc);
+static int gpiod_get_value(const struct gpio_desc *desc);
 static void gpiod_set_value(struct gpio_desc *desc, int value);
-static int gpiod_cansleep(struct gpio_desc *desc);
-static int gpiod_to_irq(struct gpio_desc *desc);
+static int gpiod_cansleep(const struct gpio_desc *desc);
+static int gpiod_to_irq(const struct gpio_desc *desc);
 static int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
 static int gpiod_export_link(struct device *dev, const char *name,
                             struct gpio_desc *desc);
@@ -171,12 +172,12 @@ static int gpio_ensure_requested(struct gpio_desc *desc)
        return 0;
 }
 
-/* caller holds gpio_lock *OR* gpio is marked as requested */
-static struct gpio_chip *gpiod_to_chip(struct gpio_desc *desc)
+static struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc)
 {
-       return desc->chip;
+       return desc ? desc->chip : NULL;
 }
 
+/* caller holds gpio_lock *OR* gpio is marked as requested */
 struct gpio_chip *gpio_to_chip(unsigned gpio)
 {
        return gpiod_to_chip(gpio_to_desc(gpio));
@@ -207,7 +208,7 @@ static int gpiochip_find_base(int ngpio)
 }
 
 /* caller ensures gpio is valid and requested, chip->get_direction may sleep  */
-static int gpiod_get_direction(struct gpio_desc *desc)
+static int gpiod_get_direction(const struct gpio_desc *desc)
 {
        struct gpio_chip        *chip;
        unsigned                offset;
@@ -223,11 +224,13 @@ static int gpiod_get_direction(struct gpio_desc *desc)
        if (status > 0) {
                /* GPIOF_DIR_IN, or other positive */
                status = 1;
-               clear_bit(FLAG_IS_OUT, &desc->flags);
+               /* FLAG_IS_OUT is just a cache of the result of get_direction(),
+                * so it does not affect constness per se */
+               clear_bit(FLAG_IS_OUT, &((struct gpio_desc *)desc)->flags);
        }
        if (status == 0) {
                /* GPIOF_DIR_OUT */
-               set_bit(FLAG_IS_OUT, &desc->flags);
+               set_bit(FLAG_IS_OUT, &((struct gpio_desc *)desc)->flags);
        }
        return status;
 }
@@ -263,7 +266,7 @@ static DEFINE_MUTEX(sysfs_lock);
 static ssize_t gpio_direction_show(struct device *dev,
                struct device_attribute *attr, char *buf)
 {
-       struct gpio_desc        *desc = dev_get_drvdata(dev);
+       const struct gpio_desc  *desc = dev_get_drvdata(dev);
        ssize_t                 status;
 
        mutex_lock(&sysfs_lock);
@@ -654,6 +657,11 @@ static ssize_t export_store(struct class *class,
                goto done;
 
        desc = gpio_to_desc(gpio);
+       /* reject invalid GPIOs */
+       if (!desc) {
+               pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
+               return -EINVAL;
+       }
 
        /* No extra locking here; FLAG_SYSFS just signifies that the
         * request and export were done by on behalf of userspace, so
@@ -690,12 +698,14 @@ static ssize_t unexport_store(struct class *class,
        if (status < 0)
                goto done;
 
-       status = -EINVAL;
-
        desc = gpio_to_desc(gpio);
        /* reject bogus commands (gpio_unexport ignores them) */
-       if (!desc)
-               goto done;
+       if (!desc) {
+               pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
+               return -EINVAL;
+       }
+
+       status = -EINVAL;
 
        /* No extra locking here; FLAG_SYSFS just signifies that the
         * request and export were done by on behalf of userspace, so
@@ -846,8 +856,10 @@ static int gpiod_export_link(struct device *dev, const char *name,
 {
        int                     status = -EINVAL;
 
-       if (!desc)
-               goto done;
+       if (!desc) {
+               pr_warn("%s: invalid GPIO\n", __func__);
+               return -EINVAL;
+       }
 
        mutex_lock(&sysfs_lock);
 
@@ -865,7 +877,6 @@ static int gpiod_export_link(struct device *dev, const char *name,
 
        mutex_unlock(&sysfs_lock);
 
-done:
        if (status)
                pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc),
                         status);
@@ -896,8 +907,10 @@ static int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value)
        struct device           *dev = NULL;
        int                     status = -EINVAL;
 
-       if (!desc)
-               goto done;
+       if (!desc) {
+               pr_warn("%s: invalid GPIO\n", __func__);
+               return -EINVAL;
+       }
 
        mutex_lock(&sysfs_lock);
 
@@ -914,7 +927,6 @@ static int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value)
 unlock:
        mutex_unlock(&sysfs_lock);
 
-done:
        if (status)
                pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc),
                         status);
@@ -940,8 +952,8 @@ static void gpiod_unexport(struct gpio_desc *desc)
        struct device           *dev = NULL;
 
        if (!desc) {
-               status = -EINVAL;
-               goto done;
+               pr_warn("%s: invalid GPIO\n", __func__);
+               return;
        }
 
        mutex_lock(&sysfs_lock);
@@ -962,7 +974,7 @@ static void gpiod_unexport(struct gpio_desc *desc)
                device_unregister(dev);
                put_device(dev);
        }
-done:
+
        if (status)
                pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc),
                         status);
@@ -1384,12 +1396,13 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
        int                     status = -EPROBE_DEFER;
        unsigned long           flags;
 
-       spin_lock_irqsave(&gpio_lock, flags);
-
        if (!desc) {
-               status = -EINVAL;
-               goto done;
+               pr_warn("%s: invalid GPIO\n", __func__);
+               return -EINVAL;
        }
+
+       spin_lock_irqsave(&gpio_lock, flags);
+
        chip = desc->chip;
        if (chip == NULL)
                goto done;
@@ -1432,8 +1445,7 @@ static int gpiod_request(struct gpio_desc *desc, const char *label)
 done:
        if (status)
                pr_debug("_gpio_request: gpio-%d (%s) status %d\n",
-                        desc ? desc_to_gpio(desc) : -1,
-                        label ? : "?", status);
+                        desc_to_gpio(desc), label ? : "?", status);
        spin_unlock_irqrestore(&gpio_lock, flags);
        return status;
 }
@@ -1616,10 +1628,13 @@ static int gpiod_direction_input(struct gpio_desc *desc)
        int                     status = -EINVAL;
        int                     offset;
 
+       if (!desc) {
+               pr_warn("%s: invalid GPIO\n", __func__);
+               return -EINVAL;
+       }
+
        spin_lock_irqsave(&gpio_lock, flags);
 
-       if (!desc)
-               goto fail;
        chip = desc->chip;
        if (!chip || !chip->get || !chip->direction_input)
                goto fail;
@@ -1655,13 +1670,9 @@ lose:
        return status;
 fail:
        spin_unlock_irqrestore(&gpio_lock, flags);
-       if (status) {
-               int gpio = -1;
-               if (desc)
-                       gpio = desc_to_gpio(desc);
-               pr_debug("%s: gpio-%d status %d\n",
-                       __func__, gpio, status);
-       }
+       if (status)
+               pr_debug("%s: gpio-%d status %d\n", __func__,
+                        desc_to_gpio(desc), status);
        return status;
 }
 
@@ -1678,6 +1689,11 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value)
        int                     status = -EINVAL;
        int offset;
 
+       if (!desc) {
+               pr_warn("%s: invalid GPIO\n", __func__);
+               return -EINVAL;
+       }
+
        /* Open drain pin should not be driven to 1 */
        if (value && test_bit(FLAG_OPEN_DRAIN,  &desc->flags))
                return gpiod_direction_input(desc);
@@ -1688,8 +1704,6 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value)
 
        spin_lock_irqsave(&gpio_lock, flags);
 
-       if (!desc)
-               goto fail;
        chip = desc->chip;
        if (!chip || !chip->set || !chip->direction_output)
                goto fail;
@@ -1725,13 +1739,9 @@ lose:
        return status;
 fail:
        spin_unlock_irqrestore(&gpio_lock, flags);
-       if (status) {
-               int gpio = -1;
-               if (desc)
-                       gpio = desc_to_gpio(desc);
-               pr_debug("%s: gpio-%d status %d\n",
-                       __func__, gpio, status);
-       }
+       if (status)
+               pr_debug("%s: gpio-%d status %d\n", __func__,
+                        desc_to_gpio(desc), status);
        return status;
 }
 
@@ -1753,10 +1763,13 @@ static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
        int                     status = -EINVAL;
        int                     offset;
 
+       if (!desc) {
+               pr_warn("%s: invalid GPIO\n", __func__);
+               return -EINVAL;
+       }
+
        spin_lock_irqsave(&gpio_lock, flags);
 
-       if (!desc)
-               goto fail;
        chip = desc->chip;
        if (!chip || !chip->set || !chip->set_debounce)
                goto fail;
@@ -1776,13 +1789,9 @@ static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce)
 
 fail:
        spin_unlock_irqrestore(&gpio_lock, flags);
-       if (status) {
-               int gpio = -1;
-               if (desc)
-                       gpio = desc_to_gpio(desc);
-               pr_debug("%s: gpio-%d status %d\n",
-                       __func__, gpio, status);
-       }
+       if (status)
+               pr_debug("%s: gpio-%d status %d\n", __func__,
+                        desc_to_gpio(desc), status);
 
        return status;
 }
@@ -1824,12 +1833,14 @@ EXPORT_SYMBOL_GPL(gpio_set_debounce);
  * It returns the zero or nonzero value provided by the associated
  * gpio_chip.get() method; or zero if no such method is provided.
  */
-static int gpiod_get_value(struct gpio_desc *desc)
+static int gpiod_get_value(const struct gpio_desc *desc)
 {
        struct gpio_chip        *chip;
        int value;
        int offset;
 
+       if (!desc)
+               return 0;
        chip = desc->chip;
        offset = gpio_chip_hwgpio(desc);
        /* Should be using gpio_get_value_cansleep() */
@@ -1912,6 +1923,8 @@ static void gpiod_set_value(struct gpio_desc *desc, int value)
 {
        struct gpio_chip        *chip;
 
+       if (!desc)
+               return;
        chip = desc->chip;
        /* Should be using gpio_set_value_cansleep() */
        WARN_ON(chip->can_sleep);
@@ -1938,8 +1951,10 @@ EXPORT_SYMBOL_GPL(__gpio_set_value);
  * This is used directly or indirectly to implement gpio_cansleep().  It
  * returns nonzero if access reading or writing the GPIO value can sleep.
  */
-static int gpiod_cansleep(struct gpio_desc *desc)
+static int gpiod_cansleep(const struct gpio_desc *desc)
 {
+       if (!desc)
+               return 0;
        /* only call this on GPIOs that are valid! */
        return desc->chip->can_sleep;
 }
@@ -1959,11 +1974,13 @@ EXPORT_SYMBOL_GPL(__gpio_cansleep);
  * It returns the number of the IRQ signaled by this (input) GPIO,
  * or a negative errno.
  */
-static int gpiod_to_irq(struct gpio_desc *desc)
+static int gpiod_to_irq(const struct gpio_desc *desc)
 {
        struct gpio_chip        *chip;
        int                     offset;
 
+       if (!desc)
+               return -EINVAL;
        chip = desc->chip;
        offset = gpio_chip_hwgpio(desc);
        return chip->to_irq ? chip->to_irq(chip, offset) : -ENXIO;
@@ -1980,13 +1997,15 @@ EXPORT_SYMBOL_GPL(__gpio_to_irq);
  * Common examples include ones connected to I2C or SPI chips.
  */
 
-static int gpiod_get_value_cansleep(struct gpio_desc *desc)
+static int gpiod_get_value_cansleep(const struct gpio_desc *desc)
 {
        struct gpio_chip        *chip;
        int value;
        int offset;
 
        might_sleep_if(extra_checks);
+       if (!desc)
+               return 0;
        chip = desc->chip;
        offset = gpio_chip_hwgpio(desc);
        value = chip->get ? chip->get(chip, offset) : 0;
@@ -2005,6 +2024,8 @@ static void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
        struct gpio_chip        *chip;
 
        might_sleep_if(extra_checks);
+       if (!desc)
+               return;
        chip = desc->chip;
        trace_gpio_value(desc_to_gpio(desc), 0, value);
        if (test_bit(FLAG_OPEN_DRAIN,  &desc->flags))
index c5b8c81b94402321f599f4c3e5d99b88ee82a9e3..0a8eceb7590244af233d153845a91c79e6662420 100644 (file)
@@ -379,15 +379,15 @@ static const struct pci_device_id pciidlist[] = {         /* aka */
        INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */
        INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */
        INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */
-       INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT1 desktop */
+       INTEL_VGA_DEVICE(0x0D02, &intel_haswell_d_info), /* CRW GT1 desktop */
+       INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT2 desktop */
        INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */
-       INTEL_VGA_DEVICE(0x0D32, &intel_haswell_d_info), /* CRW GT2 desktop */
-       INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT1 server */
+       INTEL_VGA_DEVICE(0x0D0A, &intel_haswell_d_info), /* CRW GT1 server */
+       INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT2 server */
        INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */
-       INTEL_VGA_DEVICE(0x0D3A, &intel_haswell_d_info), /* CRW GT2 server */
-       INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT1 mobile */
+       INTEL_VGA_DEVICE(0x0D06, &intel_haswell_m_info), /* CRW GT1 mobile */
+       INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT2 mobile */
        INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */
-       INTEL_VGA_DEVICE(0x0D36, &intel_haswell_m_info), /* CRW GT2 mobile */
        INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info),
        INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info),
        INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info),
@@ -495,6 +495,7 @@ static int i915_drm_freeze(struct drm_device *dev)
                intel_modeset_disable(dev);
 
                drm_irq_uninstall(dev);
+               dev_priv->enable_hotplug_processing = false;
        }
 
        i915_save_state(dev);
@@ -568,10 +569,20 @@ static int __i915_drm_thaw(struct drm_device *dev)
                error = i915_gem_init_hw(dev);
                mutex_unlock(&dev->struct_mutex);
 
+               /* We need working interrupts for modeset enabling ... */
+               drm_irq_install(dev);
+
                intel_modeset_init_hw(dev);
                intel_modeset_setup_hw_state(dev, false);
-               drm_irq_install(dev);
+
+               /*
+                * ... but also need to make sure that hotplug processing
+                * doesn't cause havoc. Like in the driver load code we don't
+                * bother with the tiny race here where we might loose hotplug
+                * notifications.
+                * */
                intel_hpd_init(dev);
+               dev_priv->enable_hotplug_processing = true;
        }
 
        intel_opregion_init(dev);
index 2cd97d1cc920dbf1555af5d28d97d7cf893f6567..3c7bb0410b517fe84ae696c720441d553f63cd7f 100644 (file)
@@ -701,7 +701,7 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
 {
        struct drm_device *dev = (struct drm_device *) arg;
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       u32 de_iir, gt_iir, de_ier, pm_iir;
+       u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier;
        irqreturn_t ret = IRQ_NONE;
        int i;
 
@@ -711,6 +711,15 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
        de_ier = I915_READ(DEIER);
        I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
 
+       /* Disable south interrupts. We'll only write to SDEIIR once, so further
+        * interrupts will will be stored on its back queue, and then we'll be
+        * able to process them after we restore SDEIER (as soon as we restore
+        * it, we'll get an interrupt if SDEIIR still has something to process
+        * due to its back queue). */
+       sde_ier = I915_READ(SDEIER);
+       I915_WRITE(SDEIER, 0);
+       POSTING_READ(SDEIER);
+
        gt_iir = I915_READ(GTIIR);
        if (gt_iir) {
                snb_gt_irq_handler(dev, dev_priv, gt_iir);
@@ -759,6 +768,8 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
 
        I915_WRITE(DEIER, de_ier);
        POSTING_READ(DEIER);
+       I915_WRITE(SDEIER, sde_ier);
+       POSTING_READ(SDEIER);
 
        return ret;
 }
@@ -778,7 +789,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
        struct drm_device *dev = (struct drm_device *) arg;
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        int ret = IRQ_NONE;
-       u32 de_iir, gt_iir, de_ier, pm_iir;
+       u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier;
 
        atomic_inc(&dev_priv->irq_received);
 
@@ -787,6 +798,15 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
        I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
        POSTING_READ(DEIER);
 
+       /* Disable south interrupts. We'll only write to SDEIIR once, so further
+        * interrupts will will be stored on its back queue, and then we'll be
+        * able to process them after we restore SDEIER (as soon as we restore
+        * it, we'll get an interrupt if SDEIIR still has something to process
+        * due to its back queue). */
+       sde_ier = I915_READ(SDEIER);
+       I915_WRITE(SDEIER, 0);
+       POSTING_READ(SDEIER);
+
        de_iir = I915_READ(DEIIR);
        gt_iir = I915_READ(GTIIR);
        pm_iir = I915_READ(GEN6_PMIIR);
@@ -849,6 +869,8 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
 done:
        I915_WRITE(DEIER, de_ier);
        POSTING_READ(DEIER);
+       I915_WRITE(SDEIER, sde_ier);
+       POSTING_READ(SDEIER);
 
        return ret;
 }
index 527b664d343490238aded9ce08d42e2f4e4549a6..848992f67d56daa8910ce0e66210f51bddb2f604 100644 (file)
 #define   ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16)
 #define   ADPA_USE_VGA_HVPOLARITY (1<<15)
 #define   ADPA_SETS_HVPOLARITY 0
-#define   ADPA_VSYNC_CNTL_DISABLE (1<<11)
+#define   ADPA_VSYNC_CNTL_DISABLE (1<<10)
 #define   ADPA_VSYNC_CNTL_ENABLE 0
-#define   ADPA_HSYNC_CNTL_DISABLE (1<<10)
+#define   ADPA_HSYNC_CNTL_DISABLE (1<<11)
 #define   ADPA_HSYNC_CNTL_ENABLE 0
 #define   ADPA_VSYNC_ACTIVE_HIGH (1<<4)
 #define   ADPA_VSYNC_ACTIVE_LOW        0
index 969d08c72d1023c89116234fcf1844622d0f1081..32a3693905ecb14f697fd82b4f8a2419e2818552 100644 (file)
@@ -88,7 +88,7 @@ static void intel_disable_crt(struct intel_encoder *encoder)
        u32 temp;
 
        temp = I915_READ(crt->adpa_reg);
-       temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
+       temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
        temp &= ~ADPA_DAC_ENABLE;
        I915_WRITE(crt->adpa_reg, temp);
 }
index d64af5aa4a1caeccc1b5f5f6d85e68cc4e5c7fff..8d0bac3c35d7df012225ea47e922c60b353a0915 100644 (file)
@@ -1391,8 +1391,8 @@ void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder)
        struct intel_dp *intel_dp = &intel_dig_port->dp;
        struct drm_i915_private *dev_priv = encoder->dev->dev_private;
        enum port port = intel_dig_port->port;
-       bool wait;
        uint32_t val;
+       bool wait = false;
 
        if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
                val = I915_READ(DDI_BUF_CTL(port));
index a05ac2c91ba2cd3cf5a8599794a74674a5ac04ed..287b42c9d1a8250e56d8a72d1b527cbb7dc1ad38 100644 (file)
@@ -3604,6 +3604,30 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
         */
 }
 
+/**
+ * i9xx_fixup_plane - ugly workaround for G45 to fire up the hardware
+ * cursor plane briefly if not already running after enabling the display
+ * plane.
+ * This workaround avoids occasional blank screens when self refresh is
+ * enabled.
+ */
+static void
+g4x_fixup_plane(struct drm_i915_private *dev_priv, enum pipe pipe)
+{
+       u32 cntl = I915_READ(CURCNTR(pipe));
+
+       if ((cntl & CURSOR_MODE) == 0) {
+               u32 fw_bcl_self = I915_READ(FW_BLC_SELF);
+
+               I915_WRITE(FW_BLC_SELF, fw_bcl_self & ~FW_BLC_SELF_EN);
+               I915_WRITE(CURCNTR(pipe), CURSOR_MODE_64_ARGB_AX);
+               intel_wait_for_vblank(dev_priv->dev, pipe);
+               I915_WRITE(CURCNTR(pipe), cntl);
+               I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe)));
+               I915_WRITE(FW_BLC_SELF, fw_bcl_self);
+       }
+}
+
 static void i9xx_crtc_enable(struct drm_crtc *crtc)
 {
        struct drm_device *dev = crtc->dev;
@@ -3629,6 +3653,8 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
 
        intel_enable_pipe(dev_priv, pipe, false);
        intel_enable_plane(dev_priv, plane, pipe);
+       if (IS_G4X(dev))
+               g4x_fixup_plane(dev_priv, pipe);
 
        intel_crtc_load_lut(crtc);
        intel_update_fbc(dev);
@@ -7256,8 +7282,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_framebuffer *intel_fb;
-       struct drm_i915_gem_object *obj;
+       struct drm_framebuffer *old_fb = crtc->fb;
+       struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_unpin_work *work;
        unsigned long flags;
@@ -7282,8 +7308,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 
        work->event = event;
        work->crtc = crtc;
-       intel_fb = to_intel_framebuffer(crtc->fb);
-       work->old_fb_obj = intel_fb->obj;
+       work->old_fb_obj = to_intel_framebuffer(old_fb)->obj;
        INIT_WORK(&work->work, intel_unpin_work_fn);
 
        ret = drm_vblank_get(dev, intel_crtc->pipe);
@@ -7303,9 +7328,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        intel_crtc->unpin_work = work;
        spin_unlock_irqrestore(&dev->event_lock, flags);
 
-       intel_fb = to_intel_framebuffer(fb);
-       obj = intel_fb->obj;
-
        if (atomic_read(&intel_crtc->unpin_work_count) >= 2)
                flush_workqueue(dev_priv->wq);
 
@@ -7340,6 +7362,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 
 cleanup_pending:
        atomic_dec(&intel_crtc->unpin_work_count);
+       crtc->fb = old_fb;
        drm_gem_object_unreference(&work->old_fb_obj->base);
        drm_gem_object_unreference(&obj->base);
        mutex_unlock(&dev->struct_mutex);
index f61cb7998c7230d28c83850aeab068958be5df3a..6f728e5ee79391d3bf726f971eb7b96af307df0d 100644 (file)
@@ -353,7 +353,8 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq)
 
 #define C (((status = I915_READ_NOTRACE(ch_ctl)) & DP_AUX_CH_CTL_SEND_BUSY) == 0)
        if (has_aux_irq)
-               done = wait_event_timeout(dev_priv->gmbus_wait_queue, C, 10);
+               done = wait_event_timeout(dev_priv->gmbus_wait_queue, C,
+                                         msecs_to_jiffies(10));
        else
                done = wait_for_atomic(C, 10) == 0;
        if (!done)
index 61fee7fcdc2c1efeb7c7c0fd1d0fd058e2dd3199..a1794c6df1bf1b80917f60e2145c39ae741aa478 100644 (file)
@@ -2574,7 +2574,7 @@ static void gen6_enable_rps(struct drm_device *dev)
        I915_WRITE(GEN6_RC_SLEEP, 0);
        I915_WRITE(GEN6_RC1e_THRESHOLD, 1000);
        I915_WRITE(GEN6_RC6_THRESHOLD, 50000);
-       I915_WRITE(GEN6_RC6p_THRESHOLD, 100000);
+       I915_WRITE(GEN6_RC6p_THRESHOLD, 150000);
        I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
 
        /* Check if we are enabling RC6 */
index 5ea5033eae0a4109d9230dd663508273da0bfd7c..4d932c46725dda950a4b2cd197e1923fca18ab50 100644 (file)
@@ -112,7 +112,6 @@ struct mga_framebuffer {
 struct mga_fbdev {
        struct drm_fb_helper helper;
        struct mga_framebuffer mfb;
-       struct list_head fbdev_list;
        void *sysram;
        int size;
        struct ttm_bo_kmap_obj mapping;
index 5a88ec51b5137604c0a0824fea72941e6de8ccc7..d3dcf54e6233dd332e36a18e8b683272a9c63a04 100644 (file)
@@ -92,6 +92,7 @@ struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev)
        int ret;
        int data, clock;
 
+       WREG_DAC(MGA1064_GEN_IO_CTL2, 1);
        WREG_DAC(MGA1064_GEN_IO_DATA, 0xff);
        WREG_DAC(MGA1064_GEN_IO_CTL, 0);
 
index d3d99a28ddef770d78525cd2e32786f40f047084..a274b9906ef892334460f061e542839a752a591f 100644 (file)
@@ -1406,6 +1406,14 @@ static int mga_vga_get_modes(struct drm_connector *connector)
 static int mga_vga_mode_valid(struct drm_connector *connector,
                                 struct drm_display_mode *mode)
 {
+       struct drm_device *dev = connector->dev;
+       struct mga_device *mdev = (struct mga_device*)dev->dev_private;
+       struct mga_fbdev *mfbdev = mdev->mfbdev;
+       struct drm_fb_helper *fb_helper = &mfbdev->helper;
+       struct drm_fb_helper_connector *fb_helper_conn = NULL;
+       int bpp = 32;
+       int i = 0;
+
        /* FIXME: Add bandwidth and g200se limitations */
 
        if (mode->crtc_hdisplay > 2048 || mode->crtc_hsync_start > 4096 ||
@@ -1415,6 +1423,25 @@ static int mga_vga_mode_valid(struct drm_connector *connector,
                return MODE_BAD;
        }
 
+       /* Validate the mode input by the user */
+       for (i = 0; i < fb_helper->connector_count; i++) {
+               if (fb_helper->connector_info[i]->connector == connector) {
+                       /* Found the helper for this connector */
+                       fb_helper_conn = fb_helper->connector_info[i];
+                       if (fb_helper_conn->cmdline_mode.specified) {
+                               if (fb_helper_conn->cmdline_mode.bpp_specified) {
+                                       bpp = fb_helper_conn->cmdline_mode.bpp;
+                               }
+                       }
+               }
+       }
+
+       if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > mdev->mc.vram_size) {
+               if (fb_helper_conn)
+                       fb_helper_conn->cmdline_mode.specified = false;
+               return MODE_BAD;
+       }
+
        return MODE_OK;
 }
 
index 61cec0f6ff1cae895c85562351cfcdaf777df82f..4857f913efddd3226c9a8d9362031c337bcefbdf 100644 (file)
@@ -350,7 +350,7 @@ nve0_graph_init_gpc_0(struct nvc0_graph_priv *priv)
                nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918);
        }
 
-       nv_wr32(priv, GPC_BCAST(0x1bd4), magicgpc918);
+       nv_wr32(priv, GPC_BCAST(0x3fd4), magicgpc918);
        nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800));
 }
 
index 2cc1e6a5eb6aa2b46eb27632ecafe71222cc9041..9c41b58d57e2511a2988447dbb46eb376d853868 100644 (file)
@@ -869,7 +869,7 @@ init_idx_addr_latched(struct nvbios_init *init)
                init->offset += 2;
 
                init_wr32(init, dreg, idata);
-               init_mask(init, creg, ~mask, data | idata);
+               init_mask(init, creg, ~mask, data | iaddr);
        }
 }
 
index a114a0ed7e98d13546a2d8672990985fd3f4c257..2e98e8a3f1aa33c8ccf9673334d7fd3e73dab708 100644 (file)
@@ -142,6 +142,7 @@ nouveau_i2c_port_create_(struct nouveau_object *parent,
        /* drop port's i2c subdev refcount, i2c handles this itself */
        if (ret == 0) {
                list_add_tail(&port->head, &i2c->ports);
+               atomic_dec(&parent->refcount);
                atomic_dec(&engine->refcount);
        }
 
index d28430cd2ba6066ad62c118b8d13d59fa7a88793..6e7a55f93a85207c10198b890b31df7dd0f7bd3c 100644 (file)
@@ -47,6 +47,18 @@ nouveau_agp_enabled(struct nouveau_drm *drm)
        if (drm->agp.stat == UNKNOWN) {
                if (!nouveau_agpmode)
                        return false;
+#ifdef __powerpc__
+               /* Disable AGP by default on all PowerPC machines for
+                * now -- At least some UniNorth-2 AGP bridges are
+                * known to be broken: DMA from the host to the card
+                * works just fine, but writeback from the card to the
+                * host goes straight to memory untranslated bypassing
+                * the GATT somehow, making them quite painful to deal
+                * with...
+                */
+               if (nouveau_agpmode == -1)
+                       return false;
+#endif
                return true;
        }
 
index a6237c9cbbc30c5cacfc246733fdbf1c67e68588..87a5a56ed358f2dda0098f955d98c6ca0df2104b 100644 (file)
@@ -55,9 +55,9 @@
 
 /* offsets in shared sync bo of various structures */
 #define EVO_SYNC(c, o) ((c) * 0x0100 + (o))
-#define EVO_MAST_NTFY     EVO_SYNC(  0, 0x00)
-#define EVO_FLIP_SEM0(c)  EVO_SYNC((c), 0x00)
-#define EVO_FLIP_SEM1(c)  EVO_SYNC((c), 0x10)
+#define EVO_MAST_NTFY     EVO_SYNC(      0, 0x00)
+#define EVO_FLIP_SEM0(c)  EVO_SYNC((c) + 1, 0x00)
+#define EVO_FLIP_SEM1(c)  EVO_SYNC((c) + 1, 0x10)
 
 #define EVO_CORE_HANDLE      (0xd1500000)
 #define EVO_CHAN_HANDLE(t,i) (0xd15c0000 | (((t) & 0x00ff) << 8) | (i))
@@ -341,10 +341,8 @@ struct nv50_curs {
 
 struct nv50_sync {
        struct nv50_dmac base;
-       struct {
-               u32 offset;
-               u16 value;
-       } sem;
+       u32 addr;
+       u32 data;
 };
 
 struct nv50_ovly {
@@ -471,13 +469,33 @@ nv50_display_crtc_sema(struct drm_device *dev, int crtc)
        return nv50_disp(dev)->sync;
 }
 
+struct nv50_display_flip {
+       struct nv50_disp *disp;
+       struct nv50_sync *chan;
+};
+
+static bool
+nv50_display_flip_wait(void *data)
+{
+       struct nv50_display_flip *flip = data;
+       if (nouveau_bo_rd32(flip->disp->sync, flip->chan->addr / 4) ==
+                                             flip->chan->data);
+               return true;
+       usleep_range(1, 2);
+       return false;
+}
+
 void
 nv50_display_flip_stop(struct drm_crtc *crtc)
 {
-       struct nv50_sync *sync = nv50_sync(crtc);
+       struct nouveau_device *device = nouveau_dev(crtc->dev);
+       struct nv50_display_flip flip = {
+               .disp = nv50_disp(crtc->dev),
+               .chan = nv50_sync(crtc),
+       };
        u32 *push;
 
-       push = evo_wait(sync, 8);
+       push = evo_wait(flip.chan, 8);
        if (push) {
                evo_mthd(push, 0x0084, 1);
                evo_data(push, 0x00000000);
@@ -487,8 +505,10 @@ nv50_display_flip_stop(struct drm_crtc *crtc)
                evo_data(push, 0x00000000);
                evo_mthd(push, 0x0080, 1);
                evo_data(push, 0x00000000);
-               evo_kick(push, sync);
+               evo_kick(push, flip.chan);
        }
+
+       nv_wait_cb(device, nv50_display_flip_wait, &flip);
 }
 
 int
@@ -496,11 +516,10 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
                       struct nouveau_channel *chan, u32 swap_interval)
 {
        struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb);
-       struct nv50_disp *disp = nv50_disp(crtc->dev);
        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
        struct nv50_sync *sync = nv50_sync(crtc);
+       int head = nv_crtc->index, ret;
        u32 *push;
-       int ret;
 
        swap_interval <<= 4;
        if (swap_interval == 0)
@@ -510,58 +529,64 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
        if (unlikely(push == NULL))
                return -EBUSY;
 
-       /* synchronise with the rendering channel, if necessary */
-       if (likely(chan)) {
+       if (chan && nv_mclass(chan->object) < NV84_CHANNEL_IND_CLASS) {
+               ret = RING_SPACE(chan, 8);
+               if (ret)
+                       return ret;
+
+               BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2);
+               OUT_RING  (chan, NvEvoSema0 + head);
+               OUT_RING  (chan, sync->addr ^ 0x10);
+               BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_RELEASE, 1);
+               OUT_RING  (chan, sync->data + 1);
+               BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_OFFSET, 2);
+               OUT_RING  (chan, sync->addr);
+               OUT_RING  (chan, sync->data);
+       } else
+       if (chan && nv_mclass(chan->object) < NVC0_CHANNEL_IND_CLASS) {
+               u64 addr = nv84_fence_crtc(chan, head) + sync->addr;
+               ret = RING_SPACE(chan, 12);
+               if (ret)
+                       return ret;
+
+               BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1);
+               OUT_RING  (chan, chan->vram);
+               BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
+               OUT_RING  (chan, upper_32_bits(addr ^ 0x10));
+               OUT_RING  (chan, lower_32_bits(addr ^ 0x10));
+               OUT_RING  (chan, sync->data + 1);
+               OUT_RING  (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG);
+               BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
+               OUT_RING  (chan, upper_32_bits(addr));
+               OUT_RING  (chan, lower_32_bits(addr));
+               OUT_RING  (chan, sync->data);
+               OUT_RING  (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL);
+       } else
+       if (chan) {
+               u64 addr = nv84_fence_crtc(chan, head) + sync->addr;
                ret = RING_SPACE(chan, 10);
                if (ret)
                        return ret;
 
-               if (nv_mclass(chan->object) < NV84_CHANNEL_IND_CLASS) {
-                       BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2);
-                       OUT_RING  (chan, NvEvoSema0 + nv_crtc->index);
-                       OUT_RING  (chan, sync->sem.offset);
-                       BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_RELEASE, 1);
-                       OUT_RING  (chan, 0xf00d0000 | sync->sem.value);
-                       BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_OFFSET, 2);
-                       OUT_RING  (chan, sync->sem.offset ^ 0x10);
-                       OUT_RING  (chan, 0x74b1e000);
-                       BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1);
-                       OUT_RING  (chan, NvSema);
-               } else
-               if (nv_mclass(chan->object) < NVC0_CHANNEL_IND_CLASS) {
-                       u64 offset = nv84_fence_crtc(chan, nv_crtc->index);
-                       offset += sync->sem.offset;
-
-                       BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
-                       OUT_RING  (chan, upper_32_bits(offset));
-                       OUT_RING  (chan, lower_32_bits(offset));
-                       OUT_RING  (chan, 0xf00d0000 | sync->sem.value);
-                       OUT_RING  (chan, 0x00000002);
-                       BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
-                       OUT_RING  (chan, upper_32_bits(offset));
-                       OUT_RING  (chan, lower_32_bits(offset ^ 0x10));
-                       OUT_RING  (chan, 0x74b1e000);
-                       OUT_RING  (chan, 0x00000001);
-               } else {
-                       u64 offset = nv84_fence_crtc(chan, nv_crtc->index);
-                       offset += sync->sem.offset;
-
-                       BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
-                       OUT_RING  (chan, upper_32_bits(offset));
-                       OUT_RING  (chan, lower_32_bits(offset));
-                       OUT_RING  (chan, 0xf00d0000 | sync->sem.value);
-                       OUT_RING  (chan, 0x00001002);
-                       BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
-                       OUT_RING  (chan, upper_32_bits(offset));
-                       OUT_RING  (chan, lower_32_bits(offset ^ 0x10));
-                       OUT_RING  (chan, 0x74b1e000);
-                       OUT_RING  (chan, 0x00001001);
-               }
+               BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
+               OUT_RING  (chan, upper_32_bits(addr ^ 0x10));
+               OUT_RING  (chan, lower_32_bits(addr ^ 0x10));
+               OUT_RING  (chan, sync->data + 1);
+               OUT_RING  (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG |
+                                NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD);
+               BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
+               OUT_RING  (chan, upper_32_bits(addr));
+               OUT_RING  (chan, lower_32_bits(addr));
+               OUT_RING  (chan, sync->data);
+               OUT_RING  (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL |
+                                NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD);
+       }
 
+       if (chan) {
+               sync->addr ^= 0x10;
+               sync->data++;
                FIRE_RING (chan);
        } else {
-               nouveau_bo_wr32(disp->sync, sync->sem.offset / 4,
-                               0xf00d0000 | sync->sem.value);
                evo_sync(crtc->dev);
        }
 
@@ -575,9 +600,9 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
                evo_data(push, 0x40000000);
        }
        evo_mthd(push, 0x0088, 4);
-       evo_data(push, sync->sem.offset);
-       evo_data(push, 0xf00d0000 | sync->sem.value);
-       evo_data(push, 0x74b1e000);
+       evo_data(push, sync->addr);
+       evo_data(push, sync->data++);
+       evo_data(push, sync->data);
        evo_data(push, NvEvoSync);
        evo_mthd(push, 0x00a0, 2);
        evo_data(push, 0x00000000);
@@ -605,9 +630,6 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
        evo_mthd(push, 0x0080, 1);
        evo_data(push, 0x00000000);
        evo_kick(push, sync);
-
-       sync->sem.offset ^= 0x10;
-       sync->sem.value++;
        return 0;
 }
 
@@ -1379,7 +1401,8 @@ nv50_crtc_create(struct drm_device *dev, struct nouveau_object *core, int index)
        if (ret)
                goto out;
 
-       head->sync.sem.offset = EVO_SYNC(1 + index, 0x00);
+       head->sync.addr = EVO_FLIP_SEM0(index);
+       head->sync.data = 0x00000000;
 
        /* allocate overlay resources */
        ret = nv50_pioc_create(disp->core, NV50_DISP_OIMM_CLASS, index,
@@ -2112,15 +2135,23 @@ nv50_display_fini(struct drm_device *dev)
 int
 nv50_display_init(struct drm_device *dev)
 {
-       u32 *push = evo_wait(nv50_mast(dev), 32);
-       if (push) {
-               evo_mthd(push, 0x0088, 1);
-               evo_data(push, NvEvoSync);
-               evo_kick(push, nv50_mast(dev));
-               return 0;
+       struct nv50_disp *disp = nv50_disp(dev);
+       struct drm_crtc *crtc;
+       u32 *push;
+
+       push = evo_wait(nv50_mast(dev), 32);
+       if (!push)
+               return -EBUSY;
+
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+               struct nv50_sync *sync = nv50_sync(crtc);
+               nouveau_bo_wr32(disp->sync, sync->addr / 4, sync->data);
        }
 
-       return -EBUSY;
+       evo_mthd(push, 0x0088, 1);
+       evo_data(push, NvEvoSync);
+       evo_kick(push, nv50_mast(dev));
+       return 0;
 }
 
 void
index 3c38ea46531cfe6b9bc6397c01337393fe3e8a51..305a657bf21561242991e56365439781df54c2df 100644 (file)
@@ -2438,6 +2438,12 @@ static u32 evergreen_gpu_check_soft_reset(struct radeon_device *rdev)
        if (tmp & L2_BUSY)
                reset_mask |= RADEON_RESET_VMC;
 
+       /* Skip MC reset as it's mostly likely not hung, just busy */
+       if (reset_mask & RADEON_RESET_MC) {
+               DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
+               reset_mask &= ~RADEON_RESET_MC;
+       }
+
        return reset_mask;
 }
 
index 99fb13286fd02d3393ff09e28b9c10e91cb9d9e7..eb8ac315f92faa3cbd58468b6bf9ba360a8c0986 100644 (file)
@@ -834,7 +834,7 @@ static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p,
                         __func__, __LINE__, toffset, surf.base_align);
                return -EINVAL;
        }
-       if (moffset & (surf.base_align - 1)) {
+       if (surf.nsamples <= 1 && moffset & (surf.base_align - 1)) {
                dev_warn(p->dev, "%s:%d mipmap bo base %ld not aligned with %ld\n",
                         __func__, __LINE__, moffset, surf.base_align);
                return -EINVAL;
index 7cead763be9ec760ad05919ae11d4e5a6b504d85..d4c633e12863bb9c546d6eae81d3fb7f835303e9 100644 (file)
@@ -1381,6 +1381,12 @@ static u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev)
        if (tmp & L2_BUSY)
                reset_mask |= RADEON_RESET_VMC;
 
+       /* Skip MC reset as it's mostly likely not hung, just busy */
+       if (reset_mask & RADEON_RESET_MC) {
+               DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
+               reset_mask &= ~RADEON_RESET_MC;
+       }
+
        return reset_mask;
 }
 
index 6d4b5611daf4b2f96c05c00593c186acbb015e7f..0740db3fcd2268af78e286ec6ec634570ff7efcd 100644 (file)
@@ -1394,6 +1394,12 @@ static u32 r600_gpu_check_soft_reset(struct radeon_device *rdev)
        if (r600_is_display_hung(rdev))
                reset_mask |= RADEON_RESET_DISPLAY;
 
+       /* Skip MC reset as it's mostly likely not hung, just busy */
+       if (reset_mask & RADEON_RESET_MC) {
+               DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
+               reset_mask &= ~RADEON_RESET_MC;
+       }
+
        return reset_mask;
 }
 
index 3e403bdda58fc8eb69b3583d647770f2b9b41210..78edadc9e86b22b8ec64d5877f4b98365cafcffd 100644 (file)
@@ -970,6 +970,15 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct
                        found = 1;
        }
 
+       /* quirks */
+       /* Radeon 9100 (R200) */
+       if ((dev->pdev->device == 0x514D) &&
+           (dev->pdev->subsystem_vendor == 0x174B) &&
+           (dev->pdev->subsystem_device == 0x7149)) {
+               /* vbios value is bad, use the default */
+               found = 0;
+       }
+
        if (!found) /* fallback to defaults */
                radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac);
 
index 167758488ed6fd6781cbf3fa5d8a5b5a1e3c10a1..66a7f0fd96201f09a7f540057d62c9bd89d6b23e 100644 (file)
  *   2.27.0 - r600-SI: Add CS ioctl support for async DMA
  *   2.28.0 - r600-eg: Add MEM_WRITE packet support
  *   2.29.0 - R500 FP16 color clear registers
+ *   2.30.0 - fix for FMASK texturing
  */
 #define KMS_DRIVER_MAJOR       2
-#define KMS_DRIVER_MINOR       29
+#define KMS_DRIVER_MINOR       30
 #define KMS_DRIVER_PATCHLEVEL  0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);
index 90374dd7796003381adb8a774e061d722579adda..48f80cd42d8f35a8a4e8757c6268172288c4573a 100644 (file)
@@ -400,6 +400,9 @@ void radeon_irq_kms_enable_afmt(struct radeon_device *rdev, int block)
 {
        unsigned long irqflags;
 
+       if (!rdev->ddev->irq_enabled)
+               return;
+
        spin_lock_irqsave(&rdev->irq.lock, irqflags);
        rdev->irq.afmt[block] = true;
        radeon_irq_set(rdev);
@@ -419,6 +422,9 @@ void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block)
 {
        unsigned long irqflags;
 
+       if (!rdev->ddev->irq_enabled)
+               return;
+
        spin_lock_irqsave(&rdev->irq.lock, irqflags);
        rdev->irq.afmt[block] = false;
        radeon_irq_set(rdev);
@@ -438,6 +444,9 @@ void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask)
        unsigned long irqflags;
        int i;
 
+       if (!rdev->ddev->irq_enabled)
+               return;
+
        spin_lock_irqsave(&rdev->irq.lock, irqflags);
        for (i = 0; i < RADEON_MAX_HPD_PINS; ++i)
                rdev->irq.hpd[i] |= !!(hpd_mask & (1 << i));
@@ -458,6 +467,9 @@ void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask)
        unsigned long irqflags;
        int i;
 
+       if (!rdev->ddev->irq_enabled)
+               return;
+
        spin_lock_irqsave(&rdev->irq.lock, irqflags);
        for (i = 0; i < RADEON_MAX_HPD_PINS; ++i)
                rdev->irq.hpd[i] &= !(hpd_mask & (1 << i));
index 80979ed951eb1afdacafa23b89ac7e116075858f..9128120da04441621ec1050b8cb0ff236704b7cf 100644 (file)
@@ -2284,6 +2284,12 @@ static u32 si_gpu_check_soft_reset(struct radeon_device *rdev)
        if (tmp & L2_BUSY)
                reset_mask |= RADEON_RESET_VMC;
 
+       /* Skip MC reset as it's mostly likely not hung, just busy */
+       if (reset_mask & RADEON_RESET_MC) {
+               DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
+               reset_mask &= ~RADEON_RESET_MC;
+       }
+
        return reset_mask;
 }
 
index c92955df065888b3c5898b91093bf1d3cb195807..be1daf7344d3bde2fccd59c7a156f575b594dae4 100644 (file)
@@ -4,7 +4,6 @@ config DRM_TEGRA
        select DRM_KMS_HELPER
        select DRM_GEM_CMA_HELPER
        select DRM_KMS_CMA_HELPER
-       select DRM_HDMI
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
index 9500f2f3f8fea702432e683a56dc0eea53dbf3fe..8758f38c948c2022b45da342f15025228ea6b22d 100644 (file)
@@ -459,19 +459,25 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev,
                                    struct dj_report *dj_report)
 {
        struct hid_device *hdev = djrcv_dev->hdev;
-       int sent_bytes;
+       struct hid_report *report;
+       struct hid_report_enum *output_report_enum;
+       u8 *data = (u8 *)(&dj_report->device_index);
+       int i;
 
-       if (!hdev->hid_output_raw_report) {
-               dev_err(&hdev->dev, "%s:"
-                       "hid_output_raw_report is null\n", __func__);
+       output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
+       report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
+
+       if (!report) {
+               dev_err(&hdev->dev, "%s: unable to find dj report\n", __func__);
                return -ENODEV;
        }
 
-       sent_bytes = hdev->hid_output_raw_report(hdev, (u8 *) dj_report,
-                                                sizeof(struct dj_report),
-                                                HID_OUTPUT_REPORT);
+       for (i = 0; i < report->field[0]->report_count; i++)
+               report->field[0]->value[i] = data[i];
+
+       usbhid_submit_report(hdev, report, USB_DIR_OUT);
 
-       return (sent_bytes < 0) ? sent_bytes : 0;
+       return 0;
 }
 
 static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
index 9652a2c92a24ddfa00d4100584093da96b6821fe..a58de38e23d821f969a720e9fe03be6aca87752a 100644 (file)
@@ -62,7 +62,7 @@ struct ltc2978_data {
        int temp_min, temp_max;
        int vout_min[8], vout_max[8];
        int iout_max[2];
-       int temp2_max[2];
+       int temp2_max;
        struct pmbus_driver_info info;
 };
 
@@ -204,10 +204,9 @@ static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg)
                ret = pmbus_read_word_data(client, page,
                                           LTC3880_MFR_TEMPERATURE2_PEAK);
                if (ret >= 0) {
-                       if (lin11_to_val(ret)
-                           > lin11_to_val(data->temp2_max[page]))
-                               data->temp2_max[page] = ret;
-                       ret = data->temp2_max[page];
+                       if (lin11_to_val(ret) > lin11_to_val(data->temp2_max))
+                               data->temp2_max = ret;
+                       ret = data->temp2_max;
                }
                break;
        case PMBUS_VIRT_READ_VIN_MIN:
@@ -248,11 +247,11 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page,
 
        switch (reg) {
        case PMBUS_VIRT_RESET_IOUT_HISTORY:
-               data->iout_max[page] = 0x7fff;
+               data->iout_max[page] = 0x7c00;
                ret = ltc2978_clear_peaks(client, page, data->id);
                break;
        case PMBUS_VIRT_RESET_TEMP2_HISTORY:
-               data->temp2_max[page] = 0x7fff;
+               data->temp2_max = 0x7c00;
                ret = ltc2978_clear_peaks(client, page, data->id);
                break;
        case PMBUS_VIRT_RESET_VOUT_HISTORY:
@@ -262,12 +261,12 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page,
                break;
        case PMBUS_VIRT_RESET_VIN_HISTORY:
                data->vin_min = 0x7bff;
-               data->vin_max = 0;
+               data->vin_max = 0x7c00;
                ret = ltc2978_clear_peaks(client, page, data->id);
                break;
        case PMBUS_VIRT_RESET_TEMP_HISTORY:
                data->temp_min = 0x7bff;
-               data->temp_max = 0x7fff;
+               data->temp_max = 0x7c00;
                ret = ltc2978_clear_peaks(client, page, data->id);
                break;
        default:
@@ -321,12 +320,13 @@ static int ltc2978_probe(struct i2c_client *client,
        info = &data->info;
        info->write_word_data = ltc2978_write_word_data;
 
-       data->vout_min[0] = 0xffff;
        data->vin_min = 0x7bff;
+       data->vin_max = 0x7c00;
        data->temp_min = 0x7bff;
-       data->temp_max = 0x7fff;
+       data->temp_max = 0x7c00;
+       data->temp2_max = 0x7c00;
 
-       switch (id->driver_data) {
+       switch (data->id) {
        case ltc2978:
                info->read_word_data = ltc2978_read_word_data;
                info->pages = 8;
@@ -336,7 +336,6 @@ static int ltc2978_probe(struct i2c_client *client,
                for (i = 1; i < 8; i++) {
                        info->func[i] = PMBUS_HAVE_VOUT
                          | PMBUS_HAVE_STATUS_VOUT;
-                       data->vout_min[i] = 0xffff;
                }
                break;
        case ltc3880:
@@ -352,11 +351,14 @@ static int ltc2978_probe(struct i2c_client *client,
                  | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
                  | PMBUS_HAVE_POUT
                  | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
-               data->vout_min[1] = 0xffff;
+               data->iout_max[0] = 0x7c00;
+               data->iout_max[1] = 0x7c00;
                break;
        default:
                return -ENODEV;
        }
+       for (i = 0; i < info->pages; i++)
+               data->vout_min[i] = 0xffff;
 
        return pmbus_do_probe(client, id, info);
 }
index bfe326e896dfd6d277ed22aec18ff9431ae8b8c1..2507f902fb7aa4ea450079a69bbbf8234e7e0ef4 100644 (file)
@@ -965,7 +965,13 @@ static int sht15_probe(struct platform_device *pdev)
                if (voltage)
                        data->supply_uv = voltage;
 
-               regulator_enable(data->reg);
+               ret = regulator_enable(data->reg);
+               if (ret != 0) {
+                       dev_err(&pdev->dev,
+                               "failed to enable regulator: %d\n", ret);
+                       return ret;
+               }
+
                /*
                 * Setup a notifier block to update this if another device
                 * causes the voltage to change
index a479375a8fd8067ad5cabd21974f441f996f90d6..e0c404bdc4a8333d60cef68189e8d2513d7ccc1a 100644 (file)
@@ -410,6 +410,7 @@ static struct file_system_type ipathfs_fs_type = {
        .mount =        ipathfs_mount,
        .kill_sb =      ipathfs_kill_super,
 };
+MODULE_ALIAS_FS("ipathfs");
 
 int __init ipath_init_ipathfs(void)
 {
index 644bd6f6467ca0d7a38c9aa915c49873eea72f38..f247fc6e61826db010b2ac6c267e5fe1ee3ae09b 100644 (file)
@@ -604,6 +604,7 @@ static struct file_system_type qibfs_fs_type = {
        .mount =        qibfs_mount,
        .kill_sb =      qibfs_kill_super,
 };
+MODULE_ALIAS_FS("ipathfs");
 
 int __init qib_init_qibfs(void)
 {
index d04f810cb1ddf8d617f1a77e7aa8d6d8657a6ca8..59aa24002c7bff9e1f8629787c7c0ce9eea36886 100644 (file)
 /* Define for MXT_GEN_COMMAND_T6 */
 #define MXT_BOOT_VALUE         0xa5
 #define MXT_BACKUP_VALUE       0x55
-#define MXT_BACKUP_TIME                25      /* msec */
-#define MXT_RESET_TIME         65      /* msec */
+#define MXT_BACKUP_TIME                50      /* msec */
+#define MXT_RESET_TIME         200     /* msec */
 
 #define MXT_FWRESET_TIME       175     /* msec */
 
+/* MXT_SPT_GPIOPWM_T19 field */
+#define MXT_GPIO0_MASK         0x04
+#define MXT_GPIO1_MASK         0x08
+#define MXT_GPIO2_MASK         0x10
+#define MXT_GPIO3_MASK         0x20
+
 /* Command to unlock bootloader */
 #define MXT_UNLOCK_CMD_MSB     0xaa
 #define MXT_UNLOCK_CMD_LSB     0xdc
 /* Touchscreen absolute values */
 #define MXT_MAX_AREA           0xff
 
+#define MXT_PIXELS_PER_MM      20
+
 struct mxt_info {
        u8 family_id;
        u8 variant_id;
@@ -243,6 +251,8 @@ struct mxt_data {
        const struct mxt_platform_data *pdata;
        struct mxt_object *object_table;
        struct mxt_info info;
+       bool is_tp;
+
        unsigned int irq;
        unsigned int max_x;
        unsigned int max_y;
@@ -251,6 +261,7 @@ struct mxt_data {
        u8 T6_reportid;
        u8 T9_reportid_min;
        u8 T9_reportid_max;
+       u8 T19_reportid;
 };
 
 static bool mxt_object_readable(unsigned int type)
@@ -502,6 +513,21 @@ static int mxt_write_object(struct mxt_data *data,
        return mxt_write_reg(data->client, reg + offset, val);
 }
 
+static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
+{
+       struct input_dev *input = data->input_dev;
+       bool button;
+       int i;
+
+       /* Active-low switch */
+       for (i = 0; i < MXT_NUM_GPIO; i++) {
+               if (data->pdata->key_map[i] == KEY_RESERVED)
+                       continue;
+               button = !(message->message[0] & MXT_GPIO0_MASK << i);
+               input_report_key(input, data->pdata->key_map[i], button);
+       }
+}
+
 static void mxt_input_touchevent(struct mxt_data *data,
                                      struct mxt_message *message, int id)
 {
@@ -585,6 +611,9 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
                        int id = reportid - data->T9_reportid_min;
                        mxt_input_touchevent(data, &message, id);
                        update_input = true;
+               } else if (message.reportid == data->T19_reportid) {
+                       mxt_input_button(data, &message);
+                       update_input = true;
                } else {
                        mxt_dump_message(dev, &message);
                }
@@ -764,6 +793,9 @@ static int mxt_get_object_table(struct mxt_data *data)
                        data->T9_reportid_min = min_id;
                        data->T9_reportid_max = max_id;
                        break;
+               case MXT_SPT_GPIOPWM_T19:
+                       data->T19_reportid = min_id;
+                       break;
                }
        }
 
@@ -777,7 +809,7 @@ static void mxt_free_object_table(struct mxt_data *data)
        data->T6_reportid = 0;
        data->T9_reportid_min = 0;
        data->T9_reportid_max = 0;
-
+       data->T19_reportid = 0;
 }
 
 static int mxt_initialize(struct mxt_data *data)
@@ -1115,9 +1147,13 @@ static int mxt_probe(struct i2c_client *client,
                goto err_free_mem;
        }
 
-       input_dev->name = "Atmel maXTouch Touchscreen";
+       data->is_tp = pdata && pdata->is_tp;
+
+       input_dev->name = (data->is_tp) ? "Atmel maXTouch Touchpad" :
+                                         "Atmel maXTouch Touchscreen";
        snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0",
                 client->adapter->nr, client->addr);
+
        input_dev->phys = data->phys;
 
        input_dev->id.bustype = BUS_I2C;
@@ -1140,6 +1176,29 @@ static int mxt_probe(struct i2c_client *client,
        __set_bit(EV_KEY, input_dev->evbit);
        __set_bit(BTN_TOUCH, input_dev->keybit);
 
+       if (data->is_tp) {
+               int i;
+               __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
+               __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
+
+               for (i = 0; i < MXT_NUM_GPIO; i++)
+                       if (pdata->key_map[i] != KEY_RESERVED)
+                               __set_bit(pdata->key_map[i], input_dev->keybit);
+
+               __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
+               __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
+               __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
+               __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
+               __set_bit(BTN_TOOL_QUINTTAP, input_dev->keybit);
+
+               input_abs_set_res(input_dev, ABS_X, MXT_PIXELS_PER_MM);
+               input_abs_set_res(input_dev, ABS_Y, MXT_PIXELS_PER_MM);
+               input_abs_set_res(input_dev, ABS_MT_POSITION_X,
+                                 MXT_PIXELS_PER_MM);
+               input_abs_set_res(input_dev, ABS_MT_POSITION_Y,
+                                 MXT_PIXELS_PER_MM);
+       }
+
        /* For single touch */
        input_set_abs_params(input_dev, ABS_X,
                             0, data->max_x, 0, 0);
@@ -1258,6 +1317,7 @@ static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume);
 static const struct i2c_device_id mxt_id[] = {
        { "qt602240_ts", 0 },
        { "atmel_mxt_ts", 0 },
+       { "atmel_mxt_tp", 0 },
        { "mXT224", 0 },
        { }
 };
index dc7e478b7e5f88443e059a1afeca4b57b6e778a4..e5cdaf87822c3a5e53b07feedb47c33ffc5d2d09 100644 (file)
@@ -1083,6 +1083,7 @@ static const char *dma_remap_fault_reasons[] =
        "non-zero reserved fields in RTP",
        "non-zero reserved fields in CTP",
        "non-zero reserved fields in PTE",
+       "PCE for translation request specifies blocking",
 };
 
 static const char *irq_remap_fault_reasons[] =
index 017c67ea3f4c7681ef5fb0fbd66b7009b89ed14d..ead0a4fb7448643faa66cb8c3fceee3c2b62d9fd 100644 (file)
@@ -294,13 +294,13 @@ int st5481_setup_usb(struct st5481_adapter *adapter)
        // Allocate URBs and buffers for interrupt endpoint
        urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!urb) {
-               return -ENOMEM;
+               goto err1;
        }
        intr->urb = urb;
 
        buf = kmalloc(INT_PKT_SIZE, GFP_KERNEL);
        if (!buf) {
-               return -ENOMEM;
+               goto err2;
        }
 
        endpoint = &altsetting->endpoint[EP_INT-1];
@@ -313,6 +313,14 @@ int st5481_setup_usb(struct st5481_adapter *adapter)
                         endpoint->desc.bInterval);
 
        return 0;
+err2:
+       usb_free_urb(intr->urb);
+       intr->urb = NULL;
+err1:
+       usb_free_urb(ctrl->urb);
+       ctrl->urb = NULL;
+
+       return -ENOMEM;
 }
 
 /*
index c45b3aedafba975f720a1ab422c764ef4fe1b0c4..d873cbae2fbb86acb6d9ad2ba02842d4144ac2b6 100644 (file)
@@ -138,8 +138,7 @@ int pl320_ipc_unregister_notifier(struct notifier_block *nb)
 }
 EXPORT_SYMBOL_GPL(pl320_ipc_unregister_notifier);
 
-static int __init pl320_probe(struct amba_device *adev,
-                               const struct amba_id *id)
+static int pl320_probe(struct amba_device *adev, const struct amba_id *id)
 {
        int ret;
 
index e30b490055aa8ce3ef3edf2229b6cd2724bf794a..4d8d90b4fe7812ea5169619d3945b0722d46f1ec 100644 (file)
@@ -154,17 +154,6 @@ config MD_RAID456
 
          If unsure, say Y.
 
-config MULTICORE_RAID456
-       bool "RAID-4/RAID-5/RAID-6 Multicore processing (EXPERIMENTAL)"
-       depends on MD_RAID456
-       depends on SMP
-       depends on EXPERIMENTAL
-       ---help---
-         Enable the raid456 module to dispatch per-stripe raid operations to a
-         thread pool.
-
-         If unsure, say N.
-
 config MD_MULTIPATH
        tristate "Multipath I/O support"
        depends on BLK_DEV_MD
index 9a01d1e4c78302a0fef677e2c516f2bf3daeca70..311e3d35b272e4ae30fa32b3bca9f567394896ef 100644 (file)
@@ -91,15 +91,44 @@ static struct raid_type {
        {"raid6_nc", "RAID6 (N continue)",              2, 4, 6, ALGORITHM_ROTATING_N_CONTINUE}
 };
 
+static char *raid10_md_layout_to_format(int layout)
+{
+       /*
+        * Bit 16 and 17 stand for "offset" and "use_far_sets"
+        * Refer to MD's raid10.c for details
+        */
+       if ((layout & 0x10000) && (layout & 0x20000))
+               return "offset";
+
+       if ((layout & 0xFF) > 1)
+               return "near";
+
+       return "far";
+}
+
 static unsigned raid10_md_layout_to_copies(int layout)
 {
-       return layout & 0xFF;
+       if ((layout & 0xFF) > 1)
+               return layout & 0xFF;
+       return (layout >> 8) & 0xFF;
 }
 
 static int raid10_format_to_md_layout(char *format, unsigned copies)
 {
-       /* 1 "far" copy, and 'copies' "near" copies */
-       return (1 << 8) | (copies & 0xFF);
+       unsigned n = 1, f = 1;
+
+       if (!strcmp("near", format))
+               n = copies;
+       else
+               f = copies;
+
+       if (!strcmp("offset", format))
+               return 0x30000 | (f << 8) | n;
+
+       if (!strcmp("far", format))
+               return 0x20000 | (f << 8) | n;
+
+       return (f << 8) | n;
 }
 
 static struct raid_type *get_raid_type(char *name)
@@ -352,6 +381,7 @@ static int validate_raid_redundancy(struct raid_set *rs)
 {
        unsigned i, rebuild_cnt = 0;
        unsigned rebuilds_per_group, copies, d;
+       unsigned group_size, last_group_start;
 
        for (i = 0; i < rs->md.raid_disks; i++)
                if (!test_bit(In_sync, &rs->dev[i].rdev.flags) ||
@@ -379,9 +409,6 @@ static int validate_raid_redundancy(struct raid_set *rs)
                 * as long as the failed devices occur in different mirror
                 * groups (i.e. different stripes).
                 *
-                * Right now, we only allow for "near" copies.  When other
-                * formats are added, we will have to check those too.
-                *
                 * When checking "near" format, make sure no adjacent devices
                 * have failed beyond what can be handled.  In addition to the
                 * simple case where the number of devices is a multiple of the
@@ -391,14 +418,41 @@ static int validate_raid_redundancy(struct raid_set *rs)
                 *          A    A    B    B    C
                 *          C    D    D    E    E
                 */
-               for (i = 0; i < rs->md.raid_disks * copies; i++) {
-                       if (!(i % copies))
+               if (!strcmp("near", raid10_md_layout_to_format(rs->md.layout))) {
+                       for (i = 0; i < rs->md.raid_disks * copies; i++) {
+                               if (!(i % copies))
+                                       rebuilds_per_group = 0;
+                               d = i % rs->md.raid_disks;
+                               if ((!rs->dev[d].rdev.sb_page ||
+                                    !test_bit(In_sync, &rs->dev[d].rdev.flags)) &&
+                                   (++rebuilds_per_group >= copies))
+                                       goto too_many;
+                       }
+                       break;
+               }
+
+               /*
+                * When checking "far" and "offset" formats, we need to ensure
+                * that the device that holds its copy is not also dead or
+                * being rebuilt.  (Note that "far" and "offset" formats only
+                * support two copies right now.  These formats also only ever
+                * use the 'use_far_sets' variant.)
+                *
+                * This check is somewhat complicated by the need to account
+                * for arrays that are not a multiple of (far) copies.  This
+                * results in the need to treat the last (potentially larger)
+                * set differently.
+                */
+               group_size = (rs->md.raid_disks / copies);
+               last_group_start = (rs->md.raid_disks / group_size) - 1;
+               last_group_start *= group_size;
+               for (i = 0; i < rs->md.raid_disks; i++) {
+                       if (!(i % copies) && !(i > last_group_start))
                                rebuilds_per_group = 0;
-                       d = i % rs->md.raid_disks;
-                       if ((!rs->dev[d].rdev.sb_page ||
-                            !test_bit(In_sync, &rs->dev[d].rdev.flags)) &&
+                       if ((!rs->dev[i].rdev.sb_page ||
+                            !test_bit(In_sync, &rs->dev[i].rdev.flags)) &&
                            (++rebuilds_per_group >= copies))
-                               goto too_many;
+                                       goto too_many;
                }
                break;
        default:
@@ -433,7 +487,7 @@ too_many:
  *
  * RAID10-only options:
  *    [raid10_copies <# copies>]        Number of copies.  (Default: 2)
- *    [raid10_format <near>]            Layout algorithm.  (Default: near)
+ *    [raid10_format <near|far|offset>] Layout algorithm.  (Default: near)
  */
 static int parse_raid_params(struct raid_set *rs, char **argv,
                             unsigned num_raid_params)
@@ -520,7 +574,9 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
                                rs->ti->error = "'raid10_format' is an invalid parameter for this RAID type";
                                return -EINVAL;
                        }
-                       if (strcmp("near", argv[i])) {
+                       if (strcmp("near", argv[i]) &&
+                           strcmp("far", argv[i]) &&
+                           strcmp("offset", argv[i])) {
                                rs->ti->error = "Invalid 'raid10_format' value given";
                                return -EINVAL;
                        }
@@ -644,6 +700,15 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
                        return -EINVAL;
                }
 
+               /*
+                * If the format is not "near", we only support
+                * two copies at the moment.
+                */
+               if (strcmp("near", raid10_format) && (raid10_copies > 2)) {
+                       rs->ti->error = "Too many copies for given RAID10 format.";
+                       return -EINVAL;
+               }
+
                /* (Len * #mirrors) / #devices */
                sectors_per_dev = rs->ti->len * raid10_copies;
                sector_div(sectors_per_dev, rs->md.raid_disks);
@@ -854,17 +919,30 @@ static int super_init_validation(struct mddev *mddev, struct md_rdev *rdev)
        /*
         * Reshaping is not currently allowed
         */
-       if ((le32_to_cpu(sb->level) != mddev->level) ||
-           (le32_to_cpu(sb->layout) != mddev->layout) ||
-           (le32_to_cpu(sb->stripe_sectors) != mddev->chunk_sectors)) {
-               DMERR("Reshaping arrays not yet supported.");
+       if (le32_to_cpu(sb->level) != mddev->level) {
+               DMERR("Reshaping arrays not yet supported. (RAID level change)");
+               return -EINVAL;
+       }
+       if (le32_to_cpu(sb->layout) != mddev->layout) {
+               DMERR("Reshaping arrays not yet supported. (RAID layout change)");
+               DMERR("  0x%X vs 0x%X", le32_to_cpu(sb->layout), mddev->layout);
+               DMERR("  Old layout: %s w/ %d copies",
+                     raid10_md_layout_to_format(le32_to_cpu(sb->layout)),
+                     raid10_md_layout_to_copies(le32_to_cpu(sb->layout)));
+               DMERR("  New layout: %s w/ %d copies",
+                     raid10_md_layout_to_format(mddev->layout),
+                     raid10_md_layout_to_copies(mddev->layout));
+               return -EINVAL;
+       }
+       if (le32_to_cpu(sb->stripe_sectors) != mddev->chunk_sectors) {
+               DMERR("Reshaping arrays not yet supported. (stripe sectors change)");
                return -EINVAL;
        }
 
        /* We can only change the number of devices in RAID1 right now */
        if ((rs->raid_type->level != 1) &&
            (le32_to_cpu(sb->num_devices) != mddev->raid_disks)) {
-               DMERR("Reshaping arrays not yet supported.");
+               DMERR("Reshaping arrays not yet supported. (device count change)");
                return -EINVAL;
        }
 
@@ -1329,7 +1407,8 @@ static void raid_status(struct dm_target *ti, status_type_t type,
                               raid10_md_layout_to_copies(rs->md.layout));
 
                if (rs->print_flags & DMPF_RAID10_FORMAT)
-                       DMEMIT(" raid10_format near");
+                       DMEMIT(" raid10_format %s",
+                              raid10_md_layout_to_format(rs->md.layout));
 
                DMEMIT(" %d", rs->md.raid_disks);
                for (i = 0; i < rs->md.raid_disks; i++) {
@@ -1418,6 +1497,10 @@ static struct target_type raid_target = {
 
 static int __init dm_raid_init(void)
 {
+       DMINFO("Loading target version %u.%u.%u",
+              raid_target.version[0],
+              raid_target.version[1],
+              raid_target.version[2]);
        return dm_register_target(&raid_target);
 }
 
index 3db3d1b271f7ef18650a227a8dd07dbc2b8fefbc..fcb878f88796c8ab884da058b36ea5f287fe2eab 100644 (file)
@@ -307,6 +307,10 @@ static void md_make_request(struct request_queue *q, struct bio *bio)
                bio_io_error(bio);
                return;
        }
+       if (mddev->ro == 1 && unlikely(rw == WRITE)) {
+               bio_endio(bio, bio_sectors(bio) == 0 ? 0 : -EROFS);
+               return;
+       }
        smp_rmb(); /* Ensure implications of  'active' are visible */
        rcu_read_lock();
        if (mddev->suspended) {
@@ -2994,6 +2998,9 @@ rdev_size_store(struct md_rdev *rdev, const char *buf, size_t len)
                } else if (!sectors)
                        sectors = (i_size_read(rdev->bdev->bd_inode) >> 9) -
                                rdev->data_offset;
+               if (!my_mddev->pers->resize)
+                       /* Cannot change size for RAID0 or Linear etc */
+                       return -EINVAL;
        }
        if (sectors < my_mddev->dev_sectors)
                return -EINVAL; /* component must fit device */
@@ -6525,7 +6532,17 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
                        mddev->ro = 0;
                        sysfs_notify_dirent_safe(mddev->sysfs_state);
                        set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
-                       md_wakeup_thread(mddev->thread);
+                       /* mddev_unlock will wake thread */
+                       /* If a device failed while we were read-only, we
+                        * need to make sure the metadata is updated now.
+                        */
+                       if (test_bit(MD_CHANGE_DEVS, &mddev->flags)) {
+                               mddev_unlock(mddev);
+                               wait_event(mddev->sb_wait,
+                                          !test_bit(MD_CHANGE_DEVS, &mddev->flags) &&
+                                          !test_bit(MD_CHANGE_PENDING, &mddev->flags));
+                               mddev_lock(mddev);
+                       }
                } else {
                        err = -EROFS;
                        goto abort_unlock;
index 24b359717a7e8917a4955e36651e6eb4009dc393..0505452de8d6ee2b3533c7930d62df544636b0c3 100644 (file)
@@ -175,7 +175,13 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf)
                        rdev1->new_raid_disk = j;
                }
 
-               if (j < 0 || j >= mddev->raid_disks) {
+               if (j < 0) {
+                       printk(KERN_ERR
+                              "md/raid0:%s: remove inactive devices before converting to RAID0\n",
+                              mdname(mddev));
+                       goto abort;
+               }
+               if (j >= mddev->raid_disks) {
                        printk(KERN_ERR "md/raid0:%s: bad disk number %d - "
                               "aborting!\n", mdname(mddev), j);
                        goto abort;
@@ -289,7 +295,7 @@ abort:
        kfree(conf->strip_zone);
        kfree(conf->devlist);
        kfree(conf);
-       *private_conf = NULL;
+       *private_conf = ERR_PTR(err);
        return err;
 }
 
@@ -411,7 +417,8 @@ static sector_t raid0_size(struct mddev *mddev, sector_t sectors, int raid_disks
                  "%s does not support generic reshape\n", __func__);
 
        rdev_for_each(rdev, mddev)
-               array_sectors += rdev->sectors;
+               array_sectors += (rdev->sectors &
+                                 ~(sector_t)(mddev->chunk_sectors-1));
 
        return array_sectors;
 }
index d5bddfc4010e4f77ea6d28a3f8fde5ff304bcc6e..fd86b372692db6d6bd5c6afdd498ae16be49f2c3 100644 (file)
@@ -967,6 +967,7 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule)
                bio_list_merge(&conf->pending_bio_list, &plug->pending);
                conf->pending_count += plug->pending_cnt;
                spin_unlock_irq(&conf->device_lock);
+               wake_up(&conf->wait_barrier);
                md_wakeup_thread(mddev->thread);
                kfree(plug);
                return;
@@ -1000,6 +1001,7 @@ static void make_request(struct mddev *mddev, struct bio * bio)
        const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA));
        const unsigned long do_discard = (bio->bi_rw
                                          & (REQ_DISCARD | REQ_SECURE));
+       const unsigned long do_same = (bio->bi_rw & REQ_WRITE_SAME);
        struct md_rdev *blocked_rdev;
        struct blk_plug_cb *cb;
        struct raid1_plug_cb *plug = NULL;
@@ -1301,7 +1303,8 @@ read_again:
                                   conf->mirrors[i].rdev->data_offset);
                mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
                mbio->bi_end_io = raid1_end_write_request;
-               mbio->bi_rw = WRITE | do_flush_fua | do_sync | do_discard;
+               mbio->bi_rw =
+                       WRITE | do_flush_fua | do_sync | do_discard | do_same;
                mbio->bi_private = r1_bio;
 
                atomic_inc(&r1_bio->remaining);
@@ -2818,6 +2821,9 @@ static int run(struct mddev *mddev)
        if (IS_ERR(conf))
                return PTR_ERR(conf);
 
+       if (mddev->queue)
+               blk_queue_max_write_same_sectors(mddev->queue,
+                                                mddev->chunk_sectors);
        rdev_for_each(rdev, mddev) {
                if (!mddev->gendisk)
                        continue;
index 64d48249c03bf09f73580f4465b59192faa005ab..77b562d18a90c4d27d9a5c43e82518e174ed84c7 100644 (file)
  *    near_copies (stored in low byte of layout)
  *    far_copies (stored in second byte of layout)
  *    far_offset (stored in bit 16 of layout )
+ *    use_far_sets (stored in bit 17 of layout )
  *
- * The data to be stored is divided into chunks using chunksize.
- * Each device is divided into far_copies sections.
- * In each section, chunks are laid out in a style similar to raid0, but
- * near_copies copies of each chunk is stored (each on a different drive).
- * The starting device for each section is offset near_copies from the starting
- * device of the previous section.
- * Thus they are (near_copies*far_copies) of each chunk, and each is on a different
- * drive.
- * near_copies and far_copies must be at least one, and their product is at most
- * raid_disks.
+ * The data to be stored is divided into chunks using chunksize.  Each device
+ * is divided into far_copies sections.   In each section, chunks are laid out
+ * in a style similar to raid0, but near_copies copies of each chunk is stored
+ * (each on a different drive).  The starting device for each section is offset
+ * near_copies from the starting device of the previous section.  Thus there
+ * are (near_copies * far_copies) of each chunk, and each is on a different
+ * drive.  near_copies and far_copies must be at least one, and their product
+ * is at most raid_disks.
  *
  * If far_offset is true, then the far_copies are handled a bit differently.
- * The copies are still in different stripes, but instead of be very far apart
- * on disk, there are adjacent stripes.
+ * The copies are still in different stripes, but instead of being very far
+ * apart on disk, there are adjacent stripes.
+ *
+ * The far and offset algorithms are handled slightly differently if
+ * 'use_far_sets' is true.  In this case, the array's devices are grouped into
+ * sets that are (near_copies * far_copies) in size.  The far copied stripes
+ * are still shifted by 'near_copies' devices, but this shifting stays confined
+ * to the set rather than the entire array.  This is done to improve the number
+ * of device combinations that can fail without causing the array to fail.
+ * Example 'far' algorithm w/o 'use_far_sets' (each letter represents a chunk
+ * on a device):
+ *    A B C D    A B C D E
+ *      ...         ...
+ *    D A B C    E A B C D
+ * Example 'far' algorithm w/ 'use_far_sets' enabled (sets illustrated w/ []'s):
+ *    [A B] [C D]    [A B] [C D E]
+ *    |...| |...|    |...| | ... |
+ *    [B A] [D C]    [B A] [E C D]
  */
 
 /*
@@ -535,6 +550,13 @@ static void __raid10_find_phys(struct geom *geo, struct r10bio *r10bio)
        sector_t stripe;
        int dev;
        int slot = 0;
+       int last_far_set_start, last_far_set_size;
+
+       last_far_set_start = (geo->raid_disks / geo->far_set_size) - 1;
+       last_far_set_start *= geo->far_set_size;
+
+       last_far_set_size = geo->far_set_size;
+       last_far_set_size += (geo->raid_disks % geo->far_set_size);
 
        /* now calculate first sector/dev */
        chunk = r10bio->sector >> geo->chunk_shift;
@@ -551,15 +573,25 @@ static void __raid10_find_phys(struct geom *geo, struct r10bio *r10bio)
        /* and calculate all the others */
        for (n = 0; n < geo->near_copies; n++) {
                int d = dev;
+               int set;
                sector_t s = sector;
-               r10bio->devs[slot].addr = sector;
                r10bio->devs[slot].devnum = d;
+               r10bio->devs[slot].addr = s;
                slot++;
 
                for (f = 1; f < geo->far_copies; f++) {
+                       set = d / geo->far_set_size;
                        d += geo->near_copies;
-                       if (d >= geo->raid_disks)
-                               d -= geo->raid_disks;
+
+                       if ((geo->raid_disks % geo->far_set_size) &&
+                           (d > last_far_set_start)) {
+                               d -= last_far_set_start;
+                               d %= last_far_set_size;
+                               d += last_far_set_start;
+                       } else {
+                               d %= geo->far_set_size;
+                               d += geo->far_set_size * set;
+                       }
                        s += geo->stride;
                        r10bio->devs[slot].devnum = d;
                        r10bio->devs[slot].addr = s;
@@ -595,6 +627,20 @@ static sector_t raid10_find_virt(struct r10conf *conf, sector_t sector, int dev)
         * or recovery, so reshape isn't happening
         */
        struct geom *geo = &conf->geo;
+       int far_set_start = (dev / geo->far_set_size) * geo->far_set_size;
+       int far_set_size = geo->far_set_size;
+       int last_far_set_start;
+
+       if (geo->raid_disks % geo->far_set_size) {
+               last_far_set_start = (geo->raid_disks / geo->far_set_size) - 1;
+               last_far_set_start *= geo->far_set_size;
+
+               if (dev >= last_far_set_start) {
+                       far_set_size = geo->far_set_size;
+                       far_set_size += (geo->raid_disks % geo->far_set_size);
+                       far_set_start = last_far_set_start;
+               }
+       }
 
        offset = sector & geo->chunk_mask;
        if (geo->far_offset) {
@@ -602,13 +648,13 @@ static sector_t raid10_find_virt(struct r10conf *conf, sector_t sector, int dev)
                chunk = sector >> geo->chunk_shift;
                fc = sector_div(chunk, geo->far_copies);
                dev -= fc * geo->near_copies;
-               if (dev < 0)
-                       dev += geo->raid_disks;
+               if (dev < far_set_start)
+                       dev += far_set_size;
        } else {
                while (sector >= geo->stride) {
                        sector -= geo->stride;
-                       if (dev < geo->near_copies)
-                               dev += geo->raid_disks - geo->near_copies;
+                       if (dev < (geo->near_copies + far_set_start))
+                               dev += far_set_size - geo->near_copies;
                        else
                                dev -= geo->near_copies;
                }
@@ -1073,6 +1119,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
                bio_list_merge(&conf->pending_bio_list, &plug->pending);
                conf->pending_count += plug->pending_cnt;
                spin_unlock_irq(&conf->device_lock);
+               wake_up(&conf->wait_barrier);
                md_wakeup_thread(mddev->thread);
                kfree(plug);
                return;
@@ -1105,6 +1152,7 @@ static void make_request(struct mddev *mddev, struct bio * bio)
        const unsigned long do_fua = (bio->bi_rw & REQ_FUA);
        const unsigned long do_discard = (bio->bi_rw
                                          & (REQ_DISCARD | REQ_SECURE));
+       const unsigned long do_same = (bio->bi_rw & REQ_WRITE_SAME);
        unsigned long flags;
        struct md_rdev *blocked_rdev;
        struct blk_plug_cb *cb;
@@ -1460,7 +1508,8 @@ retry_write:
                                                              rdev));
                        mbio->bi_bdev = rdev->bdev;
                        mbio->bi_end_io = raid10_end_write_request;
-                       mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
+                       mbio->bi_rw =
+                               WRITE | do_sync | do_fua | do_discard | do_same;
                        mbio->bi_private = r10_bio;
 
                        atomic_inc(&r10_bio->remaining);
@@ -1502,7 +1551,8 @@ retry_write:
                                                   r10_bio, rdev));
                        mbio->bi_bdev = rdev->bdev;
                        mbio->bi_end_io = raid10_end_write_request;
-                       mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
+                       mbio->bi_rw =
+                               WRITE | do_sync | do_fua | do_discard | do_same;
                        mbio->bi_private = r10_bio;
 
                        atomic_inc(&r10_bio->remaining);
@@ -3436,7 +3486,7 @@ static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new)
                disks = mddev->raid_disks + mddev->delta_disks;
                break;
        }
-       if (layout >> 17)
+       if (layout >> 18)
                return -1;
        if (chunk < (PAGE_SIZE >> 9) ||
            !is_power_of_2(chunk))
@@ -3448,6 +3498,7 @@ static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new)
        geo->near_copies = nc;
        geo->far_copies = fc;
        geo->far_offset = fo;
+       geo->far_set_size = (layout & (1<<17)) ? disks / fc : disks;
        geo->chunk_mask = chunk - 1;
        geo->chunk_shift = ffz(~chunk);
        return nc*fc;
@@ -3569,6 +3620,8 @@ static int run(struct mddev *mddev)
        if (mddev->queue) {
                blk_queue_max_discard_sectors(mddev->queue,
                                              mddev->chunk_sectors);
+               blk_queue_max_write_same_sectors(mddev->queue,
+                                                mddev->chunk_sectors);
                blk_queue_io_min(mddev->queue, chunk_size);
                if (conf->geo.raid_disks % conf->geo.near_copies)
                        blk_queue_io_opt(mddev->queue, chunk_size * conf->geo.raid_disks);
index 1054cf602345250f059ef81fae8bf9ef330cccd1..157d69e83ff401972f395db9bb281faa8df75a65 100644 (file)
@@ -33,6 +33,11 @@ struct r10conf {
                                               * far_offset, in which case it is
                                               * 1 stripe.
                                               */
+               int             far_set_size; /* The number of devices in a set,
+                                              * where a 'set' are devices that
+                                              * contain far/offset copies of
+                                              * each other.
+                                              */
                int             chunk_shift; /* shift from chunks to sectors */
                sector_t        chunk_mask;
        } prev, geo;
index 5af2d270908178b2628a3db42c508417fc4f5579..3ee2912889e7110274acabc28df3c6664abcb0f7 100644 (file)
@@ -1403,7 +1403,7 @@ static void ops_run_check_pq(struct stripe_head *sh, struct raid5_percpu *percpu
                           &sh->ops.zero_sum_result, percpu->spare_page, &submit);
 }
 
-static void __raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
+static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
 {
        int overlap_clear = 0, i, disks = sh->disks;
        struct dma_async_tx_descriptor *tx = NULL;
@@ -1468,36 +1468,6 @@ static void __raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
        put_cpu();
 }
 
-#ifdef CONFIG_MULTICORE_RAID456
-static void async_run_ops(void *param, async_cookie_t cookie)
-{
-       struct stripe_head *sh = param;
-       unsigned long ops_request = sh->ops.request;
-
-       clear_bit_unlock(STRIPE_OPS_REQ_PENDING, &sh->state);
-       wake_up(&sh->ops.wait_for_ops);
-
-       __raid_run_ops(sh, ops_request);
-       release_stripe(sh);
-}
-
-static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
-{
-       /* since handle_stripe can be called outside of raid5d context
-        * we need to ensure sh->ops.request is de-staged before another
-        * request arrives
-        */
-       wait_event(sh->ops.wait_for_ops,
-                  !test_and_set_bit_lock(STRIPE_OPS_REQ_PENDING, &sh->state));
-       sh->ops.request = ops_request;
-
-       atomic_inc(&sh->count);
-       async_schedule(async_run_ops, sh);
-}
-#else
-#define raid_run_ops __raid_run_ops
-#endif
-
 static int grow_one_stripe(struct r5conf *conf)
 {
        struct stripe_head *sh;
@@ -1506,9 +1476,6 @@ static int grow_one_stripe(struct r5conf *conf)
                return 0;
 
        sh->raid_conf = conf;
-       #ifdef CONFIG_MULTICORE_RAID456
-       init_waitqueue_head(&sh->ops.wait_for_ops);
-       #endif
 
        spin_lock_init(&sh->stripe_lock);
 
@@ -1627,9 +1594,6 @@ static int resize_stripes(struct r5conf *conf, int newsize)
                        break;
 
                nsh->raid_conf = conf;
-               #ifdef CONFIG_MULTICORE_RAID456
-               init_waitqueue_head(&nsh->ops.wait_for_ops);
-               #endif
                spin_lock_init(&nsh->stripe_lock);
 
                list_add(&nsh->lru, &newstripes);
index 6673e578b3e9a00bce4a949cc19495359c66ebda..ce5b75616b453dd49c8fce21cf699fb465b6f4ad 100644 (file)
@@ -110,6 +110,7 @@ static struct file_system_type ibmasmfs_type = {
        .mount          = ibmasmfs_mount,
        .kill_sb        = kill_litter_super,
 };
+MODULE_ALIAS_FS("ibmasmfs");
 
 static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent)
 {
index 82c06165d3d27351f3cebf9966b513b6669e96bf..92ab30ab00dcab1d0bc6405a94bbe3aeffcfb128 100644 (file)
@@ -1238,6 +1238,7 @@ static struct file_system_type mtd_inodefs_type = {
        .mount = mtd_inodefs_mount,
        .kill_sb = kill_anon_super,
 };
+MODULE_ALIAS_FS("mtd_inodefs");
 
 static int __init init_mtdchar(void)
 {
index 11d01d67b3f510d7e5d159784aee36f6c612cb12..7bd068a6056a3ef3c66bde04f108d1bbf5dcd926 100644 (file)
@@ -1629,7 +1629,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
        /* If this is the first slave, then we need to set the master's hardware
         * address to be the same as the slave's. */
-       if (bond->dev_addr_from_first)
+       if (bond->slave_cnt == 0 && bond->dev_addr_from_first)
                bond_set_dev_addr(bond->dev, slave_dev);
 
        new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL);
index 639049d7e92de5bda8cd901a711f7cc4626d1302..da5f4397f87c2744e13d4cb3bf0c99fb85d4666a 100644 (file)
@@ -301,12 +301,16 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring,
                        bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n",
                                  ring->start);
                } else {
+                       /* Omit CRC. */
+                       len -= ETH_FCS_LEN;
+
                        new_skb = netdev_alloc_skb_ip_align(bgmac->net_dev, len);
                        if (new_skb) {
                                skb_put(new_skb, len);
                                skb_copy_from_linear_data_offset(skb, BGMAC_RX_FRAME_OFFSET,
                                                                 new_skb->data,
                                                                 len);
+                               skb_checksum_none_assert(skb);
                                new_skb->protocol =
                                        eth_type_trans(new_skb, bgmac->net_dev);
                                netif_receive_skb(new_skb);
index ecac04a3687c6b2967ccc3e8e1ab78bf2107e4e9..a923bc4d5a1f5540704423215a8f772bd3a8831a 100644 (file)
@@ -3142,7 +3142,7 @@ static inline __le16 bnx2x_csum_fix(unsigned char *t_header, u16 csum, s8 fix)
                tsum = ~csum_fold(csum_add((__force __wsum) csum,
                                  csum_partial(t_header, -fix, 0)));
 
-       return bswab16(csum);
+       return bswab16(tsum);
 }
 
 static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb)
index 9a674b14b403dc605bfb10c448ea8a175a2614ae..edfa67adf2f975d6b5d6dc382e4cf6d5617a2b3b 100644 (file)
@@ -281,6 +281,8 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                        cmd->lp_advertising |= ADVERTISED_2500baseX_Full;
                if (status & LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE)
                        cmd->lp_advertising |= ADVERTISED_10000baseT_Full;
+               if (status & LINK_STATUS_LINK_PARTNER_20GXFD_CAPABLE)
+                       cmd->lp_advertising |= ADVERTISED_20000baseKR2_Full;
        }
 
        cmd->maxtxpkt = 0;
@@ -463,6 +465,10 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                                                ADVERTISED_10000baseKR_Full))
                                bp->link_params.speed_cap_mask[cfg_idx] |=
                                        PORT_HW_CFG_SPEED_CAPABILITY_D0_10G;
+
+                       if (cmd->advertising & ADVERTISED_20000baseKR2_Full)
+                               bp->link_params.speed_cap_mask[cfg_idx] |=
+                                       PORT_HW_CFG_SPEED_CAPABILITY_D0_20G;
                }
        } else { /* forced speed */
                /* advertise the requested speed and duplex if supported */
index 1663e0b6b5a01f0baee17e6584dc6b65cf07344c..31c5787970dbc342ad2ea4fc959d81baa187d356 100644 (file)
@@ -10422,6 +10422,28 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
                                         MDIO_PMA_DEVAD,
                                         MDIO_PMA_REG_8481_LED1_MASK,
                                         0x0);
+                       if (phy->type ==
+                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) {
+                               /* Disable MI_INT interrupt before setting LED4
+                                * source to constant off.
+                                */
+                               if (REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
+                                          params->port*4) &
+                                   NIG_MASK_MI_INT) {
+                                       params->link_flags |=
+                                       LINK_FLAGS_INT_DISABLED;
+
+                                       bnx2x_bits_dis(
+                                               bp,
+                                               NIG_REG_MASK_INTERRUPT_PORT0 +
+                                               params->port*4,
+                                               NIG_MASK_MI_INT);
+                               }
+                               bnx2x_cl45_write(bp, phy,
+                                                MDIO_PMA_DEVAD,
+                                                MDIO_PMA_REG_8481_SIGNAL_MASK,
+                                                0x0);
+                       }
                }
                break;
        case LED_MODE_ON:
@@ -10468,6 +10490,28 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
                                         MDIO_PMA_DEVAD,
                                         MDIO_PMA_REG_8481_LED1_MASK,
                                         0x20);
+                       if (phy->type ==
+                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) {
+                               /* Disable MI_INT interrupt before setting LED4
+                                * source to constant on.
+                                */
+                               if (REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
+                                          params->port*4) &
+                                   NIG_MASK_MI_INT) {
+                                       params->link_flags |=
+                                       LINK_FLAGS_INT_DISABLED;
+
+                                       bnx2x_bits_dis(
+                                               bp,
+                                               NIG_REG_MASK_INTERRUPT_PORT0 +
+                                               params->port*4,
+                                               NIG_MASK_MI_INT);
+                               }
+                               bnx2x_cl45_write(bp, phy,
+                                                MDIO_PMA_DEVAD,
+                                                MDIO_PMA_REG_8481_SIGNAL_MASK,
+                                                0x20);
+                       }
                }
                break;
 
@@ -10532,6 +10576,22 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
                                         MDIO_PMA_DEVAD,
                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
                                         val);
+                       if (phy->type ==
+                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) {
+                               /* Restore LED4 source to external link,
+                                * and re-enable interrupts.
+                                */
+                               bnx2x_cl45_write(bp, phy,
+                                                MDIO_PMA_DEVAD,
+                                                MDIO_PMA_REG_8481_SIGNAL_MASK,
+                                                0x40);
+                               if (params->link_flags &
+                                   LINK_FLAGS_INT_DISABLED) {
+                                       bnx2x_link_int_enable(params);
+                                       params->link_flags &=
+                                               ~LINK_FLAGS_INT_DISABLED;
+                               }
+                       }
                }
                break;
        }
@@ -11791,6 +11851,8 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
                        phy->media_type = ETH_PHY_KR;
                        phy->flags |= FLAGS_WC_DUAL_MODE;
                        phy->supported &= (SUPPORTED_20000baseKR2_Full |
+                                          SUPPORTED_10000baseT_Full |
+                                          SUPPORTED_1000baseT_Full |
                                           SUPPORTED_Autoneg |
                                           SUPPORTED_FIBRE |
                                           SUPPORTED_Pause |
@@ -13437,7 +13499,7 @@ void bnx2x_period_func(struct link_params *params, struct link_vars *vars)
                struct bnx2x_phy *phy = &params->phy[INT_PHY];
                bnx2x_set_aer_mmd(params, phy);
                if ((phy->supported & SUPPORTED_20000baseKR2_Full) &&
-                   (phy->speed_cap_mask & SPEED_20000))
+                   (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G))
                        bnx2x_check_kr2_wa(params, vars, phy);
                bnx2x_check_over_curr(params, vars);
                if (vars->rx_tx_asic_rst)
index d25c7d79787a1bacdfb0dc526bc9814fdfab8d2d..be5c195d03dd01addf2706c81896d1872b94d96c 100644 (file)
@@ -307,7 +307,8 @@ struct link_params {
        struct bnx2x *bp;
        u16 req_fc_auto_adv; /* Should be set to TX / BOTH when
                                req_flow_ctrl is set to AUTO */
-       u16 rsrv1;
+       u16 link_flags;
+#define LINK_FLAGS_INT_DISABLED                (1<<0)
        u32 lfa_base;
 };
 
index fccc3bf2141d7a757f97ac307a9f3d5678a4b57c..069a155d16ed40c57da5e70a8088eef767d0690b 100644 (file)
@@ -246,14 +246,13 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        struct bufdesc *bdp;
        void *bufaddr;
        unsigned short  status;
-       unsigned long flags;
+       unsigned int index;
 
        if (!fep->link) {
                /* Link is down or autonegotiation is in progress. */
                return NETDEV_TX_BUSY;
        }
 
-       spin_lock_irqsave(&fep->hw_lock, flags);
        /* Fill in a Tx ring entry */
        bdp = fep->cur_tx;
 
@@ -264,7 +263,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                 * This should not happen, since ndev->tbusy should be set.
                 */
                printk("%s: tx queue full!.\n", ndev->name);
-               spin_unlock_irqrestore(&fep->hw_lock, flags);
                return NETDEV_TX_BUSY;
        }
 
@@ -280,13 +278,13 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
         * 4-byte boundaries. Use bounce buffers to copy data
         * and get it aligned. Ugh.
         */
+       if (fep->bufdesc_ex)
+               index = (struct bufdesc_ex *)bdp -
+                       (struct bufdesc_ex *)fep->tx_bd_base;
+       else
+               index = bdp - fep->tx_bd_base;
+
        if (((unsigned long) bufaddr) & FEC_ALIGNMENT) {
-               unsigned int index;
-               if (fep->bufdesc_ex)
-                       index = (struct bufdesc_ex *)bdp -
-                               (struct bufdesc_ex *)fep->tx_bd_base;
-               else
-                       index = bdp - fep->tx_bd_base;
                memcpy(fep->tx_bounce[index], skb->data, skb->len);
                bufaddr = fep->tx_bounce[index];
        }
@@ -300,10 +298,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                swap_buffer(bufaddr, skb->len);
 
        /* Save skb pointer */
-       fep->tx_skbuff[fep->skb_cur] = skb;
-
-       ndev->stats.tx_bytes += skb->len;
-       fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK;
+       fep->tx_skbuff[index] = skb;
 
        /* Push the data cache so the CPM does not get stale memory
         * data.
@@ -331,26 +326,22 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                        ebdp->cbd_esc = BD_ENET_TX_INT;
                }
        }
-       /* Trigger transmission start */
-       writel(0, fep->hwp + FEC_X_DES_ACTIVE);
-
        /* If this was the last BD in the ring, start at the beginning again. */
        if (status & BD_ENET_TX_WRAP)
                bdp = fep->tx_bd_base;
        else
                bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
 
-       if (bdp == fep->dirty_tx) {
-               fep->tx_full = 1;
+       fep->cur_tx = bdp;
+
+       if (fep->cur_tx == fep->dirty_tx)
                netif_stop_queue(ndev);
-       }
 
-       fep->cur_tx = bdp;
+       /* Trigger transmission start */
+       writel(0, fep->hwp + FEC_X_DES_ACTIVE);
 
        skb_tx_timestamp(skb);
 
-       spin_unlock_irqrestore(&fep->hw_lock, flags);
-
        return NETDEV_TX_OK;
 }
 
@@ -406,11 +397,8 @@ fec_restart(struct net_device *ndev, int duplex)
                writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc)
                        * RX_RING_SIZE, fep->hwp + FEC_X_DES_START);
 
-       fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
        fep->cur_rx = fep->rx_bd_base;
 
-       /* Reset SKB transmit buffers. */
-       fep->skb_cur = fep->skb_dirty = 0;
        for (i = 0; i <= TX_RING_MOD_MASK; i++) {
                if (fep->tx_skbuff[i]) {
                        dev_kfree_skb_any(fep->tx_skbuff[i]);
@@ -573,20 +561,35 @@ fec_enet_tx(struct net_device *ndev)
        struct bufdesc *bdp;
        unsigned short status;
        struct  sk_buff *skb;
+       int     index = 0;
 
        fep = netdev_priv(ndev);
-       spin_lock(&fep->hw_lock);
        bdp = fep->dirty_tx;
 
+       /* get next bdp of dirty_tx */
+       if (bdp->cbd_sc & BD_ENET_TX_WRAP)
+               bdp = fep->tx_bd_base;
+       else
+               bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex);
+
        while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
-               if (bdp == fep->cur_tx && fep->tx_full == 0)
+
+               /* current queue is empty */
+               if (bdp == fep->cur_tx)
                        break;
 
+               if (fep->bufdesc_ex)
+                       index = (struct bufdesc_ex *)bdp -
+                               (struct bufdesc_ex *)fep->tx_bd_base;
+               else
+                       index = bdp - fep->tx_bd_base;
+
                dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
                                FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
                bdp->cbd_bufaddr = 0;
 
-               skb = fep->tx_skbuff[fep->skb_dirty];
+               skb = fep->tx_skbuff[index];
+
                /* Check for errors. */
                if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC |
                                   BD_ENET_TX_RL | BD_ENET_TX_UN |
@@ -631,8 +634,9 @@ fec_enet_tx(struct net_device *ndev)
 
                /* Free the sk buffer associated with this last transmit */
                dev_kfree_skb_any(skb);
-               fep->tx_skbuff[fep->skb_dirty] = NULL;
-               fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK;
+               fep->tx_skbuff[index] = NULL;
+
+               fep->dirty_tx = bdp;
 
                /* Update pointer to next buffer descriptor to be transmitted */
                if (status & BD_ENET_TX_WRAP)
@@ -642,14 +646,12 @@ fec_enet_tx(struct net_device *ndev)
 
                /* Since we have freed up a buffer, the ring is no longer full
                 */
-               if (fep->tx_full) {
-                       fep->tx_full = 0;
+               if (fep->dirty_tx != fep->cur_tx) {
                        if (netif_queue_stopped(ndev))
                                netif_wake_queue(ndev);
                }
        }
-       fep->dirty_tx = bdp;
-       spin_unlock(&fep->hw_lock);
+       return;
 }
 
 
@@ -816,7 +818,7 @@ fec_enet_interrupt(int irq, void *dev_id)
                int_events = readl(fep->hwp + FEC_IEVENT);
                writel(int_events, fep->hwp + FEC_IEVENT);
 
-               if (int_events & FEC_ENET_RXF) {
+               if (int_events & (FEC_ENET_RXF | FEC_ENET_TXF)) {
                        ret = IRQ_HANDLED;
 
                        /* Disable the RX interrupt */
@@ -827,15 +829,6 @@ fec_enet_interrupt(int irq, void *dev_id)
                        }
                }
 
-               /* Transmit OK, or non-fatal error. Update the buffer
-                * descriptors. FEC handles all errors, we just discover
-                * them as part of the transmit process.
-                */
-               if (int_events & FEC_ENET_TXF) {
-                       ret = IRQ_HANDLED;
-                       fec_enet_tx(ndev);
-               }
-
                if (int_events & FEC_ENET_MII) {
                        ret = IRQ_HANDLED;
                        complete(&fep->mdio_done);
@@ -851,6 +844,8 @@ static int fec_enet_rx_napi(struct napi_struct *napi, int budget)
        int pkts = fec_enet_rx(ndev, budget);
        struct fec_enet_private *fep = netdev_priv(ndev);
 
+       fec_enet_tx(ndev);
+
        if (pkts < budget) {
                napi_complete(napi);
                writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
@@ -1646,6 +1641,7 @@ static int fec_enet_init(struct net_device *ndev)
 
        /* ...and the same for transmit */
        bdp = fep->tx_bd_base;
+       fep->cur_tx = bdp;
        for (i = 0; i < TX_RING_SIZE; i++) {
 
                /* Initialize the BD for every fragment in the page. */
@@ -1657,6 +1653,7 @@ static int fec_enet_init(struct net_device *ndev)
        /* Set the last buffer to wrap */
        bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
        bdp->cbd_sc |= BD_SC_WRAP;
+       fep->dirty_tx = bdp;
 
        fec_restart(ndev, 0);
 
index 01579b8e37c4f979ea668b28538be4e22e255baa..f5390071efd0622832686d753f501c49039906c2 100644 (file)
@@ -97,6 +97,13 @@ struct bufdesc {
        unsigned short cbd_sc;  /* Control and status info */
        unsigned long cbd_bufaddr;      /* Buffer address */
 };
+#else
+struct bufdesc {
+       unsigned short  cbd_sc;                 /* Control and status info */
+       unsigned short  cbd_datlen;             /* Data length */
+       unsigned long   cbd_bufaddr;            /* Buffer address */
+};
+#endif
 
 struct bufdesc_ex {
        struct bufdesc desc;
@@ -107,14 +114,6 @@ struct bufdesc_ex {
        unsigned short res0[4];
 };
 
-#else
-struct bufdesc {
-       unsigned short  cbd_sc;                 /* Control and status info */
-       unsigned short  cbd_datlen;             /* Data length */
-       unsigned long   cbd_bufaddr;            /* Buffer address */
-};
-#endif
-
 /*
  *     The following definitions courtesy of commproc.h, which where
  *     Copyright (c) 1997 Dan Malek (dmalek@jlc.net).
@@ -214,8 +213,6 @@ struct fec_enet_private {
        unsigned char *tx_bounce[TX_RING_SIZE];
        struct  sk_buff *tx_skbuff[TX_RING_SIZE];
        struct  sk_buff *rx_skbuff[RX_RING_SIZE];
-       ushort  skb_cur;
-       ushort  skb_dirty;
 
        /* CPM dual port RAM relative addresses */
        dma_addr_t      bd_dma;
@@ -227,7 +224,6 @@ struct fec_enet_private {
        /* The ring entries to be free()ed */
        struct bufdesc  *dirty_tx;
 
-       uint    tx_full;
        /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
        spinlock_t hw_lock;
 
index 8900398ba103929135278c1046e50126d627eabd..28fb50a1e9c350851b3844592bf85adea877f604 100644 (file)
@@ -4765,8 +4765,10 @@ static void rtl_hw_start_8168bb(struct rtl8169_private *tp)
 
        RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
 
-       rtl_tx_performance_tweak(pdev,
-               (0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN);
+       if (tp->dev->mtu <= ETH_DATA_LEN) {
+               rtl_tx_performance_tweak(pdev, (0x5 << MAX_READ_REQUEST_SHIFT) |
+                                        PCI_EXP_DEVCTL_NOSNOOP_EN);
+       }
 }
 
 static void rtl_hw_start_8168bef(struct rtl8169_private *tp)
@@ -4789,7 +4791,8 @@ static void __rtl_hw_start_8168cp(struct rtl8169_private *tp)
 
        RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
 
-       rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+       if (tp->dev->mtu <= ETH_DATA_LEN)
+               rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
 
        rtl_disable_clock_request(pdev);
 
@@ -4822,7 +4825,8 @@ static void rtl_hw_start_8168cp_2(struct rtl8169_private *tp)
 
        RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
 
-       rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+       if (tp->dev->mtu <= ETH_DATA_LEN)
+               rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
 
        RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
 }
@@ -4841,7 +4845,8 @@ static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp)
 
        RTL_W8(MaxTxPacketSize, TxPacketMax);
 
-       rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+       if (tp->dev->mtu <= ETH_DATA_LEN)
+               rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
 
        RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
 }
@@ -4901,7 +4906,8 @@ static void rtl_hw_start_8168d(struct rtl8169_private *tp)
 
        RTL_W8(MaxTxPacketSize, TxPacketMax);
 
-       rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+       if (tp->dev->mtu <= ETH_DATA_LEN)
+               rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
 
        RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
 }
@@ -4913,7 +4919,8 @@ static void rtl_hw_start_8168dp(struct rtl8169_private *tp)
 
        rtl_csi_access_enable_1(tp);
 
-       rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+       if (tp->dev->mtu <= ETH_DATA_LEN)
+               rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
 
        RTL_W8(MaxTxPacketSize, TxPacketMax);
 
@@ -4972,7 +4979,8 @@ static void rtl_hw_start_8168e_1(struct rtl8169_private *tp)
 
        rtl_ephy_init(tp, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1));
 
-       rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+       if (tp->dev->mtu <= ETH_DATA_LEN)
+               rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
 
        RTL_W8(MaxTxPacketSize, TxPacketMax);
 
@@ -4998,7 +5006,8 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)
 
        rtl_ephy_init(tp, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2));
 
-       rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+       if (tp->dev->mtu <= ETH_DATA_LEN)
+               rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
 
        rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
        rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
index bf57b3cb16abdbc1e89e8aaa83c99a9c47888552..0bc00991d31010cf1ec4efd95ec95afba8aa5d53 100644 (file)
@@ -779,6 +779,7 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
                                                tx_queue->txd.entries);
        }
 
+       efx_device_detach_sync(efx);
        efx_stop_all(efx);
        efx_stop_interrupts(efx, true);
 
@@ -832,6 +833,7 @@ out:
 
        efx_start_interrupts(efx, true);
        efx_start_all(efx);
+       netif_device_attach(efx->net_dev);
        return rc;
 
 rollback:
@@ -1641,8 +1643,12 @@ static void efx_stop_all(struct efx_nic *efx)
        /* Flush efx_mac_work(), refill_workqueue, monitor_work */
        efx_flush_all(efx);
 
-       /* Stop the kernel transmit interface late, so the watchdog
-        * timer isn't ticking over the flush */
+       /* Stop the kernel transmit interface.  This is only valid if
+        * the device is stopped or detached; otherwise the watchdog
+        * may fire immediately.
+        */
+       WARN_ON(netif_running(efx->net_dev) &&
+               netif_device_present(efx->net_dev));
        netif_tx_disable(efx->net_dev);
 
        efx_stop_datapath(efx);
@@ -1963,16 +1969,18 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu)
        if (new_mtu > EFX_MAX_MTU)
                return -EINVAL;
 
-       efx_stop_all(efx);
-
        netif_dbg(efx, drv, efx->net_dev, "changing MTU to %d\n", new_mtu);
 
+       efx_device_detach_sync(efx);
+       efx_stop_all(efx);
+
        mutex_lock(&efx->mac_lock);
        net_dev->mtu = new_mtu;
        efx->type->reconfigure_mac(efx);
        mutex_unlock(&efx->mac_lock);
 
        efx_start_all(efx);
+       netif_device_attach(efx->net_dev);
        return 0;
 }
 
index 2d756c1d71425823100f572065e224a59ca16813..0a90abd2421b62540d7e2fb2888caa0a4a3abf3a 100644 (file)
@@ -210,6 +210,7 @@ struct efx_tx_queue {
  *     Will be %NULL if the buffer slot is currently free.
  * @page: The associated page buffer. Valif iff @flags & %EFX_RX_BUF_PAGE.
  *     Will be %NULL if the buffer slot is currently free.
+ * @page_offset: Offset within page. Valid iff @flags & %EFX_RX_BUF_PAGE.
  * @len: Buffer length, in bytes.
  * @flags: Flags for buffer and packet state.
  */
@@ -219,7 +220,8 @@ struct efx_rx_buffer {
                struct sk_buff *skb;
                struct page *page;
        } u;
-       unsigned int len;
+       u16 page_offset;
+       u16 len;
        u16 flags;
 };
 #define EFX_RX_BUF_PAGE                0x0001
index d780a0d096b4c5b0b87036c6404089309592d43b..879ff5849bbd181e58e9d5be8e75f28d89f2ddad 100644 (file)
@@ -90,11 +90,7 @@ static unsigned int rx_refill_threshold;
 static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx,
                                             struct efx_rx_buffer *buf)
 {
-       /* Offset is always within one page, so we don't need to consider
-        * the page order.
-        */
-       return ((unsigned int) buf->dma_addr & (PAGE_SIZE - 1)) +
-               efx->type->rx_buffer_hash_size;
+       return buf->page_offset + efx->type->rx_buffer_hash_size;
 }
 static inline unsigned int efx_rx_buf_size(struct efx_nic *efx)
 {
@@ -187,6 +183,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
        struct efx_nic *efx = rx_queue->efx;
        struct efx_rx_buffer *rx_buf;
        struct page *page;
+       unsigned int page_offset;
        struct efx_rx_page_state *state;
        dma_addr_t dma_addr;
        unsigned index, count;
@@ -211,12 +208,14 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
                state->dma_addr = dma_addr;
 
                dma_addr += sizeof(struct efx_rx_page_state);
+               page_offset = sizeof(struct efx_rx_page_state);
 
        split:
                index = rx_queue->added_count & rx_queue->ptr_mask;
                rx_buf = efx_rx_buffer(rx_queue, index);
                rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN;
                rx_buf->u.page = page;
+               rx_buf->page_offset = page_offset;
                rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN;
                rx_buf->flags = EFX_RX_BUF_PAGE;
                ++rx_queue->added_count;
@@ -227,6 +226,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
                        /* Use the second half of the page */
                        get_page(page);
                        dma_addr += (PAGE_SIZE >> 1);
+                       page_offset += (PAGE_SIZE >> 1);
                        ++count;
                        goto split;
                }
@@ -236,7 +236,8 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
 }
 
 static void efx_unmap_rx_buffer(struct efx_nic *efx,
-                               struct efx_rx_buffer *rx_buf)
+                               struct efx_rx_buffer *rx_buf,
+                               unsigned int used_len)
 {
        if ((rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.page) {
                struct efx_rx_page_state *state;
@@ -247,6 +248,10 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx,
                                       state->dma_addr,
                                       efx_rx_buf_size(efx),
                                       DMA_FROM_DEVICE);
+               } else if (used_len) {
+                       dma_sync_single_for_cpu(&efx->pci_dev->dev,
+                                               rx_buf->dma_addr, used_len,
+                                               DMA_FROM_DEVICE);
                }
        } else if (!(rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.skb) {
                dma_unmap_single(&efx->pci_dev->dev, rx_buf->dma_addr,
@@ -269,7 +274,7 @@ static void efx_free_rx_buffer(struct efx_nic *efx,
 static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue,
                               struct efx_rx_buffer *rx_buf)
 {
-       efx_unmap_rx_buffer(rx_queue->efx, rx_buf);
+       efx_unmap_rx_buffer(rx_queue->efx, rx_buf, 0);
        efx_free_rx_buffer(rx_queue->efx, rx_buf);
 }
 
@@ -535,10 +540,10 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
                goto out;
        }
 
-       /* Release card resources - assumes all RX buffers consumed in-order
-        * per RX queue
+       /* Release and/or sync DMA mapping - assumes all RX buffers
+        * consumed in-order per RX queue
         */
-       efx_unmap_rx_buffer(efx, rx_buf);
+       efx_unmap_rx_buffer(efx, rx_buf, len);
 
        /* Prefetch nice and early so data will (hopefully) be in cache by
         * the time we look at it.
index 7e93df6585e7fd7cce9db2ba3f9ed3187f2b699c..01ffbc48698298d1678b478599c1b46f2ee55ef9 100644 (file)
@@ -731,7 +731,7 @@ static inline void cpsw_add_default_vlan(struct cpsw_priv *priv)
 
        writel(vlan, &priv->host_port_regs->port_vlan);
 
-       for (i = 0; i < 2; i++)
+       for (i = 0; i < priv->data.slaves; i++)
                slave_write(priv->slaves + i, vlan, reg);
 
        cpsw_ale_add_vlan(priv->ale, vlan, ALE_ALL_PORTS << port,
index 29934446436ac0e6dd7df8d80797a3b4351d77ac..abf7b6153d00b8527b997e4e947b48a63449af4b 100644 (file)
@@ -257,8 +257,7 @@ static struct phy_driver ksphy_driver[] = {
        .phy_id         = PHY_ID_KSZ9021,
        .phy_id_mask    = 0x000ffffe,
        .name           = "Micrel KSZ9021 Gigabit PHY",
-       .features       = (PHY_GBIT_FEATURES | SUPPORTED_Pause
-                               | SUPPORTED_Asym_Pause),
+       .features       = (PHY_GBIT_FEATURES | SUPPORTED_Pause),
        .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
        .config_init    = kszphy_config_init,
        .config_aneg    = genphy_config_aneg,
index 9930f999956172fa20ad5e5a34d3db5297fe9c12..3657b4a29124b57bc335417a1389f792aaf2ce79 100644 (file)
@@ -44,13 +44,13 @@ MODULE_LICENSE("GPL");
 
 void phy_device_free(struct phy_device *phydev)
 {
-       kfree(phydev);
+       put_device(&phydev->dev);
 }
 EXPORT_SYMBOL(phy_device_free);
 
 static void phy_device_release(struct device *dev)
 {
-       phy_device_free(to_phy_device(dev));
+       kfree(to_phy_device(dev));
 }
 
 static struct phy_driver genphy_driver;
@@ -201,6 +201,8 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,
           there's no driver _already_ loaded. */
        request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT, MDIO_ID_ARGS(phy_id));
 
+       device_initialize(&dev->dev);
+
        return dev;
 }
 EXPORT_SYMBOL(phy_device_create);
@@ -363,9 +365,9 @@ int phy_device_register(struct phy_device *phydev)
        /* Run all of the fixups for this PHY */
        phy_scan_fixups(phydev);
 
-       err = device_register(&phydev->dev);
+       err = device_add(&phydev->dev);
        if (err) {
-               pr_err("phy %d failed to register\n", phydev->addr);
+               pr_err("PHY %d failed to add\n", phydev->addr);
                goto out;
        }
 
index da92ed3797aa32e763c1496a5dce9cca4a273bd5..3b6e9b83342db08c28f318c38253d315ae60317c 100644 (file)
@@ -156,6 +156,24 @@ config USB_NET_AX8817X
          This driver creates an interface named "ethX", where X depends on
          what other networking devices you have in use.
 
+config USB_NET_AX88179_178A
+       tristate "ASIX AX88179/178A USB 3.0/2.0 to Gigabit Ethernet"
+       depends on USB_USBNET
+       select CRC32
+       select PHYLIB
+       default y
+       help
+         This option adds support for ASIX AX88179 based USB 3.0/2.0
+         to Gigabit Ethernet adapters.
+
+         This driver should work with at least the following devices:
+           * ASIX AX88179
+           * ASIX AX88178A
+           * Sitcomm LN-032
+
+         This driver creates an interface named "ethX", where X depends on
+         what other networking devices you have in use.
+
 config USB_NET_CDCETHER
        tristate "CDC Ethernet support (smart devices such as cable modems)"
        depends on USB_USBNET
index 478691326f37fc3303199a07dd9e83ae087615be..119b06c9aa167235571ccc8649e25191497e505d 100644 (file)
@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_RTL8150)       += rtl8150.o
 obj-$(CONFIG_USB_HSO)          += hso.o
 obj-$(CONFIG_USB_NET_AX8817X)  += asix.o
 asix-y := asix_devices.o asix_common.o ax88172a.o
+obj-$(CONFIG_USB_NET_AX88179_178A)      += ax88179_178a.o
 obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
 obj-$(CONFIG_USB_NET_CDC_EEM)  += cdc_eem.o
 obj-$(CONFIG_USB_NET_DM9601)   += dm9601.o
index 2205dbc8d32fc2bbcb74e5c82047913edc3fdd24..709753469099c032aad55c3b98da120a0f930b2e 100644 (file)
@@ -924,6 +924,29 @@ static const struct driver_info ax88178_info = {
        .tx_fixup = asix_tx_fixup,
 };
 
+/*
+ * USBLINK 20F9 "USB 2.0 LAN" USB ethernet adapter, typically found in
+ * no-name packaging.
+ * USB device strings are:
+ *   1: Manufacturer: USBLINK
+ *   2: Product: HG20F9 USB2.0
+ *   3: Serial: 000003
+ * Appears to be compatible with Asix 88772B.
+ */
+static const struct driver_info hg20f9_info = {
+       .description = "HG20F9 USB 2.0 Ethernet",
+       .bind = ax88772_bind,
+       .unbind = ax88772_unbind,
+       .status = asix_status,
+       .link_reset = ax88772_link_reset,
+       .reset = ax88772_reset,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR |
+                FLAG_MULTI_PACKET,
+       .rx_fixup = asix_rx_fixup_common,
+       .tx_fixup = asix_tx_fixup,
+       .data = FLAG_EEPROM_MAC,
+};
+
 extern const struct driver_info ax88172a_info;
 
 static const struct usb_device_id      products [] = {
@@ -1063,6 +1086,14 @@ static const struct usb_device_id        products [] = {
        /* ASIX 88172a demo board */
        USB_DEVICE(0x0b95, 0x172a),
        .driver_info = (unsigned long) &ax88172a_info,
+}, {
+       /*
+        * USBLINK HG20F9 "USB 2.0 LAN"
+        * Appears to have gazumped Linksys's manufacturer ID but
+        * doesn't (yet) conflict with any known Linksys product.
+        */
+       USB_DEVICE(0x066b, 0x20f9),
+       .driver_info = (unsigned long) &hg20f9_info,
 },
        { },            // END
 };
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
new file mode 100644 (file)
index 0000000..71c27d8
--- /dev/null
@@ -0,0 +1,1448 @@
+/*
+ * ASIX AX88179/178A USB 3.0/2.0 to Gigabit Ethernet Devices
+ *
+ * Copyright (C) 2011-2013 ASIX
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+#include <linux/usb/usbnet.h>
+
+#define AX88179_PHY_ID                         0x03
+#define AX_EEPROM_LEN                          0x100
+#define AX88179_EEPROM_MAGIC                   0x17900b95
+#define AX_MCAST_FLTSIZE                       8
+#define AX_MAX_MCAST                           64
+#define AX_INT_PPLS_LINK                       ((u32)BIT(16))
+#define AX_RXHDR_L4_TYPE_MASK                  0x1c
+#define AX_RXHDR_L4_TYPE_UDP                   4
+#define AX_RXHDR_L4_TYPE_TCP                   16
+#define AX_RXHDR_L3CSUM_ERR                    2
+#define AX_RXHDR_L4CSUM_ERR                    1
+#define AX_RXHDR_CRC_ERR                       ((u32)BIT(31))
+#define AX_RXHDR_DROP_ERR                      ((u32)BIT(30))
+#define AX_ACCESS_MAC                          0x01
+#define AX_ACCESS_PHY                          0x02
+#define AX_ACCESS_EEPROM                       0x04
+#define AX_ACCESS_EFUS                         0x05
+#define AX_PAUSE_WATERLVL_HIGH                 0x54
+#define AX_PAUSE_WATERLVL_LOW                  0x55
+
+#define PHYSICAL_LINK_STATUS                   0x02
+       #define AX_USB_SS               0x04
+       #define AX_USB_HS               0x02
+
+#define GENERAL_STATUS                         0x03
+/* Check AX88179 version. UA1:Bit2 = 0,  UA2:Bit2 = 1 */
+       #define AX_SECLD                0x04
+
+#define AX_SROM_ADDR                           0x07
+#define AX_SROM_CMD                            0x0a
+       #define EEP_RD                  0x04
+       #define EEP_BUSY                0x10
+
+#define AX_SROM_DATA_LOW                       0x08
+#define AX_SROM_DATA_HIGH                      0x09
+
+#define AX_RX_CTL                              0x0b
+       #define AX_RX_CTL_DROPCRCERR    0x0100
+       #define AX_RX_CTL_IPE           0x0200
+       #define AX_RX_CTL_START         0x0080
+       #define AX_RX_CTL_AP            0x0020
+       #define AX_RX_CTL_AM            0x0010
+       #define AX_RX_CTL_AB            0x0008
+       #define AX_RX_CTL_AMALL         0x0002
+       #define AX_RX_CTL_PRO           0x0001
+       #define AX_RX_CTL_STOP          0x0000
+
+#define AX_NODE_ID                             0x10
+#define AX_MULFLTARY                           0x16
+
+#define AX_MEDIUM_STATUS_MODE                  0x22
+       #define AX_MEDIUM_GIGAMODE      0x01
+       #define AX_MEDIUM_FULL_DUPLEX   0x02
+       #define AX_MEDIUM_ALWAYS_ONE    0x04
+       #define AX_MEDIUM_EN_125MHZ     0x08
+       #define AX_MEDIUM_RXFLOW_CTRLEN 0x10
+       #define AX_MEDIUM_TXFLOW_CTRLEN 0x20
+       #define AX_MEDIUM_RECEIVE_EN    0x100
+       #define AX_MEDIUM_PS            0x200
+       #define AX_MEDIUM_JUMBO_EN      0x8040
+
+#define AX_MONITOR_MOD                         0x24
+       #define AX_MONITOR_MODE_RWLC    0x02
+       #define AX_MONITOR_MODE_RWMP    0x04
+       #define AX_MONITOR_MODE_PMEPOL  0x20
+       #define AX_MONITOR_MODE_PMETYPE 0x40
+
+#define AX_GPIO_CTRL                           0x25
+       #define AX_GPIO_CTRL_GPIO3EN    0x80
+       #define AX_GPIO_CTRL_GPIO2EN    0x40
+       #define AX_GPIO_CTRL_GPIO1EN    0x20
+
+#define AX_PHYPWR_RSTCTL                       0x26
+       #define AX_PHYPWR_RSTCTL_BZ     0x0010
+       #define AX_PHYPWR_RSTCTL_IPRL   0x0020
+       #define AX_PHYPWR_RSTCTL_AT     0x1000
+
+#define AX_RX_BULKIN_QCTRL                     0x2e
+#define AX_CLK_SELECT                          0x33
+       #define AX_CLK_SELECT_BCS       0x01
+       #define AX_CLK_SELECT_ACS       0x02
+       #define AX_CLK_SELECT_ULR       0x08
+
+#define AX_RXCOE_CTL                           0x34
+       #define AX_RXCOE_IP             0x01
+       #define AX_RXCOE_TCP            0x02
+       #define AX_RXCOE_UDP            0x04
+       #define AX_RXCOE_TCPV6          0x20
+       #define AX_RXCOE_UDPV6          0x40
+
+#define AX_TXCOE_CTL                           0x35
+       #define AX_TXCOE_IP             0x01
+       #define AX_TXCOE_TCP            0x02
+       #define AX_TXCOE_UDP            0x04
+       #define AX_TXCOE_TCPV6          0x20
+       #define AX_TXCOE_UDPV6          0x40
+
+#define AX_LEDCTRL                             0x73
+
+#define GMII_PHY_PHYSR                         0x11
+       #define GMII_PHY_PHYSR_SMASK    0xc000
+       #define GMII_PHY_PHYSR_GIGA     0x8000
+       #define GMII_PHY_PHYSR_100      0x4000
+       #define GMII_PHY_PHYSR_FULL     0x2000
+       #define GMII_PHY_PHYSR_LINK     0x400
+
+#define GMII_LED_ACT                           0x1a
+       #define GMII_LED_ACTIVE_MASK    0xff8f
+       #define GMII_LED0_ACTIVE        BIT(4)
+       #define GMII_LED1_ACTIVE        BIT(5)
+       #define GMII_LED2_ACTIVE        BIT(6)
+
+#define GMII_LED_LINK                          0x1c
+       #define GMII_LED_LINK_MASK      0xf888
+       #define GMII_LED0_LINK_10       BIT(0)
+       #define GMII_LED0_LINK_100      BIT(1)
+       #define GMII_LED0_LINK_1000     BIT(2)
+       #define GMII_LED1_LINK_10       BIT(4)
+       #define GMII_LED1_LINK_100      BIT(5)
+       #define GMII_LED1_LINK_1000     BIT(6)
+       #define GMII_LED2_LINK_10       BIT(8)
+       #define GMII_LED2_LINK_100      BIT(9)
+       #define GMII_LED2_LINK_1000     BIT(10)
+       #define LED0_ACTIVE             BIT(0)
+       #define LED0_LINK_10            BIT(1)
+       #define LED0_LINK_100           BIT(2)
+       #define LED0_LINK_1000          BIT(3)
+       #define LED0_FD                 BIT(4)
+       #define LED0_USB3_MASK          0x001f
+       #define LED1_ACTIVE             BIT(5)
+       #define LED1_LINK_10            BIT(6)
+       #define LED1_LINK_100           BIT(7)
+       #define LED1_LINK_1000          BIT(8)
+       #define LED1_FD                 BIT(9)
+       #define LED1_USB3_MASK          0x03e0
+       #define LED2_ACTIVE             BIT(10)
+       #define LED2_LINK_1000          BIT(13)
+       #define LED2_LINK_100           BIT(12)
+       #define LED2_LINK_10            BIT(11)
+       #define LED2_FD                 BIT(14)
+       #define LED_VALID               BIT(15)
+       #define LED2_USB3_MASK          0x7c00
+
+#define GMII_PHYPAGE                           0x1e
+#define GMII_PHY_PAGE_SELECT                   0x1f
+       #define GMII_PHY_PGSEL_EXT      0x0007
+       #define GMII_PHY_PGSEL_PAGE0    0x0000
+
+struct ax88179_data {
+       u16 rxctl;
+       u16 reserved;
+};
+
+struct ax88179_int_data {
+       __le32 intdata1;
+       __le32 intdata2;
+};
+
+static const struct {
+       unsigned char ctrl, timer_l, timer_h, size, ifg;
+} AX88179_BULKIN_SIZE[] =      {
+       {7, 0x4f, 0,    0x12, 0xff},
+       {7, 0x20, 3,    0x16, 0xff},
+       {7, 0xae, 7,    0x18, 0xff},
+       {7, 0xcc, 0x4c, 0x18, 8},
+};
+
+static int __ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+                             u16 size, void *data, int in_pm)
+{
+       int ret;
+       int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16);
+
+       BUG_ON(!dev);
+
+       if (!in_pm)
+               fn = usbnet_read_cmd;
+       else
+               fn = usbnet_read_cmd_nopm;
+
+       ret = fn(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                value, index, data, size);
+
+       if (unlikely(ret < 0))
+               netdev_warn(dev->net, "Failed to read reg index 0x%04x: %d\n",
+                           index, ret);
+
+       return ret;
+}
+
+static int __ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+                              u16 size, void *data, int in_pm)
+{
+       int ret;
+       int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16);
+
+       BUG_ON(!dev);
+
+       if (!in_pm)
+               fn = usbnet_write_cmd;
+       else
+               fn = usbnet_write_cmd_nopm;
+
+       ret = fn(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                value, index, data, size);
+
+       if (unlikely(ret < 0))
+               netdev_warn(dev->net, "Failed to write reg index 0x%04x: %d\n",
+                           index, ret);
+
+       return ret;
+}
+
+static void ax88179_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value,
+                                   u16 index, u16 size, void *data)
+{
+       u16 buf;
+
+       if (2 == size) {
+               buf = *((u16 *)data);
+               cpu_to_le16s(&buf);
+               usbnet_write_cmd_async(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR |
+                                      USB_RECIP_DEVICE, value, index, &buf,
+                                      size);
+       } else {
+               usbnet_write_cmd_async(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR |
+                                      USB_RECIP_DEVICE, value, index, data,
+                                      size);
+       }
+}
+
+static int ax88179_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
+                                u16 index, u16 size, void *data)
+{
+       int ret;
+
+       if (2 == size) {
+               u16 buf;
+               ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 1);
+               le16_to_cpus(&buf);
+               *((u16 *)data) = buf;
+       } else if (4 == size) {
+               u32 buf;
+               ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 1);
+               le32_to_cpus(&buf);
+               *((u32 *)data) = buf;
+       } else {
+               ret = __ax88179_read_cmd(dev, cmd, value, index, size, data, 1);
+       }
+
+       return ret;
+}
+
+static int ax88179_write_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
+                                 u16 index, u16 size, void *data)
+{
+       int ret;
+
+       if (2 == size) {
+               u16 buf;
+               buf = *((u16 *)data);
+               cpu_to_le16s(&buf);
+               ret = __ax88179_write_cmd(dev, cmd, value, index,
+                                         size, &buf, 1);
+       } else {
+               ret = __ax88179_write_cmd(dev, cmd, value, index,
+                                         size, data, 1);
+       }
+
+       return ret;
+}
+
+static int ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+                           u16 size, void *data)
+{
+       int ret;
+
+       if (2 == size) {
+               u16 buf;
+               ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 0);
+               le16_to_cpus(&buf);
+               *((u16 *)data) = buf;
+       } else if (4 == size) {
+               u32 buf;
+               ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 0);
+               le32_to_cpus(&buf);
+               *((u32 *)data) = buf;
+       } else {
+               ret = __ax88179_read_cmd(dev, cmd, value, index, size, data, 0);
+       }
+
+       return ret;
+}
+
+static int ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+                            u16 size, void *data)
+{
+       int ret;
+
+       if (2 == size) {
+               u16 buf;
+               buf = *((u16 *)data);
+               cpu_to_le16s(&buf);
+               ret = __ax88179_write_cmd(dev, cmd, value, index,
+                                         size, &buf, 0);
+       } else {
+               ret = __ax88179_write_cmd(dev, cmd, value, index,
+                                         size, data, 0);
+       }
+
+       return ret;
+}
+
+static void ax88179_status(struct usbnet *dev, struct urb *urb)
+{
+       struct ax88179_int_data *event;
+       u32 link;
+
+       if (urb->actual_length < 8)
+               return;
+
+       event = urb->transfer_buffer;
+       le32_to_cpus((void *)&event->intdata1);
+
+       link = (((__force u32)event->intdata1) & AX_INT_PPLS_LINK) >> 16;
+
+       if (netif_carrier_ok(dev->net) != link) {
+               if (link)
+                       usbnet_defer_kevent(dev, EVENT_LINK_RESET);
+               else
+                       netif_carrier_off(dev->net);
+
+               netdev_info(dev->net, "ax88179 - Link status is: %d\n", link);
+       }
+}
+
+static int ax88179_mdio_read(struct net_device *netdev, int phy_id, int loc)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       u16 res;
+
+       ax88179_read_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)loc, 2, &res);
+       return res;
+}
+
+static void ax88179_mdio_write(struct net_device *netdev, int phy_id, int loc,
+                              int val)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       u16 res = (u16) val;
+
+       ax88179_write_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)loc, 2, &res);
+}
+
+static int ax88179_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       struct usbnet *dev = usb_get_intfdata(intf);
+       u16 tmp16;
+       u8 tmp8;
+
+       usbnet_suspend(intf, message);
+
+       /* Disable RX path */
+       ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                             2, 2, &tmp16);
+       tmp16 &= ~AX_MEDIUM_RECEIVE_EN;
+       ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                              2, 2, &tmp16);
+
+       /* Force bulk-in zero length */
+       ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
+                             2, 2, &tmp16);
+
+       tmp16 |= AX_PHYPWR_RSTCTL_BZ | AX_PHYPWR_RSTCTL_IPRL;
+       ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
+                              2, 2, &tmp16);
+
+       /* change clock */
+       tmp8 = 0;
+       ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
+
+       /* Configure RX control register => stop operation */
+       tmp16 = AX_RX_CTL_STOP;
+       ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16);
+
+       return 0;
+}
+
+/* This function is used to enable the autodetach function. */
+/* This function is determined by offset 0x43 of EEPROM */
+static int ax88179_auto_detach(struct usbnet *dev, int in_pm)
+{
+       u16 tmp16;
+       u8 tmp8;
+       int (*fnr)(struct usbnet *, u8, u16, u16, u16, void *);
+       int (*fnw)(struct usbnet *, u8, u16, u16, u16, void *);
+
+       if (!in_pm) {
+               fnr = ax88179_read_cmd;
+               fnw = ax88179_write_cmd;
+       } else {
+               fnr = ax88179_read_cmd_nopm;
+               fnw = ax88179_write_cmd_nopm;
+       }
+
+       if (fnr(dev, AX_ACCESS_EEPROM, 0x43, 1, 2, &tmp16) < 0)
+               return 0;
+
+       if ((tmp16 == 0xFFFF) || (!(tmp16 & 0x0100)))
+               return 0;
+
+       /* Enable Auto Detach bit */
+       tmp8 = 0;
+       fnr(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
+       tmp8 |= AX_CLK_SELECT_ULR;
+       fnw(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
+
+       fnr(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16);
+       tmp16 |= AX_PHYPWR_RSTCTL_AT;
+       fnw(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16);
+
+       return 0;
+}
+
+static int ax88179_resume(struct usb_interface *intf)
+{
+       struct usbnet *dev = usb_get_intfdata(intf);
+       u16 tmp16;
+       u8 tmp8;
+
+       netif_carrier_off(dev->net);
+
+       /* Power up ethernet PHY */
+       tmp16 = 0;
+       ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
+                              2, 2, &tmp16);
+       udelay(1000);
+
+       tmp16 = AX_PHYPWR_RSTCTL_IPRL;
+       ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
+                              2, 2, &tmp16);
+       msleep(200);
+
+       /* Ethernet PHY Auto Detach*/
+       ax88179_auto_detach(dev, 1);
+
+       /* Enable clock */
+       ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC,  AX_CLK_SELECT, 1, 1, &tmp8);
+       tmp8 |= AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
+       ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8);
+       msleep(100);
+
+       /* Configure RX control register => start operation */
+       tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START |
+               AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
+       ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16);
+
+       return usbnet_resume(intf);
+}
+
+static void
+ax88179_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
+{
+       struct usbnet *dev = netdev_priv(net);
+       u8 opt;
+
+       if (ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD,
+                            1, 1, &opt) < 0) {
+               wolinfo->supported = 0;
+               wolinfo->wolopts = 0;
+               return;
+       }
+
+       wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
+       wolinfo->wolopts = 0;
+       if (opt & AX_MONITOR_MODE_RWLC)
+               wolinfo->wolopts |= WAKE_PHY;
+       if (opt & AX_MONITOR_MODE_RWMP)
+               wolinfo->wolopts |= WAKE_MAGIC;
+}
+
+static int
+ax88179_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
+{
+       struct usbnet *dev = netdev_priv(net);
+       u8 opt = 0;
+
+       if (wolinfo->wolopts & WAKE_PHY)
+               opt |= AX_MONITOR_MODE_RWLC;
+       if (wolinfo->wolopts & WAKE_MAGIC)
+               opt |= AX_MONITOR_MODE_RWMP;
+
+       if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD,
+                             1, 1, &opt) < 0)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int ax88179_get_eeprom_len(struct net_device *net)
+{
+       return AX_EEPROM_LEN;
+}
+
+static int
+ax88179_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom,
+                  u8 *data)
+{
+       struct usbnet *dev = netdev_priv(net);
+       u16 *eeprom_buff;
+       int first_word, last_word;
+       int i, ret;
+
+       if (eeprom->len == 0)
+               return -EINVAL;
+
+       eeprom->magic = AX88179_EEPROM_MAGIC;
+
+       first_word = eeprom->offset >> 1;
+       last_word = (eeprom->offset + eeprom->len - 1) >> 1;
+       eeprom_buff = kmalloc(sizeof(u16) * (last_word - first_word + 1),
+                             GFP_KERNEL);
+       if (!eeprom_buff)
+               return -ENOMEM;
+
+       /* ax88179/178A returns 2 bytes from eeprom on read */
+       for (i = first_word; i <= last_word; i++) {
+               ret = __ax88179_read_cmd(dev, AX_ACCESS_EEPROM, i, 1, 2,
+                                        &eeprom_buff[i - first_word],
+                                        0);
+               if (ret < 0) {
+                       kfree(eeprom_buff);
+                       return -EIO;
+               }
+       }
+
+       memcpy(data, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
+       kfree(eeprom_buff);
+       return 0;
+}
+
+static int ax88179_get_settings(struct net_device *net, struct ethtool_cmd *cmd)
+{
+       struct usbnet *dev = netdev_priv(net);
+       return mii_ethtool_gset(&dev->mii, cmd);
+}
+
+static int ax88179_set_settings(struct net_device *net, struct ethtool_cmd *cmd)
+{
+       struct usbnet *dev = netdev_priv(net);
+       return mii_ethtool_sset(&dev->mii, cmd);
+}
+
+
+static int ax88179_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
+{
+       struct usbnet *dev = netdev_priv(net);
+       return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
+}
+
+static const struct ethtool_ops ax88179_ethtool_ops = {
+       .get_link               = ethtool_op_get_link,
+       .get_msglevel           = usbnet_get_msglevel,
+       .set_msglevel           = usbnet_set_msglevel,
+       .get_wol                = ax88179_get_wol,
+       .set_wol                = ax88179_set_wol,
+       .get_eeprom_len         = ax88179_get_eeprom_len,
+       .get_eeprom             = ax88179_get_eeprom,
+       .get_settings           = ax88179_get_settings,
+       .set_settings           = ax88179_set_settings,
+       .nway_reset             = usbnet_nway_reset,
+};
+
+static void ax88179_set_multicast(struct net_device *net)
+{
+       struct usbnet *dev = netdev_priv(net);
+       struct ax88179_data *data = (struct ax88179_data *)dev->data;
+       u8 *m_filter = ((u8 *)dev->data) + 12;
+
+       data->rxctl = (AX_RX_CTL_START | AX_RX_CTL_AB | AX_RX_CTL_IPE);
+
+       if (net->flags & IFF_PROMISC) {
+               data->rxctl |= AX_RX_CTL_PRO;
+       } else if (net->flags & IFF_ALLMULTI ||
+                  netdev_mc_count(net) > AX_MAX_MCAST) {
+               data->rxctl |= AX_RX_CTL_AMALL;
+       } else if (netdev_mc_empty(net)) {
+               /* just broadcast and directed */
+       } else {
+               /* We use the 20 byte dev->data for our 8 byte filter buffer
+                * to avoid allocating memory that is tricky to free later
+                */
+               u32 crc_bits;
+               struct netdev_hw_addr *ha;
+
+               memset(m_filter, 0, AX_MCAST_FLTSIZE);
+
+               netdev_for_each_mc_addr(ha, net) {
+                       crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26;
+                       *(m_filter + (crc_bits >> 3)) |= (1 << (crc_bits & 7));
+               }
+
+               ax88179_write_cmd_async(dev, AX_ACCESS_MAC, AX_MULFLTARY,
+                                       AX_MCAST_FLTSIZE, AX_MCAST_FLTSIZE,
+                                       m_filter);
+
+               data->rxctl |= AX_RX_CTL_AM;
+       }
+
+       ax88179_write_cmd_async(dev, AX_ACCESS_MAC, AX_RX_CTL,
+                               2, 2, &data->rxctl);
+}
+
+static int
+ax88179_set_features(struct net_device *net, netdev_features_t features)
+{
+       u8 tmp;
+       struct usbnet *dev = netdev_priv(net);
+       netdev_features_t changed = net->features ^ features;
+
+       if (changed & NETIF_F_IP_CSUM) {
+               ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp);
+               tmp ^= AX_TXCOE_TCP | AX_TXCOE_UDP;
+               ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp);
+       }
+
+       if (changed & NETIF_F_IPV6_CSUM) {
+               ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp);
+               tmp ^= AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
+               ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp);
+       }
+
+       if (changed & NETIF_F_RXCSUM) {
+               ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &tmp);
+               tmp ^= AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
+                      AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
+               ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &tmp);
+       }
+
+       return 0;
+}
+
+static int ax88179_change_mtu(struct net_device *net, int new_mtu)
+{
+       struct usbnet *dev = netdev_priv(net);
+       u16 tmp16;
+
+       if (new_mtu <= 0 || new_mtu > 4088)
+               return -EINVAL;
+
+       net->mtu = new_mtu;
+       dev->hard_mtu = net->mtu + net->hard_header_len;
+
+       if (net->mtu > 1500) {
+               ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                                2, 2, &tmp16);
+               tmp16 |= AX_MEDIUM_JUMBO_EN;
+               ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                                 2, 2, &tmp16);
+       } else {
+               ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                                2, 2, &tmp16);
+               tmp16 &= ~AX_MEDIUM_JUMBO_EN;
+               ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                                 2, 2, &tmp16);
+       }
+
+       return 0;
+}
+
+static int ax88179_set_mac_addr(struct net_device *net, void *p)
+{
+       struct usbnet *dev = netdev_priv(net);
+       struct sockaddr *addr = p;
+
+       if (netif_running(net))
+               return -EBUSY;
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       memcpy(net->dev_addr, addr->sa_data, ETH_ALEN);
+
+       /* Set the MAC address */
+       return ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
+                                ETH_ALEN, net->dev_addr);
+}
+
+static const struct net_device_ops ax88179_netdev_ops = {
+       .ndo_open               = usbnet_open,
+       .ndo_stop               = usbnet_stop,
+       .ndo_start_xmit         = usbnet_start_xmit,
+       .ndo_tx_timeout         = usbnet_tx_timeout,
+       .ndo_change_mtu         = ax88179_change_mtu,
+       .ndo_set_mac_address    = ax88179_set_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_do_ioctl           = ax88179_ioctl,
+       .ndo_set_rx_mode        = ax88179_set_multicast,
+       .ndo_set_features       = ax88179_set_features,
+};
+
+static int ax88179_check_eeprom(struct usbnet *dev)
+{
+       u8 i, buf, eeprom[20];
+       u16 csum, delay = HZ / 10;
+       unsigned long jtimeout;
+
+       /* Read EEPROM content */
+       for (i = 0; i < 6; i++) {
+               buf = i;
+               if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_ADDR,
+                                     1, 1, &buf) < 0)
+                       return -EINVAL;
+
+               buf = EEP_RD;
+               if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD,
+                                     1, 1, &buf) < 0)
+                       return -EINVAL;
+
+               jtimeout = jiffies + delay;
+               do {
+                       ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD,
+                                        1, 1, &buf);
+
+                       if (time_after(jiffies, jtimeout))
+                               return -EINVAL;
+
+               } while (buf & EEP_BUSY);
+
+               __ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_LOW,
+                                  2, 2, &eeprom[i * 2], 0);
+
+               if ((i == 0) && (eeprom[0] == 0xFF))
+                       return -EINVAL;
+       }
+
+       csum = eeprom[6] + eeprom[7] + eeprom[8] + eeprom[9];
+       csum = (csum >> 8) + (csum & 0xff);
+       if ((csum + eeprom[10]) != 0xff)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int ax88179_check_efuse(struct usbnet *dev, u16 *ledmode)
+{
+       u8      i;
+       u8      efuse[64];
+       u16     csum = 0;
+
+       if (ax88179_read_cmd(dev, AX_ACCESS_EFUS, 0, 64, 64, efuse) < 0)
+               return -EINVAL;
+
+       if (*efuse == 0xFF)
+               return -EINVAL;
+
+       for (i = 0; i < 64; i++)
+               csum = csum + efuse[i];
+
+       while (csum > 255)
+               csum = (csum & 0x00FF) + ((csum >> 8) & 0x00FF);
+
+       if (csum != 0xFF)
+               return -EINVAL;
+
+       *ledmode = (efuse[51] << 8) | efuse[52];
+
+       return 0;
+}
+
+static int ax88179_convert_old_led(struct usbnet *dev, u16 *ledvalue)
+{
+       u16 led;
+
+       /* Loaded the old eFuse LED Mode */
+       if (ax88179_read_cmd(dev, AX_ACCESS_EEPROM, 0x3C, 1, 2, &led) < 0)
+               return -EINVAL;
+
+       led >>= 8;
+       switch (led) {
+       case 0xFF:
+               led = LED0_ACTIVE | LED1_LINK_10 | LED1_LINK_100 |
+                     LED1_LINK_1000 | LED2_ACTIVE | LED2_LINK_10 |
+                     LED2_LINK_100 | LED2_LINK_1000 | LED_VALID;
+               break;
+       case 0xFE:
+               led = LED0_ACTIVE | LED1_LINK_1000 | LED2_LINK_100 | LED_VALID;
+               break;
+       case 0xFD:
+               led = LED0_ACTIVE | LED1_LINK_1000 | LED2_LINK_100 |
+                     LED2_LINK_10 | LED_VALID;
+               break;
+       case 0xFC:
+               led = LED0_ACTIVE | LED1_ACTIVE | LED1_LINK_1000 | LED2_ACTIVE |
+                     LED2_LINK_100 | LED2_LINK_10 | LED_VALID;
+               break;
+       default:
+               led = LED0_ACTIVE | LED1_LINK_10 | LED1_LINK_100 |
+                     LED1_LINK_1000 | LED2_ACTIVE | LED2_LINK_10 |
+                     LED2_LINK_100 | LED2_LINK_1000 | LED_VALID;
+               break;
+       }
+
+       *ledvalue = led;
+
+       return 0;
+}
+
+static int ax88179_led_setting(struct usbnet *dev)
+{
+       u8 ledfd, value = 0;
+       u16 tmp, ledact, ledlink, ledvalue = 0, delay = HZ / 10;
+       unsigned long jtimeout;
+
+       /* Check AX88179 version. UA1 or UA2*/
+       ax88179_read_cmd(dev, AX_ACCESS_MAC, GENERAL_STATUS, 1, 1, &value);
+
+       if (!(value & AX_SECLD)) {      /* UA1 */
+               value = AX_GPIO_CTRL_GPIO3EN | AX_GPIO_CTRL_GPIO2EN |
+                       AX_GPIO_CTRL_GPIO1EN;
+               if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_GPIO_CTRL,
+                                     1, 1, &value) < 0)
+                       return -EINVAL;
+       }
+
+       /* Check EEPROM */
+       if (!ax88179_check_eeprom(dev)) {
+               value = 0x42;
+               if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_ADDR,
+                                     1, 1, &value) < 0)
+                       return -EINVAL;
+
+               value = EEP_RD;
+               if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD,
+                                     1, 1, &value) < 0)
+                       return -EINVAL;
+
+               jtimeout = jiffies + delay;
+               do {
+                       ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD,
+                                        1, 1, &value);
+
+                       if (time_after(jiffies, jtimeout))
+                               return -EINVAL;
+
+               } while (value & EEP_BUSY);
+
+               ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_HIGH,
+                                1, 1, &value);
+               ledvalue = (value << 8);
+
+               ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_LOW,
+                                1, 1, &value);
+               ledvalue |= value;
+
+               /* load internal ROM for defaule setting */
+               if ((ledvalue == 0xFFFF) || ((ledvalue & LED_VALID) == 0))
+                       ax88179_convert_old_led(dev, &ledvalue);
+
+       } else if (!ax88179_check_efuse(dev, &ledvalue)) {
+               if ((ledvalue == 0xFFFF) || ((ledvalue & LED_VALID) == 0))
+                       ax88179_convert_old_led(dev, &ledvalue);
+       } else {
+               ax88179_convert_old_led(dev, &ledvalue);
+       }
+
+       tmp = GMII_PHY_PGSEL_EXT;
+       ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+                         GMII_PHY_PAGE_SELECT, 2, &tmp);
+
+       tmp = 0x2c;
+       ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+                         GMII_PHYPAGE, 2, &tmp);
+
+       ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+                        GMII_LED_ACT, 2, &ledact);
+
+       ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+                        GMII_LED_LINK, 2, &ledlink);
+
+       ledact &= GMII_LED_ACTIVE_MASK;
+       ledlink &= GMII_LED_LINK_MASK;
+
+       if (ledvalue & LED0_ACTIVE)
+               ledact |= GMII_LED0_ACTIVE;
+
+       if (ledvalue & LED1_ACTIVE)
+               ledact |= GMII_LED1_ACTIVE;
+
+       if (ledvalue & LED2_ACTIVE)
+               ledact |= GMII_LED2_ACTIVE;
+
+       if (ledvalue & LED0_LINK_10)
+               ledlink |= GMII_LED0_LINK_10;
+
+       if (ledvalue & LED1_LINK_10)
+               ledlink |= GMII_LED1_LINK_10;
+
+       if (ledvalue & LED2_LINK_10)
+               ledlink |= GMII_LED2_LINK_10;
+
+       if (ledvalue & LED0_LINK_100)
+               ledlink |= GMII_LED0_LINK_100;
+
+       if (ledvalue & LED1_LINK_100)
+               ledlink |= GMII_LED1_LINK_100;
+
+       if (ledvalue & LED2_LINK_100)
+               ledlink |= GMII_LED2_LINK_100;
+
+       if (ledvalue & LED0_LINK_1000)
+               ledlink |= GMII_LED0_LINK_1000;
+
+       if (ledvalue & LED1_LINK_1000)
+               ledlink |= GMII_LED1_LINK_1000;
+
+       if (ledvalue & LED2_LINK_1000)
+               ledlink |= GMII_LED2_LINK_1000;
+
+       tmp = ledact;
+       ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+                         GMII_LED_ACT, 2, &tmp);
+
+       tmp = ledlink;
+       ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+                         GMII_LED_LINK, 2, &tmp);
+
+       tmp = GMII_PHY_PGSEL_PAGE0;
+       ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+                         GMII_PHY_PAGE_SELECT, 2, &tmp);
+
+       /* LED full duplex setting */
+       ledfd = 0;
+       if (ledvalue & LED0_FD)
+               ledfd |= 0x01;
+       else if ((ledvalue & LED0_USB3_MASK) == 0)
+               ledfd |= 0x02;
+
+       if (ledvalue & LED1_FD)
+               ledfd |= 0x04;
+       else if ((ledvalue & LED1_USB3_MASK) == 0)
+               ledfd |= 0x08;
+
+       if (ledvalue & LED2_FD)
+               ledfd |= 0x10;
+       else if ((ledvalue & LED2_USB3_MASK) == 0)
+               ledfd |= 0x20;
+
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_LEDCTRL, 1, 1, &ledfd);
+
+       return 0;
+}
+
+static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       u8 buf[5];
+       u16 *tmp16;
+       u8 *tmp;
+       struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
+
+       usbnet_get_endpoints(dev, intf);
+
+       tmp16 = (u16 *)buf;
+       tmp = (u8 *)buf;
+
+       memset(ax179_data, 0, sizeof(*ax179_data));
+
+       /* Power up ethernet PHY */
+       *tmp16 = 0;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
+       *tmp16 = AX_PHYPWR_RSTCTL_IPRL;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
+       msleep(200);
+
+       *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp);
+       msleep(100);
+
+       ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
+                        ETH_ALEN, dev->net->dev_addr);
+       memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN);
+
+       /* RX bulk configuration */
+       memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);
+
+       dev->rx_urb_size = 1024 * 20;
+
+       *tmp = 0x34;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp);
+
+       *tmp = 0x52;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH,
+                         1, 1, tmp);
+
+       dev->net->netdev_ops = &ax88179_netdev_ops;
+       dev->net->ethtool_ops = &ax88179_ethtool_ops;
+       dev->net->needed_headroom = 8;
+
+       /* Initialize MII structure */
+       dev->mii.dev = dev->net;
+       dev->mii.mdio_read = ax88179_mdio_read;
+       dev->mii.mdio_write = ax88179_mdio_write;
+       dev->mii.phy_id_mask = 0xff;
+       dev->mii.reg_num_mask = 0xff;
+       dev->mii.phy_id = 0x03;
+       dev->mii.supports_gmii = 1;
+
+       dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+                             NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO;
+
+       dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+                                NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO;
+
+       /* Enable checksum offload */
+       *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
+              AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp);
+
+       *tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP |
+              AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp);
+
+       /* Configure RX control register => start operation */
+       *tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START |
+                AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16);
+
+       *tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL |
+              AX_MONITOR_MODE_RWMP;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp);
+
+       /* Configure default medium type => giga */
+       *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
+                AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE |
+                AX_MEDIUM_FULL_DUPLEX | AX_MEDIUM_GIGAMODE;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                         2, 2, tmp16);
+
+       ax88179_led_setting(dev);
+
+       /* Restart autoneg */
+       mii_nway_restart(&dev->mii);
+
+       netif_carrier_off(dev->net);
+
+       return 0;
+}
+
+static void ax88179_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+       u16 tmp16;
+
+       /* Configure RX control register => stop operation */
+       tmp16 = AX_RX_CTL_STOP;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16);
+
+       tmp16 = 0;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp16);
+
+       /* Power down ethernet PHY */
+       tmp16 = 0;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16);
+}
+
+static void
+ax88179_rx_checksum(struct sk_buff *skb, u32 *pkt_hdr)
+{
+       skb->ip_summed = CHECKSUM_NONE;
+
+       /* checksum error bit is set */
+       if ((*pkt_hdr & AX_RXHDR_L3CSUM_ERR) ||
+           (*pkt_hdr & AX_RXHDR_L4CSUM_ERR))
+               return;
+
+       /* It must be a TCP or UDP packet with a valid checksum */
+       if (((*pkt_hdr & AX_RXHDR_L4_TYPE_MASK) == AX_RXHDR_L4_TYPE_TCP) ||
+           ((*pkt_hdr & AX_RXHDR_L4_TYPE_MASK) == AX_RXHDR_L4_TYPE_UDP))
+               skb->ip_summed = CHECKSUM_UNNECESSARY;
+}
+
+static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+       struct sk_buff *ax_skb;
+       int pkt_cnt;
+       u32 rx_hdr;
+       u16 hdr_off;
+       u32 *pkt_hdr;
+
+       skb_trim(skb, skb->len - 4);
+       memcpy(&rx_hdr, skb_tail_pointer(skb), 4);
+       le32_to_cpus(&rx_hdr);
+
+       pkt_cnt = (u16)rx_hdr;
+       hdr_off = (u16)(rx_hdr >> 16);
+       pkt_hdr = (u32 *)(skb->data + hdr_off);
+
+       while (pkt_cnt--) {
+               u16 pkt_len;
+
+               le32_to_cpus(pkt_hdr);
+               pkt_len = (*pkt_hdr >> 16) & 0x1fff;
+
+               /* Check CRC or runt packet */
+               if ((*pkt_hdr & AX_RXHDR_CRC_ERR) ||
+                   (*pkt_hdr & AX_RXHDR_DROP_ERR)) {
+                       skb_pull(skb, (pkt_len + 7) & 0xFFF8);
+                       pkt_hdr++;
+                       continue;
+               }
+
+               if (pkt_cnt == 0) {
+                       /* Skip IP alignment psudo header */
+                       skb_pull(skb, 2);
+                       skb->len = pkt_len;
+                       skb_set_tail_pointer(skb, pkt_len);
+                       skb->truesize = pkt_len + sizeof(struct sk_buff);
+                       ax88179_rx_checksum(skb, pkt_hdr);
+                       return 1;
+               }
+
+               ax_skb = skb_clone(skb, GFP_ATOMIC);
+               if (ax_skb) {
+                       ax_skb->len = pkt_len;
+                       ax_skb->data = skb->data + 2;
+                       skb_set_tail_pointer(ax_skb, pkt_len);
+                       ax_skb->truesize = pkt_len + sizeof(struct sk_buff);
+                       ax88179_rx_checksum(ax_skb, pkt_hdr);
+                       usbnet_skb_return(dev, ax_skb);
+               } else {
+                       return 0;
+               }
+
+               skb_pull(skb, (pkt_len + 7) & 0xFFF8);
+               pkt_hdr++;
+       }
+       return 1;
+}
+
+static struct sk_buff *
+ax88179_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
+{
+       u32 tx_hdr1, tx_hdr2;
+       int frame_size = dev->maxpacket;
+       int mss = skb_shinfo(skb)->gso_size;
+       int headroom;
+       int tailroom;
+
+       tx_hdr1 = skb->len;
+       tx_hdr2 = mss;
+       if (((skb->len + 8) % frame_size) == 0)
+               tx_hdr2 |= 0x80008000;  /* Enable padding */
+
+       skb_linearize(skb);
+       headroom = skb_headroom(skb);
+       tailroom = skb_tailroom(skb);
+
+       if (!skb_header_cloned(skb) &&
+           !skb_cloned(skb) &&
+           (headroom + tailroom) >= 8) {
+               if (headroom < 8) {
+                       skb->data = memmove(skb->head + 8, skb->data, skb->len);
+                       skb_set_tail_pointer(skb, skb->len);
+               }
+       } else {
+               struct sk_buff *skb2;
+
+               skb2 = skb_copy_expand(skb, 8, 0, flags);
+               dev_kfree_skb_any(skb);
+               skb = skb2;
+               if (!skb)
+                       return NULL;
+       }
+
+       skb_push(skb, 4);
+       cpu_to_le32s(&tx_hdr2);
+       skb_copy_to_linear_data(skb, &tx_hdr2, 4);
+
+       skb_push(skb, 4);
+       cpu_to_le32s(&tx_hdr1);
+       skb_copy_to_linear_data(skb, &tx_hdr1, 4);
+
+       return skb;
+}
+
+static int ax88179_link_reset(struct usbnet *dev)
+{
+       struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data;
+       u8 tmp[5], link_sts;
+       u16 mode, tmp16, delay = HZ / 10;
+       u32 tmp32 = 0x40000000;
+       unsigned long jtimeout;
+
+       jtimeout = jiffies + delay;
+       while (tmp32 & 0x40000000) {
+               mode = 0;
+               ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &mode);
+               ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2,
+                                 &ax179_data->rxctl);
+
+               /*link up, check the usb device control TX FIFO full or empty*/
+               ax88179_read_cmd(dev, 0x81, 0x8c, 0, 4, &tmp32);
+
+               if (time_after(jiffies, jtimeout))
+                       return 0;
+       }
+
+       mode = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
+              AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE;
+
+       ax88179_read_cmd(dev, AX_ACCESS_MAC, PHYSICAL_LINK_STATUS,
+                        1, 1, &link_sts);
+
+       ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID,
+                        GMII_PHY_PHYSR, 2, &tmp16);
+
+       if (!(tmp16 & GMII_PHY_PHYSR_LINK)) {
+               return 0;
+       } else if (GMII_PHY_PHYSR_GIGA == (tmp16 & GMII_PHY_PHYSR_SMASK)) {
+               mode |= AX_MEDIUM_GIGAMODE | AX_MEDIUM_EN_125MHZ;
+               if (dev->net->mtu > 1500)
+                       mode |= AX_MEDIUM_JUMBO_EN;
+
+               if (link_sts & AX_USB_SS)
+                       memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
+               else if (link_sts & AX_USB_HS)
+                       memcpy(tmp, &AX88179_BULKIN_SIZE[1], 5);
+               else
+                       memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
+       } else if (GMII_PHY_PHYSR_100 == (tmp16 & GMII_PHY_PHYSR_SMASK)) {
+               mode |= AX_MEDIUM_PS;
+
+               if (link_sts & (AX_USB_SS | AX_USB_HS))
+                       memcpy(tmp, &AX88179_BULKIN_SIZE[2], 5);
+               else
+                       memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
+       } else {
+               memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5);
+       }
+
+       /* RX bulk configuration */
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);
+
+       dev->rx_urb_size = (1024 * (tmp[3] + 2));
+
+       if (tmp16 & GMII_PHY_PHYSR_FULL)
+               mode |= AX_MEDIUM_FULL_DUPLEX;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                         2, 2, &mode);
+
+       netif_carrier_on(dev->net);
+
+       return 0;
+}
+
+static int ax88179_reset(struct usbnet *dev)
+{
+       u8 buf[5];
+       u16 *tmp16;
+       u8 *tmp;
+
+       tmp16 = (u16 *)buf;
+       tmp = (u8 *)buf;
+
+       /* Power up ethernet PHY */
+       *tmp16 = 0;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
+
+       *tmp16 = AX_PHYPWR_RSTCTL_IPRL;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16);
+       msleep(200);
+
+       *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp);
+       msleep(100);
+
+       /* Ethernet PHY Auto Detach*/
+       ax88179_auto_detach(dev, 0);
+
+       ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, ETH_ALEN,
+                        dev->net->dev_addr);
+       memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN);
+
+       /* RX bulk configuration */
+       memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5);
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp);
+
+       dev->rx_urb_size = 1024 * 20;
+
+       *tmp = 0x34;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp);
+
+       *tmp = 0x52;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH,
+                         1, 1, tmp);
+
+       dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+                             NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO;
+
+       dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+                                NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO;
+
+       /* Enable checksum offload */
+       *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
+              AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp);
+
+       *tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP |
+              AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp);
+
+       /* Configure RX control register => start operation */
+       *tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START |
+                AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16);
+
+       *tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL |
+              AX_MONITOR_MODE_RWMP;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp);
+
+       /* Configure default medium type => giga */
+       *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN |
+                AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE |
+                AX_MEDIUM_FULL_DUPLEX | AX_MEDIUM_GIGAMODE;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                         2, 2, tmp16);
+
+       ax88179_led_setting(dev);
+
+       /* Restart autoneg */
+       mii_nway_restart(&dev->mii);
+
+       netif_carrier_off(dev->net);
+
+       return 0;
+}
+
+static int ax88179_stop(struct usbnet *dev)
+{
+       u16 tmp16;
+
+       ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                        2, 2, &tmp16);
+       tmp16 &= ~AX_MEDIUM_RECEIVE_EN;
+       ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+                         2, 2, &tmp16);
+
+       return 0;
+}
+
+static const struct driver_info ax88179_info = {
+       .description = "ASIX AX88179 USB 3.0 Gigibit Ethernet",
+       .bind = ax88179_bind,
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+       .reset = ax88179_reset,
+       .stop = ax88179_stop,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+       .tx_fixup = ax88179_tx_fixup,
+};
+
+static const struct driver_info ax88178a_info = {
+       .description = "ASIX AX88178A USB 2.0 Gigibit Ethernet",
+       .bind = ax88179_bind,
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+       .reset = ax88179_reset,
+       .stop = ax88179_stop,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+       .tx_fixup = ax88179_tx_fixup,
+};
+
+static const struct driver_info sitecom_info = {
+       .description = "Sitecom USB 3.0 to Gigabit Adapter",
+       .bind = ax88179_bind,
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+       .reset = ax88179_reset,
+       .stop = ax88179_stop,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+       .tx_fixup = ax88179_tx_fixup,
+};
+
+static const struct usb_device_id products[] = {
+{
+       /* ASIX AX88179 10/100/1000 */
+       USB_DEVICE(0x0b95, 0x1790),
+       .driver_info = (unsigned long)&ax88179_info,
+}, {
+       /* ASIX AX88178A 10/100/1000 */
+       USB_DEVICE(0x0b95, 0x178a),
+       .driver_info = (unsigned long)&ax88178a_info,
+}, {
+       /* Sitecom USB 3.0 to Gigabit Adapter */
+       USB_DEVICE(0x0df6, 0x0072),
+       .driver_info = (unsigned long) &sitecom_info,
+},
+       { },
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver ax88179_178a_driver = {
+       .name =         "ax88179_178a",
+       .id_table =     products,
+       .probe =        usbnet_probe,
+       .suspend =      ax88179_suspend,
+       .resume =       ax88179_resume,
+       .disconnect =   usbnet_disconnect,
+       .supports_autosuspend = 1,
+       .disable_hub_initiated_lpm = 1,
+};
+
+module_usb_driver(ax88179_178a_driver);
+
+MODULE_DESCRIPTION("ASIX AX88179/178A based USB 3.0/2.0 Gigabit Ethernet Devices");
+MODULE_LICENSE("GPL");
index 4a8c25a222940d3061b61336976db5f1e80aef58..61b74a2b89ac4fbcf2ac494fc0045645efc379a0 100644 (file)
@@ -1213,6 +1213,14 @@ static const struct usb_device_id cdc_devs[] = {
          .driver_info = (unsigned long) &wwan_info,
        },
 
+       /* tag Huawei devices as wwan */
+       { USB_VENDOR_AND_INTERFACE_INFO(0x12d1,
+                                       USB_CLASS_COMM,
+                                       USB_CDC_SUBCLASS_NCM,
+                                       USB_CDC_PROTO_NONE),
+         .driver_info = (unsigned long)&wwan_info,
+       },
+
        /* Huawei NCM devices disguised as vendor specific */
        { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16),
          .driver_info = (unsigned long)&wwan_info,
index 5f845beeb18b86210d3aebf9f52fdcfff87e1462..050ca4a4850d9b874ef1ddd271a2c2abd4fd9644 100644 (file)
@@ -27,7 +27,7 @@
 #define WME_MAX_BA              WME_BA_BMP_SIZE
 #define ATH_TID_MAX_BUFS        (2 * WME_MAX_BA)
 
-#define ATH_RSSI_DUMMY_MARKER   0x127
+#define ATH_RSSI_DUMMY_MARKER   127
 #define ATH_RSSI_LPF_LEN               10
 #define RSSI_LPF_THRESHOLD             -20
 #define ATH_RSSI_EP_MULTIPLIER     (1<<7)
index 96bfb18078fa14b0013d4b3e93e7544b16639746..d3b099d7898b692b181029c808d41969554035ee 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/firmware.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/etherdevice.h>
 #include <linux/leds.h>
 #include <linux/slab.h>
 #include <net/mac80211.h>
index 3ad1fd05c5e769fc429325377470c888edb354a2..bd8251c1c7494fe69a140d4089d6d2d586c0eaae 100644 (file)
@@ -1067,15 +1067,19 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
 
        last_rssi = priv->rx.last_rssi;
 
-       if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
-               rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi,
-                                                    ATH_RSSI_EP_MULTIPLIER);
+       if (ieee80211_is_beacon(hdr->frame_control) &&
+           !is_zero_ether_addr(common->curbssid) &&
+           ether_addr_equal(hdr->addr3, common->curbssid)) {
+               s8 rssi = rxbuf->rxstatus.rs_rssi;
 
-       if (rxbuf->rxstatus.rs_rssi < 0)
-               rxbuf->rxstatus.rs_rssi = 0;
+               if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
+                       rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER);
 
-       if (ieee80211_is_beacon(fc))
-               priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
+               if (rssi < 0)
+                       rssi = 0;
+
+               priv->ah->stats.avgbrssi = rssi;
+       }
 
        rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
        rx_status->band = hw->conf.channel->band;
index 2a2ae403e0e5202a996fab3e1a7cf9ebecfa2c0a..07e25260c31d85084c8c680f69cda6ac85264e21 100644 (file)
@@ -1463,7 +1463,9 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah,
                        reset_type = ATH9K_RESET_POWER_ON;
                else
                        reset_type = ATH9K_RESET_COLD;
-       }
+       } else if (ah->chip_fullsleep || REG_READ(ah, AR_Q_TXE) ||
+                  (REG_READ(ah, AR_CR) & AR_CR_RXE))
+               reset_type = ATH9K_RESET_COLD;
 
        if (!ath9k_hw_set_reset_reg(ah, reset_type))
                return false;
index 9a0f45ec9e01e2456610e28d0f760ce7d890451e..10f01793d7a605cf4dc7e4d6312ac4af8f4caa64 100644 (file)
@@ -349,25 +349,23 @@ TRACE_EVENT(iwlwifi_dev_rx_data,
 TRACE_EVENT(iwlwifi_dev_hcmd,
        TP_PROTO(const struct device *dev,
                 struct iwl_host_cmd *cmd, u16 total_size,
-                const void *hdr, size_t hdr_len),
-       TP_ARGS(dev, cmd, total_size, hdr, hdr_len),
+                struct iwl_cmd_header *hdr),
+       TP_ARGS(dev, cmd, total_size, hdr),
        TP_STRUCT__entry(
                DEV_ENTRY
                __dynamic_array(u8, hcmd, total_size)
                __field(u32, flags)
        ),
        TP_fast_assign(
-               int i, offset = hdr_len;
+               int i, offset = sizeof(*hdr);
 
                DEV_ASSIGN;
                __entry->flags = cmd->flags;
-               memcpy(__get_dynamic_array(hcmd), hdr, hdr_len);
+               memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr));
 
                for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
                        if (!cmd->len[i])
                                continue;
-                       if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
-                               continue;
                        memcpy((u8 *)__get_dynamic_array(hcmd) + offset,
                               cmd->data[i], cmd->len[i]);
                        offset += cmd->len[i];
index 14fc8d39fc28e81c1cb11487b3820374c5807848..3392011a876841bae6ac4d75eb11fa4a764cc07b 100644 (file)
@@ -136,12 +136,6 @@ struct iwl_calib_res_notif_phy_db {
        u8 data[];
 } __packed;
 
-#define IWL_PHY_DB_STATIC_PIC cpu_to_le32(0x21436587)
-static inline void iwl_phy_db_test_pic(__le32 pic)
-{
-       WARN_ON(IWL_PHY_DB_STATIC_PIC != pic);
-}
-
 struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans)
 {
        struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db),
@@ -260,11 +254,6 @@ int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt,
                        (size - CHANNEL_NUM_SIZE) / phy_db->channel_num;
        }
 
-       /* Test PIC */
-       if (type != IWL_PHY_DB_CFG)
-               iwl_phy_db_test_pic(*(((__le32 *)phy_db_notif->data) +
-                                     (size / sizeof(__le32)) - 1));
-
        IWL_DEBUG_INFO(phy_db->trans,
                       "%s(%d): [PHYDB]SET: Type %d , Size: %d\n",
                       __func__, __LINE__, type, size);
@@ -372,11 +361,6 @@ int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db,
                *size = entry->size;
        }
 
-       /* Test PIC */
-       if (type != IWL_PHY_DB_CFG)
-               iwl_phy_db_test_pic(*(((__le32 *)*data) +
-                                     (*size / sizeof(__le32)) - 1));
-
        IWL_DEBUG_INFO(phy_db->trans,
                       "%s(%d): [PHYDB] GET: Type %d , Size: %d\n",
                       __func__, __LINE__, type, *size);
index c64d864799cd49659acf6c2498aba7b62ca35891..994c8c263dc0e6744afa176e0be5ef4e89d6638d 100644 (file)
@@ -61,6 +61,7 @@
  *
  *****************************************************************************/
 
+#include <linux/etherdevice.h>
 #include <net/cfg80211.h>
 #include <net/ipv6.h>
 #include "iwl-modparams.h"
@@ -192,6 +193,11 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
                                           sizeof(wkc), &wkc);
                data->error = ret != 0;
 
+               mvm->ptk_ivlen = key->iv_len;
+               mvm->ptk_icvlen = key->icv_len;
+               mvm->gtk_ivlen = key->iv_len;
+               mvm->gtk_icvlen = key->icv_len;
+
                /* don't upload key again */
                goto out_unlock;
        }
@@ -304,9 +310,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
         */
        if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
                key->hw_key_idx = 0;
+               mvm->ptk_ivlen = key->iv_len;
+               mvm->ptk_icvlen = key->icv_len;
        } else {
                data->gtk_key_idx++;
                key->hw_key_idx = data->gtk_key_idx;
+               mvm->gtk_ivlen = key->iv_len;
+               mvm->gtk_icvlen = key->icv_len;
        }
 
        ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true);
@@ -649,6 +659,11 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
        /* We reprogram keys and shouldn't allocate new key indices */
        memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
 
+       mvm->ptk_ivlen = 0;
+       mvm->ptk_icvlen = 0;
+       mvm->ptk_ivlen = 0;
+       mvm->ptk_icvlen = 0;
+
        /*
         * The D3 firmware still hardcodes the AP station ID for the
         * BSS we're associated with as 0. As a result, we have to move
@@ -783,7 +798,6 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
        struct iwl_wowlan_status *status;
        u32 reasons;
        int ret, len;
-       bool pkt8023 = false;
        struct sk_buff *pkt = NULL;
 
        iwl_trans_read_mem_bytes(mvm->trans, base,
@@ -824,7 +838,8 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
        status = (void *)cmd.resp_pkt->data;
 
        if (len - sizeof(struct iwl_cmd_header) !=
-           sizeof(*status) + le32_to_cpu(status->wake_packet_bufsize)) {
+           sizeof(*status) +
+           ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4)) {
                IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
                goto out;
        }
@@ -836,61 +851,96 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
                goto report;
        }
 
-       if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) {
+       if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET)
                wakeup.magic_pkt = true;
-               pkt8023 = true;
-       }
 
-       if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) {
+       if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN)
                wakeup.pattern_idx =
                        le16_to_cpu(status->pattern_number);
-               pkt8023 = true;
-       }
 
        if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
                       IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH))
                wakeup.disconnect = true;
 
-       if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) {
+       if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE)
                wakeup.gtk_rekey_failure = true;
-               pkt8023 = true;
-       }
 
-       if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) {
+       if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
                wakeup.rfkill_release = true;
-               pkt8023 = true;
-       }
 
-       if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) {
+       if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST)
                wakeup.eap_identity_req = true;
-               pkt8023 = true;
-       }
 
-       if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) {
+       if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE)
                wakeup.four_way_handshake = true;
-               pkt8023 = true;
-       }
 
        if (status->wake_packet_bufsize) {
-               u32 pktsize = le32_to_cpu(status->wake_packet_bufsize);
-               u32 pktlen = le32_to_cpu(status->wake_packet_length);
+               int pktsize = le32_to_cpu(status->wake_packet_bufsize);
+               int pktlen = le32_to_cpu(status->wake_packet_length);
+               const u8 *pktdata = status->wake_packet;
+               struct ieee80211_hdr *hdr = (void *)pktdata;
+               int truncated = pktlen - pktsize;
+
+               /* this would be a firmware bug */
+               if (WARN_ON_ONCE(truncated < 0))
+                       truncated = 0;
+
+               if (ieee80211_is_data(hdr->frame_control)) {
+                       int hdrlen = ieee80211_hdrlen(hdr->frame_control);
+                       int ivlen = 0, icvlen = 4; /* also FCS */
 
-               if (pkt8023) {
                        pkt = alloc_skb(pktsize, GFP_KERNEL);
                        if (!pkt)
                                goto report;
-                       memcpy(skb_put(pkt, pktsize), status->wake_packet,
-                              pktsize);
+
+                       memcpy(skb_put(pkt, hdrlen), pktdata, hdrlen);
+                       pktdata += hdrlen;
+                       pktsize -= hdrlen;
+
+                       if (ieee80211_has_protected(hdr->frame_control)) {
+                               if (is_multicast_ether_addr(hdr->addr1)) {
+                                       ivlen = mvm->gtk_ivlen;
+                                       icvlen += mvm->gtk_icvlen;
+                               } else {
+                                       ivlen = mvm->ptk_ivlen;
+                                       icvlen += mvm->ptk_icvlen;
+                               }
+                       }
+
+                       /* if truncated, FCS/ICV is (partially) gone */
+                       if (truncated >= icvlen) {
+                               icvlen = 0;
+                               truncated -= icvlen;
+                       } else {
+                               icvlen -= truncated;
+                               truncated = 0;
+                       }
+
+                       pktsize -= ivlen + icvlen;
+                       pktdata += ivlen;
+
+                       memcpy(skb_put(pkt, pktsize), pktdata, pktsize);
+
                        if (ieee80211_data_to_8023(pkt, vif->addr, vif->type))
                                goto report;
                        wakeup.packet = pkt->data;
                        wakeup.packet_present_len = pkt->len;
-                       wakeup.packet_len = pkt->len - (pktlen - pktsize);
+                       wakeup.packet_len = pkt->len - truncated;
                        wakeup.packet_80211 = false;
                } else {
+                       int fcslen = 4;
+
+                       if (truncated >= 4) {
+                               truncated -= 4;
+                               fcslen = 0;
+                       } else {
+                               fcslen -= truncated;
+                               truncated = 0;
+                       }
+                       pktsize -= fcslen;
                        wakeup.packet = status->wake_packet;
                        wakeup.packet_present_len = pktsize;
-                       wakeup.packet_len = pktlen;
+                       wakeup.packet_len = pktlen - truncated;
                        wakeup.packet_80211 = true;
                }
        }
index e8264e11b12da0d2ab33108ff2cf8676ecd61825..7e169b085afe05f1c4c5a17804e864d8bc15e9f2 100644 (file)
@@ -557,11 +557,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
        return ret;
 }
 
-static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
-                                        struct ieee80211_vif *vif)
+static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
+                                       struct ieee80211_vif *vif)
 {
-       struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
-       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        u32 tfd_msk = 0, ac;
 
        for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
@@ -594,12 +592,21 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
                 */
                flush_work(&mvm->sta_drained_wk);
        }
+}
+
+static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
+                                        struct ieee80211_vif *vif)
+{
+       struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+       iwl_mvm_prepare_mac_removal(mvm, vif);
 
        mutex_lock(&mvm->mutex);
 
        /*
         * For AP/GO interface, the tear down of the resources allocated to the
-        * interface should be handled as part of the bss_info_changed flow.
+        * interface is be handled as part of the stop_ap flow.
         */
        if (vif->type == NL80211_IFTYPE_AP) {
                iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
@@ -763,6 +770,8 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 
+       iwl_mvm_prepare_mac_removal(mvm, vif);
+
        mutex_lock(&mvm->mutex);
 
        mvmvif->ap_active = false;
index 4e339ccfa8005e6afd5f7d549982906cff9004aa..537711b1047865cf42fb9ed271369917c4f736fb 100644 (file)
@@ -327,6 +327,10 @@ struct iwl_mvm {
        struct led_classdev led;
 
        struct ieee80211_vif *p2p_device_vif;
+
+#ifdef CONFIG_PM_SLEEP
+       int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
+#endif
 };
 
 /* Extract MVM priv from op_mode and _hw */
index aa2a39a637ddebb15e2b1f390eaa84c839af3dda..3d62e8055352b667ee4a776f4d218d7d4d3431ee 100644 (file)
@@ -182,6 +182,15 @@ struct iwl_queue {
 #define TFD_TX_CMD_SLOTS 256
 #define TFD_CMD_SLOTS 32
 
+/*
+ * The FH will write back to the first TB only, so we need
+ * to copy some data into the buffer regardless of whether
+ * it should be mapped or not. This indicates how much to
+ * copy, even for HCMDs it must be big enough to fit the
+ * DRAM scratch from the TX cmd, at least 16 bytes.
+ */
+#define IWL_HCMD_MIN_COPY_SIZE 16
+
 struct iwl_pcie_txq_entry {
        struct iwl_device_cmd *cmd;
        struct iwl_device_cmd *copy_cmd;
index 8e9e3212fe784bcc8c3aea8007111669bee2441b..8b625a7f56859a32523e73f1e502d967f65d8aea 100644 (file)
@@ -1152,10 +1152,12 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
        void *dup_buf = NULL;
        dma_addr_t phys_addr;
        int idx;
-       u16 copy_size, cmd_size;
+       u16 copy_size, cmd_size, dma_size;
        bool had_nocopy = false;
        int i;
        u32 cmd_pos;
+       const u8 *cmddata[IWL_MAX_CMD_TFDS];
+       u16 cmdlen[IWL_MAX_CMD_TFDS];
 
        copy_size = sizeof(out_cmd->hdr);
        cmd_size = sizeof(out_cmd->hdr);
@@ -1164,8 +1166,23 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
        BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1);
 
        for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+               cmddata[i] = cmd->data[i];
+               cmdlen[i] = cmd->len[i];
+
                if (!cmd->len[i])
                        continue;
+
+               /* need at least IWL_HCMD_MIN_COPY_SIZE copied */
+               if (copy_size < IWL_HCMD_MIN_COPY_SIZE) {
+                       int copy = IWL_HCMD_MIN_COPY_SIZE - copy_size;
+
+                       if (copy > cmdlen[i])
+                               copy = cmdlen[i];
+                       cmdlen[i] -= copy;
+                       cmddata[i] += copy;
+                       copy_size += copy;
+               }
+
                if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) {
                        had_nocopy = true;
                        if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) {
@@ -1185,7 +1202,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
                                goto free_dup_buf;
                        }
 
-                       dup_buf = kmemdup(cmd->data[i], cmd->len[i],
+                       dup_buf = kmemdup(cmddata[i], cmdlen[i],
                                          GFP_ATOMIC);
                        if (!dup_buf)
                                return -ENOMEM;
@@ -1195,7 +1212,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
                                idx = -EINVAL;
                                goto free_dup_buf;
                        }
-                       copy_size += cmd->len[i];
+                       copy_size += cmdlen[i];
                }
                cmd_size += cmd->len[i];
        }
@@ -1242,14 +1259,31 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
 
        /* and copy the data that needs to be copied */
        cmd_pos = offsetof(struct iwl_device_cmd, payload);
+       copy_size = sizeof(out_cmd->hdr);
        for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
-               if (!cmd->len[i])
+               int copy = 0;
+
+               if (!cmd->len)
                        continue;
-               if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
-                                        IWL_HCMD_DFL_DUP))
-                       break;
-               memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]);
-               cmd_pos += cmd->len[i];
+
+               /* need at least IWL_HCMD_MIN_COPY_SIZE copied */
+               if (copy_size < IWL_HCMD_MIN_COPY_SIZE) {
+                       copy = IWL_HCMD_MIN_COPY_SIZE - copy_size;
+
+                       if (copy > cmd->len[i])
+                               copy = cmd->len[i];
+               }
+
+               /* copy everything if not nocopy/dup */
+               if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
+                                          IWL_HCMD_DFL_DUP)))
+                       copy = cmd->len[i];
+
+               if (copy) {
+                       memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy);
+                       cmd_pos += copy;
+                       copy_size += copy;
+               }
        }
 
        WARN_ON_ONCE(txq->entries[idx].copy_cmd);
@@ -1275,7 +1309,14 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
                     out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
                     cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue);
 
-       phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size,
+       /*
+        * If the entire command is smaller than IWL_HCMD_MIN_COPY_SIZE, we must
+        * still map at least that many bytes for the hardware to write back to.
+        * We have enough space, so that's not a problem.
+        */
+       dma_size = max_t(u16, copy_size, IWL_HCMD_MIN_COPY_SIZE);
+
+       phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, dma_size,
                                   DMA_BIDIRECTIONAL);
        if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
                idx = -ENOMEM;
@@ -1283,14 +1324,15 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
        }
 
        dma_unmap_addr_set(out_meta, mapping, phys_addr);
-       dma_unmap_len_set(out_meta, len, copy_size);
+       dma_unmap_len_set(out_meta, len, dma_size);
 
        iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1);
 
+       /* map the remaining (adjusted) nocopy/dup fragments */
        for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
-               const void *data = cmd->data[i];
+               const void *data = cmddata[i];
 
-               if (!cmd->len[i])
+               if (!cmdlen[i])
                        continue;
                if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
                                           IWL_HCMD_DFL_DUP)))
@@ -1298,7 +1340,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
                if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP)
                        data = dup_buf;
                phys_addr = dma_map_single(trans->dev, (void *)data,
-                                          cmd->len[i], DMA_BIDIRECTIONAL);
+                                          cmdlen[i], DMA_BIDIRECTIONAL);
                if (dma_mapping_error(trans->dev, phys_addr)) {
                        iwl_pcie_tfd_unmap(trans, out_meta,
                                           &txq->tfds[q->write_ptr],
@@ -1307,7 +1349,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
                        goto out;
                }
 
-               iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0);
+               iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], 0);
        }
 
        out_meta->flags = cmd->flags;
@@ -1317,8 +1359,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
 
        txq->need_update = 1;
 
-       trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size,
-                              &out_cmd->hdr, copy_size);
+       trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr);
 
        /* start timer if queue currently empty */
        if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout)
index 739309e70d8be7872e9272c9e25dcb7e3a5b2a4a..45578335e4200f2f47a3fc8284f9bd09127209ee 100644 (file)
@@ -825,6 +825,11 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card)
 
        sdio_release_host(func);
 
+       /* Set fw_ready before queuing any commands so that
+        * lbs_thread won't block from sending them to firmware.
+        */
+       priv->fw_ready = 1;
+
        /*
         * FUNC_INIT is required for SD8688 WLAN/BT multiple functions
         */
@@ -839,7 +844,6 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card)
                        netdev_alert(priv->dev, "CMD_FUNC_INIT cmd failed\n");
        }
 
-       priv->fw_ready = 1;
        wake_up(&card->pwron_waitq);
 
        if (!card->started) {
index 35c79722c361f0e6165071e986af4c5e3f3b8ea3..5c395e2e6a2b874fb0257424663a73cb7abf0c17 100644 (file)
@@ -302,7 +302,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
                i++;
                usleep_range(10, 20);
                /* 50ms max wait */
-               if (i == 50000)
+               if (i == 5000)
                        break;
        }
 
index 1031db66474a6403e67ab5a8f5789820343ac1a6..189744db65e073ec96ff396d7ae8fee46a3c3fcd 100644 (file)
@@ -1236,8 +1236,10 @@ static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev)
         */
        if_limit = &rt2x00dev->if_limits_ap;
        if_limit->max = rt2x00dev->ops->max_ap_intf;
-       if_limit->types = BIT(NL80211_IFTYPE_AP) |
-                       BIT(NL80211_IFTYPE_MESH_POINT);
+       if_limit->types = BIT(NL80211_IFTYPE_AP);
+#ifdef CONFIG_MAC80211_MESH
+       if_limit->types |= BIT(NL80211_IFTYPE_MESH_POINT);
+#endif
 
        /*
         * Build up AP interface combinations structure.
@@ -1309,7 +1311,9 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
                rt2x00dev->hw->wiphy->interface_modes |=
                    BIT(NL80211_IFTYPE_ADHOC) |
                    BIT(NL80211_IFTYPE_AP) |
+#ifdef CONFIG_MAC80211_MESH
                    BIT(NL80211_IFTYPE_MESH_POINT) |
+#endif
                    BIT(NL80211_IFTYPE_WDS);
 
        rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
index 445ffda715ade70884bf52dda1bd3e0391b6bd5a..7c12d9c2b23010a54c2752a0abac70b1bcf17735 100644 (file)
@@ -276,6 +276,7 @@ static struct file_system_type oprofilefs_type = {
        .mount          = oprofilefs_mount,
        .kill_sb        = kill_litter_super,
 };
+MODULE_ALIAS_FS("oprofilefs");
 
 
 int __init oprofilefs_register(void)
index 39c937f9b426ef392e3820ee2c7f69e128da403e..dee5dddaa292a04ad2200c005ad59b959ed5ad7e 100644 (file)
@@ -331,8 +331,14 @@ static void pci_acpi_cleanup(struct device *dev)
        }
 }
 
+static bool pci_acpi_bus_match(struct device *dev)
+{
+       return dev->bus == &pci_bus_type;
+}
+
 static struct acpi_bus_type acpi_pci_bus = {
-       .bus = &pci_bus_type,
+       .name = "PCI",
+       .match = pci_acpi_bus_match,
        .find_device = acpi_pci_find_device,
        .setup = pci_acpi_setup,
        .cleanup = pci_acpi_cleanup,
index 93d66809355a203e97b0e4229f5dc2ac932d2e54..3e5b4497a1d02010b4c63bdc939f67127bb19976 100644 (file)
@@ -23,6 +23,9 @@
 
 #include <linux/dmi.h>
 #include <linux/i2c.h>
+#include <linux/i2c/atmel_mxt_ts.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
 #include <linux/module.h>
 
 #define ATMEL_TP_I2C_ADDR      0x4b
@@ -67,15 +70,49 @@ static struct i2c_board_info __initdata tsl2563_als_device = {
        I2C_BOARD_INFO("tsl2563", TAOS_ALS_I2C_ADDR),
 };
 
+static struct mxt_platform_data atmel_224s_tp_platform_data = {
+       .x_line                 = 18,
+       .y_line                 = 12,
+       .x_size                 = 102*20,
+       .y_size                 = 68*20,
+       .blen                   = 0x80, /* Gain setting is in upper 4 bits */
+       .threshold              = 0x32,
+       .voltage                = 0,    /* 3.3V */
+       .orient                 = MXT_VERTICAL_FLIP,
+       .irqflags               = IRQF_TRIGGER_FALLING,
+       .is_tp                  = true,
+       .key_map                = { KEY_RESERVED,
+                                   KEY_RESERVED,
+                                   KEY_RESERVED,
+                                   BTN_LEFT },
+       .config                 = NULL,
+       .config_length          = 0,
+};
+
 static struct i2c_board_info __initdata atmel_224s_tp_device = {
        I2C_BOARD_INFO("atmel_mxt_tp", ATMEL_TP_I2C_ADDR),
-       .platform_data = NULL,
+       .platform_data = &atmel_224s_tp_platform_data,
        .flags          = I2C_CLIENT_WAKE,
 };
 
+static struct mxt_platform_data atmel_1664s_platform_data = {
+       .x_line                 = 32,
+       .y_line                 = 50,
+       .x_size                 = 1700,
+       .y_size                 = 2560,
+       .blen                   = 0x89, /* Gain setting is in upper 4 bits */
+       .threshold              = 0x28,
+       .voltage                = 0,    /* 3.3V */
+       .orient                 = MXT_ROTATED_90_COUNTER,
+       .irqflags               = IRQF_TRIGGER_FALLING,
+       .is_tp                  = false,
+       .config                 = NULL,
+       .config_length          = 0,
+};
+
 static struct i2c_board_info __initdata atmel_1664s_device = {
        I2C_BOARD_INFO("atmel_mxt_ts", ATMEL_TS_I2C_ADDR),
-       .platform_data = NULL,
+       .platform_data = &atmel_1664s_platform_data,
        .flags          = I2C_CLIENT_WAKE,
 };
 
index 8813fc03aa099fbb37b3a2321160fef4cdd51ef0..55cd459a39080d6d162074c74772e9850d88c8f1 100644 (file)
@@ -353,8 +353,14 @@ static int __init acpi_pnp_find_device(struct device *dev, acpi_handle * handle)
 /* complete initialization of a PNPACPI device includes having
  * pnpdev->dev.archdata.acpi_handle point to its ACPI sibling.
  */
+static bool acpi_pnp_bus_match(struct device *dev)
+{
+       return dev->bus == &pnp_bus_type;
+}
+
 static struct acpi_bus_type __initdata acpi_pnp_bus = {
-       .bus         = &pnp_bus_type,
+       .name        = "PNP",
+       .match       = acpi_pnp_bus_match,
        .find_device = acpi_pnp_find_device,
 };
 
index da9782bd27d0a182d32578c4779481072d0657ef..e3661c20cf389fe38bcbb9406f25476aae9d4796 100644 (file)
@@ -2830,7 +2830,7 @@ EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap);
  * regulator_allow_bypass - allow the regulator to go into bypass mode
  *
  * @regulator: Regulator to configure
- * @allow: enable or disable bypass mode
+ * @enable: enable or disable bypass mode
  *
  * Allow the regulator to go into bypass mode if all other consumers
  * for the regulator also enable bypass mode and the machine
@@ -3057,9 +3057,13 @@ int regulator_bulk_enable(int num_consumers,
        return 0;
 
 err:
-       pr_err("Failed to enable %s: %d\n", consumers[i].supply, ret);
-       while (--i >= 0)
-               regulator_disable(consumers[i].consumer);
+       for (i = 0; i < num_consumers; i++) {
+               if (consumers[i].ret < 0)
+                       pr_err("Failed to enable %s: %d\n", consumers[i].supply,
+                              consumers[i].ret);
+               else
+                       regulator_disable(consumers[i].consumer);
+       }
 
        return ret;
 }
index 219d162b651e3c75f2077517e5b3e0b69c28100f..a53c11a529d5f65dc55e6790167c4d69f5c68de0 100644 (file)
@@ -528,7 +528,7 @@ static int db8500_regulator_probe(struct platform_device *pdev)
        return 0;
 }
 
-static int __exit db8500_regulator_remove(struct platform_device *pdev)
+static int db8500_regulator_remove(struct platform_device *pdev)
 {
        int i;
 
@@ -553,7 +553,7 @@ static struct platform_driver db8500_regulator_driver = {
                .owner = THIS_MODULE,
        },
        .probe = db8500_regulator_probe,
-       .remove = __exit_p(db8500_regulator_remove),
+       .remove = db8500_regulator_remove,
 };
 
 static int __init db8500_regulator_init(void)
index cde13bb5a8fbc4163eb7769b9b7e09e90eaf1d75..39cf14606784bd3571c6aab2d361807d0bdf7c99 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright 2011-2012 Texas Instruments Inc.
  *
  * Author: Graeme Gregory <gg@slimlogic.co.uk>
+ * Author: Ian Lartey <ian@slimlogic.co.uk>
  *
  *  This program is free software; you can redistribute it and/or modify it
  *  under  the terms of the GNU General  Public License as published by the
@@ -156,7 +157,7 @@ static const struct regs_info palmas_regs_info[] = {
  *
  * So they are basically (maxV-minV)/stepV
  */
-#define PALMAS_SMPS_NUM_VOLTAGES       116
+#define PALMAS_SMPS_NUM_VOLTAGES       117
 #define PALMAS_SMPS10_NUM_VOLTAGES     2
 #define PALMAS_LDO_NUM_VOLTAGES                50
 
index 74508cc62d67baafcc39fb3face73f1e7a810d90..f705d25b437ccfc57a144a600d6993ce926869c1 100644 (file)
@@ -471,24 +471,23 @@ twl4030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
                            selector);
 }
 
-static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
+static int twl4030ldo_get_voltage_sel(struct regulator_dev *rdev)
 {
        struct twlreg_info      *info = rdev_get_drvdata(rdev);
-       int             vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER,
-                                                               VREG_VOLTAGE);
+       int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE);
 
        if (vsel < 0)
                return vsel;
 
        vsel &= info->table_len - 1;
-       return LDO_MV(info->table[vsel]) * 1000;
+       return vsel;
 }
 
 static struct regulator_ops twl4030ldo_ops = {
        .list_voltage   = twl4030ldo_list_voltage,
 
        .set_voltage_sel = twl4030ldo_set_voltage_sel,
-       .get_voltage    = twl4030ldo_get_voltage,
+       .get_voltage_sel = twl4030ldo_get_voltage_sel,
 
        .enable         = twl4030reg_enable,
        .disable        = twl4030reg_disable,
index 765398c063c7f751f383a279ac7ddaa9f841a05c..c31187d79343a17af26404a2d6c547dc392ae151 100644 (file)
@@ -71,9 +71,14 @@ struct kmem_cache *scsi_sdb_cache;
 #ifdef CONFIG_ACPI
 #include <acpi/acpi_bus.h>
 
+static bool acpi_scsi_bus_match(struct device *dev)
+{
+       return dev->bus == &scsi_bus_type;
+}
+
 int scsi_register_acpi_bus_type(struct acpi_bus_type *bus)
 {
-        bus->bus = &scsi_bus_type;
+        bus->match = acpi_scsi_bus_match;
         return register_acpi_bus_type(bus);
 }
 EXPORT_SYMBOL_GPL(scsi_register_acpi_bus_type);
index 8adc79d1b40277ac15092a53bac28749627c60cf..f6373dade7fb056f78ae49a1674b6b747f367fb2 100644 (file)
@@ -1223,6 +1223,7 @@ static struct file_system_type ffs_fs_type = {
        .mount          = ffs_fs_mount,
        .kill_sb        = ffs_fs_kill_sb,
 };
+MODULE_ALIAS_FS("functionfs");
 
 
 /* Driver's main init/cleanup functions *************************************/
index 1956593ee89d17b13d24e13c725eef8dd59cf7e7..81e939e90c4c44f7ead9bad36eac03f98f998421 100644 (file)
@@ -881,17 +881,12 @@ static struct vio_driver hvcs_vio_driver = {
 /* Only called from hvcs_get_pi please */
 static void hvcs_set_pi(struct hvcs_partner_info *pi, struct hvcs_struct *hvcsd)
 {
-       int clclength;
-
        hvcsd->p_unit_address = pi->unit_address;
        hvcsd->p_partition_ID  = pi->partition_ID;
-       clclength = strlen(&pi->location_code[0]);
-       if (clclength > HVCS_CLC_LENGTH)
-               clclength = HVCS_CLC_LENGTH;
 
        /* copy the null-term char too */
-       strncpy(&hvcsd->p_location_code[0],
-                       &pi->location_code[0], clclength + 1);
+       strlcpy(&hvcsd->p_location_code[0],
+                       &pi->location_code[0], sizeof(hvcsd->p_location_code));
 }
 
 /*
index cef4252bb31a3c4cfcc1ccd4ce6338bde51fd33d..b6f4bad3f756eefb173097767ffde6970e06220e 100644 (file)
@@ -210,9 +210,14 @@ static int usb_acpi_find_device(struct device *dev, acpi_handle *handle)
        return 0;
 }
 
+static bool usb_acpi_bus_match(struct device *dev)
+{
+       return is_usb_device(dev) || is_usb_port(dev);
+}
+
 static struct acpi_bus_type usb_acpi_bus = {
-       .bus = &usb_bus_type,
-       .find_bridge = usb_acpi_find_device,
+       .name = "USB",
+       .match = usb_acpi_bus_match,
        .find_device = usb_acpi_find_device,
 };
 
index 38388d7844fc75ff2287f3be4502b69b797efd28..c377ff84bf2cf39f7b39dfbedc1c93db971848a5 100644 (file)
@@ -1235,6 +1235,7 @@ static struct file_system_type ffs_fs_type = {
        .mount          = ffs_fs_mount,
        .kill_sb        = ffs_fs_kill_sb,
 };
+MODULE_ALIAS_FS("functionfs");
 
 
 /* Driver's main init/cleanup functions *************************************/
index 8ac840f25ba9641f2939f807af8f4d768169702e..e2b2e9cf254a8c9a6c464c80f067e6a7a81af467 100644 (file)
@@ -2105,6 +2105,7 @@ static struct file_system_type gadgetfs_type = {
        .mount          = gadgetfs_mount,
        .kill_sb        = gadgetfs_kill_sb,
 };
+MODULE_ALIAS_FS("gadgetfs");
 
 /*----------------------------------------------------------------------*/
 
index ec0abb6df3c303fa7ace7b0e8b6e018f39ce8fb7..71679875f056ccaf92eafba1b0a194cd7f177429 100644 (file)
@@ -75,6 +75,7 @@ static struct file_system_type xenfs_type = {
        .mount =        xenfs_mount,
        .kill_sb =      kill_litter_super,
 };
+MODULE_ALIAS_FS("xenfs");
 
 static int __init xenfs_init(void)
 {
index 91dad63e5a2db0cddc1bb9c43ad0bca0694ec9c9..2756dcd5de6e0ed0306e148682bc51d4749e121a 100644 (file)
@@ -365,3 +365,4 @@ struct file_system_type v9fs_fs_type = {
        .owner = THIS_MODULE,
        .fs_flags = FS_RENAME_DOES_D_MOVE,
 };
+MODULE_ALIAS_FS("9p");
index d5712293579376a89a99befc8eb59e5ecded02bb..0ff4bae2c2a2c2372a75bc5486a4920672aef0bf 100644 (file)
@@ -524,6 +524,7 @@ static struct file_system_type adfs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("adfs");
 
 static int __init init_adfs_fs(void)
 {
index b84dc7352502df2976438435b2523f98d5d55966..45161a832bbc9e4aa2d7f6b72a950273e0af7062 100644 (file)
@@ -622,6 +622,7 @@ static struct file_system_type affs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("affs");
 
 static int __init init_affs_fs(void)
 {
index 7c31ec39957587a59062b3f81dd338aa57e575aa..c4861557e38573796dd20237ff90938ee5f1429e 100644 (file)
@@ -45,6 +45,7 @@ struct file_system_type afs_fs_type = {
        .kill_sb        = afs_kill_super,
        .fs_flags       = 0,
 };
+MODULE_ALIAS_FS("afs");
 
 static const struct super_operations afs_super_ops = {
        .statfs         = afs_statfs,
index cddc74b9cdb2d03f6e2203666c86118ef60596c6..b3db517e89ec12b771a77f46deb2572782b83e09 100644 (file)
@@ -26,6 +26,7 @@ static struct file_system_type autofs_fs_type = {
        .mount          = autofs_mount,
        .kill_sb        = autofs4_kill_sb,
 };
+MODULE_ALIAS_FS("autofs");
 
 static int __init init_autofs4_fs(void)
 {
index c8f4e25eb9e2f6e2818b17de47adb4a61e82eeca..8615ee89ab55d8c6d96a26556327b31c3967c0b6 100644 (file)
@@ -951,6 +951,7 @@ static struct file_system_type befs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,      
 };
+MODULE_ALIAS_FS("befs");
 
 static int __init
 init_befs_fs(void)
index 737aaa3f709062a9d8aec826c26e956b18eb2bcf..5e376bb934196d2b8a0e104473c637439e5e2244 100644 (file)
@@ -473,6 +473,7 @@ static struct file_system_type bfs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("bfs");
 
 static int __init init_bfs_fs(void)
 {
index fecbbf3f8ff24340ab4b84e95ace2339a3f631a4..751df5e4f61a71f2a8eac366ebb3e8a040a3fc53 100644 (file)
@@ -720,6 +720,7 @@ static struct file_system_type bm_fs_type = {
        .mount          = bm_mount,
        .kill_sb        = kill_litter_super,
 };
+MODULE_ALIAS_FS("binfmt_misc");
 
 static int __init init_misc_binfmt(void)
 {
index 0b278b117cbe609611764cf45127f89a133eed5f..14fce27b4780803c53d0a04b5b8557c1096e61fb 100644 (file)
@@ -22,8 +22,9 @@
 #include "disk-io.h"
 #include "transaction.h"
 
-#define BTRFS_DELAYED_WRITEBACK                400
-#define BTRFS_DELAYED_BACKGROUND       100
+#define BTRFS_DELAYED_WRITEBACK                512
+#define BTRFS_DELAYED_BACKGROUND       128
+#define BTRFS_DELAYED_BATCH            16
 
 static struct kmem_cache *delayed_node_cache;
 
@@ -494,6 +495,15 @@ static int __btrfs_add_delayed_deletion_item(struct btrfs_delayed_node *node,
                                        BTRFS_DELAYED_DELETION_ITEM);
 }
 
+static void finish_one_item(struct btrfs_delayed_root *delayed_root)
+{
+       int seq = atomic_inc_return(&delayed_root->items_seq);
+       if ((atomic_dec_return(&delayed_root->items) <
+           BTRFS_DELAYED_BACKGROUND || seq % BTRFS_DELAYED_BATCH == 0) &&
+           waitqueue_active(&delayed_root->wait))
+               wake_up(&delayed_root->wait);
+}
+
 static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item)
 {
        struct rb_root *root;
@@ -512,10 +522,8 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item)
 
        rb_erase(&delayed_item->rb_node, root);
        delayed_item->delayed_node->count--;
-       if (atomic_dec_return(&delayed_root->items) <
-           BTRFS_DELAYED_BACKGROUND &&
-           waitqueue_active(&delayed_root->wait))
-               wake_up(&delayed_root->wait);
+
+       finish_one_item(delayed_root);
 }
 
 static void btrfs_release_delayed_item(struct btrfs_delayed_item *item)
@@ -1056,10 +1064,7 @@ static void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node)
                delayed_node->count--;
 
                delayed_root = delayed_node->root->fs_info->delayed_root;
-               if (atomic_dec_return(&delayed_root->items) <
-                   BTRFS_DELAYED_BACKGROUND &&
-                   waitqueue_active(&delayed_root->wait))
-                       wake_up(&delayed_root->wait);
+               finish_one_item(delayed_root);
        }
 }
 
@@ -1304,35 +1309,44 @@ void btrfs_remove_delayed_node(struct inode *inode)
        btrfs_release_delayed_node(delayed_node);
 }
 
-struct btrfs_async_delayed_node {
-       struct btrfs_root *root;
-       struct btrfs_delayed_node *delayed_node;
+struct btrfs_async_delayed_work {
+       struct btrfs_delayed_root *delayed_root;
+       int nr;
        struct btrfs_work work;
 };
 
-static void btrfs_async_run_delayed_node_done(struct btrfs_work *work)
+static void btrfs_async_run_delayed_root(struct btrfs_work *work)
 {
-       struct btrfs_async_delayed_node *async_node;
+       struct btrfs_async_delayed_work *async_work;
+       struct btrfs_delayed_root *delayed_root;
        struct btrfs_trans_handle *trans;
        struct btrfs_path *path;
        struct btrfs_delayed_node *delayed_node = NULL;
        struct btrfs_root *root;
        struct btrfs_block_rsv *block_rsv;
-       int need_requeue = 0;
+       int total_done = 0;
 
-       async_node = container_of(work, struct btrfs_async_delayed_node, work);
+       async_work = container_of(work, struct btrfs_async_delayed_work, work);
+       delayed_root = async_work->delayed_root;
 
        path = btrfs_alloc_path();
        if (!path)
                goto out;
-       path->leave_spinning = 1;
 
-       delayed_node = async_node->delayed_node;
+again:
+       if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND / 2)
+               goto free_path;
+
+       delayed_node = btrfs_first_prepared_delayed_node(delayed_root);
+       if (!delayed_node)
+               goto free_path;
+
+       path->leave_spinning = 1;
        root = delayed_node->root;
 
        trans = btrfs_join_transaction(root);
        if (IS_ERR(trans))
-               goto free_path;
+               goto release_path;
 
        block_rsv = trans->block_rsv;
        trans->block_rsv = &root->fs_info->delayed_block_rsv;
@@ -1363,57 +1377,47 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work)
         * Task1 will sleep until the transaction is commited.
         */
        mutex_lock(&delayed_node->mutex);
-       if (delayed_node->count)
-               need_requeue = 1;
-       else
-               btrfs_dequeue_delayed_node(root->fs_info->delayed_root,
-                                          delayed_node);
+       btrfs_dequeue_delayed_node(root->fs_info->delayed_root, delayed_node);
        mutex_unlock(&delayed_node->mutex);
 
        trans->block_rsv = block_rsv;
        btrfs_end_transaction_dmeta(trans, root);
        btrfs_btree_balance_dirty_nodelay(root);
+
+release_path:
+       btrfs_release_path(path);
+       total_done++;
+
+       btrfs_release_prepared_delayed_node(delayed_node);
+       if (async_work->nr == 0 || total_done < async_work->nr)
+               goto again;
+
 free_path:
        btrfs_free_path(path);
 out:
-       if (need_requeue)
-               btrfs_requeue_work(&async_node->work);
-       else {
-               btrfs_release_prepared_delayed_node(delayed_node);
-               kfree(async_node);
-       }
+       wake_up(&delayed_root->wait);
+       kfree(async_work);
 }
 
+
 static int btrfs_wq_run_delayed_node(struct btrfs_delayed_root *delayed_root,
-                                    struct btrfs_root *root, int all)
+                                    struct btrfs_root *root, int nr)
 {
-       struct btrfs_async_delayed_node *async_node;
-       struct btrfs_delayed_node *curr;
-       int count = 0;
+       struct btrfs_async_delayed_work *async_work;
 
-again:
-       curr = btrfs_first_prepared_delayed_node(delayed_root);
-       if (!curr)
+       if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND)
                return 0;
 
-       async_node = kmalloc(sizeof(*async_node), GFP_NOFS);
-       if (!async_node) {
-               btrfs_release_prepared_delayed_node(curr);
+       async_work = kmalloc(sizeof(*async_work), GFP_NOFS);
+       if (!async_work)
                return -ENOMEM;
-       }
-
-       async_node->root = root;
-       async_node->delayed_node = curr;
-
-       async_node->work.func = btrfs_async_run_delayed_node_done;
-       async_node->work.flags = 0;
 
-       btrfs_queue_worker(&root->fs_info->delayed_workers, &async_node->work);
-       count++;
-
-       if (all || count < 4)
-               goto again;
+       async_work->delayed_root = delayed_root;
+       async_work->work.func = btrfs_async_run_delayed_root;
+       async_work->work.flags = 0;
+       async_work->nr = nr;
 
+       btrfs_queue_worker(&root->fs_info->delayed_workers, &async_work->work);
        return 0;
 }
 
@@ -1424,30 +1428,55 @@ void btrfs_assert_delayed_root_empty(struct btrfs_root *root)
        WARN_ON(btrfs_first_delayed_node(delayed_root));
 }
 
+static int refs_newer(struct btrfs_delayed_root *delayed_root,
+                     int seq, int count)
+{
+       int val = atomic_read(&delayed_root->items_seq);
+
+       if (val < seq || val >= seq + count)
+               return 1;
+       return 0;
+}
+
 void btrfs_balance_delayed_items(struct btrfs_root *root)
 {
        struct btrfs_delayed_root *delayed_root;
+       int seq;
 
        delayed_root = btrfs_get_delayed_root(root);
 
        if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND)
                return;
 
+       seq = atomic_read(&delayed_root->items_seq);
+
        if (atomic_read(&delayed_root->items) >= BTRFS_DELAYED_WRITEBACK) {
                int ret;
-               ret = btrfs_wq_run_delayed_node(delayed_root, root, 1);
+               DEFINE_WAIT(__wait);
+
+               ret = btrfs_wq_run_delayed_node(delayed_root, root, 0);
                if (ret)
                        return;
 
-               wait_event_interruptible_timeout(
-                               delayed_root->wait,
-                               (atomic_read(&delayed_root->items) <
-                                BTRFS_DELAYED_BACKGROUND),
-                               HZ);
-               return;
+               while (1) {
+                       prepare_to_wait(&delayed_root->wait, &__wait,
+                                       TASK_INTERRUPTIBLE);
+
+                       if (refs_newer(delayed_root, seq,
+                                      BTRFS_DELAYED_BATCH) ||
+                           atomic_read(&delayed_root->items) <
+                           BTRFS_DELAYED_BACKGROUND) {
+                               break;
+                       }
+                       if (!signal_pending(current))
+                               schedule();
+                       else
+                               break;
+               }
+               finish_wait(&delayed_root->wait, &__wait);
        }
 
-       btrfs_wq_run_delayed_node(delayed_root, root, 0);
+       btrfs_wq_run_delayed_node(delayed_root, root, BTRFS_DELAYED_BATCH);
 }
 
 /* Will return 0 or -ENOMEM */
index 78b6ad0fc6699c5c59d5f9ccddef641aa80c5d09..1d5c5f7abe3e01bf872913d123f5c43b2797fd2b 100644 (file)
@@ -43,6 +43,7 @@ struct btrfs_delayed_root {
         */
        struct list_head prepare_list;
        atomic_t items;         /* for delayed items */
+       atomic_t items_seq;     /* for delayed items */
        int nodes;              /* for delayed nodes */
        wait_queue_head_t wait;
 };
@@ -86,6 +87,7 @@ static inline void btrfs_init_delayed_root(
                                struct btrfs_delayed_root *delayed_root)
 {
        atomic_set(&delayed_root->items, 0);
+       atomic_set(&delayed_root->items_seq, 0);
        delayed_root->nodes = 0;
        spin_lock_init(&delayed_root->lock);
        init_waitqueue_head(&delayed_root->wait);
index 02369a3c162e0e891a09c3f893f277c5ec907635..7d84651e850b22cb937b29c68d34c1119af1e4a0 100644 (file)
@@ -62,7 +62,7 @@ static void btrfs_destroy_ordered_operations(struct btrfs_transaction *t,
 static void btrfs_destroy_ordered_extents(struct btrfs_root *root);
 static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
                                      struct btrfs_root *root);
-static void btrfs_destroy_pending_snapshots(struct btrfs_transaction *t);
+static void btrfs_evict_pending_snapshots(struct btrfs_transaction *t);
 static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root);
 static int btrfs_destroy_marked_extents(struct btrfs_root *root,
                                        struct extent_io_tree *dirty_pages,
@@ -3687,7 +3687,7 @@ int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
        return ret;
 }
 
-static void btrfs_destroy_pending_snapshots(struct btrfs_transaction *t)
+static void btrfs_evict_pending_snapshots(struct btrfs_transaction *t)
 {
        struct btrfs_pending_snapshot *snapshot;
        struct list_head splice;
@@ -3700,10 +3700,8 @@ static void btrfs_destroy_pending_snapshots(struct btrfs_transaction *t)
                snapshot = list_entry(splice.next,
                                      struct btrfs_pending_snapshot,
                                      list);
-
+               snapshot->error = -ECANCELED;
                list_del_init(&snapshot->list);
-
-               kfree(snapshot);
        }
 }
 
@@ -3840,6 +3838,8 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
        cur_trans->blocked = 1;
        wake_up(&root->fs_info->transaction_blocked_wait);
 
+       btrfs_evict_pending_snapshots(cur_trans);
+
        cur_trans->blocked = 0;
        wake_up(&root->fs_info->transaction_wait);
 
@@ -3849,8 +3849,6 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
        btrfs_destroy_delayed_inodes(root);
        btrfs_assert_delayed_root_empty(root);
 
-       btrfs_destroy_pending_snapshots(cur_trans);
-
        btrfs_destroy_marked_extents(root, &cur_trans->dirty_pages,
                                     EXTENT_DIRTY);
        btrfs_destroy_pinned_extent(root,
@@ -3894,6 +3892,8 @@ int btrfs_cleanup_transaction(struct btrfs_root *root)
                if (waitqueue_active(&root->fs_info->transaction_blocked_wait))
                        wake_up(&root->fs_info->transaction_blocked_wait);
 
+               btrfs_evict_pending_snapshots(t);
+
                t->blocked = 0;
                smp_mb();
                if (waitqueue_active(&root->fs_info->transaction_wait))
@@ -3907,8 +3907,6 @@ int btrfs_cleanup_transaction(struct btrfs_root *root)
                btrfs_destroy_delayed_inodes(root);
                btrfs_assert_delayed_root_empty(root);
 
-               btrfs_destroy_pending_snapshots(t);
-
                btrfs_destroy_delalloc_inodes(root);
 
                spin_lock(&root->fs_info->trans_lock);
index c226daefd65d20a7c635723926f978172f53aaa6..d1470adca8f87aafa6a028995eeac0e91ee781db 100644 (file)
@@ -8502,6 +8502,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
        struct btrfs_key ins;
        u64 cur_offset = start;
        u64 i_size;
+       u64 cur_bytes;
        int ret = 0;
        bool own_trans = true;
 
@@ -8516,8 +8517,9 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
                        }
                }
 
-               ret = btrfs_reserve_extent(trans, root,
-                                          min(num_bytes, 256ULL * 1024 * 1024),
+               cur_bytes = min(num_bytes, 256ULL * 1024 * 1024);
+               cur_bytes = max(cur_bytes, min_size);
+               ret = btrfs_reserve_extent(trans, root, cur_bytes,
                                           min_size, 0, *alloc_hint, &ins, 1);
                if (ret) {
                        if (own_trans)
index c83086fdda055e25f2f9c378ca71fc420f807ed3..2c02310ff2d96320ebf2d348ed339dd0ea047e0f 100644 (file)
@@ -527,6 +527,8 @@ fail:
        if (async_transid) {
                *async_transid = trans->transid;
                err = btrfs_commit_transaction_async(trans, root, 1);
+               if (err)
+                       err = btrfs_commit_transaction(trans, root);
        } else {
                err = btrfs_commit_transaction(trans, root);
        }
@@ -592,16 +594,14 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
                *async_transid = trans->transid;
                ret = btrfs_commit_transaction_async(trans,
                                     root->fs_info->extent_root, 1);
+               if (ret)
+                       ret = btrfs_commit_transaction(trans, root);
        } else {
                ret = btrfs_commit_transaction(trans,
                                               root->fs_info->extent_root);
        }
-       if (ret) {
-               /* cleanup_transaction has freed this for us */
-               if (trans->aborted)
-                       pending_snapshot = NULL;
+       if (ret)
                goto fail;
-       }
 
        ret = pending_snapshot->error;
        if (ret)
@@ -2245,13 +2245,6 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
        if (ret)
                return ret;
 
-       if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running,
-                       1)) {
-               pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n");
-               mnt_drop_write_file(file);
-               return -EINVAL;
-       }
-
        if (btrfs_root_readonly(root)) {
                ret = -EROFS;
                goto out;
@@ -2306,7 +2299,6 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
                ret = -EINVAL;
        }
 out:
-       atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0);
        mnt_drop_write_file(file);
        return ret;
 }
index 50695dc5e2abb273a221a1d03446016b66039c53..b67171e6d688362167fed9db03cdc659b88061ea 100644 (file)
@@ -1269,6 +1269,8 @@ static int __update_reloc_root(struct btrfs_root *root, int del)
        }
        spin_unlock(&rc->reloc_root_tree.lock);
 
+       if (!node)
+               return 0;
        BUG_ON((struct btrfs_root *)node->data != root);
 
        if (!del) {
@@ -2237,6 +2239,21 @@ again:
        return err;
 }
 
+static noinline_for_stack
+void free_reloc_roots(struct list_head *list)
+{
+       struct btrfs_root *reloc_root;
+
+       while (!list_empty(list)) {
+               reloc_root = list_entry(list->next, struct btrfs_root,
+                                       root_list);
+               __update_reloc_root(reloc_root, 1);
+               free_extent_buffer(reloc_root->node);
+               free_extent_buffer(reloc_root->commit_root);
+               kfree(reloc_root);
+       }
+}
+
 static noinline_for_stack
 int merge_reloc_roots(struct reloc_control *rc)
 {
@@ -2244,7 +2261,7 @@ int merge_reloc_roots(struct reloc_control *rc)
        struct btrfs_root *reloc_root;
        LIST_HEAD(reloc_roots);
        int found = 0;
-       int ret;
+       int ret = 0;
 again:
        root = rc->extent_root;
 
@@ -2270,20 +2287,33 @@ again:
                        BUG_ON(root->reloc_root != reloc_root);
 
                        ret = merge_reloc_root(rc, root);
-                       BUG_ON(ret);
+                       if (ret)
+                               goto out;
                } else {
                        list_del_init(&reloc_root->root_list);
                }
                ret = btrfs_drop_snapshot(reloc_root, rc->block_rsv, 0, 1);
-               BUG_ON(ret < 0);
+               if (ret < 0) {
+                       if (list_empty(&reloc_root->root_list))
+                               list_add_tail(&reloc_root->root_list,
+                                             &reloc_roots);
+                       goto out;
+               }
        }
 
        if (found) {
                found = 0;
                goto again;
        }
+out:
+       if (ret) {
+               btrfs_std_error(root->fs_info, ret);
+               if (!list_empty(&reloc_roots))
+                       free_reloc_roots(&reloc_roots);
+       }
+
        BUG_ON(!RB_EMPTY_ROOT(&rc->reloc_root_tree.rb_root));
-       return 0;
+       return ret;
 }
 
 static void free_block_list(struct rb_root *blocks)
@@ -2818,8 +2848,10 @@ int relocate_tree_blocks(struct btrfs_trans_handle *trans,
        int err = 0;
 
        path = btrfs_alloc_path();
-       if (!path)
-               return -ENOMEM;
+       if (!path) {
+               err = -ENOMEM;
+               goto out_path;
+       }
 
        rb_node = rb_first(blocks);
        while (rb_node) {
@@ -2858,10 +2890,11 @@ int relocate_tree_blocks(struct btrfs_trans_handle *trans,
                rb_node = rb_next(rb_node);
        }
 out:
-       free_block_list(blocks);
        err = finish_pending_nodes(trans, rc, path, err);
 
        btrfs_free_path(path);
+out_path:
+       free_block_list(blocks);
        return err;
 }
 
@@ -3698,7 +3731,15 @@ int prepare_to_relocate(struct reloc_control *rc)
        set_reloc_control(rc);
 
        trans = btrfs_join_transaction(rc->extent_root);
-       BUG_ON(IS_ERR(trans));
+       if (IS_ERR(trans)) {
+               unset_reloc_control(rc);
+               /*
+                * extent tree is not a ref_cow tree and has no reloc_root to
+                * cleanup.  And callers are responsible to free the above
+                * block rsv.
+                */
+               return PTR_ERR(trans);
+       }
        btrfs_commit_transaction(trans, rc->extent_root);
        return 0;
 }
@@ -3730,7 +3771,11 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
        while (1) {
                progress++;
                trans = btrfs_start_transaction(rc->extent_root, 0);
-               BUG_ON(IS_ERR(trans));
+               if (IS_ERR(trans)) {
+                       err = PTR_ERR(trans);
+                       trans = NULL;
+                       break;
+               }
 restart:
                if (update_backref_cache(trans, &rc->backref_cache)) {
                        btrfs_end_transaction(trans, rc->extent_root);
@@ -4264,14 +4309,9 @@ int btrfs_recover_relocation(struct btrfs_root *root)
 out_free:
        kfree(rc);
 out:
-       while (!list_empty(&reloc_roots)) {
-               reloc_root = list_entry(reloc_roots.next,
-                                       struct btrfs_root, root_list);
-               list_del(&reloc_root->root_list);
-               free_extent_buffer(reloc_root->node);
-               free_extent_buffer(reloc_root->commit_root);
-               kfree(reloc_root);
-       }
+       if (!list_empty(&reloc_roots))
+               free_reloc_roots(&reloc_roots);
+
        btrfs_free_path(path);
 
        if (err == 0) {
index 68a29a1ea0688b868a0b33b8298b38159be5ec80..f6b88595f858b08f47fd530f3409124c288eb852 100644 (file)
@@ -1558,6 +1558,7 @@ static struct file_system_type btrfs_fs_type = {
        .kill_sb        = btrfs_kill_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("btrfs");
 
 /*
  * used by btrfsctl to scan devices when no FS is mounted
index e52da6fb11659e3b1b893086581b7c5a85d8eeb6..9250b9c4f01e1b826e25414e6ace942487e2ccca 100644 (file)
@@ -1052,7 +1052,12 @@ int btrfs_defrag_root(struct btrfs_root *root)
 
 /*
  * new snapshots need to be created at a very specific time in the
- * transaction commit.  This does the actual creation
+ * transaction commit.  This does the actual creation.
+ *
+ * Note:
+ * If the error which may affect the commitment of the current transaction
+ * happens, we should return the error number. If the error which just affect
+ * the creation of the pending snapshots, just return 0.
  */
 static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
                                   struct btrfs_fs_info *fs_info,
@@ -1071,7 +1076,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        struct extent_buffer *tmp;
        struct extent_buffer *old;
        struct timespec cur_time = CURRENT_TIME;
-       int ret;
+       int ret = 0;
        u64 to_reserve = 0;
        u64 index = 0;
        u64 objectid;
@@ -1080,40 +1085,36 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
 
        path = btrfs_alloc_path();
        if (!path) {
-               ret = pending->error = -ENOMEM;
-               return ret;
+               pending->error = -ENOMEM;
+               return 0;
        }
 
        new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
        if (!new_root_item) {
-               ret = pending->error = -ENOMEM;
+               pending->error = -ENOMEM;
                goto root_item_alloc_fail;
        }
 
-       ret = btrfs_find_free_objectid(tree_root, &objectid);
-       if (ret) {
-               pending->error = ret;
+       pending->error = btrfs_find_free_objectid(tree_root, &objectid);
+       if (pending->error)
                goto no_free_objectid;
-       }
 
        btrfs_reloc_pre_snapshot(trans, pending, &to_reserve);
 
        if (to_reserve > 0) {
-               ret = btrfs_block_rsv_add(root, &pending->block_rsv,
-                                         to_reserve,
-                                         BTRFS_RESERVE_NO_FLUSH);
-               if (ret) {
-                       pending->error = ret;
+               pending->error = btrfs_block_rsv_add(root,
+                                                    &pending->block_rsv,
+                                                    to_reserve,
+                                                    BTRFS_RESERVE_NO_FLUSH);
+               if (pending->error)
                        goto no_free_objectid;
-               }
        }
 
-       ret = btrfs_qgroup_inherit(trans, fs_info, root->root_key.objectid,
-                                  objectid, pending->inherit);
-       if (ret) {
-               pending->error = ret;
+       pending->error = btrfs_qgroup_inherit(trans, fs_info,
+                                             root->root_key.objectid,
+                                             objectid, pending->inherit);
+       if (pending->error)
                goto no_free_objectid;
-       }
 
        key.objectid = objectid;
        key.offset = (u64)-1;
@@ -1141,7 +1142,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
                                         dentry->d_name.len, 0);
        if (dir_item != NULL && !IS_ERR(dir_item)) {
                pending->error = -EEXIST;
-               goto fail;
+               goto dir_item_existed;
        } else if (IS_ERR(dir_item)) {
                ret = PTR_ERR(dir_item);
                btrfs_abort_transaction(trans, root, ret);
@@ -1272,6 +1273,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
        if (ret)
                btrfs_abort_transaction(trans, root, ret);
 fail:
+       pending->error = ret;
+dir_item_existed:
        trans->block_rsv = rsv;
        trans->bytes_reserved = 0;
 no_free_objectid:
@@ -1287,12 +1290,17 @@ root_item_alloc_fail:
 static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
                                             struct btrfs_fs_info *fs_info)
 {
-       struct btrfs_pending_snapshot *pending;
+       struct btrfs_pending_snapshot *pending, *next;
        struct list_head *head = &trans->transaction->pending_snapshots;
+       int ret = 0;
 
-       list_for_each_entry(pending, head, list)
-               create_pending_snapshot(trans, fs_info, pending);
-       return 0;
+       list_for_each_entry_safe(pending, next, head, list) {
+               list_del(&pending->list);
+               ret = create_pending_snapshot(trans, fs_info, pending);
+               if (ret)
+                       break;
+       }
+       return ret;
 }
 
 static void update_super_roots(struct btrfs_root *root)
@@ -1448,6 +1456,13 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans,
        btrfs_abort_transaction(trans, root, err);
 
        spin_lock(&root->fs_info->trans_lock);
+
+       if (list_empty(&cur_trans->list)) {
+               spin_unlock(&root->fs_info->trans_lock);
+               btrfs_end_transaction(trans, root);
+               return;
+       }
+
        list_del_init(&cur_trans->list);
        if (cur_trans == root->fs_info->running_transaction) {
                root->fs_info->trans_no_join = 1;
index c7ef569eb22a8b71a455721edc57a61acc66a226..451fad96ecd115393207e69433162b7328f74923 100644 (file)
@@ -1382,7 +1382,10 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans,
 
        btrfs_release_path(path);
        if (ret == 0) {
-               btrfs_inc_nlink(inode);
+               if (!inode->i_nlink)
+                       set_nlink(inode, 1);
+               else
+                       btrfs_inc_nlink(inode);
                ret = btrfs_update_inode(trans, root, inode);
        } else if (ret == -EEXIST) {
                ret = 0;
index 35bb2d4ed29f6ed1a00fabb5491fc40d5d669994..6b9cff42265d06e5b26a7ed53684a5551675a930 100644 (file)
@@ -2379,7 +2379,11 @@ static int btrfs_relocate_chunk(struct btrfs_root *root,
                return ret;
 
        trans = btrfs_start_transaction(root, 0);
-       BUG_ON(IS_ERR(trans));
+       if (IS_ERR(trans)) {
+               ret = PTR_ERR(trans);
+               btrfs_std_error(root->fs_info, ret);
+               return ret;
+       }
 
        lock_chunks(root);
 
@@ -3050,7 +3054,8 @@ static void __cancel_balance(struct btrfs_fs_info *fs_info)
 
        unset_balance_control(fs_info);
        ret = del_balance_item(fs_info->tree_root);
-       BUG_ON(ret);
+       if (ret)
+               btrfs_std_error(fs_info, ret);
 
        atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
 }
@@ -3230,6 +3235,11 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
                update_ioctl_balance_args(fs_info, 0, bargs);
        }
 
+       if ((ret && ret != -ECANCELED && ret != -ENOSPC) ||
+           balance_need_close(fs_info)) {
+               __cancel_balance(fs_info);
+       }
+
        wake_up(&fs_info->balance_wait_q);
 
        return ret;
index 9fe17c6c2876c0cbec11b57b6e5de76349320244..6ddc0bca56b2e61abda40b5ad8194be95f73c152 100644 (file)
@@ -952,6 +952,7 @@ static struct file_system_type ceph_fs_type = {
        .kill_sb        = ceph_kill_sb,
        .fs_flags       = FS_RENAME_DOES_D_MOVE,
 };
+MODULE_ALIAS_FS("ceph");
 
 #define _STRINGIFY(x) #x
 #define STRINGIFY(x) _STRINGIFY(x)
index 7353bc5d73d7cfcdba7125b8e83d783f639619ca..8e2e799e7a2451e5dd7300a57fbf81b32a28bf94 100644 (file)
@@ -1909,12 +1909,12 @@ cifs_writev_requeue(struct cifs_writedata *wdata)
        } while (rc == -EAGAIN);
 
        for (i = 0; i < wdata->nr_pages; i++) {
+               unlock_page(wdata->pages[i]);
                if (rc != 0) {
                        SetPageError(wdata->pages[i]);
                        end_page_writeback(wdata->pages[i]);
                        page_cache_release(wdata->pages[i]);
                }
-               unlock_page(wdata->pages[i]);
        }
 
        mapping_set_error(inode->i_mapping, rc);
index 54125e04fd0c88d4c17d7833b557e21c1696bcb3..991c63c6bdd053189082c6208407a5df55b29053 100644 (file)
@@ -97,7 +97,7 @@ enum {
        Opt_user, Opt_pass, Opt_ip,
        Opt_unc, Opt_domain,
        Opt_srcaddr, Opt_prefixpath,
-       Opt_iocharset, Opt_sockopt,
+       Opt_iocharset,
        Opt_netbiosname, Opt_servern,
        Opt_ver, Opt_vers, Opt_sec, Opt_cache,
 
@@ -202,7 +202,6 @@ static const match_table_t cifs_mount_option_tokens = {
        { Opt_srcaddr, "srcaddr=%s" },
        { Opt_prefixpath, "prefixpath=%s" },
        { Opt_iocharset, "iocharset=%s" },
-       { Opt_sockopt, "sockopt=%s" },
        { Opt_netbiosname, "netbiosname=%s" },
        { Opt_servern, "servern=%s" },
        { Opt_ver, "ver=%s" },
@@ -1752,19 +1751,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                         */
                        cFYI(1, "iocharset set to %s", string);
                        break;
-               case Opt_sockopt:
-                       string = match_strdup(args);
-                       if (string == NULL)
-                               goto out_nomem;
-
-                       if (strnicmp(string, "TCP_NODELAY", 11) == 0) {
-                               printk(KERN_WARNING "CIFS: the "
-                                       "sockopt=TCP_NODELAY option has been "
-                                       "deprecated and will be removed "
-                                       "in 3.9\n");
-                               vol->sockopt_tcp_nodelay = 1;
-                       }
-                       break;
                case Opt_netbiosname:
                        string = match_strdup(args);
                        if (string == NULL)
index 83f2606c76d00f090ec6a5b8e550a102de3fadbc..0079696305c980def5c17cc1906f75d20f3565c4 100644 (file)
@@ -995,6 +995,15 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
                return PTR_ERR(tlink);
        tcon = tlink_tcon(tlink);
 
+       /*
+        * We cannot rename the file if the server doesn't support
+        * CAP_INFOLEVEL_PASSTHRU
+        */
+       if (!(tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)) {
+               rc = -EBUSY;
+               goto out;
+       }
+
        rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
                         DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
                         &netfid, &oplock, NULL, cifs_sb->local_nls,
@@ -1023,7 +1032,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
                                        current->tgid);
                /* although we would like to mark the file hidden
                   if that fails we will still try to rename it */
-               if (rc != 0)
+               if (!rc)
                        cifsInode->cifsAttrs = dosattr;
                else
                        dosattr = origattr; /* since not able to change them */
index c9c7aa7ed96685bc94b36103350204c68a19b827..bceffe7b8f8d2fdcda17aafd8c5069ea079c111d 100644 (file)
@@ -744,4 +744,5 @@ struct smb_version_values smb30_values = {
        .cap_unix = 0,
        .cap_nt_find = SMB2_NT_FIND,
        .cap_large_files = SMB2_LARGE_FILES,
+       .oplock_read = SMB2_OPLOCK_LEVEL_II,
 };
index dada9d0abedeb9f3d5ae29b0d0d9bde577975f63..4dcc0d81a7aa511069869141d0d1470800a82e54 100644 (file)
@@ -329,4 +329,5 @@ struct file_system_type coda_fs_type = {
        .kill_sb        = kill_anon_super,
        .fs_flags       = FS_BINARY_MOUNTDATA,
 };
+MODULE_ALIAS_FS("coda");
 
index aee0a7ebbd8ee2d410fe4e72e1c9faf3bb1e1616..7f26c3cf75ae67e2e25788276ba6c379df4f8d61 100644 (file)
@@ -114,6 +114,7 @@ static struct file_system_type configfs_fs_type = {
        .mount          = configfs_do_mount,
        .kill_sb        = kill_litter_super,
 };
+MODULE_ALIAS_FS("configfs");
 
 struct dentry *configfs_pin_fs(void)
 {
index 3ceb9ec976e182202cb40b0632f6693086272d92..35b1c7bd18b758a30fc03fd4267151d18fcb2281 100644 (file)
@@ -573,6 +573,7 @@ static struct file_system_type cramfs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("cramfs");
 
 static int __init init_cramfs_fs(void)
 {
index 0c4f80b447fb28d2dd7958613152542f03241e03..4888cb3fdef76037b7af5f9db898bdcb82ce48c2 100644 (file)
@@ -299,6 +299,7 @@ static struct file_system_type debug_fs_type = {
        .mount =        debug_mount,
        .kill_sb =      kill_litter_super,
 };
+MODULE_ALIAS_FS("debugfs");
 
 static struct dentry *__create_file(const char *name, umode_t mode,
                                    struct dentry *parent, void *data,
index e15ef38c24fa4b91ee0dfe5e62eece16200807b4..434aa313f077c2789bdef6e1cba0bf2725c37b7b 100644 (file)
@@ -12,3 +12,11 @@ config ECRYPT_FS
 
          To compile this file system support as a module, choose M here: the
          module will be called ecryptfs.
+
+config ECRYPT_FS_MESSAGING
+       bool "Enable notifications for userspace key wrap/unwrap"
+       depends on ECRYPT_FS
+       help
+         Enables the /dev/ecryptfs entry for use by ecryptfsd. This allows
+         for userspace to wrap/unwrap file encryption keys by other
+         backends, like OpenSSL.
index 2cc9ee4ad2eb774f144e1d706276c7d037c6bb7d..49678a69947dac7ce580941799cba91d51a5cdae 100644 (file)
@@ -1,7 +1,10 @@
 #
-# Makefile for the Linux 2.6 eCryptfs
+# Makefile for the Linux eCryptfs
 #
 
 obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o
 
-ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o read_write.o crypto.o keystore.o messaging.o miscdev.o kthread.o debug.o
+ecryptfs-y := dentry.o file.o inode.o main.o super.o mmap.o read_write.o \
+             crypto.o keystore.o kthread.o debug.o
+
+ecryptfs-$(CONFIG_ECRYPT_FS_MESSAGING) += messaging.o miscdev.o
index a7b0c2dfb3db76066703076ab43f4d589637523d..d5c25db4398f0244f0f1d0c1f1e20a55f8f51aa9 100644 (file)
@@ -301,17 +301,14 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
        while (size > 0 && i < sg_size) {
                pg = virt_to_page(addr);
                offset = offset_in_page(addr);
-               if (sg)
-                       sg_set_page(&sg[i], pg, 0, offset);
+               sg_set_page(&sg[i], pg, 0, offset);
                remainder_of_page = PAGE_CACHE_SIZE - offset;
                if (size >= remainder_of_page) {
-                       if (sg)
-                               sg[i].length = remainder_of_page;
+                       sg[i].length = remainder_of_page;
                        addr += remainder_of_page;
                        size -= remainder_of_page;
                } else {
-                       if (sg)
-                               sg[i].length = size;
+                       sg[i].length = size;
                        addr += size;
                        size = 0;
                }
index 1b5d9af937dfc4a33015eaa154a8956857381749..bf12ba5dd223befe93ce786c3a3848cdf5e38fcd 100644 (file)
 static int ecryptfs_d_revalidate(struct dentry *dentry, unsigned int flags)
 {
        struct dentry *lower_dentry;
-       struct vfsmount *lower_mnt;
        int rc = 1;
 
        if (flags & LOOKUP_RCU)
                return -ECHILD;
 
        lower_dentry = ecryptfs_dentry_to_lower(dentry);
-       lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
        if (!lower_dentry->d_op || !lower_dentry->d_op->d_revalidate)
                goto out;
        rc = lower_dentry->d_op->d_revalidate(lower_dentry, flags);
index 7e2c6f5d7985ffc3fae9482a6eb952b58621e278..dd299b389d4e4fc36b7694dbf6acac0dcf9742f7 100644 (file)
@@ -172,6 +172,19 @@ ecryptfs_get_key_payload_data(struct key *key)
 #define ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE 24
 #define ECRYPTFS_ENCRYPTED_DENTRY_NAME_LEN (18 + 1 + 4 + 1 + 32)
 
+#ifdef CONFIG_ECRYPT_FS_MESSAGING
+# define ECRYPTFS_VERSIONING_MASK_MESSAGING (ECRYPTFS_VERSIONING_DEVMISC \
+                                            | ECRYPTFS_VERSIONING_PUBKEY)
+#else
+# define ECRYPTFS_VERSIONING_MASK_MESSAGING 0
+#endif
+
+#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \
+                                 | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \
+                                 | ECRYPTFS_VERSIONING_XATTR \
+                                 | ECRYPTFS_VERSIONING_MULTKEY \
+                                 | ECRYPTFS_VERSIONING_MASK_MESSAGING \
+                                 | ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION)
 struct ecryptfs_key_sig {
        struct list_head crypt_stat_list;
        char keysig[ECRYPTFS_SIG_SIZE_HEX + 1];
@@ -399,7 +412,9 @@ struct ecryptfs_daemon {
        struct hlist_node euid_chain;
 };
 
+#ifdef CONFIG_ECRYPT_FS_MESSAGING
 extern struct mutex ecryptfs_daemon_hash_mux;
+#endif
 
 static inline size_t
 ecryptfs_lower_header_size(struct ecryptfs_crypt_stat *crypt_stat)
@@ -610,6 +625,7 @@ int
 ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
                  size_t size, int flags);
 int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode);
+#ifdef CONFIG_ECRYPT_FS_MESSAGING
 int ecryptfs_process_response(struct ecryptfs_daemon *daemon,
                              struct ecryptfs_message *msg, u32 seq);
 int ecryptfs_send_message(char *data, int data_len,
@@ -618,6 +634,24 @@ int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx,
                               struct ecryptfs_message **emsg);
 int ecryptfs_init_messaging(void);
 void ecryptfs_release_messaging(void);
+#else
+static inline int ecryptfs_init_messaging(void)
+{
+       return 0;
+}
+static inline void ecryptfs_release_messaging(void)
+{ }
+static inline int ecryptfs_send_message(char *data, int data_len,
+                                       struct ecryptfs_msg_ctx **msg_ctx)
+{
+       return -ENOTCONN;
+}
+static inline int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx,
+                                            struct ecryptfs_message **emsg)
+{
+       return -ENOMSG;
+}
+#endif
 
 void
 ecryptfs_write_header_metadata(char *virt,
@@ -655,12 +689,11 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs,
                                     size_t offset_in_page, size_t size,
                                     struct inode *ecryptfs_inode);
 struct page *ecryptfs_get_locked_page(struct inode *inode, loff_t index);
-int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon);
-int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon);
 int ecryptfs_parse_packet_length(unsigned char *data, size_t *size,
                                 size_t *length_size);
 int ecryptfs_write_packet_length(char *dest, size_t size,
                                 size_t *packet_size_length);
+#ifdef CONFIG_ECRYPT_FS_MESSAGING
 int ecryptfs_init_ecryptfs_miscdev(void);
 void ecryptfs_destroy_ecryptfs_miscdev(void);
 int ecryptfs_send_miscdev(char *data, size_t data_size,
@@ -669,6 +702,9 @@ int ecryptfs_send_miscdev(char *data, size_t data_size,
 void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx);
 int
 ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, struct file *file);
+int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon);
+int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon);
+#endif
 int ecryptfs_init_kthread(void);
 void ecryptfs_destroy_kthread(void);
 int ecryptfs_privileged_open(struct file **lower_file,
index 53acc9d0c1384ff8030a17e922a7e6fb45dcf081..63b1f54b6a1ff01862f381ae678afa3d46e4c15e 100644 (file)
@@ -199,7 +199,6 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
        struct dentry *ecryptfs_dentry = file->f_path.dentry;
        /* Private value of ecryptfs_dentry allocated in
         * ecryptfs_lookup() */
-       struct dentry *lower_dentry;
        struct ecryptfs_file_info *file_info;
 
        mount_crypt_stat = &ecryptfs_superblock_to_private(
@@ -222,7 +221,6 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
                rc = -ENOMEM;
                goto out;
        }
-       lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
        crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
        mutex_lock(&crypt_stat->cs_mutex);
        if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) {
index e0f07fb6d56b65fbca944e52512d3d5239d600bb..5eab400e25903b71641d4a056254c79f3a776885 100644 (file)
@@ -999,8 +999,8 @@ out:
        return rc;
 }
 
-int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry,
-                         struct kstat *stat)
+static int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry,
+                                struct kstat *stat)
 {
        struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
        int rc = 0;
@@ -1021,8 +1021,8 @@ int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry,
        return rc;
 }
 
-int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
-                    struct kstat *stat)
+static int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                           struct kstat *stat)
 {
        struct kstat lower_stat;
        int rc;
index 2333203a120b3b853f71ef011a0755a3be04fd6a..7d52806c21197206a5932b08a68e7dc9d6899253 100644 (file)
@@ -1150,7 +1150,7 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
        struct ecryptfs_message *msg = NULL;
        char *auth_tok_sig;
        char *payload;
-       size_t payload_len;
+       size_t payload_len = 0;
        int rc;
 
        rc = ecryptfs_get_auth_tok_sig(&auth_tok_sig, auth_tok);
@@ -1168,7 +1168,7 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
        rc = ecryptfs_send_message(payload, payload_len, &msg_ctx);
        if (rc) {
                ecryptfs_printk(KERN_ERR, "Error sending message to "
-                               "ecryptfsd\n");
+                               "ecryptfsd: %d\n", rc);
                goto out;
        }
        rc = ecryptfs_wait_for_response(msg_ctx, &msg);
@@ -1202,8 +1202,7 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
                                  crypt_stat->key_size);
        }
 out:
-       if (msg)
-               kfree(msg);
+       kfree(msg);
        return rc;
 }
 
@@ -1989,7 +1988,7 @@ pki_encrypt_session_key(struct key *auth_tok_key,
        rc = ecryptfs_send_message(payload, payload_len, &msg_ctx);
        if (rc) {
                ecryptfs_printk(KERN_ERR, "Error sending message to "
-                               "ecryptfsd\n");
+                               "ecryptfsd: %d\n", rc);
                goto out;
        }
        rc = ecryptfs_wait_for_response(msg_ctx, &msg);
index 4e0886c9e5c476059346f5a0d520257418ce03ba..e924cf45aad9559533214814cccbb05aa7a06b44 100644 (file)
@@ -629,6 +629,7 @@ static struct file_system_type ecryptfs_fs_type = {
        .kill_sb = ecryptfs_kill_block_super,
        .fs_flags = 0
 };
+MODULE_ALIAS_FS("ecryptfs");
 
 /**
  * inode_info_init_once
index 8d7a577ae49782f8398a21315301ea254f68fc71..49ff8ea08f1ca88252d82a34c98d77d0c490ff86 100644 (file)
@@ -97,8 +97,7 @@ static void ecryptfs_msg_ctx_free_to_alloc(struct ecryptfs_msg_ctx *msg_ctx)
 void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx)
 {
        list_move(&(msg_ctx->node), &ecryptfs_msg_ctx_free_list);
-       if (msg_ctx->msg)
-               kfree(msg_ctx->msg);
+       kfree(msg_ctx->msg);
        msg_ctx->msg = NULL;
        msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_FREE;
 }
@@ -283,7 +282,7 @@ ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type,
        int rc;
 
        rc = ecryptfs_find_daemon_by_euid(&daemon);
-       if (rc || !daemon) {
+       if (rc) {
                rc = -ENOTCONN;
                goto out;
        }
index 2002431ef9a0ff238d838b9d4c2f8bb9760007fa..c6f57a74a559da265bc8f062eab06488d8d7c00a 100644 (file)
@@ -33,6 +33,7 @@ static struct file_system_type efs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("efs");
 
 static struct pt_types sgi_pt_types[] = {
        {0x00,          "SGI vh"},
index 5e59280d42d779fb13fe9171d22d24ea4fc81095..9d9763328734e63e27ce6ef6f364518cb7f602c0 100644 (file)
@@ -1010,6 +1010,7 @@ static struct file_system_type exofs_type = {
        .mount          = exofs_mount,
        .kill_sb        = generic_shutdown_super,
 };
+MODULE_ALIAS_FS("exofs");
 
 static int __init init_exofs(void)
 {
index 7f68c8114026a7521ca1808775a89cc1e3765542..288534920fe5cc4960f99ae636777344c5d42db6 100644 (file)
@@ -1536,6 +1536,7 @@ static struct file_system_type ext2_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("ext2");
 
 static int __init init_ext2_fs(void)
 {
index 5546ca225ffe19ee3e53d75ee4e18936fa47cc83..1d6e2ed853229edfebb4de3a51fff8e86846e1ae 100644 (file)
@@ -3068,6 +3068,7 @@ static struct file_system_type ext3_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("ext3");
 
 static int __init init_ext3_fs(void)
 {
index 5e6c878361935f405ccefd532b40d9c3101f0317..34e8552192310a709e6d3d9ccedb35cbe3fca972 100644 (file)
@@ -90,6 +90,7 @@ static struct file_system_type ext2_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("ext2");
 #define IS_EXT2_SB(sb) ((sb)->s_bdev->bd_holder == &ext2_fs_type)
 #else
 #define IS_EXT2_SB(sb) (0)
@@ -104,6 +105,7 @@ static struct file_system_type ext3_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("ext3");
 #define IS_EXT3_SB(sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type)
 #else
 #define IS_EXT3_SB(sb) (0)
@@ -5152,7 +5154,6 @@ static inline int ext2_feature_set_ok(struct super_block *sb)
                return 0;
        return 1;
 }
-MODULE_ALIAS("ext2");
 #else
 static inline void register_as_ext2(void) { }
 static inline void unregister_as_ext2(void) { }
@@ -5185,7 +5186,6 @@ static inline int ext3_feature_set_ok(struct super_block *sb)
                return 0;
        return 1;
 }
-MODULE_ALIAS("ext3");
 #else
 static inline void register_as_ext3(void) { }
 static inline void unregister_as_ext3(void) { }
@@ -5199,6 +5199,7 @@ static struct file_system_type ext4_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("ext4");
 
 static int __init ext4_init_feat_adverts(void)
 {
index 8c117649a035dc5e5df58264c25b87c1d3a43ae5..fea6e582a2ed62995e1db703af39a2c436e9df4f 100644 (file)
@@ -687,6 +687,7 @@ static struct file_system_type f2fs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("f2fs");
 
 static int __init init_inodecache(void)
 {
index e2cfda94a28d249fd85961747b625a3c8b5bd100..081b759cff83fee7dc4fa3ba901b2ba9f92c888b 100644 (file)
@@ -668,6 +668,7 @@ static struct file_system_type msdos_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("msdos");
 
 static int __init init_msdos_fs(void)
 {
index ac959d655e7d7f7dd92448437b58ec4fe81ce1ab..2da952036a3d7527d98b527ff7114b6d14ec4d43 100644 (file)
@@ -1073,6 +1073,7 @@ static struct file_system_type vfat_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("vfat");
 
 static int __init init_vfat_fs(void)
 {
index da165f6adcbfa67a12f9f19363692ab6c5d00d19..92567d95ba6ab1adbf94c2ead01f94b60ae02a40 100644 (file)
@@ -273,7 +273,7 @@ struct file_system_type *get_fs_type(const char *name)
        int len = dot ? dot - name : strlen(name);
 
        fs = __get_fs_type(name, len);
-       if (!fs && (request_module("%.*s", len, name) == 0))
+       if (!fs && (request_module("fs-%.*s", len, name) == 0))
                fs = __get_fs_type(name, len);
 
        if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) {
index fed2c8afb3a9f401945ca5d8a226a4df5ebb4c9f..45507430806924e7cb1462c29c3bf1376ce9bc5d 100644 (file)
@@ -52,7 +52,6 @@ MODULE_AUTHOR("Christoph Hellwig");
 MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver");
 MODULE_LICENSE("Dual BSD/GPL");
 
-MODULE_ALIAS("vxfs"); /* makes mount -t vxfs autoload the module */
 
 
 static void            vxfs_put_super(struct super_block *);
@@ -258,6 +257,7 @@ static struct file_system_type vxfs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("vxfs"); /* makes mount -t vxfs autoload the module */
 
 static int __init
 vxfs_init(void)
index b7978b9f75ef01e20e3c18afe20a27df9f6dbe6c..a0b0855d00a985c78288074f9adc813d14addfe1 100644 (file)
@@ -341,6 +341,7 @@ static struct file_system_type fuse_ctl_fs_type = {
        .mount          = fuse_ctl_mount,
        .kill_sb        = fuse_ctl_kill_sb,
 };
+MODULE_ALIAS_FS("fusectl");
 
 int __init fuse_ctl_init(void)
 {
index df00993ed108816b6902080d0ac98fd742407c12..137185c3884fbbb9dfcab6115c78952d7aec7f08 100644 (file)
@@ -1117,6 +1117,7 @@ static struct file_system_type fuse_fs_type = {
        .mount          = fuse_mount,
        .kill_sb        = fuse_kill_sb_anon,
 };
+MODULE_ALIAS_FS("fuse");
 
 #ifdef CONFIG_BLOCK
 static struct dentry *fuse_mount_blk(struct file_system_type *fs_type,
@@ -1146,6 +1147,7 @@ static struct file_system_type fuseblk_fs_type = {
        .kill_sb        = fuse_kill_sb_blk,
        .fs_flags       = FS_REQUIRES_DEV | FS_HAS_SUBTYPE,
 };
+MODULE_ALIAS_FS("fuseblk");
 
 static inline int register_fuseblk(void)
 {
index 1b612be4b873c663640cbd1338d9ff2d5aaa5d8e..60ede2a0f43fbc498201cc3262da939110eac0bb 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/gfs2_ondisk.h>
 #include <linux/quotaops.h>
 #include <linux/lockdep.h>
+#include <linux/module.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -1425,6 +1426,7 @@ struct file_system_type gfs2_fs_type = {
        .kill_sb = gfs2_kill_sb,
        .owner = THIS_MODULE,
 };
+MODULE_ALIAS_FS("gfs2");
 
 struct file_system_type gfs2meta_fs_type = {
        .name = "gfs2meta",
@@ -1432,4 +1434,4 @@ struct file_system_type gfs2meta_fs_type = {
        .mount = gfs2_mount_meta,
        .owner = THIS_MODULE,
 };
-
+MODULE_ALIAS_FS("gfs2meta");
index e93ddaadfd1e445fa89e976c9692f2afa302094c..bbaaa8a4ee6445e90920da2431defcc064013ace 100644 (file)
@@ -466,6 +466,7 @@ static struct file_system_type hfs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("hfs");
 
 static void hfs_init_once(void *p)
 {
index 974c26f96faeaa2575cdc80e81b36cbb955cf07e..7b87284e46dc9b0fb50e1f40dcfebe9f44547b93 100644 (file)
@@ -654,6 +654,7 @@ static struct file_system_type hfsplus_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("hfsplus");
 
 static void hfsplus_init_once(void *p)
 {
index 74f55703be498ca0220f9150ed29a08818cd5dfd..126d3c2e2dee12b2e1b1095fd774d1fceced108f 100644 (file)
@@ -748,6 +748,7 @@ static struct file_system_type hppfs_type = {
        .kill_sb        = kill_anon_super,
        .fs_flags       = 0,
 };
+MODULE_ALIAS_FS("hppfs");
 
 static int __init init_hppfs(void)
 {
index 7f94e0cbc69c78bfda1431c85d1f9280315ded89..84e3d856e91d05c27aa182be0d28dead99128c93 100644 (file)
@@ -896,6 +896,7 @@ static struct file_system_type hugetlbfs_fs_type = {
        .mount          = hugetlbfs_mount,
        .kill_sb        = kill_litter_super,
 };
+MODULE_ALIAS_FS("hugetlbfs");
 
 static struct vfsmount *hugetlbfs_vfsmount[HUGE_MAX_HSTATE];
 
index 67ce52507d7dec7f2f009624979ffa4910f8ea36..a67f16e846a2c766341fea2a6437c77d61700769 100644 (file)
@@ -1556,6 +1556,7 @@ static struct file_system_type iso9660_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("iso9660");
 
 static int __init init_iso9660_fs(void)
 {
@@ -1593,5 +1594,3 @@ static void __exit exit_iso9660_fs(void)
 module_init(init_iso9660_fs)
 module_exit(exit_iso9660_fs)
 MODULE_LICENSE("GPL");
-/* Actual filesystem name is iso9660, as requested in filesystems.c */
-MODULE_ALIAS("iso9660");
index d3d8799e2187233e23e1614990443203d4fff1ad..0defb1cc2a3520d6f5f67cc880f91d0e9fe5b244 100644 (file)
@@ -356,6 +356,7 @@ static struct file_system_type jffs2_fs_type = {
        .mount =        jffs2_mount,
        .kill_sb =      jffs2_kill_sb,
 };
+MODULE_ALIAS_FS("jffs2");
 
 static int __init init_jffs2_fs(void)
 {
index 060ba638becbe39ee85104860d325b0f4e16a8f7..2003e830ed1c0d890f1fe0944db8dff04dab8ee6 100644 (file)
@@ -833,6 +833,7 @@ static struct file_system_type jfs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("jfs");
 
 static void init_once(void *foo)
 {
index 345c24b8a6f86965b39d7dd017fb294908ddd8d0..54360293bcb5cd0680c3042e6f0b9b87e342c649 100644 (file)
@@ -608,6 +608,7 @@ static struct file_system_type logfs_fs_type = {
        .fs_flags       = FS_REQUIRES_DEV,
 
 };
+MODULE_ALIAS_FS("logfs");
 
 static int __init logfs_init(void)
 {
index 99541cceb584966da9aba7b70dd094653cf158b9..df122496f32821bd145490800467d41d02c87f63 100644 (file)
@@ -660,6 +660,7 @@ static struct file_system_type minix_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("minix");
 
 static int __init init_minix_fs(void)
 {
index 961bc1268366d80c8b44adf5adc0aec26f59edbd..57ae9c8c66bfc6d98ae96643874710cdc3de321a 100644 (file)
@@ -689,8 +689,6 @@ void nd_jump_link(struct nameidata *nd, struct path *path)
        nd->path = *path;
        nd->inode = nd->path.dentry->d_inode;
        nd->flags |= LOOKUP_JUMPED;
-
-       BUG_ON(nd->inode->i_op->follow_link);
 }
 
 static inline void put_link(struct nameidata *nd, struct path *link, void *cookie)
index 7dafd6899a62a5893be0bd304d4e38e40a1957c8..26910c8154da1be65c0318eb088d5d69d3e08baf 100644 (file)
@@ -1051,6 +1051,7 @@ static struct file_system_type ncp_fs_type = {
        .kill_sb        = kill_anon_super,
        .fs_flags       = FS_BINARY_MOUNTDATA,
 };
+MODULE_ALIAS_FS("ncpfs");
 
 static int __init init_ncp_fs(void)
 {
index 17b32b7224574207fba2ee5384474b69d6abcc99..95cdcb208dfb630396058a0688c4341a170b4968 100644 (file)
@@ -294,6 +294,7 @@ struct file_system_type nfs_fs_type = {
        .kill_sb        = nfs_kill_super,
        .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
 };
+MODULE_ALIAS_FS("nfs");
 EXPORT_SYMBOL_GPL(nfs_fs_type);
 
 struct file_system_type nfs_xdev_fs_type = {
@@ -333,6 +334,7 @@ struct file_system_type nfs4_fs_type = {
        .kill_sb        = nfs_kill_super,
        .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
 };
+MODULE_ALIAS_FS("nfs4");
 EXPORT_SYMBOL_GPL(nfs4_fs_type);
 
 static int __init register_nfs4_fs(void)
@@ -2717,6 +2719,5 @@ module_param(send_implementation_id, ushort, 0644);
 MODULE_PARM_DESC(send_implementation_id,
                "Send implementation ID with NFSv4.1 exchange_id");
 MODULE_PARM_DESC(nfs4_unique_id, "nfs_client_id4 uniquifier string");
-MODULE_ALIAS("nfs4");
 
 #endif /* CONFIG_NFS_V4 */
index 13a21c8fca490884e05e832d1a657daf9d1af58f..f33455b4d957a44f50a873fc5bd53d1727e4b563 100644 (file)
@@ -1090,6 +1090,7 @@ static struct file_system_type nfsd_fs_type = {
        .mount          = nfsd_mount,
        .kill_sb        = nfsd_umount,
 };
+MODULE_ALIAS_FS("nfsd");
 
 #ifdef CONFIG_PROC_FS
 static int create_proc_exports_entry(void)
index 3c991dc84f2f2df6f8c9dccd922d8edbf1ff32a5..c7d1f9f18b094fb1f281fb0dfcb6b53328dc72fe 100644 (file)
@@ -1361,6 +1361,7 @@ struct file_system_type nilfs_fs_type = {
        .kill_sb  = kill_block_super,
        .fs_flags = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("nilfs2");
 
 static void nilfs_inode_init_once(void *obj)
 {
index 4a8289f8b16c87495e8e6b94fccc6f83c5643c7e..82650d52d9168ee4f1e1b4282813afdaca5c7ec6 100644 (file)
@@ -3079,6 +3079,7 @@ static struct file_system_type ntfs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("ntfs");
 
 /* Stable names for the slab caches. */
 static const char ntfs_index_ctx_cache_name[] = "ntfs_index_ctx_cache";
index 4c5fc8d77dc26e8ee9f4238b03dc95c785945398..12bafb7265ceb8d2a13e8a1fb3aa86a73149a43e 100644 (file)
@@ -640,6 +640,7 @@ static struct file_system_type dlmfs_fs_type = {
        .mount          = dlmfs_mount,
        .kill_sb        = kill_litter_super,
 };
+MODULE_ALIAS_FS("ocfs2_dlmfs");
 
 static int __init init_dlmfs_fs(void)
 {
index 9b6910dec4ba79623027455e9833f4892ce3e0ea..01b85165552b75f1cf2e17893bea1054eb19ff81 100644 (file)
@@ -1266,6 +1266,7 @@ static struct file_system_type ocfs2_fs_type = {
        .fs_flags       = FS_REQUIRES_DEV|FS_RENAME_DOES_D_MOVE,
        .next           = NULL
 };
+MODULE_ALIAS_FS("ocfs2");
 
 static int ocfs2_check_set_options(struct super_block *sb,
                                   struct mount_options *options)
index 25d715c7c87abdd373918da6a42489332c88e3c0..d8b0afde2179cc4c4d790ed5a5632a0620cc6ca9 100644 (file)
@@ -572,6 +572,7 @@ static struct file_system_type omfs_fs_type = {
        .kill_sb = kill_block_super,
        .fs_flags = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("omfs");
 
 static int __init init_omfs_fs(void)
 {
index ae47fa7efb9d9306b6dbb2167f7fa3840164219e..75885ffde44e58a967799d3b461181e74bb8fd9c 100644 (file)
@@ -432,6 +432,7 @@ static struct file_system_type openprom_fs_type = {
        .mount          = openprom_mount,
        .kill_sb        = kill_anon_super,
 };
+MODULE_ALIAS_FS("openpromfs");
 
 static void op_inode_init_once(void *data)
 {
index b7a47196c8c3577e9cda96125a0157444128a7be..66b51c0383da790c1219aa9716d484681f61cde8 100644 (file)
@@ -118,7 +118,7 @@ static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd)
        struct super_block *sb = inode->i_sb;
        struct proc_inode *ei = PROC_I(inode);
        struct task_struct *task;
-       struct dentry *ns_dentry;
+       struct path ns_path;
        void *error = ERR_PTR(-EACCES);
 
        task = get_proc_task(inode);
@@ -128,14 +128,14 @@ static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd)
        if (!ptrace_may_access(task, PTRACE_MODE_READ))
                goto out_put_task;
 
-       ns_dentry = proc_ns_get_dentry(sb, task, ei->ns_ops);
-       if (IS_ERR(ns_dentry)) {
-               error = ERR_CAST(ns_dentry);
+       ns_path.dentry = proc_ns_get_dentry(sb, task, ei->ns_ops);
+       if (IS_ERR(ns_path.dentry)) {
+               error = ERR_CAST(ns_path.dentry);
                goto out_put_task;
        }
 
-       dput(nd->path.dentry);
-       nd->path.dentry = ns_dentry;
+       ns_path.mnt = mntget(nd->path.mnt);
+       nd_jump_link(nd, &ns_path);
        error = NULL;
 
 out_put_task:
index 43098bb5723af2890acaaa8d2f3a86a37fc7b811..2e8caa62da78a71cc1ee46ce49634aab9408a779 100644 (file)
@@ -412,6 +412,7 @@ static struct file_system_type qnx4_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("qnx4");
 
 static int __init init_qnx4_fs(void)
 {
index 57199a52a3510688c09f25553dc4557de3b65696..8d941edfefa156bedb93a1a074ccda0e9a042fad 100644 (file)
@@ -672,6 +672,7 @@ static struct file_system_type qnx6_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("qnx6");
 
 static int __init init_qnx6_fs(void)
 {
index 418bdc3a57da4e11092477fa1b3cbf2e37f71422..194113b1b11bf045f232899d01c28effe6cab786 100644 (file)
@@ -2434,6 +2434,7 @@ struct file_system_type reiserfs_fs_type = {
        .kill_sb = reiserfs_kill_sb,
        .fs_flags = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("reiserfs");
 
 MODULE_DESCRIPTION("ReiserFS journaled filesystem");
 MODULE_AUTHOR("Hans Reiser <reiser@namesys.com>");
index 7e8d3a80bdab1dcfce41d121cb074e58bf850679..15cbc41ee3653133c6e7001aec75e754582362e6 100644 (file)
@@ -599,6 +599,7 @@ static struct file_system_type romfs_fs_type = {
        .kill_sb        = romfs_kill_sb,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("romfs");
 
 /*
  * inode storage initialiser
index a38e87bdd78dcb6fa112f954b30a93de9dc06420..a39938b1feea148dcecbb8db3731bd37832396fc 100644 (file)
@@ -545,6 +545,7 @@ static struct file_system_type sysv_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("sysv");
 
 static struct file_system_type v7_fs_type = {
        .owner          = THIS_MODULE,
@@ -553,6 +554,7 @@ static struct file_system_type v7_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("v7");
 
 static int __init init_sysv_fs(void)
 {
@@ -586,5 +588,4 @@ static void __exit exit_sysv_fs(void)
 
 module_init(init_sysv_fs)
 module_exit(exit_sysv_fs)
-MODULE_ALIAS("v7");
 MODULE_LICENSE("GPL");
index ddc0f6ae65e9992af3dc689ad61021e86c5e40a1..ac838b844936cdc29be5f3eff7192e9cb9a15582 100644 (file)
@@ -2174,6 +2174,7 @@ static struct file_system_type ubifs_fs_type = {
        .mount   = ubifs_mount,
        .kill_sb = kill_ubifs_super,
 };
+MODULE_ALIAS_FS("ubifs");
 
 /*
  * Inode slab cache constructor.
index dc8e3a861d0fcddc79d3113b179672d7b59978e8..329f2f53b7ed655b2ef525331f7c75a714d58de9 100644 (file)
@@ -1500,6 +1500,7 @@ static struct file_system_type ufs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("ufs");
 
 static int __init init_ufs_fs(void)
 {
index c407121873b4763984f21870723e6e517b03f23c..ea341cea68cbfc5a7798810f0239ff34bfedfb09 100644 (file)
@@ -1561,6 +1561,7 @@ static struct file_system_type xfs_fs_type = {
        .kill_sb                = kill_block_super,
        .fs_flags               = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("xfs");
 
 STATIC int __init
 xfs_init_zones(void)
index e65278f560c40593e5a3f6fd8b520d5fce3f4468..22ba56e834e279c55d439a97144498457609f349 100644 (file)
@@ -437,11 +437,9 @@ void acpi_remove_dir(struct acpi_device *);
  */
 struct acpi_bus_type {
        struct list_head list;
-       struct bus_type *bus;
-       /* For general devices under the bus */
+       const char *name;
+       bool (*match)(struct device *dev);
        int (*find_device) (struct device *, acpi_handle *);
-       /* For bridges, such as PCI root bridge, IDE controller */
-       int (*find_bridge) (struct device *, acpi_handle *);
        void (*setup)(struct device *);
        void (*cleanup)(struct device *);
 };
index 8839b3a246608989089582f7a20cd237d4f177cd..e3e0d651c6cab54b51745a242a844b142a64bc71 100644 (file)
@@ -443,12 +443,12 @@ struct drm_crtc {
  * @dpms: set power state (see drm_crtc_funcs above)
  * @save: save connector state
  * @restore: restore connector state
- * @reset: reset connector after state has been invalidate (e.g. resume)
+ * @reset: reset connector after state has been invalidated (e.g. resume)
  * @detect: is this connector active?
  * @fill_modes: fill mode list for this connector
- * @set_property: property for this connector may need update
+ * @set_property: property for this connector may need an update
  * @destroy: make object go away
- * @force: notify the driver the connector is forced on
+ * @force: notify the driver that the connector is forced on
  *
  * Each CRTC may have one or more connectors attached to it.  The functions
  * below allow the core DRM code to control connectors, enumerate available modes,
index 2224a8c0cb6404974c217cfb825576c4fcf9665a..8d5ab998a222565c44df58930b70dafa38381a6b 100644 (file)
@@ -6,9 +6,8 @@
 #define ECRYPTFS_VERSION_MINOR 0x04
 #define ECRYPTFS_SUPPORTED_FILE_VERSION 0x03
 /* These flags indicate which features are supported by the kernel
- * module; userspace tools such as the mount helper read
- * ECRYPTFS_VERSIONING_MASK from a sysfs handle in order to determine
- * how to behave. */
+ * module; userspace tools such as the mount helper read the feature
+ * bits from a sysfs handle in order to determine how to behave. */
 #define ECRYPTFS_VERSIONING_PASSPHRASE            0x00000001
 #define ECRYPTFS_VERSIONING_PUBKEY                0x00000002
 #define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004
 #define ECRYPTFS_VERSIONING_HMAC                  0x00000080
 #define ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION   0x00000100
 #define ECRYPTFS_VERSIONING_GCM                   0x00000200
-#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \
-                                 | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \
-                                 | ECRYPTFS_VERSIONING_PUBKEY \
-                                 | ECRYPTFS_VERSIONING_XATTR \
-                                 | ECRYPTFS_VERSIONING_MULTKEY \
-                                 | ECRYPTFS_VERSIONING_DEVMISC \
-                                 | ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION)
 #define ECRYPTFS_MAX_PASSWORD_LENGTH 64
 #define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH
 #define ECRYPTFS_SALT_SIZE 8
index 74a907b8b950c5c7d8e2e736003258429f01abf0..2c28271ab9d40a834c50931084cb15e8860cd765 100644 (file)
@@ -1825,6 +1825,8 @@ struct file_system_type {
        struct lock_class_key i_mutex_dir_key;
 };
 
+#define MODULE_ALIAS_FS(NAME) MODULE_ALIAS("fs-" NAME)
+
 extern struct dentry *mount_ns(struct file_system_type *fs_type, int flags,
        void *data, int (*fill_super)(struct super_block *, void *, int));
 extern struct dentry *mount_bdev(struct file_system_type *fs_type,
index 29eb805ea4a6b2c98236bbd0f24cc00a45ec53df..c1d6555d2567468f86a6c1b6d745d927f1a25815 100644 (file)
 
 #ifdef CONFIG_PREEMPT_COUNT
 # define preemptible() (preempt_count() == 0 && !irqs_disabled())
-# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
 #else
 # define preemptible() 0
-# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
 
 #if defined(CONFIG_SMP) || defined(CONFIG_GENERIC_HARDIRQS)
index f027f7a63511bbdcd0daf459e5dce65434117dcf..99e379b74398e645e060f523cd29f8c5dca4dab3 100644 (file)
@@ -15,6 +15,9 @@
 
 #include <linux/types.h>
 
+/* For key_map array */
+#define MXT_NUM_GPIO           4
+
 /* Orient */
 #define MXT_NORMAL             0x0
 #define MXT_DIAGONAL           0x1
@@ -39,6 +42,8 @@ struct mxt_platform_data {
        unsigned int voltage;
        unsigned char orient;
        unsigned long irqflags;
+       bool is_tp;
+       const unsigned int key_map[MXT_NUM_GPIO];
 };
 
 #endif /* __LINUX_ATMEL_MXT_TS_H */
index ef9acd3c84506fcd3525166501387445181e92c0..01d25e6fc792472692f6e601de77a7b83fe69734 100644 (file)
@@ -854,6 +854,8 @@ type_pf_tresize(struct ip_set *set, bool retried)
 retry:
        ret = 0;
        htable_bits++;
+       pr_debug("attempt to resize set %s from %u to %u, t %p\n",
+                set->name, orig->htable_bits, htable_bits, orig);
        if (!htable_bits) {
                /* In case we have plenty of memory :-) */
                pr_warning("Cannot increase the hashsize of set %s further\n",
@@ -873,7 +875,7 @@ retry:
                        data = ahash_tdata(n, j);
                        m = hbucket(t, HKEY(data, h->initval, htable_bits));
                        ret = type_pf_elem_tadd(m, data, AHASH_MAX(h), 0,
-                                               type_pf_data_timeout(data));
+                                               ip_set_timeout_get(type_pf_data_timeout(data)));
                        if (ret < 0) {
                                read_unlock_bh(&set->lock);
                                ahash_destroy(t);
index 23070fd83872004cdb91367ef1857c0d6ca04a52..7df93f52db089afb7f65ca574e89ee4996714d08 100644 (file)
@@ -199,6 +199,8 @@ enum regulator_type {
  *                output when using regulator_set_voltage_sel_regmap
  * @enable_reg: Register for control when using regmap enable/disable ops
  * @enable_mask: Mask for control when using regmap enable/disable ops
+ * @bypass_reg: Register for control when using regmap set_bypass
+ * @bypass_mask: Mask for control when using regmap set_bypass
  *
  * @enable_time: Time taken for initial enable of regulator (in uS).
  */
index c65dee059913c8d429a614bf3c9b16e088369216..13e929679550ab4967b72a73e544dbf531f74004 100644 (file)
@@ -24,6 +24,9 @@ struct smpboot_thread_data;
  *                     parked (cpu offline)
  * @unpark:            Optional unpark function, called when the thread is
  *                     unparked (cpu online)
+ * @pre_unpark:                Optional unpark function, called before the thread is
+ *                     unparked (cpu online). This is not guaranteed to be
+ *                     called on the target cpu of the thread. Careful!
  * @selfparking:       Thread is not parked by the park function.
  * @thread_comm:       The base name of the thread
  */
@@ -37,6 +40,7 @@ struct smp_hotplug_thread {
        void                            (*cleanup)(unsigned int cpu, bool online);
        void                            (*park)(unsigned int cpu);
        void                            (*unpark)(unsigned int cpu);
+       void                            (*pre_unpark)(unsigned int cpu);
        bool                            selfparking;
        const char                      *thread_comm;
 };
index 23f2e98d4b654dbd497def51219cbe0806c23cb8..cf0694d4ad60f62be703eaec51db142b9c5c4e29 100644 (file)
@@ -1045,6 +1045,10 @@ static inline bool tcp_prequeue(struct sock *sk, struct sk_buff *skb)
        if (sysctl_tcp_low_latency || !tp->ucopy.task)
                return false;
 
+       if (skb->len <= tcp_hdrlen(skb) &&
+           skb_queue_len(&tp->ucopy.prequeue) == 0)
+               return false;
+
        __skb_queue_tail(&tp->ucopy.prequeue, skb);
        tp->ucopy.memory += skb->truesize;
        if (tp->ucopy.memory > sk->sk_rcvbuf) {
index 950572f9d7963858d46e01998fea00e14024f26b..31cd1bf6af271771e67bdf6e29eb306371d3d130 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -820,15 +820,17 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp,
        struct msg_msg *copy = NULL;
        unsigned long copy_number = 0;
 
+       ns = current->nsproxy->ipc_ns;
+
        if (msqid < 0 || (long) bufsz < 0)
                return -EINVAL;
        if (msgflg & MSG_COPY) {
-               copy = prepare_copy(buf, bufsz, msgflg, &msgtyp, &copy_number);
+               copy = prepare_copy(buf, min_t(size_t, bufsz, ns->msg_ctlmax),
+                                   msgflg, &msgtyp, &copy_number);
                if (IS_ERR(copy))
                        return PTR_ERR(copy);
        }
        mode = convert_mode(&msgtyp, msgflg);
-       ns = current->nsproxy->ipc_ns;
 
        msq = msg_lock_check(ns, msqid);
        if (IS_ERR(msq)) {
index ebfcbfa8b7f25a4193dcfd196963e4b87428a6e6..5df8e4bf1db00debfedc37a3487cfddc612126ad 100644 (file)
@@ -117,9 +117,6 @@ struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst)
        if (alen > DATALEN_MSG)
                alen = DATALEN_MSG;
 
-       dst->next = NULL;
-       dst->security = NULL;
-
        memcpy(dst + 1, src + 1, alen);
 
        len -= alen;
index b9bde572782932f24d8a3a9f3a4f0670cb07b633..8eaed9aa9cf0c1995520605af1de8ef3b9e95485 100644 (file)
@@ -131,7 +131,7 @@ static int smpboot_thread_fn(void *data)
                        continue;
                }
 
-               //BUG_ON(td->cpu != smp_processor_id());
+               BUG_ON(td->cpu != smp_processor_id());
 
                /* Check for state change setup */
                switch (td->status) {
@@ -209,6 +209,8 @@ static void smpboot_unpark_thread(struct smp_hotplug_thread *ht, unsigned int cp
 {
        struct task_struct *tsk = *per_cpu_ptr(ht->store, cpu);
 
+       if (ht->pre_unpark)
+               ht->pre_unpark(cpu);
        kthread_unpark(tsk);
 }
 
index b4d252fd195b927afd402977b64efb3faa7ed96f..14d7758074aadf4d1c43947ecef675e8bb6c044e 100644 (file)
@@ -323,18 +323,10 @@ void irq_enter(void)
 
 static inline void invoke_softirq(void)
 {
-       if (!force_irqthreads) {
-#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
+       if (!force_irqthreads)
                __do_softirq();
-#else
-               do_softirq();
-#endif
-       } else {
-               __local_bh_disable((unsigned long)__builtin_return_address(0),
-                               SOFTIRQ_OFFSET);
+       else
                wakeup_softirqd();
-               __local_bh_enable(SOFTIRQ_OFFSET);
-       }
 }
 
 /*
@@ -342,9 +334,15 @@ static inline void invoke_softirq(void)
  */
 void irq_exit(void)
 {
+#ifndef __ARCH_IRQ_EXIT_IRQS_DISABLED
+       local_irq_disable();
+#else
+       WARN_ON_ONCE(!irqs_disabled());
+#endif
+
        account_irq_exit_time(current);
        trace_hardirq_exit();
-       sub_preempt_count(IRQ_EXIT_OFFSET);
+       sub_preempt_count(HARDIRQ_OFFSET);
        if (!in_interrupt() && local_softirq_pending())
                invoke_softirq();
 
@@ -354,7 +352,6 @@ void irq_exit(void)
                tick_nohz_irq_exit();
 #endif
        rcu_irq_exit();
-       sched_preempt_enable_no_resched();
 }
 
 /*
index 95d178c62d5a8537c18fa2d6f1d947aed1a93448..c09f2955ae3055b42f1edde601ee1eb431bfc18a 100644 (file)
@@ -336,7 +336,7 @@ static struct smp_hotplug_thread cpu_stop_threads = {
        .create                 = cpu_stop_create,
        .setup                  = cpu_stop_unpark,
        .park                   = cpu_stop_park,
-       .unpark                 = cpu_stop_unpark,
+       .pre_unpark             = cpu_stop_unpark,
        .selfparking            = true,
 };
 
index 73f4d53c02f3deaee2a0df5b2909a218b38a10e8..00739aaf95a2717536957f9cb08413621417a2f8 100644 (file)
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -569,8 +569,7 @@ void idr_remove(struct idr *idp, int id)
        struct idr_layer *p;
        struct idr_layer *to_free;
 
-       /* see comment in idr_find_slowpath() */
-       if (WARN_ON_ONCE(id < 0))
+       if (id < 0)
                return;
 
        sub_remove(idp, (idp->layers - 1) * IDR_BITS, id);
@@ -667,15 +666,7 @@ void *idr_find_slowpath(struct idr *idp, int id)
        int n;
        struct idr_layer *p;
 
-       /*
-        * If @id is negative, idr_find() used to ignore the sign bit and
-        * performed lookup with the rest of bits, which is weird and can
-        * lead to very obscure bugs.  We're now returning NULL for all
-        * negative IDs but just in case somebody was depending on the sign
-        * bit being ignored, let's trigger WARN_ON_ONCE() so that they can
-        * be detected and fixed.  WARN_ON_ONCE() can later be removed.
-        */
-       if (WARN_ON_ONCE(id < 0))
+       if (id < 0)
                return NULL;
 
        p = rcu_dereference_raw(idp->top);
@@ -824,8 +815,7 @@ void *idr_replace(struct idr *idp, void *ptr, int id)
        int n;
        struct idr_layer *p, *old_p;
 
-       /* see comment in idr_find_slowpath() */
-       if (WARN_ON_ONCE(id < 0))
+       if (id < 0)
                return ERR_PTR(-EINVAL);
 
        p = idp->top;
index 85bfd4c1634629dc35a2f671c43cd3e2d8c818cc..b6afe0c440d8b3e500f4a09e2875491c7d70199a 100644 (file)
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -489,7 +489,7 @@ out:                page = NULL;
  */
 static inline int get_kpfn_nid(unsigned long kpfn)
 {
-       return ksm_merge_across_nodes ? 0 : pfn_to_nid(kpfn);
+       return ksm_merge_across_nodes ? 0 : NUMA(pfn_to_nid(kpfn));
 }
 
 static void remove_node_from_stable_tree(struct stable_node *stable_node)
index 53b8201b31eb6f21bf66a3ca26f07fbf39f21c65..2b552224f5cf7f8b0807d244963df29fbb245634 100644 (file)
@@ -3012,6 +3012,8 @@ void memcg_update_array_size(int num)
                memcg_limited_groups_array_size = memcg_caches_array_size(num);
 }
 
+static void kmem_cache_destroy_work_func(struct work_struct *w);
+
 int memcg_update_cache_size(struct kmem_cache *s, int num_groups)
 {
        struct memcg_cache_params *cur_params = s->memcg_params;
@@ -3031,6 +3033,8 @@ int memcg_update_cache_size(struct kmem_cache *s, int num_groups)
                        return -ENOMEM;
                }
 
+               INIT_WORK(&s->memcg_params->destroy,
+                               kmem_cache_destroy_work_func);
                s->memcg_params->is_root_cache = true;
 
                /*
@@ -3078,6 +3082,8 @@ int memcg_register_cache(struct mem_cgroup *memcg, struct kmem_cache *s,
        if (!s->memcg_params)
                return -ENOMEM;
 
+       INIT_WORK(&s->memcg_params->destroy,
+                       kmem_cache_destroy_work_func);
        if (memcg) {
                s->memcg_params->memcg = memcg;
                s->memcg_params->root_cache = root_cache;
@@ -3358,8 +3364,6 @@ static void mem_cgroup_destroy_all_caches(struct mem_cgroup *memcg)
        list_for_each_entry(params, &memcg->memcg_slab_caches, list) {
                cachep = memcg_params_to_cache(params);
                cachep->memcg_params->dead = true;
-               INIT_WORK(&cachep->memcg_params->destroy,
-                                 kmem_cache_destroy_work_func);
                schedule_work(&cachep->memcg_params->destroy);
        }
        mutex_unlock(&memcg->slab_caches_mutex);
index 31d26637b6587acac54e83ecc017ac063ec0d11d..74310017296ee02317b79a2c28b25ef303fc7720 100644 (file)
@@ -2390,9 +2390,9 @@ restart:
 
                                *mpol_new = *n->policy;
                                atomic_set(&mpol_new->refcnt, 1);
-                               sp_node_init(n_new, n->end, end, mpol_new);
-                               sp_insert(sp, n_new);
+                               sp_node_init(n_new, end, n->end, mpol_new);
                                n->end = start;
+                               sp_insert(sp, n_new);
                                n_new = NULL;
                                mpol_new = NULL;
                                break;
index 74dea377fe5b1ee2b111cd2b433647195a5ab782..de2e950a0a7a8724a06618b45334e0c544278f70 100644 (file)
@@ -655,7 +655,7 @@ static struct p9_trans_module p9_virtio_trans = {
        .create = p9_virtio_create,
        .close = p9_virtio_close,
        .request = p9_virtio_request,
-       //.zc_request = p9_virtio_zc_request,
+       .zc_request = p9_virtio_zc_request,
        .cancel = p9_virtio_cancel,
        /*
         * We leave one entry for input and one entry for response
index 1ae1d9cb278d4047083214ba0336dd846f4822a1..21760f0089749217e03790e02b49998fc5a7958c 100644 (file)
@@ -118,7 +118,7 @@ static struct caif_device_entry *caif_get(struct net_device *dev)
        return NULL;
 }
 
-void caif_flow_cb(struct sk_buff *skb)
+static void caif_flow_cb(struct sk_buff *skb)
 {
        struct caif_device_entry *caifd;
        void (*dtor)(struct sk_buff *skb) = NULL;
index 3ebc8cbc91fff419097799784dad4aa374ced101..ef8ebaa993cf3ca9c915f8d2a230a3d04af79c34 100644 (file)
@@ -81,8 +81,8 @@ static void cfusbl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
                layr->up->ctrlcmd(layr->up, ctrl, layr->id);
 }
 
-struct cflayer *cfusbl_create(int phyid, u8 ethaddr[ETH_ALEN],
-                                       u8 braddr[ETH_ALEN])
+static struct cflayer *cfusbl_create(int phyid, u8 ethaddr[ETH_ALEN],
+                                     u8 braddr[ETH_ALEN])
 {
        struct cfusbl *this = kmalloc(sizeof(struct cfusbl), GFP_ATOMIC);
 
index 87abd3e2bd329d7ee3630cbc3ed4770d35e6370e..2bdf802e28e270c4717c06bc64469eab073f068d 100644 (file)
@@ -228,9 +228,11 @@ static int ip_local_deliver_finish(struct sk_buff *skb)
                                        icmp_send(skb, ICMP_DEST_UNREACH,
                                                  ICMP_PROT_UNREACH, 0);
                                }
-                       } else
+                               kfree_skb(skb);
+                       } else {
                                IP_INC_STATS_BH(net, IPSTATS_MIB_INDELIVERS);
-                       kfree_skb(skb);
+                               consume_skb(skb);
+                       }
                }
        }
  out:
index a759e19496d2f57f508db27f21ab73b2b320523a..0d9bdacce99f46a77982d89c86a7764fe9ef15f8 100644 (file)
@@ -5485,6 +5485,9 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
                                if (tcp_checksum_complete_user(sk, skb))
                                        goto csum_error;
 
+                               if ((int)skb->truesize > sk->sk_forward_alloc)
+                                       goto step5;
+
                                /* Predicted packet is in window by definition.
                                 * seq == rcv_nxt and rcv_wup <= rcv_nxt.
                                 * Hence, check seq<=rcv_wup reduces to:
@@ -5496,9 +5499,6 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
 
                                tcp_rcv_rtt_measure_ts(sk, skb);
 
-                               if ((int)skb->truesize > sk->sk_forward_alloc)
-                                       goto step5;
-
                                NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPHPHITS);
 
                                /* Bulk data transfer: receiver */
index 5b10414e619e5020fa4285a1e20790bdf5a8e845..b1876e52091e1ea2568b5b1acf9411df5986ef84 100644 (file)
@@ -241,9 +241,11 @@ resubmit:
                                icmpv6_send(skb, ICMPV6_PARAMPROB,
                                            ICMPV6_UNK_NEXTHDR, nhoff);
                        }
-               } else
+                       kfree_skb(skb);
+               } else {
                        IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDELIVERS);
-               kfree_skb(skb);
+                       consume_skb(skb);
+               }
        }
        rcu_read_unlock();
        return 0;
index 928266569689e7624cde4206f657df495a0bdd43..e5fe0041adfa389388060bffae7055db3508c407 100644 (file)
@@ -1915,7 +1915,8 @@ void rt6_purge_dflt_routers(struct net *net)
 restart:
        read_lock_bh(&table->tb6_lock);
        for (rt = table->tb6_root.leaf; rt; rt = rt->dst.rt6_next) {
-               if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) {
+               if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF) &&
+                   (!rt->rt6i_idev || rt->rt6i_idev->cnf.accept_ra != 2)) {
                        dst_hold(&rt->dst);
                        read_unlock_bh(&table->tb6_lock);
                        ip6_del_rt(rt);
index e71e85ba2bf1c180b2038d62021283ddf7982b07..29340a9a6fb9937f9bc848ffda5c49c51cca47ee 100644 (file)
@@ -495,8 +495,11 @@ static void iriap_getvaluebyclass_confirm(struct iriap_cb *self,
 /*             case CS_ISO_8859_9: */
 /*             case CS_UNICODE: */
                default:
-                       IRDA_DEBUG(0, "%s(), charset %s, not supported\n",
-                                  __func__, ias_charset_types[charset]);
+                       IRDA_DEBUG(0, "%s(), charset [%d] %s, not supported\n",
+                                  __func__, charset,
+                                  charset < ARRAY_SIZE(ias_charset_types) ?
+                                       ias_charset_types[charset] :
+                                       "(unknown)");
 
                        /* Aborting, close connection! */
                        iriap_disconnect_request(self);
index 3f4e3afc191a524d57c29659324ddc0ac6cd9c1e..6a53371dba1f1b357f9cd4f34b7af166ed324eab 100644 (file)
@@ -355,6 +355,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
        l2tp_xmit_skb(session, skb, session->hdr_len);
 
        sock_put(ps->tunnel_sock);
+       sock_put(sk);
 
        return error;
 
index 09d96a8f6c2c7c64679bef8062d7d87db75addc1..808f5fcd1ced92127f8786700a759465e0708060 100644 (file)
@@ -3285,13 +3285,19 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
                                     struct cfg80211_chan_def *chandef)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+       struct ieee80211_local *local = wiphy_priv(wiphy);
        struct ieee80211_chanctx_conf *chanctx_conf;
        int ret = -ENODATA;
 
        rcu_read_lock();
-       chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
-       if (chanctx_conf) {
-               *chandef = chanctx_conf->def;
+       if (local->use_chanctx) {
+               chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
+               if (chanctx_conf) {
+                       *chandef = chanctx_conf->def;
+                       ret = 0;
+               }
+       } else if (local->open_count == local->monitors) {
+               *chandef = local->monitor_chandef;
                ret = 0;
        }
        rcu_read_unlock();
index 2c059e54e88575bf1364a17b9a9bc2f020c5a7a6..640afab304d7a02e50414a16f3df8e22c6ea4c30 100644 (file)
@@ -107,7 +107,7 @@ void ieee80211_recalc_idle(struct ieee80211_local *local)
 
        lockdep_assert_held(&local->mtx);
 
-       active = !list_empty(&local->chanctx_list);
+       active = !list_empty(&local->chanctx_list) || local->monitors;
 
        if (!local->ops->remain_on_channel) {
                list_for_each_entry(roc, &local->roc_list, list) {
index de8548bf0a7f27cef20e06077d3c603ad22a7baa..ce78d1149f1dc2e873eb4291ce9459b40a89b4db 100644 (file)
@@ -1231,34 +1231,40 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local,
                if (local->queue_stop_reasons[q] ||
                    (!txpending && !skb_queue_empty(&local->pending[q]))) {
                        if (unlikely(info->flags &
-                                       IEEE80211_TX_INTFL_OFFCHAN_TX_OK &&
-                                    local->queue_stop_reasons[q] &
-                                       ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL))) {
+                                    IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) {
+                               if (local->queue_stop_reasons[q] &
+                                   ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL)) {
+                                       /*
+                                        * Drop off-channel frames if queues
+                                        * are stopped for any reason other
+                                        * than off-channel operation. Never
+                                        * queue them.
+                                        */
+                                       spin_unlock_irqrestore(
+                                               &local->queue_stop_reason_lock,
+                                               flags);
+                                       ieee80211_purge_tx_queue(&local->hw,
+                                                                skbs);
+                                       return true;
+                               }
+                       } else {
+
                                /*
-                                * Drop off-channel frames if queues are stopped
-                                * for any reason other than off-channel
-                                * operation. Never queue them.
+                                * Since queue is stopped, queue up frames for
+                                * later transmission from the tx-pending
+                                * tasklet when the queue is woken again.
                                 */
-                               spin_unlock_irqrestore(
-                                       &local->queue_stop_reason_lock, flags);
-                               ieee80211_purge_tx_queue(&local->hw, skbs);
-                               return true;
+                               if (txpending)
+                                       skb_queue_splice_init(skbs,
+                                                             &local->pending[q]);
+                               else
+                                       skb_queue_splice_tail_init(skbs,
+                                                                  &local->pending[q]);
+
+                               spin_unlock_irqrestore(&local->queue_stop_reason_lock,
+                                                      flags);
+                               return false;
                        }
-
-                       /*
-                        * Since queue is stopped, queue up frames for later
-                        * transmission from the tx-pending tasklet when the
-                        * queue is woken again.
-                        */
-                       if (txpending)
-                               skb_queue_splice_init(skbs, &local->pending[q]);
-                       else
-                               skb_queue_splice_tail_init(skbs,
-                                                          &local->pending[q]);
-
-                       spin_unlock_irqrestore(&local->queue_stop_reason_lock,
-                                              flags);
-                       return false;
                }
                spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 
@@ -1844,9 +1850,24 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                }
 
                if (!is_multicast_ether_addr(skb->data)) {
+                       struct sta_info *next_hop;
+                       bool mpp_lookup = true;
+
                        mpath = mesh_path_lookup(sdata, skb->data);
-                       if (!mpath)
+                       if (mpath) {
+                               mpp_lookup = false;
+                               next_hop = rcu_dereference(mpath->next_hop);
+                               if (!next_hop ||
+                                   !(mpath->flags & (MESH_PATH_ACTIVE |
+                                                     MESH_PATH_RESOLVING)))
+                                       mpp_lookup = true;
+                       }
+
+                       if (mpp_lookup)
                                mppath = mpp_path_lookup(sdata, skb->data);
+
+                       if (mppath && mpath)
+                               mesh_path_del(mpath->sdata, mpath->dst);
                }
 
                /*
@@ -2350,9 +2371,9 @@ static int ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
        if (local->tim_in_locked_section) {
                __ieee80211_beacon_add_tim(sdata, ps, skb);
        } else {
-               spin_lock(&local->tim_lock);
+               spin_lock_bh(&local->tim_lock);
                __ieee80211_beacon_add_tim(sdata, ps, skb);
-               spin_unlock(&local->tim_lock);
+               spin_unlock_bh(&local->tim_lock);
        }
 
        return 0;
index f82b2e606cfd53048d5e208855d0d18fb5539a74..1ba9dbc0e107cae96efdf58b4b18d7c4d38d9e6b 100644 (file)
@@ -1470,7 +1470,8 @@ ip_set_utest(struct sock *ctnl, struct sk_buff *skb,
        if (ret == -EAGAIN)
                ret = 1;
 
-       return ret < 0 ? ret : ret > 0 ? 0 : -IPSET_ERR_EXIST;
+       return (ret < 0 && ret != -ENOTEMPTY) ? ret :
+               ret > 0 ? 0 : -IPSET_ERR_EXIST;
 }
 
 /* Get headed data of a set */
index f0a4658f3273e2e87bac1ae88058e1209ed3332a..aba232f9f3081968081edb0ed6ece382e954b653 100644 (file)
@@ -82,10 +82,7 @@ static void rds_message_purge(struct rds_message *rm)
 void rds_message_put(struct rds_message *rm)
 {
        rdsdebug("put rm %p ref %d\n", rm, atomic_read(&rm->m_refcount));
-       if (atomic_read(&rm->m_refcount) == 0) {
-printk(KERN_CRIT "danger refcount zero on %p\n", rm);
-WARN_ON(1);
-       }
+       WARN(!atomic_read(&rm->m_refcount), "danger refcount zero on %p\n", rm);
        if (atomic_dec_and_test(&rm->m_refcount)) {
                BUG_ON(!list_empty(&rm->m_sock_item));
                BUG_ON(!list_empty(&rm->m_conn_item));
@@ -197,6 +194,9 @@ struct rds_message *rds_message_alloc(unsigned int extra_len, gfp_t gfp)
 {
        struct rds_message *rm;
 
+       if (extra_len > KMALLOC_MAX_SIZE - sizeof(struct rds_message))
+               return NULL;
+
        rm = kzalloc(sizeof(struct rds_message) + extra_len, gfp);
        if (!rm)
                goto out;
index 2b3ef03c60984050d542834433bd9a1e0ef6645a..12ed45dbe75d6b779fd0dcf4d38f6126e23c03fb 100644 (file)
@@ -155,7 +155,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
 
        /* SCTP-AUTH extensions*/
        INIT_LIST_HEAD(&ep->endpoint_shared_keys);
-       null_key = sctp_auth_shkey_create(0, GFP_KERNEL);
+       null_key = sctp_auth_shkey_create(0, gfp);
        if (!null_key)
                goto nomem;
 
index c99458df3f3fd458eac2d5f5388b6fba6aed4e3a..b9070736b8d9a24383be81b1764d191e854d3e63 100644 (file)
@@ -5653,6 +5653,9 @@ static int sctp_getsockopt_assoc_stats(struct sock *sk, int len,
        if (len < sizeof(sctp_assoc_t))
                return -EINVAL;
 
+       /* Allow the struct to grow and fill in as much as possible */
+       len = min_t(size_t, len, sizeof(sas));
+
        if (copy_from_user(&sas, optval, len))
                return -EFAULT;
 
@@ -5686,9 +5689,6 @@ static int sctp_getsockopt_assoc_stats(struct sock *sk, int len,
        /* Mark beginning of a new observation period */
        asoc->stats.max_obs_rto = asoc->rto_min;
 
-       /* Allow the struct to grow and fill in as much as possible */
-       len = min_t(size_t, len, sizeof(sas));
-
        if (put_user(len, optlen))
                return -EFAULT;
 
index 442ad4ed6315fab99ec5b78d012e65a8236e2fae..825ea94415b39818f637b54c5abe112394edc322 100644 (file)
@@ -41,8 +41,6 @@
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
 
-#define MAX_KMALLOC_SIZE       131072
-
 static struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in,
                                            __u16 out);
 
@@ -65,7 +63,7 @@ struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out,
        int size;
 
        size = sctp_ssnmap_size(in, out);
-       if (size <= MAX_KMALLOC_SIZE)
+       if (size <= KMALLOC_MAX_SIZE)
                retval = kmalloc(size, gfp);
        else
                retval = (struct sctp_ssnmap *)
@@ -82,7 +80,7 @@ struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out,
        return retval;
 
 fail_map:
-       if (size <= MAX_KMALLOC_SIZE)
+       if (size <= KMALLOC_MAX_SIZE)
                kfree(retval);
        else
                free_pages((unsigned long)retval, get_order(size));
@@ -124,7 +122,7 @@ void sctp_ssnmap_free(struct sctp_ssnmap *map)
                int size;
 
                size = sctp_ssnmap_size(map->in.len, map->out.len);
-               if (size <= MAX_KMALLOC_SIZE)
+               if (size <= KMALLOC_MAX_SIZE)
                        kfree(map);
                else
                        free_pages((unsigned long)map, get_order(size));
index 5f25e0c92c31e48460536cd2bb0fc29549172b93..396c45174e5b696d90c6940d7aa0ce511c70293c 100644 (file)
@@ -51,7 +51,7 @@
 static void sctp_tsnmap_update(struct sctp_tsnmap *map);
 static void sctp_tsnmap_find_gap_ack(unsigned long *map, __u16 off,
                                     __u16 len, __u16 *start, __u16 *end);
-static int sctp_tsnmap_grow(struct sctp_tsnmap *map, u16 gap);
+static int sctp_tsnmap_grow(struct sctp_tsnmap *map, u16 size);
 
 /* Initialize a block of memory as a tsnmap.  */
 struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *map, __u16 len,
@@ -124,7 +124,7 @@ int sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn,
 
        gap = tsn - map->base_tsn;
 
-       if (gap >= map->len && !sctp_tsnmap_grow(map, gap))
+       if (gap >= map->len && !sctp_tsnmap_grow(map, gap + 1))
                return -ENOMEM;
 
        if (!sctp_tsnmap_has_gap(map) && gap == 0) {
@@ -360,23 +360,24 @@ __u16 sctp_tsnmap_num_gabs(struct sctp_tsnmap *map,
        return ngaps;
 }
 
-static int sctp_tsnmap_grow(struct sctp_tsnmap *map, u16 gap)
+static int sctp_tsnmap_grow(struct sctp_tsnmap *map, u16 size)
 {
        unsigned long *new;
        unsigned long inc;
        u16  len;
 
-       if (gap >= SCTP_TSN_MAP_SIZE)
+       if (size > SCTP_TSN_MAP_SIZE)
                return 0;
 
-       inc = ALIGN((gap - map->len),BITS_PER_LONG) + SCTP_TSN_MAP_INCREMENT;
+       inc = ALIGN((size - map->len), BITS_PER_LONG) + SCTP_TSN_MAP_INCREMENT;
        len = min_t(u16, map->len + inc, SCTP_TSN_MAP_SIZE);
 
        new = kzalloc(len>>3, GFP_ATOMIC);
        if (!new)
                return 0;
 
-       bitmap_copy(new, map->tsn_map, map->max_tsn_seen - map->base_tsn);
+       bitmap_copy(new, map->tsn_map,
+               map->max_tsn_seen - map->cumulative_tsn_ack_point);
        kfree(map->tsn_map);
        map->tsn_map = new;
        map->len = len;
index ada17464b65bf23a089c036fba47989a2a1d4b8b..0fd5b3d2df03158d17f0d356825209e571e419d7 100644 (file)
@@ -106,6 +106,7 @@ int sctp_ulpq_tail_data(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
 {
        struct sk_buff_head temp;
        struct sctp_ulpevent *event;
+       int event_eor = 0;
 
        /* Create an event from the incoming chunk. */
        event = sctp_ulpevent_make_rcvmsg(chunk->asoc, chunk, gfp);
@@ -127,10 +128,12 @@ int sctp_ulpq_tail_data(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
        /* Send event to the ULP.  'event' is the sctp_ulpevent for
         * very first SKB on the 'temp' list.
         */
-       if (event)
+       if (event) {
+               event_eor = (event->msg_flags & MSG_EOR) ? 1 : 0;
                sctp_ulpq_tail_event(ulpq, event);
+       }
 
-       return 0;
+       return event_eor;
 }
 
 /* Add a new event for propagation to the ULP.  */
@@ -540,14 +543,19 @@ static struct sctp_ulpevent *sctp_ulpq_retrieve_partial(struct sctp_ulpq *ulpq)
                ctsn = cevent->tsn;
 
                switch (cevent->msg_flags & SCTP_DATA_FRAG_MASK) {
+               case SCTP_DATA_FIRST_FRAG:
+                       if (!first_frag)
+                               return NULL;
+                       goto done;
                case SCTP_DATA_MIDDLE_FRAG:
                        if (!first_frag) {
                                first_frag = pos;
                                next_tsn = ctsn + 1;
                                last_frag = pos;
-                       } else if (next_tsn == ctsn)
+                       } else if (next_tsn == ctsn) {
                                next_tsn++;
-                       else
+                               last_frag = pos;
+                       } else
                                goto done;
                        break;
                case SCTP_DATA_LAST_FRAG:
@@ -651,6 +659,14 @@ static struct sctp_ulpevent *sctp_ulpq_retrieve_first(struct sctp_ulpq *ulpq)
                        } else
                                goto done;
                        break;
+
+               case SCTP_DATA_LAST_FRAG:
+                       if (!first_frag)
+                               return NULL;
+                       else
+                               goto done;
+                       break;
+
                default:
                        return NULL;
                }
@@ -962,20 +978,43 @@ static __u16 sctp_ulpq_renege_list(struct sctp_ulpq *ulpq,
                struct sk_buff_head *list, __u16 needed)
 {
        __u16 freed = 0;
-       __u32 tsn;
-       struct sk_buff *skb;
+       __u32 tsn, last_tsn;
+       struct sk_buff *skb, *flist, *last;
        struct sctp_ulpevent *event;
        struct sctp_tsnmap *tsnmap;
 
        tsnmap = &ulpq->asoc->peer.tsn_map;
 
-       while ((skb = __skb_dequeue_tail(list)) != NULL) {
-               freed += skb_headlen(skb);
+       while ((skb = skb_peek_tail(list)) != NULL) {
                event = sctp_skb2event(skb);
                tsn = event->tsn;
 
+               /* Don't renege below the Cumulative TSN ACK Point. */
+               if (TSN_lte(tsn, sctp_tsnmap_get_ctsn(tsnmap)))
+                       break;
+
+               /* Events in ordering queue may have multiple fragments
+                * corresponding to additional TSNs.  Sum the total
+                * freed space; find the last TSN.
+                */
+               freed += skb_headlen(skb);
+               flist = skb_shinfo(skb)->frag_list;
+               for (last = flist; flist; flist = flist->next) {
+                       last = flist;
+                       freed += skb_headlen(last);
+               }
+               if (last)
+                       last_tsn = sctp_skb2event(last)->tsn;
+               else
+                       last_tsn = tsn;
+
+               /* Unlink the event, then renege all applicable TSNs. */
+               __skb_unlink(skb, list);
                sctp_ulpevent_free(event);
-               sctp_tsnmap_renege(tsnmap, tsn);
+               while (TSN_lte(tsn, last_tsn)) {
+                       sctp_tsnmap_renege(tsnmap, tsn);
+                       tsn++;
+               }
                if (freed >= needed)
                        return freed;
        }
@@ -1002,16 +1041,28 @@ void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq,
        struct sctp_ulpevent *event;
        struct sctp_association *asoc;
        struct sctp_sock *sp;
+       __u32 ctsn;
+       struct sk_buff *skb;
 
        asoc = ulpq->asoc;
        sp = sctp_sk(asoc->base.sk);
 
        /* If the association is already in Partial Delivery mode
-        * we have noting to do.
+        * we have nothing to do.
         */
        if (ulpq->pd_mode)
                return;
 
+       /* Data must be at or below the Cumulative TSN ACK Point to
+        * start partial delivery.
+        */
+       skb = skb_peek(&asoc->ulpq.reasm);
+       if (skb != NULL) {
+               ctsn = sctp_skb2event(skb)->tsn;
+               if (!TSN_lte(ctsn, sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map)))
+                       return;
+       }
+
        /* If the user enabled fragment interleave socket option,
         * multiple associations can enter partial delivery.
         * Otherwise, we can only enter partial delivery if the
@@ -1054,12 +1105,16 @@ void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
        }
        /* If able to free enough room, accept this chunk. */
        if (chunk && (freed >= needed)) {
-               __u32 tsn;
-               tsn = ntohl(chunk->subh.data_hdr->tsn);
-               sctp_tsnmap_mark(&asoc->peer.tsn_map, tsn, chunk->transport);
-               sctp_ulpq_tail_data(ulpq, chunk, gfp);
-
-               sctp_ulpq_partial_delivery(ulpq, gfp);
+               int retval;
+               retval = sctp_ulpq_tail_data(ulpq, chunk, gfp);
+               /*
+                * Enter partial delivery if chunk has not been
+                * delivered; otherwise, drain the reassembly queue.
+                */
+               if (retval <= 0)
+                       sctp_ulpq_partial_delivery(ulpq, gfp);
+               else if (retval == 1)
+                       sctp_ulpq_reasm_drain(ulpq);
        }
 
        sk_mem_reclaim(asoc->base.sk);
index 7b9b40224a27768bb87014fdaa89d82413e7496f..a0f48a51e14e5e3b57a34970f0be204ec5c802ff 100644 (file)
@@ -1174,6 +1174,7 @@ static struct file_system_type rpc_pipe_fs_type = {
        .mount          = rpc_mount,
        .kill_sb        = rpc_kill_sb,
 };
+MODULE_ALIAS_FS("rpc_pipefs");
 
 static void
 init_once(void *foo)
@@ -1218,6 +1219,3 @@ void unregister_rpc_pipefs(void)
        kmem_cache_destroy(rpc_inode_cachep);
        unregister_filesystem(&rpc_pipe_fs_type);
 }
-
-/* Make 'mount -t rpc_pipefs ...' autoload this module. */
-MODULE_ALIAS("rpc_pipefs");
index 35545ccc30fd0079acb1e848c4ecaff0cdc8b371..e652d05ff712714f597857b225b432aafea1c34c 100644 (file)
@@ -554,16 +554,9 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
        if ((chan->flags & IEEE80211_CHAN_NO_IBSS) &&
            nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS))
                goto nla_put_failure;
-       if (chan->flags & IEEE80211_CHAN_RADAR) {
-               u32 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
-               if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
-                       goto nla_put_failure;
-               if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
-                               chan->dfs_state))
-                       goto nla_put_failure;
-               if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME, time))
-                       goto nla_put_failure;
-       }
+       if ((chan->flags & IEEE80211_CHAN_RADAR) &&
+           nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
+               goto nla_put_failure;
        if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
            nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
                goto nla_put_failure;
@@ -900,9 +893,6 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy,
                    nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
                                c->max_interfaces))
                        goto nla_put_failure;
-               if (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
-                               c->radar_detect_widths))
-                       goto nla_put_failure;
 
                nla_nest_end(msg, nl_combi);
        }
@@ -914,48 +904,6 @@ nla_put_failure:
        return -ENOBUFS;
 }
 
-#ifdef CONFIG_PM
-static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
-                                       struct sk_buff *msg)
-{
-       const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan.tcp;
-       struct nlattr *nl_tcp;
-
-       if (!tcp)
-               return 0;
-
-       nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
-       if (!nl_tcp)
-               return -ENOBUFS;
-
-       if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
-                       tcp->data_payload_max))
-               return -ENOBUFS;
-
-       if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
-                       tcp->data_payload_max))
-               return -ENOBUFS;
-
-       if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
-               return -ENOBUFS;
-
-       if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
-                               sizeof(*tcp->tok), tcp->tok))
-               return -ENOBUFS;
-
-       if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
-                       tcp->data_interval_max))
-               return -ENOBUFS;
-
-       if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
-                       tcp->wake_payload_max))
-               return -ENOBUFS;
-
-       nla_nest_end(msg, nl_tcp);
-       return 0;
-}
-#endif
-
 static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags,
                              struct cfg80211_registered_device *dev)
 {
@@ -1330,9 +1278,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
                                goto nla_put_failure;
                }
 
-               if (nl80211_send_wowlan_tcp_caps(dev, msg))
-                       goto nla_put_failure;
-
                nla_nest_end(msg, nl_wowlan);
        }
 #endif
index 58dfe089094793030f56fdb895f6621e403e4157..a571fad91010156aa7c532836b2a612e8e82e6fd 100644 (file)
@@ -839,7 +839,7 @@ void key_change_session_keyring(struct callback_head *twork)
        new-> sgid      = old-> sgid;
        new->fsgid      = old->fsgid;
        new->user       = get_uid(old->user);
-       new->user_ns    = get_user_ns(new->user_ns);
+       new->user_ns    = get_user_ns(old->user_ns);
        new->group_info = get_group_info(old->group_info);
 
        new->securebits = old->securebits;
index 066f5f3e3f4ca73b78be2a9b86c9baba4d47855b..c3908862bc8b63932aaa8724a50d7a5ae19a8cf3 100644 (file)
@@ -285,7 +285,12 @@ local_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev
 static int
 note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev)
 {
-       struct seq_oss_synthinfo *info = &dp->synths[dev];
+       struct seq_oss_synthinfo *info;
+
+       if (!snd_seq_oss_synth_is_valid(dp, dev))
+               return -ENXIO;
+
+       info = &dp->synths[dev];
        switch (info->arg.event_passing) {
        case SNDRV_SEQ_OSS_PROCESS_EVENTS:
                if (! info->ch || ch < 0 || ch >= info->nr_voices) {
@@ -340,7 +345,12 @@ note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, st
 static int
 note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev)
 {
-       struct seq_oss_synthinfo *info = &dp->synths[dev];
+       struct seq_oss_synthinfo *info;
+
+       if (!snd_seq_oss_synth_is_valid(dp, dev))
+               return -ENXIO;
+
+       info = &dp->synths[dev];
        switch (info->arg.event_passing) {
        case SNDRV_SEQ_OSS_PROCESS_EVENTS:
                if (! info->ch || ch < 0 || ch >= info->nr_voices) {
index 857586135d1820ee9310b2794716f4aef2c903eb..0097f3619faae2b955757a83377f171872b35b75 100644 (file)
@@ -213,7 +213,10 @@ static int slave_put(struct snd_kcontrol *kcontrol,
        }
        if (!changed)
                return 0;
-       return slave_put_val(slave, ucontrol);
+       err = slave_put_val(slave, ucontrol);
+       if (err < 0)
+               return err;
+       return 1;
 }
 
 static int slave_tlv_cmd(struct snd_kcontrol *kcontrol,
index 04b57383e8cbcb89212e2d63960242653e774b21..97c68dd24ef5dfed33d340730371e4a40e34347d 100644 (file)
@@ -3334,6 +3334,8 @@ int snd_hda_create_dig_out_ctls(struct hda_codec *codec,
                return -EBUSY;
        }
        spdif = snd_array_new(&codec->spdif_out);
+       if (!spdif)
+               return -ENOMEM;
        for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
                kctl = snd_ctl_new1(dig_mix, codec);
                if (!kctl)
@@ -3431,11 +3433,16 @@ static struct snd_kcontrol_new spdif_share_sw = {
 int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
                                  struct hda_multi_out *mout)
 {
+       struct snd_kcontrol *kctl;
+
        if (!mout->dig_out_nid)
                return 0;
+
+       kctl = snd_ctl_new1(&spdif_share_sw, mout);
+       if (!kctl)
+               return -ENOMEM;
        /* ATTENTION: here mout is passed as private_data, instead of codec */
-       return snd_hda_ctl_add(codec, mout->dig_out_nid,
-                             snd_ctl_new1(&spdif_share_sw, mout));
+       return snd_hda_ctl_add(codec, mout->dig_out_nid, kctl);
 }
 EXPORT_SYMBOL_HDA(snd_hda_create_spdif_share_sw);
 
index db02c1e96b080c2525b313cc9fae11d2550af731..eefc4563b2f946c440df969d063a403e09c37dc0 100644 (file)
@@ -2298,6 +2298,11 @@ static int dspxfr_one_seg(struct hda_codec *codec,
        hda_frame_size_words = ((sample_rate_div == 0) ? 0 :
                        (num_chans * sample_rate_mul / sample_rate_div));
 
+       if (hda_frame_size_words == 0) {
+               snd_printdd(KERN_ERR "frmsz zero\n");
+               return -EINVAL;
+       }
+
        buffer_size_words = min(buffer_size_words,
                                (unsigned int)(UC_RANGE(chip_addx, 1) ?
                                65536 : 32768));
@@ -2308,8 +2313,7 @@ static int dspxfr_one_seg(struct hda_codec *codec,
                   chip_addx, hda_frame_size_words, num_chans,
                   sample_rate_mul, sample_rate_div, buffer_size_words);
 
-       if ((buffer_addx == NULL) || (hda_frame_size_words == 0) ||
-           (buffer_size_words < hda_frame_size_words)) {
+       if (buffer_size_words < hda_frame_size_words) {
                snd_printdd(KERN_ERR "dspxfr_one_seg:failed\n");
                return -EINVAL;
        }
index 2d4237bc0d8e5e85059b8771bad958ae10887ff5..563c24df4d6f03f393def96afcd8340ee4538180 100644 (file)
@@ -3163,6 +3163,7 @@ static int patch_alc269(struct hda_codec *codec)
        case 0x10ec0290:
                spec->codec_variant = ALC269_TYPE_ALC280;
                break;
+       case 0x10ec0233:
        case 0x10ec0282:
        case 0x10ec0283:
                spec->codec_variant = ALC269_TYPE_ALC282;
@@ -3862,6 +3863,7 @@ static int patch_alc680(struct hda_codec *codec)
  */
 static const struct hda_codec_preset snd_hda_preset_realtek[] = {
        { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
+       { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 },
        { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
        { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
        { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
index 2ffdc35d5ffdca6ba5e1d1587feae59e6d08beaa..806407a3973e41784749f21c841628ad262c73f7 100644 (file)
@@ -2594,6 +2594,8 @@ static int snd_ice1712_create(struct snd_card *card,
        snd_ice1712_proc_init(ice);
        synchronize_irq(pci->irq);
 
+       card->private_data = ice;
+
        err = pci_request_regions(pci, "ICE1712");
        if (err < 0) {
                kfree(ice);
index b8d461db369f1f2952fb562f9ce78ddd74e5e069..b82bbf584146dc0b7c1bbaeb416a96f03f0d67af 100644 (file)
@@ -573,6 +573,13 @@ static const struct reg_default wm5102_sysclk_reva_patch[] = {
        { 0x025e, 0x0112 },
 };
 
+static const struct reg_default wm5102_sysclk_revb_patch[] = {
+       { 0x3081, 0x08FE },
+       { 0x3083, 0x00ED },
+       { 0x30C1, 0x08FE },
+       { 0x30C3, 0x00ED },
+};
+
 static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
                            struct snd_kcontrol *kcontrol, int event)
 {
@@ -587,6 +594,10 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
                patch = wm5102_sysclk_reva_patch;
                patch_size = ARRAY_SIZE(wm5102_sysclk_reva_patch);
                break;
+       default:
+               patch = wm5102_sysclk_revb_patch;
+               patch_size = ARRAY_SIZE(wm5102_sysclk_revb_patch);
+               break;
        }
 
        switch (event) {
@@ -755,7 +766,7 @@ SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
 
 SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
             ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R("OUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
+SOC_DOUBLE_R("HPOUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
             ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1),
 SOC_SINGLE("EPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
           ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
@@ -767,7 +778,7 @@ SOC_DOUBLE_R("SPKDAT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L,
 SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
                 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_VOL_SHIFT,
                 0xbf, 0, digital_tlv),
-SOC_DOUBLE_R_TLV("OUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
+SOC_DOUBLE_R_TLV("HPOUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
                 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT,
                 0xbf, 0, digital_tlv),
 SOC_SINGLE_TLV("EPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
index cd17b477781d8b370aa78eb2eadad86dcdd4cc31..cdeb301da1f69221f065ccf7f07bfa290e0e9dff 100644 (file)
@@ -213,9 +213,9 @@ ARIZONA_MIXER_CONTROLS("SPKDAT2R", ARIZONA_OUT6RMIX_INPUT_1_SOURCE),
 
 SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L,
           ARIZONA_OUT1_OSR_SHIFT, 1, 0),
-SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
+SOC_SINGLE("HPOUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
           ARIZONA_OUT2_OSR_SHIFT, 1, 0),
-SOC_SINGLE("OUT3 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
+SOC_SINGLE("HPOUT3 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
           ARIZONA_OUT3_OSR_SHIFT, 1, 0),
 SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
           ARIZONA_OUT4_OSR_SHIFT, 1, 0),
@@ -226,9 +226,9 @@ SOC_SINGLE("SPKDAT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_6L,
 
 SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
             ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R("OUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
+SOC_DOUBLE_R("HPOUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
             ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1),
-SOC_DOUBLE_R("OUT3 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
+SOC_DOUBLE_R("HPOUT3 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
             ARIZONA_DAC_DIGITAL_VOLUME_3R, ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
 SOC_DOUBLE_R("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
             ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
@@ -240,10 +240,10 @@ SOC_DOUBLE_R("SPKDAT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_6L,
 SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
                 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_VOL_SHIFT,
                 0xbf, 0, digital_tlv),
-SOC_DOUBLE_R_TLV("OUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
+SOC_DOUBLE_R_TLV("HPOUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
                 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT,
                 0xbf, 0, digital_tlv),
-SOC_DOUBLE_R_TLV("OUT3 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
+SOC_DOUBLE_R_TLV("HPOUT3 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
                 ARIZONA_DAC_DIGITAL_VOLUME_3R, ARIZONA_OUT3L_VOL_SHIFT,
                 0xbf, 0, digital_tlv),
 SOC_DOUBLE_R_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
@@ -260,11 +260,11 @@ SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L,
                       ARIZONA_OUTPUT_PATH_CONFIG_1R,
                       ARIZONA_OUT1L_PGA_VOL_SHIFT,
                       0x34, 0x40, 0, ana_tlv),
-SOC_DOUBLE_R_RANGE_TLV("OUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L,
+SOC_DOUBLE_R_RANGE_TLV("HPOUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L,
                       ARIZONA_OUTPUT_PATH_CONFIG_2R,
                       ARIZONA_OUT2L_PGA_VOL_SHIFT,
                       0x34, 0x40, 0, ana_tlv),
-SOC_DOUBLE_R_RANGE_TLV("OUT3 Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
+SOC_DOUBLE_R_RANGE_TLV("HPOUT3 Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
                       ARIZONA_OUTPUT_PATH_CONFIG_3R,
                       ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
 
index ec0efc1443ba770a6c40a2e18c90b117931823bd..0e8b3aaf6c8d698e9dad1f25fdccbabc9ee9f1ef 100644 (file)
@@ -1301,7 +1301,7 @@ static irqreturn_t wm8350_hpl_jack_handler(int irq, void *data)
        if (device_may_wakeup(wm8350->dev))
                pm_wakeup_event(wm8350->dev, 250);
 
-       schedule_delayed_work(&priv->hpl.work, 200);
+       schedule_delayed_work(&priv->hpl.work, msecs_to_jiffies(200));
 
        return IRQ_HANDLED;
 }
@@ -1318,7 +1318,7 @@ static irqreturn_t wm8350_hpr_jack_handler(int irq, void *data)
        if (device_may_wakeup(wm8350->dev))
                pm_wakeup_event(wm8350->dev, 250);
 
-       schedule_delayed_work(&priv->hpr.work, 200);
+       schedule_delayed_work(&priv->hpr.work, msecs_to_jiffies(200));
 
        return IRQ_HANDLED;
 }
index 9bb9273259937770ac4f8b188b05f803a1079121..a64b93425ae3367051cba0ef0a5f59a233abd2ee 100644 (file)
@@ -53,8 +53,8 @@
  * using 2 wire for device control, so we cache them instead.
  */
 static const struct reg_default wm8960_reg_defaults[] = {
-       {  0x0, 0x0097 },
-       {  0x1, 0x0097 },
+       {  0x0, 0x00a7 },
+       {  0x1, 0x00a7 },
        {  0x2, 0x0000 },
        {  0x3, 0x0000 },
        {  0x4, 0x0000 },
@@ -323,8 +323,8 @@ SND_SOC_DAPM_MIXER("Left Input Mixer", WM8960_POWER3, 5, 0,
 SND_SOC_DAPM_MIXER("Right Input Mixer", WM8960_POWER3, 4, 0,
                   wm8960_rin, ARRAY_SIZE(wm8960_rin)),
 
-SND_SOC_DAPM_ADC("Left ADC", "Capture", WM8960_POWER2, 3, 0),
-SND_SOC_DAPM_ADC("Right ADC", "Capture", WM8960_POWER2, 2, 0),
+SND_SOC_DAPM_ADC("Left ADC", "Capture", WM8960_POWER1, 3, 0),
+SND_SOC_DAPM_ADC("Right ADC", "Capture", WM8960_POWER1, 2, 0),
 
 SND_SOC_DAPM_DAC("Left DAC", "Playback", WM8960_POWER2, 8, 0),
 SND_SOC_DAPM_DAC("Right DAC", "Playback", WM8960_POWER2, 7, 0),
index c27069d24d77257d41039e1632f04ae2c33a57bd..729958713cd44723f7b07c1e6815d61e5adde587 100644 (file)
 
 #define TEGRA20_I2S_TIMING_NON_SYM_ENABLE              (1 << 12)
 #define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT     0
-#define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US   0x7fff
+#define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US   0x7ff
 #define TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK      (TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT)
 
 /* Fields in TEGRA20_I2S_FIFO_SCR */
index 34dc47b9581c21e8700eab513265d5c4096ca794..a294d942b9f72aa7c7b2595ca05c98deb6ffe2b9 100644 (file)
 
 #define TEGRA30_I2S_TIMING_NON_SYM_ENABLE              (1 << 12)
 #define TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT     0
-#define TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US   0x7fff
+#define TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US   0x7ff
 #define TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_MASK      (TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US << TEGRA30_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT)
 
 /* Fields in TEGRA30_I2S_OFFSET */
index 880cdd5dc63f44fb9197f09b41296b2bbde4cc5a..77edcdcc016bbe9e891dbee8ce27c5824caaae63 100644 (file)
@@ -125,6 +125,63 @@ test_open_unlink()
        ./open-unlink $file
 }
 
+# test that we can create a range of filenames
+test_valid_filenames()
+{
+       local attrs='\x07\x00\x00\x00'
+       local ret=0
+
+       local file_list="abc dump-type0-11-1-1362436005 1234 -"
+       for f in $file_list; do
+               local file=$efivarfs_mount/$f-$test_guid
+
+               printf "$attrs\x00" > $file
+
+               if [ ! -e $file ]; then
+                       echo "$file could not be created" >&2
+                       ret=1
+               else
+                       rm $file
+               fi
+       done
+
+       exit $ret
+}
+
+test_invalid_filenames()
+{
+       local attrs='\x07\x00\x00\x00'
+       local ret=0
+
+       local file_list="
+               -1234-1234-1234-123456789abc
+               foo
+               foo-bar
+               -foo-
+               foo-barbazba-foob-foob-foob-foobarbazfoo
+               foo-------------------------------------
+               -12345678-1234-1234-1234-123456789abc
+               a-12345678=1234-1234-1234-123456789abc
+               a-12345678-1234=1234-1234-123456789abc
+               a-12345678-1234-1234=1234-123456789abc
+               a-12345678-1234-1234-1234=123456789abc
+               1112345678-1234-1234-1234-123456789abc"
+
+       for f in $file_list; do
+               local file=$efivarfs_mount/$f
+
+               printf "$attrs\x00" 2>/dev/null > $file
+
+               if [ -e $file ]; then
+                       echo "Creating $file should have failed" >&2
+                       rm $file
+                       ret=1
+               fi
+       done
+
+       exit $ret
+}
+
 check_prereqs
 
 rc=0
@@ -135,5 +192,7 @@ run_test test_create_read
 run_test test_delete
 run_test test_zero_size_delete
 run_test test_open_unlink
+run_test test_valid_filenames
+run_test test_invalid_filenames
 
 exit $rc