]> rtime.felk.cvut.cz Git - mcf548x/linux.git/commitdiff
Merge branches 'x86-fixes-for-linus' and 'perf-fixes-for-linus' of git://git.kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 19 Dec 2010 18:44:54 +0000 (10:44 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 19 Dec 2010 18:44:54 +0000 (10:44 -0800)
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86-32: Make sure we can map all of lowmem if we need to
  x86, vt-d: Handle previous faults after enabling fault handling
  x86: Enable the intr-remap fault handling after local APIC setup
  x86, vt-d: Fix the vt-d fault handling irq migration in the x2apic mode
  x86, vt-d: Quirk for masking vtd spec errors to platform error handling logic
  x86, xsave: Use alloc_bootmem_align() instead of alloc_bootmem()
  bootmem: Add alloc_bootmem_align()
  x86, gcc-4.6: Use gcc -m options when building vdso
  x86: HPET: Chose a paranoid safe value for the ETIME check
  x86: io_apic: Avoid unused variable warning when CONFIG_GENERIC_PENDING_IRQ=n

* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  perf: Fix off by one in perf_swevent_init()
  perf: Fix duplicate events with multiple-pmu vs software events
  ftrace: Have recordmcount honor endianness in fn_ELF_R_INFO
  scripts/tags.sh: Add magic for trace-events
  tracing: Fix panic when lseek() called on "trace" opened for writing

393 files changed:
Documentation/filesystems/Locking
Documentation/filesystems/vfs.txt
Documentation/kernel-parameters.txt
Documentation/power/runtime_pm.txt
MAINTAINERS
Makefile
arch/arm/Kconfig
arch/arm/mach-at91/Makefile
arch/arm/mach-at91/board-pcontrol-g20.c
arch/arm/mach-at91/board-stamp9g20.c
arch/arm/mach-at91/clock.c
arch/arm/mach-at91/include/mach/stamp9g20.h [new file with mode: 0644]
arch/arm/mach-mmp/mmp2.c
arch/arm/mach-omap2/board-zoom-peripherals.c
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/pm-debug.c
arch/arm/mach-omap2/pm24xx.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/prcm-common.h
arch/arm/mach-pxa/palmtx.c
arch/arm/mm/cache-v6.S
arch/arm/mm/cache-v7.S
arch/arm/mm/proc-macros.S
arch/arm/plat-omap/counter_32k.c
arch/arm/plat-omap/sram.c
arch/arm/tools/mach-types
arch/mips/Kconfig
arch/mips/alchemy/common/platform.c
arch/mips/alchemy/devboards/prom.c
arch/mips/ar7/clock.c
arch/mips/ar7/time.c
arch/mips/bcm47xx/setup.c
arch/mips/include/asm/cpu.h
arch/mips/include/asm/elf.h
arch/mips/include/asm/io.h
arch/mips/include/asm/mach-ar7/ar7.h
arch/mips/include/asm/mach-bcm47xx/nvram.h
arch/mips/jz4740/board-qi_lb60.c
arch/mips/jz4740/platform.c
arch/mips/jz4740/prom.c
arch/mips/kernel/cevt-r4k.c
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/linux32.c
arch/mips/kernel/process.c
arch/mips/kernel/prom.c
arch/mips/kernel/smp-mt.c
arch/mips/kernel/traps.c
arch/mips/kernel/vpe.c
arch/mips/lib/memset.S
arch/mips/loongson/common/env.c
arch/mips/math-emu/cp1emu.c
arch/mips/mm/dma-default.c
arch/mips/mm/sc-mips.c
arch/mips/pmc-sierra/yosemite/py-console.c
arch/mips/sibyte/swarm/setup.c
arch/sh/Kconfig
arch/sh/include/asm/unistd_32.h
arch/sh/kernel/syscalls_32.S
arch/sparc/include/asm/openprom.h
arch/sparc/include/asm/oplib_32.h
arch/sparc/include/asm/oplib_64.h
arch/sparc/kernel/leon_kernel.c
arch/sparc/prom/Makefile
arch/sparc/prom/console_32.c
arch/sparc/prom/console_64.c
arch/sparc/prom/devops_32.c [deleted file]
arch/sparc/prom/devops_64.c [deleted file]
arch/sparc/prom/misc_64.c
arch/sparc/prom/printf.c
arch/sparc/prom/tree_32.c
arch/sparc/prom/tree_64.c
arch/tile/include/asm/signal.h
arch/tile/kernel/compat_signal.c
arch/tile/kernel/intvec_32.S
arch/tile/kernel/process.c
arch/tile/kernel/signal.c
arch/x86/crypto/ghash-clmulni-intel_glue.c
arch/x86/include/asm/e820.h
arch/x86/include/asm/kvm_host.h
arch/x86/kernel/Makefile
arch/x86/kernel/head_32.S
arch/x86/kernel/resource.c [new file with mode: 0644]
arch/x86/kernel/setup.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/kvm/x86.h
arch/x86/lguest/boot.c
arch/x86/lguest/i386_head.S
arch/x86/pci/i386.c
block/bsg.c
drivers/acpi/ac.c
drivers/acpi/apei/erst.c
drivers/acpi/apei/hest.c
drivers/acpi/battery.c
drivers/acpi/ec.c
drivers/acpi/osl.c
drivers/acpi/power.c
drivers/acpi/processor_thermal.c
drivers/acpi/sleep.c
drivers/atm/adummy.c
drivers/atm/ambassador.c
drivers/atm/atmtcp.c
drivers/atm/eni.c
drivers/atm/firestream.c
drivers/atm/fore200e.c
drivers/atm/he.c
drivers/atm/horizon.c
drivers/atm/idt77252.c
drivers/atm/iphase.c
drivers/atm/lanai.c
drivers/atm/nicstar.c
drivers/atm/solos-pci.c
drivers/atm/zatm.c
drivers/block/xen-blkfront.c
drivers/bluetooth/ath3k.c
drivers/bluetooth/btusb.c
drivers/connector/connector.c
drivers/dma/Makefile
drivers/dma/at_hdmac.c
drivers/dma/fsldma.c
drivers/dma/fsldma.h
drivers/dma/imx-dma.c
drivers/dma/imx-sdma.c
drivers/dma/intel_mid_dma.c
drivers/dma/ioat/Makefile
drivers/dma/pch_dma.c
drivers/dma/ppc4xx/adma.c
drivers/edac/amd64_edac.c
drivers/edac/edac_core.h
drivers/edac/edac_mc.c
drivers/firewire/ohci.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/radeon/r600.c
drivers/hwmon/adm1026.c
drivers/hwmon/it87.c
drivers/hwmon/ltc4215.c
drivers/i2c/busses/i2c-intel-mid.c
drivers/idle/intel_idle.c
drivers/infiniband/core/uverbs_cmd.c
drivers/input/evdev.c
drivers/input/tablet/wacom_wac.c
drivers/md/md.c
drivers/md/raid10.c
drivers/media/radio/radio-aimslab.c
drivers/media/radio/radio-aztech.c
drivers/media/radio/radio-cadet.c
drivers/media/radio/radio-gemtek-pci.c
drivers/media/radio/radio-gemtek.c
drivers/media/radio/radio-maestro.c
drivers/media/radio/radio-maxiradio.c
drivers/media/radio/radio-miropcm20.c
drivers/media/radio/radio-rtrack2.c
drivers/media/radio/radio-sf16fmi.c
drivers/media/radio/radio-sf16fmr2.c
drivers/media/radio/radio-si4713.c
drivers/media/radio/radio-tea5764.c
drivers/media/radio/radio-terratec.c
drivers/media/radio/radio-timb.c
drivers/media/radio/radio-trust.c
drivers/media/radio/radio-typhoon.c
drivers/media/radio/radio-zoltrix.c
drivers/media/video/arv.c
drivers/media/video/bw-qcam.c
drivers/media/video/c-qcam.c
drivers/media/video/cafe_ccic.c
drivers/media/video/cx18/cx18-alsa-pcm.c
drivers/media/video/cx18/cx18-streams.c
drivers/media/video/et61x251/et61x251_core.c
drivers/media/video/meye.c
drivers/media/video/pms.c
drivers/media/video/sh_vou.c
drivers/media/video/sn9c102/sn9c102_core.c
drivers/media/video/uvc/uvc_ctrl.c
drivers/media/video/uvc/uvc_queue.c
drivers/media/video/uvc/uvc_v4l2.c
drivers/media/video/uvc/uvc_video.c
drivers/media/video/uvc/uvcvideo.h
drivers/media/video/v4l2-dev.c
drivers/media/video/v4l2-device.c
drivers/media/video/w9966.c
drivers/mtd/maps/pxa2xx-flash.c
drivers/mtd/nand/omap2.c
drivers/net/b44.c
drivers/net/benet/be_cmds.c
drivers/net/bnx2x/bnx2x.h
drivers/net/bnx2x/bnx2x_cmn.c
drivers/net/bnx2x/bnx2x_init_ops.h
drivers/net/bonding/bond_main.c
drivers/net/bonding/bonding.h
drivers/net/caif/caif_shm_u5500.c
drivers/net/caif/caif_shmcore.c
drivers/net/cxgb4/t4_hw.c
drivers/net/cxgb4vf/cxgb4vf_main.c
drivers/net/ehea/ehea_ethtool.c
drivers/net/ehea/ehea_main.c
drivers/net/enic/enic_main.c
drivers/net/ifb.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/phy/Kconfig
drivers/net/phy/icplus.c
drivers/net/pppoe.c
drivers/net/qlge/qlge.h
drivers/net/qlge/qlge_main.c
drivers/net/qlge/qlge_mpi.c
drivers/net/r8169.c
drivers/net/sfc/efx.c
drivers/net/sfc/net_driver.h
drivers/net/sfc/nic.c
drivers/net/stmmac/stmmac_main.c
drivers/net/tulip/dmfe.c
drivers/net/usb/hso.c
drivers/net/wan/hd64572.c
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/eeprom.c
drivers/net/wireless/ath/ath9k/eeprom.h
drivers/net/wireless/ath/ath9k/eeprom_def.c
drivers/net/wireless/ath/ath9k/hif_usb.c
drivers/net/wireless/ath/ath9k/htc.h
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/mac.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/carl9170/fw.c
drivers/net/wireless/ath/carl9170/main.c
drivers/net/wireless/ath/carl9170/tx.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/libertas/if_spi.c
drivers/net/wireless/libertas/main.c
drivers/net/wireless/orinoco/main.c
drivers/net/wireless/orinoco/orinoco_cs.c
drivers/net/wireless/orinoco/scan.c
drivers/net/wireless/orinoco/scan.h
drivers/net/wireless/orinoco/spectrum_cs.c
drivers/net/wireless/orinoco/wext.c
drivers/net/xen-netfront.c
drivers/pci/bus.c
drivers/pci/quirks.c
drivers/pnp/pnpacpi/core.c
drivers/regulator/tps6586x-regulator.c
drivers/s390/scsi/zfcp_erp.c
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_scsi.c
drivers/scsi/hpsa.c
drivers/scsi/osd/osd_initiator.c
drivers/scsi/pmcraid.c
drivers/scsi/pmcraid.h
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_nx.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_version.h
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib.c
drivers/serial/kgdboc.c
drivers/spi/dw_spi.c
drivers/usb/atm/usbatm.c
drivers/vhost/vhost.c
drivers/video/modedb.c
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/file.c
fs/btrfs/free-space-cache.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/ioctl.h
fs/btrfs/orphan.c
fs/btrfs/super.c
fs/btrfs/volumes.c
fs/btrfs/volumes.h
fs/ceph/dir.c
fs/ceph/ioctl.h
fs/ceph/locks.c
fs/ceph/mds_client.c
fs/ceph/mds_client.h
fs/cifs/Makefile
fs/cifs/README
fs/cifs/cifs_fs_sb.h
fs/cifs/cifsacl.c
fs/cifs/cifsacl.h
fs/cifs/cifsfs.c
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/readdir.c
fs/exec.c
fs/ext4/ext4.h
fs/ext4/inode.c
fs/ext4/namei.c
fs/ext4/super.c
fs/fuse/file.c
fs/namei.c
fs/nfs/dir.c
fs/nfs/file.c
fs/nfs/inode.c
fs/nfs/mount_clnt.c
fs/nfs/nfs4proc.c
fs/nfs/pagelist.c
fs/nfs/read.c
fs/nfs/super.c
fs/nfs/write.c
fs/nfsd/nfs3xdr.c
fs/nfsd/xdr4.h
fs/nilfs2/gcinode.c
fs/nilfs2/ioctl.c
fs/notify/fanotify/fanotify.c
fs/notify/fanotify/fanotify_user.c
fs/notify/inotify/inotify_user.c
fs/xfs/xfs_rename.c
include/acpi/video.h
include/linux/acpi.h
include/linux/atmdev.h
include/linux/fanotify.h
include/linux/fs.h
include/linux/fsnotify.h
include/linux/fsnotify_backend.h
include/linux/input.h
include/linux/ioport.h
include/linux/mfd/wm8994/pdata.h
include/linux/nfs_fs.h
include/linux/nfs_page.h
include/linux/perf_event.h
include/linux/pm_runtime.h
include/linux/sched.h
include/linux/snmp.h
include/linux/ssb/ssb_driver_gige.h
include/linux/video_output.h
include/media/v4l2-device.h
include/net/sock.h
include/xen/interface/io/ring.h
kernel/fork.c
kernel/perf_event.c
kernel/power/swap.c
kernel/power/user.c
kernel/resource.c
kernel/sched.c
kernel/timer.c
kernel/trace/trace.c
kernel/workqueue.c
mm/filemap.c
mm/mmap.c
mm/truncate.c
mm/vmscan.c
net/atm/atm_sysfs.c
net/atm/resources.c
net/atm/resources.h
net/bluetooth/sco.c
net/core/filter.c
net/core/timestamping.c
net/econet/af_econet.c
net/ipv4/proc.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_output.c
net/ipv6/addrconf.c
net/ipv6/ip6_tunnel.c
net/ipv6/sit.c
net/l2tp/l2tp_ip.c
net/llc/af_llc.c
net/mac80211/rx.c
net/mac80211/tx.c
net/sctp/socket.c
net/socket.c
net/sunrpc/svc_xprt.c
net/x25/x25_link.c
net/xfrm/xfrm_state.c
scripts/recordmcount.h
scripts/tags.sh
sound/pci/hda/hda_eld.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/soc/codecs/wm8580.c
sound/soc/codecs/wm8904.c
sound/soc/codecs/wm8955.c
sound/soc/codecs/wm8960.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm_hubs.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c

index a91f30890011ddf69ba9b859484966c943db7fb5..b6426f15b4ae85f5469b962806004237b9b5607e 100644 (file)
@@ -173,12 +173,13 @@ prototypes:
        sector_t (*bmap)(struct address_space *, sector_t);
        int (*invalidatepage) (struct page *, unsigned long);
        int (*releasepage) (struct page *, int);
+       void (*freepage)(struct page *);
        int (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
                        loff_t offset, unsigned long nr_segs);
        int (*launder_page) (struct page *);
 
 locking rules:
-       All except set_page_dirty may block
+       All except set_page_dirty and freepage may block
 
                        BKL     PageLocked(page)        i_mutex
 writepage:             no      yes, unlocks (see below)
@@ -193,6 +194,7 @@ perform_write:              no      n/a                     yes
 bmap:                  no
 invalidatepage:                no      yes
 releasepage:           no      yes
+freepage:              no      yes
 direct_IO:             no
 launder_page:          no      yes
 
@@ -288,6 +290,9 @@ buffers from the page in preparation for freeing it.  It returns zero to
 indicate that the buffers are (or may be) freeable.  If ->releasepage is zero,
 the kernel assumes that the fs has no private interest in the buffers.
 
+       ->freepage() is called when the kernel is done dropping the page
+from the page cache.
+
        ->launder_page() may be called prior to releasing a page if
 it is still found to be dirty. It returns zero if the page was successfully
 cleaned, or an error value if not. Note that in order to prevent the page
index 55c28b79d8dce3afcb239f45cc1cc62c44685d3c..20899e095e7e6879580b53aa9aa0282fb4b5ce63 100644 (file)
@@ -534,6 +534,7 @@ struct address_space_operations {
        sector_t (*bmap)(struct address_space *, sector_t);
        int (*invalidatepage) (struct page *, unsigned long);
        int (*releasepage) (struct page *, int);
+       void (*freepage)(struct page *);
        ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
                        loff_t offset, unsigned long nr_segs);
        struct page* (*get_xip_page)(struct address_space *, sector_t,
@@ -678,6 +679,12 @@ struct address_space_operations {
         need to ensure this.  Possibly it can clear the PageUptodate
         bit if it cannot free private data yet.
 
+  freepage: freepage is called once the page is no longer visible in
+        the page cache in order to allow the cleanup of any private
+       data. Since it may be called by the memory reclaimer, it
+       should not assume that the original address_space mapping still
+       exists, and it should not block.
+
   direct_IO: called by the generic read/write routines to perform
         direct_IO - that is IO requests which bypass the page cache
         and transfer data directly between the storage and the
index cdd2a6e8a3b79ae9fabc67230a27a21927642c9b..8b61c93609994dd91e36c25e1b29647ad084eaff 100644 (file)
@@ -2175,11 +2175,6 @@ and is between 256 and 4096 characters. It is defined in the file
        reset_devices   [KNL] Force drivers to reset the underlying device
                        during initialization.
 
-       resource_alloc_from_bottom
-                       Allocate new resources from the beginning of available
-                       space, not the end.  If you need to use this, please
-                       report a bug.
-
        resume=         [SWSUSP]
                        Specify the partition device for software suspend
 
index 489e9bacd165ad4a354130edcf7e03d97471b52b..41cc7b30d7ddaff700a198b590eb91047d90d0d0 100644 (file)
@@ -379,8 +379,8 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
       zero)
 
   bool pm_runtime_suspended(struct device *dev);
-    - return true if the device's runtime PM status is 'suspended', or false
-      otherwise
+    - return true if the device's runtime PM status is 'suspended' and its
+      'power.disable_depth' field is equal to zero, or false otherwise
 
   void pm_runtime_allow(struct device *dev);
     - set the power.runtime_auto flag for the device and decrease its usage
index 1a1c27b9c557b2e07af18cb9b8c4e97c53c95c86..6a588873cf8d2da8b00f803a1dcd8d96841292bd 100644 (file)
@@ -559,14 +559,14 @@ W:        http://maxim.org.za/at91_26.html
 S:     Maintained
 
 ARM/BCMRING ARM ARCHITECTURE
-M:     Leo Chen <leochen@broadcom.com>
+M:     Jiandong Zheng <jdzheng@broadcom.com>
 M:     Scott Branden <sbranden@broadcom.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/mach-bcmring
 
 ARM/BCMRING MTD NAND DRIVER
-M:     Leo Chen <leochen@broadcom.com>
+M:     Jiandong Zheng <jdzheng@broadcom.com>
 M:     Scott Branden <sbranden@broadcom.com>
 L:     linux-mtd@lists.infradead.org
 S:     Maintained
@@ -815,7 +815,7 @@ F:  drivers/mmc/host/msm_sdcc.c
 F:     drivers/mmc/host/msm_sdcc.h
 F:     drivers/serial/msm_serial.h
 F:     drivers/serial/msm_serial.c
-T:     git git://codeaurora.org/quic/kernel/dwalker/linux-msm.git
+T:     git git://codeaurora.org/quic/kernel/davidb/linux-msm.git
 S:     Maintained
 
 ARM/TOSA MACHINE SUPPORT
@@ -5932,7 +5932,6 @@ F:        include/linux/tty.h
 
 TULIP NETWORK DRIVERS
 M:     Grant Grundler <grundler@parisc-linux.org>
-M:     Kyle McMartin <kyle@mcmartin.ca>
 L:     netdev@vger.kernel.org
 S:     Maintained
 F:     drivers/net/tulip/
@@ -6584,6 +6583,15 @@ F:       include/linux/mfd/wm8400*
 F:     include/sound/wm????.h
 F:     sound/soc/codecs/wm*
 
+WORKQUEUE
+M:     Tejun Heo <tj@kernel.org>
+L:     linux-kernel@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git
+S:     Maintained
+F:     include/linux/workqueue.h
+F:     kernel/workqueue.c
+F:     Documentation/workqueue.txt
+
 X.25 NETWORK LAYER
 M:     Andrew Hendry <andrew.hendry@gmail.com>
 L:     linux-x25@vger.kernel.org
index 3d94974542eac52bec7078dc9f9a70bcb46596d5..5aa44278d95686e9719f38592599b094a72a1366 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 37
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc6
 NAME = Flesh-Eating Bats with Fangs
 
 # *DOCUMENTATION*
index f1d9297b105084be1f3718213fd592e0dd0d1747..d56d21c0573ba519b36d7f1e4012eb609dfbb664 100644 (file)
@@ -1311,7 +1311,7 @@ config HZ
 
 config THUMB2_KERNEL
        bool "Compile the kernel in Thumb-2 mode"
-       depends on CPU_V7 && EXPERIMENTAL
+       depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL
        select AEABI
        select ARM_ASM_UNIFIED
        help
@@ -1759,7 +1759,7 @@ comment "At least one emulation must be selected"
 
 config FPE_NWFPE
        bool "NWFPE math emulation"
-       depends on !AEABI || OABI_COMPAT
+       depends on (!AEABI || OABI_COMPAT) && !THUMB2_KERNEL
        ---help---
          Say Y to include the NWFPE floating point emulator in the kernel.
          This is necessary to run most binaries. Linux does not currently
index 62d686f0b42602e6b1f7beb096524944452b3b45..d13add71f72accab27ae6abade209d8fad2259f9 100644 (file)
@@ -65,7 +65,7 @@ obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
 obj-$(CONFIG_MACH_CPU9G20)     += board-cpu9krea.o
 obj-$(CONFIG_MACH_STAMP9G20)   += board-stamp9g20.o
 obj-$(CONFIG_MACH_PORTUXG20)   += board-stamp9g20.o
-obj-$(CONFIG_MACH_PCONTROL_G20)        += board-pcontrol-g20.o
+obj-$(CONFIG_MACH_PCONTROL_G20)        += board-pcontrol-g20.o board-stamp9g20.o
 
 # AT91SAM9260/AT91SAM9G20 board-specific support
 obj-$(CONFIG_MACH_SNAPPER_9260)        += board-snapper9260.o
index bba5a560e02b8c829304ffdded29038760167cdd..feb65787c30be5502985a112e4b200d0f7de8ac0 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <mach/board.h>
 #include <mach/at91sam9_smc.h>
+#include <mach/stamp9g20.h>
 
 #include "sam9_smc.h"
 #include "generic.h"
 
 static void __init pcontrol_g20_map_io(void)
 {
-       /* Initialize processor: 18.432 MHz crystal */
-       at91sam9260_initialize(18432000);
-
-       /* DGBU on ttyS0. (Rx, Tx) only TTL -> JTAG connector X7 17,19 ) */
-       at91_register_uart(0, 0, 0);
+       stamp9g20_map_io();
 
        /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback  A2 */
        at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS
@@ -54,9 +51,6 @@ static void __init pcontrol_g20_map_io(void)
 
        /* USART2 on ttyS3. (Rx, Tx)  9bit-Bus  Multidrop-mode  X4 */
        at91_register_uart(AT91SAM9260_ID_US4, 3, 0);
-
-       /* set serial console to ttyS0 (ie, DBGU) */
-       at91_set_serial_console(0);
 }
 
 
@@ -66,38 +60,6 @@ static void __init init_irq(void)
 }
 
 
-/*
- * NAND flash 512MiB 1,8V 8-bit, sector size 128 KiB
- */
-static struct atmel_nand_data __initdata nand_data = {
-       .ale            = 21,
-       .cle            = 22,
-       .rdy_pin        = AT91_PIN_PC13,
-       .enable_pin     = AT91_PIN_PC14,
-};
-
-/*
- * Bus timings; unit = 7.57ns
- */
-static struct sam9_smc_config __initdata nand_smc_config = {
-       .ncs_read_setup         = 0,
-       .nrd_setup              = 2,
-       .ncs_write_setup        = 0,
-       .nwe_setup              = 2,
-
-       .ncs_read_pulse         = 4,
-       .nrd_pulse              = 4,
-       .ncs_write_pulse        = 4,
-       .nwe_pulse              = 4,
-
-       .read_cycle             = 7,
-       .write_cycle            = 7,
-
-       .mode                   = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
-                       | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
-       .tdf_cycles             = 3,
-};
-
 static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { {
        .ncs_read_setup         = 16,
        .nrd_setup              = 18,
@@ -138,14 +100,6 @@ static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { {
        .tdf_cycles             = 1,
 } };
 
-static void __init add_device_nand(void)
-{
-       /* configure chip-select 3 (NAND) */
-       sam9_smc_configure(3, &nand_smc_config);
-       at91_add_device_nand(&nand_data);
-}
-
-
 static void __init add_device_pcontrol(void)
 {
        /* configure chip-select 4 (IO compatible to 8051  X4 ) */
@@ -155,23 +109,6 @@ static void __init add_device_pcontrol(void)
 }
 
 
-/*
- * MCI (SD/MMC)
- * det_pin, wp_pin and vcc_pin are not connected
- */
-#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
-static struct mci_platform_data __initdata mmc_data = {
-       .slot[0] = {
-               .bus_width      = 4,
-       },
-};
-#else
-static struct at91_mmc_data __initdata mmc_data = {
-       .wire4          = 1,
-};
-#endif
-
-
 /*
  * USB Host port
  */
@@ -265,42 +202,13 @@ static struct spi_board_info pcontrol_g20_spi_devices[] = {
 };
 
 
-/*
- * Dallas 1-Wire  DS2431
- */
-static struct w1_gpio_platform_data w1_gpio_pdata = {
-       .pin            = AT91_PIN_PA29,
-       .is_open_drain  = 1,
-};
-
-static struct platform_device w1_device = {
-       .name                   = "w1-gpio",
-       .id                     = -1,
-       .dev.platform_data      = &w1_gpio_pdata,
-};
-
-static void add_wire1(void)
-{
-       at91_set_GPIO_periph(w1_gpio_pdata.pin, 1);
-       at91_set_multi_drive(w1_gpio_pdata.pin, 1);
-       platform_device_register(&w1_device);
-}
-
-
 static void __init pcontrol_g20_board_init(void)
 {
-       at91_add_device_serial();
-       add_device_nand();
-#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
-       at91_add_device_mci(0, &mmc_data);
-#else
-       at91_add_device_mmc(0, &mmc_data);
-#endif
+       stamp9g20_board_init();
        at91_add_device_usbh(&usbh_data);
        at91_add_device_eth(&macb_data);
        at91_add_device_i2c(pcontrol_g20_i2c_devices,
                ARRAY_SIZE(pcontrol_g20_i2c_devices));
-       add_wire1();
        add_device_pcontrol();
        at91_add_device_spi(pcontrol_g20_spi_devices,
                ARRAY_SIZE(pcontrol_g20_spi_devices));
index 5206eef4a67eba12e1b22bd7ae0faa48ce29271a..f8902b118960d84f4d9bf6c57d3a28e9c302df64 100644 (file)
@@ -32,7 +32,7 @@
 #include "generic.h"
 
 
-static void __init portuxg20_map_io(void)
+void __init stamp9g20_map_io(void)
 {
        /* Initialize processor: 18.432 MHz crystal */
        at91sam9260_initialize(18432000);
@@ -40,6 +40,24 @@ static void __init portuxg20_map_io(void)
        /* DGBU on ttyS0. (Rx & Tx only) */
        at91_register_uart(0, 0, 0);
 
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
+}
+
+static void __init stamp9g20evb_map_io(void)
+{
+       stamp9g20_map_io();
+
+       /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+       at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+                                               | ATMEL_UART_DTR | ATMEL_UART_DSR
+                                               | ATMEL_UART_DCD | ATMEL_UART_RI);
+}
+
+static void __init portuxg20_map_io(void)
+{
+       stamp9g20_map_io();
+
        /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
        at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
                                                | ATMEL_UART_DTR | ATMEL_UART_DSR
@@ -56,26 +74,6 @@ static void __init portuxg20_map_io(void)
 
        /* USART5 on ttyS6. (Rx, Tx only) */
        at91_register_uart(AT91SAM9260_ID_US5, 6, 0);
-
-       /* set serial console to ttyS0 (ie, DBGU) */
-       at91_set_serial_console(0);
-}
-
-static void __init stamp9g20_map_io(void)
-{
-       /* Initialize processor: 18.432 MHz crystal */
-       at91sam9260_initialize(18432000);
-
-       /* DGBU on ttyS0. (Rx & Tx only) */
-       at91_register_uart(0, 0, 0);
-
-       /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
-       at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
-                                               | ATMEL_UART_DTR | ATMEL_UART_DSR
-                                               | ATMEL_UART_DCD | ATMEL_UART_RI);
-
-       /* set serial console to ttyS0 (ie, DBGU) */
-       at91_set_serial_console(0);
 }
 
 static void __init init_irq(void)
@@ -156,7 +154,7 @@ static struct at91_udc_data __initdata portuxg20_udc_data = {
        .pullup_pin     = 0,            /* pull-up driven by UDC */
 };
 
-static struct at91_udc_data __initdata stamp9g20_udc_data = {
+static struct at91_udc_data __initdata stamp9g20evb_udc_data = {
        .vbus_pin       = AT91_PIN_PA22,
        .pullup_pin     = 0,            /* pull-up driven by UDC */
 };
@@ -190,7 +188,7 @@ static struct gpio_led portuxg20_leds[] = {
        }
 };
 
-static struct gpio_led stamp9g20_leds[] = {
+static struct gpio_led stamp9g20evb_leds[] = {
        {
                .name                   = "D8",
                .gpio                   = AT91_PIN_PB18,
@@ -250,7 +248,7 @@ void add_w1(void)
 }
 
 
-static void __init generic_board_init(void)
+void __init stamp9g20_board_init(void)
 {
        /* Serial */
        at91_add_device_serial();
@@ -262,34 +260,40 @@ static void __init generic_board_init(void)
 #else
        at91_add_device_mmc(0, &mmc_data);
 #endif
-       /* USB Host */
-       at91_add_device_usbh(&usbh_data);
-       /* Ethernet */
-       at91_add_device_eth(&macb_data);
-       /* I2C */
-       at91_add_device_i2c(NULL, 0);
        /* W1 */
        add_w1();
 }
 
 static void __init portuxg20_board_init(void)
 {
-       generic_board_init();
-       /* SPI */
-       at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices));
+       stamp9g20_board_init();
+       /* USB Host */
+       at91_add_device_usbh(&usbh_data);
        /* USB Device */
        at91_add_device_udc(&portuxg20_udc_data);
+       /* Ethernet */
+       at91_add_device_eth(&macb_data);
+       /* I2C */
+       at91_add_device_i2c(NULL, 0);
+       /* SPI */
+       at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices));
        /* LEDs */
        at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds));
 }
 
-static void __init stamp9g20_board_init(void)
+static void __init stamp9g20evb_board_init(void)
 {
-       generic_board_init();
+       stamp9g20_board_init();
+       /* USB Host */
+       at91_add_device_usbh(&usbh_data);
        /* USB Device */
-       at91_add_device_udc(&stamp9g20_udc_data);
+       at91_add_device_udc(&stamp9g20evb_udc_data);
+       /* Ethernet */
+       at91_add_device_eth(&macb_data);
+       /* I2C */
+       at91_add_device_i2c(NULL, 0);
        /* LEDs */
-       at91_gpio_leds(stamp9g20_leds, ARRAY_SIZE(stamp9g20_leds));
+       at91_gpio_leds(stamp9g20evb_leds, ARRAY_SIZE(stamp9g20evb_leds));
 }
 
 MACHINE_START(PORTUXG20, "taskit PortuxG20")
@@ -305,7 +309,7 @@ MACHINE_START(STAMP9G20, "taskit Stamp9G20")
        /* Maintainer: taskit GmbH */
        .boot_params    = AT91_SDRAM_BASE + 0x100,
        .timer          = &at91sam926x_timer,
-       .map_io         = stamp9g20_map_io,
+       .map_io         = stamp9g20evb_map_io,
        .init_irq       = init_irq,
-       .init_machine   = stamp9g20_board_init,
+       .init_machine   = stamp9g20evb_board_init,
 MACHINE_END
index 7525cee3983f7252fac0542be5955a490ca6869b..9113da6845f17482437ed984bd978b9b28378dfe 100644 (file)
@@ -658,7 +658,7 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock)
        /* Now set uhpck values */
        uhpck.parent = &utmi_clk;
        uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
-       uhpck.rate_hz = utmi_clk.parent->rate_hz;
+       uhpck.rate_hz = utmi_clk.rate_hz;
        uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
 }
 
diff --git a/arch/arm/mach-at91/include/mach/stamp9g20.h b/arch/arm/mach-at91/include/mach/stamp9g20.h
new file mode 100644 (file)
index 0000000..6120f9c
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __MACH_STAMP9G20_H
+#define __MACH_STAMP9G20_H
+
+void stamp9g20_map_io(void);
+void stamp9g20_board_init(void);
+
+#endif
index daf3993349f81986fa8f5b90ca0c4bcb4e7acc8a..2e3dd08ccc3f3f1d062eaac583b92109e39c31f4 100644 (file)
@@ -126,7 +126,6 @@ static APBC_CLK(twsi3, MMP2_TWSI3, 0, 26000000);
 static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000);
 static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000);
 static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000);
-static APBC_CLK(rtc, MMP2_RTC, 0, 32768);
 
 static APMU_CLK(nand, NAND, 0xbf, 100000000);
 
index 86c9b210295214c175638df2997745d2643cd447..9db9203667df504c5b5731680b3f75077ae79b6d 100644 (file)
@@ -216,7 +216,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
        {
                .name           = "wl1271",
                .mmc            = 3,
-               .caps           = MMC_CAP_4_BIT_DATA,
+               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
                .gpio_wp        = -EINVAL,
                .gpio_cd        = -EINVAL,
                .nonremovable   = true,
index 40562ddd3ee4fe29ea1e173a61d778225d28b01d..a1939b1e6f82e0d30ca77b8b4156c27eb6f1c4ce 100644 (file)
@@ -297,7 +297,7 @@ static int __init _omap2_init_reprogram_sdrc(void)
                return 0;
 
        dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck");
-       if (!dpll3_m2_ck)
+       if (IS_ERR(dpll3_m2_ck))
                return -EINVAL;
 
        rate = clk_get_rate(dpll3_m2_ck);
index 5e81517a7af2040a8bff6a2e2eabc9a96e300b76..a8afb610c7d83fa7a500445ea4647d4935d26e09 100644 (file)
@@ -161,6 +161,23 @@ void omap2_pm_dump(int mode, int resume, unsigned int us)
                printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val);
 }
 
+void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
+{
+       u32 tick_rate, cycles;
+
+       if (!seconds && !milliseconds)
+               return;
+
+       tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
+       cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
+       omap_dm_timer_stop(gptimer_wakeup);
+       omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
+
+       pr_info("PM: Resume timer in %u.%03u secs"
+               " (%d ticks at %d ticks/sec.)\n",
+               seconds, milliseconds, cycles, tick_rate);
+}
+
 #ifdef CONFIG_DEBUG_FS
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
@@ -354,23 +371,6 @@ void pm_dbg_update_time(struct powerdomain *pwrdm, int prev)
        pwrdm->timer = t;
 }
 
-void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
-{
-       u32 tick_rate, cycles;
-
-       if (!seconds && !milliseconds)
-               return;
-
-       tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
-       cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
-       omap_dm_timer_stop(gptimer_wakeup);
-       omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
-
-       pr_info("PM: Resume timer in %u.%03u secs"
-               " (%d ticks at %d ticks/sec.)\n",
-               seconds, milliseconds, cycles, tick_rate);
-}
-
 static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
 {
        struct seq_file *s = (struct seq_file *)user;
index c85923e56b85e350b97b027d9a8352e9a8b6776b..aaeea49b9bdd80f6e51affaee9c3a38ff6e2368f 100644 (file)
 #include <plat/powerdomain.h>
 #include <plat/clockdomain.h>
 
+#ifdef CONFIG_SUSPEND
+static suspend_state_t suspend_state = PM_SUSPEND_ON;
+static inline bool is_suspending(void)
+{
+       return (suspend_state != PM_SUSPEND_ON);
+}
+#else
+static inline bool is_suspending(void)
+{
+       return false;
+}
+#endif
+
 static void (*omap2_sram_idle)(void);
 static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl,
                                  void __iomem *sdrc_power);
@@ -120,8 +133,9 @@ static void omap2_enter_full_retention(void)
                goto no_sleep;
 
        /* Block console output in case it is on one of the OMAP UARTs */
-       if (try_acquire_console_sem())
-               goto no_sleep;
+       if (!is_suspending())
+               if (try_acquire_console_sem())
+                       goto no_sleep;
 
        omap_uart_prepare_idle(0);
        omap_uart_prepare_idle(1);
@@ -136,7 +150,8 @@ static void omap2_enter_full_retention(void)
        omap_uart_resume_idle(1);
        omap_uart_resume_idle(0);
 
-       release_console_sem();
+       if (!is_suspending())
+               release_console_sem();
 
 no_sleep:
        if (omap2_pm_debug) {
@@ -284,6 +299,12 @@ out:
        local_irq_enable();
 }
 
+static int omap2_pm_begin(suspend_state_t state)
+{
+       suspend_state = state;
+       return 0;
+}
+
 static int omap2_pm_prepare(void)
 {
        /* We cannot sleep in idle until we have resumed */
@@ -333,10 +354,17 @@ static void omap2_pm_finish(void)
        enable_hlt();
 }
 
+static void omap2_pm_end(void)
+{
+       suspend_state = PM_SUSPEND_ON;
+}
+
 static struct platform_suspend_ops omap_pm_ops = {
+       .begin          = omap2_pm_begin,
        .prepare        = omap2_pm_prepare,
        .enter          = omap2_pm_enter,
        .finish         = omap2_pm_finish,
+       .end            = omap2_pm_end,
        .valid          = suspend_valid_only_mem,
 };
 
index 0ec8a04b74730bfccc3e0d709c493e9d8ac8e256..648b8c50d02422eeda2146cf3d3ebbe4b44d5a75 100644 (file)
 #include "sdrc.h"
 #include "control.h"
 
+#ifdef CONFIG_SUSPEND
+static suspend_state_t suspend_state = PM_SUSPEND_ON;
+static inline bool is_suspending(void)
+{
+       return (suspend_state != PM_SUSPEND_ON);
+}
+#else
+static inline bool is_suspending(void)
+{
+       return false;
+}
+#endif
+
 /* Scratchpad offsets */
 #define OMAP343X_TABLE_ADDRESS_OFFSET     0xc4
 #define OMAP343X_TABLE_VALUE_OFFSET       0xc0
@@ -387,10 +400,11 @@ void omap_sram_idle(void)
        }
 
        /* Block console output in case it is on one of the OMAP UARTs */
-       if (per_next_state < PWRDM_POWER_ON ||
-           core_next_state < PWRDM_POWER_ON)
-               if (try_acquire_console_sem())
-                       goto console_still_active;
+       if (!is_suspending())
+               if (per_next_state < PWRDM_POWER_ON ||
+                   core_next_state < PWRDM_POWER_ON)
+                       if (try_acquire_console_sem())
+                               goto console_still_active;
 
        /* PER */
        if (per_next_state < PWRDM_POWER_ON) {
@@ -470,7 +484,8 @@ void omap_sram_idle(void)
                omap_uart_resume_idle(3);
        }
 
-       release_console_sem();
+       if (!is_suspending())
+               release_console_sem();
 
 console_still_active:
        /* Disable IO-PAD and IO-CHAIN wakeup */
@@ -514,8 +529,6 @@ out:
 }
 
 #ifdef CONFIG_SUSPEND
-static suspend_state_t suspend_state;
-
 static int omap3_pm_prepare(void)
 {
        disable_hlt();
index 298a22a754e20a56e428aeaed051cdd7b2b923f7..f81acee4738dea03f64576b6a6288282002def39 100644 (file)
 #define OMAP24XX_EN_GPT1_MASK                          (1 << 0)
 
 /* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */
-#define OMAP24XX_ST_GPIOS_SHIFT                                (1 << 2)
-#define OMAP24XX_ST_GPIOS_MASK                         2
-#define OMAP24XX_ST_GPT1_SHIFT                         (1 << 0)
-#define OMAP24XX_ST_GPT1_MASK                          0
+#define OMAP24XX_ST_GPIOS_SHIFT                                2
+#define OMAP24XX_ST_GPIOS_MASK                         (1 << 2)
+#define OMAP24XX_ST_GPT1_SHIFT                         0
+#define OMAP24XX_ST_GPT1_MASK                          (1 << 0)
 
 /* CM_IDLEST_MDM and PM_WKST_MDM shared bits */
-#define OMAP2430_ST_MDM_SHIFT                          (1 << 0)
+#define OMAP2430_ST_MDM_SHIFT                          0
+#define OMAP2430_ST_MDM_MASK                           (1 << 0)
 
 
 /* 3430 register bits shared between CM & PRM registers */
index d2060a1d1d6820bcaf796e1a256a92989ce45365..e5c9932b75887914ec1c95b94692322b98f0e4b1 100644 (file)
@@ -241,7 +241,8 @@ static inline void palmtx_keys_init(void) {}
 /******************************************************************************
  * NAND Flash
  ******************************************************************************/
-#if defined(CONFIG_MTD_NAND_GPIO) || defined(CONFIG_MTD_NAND_GPIO_MODULE)
+#if defined(CONFIG_MTD_NAND_PLATFORM) || \
+       defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
 static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd,
                                 unsigned int ctrl)
 {
index 99fa688dfadd305113670aa48ea185a9899f8e5b..c96fa1b3f49f5d78b670289a1d8fc8ccf3b38b30 100644 (file)
@@ -203,6 +203,10 @@ ENTRY(v6_flush_kern_dcache_area)
  *     - end     - virtual end address of region
  */
 v6_dma_inv_range:
+#ifdef CONFIG_DMA_CACHE_RWFO
+       ldrb    r2, [r0]                        @ read for ownership
+       strb    r2, [r0]                        @ write for ownership
+#endif
        tst     r0, #D_CACHE_LINE_SIZE - 1
        bic     r0, r0, #D_CACHE_LINE_SIZE - 1
 #ifdef HARVARD_CACHE
@@ -211,6 +215,10 @@ v6_dma_inv_range:
        mcrne   p15, 0, r0, c7, c11, 1          @ clean unified line
 #endif
        tst     r1, #D_CACHE_LINE_SIZE - 1
+#ifdef CONFIG_DMA_CACHE_RWFO
+       ldrneb  r2, [r1, #-1]                   @ read for ownership
+       strneb  r2, [r1, #-1]                   @ write for ownership
+#endif
        bic     r1, r1, #D_CACHE_LINE_SIZE - 1
 #ifdef HARVARD_CACHE
        mcrne   p15, 0, r1, c7, c14, 1          @ clean & invalidate D line
@@ -218,10 +226,6 @@ v6_dma_inv_range:
        mcrne   p15, 0, r1, c7, c15, 1          @ clean & invalidate unified line
 #endif
 1:
-#ifdef CONFIG_DMA_CACHE_RWFO
-       ldr     r2, [r0]                        @ read for ownership
-       str     r2, [r0]                        @ write for ownership
-#endif
 #ifdef HARVARD_CACHE
        mcr     p15, 0, r0, c7, c6, 1           @ invalidate D line
 #else
@@ -229,6 +233,10 @@ v6_dma_inv_range:
 #endif
        add     r0, r0, #D_CACHE_LINE_SIZE
        cmp     r0, r1
+#ifdef CONFIG_DMA_CACHE_RWFO
+       ldrlo   r2, [r0]                        @ read for ownership
+       strlo   r2, [r0]                        @ write for ownership
+#endif
        blo     1b
        mov     r0, #0
        mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
@@ -263,12 +271,12 @@ v6_dma_clean_range:
  *     - end     - virtual end address of region
  */
 ENTRY(v6_dma_flush_range)
-       bic     r0, r0, #D_CACHE_LINE_SIZE - 1
-1:
 #ifdef CONFIG_DMA_CACHE_RWFO
-       ldr     r2, [r0]                        @ read for ownership
-       str     r2, [r0]                        @ write for ownership
+       ldrb    r2, [r0]                @ read for ownership
+       strb    r2, [r0]                @ write for ownership
 #endif
+       bic     r0, r0, #D_CACHE_LINE_SIZE - 1
+1:
 #ifdef HARVARD_CACHE
        mcr     p15, 0, r0, c7, c14, 1          @ clean & invalidate D line
 #else
@@ -276,6 +284,10 @@ ENTRY(v6_dma_flush_range)
 #endif
        add     r0, r0, #D_CACHE_LINE_SIZE
        cmp     r0, r1
+#ifdef CONFIG_DMA_CACHE_RWFO
+       ldrlob  r2, [r0]                        @ read for ownership
+       strlob  r2, [r0]                        @ write for ownership
+#endif
        blo     1b
        mov     r0, #0
        mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
index a3ebf7a4f49b2b404da115a58e7fdf6923792625..6136e68ce953d038ef0fa92b8211a3c477ef8e83 100644 (file)
@@ -173,15 +173,22 @@ ENTRY(v7_coherent_user_range)
  UNWIND(.fnstart               )
        dcache_line_size r2, r3
        sub     r3, r2, #1
-       bic     r0, r0, r3
+       bic     r12, r0, r3
 1:
- USER( mcr     p15, 0, r0, c7, c11, 1  )       @ clean D line to the point of unification
+ USER( mcr     p15, 0, r12, c7, c11, 1 )       @ clean D line to the point of unification
+       add     r12, r12, r2
+       cmp     r12, r1
+       blo     1b
        dsb
- USER( mcr     p15, 0, r0, c7, c5, 1   )       @ invalidate I line
-       add     r0, r0, r2
+       icache_line_size r2, r3
+       sub     r3, r2, #1
+       bic     r12, r0, r3
 2:
-       cmp     r0, r1
-       blo     1b
+ USER( mcr     p15, 0, r12, c7, c5, 1  )       @ invalidate I line
+       add     r12, r12, r2
+       cmp     r12, r1
+       blo     2b
+3:
        mov     r0, #0
        ALT_SMP(mcr     p15, 0, r0, c7, c1, 6)  @ invalidate BTB Inner Shareable
        ALT_UP(mcr      p15, 0, r0, c7, c5, 6)  @ invalidate BTB
@@ -194,10 +201,10 @@ ENTRY(v7_coherent_user_range)
  * isn't mapped, just try the next page.
  */
 9001:
-       mov     r0, r0, lsr #12
-       mov     r0, r0, lsl #12
-       add     r0, r0, #4096
-       b       2b
+       mov     r12, r12, lsr #12
+       mov     r12, r12, lsl #12
+       add     r12, r12, #4096
+       b       3b
  UNWIND(.fnend         )
 ENDPROC(v7_coherent_kern_range)
 ENDPROC(v7_coherent_user_range)
index 7d63beaf97456541c0718c84b475b844194156e6..b795afd0a2c620ad1e8f774b1c166bc8639b2847 100644 (file)
        .endm
 
 /*
- * cache_line_size - get the cache line size from the CSIDR register
- * (available on ARMv7+). It assumes that the CSSR register was configured
- * to access the L1 data cache CSIDR.
+ * dcache_line_size - get the minimum D-cache line size from the CTR register
+ * on ARMv7.
  */
        .macro  dcache_line_size, reg, tmp
-       mrc     p15, 1, \tmp, c0, c0, 0         @ read CSIDR
-       and     \tmp, \tmp, #7                  @ cache line size encoding
-       mov     \reg, #16                       @ size offset
+       mrc     p15, 0, \tmp, c0, c0, 1         @ read ctr
+       lsr     \tmp, \tmp, #16
+       and     \tmp, \tmp, #0xf                @ cache line size encoding
+       mov     \reg, #4                        @ bytes per word
        mov     \reg, \reg, lsl \tmp            @ actual cache line size
        .endm
 
+/*
+ * icache_line_size - get the minimum I-cache line size from the CTR register
+ * on ARMv7.
+ */
+       .macro  icache_line_size, reg, tmp
+       mrc     p15, 0, \tmp, c0, c0, 1         @ read ctr
+       and     \tmp, \tmp, #0xf                @ cache line size encoding
+       mov     \reg, #4                        @ bytes per word
+       mov     \reg, \reg, lsl \tmp            @ actual cache line size
+       .endm
 
 /*
  * Sanity check the PTE configuration for the code below - which makes
index 155fe43a672bc47fde734dc76e10fb844e9b22e5..8722a136f3a5bee844f5643dd195c95f077db666 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/err.h>
 
 #include <plat/common.h>
 #include <plat/board.h>
@@ -164,7 +165,7 @@ static int __init omap_init_clocksource_32k(void)
                        return -ENODEV;
 
                sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
-               if (sync_32k_ick)
+               if (!IS_ERR(sync_32k_ick))
                        clk_enable(sync_32k_ick);
 
                clocksource_32k.mult = clocksource_hz2mult(32768,
index e2c8eebe6b3a54a1ab7c0a9ffa25f280117ceb04..74dac419d328297a4347b8a29ce1d5c150af1480 100644 (file)
@@ -166,7 +166,7 @@ static void __init omap_detect_sram(void)
                     cpu_is_omap1710())
                        omap_sram_size = 0x4000;        /* 16K */
                else if (cpu_is_omap1611())
-                       omap_sram_size = 0x3e800;       /* 250K */
+                       omap_sram_size = SZ_256K;
                else {
                        printk(KERN_ERR "Could not detect SRAM size\n");
                        omap_sram_size = 0x4000;
index 55590a4d87c932984404d1df13ca4c296c9d7117..2fea897ebeb12959415120a7c1cdcaf5d8ac8fee 100644 (file)
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Thu Sep 9 22:43:01 2010
+# Last update: Sun Dec 12 23:24:27 2010
 #
 # machine_is_xxx       CONFIG_xxxx             MACH_TYPE_xxx           number
 #
@@ -2321,7 +2321,7 @@ mx31txtr          MACH_MX31TXTR           MX31TXTR                2332
 u380                   MACH_U380               U380                    2333
 oamp3_hualu            MACH_HUALU_BOARD        HUALU_BOARD             2334
 npcmx50                        MACH_NPCMX50            NPCMX50                 2335
-mx51_lange51           MACH_MX51_LANGE51       MX51_LANGE51            2336
+mx51_efikamx           MACH_MX51_EFIKAMX       MX51_EFIKAMX            2336
 mx51_lange52           MACH_MX51_LANGE52       MX51_LANGE52            2337
 riom                   MACH_RIOM               RIOM                    2338
 comcas                 MACH_COMCAS             COMCAS                  2339
@@ -2355,7 +2355,7 @@ at91sam9263cs             MACH_AT91SAM9263CS      AT91SAM9263CS           2366
 csb732                 MACH_CSB732             CSB732                  2367
 u8500                  MACH_U8500              U8500                   2368
 huqiu                  MACH_HUQIU              HUQIU                   2369
-mx51_kunlun            MACH_MX51_KUNLUN        MX51_KUNLUN             2370
+mx51_efikasb           MACH_MX51_EFIKASB       MX51_EFIKASB            2370
 pmt1g                  MACH_PMT1G              PMT1G                   2371
 htcelf                 MACH_HTCELF             HTCELF                  2372
 armadillo420           MACH_ARMADILLO420       ARMADILLO420            2373
@@ -2971,7 +2971,7 @@ premierwave_en            MACH_PREMIERWAVE_EN     PREMIERWAVE_EN          2985
 wasabi                 MACH_WASABI             WASABI                  2986
 vivow                  MACH_VIVOW              VIVOW                   2987
 mx50_rdp               MACH_MX50_RDP           MX50_RDP                2988
-universal              MACH_UNIVERSAL          UNIVERSAL               2989
+universal_c210         MACH_UNIVERSAL_C210     UNIVERSAL_C210          2989
 real6410               MACH_REAL6410           REAL6410                2990
 spx_sakura             MACH_SPX_SAKURA         SPX_SAKURA              2991
 ij3k_2440              MACH_IJ3K_2440          IJ3K_2440               2992
@@ -3044,3 +3044,178 @@ harvest_desoto          MACH_HARVEST_DESOTO     HARVEST_DESOTO          3059
 msm8x60_qrdc           MACH_MSM8X60_QRDC       MSM8X60_QRDC            3060
 spear900               MACH_SPEAR900           SPEAR900                3061
 pcontrol_g20           MACH_PCONTROL_G20       PCONTROL_G20            3062
+rdstor                 MACH_RDSTOR             RDSTOR                  3063
+usdloader              MACH_USDLOADER          USDLOADER               3064
+tsoploader             MACH_TSOPLOADER         TSOPLOADER              3065
+kronos                 MACH_KRONOS             KRONOS                  3066
+ffcore                 MACH_FFCORE             FFCORE                  3067
+mone                   MACH_MONE               MONE                    3068
+unit2s                 MACH_UNIT2S             UNIT2S                  3069
+acer_a5                        MACH_ACER_A5            ACER_A5                 3070
+etherpro_isp           MACH_ETHERPRO_ISP       ETHERPRO_ISP            3071
+stretchs7000           MACH_STRETCHS7000       STRETCHS7000            3072
+p87_smartsim           MACH_P87_SMARTSIM       P87_SMARTSIM            3073
+tulip                  MACH_TULIP              TULIP                   3074
+sunflower              MACH_SUNFLOWER          SUNFLOWER               3075
+rib                    MACH_RIB                RIB                     3076
+clod                   MACH_CLOD               CLOD                    3077
+rump                   MACH_RUMP               RUMP                    3078
+tenderloin             MACH_TENDERLOIN         TENDERLOIN              3079
+shortloin              MACH_SHORTLOIN          SHORTLOIN               3080
+crespo                 MACH_CRESPO             CRESPO                  3081
+antares                        MACH_ANTARES            ANTARES                 3082
+wb40n                  MACH_WB40N              WB40N                   3083
+herring                        MACH_HERRING            HERRING                 3084
+naxy400                        MACH_NAXY400            NAXY400                 3085
+naxy1200               MACH_NAXY1200           NAXY1200                3086
+vpr200                 MACH_VPR200             VPR200                  3087
+bug20                  MACH_BUG20              BUG20                   3088
+goflexnet              MACH_GOFLEXNET          GOFLEXNET               3089
+torbreck               MACH_TORBRECK           TORBRECK                3090
+saarb_mg1              MACH_SAARB_MG1          SAARB_MG1               3091
+callisto               MACH_CALLISTO           CALLISTO                3092
+multhsu                        MACH_MULTHSU            MULTHSU                 3093
+saluda                 MACH_SALUDA             SALUDA                  3094
+pemp_omap3_apollo      MACH_PEMP_OMAP3_APOLLO  PEMP_OMAP3_APOLLO       3095
+vc0718                 MACH_VC0718             VC0718                  3096
+mvblx                  MACH_MVBLX              MVBLX                   3097
+inhand_apeiron         MACH_INHAND_APEIRON     INHAND_APEIRON          3098
+inhand_fury            MACH_INHAND_FURY        INHAND_FURY             3099
+inhand_siren           MACH_INHAND_SIREN       INHAND_SIREN            3100
+hdnvp                  MACH_HDNVP              HDNVP                   3101
+softwinner             MACH_SOFTWINNER         SOFTWINNER              3102
+prima2_evb             MACH_PRIMA2_EVB         PRIMA2_EVB              3103
+nas6210                        MACH_NAS6210            NAS6210                 3104
+unisdev                        MACH_UNISDEV            UNISDEV                 3105
+sbca11                 MACH_SBCA11             SBCA11                  3106
+saga                   MACH_SAGA               SAGA                    3107
+ns_k330                        MACH_NS_K330            NS_K330                 3108
+tanna                  MACH_TANNA              TANNA                   3109
+imate8502              MACH_IMATE8502          IMATE8502               3110
+aspen                  MACH_ASPEN              ASPEN                   3111
+daintree_cwac          MACH_DAINTREE_CWAC      DAINTREE_CWAC           3112
+zmx25                  MACH_ZMX25              ZMX25                   3113
+maple1                 MACH_MAPLE1             MAPLE1                  3114
+qsd8x72_surf           MACH_QSD8X72_SURF       QSD8X72_SURF            3115
+qsd8x72_ffa            MACH_QSD8X72_FFA        QSD8X72_FFA             3116
+abilene                        MACH_ABILENE            ABILENE                 3117
+eigen_ttr              MACH_EIGEN_TTR          EIGEN_TTR               3118
+iomega_ix2_200         MACH_IOMEGA_IX2_200     IOMEGA_IX2_200          3119
+coretec_vcx7400                MACH_CORETEC_VCX7400    CORETEC_VCX7400         3120
+santiago               MACH_SANTIAGO           SANTIAGO                3121
+mx257sol               MACH_MX257SOL           MX257SOL                3122
+strasbourg             MACH_STRASBOURG         STRASBOURG              3123
+msm8x60_fluid          MACH_MSM8X60_FLUID      MSM8X60_FLUID           3124
+smartqv5               MACH_SMARTQV5           SMARTQV5                3125
+smartqv3               MACH_SMARTQV3           SMARTQV3                3126
+smartqv7               MACH_SMARTQV7           SMARTQV7                3127
+paz00                  MACH_PAZ00              PAZ00                   3128
+acmenetusfoxg20                MACH_ACMENETUSFOXG20    ACMENETUSFOXG20         3129
+htcwillow              MACH_HTCWILLOW          HTCWILLOW               3130
+fwbd_0404              MACH_FWBD_0404          FWBD_0404               3131
+hdgu                   MACH_HDGU               HDGU                    3132
+pyramid                        MACH_PYRAMID            PYRAMID                 3133
+epiphan                        MACH_EPIPHAN            EPIPHAN                 3134
+omap_bender            MACH_OMAP_BENDER        OMAP_BENDER             3135
+gurnard                        MACH_GURNARD            GURNARD                 3136
+gtl_it5100             MACH_GTL_IT5100         GTL_IT5100              3137
+bcm2708                        MACH_BCM2708            BCM2708                 3138
+mx51_ggc               MACH_MX51_GGC           MX51_GGC                3139
+sharespace             MACH_SHARESPACE         SHARESPACE              3140
+haba_knx_explorer      MACH_HABA_KNX_EXPLORER  HABA_KNX_EXPLORER       3141
+simtec_kirkmod         MACH_SIMTEC_KIRKMOD     SIMTEC_KIRKMOD          3142
+crux                   MACH_CRUX               CRUX                    3143
+mx51_bravo             MACH_MX51_BRAVO         MX51_BRAVO              3144
+charon                 MACH_CHARON             CHARON                  3145
+picocom3               MACH_PICOCOM3           PICOCOM3                3146
+picocom4               MACH_PICOCOM4           PICOCOM4                3147
+serrano                        MACH_SERRANO            SERRANO                 3148
+doubleshot             MACH_DOUBLESHOT         DOUBLESHOT              3149
+evsy                   MACH_EVSY               EVSY                    3150
+huashan                        MACH_HUASHAN            HUASHAN                 3151
+lausanne               MACH_LAUSANNE           LAUSANNE                3152
+emerald                        MACH_EMERALD            EMERALD                 3153
+tqma35                 MACH_TQMA35             TQMA35                  3154
+marvel                 MACH_MARVEL             MARVEL                  3155
+manuae                 MACH_MANUAE             MANUAE                  3156
+chacha                 MACH_CHACHA             CHACHA                  3157
+lemon                  MACH_LEMON              LEMON                   3158
+csc                    MACH_CSC                CSC                     3159
+gira_knxip_router      MACH_GIRA_KNXIP_ROUTER  GIRA_KNXIP_ROUTER       3160
+t20                    MACH_T20                T20                     3161
+hdmini                 MACH_HDMINI             HDMINI                  3162
+sciphone_g2            MACH_SCIPHONE_G2        SCIPHONE_G2             3163
+express                        MACH_EXPRESS            EXPRESS                 3164
+express_kt             MACH_EXPRESS_KT         EXPRESS_KT              3165
+maximasp               MACH_MAXIMASP           MAXIMASP                3166
+nitrogen_imx51         MACH_NITROGEN_IMX51     NITROGEN_IMX51          3167
+nitrogen_imx53         MACH_NITROGEN_IMX53     NITROGEN_IMX53          3168
+sunfire                        MACH_SUNFIRE            SUNFIRE                 3169
+arowana                        MACH_AROWANA            AROWANA                 3170
+tegra_daytona          MACH_TEGRA_DAYTONA      TEGRA_DAYTONA           3171
+tegra_swordfish                MACH_TEGRA_SWORDFISH    TEGRA_SWORDFISH         3172
+edison                 MACH_EDISON             EDISON                  3173
+svp8500v1              MACH_SVP8500V1          SVP8500V1               3174
+svp8500v2              MACH_SVP8500V2          SVP8500V2               3175
+svp5500                        MACH_SVP5500            SVP5500                 3176
+b5500                  MACH_B5500              B5500                   3177
+s5500                  MACH_S5500              S5500                   3178
+icon                   MACH_ICON               ICON                    3179
+elephant               MACH_ELEPHANT           ELEPHANT                3180
+msm8x60_fusion         MACH_MSM8X60_FUSION     MSM8X60_FUSION          3181
+shooter                        MACH_SHOOTER            SHOOTER                 3182
+spade_lte              MACH_SPADE_LTE          SPADE_LTE               3183
+philhwani              MACH_PHILHWANI          PHILHWANI               3184
+gsncomm                        MACH_GSNCOMM            GSNCOMM                 3185
+strasbourg_a2          MACH_STRASBOURG_A2      STRASBOURG_A2           3186
+mmm                    MACH_MMM                MMM                     3187
+davinci_dm365_bv       MACH_DAVINCI_DM365_BV   DAVINCI_DM365_BV        3188
+ag5evm                 MACH_AG5EVM             AG5EVM                  3189
+sc575plc               MACH_SC575PLC           SC575PLC                3190
+sc575hmi               MACH_SC575IPC           SC575IPC                3191
+omap3_tdm3730          MACH_OMAP3_TDM3730      OMAP3_TDM3730           3192
+g7                     MACH_G7                 G7                      3193
+top9000_eval           MACH_TOP9000_EVAL       TOP9000_EVAL            3194
+top9000_su             MACH_TOP9000_SU         TOP9000_SU              3195
+utm300                 MACH_UTM300             UTM300                  3196
+tsunagi                        MACH_TSUNAGI            TSUNAGI                 3197
+ts75xx                 MACH_TS75XX             TS75XX                  3198
+msm8x60_fusn_ffa       MACH_MSM8X60_FUSN_FFA   MSM8X60_FUSN_FFA        3199
+ts47xx                 MACH_TS47XX             TS47XX                  3200
+da850_k5               MACH_DA850_K5           DA850_K5                3201
+ax502                  MACH_AX502              AX502                   3202
+igep0032               MACH_IGEP0032           IGEP0032                3203
+antero                 MACH_ANTERO             ANTERO                  3204
+synergy                        MACH_SYNERGY            SYNERGY                 3205
+ics_if_voip            MACH_ICS_IF_VOIP        ICS_IF_VOIP             3206
+wlf_cragg_6410         MACH_WLF_CRAGG_6410     WLF_CRAGG_6410          3207
+punica                 MACH_PUNICA             PUNICA                  3208
+sbc_nt250              MACH_SBC_NT250          SBC_NT250               3209
+mx27_wmultra           MACH_MX27_WMULTRA       MX27_WMULTRA            3210
+mackerel               MACH_MACKEREL           MACKEREL                3211
+fa9x27                 MACH_FA9X27             FA9X27                  3213
+ns2816tb               MACH_NS2816TB           NS2816TB                3214
+ns2816_ntpad           MACH_NS2816_NTPAD       NS2816_NTPAD            3215
+ns2816_ntnb            MACH_NS2816_NTNB        NS2816_NTNB             3216
+kaen                   MACH_KAEN               KAEN                    3217
+nv1000                 MACH_NV1000             NV1000                  3218
+nuc950ts               MACH_NUC950TS           NUC950TS                3219
+nokia_rm680            MACH_NOKIA_RM680        NOKIA_RM680             3220
+ast2200                        MACH_AST2200            AST2200                 3221
+lead                   MACH_LEAD               LEAD                    3222
+unino1                 MACH_UNINO1             UNINO1                  3223
+greeco                 MACH_GREECO             GREECO                  3224
+verdi                  MACH_VERDI              VERDI                   3225
+dm6446_adbox           MACH_DM6446_ADBOX       DM6446_ADBOX            3226
+quad_salsa             MACH_QUAD_SALSA         QUAD_SALSA              3227
+abb_gma_1_1            MACH_ABB_GMA_1_1        ABB_GMA_1_1             3228
+svcid                  MACH_SVCID              SVCID                   3229
+msm8960_sim            MACH_MSM8960_SIM        MSM8960_SIM             3230
+msm8960_rumi3          MACH_MSM8960_RUMI3      MSM8960_RUMI3           3231
+icon_g                 MACH_ICON_G             ICON_G                  3232
+mb3                    MACH_MB3                MB3                     3233
+gsia18s                        MACH_GSIA18S            GSIA18S                 3234
+pivicc                 MACH_PIVICC             PIVICC                  3235
+pcm048                 MACH_PCM048             PCM048                  3236
+dds                    MACH_DDS                DDS                     3237
+chalten_xa1            MACH_CHALTEN_XA1        CHALTEN_XA1             3238
index 67a2fa2caa494ff06e2550aa8cea7cf61d69f39e..0a9b5b8b2a1935103ecf9d81a2367d0a0633f1e4 100644 (file)
@@ -19,6 +19,8 @@ config MIPS
        select GENERIC_ATOMIC64 if !64BIT
        select HAVE_DMA_ATTRS
        select HAVE_DMA_API_DEBUG
+       select HAVE_GENERIC_HARDIRQS
+       select GENERIC_IRQ_PROBE
 
 menu "Machine selection"
 
@@ -1664,6 +1666,28 @@ config PAGE_SIZE_64KB
 
 endchoice
 
+config FORCE_MAX_ZONEORDER
+       int "Maximum zone order"
+       range 13 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB
+       default "13" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB
+       range 12 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB
+       default "12" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB
+       range 11 64
+       default "11"
+       help
+         The kernel memory allocator divides physically contiguous memory
+         blocks into "zones", where each zone is a power of two number of
+         pages.  This option selects the largest power of two that the kernel
+         keeps in the memory allocator.  If you need to allocate very large
+         blocks of physically contiguous memory, then you may need to
+         increase this value.
+
+         This config option is actually maximum order plus one. For example,
+         a value of 11 means that the largest free memory block is 2^10 pages.
+
+         The page size is not necessarily 4KB.  Keep this in mind
+         when choosing a value for this option.
+
 config BOARD_SCACHE
        bool
 
@@ -1921,20 +1945,6 @@ config CPU_R4000_WORKAROUNDS
 config CPU_R4400_WORKAROUNDS
        bool
 
-#
-# Use the generic interrupt handling code in kernel/irq/:
-#
-config GENERIC_HARDIRQS
-       bool
-       default y
-
-config GENERIC_IRQ_PROBE
-       bool
-       default y
-
-config IRQ_PER_CPU
-       bool
-
 #
 # - Highmem only makes sense for the 32-bit kernel.
 # - The current highmem code will only work properly on physically indexed
index 3691630931d6100ae901d8adbddcc6ccb6cf960e..9e7814db3d03411d08bfe93868f84d646dd93d93 100644 (file)
@@ -27,6 +27,7 @@
 static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
                            unsigned int old_state)
 {
+#ifdef CONFIG_SERIAL_8250
        switch (state) {
        case 0:
                if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) {
@@ -49,6 +50,7 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state,
                serial8250_do_pm(port, state, old_state);
                break;
        }
+#endif
 }
 
 #define PORT(_base, _irq)                                      \
index b30df5c97ad35e46e534b047c144975c01db6b76..baeb21385058b8d5efe5e046620e66746b754d73 100644 (file)
@@ -54,10 +54,9 @@ void __init prom_init(void)
 
        prom_init_cmdline();
        memsize_str = prom_getenv("memsize");
-       if (!memsize_str)
+       if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize))
                memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE;
-       else
-               strict_strtoul(memsize_str, 0, &memsize);
+
        add_memory_region(0, memsize, BOOT_MEM_RAM);
 }
 
index fc0e7154e8d69835c56eb45891a9e98beca0e82f..2ca4ada1c291cf7cb13f0ac047d6b879e9e1b400 100644 (file)
@@ -239,12 +239,12 @@ static void tnetd7300_set_clock(u32 shift, struct tnetd7300_clock *clock,
        calculate(base_clock, frequency, &prediv, &postdiv, &mul);
 
        writel(((prediv - 1) << PREDIV_SHIFT) | (postdiv - 1), &clock->ctrl);
-       msleep(1);
+       mdelay(1);
        writel(4, &clock->pll);
        while (readl(&clock->pll) & PLL_STATUS)
                ;
        writel(((mul - 1) << MUL_SHIFT) | (0xff << 3) | 0x0e, &clock->pll);
-       msleep(75);
+       mdelay(75);
 }
 
 static void __init tnetd7300_init_clocks(void)
@@ -456,7 +456,7 @@ void clk_put(struct clk *clk)
 }
 EXPORT_SYMBOL(clk_put);
 
-int __init ar7_init_clocks(void)
+void __init ar7_init_clocks(void)
 {
        switch (ar7_chip_id()) {
        case AR7_CHIP_7100:
@@ -472,7 +472,4 @@ int __init ar7_init_clocks(void)
        }
        /* adjust vbus clock rate */
        vbus_clk.rate = bus_clk.rate / 2;
-
-       return 0;
 }
-arch_initcall(ar7_init_clocks);
index 5fb8a01340855f402340914784c65924faaa163e..22c93213b233db0090a2c8175cee864f2cf62619 100644 (file)
@@ -30,6 +30,9 @@ void __init plat_time_init(void)
 {
        struct clk *cpu_clk;
 
+       /* Initialize ar7 clocks so the CPU clock frequency is correct */
+       ar7_init_clocks();
+
        cpu_clk = clk_get(NULL, "cpu");
        if (IS_ERR(cpu_clk)) {
                printk(KERN_ERR "unable to get cpu clock\n");
index b1aee33efd11454e7f47c7d8beb7d0d50ed9ca2a..c95f90bf734ca9c1765b14728f391a14af62917b 100644 (file)
@@ -32,7 +32,6 @@
 #include <asm/reboot.h>
 #include <asm/time.h>
 #include <bcm47xx.h>
-#include <asm/fw/cfe/cfe_api.h>
 #include <asm/mach-bcm47xx/nvram.h>
 
 struct ssb_bus ssb_bcm47xx;
@@ -57,68 +56,112 @@ static void bcm47xx_machine_halt(void)
                cpu_relax();
 }
 
-static void str2eaddr(char *str, char *dest)
-{
-       int i = 0;
+#define READ_FROM_NVRAM(_outvar, name, buf) \
+       if (nvram_getenv(name, buf, sizeof(buf)) >= 0)\
+               sprom->_outvar = simple_strtoul(buf, NULL, 0);
 
-       if (str == NULL) {
-               memset(dest, 0, 6);
-               return;
+static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
+{
+       char buf[100];
+       u32 boardflags;
+
+       memset(sprom, 0, sizeof(struct ssb_sprom));
+
+       sprom->revision = 1; /* Fallback: Old hardware does not define this. */
+       READ_FROM_NVRAM(revision, "sromrev", buf);
+       if (nvram_getenv("il0macaddr", buf, sizeof(buf)) >= 0)
+               nvram_parse_macaddr(buf, sprom->il0mac);
+       if (nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
+               nvram_parse_macaddr(buf, sprom->et0mac);
+       if (nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
+               nvram_parse_macaddr(buf, sprom->et1mac);
+       READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf);
+       READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf);
+       READ_FROM_NVRAM(et0mdcport, "et0mdcport", buf);
+       READ_FROM_NVRAM(et1mdcport, "et1mdcport", buf);
+       READ_FROM_NVRAM(board_rev, "boardrev", buf);
+       READ_FROM_NVRAM(country_code, "ccode", buf);
+       READ_FROM_NVRAM(ant_available_a, "aa5g", buf);
+       READ_FROM_NVRAM(ant_available_bg, "aa2g", buf);
+       READ_FROM_NVRAM(pa0b0, "pa0b0", buf);
+       READ_FROM_NVRAM(pa0b1, "pa0b1", buf);
+       READ_FROM_NVRAM(pa0b2, "pa0b2", buf);
+       READ_FROM_NVRAM(pa1b0, "pa1b0", buf);
+       READ_FROM_NVRAM(pa1b1, "pa1b1", buf);
+       READ_FROM_NVRAM(pa1b2, "pa1b2", buf);
+       READ_FROM_NVRAM(pa1lob0, "pa1lob0", buf);
+       READ_FROM_NVRAM(pa1lob2, "pa1lob1", buf);
+       READ_FROM_NVRAM(pa1lob1, "pa1lob2", buf);
+       READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf);
+       READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf);
+       READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf);
+       READ_FROM_NVRAM(gpio0, "wl0gpio0", buf);
+       READ_FROM_NVRAM(gpio1, "wl0gpio1", buf);
+       READ_FROM_NVRAM(gpio2, "wl0gpio2", buf);
+       READ_FROM_NVRAM(gpio3, "wl0gpio3", buf);
+       READ_FROM_NVRAM(maxpwr_bg, "pa0maxpwr", buf);
+       READ_FROM_NVRAM(maxpwr_al, "pa1lomaxpwr", buf);
+       READ_FROM_NVRAM(maxpwr_a, "pa1maxpwr", buf);
+       READ_FROM_NVRAM(maxpwr_ah, "pa1himaxpwr", buf);
+       READ_FROM_NVRAM(itssi_a, "pa1itssit", buf);
+       READ_FROM_NVRAM(itssi_bg, "pa0itssit", buf);
+       READ_FROM_NVRAM(tri2g, "tri2g", buf);
+       READ_FROM_NVRAM(tri5gl, "tri5gl", buf);
+       READ_FROM_NVRAM(tri5g, "tri5g", buf);
+       READ_FROM_NVRAM(tri5gh, "tri5gh", buf);
+       READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf);
+       READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf);
+       READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf);
+       READ_FROM_NVRAM(rssismc2g, "rssismc2g", buf);
+       READ_FROM_NVRAM(rssismf2g, "rssismf2g", buf);
+       READ_FROM_NVRAM(bxa2g, "bxa2g", buf);
+       READ_FROM_NVRAM(rssisav5g, "rssisav5g", buf);
+       READ_FROM_NVRAM(rssismc5g, "rssismc5g", buf);
+       READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf);
+       READ_FROM_NVRAM(bxa5g, "bxa5g", buf);
+       READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf);
+       READ_FROM_NVRAM(ofdm2gpo, "ofdm2gpo", buf);
+       READ_FROM_NVRAM(ofdm5glpo, "ofdm5glpo", buf);
+       READ_FROM_NVRAM(ofdm5gpo, "ofdm5gpo", buf);
+       READ_FROM_NVRAM(ofdm5ghpo, "ofdm5ghpo", buf);
+
+       if (nvram_getenv("boardflags", buf, sizeof(buf)) >= 0) {
+               boardflags = simple_strtoul(buf, NULL, 0);
+               if (boardflags) {
+                       sprom->boardflags_lo = (boardflags & 0x0000FFFFU);
+                       sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16;
+               }
        }
-
-       for (;;) {
-               dest[i++] = (char) simple_strtoul(str, NULL, 16);
-               str += 2;
-               if (!*str++ || i == 6)
-                       break;
+       if (nvram_getenv("boardflags2", buf, sizeof(buf)) >= 0) {
+               boardflags = simple_strtoul(buf, NULL, 0);
+               if (boardflags) {
+                       sprom->boardflags2_lo = (boardflags & 0x0000FFFFU);
+                       sprom->boardflags2_hi = (boardflags & 0xFFFF0000U) >> 16;
+               }
        }
 }
 
 static int bcm47xx_get_invariants(struct ssb_bus *bus,
                                   struct ssb_init_invariants *iv)
 {
-       char buf[100];
+       char buf[20];
 
        /* Fill boardinfo structure */
        memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo));
 
-       if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0)
-               iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
-       if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("boardtype", buf, sizeof(buf)) >= 0)
+       if (nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0)
+               iv->boardinfo.vendor = (u16)simple_strtoul(buf, NULL, 0);
+       else
+               iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM;
+       if (nvram_getenv("boardtype", buf, sizeof(buf)) >= 0)
                iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
-       if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
+       if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
                iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0);
 
-       /* Fill sprom structure */
-       memset(&(iv->sprom), 0, sizeof(struct ssb_sprom));
-       iv->sprom.revision = 3;
-
-       if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
-               str2eaddr(buf, iv->sprom.et0mac);
+       bcm47xx_fill_sprom(&iv->sprom);
 
-       if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
-               str2eaddr(buf, iv->sprom.et1mac);
-
-       if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("et0phyaddr", buf, sizeof(buf)) >= 0)
-               iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 0);
-
-       if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("et1phyaddr", buf, sizeof(buf)) >= 0)
-               iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 0);
-
-       if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("et0mdcport", buf, sizeof(buf)) >= 0)
-               iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10);
-
-       if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0 ||
-           nvram_getenv("et1mdcport", buf, sizeof(buf)) >= 0)
-               iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10);
+       if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
+               iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
 
        return 0;
 }
@@ -126,12 +169,28 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
 void __init plat_mem_setup(void)
 {
        int err;
+       char buf[100];
+       struct ssb_mipscore *mcore;
 
        err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE,
                                      bcm47xx_get_invariants);
        if (err)
                panic("Failed to initialize SSB bus (err %d)\n", err);
 
+       mcore = &ssb_bcm47xx.mipscore;
+       if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
+               if (strstr(buf, "console=ttyS1")) {
+                       struct ssb_serial_port port;
+
+                       printk(KERN_DEBUG "Swapping serial ports!\n");
+                       /* swap serial ports */
+                       memcpy(&port, &mcore->serial_ports[0], sizeof(port));
+                       memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1],
+                              sizeof(port));
+                       memcpy(&mcore->serial_ports[1], &port, sizeof(port));
+               }
+       }
+
        _machine_restart = bcm47xx_machine_restart;
        _machine_halt = bcm47xx_machine_halt;
        pm_power_off = bcm47xx_machine_halt;
index 06d59dcbe24310a92669983231a51e3aad34d324..86877539c6e83679f248d7245324693a690105e6 100644 (file)
  * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM
  */
 
-#define PRID_IMP_BMIPS4KC      0x4000
-#define PRID_IMP_BMIPS32       0x8000
+#define PRID_IMP_BMIPS32_REV4  0x4000
+#define PRID_IMP_BMIPS32_REV8  0x8000
 #define PRID_IMP_BMIPS3300     0x9000
 #define PRID_IMP_BMIPS3300_ALT 0x9100
 #define PRID_IMP_BMIPS3300_BUG 0x0000
index fd1d39eb74319b60473daf46cb5e4ecf1bcacb2e..455c0ac7d4ea84632cc41c40ee48e7dd9e82ce86 100644 (file)
@@ -249,7 +249,8 @@ extern struct mips_abi mips_abi_n32;
 
 #define SET_PERSONALITY(ex)                                            \
 do {                                                                   \
-       set_personality(PER_LINUX);                                     \
+       if (personality(current->personality) != PER_LINUX)             \
+               set_personality(PER_LINUX);                             \
                                                                        \
        current->thread.abi = &mips_abi;                                \
 } while (0)
@@ -296,6 +297,8 @@ do {                                                                        \
 
 #define SET_PERSONALITY(ex)                                            \
 do {                                                                   \
+       unsigned int p;                                                 \
+                                                                       \
        clear_thread_flag(TIF_32BIT_REGS);                              \
        clear_thread_flag(TIF_32BIT_ADDR);                              \
                                                                        \
@@ -304,7 +307,8 @@ do {                                                                        \
        else                                                            \
                current->thread.abi = &mips_abi;                        \
                                                                        \
-       if (current->personality != PER_LINUX32)                        \
+       p = personality(current->personality);                          \
+       if (p != PER_LINUX32 && p != PER_LINUX)                         \
                set_personality(PER_LINUX);                             \
 } while (0)
 
index c98bf514ec7de9efe6596721cfa472d878da3f16..5b017f23e243d71b195cfea786c70ef389da7810 100644 (file)
@@ -329,10 +329,14 @@ static inline void pfx##write##bwlq(type val,                             \
                        "dsrl32 %L0, %L0, 0"                    "\n\t"  \
                        "dsll32 %M0, %M0, 0"                    "\n\t"  \
                        "or     %L0, %L0, %M0"                  "\n\t"  \
+                       ".set   push"                           "\n\t"  \
+                       ".set   noreorder"                      "\n\t"  \
+                       ".set   nomacro"                        "\n\t"  \
                        "sd     %L0, %2"                        "\n\t"  \
+                       ".set   pop"                            "\n\t"  \
                        ".set   mips0"                          "\n"    \
                        : "=r" (__tmp)                                  \
-                       : "0" (__val), "m" (*__mem));                   \
+                       : "0" (__val), "R" (*__mem));                   \
                if (irq)                                                \
                        local_irq_restore(__flags);                     \
        } else                                                          \
@@ -355,12 +359,16 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem)      \
                        local_irq_save(__flags);                        \
                __asm__ __volatile__(                                   \
                        ".set   mips3"          "\t\t# __readq" "\n\t"  \
+                       ".set   push"                           "\n\t"  \
+                       ".set   noreorder"                      "\n\t"  \
+                       ".set   nomacro"                        "\n\t"  \
                        "ld     %L0, %1"                        "\n\t"  \
+                       ".set   pop"                            "\n\t"  \
                        "dsra32 %M0, %L0, 0"                    "\n\t"  \
                        "sll    %L0, %L0, 0"                    "\n\t"  \
                        ".set   mips0"                          "\n"    \
                        : "=r" (__val)                                  \
-                       : "m" (*__mem));                                \
+                       : "R" (*__mem));                                \
                if (irq)                                                \
                        local_irq_restore(__flags);                     \
        } else {                                                        \
index 7919d76186bf1b78dca75c62e1fc41f731fc6ebb..07d3fadb24437e289bae5c8da747b2fdd647e8a5 100644 (file)
@@ -201,7 +201,6 @@ static inline void ar7_device_off(u32 bit)
 }
 
 int __init ar7_gpio_init(void);
-
-int __init ar7_gpio_init(void);
+void __init ar7_init_clocks(void);
 
 #endif /* __AR7_H__ */
index c58ebd8bc1551dd92e14111acc1ac92c4b17d1b7..9759588ba3cff0c81da6cd454148a6787e4babcf 100644 (file)
@@ -12,6 +12,7 @@
 #define __NVRAM_H
 
 #include <linux/types.h>
+#include <linux/kernel.h>
 
 struct nvram_header {
        u32 magic;
@@ -36,4 +37,10 @@ struct nvram_header {
 
 extern int nvram_getenv(char *name, char *val, size_t val_len);
 
+static inline void nvram_parse_macaddr(char *buf, u8 *macaddr)
+{
+       sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], &macaddr[1],
+              &macaddr[2], &macaddr[3], &macaddr[4], &macaddr[5]);
+}
+
 #endif
index 5742bb4d78f4db6aefa966b443dee7e095a2cfc5..5c0a3575877cce27c171d2d9a676dd8cf8073a7a 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 2009 Qi Hardware inc.,
  * Author: Xiangfu Liu <xiangfu@qi-hardware.com>
- * Copyright 2010, Lars-Petrer Clausen <lars@metafoo.de>
+ * Copyright 2010, Lars-Peter Clausen <lars@metafoo.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 or later
@@ -235,7 +235,7 @@ static const unsigned int qi_lb60_keypad_rows[] = {
        QI_LB60_GPIO_KEYIN(3),
        QI_LB60_GPIO_KEYIN(4),
        QI_LB60_GPIO_KEYIN(5),
-       QI_LB60_GPIO_KEYIN(7),
+       QI_LB60_GPIO_KEYIN(6),
        QI_LB60_GPIO_KEYIN8,
 };
 
index 95bc2b5b14f1b2c56cd141f2c8a2b8ea6370dcde..1cc9e544d16bd16609aaef30bd5779ad26f5dc14 100644 (file)
@@ -208,7 +208,7 @@ struct platform_device jz4740_i2s_device = {
 
 /* PCM */
 struct platform_device jz4740_pcm_device = {
-       .name           = "jz4740-pcm",
+       .name           = "jz4740-pcm-audio",
        .id             = -1,
 };
 
index cfeac15eb2e4d5716530fd07c5b6db3a8d77cadb..4a70407f55bb7df9d68bc46256b8c007c08c6e59 100644 (file)
@@ -23,7 +23,7 @@
 #include <asm/bootinfo.h>
 #include <asm/mach-jz4740/base.h>
 
-void jz4740_init_cmdline(int argc, char *argv[])
+static __init void jz4740_init_cmdline(int argc, char *argv[])
 {
        unsigned int count = COMMAND_LINE_SIZE - 1;
        int i;
index 2f4d7a99bcc2fcc91b3838599b0b0c3d4fb1c432..98c5a9737c14d2c200a161640122f9a8af053e88 100644 (file)
@@ -32,7 +32,7 @@ static int mips_next_event(unsigned long delta,
        cnt = read_c0_count();
        cnt += delta;
        write_c0_compare(cnt);
-       res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0;
+       res = ((int)(read_c0_count() - cnt) >= 0) ? -ETIME : 0;
        return res;
 }
 
index 71620e19827ad681a7834f0e400104cec4968ef2..68dae7b6b5db62a0a48a17e6fe339a2d56bd8bd8 100644 (file)
@@ -905,7 +905,8 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
 {
        decode_configs(c);
        switch (c->processor_id & 0xff00) {
-       case PRID_IMP_BMIPS32:
+       case PRID_IMP_BMIPS32_REV4:
+       case PRID_IMP_BMIPS32_REV8:
                c->cputype = CPU_BMIPS32;
                __cpu_name[cpu] = "Broadcom BMIPS32";
                break;
@@ -933,10 +934,6 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
                __cpu_name[cpu] = "Broadcom BMIPS5000";
                c->options |= MIPS_CPU_ULRI;
                break;
-       case PRID_IMP_BMIPS4KC:
-               c->cputype = CPU_4KC;
-               __cpu_name[cpu] = "MIPS 4Kc";
-               break;
        }
 }
 
index 6343b4a5b8350cb3a93edea5d75f3154cde48343..876a75cc376f7a8602d231c1c11440be8c88d7ae 100644 (file)
@@ -251,14 +251,15 @@ SYSCALL_DEFINE5(n32_msgrcv, int, msqid, u32, msgp, size_t, msgsz,
 
 SYSCALL_DEFINE1(32_personality, unsigned long, personality)
 {
+       unsigned int p = personality & 0xffffffff;
        int ret;
-       personality &= 0xffffffff;
+
        if (personality(current->personality) == PER_LINUX32 &&
-           personality == PER_LINUX)
-               personality = PER_LINUX32;
-       ret = sys_personality(personality);
-       if (ret == PER_LINUX32)
-               ret = PER_LINUX;
+           personality(p) == PER_LINUX)
+               p = (p & ~PER_MASK) | PER_LINUX32;
+       ret = sys_personality(p);
+       if (ret != -1 && personality(ret) == PER_LINUX32)
+               ret = (ret & ~PER_MASK) | PER_LINUX;
        return ret;
 }
 
index 99960940d4a410bba1e9842a7049161e74d04d25..ae167df73dddf2df41a2158050c164cb4fb346d4 100644 (file)
@@ -142,7 +142,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
        childregs->regs[7] = 0; /* Clear error flag */
 
        childregs->regs[2] = 0; /* Child gets zero as return value */
-       regs->regs[2] = p->pid;
 
        if (childregs->cp0_status & ST0_CU0) {
                childregs->regs[28] = (unsigned long) ti;
index e000b278f0243cfdfa1986be89b728c5b371a480..9dbe58368953809f721e845a004f98cb57809dba 100644 (file)
@@ -100,7 +100,7 @@ void __init device_tree_init(void)
                return;
 
        base = virt_to_phys((void *)initial_boot_params);
-       size = initial_boot_params->totalsize;
+       size = be32_to_cpu(initial_boot_params->totalsize);
 
        /* Before we do anything, lets reserve the dt blob */
        reserve_mem_mach(base, size);
index 43e7cdc5ded23a42fa1a8f24376ddf60eb96ccac..c0e81418ba21281ea4f3b5cedff5e564f947c1a1 100644 (file)
@@ -153,7 +153,7 @@ static void __cpuinit vsmp_init_secondary(void)
 {
        extern int gic_present;
 
-       /* This is Malta specific: IPI,performance and timer inetrrupts */
+       /* This is Malta specific: IPI,performance and timer interrupts */
        if (gic_present)
                change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 |
                                         STATUSF_IP6 | STATUSF_IP7);
index 8e9fbe75894e5f5199618264fcddde6410d42dc7..e97104302541fd4111ae9ceca477e04cf2b5add7 100644 (file)
@@ -83,7 +83,8 @@ extern asmlinkage void handle_mcheck(void);
 extern asmlinkage void handle_reserved(void);
 
 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
-       struct mips_fpu_struct *ctx, int has_fpu);
+                                   struct mips_fpu_struct *ctx, int has_fpu,
+                                   void *__user *fault_addr);
 
 void (*board_be_init)(void);
 int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
@@ -661,12 +662,36 @@ asmlinkage void do_ov(struct pt_regs *regs)
        force_sig_info(SIGFPE, &info, current);
 }
 
+static int process_fpemu_return(int sig, void __user *fault_addr)
+{
+       if (sig == SIGSEGV || sig == SIGBUS) {
+               struct siginfo si = {0};
+               si.si_addr = fault_addr;
+               si.si_signo = sig;
+               if (sig == SIGSEGV) {
+                       if (find_vma(current->mm, (unsigned long)fault_addr))
+                               si.si_code = SEGV_ACCERR;
+                       else
+                               si.si_code = SEGV_MAPERR;
+               } else {
+                       si.si_code = BUS_ADRERR;
+               }
+               force_sig_info(sig, &si, current);
+               return 1;
+       } else if (sig) {
+               force_sig(sig, current);
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
 /*
  * XXX Delayed fp exceptions when doing a lazy ctx switch XXX
  */
 asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
 {
-       siginfo_t info;
+       siginfo_t info = {0};
 
        if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE)
            == NOTIFY_STOP)
@@ -675,6 +700,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
 
        if (fcr31 & FPU_CSR_UNI_X) {
                int sig;
+               void __user *fault_addr = NULL;
 
                /*
                 * Unimplemented operation exception.  If we've got the full
@@ -690,7 +716,8 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
                lose_fpu(1);
 
                /* Run the emulator */
-               sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1);
+               sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
+                                              &fault_addr);
 
                /*
                 * We can't allow the emulated instruction to leave any of
@@ -702,8 +729,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
                own_fpu(1);     /* Using the FPU again.  */
 
                /* If something went wrong, signal */
-               if (sig)
-                       force_sig(sig, current);
+               process_fpemu_return(sig, fault_addr);
 
                return;
        } else if (fcr31 & FPU_CSR_INV_X)
@@ -996,11 +1022,11 @@ asmlinkage void do_cpu(struct pt_regs *regs)
 
                if (!raw_cpu_has_fpu) {
                        int sig;
+                       void __user *fault_addr = NULL;
                        sig = fpu_emulator_cop1Handler(regs,
-                                               &current->thread.fpu, 0);
-                       if (sig)
-                               force_sig(sig, current);
-                       else
+                                                      &current->thread.fpu,
+                                                      0, &fault_addr);
+                       if (!process_fpemu_return(sig, fault_addr))
                                mt_ase_fp_affinity();
                }
 
index 3eb3cde2f66160c0b4f5aeee889dc9adbfedf823..6a1fdfef8fded5763a457ec026467b356717fc78 100644 (file)
@@ -1092,6 +1092,10 @@ static int vpe_open(struct inode *inode, struct file *filp)
 
        /* this of-course trashes what was there before... */
        v->pbuffer = vmalloc(P_SIZE);
+       if (!v->pbuffer) {
+               pr_warning("VPE loader: unable to allocate memory\n");
+               return -ENOMEM;
+       }
        v->plen = P_SIZE;
        v->load_addr = NULL;
        v->len = 0;
@@ -1149,10 +1153,9 @@ static int vpe_release(struct inode *inode, struct file *filp)
        if (ret < 0)
                v->shared_ptr = NULL;
 
-       // cleanup any temp buffers
-       if (v->pbuffer)
-               vfree(v->pbuffer);
+       vfree(v->pbuffer);
        v->plen = 0;
+
        return ret;
 }
 
@@ -1169,11 +1172,6 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer,
        if (v == NULL)
                return -ENODEV;
 
-       if (v->pbuffer == NULL) {
-               printk(KERN_ERR "VPE loader: no buffer for program\n");
-               return -ENOMEM;
-       }
-
        if ((count + v->len) > v->plen) {
                printk(KERN_WARNING
                       "VPE loader: elf size too big. Perhaps strip uneeded symbols\n");
index 77dc3b20110ab9d583e09a9cac94e865bc2deab1..606c8a9efe3bb146930aca3b7c438f0095cbe066 100644 (file)
@@ -161,16 +161,16 @@ FEXPORT(__bzero)
 
 .Lfwd_fixup:
        PTR_L           t0, TI_TASK($28)
-       LONG_L          t0, THREAD_BUADDR(t0)
        andi            a2, 0x3f
+       LONG_L          t0, THREAD_BUADDR(t0)
        LONG_ADDU       a2, t1
        jr              ra
         LONG_SUBU      a2, t0
 
 .Lpartial_fixup:
        PTR_L           t0, TI_TASK($28)
-       LONG_L          t0, THREAD_BUADDR(t0)
        andi            a2, LONGMASK
+       LONG_L          t0, THREAD_BUADDR(t0)
        LONG_ADDU       a2, t1
        jr              ra
         LONG_SUBU      a2, t0
index ae4cff97a56c5073d75925a7c89a94ee5a410513..11b193f848f88b7aa1c5ab5a842c2cf4e80ed7d7 100644 (file)
@@ -29,9 +29,9 @@ unsigned long memsize, highmemsize;
 
 #define parse_even_earlier(res, option, p)                             \
 do {                                                                   \
+       int ret;                                                        \
        if (strncmp(option, (char *)p, strlen(option)) == 0)            \
-                       strict_strtol((char *)p + strlen(option"="),    \
-                                       10, &res);                      \
+               ret = strict_strtol((char *)p + strlen(option"="), 10, &res); \
 } while (0)
 
 void __init prom_init_env(void)
index b2ad1b0910ffb86d009dac8769310f30af3c3fcc..d32cb050311053a8e873ea470617b0ec17f13e26 100644 (file)
@@ -64,7 +64,7 @@ static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
 
 #if __mips >= 4 && __mips != 32
 static int fpux_emu(struct pt_regs *,
-       struct mips_fpu_struct *, mips_instruction);
+       struct mips_fpu_struct *, mips_instruction, void *__user *);
 #endif
 
 /* Further private data for which no space exists in mips_fpu_struct */
@@ -208,16 +208,23 @@ static inline int cop1_64bit(struct pt_regs *xcp)
  * Two instructions if the instruction is in a branch delay slot.
  */
 
-static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
+static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+                      void *__user *fault_addr)
 {
        mips_instruction ir;
        unsigned long emulpc, contpc;
        unsigned int cond;
 
-       if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
+       if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) {
                MIPS_FPU_EMU_INC_STATS(errors);
+               *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
                return SIGBUS;
        }
+       if (__get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) {
+               MIPS_FPU_EMU_INC_STATS(errors);
+               *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
+               return SIGSEGV;
+       }
 
        /* XXX NEC Vr54xx bug workaround */
        if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir))
@@ -245,10 +252,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
 #endif
                        return SIGILL;
                }
-               if (get_user(ir, (mips_instruction __user *) emulpc)) {
+               if (!access_ok(VERIFY_READ, emulpc, sizeof(mips_instruction))) {
                        MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = (mips_instruction __user *)emulpc;
                        return SIGBUS;
                }
+               if (__get_user(ir, (mips_instruction __user *) emulpc)) {
+                       MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = (mips_instruction __user *)emulpc;
+                       return SIGSEGV;
+               }
                /* __compute_return_epc() will have updated cp0_epc */
                contpc = xcp->cp0_epc;
                /* In order not to confuse ptrace() et al, tweak context */
@@ -269,10 +282,17 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
                u64 val;
 
                MIPS_FPU_EMU_INC_STATS(loads);
-               if (get_user(val, va)) {
+
+               if (!access_ok(VERIFY_READ, va, sizeof(u64))) {
                        MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = va;
                        return SIGBUS;
                }
+               if (__get_user(val, va)) {
+                       MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = va;
+                       return SIGSEGV;
+               }
                DITOREG(val, MIPSInst_RT(ir));
                break;
        }
@@ -284,10 +304,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
 
                MIPS_FPU_EMU_INC_STATS(stores);
                DIFROMREG(val, MIPSInst_RT(ir));
-               if (put_user(val, va)) {
+               if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) {
                        MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = va;
                        return SIGBUS;
                }
+               if (__put_user(val, va)) {
+                       MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = va;
+                       return SIGSEGV;
+               }
                break;
        }
 
@@ -297,10 +323,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
                u32 val;
 
                MIPS_FPU_EMU_INC_STATS(loads);
-               if (get_user(val, va)) {
+               if (!access_ok(VERIFY_READ, va, sizeof(u32))) {
                        MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = va;
                        return SIGBUS;
                }
+               if (__get_user(val, va)) {
+                       MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = va;
+                       return SIGSEGV;
+               }
                SITOREG(val, MIPSInst_RT(ir));
                break;
        }
@@ -312,10 +344,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
 
                MIPS_FPU_EMU_INC_STATS(stores);
                SIFROMREG(val, MIPSInst_RT(ir));
-               if (put_user(val, va)) {
+               if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) {
                        MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = va;
                        return SIGBUS;
                }
+               if (__put_user(val, va)) {
+                       MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = va;
+                       return SIGSEGV;
+               }
                break;
        }
 
@@ -440,11 +478,18 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
                                contpc = (xcp->cp0_epc +
                                        (MIPSInst_SIMM(ir) << 2));
 
-                               if (get_user(ir,
-                                   (mips_instruction __user *) xcp->cp0_epc)) {
+                               if (!access_ok(VERIFY_READ, xcp->cp0_epc,
+                                              sizeof(mips_instruction))) {
                                        MIPS_FPU_EMU_INC_STATS(errors);
+                                       *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
                                        return SIGBUS;
                                }
+                               if (__get_user(ir,
+                                   (mips_instruction __user *) xcp->cp0_epc)) {
+                                       MIPS_FPU_EMU_INC_STATS(errors);
+                                       *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
+                                       return SIGSEGV;
+                               }
 
                                switch (MIPSInst_OPCODE(ir)) {
                                case lwc1_op:
@@ -506,9 +551,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx)
 
 #if __mips >= 4 && __mips != 32
        case cop1x_op:{
-               int sig;
-
-               if ((sig = fpux_emu(xcp, ctx, ir)))
+               int sig = fpux_emu(xcp, ctx, ir, fault_addr);
+               if (sig)
                        return sig;
                break;
        }
@@ -604,7 +648,7 @@ DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg);
 DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg);
 
 static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
-       mips_instruction ir)
+       mips_instruction ir, void *__user *fault_addr)
 {
        unsigned rcsr = 0;      /* resulting csr */
 
@@ -624,10 +668,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                                xcp->regs[MIPSInst_FT(ir)]);
 
                        MIPS_FPU_EMU_INC_STATS(loads);
-                       if (get_user(val, va)) {
+                       if (!access_ok(VERIFY_READ, va, sizeof(u32))) {
                                MIPS_FPU_EMU_INC_STATS(errors);
+                               *fault_addr = va;
                                return SIGBUS;
                        }
+                       if (__get_user(val, va)) {
+                               MIPS_FPU_EMU_INC_STATS(errors);
+                               *fault_addr = va;
+                               return SIGSEGV;
+                       }
                        SITOREG(val, MIPSInst_FD(ir));
                        break;
 
@@ -638,10 +688,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                        MIPS_FPU_EMU_INC_STATS(stores);
 
                        SIFROMREG(val, MIPSInst_FS(ir));
-                       if (put_user(val, va)) {
+                       if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) {
                                MIPS_FPU_EMU_INC_STATS(errors);
+                               *fault_addr = va;
                                return SIGBUS;
                        }
+                       if (put_user(val, va)) {
+                               MIPS_FPU_EMU_INC_STATS(errors);
+                               *fault_addr = va;
+                               return SIGSEGV;
+                       }
                        break;
 
                case madd_s_op:
@@ -701,10 +757,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                                xcp->regs[MIPSInst_FT(ir)]);
 
                        MIPS_FPU_EMU_INC_STATS(loads);
-                       if (get_user(val, va)) {
+                       if (!access_ok(VERIFY_READ, va, sizeof(u64))) {
                                MIPS_FPU_EMU_INC_STATS(errors);
+                               *fault_addr = va;
                                return SIGBUS;
                        }
+                       if (__get_user(val, va)) {
+                               MIPS_FPU_EMU_INC_STATS(errors);
+                               *fault_addr = va;
+                               return SIGSEGV;
+                       }
                        DITOREG(val, MIPSInst_FD(ir));
                        break;
 
@@ -714,10 +776,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 
                        MIPS_FPU_EMU_INC_STATS(stores);
                        DIFROMREG(val, MIPSInst_FS(ir));
-                       if (put_user(val, va)) {
+                       if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) {
                                MIPS_FPU_EMU_INC_STATS(errors);
+                               *fault_addr = va;
                                return SIGBUS;
                        }
+                       if (__put_user(val, va)) {
+                               MIPS_FPU_EMU_INC_STATS(errors);
+                               *fault_addr = va;
+                               return SIGSEGV;
+                       }
                        break;
 
                case madd_d_op:
@@ -1242,7 +1310,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 }
 
 int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
-       int has_fpu)
+       int has_fpu, void *__user *fault_addr)
 {
        unsigned long oldepc, prevepc;
        mips_instruction insn;
@@ -1252,10 +1320,16 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
        do {
                prevepc = xcp->cp0_epc;
 
-               if (get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) {
+               if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) {
                        MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
                        return SIGBUS;
                }
+               if (__get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) {
+                       MIPS_FPU_EMU_INC_STATS(errors);
+                       *fault_addr = (mips_instruction __user *)xcp->cp0_epc;
+                       return SIGSEGV;
+               }
                if (insn == 0)
                        xcp->cp0_epc += 4;      /* skip nops */
                else {
@@ -1267,7 +1341,7 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
                         */
                        /* convert to ieee library modes */
                        ieee754_csr.rm = ieee_rm[ieee754_csr.rm];
-                       sig = cop1Emulate(xcp, ctx);
+                       sig = cop1Emulate(xcp, ctx, fault_addr);
                        /* revert to mips rounding mode */
                        ieee754_csr.rm = mips_rm[ieee754_csr.rm];
                }
index 4fc1a0fbe0074e154c64a89f8f40d90bd6e1bd91..21ea14efb83747c5275858c6b64a18b6ea040131 100644 (file)
@@ -288,7 +288,7 @@ int mips_dma_supported(struct device *dev, u64 mask)
        return plat_dma_supported(dev, mask);
 }
 
-void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
                         enum dma_data_direction direction)
 {
        BUG_ON(direction == DMA_NONE);
@@ -298,6 +298,8 @@ void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
                __dma_sync((unsigned long)vaddr, size, direction);
 }
 
+EXPORT_SYMBOL(dma_cache_sync);
+
 static struct dma_map_ops mips_default_dma_map_ops = {
        .alloc_coherent = mips_dma_alloc_coherent,
        .free_coherent = mips_dma_free_coherent,
index 505fecad4684f272b7a00d6dd8e3f3098875df4c..9cca8de0054507ca3869071d6bc72dab01e13170 100644 (file)
@@ -68,6 +68,9 @@ static struct bcache_ops mips_sc_ops = {
  */
 static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
 {
+       unsigned int config2 = read_c0_config2();
+       unsigned int tmp;
+
        /* Check the bypass bit (L2B) */
        switch (c->cputype) {
        case CPU_34K:
@@ -83,6 +86,7 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
                c->scache.linesz = 2 << tmp;
        else
                return 0;
+       return 1;
 }
 
 static inline int __init mips_sc_probe(void)
index b7f1d9c4a8a3c7d588b270d6bd6e1bad0590f6b2..434d7b1a8c6a7abf4c492a14b975111a21b1a4ab 100644 (file)
@@ -65,11 +65,15 @@ static unsigned char readb_outer_space(unsigned long long phys)
 
        __asm__ __volatile__ (
        "       .set    mips3           \n"
+       "       .set    push            \n"
+       "       .set    noreorder       \n"
+       "       .set    nomacro         \n"
        "       ld      %0, %1          \n"
+       "       .set    pop             \n"
        "       lbu     %0, (%0)        \n"
        "       .set    mips0           \n"
        : "=r" (res)
-       : "m" (vaddr));
+       : "R" (vaddr));
 
        write_c0_status(sr);
        ssnop_4();
@@ -89,11 +93,15 @@ static void writeb_outer_space(unsigned long long phys, unsigned char c)
 
        __asm__ __volatile__ (
        "       .set    mips3           \n"
+       "       .set    push            \n"
+       "       .set    noreorder       \n"
+       "       .set    nomacro         \n"
        "       ld      %0, %1          \n"
+       "       .set    pop             \n"
        "       sb      %2, (%0)        \n"
        "       .set    mips0           \n"
        : "=&r" (tmp)
-       : "m" (vaddr), "r" (c));
+       : "R" (vaddr), "r" (c));
 
        write_c0_status(sr);
        ssnop_4();
index c308989fc464c3c76a1bc258d38713543c4004c8..41707a245dea61c1cabd467f2bc3d2ec2ca28cd8 100644 (file)
@@ -82,7 +82,7 @@ int swarm_be_handler(struct pt_regs *regs, int is_fixup)
 enum swarm_rtc_type {
        RTC_NONE,
        RTC_XICOR,
-       RTC_M4LT81
+       RTC_M41T81,
 };
 
 enum swarm_rtc_type swarm_rtc_type;
@@ -96,7 +96,7 @@ void read_persistent_clock(struct timespec *ts)
                sec = xicor_get_time();
                break;
 
-       case RTC_M4LT81:
+       case RTC_M41T81:
                sec = m41t81_get_time();
                break;
 
@@ -115,7 +115,7 @@ int rtc_mips_set_time(unsigned long sec)
        case RTC_XICOR:
                return xicor_set_time(sec);
 
-       case RTC_M4LT81:
+       case RTC_M41T81:
                return m41t81_set_time(sec);
 
        case RTC_NONE:
@@ -141,7 +141,7 @@ void __init plat_mem_setup(void)
        if (xicor_probe())
                swarm_rtc_type = RTC_XICOR;
        if (m41t81_probe())
-               swarm_rtc_type = RTC_M4LT81;
+               swarm_rtc_type = RTC_M41T81;
 
 #ifdef CONFIG_VT
        screen_info = (struct screen_info) {
index 7f217b3a50a806b7347f991b588397011aa3388e..2e9d78d21fd36f9648286b2eb46df84beb4c9816 100644 (file)
@@ -22,7 +22,8 @@ config SUPERH
        select HAVE_SPARSE_IRQ
        select RTC_LIB
        select GENERIC_ATOMIC64
-       select GENERIC_HARDIRQS_NO_DEPRECATED
+       # Support the deprecated APIs until MFD and GPIOLIB catch up.
+       select GENERIC_HARDIRQS_NO_DEPRECATED if !MFD_SUPPORT && !GPIOLIB
        help
          The SuperH is a RISC processor targeted for use in embedded systems
          and consumer electronics; it was also used in the Sega Dreamcast
index 903cd618eb740606853662d23765a694044e586c..d6741fca89a4f2d42b763d9789c5b81dc574988e 100644 (file)
 #define __NR_sendmsg           355
 #define __NR_recvmsg           356
 #define __NR_recvmmsg          357
+#define __NR_accept4           358
 
-#define NR_syscalls 358
+#define NR_syscalls 359
 
 #ifdef __KERNEL__
 
index e872e81add8a96ed12709964768a699f8a50306d..6fc347ebe59dfe0a356fe4d2d4f31ea52fa69206 100644 (file)
@@ -375,3 +375,4 @@ ENTRY(sys_call_table)
        .long sys_sendmsg               /* 355 */
        .long sys_recvmsg
        .long sys_recvmmsg
+       .long sys_accept4
index 81cd43432dc0ea5027eb0757ae2e27e2b13c5358..47eaafad15ceb63c8de66a8ef573d8fed32a714d 100644 (file)
@@ -39,7 +39,7 @@ struct linux_dev_v2_funcs {
        int (*v2_dev_open)(char *devpath);
        void (*v2_dev_close)(int d);
        int (*v2_dev_read)(int d, char *buf, int nbytes);
-       int (*v2_dev_write)(int d, char *buf, int nbytes);
+       int (*v2_dev_write)(int d, const char *buf, int nbytes);
        int (*v2_dev_seek)(int d, int hi, int lo);
 
        /* Never issued (multistage load support) */
index 51296a6f5005389877ca17c234f670fa71a3f8c0..9e5c64084b865781ca6782ced49b670ae35a5490 100644 (file)
@@ -60,25 +60,6 @@ extern char *prom_getbootargs(void);
 extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes);
 extern void prom_unmapio(char *virt_addr, unsigned int num_bytes);
 
-/* Device operations. */
-
-/* Open the device described by the passed string.  Note, that the format
- * of the string is different on V0 vs. V2->higher proms.  The caller must
- * know what he/she is doing!  Returns the device descriptor, an int.
- */
-extern int prom_devopen(char *device_string);
-
-/* Close a previously opened device described by the passed integer
- * descriptor.
- */
-extern int prom_devclose(int device_handle);
-
-/* Do a seek operation on the device described by the passed integer
- * descriptor.
- */
-extern void prom_seek(int device_handle, unsigned int seek_hival,
-                     unsigned int seek_lowval);
-
 /* Miscellaneous routines, don't really fit in any category per se. */
 
 /* Reboot the machine with the command line passed. */
@@ -121,19 +102,8 @@ extern int prom_getrev(void);
 /* Get the prom firmware revision. */
 extern int prom_getprev(void);
 
-/* Character operations to/from the console.... */
-
-/* Non-blocking get character from console. */
-extern int prom_nbgetchar(void);
-
-/* Non-blocking put character to console. */
-extern int prom_nbputchar(char character);
-
-/* Blocking get character from console. */
-extern char prom_getchar(void);
-
-/* Blocking put character to console. */
-extern void prom_putchar(char character);
+/* Write a buffer of characters to the console. */
+extern void prom_console_write_buf(const char *buf, int len);
 
 /* Prom's internal routines, don't use in kernel/boot code. */
 extern void prom_printf(const char *fmt, ...);
@@ -238,7 +208,6 @@ extern int prom_node_has_property(phandle node, char *property);
 extern int prom_setprop(phandle node, const char *prop_name, char *prop_value,
                        int value_size);
 
-extern phandle prom_pathtoinode(char *path);
 extern phandle prom_inst2pkg(int);
 
 /* Dorking with Bus ranges... */
index c9cc078e3e31531522fe5d531abcb0b72a1980b2..8cd0df34e82b86ada58f1399a8dab12a260adacb 100644 (file)
@@ -67,27 +67,6 @@ extern void prom_init(void *cif_handler, void *cif_stack);
 /* Boot argument acquisition, returns the boot command line string. */
 extern char *prom_getbootargs(void);
 
-/* Device utilities. */
-
-/* Device operations. */
-
-/* Open the device described by the passed string.  Note, that the format
- * of the string is different on V0 vs. V2->higher proms.  The caller must
- * know what he/she is doing!  Returns the device descriptor, an int.
- */
-extern int prom_devopen(const char *device_string);
-
-/* Close a previously opened device described by the passed integer
- * descriptor.
- */
-extern int prom_devclose(int device_handle);
-
-/* Do a seek operation on the device described by the passed integer
- * descriptor.
- */
-extern void prom_seek(int device_handle, unsigned int seek_hival,
-                     unsigned int seek_lowval);
-
 /* Miscellaneous routines, don't really fit in any category per se. */
 
 /* Reboot the machine with the command line passed. */
@@ -109,33 +88,14 @@ extern void prom_halt(void) __attribute__ ((noreturn));
 /* Halt and power-off the machine. */
 extern void prom_halt_power_off(void) __attribute__ ((noreturn));
 
-/* Set the PROM 'sync' callback function to the passed function pointer.
- * When the user gives the 'sync' command at the prom prompt while the
- * kernel is still active, the prom will call this routine.
- *
- */
-typedef int (*callback_func_t)(long *cmd);
-extern void prom_setcallback(callback_func_t func_ptr);
-
 /* Acquire the IDPROM of the root node in the prom device tree.  This
  * gets passed a buffer where you would like it stuffed.  The return value
  * is the format type of this idprom or 0xff on error.
  */
 extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size);
 
-/* Character operations to/from the console.... */
-
-/* Non-blocking get character from console. */
-extern int prom_nbgetchar(void);
-
-/* Non-blocking put character to console. */
-extern int prom_nbputchar(char character);
-
-/* Blocking get character from console. */
-extern char prom_getchar(void);
-
-/* Blocking put character to console. */
-extern void prom_putchar(char character);
+/* Write a buffer of characters to the console. */
+extern void prom_console_write_buf(const char *buf, int len);
 
 /* Prom's internal routines, don't use in kernel/boot code. */
 extern void prom_printf(const char *fmt, ...);
@@ -279,9 +239,7 @@ extern phandle prom_finddevice(const char *name);
 extern int prom_setprop(phandle node, const char *prop_name, char *prop_value,
                        int value_size);
 
-extern phandle prom_pathtoinode(const char *path);
 extern phandle prom_inst2pkg(int);
-extern int prom_service_exists(const char *service_name);
 extern void prom_sun4v_guest_soft_state(void);
 
 extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
index 2d51527d810fc811531dae33c4bafc281b47d924..f01c42661ee51283183e6b6588297d20a78ec392 100644 (file)
@@ -114,7 +114,7 @@ void __init leon_init_timers(irq_handler_t counter_fn)
        if (leon3_gptimer_regs && leon3_irqctrl_regs) {
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0);
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld,
-                                     (((1000000 / 100) - 1)));
+                                     (((1000000 / HZ) - 1)));
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0);
 
 #ifdef CONFIG_SMP
@@ -128,7 +128,7 @@ void __init leon_init_timers(irq_handler_t counter_fn)
                }
 
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0);
-               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/100) - 1)));
+               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/HZ) - 1)));
                LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0);
 # endif
 
index 1b8c073adb44fe341b883f87865b28531d61b95f..816c0fa12dc0f546b94b58a728a24197adb48d22 100644 (file)
@@ -6,7 +6,6 @@ ccflags := -Werror
 
 lib-y                 := bootstr_$(BITS).o
 lib-$(CONFIG_SPARC32) += devmap.o
-lib-y                 += devops_$(BITS).o
 lib-y                 += init_$(BITS).o
 lib-$(CONFIG_SPARC32) += memory.o
 lib-y                 += misc_$(BITS).o
index 5340264b78f57c79dcd4f031d8348d31e9df1100..48863108a44ce6af379436c7f32ba2063e39a3f2 100644 (file)
 
 extern void restore_current(void);
 
-/* Non blocking get character from console input device, returns -1
- * if no input was taken.  This can be used for polling.
- */
-int
-prom_nbgetchar(void)
-{
-       static char inc;
-       int i = -1;
-       unsigned long flags;
-
-       spin_lock_irqsave(&prom_lock, flags);
-       switch(prom_vers) {
-       case PROM_V0:
-               i = (*(romvec->pv_nbgetchar))();
-               break;
-       case PROM_V2:
-       case PROM_V3:
-               if( (*(romvec->pv_v2devops).v2_dev_read)(*romvec->pv_v2bootargs.fd_stdin , &inc, 0x1) == 1) {
-                       i = inc;
-               } else {
-                       i = -1;
-               }
-               break;
-       default:
-               i = -1;
-               break;
-       };
-       restore_current();
-       spin_unlock_irqrestore(&prom_lock, flags);
-       return i; /* Ugh, we could spin forever on unsupported proms ;( */
-}
-
 /* Non blocking put character to console device, returns -1 if
  * unsuccessful.
  */
-int
-prom_nbputchar(char c)
+static int prom_nbputchar(const char *buf)
 {
-       static char outc;
        unsigned long flags;
        int i = -1;
 
        spin_lock_irqsave(&prom_lock, flags);
        switch(prom_vers) {
        case PROM_V0:
-               i = (*(romvec->pv_nbputchar))(c);
+               i = (*(romvec->pv_nbputchar))(*buf);
                break;
        case PROM_V2:
        case PROM_V3:
-               outc = c;
-               if( (*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, &outc, 0x1) == 1)
+               if ((*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout,
+                                                         buf, 0x1) == 1)
                        i = 0;
-               else
-                       i = -1;
                break;
        default:
-               i = -1;
                break;
        };
        restore_current();
@@ -80,18 +43,14 @@ prom_nbputchar(char c)
        return i; /* Ugh, we could spin forever on unsupported proms ;( */
 }
 
-/* Blocking version of get character routine above. */
-char
-prom_getchar(void)
+void prom_console_write_buf(const char *buf, int len)
 {
-       int character;
-       while((character = prom_nbgetchar()) == -1) ;
-       return (char) character;
+       while (len) {
+               int n = prom_nbputchar(buf);
+               if (n)
+                       continue;
+               len--;
+               buf++;
+       }
 }
 
-/* Blocking version of put character routine above. */
-void
-prom_putchar(char c)
-{
-       while(prom_nbputchar(c) == -1) ;
-}
index 10322dc2f557a22d5befcc17dd4a27d8b6604f89..ed39e75828bd1eb6057f192d052ab88f5b943ddd 100644 (file)
 
 extern int prom_stdin, prom_stdout;
 
-/* Non blocking get character from console input device, returns -1
- * if no input was taken.  This can be used for polling.
- */
-inline int
-prom_nbgetchar(void)
-{
-       unsigned long args[7];
-       char inc;
-
-       args[0] = (unsigned long) "read";
-       args[1] = 3;
-       args[2] = 1;
-       args[3] = (unsigned int) prom_stdin;
-       args[4] = (unsigned long) &inc;
-       args[5] = 1;
-       args[6] = (unsigned long) -1;
-
-       p1275_cmd_direct(args);
-
-       if (args[6] == 1)
-               return inc;
-       return -1;
-}
-
-/* Non blocking put character to console device, returns -1 if
- * unsuccessful.
- */
-inline int
-prom_nbputchar(char c)
+static int __prom_console_write_buf(const char *buf, int len)
 {
        unsigned long args[7];
-       char outc;
-       
-       outc = c;
+       int ret;
 
        args[0] = (unsigned long) "write";
        args[1] = 3;
        args[2] = 1;
        args[3] = (unsigned int) prom_stdout;
-       args[4] = (unsigned long) &outc;
-       args[5] = 1;
+       args[4] = (unsigned long) buf;
+       args[5] = (unsigned int) len;
        args[6] = (unsigned long) -1;
 
        p1275_cmd_direct(args);
 
-       if (args[6] == 1)
-               return 0;
-       else
+       ret = (int) args[6];
+       if (ret < 0)
                return -1;
+       return ret;
 }
 
-/* Blocking version of get character routine above. */
-char
-prom_getchar(void)
-{
-       int character;
-       while((character = prom_nbgetchar()) == -1) ;
-       return (char) character;
-}
-
-/* Blocking version of put character routine above. */
-void
-prom_putchar(char c)
+void prom_console_write_buf(const char *buf, int len)
 {
-       prom_nbputchar(c);
-}
-
-void
-prom_puts(const char *s, int len)
-{
-       unsigned long args[7];
-
-       args[0] = (unsigned long) "write";
-       args[1] = 3;
-       args[2] = 1;
-       args[3] = (unsigned int) prom_stdout;
-       args[4] = (unsigned long) s;
-       args[5] = len;
-       args[6] = (unsigned long) -1;
-
-       p1275_cmd_direct(args);
+       while (len) {
+               int n = __prom_console_write_buf(buf, len);
+               if (n < 0)
+                       continue;
+               len -= n;
+               buf += len;
+       }
 }
diff --git a/arch/sparc/prom/devops_32.c b/arch/sparc/prom/devops_32.c
deleted file mode 100644 (file)
index 9c5d468..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * devops.c:  Device operations using the PROM.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-
-extern void restore_current(void);
-
-/* Open the device described by the string 'dstr'.  Returns the handle
- * to that device used for subsequent operations on that device.
- * Returns -1 on failure.
- */
-int
-prom_devopen(char *dstr)
-{
-       int handle;
-       unsigned long flags;
-       spin_lock_irqsave(&prom_lock, flags);
-       switch(prom_vers) {
-       case PROM_V0:
-               handle = (*(romvec->pv_v0devops.v0_devopen))(dstr);
-               if(handle == 0) handle = -1;
-               break;
-       case PROM_V2:
-       case PROM_V3:
-               handle = (*(romvec->pv_v2devops.v2_dev_open))(dstr);
-               break;
-       default:
-               handle = -1;
-               break;
-       };
-       restore_current();
-       spin_unlock_irqrestore(&prom_lock, flags);
-
-       return handle;
-}
-
-/* Close the device described by device handle 'dhandle'. */
-int
-prom_devclose(int dhandle)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&prom_lock, flags);
-       switch(prom_vers) {
-       case PROM_V0:
-               (*(romvec->pv_v0devops.v0_devclose))(dhandle);
-               break;
-       case PROM_V2:
-       case PROM_V3:
-               (*(romvec->pv_v2devops.v2_dev_close))(dhandle);
-               break;
-       default:
-               break;
-       };
-       restore_current();
-       spin_unlock_irqrestore(&prom_lock, flags);
-       return 0;
-}
-
-/* Seek to specified location described by 'seekhi' and 'seeklo'
- * for device 'dhandle'.
- */
-void
-prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&prom_lock, flags);
-       switch(prom_vers) {
-       case PROM_V0:
-               (*(romvec->pv_v0devops.v0_seekdev))(dhandle, seekhi, seeklo);
-               break;
-       case PROM_V2:
-       case PROM_V3:
-               (*(romvec->pv_v2devops.v2_dev_seek))(dhandle, seekhi, seeklo);
-               break;
-       default:
-               break;
-       };
-       restore_current();
-       spin_unlock_irqrestore(&prom_lock, flags);
-}
diff --git a/arch/sparc/prom/devops_64.c b/arch/sparc/prom/devops_64.c
deleted file mode 100644 (file)
index a017119..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * devops.c:  Device operations using the PROM.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-
-/* Open the device described by the string 'dstr'.  Returns the handle
- * to that device used for subsequent operations on that device.
- * Returns 0 on failure.
- */
-int
-prom_devopen(const char *dstr)
-{
-       unsigned long args[5];
-
-       args[0] = (unsigned long) "open";
-       args[1] = 1;
-       args[2] = 1;
-       args[3] = (unsigned long) dstr;
-       args[4] = (unsigned long) -1;
-
-       p1275_cmd_direct(args);
-
-       return (int) args[4];
-}
-
-/* Close the device described by device handle 'dhandle'. */
-int
-prom_devclose(int dhandle)
-{
-       unsigned long args[4];
-
-       args[0] = (unsigned long) "close";
-       args[1] = 1;
-       args[2] = 0;
-       args[3] = (unsigned int) dhandle;
-
-       p1275_cmd_direct(args);
-
-       return 0;
-}
-
-/* Seek to specified location described by 'seekhi' and 'seeklo'
- * for device 'dhandle'.
- */
-void
-prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
-{
-       unsigned long args[7];
-
-       args[0] = (unsigned long) "seek";
-       args[1] = 3;
-       args[2] = 1;
-       args[3] = (unsigned int) dhandle;
-       args[4] = seekhi;
-       args[5] = seeklo;
-       args[6] = (unsigned long) -1;
-
-       p1275_cmd_direct(args);
-}
index d24bc44e361ee20b654960cc7784176670705da6..e4f31d4d3715cc5c27752633ba58e052e853a956 100644 (file)
@@ -18,7 +18,7 @@
 #include <asm/system.h>
 #include <asm/ldc.h>
 
-int prom_service_exists(const char *service_name)
+static int prom_service_exists(const char *service_name)
 {
        unsigned long args[5];
 
@@ -150,20 +150,6 @@ void prom_halt_power_off(void)
        prom_halt();
 }
 
-/* Set prom sync handler to call function 'funcp'. */
-void prom_setcallback(callback_func_t funcp)
-{
-       unsigned long args[5];
-       if (!funcp)
-               return;
-       args[0] = (unsigned long) "set-callback";
-       args[1] = 1;
-       args[2] = 1;
-       args[3] = (unsigned long) funcp;
-       args[4] = (unsigned long) -1;
-       p1275_cmd_direct(args);
-}
-
 /* Get the idprom and stuff it into buffer 'idbuf'.  Returns the
  * format type.  'num_bytes' is the number of bytes that your idbuf
  * has space for.  Returns 0xff on error.
index ca869266b9f3d0106e60d7b8c28f5cdcf614826b..d9682f06b3b056c7862ec7cda4214a95ab213a03 100644 (file)
 
 #include <linux/kernel.h>
 #include <linux/compiler.h>
+#include <linux/spinlock.h>
 
 #include <asm/openprom.h>
 #include <asm/oplib.h>
 
+#define CONSOLE_WRITE_BUF_SIZE 1024
+
 static char ppbuf[1024];
+static char console_write_buf[CONSOLE_WRITE_BUF_SIZE];
+static DEFINE_RAW_SPINLOCK(console_write_lock);
 
 void notrace prom_write(const char *buf, unsigned int n)
 {
-       char ch;
+       unsigned int dest_len;
+       unsigned long flags;
+       char *dest;
+
+       dest = console_write_buf;
+       raw_spin_lock_irqsave(&console_write_lock, flags);
 
-       while (n != 0) {
-               --n;
-               if ((ch = *buf++) == '\n')
-                       prom_putchar('\r');
-               prom_putchar(ch);
+       dest_len = 0;
+       while (n-- != 0) {
+               char ch = *buf++;
+               if (ch == '\n') {
+                       *dest++ = '\r';
+                       dest_len++;
+               }
+               *dest++ = ch;
+               dest_len++;
+               if (dest_len >= CONSOLE_WRITE_BUF_SIZE - 1) {
+                       prom_console_write_buf(console_write_buf, dest_len);
+                       dest = console_write_buf;
+                       dest_len = 0;
+               }
        }
+       if (dest_len)
+               prom_console_write_buf(console_write_buf, dest_len);
+
+       raw_spin_unlock_irqrestore(&console_write_lock, flags);
 }
 
 void notrace prom_printf(const char *fmt, ...)
index 63e08e149774fc6a0a30fcd9228abb83f434aae7..535e2e69ac1d8287470356218511c25af6be7a8c 100644 (file)
@@ -342,19 +342,3 @@ phandle prom_inst2pkg(int inst)
        if (node == -1) return 0;
        return node;
 }
-
-/* Return 'node' assigned to a particular prom 'path'
- * FIXME: Should work for v0 as well
- */
-phandle prom_pathtoinode(char *path)
-{
-       phandle node;
-       int inst;
-       
-       inst = prom_devopen (path);
-       if (inst == -1) return 0;
-       node = prom_inst2pkg (inst);
-       prom_devclose (inst);
-       if (node == -1) return 0;
-       return node;
-}
index 691be68932f84cf7d804b2a7ce6720fceeedc447..d93660048376c9d9bf4478720a6825e9e7b117ed 100644 (file)
@@ -374,24 +374,6 @@ inline phandle prom_inst2pkg(int inst)
        return node;
 }
 
-/* Return 'node' assigned to a particular prom 'path'
- * FIXME: Should work for v0 as well
- */
-phandle prom_pathtoinode(const char *path)
-{
-       phandle node;
-       int inst;
-
-       inst = prom_devopen (path);
-       if (inst == 0)
-               return 0;
-       node = prom_inst2pkg(inst);
-       prom_devclose(inst);
-       if (node == -1)
-               return 0;
-       return node;
-}
-
 int prom_ihandle2path(int handle, char *buffer, int bufsize)
 {
        unsigned long args[7];
index c1ee1d61d44ca8a07c504b9af425df3a9c7185c7..81d92a45cd4b613e2c18add9afe153e43a5d703e 100644 (file)
@@ -25,7 +25,7 @@
 
 #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
 struct pt_regs;
-int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *);
+int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
 int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
 void do_signal(struct pt_regs *regs);
 #endif
index 543d6a33aa26f6c02f7f41f59fcdceea1729bcd8..dbb0dfc7beceb10eaa25fd4b73579cdc620334c5 100644 (file)
@@ -290,12 +290,12 @@ long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
        return ret;
 }
 
+/* The assembly shim for this function arranges to ignore the return value. */
 long compat_sys_rt_sigreturn(struct pt_regs *regs)
 {
        struct compat_rt_sigframe __user *frame =
                (struct compat_rt_sigframe __user *) compat_ptr(regs->sp);
        sigset_t set;
-       long r0;
 
        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
                goto badframe;
@@ -308,13 +308,13 @@ long compat_sys_rt_sigreturn(struct pt_regs *regs)
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
 
-       if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
+       if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
                goto badframe;
 
        if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0)
                goto badframe;
 
-       return r0;
+       return 0;
 
 badframe:
        force_sig(SIGSEGV, current);
index f5821626247fee9891d47eca123b26440f6c025c..5eed4a02bf62335e17a39f663cd4485869f44ea5 100644 (file)
@@ -1342,8 +1342,8 @@ handle_syscall:
        lw      r20, r20
 
        /* Jump to syscall handler. */
-       jalr    r20; .Lhandle_syscall_link:
-       FEEDBACK_REENTER(handle_syscall)
+       jalr    r20
+.Lhandle_syscall_link: /* value of "lr" after "jalr r20" above */
 
        /*
         * Write our r0 onto the stack so it gets restored instead
@@ -1352,6 +1352,9 @@ handle_syscall:
        PTREGS_PTR(r29, PTREGS_OFFSET_REG(0))
        sw      r29, r0
 
+.Lsyscall_sigreturn_skip:
+       FEEDBACK_REENTER(handle_syscall)
+
        /* Do syscall trace again, if requested. */
        lw      r30, r31
        andi    r30, r30, _TIF_SYSCALL_TRACE
@@ -1536,9 +1539,24 @@ STD_ENTRY_LOCAL(bad_intr)
        };                                              \
        STD_ENDPROC(_##x)
 
+/*
+ * Special-case sigreturn to not write r0 to the stack on return.
+ * This is technically more efficient, but it also avoids difficulties
+ * in the 64-bit OS when handling 32-bit compat code, since we must not
+ * sign-extend r0 for the sigreturn return-value case.
+ */
+#define PTREGS_SYSCALL_SIGRETURN(x, reg)                \
+       STD_ENTRY(_##x);                                \
+       addli   lr, lr, .Lsyscall_sigreturn_skip - .Lhandle_syscall_link; \
+       {                                               \
+        PTREGS_PTR(reg, PTREGS_OFFSET_BASE);           \
+        j      x                                       \
+       };                                              \
+       STD_ENDPROC(_##x)
+
 PTREGS_SYSCALL(sys_execve, r3)
 PTREGS_SYSCALL(sys_sigaltstack, r2)
-PTREGS_SYSCALL(sys_rt_sigreturn, r0)
+PTREGS_SYSCALL_SIGRETURN(sys_rt_sigreturn, r0)
 PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1)
 
 /* Save additional callee-saves to pt_regs, put address in r4 and jump. */
index 8430f45daea6bce566cc0980db85f0d0b213af72..e90eb53173b0b5e1c2f7c3ba60ad4be38940a34d 100644 (file)
@@ -211,6 +211,13 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
        childregs->regs[0] = 0;         /* return value is zero */
        childregs->sp = sp;  /* override with new user stack pointer */
 
+       /*
+        * If CLONE_SETTLS is set, set "tp" in the new task to "r4",
+        * which is passed in as arg #5 to sys_clone().
+        */
+       if (clone_flags & CLONE_SETTLS)
+               childregs->tp = regs->regs[4];
+
        /*
         * Copy the callee-saved registers from the passed pt_regs struct
         * into the context-switch callee-saved registers area.
@@ -539,6 +546,7 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
        return __switch_to(prev, next, next_current_ksp0(next));
 }
 
+/* Note there is an implicit fifth argument if (clone_flags & CLONE_SETTLS). */
 SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
                void __user *, parent_tidptr, void __user *, child_tidptr,
                struct pt_regs *, regs)
index 757407e36696688d59810453b1ffca8da8522a62..1260321155f1d591b85131f44d9c72ad31122626 100644 (file)
@@ -52,7 +52,7 @@ SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss,
  */
 
 int restore_sigcontext(struct pt_regs *regs,
-                      struct sigcontext __user *sc, long *pr0)
+                      struct sigcontext __user *sc)
 {
        int err = 0;
        int i;
@@ -75,17 +75,15 @@ int restore_sigcontext(struct pt_regs *regs,
 
        regs->faultnum = INT_SWINT_1_SIGRETURN;
 
-       err |= __get_user(*pr0, &sc->gregs[0]);
        return err;
 }
 
-/* sigreturn() returns long since it restores r0 in the interrupted code. */
+/* The assembly shim for this function arranges to ignore the return value. */
 SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
 {
        struct rt_sigframe __user *frame =
                (struct rt_sigframe __user *)(regs->sp);
        sigset_t set;
-       long r0;
 
        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
                goto badframe;
@@ -98,13 +96,13 @@ SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
 
-       if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
+       if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
                goto badframe;
 
        if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
                goto badframe;
 
-       return r0;
+       return 0;
 
 badframe:
        force_sig(SIGSEGV, current);
index cbcc8d8ea93a9144471fede4aeca15bdb4780203..7a6e68e4f748fc2db4af59f42d4c1caad9460060 100644 (file)
@@ -10,6 +10,7 @@
  * by the Free Software Foundation.
  */
 
+#include <linux/err.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
index 5be1542fbfaf73bfccd03a101e94a1cca47d36b0..e99d55d74df5023d72b763ca244c9d17bbd1dd53 100644 (file)
@@ -72,6 +72,9 @@ struct e820map {
 #define BIOS_BEGIN             0x000a0000
 #define BIOS_END               0x00100000
 
+#define BIOS_ROM_BASE          0xffe00000
+#define BIOS_ROM_END           0xffffffff
+
 #ifdef __KERNEL__
 /* see comment in arch/x86/kernel/e820.c */
 extern struct e820map e820;
index 9e6fe391094e545eb41b9fa295df93a827c1fa30..f702f82aa1ebf5df3905ca32ac9326be76c03b91 100644 (file)
@@ -79,7 +79,7 @@
 #define KVM_NUM_MMU_PAGES (1 << KVM_MMU_HASH_SHIFT)
 #define KVM_MIN_FREE_MMU_PAGES 5
 #define KVM_REFILL_PAGES 25
-#define KVM_MAX_CPUID_ENTRIES 40
+#define KVM_MAX_CPUID_ENTRIES 80
 #define KVM_NR_FIXED_MTRR_REGION 88
 #define KVM_NR_VAR_MTRR 8
 
index 9e13763b609242e0c5429a364be461a7e8fc2594..1e994754d323f400b85c5d1d7350c6e52a702ff9 100644 (file)
@@ -45,6 +45,7 @@ obj-y                 += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
 obj-y                  += alternative.o i8253.o pci-nommu.o hw_breakpoint.o
 obj-y                  += tsc.o io_delay.o rtc.o
 obj-y                  += pci-iommu_table.o
+obj-y                  += resource.o
 
 obj-$(CONFIG_X86_TRAMPOLINE)   += trampoline.o
 obj-y                          += process.o
index d7cdf5bc1e637f9db85423fa70fef6b884d76f28..c0dbd9ac24f0d5cf7e87f8f0439275656b877f73 100644 (file)
@@ -622,13 +622,13 @@ ENTRY(initial_code)
 __PAGE_ALIGNED_BSS
        .align PAGE_SIZE_asm
 #ifdef CONFIG_X86_PAE
-initial_pg_pmd:
+ENTRY(initial_pg_pmd)
        .fill 1024*KPMDS,4,0
 #else
 ENTRY(initial_page_table)
        .fill 1024,4,0
 #endif
-initial_pg_fixmap:
+ENTRY(initial_pg_fixmap)
        .fill 1024,4,0
 ENTRY(empty_zero_page)
        .fill 4096,1,0
diff --git a/arch/x86/kernel/resource.c b/arch/x86/kernel/resource.c
new file mode 100644 (file)
index 0000000..2a26819
--- /dev/null
@@ -0,0 +1,48 @@
+#include <linux/ioport.h>
+#include <asm/e820.h>
+
+static void resource_clip(struct resource *res, resource_size_t start,
+                         resource_size_t end)
+{
+       resource_size_t low = 0, high = 0;
+
+       if (res->end < start || res->start > end)
+               return;         /* no conflict */
+
+       if (res->start < start)
+               low = start - res->start;
+
+       if (res->end > end)
+               high = res->end - end;
+
+       /* Keep the area above or below the conflict, whichever is larger */
+       if (low > high)
+               res->end = start - 1;
+       else
+               res->start = end + 1;
+}
+
+static void remove_e820_regions(struct resource *avail)
+{
+       int i;
+       struct e820entry *entry;
+
+       for (i = 0; i < e820.nr_map; i++) {
+               entry = &e820.map[i];
+
+               resource_clip(avail, entry->addr,
+                             entry->addr + entry->size - 1);
+       }
+}
+
+void arch_remove_reservations(struct resource *avail)
+{
+       /* Trim out BIOS areas (low 1MB and high 2MB) and E820 regions */
+       if (avail->flags & IORESOURCE_MEM) {
+               if (avail->start < BIOS_END)
+                       avail->start = BIOS_END;
+               resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END);
+
+               remove_e820_regions(avail);
+       }
+}
index 21c6746338afef0949e89f8b2c0442654401546e..85268f8eadf667c6034c06882ed661cb7d03e4a8 100644 (file)
@@ -769,7 +769,6 @@ void __init setup_arch(char **cmdline_p)
 
        x86_init.oem.arch_setup();
 
-       resource_alloc_from_bottom = 0;
        iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1;
        setup_memory_map();
        parse_setup_data();
index 1ca12298ffc74f2d783effb35da0953163bbb314..b81a9b7c2ca486f3faa8d8c8314ef4e1115e69e3 100644 (file)
@@ -3494,6 +3494,10 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu)
 static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)
 {
        switch (func) {
+       case 0x00000001:
+               /* Mask out xsave bit as long as it is not supported by SVM */
+               entry->ecx &= ~(bit(X86_FEATURE_XSAVE));
+               break;
        case 0x80000001:
                if (nested)
                        entry->ecx |= (1 << 2); /* Set SVM bit */
index ff21fdda0c53b6dbf2ca84b1e4e2300e2a659b90..81fcbe9515c59d7e68734d2d4c53fa23bb72624a 100644 (file)
@@ -4227,11 +4227,6 @@ static int vmx_get_lpage_level(void)
                return PT_PDPE_LEVEL;
 }
 
-static inline u32 bit(int bitno)
-{
-       return 1 << (bitno & 31);
-}
-
 static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
 {
        struct kvm_cpuid_entry2 *best;
index cdac9e592aa53ee84b7e184900601ab4730354e5..b989e1f1e5d36b732d1d9c864f369b39a7459105 100644 (file)
@@ -155,11 +155,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
 
 u64 __read_mostly host_xcr0;
 
-static inline u32 bit(int bitno)
-{
-       return 1 << (bitno & 31);
-}
-
 static void kvm_on_user_return(struct user_return_notifier *urn)
 {
        unsigned slot;
@@ -4569,9 +4564,11 @@ static void kvm_timer_init(void)
 #ifdef CONFIG_CPU_FREQ
                struct cpufreq_policy policy;
                memset(&policy, 0, sizeof(policy));
-               cpufreq_get_policy(&policy, get_cpu());
+               cpu = get_cpu();
+               cpufreq_get_policy(&policy, cpu);
                if (policy.cpuinfo.max_freq)
                        max_tsc_khz = policy.cpuinfo.max_freq;
+               put_cpu();
 #endif
                cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block,
                                          CPUFREQ_TRANSITION_NOTIFIER);
@@ -5522,6 +5519,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 
        mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4;
        kvm_x86_ops->set_cr4(vcpu, sregs->cr4);
+       if (sregs->cr4 & X86_CR4_OSXSAVE)
+               update_cpuid(vcpu);
        if (!is_long_mode(vcpu) && is_pae(vcpu)) {
                load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3);
                mmu_reset_needed = 1;
index 2cea414489f37caa75876e7a186e00ac93937ec1..c600da830ce0e412fa4b60365909792a9b916a4d 100644 (file)
@@ -70,6 +70,11 @@ static inline int is_paging(struct kvm_vcpu *vcpu)
        return kvm_read_cr0_bits(vcpu, X86_CR0_PG);
 }
 
+static inline u32 bit(int bitno)
+{
+       return 1 << (bitno & 31);
+}
+
 void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
 void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
 int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq);
index 73b1e1a1f4891708a8714570e36ce62b15ba6fc7..4996cf5f73a07db446c2fe3e1c9fe7070662b741 100644 (file)
@@ -531,7 +531,10 @@ static void lguest_write_cr3(unsigned long cr3)
 {
        lguest_data.pgdir = cr3;
        lazy_hcall1(LHCALL_NEW_PGTABLE, cr3);
-       cr3_changed = true;
+
+       /* These two page tables are simple, linear, and used during boot */
+       if (cr3 != __pa(swapper_pg_dir) && cr3 != __pa(initial_page_table))
+               cr3_changed = true;
 }
 
 static unsigned long lguest_read_cr3(void)
@@ -703,9 +706,9 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval)
  * to forget all of them.  Fortunately, this is very rare.
  *
  * ... except in early boot when the kernel sets up the initial pagetables,
- * which makes booting astonishingly slow: 1.83 seconds!  So we don't even tell
- * the Host anything changed until we've done the first page table switch,
- * which brings boot back to 0.25 seconds.
+ * which makes booting astonishingly slow: 48 seconds!  So we don't even tell
+ * the Host anything changed until we've done the first real page table switch,
+ * which brings boot back to 4.3 seconds.
  */
 static void lguest_set_pte(pte_t *ptep, pte_t pteval)
 {
@@ -1002,7 +1005,7 @@ static void lguest_time_init(void)
        clockevents_register_device(&lguest_clockevent);
 
        /* Finally, we unblock the timer interrupt. */
-       enable_lguest_irq(0);
+       clear_bit(0, lguest_data.blocked_interrupts);
 }
 
 /*
@@ -1349,9 +1352,6 @@ __init void lguest_init(void)
         */
        switch_to_new_gdt(0);
 
-       /* We actually boot with all memory mapped, but let's say 128MB. */
-       max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT;
-
        /*
         * The Host<->Guest Switcher lives at the top of our address space, and
         * the Host told us how big it is when we made LGUEST_INIT hypercall:
index 4f420c2f2d5534ea4ac5af20292e25c4346c3cda..e7d5382ef26344534b0883a11d02b19a82d4a9cd 100644 (file)
@@ -4,6 +4,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/thread_info.h>
 #include <asm/processor-flags.h>
+#include <asm/pgtable.h>
 
 /*G:020
  * Our story starts with the kernel booting into startup_32 in
@@ -37,9 +38,113 @@ ENTRY(lguest_entry)
        /* Set up the initial stack so we can run C code. */
        movl $(init_thread_union+THREAD_SIZE),%esp
 
+       call init_pagetables
+
        /* Jumps are relative: we're running __PAGE_OFFSET too low. */
        jmp lguest_init+__PAGE_OFFSET
 
+/*
+ * Initialize page tables.  This creates a PDE and a set of page
+ * tables, which are located immediately beyond __brk_base.  The variable
+ * _brk_end is set up to point to the first "safe" location.
+ * Mappings are created both at virtual address 0 (identity mapping)
+ * and PAGE_OFFSET for up to _end.
+ *
+ * FIXME: This code is taken verbatim from arch/x86/kernel/head_32.S: they
+ * don't have a stack at this point, so we can't just use call and ret.
+ */
+init_pagetables:
+#if PTRS_PER_PMD > 1
+#define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD)
+#else
+#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
+#endif
+#define pa(X) ((X) - __PAGE_OFFSET)
+
+/* Enough space to fit pagetables for the low memory linear map */
+MAPPING_BEYOND_END = \
+       PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT
+#ifdef CONFIG_X86_PAE
+
+       /*
+        * In PAE mode initial_page_table is statically defined to contain
+        * enough entries to cover the VMSPLIT option (that is the top 1, 2 or 3
+        * entries). The identity mapping is handled by pointing two PGD entries
+        * to the first kernel PMD.
+        *
+        * Note the upper half of each PMD or PTE are always zero at this stage.
+        */
+
+#define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */
+
+       xorl %ebx,%ebx                          /* %ebx is kept at zero */
+
+       movl $pa(__brk_base), %edi
+       movl $pa(initial_pg_pmd), %edx
+       movl $PTE_IDENT_ATTR, %eax
+10:
+       leal PDE_IDENT_ATTR(%edi),%ecx          /* Create PMD entry */
+       movl %ecx,(%edx)                        /* Store PMD entry */
+                                               /* Upper half already zero */
+       addl $8,%edx
+       movl $512,%ecx
+11:
+       stosl
+       xchgl %eax,%ebx
+       stosl
+       xchgl %eax,%ebx
+       addl $0x1000,%eax
+       loop 11b
+
+       /*
+        * End condition: we must map up to the end + MAPPING_BEYOND_END.
+        */
+       movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
+       cmpl %ebp,%eax
+       jb 10b
+1:
+       addl $__PAGE_OFFSET, %edi
+       movl %edi, pa(_brk_end)
+       shrl $12, %eax
+       movl %eax, pa(max_pfn_mapped)
+
+       /* Do early initialization of the fixmap area */
+       movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
+       movl %eax,pa(initial_pg_pmd+0x1000*KPMDS-8)
+#else  /* Not PAE */
+
+page_pde_offset = (__PAGE_OFFSET >> 20);
+
+       movl $pa(__brk_base), %edi
+       movl $pa(initial_page_table), %edx
+       movl $PTE_IDENT_ATTR, %eax
+10:
+       leal PDE_IDENT_ATTR(%edi),%ecx          /* Create PDE entry */
+       movl %ecx,(%edx)                        /* Store identity PDE entry */
+       movl %ecx,page_pde_offset(%edx)         /* Store kernel PDE entry */
+       addl $4,%edx
+       movl $1024, %ecx
+11:
+       stosl
+       addl $0x1000,%eax
+       loop 11b
+       /*
+        * End condition: we must map up to the end + MAPPING_BEYOND_END.
+        */
+       movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
+       cmpl %ebp,%eax
+       jb 10b
+       addl $__PAGE_OFFSET, %edi
+       movl %edi, pa(_brk_end)
+       shrl $12, %eax
+       movl %eax, pa(max_pfn_mapped)
+
+       /* Do early initialization of the fixmap area */
+       movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
+       movl %eax,pa(initial_page_table+0xffc)
+#endif
+       ret
+
 /*G:055
  * We create a macro which puts the assembler code between lgstart_ and lgend_
  * markers.  These templates are put in the .text section: they can't be
index c4bb261c106e16eaeab09092a9942418dba61133..b1805b78842fec1efd9da3a1cebfca74c4b25371 100644 (file)
@@ -65,21 +65,13 @@ pcibios_align_resource(void *data, const struct resource *res,
                        resource_size_t size, resource_size_t align)
 {
        struct pci_dev *dev = data;
-       resource_size_t start = round_down(res->end - size + 1, align);
+       resource_size_t start = res->start;
 
        if (res->flags & IORESOURCE_IO) {
-
-               /*
-                * If we're avoiding ISA aliases, the largest contiguous I/O
-                * port space is 256 bytes.  Clearing bits 9 and 10 preserves
-                * all 256-byte and smaller alignments, so the result will
-                * still be correctly aligned.
-                */
-               if (!skip_isa_ioresource_align(dev))
-                       start &= ~0x300;
-       } else if (res->flags & IORESOURCE_MEM) {
-               if (start < BIOS_END)
-                       start = res->end;       /* fail; no space */
+               if (skip_isa_ioresource_align(dev))
+                       return start;
+               if (start & 0x300)
+                       start = (start + 0x3ff) & ~0x3ff;
        }
        return start;
 }
index f20d6a789d484591e9fdb5642fa893c233c2b9b0..0c8b64a16484721308587c7a6b635344a9144a1e 100644 (file)
@@ -250,6 +250,14 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
        int ret, rw;
        unsigned int dxfer_len;
        void *dxferp = NULL;
+       struct bsg_class_device *bcd = &q->bsg_dev;
+
+       /* if the LLD has been removed then the bsg_unregister_queue will
+        * eventually be called and the class_dev was freed, so we can no
+        * longer use this request_queue. Return no such address.
+        */
+       if (!bcd->class_dev)
+               return ERR_PTR(-ENXIO);
 
        dprintk("map hdr %llx/%u %llx/%u\n", (unsigned long long) hdr->dout_xferp,
                hdr->dout_xfer_len, (unsigned long long) hdr->din_xferp,
index ba9afeaa23acfb676021c86432fd89b45f8ba5cf..25d3aaebc10d4d86238c0af67bcb01976b6dcd65 100644 (file)
@@ -100,24 +100,7 @@ static const struct file_operations acpi_ac_fops = {
        .release = single_release,
 };
 #endif
-static int get_ac_property(struct power_supply *psy,
-                          enum power_supply_property psp,
-                          union power_supply_propval *val)
-{
-       struct acpi_ac *ac = to_acpi_ac(psy);
-       switch (psp) {
-       case POWER_SUPPLY_PROP_ONLINE:
-               val->intval = ac->state;
-               break;
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
 
-static enum power_supply_property ac_props[] = {
-       POWER_SUPPLY_PROP_ONLINE,
-};
 /* --------------------------------------------------------------------------
                                AC Adapter Management
    -------------------------------------------------------------------------- */
@@ -140,6 +123,35 @@ static int acpi_ac_get_state(struct acpi_ac *ac)
        return 0;
 }
 
+/* --------------------------------------------------------------------------
+                            sysfs I/F
+   -------------------------------------------------------------------------- */
+static int get_ac_property(struct power_supply *psy,
+                          enum power_supply_property psp,
+                          union power_supply_propval *val)
+{
+       struct acpi_ac *ac = to_acpi_ac(psy);
+
+       if (!ac)
+               return -ENODEV;
+
+       if (acpi_ac_get_state(ac))
+               return -ENODEV;
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_ONLINE:
+               val->intval = ac->state;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static enum power_supply_property ac_props[] = {
+       POWER_SUPPLY_PROP_ONLINE,
+};
+
 #ifdef CONFIG_ACPI_PROCFS_POWER
 /* --------------------------------------------------------------------------
                               FS Interface (/proc)
index 1211c03149e8c7c258fee89dd1109e1e6b901c26..5850d320404c35b9c7318eb0619ae54c7e32a30b 100644 (file)
@@ -86,7 +86,7 @@ static struct erst_erange {
  * It is used to provide exclusive accessing for ERST Error Log
  * Address Range too.
  */
-static DEFINE_SPINLOCK(erst_lock);
+static DEFINE_RAW_SPINLOCK(erst_lock);
 
 static inline int erst_errno(int command_status)
 {
@@ -421,9 +421,9 @@ ssize_t erst_get_record_count(void)
        if (erst_disable)
                return -ENODEV;
 
-       spin_lock_irqsave(&erst_lock, flags);
+       raw_spin_lock_irqsave(&erst_lock, flags);
        count = __erst_get_record_count();
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
 
        return count;
 }
@@ -456,9 +456,9 @@ int erst_get_next_record_id(u64 *record_id)
        if (erst_disable)
                return -ENODEV;
 
-       spin_lock_irqsave(&erst_lock, flags);
+       raw_spin_lock_irqsave(&erst_lock, flags);
        rc = __erst_get_next_record_id(record_id);
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
 
        return rc;
 }
@@ -624,17 +624,17 @@ int erst_write(const struct cper_record_header *record)
                return -EINVAL;
 
        if (erst_erange.attr & ERST_RANGE_NVRAM) {
-               if (!spin_trylock_irqsave(&erst_lock, flags))
+               if (!raw_spin_trylock_irqsave(&erst_lock, flags))
                        return -EBUSY;
                rc = __erst_write_to_nvram(record);
-               spin_unlock_irqrestore(&erst_lock, flags);
+               raw_spin_unlock_irqrestore(&erst_lock, flags);
                return rc;
        }
 
        if (record->record_length > erst_erange.size)
                return -EINVAL;
 
-       if (!spin_trylock_irqsave(&erst_lock, flags))
+       if (!raw_spin_trylock_irqsave(&erst_lock, flags))
                return -EBUSY;
        memcpy(erst_erange.vaddr, record, record->record_length);
        rcd_erange = erst_erange.vaddr;
@@ -642,7 +642,7 @@ int erst_write(const struct cper_record_header *record)
        memcpy(&rcd_erange->persistence_information, "ER", 2);
 
        rc = __erst_write_to_storage(0);
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
 
        return rc;
 }
@@ -696,9 +696,9 @@ ssize_t erst_read(u64 record_id, struct cper_record_header *record,
        if (erst_disable)
                return -ENODEV;
 
-       spin_lock_irqsave(&erst_lock, flags);
+       raw_spin_lock_irqsave(&erst_lock, flags);
        len = __erst_read(record_id, record, buflen);
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
        return len;
 }
 EXPORT_SYMBOL_GPL(erst_read);
@@ -719,20 +719,20 @@ ssize_t erst_read_next(struct cper_record_header *record, size_t buflen)
        if (erst_disable)
                return -ENODEV;
 
-       spin_lock_irqsave(&erst_lock, flags);
+       raw_spin_lock_irqsave(&erst_lock, flags);
        rc = __erst_get_next_record_id(&record_id);
        if (rc) {
-               spin_unlock_irqrestore(&erst_lock, flags);
+               raw_spin_unlock_irqrestore(&erst_lock, flags);
                return rc;
        }
        /* no more record */
        if (record_id == APEI_ERST_INVALID_RECORD_ID) {
-               spin_unlock_irqrestore(&erst_lock, flags);
+               raw_spin_unlock_irqrestore(&erst_lock, flags);
                return 0;
        }
 
        len = __erst_read(record_id, record, buflen);
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
 
        return len;
 }
@@ -746,12 +746,12 @@ int erst_clear(u64 record_id)
        if (erst_disable)
                return -ENODEV;
 
-       spin_lock_irqsave(&erst_lock, flags);
+       raw_spin_lock_irqsave(&erst_lock, flags);
        if (erst_erange.attr & ERST_RANGE_NVRAM)
                rc = __erst_clear_from_nvram(record_id);
        else
                rc = __erst_clear_from_storage(record_id);
-       spin_unlock_irqrestore(&erst_lock, flags);
+       raw_spin_unlock_irqrestore(&erst_lock, flags);
 
        return rc;
 }
index 1a3508a7fe03f157c2e0144727bbeb5c244d2a46..daa7bc63f1d4bad00fd988ddcce3681fdc74f804 100644 (file)
@@ -46,9 +46,9 @@ EXPORT_SYMBOL_GPL(hest_disable);
 
 /* HEST table parsing */
 
-static struct acpi_table_hest *hest_tab;
+static struct acpi_table_hest *__read_mostly hest_tab;
 
-static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = {
+static const int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = {
        [ACPI_HEST_TYPE_IA32_CHECK] = -1,       /* need further calculation */
        [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1,
        [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi),
@@ -126,7 +126,7 @@ struct ghes_arr {
        unsigned int count;
 };
 
-static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
+static int __init hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
 {
        int *count = data;
 
@@ -135,7 +135,7 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
        return 0;
 }
 
-static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
+static int __init hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
 {
        struct platform_device *ghes_dev;
        struct ghes_arr *ghes_arr = data;
@@ -165,7 +165,7 @@ err:
        return rc;
 }
 
-static int hest_ghes_dev_register(unsigned int ghes_count)
+static int __init hest_ghes_dev_register(unsigned int ghes_count)
 {
        int rc, i;
        struct ghes_arr ghes_arr;
index 95649d373071ac93d14bbbb478db1ab4a8cdb801..9fb9d5ac939db1c071c4cdcaa7fba49364236e25 100644 (file)
@@ -130,6 +130,8 @@ struct acpi_battery {
        unsigned long flags;
 };
 
+static int acpi_battery_update(struct acpi_battery *battery);
+
 #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
 
 inline int acpi_battery_present(struct acpi_battery *battery)
@@ -184,6 +186,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
        int ret = 0;
        struct acpi_battery *battery = to_acpi_battery(psy);
 
+       if (acpi_battery_update(battery))
+               return -ENODEV;
+
        if (acpi_battery_present(battery)) {
                /* run battery update only if it is present */
                acpi_battery_get_state(battery);
index 372ff80b7b0c93f88f6f2ea9e100c0fdd2aaf6bf..302b31ed31f1ea099faa48b989114e9c99dc1485 100644 (file)
@@ -934,6 +934,9 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {
        ec_flag_msi, "MSI hardware", {
        DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL},
        {
+       ec_flag_msi, "MSI hardware", {
+       DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL},
+       {
        ec_validate_ecdt, "ASUS hardware", {
        DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
        {},
index 966feddf6b1ba29457fde294223018ad23666e39..055d7b701fff16d18fe5de5ea243ba8ec477e3ec 100644 (file)
@@ -110,9 +110,6 @@ struct acpi_ioremap {
 static LIST_HEAD(acpi_ioremaps);
 static DEFINE_SPINLOCK(acpi_ioremap_lock);
 
-#define        OSI_STRING_LENGTH_MAX 64        /* arbitrary */
-static char osi_setup_string[OSI_STRING_LENGTH_MAX];
-
 static void __init acpi_osi_setup_late(void);
 
 /*
@@ -152,8 +149,7 @@ static struct osi_linux {
        unsigned int    enable:1;
        unsigned int    dmi:1;
        unsigned int    cmdline:1;
-       unsigned int    known:1;
-} osi_linux = { 0, 0, 0, 0};
+} osi_linux = {0, 0, 0};
 
 static u32 acpi_osi_handler(acpi_string interface, u32 supported)
 {
@@ -1055,13 +1051,53 @@ static int __init acpi_os_name_setup(char *str)
 
 __setup("acpi_os_name=", acpi_os_name_setup);
 
+#define        OSI_STRING_LENGTH_MAX 64        /* arbitrary */
+#define        OSI_STRING_ENTRIES_MAX 16       /* arbitrary */
+
+struct osi_setup_entry {
+       char string[OSI_STRING_LENGTH_MAX];
+       bool enable;
+};
+
+static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX];
+
+void __init acpi_osi_setup(char *str)
+{
+       struct osi_setup_entry *osi;
+       bool enable = true;
+       int i;
+
+       if (!acpi_gbl_create_osi_method)
+               return;
+
+       if (str == NULL || *str == '\0') {
+               printk(KERN_INFO PREFIX "_OSI method disabled\n");
+               acpi_gbl_create_osi_method = FALSE;
+               return;
+       }
+
+       if (*str == '!') {
+               str++;
+               enable = false;
+       }
+
+       for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
+               osi = &osi_setup_entries[i];
+               if (!strcmp(osi->string, str)) {
+                       osi->enable = enable;
+                       break;
+               } else if (osi->string[0] == '\0') {
+                       osi->enable = enable;
+                       strncpy(osi->string, str, OSI_STRING_LENGTH_MAX);
+                       break;
+               }
+       }
+}
+
 static void __init set_osi_linux(unsigned int enable)
 {
-       if (osi_linux.enable != enable) {
+       if (osi_linux.enable != enable)
                osi_linux.enable = enable;
-               printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n",
-                       enable ? "Add": "Delet");
-       }
 
        if (osi_linux.enable)
                acpi_osi_setup("Linux");
@@ -1073,7 +1109,8 @@ static void __init set_osi_linux(unsigned int enable)
 
 static void __init acpi_cmdline_osi_linux(unsigned int enable)
 {
-       osi_linux.cmdline = 1;  /* cmdline set the default */
+       osi_linux.cmdline = 1;  /* cmdline set the default and override DMI */
+       osi_linux.dmi = 0;
        set_osi_linux(enable);
 
        return;
@@ -1081,15 +1118,12 @@ static void __init acpi_cmdline_osi_linux(unsigned int enable)
 
 void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
 {
-       osi_linux.dmi = 1;      /* DMI knows that this box asks OSI(Linux) */
-
        printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
 
        if (enable == -1)
                return;
 
-       osi_linux.known = 1;    /* DMI knows which OSI(Linux) default needed */
-
+       osi_linux.dmi = 1;      /* DMI knows that this box asks OSI(Linux) */
        set_osi_linux(enable);
 
        return;
@@ -1104,37 +1138,44 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
  */
 static void __init acpi_osi_setup_late(void)
 {
-       char *str = osi_setup_string;
+       struct osi_setup_entry *osi;
+       char *str;
+       int i;
+       acpi_status status;
 
-       if (*str == '\0')
-               return;
+       for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
+               osi = &osi_setup_entries[i];
+               str = osi->string;
 
-       if (!strcmp("!Linux", str)) {
-               acpi_cmdline_osi_linux(0);      /* !enable */
-       } else if (*str == '!') {
-               if (acpi_remove_interface(++str) == AE_OK)
-                       printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
-       } else if (!strcmp("Linux", str)) {
-               acpi_cmdline_osi_linux(1);      /* enable */
-       } else {
-               if (acpi_install_interface(str) == AE_OK)
-                       printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
+               if (*str == '\0')
+                       break;
+               if (osi->enable) {
+                       status = acpi_install_interface(str);
+
+                       if (ACPI_SUCCESS(status))
+                               printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
+               } else {
+                       status = acpi_remove_interface(str);
+
+                       if (ACPI_SUCCESS(status))
+                               printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
+               }
        }
 }
 
-int __init acpi_osi_setup(char *str)
+static int __init osi_setup(char *str)
 {
-       if (str == NULL || *str == '\0') {
-               printk(KERN_INFO PREFIX "_OSI method disabled\n");
-               acpi_gbl_create_osi_method = FALSE;
-       } else {
-               strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX);
-       }
+       if (str && !strcmp("Linux", str))
+               acpi_cmdline_osi_linux(1);
+       else if (str && !strcmp("!Linux", str))
+               acpi_cmdline_osi_linux(0);
+       else
+               acpi_osi_setup(str);
 
        return 1;
 }
 
-__setup("acpi_osi=", acpi_osi_setup);
+__setup("acpi_osi=", osi_setup);
 
 /* enable serialization to combat AE_ALREADY_EXISTS errors */
 static int __init acpi_serialize_setup(char *str)
@@ -1530,7 +1571,7 @@ acpi_status __init acpi_os_initialize(void)
        return AE_OK;
 }
 
-acpi_status acpi_os_initialize1(void)
+acpi_status __init acpi_os_initialize1(void)
 {
        kacpid_wq = create_workqueue("kacpid");
        kacpi_notify_wq = create_workqueue("kacpi_notify");
index 67dedeed144cf82c8e13859e7222b976d0eebb2e..4c9c2fb5d98f9a14a67e8618b44dc6f2c642887b 100644 (file)
@@ -213,11 +213,13 @@ static int acpi_power_on(acpi_handle handle)
                                  resource->name));
        } else {
                result = __acpi_power_on(resource);
+               if (result)
+                       resource->ref_count--;
        }
 
        mutex_unlock(&resource->resource_lock);
 
-       return 0;
+       return result;
 }
 
 static int acpi_power_off_device(acpi_handle handle)
@@ -465,10 +467,12 @@ int acpi_power_transition(struct acpi_device *device, int state)
        struct acpi_handle_list *tl = NULL;     /* Target Resources */
        int i = 0;
 
-
        if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
                return -EINVAL;
 
+       if (device->power.state == state)
+               return 0;
+
        if ((device->power.state < ACPI_STATE_D0)
            || (device->power.state > ACPI_STATE_D3))
                return -ENODEV;
@@ -488,10 +492,6 @@ int acpi_power_transition(struct acpi_device *device, int state)
                        goto end;
        }
 
-       if (device->power.state == state) {
-               goto end;
-       }
-
        /*
         * Then we dereference all power resources used in the current list.
         */
index fde49b9b1d99ed04eaf4192473ff7ce3bb913fd6..79cb6533289456c4f43b92dda5d7059a27345afa 100644 (file)
@@ -156,15 +156,6 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state)
        return 0;
 }
 
-static int acpi_thermal_cpufreq_increase(unsigned int cpu)
-{
-       return -ENODEV;
-}
-static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
-{
-       return -ENODEV;
-}
-
 #endif
 
 int acpi_processor_get_limit_info(struct acpi_processor *pr)
index 721d93b3ceee78c3b271f5f84ffe4fc795e435e1..febb153b5a68cf216fdd1b528ac44159e73abcba 100644 (file)
@@ -27,8 +27,6 @@
 
 static u8 sleep_states[ACPI_S_STATE_COUNT];
 
-static u32 acpi_target_sleep_state = ACPI_STATE_S0;
-
 static void acpi_sleep_tts_switch(u32 acpi_state)
 {
        union acpi_object in_arg = { ACPI_TYPE_INTEGER };
@@ -81,6 +79,8 @@ static int acpi_sleep_prepare(u32 acpi_state)
 }
 
 #ifdef CONFIG_ACPI_SLEEP
+static u32 acpi_target_sleep_state = ACPI_STATE_S0;
+
 /*
  * The ACPI specification wants us to save NVS memory regions during hibernation
  * and to restore them during the subsequent resume.  Windows does that also for
@@ -427,6 +427,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
                DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"),
                },
        },
+       {
+       .callback = init_nvs_nosave,
+       .ident = "Sony Vaio VGN-NW130D",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
+               },
+       },
        {},
 };
 #endif /* CONFIG_SUSPEND */
index 46b94762125b0b179792948cbd47be8a9bc8448f..f9b983ae68777544f5cc986f3e0e4e3b1f074179 100644 (file)
@@ -154,7 +154,7 @@ static int __init adummy_init(void)
                err = -ENOMEM;
                goto out;
        }
-       atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL);
+       atm_dev = atm_dev_register(DEV_LABEL, NULL, &adummy_ops, -1, NULL);
        if (!atm_dev) {
                printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
                err = -ENODEV;
index a33896a482e6eb0e0dd964649b5b6d7d90e64858..ffe9b655292e148e929365fe5bd8cd1b86443411 100644 (file)
@@ -2244,7 +2244,8 @@ static int __devinit amb_probe(struct pci_dev *pci_dev, const struct pci_device_
                goto out_reset;
        }
 
-       dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL);
+       dev->atm_dev = atm_dev_register (DEV_LABEL, &pci_dev->dev, &amb_ops, -1,
+                                        NULL);
        if (!dev->atm_dev) {
                PRINTD (DBG_ERR, "failed to register Madge ATM adapter");
                err = -EINVAL;
index b9101818b47b4012d9c5589d7b8ffd672cb26fc7..2b464b631f22697ac5f177d371b94d5646683d8f 100644 (file)
@@ -366,7 +366,7 @@ static int atmtcp_create(int itf,int persist,struct atm_dev **result)
        if (!dev_data)
                return -ENOMEM;
 
-       dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,itf,NULL);
+       dev = atm_dev_register(DEV_LABEL,NULL,&atmtcp_v_dev_ops,itf,NULL);
        if (!dev) {
                kfree(dev_data);
                return itf == -1 ? -ENOMEM : -EBUSY;
index 97c5898cd76e894350dfcc3a444de9ce2d202e35..c495fae742008c6569da47d5c3ca91c7f5ad48b4 100644 (file)
@@ -2244,7 +2244,7 @@ static int __devinit eni_init_one(struct pci_dev *pci_dev,
                    &zeroes);
                if (!cpu_zeroes) goto out1;
        }
-       dev = atm_dev_register(DEV_LABEL,&ops,-1,NULL);
+       dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL);
        if (!dev) goto out2;
        pci_set_drvdata(pci_dev, dev);
        eni_dev->pci_dev = pci_dev;
index 5d86bb803e9493443659f49180b68c147066a166..7d912baf01d444c6adaaa943f87e107ead7441b6 100644 (file)
@@ -1911,7 +1911,7 @@ static int __devinit firestream_init_one (struct pci_dev *pci_dev,
                    fs_dev, sizeof (struct fs_dev));
        if (!fs_dev)
                goto err_out;
-       atm_dev = atm_dev_register("fs", &ops, -1, NULL);
+       atm_dev = atm_dev_register("fs", &pci_dev->dev, &ops, -1, NULL);
        if (!atm_dev)
                goto err_out_free_fs_dev;
   
index c8fc69c85a062f81029495e827ae615547f964e9..962c309b40c035bea03e751fd9531de6eb7df1e9 100644 (file)
@@ -2567,14 +2567,14 @@ release:
 
 
 static int __devinit
-fore200e_register(struct fore200e* fore200e)
+fore200e_register(struct fore200e* fore200e, struct device *parent)
 {
     struct atm_dev* atm_dev;
 
     DPRINTK(2, "device %s being registered\n", fore200e->name);
 
-    atm_dev = atm_dev_register(fore200e->bus->proc_name, &fore200e_ops, -1,
-      NULL); 
+    atm_dev = atm_dev_register(fore200e->bus->proc_name, parent, &fore200e_ops,
+                               -1, NULL);
     if (atm_dev == NULL) {
        printk(FORE200E "unable to register device %s\n", fore200e->name);
        return -ENODEV;
@@ -2594,9 +2594,9 @@ fore200e_register(struct fore200e* fore200e)
 
 
 static int __devinit
-fore200e_init(struct fore200e* fore200e)
+fore200e_init(struct fore200e* fore200e, struct device *parent)
 {
-    if (fore200e_register(fore200e) < 0)
+    if (fore200e_register(fore200e, parent) < 0)
        return -ENODEV;
     
     if (fore200e->bus->configure(fore200e) < 0)
@@ -2662,7 +2662,7 @@ static int __devinit fore200e_sba_probe(struct platform_device *op,
 
        sprintf(fore200e->name, "%s-%d", bus->model_name, index);
 
-       err = fore200e_init(fore200e);
+       err = fore200e_init(fore200e, &op->dev);
        if (err < 0) {
                fore200e_shutdown(fore200e);
                kfree(fore200e);
@@ -2740,7 +2740,7 @@ fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent
 
     sprintf(fore200e->name, "%s-%d", bus->model_name, index);
 
-    err = fore200e_init(fore200e);
+    err = fore200e_init(fore200e, &pci_dev->dev);
     if (err < 0) {
        fore200e_shutdown(fore200e);
        goto out_free;
index 801e8b6e9d1fee08dd1b3d091ff3739193ee98cc..6cf59bf281dc1b601884586b7d8651ea0ecbeaa7 100644 (file)
@@ -366,7 +366,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
                goto init_one_failure;
        }
 
-       atm_dev = atm_dev_register(DEV_LABEL, &he_ops, -1, NULL);
+       atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &he_ops, -1, NULL);
        if (!atm_dev) {
                err = -ENODEV;
                goto init_one_failure;
index a95790452a685f3325ed64af5db2f2596f911236..24761e1d6642d7c6a2c7dcb6e8d4073c89f76c64 100644 (file)
@@ -2733,7 +2733,8 @@ static int __devinit hrz_probe(struct pci_dev *pci_dev, const struct pci_device_
        PRINTD(DBG_INFO, "found Madge ATM adapter (hrz) at: IO %x, IRQ %u, MEM %p",
               iobase, irq, membase);
 
-       dev->atm_dev = atm_dev_register(DEV_LABEL, &hrz_ops, -1, NULL);
+       dev->atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &hrz_ops, -1,
+                                       NULL);
        if (!(dev->atm_dev)) {
                PRINTD(DBG_ERR, "failed to register Madge ATM adapter");
                err = -EINVAL;
index bce57328ddde9addf376fe550a768194c4173c9b..bfb7feee0400df5c8f9a13adc0cde06a053c2ac7 100644 (file)
@@ -3698,7 +3698,8 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id)
                goto err_out_iounmap;
        }
 
-       dev = atm_dev_register("idt77252", &idt77252_ops, -1, NULL);
+       dev = atm_dev_register("idt77252", &pcidev->dev, &idt77252_ops, -1,
+                              NULL);
        if (!dev) {
                printk("%s: can't register atm device\n", card->name);
                err = -EIO;
index 9309d4724e1322effe4010042dc0a3136a432ebb..729254053758f0d3680ad67f52a32a07865f86b0 100644 (file)
@@ -3172,7 +3172,7 @@ static int __devinit ia_init_one(struct pci_dev *pdev,
                ret = -ENODEV;
                goto err_out_free_iadev;
        }
-       dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
+       dev = atm_dev_register(DEV_LABEL, &pdev->dev, &ops, -1, NULL);
        if (!dev) {
                ret = -ENOMEM;
                goto err_out_disable_dev;
index cbe15a86c6698b2044b45469fa57f8d199aca15e..a395c9aab146ec4f78d0b05767c81b04889c16ef 100644 (file)
@@ -2591,7 +2591,7 @@ static int __devinit lanai_init_one(struct pci_dev *pci,
                return -ENOMEM;
        }
 
-       atmdev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
+       atmdev = atm_dev_register(DEV_LABEL, &pci->dev, &ops, -1, NULL);
        if (atmdev == NULL) {
                printk(KERN_ERR DEV_LABEL
                    ": couldn't register atm device!\n");
index 2f3516b7f118cd59e7b9156ba1b004a6caee6c86..6b313ee9231baa2cd37893ba26c5e4877462ba0a 100644 (file)
@@ -771,7 +771,8 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev)
        }
 
        /* Register device */
-       card->atmdev = atm_dev_register("nicstar", &atm_ops, -1, NULL);
+       card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops,
+                                       -1, NULL);
        if (card->atmdev == NULL) {
                printk("nicstar%d: can't register device.\n", i);
                error = 17;
index 2e08c996fd30a6156e8a0a19e46966824d3d89df..73fb1c4f4cd4e99f0b57df7977c22216a781e1e6 100644 (file)
@@ -166,7 +166,7 @@ static irqreturn_t solos_irq(int irq, void *dev_id);
 static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
 static int list_vccs(int vci);
 static void release_vccs(struct atm_dev *dev);
-static int atm_init(struct solos_card *);
+static int atm_init(struct solos_card *, struct device *);
 static void atm_remove(struct solos_card *);
 static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
 static void solos_bh(unsigned long);
@@ -1210,7 +1210,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
        if (db_firmware_upgrade)
                flash_upgrade(card, 3);
 
-       err = atm_init(card);
+       err = atm_init(card, &dev->dev);
        if (err)
                goto out_free_irq;
 
@@ -1233,7 +1233,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
        return err;
 }
 
-static int atm_init(struct solos_card *card)
+static int atm_init(struct solos_card *card, struct device *parent)
 {
        int i;
 
@@ -1244,7 +1244,7 @@ static int atm_init(struct solos_card *card)
                skb_queue_head_init(&card->tx_queue[i]);
                skb_queue_head_init(&card->cli_queue[i]);
 
-               card->atmdev[i] = atm_dev_register("solos-pci", &fpga_ops, -1, NULL);
+               card->atmdev[i] = atm_dev_register("solos-pci", parent, &fpga_ops, -1, NULL);
                if (!card->atmdev[i]) {
                        dev_err(&card->dev->dev, "Could not register ATM device %d\n", i);
                        atm_remove(card);
index 4e885d2da49c6f0b5899b9eb3d8d1a874e700ca3..624917902b656f249fd06b057090f0f9d7b97961 100644 (file)
@@ -1597,7 +1597,7 @@ static int __devinit zatm_init_one(struct pci_dev *pci_dev,
                goto out;
        }
 
-       dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL);
+       dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL);
        if (!dev)
                goto out_free;
 
index 4f9e22f29138f1001dfca566ab3b04e176b6ae2e..657873e4328dbf05421b80e8d1231f27c5d3b369 100644 (file)
@@ -72,7 +72,7 @@ struct blk_shadow {
 static DEFINE_MUTEX(blkfront_mutex);
 static const struct block_device_operations xlvbd_block_fops;
 
-#define BLK_RING_SIZE __RING_SIZE((struct blkif_sring *)0, PAGE_SIZE)
+#define BLK_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE)
 
 /*
  * We have one of these per vbd, whether ide, scsi or 'other'.  They
index 128cae4e8629465429cf271209f587b8e192b3ad..949ed09c6361130c30c3ebda1bc4db02b00fa4c2 100644 (file)
 static struct usb_device_id ath3k_table[] = {
        /* Atheros AR3011 */
        { USB_DEVICE(0x0CF3, 0x3000) },
+
+       /* Atheros AR3011 with sflash firmware*/
+       { USB_DEVICE(0x0CF3, 0x3002) },
+
        { }     /* Terminating entry */
 };
 
index ab3894f742c3002a90a98b89f116ab30c75cdb28..1da773f899a2708f1c151b892098ed3ddbaf79cf 100644 (file)
@@ -99,6 +99,9 @@ static struct usb_device_id blacklist_table[] = {
        /* Broadcom BCM2033 without firmware */
        { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE },
 
+       /* Atheros 3011 with sflash firmware */
+       { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
+
        /* Broadcom BCM2035 */
        { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
        { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
@@ -239,7 +242,8 @@ static void btusb_intr_complete(struct urb *urb)
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err < 0) {
-               BT_ERR("%s urb %p failed to resubmit (%d)",
+               if (err != -EPERM)
+                       BT_ERR("%s urb %p failed to resubmit (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
        }
@@ -323,7 +327,8 @@ static void btusb_bulk_complete(struct urb *urb)
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err < 0) {
-               BT_ERR("%s urb %p failed to resubmit (%d)",
+               if (err != -EPERM)
+                       BT_ERR("%s urb %p failed to resubmit (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
        }
@@ -412,7 +417,8 @@ static void btusb_isoc_complete(struct urb *urb)
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err < 0) {
-               BT_ERR("%s urb %p failed to resubmit (%d)",
+               if (err != -EPERM)
+                       BT_ERR("%s urb %p failed to resubmit (%d)",
                                                hdev->name, urb, -err);
                usb_unanchor_urb(urb);
        }
index e16c3fa8d2e3e3649a6cab79fb34db9323aae711..05117f1ad8674839331ddb7c473b4cfc739bbddd 100644 (file)
@@ -36,6 +36,7 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
 MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector.");
+MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_CONNECTOR);
 
 static struct cn_dev cdev;
 
index a8a84f4587f20d7437af9ce12932dbf8e92a4e1b..64b21f5cd740fc5dfa1d5f09b1a944ed1f661440 100644 (file)
@@ -1,8 +1,8 @@
 ifeq ($(CONFIG_DMADEVICES_DEBUG),y)
-       EXTRA_CFLAGS    += -DDEBUG
+       ccflags-y       += -DDEBUG
 endif
 ifeq ($(CONFIG_DMADEVICES_VDEBUG),y)
-       EXTRA_CFLAGS    += -DVERBOSE_DEBUG
+       ccflags-y       += -DVERBOSE_DEBUG
 endif
 
 obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
index a0f3e6a06e06532b3701ade73b110d823eec591f..ea0ee81cff53e266643140eb752ef3ba26289c6a 100644 (file)
@@ -722,7 +722,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
                        desc->lli.daddr = mem;
                        desc->lli.ctrla = ctrla
                                        | ATC_DST_WIDTH(mem_width)
-                                       | len >> mem_width;
+                                       | len >> reg_width;
                        desc->lli.ctrlb = ctrlb;
 
                        if (!first) {
index 286c3ac6bdcc236d020229ce0397ee9e78e07100..e5e172d21692d60a81fce6a9ed06e5807c57b370 100644 (file)
@@ -50,9 +50,11 @@ static void dma_init(struct fsldma_chan *chan)
                 * EIE - Error interrupt enable
                 * EOSIE - End of segments interrupt enable (basic mode)
                 * EOLNIE - End of links interrupt enable
+                * BWC - Bandwidth sharing among channels
                 */
-               DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_EIE
-                               | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32);
+               DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_BWC
+                               | FSL_DMA_MR_EIE | FSL_DMA_MR_EOLNIE
+                               | FSL_DMA_MR_EOSIE, 32);
                break;
        case FSL_DMA_IP_83XX:
                /* Set the channel to below modes:
index cb4d6ff5159766baf7dce594dca6fb57e3d28dd2..ba9f403c0fbe9127441e7b92bf70c59c71cbde28 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (C) 2007-2010 Freescale Semiconductor, Inc. All rights reserved.
  *
  * Author:
  *   Zhang Wei <wei.zhang@freescale.com>, Jul 2007
 #define FSL_DMA_MR_DAHE                0x00002000
 #define FSL_DMA_MR_SAHE                0x00001000
 
+/*
+ * Bandwidth/pause control determines how many bytes a given
+ * channel is allowed to transfer before the DMA engine pauses
+ * the current channel and switches to the next channel
+ */
+#define FSL_DMA_MR_BWC         0x08000000
+
 /* Special MR definition for MPC8349 */
 #define FSL_DMA_MR_EOTIE       0x00000080
 #define FSL_DMA_MR_PRC_RM      0x00000800
index f629e4961af593f0ab5d3697fce77b306ab1ed9b..e53d438142bb8747cb8f288e64d75b0ba2e18a97 100644 (file)
@@ -379,7 +379,7 @@ static int __init imxdma_probe(struct platform_device *pdev)
        return 0;
 
 err_init:
-       while (i-- >= 0) {
+       while (--i >= 0) {
                struct imxdma_channel *imxdmac = &imxdma->channel[i];
                imx_dma_free(imxdmac->imxdma_channel);
        }
index 0834323a0599595b5a7fa8db1224a85125305031..d0602dd5d1b238eedf2500cd240ef0dc092800a8 100644 (file)
@@ -951,7 +951,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
                struct sdma_buffer_descriptor *bd = &sdmac->bd[i];
                int param;
 
-               bd->buffer_addr = sgl->dma_address;
+               bd->buffer_addr = sg->dma_address;
 
                count = sg->length;
 
@@ -1385,7 +1385,7 @@ static int __init sdma_module_init(void)
 {
        return platform_driver_probe(&sdma_driver, sdma_probe);
 }
-subsys_initcall(sdma_module_init);
+module_init(sdma_module_init);
 
 MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>");
 MODULE_DESCRIPTION("i.MX SDMA driver");
index 338bc4eed1f3f55b4de66c623a135289862c783f..3109bd94bc4f403c5aba44e8ff7cb092aa23b4cd 100644 (file)
@@ -1075,7 +1075,6 @@ static int mid_setup_dma(struct pci_dev *pdev)
        if (NULL == dma->dma_pool) {
                pr_err("ERR_MDMA:pci_pool_create failed\n");
                err = -ENOMEM;
-               kfree(dma);
                goto err_dma_pool;
        }
 
@@ -1186,7 +1185,6 @@ err_engine:
        free_irq(pdev->irq, dma);
 err_irq:
        pci_pool_destroy(dma->dma_pool);
-       kfree(dma);
 err_dma_pool:
        pr_err("ERR_MDMA:setup_dma failed: %d\n", err);
        return err;
@@ -1413,7 +1411,7 @@ static const struct dev_pm_ops intel_mid_dma_pm = {
        .runtime_idle = dma_runtime_idle,
 };
 
-static struct pci_driver intel_mid_dma_pci = {
+static struct pci_driver intel_mid_dma_pci_driver = {
        .name           =       "Intel MID DMA",
        .id_table       =       intel_mid_dma_ids,
        .probe          =       intel_mid_dma_probe,
@@ -1431,13 +1429,13 @@ static int __init intel_mid_dma_init(void)
 {
        pr_debug("INFO_MDMA: LNW DMA Driver Version %s\n",
                        INTEL_MID_DMA_DRIVER_VERSION);
-       return pci_register_driver(&intel_mid_dma_pci);
+       return pci_register_driver(&intel_mid_dma_pci_driver);
 }
 fs_initcall(intel_mid_dma_init);
 
 static void __exit intel_mid_dma_exit(void)
 {
-       pci_unregister_driver(&intel_mid_dma_pci);
+       pci_unregister_driver(&intel_mid_dma_pci_driver);
 }
 module_exit(intel_mid_dma_exit);
 
index 8997d3fb9051db0020bbeb721cc5a562d780bf47..0ff7270af25b97800d64fcc6f62c350f3115f322 100644 (file)
@@ -1,2 +1,2 @@
 obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
-ioatdma-objs := pci.o dma.o dma_v2.o dma_v3.o dca.o
+ioatdma-y := pci.o dma.o dma_v2.o dma_v3.o dca.o
index 92b679024fedd9e033e9cbae311f7f8d7f221142..c064c89420d06080a737ea48356501aeeae869cd 100644 (file)
@@ -259,11 +259,6 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc)
                return;
        }
 
-       channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr);
-       channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr);
-       channel_writel(pd_chan, SIZE, desc->regs.size);
-       channel_writel(pd_chan, NEXT, desc->regs.next);
-
        dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n",
                pd_chan->chan.chan_id, desc->regs.dev_addr);
        dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n",
@@ -273,10 +268,16 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc)
        dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n",
                pd_chan->chan.chan_id, desc->regs.next);
 
-       if (list_empty(&desc->tx_list))
+       if (list_empty(&desc->tx_list)) {
+               channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr);
+               channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr);
+               channel_writel(pd_chan, SIZE, desc->regs.size);
+               channel_writel(pd_chan, NEXT, desc->regs.next);
                pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT);
-       else
+       } else {
+               channel_writel(pd_chan, NEXT, desc->txd.phys);
                pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG);
+       }
 
        val = dma_readl(pd, CTL2);
        val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id);
index 0d58a4a4487fbbaefc167182a627c6b0b0f222b3..cef584533ee8a9ca5628b874b5d6c644a4ad05f4 100644 (file)
@@ -4449,9 +4449,8 @@ static int __devinit ppc440spe_adma_probe(struct platform_device *ofdev,
 
        if (!request_mem_region(res.start, resource_size(&res),
                                dev_driver_string(&ofdev->dev))) {
-               dev_err(&ofdev->dev, "failed to request memory region "
-                       "(0x%016llx-0x%016llx)\n",
-                       (u64)res.start, (u64)res.end);
+               dev_err(&ofdev->dev, "failed to request memory region %pR\n",
+                       &res);
                initcode = PPC_ADMA_INIT_MEMREG;
                ret = -EBUSY;
                goto out;
index 8521401bbd751406e6f2752e10868f63c7e3b48a..eca9ba193e94a914aa64740f0b4262b8f7c99b81 100644 (file)
@@ -1572,7 +1572,7 @@ static int f10_match_to_this_node(struct amd64_pvt *pvt, int dram_range,
        debugf1("   HoleOffset=0x%x  HoleValid=0x%x IntlvSel=0x%x\n",
                        hole_off, hole_valid, intlv_sel);
 
-       if (intlv_en ||
+       if (intlv_en &&
            (intlv_sel != ((sys_addr >> 12) & intlv_en)))
                return -EINVAL;
 
index d7ca43a828bd3fe57b3de1341d7e75d1bed84f0a..251440cd50a3b41ea47f4511365909b707ebf0e8 100644 (file)
 #define MC_PROC_NAME_MAX_LEN   7
 
 #if PAGE_SHIFT < 20
-#define PAGES_TO_MiB( pages )  ( ( pages ) >> ( 20 - PAGE_SHIFT ) )
-#define MiB_TO_PAGES(mb)       ((mb) >> (20 - PAGE_SHIFT))
+#define PAGES_TO_MiB(pages)    ((pages) >> (20 - PAGE_SHIFT))
+#define MiB_TO_PAGES(mb)       ((mb) << (20 - PAGE_SHIFT))
 #else                          /* PAGE_SHIFT > 20 */
-#define PAGES_TO_MiB( pages )  ( ( pages ) << ( PAGE_SHIFT - 20 ) )
+#define PAGES_TO_MiB(pages)    ((pages) << (PAGE_SHIFT - 20))
 #define MiB_TO_PAGES(mb)       ((mb) >> (PAGE_SHIFT - 20))
 #endif
 
index ba6586a69ccce3b000fb22ee21512ab4673b44ac..795ea69c4d8f5fb6149c62fba8e085bd83363309 100644 (file)
@@ -586,14 +586,16 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev)
                return NULL;
        }
 
-       /* marking MCI offline */
-       mci->op_state = OP_OFFLINE;
-
        del_mc_from_global_list(mci);
        mutex_unlock(&mem_ctls_mutex);
 
-       /* flush workq processes and remove sysfs */
+       /* flush workq processes */
        edac_mc_workq_teardown(mci);
+
+       /* marking MCI offline */
+       mci->op_state = OP_OFFLINE;
+
+       /* remove from sysfs */
        edac_remove_sysfs_mci_device(mci);
 
        edac_printk(KERN_INFO, EDAC_MC,
index 84eb607d6c031b4275e834604d4c0c0729fa8502..e3c8b60bd86be8873e781bef053f466898be16c2 100644 (file)
@@ -242,6 +242,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
 
 static char ohci_driver_name[] = KBUILD_MODNAME;
 
+#define PCI_DEVICE_ID_AGERE_FW643      0x5901
 #define PCI_DEVICE_ID_JMICRON_JMB38X_FW        0x2380
 #define PCI_DEVICE_ID_TI_TSB12LV22     0x8009
 
@@ -253,18 +254,34 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
 
 /* In case of multiple matches in ohci_quirks[], only the first one is used. */
 static const struct {
-       unsigned short vendor, device, flags;
+       unsigned short vendor, device, revision, flags;
 } ohci_quirks[] = {
-       {PCI_VENDOR_ID_TI,      PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER |
-                                                           QUIRK_RESET_PACKET |
-                                                           QUIRK_NO_1394A},
-       {PCI_VENDOR_ID_TI,      PCI_ANY_ID,     QUIRK_RESET_PACKET},
-       {PCI_VENDOR_ID_AL,      PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
-       {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI},
-       {PCI_VENDOR_ID_NEC,     PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
-       {PCI_VENDOR_ID_VIA,     PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
-       {PCI_VENDOR_ID_RICOH,   PCI_ANY_ID,     QUIRK_CYCLE_TIMER},
-       {PCI_VENDOR_ID_APPLE,   PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS},
+       {PCI_VENDOR_ID_AL, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_CYCLE_TIMER},
+
+       {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, PCI_ANY_ID,
+               QUIRK_BE_HEADERS},
+
+       {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6,
+               QUIRK_NO_MSI},
+
+       {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, PCI_ANY_ID,
+               QUIRK_NO_MSI},
+
+       {PCI_VENDOR_ID_NEC, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_CYCLE_TIMER},
+
+       {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_CYCLE_TIMER},
+
+       {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, PCI_ANY_ID,
+               QUIRK_CYCLE_TIMER | QUIRK_RESET_PACKET | QUIRK_NO_1394A},
+
+       {PCI_VENDOR_ID_TI, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_RESET_PACKET},
+
+       {PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID,
+               QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
 };
 
 /* This overrides anything that was found in ohci_quirks[]. */
@@ -2927,9 +2944,11 @@ static int __devinit pci_probe(struct pci_dev *dev,
        }
 
        for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++)
-               if (ohci_quirks[i].vendor == dev->vendor &&
-                   (ohci_quirks[i].device == dev->device ||
-                    ohci_quirks[i].device == (unsigned short)PCI_ANY_ID)) {
+               if ((ohci_quirks[i].vendor == dev->vendor) &&
+                   (ohci_quirks[i].device == (unsigned short)PCI_ANY_ID ||
+                    ohci_quirks[i].device == dev->device) &&
+                   (ohci_quirks[i].revision == (unsigned short)PCI_ANY_ID ||
+                    ohci_quirks[i].revision >= dev->revision)) {
                        ohci->quirks = ohci_quirks[i].flags;
                        break;
                }
index 6985cb1da72cbc232919ab2bb93a52f26304a345..2baa6708e44cd835704ea832c861b7d5fe4b6e33 100644 (file)
@@ -156,12 +156,12 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
        { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 },
        { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 },
        { DRM_MODE_CONNECTOR_Component, "Component", 0 },
-       { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN", 0 },
-       { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 },
-       { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 },
-       { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
+       { DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 },
+       { DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 },
+       { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 },
+       { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 },
        { DRM_MODE_CONNECTOR_TV, "TV", 0 },
-       { DRM_MODE_CONNECTOR_eDP, "Embedded DisplayPort", 0 },
+       { DRM_MODE_CONNECTOR_eDP, "eDP", 0 },
 };
 
 static struct drm_prop_enum_list drm_encoder_enum_list[] =
index 722700d5d73ee69a6ac49d4fbd96d307f704c2bb..16d5155edad14fd63dea3b10243a71c6bd3d0ea1 100644 (file)
@@ -628,7 +628,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
        if ((seq - vblwait->request.sequence) <= (1 << 23)) {
                e->event.tv_sec = now.tv_sec;
                e->event.tv_usec = now.tv_usec;
-               drm_vblank_put(dev, e->pipe);
+               drm_vblank_put(dev, pipe);
                list_add_tail(&e->base.link, &e->base.file_priv->event_list);
                wake_up_interruptible(&e->base.file_priv->event_wait);
                trace_drm_vblank_event_delivered(current->pid, pipe,
@@ -645,7 +645,7 @@ err_unlock:
        spin_unlock_irqrestore(&dev->event_lock, flags);
        kfree(e);
 err_put:
-       drm_vblank_put(dev, e->pipe);
+       drm_vblank_put(dev, pipe);
        return ret;
 }
 
index a322d4f647bd2cbe479f6b482f1249ada5de454e..4d7a2e1bdb90e498138eea542e22884c9e36eb0d 100644 (file)
@@ -878,12 +878,15 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
        u32 tmp;
 
        /* flush hdp cache so updates hit vram */
-       if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) {
+       if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
+           !(rdev->flags & RADEON_IS_AGP)) {
                void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
                u32 tmp;
 
                /* r7xx hw bug.  write to HDP_DEBUG1 followed by fb read
                 * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
+                * This seems to cause problems on some AGP cards. Just use the old
+                * method for them.
                 */
                WREG32(HDP_DEBUG1, 0);
                tmp = readl((void __iomem *)ptr);
@@ -3485,10 +3488,12 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev)
 void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
 {
        /* r7xx hw bug.  write to HDP_DEBUG1 followed by fb read
-        * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
+        * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL.
+        * This seems to cause problems on some AGP cards. Just use the old
+        * method for them.
         */
        if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
-           rdev->vram_scratch.ptr) {
+           rdev->vram_scratch.ptr && !(rdev->flags & RADEON_IS_AGP)) {
                void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
                u32 tmp;
 
index 4bf969c0a32b5ee9cb667a4341759e651f58d569..be0fdd58aa29301fbe15f9186580d724ba769544 100644 (file)
@@ -916,27 +916,27 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
        int nr = sensor_attr->index;
        struct i2c_client *client = to_i2c_client(dev);
        struct adm1026_data *data = i2c_get_clientdata(client);
-       int val, orig_div, new_div, shift;
+       int val, orig_div, new_div;
 
        val = simple_strtol(buf, NULL, 10);
        new_div = DIV_TO_REG(val);
-       if (new_div == 0) {
-               return -EINVAL;
-       }
+
        mutex_lock(&data->update_lock);
        orig_div = data->fan_div[nr];
        data->fan_div[nr] = DIV_FROM_REG(new_div);
 
        if (nr < 4) { /* 0 <= nr < 4 */
-               shift = 2 * nr;
                adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3,
-                       ((DIV_TO_REG(orig_div) & (~(0x03 << shift))) |
-                       (new_div << shift)));
+                                   (DIV_TO_REG(data->fan_div[0]) << 0) |
+                                   (DIV_TO_REG(data->fan_div[1]) << 2) |
+                                   (DIV_TO_REG(data->fan_div[2]) << 4) |
+                                   (DIV_TO_REG(data->fan_div[3]) << 6));
        } else { /* 3 < nr < 8 */
-               shift = 2 * (nr - 4);
                adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7,
-                       ((DIV_TO_REG(orig_div) & (~(0x03 << (2 * shift)))) |
-                       (new_div << shift)));
+                                   (DIV_TO_REG(data->fan_div[4]) << 0) |
+                                   (DIV_TO_REG(data->fan_div[5]) << 2) |
+                                   (DIV_TO_REG(data->fan_div[6]) << 4) |
+                                   (DIV_TO_REG(data->fan_div[7]) << 6));
        }
 
        if (data->fan_div[nr] != orig_div) {
index 14a5d981be7d07030a264352dbc8d8af1e158c2d..a428a92641954a640dd783f051fc9c5565c13d9b 100644 (file)
@@ -187,6 +187,7 @@ static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 };
 #define IT87_REG_FAN_MAIN_CTRL 0x13
 #define IT87_REG_FAN_CTL       0x14
 #define IT87_REG_PWM(nr)       (0x15 + (nr))
+#define IT87_REG_PWM_DUTY(nr)  (0x63 + (nr) * 8)
 
 #define IT87_REG_VIN(nr)       (0x20 + (nr))
 #define IT87_REG_TEMP(nr)      (0x29 + (nr))
@@ -251,12 +252,16 @@ struct it87_data {
        u8 fan_main_ctrl;       /* Register value */
        u8 fan_ctl;             /* Register value */
 
-       /* The following 3 arrays correspond to the same registers. The
-        * meaning of bits 6-0 depends on the value of bit 7, and we want
-        * to preserve settings on mode changes, so we have to track all
-        * values separately. */
+       /* The following 3 arrays correspond to the same registers up to
+        * the IT8720F. The meaning of bits 6-0 depends on the value of bit
+        * 7, and we want to preserve settings on mode changes, so we have
+        * to track all values separately.
+        * Starting with the IT8721F, the manual PWM duty cycles are stored
+        * in separate registers (8-bit values), so the separate tracking
+        * is no longer needed, but it is still done to keep the driver
+        * simple. */
        u8 pwm_ctrl[3];         /* Register value */
-       u8 pwm_duty[3];         /* Manual PWM value set by user (bit 6-0) */
+       u8 pwm_duty[3];         /* Manual PWM value set by user */
        u8 pwm_temp_map[3];     /* PWM to temp. chan. mapping (bits 1-0) */
 
        /* Automatic fan speed control registers */
@@ -832,7 +837,9 @@ static ssize_t set_pwm_enable(struct device *dev,
                                 data->fan_main_ctrl);
        } else {
                if (val == 1)                           /* Manual mode */
-                       data->pwm_ctrl[nr] = data->pwm_duty[nr];
+                       data->pwm_ctrl[nr] = data->type == it8721 ?
+                                            data->pwm_temp_map[nr] :
+                                            data->pwm_duty[nr];
                else                                    /* Automatic mode */
                        data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr];
                it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
@@ -858,12 +865,25 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
                return -EINVAL;
 
        mutex_lock(&data->update_lock);
-       data->pwm_duty[nr] = pwm_to_reg(data, val);
-       /* If we are in manual mode, write the duty cycle immediately;
-        * otherwise, just store it for later use. */
-       if (!(data->pwm_ctrl[nr] & 0x80)) {
-               data->pwm_ctrl[nr] = data->pwm_duty[nr];
-               it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]);
+       if (data->type == it8721) {
+               /* If we are in automatic mode, the PWM duty cycle register
+                * is read-only so we can't write the value */
+               if (data->pwm_ctrl[nr] & 0x80) {
+                       mutex_unlock(&data->update_lock);
+                       return -EBUSY;
+               }
+               data->pwm_duty[nr] = pwm_to_reg(data, val);
+               it87_write_value(data, IT87_REG_PWM_DUTY(nr),
+                                data->pwm_duty[nr]);
+       } else {
+               data->pwm_duty[nr] = pwm_to_reg(data, val);
+               /* If we are in manual mode, write the duty cycle immediately;
+                * otherwise, just store it for later use. */
+               if (!(data->pwm_ctrl[nr] & 0x80)) {
+                       data->pwm_ctrl[nr] = data->pwm_duty[nr];
+                       it87_write_value(data, IT87_REG_PWM(nr),
+                                        data->pwm_ctrl[nr]);
+               }
        }
        mutex_unlock(&data->update_lock);
        return count;
@@ -1958,7 +1978,10 @@ static void __devinit it87_init_device(struct platform_device *pdev)
         *   channels to use when later setting to automatic mode later.
         *   Use a 1:1 mapping by default (we are clueless.)
         * In both cases, the value can (and should) be changed by the user
-        * prior to switching to a different mode. */
+        * prior to switching to a different mode.
+        * Note that this is no longer needed for the IT8721F and later, as
+        * these have separate registers for the temperature mapping and the
+        * manual duty cycle. */
        for (i = 0; i < 3; i++) {
                data->pwm_temp_map[i] = i;
                data->pwm_duty[i] = 0x7f;       /* Full speed */
@@ -2034,10 +2057,16 @@ static void __devinit it87_init_device(struct platform_device *pdev)
 static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
 {
        data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr));
-       if (data->pwm_ctrl[nr] & 0x80)  /* Automatic mode */
+       if (data->type == it8721) {
                data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
-       else                            /* Manual mode */
-               data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f;
+               data->pwm_duty[nr] = it87_read_value(data,
+                                                    IT87_REG_PWM_DUTY(nr));
+       } else {
+               if (data->pwm_ctrl[nr] & 0x80)  /* Automatic mode */
+                       data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03;
+               else                            /* Manual mode */
+                       data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f;
+       }
 
        if (has_old_autopwm(data)) {
                int i;
index 00d975eb5b83dcc86ddd8d5f5b6846c9d370f6e6..c7e6d8e81656391e7f7919d5e4c92d08a69b1700 100644 (file)
@@ -205,7 +205,6 @@ LTC4215_ALARM(curr1_max_alarm,      (1 << 2),       LTC4215_STATUS);
 
 /* Power (virtual) */
 LTC4215_POWER(power1_input);
-LTC4215_ALARM(power1_alarm,    (1 << 3),       LTC4215_STATUS);
 
 /* Input Voltage */
 LTC4215_VOLTAGE(in1_input,                     LTC4215_ADIN);
@@ -214,6 +213,7 @@ LTC4215_ALARM(in1_min_alarm,        (1 << 1),       LTC4215_STATUS);
 
 /* Output Voltage */
 LTC4215_VOLTAGE(in2_input,                     LTC4215_SOURCE);
+LTC4215_ALARM(in2_min_alarm,   (1 << 3),       LTC4215_STATUS);
 
 /* Finally, construct an array of pointers to members of the above objects,
  * as required for sysfs_create_group()
@@ -223,13 +223,13 @@ static struct attribute *ltc4215_attributes[] = {
        &sensor_dev_attr_curr1_max_alarm.dev_attr.attr,
 
        &sensor_dev_attr_power1_input.dev_attr.attr,
-       &sensor_dev_attr_power1_alarm.dev_attr.attr,
 
        &sensor_dev_attr_in1_input.dev_attr.attr,
        &sensor_dev_attr_in1_max_alarm.dev_attr.attr,
        &sensor_dev_attr_in1_min_alarm.dev_attr.attr,
 
        &sensor_dev_attr_in2_input.dev_attr.attr,
+       &sensor_dev_attr_in2_min_alarm.dev_attr.attr,
 
        NULL,
 };
index 80f70d3a744dc65024c868843a66cd336fd53ce5..c71492782bbd4dda6e1f4a585adbba419ce4694d 100644 (file)
@@ -999,7 +999,7 @@ static int __devinit intel_mid_i2c_probe(struct pci_dev *dev,
 
        /* Initialize struct members */
        snprintf(mrst->adap.name, sizeof(mrst->adap.name),
-               "MRST/Medfield I2C at %lx", start);
+               "Intel MID I2C at %lx", start);
        mrst->adap.owner = THIS_MODULE;
        mrst->adap.algo = &intel_mid_i2c_algorithm;
        mrst->adap.dev.parent = &dev->dev;
index 41665d2f9f93c1fa585533184468da72039fe7cf..c131d58bcb50d818e05ee0464581bceedfdbf20f 100644 (file)
@@ -273,8 +273,6 @@ static int intel_idle_probe(void)
 
        pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates);
 
-       if (boot_cpu_has(X86_FEATURE_ARAT))     /* Always Reliable APIC Timer */
-               lapic_timer_reliable_states = 0xFFFFFFFF;
 
        if (boot_cpu_data.x86 != 6)     /* family 6 */
                return -ENODEV;
@@ -286,8 +284,6 @@ static int intel_idle_probe(void)
        case 0x1F:      /* Core i7 and i5 Processor - Nehalem */
        case 0x2E:      /* Nehalem-EX Xeon */
        case 0x2F:      /* Westmere-EX Xeon */
-               lapic_timer_reliable_states = (1 << 1);  /* C1 */
-
        case 0x25:      /* Westmere */
        case 0x2C:      /* Westmere */
                cpuidle_state_table = nehalem_cstates;
@@ -295,7 +291,6 @@ static int intel_idle_probe(void)
 
        case 0x1C:      /* 28 - Atom Processor */
        case 0x26:      /* 38 - Lincroft Atom Processor */
-               lapic_timer_reliable_states = (1 << 1); /* C1 */
                cpuidle_state_table = atom_cstates;
                break;
 
@@ -303,10 +298,6 @@ static int intel_idle_probe(void)
        case 0x2D:      /* SNB Xeon */
                cpuidle_state_table = snb_cstates;
                break;
-#ifdef FUTURE_USE
-       case 0x17:      /* 23 - Core 2 Duo */
-               lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */
-#endif
 
        default:
                pr_debug(PREFIX "does not run on family %d model %d\n",
@@ -314,6 +305,9 @@ static int intel_idle_probe(void)
                return -ENODEV;
        }
 
+       if (boot_cpu_has(X86_FEATURE_ARAT))     /* Always Reliable APIC Timer */
+               lapic_timer_reliable_states = 0xFFFFFFFF;
+
        pr_debug(PREFIX "v" INTEL_IDLE_VERSION
                " model 0x%X\n", boot_cpu_data.x86_model);
 
index b342248aec059060e19f64ffd69ec28af256682a..c42699285f8eb0d67745c359afadc6e125e7815d 100644 (file)
@@ -893,68 +893,81 @@ out:
        return ret ? ret : in_len;
 }
 
+static int copy_wc_to_user(void __user *dest, struct ib_wc *wc)
+{
+       struct ib_uverbs_wc tmp;
+
+       tmp.wr_id               = wc->wr_id;
+       tmp.status              = wc->status;
+       tmp.opcode              = wc->opcode;
+       tmp.vendor_err          = wc->vendor_err;
+       tmp.byte_len            = wc->byte_len;
+       tmp.ex.imm_data         = (__u32 __force) wc->ex.imm_data;
+       tmp.qp_num              = wc->qp->qp_num;
+       tmp.src_qp              = wc->src_qp;
+       tmp.wc_flags            = wc->wc_flags;
+       tmp.pkey_index          = wc->pkey_index;
+       tmp.slid                = wc->slid;
+       tmp.sl                  = wc->sl;
+       tmp.dlid_path_bits      = wc->dlid_path_bits;
+       tmp.port_num            = wc->port_num;
+       tmp.reserved            = 0;
+
+       if (copy_to_user(dest, &tmp, sizeof tmp))
+               return -EFAULT;
+
+       return 0;
+}
+
 ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
                          const char __user *buf, int in_len,
                          int out_len)
 {
        struct ib_uverbs_poll_cq       cmd;
-       struct ib_uverbs_poll_cq_resp *resp;
+       struct ib_uverbs_poll_cq_resp  resp;
+       u8 __user                     *header_ptr;
+       u8 __user                     *data_ptr;
        struct ib_cq                  *cq;
-       struct ib_wc                  *wc;
-       int                            ret = 0;
-       int                            i;
-       int                            rsize;
+       struct ib_wc                   wc;
+       int                            ret;
 
        if (copy_from_user(&cmd, buf, sizeof cmd))
                return -EFAULT;
 
-       wc = kmalloc(cmd.ne * sizeof *wc, GFP_KERNEL);
-       if (!wc)
-               return -ENOMEM;
-
-       rsize = sizeof *resp + cmd.ne * sizeof(struct ib_uverbs_wc);
-       resp = kmalloc(rsize, GFP_KERNEL);
-       if (!resp) {
-               ret = -ENOMEM;
-               goto out_wc;
-       }
-
        cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0);
-       if (!cq) {
-               ret = -EINVAL;
-               goto out;
-       }
+       if (!cq)
+               return -EINVAL;
 
-       resp->count = ib_poll_cq(cq, cmd.ne, wc);
+       /* we copy a struct ib_uverbs_poll_cq_resp to user space */
+       header_ptr = (void __user *)(unsigned long) cmd.response;
+       data_ptr = header_ptr + sizeof resp;
 
-       put_cq_read(cq);
+       memset(&resp, 0, sizeof resp);
+       while (resp.count < cmd.ne) {
+               ret = ib_poll_cq(cq, 1, &wc);
+               if (ret < 0)
+                       goto out_put;
+               if (!ret)
+                       break;
+
+               ret = copy_wc_to_user(data_ptr, &wc);
+               if (ret)
+                       goto out_put;
 
-       for (i = 0; i < resp->count; i++) {
-               resp->wc[i].wr_id          = wc[i].wr_id;
-               resp->wc[i].status         = wc[i].status;
-               resp->wc[i].opcode         = wc[i].opcode;
-               resp->wc[i].vendor_err     = wc[i].vendor_err;
-               resp->wc[i].byte_len       = wc[i].byte_len;
-               resp->wc[i].ex.imm_data    = (__u32 __force) wc[i].ex.imm_data;
-               resp->wc[i].qp_num         = wc[i].qp->qp_num;
-               resp->wc[i].src_qp         = wc[i].src_qp;
-               resp->wc[i].wc_flags       = wc[i].wc_flags;
-               resp->wc[i].pkey_index     = wc[i].pkey_index;
-               resp->wc[i].slid           = wc[i].slid;
-               resp->wc[i].sl             = wc[i].sl;
-               resp->wc[i].dlid_path_bits = wc[i].dlid_path_bits;
-               resp->wc[i].port_num       = wc[i].port_num;
+               data_ptr += sizeof(struct ib_uverbs_wc);
+               ++resp.count;
        }
 
-       if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize))
+       if (copy_to_user(header_ptr, &resp, sizeof resp)) {
                ret = -EFAULT;
+               goto out_put;
+       }
 
-out:
-       kfree(resp);
+       ret = in_len;
 
-out_wc:
-       kfree(wc);
-       return ret ? ret : in_len;
+out_put:
+       put_cq_read(cq);
+       return ret;
 }
 
 ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,
index e3f7fc6f95657e2f4846cebc0efae905d309c31d..68f09a868434b52a6522c147dce8125f42f6505f 100644 (file)
@@ -534,76 +534,73 @@ static int handle_eviocgbit(struct input_dev *dev,
 }
 #undef OLD_KEY_MAX
 
-static int evdev_handle_get_keycode(struct input_dev *dev,
-                                   void __user *p, size_t size)
+static int evdev_handle_get_keycode(struct input_dev *dev, void __user *p)
 {
-       struct input_keymap_entry ke;
+       struct input_keymap_entry ke = {
+               .len    = sizeof(unsigned int),
+               .flags  = 0,
+       };
+       int __user *ip = (int __user *)p;
        int error;
 
-       memset(&ke, 0, sizeof(ke));
-
-       if (size == sizeof(unsigned int[2])) {
-               /* legacy case */
-               int __user *ip = (int __user *)p;
+       /* legacy case */
+       if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
+               return -EFAULT;
 
-               if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
-                       return -EFAULT;
+       error = input_get_keycode(dev, &ke);
+       if (error)
+               return error;
 
-               ke.len = sizeof(unsigned int);
-               ke.flags = 0;
+       if (put_user(ke.keycode, ip + 1))
+               return -EFAULT;
 
-               error = input_get_keycode(dev, &ke);
-               if (error)
-                       return error;
+       return 0;
+}
 
-               if (put_user(ke.keycode, ip + 1))
-                       return -EFAULT;
+static int evdev_handle_get_keycode_v2(struct input_dev *dev, void __user *p)
+{
+       struct input_keymap_entry ke;
+       int error;
 
-       } else {
-               size = min(size, sizeof(ke));
+       if (copy_from_user(&ke, p, sizeof(ke)))
+               return -EFAULT;
 
-               if (copy_from_user(&ke, p, size))
-                       return -EFAULT;
+       error = input_get_keycode(dev, &ke);
+       if (error)
+               return error;
 
-               error = input_get_keycode(dev, &ke);
-               if (error)
-                       return error;
+       if (copy_to_user(p, &ke, sizeof(ke)))
+               return -EFAULT;
 
-               if (copy_to_user(p, &ke, size))
-                       return -EFAULT;
-       }
        return 0;
 }
 
-static int evdev_handle_set_keycode(struct input_dev *dev,
-                                   void __user *p, size_t size)
+static int evdev_handle_set_keycode(struct input_dev *dev, void __user *p)
 {
-       struct input_keymap_entry ke;
-
-       memset(&ke, 0, sizeof(ke));
+       struct input_keymap_entry ke = {
+               .len    = sizeof(unsigned int),
+               .flags  = 0,
+       };
+       int __user *ip = (int __user *)p;
 
-       if (size == sizeof(unsigned int[2])) {
-               /* legacy case */
-               int __user *ip = (int __user *)p;
+       if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
+               return -EFAULT;
 
-               if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))
-                       return -EFAULT;
+       if (get_user(ke.keycode, ip + 1))
+               return -EFAULT;
 
-               if (get_user(ke.keycode, ip + 1))
-                       return -EFAULT;
+       return input_set_keycode(dev, &ke);
+}
 
-               ke.len = sizeof(unsigned int);
-               ke.flags = 0;
+static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p)
+{
+       struct input_keymap_entry ke;
 
-       } else {
-               size = min(size, sizeof(ke));
+       if (copy_from_user(&ke, p, sizeof(ke)))
+               return -EFAULT;
 
-               if (copy_from_user(&ke, p, size))
-                       return -EFAULT;
-
-               if (ke.len > sizeof(ke.scancode))
-                       return -EINVAL;
-       }
+       if (ke.len > sizeof(ke.scancode))
+               return -EINVAL;
 
        return input_set_keycode(dev, &ke);
 }
@@ -669,6 +666,18 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
                        return evdev_grab(evdev, client);
                else
                        return evdev_ungrab(evdev, client);
+
+       case EVIOCGKEYCODE:
+               return evdev_handle_get_keycode(dev, p);
+
+       case EVIOCSKEYCODE:
+               return evdev_handle_set_keycode(dev, p);
+
+       case EVIOCGKEYCODE_V2:
+               return evdev_handle_get_keycode_v2(dev, p);
+
+       case EVIOCSKEYCODE_V2:
+               return evdev_handle_set_keycode_v2(dev, p);
        }
 
        size = _IOC_SIZE(cmd);
@@ -708,12 +717,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
                        return -EFAULT;
 
                return error;
-
-       case EVIOC_MASK_SIZE(EVIOCGKEYCODE):
-               return evdev_handle_get_keycode(dev, p, size);
-
-       case EVIOC_MASK_SIZE(EVIOCSKEYCODE):
-               return evdev_handle_set_keycode(dev, p, size);
        }
 
        /* Multi-number variable-length handlers */
index 4852b440960abadea47ab158dc8e6e6140970b06..435b0af401e46e38b23fd6ffba9e862f90c9729b 100644 (file)
@@ -1436,6 +1436,8 @@ static struct wacom_features wacom_features_0xD2 =
        { "Wacom Bamboo Craft",   WACOM_PKGLEN_BBFUN,     14720,  9200, 1023, 63, BAMBOO_PT };
 static struct wacom_features wacom_features_0xD3 =
        { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN,     21648, 13530, 1023, 63, BAMBOO_PT };
+static const struct wacom_features wacom_features_0xD4 =
+       { "Wacom Bamboo Pen",     WACOM_PKGLEN_BBFUN,     14720,  9200,  255, 63, BAMBOO_PT };
 static struct wacom_features wacom_features_0xD8 =
        { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN,   21648, 13530, 1023, 63, BAMBOO_PT };
 static struct wacom_features wacom_features_0xDA =
@@ -1510,6 +1512,7 @@ const struct usb_device_id wacom_ids[] = {
        { USB_DEVICE_WACOM(0xD1) },
        { USB_DEVICE_WACOM(0xD2) },
        { USB_DEVICE_WACOM(0xD3) },
+       { USB_DEVICE_WACOM(0xD4) },
        { USB_DEVICE_WACOM(0xD8) },
        { USB_DEVICE_WACOM(0xDA) },
        { USB_DEVICE_WACOM(0xDB) },
index 84c46a161927999ebfc6c5d56d98e76247e66ae4..e71c5fa527f59ec3e6ea5fd6ce7d09746bfc437e 100644 (file)
@@ -371,10 +371,15 @@ static void md_end_flush(struct bio *bio, int err)
        bio_put(bio);
 }
 
-static void submit_flushes(mddev_t *mddev)
+static void md_submit_flush_data(struct work_struct *ws);
+
+static void submit_flushes(struct work_struct *ws)
 {
+       mddev_t *mddev = container_of(ws, mddev_t, flush_work);
        mdk_rdev_t *rdev;
 
+       INIT_WORK(&mddev->flush_work, md_submit_flush_data);
+       atomic_set(&mddev->flush_pending, 1);
        rcu_read_lock();
        list_for_each_entry_rcu(rdev, &mddev->disks, same_set)
                if (rdev->raid_disk >= 0 &&
@@ -397,6 +402,8 @@ static void submit_flushes(mddev_t *mddev)
                        rdev_dec_pending(rdev, mddev);
                }
        rcu_read_unlock();
+       if (atomic_dec_and_test(&mddev->flush_pending))
+               queue_work(md_wq, &mddev->flush_work);
 }
 
 static void md_submit_flush_data(struct work_struct *ws)
@@ -404,8 +411,6 @@ static void md_submit_flush_data(struct work_struct *ws)
        mddev_t *mddev = container_of(ws, mddev_t, flush_work);
        struct bio *bio = mddev->flush_bio;
 
-       atomic_set(&mddev->flush_pending, 1);
-
        if (bio->bi_size == 0)
                /* an empty barrier - all done */
                bio_endio(bio, 0);
@@ -414,10 +419,9 @@ static void md_submit_flush_data(struct work_struct *ws)
                if (mddev->pers->make_request(mddev, bio))
                        generic_make_request(bio);
        }
-       if (atomic_dec_and_test(&mddev->flush_pending)) {
-               mddev->flush_bio = NULL;
-               wake_up(&mddev->sb_wait);
-       }
+
+       mddev->flush_bio = NULL;
+       wake_up(&mddev->sb_wait);
 }
 
 void md_flush_request(mddev_t *mddev, struct bio *bio)
@@ -429,13 +433,8 @@ void md_flush_request(mddev_t *mddev, struct bio *bio)
        mddev->flush_bio = bio;
        spin_unlock_irq(&mddev->write_lock);
 
-       atomic_set(&mddev->flush_pending, 1);
-       INIT_WORK(&mddev->flush_work, md_submit_flush_data);
-
-       submit_flushes(mddev);
-
-       if (atomic_dec_and_test(&mddev->flush_pending))
-               queue_work(md_wq, &mddev->flush_work);
+       INIT_WORK(&mddev->flush_work, submit_flushes);
+       queue_work(md_wq, &mddev->flush_work);
 }
 EXPORT_SYMBOL(md_flush_request);
 
@@ -5160,7 +5159,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
                                PTR_ERR(rdev));
                        return PTR_ERR(rdev);
                }
-               /* set save_raid_disk if appropriate */
+               /* set saved_raid_disk if appropriate */
                if (!mddev->persistent) {
                        if (info->state & (1<<MD_DISK_SYNC)  &&
                            info->raid_disk < mddev->raid_disks)
@@ -5170,7 +5169,10 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
                } else
                        super_types[mddev->major_version].
                                validate_super(mddev, rdev);
-               rdev->saved_raid_disk = rdev->raid_disk;
+               if (test_bit(In_sync, &rdev->flags))
+                       rdev->saved_raid_disk = rdev->raid_disk;
+               else
+                       rdev->saved_raid_disk = -1;
 
                clear_bit(In_sync, &rdev->flags); /* just to be sure */
                if (info->state & (1<<MD_DISK_WRITEMOSTLY))
@@ -6042,9 +6044,8 @@ static int md_thread(void * arg)
                         || kthread_should_stop(),
                         thread->timeout);
 
-               clear_bit(THREAD_WAKEUP, &thread->flags);
-
-               thread->run(thread->mddev);
+               if (test_and_clear_bit(THREAD_WAKEUP, &thread->flags))
+                       thread->run(thread->mddev);
        }
 
        return 0;
index c67aa54694ae72605b2165949fe1033dc2d542b9..0641674827f06786dee5549ada83b23820928748 100644 (file)
@@ -2397,13 +2397,13 @@ static int run(mddev_t *mddev)
        return 0;
 
 out_free_conf:
+       md_unregister_thread(mddev->thread);
        if (conf->r10bio_pool)
                mempool_destroy(conf->r10bio_pool);
        safe_put_page(conf->tmppage);
        kfree(conf->mirrors);
        kfree(conf);
        mddev->private = NULL;
-       md_unregister_thread(mddev->thread);
 out:
        return -EIO;
 }
index 5bf4985daede6a49e9b35adcb3b3256b51a14924..05e832f61c3e88772e1ae8b3b1059a0825a5b86c 100644 (file)
@@ -361,7 +361,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
 
 static const struct v4l2_file_operations rtrack_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops rtrack_ioctl_ops = {
@@ -412,13 +412,6 @@ static int __init rtrack_init(void)
        rt->vdev.release = video_device_release_empty;
        video_set_drvdata(&rt->vdev, rt);
 
-       if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
-               v4l2_device_unregister(&rt->v4l2_dev);
-               release_region(rt->io, 2);
-               return -EINVAL;
-       }
-       v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n");
-
        /* Set up the I/O locking */
 
        mutex_init(&rt->lock);
@@ -430,6 +423,13 @@ static int __init rtrack_init(void)
        sleep_delay(2000000);   /* make sure it's totally down  */
        outb(0xc0, rt->io);             /* steady volume, mute card     */
 
+       if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+               v4l2_device_unregister(&rt->v4l2_dev);
+               release_region(rt->io, 2);
+               return -EINVAL;
+       }
+       v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n");
+
        return 0;
 }
 
index c22311393624d26ebfbe0d4db8776a7c536b3a70..dd8a6ab0d437ab10022d1b65f1d802cc8d2b006c 100644 (file)
@@ -324,7 +324,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
 
 static const struct v4l2_file_operations aztech_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops aztech_ioctl_ops = {
@@ -375,6 +375,8 @@ static int __init aztech_init(void)
        az->vdev.ioctl_ops = &aztech_ioctl_ops;
        az->vdev.release = video_device_release_empty;
        video_set_drvdata(&az->vdev, az);
+       /* mute card - prevents noisy bootups */
+       outb(0, az->io);
 
        if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
                v4l2_device_unregister(v4l2_dev);
@@ -383,8 +385,6 @@ static int __init aztech_init(void)
        }
 
        v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
-       /* mute card - prevents noisy bootups */
-       outb(0, az->io);
        return 0;
 }
 
index b701ea6e7c7379fc0593fae6c22c4678152cd4e7..bc9ad0897c559b9142aea9ba7cbf486caaf1d5c4 100644 (file)
@@ -328,11 +328,10 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo
        unsigned char readbuf[RDS_BUFFER];
        int i = 0;
 
+       mutex_lock(&dev->lock);
        if (dev->rdsstat == 0) {
-               mutex_lock(&dev->lock);
                dev->rdsstat = 1;
                outb(0x80, dev->io);        /* Select RDS fifo */
-               mutex_unlock(&dev->lock);
                init_timer(&dev->readtimer);
                dev->readtimer.function = cadet_handler;
                dev->readtimer.data = (unsigned long)dev;
@@ -340,12 +339,15 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo
                add_timer(&dev->readtimer);
        }
        if (dev->rdsin == dev->rdsout) {
+               mutex_unlock(&dev->lock);
                if (file->f_flags & O_NONBLOCK)
                        return -EWOULDBLOCK;
                interruptible_sleep_on(&dev->read_queue);
+               mutex_lock(&dev->lock);
        }
        while (i < count && dev->rdsin != dev->rdsout)
                readbuf[i++] = dev->rdsbuf[dev->rdsout++];
+       mutex_unlock(&dev->lock);
 
        if (copy_to_user(data, readbuf, i))
                return -EFAULT;
@@ -525,9 +527,11 @@ static int cadet_open(struct file *file)
 {
        struct cadet *dev = video_drvdata(file);
 
+       mutex_lock(&dev->lock);
        dev->users++;
        if (1 == dev->users)
                init_waitqueue_head(&dev->read_queue);
+       mutex_unlock(&dev->lock);
        return 0;
 }
 
@@ -535,11 +539,13 @@ static int cadet_release(struct file *file)
 {
        struct cadet *dev = video_drvdata(file);
 
+       mutex_lock(&dev->lock);
        dev->users--;
        if (0 == dev->users) {
                del_timer_sync(&dev->readtimer);
                dev->rdsstat = 0;
        }
+       mutex_unlock(&dev->lock);
        return 0;
 }
 
@@ -559,7 +565,7 @@ static const struct v4l2_file_operations cadet_fops = {
        .open           = cadet_open,
        .release        = cadet_release,
        .read           = cadet_read,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
        .poll           = cadet_poll,
 };
 
index 79039674a0e0bddff9976de584437a60b948e789..28fa85ba2087cfd56c067ac51a9669945eb44757 100644 (file)
@@ -361,7 +361,7 @@ MODULE_DEVICE_TABLE(pci, gemtek_pci_id);
 
 static const struct v4l2_file_operations gemtek_pci_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = {
@@ -422,11 +422,11 @@ static int __devinit gemtek_pci_probe(struct pci_dev *pdev, const struct pci_dev
        card->vdev.release = video_device_release_empty;
        video_set_drvdata(&card->vdev, card);
 
+       gemtek_pci_mute(card);
+
        if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0)
                goto err_video;
 
-       gemtek_pci_mute(card);
-
        v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n",
                pdev->revision, card->iobase, card->iobase + card->length - 1);
 
index 73985f641f072d361d128f769530281b150ffbfb..259936422e493b4dcf6dd6742d17bc5acd5b2995 100644 (file)
@@ -378,7 +378,7 @@ static int gemtek_probe(struct gemtek *gt)
 
 static const struct v4l2_file_operations gemtek_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static int vidioc_querycap(struct file *file, void *priv,
@@ -577,12 +577,6 @@ static int __init gemtek_init(void)
        gt->vdev.release = video_device_release_empty;
        video_set_drvdata(&gt->vdev, gt);
 
-       if (video_register_device(&gt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
-               v4l2_device_unregister(v4l2_dev);
-               release_region(gt->io, 1);
-               return -EBUSY;
-       }
-
        /* Set defaults */
        gt->lastfreq = GEMTEK_LOWFREQ;
        gt->bu2614data = 0;
@@ -590,6 +584,12 @@ static int __init gemtek_init(void)
        if (initmute)
                gemtek_mute(gt);
 
+       if (video_register_device(&gt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+               v4l2_device_unregister(v4l2_dev);
+               release_region(gt->io, 1);
+               return -EBUSY;
+       }
+
        return 0;
 }
 
index 08f1051979cae6f7508026dc0e957a23de775795..6af61bfeb1780089718f96884f6dc0dfc8550943 100644 (file)
@@ -299,7 +299,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
 
 static const struct v4l2_file_operations maestro_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
@@ -383,22 +383,20 @@ static int __devinit maestro_probe(struct pci_dev *pdev,
        dev->vdev.release = video_device_release_empty;
        video_set_drvdata(&dev->vdev, dev);
 
+       if (!radio_power_on(dev)) {
+               retval = -EIO;
+               goto errfr1;
+       }
+
        retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr);
        if (retval) {
                v4l2_err(v4l2_dev, "can't register video device!\n");
                goto errfr1;
        }
 
-       if (!radio_power_on(dev)) {
-               retval = -EIO;
-               goto errunr;
-       }
-
        v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n");
 
        return 0;
-errunr:
-       video_unregister_device(&dev->vdev);
 errfr1:
        v4l2_device_unregister(v4l2_dev);
 errfr:
index 255d40df4b461e9e5287462c08901a78758a565f..6459a220b0dd46ddb22326e0595f8964ae4915d2 100644 (file)
@@ -346,7 +346,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
 
 static const struct v4l2_file_operations maxiradio_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = {
index 4ff885445fd455371823ad55a00f82e4c2afdcfe..3fb76e3834c99da96e8621ab4ecd89458913d259 100644 (file)
@@ -33,6 +33,7 @@ struct pcm20 {
        unsigned long freq;
        int muted;
        struct snd_miro_aci *aci;
+       struct mutex lock;
 };
 
 static struct pcm20 pcm20_card = {
@@ -72,7 +73,7 @@ static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq)
 
 static const struct v4l2_file_operations pcm20_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static int vidioc_querycap(struct file *file, void *priv,
@@ -229,7 +230,7 @@ static int __init pcm20_init(void)
                return -ENODEV;
        }
        strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name));
-
+       mutex_init(&dev->lock);
 
        res = v4l2_device_register(NULL, v4l2_dev);
        if (res < 0) {
@@ -242,6 +243,7 @@ static int __init pcm20_init(void)
        dev->vdev.fops = &pcm20_fops;
        dev->vdev.ioctl_ops = &pcm20_ioctl_ops;
        dev->vdev.release = video_device_release_empty;
+       dev->vdev.lock = &dev->lock;
        video_set_drvdata(&dev->vdev, dev);
 
        if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0)
index a79296aac9a9636e408a27a7da9a42cf9c4e21e3..8d6ea591bd188815c374ddf5c5e603a5aa3d6e8e 100644 (file)
@@ -266,7 +266,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
 
 static const struct v4l2_file_operations rtrack2_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = {
@@ -315,6 +315,10 @@ static int __init rtrack2_init(void)
        dev->vdev.release = video_device_release_empty;
        video_set_drvdata(&dev->vdev, dev);
 
+       /* mute card - prevents noisy bootups */
+       outb(1, dev->io);
+       dev->muted = 1;
+
        mutex_init(&dev->lock);
        if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
                v4l2_device_unregister(v4l2_dev);
@@ -324,10 +328,6 @@ static int __init rtrack2_init(void)
 
        v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n");
 
-       /* mute card - prevents noisy bootups */
-       outb(1, dev->io);
-       dev->muted = 1;
-
        return 0;
 }
 
index 985359d18aa58fd8e350d0e06b05b66020534bc5..b5a5f89e238a91fe432326d0da9487cf32ad9943 100644 (file)
@@ -260,7 +260,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
 
 static const struct v4l2_file_operations fmi_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops fmi_ioctl_ops = {
@@ -382,6 +382,9 @@ static int __init fmi_init(void)
 
        mutex_init(&fmi->lock);
 
+       /* mute card - prevents noisy bootups */
+       fmi_mute(fmi);
+
        if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
                v4l2_device_unregister(v4l2_dev);
                release_region(fmi->io, 2);
@@ -391,8 +394,6 @@ static int __init fmi_init(void)
        }
 
        v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io);
-       /* mute card - prevents noisy bootups */
-       fmi_mute(fmi);
        return 0;
 }
 
index 52c7bbb32b8b7ea10312ff58716c47f1ed472bd2..dc3f04c52d5e11e923829e74a548d78d1b3e6cad 100644 (file)
@@ -376,7 +376,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
 
 static const struct v4l2_file_operations fmr2_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops fmr2_ioctl_ops = {
@@ -424,6 +424,10 @@ static int __init fmr2_init(void)
        fmr2->vdev.release = video_device_release_empty;
        video_set_drvdata(&fmr2->vdev, fmr2);
 
+       /* mute card - prevents noisy bootups */
+       fmr2_mute(fmr2->io);
+       fmr2_product_info(fmr2);
+
        if (video_register_device(&fmr2->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
                v4l2_device_unregister(v4l2_dev);
                release_region(fmr2->io, 2);
@@ -431,11 +435,6 @@ static int __init fmr2_init(void)
        }
 
        v4l2_info(v4l2_dev, "SF16FMR2 radio card driver at 0x%x.\n", fmr2->io);
-       /* mute card - prevents noisy bootups */
-       mutex_lock(&fmr2->lock);
-       fmr2_mute(fmr2->io);
-       fmr2_product_info(fmr2);
-       mutex_unlock(&fmr2->lock);
        debug_print((KERN_DEBUG "card_type %d\n", fmr2->card_type));
        return 0;
 }
index 03829e6818bd4bc156d922c7c19ee8daaabc0fc8..726d367ad8d0f2119b5e832d8ccca593d2a6d3fa 100644 (file)
@@ -53,7 +53,8 @@ struct radio_si4713_device {
 /* radio_si4713_fops - file operations interface */
 static const struct v4l2_file_operations radio_si4713_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       /* Note: locking is done at the subdev level in the i2c driver. */
+       .unlocked_ioctl = video_ioctl2,
 };
 
 /* Video4Linux Interface */
index 789d2ec66e1948d2d071c3424f92dc820b0bcc0b..0e71d816c725885535cc4d1da4f992809d0d6257 100644 (file)
@@ -142,7 +142,6 @@ struct tea5764_device {
        struct video_device             *videodev;
        struct tea5764_regs             regs;
        struct mutex                    mutex;
-       int                             users;
 };
 
 /* I2C code related */
@@ -458,41 +457,10 @@ static int vidioc_s_audio(struct file *file, void *priv,
        return 0;
 }
 
-static int tea5764_open(struct file *file)
-{
-       /* Currently we support only one device */
-       struct tea5764_device *radio = video_drvdata(file);
-
-       mutex_lock(&radio->mutex);
-       /* Only exclusive access */
-       if (radio->users) {
-               mutex_unlock(&radio->mutex);
-               return -EBUSY;
-       }
-       radio->users++;
-       mutex_unlock(&radio->mutex);
-       file->private_data = radio;
-       return 0;
-}
-
-static int tea5764_close(struct file *file)
-{
-       struct tea5764_device *radio = video_drvdata(file);
-
-       if (!radio)
-               return -ENODEV;
-       mutex_lock(&radio->mutex);
-       radio->users--;
-       mutex_unlock(&radio->mutex);
-       return 0;
-}
-
 /* File system interface */
 static const struct v4l2_file_operations tea5764_fops = {
        .owner          = THIS_MODULE,
-       .open           = tea5764_open,
-       .release        = tea5764_close,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops tea5764_ioctl_ops = {
@@ -527,7 +495,7 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client,
        int ret;
 
        PDEBUG("probe");
-       radio = kmalloc(sizeof(struct tea5764_device), GFP_KERNEL);
+       radio = kzalloc(sizeof(struct tea5764_device), GFP_KERNEL);
        if (!radio)
                return -ENOMEM;
 
@@ -555,12 +523,7 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client,
 
        i2c_set_clientdata(client, radio);
        video_set_drvdata(radio->videodev, radio);
-
-       ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
-       if (ret < 0) {
-               PWARN("Could not register video device!");
-               goto errrel;
-       }
+       radio->videodev->lock = &radio->mutex;
 
        /* initialize and power off the chip */
        tea5764_i2c_read(radio);
@@ -568,6 +531,12 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client,
        tea5764_mute(radio, 1);
        tea5764_power_down(radio);
 
+       ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
+       if (ret < 0) {
+               PWARN("Could not register video device!");
+               goto errrel;
+       }
+
        PINFO("registered.");
        return 0;
 errrel:
index fc1c860fd43844c188d4e42cc845a5f40b4ae957..a32663917059c1cd4734247452c33444c02ad5d2 100644 (file)
@@ -338,7 +338,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
 
 static const struct v4l2_file_operations terratec_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops terratec_ioctl_ops = {
@@ -389,6 +389,9 @@ static int __init terratec_init(void)
 
        mutex_init(&tt->lock);
 
+       /* mute card - prevents noisy bootups */
+       tt_write_vol(tt, 0);
+
        if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
                v4l2_device_unregister(&tt->v4l2_dev);
                release_region(tt->io, 2);
@@ -396,9 +399,6 @@ static int __init terratec_init(void)
        }
 
        v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n");
-
-       /* mute card - prevents noisy bootups */
-       tt_write_vol(tt, 0);
        return 0;
 }
 
index b8bb3ef47df5c72153e7e1964ddbc679b3c1b8ed..a185610b376be1a14e79b52751c7f95aab777dd0 100644 (file)
@@ -34,6 +34,7 @@ struct timbradio {
        struct v4l2_subdev      *sd_dsp;
        struct video_device     video_dev;
        struct v4l2_device      v4l2_dev;
+       struct mutex            lock;
 };
 
 
@@ -142,7 +143,7 @@ static const struct v4l2_ioctl_ops timbradio_ioctl_ops = {
 
 static const struct v4l2_file_operations timbradio_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static int __devinit timbradio_probe(struct platform_device *pdev)
@@ -164,6 +165,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev)
        }
 
        tr->pdata = *pdata;
+       mutex_init(&tr->lock);
 
        strlcpy(tr->video_dev.name, "Timberdale Radio",
                sizeof(tr->video_dev.name));
@@ -171,6 +173,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev)
        tr->video_dev.ioctl_ops = &timbradio_ioctl_ops;
        tr->video_dev.release = video_device_release_empty;
        tr->video_dev.minor = -1;
+       tr->video_dev.lock = &tr->lock;
 
        strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name));
        err = v4l2_device_register(NULL, &tr->v4l2_dev);
index 9d6dcf8af5b01de328436a0955ae190fe651aa72..22fa9cc28abed060cff57e1e3a78227575c9ee36 100644 (file)
@@ -344,7 +344,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
 
 static const struct v4l2_file_operations trust_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops trust_ioctl_ops = {
@@ -396,14 +396,6 @@ static int __init trust_init(void)
        tr->vdev.release = video_device_release_empty;
        video_set_drvdata(&tr->vdev, tr);
 
-       if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
-               v4l2_device_unregister(v4l2_dev);
-               release_region(tr->io, 2);
-               return -EINVAL;
-       }
-
-       v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n");
-
        write_i2c(tr, 2, TDA7318_ADDR, 0x80);   /* speaker att. LF = 0 dB */
        write_i2c(tr, 2, TDA7318_ADDR, 0xa0);   /* speaker att. RF = 0 dB */
        write_i2c(tr, 2, TDA7318_ADDR, 0xc0);   /* speaker att. LR = 0 dB */
@@ -418,6 +410,14 @@ static int __init trust_init(void)
        /* mute card - prevents noisy bootups */
        tr_setmute(tr, 1);
 
+       if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+               v4l2_device_unregister(v4l2_dev);
+               release_region(tr->io, 2);
+               return -EINVAL;
+       }
+
+       v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n");
+
        return 0;
 }
 
index b1f630527dc12df962d9eeef051413e800e6a785..8dbbf08f22077ad2b7c84e8e3992d3b33eab88e7 100644 (file)
@@ -317,7 +317,7 @@ static int vidioc_log_status(struct file *file, void *priv)
 
 static const struct v4l2_file_operations typhoon_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops typhoon_ioctl_ops = {
@@ -344,18 +344,18 @@ static int __init typhoon_init(void)
 
        strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name));
        dev->io = io;
-       dev->curfreq = dev->mutefreq = mutefreq;
 
        if (dev->io == -1) {
                v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n");
                return -EINVAL;
        }
 
-       if (dev->mutefreq < 87000 || dev->mutefreq > 108500) {
+       if (mutefreq < 87000 || mutefreq > 108500) {
                v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n");
                v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n");
                return -EINVAL;
        }
+       dev->curfreq = dev->mutefreq = mutefreq << 4;
 
        mutex_init(&dev->lock);
        if (!request_region(dev->io, 8, "typhoon")) {
@@ -378,17 +378,17 @@ static int __init typhoon_init(void)
        dev->vdev.ioctl_ops = &typhoon_ioctl_ops;
        dev->vdev.release = video_device_release_empty;
        video_set_drvdata(&dev->vdev, dev);
+
+       /* mute card - prevents noisy bootups */
+       typhoon_mute(dev);
+
        if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
                v4l2_device_unregister(&dev->v4l2_dev);
                release_region(dev->io, 8);
                return -EINVAL;
        }
        v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io);
-       v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", dev->mutefreq);
-       dev->mutefreq <<= 4;
-
-       /* mute card - prevents noisy bootups */
-       typhoon_mute(dev);
+       v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", mutefreq);
 
        return 0;
 }
index f31eab99c943ba9cdc722e7b3163ed91f079d8a1..af99c5bd88c1f0ce15311ec63c137aeee2ce42ab 100644 (file)
@@ -377,7 +377,7 @@ static int vidioc_s_audio(struct file *file, void *priv,
 static const struct v4l2_file_operations zoltrix_fops =
 {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = {
@@ -424,20 +424,6 @@ static int __init zoltrix_init(void)
                return res;
        }
 
-       strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name));
-       zol->vdev.v4l2_dev = v4l2_dev;
-       zol->vdev.fops = &zoltrix_fops;
-       zol->vdev.ioctl_ops = &zoltrix_ioctl_ops;
-       zol->vdev.release = video_device_release_empty;
-       video_set_drvdata(&zol->vdev, zol);
-
-       if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
-               v4l2_device_unregister(v4l2_dev);
-               release_region(zol->io, 2);
-               return -EINVAL;
-       }
-       v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n");
-
        mutex_init(&zol->lock);
 
        /* mute card - prevents noisy bootups */
@@ -452,6 +438,20 @@ static int __init zoltrix_init(void)
        zol->curvol = 0;
        zol->stereo = 1;
 
+       strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name));
+       zol->vdev.v4l2_dev = v4l2_dev;
+       zol->vdev.fops = &zoltrix_fops;
+       zol->vdev.ioctl_ops = &zoltrix_ioctl_ops;
+       zol->vdev.release = video_device_release_empty;
+       video_set_drvdata(&zol->vdev, zol);
+
+       if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+               v4l2_device_unregister(v4l2_dev);
+               release_region(zol->io, 2);
+               return -EINVAL;
+       }
+       v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n");
+
        return 0;
 }
 
index 31e7a123d19a954f86808ec80ae8978fd044d3d8..f989f2820d88e90f49f5b4fc6081002126c0c3c2 100644 (file)
@@ -712,7 +712,7 @@ static int ar_initialize(struct ar *ar)
 static const struct v4l2_file_operations ar_fops = {
        .owner          = THIS_MODULE,
        .read           = ar_read,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops ar_ioctl_ops = {
index 935e0c9a96744aa1e4f0cd3d443c8ee4c8b407d2..c1193506131c3a37e3c347a8703771a98f3938af 100644 (file)
@@ -860,7 +860,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
 
 static const struct v4l2_file_operations qcam_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
        .read           = qcam_read,
 };
 
index 6e4b19698c13fe6212ee08cfd0d9bee7be3cf964..24fc00965a12d048be055498230b734b794283fa 100644 (file)
@@ -718,7 +718,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
 
 static const struct v4l2_file_operations qcam_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
        .read           = qcam_read,
 };
 
index 260c666ce9317266fb271ffead70ea1605e99db1..0dfff50891e404056059eaf18316bd81fed0824f 100644 (file)
@@ -1775,7 +1775,7 @@ static const struct v4l2_file_operations cafe_v4l_fops = {
        .read = cafe_v4l_read,
        .poll = cafe_v4l_poll,
        .mmap = cafe_v4l_mmap,
-       .ioctl = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = {
index 8f55692db36d278e01191bd3fd2ea9e380c90965..82d195be91976ad18ae3cb9059e64efcf2c44788 100644 (file)
@@ -218,7 +218,13 @@ static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream)
 static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream,
                     unsigned int cmd, void *arg)
 {
-       return snd_pcm_lib_ioctl(substream, cmd, arg);
+       struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream);
+       int ret;
+
+       snd_cx18_lock(cxsc);
+       ret = snd_pcm_lib_ioctl(substream, cmd, arg);
+       snd_cx18_unlock(cxsc);
+       return ret;
 }
 
 
index 9045f1ece0ebb35cdb1b85eec68b96cc2344fcfc..ab461e27d9dd1ad6206e9054f391605556563a74 100644 (file)
@@ -41,7 +41,7 @@ static struct v4l2_file_operations cx18_v4l2_enc_fops = {
        .read = cx18_v4l2_read,
        .open = cx18_v4l2_open,
        /* FIXME change to video_ioctl2 if serialization lock can be removed */
-       .ioctl = cx18_v4l2_ioctl,
+       .unlocked_ioctl = cx18_v4l2_ioctl,
        .release = cx18_v4l2_close,
        .poll = cx18_v4l2_enc_poll,
 };
index a5cfc76b40b71e26dcc68e41f1f0b8acdf128e51..bb164099ea2c866a4a250664dbd7f06ddf48767c 100644 (file)
@@ -2530,7 +2530,7 @@ static const struct v4l2_file_operations et61x251_fops = {
        .owner = THIS_MODULE,
        .open =    et61x251_open,
        .release = et61x251_release,
-       .ioctl =   et61x251_ioctl,
+       .unlocked_ioctl =   et61x251_ioctl,
        .read =    et61x251_read,
        .poll =    et61x251_poll,
        .mmap =    et61x251_mmap,
index 2be23bccd3c89e9a72b1131cb6bf1804df1434d0..48d2c2419c13134abf0c55cdf347bdfd97c897bd 100644 (file)
@@ -1659,7 +1659,7 @@ static const struct v4l2_file_operations meye_fops = {
        .open           = meye_open,
        .release        = meye_release,
        .mmap           = meye_mmap,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
        .poll           = meye_poll,
 };
 
@@ -1831,12 +1831,6 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
        msleep(1);
        mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
 
-       if (video_register_device(meye.vdev, VFL_TYPE_GRABBER,
-                                 video_nr) < 0) {
-               v4l2_err(v4l2_dev, "video_register_device failed\n");
-               goto outvideoreg;
-       }
-
        mutex_init(&meye.lock);
        init_waitqueue_head(&meye.proc_list);
        meye.brightness = 32 << 10;
@@ -1858,6 +1852,12 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
        sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0);
        sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48);
 
+       if (video_register_device(meye.vdev, VFL_TYPE_GRABBER,
+                                 video_nr) < 0) {
+               v4l2_err(v4l2_dev, "video_register_device failed\n");
+               goto outvideoreg;
+       }
+
        v4l2_info(v4l2_dev, "Motion Eye Camera Driver v%s.\n",
               MEYE_DRIVER_VERSION);
        v4l2_info(v4l2_dev, "mchip KL5A72002 rev. %d, base %lx, irq %d\n",
index 7129b50757dbd7605fa13449bd7793511019f52f..7551907f8c280f4b9f896094ea9fe0cc079bfd19 100644 (file)
@@ -932,7 +932,7 @@ static ssize_t pms_read(struct file *file, char __user *buf,
 
 static const struct v4l2_file_operations pms_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
        .read           = pms_read,
 };
 
index 4e5a8cf76dedf7807b5a11ef5369f3f86c3c537c..07cf0c6c7c1f7a210c3a078fc580ee68845535c6 100644 (file)
@@ -75,6 +75,7 @@ struct sh_vou_device {
        int pix_idx;
        struct videobuf_buffer *active;
        enum sh_vou_status status;
+       struct mutex fop_lock;
 };
 
 struct sh_vou_file {
@@ -235,7 +236,7 @@ static void free_buffer(struct videobuf_queue *vq, struct videobuf_buffer *vb)
        vb->state = VIDEOBUF_NEEDS_INIT;
 }
 
-/* Locking: caller holds vq->vb_lock mutex */
+/* Locking: caller holds fop_lock mutex */
 static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count,
                            unsigned int *size)
 {
@@ -257,7 +258,7 @@ static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count,
        return 0;
 }
 
-/* Locking: caller holds vq->vb_lock mutex */
+/* Locking: caller holds fop_lock mutex */
 static int sh_vou_buf_prepare(struct videobuf_queue *vq,
                              struct videobuf_buffer *vb,
                              enum v4l2_field field)
@@ -306,7 +307,7 @@ static int sh_vou_buf_prepare(struct videobuf_queue *vq,
        return 0;
 }
 
-/* Locking: caller holds vq->vb_lock mutex and vq->irqlock spinlock */
+/* Locking: caller holds fop_lock mutex and vq->irqlock spinlock */
 static void sh_vou_buf_queue(struct videobuf_queue *vq,
                             struct videobuf_buffer *vb)
 {
@@ -1190,7 +1191,7 @@ static int sh_vou_open(struct file *file)
                                       V4L2_BUF_TYPE_VIDEO_OUTPUT,
                                       V4L2_FIELD_NONE,
                                       sizeof(struct videobuf_buffer), vdev,
-                                      NULL);
+                                      &vou_dev->fop_lock);
 
        return 0;
 }
@@ -1292,7 +1293,7 @@ static const struct v4l2_file_operations sh_vou_fops = {
        .owner          = THIS_MODULE,
        .open           = sh_vou_open,
        .release        = sh_vou_release,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
        .mmap           = sh_vou_mmap,
        .poll           = sh_vou_poll,
 };
@@ -1331,6 +1332,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev)
 
        INIT_LIST_HEAD(&vou_dev->queue);
        spin_lock_init(&vou_dev->lock);
+       mutex_init(&vou_dev->fop_lock);
        atomic_set(&vou_dev->use_count, 0);
        vou_dev->pdata = vou_pdata;
        vou_dev->status = SH_VOU_IDLE;
@@ -1388,6 +1390,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev)
                vdev->tvnorms |= V4L2_STD_PAL;
        vdev->v4l2_dev = &vou_dev->v4l2_dev;
        vdev->release = video_device_release;
+       vdev->lock = &vou_dev->fop_lock;
 
        vou_dev->vdev = vdev;
        video_set_drvdata(vdev, vou_dev);
index 28e19daadec953b879084ec539a17eed2da147a6..f49fbfb7dc1377800da49d0c723caa13a5d14e27 100644 (file)
@@ -3238,7 +3238,7 @@ static const struct v4l2_file_operations sn9c102_fops = {
        .owner = THIS_MODULE,
        .open = sn9c102_open,
        .release = sn9c102_release,
-       .ioctl = sn9c102_ioctl,
+       .unlocked_ioctl = sn9c102_ioctl,
        .read = sn9c102_read,
        .poll = sn9c102_poll,
        .mmap = sn9c102_mmap,
index f169f77366771a925978e65a9eeae7c18d49b812..59f8a9ad3796c3ef5960b4e77f12a7269ea7b7b9 100644 (file)
@@ -785,7 +785,7 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id,
        }
 }
 
-struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
+static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
        __u32 v4l2_id, struct uvc_control_mapping **mapping)
 {
        struct uvc_control *ctrl = NULL;
@@ -944,6 +944,52 @@ done:
        return ret;
 }
 
+/*
+ * Mapping V4L2 controls to UVC controls can be straighforward if done well.
+ * Most of the UVC controls exist in V4L2, and can be mapped directly. Some
+ * must be grouped (for instance the Red Balance, Blue Balance and Do White
+ * Balance V4L2 controls use the White Balance Component UVC control) or
+ * otherwise translated. The approach we take here is to use a translation
+ * table for the controls that can be mapped directly, and handle the others
+ * manually.
+ */
+int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
+       struct v4l2_querymenu *query_menu)
+{
+       struct uvc_menu_info *menu_info;
+       struct uvc_control_mapping *mapping;
+       struct uvc_control *ctrl;
+       u32 index = query_menu->index;
+       u32 id = query_menu->id;
+       int ret;
+
+       memset(query_menu, 0, sizeof(*query_menu));
+       query_menu->id = id;
+       query_menu->index = index;
+
+       ret = mutex_lock_interruptible(&chain->ctrl_mutex);
+       if (ret < 0)
+               return -ERESTARTSYS;
+
+       ctrl = uvc_find_control(chain, query_menu->id, &mapping);
+       if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) {
+               ret = -EINVAL;
+               goto done;
+       }
+
+       if (query_menu->index >= mapping->menu_count) {
+               ret = -EINVAL;
+               goto done;
+       }
+
+       menu_info = &mapping->menu_info[query_menu->index];
+       strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
+
+done:
+       mutex_unlock(&chain->ctrl_mutex);
+       return ret;
+}
+
 
 /* --------------------------------------------------------------------------
  * Control transactions
index ed6d5449741c58cb7b546b8a09a0b21f82759794..f14581bd707f0155248f788382fe6452cad7198c 100644 (file)
@@ -89,6 +89,39 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type,
        queue->type = type;
 }
 
+/*
+ * Free the video buffers.
+ *
+ * This function must be called with the queue lock held.
+ */
+static int __uvc_free_buffers(struct uvc_video_queue *queue)
+{
+       unsigned int i;
+
+       for (i = 0; i < queue->count; ++i) {
+               if (queue->buffer[i].vma_use_count != 0)
+                       return -EBUSY;
+       }
+
+       if (queue->count) {
+               vfree(queue->mem);
+               queue->count = 0;
+       }
+
+       return 0;
+}
+
+int uvc_free_buffers(struct uvc_video_queue *queue)
+{
+       int ret;
+
+       mutex_lock(&queue->mutex);
+       ret = __uvc_free_buffers(queue);
+       mutex_unlock(&queue->mutex);
+
+       return ret;
+}
+
 /*
  * Allocate the video buffers.
  *
@@ -110,7 +143,7 @@ int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers,
 
        mutex_lock(&queue->mutex);
 
-       if ((ret = uvc_free_buffers(queue)) < 0)
+       if ((ret = __uvc_free_buffers(queue)) < 0)
                goto done;
 
        /* Bail out if no buffers should be allocated. */
@@ -151,28 +184,6 @@ done:
        return ret;
 }
 
-/*
- * Free the video buffers.
- *
- * This function must be called with the queue lock held.
- */
-int uvc_free_buffers(struct uvc_video_queue *queue)
-{
-       unsigned int i;
-
-       for (i = 0; i < queue->count; ++i) {
-               if (queue->buffer[i].vma_use_count != 0)
-                       return -EBUSY;
-       }
-
-       if (queue->count) {
-               vfree(queue->mem);
-               queue->count = 0;
-       }
-
-       return 0;
-}
-
 /*
  * Check if buffers have been allocated.
  */
@@ -368,6 +379,82 @@ done:
        return ret;
 }
 
+/*
+ * VMA operations.
+ */
+static void uvc_vm_open(struct vm_area_struct *vma)
+{
+       struct uvc_buffer *buffer = vma->vm_private_data;
+       buffer->vma_use_count++;
+}
+
+static void uvc_vm_close(struct vm_area_struct *vma)
+{
+       struct uvc_buffer *buffer = vma->vm_private_data;
+       buffer->vma_use_count--;
+}
+
+static const struct vm_operations_struct uvc_vm_ops = {
+       .open           = uvc_vm_open,
+       .close          = uvc_vm_close,
+};
+
+/*
+ * Memory-map a video buffer.
+ *
+ * This function implements video buffers memory mapping and is intended to be
+ * used by the device mmap handler.
+ */
+int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
+{
+       struct uvc_buffer *uninitialized_var(buffer);
+       struct page *page;
+       unsigned long addr, start, size;
+       unsigned int i;
+       int ret = 0;
+
+       start = vma->vm_start;
+       size = vma->vm_end - vma->vm_start;
+
+       mutex_lock(&queue->mutex);
+
+       for (i = 0; i < queue->count; ++i) {
+               buffer = &queue->buffer[i];
+               if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
+                       break;
+       }
+
+       if (i == queue->count || size != queue->buf_size) {
+               ret = -EINVAL;
+               goto done;
+       }
+
+       /*
+        * VM_IO marks the area as being an mmaped region for I/O to a
+        * device. It also prevents the region from being core dumped.
+        */
+       vma->vm_flags |= VM_IO;
+
+       addr = (unsigned long)queue->mem + buffer->buf.m.offset;
+       while (size > 0) {
+               page = vmalloc_to_page((void *)addr);
+               if ((ret = vm_insert_page(vma, start, page)) < 0)
+                       goto done;
+
+               start += PAGE_SIZE;
+               addr += PAGE_SIZE;
+               size -= PAGE_SIZE;
+       }
+
+       vma->vm_ops = &uvc_vm_ops;
+       vma->vm_private_data = buffer;
+       uvc_vm_open(vma);
+
+done:
+       mutex_unlock(&queue->mutex);
+       return ret;
+}
+
 /*
  * Poll the video queue.
  *
index 6d15de9b520437a4440dc8da2071efd0b91fe306..8cf61e8a634ffeb7cb23bfe004efc2c60053f1e8 100644 (file)
@@ -100,40 +100,6 @@ done:
  * V4L2 interface
  */
 
-/*
- * Mapping V4L2 controls to UVC controls can be straighforward if done well.
- * Most of the UVC controls exist in V4L2, and can be mapped directly. Some
- * must be grouped (for instance the Red Balance, Blue Balance and Do White
- * Balance V4L2 controls use the White Balance Component UVC control) or
- * otherwise translated. The approach we take here is to use a translation
- * table for the controls that can be mapped directly, and handle the others
- * manually.
- */
-static int uvc_v4l2_query_menu(struct uvc_video_chain *chain,
-       struct v4l2_querymenu *query_menu)
-{
-       struct uvc_menu_info *menu_info;
-       struct uvc_control_mapping *mapping;
-       struct uvc_control *ctrl;
-       u32 index = query_menu->index;
-       u32 id = query_menu->id;
-
-       ctrl = uvc_find_control(chain, query_menu->id, &mapping);
-       if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU)
-               return -EINVAL;
-
-       if (query_menu->index >= mapping->menu_count)
-               return -EINVAL;
-
-       memset(query_menu, 0, sizeof(*query_menu));
-       query_menu->id = id;
-       query_menu->index = index;
-
-       menu_info = &mapping->menu_info[query_menu->index];
-       strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
-       return 0;
-}
-
 /*
  * Find the frame interval closest to the requested frame interval for the
  * given frame format and size. This should be done by the device as part of
@@ -260,12 +226,14 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream,
         * developers test their webcams with the Linux driver as well as with
         * the Windows driver).
         */
+       mutex_lock(&stream->mutex);
        if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
                probe->dwMaxVideoFrameSize =
                        stream->ctrl.dwMaxVideoFrameSize;
 
        /* Probe the device. */
        ret = uvc_probe_video(stream, probe);
+       mutex_unlock(&stream->mutex);
        if (ret < 0)
                goto done;
 
@@ -289,14 +257,21 @@ done:
 static int uvc_v4l2_get_format(struct uvc_streaming *stream,
        struct v4l2_format *fmt)
 {
-       struct uvc_format *format = stream->cur_format;
-       struct uvc_frame *frame = stream->cur_frame;
+       struct uvc_format *format;
+       struct uvc_frame *frame;
+       int ret = 0;
 
        if (fmt->type != stream->type)
                return -EINVAL;
 
-       if (format == NULL || frame == NULL)
-               return -EINVAL;
+       mutex_lock(&stream->mutex);
+       format = stream->cur_format;
+       frame = stream->cur_frame;
+
+       if (format == NULL || frame == NULL) {
+               ret = -EINVAL;
+               goto done;
+       }
 
        fmt->fmt.pix.pixelformat = format->fcc;
        fmt->fmt.pix.width = frame->wWidth;
@@ -307,7 +282,9 @@ static int uvc_v4l2_get_format(struct uvc_streaming *stream,
        fmt->fmt.pix.colorspace = format->colorspace;
        fmt->fmt.pix.priv = 0;
 
-       return 0;
+done:
+       mutex_unlock(&stream->mutex);
+       return ret;
 }
 
 static int uvc_v4l2_set_format(struct uvc_streaming *stream,
@@ -321,18 +298,24 @@ static int uvc_v4l2_set_format(struct uvc_streaming *stream,
        if (fmt->type != stream->type)
                return -EINVAL;
 
-       if (uvc_queue_allocated(&stream->queue))
-               return -EBUSY;
-
        ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame);
        if (ret < 0)
                return ret;
 
+       mutex_lock(&stream->mutex);
+
+       if (uvc_queue_allocated(&stream->queue)) {
+               ret = -EBUSY;
+               goto done;
+       }
+
        memcpy(&stream->ctrl, &probe, sizeof probe);
        stream->cur_format = format;
        stream->cur_frame = frame;
 
-       return 0;
+done:
+       mutex_unlock(&stream->mutex);
+       return ret;
 }
 
 static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
@@ -343,7 +326,10 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
        if (parm->type != stream->type)
                return -EINVAL;
 
+       mutex_lock(&stream->mutex);
        numerator = stream->ctrl.dwFrameInterval;
+       mutex_unlock(&stream->mutex);
+
        denominator = 10000000;
        uvc_simplify_fraction(&numerator, &denominator, 8, 333);
 
@@ -370,7 +356,6 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
 static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
                struct v4l2_streamparm *parm)
 {
-       struct uvc_frame *frame = stream->cur_frame;
        struct uvc_streaming_control probe;
        struct v4l2_fract timeperframe;
        uint32_t interval;
@@ -379,28 +364,36 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
        if (parm->type != stream->type)
                return -EINVAL;
 
-       if (uvc_queue_streaming(&stream->queue))
-               return -EBUSY;
-
        if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
                timeperframe = parm->parm.capture.timeperframe;
        else
                timeperframe = parm->parm.output.timeperframe;
 
-       memcpy(&probe, &stream->ctrl, sizeof probe);
        interval = uvc_fraction_to_interval(timeperframe.numerator,
                timeperframe.denominator);
-
        uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n",
                timeperframe.numerator, timeperframe.denominator, interval);
-       probe.dwFrameInterval = uvc_try_frame_interval(frame, interval);
+
+       mutex_lock(&stream->mutex);
+
+       if (uvc_queue_streaming(&stream->queue)) {
+               mutex_unlock(&stream->mutex);
+               return -EBUSY;
+       }
+
+       memcpy(&probe, &stream->ctrl, sizeof probe);
+       probe.dwFrameInterval =
+               uvc_try_frame_interval(stream->cur_frame, interval);
 
        /* Probe the device with the new settings. */
        ret = uvc_probe_video(stream, &probe);
-       if (ret < 0)
+       if (ret < 0) {
+               mutex_unlock(&stream->mutex);
                return ret;
+       }
 
        memcpy(&stream->ctrl, &probe, sizeof probe);
+       mutex_unlock(&stream->mutex);
 
        /* Return the actual frame period. */
        timeperframe.numerator = probe.dwFrameInterval;
@@ -528,11 +521,9 @@ static int uvc_v4l2_release(struct file *file)
        if (uvc_has_privileges(handle)) {
                uvc_video_enable(stream, 0);
 
-               mutex_lock(&stream->queue.mutex);
                if (uvc_free_buffers(&stream->queue) < 0)
                        uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to "
                                        "free buffers.\n");
-               mutex_unlock(&stream->queue.mutex);
        }
 
        /* Release the file handle. */
@@ -624,7 +615,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
        }
 
        case VIDIOC_QUERYMENU:
-               return uvc_v4l2_query_menu(chain, arg);
+               return uvc_query_v4l2_menu(chain, arg);
 
        case VIDIOC_G_EXT_CTRLS:
        {
@@ -905,15 +896,17 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
        case VIDIOC_CROPCAP:
        {
                struct v4l2_cropcap *ccap = arg;
-               struct uvc_frame *frame = stream->cur_frame;
 
                if (ccap->type != stream->type)
                        return -EINVAL;
 
                ccap->bounds.left = 0;
                ccap->bounds.top = 0;
-               ccap->bounds.width = frame->wWidth;
-               ccap->bounds.height = frame->wHeight;
+
+               mutex_lock(&stream->mutex);
+               ccap->bounds.width = stream->cur_frame->wWidth;
+               ccap->bounds.height = stream->cur_frame->wHeight;
+               mutex_unlock(&stream->mutex);
 
                ccap->defrect = ccap->bounds;
 
@@ -930,8 +923,6 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
        case VIDIOC_REQBUFS:
        {
                struct v4l2_requestbuffers *rb = arg;
-               unsigned int bufsize =
-                       stream->ctrl.dwMaxVideoFrameSize;
 
                if (rb->type != stream->type ||
                    rb->memory != V4L2_MEMORY_MMAP)
@@ -940,7 +931,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
                if ((ret = uvc_acquire_privileges(handle)) < 0)
                        return ret;
 
-               ret = uvc_alloc_buffers(&stream->queue, rb->count, bufsize);
+               mutex_lock(&stream->mutex);
+               ret = uvc_alloc_buffers(&stream->queue, rb->count,
+                                       stream->ctrl.dwMaxVideoFrameSize);
+               mutex_unlock(&stream->mutex);
                if (ret < 0)
                        return ret;
 
@@ -988,7 +982,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
                if (!uvc_has_privileges(handle))
                        return -EBUSY;
 
+               mutex_lock(&stream->mutex);
                ret = uvc_video_enable(stream, 1);
+               mutex_unlock(&stream->mutex);
                if (ret < 0)
                        return ret;
                break;
@@ -1068,79 +1064,14 @@ static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
        return -EINVAL;
 }
 
-/*
- * VMA operations.
- */
-static void uvc_vm_open(struct vm_area_struct *vma)
-{
-       struct uvc_buffer *buffer = vma->vm_private_data;
-       buffer->vma_use_count++;
-}
-
-static void uvc_vm_close(struct vm_area_struct *vma)
-{
-       struct uvc_buffer *buffer = vma->vm_private_data;
-       buffer->vma_use_count--;
-}
-
-static const struct vm_operations_struct uvc_vm_ops = {
-       .open           = uvc_vm_open,
-       .close          = uvc_vm_close,
-};
-
 static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
 {
        struct uvc_fh *handle = file->private_data;
        struct uvc_streaming *stream = handle->stream;
-       struct uvc_video_queue *queue = &stream->queue;
-       struct uvc_buffer *uninitialized_var(buffer);
-       struct page *page;
-       unsigned long addr, start, size;
-       unsigned int i;
-       int ret = 0;
 
        uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n");
 
-       start = vma->vm_start;
-       size = vma->vm_end - vma->vm_start;
-
-       mutex_lock(&queue->mutex);
-
-       for (i = 0; i < queue->count; ++i) {
-               buffer = &queue->buffer[i];
-               if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
-                       break;
-       }
-
-       if (i == queue->count || size != queue->buf_size) {
-               ret = -EINVAL;
-               goto done;
-       }
-
-       /*
-        * VM_IO marks the area as being an mmaped region for I/O to a
-        * device. It also prevents the region from being core dumped.
-        */
-       vma->vm_flags |= VM_IO;
-
-       addr = (unsigned long)queue->mem + buffer->buf.m.offset;
-       while (size > 0) {
-               page = vmalloc_to_page((void *)addr);
-               if ((ret = vm_insert_page(vma, start, page)) < 0)
-                       goto done;
-
-               start += PAGE_SIZE;
-               addr += PAGE_SIZE;
-               size -= PAGE_SIZE;
-       }
-
-       vma->vm_ops = &uvc_vm_ops;
-       vma->vm_private_data = buffer;
-       uvc_vm_open(vma);
-
-done:
-       mutex_unlock(&queue->mutex);
-       return ret;
+       return uvc_queue_mmap(&stream->queue, vma);
 }
 
 static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait)
@@ -1157,7 +1088,7 @@ const struct v4l2_file_operations uvc_fops = {
        .owner          = THIS_MODULE,
        .open           = uvc_v4l2_open,
        .release        = uvc_v4l2_release,
-       .ioctl          = uvc_v4l2_ioctl,
+       .unlocked_ioctl = uvc_v4l2_ioctl,
        .read           = uvc_v4l2_read,
        .mmap           = uvc_v4l2_mmap,
        .poll           = uvc_v4l2_poll,
index 5555f01028385b3287952a53d45b2477db021582..5673d673504b838f510966c31c46c078da032bdd 100644 (file)
@@ -293,8 +293,6 @@ int uvc_probe_video(struct uvc_streaming *stream,
        unsigned int i;
        int ret;
 
-       mutex_lock(&stream->mutex);
-
        /* Perform probing. The device should adjust the requested values
         * according to its capabilities. However, some devices, namely the
         * first generation UVC Logitech webcams, don't implement the Video
@@ -346,7 +344,6 @@ int uvc_probe_video(struct uvc_streaming *stream,
        }
 
 done:
-       mutex_unlock(&stream->mutex);
        return ret;
 }
 
index d97cf6d6a4f96c5ef6da3c3b48de0c83652ace70..45f01e7e13d2f90abd30466c8390c8fcecc4fb5a 100644 (file)
@@ -436,7 +436,9 @@ struct uvc_streaming {
        struct uvc_streaming_control ctrl;
        struct uvc_format *cur_format;
        struct uvc_frame *cur_frame;
-
+       /* Protect access to ctrl, cur_format, cur_frame and hardware video
+        * probe control.
+        */
        struct mutex mutex;
 
        unsigned int frozen : 1;
@@ -574,6 +576,8 @@ extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable);
 extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect);
 extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
                struct uvc_buffer *buf);
+extern int uvc_queue_mmap(struct uvc_video_queue *queue,
+               struct vm_area_struct *vma);
 extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue,
                struct file *file, poll_table *wait);
 extern int uvc_queue_allocated(struct uvc_video_queue *queue);
@@ -606,10 +610,10 @@ extern int uvc_status_suspend(struct uvc_device *dev);
 extern int uvc_status_resume(struct uvc_device *dev);
 
 /* Controls */
-extern struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
-               __u32 v4l2_id, struct uvc_control_mapping **mapping);
 extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
                struct v4l2_queryctrl *v4l2_ctrl);
+extern int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
+               struct v4l2_querymenu *query_menu);
 
 extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
                const struct uvc_control_mapping *mapping);
index 03f7f4670e9badd4491f8cddb8e748a848c14119..359e23290a7e99ae0301a6d6844a445343cb900e 100644 (file)
@@ -186,12 +186,12 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf,
                size_t sz, loff_t *off)
 {
        struct video_device *vdev = video_devdata(filp);
-       int ret = -EIO;
+       int ret = -ENODEV;
 
        if (!vdev->fops->read)
                return -EINVAL;
-       if (vdev->lock)
-               mutex_lock(vdev->lock);
+       if (vdev->lock && mutex_lock_interruptible(vdev->lock))
+               return -ERESTARTSYS;
        if (video_is_registered(vdev))
                ret = vdev->fops->read(filp, buf, sz, off);
        if (vdev->lock)
@@ -203,12 +203,12 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf,
                size_t sz, loff_t *off)
 {
        struct video_device *vdev = video_devdata(filp);
-       int ret = -EIO;
+       int ret = -ENODEV;
 
        if (!vdev->fops->write)
                return -EINVAL;
-       if (vdev->lock)
-               mutex_lock(vdev->lock);
+       if (vdev->lock && mutex_lock_interruptible(vdev->lock))
+               return -ERESTARTSYS;
        if (video_is_registered(vdev))
                ret = vdev->fops->write(filp, buf, sz, off);
        if (vdev->lock)
@@ -219,10 +219,10 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf,
 static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll)
 {
        struct video_device *vdev = video_devdata(filp);
-       int ret = DEFAULT_POLLMASK;
+       int ret = POLLERR | POLLHUP;
 
        if (!vdev->fops->poll)
-               return ret;
+               return DEFAULT_POLLMASK;
        if (vdev->lock)
                mutex_lock(vdev->lock);
        if (video_is_registered(vdev))
@@ -238,20 +238,45 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        int ret = -ENODEV;
 
        if (vdev->fops->unlocked_ioctl) {
-               if (vdev->lock)
-                       mutex_lock(vdev->lock);
+               if (vdev->lock && mutex_lock_interruptible(vdev->lock))
+                       return -ERESTARTSYS;
                if (video_is_registered(vdev))
                        ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
                if (vdev->lock)
                        mutex_unlock(vdev->lock);
        } else if (vdev->fops->ioctl) {
-               /* TODO: convert all drivers to unlocked_ioctl */
+               /* This code path is a replacement for the BKL. It is a major
+                * hack but it will have to do for those drivers that are not
+                * yet converted to use unlocked_ioctl.
+                *
+                * There are two options: if the driver implements struct
+                * v4l2_device, then the lock defined there is used to
+                * serialize the ioctls. Otherwise the v4l2 core lock defined
+                * below is used. This lock is really bad since it serializes
+                * completely independent devices.
+                *
+                * Both variants suffer from the same problem: if the driver
+                * sleeps, then it blocks all ioctls since the lock is still
+                * held. This is very common for VIDIOC_DQBUF since that
+                * normally waits for a frame to arrive. As a result any other
+                * ioctl calls will proceed very, very slowly since each call
+                * will have to wait for the VIDIOC_QBUF to finish. Things that
+                * should take 0.01s may now take 10-20 seconds.
+                *
+                * The workaround is to *not* take the lock for VIDIOC_DQBUF.
+                * This actually works OK for videobuf-based drivers, since
+                * videobuf will take its own internal lock.
+                */
                static DEFINE_MUTEX(v4l2_ioctl_mutex);
+               struct mutex *m = vdev->v4l2_dev ?
+                       &vdev->v4l2_dev->ioctl_lock : &v4l2_ioctl_mutex;
 
-               mutex_lock(&v4l2_ioctl_mutex);
+               if (cmd != VIDIOC_DQBUF && mutex_lock_interruptible(m))
+                       return -ERESTARTSYS;
                if (video_is_registered(vdev))
                        ret = vdev->fops->ioctl(filp, cmd, arg);
-               mutex_unlock(&v4l2_ioctl_mutex);
+               if (cmd != VIDIOC_DQBUF)
+                       mutex_unlock(m);
        } else
                ret = -ENOTTY;
 
@@ -265,8 +290,8 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
 
        if (!vdev->fops->mmap)
                return ret;
-       if (vdev->lock)
-               mutex_lock(vdev->lock);
+       if (vdev->lock && mutex_lock_interruptible(vdev->lock))
+               return -ERESTARTSYS;
        if (video_is_registered(vdev))
                ret = vdev->fops->mmap(filp, vm);
        if (vdev->lock)
@@ -284,7 +309,7 @@ static int v4l2_open(struct inode *inode, struct file *filp)
        mutex_lock(&videodev_lock);
        vdev = video_devdata(filp);
        /* return ENODEV if the video device has already been removed. */
-       if (vdev == NULL) {
+       if (vdev == NULL || !video_is_registered(vdev)) {
                mutex_unlock(&videodev_lock);
                return -ENODEV;
        }
@@ -292,8 +317,10 @@ static int v4l2_open(struct inode *inode, struct file *filp)
        video_get(vdev);
        mutex_unlock(&videodev_lock);
        if (vdev->fops->open) {
-               if (vdev->lock)
-                       mutex_lock(vdev->lock);
+               if (vdev->lock && mutex_lock_interruptible(vdev->lock)) {
+                       ret = -ERESTARTSYS;
+                       goto err;
+               }
                if (video_is_registered(vdev))
                        ret = vdev->fops->open(filp);
                else
@@ -302,6 +329,7 @@ static int v4l2_open(struct inode *inode, struct file *filp)
                        mutex_unlock(vdev->lock);
        }
 
+err:
        /* decrease the refcount in case of an error */
        if (ret)
                video_put(vdev);
@@ -596,7 +624,12 @@ void video_unregister_device(struct video_device *vdev)
        if (!vdev || !video_is_registered(vdev))
                return;
 
+       mutex_lock(&videodev_lock);
+       /* This must be in a critical section to prevent a race with v4l2_open.
+        * Once this bit has been cleared video_get may never be called again.
+        */
        clear_bit(V4L2_FL_REGISTERED, &vdev->flags);
+       mutex_unlock(&videodev_lock);
        device_unregister(&vdev->dev);
 }
 EXPORT_SYMBOL(video_unregister_device);
index 0b08f96b74a5ed5c750fdcc7541d2e38f069d79f..7fe6f92af480bc46288b3eff1d0358a30bd501e4 100644 (file)
@@ -35,6 +35,7 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
 
        INIT_LIST_HEAD(&v4l2_dev->subdevs);
        spin_lock_init(&v4l2_dev->lock);
+       mutex_init(&v4l2_dev->ioctl_lock);
        v4l2_dev->dev = dev;
        if (dev == NULL) {
                /* If dev == NULL, then name must be filled in by the caller */
index 635420d8d84a0536557582bbf507b4ae14f86f01..019ee206cbee0224fb71c9a86678c05ecf3da7d2 100644 (file)
@@ -815,7 +815,7 @@ out:
 
 static const struct v4l2_file_operations w9966_fops = {
        .owner          = THIS_MODULE,
-       .ioctl          = video_ioctl2,
+       .unlocked_ioctl = video_ioctl2,
        .read           = w9966_v4l_read,
 };
 
index dd90880048cf3fe2f8d209ad654159565a5987e4..d8ae634d347ebc4262704188adb1dea943c909e6 100644 (file)
@@ -51,7 +51,7 @@ struct pxa2xx_flash_info {
 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
 
 
-static int __init pxa2xx_flash_probe(struct platform_device *pdev)
+static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
 {
        struct flash_platform_data *flash = pdev->dev.platform_data;
        struct pxa2xx_flash_info *info;
index cd41c58b5bbd50f8ed905a1a6da71dedc5cfca7e..15682ec8530ed008f8f3f8ddbd16e577306a6407 100644 (file)
@@ -7,7 +7,6 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#define CONFIG_MTD_NAND_OMAP_HWECC
 
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
index c6e86315b3f8df37aa2ac1a767ac46fc1b5eba60..2e2b76258ab42cbc6b0dc73f70bd9547a5846857 100644 (file)
@@ -381,11 +381,11 @@ static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote)
        __b44_set_flow_ctrl(bp, pause_enab);
 }
 
-#ifdef SSB_DRIVER_MIPS
-extern char *nvram_get(char *name);
+#ifdef CONFIG_BCM47XX
+#include <asm/mach-bcm47xx/nvram.h>
 static void b44_wap54g10_workaround(struct b44 *bp)
 {
-       const char *str;
+       char buf[20];
        u32 val;
        int err;
 
@@ -394,10 +394,9 @@ static void b44_wap54g10_workaround(struct b44 *bp)
         * see https://dev.openwrt.org/ticket/146
         * check and reset bit "isolate"
         */
-       str = nvram_get("boardnum");
-       if (!str)
+       if (nvram_getenv("boardnum", buf, sizeof(buf)) < 0)
                return;
-       if (simple_strtoul(str, NULL, 0) == 2) {
+       if (simple_strtoul(buf, NULL, 0) == 2) {
                err = __b44_readphy(bp, 0, MII_BMCR, &val);
                if (err)
                        goto error;
index 36eca1ce75d4e29a4c41bbf285931ce003a6a92a..e4465d222a7d019654c27c5f4d3db89067f89cf8 100644 (file)
@@ -1235,7 +1235,7 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
 
                i = 0;
                netdev_for_each_mc_addr(ha, netdev)
-                       memcpy(req->mac[i].byte, ha->addr, ETH_ALEN);
+                       memcpy(req->mac[i++].byte, ha->addr, ETH_ALEN);
        } else {
                req->promiscuous = 1;
        }
index 863e73a85fbe0ef4cd48ebac5cd5e95846397ebc..d255428122fc0b87d3e4ff2925410b5b2d5f6a47 100644 (file)
@@ -20,8 +20,8 @@
  * (you will need to reboot afterwards) */
 /* #define BNX2X_STOP_ON_ERROR */
 
-#define DRV_MODULE_VERSION      "1.60.00-4"
-#define DRV_MODULE_RELDATE      "2010/11/01"
+#define DRV_MODULE_VERSION      "1.60.01-0"
+#define DRV_MODULE_RELDATE      "2010/11/12"
 #define BNX2X_BC_VER            0x040200
 
 #define BNX2X_MULTI_QUEUE
index 94d5f59d5a6f0a1de6dd8cc5ad44fc2083649b98..0af361e4e3d16ab83d8c3067396f63c5d46d1cb1 100644 (file)
@@ -1782,15 +1782,15 @@ exit_lbl:
 }
 #endif
 
-static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb,
-                                    struct eth_tx_parse_bd_e2 *pbd,
-                                    u32 xmit_type)
+static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data,
+                                       u32 xmit_type)
 {
-       pbd->parsing_data |= cpu_to_le16(skb_shinfo(skb)->gso_size) <<
-               ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT;
+       *parsing_data |= (skb_shinfo(skb)->gso_size <<
+                             ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) &
+                             ETH_TX_PARSE_BD_E2_LSO_MSS;
        if ((xmit_type & XMIT_GSO_V6) &&
            (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6))
-               pbd->parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR;
+               *parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR;
 }
 
 /**
@@ -1835,15 +1835,15 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb,
  * @return header len
  */
 static inline  u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb,
-       struct eth_tx_parse_bd_e2 *pbd,
-       u32 xmit_type)
+       u32 *parsing_data, u32 xmit_type)
 {
-       pbd->parsing_data |= cpu_to_le16(tcp_hdrlen(skb)/4) <<
-               ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT;
+       *parsing_data |= ((tcp_hdrlen(skb)/4) <<
+               ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) &
+               ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW;
 
-       pbd->parsing_data |= cpu_to_le16(((unsigned char *)tcp_hdr(skb) -
-                                         skb->data) / 2) <<
-               ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT;
+       *parsing_data |= ((((u8 *)tcp_hdr(skb) - skb->data) / 2) <<
+               ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) &
+               ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W;
 
        return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data;
 }
@@ -1912,6 +1912,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL;
        struct eth_tx_parse_bd_e1x *pbd_e1x = NULL;
        struct eth_tx_parse_bd_e2 *pbd_e2 = NULL;
+       u32 pbd_e2_parsing_data = 0;
        u16 pkt_prod, bd_prod;
        int nbd, fp_index;
        dma_addr_t mapping;
@@ -2033,8 +2034,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
                memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2));
                /* Set PBD in checksum offload case */
                if (xmit_type & XMIT_CSUM)
-                       hlen = bnx2x_set_pbd_csum_e2(bp,
-                                                    skb, pbd_e2, xmit_type);
+                       hlen = bnx2x_set_pbd_csum_e2(bp, skb,
+                                                    &pbd_e2_parsing_data,
+                                                    xmit_type);
        } else {
                pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x;
                memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x));
@@ -2076,10 +2078,18 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd,
                                                 hlen, bd_prod, ++nbd);
                if (CHIP_IS_E2(bp))
-                       bnx2x_set_pbd_gso_e2(skb, pbd_e2, xmit_type);
+                       bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data,
+                                            xmit_type);
                else
                        bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type);
        }
+
+       /* Set the PBD's parsing_data field if not zero
+        * (for the chips newer than 57711).
+        */
+       if (pbd_e2_parsing_data)
+               pbd_e2->parsing_data = cpu_to_le32(pbd_e2_parsing_data);
+
        tx_data_bd = (struct eth_tx_bd *)tx_start_bd;
 
        /* Handle fragmented skb */
index a306b0e46b613417c630e79398c5f8250204195d..66df29fcf7516e45b7794fee314d0122fca6d42b 100644 (file)
@@ -838,7 +838,7 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count,
 /****************************************************************************
 * SRC initializations
 ****************************************************************************/
-
+#ifdef BCM_CNIC
 /* called during init func stage */
 static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2,
                              dma_addr_t t2_mapping, int src_cid_count)
@@ -862,5 +862,5 @@ static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2,
                    U64_HI((u64)t2_mapping +
                           (src_cid_count-1) * sizeof(struct src_ent)));
 }
-
+#endif
 #endif /* BNX2X_INIT_OPS_H */
index 71a169740d05daf463b04f2ff591a943f8c1847e..d0ea760ce419f0ae8040bf880cd80013c651a93a 100644 (file)
@@ -171,7 +171,7 @@ MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link
 /*----------------------------- Global variables ----------------------------*/
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-cpumask_var_t netpoll_block_tx;
+atomic_t netpoll_block_tx = ATOMIC_INIT(0);
 #endif
 
 static const char * const version =
@@ -1576,7 +1576,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->slave_cnt == 0)
+       if (is_zero_ether_addr(bond->dev->dev_addr))
                memcpy(bond->dev->dev_addr, slave_dev->dev_addr,
                       slave_dev->addr_len);
 
@@ -5299,13 +5299,6 @@ static int __init bonding_init(void)
        if (res)
                goto out;
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) {
-               res = -ENOMEM;
-               goto out;
-       }
-#endif
-
        res = register_pernet_subsys(&bond_net_ops);
        if (res)
                goto out;
@@ -5334,9 +5327,6 @@ err:
        rtnl_link_unregister(&bond_link_ops);
 err_link:
        unregister_pernet_subsys(&bond_net_ops);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       free_cpumask_var(netpoll_block_tx);
-#endif
        goto out;
 
 }
@@ -5353,7 +5343,10 @@ static void __exit bonding_exit(void)
        unregister_pernet_subsys(&bond_net_ops);
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-       free_cpumask_var(netpoll_block_tx);
+       /*
+        * Make sure we don't have an imbalance on our netpoll blocking
+        */
+       WARN_ON(atomic_read(&netpoll_block_tx));
 #endif
 }
 
index 4eedb12df6caf2e4676cbe11e2134e97ec01def1..c2f081352a037894d6e8238ccb70c39e796c4a69 100644 (file)
 
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
-extern cpumask_var_t netpoll_block_tx;
+extern atomic_t netpoll_block_tx;
 
 static inline void block_netpoll_tx(void)
 {
-       preempt_disable();
-       BUG_ON(cpumask_test_and_set_cpu(smp_processor_id(),
-                                       netpoll_block_tx));
+       atomic_inc(&netpoll_block_tx);
 }
 
 static inline void unblock_netpoll_tx(void)
 {
-       BUG_ON(!cpumask_test_and_clear_cpu(smp_processor_id(),
-                                          netpoll_block_tx));
-       preempt_enable();
+       atomic_dec(&netpoll_block_tx);
 }
 
 static inline int is_netpoll_tx_blocked(struct net_device *dev)
 {
        if (unlikely(dev->priv_flags & IFF_IN_NETPOLL))
-               return cpumask_test_cpu(smp_processor_id(), netpoll_block_tx);
+               return atomic_read(&netpoll_block_tx);
        return 0;
 }
 #else
index 1cd90da86f130ea588070634db35959a47ca7b87..32b1c6fb2de1a74e5b97254cdf075ca933464734 100644 (file)
@@ -5,7 +5,7 @@
  * License terms: GNU General Public License (GPL) version 2
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt
 
 #include <linux/version.h>
 #include <linux/init.h>
index 19f9c065666745633752c3e59b312d2a4e9812c0..80511167f35bd4bcfb53cf424eb58ff4174a558b 100644 (file)
@@ -6,7 +6,7 @@
  * License terms: GNU General Public License (GPL) version 2
  */
 
-#define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt
 
 #include <linux/spinlock.h>
 #include <linux/sched.h>
index bb813d94aea8ef5ae11db63ce6ac795fd0a62c39..e97521c801ea6e4a90714bd2038d4c0610b8806a 100644 (file)
@@ -2408,7 +2408,7 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox,
                if (index < NEXACT_MAC)
                        ret++;
                else if (hash)
-                       *hash |= (1 << hash_mac_addr(addr[i]));
+                       *hash |= (1ULL << hash_mac_addr(addr[i]));
        }
        return ret;
 }
index d887a76cd39dad036eb289d88f5a666d898eb63a..6bf464afa90ed1a60cf06bb91f31964cf82a7e5d 100644 (file)
@@ -2269,6 +2269,7 @@ static void __devinit cfg_queues(struct adapter *adapter)
 {
        struct sge *s = &adapter->sge;
        int q10g, n10g, qidx, pidx, qs;
+       size_t iqe_size;
 
        /*
         * We should not be called till we know how many Queue Sets we can
@@ -2312,6 +2313,13 @@ static void __devinit cfg_queues(struct adapter *adapter)
        }
        s->ethqsets = qidx;
 
+       /*
+        * The Ingress Queue Entry Size for our various Response Queues needs
+        * to be big enough to accommodate the largest message we can receive
+        * from the chip/firmware; which is 64 bytes ...
+        */
+       iqe_size = 64;
+
        /*
         * Set up default Queue Set parameters ...  Start off with the
         * shortest interrupt holdoff timer.
@@ -2320,7 +2328,7 @@ static void __devinit cfg_queues(struct adapter *adapter)
                struct sge_eth_rxq *rxq = &s->ethrxq[qs];
                struct sge_eth_txq *txq = &s->ethtxq[qs];
 
-               init_rspq(&rxq->rspq, 0, 0, 1024, L1_CACHE_BYTES);
+               init_rspq(&rxq->rspq, 0, 0, 1024, iqe_size);
                rxq->fl.size = 72;
                txq->q.size = 1024;
        }
@@ -2329,8 +2337,7 @@ static void __devinit cfg_queues(struct adapter *adapter)
         * The firmware event queue is used for link state changes and
         * notifications of TX DMA completions.
         */
-       init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512,
-                 L1_CACHE_BYTES);
+       init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512, iqe_size);
 
        /*
         * The forwarded interrupt queue is used when we're in MSI interrupt
@@ -2346,7 +2353,7 @@ static void __devinit cfg_queues(struct adapter *adapter)
         * any time ...
         */
        init_rspq(&s->intrq, SGE_TIMER_RSTRT_CNTR, 0, MSIX_ENTRIES + 1,
-                 L1_CACHE_BYTES);
+                 iqe_size);
 }
 
 /*
index 75b099ce49c9b47e361adc66da99d148b58640f3..1f37ee6b2a2626282fd5a772cc21f821321b9379 100644 (file)
@@ -261,6 +261,13 @@ static void ehea_get_ethtool_stats(struct net_device *dev,
 
 }
 
+static int ehea_set_flags(struct net_device *dev, u32 data)
+{
+       return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO
+                                       | ETH_FLAG_TXVLAN
+                                       | ETH_FLAG_RXVLAN);
+}
+
 const struct ethtool_ops ehea_ethtool_ops = {
        .get_settings = ehea_get_settings,
        .get_drvinfo = ehea_get_drvinfo,
@@ -273,6 +280,8 @@ const struct ethtool_ops ehea_ethtool_ops = {
        .get_ethtool_stats = ehea_get_ethtool_stats,
        .get_rx_csum = ehea_get_rx_csum,
        .set_settings = ehea_set_settings,
+       .get_flags = ethtool_op_get_flags,
+       .set_flags = ehea_set_flags,
        .nway_reset = ehea_nway_reset,          /* Restart autonegotiation */
 };
 
index 3d0af08483a16792874d46958c2821641f5b7f97..b95f087cd5a9c4a51525718e90ba65b56cf81b99 100644 (file)
@@ -683,7 +683,7 @@ static void ehea_proc_skb(struct ehea_port_res *pr, struct ehea_cqe *cqe,
        int vlan_extracted = ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) &&
                              pr->port->vgrp);
 
-       if (use_lro) {
+       if (skb->dev->features & NETIF_F_LRO) {
                if (vlan_extracted)
                        lro_vlan_hwaccel_receive_skb(&pr->lro_mgr, skb,
                                                     pr->port->vgrp,
@@ -787,7 +787,7 @@ static int ehea_proc_rwqes(struct net_device *dev,
                }
                cqe = ehea_poll_rq1(qp, &wqe_index);
        }
-       if (use_lro)
+       if (dev->features & NETIF_F_LRO)
                lro_flush_all(&pr->lro_mgr);
 
        pr->rx_packets += processed;
@@ -3278,6 +3278,9 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
                      | NETIF_F_LLTX;
        dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
 
+       if (use_lro)
+               dev->features |= NETIF_F_LRO;
+
        INIT_WORK(&port->reset_task, ehea_reset_port);
 
        ret = register_netdev(dev);
index a466ef91dd4351d58f37e4ed5b443395ce4725e6..aa28b270c045e1a32562be18f68a1ec0449f276f 100644 (file)
@@ -1962,7 +1962,8 @@ static void enic_poll_controller(struct net_device *netdev)
        case VNIC_DEV_INTR_MODE_MSIX:
                for (i = 0; i < enic->rq_count; i++) {
                        intr = enic_msix_rq_intr(enic, i);
-                       enic_isr_msix_rq(enic->msix_entry[intr].vector, enic);
+                       enic_isr_msix_rq(enic->msix_entry[intr].vector,
+                               &enic->napi[i]);
                }
                intr = enic_msix_wq_intr(enic, i);
                enic_isr_msix_wq(enic->msix_entry[intr].vector, enic);
index ab9f675c5b8b8b86473d07b60b3ad933523b3ab5..fe337bd121aa74d3eb60cf866e31b8f76fa84573 100644 (file)
@@ -104,6 +104,8 @@ static void ri_tasklet(unsigned long dev)
                        rcu_read_unlock();
                        dev_kfree_skb(skb);
                        stats->tx_dropped++;
+                       if (skb_queue_len(&dp->tq) != 0)
+                               goto resched;
                        break;
                }
                rcu_read_unlock();
index fbad4d819608f234d0eff25175bccf9a8545c20b..eee0b298bd3616558ca8d9f5cf44a02fe95c68e7 100644 (file)
@@ -4771,6 +4771,9 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
                adapter->rx_ring[i] = NULL;
        }
 
+       adapter->num_tx_queues = 0;
+       adapter->num_rx_queues = 0;
+
        ixgbe_free_q_vectors(adapter);
        ixgbe_reset_interrupt_capability(adapter);
 }
index cb3d13e4e074097a4b89b9f0315f3d64b6ad68ff..35fda5ac8120c056eb94d0f14bea376494d2d59c 100644 (file)
@@ -64,7 +64,7 @@ config BCM63XX_PHY
 config ICPLUS_PHY
        tristate "Drivers for ICPlus PHYs"
        ---help---
-         Currently supports the IP175C PHY.
+         Currently supports the IP175C and IP1001 PHYs.
 
 config REALTEK_PHY
        tristate "Drivers for Realtek PHYs"
index c1d2d251fe8bfcef7114fd57b1018c70697006f5..9a09e24c30bc2e222974b481f76d219ed6a22cd6 100644 (file)
@@ -30,7 +30,7 @@
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
-MODULE_DESCRIPTION("ICPlus IP175C PHY driver");
+MODULE_DESCRIPTION("ICPlus IP175C/IC1001 PHY drivers");
 MODULE_AUTHOR("Michael Barkowski");
 MODULE_LICENSE("GPL");
 
@@ -89,6 +89,33 @@ static int ip175c_config_init(struct phy_device *phydev)
        return 0;
 }
 
+static int ip1001_config_init(struct phy_device *phydev)
+{
+       int err, value;
+
+       /* Software Reset PHY */
+       value = phy_read(phydev, MII_BMCR);
+       value |= BMCR_RESET;
+       err = phy_write(phydev, MII_BMCR, value);
+       if (err < 0)
+               return err;
+
+       do {
+               value = phy_read(phydev, MII_BMCR);
+       } while (value & BMCR_RESET);
+
+       /* Additional delay (2ns) used to adjust RX clock phase
+        * at GMII/ RGMII interface */
+       value = phy_read(phydev, 16);
+       value |= 0x3;
+
+       err = phy_write(phydev, 16, value);
+       if (err < 0)
+               return err;
+
+       return err;
+}
+
 static int ip175c_read_status(struct phy_device *phydev)
 {
        if (phydev->addr == 4) /* WAN port */
@@ -121,21 +148,43 @@ static struct phy_driver ip175c_driver = {
        .driver         = { .owner = THIS_MODULE,},
 };
 
-static int __init ip175c_init(void)
+static struct phy_driver ip1001_driver = {
+       .phy_id         = 0x02430d90,
+       .name           = "ICPlus IP1001",
+       .phy_id_mask    = 0x0ffffff0,
+       .features       = PHY_GBIT_FEATURES | SUPPORTED_Pause |
+                         SUPPORTED_Asym_Pause,
+       .config_init    = &ip1001_config_init,
+       .config_aneg    = &genphy_config_aneg,
+       .read_status    = &genphy_read_status,
+       .suspend        = genphy_suspend,
+       .resume         = genphy_resume,
+       .driver         = { .owner = THIS_MODULE,},
+};
+
+static int __init icplus_init(void)
 {
+       int ret = 0;
+
+       ret = phy_driver_register(&ip1001_driver);
+       if (ret < 0)
+               return -ENODEV;
+
        return phy_driver_register(&ip175c_driver);
 }
 
-static void __exit ip175c_exit(void)
+static void __exit icplus_exit(void)
 {
+       phy_driver_unregister(&ip1001_driver);
        phy_driver_unregister(&ip175c_driver);
 }
 
-module_init(ip175c_init);
-module_exit(ip175c_exit);
+module_init(icplus_init);
+module_exit(icplus_exit);
 
 static struct mdio_device_id __maybe_unused icplus_tbl[] = {
        { 0x02430d80, 0x0ffffff0 },
+       { 0x02430d90, 0x0ffffff0 },
        { }
 };
 
index d72fb0519a2aa674a8757f5146b0df19655d9749..78c0e3c9b2b5fcb8d42fb910ab2416e4db787dc7 100644 (file)
@@ -948,7 +948,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb)
 
 abort:
        kfree_skb(skb);
-       return 0;
+       return 1;
 }
 
 /************************************************************************
index 22821398fc63765054eff056ab2529beedfb30fc..9787dff90d3fa18a3e70cbdac43fa73062202b33 100644 (file)
@@ -2083,6 +2083,7 @@ struct ql_adapter {
        u32 mailbox_in;
        u32 mailbox_out;
        struct mbox_params idc_mbc;
+       struct mutex    mpi_mutex;
 
        int tx_ring_size;
        int rx_ring_size;
index 528eaef5308fa59460c8697ffc4fc0400d74a6cb..2555b1d34f346d691f904bb3f8593a3933f2b6fc 100644 (file)
@@ -4629,6 +4629,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
        INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work);
        INIT_DELAYED_WORK(&qdev->mpi_core_to_log, ql_mpi_core_to_log);
        init_completion(&qdev->ide_completion);
+       mutex_init(&qdev->mpi_mutex);
 
        if (!cards_found) {
                dev_info(&pdev->dev, "%s\n", DRV_STRING);
index 0e7c7c7ee1647006baf561ffd90308290fbd2399..a2e919bcb3c6b616250eeafb4e76ae7a5921f50e 100644 (file)
@@ -534,6 +534,7 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
        int status;
        unsigned long count;
 
+       mutex_lock(&qdev->mpi_mutex);
 
        /* Begin polled mode for MPI */
        ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
@@ -603,6 +604,7 @@ done:
 end:
        /* End polled mode for MPI */
        ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
+       mutex_unlock(&qdev->mpi_mutex);
        return status;
 }
 
@@ -1099,9 +1101,7 @@ int ql_wait_fifo_empty(struct ql_adapter *qdev)
 static int ql_set_port_cfg(struct ql_adapter *qdev)
 {
        int status;
-       rtnl_lock();
        status = ql_mb_set_port_cfg(qdev);
-       rtnl_unlock();
        if (status)
                return status;
        status = ql_idc_wait(qdev);
@@ -1122,9 +1122,7 @@ void ql_mpi_port_cfg_work(struct work_struct *work)
            container_of(work, struct ql_adapter, mpi_port_cfg_work.work);
        int status;
 
-       rtnl_lock();
        status = ql_mb_get_port_cfg(qdev);
-       rtnl_unlock();
        if (status) {
                netif_err(qdev, drv, qdev->ndev,
                          "Bug: Failed to get port config data.\n");
@@ -1167,7 +1165,6 @@ void ql_mpi_idc_work(struct work_struct *work)
        u32 aen;
        int timeout;
 
-       rtnl_lock();
        aen = mbcp->mbox_out[1] >> 16;
        timeout = (mbcp->mbox_out[1] >> 8) & 0xf;
 
@@ -1231,7 +1228,6 @@ void ql_mpi_idc_work(struct work_struct *work)
                }
                break;
        }
-       rtnl_unlock();
 }
 
 void ql_mpi_work(struct work_struct *work)
@@ -1242,7 +1238,7 @@ void ql_mpi_work(struct work_struct *work)
        struct mbox_params *mbcp = &mbc;
        int err = 0;
 
-       rtnl_lock();
+       mutex_lock(&qdev->mpi_mutex);
        /* Begin polled mode for MPI */
        ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
 
@@ -1259,7 +1255,7 @@ void ql_mpi_work(struct work_struct *work)
 
        /* End polled mode for MPI */
        ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
-       rtnl_unlock();
+       mutex_unlock(&qdev->mpi_mutex);
        ql_enable_completion_interrupt(qdev, 0);
 }
 
index 7d33ef4bcb4a1d6ca7125d6780e173889ebbb0d8..53b13deade9528539ea2dcaf5fe268b0e1ceabda 100644 (file)
@@ -744,26 +744,36 @@ static void rtl8169_xmii_reset_enable(void __iomem *ioaddr)
        mdio_write(ioaddr, MII_BMCR, val & 0xffff);
 }
 
-static void rtl8169_check_link_status(struct net_device *dev,
+static void __rtl8169_check_link_status(struct net_device *dev,
                                      struct rtl8169_private *tp,
-                                     void __iomem *ioaddr)
+                                     void __iomem *ioaddr,
+                                     bool pm)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&tp->lock, flags);
        if (tp->link_ok(ioaddr)) {
                /* This is to cancel a scheduled suspend if there's one. */
-               pm_request_resume(&tp->pci_dev->dev);
+               if (pm)
+                       pm_request_resume(&tp->pci_dev->dev);
                netif_carrier_on(dev);
                netif_info(tp, ifup, dev, "link up\n");
        } else {
                netif_carrier_off(dev);
                netif_info(tp, ifdown, dev, "link down\n");
-               pm_schedule_suspend(&tp->pci_dev->dev, 100);
+               if (pm)
+                       pm_schedule_suspend(&tp->pci_dev->dev, 100);
        }
        spin_unlock_irqrestore(&tp->lock, flags);
 }
 
+static void rtl8169_check_link_status(struct net_device *dev,
+                                     struct rtl8169_private *tp,
+                                     void __iomem *ioaddr)
+{
+       __rtl8169_check_link_status(dev, tp, ioaddr, false);
+}
+
 #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
 
 static u32 __rtl8169_get_wol(struct rtl8169_private *tp)
@@ -4600,7 +4610,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
                }
 
                if (status & LinkChg)
-                       rtl8169_check_link_status(dev, tp, ioaddr);
+                       __rtl8169_check_link_status(dev, tp, ioaddr, true);
 
                /* We need to see the lastest version of tp->intr_mask to
                 * avoid ignoring an MSI interrupt and having to wait for
@@ -4890,11 +4900,7 @@ static int rtl8169_runtime_idle(struct device *device)
        struct net_device *dev = pci_get_drvdata(pdev);
        struct rtl8169_private *tp = netdev_priv(dev);
 
-       if (!tp->TxDescArray)
-               return 0;
-
-       rtl8169_check_link_status(dev, tp, tp->mmio_addr);
-       return -EBUSY;
+       return tp->TxDescArray ? -EBUSY : 0;
 }
 
 static const struct dev_pm_ops rtl8169_pm_ops = {
index 05df20e47976cb3965c59c5b227e67877bd2d0c4..fb83cdd946436561dbe645f5d742317fea8cfe91 100644 (file)
@@ -197,7 +197,9 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value");
 
 static void efx_remove_channels(struct efx_nic *efx);
 static void efx_remove_port(struct efx_nic *efx);
+static void efx_init_napi(struct efx_nic *efx);
 static void efx_fini_napi(struct efx_nic *efx);
+static void efx_fini_napi_channel(struct efx_channel *channel);
 static void efx_fini_struct(struct efx_nic *efx);
 static void efx_start_all(struct efx_nic *efx);
 static void efx_stop_all(struct efx_nic *efx);
@@ -335,8 +337,10 @@ void efx_process_channel_now(struct efx_channel *channel)
 
        /* Disable interrupts and wait for ISRs to complete */
        efx_nic_disable_interrupts(efx);
-       if (efx->legacy_irq)
+       if (efx->legacy_irq) {
                synchronize_irq(efx->legacy_irq);
+               efx->legacy_irq_enabled = false;
+       }
        if (channel->irq)
                synchronize_irq(channel->irq);
 
@@ -351,6 +355,8 @@ void efx_process_channel_now(struct efx_channel *channel)
        efx_channel_processed(channel);
 
        napi_enable(&channel->napi_str);
+       if (efx->legacy_irq)
+               efx->legacy_irq_enabled = true;
        efx_nic_enable_interrupts(efx);
 }
 
@@ -426,6 +432,7 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel)
 
                *channel = *old_channel;
 
+               channel->napi_dev = NULL;
                memset(&channel->eventq, 0, sizeof(channel->eventq));
 
                rx_queue = &channel->rx_queue;
@@ -736,9 +743,13 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)
        if (rc)
                goto rollback;
 
+       efx_init_napi(efx);
+
        /* Destroy old channels */
-       for (i = 0; i < efx->n_channels; i++)
+       for (i = 0; i < efx->n_channels; i++) {
+               efx_fini_napi_channel(other_channel[i]);
                efx_remove_channel(other_channel[i]);
+       }
 out:
        /* Free unused channel structures */
        for (i = 0; i < efx->n_channels; i++)
@@ -1400,6 +1411,8 @@ static void efx_start_all(struct efx_nic *efx)
                efx_start_channel(channel);
        }
 
+       if (efx->legacy_irq)
+               efx->legacy_irq_enabled = true;
        efx_nic_enable_interrupts(efx);
 
        /* Switch to event based MCDI completions after enabling interrupts.
@@ -1460,8 +1473,10 @@ static void efx_stop_all(struct efx_nic *efx)
 
        /* Disable interrupts and wait for ISR to complete */
        efx_nic_disable_interrupts(efx);
-       if (efx->legacy_irq)
+       if (efx->legacy_irq) {
                synchronize_irq(efx->legacy_irq);
+               efx->legacy_irq_enabled = false;
+       }
        efx_for_each_channel(channel, efx) {
                if (channel->irq)
                        synchronize_irq(channel->irq);
@@ -1593,7 +1608,7 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
  *
  **************************************************************************/
 
-static int efx_init_napi(struct efx_nic *efx)
+static void efx_init_napi(struct efx_nic *efx)
 {
        struct efx_channel *channel;
 
@@ -1602,18 +1617,21 @@ static int efx_init_napi(struct efx_nic *efx)
                netif_napi_add(channel->napi_dev, &channel->napi_str,
                               efx_poll, napi_weight);
        }
-       return 0;
+}
+
+static void efx_fini_napi_channel(struct efx_channel *channel)
+{
+       if (channel->napi_dev)
+               netif_napi_del(&channel->napi_str);
+       channel->napi_dev = NULL;
 }
 
 static void efx_fini_napi(struct efx_nic *efx)
 {
        struct efx_channel *channel;
 
-       efx_for_each_channel(channel, efx) {
-               if (channel->napi_dev)
-                       netif_napi_del(&channel->napi_str);
-               channel->napi_dev = NULL;
-       }
+       efx_for_each_channel(channel, efx)
+               efx_fini_napi_channel(channel);
 }
 
 /**************************************************************************
@@ -2335,9 +2353,7 @@ static int efx_pci_probe_main(struct efx_nic *efx)
        if (rc)
                goto fail1;
 
-       rc = efx_init_napi(efx);
-       if (rc)
-               goto fail2;
+       efx_init_napi(efx);
 
        rc = efx->type->init(efx);
        if (rc) {
@@ -2368,7 +2384,6 @@ static int efx_pci_probe_main(struct efx_nic *efx)
        efx->type->fini(efx);
  fail3:
        efx_fini_napi(efx);
- fail2:
        efx_remove_all(efx);
  fail1:
        return rc;
index 0a7e26d73b525b13aba1fc9e234d38a699322f2a..b137c889152b14be6486fe9271f00658f81df031 100644 (file)
@@ -621,6 +621,7 @@ struct efx_filter_state;
  * @pci_dev: The PCI device
  * @type: Controller type attributes
  * @legacy_irq: IRQ number
+ * @legacy_irq_enabled: Are IRQs enabled on NIC (INT_EN_KER register)?
  * @workqueue: Workqueue for port reconfigures and the HW monitor.
  *     Work items do not hold and must not acquire RTNL.
  * @workqueue_name: Name of workqueue
@@ -709,6 +710,7 @@ struct efx_nic {
        struct pci_dev *pci_dev;
        const struct efx_nic_type *type;
        int legacy_irq;
+       bool legacy_irq_enabled;
        struct workqueue_struct *workqueue;
        char workqueue_name[16];
        struct work_struct reset_work;
index 41c36b9a4244b907907936b0a6abeaf8f2a301d1..67cb0c96838caeee1bc0497266ef51dd8e9bb407 100644 (file)
@@ -1418,6 +1418,12 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
        u32 queues;
        int syserr;
 
+       /* Could this be ours?  If interrupts are disabled then the
+        * channel state may not be valid.
+        */
+       if (!efx->legacy_irq_enabled)
+               return result;
+
        /* Read the ISR which also ACKs the interrupts */
        efx_readd(efx, &reg, FR_BZ_INT_ISR0);
        queues = EFX_EXTRACT_DWORD(reg, 0, 31);
index 06bc6034ce810f49a67a698af524bec91e1eee5f..2114837809e76707e69f41cde38b0a0856ee745a 100644 (file)
@@ -1509,6 +1509,8 @@ static int stmmac_probe(struct net_device *dev)
                pr_warning("\tno valid MAC address;"
                        "please, use ifconfig or nwhwconfig!\n");
 
+       spin_lock_init(&priv->lock);
+
        ret = register_netdev(dev);
        if (ret) {
                pr_err("%s: ERROR %i registering the device\n",
@@ -1520,8 +1522,6 @@ static int stmmac_probe(struct net_device *dev)
            dev->name, (dev->features & NETIF_F_SG) ? "on" : "off",
            (dev->features & NETIF_F_HW_CSUM) ? "on" : "off");
 
-       spin_lock_init(&priv->lock);
-
        return ret;
 }
 
index a9f7d5d1a2695f95a968001a93c1449b9ac998be..7064e035757a16b927d35aa61991268089275744 100644 (file)
@@ -688,9 +688,6 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb,
 
        DMFE_DBUG(0, "dmfe_start_xmit", 0);
 
-       /* Resource flag check */
-       netif_stop_queue(dev);
-
        /* Too large packet check */
        if (skb->len > MAX_PACKET_SIZE) {
                pr_err("big packet = %d\n", (u16)skb->len);
@@ -698,6 +695,9 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb,
                return NETDEV_TX_OK;
        }
 
+       /* Resource flag check */
+       netif_stop_queue(dev);
+
        spin_lock_irqsave(&db->lock, flags);
 
        /* No Tx resource check, it never happen nromally */
index 62e9e8dc8190d69314529cd42d0d2b7f06228746..812edf85d6d32b017454f449f4d03e300ed4ec50 100644 (file)
@@ -958,10 +958,6 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt,
                                /* Packet is complete. Inject into stack. */
                                /* We have IP packet here */
                                odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP);
-                               /* don't check it */
-                               odev->skb_rx_buf->ip_summed =
-                                       CHECKSUM_UNNECESSARY;
-
                                skb_reset_mac_header(odev->skb_rx_buf);
 
                                /* Ship it off to the kernel */
index ea476cbd38b511039c8cb21ecdba7c61c1071ff1..e305274f83fba70c4967b2af57934ec5347a7eea 100644 (file)
@@ -293,6 +293,7 @@ static inline void sca_tx_done(port_t *port)
        struct net_device *dev = port->netdev;
        card_t* card = port->card;
        u8 stat;
+       unsigned count = 0;
 
        spin_lock(&port->lock);
 
@@ -316,10 +317,12 @@ static inline void sca_tx_done(port_t *port)
                        dev->stats.tx_bytes += readw(&desc->len);
                }
                writeb(0, &desc->stat); /* Free descriptor */
+               count++;
                port->txlast = (port->txlast + 1) % card->tx_ring_buffers;
        }
 
-       netif_wake_queue(dev);
+       if (count)
+               netif_wake_queue(dev);
        spin_unlock(&port->lock);
 }
 
index 8251946842e6186bddcd1cac303dbaea74664410..42ed923cdb1aad9479be7ed5f68a2b40c665ffcb 100644 (file)
@@ -1917,7 +1917,8 @@ ath5k_beacon_send(struct ath5k_softc *sc)
                sc->bmisscount = 0;
        }
 
-       if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
+       if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) ||
+                       sc->opmode == NL80211_IFTYPE_MESH_POINT) {
                u64 tsf = ath5k_hw_get_tsf64(ah);
                u32 tsftu = TSF_TO_TU(tsf);
                int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval;
@@ -1949,8 +1950,9 @@ ath5k_beacon_send(struct ath5k_softc *sc)
                /* NB: hw still stops DMA, so proceed */
        }
 
-       /* refresh the beacon for AP mode */
-       if (sc->opmode == NL80211_IFTYPE_AP)
+       /* refresh the beacon for AP or MESH mode */
+       if (sc->opmode == NL80211_IFTYPE_AP ||
+                       sc->opmode == NL80211_IFTYPE_MESH_POINT)
                ath5k_beacon_update(sc->hw, vif);
 
        ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
@@ -2851,7 +2853,8 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
 
        /* Assign the vap/adhoc to a beacon xmit slot. */
        if ((avf->opmode == NL80211_IFTYPE_AP) ||
-           (avf->opmode == NL80211_IFTYPE_ADHOC)) {
+           (avf->opmode == NL80211_IFTYPE_ADHOC) ||
+           (avf->opmode == NL80211_IFTYPE_MESH_POINT)) {
                int slot;
 
                WARN_ON(list_empty(&sc->bcbuf));
@@ -2870,7 +2873,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
                sc->bslot[avf->bslot] = vif;
                if (avf->opmode == NL80211_IFTYPE_AP)
                        sc->num_ap_vifs++;
-               else
+               else if (avf->opmode == NL80211_IFTYPE_ADHOC)
                        sc->num_adhoc_vifs++;
        }
 
index c4182359bee46603cffc46e9781750087f2a5f0f..a7b82f0085d2e899da46f6139dcac2185b42f924 100644 (file)
@@ -55,6 +55,8 @@
 #define SUB_NUM_CTL_MODES_AT_5G_40 2    /* excluding HT40, EXT-OFDM */
 #define SUB_NUM_CTL_MODES_AT_2G_40 3    /* excluding HT40, EXT-OFDM, EXT-CCK */
 
+#define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
+
 static const struct ar9300_eeprom ar9300_default = {
        .eepromVersion = 2,
        .templateVersion = 2,
@@ -290,20 +292,21 @@ static const struct ar9300_eeprom ar9300_default = {
                }
         },
        .ctlPowerData_2G = {
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
-                { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
 
-                { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } },
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+                { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
 
-                { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } },
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
 
-                { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } },
-                { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
+                { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
         },
        .modalHeader5G = {
                /* 4 idle,t1,t2,b (4 bits per setting) */
@@ -568,56 +571,56 @@ static const struct ar9300_eeprom ar9300_default = {
        .ctlPowerData_5G = {
                {
                        {
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 1}, {60, 0},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 1}, {60, 0},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 0}, {60, 1}, {60, 0}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
+                               CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
                        }
                },
                {
                        {
-                               {60, 0}, {60, 1}, {60, 1}, {60, 0},
-                               {60, 1}, {60, 0}, {60, 0}, {60, 0},
+                               CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                               CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 1}, {60, 1}, {60, 0},
-                               {60, 0}, {60, 0}, {60, 0}, {60, 0},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
+                               CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
-                               {60, 1}, {60, 0}, {60, 0}, {60, 0},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 1}, {60, 1},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 1}, {60, 0}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 1}, {60, 0},
+                               CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
                        }
                },
                {
                        {
-                               {60, 1}, {60, 0}, {60, 1}, {60, 1},
-                               {60, 1}, {60, 1}, {60, 0}, {60, 1},
+                               CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
+                               CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
                        }
                },
         }
@@ -1827,9 +1830,9 @@ static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
        struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
 
        if (is2GHz)
-               return ctl_2g[idx].ctlEdges[edge].tPower;
+               return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
        else
-               return ctl_5g[idx].ctlEdges[edge].tPower;
+               return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
 }
 
 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
@@ -1847,12 +1850,12 @@ static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
 
        if (is2GHz) {
                if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
-                   ctl_2g[idx].ctlEdges[edge - 1].flag)
-                       return ctl_2g[idx].ctlEdges[edge - 1].tPower;
+                   CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
+                       return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
        } else {
                if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
-                   ctl_5g[idx].ctlEdges[edge - 1].flag)
-                       return ctl_5g[idx].ctlEdges[edge - 1].tPower;
+                   CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
+                       return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
        }
 
        return AR9300_MAX_RATE_POWER;
index 3c533bb983c72859c9fbea4563070f387747506e..655b3033396c7f89ce1585479afb918102f993ae 100644 (file)
@@ -261,17 +261,12 @@ struct cal_tgt_pow_ht {
        u8 tPow2x[14];
 } __packed;
 
-struct cal_ctl_edge_pwr {
-       u8 tPower:6,
-          flag:2;
-} __packed;
-
 struct cal_ctl_data_2g {
-       struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_2G];
+       u8 ctlEdges[AR9300_NUM_BAND_EDGES_2G];
 } __packed;
 
 struct cal_ctl_data_5g {
-       struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G];
+       u8 ctlEdges[AR9300_NUM_BAND_EDGES_5G];
 } __packed;
 
 struct ar9300_eeprom {
index 170d44a35ccbd2ca06886be2be2ed8c1cd5dcf25..0963071e8f908c15ebec8131c84b792d931e56d9 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/device.h>
 #include <linux/leds.h>
 #include <linux/completion.h>
+#include <linux/pm_qos_params.h>
 
 #include "debug.h"
 #include "common.h"
@@ -328,7 +329,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
 struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
 void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
 int ath_tx_setup(struct ath_softc *sc, int haltype);
-void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
+bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
 void ath_draintxq(struct ath_softc *sc,
                     struct ath_txq *txq, bool retry_tx);
 void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
@@ -646,6 +647,8 @@ struct ath_softc {
        struct ath_descdma txsdma;
 
        struct ath_ant_comb ant_comb;
+
+       struct pm_qos_request_list pm_qos_req;
 };
 
 struct ath_wiphy {
@@ -675,7 +678,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
 }
 
 extern struct ieee80211_ops ath9k_ops;
-extern struct pm_qos_request_list ath9k_pm_qos_req;
 extern int modparam_nohwcrypt;
 extern int led_blink;
 
index 1266333f586d8f574cf8fcda7086f036f3d56403..2bbf94d0191edb0ddc84084a37b07172203f2485 100644 (file)
@@ -240,16 +240,16 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
        for (i = 0; (i < num_band_edges) &&
                     (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
                if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
-                       twiceMaxEdgePower = pRdEdgesPower[i].tPower;
+                       twiceMaxEdgePower = CTL_EDGE_TPOWER(pRdEdgesPower[i].ctl);
                        break;
                } else if ((i > 0) &&
                           (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
                                                      is2GHz))) {
                        if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
                                               is2GHz) < freq &&
-                           pRdEdgesPower[i - 1].flag) {
+                           CTL_EDGE_FLAGS(pRdEdgesPower[i - 1].ctl)) {
                                twiceMaxEdgePower =
-                                       pRdEdgesPower[i - 1].tPower;
+                                       CTL_EDGE_TPOWER(pRdEdgesPower[i - 1].ctl);
                        }
                        break;
                }
index dacb45e1b9063b620736475b6116975fcb60cf4d..dd59f09441a3cdf00cbc805a36e4734d58a04253 100644 (file)
 
 #define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1)
 
+#define CTL_EDGE_TPOWER(_ctl) ((_ctl) & 0x3f)
+#define CTL_EDGE_FLAGS(_ctl) (((_ctl) >> 6) & 0x03)
+
+#define LNA_CTL_BUF_MODE       BIT(0)
+#define LNA_CTL_ISEL_LO                BIT(1)
+#define LNA_CTL_ISEL_HI                BIT(2)
+#define LNA_CTL_BUF_IN         BIT(3)
+#define LNA_CTL_FEM_BAND       BIT(4)
+#define LNA_CTL_LOCAL_BIAS     BIT(5)
+#define LNA_CTL_FORCE_XPA      BIT(6)
+#define LNA_CTL_USE_ANT1       BIT(7)
+
 enum eeprom_param {
        EEP_NFTHRESH_5,
        EEP_NFTHRESH_2,
@@ -378,10 +390,7 @@ struct modal_eep_header {
        u8 xatten2Margin[AR5416_MAX_CHAINS];
        u8 ob_ch1;
        u8 db_ch1;
-       u8 useAnt1:1,
-           force_xpaon:1,
-           local_bias:1,
-           femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
+       u8 lna_ctl;
        u8 miscBits;
        u16 xpaBiasLvlFreq[3];
        u8 futureModal[6];
@@ -535,18 +544,10 @@ struct cal_target_power_ht {
        u8 tPow2x[8];
 } __packed;
 
-
-#ifdef __BIG_ENDIAN_BITFIELD
-struct cal_ctl_edges {
-       u8 bChannel;
-       u8 flag:2, tPower:6;
-} __packed;
-#else
 struct cal_ctl_edges {
        u8 bChannel;
-       u8 tPower:6, flag:2;
+       u8 ctl;
 } __packed;
-#endif
 
 struct cal_data_op_loop_ar9287 {
        u8 pwrPdg[2][5];
index 76b4d65472dd2b37dbf98ff69b57646e53443c61..a3ccb1b9638d7b8b44f32ba651d519d042b806ec 100644 (file)
@@ -451,9 +451,10 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
                ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
                                          AR_AN_TOP2_LOCALBIAS,
                                          AR_AN_TOP2_LOCALBIAS_S,
-                                         pModal->local_bias);
+                                         !!(pModal->lna_ctl &
+                                            LNA_CTL_LOCAL_BIAS));
                REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
-                             pModal->force_xpaon);
+                             !!(pModal->lna_ctl & LNA_CTL_FORCE_XPA));
        }
 
        REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
@@ -1062,15 +1063,19 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
        case 1:
                break;
        case 2:
-               scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+               if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
+                       scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+               else
+                       scaledPower = 0;
                break;
        case 3:
-               scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+               if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
+                       scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+               else
+                       scaledPower = 0;
                break;
        }
 
-       scaledPower = max((u16)0, scaledPower);
-
        if (IS_CHAN_2GHZ(chan)) {
                numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
                        SUB_NUM_CTL_MODES_AT_2G_40;
@@ -1428,9 +1433,9 @@ static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
 
        num_ant_config = 1;
 
-       if (pBase->version >= 0x0E0D)
-               if (pModal->useAnt1)
-                       num_ant_config += 1;
+       if (pBase->version >= 0x0E0D &&
+           (pModal->lna_ctl & LNA_CTL_USE_ANT1))
+               num_ant_config += 1;
 
        return num_ant_config;
 }
index dfb6560dab9205c7502cc0a546c3549635d696f2..0de3c3d3c245c2ad5f71f0a419a7ba4fab96e60c 100644 (file)
@@ -1024,6 +1024,13 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface,
        struct hif_device_usb *hif_dev =
                (struct hif_device_usb *) usb_get_intfdata(interface);
 
+       /*
+        * The device has to be set to FULLSLEEP mode in case no
+        * interface is up.
+        */
+       if (!(hif_dev->flags & HIF_USB_START))
+               ath9k_htc_suspend(hif_dev->htc_handle);
+
        ath9k_hif_usb_dealloc_urbs(hif_dev);
 
        return 0;
index 75ecf6a30d25c6ac68d346c5ac862a0255ba4be1..c3b561daa6c1035a68f4b27da92914ba4e601399 100644 (file)
@@ -455,6 +455,8 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv);
 void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv);
 void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv);
 void ath9k_ps_work(struct work_struct *work);
+bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
+                       enum ath9k_power_mode mode);
 
 void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
 void ath9k_init_leds(struct ath9k_htc_priv *priv);
@@ -464,6 +466,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
                           u16 devid, char *product);
 void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug);
 #ifdef CONFIG_PM
+void ath9k_htc_suspend(struct htc_target *htc_handle);
 int ath9k_htc_resume(struct htc_target *htc_handle);
 #endif
 #ifdef CONFIG_ATH9K_HTC_DEBUGFS
index 7c8a38d04561c26754147bea9e447724a9e8eb42..8776f49ffd41bf2a40f080798fe6c5173b80c9b4 100644 (file)
@@ -891,6 +891,12 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
 }
 
 #ifdef CONFIG_PM
+
+void ath9k_htc_suspend(struct htc_target *htc_handle)
+{
+       ath9k_htc_setpower(htc_handle->drv_priv, ATH9K_PM_FULL_SLEEP);
+}
+
 int ath9k_htc_resume(struct htc_target *htc_handle)
 {
        int ret;
index 9a3be8da755d2f7181ada323e5ec9054b58a0a9e..51977caca47fd6d456e521cff4511e1079f2e09a 100644 (file)
@@ -63,8 +63,8 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
        return mode;
 }
 
-static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
-                              enum ath9k_power_mode mode)
+bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
+                       enum ath9k_power_mode mode)
 {
        bool ret;
 
index 6ebc68bca91f0a999614572b38f69452df49645d..c7fbe25cc12827cf29f68729fe636b07ef75ebfa 100644 (file)
@@ -2044,7 +2044,8 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
                val = REG_READ(ah, AR7010_GPIO_IN);
                return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0;
        } else if (AR_SREV_9300_20_OR_LATER(ah))
-               return MS_REG_READ(AR9300, gpio) != 0;
+               return (MS(REG_READ(ah, AR_GPIO_IN), AR9300_GPIO_IN_VAL) &
+                       AR_GPIO_BIT(gpio)) != 0;
        else if (AR_SREV_9271(ah))
                return MS_REG_READ(AR9271, gpio) != 0;
        else if (AR_SREV_9287_11_OR_LATER(ah))
index 92bc5c5f48768ac42ca4b1bd02690d9d38ebed80..14b8ab386daff8823bcc3301fa52d467ce6cb01b 100644 (file)
@@ -15,7 +15,6 @@
  */
 
 #include <linux/slab.h>
-#include <linux/pm_qos_params.h>
 
 #include "ath9k.h"
 
@@ -180,8 +179,6 @@ static const struct ath_ops ath9k_common_ops = {
        .write = ath9k_iowrite32,
 };
 
-struct pm_qos_request_list ath9k_pm_qos_req;
-
 /**************************/
 /*     Initialization     */
 /**************************/
@@ -664,6 +661,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
                hw->flags |= IEEE80211_HW_MFP_CAPABLE;
 
        hw->wiphy->interface_modes =
+               BIT(NL80211_IFTYPE_P2P_GO) |
+               BIT(NL80211_IFTYPE_P2P_CLIENT) |
                BIT(NL80211_IFTYPE_AP) |
                BIT(NL80211_IFTYPE_WDS) |
                BIT(NL80211_IFTYPE_STATION) |
@@ -759,7 +758,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
        ath_init_leds(sc);
        ath_start_rfkill_poll(sc);
 
-       pm_qos_add_request(&ath9k_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
+       pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
                           PM_QOS_DEFAULT_VALUE);
 
        return 0;
@@ -830,7 +829,7 @@ void ath9k_deinit_device(struct ath_softc *sc)
        }
 
        ieee80211_unregister_hw(hw);
-       pm_qos_remove_request(&ath9k_pm_qos_req);
+       pm_qos_remove_request(&sc->pm_qos_req);
        ath_rx_cleanup(sc);
        ath_tx_cleanup(sc);
        ath9k_deinit_softc(sc);
index 8c13479b17cd9d418f7d7f496b01dbf7445ba202..c996963ab33927c027f3fb019200261c0ac07d18 100644 (file)
@@ -703,8 +703,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
                        rs->rs_phyerr = phyerr;
                } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
                        rs->rs_status |= ATH9K_RXERR_DECRYPT;
-               else if ((ads.ds_rxstatus8 & AR_MichaelErr) &&
-                        rs->rs_keyix != ATH9K_RXKEYIX_INVALID)
+               else if (ads.ds_rxstatus8 & AR_MichaelErr)
                        rs->rs_status |= ATH9K_RXERR_MIC;
                else if (ads.ds_rxstatus8 & AR_KeyMiss)
                        rs->rs_status |= ATH9K_RXERR_DECRYPT;
index 25d3ef4c338e1eb45800b45fec112fc064c095af..c0c3464d3a861162e1142a0e2931a73aedae1fab 100644 (file)
@@ -15,7 +15,6 @@
  */
 
 #include <linux/nl80211.h>
-#include <linux/pm_qos_params.h>
 #include "ath9k.h"
 #include "btcoex.h"
 
@@ -245,11 +244,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
         * the relevant bits of the h/w.
         */
        ath9k_hw_set_interrupts(ah, 0);
-       ath_drain_all_txq(sc, false);
+       stopped = ath_drain_all_txq(sc, false);
 
        spin_lock_bh(&sc->rx.pcu_lock);
 
-       stopped = ath_stoprecv(sc);
+       if (!ath_stoprecv(sc))
+               stopped = false;
 
        /* XXX: do not flush receive queue here. We don't want
         * to flush data frames already in queue because of
@@ -1244,7 +1244,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
                        ath9k_btcoex_timer_resume(sc);
        }
 
-       pm_qos_update_request(&ath9k_pm_qos_req, 55);
+       pm_qos_update_request(&sc->pm_qos_req, 55);
 
 mutex_unlock:
        mutex_unlock(&sc->mutex);
@@ -1423,7 +1423,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 
        sc->sc_flags |= SC_OP_INVALID;
 
-       pm_qos_update_request(&ath9k_pm_qos_req, PM_QOS_DEFAULT_VALUE);
+       pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE);
 
        mutex_unlock(&sc->mutex);
 
@@ -1520,7 +1520,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
        struct ath_softc *sc = aphy->sc;
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        struct ath_vif *avp = (void *)vif->drv_priv;
-       int i;
 
        ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
 
@@ -1534,21 +1533,24 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
        if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
            (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
            (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
+               /* Disable SWBA interrupt */
+               sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
                ath9k_ps_wakeup(sc);
+               ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
                ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
                ath9k_ps_restore(sc);
+               tasklet_kill(&sc->bcon_tasklet);
        }
 
        ath_beacon_return(sc, avp);
        sc->sc_flags &= ~SC_OP_BEACONS;
 
-       for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
-               if (sc->beacon.bslot[i] == vif) {
-                       printk(KERN_DEBUG "%s: vif had allocated beacon "
-                              "slot\n", __func__);
-                       sc->beacon.bslot[i] = NULL;
-                       sc->beacon.bslot_aphy[i] = NULL;
-               }
+       if (sc->nbcnvifs) {
+               /* Re-enable SWBA interrupt */
+               sc->sc_ah->imask |= ATH9K_INT_SWBA;
+               ath9k_ps_wakeup(sc);
+               ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
+               ath9k_ps_restore(sc);
        }
 
        sc->nvifs--;
index 1a62e351ec77c217598a46fae7bdbcc84c1c6050..fdc2ec52b42fcd5647df2c967598e94bcfc13c9a 100644 (file)
@@ -838,6 +838,10 @@ static bool ath9k_rx_accept(struct ath_common *common,
                            struct ath_rx_status *rx_stats,
                            bool *decrypt_error)
 {
+#define is_mc_or_valid_tkip_keyix ((is_mc ||                   \
+               (rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && \
+               test_bit(rx_stats->rs_keyix, common->tkip_keymap))))
+
        struct ath_hw *ah = common->ah;
        __le16 fc;
        u8 rx_status_len = ah->caps.rx_status_len;
@@ -879,15 +883,18 @@ static bool ath9k_rx_accept(struct ath_common *common,
                if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
                        *decrypt_error = true;
                } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
+                       bool is_mc;
                        /*
                         * The MIC error bit is only valid if the frame
                         * is not a control frame or fragment, and it was
                         * decrypted using a valid TKIP key.
                         */
+                       is_mc = !!is_multicast_ether_addr(hdr->addr1);
+
                        if (!ieee80211_is_ctl(fc) &&
                            !ieee80211_has_morefrags(fc) &&
                            !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
-                           test_bit(rx_stats->rs_keyix, common->tkip_keymap))
+                           is_mc_or_valid_tkip_keyix)
                                rxs->flag |= RX_FLAG_MMIC_ERROR;
                        else
                                rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
index dddf579aacf1c391dfb3e9e73675de1a781760da..2c6a22fbb0f0cf76fb5ac5cfd22b530402e9f693 100644 (file)
@@ -984,11 +984,13 @@ enum {
 #define AR9287_GPIO_IN_VAL_S                     11
 #define AR9271_GPIO_IN_VAL                       0xFFFF0000
 #define AR9271_GPIO_IN_VAL_S                     16
-#define AR9300_GPIO_IN_VAL                       0x0001FFFF
-#define AR9300_GPIO_IN_VAL_S                     0
 #define AR7010_GPIO_IN_VAL                       0x0000FFFF
 #define AR7010_GPIO_IN_VAL_S                     0
 
+#define AR_GPIO_IN                              0x404c
+#define AR9300_GPIO_IN_VAL                       0x0001FFFF
+#define AR9300_GPIO_IN_VAL_S                     0
+
 #define AR_GPIO_OE_OUT                           (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)
 #define AR_GPIO_OE_OUT_DRV                       0x3
 #define AR_GPIO_OE_OUT_DRV_NO                    0x0
index f2ade2402ce27709e1da385941b9adbaece96b1e..aff04789f794ee805bf50f1f13d28783f79851d3 100644 (file)
@@ -1120,7 +1120,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
        }
 }
 
-void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
+bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
 {
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -1128,7 +1128,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
        int i, npend = 0;
 
        if (sc->sc_flags & SC_OP_INVALID)
-               return;
+               return true;
 
        /* Stop beacon queue */
        ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
@@ -1142,25 +1142,15 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
                }
        }
 
-       if (npend) {
-               int r;
-
-               ath_print(common, ATH_DBG_FATAL,
-                         "Failed to stop TX DMA. Resetting hardware!\n");
-
-               spin_lock_bh(&sc->sc_resetlock);
-               r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
-               if (r)
-                       ath_print(common, ATH_DBG_FATAL,
-                                 "Unable to reset hardware; reset status %d\n",
-                                 r);
-               spin_unlock_bh(&sc->sc_resetlock);
-       }
+       if (npend)
+               ath_print(common, ATH_DBG_FATAL, "Failed to stop TX DMA!\n");
 
        for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
                if (ATH_TXQ_SETUP(sc, i))
                        ath_draintxq(sc, &sc->tx.txq[i], retry_tx);
        }
+
+       return !npend;
 }
 
 void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
index ae6c006bbc56c03bd76f0e1cc56c46a927db1db9..546b4e4ec5ea090aaf6ed0ce7b77ed024e3c8fd6 100644 (file)
@@ -291,7 +291,8 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
 
                if (SUPP(CARL9170FW_WLANTX_CAB)) {
                        ar->hw->wiphy->interface_modes |=
-                               BIT(NL80211_IFTYPE_AP);
+                               BIT(NL80211_IFTYPE_AP) |
+                               BIT(NL80211_IFTYPE_P2P_GO);
                }
        }
 
index a314c2c2bfbea433849dc60ae7f44f67c2785358..dc7b30b170d037de1dc9b38b058458a98f8efb43 100644 (file)
@@ -1631,7 +1631,8 @@ void *carl9170_alloc(size_t priv_size)
         * supports these modes. The code which will add the
         * additional interface_modes is in fw.c.
         */
-       hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+       hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+                                    BIT(NL80211_IFTYPE_P2P_CLIENT);
 
        hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
                     IEEE80211_HW_REPORTS_TX_ACK_STATUS |
index b575c865142d64f82f8e072518c0de44e46039cc..7e6506a77bbb625a28ad0e6b41f7984607fe5f80 100644 (file)
@@ -810,7 +810,7 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
 
        mac_tmp = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
                              AR9170_TX_MAC_BACKOFF);
-       mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) &&
+       mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) &
                               AR9170_TX_MAC_QOS);
 
        no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK);
index e5685dc317a80423a7acb6a68694bba4043d3897..b4de0ca10feb8f9ef18b826e00f82a240fb40e91 100644 (file)
@@ -1170,7 +1170,6 @@ static void if_sdio_remove(struct sdio_func *func)
        lbs_deb_sdio("call remove card\n");
        lbs_stop_card(card->priv);
        lbs_remove_card(card->priv);
-       card->priv->surpriseremoved = 1;
 
        flush_workqueue(card->workqueue);
        destroy_workqueue(card->workqueue);
index 79bcb4e5d2ca03c7ccb82621576296a6ea68b5d0..ecd4d04b2c3cea67aebd6d62c9446a3318a2840c 100644 (file)
@@ -1055,7 +1055,6 @@ static int __devexit libertas_spi_remove(struct spi_device *spi)
        lbs_stop_card(priv);
        lbs_remove_card(priv); /* will call free_netdev */
 
-       priv->surpriseremoved = 1;
        free_irq(spi->irq, card);
        if_spi_terminate_spi_thread(card);
        if (card->pdata->teardown)
index 46b88b118c992c12764084233f8633a62a01a629..fcd1bbfc632d527364b8f1fc91abd70ba3242225 100644 (file)
@@ -915,8 +915,6 @@ void lbs_remove_card(struct lbs_private *priv)
 
        lbs_free_adapter(priv);
        lbs_cfg_free(priv);
-
-       priv->dev = NULL;
        free_netdev(dev);
 
        lbs_deb_leave(LBS_DEB_MAIN);
index e8e2d0f4763db4f33e899ad712595d9af5173333..f3d396e7544b9d1d0f7848bc1cabb74bce75b8de 100644 (file)
@@ -1392,10 +1392,9 @@ static void orinoco_process_scan_results(struct work_struct *work)
                                orinoco_add_hostscan_results(priv, buf, len);
 
                        kfree(buf);
-               } else if (priv->scan_request) {
+               } else {
                        /* Either abort or complete the scan */
-                       cfg80211_scan_done(priv->scan_request, (len < 0));
-                       priv->scan_request = NULL;
+                       orinoco_scan_done(priv, (len < 0));
                }
 
                spin_lock_irqsave(&priv->scan_lock, flags);
@@ -1684,6 +1683,8 @@ static int __orinoco_down(struct orinoco_private *priv)
                hermes_write_regn(hw, EVACK, 0xffff);
        }
 
+       orinoco_scan_done(priv, true);
+
        /* firmware will have to reassociate */
        netif_carrier_off(dev);
        priv->last_linkstatus = 0xffff;
@@ -1762,10 +1763,7 @@ void orinoco_reset(struct work_struct *work)
        orinoco_unlock(priv, &flags);
 
        /* Scanning support: Notify scan cancellation */
-       if (priv->scan_request) {
-               cfg80211_scan_done(priv->scan_request, 1);
-               priv->scan_request = NULL;
-       }
+       orinoco_scan_done(priv, true);
 
        if (priv->hard_reset) {
                err = (*priv->hard_reset)(priv);
@@ -1813,6 +1811,12 @@ static int __orinoco_commit(struct orinoco_private *priv)
        struct net_device *dev = priv->ndev;
        int err = 0;
 
+       /* If we've called commit, we are reconfiguring or bringing the
+        * interface up. Maintaining countermeasures across this would
+        * be confusing, so note that we've disabled them. The port will
+        * be enabled later in orinoco_commit or __orinoco_up. */
+       priv->tkip_cm_active = 0;
+
        err = orinoco_hw_program_rids(priv);
 
        /* FIXME: what about netif_tx_lock */
index 71b3d68b9403a8c4c142b776179c1edef9328ebd..32954c4b243a9dc70bbb0fd350c6c79ff67875d3 100644 (file)
@@ -151,20 +151,20 @@ orinoco_cs_config(struct pcmcia_device *link)
                goto failed;
        }
 
-       ret = pcmcia_request_irq(link, orinoco_interrupt);
-       if (ret)
-               goto failed;
-
-       /* We initialize the hermes structure before completing PCMCIA
-        * configuration just in case the interrupt handler gets
-        * called. */
        mem = ioport_map(link->resource[0]->start,
                        resource_size(link->resource[0]));
        if (!mem)
                goto failed;
 
+       /* We initialize the hermes structure before completing PCMCIA
+        * configuration just in case the interrupt handler gets
+        * called. */
        hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
 
+       ret = pcmcia_request_irq(link, orinoco_interrupt);
+       if (ret)
+               goto failed;
+
        ret = pcmcia_enable_device(link);
        if (ret)
                goto failed;
index 4300d9db7d8caab2d70442b7cbd37a9da69adef9..86cb54c842e745ffd7863457f23f45185440f556 100644 (file)
@@ -229,3 +229,11 @@ void orinoco_add_hostscan_results(struct orinoco_private *priv,
                priv->scan_request = NULL;
        }
 }
+
+void orinoco_scan_done(struct orinoco_private *priv, bool abort)
+{
+       if (priv->scan_request) {
+               cfg80211_scan_done(priv->scan_request, abort);
+               priv->scan_request = NULL;
+       }
+}
index 2dc4e046dbdb61c5c19f33e14f6ae4fae381a8c9..27281fb0a6dc02f529b4ea1edf2fb29e2a6903be 100644 (file)
@@ -16,5 +16,6 @@ void orinoco_add_extscan_result(struct orinoco_private *priv,
 void orinoco_add_hostscan_results(struct orinoco_private *dev,
                                  unsigned char *buf,
                                  size_t len);
+void orinoco_scan_done(struct orinoco_private *priv, bool abort);
 
 #endif /* _ORINOCO_SCAN_H_ */
index fb859a5ad2eb8a5c2e02f349cf4002caac32fc49..db34c282e59b39340a9bf7c6c51f529bf020a1c0 100644 (file)
@@ -214,21 +214,21 @@ spectrum_cs_config(struct pcmcia_device *link)
                goto failed;
        }
 
-       ret = pcmcia_request_irq(link, orinoco_interrupt);
-       if (ret)
-               goto failed;
-
-       /* We initialize the hermes structure before completing PCMCIA
-        * configuration just in case the interrupt handler gets
-        * called. */
        mem = ioport_map(link->resource[0]->start,
                        resource_size(link->resource[0]));
        if (!mem)
                goto failed;
 
+       /* We initialize the hermes structure before completing PCMCIA
+        * configuration just in case the interrupt handler gets
+        * called. */
        hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
        hw->eeprom_pda = true;
 
+       ret = pcmcia_request_irq(link, orinoco_interrupt);
+       if (ret)
+               goto failed;
+
        ret = pcmcia_enable_device(link);
        if (ret)
                goto failed;
index 93505f93bf97711019e86bbe27f39f4f727bce01..e5afabee60d1834b898193479cf710c3bb3eed22 100644 (file)
@@ -911,10 +911,10 @@ static int orinoco_ioctl_set_auth(struct net_device *dev,
                 */
                if (param->value) {
                        priv->tkip_cm_active = 1;
-                       ret = hermes_enable_port(hw, 0);
+                       ret = hermes_disable_port(hw, 0);
                } else {
                        priv->tkip_cm_active = 0;
-                       ret = hermes_disable_port(hw, 0);
+                       ret = hermes_enable_port(hw, 0);
                }
                break;
 
index 458bb57914a32d57948ff425508f6b40ac2de7e1..cdbeec9f83ea256507c57762dda8a7f73e69983e 100644 (file)
@@ -66,8 +66,8 @@ struct netfront_cb {
 
 #define GRANT_INVALID_REF      0
 
-#define NET_TX_RING_SIZE __RING_SIZE((struct xen_netif_tx_sring *)0, PAGE_SIZE)
-#define NET_RX_RING_SIZE __RING_SIZE((struct xen_netif_rx_sring *)0, PAGE_SIZE)
+#define NET_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE)
+#define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE)
 #define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
 
 struct netfront_info {
index 003170ea2e394193bdcb7af4033a98bca9d46127..69546e9213dd7727d7b0db8f9cd56d1772ea7431 100644 (file)
@@ -64,77 +64,6 @@ void pci_bus_remove_resources(struct pci_bus *bus)
        }
 }
 
-static bool pci_bus_resource_better(struct resource *res1, bool pos1,
-                                   struct resource *res2, bool pos2)
-{
-       /* If exactly one is positive decode, always prefer that one */
-       if (pos1 != pos2)
-               return pos1 ? true : false;
-
-       /* Prefer the one that contains the highest address */
-       if (res1->end != res2->end)
-               return (res1->end > res2->end) ? true : false;
-
-       /* Otherwise, prefer the one with highest "center of gravity" */
-       if (res1->start != res2->start)
-               return (res1->start > res2->start) ? true : false;
-
-       /* Otherwise, choose one arbitrarily (but consistently) */
-       return (res1 > res2) ? true : false;
-}
-
-static bool pci_bus_resource_positive(struct pci_bus *bus, struct resource *res)
-{
-       struct pci_bus_resource *bus_res;
-
-       /*
-        * This relies on the fact that pci_bus.resource[] refers to P2P or
-        * CardBus bridge base/limit registers, which are always positively
-        * decoded.  The pci_bus.resources list contains host bridge or
-        * subtractively decoded resources.
-        */
-       list_for_each_entry(bus_res, &bus->resources, list) {
-               if (bus_res->res == res)
-                       return (bus_res->flags & PCI_SUBTRACTIVE_DECODE) ?
-                               false : true;
-       }
-       return true;
-}
-
-/*
- * Find the next-best bus resource after the cursor "res".  If the cursor is
- * NULL, return the best resource.  "Best" means that we prefer positive
- * decode regions over subtractive decode, then those at higher addresses.
- */
-static struct resource *pci_bus_find_resource_prev(struct pci_bus *bus,
-                                                  unsigned int type,
-                                                  struct resource *res)
-{
-       bool res_pos, r_pos, prev_pos = false;
-       struct resource *r, *prev = NULL;
-       int i;
-
-       res_pos = pci_bus_resource_positive(bus, res);
-       pci_bus_for_each_resource(bus, r, i) {
-               if (!r)
-                       continue;
-
-               if ((r->flags & IORESOURCE_TYPE_BITS) != type)
-                       continue;
-
-               r_pos = pci_bus_resource_positive(bus, r);
-               if (!res || pci_bus_resource_better(res, res_pos, r, r_pos)) {
-                       if (!prev || pci_bus_resource_better(r, r_pos,
-                                                            prev, prev_pos)) {
-                               prev = r;
-                               prev_pos = r_pos;
-                       }
-               }
-       }
-
-       return prev;
-}
-
 /**
  * pci_bus_alloc_resource - allocate a resource from a parent bus
  * @bus: PCI bus
@@ -160,10 +89,9 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
                                          resource_size_t),
                void *alignf_data)
 {
-       int ret = -ENOMEM;
+       int i, ret = -ENOMEM;
        struct resource *r;
        resource_size_t max = -1;
-       unsigned int type = res->flags & IORESOURCE_TYPE_BITS;
 
        type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
 
@@ -171,9 +99,10 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
        if (!(res->flags & IORESOURCE_MEM_64))
                max = PCIBIOS_MAX_MEM_32;
 
-       /* Look for space at highest addresses first */
-       r = pci_bus_find_resource_prev(bus, type, NULL);
-       for ( ; r; r = pci_bus_find_resource_prev(bus, type, r)) {
+       pci_bus_for_each_resource(bus, r, i) {
+               if (!r)
+                       continue;
+
                /* type_mask must match */
                if ((res->flags ^ r->flags) & type_mask)
                        continue;
index 36191edd6d51052560e5f8b0215cac1b4f893c89..53a786fd0d40c88d978bd4a656971be7b09cdb4a 100644 (file)
@@ -2329,6 +2329,9 @@ static void __devinit nvbridge_check_legacy_irq_routing(struct pci_dev *dev)
 {
        u32 cfg;
 
+       if (!pci_find_capability(dev, PCI_CAP_ID_HT))
+               return;
+
        pci_read_config_dword(dev, 0x74, &cfg);
 
        if (cfg & ((1 << 2) | (1 << 15))) {
index 2d73dfcecdbb4e2098e3d881a6a091a9e8ca5e62..57313f4658bc55a00a5a7d36fbb86450f8144def 100644 (file)
@@ -180,7 +180,7 @@ struct pnp_protocol pnpacpi_protocol = {
 };
 EXPORT_SYMBOL(pnpacpi_protocol);
 
-static char *pnpacpi_get_id(struct acpi_device *device)
+static char *__init pnpacpi_get_id(struct acpi_device *device)
 {
        struct acpi_hardware_id *id;
 
index 51237fbb1bbb7e15f952296a9ffcb9f668418fc9..6d20b0454a1d7284c7728e3ec0c85d7d8e22f452 100644 (file)
@@ -231,8 +231,7 @@ static int tps6586x_dvm_voltages[] = {
 };
 
 #define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits,       \
-                          ereg0, ebit0, ereg1, ebit1, goreg, gobit)    \
-{                                                                      \
+                          ereg0, ebit0, ereg1, ebit1)                  \
        .desc   = {                                                     \
                .name   = "REG-" #_id,                                  \
                .ops    = &tps6586x_regulator_##_ops,                   \
@@ -248,18 +247,26 @@ static int tps6586x_dvm_voltages[] = {
        .enable_bit[0]  = (ebit0),                                      \
        .enable_reg[1]  = TPS6586X_SUPPLY##ereg1,                       \
        .enable_bit[1]  = (ebit1),                                      \
-       .voltages       = tps6586x_##vdata##_voltages,                  \
-}
+       .voltages       = tps6586x_##vdata##_voltages,
+
+#define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit)                     \
+       .go_reg = TPS6586X_##goreg,                                     \
+       .go_bit = (gobit),
 
 #define TPS6586X_LDO(_id, vdata, vreg, shift, nbits,                   \
                     ereg0, ebit0, ereg1, ebit1)                        \
+{                                                                      \
        TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits,     \
-                          ereg0, ebit0, ereg1, ebit1, 0, 0)
+                          ereg0, ebit0, ereg1, ebit1)                  \
+}
 
 #define TPS6586X_DVM(_id, vdata, vreg, shift, nbits,                   \
                     ereg0, ebit0, ereg1, ebit1, goreg, gobit)          \
+{                                                                      \
        TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits,     \
-                          ereg0, ebit0, ereg1, ebit1, goreg, gobit)
+                          ereg0, ebit0, ereg1, ebit1)                  \
+       TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit)                      \
+}
 
 static struct tps6586x_regulator tps6586x_regulator[] = {
        TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0),
@@ -267,11 +274,11 @@ static struct tps6586x_regulator tps6586x_regulator[] = {
        TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6),
        TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4),
        TPS6586X_LDO(LDO_7, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5),
-       TPS6586X_LDO(LDO_8, ldo, SUPPLYV1, 5, 3, ENC, 6, END, 6),
+       TPS6586X_LDO(LDO_8, ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6),
        TPS6586X_LDO(LDO_9, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7),
-       TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, ENE, 7, ENE, 7),
+       TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7),
        TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1),
-       TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 1, END, 1),
+       TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7),
 
        TPS6586X_DVM(LDO_2, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3, VCC2, 6),
        TPS6586X_DVM(LDO_4, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3, VCC1, 6),
@@ -290,6 +297,10 @@ static inline int tps6586x_regulator_preinit(struct device *parent,
        uint8_t val1, val2;
        int ret;
 
+       if (ri->enable_reg[0] == ri->enable_reg[1] &&
+           ri->enable_bit[0] == ri->enable_bit[1])
+                       return 0;
+
        ret = tps6586x_read(parent, ri->enable_reg[0], &val1);
        if (ret)
                return ret;
@@ -298,14 +309,14 @@ static inline int tps6586x_regulator_preinit(struct device *parent,
        if (ret)
                return ret;
 
-       if (!(val2 & ri->enable_bit[1]))
+       if (!(val2 & (1 << ri->enable_bit[1])))
                return 0;
 
        /*
         * The regulator is on, but it's enabled with the bit we don't
         * want to use, so we switch the enable bits
         */
-       if (!(val1 & ri->enable_bit[0])) {
+       if (!(val1 & (1 << ri->enable_bit[0]))) {
                ret = tps6586x_set_bits(parent, ri->enable_reg[0],
                                        1 << ri->enable_bit[0]);
                if (ret)
index d37c7331f244f1463c154a05ec9649306fe0c358..0bcd5806bd9a616df1f919f77c7e6a741e44533e 100644 (file)
@@ -156,6 +156,8 @@ static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
                if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) ||
                      a_status & ZFCP_STATUS_COMMON_ERP_FAILED)
                        return 0;
+               if (p_status & ZFCP_STATUS_COMMON_NOESC)
+                       return need;
                if (!(a_status & ZFCP_STATUS_COMMON_UNBLOCKED))
                        need = ZFCP_ERP_ACTION_REOPEN_ADAPTER;
                /* fall through */
@@ -188,6 +190,9 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
                atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
                                &zfcp_sdev->status);
                erp_action = &zfcp_sdev->erp_action;
+               memset(erp_action, 0, sizeof(struct zfcp_erp_action));
+               erp_action->port = port;
+               erp_action->sdev = sdev;
                if (!(atomic_read(&zfcp_sdev->status) &
                      ZFCP_STATUS_COMMON_RUNNING))
                        act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
@@ -200,6 +205,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
                zfcp_erp_action_dismiss_port(port);
                atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status);
                erp_action = &port->erp_action;
+               memset(erp_action, 0, sizeof(struct zfcp_erp_action));
+               erp_action->port = port;
                if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING))
                        act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
                break;
@@ -209,6 +216,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
                zfcp_erp_action_dismiss_adapter(adapter);
                atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status);
                erp_action = &adapter->erp_action;
+               memset(erp_action, 0, sizeof(struct zfcp_erp_action));
                if (!(atomic_read(&adapter->status) &
                      ZFCP_STATUS_COMMON_RUNNING))
                        act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
@@ -218,10 +226,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
                return NULL;
        }
 
-       memset(erp_action, 0, sizeof(struct zfcp_erp_action));
        erp_action->adapter = adapter;
-       erp_action->port = port;
-       erp_action->sdev = sdev;
        erp_action->action = need;
        erp_action->status = act_status;
 
index be0317457147fc4a891f4b0be67c8116b98526b1..2eb7dd56ab800af62da15d6a4cde42f2caf6177f 100644 (file)
@@ -851,7 +851,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *scmnd)
 
        zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
 
-       req->data = zfcp_sdev;
+       req->data = sdev;
        req->handler = zfcp_fsf_abort_fcp_command_handler;
        req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
        req->qtcb->header.port_handle = zfcp_sdev->port->handle;
@@ -2069,8 +2069,6 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req)
        struct fcp_resp_with_ext *fcp_rsp;
        unsigned long flags;
 
-       zfcp_fsf_fcp_handler_common(req);
-
        read_lock_irqsave(&req->adapter->abort_lock, flags);
 
        scpnt = req->data;
@@ -2079,6 +2077,8 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req)
                return;
        }
 
+       zfcp_fsf_fcp_handler_common(req);
+
        if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
                set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED);
                goto skip_fsfstatus;
@@ -2170,12 +2170,13 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd)
        struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
        struct zfcp_qdio *qdio = adapter->qdio;
        struct fsf_qtcb_bottom_io *io;
+       unsigned long flags;
 
        if (unlikely(!(atomic_read(&zfcp_sdev->status) &
                       ZFCP_STATUS_COMMON_UNBLOCKED)))
                return -EBUSY;
 
-       spin_lock(&qdio->req_q_lock);
+       spin_lock_irqsave(&qdio->req_q_lock, flags);
        if (atomic_read(&qdio->req_q_free) <= 0) {
                atomic_inc(&qdio->req_q_full);
                goto out;
@@ -2239,7 +2240,7 @@ failed_scsi_cmnd:
        zfcp_fsf_req_free(req);
        scsi_cmnd->host_scribble = NULL;
 out:
-       spin_unlock(&qdio->req_q_lock);
+       spin_unlock_irqrestore(&qdio->req_q_lock, flags);
        return retval;
 }
 
index 6bd2dbc4c31606d5019fb1e76d92ef88583a2140..63529ed801eb3e4a37c768f1b55851863b60e9cb 100644 (file)
@@ -76,8 +76,8 @@ static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result)
        scpnt->scsi_done(scpnt);
 }
 
-static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt,
-                                 void (*done) (struct scsi_cmnd *))
+static
+int zfcp_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scpnt)
 {
        struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
        struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
@@ -87,7 +87,6 @@ static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt,
        /* reset the status for this request */
        scpnt->result = 0;
        scpnt->host_scribble = NULL;
-       scpnt->scsi_done = done;
 
        scsi_result = fc_remote_port_chkready(rport);
        if (unlikely(scsi_result)) {
@@ -127,8 +126,6 @@ static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt,
        return ret;
 }
 
-static DEF_SCSI_QCMD(zfcp_scsi_queuecommand)
-
 static int zfcp_scsi_slave_alloc(struct scsi_device *sdev)
 {
        struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
index b2fb2b2a6e700e86d7de265503b70cb48830d994..a6dea08664fc638c611260cbdd067978fb8b8092 100644 (file)
@@ -90,11 +90,7 @@ static const struct pci_device_id hpsa_pci_device_id[] = {
        {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3252},
        {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3253},
        {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3254},
-#define PCI_DEVICE_ID_HP_CISSF 0x333f
-       {PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x333F},
-       {PCI_VENDOR_ID_HP,     PCI_ANY_ID,             PCI_ANY_ID, PCI_ANY_ID,
-               PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
-       {PCI_VENDOR_ID_COMPAQ,     PCI_ANY_ID,             PCI_ANY_ID, PCI_ANY_ID,
+       {PCI_VENDOR_ID_HP,     PCI_ANY_ID,      PCI_ANY_ID, PCI_ANY_ID,
                PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
        {0,}
 };
@@ -113,8 +109,6 @@ static struct board_type products[] = {
        {0x3249103C, "Smart Array P812", &SA5_access},
        {0x324a103C, "Smart Array P712m", &SA5_access},
        {0x324b103C, "Smart Array P711m", &SA5_access},
-       {0x3233103C, "StorageWorks P1210m", &SA5_access},
-       {0x333F103C, "StorageWorks P1210m", &SA5_access},
        {0x3250103C, "Smart Array", &SA5_access},
        {0x3250113C, "Smart Array", &SA5_access},
        {0x3250123C, "Smart Array", &SA5_access},
index 0433ea6f27c9c2db97c464ca238afce39ebd0fcb..b37c8a3c1bb0de6d1b64fdf9ea3cbb8357f13805 100644 (file)
@@ -951,8 +951,8 @@ static int _osd_req_finalize_cdb_cont(struct osd_request *or, const u8 *cap_key)
        /* create a bio for continuation segment */
        bio = bio_map_kern(req_q, or->cdb_cont.buff, or->cdb_cont.total_bytes,
                           GFP_KERNEL);
-       if (unlikely(!bio))
-               return -ENOMEM;
+       if (IS_ERR(bio))
+               return PTR_ERR(bio);
 
        bio->bi_rw |= REQ_WRITE;
 
index 5e76a624cb08a843d194e7102900dfac77c2aae4..300d59f389da76175ac4720fc2d9a69b0a16b163 100644 (file)
@@ -62,6 +62,7 @@
 static unsigned int pmcraid_debug_log;
 static unsigned int pmcraid_disable_aen;
 static unsigned int pmcraid_log_level = IOASC_LOG_LEVEL_MUST;
+static unsigned int pmcraid_enable_msix;
 
 /*
  * Data structures to support multiple adapters by the LLD.
@@ -4691,7 +4692,8 @@ pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance)
        int rc;
        struct pci_dev *pdev = pinstance->pdev;
 
-       if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) {
+       if ((pmcraid_enable_msix) &&
+               (pci_find_capability(pdev, PCI_CAP_ID_MSIX))) {
                int num_hrrq = PMCRAID_NUM_MSIX_VECTORS;
                struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS];
                int i;
index 1134279604e805780f84607c523bbdd647685f24..4db210d93947275efd67e493549d75162fdf21e1 100644 (file)
@@ -42,7 +42,7 @@
  */
 #define PMCRAID_DRIVER_NAME            "PMC MaxRAID"
 #define PMCRAID_DEVFILE                        "pmcsas"
-#define PMCRAID_DRIVER_VERSION         "2.0.3"
+#define PMCRAID_DRIVER_VERSION         "1.0.3"
 #define PMCRAID_DRIVER_DATE            __DATE__
 
 #define PMCRAID_FW_VERSION_1           0x002
@@ -333,11 +333,9 @@ struct pmcraid_config_table_entry {
        __u8  lun[PMCRAID_LUN_LEN];
 } __attribute__((packed, aligned(4)));
 
-/* extended configuration table sizes are of 64 bytes in size */
-#define PMCRAID_CFGTE_EXT_SIZE 32
+/* extended configuration table sizes are also of 32 bytes in size */
 struct pmcraid_config_table_entry_ext {
        struct pmcraid_config_table_entry cfgte;
-       __u8  cfgte_ext[PMCRAID_CFGTE_EXT_SIZE];
 };
 
 /* resource types (config_table_entry.resource_type values) */
index 3a22effced5fa1a94996582b9fd13ccf151d8861..9ce539d4557e2a18d495ec2a31366cf5ebccc4aa 100644 (file)
@@ -2409,7 +2409,6 @@ struct qla_hw_data {
                uint32_t        enable_target_reset     :1;
                uint32_t        enable_lip_full_login   :1;
                uint32_t        enable_led_scheme       :1;
-               uint32_t        inta_enabled            :1;
                uint32_t        msi_enabled             :1;
                uint32_t        msix_enabled            :1;
                uint32_t        disable_serdes          :1;
index 5f94430b42f03974fda76e9f1f969cedbf3e9047..4c1ba6263eb32c1a228f2044b314c4e902f1c677 100644 (file)
@@ -1061,6 +1061,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
                fcp_cmnd->additional_cdb_len |= 2;
 
        int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun);
+       host_to_fcp_swap((uint8_t *)&fcp_cmnd->lun, sizeof(fcp_cmnd->lun));
        memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len);
        cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len);
        cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32(
index 1f06ddd9bdd10cdbe6526de1deaaab194a19118e..7f77898486a9014f1e4848e77648f78c5dce1c75 100644 (file)
@@ -2491,14 +2491,15 @@ skip_msix:
 skip_msi:
 
        ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
-           IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp);
+           ha->flags.msi_enabled ? 0 : IRQF_SHARED,
+           QLA2XXX_DRIVER_NAME, rsp);
        if (ret) {
                qla_printk(KERN_WARNING, ha,
                    "Failed to reserve interrupt %d already in use.\n",
                    ha->pdev->irq);
                goto fail;
        }
-       ha->flags.inta_enabled = 1;
+
 clear_risc_ints:
 
        /*
index 8d9edfb39803ff26809743ef8cf5e0b22abd305b..ae2acacc00036558c5ddb0e246e8b691097c80ca 100644 (file)
@@ -2749,6 +2749,7 @@ sufficient_dsds:
                        goto queuing_error_fcp_cmnd;
 
                int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun);
+               host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
 
                /* build FCP_CMND IU */
                memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd));
index 1644eabaafeb58cb3130dccdb97b489bcd0c708e..2c0876c81a3f6e5793d504b825146b6de7c2ae81 100644 (file)
@@ -829,7 +829,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 {
        scsi_qla_host_t *vha = shost_priv(cmd->device->host);
        srb_t *sp;
-       int ret;
+       int ret = SUCCESS;
        unsigned int id, lun;
        unsigned long flags;
        int wait = 0;
@@ -2064,6 +2064,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
                ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
                ha->gid_list_info_size = 8;
                ha->optrom_size = OPTROM_SIZE_82XX;
+               ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
                ha->isp_ops = &qla82xx_isp_ops;
                ha->flash_conf_off = FARX_ACCESS_FLASH_CONF;
                ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
index 8edbccb3232d3b68cb16d0054a444e657a452975..cf0075a2d0c2e66d93146bd92d95a5811f021327 100644 (file)
@@ -7,9 +7,9 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.03.04-k0"
+#define QLA2XXX_VERSION      "8.03.05-k0"
 
 #define QLA_DRIVER_MAJOR_VER   8
 #define QLA_DRIVER_MINOR_VER   3
-#define QLA_DRIVER_PATCH_VER   4
+#define QLA_DRIVER_PATCH_VER   5
 #define QLA_DRIVER_BETA_VER    0
index 824b8fc03ce52f087dd3ca4d0fdadab15dfcac17..30ac116186f5106f61415cbdd9ee0b67a3f3b88e 100644 (file)
@@ -615,7 +615,7 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
        return rtn;
 }
 
-static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
+static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
 {
        if (!scmd->device->host->hostt->eh_abort_handler)
                return FAILED;
@@ -623,31 +623,9 @@ static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
        return scmd->device->host->hostt->eh_abort_handler(scmd);
 }
 
-/**
- * scsi_try_to_abort_cmd - Ask host to abort a running command.
- * @scmd:      SCSI cmd to abort from Lower Level.
- *
- * Notes:
- *    This function will not return until the user's completion function
- *    has been called.  there is no timeout on this operation.  if the
- *    author of the low-level driver wishes this operation to be timed,
- *    they can provide this facility themselves.  helper functions in
- *    scsi_error.c can be supplied to make this easier to do.
- */
-static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
-{
-       /*
-        * scsi_done was called just after the command timed out and before
-        * we had a chance to process it. (db)
-        */
-       if (scmd->serial_number == 0)
-               return SUCCESS;
-       return __scsi_try_to_abort_cmd(scmd);
-}
-
 static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd)
 {
-       if (__scsi_try_to_abort_cmd(scmd) != SUCCESS)
+       if (scsi_try_to_abort_cmd(scmd) != SUCCESS)
                if (scsi_try_bus_device_reset(scmd) != SUCCESS)
                        if (scsi_try_target_reset(scmd) != SUCCESS)
                                if (scsi_try_bus_reset(scmd) != SUCCESS)
index eafeeda6e1942b7deda691f940c0f10efddee390..5b6bbaea59fec92565d2af4d708cedce034295ae 100644 (file)
@@ -1403,11 +1403,6 @@ static void scsi_softirq_done(struct request *rq)
 
        INIT_LIST_HEAD(&cmd->eh_entry);
 
-       /*
-        * Set the serial numbers back to zero
-        */
-       cmd->serial_number = 0;
-
        atomic_inc(&cmd->device->iodone_cnt);
        if (cmd->result)
                atomic_inc(&cmd->device->ioerr_cnt);
index 3374618300af87c16ac3ef6a674e9cb650e62f8c..25a8bc565f400b62c155dd31bb39ff08e8d85dd0 100644 (file)
@@ -90,7 +90,8 @@ static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper);
 
 static void kgdboc_restore_input(void)
 {
-       schedule_work(&kgdboc_restore_input_work);
+       if (likely(system_state == SYSTEM_RUNNING))
+               schedule_work(&kgdboc_restore_input_work);
 }
 
 static int kgdboc_register_kbd(char **cptr)
index 90439314cf673ce19c33747ab4f283f0f3f0bc01..0838c79861e49f9a0c97189af9ab25d3c0269b76 100644 (file)
@@ -413,6 +413,11 @@ static void poll_transfer(struct dw_spi *dws)
 {
        while (dws->write(dws))
                dws->read(dws);
+       /*
+        * There is a possibility that the last word of a transaction
+        * will be lost if data is not ready. Re-read to solve this issue.
+        */
+       dws->read(dws);
 
        transfer_complete(dws);
 }
index 05bf5a27b5b0491fd7fd6feaddb24f51983317d3..989e16e4ab5c4b4057f2069927d03474e8441a5c 100644 (file)
@@ -951,7 +951,9 @@ static int usbatm_atm_init(struct usbatm_data *instance)
         * condition: callbacks we register can be executed at once, before we have
         * initialized the struct atm_dev.  To protect against this, all callbacks
         * abort if atm_dev->dev_data is NULL. */
-       atm_dev = atm_dev_register(instance->driver_name, &usbatm_atm_devops, -1, NULL);
+       atm_dev = atm_dev_register(instance->driver_name,
+                                  &instance->usb_intf->dev, &usbatm_atm_devops,
+                                  -1, NULL);
        if (!atm_dev) {
                usb_err(instance, "%s: failed to register ATM device!\n", __func__);
                return -1;
@@ -966,14 +968,6 @@ static int usbatm_atm_init(struct usbatm_data *instance)
        /* temp init ATM device, set to 128kbit */
        atm_dev->link_rate = 128 * 1000 / 424;
 
-       ret = sysfs_create_link(&atm_dev->class_dev.kobj,
-                               &instance->usb_intf->dev.kobj, "device");
-       if (ret) {
-               atm_err(instance, "%s: sysfs_create_link failed: %d\n",
-                                       __func__, ret);
-               goto fail_sysfs;
-       }
-
        if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) {
                atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret);
                goto fail;
@@ -992,8 +986,6 @@ static int usbatm_atm_init(struct usbatm_data *instance)
        return 0;
 
  fail:
-       sysfs_remove_link(&atm_dev->class_dev.kobj, "device");
- fail_sysfs:
        instance->atm_dev = NULL;
        atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */
        return ret;
@@ -1329,7 +1321,6 @@ void usbatm_usb_disconnect(struct usb_interface *intf)
 
        /* ATM finalize */
        if (instance->atm_dev) {
-               sysfs_remove_link(&instance->atm_dev->class_dev.kobj, "device");
                atm_dev_deregister(instance->atm_dev);
                instance->atm_dev = NULL;
        }
index 94701ff3a23ad957a9c675bd3ccd74418c2f989e..159c77a5746fecfd6c6eeb687cf11e747e194fba 100644 (file)
@@ -884,6 +884,7 @@ static int log_write(void __user *log_base,
        int r;
        if (!write_length)
                return 0;
+       write_length += write_address % VHOST_PAGE_SIZE;
        write_address /= VHOST_PAGE_SIZE;
        for (;;) {
                u64 base = (u64)(unsigned long)log_base;
@@ -897,7 +898,7 @@ static int log_write(void __user *log_base,
                if (write_length <= VHOST_PAGE_SIZE)
                        break;
                write_length -= VHOST_PAGE_SIZE;
-               write_address += VHOST_PAGE_SIZE;
+               write_address += 1;
        }
        return r;
 }
index 0a4dbdc1693a4462bddb82cdf5e0b9ab5ec4bed2..de450c1fb86926f39190f052d7644d56f60ccc5d 100644 (file)
@@ -855,6 +855,7 @@ const struct fb_videomode *fb_find_nearest_mode(const struct fb_videomode *mode,
                        abs(cmode->yres - mode->yres);
                if (diff > d) {
                        diff = d;
+                       diff_refresh = abs(cmode->refresh - mode->refresh);
                        best = cmode;
                } else if (diff == d) {
                        d = abs(cmode->refresh - mode->refresh);
index c547cca26a266e962bbb760c0616e0846439d81d..51d2e4de34ebe58d4eb5d2c99d1fc1bb83f692f9 100644 (file)
@@ -696,6 +696,7 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
                                   __btree_submit_bio_done);
 }
 
+#ifdef CONFIG_MIGRATION
 static int btree_migratepage(struct address_space *mapping,
                        struct page *newpage, struct page *page)
 {
@@ -712,12 +713,9 @@ static int btree_migratepage(struct address_space *mapping,
        if (page_has_private(page) &&
            !try_to_release_page(page, GFP_KERNEL))
                return -EAGAIN;
-#ifdef CONFIG_MIGRATION
        return migrate_page(mapping, newpage, page);
-#else
-       return -ENOSYS;
-#endif
 }
+#endif
 
 static int btree_writepage(struct page *page, struct writeback_control *wbc)
 {
@@ -1009,7 +1007,10 @@ static int find_and_setup_root(struct btrfs_root *tree_root,
        blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
        root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
                                     blocksize, generation);
-       BUG_ON(!root->node);
+       if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) {
+               free_extent_buffer(root->node);
+               return -EIO;
+       }
        root->commit_root = btrfs_root_node(root);
        return 0;
 }
index bcd59c7dfb574def82517a80affe6a9ddf756a92..227e5815d8382393d4adc4d0a340ee636bca9d3e 100644 (file)
@@ -429,6 +429,7 @@ err:
 
 static int cache_block_group(struct btrfs_block_group_cache *cache,
                             struct btrfs_trans_handle *trans,
+                            struct btrfs_root *root,
                             int load_cache_only)
 {
        struct btrfs_fs_info *fs_info = cache->fs_info;
@@ -442,9 +443,12 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
 
        /*
         * We can't do the read from on-disk cache during a commit since we need
-        * to have the normal tree locking.
+        * to have the normal tree locking.  Also if we are currently trying to
+        * allocate blocks for the tree root we can't do the fast caching since
+        * we likely hold important locks.
         */
-       if (!trans->transaction->in_commit) {
+       if (!trans->transaction->in_commit &&
+           (root && root != root->fs_info->tree_root)) {
                spin_lock(&cache->lock);
                if (cache->cached != BTRFS_CACHE_NO) {
                        spin_unlock(&cache->lock);
@@ -2741,6 +2745,7 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group,
        struct btrfs_root *root = block_group->fs_info->tree_root;
        struct inode *inode = NULL;
        u64 alloc_hint = 0;
+       int dcs = BTRFS_DC_ERROR;
        int num_pages = 0;
        int retries = 0;
        int ret = 0;
@@ -2795,6 +2800,8 @@ again:
 
        spin_lock(&block_group->lock);
        if (block_group->cached != BTRFS_CACHE_FINISHED) {
+               /* We're not cached, don't bother trying to write stuff out */
+               dcs = BTRFS_DC_WRITTEN;
                spin_unlock(&block_group->lock);
                goto out_put;
        }
@@ -2821,6 +2828,8 @@ again:
        ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages,
                                              num_pages, num_pages,
                                              &alloc_hint);
+       if (!ret)
+               dcs = BTRFS_DC_SETUP;
        btrfs_free_reserved_data_space(inode, num_pages);
 out_put:
        iput(inode);
@@ -2828,10 +2837,7 @@ out_free:
        btrfs_release_path(root, path);
 out:
        spin_lock(&block_group->lock);
-       if (ret)
-               block_group->disk_cache_state = BTRFS_DC_ERROR;
-       else
-               block_group->disk_cache_state = BTRFS_DC_SETUP;
+       block_group->disk_cache_state = dcs;
        spin_unlock(&block_group->lock);
 
        return ret;
@@ -3037,7 +3043,13 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
 
 u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags)
 {
-       u64 num_devices = root->fs_info->fs_devices->rw_devices;
+       /*
+        * we add in the count of missing devices because we want
+        * to make sure that any RAID levels on a degraded FS
+        * continue to be honored.
+        */
+       u64 num_devices = root->fs_info->fs_devices->rw_devices +
+               root->fs_info->fs_devices->missing_devices;
 
        if (num_devices == 1)
                flags &= ~(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID0);
@@ -4080,7 +4092,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
                 * space back to the block group, otherwise we will leak space.
                 */
                if (!alloc && cache->cached == BTRFS_CACHE_NO)
-                       cache_block_group(cache, trans, 1);
+                       cache_block_group(cache, trans, NULL, 1);
 
                byte_in_group = bytenr - cache->key.objectid;
                WARN_ON(byte_in_group > cache->key.offset);
@@ -4930,11 +4942,31 @@ search:
                btrfs_get_block_group(block_group);
                search_start = block_group->key.objectid;
 
+               /*
+                * this can happen if we end up cycling through all the
+                * raid types, but we want to make sure we only allocate
+                * for the proper type.
+                */
+               if (!block_group_bits(block_group, data)) {
+                   u64 extra = BTRFS_BLOCK_GROUP_DUP |
+                               BTRFS_BLOCK_GROUP_RAID1 |
+                               BTRFS_BLOCK_GROUP_RAID10;
+
+                       /*
+                        * if they asked for extra copies and this block group
+                        * doesn't provide them, bail.  This does allow us to
+                        * fill raid0 from raid1.
+                        */
+                       if ((data & extra) && !(block_group->flags & extra))
+                               goto loop;
+               }
+
 have_block_group:
                if (unlikely(block_group->cached == BTRFS_CACHE_NO)) {
                        u64 free_percent;
 
-                       ret = cache_block_group(block_group, trans, 1);
+                       ret = cache_block_group(block_group, trans,
+                                               orig_root, 1);
                        if (block_group->cached == BTRFS_CACHE_FINISHED)
                                goto have_block_group;
 
@@ -4958,7 +4990,8 @@ have_block_group:
                        if (loop > LOOP_CACHING_NOWAIT ||
                            (loop > LOOP_FIND_IDEAL &&
                             atomic_read(&space_info->caching_threads) < 2)) {
-                               ret = cache_block_group(block_group, trans, 0);
+                               ret = cache_block_group(block_group, trans,
+                                                       orig_root, 0);
                                BUG_ON(ret);
                        }
                        found_uncached_bg = true;
@@ -5515,7 +5548,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
        u64 num_bytes = ins->offset;
 
        block_group = btrfs_lookup_block_group(root->fs_info, ins->objectid);
-       cache_block_group(block_group, trans, 0);
+       cache_block_group(block_group, trans, NULL, 0);
        caching_ctl = get_caching_control(block_group);
 
        if (!caching_ctl) {
@@ -6300,9 +6333,13 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
                                           NULL, NULL);
                BUG_ON(ret < 0);
                if (ret > 0) {
-                       ret = btrfs_del_orphan_item(trans, tree_root,
-                                                   root->root_key.objectid);
-                       BUG_ON(ret);
+                       /* if we fail to delete the orphan item this time
+                        * around, it'll get picked up the next time.
+                        *
+                        * The most common failure here is just -ENOENT.
+                        */
+                       btrfs_del_orphan_item(trans, tree_root,
+                                             root->root_key.objectid);
                }
        }
 
@@ -7878,7 +7915,14 @@ static u64 update_block_group_flags(struct btrfs_root *root, u64 flags)
        u64 stripped = BTRFS_BLOCK_GROUP_RAID0 |
                BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10;
 
-       num_devices = root->fs_info->fs_devices->rw_devices;
+       /*
+        * we add in the count of missing devices because we want
+        * to make sure that any RAID levels on a degraded FS
+        * continue to be honored.
+        */
+       num_devices = root->fs_info->fs_devices->rw_devices +
+               root->fs_info->fs_devices->missing_devices;
+
        if (num_devices == 1) {
                stripped |= BTRFS_BLOCK_GROUP_DUP;
                stripped = flags & ~stripped;
@@ -8247,7 +8291,6 @@ int btrfs_read_block_groups(struct btrfs_root *root)
                        break;
                if (ret != 0)
                        goto error;
-
                leaf = path->nodes[0];
                btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
                cache = kzalloc(sizeof(*cache), GFP_NOFS);
index c1faded5fca03a7cbcb509908cfdf3cc8362ce1f..66836d85763bbfd2dafe3821a1be30f173784fdc 100644 (file)
@@ -48,30 +48,34 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages,
                                         struct page **prepared_pages,
                                         struct iov_iter *i)
 {
-       size_t copied;
+       size_t copied = 0;
        int pg = 0;
        int offset = pos & (PAGE_CACHE_SIZE - 1);
+       int total_copied = 0;
 
        while (write_bytes > 0) {
                size_t count = min_t(size_t,
                                     PAGE_CACHE_SIZE - offset, write_bytes);
                struct page *page = prepared_pages[pg];
-again:
-               if (unlikely(iov_iter_fault_in_readable(i, count)))
-                       return -EFAULT;
-
-               /* Copy data from userspace to the current page */
-               copied = iov_iter_copy_from_user(page, i, offset, count);
+               /*
+                * Copy data from userspace to the current page
+                *
+                * Disable pagefault to avoid recursive lock since
+                * the pages are already locked
+                */
+               pagefault_disable();
+               copied = iov_iter_copy_from_user_atomic(page, i, offset, count);
+               pagefault_enable();
 
                /* Flush processor's dcache for this page */
                flush_dcache_page(page);
                iov_iter_advance(i, copied);
                write_bytes -= copied;
+               total_copied += copied;
 
+               /* Return to btrfs_file_aio_write to fault page */
                if (unlikely(copied == 0)) {
-                       count = min_t(size_t, PAGE_CACHE_SIZE - offset,
-                                     iov_iter_single_seg_count(i));
-                       goto again;
+                       break;
                }
 
                if (unlikely(copied < PAGE_CACHE_SIZE - offset)) {
@@ -81,7 +85,7 @@ again:
                        offset = 0;
                }
        }
-       return 0;
+       return total_copied;
 }
 
 /*
@@ -854,6 +858,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
        unsigned long last_index;
        int will_write;
        int buffered = 0;
+       int copied = 0;
+       int dirty_pages = 0;
 
        will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) ||
                      (file->f_flags & O_DIRECT));
@@ -970,7 +976,17 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
                WARN_ON(num_pages > nrptrs);
                memset(pages, 0, sizeof(struct page *) * nrptrs);
 
-               ret = btrfs_delalloc_reserve_space(inode, write_bytes);
+               /*
+                * Fault pages before locking them in prepare_pages
+                * to avoid recursive lock
+                */
+               if (unlikely(iov_iter_fault_in_readable(&i, write_bytes))) {
+                       ret = -EFAULT;
+                       goto out;
+               }
+
+               ret = btrfs_delalloc_reserve_space(inode,
+                                       num_pages << PAGE_CACHE_SHIFT);
                if (ret)
                        goto out;
 
@@ -978,37 +994,49 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
                                    pos, first_index, last_index,
                                    write_bytes);
                if (ret) {
-                       btrfs_delalloc_release_space(inode, write_bytes);
+                       btrfs_delalloc_release_space(inode,
+                                       num_pages << PAGE_CACHE_SHIFT);
                        goto out;
                }
 
-               ret = btrfs_copy_from_user(pos, num_pages,
+               copied = btrfs_copy_from_user(pos, num_pages,
                                           write_bytes, pages, &i);
-               if (ret == 0) {
+               dirty_pages = (copied + PAGE_CACHE_SIZE - 1) >>
+                                       PAGE_CACHE_SHIFT;
+
+               if (num_pages > dirty_pages) {
+                       if (copied > 0)
+                               atomic_inc(
+                                       &BTRFS_I(inode)->outstanding_extents);
+                       btrfs_delalloc_release_space(inode,
+                                       (num_pages - dirty_pages) <<
+                                       PAGE_CACHE_SHIFT);
+               }
+
+               if (copied > 0) {
                        dirty_and_release_pages(NULL, root, file, pages,
-                                               num_pages, pos, write_bytes);
+                                               dirty_pages, pos, copied);
                }
 
                btrfs_drop_pages(pages, num_pages);
-               if (ret) {
-                       btrfs_delalloc_release_space(inode, write_bytes);
-                       goto out;
-               }
 
-               if (will_write) {
-                       filemap_fdatawrite_range(inode->i_mapping, pos,
-                                                pos + write_bytes - 1);
-               } else {
-                       balance_dirty_pages_ratelimited_nr(inode->i_mapping,
-                                                          num_pages);
-                       if (num_pages <
-                           (root->leafsize >> PAGE_CACHE_SHIFT) + 1)
-                               btrfs_btree_balance_dirty(root, 1);
-                       btrfs_throttle(root);
+               if (copied > 0) {
+                       if (will_write) {
+                               filemap_fdatawrite_range(inode->i_mapping, pos,
+                                                        pos + copied - 1);
+                       } else {
+                               balance_dirty_pages_ratelimited_nr(
+                                                       inode->i_mapping,
+                                                       dirty_pages);
+                               if (dirty_pages <
+                               (root->leafsize >> PAGE_CACHE_SHIFT) + 1)
+                                       btrfs_btree_balance_dirty(root, 1);
+                               btrfs_throttle(root);
+                       }
                }
 
-               pos += write_bytes;
-               num_written += write_bytes;
+               pos += copied;
+               num_written += copied;
 
                cond_resched();
        }
index 22ee0dc2e6b8a712900c68a8c44df4a453fb86f0..60d684266959bbf8f96c14873e9a1f57e069a29e 100644 (file)
@@ -290,7 +290,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
                       (unsigned long long)BTRFS_I(inode)->generation,
                       (unsigned long long)generation,
                       (unsigned long long)block_group->key.objectid);
-               goto out;
+               goto free_cache;
        }
 
        if (!num_entries)
@@ -524,6 +524,12 @@ int btrfs_write_out_cache(struct btrfs_root *root,
                return 0;
        }
 
+       node = rb_first(&block_group->free_space_offset);
+       if (!node) {
+               iput(inode);
+               return 0;
+       }
+
        last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT;
        filemap_write_and_wait(inode->i_mapping);
        btrfs_wait_ordered_range(inode, inode->i_size &
@@ -543,10 +549,6 @@ int btrfs_write_out_cache(struct btrfs_root *root,
         */
        first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64);
 
-       node = rb_first(&block_group->free_space_offset);
-       if (!node)
-               goto out_free;
-
        /*
         * Lock all pages first so we can lock the extent safely.
         *
index 8039390bd6a6f7bc1d1026d917dcaeb93aa067e6..72f31ecb5c90085a2d6adfdc9b690ee038bf508f 100644 (file)
@@ -495,7 +495,7 @@ again:
                add_async_extent(async_cow, start, num_bytes,
                                 total_compressed, pages, nr_pages_ret);
 
-               if (start + num_bytes < end && start + num_bytes < actual_end) {
+               if (start + num_bytes < end) {
                        start += num_bytes;
                        pages = NULL;
                        cond_resched();
@@ -5712,9 +5712,9 @@ static void btrfs_end_dio_bio(struct bio *bio, int err)
 
        if (err) {
                printk(KERN_ERR "btrfs direct IO failed ino %lu rw %lu "
-                     "disk_bytenr %lu len %u err no %d\n",
-                     dip->inode->i_ino, bio->bi_rw, bio->bi_sector,
-                     bio->bi_size, err);
+                     "sector %#Lx len %u err no %d\n",
+                     dip->inode->i_ino, bio->bi_rw,
+                     (unsigned long long)bio->bi_sector, bio->bi_size, err);
                dip->errors = 1;
 
                /*
@@ -5934,8 +5934,7 @@ free_ordered:
         */
        if (write) {
                struct btrfs_ordered_extent *ordered;
-               ordered = btrfs_lookup_ordered_extent(inode,
-                                                     dip->logical_offset);
+               ordered = btrfs_lookup_ordered_extent(inode, file_offset);
                if (!test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags) &&
                    !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags))
                        btrfs_free_reserved_extent(root, ordered->start,
index f1c9bb4079ed8b3aaf2a01bb5211923f8e231986..f87552a1d7ea0beeb540aa59ddac3754242304cc 100644 (file)
@@ -947,23 +947,42 @@ out:
 
 static noinline int btrfs_ioctl_snap_create(struct file *file,
                                            void __user *arg, int subvol,
-                                           int async)
+                                           int v2)
 {
        struct btrfs_ioctl_vol_args *vol_args = NULL;
-       struct btrfs_ioctl_async_vol_args *async_vol_args = NULL;
+       struct btrfs_ioctl_vol_args_v2 *vol_args_v2 = NULL;
        char *name;
        u64 fd;
-       u64 transid = 0;
        int ret;
 
-       if (async) {
-               async_vol_args = memdup_user(arg, sizeof(*async_vol_args));
-               if (IS_ERR(async_vol_args))
-                       return PTR_ERR(async_vol_args);
+       if (v2) {
+               u64 transid = 0;
+               u64 *ptr = NULL;
 
-               name = async_vol_args->name;
-               fd = async_vol_args->fd;
-               async_vol_args->name[BTRFS_SNAPSHOT_NAME_MAX] = '\0';
+               vol_args_v2 = memdup_user(arg, sizeof(*vol_args_v2));
+               if (IS_ERR(vol_args_v2))
+                       return PTR_ERR(vol_args_v2);
+
+               if (vol_args_v2->flags & ~BTRFS_SUBVOL_CREATE_ASYNC) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               name = vol_args_v2->name;
+               fd = vol_args_v2->fd;
+               vol_args_v2->name[BTRFS_SUBVOL_NAME_MAX] = '\0';
+
+               if (vol_args_v2->flags & BTRFS_SUBVOL_CREATE_ASYNC)
+                       ptr = &transid;
+
+               ret = btrfs_ioctl_snap_create_transid(file, name, fd,
+                                                     subvol, ptr);
+
+               if (ret == 0 && ptr &&
+                   copy_to_user(arg +
+                                offsetof(struct btrfs_ioctl_vol_args_v2,
+                                         transid), ptr, sizeof(*ptr)))
+                       ret = -EFAULT;
        } else {
                vol_args = memdup_user(arg, sizeof(*vol_args));
                if (IS_ERR(vol_args))
@@ -971,20 +990,13 @@ static noinline int btrfs_ioctl_snap_create(struct file *file,
                name = vol_args->name;
                fd = vol_args->fd;
                vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
-       }
-
-       ret = btrfs_ioctl_snap_create_transid(file, name, fd,
-                                             subvol, &transid);
 
-       if (!ret && async) {
-               if (copy_to_user(arg +
-                               offsetof(struct btrfs_ioctl_async_vol_args,
-                               transid), &transid, sizeof(transid)))
-                       return -EFAULT;
+               ret = btrfs_ioctl_snap_create_transid(file, name, fd,
+                                                     subvol, NULL);
        }
-
+out:
        kfree(vol_args);
-       kfree(async_vol_args);
+       kfree(vol_args_v2);
 
        return ret;
 }
@@ -2246,7 +2258,7 @@ long btrfs_ioctl(struct file *file, unsigned int
                return btrfs_ioctl_getversion(file, argp);
        case BTRFS_IOC_SNAP_CREATE:
                return btrfs_ioctl_snap_create(file, argp, 0, 0);
-       case BTRFS_IOC_SNAP_CREATE_ASYNC:
+       case BTRFS_IOC_SNAP_CREATE_V2:
                return btrfs_ioctl_snap_create(file, argp, 0, 1);
        case BTRFS_IOC_SUBVOL_CREATE:
                return btrfs_ioctl_snap_create(file, argp, 1, 0);
index 17c99ebdf96049a8ad028cd6e138355df86f0c9e..c344d12c646bf7d1cbb953f8c4aba6257b6db8b9 100644 (file)
@@ -30,11 +30,15 @@ struct btrfs_ioctl_vol_args {
        char name[BTRFS_PATH_NAME_MAX + 1];
 };
 
-#define BTRFS_SNAPSHOT_NAME_MAX 4079
-struct btrfs_ioctl_async_vol_args {
+#define BTRFS_SUBVOL_CREATE_ASYNC      (1ULL << 0)
+
+#define BTRFS_SUBVOL_NAME_MAX 4039
+struct btrfs_ioctl_vol_args_v2 {
        __s64 fd;
        __u64 transid;
-       char name[BTRFS_SNAPSHOT_NAME_MAX + 1];
+       __u64 flags;
+       __u64 unused[4];
+       char name[BTRFS_SUBVOL_NAME_MAX + 1];
 };
 
 #define BTRFS_INO_LOOKUP_PATH_MAX 4080
@@ -187,6 +191,6 @@ struct btrfs_ioctl_space_args {
                                    struct btrfs_ioctl_space_args)
 #define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64)
 #define BTRFS_IOC_WAIT_SYNC  _IOW(BTRFS_IOCTL_MAGIC, 22, __u64)
-#define BTRFS_IOC_SNAP_CREATE_ASYNC _IOW(BTRFS_IOCTL_MAGIC, 23, \
-                                  struct btrfs_ioctl_async_vol_args)
+#define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \
+                                  struct btrfs_ioctl_vol_args_v2)
 #endif
index 79cba5fbc28ef8061e2d599110a3a525216a7bfd..f8be250963a09a283b8ec4ab04bcb1c3a962427e 100644 (file)
@@ -56,8 +56,12 @@ int btrfs_del_orphan_item(struct btrfs_trans_handle *trans,
                return -ENOMEM;
 
        ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
-       if (ret)
+       if (ret < 0)
                goto out;
+       if (ret) {
+               ret = -ENOENT;
+               goto out;
+       }
 
        ret = btrfs_del_item(trans, root, path);
 
index dbb51ea7a13c4b83e46c6c1f03d8d936cf75bed7..883c6fa1367eb866002d7f67d3ae2ce6497f4367 100644 (file)
@@ -685,9 +685,9 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
                mutex_unlock(&root->d_inode->i_mutex);
 
                if (IS_ERR(new_root)) {
+                       dput(root);
                        deactivate_locked_super(s);
                        error = PTR_ERR(new_root);
-                       dput(root);
                        goto error_free_subvol_name;
                }
                if (!new_root->d_inode) {
index cc04dc1445d64da8694401c2cbc2fde27105b8f9..6b9884507837581ba6231bc6c4cfb85a036b82f6 100644 (file)
@@ -412,12 +412,16 @@ static noinline int device_list_add(const char *path,
 
                device->fs_devices = fs_devices;
                fs_devices->num_devices++;
-       } else if (strcmp(device->name, path)) {
+       } else if (!device->name || strcmp(device->name, path)) {
                name = kstrdup(path, GFP_NOFS);
                if (!name)
                        return -ENOMEM;
                kfree(device->name);
                device->name = name;
+               if (device->missing) {
+                       fs_devices->missing_devices--;
+                       device->missing = 0;
+               }
        }
 
        if (found_transid > fs_devices->latest_trans) {
@@ -1236,6 +1240,9 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
 
        device->fs_devices->num_devices--;
 
+       if (device->missing)
+               root->fs_info->fs_devices->missing_devices--;
+
        next_device = list_entry(root->fs_info->fs_devices->devices.next,
                                 struct btrfs_device, dev_list);
        if (device->bdev == root->fs_info->sb->s_bdev)
@@ -3080,7 +3087,9 @@ static struct btrfs_device *add_missing_dev(struct btrfs_root *root,
        device->devid = devid;
        device->work.func = pending_bios_fn;
        device->fs_devices = fs_devices;
+       device->missing = 1;
        fs_devices->num_devices++;
+       fs_devices->missing_devices++;
        spin_lock_init(&device->io_lock);
        INIT_LIST_HEAD(&device->dev_alloc_list);
        memcpy(device->uuid, dev_uuid, BTRFS_UUID_SIZE);
@@ -3278,6 +3287,15 @@ static int read_one_dev(struct btrfs_root *root,
                        device = add_missing_dev(root, devid, dev_uuid);
                        if (!device)
                                return -ENOMEM;
+               } else if (!device->missing) {
+                       /*
+                        * this happens when a device that was properly setup
+                        * in the device info lists suddenly goes bad.
+                        * device->bdev is NULL, and so we have to set
+                        * device->missing to one here
+                        */
+                       root->fs_info->fs_devices->missing_devices++;
+                       device->missing = 1;
                }
        }
 
index 2b638b6e4eeae7cb9428490a897c1e10a9aaad1f..2740db49eb04d7a8de03d18e5935a97ff43ef9db 100644 (file)
@@ -44,6 +44,7 @@ struct btrfs_device {
 
        int writeable;
        int in_fs_metadata;
+       int missing;
 
        spinlock_t io_lock;
 
@@ -93,6 +94,7 @@ struct btrfs_fs_devices {
        u64 num_devices;
        u64 open_devices;
        u64 rw_devices;
+       u64 missing_devices;
        u64 total_rw_bytes;
        struct block_device *latest_bdev;
 
index 7d447af84ec4861acee8cd82bcecf80a892132b1..158c700fdca5e4f62763377a8374217d6371b68b 100644 (file)
@@ -114,8 +114,8 @@ static int __dcache_readdir(struct file *filp,
        spin_lock(&dcache_lock);
 
        /* start at beginning? */
-       if (filp->f_pos == 2 || (last &&
-                                filp->f_pos < ceph_dentry(last)->offset)) {
+       if (filp->f_pos == 2 || last == NULL ||
+           filp->f_pos < ceph_dentry(last)->offset) {
                if (list_empty(&parent->d_subdirs))
                        goto out_unlock;
                p = parent->d_subdirs.prev;
index a6ce54e94eb5ab435670093cd6ad789e72cc627b..52e8fd74d450b9e2895eb7c29d80e38b77eb0807 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/ioctl.h>
 #include <linux/types.h>
 
-#define CEPH_IOCTL_MAGIC 0x98
+#define CEPH_IOCTL_MAGIC 0x97
 
 /* just use u64 to align sanely on all archs */
 struct ceph_ioctl_layout {
index 40abde93c345d054279fd51cbca998525c4931c7..476b329867d41cf2cec7b3e2ad51e5f3885d9d7a 100644 (file)
  * Implement fcntl and flock locking functions.
  */
 static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
-                            u64 pid, u64 pid_ns,
-                            int cmd, u64 start, u64 length, u8 wait)
+                            int cmd, u8 wait, struct file_lock *fl)
 {
        struct inode *inode = file->f_dentry->d_inode;
        struct ceph_mds_client *mdsc =
                ceph_sb_to_client(inode->i_sb)->mdsc;
        struct ceph_mds_request *req;
        int err;
+       u64 length = 0;
 
        req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS);
        if (IS_ERR(req))
                return PTR_ERR(req);
        req->r_inode = igrab(inode);
 
+       /* mds requires start and length rather than start and end */
+       if (LLONG_MAX == fl->fl_end)
+               length = 0;
+       else
+               length = fl->fl_end - fl->fl_start + 1;
+
        dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, "
             "length: %llu, wait: %d, type`: %d", (int)lock_type,
-            (int)operation, pid, start, length, wait, cmd);
+            (int)operation, (u64)fl->fl_pid, fl->fl_start,
+            length, wait, fl->fl_type);
+
 
        req->r_args.filelock_change.rule = lock_type;
        req->r_args.filelock_change.type = cmd;
-       req->r_args.filelock_change.pid = cpu_to_le64(pid);
+       req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid);
        /* This should be adjusted, but I'm not sure if
           namespaces actually get id numbers*/
        req->r_args.filelock_change.pid_namespace =
-               cpu_to_le64((u64)pid_ns);
-       req->r_args.filelock_change.start = cpu_to_le64(start);
+               cpu_to_le64((u64)(unsigned long)fl->fl_nspid);
+       req->r_args.filelock_change.start = cpu_to_le64(fl->fl_start);
        req->r_args.filelock_change.length = cpu_to_le64(length);
        req->r_args.filelock_change.wait = wait;
 
        err = ceph_mdsc_do_request(mdsc, inode, req);
+
+       if ( operation == CEPH_MDS_OP_GETFILELOCK){
+               fl->fl_pid = le64_to_cpu(req->r_reply_info.filelock_reply->pid);
+               if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type)
+                       fl->fl_type = F_RDLCK;
+               else if (CEPH_LOCK_EXCL == req->r_reply_info.filelock_reply->type)
+                       fl->fl_type = F_WRLCK;
+               else
+                       fl->fl_type = F_UNLCK;
+
+               fl->fl_start = le64_to_cpu(req->r_reply_info.filelock_reply->start);
+               length = le64_to_cpu(req->r_reply_info.filelock_reply->start) +
+                                                le64_to_cpu(req->r_reply_info.filelock_reply->length);
+               if (length >= 1)
+                       fl->fl_end = length -1;
+               else
+                       fl->fl_end = 0;
+
+       }
        ceph_mdsc_put_request(req);
        dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, "
-            "length: %llu, wait: %d, type`: %d err code %d", (int)lock_type,
-            (int)operation, pid, start, length, wait, cmd, err);
+            "length: %llu, wait: %d, type`: %d, err code %d", (int)lock_type,
+            (int)operation, (u64)fl->fl_pid, fl->fl_start,
+            length, wait, fl->fl_type, err);
        return err;
 }
 
@@ -54,7 +82,6 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file,
  */
 int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
 {
-       u64 length;
        u8 lock_cmd;
        int err;
        u8 wait = 0;
@@ -76,29 +103,20 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
        else
                lock_cmd = CEPH_LOCK_UNLOCK;
 
-       if (LLONG_MAX == fl->fl_end)
-               length = 0;
-       else
-               length = fl->fl_end - fl->fl_start + 1;
-
-       err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
-                               (u64)fl->fl_pid,
-                               (u64)(unsigned long)fl->fl_nspid,
-                               lock_cmd, fl->fl_start,
-                               length, wait);
+       err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, lock_cmd, wait, fl);
        if (!err) {
-               dout("mds locked, locking locally");
-               err = posix_lock_file(file, fl, NULL);
-               if (err && (CEPH_MDS_OP_SETFILELOCK == op)) {
-                       /* undo! This should only happen if the kernel detects
-                        * local deadlock. */
-                       ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
-                                         (u64)fl->fl_pid,
-                                         (u64)(unsigned long)fl->fl_nspid,
-                                         CEPH_LOCK_UNLOCK, fl->fl_start,
-                                         length, 0);
-                       dout("got %d on posix_lock_file, undid lock", err);
+               if ( op != CEPH_MDS_OP_GETFILELOCK ){
+                       dout("mds locked, locking locally");
+                       err = posix_lock_file(file, fl, NULL);
+                       if (err && (CEPH_MDS_OP_SETFILELOCK == op)) {
+                               /* undo! This should only happen if the kernel detects
+                                * local deadlock. */
+                               ceph_lock_message(CEPH_LOCK_FCNTL, op, file,
+                                                 CEPH_LOCK_UNLOCK, 0, fl);
+                               dout("got %d on posix_lock_file, undid lock", err);
+                       }
                }
+
        } else {
                dout("mds returned error code %d", err);
        }
@@ -107,7 +125,6 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
 
 int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
 {
-       u64 length;
        u8 lock_cmd;
        int err;
        u8 wait = 1;
@@ -127,26 +144,15 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
                lock_cmd = CEPH_LOCK_EXCL;
        else
                lock_cmd = CEPH_LOCK_UNLOCK;
-       /* mds requires start and length rather than start and end */
-       if (LLONG_MAX == fl->fl_end)
-               length = 0;
-       else
-               length = fl->fl_end - fl->fl_start + 1;
 
        err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK,
-                               file, (u64)fl->fl_pid,
-                               (u64)(unsigned long)fl->fl_nspid,
-                               lock_cmd, fl->fl_start,
-                               length, wait);
+                               file, lock_cmd, wait, fl);
        if (!err) {
                err = flock_lock_file_wait(file, fl);
                if (err) {
                        ceph_lock_message(CEPH_LOCK_FLOCK,
                                          CEPH_MDS_OP_SETFILELOCK,
-                                         file, (u64)fl->fl_pid,
-                                         (u64)(unsigned long)fl->fl_nspid,
-                                         CEPH_LOCK_UNLOCK, fl->fl_start,
-                                         length, 0);
+                                         file, CEPH_LOCK_UNLOCK, 0, fl);
                        dout("got %d on flock_lock_file_wait, undid lock", err);
                }
        } else {
index 098b185084791730ba0143111126bc066fdb9afb..38800eaa81d066bd8f06a401d082ecd3bb3f6fea 100644 (file)
@@ -201,6 +201,38 @@ out_bad:
        return err;
 }
 
+/*
+ * parse fcntl F_GETLK results
+ */
+static int parse_reply_info_filelock(void **p, void *end,
+                struct ceph_mds_reply_info_parsed *info)
+{
+       if (*p + sizeof(*info->filelock_reply) > end)
+               goto bad;
+
+       info->filelock_reply = *p;
+       *p += sizeof(*info->filelock_reply);
+
+       if (unlikely(*p != end))
+               goto bad;
+       return 0;
+
+bad:
+       return -EIO;
+}
+
+/*
+ * parse extra results
+ */
+static int parse_reply_info_extra(void **p, void *end,
+                struct ceph_mds_reply_info_parsed *info)
+{
+       if (info->head->op == CEPH_MDS_OP_GETFILELOCK)
+               return parse_reply_info_filelock(p, end, info);
+       else
+               return parse_reply_info_dir(p, end, info);
+}
+
 /*
  * parse entire mds reply
  */
@@ -223,10 +255,10 @@ static int parse_reply_info(struct ceph_msg *msg,
                        goto out_bad;
        }
 
-       /* dir content */
+       /* extra */
        ceph_decode_32_safe(&p, end, len, bad);
        if (len > 0) {
-               err = parse_reply_info_dir(&p, p+len, info);
+               err = parse_reply_info_extra(&p, p+len, info);
                if (err < 0)
                        goto out_bad;
        }
@@ -2074,7 +2106,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
 
        mutex_lock(&session->s_mutex);
        if (err < 0) {
-               pr_err("mdsc_handle_reply got corrupt reply mds%d\n", mds);
+               pr_err("mdsc_handle_reply got corrupt reply mds%d(tid:%lld)\n", mds, tid);
                ceph_msg_dump(msg);
                goto out_err;
        }
@@ -2094,7 +2126,8 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
        mutex_lock(&req->r_fill_mutex);
        err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session);
        if (err == 0) {
-               if (result == 0 && rinfo->dir_nr)
+               if (result == 0 && req->r_op != CEPH_MDS_OP_GETFILELOCK &&
+                   rinfo->dir_nr)
                        ceph_readdir_prepopulate(req, req->r_session);
                ceph_unreserve_caps(mdsc, &req->r_caps_reservation);
        }
index 9341fd4f14320060a395c37f81b4a67b01c020d7..aabe563b54db308af80ee9fff18dd81610a9cf94 100644 (file)
@@ -42,26 +42,37 @@ struct ceph_mds_reply_info_in {
 };
 
 /*
- * parsed info about an mds reply, including information about the
- * target inode and/or its parent directory and dentry, and directory
- * contents (for readdir results).
+ * parsed info about an mds reply, including information about
+ * either: 1) the target inode and/or its parent directory and dentry,
+ * and directory contents (for readdir results), or
+ * 2) the file range lock info (for fcntl F_GETLK results).
  */
 struct ceph_mds_reply_info_parsed {
        struct ceph_mds_reply_head    *head;
 
+       /* trace */
        struct ceph_mds_reply_info_in diri, targeti;
        struct ceph_mds_reply_dirfrag *dirfrag;
        char                          *dname;
        u32                           dname_len;
        struct ceph_mds_reply_lease   *dlease;
 
-       struct ceph_mds_reply_dirfrag *dir_dir;
-       int                           dir_nr;
-       char                          **dir_dname;
-       u32                           *dir_dname_len;
-       struct ceph_mds_reply_lease   **dir_dlease;
-       struct ceph_mds_reply_info_in *dir_in;
-       u8                            dir_complete, dir_end;
+       /* extra */
+       union {
+               /* for fcntl F_GETLK results */
+               struct ceph_filelock *filelock_reply;
+
+               /* for readdir results */
+               struct {
+                       struct ceph_mds_reply_dirfrag *dir_dir;
+                       int                           dir_nr;
+                       char                          **dir_dname;
+                       u32                           *dir_dname_len;
+                       struct ceph_mds_reply_lease   **dir_dlease;
+                       struct ceph_mds_reply_info_in *dir_in;
+                       u8                            dir_complete, dir_end;
+               };
+       };
 
        /* encoded blob describing snapshot contexts for certain
           operations (e.g., open) */
index adefa60a9bdc10108ec9c802e4cbe1ea26f3f6e0..43b19dd391912476c395ffbabaaabbacc28d0146 100644 (file)
@@ -6,7 +6,9 @@ obj-$(CONFIG_CIFS) += cifs.o
 cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
          link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \
          md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \
-         readdir.o ioctl.o sess.o export.o cifsacl.o
+         readdir.o ioctl.o sess.o export.o
+
+cifs-$(CONFIG_CIFS_ACL) += cifsacl.o
 
 cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
 
index ee68d1036544d591930af8119d5e7450634adfff..46af99ab3614d545675e41e788686b39fd51204b 100644 (file)
@@ -337,6 +337,15 @@ A partial list of the supported mount options follows:
   wsize                default write size (default 57344)
                maximum wsize currently allowed by CIFS is 57344 (fourteen
                4096 byte pages)
+  actimeo=n    attribute cache timeout in seconds (default 1 second).
+               After this timeout, the cifs client requests fresh attribute
+               information from the server. This option allows to tune the
+               attribute cache timeout to suit the workload needs. Shorter
+               timeouts mean better the cache coherency, but increased number
+               of calls to the server. Longer timeouts mean reduced number
+               of calls to the server at the expense of less stricter cache
+               coherency checks (i.e. incorrect attribute cache for a short
+               period of time).
   rw           mount the network share read-write (note that the
                server may still consider the share read-only)
   ro           mount network share read-only
index e9a393c9c2ca4ddb8ec3d75cfcf0766234ec1789..7852cd6770517a8a5da7877fb788a834a0534c86 100644 (file)
@@ -48,6 +48,7 @@ struct cifs_sb_info {
        struct nls_table *local_nls;
        unsigned int rsize;
        unsigned int wsize;
+       unsigned long actimeo; /* attribute cache timeout (jiffies) */
        atomic_t active;
        uid_t   mnt_uid;
        gid_t   mnt_gid;
index c6ebea088ac7c2bf6d01d3ac02910f0164a4b4b3..a437ec391a015fb7c05725543d6c118eadefc466 100644 (file)
@@ -30,8 +30,6 @@
 #include "cifs_debug.h"
 
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-
 static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
        {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
        {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
@@ -774,4 +772,3 @@ int mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode)
 
        return rc;
 }
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
index 6c8096cf51557764aa10af6c28d108d3e93ce6e7..c4ae7d0365631f5d01db610ef3153502f2531c9d 100644 (file)
@@ -74,11 +74,7 @@ struct cifs_wksid {
        char sidname[SIDNAMELENGTH];
 } __attribute__((packed));
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-
 extern int match_sid(struct cifs_sid *);
 extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *);
 
-#endif /*  CONFIG_CIFS_EXPERIMENTAL */
-
 #endif /* _CIFSACL_H */
index 76c8a906a63eee2369123f0ea1f433ad58692b1e..3936aa7f2c2285cfb59857f8fe1925528920543a 100644 (file)
@@ -463,6 +463,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
 
        seq_printf(s, ",rsize=%d", cifs_sb->rsize);
        seq_printf(s, ",wsize=%d", cifs_sb->wsize);
+       /* convert actimeo and display it in seconds */
+               seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
 
        return 0;
 }
@@ -935,7 +937,6 @@ init_cifs(void)
        GlobalCurrentXid = 0;
        GlobalTotalActiveXid = 0;
        GlobalMaxActiveXid = 0;
-       memset(Local_System_Name, 0, 15);
        spin_lock_init(&cifs_tcp_ses_lock);
        spin_lock_init(&cifs_file_list_lock);
        spin_lock_init(&GlobalMid_Lock);
index b577bf0a1bb3622491ed0a885ca30b9e7684d24e..7136c0c3e2f961ec2c57d882163a1ffbc0e50ef1 100644 (file)
 
 #define CIFS_MIN_RCV_POOL 4
 
+/*
+ * default attribute cache timeout (jiffies)
+ */
+#define CIFS_DEF_ACTIMEO (1 * HZ)
+
+/*
+ * max attribute cache timeout (jiffies) - 2^30
+ */
+#define CIFS_MAX_ACTIMEO (1 << 30)
+
 /*
  * MAX_REQ is the maximum number of requests that WE will send
  * on one socket concurrently. It also matches the most common
@@ -746,8 +756,6 @@ GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */
 GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */
 GLOBAL_EXTERN spinlock_t GlobalMid_Lock;  /* protects above & list operations */
                                          /* on midQ entries */
-GLOBAL_EXTERN char Local_System_Name[15];
-
 /*
  *  Global counters, updated atomically
  */
index db961dc4fd3d30b4bbdf15924c1e58fded05b10e..e6d1481b16c1403cbe1c7fcae04e11abcc3f91f9 100644 (file)
@@ -54,7 +54,8 @@ do {                                                          \
             __func__, curr_xid, (int)rc);                      \
 } while (0)
 extern char *build_path_from_dentry(struct dentry *);
-extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb);
+extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
+                                       struct cifsTconInfo *tcon);
 extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
 extern char *cifs_compose_mount_options(const char *sb_mountdata,
                const char *fullpath, const struct dfs_info3_param *ref,
@@ -79,9 +80,7 @@ extern bool is_valid_oplock_break(struct smb_hdr *smb,
                                  struct TCP_Server_Info *);
 extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
-#endif
 extern unsigned int smbCalcSize(struct smb_hdr *ptr);
 extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
 extern int decode_negTokenInit(unsigned char *security_blob, int length,
index 2f2632b6df5a1efd960bf44502d280e0e9499908..67acfb3acad271a51be1a1446d4f9828119e6b39 100644 (file)
@@ -2478,95 +2478,6 @@ querySymLinkRetry:
 }
 
 #ifdef CONFIG_CIFS_EXPERIMENTAL
-/* Initialize NT TRANSACT SMB into small smb request buffer.
-   This assumes that all NT TRANSACTS that we init here have
-   total parm and data under about 400 bytes (to fit in small cifs
-   buffer size), which is the case so far, it easily fits. NB:
-       Setup words themselves and ByteCount
-       MaxSetupCount (size of returned setup area) and
-       MaxParameterCount (returned parms size) must be set by caller */
-static int
-smb_init_nttransact(const __u16 sub_command, const int setup_count,
-                  const int parm_len, struct cifsTconInfo *tcon,
-                  void **ret_buf)
-{
-       int rc;
-       __u32 temp_offset;
-       struct smb_com_ntransact_req *pSMB;
-
-       rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
-                               (void **)&pSMB);
-       if (rc)
-               return rc;
-       *ret_buf = (void *)pSMB;
-       pSMB->Reserved = 0;
-       pSMB->TotalParameterCount = cpu_to_le32(parm_len);
-       pSMB->TotalDataCount  = 0;
-       pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
-                                         MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
-       pSMB->ParameterCount = pSMB->TotalParameterCount;
-       pSMB->DataCount  = pSMB->TotalDataCount;
-       temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
-                       (setup_count * 2) - 4 /* for rfc1001 length itself */;
-       pSMB->ParameterOffset = cpu_to_le32(temp_offset);
-       pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
-       pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
-       pSMB->SubCommand = cpu_to_le16(sub_command);
-       return 0;
-}
-
-static int
-validate_ntransact(char *buf, char **ppparm, char **ppdata,
-                  __u32 *pparmlen, __u32 *pdatalen)
-{
-       char *end_of_smb;
-       __u32 data_count, data_offset, parm_count, parm_offset;
-       struct smb_com_ntransact_rsp *pSMBr;
-
-       *pdatalen = 0;
-       *pparmlen = 0;
-
-       if (buf == NULL)
-               return -EINVAL;
-
-       pSMBr = (struct smb_com_ntransact_rsp *)buf;
-
-       /* ByteCount was converted from little endian in SendReceive */
-       end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
-                       (char *)&pSMBr->ByteCount;
-
-       data_offset = le32_to_cpu(pSMBr->DataOffset);
-       data_count = le32_to_cpu(pSMBr->DataCount);
-       parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
-       parm_count = le32_to_cpu(pSMBr->ParameterCount);
-
-       *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
-       *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
-
-       /* should we also check that parm and data areas do not overlap? */
-       if (*ppparm > end_of_smb) {
-               cFYI(1, "parms start after end of smb");
-               return -EINVAL;
-       } else if (parm_count + *ppparm > end_of_smb) {
-               cFYI(1, "parm end after end of smb");
-               return -EINVAL;
-       } else if (*ppdata > end_of_smb) {
-               cFYI(1, "data starts after end of smb");
-               return -EINVAL;
-       } else if (data_count + *ppdata > end_of_smb) {
-               cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
-                       *ppdata, data_count, (data_count + *ppdata),
-                       end_of_smb, pSMBr);
-               return -EINVAL;
-       } else if (parm_count + data_count > pSMBr->ByteCount) {
-               cFYI(1, "parm count and data count larger than SMB");
-               return -EINVAL;
-       }
-       *pdatalen = data_count;
-       *pparmlen = parm_count;
-       return 0;
-}
-
 int
 CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
                        const unsigned char *searchName,
@@ -3056,7 +2967,97 @@ GetExtAttrOut:
 
 #endif /* CONFIG_POSIX */
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CONFIG_CIFS_ACL
+/*
+ * Initialize NT TRANSACT SMB into small smb request buffer.  This assumes that
+ * all NT TRANSACTS that we init here have total parm and data under about 400
+ * bytes (to fit in small cifs buffer size), which is the case so far, it
+ * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
+ * returned setup area) and MaxParameterCount (returned parms size) must be set
+ * by caller
+ */
+static int
+smb_init_nttransact(const __u16 sub_command, const int setup_count,
+                  const int parm_len, struct cifsTconInfo *tcon,
+                  void **ret_buf)
+{
+       int rc;
+       __u32 temp_offset;
+       struct smb_com_ntransact_req *pSMB;
+
+       rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
+                               (void **)&pSMB);
+       if (rc)
+               return rc;
+       *ret_buf = (void *)pSMB;
+       pSMB->Reserved = 0;
+       pSMB->TotalParameterCount = cpu_to_le32(parm_len);
+       pSMB->TotalDataCount  = 0;
+       pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
+                                         MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
+       pSMB->ParameterCount = pSMB->TotalParameterCount;
+       pSMB->DataCount  = pSMB->TotalDataCount;
+       temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
+                       (setup_count * 2) - 4 /* for rfc1001 length itself */;
+       pSMB->ParameterOffset = cpu_to_le32(temp_offset);
+       pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
+       pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
+       pSMB->SubCommand = cpu_to_le16(sub_command);
+       return 0;
+}
+
+static int
+validate_ntransact(char *buf, char **ppparm, char **ppdata,
+                  __u32 *pparmlen, __u32 *pdatalen)
+{
+       char *end_of_smb;
+       __u32 data_count, data_offset, parm_count, parm_offset;
+       struct smb_com_ntransact_rsp *pSMBr;
+
+       *pdatalen = 0;
+       *pparmlen = 0;
+
+       if (buf == NULL)
+               return -EINVAL;
+
+       pSMBr = (struct smb_com_ntransact_rsp *)buf;
+
+       /* ByteCount was converted from little endian in SendReceive */
+       end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
+                       (char *)&pSMBr->ByteCount;
+
+       data_offset = le32_to_cpu(pSMBr->DataOffset);
+       data_count = le32_to_cpu(pSMBr->DataCount);
+       parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
+       parm_count = le32_to_cpu(pSMBr->ParameterCount);
+
+       *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
+       *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
+
+       /* should we also check that parm and data areas do not overlap? */
+       if (*ppparm > end_of_smb) {
+               cFYI(1, "parms start after end of smb");
+               return -EINVAL;
+       } else if (parm_count + *ppparm > end_of_smb) {
+               cFYI(1, "parm end after end of smb");
+               return -EINVAL;
+       } else if (*ppdata > end_of_smb) {
+               cFYI(1, "data starts after end of smb");
+               return -EINVAL;
+       } else if (data_count + *ppdata > end_of_smb) {
+               cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
+                       *ppdata, data_count, (data_count + *ppdata),
+                       end_of_smb, pSMBr);
+               return -EINVAL;
+       } else if (parm_count + data_count > pSMBr->ByteCount) {
+               cFYI(1, "parm count and data count larger than SMB");
+               return -EINVAL;
+       }
+       *pdatalen = data_count;
+       *pparmlen = parm_count;
+       return 0;
+}
+
 /* Get Security Descriptor (by handle) from remote server for a file or dir */
 int
 CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
@@ -3214,7 +3215,7 @@ setCifsAclRetry:
        return (rc);
 }
 
-#endif /* CONFIG_CIFS_EXPERIMENTAL */
+#endif /* CONFIG_CIFS_ACL */
 
 /* Legacy Query Path Information call for lookup to old servers such
    as Win9x/WinME */
index 32fa4d9b5dbc11537dfc09653215a9540668e109..cc1a8604a790b46767e066a59ef897f314144163 100644 (file)
@@ -105,6 +105,7 @@ struct smb_vol {
        unsigned int wsize;
        bool sockopt_tcp_nodelay:1;
        unsigned short int port;
+       unsigned long actimeo; /* attribute cache timeout (jiffies) */
        char *prepath;
        struct sockaddr_storage srcaddr; /* allow binding to a local IP */
        struct nls_table *local_nls;
@@ -806,23 +807,20 @@ cifs_parse_mount_options(char *options, const char *devname,
        short int override_gid = -1;
        bool uid_specified = false;
        bool gid_specified = false;
+       char *nodename = utsname()->nodename;
 
        separator[0] = ',';
        separator[1] = 0;
 
-       if (Local_System_Name[0] != 0)
-               memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
-       else {
-               char *nodename = utsname()->nodename;
-               int n = strnlen(nodename, 15);
-               memset(vol->source_rfc1001_name, 0x20, 15);
-               for (i = 0; i < n; i++) {
-                       /* does not have to be perfect mapping since field is
-                       informational, only used for servers that do not support
-                       port 445 and it can be overridden at mount time */
-                       vol->source_rfc1001_name[i] = toupper(nodename[i]);
-               }
-       }
+       /*
+        * does not have to be perfect mapping since field is
+        * informational, only used for servers that do not support
+        * port 445 and it can be overridden at mount time
+        */
+       memset(vol->source_rfc1001_name, 0x20, 15);
+       for (i = 0; i < strnlen(nodename, 15); i++)
+               vol->source_rfc1001_name[i] = toupper(nodename[i]);
+
        vol->source_rfc1001_name[15] = 0;
        /* null target name indicates to use *SMBSERVR default called name
           if we end up sending RFC1001 session initialize */
@@ -840,6 +838,8 @@ cifs_parse_mount_options(char *options, const char *devname,
        /* default to using server inode numbers where available */
        vol->server_ino = 1;
 
+       vol->actimeo = CIFS_DEF_ACTIMEO;
+
        if (!options)
                return 1;
 
@@ -1214,6 +1214,16 @@ cifs_parse_mount_options(char *options, const char *devname,
                                        printk(KERN_WARNING "CIFS: server net"
                                        "biosname longer than 15 truncated.\n");
                        }
+               } else if (strnicmp(data, "actimeo", 7) == 0) {
+                       if (value && *value) {
+                               vol->actimeo = HZ * simple_strtoul(value,
+                                                                  &value, 0);
+                               if (vol->actimeo > CIFS_MAX_ACTIMEO) {
+                                       cERROR(1, "CIFS: attribute cache"
+                                                       "timeout too large");
+                                       return 1;
+                               }
+                       }
                } else if (strnicmp(data, "credentials", 4) == 0) {
                        /* ignore */
                } else if (strnicmp(data, "version", 3) == 0) {
@@ -2571,6 +2581,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
        cFYI(1, "file mode: 0x%x  dir mode: 0x%x",
                cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
 
+       cifs_sb->actimeo = pvolume_info->actimeo;
+
        if (pvolume_info->noperm)
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
        if (pvolume_info->setuids)
@@ -2821,13 +2833,13 @@ remote_path_check:
        /* check if a whole path (including prepath) is not remote */
        if (!rc && cifs_sb->prepathlen && tcon) {
                /* build_path_to_root works only when we have a valid tcon */
-               full_path = cifs_build_path_to_root(cifs_sb);
+               full_path = cifs_build_path_to_root(cifs_sb, tcon);
                if (full_path == NULL) {
                        rc = -ENOMEM;
                        goto mount_fail_check;
                }
                rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
-               if (rc != -EREMOTE) {
+               if (rc != 0 && rc != -EREMOTE) {
                        kfree(full_path);
                        goto mount_fail_check;
                }
index b857ce5db7755143affed1224c778d34ddc77b99..5a28660ca2b5e619955c05d74d9d84b95a994a4b 100644 (file)
@@ -1108,7 +1108,6 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
        return total_written;
 }
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
                                        bool fsuid_only)
 {
@@ -1142,7 +1141,6 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
        spin_unlock(&cifs_file_list_lock);
        return NULL;
 }
-#endif
 
 struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
                                        bool fsuid_only)
index 28cb6e735943f935d3ed9408f34152ba35f100b7..589f3e3f6e0023b1f8b09f1e030119896117c94f 100644 (file)
@@ -686,7 +686,7 @@ int cifs_get_inode_info(struct inode **pinode,
                        cFYI(1, "cifs_sfu_type failed: %d", tmprc);
        }
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CONFIG_CIFS_ACL
        /* fill in 0777 bits from ACL */
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
                rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path,
@@ -697,7 +697,7 @@ int cifs_get_inode_info(struct inode **pinode,
                        goto cgii_exit;
                }
        }
-#endif
+#endif /* CONFIG_CIFS_ACL */
 
        /* fill in remaining high mode bits e.g. SUID, VTX */
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
@@ -728,12 +728,12 @@ static const struct inode_operations cifs_ipc_inode_ops = {
        .lookup = cifs_lookup,
 };
 
-char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
+char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
+                               struct cifsTconInfo *tcon)
 {
        int pplen = cifs_sb->prepathlen;
        int dfsplen;
        char *full_path = NULL;
-       struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
 
        /* if no prefix path, simply set path to the root of share to "" */
        if (pplen == 0) {
@@ -875,7 +875,7 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
        char *full_path;
        struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
 
-       full_path = cifs_build_path_to_root(cifs_sb);
+       full_path = cifs_build_path_to_root(cifs_sb, tcon);
        if (full_path == NULL)
                return ERR_PTR(-ENOMEM);
 
@@ -1653,6 +1653,7 @@ static bool
 cifs_inode_needs_reval(struct inode *inode)
 {
        struct cifsInodeInfo *cifs_i = CIFS_I(inode);
+       struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
 
        if (cifs_i->clientCanCacheRead)
                return false;
@@ -1663,12 +1664,12 @@ cifs_inode_needs_reval(struct inode *inode)
        if (cifs_i->time == 0)
                return true;
 
-       /* FIXME: the actimeo should be tunable */
-       if (time_after_eq(jiffies, cifs_i->time + HZ))
+       if (!time_in_range(jiffies, cifs_i->time,
+                               cifs_i->time + cifs_sb->actimeo))
                return true;
 
        /* hardlinked files w/ noserverino get "special" treatment */
-       if (!(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
+       if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
            S_ISREG(inode->i_mode) && inode->i_nlink != 1)
                return true;
 
@@ -2121,7 +2122,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
 
        if (attrs->ia_valid & ATTR_MODE) {
                rc = 0;
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CONFIG_CIFS_ACL
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
                        rc = mode_to_cifs_acl(inode, full_path, mode);
                        if (rc) {
@@ -2130,7 +2131,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
                                goto cifs_setattr_exit;
                        }
                } else
-#endif
+#endif /* CONFIG_CIFS_ACL */
                if (((mode & S_IWUGO) == 0) &&
                    (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
 
index 32d300e8f20eb4a6676b8da50187a4b04146fcb8..a73eb9f4bdaf3608c2bf6f5dc124b5fabdd4445b 100644 (file)
@@ -759,18 +759,6 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
        rc = filldir(direntry, qstring.name, qstring.len, file->f_pos,
                     ino, fattr.cf_dtype);
 
-       /*
-        * we can not return filldir errors to the caller since they are
-        * "normal" when the stat blocksize is too small - we return remapped
-        * error instead
-        *
-        * FIXME: This looks bogus. filldir returns -EOVERFLOW in the above
-        * case already. Why should we be clobbering other errors from it?
-        */
-       if (rc) {
-               cFYI(1, "filldir rc = %d", rc);
-               rc = -EOVERFLOW;
-       }
        dput(tmp_dentry);
        return rc;
 }
index d68c378a31375bfb848aaa887fb655a8b08ec080..c62efcb959c73fc458367d811c576e634fb49634 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -275,6 +275,11 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
        vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP;
        vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
        INIT_LIST_HEAD(&vma->anon_vma_chain);
+
+       err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
+       if (err)
+               goto err;
+
        err = insert_vm_struct(mm, vma);
        if (err)
                goto err;
index 6a5edea2d70b3ac7c56e8b272686b5a799eabbcf..94ce3d7a1c4b9fe83b42954d309c8ac93b284ff5 100644 (file)
@@ -910,6 +910,7 @@ struct ext4_inode_info {
 #define EXT4_MOUNT_JOURNAL_CHECKSUM    0x800000 /* Journal checksums */
 #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT        0x1000000 /* Journal Async Commit */
 #define EXT4_MOUNT_I_VERSION            0x2000000 /* i_version support */
+#define EXT4_MOUNT_MBLK_IO_SUBMIT      0x4000000 /* multi-block io submits */
 #define EXT4_MOUNT_DELALLOC            0x8000000 /* Delalloc support */
 #define EXT4_MOUNT_DATA_ERR_ABORT      0x10000000 /* Abort on file data write */
 #define EXT4_MOUNT_BLOCK_VALIDITY      0x20000000 /* Block validity checking */
index bdbe69902207c151df025d98690c4c016cf0b0e9..e659597b690b508e1325182de702031a73843f4d 100644 (file)
@@ -2125,9 +2125,12 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd,
                         */
                        if (unlikely(journal_data && PageChecked(page)))
                                err = __ext4_journalled_writepage(page, len);
-                       else
+                       else if (test_opt(inode->i_sb, MBLK_IO_SUBMIT))
                                err = ext4_bio_write_page(&io_submit, page,
                                                          len, mpd->wbc);
+                       else
+                               err = block_write_full_page(page,
+                                       noalloc_get_block_write, mpd->wbc);
 
                        if (!err)
                                mpd->pages_written++;
index 92203b8a099f076ebbc0d794b3356289096c663f..dc40e75cba8857e6068739646b4932bb315688fd 100644 (file)
@@ -872,7 +872,7 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
        if (namelen > EXT4_NAME_LEN)
                return NULL;
        if ((namelen <= 2) && (name[0] == '.') &&
-           (name[1] == '.' || name[1] == '0')) {
+           (name[1] == '.' || name[1] == '\0')) {
                /*
                 * "." or ".." will only be in the first block
                 * NFS may look up ".."; "." should be handled by the VFS
index e32195d6aac34656b13a5619c3750e8b30586c08..fb15c9c0be74d5c06ba421f04449d981a69337ed 100644 (file)
@@ -1026,6 +1026,8 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
            !(def_mount_opts & EXT4_DEFM_NODELALLOC))
                seq_puts(seq, ",nodelalloc");
 
+       if (test_opt(sb, MBLK_IO_SUBMIT))
+               seq_puts(seq, ",mblk_io_submit");
        if (sbi->s_stripe)
                seq_printf(seq, ",stripe=%lu", sbi->s_stripe);
        /*
@@ -1239,8 +1241,8 @@ enum {
        Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
        Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err,
        Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version,
-       Opt_stripe, Opt_delalloc, Opt_nodelalloc,
-       Opt_block_validity, Opt_noblock_validity,
+       Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit,
+       Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity,
        Opt_inode_readahead_blks, Opt_journal_ioprio,
        Opt_dioread_nolock, Opt_dioread_lock,
        Opt_discard, Opt_nodiscard,
@@ -1304,6 +1306,8 @@ static const match_table_t tokens = {
        {Opt_resize, "resize"},
        {Opt_delalloc, "delalloc"},
        {Opt_nodelalloc, "nodelalloc"},
+       {Opt_mblk_io_submit, "mblk_io_submit"},
+       {Opt_nomblk_io_submit, "nomblk_io_submit"},
        {Opt_block_validity, "block_validity"},
        {Opt_noblock_validity, "noblock_validity"},
        {Opt_inode_readahead_blks, "inode_readahead_blks=%u"},
@@ -1725,6 +1729,12 @@ set_qf_format:
                case Opt_nodelalloc:
                        clear_opt(sbi->s_mount_opt, DELALLOC);
                        break;
+               case Opt_mblk_io_submit:
+                       set_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT);
+                       break;
+               case Opt_nomblk_io_submit:
+                       clear_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT);
+                       break;
                case Opt_stripe:
                        if (match_int(&args[0], &option))
                                return 0;
index 9242d294fe90d382fb7a40f1220923baea71c97e..8b984a2cebbda185af01a6d4d5f8c31c89fc6fbe 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/module.h>
+#include <linux/compat.h>
 
 static const struct file_operations fuse_direct_io_file_operations;
 
@@ -1627,6 +1628,58 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov,
        return 0;
 }
 
+/*
+ * CUSE servers compiled on 32bit broke on 64bit kernels because the
+ * ABI was defined to be 'struct iovec' which is different on 32bit
+ * and 64bit.  Fortunately we can determine which structure the server
+ * used from the size of the reply.
+ */
+static int fuse_copy_ioctl_iovec(struct iovec *dst, void *src,
+                                size_t transferred, unsigned count,
+                                bool is_compat)
+{
+#ifdef CONFIG_COMPAT
+       if (count * sizeof(struct compat_iovec) == transferred) {
+               struct compat_iovec *ciov = src;
+               unsigned i;
+
+               /*
+                * With this interface a 32bit server cannot support
+                * non-compat (i.e. ones coming from 64bit apps) ioctl
+                * requests
+                */
+               if (!is_compat)
+                       return -EINVAL;
+
+               for (i = 0; i < count; i++) {
+                       dst[i].iov_base = compat_ptr(ciov[i].iov_base);
+                       dst[i].iov_len = ciov[i].iov_len;
+               }
+               return 0;
+       }
+#endif
+
+       if (count * sizeof(struct iovec) != transferred)
+               return -EIO;
+
+       memcpy(dst, src, transferred);
+       return 0;
+}
+
+/* Make sure iov_length() won't overflow */
+static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count)
+{
+       size_t n;
+       u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT;
+
+       for (n = 0; n < count; n++) {
+               if (iov->iov_len > (size_t) max)
+                       return -ENOMEM;
+               max -= iov->iov_len;
+       }
+       return 0;
+}
+
 /*
  * For ioctls, there is no generic way to determine how much memory
  * needs to be read and/or written.  Furthermore, ioctls are allowed
@@ -1808,18 +1861,25 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
                    in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV)
                        goto out;
 
-               err = -EIO;
-               if ((in_iovs + out_iovs) * sizeof(struct iovec) != transferred)
-                       goto out;
-
-               /* okay, copy in iovs and retry */
                vaddr = kmap_atomic(pages[0], KM_USER0);
-               memcpy(page_address(iov_page), vaddr, transferred);
+               err = fuse_copy_ioctl_iovec(page_address(iov_page), vaddr,
+                                           transferred, in_iovs + out_iovs,
+                                           (flags & FUSE_IOCTL_COMPAT) != 0);
                kunmap_atomic(vaddr, KM_USER0);
+               if (err)
+                       goto out;
 
                in_iov = page_address(iov_page);
                out_iov = in_iov + in_iovs;
 
+               err = fuse_verify_ioctl_iov(in_iov, in_iovs);
+               if (err)
+                       goto out;
+
+               err = fuse_verify_ioctl_iov(out_iov, out_iovs);
+               if (err)
+                       goto out;
+
                goto retry;
        }
 
index 5362af9b73729905817a76b5c24a5b33c48d5ce7..4ff7ca530533b121763dbe3b415ad79b162a85fb 100644 (file)
@@ -1748,6 +1748,9 @@ struct file *do_filp_open(int dfd, const char *pathname,
        if (!(open_flag & O_CREAT))
                mode = 0;
 
+       /* Must never be set by userspace */
+       open_flag &= ~FMODE_NONOTIFY;
+
        /*
         * O_SYNC is implemented as __O_SYNC|O_DSYNC.  As many places only
         * check for O_DSYNC if the need any syncing at all we enforce it's
index f0a384e2ae633a1dc2de619d102d5935ff32a273..996dd8989a9135203cab110f57e7c1f8df49e200 100644 (file)
@@ -57,7 +57,7 @@ static int nfs_rename(struct inode *, struct dentry *,
                      struct inode *, struct dentry *);
 static int nfs_fsync_dir(struct file *, int);
 static loff_t nfs_llseek_dir(struct file *, loff_t, int);
-static int nfs_readdir_clear_array(struct page*, gfp_t);
+static void nfs_readdir_clear_array(struct page*);
 
 const struct file_operations nfs_dir_operations = {
        .llseek         = nfs_llseek_dir,
@@ -83,8 +83,8 @@ const struct inode_operations nfs_dir_inode_operations = {
        .setattr        = nfs_setattr,
 };
 
-const struct address_space_operations nfs_dir_addr_space_ops = {
-       .releasepage = nfs_readdir_clear_array,
+const struct address_space_operations nfs_dir_aops = {
+       .freepage = nfs_readdir_clear_array,
 };
 
 #ifdef CONFIG_NFS_V3
@@ -178,6 +178,7 @@ typedef struct {
        struct page     *page;
        unsigned long   page_index;
        u64             *dir_cookie;
+       u64             last_cookie;
        loff_t          current_index;
        decode_dirent_t decode;
 
@@ -213,17 +214,15 @@ void nfs_readdir_release_array(struct page *page)
  * we are freeing strings created by nfs_add_to_readdir_array()
  */
 static
-int nfs_readdir_clear_array(struct page *page, gfp_t mask)
+void nfs_readdir_clear_array(struct page *page)
 {
-       struct nfs_cache_array *array = nfs_readdir_get_array(page);
+       struct nfs_cache_array *array;
        int i;
 
-       if (IS_ERR(array))
-               return PTR_ERR(array);
+       array = kmap_atomic(page, KM_USER0);
        for (i = 0; i < array->size; i++)
                kfree(array->array[i].string.name);
-       nfs_readdir_release_array(page);
-       return 0;
+       kunmap_atomic(array, KM_USER0);
 }
 
 /*
@@ -272,7 +271,7 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page)
                goto out;
        array->last_cookie = entry->cookie;
        array->size++;
-       if (entry->eof == 1)
+       if (entry->eof != 0)
                array->eof_index = array->size;
 out:
        nfs_readdir_release_array(page);
@@ -312,15 +311,14 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
        for (i = 0; i < array->size; i++) {
                if (array->array[i].cookie == *desc->dir_cookie) {
                        desc->cache_entry_index = i;
-                       status = 0;
-                       goto out;
+                       return 0;
                }
        }
-       if (i == array->eof_index) {
-               desc->eof = 1;
+       if (array->eof_index >= 0) {
                status = -EBADCOOKIE;
+               if (*desc->dir_cookie == array->last_cookie)
+                       desc->eof = 1;
        }
-out:
        return status;
 }
 
@@ -328,10 +326,7 @@ static
 int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc)
 {
        struct nfs_cache_array *array;
-       int status = -EBADCOOKIE;
-
-       if (desc->dir_cookie == NULL)
-               goto out;
+       int status;
 
        array = nfs_readdir_get_array(desc->page);
        if (IS_ERR(array)) {
@@ -344,6 +339,10 @@ int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc)
        else
                status = nfs_readdir_search_for_cookie(array, desc);
 
+       if (status == -EAGAIN) {
+               desc->last_cookie = array->last_cookie;
+               desc->page_index++;
+       }
        nfs_readdir_release_array(desc->page);
 out:
        return status;
@@ -490,7 +489,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
 
                count++;
 
-               if (desc->plus == 1)
+               if (desc->plus != 0)
                        nfs_prime_dcache(desc->file->f_path.dentry, entry);
 
                status = nfs_readdir_add_to_array(entry, page);
@@ -498,7 +497,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
                        break;
        } while (!entry->eof);
 
-       if (count == 0 || (status == -EBADCOOKIE && entry->eof == 1)) {
+       if (count == 0 || (status == -EBADCOOKIE && entry->eof != 0)) {
                array = nfs_readdir_get_array(page);
                if (!IS_ERR(array)) {
                        array->eof_index = array->size;
@@ -563,7 +562,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
        unsigned int array_size = ARRAY_SIZE(pages);
 
        entry.prev_cookie = 0;
-       entry.cookie = *desc->dir_cookie;
+       entry.cookie = desc->last_cookie;
        entry.eof = 0;
        entry.fh = nfs_alloc_fhandle();
        entry.fattr = nfs_alloc_fattr();
@@ -636,6 +635,8 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page)
 static
 void cache_page_release(nfs_readdir_descriptor_t *desc)
 {
+       if (!desc->page->mapping)
+               nfs_readdir_clear_array(desc->page);
        page_cache_release(desc->page);
        desc->page = NULL;
 }
@@ -660,9 +661,8 @@ int find_cache_page(nfs_readdir_descriptor_t *desc)
                return PTR_ERR(desc->page);
 
        res = nfs_readdir_search_array(desc);
-       if (res == 0)
-               return 0;
-       cache_page_release(desc);
+       if (res != 0)
+               cache_page_release(desc);
        return res;
 }
 
@@ -672,22 +672,16 @@ int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
 {
        int res;
 
-       if (desc->page_index == 0)
+       if (desc->page_index == 0) {
                desc->current_index = 0;
-       while (1) {
-               res = find_cache_page(desc);
-               if (res != -EAGAIN)
-                       break;
-               desc->page_index++;
+               desc->last_cookie = 0;
        }
+       do {
+               res = find_cache_page(desc);
+       } while (res == -EAGAIN);
        return res;
 }
 
-static inline unsigned int dt_type(struct inode *inode)
-{
-       return (inode->i_mode >> 12) & 15;
-}
-
 /*
  * Once we've found the start of the dirent within a page: fill 'er up...
  */
@@ -717,13 +711,12 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
                        break;
                }
                file->f_pos++;
-               desc->cache_entry_index = i;
                if (i < (array->size-1))
                        *desc->dir_cookie = array->array[i+1].cookie;
                else
                        *desc->dir_cookie = array->last_cookie;
        }
-       if (i == array->eof_index)
+       if (array->eof_index >= 0)
                desc->eof = 1;
 
        nfs_readdir_release_array(desc->page);
@@ -764,6 +757,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
        }
 
        desc->page_index = 0;
+       desc->last_cookie = *desc->dir_cookie;
        desc->page = page;
 
        status = nfs_readdir_xdr_to_array(desc, page, inode);
@@ -791,7 +785,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        struct inode    *inode = dentry->d_inode;
        nfs_readdir_descriptor_t my_desc,
                        *desc = &my_desc;
-       int res = -ENOMEM;
+       int res;
 
        dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n",
                        dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -816,7 +810,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        if (res < 0)
                goto out;
 
-       while (desc->eof != 1) {
+       do {
                res = readdir_search_pagecache(desc);
 
                if (res == -EBADCOOKIE) {
@@ -844,7 +838,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
                res = nfs_do_filldir(desc, dirent, filldir);
                if (res < 0)
                        break;
-       }
+       } while (!desc->eof);
 out:
        nfs_unblock_sillyrename(dentry);
        if (res > 0)
index 60677f9f13110d1a98774595de819fddf2c0ccdf..7bf029ef4084c6e7f02e05e355382168e85e2cb8 100644 (file)
@@ -693,6 +693,7 @@ do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
 {
        struct inode *inode = filp->f_mapping->host;
        int status = 0;
+       unsigned int saved_type = fl->fl_type;
 
        /* Try local locking first */
        posix_test_lock(filp, fl);
@@ -700,6 +701,7 @@ do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
                /* found a conflict */
                goto out;
        }
+       fl->fl_type = saved_type;
 
        if (nfs_have_delegation(inode, FMODE_READ))
                goto out_noconflict;
index 314f57164602eda0762c0a226db44aa19be461f5..e67e31c734163c6fe6c0eef0d338a2b87ae55763 100644 (file)
@@ -289,6 +289,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
                } else if (S_ISDIR(inode->i_mode)) {
                        inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops;
                        inode->i_fop = &nfs_dir_operations;
+                       inode->i_data.a_ops = &nfs_dir_aops;
                        if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS))
                                set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags);
                        /* Deal with crossing mountpoints */
index eceafe74f4737ea5fbcea90b8ac19749737667b9..4f981f1f668925cba6bebe6ed4cf485da6a56dbb 100644 (file)
@@ -505,13 +505,13 @@ static struct rpc_procinfo mnt3_procedures[] = {
 
 static struct rpc_version mnt_version1 = {
        .number         = 1,
-       .nrprocs        = 2,
+       .nrprocs        = ARRAY_SIZE(mnt_procedures),
        .procs          = mnt_procedures,
 };
 
 static struct rpc_version mnt_version3 = {
        .number         = 3,
-       .nrprocs        = 2,
+       .nrprocs        = ARRAY_SIZE(mnt3_procedures),
        .procs          = mnt3_procedures,
 };
 
index 6a653ffd8e4e121e37c29d88ff2f5b0b4dbe264f..4435e5e1f904e3e5ba26f4eb578fc30c5f6d997b 100644 (file)
@@ -3361,6 +3361,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
        ret = nfs_revalidate_inode(server, inode);
        if (ret < 0)
                return ret;
+       if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL)
+               nfs_zap_acl_cache(inode);
        ret = nfs4_read_cached_acl(inode, buf, buflen);
        if (ret != -ENOENT)
                return ret;
@@ -3389,6 +3391,13 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
        nfs_inode_return_delegation(inode);
        buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
        ret = nfs4_call_sync(server, &msg, &arg, &res, 1);
+       /*
+        * Acl update can result in inode attribute update.
+        * so mark the attribute cache invalid.
+        */
+       spin_lock(&inode->i_lock);
+       NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR;
+       spin_unlock(&inode->i_lock);
        nfs_access_zap_cache(inode);
        nfs_zap_acl_cache(inode);
        return ret;
index 137b549e63dbcfa3971aac43091eb91a29a7b69f..b68536cc9046ec937b9b4ccddb98b2acf468f1db 100644 (file)
@@ -115,7 +115,7 @@ int nfs_set_page_tag_locked(struct nfs_page *req)
 {
        if (!nfs_lock_request_dontget(req))
                return 0;
-       if (req->wb_page != NULL)
+       if (test_bit(PG_MAPPED, &req->wb_flags))
                radix_tree_tag_set(&NFS_I(req->wb_context->path.dentry->d_inode)->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED);
        return 1;
 }
@@ -125,7 +125,7 @@ int nfs_set_page_tag_locked(struct nfs_page *req)
  */
 void nfs_clear_page_tag_locked(struct nfs_page *req)
 {
-       if (req->wb_page != NULL) {
+       if (test_bit(PG_MAPPED, &req->wb_flags)) {
                struct inode *inode = req->wb_context->path.dentry->d_inode;
                struct nfs_inode *nfsi = NFS_I(inode);
 
index e4b62c6f5a6e9eb721eda53d836c41055ab2e1b7..aedcaa7f291fbe4405f2b68c13f407c7de6be9ba 100644 (file)
@@ -152,7 +152,6 @@ static void nfs_readpage_release(struct nfs_page *req)
                        (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode),
                        req->wb_bytes,
                        (long long)req_offset(req));
-       nfs_clear_request(req);
        nfs_release_request(req);
 }
 
index 3c045044fca25183147704f3689c744549ebd77b..4100630c9a5b65f47bb5379ee2bc62f78e60284e 100644 (file)
@@ -1069,12 +1069,10 @@ static int nfs_parse_mount_options(char *raw,
                        mnt->flags |= NFS_MOUNT_VER3;
                        mnt->version = 3;
                        break;
-#ifdef CONFIG_NFS_V4
                case Opt_v4:
                        mnt->flags &= ~NFS_MOUNT_VER3;
                        mnt->version = 4;
                        break;
-#endif
                case Opt_udp:
                        mnt->flags &= ~NFS_MOUNT_TCP;
                        mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
@@ -1286,12 +1284,10 @@ static int nfs_parse_mount_options(char *raw,
                                mnt->flags |= NFS_MOUNT_VER3;
                                mnt->version = 3;
                                break;
-#ifdef CONFIG_NFS_V4
                        case NFS4_VERSION:
                                mnt->flags &= ~NFS_MOUNT_VER3;
                                mnt->version = 4;
                                break;
-#endif
                        default:
                                goto out_invalid_value;
                        }
index 4c14c17a5276a410bb383e3650f106ab56cf47d6..10d648ea128bf6345df70da0e15ee8ce443ab8e6 100644 (file)
@@ -390,6 +390,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
                if (nfs_have_delegation(inode, FMODE_WRITE))
                        nfsi->change_attr++;
        }
+       set_bit(PG_MAPPED, &req->wb_flags);
        SetPagePrivate(req->wb_page);
        set_page_private(req->wb_page, (unsigned long)req);
        nfsi->npages++;
@@ -415,6 +416,7 @@ static void nfs_inode_remove_request(struct nfs_page *req)
        spin_lock(&inode->i_lock);
        set_page_private(req->wb_page, 0);
        ClearPagePrivate(req->wb_page);
+       clear_bit(PG_MAPPED, &req->wb_flags);
        radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index);
        nfsi->npages--;
        if (!nfsi->npages) {
@@ -422,7 +424,6 @@ static void nfs_inode_remove_request(struct nfs_page *req)
                iput(inode);
        } else
                spin_unlock(&inode->i_lock);
-       nfs_clear_request(req);
        nfs_release_request(req);
 }
 
index 2a533a0af2a98ed91afb84e71669d328cb67a866..7e84a852cdae8117334fec6ee00d085fc29c0c66 100644 (file)
@@ -260,9 +260,11 @@ void fill_post_wcc(struct svc_fh *fhp)
        err = vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry,
                        &fhp->fh_post_attr);
        fhp->fh_post_change = fhp->fh_dentry->d_inode->i_version;
-       if (err)
+       if (err) {
                fhp->fh_post_saved = 0;
-       else
+               /* Grab the ctime anyway - set_change_info might use it */
+               fhp->fh_post_attr.ctime = fhp->fh_dentry->d_inode->i_ctime;
+       } else
                fhp->fh_post_saved = 1;
 }
 
index 4d476ff08ae6add1ec3a1b597909f1375af78b7b..60fce3dc5cb5d9f90d22b9f9c91ddc7ddeb9ff1d 100644 (file)
@@ -484,18 +484,17 @@ static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp)
 static inline void
 set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp)
 {
-       BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved);
-       cinfo->atomic = 1;
+       BUG_ON(!fhp->fh_pre_saved);
+       cinfo->atomic = fhp->fh_post_saved;
        cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode);
-       if (cinfo->change_supported) {
-               cinfo->before_change = fhp->fh_pre_change;
-               cinfo->after_change = fhp->fh_post_change;
-       } else {
-               cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
-               cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
-               cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
-               cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
-       }
+
+       cinfo->before_change = fhp->fh_pre_change;
+       cinfo->after_change = fhp->fh_post_change;
+       cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
+       cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
+       cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec;
+       cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec;
+
 }
 
 int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *);
index 33ad25ddd5c442a7875e8eca9b078b363e10d9ce..caf9a6a3fb54f0e0dd4cd63ccf103fd6aef20a70 100644 (file)
@@ -176,7 +176,6 @@ int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *bh)
 int nilfs_init_gcinode(struct inode *inode)
 {
        struct nilfs_inode_info *ii = NILFS_I(inode);
-       struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
 
        inode->i_mode = S_IFREG;
        mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
@@ -186,14 +185,6 @@ int nilfs_init_gcinode(struct inode *inode)
        ii->i_flags = 0;
        nilfs_bmap_init_gc(ii->i_bmap);
 
-       /*
-        * Add the inode to GC inode list. Garbage Collection
-        * is serialized and no two processes manipulate the
-        * list simultaneously.
-        */
-       igrab(inode);
-       list_add(&NILFS_I(inode)->i_dirty, &nilfs->ns_gc_inodes);
-
        return 0;
 }
 
index e00d9457c256179279b141868d6ed86494dec24e..b185e937a335471ec224314909a959684f56d174 100644 (file)
@@ -337,6 +337,7 @@ static int nilfs_ioctl_move_blocks(struct super_block *sb,
                                   struct nilfs_argv *argv, void *buf)
 {
        size_t nmembs = argv->v_nmembs;
+       struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs;
        struct inode *inode;
        struct nilfs_vdesc *vdesc;
        struct buffer_head *bh, *n;
@@ -353,6 +354,17 @@ static int nilfs_ioctl_move_blocks(struct super_block *sb,
                        ret = PTR_ERR(inode);
                        goto failed;
                }
+               if (list_empty(&NILFS_I(inode)->i_dirty)) {
+                       /*
+                        * Add the inode to GC inode list. Garbage Collection
+                        * is serialized and no two processes manipulate the
+                        * list simultaneously.
+                        */
+                       igrab(inode);
+                       list_add(&NILFS_I(inode)->i_dirty,
+                                &nilfs->ns_gc_inodes);
+               }
+
                do {
                        ret = nilfs_ioctl_move_inode_block(inode, vdesc,
                                                           &buffers);
index b04f88eed09e98b6134f275cb7ba530a06e7f998..f35794b97e8e5cb5cc396af28206d69ca1202935 100644 (file)
@@ -92,7 +92,11 @@ static int fanotify_get_response_from_access(struct fsnotify_group *group,
 
        pr_debug("%s: group=%p event=%p\n", __func__, group, event);
 
-       wait_event(group->fanotify_data.access_waitq, event->response);
+       wait_event(group->fanotify_data.access_waitq, event->response ||
+                               atomic_read(&group->fanotify_data.bypass_perm));
+
+       if (!event->response) /* bypass_perm set */
+               return 0;
 
        /* userspace responded, convert to something usable */
        spin_lock(&event->lock);
index 063224812b7e607879bffeedd5b90f9c4967346f..8b61220cffc597873bc0292bbf2fcd86300f3d5c 100644 (file)
@@ -106,20 +106,29 @@ static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event)
        return client_fd;
 }
 
-static ssize_t fill_event_metadata(struct fsnotify_group *group,
+static int fill_event_metadata(struct fsnotify_group *group,
                                   struct fanotify_event_metadata *metadata,
                                   struct fsnotify_event *event)
 {
+       int ret = 0;
+
        pr_debug("%s: group=%p metadata=%p event=%p\n", __func__,
                 group, metadata, event);
 
        metadata->event_len = FAN_EVENT_METADATA_LEN;
+       metadata->metadata_len = FAN_EVENT_METADATA_LEN;
        metadata->vers = FANOTIFY_METADATA_VERSION;
        metadata->mask = event->mask & FAN_ALL_OUTGOING_EVENTS;
        metadata->pid = pid_vnr(event->tgid);
-       metadata->fd = create_fd(group, event);
+       if (unlikely(event->mask & FAN_Q_OVERFLOW))
+               metadata->fd = FAN_NOFD;
+       else {
+               metadata->fd = create_fd(group, event);
+               if (metadata->fd < 0)
+                       ret = metadata->fd;
+       }
 
-       return metadata->fd;
+       return ret;
 }
 
 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
@@ -200,7 +209,7 @@ static int prepare_for_access_response(struct fsnotify_group *group,
 
        mutex_lock(&group->fanotify_data.access_mutex);
 
-       if (group->fanotify_data.bypass_perm) {
+       if (atomic_read(&group->fanotify_data.bypass_perm)) {
                mutex_unlock(&group->fanotify_data.access_mutex);
                kmem_cache_free(fanotify_response_event_cache, re);
                event->response = FAN_ALLOW;
@@ -257,24 +266,34 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
 
        pr_debug("%s: group=%p event=%p\n", __func__, group, event);
 
-       fd = fill_event_metadata(group, &fanotify_event_metadata, event);
-       if (fd < 0)
-               return fd;
+       ret = fill_event_metadata(group, &fanotify_event_metadata, event);
+       if (ret < 0)
+               goto out;
 
+       fd = fanotify_event_metadata.fd;
        ret = prepare_for_access_response(group, event, fd);
        if (ret)
                goto out_close_fd;
 
        ret = -EFAULT;
-       if (copy_to_user(buf, &fanotify_event_metadata, FAN_EVENT_METADATA_LEN))
+       if (copy_to_user(buf, &fanotify_event_metadata,
+                        fanotify_event_metadata.event_len))
                goto out_kill_access_response;
 
-       return FAN_EVENT_METADATA_LEN;
+       return fanotify_event_metadata.event_len;
 
 out_kill_access_response:
        remove_access_response(group, event, fd);
 out_close_fd:
-       sys_close(fd);
+       if (fd != FAN_NOFD)
+               sys_close(fd);
+out:
+#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
+       if (event->mask & FAN_ALL_PERM_EVENTS) {
+               event->response = FAN_DENY;
+               wake_up(&group->fanotify_data.access_waitq);
+       }
+#endif
        return ret;
 }
 
@@ -382,7 +401,7 @@ static int fanotify_release(struct inode *ignored, struct file *file)
 
        mutex_lock(&group->fanotify_data.access_mutex);
 
-       group->fanotify_data.bypass_perm = true;
+       atomic_inc(&group->fanotify_data.bypass_perm);
 
        list_for_each_entry_safe(re, lre, &group->fanotify_data.access_list, list) {
                pr_debug("%s: found group=%p re=%p event=%p\n", __func__, group,
@@ -586,11 +605,10 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
 {
        struct fsnotify_mark *fsn_mark;
        __u32 added;
+       int ret = 0;
 
        fsn_mark = fsnotify_find_vfsmount_mark(group, mnt);
        if (!fsn_mark) {
-               int ret;
-
                if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks)
                        return -ENOSPC;
 
@@ -600,17 +618,16 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
 
                fsnotify_init_mark(fsn_mark, fanotify_free_mark);
                ret = fsnotify_add_mark(fsn_mark, group, NULL, mnt, 0);
-               if (ret) {
-                       fanotify_free_mark(fsn_mark);
-                       return ret;
-               }
+               if (ret)
+                       goto err;
        }
        added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
-       fsnotify_put_mark(fsn_mark);
+
        if (added & ~mnt->mnt_fsnotify_mask)
                fsnotify_recalc_vfsmount_mask(mnt);
-
-       return 0;
+err:
+       fsnotify_put_mark(fsn_mark);
+       return ret;
 }
 
 static int fanotify_add_inode_mark(struct fsnotify_group *group,
@@ -619,6 +636,7 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 {
        struct fsnotify_mark *fsn_mark;
        __u32 added;
+       int ret = 0;
 
        pr_debug("%s: group=%p inode=%p\n", __func__, group, inode);
 
@@ -634,8 +652,6 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 
        fsn_mark = fsnotify_find_inode_mark(group, inode);
        if (!fsn_mark) {
-               int ret;
-
                if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks)
                        return -ENOSPC;
 
@@ -645,16 +661,16 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group,
 
                fsnotify_init_mark(fsn_mark, fanotify_free_mark);
                ret = fsnotify_add_mark(fsn_mark, group, inode, NULL, 0);
-               if (ret) {
-                       fanotify_free_mark(fsn_mark);
-                       return ret;
-               }
+               if (ret)
+                       goto err;
        }
        added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
-       fsnotify_put_mark(fsn_mark);
+
        if (added & ~inode->i_fsnotify_mask)
                fsnotify_recalc_inode_mask(inode);
-       return 0;
+err:
+       fsnotify_put_mark(fsn_mark);
+       return ret;
 }
 
 /* fanotify syscalls */
@@ -687,8 +703,10 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
 
        /* fsnotify_alloc_group takes a ref.  Dropped in fanotify_release */
        group = fsnotify_alloc_group(&fanotify_fsnotify_ops);
-       if (IS_ERR(group))
+       if (IS_ERR(group)) {
+               free_uid(user);
                return PTR_ERR(group);
+       }
 
        group->fanotify_data.user = user;
        atomic_inc(&user->fanotify_listeners);
@@ -698,6 +716,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
        mutex_init(&group->fanotify_data.access_mutex);
        init_waitqueue_head(&group->fanotify_data.access_waitq);
        INIT_LIST_HEAD(&group->fanotify_data.access_list);
+       atomic_set(&group->fanotify_data.bypass_perm, 0);
 #endif
        switch (flags & FAN_ALL_CLASS_BITS) {
        case FAN_CLASS_NOTIF:
@@ -764,8 +783,10 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
        if (flags & ~FAN_ALL_MARK_FLAGS)
                return -EINVAL;
        switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) {
-       case FAN_MARK_ADD:
+       case FAN_MARK_ADD:              /* fallthrough */
        case FAN_MARK_REMOVE:
+               if (!mask)
+                       return -EINVAL;
        case FAN_MARK_FLUSH:
                break;
        default:
index 444c305a468c531b7e9e8dda803a2d650a257c58..4cd5d5d78f9fa2b85f38bd9422efc3d387780295 100644 (file)
@@ -752,6 +752,7 @@ SYSCALL_DEFINE1(inotify_init1, int, flags)
        if (ret >= 0)
                return ret;
 
+       fsnotify_put_group(group);
        atomic_dec(&user->inotify_devs);
 out_free_uid:
        free_uid(user);
index d2af0a8381a63975e9668d1aa7babb942bd4f4e2..77a59891734e925318f4a91723f96eb55f7b5ae8 100644 (file)
@@ -297,6 +297,7 @@ xfs_rename(
         * it and some incremental backup programs won't work without it.
         */
        xfs_trans_ichgtime(tp, src_ip, XFS_ICHGTIME_CHG);
+       xfs_trans_log_inode(tp, src_ip, XFS_ILOG_CORE);
 
        /*
         * Adjust the link count on src_dp.  This is necessary when
index 551793c9b6e8c25b2b1d3e36a4fe8ffcb4a0f24a..0e98e679d3a749cfda3898c2fe59f82d18ca87c3 100644 (file)
@@ -1,6 +1,10 @@
 #ifndef __ACPI_VIDEO_H
 #define __ACPI_VIDEO_H
 
+#include <linux/errno.h> /* for ENODEV */
+
+struct acpi_device;
+
 #define ACPI_VIDEO_DISPLAY_CRT  1
 #define ACPI_VIDEO_DISPLAY_TV   2
 #define ACPI_VIDEO_DISPLAY_DVI  3
@@ -26,4 +30,3 @@ static inline int acpi_video_get_edid(struct acpi_device *device, int type,
 #endif
 
 #endif
-
index 050a7bccb8365ef117f365ebe3d3a8d337efc390..67c91b4418b06e59ea9de82e0c67dfb4cc5a7554 100644 (file)
@@ -219,7 +219,7 @@ static inline int acpi_video_display_switch_support(void)
 
 extern int acpi_blacklisted(void);
 extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d);
-extern int acpi_osi_setup(char *str);
+extern void acpi_osi_setup(char *str);
 
 #ifdef CONFIG_ACPI_NUMA
 int acpi_get_pxm(acpi_handle handle);
index a8e4e832cdbb094d8a99ad9d831db3d14cbdbe23..475f8c42c0e928b57fbaf370bb89471642391b77 100644 (file)
@@ -427,8 +427,10 @@ extern rwlock_t vcc_sklist_lock;
 
 #define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb))
 
-struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops,
-    int number,unsigned long *flags); /* number == -1: pick first available */
+struct atm_dev *atm_dev_register(const char *type, struct device *parent,
+                                const struct atmdev_ops *ops,
+                                int number, /* -1 == pick first available */
+                                unsigned long *flags);
 struct atm_dev *atm_dev_lookup(int number);
 void atm_dev_deregister(struct atm_dev *dev);
 
index 0f0121467fc4b8cf261cbb06a9ff6347b3596474..6c6133f76e163c88041c4a13a4b091ef6ccf13ac 100644 (file)
                                 FAN_ALL_PERM_EVENTS |\
                                 FAN_Q_OVERFLOW)
 
-#define FANOTIFY_METADATA_VERSION      2
+#define FANOTIFY_METADATA_VERSION      3
 
 struct fanotify_event_metadata {
        __u32 event_len;
-       __u32 vers;
+       __u8 vers;
+       __u8 reserved;
+       __u16 metadata_len;
        __aligned_u64 mask;
        __s32 fd;
        __s32 pid;
@@ -96,11 +98,13 @@ struct fanotify_event_metadata {
 struct fanotify_response {
        __s32 fd;
        __u32 response;
-} __attribute__ ((packed));
+};
 
 /* Legit userspace responses to a _PERM event */
 #define FAN_ALLOW      0x01
 #define FAN_DENY       0x02
+/* No fd set in event */
+#define FAN_NOFD       -1
 
 /* Helper functions to deal with fanotify_event_metadata buffers */
 #define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata))
index c9e06cc70dad585c6c185db2d1503d3fad4a5a48..090f0eacde296ec52a06fe5eb1b13c07808b7ada 100644 (file)
@@ -602,6 +602,7 @@ struct address_space_operations {
        sector_t (*bmap)(struct address_space *, sector_t);
        void (*invalidatepage) (struct page *, unsigned long);
        int (*releasepage) (struct page *, gfp_t);
+       void (*freepage)(struct page *);
        ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
                        loff_t offset, unsigned long nr_segs);
        int (*get_xip_mem)(struct address_space *, pgoff_t, int,
index 5c185fa27089f03b4e9194445ee7bfd842f125c6..b10bcdeaef768b2b0b123c4a6c862b3f5f6c0694 100644 (file)
@@ -235,9 +235,6 @@ static inline void fsnotify_open(struct file *file)
        if (S_ISDIR(inode->i_mode))
                mask |= FS_ISDIR;
 
-       /* FMODE_NONOTIFY must never be set from user */
-       file->f_mode &= ~FMODE_NONOTIFY;
-
        fsnotify_parent(path, NULL, mask);
        fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
 }
index 0a68f924f06fcf3f6f75727f382971bc16e5608f..7380763595d30accb255728f45682550cc540d63 100644 (file)
@@ -166,7 +166,7 @@ struct fsnotify_group {
                        struct mutex access_mutex;
                        struct list_head access_list;
                        wait_queue_head_t access_waitq;
-                       bool bypass_perm; /* protected by access_mutex */
+                       atomic_t bypass_perm;
 #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */
                        int f_flags;
                        unsigned int max_marks;
index a8af21d42bc146cc6f6ee186894e623b01a884ff..9777668883be6aa18a309b6388616fe08ee900ea 100644 (file)
@@ -104,8 +104,10 @@ struct input_keymap_entry {
 #define EVIOCGREP              _IOR('E', 0x03, unsigned int[2])        /* get repeat settings */
 #define EVIOCSREP              _IOW('E', 0x03, unsigned int[2])        /* set repeat settings */
 
-#define EVIOCGKEYCODE          _IOR('E', 0x04, struct input_keymap_entry)      /* get keycode */
-#define EVIOCSKEYCODE          _IOW('E', 0x04, struct input_keymap_entry)      /* set keycode */
+#define EVIOCGKEYCODE          _IOR('E', 0x04, unsigned int[2])        /* get keycode */
+#define EVIOCGKEYCODE_V2       _IOR('E', 0x04, struct input_keymap_entry)
+#define EVIOCSKEYCODE          _IOW('E', 0x04, unsigned int[2])        /* set keycode */
+#define EVIOCSKEYCODE_V2       _IOW('E', 0x04, struct input_keymap_entry)
 
 #define EVIOCGNAME(len)                _IOC(_IOC_READ, 'E', 0x06, len)         /* get device name */
 #define EVIOCGPHYS(len)                _IOC(_IOC_READ, 'E', 0x07, len)         /* get physical location */
index d377ea815d453b9ec232f22efc5503f5d456b0cf..e9bb22cba764139cc69f3faa1e16f11cc0e05eb2 100644 (file)
@@ -112,7 +112,6 @@ struct resource_list {
 /* PC/ISA/whatever - the normal PC address spaces: IO and memory */
 extern struct resource ioport_resource;
 extern struct resource iomem_resource;
-extern int resource_alloc_from_bottom;
 
 extern struct resource *request_resource_conflict(struct resource *root, struct resource *new);
 extern int request_resource(struct resource *root, struct resource *new);
@@ -124,6 +123,7 @@ extern void reserve_region_with_split(struct resource *root,
 extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new);
 extern int insert_resource(struct resource *parent, struct resource *new);
 extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new);
+extern void arch_remove_reservations(struct resource *avail);
 extern int allocate_resource(struct resource *root, struct resource *new,
                             resource_size_t size, resource_size_t min,
                             resource_size_t max, resource_size_t align,
index 5c51f367c0610166bbf6ec12d6fedc7587d7420e..add8a1b8bcf0057c3f328c51dc96a4d82ae331a5 100644 (file)
@@ -29,7 +29,7 @@ struct wm8994_ldo_pdata {
 #define WM8994_CONFIGURE_GPIO 0x8000
 
 #define WM8994_DRC_REGS 5
-#define WM8994_EQ_REGS  19
+#define WM8994_EQ_REGS  20
 
 /**
  * DRC configurations are specified with a label and a set of register
index c66fdb7d6998129701f6eaa653f1d28dd641e332..29d504d5d1c31f5698433657dd534c1500f317b2 100644 (file)
@@ -401,6 +401,7 @@ extern const struct inode_operations nfs3_file_inode_operations;
 #endif /* CONFIG_NFS_V3 */
 extern const struct file_operations nfs_file_operations;
 extern const struct address_space_operations nfs_file_aops;
+extern const struct address_space_operations nfs_dir_aops;
 
 static inline struct nfs_open_context *nfs_file_open_context(struct file *filp)
 {
index f8b60e7f4c44d9b652a94bca2ab8945130bdb061..d55cee73f63477a326b73cf7eb15e3e277567b14 100644 (file)
@@ -29,6 +29,7 @@
  */
 enum {
        PG_BUSY = 0,
+       PG_MAPPED,
        PG_CLEAN,
        PG_NEED_COMMIT,
        PG_NEED_RESCHED,
index de2c41758e29e20d6a709303f21a6d8242696fa0..4f1279e105ee143e4317219b3cb093bc8bbdd954 100644 (file)
@@ -887,6 +887,7 @@ struct perf_cpu_context {
        int                             exclusive;
        struct list_head                rotation_list;
        int                             jiffies_interval;
+       struct pmu                      *active_pmu;
 };
 
 struct perf_output_handle {
index 3ec2358f8692d11027e6af927402fcbc0f039da2..d19f1cca7f740a9150f516c98e5c9deecfd271ae 100644 (file)
@@ -77,7 +77,8 @@ static inline void device_set_run_wake(struct device *dev, bool enable)
 
 static inline bool pm_runtime_suspended(struct device *dev)
 {
-       return dev->power.runtime_status == RPM_SUSPENDED;
+       return dev->power.runtime_status == RPM_SUSPENDED
+               && !dev->power.disable_depth;
 }
 
 static inline void pm_runtime_mark_last_busy(struct device *dev)
index 2c79e921a68baeb9d5afa9b0deaa731232685ed5..223874538b33208e3c5ff11710f3161d58b4aef2 100644 (file)
@@ -143,7 +143,7 @@ extern unsigned long nr_iowait_cpu(int cpu);
 extern unsigned long this_cpu_load(void);
 
 
-extern void calc_global_load(void);
+extern void calc_global_load(unsigned long ticks);
 
 extern unsigned long get_parent_ip(unsigned long addr);
 
index ebb0c80ffd6ebb53b02fb2263e0a6ff6a634eb6a..12b2b18e50c1c321f208a83d4bbda61ce985450c 100644 (file)
@@ -230,6 +230,7 @@ enum
        LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */
        LINUX_MIB_TCPDEFERACCEPTDROP,
        LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */
+       LINUX_MIB_TCPTIMEWAITOVERFLOW,          /* TCPTimeWaitOverflow */
        __LINUX_MIB_MAX
 };
 
index 942e3873690190addb45bdde24a069a812f3b8b8..eba52a100533349461c1965f996074c187eaab08 100644 (file)
@@ -96,16 +96,21 @@ static inline bool ssb_gige_must_flush_posted_writes(struct pci_dev *pdev)
        return 0;
 }
 
-extern char * nvram_get(const char *name);
+#ifdef CONFIG_BCM47XX
+#include <asm/mach-bcm47xx/nvram.h>
 /* Get the device MAC address */
 static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr)
 {
-#ifdef CONFIG_BCM47XX
-       char *res = nvram_get("et0macaddr");
-       if (res)
-               memcpy(macaddr, res, 6);
-#endif
+       char buf[20];
+       if (nvram_getenv("et0macaddr", buf, sizeof(buf)) < 0)
+               return;
+       nvram_parse_macaddr(buf, macaddr);
 }
+#else
+static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr)
+{
+}
+#endif
 
 extern int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev,
                                          struct pci_dev *pdev);
index 2fb46bc9340d9b40617042ba8bb253754e4b6f67..ed5cdeb3604dbe6ea1fe807b33a69bf140d1622a 100644 (file)
@@ -23,6 +23,7 @@
 #ifndef _LINUX_VIDEO_OUTPUT_H
 #define _LINUX_VIDEO_OUTPUT_H
 #include <linux/device.h>
+#include <linux/err.h>
 struct output_device;
 struct output_properties {
        int (*set_state)(struct output_device *);
@@ -34,9 +35,23 @@ struct output_device {
        struct device dev;
 };
 #define to_output_device(obj) container_of(obj, struct output_device, dev)
+#if    defined(CONFIG_VIDEO_OUTPUT_CONTROL) || defined(CONFIG_VIDEO_OUTPUT_CONTROL_MODULE)
 struct output_device *video_output_register(const char *name,
        struct device *dev,
        void *devdata,
        struct output_properties *op);
 void video_output_unregister(struct output_device *dev);
+#else
+static struct output_device *video_output_register(const char *name,
+        struct device *dev,
+        void *devdata,
+        struct output_properties *op)
+{
+       return ERR_PTR(-ENODEV);
+}
+static void video_output_unregister(struct output_device *dev)
+{
+       return;
+}
+#endif
 #endif
index 6648036b728d7e32beb09fb91757931265780823..b16f307d471a2df59fd622cba1b338e42503ec16 100644 (file)
@@ -51,6 +51,8 @@ struct v4l2_device {
                        unsigned int notification, void *arg);
        /* The control handler. May be NULL. */
        struct v4l2_ctrl_handler *ctrl_handler;
+       /* BKL replacement mutex. Temporary solution only. */
+       struct mutex ioctl_lock;
 };
 
 /* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev.
index a6338d039857bf6b00bcff087f974ebf46ae0875..659d968d95c54afe6df51c3289a0d2d6fb5b34ed 100644 (file)
@@ -1155,6 +1155,8 @@ extern void sk_common_release(struct sock *sk);
 /* Initialise core socket variables */
 extern void sock_init_data(struct socket *sock, struct sock *sk);
 
+extern void sk_filter_release_rcu(struct rcu_head *rcu);
+
 /**
  *     sk_filter_release - release a socket filter
  *     @fp: filter to remove
@@ -1165,7 +1167,7 @@ extern void sock_init_data(struct socket *sock, struct sock *sk);
 static inline void sk_filter_release(struct sk_filter *fp)
 {
        if (atomic_dec_and_test(&fp->refcnt))
-               kfree(fp);
+               call_rcu_bh(&fp->rcu, sk_filter_release_rcu);
 }
 
 static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp)
index e8cbf431c8ccfd33f76fd018e8dd64ea6dd2c8b7..75271b9a8f61bedcec5a18465b5a9ca8e84a38c7 100644 (file)
@@ -24,8 +24,15 @@ typedef unsigned int RING_IDX;
  * A ring contains as many entries as will fit, rounded down to the nearest
  * power of two (so we can mask with (size-1) to loop around).
  */
-#define __RING_SIZE(_s, _sz) \
-    (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
+#define __CONST_RING_SIZE(_s, _sz)                             \
+       (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) /   \
+               sizeof(((struct _s##_sring *)0)->ring[0])))
+
+/*
+ * The same for passing in an actual pointer instead of a name tag.
+ */
+#define __RING_SIZE(_s, _sz)                                           \
+       (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
 
 /*
  * Macros to make the correct C datatypes for a new kind of ring.
index 3b159c5991b7561bdba253eeb479f91622a35fb9..5447dc7defa95b8f0e13acb80b45487df7dc2e73 100644 (file)
@@ -273,6 +273,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
 
        setup_thread_stack(tsk, orig);
        clear_user_return_notifier(tsk);
+       clear_tsk_need_resched(tsk);
        stackend = end_of_stack(tsk);
        *stackend = STACK_END_MAGIC;    /* for overflow detection */
 
index eac7e3364335a7a3f94d902e69b9ed4eac4df74a..2870feee81dd7a046703645c9ec50022d4339f39 100644 (file)
@@ -3824,6 +3824,8 @@ static void perf_event_task_event(struct perf_task_event *task_event)
        rcu_read_lock();
        list_for_each_entry_rcu(pmu, &pmus, entry) {
                cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
+               if (cpuctx->active_pmu != pmu)
+                       goto next;
                perf_event_task_ctx(&cpuctx->ctx, task_event);
 
                ctx = task_event->task_ctx;
@@ -3959,6 +3961,8 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event)
        rcu_read_lock();
        list_for_each_entry_rcu(pmu, &pmus, entry) {
                cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
+               if (cpuctx->active_pmu != pmu)
+                       goto next;
                perf_event_comm_ctx(&cpuctx->ctx, comm_event);
 
                ctxn = pmu->task_ctx_nr;
@@ -4144,6 +4148,8 @@ got_name:
        rcu_read_lock();
        list_for_each_entry_rcu(pmu, &pmus, entry) {
                cpuctx = get_cpu_ptr(pmu->pmu_cpu_context);
+               if (cpuctx->active_pmu != pmu)
+                       goto next;
                perf_event_mmap_ctx(&cpuctx->ctx, mmap_event,
                                        vma->vm_flags & VM_EXEC);
 
@@ -4713,7 +4719,7 @@ static int perf_swevent_init(struct perf_event *event)
                break;
        }
 
-       if (event_id > PERF_COUNT_SW_MAX)
+       if (event_id >= PERF_COUNT_SW_MAX)
                return -ENOENT;
 
        if (!event->parent) {
@@ -5145,20 +5151,36 @@ static void *find_pmu_context(int ctxn)
        return NULL;
 }
 
-static void free_pmu_context(void * __percpu cpu_context)
+static void update_pmu_context(struct pmu *pmu, struct pmu *old_pmu)
 {
-       struct pmu *pmu;
+       int cpu;
+
+       for_each_possible_cpu(cpu) {
+               struct perf_cpu_context *cpuctx;
+
+               cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu);
+
+               if (cpuctx->active_pmu == old_pmu)
+                       cpuctx->active_pmu = pmu;
+       }
+}
+
+static void free_pmu_context(struct pmu *pmu)
+{
+       struct pmu *i;
 
        mutex_lock(&pmus_lock);
        /*
         * Like a real lame refcount.
         */
-       list_for_each_entry(pmu, &pmus, entry) {
-               if (pmu->pmu_cpu_context == cpu_context)
+       list_for_each_entry(i, &pmus, entry) {
+               if (i->pmu_cpu_context == pmu->pmu_cpu_context) {
+                       update_pmu_context(i, pmu);
                        goto out;
+               }
        }
 
-       free_percpu(cpu_context);
+       free_percpu(pmu->pmu_cpu_context);
 out:
        mutex_unlock(&pmus_lock);
 }
@@ -5190,6 +5212,7 @@ int perf_pmu_register(struct pmu *pmu)
                cpuctx->ctx.pmu = pmu;
                cpuctx->jiffies_interval = 1;
                INIT_LIST_HEAD(&cpuctx->rotation_list);
+               cpuctx->active_pmu = pmu;
        }
 
 got_cpu_context:
@@ -5241,7 +5264,7 @@ void perf_pmu_unregister(struct pmu *pmu)
        synchronize_rcu();
 
        free_percpu(pmu->pmu_disable_count);
-       free_pmu_context(pmu->pmu_cpu_context);
+       free_pmu_context(pmu);
 }
 
 struct pmu *perf_init_event(struct perf_event *event)
index baf667bb2794c6880a834e060fd3a32943c80d68..8c7e4832b9be0f8e031fb07645f6ad8e955c0318 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "power.h"
 
-#define HIBERNATE_SIG  "LINHIB0001"
+#define HIBERNATE_SIG  "S1SUSPEND"
 
 /*
  *     The swap map is a data structure used for keeping track of each page
index 1b2ea31e6bd8c0eca7eaaf985bc84337a1e750d0..c36c3b9e8a84f59ad5894a1e2d04c7252b656ebe 100644 (file)
@@ -137,7 +137,7 @@ static int snapshot_release(struct inode *inode, struct file *filp)
        free_all_swap_pages(data->swap);
        if (data->frozen)
                thaw_processes();
-       pm_notifier_call_chain(data->mode == O_WRONLY ?
+       pm_notifier_call_chain(data->mode == O_RDONLY ?
                        PM_POST_HIBERNATION : PM_POST_RESTORE);
        atomic_inc(&snapshot_device_available);
 
index 9fad33efd0db50b3269572f598a1ce418731153c..798e2fae2a069645c13853f4b658dada92af8f66 100644 (file)
@@ -40,23 +40,6 @@ EXPORT_SYMBOL(iomem_resource);
 
 static DEFINE_RWLOCK(resource_lock);
 
-/*
- * By default, we allocate free space bottom-up.  The architecture can request
- * top-down by clearing this flag.  The user can override the architecture's
- * choice with the "resource_alloc_from_bottom" kernel boot option, but that
- * should only be a debugging tool.
- */
-int resource_alloc_from_bottom = 1;
-
-static __init int setup_alloc_from_bottom(char *s)
-{
-       printk(KERN_INFO
-              "resource: allocating from bottom-up; please report a bug\n");
-       resource_alloc_from_bottom = 1;
-       return 0;
-}
-early_param("resource_alloc_from_bottom", setup_alloc_from_bottom);
-
 static void *r_next(struct seq_file *m, void *v, loff_t *pos)
 {
        struct resource *p = v;
@@ -374,6 +357,10 @@ int __weak page_is_ram(unsigned long pfn)
        return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1;
 }
 
+void __weak arch_remove_reservations(struct resource *avail)
+{
+}
+
 static resource_size_t simple_align_resource(void *data,
                                             const struct resource *avail,
                                             resource_size_t size,
@@ -396,75 +383,8 @@ static bool resource_contains(struct resource *res1, struct resource *res2)
        return res1->start <= res2->start && res1->end >= res2->end;
 }
 
-/*
- * Find the resource before "child" in the sibling list of "root" children.
- */
-static struct resource *find_sibling_prev(struct resource *root, struct resource *child)
-{
-       struct resource *this;
-
-       for (this = root->child; this; this = this->sibling)
-               if (this->sibling == child)
-                       return this;
-
-       return NULL;
-}
-
 /*
  * Find empty slot in the resource tree given range and alignment.
- * This version allocates from the end of the root resource first.
- */
-static int find_resource_from_top(struct resource *root, struct resource *new,
-                                 resource_size_t size, resource_size_t min,
-                                 resource_size_t max, resource_size_t align,
-                                 resource_size_t (*alignf)(void *,
-                                                  const struct resource *,
-                                                  resource_size_t,
-                                                  resource_size_t),
-                                 void *alignf_data)
-{
-       struct resource *this;
-       struct resource tmp, avail, alloc;
-
-       tmp.start = root->end;
-       tmp.end = root->end;
-
-       this = find_sibling_prev(root, NULL);
-       for (;;) {
-               if (this) {
-                       if (this->end < root->end)
-                               tmp.start = this->end + 1;
-               } else
-                       tmp.start = root->start;
-
-               resource_clip(&tmp, min, max);
-
-               /* Check for overflow after ALIGN() */
-               avail = *new;
-               avail.start = ALIGN(tmp.start, align);
-               avail.end = tmp.end;
-               if (avail.start >= tmp.start) {
-                       alloc.start = alignf(alignf_data, &avail, size, align);
-                       alloc.end = alloc.start + size - 1;
-                       if (resource_contains(&avail, &alloc)) {
-                               new->start = alloc.start;
-                               new->end = alloc.end;
-                               return 0;
-                       }
-               }
-
-               if (!this || this->start == root->start)
-                       break;
-
-               tmp.end = this->start - 1;
-               this = find_sibling_prev(root, this);
-       }
-       return -EBUSY;
-}
-
-/*
- * Find empty slot in the resource tree given range and alignment.
- * This version allocates from the beginning of the root resource first.
  */
 static int find_resource(struct resource *root, struct resource *new,
                         resource_size_t size, resource_size_t min,
@@ -478,23 +398,24 @@ static int find_resource(struct resource *root, struct resource *new,
        struct resource *this = root->child;
        struct resource tmp = *new, avail, alloc;
 
+       tmp.flags = new->flags;
        tmp.start = root->start;
        /*
-        * Skip past an allocated resource that starts at 0, since the
-        * assignment of this->start - 1 to tmp->end below would cause an
-        * underflow.
+        * Skip past an allocated resource that starts at 0, since the assignment
+        * of this->start - 1 to tmp->end below would cause an underflow.
         */
        if (this && this->start == 0) {
                tmp.start = this->end + 1;
                this = this->sibling;
        }
-       for (;;) {
+       for(;;) {
                if (this)
                        tmp.end = this->start - 1;
                else
                        tmp.end = root->end;
 
                resource_clip(&tmp, min, max);
+               arch_remove_reservations(&tmp);
 
                /* Check for overflow after ALIGN() */
                avail = *new;
@@ -509,10 +430,8 @@ static int find_resource(struct resource *root, struct resource *new,
                                return 0;
                        }
                }
-
                if (!this)
                        break;
-
                tmp.start = this->end + 1;
                this = this->sibling;
        }
@@ -545,10 +464,7 @@ int allocate_resource(struct resource *root, struct resource *new,
                alignf = simple_align_resource;
 
        write_lock(&resource_lock);
-       if (resource_alloc_from_bottom)
-               err = find_resource(root, new, size, min, max, align, alignf, alignf_data);
-       else
-               err = find_resource_from_top(root, new, size, min, max, align, alignf, alignf_data);
+       err = find_resource(root, new, size, min, max, align, alignf, alignf_data);
        if (err >= 0 && __request_resource(root, new))
                err = -EBUSY;
        write_unlock(&resource_lock);
index dc91a4d09ac3b71a3c347187ff2a1691c952cebd..456c99054160a773fa6736005397a3bc138f6902 100644 (file)
@@ -636,22 +636,18 @@ static inline struct task_group *task_group(struct task_struct *p)
 
 #endif /* CONFIG_CGROUP_SCHED */
 
-static u64 irq_time_cpu(int cpu);
-static void sched_irq_time_avg_update(struct rq *rq, u64 irq_time);
+static void update_rq_clock_task(struct rq *rq, s64 delta);
 
-inline void update_rq_clock(struct rq *rq)
+static void update_rq_clock(struct rq *rq)
 {
-       if (!rq->skip_clock_update) {
-               int cpu = cpu_of(rq);
-               u64 irq_time;
+       s64 delta;
 
-               rq->clock = sched_clock_cpu(cpu);
-               irq_time = irq_time_cpu(cpu);
-               if (rq->clock - irq_time > rq->clock_task)
-                       rq->clock_task = rq->clock - irq_time;
+       if (rq->skip_clock_update)
+               return;
 
-               sched_irq_time_avg_update(rq, irq_time);
-       }
+       delta = sched_clock_cpu(cpu_of(rq)) - rq->clock;
+       rq->clock += delta;
+       update_rq_clock_task(rq, delta);
 }
 
 /*
@@ -1924,10 +1920,9 @@ static void deactivate_task(struct rq *rq, struct task_struct *p, int flags)
  * They are read and saved off onto struct rq in update_rq_clock().
  * This may result in other CPU reading this CPU's irq time and can
  * race with irq/account_system_vtime on this CPU. We would either get old
- * or new value (or semi updated value on 32 bit) with a side effect of
- * accounting a slice of irq time to wrong task when irq is in progress
- * while we read rq->clock. That is a worthy compromise in place of having
- * locks on each irq in account_system_time.
+ * or new value with a side effect of accounting a slice of irq time to wrong
+ * task when irq is in progress while we read rq->clock. That is a worthy
+ * compromise in place of having locks on each irq in account_system_time.
  */
 static DEFINE_PER_CPU(u64, cpu_hardirq_time);
 static DEFINE_PER_CPU(u64, cpu_softirq_time);
@@ -1945,19 +1940,58 @@ void disable_sched_clock_irqtime(void)
        sched_clock_irqtime = 0;
 }
 
-static u64 irq_time_cpu(int cpu)
+#ifndef CONFIG_64BIT
+static DEFINE_PER_CPU(seqcount_t, irq_time_seq);
+
+static inline void irq_time_write_begin(void)
 {
-       if (!sched_clock_irqtime)
-               return 0;
+       __this_cpu_inc(irq_time_seq.sequence);
+       smp_wmb();
+}
+
+static inline void irq_time_write_end(void)
+{
+       smp_wmb();
+       __this_cpu_inc(irq_time_seq.sequence);
+}
+
+static inline u64 irq_time_read(int cpu)
+{
+       u64 irq_time;
+       unsigned seq;
 
+       do {
+               seq = read_seqcount_begin(&per_cpu(irq_time_seq, cpu));
+               irq_time = per_cpu(cpu_softirq_time, cpu) +
+                          per_cpu(cpu_hardirq_time, cpu);
+       } while (read_seqcount_retry(&per_cpu(irq_time_seq, cpu), seq));
+
+       return irq_time;
+}
+#else /* CONFIG_64BIT */
+static inline void irq_time_write_begin(void)
+{
+}
+
+static inline void irq_time_write_end(void)
+{
+}
+
+static inline u64 irq_time_read(int cpu)
+{
        return per_cpu(cpu_softirq_time, cpu) + per_cpu(cpu_hardirq_time, cpu);
 }
+#endif /* CONFIG_64BIT */
 
+/*
+ * Called before incrementing preempt_count on {soft,}irq_enter
+ * and before decrementing preempt_count on {soft,}irq_exit.
+ */
 void account_system_vtime(struct task_struct *curr)
 {
        unsigned long flags;
+       s64 delta;
        int cpu;
-       u64 now, delta;
 
        if (!sched_clock_irqtime)
                return;
@@ -1965,9 +1999,10 @@ void account_system_vtime(struct task_struct *curr)
        local_irq_save(flags);
 
        cpu = smp_processor_id();
-       now = sched_clock_cpu(cpu);
-       delta = now - per_cpu(irq_start_time, cpu);
-       per_cpu(irq_start_time, cpu) = now;
+       delta = sched_clock_cpu(cpu) - __this_cpu_read(irq_start_time);
+       __this_cpu_add(irq_start_time, delta);
+
+       irq_time_write_begin();
        /*
         * We do not account for softirq time from ksoftirqd here.
         * We want to continue accounting softirq time to ksoftirqd thread
@@ -1975,33 +2010,55 @@ void account_system_vtime(struct task_struct *curr)
         * that do not consume any time, but still wants to run.
         */
        if (hardirq_count())
-               per_cpu(cpu_hardirq_time, cpu) += delta;
+               __this_cpu_add(cpu_hardirq_time, delta);
        else if (in_serving_softirq() && !(curr->flags & PF_KSOFTIRQD))
-               per_cpu(cpu_softirq_time, cpu) += delta;
+               __this_cpu_add(cpu_softirq_time, delta);
 
+       irq_time_write_end();
        local_irq_restore(flags);
 }
 EXPORT_SYMBOL_GPL(account_system_vtime);
 
-static void sched_irq_time_avg_update(struct rq *rq, u64 curr_irq_time)
+static void update_rq_clock_task(struct rq *rq, s64 delta)
 {
-       if (sched_clock_irqtime && sched_feat(NONIRQ_POWER)) {
-               u64 delta_irq = curr_irq_time - rq->prev_irq_time;
-               rq->prev_irq_time = curr_irq_time;
-               sched_rt_avg_update(rq, delta_irq);
-       }
+       s64 irq_delta;
+
+       irq_delta = irq_time_read(cpu_of(rq)) - rq->prev_irq_time;
+
+       /*
+        * Since irq_time is only updated on {soft,}irq_exit, we might run into
+        * this case when a previous update_rq_clock() happened inside a
+        * {soft,}irq region.
+        *
+        * When this happens, we stop ->clock_task and only update the
+        * prev_irq_time stamp to account for the part that fit, so that a next
+        * update will consume the rest. This ensures ->clock_task is
+        * monotonic.
+        *
+        * It does however cause some slight miss-attribution of {soft,}irq
+        * time, a more accurate solution would be to update the irq_time using
+        * the current rq->clock timestamp, except that would require using
+        * atomic ops.
+        */
+       if (irq_delta > delta)
+               irq_delta = delta;
+
+       rq->prev_irq_time += irq_delta;
+       delta -= irq_delta;
+       rq->clock_task += delta;
+
+       if (irq_delta && sched_feat(NONIRQ_POWER))
+               sched_rt_avg_update(rq, irq_delta);
 }
 
-#else
+#else /* CONFIG_IRQ_TIME_ACCOUNTING */
 
-static u64 irq_time_cpu(int cpu)
+static void update_rq_clock_task(struct rq *rq, s64 delta)
 {
-       return 0;
+       rq->clock_task += delta;
 }
 
-static void sched_irq_time_avg_update(struct rq *rq, u64 curr_irq_time) { }
-
-#endif
+#endif /* CONFIG_IRQ_TIME_ACCOUNTING */
 
 #include "sched_idletask.c"
 #include "sched_fair.c"
@@ -2129,7 +2186,7 @@ static void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
         * A queue event has occurred, and we're going to schedule.  In
         * this case, we can save a useless back to back clock update.
         */
-       if (test_tsk_need_resched(rq->curr))
+       if (rq->curr->se.on_rq && test_tsk_need_resched(rq->curr))
                rq->skip_clock_update = 1;
 }
 
@@ -3119,6 +3176,15 @@ static long calc_load_fold_active(struct rq *this_rq)
        return delta;
 }
 
+static unsigned long
+calc_load(unsigned long load, unsigned long exp, unsigned long active)
+{
+       load *= exp;
+       load += active * (FIXED_1 - exp);
+       load += 1UL << (FSHIFT - 1);
+       return load >> FSHIFT;
+}
+
 #ifdef CONFIG_NO_HZ
 /*
  * For NO_HZ we delay the active fold to the next LOAD_FREQ update.
@@ -3148,6 +3214,128 @@ static long calc_load_fold_idle(void)
 
        return delta;
 }
+
+/**
+ * fixed_power_int - compute: x^n, in O(log n) time
+ *
+ * @x:         base of the power
+ * @frac_bits: fractional bits of @x
+ * @n:         power to raise @x to.
+ *
+ * By exploiting the relation between the definition of the natural power
+ * function: x^n := x*x*...*x (x multiplied by itself for n times), and
+ * the binary encoding of numbers used by computers: n := \Sum n_i * 2^i,
+ * (where: n_i \elem {0, 1}, the binary vector representing n),
+ * we find: x^n := x^(\Sum n_i * 2^i) := \Prod x^(n_i * 2^i), which is
+ * of course trivially computable in O(log_2 n), the length of our binary
+ * vector.
+ */
+static unsigned long
+fixed_power_int(unsigned long x, unsigned int frac_bits, unsigned int n)
+{
+       unsigned long result = 1UL << frac_bits;
+
+       if (n) for (;;) {
+               if (n & 1) {
+                       result *= x;
+                       result += 1UL << (frac_bits - 1);
+                       result >>= frac_bits;
+               }
+               n >>= 1;
+               if (!n)
+                       break;
+               x *= x;
+               x += 1UL << (frac_bits - 1);
+               x >>= frac_bits;
+       }
+
+       return result;
+}
+
+/*
+ * a1 = a0 * e + a * (1 - e)
+ *
+ * a2 = a1 * e + a * (1 - e)
+ *    = (a0 * e + a * (1 - e)) * e + a * (1 - e)
+ *    = a0 * e^2 + a * (1 - e) * (1 + e)
+ *
+ * a3 = a2 * e + a * (1 - e)
+ *    = (a0 * e^2 + a * (1 - e) * (1 + e)) * e + a * (1 - e)
+ *    = a0 * e^3 + a * (1 - e) * (1 + e + e^2)
+ *
+ *  ...
+ *
+ * an = a0 * e^n + a * (1 - e) * (1 + e + ... + e^n-1) [1]
+ *    = a0 * e^n + a * (1 - e) * (1 - e^n)/(1 - e)
+ *    = a0 * e^n + a * (1 - e^n)
+ *
+ * [1] application of the geometric series:
+ *
+ *              n         1 - x^(n+1)
+ *     S_n := \Sum x^i = -------------
+ *             i=0          1 - x
+ */
+static unsigned long
+calc_load_n(unsigned long load, unsigned long exp,
+           unsigned long active, unsigned int n)
+{
+
+       return calc_load(load, fixed_power_int(exp, FSHIFT, n), active);
+}
+
+/*
+ * NO_HZ can leave us missing all per-cpu ticks calling
+ * calc_load_account_active(), but since an idle CPU folds its delta into
+ * calc_load_tasks_idle per calc_load_account_idle(), all we need to do is fold
+ * in the pending idle delta if our idle period crossed a load cycle boundary.
+ *
+ * Once we've updated the global active value, we need to apply the exponential
+ * weights adjusted to the number of cycles missed.
+ */
+static void calc_global_nohz(unsigned long ticks)
+{
+       long delta, active, n;
+
+       if (time_before(jiffies, calc_load_update))
+               return;
+
+       /*
+        * If we crossed a calc_load_update boundary, make sure to fold
+        * any pending idle changes, the respective CPUs might have
+        * missed the tick driven calc_load_account_active() update
+        * due to NO_HZ.
+        */
+       delta = calc_load_fold_idle();
+       if (delta)
+               atomic_long_add(delta, &calc_load_tasks);
+
+       /*
+        * If we were idle for multiple load cycles, apply them.
+        */
+       if (ticks >= LOAD_FREQ) {
+               n = ticks / LOAD_FREQ;
+
+               active = atomic_long_read(&calc_load_tasks);
+               active = active > 0 ? active * FIXED_1 : 0;
+
+               avenrun[0] = calc_load_n(avenrun[0], EXP_1, active, n);
+               avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n);
+               avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n);
+
+               calc_load_update += n * LOAD_FREQ;
+       }
+
+       /*
+        * Its possible the remainder of the above division also crosses
+        * a LOAD_FREQ period, the regular check in calc_global_load()
+        * which comes after this will take care of that.
+        *
+        * Consider us being 11 ticks before a cycle completion, and us
+        * sleeping for 4*LOAD_FREQ + 22 ticks, then the above code will
+        * age us 4 cycles, and the test in calc_global_load() will
+        * pick up the final one.
+        */
+}
 #else
 static void calc_load_account_idle(struct rq *this_rq)
 {
@@ -3157,6 +3345,10 @@ static inline long calc_load_fold_idle(void)
 {
        return 0;
 }
+
+static void calc_global_nohz(unsigned long ticks)
+{
+}
 #endif
 
 /**
@@ -3174,24 +3366,17 @@ void get_avenrun(unsigned long *loads, unsigned long offset, int shift)
        loads[2] = (avenrun[2] + offset) << shift;
 }
 
-static unsigned long
-calc_load(unsigned long load, unsigned long exp, unsigned long active)
-{
-       load *= exp;
-       load += active * (FIXED_1 - exp);
-       return load >> FSHIFT;
-}
-
 /*
  * calc_load - update the avenrun load estimates 10 ticks after the
  * CPUs have updated calc_load_tasks.
  */
-void calc_global_load(void)
+void calc_global_load(unsigned long ticks)
 {
-       unsigned long upd = calc_load_update + 10;
        long active;
 
-       if (time_before(jiffies, upd))
+       calc_global_nohz(ticks);
+
+       if (time_before(jiffies, calc_load_update + 10))
                return;
 
        active = atomic_long_read(&calc_load_tasks);
@@ -3845,7 +4030,6 @@ static void put_prev_task(struct rq *rq, struct task_struct *prev)
 {
        if (prev->se.on_rq)
                update_rq_clock(rq);
-       rq->skip_clock_update = 0;
        prev->sched_class->put_prev_task(rq, prev);
 }
 
@@ -3903,7 +4087,6 @@ need_resched_nonpreemptible:
                hrtick_clear(rq);
 
        raw_spin_lock_irq(&rq->lock);
-       clear_tsk_need_resched(prev);
 
        switch_count = &prev->nivcsw;
        if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
@@ -3935,6 +4118,8 @@ need_resched_nonpreemptible:
 
        put_prev_task(rq, prev);
        next = pick_next_task(rq);
+       clear_tsk_need_resched(prev);
+       rq->skip_clock_update = 0;
 
        if (likely(prev != next)) {
                sched_info_switch(prev, next);
@@ -3943,6 +4128,7 @@ need_resched_nonpreemptible:
                rq->nr_switches++;
                rq->curr = next;
                ++*switch_count;
+               WARN_ON_ONCE(test_tsk_need_resched(next));
 
                context_switch(rq, prev, next); /* unlocks the rq */
                /*
index 68a9ae7679b717f6eb4782ce5114ad405dec5a4c..353b9227c2ecfe11793a17b0a41f534ebdbd14f8 100644 (file)
@@ -1252,6 +1252,12 @@ unsigned long get_next_timer_interrupt(unsigned long now)
        struct tvec_base *base = __get_cpu_var(tvec_bases);
        unsigned long expires;
 
+       /*
+        * Pretend that there is no timer pending if the cpu is offline.
+        * Possible pending timers will be migrated later to an active cpu.
+        */
+       if (cpu_is_offline(smp_processor_id()))
+               return now + NEXT_TIMER_MAX_DELTA;
        spin_lock(&base->lock);
        if (time_before_eq(base->next_timer, base->timer_jiffies))
                base->next_timer = __next_timer_interrupt(base);
@@ -1319,7 +1325,7 @@ void do_timer(unsigned long ticks)
 {
        jiffies_64 += ticks;
        update_wall_time();
-       calc_global_load();
+       calc_global_load(ticks);
 }
 
 #ifdef __ARCH_WANT_SYS_ALARM
index c380612273bf75d683ddebcf5e7863b30bece806..f8cf959bad456dead3a5dec2fdd1a21e384f22bb 100644 (file)
@@ -2338,11 +2338,19 @@ tracing_write_stub(struct file *filp, const char __user *ubuf,
        return count;
 }
 
+static loff_t tracing_seek(struct file *file, loff_t offset, int origin)
+{
+       if (file->f_mode & FMODE_READ)
+               return seq_lseek(file, offset, origin);
+       else
+               return 0;
+}
+
 static const struct file_operations tracing_fops = {
        .open           = tracing_open,
        .read           = seq_read,
        .write          = tracing_write_stub,
-       .llseek         = seq_lseek,
+       .llseek         = tracing_seek,
        .release        = tracing_release,
 };
 
index 90db1bd1a97852e4c547c43d840b2ca624c9a773..e785b0f2aea57f362f9528fb979f15716f7f2aa4 100644 (file)
@@ -661,7 +661,7 @@ void wq_worker_waking_up(struct task_struct *task, unsigned int cpu)
 {
        struct worker *worker = kthread_data(task);
 
-       if (likely(!(worker->flags & WORKER_NOT_RUNNING)))
+       if (!(worker->flags & WORKER_NOT_RUNNING))
                atomic_inc(get_gcwq_nr_running(cpu));
 }
 
@@ -687,7 +687,7 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task,
        struct global_cwq *gcwq = get_gcwq(cpu);
        atomic_t *nr_running = get_gcwq_nr_running(cpu);
 
-       if (unlikely(worker->flags & WORKER_NOT_RUNNING))
+       if (worker->flags & WORKER_NOT_RUNNING)
                return NULL;
 
        /* this can only happen on the local cpu */
@@ -3692,7 +3692,8 @@ static int __init init_workqueues(void)
        system_nrt_wq = alloc_workqueue("events_nrt", WQ_NON_REENTRANT, 0);
        system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND,
                                            WQ_UNBOUND_MAX_ACTIVE);
-       BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq);
+       BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq ||
+              !system_unbound_wq);
        return 0;
 }
 early_initcall(init_workqueues);
index ea89840fc65fa2b499ce3c19c657e9e8a680b240..6b9aee20f2426b88024a25749402fc5ca1ff7a0a 100644 (file)
@@ -143,13 +143,18 @@ void __remove_from_page_cache(struct page *page)
 void remove_from_page_cache(struct page *page)
 {
        struct address_space *mapping = page->mapping;
+       void (*freepage)(struct page *);
 
        BUG_ON(!PageLocked(page));
 
+       freepage = mapping->a_ops->freepage;
        spin_lock_irq(&mapping->tree_lock);
        __remove_from_page_cache(page);
        spin_unlock_irq(&mapping->tree_lock);
        mem_cgroup_uncharge_cache_page(page);
+
+       if (freepage)
+               freepage(page);
 }
 EXPORT_SYMBOL(remove_from_page_cache);
 
index b179abb1474ae41bff47060b5241045d3b1b12ad..50a4aa0255a0703f83c8667028afe8545d78e09a 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2462,6 +2462,7 @@ int install_special_mapping(struct mm_struct *mm,
                            unsigned long addr, unsigned long len,
                            unsigned long vm_flags, struct page **pages)
 {
+       int ret;
        struct vm_area_struct *vma;
 
        vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
@@ -2479,16 +2480,23 @@ int install_special_mapping(struct mm_struct *mm,
        vma->vm_ops = &special_mapping_vmops;
        vma->vm_private_data = pages;
 
-       if (unlikely(insert_vm_struct(mm, vma))) {
-               kmem_cache_free(vm_area_cachep, vma);
-               return -ENOMEM;
-       }
+       ret = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1);
+       if (ret)
+               goto out;
+
+       ret = insert_vm_struct(mm, vma);
+       if (ret)
+               goto out;
 
        mm->total_vm += len >> PAGE_SHIFT;
 
        perf_event_mmap(vma);
 
        return 0;
+
+out:
+       kmem_cache_free(vm_area_cachep, vma);
+       return ret;
 }
 
 static DEFINE_MUTEX(mm_all_locks_mutex);
index ba887bff48c5a263c315a6ef098284df4df5bb44..3c2d5ddfa0d49f3cf31449e214d8fbd50e92ad08 100644 (file)
@@ -390,6 +390,10 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page)
        __remove_from_page_cache(page);
        spin_unlock_irq(&mapping->tree_lock);
        mem_cgroup_uncharge_cache_page(page);
+
+       if (mapping->a_ops->freepage)
+               mapping->a_ops->freepage(page);
+
        page_cache_release(page);       /* pagecache ref */
        return 1;
 failed:
index d31d7ce52c0ea2dbbf85b26019c9fdd70fab624a..9ca587c692748adbc715b440ff5aa8c89357c511 100644 (file)
@@ -494,9 +494,16 @@ static int __remove_mapping(struct address_space *mapping, struct page *page)
                spin_unlock_irq(&mapping->tree_lock);
                swapcache_free(swap, page);
        } else {
+               void (*freepage)(struct page *);
+
+               freepage = mapping->a_ops->freepage;
+
                __remove_from_page_cache(page);
                spin_unlock_irq(&mapping->tree_lock);
                mem_cgroup_uncharge_cache_page(page);
+
+               if (freepage != NULL)
+                       freepage(page);
        }
 
        return 1;
index 799c631f0fed0c1e8210d2d61e3fdf3afd27aea9..f7fa67c78766f59c0b107ece600348f401a40d57 100644 (file)
@@ -143,12 +143,13 @@ static struct class atm_class = {
        .dev_uevent             = atm_uevent,
 };
 
-int atm_register_sysfs(struct atm_dev *adev)
+int atm_register_sysfs(struct atm_dev *adev, struct device *parent)
 {
        struct device *cdev = &adev->class_dev;
        int i, j, err;
 
        cdev->class = &atm_class;
+       cdev->parent = parent;
        dev_set_drvdata(cdev, adev);
 
        dev_set_name(cdev, "%s%d", adev->type, adev->number);
index d29e582615116a68e1f476091c6475d589401878..23f45ce6f3510fb1e9b30b58b7e52fac6a456961 100644 (file)
@@ -74,8 +74,9 @@ struct atm_dev *atm_dev_lookup(int number)
 }
 EXPORT_SYMBOL(atm_dev_lookup);
 
-struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
-                                int number, unsigned long *flags)
+struct atm_dev *atm_dev_register(const char *type, struct device *parent,
+                                const struct atmdev_ops *ops, int number,
+                                unsigned long *flags)
 {
        struct atm_dev *dev, *inuse;
 
@@ -115,7 +116,7 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
                goto out_fail;
        }
 
-       if (atm_register_sysfs(dev) < 0) {
+       if (atm_register_sysfs(dev, parent) < 0) {
                pr_err("atm_register_sysfs failed for dev %s\n", type);
                atm_proc_dev_deregister(dev);
                goto out_fail;
index 126fb1840dfbb2ddd853602892e1a5e740bd90ac..521431e305073acc8c418c56317c09bb13b4731d 100644 (file)
@@ -42,6 +42,6 @@ static inline void atm_proc_dev_deregister(struct atm_dev *dev)
 
 #endif /* CONFIG_PROC_FS */
 
-int atm_register_sysfs(struct atm_dev *adev);
+int atm_register_sysfs(struct atm_dev *adev, struct device *parent);
 void atm_unregister_sysfs(struct atm_dev *adev);
 #endif
index d0927d1fdadaba4887dbac40064c4328541b9b00..66b9e5c0523a2211450cece91d5cf217fbd4722b 100644 (file)
@@ -882,7 +882,7 @@ static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
        int lm = 0;
 
        if (type != SCO_LINK && type != ESCO_LINK)
-               return 0;
+               return -EINVAL;
 
        BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
 
@@ -908,7 +908,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
        BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
 
        if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
-               return 0;
+               return -EINVAL;
 
        if (!status) {
                struct sco_conn *conn;
@@ -927,7 +927,7 @@ static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason)
        BT_DBG("hcon %p reason %d", hcon, reason);
 
        if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
-               return 0;
+               return -EINVAL;
 
        sco_conn_del(hcon, bt_err(reason));
 
index c1ee800bc080c3faf33033e1659021a0a356f7ce..ae21a0d3c4a2a4566c3792476e07ce0d2d2ece38 100644 (file)
@@ -589,23 +589,16 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
 EXPORT_SYMBOL(sk_chk_filter);
 
 /**
- *     sk_filter_rcu_release - Release a socket filter by rcu_head
+ *     sk_filter_release_rcu - Release a socket filter by rcu_head
  *     @rcu: rcu_head that contains the sk_filter to free
  */
-static void sk_filter_rcu_release(struct rcu_head *rcu)
+void sk_filter_release_rcu(struct rcu_head *rcu)
 {
        struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu);
 
-       sk_filter_release(fp);
-}
-
-static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp)
-{
-       unsigned int size = sk_filter_len(fp);
-
-       atomic_sub(size, &sk->sk_omem_alloc);
-       call_rcu_bh(&fp->rcu, sk_filter_rcu_release);
+       kfree(fp);
 }
+EXPORT_SYMBOL(sk_filter_release_rcu);
 
 /**
  *     sk_attach_filter - attach a socket filter
@@ -649,7 +642,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
        rcu_assign_pointer(sk->sk_filter, fp);
 
        if (old_fp)
-               sk_filter_delayed_uncharge(sk, old_fp);
+               sk_filter_uncharge(sk, old_fp);
        return 0;
 }
 EXPORT_SYMBOL_GPL(sk_attach_filter);
@@ -663,7 +656,7 @@ int sk_detach_filter(struct sock *sk)
                                           sock_owned_by_user(sk));
        if (filter) {
                rcu_assign_pointer(sk->sk_filter, NULL);
-               sk_filter_delayed_uncharge(sk, filter);
+               sk_filter_uncharge(sk, filter);
                ret = 0;
        }
        return ret;
index 0ae6c22da85b2a3516980691c8fbcf2f7228e3d6..c19bb4ee405ede196271ac9af5452dd21525fe2e 100644 (file)
@@ -96,11 +96,13 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb)
        struct phy_device *phydev;
        unsigned int type;
 
-       skb_push(skb, ETH_HLEN);
+       if (skb_headroom(skb) < ETH_HLEN)
+               return false;
+       __skb_push(skb, ETH_HLEN);
 
        type = classify(skb);
 
-       skb_pull(skb, ETH_HLEN);
+       __skb_pull(skb, ETH_HLEN);
 
        switch (type) {
        case PTP_CLASS_V1_IPV4:
index 13992e1d2726cd29f9d84d9f782d0eb8cf3fbd5d..15dcc1a586b4a312ee877e78b4e72f1a5e9631e2 100644 (file)
@@ -661,8 +661,10 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg)
        err = 0;
        switch (cmd) {
        case SIOCSIFADDR:
-               if (!capable(CAP_NET_ADMIN))
-                       return -EPERM;
+               if (!capable(CAP_NET_ADMIN)) {
+                       err = -EPERM;
+                       break;
+               }
 
                edev = dev->ec_ptr;
                if (edev == NULL) {
@@ -849,9 +851,13 @@ static void aun_incoming(struct sk_buff *skb, struct aunhdr *ah, size_t len)
 {
        struct iphdr *ip = ip_hdr(skb);
        unsigned char stn = ntohl(ip->saddr) & 0xff;
+       struct dst_entry *dst = skb_dst(skb);
+       struct ec_device *edev = NULL;
        struct sock *sk = NULL;
        struct sk_buff *newskb;
-       struct ec_device *edev = skb->dev->ec_ptr;
+
+       if (dst)
+               edev = dst->dev->ec_ptr;
 
        if (! edev)
                goto bad;
index 1b48eb1ed4531d3fd037e7ee9aa6367b6cb575f3..b14ec7d03b6e70b9a5a1823261ac18cb40462035 100644 (file)
@@ -253,6 +253,7 @@ static const struct snmp_mib snmp4_net_list[] = {
        SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP),
        SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP),
        SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER),
+       SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW),
        SNMP_MIB_SENTINEL
 };
 
index 43cf901d765970b6a1a80f167a80ec285a8397b6..a66735f75963582ebc2243e37fd12ca4604be678 100644 (file)
@@ -347,7 +347,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
                 * socket up.  We've got bigger problems than
                 * non-graceful socket closings.
                 */
-               LIMIT_NETDEBUG(KERN_INFO "TCP: time wait bucket table overflow\n");
+               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW);
        }
 
        tcp_update_metrics(sk);
index 05b1ecf367632763cbdb1f3bfe0e74c9c4d20c0c..61c2463e2753f809c12f31967e7fa189e41e1f54 100644 (file)
@@ -231,11 +231,10 @@ void tcp_select_initial_window(int __space, __u32 mss,
                /* when initializing use the value from init_rcv_wnd
                 * rather than the default from above
                 */
-               if (init_rcv_wnd &&
-                   (*rcv_wnd > init_rcv_wnd * mss))
-                       *rcv_wnd = init_rcv_wnd * mss;
-               else if (*rcv_wnd > init_cwnd * mss)
-                       *rcv_wnd = init_cwnd * mss;
+               if (init_rcv_wnd)
+                       *rcv_wnd = min(*rcv_wnd, init_rcv_wnd * mss);
+               else
+                       *rcv_wnd = min(*rcv_wnd, init_cwnd * mss);
        }
 
        /* Set the clamp no higher than max representable value */
@@ -386,27 +385,30 @@ struct tcp_out_options {
  */
 static u8 tcp_cookie_size_check(u8 desired)
 {
-       if (desired > 0) {
+       int cookie_size;
+
+       if (desired > 0)
                /* previously specified */
                return desired;
-       }
-       if (sysctl_tcp_cookie_size <= 0) {
+
+       cookie_size = ACCESS_ONCE(sysctl_tcp_cookie_size);
+       if (cookie_size <= 0)
                /* no default specified */
                return 0;
-       }
-       if (sysctl_tcp_cookie_size <= TCP_COOKIE_MIN) {
+
+       if (cookie_size <= TCP_COOKIE_MIN)
                /* value too small, specify minimum */
                return TCP_COOKIE_MIN;
-       }
-       if (sysctl_tcp_cookie_size >= TCP_COOKIE_MAX) {
+
+       if (cookie_size >= TCP_COOKIE_MAX)
                /* value too large, specify maximum */
                return TCP_COOKIE_MAX;
-       }
-       if (0x1 & sysctl_tcp_cookie_size) {
+
+       if (cookie_size & 1)
                /* 8-bit multiple, illegal, fix it */
-               return (u8)(sysctl_tcp_cookie_size + 0x1);
-       }
-       return (u8)sysctl_tcp_cookie_size;
+               cookie_size++;
+
+       return (u8)cookie_size;
 }
 
 /* Write previously computed TCP options to the packet.
@@ -1513,6 +1515,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
        struct tcp_sock *tp = tcp_sk(sk);
        const struct inet_connection_sock *icsk = inet_csk(sk);
        u32 send_win, cong_win, limit, in_flight;
+       int win_divisor;
 
        if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN)
                goto send_now;
@@ -1544,13 +1547,14 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
        if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len))
                goto send_now;
 
-       if (sysctl_tcp_tso_win_divisor) {
+       win_divisor = ACCESS_ONCE(sysctl_tcp_tso_win_divisor);
+       if (win_divisor) {
                u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache);
 
                /* If at least some fraction of a window is available,
                 * just use it.
                 */
-               chunk /= sysctl_tcp_tso_win_divisor;
+               chunk /= win_divisor;
                if (limit >= chunk)
                        goto send_now;
        } else {
index 23cc8e1ce8d4995a551ca93d98434e9150ad1740..93b7a933a7758254ed70ed849d333ad4d19114a7 100644 (file)
@@ -4021,11 +4021,11 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
                kfree_skb(skb);
                goto errout;
        }
-       rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
+       rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFINFO, NULL, GFP_ATOMIC);
        return;
 errout:
        if (err < 0)
-               rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err);
+               rtnl_set_sk_err(net, RTNLGRP_IPV6_IFINFO, err);
 }
 
 static inline size_t inet6_prefix_nlmsg_size(void)
index 2a59610c2a582ed885ae756729b58da00e6f324f..70e891a20fb9258686b9d9914e6694a3837d0acb 100644 (file)
@@ -1175,6 +1175,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
                                sizeof (struct ipv6hdr);
 
                        dev->mtu = rt->rt6i_dev->mtu - sizeof (struct ipv6hdr);
+                       if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+                               dev->mtu-=8;
 
                        if (dev->mtu < IPV6_MIN_MTU)
                                dev->mtu = IPV6_MIN_MTU;
@@ -1363,12 +1365,17 @@ static const struct net_device_ops ip6_tnl_netdev_ops = {
 
 static void ip6_tnl_dev_setup(struct net_device *dev)
 {
+       struct ip6_tnl *t;
+
        dev->netdev_ops = &ip6_tnl_netdev_ops;
        dev->destructor = ip6_dev_free;
 
        dev->type = ARPHRD_TUNNEL6;
        dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr);
        dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr);
+       t = netdev_priv(dev);
+       if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
+               dev->mtu-=8;
        dev->flags |= IFF_NOARP;
        dev->addr_len = sizeof(struct in6_addr);
        dev->features |= NETIF_F_NETNS_LOCAL;
index d6bfaec3bbbf1a91701fd31616757af1a565bb41..8c4d00c7cd2bb030c194c19e00b5455d2cddf3df 100644 (file)
@@ -606,8 +606,9 @@ static int ipip6_rcv(struct sk_buff *skb)
                return 0;
        }
 
-       icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+       /* no tunnel matched,  let upstream know, ipsec may handle it */
        rcu_read_unlock();
+       return 1;
 out:
        kfree_skb(skb);
        return 0;
index 0bf6a59545ab9439f3ab7126539cd9aef419b752..522e219f3558a3e0e3ad70f27e2de3d09ed8f543 100644 (file)
@@ -674,4 +674,8 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
 MODULE_DESCRIPTION("L2TP over IP");
 MODULE_VERSION("1.0");
-MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, SOCK_DGRAM, IPPROTO_L2TP);
+
+/* Use the value of SOCK_DGRAM (2) directory, because __stringify does't like
+ * enums
+ */
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 2, IPPROTO_L2TP);
index 582612998211d24aa8d4aea919eed1ba1e994db3..e35dbe55f5201c7a8b4b61ffe382766e4abadcb8 100644 (file)
@@ -317,8 +317,9 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
                goto out;
        rc = -ENODEV;
        rtnl_lock();
+       rcu_read_lock();
        if (sk->sk_bound_dev_if) {
-               llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
+               llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if);
                if (llc->dev) {
                        if (!addr->sllc_arphrd)
                                addr->sllc_arphrd = llc->dev->type;
@@ -329,13 +330,13 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
                            !llc_mac_match(addr->sllc_mac,
                                           llc->dev->dev_addr)) {
                                rc = -EINVAL;
-                               dev_put(llc->dev);
                                llc->dev = NULL;
                        }
                }
        } else
                llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd,
                                           addr->sllc_mac);
+       rcu_read_unlock();
        rtnl_unlock();
        if (!llc->dev)
                goto out;
index 902b03ee8f60789bab002691e2db69d1f8c12cf4..54fb4a0e76f03d835c6038cffeabf18874cb2d59 100644 (file)
@@ -2247,6 +2247,10 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
                break;
        case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
        case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
+               if (is_multicast_ether_addr(mgmt->da) &&
+                   !is_broadcast_ether_addr(mgmt->da))
+                       return RX_DROP_MONITOR;
+
                /* process only for station */
                if (sdata->vif.type != NL80211_IFTYPE_STATION)
                        return RX_DROP_MONITOR;
@@ -2741,6 +2745,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 
                        if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
                                return;
+                       goto out;
                }
        }
 
@@ -2780,6 +2785,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
                        return;
        }
 
+ out:
        dev_kfree_skb(skb);
 }
 
index 96c594309506432b897b4ab8c749aed4cb3c1349..7a637b80a62ef7a8d00d49285d9d6995b4083d9e 100644 (file)
@@ -1587,7 +1587,12 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
                                                list) {
                                if (!ieee80211_sdata_running(tmp_sdata))
                                        continue;
-                               if (tmp_sdata->vif.type != NL80211_IFTYPE_AP)
+                               if (tmp_sdata->vif.type ==
+                                   NL80211_IFTYPE_MONITOR ||
+                                   tmp_sdata->vif.type ==
+                                   NL80211_IFTYPE_AP_VLAN ||
+                                       tmp_sdata->vif.type ==
+                                   NL80211_IFTYPE_WDS)
                                        continue;
                                if (compare_ether_addr(tmp_sdata->vif.addr,
                                                       hdr->addr2) == 0) {
@@ -1732,15 +1737,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
        int nh_pos, h_pos;
        struct sta_info *sta = NULL;
        u32 sta_flags = 0;
+       struct sk_buff *tmp_skb;
 
        if (unlikely(skb->len < ETH_HLEN)) {
                ret = NETDEV_TX_OK;
                goto fail;
        }
 
-       nh_pos = skb_network_header(skb) - skb->data;
-       h_pos = skb_transport_header(skb) - skb->data;
-
        /* convert Ethernet header to proper 802.11 header (based on
         * operation mode) */
        ethertype = (skb->data[12] << 8) | skb->data[13];
@@ -1913,6 +1916,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                goto fail;
        }
 
+       /*
+        * If the skb is shared we need to obtain our own copy.
+        */
+       if (skb_shared(skb)) {
+               tmp_skb = skb;
+               skb = skb_copy(skb, GFP_ATOMIC);
+               kfree_skb(tmp_skb);
+
+               if (!skb) {
+                       ret = NETDEV_TX_OK;
+                       goto fail;
+               }
+       }
+
        hdr.frame_control = fc;
        hdr.duration_id = 0;
        hdr.seq_ctrl = 0;
@@ -1931,6 +1948,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
                encaps_len = 0;
        }
 
+       nh_pos = skb_network_header(skb) - skb->data;
+       h_pos = skb_transport_header(skb) - skb->data;
+
        skb_pull(skb, skip_header_bytes);
        nh_pos -= skip_header_bytes;
        h_pos -= skip_header_bytes;
index 6bd554323a342d4db49be267766b87492bd2e584..0b9ee34ad35ceb31ff764baf9cec73fba010f55b 100644 (file)
@@ -2932,6 +2932,7 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
        struct sctp_association *asoc = NULL;
        struct sctp_setpeerprim prim;
        struct sctp_chunk       *chunk;
+       struct sctp_af          *af;
        int                     err;
 
        sp = sctp_sk(sk);
@@ -2959,6 +2960,13 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
        if (!sctp_state(asoc, ESTABLISHED))
                return -ENOTCONN;
 
+       af = sctp_get_af_specific(prim.sspp_addr.ss_family);
+       if (!af)
+               return -EINVAL;
+
+       if (!af->addr_valid((union sctp_addr *)&prim.sspp_addr, sp, NULL))
+               return -EADDRNOTAVAIL;
+
        if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr))
                return -EADDRNOTAVAIL;
 
index 3ca2fd9e37200e3e12f6606065acb8c982f25528..088fb3fd45e00f3fa5d55e3e374c8751e60d225b 100644 (file)
@@ -732,6 +732,21 @@ static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,
        return ret;
 }
 
+/**
+ * kernel_recvmsg - Receive a message from a socket (kernel space)
+ * @sock:       The socket to receive the message from
+ * @msg:        Received message
+ * @vec:        Input s/g array for message data
+ * @num:        Size of input s/g array
+ * @size:       Number of bytes to read
+ * @flags:      Message flags (MSG_DONTWAIT, etc...)
+ *
+ * On return the msg structure contains the scatter/gather array passed in the
+ * vec argument. The array is modified so that it consists of the unfilled
+ * portion of the original array.
+ *
+ * The returned value is the total number of bytes received, or an error.
+ */
 int kernel_recvmsg(struct socket *sock, struct msghdr *msg,
                   struct kvec *vec, size_t num, size_t size, int flags)
 {
index ea2ff78dcf7b7ec4f2555210af82379017e6e291..3f2c5559ca1a49a496b9d531625c1e175fb029c8 100644 (file)
@@ -212,6 +212,7 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
        spin_lock(&svc_xprt_class_lock);
        list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) {
                struct svc_xprt *newxprt;
+               unsigned short newport;
 
                if (strcmp(xprt_name, xcl->xcl_name))
                        continue;
@@ -230,8 +231,9 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
                spin_lock_bh(&serv->sv_lock);
                list_add(&newxprt->xpt_list, &serv->sv_permsocks);
                spin_unlock_bh(&serv->sv_lock);
+               newport = svc_xprt_local_port(newxprt);
                clear_bit(XPT_BUSY, &newxprt->xpt_flags);
-               return svc_xprt_local_port(newxprt);
+               return newport;
        }
  err:
        spin_unlock(&svc_xprt_class_lock);
@@ -425,8 +427,13 @@ void svc_xprt_received(struct svc_xprt *xprt)
 {
        BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags));
        xprt->xpt_pool = NULL;
+       /* As soon as we clear busy, the xprt could be closed and
+        * 'put', so we need a reference to call svc_xprt_enqueue with:
+        */
+       svc_xprt_get(xprt);
        clear_bit(XPT_BUSY, &xprt->xpt_flags);
        svc_xprt_enqueue(xprt);
+       svc_xprt_put(xprt);
 }
 EXPORT_SYMBOL_GPL(svc_xprt_received);
 
index 73e7b954ad288229df4d03bc164f07da183444cc..b25c6463c3e996cf536454603f4f0257f3b8b51c 100644 (file)
@@ -394,6 +394,7 @@ void __exit x25_link_free(void)
        list_for_each_safe(entry, tmp, &x25_neigh_list) {
                nb = list_entry(entry, struct x25_neigh, node);
                __x25_remove_neigh(nb);
+               dev_put(nb->dev);
        }
        write_unlock_bh(&x25_neigh_list_lock);
 }
index eb96ce52f1789dd881116e76a08169189b50f02c..220ebc05c7afc6b602785f6e402d44098cc0bd8d 100644 (file)
@@ -1268,7 +1268,7 @@ struct xfrm_state * xfrm_state_migrate(struct xfrm_state *x,
 
        return xc;
 error:
-       kfree(xc);
+       xfrm_state_put(xc);
        return NULL;
 }
 EXPORT_SYMBOL(xfrm_state_migrate);
index 58e933a20544a2cd379446661d01f3755494bf97..39667174971d1eb86105edd927aa92d39c0954bf 100644 (file)
@@ -119,7 +119,7 @@ static uint_t (*Elf_r_sym)(Elf_Rel const *rp) = fn_ELF_R_SYM;
 
 static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type)
 {
-       rp->r_info = ELF_R_INFO(sym, type);
+       rp->r_info = _w(ELF_R_INFO(sym, type));
 }
 static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO;
 
index 8509bb51293530fae488f60594199031cd16bf07..bbbe584d44943077a41b22684b5ecdbce18f532a 100755 (executable)
@@ -125,7 +125,9 @@ exuberant()
        -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \
        --extra=+f --c-kinds=-px                                \
        --regex-asm='/^ENTRY\(([^)]*)\).*/\1/'                  \
-       --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/'
+       --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \
+       --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/'               \
+       --regex-c++='/^DEFINE_EVENT\(([^,)]*).*/trace_\1/'
 
        all_kconfigs | xargs $1 -a                              \
        --langdef=kconfig --language-force=kconfig              \
index cb0c23a6b473e07bd9d768f9430e7cde2342639c..4a663471dadc1e1e00d712bd5656577aeba56984 100644 (file)
@@ -189,6 +189,9 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a,
        a->channels = GRAB_BITS(buf, 0, 0, 3);
        a->channels++;
 
+       a->sample_bits = 0;
+       a->max_bitrate = 0;
+
        a->format = GRAB_BITS(buf, 0, 3, 4);
        switch (a->format) {
        case AUDIO_CODING_TYPE_REF_STREAM_HEADER:
@@ -198,7 +201,6 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a,
 
        case AUDIO_CODING_TYPE_LPCM:
                val = GRAB_BITS(buf, 2, 0, 3);
-               a->sample_bits = 0;
                for (i = 0; i < 3; i++)
                        if (val & (1 << i))
                                a->sample_bits |= cea_sample_sizes[i + 1];
@@ -598,24 +600,19 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
 {
        int i;
 
-       pcm->rates = 0;
-       pcm->formats = 0;
-       pcm->maxbps = 0;
-       pcm->channels_min = -1;
-       pcm->channels_max = 0;
+       /* assume basic audio support (the basic audio flag is not in ELD;
+        * however, all audio capable sinks are required to support basic
+        * audio) */
+       pcm->rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
+       pcm->formats = SNDRV_PCM_FMTBIT_S16_LE;
+       pcm->maxbps = 16;
+       pcm->channels_max = 2;
        for (i = 0; i < eld->sad_count; i++) {
                struct cea_sad *a = &eld->sad[i];
                pcm->rates |= a->rates;
-               if (a->channels < pcm->channels_min)
-                       pcm->channels_min = a->channels;
                if (a->channels > pcm->channels_max)
                        pcm->channels_max = a->channels;
                if (a->format == AUDIO_CODING_TYPE_LPCM) {
-                       if (a->sample_bits & AC_SUPPCM_BITS_16) {
-                               pcm->formats |= SNDRV_PCM_FMTBIT_S16_LE;
-                               if (pcm->maxbps < 16)
-                                       pcm->maxbps = 16;
-                       }
                        if (a->sample_bits & AC_SUPPCM_BITS_20) {
                                pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE;
                                if (pcm->maxbps < 20)
@@ -635,7 +632,6 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
        /* restrict the parameters by the values the codec provides */
        pcm->rates &= codec_pars->rates;
        pcm->formats &= codec_pars->formats;
-       pcm->channels_min = max(pcm->channels_min, codec_pars->channels_min);
        pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max);
        pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps);
 }
index 21aa9b0e28f6cb466a81a4d1e4c48622c71f89c9..b030c8eba21fdc618fe0b5bfb32cf5b156c39bba 100644 (file)
@@ -2296,6 +2296,7 @@ static int azx_dev_free(struct snd_device *device)
  */
 static struct snd_pci_quirk position_fix_list[] __devinitdata = {
        SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1025, 0x026f, "Acer Aspire 5538", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
index 846d1ead47fdf1c184fb92f37ae1faf099ec45af..76bd58a0e2b637e2c17a79cc94ab54e0747de227 100644 (file)
@@ -2116,8 +2116,8 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
        struct conexant_spec *spec = codec->spec;
        unsigned int pinctl;
 
-       snd_printdd("CXT5066: update speaker, hp_present=%d\n",
-               spec->hp_present);
+       snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n",
+                   spec->hp_present, spec->cur_eapd);
 
        /* Port A (HP) */
        pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0;
@@ -2125,11 +2125,20 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
                        pinctl);
 
        /* Port D (HP/LO) */
-       pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
-               ? spec->port_d_mode : 0;
-       /* Mute if Port A is connected on Thinkpad */
-       if (spec->thinkpad && (spec->hp_present & 1))
-               pinctl = 0;
+       if (spec->dell_automute) {
+               /* DELL AIO Port Rule: PortA>  PortD>  IntSpk */
+               pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
+                       ? PIN_OUT : 0;
+       } else if (spec->thinkpad) {
+               if (spec->cur_eapd)
+                       pinctl = spec->port_d_mode;
+               /* Mute dock line-out if Port A (laptop HP) is present */
+               if (spec->hp_present&  1)
+                       pinctl = 0;
+       } else {
+               pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
+                       ? spec->port_d_mode : 0;
+       }
        snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
                        pinctl);
 
@@ -2137,14 +2146,6 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
        pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
        snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
                        pinctl);
-
-       if (spec->dell_automute) {
-               /* DELL AIO Port Rule: PortA > PortD > IntSpk */
-               pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
-                       ? PIN_OUT : 0;
-               snd_hda_codec_write(codec, 0x1c, 0,
-                       AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
-       }
 }
 
 /* turn on/off EAPD (+ mute HP) as a master switch */
@@ -3095,8 +3096,7 @@ static const char *cxt5066_models[CXT5066_MODELS] = {
 static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
-       SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
-                     CXT5066_DELL_LAPTOP),
+       SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
        SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
@@ -3109,6 +3109,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
        SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
        SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD),
+       SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD),
        SND_PCI_QUIRK(0x17aa, 0x21c8, "Thinkpad Edge 11", CXT5066_IDEAPAD),
index d3e49aa5b9ecd42f6db6f5892319e6602ad9b7ab..31df7747990d0be6690a520321a0498c9caba349 100644 (file)
@@ -834,7 +834,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
                        return -ENODEV;
        } else {
                /* fallback to the codec default */
-               hinfo->channels_min = codec_pars->channels_min;
                hinfo->channels_max = codec_pars->channels_max;
                hinfo->rates = codec_pars->rates;
                hinfo->formats = codec_pars->formats;
index 8fddc9d08726670c8d67dc1ce9f31dd1f82a56c4..427da45d7906560f517e04de74c84ab971c0a50a 100644 (file)
@@ -4595,6 +4595,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
        SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
        SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
+       SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
        SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
        SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
        SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
@@ -10829,7 +10830,8 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
        struct auto_pin_cfg *cfg = &spec->autocfg;
-       int i, err;
+       int i, err, type;
+       int type_idx = 0;
        hda_nid_t nid;
 
        for (i = 0; i < cfg->num_inputs; i++) {
@@ -10838,9 +10840,15 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec)
                nid = cfg->inputs[i].pin;
                if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
                        char label[32];
+                       type = cfg->inputs[i].type;
+                       if (i > 0 && type == cfg->inputs[i - 1].type)
+                               type_idx++;
+                       else
+                               type_idx = 0;
                        snprintf(label, sizeof(label), "%s Boost",
                                 hda_get_autocfg_input_label(codec, cfg, i));
-                       err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 0,
+                       err = add_control(spec, ALC_CTL_WIDGET_VOL, label,
+                                         type_idx,
                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
                        if (err < 0)
                                return err;
@@ -14799,6 +14807,8 @@ static int alc269_resume(struct hda_codec *codec)
 enum {
        ALC269_FIXUP_SONY_VAIO,
        ALC269_FIXUP_DELL_M101Z,
+       ALC269_FIXUP_LENOVO_EDGE14,
+       ALC269_FIXUP_ASUS_G73JW,
 };
 
 static const struct alc_fixup alc269_fixups[] = {
@@ -14816,11 +14826,22 @@ static const struct alc_fixup alc269_fixups[] = {
                        {}
                }
        },
+       [ALC269_FIXUP_LENOVO_EDGE14] = {
+               .sku = ALC_FIXUP_SKU_IGNORE,
+       },
+       [ALC269_FIXUP_ASUS_G73JW] = {
+               .pins = (const struct alc_pincfg[]) {
+                       { 0x17, 0x99130111 }, /* subwoofer */
+                       { }
+               }
+       },
 };
 
 static struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
        SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
+       SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_LENOVO_EDGE14),
+       SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
        {}
 };
 
index a2e0ed59b3769f0b7d73024a6e4740338b1ccb81..8725d4e754310d86774935b48e1a2443fe04405c 100644 (file)
 static const u16 wm8580_reg[] = {
        0x0121, 0x017e, 0x007d, 0x0014, /*R3*/
        0x0121, 0x017e, 0x007d, 0x0194, /*R7*/
-       0x001c, 0x0002, 0x0002, 0x00c2, /*R11*/
+       0x0010, 0x0002, 0x0002, 0x00c2, /*R11*/
        0x0182, 0x0082, 0x000a, 0x0024, /*R15*/
        0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/
        0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/
@@ -491,16 +491,16 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
                paifa |= 0x8;
                break;
        case SNDRV_PCM_FORMAT_S20_3LE:
-               paifa |= 0x10;
+               paifa |= 0x0;
                paifb |= WM8580_AIF_LENGTH_20;
                break;
        case SNDRV_PCM_FORMAT_S24_LE:
-               paifa |= 0x10;
+               paifa |= 0x0;
                paifb |= WM8580_AIF_LENGTH_24;
                break;
        case SNDRV_PCM_FORMAT_S32_LE:
-               paifa |= 0x10;
-               paifb |= WM8580_AIF_LENGTH_24;
+               paifa |= 0x0;
+               paifb |= WM8580_AIF_LENGTH_32;
                break;
        default:
                return -EINVAL;
index fca60a0b57b83a807a946b86576093237b090f1f..9001cc48ba1371596c890ce12465e314d9022a81 100644 (file)
@@ -818,7 +818,8 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
        struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
 
-       return wm8904->deemph;
+       ucontrol->value.enumerated.item[0] = wm8904->deemph;
+       return 0;
 }
 
 static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
index f89ad6c9a80b9162e7040ea6fe76b434c9f743f1..9cbab8e1de0149cd8b2063406ecbae29ca0c78e5 100644 (file)
@@ -380,7 +380,8 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
        struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
 
-       return wm8955->deemph;
+       ucontrol->value.enumerated.item[0] = wm8955->deemph;
+       return 0;
 }
 
 static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
index 8d5efb333c33f260b271af07e9352b14679f0502..21986c42272f07ac693cd21d15f48cff20c43352 100644 (file)
@@ -138,7 +138,8 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
        struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
 
-       return wm8960->deemph;
+       ucontrol->value.enumerated.item[0] = wm8960->deemph;
+       return 0;
 }
 
 static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
index e8092745a207674caaf4351d815870e7367b4003..1304ca91a11c708c567f69c45052c95f1f7be17e 100644 (file)
@@ -3339,7 +3339,7 @@ static irqreturn_t wm8962_irq(int irq, void *data)
        int mask;
        int active;
 
-       mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
+       mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK);
 
        active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2);
        active &= ~mask;
index 19ca782ac970f1956243862534e5df1df12a3113..0e24092722c39522d85980a71f8a3727d01cf63f 100644 (file)
@@ -293,7 +293,7 @@ SOC_DOUBLE_R("Speaker Switch",
 SOC_DOUBLE_R("Speaker ZC Switch",
             WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT,
             7, 1, 0),
-SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 0, 3, 7, 0,
+SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 3, 0, 7, 0,
               spkboost_tlv),
 SOC_ENUM("Speaker Reference", speaker_ref),
 SOC_ENUM("Speaker Mode", speaker_mode),
index 441285ade024ff33589cd22204ef5cb82a1f14ea..85b7d548f1675f14c1a2065bbcffcf7d229a2e27 100644 (file)
@@ -1619,12 +1619,14 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
 #ifdef CONFIG_SND_SOC_AC97_BUS
        /* register any AC97 codecs */
        for (i = 0; i < card->num_rtd; i++) {
-                       ret = soc_register_ac97_dai_link(&card->rtd[i]);
-                       if (ret < 0) {
-                               printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name);
-                               goto probe_dai_err;
-                       }
+               ret = soc_register_ac97_dai_link(&card->rtd[i]);
+               if (ret < 0) {
+                       printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name);
+                       while (--i >= 0)
+                               soc_unregister_ac97_dai_link(&card->rtd[i]);
+                       goto probe_dai_err;
                }
+       }
 #endif
 
        card->instantiated = 1;
@@ -3072,7 +3074,9 @@ int snd_soc_register_dais(struct device *dev,
                pr_debug("Registered DAI '%s'\n", dai->name);
        }
 
+       mutex_lock(&client_mutex);
        snd_soc_instantiate_cards();
+       mutex_unlock(&client_mutex);
        return 0;
 
 err:
index 75ed6491222d1d283d69d5881560a823c958d253..c721502833bcbf424855c87bcf1fddf2805bbafe 100644 (file)
@@ -944,6 +944,9 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
                case SND_SOC_DAPM_STREAM_RESUME:
                        sys_power = 1;
                        break;
+               case SND_SOC_DAPM_STREAM_STOP:
+                       sys_power = !!codec->active;
+                       break;
                case SND_SOC_DAPM_STREAM_SUSPEND:
                        sys_power = 0;
                        break;