Merge branches 'acpica', 'acpidump', 'intel-idle', 'misc', 'module_acpi_driver-simpli...
authorLen Brown <len.brown@intel.com>
Sat, 6 Oct 2012 20:00:32 +0000 (16:00 -0400)
committerLen Brown <len.brown@intel.com>
Sat, 6 Oct 2012 20:00:32 +0000 (16:00 -0400)
add acpidump utility
intel_idle driver now supports IVB Xeon
turbostat can now count SMIs
ACPI can now bind to USB3 hubs
misc fixes

138 files changed:
Documentation/vfio.txt
MAINTAINERS
Makefile
arch/arm/mach-mxs/mach-mxs.c
arch/arm/mach-orion5x/common.c
arch/arm/mm/dma-mapping.c
arch/c6x/include/asm/Kbuild
arch/c6x/include/asm/barrier.h [deleted file]
arch/tile/include/gxio/iorpc_trio.h
arch/um/include/asm/processor-generic.h
arch/um/include/shared/common-offsets.h
arch/um/include/shared/user.h
arch/um/kernel/exec.c
arch/um/kernel/process.c
arch/um/kernel/signal.c
arch/um/kernel/syscall.c
arch/um/scripts/Makefile.rules
arch/x86/um/Kconfig
arch/x86/um/shared/sysdep/kernel-offsets.h
arch/x86/um/shared/sysdep/syscalls.h
arch/x86/um/signal.c
arch/x86/um/sys_call_table_32.c
arch/x86/um/syscalls_32.c
arch/x86/um/syscalls_64.c
arch/x86/xen/setup.c
drivers/acpi/acpica/Makefile
drivers/acpi/acpica/achware.h
drivers/acpi/acpica/aclocal.h
drivers/acpi/acpica/acmacros.h
drivers/acpi/acpica/dswload.c
drivers/acpi/acpica/dswload2.c
drivers/acpi/acpica/evgpe.c
drivers/acpi/acpica/evxfgpe.c
drivers/acpi/acpica/hwgpe.c
drivers/acpi/acpica/hwxfsleep.c
drivers/acpi/acpica/nsdump.c
drivers/acpi/acpica/tbinstal.c
drivers/acpi/acpica/tbxface.c
drivers/acpi/acpica/utosi.c
drivers/acpi/acpica/utxface.c
drivers/acpi/acpica/utxfinit.c [new file with mode: 0644]
drivers/acpi/button.c
drivers/acpi/fan.c
drivers/acpi/glue.c
drivers/acpi/hed.c
drivers/acpi/proc.c
drivers/acpi/sbshc.c
drivers/acpi/scan.c
drivers/acpi/utils.c
drivers/block/nvme.c
drivers/block/rbd.c
drivers/edac/i3200_edac.c
drivers/edac/i5000_edac.c
drivers/edac/sb_edac.c
drivers/gpio/gpio-lpc32xx.c
drivers/gpu/drm/nouveau/nouveau_abi16.c
drivers/gpu/drm/nouveau/nvc0_fb.c
drivers/gpu/drm/nouveau/nvc0_fifo.c
drivers/gpu/drm/nouveau/nve0_fifo.c
drivers/gpu/drm/udl/udl_connector.c
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
drivers/i2c/busses/i2c-scmi.c
drivers/idle/intel_idle.c
drivers/input/misc/atlas_btns.c
drivers/iommu/amd_iommu.c
drivers/md/dm-mpath.c
drivers/md/dm-table.c
drivers/md/dm-thin.c
drivers/md/dm-verity.c
drivers/md/dm.c
drivers/md/dm.h
drivers/md/raid10.c
drivers/md/raid5.c
drivers/mtd/mtdchar.c
drivers/net/ethernet/broadcom/bnx2.c
drivers/net/ethernet/octeon/octeon_mgmt.c
drivers/net/ethernet/pasemi/pasemi_mac.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
drivers/net/phy/bcm87xx.c
drivers/net/phy/micrel.c
drivers/net/phy/smsc.c
drivers/net/ppp/pppoe.c
drivers/net/team/team.c
drivers/net/usb/smsc75xx.c
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/platform/x86/hp_accel.c
drivers/platform/x86/ideapad-laptop.c
drivers/platform/x86/topstar-laptop.c
drivers/platform/x86/toshiba_bluetooth.c
drivers/platform/x86/xo15-ebook.c
drivers/pnp/pnpacpi/core.c
drivers/sh/pfc/pinctrl.c
drivers/usb/core/devices.c
drivers/usb/core/hcd.c
drivers/usb/core/usb-acpi.c
drivers/usb/host/ohci-at91.c
drivers/vfio/pci/vfio_pci_intrs.c
fs/dcache.c
fs/lockd/svclock.c
fs/namespace.c
include/acpi/acbuffer.h [new file with mode: 0644]
include/acpi/acnames.h
include/acpi/acpi_bus.h
include/acpi/acpixf.h
include/acpi/actbl.h
include/acpi/actbl1.h
include/acpi/actbl2.h
include/acpi/actbl3.h
include/acpi/actypes.h
include/asm-generic/unistd.h
include/linux/iommu.h
include/linux/micrel_phy.h
include/linux/nvme.h
include/linux/security.h
lib/flex_proportions.c
mm/huge_memory.c
net/batman-adv/bat_iv_ogm.c
net/batman-adv/soft-interface.c
net/bluetooth/hci_core.c
net/bluetooth/l2cap_core.c
net/bluetooth/mgmt.c
net/ceph/messenger.c
net/core/sock.c
net/ipv4/inetpeer.c
net/ipv4/raw.c
net/ipv6/mip6.c
net/ipv6/raw.c
net/l2tp/l2tp_netlink.c
net/netfilter/xt_limit.c
net/wireless/reg.c
scripts/checksyscalls.sh
sound/soc/codecs/wm2000.c
sound/usb/endpoint.c
tools/power/acpi/Makefile [new file with mode: 0644]
tools/power/acpi/acpidump.8 [new file with mode: 0644]
tools/power/acpi/acpidump.c [new file with mode: 0644]
tools/power/x86/turbostat/turbostat.8
tools/power/x86/turbostat/turbostat.c

index 0cb6685c802904c0d7becccb00e3a00321bfb928..8eda3635a17da0e8d610a01e88d928a68f833f93 100644 (file)
@@ -133,7 +133,7 @@ character devices for this group:
 $ lspci -n -s 0000:06:0d.0
 06:0d.0 0401: 1102:0002 (rev 08)
 # echo 0000:06:0d.0 > /sys/bus/pci/devices/0000:06:0d.0/driver/unbind
-# echo 1102 0002 > /sys/bus/pci/drivers/vfio/new_id
+# echo 1102 0002 > /sys/bus/pci/drivers/vfio-pci/new_id
 
 Now we need to look at what other devices are in the group to free
 it for use by VFIO:
index b17587d9412f04318dab5e7368f6e5306ca57b91..9a6c4da3b2ff2cd77e4ee01a631a9cf9433b4017 100644 (file)
@@ -3552,11 +3552,12 @@ K:      \b(ABS|SYN)_MT_
 
 INTEL C600 SERIES SAS CONTROLLER DRIVER
 M:     Intel SCU Linux support <intel-linux-scu@intel.com>
+M:     Lukasz Dorau <lukasz.dorau@intel.com>
+M:     Maciej Patelczyk <maciej.patelczyk@intel.com>
 M:     Dave Jiang <dave.jiang@intel.com>
-M:     Ed Nadolski <edmund.nadolski@intel.com>
 L:     linux-scsi@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/djbw/isci.git
-S:     Maintained
+T:     git git://git.code.sf.net/p/intel-sas/isci
+S:     Supported
 F:     drivers/scsi/isci/
 F:     firmware/isci/
 
@@ -5544,6 +5545,8 @@ F:        Documentation/devicetree/bindings/pwm/
 F:     include/linux/pwm.h
 F:     include/linux/of_pwm.h
 F:     drivers/pwm/
+F:     drivers/video/backlight/pwm_bl.c
+F:     include/linux/pwm_backlight.h
 
 PXA2xx/PXA3xx SUPPORT
 M:     Eric Miao <eric.y.miao@gmail.com>
index a3c11d589681d9a53db5cf31ca8a4e1c1b9246a5..bb9fff26f078063c395fe8f86488349614c84261 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 6
 SUBLEVEL = 0
-EXTRAVERSION = -rc7
+EXTRAVERSION =
 NAME = Terrified Chipmunk
 
 # *DOCUMENTATION*
index 8dabfe81d07c5f143626f10c57cfb993e87c6a1a..ff886e01a0b0371367ae49f3d0d323e547845478 100644 (file)
@@ -261,7 +261,7 @@ static void __init apx4devkit_init(void)
        enable_clk_enet_out();
 
        if (IS_BUILTIN(CONFIG_PHYLIB))
-               phy_register_fixup_for_uid(PHY_ID_KS8051, MICREL_PHY_ID_MASK,
+               phy_register_fixup_for_uid(PHY_ID_KSZ8051, MICREL_PHY_ID_MASK,
                                           apx4devkit_phy_fixup);
 
        mxsfb_pdata.mode_list = apx4devkit_video_modes;
index 410291c676668befcfe5b43723af071ba153e5db..a6cd14ab1e4e6f4c27103baf780df091de0cfb93 100644 (file)
@@ -204,6 +204,13 @@ void __init orion5x_wdt_init(void)
 void __init orion5x_init_early(void)
 {
        orion_time_set_base(TIMER_VIRT_BASE);
+
+       /*
+        * Some Orion5x devices allocate their coherent buffers from atomic
+        * context. Increase size of atomic coherent pool to make sure such
+        * the allocations won't fail.
+        */
+       init_dma_coherent_pool_size(SZ_1M);
 }
 
 int orion5x_tclk;
index e59c4ab71bcb78282f968cebbda09c43b49809ff..13f555d62491e59fbae0127f89e3f2b2395d3abf 100644 (file)
@@ -346,6 +346,8 @@ static int __init atomic_pool_init(void)
                       (unsigned)pool->size / 1024);
                return 0;
        }
+
+       kfree(pages);
 no_pages:
        kfree(bitmap);
 no_bitmap:
index 3af601e31e66ea5180ee498b04009c431f33e989..f08e89183cda452844fda74bc27a4db8823647d1 100644 (file)
@@ -2,6 +2,7 @@ include include/asm-generic/Kbuild.asm
 
 generic-y += atomic.h
 generic-y += auxvec.h
+generic-y += barrier.h
 generic-y += bitsperlong.h
 generic-y += bugs.h
 generic-y += cputime.h
diff --git a/arch/c6x/include/asm/barrier.h b/arch/c6x/include/asm/barrier.h
deleted file mode 100644 (file)
index 538240e..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *  Port on Texas Instruments TMS320C6x architecture
- *
- *  Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
- *  Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- */
-#ifndef _ASM_C6X_BARRIER_H
-#define _ASM_C6X_BARRIER_H
-
-#define nop()                    asm("NOP\n");
-
-#define mb()                     barrier()
-#define rmb()                    barrier()
-#define wmb()                    barrier()
-#define set_mb(var, value)       do { var = value;  mb(); } while (0)
-#define set_wmb(var, value)      do { var = value; wmb(); } while (0)
-
-#define smp_mb()                barrier()
-#define smp_rmb()               barrier()
-#define smp_wmb()               barrier()
-#define smp_read_barrier_depends()     do { } while (0)
-
-#endif /* _ASM_C6X_BARRIER_H */
index 15fb779920831eb38b110ec5530b1562d647171b..58105c31228b3b6643783e926b2db7886739ba01 100644 (file)
 #include <linux/module.h>
 #include <asm/pgtable.h>
 
-#define GXIO_TRIO_OP_ALLOC_ASIDS       IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1400)
+#define GXIO_TRIO_OP_DEALLOC_ASID      IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1400)
+#define GXIO_TRIO_OP_ALLOC_ASIDS       IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1401)
 
-#define GXIO_TRIO_OP_ALLOC_MEMORY_MAPS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1402)
+#define GXIO_TRIO_OP_ALLOC_MEMORY_MAPS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1404)
 
-#define GXIO_TRIO_OP_ALLOC_PIO_REGIONS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x140e)
-#define GXIO_TRIO_OP_INIT_PIO_REGION_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x140f)
+#define GXIO_TRIO_OP_ALLOC_PIO_REGIONS IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1412)
 
-#define GXIO_TRIO_OP_INIT_MEMORY_MAP_MMU_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1417)
-#define GXIO_TRIO_OP_GET_PORT_PROPERTY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1418)
-#define GXIO_TRIO_OP_CONFIG_LEGACY_INTR IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1419)
-#define GXIO_TRIO_OP_CONFIG_MSI_INTR   IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x141a)
+#define GXIO_TRIO_OP_INIT_PIO_REGION_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1414)
 
-#define GXIO_TRIO_OP_SET_MPS_MRS       IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141c)
-#define GXIO_TRIO_OP_FORCE_RC_LINK_UP  IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141d)
-#define GXIO_TRIO_OP_FORCE_EP_LINK_UP  IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141e)
+#define GXIO_TRIO_OP_INIT_MEMORY_MAP_MMU_AUX IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141e)
+#define GXIO_TRIO_OP_GET_PORT_PROPERTY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x141f)
+#define GXIO_TRIO_OP_CONFIG_LEGACY_INTR IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1420)
+#define GXIO_TRIO_OP_CONFIG_MSI_INTR   IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1421)
+
+#define GXIO_TRIO_OP_SET_MPS_MRS       IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1423)
+#define GXIO_TRIO_OP_FORCE_RC_LINK_UP  IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1424)
+#define GXIO_TRIO_OP_FORCE_EP_LINK_UP  IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1425)
 #define GXIO_TRIO_OP_GET_MMIO_BASE     IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
 #define GXIO_TRIO_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001)
 
index 69f1c57a8d0dc895c727b74e1a53f8acd6c94a4c..33a6a2423bd25638a2b93f20fdc77bcf6e0f1737 100644 (file)
@@ -20,14 +20,6 @@ struct mm_struct;
 
 struct thread_struct {
        struct task_struct *saved_task;
-       /*
-        * This flag is set to 1 before calling do_fork (and analyzed in
-        * copy_thread) to mark that we are begin called from userspace (fork /
-        * vfork / clone), and reset to 0 after. It is left to 0 when called
-        * from kernelspace (i.e. kernel_thread() or fork_idle(),
-        * as of 2.6.11).
-        */
-       int forking;
        struct pt_regs regs;
        int singlestep_syscall;
        void *fault_addr;
@@ -58,7 +50,6 @@ struct thread_struct {
 
 #define INIT_THREAD \
 { \
-       .forking                = 0, \
        .regs                   = EMPTY_REGS,   \
        .fault_addr             = NULL, \
        .prev_sched             = NULL, \
index 40db8f71deaef4eb19c10a09e4f01d51078d3c8d..2df313b6a586c82b6e1dec743d174b0ddd190a9e 100644 (file)
@@ -7,16 +7,6 @@ DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK);
 DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT);
 DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
 
-DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
-DEFINE_STR(UM_KERN_ALERT, KERN_ALERT);
-DEFINE_STR(UM_KERN_CRIT, KERN_CRIT);
-DEFINE_STR(UM_KERN_ERR, KERN_ERR);
-DEFINE_STR(UM_KERN_WARNING, KERN_WARNING);
-DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
-DEFINE_STR(UM_KERN_INFO, KERN_INFO);
-DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
-DEFINE_STR(UM_KERN_CONT, KERN_CONT);
-
 DEFINE(UM_ELF_CLASS, ELF_CLASS);
 DEFINE(UM_ELFCLASS32, ELFCLASS32);
 DEFINE(UM_ELFCLASS64, ELFCLASS64);
index 4fa82c055aab8d53576b06787aa1033644a16697..cef0685633369c05b6020f6071ae1a2ff094173a 100644 (file)
 extern void panic(const char *fmt, ...)
        __attribute__ ((format (printf, 1, 2)));
 
+/* Requires preincluding include/linux/kern_levels.h */
+#define UM_KERN_EMERG  KERN_EMERG
+#define UM_KERN_ALERT  KERN_ALERT
+#define UM_KERN_CRIT   KERN_CRIT
+#define UM_KERN_ERR    KERN_ERR
+#define UM_KERN_WARNING        KERN_WARNING
+#define UM_KERN_NOTICE KERN_NOTICE
+#define UM_KERN_INFO   KERN_INFO
+#define UM_KERN_DEBUG  KERN_DEBUG
+#define UM_KERN_CONT   KERN_CONT
+
 #ifdef UML_CONFIG_PRINTK
 extern int printk(const char *fmt, ...)
        __attribute__ ((format (printf, 1, 2)));
index 6cade9366364d03f2fd58e2cee85336ffdea56e5..8c82786da823df2cdf53ad9361b9b950d85018c7 100644 (file)
@@ -39,34 +39,21 @@ void flush_thread(void)
 
 void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
 {
+       get_safe_registers(regs->regs.gp, regs->regs.fp);
        PT_REGS_IP(regs) = eip;
        PT_REGS_SP(regs) = esp;
-}
-EXPORT_SYMBOL(start_thread);
-
-static long execve1(const char *file,
-                   const char __user *const __user *argv,
-                   const char __user *const __user *env)
-{
-       long error;
-
-       error = do_execve(file, argv, env, &current->thread.regs);
-       if (error == 0) {
-               task_lock(current);
-               current->ptrace &= ~PT_DTRACE;
+       current->ptrace &= ~PT_DTRACE;
 #ifdef SUBARCH_EXECVE1
-               SUBARCH_EXECVE1(&current->thread.regs.regs);
+       SUBARCH_EXECVE1(regs->regs);
 #endif
-               task_unlock(current);
-       }
-       return error;
 }
+EXPORT_SYMBOL(start_thread);
 
 long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env)
 {
        long err;
 
-       err = execve1(file, argv, env);
+       err = do_execve(file, argv, env, &current->thread.regs);
        if (!err)
                UML_LONGJMP(current->thread.exec_buf, 1);
        return err;
@@ -81,7 +68,7 @@ long sys_execve(const char __user *file, const char __user *const __user *argv,
        filename = getname(file);
        error = PTR_ERR(filename);
        if (IS_ERR(filename)) goto out;
-       error = execve1(filename, argv, env);
+       error = do_execve(filename, argv, env, &current->thread.regs);
        putname(filename);
  out:
        return error;
index 57fc7028714a51af6fc19952d0947a913523ccec..c5f5afa5074571c2b5872bc157c9f199a80c9f5b 100644 (file)
@@ -181,11 +181,12 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
                struct pt_regs *regs)
 {
        void (*handler)(void);
+       int kthread = current->flags & PF_KTHREAD;
        int ret = 0;
 
        p->thread = (struct thread_struct) INIT_THREAD;
 
-       if (current->thread.forking) {
+       if (!kthread) {
                memcpy(&p->thread.regs.regs, &regs->regs,
                       sizeof(p->thread.regs.regs));
                PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0);
@@ -195,8 +196,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
                handler = fork_handler;
 
                arch_copy_thread(&current->thread.arch, &p->thread.arch);
-       }
-       else {
+       } else {
                get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
                p->thread.request.u.thread = current->thread.request.u.thread;
                handler = new_thread_handler;
@@ -204,7 +204,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
 
        new_thread(task_stack_page(p), &p->thread.switch_buf, handler);
 
-       if (current->thread.forking) {
+       if (!kthread) {
                clear_flushed_tls(p);
 
                /*
index 7362d58efc29612c1ffaad64558b3a986b820515..cc9c2350e41741647f074cc4f43d6c4e3599123f 100644 (file)
@@ -22,9 +22,13 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
                         struct k_sigaction *ka, siginfo_t *info)
 {
        sigset_t *oldset = sigmask_to_save();
+       int singlestep = 0;
        unsigned long sp;
        int err;
 
+       if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
+               singlestep = 1;
+
        /* Did we come from a system call? */
        if (PT_REGS_SYSCALL_NR(regs) >= 0) {
                /* If so, check system call restarting.. */
@@ -61,7 +65,7 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
        if (err)
                force_sigsegv(signr, current);
        else
-               signal_delivered(signr, info, ka, regs, 0);
+               signal_delivered(signr, info, ka, regs, singlestep);
 }
 
 static int kern_do_signal(struct pt_regs *regs)
index f958cb876ee3d3e47ddff71094e8026c0a110f5d..a4c6d8eee74c702999cc26955e250f40db30f553 100644 (file)
 
 long sys_fork(void)
 {
-       long ret;
-
-       current->thread.forking = 1;
-       ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
+       return do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
                      &current->thread.regs, 0, NULL, NULL);
-       current->thread.forking = 0;
-       return ret;
 }
 
 long sys_vfork(void)
 {
-       long ret;
-
-       current->thread.forking = 1;
-       ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
+       return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
                      UPT_SP(&current->thread.regs.regs),
                      &current->thread.regs, 0, NULL, NULL);
-       current->thread.forking = 0;
-       return ret;
+}
+
+long sys_clone(unsigned long clone_flags, unsigned long newsp,
+              void __user *parent_tid, void __user *child_tid)
+{
+       if (!newsp)
+               newsp = UPT_SP(&current->thread.regs.regs);
+
+       return do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
+                     child_tid);
 }
 
 long old_mmap(unsigned long addr, unsigned long len,
index d50270d26b427ace5d5f7c8777094298859a54c3..15889df9b4663771ccddc00f7e0275645ceceb0f 100644 (file)
@@ -8,7 +8,7 @@ USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m)  $(USER_SINGLE_OBJS))
 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
 
 $(USER_OBJS:.o=.%): \
-       c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) -include user.h $(CFLAGS_$(basetarget).o)
+       c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) -include $(srctree)/include/linux/kern_levels.h -include user.h $(CFLAGS_$(basetarget).o)
 
 # These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of
 # using it directly.
index 9926e11a772dbe9b5417fa204407c2ec9ee58878..aeaff8bef2f162642ef4ad31603a301384f4b1fe 100644 (file)
@@ -21,6 +21,7 @@ config 64BIT
 config X86_32
        def_bool !64BIT
        select HAVE_AOUT
+       select ARCH_WANT_IPC_PARSE_VERSION
 
 config X86_64
        def_bool 64BIT
index 5868526b5eefa3017b784ad1a48c45b6be7ceacf..46a9df99f3c5c952601d7f153adf6bf8c1e3e937 100644 (file)
@@ -7,9 +7,6 @@
 #define DEFINE(sym, val) \
        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
 
-#define STR(x) #x
-#define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " STR(val) " " #val: : )
-
 #define BLANK() asm volatile("\n->" : : )
 
 #define OFFSET(sym, str, mem) \
index bd9a89b67e41f20bdd17b2f38f5c9543ef28c7b1..ca255a805ed936ea059312b0990e884bb2b07e1b 100644 (file)
@@ -1,3 +1,5 @@
+extern long sys_clone(unsigned long clone_flags, unsigned long newsp,
+              void __user *parent_tid, void __user *child_tid);
 #ifdef __i386__
 #include "syscalls_32.h"
 #else
index a508cea135033eba3c1c7facba8aebd04a1a0983..ba7363ecf896598c21534af5d09ef1c32e275668 100644 (file)
@@ -416,9 +416,6 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
        PT_REGS_AX(regs) = (unsigned long) sig;
        PT_REGS_DX(regs) = (unsigned long) 0;
        PT_REGS_CX(regs) = (unsigned long) 0;
-
-       if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
-               ptrace_notify(SIGTRAP);
        return 0;
 }
 
@@ -466,9 +463,6 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
        PT_REGS_AX(regs) = (unsigned long) sig;
        PT_REGS_DX(regs) = (unsigned long) &frame->info;
        PT_REGS_CX(regs) = (unsigned long) &frame->uc;
-
-       if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
-               ptrace_notify(SIGTRAP);
        return 0;
 }
 
index 68d1dc91b37badeaeff9fe517a06df2be6484f8a..b5408cecac6cd68f5f649b0a45749c1fdab40d77 100644 (file)
@@ -28,7 +28,7 @@
 #define ptregs_execve sys_execve
 #define ptregs_iopl sys_iopl
 #define ptregs_vm86old sys_vm86old
-#define ptregs_clone sys_clone
+#define ptregs_clone i386_clone
 #define ptregs_vm86 sys_vm86
 #define ptregs_sigaltstack sys_sigaltstack
 #define ptregs_vfork sys_vfork
index b853e8600b9dc1d00e74151a7e16b8af61a8bfda..db444c7218fe53bcabf105b5e2303b7d21a5fd15 100644 (file)
@@ -3,37 +3,24 @@
  * Licensed under the GPL
  */
 
-#include "linux/sched.h"
-#include "linux/shm.h"
-#include "linux/ipc.h"
-#include "linux/syscalls.h"
-#include "asm/mman.h"
-#include "asm/uaccess.h"
-#include "asm/unistd.h"
+#include <linux/syscalls.h>
+#include <sysdep/syscalls.h>
 
 /*
  * The prototype on i386 is:
  *
- *     int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr)
+ *     int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls
  *
  * and the "newtls" arg. on i386 is read by copy_thread directly from the
  * register saved on the stack.
  */
-long sys_clone(unsigned long clone_flags, unsigned long newsp,
-              int __user *parent_tid, void *newtls, int __user *child_tid)
+long i386_clone(unsigned long clone_flags, unsigned long newsp,
+               int __user *parent_tid, void *newtls, int __user *child_tid)
 {
-       long ret;
-
-       if (!newsp)
-               newsp = UPT_SP(&current->thread.regs.regs);
-
-       current->thread.forking = 1;
-       ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
-                     child_tid);
-       current->thread.forking = 0;
-       return ret;
+       return sys_clone(clone_flags, newsp, parent_tid, child_tid);
 }
 
+
 long sys_sigaction(int sig, const struct old_sigaction __user *act,
                         struct old_sigaction __user *oact)
 {
index f3d82bb6e15a410b5e706617526efe9d56a42243..adb08eb5c22a38710299d3e1a05b3b55e2ee7e63 100644 (file)
@@ -5,12 +5,9 @@
  * Licensed under the GPL
  */
 
-#include "linux/linkage.h"
-#include "linux/personality.h"
-#include "linux/utsname.h"
-#include "asm/prctl.h" /* XXX This should get the constants from libc */
-#include "asm/uaccess.h"
-#include "os.h"
+#include <linux/sched.h>
+#include <asm/prctl.h> /* XXX This should get the constants from libc */
+#include <os.h>
 
 long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
 {
@@ -79,20 +76,6 @@ long sys_arch_prctl(int code, unsigned long addr)
        return arch_prctl(current, code, (unsigned long __user *) addr);
 }
 
-long sys_clone(unsigned long clone_flags, unsigned long newsp,
-              void __user *parent_tid, void __user *child_tid)
-{
-       long ret;
-
-       if (!newsp)
-               newsp = UPT_SP(&current->thread.regs.regs);
-       current->thread.forking = 1;
-       ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
-                     child_tid);
-       current->thread.forking = 0;
-       return ret;
-}
-
 void arch_switch_to(struct task_struct *to)
 {
        if ((to->thread.arch.fs == 0) || (to->mm == NULL))
index d11ca11d14fc094379e989a6b06fe2e5b2bc72e6..e2d62d697b5dffc60ad6ea53e2ad3f1ce33282a3 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/e820.h>
 #include <asm/setup.h>
 #include <asm/acpi.h>
+#include <asm/numa.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
 
@@ -544,4 +545,7 @@ void __init xen_arch_setup(void)
        disable_cpufreq();
        WARN_ON(set_pm_idle_to_default());
        fiddle_vdso();
+#ifdef CONFIG_NUMA
+       numa_off = 1;
+#endif
 }
index 0a1b3435f920af3be09813330191aa3b179de2e2..7f1d40797e80a20608851c011bd7815185a52a68 100644 (file)
@@ -158,5 +158,6 @@ acpi-y +=           \
        utresrc.o       \
        utstate.o       \
        utxface.o       \
+       utxfinit.o      \
        utxferror.o     \
        utxfmutex.o
index 5de4ec72766d653924068cb6887d07573ef93539..d902d31abc6c5ec1957b14990cf3a4f57e13f7a0 100644 (file)
@@ -110,8 +110,7 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width);
 /*
  * hwgpe - GPE support
  */
-u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
-                            struct acpi_gpe_register_info *gpe_register_info);
+u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info);
 
 acpi_status
 acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action);
index cc80fe10e8ea916cf03a24bf4fce2a1f8e838f3b..c816ee675094e326a142e83dd4fd6bf0a7edef7c 100644 (file)
@@ -707,15 +707,18 @@ union acpi_parse_value {
        u8                              disasm_opcode;  /* Subtype used for disassembly */\
        char                            aml_op_name[16])        /* Op name (debug only) */
 
-#define ACPI_DASM_BUFFER                0x00
-#define ACPI_DASM_RESOURCE              0x01
-#define ACPI_DASM_STRING                0x02
-#define ACPI_DASM_UNICODE               0x03
-#define ACPI_DASM_EISAID                0x04
-#define ACPI_DASM_MATCHOP               0x05
-#define ACPI_DASM_LNOT_PREFIX           0x06
-#define ACPI_DASM_LNOT_SUFFIX           0x07
-#define ACPI_DASM_IGNORE                0x08
+/* Flags for disasm_flags field above */
+
+#define ACPI_DASM_BUFFER                0x00   /* Buffer is a simple data buffer */
+#define ACPI_DASM_RESOURCE              0x01   /* Buffer is a Resource Descriptor */
+#define ACPI_DASM_STRING                0x02   /* Buffer is a ASCII string */
+#define ACPI_DASM_UNICODE               0x03   /* Buffer is a Unicode string */
+#define ACPI_DASM_PLD_METHOD            0x04   /* Buffer is a _PLD method bit-packed buffer */
+#define ACPI_DASM_EISAID                0x05   /* Integer is an EISAID */
+#define ACPI_DASM_MATCHOP               0x06   /* Parent opcode is a Match() operator */
+#define ACPI_DASM_LNOT_PREFIX           0x07   /* Start of a Lnot_equal (etc.) pair of opcodes */
+#define ACPI_DASM_LNOT_SUFFIX           0x08   /* End  of a Lnot_equal (etc.) pair of opcodes */
+#define ACPI_DASM_IGNORE                0x09   /* Not used at this time */
 
 /*
  * Generic operation (for example:  If, While, Store)
@@ -932,6 +935,7 @@ struct acpi_bit_register_info {
 #define ACPI_OSI_WIN_VISTA_SP1          0x09
 #define ACPI_OSI_WIN_VISTA_SP2          0x0A
 #define ACPI_OSI_WIN_7                  0x0B
+#define ACPI_OSI_WIN_8                  0x0C
 
 #define ACPI_ALWAYS_ILLEGAL             0x00
 
@@ -1024,6 +1028,7 @@ struct acpi_port_info {
  ****************************************************************************/
 
 struct acpi_db_method_info {
+       acpi_handle method;
        acpi_handle main_thread_gate;
        acpi_handle thread_complete_gate;
        acpi_thread_id *threads;
index 832b6198652e0540a606047c782f5a74b528b447..a7f68c47f517b169d1cc2d4bbe49853a89b5264e 100644 (file)
 
 /* Bitfields within ACPI registers */
 
-#define ACPI_REGISTER_PREPARE_BITS(val, pos, mask)      ((val << pos) & mask)
-#define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val)  reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask)
+#define ACPI_REGISTER_PREPARE_BITS(val, pos, mask) \
+       ((val << pos) & mask)
 
-#define ACPI_INSERT_BITS(target, mask, source)          target = ((target & (~(mask))) | (source & mask))
+#define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val) \
+       reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask)
+
+#define ACPI_INSERT_BITS(target, mask, source) \
+       target = ((target & (~(mask))) | (source & mask))
+
+/* Generic bitfield macros and masks */
+
+#define ACPI_GET_BITS(source_ptr, position, mask) \
+       ((*source_ptr >> position) & mask)
+
+#define ACPI_SET_BITS(target_ptr, position, mask, value) \
+       (*target_ptr |= ((value & mask) << position))
+
+#define ACPI_1BIT_MASK      0x00000001
+#define ACPI_2BIT_MASK      0x00000003
+#define ACPI_3BIT_MASK      0x00000007
+#define ACPI_4BIT_MASK      0x0000000F
+#define ACPI_5BIT_MASK      0x0000001F
+#define ACPI_6BIT_MASK      0x0000003F
+#define ACPI_7BIT_MASK      0x0000007F
+#define ACPI_8BIT_MASK      0x000000FF
+#define ACPI_16BIT_MASK     0x0000FFFF
+#define ACPI_24BIT_MASK     0x00FFFFFF
 
 /*
  * An object of type struct acpi_namespace_node can appear in some contexts
index 552aa3a50c84882ce9c9aa152d1b231bf7f6cd20..557510084c7aca459fb24ace485dd89c98aa26bc 100644 (file)
@@ -230,6 +230,20 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
                        walk_state->scope_info->common.value = ACPI_TYPE_ANY;
                        break;
 
+               case ACPI_TYPE_METHOD:
+
+                       /*
+                        * Allow scope change to root during execution of module-level
+                        * code. Root is typed METHOD during this time.
+                        */
+                       if ((node == acpi_gbl_root_node) &&
+                           (walk_state->
+                            parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
+                               break;
+                       }
+
+                       /*lint -fallthrough */
+
                default:
 
                        /* All other types are an error */
index ae71477247631074fcc627b1345e307e77b334a9..89c0114210c0f32e0a3f7edf3e3d1961aa4e4a5f 100644 (file)
@@ -230,6 +230,20 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
                        walk_state->scope_info->common.value = ACPI_TYPE_ANY;
                        break;
 
+               case ACPI_TYPE_METHOD:
+
+                       /*
+                        * Allow scope change to root during execution of module-level
+                        * code. Root is typed METHOD during this time.
+                        */
+                       if ((node == acpi_gbl_root_node) &&
+                           (walk_state->
+                            parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
+                               break;
+                       }
+
+                       /*lint -fallthrough */
+
                default:
 
                        /* All other types are an error */
index afbd5cb391f671eeedef586c3c6aa515fd8eba62..ef0193d74b5db8f08a45519fbf64a639e872bca5 100644 (file)
@@ -80,8 +80,7 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info)
                return_ACPI_STATUS(AE_NOT_EXIST);
        }
 
