Merge Trond's nfs-for-next
authorJ. Bruce Fields <bfields@redhat.com>
Fri, 26 Apr 2013 15:37:29 +0000 (11:37 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Fri, 26 Apr 2013 15:37:43 +0000 (11:37 -0400)
Merging Trond's nfs-for-next branch, mainly to get
b7993cebb841b0da7a33e9d5ce301a9fd3209165 "SUNRPC: Allow rpc_create() to
request that TCP slots be unlimited", which a small piece of the
gss-proxy work depends on.

647 files changed:
CREDITS
Documentation/SubmittingPatches
Documentation/device-mapper/dm-raid.txt
Documentation/devicetree/bindings/mfd/ab8500.txt
Documentation/devicetree/bindings/tty/serial/of-serial.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/input/alps.txt
Documentation/networking/tuntap.txt
Documentation/power/opp.txt
Documentation/printk-formats.txt
Documentation/trace/ftrace.txt
MAINTAINERS
Makefile
arch/Kconfig
arch/alpha/Kconfig
arch/alpha/boot/head.S
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/boot/Makefile
arch/arm/boot/compressed/Makefile
arch/arm/boot/dts/armada-370-rd.dts
arch/arm/boot/dts/armada-370-xp.dtsi
arch/arm/boot/dts/armada-xp.dtsi
arch/arm/boot/dts/bcm2835.dtsi
arch/arm/boot/dts/dbx5x0.dtsi
arch/arm/boot/dts/dove.dtsi
arch/arm/boot/dts/href.dtsi
arch/arm/boot/dts/hrefv60plus.dts
arch/arm/boot/dts/imx53-mba53.dts
arch/arm/boot/dts/kirkwood-dns320.dts
arch/arm/boot/dts/kirkwood-dns325.dts
arch/arm/boot/dts/kirkwood-dockstar.dts
arch/arm/boot/dts/kirkwood-dreamplug.dts
arch/arm/boot/dts/kirkwood-goflexnet.dts
arch/arm/boot/dts/kirkwood-ib62x0.dts
arch/arm/boot/dts/kirkwood-iconnect.dts
arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts
arch/arm/boot/dts/kirkwood-km_kirkwood.dts
arch/arm/boot/dts/kirkwood-lschlv2.dts
arch/arm/boot/dts/kirkwood-lsxhl.dts
arch/arm/boot/dts/kirkwood-mplcec4.dts
arch/arm/boot/dts/kirkwood-ns2-common.dtsi
arch/arm/boot/dts/kirkwood-nsa310.dts
arch/arm/boot/dts/kirkwood-openblocks_a6.dts
arch/arm/boot/dts/kirkwood-topkick.dts
arch/arm/boot/dts/kirkwood.dtsi
arch/arm/boot/dts/orion5x-lacie-ethernet-disk-mini-v2.dts
arch/arm/boot/dts/snowball.dts
arch/arm/boot/dts/socfpga.dtsi
arch/arm/boot/dts/tegra20.dtsi
arch/arm/boot/dts/tegra30.dtsi
arch/arm/configs/mxs_defconfig
arch/arm/configs/omap2plus_defconfig
arch/arm/include/asm/mmu.h
arch/arm/include/asm/mmu_context.h
arch/arm/include/asm/tlbflush.h
arch/arm/include/asm/xen/events.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-at91/board-foxg20.c
arch/arm/mach-at91/board-stamp9g20.c
arch/arm/mach-imx/clk-imx6q.c
arch/arm/mach-imx/headsmp.S
arch/arm/mach-imx/pm-imx6q.c
arch/arm/mach-ixp4xx/vulcan-setup.c
arch/arm/mach-kirkwood/board-dt.c
arch/arm/mach-mxs/icoll.c
arch/arm/mach-mxs/mach-mxs.c
arch/arm/mach-mxs/mm.c
arch/arm/mach-mxs/ocotp.c
arch/arm/mach-netx/generic.c
arch/arm/mach-netx/include/mach/irqs.h
arch/arm/mach-omap1/common.h
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-rx51.c
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/gpmc.c
arch/arm/mach-omap2/mux.c
arch/arm/mach-pxa/raumfeld.c
arch/arm/mach-spear3xx/spear3xx.c
arch/arm/mm/context.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/idmap.c
arch/arm/mm/proc-v7-3level.S
arch/arm/plat-orion/addr-map.c
arch/arm/plat-spear/Kconfig
arch/avr32/Kconfig
arch/blackfin/Kconfig
arch/cris/Kconfig
arch/frv/Kconfig
arch/h8300/Kconfig
arch/ia64/Kconfig
arch/ia64/kernel/perfmon.c
arch/m32r/Kconfig
arch/m32r/include/uapi/asm/stat.h
arch/m68k/Kconfig
arch/m68k/Kconfig.machine
arch/m68k/include/asm/MC68328.h
arch/m68k/kernel/setup_no.c
arch/m68k/mm/init.c
arch/m68k/platform/coldfire/m528x.c
arch/metag/include/asm/elf.h
arch/metag/mm/Kconfig
arch/microblaze/Kconfig
arch/mips/Kconfig
arch/mn10300/Kconfig
arch/openrisc/Kconfig
arch/parisc/Kconfig
arch/powerpc/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/Kconfig
arch/s390/hypfs/inode.c
arch/s390/include/asm/cpu_mf.h
arch/score/Kconfig
arch/tile/Kconfig
arch/tile/include/asm/compat.h
arch/tile/kernel/compat.c
arch/um/drivers/chan.h
arch/um/drivers/chan_kern.c
arch/um/drivers/chan_user.c
arch/um/drivers/chan_user.h
arch/um/drivers/line.c
arch/um/drivers/net_kern.c
arch/um/drivers/ssl.c
arch/um/drivers/stdio_console.c
arch/um/os-Linux/signal.c
arch/um/os-Linux/start_up.c
arch/unicore32/Kconfig
arch/x86/Kconfig
arch/x86/include/asm/bootparam_utils.h
arch/x86/kernel/cpu/perf_event_intel_ds.c
arch/x86/kernel/setup.c
arch/x86/kernel/smpboot.c
arch/x86/mm/init.c
arch/x86/mm/pat.c
arch/x86/power/cpu.c
arch/xtensa/Kconfig
drivers/acpi/glue.c
drivers/acpi/processor_core.c
drivers/acpi/processor_driver.c
drivers/acpi/processor_perflib.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/hw_random/virtio-rng.c
drivers/char/random.c
drivers/clk/tegra/clk-tegra20.c
drivers/clk/tegra/clk-tegra30.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/gpio-mvebu.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/disp/nv50.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_abi16.c
drivers/gpu/drm/nouveau/nouveau_agp.c
drivers/gpu/drm/nouveau/nouveau_bo.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/lineage-pem.c
drivers/hwmon/pmbus/ltc2978.c
drivers/hwmon/pmbus/pmbus_core.c
drivers/hwmon/sht15.c
drivers/iio/common/st_sensors/st_sensors_core.c
drivers/iio/dac/ad5064.c
drivers/iio/imu/inv_mpu6050/Kconfig
drivers/infiniband/hw/ipath/ipath_fs.c
drivers/infiniband/hw/mlx4/cm.c
drivers/infiniband/hw/qib/qib_fs.c
drivers/input/keyboard/tc3589x-keypad.c
drivers/input/mouse/alps.c
drivers/input/mouse/alps.h
drivers/input/mouse/cypress_ps2.c
drivers/input/tablet/wacom_wac.c
drivers/input/touchscreen/ads7846.c
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/input/touchscreen/mms114.c
drivers/iommu/dmar.c
drivers/irqchip/irq-gic.c
drivers/isdn/hisax/st5481_usb.c
drivers/isdn/i4l/isdn_tty.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/mfd/Kconfig
drivers/mfd/ab8500-gpadc.c
drivers/mfd/omap-usb-host.c
drivers/mfd/palmas.c
drivers/mfd/tps65912-core.c
drivers/mfd/twl4030-audio.c
drivers/mfd/twl4030-madc.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/broadcom/tg3.c
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_hw.h
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/freescale/fec.c
drivers/net/ethernet/freescale/fec.h
drivers/net/ethernet/intel/e1000e/ethtool.c
drivers/net/ethernet/intel/e1000e/ich8lan.c
drivers/net/ethernet/intel/e1000e/ich8lan.h
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/e1000e/regs.h
drivers/net/ethernet/intel/igb/e1000_82575.c
drivers/net/ethernet/intel/igb/igb.h
drivers/net/ethernet/intel/igb/igb_hwmon.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/marvell/mv643xx_eth.c
drivers/net/ethernet/mellanox/mlx4/cq.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/fw.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/mellanox/mlx4/mlx4.h
drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
drivers/net/ethernet/mellanox/mlx4/mr.c
drivers/net/ethernet/mellanox/mlx4/pd.c
drivers/net/ethernet/mellanox/mlx4/port.c
drivers/net/ethernet/mellanox/mlx4/qp.c
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/ethernet/mellanox/mlx4/srq.c
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/efx.h
drivers/net/ethernet/sfc/net_driver.h
drivers/net/ethernet/sfc/rx.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/hippi/rrunner.c
drivers/net/macvlan.c
drivers/net/phy/micrel.c
drivers/net/phy/phy_device.c
drivers/net/team/team.c
drivers/net/tun.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/vmxnet3/vmxnet3_drv.c
drivers/net/vmxnet3/vmxnet3_ethtool.c
drivers/net/vmxnet3/vmxnet3_int.h
drivers/net/vxlan.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/dvm/sta.c
drivers/net/wireless/iwlwifi/iwl-devtrace.h
drivers/net/wireless/iwlwifi/iwl-drv.c
drivers/net/wireless/iwlwifi/iwl-modparams.h
drivers/net/wireless/iwlwifi/iwl-phy-db.c
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/mvm/d3.c
drivers/net/wireless/iwlwifi/mvm/fw-api.h
drivers/net/wireless/iwlwifi/mvm/fw.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/ops.c
drivers/net/wireless/iwlwifi/mvm/rx.c
drivers/net/wireless/iwlwifi/mvm/sta.c
drivers/net/wireless/iwlwifi/mvm/tx.c
drivers/net/wireless/iwlwifi/pcie/internal.h
drivers/net/wireless/iwlwifi/pcie/rx.c
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/rtc/rtc-mv.c
drivers/scsi/scsi_lib.c
drivers/staging/ccg/f_fs.c
drivers/staging/comedi/drivers/dt9812.c
drivers/staging/comedi/drivers/usbdux.c
drivers/staging/comedi/drivers/usbduxfast.c
drivers/staging/comedi/drivers/usbduxsigma.c
drivers/staging/imx-drm/ipuv3-crtc.c
drivers/staging/tidspbridge/rmgr/drv.c
drivers/staging/vt6656/card.c
drivers/staging/vt6656/main_usb.c
drivers/staging/zcache/ramster/tcp.c
drivers/tty/hvc/hvcs.c
drivers/tty/serial/8250/8250.c
drivers/tty/serial/8250/8250_pci.c
drivers/tty/serial/8250/8250_pnp.c
drivers/tty/serial/Kconfig
drivers/tty/serial/bcm63xx_uart.c
drivers/tty/serial/mpc52xx_uart.c
drivers/tty/serial/of_serial.c
drivers/tty/serial/vt8500_serial.c
drivers/tty/tty_buffer.c
drivers/usb/Makefile
drivers/usb/c67x00/c67x00-sched.c
drivers/usb/chipidea/udc.c
drivers/usb/class/cdc-wdm.c
drivers/usb/core/usb-acpi.c
drivers/usb/dwc3/core.c
drivers/usb/dwc3/dwc3-exynos.c
drivers/usb/dwc3/dwc3-omap.c
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/dwc3/ep0.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/Makefile
drivers/usb/gadget/composite.c
drivers/usb/gadget/f_fs.c
drivers/usb/gadget/f_uac1.c
drivers/usb/gadget/imx_udc.c
drivers/usb/gadget/inode.c
drivers/usb/gadget/omap_udc.c
drivers/usb/gadget/pxa25x_udc.c
drivers/usb/gadget/pxa27x_udc.c
drivers/usb/gadget/s3c2410_udc.c
drivers/usb/gadget/u_uac1.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-q.c
drivers/usb/musb/Kconfig
drivers/usb/musb/musb_core.c
drivers/usb/musb/omap2430.c
drivers/usb/otg/otg.c
drivers/usb/phy/omap-control-usb.c
drivers/usb/phy/omap-usb3.c
drivers/usb/phy/samsung-usbphy.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/option.c
drivers/usb/serial/qcaux.c
drivers/usb/serial/qcserial.c
drivers/usb/serial/quatech2.c
drivers/usb/storage/initializers.c
drivers/usb/storage/initializers.h
drivers/usb/storage/unusual_devs.h
drivers/video/omap/lcd_ams_delta.c
drivers/video/omap/lcd_osk.c
drivers/w1/masters/w1-gpio.c
drivers/w1/w1.c
drivers/xen/xen-acpi-processor.c
drivers/xen/xen-pciback/pciback_ops.c
drivers/xen/xen-stub.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/extent-tree.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/locking.h
fs/btrfs/qgroup.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/cifsfs.c
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/inode.c
fs/cifs/smb2ops.c
fs/coda/inode.c
fs/compat.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/ialloc.c
fs/ext2/inode.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/hostfs/hostfs_kern.c
fs/hpfs/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/cache.h
fs/nfsd/netns.h
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfscache.c
fs/nfsd/nfsctl.c
fs/nfsd/state.h
fs/nfsd/vfs.c
fs/nfsd/xdr4.h
fs/nfsd/xdr4cb.h [new file with mode: 0644]
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/pipe.c
fs/proc/namespaces.c
fs/qnx4/inode.c
fs/qnx6/inode.c
fs/quota/dquot.c
fs/reiserfs/super.c
fs/romfs/super.c
fs/squashfs/super.c
fs/sysv/super.c
fs/ubifs/super.c
fs/udf/super.c
fs/ufs/super.c
fs/xfs/xfs_super.c
include/acpi/acpi_bus.h
include/acpi/processor.h
include/asm-generic/atomic.h
include/asm-generic/cmpxchg.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/idr.h
include/linux/iio/common/st_sensors.h
include/linux/list.h
include/linux/mfd/palmas.h
include/linux/mfd/tps65912.h
include/linux/mfd/wm831x/auxadc.h
include/linux/mfd/wm831x/core.h
include/linux/netfilter/ipset/ip_set_ahash.h
include/linux/perf_event.h
include/linux/regulator/driver.h
include/linux/res_counter.h
include/linux/smpboot.h
include/linux/sunrpc/msg_prot.h
include/linux/usb/composite.h
include/net/tcp.h
include/uapi/linux/acct.h
include/uapi/linux/aio_abi.h
include/uapi/linux/raid/md_p.h
include/uapi/linux/serial_core.h
init/Kconfig
ipc/msg.c
ipc/msgutil.c
kernel/fork.c
kernel/futex.c
kernel/signal.c
kernel/smpboot.c
kernel/softirq.c
kernel/stop_machine.c
kernel/trace/Kconfig
kernel/trace/trace.c
kernel/user_namespace.c
kernel/workqueue.c
lib/idr.c
lib/xz/Kconfig
mm/Kconfig
mm/fremap.c
mm/ksm.c
mm/memcontrol.c
mm/memory_hotplug.c
mm/mempolicy.c
mm/process_vm_access.c
net/9p/trans_virtio.c
net/bridge/br_device.c
net/bridge/br_input.c
net/bridge/br_mdb.c
net/bridge/br_multicast.c
net/bridge/br_private.h
net/caif/caif_dev.c
net/caif/caif_usb.c
net/ceph/osdmap.c
net/core/dev.c
net/core/rtnetlink.c
net/dcb/dcbnl.c
net/ieee802154/6lowpan.h
net/ipv4/inet_connection_sock.c
net/ipv4/ip_input.c
net/ipv4/ip_options.c
net/ipv4/tcp_input.c
net/ipv6/ip6_input.c
net/ipv6/route.c
net/irda/ircomm/ircomm_tty.c
net/irda/iriap.c
net/key/af_key.c
net/l2tp/l2tp_ppp.c
net/mac80211/cfg.c
net/mac80211/iface.c
net/mac80211/mlme.c
net/mac80211/tx.c
net/netfilter/ipset/ip_set_core.c
net/netfilter/nf_conntrack_helper.c
net/netfilter/nfnetlink.c
net/netfilter/xt_AUDIT.c
net/netlabel/netlabel_unlabeled.c
net/rds/message.c
net/rds/stats.c
net/sched/sch_qfq.c
net/sctp/endpointola.c
net/sctp/socket.c
net/sctp/ssnmap.c
net/sctp/tsnmap.c
net/sctp/ulpqueue.c
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/cache.c
net/sunrpc/rpc_pipe.c
net/sunrpc/xprtsock.c
net/wireless/core.c
net/wireless/nl80211.c
scripts/Makefile.headersinst
security/keys/compat.c
security/keys/process_keys.c
sound/core/seq/oss/seq_oss_event.c
sound/core/seq/seq_timer.c
sound/core/vmaster.c
sound/oss/sequencer.c
sound/pci/asihpi/asihpi.c
sound/pci/hda/hda_codec.c
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_cirrus.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.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
sound/usb/card.c
tools/testing/selftests/efivarfs/efivarfs.sh
tools/usb/ffs-test.c

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 13b707b7355c005e9c877e860c93d4e9ca6baf12..c3a14e0ad0addf57715902618482a5593344f8da 100644 (file)
@@ -13,9 +13,6 @@ Required parent device properties:
                                   4 = active high level-sensitive
                                   8 = active low level-sensitive
 
-Optional parent device properties:
-- reg                    : contains the PRCMU mailbox address for the AB8500 i2c port
-
 The AB8500 consists of a large and varied group of sub-devices:
 
 Device                     IRQ Names              Supply Names   Description
@@ -86,9 +83,8 @@ Non-standard child device properties:
    - stericsson,amic2-bias-vamic1           : Analoge Mic wishes to use a non-standard Vamic
    - stericsson,earpeice-cmv                : Earpeice voltage (only: 950 | 1100 | 1270 | 1580)
 
-ab8500@5 {
+ab8500 {
          compatible = "stericsson,ab8500";
-         reg = <5>; /* mailbox 5 is i2c */
          interrupts = <0 40 0x4>;
          interrupt-controller;
          #interrupt-cells = <2>;
index 1e1145ca4f3c2cb192f7e4bf5ce95f6c73ba0801..8f01cb190f25686747873ab54eaa53652c9b35bc 100644 (file)
@@ -11,6 +11,9 @@ Required properties:
        - "nvidia,tegra20-uart"
        - "nxp,lpc3220-uart"
        - "ibm,qpace-nwp-serial"
+       - "altr,16550-FIFO32"
+       - "altr,16550-FIFO64"
+       - "altr,16550-FIFO128"
        - "serial" if the port type is unknown.
 - reg : offset and length of the register set for the device.
 - interrupts : should contain uart interrupt.
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 3262b6e4d686ac944f7e767642228f4d4cc2f8f6..e544c7ff8cfa5c6c60697aae738eb4b029e86d23 100644 (file)
@@ -3,10 +3,26 @@ ALPS Touchpad Protocol
 
 Introduction
 ------------
-
-Currently the ALPS touchpad driver supports four protocol versions in use by
-ALPS touchpads, called versions 1, 2, 3, and 4. Information about the various
-protocol versions is contained in the following sections.
+Currently the ALPS touchpad driver supports five protocol versions in use by
+ALPS touchpads, called versions 1, 2, 3, 4 and 5.
+
+Since roughly mid-2010 several new ALPS touchpads have been released and
+integrated into a variety of laptops and netbooks.  These new touchpads
+have enough behavior differences that the alps_model_data definition
+table, describing the properties of the different versions, is no longer
+adequate.  The design choices were to re-define the alps_model_data
+table, with the risk of regression testing existing devices, or isolate
+the new devices outside of the alps_model_data table.  The latter design
+choice was made.  The new touchpad signatures are named: "Rushmore",
+"Pinnacle", and "Dolphin", which you will see in the alps.c code.
+For the purposes of this document, this group of ALPS touchpads will
+generically be called "new ALPS touchpads".
+
+We experimented with probing the ACPI interface _HID (Hardware ID)/_CID
+(Compatibility ID) definition as a way to uniquely identify the
+different ALPS variants but there did not appear to be a 1:1 mapping.
+In fact, it appeared to be an m:n mapping between the _HID and actual
+hardware type.
 
 Detection
 ---------
@@ -20,9 +36,13 @@ If the E6 report is successful, the touchpad model is identified using the "E7
 report" sequence: E8-E7-E7-E7-E9. The response is the model signature and is
 matched against known models in the alps_model_data_array.
 
-With protocol versions 3 and 4, the E7 report model signature is always
-73-02-64. To differentiate between these versions, the response from the
-"Enter Command Mode" sequence must be inspected as described below.
+For older touchpads supporting protocol versions 3 and 4, the E7 report
+model signature is always 73-02-64. To differentiate between these
+versions, the response from the "Enter Command Mode" sequence must be
+inspected as described below.
+
+The new ALPS touchpads have an E7 signature of 73-03-50 or 73-03-0A but
+seem to be better differentiated by the EC Command Mode response.
 
 Command Mode
 ------------
@@ -47,6 +67,14 @@ address of the register being read, and the third contains the value of the
 register. Registers are written by writing the value one nibble at a time
 using the same encoding used for addresses.
 
+For the new ALPS touchpads, the EC command is used to enter command
+mode. The response in the new ALPS touchpads is significantly different,
+and more important in determining the behavior.  This code has been
+separated from the original alps_model_data table and put in the
+alps_identify function.  For example, there seem to be two hardware init
+sequences for the "Dolphin" touchpads as determined by the second byte
+of the EC response.
+
 Packet Format
 -------------
 
@@ -187,3 +215,28 @@ There are several things worth noting here.
     well.
 
 So far no v4 devices with tracksticks have been encountered.
+
+ALPS Absolute Mode - Protocol Version 5
+---------------------------------------
+This is basically Protocol Version 3 but with different logic for packet
+decode.  It uses the same alps_process_touchpad_packet_v3 call with a
+specialized decode_fields function pointer to correctly interpret the
+packets.  This appears to only be used by the Dolphin devices.
+
+For single-touch, the 6-byte packet format is:
+
+ byte 0:    1    1    0    0    1    0    0    0
+ byte 1:    0   x6   x5   x4   x3   x2   x1   x0
+ byte 2:    0   y6   y5   y4   y3   y2   y1   y0
+ byte 3:    0    M    R    L    1    m    r    l
+ byte 4:   y10  y9   y8   y7  x10   x9   x8   x7
+ byte 5:    0   z6   z5   z4   z3   z2   z1   z0
+
+For mt, the format is:
+
+ byte 0:    1    1    1    n3   1   n2   n1   x24
+ byte 1:    1   y7   y6    y5  y4   y3   y2    y1
+ byte 2:    ?   x2   x1   y12 y11  y10   y9    y8
+ byte 3:    0  x23  x22   x21 x20  x19  x18   x17
+ byte 4:    0   x9   x8    x7  x6   x5   x4    x3
+ byte 5:    0  x16  x15   x14 x13  x12  x11   x10
index c0aab985bad9ac4a159ea9f96e837bee28475291..949d5dcdd9a348fd646f89c62f604d9d29433d2c 100644 (file)
@@ -105,6 +105,83 @@ Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
      Proto [2 bytes]
      Raw protocol(IP, IPv6, etc) frame.
 
+  3.3 Multiqueue tuntap interface:
+
+  From version 3.8, Linux supports multiqueue tuntap which can uses multiple
+  file descriptors (queues) to parallelize packets sending or receiving. The
+  device allocation is the same as before, and if user wants to create multiple
+  queues, TUNSETIFF with the same device name must be called many times with
+  IFF_MULTI_QUEUE flag.
+
+  char *dev should be the name of the device, queues is the number of queues to
+  be created, fds is used to store and return the file descriptors (queues)
+  created to the caller. Each file descriptor were served as the interface of a
+  queue which could be accessed by userspace.
+
+  #include <linux/if.h>
+  #include <linux/if_tun.h>
+
+  int tun_alloc_mq(char *dev, int queues, int *fds)
+  {
+      struct ifreq ifr;
+      int fd, err, i;
+
+      if (!dev)
+          return -1;
+
+      memset(&ifr, 0, sizeof(ifr));
+      /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
+       *        IFF_TAP   - TAP device
+       *
+       *        IFF_NO_PI - Do not provide packet information
+       *        IFF_MULTI_QUEUE - Create a queue of multiqueue device
+       */
+      ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE;
+      strcpy(ifr.ifr_name, dev);
+
+      for (i = 0; i < queues; i++) {
+          if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
+             goto err;
+          err = ioctl(fd, TUNSETIFF, (void *)&ifr);
+          if (err) {
+             close(fd);
+             goto err;
+          }
+          fds[i] = fd;
+      }
+
+      return 0;
+  err:
+      for (--i; i >= 0; i--)
+          close(fds[i]);
+      return err;
+  }
+
+  A new ioctl(TUNSETQUEUE) were introduced to enable or disable a queue. When
+  calling it with IFF_DETACH_QUEUE flag, the queue were disabled. And when
+  calling it with IFF_ATTACH_QUEUE flag, the queue were enabled. The queue were
+  enabled by default after it was created through TUNSETIFF.
+
+  fd is the file descriptor (queue) that we want to enable or disable, when
+  enable is true we enable it, otherwise we disable it
+
+  #include <linux/if.h>
+  #include <linux/if_tun.h>
+
+  int tun_set_queue(int fd, int enable)
+  {
+      struct ifreq ifr;
+
+      memset(&ifr, 0, sizeof(ifr));
+
+      if (enable)
+         ifr.ifr_flags = IFF_ATTACH_QUEUE;
+      else
+         ifr.ifr_flags = IFF_DETACH_QUEUE;
+
+      return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
+  }
+
 Universal TUN/TAP device driver Frequently Asked Question.
    
 1. What platforms are supported by TUN/TAP driver ?
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 53d6a3c51d875771fc2966c9917aec13b17f53c6..a372304aef10a378bc00440053c0fe4028eac566 100644 (file)
@@ -1873,7 +1873,7 @@ feature:
 
        status\input  |     0      |     1      |    else    |
        --------------+------------+------------+------------+
-       not allocated |(do nothing)| alloc+swap |   EINVAL   |
+       not allocated |(do nothing)| alloc+swap |(do nothing)|
        --------------+------------+------------+------------+
        allocated     |    free    |    swap    |   clear    |
        --------------+------------+------------+------------+
index e95b1e944eb7d26e19b712af2ffa3788d47be2ec..50b4d735f961a1e5fe700faee710c8b9bd65c5dc 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
@@ -4023,6 +4005,22 @@ M:       Stanislaw Gruszka <stf_xl@wp.pl>
 S:     Maintained
 F:     drivers/usb/atm/ueagle-atm.c
 
+INA209 HARDWARE MONITOR DRIVER
+M:     Guenter Roeck <linux@roeck-us.net>
+L:     lm-sensors@lm-sensors.org
+S:     Maintained
+F:     Documentation/hwmon/ina209
+F:     Documentation/devicetree/bindings/i2c/ina209.txt
+F:     drivers/hwmon/ina209.c
+
+INA2XX HARDWARE MONITOR DRIVER
+M:     Guenter Roeck <linux@roeck-us.net>
+L:     lm-sensors@lm-sensors.org
+S:     Maintained
+F:     Documentation/hwmon/ina2xx
+F:     drivers/hwmon/ina2xx.c
+F:     include/linux/platform_data/ina2xx.h
+
 INDUSTRY PACK SUBSYSTEM (IPACK)
 M:     Samuel Iglesias Gonsalvez <siglesias@igalia.com>
 M:     Jens Taprogge <jens.taprogge@taprogge.org>
@@ -5116,6 +5114,15 @@ S:       Maintained
 F:     Documentation/hwmon/max6650
 F:     drivers/hwmon/max6650.c
 
+MAX6697 HARDWARE MONITOR DRIVER
+M:     Guenter Roeck <linux@roeck-us.net>
+L:     lm-sensors@lm-sensors.org
+S:     Maintained
+F:     Documentation/hwmon/max6697
+F:     Documentation/devicetree/bindings/i2c/max6697.txt
+F:     drivers/hwmon/max6697.c
+F:     include/linux/platform_data/max6697.h
+
 MAXIRADIO FM RADIO RECEIVER DRIVER
 M:     Hans Verkuil <hverkuil@xs4all.nl>
 L:     linux-media@vger.kernel.org
@@ -6430,6 +6437,8 @@ F:        Documentation/networking/LICENSE.qla3xxx
 F:     drivers/net/ethernet/qlogic/qla3xxx.*
 
 QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER
+M:     Rajesh Borundia <rajesh.borundia@qlogic.com>
+M:     Shahed Shaikh <shahed.shaikh@qlogic.com>
 M:     Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
 M:     Sony Chacko <sony.chacko@qlogic.com>
 M:     linux-driver@qlogic.com
index 5bd9f7700eb9582a59cc7d75bf6e55a82ce587b3..22113a77f8ed4af82257b097d821af841f082844 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 9
 SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc3
 NAME = Unicycling Gorilla
 
 # *DOCUMENTATION*
index 5a1779c93940153b30ba84a561b75aaec1e109ea..1455579791ec02514a5d616a4b6749cbec3185b0 100644 (file)
@@ -319,13 +319,6 @@ config ARCH_WANT_OLD_COMPAT_IPC
        select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
        bool
 
-config HAVE_VIRT_TO_BUS
-       bool
-       help
-         An architecture should select this if it implements the
-         deprecated interface virt_to_bus().  All new architectures
-         should probably not select this.
-
 config HAVE_ARCH_SECCOMP_FILTER
        bool
        help
index 5833aa4414816526dd23be127ef718a1900d4b7f..8a33ba01301ff5cb4966455699a164c27feb1484 100644 (file)
@@ -9,7 +9,7 @@ config ALPHA
        select HAVE_PERF_EVENTS
        select HAVE_DMA_ATTRS
        select HAVE_GENERIC_HARDIRQS
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select GENERIC_IRQ_PROBE
        select AUTO_IRQ_AFFINITY if SMP
        select GENERIC_IRQ_SHOW
index b06812bcac83b911cf43613cba8f1d6619fd380d..8efb26686d4789e2afbfc910921b2327e8fbe2c1 100644 (file)
@@ -4,6 +4,7 @@
  * initial bootloader stuff..
  */
 
+#include <asm/pal.h>
 
        .set noreorder
        .globl  __start
index 5b714695b01bb9db0455ad2f5c959a714aa00064..2c3bdce151346f403ee171b2d85d601b1826b39d 100644 (file)
@@ -49,7 +49,7 @@ config ARM
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_SYSCALL_TRACEPOINTS
        select HAVE_UID16
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select KTIME_SCALAR
        select PERF_USE_VMALLOC
        select RTC_LIB
@@ -556,7 +556,6 @@ config ARCH_IXP4XX
 config ARCH_DOVE
        bool "Marvell Dove"
        select ARCH_REQUIRE_GPIOLIB
-       select COMMON_CLK_DOVE
        select CPU_V7
        select GENERIC_CLOCKEVENTS
        select MIGHT_HAVE_PCI
@@ -1657,13 +1656,16 @@ config LOCAL_TIMERS
          accounting to be spread across the timer interval, preventing a
          "thundering herd" at every timer tick.
 
+# The GPIO number here must be sorted by descending number. In case of
+# a multiplatform kernel, we just want the highest value required by the
+# selected platforms.
 config ARCH_NR_GPIO
        int
        default 1024 if ARCH_SHMOBILE || ARCH_TEGRA
-       default 355 if ARCH_U8500
-       default 264 if MACH_H4700
        default 512 if SOC_OMAP5
+       default 355 if ARCH_U8500
        default 288 if ARCH_VT8500 || ARCH_SUNXI
+       default 264 if MACH_H4700
        default 0
        help
          Maximum number of GPIOs in the system.
@@ -1887,8 +1889,9 @@ config XEN_DOM0
 
 config XEN
        bool "Xen guest support on ARM (EXPERIMENTAL)"
-       depends on ARM && OF
+       depends on ARM && AEABI && OF
        depends on CPU_V7 && !CPU_V6
+       depends on !GENERIC_ATOMIC64
        help
          Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
 
index acddddac7ee46fb961e8ba1fe86d038276d0a632..ecfcdba2d17c5976c34d238b19fb39181b36883d 100644 (file)
@@ -492,7 +492,7 @@ config DEBUG_IMX_UART_PORT
                                                DEBUG_IMX31_UART || \
                                                DEBUG_IMX35_UART || \
                                                DEBUG_IMX51_UART || \
-                                               DEBUG_IMX50_IMX53_UART || \
+                                               DEBUG_IMX53_UART || \
                                                DEBUG_IMX6Q_UART
        default 1
        help
index 71768b8a1ab91b7d7afe8241b11fc571cc30b516..84aa2caf07ed203fb810220258401a1b51f7cab3 100644 (file)
@@ -115,4 +115,4 @@ i:
        $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
        $(obj)/Image System.map "$(INSTALL_PATH)"
 
-subdir-            := bootp compressed
+subdir-            := bootp compressed dts
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 f8e4855bc9a536b34405dca9a8ff64a268542879..070bba4f25853be236d7b7cd26790283432b5364 100644 (file)
                        status = "okay";
                        /* No CD or WP GPIOs */
                };
+
+               usb@d0050000 {
+                       status = "okay";
+               };
+
+               usb@d0051000 {
+                       status = "okay";
+               };
        };
 };
index 6f1acc75e1559ca109066c7ad68c6e11f50087a0..5b708208b607b4b1eeaf7411040c56784fd93df5 100644 (file)
@@ -31,7 +31,6 @@
        mpic: interrupt-controller@d0020000 {
              compatible = "marvell,mpic";
              #interrupt-cells = <1>;
-             #address-cells = <1>;
              #size-cells = <1>;
              interrupt-controller;
        };
@@ -54,7 +53,7 @@
                                reg = <0xd0012000 0x100>;
                                reg-shift = <2>;
                                interrupts = <41>;
-                               reg-io-width = <4>;
+                               reg-io-width = <1>;
                                status = "disabled";
                };
                serial@d0012100 {
@@ -62,7 +61,7 @@
                                reg = <0xd0012100 0x100>;
                                reg-shift = <2>;
                                interrupts = <42>;
-                               reg-io-width = <4>;
+                               reg-io-width = <1>;
                                status = "disabled";
                };
 
index 1443949c165ea8fa787fe798f687a63a116f2626..ca00d8326c8746cd127e7c35f3c8e7d3da697c15 100644 (file)
@@ -46,7 +46,7 @@
                                reg = <0xd0012200 0x100>;
                                reg-shift = <2>;
                                interrupts = <43>;
-                               reg-io-width = <4>;
+                               reg-io-width = <1>;
                                status = "disabled";
                };
                serial@d0012300 {
@@ -54,7 +54,7 @@
                                reg = <0xd0012300 0x100>;
                                reg-shift = <2>;
                                interrupts = <44>;
-                               reg-io-width = <4>;
+                               reg-io-width = <1>;
                                status = "disabled";
                };
 
index 4bf2a8774aa76ab53889c51208f5fa0cf6841c11..7e0481e2441ac49b96d33ec1491414562a3d9935 100644 (file)
                        compatible = "fixed-clock";
                        reg = <1>;
                        #clock-cells = <0>;
-                       clock-frequency = <150000000>;
+                       clock-frequency = <250000000>;
                };
        };
 };
index 69140ba99f465ea357980c84cc232924a69071c0..9de93096601a2d1d526c37faf332a5510a4fc5d1 100644 (file)
                                };
                        };
 
-                       ab8500@5 {
+                       ab8500 {
                                compatible = "stericsson,ab8500";
-                               reg = <5>; /* mailbox 5 is i2c */
                                interrupt-parent = <&intc>;
                                interrupts = <0 40 0x4>;
                                interrupt-controller;
index 67dbe20868a2746638ef2e20c380633a1e6fbcfa..f7509cafc377a14dc38aa5d77232c264a8d8a301 100644 (file)
                        status = "disabled";
                };
 
+               rtc@d8500 {
+                       compatible = "marvell,orion-rtc";
+                       reg = <0xd8500 0x20>;
+               };
+
                crypto: crypto@30000 {
                        compatible = "marvell,orion-crypto";
                        reg = <0x30000 0x10000>,
index 592fb9dc35bdcd355293e923b5a07bb79d11b1b9..379128eb9d981fc8f38b69cd8420652f48d1f91a 100644 (file)
                                };
                        };
 
-                       ab8500@5 {
+                       ab8500 {
                                ab8500-regulators {
                                        ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
                                                regulator-name = "V-DISPLAY";
index 55f4191a626ede9b0f74d27752ede38d7a547b2b..2b587a74b8136f9d396deedffd9bd43c9bd28f54 100644 (file)
                                };
                        };
 
-                       ab8500@5 {
+                       ab8500 {
                                ab8500-regulators {
                                        ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
                                                regulator-name = "V-DISPLAY";
index e54fffd483690300c2a89e6719a2621b03aa75bb..468c0a1d48d93a0804737cc78494a21234887f3b 100644 (file)
                        fsl,pins = <689 0x10000         /* DISP1_DRDY   */
                                    482 0x10000         /* DISP1_HSYNC  */
                                    489 0x10000         /* DISP1_VSYNC  */
-                                   684 0x10000         /* DISP1_DAT_0  */
                                    515 0x10000         /* DISP1_DAT_22 */
                                    523 0x10000         /* DISP1_DAT_23 */
-                                   543 0x10000         /* DISP1_DAT_21 */
+                                   545 0x10000         /* DISP1_DAT_21 */
                                    553 0x10000         /* DISP1_DAT_20 */
                                    558 0x10000         /* DISP1_DAT_19 */
                                    564 0x10000         /* DISP1_DAT_18 */
index 5bb0bf39d3b88483ffd16828b57fdd8aceca7612..c9c44b2f62d7b6a4248a7f2d84125e14ce4b1284 100644 (file)
 
        ocp@f1000000 {
                serial@12000 {
-                       clock-frequency = <166666667>;
                        status = "okay";
                };
 
                serial@12100 {
-                       clock-frequency = <166666667>;
                        status = "okay";
                };
        };
index d430713ea9b93c3fd746df1e3f4a92cf31796026..e4e4930dc5cf78b9318e9f7015980ab5bd5b90da 100644 (file)
@@ -50,7 +50,6 @@
                        };
                };
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "okay";
                };
        };
index 2e3dd34e21a554298a029dc1bdf563c26f19ea59..0196cf6b0ef29c302e2628767d3284893cc851b9 100644 (file)
@@ -37,7 +37,6 @@
                        };
                };
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index ef2d8c7057093b8ef609488fe56ae45d9991c7b3..289e51d86372895ff6428892fe199cbefa255520 100644 (file)
@@ -38,7 +38,6 @@
                        };
                };
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index 1b133e0c566e80b4c4e47ab1cd2531772065489d..bd83b8fc7c83f01304397ac17e75be5a6438128e 100644 (file)
@@ -73,7 +73,6 @@
                        };
                };
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index 71902da33d6383583659adf35b16d7b3a1684c85..5335b1aa8601309f1ce9dc1a75a21243be1364f0 100644 (file)
@@ -51,7 +51,6 @@
                        };
                };
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "okay";
                };
 
index 504f16be8b54bf682a4c45413a354a48fd27c35e..12ccf74ac3c417e6de31fa5c33a2ab731f136220 100644 (file)
@@ -78,7 +78,6 @@
                        };
                };
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index 6cae4599c4b3e620974dbfa318119db952a56136..93c3afbef9eeecc4b0b3741c2bc2360717da81b9 100644 (file)
                };
 
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index 8db3123ac80f49d0bef30aa4c6c79dcf68690a51..5bbd0542cdd3b97848515a64fd55b49adfd0eaec 100644 (file)
@@ -34,7 +34,6 @@
                };
 
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index 9510c9ea666cc15dad8b512ac6c84d2b2cd8a0d5..9f55d95f35f5806ca126cb23120abbcf0d692a94 100644 (file)
@@ -13,7 +13,6 @@
 
        ocp@f1000000 {
                serial@12000 {
-                       clock-frequency = <166666667>;
                        status = "okay";
                };
        };
index 739019c4cba9c0806ca09da9b2c8cb2fffca2762..5c84c118ed8d6f81e490c9b7924c3aecd2fb845d 100644 (file)
@@ -13,7 +13,6 @@
 
        ocp@f1000000 {
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "okay";
                };
        };
index 662dfd81b1cee275358db30328259529928d99f1..758824118a9a8e22041817183449839f1c9c072e 100644 (file)
@@ -90,7 +90,6 @@
                 };
 
                 serial@12000 {
-                        clock-frequency = <200000000>;
                         status = "ok";
                 };
 
index e8e7ecef1650e3bb9ad6b73d43382a0946a4abff..6affd924fe11c48df75653970cb92cbac7954591 100644 (file)
@@ -23,7 +23,6 @@
                };
 
                serial@12000 {
-                       clock-frequency = <166666667>;
                        status = "okay";
                };
 
index 3a178cf708d729885c78d81926349e9c15fc4f56..a7412b937a8add0c3f0ccfbc165c0a5c3325f50d 100644 (file)
                };
 
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index ede7fe0d7a87d872f9a108f25c479d6fc0c1349d..d27f7245f8e71a07539b041121b66cb06e2402a7 100644 (file)
 
        ocp@f1000000 {
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
                serial@12100 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index 842ff95d60df1f392347abb9b5a1d44981a309be..66eb45b00b25218476c372a5bb1dfc20f3046fb0 100644 (file)
                };
 
                serial@12000 {
-                       clock-frequency = <200000000>;
                        status = "ok";
                };
 
index 2c738d9dc82a17143b1578c3867dbf87e304cef0..fada7e6d24d8543fd956ef18d7981aa12b9b9ee6 100644 (file)
@@ -38,6 +38,7 @@
                        interrupt-controller;
                        #interrupt-cells = <2>;
                        interrupts = <35>, <36>, <37>, <38>;
+                       clocks = <&gate_clk 7>;
                };
 
                gpio1: gpio@10140 {
@@ -49,6 +50,7 @@
                        interrupt-controller;
                        #interrupt-cells = <2>;
                        interrupts = <39>, <40>, <41>;
+                       clocks = <&gate_clk 7>;
                };
 
                serial@12000 {
@@ -57,7 +59,6 @@
                        reg-shift = <2>;
                        interrupts = <33>;
                        clocks = <&gate_clk 7>;
-                       /* set clock-frequency in board dts */
                        status = "disabled";
                };
 
@@ -67,7 +68,6 @@
                        reg-shift = <2>;
                        interrupts = <34>;
                        clocks = <&gate_clk 7>;
-                       /* set clock-frequency in board dts */
                        status = "disabled";
                };
 
@@ -75,6 +75,7 @@
                        compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc";
                        reg = <0x10300 0x20>;
                        interrupts = <53>;
+                       clocks = <&gate_clk 7>;
                };
 
                spi@10600 {
index 5a3a58b7e18fa134d71094ea27b5138b5ca5abc3..0077fc8510b78d5b92b03a5f3a7951ee5e9d5753 100644 (file)
@@ -11,7 +11,7 @@
 
 / {
        model = "LaCie Ethernet Disk mini V2";
-       compatible = "lacie,ethernet-disk-mini-v2", "marvell-orion5x-88f5182", "marvell,orion5x";
+       compatible = "lacie,ethernet-disk-mini-v2", "marvell,orion5x-88f5182", "marvell,orion5x";
 
        memory {
                reg = <0x00000000 0x4000000>; /* 64 MB */
index 27f31a5fa4947aa530d74cfa4c0260fc406ace7e..d3ec32f6b79073fc7171f966f47257cac86aabfb 100644 (file)
                                };
                        };
 
-                       ab8500@5 {
+                       ab8500 {
                                ab8500-regulators {
                                        ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
                                                regulator-name = "V-DISPLAY";
index 936d2306e7e12e9e46fd09294b6af54e41f0ccb3..7e8769bd59774334ce330c27b91e96d5783ee93e 100644 (file)
@@ -75,6 +75,9 @@
                                compatible = "arm,pl330", "arm,primecell";
                                reg = <0xffe01000 0x1000>;
                                interrupts = <0 180 4>;
+                               #dma-cells = <1>;
+                               #dma-channels = <8>;
+                               #dma-requests = <32>;
                        };
                };
 
index 9a428931d0429d2befef3d6d3084b7499eeb3a02..48d00a099ce38d75d0df6ceb513078383c8d54e5 100644 (file)
                compatible = "arm,cortex-a9-twd-timer";
                reg = <0x50040600 0x20>;
                interrupts = <1 13 0x304>;
+               clocks = <&tegra_car 132>;
        };
 
        intc: interrupt-controller {
index 767803e1fd55f2d6e75053527e47a26d536e4f77..9d87a3ffe9980a140585d063dbb9be5f2fbfa482 100644 (file)
                compatible = "arm,cortex-a9-twd-timer";
                reg = <0x50040600 0x20>;
                interrupts = <1 13 0xf04>;
+               clocks = <&tegra_car 214>;
        };
 
        intc: interrupt-controller {
index fbbc5bb022d56ad6f6244405cc0e0911eccfdfe0..6a99e30f81d2ac992da503ba5338571c2d2731ba 100644 (file)
@@ -116,6 +116,7 @@ CONFIG_SND_SOC=y
 CONFIG_SND_MXS_SOC=y
 CONFIG_SND_SOC_MXS_SGTL5000=y
 CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_CHIPIDEA=y
 CONFIG_USB_CHIPIDEA_HOST=y
 CONFIG_USB_STORAGE=y
index b16bae2c9a600f504c442c1c9f5513179e8d710a..bd07864f14a00b0fd9608139cb607ae9f021a154 100644 (file)
@@ -126,6 +126,8 @@ CONFIG_INPUT_MISC=y
 CONFIG_INPUT_TWL4030_PWRBUTTON=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
 # CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=32
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_MANY_PORTS=y
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 5c27696de14fda11bf6866138387f1149128e485..8b1f37bfeeecf3c2d8af09ed15bcbc4cc8fa991f 100644 (file)
@@ -2,6 +2,7 @@
 #define _ASM_ARM_XEN_EVENTS_H
 
 #include <asm/ptrace.h>
+#include <asm/atomic.h>
 
 enum ipi_vector {
        XEN_PLACEHOLDER_VECTOR,
@@ -15,26 +16,8 @@ static inline int xen_irqs_disabled(struct pt_regs *regs)
        return raw_irqs_disabled_flags(regs->ARM_cpsr);
 }
 
-/*
- * We cannot use xchg because it does not support 8-byte
- * values. However it is safe to use {ldr,dtd}exd directly because all
- * platforms which Xen can run on support those instructions.
- */
-static inline xen_ulong_t xchg_xen_ulong(xen_ulong_t *ptr, xen_ulong_t val)
-{
-       xen_ulong_t oldval;
-       unsigned int tmp;
-
-       wmb();
-       asm volatile("@ xchg_xen_ulong\n"
-               "1:     ldrexd  %0, %H0, [%3]\n"
-               "       strexd  %1, %2, %H2, [%3]\n"
-               "       teq     %1, #0\n"
-               "       bne     1b"
-               : "=&r" (oldval), "=&r" (tmp)
-               : "r" (val), "r" (ptr)
-               : "memory", "cc");
-       return oldval;
-}
+#define xchg_xen_ulong(ptr, val) atomic64_xchg(container_of((ptr),     \
+                                                           atomic64_t, \
+                                                           counter), (val))
 
 #endif /* _ASM_ARM_XEN_EVENTS_H */
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 2ea7059b840bfedc5a156d009c943ee4246340ac..c20a870ea9c9295e01eda9842650a3aa593533fd 100644 (file)
@@ -176,6 +176,7 @@ static struct w1_gpio_platform_data w1_gpio_pdata = {
        /* If you choose to use a pin other than PB16 it needs to be 3.3V */
        .pin            = AT91_PIN_PB16,
        .is_open_drain  = 1,
+       .ext_pullup_enable_pin  = -EINVAL,
 };
 
 static struct platform_device w1_device = {
index a033b8df9fb2b147965c95a7393958c832180983..869cbecf00b7eee51c78b4621019ac40ea2edacf 100644 (file)
@@ -188,6 +188,7 @@ static struct spi_board_info portuxg20_spi_devices[] = {
 static struct w1_gpio_platform_data w1_gpio_pdata = {
        .pin            = AT91_PIN_PA29,
        .is_open_drain  = 1,
+       .ext_pullup_enable_pin  = -EINVAL,
 };
 
 static struct platform_device w1_device = {
index 7b025ee528a517bdb7d584e90cebefc40fb56a48..2f9ff93a4e6134773befacb68c4dd4ec5c14bb90 100644 (file)
@@ -172,7 +172,7 @@ static struct clk *clk[clk_max];
 static struct clk_onecell_data clk_data;
 
 static enum mx6q_clks const clks_init_on[] __initconst = {
-       mmdc_ch0_axi, rom,
+       mmdc_ch0_axi, rom, pll1_sys,
 };
 
 static struct clk_div_table clk_enet_ref_table[] = {
index 921fc15558549093f0ff0bbcc9b9de946d520152..a58c8b0527ccb3aad1f542b83a159c868a61655d 100644 (file)
@@ -26,16 +26,16 @@ ENDPROC(v7_secondary_startup)
 
 #ifdef CONFIG_PM
 /*
- * The following code is located into the .data section.  This is to
- * allow phys_l2x0_saved_regs to be accessed with a relative load
- * as we are running on physical address here.
+ * The following code must assume it is running from physical address
+ * where absolute virtual addresses to the data section have to be
+ * turned into relative ones.
  */
-       .data
-       .align
 
 #ifdef CONFIG_CACHE_L2X0
        .macro  pl310_resume
-       ldr     r2, phys_l2x0_saved_regs
+       adr     r0, l2x0_saved_regs_offset
+       ldr     r2, [r0]
+       add     r2, r2, r0
        ldr     r0, [r2, #L2X0_R_PHY_BASE]      @ get physical base of l2x0
        ldr     r1, [r2, #L2X0_R_AUX_CTRL]      @ get aux_ctrl value
        str     r1, [r0, #L2X0_AUX_CTRL]        @ restore aux_ctrl
@@ -43,9 +43,9 @@ ENDPROC(v7_secondary_startup)
        str     r1, [r0, #L2X0_CTRL]            @ re-enable L2
        .endm
 
-       .globl  phys_l2x0_saved_regs
-phys_l2x0_saved_regs:
-        .long   0
+l2x0_saved_regs_offset:
+       .word   l2x0_saved_regs - .
+
 #else
        .macro  pl310_resume
        .endm
index ee42d20cba19f022d4a9ece8616e27b443d7e82e..5faba7a3c95f6e74393699045aa0635331459d46 100644 (file)
@@ -22,8 +22,6 @@
 #include "common.h"
 #include "hardware.h"
 
-extern unsigned long phys_l2x0_saved_regs;
-
 static int imx6q_suspend_finish(unsigned long val)
 {
        cpu_do_idle();
@@ -57,18 +55,5 @@ static const struct platform_suspend_ops imx6q_pm_ops = {
 
 void __init imx6q_pm_init(void)
 {
-       /*
-        * The l2x0 core code provides an infrastucture to save and restore
-        * l2x0 registers across suspend/resume cycle.  But because imx6q
-        * retains L2 content during suspend and needs to resume L2 before
-        * MMU is enabled, it can only utilize register saving support and
-        * have to take care of restoring on its own.  So we save physical
-        * address of the data structure used by l2x0 core to save registers,
-        * and later restore the necessary ones in imx6q resume entry.
-        */
-#ifdef CONFIG_CACHE_L2X0
-       phys_l2x0_saved_regs = __pa(&l2x0_saved_regs);
-#endif
-
        suspend_set_ops(&imx6q_pm_ops);
 }
index d42730a1d4abf5b85ccb193c6e9c297a140485c0..d599e354ca57fd6511db36fb8660636e6d152c81 100644 (file)
@@ -163,6 +163,7 @@ static struct platform_device vulcan_max6369 = {
 
 static struct w1_gpio_platform_data vulcan_w1_gpio_pdata = {
        .pin                    = 14,
+       .ext_pullup_enable_pin  = -EINVAL,
 };
 
 static struct platform_device vulcan_w1_gpio = {
index 2e73e9d53f705775246a057bb7cfbdf8219f44a2..d367aa6b47bbf8a11df36fd856e620e81b65d0c1 100644 (file)
@@ -41,16 +41,12 @@ static void __init kirkwood_legacy_clk_init(void)
 
        struct device_node *np = of_find_compatible_node(
                NULL, NULL, "marvell,kirkwood-gating-clock");
-
        struct of_phandle_args clkspec;
+       struct clk *clk;
 
        clkspec.np = np;
        clkspec.args_count = 1;
 
-       clkspec.args[0] = CGC_BIT_GE0;
-       orion_clkdev_add(NULL, "mv643xx_eth_port.0",
-                        of_clk_get_from_provider(&clkspec));
-
        clkspec.args[0] = CGC_BIT_PEX0;
        orion_clkdev_add("0", "pcie",
                         of_clk_get_from_provider(&clkspec));
@@ -59,9 +55,24 @@ static void __init kirkwood_legacy_clk_init(void)
        orion_clkdev_add("1", "pcie",
                         of_clk_get_from_provider(&clkspec));
 
-       clkspec.args[0] = CGC_BIT_GE1;
-       orion_clkdev_add(NULL, "mv643xx_eth_port.1",
+       clkspec.args[0] = CGC_BIT_SDIO;
+       orion_clkdev_add(NULL, "mvsdio",
                         of_clk_get_from_provider(&clkspec));
+
+       /*
+        * The ethernet interfaces forget the MAC address assigned by
+        * u-boot if the clocks are turned off. Until proper DT support
+        * is available we always enable them for now.
+        */
+       clkspec.args[0] = CGC_BIT_GE0;
+       clk = of_clk_get_from_provider(&clkspec);
+       orion_clkdev_add(NULL, "mv643xx_eth_port.0", clk);
+       clk_prepare_enable(clk);
+
+       clkspec.args[0] = CGC_BIT_GE1;
+       clk = of_clk_get_from_provider(&clkspec);
+       orion_clkdev_add(NULL, "mv643xx_eth_port.1", clk);
+       clk_prepare_enable(clk);
 }
 
 static void __init kirkwood_of_clk_init(void)
index 8fb23af154b391957da0c03b16ed1d046fca6d2e..e26eeba46598356be29a31fc1e1caeac1c07a9c3 100644 (file)
@@ -100,7 +100,7 @@ static struct irq_domain_ops icoll_irq_domain_ops = {
        .xlate = irq_domain_xlate_onecell,
 };
 
-void __init icoll_of_init(struct device_node *np,
+static void __init icoll_of_init(struct device_node *np,
                          struct device_node *interrupt_parent)
 {
        /*
index 052186713347c5b4ed1a17c503825f4b9894f316..3218f1f2c0e05dfe3b067324d1fecefadb86ae29 100644 (file)
@@ -402,17 +402,17 @@ static void __init cfa10049_init(void)
 {
        enable_clk_enet_out();
        update_fec_mac_prop(OUI_CRYSTALFONTZ);
+
+       mxsfb_pdata.mode_list = cfa10049_video_modes;
+       mxsfb_pdata.mode_count = ARRAY_SIZE(cfa10049_video_modes);
+       mxsfb_pdata.default_bpp = 32;
+       mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT;
 }
 
 static void __init cfa10037_init(void)
 {
        enable_clk_enet_out();
        update_fec_mac_prop(OUI_CRYSTALFONTZ);
-
-       mxsfb_pdata.mode_list = cfa10049_video_modes;
-       mxsfb_pdata.mode_count = ARRAY_SIZE(cfa10049_video_modes);
-       mxsfb_pdata.default_bpp = 32;
-       mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT;
 }
 
 static void __init apf28_init(void)
index a4294aa9f301f93c6166c1902fe8577753bc3961..e63b7d87acbda14b1c422113e8198e58c245c999 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <mach/mx23.h>
 #include <mach/mx28.h>
+#include <mach/common.h>
 
 /*
  * Define the MX23 memory map.
index 54add60f94c98c5d8d15c119e996395a13b6fc86..1dff46703753f67e96a3efd2a62a29966aba8b71 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/processor.h>     /* for cpu_relax() */
 
 #include <mach/mxs.h>
+#include <mach/common.h>
 
 #define OCOTP_WORD_OFFSET              0x20
 #define OCOTP_WORD_COUNT               0x20
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 fb18831e88aa5009fd8d1b546bba39d9397697d3..14f7e99204798dc5cfff4fc14be33c683751a405 100644 (file)
@@ -31,6 +31,8 @@
 
 #include <plat/i2c.h>
 
+#include <mach/irqs.h>
+
 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
 void omap7xx_map_io(void);
 #else
index 49ac3dfebef90b15d7d1da6e15f06e2807bc9cc1..8111cd9ff3e5201d9c92a66a90a24e30823d7074 100644 (file)
@@ -311,9 +311,6 @@ config MACH_OMAP_ZOOM2
        default y
        select OMAP_PACKAGE_CBB
        select REGULATOR_FIXED_VOLTAGE if REGULATOR
-       select SERIAL_8250
-       select SERIAL_8250_CONSOLE
-       select SERIAL_CORE_CONSOLE
 
 config MACH_OMAP_ZOOM3
        bool "OMAP3630 Zoom3 board"
@@ -321,9 +318,6 @@ config MACH_OMAP_ZOOM3
        default y
        select OMAP_PACKAGE_CBP
        select REGULATOR_FIXED_VOLTAGE if REGULATOR
-       select SERIAL_8250
-       select SERIAL_8250_CONSOLE
-       select SERIAL_CORE_CONSOLE
 
 config MACH_CM_T35
        bool "CompuLab CM-T35/CM-T3730 modules"
index 0274ff7a2a2b1c33dcdcf5e6aaac541f15a86c84..e54a480601988402e4b43fe54e4ac287fbed51d4 100644 (file)
@@ -102,6 +102,7 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
        .init_irq       = omap_intc_of_init,
        .handle_irq     = omap3_intc_handle_irq,
        .init_machine   = omap_generic_init,
+       .init_late      = omap3_init_late,
        .init_time      = omap3_sync32k_timer_init,
        .dt_compat      = omap3_boards_compat,
        .restart        = omap3xxx_restart,
@@ -119,6 +120,7 @@ DT_MACHINE_START(OMAP3_GP_DT, "Generic OMAP3-GP (Flattened Device Tree)")
        .init_irq       = omap_intc_of_init,
        .handle_irq     = omap3_intc_handle_irq,
        .init_machine   = omap_generic_init,
+       .init_late      = omap3_init_late,
        .init_time      = omap3_secure_sync32k_timer_init,
        .dt_compat      = omap3_gp_boards_compat,
        .restart        = omap3xxx_restart,
index f7c4616cbb60a7e90f45e1fdc8a686e3cd47857f..d2ea68ea678af901715aa609b4c5f41175641ddf 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/leds.h>
+#include <linux/usb/phy.h>
 #include <linux/usb/musb.h>
 #include <linux/platform_data/spi-omap2-mcspi.h>
 
@@ -98,6 +99,7 @@ static void __init rx51_init(void)
        sdrc_params = nokia_get_sdram_timings();
        omap_sdrc_init(sdrc_params, sdrc_params);
 
+       usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
        usb_musb_init(&musb_board_data);
        rx51_peripherals_init();
 
index 0a6b9c7a63da494f6596f702cc3763fe1a25a3d2..40f4a03d728fc9a7278b722ce809bd57f47c64f4 100644 (file)
@@ -108,7 +108,6 @@ void omap35xx_init_late(void);
 void omap3630_init_late(void);
 void am35xx_init_late(void);
 void ti81xx_init_late(void);
-void omap4430_init_late(void);
 int omap2_common_pm_late_init(void);
 
 #if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
index e4b16c8efe8b05d8296f6431f253f1dd5e0e49be..410e1bac781531e35fb4aa3b58b77a9a2a01111d 100644 (file)
@@ -1122,9 +1122,6 @@ int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
        /* TODO: remove, see function definition */
        gpmc_convert_ps_to_ns(gpmc_t);
 
-       /* Now the GPMC is initialised, unreserve the chip-selects */
-       gpmc_cs_map = 0;
-
        return 0;
 }
 
@@ -1383,6 +1380,9 @@ static int gpmc_probe(struct platform_device *pdev)
        if (IS_ERR_VALUE(gpmc_setup_irq()))
                dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
 
+       /* Now the GPMC is initialised, unreserve the chip-selects */
+       gpmc_cs_map = 0;
+
        rc = gpmc_probe_dt(pdev);
        if (rc < 0) {
                clk_disable_unprepare(gpmc_l3_clk);
index 6a217c98db5484a2560d08ff343219557ee75fb9..f82cf878d6af41da87b8bb444acd609105af72a9 100644 (file)
@@ -211,8 +211,6 @@ static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
                return -EINVAL;
        }
 
-       pr_err("%s: Could not find signal %s\n", __func__, muxname);
-
        return -ENODEV;
 }
 
@@ -234,6 +232,8 @@ int __init omap_mux_get_by_name(const char *muxname,
                return mux_mode;
        }
 
+       pr_err("%s: Could not find signal %s\n", __func__, muxname);
+
        return -ENODEV;
 }
 
@@ -739,8 +739,9 @@ static void __init omap_mux_dbg_create_entry(
        list_for_each_entry(e, &partition->muxmodes, node) {
                struct omap_mux *m = &e->mux;
 
-               (void)debugfs_create_file(m->muxnames[0], S_IWUSR, mux_dbg_dir,
-                                         m, &omap_mux_dbg_signal_fops);
+               (void)debugfs_create_file(m->muxnames[0], S_IWUSR | S_IRUGO,
+                                         mux_dbg_dir, m,
+                                         &omap_mux_dbg_signal_fops);
        }
 }
 
index af41888acbd674db746f194475b4ad077150b070..969b0ba7fa703a688a7078250c2118a3e19fe4b3 100644 (file)
@@ -505,6 +505,7 @@ static struct w1_gpio_platform_data w1_gpio_platform_data = {
        .pin                    = GPIO_ONE_WIRE,
        .is_open_drain          = 0,
        .enable_external_pullup = w1_enable_external_pullup,
+       .ext_pullup_enable_pin  = -EINVAL,
 };
 
 struct platform_device raumfeld_w1_gpio_device = {
index f9d754f90c5991e6bce11371fa5702f9a8d81c16..d2b3937c4014c1cc737d737d1800f0fb58de36ea 100644 (file)
@@ -14,7 +14,7 @@
 #define pr_fmt(fmt) "SPEAr3xx: " fmt
 
 #include <linux/amba/pl022.h>
-#include <linux/amba/pl08x.h>
+#include <linux/amba/pl080.h>
 #include <linux/io.h>
 #include <plat/pl080.h>
 #include <mach/generic.h>
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 c7e3759f16d303c8c989af0a903f768f358c0e4f..e9db6b4bf65a158adf54bd4a799dbc7fee754c36 100644 (file)
@@ -342,6 +342,7 @@ static int __init atomic_pool_init(void)
 {
        struct dma_pool *pool = &atomic_pool;
        pgprot_t prot = pgprot_dmacoherent(pgprot_kernel);
+       gfp_t gfp = GFP_KERNEL | GFP_DMA;
        unsigned long nr_pages = pool->size >> PAGE_SHIFT;
        unsigned long *bitmap;
        struct page *page;
@@ -361,8 +362,8 @@ static int __init atomic_pool_init(void)
                ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page,
                                              atomic_pool_init);
        else
-               ptr = __alloc_remap_buffer(NULL, pool->size, GFP_KERNEL, prot,
-                                          &page, atomic_pool_init);
+               ptr = __alloc_remap_buffer(NULL, pool->size, gfp, prot, &page,
+                                          atomic_pool_init);
        if (ptr) {
                int i;
 
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 febe3862873ca2238aaaccf3265991c97fe5384c..807ac8e5cbc062ed7e5dbb17869a163e58b15ce7 100644 (file)
@@ -157,9 +157,12 @@ void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
                u32 size = readl(ddr_window_cpu_base + DDR_SIZE_CS_OFF(i));
 
                /*
-                * Chip select enabled?
+                * We only take care of entries for which the chip
+                * select is enabled, and that don't have high base
+                * address bits set (devices can only access the first
+                * 32 bits of the memory).
                 */
-               if (size & 1) {
+               if ((size & 1) && !(base & 0xF)) {
                        struct mbus_dram_window *w;
 
                        w = &orion_mbus_dram_info.cs[cs++];
index 739d016eb273faf8a22859856767901ce7e8beef..8a08c31b5e20a950052901f6549dccc09f1d871a 100644 (file)
@@ -10,7 +10,7 @@ choice
 
 config ARCH_SPEAR13XX
        bool "ST SPEAr13xx with Device Tree"
-       select ARCH_HAVE_CPUFREQ
+       select ARCH_HAS_CPUFREQ
        select ARM_GIC
        select CPU_V7
        select GPIO_SPEAR_SPICS
index 9b89257b2cfdc348746e0145ea428afdfc97c273..c1a868d398bd284f6c7552d31279e24215792f51 100644 (file)
@@ -7,7 +7,7 @@ config AVR32
        select HAVE_OPROFILE
        select HAVE_KPROBES
        select HAVE_GENERIC_HARDIRQS
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select GENERIC_IRQ_PROBE
        select GENERIC_ATOMIC64
        select HARDIRQS_SW_RESEND
index 600494c70e96e2d26728cc2967a31053a470f667..c3f2e0bc644aed0b64e86b7a801424d5cb239b9a 100644 (file)
@@ -33,7 +33,7 @@ config BLACKFIN
        select ARCH_HAVE_CUSTOM_GPIO_H
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select HAVE_UID16
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select ARCH_WANT_IPC_PARSE_VERSION
        select HAVE_GENERIC_HARDIRQS
        select GENERIC_ATOMIC64
index bb0ac66cf5336aab4e240e32ad44d6fd8ea10679..06dd026533e3b758b68091bc0a8c754b3084f0da 100644 (file)
@@ -43,7 +43,7 @@ config CRIS
        select GENERIC_ATOMIC64
        select HAVE_GENERIC_HARDIRQS
        select HAVE_UID16
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select ARCH_WANT_IPC_PARSE_VERSION
        select GENERIC_IRQ_SHOW
        select GENERIC_IOMAP
index 12369b194c7b2e98a9fa00b688882809f3000c36..2ce731f9aa4d522abfc7d2fbcfff33483a2b2154 100644 (file)
@@ -6,7 +6,7 @@ config FRV
        select HAVE_PERF_EVENTS
        select HAVE_UID16
        select HAVE_GENERIC_HARDIRQS
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select GENERIC_IRQ_SHOW
        select HAVE_DEBUG_BUGVERBOSE
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
index ae8551eb3736ae201bd2decbf1fc34feb23f9c75..79250de1b12a434f7b0d945cb6b4b42559a9d101 100644 (file)
@@ -5,7 +5,7 @@ config H8300
        select HAVE_GENERIC_HARDIRQS
        select GENERIC_ATOMIC64
        select HAVE_UID16
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select ARCH_WANT_IPC_PARSE_VERSION
        select GENERIC_IRQ_SHOW
        select GENERIC_CPU_DEVICES
index 33f3fdc0b214e93350b95d8ec8fcc935df2b56d9..9a02f71c6b1f7cb5e8339e55f77bb82ad9b8d8d3 100644 (file)
@@ -26,7 +26,7 @@ config IA64
        select HAVE_MEMBLOCK
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_VIRT_CPU_ACCOUNTING
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select ARCH_DISCARD_MEMBLOCK
        select GENERIC_IRQ_PROBE
        select GENERIC_PENDING_IRQ if SMP
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 92623818a1fe0ecb6147ceed0ebeb900a79df49e..bcd17b20657128ef42c2f68f0dd07880467f1c2c 100644 (file)
@@ -10,7 +10,7 @@ config M32R
        select ARCH_WANT_IPC_PARSE_VERSION
        select HAVE_DEBUG_BUGVERBOSE
        select HAVE_GENERIC_HARDIRQS
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select GENERIC_IRQ_PROBE
        select GENERIC_IRQ_SHOW
        select GENERIC_ATOMIC64
index da4518f82d6d31d71609d7a670924cbe79c88c2a..98470fe483b67861b952f7c35bb946111016c9db 100644 (file)
@@ -63,10 +63,10 @@ struct stat64 {
        long long       st_size;
        unsigned long   st_blksize;
 
-#if defined(__BIG_ENDIAN)
+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN)
        unsigned long   __pad4;         /* future possible st_blocks high bits */
        unsigned long   st_blocks;      /* Number 512-byte blocks allocated. */
-#elif defined(__LITTLE_ENDIAN)
+#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
        unsigned long   st_blocks;      /* Number 512-byte blocks allocated. */
        unsigned long   __pad4;         /* future possible st_blocks high bits */
 #else
index 0e708c78e01c6f82cdc87af1c9cd60eef285173e..6de813370b8c7d01e8b98d78634baef15da6fe3b 100644 (file)
@@ -8,7 +8,7 @@ config M68K
        select GENERIC_IRQ_SHOW
        select GENERIC_ATOMIC64
        select HAVE_UID16
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
        select GENERIC_CPU_DEVICES
        select GENERIC_STRNCPY_FROM_USER if MMU
index 7cdf6b010381f8ae31332012c18d93345232514a..7240584d343974847fbaab832bcf50388d8d2ba3 100644 (file)
@@ -310,7 +310,6 @@ config COBRA5282
 config SOM5282EM
        bool "EMAC.Inc SOM5282EM board support"
        depends on M528x
-       select EMAC_INC
        help
          Support for the EMAC.Inc SOM5282EM module.
 
index a337e56d09bf9118eea7004ee9ba21921b02faca..4ebf098b8a1fd58c9a222d864b9f4cea6f6c2171 100644 (file)
 /*
  * Here go the bitmasks themselves
  */
-#define IMR_MSPIM      (1 << SPIM _IRQ_NUM)    /* Mask SPI Master interrupt */
+#define IMR_MSPIM      (1 << SPIM_IRQ_NUM)     /* Mask SPI Master interrupt */
 #define        IMR_MTMR2       (1 << TMR2_IRQ_NUM)     /* Mask Timer 2 interrupt */
 #define IMR_MUART      (1 << UART_IRQ_NUM)     /* Mask UART interrupt */       
 #define        IMR_MWDT        (1 << WDT_IRQ_NUM)      /* Mask Watchdog Timer interrupt */
 #define IWR_ADDR       0xfffff308
 #define IWR            LONG_REF(IWR_ADDR)
 
-#define IWR_SPIM       (1 << SPIM _IRQ_NUM)    /* SPI Master interrupt */
+#define IWR_SPIM       (1 << SPIM_IRQ_NUM)     /* SPI Master interrupt */
 #define        IWR_TMR2        (1 << TMR2_IRQ_NUM)     /* Timer 2 interrupt */
 #define IWR_UART       (1 << UART_IRQ_NUM)     /* UART interrupt */    
 #define        IWR_WDT         (1 << WDT_IRQ_NUM)      /* Watchdog Timer interrupt */
 #define ISR_ADDR       0xfffff30c
 #define ISR            LONG_REF(ISR_ADDR)
 
-#define ISR_SPIM       (1 << SPIM _IRQ_NUM)    /* SPI Master interrupt */
+#define ISR_SPIM       (1 << SPIM_IRQ_NUM)     /* SPI Master interrupt */
 #define        ISR_TMR2        (1 << TMR2_IRQ_NUM)     /* Timer 2 interrupt */
 #define ISR_UART       (1 << UART_IRQ_NUM)     /* UART interrupt */    
 #define        ISR_WDT         (1 << WDT_IRQ_NUM)      /* Watchdog Timer interrupt */
 #define IPR_ADDR       0xfffff310
 #define IPR            LONG_REF(IPR_ADDR)
 
-#define IPR_SPIM       (1 << SPIM _IRQ_NUM)    /* SPI Master interrupt */
+#define IPR_SPIM       (1 << SPIM_IRQ_NUM)     /* SPI Master interrupt */
 #define        IPR_TMR2        (1 << TMR2_IRQ_NUM)     /* Timer 2 interrupt */
 #define IPR_UART       (1 << UART_IRQ_NUM)     /* UART interrupt */    
 #define        IPR_WDT         (1 << WDT_IRQ_NUM)      /* Watchdog Timer interrupt */
 
 /* 'EZ328-compatible definitions */
 #define TCN_ADDR       TCN1_ADDR
-#define TCN            TCN
+#define TCN            TCN1
 
 /*
  * Timer Unit 1 and 2 Status Registers
index 71fb29938dba260b6e5895c3d7eb5f10f2afbb16..911ba472e6c4abbd83dac862a561d98eb22526aa 100644 (file)
@@ -57,6 +57,9 @@ void (*mach_reset)(void);
 void (*mach_halt)(void);
 void (*mach_power_off)(void);
 
+#ifdef CONFIG_M68000
+#define CPU_NAME       "MC68000"
+#endif
 #ifdef CONFIG_M68328
 #define CPU_NAME       "MC68328"
 #endif
index afd8106fd83b10c2b1d51b956b178effd9a6b096..519aad8fa812ca6ac7ce07f82abb06ae080139bf 100644 (file)
@@ -188,7 +188,7 @@ void __init mem_init(void)
                }
        }
 
-#if !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
+#if defined(CONFIG_MMU) && !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE)
        /* insert pointer tables allocated so far into the tablelist */
        init_pointer_table((unsigned long)kernel_pg_dir);
        for (i = 0; i < PTRS_PER_PGD; i++) {
index 83b7dad7a84e7a1928d105fa6b08acfe3bc8c546..b03a9d271837a8efa46245eb7dc90b7a9a322b12 100644 (file)
@@ -69,7 +69,7 @@ static void __init m528x_uarts_init(void)
        u8 port;
 
        /* make sure PUAPAR is set for UART0 and UART1 */
-       port = readb(MCF5282_GPIO_PUAPAR);
+       port = readb(MCFGPIO_PUAPAR);
        port |= 0x03 | (0x03 << 2);
        writeb(port, MCFGPIO_PUAPAR);
 }
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 7843d11156e60a36d20a5f499b2ff6623e8aa275..1323fa2530eb7c144abe5da9ab1318e410d1c643 100644 (file)
@@ -19,7 +19,7 @@ config MICROBLAZE
        select HAVE_DEBUG_KMEMLEAK
        select IRQ_DOMAIN
        select HAVE_GENERIC_HARDIRQS
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select GENERIC_IRQ_PROBE
        select GENERIC_IRQ_SHOW
        select GENERIC_PCI_IOMAP
index ae9c716c46bbf5d93849f5ad9dcb5e3c9a47fd88..cd2e21ff562af434803045c048dbbfbcd28a50cb 100644 (file)
@@ -38,7 +38,7 @@ config MIPS
        select GENERIC_CLOCKEVENTS
        select GENERIC_CMOS_UPDATE
        select HAVE_MOD_ARCH_SPECIFIC
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select MODULES_USE_ELF_REL if MODULES
        select MODULES_USE_ELF_RELA if MODULES && 64BIT
        select CLONE_BACKWARDS
index b06c7360b1c6fafd6ba5ea9faba8d7dd0c9abbca..428da175d0734abab132fbbbad57154b05530b1d 100644 (file)
@@ -8,7 +8,7 @@ config MN10300
        select HAVE_ARCH_KGDB
        select GENERIC_ATOMIC64
        select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select GENERIC_CLOCKEVENTS
        select MODULES_USE_ELF_RELA
        select OLD_SIGSUSPEND3
index 014a6482ed4ce3c38c44d4bef68c758f9e684a31..9ab3bf2eca8d2efeef9f0adbadc8b94c356cb857 100644 (file)
@@ -9,10 +9,9 @@ config OPENRISC
        select OF_EARLY_FLATTREE
        select IRQ_DOMAIN
        select HAVE_MEMBLOCK
-       select ARCH_WANT_OPTIONAL_GPIOLIB
+       select ARCH_REQUIRE_GPIOLIB
         select HAVE_ARCH_TRACEHOOK
        select HAVE_GENERIC_HARDIRQS
-       select HAVE_VIRT_TO_BUS
        select GENERIC_IRQ_CHIP
        select GENERIC_IRQ_PROBE
        select GENERIC_IRQ_SHOW
index a9ff712a28643e235892c8ec426ed9b596ce77d6..0339181bf3ac3d377db760ef93a7e74933288eee 100644 (file)
@@ -21,7 +21,7 @@ config PARISC
        select GENERIC_STRNCPY_FROM_USER
        select SYSCTL_ARCH_UNALIGN_ALLOW
        select HAVE_MOD_ARCH_SPECIFIC
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select MODULES_USE_ELF_RELA
        select CLONE_BACKWARDS
        select TTY # Needed for pdc_cons.c
index b89d7eb730a25360129d0d4b7f83136e130a227d..80821512e9cc13327b4438d6ba96317b930097e9 100644 (file)
@@ -98,7 +98,7 @@ config PPC
        select HAVE_FUNCTION_GRAPH_TRACER
        select SYSCTL_EXCEPTION_TRACE
        select ARCH_WANT_OPTIONAL_GPIOLIB
-       select HAVE_VIRT_TO_BUS if !PPC64
+       select VIRT_TO_BUS if !PPC64
        select HAVE_IDE
        select HAVE_IOREMAP_PROT
        select HAVE_EFFICIENT_UNALIGNED_ACCESS
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 4b505370a1d59430b0bc519c47b926b0ed29adab..eb8fb629f00bba774b195a475471d630d6bd8bd0 100644 (file)
@@ -134,7 +134,7 @@ config S390
        select HAVE_SYSCALL_WRAPPERS
        select HAVE_UID16 if 32BIT
        select HAVE_VIRT_CPU_ACCOUNTING
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select INIT_ALL_POSSIBLE
        select KTIME_SCALAR if 32BIT
        select MODULES_USE_ELF_RELA
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 f1eddd150dd7e782876ed8faff25a6d004b3f841..c879fad404c8d36d73aff75ea1174df65374061b 100644 (file)
@@ -12,6 +12,7 @@
 #ifndef _ASM_S390_CPU_MF_H
 #define _ASM_S390_CPU_MF_H
 
+#include <linux/errno.h>
 #include <asm/facility.h>
 
 #define CPU_MF_INT_SF_IAE      (1 << 31)       /* invalid entry address */
index e569aa1fd2ba7a5c68d6dfb95564e98c2397f9d7..c8def8bc90209578a5a6d5cfaf8f9f258c4ec7fb 100644 (file)
@@ -12,7 +12,7 @@ config SCORE
        select GENERIC_CPU_DEVICES
        select GENERIC_CLOCKEVENTS
        select HAVE_MOD_ARCH_SPECIFIC
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select MODULES_USE_ELF_REL
        select CLONE_BACKWARDS
 
index ff496ab1e79445472aabd261ef133e2565c2a513..25877aebc685fcde958145add51e09e7fcbcc341 100644 (file)
@@ -17,7 +17,7 @@ config TILE
        select GENERIC_IRQ_SHOW
        select HAVE_DEBUG_BUGVERBOSE
        select HAVE_SYSCALL_WRAPPERS if TILEGX
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select SYS_HYPERVISOR
        select ARCH_HAVE_NMI_SAFE_CMPXCHG
        select GENERIC_CLOCKEVENTS
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 78f1b899996446e9e769ff703938dbb7bedc6fe6..c512b0306dd41beff8039787d1eca7b90546ed40 100644 (file)
@@ -37,7 +37,7 @@ extern int console_write_chan(struct chan *chan, const char *buf,
 extern int console_open_chan(struct line *line, struct console *co);
 extern void deactivate_chan(struct chan *chan, int irq);
 extern void reactivate_chan(struct chan *chan, int irq);
-extern void chan_enable_winch(struct chan *chan, struct tty_struct *tty);
+extern void chan_enable_winch(struct chan *chan, struct tty_port *port);
 extern int enable_chan(struct line *line);
 extern void close_chan(struct line *line);
 extern int chan_window_size(struct line *line, 
index 15c553c239a119259f2f948f8381e5a9a26f4ccb..80b47cb71e0a85e7ea1a10626f7a1e0efe8e5225 100644 (file)
@@ -122,10 +122,10 @@ static int open_chan(struct list_head *chans)
        return err;
 }
 
-void chan_enable_winch(struct chan *chan, struct tty_struct *tty)
+void chan_enable_winch(struct chan *chan, struct tty_port *port)
 {
        if (chan && chan->primary && chan->ops->winch)
-               register_winch(chan->fd, tty);
+               register_winch(chan->fd, port);
 }
 
 static void line_timer_cb(struct work_struct *work)
index 9be670ad23b5fa6c94bb6b361bb9db59a0924a2d..3fd7c3efdb18df6b0f8f1dfd68e3883052b329c1 100644 (file)
@@ -216,7 +216,7 @@ static int winch_thread(void *arg)
        }
 }
 
-static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out,
+static int winch_tramp(int fd, struct tty_port *port, int *fd_out,
                       unsigned long *stack_out)
 {
        struct winch_data data;
@@ -271,7 +271,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out,
        return err;
 }
 
-void register_winch(int fd, struct tty_struct *tty)
+void register_winch(int fd, struct tty_port *port)
 {
        unsigned long stack;
        int pid, thread, count, thread_fd = -1;
@@ -281,17 +281,17 @@ void register_winch(int fd, struct tty_struct *tty)
                return;
 
        pid = tcgetpgrp(fd);
-       if (is_skas_winch(pid, fd, tty)) {
-               register_winch_irq(-1, fd, -1, tty, 0);
+       if (is_skas_winch(pid, fd, port)) {
+               register_winch_irq(-1, fd, -1, port, 0);
                return;
        }
 
        if (pid == -1) {
-               thread = winch_tramp(fd, tty, &thread_fd, &stack);
+               thread = winch_tramp(fd, port, &thread_fd, &stack);
                if (thread < 0)
                        return;
 
-               register_winch_irq(thread_fd, fd, thread, tty, stack);
+               register_winch_irq(thread_fd, fd, thread, port, stack);
 
                count = write(thread_fd, &c, sizeof(c));
                if (count != sizeof(c))
index dc693298eb8fc0a73719d98521f8a4ae9f911dfa..03f1b565c5f9ac9028ed7b91444b89c1dde963f1 100644 (file)
@@ -38,10 +38,10 @@ extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
                               unsigned short *cols_out);
 extern void generic_free(void *data);
 
-struct tty_struct;
-extern void register_winch(int fd,  struct tty_struct *tty);
+struct tty_port;
+extern void register_winch(int fd,  struct tty_port *port);
 extern void register_winch_irq(int fd, int tty_fd, int pid,
-                              struct tty_struct *tty, unsigned long stack);
+                              struct tty_port *port, unsigned long stack);
 
 #define __channel_help(fn, prefix) \
 __uml_help(fn, prefix "[0-9]*=<channel description>\n" \
index f1b38571f94e7996d1c83712945583e3d1e75a06..be541cf69fd282cea191a3580e851549f25c39e0 100644 (file)
@@ -305,7 +305,7 @@ static int line_activate(struct tty_port *port, struct tty_struct *tty)
                return ret;
 
        if (!line->sigio) {
-               chan_enable_winch(line->chan_out, tty);
+               chan_enable_winch(line->chan_out, port);
                line->sigio = 1;
        }
 
@@ -315,8 +315,22 @@ static int line_activate(struct tty_port *port, struct tty_struct *tty)
        return 0;
 }
 
+static void unregister_winch(struct tty_struct *tty);
+
+static void line_destruct(struct tty_port *port)
+{
+       struct tty_struct *tty = tty_port_tty_get(port);
+       struct line *line = tty->driver_data;
+
+       if (line->sigio) {
+               unregister_winch(tty);
+               line->sigio = 0;
+       }
+}
+
 static const struct tty_port_operations line_port_ops = {
        .activate = line_activate,
+       .destruct = line_destruct,
 };
 
 int line_open(struct tty_struct *tty, struct file *filp)
@@ -340,18 +354,6 @@ int line_install(struct tty_driver *driver, struct tty_struct *tty,
        return 0;
 }
 
-static void unregister_winch(struct tty_struct *tty);
-
-void line_cleanup(struct tty_struct *tty)
-{
-       struct line *line = tty->driver_data;
-
-       if (line->sigio) {
-               unregister_winch(tty);
-               line->sigio = 0;
-       }
-}
-
 void line_close(struct tty_struct *tty, struct file * filp)
 {
        struct line *line = tty->driver_data;
@@ -601,7 +603,7 @@ struct winch {
        int fd;
        int tty_fd;
        int pid;
-       struct tty_struct *tty;
+       struct tty_port *port;
        unsigned long stack;
        struct work_struct work;
 };
@@ -655,7 +657,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
                        goto out;
                }
        }
-       tty = winch->tty;
+       tty = tty_port_tty_get(winch->port);
        if (tty != NULL) {
                line = tty->driver_data;
                if (line != NULL) {
@@ -663,6 +665,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
                                         &tty->winsize.ws_col);
                        kill_pgrp(tty->pgrp, SIGWINCH, 1);
                }
+               tty_kref_put(tty);
        }
  out:
        if (winch->fd != -1)
@@ -670,7 +673,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
+void register_winch_irq(int fd, int tty_fd, int pid, struct tty_port *port,
                        unsigned long stack)
 {
        struct winch *winch;
@@ -685,7 +688,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
                                   .fd          = fd,
                                   .tty_fd      = tty_fd,
                                   .pid         = pid,
-                                  .tty         = tty,
+                                  .port        = port,
                                   .stack       = stack });
 
        if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
@@ -714,15 +717,18 @@ static void unregister_winch(struct tty_struct *tty)
 {
        struct list_head *ele, *next;
        struct winch *winch;
+       struct tty_struct *wtty;
 
        spin_lock(&winch_handler_lock);
 
        list_for_each_safe(ele, next, &winch_handlers) {
                winch = list_entry(ele, struct winch, list);
-               if (winch->tty == tty) {
+               wtty = tty_port_tty_get(winch->port);
+               if (wtty == tty) {
                        free_winch(winch);
                        break;
                }
+               tty_kref_put(wtty);
        }
        spin_unlock(&winch_handler_lock);
 }
index d8926c30362946475822ff21ca6a4d5dc9f20cbf..39f186252e02521ccc33eb0fad6b450ccfb19d73 100644 (file)
@@ -218,6 +218,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
        spin_lock_irqsave(&lp->lock, flags);
 
        len = (*lp->write)(lp->fd, skb, lp);
+       skb_tx_timestamp(skb);
 
        if (len == skb->len) {
                dev->stats.tx_packets++;
@@ -281,6 +282,7 @@ static void uml_net_get_drvinfo(struct net_device *dev,
 static const struct ethtool_ops uml_net_ethtool_ops = {
        .get_drvinfo    = uml_net_get_drvinfo,
        .get_link       = ethtool_op_get_link,
+       .get_ts_info    = ethtool_op_get_ts_info,
 };
 
 static void uml_net_user_timer_expire(unsigned long _conn)
index 16fdd0a0f9d617c67b7d99f0aa4317f2fcdfc7aa..b8d14fa5205901b0955b33735d4026d2ee49f8d2 100644 (file)
@@ -105,7 +105,6 @@ static const struct tty_operations ssl_ops = {
        .throttle               = line_throttle,
        .unthrottle             = line_unthrottle,
        .install                = ssl_install,
-       .cleanup                = line_cleanup,
        .hangup                 = line_hangup,
 };
 
index 827777af3f6d673bcb26570e4e28ccc370cfcd5e..7b361f36ca965f7b9ce202133f752e0347290c04 100644 (file)
@@ -110,7 +110,6 @@ static const struct tty_operations console_ops = {
        .set_termios            = line_set_termios,
        .throttle               = line_throttle,
        .unthrottle             = line_unthrottle,
-       .cleanup                = line_cleanup,
        .hangup                 = line_hangup,
 };
 
index b1469fe9329564dac95f1fc5b6320f0ed56ea31b..9d9f1b4bf8269d89af35a08b5e24064337a410e4 100644 (file)
@@ -15,7 +15,7 @@
 #include <sysdep/mcontext.h>
 #include "internal.h"
 
-void (*sig_info[NSIG])(int, siginfo_t *, struct uml_pt_regs *) = {
+void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = {
        [SIGTRAP]       = relay_signal,
        [SIGFPE]        = relay_signal,
        [SIGILL]        = relay_signal,
index da4b9e9999fd2640764c8a4afe0c11ca2f43bc3b..337518c5042a5cb4895e389202e6a4c5bc9654b2 100644 (file)
@@ -15,6 +15,8 @@
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/resource.h>
 #include <asm/unistd.h>
 #include <init.h>
 #include <os.h>
index dc50b157fc83385b815768fb69ca2351fac83271..2943e3acdf0cba611bcd0fc222fbc59fb3f6602a 100644 (file)
@@ -9,7 +9,7 @@ config UNICORE32
        select GENERIC_ATOMIC64
        select HAVE_KERNEL_LZO
        select HAVE_KERNEL_LZMA
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select ARCH_HAVE_CUSTOM_GPIO_H
        select GENERIC_FIND_FIRST_BIT
        select GENERIC_IRQ_PROBE
index a4f24f5b1218520074eacc4918bcf5fd04d139a4..70c0f3da0476a35ba93546689bb4b06b5f576bba 100644 (file)
@@ -112,7 +112,7 @@ config X86
        select GENERIC_STRNLEN_USER
        select HAVE_CONTEXT_TRACKING if X86_64
        select HAVE_IRQ_TIME_ACCOUNTING
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select MODULES_USE_ELF_REL if X86_32
        select MODULES_USE_ELF_RELA if X86_64
        select CLONE_BACKWARDS if X86_32
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 826054a4f2ee4c54ea4cfb9d29ab117db35e7fc5..b05a575d56f42f4543504b999a3b4875de110772 100644 (file)
@@ -729,3 +729,13 @@ void intel_ds_init(void)
                }
        }
 }
+
+void perf_restore_debug_store(void)
+{
+       struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
+
+       if (!x86_pmu.bts && !x86_pmu.pebs)
+               return;
+
+       wrmsrl(MSR_IA32_DS_AREA, (unsigned long)ds);
+}
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 120cee1c3f8d6ab8d3873c537d063e3d45553778..3c68768d7a75963d8825f65b3ac28fff2f257361 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/suspend.h>
 #include <linux/export.h>
 #include <linux/smp.h>
+#include <linux/perf_event.h>
 
 #include <asm/pgtable.h>
 #include <asm/proto.h>
@@ -228,6 +229,7 @@ static void __restore_processor_state(struct saved_context *ctxt)
        do_fpu_end();
        x86_platform.restore_sched_clock_state();
        mtrr_bp_restore();
+       perf_restore_debug_store();
 }
 
 /* Needed by apm.c */
index 35876ffac11d19875b15828a2d8bee3c51081baa..b09de49dbec5cf0a7d65590afc7c2a97158399bf 100644 (file)
@@ -9,7 +9,7 @@ config XTENSA
        select HAVE_IDE
        select GENERIC_ATOMIC64
        select HAVE_GENERIC_HARDIRQS
-       select HAVE_VIRT_TO_BUS
+       select VIRT_TO_BUS
        select GENERIC_IRQ_SHOW
        select GENERIC_CPU_DEVICES
        select MODULES_USE_ELF_RELA
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 53e7ac9403a7dc21502e90a698ef1b27ad668a37..e854582f29a672a5920500333e26a0b77b310e58 100644 (file)
@@ -465,7 +465,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
        return result;
 }
 
-static int acpi_processor_get_performance_info(struct acpi_processor *pr)
+int acpi_processor_get_performance_info(struct acpi_processor *pr)
 {
        int result = 0;
        acpi_status status = AE_OK;
@@ -509,7 +509,7 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr)
 #endif
        return result;
 }
-
+EXPORT_SYMBOL_GPL(acpi_processor_get_performance_info);
 int acpi_processor_notify_smm(struct module *calling_module)
 {
        acpi_status status;
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 10fd71ccf587789858582b09f37e646b7119e937..6bf4d47324eb884e7f462678acf493fec4c518b1 100644 (file)
@@ -92,14 +92,22 @@ static int probe_common(struct virtio_device *vdev)
 {
        int err;
 
+       if (vq) {
+               /* We only support one device for now */
+               return -EBUSY;
+       }
        /* We expect a single virtqueue. */
        vq = virtio_find_single_vq(vdev, random_recv_done, "input");
-       if (IS_ERR(vq))
-               return PTR_ERR(vq);
+       if (IS_ERR(vq)) {
+               err = PTR_ERR(vq);
+               vq = NULL;
+               return err;
+       }
 
        err = hwrng_register(&virtio_hwrng);
        if (err) {
                vdev->config->del_vqs(vdev);
+               vq = NULL;
                return err;
        }
 
@@ -112,6 +120,7 @@ static void remove_common(struct virtio_device *vdev)
        busy = false;
        hwrng_unregister(&virtio_hwrng);
        vdev->config->del_vqs(vdev);
+       vq = NULL;
 }
 
 static int virtrng_probe(struct virtio_device *vdev)
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 143ce1f899ad74a5ce447652f64bb48c34b39652..1e2de730536282da499d60a57397f56b7d871c5e 100644 (file)
@@ -1292,7 +1292,6 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = {
        TEGRA_CLK_DUPLICATE(usbd,   "tegra-ehci.0", NULL),
        TEGRA_CLK_DUPLICATE(usbd,   "tegra-otg",    NULL),
        TEGRA_CLK_DUPLICATE(cclk,   NULL,           "cpu"),
-       TEGRA_CLK_DUPLICATE(twd,    "smp_twd",      NULL),
        TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* Must be the last entry */
 };
 
index 32c61cb6d0bb186d01a37fbea5dc3b15ef126e86..ba6f51bc9f3b8bc229bf0900ff380002fbb51e14 100644 (file)
@@ -1931,7 +1931,6 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = {
        TEGRA_CLK_DUPLICATE(cml1, "tegra_sata_cml", NULL),
        TEGRA_CLK_DUPLICATE(cml0, "tegra_pcie", "cml"),
        TEGRA_CLK_DUPLICATE(pciex, "tegra_pcie", "pciex"),
-       TEGRA_CLK_DUPLICATE(twd, "smp_twd", NULL),
        TEGRA_CLK_DUPLICATE(vcp, "nvavp", "vcp"),
        TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* MUST be the last entry */
 };
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 7472182967ce15b44d964d184038fbca247724e8..61a6fde6c089b28a76f3ca5012309c101ebcf2b2 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/io.h>
 #include <linux/of_irq.h>
 #include <linux/of_device.h>
+#include <linux/clk.h>
 #include <linux/pinctrl/consumer.h>
 
 /*
@@ -496,6 +497,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
        struct resource *res;
        struct irq_chip_generic *gc;
        struct irq_chip_type *ct;
+       struct clk *clk;
        unsigned int ngpios;
        int soc_variant;
        int i, cpu, id;
@@ -529,6 +531,11 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
                return id;
        }
 
+       clk = devm_clk_get(&pdev->dev, NULL);
+       /* Not all SoCs require a clock.*/
+       if (!IS_ERR(clk))
+               clk_prepare_enable(clk);
+
        mvchip->soc_variant = soc_variant;
        mvchip->chip.label = dev_name(&pdev->dev);
        mvchip->chip.dev = &pdev->dev;
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 5fa13267bd9f427b7f83251f22e6bd13a80683b3..02e369f80449a2d222375349aa4937623f2ac9e7 100644 (file)
@@ -544,13 +544,13 @@ nv50_disp_curs_ofuncs = {
 static void
 nv50_disp_base_vblank_enable(struct nouveau_event *event, int head)
 {
-       nv_mask(event->priv, 0x61002c, (1 << head), (1 << head));
+       nv_mask(event->priv, 0x61002c, (4 << head), (4 << head));
 }
 
 static void
 nv50_disp_base_vblank_disable(struct nouveau_event *event, int head)
 {
-       nv_mask(event->priv, 0x61002c, (1 << head), (0 << head));
+       nv_mask(event->priv, 0x61002c, (4 << head), 0);
 }
 
 static int
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 41241922263fd79641a2486033d933932025524e..3b6dc883e150a4b8d3493cfd6104d7f827967e98 100644 (file)
@@ -116,6 +116,11 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16,
 {
        struct nouveau_abi16_ntfy *ntfy, *temp;
 
+       /* wait for all activity to stop before releasing notify object, which
+        * may be still in use */
+       if (chan->chan && chan->ntfy)
+               nouveau_channel_idle(chan->chan);
+
        /* cleanup notifier state */
        list_for_each_entry_safe(ntfy, temp, &chan->notifiers, head) {
                nouveau_abi16_ntfy_fini(chan, ntfy);
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 11ca82148edcb13505d9c7d06a303ad25053b04b..7ff10711a4d0a437d856df1dafbb0eddf9cee82e 100644 (file)
@@ -801,7 +801,7 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
                stride  = 16 * 4;
                height  = amount / stride;
 
-               if (new_mem->mem_type == TTM_PL_VRAM &&
+               if (old_mem->mem_type == TTM_PL_VRAM &&
                    nouveau_bo_tile_layout(nvbo)) {
                        ret = RING_SPACE(chan, 8);
                        if (ret)
@@ -823,7 +823,7 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
                        BEGIN_NV04(chan, NvSubCopy, 0x0200, 1);
                        OUT_RING  (chan, 1);
                }
-               if (old_mem->mem_type == TTM_PL_VRAM &&
+               if (new_mem->mem_type == TTM_PL_VRAM &&
                    nouveau_bo_tile_layout(nvbo)) {
                        ret = RING_SPACE(chan, 8);
                        if (ret)
index a6237c9cbbc30c5cacfc246733fdbf1c67e68588..2db57990f65c3c7c6a3aca012b30384e36942876 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
@@ -2245,6 +2276,7 @@ nv50_display_create(struct drm_device *dev)
                        NV_WARN(drm, "failed to create encoder %d/%d/%d: %d\n",
                                     dcbe->location, dcbe->type,
                                     ffs(dcbe->or) - 1, ret);
+                       ret = 0;
                }
        }
 
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 41df29f59b0e5dd011f8258c228b14650a174f5f..ebbb9f4f27a3357714f9c654979d73def306c766 100644 (file)
@@ -422,6 +422,7 @@ static struct attribute *pem_input_attributes[] = {
        &sensor_dev_attr_in2_input.dev_attr.attr,
        &sensor_dev_attr_curr1_input.dev_attr.attr,
        &sensor_dev_attr_power1_input.dev_attr.attr,
+       NULL
 };
 
 static const struct attribute_group pem_input_group = {
@@ -432,6 +433,7 @@ static struct attribute *pem_fan_attributes[] = {
        &sensor_dev_attr_fan1_input.dev_attr.attr,
        &sensor_dev_attr_fan2_input.dev_attr.attr,
        &sensor_dev_attr_fan3_input.dev_attr.attr,
+       NULL
 };
 
 static const struct attribute_group pem_fan_group = {
index 9652a2c92a24ddfa00d4100584093da96b6821fe..6d6130752f942380b6fe475504c9a2f75b422f44 100644 (file)
@@ -59,10 +59,10 @@ enum chips { ltc2978, ltc3880 };
 struct ltc2978_data {
        enum chips id;
        int vin_min, vin_max;
-       int temp_min, temp_max;
+       int temp_min, temp_max[2];
        int vout_min[8], vout_max[8];
        int iout_max[2];
-       int temp2_max[2];
+       int temp2_max;
        struct pmbus_driver_info info;
 };
 
@@ -113,9 +113,10 @@ static int ltc2978_read_word_data_common(struct i2c_client *client, int page,
                ret = pmbus_read_word_data(client, page,
                                           LTC2978_MFR_TEMPERATURE_PEAK);
                if (ret >= 0) {
-                       if (lin11_to_val(ret) > lin11_to_val(data->temp_max))
-                               data->temp_max = ret;
-                       ret = data->temp_max;
+                       if (lin11_to_val(ret)
+                           > lin11_to_val(data->temp_max[page]))
+                               data->temp_max[page] = ret;
+                       ret = data->temp_max[page];
                }
                break;
        case PMBUS_VIRT_RESET_VOUT_HISTORY:
@@ -204,10 +205,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 +248,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 +262,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[page] = 0x7c00;
                ret = ltc2978_clear_peaks(client, page, data->id);
                break;
        default:
@@ -321,12 +321,14 @@ 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;
+       for (i = 0; i < ARRAY_SIZE(data->temp_max); i++)
+               data->temp_max[i] = 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 +338,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 +353,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 80eef50c50fd27f9022f3f3176ff6434ad945867..9add60920ac00ed5aa70ca0e1113887836e0ae7d 100644 (file)
@@ -766,12 +766,14 @@ static ssize_t pmbus_show_label(struct device *dev,
 static int pmbus_add_attribute(struct pmbus_data *data, struct attribute *attr)
 {
        if (data->num_attributes >= data->max_attributes - 1) {
-               data->max_attributes += PMBUS_ATTR_ALLOC_SIZE;
-               data->group.attrs = krealloc(data->group.attrs,
-                                            sizeof(struct attribute *) *
-                                            data->max_attributes, GFP_KERNEL);
-               if (data->group.attrs == NULL)
+               int new_max_attrs = data->max_attributes + PMBUS_ATTR_ALLOC_SIZE;
+               void *new_attrs = krealloc(data->group.attrs,
+                                          new_max_attrs * sizeof(void *),
+                                          GFP_KERNEL);
+               if (!new_attrs)
                        return -ENOMEM;
+               data->group.attrs = new_attrs;
+               data->max_attributes = new_max_attrs;
        }
 
        data->group.attrs[data->num_attributes++] = attr;
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 0198324a8b0cf87c5f6b1f84f31b0b8f7b9070eb..bd33473f8e38afd4deeeb243f12c2bf981587740 100644 (file)
@@ -62,7 +62,7 @@ st_sensors_match_odr_error:
 int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr)
 {
        int err;
-       struct st_sensor_odr_avl odr_out;
+       struct st_sensor_odr_avl odr_out = {0, 0};
        struct st_sensor_data *sdata = iio_priv(indio_dev);
 
        err = st_sensors_match_odr(sdata->sensor, odr, &odr_out);
@@ -114,7 +114,7 @@ st_sensors_match_odr_error:
 
 static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs)
 {
-       int err, i;
+       int err, i = 0;
        struct st_sensor_data *sdata = iio_priv(indio_dev);
 
        err = st_sensors_match_fs(sdata->sensor, fs, &i);
@@ -139,14 +139,13 @@ st_accel_set_fullscale_error:
 
 int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable)
 {
-       bool found;
        u8 tmp_value;
        int err = -EINVAL;
-       struct st_sensor_odr_avl odr_out;
+       bool found = false;
+       struct st_sensor_odr_avl odr_out = {0, 0};
        struct st_sensor_data *sdata = iio_priv(indio_dev);
 
        if (enable) {
-               found = false;
                tmp_value = sdata->sensor->pw.value_on;
                if ((sdata->sensor->odr.addr == sdata->sensor->pw.addr) &&
                        (sdata->sensor->odr.mask == sdata->sensor->pw.mask)) {
index 2fe1d4edcb2f2b93fdc21b30fdb777d9d4bc923b..74f2d52795f6e6c44fe49025b49adbe13f33fc39 100644 (file)
@@ -27,7 +27,6 @@
 #define AD5064_ADDR(x)                         ((x) << 20)
 #define AD5064_CMD(x)                          ((x) << 24)
 
-#define AD5064_ADDR_DAC(chan)                  (chan)
 #define AD5064_ADDR_ALL_DAC                    0xF
 
 #define AD5064_CMD_WRITE_INPUT_N               0x0
@@ -131,15 +130,15 @@ static int ad5064_write(struct ad5064_state *st, unsigned int cmd,
 }
 
 static int ad5064_sync_powerdown_mode(struct ad5064_state *st,
-       unsigned int channel)
+       const struct iio_chan_spec *chan)
 {
        unsigned int val;
        int ret;
 
-       val = (0x1 << channel);
+       val = (0x1 << chan->address);
 
-       if (st->pwr_down[channel])
-               val |= st->pwr_down_mode[channel] << 8;
+       if (st->pwr_down[chan->channel])
+               val |= st->pwr_down_mode[chan->channel] << 8;
 
        ret = ad5064_write(st, AD5064_CMD_POWERDOWN_DAC, 0, val, 0);
 
@@ -169,7 +168,7 @@ static int ad5064_set_powerdown_mode(struct iio_dev *indio_dev,
        mutex_lock(&indio_dev->mlock);
        st->pwr_down_mode[chan->channel] = mode + 1;
 
-       ret = ad5064_sync_powerdown_mode(st, chan->channel);
+       ret = ad5064_sync_powerdown_mode(st, chan);
        mutex_unlock(&indio_dev->mlock);
 
        return ret;
@@ -205,7 +204,7 @@ static ssize_t ad5064_write_dac_powerdown(struct iio_dev *indio_dev,
        mutex_lock(&indio_dev->mlock);
        st->pwr_down[chan->channel] = pwr_down;
 
-       ret = ad5064_sync_powerdown_mode(st, chan->channel);
+       ret = ad5064_sync_powerdown_mode(st, chan);
        mutex_unlock(&indio_dev->mlock);
        return ret ? ret : len;
 }
@@ -258,7 +257,7 @@ static int ad5064_write_raw(struct iio_dev *indio_dev,
 
        switch (mask) {
        case IIO_CHAN_INFO_RAW:
-               if (val > (1 << chan->scan_type.realbits) || val < 0)
+               if (val >= (1 << chan->scan_type.realbits) || val < 0)
                        return -EINVAL;
 
                mutex_lock(&indio_dev->mlock);
@@ -292,34 +291,44 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info[] = {
        { },
 };
 
-#define AD5064_CHANNEL(chan, bits) {                           \
+#define AD5064_CHANNEL(chan, addr, bits) {                     \
        .type = IIO_VOLTAGE,                                    \
        .indexed = 1,                                           \
        .output = 1,                                            \
        .channel = (chan),                                      \
        .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT |           \
        IIO_CHAN_INFO_SCALE_SEPARATE_BIT,                       \
-       .address = AD5064_ADDR_DAC(chan),                       \
+       .address = addr,                                        \
        .scan_type = IIO_ST('u', (bits), 16, 20 - (bits)),      \
        .ext_info = ad5064_ext_info,                            \
 }
 
 #define DECLARE_AD5064_CHANNELS(name, bits) \
 const struct iio_chan_spec name[] = { \
-       AD5064_CHANNEL(0, bits), \
-       AD5064_CHANNEL(1, bits), \
-       AD5064_CHANNEL(2, bits), \
-       AD5064_CHANNEL(3, bits), \
-       AD5064_CHANNEL(4, bits), \
-       AD5064_CHANNEL(5, bits), \
-       AD5064_CHANNEL(6, bits), \
-       AD5064_CHANNEL(7, bits), \
+       AD5064_CHANNEL(0, 0, bits), \
+       AD5064_CHANNEL(1, 1, bits), \
+       AD5064_CHANNEL(2, 2, bits), \
+       AD5064_CHANNEL(3, 3, bits), \
+       AD5064_CHANNEL(4, 4, bits), \
+       AD5064_CHANNEL(5, 5, bits), \
+       AD5064_CHANNEL(6, 6, bits), \
+       AD5064_CHANNEL(7, 7, bits), \
+}
+
+#define DECLARE_AD5065_CHANNELS(name, bits) \
+const struct iio_chan_spec name[] = { \
+       AD5064_CHANNEL(0, 0, bits), \
+       AD5064_CHANNEL(1, 3, bits), \
 }
 
 static DECLARE_AD5064_CHANNELS(ad5024_channels, 12);
 static DECLARE_AD5064_CHANNELS(ad5044_channels, 14);
 static DECLARE_AD5064_CHANNELS(ad5064_channels, 16);
 
+static DECLARE_AD5065_CHANNELS(ad5025_channels, 12);
+static DECLARE_AD5065_CHANNELS(ad5045_channels, 14);
+static DECLARE_AD5065_CHANNELS(ad5065_channels, 16);
+
 static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
        [ID_AD5024] = {
                .shared_vref = false,
@@ -328,7 +337,7 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
        },
        [ID_AD5025] = {
                .shared_vref = false,
-               .channels = ad5024_channels,
+               .channels = ad5025_channels,
                .num_channels = 2,
        },
        [ID_AD5044] = {
@@ -338,7 +347,7 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
        },
        [ID_AD5045] = {
                .shared_vref = false,
-               .channels = ad5044_channels,
+               .channels = ad5045_channels,
                .num_channels = 2,
        },
        [ID_AD5064] = {
@@ -353,7 +362,7 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = {
        },
        [ID_AD5065] = {
                .shared_vref = false,
-               .channels = ad5064_channels,
+               .channels = ad5065_channels,
                .num_channels = 2,
        },
        [ID_AD5628_1] = {
@@ -429,6 +438,7 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
 {
        struct iio_dev *indio_dev;
        struct ad5064_state *st;
+       unsigned int midscale;
        unsigned int i;
        int ret;
 
@@ -465,11 +475,6 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
                        goto error_free_reg;
        }
 
-       for (i = 0; i < st->chip_info->num_channels; ++i) {
-               st->pwr_down_mode[i] = AD5064_LDAC_PWRDN_1K;
-               st->dac_cache[i] = 0x8000;
-       }
-
        indio_dev->dev.parent = dev;
        indio_dev->name = name;
        indio_dev->info = &ad5064_info;
@@ -477,6 +482,13 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
        indio_dev->channels = st->chip_info->channels;
        indio_dev->num_channels = st->chip_info->num_channels;
 
+       midscale = (1 << indio_dev->channels[0].scan_type.realbits) /  2;
+
+       for (i = 0; i < st->chip_info->num_channels; ++i) {
+               st->pwr_down_mode[i] = AD5064_LDAC_PWRDN_1K;
+               st->dac_cache[i] = midscale;
+       }
+
        ret = iio_device_register(indio_dev);
        if (ret)
                goto error_disable_reg;
index b5cfa3a354cfe5e98ad9dd7b664adbaff10a00f9..361b2328453d478cd5ba945e91b9c242310b6119 100644 (file)
@@ -5,6 +5,7 @@
 config INV_MPU6050_IIO
        tristate "Invensense MPU6050 devices"
        depends on I2C && SYSFS
+       select IIO_BUFFER
        select IIO_TRIGGERED_BUFFER
        help
          This driver supports the Invensense MPU6050 devices.
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 e0d79b2395e4f859f51c51e9c314f9306834f123..add98d01476c1307629bd813d341bac6d34c9a76 100644 (file)
@@ -362,7 +362,6 @@ void mlx4_ib_cm_paravirt_init(struct mlx4_ib_dev *dev)
        INIT_LIST_HEAD(&dev->sriov.cm_list);
        dev->sriov.sl_id_map = RB_ROOT;
        idr_init(&dev->sriov.pv_id_table);
-       idr_pre_get(&dev->sriov.pv_id_table, GFP_KERNEL);
 }
 
 /* slave = -1 ==> all slaves */
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 2fb0d76a04c4f06d072a45765349406c2d2810f7..208de7cbb7fae2460dac5576c69f5847165ac3c9 100644 (file)
@@ -70,8 +70,6 @@
 #define TC3589x_EVT_INT_CLR    0x2
 #define TC3589x_KBD_INT_CLR    0x1
 
-#define TC3589x_KBD_KEYMAP_SIZE     64
-
 /**
  * struct tc_keypad - data structure used by keypad driver
  * @tc3589x:    pointer to tc35893
@@ -88,7 +86,7 @@ struct tc_keypad {
        const struct tc3589x_keypad_platform_data *board;
        unsigned int krow;
        unsigned int kcol;
-       unsigned short keymap[TC3589x_KBD_KEYMAP_SIZE];
+       unsigned short *keymap;
        bool keypad_stopped;
 };
 
@@ -338,12 +336,14 @@ static int tc3589x_keypad_probe(struct platform_device *pdev)
 
        error = matrix_keypad_build_keymap(plat->keymap_data, NULL,
                                           TC3589x_MAX_KPROW, TC3589x_MAX_KPCOL,
-                                          keypad->keymap, input);
+                                          NULL, input);
        if (error) {
                dev_err(&pdev->dev, "Failed to build keymap\n");
                goto err_free_mem;
        }
 
+       keypad->keymap = input->keycode;
+
        input_set_capability(input, EV_MSC, MSC_SCAN);
        if (!plat->no_autorepeat)
                __set_bit(EV_REP, input->evbit);
index 7b99fc7c9438dbcbcc115248403e4b9704611f29..0238e0e143350a3254e07bf0f73e035e2b3cef57 100644 (file)
@@ -490,6 +490,29 @@ static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p)
        f->y_map |= (p[5] & 0x20) << 6;
 }
 
+static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p)
+{
+       f->first_mp = !!(p[0] & 0x02);
+       f->is_mp = !!(p[0] & 0x20);
+
+       f->fingers = ((p[0] & 0x6) >> 1 |
+                    (p[0] & 0x10) >> 2);
+       f->x_map = ((p[2] & 0x60) >> 5) |
+                  ((p[4] & 0x7f) << 2) |
+                  ((p[5] & 0x7f) << 9) |
+                  ((p[3] & 0x07) << 16) |
+                  ((p[3] & 0x70) << 15) |
+                  ((p[0] & 0x01) << 22);
+       f->y_map = (p[1] & 0x7f) |
+                  ((p[2] & 0x1f) << 7);
+
+       f->x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7));
+       f->y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3));
+       f->z = (p[0] & 4) ? 0 : p[5] & 0x7f;
+
+       alps_decode_buttons_v3(f, p);
+}
+
 static void alps_process_touchpad_packet_v3(struct psmouse *psmouse)
 {
        struct alps_data *priv = psmouse->private;
@@ -874,7 +897,8 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse)
        }
 
        /* Bytes 2 - pktsize should have 0 in the highest bit */
-       if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
+       if (priv->proto_version != ALPS_PROTO_V5 &&
+           psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize &&
            (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) {
                psmouse_dbg(psmouse, "refusing packet[%i] = %x\n",
                            psmouse->pktcnt - 1,
@@ -994,8 +1018,7 @@ static int alps_rpt_cmd(struct psmouse *psmouse, int init_command,
        return 0;
 }
 
-static int alps_enter_command_mode(struct psmouse *psmouse,
-                                  unsigned char *resp)
+static int alps_enter_command_mode(struct psmouse *psmouse)
 {
        unsigned char param[4];
 
@@ -1004,14 +1027,12 @@ static int alps_enter_command_mode(struct psmouse *psmouse,
                return -1;
        }
 
-       if (param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) {
+       if ((param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) &&
+           param[0] != 0x73) {
                psmouse_dbg(psmouse,
                            "unknown response while entering command mode\n");
                return -1;
        }
-
-       if (resp)
-               *resp = param[2];
        return 0;
 }
 
@@ -1176,7 +1197,7 @@ static int alps_passthrough_mode_v3(struct psmouse *psmouse,
 {
        int reg_val, ret = -1;
 
-       if (alps_enter_command_mode(psmouse, NULL))
+       if (alps_enter_command_mode(psmouse))
                return -1;
 
        reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x0008);
@@ -1216,7 +1237,7 @@ static int alps_probe_trackstick_v3(struct psmouse *psmouse, int reg_base)
 {
        int ret = -EIO, reg_val;
 
-       if (alps_enter_command_mode(psmouse, NULL))
+       if (alps_enter_command_mode(psmouse))
                goto error;
 
        reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x08);
@@ -1279,7 +1300,7 @@ static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base)
                 * supported by this driver. If bit 1 isn't set the packet
                 * format is different.
                 */
-               if (alps_enter_command_mode(psmouse, NULL) ||
+               if (alps_enter_command_mode(psmouse) ||
                    alps_command_mode_write_reg(psmouse,
                                                reg_base + 0x08, 0x82) ||
                    alps_exit_command_mode(psmouse))
@@ -1306,7 +1327,7 @@ static int alps_hw_init_v3(struct psmouse *psmouse)
            alps_setup_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE) == -EIO)
                goto error;
 
-       if (alps_enter_command_mode(psmouse, NULL) ||
+       if (alps_enter_command_mode(psmouse) ||
            alps_absolute_mode_v3(psmouse)) {
                psmouse_err(psmouse, "Failed to enter absolute mode\n");
                goto error;
@@ -1381,7 +1402,7 @@ static int alps_hw_init_rushmore_v3(struct psmouse *psmouse)
                        priv->flags &= ~ALPS_DUALPOINT;
        }
 
-       if (alps_enter_command_mode(psmouse, NULL) ||
+       if (alps_enter_command_mode(psmouse) ||
            alps_command_mode_read_reg(psmouse, 0xc2d9) == -1 ||
            alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00))
                goto error;
@@ -1431,7 +1452,7 @@ static int alps_hw_init_v4(struct psmouse *psmouse)
        struct ps2dev *ps2dev = &psmouse->ps2dev;
        unsigned char param[4];
 
-       if (alps_enter_command_mode(psmouse, NULL))
+       if (alps_enter_command_mode(psmouse))
                goto error;
 
        if (alps_absolute_mode_v4(psmouse)) {
@@ -1499,6 +1520,23 @@ error:
        return -1;
 }
 
+static int alps_hw_init_dolphin_v1(struct psmouse *psmouse)
+{
+       struct ps2dev *ps2dev = &psmouse->ps2dev;
+       unsigned char param[2];
+
+       /* This is dolphin "v1" as empirically defined by florin9doi */
+       param[0] = 0x64;
+       param[1] = 0x28;
+
+       if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) ||
+           ps2_command(ps2dev, &param[0], PSMOUSE_CMD_SETRATE) ||
+           ps2_command(ps2dev, &param[1], PSMOUSE_CMD_SETRATE))
+               return -1;
+
+       return 0;
+}
+
 static void alps_set_defaults(struct alps_data *priv)
 {
        priv->byte0 = 0x8f;
@@ -1532,6 +1570,21 @@ static void alps_set_defaults(struct alps_data *priv)
                priv->nibble_commands = alps_v4_nibble_commands;
                priv->addr_command = PSMOUSE_CMD_DISABLE;
                break;
+       case ALPS_PROTO_V5:
+               priv->hw_init = alps_hw_init_dolphin_v1;
+               priv->process_packet = alps_process_packet_v3;
+               priv->decode_fields = alps_decode_dolphin;
+               priv->set_abs_params = alps_set_abs_params_mt;
+               priv->nibble_commands = alps_v3_nibble_commands;
+               priv->addr_command = PSMOUSE_CMD_RESET_WRAP;
+               priv->byte0 = 0xc8;
+               priv->mask0 = 0xc8;
+               priv->flags = 0;
+               priv->x_max = 1360;
+               priv->y_max = 660;
+               priv->x_bits = 23;
+               priv->y_bits = 12;
+               break;
        }
 }
 
@@ -1591,6 +1644,12 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
                return -EIO;
 
        if (alps_match_table(psmouse, priv, e7, ec) == 0) {
+               return 0;
+       } else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 &&
+                  ec[0] == 0x73 && ec[1] == 0x01) {
+               priv->proto_version = ALPS_PROTO_V5;
+               alps_set_defaults(priv);
+
                return 0;
        } else if (ec[0] == 0x88 && ec[1] == 0x08) {
                priv->proto_version = ALPS_PROTO_V3;
index 970480551b6e67e540fdb76b2865e8dd573d550a..eee59853b9ce0c21bc755c206430911e15789964 100644 (file)
@@ -16,6 +16,7 @@
 #define ALPS_PROTO_V2  2
 #define ALPS_PROTO_V3  3
 #define ALPS_PROTO_V4  4
+#define ALPS_PROTO_V5  5
 
 /**
  * struct alps_model_info - touchpad ID table
index 1673dc6c8092b9697e95d2c5dc4beeffa92852f6..f51765fff0545e91be567942255cf19532f94a71 100644 (file)
@@ -236,6 +236,13 @@ static int cypress_read_fw_version(struct psmouse *psmouse)
        cytp->fw_version = param[2] & FW_VERSION_MASX;
        cytp->tp_metrics_supported = (param[2] & TP_METRICS_MASK) ? 1 : 0;
 
+       /*
+        * Trackpad fw_version 11 (in Dell XPS12) yields a bogus response to
+        * CYTP_CMD_READ_TP_METRICS so do not try to use it. LP: #1103594.
+        */
+       if (cytp->fw_version >= 11)
+               cytp->tp_metrics_supported = 0;
+
        psmouse_dbg(psmouse, "cytp->fw_version = %d\n", cytp->fw_version);
        psmouse_dbg(psmouse, "cytp->tp_metrics_supported = %d\n",
                 cytp->tp_metrics_supported);
@@ -258,6 +265,9 @@ static int cypress_read_tp_metrics(struct psmouse *psmouse)
        cytp->tp_res_x = cytp->tp_max_abs_x / cytp->tp_width;
        cytp->tp_res_y = cytp->tp_max_abs_y / cytp->tp_high;
 
+       if (!cytp->tp_metrics_supported)
+               return 0;
+
        memset(param, 0, sizeof(param));
        if (cypress_send_ext_cmd(psmouse, CYTP_CMD_READ_TP_METRICS, param) == 0) {
                /* Update trackpad parameters. */
@@ -315,18 +325,15 @@ static int cypress_read_tp_metrics(struct psmouse *psmouse)
 
 static int cypress_query_hardware(struct psmouse *psmouse)
 {
-       struct cytp_data *cytp = psmouse->private;
        int ret;
 
        ret = cypress_read_fw_version(psmouse);
        if (ret)
                return ret;
 
-       if (cytp->tp_metrics_supported) {
-               ret = cypress_read_tp_metrics(psmouse);
-               if (ret)
-                       return ret;
-       }
+       ret = cypress_read_tp_metrics(psmouse);
+       if (ret)
+               return ret;
 
        return 0;
 }
index 41b6fbf601122b26500c397d24e34f9789286f81..1daa97913b7d20068845865a405387404fffe1d8 100644 (file)
@@ -2017,6 +2017,9 @@ static const struct wacom_features wacom_features_0x100 =
 static const struct wacom_features wacom_features_0x101 =
        { "Wacom ISDv4 101",      WACOM_PKGLEN_MTTPC,     26202, 16325,  255,
          0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
+static const struct wacom_features wacom_features_0x10D =
+       { "Wacom ISDv4 10D",      WACOM_PKGLEN_MTTPC,     26202, 16325,  255,
+         0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
 static const struct wacom_features wacom_features_0x4001 =
        { "Wacom ISDv4 4001",      WACOM_PKGLEN_MTTPC,     26202, 16325,  255,
          0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
@@ -2201,6 +2204,7 @@ const struct usb_device_id wacom_ids[] = {
        { USB_DEVICE_WACOM(0xEF) },
        { USB_DEVICE_WACOM(0x100) },
        { USB_DEVICE_WACOM(0x101) },
+       { USB_DEVICE_WACOM(0x10D) },
        { USB_DEVICE_WACOM(0x4001) },
        { USB_DEVICE_WACOM(0x47) },
        { USB_DEVICE_WACOM(0xF4) },
index 4f702b3ec1a3f1f9e4210d4e666c5be1beea8801..434c3df250caa3bc0a058a890e6b64f9bd78b450 100644 (file)
@@ -236,7 +236,12 @@ static void __ads7846_disable(struct ads7846 *ts)
 /* Must be called with ts->lock held */
 static void __ads7846_enable(struct ads7846 *ts)
 {
-       regulator_enable(ts->reg);
+       int error;
+
+       error = regulator_enable(ts->reg);
+       if (error != 0)
+               dev_err(&ts->spi->dev, "Failed to enable supply: %d\n", error);
+
        ads7846_restart(ts);
 }
 
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 4a29ddf6bf1e9a9bfed9a1afcc8cba810e66800c..1443532fe6c4d112f15a317d598ddc4f4dc78fb5 100644 (file)
@@ -314,15 +314,27 @@ static int mms114_start(struct mms114_data *data)
        struct i2c_client *client = data->client;
        int error;
 
-       if (data->core_reg)
-               regulator_enable(data->core_reg);
-       if (data->io_reg)
-               regulator_enable(data->io_reg);
+       error = regulator_enable(data->core_reg);
+       if (error) {
+               dev_err(&client->dev, "Failed to enable avdd: %d\n", error);
+               return error;
+       }
+
+       error = regulator_enable(data->io_reg);
+       if (error) {
+               dev_err(&client->dev, "Failed to enable vdd: %d\n", error);
+               regulator_disable(data->core_reg);
+               return error;
+       }
+
        mdelay(MMS114_POWERON_DELAY);
 
        error = mms114_setup_regs(data);
-       if (error < 0)
+       if (error < 0) {
+               regulator_disable(data->io_reg);
+               regulator_disable(data->core_reg);
                return error;
+       }
 
        if (data->pdata->cfg_pin)
                data->pdata->cfg_pin(true);
@@ -335,16 +347,20 @@ static int mms114_start(struct mms114_data *data)
 static void mms114_stop(struct mms114_data *data)
 {
        struct i2c_client *client = data->client;
+       int error;
 
        disable_irq(client->irq);
 
        if (data->pdata->cfg_pin)
                data->pdata->cfg_pin(false);
 
-       if (data->io_reg)
-               regulator_disable(data->io_reg);
-       if (data->core_reg)
-               regulator_disable(data->core_reg);
+       error = regulator_disable(data->io_reg);
+       if (error)
+               dev_warn(&client->dev, "Failed to disable vdd: %d\n", error);
+
+       error = regulator_disable(data->core_reg);
+       if (error)
+               dev_warn(&client->dev, "Failed to disable avdd: %d\n", error);
 }
 
 static int mms114_input_open(struct input_dev *dev)
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 644d724684232d9b389fcc056f78aaab1e155817..a32e0d5aa45f43eb71c91ab9020696436212ae95 100644 (file)
@@ -648,7 +648,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
 
        /* Convert our logical CPU mask into a physical one. */
        for_each_cpu(cpu, mask)
-               map |= 1 << cpu_logical_map(cpu);
+               map |= gic_cpu_map[cpu];
 
        /*
         * Ensure that stores to Normal memory are visible to the
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 d8a7d832341436ce62e1dfaacc6b6578ab79e224..ebaebdf30f98dce768d187a7e471ab6455604bd3 100644 (file)
@@ -902,7 +902,9 @@ isdn_tty_send_msg(modem_info *info, atemu *m, char *msg)
        int j;
        int l;
 
-       l = strlen(msg);
+       l = min(strlen(msg), sizeof(cmd.parm) - sizeof(cmd.parm.cmsg)
+               + sizeof(cmd.parm.cmsg.para) - 2);
+
        if (!l) {
                isdn_tty_modem_result(RESULT_ERROR, info);
                return;
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 671f5b171c737d78c9659d2afe3a68e02fd3981f..c346941a251593bbe42bd8f3d3171acc6a93c2cf 100644 (file)
@@ -858,6 +858,7 @@ config EZX_PCAP
 config AB8500_CORE
        bool "ST-Ericsson AB8500 Mixed Signal Power Management chip"
        depends on GENERIC_HARDIRQS && ABX500_CORE && MFD_DB8500_PRCMU
+       select POWER_SUPPLY
        select MFD_CORE
        select IRQ_DOMAIN
        help
index b1f3561b023f0aaa4939bc469e3c0a40a718d0db..5f341a50ee5a5783e6e84118124e9efcfe177bd3 100644 (file)
@@ -594,9 +594,12 @@ static int ab8500_gpadc_runtime_suspend(struct device *dev)
 static int ab8500_gpadc_runtime_resume(struct device *dev)
 {
        struct ab8500_gpadc *gpadc = dev_get_drvdata(dev);
+       int ret;
 
-       regulator_enable(gpadc->regu);
-       return 0;
+       ret = regulator_enable(gpadc->regu);
+       if (ret)
+               dev_err(dev, "Failed to enable vtvout LDO: %d\n", ret);
+       return ret;
 }
 
 static int ab8500_gpadc_runtime_idle(struct device *dev)
@@ -643,7 +646,7 @@ static int ab8500_gpadc_probe(struct platform_device *pdev)
        }
 
        /* VTVout LDO used to power up ab8500-GPADC */
-       gpadc->regu = regulator_get(&pdev->dev, "vddadc");
+       gpadc->regu = devm_regulator_get(&pdev->dev, "vddadc");
        if (IS_ERR(gpadc->regu)) {
                ret = PTR_ERR(gpadc->regu);
                dev_err(gpadc->dev, "failed to get vtvout LDO\n");
@@ -652,7 +655,11 @@ static int ab8500_gpadc_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, gpadc);
 
-       regulator_enable(gpadc->regu);
+       ret = regulator_enable(gpadc->regu);
+       if (ret) {
+               dev_err(gpadc->dev, "Failed to enable vtvout LDO: %d\n", ret);
+               goto fail_enable;
+       }
 
        pm_runtime_set_autosuspend_delay(gpadc->dev, GPADC_AUDOSUSPEND_DELAY);
        pm_runtime_use_autosuspend(gpadc->dev);
@@ -663,6 +670,8 @@ static int ab8500_gpadc_probe(struct platform_device *pdev)
        list_add_tail(&gpadc->node, &ab8500_gpadc_list);
        dev_dbg(gpadc->dev, "probe success\n");
        return 0;
+
+fail_enable:
 fail_irq:
        free_irq(gpadc->irq, gpadc);
 fail:
index 6b5edf64de2b3a4eafbdc0ace93a5a4bd2d4caea..4febc5c7fdeece4a87be9c2dca0eb642357d4cc7 100644 (file)
@@ -460,15 +460,15 @@ static void omap_usbhs_init(struct device *dev)
 
        switch (omap->usbhs_rev) {
        case OMAP_USBHS_REV1:
-               omap_usbhs_rev1_hostconfig(omap, reg);
+               reg = omap_usbhs_rev1_hostconfig(omap, reg);
                break;
 
        case OMAP_USBHS_REV2:
-               omap_usbhs_rev2_hostconfig(omap, reg);
+               reg = omap_usbhs_rev2_hostconfig(omap, reg);
                break;
 
        default:        /* newer revisions */
-               omap_usbhs_rev2_hostconfig(omap, reg);
+               reg = omap_usbhs_rev2_hostconfig(omap, reg);
                break;
        }
 
index bbdbc50a3ccadb7ec98d5d6cd6176c36b9d85a50..73bf76df1044cc70b04bc383d2ad7ec9384a7fcc 100644 (file)
@@ -257,9 +257,24 @@ static struct regmap_irq_chip palmas_irq_chip = {
                        PALMAS_INT1_MASK),
 };
 
-static void palmas_dt_to_pdata(struct device_node *node,
+static int palmas_set_pdata_irq_flag(struct i2c_client *i2c,
                struct palmas_platform_data *pdata)
 {
+       struct irq_data *irq_data = irq_get_irq_data(i2c->irq);
+       if (!irq_data) {
+               dev_err(&i2c->dev, "Invalid IRQ: %d\n", i2c->irq);
+               return -EINVAL;
+       }
+
+       pdata->irq_flags = irqd_get_trigger_type(irq_data);
+       dev_info(&i2c->dev, "Irq flag is 0x%08x\n", pdata->irq_flags);
+       return 0;
+}
+
+static void palmas_dt_to_pdata(struct i2c_client *i2c,
+               struct palmas_platform_data *pdata)
+{
+       struct device_node *node = i2c->dev.of_node;
        int ret;
        u32 prop;
 
@@ -283,6 +298,8 @@ static void palmas_dt_to_pdata(struct device_node *node,
                pdata->power_ctrl = PALMAS_POWER_CTRL_NSLEEP_MASK |
                                        PALMAS_POWER_CTRL_ENABLE1_MASK |
                                        PALMAS_POWER_CTRL_ENABLE2_MASK;
+       if (i2c->irq)
+               palmas_set_pdata_irq_flag(i2c, pdata);
 }
 
 static int palmas_i2c_probe(struct i2c_client *i2c,
@@ -304,7 +321,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
                if (!pdata)
                        return -ENOMEM;
 
-               palmas_dt_to_pdata(node, pdata);
+               palmas_dt_to_pdata(i2c, pdata);
        }
 
        if (!pdata)
@@ -344,6 +361,19 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
                }
        }
 
+       /* Change interrupt line output polarity */
+       if (pdata->irq_flags & IRQ_TYPE_LEVEL_HIGH)
+               reg = PALMAS_POLARITY_CTRL_INT_POLARITY;
+       else
+               reg = 0;
+       ret = palmas_update_bits(palmas, PALMAS_PU_PD_OD_BASE,
+                       PALMAS_POLARITY_CTRL, PALMAS_POLARITY_CTRL_INT_POLARITY,
+                       reg);
+       if (ret < 0) {
+               dev_err(palmas->dev, "POLARITY_CTRL updat failed: %d\n", ret);
+               goto err;
+       }
+
        /* Change IRQ into clear on read mode for efficiency */
        slave = PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE);
        addr = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL);
@@ -352,7 +382,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
        regmap_write(palmas->regmap[slave], addr, reg);
 
        ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq,
-                       IRQF_ONESHOT | IRQF_TRIGGER_LOW, 0, &palmas_irq_chip,
+                       IRQF_ONESHOT | pdata->irq_flags, 0, &palmas_irq_chip,
                        &palmas->irq_data);
        if (ret < 0)
                goto err;
index 4658b5bdcd84488d3379a2ef4f33e334eb96ea2f..aeb8e40ab4249ac2acdbdb43d7149ca8ca5efde4 100644 (file)
@@ -169,6 +169,7 @@ err:
 void tps65912_device_exit(struct tps65912 *tps65912)
 {
        mfd_remove_devices(tps65912->dev);
+       tps65912_irq_exit(tps65912);
        kfree(tps65912);
 }
 
index e16edca926709bbe501d52dc5fb37f578e9710a4..d2ab222138c29eb24ed8d62247928dda7127b31d 100644 (file)
@@ -118,7 +118,7 @@ EXPORT_SYMBOL_GPL(twl4030_audio_enable_resource);
  * Disable the resource.
  * The function returns with error or the content of the register
  */
-int twl4030_audio_disable_resource(unsigned id)
+int twl4030_audio_disable_resource(enum twl4030_audio_res id)
 {
        struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev);
        int val;
index 88ff9dc83305e2d2a644c6c049abb35439c2b5ad..942b666a2a07b20ad02f97b864500db0259b8669 100644 (file)
@@ -800,7 +800,7 @@ static int twl4030_madc_remove(struct platform_device *pdev)
 
 static struct platform_driver twl4030_madc_driver = {
        .probe = twl4030_madc_probe,
-       .remove = __exit_p(twl4030_madc_remove),
+       .remove = twl4030_madc_remove,
        .driver = {
                   .name = "twl4030_madc",
                   .owner = THIS_MODULE,
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..8b4e96e01d6ce15def39381bcbc0a6b996d7bb85 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);
@@ -1964,7 +1964,6 @@ static int __bond_release_one(struct net_device *bond_dev,
        }
 
        block_netpoll_tx();
-       call_netdevice_notifiers(NETDEV_RELEASE, bond_dev);
        write_lock_bh(&bond->lock);
 
        slave = bond_get_slave_by_dev(bond, slave_dev);
@@ -2066,8 +2065,10 @@ static int __bond_release_one(struct net_device *bond_dev,
        write_unlock_bh(&bond->lock);
        unblock_netpoll_tx();
 
-       if (bond->slave_cnt == 0)
+       if (bond->slave_cnt == 0) {
                call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev);
+               call_netdevice_notifiers(NETDEV_RELEASE, bond->dev);
+       }
 
        bond_compute_features(bond);
        if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
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..77ebae0ac64aa9a4e681a506129c5a835d85ef4e 100644 (file)
@@ -8647,7 +8647,9 @@ void bnx2x_handle_module_detect_int(struct link_params *params)
                                                MDIO_WC_DEVAD,
                                                MDIO_WC_REG_DIGITAL5_MISC6,
                                                &rx_tx_in_reset);
-                               if (!rx_tx_in_reset) {
+                               if ((!rx_tx_in_reset) &&
+                                   (params->link_flags &
+                                    PHY_INITIALIZED)) {
                                        bnx2x_warpcore_reset_lane(bp, phy, 1);
                                        bnx2x_warpcore_config_sfi(phy, params);
                                        bnx2x_warpcore_reset_lane(bp, phy, 0);
@@ -10422,6 +10424,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 +10492,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 +10578,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 +11853,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 |
@@ -12465,6 +12529,8 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
        vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
        vars->mac_type = MAC_TYPE_NONE;
        vars->phy_flags = 0;
+       vars->check_kr2_recovery_cnt = 0;
+       params->link_flags = PHY_INITIALIZED;
        /* Driver opens NIG-BRB filters */
        bnx2x_set_rx_filter(params, 1);
        /* Check if link flap can be avoided */
@@ -12629,6 +12695,7 @@ int bnx2x_lfa_reset(struct link_params *params,
        struct bnx2x *bp = params->bp;
        vars->link_up = 0;
        vars->phy_flags = 0;
+       params->link_flags &= ~PHY_INITIALIZED;
        if (!params->lfa_base)
                return bnx2x_link_reset(params, vars, 1);
        /*
@@ -13349,6 +13416,7 @@ static void bnx2x_disable_kr2(struct link_params *params,
        vars->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE;
        bnx2x_update_link_attr(params, vars->link_attr_sync);
 
+       vars->check_kr2_recovery_cnt = CHECK_KR2_RECOVERY_CNT;
        /* Restart AN on leading lane */
        bnx2x_warpcore_restart_AN_KR(phy, params);
 }
@@ -13377,6 +13445,15 @@ static void bnx2x_check_kr2_wa(struct link_params *params,
                return;
        }
 
+       /* Once KR2 was disabled, wait 5 seconds before checking KR2 recovery
+        * since some switches tend to reinit the AN process and clear the
+        * advertised BP/NP after ~2 seconds causing the KR2 to be disabled
+        * and recovered many times
+        */
+       if (vars->check_kr2_recovery_cnt > 0) {
+               vars->check_kr2_recovery_cnt--;
+               return;
+       }
        lane = bnx2x_get_warpcore_lane(phy, params);
        CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
                          MDIO_AER_BLOCK_AER_REG, lane);
@@ -13437,7 +13514,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..56c2aae4e2c81b33818d6628cc342e67862d7ebd 100644 (file)
@@ -307,7 +307,9 @@ 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)
+#define PHY_INITIALIZED                (1<<1)
        u32 lfa_base;
 };
 
@@ -341,7 +343,8 @@ struct link_vars {
        u32 link_status;
        u32 eee_status;
        u8 fault_detected;
-       u8 rsrv1;
+       u8 check_kr2_recovery_cnt;
+#define CHECK_KR2_RECOVERY_CNT 5
        u16 periodic_flags;
 #define PERIODIC_FLAGS_LINK_EVENT      0x0001
 
index fdb9b5655414e77dc6506cdda13642ef16115e27..93729f9423588de05fa4d5e25dbcef99438fd17d 100644 (file)
@@ -1869,6 +1869,8 @@ static void tg3_link_report(struct tg3 *tp)
 
                tg3_ump_link_report(tp);
        }
+
+       tp->link_up = netif_carrier_ok(tp->dev);
 }
 
 static u16 tg3_advert_flowctrl_1000X(u8 flow_ctrl)
@@ -2522,12 +2524,6 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
        return err;
 }
 
-static void tg3_carrier_on(struct tg3 *tp)
-{
-       netif_carrier_on(tp->dev);
-       tp->link_up = true;
-}
-
 static void tg3_carrier_off(struct tg3 *tp)
 {
        netif_carrier_off(tp->dev);
@@ -2553,7 +2549,7 @@ static int tg3_phy_reset(struct tg3 *tp)
                return -EBUSY;
 
        if (netif_running(tp->dev) && tp->link_up) {
-               tg3_carrier_off(tp);
+               netif_carrier_off(tp->dev);
                tg3_link_report(tp);
        }
 
@@ -4262,9 +4258,9 @@ static bool tg3_test_and_report_link_chg(struct tg3 *tp, int curr_link_up)
 {
        if (curr_link_up != tp->link_up) {
                if (curr_link_up) {
-                       tg3_carrier_on(tp);
+                       netif_carrier_on(tp->dev);
                } else {
-                       tg3_carrier_off(tp);
+                       netif_carrier_off(tp->dev);
                        if (tp->phy_flags & TG3_PHYFLG_MII_SERDES)
                                tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT;
                }
index 28ceb84141851e26e8d49f1175099235a512d54b..29aff55f2eea414bf8dec52d61bee70a034fc12c 100644 (file)
@@ -349,6 +349,7 @@ struct be_adapter {
        struct pci_dev *pdev;
        struct net_device *netdev;
 
+       u8 __iomem *csr;        /* CSR BAR used only for BE2/3 */
        u8 __iomem *db;         /* Door Bell */
 
        struct mutex mbox_lock; /* For serializing mbox cmds to BE card */
index 071aea79d218f01eb166d910a310ef0f49efa470..3c9b4f12e3e516ff8775c208a3b138c9acd5c109 100644 (file)
@@ -473,19 +473,17 @@ static int be_mbox_notify_wait(struct be_adapter *adapter)
        return 0;
 }
 
-static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage)
+static u16 be_POST_stage_get(struct be_adapter *adapter)
 {
        u32 sem;
-       u32 reg = skyhawk_chip(adapter) ? SLIPORT_SEMAPHORE_OFFSET_SH :
-                                         SLIPORT_SEMAPHORE_OFFSET_BE;
 
-       pci_read_config_dword(adapter->pdev, reg, &sem);
-       *stage = sem & POST_STAGE_MASK;
-
-       if ((sem >> POST_ERR_SHIFT) & POST_ERR_MASK)
-               return -1;
+       if (BEx_chip(adapter))
+               sem  = ioread32(adapter->csr + SLIPORT_SEMAPHORE_OFFSET_BEx);
        else
-               return 0;
+               pci_read_config_dword(adapter->pdev,
+                                     SLIPORT_SEMAPHORE_OFFSET_SH, &sem);
+
+       return sem & POST_STAGE_MASK;
 }
 
 int lancer_wait_ready(struct be_adapter *adapter)
@@ -579,19 +577,17 @@ int be_fw_wait_ready(struct be_adapter *adapter)
        }
 
        do {
-               status = be_POST_stage_get(adapter, &stage);
-               if (status) {
-                       dev_err(dev, "POST error; stage=0x%x\n", stage);
-                       return -1;
-               } else if (stage != POST_STAGE_ARMFW_RDY) {
-                       if (msleep_interruptible(2000)) {
-                               dev_err(dev, "Waiting for POST aborted\n");
-                               return -EINTR;
-                       }
-                       timeout += 2;
-               } else {
+               stage = be_POST_stage_get(adapter);
+               if (stage == POST_STAGE_ARMFW_RDY)
                        return 0;
+
+               dev_info(dev, "Waiting for POST, %ds elapsed\n",
+                        timeout);
+               if (msleep_interruptible(2000)) {
+                       dev_err(dev, "Waiting for POST aborted\n");
+                       return -EINTR;
                }
+               timeout += 2;
        } while (timeout < 60);
 
        dev_err(dev, "POST timeout; stage=0x%x\n", stage);
index 541d4530d5bfadb2d038b3aa4e233a069cf9c94a..62dc220695f724999c8df269531274ba38ec0b4a 100644 (file)
@@ -32,8 +32,8 @@
 #define MPU_EP_CONTROL                 0
 
 /********** MPU semphore: used for SH & BE  *************/
-#define SLIPORT_SEMAPHORE_OFFSET_BE            0x7c
-#define SLIPORT_SEMAPHORE_OFFSET_SH            0x94
+#define SLIPORT_SEMAPHORE_OFFSET_BEx           0xac  /* CSR BAR offset */
+#define SLIPORT_SEMAPHORE_OFFSET_SH            0x94  /* PCI-CFG offset */
 #define POST_STAGE_MASK                                0x0000FFFF
 #define POST_ERR_MASK                          0x1
 #define POST_ERR_SHIFT                         31
index 3860888ac711a7fe7630cad2c06bb3819eb1f3a0..08e54f3d288bc9a2e23faa8bb954dcb4bd8cf584 100644 (file)
@@ -3688,6 +3688,8 @@ static void be_netdev_init(struct net_device *netdev)
 
 static void be_unmap_pci_bars(struct be_adapter *adapter)
 {
+       if (adapter->csr)
+               pci_iounmap(adapter->pdev, adapter->csr);
        if (adapter->db)
                pci_iounmap(adapter->pdev, adapter->db);
 }
@@ -3721,6 +3723,12 @@ static int be_map_pci_bars(struct be_adapter *adapter)
        adapter->if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
                                SLI_INTF_IF_TYPE_SHIFT;
 
+       if (BEx_chip(adapter) && be_physfn(adapter)) {
+               adapter->csr = pci_iomap(adapter->pdev, 2, 0);
+               if (adapter->csr == NULL)
+                       return -ENOMEM;
+       }
+
        addr = pci_iomap(adapter->pdev, db_bar(adapter), 0);
        if (addr == NULL)
                goto pci_map_err;
@@ -4329,6 +4337,8 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
        pci_restore_state(pdev);
 
        /* Check if card is ok and fw is ready */
+       dev_info(&adapter->pdev->dev,
+                "Waiting for FW to be ready after EEH reset\n");
        status = be_fw_wait_ready(adapter);
        if (status)
                return PCI_ERS_RESULT_DISCONNECT;
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 2c1813737f6d2562189065d945a5002750d8e10c..f91a8f3f9d48beff868f0e9e567ec1779273c877 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
 #include <linux/mdio.h>
+#include <linux/pm_runtime.h>
 
 #include "e1000.h"
 
@@ -2229,7 +2230,19 @@ static int e1000e_get_ts_info(struct net_device *netdev,
        return 0;
 }
 
+static int e1000e_ethtool_begin(struct net_device *netdev)
+{
+       return pm_runtime_get_sync(netdev->dev.parent);
+}
+
+static void e1000e_ethtool_complete(struct net_device *netdev)
+{
+       pm_runtime_put_sync(netdev->dev.parent);
+}
+
 static const struct ethtool_ops e1000_ethtool_ops = {
+       .begin                  = e1000e_ethtool_begin,
+       .complete               = e1000e_ethtool_complete,
        .get_settings           = e1000_get_settings,
        .set_settings           = e1000_set_settings,
        .get_drvinfo            = e1000_get_drvinfo,
index dff7bff8b8e0f1d5ee4e6ca4af510516b3d7fd49..121a865c7fbd12855b32b5dff2883332f3b9485b 100644 (file)
@@ -781,6 +781,59 @@ release:
        return ret_val;
 }
 
+/**
+ *  e1000_k1_workaround_lpt_lp - K1 workaround on Lynxpoint-LP
+ *  @hw:   pointer to the HW structure
+ *  @link: link up bool flag
+ *
+ *  When K1 is enabled for 1Gbps, the MAC can miss 2 DMA completion indications
+ *  preventing further DMA write requests.  Workaround the issue by disabling
+ *  the de-assertion of the clock request when in 1Gpbs mode.
+ **/
+static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link)
+{
+       u32 fextnvm6 = er32(FEXTNVM6);
+       s32 ret_val = 0;
+
+       if (link && (er32(STATUS) & E1000_STATUS_SPEED_1000)) {
+               u16 kmrn_reg;
+
+               ret_val = hw->phy.ops.acquire(hw);
+               if (ret_val)
+                       return ret_val;
+
+               ret_val =
+                   e1000e_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG,
+                                               &kmrn_reg);
+               if (ret_val)
+                       goto release;
+
+               ret_val =
+                   e1000e_write_kmrn_reg_locked(hw,
+                                                E1000_KMRNCTRLSTA_K1_CONFIG,
+                                                kmrn_reg &
+                                                ~E1000_KMRNCTRLSTA_K1_ENABLE);
+               if (ret_val)
+                       goto release;
+
+               usleep_range(10, 20);
+
+               ew32(FEXTNVM6, fextnvm6 | E1000_FEXTNVM6_REQ_PLL_CLK);
+
+               ret_val =
+                   e1000e_write_kmrn_reg_locked(hw,
+                                                E1000_KMRNCTRLSTA_K1_CONFIG,
+                                                kmrn_reg);
+release:
+               hw->phy.ops.release(hw);
+       } else {
+               /* clear FEXTNVM6 bit 8 on link down or 10/100 */
+               ew32(FEXTNVM6, fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK);
+       }
+
+       return ret_val;
+}
+
 /**
  *  e1000_check_for_copper_link_ich8lan - Check for link (Copper)
  *  @hw: pointer to the HW structure
@@ -818,6 +871,14 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
                        return ret_val;
        }
 
+       /* Work-around I218 hang issue */
+       if ((hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_LM) ||
+           (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_V)) {
+               ret_val = e1000_k1_workaround_lpt_lp(hw, link);
+               if (ret_val)
+                       return ret_val;
+       }
+
        /* Clear link partner's EEE ability */
        hw->dev_spec.ich8lan.eee_lp_ability = 0;
 
@@ -3954,8 +4015,16 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw)
 
        phy_ctrl = er32(PHY_CTRL);
        phy_ctrl |= E1000_PHY_CTRL_GBE_DISABLE;
+
        if (hw->phy.type == e1000_phy_i217) {
-               u16 phy_reg;
+               u16 phy_reg, device_id = hw->adapter->pdev->device;
+
+               if ((device_id == E1000_DEV_ID_PCH_LPTLP_I218_LM) ||
+                   (device_id == E1000_DEV_ID_PCH_LPTLP_I218_V)) {
+                       u32 fextnvm6 = er32(FEXTNVM6);
+
+                       ew32(FEXTNVM6, fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK);
+               }
 
                ret_val = hw->phy.ops.acquire(hw);
                if (ret_val)
index b6d3174d7d2d737ff599b2f3f17d6bb7bb1b7cc6..8bf4655c2e17f25a26b70bb6c0ad268034bf8c04 100644 (file)
@@ -92,6 +92,8 @@
 #define E1000_FEXTNVM4_BEACON_DURATION_8USEC   0x7
 #define E1000_FEXTNVM4_BEACON_DURATION_16USEC  0x3
 
+#define E1000_FEXTNVM6_REQ_PLL_CLK     0x00000100
+
 #define PCIE_ICH8_SNOOP_ALL    PCIE_NO_SNOOP_ALL
 
 #define E1000_ICH_RAR_ENTRIES  7
index a177b8b65c44c615271b85840c18bd217f959212..948b86ffa4f027753eec3f5b57b45b90277947ab 100644 (file)
@@ -4303,6 +4303,7 @@ static int e1000_open(struct net_device *netdev)
        netif_start_queue(netdev);
 
        adapter->idle_check = true;
+       hw->mac.get_link_status = true;
        pm_runtime_put(&pdev->dev);
 
        /* fire a link status change interrupt to start the watchdog */
@@ -4662,6 +4663,7 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)
            (adapter->hw.phy.media_type == e1000_media_type_copper)) {
                int ret_val;
 
+               pm_runtime_get_sync(&adapter->pdev->dev);
                ret_val = e1e_rphy(hw, MII_BMCR, &phy->bmcr);
                ret_val |= e1e_rphy(hw, MII_BMSR, &phy->bmsr);
                ret_val |= e1e_rphy(hw, MII_ADVERTISE, &phy->advertise);
@@ -4672,6 +4674,7 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)
                ret_val |= e1e_rphy(hw, MII_ESTATUS, &phy->estatus);
                if (ret_val)
                        e_warn("Error reading PHY register\n");
+               pm_runtime_put_sync(&adapter->pdev->dev);
        } else {
                /* Do not read PHY registers if link is not up
                 * Set values to typical power-on defaults
@@ -5887,8 +5890,7 @@ release:
        return retval;
 }
 
-static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
-                           bool runtime)
+static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -5912,10 +5914,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
        }
        e1000e_reset_interrupt_capability(adapter);
 
-       retval = pci_save_state(pdev);
-       if (retval)
-               return retval;
-
        status = er32(STATUS);
        if (status & E1000_STATUS_LU)
                wufc &= ~E1000_WUFC_LNKC;
@@ -5971,13 +5969,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
                ew32(WUFC, 0);
        }
 
-       *enable_wake = !!wufc;
-
-       /* make sure adapter isn't asleep if manageability is enabled */
-       if ((adapter->flags & FLAG_MNG_PT_ENABLED) ||
-           (hw->mac.ops.check_mng_mode(hw)))
-               *enable_wake = true;
-
        if (adapter->hw.phy.type == e1000_phy_igp_3)
                e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
 
@@ -5986,27 +5977,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
         */
        e1000e_release_hw_control(adapter);
 
-       pci_disable_device(pdev);
-
-       return 0;
-}
-
-static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake)
-{
-       if (sleep && wake) {
-               pci_prepare_to_sleep(pdev);
-               return;
-       }
-
-       pci_wake_from_d3(pdev, wake);
-       pci_set_power_state(pdev, PCI_D3hot);
-}
-
-static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
-                                    bool wake)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct e1000_adapter *adapter = netdev_priv(netdev);
+       pci_clear_master(pdev);
 
        /* The pci-e switch on some quad port adapters will report a
         * correctable error when the MAC transitions from D0 to D3.  To
@@ -6021,12 +5992,13 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
                pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL,
                                           (devctl & ~PCI_EXP_DEVCTL_CERE));
 
-               e1000_power_off(pdev, sleep, wake);
+               pci_save_state(pdev);
+               pci_prepare_to_sleep(pdev);
 
                pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, devctl);
-       } else {
-               e1000_power_off(pdev, sleep, wake);
        }
+
+       return 0;
 }
 
 #ifdef CONFIG_PCIEASPM
@@ -6084,9 +6056,7 @@ static int __e1000_resume(struct pci_dev *pdev)
        if (aspm_disable_flag)
                e1000e_disable_aspm(pdev, aspm_disable_flag);
 
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-       pci_save_state(pdev);
+       pci_set_master(pdev);
 
        e1000e_set_interrupt_capability(adapter);
        if (netif_running(netdev)) {
@@ -6152,14 +6122,8 @@ static int __e1000_resume(struct pci_dev *pdev)
 static int e1000_suspend(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
-       int retval;
-       bool wake;
-
-       retval = __e1000_shutdown(pdev, &wake, false);
-       if (!retval)
-               e1000_complete_shutdown(pdev, true, wake);
 
-       return retval;
+       return __e1000_shutdown(pdev, false);
 }
 
 static int e1000_resume(struct device *dev)
@@ -6182,13 +6146,10 @@ static int e1000_runtime_suspend(struct device *dev)
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct e1000_adapter *adapter = netdev_priv(netdev);
 
-       if (e1000e_pm_ready(adapter)) {
-               bool wake;
-
-               __e1000_shutdown(pdev, &wake, true);
-       }
+       if (!e1000e_pm_ready(adapter))
+               return 0;
 
-       return 0;
+       return __e1000_shutdown(pdev, true);
 }
 
 static int e1000_idle(struct device *dev)
@@ -6226,12 +6187,7 @@ static int e1000_runtime_resume(struct device *dev)
 
 static void e1000_shutdown(struct pci_dev *pdev)
 {
-       bool wake = false;
-
-       __e1000_shutdown(pdev, &wake, false);
-
-       if (system_state == SYSTEM_POWER_OFF)
-               e1000_complete_shutdown(pdev, false, wake);
+       __e1000_shutdown(pdev, false);
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -6352,9 +6308,9 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
                        "Cannot re-enable PCI device after reset.\n");
                result = PCI_ERS_RESULT_DISCONNECT;
        } else {
-               pci_set_master(pdev);
                pdev->state_saved = true;
                pci_restore_state(pdev);
+               pci_set_master(pdev);
 
                pci_enable_wake(pdev, PCI_D3hot, 0);
                pci_enable_wake(pdev, PCI_D3cold, 0);
@@ -6783,7 +6739,11 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        /* initialize the wol settings based on the eeprom settings */
        adapter->wol = adapter->eeprom_wol;
-       device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
+
+       /* make sure adapter isn't asleep if manageability is enabled */
+       if (adapter->wol || (adapter->flags & FLAG_MNG_PT_ENABLED) ||
+           (hw->mac.ops.check_mng_mode(hw)))
+               device_wakeup_enable(&pdev->dev);
 
        /* save off EEPROM version number */
        e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers);
index 794fe14976667059b3cb33924f49dec84cde2aef..a7e6a3e37257b34f200ba01c3525fd3269964943 100644 (file)
@@ -42,6 +42,7 @@
 #define E1000_FEXTNVM  0x00028 /* Future Extended NVM - RW */
 #define E1000_FEXTNVM3 0x0003C /* Future Extended NVM 3 - RW */
 #define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */
+#define E1000_FEXTNVM6 0x00010 /* Future Extended NVM 6 - RW */
 #define E1000_FEXTNVM7 0x000E4 /* Future Extended NVM 7 - RW */
 #define E1000_FCT      0x00030 /* Flow Control Type - RW */
 #define E1000_VET      0x00038 /* VLAN Ether Type - RW */
index 84e7e0909def4bb866411851b2a8ceecffeb1212..b64542acfa3449bda2ee5c793d83de6cda1f097c 100644 (file)
@@ -1361,11 +1361,16 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
        switch (hw->phy.type) {
        case e1000_phy_i210:
        case e1000_phy_m88:
-               if (hw->phy.id == I347AT4_E_PHY_ID ||
-                   hw->phy.id == M88E1112_E_PHY_ID)
+               switch (hw->phy.id) {
+               case I347AT4_E_PHY_ID:
+               case M88E1112_E_PHY_ID:
+               case I210_I_PHY_ID:
                        ret_val = igb_copper_link_setup_m88_gen2(hw);
-               else
+                       break;
+               default:
                        ret_val = igb_copper_link_setup_m88(hw);
+                       break;
+               }
                break;
        case e1000_phy_igp_3:
                ret_val = igb_copper_link_setup_igp(hw);
index d27edbc63923a2f2429ef85d3e7713c50f8e8469..25151401c2abe54dcec7fe1fe6f48791e0660a64 100644 (file)
@@ -447,7 +447,7 @@ struct igb_adapter {
 #endif
        struct i2c_algo_bit_data i2c_algo;
        struct i2c_adapter i2c_adap;
-       struct igb_i2c_client_list *i2c_clients;
+       struct i2c_client *i2c_client;
 };
 
 #define IGB_FLAG_HAS_MSI               (1 << 0)
index 0a9b073d0b033ea7e03f745e4983e048804daf1f..4623502054d5347b2723811fe1cdca0d1e93ae0e 100644 (file)
 #include <linux/pci.h>
 
 #ifdef CONFIG_IGB_HWMON
+struct i2c_board_info i350_sensor_info = {
+       I2C_BOARD_INFO("i350bb", (0Xf8 >> 1)),
+};
+
 /* hwmon callback functions */
 static ssize_t igb_hwmon_show_location(struct device *dev,
                                         struct device_attribute *attr,
@@ -188,6 +192,7 @@ int igb_sysfs_init(struct igb_adapter *adapter)
        unsigned int i;
        int n_attrs;
        int rc = 0;
+       struct i2c_client *client = NULL;
 
        /* If this method isn't defined we don't support thermals */
        if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL)
@@ -198,6 +203,15 @@ int igb_sysfs_init(struct igb_adapter *adapter)
                if (rc)
                        goto exit;
 
+       /* init i2c_client */
+       client = i2c_new_device(&adapter->i2c_adap, &i350_sensor_info);
+       if (client == NULL) {
+               dev_info(&adapter->pdev->dev,
+                       "Failed to create new i2c device..\n");
+               goto exit;
+       }
+       adapter->i2c_client = client;
+
        /* Allocation space for max attributes
         * max num sensors * values (loc, temp, max, caution)
         */
index ed79a1c53b59b0c101f1e5a2c2363f67f1fe0b04..4dbd62968c7a18090a61029249c04f6ee3b1335e 100644 (file)
@@ -1923,10 +1923,6 @@ void igb_set_fw_version(struct igb_adapter *adapter)
        return;
 }
 
-static const struct i2c_board_info i350_sensor_info = {
-       I2C_BOARD_INFO("i350bb", 0Xf8),
-};
-
 /*  igb_init_i2c - Init I2C interface
  *  @adapter: pointer to adapter structure
  *
@@ -6227,13 +6223,6 @@ static struct sk_buff *igb_build_rx_buffer(struct igb_ring *rx_ring,
        /* If we spanned a buffer we have a huge mess so test for it */
        BUG_ON(unlikely(!igb_test_staterr(rx_desc, E1000_RXD_STAT_EOP)));
 
-       /* Guarantee this function can be used by verifying buffer sizes */
-       BUILD_BUG_ON(SKB_WITH_OVERHEAD(IGB_RX_BUFSZ) < (NET_SKB_PAD +
-                                                       NET_IP_ALIGN +
-                                                       IGB_TS_HDR_LEN +
-                                                       ETH_FRAME_LEN +
-                                                       ETH_FCS_LEN));
-
        rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean];
        page = rx_buffer->page;
        prefetchw(page);
@@ -7724,67 +7713,6 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba)
        }
 }
 
-static DEFINE_SPINLOCK(i2c_clients_lock);
-
-/*  igb_get_i2c_client - returns matching client
- *  in adapters's client list.
- *  @adapter: adapter struct
- *  @dev_addr: device address of i2c needed.
- */
-static struct i2c_client *
-igb_get_i2c_client(struct igb_adapter *adapter, u8 dev_addr)
-{
-       ulong flags;
-       struct igb_i2c_client_list *client_list;
-       struct i2c_client *client = NULL;
-       struct i2c_board_info client_info = {
-               I2C_BOARD_INFO("igb", 0x00),
-       };
-
-       spin_lock_irqsave(&i2c_clients_lock, flags);
-       client_list = adapter->i2c_clients;
-
-       /* See if we already have an i2c_client */
-       while (client_list) {
-               if (client_list->client->addr == (dev_addr >> 1)) {
-                       client = client_list->client;
-                       goto exit;
-               } else {
-                       client_list = client_list->next;
-               }
-       }
-
-       /* no client_list found, create a new one */
-       client_list = kzalloc(sizeof(*client_list), GFP_ATOMIC);
-       if (client_list == NULL)
-               goto exit;
-
-       /* dev_addr passed to us is left-shifted by 1 bit
-        * i2c_new_device call expects it to be flush to the right.
-        */
-       client_info.addr = dev_addr >> 1;
-       client_info.platform_data = adapter;
-       client_list->client = i2c_new_device(&adapter->i2c_adap, &client_info);
-       if (client_list->client == NULL) {
-               dev_info(&adapter->pdev->dev,
-                       "Failed to create new i2c device..\n");
-               goto err_no_client;
-       }
-
-       /* insert new client at head of list */
-       client_list->next = adapter->i2c_clients;
-       adapter->i2c_clients = client_list;
-
-       client = client_list->client;
-       goto exit;
-
-err_no_client:
-       kfree(client_list);
-exit:
-       spin_unlock_irqrestore(&i2c_clients_lock, flags);
-       return client;
-}
-
 /*  igb_read_i2c_byte - Reads 8 bit word over I2C
  *  @hw: pointer to hardware structure
  *  @byte_offset: byte offset to read
@@ -7798,7 +7726,7 @@ s32 igb_read_i2c_byte(struct e1000_hw *hw, u8 byte_offset,
                                u8 dev_addr, u8 *data)
 {
        struct igb_adapter *adapter = container_of(hw, struct igb_adapter, hw);
-       struct i2c_client *this_client = igb_get_i2c_client(adapter, dev_addr);
+       struct i2c_client *this_client = adapter->i2c_client;
        s32 status;
        u16 swfw_mask = 0;
 
@@ -7835,7 +7763,7 @@ s32 igb_write_i2c_byte(struct e1000_hw *hw, u8 byte_offset,
                                 u8 dev_addr, u8 data)
 {
        struct igb_adapter *adapter = container_of(hw, struct igb_adapter, hw);
-       struct i2c_client *this_client = igb_get_i2c_client(adapter, dev_addr);
+       struct i2c_client *this_client = adapter->i2c_client;
        s32 status;
        u16 swfw_mask = E1000_SWFW_PHY0_SM;
 
index 29140502b71aea8765a917f2b68e34d8d645b249..6562c736a1d83df96a8feb249a289268b014a854 100644 (file)
@@ -1081,6 +1081,45 @@ static void txq_set_fixed_prio_mode(struct tx_queue *txq)
 
 
 /* mii management interface *************************************************/
+static void mv643xx_adjust_pscr(struct mv643xx_eth_private *mp)
+{
+       u32 pscr = rdlp(mp, PORT_SERIAL_CONTROL);
+       u32 autoneg_disable = FORCE_LINK_PASS |
+                    DISABLE_AUTO_NEG_SPEED_GMII |
+                    DISABLE_AUTO_NEG_FOR_FLOW_CTRL |
+                    DISABLE_AUTO_NEG_FOR_DUPLEX;
+
+       if (mp->phy->autoneg == AUTONEG_ENABLE) {
+               /* enable auto negotiation */
+               pscr &= ~autoneg_disable;
+               goto out_write;
+       }
+
+       pscr |= autoneg_disable;
+
+       if (mp->phy->speed == SPEED_1000) {
+               /* force gigabit, half duplex not supported */
+               pscr |= SET_GMII_SPEED_TO_1000;
+               pscr |= SET_FULL_DUPLEX_MODE;
+               goto out_write;
+       }
+
+       pscr &= ~SET_GMII_SPEED_TO_1000;
+
+       if (mp->phy->speed == SPEED_100)
+               pscr |= SET_MII_SPEED_TO_100;
+       else
+               pscr &= ~SET_MII_SPEED_TO_100;
+
+       if (mp->phy->duplex == DUPLEX_FULL)
+               pscr |= SET_FULL_DUPLEX_MODE;
+       else
+               pscr &= ~SET_FULL_DUPLEX_MODE;
+
+out_write:
+       wrlp(mp, PORT_SERIAL_CONTROL, pscr);
+}
+
 static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id)
 {
        struct mv643xx_eth_shared_private *msp = dev_id;
@@ -1499,6 +1538,7 @@ static int
 mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
        struct mv643xx_eth_private *mp = netdev_priv(dev);
+       int ret;
 
        if (mp->phy == NULL)
                return -EINVAL;
@@ -1508,7 +1548,10 @@ mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
         */
        cmd->advertising &= ~ADVERTISED_1000baseT_Half;
 
-       return phy_ethtool_sset(mp->phy, cmd);
+       ret = phy_ethtool_sset(mp->phy, cmd);
+       if (!ret)
+               mv643xx_adjust_pscr(mp);
+       return ret;
 }
 
 static void mv643xx_eth_get_drvinfo(struct net_device *dev,
@@ -2442,11 +2485,15 @@ static int mv643xx_eth_stop(struct net_device *dev)
 static int mv643xx_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
        struct mv643xx_eth_private *mp = netdev_priv(dev);
+       int ret;
 
-       if (mp->phy != NULL)
-               return phy_mii_ioctl(mp->phy, ifr, cmd);
+       if (mp->phy == NULL)
+               return -ENOTSUPP;
 
-       return -EOPNOTSUPP;
+       ret = phy_mii_ioctl(mp->phy, ifr, cmd);
+       if (!ret)
+               mv643xx_adjust_pscr(mp);
+       return ret;
 }
 
 static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu)
index 7e64033d7de39ed7723c162c75e24cf49cd3d6fa..0706623cfb96abf74b2d6ebb15d15f05d18504f5 100644 (file)
@@ -226,7 +226,7 @@ void __mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn)
 
 static void mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn)
 {
-       u64 in_param;
+       u64 in_param = 0;
        int err;
 
        if (mlx4_is_mfunc(dev)) {
index bb4d8d99f36d2d69060a534e4e39ca07a69187a8..995d4b6d5c1e924a870f3da67c6ce1b543b99a83 100644 (file)
@@ -565,34 +565,38 @@ static void mlx4_en_put_qp(struct mlx4_en_priv *priv)
        struct mlx4_en_dev *mdev = priv->mdev;
        struct mlx4_dev *dev = mdev->dev;
        int qpn = priv->base_qpn;
-       u64 mac = mlx4_en_mac_to_u64(priv->dev->dev_addr);
-
-       en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n",
-              priv->dev->dev_addr);
-       mlx4_unregister_mac(dev, priv->port, mac);
+       u64 mac;
 
-       if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0) {
+       if (dev->caps.steering_mode == MLX4_STEERING_MODE_A0) {
+               mac = mlx4_en_mac_to_u64(priv->dev->dev_addr);
+               en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n",
+                      priv->dev->dev_addr);
+               mlx4_unregister_mac(dev, priv->port, mac);
+       } else {
                struct mlx4_mac_entry *entry;
                struct hlist_node *tmp;
                struct hlist_head *bucket;
-               unsigned int mac_hash;
+               unsigned int i;
 
-               mac_hash = priv->dev->dev_addr[MLX4_EN_MAC_HASH_IDX];
-               bucket = &priv->mac_hash[mac_hash];
-               hlist_for_each_entry_safe(entry, tmp, bucket, hlist) {
-                       if (ether_addr_equal_64bits(entry->mac,
-                                                   priv->dev->dev_addr)) {
-                               en_dbg(DRV, priv, "Releasing qp: port %d, MAC %pM, qpn %d\n",
-                                      priv->port, priv->dev->dev_addr, qpn);
+               for (i = 0; i < MLX4_EN_MAC_HASH_SIZE; ++i) {
+                       bucket = &priv->mac_hash[i];
+                       hlist_for_each_entry_safe(entry, tmp, bucket, hlist) {
+                               mac = mlx4_en_mac_to_u64(entry->mac);
+                               en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n",
+                                      entry->mac);
                                mlx4_en_uc_steer_release(priv, entry->mac,
                                                         qpn, entry->reg_id);
-                               mlx4_qp_release_range(dev, qpn, 1);
 
+                               mlx4_unregister_mac(dev, priv->port, mac);
                                hlist_del_rcu(&entry->hlist);
                                kfree_rcu(entry, rcu);
-                               break;
                        }
                }
+
+               en_dbg(DRV, priv, "Releasing qp: port %d, qpn %d\n",
+                      priv->port, qpn);
+               mlx4_qp_release_range(dev, qpn, 1);
+               priv->flags &= ~MLX4_EN_FLAG_FORCE_PROMISC;
        }
 }
 
@@ -650,28 +654,10 @@ u64 mlx4_en_mac_to_u64(u8 *addr)
        return mac;
 }
 
-static int mlx4_en_set_mac(struct net_device *dev, void *addr)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-       struct mlx4_en_dev *mdev = priv->mdev;
-       struct sockaddr *saddr = addr;
-
-       if (!is_valid_ether_addr(saddr->sa_data))
-               return -EADDRNOTAVAIL;
-
-       memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN);
-       queue_work(mdev->workqueue, &priv->mac_task);
-       return 0;
-}
-
-static void mlx4_en_do_set_mac(struct work_struct *work)
+static int mlx4_en_do_set_mac(struct mlx4_en_priv *priv)
 {
-       struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv,
-                                                mac_task);
-       struct mlx4_en_dev *mdev = priv->mdev;
        int err = 0;
 
-       mutex_lock(&mdev->state_lock);
        if (priv->port_up) {
                /* Remove old MAC and insert the new one */
                err = mlx4_en_replace_mac(priv, priv->base_qpn,
@@ -683,7 +669,26 @@ static void mlx4_en_do_set_mac(struct work_struct *work)
        } else
                en_dbg(HW, priv, "Port is down while registering mac, exiting...\n");
 
+       return err;
+}
+
+static int mlx4_en_set_mac(struct net_device *dev, void *addr)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       struct sockaddr *saddr = addr;
+       int err;
+
+       if (!is_valid_ether_addr(saddr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN);
+
+       mutex_lock(&mdev->state_lock);
+       err = mlx4_en_do_set_mac(priv);
        mutex_unlock(&mdev->state_lock);
+
+       return err;
 }
 
 static void mlx4_en_clear_list(struct net_device *dev)
@@ -1348,7 +1353,7 @@ static void mlx4_en_do_get_stats(struct work_struct *work)
                queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
        }
        if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) {
-               queue_work(mdev->workqueue, &priv->mac_task);
+               mlx4_en_do_set_mac(priv);
                mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0;
        }
        mutex_unlock(&mdev->state_lock);
@@ -1828,9 +1833,11 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv)
        }
 
 #ifdef CONFIG_RFS_ACCEL
-       priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->mdev->dev->caps.comp_pool);
-       if (!priv->dev->rx_cpu_rmap)
-               goto err;
+       if (priv->mdev->dev->caps.comp_pool) {
+               priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->mdev->dev->caps.comp_pool);
+               if (!priv->dev->rx_cpu_rmap)
+                       goto err;
+       }
 #endif
 
        return 0;
@@ -2078,7 +2085,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        priv->msg_enable = MLX4_EN_MSG_LEVEL;
        spin_lock_init(&priv->stats_lock);
        INIT_WORK(&priv->rx_mode_task, mlx4_en_do_set_rx_mode);
-       INIT_WORK(&priv->mac_task, mlx4_en_do_set_mac);
        INIT_WORK(&priv->watchdog_task, mlx4_en_restart);
        INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate);
        INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats);
index 50917eb3013e1bad3aef4a572a006002d5ba61f0..f6245579962d5f0c1a81e31f757a52d16c7cd3de 100644 (file)
@@ -787,6 +787,14 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
        bmme_flags &= ~MLX4_BMME_FLAG_TYPE_2_WIN;
        MLX4_PUT(outbox->buf, bmme_flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET);
 
+       /* turn off device-managed steering capability if not enabled */
+       if (dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED) {
+               MLX4_GET(field, outbox->buf,
+                        QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET);
+               field &= 0x7f;
+               MLX4_PUT(outbox->buf, field,
+                        QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET);
+       }
        return 0;
 }
 
index d180bc46826afd0189eb7aa0360baf598615c02b..16abde20e1fcd2daaefc6b9a671b4c6c1a4313bb 100644 (file)
@@ -1555,7 +1555,7 @@ void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
 
 void mlx4_counter_free(struct mlx4_dev *dev, u32 idx)
 {
-       u64 in_param;
+       u64 in_param = 0;
 
        if (mlx4_is_mfunc(dev)) {
                set_param_l(&in_param, idx);
index cf883345af8887eeac97eb5b7278b98a98ffe4bb..d738454116a088db7a098c88f2ef5fc9b7eb1698 100644 (file)
@@ -1235,7 +1235,7 @@ int mlx4_get_qp_per_mgm(struct mlx4_dev *dev);
 
 static inline void set_param_l(u64 *arg, u32 val)
 {
-       *((u32 *)arg) = val;
+       *arg = (*arg & 0xffffffff00000000ULL) | (u64) val;
 }
 
 static inline void set_param_h(u64 *arg, u32 val)
index c313d7e943a95cbd049d2ed000dc76ab8c4e0009..f710b7ce0dcbbf9ef740d0661add1bb744921b9f 100644 (file)
@@ -509,7 +509,6 @@ struct mlx4_en_priv {
        struct mlx4_en_cq rx_cq[MAX_RX_RINGS];
        struct mlx4_qp drop_qp;
        struct work_struct rx_mode_task;
-       struct work_struct mac_task;
        struct work_struct watchdog_task;
        struct work_struct linkstate_task;
        struct delayed_work stats_task;
index 602ca9bf78e46b22ec921140c4539105b8597454..f91719a08cbac000dc34f68f7d40252aa652ac58 100644 (file)
@@ -183,7 +183,7 @@ u32 __mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order)
 
 static u32 mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order)
 {
-       u64 in_param;
+       u64 in_param = 0;
        u64 out_param;
        int err;
 
@@ -240,7 +240,7 @@ void __mlx4_free_mtt_range(struct mlx4_dev *dev, u32 offset, int order)
 
 static void mlx4_free_mtt_range(struct mlx4_dev *dev, u32 offset, int order)
 {
-       u64 in_param;
+       u64 in_param = 0;
        int err;
 
        if (mlx4_is_mfunc(dev)) {
@@ -351,7 +351,7 @@ void __mlx4_mpt_release(struct mlx4_dev *dev, u32 index)
 
 static void mlx4_mpt_release(struct mlx4_dev *dev, u32 index)
 {
-       u64 in_param;
+       u64 in_param = 0;
 
        if (mlx4_is_mfunc(dev)) {
                set_param_l(&in_param, index);
@@ -374,7 +374,7 @@ int __mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index)
 
 static int mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index)
 {
-       u64 param;
+       u64 param = 0;
 
        if (mlx4_is_mfunc(dev)) {
                set_param_l(&param, index);
@@ -395,7 +395,7 @@ void __mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index)
 
 static void mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index)
 {
-       u64 in_param;
+       u64 in_param = 0;
 
        if (mlx4_is_mfunc(dev)) {
                set_param_l(&in_param, index);
index 1ac88637ad9de145f81d9e4851fda2387da12158..00f223acada79a8f0bf6b52ae21e75afbfb60ce0 100644 (file)
@@ -101,7 +101,7 @@ void __mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn)
 
 void mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn)
 {
-       u64 in_param;
+       u64 in_param = 0;
        int err;
 
        if (mlx4_is_mfunc(dev)) {
index 719ead15e49181f1fc419b0c18310db521280eff..10c57c86388baed3626cc803fc8acadf605ca855 100644 (file)
@@ -175,7 +175,7 @@ EXPORT_SYMBOL_GPL(__mlx4_register_mac);
 
 int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac)
 {
-       u64 out_param;
+       u64 out_param = 0;
        int err;
 
        if (mlx4_is_mfunc(dev)) {
@@ -222,7 +222,7 @@ EXPORT_SYMBOL_GPL(__mlx4_unregister_mac);
 
 void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac)
 {
-       u64 out_param;
+       u64 out_param = 0;
 
        if (mlx4_is_mfunc(dev)) {
                set_param_l(&out_param, port);
@@ -361,7 +361,7 @@ out:
 
 int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
 {
-       u64 out_param;
+       u64 out_param = 0;
        int err;
 
        if (mlx4_is_mfunc(dev)) {
@@ -406,7 +406,7 @@ out:
 
 void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
 {
-       u64 in_param;
+       u64 in_param = 0;
        int err;
 
        if (mlx4_is_mfunc(dev)) {
index 81e2abe07bbbf656689ba327ab0d4d22368961df..e891b058c1befdc09927ea1ab49aa70e282d4278 100644 (file)
@@ -222,7 +222,7 @@ int __mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align,
 
 int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, int *base)
 {
-       u64 in_param;
+       u64 in_param = 0;
        u64 out_param;
        int err;
 
@@ -255,7 +255,7 @@ void __mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt)
 
 void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt)
 {
-       u64 in_param;
+       u64 in_param = 0;
        int err;
 
        if (mlx4_is_mfunc(dev)) {
@@ -319,7 +319,7 @@ err_out:
 
 static int mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn)
 {
-       u64 param;
+       u64 param = 0;
 
        if (mlx4_is_mfunc(dev)) {
                set_param_l(&param, qpn);
@@ -344,7 +344,7 @@ void __mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn)
 
 static void mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn)
 {
-       u64 in_param;
+       u64 in_param = 0;
 
        if (mlx4_is_mfunc(dev)) {
                set_param_l(&in_param, qpn);
index 083fb48dc3d7bd7bfa014f8ddc9a7eed81dffca5..2995687f1aee3692ef5c164cff02870607f76224 100644 (file)
@@ -2990,6 +2990,9 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
        u8 steer_type_mask = 2;
        enum mlx4_steer_type type = (gid[7] & steer_type_mask) >> 1;
 
+       if (dev->caps.steering_mode != MLX4_STEERING_MODE_B0)
+               return -EINVAL;
+
        qpn = vhcr->in_modifier & 0xffffff;
        err = get_res(dev, slave, qpn, RES_QP, &rqp);
        if (err)
index feda6c00829f391e0d5bd822db970c5d6a2f7ca2..e329fe1f11b736d8e717880c7e6e7e092db2a14c 100644 (file)
@@ -149,7 +149,7 @@ void __mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn)
 
 static void mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn)
 {
-       u64 in_param;
+       u64 in_param = 0;
 
        if (mlx4_is_mfunc(dev)) {
                set_param_l(&in_param, srqn);
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 50247dfe8f574d2a7184c8ea675b5ecabdcc37cc..d2f790df6dcbf6872084c49d74a8a63efb58f569 100644 (file)
@@ -171,9 +171,9 @@ static inline void efx_device_detach_sync(struct efx_nic *efx)
         * TX scheduler is stopped when we're done and before
         * netif_device_present() becomes false.
         */
-       netif_tx_lock(dev);
+       netif_tx_lock_bh(dev);
        netif_device_detach(dev);
-       netif_tx_unlock(dev);
+       netif_tx_unlock_bh(dev);
 }
 
 #endif /* EFX_EFX_H */
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..bb579a6128c8ce883ac7156ea24ac541d4901e38 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 + EFX_PAGE_IP_ALIGN;
                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 e5b19b05690967ed93f9ac50be4d1548911bf38a..3c4d6274bb9b25527aa2af7e1daf4f07fe3a84d0 100644 (file)
@@ -202,6 +202,9 @@ static int rr_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        return 0;
 
  out:
+       if (rrpriv->evt_ring)
+               pci_free_consistent(pdev, EVT_RING_SIZE, rrpriv->evt_ring,
+                                   rrpriv->evt_ring_dma);
        if (rrpriv->rx_ring)
                pci_free_consistent(pdev, RX_TOTAL_SIZE, rrpriv->rx_ring,
                                    rrpriv->rx_ring_dma);
index 417b2af1aa8097fd3e158e8b9e09b59885d8c723..73abbc1655d5c7b793601f93027dad37d2923150 100644 (file)
@@ -660,6 +660,7 @@ void macvlan_common_setup(struct net_device *dev)
        ether_setup(dev);
 
        dev->priv_flags        &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
+       dev->priv_flags        |= IFF_UNICAST_FLT;
        dev->netdev_ops         = &macvlan_netdev_ops;
        dev->destructor         = free_netdev;
        dev->header_ops         = &macvlan_hard_header_ops,
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 05c5efe8459148be152db604da421fe35e95ba41..bf3419297875b102da599162c0852ecfd9eb71eb 100644 (file)
@@ -1138,6 +1138,8 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
        netdev_upper_dev_unlink(port_dev, dev);
        team_port_disable_netpoll(port);
        vlan_vids_del_by_dev(port_dev, dev);
+       dev_uc_unsync(port_dev, dev);
+       dev_mc_unsync(port_dev, dev);
        dev_close(port_dev);
        team_port_leave(team, port);
 
index 2c6a22e278ea15843b7fb4500749304aad0a1444..b7c457adc0dc7439cc2a842409ed3871207f079b 100644 (file)
@@ -747,6 +747,8 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
                goto drop;
        skb_orphan(skb);
 
+       nf_reset(skb);
+
        /* Enqueue packet */
        skb_queue_tail(&tfile->socket.sk->sk_receive_queue, skb);
 
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 4aad350e4daec8e5c252052153688b19ae51996d..eae7a03d4f9bb7a5b69414d9c161bb7b0f777b77 100644 (file)
@@ -2958,6 +2958,7 @@ vmxnet3_probe_device(struct pci_dev *pdev,
 
        adapter->num_rx_queues = num_rx_queues;
        adapter->num_tx_queues = num_tx_queues;
+       adapter->rx_buf_per_pkt = 1;
 
        size = sizeof(struct Vmxnet3_TxQueueDesc) * adapter->num_tx_queues;
        size += sizeof(struct Vmxnet3_RxQueueDesc) * adapter->num_rx_queues;
index a0feb17a023844fac5840e8c92998f46d119464e..63a124340cbecb19f3ad0d5f9b43f6fcfed6b4e0 100644 (file)
@@ -472,6 +472,12 @@ vmxnet3_set_ringparam(struct net_device *netdev,
                                                VMXNET3_RX_RING_MAX_SIZE)
                return -EINVAL;
 
+       /* if adapter not yet initialized, do nothing */
+       if (adapter->rx_buf_per_pkt == 0) {
+               netdev_err(netdev, "adapter not completely initialized, "
+                          "ring size cannot be changed yet\n");
+               return -EOPNOTSUPP;
+       }
 
        /* round it up to a multiple of VMXNET3_RING_SIZE_ALIGN */
        new_tx_ring_size = (param->tx_pending + VMXNET3_RING_SIZE_MASK) &
index 3198384689d9fbcb5119c029706844b7d8bc86bc..35418146fa170100ec1f8aef59c123e6a5b908df 100644 (file)
 /*
  * Version numbers
  */
-#define VMXNET3_DRIVER_VERSION_STRING   "1.1.29.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING   "1.1.30.0-k"
 
 /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM      0x01011D00
+#define VMXNET3_DRIVER_VERSION_NUM      0x01011E00
 
 #if defined(CONFIG_PCI_MSI)
        /* RSS only makes sense if MSI-X is supported. */
index f10e58ac9c1b6078527ecbc88b2c59fe54d4ea66..7cee7a3068ec11ae9a7f91efa612748dfdd0463e 100644 (file)
@@ -961,6 +961,8 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
        iph->ttl        = ttl ? : ip4_dst_hoplimit(&rt->dst);
        tunnel_ip_select_ident(skb, old_iph, &rt->dst);
 
+       nf_reset(skb);
+
        vxlan_set_owner(dev, skb);
 
        /* See iptunnel_xmit() */
@@ -1504,6 +1506,14 @@ static __net_init int vxlan_init_net(struct net *net)
 static __net_exit void vxlan_exit_net(struct net *net)
 {
        struct vxlan_net *vn = net_generic(net, vxlan_net_id);
+       struct vxlan_dev *vxlan;
+       unsigned h;
+
+       rtnl_lock();
+       for (h = 0; h < VNI_HASH_SIZE; ++h)
+               hlist_for_each_entry(vxlan, &vn->vni_list[h], hlist)
+                       dev_close(vxlan->dev);
+       rtnl_unlock();
 
        if (vn->sock) {
                sk_release_kernel(vn->sock->sk);
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 94ef33838bc69b615f8f47140922bf0d13eb2453..b775769f8322c437558712af955332296e95db89 100644 (file)
@@ -151,7 +151,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
                       sta_id, sta->sta.addr, flags & CMD_ASYNC ?  "a" : "");
 
        if (!(flags & CMD_ASYNC)) {
-               cmd.flags |= CMD_WANT_SKB | CMD_WANT_HCMD;
+               cmd.flags |= CMD_WANT_SKB;
                might_sleep();
        }
 
index 9a0f45ec9e01e2456610e28d0f760ce7d890451e..81aa91fab5aafcc1dc7fa597c85878d01ab83685 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++) {
+               for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; 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 6f228bb2b84431e61cd8292d1563f81faa91efc6..fbfd2d1371176e247a22e5fca00ee5809088c306 100644 (file)
@@ -1102,7 +1102,6 @@ void iwl_drv_stop(struct iwl_drv *drv)
 
 /* shared module parameters */
 struct iwl_mod_params iwlwifi_mod_params = {
-       .amsdu_size_8K = 1,
        .restart_fw = 1,
        .plcp_check = true,
        .bt_coex_active = true,
@@ -1207,7 +1206,7 @@ MODULE_PARM_DESC(11n_disable,
        "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX");
 module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K,
                   int, S_IRUGO);
-MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
+MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)");
 module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, int, S_IRUGO);
 MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
 
index e5e3a79eae2fbd5e8f544db2cc9605522770dddb..2c2a729092f5e894013c39f1eccb0a739a5e56d4 100644 (file)
@@ -91,7 +91,7 @@ enum iwl_power_level {
  * @sw_crypto: using hardware encryption, default = 0
  * @disable_11n: disable 11n capabilities, default = 0,
  *     use IWL_DISABLE_HT_* constants
- * @amsdu_size_8K: enable 8K amsdu size, default = 1
+ * @amsdu_size_8K: enable 8K amsdu size, default = 0
  * @restart_fw: restart firmware, default = 1
  * @plcp_check: enable plcp health check, default = true
  * @wd_disable: enable stuck queue check, default = 0
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 8c7bec6b9a0be92d29136a47fc20f920a5ce7a6d..0cac2b7af78b99eb1e8c8951a9638c12033e382c 100644 (file)
@@ -186,19 +186,13 @@ struct iwl_rx_packet {
  * @CMD_ASYNC: Return right away and don't want for the response
  * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the
  *     response. The caller needs to call iwl_free_resp when done.
- * @CMD_WANT_HCMD: The caller needs to get the HCMD that was sent in the
- *     response handler. Chunks flagged by %IWL_HCMD_DFL_NOCOPY won't be
- *     copied. The pointer passed to the response handler is in the transport
- *     ownership and don't need to be freed by the op_mode. This also means
- *     that the pointer is invalidated after the op_mode's handler returns.
  * @CMD_ON_DEMAND: This command is sent by the test mode pipe.
  */
 enum CMD_MODE {
        CMD_SYNC                = 0,
        CMD_ASYNC               = BIT(0),
        CMD_WANT_SKB            = BIT(1),
-       CMD_WANT_HCMD           = BIT(2),
-       CMD_ON_DEMAND           = BIT(3),
+       CMD_ON_DEMAND           = BIT(2),
 };
 
 #define DEF_CMD_PAYLOAD_SIZE 320
@@ -217,7 +211,11 @@ struct iwl_device_cmd {
 
 #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
 
-#define IWL_MAX_CMD_TFDS       2
+/*
+ * number of transfer buffers (fragments) per transmit frame descriptor;
+ * this is just the driver's idea, the hardware supports 20
+ */
+#define IWL_MAX_CMD_TBS_PER_TFD        2
 
 /**
  * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command
@@ -254,15 +252,15 @@ enum iwl_hcmd_dataflag {
  * @id: id of the host command
  */
 struct iwl_host_cmd {
-       const void *data[IWL_MAX_CMD_TFDS];
+       const void *data[IWL_MAX_CMD_TBS_PER_TFD];
        struct iwl_rx_packet *resp_pkt;
        unsigned long _rx_page_addr;
        u32 _rx_page_order;
        int handler_status;
 
        u32 flags;
-       u16 len[IWL_MAX_CMD_TFDS];
-       u8 dataflags[IWL_MAX_CMD_TFDS];
+       u16 len[IWL_MAX_CMD_TBS_PER_TFD];
+       u8 dataflags[IWL_MAX_CMD_TBS_PER_TFD];
        u8 id;
 };
 
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 23eebda848b05ae64f9ae8dfb6ce5647dded4b19..2adb61f103f4cd310ae654fdd83ff466a843dda5 100644 (file)
@@ -762,18 +762,20 @@ struct iwl_phy_context_cmd {
 #define IWL_RX_INFO_PHY_CNT 8
 #define IWL_RX_INFO_AGC_IDX 1
 #define IWL_RX_INFO_RSSI_AB_IDX 2
-#define IWL_RX_INFO_RSSI_C_IDX 3
-#define IWL_OFDM_AGC_DB_MSK 0xfe00
-#define IWL_OFDM_AGC_DB_POS 9
+#define IWL_OFDM_AGC_A_MSK 0x0000007f
+#define IWL_OFDM_AGC_A_POS 0
+#define IWL_OFDM_AGC_B_MSK 0x00003f80
+#define IWL_OFDM_AGC_B_POS 7
+#define IWL_OFDM_AGC_CODE_MSK 0x3fe00000
+#define IWL_OFDM_AGC_CODE_POS 20
 #define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff
-#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00
 #define IWL_OFDM_RSSI_A_POS 0
+#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00
+#define IWL_OFDM_RSSI_ALLBAND_A_POS 8
 #define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000
-#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000
 #define IWL_OFDM_RSSI_B_POS 16
-#define IWL_OFDM_RSSI_INBAND_C_MSK 0x00ff
-#define IWL_OFDM_RSSI_ALLBAND_C_MSK 0xff00
-#define IWL_OFDM_RSSI_C_POS 0
+#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000
+#define IWL_OFDM_RSSI_ALLBAND_B_POS 24
 
 /**
  * struct iwl_rx_phy_info - phy info
index d3d959db03a9727e7033a871fc4717654dc3ec10..500f818dba0412df8e5a76d018ddaec761529820 100644 (file)
 #define UCODE_VALID_OK cpu_to_le32(0x1)
 
 /* Default calibration values for WkP - set to INIT image w/o running */
-static const u8 wkp_calib_values_bb_filter[] = { 0xbf, 0x00, 0x5f, 0x00, 0x2f,
-                                                0x00, 0x18, 0x00 };
-static const u8 wkp_calib_values_rx_dc[] = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-                                            0x7f, 0x7f, 0x7f };
-static const u8 wkp_calib_values_tx_lo[] = { 0x00, 0x00, 0x00, 0x00 };
-static const u8 wkp_calib_values_tx_iq[] = { 0xff, 0x00, 0xff, 0x00, 0x00,
-                                            0x00 };
-static const u8 wkp_calib_values_rx_iq[] = { 0xff, 0x00, 0x00, 0x00 };
 static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 };
 static const u8 wkp_calib_values_tx_iq_skew[] = { 0x01, 0x00, 0x00, 0x00 };
-static const u8 wkp_calib_values_xtal[] = { 0xd2, 0xd2 };
 
 struct iwl_calib_default_data {
        u16 size;
@@ -99,12 +90,7 @@ struct iwl_calib_default_data {
 #define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf}
 
 static const struct iwl_calib_default_data wkp_calib_default_data[12] = {
-       [5] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_dc),
-       [6] = CALIB_SIZE_N_DATA(wkp_calib_values_bb_filter),
-       [7] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_lo),
-       [8] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq),
        [9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew),
-       [10] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq),
        [11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew),
 };
 
@@ -241,20 +227,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
 
        return 0;
 }
-#define IWL_HW_REV_ID_RAINBOW  0x2
-#define IWL_PROJ_TYPE_LHP      0x5
-
-static u32 iwl_mvm_build_phy_cfg(struct iwl_mvm *mvm)
-{
-       struct iwl_nvm_data *data = mvm->nvm_data;
-       /* Temp calls to static definitions, will be changed to CSR calls */
-       u8 hw_rev_id = IWL_HW_REV_ID_RAINBOW;
-       u8 project_type = IWL_PROJ_TYPE_LHP;
-
-       return data->radio_cfg_dash | (data->radio_cfg_step << 2) |
-               (hw_rev_id << 4) | ((project_type & 0x7f) << 6) |
-               (data->valid_tx_ant << 16) | (data->valid_rx_ant << 20);
-}
 
 static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
 {
@@ -262,7 +234,7 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
        enum iwl_ucode_type ucode_type = mvm->cur_ucode;
 
        /* Set parameters */
-       phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_build_phy_cfg(mvm));
+       phy_cfg_cmd.phy_cfg = cpu_to_le32(mvm->fw->phy_config);
        phy_cfg_cmd.calib_control.event_trigger =
                mvm->fw->default_calib[ucode_type].event_trigger;
        phy_cfg_cmd.calib_control.flow_trigger =
@@ -275,103 +247,6 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
                                    sizeof(phy_cfg_cmd), &phy_cfg_cmd);
 }
 
-/* Starting with the new PHY DB implementation - New calibs are enabled */
-/* Value - 0x405e7 */
-#define IWL_CALIB_DEFAULT_FLOW_INIT    (IWL_CALIB_CFG_XTAL_IDX         |\
-                                        IWL_CALIB_CFG_TEMPERATURE_IDX  |\
-                                        IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
-                                        IWL_CALIB_CFG_DC_IDX           |\
-                                        IWL_CALIB_CFG_BB_FILTER_IDX    |\
-                                        IWL_CALIB_CFG_LO_LEAKAGE_IDX   |\
-                                        IWL_CALIB_CFG_TX_IQ_IDX        |\
-                                        IWL_CALIB_CFG_RX_IQ_IDX        |\
-                                        IWL_CALIB_CFG_AGC_IDX)
-
-#define IWL_CALIB_DEFAULT_EVENT_INIT   0x0
-
-/* Value 0x41567 */
-#define IWL_CALIB_DEFAULT_FLOW_RUN     (IWL_CALIB_CFG_XTAL_IDX         |\
-                                        IWL_CALIB_CFG_TEMPERATURE_IDX  |\
-                                        IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
-                                        IWL_CALIB_CFG_BB_FILTER_IDX    |\
-                                        IWL_CALIB_CFG_DC_IDX           |\
-                                        IWL_CALIB_CFG_TX_IQ_IDX        |\
-                                        IWL_CALIB_CFG_RX_IQ_IDX        |\
-                                        IWL_CALIB_CFG_SENSITIVITY_IDX  |\
-                                        IWL_CALIB_CFG_AGC_IDX)
-
-#define IWL_CALIB_DEFAULT_EVENT_RUN    (IWL_CALIB_CFG_XTAL_IDX         |\
-                                        IWL_CALIB_CFG_TEMPERATURE_IDX  |\
-                                        IWL_CALIB_CFG_VOLTAGE_READ_IDX |\
-                                        IWL_CALIB_CFG_TX_PWR_IDX       |\
-                                        IWL_CALIB_CFG_DC_IDX           |\
-                                        IWL_CALIB_CFG_TX_IQ_IDX        |\
-                                        IWL_CALIB_CFG_SENSITIVITY_IDX)
-
-/*
- * Sets the calibrations trigger values that will be sent to the FW for runtime
- * and init calibrations.
- * The ones given in the FW TLV are not correct.
- */
-static void iwl_set_default_calib_trigger(struct iwl_mvm *mvm)
-{
-       struct iwl_tlv_calib_ctrl default_calib;
-
-       /*
-        * WkP FW TLV calib bits are wrong, overwrite them.
-        * This defines the dynamic calibrations which are implemented in the
-        * uCode both for init(flow) calculation and event driven calibs.
-        */
-
-       /* Init Image */
-       default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_INIT);
-       default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_INIT);
-
-       if (default_calib.event_trigger !=
-           mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger)
-               IWL_ERR(mvm,
-                       "Updating the event calib for INIT image: 0x%x -> 0x%x\n",
-                       mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger,
-                       default_calib.event_trigger);
-       if (default_calib.flow_trigger !=
-           mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger)
-               IWL_ERR(mvm,
-                       "Updating the flow calib for INIT image: 0x%x -> 0x%x\n",
-                       mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger,
-                       default_calib.flow_trigger);
-
-       memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_INIT],
-              &default_calib, sizeof(struct iwl_tlv_calib_ctrl));
-       IWL_ERR(mvm,
-               "Setting uCode init calibrations event 0x%x, trigger 0x%x\n",
-               default_calib.event_trigger,
-               default_calib.flow_trigger);
-
-       /* Run time image */
-       default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_RUN);
-       default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_RUN);
-
-       if (default_calib.event_trigger !=
-           mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger)
-               IWL_ERR(mvm,
-                       "Updating the event calib for RT image: 0x%x -> 0x%x\n",
-                       mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger,
-                       default_calib.event_trigger);
-       if (default_calib.flow_trigger !=
-           mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger)
-               IWL_ERR(mvm,
-                       "Updating the flow calib for RT image: 0x%x -> 0x%x\n",
-                       mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger,
-                       default_calib.flow_trigger);
-
-       memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_REGULAR],
-              &default_calib, sizeof(struct iwl_tlv_calib_ctrl));
-       IWL_ERR(mvm,
-               "Setting uCode runtime calibs event 0x%x, trigger 0x%x\n",
-               default_calib.event_trigger,
-               default_calib.flow_trigger);
-}
-
 static int iwl_set_default_calibrations(struct iwl_mvm *mvm)
 {
        u8 cmd_raw[16]; /* holds the variable size commands */
@@ -446,8 +321,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
        ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
        WARN_ON(ret);
 
-       /* Override the calibrations from TLV and the const of fw */
-       iwl_set_default_calib_trigger(mvm);
+       /* Send TX valid antennas before triggering calibrations */
+       ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant);
+       if (ret)
+               goto error;
 
        /* WkP doesn't have all calibrations, need to set default values */
        if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
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..bdae700c769eb292223d8871b1789a46f6f13610 100644 (file)
@@ -80,7 +80,8 @@
 
 #define IWL_INVALID_MAC80211_QUEUE     0xff
 #define IWL_MVM_MAX_ADDRESSES          2
-#define IWL_RSSI_OFFSET 44
+/* RSSI offset for WkP */
+#define IWL_RSSI_OFFSET 50
 
 enum iwl_mvm_tx_fifo {
        IWL_MVM_TX_FIFO_BK = 0,
@@ -327,6 +328,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 aa59adf87db333f66b0a2e925ddd66afd574ae60..d0f9c1e0475e71659576b609b8f3365196435f02 100644 (file)
@@ -624,12 +624,8 @@ static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
        ieee80211_free_txskb(mvm->hw, skb);
 }
 
-static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
+static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
 {
-       struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
-
-       iwl_mvm_dump_nic_error_log(mvm);
-
        iwl_abort_notification_waits(&mvm->notif_wait);
 
        /*
@@ -663,9 +659,21 @@ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
        }
 }
 
+static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
+{
+       struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
+
+       iwl_mvm_dump_nic_error_log(mvm);
+
+       iwl_mvm_nic_restart(mvm);
+}
+
 static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)
 {
+       struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
+
        WARN_ON(1);
+       iwl_mvm_nic_restart(mvm);
 }
 
 static const struct iwl_op_mode_ops iwl_mvm_ops = {
index 3f40ab05bbd8181d55d4e1999ebc77f5f977b6f9..b0b190d0ec23659279f9a33e7d57b21428114f30 100644 (file)
@@ -131,33 +131,42 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm,
 static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm,
                             struct iwl_rx_phy_info *phy_info)
 {
-       u32 rssi_a, rssi_b, rssi_c, max_rssi, agc_db;
+       int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm;
+       int rssi_all_band_a, rssi_all_band_b;
+       u32 agc_a, agc_b, max_agc;
        u32 val;
 
-       /* Find max rssi among 3 possible receivers.
+       /* Find max rssi among 2 possible receivers.
         * These values are measured by the Digital Signal Processor (DSP).
         * They should stay fairly constant even as the signal strength varies,
         * if the radio's Automatic Gain Control (AGC) is working right.
         * AGC value (see below) will provide the "interesting" info.
         */
+       val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]);
+       agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS;
+       agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS;
+       max_agc = max_t(u32, agc_a, agc_b);
+
        val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]);
        rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS;
        rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS;
-       val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_C_IDX]);
-       rssi_c = (val & IWL_OFDM_RSSI_INBAND_C_MSK) >> IWL_OFDM_RSSI_C_POS;
-
-       val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]);
-       agc_db = (val & IWL_OFDM_AGC_DB_MSK) >> IWL_OFDM_AGC_DB_POS;
+       rssi_all_band_a = (val & IWL_OFDM_RSSI_ALLBAND_A_MSK) >>
+                               IWL_OFDM_RSSI_ALLBAND_A_POS;
+       rssi_all_band_b = (val & IWL_OFDM_RSSI_ALLBAND_B_MSK) >>
+                               IWL_OFDM_RSSI_ALLBAND_B_POS;
 
-       max_rssi = max_t(u32, rssi_a, rssi_b);
-       max_rssi = max_t(u32, max_rssi, rssi_c);
+       /*
+        * dBm = rssi dB - agc dB - constant.
+        * Higher AGC (higher radio gain) means lower signal.
+        */
+       rssi_a_dbm = rssi_a - IWL_RSSI_OFFSET - agc_a;
+       rssi_b_dbm = rssi_b - IWL_RSSI_OFFSET - agc_b;
+       max_rssi_dbm = max_t(int, rssi_a_dbm, rssi_b_dbm);
 
-       IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
-                       rssi_a, rssi_b, rssi_c, max_rssi, agc_db);
+       IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n",
+                       rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b);
 
-       /* dBm = max_rssi dB - agc dB - constant.
-        * Higher AGC (higher radio gain) means lower signal. */
-       return max_rssi - agc_db - IWL_RSSI_OFFSET;
+       return max_rssi_dbm;
 }
 
 /*
index 861a7f9f8e7f4c0a932e4ce71e607bdc8a3b94fa..274f44e2ef60e52d1fb39f66735c98563036449e 100644 (file)
@@ -770,6 +770,16 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
        u16 txq_id;
        int err;
 
+
+       /*
+        * If mac80211 is cleaning its state, then say that we finished since
+        * our state has been cleared anyway.
+        */
+       if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
+               ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+               return 0;
+       }
+
        spin_lock_bh(&mvmsta->lock);
 
        txq_id = tid_data->txq_id;
index 6b67ce3f679ceb8ad4907c14c32926d0828f9f75..6645efe5c03edfdc3c4523f0c06ab1d7bc0c7629 100644 (file)
@@ -607,12 +607,8 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
 
                /* Single frame failure in an AMPDU queue => send BAR */
                if (txq_id >= IWL_FIRST_AMPDU_QUEUE &&
-                   !(info->flags & IEEE80211_TX_STAT_ACK)) {
-                       /* there must be only one skb in the skb_list */
-                       WARN_ON_ONCE(skb_freed > 1 ||
-                                    !skb_queue_empty(&skbs));
+                   !(info->flags & IEEE80211_TX_STAT_ACK))
                        info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
-               }
 
                /* W/A FW bug: seq_ctl is wrong when the queue is flushed */
                if (status == TX_STATUS_FAIL_FIFO_FLUSHED) {
index aa2a39a637ddebb15e2b1f390eaa84c839af3dda..148843e7f34f26f9ea98d8ae269e366765cba115 100644 (file)
@@ -137,10 +137,6 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd)
 struct iwl_cmd_meta {
        /* only for SYNC commands, iff the reply skb is wanted */
        struct iwl_host_cmd *source;
-
-       DEFINE_DMA_UNMAP_ADDR(mapping);
-       DEFINE_DMA_UNMAP_LEN(len);
-
        u32 flags;
 };
 
@@ -182,19 +178,39 @@ 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 big the
+ * first TB must be to include the scratch buffer. Since
+ * the scratch is 4 bytes at offset 12, it's 16 now. If we
+ * make it bigger then allocations will be bigger and copy
+ * slower, so that's probably not useful.
+ */
+#define IWL_HCMD_SCRATCHBUF_SIZE       16
+
 struct iwl_pcie_txq_entry {
        struct iwl_device_cmd *cmd;
-       struct iwl_device_cmd *copy_cmd;
        struct sk_buff *skb;
        /* buffer to free after command completes */
        const void *free_buf;
        struct iwl_cmd_meta meta;
 };
 
+struct iwl_pcie_txq_scratch_buf {
+       struct iwl_cmd_header hdr;
+       u8 buf[8];
+       __le32 scratch;
+};
+
 /**
  * struct iwl_txq - Tx Queue for DMA
  * @q: generic Rx/Tx queue descriptor
  * @tfds: transmit frame descriptors (DMA memory)
+ * @scratchbufs: start of command headers, including scratch buffers, for
+ *     the writeback -- this is DMA memory and an array holding one buffer
+ *     for each command on the queue
+ * @scratchbufs_dma: DMA address for the scratchbufs start
  * @entries: transmit entries (driver state)
  * @lock: queue lock
  * @stuck_timer: timer that fires if queue gets stuck
@@ -208,6 +224,8 @@ struct iwl_pcie_txq_entry {
 struct iwl_txq {
        struct iwl_queue q;
        struct iwl_tfd *tfds;
+       struct iwl_pcie_txq_scratch_buf *scratchbufs;
+       dma_addr_t scratchbufs_dma;
        struct iwl_pcie_txq_entry *entries;
        spinlock_t lock;
        struct timer_list stuck_timer;
@@ -216,6 +234,13 @@ struct iwl_txq {
        u8 active;
 };
 
+static inline dma_addr_t
+iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)
+{
+       return txq->scratchbufs_dma +
+              sizeof(struct iwl_pcie_txq_scratch_buf) * idx;
+}
+
 /**
  * struct iwl_trans_pcie - PCIe transport specific data
  * @rxq: all the RX queue data
index b0ae06d2456f1c388ba47fcdbb88f74063ea1162..567e67ad1f617682cbba7a90f2ca95e53eb07eea 100644 (file)
@@ -637,22 +637,14 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
                index = SEQ_TO_INDEX(sequence);
                cmd_index = get_cmd_index(&txq->q, index);
 
-               if (reclaim) {
-                       struct iwl_pcie_txq_entry *ent;
-                       ent = &txq->entries[cmd_index];
-                       cmd = ent->copy_cmd;
-                       WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD);
-               } else {
+               if (reclaim)
+                       cmd = txq->entries[cmd_index].cmd;
+               else
                        cmd = NULL;
-               }
 
                err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);
 
                if (reclaim) {
-                       /* The original command isn't needed any more */
-                       kfree(txq->entries[cmd_index].copy_cmd);
-                       txq->entries[cmd_index].copy_cmd = NULL;
-                       /* nor is the duplicated part of the command */
                        kfree(txq->entries[cmd_index].free_buf);
                        txq->entries[cmd_index].free_buf = NULL;
                }
index 8e9e3212fe784bcc8c3aea8007111669bee2441b..8595c16f74deb8bdcf531725e3c65c0986d58745 100644 (file)
@@ -191,12 +191,9 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
        }
 
        for (i = q->read_ptr; i != q->write_ptr;
-            i = iwl_queue_inc_wrap(i, q->n_bd)) {
-               struct iwl_tx_cmd *tx_cmd =
-                       (struct iwl_tx_cmd *)txq->entries[i].cmd->payload;
+            i = iwl_queue_inc_wrap(i, q->n_bd))
                IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
-                       get_unaligned_le32(&tx_cmd->scratch));
-       }
+                       le32_to_cpu(txq->scratchbufs[i].scratch));
 
        iwl_op_mode_nic_error(trans->op_mode);
 }
@@ -367,8 +364,8 @@ static inline u8 iwl_pcie_tfd_get_num_tbs(struct iwl_tfd *tfd)
 }
 
 static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
-                              struct iwl_cmd_meta *meta, struct iwl_tfd *tfd,
-                              enum dma_data_direction dma_dir)
+                              struct iwl_cmd_meta *meta,
+                              struct iwl_tfd *tfd)
 {
        int i;
        int num_tbs;
@@ -382,17 +379,12 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
                return;
        }
 
-       /* Unmap tx_cmd */
-       if (num_tbs)
-               dma_unmap_single(trans->dev,
-                               dma_unmap_addr(meta, mapping),
-                               dma_unmap_len(meta, len),
-                               DMA_BIDIRECTIONAL);
+       /* first TB is never freed - it's the scratchbuf data */
 
-       /* Unmap chunks, if any. */
        for (i = 1; i < num_tbs; i++)
                dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i),
-                                iwl_pcie_tfd_tb_get_len(tfd, i), dma_dir);
+                                iwl_pcie_tfd_tb_get_len(tfd, i),
+                                DMA_TO_DEVICE);
 
        tfd->num_tbs = 0;
 }
@@ -406,8 +398,7 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans,
  * Does NOT advance any TFD circular buffer read/write indexes
  * Does NOT free the TFD itself (which is within circular buffer)
  */
-static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq,
-                                 enum dma_data_direction dma_dir)
+static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq)
 {
        struct iwl_tfd *tfd_tmp = txq->tfds;
 
@@ -418,8 +409,7 @@ static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq,
        lockdep_assert_held(&txq->lock);
 
        /* We have only q->n_window txq->entries, but we use q->n_bd tfds */
-       iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr],
-                          dma_dir);
+       iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr]);
 
        /* free SKB */
        if (txq->entries) {
@@ -479,6 +469,7 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans,
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX;
+       size_t scratchbuf_sz;
        int i;
 
        if (WARN_ON(txq->entries || txq->tfds))
@@ -514,9 +505,25 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans,
                IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz);
                goto error;
        }
+
+       BUILD_BUG_ON(IWL_HCMD_SCRATCHBUF_SIZE != sizeof(*txq->scratchbufs));
+       BUILD_BUG_ON(offsetof(struct iwl_pcie_txq_scratch_buf, scratch) !=
+                       sizeof(struct iwl_cmd_header) +
+                       offsetof(struct iwl_tx_cmd, scratch));
+
+       scratchbuf_sz = sizeof(*txq->scratchbufs) * slots_num;
+
+       txq->scratchbufs = dma_alloc_coherent(trans->dev, scratchbuf_sz,
+                                             &txq->scratchbufs_dma,
+                                             GFP_KERNEL);
+       if (!txq->scratchbufs)
+               goto err_free_tfds;
+
        txq->q.id = txq_id;
 
        return 0;
+err_free_tfds:
+       dma_free_coherent(trans->dev, tfd_sz, txq->tfds, txq->q.dma_addr);
 error:
        if (txq->entries && txq_id == trans_pcie->cmd_queue)
                for (i = 0; i < slots_num; i++)
@@ -565,22 +572,13 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        struct iwl_txq *txq = &trans_pcie->txq[txq_id];
        struct iwl_queue *q = &txq->q;
-       enum dma_data_direction dma_dir;
 
        if (!q->n_bd)
                return;
 
-       /* In the command queue, all the TBs are mapped as BIDI
-        * so unmap them as such.
-        */
-       if (txq_id == trans_pcie->cmd_queue)
-               dma_dir = DMA_BIDIRECTIONAL;
-       else
-               dma_dir = DMA_TO_DEVICE;
-
        spin_lock_bh(&txq->lock);
        while (q->write_ptr != q->read_ptr) {
-               iwl_pcie_txq_free_tfd(trans, txq, dma_dir);
+               iwl_pcie_txq_free_tfd(trans, txq);
                q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
        }
        spin_unlock_bh(&txq->lock);
@@ -610,7 +608,6 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
        if (txq_id == trans_pcie->cmd_queue)
                for (i = 0; i < txq->q.n_window; i++) {
                        kfree(txq->entries[i].cmd);
-                       kfree(txq->entries[i].copy_cmd);
                        kfree(txq->entries[i].free_buf);
                }
 
@@ -619,6 +616,10 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
                dma_free_coherent(dev, sizeof(struct iwl_tfd) *
                                  txq->q.n_bd, txq->tfds, txq->q.dma_addr);
                txq->q.dma_addr = 0;
+
+               dma_free_coherent(dev,
+                                 sizeof(*txq->scratchbufs) * txq->q.n_window,
+                                 txq->scratchbufs, txq->scratchbufs_dma);
        }
 
        kfree(txq->entries);
@@ -962,7 +963,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
 
                iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq);
 
-               iwl_pcie_txq_free_tfd(trans, txq, DMA_TO_DEVICE);
+               iwl_pcie_txq_free_tfd(trans, txq);
        }
 
        iwl_pcie_txq_progress(trans_pcie, txq);
@@ -1152,20 +1153,37 @@ 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, scratch_size;
        bool had_nocopy = false;
        int i;
        u32 cmd_pos;
+       const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD];
+       u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD];
 
        copy_size = sizeof(out_cmd->hdr);
        cmd_size = sizeof(out_cmd->hdr);
 
        /* need one for the header if the first is NOCOPY */
-       BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1);
+       BUILD_BUG_ON(IWL_MAX_CMD_TBS_PER_TFD > IWL_NUM_OF_TBS - 1);
+
+       for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
+               cmddata[i] = cmd->data[i];
+               cmdlen[i] = cmd->len[i];
 
-       for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
                if (!cmd->len[i])
                        continue;
+
+               /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */
+               if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) {
+                       int copy = IWL_HCMD_SCRATCHBUF_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 +1203,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 +1213,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,30 +1260,30 @@ 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);
-       for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
-               if (!cmd->len[i])
+       copy_size = sizeof(out_cmd->hdr);
+       for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; 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];
-       }
 
-       WARN_ON_ONCE(txq->entries[idx].copy_cmd);
+               /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */
+               if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) {
+                       copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size;
 
-       /*
-        * since out_cmd will be the source address of the FH, it will write
-        * the retry count there. So when the user needs to receivce the HCMD
-        * that corresponds to the response in the response handler, it needs
-        * to set CMD_WANT_HCMD.
-        */
-       if (cmd->flags & CMD_WANT_HCMD) {
-               txq->entries[idx].copy_cmd =
-                       kmemdup(out_cmd, cmd_pos, GFP_ATOMIC);
-               if (unlikely(!txq->entries[idx].copy_cmd)) {
-                       idx = -ENOMEM;
-                       goto out;
+                       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;
                }
        }
 
@@ -1275,22 +1293,35 @@ 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,
-                                  DMA_BIDIRECTIONAL);
-       if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
-               idx = -ENOMEM;
-               goto out;
-       }
-
-       dma_unmap_addr_set(out_meta, mapping, phys_addr);
-       dma_unmap_len_set(out_meta, len, copy_size);
+       /* start the TFD with the scratchbuf */
+       scratch_size = min_t(int, copy_size, IWL_HCMD_SCRATCHBUF_SIZE);
+       memcpy(&txq->scratchbufs[q->write_ptr], &out_cmd->hdr, scratch_size);
+       iwl_pcie_txq_build_tfd(trans, txq,
+                              iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr),
+                              scratch_size, 1);
+
+       /* map first command fragment, if any remains */
+       if (copy_size > scratch_size) {
+               phys_addr = dma_map_single(trans->dev,
+                                          ((u8 *)&out_cmd->hdr) + scratch_size,
+                                          copy_size - scratch_size,
+                                          DMA_TO_DEVICE);
+               if (dma_mapping_error(trans->dev, phys_addr)) {
+                       iwl_pcie_tfd_unmap(trans, out_meta,
+                                          &txq->tfds[q->write_ptr]);
+                       idx = -ENOMEM;
+                       goto out;
+               }
 
-       iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1);
+               iwl_pcie_txq_build_tfd(trans, txq, phys_addr,
+                                      copy_size - scratch_size, 0);
+       }
 
-       for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
-               const void *data = cmd->data[i];
+       /* map the remaining (adjusted) nocopy/dup fragments */
+       for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; 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,16 +1329,15 @@ 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_TO_DEVICE);
                if (dma_mapping_error(trans->dev, phys_addr)) {
                        iwl_pcie_tfd_unmap(trans, out_meta,
-                                          &txq->tfds[q->write_ptr],
-                                          DMA_BIDIRECTIONAL);
+                                          &txq->tfds[q->write_ptr]);
                        idx = -ENOMEM;
                        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 +1347,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)
@@ -1377,7 +1406,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
        cmd = txq->entries[cmd_index].cmd;
        meta = &txq->entries[cmd_index].meta;
 
-       iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL);
+       iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index]);
 
        /* Input error checking is done when commands are added to queue. */
        if (meta->flags & CMD_WANT_SKB) {
@@ -1556,10 +1585,9 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
        struct iwl_cmd_meta *out_meta;
        struct iwl_txq *txq;
        struct iwl_queue *q;
-       dma_addr_t phys_addr = 0;
-       dma_addr_t txcmd_phys;
-       dma_addr_t scratch_phys;
-       u16 len, firstlen, secondlen;
+       dma_addr_t tb0_phys, tb1_phys, scratch_phys;
+       void *tb1_addr;
+       u16 len, tb1_len, tb2_len;
        u8 wait_write_ptr = 0;
        __le16 fc = hdr->frame_control;
        u8 hdr_len = ieee80211_hdrlen(fc);
@@ -1597,85 +1625,80 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
                cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
                            INDEX_TO_SEQ(q->write_ptr)));
 
+       tb0_phys = iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr);
+       scratch_phys = tb0_phys + sizeof(struct iwl_cmd_header) +
+                      offsetof(struct iwl_tx_cmd, scratch);
+
+       tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
+       tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
+
        /* Set up first empty entry in queue's array of Tx/cmd buffers */
        out_meta = &txq->entries[q->write_ptr].meta;
 
        /*
-        * Use the first empty entry in this queue's command buffer array
-        * to contain the Tx command and MAC header concatenated together
-        * (payload data will be in another buffer).
-        * Size of this varies, due to varying MAC header length.
-        * If end is not dword aligned, we'll have 2 extra bytes at the end
-        * of the MAC header (device reads on dword boundaries).
-        * We'll tell device about this padding later.
+        * The second TB (tb1) points to the remainder of the TX command
+        * and the 802.11 header - dword aligned size
+        * (This calculation modifies the TX command, so do it before the
+        * setup of the first TB)
         */
-       len = sizeof(struct iwl_tx_cmd) +
-               sizeof(struct iwl_cmd_header) + hdr_len;
-       firstlen = (len + 3) & ~3;
+       len = sizeof(struct iwl_tx_cmd) + sizeof(struct iwl_cmd_header) +
+             hdr_len - IWL_HCMD_SCRATCHBUF_SIZE;
+       tb1_len = (len + 3) & ~3;
 
        /* Tell NIC about any 2-byte padding after MAC header */
-       if (firstlen != len)
+       if (tb1_len != len)
                tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
 
-       /* Physical address of this Tx command's header (not MAC header!),
-        * within command buffer array. */
-       txcmd_phys = dma_map_single(trans->dev,
-                                   &dev_cmd->hdr, firstlen,
-                                   DMA_BIDIRECTIONAL);
-       if (unlikely(dma_mapping_error(trans->dev, txcmd_phys)))
-               goto out_err;
-       dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
-       dma_unmap_len_set(out_meta, len, firstlen);
+       /* The first TB points to the scratchbuf data - min_copy bytes */
+       memcpy(&txq->scratchbufs[q->write_ptr], &dev_cmd->hdr,
+              IWL_HCMD_SCRATCHBUF_SIZE);
+       iwl_pcie_txq_build_tfd(trans, txq, tb0_phys,
+                              IWL_HCMD_SCRATCHBUF_SIZE, 1);
 
-       if (!ieee80211_has_morefrags(fc)) {
-               txq->need_update = 1;
-       } else {
-               wait_write_ptr = 1;
-               txq->need_update = 0;
-       }
+       /* there must be data left over for TB1 or this code must be changed */
+       BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_HCMD_SCRATCHBUF_SIZE);
+
+       /* map the data for TB1 */
+       tb1_addr = ((u8 *)&dev_cmd->hdr) + IWL_HCMD_SCRATCHBUF_SIZE;
+       tb1_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE);
+       if (unlikely(dma_mapping_error(trans->dev, tb1_phys)))
+               goto out_err;
+       iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, 0);
 
-       /* Set up TFD's 2nd entry to point directly to remainder of skb,
-        * if any (802.11 null frames have no payload). */
-       secondlen = skb->len - hdr_len;
-       if (secondlen > 0) {
-               phys_addr = dma_map_single(trans->dev, skb->data + hdr_len,
-                                          secondlen, DMA_TO_DEVICE);
-               if (unlikely(dma_mapping_error(trans->dev, phys_addr))) {
-                       dma_unmap_single(trans->dev,
-                                        dma_unmap_addr(out_meta, mapping),
-                                        dma_unmap_len(out_meta, len),
-                                        DMA_BIDIRECTIONAL);
+       /*
+        * Set up TFD's third entry to point directly to remainder
+        * of skb, if any (802.11 null frames have no payload).
+        */
+       tb2_len = skb->len - hdr_len;
+       if (tb2_len > 0) {
+               dma_addr_t tb2_phys = dma_map_single(trans->dev,
+                                                    skb->data + hdr_len,
+                                                    tb2_len, DMA_TO_DEVICE);
+               if (unlikely(dma_mapping_error(trans->dev, tb2_phys))) {
+                       iwl_pcie_tfd_unmap(trans, out_meta,
+                                          &txq->tfds[q->write_ptr]);
                        goto out_err;
                }
+               iwl_pcie_txq_build_tfd(trans, txq, tb2_phys, tb2_len, 0);
        }
 
-       /* Attach buffers to TFD */
-       iwl_pcie_txq_build_tfd(trans, txq, txcmd_phys, firstlen, 1);
-       if (secondlen > 0)
-               iwl_pcie_txq_build_tfd(trans, txq, phys_addr, secondlen, 0);
-
-       scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
-                               offsetof(struct iwl_tx_cmd, scratch);
-
-       /* take back ownership of DMA buffer to enable update */
-       dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen,
-                               DMA_BIDIRECTIONAL);
-       tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
-       tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
-
        /* Set up entry for this TFD in Tx byte-count array */
        iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len));
 
-       dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen,
-                                  DMA_BIDIRECTIONAL);
-
        trace_iwlwifi_dev_tx(trans->dev, skb,
                             &txq->tfds[txq->q.write_ptr],
                             sizeof(struct iwl_tfd),
-                            &dev_cmd->hdr, firstlen,
-                            skb->data + hdr_len, secondlen);
+                            &dev_cmd->hdr, IWL_HCMD_SCRATCHBUF_SIZE + tb1_len,
+                            skb->data + hdr_len, tb2_len);
        trace_iwlwifi_dev_tx_data(trans->dev, skb,
-                                 skb->data + hdr_len, secondlen);
+                                 skb->data + hdr_len, tb2_len);
+
+       if (!ieee80211_has_morefrags(fc)) {
+               txq->need_update = 1;
+       } else {
+               wait_write_ptr = 1;
+               txq->need_update = 0;
+       }
 
        /* start timer if queue currently empty */
        if (txq->need_update && q->read_ptr == q->write_ptr &&
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 57233c8859989d15a2a6ce5b041c1363d07374c2..8f87fec27ce78ffa9c191bf104cb9326368f88fc 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/delay.h>
+#include <linux/clk.h>
 #include <linux/gfp.h>
 #include <linux/module.h>
 
@@ -41,6 +42,7 @@ struct rtc_plat_data {
        struct rtc_device *rtc;
        void __iomem *ioaddr;
        int             irq;
+       struct clk      *clk;
 };
 
 static int mv_rtc_set_time(struct device *dev, struct rtc_time *tm)
@@ -221,6 +223,7 @@ static int mv_rtc_probe(struct platform_device *pdev)
        struct rtc_plat_data *pdata;
        resource_size_t size;
        u32 rtc_time;
+       int ret = 0;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res)
@@ -239,11 +242,17 @@ static int mv_rtc_probe(struct platform_device *pdev)
        if (!pdata->ioaddr)
                return -ENOMEM;
 
+       pdata->clk = devm_clk_get(&pdev->dev, NULL);
+       /* Not all SoCs require a clock.*/
+       if (!IS_ERR(pdata->clk))
+               clk_prepare_enable(pdata->clk);
+
        /* make sure the 24 hours mode is enabled */
        rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
        if (rtc_time & RTC_HOURS_12H_MODE) {
                dev_err(&pdev->dev, "24 Hours mode not supported.\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out;
        }
 
        /* make sure it is actually functional */
@@ -252,7 +261,8 @@ static int mv_rtc_probe(struct platform_device *pdev)
                rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS);
                if (rtc_time == 0x01000000) {
                        dev_err(&pdev->dev, "internal RTC not ticking\n");
-                       return -ENODEV;
+                       ret = -ENODEV;
+                       goto out;
                }
        }
 
@@ -268,8 +278,10 @@ static int mv_rtc_probe(struct platform_device *pdev)
        } else
                pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
                                                 &mv_rtc_ops, THIS_MODULE);
-       if (IS_ERR(pdata->rtc))
-               return PTR_ERR(pdata->rtc);
+       if (IS_ERR(pdata->rtc)) {
+               ret = PTR_ERR(pdata->rtc);
+               goto out;
+       }
 
        if (pdata->irq >= 0) {
                writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS);
@@ -282,6 +294,11 @@ static int mv_rtc_probe(struct platform_device *pdev)
        }
 
        return 0;
+out:
+       if (!IS_ERR(pdata->clk))
+               clk_disable_unprepare(pdata->clk);
+
+       return ret;
 }
 
 static int __exit mv_rtc_remove(struct platform_device *pdev)
@@ -292,6 +309,9 @@ static int __exit mv_rtc_remove(struct platform_device *pdev)
                device_init_wakeup(&pdev->dev, 0);
 
        rtc_device_unregister(pdata->rtc);
+       if (!IS_ERR(pdata->clk))
+               clk_disable_unprepare(pdata->clk);
+
        return 0;
 }
 
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 192cf088f834a07c2388b50f0cc357e9f9298d36..57b4519047911dc36000580b87296e1716ebf5ed 100644 (file)
@@ -947,12 +947,13 @@ static int dt9812_di_rinsn(struct comedi_device *dev,
                           unsigned int *data)
 {
        struct comedi_dt9812 *devpriv = dev->private;
+       unsigned int channel = CR_CHAN(insn->chanspec);
        int n;
        u8 bits = 0;
 
        dt9812_digital_in(devpriv->slot, &bits);
        for (n = 0; n < insn->n; n++)
-               data[n] = ((1 << insn->chanspec) & bits) != 0;
+               data[n] = ((1 << channel) & bits) != 0;
        return n;
 }
 
@@ -961,12 +962,13 @@ static int dt9812_do_winsn(struct comedi_device *dev,
                           unsigned int *data)
 {
        struct comedi_dt9812 *devpriv = dev->private;
+       unsigned int channel = CR_CHAN(insn->chanspec);
        int n;
        u8 bits = 0;
 
        dt9812_digital_out_shadow(devpriv->slot, &bits);
        for (n = 0; n < insn->n; n++) {
-               u8 mask = 1 << insn->chanspec;
+               u8 mask = 1 << channel;
 
                bits &= ~mask;
                if (data[n])
@@ -981,13 +983,13 @@ static int dt9812_ai_rinsn(struct comedi_device *dev,
                           unsigned int *data)
 {
        struct comedi_dt9812 *devpriv = dev->private;
+       unsigned int channel = CR_CHAN(insn->chanspec);
        int n;
 
        for (n = 0; n < insn->n; n++) {
                u16 value = 0;
 
-               dt9812_analog_in(devpriv->slot, insn->chanspec, &value,
-                                DT9812_GAIN_1);
+               dt9812_analog_in(devpriv->slot, channel, &value, DT9812_GAIN_1);
                data[n] = value;
        }
        return n;
@@ -998,12 +1000,13 @@ static int dt9812_ao_rinsn(struct comedi_device *dev,
                           unsigned int *data)
 {
        struct comedi_dt9812 *devpriv = dev->private;
+       unsigned int channel = CR_CHAN(insn->chanspec);
        int n;
        u16 value;
 
        for (n = 0; n < insn->n; n++) {
                value = 0;
-               dt9812_analog_out_shadow(devpriv->slot, insn->chanspec, &value);
+               dt9812_analog_out_shadow(devpriv->slot, channel, &value);
                data[n] = value;
        }
        return n;
@@ -1014,10 +1017,11 @@ static int dt9812_ao_winsn(struct comedi_device *dev,
                           unsigned int *data)
 {
        struct comedi_dt9812 *devpriv = dev->private;
+       unsigned int channel = CR_CHAN(insn->chanspec);
        int n;
 
        for (n = 0; n < insn->n; n++)
-               dt9812_analog_out(devpriv->slot, insn->chanspec, data[n]);
+               dt9812_analog_out(devpriv->slot, channel, data[n]);
        return n;
 }
 
index 1a0062a04456c54c517acc7d73454014555a7611..6aac1f60bc42c1cc927cd2a9930aa1bc356f28cb 100644 (file)
@@ -730,10 +730,14 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
 static int usbduxsub_start(struct usbduxsub *usbduxsub)
 {
        int errcode = 0;
-       uint8_t local_transfer_buffer[16];
+       uint8_t *local_transfer_buffer;
+
+       local_transfer_buffer = kmalloc(1, GFP_KERNEL);
+       if (!local_transfer_buffer)
+               return -ENOMEM;
 
        /* 7f92 to zero */
-       local_transfer_buffer[0] = 0;
+       *local_transfer_buffer = 0;
        errcode = usb_control_msg(usbduxsub->usbdev,
                                  /* create a pipe for a control transfer */
                                  usb_sndctrlpipe(usbduxsub->usbdev, 0),
@@ -751,22 +755,25 @@ static int usbduxsub_start(struct usbduxsub *usbduxsub)
                                  1,
                                  /* Timeout */
                                  BULK_TIMEOUT);
-       if (errcode < 0) {
+       if (errcode < 0)
                dev_err(&usbduxsub->interface->dev,
                        "comedi_: control msg failed (start)\n");
-               return errcode;
-       }
-       return 0;
+
+       kfree(local_transfer_buffer);
+       return errcode;
 }
 
 static int usbduxsub_stop(struct usbduxsub *usbduxsub)
 {
        int errcode = 0;
+       uint8_t *local_transfer_buffer;
 
-       uint8_t local_transfer_buffer[16];
+       local_transfer_buffer = kmalloc(1, GFP_KERNEL);
+       if (!local_transfer_buffer)
+               return -ENOMEM;
 
        /* 7f92 to one */
-       local_transfer_buffer[0] = 1;
+       *local_transfer_buffer = 1;
        errcode = usb_control_msg(usbduxsub->usbdev,
                                  usb_sndctrlpipe(usbduxsub->usbdev, 0),
                                  /* bRequest, "Firmware" */
@@ -781,12 +788,12 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub)
                                  1,
                                  /* Timeout */
                                  BULK_TIMEOUT);
-       if (errcode < 0) {
+       if (errcode < 0)
                dev_err(&usbduxsub->interface->dev,
                        "comedi_: control msg failed (stop)\n");
-               return errcode;
-       }
-       return 0;
+
+       kfree(local_transfer_buffer);
+       return errcode;
 }
 
 static int usbduxsub_upload(struct usbduxsub *usbduxsub,
index 4bf5dd094dc9da043b2aea8302c6638e229cf926..1ba0e3df492d1e9ceeedcebe4af3e85b82a08491 100644 (file)
@@ -436,10 +436,14 @@ static void usbduxfastsub_ai_Irq(struct urb *urb)
 static int usbduxfastsub_start(struct usbduxfastsub_s *udfs)
 {
        int ret;
-       unsigned char local_transfer_buffer[16];
+       unsigned char *local_transfer_buffer;
+
+       local_transfer_buffer = kmalloc(1, GFP_KERNEL);
+       if (!local_transfer_buffer)
+               return -ENOMEM;
 
        /* 7f92 to zero */
-       local_transfer_buffer[0] = 0;
+       *local_transfer_buffer = 0;
        /* bRequest, "Firmware" */
        ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0),
                              USBDUXFASTSUB_FIRMWARE,
@@ -450,22 +454,25 @@ static int usbduxfastsub_start(struct usbduxfastsub_s *udfs)
                              local_transfer_buffer,
                              1,      /* Length */
                              EZTIMEOUT);    /* Timeout */
-       if (ret < 0) {
+       if (ret < 0)
                dev_err(&udfs->interface->dev,
                        "control msg failed (start)\n");
-               return ret;
-       }
 
-       return 0;
+       kfree(local_transfer_buffer);
+       return ret;
 }
 
 static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
 {
        int ret;
-       unsigned char local_transfer_buffer[16];
+       unsigned char *local_transfer_buffer;
+
+       local_transfer_buffer = kmalloc(1, GFP_KERNEL);
+       if (!local_transfer_buffer)
+               return -ENOMEM;
 
        /* 7f92 to one */
-       local_transfer_buffer[0] = 1;
+       *local_transfer_buffer = 1;
        /* bRequest, "Firmware" */
        ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0),
                              USBDUXFASTSUB_FIRMWARE,
@@ -474,13 +481,12 @@ static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
                              0x0000,   /* Index */
                              local_transfer_buffer, 1, /* Length */
                              EZTIMEOUT);       /* Timeout */
-       if (ret < 0) {
+       if (ret < 0)
                dev_err(&udfs->interface->dev,
                        "control msg failed (stop)\n");
-               return ret;
-       }
 
-       return 0;
+       kfree(local_transfer_buffer);
+       return ret;
 }
 
 static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs,
index d066351a71b2793d4f1ad60dd27e8db7dd0ea0e7..a728c8fc32a270e4a8963dc0eca3e14799fd6602 100644 (file)
@@ -681,7 +681,11 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
 static int usbduxsub_start(struct usbduxsub *usbduxsub)
 {
        int errcode = 0;
-       uint8_t local_transfer_buffer[16];
+       uint8_t *local_transfer_buffer;
+
+       local_transfer_buffer = kmalloc(16, GFP_KERNEL);
+       if (!local_transfer_buffer)
+               return -ENOMEM;
 
        /* 7f92 to zero */
        local_transfer_buffer[0] = 0;
@@ -702,19 +706,22 @@ static int usbduxsub_start(struct usbduxsub *usbduxsub)
                                  1,
                                  /* Timeout */
                                  BULK_TIMEOUT);
-       if (errcode < 0) {
+       if (errcode < 0)
                dev_err(&usbduxsub->interface->dev,
                        "comedi_: control msg failed (start)\n");
-               return errcode;
-       }
-       return 0;
+
+       kfree(local_transfer_buffer);
+       return errcode;
 }
 
 static int usbduxsub_stop(struct usbduxsub *usbduxsub)
 {
        int errcode = 0;
+       uint8_t *local_transfer_buffer;
 
-       uint8_t local_transfer_buffer[16];
+       local_transfer_buffer = kmalloc(16, GFP_KERNEL);
+       if (!local_transfer_buffer)
+               return -ENOMEM;
 
        /* 7f92 to one */
        local_transfer_buffer[0] = 1;
@@ -732,12 +739,12 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub)
                                  1,
                                  /* Timeout */
                                  BULK_TIMEOUT);
-       if (errcode < 0) {
+       if (errcode < 0)
                dev_err(&usbduxsub->interface->dev,
                        "comedi_: control msg failed (stop)\n");
-               return errcode;
-       }
-       return 0;
+
+       kfree(local_transfer_buffer);
+       return errcode;
 }
 
 static int usbduxsub_upload(struct usbduxsub *usbduxsub,
index 4b3a019409b5793632efa538cdcf65e0030f217f..b028b0d1317b8c4d89967c64bd5d5e20cdfa9f35 100644 (file)
@@ -483,17 +483,6 @@ static int ipu_get_resources(struct ipu_crtc *ipu_crtc,
                goto err_out;
        }
 
-       ipu_crtc->irq = ipu_idmac_channel_irq(ipu, ipu_crtc->ipu_ch,
-                       IPU_IRQ_EOF);
-       ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0,
-                       "imx_drm", ipu_crtc);
-       if (ret < 0) {
-               dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
-               goto err_out;
-       }
-
-       disable_irq(ipu_crtc->irq);
-
        return 0;
 err_out:
        ipu_put_resources(ipu_crtc);
@@ -504,6 +493,7 @@ err_out:
 static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
                struct ipu_client_platformdata *pdata)
 {
+       struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
        int ret;
 
        ret = ipu_get_resources(ipu_crtc, pdata);
@@ -522,6 +512,17 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
                goto err_put_resources;
        }
 
+       ipu_crtc->irq = ipu_idmac_channel_irq(ipu, ipu_crtc->ipu_ch,
+                       IPU_IRQ_EOF);
+       ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0,
+                       "imx_drm", ipu_crtc);
+       if (ret < 0) {
+               dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
+               goto err_put_resources;
+       }
+
+       disable_irq(ipu_crtc->irq);
+
        return 0;
 
 err_put_resources:
index db1da28cecba84d4800363df964647e85b8177c9..be26917a68968897758d0ce70fbd56ebb976f484 100644 (file)
@@ -76,37 +76,28 @@ int drv_insert_node_res_element(void *hnode, void *node_resource,
        struct node_res_object **node_res_obj =
            (struct node_res_object **)node_resource;
        struct process_context *ctxt = (struct process_context *)process_ctxt;
-       int status = 0;
        int retval;
 
        *node_res_obj = kzalloc(sizeof(struct node_res_object), GFP_KERNEL);
-       if (!*node_res_obj) {
-               status = -ENOMEM;
-               goto func_end;
-       }
+       if (!*node_res_obj)
+               return -ENOMEM;
 
        (*node_res_obj)->node = hnode;
-       retval = idr_get_new(ctxt->node_id, *node_res_obj,
-                                               &(*node_res_obj)->id);
-       if (retval == -EAGAIN) {
-               if (!idr_pre_get(ctxt->node_id, GFP_KERNEL)) {
-                       pr_err("%s: OUT OF MEMORY\n", __func__);
-                       status = -ENOMEM;
-                       goto func_end;
-               }
-
-               retval = idr_get_new(ctxt->node_id, *node_res_obj,
-                                               &(*node_res_obj)->id);
+       retval = idr_alloc(ctxt->node_id, *node_res_obj, 0, 0, GFP_KERNEL);
+       if (retval >= 0) {
+               (*node_res_obj)->id = retval;
+               return 0;
        }
-       if (retval) {
+
+       kfree(*node_res_obj);
+
+       if (retval == -ENOSPC) {
                pr_err("%s: FAILED, IDR is FULL\n", __func__);
-               status = -EFAULT;
+               return -EFAULT;
+       } else {
+               pr_err("%s: OUT OF MEMORY\n", __func__);
+               return -ENOMEM;
        }
-func_end:
-       if (status)
-               kfree(*node_res_obj);
-
-       return status;
 }
 
 /* Release all Node resources and its context
@@ -201,35 +192,26 @@ int drv_proc_insert_strm_res_element(void *stream_obj,
        struct strm_res_object **pstrm_res =
            (struct strm_res_object **)strm_res;
        struct process_context *ctxt = (struct process_context *)process_ctxt;
-       int status = 0;
        int retval;
 
        *pstrm_res = kzalloc(sizeof(struct strm_res_object), GFP_KERNEL);
-       if (*pstrm_res == NULL) {
-               status = -EFAULT;
-               goto func_end;
-       }
+       if (*pstrm_res == NULL)
+               return -EFAULT;
 
        (*pstrm_res)->stream = stream_obj;
-       retval = idr_get_new(ctxt->stream_id, *pstrm_res,
-                                               &(*pstrm_res)->id);
-       if (retval == -EAGAIN) {
-               if (!idr_pre_get(ctxt->stream_id, GFP_KERNEL)) {
-                       pr_err("%s: OUT OF MEMORY\n", __func__);
-                       status = -ENOMEM;
-                       goto func_end;
-               }
-
-               retval = idr_get_new(ctxt->stream_id, *pstrm_res,
-                                               &(*pstrm_res)->id);
+       retval = idr_alloc(ctxt->stream_id, *pstrm_res, 0, 0, GFP_KERNEL);
+       if (retval >= 0) {
+               (*pstrm_res)->id = retval;
+               return 0;
        }
-       if (retval) {
+
+       if (retval == -ENOSPC) {
                pr_err("%s: FAILED, IDR is FULL\n", __func__);
-               status = -EPERM;
+               return -EPERM;
+       } else {
+               pr_err("%s: OUT OF MEMORY\n", __func__);
+               return -ENOMEM;
        }
-
-func_end:
-       return status;
 }
 
 static int drv_proc_free_strm_res(int id, void *p, void *process_ctxt)
index 22918a106d7365df4e1f1dbd06bd975c7f9c41d1..d2479b766450e69e81d198ad768b5564ad3f6336 100644 (file)
@@ -790,7 +790,7 @@ u64 CARDqGetNextTBTT(u64 qwTSF, WORD wBeaconInterval)
        if ((~uLowNextTBTT) < uLowRemain)
                qwTSF = ((qwTSF >> 32) + 1) << 32;
 
-       qwTSF = (qwTSF & 0xffffffff00000000UL) |
+       qwTSF = (qwTSF & 0xffffffff00000000ULL) |
                (u64)(uLowNextTBTT + uLowRemain);
 
     return (qwTSF);
index d5f53e1a74a2e8509e5e3f28eb77b17fa8943204..a5063a6f64d9f669e59eb08167a1ef0e93ec277d 100644 (file)
@@ -669,8 +669,6 @@ static int vt6656_suspend(struct usb_interface *intf, pm_message_t message)
        if (device->flags & DEVICE_FLAGS_OPENED)
                device_close(device->dev);
 
-       usb_put_dev(interface_to_usbdev(intf));
-
        return 0;
 }
 
@@ -681,8 +679,6 @@ static int vt6656_resume(struct usb_interface *intf)
        if (!device || !device->dev)
                return -ENODEV;
 
-       usb_get_dev(interface_to_usbdev(intf));
-
        if (!(device->flags & DEVICE_FLAGS_OPENED))
                device_open(device->dev);
 
index aa2a1a763aa41440a1663e0c5e8b45153294708c..f6e1e5209d88586f6e33fc43138bed199fb239af 100644 (file)
@@ -300,27 +300,22 @@ static u8 r2net_num_from_nn(struct r2net_node *nn)
 
 static int r2net_prep_nsw(struct r2net_node *nn, struct r2net_status_wait *nsw)
 {
-       int ret = 0;
+       int ret;
 
-       do {
-               if (!idr_pre_get(&nn->nn_status_idr, GFP_ATOMIC)) {
-                       ret = -EAGAIN;
-                       break;
-               }
-               spin_lock(&nn->nn_lock);
-               ret = idr_get_new(&nn->nn_status_idr, nsw, &nsw->ns_id);
-               if (ret == 0)
-                       list_add_tail(&nsw->ns_node_item,
-                                     &nn->nn_status_list);
-               spin_unlock(&nn->nn_lock);
-       } while (ret == -EAGAIN);
+       spin_lock(&nn->nn_lock);
+       ret = idr_alloc(&nn->nn_status_idr, nsw, 0, 0, GFP_ATOMIC);
+       if (ret >= 0) {
+               nsw->ns_id = ret;
+               list_add_tail(&nsw->ns_node_item, &nn->nn_status_list);
+       }
+       spin_unlock(&nn->nn_lock);
 
-       if (ret == 0)  {
+       if (ret >= 0) {
                init_waitqueue_head(&nsw->ns_wq);
                nsw->ns_sys_status = R2NET_ERR_NONE;
                nsw->ns_status = 0;
+               return 0;
        }
-
        return ret;
 }
 
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 0efc815a496869fbe80cec247fb99af9286105f9..cf6a5383748aa6cf468a76e72e1c575497031eed 100644 (file)
@@ -301,7 +301,28 @@ static const struct serial8250_config uart_config[] = {
        },
        [PORT_8250_CIR] = {
                .name           = "CIR port"
-       }
+       },
+       [PORT_ALTR_16550_F32] = {
+               .name           = "Altera 16550 FIFO32",
+               .fifo_size      = 32,
+               .tx_loadsz      = 32,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
+       },
+       [PORT_ALTR_16550_F64] = {
+               .name           = "Altera 16550 FIFO64",
+               .fifo_size      = 64,
+               .tx_loadsz      = 64,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
+       },
+       [PORT_ALTR_16550_F128] = {
+               .name           = "Altera 16550 FIFO128",
+               .fifo_size      = 128,
+               .tx_loadsz      = 128,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
+       },
 };
 
 /* Uart divisor latch read */
@@ -3396,3 +3417,32 @@ module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
 MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
 #endif
 MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
+
+#ifndef MODULE
+/* This module was renamed to 8250_core in 3.7.  Keep the old "8250" name
+ * working as well for the module options so we don't break people.  We
+ * need to keep the names identical and the convenient macros will happily
+ * refuse to let us do that by failing the build with redefinition errors
+ * of global variables.  So we stick them inside a dummy function to avoid
+ * those conflicts.  The options still get parsed, and the redefined
+ * MODULE_PARAM_PREFIX lets us keep the "8250." syntax alive.
+ *
+ * This is hacky.  I'm sorry.
+ */
+static void __used s8250_options(void)
+{
+#undef MODULE_PARAM_PREFIX
+#define MODULE_PARAM_PREFIX "8250."
+
+       module_param_cb(share_irqs, &param_ops_uint, &share_irqs, 0644);
+       module_param_cb(nr_uarts, &param_ops_uint, &nr_uarts, 0644);
+       module_param_cb(skip_txen_test, &param_ops_uint, &skip_txen_test, 0644);
+#ifdef CONFIG_SERIAL_8250_RSA
+       __module_param_call(MODULE_PARAM_PREFIX, probe_rsa,
+               &param_array_ops, .arr = &__param_arr_probe_rsa,
+               0444, -1);
+#endif
+}
+#else
+MODULE_ALIAS("8250");
+#endif
index 791c5a77ec61d473495190049ab5776e8a02a846..aa76825229dca32d612781f877b1d1167add71af 100644 (file)
@@ -1571,6 +1571,7 @@ pci_wch_ch353_setup(struct serial_private *priv,
 
 /* Unknown vendors/cards - this should not be in linux/pci_ids.h */
 #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584        0x1584
+#define PCI_SUBDEVICE_ID_UNKNOWN_0x1588        0x1588
 
 /*
  * Master list of serial port init/setup/exit quirks.
@@ -1850,15 +1851,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .setup          = pci_default_setup,
                .exit           = pci_plx9050_exit,
        },
-       {
-               .vendor         = PCI_VENDOR_ID_PLX,
-               .device         = PCI_DEVICE_ID_PLX_9050,
-               .subvendor      = PCI_VENDOR_ID_PLX,
-               .subdevice      = PCI_SUBDEVICE_ID_UNKNOWN_0x1584,
-               .init           = pci_plx9050_init,
-               .setup          = pci_default_setup,
-               .exit           = pci_plx9050_exit,
-       },
        {
                .vendor         = PCI_VENDOR_ID_PLX,
                .device         = PCI_DEVICE_ID_PLX_ROMULUS,
@@ -3733,7 +3725,12 @@ static struct pci_device_id serial_pci_tbl[] = {
        {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
                PCI_VENDOR_ID_PLX,
                PCI_SUBDEVICE_ID_UNKNOWN_0x1584, 0, 0,
-               pbn_b0_4_115200 },
+               pbn_b2_4_115200 },
+       /* Unknown card - subdevice 0x1588 */
+       {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+               PCI_VENDOR_ID_PLX,
+               PCI_SUBDEVICE_ID_UNKNOWN_0x1588, 0, 0,
+               pbn_b2_8_115200 },
        {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
                PCI_SUBVENDOR_ID_KEYSPAN,
                PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0,
@@ -4791,6 +4788,10 @@ static struct pci_device_id serial_pci_tbl[] = {
                PCI_VENDOR_ID_IBM, 0x0299,
                0, 0, pbn_b0_bt_2_115200 },
 
+       {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
+               0x1000, 0x0012,
+               0, 0, pbn_b0_bt_2_115200 },
+
        {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901,
                0xA000, 0x1000,
                0, 0, pbn_b0_1_115200 },
index 35d9ab95c5cbb51d6092f67540678f00e4ee52bd..b3455a970a1da01c0afcf013d8c31a49e1004005 100644 (file)
@@ -429,6 +429,7 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
 {
        struct uart_8250_port uart;
        int ret, line, flags = dev_id->driver_data;
+       struct resource *res = NULL;
 
        if (flags & UNKNOWN_DEV) {
                ret = serial_pnp_guess_board(dev);
@@ -439,11 +440,12 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
        memset(&uart, 0, sizeof(uart));
        if (pnp_irq_valid(dev, 0))
                uart.port.irq = pnp_irq(dev, 0);
-       if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) {
-               uart.port.iobase = pnp_port_start(dev, 2);
-               uart.port.iotype = UPIO_PORT;
-       } else if (pnp_port_valid(dev, 0)) {
-               uart.port.iobase = pnp_port_start(dev, 0);
+       if ((flags & CIR_PORT) && pnp_port_valid(dev, 2))
+               res = pnp_get_resource(dev, IORESOURCE_IO, 2);
+       else if (pnp_port_valid(dev, 0))
+               res = pnp_get_resource(dev, IORESOURCE_IO, 0);
+       if (pnp_resource_enabled(res)) {
+               uart.port.iobase = res->start;
                uart.port.iotype = UPIO_PORT;
        } else if (pnp_mem_valid(dev, 0)) {
                uart.port.mapbase = pnp_mem_start(dev, 0);
index cf9210db9fa917cd213559ec2c0cffd53c9f123b..7e7006fd404e62000b19b728274c0abf8a51bf38 100644 (file)
@@ -211,14 +211,14 @@ config SERIAL_SAMSUNG
 config SERIAL_SAMSUNG_UARTS_4
        bool
        depends on PLAT_SAMSUNG
-       default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442)
+       default y if !(CPU_S3C2410 || CPU_S3C2412 || CPU_S3C2440 || CPU_S3C2442)
        help
          Internal node for the common case of 4 Samsung compatible UARTs
 
 config SERIAL_SAMSUNG_UARTS
        int
        depends on PLAT_SAMSUNG
-       default 6 if ARCH_S5P6450
+       default 6 if CPU_S5P6450
        default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416
        default 3
        help
index 719594e5fc219aafe5826730e1a4af659f7639b9..52a3ecd404219c7365850debe309d06b99a2d8c8 100644 (file)
@@ -235,7 +235,7 @@ static const char *bcm_uart_type(struct uart_port *port)
  */
 static void bcm_uart_do_rx(struct uart_port *port)
 {
-       struct tty_port *port = &port->state->port;
+       struct tty_port *tty_port = &port->state->port;
        unsigned int max_count;
 
        /* limit number of char read in interrupt, should not be
@@ -260,7 +260,7 @@ static void bcm_uart_do_rx(struct uart_port *port)
                        bcm_uart_writel(port, val, UART_CTL_REG);
 
                        port->icount.overrun++;
-                       tty_insert_flip_char(port, 0, TTY_OVERRUN);
+                       tty_insert_flip_char(tty_port, 0, TTY_OVERRUN);
                }
 
                if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY)))
@@ -299,11 +299,11 @@ static void bcm_uart_do_rx(struct uart_port *port)
 
 
                if ((cstat & port->ignore_status_mask) == 0)
-                       tty_insert_flip_char(port, c, flag);
+                       tty_insert_flip_char(tty_port, c, flag);
 
        } while (--max_count);
 
-       tty_flip_buffer_push(port);
+       tty_flip_buffer_push(tty_port);
 }
 
 /*
index c0e1fad51be76f5969b71b561983cf6b6bba9b92..018bad922554fc45b9ad711bcab2a106fc683b6e 100644 (file)
@@ -550,7 +550,7 @@ static int mpc512x_psc_clock(struct uart_port *port, int enable)
                return 0;
 
        psc_num = (port->mapbase & 0xf00) >> 8;
-       snprintf(clk_name, sizeof(clk_name), "psc%d_clk", psc_num);
+       snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num);
        psc_clk = clk_get(port->dev, clk_name);
        if (IS_ERR(psc_clk)) {
                dev_err(port->dev, "Failed to get PSC clock entry!\n");
index d5874605682b77c69a272d71307fc24c70289b24..b025d54382754456efbb021e466079727381bcba 100644 (file)
@@ -241,6 +241,12 @@ static struct of_device_id of_platform_serial_table[] = {
        { .compatible = "ns16850",  .data = (void *)PORT_16850, },
        { .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, },
        { .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, },
+       { .compatible = "altr,16550-FIFO32",
+               .data = (void *)PORT_ALTR_16550_F32, },
+       { .compatible = "altr,16550-FIFO64",
+               .data = (void *)PORT_ALTR_16550_F64, },
+       { .compatible = "altr,16550-FIFO128",
+               .data = (void *)PORT_ALTR_16550_F128, },
 #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL
        { .compatible = "ibm,qpace-nwp-serial",
                .data = (void *)PORT_NWPSERIAL, },
index a3f9dd5c9dff40dacf86966ae3d6ff1335055f97..705240e6c4ec1714fb0c367e9f226eb23d705464 100644 (file)
@@ -611,14 +611,7 @@ static int vt8500_serial_probe(struct platform_device *pdev)
        vt8500_port->uart.dev = &pdev->dev;
        vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
 
-       vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0);
-       if (!IS_ERR(vt8500_port->clk)) {
-               vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk);
-       } else {
-               /* use the default of 24Mhz if not specified and warn */
-               pr_warn("%s: serial clock source not specified\n", __func__);
-               vt8500_port->uart.uartclk = 24000000;
-       }
+       vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk);
 
        snprintf(vt8500_port->name, sizeof(vt8500_port->name),
                 "VT8500 UART%d", pdev->id);
index bb119934e76cd8c70bdde28038553b60867b3282..578aa7594b11febce9cf50b6f5863bc8a34dfe8c 100644 (file)
@@ -425,7 +425,7 @@ static void flush_to_ldisc(struct work_struct *work)
        struct tty_ldisc *disc;
 
        tty = port->itty;
-       if (WARN_RATELIMIT(tty == NULL, "tty is NULL\n"))
+       if (tty == NULL)
                return;
 
        disc = tty_ldisc_ref(tty);
index f5ed3d75fa5a2ce615f32b10b7f0461f839e5757..8f5ebced5df0010e4d881c7978a5e132d92c8306 100644 (file)
@@ -46,7 +46,7 @@ obj-$(CONFIG_USB_MICROTEK)    += image/
 obj-$(CONFIG_USB_SERIAL)       += serial/
 
 obj-$(CONFIG_USB)              += misc/
-obj-$(CONFIG_USB_COMMON)       += phy/
+obj-$(CONFIG_USB_OTG_UTILS)    += phy/
 obj-$(CONFIG_EARLY_PRINTK_DBGP)        += early/
 
 obj-$(CONFIG_USB_ATM)          += atm/
index a03fbc15fa9cce3ed28f209380f2a091e73223c7..aa491627a45ba83b51a881e0f5b7226a26139933 100644 (file)
@@ -100,7 +100,7 @@ struct c67x00_urb_priv {
 #define TD_PIDEP_OFFSET                0x04
 #define TD_PIDEPMASK_PID       0xF0
 #define TD_PIDEPMASK_EP                0x0F
-#define TD_PORTLENMASK_DL      0x02FF
+#define TD_PORTLENMASK_DL      0x03FF
 #define TD_PORTLENMASK_PN      0xC000
 
 #define TD_STATUS_OFFSET       0x07
@@ -590,7 +590,7 @@ static int c67x00_create_td(struct c67x00_hcd *c67x00, struct urb *urb,
 {
        struct c67x00_td *td;
        struct c67x00_urb_priv *urbp = urb->hcpriv;
-       const __u8 active_flag = 1, retry_cnt = 1;
+       const __u8 active_flag = 1, retry_cnt = 3;
        __u8 cmd = 0;
        int tt = 0;
 
index 2f45bba8561d10a5f8b52607344cfdeb957a540e..f64fbea1cf20aa689452ea50198ea9f8f70701b3 100644 (file)
@@ -1767,7 +1767,7 @@ static int udc_start(struct ci13xxx *ci)
                goto put_transceiver;
        }
 
-       retval = dbg_create_files(&ci->gadget.dev);
+       retval = dbg_create_files(ci->dev);
        if (retval)
                goto unreg_device;
 
@@ -1796,7 +1796,7 @@ remove_trans:
 
        dev_err(dev, "error = %i\n", retval);
 remove_dbg:
-       dbg_remove_files(&ci->gadget.dev);
+       dbg_remove_files(ci->dev);
 unreg_device:
        device_unregister(&ci->gadget.dev);
 put_transceiver:
@@ -1836,7 +1836,7 @@ static void udc_stop(struct ci13xxx *ci)
                if (ci->global_phy)
                        usb_put_phy(ci->transceiver);
        }
-       dbg_remove_files(&ci->gadget.dev);
+       dbg_remove_files(ci->dev);
        device_unregister(&ci->gadget.dev);
        /* my kobject is dynamic, I swear! */
        memset(&ci->gadget, 0, sizeof(ci->gadget));
index 5f0cb417b736bb4b61c73afc52672029af59cbda..122d056d96d570c2d59762fda22e0e973ac081b5 100644 (file)
@@ -56,6 +56,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids);
 #define WDM_RESPONDING         7
 #define WDM_SUSPENDING         8
 #define WDM_RESETTING          9
+#define WDM_OVERFLOW           10
 
 #define WDM_MAX                        16
 
@@ -155,6 +156,7 @@ static void wdm_in_callback(struct urb *urb)
 {
        struct wdm_device *desc = urb->context;
        int status = urb->status;
+       int length = urb->actual_length;
 
        spin_lock(&desc->iuspin);
        clear_bit(WDM_RESPONDING, &desc->flags);
@@ -185,9 +187,17 @@ static void wdm_in_callback(struct urb *urb)
        }
 
        desc->rerr = status;
-       desc->reslength = urb->actual_length;
-       memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength);
-       desc->length += desc->reslength;
+       if (length + desc->length > desc->wMaxCommand) {
+               /* The buffer would overflow */
+               set_bit(WDM_OVERFLOW, &desc->flags);
+       } else {
+               /* we may already be in overflow */
+               if (!test_bit(WDM_OVERFLOW, &desc->flags)) {
+                       memmove(desc->ubuf + desc->length, desc->inbuf, length);
+                       desc->length += length;
+                       desc->reslength = length;
+               }
+       }
 skip_error:
        wake_up(&desc->wait);
 
@@ -435,6 +445,11 @@ retry:
                        rv = -ENODEV;
                        goto err;
                }
+               if (test_bit(WDM_OVERFLOW, &desc->flags)) {
+                       clear_bit(WDM_OVERFLOW, &desc->flags);
+                       rv = -ENOBUFS;
+                       goto err;
+               }
                i++;
                if (file->f_flags & O_NONBLOCK) {
                        if (!test_bit(WDM_READ, &desc->flags)) {
@@ -478,6 +493,7 @@ retry:
                        spin_unlock_irq(&desc->iuspin);
                        goto retry;
                }
+
                if (!desc->reslength) { /* zero length read */
                        dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__);
                        clear_bit(WDM_READ, &desc->flags);
@@ -1004,6 +1020,7 @@ static int wdm_post_reset(struct usb_interface *intf)
        struct wdm_device *desc = wdm_find_device(intf);
        int rv;
 
+       clear_bit(WDM_OVERFLOW, &desc->flags);
        clear_bit(WDM_RESETTING, &desc->flags);
        rv = recover_from_urb_loss(desc);
        mutex_unlock(&desc->wlock);
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 999909451e37ef75e9fb49d42f35fc34bceb646f..ffa6b004a84bec3b4d58b9e5b6bd515d499e603d 100644 (file)
@@ -583,6 +583,7 @@ static int dwc3_remove(struct platform_device *pdev)
                break;
        }
 
+       dwc3_free_event_buffers(dwc);
        dwc3_core_exit(dwc);
 
        return 0;
index b50da53e9a52046a5441a9ea230e267d6a476c93..b082bec7343e0e79cd3e1d062c2aba16173ffbab 100644 (file)
@@ -23,8 +23,6 @@
 #include <linux/usb/nop-usb-xceiv.h>
 #include <linux/of.h>
 
-#include "core.h"
-
 struct dwc3_exynos {
        struct platform_device  *dwc3;
        struct platform_device  *usb2_phy;
index 22f337f572190234c4f75fd06a78b14ce4a2faf9..afa05e3c9cf40b9b731e6d16f8543c07a6cb62c8 100644 (file)
@@ -54,8 +54,6 @@
 #include <linux/usb/otg.h>
 #include <linux/usb/nop-usb-xceiv.h>
 
-#include "core.h"
-
 /*
  * All these registers belong to OMAP's Wrapper around the
  * DesignWare USB3 Core.
@@ -465,20 +463,20 @@ static int dwc3_omap_remove(struct platform_device *pdev)
        return 0;
 }
 
-static const struct of_device_id of_dwc3_matach[] = {
+static const struct of_device_id of_dwc3_match[] = {
        {
                "ti,dwc3",
        },
        { },
 };
-MODULE_DEVICE_TABLE(of, of_dwc3_matach);
+MODULE_DEVICE_TABLE(of, of_dwc3_match);
 
 static struct platform_driver dwc3_omap_driver = {
        .probe          = dwc3_omap_probe,
        .remove         = dwc3_omap_remove,
        .driver         = {
                .name   = "omap-dwc3",
-               .of_match_table = of_dwc3_matach,
+               .of_match_table = of_dwc3_match,
        },
 };
 
index 7d70f44567d2a80fb9b5cf459f36ac0f61dafdf3..e8d77689a322d941042643a980e423545f7bc365 100644 (file)
@@ -45,8 +45,6 @@
 #include <linux/usb/otg.h>
 #include <linux/usb/nop-usb-xceiv.h>
 
-#include "core.h"
-
 /* FIXME define these in <linux/pci_ids.h> */
 #define PCI_VENDOR_ID_SYNOPSYS         0x16c3
 #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3        0xabcd
index d7da073a23fee142edc051e562d5cba498c97e63..1d139ca05ef17bdd56cdfa3ba9027ea70c337d88 100644 (file)
@@ -891,7 +891,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
                                DWC3_TRBCTL_CONTROL_DATA);
        } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket)
                        && (dep->number == 0)) {
-               u32             transfer_size;
+               u32     transfer_size;
+               u32     maxpacket;
 
                ret = usb_gadget_map_request(&dwc->gadget, &req->request,
                                dep->number);
@@ -902,8 +903,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
 
                WARN_ON(req->request.length > DWC3_EP0_BOUNCE_SIZE);
 
-               transfer_size = roundup(req->request.length,
-                               (u32) dep->endpoint.maxpacket);
+               maxpacket = dep->endpoint.maxpacket;
+               transfer_size = roundup(req->request.length, maxpacket);
 
                dwc->ep0_bounced = true;
 
index a04342f6cbfae6979f1f053776e7e1297ca1bdfb..82e160e96fcafd20f15c4443cba953d569c071f1 100644 (file)
@@ -2159,7 +2159,6 @@ static void dwc3_gadget_phy_suspend(struct dwc3 *dwc, u8 speed)
 
 static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
 {
-       struct dwc3_gadget_ep_cmd_params params;
        struct dwc3_ep          *dep;
        int                     ret;
        u32                     reg;
@@ -2167,8 +2166,6 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
 
        dev_vdbg(dwc->dev, "%s\n", __func__);
 
-       memset(&params, 0x00, sizeof(params));
-
        reg = dwc3_readl(dwc->regs, DWC3_DSTS);
        speed = reg & DWC3_DSTS_CONNECTSPD;
        dwc->speed = speed;
index 97a13c349cc52bfa4928c6eab5fd11470bcc5a26..82fb22511356d4ffd610d57b2787f457a93e5f9e 100644 (file)
@@ -35,6 +35,12 @@ mv_udc-y                     := mv_udc_core.o
 obj-$(CONFIG_USB_FUSB300)      += fusb300_udc.o
 obj-$(CONFIG_USB_MV_U3D)       += mv_u3d_core.o
 
+# USB Functions
+obj-$(CONFIG_USB_F_ACM)                += f_acm.o
+f_ss_lb-y                      := f_loopback.o f_sourcesink.o
+obj-$(CONFIG_USB_F_SS_LB)      += f_ss_lb.o
+obj-$(CONFIG_USB_U_SERIAL)     += u_serial.o
+
 #
 # USB gadget drivers
 #
@@ -74,9 +80,3 @@ obj-$(CONFIG_USB_G_WEBCAM)    += g_webcam.o
 obj-$(CONFIG_USB_G_NCM)                += g_ncm.o
 obj-$(CONFIG_USB_G_ACM_MS)     += g_acm_ms.o
 obj-$(CONFIG_USB_GADGET_TARGET)        += tcm_usb_gadget.o
-
-# USB Functions
-obj-$(CONFIG_USB_F_ACM)                += f_acm.o
-f_ss_lb-y                      := f_loopback.o f_sourcesink.o
-obj-$(CONFIG_USB_F_SS_LB)      += f_ss_lb.o
-obj-$(CONFIG_USB_U_SERIAL)     += u_serial.o
index 7c821de8ce3d95d53d03beffd85e4ab9f962f571..c0d62b2786104a6ed2a3501d2bd74e739841c970 100644 (file)
@@ -1757,10 +1757,7 @@ static const struct usb_gadget_driver composite_driver_template = {
 /**
  * usb_composite_probe() - register a composite driver
  * @driver: the driver to register
- * @bind: the callback used to allocate resources that are shared across the
- *     whole device, such as string IDs, and add its configurations using
- *     @usb_add_config().  This may fail by returning a negative errno
- *     value; it should return zero on successful initialization.
+ *
  * Context: single threaded during gadget setup
  *
  * This function is used to register drivers using the composite driver
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 f570e667a640d0619cd6abaffaf9705738fcab24..fa8ea4ea00c1a3014be0fdc35dfcc52bb17af166 100644 (file)
@@ -418,6 +418,7 @@ static int audio_get_intf_req(struct usb_function *f,
 
        req->context = audio;
        req->complete = f_audio_complete;
+       len = min_t(size_t, sizeof(value), len);
        memcpy(req->buf, &value, len);
 
        return len;
index 8efd7555fa21a93884a48a52eb743d28407f2410..5bd930d779b9dd957b51d610469b4e6e4ead5663 100644 (file)
@@ -1334,27 +1334,18 @@ static int imx_udc_start(struct usb_gadget *gadget,
                struct usb_gadget_driver *driver)
 {
        struct imx_udc_struct *imx_usb;
-       int retval;
 
        imx_usb = container_of(gadget, struct imx_udc_struct, gadget);
        /* first hook up the driver ... */
        imx_usb->driver = driver;
        imx_usb->gadget.dev.driver = &driver->driver;
 
-       retval = device_add(&imx_usb->gadget.dev);
-       if (retval)
-               goto fail;
-
        D_INI(imx_usb->dev, "<%s> registered gadget driver '%s'\n",
                __func__, driver->driver.name);
 
        imx_udc_enable(imx_usb);
 
        return 0;
-fail:
-       imx_usb->driver = NULL;
-       imx_usb->gadget.dev.driver = NULL;
-       return retval;
 }
 
 static int imx_udc_stop(struct usb_gadget *gadget,
@@ -1370,8 +1361,6 @@ static int imx_udc_stop(struct usb_gadget *gadget,
        imx_usb->gadget.dev.driver = NULL;
        imx_usb->driver = NULL;
 
-       device_del(&imx_usb->gadget.dev);
-
        D_INI(imx_usb->dev, "<%s> unregistered gadget driver '%s'\n",
                __func__, driver->driver.name);
 
@@ -1477,6 +1466,10 @@ static int __init imx_udc_probe(struct platform_device *pdev)
        imx_usb->gadget.dev.parent = &pdev->dev;
        imx_usb->gadget.dev.dma_mask = pdev->dev.dma_mask;
 
+       ret = device_add(&imx_usb->gadget.dev);
+       if (retval)
+               goto fail4;
+
        platform_set_drvdata(pdev, imx_usb);
 
        usb_init_data(imx_usb);
@@ -1488,9 +1481,11 @@ static int __init imx_udc_probe(struct platform_device *pdev)
 
        ret = usb_add_gadget_udc(&pdev->dev, &imx_usb->gadget);
        if (ret)
-               goto fail4;
+               goto fail5;
 
        return 0;
+fail5:
+       device_unregister(&imx_usb->gadget.dev);
 fail4:
        for (i = 0; i < IMX_USB_NB_EP + 1; i++)
                free_irq(imx_usb->usbd_int[i], imx_usb);
@@ -1514,6 +1509,7 @@ static int __exit imx_udc_remove(struct platform_device *pdev)
        int i;
 
        usb_del_gadget_udc(&imx_usb->gadget);
+       device_unregister(&imx_usb->gadget.dev);
        imx_udc_disable(imx_usb);
        del_timer(&imx_usb->timer);
 
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 06be85c2b2337a7b9f909822fb3f8ab37313ad0c..f8445653577fbb107256576fec5481b4b94f758f 100644 (file)
@@ -62,6 +62,7 @@
 #define        DRIVER_VERSION  "4 October 2004"
 
 #define OMAP_DMA_USB_W2FC_TX0          29
+#define OMAP_DMA_USB_W2FC_RX0          26
 
 /*
  * The OMAP UDC needs _very_ early endpoint setup:  before enabling the
@@ -1310,7 +1311,7 @@ static int omap_pullup(struct usb_gadget *gadget, int is_on)
 }
 
 static int omap_udc_start(struct usb_gadget *g,
-               struct usb_gadget_driver *driver)
+               struct usb_gadget_driver *driver);
 static int omap_udc_stop(struct usb_gadget *g,
                struct usb_gadget_driver *driver);
 
index 2bbcdce942dc2b7a8c29f17361e2a95fd59f47db..d0f37484b6b0cf67faf1875db8440521b030f1a2 100644 (file)
@@ -1266,13 +1266,6 @@ static int pxa25x_udc_start(struct usb_gadget *g,
        dev->gadget.dev.driver = &driver->driver;
        dev->pullup = 1;
 
-       retval = device_add (&dev->gadget.dev);
-       if (retval) {
-               dev->driver = NULL;
-               dev->gadget.dev.driver = NULL;
-               return retval;
-       }
-
        /* ... then enable host detection and ep0; and we're ready
         * for set_configuration as well as eventual disconnect.
         */
@@ -1310,6 +1303,10 @@ stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver)
        }
        del_timer_sync(&dev->timer);
 
+       /* report disconnect; the driver is already quiesced */
+       if (driver)
+               driver->disconnect(&dev->gadget);
+
        /* re-init driver-visible data structures */
        udc_reinit(dev);
 }
@@ -1331,7 +1328,6 @@ static int pxa25x_udc_stop(struct usb_gadget*g,
        dev->gadget.dev.driver = NULL;
        dev->driver = NULL;
 
-       device_del (&dev->gadget.dev);
        dump_state(dev);
 
        return 0;
@@ -2146,6 +2142,13 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
        dev->gadget.dev.parent = &pdev->dev;
        dev->gadget.dev.dma_mask = pdev->dev.dma_mask;
 
+       retval = device_add(&dev->gadget.dev);
+       if (retval) {
+               dev->driver = NULL;
+               dev->gadget.dev.driver = NULL;
+               goto err_device_add;
+       }
+
        the_controller = dev;
        platform_set_drvdata(pdev, dev);
 
@@ -2196,6 +2199,8 @@ lubbock_fail0:
        free_irq(irq, dev);
 #endif
  err_irq1:
+       device_unregister(&dev->gadget.dev);
+ err_device_add:
        if (gpio_is_valid(dev->mach->gpio_pullup))
                gpio_free(dev->mach->gpio_pullup);
  err_gpio_pullup:
@@ -2217,10 +2222,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev)
 {
        struct pxa25x_udc *dev = platform_get_drvdata(pdev);
 
-       usb_del_gadget_udc(&dev->gadget);
        if (dev->driver)
                return -EBUSY;
 
+       usb_del_gadget_udc(&dev->gadget);
+       device_unregister(&dev->gadget.dev);
        dev->pullup = 0;
        pullup(dev);
 
index f7d25795821ac2830aa6ae587eda30c714c16342..2fc867652ef5df8f97e55c7c3ebe45196c672ab7 100644 (file)
@@ -1814,11 +1814,6 @@ static int pxa27x_udc_start(struct usb_gadget *g,
        udc->gadget.dev.driver = &driver->driver;
        dplus_pullup(udc, 1);
 
-       retval = device_add(&udc->gadget.dev);
-       if (retval) {
-               dev_err(udc->dev, "device_add error %d\n", retval);
-               goto fail;
-       }
        if (!IS_ERR_OR_NULL(udc->transceiver)) {
                retval = otg_set_peripheral(udc->transceiver->otg,
                                                &udc->gadget);
@@ -1876,7 +1871,6 @@ static int pxa27x_udc_stop(struct usb_gadget *g,
 
        udc->driver = NULL;
 
-       device_del(&udc->gadget.dev);
 
        if (!IS_ERR_OR_NULL(udc->transceiver))
                return otg_set_peripheral(udc->transceiver->otg, NULL);
@@ -2480,13 +2474,24 @@ static int __init pxa_udc_probe(struct platform_device *pdev)
                        driver_name, udc->irq, retval);
                goto err_irq;
        }
+
+       retval = device_add(&udc->gadget.dev);
+       if (retval) {
+               dev_err(udc->dev, "device_add error %d\n", retval);
+               goto err_dev_add;
+       }
+
        retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget);
        if (retval)
                goto err_add_udc;
 
        pxa_init_debugfs(udc);
+
        return 0;
+
 err_add_udc:
+       device_unregister(&udc->gadget.dev);
+err_dev_add:
        free_irq(udc->irq, udc);
 err_irq:
        iounmap(udc->regs);
@@ -2507,6 +2512,7 @@ static int __exit pxa_udc_remove(struct platform_device *_dev)
        int gpio = udc->mach->gpio_pullup;
 
        usb_del_gadget_udc(&udc->gadget);
+       device_del(&udc->gadget.dev);
        usb_gadget_unregister_driver(udc->driver);
        free_irq(udc->irq, udc);
        pxa_cleanup_debugfs(udc);
index fc07b43812867d4070143093060be8d328fad9ff..08f89652533baa0702bf4a85429d282b56973695 100644 (file)
@@ -1668,8 +1668,7 @@ static void s3c2410_udc_enable(struct s3c2410_udc *dev)
 static int s3c2410_udc_start(struct usb_gadget *g,
                struct usb_gadget_driver *driver)
 {
-       struct s3c2410_udc *udc = to_s3c2410(g)
-       int             retval;
+       struct s3c2410_udc *udc = to_s3c2410(g);
 
        dprintk(DEBUG_NORMAL, "%s() '%s'\n", __func__, driver->driver.name);
 
@@ -1677,22 +1676,10 @@ static int s3c2410_udc_start(struct usb_gadget *g,
        udc->driver = driver;
        udc->gadget.dev.driver = &driver->driver;
 
-       /* Bind the driver */
-       retval = device_add(&udc->gadget.dev);
-       if (retval) {
-               dev_err(&udc->gadget.dev, "Error in device_add() : %d\n", retval);
-               goto register_error;
-       }
-
        /* Enable udc */
        s3c2410_udc_enable(udc);
 
        return 0;
-
-register_error:
-       udc->driver = NULL;
-       udc->gadget.dev.driver = NULL;
-       return retval;
 }
 
 static int s3c2410_udc_stop(struct usb_gadget *g,
@@ -1700,7 +1687,6 @@ static int s3c2410_udc_stop(struct usb_gadget *g,
 {
        struct s3c2410_udc *udc = to_s3c2410(g);
 
-       device_del(&udc->gadget.dev);
        udc->driver = NULL;
 
        /* Disable udc */
@@ -1842,6 +1828,13 @@ static int s3c2410_udc_probe(struct platform_device *pdev)
        udc->gadget.dev.parent = &pdev->dev;
        udc->gadget.dev.dma_mask = pdev->dev.dma_mask;
 
+       /* Bind the driver */
+       retval = device_add(&udc->gadget.dev);
+       if (retval) {
+               dev_err(&udc->gadget.dev, "Error in device_add() : %d\n", retval);
+               goto err_device_add;
+       }
+
        the_controller = udc;
        platform_set_drvdata(pdev, udc);
 
@@ -1930,6 +1923,8 @@ err_gpio_claim:
 err_int:
        free_irq(IRQ_USBD, udc);
 err_map:
+       device_unregister(&udc->gadget.dev);
+err_device_add:
        iounmap(base_addr);
 err_mem:
        release_mem_region(rsrc_start, rsrc_len);
@@ -1947,10 +1942,11 @@ static int s3c2410_udc_remove(struct platform_device *pdev)
 
        dev_dbg(&pdev->dev, "%s()\n", __func__);
 
-       usb_del_gadget_udc(&udc->gadget);
        if (udc->driver)
                return -EBUSY;
 
+       usb_del_gadget_udc(&udc->gadget);
+       device_unregister(&udc->gadget.dev);
        debugfs_remove(udc->regs_info);
 
        if (udc_info && !udc_info->udc_command &&
index e0c5e88e03ed30dc02c533d0eae3a41b94bcb00b..c7d460f43390da9dd5bfad40774f8c6b3fccf54d 100644 (file)
@@ -240,8 +240,11 @@ static int gaudio_open_snd_dev(struct gaudio *card)
        snd = &card->playback;
        snd->filp = filp_open(fn_play, O_WRONLY, 0);
        if (IS_ERR(snd->filp)) {
+               int ret = PTR_ERR(snd->filp);
+
                ERROR(card, "No such PCM playback device: %s\n", fn_play);
                snd->filp = NULL;
+               return ret;
        }
        pcm_file = snd->filp->private_data;
        snd->substream = pcm_file->substream;
index b416a3fc99594f30afbb15995191313f6c9315a6..5726cb144abfdf425870168589e0d609e12d059a 100644 (file)
@@ -748,11 +748,9 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
                /* guard against (alleged) silicon errata */
                if (cmd & CMD_IAAD)
                        ehci_dbg(ehci, "IAA with IAAD still set?\n");
-               if (ehci->async_iaa) {
+               if (ehci->async_iaa)
                        COUNT(ehci->stats.iaa);
-                       end_unlink_async(ehci);
-               } else
-                       ehci_dbg(ehci, "IAA with nothing unlinked?\n");
+               end_unlink_async(ehci);
        }
 
        /* remote wakeup [4.3.1] */
index fd252f0cfb3a7873ec7bad8226a036a9668b182e..5464665f0b6aa7b86b472b080213715dcacfe5f4 100644 (file)
@@ -135,7 +135,7 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)
                 * qtd is updated in qh_completions(). Update the QH
                 * overlay here.
                 */
-               if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) {
+               if (qh->hw->hw_token & ACTIVE_BIT(ehci)) {
                        qh->hw->hw_qtd_next = qtd->hw_next;
                        qtd = NULL;
                }
@@ -449,11 +449,19 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
                        else if (last_status == -EINPROGRESS && !urb->unlinked)
                                continue;
 
-                       /* qh unlinked; token in overlay may be most current */
-                       if (state == QH_STATE_IDLE
-                                       && cpu_to_hc32(ehci, qtd->qtd_dma)
-                                               == hw->hw_current) {
+                       /*
+                        * If this was the active qtd when the qh was unlinked
+                        * and the overlay's token is active, then the overlay
+                        * hasn't been written back to the qtd yet so use its
+                        * token instead of the qtd's.  After the qtd is
+                        * processed and removed, the overlay won't be valid
+                        * any more.
+                        */
+                       if (state == QH_STATE_IDLE &&
+                                       qh->qtd_list.next == &qtd->qtd_list &&
+                                       (hw->hw_token & ACTIVE_BIT(ehci))) {
                                token = hc32_to_cpu(ehci, hw->hw_token);
+                               hw->hw_token &= ~ACTIVE_BIT(ehci);
 
                                /* An unlink may leave an incomplete
                                 * async transaction in the TT buffer.
@@ -1170,7 +1178,7 @@ static void single_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh)
        struct ehci_qh          *prev;
 
        /* Add to the end of the list of QHs waiting for the next IAAD */
-       qh->qh_state = QH_STATE_UNLINK;
+       qh->qh_state = QH_STATE_UNLINK_WAIT;
        if (ehci->async_unlink)
                ehci->async_unlink_last->unlink_next = qh;
        else
@@ -1213,9 +1221,19 @@ static void start_iaa_cycle(struct ehci_hcd *ehci, bool nested)
 
                /* Do only the first waiting QH (nVidia bug?) */
                qh = ehci->async_unlink;
-               ehci->async_iaa = qh;
-               ehci->async_unlink = qh->unlink_next;
-               qh->unlink_next = NULL;
+
+               /*
+                * Intel (?) bug: The HC can write back the overlay region
+                * even after the IAA interrupt occurs.  In self-defense,
+                * always go through two IAA cycles for each QH.
+                */
+               if (qh->qh_state == QH_STATE_UNLINK_WAIT) {
+                       qh->qh_state = QH_STATE_UNLINK;
+               } else {
+                       ehci->async_iaa = qh;
+                       ehci->async_unlink = qh->unlink_next;
+                       qh->unlink_next = NULL;
+               }
 
                /* Make sure the unlinks are all visible to the hardware */
                wmb();
index 45b19e2c60bacfe396469c2d4ea426c3ff68c830..05e51432dd2f77eb08bda0b43293df5363425ef0 100644 (file)
@@ -7,11 +7,6 @@
 config USB_MUSB_HDRC
        tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
        depends on USB && USB_GADGET
-       select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN)
-       select NOP_USB_XCEIV if (SOC_TI81XX || SOC_AM33XX)
-       select TWL4030_USB if MACH_OMAP_3430SDP
-       select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
-       select OMAP_CONTROL_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
        select USB_OTG_UTILS
        help
          Say Y here if your system has a dual role high speed USB
index 60b41cc28da446558690f0e37bff33111823f281..daec6e0f7e381e52750cffab9112488c3af1e01d 100644 (file)
@@ -1624,8 +1624,6 @@ EXPORT_SYMBOL_GPL(musb_dma_completion);
 
 /*-------------------------------------------------------------------------*/
 
-#ifdef CONFIG_SYSFS
-
 static ssize_t
 musb_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
@@ -1742,8 +1740,6 @@ static const struct attribute_group musb_attr_group = {
        .attrs = musb_attributes,
 };
 
-#endif /* sysfs */
-
 /* Only used to provide driver mode change events */
 static void musb_irq_work(struct work_struct *data)
 {
@@ -1968,11 +1964,9 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
        if (status < 0)
                goto fail4;
 
-#ifdef CONFIG_SYSFS
        status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group);
        if (status)
                goto fail5;
-#endif
 
        pm_runtime_put(musb->controller);
 
index 1762354fe793198fbfc075fb95ab22468dc34a8b..1a42a458f2c4ff64cb8e9e3492bf368cf79cf0c3 100644 (file)
@@ -51,7 +51,7 @@ struct omap2430_glue {
 };
 #define glue_to_musb(g)                platform_get_drvdata(g->musb)
 
-struct omap2430_glue           *_glue;
+static struct omap2430_glue    *_glue;
 
 static struct timer_list musb_idle_timer;
 
@@ -237,9 +237,13 @@ void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
 {
        struct omap2430_glue    *glue = _glue;
 
-       if (glue && glue_to_musb(glue)) {
-               glue->status = status;
-       } else {
+       if (!glue) {
+               pr_err("%s: musb core is not yet initialized\n", __func__);
+               return;
+       }
+       glue->status = status;
+
+       if (!glue_to_musb(glue)) {
                pr_err("%s: musb core is not yet ready\n", __func__);
                return;
        }
index e1814397ca3ab9631872a481d0a60c2b77b89afc..2bd03d261a50f4f8f8df3583dcc57961c3b8ec34 100644 (file)
@@ -130,7 +130,7 @@ struct usb_phy *usb_get_phy(enum usb_phy_type type)
        spin_lock_irqsave(&phy_lock, flags);
 
        phy = __usb_find_phy(&phy_list, type);
-       if (IS_ERR(phy)) {
+       if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) {
                pr_err("unable to find transceiver of type %s\n",
                        usb_phy_type_string(type));
                goto err0;
@@ -228,7 +228,7 @@ struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index)
        spin_lock_irqsave(&phy_lock, flags);
 
        phy = __usb_find_phy_dev(dev, &phy_bind_list, index);
-       if (IS_ERR(phy)) {
+       if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) {
                pr_err("unable to find transceiver\n");
                goto err0;
        }
@@ -301,8 +301,12 @@ EXPORT_SYMBOL(devm_usb_put_phy);
  */
 void usb_put_phy(struct usb_phy *x)
 {
-       if (x)
+       if (x) {
+               struct module *owner = x->dev->driver->owner;
+
                put_device(x->dev);
+               module_put(owner);
+       }
 }
 EXPORT_SYMBOL(usb_put_phy);
 
index 5323b71c3521f4ebe41ad74260787103e6933ce5..1419ceda9759c591f5036dddda8c5c673a2d7fa4 100644 (file)
@@ -219,32 +219,26 @@ static int omap_control_usb_probe(struct platform_device *pdev)
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                "control_dev_conf");
-       control_usb->dev_conf = devm_request_and_ioremap(&pdev->dev, res);
-       if (!control_usb->dev_conf) {
-               dev_err(&pdev->dev, "Failed to obtain io memory\n");
-               return -EADDRNOTAVAIL;
-       }
+       control_usb->dev_conf = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(control_usb->dev_conf))
+               return PTR_ERR(control_usb->dev_conf);
 
        if (control_usb->type == OMAP_CTRL_DEV_TYPE1) {
                res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                        "otghs_control");
-               control_usb->otghs_control = devm_request_and_ioremap(
+               control_usb->otghs_control = devm_ioremap_resource(
                        &pdev->dev, res);
-               if (!control_usb->otghs_control) {
-                       dev_err(&pdev->dev, "Failed to obtain io memory\n");
-                       return -EADDRNOTAVAIL;
-               }
+               if (IS_ERR(control_usb->otghs_control))
+                       return PTR_ERR(control_usb->otghs_control);
        }
 
        if (control_usb->type == OMAP_CTRL_DEV_TYPE2) {
                res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
                        "phy_power_usb");
-               control_usb->phy_power = devm_request_and_ioremap(
+               control_usb->phy_power = devm_ioremap_resource(
                        &pdev->dev, res);
-               if (!control_usb->phy_power) {
-                       dev_dbg(&pdev->dev, "Failed to obtain io memory\n");
-                       return -EADDRNOTAVAIL;
-               }
+               if (IS_ERR(control_usb->phy_power))
+                       return PTR_ERR(control_usb->phy_power);
 
                control_usb->sys_clk = devm_clk_get(control_usb->dev,
                        "sys_clkin");
index fadc0c2b65bb7baf6b633c97cb187a16c4bd9d93..a6e60b1e102e84c070a44e139d8e9ac2b1ff01c7 100644 (file)
@@ -212,11 +212,9 @@ static int omap_usb3_probe(struct platform_device *pdev)
        }
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl");
-       phy->pll_ctrl_base = devm_request_and_ioremap(&pdev->dev, res);
-       if (!phy->pll_ctrl_base) {
-               dev_err(&pdev->dev, "ioremap of pll_ctrl failed\n");
-               return -ENOMEM;
-       }
+       phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(phy->pll_ctrl_base))
+               return PTR_ERR(phy->pll_ctrl_base);
 
        phy->dev                = &pdev->dev;
 
index 6ea5537338325f6f8ed9fe10cb7756bb79f2daf2..967101ec15fdf268cc8d2a73493be36df718d687 100644 (file)
@@ -787,11 +787,9 @@ static int samsung_usbphy_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       phy_base = devm_request_and_ioremap(dev, phy_mem);
-       if (!phy_base) {
-               dev_err(dev, "%s: register mapping failed\n", __func__);
-               return -ENXIO;
-       }
+       phy_base = devm_ioremap_resource(dev, phy_mem);
+       if (IS_ERR(phy_base))
+               return PTR_ERR(phy_base);
 
        sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
        if (!sphy)
index edc0f0dcad8378f4298d68815d2935404d8fedac..4747d1c328ffbdc13e1ca4337dc11a6c557711f5 100644 (file)
@@ -85,6 +85,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */
        { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
        { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
+       { USB_DEVICE(0x2405, 0x0003) }, /* West Mountain Radio RIGblaster Advantage */
        { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */
        { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
        { USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */
@@ -150,6 +151,25 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
        { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */
        { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */
+       { USB_DEVICE(0x1FB9, 0x0100) }, /* Lake Shore Model 121 Current Source */
+       { USB_DEVICE(0x1FB9, 0x0200) }, /* Lake Shore Model 218A Temperature Monitor */
+       { USB_DEVICE(0x1FB9, 0x0201) }, /* Lake Shore Model 219 Temperature Monitor */
+       { USB_DEVICE(0x1FB9, 0x0202) }, /* Lake Shore Model 233 Temperature Transmitter */
+       { USB_DEVICE(0x1FB9, 0x0203) }, /* Lake Shore Model 235 Temperature Transmitter */
+       { USB_DEVICE(0x1FB9, 0x0300) }, /* Lake Shore Model 335 Temperature Controller */
+       { USB_DEVICE(0x1FB9, 0x0301) }, /* Lake Shore Model 336 Temperature Controller */
+       { USB_DEVICE(0x1FB9, 0x0302) }, /* Lake Shore Model 350 Temperature Controller */
+       { USB_DEVICE(0x1FB9, 0x0303) }, /* Lake Shore Model 371 AC Bridge */
+       { USB_DEVICE(0x1FB9, 0x0400) }, /* Lake Shore Model 411 Handheld Gaussmeter */
+       { USB_DEVICE(0x1FB9, 0x0401) }, /* Lake Shore Model 425 Gaussmeter */
+       { USB_DEVICE(0x1FB9, 0x0402) }, /* Lake Shore Model 455A Gaussmeter */
+       { USB_DEVICE(0x1FB9, 0x0403) }, /* Lake Shore Model 475A Gaussmeter */
+       { USB_DEVICE(0x1FB9, 0x0404) }, /* Lake Shore Model 465 Three Axis Gaussmeter */
+       { USB_DEVICE(0x1FB9, 0x0600) }, /* Lake Shore Model 625A Superconducting MPS */
+       { USB_DEVICE(0x1FB9, 0x0601) }, /* Lake Shore Model 642A Magnet Power Supply */
+       { USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */
+       { USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */
+       { USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */
        { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
        { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */
        { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */
index f7d339d8187bd690b86b22ccf85b740781257226..558adfc05007dbdf46f2dc9a5280579b3cdbdab2 100644 (file)
@@ -341,6 +341,8 @@ static void option_instat_callback(struct urb *urb);
 #define CINTERION_PRODUCT_EU3_E                        0x0051
 #define CINTERION_PRODUCT_EU3_P                        0x0052
 #define CINTERION_PRODUCT_PH8                  0x0053
+#define CINTERION_PRODUCT_AH6                  0x0055
+#define CINTERION_PRODUCT_PLS8                 0x0060
 
 /* Olivetti products */
 #define OLIVETTI_VENDOR_ID                     0x0b3c
@@ -579,6 +581,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(QUANTA_VENDOR_ID, 0xea42),
                .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c1f, USB_CLASS_COMM, 0x02, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff),
                .driver_info = (kernel_ulong_t) &net_intf1_blacklist },
@@ -1260,6 +1263,8 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AH6) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLS8) },
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, 
        { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
        { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },
index 9b1b96f2d0955d8d8e98a284bf0fda6123c6c900..31f81c3c15eb780a10eccaa3b937cebb9f713df3 100644 (file)
@@ -69,6 +69,7 @@ static struct usb_device_id id_table[] = {
        { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfd, 0xff) },  /* NMEA */
        { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfe, 0xff) },  /* WMC */
        { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xff, 0xff) },  /* DIAG */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x1fac, 0x0151, 0xff, 0xff, 0xff) },
        { },
 };
 MODULE_DEVICE_TABLE(usb, id_table);
index 24662547dc5b2e60ffc51abc846e930e0afc1182..59b32b7821264d6d02b34fe4df881496ebf271b2 100644 (file)
@@ -197,12 +197,15 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
 
        if (is_gobi1k) {
                /* Gobi 1K USB layout:
-                * 0: serial port (doesn't respond)
+                * 0: DM/DIAG (use libqcdm from ModemManager for communication)
                 * 1: serial port (doesn't respond)
                 * 2: AT-capable modem port
                 * 3: QMI/net
                 */
-               if (ifnum == 2)
+               if (ifnum == 0) {
+                       dev_dbg(dev, "Gobi 1K DM/DIAG interface found\n");
+                       altsetting = 1;
+               } else if (ifnum == 2)
                        dev_dbg(dev, "Modem port found\n");
                else
                        altsetting = -1;
index 00e6c9bac8a309b0df675903654ce0521f991cad..d643a4d4d770819a68cd32f9402b5d2e8839c436 100644 (file)
@@ -661,7 +661,9 @@ void qt2_process_read_urb(struct urb *urb)
                                                 __func__);
                                        break;
                                }
-                               tty_flip_buffer_push(&port->port);
+
+                               if (port_priv->is_open)
+                                       tty_flip_buffer_push(&port->port);
 
                                newport = *(ch + 3);
 
@@ -704,7 +706,8 @@ void qt2_process_read_urb(struct urb *urb)
                tty_insert_flip_string(&port->port, ch, 1);
        }
 
-       tty_flip_buffer_push(&port->port);
+       if (port_priv->is_open)
+               tty_flip_buffer_push(&port->port);
 }
 
 static void qt2_write_bulk_callback(struct urb *urb)
index 7ab9046ae0eca5fe64ea930206c18a7cdeda1420..105d900150c1a80155c2afcec6a61f4fb07fd0b4 100644 (file)
@@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us)
        return 0;
 }
 
-/* This places the HUAWEI usb dongles in multi-port mode */
-static int usb_stor_huawei_feature_init(struct us_data *us)
+/* This places the HUAWEI E220 devices in multi-port mode */
+int usb_stor_huawei_e220_init(struct us_data *us)
 {
        int result;
 
@@ -104,75 +104,3 @@ static int usb_stor_huawei_feature_init(struct us_data *us)
        US_DEBUGP("Huawei mode set result is %d\n", result);
        return 0;
 }
-
-/*
- * It will send a scsi switch command called rewind' to huawei dongle.
- * When the dongle receives this command at the first time,
- * it will reboot immediately. After rebooted, it will ignore this command.
- * So it is  unnecessary to read its response.
- */
-static int usb_stor_huawei_scsi_init(struct us_data *us)
-{
-       int result = 0;
-       int act_len = 0;
-       struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf;
-       char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00,
-                       0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
-       bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN);
-       bcbw->Tag = 0;
-       bcbw->DataTransferLength = 0;
-       bcbw->Flags = bcbw->Lun = 0;
-       bcbw->Length = sizeof(rewind_cmd);
-       memset(bcbw->CDB, 0, sizeof(bcbw->CDB));
-       memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd));
-
-       result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw,
-                                       US_BULK_CB_WRAP_LEN, &act_len);
-       US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result);
-       return result;
-}
-
-/*
- * It tries to find the supported Huawei USB dongles.
- * In Huawei, they assign the following product IDs
- * for all of their mobile broadband dongles,
- * including the new dongles in the future.
- * So if the product ID is not included in this list,
- * it means it is not Huawei's mobile broadband dongles.
- */
-static int usb_stor_huawei_dongles_pid(struct us_data *us)
-{
-       struct usb_interface_descriptor *idesc;
-       int idProduct;
-
-       idesc = &us->pusb_intf->cur_altsetting->desc;
-       idProduct = le16_to_cpu(us->pusb_dev->descriptor.idProduct);
-       /* The first port is CDROM,
-        * means the dongle in the single port mode,
-        * and a switch command is required to be sent. */
-       if (idesc && idesc->bInterfaceNumber == 0) {
-               if ((idProduct == 0x1001)
-                       || (idProduct == 0x1003)
-                       || (idProduct == 0x1004)
-                       || (idProduct >= 0x1401 && idProduct <= 0x1500)
-                       || (idProduct >= 0x1505 && idProduct <= 0x1600)
-                       || (idProduct >= 0x1c02 && idProduct <= 0x2202)) {
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-int usb_stor_huawei_init(struct us_data *us)
-{
-       int result = 0;
-
-       if (usb_stor_huawei_dongles_pid(us)) {
-               if (le16_to_cpu(us->pusb_dev->descriptor.idProduct) >= 0x1446)
-                       result = usb_stor_huawei_scsi_init(us);
-               else
-                       result = usb_stor_huawei_feature_init(us);
-       }
-       return result;
-}
index 5376d4fc76f04c25092244765237f94f44456ba1..529327fbb06be1b6876e8802b84bd281287291c3 100644 (file)
@@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data *us);
  * flash reader */
 int usb_stor_ucr61s2b_init(struct us_data *us);
 
-/* This places the HUAWEI usb dongles in multi-port mode */
-int usb_stor_huawei_init(struct us_data *us);
+/* This places the HUAWEI E220 devices in multi-port mode */
+int usb_stor_huawei_e220_init(struct us_data *us);
index 72923b56bbf6b871a6da926168d43cf8db3e6383..da04a074e7900c8dcc413bf761d5f471e29218a3 100644 (file)
  * as opposed to devices that do something strangely or wrongly.
  */
 
+/* In-kernel mode switching is deprecated.  Do not add new devices to
+ * this list for the sole purpose of switching them to a different
+ * mode.  Existing userspace solutions are superior.
+ *
+ * New mode switching devices should instead be added to the database
+ * maintained at http://www.draisberghof.de/usb_modeswitch/
+ */
+
 #if !defined(CONFIG_USB_STORAGE_SDDR09) && \
                !defined(CONFIG_USB_STORAGE_SDDR09_MODULE)
 #define NO_SDDR09
@@ -1527,10 +1535,335 @@ UNUSUAL_DEV(  0x1210, 0x0003, 0x0100, 0x0100,
 /* Reported by fangxiaozhi <huananhu@huawei.com>
  * This brings the HUAWEI data card devices into multi-port mode
  */
-UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50,
+UNUSUAL_DEV(  0x12d1, 0x1001, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1003, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1004, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1401, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1402, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1403, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1404, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1405, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1406, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1407, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1408, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1409, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x140A, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x140B, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x140C, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x140D, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x140E, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x140F, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1410, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1411, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1412, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1413, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1414, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1415, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1416, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1417, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1418, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1419, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141A, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141B, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141C, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141D, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141E, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x141F, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1420, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1421, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1422, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1423, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1424, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1425, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1426, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1427, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1428, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1429, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142A, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142B, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142C, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142D, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142E, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x142F, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1430, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1431, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1432, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1433, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1434, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1435, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1436, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1437, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1438, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x1439, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143A, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143B, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143C, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143D, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143E, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV(  0x12d1, 0x143F, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
-               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init,
+               USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
 
 /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */
index ed4cad87fbcdb39717e283ed8b764312b745fff3..4a5f2cd3d3bf01a5776df21c137ce11586109689 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/lcd.h>
 #include <linux/gpio.h>
 
+#include <mach/hardware.h>
 #include <mach/board-ams-delta.h>
 
 #include "omapfb.h"
index 3aa62da89195949d89e7dd3bb4d44cc60342c7d4..7fbe04bce0ed6402371edf515641175c4d8320bf 100644 (file)
 #include <linux/platform_device.h>
 
 #include <asm/gpio.h>
+
+#include <mach/hardware.h>
 #include <mach/mux.h>
+
 #include "omapfb.h"
 
 static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
index d39dfa4cc23570b9c6cc8e57e7aa3a8d759a007b..46d97014342ef1f27f37046332e35d6e40a5b108 100644 (file)
@@ -47,11 +47,13 @@ static u8 w1_gpio_read_bit(void *data)
        return gpio_get_value(pdata->pin) ? 1 : 0;
 }
 
+#if defined(CONFIG_OF)
 static struct of_device_id w1_gpio_dt_ids[] = {
        { .compatible = "w1-gpio" },
        {}
 };
 MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids);
+#endif
 
 static int w1_gpio_probe_dt(struct platform_device *pdev)
 {
@@ -158,7 +160,7 @@ static int w1_gpio_probe(struct platform_device *pdev)
        return err;
 }
 
-static int __exit w1_gpio_remove(struct platform_device *pdev)
+static int w1_gpio_remove(struct platform_device *pdev)
 {
        struct w1_bus_master *master = platform_get_drvdata(pdev);
        struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
@@ -210,7 +212,7 @@ static struct platform_driver w1_gpio_driver = {
                .of_match_table = of_match_ptr(w1_gpio_dt_ids),
        },
        .probe = w1_gpio_probe,
-       .remove = __exit_p(w1_gpio_remove),
+       .remove = w1_gpio_remove,
        .suspend = w1_gpio_suspend,
        .resume = w1_gpio_resume,
 };
index 7994d933f040bd85ef9f26dfee1587c38e37cba5..7ce277d2bb676182dcbcddae1f500a77ae038842 100644 (file)
@@ -924,7 +924,8 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb
                        tmp64 = (triplet_ret >> 2);
                        rn |= (tmp64 << i);
 
-                       if (kthread_should_stop()) {
+                       /* ensure we're called from kthread and not by netlink callback */
+                       if (!dev->priv && kthread_should_stop()) {
                                mutex_unlock(&dev->bus_mutex);
                                dev_dbg(&dev->dev, "Abort w1_search\n");
                                return;
index 316df65163cfa5d6485a256edf2cdab24e8805d6..f3278a6603ca3b0913280f4bfa5c7e07c0eff47a 100644 (file)
@@ -500,16 +500,16 @@ static int __init xen_acpi_processor_init(void)
        (void)acpi_processor_preregister_performance(acpi_perf_data);
 
        for_each_possible_cpu(i) {
+               struct acpi_processor *pr;
                struct acpi_processor_performance *perf;
 
+               pr = per_cpu(processors, i);
                perf = per_cpu_ptr(acpi_perf_data, i);
-               rc = acpi_processor_register_performance(perf, i);
+               pr->performance = perf;
+               rc = acpi_processor_get_performance_info(pr);
                if (rc)
                        goto err_out;
        }
-       rc = acpi_processor_notify_smm(THIS_MODULE);
-       if (rc)
-               goto err_unregister;
 
        for_each_possible_cpu(i) {
                struct acpi_processor *_pr;
index 37c1f825f513764c998e808acf482d9d20cda7e0..b98cf0c35725a1714afbc498ee1ab49864eb1ff3 100644 (file)
@@ -113,7 +113,8 @@ void xen_pcibk_reset_device(struct pci_dev *dev)
                if (dev->msi_enabled)
                        pci_disable_msi(dev);
 #endif
-               pci_disable_device(dev);
+               if (pci_is_enabled(dev))
+                       pci_disable_device(dev);
 
                pci_write_config_word(dev, PCI_COMMAND, 0);
 
index d85e411cbf8924ceaf8e3947ab961e1c5ea68744..bbef194c5b0183181f74405103ebeb782935c33f 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/export.h>
 #include <linux/types.h>
 #include <linux/acpi.h>
-#include <acpi/acpi_drivers.h>
 #include <xen/acpi.h>
 
 #ifdef CONFIG_ACPI
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 3e074dab2d57a3e39ad16538f7a51bfde8e4ed91..9ac2eca681ebb09c605612dd563bc4417e4fc587 100644 (file)
@@ -1467,8 +1467,11 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
        if (ret && !insert) {
                err = -ENOENT;
                goto out;
+       } else if (ret) {
+               err = -EIO;
+               WARN_ON(1);
+               goto out;
        }
-       BUG_ON(ret); /* Corruption */
 
        leaf = path->nodes[0];
        item_size = btrfs_item_size_nr(leaf, path->slots[0]);
index af1d0605a5c1e74b3f30392d4e28c0faf34400ad..5b4ea5f55b8f47d0bf9a90992dd9da2d33880e14 100644 (file)
@@ -591,6 +591,7 @@ void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
                }
                compressed = test_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
                clear_bit(EXTENT_FLAG_PINNED, &em->flags);
+               clear_bit(EXTENT_FLAG_LOGGING, &flags);
                remove_extent_mapping(em_tree, em);
                if (no_splits)
                        goto next;
index c226daefd65d20a7c635723926f978172f53aaa6..ca1b767d51f760672f8de72c48efbf3df8e58a75 100644 (file)
@@ -2312,6 +2312,7 @@ again:
        key.type = BTRFS_EXTENT_DATA_KEY;
        key.offset = start;
 
+       path->leave_spinning = 1;
        if (merge) {
                struct btrfs_file_extent_item *fi;
                u64 extent_len;
@@ -2368,6 +2369,7 @@ again:
 
        btrfs_mark_buffer_dirty(leaf);
        inode_add_bytes(inode, len);
+       btrfs_release_path(path);
 
        ret = btrfs_inc_extent_ref(trans, root, new->bytenr,
                        new->disk_len, 0,
@@ -2381,6 +2383,7 @@ again:
        ret = 1;
 out_free_path:
        btrfs_release_path(path);
+       path->leave_spinning = 0;
        btrfs_end_transaction(trans, root);
 out_unlock:
        unlock_extent_cached(&BTRFS_I(inode)->io_tree, lock_start, lock_end,
@@ -8502,6 +8505,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 +8520,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 ca52681e5f4049c45f2a228a3f8237ca23815772..b81e0e9a48941891681eef385d10d071f6cbe51b 100644 (file)
@@ -26,7 +26,6 @@
 
 void btrfs_tree_lock(struct extent_buffer *eb);
 void btrfs_tree_unlock(struct extent_buffer *eb);
-int btrfs_try_spin_lock(struct extent_buffer *eb);
 
 void btrfs_tree_read_lock(struct extent_buffer *eb);
 void btrfs_tree_read_unlock(struct extent_buffer *eb);
index aee4b1cc3d988ccc0dbde615000d07bcf5d35051..5471e47d6559eafeb36e55035cb427710c5ee4ba 100644 (file)
@@ -1525,21 +1525,23 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
 
                if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) &&
                    qg->reserved + qg->rfer + num_bytes >
-                   qg->max_rfer)
+                   qg->max_rfer) {
                        ret = -EDQUOT;
+                       goto out;
+               }
 
                if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) &&
                    qg->reserved + qg->excl + num_bytes >
-                   qg->max_excl)
+                   qg->max_excl) {
                        ret = -EDQUOT;
+                       goto out;
+               }
 
                list_for_each_entry(glist, &qg->groups, next_group) {
                        ulist_add(ulist, glist->group->qgroupid,
                                  (uintptr_t)glist->group, GFP_ATOMIC);
                }
        }
-       if (ret)
-               goto out;
 
        /*
         * no limits exceeded, now record the reservation into all qgroups
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..50767bbaad6c6bfeb40e4d0e815446effd5392b3 100644 (file)
@@ -625,14 +625,13 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
 
        btrfs_trans_release_metadata(trans, root);
        trans->block_rsv = NULL;
-       /*
-        * the same root has to be passed to start_transaction and
-        * end_transaction. Subvolume quota depends on this.
-        */
-       WARN_ON(trans->root != root);
 
        if (trans->qgroup_reserved) {
-               btrfs_qgroup_free(root, trans->qgroup_reserved);
+               /*
+                * the same root has to be passed here between start_transaction
+                * and end_transaction. Subvolume quota depends on this.
+                */
+               btrfs_qgroup_free(trans->root, trans->qgroup_reserved);
                trans->qgroup_reserved = 0;
        }
 
@@ -1052,7 +1051,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 +1075,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 +1084,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 +1141,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 +1272,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 +1289,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 +1455,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..5989a92236f7f1b578ec3ccf88078bb69c1093d3 100644 (file)
@@ -684,6 +684,12 @@ int btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
                __btrfs_close_devices(fs_devices);
                free_fs_devices(fs_devices);
        }
+       /*
+        * Wait for rcu kworkers under __btrfs_close_devices
+        * to finish all blkdev_puts so device is really
+        * free when umount is done.
+        */
+       rcu_barrier();
        return ret;
 }
 
@@ -2379,7 +2385,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 +3060,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 +3241,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 1a052c0eee8eae9181e0e58ac5d0ff8852c0db8e..3cf8a15af91607bf000467e3c7c166337a8148f0 100644 (file)
@@ -777,6 +777,7 @@ struct file_system_type cifs_fs_type = {
        .kill_sb = cifs_kill_sb,
        /*  .fs_flags */
 };
+MODULE_ALIAS_FS("cifs");
 const struct inode_operations cifs_dir_inode_ops = {
        .create = cifs_create,
        .atomic_open = cifs_atomic_open,
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 fe40fde291111b0f4d521756403dbc530be4da8a..d487985dd0ead4261079ff4157d7245d2ea6e2bb 100644 (file)
@@ -558,6 +558,10 @@ ssize_t compat_rw_copy_check_uvector(int type,
        }
        *ret_pointer = iov;
 
+       ret = -EFAULT;
+       if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
+               goto out;
+
        /*
         * Single unix specification:
         * We should -EINVAL if an element length is not >= 0 and fitting an
@@ -1080,17 +1084,12 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
        if (!file->f_op)
                goto out;
 
-       ret = -EFAULT;
-       if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
-               goto out;
-
-       tot_len = compat_rw_copy_check_uvector(type, uvector, nr_segs,
+       ret = compat_rw_copy_check_uvector(type, uvector, nr_segs,
                                               UIO_FASTIOV, iovstack, &iov);
-       if (tot_len == 0) {
-               ret = 0;
+       if (ret <= 0)
                goto out;
-       }
 
+       tot_len = ret;
        ret = rw_verify_area(type, file, pos, tot_len);
        if (ret < 0)
                goto out;
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 8f370e012e613e73016856a9cab3c6257666a1a1..7cadd823bb311643a6cb7042222870767224b4c9 100644 (file)
@@ -118,7 +118,6 @@ void ext2_free_inode (struct inode * inode)
         * as writing the quota to disk may need the lock as well.
         */
        /* Quota is already initialized in iput() */
-       ext2_xattr_delete_inode(inode);
        dquot_free_inode(inode);
        dquot_drop(inode);
 
index c3881e56662efac8c80ec409c5808771303ed24f..fe60cc1117d834a1fbdc086b9aad01367518903b 100644 (file)
@@ -34,6 +34,7 @@
 #include "ext2.h"
 #include "acl.h"
 #include "xip.h"
+#include "xattr.h"
 
 static int __ext2_write_inode(struct inode *inode, int do_sync);
 
@@ -88,6 +89,7 @@ void ext2_evict_inode(struct inode * inode)
                inode->i_size = 0;
                if (inode->i_blocks)
                        ext2_truncate_blocks(inode, 0);
+               ext2_xattr_delete_inode(inode);
        }
 
        invalidate_inode_buffers(inode);
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..fb5120a5505c055b9de9e7b948713256329cf690 100644 (file)
@@ -353,7 +353,7 @@ static struct block_device *ext3_blkdev_get(dev_t dev, struct super_block *sb)
        return bdev;
 
 fail:
-       ext3_msg(sb, "error: failed to open journal device %s: %ld",
+       ext3_msg(sb, KERN_ERR, "error: failed to open journal device %s: %ld",
                __bdevname(dev, b), PTR_ERR(bdev));
 
        return NULL;
@@ -887,7 +887,7 @@ static ext3_fsblk_t get_sb_block(void **data, struct super_block *sb)
        /*todo: use simple_strtoll with >32bit ext3 */
        sb_block = simple_strtoul(options, &options, 0);
        if (*options && *options != ',') {
-               ext3_msg(sb, "error: invalid sb specification: %s",
+               ext3_msg(sb, KERN_ERR, "error: invalid sb specification: %s",
                       (char *) *data);
                return 1;
        }
@@ -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..b3818b48f418577ad5a7abeb979e1b7d1acd836b 100644 (file)
@@ -90,6 +90,8 @@ static struct file_system_type ext2_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("ext2");
+MODULE_ALIAS("ext2");
 #define IS_EXT2_SB(sb) ((sb)->s_bdev->bd_holder == &ext2_fs_type)
 #else
 #define IS_EXT2_SB(sb) (0)
@@ -104,6 +106,8 @@ static struct file_system_type ext3_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("ext3");
+MODULE_ALIAS("ext3");
 #define IS_EXT3_SB(sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type)
 #else
 #define IS_EXT3_SB(sb) (0)
@@ -5152,7 +5156,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 +5188,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 +5201,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..e37eb274e492a9dfd36d4f717d363b6932ae90b5 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,8 @@ 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 */
+MODULE_ALIAS("vxfs");
 
 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 fbabb906066fa4756c846e6c6e6e577f00f1b6ed..0f6e52d22b8420fdbd3e5b315fe403d742c0a52f 100644 (file)
@@ -845,15 +845,8 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
                return err;
 
        if ((attr->ia_valid & ATTR_SIZE) &&
-           attr->ia_size != i_size_read(inode)) {
-               int error;
-
-               error = inode_newsize_ok(inode, attr->ia_size);
-               if (error)
-                       return error;
-
+           attr->ia_size != i_size_read(inode))
                truncate_setsize(inode, attr->ia_size);
-       }
 
        setattr_copy(inode, attr);
        mark_inode_dirty(inode);
@@ -993,6 +986,7 @@ static struct file_system_type hostfs_type = {
        .kill_sb        = hostfs_kill_sb,
        .fs_flags       = 0,
 };
+MODULE_ALIAS_FS("hostfs");
 
 static int __init init_hostfs(void)
 {
index a3076228523db4db7a105a966f6049a8570b705c..a0617e7069579c61baed047b3ba2992b294d6082 100644 (file)
@@ -688,6 +688,7 @@ static struct file_system_type hpfs_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("hpfs");
 
 static int __init init_hpfs_fs(void)
 {
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..d9b8aebdeb22b467eb9717996b823734f8446300 100644 (file)
@@ -1556,6 +1556,8 @@ static struct file_system_type iso9660_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("iso9660");
+MODULE_ALIAS("iso9660");
 
 static int __init init_iso9660_fs(void)
 {
@@ -1593,5 +1595,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..2f8a29db0f1bed59a8300d64038ebe4404d611a6 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,8 @@ 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");
+MODULE_ALIAS("nfs4");
 EXPORT_SYMBOL_GPL(nfs4_fs_type);
 
 static int __init register_nfs4_fs(void)
@@ -2717,6 +2720,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 87fd1410b737e19093157452e42f10f12073676f..d5c5b3e00266219320720944a17a7e7be6feb811 100644 (file)
@@ -82,6 +82,7 @@ int   nfsd_reply_cache_init(void);
 void   nfsd_reply_cache_shutdown(void);
 int    nfsd_cache_lookup(struct svc_rqst *);
 void   nfsd_cache_update(struct svc_rqst *, int, __be32 *);
+int    nfsd_reply_cache_stats_open(struct inode *, struct file *);
 
 #ifdef CONFIG_NFSD_V4
 void   nfsd4_set_statp(struct svc_rqst *rqstp, __be32 *statp);
index 1051bebff1b0d5c0c1da8d82043506d7eca465d3..849a7c3ced22cbacf33c3fa3e33802b43e3fb798 100644 (file)
@@ -80,6 +80,7 @@ struct nfsd_net {
         */
        struct list_head client_lru;
        struct list_head close_lru;
+       struct list_head del_recall_lru;
 
        struct delayed_work laundromat_work;
 
index 99bc85ff02179f3e28ed36f56872e1e48d190e21..7f05cd140de3cb2a8c75665bdbcad8bb3d823582 100644 (file)
@@ -37,6 +37,7 @@
 #include "nfsd.h"
 #include "state.h"
 #include "netns.h"
+#include "xdr4cb.h"
 
 #define NFSDDBG_FACILITY                NFSDDBG_PROC
 
@@ -53,30 +54,6 @@ enum {
        NFSPROC4_CLNT_CB_SEQUENCE,
 };
 
-#define NFS4_MAXTAGLEN         20
-
-#define NFS4_enc_cb_null_sz            0
-#define NFS4_dec_cb_null_sz            0
-#define cb_compound_enc_hdr_sz         4
-#define cb_compound_dec_hdr_sz         (3 + (NFS4_MAXTAGLEN >> 2))
-#define sessionid_sz                   (NFS4_MAX_SESSIONID_LEN >> 2)
-#define cb_sequence_enc_sz             (sessionid_sz + 4 +             \
-                                       1 /* no referring calls list yet */)
-#define cb_sequence_dec_sz             (op_dec_sz + sessionid_sz + 4)
-
-#define op_enc_sz                      1
-#define op_dec_sz                      2
-#define enc_nfs4_fh_sz                 (1 + (NFS4_FHSIZE >> 2))
-#define enc_stateid_sz                 (NFS4_STATEID_SIZE >> 2)
-#define NFS4_enc_cb_recall_sz          (cb_compound_enc_hdr_sz +       \
-                                       cb_sequence_enc_sz +            \
-                                       1 + enc_stateid_sz +            \
-                                       enc_nfs4_fh_sz)
-
-#define NFS4_dec_cb_recall_sz          (cb_compound_dec_hdr_sz  +      \
-                                       cb_sequence_dec_sz +            \
-                                       op_dec_sz)
-
 struct nfs4_cb_compound_hdr {
        /* args */
        u32             ident;  /* minorversion 0 only */
@@ -817,8 +794,7 @@ static bool nfsd41_cb_get_slot(struct nfs4_client *clp, struct rpc_task *task)
 static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata)
 {
        struct nfsd4_callback *cb = calldata;
-       struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall);
-       struct nfs4_client *clp = dp->dl_stid.sc_client;
+       struct nfs4_client *clp = cb->cb_clp;
        u32 minorversion = clp->cl_minorversion;
 
        cb->cb_minorversion = minorversion;
@@ -839,8 +815,7 @@ static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata)
 static void nfsd4_cb_done(struct rpc_task *task, void *calldata)
 {
        struct nfsd4_callback *cb = calldata;
-       struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall);
-       struct nfs4_client *clp = dp->dl_stid.sc_client;
+       struct nfs4_client *clp = cb->cb_clp;
 
        dprintk("%s: minorversion=%d\n", __func__,
                clp->cl_minorversion);
@@ -863,7 +838,7 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
 {
        struct nfsd4_callback *cb = calldata;
        struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall);
-       struct nfs4_client *clp = dp->dl_stid.sc_client;
+       struct nfs4_client *clp = cb->cb_clp;
        struct rpc_clnt *current_rpc_client = clp->cl_cb_client;
 
        nfsd4_cb_done(task, calldata);
index ae73175e6e6854fda740bd5a0dd88d17f14d556f..5dee81141ab71983f0f8985d1969fc8ab738a967 100644 (file)
@@ -191,9 +191,18 @@ static __be32 nfsd_check_obj_isreg(struct svc_fh *fh)
        return nfserr_symlink;
 }
 
+static void nfsd4_set_open_owner_reply_cache(struct nfsd4_compound_state *cstate, struct nfsd4_open *open, struct svc_fh *resfh)
+{
+       if (nfsd4_has_session(cstate))
+               return;
+       fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh,
+                       &resfh->fh_handle);
+}
+
 static __be32
-do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
+do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
 {
+       struct svc_fh *current_fh = &cstate->current_fh;
        struct svc_fh *resfh;
        int accmode;
        __be32 status;
@@ -252,9 +261,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o
        if (is_create_with_attrs(open) && open->op_acl != NULL)
                do_set_nfs4_acl(rqstp, resfh, open->op_acl, open->op_bmval);
 
-       /* set reply cache */
-       fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh,
-                       &resfh->fh_handle);
+       nfsd4_set_open_owner_reply_cache(cstate, open, resfh);
        accmode = NFSD_MAY_NOP;
        if (open->op_created)
                accmode |= NFSD_MAY_OWNER_OVERRIDE;
@@ -268,8 +275,9 @@ out:
 }
 
 static __be32
-do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open)
+do_open_fhandle(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
 {
+       struct svc_fh *current_fh = &cstate->current_fh;
        __be32 status;
 
        /* We don't know the target directory, and therefore can not
@@ -278,9 +286,7 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_
 
        memset(&open->op_cinfo, 0, sizeof(struct nfsd4_change_info));
 
-       /* set replay cache */
-       fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh,
-                       &current_fh->fh_handle);
+       nfsd4_set_open_owner_reply_cache(cstate, open, current_fh);
 
        open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) &&
                (open->op_iattr.ia_size == 0);
@@ -351,6 +357,10 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        }
        if (status)
                goto out;
+       if (open->op_xdr_error) {
+               status = open->op_xdr_error;
+               goto out;
+       }
 
        status = nfsd4_check_open_attributes(rqstp, cstate, open);
        if (status)
@@ -368,8 +378,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        switch (open->op_claim_type) {
                case NFS4_OPEN_CLAIM_DELEGATE_CUR:
                case NFS4_OPEN_CLAIM_NULL:
-                       status = do_open_lookup(rqstp, &cstate->current_fh,
-                                               open);
+                       status = do_open_lookup(rqstp, cstate, open);
                        if (status)
                                goto out;
                        break;
@@ -382,8 +391,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                                goto out;
                case NFS4_OPEN_CLAIM_FH:
                case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
-                       status = do_open_fhandle(rqstp, &cstate->current_fh,
-                                                open);
+                       status = do_open_fhandle(rqstp, cstate, open);
                        if (status)
                                goto out;
                        break;
@@ -409,13 +417,32 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        WARN_ON(status && open->op_created);
 out:
        nfsd4_cleanup_open_state(open, status);
-       if (open->op_openowner)
+       if (open->op_openowner && !nfsd4_has_session(cstate))
                cstate->replay_owner = &open->op_openowner->oo_owner;
-       else
+       nfsd4_bump_seqid(cstate, status);
+       if (!cstate->replay_owner)
                nfs4_unlock_state();
        return status;
 }
 
+/*
+ * OPEN is the only seqid-mutating operation whose decoding can fail
+ * with a seqid-mutating error (specifically, decoding of user names in
+ * the attributes).  Therefore we have to do some processing to look up
+ * the stateowner so that we can bump the seqid.
+ */
+static __be32 nfsd4_open_omfg(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_op *op)
+{
+       struct nfsd4_open *open = (struct nfsd4_open *)&op->u;
+
+       if (!seqid_mutating_err(ntohl(op->status)))
+               return op->status;
+       if (nfsd4_has_session(cstate))
+               return op->status;
+       open->op_xdr_error = op->status;
+       return nfsd4_open(rqstp, cstate, open);
+}
+
 /*
  * filehandle-manipulating ops.
  */
@@ -931,14 +958,14 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        nfs4_lock_state();
        status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
                                        cstate, stateid, WR_STATE, &filp);
-       if (filp)
-               get_file(filp);
-       nfs4_unlock_state();
-
        if (status) {
+               nfs4_unlock_state();
                dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
                return status;
        }
+       if (filp)
+               get_file(filp);
+       nfs4_unlock_state();
 
        cnt = write->wr_buflen;
        write->wr_how_written = write->wr_stable_how;
@@ -1244,8 +1271,11 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
                 * for example, if there is a miscellaneous XDR error
                 * it will be set to nfserr_bad_xdr.
                 */
-               if (op->status)
+               if (op->status) {
+                       if (op->opnum == OP_OPEN)
+                               op->status = nfsd4_open_omfg(rqstp, cstate, op);
                        goto encode_op;
+               }
 
                /* We must be able to encode a successful response to
                 * this operation, with enough room left over to encode a
@@ -1282,12 +1312,9 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
                if (op->status)
                        goto encode_op;
 
-               if (opdesc->op_func) {
-                       if (opdesc->op_get_currentstateid)
-                               opdesc->op_get_currentstateid(cstate, &op->u);
-                       op->status = opdesc->op_func(rqstp, cstate, &op->u);
-               } else
-                       BUG_ON(op->status == nfs_ok);
+               if (opdesc->op_get_currentstateid)
+                       opdesc->op_get_currentstateid(cstate, &op->u);
+               op->status = opdesc->op_func(rqstp, cstate, &op->u);
 
                if (!op->status) {
                        if (opdesc->op_set_currentstateid)
index 16d39c6c4fbb56b11c25ac8927b8913b1a928a15..e39bf5381bca2c78e3cad61fcc750c653f95248a 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/sunrpc/svcauth_gss.h>
 #include <linux/sunrpc/addr.h>
 #include "xdr4.h"
+#include "xdr4cb.h"
 #include "vfs.h"
 #include "current_stateid.h"
 
@@ -94,17 +95,32 @@ nfs4_lock_state(void)
        mutex_lock(&client_mutex);
 }
 
-static void free_session(struct kref *);
+static void free_session(struct nfsd4_session *);
 
-/* Must be called under the client_lock */
-static void nfsd4_put_session_locked(struct nfsd4_session *ses)
+void nfsd4_put_session(struct nfsd4_session *ses)
+{
+       atomic_dec(&ses->se_ref);
+}
+
+static bool is_session_dead(struct nfsd4_session *ses)
+{
+       return ses->se_flags & NFS4_SESSION_DEAD;
+}
+
+static __be32 mark_session_dead_locked(struct nfsd4_session *ses)
 {
-       kref_put(&ses->se_ref, free_session);
+       if (atomic_read(&ses->se_ref))
+               return nfserr_jukebox;
+       ses->se_flags |= NFS4_SESSION_DEAD;
+       return nfs_ok;
 }
 
-static void nfsd4_get_session(struct nfsd4_session *ses)
+static __be32 nfsd4_get_session_locked(struct nfsd4_session *ses)
 {
-       kref_get(&ses->se_ref);
+       if (is_session_dead(ses))
+               return nfserr_badsession;
+       atomic_inc(&ses->se_ref);
+       return nfs_ok;
 }
 
 void
@@ -113,6 +129,90 @@ nfs4_unlock_state(void)
        mutex_unlock(&client_mutex);
 }
 
+static bool is_client_expired(struct nfs4_client *clp)
+{
+       return clp->cl_time == 0;
+}
+
+static __be32 mark_client_expired_locked(struct nfs4_client *clp)
+{
+       if (atomic_read(&clp->cl_refcount))
+               return nfserr_jukebox;
+       clp->cl_time = 0;
+       return nfs_ok;
+}
+
+static __be32 mark_client_expired(struct nfs4_client *clp)
+{
+       struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
+       __be32 ret;
+
+       spin_lock(&nn->client_lock);
+       ret = mark_client_expired_locked(clp);
+       spin_unlock(&nn->client_lock);
+       return ret;
+}
+
+static __be32 get_client_locked(struct nfs4_client *clp)
+{
+       if (is_client_expired(clp))
+               return nfserr_expired;
+       atomic_inc(&clp->cl_refcount);
+       return nfs_ok;
+}
+
+/* must be called under the client_lock */
+static inline void
+renew_client_locked(struct nfs4_client *clp)
+{
+       struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
+
+       if (is_client_expired(clp)) {
+               WARN_ON(1);
+               printk("%s: client (clientid %08x/%08x) already expired\n",
+                       __func__,
+                       clp->cl_clientid.cl_boot,
+                       clp->cl_clientid.cl_id);
+               return;
+       }
+
+       dprintk("renewing client (clientid %08x/%08x)\n",
+                       clp->cl_clientid.cl_boot,
+                       clp->cl_clientid.cl_id);
+       list_move_tail(&clp->cl_lru, &nn->client_lru);
+       clp->cl_time = get_seconds();
+}
+
+static inline void
+renew_client(struct nfs4_client *clp)
+{
+       struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
+
+       spin_lock(&nn->client_lock);
+       renew_client_locked(clp);
+       spin_unlock(&nn->client_lock);
+}
+
+static void put_client_renew_locked(struct nfs4_client *clp)
+{
+       if (!atomic_dec_and_test(&clp->cl_refcount))
+               return;
+       if (!is_client_expired(clp))
+               renew_client_locked(clp);
+}
+
+void put_client_renew(struct nfs4_client *clp)
+{
+       struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
+
+       if (!atomic_dec_and_lock(&clp->cl_refcount, &nn->client_lock))
+               return;
+       if (!is_client_expired(clp))
+               renew_client_locked(clp);
+       spin_unlock(&nn->client_lock);
+}
+
+
 static inline u32
 opaque_hashval(const void *ptr, int nbytes)
 {
@@ -126,8 +226,6 @@ opaque_hashval(const void *ptr, int nbytes)
        return x;
 }
 
-static struct list_head del_recall_lru;
-
 static void nfsd4_free_file(struct nfs4_file *f)
 {
        kmem_cache_free(file_slab, f);
@@ -137,7 +235,7 @@ static inline void
 put_nfs4_file(struct nfs4_file *fi)
 {
        if (atomic_dec_and_lock(&fi->fi_ref, &recall_lock)) {
-               list_del(&fi->fi_hash);
+               hlist_del(&fi->fi_hash);
                spin_unlock(&recall_lock);
                iput(fi->fi_inode);
                nfsd4_free_file(fi);
@@ -181,7 +279,7 @@ static unsigned int file_hashval(struct inode *ino)
        return hash_ptr(ino, FILE_HASH_BITS);
 }
 
-static struct list_head file_hashtbl[FILE_HASH_SIZE];
+static struct hlist_head file_hashtbl[FILE_HASH_SIZE];
 
 static void __nfs4_file_get_access(struct nfs4_file *fp, int oflag)
 {
@@ -210,13 +308,7 @@ static void __nfs4_file_put_access(struct nfs4_file *fp, int oflag)
 {
        if (atomic_dec_and_test(&fp->fi_access[oflag])) {
                nfs4_file_put_fd(fp, oflag);
-               /*
-                * It's also safe to get rid of the RDWR open *if*
-                * we no longer have need of the other kind of access
-                * or if we already have the other kind of open:
-                */
-               if (fp->fi_fds[1-oflag]
-                       || atomic_read(&fp->fi_access[1 - oflag]) == 0)
+               if (atomic_read(&fp->fi_access[1 - oflag]) == 0)
                        nfs4_file_put_fd(fp, O_RDWR);
        }
 }
@@ -230,37 +322,6 @@ static void nfs4_file_put_access(struct nfs4_file *fp, int oflag)
                __nfs4_file_put_access(fp, oflag);
 }
 
-static inline int get_new_stid(struct nfs4_stid *stid)
-{
-       static int min_stateid = 0;
-       struct idr *stateids = &stid->sc_client->cl_stateids;
-       int new_stid;
-       int error;
-
-       error = idr_get_new_above(stateids, stid, min_stateid, &new_stid);
-       /*
-        * Note: the necessary preallocation was done in
-        * nfs4_alloc_stateid().  The idr code caps the number of
-        * preallocations that can exist at a time, but the state lock
-        * prevents anyone from using ours before we get here:
-        */
-       WARN_ON_ONCE(error);
-       /*
-        * It shouldn't be a problem to reuse an opaque stateid value.
-        * I don't think it is for 4.1.  But with 4.0 I worry that, for
-        * example, a stray write retransmission could be accepted by
-        * the server when it should have been rejected.  Therefore,
-        * adopt a trick from the sctp code to attempt to maximize the
-        * amount of time until an id is reused, by ensuring they always
-        * "increase" (mod INT_MAX):
-        */
-
-       min_stateid = new_stid+1;
-       if (min_stateid == INT_MAX)
-               min_stateid = 0;
-       return new_stid;
-}
-
 static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct
 kmem_cache *slab)
 {
@@ -273,9 +334,8 @@ kmem_cache *slab)
        if (!stid)
                return NULL;
 
-       if (!idr_pre_get(stateids, GFP_KERNEL))
-               goto out_free;
-       if (idr_get_new_above(stateids, stid, min_stateid, &new_id))
+       new_id = idr_alloc(stateids, stid, min_stateid, 0, GFP_KERNEL);
+       if (new_id < 0)
                goto out_free;
        stid->sc_client = cl;
        stid->sc_type = 0;
@@ -299,7 +359,7 @@ kmem_cache *slab)
                min_stateid = 0;
        return stid;
 out_free:
-       kfree(stid);
+       kmem_cache_free(slab, stid);
        return NULL;
 }
 
@@ -350,21 +410,18 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv
        return dp;
 }
 
-static void free_stid(struct nfs4_stid *s, struct kmem_cache *slab)
+static void remove_stid(struct nfs4_stid *s)
 {
        struct idr *stateids = &s->sc_client->cl_stateids;
 
        idr_remove(stateids, s->sc_stateid.si_opaque.so_id);
-       kmem_cache_free(slab, s);
 }
 
 void
 nfs4_put_delegation(struct nfs4_delegation *dp)
 {
        if (atomic_dec_and_test(&dp->dl_count)) {
-               dprintk("NFSD: freeing dp %p\n",dp);
-               put_nfs4_file(dp->dl_file);
-               free_stid(&dp->dl_stid, deleg_slab);
+               kmem_cache_free(deleg_slab, dp);
                num_delegations--;
        }
 }
@@ -388,16 +445,45 @@ static void unhash_stid(struct nfs4_stid *s)
 static void
 unhash_delegation(struct nfs4_delegation *dp)
 {
-       unhash_stid(&dp->dl_stid);
        list_del_init(&dp->dl_perclnt);
        spin_lock(&recall_lock);
        list_del_init(&dp->dl_perfile);
        list_del_init(&dp->dl_recall_lru);
        spin_unlock(&recall_lock);
        nfs4_put_deleg_lease(dp->dl_file);
+       put_nfs4_file(dp->dl_file);
+       dp->dl_file = NULL;
+}
+
+
+
+static void destroy_revoked_delegation(struct nfs4_delegation *dp)
+{
+       list_del_init(&dp->dl_recall_lru);
+       remove_stid(&dp->dl_stid);
+       nfs4_put_delegation(dp);
+}
+
+static void destroy_delegation(struct nfs4_delegation *dp)
+{
+       unhash_delegation(dp);
+       remove_stid(&dp->dl_stid);
        nfs4_put_delegation(dp);
 }
 
+static void revoke_delegation(struct nfs4_delegation *dp)
+{
+       struct nfs4_client *clp = dp->dl_stid.sc_client;
+
+       if (clp->cl_minorversion == 0)
+               destroy_delegation(dp);
+       else {
+               unhash_delegation(dp);
+               dp->dl_stid.sc_type = NFS4_REVOKED_DELEG_STID;
+               list_add(&dp->dl_recall_lru, &clp->cl_revoked);
+       }
+}
+
 /* 
  * SETCLIENTID state 
  */
@@ -538,7 +624,8 @@ static void close_generic_stateid(struct nfs4_ol_stateid *stp)
 
 static void free_generic_stateid(struct nfs4_ol_stateid *stp)
 {
-       free_stid(&stp->st_stid, stateid_slab);
+       remove_stid(&stp->st_stid);
+       kmem_cache_free(stateid_slab, stp);
 }
 
 static void release_lock_stateid(struct nfs4_ol_stateid *stp)
@@ -654,6 +741,28 @@ dump_sessionid(const char *fn, struct nfs4_sessionid *sessionid)
 }
 #endif
 
+/*
+ * Bump the seqid on cstate->replay_owner, and clear replay_owner if it
+ * won't be used for replay.
+ */
+void nfsd4_bump_seqid(struct nfsd4_compound_state *cstate, __be32 nfserr)
+{
+       struct nfs4_stateowner *so = cstate->replay_owner;
+
+       if (nfserr == nfserr_replay_me)
+               return;
+
+       if (!seqid_mutating_err(ntohl(nfserr))) {
+               cstate->replay_owner = NULL;
+               return;
+       }
+       if (!so)
+               return;
+       if (so->so_is_open_owner)
+               release_last_closed_stateid(openowner(so));
+       so->so_seqid++;
+       return;
+}
 
 static void
 gen_sessionid(struct nfsd4_session *ses)
@@ -694,17 +803,15 @@ free_session_slots(struct nfsd4_session *ses)
  * We don't actually need to cache the rpc and session headers, so we
  * can allocate a little less for each slot:
  */
-static inline int slot_bytes(struct nfsd4_channel_attrs *ca)
+static inline u32 slot_bytes(struct nfsd4_channel_attrs *ca)
 {
-       return ca->maxresp_cached - NFSD_MIN_HDR_SEQ_SZ;
-}
-
-static int nfsd4_sanitize_slot_size(u32 size)
-{
-       size -= NFSD_MIN_HDR_SEQ_SZ; /* We don't cache the rpc header */
-       size = min_t(u32, size, NFSD_SLOT_CACHE_SIZE);
+       u32 size;
 
-       return size;
+       if (ca->maxresp_cached < NFSD_MIN_HDR_SEQ_SZ)
+               size = 0;
+       else
+               size = ca->maxresp_cached - NFSD_MIN_HDR_SEQ_SZ;
+       return size + sizeof(struct nfsd4_slot);
 }
 
 /*
@@ -712,12 +819,12 @@ static int nfsd4_sanitize_slot_size(u32 size)
  * re-negotiate active sessions and reduce their slot usage to make
  * room for new connections. For now we just fail the create session.
  */
-static int nfsd4_get_drc_mem(int slotsize, u32 num)
+static u32 nfsd4_get_drc_mem(struct nfsd4_channel_attrs *ca)
 {
+       u32 slotsize = slot_bytes(ca);
+       u32 num = ca->maxreqs;
        int avail;
 
-       num = min_t(u32, num, NFSD_MAX_SLOTS_PER_SESSION);
-
        spin_lock(&nfsd_drc_lock);
        avail = min((unsigned long)NFSD_MAX_MEM_PER_SESSION,
                    nfsd_drc_max_mem - nfsd_drc_mem_used);
@@ -728,15 +835,19 @@ static int nfsd4_get_drc_mem(int slotsize, u32 num)
        return num;
 }
 
-static void nfsd4_put_drc_mem(int slotsize, int num)
+static void nfsd4_put_drc_mem(struct nfsd4_channel_attrs *ca)
 {
+       int slotsize = slot_bytes(ca);
+
        spin_lock(&nfsd_drc_lock);
-       nfsd_drc_mem_used -= slotsize * num;
+       nfsd_drc_mem_used -= slotsize * ca->maxreqs;
        spin_unlock(&nfsd_drc_lock);
 }
 
-static struct nfsd4_session *__alloc_session(int slotsize, int numslots)
+static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *attrs)
 {
+       int numslots = attrs->maxreqs;
+       int slotsize = slot_bytes(attrs);
        struct nfsd4_session *new;
        int mem, i;
 
@@ -749,8 +860,7 @@ static struct nfsd4_session *__alloc_session(int slotsize, int numslots)
                return NULL;
        /* allocate each struct nfsd4_slot and data cache in one piece */
        for (i = 0; i < numslots; i++) {
-               mem = sizeof(struct nfsd4_slot) + slotsize;
-               new->se_slots[i] = kzalloc(mem, GFP_KERNEL);
+               new->se_slots[i] = kzalloc(slotsize, GFP_KERNEL);
                if (!new->se_slots[i])
                        goto out_free;
        }
@@ -762,21 +872,6 @@ out_free:
        return NULL;
 }
 
-static void init_forechannel_attrs(struct nfsd4_channel_attrs *new,
-                                  struct nfsd4_channel_attrs *req,
-                                  int numslots, int slotsize,
-                                  struct nfsd_net *nn)
-{
-       u32 maxrpc = nn->nfsd_serv->sv_max_mesg;
-
-       new->maxreqs = numslots;
-       new->maxresp_cached = min_t(u32, req->maxresp_cached,
-                                       slotsize + NFSD_MIN_HDR_SEQ_SZ);
-       new->maxreq_sz = min_t(u32, req->maxreq_sz, maxrpc);
-       new->maxresp_sz = min_t(u32, req->maxresp_sz, maxrpc);
-       new->maxops = min_t(u32, req->maxops, NFSD_MAX_OPS_PER_COMPOUND);
-}
-
 static void free_conn(struct nfsd4_conn *c)
 {
        svc_xprt_put(c->cn_xprt);
@@ -793,8 +888,8 @@ static void nfsd4_conn_lost(struct svc_xpt_user *u)
                list_del(&c->cn_persession);
                free_conn(c);
        }
-       spin_unlock(&clp->cl_lock);
        nfsd4_probe_callback(clp);
+       spin_unlock(&clp->cl_lock);
 }
 
 static struct nfsd4_conn *alloc_conn(struct svc_rqst *rqstp, u32 flags)
@@ -878,59 +973,20 @@ static void nfsd4_del_conns(struct nfsd4_session *s)
 
 static void __free_session(struct nfsd4_session *ses)
 {
-       nfsd4_put_drc_mem(slot_bytes(&ses->se_fchannel), ses->se_fchannel.maxreqs);
        free_session_slots(ses);
        kfree(ses);
 }
 
-static void free_session(struct kref *kref)
+static void free_session(struct nfsd4_session *ses)
 {
-       struct nfsd4_session *ses;
-       struct nfsd_net *nn;
-
-       ses = container_of(kref, struct nfsd4_session, se_ref);
-       nn = net_generic(ses->se_client->net, nfsd_net_id);
+       struct nfsd_net *nn = net_generic(ses->se_client->net, nfsd_net_id);
 
        lockdep_assert_held(&nn->client_lock);
        nfsd4_del_conns(ses);
+       nfsd4_put_drc_mem(&ses->se_fchannel);
        __free_session(ses);
 }
 
-void nfsd4_put_session(struct nfsd4_session *ses)
-{
-       struct nfsd_net *nn = net_generic(ses->se_client->net, nfsd_net_id);
-
-       spin_lock(&nn->client_lock);
-       nfsd4_put_session_locked(ses);
-       spin_unlock(&nn->client_lock);
-}
-
-static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fchan,
-                                          struct nfsd_net *nn)
-{
-       struct nfsd4_session *new;
-       int numslots, slotsize;
-       /*
-        * Note decreasing slot size below client's request may
-        * make it difficult for client to function correctly, whereas
-        * decreasing the number of slots will (just?) affect
-        * performance.  When short on memory we therefore prefer to
-        * decrease number of slots instead of their size.
-        */
-       slotsize = nfsd4_sanitize_slot_size(fchan->maxresp_cached);
-       numslots = nfsd4_get_drc_mem(slotsize, fchan->maxreqs);
-       if (numslots < 1)
-               return NULL;
-
-       new = __alloc_session(slotsize, numslots);
-       if (!new) {
-               nfsd4_put_drc_mem(slotsize, numslots);
-               return NULL;
-       }
-       init_forechannel_attrs(&new->se_fchannel, fchan, numslots, slotsize, nn);
-       return new;
-}
-
 static void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, struct nfs4_client *clp, struct nfsd4_create_session *cses)
 {
        int idx;
@@ -945,7 +1001,7 @@ static void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, stru
        new->se_flags = cses->flags;
        new->se_cb_prog = cses->callback_prog;
        new->se_cb_sec = cses->cb_sec;
-       kref_init(&new->se_ref);
+       atomic_set(&new->se_ref, 0);
        idx = hash_sessionid(&new->se_sessionid);
        spin_lock(&nn->client_lock);
        list_add(&new->se_hash, &nn->sessionid_hashtbl[idx]);
@@ -953,7 +1009,8 @@ static void init_session(struct svc_rqst *rqstp, struct nfsd4_session *new, stru
        list_add(&new->se_perclnt, &clp->cl_sessions);
        spin_unlock(&clp->cl_lock);
        spin_unlock(&nn->client_lock);
-
+       memcpy(&new->se_fchannel, &cses->fore_channel,
+                       sizeof(struct nfsd4_channel_attrs));
        if (cses->flags & SESSION4_BACK_CHAN) {
                struct sockaddr *sa = svc_addr(rqstp);
                /*
@@ -1000,38 +1057,6 @@ unhash_session(struct nfsd4_session *ses)
        spin_unlock(&ses->se_client->cl_lock);
 }
 
-/* must be called under the client_lock */
-static inline void
-renew_client_locked(struct nfs4_client *clp)
-{
-       struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
-
-       if (is_client_expired(clp)) {
-               WARN_ON(1);
-               printk("%s: client (clientid %08x/%08x) already expired\n",
-                       __func__,
-                       clp->cl_clientid.cl_boot,
-                       clp->cl_clientid.cl_id);
-               return;
-       }
-
-       dprintk("renewing client (clientid %08x/%08x)\n", 
-                       clp->cl_clientid.cl_boot, 
-                       clp->cl_clientid.cl_id);
-       list_move_tail(&clp->cl_lru, &nn->client_lru);
-       clp->cl_time = get_seconds();
-}
-
-static inline void
-renew_client(struct nfs4_client *clp)
-{
-       struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
-
-       spin_lock(&nn->client_lock);
-       renew_client_locked(clp);
-       spin_unlock(&nn->client_lock);
-}
-
 /* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
 static int
 STALE_CLIENTID(clientid_t *clid, struct nfsd_net *nn)
@@ -1075,7 +1100,8 @@ free_client(struct nfs4_client *clp)
                ses = list_entry(clp->cl_sessions.next, struct nfsd4_session,
                                se_perclnt);
                list_del(&ses->se_perclnt);
-               nfsd4_put_session_locked(ses);
+               WARN_ON_ONCE(atomic_read(&ses->se_ref));
+               free_session(ses);
        }
        free_svc_cred(&clp->cl_cred);
        kfree(clp->cl_name.data);
@@ -1083,29 +1109,12 @@ free_client(struct nfs4_client *clp)
        kfree(clp);
 }
 
-void
-release_session_client(struct nfsd4_session *session)
-{
-       struct nfs4_client *clp = session->se_client;
-       struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
-
-       if (!atomic_dec_and_lock(&clp->cl_refcount, &nn->client_lock))
-               return;
-       if (is_client_expired(clp)) {
-               free_client(clp);
-               session->se_client = NULL;
-       } else
-               renew_client_locked(clp);
-       spin_unlock(&nn->client_lock);
-}
-
 /* must be called under the client_lock */
 static inline void
 unhash_client_locked(struct nfs4_client *clp)
 {
        struct nfsd4_session *ses;
 
-       mark_client_expired(clp);
        list_del(&clp->cl_lru);
        spin_lock(&clp->cl_lock);
        list_for_each_entry(ses, &clp->cl_sessions, se_perclnt)
@@ -1131,7 +1140,7 @@ destroy_client(struct nfs4_client *clp)
        spin_unlock(&recall_lock);
        while (!list_empty(&reaplist)) {
                dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
-               unhash_delegation(dp);
+               destroy_delegation(dp);
        }
        while (!list_empty(&clp->cl_openowners)) {
                oo = list_entry(clp->cl_openowners.next, struct nfs4_openowner, oo_perclient);
@@ -1147,8 +1156,8 @@ destroy_client(struct nfs4_client *clp)
                rb_erase(&clp->cl_namenode, &nn->unconf_name_tree);
        spin_lock(&nn->client_lock);
        unhash_client_locked(clp);
-       if (atomic_read(&clp->cl_refcount) == 0)
-               free_client(clp);
+       WARN_ON_ONCE(atomic_read(&clp->cl_refcount));
+       free_client(clp);
        spin_unlock(&nn->client_lock);
 }
 
@@ -1327,6 +1336,7 @@ static struct nfs4_client *create_client(struct xdr_netobj name,
        INIT_LIST_HEAD(&clp->cl_delegations);
        INIT_LIST_HEAD(&clp->cl_lru);
        INIT_LIST_HEAD(&clp->cl_callbacks);
+       INIT_LIST_HEAD(&clp->cl_revoked);
        spin_lock_init(&clp->cl_lock);
        nfsd4_init_callback(&clp->cl_cb_null);
        clp->cl_time = get_seconds();
@@ -1408,12 +1418,12 @@ move_to_confirmed(struct nfs4_client *clp)
 }
 
 static struct nfs4_client *
-find_confirmed_client(clientid_t *clid, bool sessions, struct nfsd_net *nn)
+find_client_in_id_table(struct list_head *tbl, clientid_t *clid, bool sessions)
 {
        struct nfs4_client *clp;
        unsigned int idhashval = clientid_hashval(clid->cl_id);
 
-       list_for_each_entry(clp, &nn->conf_id_hashtbl[idhashval], cl_idhash) {
+       list_for_each_entry(clp, &tbl[idhashval], cl_idhash) {
                if (same_clid(&clp->cl_clientid, clid)) {
                        if ((bool)clp->cl_minorversion != sessions)
                                return NULL;
@@ -1424,20 +1434,20 @@ find_confirmed_client(clientid_t *clid, bool sessions, struct nfsd_net *nn)
        return NULL;
 }
 
+static struct nfs4_client *
+find_confirmed_client(clientid_t *clid, bool sessions, struct nfsd_net *nn)
+{
+       struct list_head *tbl = nn->conf_id_hashtbl;
+
+       return find_client_in_id_table(tbl, clid, sessions);
+}
+
 static struct nfs4_client *
 find_unconfirmed_client(clientid_t *clid, bool sessions, struct nfsd_net *nn)
 {
-       struct nfs4_client *clp;
-       unsigned int idhashval = clientid_hashval(clid->cl_id);
+       struct list_head *tbl = nn->unconf_id_hashtbl;
 
-       list_for_each_entry(clp, &nn->unconf_id_hashtbl[idhashval], cl_idhash) {
-               if (same_clid(&clp->cl_clientid, clid)) {
-                       if ((bool)clp->cl_minorversion != sessions)
-                               return NULL;
-                       return clp;
-               }
-       }
-       return NULL;
+       return find_client_in_id_table(tbl, clid, sessions);
 }
 
 static bool clp_used_exchangeid(struct nfs4_client *clp)
@@ -1782,10 +1792,55 @@ nfsd4_replay_create_session(struct nfsd4_create_session *cr_ses,
                                /* seqid, slotID, slotID, slotID, status */ \
                        5 ) * sizeof(__be32))
 
-static bool check_forechannel_attrs(struct nfsd4_channel_attrs fchannel)
+static __be32 check_forechannel_attrs(struct nfsd4_channel_attrs *ca, struct nfsd_net *nn)
 {
-       return fchannel.maxreq_sz < NFSD_MIN_REQ_HDR_SEQ_SZ
-               || fchannel.maxresp_sz < NFSD_MIN_RESP_HDR_SEQ_SZ;
+       u32 maxrpc = nn->nfsd_serv->sv_max_mesg;
+
+       if (ca->maxreq_sz < NFSD_MIN_REQ_HDR_SEQ_SZ)
+               return nfserr_toosmall;
+       if (ca->maxresp_sz < NFSD_MIN_RESP_HDR_SEQ_SZ)
+               return nfserr_toosmall;
+       ca->headerpadsz = 0;
+       ca->maxreq_sz = min_t(u32, ca->maxreq_sz, maxrpc);
+       ca->maxresp_sz = min_t(u32, ca->maxresp_sz, maxrpc);
+       ca->maxops = min_t(u32, ca->maxops, NFSD_MAX_OPS_PER_COMPOUND);
+       ca->maxresp_cached = min_t(u32, ca->maxresp_cached,
+                       NFSD_SLOT_CACHE_SIZE + NFSD_MIN_HDR_SEQ_SZ);
+       ca->maxreqs = min_t(u32, ca->maxreqs, NFSD_MAX_SLOTS_PER_SESSION);
+       /*
+        * Note decreasing slot size below client's request may make it
+        * difficult for client to function correctly, whereas
+        * decreasing the number of slots will (just?) affect
+        * performance.  When short on memory we therefore prefer to
+        * decrease number of slots instead of their size.  Clients that
+        * request larger slots than they need will get poor results:
+        */
+       ca->maxreqs = nfsd4_get_drc_mem(ca);
+       if (!ca->maxreqs)
+               return nfserr_jukebox;
+
+       return nfs_ok;
+}
+
+static __be32 check_backchannel_attrs(struct nfsd4_channel_attrs *ca)
+{
+       ca->headerpadsz = 0;
+
+       /*
+        * These RPC_MAX_HEADER macros are overkill, especially since we
+        * don't even do gss on the backchannel yet.  But this is still
+        * less than 1k.  Tighten up this estimate in the unlikely event
+        * it turns out to be a problem for some client:
+        */
+       if (ca->maxreq_sz < NFS4_enc_cb_recall_sz + RPC_MAX_HEADER_WITH_AUTH)
+               return nfserr_toosmall;
+       if (ca->maxresp_sz < NFS4_dec_cb_recall_sz + RPC_MAX_REPHEADER_WITH_AUTH)
+               return nfserr_toosmall;
+       ca->maxresp_cached = 0;
+       if (ca->maxops < 2)
+               return nfserr_toosmall;
+
+       return nfs_ok;
 }
 
 __be32
@@ -1803,12 +1858,16 @@ nfsd4_create_session(struct svc_rqst *rqstp,
 
        if (cr_ses->flags & ~SESSION4_FLAG_MASK_A)
                return nfserr_inval;
-       if (check_forechannel_attrs(cr_ses->fore_channel))
-               return nfserr_toosmall;
-       new = alloc_session(&cr_ses->fore_channel, nn);
-       if (!new)
-               return nfserr_jukebox;
+       status = check_forechannel_attrs(&cr_ses->fore_channel, nn);
+       if (status)
+               return status;
+       status = check_backchannel_attrs(&cr_ses->back_channel);
+       if (status)
+               return status;
        status = nfserr_jukebox;
+       new = alloc_session(&cr_ses->fore_channel);
+       if (!new)
+               goto out_release_drc_mem;
        conn = alloc_conn_from_crses(rqstp, cr_ses);
        if (!conn)
                goto out_free_session;
@@ -1816,6 +1875,7 @@ nfsd4_create_session(struct svc_rqst *rqstp,
        nfs4_lock_state();
        unconf = find_unconfirmed_client(&cr_ses->clientid, true, nn);
        conf = find_confirmed_client(&cr_ses->clientid, true, nn);
+       WARN_ON_ONCE(conf && unconf);
 
        if (conf) {
                cs_slot = &conf->cl_cs_slot;
@@ -1842,8 +1902,12 @@ nfsd4_create_session(struct svc_rqst *rqstp,
                        goto out_free_conn;
                }
                old = find_confirmed_client_by_name(&unconf->cl_name, nn);
-               if (old)
+               if (old) {
+                       status = mark_client_expired(old);
+                       if (status)
+                               goto out_free_conn;
                        expire_client(old);
+               }
                move_to_confirmed(unconf);
                conf = unconf;
        } else {
@@ -1862,23 +1926,21 @@ nfsd4_create_session(struct svc_rqst *rqstp,
 
        memcpy(cr_ses->sessionid.data, new->se_sessionid.data,
               NFS4_MAX_SESSIONID_LEN);
-       memcpy(&cr_ses->fore_channel, &new->se_fchannel,
-               sizeof(struct nfsd4_channel_attrs));
        cs_slot->sl_seqid++;
        cr_ses->seqid = cs_slot->sl_seqid;
 
        /* cache solo and embedded create sessions under the state lock */
        nfsd4_cache_create_session(cr_ses, cs_slot, status);
        nfs4_unlock_state();
-out:
-       dprintk("%s returns %d\n", __func__, ntohl(status));
        return status;
 out_free_conn:
        nfs4_unlock_state();
        free_conn(conn);
 out_free_session:
        __free_session(new);
-       goto out;
+out_release_drc_mem:
+       nfsd4_put_drc_mem(&cr_ses->fore_channel);
+       return status;
 }
 
 static __be32 nfsd4_map_bcts_dir(u32 *dir)
@@ -1916,30 +1978,30 @@ __be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp,
 {
        __be32 status;
        struct nfsd4_conn *conn;
+       struct nfsd4_session *session;
        struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
 
        if (!nfsd4_last_compound_op(rqstp))
                return nfserr_not_only_op;
+       nfs4_lock_state();
        spin_lock(&nn->client_lock);
-       cstate->session = find_in_sessionid_hashtbl(&bcts->sessionid, SVC_NET(rqstp));
-       /* Sorta weird: we only need the refcnt'ing because new_conn acquires
-        * client_lock iself: */
-       if (cstate->session) {
-               nfsd4_get_session(cstate->session);
-               atomic_inc(&cstate->session->se_client->cl_refcount);
-       }
+       session = find_in_sessionid_hashtbl(&bcts->sessionid, SVC_NET(rqstp));
        spin_unlock(&nn->client_lock);
-       if (!cstate->session)
-               return nfserr_badsession;
-
+       status = nfserr_badsession;
+       if (!session)
+               goto out;
        status = nfsd4_map_bcts_dir(&bcts->dir);
        if (status)
-               return status;
+               goto out;
        conn = alloc_conn(rqstp, bcts->dir);
+       status = nfserr_jukebox;
        if (!conn)
-               return nfserr_jukebox;
-       nfsd4_init_conn(rqstp, conn, cstate->session);
-       return nfs_ok;
+               goto out;
+       nfsd4_init_conn(rqstp, conn, session);
+       status = nfs_ok;
+out:
+       nfs4_unlock_state();
+       return status;
 }
 
 static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4_sessionid *sid)
@@ -1955,42 +2017,36 @@ nfsd4_destroy_session(struct svc_rqst *r,
                      struct nfsd4_destroy_session *sessionid)
 {
        struct nfsd4_session *ses;
-       __be32 status = nfserr_badsession;
+       __be32 status;
        struct nfsd_net *nn = net_generic(SVC_NET(r), nfsd_net_id);
 
-       /* Notes:
-        * - The confirmed nfs4_client->cl_sessionid holds destroyed sessinid
-        * - Should we return nfserr_back_chan_busy if waiting for
-        *   callbacks on to-be-destroyed session?
-        * - Do we need to clear any callback info from previous session?
-        */
-
+       nfs4_lock_state();
+       status = nfserr_not_only_op;
        if (nfsd4_compound_in_session(cstate->session, &sessionid->sessionid)) {
                if (!nfsd4_last_compound_op(r))
-                       return nfserr_not_only_op;
+                       goto out;
        }
        dump_sessionid(__func__, &sessionid->sessionid);
        spin_lock(&nn->client_lock);
        ses = find_in_sessionid_hashtbl(&sessionid->sessionid, SVC_NET(r));
-       if (!ses) {
-               spin_unlock(&nn->client_lock);
-               goto out;
-       }
-
+       status = nfserr_badsession;
+       if (!ses)
+               goto out_client_lock;
+       status = mark_session_dead_locked(ses);
+       if (status)
+               goto out_client_lock;
        unhash_session(ses);
        spin_unlock(&nn->client_lock);
 
-       nfs4_lock_state();
        nfsd4_probe_callback_sync(ses->se_client);
-       nfs4_unlock_state();
 
        spin_lock(&nn->client_lock);
-       nfsd4_del_conns(ses);
-       nfsd4_put_session_locked(ses);
-       spin_unlock(&nn->client_lock);
+       free_session(ses);
        status = nfs_ok;
+out_client_lock:
+       spin_unlock(&nn->client_lock);
 out:
-       dprintk("%s returns %d\n", __func__, ntohl(status));
+       nfs4_unlock_state();
        return status;
 }
 
@@ -2050,6 +2106,7 @@ nfsd4_sequence(struct svc_rqst *rqstp,
 {
        struct nfsd4_compoundres *resp = rqstp->rq_resp;
        struct nfsd4_session *session;
+       struct nfs4_client *clp;
        struct nfsd4_slot *slot;
        struct nfsd4_conn *conn;
        __be32 status;
@@ -2070,19 +2127,26 @@ nfsd4_sequence(struct svc_rqst *rqstp,
        status = nfserr_badsession;
        session = find_in_sessionid_hashtbl(&seq->sessionid, SVC_NET(rqstp));
        if (!session)
-               goto out;
+               goto out_no_session;
+       clp = session->se_client;
+       status = get_client_locked(clp);
+       if (status)
+               goto out_no_session;
+       status = nfsd4_get_session_locked(session);
+       if (status)
+               goto out_put_client;
 
        status = nfserr_too_many_ops;
        if (nfsd4_session_too_many_ops(rqstp, session))
-               goto out;
+               goto out_put_session;
 
        status = nfserr_req_too_big;
        if (nfsd4_request_too_big(rqstp, session))
-               goto out;
+               goto out_put_session;
 
        status = nfserr_badslot;
        if (seq->slotid >= session->se_fchannel.maxreqs)
-               goto out;
+               goto out_put_session;
 
        slot = session->se_slots[seq->slotid];
        dprintk("%s: slotid %d\n", __func__, seq->slotid);
@@ -2097,7 +2161,7 @@ nfsd4_sequence(struct svc_rqst *rqstp,
        if (status == nfserr_replay_cache) {
                status = nfserr_seq_misordered;
                if (!(slot->sl_flags & NFSD4_SLOT_INITIALIZED))
-                       goto out;
+                       goto out_put_session;
                cstate->slot = slot;
                cstate->session = session;
                /* Return the cached reply status and set cstate->status
@@ -2107,7 +2171,7 @@ nfsd4_sequence(struct svc_rqst *rqstp,
                goto out;
        }
        if (status)
-               goto out;
+               goto out_put_session;
 
        nfsd4_sequence_check_conn(conn, session);
        conn = NULL;
@@ -2124,27 +2188,27 @@ nfsd4_sequence(struct svc_rqst *rqstp,
        cstate->session = session;
 
 out:
-       /* Hold a session reference until done processing the compound. */
-       if (cstate->session) {
-               struct nfs4_client *clp = session->se_client;
-
-               nfsd4_get_session(cstate->session);
-               atomic_inc(&clp->cl_refcount);
-               switch (clp->cl_cb_state) {
-               case NFSD4_CB_DOWN:
-                       seq->status_flags = SEQ4_STATUS_CB_PATH_DOWN;
-                       break;
-               case NFSD4_CB_FAULT:
-                       seq->status_flags = SEQ4_STATUS_BACKCHANNEL_FAULT;
-                       break;
-               default:
-                       seq->status_flags = 0;
-               }
+       switch (clp->cl_cb_state) {
+       case NFSD4_CB_DOWN:
+               seq->status_flags = SEQ4_STATUS_CB_PATH_DOWN;
+               break;
+       case NFSD4_CB_FAULT:
+               seq->status_flags = SEQ4_STATUS_BACKCHANNEL_FAULT;
+               break;
+       default:
+               seq->status_flags = 0;
        }
+       if (!list_empty(&clp->cl_revoked))
+               seq->status_flags |= SEQ4_STATUS_RECALLABLE_STATE_REVOKED;
+out_no_session:
        kfree(conn);
        spin_unlock(&nn->client_lock);
-       dprintk("%s: return %d\n", __func__, ntohl(status));
        return status;
+out_put_session:
+       nfsd4_put_session(session);
+out_put_client:
+       put_client_renew_locked(clp);
+       goto out_no_session;
 }
 
 __be32
@@ -2157,17 +2221,12 @@ nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta
        nfs4_lock_state();
        unconf = find_unconfirmed_client(&dc->clientid, true, nn);
        conf = find_confirmed_client(&dc->clientid, true, nn);
+       WARN_ON_ONCE(conf && unconf);
 
        if (conf) {
                clp = conf;
 
-               if (!is_client_expired(conf) && client_has_state(conf)) {
-                       status = nfserr_clientid_busy;
-                       goto out;
-               }
-
-               /* rfc5661 18.50.3 */
-               if (cstate->session && conf == cstate->session->se_client) {
+               if (client_has_state(conf)) {
                        status = nfserr_clientid_busy;
                        goto out;
                }
@@ -2181,7 +2240,6 @@ nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta
        expire_client(clp);
 out:
        nfs4_unlock_state();
-       dprintk("%s return %d\n", __func__, ntohl(status));
        return status;
 }
 
@@ -2319,8 +2377,12 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
                expire_client(unconf);
        } else { /* case 3: normal case; new or rebooted client */
                conf = find_confirmed_client_by_name(&unconf->cl_name, nn);
-               if (conf)
+               if (conf) {
+                       status = mark_client_expired(conf);
+                       if (status)
+                               goto out;
                        expire_client(conf);
+               }
                move_to_confirmed(unconf);
                nfsd4_probe_callback(unconf);
        }
@@ -2340,7 +2402,6 @@ static void nfsd4_init_file(struct nfs4_file *fp, struct inode *ino)
        unsigned int hashval = file_hashval(ino);
 
        atomic_set(&fp->fi_ref, 1);
-       INIT_LIST_HEAD(&fp->fi_hash);
        INIT_LIST_HEAD(&fp->fi_stateids);
        INIT_LIST_HEAD(&fp->fi_delegations);
        fp->fi_inode = igrab(ino);
@@ -2349,7 +2410,7 @@ static void nfsd4_init_file(struct nfs4_file *fp, struct inode *ino)
        memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
        memset(fp->fi_access, 0, sizeof(fp->fi_access));
        spin_lock(&recall_lock);
-       list_add(&fp->fi_hash, &file_hashtbl[hashval]);
+       hlist_add_head(&fp->fi_hash, &file_hashtbl[hashval]);
        spin_unlock(&recall_lock);
 }
 
@@ -2535,7 +2596,7 @@ find_file(struct inode *ino)
        struct nfs4_file *fp;
 
        spin_lock(&recall_lock);
-       list_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) {
+       hlist_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) {
                if (fp->fi_inode == ino) {
                        get_nfs4_file(fp);
                        spin_unlock(&recall_lock);
@@ -2558,8 +2619,6 @@ nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
        struct nfs4_ol_stateid *stp;
        __be32 ret;
 
-       dprintk("NFSD: nfs4_share_conflict\n");
-
        fp = find_file(ino);
        if (!fp)
                return nfs_ok;
@@ -2578,6 +2637,9 @@ out:
 
 static void nfsd_break_one_deleg(struct nfs4_delegation *dp)
 {
+       struct nfs4_client *clp = dp->dl_stid.sc_client;
+       struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
+
        /* We're assuming the state code never drops its reference
         * without first removing the lease.  Since we're in this lease
         * callback (and since the lease code is serialized by the kernel
@@ -2585,7 +2647,7 @@ static void nfsd_break_one_deleg(struct nfs4_delegation *dp)
         * it's safe to take a reference: */
        atomic_inc(&dp->dl_count);
 
-       list_add_tail(&dp->dl_recall_lru, &del_recall_lru);
+       list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru);
 
        /* only place dl_time is set. protected by lock_flocks*/
        dp->dl_time = get_seconds();
@@ -2731,7 +2793,7 @@ static bool nfsd4_is_deleg_cur(struct nfsd4_open *open)
 }
 
 static __be32
-nfs4_check_deleg(struct nfs4_client *cl, struct nfs4_file *fp, struct nfsd4_open *open,
+nfs4_check_deleg(struct nfs4_client *cl, struct nfsd4_open *open,
                struct nfs4_delegation **dp)
 {
        int flags;
@@ -3056,7 +3118,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
        if (fp) {
                if ((status = nfs4_check_open(fp, open, &stp)))
                        goto out;
-               status = nfs4_check_deleg(cl, fp, open, &dp);
+               status = nfs4_check_deleg(cl, open, &dp);
                if (status)
                        goto out;
        } else {
@@ -3234,13 +3296,12 @@ nfs4_laundromat(struct nfsd_net *nn)
                                clientid_val = t;
                        break;
                }
-               if (atomic_read(&clp->cl_refcount)) {
+               if (mark_client_expired_locked(clp)) {
                        dprintk("NFSD: client in use (clientid %08x)\n",
                                clp->cl_clientid.cl_id);
                        continue;
                }
-               unhash_client_locked(clp);
-               list_add(&clp->cl_lru, &reaplist);
+               list_move(&clp->cl_lru, &reaplist);
        }
        spin_unlock(&nn->client_lock);
        list_for_each_safe(pos, next, &reaplist) {
@@ -3250,7 +3311,7 @@ nfs4_laundromat(struct nfsd_net *nn)
                expire_client(clp);
        }
        spin_lock(&recall_lock);
-       list_for_each_safe(pos, next, &del_recall_lru) {
+       list_for_each_safe(pos, next, &nn->del_recall_lru) {
                dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
                if (net_generic(dp->dl_stid.sc_client->net, nfsd_net_id) != nn)
                        continue;
@@ -3265,7 +3326,7 @@ nfs4_laundromat(struct nfsd_net *nn)
        spin_unlock(&recall_lock);
        list_for_each_safe(pos, next, &reaplist) {
                dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
-               unhash_delegation(dp);
+               revoke_delegation(dp);
        }
        test_val = nn->nfsd4_lease;
        list_for_each_safe(pos, next, &nn->close_lru) {
@@ -3308,16 +3369,6 @@ static inline __be32 nfs4_check_fh(struct svc_fh *fhp, struct nfs4_ol_stateid *s
        return nfs_ok;
 }
 
-static int
-STALE_STATEID(stateid_t *stateid, struct nfsd_net *nn)
-{
-       if (stateid->si_opaque.so_clid.cl_boot == nn->boot_time)
-               return 0;
-       dprintk("NFSD: stale stateid " STATEID_FMT "!\n",
-               STATEID_VAL(stateid));
-       return 1;
-}
-
 static inline int
 access_permit_read(struct nfs4_ol_stateid *stp)
 {
@@ -3434,13 +3485,24 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
        status = check_stateid_generation(stateid, &s->sc_stateid, 1);
        if (status)
                return status;
-       if (!(s->sc_type & (NFS4_OPEN_STID | NFS4_LOCK_STID)))
+       switch (s->sc_type) {
+       case NFS4_DELEG_STID:
+               return nfs_ok;
+       case NFS4_REVOKED_DELEG_STID:
+               return nfserr_deleg_revoked;
+       case NFS4_OPEN_STID:
+       case NFS4_LOCK_STID:
+               ols = openlockstateid(s);
+               if (ols->st_stateowner->so_is_open_owner
+                               && !(openowner(ols->st_stateowner)->oo_flags
+                                               & NFS4_OO_CONFIRMED))
+                       return nfserr_bad_stateid;
                return nfs_ok;
-       ols = openlockstateid(s);
-       if (ols->st_stateowner->so_is_open_owner
-           && !(openowner(ols->st_stateowner)->oo_flags & NFS4_OO_CONFIRMED))
+       default:
+               printk("unknown stateid type %x\n", s->sc_type);
+       case NFS4_CLOSED_STID:
                return nfserr_bad_stateid;
-       return nfs_ok;
+       }
 }
 
 static __be32 nfsd4_lookup_stateid(stateid_t *stateid, unsigned char typemask,
@@ -3448,19 +3510,20 @@ static __be32 nfsd4_lookup_stateid(stateid_t *stateid, unsigned char typemask,
                                   struct nfsd_net *nn)
 {
        struct nfs4_client *cl;
+       __be32 status;
 
        if (ZERO_STATEID(stateid) || ONE_STATEID(stateid))
                return nfserr_bad_stateid;
-       if (STALE_STATEID(stateid, nn))
+       status = lookup_clientid(&stateid->si_opaque.so_clid, sessions,
+                                                       nn, &cl);
+       if (status == nfserr_stale_clientid)
                return nfserr_stale_stateid;
-       cl = find_confirmed_client(&stateid->si_opaque.so_clid, sessions, nn);
-       if (!cl)
-               return nfserr_expired;
+       if (status)
+               return status;
        *s = find_stateid_by_type(cl, stateid, typemask);
        if (!*s)
                return nfserr_bad_stateid;
        return nfs_ok;
-
 }
 
 /*
@@ -3570,6 +3633,7 @@ nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 {
        stateid_t *stateid = &free_stateid->fr_stateid;
        struct nfs4_stid *s;
+       struct nfs4_delegation *dp;
        struct nfs4_client *cl = cstate->session->se_client;
        __be32 ret = nfserr_bad_stateid;
 
@@ -3591,6 +3655,11 @@ nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                else
                        ret = nfserr_locks_held;
                break;
+       case NFS4_REVOKED_DELEG_STID:
+               dp = delegstateid(s);
+               destroy_revoked_delegation(dp);
+               ret = nfs_ok;
+               break;
        default:
                ret = nfserr_bad_stateid;
        }
@@ -3615,10 +3684,12 @@ static __be32 nfs4_seqid_op_checks(struct nfsd4_compound_state *cstate, stateid_
        status = nfsd4_check_seqid(cstate, sop, seqid);
        if (status)
                return status;
-       if (stp->st_stid.sc_type == NFS4_CLOSED_STID)
+       if (stp->st_stid.sc_type == NFS4_CLOSED_STID
+               || stp->st_stid.sc_type == NFS4_REVOKED_DELEG_STID)
                /*
                 * "Closed" stateid's exist *only* to return
-                * nfserr_replay_me from the previous step.
+                * nfserr_replay_me from the previous step, and
+                * revoked delegations are kept only for free_stateid.
                 */
                return nfserr_bad_stateid;
        status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate));
@@ -3648,7 +3719,8 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid,
        if (status)
                return status;
        *stpp = openlockstateid(s);
-       cstate->replay_owner = (*stpp)->st_stateowner;
+       if (!nfsd4_has_session(cstate))
+               cstate->replay_owner = (*stpp)->st_stateowner;
 
        return nfs4_seqid_op_checks(cstate, stateid, seqid, *stpp);
 }
@@ -3706,6 +3778,7 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        nfsd4_client_record_create(oo->oo_owner.so_client);
        status = nfs_ok;
 out:
+       nfsd4_bump_seqid(cstate, status);
        if (!cstate->replay_owner)
                nfs4_unlock_state();
        return status;
@@ -3789,31 +3862,12 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
        memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
        status = nfs_ok;
 out:
+       nfsd4_bump_seqid(cstate, status);
        if (!cstate->replay_owner)
                nfs4_unlock_state();
        return status;
 }
 
-void nfsd4_purge_closed_stateid(struct nfs4_stateowner *so)
-{
-       struct nfs4_openowner *oo;
-       struct nfs4_ol_stateid *s;
-
-       if (!so->so_is_open_owner)
-               return;
-       oo = openowner(so);
-       s = oo->oo_last_closed_stid;
-       if (!s)
-               return;
-       if (!(oo->oo_flags & NFS4_OO_PURGE_CLOSE)) {
-               /* Release the last_closed_stid on the next seqid bump: */
-               oo->oo_flags |= NFS4_OO_PURGE_CLOSE;
-               return;
-       }
-       oo->oo_flags &= ~NFS4_OO_PURGE_CLOSE;
-       release_last_closed_stateid(oo);
-}
-
 static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s)
 {
        unhash_open_stateid(s);
@@ -3842,28 +3896,30 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                                        &close->cl_stateid,
                                        NFS4_OPEN_STID|NFS4_CLOSED_STID,
                                        &stp, nn);
+       nfsd4_bump_seqid(cstate, status);
        if (status)
                goto out; 
        oo = openowner(stp->st_stateowner);
-       status = nfs_ok;
        update_stateid(&stp->st_stid.sc_stateid);
        memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
 
        nfsd4_close_open_stateid(stp);
-       release_last_closed_stateid(oo);
-       oo->oo_last_closed_stid = stp;
+
+       if (cstate->minorversion) {
+               unhash_stid(&stp->st_stid);
+               free_generic_stateid(stp);
+       } else
+               oo->oo_last_closed_stid = stp;
 
        if (list_empty(&oo->oo_owner.so_stateids)) {
-               if (cstate->minorversion) {
+               if (cstate->minorversion)
                        release_openowner(oo);
-                       cstate->replay_owner = NULL;
-               } else {
+               else {
                        /*
                         * In the 4.0 case we need to keep the owners around a
                         * little while to handle CLOSE replay.
                         */
-                       if (list_empty(&oo->oo_owner.so_stateids))
-                               move_to_close_lru(oo, SVC_NET(rqstp));
+                       move_to_close_lru(oo, SVC_NET(rqstp));
                }
        }
 out:
@@ -3895,7 +3951,7 @@ nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        if (status)
                goto out;
 
-       unhash_delegation(dp);
+       destroy_delegation(dp);
 out:
        nfs4_unlock_state();
 
@@ -4273,6 +4329,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 out:
        if (status && new_state)
                release_lockowner(lock_sop);
+       nfsd4_bump_seqid(cstate, status);
        if (!cstate->replay_owner)
                nfs4_unlock_state();
        if (file_lock)
@@ -4382,6 +4439,7 @@ __be32
 nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
            struct nfsd4_locku *locku)
 {
+       struct nfs4_lockowner *lo;
        struct nfs4_ol_stateid *stp;
        struct file *filp = NULL;
        struct file_lock *file_lock = NULL;
@@ -4414,9 +4472,10 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                status = nfserr_jukebox;
                goto out;
        }
+       lo = lockowner(stp->st_stateowner);
        locks_init_lock(file_lock);
        file_lock->fl_type = F_UNLCK;
-       file_lock->fl_owner = (fl_owner_t)lockowner(stp->st_stateowner);
+       file_lock->fl_owner = (fl_owner_t)lo;
        file_lock->fl_pid = current->tgid;
        file_lock->fl_file = filp;
        file_lock->fl_flags = FL_POSIX;
@@ -4427,21 +4486,21 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                                                locku->lu_length);
        nfs4_transform_lock_offset(file_lock);
 
-       /*
-       *  Try to unlock the file in the VFS.
-       */
        err = vfs_lock_file(filp, F_SETLK, file_lock, NULL);
        if (err) {
                dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n");
                goto out_nfserr;
        }
-       /*
-       * OK, unlock succeeded; the only thing left to do is update the stateid.
-       */
        update_stateid(&stp->st_stid.sc_stateid);
        memcpy(&locku->lu_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
 
+       if (nfsd4_has_session(cstate) && !check_for_locks(stp->st_file, lo)) {
+               WARN_ON_ONCE(cstate->replay_owner);
+               release_lockowner(lo);
+       }
+
 out:
+       nfsd4_bump_seqid(cstate, status);
        if (!cstate->replay_owner)
                nfs4_unlock_state();
        if (file_lock)
@@ -4634,6 +4693,8 @@ nfs4_check_open_reclaim(clientid_t *clid, bool sessions, struct nfsd_net *nn)
 
 u64 nfsd_forget_client(struct nfs4_client *clp, u64 max)
 {
+       if (mark_client_expired(clp))
+               return 0;
        expire_client(clp);
        return 1;
 }
@@ -4740,7 +4801,7 @@ u64 nfsd_forget_client_delegations(struct nfs4_client *clp, u64 max)
        spin_unlock(&recall_lock);
 
        list_for_each_entry_safe(dp, next, &victims, dl_recall_lru)
-               unhash_delegation(dp);
+               revoke_delegation(dp);
 
        return count;
 }
@@ -4812,12 +4873,6 @@ struct nfs4_client *nfsd_find_client(struct sockaddr_storage *addr, size_t addr_
 void
 nfs4_state_init(void)
 {
-       int i;
-
-       for (i = 0; i < FILE_HASH_SIZE; i++) {
-               INIT_LIST_HEAD(&file_hashtbl[i]);
-       }
-       INIT_LIST_HEAD(&del_recall_lru);
 }
 
 /*
@@ -4881,6 +4936,7 @@ static int nfs4_state_create_net(struct net *net)
        nn->unconf_name_tree = RB_ROOT;
        INIT_LIST_HEAD(&nn->client_lru);
        INIT_LIST_HEAD(&nn->close_lru);
+       INIT_LIST_HEAD(&nn->del_recall_lru);
        spin_lock_init(&nn->client_lock);
 
        INIT_DELAYED_WORK(&nn->laundromat_work, laundromat_main);
@@ -4993,16 +5049,14 @@ nfs4_state_shutdown_net(struct net *net)
 
        INIT_LIST_HEAD(&reaplist);
        spin_lock(&recall_lock);
-       list_for_each_safe(pos, next, &del_recall_lru) {
+       list_for_each_safe(pos, next, &nn->del_recall_lru) {
                dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
-               if (dp->dl_stid.sc_client->net != net)
-                       continue;
                list_move(&dp->dl_recall_lru, &reaplist);
        }
        spin_unlock(&recall_lock);
        list_for_each_safe(pos, next, &reaplist) {
                dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
-               unhash_delegation(dp);
+               destroy_delegation(dp);
        }
 
        nfsd4_client_tracking_exit(net);
index 01168865dd37395a047cbeeb0175d7c8a5b80f88..888a600dad8c6df5829ee57e49e05a23658948e6 100644 (file)
@@ -264,7 +264,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
                iattr->ia_valid |= ATTR_SIZE;
        }
        if (bmval[0] & FATTR4_WORD0_ACL) {
-               int nace;
+               u32 nace;
                struct nfs4_ace *ace;
 
                READ_BUF(4); len += 4;
@@ -344,10 +344,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
                           all 32 bits of 'nseconds'. */
                        READ_BUF(12);
                        len += 12;
-                       READ32(dummy32);
-                       if (dummy32)
-                               return nfserr_inval;
-                       READ32(iattr->ia_atime.tv_sec);
+                       READ64(iattr->ia_atime.tv_sec);
                        READ32(iattr->ia_atime.tv_nsec);
                        if (iattr->ia_atime.tv_nsec >= (u32)1000000000)
                                return nfserr_inval;
@@ -370,10 +367,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
                           all 32 bits of 'nseconds'. */
                        READ_BUF(12);
                        len += 12;
-                       READ32(dummy32);
-                       if (dummy32)
-                               return nfserr_inval;
-                       READ32(iattr->ia_mtime.tv_sec);
+                       READ64(iattr->ia_mtime.tv_sec);
                        READ32(iattr->ia_mtime.tv_nsec);
                        if (iattr->ia_mtime.tv_nsec >= (u32)1000000000)
                                return nfserr_inval;
@@ -804,6 +798,7 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
        open->op_iattr.ia_valid = 0;
        open->op_openowner = NULL;
 
+       open->op_xdr_error = 0;
        /* seqid, share_access, share_deny, clientid, ownerlen */
        READ_BUF(4);
        READ32(open->op_seqid);
@@ -1692,36 +1687,6 @@ static void write_cinfo(__be32 **p, struct nfsd4_change_info *c)
 } while (0)
 #define ADJUST_ARGS()          resp->p = p
 
-/*
- * Header routine to setup seqid operation replay cache
- */
-#define ENCODE_SEQID_OP_HEAD                                   \
-       __be32 *save;                                           \
-                                                               \
-       save = resp->p;
-
-/*
- * Routine for encoding the result of a "seqid-mutating" NFSv4 operation.  This
- * is where sequence id's are incremented, and the replay cache is filled.
- * Note that we increment sequence id's here, at the last moment, so we're sure
- * we know whether the error to be returned is a sequence id mutating error.
- */
-
-static void encode_seqid_op_tail(struct nfsd4_compoundres *resp, __be32 *save, __be32 nfserr)
-{
-       struct nfs4_stateowner *stateowner = resp->cstate.replay_owner;
-
-       if (seqid_mutating_err(ntohl(nfserr)) && stateowner) {
-               stateowner->so_seqid++;
-               stateowner->so_replay.rp_status = nfserr;
-               stateowner->so_replay.rp_buflen =
-                         (char *)resp->p - (char *)save;
-               memcpy(stateowner->so_replay.rp_buf, save,
-                       stateowner->so_replay.rp_buflen);
-               nfsd4_purge_closed_stateid(stateowner);
-       }
-}
-
 /* Encode as an array of strings the string given with components
  * separated @sep, escaped with esc_enter and esc_exit.
  */
@@ -2401,8 +2366,7 @@ out_acl:
        if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
                if ((buflen -= 12) < 0)
                        goto out_resource;
-               WRITE32(0);
-               WRITE32(stat.atime.tv_sec);
+               WRITE64((s64)stat.atime.tv_sec);
                WRITE32(stat.atime.tv_nsec);
        }
        if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
@@ -2415,15 +2379,13 @@ out_acl:
        if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
                if ((buflen -= 12) < 0)
                        goto out_resource;
-               WRITE32(0);
-               WRITE32(stat.ctime.tv_sec);
+               WRITE64((s64)stat.ctime.tv_sec);
                WRITE32(stat.ctime.tv_nsec);
        }
        if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
                if ((buflen -= 12) < 0)
                        goto out_resource;
-               WRITE32(0);
-               WRITE32(stat.mtime.tv_sec);
+               WRITE64((s64)stat.mtime.tv_sec);
                WRITE32(stat.mtime.tv_nsec);
        }
        if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {
@@ -2661,12 +2623,9 @@ static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp,
 static __be32
 nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
 {
-       ENCODE_SEQID_OP_HEAD;
-
        if (!nfserr)
                nfsd4_encode_stateid(resp, &close->cl_stateid);
 
-       encode_seqid_op_tail(resp, save, nfserr);
        return nfserr;
 }
 
@@ -2762,14 +2721,11 @@ nfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denie
 static __be32
 nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
 {
-       ENCODE_SEQID_OP_HEAD;
-
        if (!nfserr)
                nfsd4_encode_stateid(resp, &lock->lk_resp_stateid);
        else if (nfserr == nfserr_denied)
                nfsd4_encode_lock_denied(resp, &lock->lk_denied);
 
-       encode_seqid_op_tail(resp, save, nfserr);
        return nfserr;
 }
 
@@ -2784,12 +2740,9 @@ nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_l
 static __be32
 nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
 {
-       ENCODE_SEQID_OP_HEAD;
-
        if (!nfserr)
                nfsd4_encode_stateid(resp, &locku->lu_stateid);
 
-       encode_seqid_op_tail(resp, save, nfserr);
        return nfserr;
 }
 
@@ -2812,7 +2765,6 @@ static __be32
 nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
 {
        __be32 *p;
-       ENCODE_SEQID_OP_HEAD;
 
        if (nfserr)
                goto out;
@@ -2884,31 +2836,24 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
        }
        /* XXX save filehandle here */
 out:
-       encode_seqid_op_tail(resp, save, nfserr);
        return nfserr;
 }
 
 static __be32
 nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
 {
-       ENCODE_SEQID_OP_HEAD;
-
        if (!nfserr)
                nfsd4_encode_stateid(resp, &oc->oc_resp_stateid);
 
-       encode_seqid_op_tail(resp, save, nfserr);
        return nfserr;
 }
 
 static __be32
 nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
 {
-       ENCODE_SEQID_OP_HEAD;
-
        if (!nfserr)
                nfsd4_encode_stateid(resp, &od->od_stateid);
 
-       encode_seqid_op_tail(resp, save, nfserr);
        return nfserr;
 }
 
@@ -3566,6 +3511,7 @@ __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad)
 void
 nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
 {
+       struct nfs4_stateowner *so = resp->cstate.replay_owner;
        __be32 *statp;
        __be32 *p;
 
@@ -3582,6 +3528,11 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
        /* nfsd4_check_drc_limit guarantees enough room for error status */
        if (!op->status)
                op->status = nfsd4_check_resp_size(resp, 0);
+       if (so) {
+               so->so_replay.rp_status = op->status;
+               so->so_replay.rp_buflen = (char *)resp->p - (char *)(statp+1);
+               memcpy(so->so_replay.rp_buf, statp+1, so->so_replay.rp_buflen);
+       }
 status:
        /*
         * Note: We write the status directly, instead of using WRITE32(),
@@ -3683,7 +3634,7 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compo
                        cs->slot->sl_flags &= ~NFSD4_SLOT_INUSE;
                }
                /* Renew the clientid on success and on replay */
-               release_session_client(cs->session);
+               put_client_renew(cs->session->se_client);
                nfsd4_put_session(cs->session);
        }
        return 1;
index 62c1ee128aebafbd82e70863e57caa74de804e13..eb2587745a6409326c7358228a5ef02eb8719a1c 100644 (file)
@@ -11,6 +11,8 @@
 #include <linux/slab.h>
 #include <linux/sunrpc/addr.h>
 #include <linux/highmem.h>
+#include <linux/log2.h>
+#include <linux/hash.h>
 #include <net/checksum.h>
 
 #include "nfsd.h"
 
 #define NFSDDBG_FACILITY       NFSDDBG_REPCACHE
 
-#define HASHSIZE               64
+/*
+ * We use this value to determine the number of hash buckets from the max
+ * cache size, the idea being that when the cache is at its maximum number
+ * of entries, then this should be the average number of entries per bucket.
+ */
+#define TARGET_BUCKET_SIZE     64
 
 static struct hlist_head *     cache_hash;
 static struct list_head        lru_head;
 static struct kmem_cache       *drc_slab;
-static unsigned int            num_drc_entries;
+
+/* max number of entries allowed in the cache */
 static unsigned int            max_drc_entries;
 
+/* number of significant bits in the hash value */
+static unsigned int            maskbits;
+
 /*
- * Calculate the hash index from an XID.
+ * Stats and other tracking of on the duplicate reply cache. All of these and
+ * the "rc" fields in nfsdstats are protected by the cache_lock
  */
-static inline u32 request_hash(u32 xid)
-{
-       u32 h = xid;
-       h ^= (xid >> 24);
-       return h & (HASHSIZE-1);
-}
+
+/* total number of entries */
+static unsigned int            num_drc_entries;
+
+/* cache misses due only to checksum comparison failures */
+static unsigned int            payload_misses;
+
+/* amount of memory (in bytes) currently consumed by the DRC */
+static unsigned int            drc_mem_usage;
+
+/* longest hash chain seen */
+static unsigned int            longest_chain;
+
+/* size of cache when we saw the longest hash chain */
+static unsigned int            longest_chain_cachesize;
 
 static int     nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *vec);
 static void    cache_cleaner_func(struct work_struct *unused);
@@ -82,6 +103,16 @@ nfsd_cache_size_limit(void)
        return min_t(unsigned int, limit, 256*1024);
 }
 
+/*
+ * Compute the number of hash buckets we need. Divide the max cachesize by
+ * the "target" max bucket size, and round up to next power of two.
+ */
+static unsigned int
+nfsd_hashsize(unsigned int limit)
+{
+       return roundup_pow_of_two(limit / TARGET_BUCKET_SIZE);
+}
+
 static struct svc_cacherep *
 nfsd_reply_cache_alloc(void)
 {
@@ -100,11 +131,15 @@ nfsd_reply_cache_alloc(void)
 static void
 nfsd_reply_cache_free_locked(struct svc_cacherep *rp)
 {
-       if (rp->c_type == RC_REPLBUFF)
+       if (rp->c_type == RC_REPLBUFF && rp->c_replvec.iov_base) {
+               drc_mem_usage -= rp->c_replvec.iov_len;
                kfree(rp->c_replvec.iov_base);
-       hlist_del(&rp->c_hash);
+       }
+       if (!hlist_unhashed(&rp->c_hash))
+               hlist_del(&rp->c_hash);
        list_del(&rp->c_lru);
        --num_drc_entries;
+       drc_mem_usage -= sizeof(*rp);
        kmem_cache_free(drc_slab, rp);
 }
 
@@ -118,20 +153,24 @@ nfsd_reply_cache_free(struct svc_cacherep *rp)
 
 int nfsd_reply_cache_init(void)
 {
+       unsigned int hashsize;
+
+       INIT_LIST_HEAD(&lru_head);
+       max_drc_entries = nfsd_cache_size_limit();
+       num_drc_entries = 0;
+       hashsize = nfsd_hashsize(max_drc_entries);
+       maskbits = ilog2(hashsize);
+
        register_shrinker(&nfsd_reply_cache_shrinker);
        drc_slab = kmem_cache_create("nfsd_drc", sizeof(struct svc_cacherep),
                                        0, 0, NULL);
        if (!drc_slab)
                goto out_nomem;
 
-       cache_hash = kcalloc(HASHSIZE, sizeof(struct hlist_head), GFP_KERNEL);
+       cache_hash = kcalloc(hashsize, sizeof(struct hlist_head), GFP_KERNEL);
        if (!cache_hash)
                goto out_nomem;
 
-       INIT_LIST_HEAD(&lru_head);
-       max_drc_entries = nfsd_cache_size_limit();
-       num_drc_entries = 0;
-
        return 0;
 out_nomem:
        printk(KERN_ERR "nfsd: failed to allocate reply cache\n");
@@ -179,7 +218,7 @@ static void
 hash_refile(struct svc_cacherep *rp)
 {
        hlist_del_init(&rp->c_hash);
-       hlist_add_head(&rp->c_hash, cache_hash + request_hash(rp->c_xid));
+       hlist_add_head(&rp->c_hash, cache_hash + hash_32(rp->c_xid, maskbits));
 }
 
 static inline bool
@@ -272,6 +311,26 @@ nfsd_cache_csum(struct svc_rqst *rqstp)
        return csum;
 }
 
+static bool
+nfsd_cache_match(struct svc_rqst *rqstp, __wsum csum, struct svc_cacherep *rp)
+{
+       /* Check RPC header info first */
+       if (rqstp->rq_xid != rp->c_xid || rqstp->rq_proc != rp->c_proc ||
+           rqstp->rq_prot != rp->c_prot || rqstp->rq_vers != rp->c_vers ||
+           rqstp->rq_arg.len != rp->c_len ||
+           !rpc_cmp_addr(svc_addr(rqstp), (struct sockaddr *)&rp->c_addr) ||
+           rpc_get_port(svc_addr(rqstp)) != rpc_get_port((struct sockaddr *)&rp->c_addr))
+               return false;
+
+       /* compare checksum of NFS data */
+       if (csum != rp->c_csum) {
+               ++payload_misses;
+               return false;
+       }
+
+       return true;
+}
+
 /*
  * Search the request hash for an entry that matches the given rqstp.
  * Must be called with cache_lock held. Returns the found entry or
@@ -280,23 +339,30 @@ nfsd_cache_csum(struct svc_rqst *rqstp)
 static struct svc_cacherep *
 nfsd_cache_search(struct svc_rqst *rqstp, __wsum csum)
 {
-       struct svc_cacherep     *rp;
+       struct svc_cacherep     *rp, *ret = NULL;
        struct hlist_head       *rh;
-       __be32                  xid = rqstp->rq_xid;
-       u32                     proto =  rqstp->rq_prot,
-                               vers = rqstp->rq_vers,
-                               proc = rqstp->rq_proc;
+       unsigned int            entries = 0;
 
-       rh = &cache_hash[request_hash(xid)];
+       rh = &cache_hash[hash_32(rqstp->rq_xid, maskbits)];
        hlist_for_each_entry(rp, rh, c_hash) {
-               if (xid == rp->c_xid && proc == rp->c_proc &&
-                   proto == rp->c_prot && vers == rp->c_vers &&
-                   rqstp->rq_arg.len == rp->c_len && csum == rp->c_csum &&
-                   rpc_cmp_addr(svc_addr(rqstp), (struct sockaddr *)&rp->c_addr) &&
-                   rpc_get_port(svc_addr(rqstp)) == rpc_get_port((struct sockaddr *)&rp->c_addr))
-                       return rp;
+               ++entries;
+               if (nfsd_cache_match(rqstp, csum, rp)) {
+                       ret = rp;
+                       break;
+               }
        }
-       return NULL;
+
+       /* tally hash chain length stats */
+       if (entries > longest_chain) {
+               longest_chain = entries;
+               longest_chain_cachesize = num_drc_entries;
+       } else if (entries == longest_chain) {
+               /* prefer to keep the smallest cachesize possible here */
+               longest_chain_cachesize = min(longest_chain_cachesize,
+                                               num_drc_entries);
+       }
+
+       return ret;
 }
 
 /*
@@ -317,55 +383,55 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
        __wsum                  csum;
        unsigned long           age;
        int type = rqstp->rq_cachetype;
-       int rtn;
+       int rtn = RC_DOIT;
 
        rqstp->rq_cacherep = NULL;
        if (type == RC_NOCACHE) {
                nfsdstats.rcnocache++;
-               return RC_DOIT;
+               return rtn;
        }
 
        csum = nfsd_cache_csum(rqstp);
 
+       /*
+        * Since the common case is a cache miss followed by an insert,
+        * preallocate an entry. First, try to reuse the first entry on the LRU
+        * if it works, then go ahead and prune the LRU list.
+        */
        spin_lock(&cache_lock);
-       rtn = RC_DOIT;
-
-       rp = nfsd_cache_search(rqstp, csum);
-       if (rp)
-               goto found_entry;
-
-       /* Try to use the first entry on the LRU */
        if (!list_empty(&lru_head)) {
                rp = list_first_entry(&lru_head, struct svc_cacherep, c_lru);
                if (nfsd_cache_entry_expired(rp) ||
                    num_drc_entries >= max_drc_entries) {
                        lru_put_end(rp);
                        prune_cache_entries();
-                       goto setup_entry;
+                       goto search_cache;
                }
        }
 
-       /* Drop the lock and allocate a new entry */
+       /* No expired ones available, allocate a new one. */
        spin_unlock(&cache_lock);
        rp = nfsd_reply_cache_alloc();
-       if (!rp) {
-               dprintk("nfsd: unable to allocate DRC entry!\n");
-               return RC_DOIT;
-       }
        spin_lock(&cache_lock);
-       ++num_drc_entries;
+       if (likely(rp)) {
+               ++num_drc_entries;
+               drc_mem_usage += sizeof(*rp);
+       }
 
-       /*
-        * Must search again just in case someone inserted one
-        * after we dropped the lock above.
-        */
+search_cache:
        found = nfsd_cache_search(rqstp, csum);
        if (found) {
-               nfsd_reply_cache_free_locked(rp);
+               if (likely(rp))
+                       nfsd_reply_cache_free_locked(rp);
                rp = found;
                goto found_entry;
        }
 
+       if (!rp) {
+               dprintk("nfsd: unable to allocate DRC entry!\n");
+               goto out;
+       }
+
        /*
         * We're keeping the one we just allocated. Are we now over the
         * limit? Prune one off the tip of the LRU in trade for the one we
@@ -375,7 +441,6 @@ nfsd_cache_lookup(struct svc_rqst *rqstp)
                nfsd_reply_cache_free_locked(list_first_entry(&lru_head,
                                                struct svc_cacherep, c_lru));
 
-setup_entry:
        nfsdstats.rcmisses++;
        rqstp->rq_cacherep = rp;
        rp->c_state = RC_INPROG;
@@ -393,6 +458,7 @@ setup_entry:
 
        /* release any buffer */
        if (rp->c_type == RC_REPLBUFF) {
+               drc_mem_usage -= rp->c_replvec.iov_len;
                kfree(rp->c_replvec.iov_base);
                rp->c_replvec.iov_base = NULL;
        }
@@ -461,6 +527,7 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp)
        struct svc_cacherep *rp = rqstp->rq_cacherep;
        struct kvec     *resv = &rqstp->rq_res.head[0], *cachv;
        int             len;
+       size_t          bufsize = 0;
 
        if (!rp)
                return;
@@ -482,19 +549,21 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp)
                break;
        case RC_REPLBUFF:
                cachv = &rp->c_replvec;
-               cachv->iov_base = kmalloc(len << 2, GFP_KERNEL);
+               bufsize = len << 2;
+               cachv->iov_base = kmalloc(bufsize, GFP_KERNEL);
                if (!cachv->iov_base) {
                        nfsd_reply_cache_free(rp);
                        return;
                }
-               cachv->iov_len = len << 2;
-               memcpy(cachv->iov_base, statp, len << 2);
+               cachv->iov_len = bufsize;
+               memcpy(cachv->iov_base, statp, bufsize);
                break;
        case RC_NOCACHE:
                nfsd_reply_cache_free(rp);
                return;
        }
        spin_lock(&cache_lock);
+       drc_mem_usage += bufsize;
        lru_put_end(rp);
        rp->c_secure = rqstp->rq_secure;
        rp->c_type = cachetype;
@@ -522,3 +591,30 @@ nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *data)
        vec->iov_len += data->iov_len;
        return 1;
 }
+
+/*
+ * Note that fields may be added, removed or reordered in the future. Programs
+ * scraping this file for info should test the labels to ensure they're
+ * getting the correct field.
+ */
+static int nfsd_reply_cache_stats_show(struct seq_file *m, void *v)
+{
+       spin_lock(&cache_lock);
+       seq_printf(m, "max entries:           %u\n", max_drc_entries);
+       seq_printf(m, "num entries:           %u\n", num_drc_entries);
+       seq_printf(m, "hash buckets:          %u\n", 1 << maskbits);
+       seq_printf(m, "mem usage:             %u\n", drc_mem_usage);
+       seq_printf(m, "cache hits:            %u\n", nfsdstats.rchits);
+       seq_printf(m, "cache misses:          %u\n", nfsdstats.rcmisses);
+       seq_printf(m, "not cached:            %u\n", nfsdstats.rcnocache);
+       seq_printf(m, "payload misses:        %u\n", payload_misses);
+       seq_printf(m, "longest chain len:     %u\n", longest_chain);
+       seq_printf(m, "cachesize at longest:  %u\n", longest_chain_cachesize);
+       spin_unlock(&cache_lock);
+       return 0;
+}
+
+int nfsd_reply_cache_stats_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, nfsd_reply_cache_stats_show, NULL);
+}
index 13a21c8fca490884e05e832d1a657daf9d1af58f..68a4d320cd14f577e6719f0761a136055dccdd4b 100644 (file)
@@ -35,6 +35,7 @@ enum {
        NFSD_Threads,
        NFSD_Pool_Threads,
        NFSD_Pool_Stats,
+       NFSD_Reply_Cache_Stats,
        NFSD_Versions,
        NFSD_Ports,
        NFSD_MaxBlkSize,
@@ -212,6 +213,13 @@ static const struct file_operations pool_stats_operations = {
        .owner          = THIS_MODULE,
 };
 
+static struct file_operations reply_cache_stats_operations = {
+       .open           = nfsd_reply_cache_stats_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
 /*----------------------------------------------------------------------------*/
 /*
  * payload - write methods
@@ -1047,6 +1055,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
                [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_Pool_Stats] = {"pool_stats", &pool_stats_operations, S_IRUGO},
+               [NFSD_Reply_Cache_Stats] = {"reply_cache_stats", &reply_cache_stats_operations, S_IRUGO},
                [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO},
                [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO},
@@ -1090,6 +1099,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)
@@ -1101,8 +1111,10 @@ static int create_proc_exports_entry(void)
                return -ENOMEM;
        entry = proc_create("exports", 0, entry,
                                 &exports_proc_operations);
-       if (!entry)
+       if (!entry) {
+               remove_proc_entry("fs/nfs", NULL);
                return -ENOMEM;
+       }
        return 0;
 }
 #else /* CONFIG_PROC_FS */
index 1a8c7391f7aef5a6b83f725816704c7720c21179..274e2a114e050f02363f90495bcd23c018e646d5 100644 (file)
@@ -79,6 +79,8 @@ struct nfs4_stid {
 #define NFS4_DELEG_STID 4
 /* For an open stateid kept around *only* to process close replays: */
 #define NFS4_CLOSED_STID 8
+/* For a deleg stateid kept around only to process free_stateid's: */
+#define NFS4_REVOKED_DELEG_STID 16
        unsigned char sc_type;
        stateid_t sc_stateid;
        struct nfs4_client *sc_client;
@@ -194,9 +196,11 @@ struct nfsd4_conn {
 };
 
 struct nfsd4_session {
-       struct kref             se_ref;
+       atomic_t                se_ref;
        struct list_head        se_hash;        /* hash by sessionid */
        struct list_head        se_perclnt;
+/* See SESSION4_PERSIST, etc. for standard flags; this is internal-only: */
+#define NFS4_SESSION_DEAD      0x010
        u32                     se_flags;
        struct nfs4_client      *se_client;
        struct nfs4_sessionid   se_sessionid;
@@ -236,6 +240,7 @@ struct nfs4_client {
        struct list_head        cl_openowners;
        struct idr              cl_stateids;    /* stateid lookup */
        struct list_head        cl_delegations;
+       struct list_head        cl_revoked;     /* unacknowledged, revoked 4.1 state */
        struct list_head        cl_lru;         /* tail queue */
        struct xdr_netobj       cl_name;        /* id generated by client */
        nfs4_verifier           cl_verifier;    /* generated by client */
@@ -286,18 +291,6 @@ struct nfs4_client {
        struct net              *net;
 };
 
-static inline void
-mark_client_expired(struct nfs4_client *clp)
-{
-       clp->cl_time = 0;
-}
-
-static inline bool
-is_client_expired(struct nfs4_client *clp)
-{
-       return clp->cl_time == 0;
-}
-
 /* struct nfs4_client_reset
  * one per old client. Populates reset_str_hashtbl. Filled from conf_id_hashtbl
  * upon lease reset, or from upcall to state_daemon (to read in state
@@ -365,7 +358,6 @@ struct nfs4_openowner {
        struct nfs4_ol_stateid *oo_last_closed_stid;
        time_t                  oo_time; /* time of placement on so_close_lru */
 #define NFS4_OO_CONFIRMED   1
-#define NFS4_OO_PURGE_CLOSE 2
 #define NFS4_OO_NEW         4
        unsigned char           oo_flags;
 };
@@ -373,7 +365,7 @@ struct nfs4_openowner {
 struct nfs4_lockowner {
        struct nfs4_stateowner  lo_owner; /* must be first element */
        struct list_head        lo_owner_ino_hash; /* hash by owner,file */
-       struct list_head        lo_perstateid; /* for lockowners only */
+       struct list_head        lo_perstateid;
        struct list_head        lo_list; /* for temporary uses */
 };
 
@@ -390,7 +382,7 @@ static inline struct nfs4_lockowner * lockowner(struct nfs4_stateowner *so)
 /* nfs4_file: a file opened by some number of (open) nfs4_stateowners. */
 struct nfs4_file {
        atomic_t                fi_ref;
-       struct list_head        fi_hash;    /* hash by "struct inode *" */
+       struct hlist_node       fi_hash;    /* hash by "struct inode *" */
        struct list_head        fi_stateids;
        struct list_head        fi_delegations;
        /* One each for O_RDONLY, O_WRONLY, O_RDWR: */
@@ -486,8 +478,7 @@ extern void nfs4_put_delegation(struct nfs4_delegation *dp);
 extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(const char *name,
                                                        struct nfsd_net *nn);
 extern bool nfs4_has_reclaimed_state(const char *name, struct nfsd_net *nn);
-extern void release_session_client(struct nfsd4_session *);
-extern void nfsd4_purge_closed_stateid(struct nfs4_stateowner *);
+extern void put_client_renew(struct nfs4_client *clp);
 
 /* nfs4recover operations */
 extern int nfsd4_client_tracking_init(struct net *net);
index 2a7eb536de0bec80dfbfd7d981139f2e925e644e..2b2e2396a86913b4d4e69c376852ded82dd9be3a 100644 (file)
@@ -1013,6 +1013,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
        int                     host_err;
        int                     stable = *stablep;
        int                     use_wgather;
+       loff_t                  pos = offset;
 
        dentry = file->f_path.dentry;
        inode = dentry->d_inode;
@@ -1025,7 +1026,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
 
        /* Write the data. */
        oldfs = get_fs(); set_fs(KERNEL_DS);
-       host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset);
+       host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &pos);
        set_fs(oldfs);
        if (host_err < 0)
                goto out_nfserr;
index 546f8983ecf144faa4c8c8b2bacbef821e12a875..3b271d2092b6c7397bc6fa2cb61674290ecc831a 100644 (file)
@@ -184,7 +184,6 @@ struct nfsd4_lock {
 #define lk_old_lock_stateid     v.old.lock_stateid
 #define lk_old_lock_seqid       v.old.lock_seqid
 
-#define lk_rflags       u.ok.rflags
 #define lk_resp_stateid u.ok.stateid
 #define lk_denied       u.denied
 
@@ -237,6 +236,7 @@ struct nfsd4_open {
        u32             op_share_deny;      /* request */
        u32             op_deleg_want;      /* request */
        stateid_t       op_stateid;         /* response */
+       __be32          op_xdr_error;       /* see nfsd4_open_omfg() */
        u32             op_recall;          /* recall */
        struct nfsd4_change_info  op_cinfo; /* response */
        u32             op_rflags;          /* response */
@@ -623,6 +623,7 @@ extern __be32 nfsd4_test_stateid(struct svc_rqst *rqstp,
                struct nfsd4_compound_state *, struct nfsd4_test_stateid *test_stateid);
 extern __be32 nfsd4_free_stateid(struct svc_rqst *rqstp,
                struct nfsd4_compound_state *, struct nfsd4_free_stateid *free_stateid);
+extern void nfsd4_bump_seqid(struct nfsd4_compound_state *, __be32 nfserr);
 #endif
 
 /*
diff --git a/fs/nfsd/xdr4cb.h b/fs/nfsd/xdr4cb.h
new file mode 100644 (file)
index 0000000..c5c55df
--- /dev/null
@@ -0,0 +1,23 @@
+#define NFS4_MAXTAGLEN         20
+
+#define NFS4_enc_cb_null_sz            0
+#define NFS4_dec_cb_null_sz            0
+#define cb_compound_enc_hdr_sz         4
+#define cb_compound_dec_hdr_sz         (3 + (NFS4_MAXTAGLEN >> 2))
+#define sessionid_sz                   (NFS4_MAX_SESSIONID_LEN >> 2)
+#define cb_sequence_enc_sz             (sessionid_sz + 4 +             \
+                                       1 /* no referring calls list yet */)
+#define cb_sequence_dec_sz             (op_dec_sz + sessionid_sz + 4)
+
+#define op_enc_sz                      1
+#define op_dec_sz                      2
+#define enc_nfs4_fh_sz                 (1 + (NFS4_FHSIZE >> 2))
+#define enc_stateid_sz                 (NFS4_STATEID_SIZE >> 2)
+#define NFS4_enc_cb_recall_sz          (cb_compound_enc_hdr_sz +       \
+                                       cb_sequence_enc_sz +            \
+                                       1 + enc_stateid_sz +            \
+                                       enc_nfs4_fh_sz)
+
+#define NFS4_dec_cb_recall_sz          (cb_compound_dec_hdr_sz  +      \
+                                       cb_sequence_dec_sz +            \
+                                       op_dec_sz)
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 64a494cef0a00be57d0800637b71caf2537c2694..2234f3f61f8d8fbc6a1f77dbaae6412130b8a5d4 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -863,6 +863,9 @@ pipe_rdwr_open(struct inode *inode, struct file *filp)
 {
        int ret = -ENOENT;
 
+       if (!(filp->f_mode & (FMODE_READ|FMODE_WRITE)))
+               return -EINVAL;
+
        mutex_lock(&inode->i_mutex);
 
        if (inode->i_pipe) {
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 05ae3c97f7a5fc552e771f9cf7312e4b61cffc1f..3e64169ef52710ff11f9c7f8c44ee3c910cbd321 100644 (file)
@@ -1439,8 +1439,11 @@ static void __dquot_initialize(struct inode *inode, int type)
                         * did a write before quota was turned on
                         */
                        rsv = inode_get_rsv_space(inode);
-                       if (unlikely(rsv))
+                       if (unlikely(rsv)) {
+                               spin_lock(&dq_data_lock);
                                dquot_resv_space(inode->i_dquot[cnt], rsv);
+                               spin_unlock(&dq_data_lock);
+                       }
                }
        }
 out_err:
index 418bdc3a57da4e11092477fa1b3cbf2e37f71422..f8a23c3078f87d5eda59c30d55cea7ecc94b9273 100644 (file)
@@ -1147,8 +1147,7 @@ static int reiserfs_parse_options(struct super_block *s, char *options,   /* strin
                                                         "on filesystem root.");
                                        return 0;
                                }
-                               qf_names[qtype] =
-                                   kmalloc(strlen(arg) + 1, GFP_KERNEL);
+                               qf_names[qtype] = kstrdup(arg, GFP_KERNEL);
                                if (!qf_names[qtype]) {
                                        reiserfs_warning(s, "reiserfs-2502",
                                                         "not enough memory "
@@ -1156,7 +1155,6 @@ static int reiserfs_parse_options(struct super_block *s, char *options,   /* strin
                                                         "quotafile name.");
                                        return 0;
                                }
-                               strcpy(qf_names[qtype], arg);
                                if (qtype == USRQUOTA)
                                        *mount_options |= 1 << REISERFS_USRQUOTA;
                                else
@@ -2434,6 +2432,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 260e3928d4f52bb94076e0025f5fd8bef08bb1c3..60553a9053ca82b7264862e8168b61df0ce7de89 100644 (file)
@@ -489,6 +489,7 @@ static struct file_system_type squashfs_fs_type = {
        .kill_sb = kill_block_super,
        .fs_flags = FS_REQUIRES_DEV
 };
+MODULE_ALIAS_FS("squashfs");
 
 static const struct super_operations squashfs_super_ops = {
        .alloc_inode = squashfs_alloc_inode,
index a38e87bdd78dcb6fa112f954b30a93de9dc06420..d0c6a007ce835cf869fac695eb5445b34be6d814 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,8 @@ static struct file_system_type v7_fs_type = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("v7");
+MODULE_ALIAS("v7");
 
 static int __init init_sysv_fs(void)
 {
@@ -586,5 +589,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 bc5b30a819e82e8622d2ead088c52ef5cf7c268e..9ac4057a86c90f64a84ea2cee0b92e4f549ac01a 100644 (file)
@@ -118,6 +118,7 @@ static struct file_system_type udf_fstype = {
        .kill_sb        = kill_block_super,
        .fs_flags       = FS_REQUIRES_DEV,
 };
+MODULE_ALIAS_FS("udf");
 
 static struct kmem_cache *udf_inode_cachep;
 
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 555d0337ad955bbdccd6a7f5b261e9d0777462c3..b327b5a9296d36fb6c31fd26e382488fd0b45cbb 100644 (file)
@@ -235,6 +235,9 @@ extern void acpi_processor_unregister_performance(struct
          if a _PPC object exists, rmmod is disallowed then */
 int acpi_processor_notify_smm(struct module *calling_module);
 
+/* parsing the _P* objects. */
+extern int acpi_processor_get_performance_info(struct acpi_processor *pr);
+
 /* for communication between multiple parts of the processor kernel module */
 DECLARE_PER_CPU(struct acpi_processor *, processors);
 extern struct acpi_processor_errata errata;
index 1ced6413ea0345580830394554e0ed2b69ba1224..33bd2de3bc1e930da34dcb8b6007825807ddacb3 100644 (file)
@@ -136,12 +136,6 @@ static inline void atomic_dec(atomic_t *v)
 #define atomic_xchg(ptr, v)            (xchg(&(ptr)->counter, (v)))
 #define atomic_cmpxchg(v, old, new)    (cmpxchg(&((v)->counter), (old), (new)))
 
-#define cmpxchg_local(ptr, o, n)                                              \
-       ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
-                       (unsigned long)(n), sizeof(*(ptr))))
-
-#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
-
 static inline int __atomic_add_unless(atomic_t *v, int a, int u)
 {
   int c, old;
index 14883026015dc50be00508f8eccf9cf805ea0ef4..811fb1e9b06131303d41f07797becb024e61d77f 100644 (file)
@@ -92,6 +92,16 @@ unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
  */
 #include <asm-generic/cmpxchg-local.h>
 
+#ifndef cmpxchg_local
+#define cmpxchg_local(ptr, o, n)                                              \
+       ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
+                       (unsigned long)(n), sizeof(*(ptr))))
+#endif
+
+#ifndef cmpxchg64_local
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+#endif
+
 #define cmpxchg(ptr, o, n)     cmpxchg_local((ptr), (o), (n))
 #define cmpxchg64(ptr, o, n)   cmpxchg64_local((ptr), (o), (n))
 
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 a6f38b5c34e47d000f73483b6a8b3967a7c2f39e..2640c7e99e51c65489d817ee9a44f6205a2cb0ad 100644 (file)
@@ -73,8 +73,6 @@ struct idr {
  */
 
 void *idr_find_slowpath(struct idr *idp, int id);
-int idr_pre_get(struct idr *idp, gfp_t gfp_mask);
-int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
 void idr_preload(gfp_t gfp_mask);
 int idr_alloc(struct idr *idp, void *ptr, int start, int end, gfp_t gfp_mask);
 int idr_for_each(struct idr *idp,
@@ -99,7 +97,7 @@ static inline void idr_preload_end(void)
 
 /**
  * idr_find - return pointer for given id
- * @idp: idr handle
+ * @idr: idr handle
  * @id: lookup key
  *
  * Return the pointer given the id it has been registered with.  A %NULL
@@ -119,19 +117,6 @@ static inline void *idr_find(struct idr *idr, int id)
        return idr_find_slowpath(idr, id);
 }
 
-/**
- * idr_get_new - allocate new idr entry
- * @idp: idr handle
- * @ptr: pointer you want associated with the id
- * @id: pointer to the allocated handle
- *
- * Simple wrapper around idr_get_new_above() w/ @starting_id of zero.
- */
-static inline int idr_get_new(struct idr *idp, void *ptr, int *id)
-{
-       return idr_get_new_above(idp, ptr, 0, id);
-}
-
 /**
  * idr_for_each_entry - iterate over an idr's elements of a given type
  * @idp:     idr handle
@@ -143,7 +128,56 @@ static inline int idr_get_new(struct idr *idp, void *ptr, int *id)
             entry != NULL;                                             \
             ++id, entry = (typeof(entry))idr_get_next((idp), &(id)))
 
-void __idr_remove_all(struct idr *idp);        /* don't use */
+/*
+ * Don't use the following functions.  These exist only to suppress
+ * deprecated warnings on EXPORT_SYMBOL()s.
+ */
+int __idr_pre_get(struct idr *idp, gfp_t gfp_mask);
+int __idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id);
+void __idr_remove_all(struct idr *idp);
+
+/**
+ * idr_pre_get - reserve resources for idr allocation
+ * @idp:       idr handle
+ * @gfp_mask:  memory allocation flags
+ *
+ * Part of old alloc interface.  This is going away.  Use
+ * idr_preload[_end]() and idr_alloc() instead.
+ */
+static inline int __deprecated idr_pre_get(struct idr *idp, gfp_t gfp_mask)
+{
+       return __idr_pre_get(idp, gfp_mask);
+}
+
+/**
+ * idr_get_new_above - allocate new idr entry above or equal to a start id
+ * @idp: idr handle
+ * @ptr: pointer you want associated with the id
+ * @starting_id: id to start search at
+ * @id: pointer to the allocated handle
+ *
+ * Part of old alloc interface.  This is going away.  Use
+ * idr_preload[_end]() and idr_alloc() instead.
+ */
+static inline int __deprecated idr_get_new_above(struct idr *idp, void *ptr,
+                                                int starting_id, int *id)
+{
+       return __idr_get_new_above(idp, ptr, starting_id, id);
+}
+
+/**
+ * idr_get_new - allocate new idr entry
+ * @idp: idr handle
+ * @ptr: pointer you want associated with the id
+ * @id: pointer to the allocated handle
+ *
+ * Part of old alloc interface.  This is going away.  Use
+ * idr_preload[_end]() and idr_alloc() instead.
+ */
+static inline int __deprecated idr_get_new(struct idr *idp, void *ptr, int *id)
+{
+       return __idr_get_new_above(idp, ptr, 0, id);
+}
 
 /**
  * idr_remove_all - remove all ids from the given idr tree
index 1f86a97ab2e2016407e68fe352bba3b4d018880d..8bd12be0b02f875f1182e9fdcaee69598bc8e083 100644 (file)
@@ -227,14 +227,17 @@ struct st_sensor_data {
 };
 
 #ifdef CONFIG_IIO_BUFFER
+irqreturn_t st_sensors_trigger_handler(int irq, void *p);
+
+int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf);
+#endif
+
+#ifdef CONFIG_IIO_TRIGGER
 int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
                                const struct iio_trigger_ops *trigger_ops);
 
 void st_sensors_deallocate_trigger(struct iio_dev *indio_dev);
 
-irqreturn_t st_sensors_trigger_handler(int irq, void *p);
-
-int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf);
 #else
 static inline int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
                                const struct iio_trigger_ops *trigger_ops)
index d991cc147c98f81fbca56ca0cbdf6a6b62aa6c3e..6a1f8df9144bcfd5c1af3e9cbad600fe61749c29 100644 (file)
@@ -667,7 +667,9 @@ static inline void hlist_move_list(struct hlist_head *old,
             pos = n)
 
 #define hlist_entry_safe(ptr, type, member) \
-       (ptr) ? hlist_entry(ptr, type, member) : NULL
+       ({ typeof(ptr) ____ptr = (ptr); \
+          ____ptr ? hlist_entry(____ptr, type, member) : NULL; \
+       })
 
 /**
  * hlist_for_each_entry        - iterate over list of given type
index a4d13d7cd00187cf2928de2d651d486388078224..3bbda22721ea083cc35251e399a37742b72c8bae 100644 (file)
@@ -221,6 +221,7 @@ struct palmas_clk_platform_data {
 };
 
 struct palmas_platform_data {
+       int irq_flags;
        int gpio_base;
 
        /* bit value to be loaded to the POWER_CTRL register */
index aaceab402ec53a35fdbe3eb57ebe6aeb90610753..6d309032dc0ddc7da95e8a1b6b20b275fef0b7bb 100644 (file)
@@ -323,5 +323,6 @@ int tps65912_device_init(struct tps65912 *tps65912);
 void tps65912_device_exit(struct tps65912 *tps65912);
 int tps65912_irq_init(struct tps65912 *tps65912, int irq,
                        struct tps65912_platform_data *pdata);
+int tps65912_irq_exit(struct tps65912 *tps65912);
 
 #endif /*  __LINUX_MFD_TPS65912_H */
index b132067e9e997252c2fa19bf5c4be3c48b0f8f87..867aa23f93704b04154d9ff958990e3b635abc50 100644 (file)
@@ -15,6 +15,8 @@
 #ifndef __MFD_WM831X_AUXADC_H__
 #define __MFD_WM831X_AUXADC_H__
 
+struct wm831x;
+
 /*
  * R16429 (0x402D) - AuxADC Data
  */
index 4a3b83a776148eb2ace611436b38ab42e931450e..76c22648436f22dad8ee59cec7f69ee984322a47 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/irqdomain.h>
 #include <linux/list.h>
 #include <linux/regmap.h>
+#include <linux/mfd/wm831x/auxadc.h>
 
 /*
  * Register values.
@@ -355,7 +356,6 @@ enum wm831x_parent {
 };
 
 struct wm831x;
-enum wm831x_auxadc;
 
 typedef int (*wm831x_auxadc_read_fn)(struct wm831x *wm831x,
                                     enum wm831x_auxadc input);
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 e47ee462c2f2e69a8cbef4ef3a3d7bfc873cb51f..1d795df6f4cfdb53575efe2fd756015c0ad363de 100644 (file)
@@ -799,6 +799,12 @@ static inline int __perf_event_disable(void *info)                 { return -1; }
 static inline void perf_event_task_tick(void)                          { }
 #endif
 
+#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_INTEL)
+extern void perf_restore_debug_store(void);
+#else
+static inline void perf_restore_debug_store(void)                      { }
+#endif
+
 #define perf_output_put(handle, x) perf_output_copy((handle), &(x), sizeof(x))
 
 /*
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 5ae8456d967010b8cb35b1d861d28a487e2103ba..c23099413ad6c03b935826d6680388cc3976ce81 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/cgroup.h>
+#include <linux/errno.h>
 
 /*
  * The core object. the cgroup that wishes to account for some
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 c68a147939a63ef9a6b04e08c9aef27e97621c31..aadc6a04e1acb91bb4baa40b545237d4822dfaee 100644 (file)
@@ -138,6 +138,9 @@ typedef __be32      rpc_fraghdr;
 #define RPC_MAX_HEADER_WITH_AUTH \
        (RPC_CALLHDRSIZE + 2*(2+RPC_MAX_AUTH_SIZE/4))
 
+#define RPC_MAX_REPHEADER_WITH_AUTH \
+       (RPC_REPHDRSIZE + (2 + RPC_MAX_AUTH_SIZE/4))
+
 /*
  * RFC1833/RFC3530 rpcbind (v3+) well-known netid's.
  */
index 3c671c1b37f65350c7f18a6afac3e6a7c594a820..8860594d6364b30f4a5e1c2d4b64be63a28d2a9a 100644 (file)
@@ -60,7 +60,7 @@ struct usb_configuration;
  * @name: For diagnostics, identifies the function.
  * @strings: tables of strings, keyed by identifiers assigned during bind()
  *     and by language IDs provided in control requests
- * @descriptors: Table of full (or low) speed descriptors, using interface and
+ * @fs_descriptors: Table of full (or low) speed descriptors, using interface and
  *     string identifiers assigned during @bind().  If this pointer is null,
  *     the function will not be available at full speed (or at low speed).
  * @hs_descriptors: Table of high speed descriptors, using interface and
@@ -290,6 +290,7 @@ enum {
  *     after function notifications
  * @resume: Notifies configuration when the host restarts USB traffic,
  *     before function notifications
+ * @gadget_driver: Gadget driver controlling this driver
  *
  * Devices default to reporting self powered operation.  Devices which rely
  * on bus powered operation should report this in their @bind method.
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 11b6ca3e0873c4795fc3b8e8214e5503e6ba16d4..df2f9a0bba6ab78ad93f8ceb7aa240bf6cf329ec 100644 (file)
@@ -107,10 +107,12 @@ struct acct_v3
 #define ACORE          0x08    /* ... dumped core */
 #define AXSIG          0x10    /* ... was killed by a signal */
 
-#ifdef __BIG_ENDIAN
+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN)
 #define ACCT_BYTEORDER 0x80    /* accounting file is big endian */
-#else
+#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
 #define ACCT_BYTEORDER 0x00    /* accounting file is little endian */
+#else
+#error unspecified endianness
 #endif
 
 #ifndef __KERNEL__
index 86fa7a71336a1cc2ea007c7410e3ede14807ec4c..bb2554f7fbd12a677015d48703ccf681357e84c6 100644 (file)
@@ -62,9 +62,9 @@ struct io_event {
        __s64           res2;           /* secondary result */
 };
 
-#if defined(__LITTLE_ENDIAN)
+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
 #define PADDED(x,y)    x, y
-#elif defined(__BIG_ENDIAN)
+#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN)
 #define PADDED(x,y)    y, x
 #else
 #error edit for your odd byteorder.
index ee753536ab7088350a147e1743805985a6b01ac0..fe1a5406d4d93cdf6012d11ab7315f014b552ede 100644 (file)
@@ -145,16 +145,18 @@ typedef struct mdp_superblock_s {
        __u32 failed_disks;     /*  4 Number of failed disks                  */
        __u32 spare_disks;      /*  5 Number of spare disks                   */
        __u32 sb_csum;          /*  6 checksum of the whole superblock        */
-#ifdef __BIG_ENDIAN
+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN)
        __u32 events_hi;        /*  7 high-order of superblock update count   */
        __u32 events_lo;        /*  8 low-order of superblock update count    */
        __u32 cp_events_hi;     /*  9 high-order of checkpoint update count   */
        __u32 cp_events_lo;     /* 10 low-order of checkpoint update count    */
-#else
+#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)
        __u32 events_lo;        /*  7 low-order of superblock update count    */
        __u32 events_hi;        /*  8 high-order of superblock update count   */
        __u32 cp_events_lo;     /*  9 low-order of checkpoint update count    */
        __u32 cp_events_hi;     /* 10 high-order of checkpoint update count   */
+#else
+#error unspecified endianness
 #endif
        __u32 recovery_cp;      /* 11 recovery checkpoint sector count        */
        /* There are only valid for minor_version > 90 */
index b6a23a483d740d635f50bf2ab5261510396e5dff..74c2bf7211f85ed0a55f82987d690cd6bc9aad7c 100644 (file)
 #define PORT_8250_CIR  23      /* CIR infrared port, has its own driver */
 #define PORT_XR17V35X  24      /* Exar XR17V35x UARTs */
 #define PORT_BRCM_TRUMANAGE    25
-#define PORT_MAX_8250  25      /* max port ID */
+#define PORT_ALTR_16550_F32 26 /* Altera 16550 UART with 32 FIFOs */
+#define PORT_ALTR_16550_F64 27 /* Altera 16550 UART with 64 FIFOs */
+#define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */
+#define PORT_MAX_8250  28      /* max port ID */
 
 /*
  * ARM specific type numbers.  These are not currently guaranteed
index 22616cd434bc7d91d157074eb0cf9c9ce9b9f0f0..5341d7232c3ac083c2f87c8a3e1098a9c5e8d601 100644 (file)
@@ -28,10 +28,6 @@ config BUILDTIME_EXTABLE_SORT
 
 menu "General setup"
 
-config EXPERIMENTAL
-       bool
-       default y
-
 config BROKEN
        bool
 
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 8d932b1c9056af738e2903bf813bcbd035ed3892..1766d324d5e35c38ca3910ea237857c0600d1a02 100644 (file)
@@ -1141,6 +1141,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
                return ERR_PTR(-EINVAL);
 
+       if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
+               return ERR_PTR(-EINVAL);
+
        /*
         * Thread groups must share signals as well, and detached threads
         * can only be started up within the thread group.
@@ -1807,7 +1810,7 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
         * If unsharing a user namespace must also unshare the thread.
         */
        if (unshare_flags & CLONE_NEWUSER)
-               unshare_flags |= CLONE_THREAD;
+               unshare_flags |= CLONE_THREAD | CLONE_FS;
        /*
         * If unsharing a pid namespace must also unshare the thread.
         */
index f0090a993dab1e3d43fd202e05bd904aefc05f2a..b26dcfc02c9489b3ca00bfd076f2208bb4964366 100644 (file)
@@ -223,7 +223,8 @@ static void drop_futex_key_refs(union futex_key *key)
  * @rw:                mapping needs to be read/write (values: VERIFY_READ,
  *              VERIFY_WRITE)
  *
- * Returns a negative error code or 0
+ * Return: a negative error code or 0
+ *
  * The key words are stored in *key on success.
  *
  * For shared mappings, it's (page->index, file_inode(vma->vm_file),
@@ -705,9 +706,9 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
  *                     be "current" except in the case of requeue pi.
  * @set_waiters:       force setting the FUTEX_WAITERS bit (1) or not (0)
  *
- * Returns:
- *  0 - ready to wait
- *  1 - acquired the lock
+ * Return:
+ *  0 - ready to wait;
+ *  1 - acquired the lock;
  * <0 - error
  *
  * The hb->lock and futex_key refs shall be held by the caller.
@@ -1191,9 +1192,9 @@ void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key,
  * then direct futex_lock_pi_atomic() to force setting the FUTEX_WAITERS bit.
  * hb1 and hb2 must be held by the caller.
  *
- * Returns:
- *  0 - failed to acquire the lock atomicly
- *  1 - acquired the lock
+ * Return:
+ *  0 - failed to acquire the lock atomically;
+ *  1 - acquired the lock;
  * <0 - error
  */
 static int futex_proxy_trylock_atomic(u32 __user *pifutex,
@@ -1254,8 +1255,8 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
  * Requeue waiters on uaddr1 to uaddr2. In the requeue_pi case, try to acquire
  * uaddr2 atomically on behalf of the top waiter.
  *
- * Returns:
- * >=0 - on success, the number of tasks requeued or woken
+ * Return:
+ * >=0 - on success, the number of tasks requeued or woken;
  *  <0 - on error
  */
 static int futex_requeue(u32 __user *uaddr1, unsigned int flags,
@@ -1536,8 +1537,8 @@ static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb)
  * The q->lock_ptr must not be held by the caller. A call to unqueue_me() must
  * be paired with exactly one earlier call to queue_me().
  *
- * Returns:
- *   1 - if the futex_q was still queued (and we removed unqueued it)
+ * Return:
+ *   1 - if the futex_q was still queued (and we removed unqueued it);
  *   0 - if the futex_q was already removed by the waking thread
  */
 static int unqueue_me(struct futex_q *q)
@@ -1707,9 +1708,9 @@ static long futex_wait_restart(struct restart_block *restart);
  * the pi_state owner as well as handle race conditions that may allow us to
  * acquire the lock. Must be called with the hb lock held.
  *
- * Returns:
- *  1 - success, lock taken
- *  0 - success, lock not taken
+ * Return:
+ *  1 - success, lock taken;
+ *  0 - success, lock not taken;
  * <0 - on error (-EFAULT)
  */
 static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked)
@@ -1824,8 +1825,8 @@ static void futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q,
  * Return with the hb lock held and a q.key reference on success, and unlocked
  * with no q.key reference on failure.
  *
- * Returns:
- *  0 - uaddr contains val and hb has been locked
+ * Return:
+ *  0 - uaddr contains val and hb has been locked;
  * <1 - -EFAULT or -EWOULDBLOCK (uaddr does not contain val) and hb is unlocked
  */
 static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags,
@@ -2203,9 +2204,9 @@ pi_faulted:
  * the wakeup and return the appropriate error code to the caller.  Must be
  * called with the hb lock held.
  *
- * Returns
- *  0 - no early wakeup detected
- * <0 - -ETIMEDOUT or -ERESTARTNOINTR
+ * Return:
+ *  0 = no early wakeup detected;
+ * <0 = -ETIMEDOUT or -ERESTARTNOINTR
  */
 static inline
 int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
@@ -2247,7 +2248,6 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
  * @val:       the expected value of uaddr
  * @abs_time:  absolute timeout
  * @bitset:    32 bit wakeup bitset set by userspace, defaults to all
- * @clockrt:   whether to use CLOCK_REALTIME (1) or CLOCK_MONOTONIC (0)
  * @uaddr2:    the pi futex we will take prior to returning to user-space
  *
  * The caller will wait on uaddr and will be requeued by futex_requeue() to
@@ -2258,7 +2258,7 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
  * there was a need to.
  *
  * We call schedule in futex_wait_queue_me() when we enqueue and return there
- * via the following:
+ * via the following--
  * 1) wakeup on uaddr2 after an atomic lock acquisition by futex_requeue()
  * 2) wakeup on uaddr2 after a requeue
  * 3) signal
@@ -2276,8 +2276,8 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
  *
  * If 4 or 7, we cleanup and return with -ETIMEDOUT.
  *
- * Returns:
- *  0 - On success
+ * Return:
+ *  0 - On success;
  * <0 - On error
  */
 static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
index 2ec870a4c3c4faa2a6c30c0ee380d9fc9bd25de5..dd72567767d963ccb8ac2f3cfa4a824fa5f81b4e 100644 (file)
@@ -485,6 +485,9 @@ flush_signal_handlers(struct task_struct *t, int force_default)
                if (force_default || ka->sa.sa_handler != SIG_IGN)
                        ka->sa.sa_handler = SIG_DFL;
                ka->sa.sa_flags = 0;
+#ifdef __ARCH_HAS_SA_RESTORER
+               ka->sa.sa_restorer = NULL;
+#endif
                sigemptyset(&ka->sa.sa_mask);
                ka++;
        }
@@ -2682,7 +2685,7 @@ static int do_sigpending(void *set, unsigned long sigsetsize)
 /**
  *  sys_rt_sigpending - examine a pending signal that has been raised
  *                     while blocked
- *  @set: stores pending signals
+ *  @uset: stores pending signals
  *  @sigsetsize: size of sigset_t type or larger
  */
 SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, uset, size_t, sigsetsize)
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 192473b22799032c5cb013868f778ad4bc30626a..fc382d6e2765d4a454a85aa5591c8edc452dccfb 100644 (file)
@@ -414,24 +414,28 @@ config PROBE_EVENTS
        def_bool n
 
 config DYNAMIC_FTRACE
-       bool "enable/disable ftrace tracepoints dynamically"
+       bool "enable/disable function tracing dynamically"
        depends on FUNCTION_TRACER
        depends on HAVE_DYNAMIC_FTRACE
        default y
        help
-          This option will modify all the calls to ftrace dynamically
-         (will patch them out of the binary image and replace them
-         with a No-Op instruction) as they are called. A table is
-         created to dynamically enable them again.
+         This option will modify all the calls to function tracing
+         dynamically (will patch them out of the binary image and
+         replace them with a No-Op instruction) on boot up. During
+         compile time, a table is made of all the locations that ftrace
+         can function trace, and this table is linked into the kernel
+         image. When this is enabled, functions can be individually
+         enabled, and the functions not enabled will not affect
+         performance of the system.
+
+         See the files in /sys/kernel/debug/tracing:
+           available_filter_functions
+           set_ftrace_filter
+           set_ftrace_notrace
 
          This way a CONFIG_FUNCTION_TRACER kernel is slightly larger, but
          otherwise has native performance as long as no tracing is active.
 
-         The changes to the code are done by a kernel thread that
-         wakes up once a second and checks to see if any ftrace calls
-         were made. If so, it runs stop_machine (stops all CPUS)
-         and modifies the code to jump over the call to ftrace.
-
 config DYNAMIC_FTRACE_WITH_REGS
        def_bool y
        depends on DYNAMIC_FTRACE
index c2e2c23103742e3a3e53cf7b318aa0c804f5e1a8..1f835a83cb2c4c74b13b0c8641ce648a75591ae6 100644 (file)
@@ -2400,6 +2400,27 @@ static void test_ftrace_alive(struct seq_file *m)
        seq_printf(m, "#          MAY BE MISSING FUNCTION EVENTS\n");
 }
 
+#ifdef CONFIG_TRACER_MAX_TRACE
+static void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter)
+{
+       if (iter->trace->allocated_snapshot)
+               seq_printf(m, "#\n# * Snapshot is allocated *\n#\n");
+       else
+               seq_printf(m, "#\n# * Snapshot is freed *\n#\n");
+
+       seq_printf(m, "# Snapshot commands:\n");
+       seq_printf(m, "# echo 0 > snapshot : Clears and frees snapshot buffer\n");
+       seq_printf(m, "# echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.\n");
+       seq_printf(m, "#                      Takes a snapshot of the main buffer.\n");
+       seq_printf(m, "# echo 2 > snapshot : Clears snapshot buffer (but does not allocate)\n");
+       seq_printf(m, "#                      (Doesn't have to be '2' works with any number that\n");
+       seq_printf(m, "#                       is not a '0' or '1')\n");
+}
+#else
+/* Should never be called */
+static inline void print_snapshot_help(struct seq_file *m, struct trace_iterator *iter) { }
+#endif
+
 static int s_show(struct seq_file *m, void *v)
 {
        struct trace_iterator *iter = v;
@@ -2411,7 +2432,9 @@ static int s_show(struct seq_file *m, void *v)
                        seq_puts(m, "#\n");
                        test_ftrace_alive(m);
                }
-               if (iter->trace && iter->trace->print_header)
+               if (iter->snapshot && trace_empty(iter))
+                       print_snapshot_help(m, iter);
+               else if (iter->trace && iter->trace->print_header)
                        iter->trace->print_header(m);
                else
                        trace_default_header(m);
@@ -4144,8 +4167,6 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
        default:
                if (current_trace->allocated_snapshot)
                        tracing_reset_online_cpus(&max_tr);
-               else
-                       ret = -EINVAL;
                break;
        }
 
index 8b650837083e74f7c8bcac7b4f83081c448e36ed..b14f4d3420439ca629be08494ef417e734513499 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/uaccess.h>
 #include <linux/ctype.h>
 #include <linux/projid.h>
+#include <linux/fs_struct.h>
 
 static struct kmem_cache *user_ns_cachep __read_mostly;
 
@@ -837,6 +838,9 @@ static int userns_install(struct nsproxy *nsproxy, void *ns)
        if (atomic_read(&current->mm->mm_users) > 1)
                return -EINVAL;
 
+       if (current->fs->users != 1)
+               return -EINVAL;
+
        if (!ns_capable(user_ns, CAP_SYS_ADMIN))
                return -EPERM;
 
index 81f2457811eb346915b8c17e4ce5ed44a5de8c10..55fac5b991b768ef059a783fb2a85d7521154e60 100644 (file)
@@ -457,11 +457,12 @@ static int worker_pool_assign_id(struct worker_pool *pool)
        int ret;
 
        mutex_lock(&worker_pool_idr_mutex);
-       idr_pre_get(&worker_pool_idr, GFP_KERNEL);
-       ret = idr_get_new(&worker_pool_idr, pool, &pool->id);
+       ret = idr_alloc(&worker_pool_idr, pool, 0, 0, GFP_KERNEL);
+       if (ret >= 0)
+               pool->id = ret;
        mutex_unlock(&worker_pool_idr_mutex);
 
-       return ret;
+       return ret < 0 ? ret : 0;
 }
 
 /*
index 73f4d53c02f3deaee2a0df5b2909a218b38a10e8..322e2816f2fb6fe67b512bb4329c49e7377c1591 100644 (file)
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -106,8 +106,14 @@ static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr)
        if (layer_idr)
                return get_from_free_list(layer_idr);
 
-       /* try to allocate directly from kmem_cache */
-       new = kmem_cache_zalloc(idr_layer_cache, gfp_mask);
+       /*
+        * Try to allocate directly from kmem_cache.  We want to try this
+        * before preload buffer; otherwise, non-preloading idr_alloc()
+        * users will end up taking advantage of preloading ones.  As the
+        * following is allowed to fail for preloaded cases, suppress
+        * warning this time.
+        */
+       new = kmem_cache_zalloc(idr_layer_cache, gfp_mask | __GFP_NOWARN);
        if (new)
                return new;
 
@@ -115,18 +121,24 @@ static struct idr_layer *idr_layer_alloc(gfp_t gfp_mask, struct idr *layer_idr)
         * Try to fetch one from the per-cpu preload buffer if in process
         * context.  See idr_preload() for details.
         */
-       if (in_interrupt())
-               return NULL;
-
-       preempt_disable();
-       new = __this_cpu_read(idr_preload_head);
-       if (new) {
-               __this_cpu_write(idr_preload_head, new->ary[0]);
-               __this_cpu_dec(idr_preload_cnt);
-               new->ary[0] = NULL;
+       if (!in_interrupt()) {
+               preempt_disable();
+               new = __this_cpu_read(idr_preload_head);
+               if (new) {
+                       __this_cpu_write(idr_preload_head, new->ary[0]);
+                       __this_cpu_dec(idr_preload_cnt);
+                       new->ary[0] = NULL;
+               }
+               preempt_enable();
+               if (new)
+                       return new;
        }
-       preempt_enable();
-       return new;
+
+       /*
+        * Both failed.  Try kmem_cache again w/o adding __GFP_NOWARN so
+        * that memory allocation failure warning is printed as intended.
+        */
+       return kmem_cache_zalloc(idr_layer_cache, gfp_mask);
 }
 
 static void idr_layer_rcu_free(struct rcu_head *head)
@@ -184,20 +196,7 @@ static void idr_mark_full(struct idr_layer **pa, int id)
        }
 }
 
-/**
- * idr_pre_get - reserve resources for idr allocation
- * @idp:       idr handle
- * @gfp_mask:  memory allocation flags
- *
- * This function should be called prior to calling the idr_get_new* functions.
- * It preallocates enough memory to satisfy the worst possible allocation. The
- * caller should pass in GFP_KERNEL if possible.  This of course requires that
- * no spinning locks be held.
- *
- * If the system is REALLY out of memory this function returns %0,
- * otherwise %1.
- */
-int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
+int __idr_pre_get(struct idr *idp, gfp_t gfp_mask)
 {
        while (idp->id_free_cnt < MAX_IDR_FREE) {
                struct idr_layer *new;
@@ -208,13 +207,12 @@ int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
        }
        return 1;
 }
-EXPORT_SYMBOL(idr_pre_get);
+EXPORT_SYMBOL(__idr_pre_get);
 
 /**
  * sub_alloc - try to allocate an id without growing the tree depth
  * @idp: idr handle
  * @starting_id: id to start search at
- * @id: pointer to the allocated handle
  * @pa: idr_layer[MAX_IDR_LEVEL] used as backtrack buffer
  * @gfp_mask: allocation mask for idr_layer_alloc()
  * @layer_idr: optional idr passed to idr_layer_alloc()
@@ -376,25 +374,7 @@ static void idr_fill_slot(struct idr *idr, void *ptr, int id,
        idr_mark_full(pa, id);
 }
 
-/**
- * idr_get_new_above - allocate new idr entry above or equal to a start id
- * @idp: idr handle
- * @ptr: pointer you want associated with the id
- * @starting_id: id to start search at
- * @id: pointer to the allocated handle
- *
- * This is the allocate id function.  It should be called with any
- * required locks.
- *
- * If allocation from IDR's private freelist fails, idr_get_new_above() will
- * return %-EAGAIN.  The caller should retry the idr_pre_get() call to refill
- * IDR's preallocation and then retry the idr_get_new_above() call.
- *
- * If the idr is full idr_get_new_above() will return %-ENOSPC.
- *
- * @id returns a value in the range @starting_id ... %0x7fffffff
- */
-int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
+int __idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
 {
        struct idr_layer *pa[MAX_IDR_LEVEL + 1];
        int rv;
@@ -407,7 +387,7 @@ int idr_get_new_above(struct idr *idp, void *ptr, int starting_id, int *id)
        *id = rv;
        return 0;
 }
-EXPORT_SYMBOL(idr_get_new_above);
+EXPORT_SYMBOL(__idr_get_new_above);
 
 /**
  * idr_preload - preload for idr_alloc()
@@ -569,8 +549,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 +646,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 +795,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;
@@ -918,7 +888,7 @@ static void free_bitmap(struct ida *ida, struct ida_bitmap *bitmap)
 int ida_pre_get(struct ida *ida, gfp_t gfp_mask)
 {
        /* allocate idr_layers */
-       if (!idr_pre_get(&ida->idr, gfp_mask))
+       if (!__idr_pre_get(&ida->idr, gfp_mask))
                return 0;
 
        /* allocate free_bitmap */
index 82a04d7ba99ea317aca1888c103f3bee32590bbb..08837db52d94f16b39a45a80eaa4fef774ef8b7b 100644 (file)
@@ -15,7 +15,7 @@ config XZ_DEC_X86
 
 config XZ_DEC_POWERPC
        bool "PowerPC BCJ filter decoder"
-       default y if POWERPC
+       default y if PPC
        select XZ_DEC_BCJ
 
 config XZ_DEC_IA64
index ae55c1e04d105016cf7c780398552e56a498e65a..3bea74f1ccfe1f1f5c134fd5c98767d620553b60 100644 (file)
@@ -286,8 +286,12 @@ config NR_QUICK
        default "1"
 
 config VIRT_TO_BUS
-       def_bool y
-       depends on HAVE_VIRT_TO_BUS
+       bool
+       help
+         An architecture should select this if it implements the
+         deprecated interface virt_to_bus().  All new architectures
+         should probably not select this.
+
 
 config MMU_NOTIFIER
        bool
index 0cd4c11488edf8c8fd33346e9b94e28fb3272aa1..4723ac8d2fc200d5990f830b6f4c8c0fd2a9bbcf 100644 (file)
@@ -129,7 +129,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
        struct vm_area_struct *vma;
        int err = -EINVAL;
        int has_write_lock = 0;
-       vm_flags_t vm_flags;
+       vm_flags_t vm_flags = 0;
 
        if (prot)
                return err;
@@ -254,7 +254,8 @@ get_write_lock:
         */
 
 out:
-       vm_flags = vma->vm_flags;
+       if (vma)
+               vm_flags = vma->vm_flags;
        if (likely(!has_write_lock))
                up_read(&mm->mmap_sem);
        else
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 b81a367b9f39bb056cc4127a674e8a3dd4d2567d..9597eec8239d3f2e3fc2052179ed588643be53e0 100644 (file)
@@ -1801,7 +1801,7 @@ int __ref remove_memory(int nid, u64 start, u64 size)
        int retry = 1;
 
        start_pfn = PFN_DOWN(start);
-       end_pfn = start_pfn + PFN_DOWN(size);
+       end_pfn = PFN_UP(start + size - 1);
 
        /*
         * When CONFIG_MEMCG is on, one memory block may be used by other
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 926b466497492f3f8463ebc623adc4fbddf9547a..fd26d0433509e2b5885c74249a9eb04828285180 100644 (file)
@@ -429,12 +429,6 @@ compat_process_vm_rw(compat_pid_t pid,
        if (flags != 0)
                return -EINVAL;
 
-       if (!access_ok(VERIFY_READ, lvec, liovcnt * sizeof(*lvec)))
-               goto out;
-
-       if (!access_ok(VERIFY_READ, rvec, riovcnt * sizeof(*rvec)))
-               goto out;
-
        if (vm_write)
                rc = compat_rw_copy_check_uvector(WRITE, lvec, liovcnt,
                                                  UIO_FASTIOV, iovstack_l,
@@ -459,8 +453,6 @@ free_iovecs:
                kfree(iov_r);
        if (iov_l != iovstack_l)
                kfree(iov_l);
-
-out:
        return rc;
 }
 
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 d5f1d3fd4b28df39473446defcbad23928d4cb2d..314c73ed418fc43e977c7d47e4bce88ea1104b53 100644 (file)
@@ -66,7 +66,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
                        goto out;
                }
 
-               mdst = br_mdb_get(br, skb);
+               mdst = br_mdb_get(br, skb, vid);
                if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb))
                        br_multicast_deliver(mdst, skb);
                else
index 480330151898486eee3a42382c28f327021d111b..828e2bcc1f525570809b652c98e1c011b2850940 100644 (file)
@@ -97,7 +97,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
        if (is_broadcast_ether_addr(dest))
                skb2 = skb;
        else if (is_multicast_ether_addr(dest)) {
-               mdst = br_mdb_get(br, skb);
+               mdst = br_mdb_get(br, skb, vid);
                if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) {
                        if ((mdst && mdst->mglist) ||
                            br_multicast_is_router(br))
index 9f97b850fc65171cf87692cf87a3b2e29d906e0c..ee79f3f20383c9112ff2685ef10b6d69a1d40c97 100644 (file)
@@ -80,6 +80,7 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
                                port = p->port;
                                if (port) {
                                        struct br_mdb_entry e;
+                                       memset(&e, 0, sizeof(e));
                                        e.ifindex = port->dev->ifindex;
                                        e.state = p->state;
                                        if (p->addr.proto == htons(ETH_P_IP))
@@ -136,6 +137,7 @@ static int br_mdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
                                break;
 
                        bpm = nlmsg_data(nlh);
+                       memset(bpm, 0, sizeof(*bpm));
                        bpm->ifindex = dev->ifindex;
                        if (br_mdb_fill_info(skb, cb, dev) < 0)
                                goto out;
@@ -171,6 +173,7 @@ static int nlmsg_populate_mdb_fill(struct sk_buff *skb,
                return -EMSGSIZE;
 
        bpm = nlmsg_data(nlh);
+       memset(bpm, 0, sizeof(*bpm));
        bpm->family  = AF_BRIDGE;
        bpm->ifindex = dev->ifindex;
        nest = nla_nest_start(skb, MDBA_MDB);
@@ -228,6 +231,7 @@ void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
 {
        struct br_mdb_entry entry;
 
+       memset(&entry, 0, sizeof(entry));
        entry.ifindex = port->dev->ifindex;
        entry.addr.proto = group->proto;
        entry.addr.u.ip4 = group->u.ip4;
index 10e6fce1bb62abb0987a98c167bf653356e088ac..923fbeaf7afdbb957afb732fc226c4fb669e6a2e 100644 (file)
@@ -132,7 +132,7 @@ static struct net_bridge_mdb_entry *br_mdb_ip6_get(
 #endif
 
 struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
-                                       struct sk_buff *skb)
+                                       struct sk_buff *skb, u16 vid)
 {
        struct net_bridge_mdb_htable *mdb = rcu_dereference(br->mdb);
        struct br_ip ip;
@@ -144,6 +144,7 @@ struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
                return NULL;
 
        ip.proto = skb->protocol;
+       ip.vid = vid;
 
        switch (skb->protocol) {
        case htons(ETH_P_IP):
index 6d314c4e6bcbca8aa68da999e6117879cda9db12..3cbf5beb3d4be267fbea19a2fd81b7b09d3d6a0c 100644 (file)
@@ -442,7 +442,7 @@ extern int br_multicast_rcv(struct net_bridge *br,
                            struct net_bridge_port *port,
                            struct sk_buff *skb);
 extern struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
-                                              struct sk_buff *skb);
+                                              struct sk_buff *skb, u16 vid);
 extern void br_multicast_add_port(struct net_bridge_port *port);
 extern void br_multicast_del_port(struct net_bridge_port *port);
 extern void br_multicast_enable_port(struct net_bridge_port *port);
@@ -504,7 +504,7 @@ static inline int br_multicast_rcv(struct net_bridge *br,
 }
 
 static inline struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
-                                                     struct sk_buff *skb)
+                                                     struct sk_buff *skb, u16 vid)
 {
        return NULL;
 }
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 69bc4bf89e3e79bb47eddcac63367913a8645ef0..4543b9aba40ce1a9e4565824624bcecba6c298cb 100644 (file)
@@ -654,6 +654,24 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
        return 0;
 }
 
+static int __decode_pgid(void **p, void *end, struct ceph_pg *pg)
+{
+       u8 v;
+
+       ceph_decode_need(p, end, 1+8+4+4, bad);
+       v = ceph_decode_8(p);
+       if (v != 1)
+               goto bad;
+       pg->pool = ceph_decode_64(p);
+       pg->seed = ceph_decode_32(p);
+       *p += 4; /* skip preferred */
+       return 0;
+
+bad:
+       dout("error decoding pgid\n");
+       return -EINVAL;
+}
+
 /*
  * decode a full map.
  */
@@ -745,13 +763,12 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
        for (i = 0; i < len; i++) {
                int n, j;
                struct ceph_pg pgid;
-               struct ceph_pg_v1 pgid_v1;
                struct ceph_pg_mapping *pg;
 
-               ceph_decode_need(p, end, sizeof(u32) + sizeof(u64), bad);
-               ceph_decode_copy(p, &pgid_v1, sizeof(pgid_v1));
-               pgid.pool = le32_to_cpu(pgid_v1.pool);
-               pgid.seed = le16_to_cpu(pgid_v1.ps);
+               err = __decode_pgid(p, end, &pgid);
+               if (err)
+                       goto bad;
+               ceph_decode_need(p, end, sizeof(u32), bad);
                n = ceph_decode_32(p);
                err = -EINVAL;
                if (n > (UINT_MAX - sizeof(*pg)) / sizeof(u32))
@@ -818,8 +835,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
        u16 version;
 
        ceph_decode_16_safe(p, end, version, bad);
-       if (version > 6) {
-               pr_warning("got unknown v %d > %d of inc osdmap\n", version, 6);
+       if (version != 6) {
+               pr_warning("got unknown v %d != 6 of inc osdmap\n", version);
                goto bad;
        }
 
@@ -963,15 +980,14 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
        while (len--) {
                struct ceph_pg_mapping *pg;
                int j;
-               struct ceph_pg_v1 pgid_v1;
                struct ceph_pg pgid;
                u32 pglen;
-               ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad);
-               ceph_decode_copy(p, &pgid_v1, sizeof(pgid_v1));
-               pgid.pool = le32_to_cpu(pgid_v1.pool);
-               pgid.seed = le16_to_cpu(pgid_v1.ps);
-               pglen = ceph_decode_32(p);
 
+               err = __decode_pgid(p, end, &pgid);
+               if (err)
+                       goto bad;
+               ceph_decode_need(p, end, sizeof(u32), bad);
+               pglen = ceph_decode_32(p);
                if (pglen) {
                        ceph_decode_need(p, end, pglen*sizeof(u32), bad);
 
index a06a7a58dd1181b4134adf7cd95d4b1b5512cda3..dffbef70cd31253625da50819a171fbc59b386a5 100644 (file)
@@ -3444,6 +3444,7 @@ ncls:
                }
                switch (rx_handler(&skb)) {
                case RX_HANDLER_CONSUMED:
+                       ret = NET_RX_SUCCESS;
                        goto unlock;
                case RX_HANDLER_ANOTHER:
                        goto another_round;
@@ -4103,7 +4104,7 @@ static void net_rx_action(struct softirq_action *h)
                 * Allow this to run for 2 jiffies since which will allow
                 * an average latency of 1.5/HZ.
                 */
-               if (unlikely(budget <= 0 || time_after(jiffies, time_limit)))
+               if (unlikely(budget <= 0 || time_after_eq(jiffies, time_limit)))
                        goto softnet_break;
 
                local_irq_enable();
@@ -4780,7 +4781,7 @@ EXPORT_SYMBOL(dev_set_mac_address);
 /**
  *     dev_change_carrier - Change device carrier
  *     @dev: device
- *     @new_carries: new value
+ *     @new_carrier: new value
  *
  *     Change device carrier
  */
index b376410ff2590f3e10897488fd6c092df70faa4c..a585d45cc9d9faefbc51fde485971a1336065e58 100644 (file)
@@ -979,6 +979,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
                         * report anything.
                         */
                        ivi.spoofchk = -1;
+                       memset(ivi.mac, 0, sizeof(ivi.mac));
                        if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi))
                                break;
                        vf_mac.vf =
index 1b588e23cf80b561632b9b5e16b851dff218a933..21291f1abcd6d0d228241b6771984d704bc1699e 100644 (file)
@@ -284,6 +284,7 @@ static int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlmsghdr *nlh,
        if (!netdev->dcbnl_ops->getpermhwaddr)
                return -EOPNOTSUPP;
 
+       memset(perm_addr, 0, sizeof(perm_addr));
        netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr);
 
        return nla_put(skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), perm_addr);
@@ -1042,6 +1043,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
 
        if (ops->ieee_getets) {
                struct ieee_ets ets;
+               memset(&ets, 0, sizeof(ets));
                err = ops->ieee_getets(netdev, &ets);
                if (!err &&
                    nla_put(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets))
@@ -1050,6 +1052,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
 
        if (ops->ieee_getmaxrate) {
                struct ieee_maxrate maxrate;
+               memset(&maxrate, 0, sizeof(maxrate));
                err = ops->ieee_getmaxrate(netdev, &maxrate);
                if (!err) {
                        err = nla_put(skb, DCB_ATTR_IEEE_MAXRATE,
@@ -1061,6 +1064,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
 
        if (ops->ieee_getpfc) {
                struct ieee_pfc pfc;
+               memset(&pfc, 0, sizeof(pfc));
                err = ops->ieee_getpfc(netdev, &pfc);
                if (!err &&
                    nla_put(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc))
@@ -1094,6 +1098,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
        /* get peer info if available */
        if (ops->ieee_peer_getets) {
                struct ieee_ets ets;
+               memset(&ets, 0, sizeof(ets));
                err = ops->ieee_peer_getets(netdev, &ets);
                if (!err &&
                    nla_put(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets))
@@ -1102,6 +1107,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
 
        if (ops->ieee_peer_getpfc) {
                struct ieee_pfc pfc;
+               memset(&pfc, 0, sizeof(pfc));
                err = ops->ieee_peer_getpfc(netdev, &pfc);
                if (!err &&
                    nla_put(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc))
@@ -1280,6 +1286,7 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev)
        /* peer info if available */
        if (ops->cee_peer_getpg) {
                struct cee_pg pg;
+               memset(&pg, 0, sizeof(pg));
                err = ops->cee_peer_getpg(netdev, &pg);
                if (!err &&
                    nla_put(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg))
@@ -1288,6 +1295,7 @@ static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev)
 
        if (ops->cee_peer_getpfc) {
                struct cee_pfc pfc;
+               memset(&pfc, 0, sizeof(pfc));
                err = ops->cee_peer_getpfc(netdev, &pfc);
                if (!err &&
                    nla_put(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc))
index 8c2251fb0a3fb5ba9347710e4682bdb273d49af9..bba5f8336317a178c5c7c073acd3bbfafde0e6b9 100644 (file)
@@ -84,7 +84,7 @@
        (memcmp(addr1, addr2, length >> 3) == 0)
 
 /* local link, i.e. FE80::/10 */
-#define is_addr_link_local(a) (((a)->s6_addr16[0]) == 0x80FE)
+#define is_addr_link_local(a) (((a)->s6_addr16[0]) == htons(0xFE80))
 
 /*
  * check whether we can compress the IID to 16 bits,
index 7d1874be1df36282ca6c4d0ef3001d05686f335f..786d97aee751e2f2206b9e3b66398bc0995cc645 100644 (file)
@@ -735,6 +735,7 @@ EXPORT_SYMBOL(inet_csk_destroy_sock);
  * tcp/dccp_create_openreq_child().
  */
 void inet_csk_prepare_forced_close(struct sock *sk)
+       __releases(&sk->sk_lock.slock)
 {
        /* sk_clone_lock locked the socket and set refcnt to 2 */
        bh_unlock_sock(sk);
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 f6289bf6f3325edc2c78541eca88e546e5ec97c9..310a3647c83d948949e8c76ef8e89b68def338dd 100644 (file)
@@ -423,7 +423,7 @@ int ip_options_compile(struct net *net,
                                        put_unaligned_be32(midtime, timeptr);
                                        opt->is_changed = 1;
                                }
-                       } else {
+                       } else if ((optptr[3]&0xF) != IPOPT_TS_PRESPEC) {
                                unsigned int overflow = optptr[3]>>4;
                                if (overflow == 15) {
                                        pp_ptr = optptr + 3;
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..e33fe0ab2568ec5a750e846457ff52a6a3395c86 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;
@@ -279,7 +281,8 @@ int ip6_mc_input(struct sk_buff *skb)
         *      IPv6 multicast router mode is now supported ;)
         */
        if (dev_net(skb->dev)->ipv6.devconf_all->mc_forwarding &&
-           !(ipv6_addr_type(&hdr->daddr) & IPV6_ADDR_LINKLOCAL) &&
+           !(ipv6_addr_type(&hdr->daddr) &
+             (IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL)) &&
            likely(!(IP6CB(skb)->flags & IP6SKB_FORWARDED))) {
                /*
                 * Okay, we try to forward - split and duplicate
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 9a5fd3c3e530c5dc82c04ccf04abf0f93b0f3a28..362ba47968e41de822122f9c215e012ba566cd59 100644 (file)
@@ -280,7 +280,7 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
        struct tty_port *port = &self->port;
        DECLARE_WAITQUEUE(wait, current);
        int             retval;
-       int             do_clocal = 0, extra_count = 0;
+       int             do_clocal = 0;
        unsigned long   flags;
 
        IRDA_DEBUG(2, "%s()\n", __func__ );
@@ -289,8 +289,15 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
         * If non-blocking mode is set, or the port is not enabled,
         * then make the check up front and then exit.
         */
-       if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
-               /* nonblock mode is set or port is not enabled */
+       if (test_bit(TTY_IO_ERROR, &tty->flags)) {
+               port->flags |= ASYNC_NORMAL_ACTIVE;
+               return 0;
+       }
+
+       if (filp->f_flags & O_NONBLOCK) {
+               /* nonblock mode is set */
+               if (tty->termios.c_cflag & CBAUD)
+                       tty_port_raise_dtr_rts(port);
                port->flags |= ASYNC_NORMAL_ACTIVE;
                IRDA_DEBUG(1, "%s(), O_NONBLOCK requested!\n", __func__ );
                return 0;
@@ -315,18 +322,16 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
              __FILE__, __LINE__, tty->driver->name, port->count);
 
        spin_lock_irqsave(&port->lock, flags);
-       if (!tty_hung_up_p(filp)) {
-               extra_count = 1;
+       if (!tty_hung_up_p(filp))
                port->count--;
-       }
-       spin_unlock_irqrestore(&port->lock, flags);
        port->blocked_open++;
+       spin_unlock_irqrestore(&port->lock, flags);
 
        while (1) {
                if (tty->termios.c_cflag & CBAUD)
                        tty_port_raise_dtr_rts(port);
 
-               current->state = TASK_INTERRUPTIBLE;
+               set_current_state(TASK_INTERRUPTIBLE);
 
                if (tty_hung_up_p(filp) ||
                    !test_bit(ASYNCB_INITIALIZED, &port->flags)) {
@@ -361,13 +366,11 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
        __set_current_state(TASK_RUNNING);
        remove_wait_queue(&port->open_wait, &wait);
 
-       if (extra_count) {
-               /* ++ is not atomic, so this should be protected - Jean II */
-               spin_lock_irqsave(&port->lock, flags);
+       spin_lock_irqsave(&port->lock, flags);
+       if (!tty_hung_up_p(filp))
                port->count++;
-               spin_unlock_irqrestore(&port->lock, flags);
-       }
        port->blocked_open--;
+       spin_unlock_irqrestore(&port->lock, flags);
 
        IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n",
              __FILE__, __LINE__, tty->driver->name, port->count);
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 556fdafdd1ea3fb6d85b44c2e3efeb600b1839b8..8555f331ea60d4bca67cbe91390ed077f62a091e 100644 (file)
@@ -2201,7 +2201,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, const struct sadb_
                      XFRM_POLICY_BLOCK : XFRM_POLICY_ALLOW);
        xp->priority = pol->sadb_x_policy_priority;
 
-       sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
+       sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1];
        xp->family = pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.saddr);
        if (!xp->family) {
                err = -EINVAL;
@@ -2214,7 +2214,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, const struct sadb_
        if (xp->selector.sport)
                xp->selector.sport_mask = htons(0xffff);
 
-       sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1],
+       sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1];
        pfkey_sadb_addr2xfrm_addr(sa, &xp->selector.daddr);
        xp->selector.prefixlen_d = sa->sadb_address_prefixlen;
 
@@ -2315,7 +2315,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa
 
        memset(&sel, 0, sizeof(sel));
 
-       sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
+       sa = ext_hdrs[SADB_EXT_ADDRESS_SRC-1];
        sel.family = pfkey_sadb_addr2xfrm_addr(sa, &sel.saddr);
        sel.prefixlen_s = sa->sadb_address_prefixlen;
        sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
@@ -2323,7 +2323,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa
        if (sel.sport)
                sel.sport_mask = htons(0xffff);
 
-       sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1],
+       sa = ext_hdrs[SADB_EXT_ADDRESS_DST-1];
        pfkey_sadb_addr2xfrm_addr(sa, &sel.daddr);
        sel.prefixlen_d = sa->sadb_address_prefixlen;
        sel.proto = pfkey_proto_to_xfrm(sa->sadb_address_proto);
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..fb306814576affa7e636fa53353d29ba1e39b668 100644 (file)
@@ -3285,6 +3285,7 @@ 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;
 
@@ -3293,6 +3294,16 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
        if (chanctx_conf) {
                *chandef = chanctx_conf->def;
                ret = 0;
+       } else if (local->open_count > 0 &&
+                  local->open_count == local->monitors &&
+                  sdata->vif.type == NL80211_IFTYPE_MONITOR) {
+               if (local->use_chanctx)
+                       *chandef = local->monitor_chandef;
+               else
+                       cfg80211_chandef_create(chandef,
+                                               local->_oper_channel,
+                                               local->_oper_channel_type);
+               ret = 0;
        }
        rcu_read_unlock();
 
index 2c059e54e88575bf1364a17b9a9bc2f020c5a7a6..baaa8608e52de8d9d504f14a254bb7e6631b5f2e 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) {
@@ -541,6 +541,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
 
                ieee80211_adjust_monitor_flags(sdata, 1);
                ieee80211_configure_filter(local);
+               mutex_lock(&local->mtx);
+               ieee80211_recalc_idle(local);
+               mutex_unlock(&local->mtx);
 
                netif_carrier_on(dev);
                break;
@@ -812,6 +815,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
 
                ieee80211_adjust_monitor_flags(sdata, -1);
                ieee80211_configure_filter(local);
+               mutex_lock(&local->mtx);
+               ieee80211_recalc_idle(local);
+               mutex_unlock(&local->mtx);
                break;
        case NL80211_IFTYPE_P2P_DEVICE:
                /* relies on synchronize_rcu() below */
index 9f6464f3e05f94e0025c4449b4a29e35bc185725..141577412d8407fc8b18ad354a34ad8de105f154 100644 (file)
@@ -647,6 +647,9 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
                our_mcs = (le16_to_cpu(vht_cap.vht_mcs.rx_mcs_map) &
                                                                mask) >> shift;
 
+               if (our_mcs == IEEE80211_VHT_MCS_NOT_SUPPORTED)
+                       continue;
+
                switch (ap_mcs) {
                default:
                        if (our_mcs <= ap_mcs)
@@ -3502,6 +3505,14 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
+       /*
+        * Stop timers before deleting work items, as timers
+        * could race and re-add the work-items. They will be
+        * re-established on connection.
+        */
+       del_timer_sync(&ifmgd->conn_mon_timer);
+       del_timer_sync(&ifmgd->bcn_mon_timer);
+
        /*
         * we need to use atomic bitops for the running bits
         * only because both timers might fire at the same
@@ -3516,13 +3527,9 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
        if (del_timer_sync(&ifmgd->timer))
                set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
 
-       cancel_work_sync(&ifmgd->chswitch_work);
        if (del_timer_sync(&ifmgd->chswitch_timer))
                set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
-
-       /* these will just be re-established on connection */
-       del_timer_sync(&ifmgd->conn_mon_timer);
-       del_timer_sync(&ifmgd->bcn_mon_timer);
+       cancel_work_sync(&ifmgd->chswitch_work);
 }
 
 void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
@@ -4315,6 +4322,17 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
+       /*
+        * Make sure some work items will not run after this,
+        * they will not do anything but might not have been
+        * cancelled when disconnecting.
+        */
+       cancel_work_sync(&ifmgd->monitor_work);
+       cancel_work_sync(&ifmgd->beacon_connection_loss_work);
+       cancel_work_sync(&ifmgd->request_smps_work);
+       cancel_work_sync(&ifmgd->csa_connection_drop_work);
+       cancel_work_sync(&ifmgd->chswitch_work);
+
        mutex_lock(&ifmgd->mtx);
        if (ifmgd->assoc_data)
                ieee80211_destroy_assoc_data(sdata, false);
index de8548bf0a7f27cef20e06077d3c603ad22a7baa..8914d2d2881aab77c5741479d6dbf516db59e3b3 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;
@@ -2724,7 +2745,8 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
                                cpu_to_le16(IEEE80211_FCTL_MOREDATA);
                }
 
-               sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
+               if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+                       sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
                if (!ieee80211_tx_prepare(sdata, &tx, skb))
                        break;
                dev_kfree_skb_any(skb);
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 a9740bd6fe543bc5d93a05296d9c0dd0260c340b..94b4b9853f60488a1aa9b12ff9e96cac3c90d4d2 100644 (file)
@@ -339,6 +339,13 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct,
 {
        const struct nf_conn_help *help;
        const struct nf_conntrack_helper *helper;
+       struct va_format vaf;
+       va_list args;
+
+       va_start(args, fmt);
+
+       vaf.fmt = fmt;
+       vaf.va = &args;
 
        /* Called from the helper function, this call never fails */
        help = nfct_help(ct);
@@ -347,7 +354,9 @@ void nf_ct_helper_log(struct sk_buff *skb, const struct nf_conn *ct,
        helper = rcu_dereference(help->helper);
 
        nf_log_packet(nf_ct_l3num(ct), 0, skb, NULL, NULL, NULL,
-                     "nf_ct_%s: dropping packet: %s ", helper->name, fmt);
+                     "nf_ct_%s: dropping packet: %pV ", helper->name, &vaf);
+
+       va_end(args);
 }
 EXPORT_SYMBOL_GPL(nf_ct_helper_log);
 
index d578ec251712b011be829e01aba8f379fb6babd7..0b1b32cda3072d2867edd82c3154538194f606d6 100644 (file)
@@ -62,11 +62,6 @@ void nfnl_unlock(__u8 subsys_id)
 }
 EXPORT_SYMBOL_GPL(nfnl_unlock);
 
-static struct mutex *nfnl_get_lock(__u8 subsys_id)
-{
-       return &table[subsys_id].mutex;
-}
-
 int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n)
 {
        nfnl_lock(n->subsys_id);
@@ -199,7 +194,7 @@ replay:
                        rcu_read_unlock();
                        nfnl_lock(subsys_id);
                        if (rcu_dereference_protected(table[subsys_id].subsys,
-                               lockdep_is_held(nfnl_get_lock(subsys_id))) != ss ||
+                               lockdep_is_held(&table[subsys_id].mutex)) != ss ||
                            nfnetlink_find_client(type, ss) != nc)
                                err = -EAGAIN;
                        else if (nc->call)
index ba92824086f3c3843c7158c5a5de86fe0db53dc4..3228d7f24eb4107ff717af4323e834af3e680797 100644 (file)
@@ -124,6 +124,9 @@ audit_tg(struct sk_buff *skb, const struct xt_action_param *par)
        const struct xt_audit_info *info = par->targinfo;
        struct audit_buffer *ab;
 
+       if (audit_enabled == 0)
+               goto errout;
+
        ab = audit_log_start(NULL, GFP_ATOMIC, AUDIT_NETFILTER_PKT);
        if (ab == NULL)
                goto errout;
index 847d495cd4de0bee797f994fcaf491ed6efb30ce..8a6c6ea466d874dd34afd2013bef4f777a47db42 100644 (file)
@@ -1189,8 +1189,6 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
        struct netlbl_unlhsh_walk_arg cb_arg;
        u32 skip_bkt = cb->args[0];
        u32 skip_chain = cb->args[1];
-       u32 skip_addr4 = cb->args[2];
-       u32 skip_addr6 = cb->args[3];
        u32 iter_bkt;
        u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0;
        struct netlbl_unlhsh_iface *iface;
@@ -1215,7 +1213,7 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
                                continue;
                        netlbl_af4list_foreach_rcu(addr4,
                                                   &iface->addr4_list) {
-                               if (iter_addr4++ < skip_addr4)
+                               if (iter_addr4++ < cb->args[2])
                                        continue;
                                if (netlbl_unlabel_staticlist_gen(
                                              NLBL_UNLABEL_C_STATICLIST,
@@ -1231,7 +1229,7 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
 #if IS_ENABLED(CONFIG_IPV6)
                        netlbl_af6list_foreach_rcu(addr6,
                                                   &iface->addr6_list) {
-                               if (iter_addr6++ < skip_addr6)
+                               if (iter_addr6++ < cb->args[3])
                                        continue;
                                if (netlbl_unlabel_staticlist_gen(
                                              NLBL_UNLABEL_C_STATICLIST,
@@ -1250,10 +1248,10 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
 
 unlabel_staticlist_return:
        rcu_read_unlock();
-       cb->args[0] = skip_bkt;
-       cb->args[1] = skip_chain;
-       cb->args[2] = skip_addr4;
-       cb->args[3] = skip_addr6;
+       cb->args[0] = iter_bkt;
+       cb->args[1] = iter_chain;
+       cb->args[2] = iter_addr4;
+       cb->args[3] = iter_addr6;
        return skb->len;
 }
 
@@ -1273,12 +1271,9 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
 {
        struct netlbl_unlhsh_walk_arg cb_arg;
        struct netlbl_unlhsh_iface *iface;
-       u32 skip_addr4 = cb->args[0];
-       u32 skip_addr6 = cb->args[1];
-       u32 iter_addr4 = 0;
+       u32 iter_addr4 = 0, iter_addr6 = 0;
        struct netlbl_af4list *addr4;
 #if IS_ENABLED(CONFIG_IPV6)
-       u32 iter_addr6 = 0;
        struct netlbl_af6list *addr6;
 #endif
 
@@ -1292,7 +1287,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
                goto unlabel_staticlistdef_return;
 
        netlbl_af4list_foreach_rcu(addr4, &iface->addr4_list) {
-               if (iter_addr4++ < skip_addr4)
+               if (iter_addr4++ < cb->args[0])
                        continue;
                if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
                                              iface,
@@ -1305,7 +1300,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
        }
 #if IS_ENABLED(CONFIG_IPV6)
        netlbl_af6list_foreach_rcu(addr6, &iface->addr6_list) {
-               if (iter_addr6++ < skip_addr6)
+               if (iter_addr6++ < cb->args[1])
                        continue;
                if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
                                              iface,
@@ -1320,8 +1315,8 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
 
 unlabel_staticlistdef_return:
        rcu_read_unlock();
-       cb->args[0] = skip_addr4;
-       cb->args[1] = skip_addr6;
+       cb->args[0] = iter_addr4;
+       cb->args[1] = iter_addr6;
        return skb->len;
 }
 
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 7be790d60b900d30053256b2f6cb1753056b0ba3..73be187d389ed044c886d22e4960905283d9de87 100644 (file)
@@ -87,6 +87,7 @@ void rds_stats_info_copy(struct rds_info_iterator *iter,
        for (i = 0; i < nr; i++) {
                BUG_ON(strlen(names[i]) >= sizeof(ctr.name));
                strncpy(ctr.name, names[i], sizeof(ctr.name) - 1);
+               ctr.name[sizeof(ctr.name) - 1] = '\0';
                ctr.value = values[i];
 
                rds_info_copy(iter, &ctr, sizeof(ctr));
index e9a77f621c3dfc87d49ed534003a20ceb1d98f8d..d51852bba01c981c9f9834dad82cfbcfec904508 100644 (file)
@@ -298,6 +298,10 @@ static void qfq_update_agg(struct qfq_sched *q, struct qfq_aggregate *agg,
            new_num_classes == q->max_agg_classes - 1) /* agg no more full */
                hlist_add_head(&agg->nonfull_next, &q->nonfull_aggs);
 
+       /* The next assignment may let
+        * agg->initial_budget > agg->budgetmax
+        * hold, we will take it into account in charge_actual_service().
+        */
        agg->budgetmax = new_num_classes * agg->lmax;
        new_agg_weight = agg->class_weight * new_num_classes;
        agg->inv_w = ONE_FP/new_agg_weight;
@@ -817,7 +821,7 @@ static void qfq_make_eligible(struct qfq_sched *q)
        unsigned long old_vslot = q->oldV >> q->min_slot_shift;
 
        if (vslot != old_vslot) {
-               unsigned long mask = (1UL << fls(vslot ^ old_vslot)) - 1;
+               unsigned long mask = (1ULL << fls(vslot ^ old_vslot)) - 1;
                qfq_move_groups(q, mask, IR, ER);
                qfq_move_groups(q, mask, IB, EB);
        }
@@ -988,12 +992,23 @@ static inline struct sk_buff *qfq_peek_skb(struct qfq_aggregate *agg,
 /* Update F according to the actual service received by the aggregate. */
 static inline void charge_actual_service(struct qfq_aggregate *agg)
 {
-       /* compute the service received by the aggregate */
-       u32 service_received = agg->initial_budget - agg->budget;
+       /* Compute the service received by the aggregate, taking into
+        * account that, after decreasing the number of classes in
+        * agg, it may happen that
+        * agg->initial_budget - agg->budget > agg->bugdetmax
+        */
+       u32 service_received = min(agg->budgetmax,
+                                  agg->initial_budget - agg->budget);
 
        agg->F = agg->S + (u64)service_received * agg->inv_w;
 }
 
+static inline void qfq_update_agg_ts(struct qfq_sched *q,
+                                    struct qfq_aggregate *agg,
+                                    enum update_reason reason);
+
+static void qfq_schedule_agg(struct qfq_sched *q, struct qfq_aggregate *agg);
+
 static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
 {
        struct qfq_sched *q = qdisc_priv(sch);
@@ -1021,7 +1036,7 @@ static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
                in_serv_agg->initial_budget = in_serv_agg->budget =
                        in_serv_agg->budgetmax;
 
-               if (!list_empty(&in_serv_agg->active))
+               if (!list_empty(&in_serv_agg->active)) {
                        /*
                         * Still active: reschedule for
                         * service. Possible optimization: if no other
@@ -1032,8 +1047,9 @@ static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
                         * handle it, we would need to maintain an
                         * extra num_active_aggs field.
                        */
-                       qfq_activate_agg(q, in_serv_agg, requeue);
-               else if (sch->q.qlen == 0) { /* no aggregate to serve */
+                       qfq_update_agg_ts(q, in_serv_agg, requeue);
+                       qfq_schedule_agg(q, in_serv_agg);
+               } else if (sch->q.qlen == 0) { /* no aggregate to serve */
                        q->in_serv_agg = NULL;
                        return NULL;
                }
@@ -1052,7 +1068,15 @@ static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
        qdisc_bstats_update(sch, skb);
 
        agg_dequeue(in_serv_agg, cl, len);
-       in_serv_agg->budget -= len;
+       /* If lmax is lowered, through qfq_change_class, for a class
+        * owning pending packets with larger size than the new value
+        * of lmax, then the following condition may hold.
+        */
+       if (unlikely(in_serv_agg->budget < len))
+               in_serv_agg->budget = 0;
+       else
+               in_serv_agg->budget -= len;
+
        q->V += (u64)len * IWSUM;
        pr_debug("qfq dequeue: len %u F %lld now %lld\n",
                 len, (unsigned long long) in_serv_agg->F,
@@ -1217,17 +1241,11 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        cl->deficit = agg->lmax;
        list_add_tail(&cl->alist, &agg->active);
 
-       if (list_first_entry(&agg->active, struct qfq_class, alist) != cl)
-               return err; /* aggregate was not empty, nothing else to do */
+       if (list_first_entry(&agg->active, struct qfq_class, alist) != cl ||
+           q->in_serv_agg == agg)
+               return err; /* non-empty or in service, nothing else to do */
 
-       /* recharge budget */
-       agg->initial_budget = agg->budget = agg->budgetmax;
-
-       qfq_update_agg_ts(q, agg, enqueue);
-       if (q->in_serv_agg == NULL)
-               q->in_serv_agg = agg;
-       else if (agg != q->in_serv_agg)
-               qfq_schedule_agg(q, agg);
+       qfq_activate_agg(q, agg, enqueue);
 
        return err;
 }
@@ -1261,7 +1279,8 @@ static void qfq_schedule_agg(struct qfq_sched *q, struct qfq_aggregate *agg)
                /* group was surely ineligible, remove */
                __clear_bit(grp->index, &q->bitmaps[IR]);
                __clear_bit(grp->index, &q->bitmaps[IB]);
-       } else if (!q->bitmaps[ER] && qfq_gt(roundedS, q->V))
+       } else if (!q->bitmaps[ER] && qfq_gt(roundedS, q->V) &&
+                  q->in_serv_agg == NULL)
                q->V = roundedS;
 
        grp->S = roundedS;
@@ -1284,8 +1303,15 @@ skip_update:
 static void qfq_activate_agg(struct qfq_sched *q, struct qfq_aggregate *agg,
                             enum update_reason reason)
 {
+       agg->initial_budget = agg->budget = agg->budgetmax; /* recharge budg. */
+
        qfq_update_agg_ts(q, agg, reason);
-       qfq_schedule_agg(q, agg);
+       if (q->in_serv_agg == NULL) { /* no aggr. in service or scheduled */
+               q->in_serv_agg = agg; /* start serving this aggregate */
+                /* update V: to be in service, agg must be eligible */
+               q->oldV = q->V = agg->S;
+       } else if (agg != q->in_serv_agg)
+               qfq_schedule_agg(q, agg);
 }
 
 static void qfq_slot_remove(struct qfq_sched *q, struct qfq_group *grp,
@@ -1357,8 +1383,6 @@ static void qfq_deactivate_agg(struct qfq_sched *q, struct qfq_aggregate *agg)
                        __set_bit(grp->index, &q->bitmaps[s]);
                }
        }
-
-       qfq_update_eligible(q);
 }
 
 static void qfq_qlen_notify(struct Qdisc *sch, unsigned long arg)
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 f7d34e7b6f818ba52bec46795b83062cbdf5a71e..5ead60550895f848ba2348bba3bbbfc50ddea7ea 100644 (file)
@@ -447,17 +447,21 @@ static int rsc_parse(struct cache_detail *cd,
        else {
                int N, i;
 
+               /*
+                * NOTE: we skip uid_valid()/gid_valid() checks here:
+                * instead, * -1 id's are later mapped to the
+                * (export-specific) anonymous id by nfsd_setuser.
+                *
+                * (But supplementary gid's get no such special
+                * treatment so are checked for validity here.)
+                */
                /* uid */
                rsci.cred.cr_uid = make_kuid(&init_user_ns, id);
-               if (!uid_valid(rsci.cred.cr_uid))
-                       goto out;
 
                /* gid */
                if (get_int(&mesg, &id))
                        goto out;
                rsci.cred.cr_gid = make_kgid(&init_user_ns, id);
-               if (!gid_valid(rsci.cred.cr_gid))
-                       goto out;
 
                /* number of additional gid's */
                if (get_int(&mesg, &N))
index 25d58e766014bf751ba404cac60893b2cfc5ecf9..1d3c5144a331b5d9b4966be701dfb960ad945456 100644 (file)
@@ -986,8 +986,10 @@ static int cache_open(struct inode *inode, struct file *filp,
        nonseekable_open(inode, filp);
        if (filp->f_mode & FMODE_READ) {
                rp = kmalloc(sizeof(*rp), GFP_KERNEL);
-               if (!rp)
+               if (!rp) {
+                       module_put(cd->owner);
                        return -ENOMEM;
+               }
                rp->offset = 0;
                rp->q.reader = 1;
                atomic_inc(&cd->readers);
index 7b9b40224a27768bb87014fdaa89d82413e7496f..a9129f8d70706f5e33ac8f39cb3ea8a3e5825ca2 100644 (file)
@@ -1174,6 +1174,8 @@ static struct file_system_type rpc_pipe_fs_type = {
        .mount          = rpc_mount,
        .kill_sb        = rpc_kill_sb,
 };
+MODULE_ALIAS_FS("rpc_pipefs");
+MODULE_ALIAS("rpc_pipefs");
 
 static void
 init_once(void *foo)
@@ -1218,6 +1220,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 726e702b7a2935265b5f0c70378229f26c6f5c38..9c2825827decfb1a0b6fd2f4a80c0cd66fe36eb7 100644 (file)
@@ -849,6 +849,14 @@ static void xs_tcp_close(struct rpc_xprt *xprt)
                xs_tcp_shutdown(xprt);
 }
 
+static void xs_local_destroy(struct rpc_xprt *xprt)
+{
+       xs_close(xprt);
+       xs_free_peer_addresses(xprt);
+       xprt_free(xprt);
+       module_put(THIS_MODULE);
+}
+
 /**
  * xs_destroy - prepare to shutdown a transport
  * @xprt: doomed transport
@@ -862,10 +870,7 @@ static void xs_destroy(struct rpc_xprt *xprt)
 
        cancel_delayed_work_sync(&transport->connect_worker);
 
-       xs_close(xprt);
-       xs_free_peer_addresses(xprt);
-       xprt_free(xprt);
-       module_put(THIS_MODULE);
+       xs_local_destroy(xprt);
 }
 
 static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
@@ -2482,7 +2487,7 @@ static struct rpc_xprt_ops xs_local_ops = {
        .send_request           = xs_local_send_request,
        .set_retrans_timeout    = xprt_set_retrans_timeout_def,
        .close                  = xs_close,
-       .destroy                = xs_destroy,
+       .destroy                = xs_local_destroy,
        .print_stats            = xs_local_print_stats,
 };
 
index 5ffff039b0174eefb8f3967dc6f5307ea7cb2f8c..ea4155fe97334f91794dbb7a55f0dab28219c2a3 100644 (file)
@@ -367,8 +367,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
        rdev->wiphy.rts_threshold = (u32) -1;
        rdev->wiphy.coverage_class = 0;
 
-       rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH |
-                              NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
+       rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH;
 
        return &rdev->wiphy;
 }
index 35545ccc30fd0079acb1e848c4ecaff0cdc8b371..d44ab216c0ecd8b01d4386edf62cd07c3f2071db 100644 (file)
@@ -554,27 +554,8 @@ 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_NO_HT40MINUS) &&
-           nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
-               goto nla_put_failure;
-       if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
-           nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
-               goto nla_put_failure;
-       if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
-           nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
-               goto nla_put_failure;
-       if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
-           nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
+       if ((chan->flags & IEEE80211_CHAN_RADAR) &&
+           nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
                goto nla_put_failure;
 
        if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
@@ -900,9 +881,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 +892,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 +1266,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
@@ -1365,15 +1298,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
                        dev->wiphy.max_acl_mac_addrs))
                goto nla_put_failure;
 
-       if (dev->wiphy.extended_capabilities &&
-           (nla_put(msg, NL80211_ATTR_EXT_CAPA,
-                    dev->wiphy.extended_capabilities_len,
-                    dev->wiphy.extended_capabilities) ||
-            nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
-                    dev->wiphy.extended_capabilities_len,
-                    dev->wiphy.extended_capabilities_mask)))
-               goto nla_put_failure;
-
        return genlmsg_end(msg, hdr);
 
  nla_put_failure:
@@ -1383,7 +1307,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
 
 static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
 {
-       int idx = 0;
+       int idx = 0, ret;
        int start = cb->args[0];
        struct cfg80211_registered_device *dev;
 
@@ -1393,9 +1317,29 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
                        continue;
                if (++idx <= start)
                        continue;
-               if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid,
-                                      cb->nlh->nlmsg_seq, NLM_F_MULTI,
-                                      dev) < 0) {
+               ret = nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid,
+                                        cb->nlh->nlmsg_seq, NLM_F_MULTI,
+                                        dev);
+               if (ret < 0) {
+                       /*
+                        * If sending the wiphy data didn't fit (ENOBUFS or
+                        * EMSGSIZE returned), this SKB is still empty (so
+                        * it's not too big because another wiphy dataset is
+                        * already in the skb) and we've not tried to adjust
+                        * the dump allocation yet ... then adjust the alloc
+                        * size to be bigger, and return 1 but with the empty
+                        * skb. This results in an empty message being RX'ed
+                        * in userspace, but that is ignored.
+                        *
+                        * We can then retry with the larger buffer.
+                        */
+                       if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
+                           !skb->len &&
+                           cb->min_dump_alloc < 4096) {
+                               cb->min_dump_alloc = 4096;
+                               mutex_unlock(&cfg80211_mutex);
+                               return 1;
+                       }
                        idx--;
                        break;
                }
@@ -1412,7 +1356,7 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
        struct sk_buff *msg;
        struct cfg80211_registered_device *dev = info->user_ptr[0];
 
-       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+       msg = nlmsg_new(4096, GFP_KERNEL);
        if (!msg)
                return -ENOMEM;
 
index 25f216a841d5fcd734c4b234541aed998b561852..477d137c0557b8b70571d9e6e0873e2af221d53b 100644 (file)
@@ -14,7 +14,7 @@ kbuild-file := $(srctree)/$(obj)/Kbuild
 include $(kbuild-file)
 
 # called may set destination dir (when installing to asm/)
-_dst := $(or $(destination-y),$(dst),$(obj))
+_dst := $(if $(destination-y),$(destination-y),$(if $(dst),$(dst),$(obj)))
 
 old-kbuild-file := $(srctree)/$(subst uapi/,,$(obj))/Kbuild
 ifneq ($(wildcard $(old-kbuild-file)),)
@@ -48,13 +48,14 @@ all-files     := $(header-y) $(genhdr-y) $(wrapper-files)
 output-files  := $(addprefix $(installdir)/, $(all-files))
 
 input-files   := $(foreach hdr, $(header-y), \
-                  $(or \
+                  $(if $(wildcard $(srcdir)/$(hdr)), \
                        $(wildcard $(srcdir)/$(hdr)), \
-                       $(wildcard $(oldsrcdir)/$(hdr)), \
-                       $(error Missing UAPI file $(srcdir)/$(hdr)) \
+                       $(if $(wildcard $(oldsrcdir)/$(hdr)), \
+                               $(wildcard $(oldsrcdir)/$(hdr)), \
+                               $(error Missing UAPI file $(srcdir)/$(hdr))) \
                   )) \
                 $(foreach hdr, $(genhdr-y), \
-                  $(or \
+                  $(if $(wildcard $(gendir)/$(hdr)), \
                        $(wildcard $(gendir)/$(hdr)), \
                        $(error Missing generated UAPI file $(gendir)/$(hdr)) \
                   ))
index 1c261763f4799180432f2162a096579007243203..d65fa7fa29ba1a53b1ef4fb6d76c7aeafb7da65a 100644 (file)
@@ -40,12 +40,12 @@ static long compat_keyctl_instantiate_key_iov(
                                           ARRAY_SIZE(iovstack),
                                           iovstack, &iov);
        if (ret < 0)
-               return ret;
+               goto err;
        if (ret == 0)
                goto no_payload_free;
 
        ret = keyctl_instantiate_key_common(id, iov, ioc, ret, ringid);
-
+err:
        if (iov != iovstack)
                kfree(iov);
        return ret;
index 58dfe089094793030f56fdb895f6621e403e4157..42defae1e161632e93b13b8194af1a30a09f2492 100644 (file)
@@ -57,7 +57,7 @@ int install_user_keyrings(void)
 
        kenter("%p{%u}", user, uid);
 
-       if (user->uid_keyring) {
+       if (user->uid_keyring && user->session_keyring) {
                kleave(" = 0 [exist]");
                return 0;
        }
@@ -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 160b1bd0cd62262931896573953e990736e4da52..24d44b2f61acda72453e5be78958aae15b8afccf 100644 (file)
@@ -290,10 +290,10 @@ int snd_seq_timer_open(struct snd_seq_queue *q)
                        tid.device = SNDRV_TIMER_GLOBAL_SYSTEM;
                        err = snd_timer_open(&t, str, &tid, q->queue);
                }
-               if (err < 0) {
-                       snd_printk(KERN_ERR "seq fatal error: cannot create timer (%i)\n", err);
-                       return err;
-               }
+       }
+       if (err < 0) {
+               snd_printk(KERN_ERR "seq fatal error: cannot create timer (%i)\n", err);
+               return err;
        }
        t->callback = snd_seq_timer_interrupt;
        t->callback_data = q;
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 30bcfe470f8310fa7fa72cc1ddcf7ab4ba6a794c..4ff60a6427d9d8d3ea7cf095bc2766f2d49955fc 100644 (file)
@@ -545,6 +545,9 @@ static void seq_chn_common_event(unsigned char *event_rec)
                case MIDI_PGM_CHANGE:
                        if (seq_mode == SEQ_2)
                        {
+                               if (chn > 15)
+                                       break;
+
                                synth_devs[dev]->chn_info[chn].pgm_num = p1;
                                if ((int) dev >= num_synths)
                                        synth_devs[dev]->set_instr(dev, chn, p1);
@@ -596,6 +599,9 @@ static void seq_chn_common_event(unsigned char *event_rec)
                case MIDI_PITCH_BEND:
                        if (seq_mode == SEQ_2)
                        {
+                               if (chn > 15)
+                                       break;
+
                                synth_devs[dev]->chn_info[chn].bender_value = w14;
 
                                if ((int) dev < num_synths)
index 3536b076b529ab8c25edf1292a62e713e841b800..0aabfedeecbae241b6ab4e182713a3d2e85b82e8 100644 (file)
@@ -2549,7 +2549,7 @@ static int snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
 
 static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
 {
-       struct snd_card *card = asihpi->card;
+       struct snd_card *card;
        unsigned int idx = 0;
        unsigned int subindex = 0;
        int err;
@@ -2557,6 +2557,7 @@ static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
 
        if (snd_BUG_ON(!asihpi))
                return -EINVAL;
+       card = asihpi->card;
        strcpy(card->mixername, "Asihpi Mixer");
 
        err =
index 04b57383e8cbcb89212e2d63960242653e774b21..a9ebcf9e3710ece320bd656bd45e8ff615b0eb75 100644 (file)
@@ -494,7 +494,7 @@ static unsigned int get_num_conns(struct hda_codec *codec, hda_nid_t nid)
 
 int snd_hda_get_num_raw_conns(struct hda_codec *codec, hda_nid_t nid)
 {
-       return get_num_conns(codec, nid) & AC_CLIST_LENGTH;
+       return snd_hda_get_raw_connections(codec, nid, NULL, 0);
 }
 
 /**
@@ -517,9 +517,6 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
        hda_nid_t prev_nid;
        int null_count = 0;
 
-       if (snd_BUG_ON(!conn_list || max_conns <= 0))
-               return -EINVAL;
-
        parm = get_num_conns(codec, nid);
        if (!parm)
                return 0;
@@ -545,7 +542,8 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
                                          AC_VERB_GET_CONNECT_LIST, 0);
                if (parm == -1 && codec->bus->rirb_error)
                        return -EIO;
-               conn_list[0] = parm & mask;
+               if (conn_list)
+                       conn_list[0] = parm & mask;
                return 1;
        }
 
@@ -580,14 +578,20 @@ int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
                                continue;
                        }
                        for (n = prev_nid + 1; n <= val; n++) {
+                               if (conn_list) {
+                                       if (conns >= max_conns)
+                                               return -ENOSPC;
+                                       conn_list[conns] = n;
+                               }
+                               conns++;
+                       }
+               } else {
+                       if (conn_list) {
                                if (conns >= max_conns)
                                        return -ENOSPC;
-                               conn_list[conns++] = n;
+                               conn_list[conns] = val;
                        }
-               } else {
-                       if (conns >= max_conns)
-                               return -ENOSPC;
-                       conn_list[conns++] = val;
+                       conns++;
                }
                prev_nid = val;
        }
@@ -3334,6 +3338,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 +3437,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..0792b5725f9c5e501886556ce68f1c383aef1460 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;
        }
@@ -3235,7 +3239,7 @@ static int ca0132_set_vipsource(struct hda_codec *codec, int val)
        struct ca0132_spec *spec = codec->spec;
        unsigned int tmp;
 
-       if (!dspload_is_loaded(codec))
+       if (spec->dsp_state != DSP_DOWNLOADED)
                return 0;
 
        /* if CrystalVoice if off, vipsource should be 0 */
@@ -4263,11 +4267,12 @@ static void ca0132_refresh_widget_caps(struct hda_codec *codec)
  */
 static void ca0132_setup_defaults(struct hda_codec *codec)
 {
+       struct ca0132_spec *spec = codec->spec;
        unsigned int tmp;
        int num_fx;
        int idx, i;
 
-       if (!dspload_is_loaded(codec))
+       if (spec->dsp_state != DSP_DOWNLOADED)
                return;
 
        /* out, in effects + voicefx */
@@ -4347,12 +4352,16 @@ static bool ca0132_download_dsp_images(struct hda_codec *codec)
                return false;
 
        dsp_os_image = (struct dsp_image_seg *)(fw_entry->data);
-       dspload_image(codec, dsp_os_image, 0, 0, true, 0);
+       if (dspload_image(codec, dsp_os_image, 0, 0, true, 0)) {
+               pr_err("ca0132 dspload_image failed.\n");
+               goto exit_download;
+       }
+
        dsp_loaded = dspload_wait_loaded(codec);
 
+exit_download:
        release_firmware(fw_entry);
 
-
        return dsp_loaded;
 }
 
@@ -4363,16 +4372,13 @@ static void ca0132_download_dsp(struct hda_codec *codec)
 #ifndef CONFIG_SND_HDA_CODEC_CA0132_DSP
        return; /* NOP */
 #endif
-       spec->dsp_state = DSP_DOWNLOAD_INIT;
 
-       if (spec->dsp_state == DSP_DOWNLOAD_INIT) {
-               chipio_enable_clocks(codec);
-               spec->dsp_state = DSP_DOWNLOADING;
-               if (!ca0132_download_dsp_images(codec))
-                       spec->dsp_state = DSP_DOWNLOAD_FAILED;
-               else
-                       spec->dsp_state = DSP_DOWNLOADED;
-       }
+       chipio_enable_clocks(codec);
+       spec->dsp_state = DSP_DOWNLOADING;
+       if (!ca0132_download_dsp_images(codec))
+               spec->dsp_state = DSP_DOWNLOAD_FAILED;
+       else
+               spec->dsp_state = DSP_DOWNLOADED;
 
        if (spec->dsp_state == DSP_DOWNLOADED)
                ca0132_set_dsp_msr(codec, true);
index 72ebb8a36b135938593db795d255b27479a5231f..60d08f669f0c1dec9c4a165437f466dec73071bb 100644 (file)
@@ -506,6 +506,8 @@ static int patch_cs420x(struct hda_codec *codec)
        if (!spec)
                return -ENOMEM;
 
+       spec->gen.automute_hook = cs_automute;
+
        snd_hda_pick_fixup(codec, cs420x_models, cs420x_fixup_tbl,
                           cs420x_fixups);
        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
@@ -893,6 +895,8 @@ static int patch_cs4210(struct hda_codec *codec)
        if (!spec)
                return -ENOMEM;
 
+       spec->gen.automute_hook = cs_automute;
+
        snd_hda_pick_fixup(codec, cs421x_models, cs421x_fixup_tbl,
                           cs421x_fixups);
        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
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 83d5335ac348ee2c3b7a3f7e243f7d5ad8096045..dafe04ae8c72b6ba711d7f8dce4ac7878552b883 100644 (file)
@@ -815,6 +815,29 @@ static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity)
        return 0;
 }
 
+/* check whether a built-in speaker is included in parsed pins */
+static bool has_builtin_speaker(struct hda_codec *codec)
+{
+       struct sigmatel_spec *spec = codec->spec;
+       hda_nid_t *nid_pin;
+       int nids, i;
+
+       if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) {
+               nid_pin = spec->gen.autocfg.line_out_pins;
+               nids = spec->gen.autocfg.line_outs;
+       } else {
+               nid_pin = spec->gen.autocfg.speaker_pins;
+               nids = spec->gen.autocfg.speaker_outs;
+       }
+
+       for (i = 0; i < nids; i++) {
+               unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid_pin[i]);
+               if (snd_hda_get_input_pin_attr(def_conf) == INPUT_PIN_ATTR_INT)
+                       return true;
+       }
+       return false;
+}
+
 /*
  * PC beep controls
  */
@@ -3890,6 +3913,12 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
                return err;
        }
 
+       /* Don't GPIO-mute speakers if there are no internal speakers, because
+        * the GPIO might be necessary for Headphone
+        */
+       if (spec->eapd_switch && !has_builtin_speaker(codec))
+               spec->eapd_switch = 0;
+
        codec->proc_widget_hook = stac92hd7x_proc_hook;
 
        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
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 803953a9bff338056795c888cecc9d7fb9c6daa2..2da8ad75fd96c7c0245dfca05c9997e5c3d355a1 100644 (file)
@@ -243,6 +243,21 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
                struct usb_interface_assoc_descriptor *assoc =
                        usb_ifnum_to_if(dev, ctrlif)->intf_assoc;
 
+               if (!assoc) {
+                       /*
+                        * Firmware writers cannot count to three.  So to find
+                        * the IAD on the NuForce UDH-100, also check the next
+                        * interface.
+                        */
+                       struct usb_interface *iface =
+                               usb_ifnum_to_if(dev, ctrlif + 1);
+                       if (iface &&
+                           iface->intf_assoc &&
+                           iface->intf_assoc->bFunctionClass == USB_CLASS_AUDIO &&
+                           iface->intf_assoc->bFunctionProtocol == UAC_VERSION_2)
+                               assoc = iface->intf_assoc;
+               }
+
                if (!assoc) {
                        snd_printk(KERN_ERR "Audio class v2 interfaces need an interface association\n");
                        return -EINVAL;
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
index 8674b9ec14f69882f2e64e689581284bdfeced4b..fe1e66b6ef40bbb1e490edcf2476645d81b66d3f 100644 (file)
@@ -38,7 +38,7 @@
 #include <unistd.h>
 #include <tools/le_byteshift.h>
 
-#include "../../include/linux/usb/functionfs.h"
+#include "../../include/uapi/linux/usb/functionfs.h"
 
 
 /******************** Little Endian Handling ********************************/