-       register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
-                                               gpe_register_info);
+       register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
 
        /* Clear the run bit up front */
 
@@ -379,6 +378,18 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
                         */
                        if (!(gpe_register_info->enable_for_run |
                              gpe_register_info->enable_for_wake)) {
+                               ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
+                                                 "Ignore disabled registers for GPE%02X-GPE%02X: "
+                                                 "RunEnable=%02X, WakeEnable=%02X\n",
+                                                 gpe_register_info->
+                                                 base_gpe_number,
+                                                 gpe_register_info->
+                                                 base_gpe_number +
+                                                 (ACPI_GPE_REGISTER_WIDTH - 1),
+                                                 gpe_register_info->
+                                                 enable_for_run,
+                                                 gpe_register_info->
+                                                 enable_for_wake));
                                continue;
                        }
 
@@ -401,9 +412,14 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
                        }
 
                        ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
-                                         "Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n",
+                                         "Read registers for GPE%02X-GPE%02X: Status=%02X, Enable=%02X, "
+                                         "RunEnable=%02X, WakeEnable=%02X\n",
                                          gpe_register_info->base_gpe_number,
-                                         status_reg, enable_reg));
+                                         gpe_register_info->base_gpe_number +
+                                         (ACPI_GPE_REGISTER_WIDTH - 1),
+                                         status_reg, enable_reg,
+                                         gpe_register_info->enable_for_run,
+                                         gpe_register_info->enable_for_wake));
 
                        /* Check if there is anything active at all in this register */
 
index 6affbdb4b88c930567f8c3a852b8c051fbbb0dbf..87c5f2332260d740f07d394010a19c261dc488b0 100644 (file)
@@ -357,8 +357,7 @@ acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 ac
                goto unlock_and_exit;
        }
 
-       register_bit =
-           acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
+       register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
 
        /* Perform the action */
 
index 25bd28c4ae8d0055afa5fe44779b123508579fbd..db4076580e2b38d5fd22c7178b1663de5c0d379b 100644 (file)
@@ -60,7 +60,6 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
  * FUNCTION:   acpi_hw_get_gpe_register_bit
  *
  * PARAMETERS: gpe_event_info      - Info block for the GPE
- *             gpe_register_info   - Info block for the GPE register
  *
  * RETURN:     Register mask with a one in the GPE bit position
  *
@@ -69,11 +68,10 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
  *
  ******************************************************************************/
 
-u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
-                            struct acpi_gpe_register_info *gpe_register_info)
+u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info)
 {
        return (u32)1 << (gpe_event_info->gpe_number -
-                               gpe_register_info->base_gpe_number);
+                gpe_event_info->register_info->base_gpe_number);
 }
 
 /******************************************************************************
@@ -115,8 +113,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
 
        /* Set or clear just the bit that corresponds to this GPE */
 
-       register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
-                                               gpe_register_info);
+       register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
        switch (action) {
        case ACPI_GPE_CONDITIONAL_ENABLE:
 
@@ -178,8 +175,7 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
         * Write a one to the appropriate bit in the status register to
         * clear this GPE.
         */
-       register_bit =
-           acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
+       register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
 
        status = acpi_hw_write(register_bit,
                               &gpe_register_info->status_address);
@@ -222,8 +218,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
 
        /* Get the register bitmask for this GPE */
 
-       register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
-                                               gpe_register_info);
+       register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
 
        /* GPE currently enabled? (enabled for runtime?) */
 
index 1f165a750ae28736ca5066c908d5ade37ba4740e..0ff1ecea5c3ae9844b1f2e12e1e159932a26433c 100644 (file)
@@ -381,7 +381,6 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state)
  * FUNCTION:    acpi_leave_sleep_state_prep
  *
  * PARAMETERS:  sleep_state         - Which sleep state we are exiting
- *              flags               - ACPI_EXECUTE_BFS to run optional method
  *
  * RETURN:      Status
  *
index 7ee4e6aeb0a2da82d219a7fdac501efb83338daa..2526aaf945ee20510cf3cd7d7dab1bdea646c354 100644 (file)
@@ -264,7 +264,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
                switch (type) {
                case ACPI_TYPE_PROCESSOR:
 
-                       acpi_os_printf("ID %X Len %.4X Addr %p\n",
+                       acpi_os_printf("ID %02X Len %02X Addr %p\n",
                                       obj_desc->processor.proc_id,
                                       obj_desc->processor.length,
                                       ACPI_CAST_PTR(void,
index 74f97d74db1c7772bf79bc39eb0daea11ebf3049..70f9d787c82cd9e8af9ae6fbd19d4d5a7cee2ac0 100644 (file)
@@ -350,6 +350,7 @@ struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header
 acpi_status acpi_tb_resize_root_table_list(void)
 {
        struct acpi_table_desc *tables;
+       u32 table_count;
 
        ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
 
@@ -363,8 +364,13 @@ acpi_status acpi_tb_resize_root_table_list(void)
 
        /* Increase the Table Array size */
 
-       tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
-                                      max_table_count +
+       if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
+               table_count = acpi_gbl_root_table_list.max_table_count;
+       } else {
+               table_count = acpi_gbl_root_table_list.current_table_count;
+       }
+
+       tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count +
                                       ACPI_ROOT_TABLE_SIZE_INCREMENT) *
                                      sizeof(struct acpi_table_desc));
        if (!tables) {
@@ -377,8 +383,8 @@ acpi_status acpi_tb_resize_root_table_list(void)
 
        if (acpi_gbl_root_table_list.tables) {
                ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
-                           (acpi_size) acpi_gbl_root_table_list.
-                           max_table_count * sizeof(struct acpi_table_desc));
+                           (acpi_size) table_count *
+                           sizeof(struct acpi_table_desc));
 
                if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
                        ACPI_FREE(acpi_gbl_root_table_list.tables);
@@ -386,9 +392,9 @@ acpi_status acpi_tb_resize_root_table_list(void)
        }
 
        acpi_gbl_root_table_list.tables = tables;
-       acpi_gbl_root_table_list.max_table_count +=
-           ACPI_ROOT_TABLE_SIZE_INCREMENT;
-       acpi_gbl_root_table_list.flags |= (u8)ACPI_ROOT_ORIGIN_ALLOCATED;
+       acpi_gbl_root_table_list.max_table_count =
+           table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
+       acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
 
        return_ACPI_STATUS(AE_OK);
 }
index 29e51bc013838c5d33cf1df0089331ae3380951b..21101262e47a1a4fd33f7cdf1b4973647571e435 100644 (file)
@@ -159,14 +159,12 @@ acpi_initialize_tables(struct acpi_table_desc * initial_table_array,
  * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
  *              root list from the previously provided scratch area. Should
  *              be called once dynamic memory allocation is available in the
- *              kernel
+ *              kernel.
  *
  ******************************************************************************/
 acpi_status acpi_reallocate_root_table(void)
 {
-       struct acpi_table_desc *tables;
-       acpi_size new_size;
-       acpi_size current_size;
+       acpi_status status;
 
        ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);
 
@@ -178,39 +176,10 @@ acpi_status acpi_reallocate_root_table(void)
                return_ACPI_STATUS(AE_SUPPORT);
        }
 
-       /*
-        * Get the current size of the root table and add the default
-        * increment to create the new table size.
-        */
-       current_size = (acpi_size)
-           acpi_gbl_root_table_list.current_table_count *
-           sizeof(struct acpi_table_desc);
-
-       new_size = current_size +
-           (ACPI_ROOT_TABLE_SIZE_INCREMENT * sizeof(struct acpi_table_desc));
-
-       /* Create new array and copy the old array */
-
-       tables = ACPI_ALLOCATE_ZEROED(new_size);
-       if (!tables) {
-               return_ACPI_STATUS(AE_NO_MEMORY);
-       }
+       acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE;
 
-       ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, current_size);
-
-       /*
-        * Update the root table descriptor. The new size will be the current
-        * number of tables plus the increment, independent of the reserved
-        * size of the original table list.
-        */
-       acpi_gbl_root_table_list.tables = tables;
-       acpi_gbl_root_table_list.max_table_count =
-           acpi_gbl_root_table_list.current_table_count +
-           ACPI_ROOT_TABLE_SIZE_INCREMENT;
-       acpi_gbl_root_table_list.flags =
-           ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE;
-
-       return_ACPI_STATUS(AE_OK);
+       status = acpi_tb_resize_root_table_list();
+       return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
index 34ef0bd7e4b414286fe191e1f4ab3df27f958b0e..676285d6116d3b55bd57478bac58a8b780c368aa 100644 (file)
@@ -73,6 +73,7 @@ static struct acpi_interface_info acpi_default_supported_interfaces[] = {
        {"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1},  /* Windows Vista SP1 - Added 09/2009 */
        {"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2},  /* Windows Vista SP2 - Added 09/2010 */
        {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7},      /* Windows 7 and Server 2008 R2 - Added 09/2009 */
+       {"Windows 2012", NULL, 0, ACPI_OSI_WIN_8},      /* Windows 8 and Server 2012 - Added 08/2012 */
 
        /* Feature Group Strings */
 
index 534179f1177bf49239dc3561d7f29ac5422a6594..b09632b4f5b3faacabbe29c637334788cb85857a 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Module Name: utxface - External interfaces for "global" ACPI functions
+ * Module Name: utxface - External interfaces, miscellaneous utility functions
  *
  *****************************************************************************/
 
 #define _COMPONENT          ACPI_UTILITIES
 ACPI_MODULE_NAME("utxface")
 
-#ifndef ACPI_ASL_COMPILER
-/*******************************************************************************
- *
- * FUNCTION:    acpi_initialize_subsystem
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Initializes all global variables.  This is the first function
- *              called, so any early initialization belongs here.
- *
- ******************************************************************************/
-acpi_status __init acpi_initialize_subsystem(void)
-{
-       acpi_status status;
-
-       ACPI_FUNCTION_TRACE(acpi_initialize_subsystem);
-
-       acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE;
-       ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace());
-
-       /* Initialize the OS-Dependent layer */
-
-       status = acpi_os_initialize();
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status, "During OSL initialization"));
-               return_ACPI_STATUS(status);
-       }
-
-       /* Initialize all globals used by the subsystem */
-
-       status = acpi_ut_init_globals();
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status,
-                               "During initialization of globals"));
-               return_ACPI_STATUS(status);
-       }
-
-       /* Create the default mutex objects */
-
-       status = acpi_ut_mutex_initialize();
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status,
-                               "During Global Mutex creation"));
-               return_ACPI_STATUS(status);
-       }
-
-       /*
-        * Initialize the namespace manager and
-        * the root of the namespace tree
-        */
-       status = acpi_ns_root_initialize();
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status,
-                               "During Namespace initialization"));
-               return_ACPI_STATUS(status);
-       }
-
-       /* Initialize the global OSI interfaces list with the static names */
-
-       status = acpi_ut_initialize_interfaces();
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status,
-                               "During OSI interfaces initialization"));
-               return_ACPI_STATUS(status);
-       }
-
-       /* If configured, initialize the AML debugger */
-
-       ACPI_DEBUGGER_EXEC(status = acpi_db_initialize());
-       return_ACPI_STATUS(status);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_enable_subsystem
- *
- * PARAMETERS:  flags           - Init/enable Options
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Completes the subsystem initialization including hardware.
- *              Puts system into ACPI mode if it isn't already.
- *
- ******************************************************************************/
-acpi_status acpi_enable_subsystem(u32 flags)
-{
-       acpi_status status = AE_OK;
-
-       ACPI_FUNCTION_TRACE(acpi_enable_subsystem);
-
-#if (!ACPI_REDUCED_HARDWARE)
-
-       /* Enable ACPI mode */
-
-       if (!(flags & ACPI_NO_ACPI_ENABLE)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                                 "[Init] Going into ACPI mode\n"));
-
-               acpi_gbl_original_mode = acpi_hw_get_mode();
-
-               status = acpi_enable();
-               if (ACPI_FAILURE(status)) {
-                       ACPI_WARNING((AE_INFO, "AcpiEnable failed"));
-                       return_ACPI_STATUS(status);
-               }
-       }
-
-       /*
-        * Obtain a permanent mapping for the FACS. This is required for the
-        * Global Lock and the Firmware Waking Vector
-        */
-       status = acpi_tb_initialize_facs();
-       if (ACPI_FAILURE(status)) {
-               ACPI_WARNING((AE_INFO, "Could not map the FACS table"));
-               return_ACPI_STATUS(status);
-       }
-#endif                         /* !ACPI_REDUCED_HARDWARE */
-
-       /*
-        * Install the default op_region handlers. These are installed unless
-        * other handlers have already been installed via the
-        * install_address_space_handler interface.
-        */
-       if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                                 "[Init] Installing default address space handlers\n"));
-
-               status = acpi_ev_install_region_handlers();
-               if (ACPI_FAILURE(status)) {
-                       return_ACPI_STATUS(status);
-               }
-       }
-#if (!ACPI_REDUCED_HARDWARE)
-       /*
-        * Initialize ACPI Event handling (Fixed and General Purpose)
-        *
-        * Note1: We must have the hardware and events initialized before we can
-        * execute any control methods safely. Any control method can require
-        * ACPI hardware support, so the hardware must be fully initialized before
-        * any method execution!
-        *
-        * Note2: Fixed events are initialized and enabled here. GPEs are
-        * initialized, but cannot be enabled until after the hardware is
-        * completely initialized (SCI and global_lock activated)
-        */
-       if (!(flags & ACPI_NO_EVENT_INIT)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                                 "[Init] Initializing ACPI events\n"));
-
-               status = acpi_ev_initialize_events();
-               if (ACPI_FAILURE(status)) {
-                       return_ACPI_STATUS(status);
-               }
-       }
-
-       /*
-        * Install the SCI handler and Global Lock handler. This completes the
-        * hardware initialization.
-        */
-       if (!(flags & ACPI_NO_HANDLER_INIT)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                                 "[Init] Installing SCI/GL handlers\n"));
-
-               status = acpi_ev_install_xrupt_handlers();
-               if (ACPI_FAILURE(status)) {
-                       return_ACPI_STATUS(status);
-               }
-       }
-#endif                         /* !ACPI_REDUCED_HARDWARE */
-
-       return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_enable_subsystem)
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_initialize_objects
- *
- * PARAMETERS:  flags           - Init/enable Options
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Completes namespace initialization by initializing device
- *              objects and executing AML code for Regions, buffers, etc.
- *
- ******************************************************************************/
-acpi_status acpi_initialize_objects(u32 flags)
-{
-       acpi_status status = AE_OK;
-
-       ACPI_FUNCTION_TRACE(acpi_initialize_objects);
-
-       /*
-        * Run all _REG methods
-        *
-        * Note: Any objects accessed by the _REG methods will be automatically
-        * initialized, even if they contain executable AML (see the call to
-        * acpi_ns_initialize_objects below).
-        */
-       if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                                 "[Init] Executing _REG OpRegion methods\n"));
-
-               status = acpi_ev_initialize_op_regions();
-               if (ACPI_FAILURE(status)) {
-                       return_ACPI_STATUS(status);
-               }
-       }
-
-       /*
-        * Execute any module-level code that was detected during the table load
-        * phase. Although illegal since ACPI 2.0, there are many machines that
-        * contain this type of code. Each block of detected executable AML code
-        * outside of any control method is wrapped with a temporary control
-        * method object and placed on a global list. The methods on this list
-        * are executed below.
-        */
-       acpi_ns_exec_module_code_list();
-
-       /*
-        * Initialize the objects that remain uninitialized. This runs the
-        * executable AML that may be part of the declaration of these objects:
-        * operation_regions, buffer_fields, Buffers, and Packages.
-        */
-       if (!(flags & ACPI_NO_OBJECT_INIT)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                                 "[Init] Completing Initialization of ACPI Objects\n"));
-
-               status = acpi_ns_initialize_objects();
-               if (ACPI_FAILURE(status)) {
-                       return_ACPI_STATUS(status);
-               }
-       }
-
-       /*
-        * Initialize all device objects in the namespace. This runs the device
-        * _STA and _INI methods.
-        */
-       if (!(flags & ACPI_NO_DEVICE_INIT)) {
-               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                                 "[Init] Initializing ACPI Devices\n"));
-
-               status = acpi_ns_initialize_devices();
-               if (ACPI_FAILURE(status)) {
-                       return_ACPI_STATUS(status);
-               }
-       }
-
-       /*
-        * Empty the caches (delete the cached objects) on the assumption that
-        * the table load filled them up more than they will be at runtime --
-        * thus wasting non-paged memory.
-        */
-       status = acpi_purge_cached_objects();
-
-       acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK;
-       return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_initialize_objects)
-
-#endif
 /*******************************************************************************
  *
  * FUNCTION:    acpi_terminate
@@ -683,3 +418,90 @@ acpi_check_address_range(acpi_adr_space_type space_id,
 
 ACPI_EXPORT_SYMBOL(acpi_check_address_range)
 #endif                         /* !ACPI_ASL_COMPILER */
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_decode_pld_buffer
+ *
+ * PARAMETERS:  in_buffer           - Buffer returned by _PLD method
+ *              length              - Length of the in_buffer
+ *              return_buffer       - Where the decode buffer is returned
+ *
+ * RETURN:      Status and the decoded _PLD buffer. User must deallocate
+ *              the buffer via ACPI_FREE.
+ *
+ * DESCRIPTION: Decode the bit-packed buffer returned by the _PLD method into
+ *              a local struct that is much more useful to an ACPI driver.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_decode_pld_buffer(u8 *in_buffer,
+                      acpi_size length, struct acpi_pld_info ** return_buffer)
+{
+       struct acpi_pld_info *pld_info;
+       u32 *buffer = ACPI_CAST_PTR(u32, in_buffer);
+       u32 dword;
+
+       /* Parameter validation */
+
+       if (!in_buffer || !return_buffer || (length < 16)) {
+               return (AE_BAD_PARAMETER);
+       }
+
+       pld_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pld_info));
+       if (!pld_info) {
+               return (AE_NO_MEMORY);
+       }
+
+       /* First 32-bit DWord */
+
+       ACPI_MOVE_32_TO_32(&dword, &buffer[0]);
+       pld_info->revision = ACPI_PLD_GET_REVISION(&dword);
+       pld_info->ignore_color = ACPI_PLD_GET_IGNORE_COLOR(&dword);
+       pld_info->color = ACPI_PLD_GET_COLOR(&dword);
+
+       /* Second 32-bit DWord */
+
+       ACPI_MOVE_32_TO_32(&dword, &buffer[1]);
+       pld_info->width = ACPI_PLD_GET_WIDTH(&dword);
+       pld_info->height = ACPI_PLD_GET_HEIGHT(&dword);
+
+       /* Third 32-bit DWord */
+
+       ACPI_MOVE_32_TO_32(&dword, &buffer[2]);
+       pld_info->user_visible = ACPI_PLD_GET_USER_VISIBLE(&dword);
+       pld_info->dock = ACPI_PLD_GET_DOCK(&dword);
+       pld_info->lid = ACPI_PLD_GET_LID(&dword);
+       pld_info->panel = ACPI_PLD_GET_PANEL(&dword);
+       pld_info->vertical_position = ACPI_PLD_GET_VERTICAL(&dword);
+       pld_info->horizontal_position = ACPI_PLD_GET_HORIZONTAL(&dword);
+       pld_info->shape = ACPI_PLD_GET_SHAPE(&dword);
+       pld_info->group_orientation = ACPI_PLD_GET_ORIENTATION(&dword);
+       pld_info->group_token = ACPI_PLD_GET_TOKEN(&dword);
+       pld_info->group_position = ACPI_PLD_GET_POSITION(&dword);
+       pld_info->bay = ACPI_PLD_GET_BAY(&dword);
+
+       /* Fourth 32-bit DWord */
+
+       ACPI_MOVE_32_TO_32(&dword, &buffer[3]);
+       pld_info->ejectable = ACPI_PLD_GET_EJECTABLE(&dword);
+       pld_info->ospm_eject_required = ACPI_PLD_GET_OSPM_EJECT(&dword);
+       pld_info->cabinet_number = ACPI_PLD_GET_CABINET(&dword);
+       pld_info->card_cage_number = ACPI_PLD_GET_CARD_CAGE(&dword);
+       pld_info->reference = ACPI_PLD_GET_REFERENCE(&dword);
+       pld_info->rotation = ACPI_PLD_GET_ROTATION(&dword);
+       pld_info->order = ACPI_PLD_GET_ORDER(&dword);
+
+       if (length >= ACPI_PLD_BUFFER_SIZE) {
+
+               /* Fifth 32-bit DWord (Revision 2 of _PLD) */
+
+               ACPI_MOVE_32_TO_32(&dword, &buffer[4]);
+               pld_info->vertical_offset = ACPI_PLD_GET_VERT_OFFSET(&dword);
+               pld_info->horizontal_offset = ACPI_PLD_GET_HORIZ_OFFSET(&dword);
+       }
+
+       *return_buffer = pld_info;
+       return (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_decode_pld_buffer)
diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c
new file mode 100644 (file)
index 0000000..14f5236
--- /dev/null
@@ -0,0 +1,317 @@
+/******************************************************************************
+ *
+ * Module Name: utxfinit - External interfaces for ACPICA initialization
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <linux/export.h>
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acevents.h"
+#include "acnamesp.h"
+#include "acdebug.h"
+#include "actables.h"
+
+#define _COMPONENT          ACPI_UTILITIES
+ACPI_MODULE_NAME("utxfinit")
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_initialize_subsystem
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initializes all global variables. This is the first function
+ *              called, so any early initialization belongs here.
+ *
+ ******************************************************************************/
+acpi_status acpi_initialize_subsystem(void)
+{
+       acpi_status status;
+
+       ACPI_FUNCTION_TRACE(acpi_initialize_subsystem);
+
+       acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE;
+       ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace());
+
+       /* Initialize the OS-Dependent layer */
+
+       status = acpi_os_initialize();
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status, "During OSL initialization"));
+               return_ACPI_STATUS(status);
+       }
+
+       /* Initialize all globals used by the subsystem */
+
+       status = acpi_ut_init_globals();
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status,
+                               "During initialization of globals"));
+               return_ACPI_STATUS(status);
+       }
+
+       /* Create the default mutex objects */
+
+       status = acpi_ut_mutex_initialize();
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status,
+                               "During Global Mutex creation"));
+               return_ACPI_STATUS(status);
+       }
+
+       /*
+        * Initialize the namespace manager and
+        * the root of the namespace tree
+        */
+       status = acpi_ns_root_initialize();
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status,
+                               "During Namespace initialization"));
+               return_ACPI_STATUS(status);
+       }
+
+       /* Initialize the global OSI interfaces list with the static names */
+
+       status = acpi_ut_initialize_interfaces();
+       if (ACPI_FAILURE(status)) {
+               ACPI_EXCEPTION((AE_INFO, status,
+                               "During OSI interfaces initialization"));
+               return_ACPI_STATUS(status);
+       }
+
+       /* If configured, initialize the AML debugger */
+
+       ACPI_DEBUGGER_EXEC(status = acpi_db_initialize());
+       return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_initialize_subsystem)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_enable_subsystem
+ *
+ * PARAMETERS:  flags               - Init/enable Options
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Completes the subsystem initialization including hardware.
+ *              Puts system into ACPI mode if it isn't already.
+ *
+ ******************************************************************************/
+acpi_status acpi_enable_subsystem(u32 flags)
+{
+       acpi_status status = AE_OK;
+
+       ACPI_FUNCTION_TRACE(acpi_enable_subsystem);
+
+#if (!ACPI_REDUCED_HARDWARE)
+
+       /* Enable ACPI mode */
+
+       if (!(flags & ACPI_NO_ACPI_ENABLE)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+                                 "[Init] Going into ACPI mode\n"));
+
+               acpi_gbl_original_mode = acpi_hw_get_mode();
+
+               status = acpi_enable();
+               if (ACPI_FAILURE(status)) {
+                       ACPI_WARNING((AE_INFO, "AcpiEnable failed"));
+                       return_ACPI_STATUS(status);
+               }
+       }
+
+       /*
+        * Obtain a permanent mapping for the FACS. This is required for the
+        * Global Lock and the Firmware Waking Vector
+        */
+       status = acpi_tb_initialize_facs();
+       if (ACPI_FAILURE(status)) {
+               ACPI_WARNING((AE_INFO, "Could not map the FACS table"));
+               return_ACPI_STATUS(status);
+       }
+#endif                         /* !ACPI_REDUCED_HARDWARE */
+
+       /*
+        * Install the default op_region handlers. These are installed unless
+        * other handlers have already been installed via the
+        * install_address_space_handler interface.
+        */
+       if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+                                 "[Init] Installing default address space handlers\n"));
+
+               status = acpi_ev_install_region_handlers();
+               if (ACPI_FAILURE(status)) {
+                       return_ACPI_STATUS(status);
+               }
+       }
+#if (!ACPI_REDUCED_HARDWARE)
+       /*
+        * Initialize ACPI Event handling (Fixed and General Purpose)
+        *
+        * Note1: We must have the hardware and events initialized before we can
+        * execute any control methods safely. Any control method can require
+        * ACPI hardware support, so the hardware must be fully initialized before
+        * any method execution!
+        *
+        * Note2: Fixed events are initialized and enabled here. GPEs are
+        * initialized, but cannot be enabled until after the hardware is
+        * completely initialized (SCI and global_lock activated) and the various
+        * initialization control methods are run (_REG, _STA, _INI) on the
+        * entire namespace.
+        */
+       if (!(flags & ACPI_NO_EVENT_INIT)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+                                 "[Init] Initializing ACPI events\n"));
+
+               status = acpi_ev_initialize_events();
+               if (ACPI_FAILURE(status)) {
+                       return_ACPI_STATUS(status);
+               }
+       }
+
+       /*
+        * Install the SCI handler and Global Lock handler. This completes the
+        * hardware initialization.
+        */
+       if (!(flags & ACPI_NO_HANDLER_INIT)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+                                 "[Init] Installing SCI/GL handlers\n"));
+
+               status = acpi_ev_install_xrupt_handlers();
+               if (ACPI_FAILURE(status)) {
+                       return_ACPI_STATUS(status);
+               }
+       }
+#endif                         /* !ACPI_REDUCED_HARDWARE */
+
+       return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_enable_subsystem)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_initialize_objects
+ *
+ * PARAMETERS:  flags               - Init/enable Options
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Completes namespace initialization by initializing device
+ *              objects and executing AML code for Regions, buffers, etc.
+ *
+ ******************************************************************************/
+acpi_status acpi_initialize_objects(u32 flags)
+{
+       acpi_status status = AE_OK;
+
+       ACPI_FUNCTION_TRACE(acpi_initialize_objects);
+
+       /*
+        * Run all _REG methods
+        *
+        * Note: Any objects accessed by the _REG methods will be automatically
+        * initialized, even if they contain executable AML (see the call to
+        * acpi_ns_initialize_objects below).
+        */
+       if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+                                 "[Init] Executing _REG OpRegion methods\n"));
+
+               status = acpi_ev_initialize_op_regions();
+               if (ACPI_FAILURE(status)) {
+                       return_ACPI_STATUS(status);
+               }
+       }
+
+       /*
+        * Execute any module-level code that was detected during the table load
+        * phase. Although illegal since ACPI 2.0, there are many machines that
+        * contain this type of code. Each block of detected executable AML code
+        * outside of any control method is wrapped with a temporary control
+        * method object and placed on a global list. The methods on this list
+        * are executed below.
+        */
+       acpi_ns_exec_module_code_list();
+
+       /*
+        * Initialize the objects that remain uninitialized. This runs the
+        * executable AML that may be part of the declaration of these objects:
+        * operation_regions, buffer_fields, Buffers, and Packages.
+        */
+       if (!(flags & ACPI_NO_OBJECT_INIT)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+                                 "[Init] Completing Initialization of ACPI Objects\n"));
+
+               status = acpi_ns_initialize_objects();
+               if (ACPI_FAILURE(status)) {
+                       return_ACPI_STATUS(status);
+               }
+       }
+
+       /*
+        * Initialize all device objects in the namespace. This runs the device
+        * _STA and _INI methods.
+        */
+       if (!(flags & ACPI_NO_DEVICE_INIT)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+                                 "[Init] Initializing ACPI Devices\n"));
+
+               status = acpi_ns_initialize_devices();
+               if (ACPI_FAILURE(status)) {
+                       return_ACPI_STATUS(status);
+               }
+       }
+
+       /*
+        * Empty the caches (delete the cached objects) on the assumption that
+        * the table load filled them up more than they will be at runtime --
+        * thus wasting non-paged memory.
+        */
+       status = acpi_purge_cached_objects();
+
+       acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK;
+       return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_initialize_objects)
index 314a3b84bbc7e2626a227a4ef2a620204dbf2434..f0d936b65e375c40be1898fbf49b4cb40006ecb9 100644 (file)
@@ -450,15 +450,4 @@ static int acpi_button_remove(struct acpi_device *device, int type)
        return 0;
 }
 
-static int __init acpi_button_init(void)
-{
-       return acpi_bus_register_driver(&acpi_button_driver);
-}
-
-static void __exit acpi_button_exit(void)
-{
-       acpi_bus_unregister_driver(&acpi_button_driver);
-}
-
-module_init(acpi_button_init);
-module_exit(acpi_button_exit);
+module_acpi_driver(acpi_button_driver);
index bc36a476f1abf139586391c4e490cad56aff4368..3bd6a54702d683bbca8bcee056293eb938f7d71b 100644 (file)
@@ -212,24 +212,4 @@ static int acpi_fan_resume(struct device *dev)
 }
 #endif
 
-static int __init acpi_fan_init(void)
-{
-       int result = 0;
-
-       result = acpi_bus_register_driver(&acpi_fan_driver);
-       if (result < 0)
-               return -ENODEV;
-
-       return 0;
-}
-
-static void __exit acpi_fan_exit(void)
-{
-
-       acpi_bus_unregister_driver(&acpi_fan_driver);
-
-       return;
-}
-
-module_init(acpi_fan_init);
-module_exit(acpi_fan_exit);
+module_acpi_driver(acpi_fan_driver);
index 243ee85e4d2ed02ad29c22435dd4c5437390f6a7..d1a2d74033e945237afdef3fac02aea87cdebbdd 100644 (file)
@@ -25,6 +25,8 @@
 static LIST_HEAD(bus_type_list);
 static DECLARE_RWSEM(bus_type_sem);
 
+#define PHYSICAL_NODE_STRING "physical_node"
+
 int register_acpi_bus_type(struct acpi_bus_type *type)
 {
        if (acpi_disabled)
@@ -124,84 +126,119 @@ acpi_handle acpi_get_child(acpi_handle parent, u64 address)
 
 EXPORT_SYMBOL(acpi_get_child);
 
-/* Link ACPI devices with physical devices */
-static void acpi_glue_data_handler(acpi_handle handle,
-                                  void *context)
-{
-       /* we provide an empty handler */
-}
-
-/* Note: a success call will increase reference count by one */
-struct device *acpi_get_physical_device(acpi_handle handle)
-{
-       acpi_status status;
-       struct device *dev;
-
-       status = acpi_get_data(handle, acpi_glue_data_handler, (void **)&dev);
-       if (ACPI_SUCCESS(status))
-               return get_device(dev);
-       return NULL;
-}
-
-EXPORT_SYMBOL(acpi_get_physical_device);
-
 static int acpi_bind_one(struct device *dev, acpi_handle handle)
 {
        struct acpi_device *acpi_dev;
        acpi_status status;
+       struct acpi_device_physical_node *physical_node;
+       char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2];
+       int retval = -EINVAL;
 
        if (dev->archdata.acpi_handle) {
                dev_warn(dev, "Drivers changed 'acpi_handle'\n");
                return -EINVAL;
        }
+
        get_device(dev);
-       status = acpi_attach_data(handle, acpi_glue_data_handler, dev);
-       if (ACPI_FAILURE(status)) {
-               put_device(dev);
-               return -EINVAL;
+       status = acpi_bus_get_device(handle, &acpi_dev);
+       if (ACPI_FAILURE(status))
+               goto err;
+
+       physical_node = kzalloc(sizeof(struct acpi_device_physical_node),
+               GFP_KERNEL);
+       if (!physical_node) {
+               retval = -ENOMEM;
+               goto err;
        }
-       dev->archdata.acpi_handle = handle;
 
-       status = acpi_bus_get_device(handle, &acpi_dev);
-       if (!ACPI_FAILURE(status)) {
-               int ret;
-
-               ret = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
-                               "firmware_node");
-               ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
-                               "physical_node");
-               if (acpi_dev->wakeup.flags.valid)
-                       device_set_wakeup_capable(dev, true);
+       mutex_lock(&acpi_dev->physical_node_lock);
+       /* allocate physical node id according to physical_node_id_bitmap */
+       physical_node->node_id =
+               find_first_zero_bit(acpi_dev->physical_node_id_bitmap,
+               ACPI_MAX_PHYSICAL_NODE);
+       if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) {
+               retval = -ENOSPC;
+               mutex_unlock(&acpi_dev->physical_node_lock);
+               goto err;
        }
 
+       set_bit(physical_node->node_id, acpi_dev->physical_node_id_bitmap);
+       physical_node->dev = dev;
+       list_add_tail(&physical_node->node, &acpi_dev->physical_node_list);
+       acpi_dev->physical_node_count++;
+       mutex_unlock(&acpi_dev->physical_node_lock);
+
+       dev->archdata.acpi_handle = handle;
+
+       if (!physical_node->node_id)
+               strcpy(physical_node_name, PHYSICAL_NODE_STRING);
+       else
+               sprintf(physical_node_name,
+                       "physical_node%d", physical_node->node_id);
+       retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
+                       physical_node_name);
+       retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
+               "firmware_node");
+
+       if (acpi_dev->wakeup.flags.valid)
+               device_set_wakeup_capable(dev, true);
+
        return 0;
+
+ err:
+       put_device(dev);
+       return retval;
 }
 
 static int acpi_unbind_one(struct device *dev)
 {
+       struct acpi_device_physical_node *entry;
+       struct acpi_device *acpi_dev;
+       acpi_status status;
+       struct list_head *node, *next;
+
        if (!dev->archdata.acpi_handle)
                return 0;
-       if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) {
-               struct acpi_device *acpi_dev;
 
-               /* acpi_get_physical_device increase refcnt by one */
-               put_device(dev);
+       status = acpi_bus_get_device(dev->archdata.acpi_handle,
+               &acpi_dev);
+       if (ACPI_FAILURE(status))
+               goto err;
 
-               if (!acpi_bus_get_device(dev->archdata.acpi_handle,
-                                       &acpi_dev)) {
-                       sysfs_remove_link(&dev->kobj, "firmware_node");
-                       sysfs_remove_link(&acpi_dev->dev.kobj, "physical_node");
-               }
+       mutex_lock(&acpi_dev->physical_node_lock);
+       list_for_each_safe(node, next, &acpi_dev->physical_node_list) {
+               char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2];
+
+               entry = list_entry(node, struct acpi_device_physical_node,
+                       node);
+               if (entry->dev != dev)
+                       continue;
+
+               list_del(node);
+               clear_bit(entry->node_id, acpi_dev->physical_node_id_bitmap);
 
-               acpi_detach_data(dev->archdata.acpi_handle,
-                                acpi_glue_data_handler);
+               acpi_dev->physical_node_count--;
+
+               if (!entry->node_id)
+                       strcpy(physical_node_name, PHYSICAL_NODE_STRING);
+               else
+                       sprintf(physical_node_name,
+                               "physical_node%d", entry->node_id);
+
+               sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name);
+               sysfs_remove_link(&dev->kobj, "firmware_node");
                dev->archdata.acpi_handle = NULL;
                /* acpi_bind_one increase refcnt by one */
                put_device(dev);
-       } else {
-               dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
+               kfree(entry);
        }
+       mutex_unlock(&acpi_dev->physical_node_lock);
+
        return 0;
+
+err:
+       dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
+       return -EINVAL;
 }
 
 static int acpi_platform_notify(struct device *dev)
index d0c1967f7597aff1517b6b2ab65103688094c8a3..20a0f2c3ca3b7d1143825ec0946aea54b60f4179 100644 (file)
@@ -86,25 +86,7 @@ static struct acpi_driver acpi_hed_driver = {
                .notify = acpi_hed_notify,
        },
 };
-
-static int __init acpi_hed_init(void)
-{
-       if (acpi_disabled)
-               return -ENODEV;
-
-       if (acpi_bus_register_driver(&acpi_hed_driver) < 0)
-               return -ENODEV;
-
-       return 0;
-}
-
-static void __exit acpi_hed_exit(void)
-{
-       acpi_bus_unregister_driver(&acpi_hed_driver);
-}
-
-module_init(acpi_hed_init);
-module_exit(acpi_hed_exit);
+module_acpi_driver(acpi_hed_driver);
 
 ACPI_MODULE_NAME("hed");
 MODULE_AUTHOR("Huang Ying");
index 251c7b6273a9e83b21757aaa4c9c7cf3189a6e98..27adb090bb3059bcb6fe9127384edc1bbfe55102 100644 (file)
@@ -302,26 +302,41 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
        list_for_each_safe(node, next, &acpi_wakeup_device_list) {
                struct acpi_device *dev =
                    container_of(node, struct acpi_device, wakeup_list);
-               struct device *ldev;
+               struct acpi_device_physical_node *entry;
 
                if (!dev->wakeup.flags.valid)
                        continue;
 
-               ldev = acpi_get_physical_device(dev->handle);
-               seq_printf(seq, "%s\t  S%d\t%c%-8s  ",
+               seq_printf(seq, "%s\t  S%d\t",
                           dev->pnp.bus_id,
-                          (u32) dev->wakeup.sleep_state,
-                          dev->wakeup.flags.run_wake ? '*' : ' ',
-                          (device_may_wakeup(&dev->dev)
-                            || (ldev && device_may_wakeup(ldev))) ?
-                              "enabled" : "disabled");
-               if (ldev)
-                       seq_printf(seq, "%s:%s",
-                                  ldev->bus ? ldev->bus->name : "no-bus",
-                                  dev_name(ldev));
-               seq_printf(seq, "\n");
-               put_device(ldev);
-
+                          (u32) dev->wakeup.sleep_state);
+
+               if (!dev->physical_node_count)
+                       seq_printf(seq, "%c%-8s\n",
+                               dev->wakeup.flags.run_wake ?
+                               '*' : ' ', "disabled");
+               else {
+                       struct device *ldev;
+                       list_for_each_entry(entry, &dev->physical_node_list,
+                                       node) {
+                               ldev = get_device(entry->dev);
+                               if (!ldev)
+                                       continue;
+
+                               if (&entry->node !=
+                                               dev->physical_node_list.next)
+                                       seq_printf(seq, "\t\t");
+
+                               seq_printf(seq, "%c%-8s  %s:%s\n",
+                                       dev->wakeup.flags.run_wake ? '*' : ' ',
+                                       (device_may_wakeup(&dev->dev) ||
+                                       (ldev && device_may_wakeup(ldev))) ?
+                                       "enabled" : "disabled",
+                                       ldev->bus ? ldev->bus->name :
+                                       "no-bus", dev_name(ldev));
+                               put_device(ldev);
+                       }
+               }
        }
        mutex_unlock(&acpi_device_lock);
        return 0;
@@ -329,12 +344,14 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
 
 static void physical_device_enable_wakeup(struct acpi_device *adev)
 {
-       struct device *dev = acpi_get_physical_device(adev->handle);
+       struct acpi_device_physical_node *entry;
 
-       if (dev && device_can_wakeup(dev)) {
-               bool enable = !device_may_wakeup(dev);
-               device_set_wakeup_enable(dev, enable);
-       }
+       list_for_each_entry(entry,
+               &adev->physical_node_list, node)
+               if (entry->dev && device_can_wakeup(entry->dev)) {
+                       bool enable = !device_may_wakeup(entry->dev);
+                       device_set_wakeup_enable(entry->dev, enable);
+               }
 }
 
 static ssize_t
index f8d2a472795c588b8eee51cfa1319fa98a6e132d..cf6129a8af7c97619809b19e6fc46a5be010dd66 100644 (file)
@@ -310,23 +310,7 @@ static int acpi_smbus_hc_remove(struct acpi_device *device, int type)
        return 0;
 }
 
-static int __init acpi_smb_hc_init(void)
-{
-       int result;
-
-       result = acpi_bus_register_driver(&acpi_smb_hc_driver);
-       if (result < 0)
-               return -ENODEV;
-       return 0;
-}
-
-static void __exit acpi_smb_hc_exit(void)
-{
-       acpi_bus_unregister_driver(&acpi_smb_hc_driver);
-}
-
-module_init(acpi_smb_hc_init);
-module_exit(acpi_smb_hc_exit);
+module_acpi_driver(acpi_smb_hc_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Alexey Starikovskiy");
index 04302835723d2e2cd1c2b15907140f0e2cd41858..1fcb8678665c0e89113da39e0f603db2d49eeccb 100644 (file)
@@ -531,6 +531,8 @@ static int acpi_device_register(struct acpi_device *device)
        INIT_LIST_HEAD(&device->children);
        INIT_LIST_HEAD(&device->node);
        INIT_LIST_HEAD(&device->wakeup_list);
+       INIT_LIST_HEAD(&device->physical_node_list);
+       mutex_init(&device->physical_node_lock);
 
        new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
        if (!new_bus_id) {
index 3e87c9c538aaf376488593b3d7e28a05121396db..462f7e300363caa5ea0cd3e62d2a1b78952c7919 100644 (file)
@@ -384,7 +384,7 @@ acpi_evaluate_reference(acpi_handle handle,
 EXPORT_SYMBOL(acpi_evaluate_reference);
 
 acpi_status
-acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld *pld)
+acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld)
 {
        acpi_status status;
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -400,13 +400,16 @@ acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld *pld)
        if (!output || output->type != ACPI_TYPE_PACKAGE
            || !output->package.count
            || output->package.elements[0].type != ACPI_TYPE_BUFFER
-           || output->package.elements[0].buffer.length > sizeof(*pld)) {
+           || output->package.elements[0].buffer.length < ACPI_PLD_REV1_BUFFER_SIZE) {
                status = AE_TYPE;
                goto out;
        }
 
-       memcpy(pld, output->package.elements[0].buffer.pointer,
-              output->package.elements[0].buffer.length);
+       status = acpi_decode_pld_buffer(
+                       output->package.elements[0].buffer.pointer,
+                       output->package.elements[0].buffer.length,
+                       pld);
+
 out:
        kfree(buffer.pointer);
        return status;
index 38a2d0631882ccd192ee475fc3b0f7a2e3b9d0cb..ad16c68c86451bd80dc18bbb7673e14d4611d947 100644 (file)
@@ -79,6 +79,7 @@ struct nvme_dev {
        char serial[20];
        char model[40];
        char firmware_rev[8];
+       u32 max_hw_sectors;
 };
 
 /*
@@ -835,15 +836,15 @@ static int nvme_identify(struct nvme_dev *dev, unsigned nsid, unsigned cns,
 }
 
 static int nvme_get_features(struct nvme_dev *dev, unsigned fid,
-                               unsigned dword11, dma_addr_t dma_addr)
+                               unsigned nsid, dma_addr_t dma_addr)
 {
        struct nvme_command c;
 
        memset(&c, 0, sizeof(c));
        c.features.opcode = nvme_admin_get_features;
+       c.features.nsid = cpu_to_le32(nsid);
        c.features.prp1 = cpu_to_le64(dma_addr);
        c.features.fid = cpu_to_le32(fid);
-       c.features.dword11 = cpu_to_le32(dword11);
 
        return nvme_submit_admin_cmd(dev, &c, NULL);
 }
@@ -862,11 +863,51 @@ static int nvme_set_features(struct nvme_dev *dev, unsigned fid,
        return nvme_submit_admin_cmd(dev, &c, result);
 }
 
+/**
+ * nvme_cancel_ios - Cancel outstanding I/Os
+ * @queue: The queue to cancel I/Os on
+ * @timeout: True to only cancel I/Os which have timed out
+ */
+static void nvme_cancel_ios(struct nvme_queue *nvmeq, bool timeout)
+{
+       int depth = nvmeq->q_depth - 1;
+       struct nvme_cmd_info *info = nvme_cmd_info(nvmeq);
+       unsigned long now = jiffies;
+       int cmdid;
+
+       for_each_set_bit(cmdid, nvmeq->cmdid_data, depth) {
+               void *ctx;
+               nvme_completion_fn fn;
+               static struct nvme_completion cqe = {
+                       .status = cpu_to_le16(NVME_SC_ABORT_REQ) << 1,
+               };
+
+               if (timeout && !time_after(now, info[cmdid].timeout))
+                       continue;
+               dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d\n", cmdid);
+               ctx = cancel_cmdid(nvmeq, cmdid, &fn);
+               fn(nvmeq->dev, ctx, &cqe);
+       }
+}
+
+static void nvme_free_queue_mem(struct nvme_queue *nvmeq)
+{
+       dma_free_coherent(nvmeq->q_dmadev, CQ_SIZE(nvmeq->q_depth),
+                               (void *)nvmeq->cqes, nvmeq->cq_dma_addr);
+       dma_free_coherent(nvmeq->q_dmadev, SQ_SIZE(nvmeq->q_depth),
+                                       nvmeq->sq_cmds, nvmeq->sq_dma_addr);
+       kfree(nvmeq);
+}
+
 static void nvme_free_queue(struct nvme_dev *dev, int qid)
 {
        struct nvme_queue *nvmeq = dev->queues[qid];
        int vector = dev->entry[nvmeq->cq_vector].vector;
 
+       spin_lock_irq(&nvmeq->q_lock);
+       nvme_cancel_ios(nvmeq, false);
+       spin_unlock_irq(&nvmeq->q_lock);
+
        irq_set_affinity_hint(vector, NULL);
        free_irq(vector, nvmeq);
 
@@ -876,18 +917,15 @@ static void nvme_free_queue(struct nvme_dev *dev, int qid)
                adapter_delete_cq(dev, qid);
        }
 
-       dma_free_coherent(nvmeq->q_dmadev, CQ_SIZE(nvmeq->q_depth),
-                               (void *)nvmeq->cqes, nvmeq->cq_dma_addr);
-       dma_free_coherent(nvmeq->q_dmadev, SQ_SIZE(nvmeq->q_depth),
-                                       nvmeq->sq_cmds, nvmeq->sq_dma_addr);
-       kfree(nvmeq);
+       nvme_free_queue_mem(nvmeq);
 }
 
 static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid,
                                                        int depth, int vector)
 {
        struct device *dmadev = &dev->pci_dev->dev;
-       unsigned extra = (depth / 8) + (depth * sizeof(struct nvme_cmd_info));
+       unsigned extra = DIV_ROUND_UP(depth, 8) + (depth *
+                                               sizeof(struct nvme_cmd_info));
        struct nvme_queue *nvmeq = kzalloc(sizeof(*nvmeq) + extra, GFP_KERNEL);
        if (!nvmeq)
                return NULL;
@@ -975,7 +1013,7 @@ static __devinit struct nvme_queue *nvme_create_queue(struct nvme_dev *dev,
 
 static int __devinit nvme_configure_admin_queue(struct nvme_dev *dev)
 {
-       int result;
+       int result = 0;
        u32 aqa;
        u64 cap;
        unsigned long timeout;
@@ -1005,17 +1043,22 @@ static int __devinit nvme_configure_admin_queue(struct nvme_dev *dev)
        timeout = ((NVME_CAP_TIMEOUT(cap) + 1) * HZ / 2) + jiffies;
        dev->db_stride = NVME_CAP_STRIDE(cap);
 
-       while (!(readl(&dev->bar->csts) & NVME_CSTS_RDY)) {
+       while (!result && !(readl(&dev->bar->csts) & NVME_CSTS_RDY)) {
                msleep(100);
                if (fatal_signal_pending(current))
-                       return -EINTR;
+                       result = -EINTR;
                if (time_after(jiffies, timeout)) {
                        dev_err(&dev->pci_dev->dev,
                                "Device not ready; aborting initialisation\n");
-                       return -ENODEV;
+                       result = -ENODEV;
                }
        }
 
+       if (result) {
+               nvme_free_queue_mem(nvmeq);
+               return result;
+       }
+
        result = queue_request_irq(dev, nvmeq, "nvme admin");
        dev->queues[0] = nvmeq;
        return result;
@@ -1037,6 +1080,8 @@ static struct nvme_iod *nvme_map_user_pages(struct nvme_dev *dev, int write,
        offset = offset_in_page(addr);
        count = DIV_ROUND_UP(offset + length, PAGE_SIZE);
        pages = kcalloc(count, sizeof(*pages), GFP_KERNEL);
+       if (!pages)
+               return ERR_PTR(-ENOMEM);
 
        err = get_user_pages_fast(addr, count, 1, pages);
        if (err < count) {
@@ -1146,14 +1191,13 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
        return status;
 }
 
-static int nvme_user_admin_cmd(struct nvme_ns *ns,
+static int nvme_user_admin_cmd(struct nvme_dev *dev,
                                        struct nvme_admin_cmd __user *ucmd)
 {
-       struct nvme_dev *dev = ns->dev;
        struct nvme_admin_cmd cmd;
        struct nvme_command c;
        int status, length;
-       struct nvme_iod *iod;
+       struct nvme_iod *uninitialized_var(iod);
 
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
@@ -1204,7 +1248,7 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
        case NVME_IOCTL_ID:
                return ns->ns_id;
        case NVME_IOCTL_ADMIN_CMD:
-               return nvme_user_admin_cmd(ns, (void __user *)arg);
+               return nvme_user_admin_cmd(ns->dev, (void __user *)arg);
        case NVME_IOCTL_SUBMIT_IO:
                return nvme_submit_io(ns, (void __user *)arg);
        default:
@@ -1218,26 +1262,6 @@ static const struct block_device_operations nvme_fops = {
        .compat_ioctl   = nvme_ioctl,
 };
 
-static void nvme_timeout_ios(struct nvme_queue *nvmeq)
-{
-       int depth = nvmeq->q_depth - 1;
-       struct nvme_cmd_info *info = nvme_cmd_info(nvmeq);
-       unsigned long now = jiffies;
-       int cmdid;
-
-       for_each_set_bit(cmdid, nvmeq->cmdid_data, depth) {
-               void *ctx;
-               nvme_completion_fn fn;
-               static struct nvme_completion cqe = { .status = cpu_to_le16(NVME_SC_ABORT_REQ) << 1, };
-
-               if (!time_after(now, info[cmdid].timeout))
-                       continue;
-               dev_warn(nvmeq->q_dmadev, "Timing out I/O %d\n", cmdid);
-               ctx = cancel_cmdid(nvmeq, cmdid, &fn);
-               fn(nvmeq->dev, ctx, &cqe);
-       }
-}
-
 static void nvme_resubmit_bios(struct nvme_queue *nvmeq)
 {
        while (bio_list_peek(&nvmeq->sq_cong)) {
@@ -1269,7 +1293,7 @@ static int nvme_kthread(void *data)
                                spin_lock_irq(&nvmeq->q_lock);
                                if (nvme_process_cq(nvmeq))
                                        printk("process_cq did something\n");
-                               nvme_timeout_ios(nvmeq);
+                               nvme_cancel_ios(nvmeq, true);
                                nvme_resubmit_bios(nvmeq);
                                spin_unlock_irq(&nvmeq->q_lock);
                        }
@@ -1339,6 +1363,9 @@ static struct nvme_ns *nvme_alloc_ns(struct nvme_dev *dev, int nsid,
        ns->disk = disk;
        lbaf = id->flbas & 0xf;
        ns->lba_shift = id->lbaf[lbaf].ds;
+       blk_queue_logical_block_size(ns->queue, 1 << ns->lba_shift);
+       if (dev->max_hw_sectors)
+               blk_queue_max_hw_sectors(ns->queue, dev->max_hw_sectors);
 
        disk->major = nvme_major;
        disk->minors = NVME_MINORS;
@@ -1383,7 +1410,7 @@ static int set_queue_count(struct nvme_dev *dev, int count)
 
 static int __devinit nvme_setup_io_queues(struct nvme_dev *dev)
 {
-       int result, cpu, i, nr_io_queues, db_bar_size;
+       int result, cpu, i, nr_io_queues, db_bar_size, q_depth;
 
        nr_io_queues = num_online_cpus();
        result = set_queue_count(dev, nr_io_queues);
@@ -1429,9 +1456,10 @@ static int __devinit nvme_setup_io_queues(struct nvme_dev *dev)
                cpu = cpumask_next(cpu, cpu_online_mask);
        }
 
+       q_depth = min_t(int, NVME_CAP_MQES(readq(&dev->bar->cap)) + 1,
+                                                               NVME_Q_DEPTH);
        for (i = 0; i < nr_io_queues; i++) {
-               dev->queues[i + 1] = nvme_create_queue(dev, i + 1,
-                                                       NVME_Q_DEPTH, i);
+               dev->queues[i + 1] = nvme_create_queue(dev, i + 1, q_depth, i);
                if (IS_ERR(dev->queues[i + 1]))
                        return PTR_ERR(dev->queues[i + 1]);
                dev->queue_count++;
@@ -1480,6 +1508,10 @@ static int __devinit nvme_dev_add(struct nvme_dev *dev)
        memcpy(dev->serial, ctrl->sn, sizeof(ctrl->sn));
        memcpy(dev->model, ctrl->mn, sizeof(ctrl->mn));
        memcpy(dev->firmware_rev, ctrl->fr, sizeof(ctrl->fr));
+       if (ctrl->mdts) {
+               int shift = NVME_CAP_MPSMIN(readq(&dev->bar->cap)) + 12;
+               dev->max_hw_sectors = 1 << (ctrl->mdts + shift - 9);
+       }
 
        id_ns = mem;
        for (i = 1; i <= nn; i++) {
@@ -1523,8 +1555,6 @@ static int nvme_dev_remove(struct nvme_dev *dev)
        list_del(&dev->node);
        spin_unlock(&dev_list_lock);
 
-       /* TODO: wait all I/O finished or cancel them */
-
        list_for_each_entry_safe(ns, next, &dev->namespaces, list) {
                list_del(&ns->list);
                del_gendisk(ns->disk);
@@ -1560,15 +1590,33 @@ static void nvme_release_prp_pools(struct nvme_dev *dev)
        dma_pool_destroy(dev->prp_small_pool);
 }
 
-/* XXX: Use an ida or something to let remove / add work correctly */
-static void nvme_set_instance(struct nvme_dev *dev)
+static DEFINE_IDA(nvme_instance_ida);
+
+static int nvme_set_instance(struct nvme_dev *dev)
 {
-       static int instance;
-       dev->instance = instance++;
+       int instance, error;
+
+       do {
+               if (!ida_pre_get(&nvme_instance_ida, GFP_KERNEL))
+                       return -ENODEV;
+
+               spin_lock(&dev_list_lock);
+               error = ida_get_new(&nvme_instance_ida, &instance);
+               spin_unlock(&dev_list_lock);
+       } while (error == -EAGAIN);
+
+       if (error)
+               return -ENODEV;
+
+       dev->instance = instance;
+       return 0;
 }
 
 static void nvme_release_instance(struct nvme_dev *dev)
 {
+       spin_lock(&dev_list_lock);
+       ida_remove(&nvme_instance_ida, dev->instance);
+       spin_unlock(&dev_list_lock);
 }
 
 static int __devinit nvme_probe(struct pci_dev *pdev,
@@ -1601,7 +1649,10 @@ static int __devinit nvme_probe(struct pci_dev *pdev,
        pci_set_drvdata(pdev, dev);
        dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
        dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
-       nvme_set_instance(dev);
+       result = nvme_set_instance(dev);
+       if (result)
+               goto disable;
+
        dev->entry[0].vector = pdev->irq;
 
        result = nvme_setup_prp_pools(dev);
@@ -1704,15 +1755,17 @@ static struct pci_driver nvme_driver = {
 
 static int __init nvme_init(void)
 {
-       int result = -EBUSY;
+       int result;
 
        nvme_thread = kthread_run(nvme_kthread, NULL, "nvme");
        if (IS_ERR(nvme_thread))
                return PTR_ERR(nvme_thread);
 
-       nvme_major = register_blkdev(nvme_major, "nvme");
-       if (nvme_major <= 0)
+       result = register_blkdev(nvme_major, "nvme");
+       if (result < 0)
                goto kill_kthread;
+       else if (result > 0)
+               nvme_major = result;
 
        result = pci_register_driver(&nvme_driver);
        if (result)
index 9917943a3572ef577ac7a511ef375d11dae08350..54a55f03115df1df8dddb45e354eb8246336e56b 100644 (file)
@@ -246,13 +246,12 @@ static int rbd_open(struct block_device *bdev, fmode_t mode)
 {
        struct rbd_device *rbd_dev = bdev->bd_disk->private_data;
 
-       rbd_get_dev(rbd_dev);
-
-       set_device_ro(bdev, rbd_dev->read_only);
-
        if ((mode & FMODE_WRITE) && rbd_dev->read_only)
                return -EROFS;
 
+       rbd_get_dev(rbd_dev);
+       set_device_ro(bdev, rbd_dev->read_only);
+
        return 0;
 }
 
index 47180a08edad28c7c95fea0cd51e9b7b15172f27..b6653a6fc5d56af68e55b0f2ea10855a1927ee2f 100644 (file)
@@ -391,7 +391,7 @@ static int i3200_probe1(struct pci_dev *pdev, int dev_idx)
                for (j = 0; j < nr_channels; j++) {
                        struct dimm_info *dimm = csrow->channels[j]->dimm;
 
-                       dimm->nr_pages = nr_pages / nr_channels;
+                       dimm->nr_pages = nr_pages;
                        dimm->grain = nr_pages << PAGE_SHIFT;
                        dimm->mtype = MEM_DDR2;
                        dimm->dtype = DEV_UNKNOWN;
index 39c63757c2a14fd7bc988c23d7ee6be2e84d0a06..6a49dd00b81b8fce1181a0e0d436bb8e4ce211d5 100644 (file)
@@ -1012,6 +1012,10 @@ static void handle_channel(struct i5000_pvt *pvt, int slot, int channel,
                        /* add the number of COLUMN bits */
                        addrBits += MTR_DIMM_COLS_ADDR_BITS(mtr);
 
+                       /* Dual-rank memories have twice the size */
+                       if (dinfo->dual_rank)
+                               addrBits++;
+
                        addrBits += 6;  /* add 64 bits per DIMM */
                        addrBits -= 20; /* divide by 2^^20 */
                        addrBits -= 3;  /* 8 bits per bytes */
index f3b1f9fafa4b20b4f40917bcbab827ad760515df..5715b7c2c5177a6c76ed732fb6f20de9b7578220 100644 (file)
@@ -513,7 +513,8 @@ static int get_dimm_config(struct mem_ctl_info *mci)
 {
        struct sbridge_pvt *pvt = mci->pvt_info;
        struct dimm_info *dimm;
-       int i, j, banks, ranks, rows, cols, size, npages;
+       unsigned i, j, banks, ranks, rows, cols, npages;
+       u64 size;
        u32 reg;
        enum edac_type mode;
        enum mem_type mtype;
@@ -585,10 +586,10 @@ static int get_dimm_config(struct mem_ctl_info *mci)
                                cols = numcol(mtr);
 
                                /* DDR3 has 8 I/O banks */
-                               size = (rows * cols * banks * ranks) >> (20 - 3);
+                               size = ((u64)rows * cols * banks * ranks) >> (20 - 3);
                                npages = MiB_TO_PAGES(size);
 
-                               edac_dbg(0, "mc#%d: channel %d, dimm %d, %d Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n",
+                               edac_dbg(0, "mc#%d: channel %d, dimm %d, %Ld Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n",
                                         pvt->sbridge_dev->mc, i, j,
                                         size, npages,
                                         banks, ranks, rows, cols);
index 8a420f13905e814bc9e76672941d64fd31ab57f2..ed94b4ea72e9324cdc70a1ad4551f0e85fca89d0 100644 (file)
@@ -308,6 +308,7 @@ static int lpc32xx_gpio_dir_output_p012(struct gpio_chip *chip, unsigned pin,
 {
        struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
 
+       __set_gpio_level_p012(group, pin, value);
        __set_gpio_dir_p012(group, pin, 0);
 
        return 0;
@@ -318,6 +319,7 @@ static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin,
 {
        struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
 
+       __set_gpio_level_p3(group, pin, value);
        __set_gpio_dir_p3(group, pin, 0);
 
        return 0;
@@ -326,6 +328,9 @@ static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin,
 static int lpc32xx_gpio_dir_out_always(struct gpio_chip *chip, unsigned pin,
        int value)
 {
+       struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+
+       __set_gpo_level_p3(group, pin, value);
        return 0;
 }
 
index ff23d88880e50ab727b6836c4fc7ad6d8860a222..3ca240b4413d48eb9ddf0bdf479db97345397965 100644 (file)
@@ -179,7 +179,7 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
                        return 0;
        } else
        if (init->class == 0x906e) {
-               NV_ERROR(dev, "906e not supported yet\n");
+               NV_DEBUG(dev, "906e not supported yet\n");
                return -EINVAL;
        }
 
index f704e942372e75b291cc505536a197c4c464a537..f376c39310dfb11e00a944577aba9209e4481451 100644 (file)
@@ -124,6 +124,7 @@ nvc0_fb_init(struct drm_device *dev)
        priv = dev_priv->engine.fb.priv;
 
        nv_wr32(dev, 0x100c10, priv->r100c10 >> 8);
+       nv_mask(dev, 0x17e820, 0x00100000, 0x00000000); /* NV_PLTCG_INTR_EN */
        return 0;
 }
 
index 7d85553d518c42ee5826c0cf516086cf01ce1534..cd39eb99f5b15b4aef3f9fa4d47967b7bf3f55f6 100644 (file)
@@ -373,7 +373,8 @@ nvc0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
 static void
 nvc0_fifo_isr(struct drm_device *dev)
 {
-       u32 stat = nv_rd32(dev, 0x002100);
+       u32 mask = nv_rd32(dev, 0x002140);
+       u32 stat = nv_rd32(dev, 0x002100) & mask;
 
        if (stat & 0x00000100) {
                NV_INFO(dev, "PFIFO: unknown status 0x00000100\n");
index e98d144e6eb9df766fc458e03bdd35acef349ce4..281bece751b61eb091d2b6da73144dc9d2ddb5c5 100644 (file)
@@ -345,7 +345,8 @@ nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
 static void
 nve0_fifo_isr(struct drm_device *dev)
 {
-       u32 stat = nv_rd32(dev, 0x002100);
+       u32 mask = nv_rd32(dev, 0x002140);
+       u32 stat = nv_rd32(dev, 0x002100) & mask;
 
        if (stat & 0x00000100) {
                NV_INFO(dev, "PFIFO: unknown status 0x00000100\n");
index ba055e9ca0077875a3a49d3533d729a95ccf98fd..8d9dc44f1f94f56c32234fdb527576f7817433ad 100644 (file)
@@ -69,6 +69,13 @@ static int udl_get_modes(struct drm_connector *connector)
 static int udl_mode_valid(struct drm_connector *connector,
                          struct drm_display_mode *mode)
 {
+       struct udl_device *udl = connector->dev->dev_private;
+       if (!udl->sku_pixel_limit)
+               return 0;
+
+       if (mode->vdisplay * mode->hdisplay > udl->sku_pixel_limit)
+               return MODE_VIRTUAL_Y;
+
        return 0;
 }
 
index f2fb8f15e2f127b350e33c210d2b91d44ed09134..7e0743358dffdf5176d2aa48a393beb21803c6cd 100644 (file)
@@ -1018,7 +1018,7 @@ int vmw_event_fence_action_create(struct drm_file *file_priv,
        }
 
 
-       event = kzalloc(sizeof(event->event), GFP_KERNEL);
+       event = kzalloc(sizeof(*event), GFP_KERNEL);
        if (unlikely(event == NULL)) {
                DRM_ERROR("Failed to allocate an event.\n");
                ret = -ENOMEM;
index 388cbdc96db7306280b5d4ab6fcc99871e77b7ca..6aafa3d88ff0438f6585d0a315998bd8bfba5f9f 100644 (file)
@@ -426,19 +426,7 @@ static struct acpi_driver acpi_smbus_cmi_driver = {
                .remove = acpi_smbus_cmi_remove,
        },
 };
-
-static int __init acpi_smbus_cmi_init(void)
-{
-       return acpi_bus_register_driver(&acpi_smbus_cmi_driver);
-}
-
-static void __exit acpi_smbus_cmi_exit(void)
-{
-       acpi_bus_unregister_driver(&acpi_smbus_cmi_driver);
-}
-
-module_init(acpi_smbus_cmi_init);
-module_exit(acpi_smbus_cmi_exit);
+module_acpi_driver(acpi_smbus_cmi_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Crane Cai <crane.cai@amd.com>");
index e8726177d103082021a6549d4ce32d161e2bab2a..b0f6b4c8ee14c31dbdd53595a526835b9b8bb1e8 100644 (file)
@@ -413,6 +413,7 @@ static const struct x86_cpu_id intel_idle_ids[] = {
        ICPU(0x2a, idle_cpu_snb),
        ICPU(0x2d, idle_cpu_snb),
        ICPU(0x3a, idle_cpu_ivb),
+       ICPU(0x3e, idle_cpu_ivb),
        {}
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids);
index 601f7372f9c47e7eb171f2449619f66a2a0d5713..26f13131639aa8e5432f499efa155403a972607a 100644 (file)
@@ -151,22 +151,7 @@ static struct acpi_driver atlas_acpi_driver = {
                .remove = atlas_acpi_button_remove,
        },
 };
-
-static int __init atlas_acpi_init(void)
-{
-       if (acpi_disabled)
-               return -ENODEV;
-
-       return acpi_bus_register_driver(&atlas_acpi_driver);
-}
-
-static void __exit atlas_acpi_exit(void)
-{
-       acpi_bus_unregister_driver(&atlas_acpi_driver);
-}
-
-module_init(atlas_acpi_init);
-module_exit(atlas_acpi_exit);
+module_acpi_driver(atlas_acpi_driver);
 
 MODULE_AUTHOR("Jaya Kumar");
 MODULE_LICENSE("GPL");
index b64502dfa9f4567ca028bcb9b7913d4b38696019..e89daf1b21b49159e549ce863f45dd72e39b1b56 100644 (file)
@@ -266,7 +266,7 @@ static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to)
 
 static int iommu_init_device(struct device *dev)
 {
-       struct pci_dev *dma_pdev, *pdev = to_pci_dev(dev);
+       struct pci_dev *dma_pdev = NULL, *pdev = to_pci_dev(dev);
        struct iommu_dev_data *dev_data;
        struct iommu_group *group;
        u16 alias;
@@ -293,7 +293,9 @@ static int iommu_init_device(struct device *dev)
                dev_data->alias_data = alias_data;
 
                dma_pdev = pci_get_bus_and_slot(alias >> 8, alias & 0xff);
-       } else
+       }
+
+       if (dma_pdev == NULL)
                dma_pdev = pci_dev_get(pdev);
 
        /* Account for quirked devices */
index d8abb90a6c2fbecae99ae2de09ebc2f3d726731e..034233eefc8266eba122556fc6ffdb36e054eced 100644 (file)
@@ -1555,6 +1555,7 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd,
                           unsigned long arg)
 {
        struct multipath *m = ti->private;
+       struct pgpath *pgpath;
        struct block_device *bdev;
        fmode_t mode;
        unsigned long flags;
@@ -1570,12 +1571,14 @@ again:
        if (!m->current_pgpath)
                __choose_pgpath(m, 0);
 
-       if (m->current_pgpath) {
-               bdev = m->current_pgpath->path.dev->bdev;
-               mode = m->current_pgpath->path.dev->mode;
+       pgpath = m->current_pgpath;
+
+       if (pgpath) {
+               bdev = pgpath->path.dev->bdev;
+               mode = pgpath->path.dev->mode;
        }
 
-       if (m->queue_io)
+       if ((pgpath && m->queue_io) || (!pgpath && m->queue_if_no_path))
                r = -EAGAIN;
        else if (!bdev)
                r = -EIO;
index f90069029aaeed02ab6f4f61814afc92d13db2f0..100368eb7991a50c57e473ea20bf4a8441e91ff0 100644 (file)
@@ -1212,6 +1212,41 @@ struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector)
        return &t->targets[(KEYS_PER_NODE * n) + k];
 }
 
+static int count_device(struct dm_target *ti, struct dm_dev *dev,
+                       sector_t start, sector_t len, void *data)
+{
+       unsigned *num_devices = data;
+
+       (*num_devices)++;
+
+       return 0;
+}
+
+/*
+ * Check whether a table has no data devices attached using each
+ * target's iterate_devices method.
+ * Returns false if the result is unknown because a target doesn't
+ * support iterate_devices.
+ */
+bool dm_table_has_no_data_devices(struct dm_table *table)
+{
+       struct dm_target *uninitialized_var(ti);
+       unsigned i = 0, num_devices = 0;
+
+       while (i < dm_table_get_num_targets(table)) {
+               ti = dm_table_get_target(table, i++);
+
+               if (!ti->type->iterate_devices)
+                       return false;
+
+               ti->type->iterate_devices(ti, count_device, &num_devices);
+               if (num_devices)
+                       return false;
+       }
+
+       return true;
+}
+
 /*
  * Establish the new table's queue_limits and validate them.
  */
@@ -1354,17 +1389,25 @@ static int device_is_nonrot(struct dm_target *ti, struct dm_dev *dev,
        return q && blk_queue_nonrot(q);
 }
 
-static bool dm_table_is_nonrot(struct dm_table *t)
+static int device_is_not_random(struct dm_target *ti, struct dm_dev *dev,
+                            sector_t start, sector_t len, void *data)
+{
+       struct request_queue *q = bdev_get_queue(dev->bdev);
+
+       return q && !blk_queue_add_random(q);
+}
+
+static bool dm_table_all_devices_attribute(struct dm_table *t,
+                                          iterate_devices_callout_fn func)
 {
        struct dm_target *ti;
        unsigned i = 0;
 
-       /* Ensure that all underlying device are non-rotational. */
        while (i < dm_table_get_num_targets(t)) {
                ti = dm_table_get_target(t, i++);
 
                if (!ti->type->iterate_devices ||
-                   !ti->type->iterate_devices(ti, device_is_nonrot, NULL))
+                   !ti->type->iterate_devices(ti, func, NULL))
                        return 0;
        }
 
@@ -1396,13 +1439,23 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
        if (!dm_table_discard_zeroes_data(t))
                q->limits.discard_zeroes_data = 0;
 
-       if (dm_table_is_nonrot(t))
+       /* Ensure that all underlying devices are non-rotational. */
+       if (dm_table_all_devices_attribute(t, device_is_nonrot))
                queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
        else
                queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, q);
 
        dm_table_set_integrity(t);
 
+       /*
+        * Determine whether or not this queue's I/O timings contribute
+        * to the entropy pool, Only request-based targets use this.
+        * Clear QUEUE_FLAG_ADD_RANDOM if any underlying device does not
+        * have it set.
+        */
+       if (blk_queue_add_random(q) && dm_table_all_devices_attribute(t, device_is_not_random))
+               queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, q);
+
        /*
         * QUEUE_FLAG_STACKABLE must be set after all queue settings are
         * visible to other CPUs because, once the flag is set, incoming bios
index af1fc3b2c2adbb365e247a2d45c1f7a94de9b6dd..c29410af1e2211cbba6029a16128e2fabbf97976 100644 (file)
@@ -509,9 +509,9 @@ enum pool_mode {
 struct pool_features {
        enum pool_mode mode;
 
-       unsigned zero_new_blocks:1;
-       unsigned discard_enabled:1;
-       unsigned discard_passdown:1;
+       bool zero_new_blocks:1;
+       bool discard_enabled:1;
+       bool discard_passdown:1;
 };
 
 struct thin_c;
@@ -580,7 +580,8 @@ struct pool_c {
        struct dm_target_callbacks callbacks;
 
        dm_block_t low_water_blocks;
-       struct pool_features pf;
+       struct pool_features requested_pf; /* Features requested during table load */
+       struct pool_features adjusted_pf;  /* Features used after adjusting for constituent devices */
 };
 
 /*
@@ -1839,6 +1840,47 @@ static void __requeue_bios(struct pool *pool)
 /*----------------------------------------------------------------
  * Binding of control targets to a pool object
  *--------------------------------------------------------------*/
+static bool data_dev_supports_discard(struct pool_c *pt)
+{
+       struct request_queue *q = bdev_get_queue(pt->data_dev->bdev);
+
+       return q && blk_queue_discard(q);
+}
+
+/*
+ * If discard_passdown was enabled verify that the data device
+ * supports discards.  Disable discard_passdown if not.
+ */
+static void disable_passdown_if_not_supported(struct pool_c *pt)
+{
+       struct pool *pool = pt->pool;
+       struct block_device *data_bdev = pt->data_dev->bdev;
+       struct queue_limits *data_limits = &bdev_get_queue(data_bdev)->limits;
+       sector_t block_size = pool->sectors_per_block << SECTOR_SHIFT;
+       const char *reason = NULL;
+       char buf[BDEVNAME_SIZE];
+
+       if (!pt->adjusted_pf.discard_passdown)
+               return;
+
+       if (!data_dev_supports_discard(pt))
+               reason = "discard unsupported";
+
+       else if (data_limits->max_discard_sectors < pool->sectors_per_block)
+               reason = "max discard sectors smaller than a block";
+
+       else if (data_limits->discard_granularity > block_size)
+               reason = "discard granularity larger than a block";
+
+       else if (block_size & (data_limits->discard_granularity - 1))
+               reason = "discard granularity not a factor of block size";
+
+       if (reason) {
+               DMWARN("Data device (%s) %s: Disabling discard passdown.", bdevname(data_bdev, buf), reason);
+               pt->adjusted_pf.discard_passdown = false;
+       }
+}
+
 static int bind_control_target(struct pool *pool, struct dm_target *ti)
 {
        struct pool_c *pt = ti->private;
@@ -1847,31 +1889,16 @@ static int bind_control_target(struct pool *pool, struct dm_target *ti)
         * We want to make sure that degraded pools are never upgraded.
         */
        enum pool_mode old_mode = pool->pf.mode;
-       enum pool_mode new_mode = pt->pf.mode;
+       enum pool_mode new_mode = pt->adjusted_pf.mode;
 
        if (old_mode > new_mode)
                new_mode = old_mode;
 
        pool->ti = ti;
        pool->low_water_blocks = pt->low_water_blocks;
-       pool->pf = pt->pf;
-       set_pool_mode(pool, new_mode);
+       pool->pf = pt->adjusted_pf;
 
-       /*
-        * If discard_passdown was enabled verify that the data device
-        * supports discards.  Disable discard_passdown if not; otherwise
-        * -EOPNOTSUPP will be returned.
-        */
-       /* FIXME: pull this out into a sep fn. */
-       if (pt->pf.discard_passdown) {
-               struct request_queue *q = bdev_get_queue(pt->data_dev->bdev);
-               if (!q || !blk_queue_discard(q)) {
-                       char buf[BDEVNAME_SIZE];
-                       DMWARN("Discard unsupported by data device (%s): Disabling discard passdown.",
-                              bdevname(pt->data_dev->bdev, buf));
-                       pool->pf.discard_passdown = 0;
-               }
-       }
+       set_pool_mode(pool, new_mode);
 
        return 0;
 }
@@ -1889,9 +1916,9 @@ static void unbind_control_target(struct pool *pool, struct dm_target *ti)
 static void pool_features_init(struct pool_features *pf)
 {
        pf->mode = PM_WRITE;
-       pf->zero_new_blocks = 1;
-       pf->discard_enabled = 1;
-       pf->discard_passdown = 1;
+       pf->zero_new_blocks = true;
+       pf->discard_enabled = true;
+       pf->discard_passdown = true;
 }
 
 static void __pool_destroy(struct pool *pool)
@@ -2119,13 +2146,13 @@ static int parse_pool_features(struct dm_arg_set *as, struct pool_features *pf,
                argc--;
 
                if (!strcasecmp(arg_name, "skip_block_zeroing"))
-                       pf->zero_new_blocks = 0;
+                       pf->zero_new_blocks = false;
 
                else if (!strcasecmp(arg_name, "ignore_discard"))
-                       pf->discard_enabled = 0;
+                       pf->discard_enabled = false;
 
                else if (!strcasecmp(arg_name, "no_discard_passdown"))
-                       pf->discard_passdown = 0;
+                       pf->discard_passdown = false;
 
                else if (!strcasecmp(arg_name, "read_only"))
                        pf->mode = PM_READ_ONLY;
@@ -2259,8 +2286,9 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
        pt->metadata_dev = metadata_dev;
        pt->data_dev = data_dev;
        pt->low_water_blocks = low_water_blocks;
-       pt->pf = pf;
+       pt->adjusted_pf = pt->requested_pf = pf;
        ti->num_flush_requests = 1;
+
        /*
         * Only need to enable discards if the pool should pass
         * them down to the data device.  The thin device's discard
@@ -2268,12 +2296,14 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
         */
        if (pf.discard_enabled && pf.discard_passdown) {
                ti->num_discard_requests = 1;
+
                /*
                 * Setting 'discards_supported' circumvents the normal
                 * stacking of discard limits (this keeps the pool and
                 * thin devices' discard limits consistent).
                 */
                ti->discards_supported = true;
+               ti->discard_zeroes_data_unsupported = true;
        }
        ti->private = pt;
 
@@ -2703,7 +2733,7 @@ static int pool_status(struct dm_target *ti, status_type_t type,
                       format_dev_t(buf2, pt->data_dev->bdev->bd_dev),
                       (unsigned long)pool->sectors_per_block,
                       (unsigned long long)pt->low_water_blocks);
-               emit_flags(&pt->pf, result, sz, maxlen);
+               emit_flags(&pt->requested_pf, result, sz, maxlen);
                break;
        }
 
@@ -2732,20 +2762,21 @@ static int pool_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
        return min(max_size, q->merge_bvec_fn(q, bvm, biovec));
 }
 
-static void set_discard_limits(struct pool *pool, struct queue_limits *limits)
+static void set_discard_limits(struct pool_c *pt, struct queue_limits *limits)
 {
-       /*
-        * FIXME: these limits may be incompatible with the pool's data device
-        */
+       struct pool *pool = pt->pool;
+       struct queue_limits *data_limits;
+
        limits->max_discard_sectors = pool->sectors_per_block;
 
        /*
-        * This is just a hint, and not enforced.  We have to cope with
-        * bios that cover a block partially.  A discard that spans a block
-        * boundary is not sent to this target.
+        * discard_granularity is just a hint, and not enforced.
         */
-       limits->discard_granularity = pool->sectors_per_block << SECTOR_SHIFT;
-       limits->discard_zeroes_data = pool->pf.zero_new_blocks;
+       if (pt->adjusted_pf.discard_passdown) {
+               data_limits = &bdev_get_queue(pt->data_dev->bdev)->limits;
+               limits->discard_granularity = data_limits->discard_granularity;
+       } else
+               limits->discard_granularity = pool->sectors_per_block << SECTOR_SHIFT;
 }
 
 static void pool_io_hints(struct dm_target *ti, struct queue_limits *limits)
@@ -2755,15 +2786,25 @@ static void pool_io_hints(struct dm_target *ti, struct queue_limits *limits)
 
        blk_limits_io_min(limits, 0);
        blk_limits_io_opt(limits, pool->sectors_per_block << SECTOR_SHIFT);
-       if (pool->pf.discard_enabled)
-               set_discard_limits(pool, limits);
+
+       /*
+        * pt->adjusted_pf is a staging area for the actual features to use.
+        * They get transferred to the live pool in bind_control_target()
+        * called from pool_preresume().
+        */
+       if (!pt->adjusted_pf.discard_enabled)
+               return;
+
+       disable_passdown_if_not_supported(pt);
+
+       set_discard_limits(pt, limits);
 }
 
 static struct target_type pool_target = {
        .name = "thin-pool",
        .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE |
                    DM_TARGET_IMMUTABLE,
-       .version = {1, 3, 0},
+       .version = {1, 4, 0},
        .module = THIS_MODULE,
        .ctr = pool_ctr,
        .dtr = pool_dtr,
@@ -3042,19 +3083,19 @@ static int thin_iterate_devices(struct dm_target *ti,
        return 0;
 }
 
+/*
+ * A thin device always inherits its queue limits from its pool.
+ */
 static void thin_io_hints(struct dm_target *ti, struct queue_limits *limits)
 {
        struct thin_c *tc = ti->private;
-       struct pool *pool = tc->pool;
 
-       blk_limits_io_min(limits, 0);
-       blk_limits_io_opt(limits, pool->sectors_per_block << SECTOR_SHIFT);
-       set_discard_limits(pool, limits);
+       *limits = bdev_get_queue(tc->pool_dev->bdev)->limits;
 }
 
 static struct target_type thin_target = {
        .name = "thin",
-       .version = {1, 3, 0},
+       .version = {1, 4, 0},
        .module = THIS_MODULE,
        .ctr = thin_ctr,
        .dtr = thin_dtr,
index 254d19268ad2fa0c7102014c997b75294450ba42..892ae2766aa6adad52b6d99030a1d8d3bcf2ac38 100644 (file)
@@ -718,8 +718,8 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
        v->hash_dev_block_bits = ffs(num) - 1;
 
        if (sscanf(argv[5], "%llu%c", &num_ll, &dummy) != 1 ||
-           num_ll << (v->data_dev_block_bits - SECTOR_SHIFT) !=
-           (sector_t)num_ll << (v->data_dev_block_bits - SECTOR_SHIFT)) {
+           (sector_t)(num_ll << (v->data_dev_block_bits - SECTOR_SHIFT))
+           >> (v->data_dev_block_bits - SECTOR_SHIFT) != num_ll) {
                ti->error = "Invalid data blocks";
                r = -EINVAL;
                goto bad;
@@ -733,8 +733,8 @@ static int verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
        }
 
        if (sscanf(argv[6], "%llu%c", &num_ll, &dummy) != 1 ||
-           num_ll << (v->hash_dev_block_bits - SECTOR_SHIFT) !=
-           (sector_t)num_ll << (v->hash_dev_block_bits - SECTOR_SHIFT)) {
+           (sector_t)(num_ll << (v->hash_dev_block_bits - SECTOR_SHIFT))
+           >> (v->hash_dev_block_bits - SECTOR_SHIFT) != num_ll) {
                ti->error = "Invalid hash start";
                r = -EINVAL;
                goto bad;
index 4e09b6ff5b493403d4e51be0b4fee2d99643e276..67ffa391edcf1e70a0cc94e7085a1e99abd7a151 100644 (file)
@@ -865,10 +865,14 @@ static void dm_done(struct request *clone, int error, bool mapped)
 {
        int r = error;
        struct dm_rq_target_io *tio = clone->end_io_data;
-       dm_request_endio_fn rq_end_io = tio->ti->type->rq_end_io;
+       dm_request_endio_fn rq_end_io = NULL;
 
-       if (mapped && rq_end_io)
-               r = rq_end_io(tio->ti, clone, error, &tio->info);
+       if (tio->ti) {
+               rq_end_io = tio->ti->type->rq_end_io;
+
+               if (mapped && rq_end_io)
+                       r = rq_end_io(tio->ti, clone, error, &tio->info);
+       }
 
        if (r <= 0)
                /* The target wants to complete the I/O */
@@ -1588,15 +1592,6 @@ static int map_request(struct dm_target *ti, struct request *clone,
        int r, requeued = 0;
        struct dm_rq_target_io *tio = clone->end_io_data;
 
-       /*
-        * Hold the md reference here for the in-flight I/O.
-        * We can't rely on the reference count by device opener,
-        * because the device may be closed during the request completion
-        * when all bios are completed.
-        * See the comment in rq_completed() too.
-        */
-       dm_get(md);
-
        tio->ti = ti;
        r = ti->type->map_rq(ti, clone, &tio->info);
        switch (r) {
@@ -1628,6 +1623,26 @@ static int map_request(struct dm_target *ti, struct request *clone,
        return requeued;
 }
 
+static struct request *dm_start_request(struct mapped_device *md, struct request *orig)
+{
+       struct request *clone;
+
+       blk_start_request(orig);
+       clone = orig->special;
+       atomic_inc(&md->pending[rq_data_dir(clone)]);
+
+       /*
+        * Hold the md reference here for the in-flight I/O.
+        * We can't rely on the reference count by device opener,
+        * because the device may be closed during the request completion
+        * when all bios are completed.
+        * See the comment in rq_completed() too.
+        */
+       dm_get(md);
+
+       return clone;
+}
+
 /*
  * q->request_fn for request-based dm.
  * Called with the queue lock held.
@@ -1657,14 +1672,21 @@ static void dm_request_fn(struct request_queue *q)
                        pos = blk_rq_pos(rq);
 
                ti = dm_table_find_target(map, pos);
-               BUG_ON(!dm_target_is_valid(ti));
+               if (!dm_target_is_valid(ti)) {
+                       /*
+                        * Must perform setup, that dm_done() requires,
+                        * before calling dm_kill_unmapped_request
+                        */
+                       DMERR_LIMIT("request attempted access beyond the end of device");
+                       clone = dm_start_request(md, rq);
+                       dm_kill_unmapped_request(clone, -EIO);
+                       continue;
+               }
 
                if (ti->type->busy && ti->type->busy(ti))
                        goto delay_and_out;
 
-               blk_start_request(rq);
-               clone = rq->special;
-               atomic_inc(&md->pending[rq_data_dir(clone)]);
+               clone = dm_start_request(md, rq);
 
                spin_unlock(q->queue_lock);
                if (map_request(ti, clone, md))
@@ -1684,8 +1706,6 @@ delay_and_out:
        blk_delay_queue(q, HZ / 10);
 out:
        dm_table_put(map);
-
-       return;
 }
 
 int dm_underlying_device_busy(struct request_queue *q)
@@ -2409,7 +2429,7 @@ static void dm_queue_flush(struct mapped_device *md)
  */
 struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table)
 {
-       struct dm_table *map = ERR_PTR(-EINVAL);
+       struct dm_table *live_map, *map = ERR_PTR(-EINVAL);
        struct queue_limits limits;
        int r;
 
@@ -2419,6 +2439,19 @@ struct dm_table *dm_swap_table(struct mapped_device *md, struct dm_table *table)
        if (!dm_suspended_md(md))
                goto out;
 
+       /*
+        * If the new table has no data devices, retain the existing limits.
+        * This helps multipath with queue_if_no_path if all paths disappear,
+        * then new I/O is queued based on these limits, and then some paths
+        * reappear.
+        */
+       if (dm_table_has_no_data_devices(table)) {
+               live_map = dm_get_live_table(md);
+               if (live_map)
+                       limits = md->queue->limits;
+               dm_table_put(live_map);
+       }
+
        r = dm_calculate_queue_limits(table, &limits);
        if (r) {
                map = ERR_PTR(r);
index 52eef493d2669290eaa3f2a22e46717dac9aa1eb..6a99fefaa74306aa6e586c47c3eacf33706556b1 100644 (file)
@@ -54,6 +54,7 @@ void dm_table_event_callback(struct dm_table *t,
                             void (*fn)(void *), void *context);
 struct dm_target *dm_table_get_target(struct dm_table *t, unsigned int index);
 struct dm_target *dm_table_find_target(struct dm_table *t, sector_t sector);
+bool dm_table_has_no_data_devices(struct dm_table *table);
 int dm_calculate_queue_limits(struct dm_table *table,
                              struct queue_limits *limits);
 void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
index 1c2eb38f3c51a6dcc93148ca34b1a6a1de7aa465..0138a727c1f3c220bc91a02c9bdf720599465eb9 100644 (file)
@@ -1512,14 +1512,16 @@ static int _enough(struct r10conf *conf, struct geom *geo, int ignore)
        do {
                int n = conf->copies;
                int cnt = 0;
+               int this = first;
                while (n--) {
-                       if (conf->mirrors[first].rdev &&
-                           first != ignore)
+                       if (conf->mirrors[this].rdev &&
+                           this != ignore)
                                cnt++;
-                       first = (first+1) % geo->raid_disks;
+                       this = (this+1) % geo->raid_disks;
                }
                if (cnt == 0)
                        return 0;
+               first = (first + geo->near_copies) % geo->raid_disks;
        } while (first != 0);
        return 1;
 }
index 7031b865b3a030488614764528295d509c663ba5..0689173fd9f568583708c53396631ac8e1838c55 100644 (file)
@@ -1591,6 +1591,7 @@ static int resize_stripes(struct r5conf *conf, int newsize)
                #ifdef CONFIG_MULTICORE_RAID456
                init_waitqueue_head(&nsh->ops.wait_for_ops);
                #endif
+               spin_lock_init(&nsh->stripe_lock);
 
                list_add(&nsh->lru, &newstripes);
        }
index f2f482bec5736b21a562da5e4fda11375e8cf457..a6e74514e6624e95f8e6e56fb319d567b1011f78 100644 (file)
@@ -1123,6 +1123,33 @@ static unsigned long mtdchar_get_unmapped_area(struct file *file,
 }
 #endif
 
+static inline unsigned long get_vm_size(struct vm_area_struct *vma)
+{
+       return vma->vm_end - vma->vm_start;
+}
+
+static inline resource_size_t get_vm_offset(struct vm_area_struct *vma)
+{
+       return (resource_size_t) vma->vm_pgoff << PAGE_SHIFT;
+}
+
+/*
+ * Set a new vm offset.
+ *
+ * Verify that the incoming offset really works as a page offset,
+ * and that the offset and size fit in a resource_size_t.
+ */
+static inline int set_vm_offset(struct vm_area_struct *vma, resource_size_t off)
+{
+       pgoff_t pgoff = off >> PAGE_SHIFT;
+       if (off != (resource_size_t) pgoff << PAGE_SHIFT)
+               return -EINVAL;
+       if (off + get_vm_size(vma) - 1 < off)
+               return -EINVAL;
+       vma->vm_pgoff = pgoff;
+       return 0;
+}
+
 /*
  * set up a mapping for shared memory segments
  */
@@ -1132,20 +1159,29 @@ static int mtdchar_mmap(struct file *file, struct vm_area_struct *vma)
        struct mtd_file_info *mfi = file->private_data;
        struct mtd_info *mtd = mfi->mtd;
        struct map_info *map = mtd->priv;
-       unsigned long start;
-       unsigned long off;
-       u32 len;
+       resource_size_t start, off;
+       unsigned long len, vma_len;
 
        if (mtd->type == MTD_RAM || mtd->type == MTD_ROM) {
-               off = vma->vm_pgoff << PAGE_SHIFT;
+               off = get_vm_offset(vma);
                start = map->phys;
                len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size);
                start &= PAGE_MASK;
-               if ((vma->vm_end - vma->vm_start + off) > len)
+               vma_len = get_vm_size(vma);
+
+               /* Overflow in off+len? */
+               if (vma_len + off < off)
+                       return -EINVAL;
+               /* Does it fit in the mapping? */
+               if (vma_len + off > len)
                        return -EINVAL;
 
                off += start;
-               vma->vm_pgoff = off >> PAGE_SHIFT;
+               /* Did that overflow? */
+               if (off < start)
+                       return -EINVAL;
+               if (set_vm_offset(vma, off) < 0)
+                       return -EINVAL;
                vma->vm_flags |= VM_IO | VM_RESERVED;
 
 #ifdef pgprot_noncached
index 79cebd8525ce3d451e30b935484dac18535939f2..e48312f2305db18a08b5744a01013455a7b732ab 100644 (file)
@@ -8564,7 +8564,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        return 0;
 
 error:
-       iounmap(bp->regview);
+       pci_iounmap(pdev, bp->regview);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
index c42bbb16cdaebdeb7147dc887705abcfe91e86e0..a688a2ddcfd612866edbce5f8ee08b7f92fbd8e0 100644 (file)
@@ -722,10 +722,8 @@ static int octeon_mgmt_init_phy(struct net_device *netdev)
                                   octeon_mgmt_adjust_link, 0,
                                   PHY_INTERFACE_MODE_MII);
 
-       if (IS_ERR(p->phydev)) {
-               p->phydev = NULL;
+       if (!p->phydev)
                return -1;
-       }
 
        phy_start_aneg(p->phydev);
 
index e559dfa06d6ace1c349cf48efe33738ef642e778..6fa74d530e44d390ce87946b8327a476e5a728e5 100644 (file)
@@ -1101,9 +1101,9 @@ static int pasemi_mac_phy_init(struct net_device *dev)
        phydev = of_phy_connect(dev, phy_dn, &pasemi_adjust_link, 0,
                                PHY_INTERFACE_MODE_SGMII);
 
-       if (IS_ERR(phydev)) {
+       if (!phydev) {
                printk(KERN_ERR "%s: Could not attach to phy\n", dev->name);
-               return PTR_ERR(phydev);
+               return -ENODEV;
        }
 
        mac->phydev = phydev;
index b8ead696141efbaf452f3a46c23dfba1f199f2fb..2a179d087207e4375afb0d66f712043a10417786 100644 (file)
@@ -15,7 +15,7 @@ qlcnic_poll_rsp(struct qlcnic_adapter *adapter)
 
        do {
                /* give atleast 1ms for firmware to respond */
-               msleep(1);
+               mdelay(1);
 
                if (++timeout > QLCNIC_OS_CRB_RETRY_COUNT)
                        return QLCNIC_CDRP_RSP_TIMEOUT;
@@ -601,7 +601,7 @@ void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter)
                qlcnic_fw_cmd_destroy_tx_ctx(adapter);
 
                /* Allow dma queues to drain after context reset */
-               msleep(20);
+               mdelay(20);
        }
 }
 
index 2346b38b9837101deae4848443da3d5b6be7cdeb..799789518e873edf273c95be6ec1c3b59ff4aa80 100644 (file)
@@ -229,3 +229,5 @@ static void __exit bcm87xx_exit(void)
                ARRAY_SIZE(bcm87xx_driver));
 }
 module_exit(bcm87xx_exit);
+
+MODULE_LICENSE("GPL");
index cf287e0eb4088574530bdb65b86d0276b589b744..2165d5fdb8c0f08675772f8dded60f3a15ac34ba 100644 (file)
 #include <linux/phy.h>
 #include <linux/micrel_phy.h>
 
+/* Operation Mode Strap Override */
+#define MII_KSZPHY_OMSO                                0x16
+#define KSZPHY_OMSO_B_CAST_OFF                 (1 << 9)
+#define KSZPHY_OMSO_RMII_OVERRIDE              (1 << 1)
+#define KSZPHY_OMSO_MII_OVERRIDE               (1 << 0)
+
 /* general Interrupt control/status reg in vendor specific block. */
 #define MII_KSZPHY_INTCS                       0x1B
 #define        KSZPHY_INTCS_JABBER                     (1 << 15)
@@ -101,6 +107,13 @@ static int kszphy_config_init(struct phy_device *phydev)
        return 0;
 }
 
+static int ksz8021_config_init(struct phy_device *phydev)
+{
+       const u16 val = KSZPHY_OMSO_B_CAST_OFF | KSZPHY_OMSO_RMII_OVERRIDE;
+       phy_write(phydev, MII_KSZPHY_OMSO, val);
+       return 0;
+}
+
 static int ks8051_config_init(struct phy_device *phydev)
 {
        int regval;
@@ -128,9 +141,22 @@ static struct phy_driver ksphy_driver[] = {
        .config_intr    = ks8737_config_intr,
        .driver         = { .owner = THIS_MODULE,},
 }, {
-       .phy_id         = PHY_ID_KS8041,
+       .phy_id         = PHY_ID_KSZ8021,
+       .phy_id_mask    = 0x00ffffff,
+       .name           = "Micrel KSZ8021",
+       .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause |
+                          SUPPORTED_Asym_Pause),
+       .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
+       .config_init    = ksz8021_config_init,
+       .config_aneg    = genphy_config_aneg,
+       .read_status    = genphy_read_status,
+       .ack_interrupt  = kszphy_ack_interrupt,
+       .config_intr    = kszphy_config_intr,
+       .driver         = { .owner = THIS_MODULE,},
+}, {
+       .phy_id         = PHY_ID_KSZ8041,
        .phy_id_mask    = 0x00fffff0,
-       .name           = "Micrel KS8041",
+       .name           = "Micrel KSZ8041",
        .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause
                                | SUPPORTED_Asym_Pause),
        .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
@@ -141,9 +167,9 @@ static struct phy_driver ksphy_driver[] = {
        .config_intr    = kszphy_config_intr,
        .driver         = { .owner = THIS_MODULE,},
 }, {
-       .phy_id         = PHY_ID_KS8051,
+       .phy_id         = PHY_ID_KSZ8051,
        .phy_id_mask    = 0x00fffff0,
-       .name           = "Micrel KS8051",
+       .name           = "Micrel KSZ8051",
        .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause
                                | SUPPORTED_Asym_Pause),
        .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
@@ -154,8 +180,8 @@ static struct phy_driver ksphy_driver[] = {
        .config_intr    = kszphy_config_intr,
        .driver         = { .owner = THIS_MODULE,},
 }, {
-       .phy_id         = PHY_ID_KS8001,
-       .name           = "Micrel KS8001 or KS8721",
+       .phy_id         = PHY_ID_KSZ8001,
+       .name           = "Micrel KSZ8001 or KS8721",
        .phy_id_mask    = 0x00ffffff,
        .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
        .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
@@ -201,10 +227,11 @@ MODULE_LICENSE("GPL");
 
 static struct mdio_device_id __maybe_unused micrel_tbl[] = {
        { PHY_ID_KSZ9021, 0x000ffffe },
-       { PHY_ID_KS8001, 0x00ffffff },
+       { PHY_ID_KSZ8001, 0x00ffffff },
        { PHY_ID_KS8737, 0x00fffff0 },
-       { PHY_ID_KS8041, 0x00fffff0 },
-       { PHY_ID_KS8051, 0x00fffff0 },
+       { PHY_ID_KSZ8021, 0x00ffffff },
+       { PHY_ID_KSZ8041, 0x00fffff0 },
+       { PHY_ID_KSZ8051, 0x00fffff0 },
        { }
 };
 
index 6d6192316b30988ed742cf7261de5c5daaa310f2..88e3991464e7e1531934bcb562718e97abcbfb9b 100644 (file)
@@ -56,6 +56,32 @@ static int smsc_phy_config_init(struct phy_device *phydev)
        return smsc_phy_ack_interrupt (phydev);
 }
 
+static int lan87xx_config_init(struct phy_device *phydev)
+{
+       /*
+        * Make sure the EDPWRDOWN bit is NOT set. Setting this bit on
+        * LAN8710/LAN8720 PHY causes the PHY to misbehave, likely due
+        * to a bug on the chip.
+        *
+        * When the system is powered on with the network cable being
+        * disconnected all the way until after ifconfig ethX up is
+        * issued for the LAN port with this PHY, connecting the cable
+        * afterwards does not cause LINK change detection, while the
+        * expected behavior is the Link UP being detected.
+        */
+       int rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
+       if (rc < 0)
+               return rc;
+
+       rc &= ~MII_LAN83C185_EDPWRDOWN;
+
+       rc = phy_write(phydev, MII_LAN83C185_CTRL_STATUS, rc);
+       if (rc < 0)
+               return rc;
+
+       return smsc_phy_ack_interrupt(phydev);
+}
+
 static int lan911x_config_init(struct phy_device *phydev)
 {
        return smsc_phy_ack_interrupt(phydev);
@@ -162,7 +188,7 @@ static struct phy_driver smsc_phy_driver[] = {
        /* basic functions */
        .config_aneg    = genphy_config_aneg,
        .read_status    = genphy_read_status,
-       .config_init    = smsc_phy_config_init,
+       .config_init    = lan87xx_config_init,
 
        /* IRQ related */
        .ack_interrupt  = smsc_phy_ack_interrupt,
index cbf7047decc04340d39be3daa95359469b9e73ec..20f31d0d1536c36658b481fa083eb6b445637ef7 100644 (file)
@@ -570,7 +570,7 @@ static int pppoe_release(struct socket *sock)
 
        po = pppox_sk(sk);
 
-       if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
+       if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) {
                dev_put(po->pppoe_dev);
                po->pppoe_dev = NULL;
        }
index 341b65dbbcd324d9512f957fc7b663481a073aea..f8cd61f449a4772da5a50a446cd07fc80d5928c8 100644 (file)
@@ -848,7 +848,7 @@ static struct netpoll_info *team_netpoll_info(struct team *team)
 }
 #endif
 
-static void __team_port_change_check(struct team_port *port, bool linkup);
+static void __team_port_change_port_added(struct team_port *port, bool linkup);
 
 static int team_port_add(struct team *team, struct net_device *port_dev)
 {
@@ -948,7 +948,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev)
        team_port_enable(team, port);
        list_add_tail_rcu(&port->list, &team->port_list);
        __team_compute_features(team);
-       __team_port_change_check(port, !!netif_carrier_ok(port_dev));
+       __team_port_change_port_added(port, !!netif_carrier_ok(port_dev));
        __team_options_change_check(team);
 
        netdev_info(dev, "Port device %s added\n", portname);
@@ -983,6 +983,8 @@ err_set_mtu:
        return err;
 }
 
+static void __team_port_change_port_removed(struct team_port *port);
+
 static int team_port_del(struct team *team, struct net_device *port_dev)
 {
        struct net_device *dev = team->dev;
@@ -999,8 +1001,7 @@ static int team_port_del(struct team *team, struct net_device *port_dev)
        __team_option_inst_mark_removed_port(team, port);
        __team_options_change_check(team);
        __team_option_inst_del_port(team, port);
-       port->removed = true;
-       __team_port_change_check(port, false);
+       __team_port_change_port_removed(port);
        team_port_disable(team, port);
        list_del_rcu(&port->list);
        netdev_rx_handler_unregister(port_dev);
@@ -1652,8 +1653,8 @@ static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)
 
        hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
                          &team_nl_family, 0, TEAM_CMD_NOOP);
-       if (IS_ERR(hdr)) {
-               err = PTR_ERR(hdr);
+       if (!hdr) {
+               err = -EMSGSIZE;
                goto err_msg_put;
        }
 
@@ -1847,8 +1848,8 @@ start_again:
 
        hdr = genlmsg_put(skb, pid, seq, &team_nl_family, flags | NLM_F_MULTI,
                          TEAM_CMD_OPTIONS_GET);
-       if (IS_ERR(hdr))
-               return PTR_ERR(hdr);
+       if (!hdr)
+               return -EMSGSIZE;
 
        if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
                goto nla_put_failure;
@@ -2067,8 +2068,8 @@ static int team_nl_fill_port_list_get(struct sk_buff *skb,
 
        hdr = genlmsg_put(skb, pid, seq, &team_nl_family, flags,
                          TEAM_CMD_PORT_LIST_GET);
-       if (IS_ERR(hdr))
-               return PTR_ERR(hdr);
+       if (!hdr)
+               return -EMSGSIZE;
 
        if (nla_put_u32(skb, TEAM_ATTR_TEAM_IFINDEX, team->dev->ifindex))
                goto nla_put_failure;
@@ -2251,13 +2252,11 @@ static void __team_options_change_check(struct team *team)
 }
 
 /* rtnl lock is held */
-static void __team_port_change_check(struct team_port *port, bool linkup)
+
+static void __team_port_change_send(struct team_port *port, bool linkup)
 {
        int err;
 
-       if (!port->removed && port->state.linkup == linkup)
-               return;
-
        port->changed = true;
        port->state.linkup = linkup;
        team_refresh_port_linkup(port);
@@ -2282,6 +2281,23 @@ send_event:
 
 }
 
+static void __team_port_change_check(struct team_port *port, bool linkup)
+{
+       if (port->state.linkup != linkup)
+               __team_port_change_send(port, linkup);
+}
+
+static void __team_port_change_port_added(struct team_port *port, bool linkup)
+{
+       __team_port_change_send(port, linkup);
+}
+
+static void __team_port_change_port_removed(struct team_port *port)
+{
+       port->removed = true;
+       __team_port_change_send(port, false);
+}
+
 static void team_port_change_check(struct team_port *port, bool linkup)
 {
        struct team *team = port->team;
index f5ab6e613ec8dcddf6b36e25a1dd0f79c50849db..376143e8a1aaf6f78ee44fb76888922064c46dd1 100644 (file)
@@ -1253,6 +1253,7 @@ static struct usb_driver smsc75xx_driver = {
        .probe          = usbnet_probe,
        .suspend        = usbnet_suspend,
        .resume         = usbnet_resume,
+       .reset_resume   = usbnet_resume,
        .disconnect     = usbnet_disconnect,
        .disable_hub_initiated_lpm = 1,
 };
index 1e86ea2266d46971844ba5c66a2fb1142a47609d..dbeebef562d5ca0bca0c9b3ac391747ebfe02973 100644 (file)
@@ -1442,6 +1442,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
        return err;
 
 err_free_irq:
+       trans_pcie->irq_requested = false;
        free_irq(trans_pcie->irq, trans);
 error:
        iwl_free_isr_ict(trans);
index 6b9af989632b72a9f2c0b1641a5fdd5600844de0..18d74f29dcb21784c6f83814f46e58d67366ae3c 100644 (file)
@@ -382,31 +382,8 @@ static struct acpi_driver lis3lv02d_driver = {
        },
        .drv.pm = HP_ACCEL_PM,
 };
-
-static int __init lis3lv02d_init_module(void)
-{
-       int ret;
-
-       if (acpi_disabled)
-               return -ENODEV;
-
-       ret = acpi_bus_register_driver(&lis3lv02d_driver);
-       if (ret < 0)
-               return ret;
-
-       pr_info("driver loaded\n");
-
-       return 0;
-}
-
-static void __exit lis3lv02d_exit_module(void)
-{
-       acpi_bus_unregister_driver(&lis3lv02d_driver);
-}
+module_acpi_driver(lis3lv02d_driver);
 
 MODULE_DESCRIPTION("Glue between LIS3LV02Dx and HP ACPI BIOS and support for disk protection LED.");
 MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek");
 MODULE_LICENSE("GPL");
-
-module_init(lis3lv02d_init_module);
-module_exit(lis3lv02d_exit_module);
index dae7abe1d711487ce3499232f809f28bc3983232..5ff4f2e314d2857656de31f127823dc8d20556af 100644 (file)
@@ -917,20 +917,8 @@ static struct acpi_driver ideapad_acpi_driver = {
        .drv.pm = &ideapad_pm,
        .owner = THIS_MODULE,
 };
-
-static int __init ideapad_acpi_module_init(void)
-{
-       return acpi_bus_register_driver(&ideapad_acpi_driver);
-}
-
-static void __exit ideapad_acpi_module_exit(void)
-{
-       acpi_bus_unregister_driver(&ideapad_acpi_driver);
-}
+module_acpi_driver(ideapad_acpi_driver);
 
 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
 MODULE_DESCRIPTION("IdeaPad ACPI Extras");
 MODULE_LICENSE("GPL");
-
-module_init(ideapad_acpi_module_init);
-module_exit(ideapad_acpi_module_exit);
index d528daa0e81c0eec51b23c962c2e7eb5ce0047d2..d727bfee89a6eef656aef88df13b78e4d082ad49 100644 (file)
@@ -186,27 +186,7 @@ static struct acpi_driver acpi_topstar_driver = {
                .notify = acpi_topstar_notify,
        },
 };
-
-static int __init topstar_laptop_init(void)
-{
-       int ret;
-
-       ret = acpi_bus_register_driver(&acpi_topstar_driver);
-       if (ret < 0)
-               return ret;
-
-       pr_info("ACPI extras driver loaded\n");
-
-       return 0;
-}
-
-static void __exit topstar_laptop_exit(void)
-{
-       acpi_bus_unregister_driver(&acpi_topstar_driver);
-}
-
-module_init(topstar_laptop_init);
-module_exit(topstar_laptop_exit);
+module_acpi_driver(acpi_topstar_driver);
 
 MODULE_AUTHOR("Herton Ronaldo Krzesinski");
 MODULE_DESCRIPTION("Topstar Laptop ACPI Extras driver");
index 5e5d6317d690095b9f95ff761b2c5d5d0cb5a7d4..e95be0b74859b286c92979a1de1e766abaf4e65e 100644 (file)
@@ -122,30 +122,10 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device)
        return result;
 }
 
-static int __init toshiba_bt_rfkill_init(void)
-{
-       int result;
-
-       result = acpi_bus_register_driver(&toshiba_bt_rfkill_driver);
-       if (result < 0) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                                 "Error registering driver\n"));
-               return result;
-       }
-
-       return 0;
-}
-
 static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type)
 {
        /* clean up */
        return 0;
 }
 
-static void __exit toshiba_bt_rfkill_exit(void)
-{
-       acpi_bus_unregister_driver(&toshiba_bt_rfkill_driver);
-}
-
-module_init(toshiba_bt_rfkill_init);
-module_exit(toshiba_bt_rfkill_exit);
+module_acpi_driver(toshiba_bt_rfkill_driver);
index 38ba39d7ca7de5cebd5f45163f55035b4f303d6e..16d340c3b85256fad50fe57c4ca620d49f8fdcc1 100644 (file)
@@ -170,16 +170,4 @@ static struct acpi_driver xo15_ebook_driver = {
        },
        .drv.pm = &ebook_switch_pm,
 };
-
-static int __init xo15_ebook_init(void)
-{
-       return acpi_bus_register_driver(&xo15_ebook_driver);
-}
-
-static void __exit xo15_ebook_exit(void)
-{
-       acpi_bus_unregister_driver(&xo15_ebook_driver);
-}
-
-module_init(xo15_ebook_init);
-module_exit(xo15_ebook_exit);
+module_acpi_driver(xo15_ebook_driver);
index 507a8e2b9a4c9e527347876706f92e95d0fa631f..26b5d4b18dd7ac633119cbe7c7562e385624430a 100644 (file)
@@ -321,14 +321,9 @@ static int __init acpi_pnp_match(struct device *dev, void *_pnp)
 {
        struct acpi_device *acpi = to_acpi_device(dev);
        struct pnp_dev *pnp = _pnp;
-       struct device *physical_device;
-
-       physical_device = acpi_get_physical_device(acpi->handle);
-       if (physical_device)
-               put_device(physical_device);
 
        /* true means it matched */
-       return !physical_device
+       return !acpi->physical_node_count
            && compare_pnp_id(pnp->id, acpi_device_hid(acpi));
 }
 
index a3ac39b79192a4c8f2de0d063054f5477a1f257a..0646bf6e7889a10ed6e4773af378c264377d5f8b 100644 (file)
@@ -208,6 +208,8 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,
 
                break;
        case PINMUX_TYPE_GPIO:
+       case PINMUX_TYPE_INPUT:
+       case PINMUX_TYPE_OUTPUT:
                break;
        default:
                pr_err("Unsupported mux type (%d), bailing...\n", pinmux_type);
index d9569658476274f34d8a51726da828d87bf44831..3440812b4a849c3d2f372e022f730ade5f5e3e6b 100644 (file)
@@ -624,7 +624,7 @@ static ssize_t usb_device_read(struct file *file, char __user *buf,
        /* print devices for all busses */
        list_for_each_entry(bus, &usb_bus_list, bus_list) {
                /* recurse through all children of the root hub */
-               if (!bus->root_hub)
+               if (!bus_to_hcd(bus)->rh_registered)
                        continue;
                usb_lock_device(bus->root_hub);
                ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos,
index bc84106ac057d7affb0e4d7c5c6ce22dcc2b7943..75ba2091f9b4f253a699563e22a9c6fd80c12676 100644 (file)
@@ -1011,10 +1011,7 @@ static int register_root_hub(struct usb_hcd *hcd)
        if (retval) {
                dev_err (parent_dev, "can't register root hub for %s, %d\n",
                                dev_name(&usb_dev->dev), retval);
-       }
-       mutex_unlock(&usb_bus_list_lock);
-
-       if (retval == 0) {
+       } else {
                spin_lock_irq (&hcd_root_hub_lock);
                hcd->rh_registered = 1;
                spin_unlock_irq (&hcd_root_hub_lock);
@@ -1023,6 +1020,7 @@ static int register_root_hub(struct usb_hcd *hcd)
                if (HCD_DEAD(hcd))
                        usb_hc_died (hcd);      /* This time clean up */
        }
+       mutex_unlock(&usb_bus_list_lock);
 
        return retval;
 }
index 8947b203d5a4dd1cbe2dcc190a9d3b19363bf75b..ce45f553523628f9533f7b235971b9f19c005032 100644 (file)
@@ -52,18 +52,19 @@ out:
 static int usb_acpi_check_pld(struct usb_device *udev, acpi_handle handle)
 {
        acpi_status status;
-       struct acpi_pld pld;
+       struct acpi_pld_info *pld;
 
        status = acpi_get_physical_device_location(handle, &pld);
 
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
-       if (pld.user_visible)
+       if (pld->user_visible)
                udev->removable = USB_DEVICE_REMOVABLE;
        else
                udev->removable = USB_DEVICE_FIXED;
 
+       ACPI_FREE(pld);
        return 0;
 }
 
index aaa8d2bce21702aa8d7844bb343de68bd30f0a3d..0bf72f943b00d392654fdc9613e4f397bfac2d32 100644 (file)
@@ -467,7 +467,8 @@ static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)
        /* From the GPIO notifying the over-current situation, find
         * out the corresponding port */
        at91_for_each_port(port) {
-               if (gpio_to_irq(pdata->overcurrent_pin[port]) == irq) {
+               if (gpio_is_valid(pdata->overcurrent_pin[port]) &&
+                               gpio_to_irq(pdata->overcurrent_pin[port]) == irq) {
                        gpio = pdata->overcurrent_pin[port];
                        break;
                }
index 211a4920b88a577216ed9905db510c691cdb4d84..d8dedc7d3910c7bdc362dac6e099326642f0f1fb 100644 (file)
@@ -76,9 +76,24 @@ static int virqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key)
                        schedule_work(&virqfd->inject);
        }
 
-       if (flags & POLLHUP)
-               /* The eventfd is closing, detach from VFIO */
-               virqfd_deactivate(virqfd);
+       if (flags & POLLHUP) {
+               unsigned long flags;
+               spin_lock_irqsave(&virqfd->vdev->irqlock, flags);
+
+               /*
+                * The eventfd is closing, if the virqfd has not yet been
+                * queued for release, as determined by testing whether the
+                * vdev pointer to it is still valid, queue it now.  As
+                * with kvm irqfds, we know we won't race against the virqfd
+                * going away because we hold wqh->lock to get here.
+                */
+               if (*(virqfd->pvirqfd) == virqfd) {
+                       *(virqfd->pvirqfd) = NULL;
+                       virqfd_deactivate(virqfd);
+               }
+
+               spin_unlock_irqrestore(&virqfd->vdev->irqlock, flags);
+       }
 
        return 0;
 }
@@ -93,7 +108,6 @@ static void virqfd_ptable_queue_proc(struct file *file,
 static void virqfd_shutdown(struct work_struct *work)
 {
        struct virqfd *virqfd = container_of(work, struct virqfd, shutdown);
-       struct virqfd **pvirqfd = virqfd->pvirqfd;
        u64 cnt;
 
        eventfd_ctx_remove_wait_queue(virqfd->eventfd, &virqfd->wait, &cnt);
@@ -101,7 +115,6 @@ static void virqfd_shutdown(struct work_struct *work)
        eventfd_ctx_put(virqfd->eventfd);
 
        kfree(virqfd);
-       *pvirqfd = NULL;
 }
 
 static void virqfd_inject(struct work_struct *work)
@@ -122,15 +135,11 @@ static int virqfd_enable(struct vfio_pci_device *vdev,
        int ret = 0;
        unsigned int events;
 
-       if (*pvirqfd)
-               return -EBUSY;
-
        virqfd = kzalloc(sizeof(*virqfd), GFP_KERNEL);
        if (!virqfd)
                return -ENOMEM;
 
        virqfd->pvirqfd = pvirqfd;
-       *pvirqfd = virqfd;
        virqfd->vdev = vdev;
        virqfd->handler = handler;
        virqfd->thread = thread;
@@ -153,6 +162,23 @@ static int virqfd_enable(struct vfio_pci_device *vdev,
 
        virqfd->eventfd = ctx;
 
+       /*
+        * virqfds can be released by closing the eventfd or directly
+        * through ioctl.  These are both done through a workqueue, so
+        * we update the pointer to the virqfd under lock to avoid
+        * pushing multiple jobs to release the same virqfd.
+        */
+       spin_lock_irq(&vdev->irqlock);
+
+       if (*pvirqfd) {
+               spin_unlock_irq(&vdev->irqlock);
+               ret = -EBUSY;
+               goto fail;
+       }
+       *pvirqfd = virqfd;
+
+       spin_unlock_irq(&vdev->irqlock);
+
        /*
         * Install our own custom wake-up handling so we are notified via
         * a callback whenever someone signals the underlying eventfd.
@@ -187,19 +213,29 @@ fail:
                fput(file);
 
        kfree(virqfd);
-       *pvirqfd = NULL;
 
        return ret;
 }
 
-static void virqfd_disable(struct virqfd *virqfd)
+static void virqfd_disable(struct vfio_pci_device *vdev,
+                          struct virqfd **pvirqfd)
 {
-       if (!virqfd)
-               return;
+       unsigned long flags;
+
+       spin_lock_irqsave(&vdev->irqlock, flags);
+
+       if (*pvirqfd) {
+               virqfd_deactivate(*pvirqfd);
+               *pvirqfd = NULL;
+       }
 
-       virqfd_deactivate(virqfd);
+       spin_unlock_irqrestore(&vdev->irqlock, flags);
 
-       /* Block until we know all outstanding shutdown jobs have completed. */
+       /*
+        * Block until we know all outstanding shutdown jobs have completed.
+        * Even if we don't queue the job, flush the wq to be sure it's
+        * been released.
+        */
        flush_workqueue(vfio_irqfd_cleanup_wq);
 }
 
@@ -392,8 +428,8 @@ static int vfio_intx_set_signal(struct vfio_pci_device *vdev, int fd)
 static void vfio_intx_disable(struct vfio_pci_device *vdev)
 {
        vfio_intx_set_signal(vdev, -1);
-       virqfd_disable(vdev->ctx[0].unmask);
-       virqfd_disable(vdev->ctx[0].mask);
+       virqfd_disable(vdev, &vdev->ctx[0].unmask);
+       virqfd_disable(vdev, &vdev->ctx[0].mask);
        vdev->irq_type = VFIO_PCI_NUM_IRQS;
        vdev->num_ctx = 0;
        kfree(vdev->ctx);
@@ -539,8 +575,8 @@ static void vfio_msi_disable(struct vfio_pci_device *vdev, bool msix)
        vfio_msi_set_block(vdev, 0, vdev->num_ctx, NULL, msix);
 
        for (i = 0; i < vdev->num_ctx; i++) {
-               virqfd_disable(vdev->ctx[i].unmask);
-               virqfd_disable(vdev->ctx[i].mask);
+               virqfd_disable(vdev, &vdev->ctx[i].unmask);
+               virqfd_disable(vdev, &vdev->ctx[i].mask);
        }
 
        if (msix) {
@@ -577,7 +613,7 @@ static int vfio_pci_set_intx_unmask(struct vfio_pci_device *vdev,
                                             vfio_send_intx_eventfd, NULL,
                                             &vdev->ctx[0].unmask, fd);
 
-               virqfd_disable(vdev->ctx[0].unmask);
+               virqfd_disable(vdev, &vdev->ctx[0].unmask);
        }
 
        return 0;
index 16521a9f203859a28a8804d3fb2f5f4cb894ed7f..693f95bf1caeb8769517aa7046702f86b6494fa7 100644 (file)
@@ -1134,6 +1134,8 @@ positive:
        return 1;
 
 rename_retry:
+       if (locked)
+               goto again;
        locked = 1;
        write_seqlock(&rename_lock);
        goto again;
@@ -1141,7 +1143,7 @@ rename_retry:
 EXPORT_SYMBOL(have_submounts);
 
 /*
- * Search the dentry child list for the specified parent,
+ * Search the dentry child list of the specified parent,
  * and move any unused dentries to the end of the unused
  * list for prune_dcache(). We descend to the next level
  * whenever the d_subdirs list is non-empty and continue
@@ -1236,6 +1238,8 @@ out:
 rename_retry:
        if (found)
                return found;
+       if (locked)
+               goto again;
        locked = 1;
        write_seqlock(&rename_lock);
        goto again;
@@ -3035,6 +3039,8 @@ resume:
        return;
 
 rename_retry:
+       if (locked)
+               goto again;
        locked = 1;
        write_seqlock(&rename_lock);
        goto again;
index fb1a2bedbe9789a8fcca5618b4637d70b25fb8ab..8d80c990dffdfc34b9f0168c39d208b99018c01e 100644 (file)
@@ -289,7 +289,6 @@ static void nlmsvc_free_block(struct kref *kref)
        dprintk("lockd: freeing block %p...\n", block);
 
        /* Remove block from file's list of blocks */
-       mutex_lock(&file->f_mutex);
        list_del_init(&block->b_flist);
        mutex_unlock(&file->f_mutex);
 
@@ -303,7 +302,7 @@ static void nlmsvc_free_block(struct kref *kref)
 static void nlmsvc_release_block(struct nlm_block *block)
 {
        if (block != NULL)
-               kref_put(&block->b_count, nlmsvc_free_block);
+               kref_put_mutex(&block->b_count, nlmsvc_free_block, &block->b_file->f_mutex);
 }
 
 /*
index 4d31f73e2561d4d0e19d85becc0223dda27b4710..7bdf7907413f0ea5f3c9e9c2de6b4002381e2064 100644 (file)
@@ -1886,8 +1886,14 @@ static int do_add_mount(struct mount *newmnt, struct path *path, int mnt_flags)
                return err;
 
        err = -EINVAL;
-       if (!(mnt_flags & MNT_SHRINKABLE) && !check_mnt(real_mount(path->mnt)))
-               goto unlock;
+       if (unlikely(!check_mnt(real_mount(path->mnt)))) {
+               /* that's acceptable only for automounts done in private ns */
+               if (!(mnt_flags & MNT_SHRINKABLE))
+                       goto unlock;
+               /* ... and for those we'd better have mountpoint still alive */
+               if (!real_mount(path->mnt)->mnt_ns)
+                       goto unlock;
+       }
 
        /* Refuse the same filesystem on the same mount point */
        err = -EBUSY;
diff --git a/include/acpi/acbuffer.h b/include/acpi/acbuffer.h
new file mode 100644 (file)
index 0000000..a1e45cd
--- /dev/null
@@ -0,0 +1,235 @@
+/******************************************************************************
+ *
+ * Name: acbuffer.h - Support for buffers returned by ACPI predefined names
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef __ACBUFFER_H__
+#define __ACBUFFER_H__
+
+/*
+ * Contains buffer structures for these predefined names:
+ * _FDE, _GRT, _GTM, _PLD, _SRT
+ */
+
+/*
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
+ */
+
+/* _FDE return value */
+
+struct acpi_fde_info {
+       u32 floppy0;
+       u32 floppy1;
+       u32 floppy2;
+       u32 floppy3;
+       u32 tape;
+};
+
+/*
+ * _GRT return value
+ * _SRT input value
+ */
+struct acpi_grt_info {
+       u16 year;
+       u8 month;
+       u8 day;
+       u8 hour;
+       u8 minute;
+       u8 second;
+       u8 valid;
+       u16 milliseconds;
+       u16 timezone;
+       u8 daylight;
+       u8 reserved[3];
+};
+
+/* _GTM return value */
+
+struct acpi_gtm_info {
+       u32 pio_speed0;
+       u32 dma_speed0;
+       u32 pio_speed1;
+       u32 dma_speed1;
+       u32 flags;
+};
+
+/*
+ * Formatted _PLD return value. The minimum size is a package containing
+ * one buffer.
+ * Revision 1: Buffer is 16 bytes (128 bits)
+ * Revision 2: Buffer is 20 bytes (160 bits)
+ *
+ * Note: This structure is returned from the acpi_decode_pld_buffer
+ * interface.
+ */
+struct acpi_pld_info {
+       u8 revision;
+       u8 ignore_color;
+       u32 color;
+       u16 width;
+       u16 height;
+       u8 user_visible;
+       u8 dock;
+       u8 lid;
+       u8 panel;
+       u8 vertical_position;
+       u8 horizontal_position;
+       u8 shape;
+       u8 group_orientation;
+       u8 group_token;
+       u8 group_position;
+       u8 bay;
+       u8 ejectable;
+       u8 ospm_eject_required;
+       u8 cabinet_number;
+       u8 card_cage_number;
+       u8 reference;
+       u8 rotation;
+       u8 order;
+       u8 reserved;
+       u16 vertical_offset;
+       u16 horizontal_offset;
+};
+
+/*
+ * Macros to:
+ *     1) Convert a _PLD buffer to internal struct acpi_pld_info format - ACPI_PLD_GET*
+ *        (Used by acpi_decode_pld_buffer)
+ *     2) Construct a _PLD buffer - ACPI_PLD_SET*
+ *        (Intended for BIOS use only)
+ */
+#define ACPI_PLD_REV1_BUFFER_SIZE               16     /* For Revision 1 of the buffer (From ACPI spec) */
+#define ACPI_PLD_BUFFER_SIZE                    20     /* For Revision 2 of the buffer (From ACPI spec) */
+
+/* First 32-bit dword, bits 0:32 */
+
+#define ACPI_PLD_GET_REVISION(dword)            ACPI_GET_BITS (dword, 0, ACPI_7BIT_MASK)
+#define ACPI_PLD_SET_REVISION(dword,value)      ACPI_SET_BITS (dword, 0, ACPI_7BIT_MASK, value)        /* Offset 0, Len 7 */
+
+#define ACPI_PLD_GET_IGNORE_COLOR(dword)        ACPI_GET_BITS (dword, 7, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_IGNORE_COLOR(dword,value)  ACPI_SET_BITS (dword, 7, ACPI_1BIT_MASK, value)        /* Offset 7, Len 1 */
+
+#define ACPI_PLD_GET_COLOR(dword)               ACPI_GET_BITS (dword, 8, ACPI_24BIT_MASK)
+#define ACPI_PLD_SET_COLOR(dword,value)         ACPI_SET_BITS (dword, 8, ACPI_24BIT_MASK, value)       /* Offset 8, Len 24 */
+
+/* Second 32-bit dword, bits 33:63 */
+
+#define ACPI_PLD_GET_WIDTH(dword)               ACPI_GET_BITS (dword, 0, ACPI_16BIT_MASK)
+#define ACPI_PLD_SET_WIDTH(dword,value)         ACPI_SET_BITS (dword, 0, ACPI_16BIT_MASK, value)       /* Offset 32+0=32, Len 16 */
+
+#define ACPI_PLD_GET_HEIGHT(dword)              ACPI_GET_BITS (dword, 16, ACPI_16BIT_MASK)
+#define ACPI_PLD_SET_HEIGHT(dword,value)        ACPI_SET_BITS (dword, 16, ACPI_16BIT_MASK, value)      /* Offset 32+16=48, Len 16 */
+
+/* Third 32-bit dword, bits 64:95 */
+
+#define ACPI_PLD_GET_USER_VISIBLE(dword)        ACPI_GET_BITS (dword, 0, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_USER_VISIBLE(dword,value)  ACPI_SET_BITS (dword, 0, ACPI_1BIT_MASK, value)        /* Offset 64+0=64, Len 1 */
+
+#define ACPI_PLD_GET_DOCK(dword)                ACPI_GET_BITS (dword, 1, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_DOCK(dword,value)          ACPI_SET_BITS (dword, 1, ACPI_1BIT_MASK, value)        /* Offset 64+1=65, Len 1 */
+
+#define ACPI_PLD_GET_LID(dword)                 ACPI_GET_BITS (dword, 2, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_LID(dword,value)           ACPI_SET_BITS (dword, 2, ACPI_1BIT_MASK, value)        /* Offset 64+2=66, Len 1 */
+
+#define ACPI_PLD_GET_PANEL(dword)               ACPI_GET_BITS (dword, 3, ACPI_3BIT_MASK)
+#define ACPI_PLD_SET_PANEL(dword,value)         ACPI_SET_BITS (dword, 3, ACPI_3BIT_MASK, value)        /* Offset 64+3=67, Len 3 */
+
+#define ACPI_PLD_GET_VERTICAL(dword)            ACPI_GET_BITS (dword, 6, ACPI_2BIT_MASK)
+#define ACPI_PLD_SET_VERTICAL(dword,value)      ACPI_SET_BITS (dword, 6, ACPI_2BIT_MASK, value)        /* Offset 64+6=70, Len 2 */
+
+#define ACPI_PLD_GET_HORIZONTAL(dword)          ACPI_GET_BITS (dword, 8, ACPI_2BIT_MASK)
+#define ACPI_PLD_SET_HORIZONTAL(dword,value)    ACPI_SET_BITS (dword, 8, ACPI_2BIT_MASK, value)        /* Offset 64+8=72, Len 2 */
+
+#define ACPI_PLD_GET_SHAPE(dword)               ACPI_GET_BITS (dword, 10, ACPI_4BIT_MASK)
+#define ACPI_PLD_SET_SHAPE(dword,value)         ACPI_SET_BITS (dword, 10, ACPI_4BIT_MASK, value)       /* Offset 64+10=74, Len 4 */
+
+#define ACPI_PLD_GET_ORIENTATION(dword)         ACPI_GET_BITS (dword, 14, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_ORIENTATION(dword,value)   ACPI_SET_BITS (dword, 14, ACPI_1BIT_MASK, value)       /* Offset 64+14=78, Len 1 */
+
+#define ACPI_PLD_GET_TOKEN(dword)               ACPI_GET_BITS (dword, 15, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_TOKEN(dword,value)         ACPI_SET_BITS (dword, 15, ACPI_8BIT_MASK, value)       /* Offset 64+15=79, Len 8 */
+
+#define ACPI_PLD_GET_POSITION(dword)            ACPI_GET_BITS (dword, 23, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_POSITION(dword,value)      ACPI_SET_BITS (dword, 23, ACPI_8BIT_MASK, value)       /* Offset 64+23=87, Len 8 */
+
+#define ACPI_PLD_GET_BAY(dword)                 ACPI_GET_BITS (dword, 31, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_BAY(dword,value)           ACPI_SET_BITS (dword, 31, ACPI_1BIT_MASK, value)       /* Offset 64+31=95, Len 1 */
+
+/* Fourth 32-bit dword, bits 96:127 */
+
+#define ACPI_PLD_GET_EJECTABLE(dword)           ACPI_GET_BITS (dword, 0, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_EJECTABLE(dword,value)     ACPI_SET_BITS (dword, 0, ACPI_1BIT_MASK, value)        /* Offset 96+0=96, Len 1 */
+
+#define ACPI_PLD_GET_OSPM_EJECT(dword)          ACPI_GET_BITS (dword, 1, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_OSPM_EJECT(dword,value)    ACPI_SET_BITS (dword, 1, ACPI_1BIT_MASK, value)        /* Offset 96+1=97, Len 1 */
+
+#define ACPI_PLD_GET_CABINET(dword)             ACPI_GET_BITS (dword, 2, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_CABINET(dword,value)       ACPI_SET_BITS (dword, 2, ACPI_8BIT_MASK, value)        /* Offset 96+2=98, Len 8 */
+
+#define ACPI_PLD_GET_CARD_CAGE(dword)           ACPI_GET_BITS (dword, 10, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_CARD_CAGE(dword,value)     ACPI_SET_BITS (dword, 10, ACPI_8BIT_MASK, value)       /* Offset 96+10=106, Len 8 */
+
+#define ACPI_PLD_GET_REFERENCE(dword)           ACPI_GET_BITS (dword, 18, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_REFERENCE(dword,value)     ACPI_SET_BITS (dword, 18, ACPI_1BIT_MASK, value)       /* Offset 96+18=114, Len 1 */
+
+#define ACPI_PLD_GET_ROTATION(dword)            ACPI_GET_BITS (dword, 19, ACPI_4BIT_MASK)
+#define ACPI_PLD_SET_ROTATION(dword,value)      ACPI_SET_BITS (dword, 19, ACPI_4BIT_MASK, value)       /* Offset 96+19=115, Len 4 */
+
+#define ACPI_PLD_GET_ORDER(dword)               ACPI_GET_BITS (dword, 23, ACPI_5BIT_MASK)
+#define ACPI_PLD_SET_ORDER(dword,value)         ACPI_SET_BITS (dword, 23, ACPI_5BIT_MASK, value)       /* Offset 96+23=119, Len 5 */
+
+/* Fifth 32-bit dword, bits 128:159 (Revision 2 of _PLD only) */
+
+#define ACPI_PLD_GET_VERT_OFFSET(dword)         ACPI_GET_BITS (dword, 0, ACPI_16BIT_MASK)
+#define ACPI_PLD_SET_VERT_OFFSET(dword,value)   ACPI_SET_BITS (dword, 0, ACPI_16BIT_MASK, value)       /* Offset 128+0=128, Len 16 */
+
+#define ACPI_PLD_GET_HORIZ_OFFSET(dword)        ACPI_GET_BITS (dword, 16, ACPI_16BIT_MASK)
+#define ACPI_PLD_SET_HORIZ_OFFSET(dword,value)  ACPI_SET_BITS (dword, 16, ACPI_16BIT_MASK, value)      /* Offset 128+16=144, Len 16 */
+
+#endif                         /* ACBUFFER_H */
index d988ac54f41ed385fe47e60d1dc08de45ae603a6..745dd24e3cb51cdacae4f7acccf7764c6c02e261 100644 (file)
 #define METHOD_NAME__PRW        "_PRW"
 #define METHOD_NAME__SRS        "_SRS"
 #define METHOD_NAME__CBA        "_CBA"
+#define METHOD_NAME__PLD        "_PLD"
 
 /* Method names - these methods must appear at the namespace root */
 
-#define METHOD_PATHNAME__BFS    "\\_BFS"
-#define METHOD_PATHNAME__GTS    "\\_GTS"
 #define METHOD_PATHNAME__PTS    "\\_PTS"
 #define METHOD_PATHNAME__SST    "\\_SI._SST"
 #define METHOD_PATHNAME__WAK    "\\_WAK"
index 3eb9de3188240a7b4da6cdfbeafd79ad999bff8f..0daa0fbd865437ab12a756535e8c2432c363bf35 100644 (file)
@@ -54,37 +54,8 @@ acpi_status
 acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event,
                        u32 status_code, struct acpi_buffer *status_buf);
 
-struct acpi_pld {
-       unsigned int revision:7; /* 0 */
-       unsigned int ignore_colour:1; /* 7 */
-       unsigned int colour:24; /* 8 */
-       unsigned int width:16; /* 32 */
-       unsigned int height:16; /* 48 */
-       unsigned int user_visible:1; /* 64 */
-       unsigned int dock:1; /* 65 */
-       unsigned int lid:1; /* 66 */
-       unsigned int panel:3; /* 67 */
-       unsigned int vertical_pos:2; /* 70 */
-       unsigned int horizontal_pos:2; /* 72 */
-       unsigned int shape:4; /* 74 */
-       unsigned int group_orientation:1; /* 78 */
-       unsigned int group_token:8; /* 79 */
-       unsigned int group_position:8; /* 87 */
-       unsigned int bay:1; /* 95 */
-       unsigned int ejectable:1; /* 96 */
-       unsigned int ospm_eject_required:1; /* 97 */
-       unsigned int cabinet_number:8; /* 98 */
-       unsigned int card_cage_number:8; /* 106 */
-       unsigned int reference:1; /* 114 */
-       unsigned int rotation:4; /* 115 */
-       unsigned int order:5; /* 119 */
-       unsigned int reserved:4; /* 124 */
-       unsigned int vertical_offset:16; /* 128 */
-       unsigned int horizontal_offset:16; /* 144 */
-} __attribute__((__packed__));
-
 acpi_status
-acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld *pld);
+acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld);
 #ifdef CONFIG_ACPI
 
 #include <linux/proc_fs.h>
@@ -283,8 +254,16 @@ struct acpi_device_wakeup {
        int prepare_count;
 };
 
-/* Device */
+struct acpi_device_physical_node {
+       u8 node_id;
+       struct list_head node;
+       struct device *dev;
+};
+
+/* set maximum of physical nodes to 32 for expansibility */
+#define ACPI_MAX_PHYSICAL_NODE 32
 
+/* Device */
 struct acpi_device {
        int device_type;
        acpi_handle handle;             /* no handle for fixed hardware */
@@ -305,6 +284,10 @@ struct acpi_device {
        struct device dev;
        struct acpi_bus_ops bus_ops;    /* workaround for different code path for hotplug */
        enum acpi_bus_removal_type removal_type;        /* indicate for different removal type */
+       u8 physical_node_count;
+       struct list_head physical_node_list;
+       struct mutex physical_node_lock;
+       DECLARE_BITMAP(physical_node_id_bitmap, ACPI_MAX_PHYSICAL_NODE);
 };
 
 static inline void *acpi_driver_data(struct acpi_device *d)
@@ -382,6 +365,19 @@ int acpi_match_device_ids(struct acpi_device *device,
 int acpi_create_dir(struct acpi_device *);
 void acpi_remove_dir(struct acpi_device *);
 
+
+/**
+ * module_acpi_driver(acpi_driver) - Helper macro for registering an ACPI driver
+ * @__acpi_driver: acpi_driver struct
+ *
+ * Helper macro for ACPI drivers which do not do anything special in module
+ * init/exit. This eliminates a lot of boilerplate. Each module may only
+ * use this macro once, and calling it replaces module_init() and module_exit()
+ */
+#define module_acpi_driver(__acpi_driver) \
+       module_driver(__acpi_driver, acpi_bus_register_driver, \
+                     acpi_bus_unregister_driver)
+
 /*
  * Bind physical devices with ACPI devices
  */
@@ -395,7 +391,6 @@ struct acpi_bus_type {
 };
 int register_acpi_bus_type(struct acpi_bus_type *);
 int unregister_acpi_bus_type(struct acpi_bus_type *);
-struct device *acpi_get_physical_device(acpi_handle);
 
 struct acpi_pci_root {
        struct list_head node;
index 26a92fc28a590ce68a198b326632835f46cda1d9..267bfc4b26a9b78f4c0f83eb92b0140c656bce9a 100644 (file)
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20120711
+#define ACPI_CA_VERSION                 0x20120913
 
 #include "acconfig.h"
 #include "actypes.h"
 #include "actbl.h"
+#include "acbuffer.h"
 
 extern u8 acpi_gbl_permanent_mmap;
 
@@ -144,6 +145,10 @@ acpi_check_address_range(acpi_adr_space_type space_id,
                         acpi_physical_address address,
                         acpi_size length, u8 warn);
 
+acpi_status
+acpi_decode_pld_buffer(u8 *in_buffer,
+                      acpi_size length, struct acpi_pld_info **return_buffer);
+
 /*
  * ACPI Memory management
  */
index 59a73e1b2845fbde763818159cc6b9791c34586d..4f94b1d812d5a7af89abbcda02ae4adf9924e42f 100644 (file)
 #pragma pack(1)
 
 /*
- * Note about bitfields: The u8 type is used for bitfields in ACPI tables.
- * This is the only type that is even remotely portable. Anything else is not
- * portable, so do not use any other bitfield types.
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
  */
 
 /*******************************************************************************
 struct acpi_table_header {
        char signature[ACPI_NAME_SIZE]; /* ASCII table signature */
        u32 length;             /* Length of table in bytes, including this header */
-       u8 revision;            /* ACPI Specification minor version # */
+       u8 revision;            /* ACPI Specification minor version number */
        u8 checksum;            /* To make sum of entire table == 0 */
        char oem_id[ACPI_OEM_ID_SIZE];  /* ASCII OEM identification */
        char oem_table_id[ACPI_OEM_TABLE_ID_SIZE];      /* ASCII OEM table identification */
@@ -108,7 +114,7 @@ struct acpi_table_header {
  * GAS - Generic Address Structure (ACPI 2.0+)
  *
  * Note: Since this structure is used in the ACPI tables, it is byte aligned.
- * If misaliged access is not supported by the hardware, accesses to the
+ * If misaligned access is not supported by the hardware, accesses to the
  * 64-bit Address field must be performed with care.
  *
  ******************************************************************************/
@@ -210,18 +216,18 @@ struct acpi_table_fadt {
        u8 preferred_profile;   /* Conveys preferred power management profile to OSPM. */
        u16 sci_interrupt;      /* System vector of SCI interrupt */
        u32 smi_command;        /* 32-bit Port address of SMI command port */
-       u8 acpi_enable;         /* Value to write to smi_cmd to enable ACPI */
-       u8 acpi_disable;        /* Value to write to smi_cmd to disable ACPI */
-       u8 s4_bios_request;     /* Value to write to SMI CMD to enter S4BIOS state */
+       u8 acpi_enable;         /* Value to write to SMI_CMD to enable ACPI */
+       u8 acpi_disable;        /* Value to write to SMI_CMD to disable ACPI */
+       u8 s4_bios_request;     /* Value to write to SMI_CMD to enter S4BIOS state */
        u8 pstate_control;      /* Processor performance state control */
-       u32 pm1a_event_block;   /* 32-bit Port address of Power Mgt 1a Event Reg Blk */
-       u32 pm1b_event_block;   /* 32-bit Port address of Power Mgt 1b Event Reg Blk */
-       u32 pm1a_control_block; /* 32-bit Port address of Power Mgt 1a Control Reg Blk */
-       u32 pm1b_control_block; /* 32-bit Port address of Power Mgt 1b Control Reg Blk */
-       u32 pm2_control_block;  /* 32-bit Port address of Power Mgt 2 Control Reg Blk */
-       u32 pm_timer_block;     /* 32-bit Port address of Power Mgt Timer Ctrl Reg Blk */
-       u32 gpe0_block;         /* 32-bit Port address of General Purpose Event 0 Reg Blk */
-       u32 gpe1_block;         /* 32-bit Port address of General Purpose Event 1 Reg Blk */
+       u32 pm1a_event_block;   /* 32-bit port address of Power Mgt 1a Event Reg Blk */
+       u32 pm1b_event_block;   /* 32-bit port address of Power Mgt 1b Event Reg Blk */
+       u32 pm1a_control_block; /* 32-bit port address of Power Mgt 1a Control Reg Blk */
+       u32 pm1b_control_block; /* 32-bit port address of Power Mgt 1b Control Reg Blk */
+       u32 pm2_control_block;  /* 32-bit port address of Power Mgt 2 Control Reg Blk */
+       u32 pm_timer_block;     /* 32-bit port address of Power Mgt Timer Ctrl Reg Blk */
+       u32 gpe0_block;         /* 32-bit port address of General Purpose Event 0 Reg Blk */
+       u32 gpe1_block;         /* 32-bit port address of General Purpose Event 1 Reg Blk */
        u8 pm1_event_length;    /* Byte Length of ports at pm1x_event_block */
        u8 pm1_control_length;  /* Byte Length of ports at pm1x_control_block */
        u8 pm2_control_length;  /* Byte Length of ports at pm2_control_block */
@@ -229,12 +235,12 @@ struct acpi_table_fadt {
        u8 gpe0_block_length;   /* Byte Length of ports at gpe0_block */
        u8 gpe1_block_length;   /* Byte Length of ports at gpe1_block */
        u8 gpe1_base;           /* Offset in GPE number space where GPE1 events start */
-       u8 cst_control;         /* Support for the _CST object and C States change notification */
+       u8 cst_control;         /* Support for the _CST object and C-States change notification */
        u16 c2_latency;         /* Worst case HW latency to enter/exit C2 state */
        u16 c3_latency;         /* Worst case HW latency to enter/exit C3 state */
-       u16 flush_size;         /* Processor's memory cache line width, in bytes */
+       u16 flush_size;         /* Processor memory cache line width, in bytes */
        u16 flush_stride;       /* Number of flush strides that need to be read */
-       u8 duty_offset;         /* Processor duty cycle index in processor's P_CNT reg */
+       u8 duty_offset;         /* Processor duty cycle index in processor P_CNT reg */
        u8 duty_width;          /* Processor duty cycle value bit width in P_CNT register */
        u8 day_alarm;           /* Index to day-of-month alarm in RTC CMOS RAM */
        u8 month_alarm;         /* Index to month-of-year alarm in RTC CMOS RAM */
@@ -255,11 +261,11 @@ struct acpi_table_fadt {
        struct acpi_generic_address xpm_timer_block;    /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */
        struct acpi_generic_address xgpe0_block;        /* 64-bit Extended General Purpose Event 0 Reg Blk address */
        struct acpi_generic_address xgpe1_block;        /* 64-bit Extended General Purpose Event 1 Reg Blk address */
-       struct acpi_generic_address sleep_control;      /* 64-bit Sleep Control register */
-       struct acpi_generic_address sleep_status;       /* 64-bit Sleep Status register */
+       struct acpi_generic_address sleep_control;      /* 64-bit Sleep Control register (ACPI 5.0) */
+       struct acpi_generic_address sleep_status;       /* 64-bit Sleep Status register (ACPI 5.0) */
 };
 
-/* Masks for FADT Boot Architecture Flags (boot_flags) */
+/* Masks for FADT Boot Architecture Flags (boot_flags) [Vx]=Introduced in this FADT revision */
 
 #define ACPI_FADT_LEGACY_DEVICES    (1)        /* 00: [V2] System has LPC or ISA bus devices */
 #define ACPI_FADT_8042              (1<<1)     /* 01: [V3] System has an 8042 controller on port 60/64 */
@@ -272,13 +278,13 @@ struct acpi_table_fadt {
 
 /* Masks for FADT flags */
 
-#define ACPI_FADT_WBINVD            (1)        /* 00: [V1] The wbinvd instruction works properly */
-#define ACPI_FADT_WBINVD_FLUSH      (1<<1)     /* 01: [V1] wbinvd flushes but does not invalidate caches */
+#define ACPI_FADT_WBINVD            (1)        /* 00: [V1] The WBINVD instruction works properly */
+#define ACPI_FADT_WBINVD_FLUSH      (1<<1)     /* 01: [V1] WBINVD flushes but does not invalidate caches */
 #define ACPI_FADT_C1_SUPPORTED      (1<<2)     /* 02: [V1] All processors support C1 state */
 #define ACPI_FADT_C2_MP_SUPPORTED   (1<<3)     /* 03: [V1] C2 state works on MP system */
 #define ACPI_FADT_POWER_BUTTON      (1<<4)     /* 04: [V1] Power button is handled as a control method device */
 #define ACPI_FADT_SLEEP_BUTTON      (1<<5)     /* 05: [V1] Sleep button is handled as a control method device */
-#define ACPI_FADT_FIXED_RTC         (1<<6)     /* 06: [V1] RTC wakeup status not in fixed register space */
+#define ACPI_FADT_FIXED_RTC         (1<<6)     /* 06: [V1] RTC wakeup status is not in fixed register space */
 #define ACPI_FADT_S4_RTC_WAKE       (1<<7)     /* 07: [V1] RTC alarm can wake system from S4 */
 #define ACPI_FADT_32BIT_TIMER       (1<<8)     /* 08: [V1] ACPI timer width is 32-bit (0=24-bit) */
 #define ACPI_FADT_DOCKING_SUPPORTED (1<<9)     /* 09: [V1] Docking supported */
@@ -297,7 +303,7 @@ struct acpi_table_fadt {
 
 /* Values for preferred_profile (Preferred Power Management Profiles) */
 
-enum acpi_prefered_pm_profiles {
+enum acpi_preferred_pm_profiles {
        PM_UNSPECIFIED = 0,
        PM_DESKTOP = 1,
        PM_MOBILE = 2,
@@ -335,7 +341,7 @@ union acpi_name_union {
 struct acpi_table_desc {
        acpi_physical_address address;
        struct acpi_table_header *pointer;
-       u32 length;             /* Length fixed at 32 bits */
+       u32 length;             /* Length fixed at 32 bits (fixed in table header) */
        union acpi_name_union signature;
        acpi_owner_id owner_id;
        u8 flags;
index 300d14e7c5d5e76ae24b3e4d77d279769f5a48aa..280fc45b59dde399ca5c646c9dae553b3aa16591 100644 (file)
 #pragma pack(1)
 
 /*
- * Note about bitfields: The u8 type is used for bitfields in ACPI tables.
- * This is the only type that is even remotely portable. Anything else is not
- * portable, so do not use any other bitfield types.
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
  */
 
 /*******************************************************************************
@@ -489,7 +495,9 @@ enum acpi_hest_notify_types {
        ACPI_HEST_NOTIFY_LOCAL = 2,
        ACPI_HEST_NOTIFY_SCI = 3,
        ACPI_HEST_NOTIFY_NMI = 4,
-       ACPI_HEST_NOTIFY_RESERVED = 5   /* 5 and greater are reserved */
+       ACPI_HEST_NOTIFY_CMCI = 5,      /* ACPI 5.0 */
+       ACPI_HEST_NOTIFY_MCE = 6,       /* ACPI 5.0 */
+       ACPI_HEST_NOTIFY_RESERVED = 7   /* 7 and greater are reserved */
 };
 
 /* Values for config_write_enable bitfield above */
index d9ceb3d316299275fdb2100c2843368be7541317..1b2b356486d1637651607ae01a76e0917e7d7539 100644 (file)
@@ -63,6 +63,8 @@
  */
 #define ACPI_SIG_ASF            "ASF!" /* Alert Standard Format table */
 #define ACPI_SIG_BOOT           "BOOT" /* Simple Boot Flag Table */
+#define ACPI_SIG_CSRT           "CSRT" /* Core System Resource Table */
+#define ACPI_SIG_DBG2           "DBG2" /* Debug Port table type 2 */
 #define ACPI_SIG_DBGP           "DBGP" /* Debug Port table */
 #define ACPI_SIG_DMAR           "DMAR" /* DMA Remapping table */
 #define ACPI_SIG_HPET           "HPET" /* High Precision Event Timer table */
 #pragma pack(1)
 
 /*
- * Note about bitfields: The u8 type is used for bitfields in ACPI tables.
- * This is the only type that is even remotely portable. Anything else is not
- * portable, so do not use any other bitfield types.
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
  */
 
 /*******************************************************************************
@@ -230,6 +238,115 @@ struct acpi_table_boot {
        u8 reserved[3];
 };
 
+/*******************************************************************************
+ *
+ * CSRT - Core System Resource Table
+ *        Version 0
+ *
+ * Conforms to the "Core System Resource Table (CSRT)", November 14, 2011
+ *
+ ******************************************************************************/
+
+struct acpi_table_csrt {
+       struct acpi_table_header header;        /* Common ACPI table header */
+};
+
+/* Resource Group subtable */
+
+struct acpi_csrt_group {
+       u32 length;
+       u32 vendor_id;
+       u32 subvendor_id;
+       u16 device_id;
+       u16 subdevice_id;
+       u16 revision;
+       u16 reserved;
+       u32 info_length;
+
+       /* Shared data (length = info_length) immediately follows */
+};
+
+/* Resource Descriptor subtable */
+
+struct acpi_csrt_descriptor {
+       u32 length;
+       u16 type;
+       u16 subtype;
+       u32 uid;
+
+       /* Resource-specific information immediately follows */
+};
+
+/* Resource Types */
+
+#define ACPI_CSRT_TYPE_INTERRUPT    0x0001
+#define ACPI_CSRT_TYPE_TIMER        0x0002
+#define ACPI_CSRT_TYPE_DMA          0x0003
+
+/* Resource Subtypes */
+
+#define ACPI_CSRT_XRUPT_LINE        0x0000
+#define ACPI_CSRT_XRUPT_CONTROLLER  0x0001
+#define ACPI_CSRT_TIMER             0x0000
+#define ACPI_CSRT_DMA_CHANNEL       0x0000
+#define ACPI_CSRT_DMA_CONTROLLER    0x0001
+
+/*******************************************************************************
+ *
+ * DBG2 - Debug Port Table 2
+ *        Version 0 (Both main table and subtables)
+ *
+ * Conforms to "Microsoft Debug Port Table 2 (DBG2)", May 22 2012.
+ *
+ ******************************************************************************/
+
+struct acpi_table_dbg2 {
+       struct acpi_table_header header;        /* Common ACPI table header */
+       u32 info_offset;
+       u32 info_count;
+};
+
+/* Debug Device Information Subtable */
+
+struct acpi_dbg2_device {
+       u8 revision;
+       u16 length;
+       u8 register_count;      /* Number of base_address registers */
+       u16 namepath_length;
+       u16 namepath_offset;
+       u16 oem_data_length;
+       u16 oem_data_offset;
+       u16 port_type;
+       u16 port_subtype;
+       u16 reserved;
+       u16 base_address_offset;
+       u16 address_size_offset;
+       /*
+        * Data that follows:
+        *    base_address (required) - Each in 12-byte Generic Address Structure format.
+        *    address_size (required) - Array of u32 sizes corresponding to each base_address register.
+        *    Namepath    (required) - Null terminated string. Single dot if not supported.
+        *    oem_data    (optional) - Length is oem_data_length.
+        */
+};
+
+/* Types for port_type field above */
+
+#define ACPI_DBG2_SERIAL_PORT       0x8000
+#define ACPI_DBG2_1394_PORT         0x8001
+#define ACPI_DBG2_USB_PORT          0x8002
+#define ACPI_DBG2_NET_PORT          0x8003
+
+/* Subtypes for port_subtype field above */
+
+#define ACPI_DBG2_16550_COMPATIBLE  0x0000
+#define ACPI_DBG2_16550_SUBSET      0x0001
+
+#define ACPI_DBG2_1394_STANDARD     0x0000
+
+#define ACPI_DBG2_USB_XHCI          0x0000
+#define ACPI_DBG2_USB_EHCI          0x0001
+
 /*******************************************************************************
  *
  * DBGP - Debug Port table
index f65a0ed869ebc327bceee545bbe7d905726b05b4..8c61b5fe42a48417fb7b9b4080fac0ff743978a4 100644 (file)
@@ -75,7 +75,6 @@
 /* Reserved table signatures */
 
 #define ACPI_SIG_CSRT           "CSRT" /* Core System Resources Table */
-#define ACPI_SIG_DBG2           "DBG2" /* Debug Port table 2 */
 #define ACPI_SIG_MATR           "MATR" /* Memory Address Translation Table */
 #define ACPI_SIG_MSDM           "MSDM" /* Microsoft Data Management Table */
 #define ACPI_SIG_WPBT           "WPBT" /* Windows Platform Binary Table */
 #pragma pack(1)
 
 /*
- * Note about bitfields: The u8 type is used for bitfields in ACPI tables.
- * This is the only type that is even remotely portable. Anything else is not
- * portable, so do not use any other bitfield types.
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
  */
 
 /*******************************************************************************
index 3d00bd5bd7e30bdfb11689512f7e502d22d4ab71..a85bae968262162fd7eb32b8a414a292a1727ff9 100644 (file)
@@ -518,13 +518,6 @@ typedef u64 acpi_integer;
 #define ACPI_SLEEP_TYPE_MAX             0x7
 #define ACPI_SLEEP_TYPE_INVALID         0xFF
 
-/*
- * Sleep/Wake flags
- */
-#define ACPI_NO_OPTIONAL_METHODS        0x00   /* Do not execute any optional methods */
-#define ACPI_EXECUTE_GTS                0x01   /* For enter sleep interface */
-#define ACPI_EXECUTE_BFS                0x02   /* For leave sleep prep interface */
-
 /*
  * Standard notify values
  */
index 991ef01cd77eac4fa6b9469dc2ad4c53640f3950..3748ec92dcbcdb988bad96406e7d53b664118152 100644 (file)
@@ -691,9 +691,11 @@ __SC_COMP(__NR_process_vm_readv, sys_process_vm_readv, \
 #define __NR_process_vm_writev 271
 __SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \
           compat_sys_process_vm_writev)
+#define __NR_kcmp 272
+__SYSCALL(__NR_kcmp, sys_kcmp)
 
 #undef __NR_syscalls
-#define __NR_syscalls 272
+#define __NR_syscalls 273
 
 /*
  * All syscalls below here should go away really,
index 7e83370e6fd2b134691e7fa348529e70d0a1ae56..f3b99e1c1042ac4073b681ee30ff7ea1f0f9a3a3 100644 (file)
@@ -256,72 +256,78 @@ static inline void iommu_set_fault_handler(struct iommu_domain *domain,
 {
 }
 
-int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group)
+static inline int iommu_attach_group(struct iommu_domain *domain,
+                                    struct iommu_group *group)
 {
        return -ENODEV;
 }
 
-void iommu_detach_group(struct iommu_domain *domain, struct iommu_group *group)
+static inline void iommu_detach_group(struct iommu_domain *domain,
+                                     struct iommu_group *group)
 {
 }
 
-struct iommu_group *iommu_group_alloc(void)
+static inline struct iommu_group *iommu_group_alloc(void)
 {
        return ERR_PTR(-ENODEV);
 }
 
-void *iommu_group_get_iommudata(struct iommu_group *group)
+static inline void *iommu_group_get_iommudata(struct iommu_group *group)
 {
        return NULL;
 }
 
-void iommu_group_set_iommudata(struct iommu_group *group, void *iommu_data,
-                              void (*release)(void *iommu_data))
+static inline void iommu_group_set_iommudata(struct iommu_group *group,
+                                            void *iommu_data,
+                                            void (*release)(void *iommu_data))
 {
 }
 
-int iommu_group_set_name(struct iommu_group *group, const char *name)
+static inline int iommu_group_set_name(struct iommu_group *group,
+                                      const char *name)
 {
        return -ENODEV;
 }
 
-int iommu_group_add_device(struct iommu_group *group, struct device *dev)
+static inline int iommu_group_add_device(struct iommu_group *group,
+                                        struct device *dev)
 {
        return -ENODEV;
 }
 
-void iommu_group_remove_device(struct device *dev)
+static inline void iommu_group_remove_device(struct device *dev)
 {
 }
 
-int iommu_group_for_each_dev(struct iommu_group *group, void *data,
-                            int (*fn)(struct device *, void *))
+static inline int iommu_group_for_each_dev(struct iommu_group *group,
+                                          void *data,
+                                          int (*fn)(struct device *, void *))
 {
        return -ENODEV;
 }
 
-struct iommu_group *iommu_group_get(struct device *dev)
+static inline struct iommu_group *iommu_group_get(struct device *dev)
 {
        return NULL;
 }
 
-void iommu_group_put(struct iommu_group *group)
+static inline void iommu_group_put(struct iommu_group *group)
 {
 }
 
-int iommu_group_register_notifier(struct iommu_group *group,
-                                 struct notifier_block *nb)
+static inline int iommu_group_register_notifier(struct iommu_group *group,
+                                               struct notifier_block *nb)
 {
        return -ENODEV;
 }
 
-int iommu_group_unregister_notifier(struct iommu_group *group,
-                                   struct notifier_block *nb)
+static inline int iommu_group_unregister_notifier(struct iommu_group *group,
+                                                 struct notifier_block *nb)
 {
        return 0;
 }
 
-int iommu_group_id(struct iommu_group *group)
+static inline int iommu_group_id(struct iommu_group *group)
 {
        return -ENODEV;
 }
index 61f0905bdc480b9078dc31e5d434158f4301df50..de201203bc7c833a09651f75678b833cfac0b880 100644 (file)
@@ -1,3 +1,15 @@
+/*
+ * include/linux/micrel_phy.h
+ *
+ * Micrel PHY IDs
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
 #ifndef _MICREL_PHY_H
 #define _MICREL_PHY_H
 
 
 #define PHY_ID_KSZ9021         0x00221610
 #define PHY_ID_KS8737          0x00221720
-#define PHY_ID_KS8041          0x00221510
-#define PHY_ID_KS8051          0x00221550
+#define PHY_ID_KSZ8021         0x00221555
+#define PHY_ID_KSZ8041         0x00221510
+#define PHY_ID_KSZ8051         0x00221550
 /* both for ks8001 Rev. A/B, and for ks8721 Rev 3. */
-#define PHY_ID_KS8001          0x0022161A
+#define PHY_ID_KSZ8001         0x0022161A
 
 /* struct phy_device dev_flags definitions */
 #define MICREL_PHY_50MHZ_CLK   0x00000001
index 9490a00529f49aa7f50a8e94e7fd7961b2002319..c25cccaa555a420b5cc6fd26d5e83a89937470a6 100644 (file)
@@ -35,8 +35,10 @@ struct nvme_bar {
        __u64                   acq;    /* Admin CQ Base Address */
 };
 
+#define NVME_CAP_MQES(cap)     ((cap) & 0xffff)
 #define NVME_CAP_TIMEOUT(cap)  (((cap) >> 24) & 0xff)
 #define NVME_CAP_STRIDE(cap)   (((cap) >> 32) & 0xf)
+#define NVME_CAP_MPSMIN(cap)   (((cap) >> 48) & 0xf)
 
 enum {
        NVME_CC_ENABLE          = 1 << 0,
index 3dea6a9d568f416ccd1b704eec1d4bff9dea6d90..d143b8e01954ab14ac224d9894bf65e111ee97fb 100644 (file)
@@ -118,6 +118,7 @@ void reset_security_ops(void);
 extern unsigned long mmap_min_addr;
 extern unsigned long dac_mmap_min_addr;
 #else
+#define mmap_min_addr          0UL
 #define dac_mmap_min_addr      0UL
 #endif
 
index c785554f95237897edc7e86f7c3ea6f1811b9bbf..ebf3bac460b01c3638e87d23975426f448d58064 100644 (file)
@@ -62,7 +62,7 @@ void fprop_global_destroy(struct fprop_global *p)
  */
 bool fprop_new_period(struct fprop_global *p, int periods)
 {
-       u64 events;
+       s64 events;
        unsigned long flags;
 
        local_irq_save(flags);
index 57c4b93090151f2acbc1271b7b214fe5bc96478c..141dbb695097c1f0674b8978456eb1d0c98e3e67 100644 (file)
@@ -1811,7 +1811,6 @@ static void __collapse_huge_page_copy(pte_t *pte, struct page *page,
                        src_page = pte_page(pteval);
                        copy_user_highpage(page, src_page, address, vma);
                        VM_BUG_ON(page_mapcount(src_page) != 1);
-                       VM_BUG_ON(page_count(src_page) != 2);
                        release_pte_page(src_page);
                        /*
                         * ptl mostly unnecessary, but preempt has to
index e877af8bdd1e8551335ec810ea1ad2c32bedc64e..469daabd90c7bf28572c3f9066ee2146ed590fd1 100644 (file)
@@ -642,7 +642,8 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
        struct batadv_neigh_node *router = NULL;
        struct batadv_orig_node *orig_node_tmp;
        struct hlist_node *node;
-       uint8_t bcast_own_sum_orig, bcast_own_sum_neigh;
+       int if_num;
+       uint8_t sum_orig, sum_neigh;
        uint8_t *neigh_addr;
 
        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
@@ -727,17 +728,17 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
        if (router && (neigh_node->tq_avg == router->tq_avg)) {
                orig_node_tmp = router->orig_node;
                spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
-               bcast_own_sum_orig =
-                       orig_node_tmp->bcast_own_sum[if_incoming->if_num];
+               if_num = router->if_incoming->if_num;
+               sum_orig = orig_node_tmp->bcast_own_sum[if_num];
                spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
 
                orig_node_tmp = neigh_node->orig_node;
                spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
-               bcast_own_sum_neigh =
-                       orig_node_tmp->bcast_own_sum[if_incoming->if_num];
+               if_num = neigh_node->if_incoming->if_num;
+               sum_neigh = orig_node_tmp->bcast_own_sum[if_num];
                spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
 
-               if (bcast_own_sum_orig >= bcast_own_sum_neigh)
+               if (sum_orig >= sum_neigh)
                        goto update_tt;
        }
 
index 109ea2aae96cde266aef1123bb73a3fa7d219e79..21c53577c8d6a5e65599aa5c01d8d9d93c6fb838 100644 (file)
@@ -100,18 +100,21 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
 {
        struct batadv_priv *bat_priv = netdev_priv(dev);
        struct sockaddr *addr = p;
+       uint8_t old_addr[ETH_ALEN];
 
        if (!is_valid_ether_addr(addr->sa_data))
                return -EADDRNOTAVAIL;
 
+       memcpy(old_addr, dev->dev_addr, ETH_ALEN);
+       memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+
        /* only modify transtable if it has been initialized before */
        if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) {
-               batadv_tt_local_remove(bat_priv, dev->dev_addr,
+               batadv_tt_local_remove(bat_priv, old_addr,
                                       "mac address changed", false);
                batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX);
        }
 
-       memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
        dev->addr_assign_type &= ~NET_ADDR_RANDOM;
        return 0;
 }
index d4de5db18d5a8e48d950a368e7ef93840d269a07..0b997c8f965531d22da050339d17011ab9dd5b3c 100644 (file)
@@ -734,6 +734,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
 
        cancel_work_sync(&hdev->le_scan);
 
+       cancel_delayed_work(&hdev->power_off);
+
        hci_req_cancel(hdev, ENODEV);
        hci_req_lock(hdev);
 
index 4ea1710a478329a5d4219ce686a2ef4450ca30b8..38c00f142203505d3a3c809e8e6162f159ae0196 100644 (file)
@@ -1008,7 +1008,7 @@ static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *c
        if (!conn)
                return;
 
-       if (chan->mode == L2CAP_MODE_ERTM) {
+       if (chan->mode == L2CAP_MODE_ERTM && chan->state == BT_CONNECTED) {
                __clear_retrans_timer(chan);
                __clear_monitor_timer(chan);
                __clear_ack_timer(chan);
index ad6613d17ca6de815be200b9576d6ecf510fef0d..eba022de3c205bb55f2ed9639e4faf21d78ae9a8 100644 (file)
@@ -2875,6 +2875,22 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
                if (scan)
                        hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
 
+               if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
+                       u8 ssp = 1;
+
+                       hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, 1, &ssp);
+               }
+
+               if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
+                       struct hci_cp_write_le_host_supported cp;
+
+                       cp.le = 1;
+                       cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
+
+                       hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED,
+                                    sizeof(cp), &cp);
+               }
+
                update_class(hdev);
                update_name(hdev, hdev->dev_name);
                update_eir(hdev);
index 24c5eea8c45bb1233edfad141baf6a6391e023c6..159aa8bef9e7fe2f89f9b508c39a209aa92d3c0d 100644 (file)
@@ -1073,16 +1073,13 @@ static int write_partial_msg_pages(struct ceph_connection *con)
                        BUG_ON(kaddr == NULL);
                        base = kaddr + con->out_msg_pos.page_pos + bio_offset;
                        crc = crc32c(crc, base, len);
+                       kunmap(page);
                        msg->footer.data_crc = cpu_to_le32(crc);
                        con->out_msg_pos.did_page_crc = true;
                }
                ret = ceph_tcp_sendpage(con->sock, page,
                                      con->out_msg_pos.page_pos + bio_offset,
                                      len, 1);
-
-               if (do_datacrc)
-                       kunmap(page);
-
                if (ret <= 0)
                        goto out;
 
index 30579207612175f0a65b19310368079c54ce4bc9..a6000fbad2949f58a079322f4e328e0c051df896 100644 (file)
@@ -691,7 +691,8 @@ set_rcvbuf:
 
        case SO_KEEPALIVE:
 #ifdef CONFIG_INET
-               if (sk->sk_protocol == IPPROTO_TCP)
+               if (sk->sk_protocol == IPPROTO_TCP &&
+                   sk->sk_type == SOCK_STREAM)
                        tcp_set_keepalive(sk, valbool);
 #endif
                sock_valbool_flag(sk, SOCK_KEEPOPEN, valbool);
index e1e0a4e8fd3469f7534cdc65b7ba3312ad66fa39..c7527f6b9ad9b54f36185975aed21171757c4600 100644 (file)
@@ -510,7 +510,10 @@ relookup:
                                        secure_ipv6_id(daddr->addr.a6));
                p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW;
                p->rate_tokens = 0;
-               p->rate_last = 0;
+               /* 60*HZ is arbitrary, but chosen enough high so that the first
+                * calculation of tokens is at its maximum.
+                */
+               p->rate_last = jiffies - 60*HZ;
                INIT_LIST_HEAD(&p->gc_list);
 
                /* Link the node. */
index ff0f071969ea77dbdb6797584765e32bc958203f..d23c6571ba1c34525114af16f0818cfe6bbf1f14 100644 (file)
@@ -131,18 +131,20 @@ found:
  *     0 - deliver
  *     1 - block
  */
-static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb)
+static int icmp_filter(const struct sock *sk, const struct sk_buff *skb)
 {
-       int type;
+       struct icmphdr _hdr;
+       const struct icmphdr *hdr;
 
-       if (!pskb_may_pull(skb, sizeof(struct icmphdr)))
+       hdr = skb_header_pointer(skb, skb_transport_offset(skb),
+                                sizeof(_hdr), &_hdr);
+       if (!hdr)
                return 1;
 
-       type = icmp_hdr(skb)->type;
-       if (type < 32) {
+       if (hdr->type < 32) {
                __u32 data = raw_sk(sk)->filter.data;
 
-               return ((1 << type) & data) != 0;
+               return ((1U << hdr->type) & data) != 0;
        }
 
        /* Do not block unknown ICMP types */
index 5b087c31d87b54f5a2574903775b81692bcd2616..0f9bdc5ee9f38c70f1c4c265e8ebe43467d6b59a 100644 (file)
@@ -86,28 +86,30 @@ static int mip6_mh_len(int type)
 
 static int mip6_mh_filter(struct sock *sk, struct sk_buff *skb)
 {
-       struct ip6_mh *mh;
+       struct ip6_mh _hdr;
+       const struct ip6_mh *mh;
 
-       if (!pskb_may_pull(skb, (skb_transport_offset(skb)) + 8) ||
-           !pskb_may_pull(skb, (skb_transport_offset(skb) +
-                                ((skb_transport_header(skb)[1] + 1) << 3))))
+       mh = skb_header_pointer(skb, skb_transport_offset(skb),
+                               sizeof(_hdr), &_hdr);
+       if (!mh)
                return -1;
 
-       mh = (struct ip6_mh *)skb_transport_header(skb);
+       if (((mh->ip6mh_hdrlen + 1) << 3) > skb->len)
+               return -1;
 
        if (mh->ip6mh_hdrlen < mip6_mh_len(mh->ip6mh_type)) {
                LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH message too short: %d vs >=%d\n",
                               mh->ip6mh_hdrlen, mip6_mh_len(mh->ip6mh_type));
-               mip6_param_prob(skb, 0, ((&mh->ip6mh_hdrlen) -
-                                        skb_network_header(skb)));
+               mip6_param_prob(skb, 0, offsetof(struct ip6_mh, ip6mh_hdrlen) +
+                               skb_network_header_len(skb));
                return -1;
        }
 
        if (mh->ip6mh_proto != IPPROTO_NONE) {
                LIMIT_NETDEBUG(KERN_DEBUG "mip6: MH invalid payload proto = %d\n",
                               mh->ip6mh_proto);
-               mip6_param_prob(skb, 0, ((&mh->ip6mh_proto) -
-                                        skb_network_header(skb)));
+               mip6_param_prob(skb, 0, offsetof(struct ip6_mh, ip6mh_proto) +
+                               skb_network_header_len(skb));
                return -1;
        }
 
index ef0579d5bca6b3794007145279f8ead1626aafe3..4a5f78b50495060470777aa41edd540bb699662f 100644 (file)
@@ -107,21 +107,20 @@ found:
  *     0 - deliver
  *     1 - block
  */
-static __inline__ int icmpv6_filter(struct sock *sk, struct sk_buff *skb)
+static int icmpv6_filter(const struct sock *sk, const struct sk_buff *skb)
 {
-       struct icmp6hdr *icmph;
-       struct raw6_sock *rp = raw6_sk(sk);
-
-       if (pskb_may_pull(skb, sizeof(struct icmp6hdr))) {
-               __u32 *data = &rp->filter.data[0];
-               int bit_nr;
+       struct icmp6hdr *_hdr;
+       const struct icmp6hdr *hdr;
 
-               icmph = (struct icmp6hdr *) skb->data;
-               bit_nr = icmph->icmp6_type;
+       hdr = skb_header_pointer(skb, skb_transport_offset(skb),
+                                sizeof(_hdr), &_hdr);
+       if (hdr) {
+               const __u32 *data = &raw6_sk(sk)->filter.data[0];
+               unsigned int type = hdr->icmp6_type;
 
-               return (data[bit_nr >> 5] & (1 << (bit_nr & 31))) != 0;
+               return (data[type >> 5] & (1U << (type & 31))) != 0;
        }
-       return 0;
+       return 1;
 }
 
 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
index d71cd9229a47a8fd85efbf3f5430c66a3e3ad5cd..6f936358d664cd3a8946317ca879180a937c8b22 100644 (file)
@@ -80,8 +80,8 @@ static int l2tp_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)
 
        hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
                          &l2tp_nl_family, 0, L2TP_CMD_NOOP);
-       if (IS_ERR(hdr)) {
-               ret = PTR_ERR(hdr);
+       if (!hdr) {
+               ret = -EMSGSIZE;
                goto err_out;
        }
 
@@ -250,8 +250,8 @@ static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 pid, u32 seq, int flags,
 
        hdr = genlmsg_put(skb, pid, seq, &l2tp_nl_family, flags,
                          L2TP_CMD_TUNNEL_GET);
-       if (IS_ERR(hdr))
-               return PTR_ERR(hdr);
+       if (!hdr)
+               return -EMSGSIZE;
 
        if (nla_put_u8(skb, L2TP_ATTR_PROTO_VERSION, tunnel->version) ||
            nla_put_u32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id) ||
@@ -617,8 +617,8 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 pid, u32 seq, int flags
        sk = tunnel->sock;
 
        hdr = genlmsg_put(skb, pid, seq, &l2tp_nl_family, flags, L2TP_CMD_SESSION_GET);
-       if (IS_ERR(hdr))
-               return PTR_ERR(hdr);
+       if (!hdr)
+               return -EMSGSIZE;
 
        if (nla_put_u32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id) ||
            nla_put_u32(skb, L2TP_ATTR_SESSION_ID, session->session_id) ||
index 5c22ce8ab3090b103ac75c7ae54d0489c1bc84e2..a4c1e4528cac7e3e820f1cecfb8ec22e8dcf5966 100644 (file)
@@ -117,11 +117,11 @@ static int limit_mt_check(const struct xt_mtchk_param *par)
 
        /* For SMP, we only want to use one set of state. */
        r->master = priv;
+       /* User avg in seconds * XT_LIMIT_SCALE: convert to jiffies *
+          128. */
+       priv->prev = jiffies;
+       priv->credit = user2credits(r->avg * r->burst); /* Credits full. */
        if (r->cost == 0) {
-               /* User avg in seconds * XT_LIMIT_SCALE: convert to jiffies *
-                  128. */
-               priv->prev = jiffies;
-               priv->credit = user2credits(r->avg * r->burst); /* Credits full. */
                r->credit_cap = priv->credit; /* Credits full. */
                r->cost = user2credits(r->avg);
        }
index 2ded3c7fad063a067151595c774b9bddd14bdc9a..72d170ca340665ea5c893cc1bec2316219abbf7c 100644 (file)
@@ -350,6 +350,9 @@ static void reg_regdb_search(struct work_struct *work)
        struct reg_regdb_search_request *request;
        const struct ieee80211_regdomain *curdom, *regdom;
        int i, r;
+       bool set_reg = false;
+
+       mutex_lock(&cfg80211_mutex);
 
        mutex_lock(&reg_regdb_search_mutex);
        while (!list_empty(&reg_regdb_search_list)) {
@@ -365,9 +368,7 @@ static void reg_regdb_search(struct work_struct *work)
                                r = reg_copy_regd(&regdom, curdom);
                                if (r)
                                        break;
-                               mutex_lock(&cfg80211_mutex);
-                               set_regdom(regdom);
-                               mutex_unlock(&cfg80211_mutex);
+                               set_reg = true;
                                break;
                        }
                }
@@ -375,6 +376,11 @@ static void reg_regdb_search(struct work_struct *work)
                kfree(request);
        }
        mutex_unlock(&reg_regdb_search_mutex);
+
+       if (set_reg)
+               set_regdom(regdom);
+
+       mutex_unlock(&cfg80211_mutex);
 }
 
 static DECLARE_WORK(reg_regdb_work, reg_regdb_search);
index d24810fc6af6caf3a15ea3f5a55b33f4f08a667b..fd8fa9aa7c4edd698430a9cb0647a8d26095a9a2 100755 (executable)
@@ -200,7 +200,7 @@ EOF
 syscall_list() {
     grep '^[0-9]' "$1" | sort -n | (
        while read nr abi name entry ; do
-           echo <<EOF
+           cat <<EOF
 #if !defined(__NR_${name}) && !defined(__IGNORE_${name})
 #warning syscall ${name} not implemented
 #endif
index 3fd5b29dc9335b5bee03b0b28f6cbbdfee2ea297..a3acb7a85f6ab26f62e92489e75e0f6b4822f831 100644 (file)
@@ -702,7 +702,7 @@ static bool wm2000_readable_reg(struct device *dev, unsigned int reg)
 }
 
 static const struct regmap_config wm2000_regmap = {
-       .reg_bits = 8,
+       .reg_bits = 16,
        .val_bits = 8,
 
        .max_register = WM2000_REG_IF_CTL,
index d6e2bb49c59c52f01288925fa52461eea510e78a..060dccb9ec75513def50e6f8be32f60f4f3b05f1 100644 (file)
@@ -197,7 +197,13 @@ static void prepare_outbound_urb(struct snd_usb_endpoint *ep,
                        /* no data provider, so send silence */
                        unsigned int offs = 0;
                        for (i = 0; i < ctx->packets; ++i) {
-                               int counts = ctx->packet_size[i];
+                               int counts;
+
+                               if (ctx->packet_size[i])
+                                       counts = ctx->packet_size[i];
+                               else
+                                       counts = snd_usb_endpoint_next_packet_size(ep);
+
                                urb->iso_frame_desc[i].offset = offs * ep->stride;
                                urb->iso_frame_desc[i].length = counts * ep->stride;
                                offs += counts;
diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile
new file mode 100644 (file)
index 0000000..6b9cf7a
--- /dev/null
@@ -0,0 +1,18 @@
+PROG= acpidump
+SRCS=  acpidump.c
+KERNEL_INCLUDE := ../../../include
+CFLAGS += -Wall -Wstrict-prototypes -Wdeclaration-after-statement -Os -s -D_LINUX -DDEFINE_ALTERNATE_TYPES -I$(KERNEL_INCLUDE) 
+
+all: acpidump
+$(PROG) : $(SRCS)
+       $(CC) $(CFLAGS) $(SRCS) -o $(PROG)
+
+CLEANFILES= $(PROG)
+
+clean : 
+       rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS)) *~
+
+install :
+       install acpidump /usr/bin/acpidump
+       install acpidump.8 /usr/share/man/man8
+
diff --git a/tools/power/acpi/acpidump.8 b/tools/power/acpi/acpidump.8
new file mode 100644 (file)
index 0000000..adfa991
--- /dev/null
@@ -0,0 +1,59 @@
+.TH ACPIDUMP 8
+.SH NAME
+acpidump \- Dump system's ACPI tables to an ASCII file.
+.SH SYNOPSIS
+.ft B
+.B acpidump > acpidump.out
+.SH DESCRIPTION
+\fBacpidump \fP dumps the systems ACPI tables to an ASCII file
+appropriate for attaching to a bug report.
+
+Subsequently, they can be processed by utilities in the ACPICA package.
+.SS Options
+no options worth worrying about.
+.PP
+.SH EXAMPLE
+
+.nf
+# acpidump > acpidump.out
+
+$ acpixtract -a acpidump.out
+        Acpi table [DSDT] -  15974 bytes written to DSDT.dat
+        Acpi table [FACS] -     64 bytes written to FACS.dat
+        Acpi table [FACP] -    116 bytes written to FACP.dat
+        Acpi table [APIC] -    120 bytes written to APIC.dat
+        Acpi table [MCFG] -     60 bytes written to MCFG.dat
+        Acpi table [SSDT] -    444 bytes written to SSDT1.dat
+        Acpi table [SSDT] -    439 bytes written to SSDT2.dat
+        Acpi table [SSDT] -    439 bytes written to SSDT3.dat
+        Acpi table [SSDT] -    439 bytes written to SSDT4.dat
+        Acpi table [SSDT] -    439 bytes written to SSDT5.dat
+        Acpi table [RSDT] -     76 bytes written to RSDT.dat
+        Acpi table [RSDP] -     20 bytes written to RSDP.dat
+
+$ iasl -d *.dat
+...
+.fi
+creates *.dsl, a human readable form which can be edited
+and compiled using iasl.
+
+
+.SH NOTES
+
+.B "acpidump "
+must be run as root.
+
+.SH REFERENCES
+ACPICA: https://acpica.org/
+
+.SH FILES
+.ta
+.nf
+/dev/mem
+/sys/firmware/acpi/tables/dynamic/*
+.fi
+
+.PP
+.SH AUTHOR
+.nf
+Written by Len Brown <len.brown@intel.com>
diff --git a/tools/power/acpi/acpidump.c b/tools/power/acpi/acpidump.c
new file mode 100644 (file)
index 0000000..0777987
--- /dev/null
@@ -0,0 +1,560 @@
+/*
+ * (c) Alexey Starikovskiy, Intel, 2005-2006.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifdef DEFINE_ALTERNATE_TYPES
+/* hack to enable building old application with new headers -lenb */
+#define acpi_fadt_descriptor acpi_table_fadt
+#define acpi_rsdp_descriptor acpi_table_rsdp
+#define DSDT_SIG ACPI_SIG_DSDT
+#define FACS_SIG ACPI_SIG_FACS
+#define FADT_SIG ACPI_SIG_FADT
+#define xfirmware_ctrl Xfacs
+#define firmware_ctrl facs
+
+typedef int                            s32;
+typedef unsigned char                  u8;
+typedef unsigned short                 u16;
+typedef unsigned int                   u32;
+typedef unsigned long long             u64;
+typedef long long                      s64;
+#endif
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include <sys/types.h>
+#include <dirent.h>
+
+#include <acpi/acconfig.h>
+#include <acpi/platform/acenv.h>
+#include <acpi/actypes.h>
+#include <acpi/actbl.h>
+
+static inline u8 checksum(u8 * buffer, u32 length)
+{
+       u8 sum = 0, *i = buffer;
+       buffer += length;
+       for (; i < buffer; sum += *(i++));
+       return sum;
+}
+
+static unsigned long psz, addr, length;
+static int print, connect, skip;
+static u8 select_sig[4];
+
+static unsigned long read_efi_systab( void )
+{
+       char buffer[80];
+       unsigned long addr;
+       FILE *f = fopen("/sys/firmware/efi/systab", "r");
+       if (f) {
+               while (fgets(buffer, 80, f)) {
+                       if (sscanf(buffer, "ACPI20=0x%lx", &addr) == 1)
+                               return addr;
+               }
+               fclose(f);
+       }
+       return 0;
+}
+
+static u8 *acpi_map_memory(unsigned long where, unsigned length)
+{
+       unsigned long offset;
+       u8 *there;
+       int fd = open("/dev/mem", O_RDONLY);
+       if (fd < 0) {
+               fprintf(stderr, "acpi_os_map_memory: cannot open /dev/mem\n");
+               exit(1);
+       }
+       offset = where % psz;
+       there = mmap(NULL, length + offset, PROT_READ, MAP_PRIVATE,
+                        fd, where - offset);
+       close(fd);
+       if (there == MAP_FAILED) return 0;
+       return (there + offset);
+}
+
+static void acpi_unmap_memory(u8 * there, unsigned length)
+{
+       unsigned long offset = (unsigned long)there % psz;
+       munmap(there - offset, length + offset);
+}
+
+static struct acpi_table_header *acpi_map_table(unsigned long where, char *sig)
+{
+       unsigned size;
+       struct acpi_table_header *tbl = (struct acpi_table_header *)
+           acpi_map_memory(where, sizeof(struct acpi_table_header));
+       if (!tbl || (sig && memcmp(sig, tbl->signature, 4))) return 0;
+       size = tbl->length;
+       acpi_unmap_memory((u8 *) tbl, sizeof(struct acpi_table_header));
+       return (struct acpi_table_header *)acpi_map_memory(where, size);
+}
+
+static void acpi_unmap_table(struct acpi_table_header *tbl)
+{
+       acpi_unmap_memory((u8 *)tbl, tbl->length);
+}
+
+static struct acpi_rsdp_descriptor *acpi_scan_for_rsdp(u8 *begin, u32 length)
+{
+       struct acpi_rsdp_descriptor *rsdp;
+       u8 *i, *end = begin + length;
+       /* Search from given start address for the requested length */
+       for (i = begin; i < end; i += ACPI_RSDP_SCAN_STEP) {
+               /* The signature and checksum must both be correct */
+               if (memcmp((char *)i, "RSD PTR ", 8)) continue;
+               rsdp = (struct acpi_rsdp_descriptor *)i;
+               /* Signature matches, check the appropriate checksum */
+               if (!checksum((u8 *) rsdp, (rsdp->revision < 2) ?
+                             ACPI_RSDP_CHECKSUM_LENGTH :
+                             ACPI_RSDP_XCHECKSUM_LENGTH))
+                       /* Checksum valid, we have found a valid RSDP */
+                       return rsdp;
+       }
+       /* Searched entire block, no RSDP was found */
+       return 0;
+}
+
+/*
+ * Output data
+ */
+static void acpi_show_data(int fd, u8 * data, int size)
+{
+       char buffer[256];
+       int len;
+       int i, remain = size;
+       while (remain > 0) {
+               len = snprintf(buffer, 256, "  %04x:", size - remain);
+               for (i = 0; i < 16 && i < remain; i++) {
+                       len +=
+                           snprintf(&buffer[len], 256 - len, " %02x", data[i]);
+               }
+               for (; i < 16; i++) {
+                       len += snprintf(&buffer[len], 256 - len, "   ");
+               }
+               len += snprintf(&buffer[len], 256 - len, "  ");
+               for (i = 0; i < 16 && i < remain; i++) {
+                       buffer[len++] = (isprint(data[i])) ? data[i] : '.';
+               }
+               buffer[len++] = '\n';
+               write(fd, buffer, len);
+               data += 16;
+               remain -= 16;
+       }
+}
+
+/*
+ * Output ACPI table
+ */
+static void acpi_show_table(int fd, struct acpi_table_header *table, unsigned long addr)
+{
+       char buff[80];
+       int len = snprintf(buff, 80, "%.4s @ %p\n", table->signature, (void *)addr);
+       write(fd, buff, len);
+       acpi_show_data(fd, (u8 *) table, table->length);
+       buff[0] = '\n';
+       write(fd, buff, 1);
+}
+
+static void write_table(int fd, struct acpi_table_header *tbl, unsigned long addr)
+{
+       static int select_done = 0;
+       if (!select_sig[0]) {
+               if (print) {
+                       acpi_show_table(fd, tbl, addr);
+               } else {
+                       write(fd, tbl, tbl->length);
+               }
+       } else if (!select_done && !memcmp(select_sig, tbl->signature, 4)) {
+               if (skip > 0) {
+                       --skip;
+                       return;
+               }
+               if (print) {
+                       acpi_show_table(fd, tbl, addr);
+               } else {
+                       write(fd, tbl, tbl->length);
+               }
+               select_done = 1;
+       }
+}
+
+static void acpi_dump_FADT(int fd, struct acpi_table_header *tbl, unsigned long xaddr) {
+       struct acpi_fadt_descriptor x;
+       unsigned long addr;
+       size_t len = sizeof(struct acpi_fadt_descriptor);
+       if (len > tbl->length) len = tbl->length;
+       memcpy(&x, tbl, len);
+       x.header.length = len;
+       if (checksum((u8 *)tbl, len)) {
+               fprintf(stderr, "Wrong checksum for FADT!\n");
+       }
+       if (x.header.length >= 148 && x.Xdsdt) {
+               addr = (unsigned long)x.Xdsdt;
+               if (connect) {
+                       x.Xdsdt = lseek(fd, 0, SEEK_CUR);
+               }
+       } else if (x.header.length >= 44 && x.dsdt) {
+               addr = (unsigned long)x.dsdt;
+               if (connect) {
+                       x.dsdt = lseek(fd, 0, SEEK_CUR);
+               }
+       } else {
+               fprintf(stderr, "No DSDT in FADT!\n");
+               goto no_dsdt;
+       }
+       tbl = acpi_map_table(addr, DSDT_SIG);
+       if (!tbl) goto no_dsdt;
+       if (checksum((u8 *)tbl, tbl->length))
+               fprintf(stderr, "Wrong checksum for DSDT!\n");
+       write_table(fd, tbl, addr);
+       acpi_unmap_table(tbl);
+no_dsdt:
+       if (x.header.length >= 140 && x.xfirmware_ctrl) {
+               addr = (unsigned long)x.xfirmware_ctrl;
+               if (connect) {
+                       x.xfirmware_ctrl = lseek(fd, 0, SEEK_CUR);
+               }
+       } else if (x.header.length >= 40 && x.firmware_ctrl) {
+               addr = (unsigned long)x.firmware_ctrl;
+               if (connect) {
+                       x.firmware_ctrl = lseek(fd, 0, SEEK_CUR);
+               }
+       } else {
+               fprintf(stderr, "No FACS in FADT!\n");
+               goto no_facs;
+       }
+       tbl = acpi_map_table(addr, FACS_SIG);
+       if (!tbl) goto no_facs;
+       /* do not checksum FACS */
+       write_table(fd, tbl, addr);
+       acpi_unmap_table(tbl);
+no_facs:
+       write_table(fd, (struct acpi_table_header *)&x, xaddr);
+}
+
+static int acpi_dump_SDT(int fd, struct acpi_rsdp_descriptor *rsdp)
+{
+       struct acpi_table_header *sdt, *tbl = 0;
+       int xsdt = 1, i, num;
+       char *offset;
+       unsigned long addr;
+       if (rsdp->revision > 1 && rsdp->xsdt_physical_address) {
+               tbl = acpi_map_table(rsdp->xsdt_physical_address, "XSDT");
+       }
+       if (!tbl && rsdp->rsdt_physical_address) {
+               xsdt = 0;
+               tbl = acpi_map_table(rsdp->rsdt_physical_address, "RSDT");
+       }
+       if (!tbl) return 0;
+       sdt = malloc(tbl->length);
+       memcpy(sdt, tbl, tbl->length);
+       acpi_unmap_table(tbl);
+       if (checksum((u8 *)sdt, sdt->length))
+               fprintf(stderr, "Wrong checksum for %s!\n", (xsdt)?"XSDT":"RSDT");
+       num = (sdt->length - sizeof(struct acpi_table_header))/((xsdt)?sizeof(u64):sizeof(u32));
+       offset = (char *)sdt + sizeof(struct acpi_table_header);
+       for (i = 0; i < num; ++i, offset += ((xsdt) ? sizeof(u64) : sizeof(u32))) {
+               addr = (xsdt) ? (unsigned long)(*(u64 *)offset):
+                               (unsigned long)(*(u32 *)offset);
+               if (!addr) continue;
+               tbl = acpi_map_table(addr, 0);
+               if (!tbl) continue;
+               if (!memcmp(tbl->signature, FADT_SIG, 4)) {
+                       acpi_dump_FADT(fd, tbl, addr);
+               } else {
+                       if (checksum((u8 *)tbl, tbl->length))
+                               fprintf(stderr, "Wrong checksum for generic table!\n");
+                       write_table(fd, tbl, addr);
+               }
+               acpi_unmap_table(tbl);
+               if (connect) {
+                       if (xsdt)
+                               (*(u64*)offset) = lseek(fd, 0, SEEK_CUR);
+                       else
+                               (*(u32*)offset) = lseek(fd, 0, SEEK_CUR);
+               }
+       }
+       if (xsdt) {
+               addr = (unsigned long)rsdp->xsdt_physical_address;
+               if (connect) {
+                       rsdp->xsdt_physical_address = lseek(fd, 0, SEEK_CUR);
+               }
+       } else {
+               addr = (unsigned long)rsdp->rsdt_physical_address;
+               if (connect) {
+                       rsdp->rsdt_physical_address = lseek(fd, 0, SEEK_CUR);
+               }
+       }
+       write_table(fd, sdt, addr);
+       free (sdt);
+       return 1;
+}
+
+#define DYNAMIC_SSDT   "/sys/firmware/acpi/tables/dynamic"
+
+static void acpi_dump_dynamic_SSDT(int fd)
+{
+       struct stat file_stat;
+       char filename[256], *ptr;
+       DIR *tabledir;
+       struct dirent *entry;
+       FILE *fp;
+       int count, readcount, length;
+       struct acpi_table_header table_header, *ptable;
+
+       if (stat(DYNAMIC_SSDT, &file_stat) == -1) {
+               /* The directory doesn't exist */
+               return;
+       }
+       tabledir = opendir(DYNAMIC_SSDT);
+       if(!tabledir){
+               /*can't open the directory */
+               return;
+         }
+
+       while ((entry = readdir(tabledir)) != 0){
+               /* skip the file of . /.. */
+               if (entry->d_name[0] == '.')
+                       continue;
+
+               sprintf(filename, "%s/%s", DYNAMIC_SSDT, entry->d_name);
+               fp = fopen(filename, "r");
+               if (fp == NULL) {
+                       fprintf(stderr, "Can't open the file of %s\n",
+                                               filename);
+                       continue;
+               }
+               /* Read the Table header to parse the table length */
+               count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp);
+               if (count < sizeof(table_header)) {
+                       /* the length is lessn than ACPI table header. skip it */
+                       fclose(fp);
+                       continue;
+               }
+               length = table_header.length;
+               ptr = malloc(table_header.length);
+               fseek(fp, 0, SEEK_SET);
+               readcount = 0;
+               while(!feof(fp) && readcount < length) {
+                       count = fread(ptr + readcount, 1, 256, fp);
+                       readcount += count;
+               }
+               fclose(fp);
+               ptable = (struct acpi_table_header *) ptr;
+               if (checksum((u8 *) ptable, ptable->length))
+                       fprintf(stderr, "Wrong checksum "
+                                       "for dynamic SSDT table!\n");
+               write_table(fd, ptable, 0);
+               free(ptr);
+       }
+       closedir(tabledir);
+       return;
+}
+
+static void usage(const char *progname)
+{
+       puts("Usage:");
+       printf("%s [--addr 0x1234][--table DSDT][--output filename]"
+               "[--binary][--length 0x456][--help]\n", progname);
+       puts("\t--addr 0x1234 or -a 0x1234 -- look for tables at this physical address");
+       puts("\t--table DSDT or -t DSDT -- only dump table with DSDT signature");
+       puts("\t--output filename or -o filename -- redirect output from stdin to filename");
+       puts("\t--binary or -b -- dump data in binary form rather than in hex-dump format");
+       puts("\t--length 0x456 or -l 0x456 -- works only with --addr, dump physical memory"
+               "\n\t\tregion without trying to understand it's contents");
+       puts("\t--skip 2 or -s 2 -- skip 2 tables of the given name and output only 3rd one");
+       puts("\t--help or -h -- this help message");
+       exit(0);
+}
+
+static struct option long_options[] = {
+       {"addr", 1, 0, 0},
+       {"table", 1, 0, 0},
+       {"output", 1, 0, 0},
+       {"binary", 0, 0, 0},
+       {"length", 1, 0, 0},
+       {"skip", 1, 0, 0},
+       {"help", 0, 0, 0},
+       {0, 0, 0, 0}
+};
+int main(int argc, char **argv)
+{
+       int option_index, c, fd;
+       u8 *raw;
+       struct acpi_rsdp_descriptor rsdpx, *x = 0;
+       char *filename = 0;
+       char buff[80];
+       memset(select_sig, 0, 4);
+       print = 1;
+       connect = 0;
+       addr = length = 0;
+       skip = 0;
+       while (1) {
+               option_index = 0;
+               c = getopt_long(argc, argv, "a:t:o:bl:s:h",
+                                   long_options, &option_index);
+               if (c == -1)
+                       break;
+
+               switch (c) {
+               case 0:
+                       switch (option_index) {
+                       case 0:
+                               addr = strtoul(optarg, (char **)NULL, 16);
+                               break;
+                       case 1:
+                               memcpy(select_sig, optarg, 4);
+                               break;
+                       case 2:
+                               filename = optarg;
+                               break;
+                       case 3:
+                               print = 0;
+                               break;
+                       case 4:
+                               length = strtoul(optarg, (char **)NULL, 16);
+                               break;
+                       case 5:
+                               skip = strtoul(optarg, (char **)NULL, 10);
+                               break;
+                       case 6:
+                               usage(argv[0]);
+                               exit(0);
+                       }
+                       break;
+               case 'a':
+                       addr = strtoul(optarg, (char **)NULL, 16);
+                       break;
+               case 't':
+                       memcpy(select_sig, optarg, 4);
+                       break;
+               case 'o':
+                       filename = optarg;
+                       break;
+               case 'b':
+                       print = 0;
+                       break;
+               case 'l':
+                       length = strtoul(optarg, (char **)NULL, 16);
+                       break;
+               case 's':
+                       skip = strtoul(optarg, (char **)NULL, 10);
+                       break;
+               case 'h':
+                       usage(argv[0]);
+                       exit(0);
+               default:
+                       printf("Unknown option!\n");
+                       usage(argv[0]);
+                       exit(0);
+               }
+       }
+
+       fd = STDOUT_FILENO;
+       if (filename) {
+               fd = creat(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+               if (fd < 0)
+                       return fd;
+       }
+
+       if (!select_sig[0] && !print) {
+               connect = 1;
+       }
+
+       psz = sysconf(_SC_PAGESIZE);
+       if (length && addr) {
+               /* We know length and address, it means we just want a memory dump */
+               if (!(raw = acpi_map_memory(addr, length)))
+                       goto not_found;
+               write(fd, raw, length);
+               acpi_unmap_memory(raw, length);
+               close(fd);
+               return 0;
+       }
+
+       length = sizeof(struct acpi_rsdp_descriptor);
+       if (!addr) {
+               addr = read_efi_systab();
+               if (!addr) {
+                       addr = ACPI_HI_RSDP_WINDOW_BASE;
+                       length = ACPI_HI_RSDP_WINDOW_SIZE;
+               }
+       }
+
+       if (!(raw = acpi_map_memory(addr, length)) ||
+           !(x = acpi_scan_for_rsdp(raw, length)))
+               goto not_found;
+
+       /* Find RSDP and print all found tables */
+       memcpy(&rsdpx, x, sizeof(struct acpi_rsdp_descriptor));
+       acpi_unmap_memory(raw, length);
+       if (connect) {
+               lseek(fd, sizeof(struct acpi_rsdp_descriptor), SEEK_SET);
+       }
+       if (!acpi_dump_SDT(fd, &rsdpx))
+               goto not_found;
+       if (connect) {
+               lseek(fd, 0, SEEK_SET);
+               write(fd, x, (rsdpx.revision < 2) ?
+                       ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH);
+       } else if (!select_sig[0] || !memcmp("RSD PTR ", select_sig, 4)) {
+               addr += (long)x - (long)raw;
+               length = snprintf(buff, 80, "RSD PTR @ %p\n", (void *)addr);
+               write(fd, buff, length);
+               acpi_show_data(fd, (u8 *) & rsdpx, (rsdpx.revision < 2) ?
+                               ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH);
+               buff[0] = '\n';
+               write(fd, buff, 1);
+       }
+       acpi_dump_dynamic_SSDT(fd);
+       close(fd);
+       return 0;
+not_found:
+       close(fd);
+       fprintf(stderr, "ACPI tables were not found. If you know location "
+               "of RSD PTR table (from dmesg, etc), "
+               "supply it with either --addr or -a option\n");
+       return 1;
+}
index 74e44507dfe9ed9b4c376b075a7dceadb0a0959f..e4d0690cccf9e888a2e920bcb783d17958b81470 100644 (file)
@@ -4,15 +4,11 @@ turbostat \- Report processor frequency and idle statistics
 .SH SYNOPSIS
 .ft B
 .B turbostat
-.RB [ "\-s" ]
-.RB [ "\-v" ]
-.RB [ "\-M MSR#" ]
+.RB [ Options ]
 .RB command
 .br
 .B turbostat
-.RB [ "\-s" ]
-.RB [ "\-v" ]
-.RB [ "\-M MSR#" ]
+.RB [ Options ]
 .RB [ "\-i interval_sec" ]
 .SH DESCRIPTION
 \fBturbostat \fP reports processor topology, frequency
@@ -27,16 +23,23 @@ supports an "invariant" TSC, plus the APERF and MPERF MSRs.
 on processors that additionally support C-state residency counters.
 
 .SS Options
-The \fB-s\fP option limits output to a 1-line system summary for each interval.
+The \fB-p\fP option limits output to the 1st thread in 1st core of each package.
 .PP
-The \fB-c\fP option limits output to the 1st thread in each core.
+The \fB-P\fP option limits output to the 1st thread in each Package.
 .PP
-The \fB-p\fP option limits output to the 1st thread in each package.
+The \fB-S\fP option limits output to a 1-line System Summary for each interval.
 .PP
 The \fB-v\fP option increases verbosity.
 .PP
-The \fB-M MSR#\fP option dumps the specified MSR,
-in addition to the usual frequency and idle statistics.
+The \fB-s\fP option prints the SMI counter, equivalent to "-c 0x34"
+.PP
+The \fB-c MSR#\fP option includes the delta of the specified 32-bit MSR counter.
+.PP
+The \fB-C MSR#\fP option includes the delta of the specified 64-bit MSR counter.
+.PP
+The \fB-m MSR#\fP option includes the the specified 32-bit MSR value.
+.PP
+The \fB-M MSR#\fP option includes the the specified 64-bit MSR value.
 .PP
 The \fB-i interval_sec\fP option prints statistics every \fiinterval_sec\fP seconds.
 The default is 5 seconds.
@@ -150,6 +153,29 @@ Note that turbostat reports average GHz of 3.63, while
 the arithmetic average of the GHz column above is lower.
 This is a weighted average, where the weight is %c0.  ie. it is the total number of
 un-halted cycles elapsed per time divided by the number of CPUs.
+.SH SMI COUNTING EXAMPLE
+On Intel Nehalem and newer processors, MSR 0x34 is a System Management Mode Interrupt (SMI) counter.
+Using the -m option, you can display how many SMIs have fired since reset, or if there
+are SMIs during the measurement interval, you can display the delta using the -d option.
+.nf
+[root@x980 ~]# turbostat -m 0x34
+cor CPU    %c0  GHz  TSC   MSR 0x034    %c1    %c3    %c6   %pc3   %pc6
+          1.41 1.82 3.38  0x00000000   8.92  37.82  51.85  17.37   0.55
+  0   0   3.73 2.03 3.38  0x00000055   1.72  48.25  46.31  17.38   0.55
+  0   6   0.14 1.63 3.38  0x00000056   5.30
+  1   2   2.51 1.80 3.38  0x00000056  15.65  29.33  52.52
+  1   8   0.10 1.65 3.38  0x00000056  18.05
+  2   4   1.16 1.68 3.38  0x00000056   5.87  24.47  68.50
+  2  10   0.10 1.63 3.38  0x00000056   6.93
+  8   1   3.84 1.91 3.38  0x00000056   1.36  50.65  44.16
+  8   7   0.08 1.64 3.38  0x00000056   5.12
+  9   3   1.82 1.73 3.38  0x00000056   7.59  24.21  66.38
+  9   9   0.09 1.68 3.38  0x00000056   9.32
+ 10   5   1.66 1.65 3.38  0x00000056  15.10  50.00  33.23
+ 10  11   1.72 1.65 3.38  0x00000056  15.05
+^C
+[root@x980 ~]# 
+.fi
 .SH NOTES
 
 .B "turbostat "
@@ -165,6 +191,13 @@ may work poorly on Linux-2.6.20 through 2.6.29,
 as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF
 in those kernels.
 
+If the TSC column does not make sense, then
+the other numbers will also make no sense.
+Turbostat is lightweight, and its data collection is not atomic.
+These issues are usually caused by an extremely short measurement
+interval (much less than 1 second), or system activity that prevents
+turbostat from being able to run on all CPUS to quickly collect data.
+
 The APERF, MPERF MSRs are defined to count non-halted cycles.
 Although it is not guaranteed by the architecture, turbostat assumes
 that they count at TSC rate, which is true on all processors tested to date.
index 861d771902065877ee0e09deb50adcde31b534fc..2655ae9a3ad8d9e6f7676006336a5e3b8fec99d1 100644 (file)
@@ -35,9 +35,9 @@
 #include <ctype.h>
 #include <sched.h>
 
-#define MSR_TSC        0x10
 #define MSR_NEHALEM_PLATFORM_INFO      0xCE
 #define MSR_NEHALEM_TURBO_RATIO_LIMIT  0x1AD
+#define MSR_IVT_TURBO_RATIO_LIMIT      0x1AE
 #define MSR_APERF      0xE8
 #define MSR_MPERF      0xE7
 #define MSR_PKG_C2_RESIDENCY   0x60D   /* SNB only */
@@ -62,7 +62,11 @@ unsigned int genuine_intel;
 unsigned int has_invariant_tsc;
 unsigned int do_nehalem_platform_info;
 unsigned int do_nehalem_turbo_ratio_limit;
-unsigned int extra_msr_offset;
+unsigned int do_ivt_turbo_ratio_limit;
+unsigned int extra_msr_offset32;
+unsigned int extra_msr_offset64;
+unsigned int extra_delta_offset32;
+unsigned int extra_delta_offset64;
 double bclk;
 unsigned int show_pkg;
 unsigned int show_core;
@@ -83,7 +87,10 @@ struct thread_data {
        unsigned long long aperf;
        unsigned long long mperf;
        unsigned long long c1;  /* derived */
-       unsigned long long extra_msr;
+       unsigned long long extra_msr64;
+       unsigned long long extra_delta64;
+       unsigned long long extra_msr32;
+       unsigned long long extra_delta32;
        unsigned int cpu_id;
        unsigned int flags;
 #define CPU_IS_FIRST_THREAD_IN_CORE    0x2
@@ -222,6 +229,14 @@ void print_header(void)
        if (has_aperf)
                outp += sprintf(outp, "  GHz");
        outp += sprintf(outp, "  TSC");
+       if (extra_delta_offset32)
+               outp += sprintf(outp, "  count 0x%03X", extra_delta_offset32);
+       if (extra_delta_offset64)
+               outp += sprintf(outp, "  COUNT 0x%03X", extra_delta_offset64);
+       if (extra_msr_offset32)
+               outp += sprintf(outp, "   MSR 0x%03X", extra_msr_offset32);
+       if (extra_msr_offset64)
+               outp += sprintf(outp, "           MSR 0x%03X", extra_msr_offset64);
        if (do_nhm_cstates)
                outp += sprintf(outp, "    %%c1");
        if (do_nhm_cstates)
@@ -238,8 +253,6 @@ void print_header(void)
                outp += sprintf(outp, "   %%pc6");
        if (do_snb_cstates)
                outp += sprintf(outp, "   %%pc7");
-       if (extra_msr_offset)
-               outp += sprintf(outp, "        MSR 0x%x ", extra_msr_offset);
 
        outp += sprintf(outp, "\n");
 }
@@ -255,8 +268,14 @@ int dump_counters(struct thread_data *t, struct core_data *c,
                fprintf(stderr, "aperf: %016llX\n", t->aperf);
                fprintf(stderr, "mperf: %016llX\n", t->mperf);
                fprintf(stderr, "c1: %016llX\n", t->c1);
+               fprintf(stderr, "msr0x%x: %08llX\n",
+                       extra_delta_offset32, t->extra_delta32);
                fprintf(stderr, "msr0x%x: %016llX\n",
-                       extra_msr_offset, t->extra_msr);
+                       extra_delta_offset64, t->extra_delta64);
+               fprintf(stderr, "msr0x%x: %08llX\n",
+                       extra_msr_offset32, t->extra_msr32);
+               fprintf(stderr, "msr0x%x: %016llX\n",
+                       extra_msr_offset64, t->extra_msr64);
        }
 
        if (c) {
@@ -360,6 +379,21 @@ int format_counters(struct thread_data *t, struct core_data *c,
        /* TSC */
        outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float);
 
+       /* delta */
+       if (extra_delta_offset32)
+               outp += sprintf(outp, "  %11llu", t->extra_delta32);
+
+       /* DELTA */
+       if (extra_delta_offset64)
+               outp += sprintf(outp, "  %11llu", t->extra_delta64);
+       /* msr */
+       if (extra_msr_offset32)
+               outp += sprintf(outp, "  0x%08llx", t->extra_msr32);
+
+       /* MSR */
+       if (extra_msr_offset64)
+               outp += sprintf(outp, "  0x%016llx", t->extra_msr64);
+
        if (do_nhm_cstates) {
                if (!skip_c1)
                        outp += sprintf(outp, " %6.2f", 100.0 * t->c1/t->tsc);
@@ -391,8 +425,6 @@ int format_counters(struct thread_data *t, struct core_data *c,
        if (do_snb_cstates)
                outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc);
 done:
-       if (extra_msr_offset)
-               outp += sprintf(outp, "  0x%016llx", t->extra_msr);
        outp += sprintf(outp, "\n");
 
        return 0;
@@ -502,10 +534,16 @@ delta_thread(struct thread_data *new, struct thread_data *old,
                old->mperf = 1; /* divide by 0 protection */
        }
 
+       old->extra_delta32 = new->extra_delta32 - old->extra_delta32;
+       old->extra_delta32 &= 0xFFFFFFFF;
+
+       old->extra_delta64 = new->extra_delta64 - old->extra_delta64;
+
        /*
-        * for "extra msr", just copy the latest w/o subtracting
+        * Extra MSR is just a snapshot, simply copy latest w/o subtracting
         */
-       old->extra_msr = new->extra_msr;
+       old->extra_msr32 = new->extra_msr32;
+       old->extra_msr64 = new->extra_msr64;
 }
 
 int delta_cpu(struct thread_data *t, struct core_data *c,
@@ -533,6 +571,9 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
        t->mperf = 0;
        t->c1 = 0;
 
+       t->extra_delta32 = 0;
+       t->extra_delta64 = 0;
+
        /* tells format_counters to dump all fields from this set */
        t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE;
 
@@ -553,6 +594,9 @@ int sum_counters(struct thread_data *t, struct core_data *c,
        average.threads.mperf += t->mperf;
        average.threads.c1 += t->c1;
 
+       average.threads.extra_delta32 += t->extra_delta32;
+       average.threads.extra_delta64 += t->extra_delta64;
+
        /* sum per-core values only for 1st thread in core */
        if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
                return 0;
@@ -588,6 +632,11 @@ void compute_average(struct thread_data *t, struct core_data *c,
        average.threads.mperf /= topo.num_cpus;
        average.threads.c1 /= topo.num_cpus;
 
+       average.threads.extra_delta32 /= topo.num_cpus;
+       average.threads.extra_delta32 &= 0xFFFFFFFF;
+
+       average.threads.extra_delta64 /= topo.num_cpus;
+
        average.cores.c3 /= topo.num_cores;
        average.cores.c6 /= topo.num_cores;
        average.cores.c7 /= topo.num_cores;
@@ -629,8 +678,24 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
                        return -4;
        }
 
-       if (extra_msr_offset)
-               if (get_msr(cpu, extra_msr_offset, &t->extra_msr))
+       if (extra_delta_offset32) {
+               if (get_msr(cpu, extra_delta_offset32, &t->extra_delta32))
+                       return -5;
+               t->extra_delta32 &= 0xFFFFFFFF;
+       }
+
+       if (extra_delta_offset64)
+               if (get_msr(cpu, extra_delta_offset64, &t->extra_delta64))
+                       return -5;
+
+       if (extra_msr_offset32) {
+               if (get_msr(cpu, extra_msr_offset32, &t->extra_msr32))
+                       return -5;
+               t->extra_msr32 &= 0xFFFFFFFF;
+       }
+
+       if (extra_msr_offset64)
+               if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64))
                        return -5;
 
        /* collect core counters only for 1st thread in core */
@@ -677,6 +742,9 @@ void print_verbose_header(void)
 
        get_msr(0, MSR_NEHALEM_PLATFORM_INFO, &msr);
 
+       if (verbose > 1)
+               fprintf(stderr, "MSR_NEHALEM_PLATFORM_INFO: 0x%llx\n", msr);
+
        ratio = (msr >> 40) & 0xFF;
        fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency\n",
                ratio, bclk, ratio * bclk);
@@ -685,14 +753,84 @@ void print_verbose_header(void)
        fprintf(stderr, "%d * %.0f = %.0f MHz TSC frequency\n",
                ratio, bclk, ratio * bclk);
 
+       if (!do_ivt_turbo_ratio_limit)
+               goto print_nhm_turbo_ratio_limits;
+
+       get_msr(0, MSR_IVT_TURBO_RATIO_LIMIT, &msr);
+
        if (verbose > 1)
-               fprintf(stderr, "MSR_NEHALEM_PLATFORM_INFO: 0x%llx\n", msr);
+               fprintf(stderr, "MSR_IVT_TURBO_RATIO_LIMIT: 0x%llx\n", msr);
+
+       ratio = (msr >> 56) & 0xFF;
+       if (ratio)
+               fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 16 active cores\n",
+                       ratio, bclk, ratio * bclk);
+
+       ratio = (msr >> 48) & 0xFF;
+       if (ratio)
+               fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 15 active cores\n",
+                       ratio, bclk, ratio * bclk);
+
+       ratio = (msr >> 40) & 0xFF;
+       if (ratio)
+               fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 14 active cores\n",
+                       ratio, bclk, ratio * bclk);
+
+       ratio = (msr >> 32) & 0xFF;
+       if (ratio)
+               fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 13 active cores\n",
+                       ratio, bclk, ratio * bclk);
+
+       ratio = (msr >> 24) & 0xFF;
+       if (ratio)
+               fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 12 active cores\n",
+                       ratio, bclk, ratio * bclk);
+
+       ratio = (msr >> 16) & 0xFF;
+       if (ratio)
+               fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 11 active cores\n",
+                       ratio, bclk, ratio * bclk);
+
+       ratio = (msr >> 8) & 0xFF;
+       if (ratio)
+               fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 10 active cores\n",
+                       ratio, bclk, ratio * bclk);
+
+       ratio = (msr >> 0) & 0xFF;
+       if (ratio)
+               fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 9 active cores\n",
+                       ratio, bclk, ratio * bclk);
+
+print_nhm_turbo_ratio_limits:
 
        if (!do_nehalem_turbo_ratio_limit)
                return;
 
        get_msr(0, MSR_NEHALEM_TURBO_RATIO_LIMIT, &msr);
 
+       if (verbose > 1)
+               fprintf(stderr, "MSR_NEHALEM_TURBO_RATIO_LIMIT: 0x%llx\n", msr);
+
+       ratio = (msr >> 56) & 0xFF;
+       if (ratio)
+               fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 8 active cores\n",
+                       ratio, bclk, ratio * bclk);
+
+       ratio = (msr >> 48) & 0xFF;
+       if (ratio)
+               fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 7 active cores\n",
+                       ratio, bclk, ratio * bclk);
+
+       ratio = (msr >> 40) & 0xFF;
+       if (ratio)
+               fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 6 active cores\n",
+                       ratio, bclk, ratio * bclk);
+
+       ratio = (msr >> 32) & 0xFF;
+       if (ratio)
+               fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 5 active cores\n",
+                       ratio, bclk, ratio * bclk);
+
        ratio = (msr >> 24) & 0xFF;
        if (ratio)
                fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 4 active cores\n",
@@ -712,7 +850,6 @@ void print_verbose_header(void)
        if (ratio)
                fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 1 active cores\n",
                        ratio, bclk, ratio * bclk);
-
 }
 
 void free_all_buffers(void)
@@ -1038,7 +1175,7 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
        case 0x2A:      /* SNB */
        case 0x2D:      /* SNB Xeon */
        case 0x3A:      /* IVB */
-       case 0x3D:      /* IVB Xeon */
+       case 0x3E:      /* IVB Xeon */
                return 1;
        case 0x2E:      /* Nehalem-EX Xeon - Beckton */
        case 0x2F:      /* Westmere-EX Xeon - Eagleton */
@@ -1046,6 +1183,22 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
                return 0;
        }
 }
+int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
+{
+       if (!genuine_intel)
+               return 0;
+
+       if (family != 6)
+               return 0;
+
+       switch (model) {
+       case 0x3E:      /* IVB Xeon */
+               return 1;
+       default:
+               return 0;
+       }
+}
+
 
 int is_snb(unsigned int family, unsigned int model)
 {
@@ -1056,7 +1209,7 @@ int is_snb(unsigned int family, unsigned int model)
        case 0x2A:
        case 0x2D:
        case 0x3A:      /* IVB */
-       case 0x3D:      /* IVB Xeon */
+       case 0x3E:      /* IVB Xeon */
                return 1;
        }
        return 0;
@@ -1145,12 +1298,13 @@ void check_cpuid()
        bclk = discover_bclk(family, model);
 
        do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model);
+       do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model);
 }
 
 
 void usage()
 {
-       fprintf(stderr, "%s: [-v] [-M MSR#] [-i interval_sec | command ...]\n",
+       fprintf(stderr, "%s: [-v][-p|-P|-S][-c MSR# | -s]][-C MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n",
                progname);
        exit(1);
 }
@@ -1440,15 +1594,15 @@ void cmdline(int argc, char **argv)
 
        progname = argv[0];
 
-       while ((opt = getopt(argc, argv, "+cpsvi:M:")) != -1) {
+       while ((opt = getopt(argc, argv, "+pPSvisc:sC:m:M:")) != -1) {
                switch (opt) {
-               case 'c':
+               case 'p':
                        show_core_only++;
                        break;
-               case 'p':
+               case 'P':
                        show_pkg_only++;
                        break;
-               case 's':
+               case 'S':
                        summary_only++;
                        break;
                case 'v':
@@ -1457,10 +1611,20 @@ void cmdline(int argc, char **argv)
                case 'i':
                        interval_sec = atoi(optarg);
                        break;
+               case 'c':
+                       sscanf(optarg, "%x", &extra_delta_offset32);
+                       break;
+               case 's':
+                       extra_delta_offset32 = 0x34;    /* SMI counter */
+                       break;
+               case 'C':
+                       sscanf(optarg, "%x", &extra_delta_offset64);
+                       break;
+               case 'm':
+                       sscanf(optarg, "%x", &extra_msr_offset32);
+                       break;
                case 'M':
-                       sscanf(optarg, "%x", &extra_msr_offset);
-                       if (verbose > 1)
-                               fprintf(stderr, "MSR 0x%X\n", extra_msr_offset);
+                       sscanf(optarg, "%x", &extra_msr_offset64);
                        break;
                default:
                        usage();
@@ -1473,7 +1637,7 @@ int main(int argc, char **argv)
        cmdline(argc, argv);
 
        if (verbose > 1)
-               fprintf(stderr, "turbostat v2.0 May 16, 2012"
+               fprintf(stderr, "turbostat v2.1 October 6, 2012"
                        " - Len Brown <lenb@kernel.org>\n");
 
        turbostat_init();