]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
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

281 files changed:
Documentation/ABI/testing/sysfs-devices-firmware_node [new file with mode: 0644]
Documentation/vfio.txt
MAINTAINERS
Makefile
arch/arm/boot/compressed/head.S
arch/arm/boot/dts/at91sam9260.dtsi
arch/arm/boot/dts/at91sam9263.dtsi
arch/arm/boot/dts/at91sam9g45.dtsi
arch/arm/boot/dts/at91sam9n12.dtsi
arch/arm/boot/dts/at91sam9x5.dtsi
arch/arm/include/asm/unistd.h
arch/arm/kernel/calls.S
arch/arm/kernel/smp_twd.c
arch/arm/mach-imx/clk-imx25.c
arch/arm/mach-imx/mach-armadillo5x0.c
arch/arm/mach-mxs/mach-mxs.c
arch/arm/mach-orion5x/common.c
arch/arm/mach-shmobile/board-kzm9g.c
arch/arm/mm/dma-mapping.c
arch/arm/plat-mxc/include/mach/mx25.h
arch/arm/plat-samsung/clock.c
arch/c6x/include/asm/Kbuild
arch/c6x/include/asm/barrier.h [deleted file]
arch/m68k/platform/coldfire/clk.c
arch/mips/kernel/smp-cmp.c
arch/mips/mm/gup.c
arch/mips/mti-malta/malta-int.c
arch/mips/mti-malta/malta-platform.c
arch/s390/include/asm/hugetlb.h
arch/s390/include/asm/tlbflush.h
arch/s390/kernel/setup.c
arch/s390/lib/uaccess_pt.c
arch/sparc/kernel/module.c
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/Kconfig
arch/x86/Makefile
arch/x86/include/asm/xen/page.h
arch/x86/kernel/cpu/perf_event.h
arch/x86/kernel/cpu/perf_event_amd_ibs.c
arch/x86/kernel/cpu/perf_event_intel.c
arch/x86/kernel/cpu/perf_event_intel_ds.c
arch/x86/kernel/cpu/perf_event_intel_uncore.c
arch/x86/mm/init.c
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/enlighten.c
arch/x86/xen/p2m.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/bus.c
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/tables.c
drivers/acpi/utils.c
drivers/block/aoe/aoecmd.c
drivers/block/nvme.c
drivers/block/rbd.c
drivers/block/xen-blkback/blkback.c
drivers/clk/Makefile
drivers/clk/clk-devres.c [new file with mode: 0644]
drivers/clk/clkdev.c
drivers/dma/at_hdmac.c
drivers/dma/pl330.c
drivers/edac/edac_mc.c
drivers/edac/i3200_edac.c
drivers/edac/i5000_edac.c
drivers/edac/sb_edac.c
drivers/gpio/gpio-lpc32xx.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/nouveau/nouveau_abi16.c
drivers/gpu/drm/nouveau/nv50_gpio.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/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/udl/udl_connector.c
drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
drivers/hid/hid-lenovo-tpkbd.c
drivers/hid/hid-logitech-dj.c
drivers/hid/hid-logitech-dj.h
drivers/hwmon/ad7314.c
drivers/hwmon/ads7871.c
drivers/hwmon/applesmc.c
drivers/hwmon/coretemp.c
drivers/hwmon/fam15h_power.c
drivers/hwmon/via-cputemp.c
drivers/i2c/busses/i2c-scmi.c
drivers/idle/intel_idle.c
drivers/input/keyboard/imx_keypad.c
drivers/input/misc/ab8500-ponkey.c
drivers/input/misc/atlas_btns.c
drivers/input/mouse/sentelic.c
drivers/input/serio/ambakmi.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/touchscreen/edt-ft5x06.c
drivers/input/touchscreen/usbtouchscreen.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/can/janz-ican3.c
drivers/net/can/ti_hecc.c
drivers/net/ethernet/broadcom/bnx2.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/cadence/at91_ether.c
drivers/net/ethernet/freescale/gianfar_ethtool.c
drivers/net/ethernet/freescale/gianfar_ptp.c
drivers/net/ethernet/intel/e1000/e1000_main.c
drivers/net/ethernet/octeon/octeon_mgmt.c
drivers/net/ethernet/pasemi/pasemi_mac.c
drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_timer.c
drivers/net/irda/sh_sir.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/asix_devices.c
drivers/net/usb/qmi_wwan.c
drivers/net/usb/smsc75xx.c
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/link.c
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
drivers/net/wireless/brcm80211/brcmsmac/channel.c
drivers/net/wireless/iwlwifi/pcie/trans.c
drivers/net/wireless/rtlwifi/rtl8192ce/def.h
drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
drivers/net/wireless/rtlwifi/rtl8192ce/sw.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/s390/block/dasd.c
drivers/s390/block/dasd_alias.c
drivers/s390/block/dasd_eckd.c
drivers/s390/cio/device.c
drivers/scsi/bnx2i/bnx2i_hwi.c
drivers/scsi/hpsa.c
drivers/scsi/mpt2sas/mpt2sas_base.c
drivers/scsi/virtio_scsi.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
drivers/watchdog/hpwdt.c
drivers/watchdog/watchdog_core.c
drivers/xen/gntdev.c
drivers/xen/grant-table.c
fs/cifs/cifs_unicode.c
fs/dcache.c
fs/debugfs/file.c
fs/lockd/svclock.c
fs/namespace.c
fs/xfs/xfs_buf.c
fs/xfs/xfs_buf.h
fs/xfs/xfs_super.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/kernel.h
include/linux/micrel_phy.h
include/linux/nvme.h
include/linux/perf_event.h
include/linux/security.h
include/linux/xfrm.h
include/net/ip6_fib.h
include/net/net_namespace.h
include/net/netns/ipv4.h
include/net/route.h
include/trace/events/kmem.h
include/xen/grant_table.h
kernel/time/timekeeping.c
lib/flex_proportions.c
mm/huge_memory.c
net/batman-adv/bat_iv_ogm.c
net/batman-adv/bitarray.h
net/batman-adv/soft-interface.c
net/bluetooth/bnep/sock.c
net/bluetooth/cmtp/sock.c
net/bluetooth/hci_core.c
net/bluetooth/hci_sock.c
net/bluetooth/hidp/sock.c
net/bluetooth/l2cap_core.c
net/bluetooth/mgmt.c
net/ceph/messenger.c
net/core/dev.c
net/core/skbuff.c
net/core/sock.c
net/ipv4/arp.c
net/ipv4/devinet.c
net/ipv4/fib_frontend.c
net/ipv4/fib_rules.c
net/ipv4/fib_trie.c
net/ipv4/inetpeer.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv6/inet6_connection_sock.c
net/ipv6/ip6_fib.c
net/ipv6/mip6.c
net/ipv6/raw.c
net/ipv6/route.c
net/l2tp/l2tp_netlink.c
net/netfilter/xt_limit.c
net/netrom/af_netrom.c
net/sched/sch_qfq.c
net/wireless/reg.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_user.c
scripts/Makefile.fwinst
scripts/checksyscalls.sh
security/selinux/include/xfrm.h
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]

diff --git a/Documentation/ABI/testing/sysfs-devices-firmware_node b/Documentation/ABI/testing/sysfs-devices-firmware_node
new file mode 100644 (file)
index 0000000..46badc9
--- /dev/null
@@ -0,0 +1,17 @@
+What:          /sys/devices/.../firmware_node/
+Date:          September 2012
+Contact:       <>
+Description:
+               The /sys/devices/.../firmware_node directory contains attributes
+               allowing the user space to check and modify some firmware
+               related properties of given device.
+
+What:          /sys/devices/.../firmware_node/description
+Date:          September 2012
+Contact:       Lance Ortiz <lance.ortiz@hp.com>
+Description:
+               The /sys/devices/.../firmware/description attribute contains a string
+               that describes the device as provided by the _STR method in the ACPI
+               namespace.  This attribute is read-only.  If the device does not have
+               an _STR method associated with it in the ACPI namespace, this
+               attribute is not present.
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 ae6928cc59d36d1450b6c9f6e5d87067b662a8db..bb9fff26f078063c395fe8f86488349614c84261 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 VERSION = 3
 PATCHLEVEL = 6
 SUBLEVEL = 0
-EXTRAVERSION = -rc6
-NAME = Saber-toothed Squirrel
+EXTRAVERSION =
+NAME = Terrified Chipmunk
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
index 81769c1341fa7d071c105d8dcb6b2fe0d9b8110c..bc67cbff39448ff84a3f0c14cd22876975ee1965 100644 (file)
@@ -653,6 +653,7 @@ __armv7_mmu_cache_on:
                mcrne   p15, 0, r0, c8, c7, 0   @ flush I,D TLBs
 #endif
                mrc     p15, 0, r0, c1, c0, 0   @ read control reg
+               bic     r0, r0, #1 << 28        @ clear SCTLR.TRE
                orr     r0, r0, #0x5000         @ I-cache enable, RR cache replacement
                orr     r0, r0, #0x003c         @ write buffer
 #ifdef CONFIG_MMU
index 66389c1c6f6297e50c8ae3b944d7311dcbb26b6c..7c95f76398de401ac166af8f32d4a34a6b918e79 100644 (file)
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioB: gpio@fffff600 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioC: gpio@fffff800 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        dbgu: serial@fffff200 {
index b460d6ce9eb592da5191871b40b2d3433156bcef..195019b7ca0e046073361a587862c885c8fbfb7e 100644 (file)
@@ -95,6 +95,7 @@
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioB: gpio@fffff400 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioC: gpio@fffff600 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioD: gpio@fffff800 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioE: gpio@fffffa00 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        dbgu: serial@ffffee00 {
index bafa8806fc17293e3bddc28aff5b4829f677c178..63751b1e744b42611f8e74d17738ccd69dd1efe1 100644 (file)
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioB: gpio@fffff400 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioC: gpio@fffff600 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioD: gpio@fffff800 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioE: gpio@fffffa00 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        dbgu: serial@ffffee00 {
index bfac0dfc332c7d10bc3fe2f87458ec728c48b885..ef9336ae9614f85ffb0ce2348b69fc06b0f756e5 100644 (file)
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioB: gpio@fffff600 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioC: gpio@fffff800 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioD: gpio@fffffa00 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        dbgu: serial@fffff200 {
index 4a18c393b1360f490c9796f3c598d349338ed2f5..8a387a8d61b745fc763c9e13f015896bc3e2bff7 100644 (file)
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioB: gpio@fffff600 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioC: gpio@fffff800 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        pioD: gpio@fffffa00 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                interrupt-controller;
+                               #interrupt-cells = <2>;
                        };
 
                        dbgu: serial@fffff200 {
index 0cab47d4a83ff97a23c7a9d2975cfb855a687e3e..2fde5fd1accedda5a00accac967e1985be9c7f08 100644 (file)
 #define __NR_setns                     (__NR_SYSCALL_BASE+375)
 #define __NR_process_vm_readv          (__NR_SYSCALL_BASE+376)
 #define __NR_process_vm_writev         (__NR_SYSCALL_BASE+377)
+                                       /* 378 for kcmp */
 
 /*
  * The following SWIs are ARM private.
  */
 #define __IGNORE_fadvise64_64
 #define __IGNORE_migrate_pages
+#define __IGNORE_kcmp
 
 #endif /* __KERNEL__ */
 #endif /* __ASM_ARM_UNISTD_H */
index 463ff4a0ec8acaa69372b8abd40a39260ee91736..e337879595e565e5666cbd8ac0c40a4a72908c0e 100644 (file)
 /* 375 */      CALL(sys_setns)
                CALL(sys_process_vm_readv)
                CALL(sys_process_vm_writev)
+               CALL(sys_ni_syscall)    /* reserved for sys_kcmp */
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
index fef42b21cecba517e67e8ed74ef8c88d3cfd2afd..e1f906989bb8161963d8a714073a8d84a8e2c2e6 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/clk.h>
-#include <linux/cpufreq.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/err.h>
@@ -96,7 +95,52 @@ static void twd_timer_stop(struct clock_event_device *clk)
        disable_percpu_irq(clk->irq);
 }
 
-#ifdef CONFIG_CPU_FREQ
+#ifdef CONFIG_COMMON_CLK
+
+/*
+ * Updates clockevent frequency when the cpu frequency changes.
+ * Called on the cpu that is changing frequency with interrupts disabled.
+ */
+static void twd_update_frequency(void *new_rate)
+{
+       twd_timer_rate = *((unsigned long *) new_rate);
+
+       clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate);
+}
+
+static int twd_rate_change(struct notifier_block *nb,
+       unsigned long flags, void *data)
+{
+       struct clk_notifier_data *cnd = data;
+
+       /*
+        * The twd clock events must be reprogrammed to account for the new
+        * frequency.  The timer is local to a cpu, so cross-call to the
+        * changing cpu.
+        */
+       if (flags == POST_RATE_CHANGE)
+               smp_call_function(twd_update_frequency,
+                                 (void *)&cnd->new_rate, 1);
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block twd_clk_nb = {
+       .notifier_call = twd_rate_change,
+};
+
+static int twd_clk_init(void)
+{
+       if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
+               return clk_notifier_register(twd_clk, &twd_clk_nb);
+
+       return 0;
+}
+core_initcall(twd_clk_init);
+
+#elif defined (CONFIG_CPU_FREQ)
+
+#include <linux/cpufreq.h>
 
 /*
  * Updates clockevent frequency when the cpu frequency changes.
index 4431a62fff5b9d3a140cd1ec3473e4f51a05f99b..d20d4795f4eaebeb633c73ec441c36a661949a47 100644 (file)
@@ -241,6 +241,6 @@ int __init mx25_clocks_init(void)
        clk_register_clkdev(clk[sdma_ahb], "ahb", "imx35-sdma");
        clk_register_clkdev(clk[iim_ipg], "iim", NULL);
 
-       mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
+       mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), MX25_INT_GPT1);
        return 0;
 }
index 2c6ab3273f9e4d4a419e54a4f7cde417fdb213a6..5985ed1b8c9875cffc99ab74233147912ae01eca 100644 (file)
@@ -526,7 +526,8 @@ static void __init armadillo5x0_init(void)
        imx31_add_mxc_nand(&armadillo5x0_nand_board_info);
 
        /* set NAND page size to 2k if not configured via boot mode pins */
-       __raw_writel(__raw_readl(MXC_CCM_RCSR) | (1 << 30), MXC_CCM_RCSR);
+       __raw_writel(__raw_readl(mx3_ccm_base + MXC_CCM_RCSR) |
+                                       (1 << 30), mx3_ccm_base + MXC_CCM_RCSR);
 
        /* RTC */
        /* Get RTC IRQ and register the chip */
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 53b7ea92c32c119bcfc6d44a96b92fac915363da..3b8a0171c3cb3e30aa7242afcdc65f13cd5c11de 100644 (file)
@@ -346,11 +346,11 @@ static struct resource sh_mmcif_resources[] = {
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = gic_spi(141),
+               .start  = gic_spi(140),
                .flags  = IORESOURCE_IRQ,
        },
        [2] = {
-               .start  = gic_spi(140),
+               .start  = gic_spi(141),
                .flags  = IORESOURCE_IRQ,
        },
 };
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 627d94f1b010d32d09091bf4f025fabb617bde03..ec466400a2002943de0ccaf840f25266db6149e0 100644 (file)
@@ -98,6 +98,7 @@
 #define MX25_INT_UART1         (NR_IRQS_LEGACY + 45)
 #define MX25_INT_GPIO2         (NR_IRQS_LEGACY + 51)
 #define MX25_INT_GPIO1         (NR_IRQS_LEGACY + 52)
+#define MX25_INT_GPT1          (NR_IRQS_LEGACY + 54)
 #define MX25_INT_FEC           (NR_IRQS_LEGACY + 57)
 
 #define MX25_DMA_REQ_SSI2_RX1  22
index 65c5eca475e76ef839a16aaef568173a2dc0ee1c..d1116e2dfbeaf57ccd0c2a1aff9ce413d9b57f2a 100644 (file)
@@ -144,6 +144,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
 
 int clk_set_rate(struct clk *clk, unsigned long rate)
 {
+       unsigned long flags;
        int ret;
 
        if (IS_ERR(clk))
@@ -159,9 +160,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
        if (clk->ops == NULL || clk->ops->set_rate == NULL)
                return -EINVAL;
 
-       spin_lock(&clocks_lock);
+       spin_lock_irqsave(&clocks_lock, flags);
        ret = (clk->ops->set_rate)(clk, rate);
-       spin_unlock(&clocks_lock);
+       spin_unlock_irqrestore(&clocks_lock, flags);
 
        return ret;
 }
@@ -173,17 +174,18 @@ struct clk *clk_get_parent(struct clk *clk)
 
 int clk_set_parent(struct clk *clk, struct clk *parent)
 {
+       unsigned long flags;
        int ret = 0;
 
        if (IS_ERR(clk))
                return -EINVAL;
 
-       spin_lock(&clocks_lock);
+       spin_lock_irqsave(&clocks_lock, flags);
 
        if (clk->ops && clk->ops->set_parent)
                ret = (clk->ops->set_parent)(clk, parent);
 
-       spin_unlock(&clocks_lock);
+       spin_unlock_irqrestore(&clocks_lock, flags);
 
        return ret;
 }
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 75f9ee967ea71cc696c3ed9cc5efb390b4ed209a..9cd13b4ce42ba9eb4367be63010802a632577629 100644 (file)
@@ -146,9 +146,3 @@ struct clk_ops clk_ops1 = {
 };
 #endif /* MCFPM_PPMCR1 */
 #endif /* MCFPM_PPMCR0 */
-
-struct clk *devm_clk_get(struct device *dev, const char *id)
-{
-       return NULL;
-}
-EXPORT_SYMBOL(devm_clk_get);
index e7e03ecf54959988e029e81783422fa0c5b78554..afc379ca375301f7e916a4fd46447239ad478a38 100644 (file)
@@ -102,7 +102,7 @@ static void cmp_init_secondary(void)
        c->vpe_id = (read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) & TCBIND_CURVPE;
 #endif
 #ifdef CONFIG_MIPS_MT_SMTC
-       c->tc_id  = (read_c0_tcbind() >> TCBIND_CURTC_SHIFT) & TCBIND_CURTC;
+       c->tc_id  = (read_c0_tcbind() & TCBIND_CURTC) >> TCBIND_CURTC_SHIFT;
 #endif
 }
 
index 33aadbcf170bb4428020ddb87a17383180719400..dcfd573871c142348c4fa790bfcbd3dcc0c50879 100644 (file)
@@ -152,6 +152,8 @@ static int gup_huge_pud(pud_t pud, unsigned long addr, unsigned long end,
        do {
                VM_BUG_ON(compound_head(page) != head);
                pages[*nr] = page;
+               if (PageTail(page))
+                       get_huge_page_tail(page);
                (*nr)++;
                page++;
                refs++;
index 7b13a4caeea41b6377fb9410fe1397f2dce6aef2..fea823f184794a8a9003ce79afd90cb762a4ed52 100644 (file)
@@ -273,16 +273,19 @@ asmlinkage void plat_irq_dispatch(void)
        unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
        int irq;
 
+       if (unlikely(!pending)) {
+               spurious_interrupt();
+               return;
+       }
+
        irq = irq_ffs(pending);
 
        if (irq == MIPSCPU_INT_I8259A)
                malta_hw0_irqdispatch();
        else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()]))
                malta_ipi_irqdispatch();
-       else if (irq >= 0)
-               do_IRQ(MIPS_CPU_IRQ_BASE + irq);
        else
-               spurious_interrupt();
+               do_IRQ(MIPS_CPU_IRQ_BASE + irq);
 }
 
 #ifdef CONFIG_MIPS_MT_SMP
index 4c35301720e76c04aad4eade1d88310c107ba6fd..80562b81f0f2a2036fbf0a28781601b420c5d872 100644 (file)
@@ -138,11 +138,6 @@ static int __init malta_add_devices(void)
        if (err)
                return err;
 
-       /*
-        * Set RTC to BCD mode to support current alarm code.
-        */
-       CMOS_WRITE(CMOS_READ(RTC_CONTROL) & ~RTC_DM_BINARY, RTC_CONTROL);
-
        return 0;
 }
 
index 799ed0f1643d135c843f3a1cdc41204063289f0f..2d6e6e3805641bbc79ce1ee11aa639f48f5e2933 100644 (file)
@@ -66,16 +66,6 @@ static inline pte_t huge_ptep_get(pte_t *ptep)
        return pte;
 }
 
-static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
-                                           unsigned long addr, pte_t *ptep)
-{
-       pte_t pte = huge_ptep_get(ptep);
-
-       mm->context.flush_mm = 1;
-       pmd_clear((pmd_t *) ptep);
-       return pte;
-}
-
 static inline void __pmd_csp(pmd_t *pmdp)
 {
        register unsigned long reg2 asm("2") = pmd_val(*pmdp);
@@ -117,6 +107,15 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm,
                __pmd_csp(pmdp);
 }
 
+static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+                                           unsigned long addr, pte_t *ptep)
+{
+       pte_t pte = huge_ptep_get(ptep);
+
+       huge_ptep_invalidate(mm, addr, ptep);
+       return pte;
+}
+
 #define huge_ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \
 ({                                                                         \
        int __changed = !pte_same(huge_ptep_get(__ptep), __entry);          \
@@ -131,10 +130,7 @@ static inline void huge_ptep_invalidate(struct mm_struct *mm,
 ({                                                                     \
        pte_t __pte = huge_ptep_get(__ptep);                            \
        if (pte_write(__pte)) {                                         \
-               (__mm)->context.flush_mm = 1;                           \
-               if (atomic_read(&(__mm)->context.attach_count) > 1 ||   \
-                   (__mm) != current->active_mm)                       \
-                       huge_ptep_invalidate(__mm, __addr, __ptep);     \
+               huge_ptep_invalidate(__mm, __addr, __ptep);             \
                set_huge_pte_at(__mm, __addr, __ptep,                   \
                                huge_pte_wrprotect(__pte));             \
        }                                                               \
index 9fde315f3a7cd42184a54f2174584258076e6a60..1d8fe2b17ef6f1d0069c0e3cc8ff70c7d9cc402a 100644 (file)
@@ -90,12 +90,10 @@ static inline void __tlb_flush_mm(struct mm_struct * mm)
 
 static inline void __tlb_flush_mm_cond(struct mm_struct * mm)
 {
-       spin_lock(&mm->page_table_lock);
        if (mm->context.flush_mm) {
                __tlb_flush_mm(mm);
                mm->context.flush_mm = 0;
        }
-       spin_unlock(&mm->page_table_lock);
 }
 
 /*
index f86c81e13c374be484f591faead417a7fb3ee572..40b57693de389b24a5b08decae1dbb1fedd47e6c 100644 (file)
@@ -974,11 +974,13 @@ static void __init setup_hwcaps(void)
        if (MACHINE_HAS_HPAGE)
                elf_hwcap |= HWCAP_S390_HPAGE;
 
+#if defined(CONFIG_64BIT)
        /*
         * 64-bit register support for 31-bit processes
         * HWCAP_S390_HIGH_GPRS is bit 9.
         */
        elf_hwcap |= HWCAP_S390_HIGH_GPRS;
+#endif
 
        get_cpu_id(&cpu_id);
        switch (cpu_id.machine) {
index 60ee2b8837972c27d8bfb3d95dd9fc3b0b4d0091..2d37bb861faf69cf43e30971881fae771322158a 100644 (file)
@@ -2,69 +2,82 @@
  *  User access functions based on page table walks for enhanced
  *  system layout without hardware support.
  *
- *    Copyright IBM Corp. 2006
+ *    Copyright IBM Corp. 2006, 2012
  *    Author(s): Gerald Schaefer (gerald.schaefer@de.ibm.com)
  */
 
 #include <linux/errno.h>
 #include <linux/hardirq.h>
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 #include <asm/uaccess.h>
 #include <asm/futex.h>
 #include "uaccess.h"
 
-static inline pte_t *follow_table(struct mm_struct *mm, unsigned long addr)
+
+/*
+ * Returns kernel address for user virtual address. If the returned address is
+ * >= -4095 (IS_ERR_VALUE(x) returns true), a fault has occured and the address
+ * contains the (negative) exception code.
+ */
+static __always_inline unsigned long follow_table(struct mm_struct *mm,
+                                                 unsigned long addr, int write)
 {
        pgd_t *pgd;
        pud_t *pud;
        pmd_t *pmd;
+       pte_t *ptep;
 
        pgd = pgd_offset(mm, addr);
        if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
-               return (pte_t *) 0x3a;
+               return -0x3aUL;
 
        pud = pud_offset(pgd, addr);
        if (pud_none(*pud) || unlikely(pud_bad(*pud)))
-               return (pte_t *) 0x3b;
+               return -0x3bUL;
 
        pmd = pmd_offset(pud, addr);
-       if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
-               return (pte_t *) 0x10;
+       if (pmd_none(*pmd))
+               return -0x10UL;
+       if (pmd_huge(*pmd)) {
+               if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO))
+                       return -0x04UL;
+               return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK);
+       }
+       if (unlikely(pmd_bad(*pmd)))
+               return -0x10UL;
+
+       ptep = pte_offset_map(pmd, addr);
+       if (!pte_present(*ptep))
+               return -0x11UL;
+       if (write && !pte_write(*ptep))
+               return -0x04UL;
 
-       return pte_offset_map(pmd, addr);
+       return (pte_val(*ptep) & PAGE_MASK) + (addr & ~PAGE_MASK);
 }
 
 static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr,
                                             size_t n, int write_user)
 {
        struct mm_struct *mm = current->mm;
-       unsigned long offset, pfn, done, size;
-       pte_t *pte;
+       unsigned long offset, done, size, kaddr;
        void *from, *to;
 
        done = 0;
 retry:
        spin_lock(&mm->page_table_lock);
        do {
-               pte = follow_table(mm, uaddr);
-               if ((unsigned long) pte < 0x1000)
+               kaddr = follow_table(mm, uaddr, write_user);
+               if (IS_ERR_VALUE(kaddr))
                        goto fault;
-               if (!pte_present(*pte)) {
-                       pte = (pte_t *) 0x11;
-                       goto fault;
-               } else if (write_user && !pte_write(*pte)) {
-                       pte = (pte_t *) 0x04;
-                       goto fault;
-               }
 
-               pfn = pte_pfn(*pte);
-               offset = uaddr & (PAGE_SIZE - 1);
+               offset = uaddr & ~PAGE_MASK;
                size = min(n - done, PAGE_SIZE - offset);
                if (write_user) {
-                       to = (void *)((pfn << PAGE_SHIFT) + offset);
+                       to = (void *) kaddr;
                        from = kptr + done;
                } else {
-                       from = (void *)((pfn << PAGE_SHIFT) + offset);
+                       from = (void *) kaddr;
                        to = kptr + done;
                }
                memcpy(to, from, size);
@@ -75,7 +88,7 @@ retry:
        return n - done;
 fault:
        spin_unlock(&mm->page_table_lock);
-       if (__handle_fault(uaddr, (unsigned long) pte, write_user))
+       if (__handle_fault(uaddr, -kaddr, write_user))
                return n - done;
        goto retry;
 }
@@ -84,27 +97,22 @@ fault:
  * Do DAT for user address by page table walk, return kernel address.
  * This function needs to be called with current->mm->page_table_lock held.
  */
-static __always_inline unsigned long __dat_user_addr(unsigned long uaddr)
+static __always_inline unsigned long __dat_user_addr(unsigned long uaddr,
+                                                    int write)
 {
        struct mm_struct *mm = current->mm;
-       unsigned long pfn;
-       pte_t *pte;
+       unsigned long kaddr;
        int rc;
 
 retry:
-       pte = follow_table(mm, uaddr);
-       if ((unsigned long) pte < 0x1000)
-               goto fault;
-       if (!pte_present(*pte)) {
-               pte = (pte_t *) 0x11;
+       kaddr = follow_table(mm, uaddr, write);
+       if (IS_ERR_VALUE(kaddr))
                goto fault;
-       }
 
-       pfn = pte_pfn(*pte);
-       return (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1));
+       return kaddr;
 fault:
        spin_unlock(&mm->page_table_lock);
-       rc = __handle_fault(uaddr, (unsigned long) pte, 0);
+       rc = __handle_fault(uaddr, -kaddr, write);
        spin_lock(&mm->page_table_lock);
        if (!rc)
                goto retry;
@@ -159,11 +167,9 @@ static size_t clear_user_pt(size_t n, void __user *to)
 
 static size_t strnlen_user_pt(size_t count, const char __user *src)
 {
-       char *addr;
        unsigned long uaddr = (unsigned long) src;
        struct mm_struct *mm = current->mm;
-       unsigned long offset, pfn, done, len;
-       pte_t *pte;
+       unsigned long offset, done, len, kaddr;
        size_t len_str;
 
        if (segment_eq(get_fs(), KERNEL_DS))
@@ -172,19 +178,13 @@ static size_t strnlen_user_pt(size_t count, const char __user *src)
 retry:
        spin_lock(&mm->page_table_lock);
        do {
-               pte = follow_table(mm, uaddr);
-               if ((unsigned long) pte < 0x1000)
-                       goto fault;
-               if (!pte_present(*pte)) {
-                       pte = (pte_t *) 0x11;
+               kaddr = follow_table(mm, uaddr, 0);
+               if (IS_ERR_VALUE(kaddr))
                        goto fault;
-               }
 
-               pfn = pte_pfn(*pte);
-               offset = uaddr & (PAGE_SIZE-1);
-               addr = (char *)(pfn << PAGE_SHIFT) + offset;
+               offset = uaddr & ~PAGE_MASK;
                len = min(count - done, PAGE_SIZE - offset);
-               len_str = strnlen(addr, len);
+               len_str = strnlen((char *) kaddr, len);
                done += len_str;
                uaddr += len_str;
        } while ((len_str == len) && (done < count));
@@ -192,7 +192,7 @@ retry:
        return done + 1;
 fault:
        spin_unlock(&mm->page_table_lock);
-       if (__handle_fault(uaddr, (unsigned long) pte, 0))
+       if (__handle_fault(uaddr, -kaddr, 0))
                return 0;
        goto retry;
 }
@@ -225,11 +225,10 @@ static size_t copy_in_user_pt(size_t n, void __user *to,
                              const void __user *from)
 {
        struct mm_struct *mm = current->mm;
-       unsigned long offset_from, offset_to, offset_max, pfn_from, pfn_to,
-                     uaddr, done, size, error_code;
+       unsigned long offset_max, uaddr, done, size, error_code;
        unsigned long uaddr_from = (unsigned long) from;
        unsigned long uaddr_to = (unsigned long) to;
-       pte_t *pte_from, *pte_to;
+       unsigned long kaddr_to, kaddr_from;
        int write_user;
 
        if (segment_eq(get_fs(), KERNEL_DS)) {
@@ -242,38 +241,23 @@ retry:
        do {
                write_user = 0;
                uaddr = uaddr_from;
-               pte_from = follow_table(mm, uaddr_from);
-               error_code = (unsigned long) pte_from;
-               if (error_code < 0x1000)
-                       goto fault;
-               if (!pte_present(*pte_from)) {
-                       error_code = 0x11;
+               kaddr_from = follow_table(mm, uaddr_from, 0);
+               error_code = kaddr_from;
+               if (IS_ERR_VALUE(error_code))
                        goto fault;
-               }
 
                write_user = 1;
                uaddr = uaddr_to;
-               pte_to = follow_table(mm, uaddr_to);
-               error_code = (unsigned long) pte_to;
-               if (error_code < 0x1000)
-                       goto fault;
-               if (!pte_present(*pte_to)) {
-                       error_code = 0x11;
+               kaddr_to = follow_table(mm, uaddr_to, 1);
+               error_code = (unsigned long) kaddr_to;
+               if (IS_ERR_VALUE(error_code))
                        goto fault;
-               } else if (!pte_write(*pte_to)) {
-                       error_code = 0x04;
-                       goto fault;
-               }
 
-               pfn_from = pte_pfn(*pte_from);
-               pfn_to = pte_pfn(*pte_to);
-               offset_from = uaddr_from & (PAGE_SIZE-1);
-               offset_to = uaddr_from & (PAGE_SIZE-1);
-               offset_max = max(offset_from, offset_to);
+               offset_max = max(uaddr_from & ~PAGE_MASK,
+                                uaddr_to & ~PAGE_MASK);
                size = min(n - done, PAGE_SIZE - offset_max);
 
-               memcpy((void *)(pfn_to << PAGE_SHIFT) + offset_to,
-                      (void *)(pfn_from << PAGE_SHIFT) + offset_from, size);
+               memcpy((void *) kaddr_to, (void *) kaddr_from, size);
                done += size;
                uaddr_from += size;
                uaddr_to += size;
@@ -282,7 +266,7 @@ retry:
        return n - done;
 fault:
        spin_unlock(&mm->page_table_lock);
-       if (__handle_fault(uaddr, error_code, write_user))
+       if (__handle_fault(uaddr, -error_code, write_user))
                return n - done;
        goto retry;
 }
@@ -341,7 +325,7 @@ int futex_atomic_op_pt(int op, u32 __user *uaddr, int oparg, int *old)
                return __futex_atomic_op_pt(op, uaddr, oparg, old);
        spin_lock(&current->mm->page_table_lock);
        uaddr = (u32 __force __user *)
-               __dat_user_addr((__force unsigned long) uaddr);
+               __dat_user_addr((__force unsigned long) uaddr, 1);
        if (!uaddr) {
                spin_unlock(&current->mm->page_table_lock);
                return -EFAULT;
@@ -378,7 +362,7 @@ int futex_atomic_cmpxchg_pt(u32 *uval, u32 __user *uaddr,
                return __futex_atomic_cmpxchg_pt(uval, uaddr, oldval, newval);
        spin_lock(&current->mm->page_table_lock);
        uaddr = (u32 __force __user *)
-               __dat_user_addr((__force unsigned long) uaddr);
+               __dat_user_addr((__force unsigned long) uaddr, 1);
        if (!uaddr) {
                spin_unlock(&current->mm->page_table_lock);
                return -EFAULT;
index 15e0a16939765148efd633663c131390daaa9893..f1ddc0d2367947d850e863aa4d0a897705074574 100644 (file)
@@ -48,9 +48,7 @@ void *module_alloc(unsigned long size)
                return NULL;
 
        ret = module_map(size);
-       if (!ret)
-               ret = ERR_PTR(-ENOMEM);
-       else
+       if (ret)
                memset(ret, 0, size);
 
        return ret;
@@ -116,6 +114,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
                v = sym->st_value + rel[i].r_addend;
 
                switch (ELF_R_TYPE(rel[i].r_info) & 0xff) {
+               case R_SPARC_DISP32:
+                       v -= (Elf_Addr) location;
+                       *loc32 = v;
+                       break;
 #ifdef CONFIG_SPARC64
                case R_SPARC_64:
                        location[0] = v >> 56;
@@ -128,11 +130,6 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
                        location[7] = v >>  0;
                        break;
 
-               case R_SPARC_DISP32:
-                       v -= (Elf_Addr) location;
-                       *loc32 = v;
-                       break;
-
                case R_SPARC_WDISP19:
                        v -= (Elf_Addr) location;
                        *loc32 = (*loc32 & ~0x7ffff) |
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 8ec3a1aa4abd3f612df4a5da31f30c67554d5182..50a1d1f9b6d3ac28c6b2294cd579d71cda2e75c1 100644 (file)
@@ -746,10 +746,10 @@ config SWIOTLB
        def_bool y if X86_64
        ---help---
          Support for software bounce buffers used on x86-64 systems
-         which don't have a hardware IOMMU (e.g. the current generation
-         of Intel's x86-64 CPUs). Using this PCI devices which can only
-         access 32-bits of memory can be used on systems with more than
-         3 GB of memory. If unsure, say Y.
+         which don't have a hardware IOMMU. Using this PCI devices
+         which can only access 32-bits of memory can be used on systems
+         with more than 3 GB of memory.
+         If unsure, say Y.
 
 config IOMMU_HELPER
        def_bool (CALGARY_IOMMU || GART_IOMMU || SWIOTLB || AMD_IOMMU)
index 682e9c210baacb99b86817adbd45ebbd17a30955..474ca35b1bce342356b27ac4118f133135d8c249 100644 (file)
@@ -142,7 +142,7 @@ KBUILD_CFLAGS += $(call cc-option,-mno-avx,)
 KBUILD_CFLAGS += $(mflags-y)
 KBUILD_AFLAGS += $(mflags-y)
 
-archscripts:
+archscripts: scripts_basic
        $(Q)$(MAKE) $(build)=arch/x86/tools relocs
 
 ###
index 93971e841dd5e7eaa032f5f4a8d5542040900a6d..472b9b783019a2e2f7c7b273ab7b13b96ec257b9 100644 (file)
@@ -51,7 +51,8 @@ extern unsigned long set_phys_range_identity(unsigned long pfn_s,
 
 extern int m2p_add_override(unsigned long mfn, struct page *page,
                            struct gnttab_map_grant_ref *kmap_op);
-extern int m2p_remove_override(struct page *page, bool clear_pte);
+extern int m2p_remove_override(struct page *page,
+                               struct gnttab_map_grant_ref *kmap_op);
 extern struct page *m2p_find_override(unsigned long mfn);
 extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);
 
index 6605a81ba3399fb8c1c9044b0e7aa8c2e22ff882..8b6defe7eefc5e6de1538984622f109c4223528d 100644 (file)
@@ -586,6 +586,8 @@ extern struct event_constraint intel_westmere_pebs_event_constraints[];
 
 extern struct event_constraint intel_snb_pebs_event_constraints[];
 
+extern struct event_constraint intel_ivb_pebs_event_constraints[];
+
 struct event_constraint *intel_pebs_constraints(struct perf_event *event);
 
 void intel_pmu_pebs_enable(struct perf_event *event);
index 7bfb5bec8630ada6580dd446e8a62de847d12288..eebd5ffe1bba0b922f9ef8481fd141f2ba9668da 100644 (file)
@@ -209,6 +209,15 @@ static int perf_ibs_precise_event(struct perf_event *event, u64 *config)
        return -EOPNOTSUPP;
 }
 
+static const struct perf_event_attr ibs_notsupp = {
+       .exclude_user   = 1,
+       .exclude_kernel = 1,
+       .exclude_hv     = 1,
+       .exclude_idle   = 1,
+       .exclude_host   = 1,
+       .exclude_guest  = 1,
+};
+
 static int perf_ibs_init(struct perf_event *event)
 {
        struct hw_perf_event *hwc = &event->hw;
@@ -229,6 +238,9 @@ static int perf_ibs_init(struct perf_event *event)
        if (event->pmu != &perf_ibs->pmu)
                return -ENOENT;
 
+       if (perf_flags(&event->attr) & perf_flags(&ibs_notsupp))
+               return -EINVAL;
+
        if (config & ~perf_ibs->config_mask)
                return -EINVAL;
 
index 0d3d63afa76abd304cb7809461152ce97e3f0828..6bca492b85475bc8eab5577447ce1fa9a5133223 100644 (file)
@@ -2048,7 +2048,6 @@ __init int intel_pmu_init(void)
        case 42: /* SandyBridge */
        case 45: /* SandyBridge, "Romely-EP" */
                x86_add_quirk(intel_sandybridge_quirk);
-       case 58: /* IvyBridge */
                memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
                       sizeof(hw_cache_event_ids));
                memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
@@ -2073,6 +2072,29 @@ __init int intel_pmu_init(void)
 
                pr_cont("SandyBridge events, ");
                break;
+       case 58: /* IvyBridge */
+               memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
+                      sizeof(hw_cache_event_ids));
+               memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
+                      sizeof(hw_cache_extra_regs));
+
+               intel_pmu_lbr_init_snb();
+
+               x86_pmu.event_constraints = intel_snb_event_constraints;
+               x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints;
+               x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
+               x86_pmu.extra_regs = intel_snb_extra_regs;
+               /* all extra regs are per-cpu when HT is on */
+               x86_pmu.er_flags |= ERF_HAS_RSP_1;
+               x86_pmu.er_flags |= ERF_NO_HT_SHARING;
+
+               /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
+               intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] =
+                       X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1);
+
+               pr_cont("IvyBridge events, ");
+               break;
+
 
        default:
                switch (x86_pmu.version) {
index e38d97bf4259fc579f2b070fef85980ae7aaab7a..826054a4f2ee4c54ea4cfb9d29ab117db35e7fc5 100644 (file)
@@ -407,6 +407,20 @@ struct event_constraint intel_snb_pebs_event_constraints[] = {
        EVENT_CONSTRAINT_END
 };
 
+struct event_constraint intel_ivb_pebs_event_constraints[] = {
+        INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
+        INTEL_UEVENT_CONSTRAINT(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
+        INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */
+        INTEL_EVENT_CONSTRAINT(0xc4, 0xf),    /* BR_INST_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xc5, 0xf),    /* BR_MISP_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xcd, 0x8),    /* MEM_TRANS_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xd0, 0xf),    /* MEM_UOP_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xd1, 0xf),    /* MEM_LOAD_UOPS_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xd2, 0xf),    /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
+        INTEL_EVENT_CONSTRAINT(0xd3, 0xf),    /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */
+        EVENT_CONSTRAINT_END
+};
+
 struct event_constraint *intel_pebs_constraints(struct perf_event *event)
 {
        struct event_constraint *c;
index 0a5571080e7453bc9d602061ffbe2c6ad81647a2..38e4894165b9cdc096e038de65fc4ee04bdb0690 100644 (file)
@@ -661,6 +661,11 @@ static void snb_uncore_msr_init_box(struct intel_uncore_box *box)
        }
 }
 
+static struct uncore_event_desc snb_uncore_events[] = {
+       INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
+       { /* end: all zeroes */ },
+};
+
 static struct attribute *snb_uncore_formats_attr[] = {
        &format_attr_event.attr,
        &format_attr_umask.attr,
@@ -704,6 +709,7 @@ static struct intel_uncore_type snb_uncore_cbox = {
        .constraints    = snb_uncore_cbox_constraints,
        .ops            = &snb_uncore_msr_ops,
        .format_group   = &snb_uncore_format_group,
+       .event_descs    = snb_uncore_events,
 };
 
 static struct intel_uncore_type *snb_msr_uncores[] = {
index e0e6990723e982e12f425f2fdd26113725f2d52a..ab1f6a93b527c9bd50acc12a52e9ce157f2cc48b 100644 (file)
@@ -319,7 +319,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
  */
 int devmem_is_allowed(unsigned long pagenr)
 {
-       if (pagenr <= 256)
+       if (pagenr < 256)
                return 1;
        if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
                return 0;
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 9642d4a3860239f3203a2ff12dba5543a26ccf4f..1fbe75a95f15953d3d0ed6cd0dd7c911a88eac0b 100644 (file)
@@ -1452,6 +1452,10 @@ asmlinkage void __init xen_start_kernel(void)
                pci_request_acs();
 
                xen_acpi_sleep_register();
+
+               /* Avoid searching for BIOS MP tables */
+               x86_init.mpparse.find_smp_config = x86_init_noop;
+               x86_init.mpparse.get_smp_config = x86_init_uint_noop;
        }
 #ifdef CONFIG_PCI
        /* PCI BIOS service won't work from a PV guest. */
index 76ba0e97e530131199e40aec0730554ae7b7825c..72213da605f50c07f3684ca07d351a8bbd7435ef 100644 (file)
@@ -828,9 +828,6 @@ int m2p_add_override(unsigned long mfn, struct page *page,
 
                        xen_mc_issue(PARAVIRT_LAZY_MMU);
                }
-               /* let's use dev_bus_addr to record the old mfn instead */
-               kmap_op->dev_bus_addr = page->index;
-               page->index = (unsigned long) kmap_op;
        }
        spin_lock_irqsave(&m2p_override_lock, flags);
        list_add(&page->lru,  &m2p_overrides[mfn_hash(mfn)]);
@@ -857,7 +854,8 @@ int m2p_add_override(unsigned long mfn, struct page *page,
        return 0;
 }
 EXPORT_SYMBOL_GPL(m2p_add_override);
-int m2p_remove_override(struct page *page, bool clear_pte)
+int m2p_remove_override(struct page *page,
+               struct gnttab_map_grant_ref *kmap_op)
 {
        unsigned long flags;
        unsigned long mfn;
@@ -887,10 +885,8 @@ int m2p_remove_override(struct page *page, bool clear_pte)
        WARN_ON(!PagePrivate(page));
        ClearPagePrivate(page);
 
-       if (clear_pte) {
-               struct gnttab_map_grant_ref *map_op =
-                       (struct gnttab_map_grant_ref *) page->index;
-               set_phys_to_machine(pfn, map_op->dev_bus_addr);
+       set_phys_to_machine(pfn, page->index);
+       if (kmap_op != NULL) {
                if (!PageHighMem(page)) {
                        struct multicall_space mcs;
                        struct gnttab_unmap_grant_ref *unmap_op;
@@ -902,13 +898,13 @@ int m2p_remove_override(struct page *page, bool clear_pte)
                         * issued. In this case handle is going to -1 because
                         * it hasn't been modified yet.
                         */
-                       if (map_op->handle == -1)
+                       if (kmap_op->handle == -1)
                                xen_mc_flush();
                        /*
-                        * Now if map_op->handle is negative it means that the
+                        * Now if kmap_op->handle is negative it means that the
                         * hypercall actually returned an error.
                         */
-                       if (map_op->handle == GNTST_general_error) {
+                       if (kmap_op->handle == GNTST_general_error) {
                                printk(KERN_WARNING "m2p_remove_override: "
                                                "pfn %lx mfn %lx, failed to modify kernel mappings",
                                                pfn, mfn);
@@ -918,8 +914,8 @@ int m2p_remove_override(struct page *page, bool clear_pte)
                        mcs = xen_mc_entry(
                                        sizeof(struct gnttab_unmap_grant_ref));
                        unmap_op = mcs.args;
-                       unmap_op->host_addr = map_op->host_addr;
-                       unmap_op->handle = map_op->handle;
+                       unmap_op->host_addr = kmap_op->host_addr;
+                       unmap_op->handle = kmap_op->handle;
                        unmap_op->dev_bus_addr = 0;
 
                        MULTI_grant_table_op(mcs.mc,
@@ -930,10 +926,9 @@ int m2p_remove_override(struct page *page, bool clear_pte)
                        set_pte_at(&init_mm, address, ptep,
                                        pfn_pte(pfn, PAGE_KERNEL));
                        __flush_tlb_single(address);
-                       map_op->host_addr = 0;
+                       kmap_op->host_addr = 0;
                }
-       } else
-               set_phys_to_machine(pfn, page->index);
+       }
 
        /* p2m(m2p(mfn)) == FOREIGN_FRAME(mfn): the mfn is already present
         * somewhere in this domain, even before being added to the
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 e0596954290b8e33e20791effc0227b80fb4a0c9..d59175efc428e58c8602b3c91730bf5cb99764d6 100644 (file)
@@ -994,14 +994,18 @@ static int __init acpi_bus_init(void)
        status = acpi_ec_ecdt_probe();
        /* Ignore result. Not having an ECDT is not fatal. */
 
-       acpi_bus_osc_support();
-
        status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
        if (ACPI_FAILURE(status)) {
                printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n");
                goto error1;
        }
 
+       /*
+        * _OSC method may exist in module level code,
+        * so it must be run after ACPI_FULL_INITIALIZATION
+        */
+       acpi_bus_osc_support();
+
        /*
         * _PDC control method may load dynamic SSDT tables,
         * and we need to install the table handler before that.
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 d1ecca2b641a97f541dfdb18f1358738025f3ba7..1fcb8678665c0e89113da39e0f603db2d49eeccb 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/signal.h>
 #include <linux/kthread.h>
 #include <linux/dmi.h>
+#include <linux/nls.h>
 
 #include <acpi/acpi_drivers.h>
 
@@ -232,8 +233,35 @@ end:
 }
 static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
 
+/* sysfs file that shows description text from the ACPI _STR method */
+static ssize_t description_show(struct device *dev,
+                               struct device_attribute *attr,
+                               char *buf) {
+       struct acpi_device *acpi_dev = to_acpi_device(dev);
+       int result;
+
+       if (acpi_dev->pnp.str_obj == NULL)
+               return 0;
+
+       /*
+        * The _STR object contains a Unicode identifier for a device.
+        * We need to convert to utf-8 so it can be displayed.
+        */
+       result = utf16s_to_utf8s(
+               (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer,
+               acpi_dev->pnp.str_obj->buffer.length,
+               UTF16_LITTLE_ENDIAN, buf,
+               PAGE_SIZE);
+
+       buf[result++] = '\n';
+
+       return result;
+}
+static DEVICE_ATTR(description, 0444, description_show, NULL);
+
 static int acpi_device_setup_files(struct acpi_device *dev)
 {
+       struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
        acpi_status status;
        acpi_handle temp;
        int result = 0;
@@ -257,6 +285,21 @@ static int acpi_device_setup_files(struct acpi_device *dev)
                        goto end;
        }
 
+       /*
+        * If device has _STR, 'description' file is created
+        */
+       status = acpi_get_handle(dev->handle, "_STR", &temp);
+       if (ACPI_SUCCESS(status)) {
+               status = acpi_evaluate_object(dev->handle, "_STR",
+                                       NULL, &buffer);
+               if (ACPI_FAILURE(status))
+                       buffer.pointer = NULL;
+               dev->pnp.str_obj = buffer.pointer;
+               result = device_create_file(&dev->dev, &dev_attr_description);
+               if (result)
+                       goto end;
+       }
+
         /*
          * If device has _EJ0, 'eject' file is created that is used to trigger
          * hot-removal function from userland.
@@ -274,8 +317,15 @@ static void acpi_device_remove_files(struct acpi_device *dev)
        acpi_handle temp;
 
        /*
-        * If device has _EJ0, 'eject' file is created that is used to trigger
-        * hot-removal function from userland.
+        * If device has _STR, remove 'description' file
+        */
+       status = acpi_get_handle(dev->handle, "_STR", &temp);
+       if (ACPI_SUCCESS(status)) {
+               kfree(dev->pnp.str_obj);
+               device_remove_file(&dev->dev, &dev_attr_description);
+       }
+       /*
+        * If device has _EJ0, remove 'eject' file.
         */
        status = acpi_get_handle(dev->handle, "_EJ0", &temp);
        if (ACPI_SUCCESS(status))
@@ -481,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 f336bca7c4503ec1d03d7741ee8185afae942381..2572d9715bda3b14ff3f43cb0efaf3122d26b26d 100644 (file)
@@ -240,10 +240,17 @@ acpi_table_parse_entries(char *id,
               table_end) {
                if (entry->type == entry_id
                    && (!max_entries || count++ < max_entries))
-                       if (handler(entry, table_end)) {
-                               early_acpi_os_unmap_memory((char *)table_header, tbl_size);
-                               return -EINVAL;
-                       }
+                       if (handler(entry, table_end))
+                               goto err;
+
+               /*
+                * If entry->length is 0, break from this loop to avoid
+                * infinite loop.
+                */
+               if (entry->length == 0) {
+                       pr_err(PREFIX "[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
+                       goto err;
+               }
 
                entry = (struct acpi_subtable_header *)
                    ((unsigned long)entry + entry->length);
@@ -255,6 +262,9 @@ acpi_table_parse_entries(char *id,
 
        early_acpi_os_unmap_memory((char *)table_header, tbl_size);
        return count;
+err:
+       early_acpi_os_unmap_memory((char *)table_header, tbl_size);
+       return -EINVAL;
 }
 
 int __init
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 de0435e63b02cbd349c5dcc282682359f6f85934..887f68f6d79a9e615beba7525cb9d0e671917c4e 100644 (file)
@@ -35,6 +35,7 @@ new_skb(ulong len)
                skb_reset_mac_header(skb);
                skb_reset_network_header(skb);
                skb->protocol = __constant_htons(ETH_P_AOE);
+               skb_checksum_none_assert(skb);
        }
        return skb;
 }
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 73f196ca713f20e037e22adccba64d0e00c936b1..c6decb901e5e16f4ba09ccef7db33675aeecb189 100644 (file)
@@ -337,7 +337,7 @@ static void xen_blkbk_unmap(struct pending_req *req)
                invcount++;
        }
 
-       ret = gnttab_unmap_refs(unmap, pages, invcount, false);
+       ret = gnttab_unmap_refs(unmap, NULL, pages, invcount);
        BUG_ON(ret);
 }
 
index 5869ea3870545f0f7c3ab64a185e1c486243b4e1..72ce247a0e8d5c08395fe92c9163a8c376c555bc 100644 (file)
@@ -1,4 +1,5 @@
 # common clock types
+obj-$(CONFIG_HAVE_CLK)         += clk-devres.o
 obj-$(CONFIG_CLKDEV_LOOKUP)    += clkdev.o
 obj-$(CONFIG_COMMON_CLK)       += clk.o clk-fixed-rate.o clk-gate.o \
                                   clk-mux.o clk-divider.o clk-fixed-factor.o
diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c
new file mode 100644 (file)
index 0000000..8f57154
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/gfp.h>
+
+static void devm_clk_release(struct device *dev, void *res)
+{
+       clk_put(*(struct clk **)res);
+}
+
+struct clk *devm_clk_get(struct device *dev, const char *id)
+{
+       struct clk **ptr, *clk;
+
+       ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
+       if (!ptr)
+               return ERR_PTR(-ENOMEM);
+
+       clk = clk_get(dev, id);
+       if (!IS_ERR(clk)) {
+               *ptr = clk;
+               devres_add(dev, ptr);
+       } else {
+               devres_free(ptr);
+       }
+
+       return clk;
+}
+EXPORT_SYMBOL(devm_clk_get);
+
+static int devm_clk_match(struct device *dev, void *res, void *data)
+{
+       struct clk **c = res;
+       if (!c || !*c) {
+               WARN_ON(!c || !*c);
+               return 0;
+       }
+       return *c == data;
+}
+
+void devm_clk_put(struct device *dev, struct clk *clk)
+{
+       int ret;
+
+       ret = devres_release(dev, devm_clk_release, devm_clk_match, clk);
+
+       WARN_ON(ret);
+}
+EXPORT_SYMBOL(devm_clk_put);
index d423c9bdd71a9d4670c340c94f7f1eb08152ed41..442a31363873d35f319e0d5ee5b6b250084c02fc 100644 (file)
@@ -171,51 +171,6 @@ void clk_put(struct clk *clk)
 }
 EXPORT_SYMBOL(clk_put);
 
-static void devm_clk_release(struct device *dev, void *res)
-{
-       clk_put(*(struct clk **)res);
-}
-
-struct clk *devm_clk_get(struct device *dev, const char *id)
-{
-       struct clk **ptr, *clk;
-
-       ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
-       if (!ptr)
-               return ERR_PTR(-ENOMEM);
-
-       clk = clk_get(dev, id);
-       if (!IS_ERR(clk)) {
-               *ptr = clk;
-               devres_add(dev, ptr);
-       } else {
-               devres_free(ptr);
-       }
-
-       return clk;
-}
-EXPORT_SYMBOL(devm_clk_get);
-
-static int devm_clk_match(struct device *dev, void *res, void *data)
-{
-       struct clk **c = res;
-       if (!c || !*c) {
-               WARN_ON(!c || !*c);
-               return 0;
-       }
-       return *c == data;
-}
-
-void devm_clk_put(struct device *dev, struct clk *clk)
-{
-       int ret;
-
-       ret = devres_destroy(dev, devm_clk_release, devm_clk_match, clk);
-
-       WARN_ON(ret);
-}
-EXPORT_SYMBOL(devm_clk_put);
-
 void clkdev_add(struct clk_lookup *cl)
 {
        mutex_lock(&clocks_mutex);
index 3934fcc4e00b1b02778bb02866fb86073f9b1f0a..7ab6e26664a77a1ab2b375148488d1209e2e21ba 100644 (file)
@@ -661,7 +661,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
                        flags);
 
        if (unlikely(!atslave || !sg_len)) {
-               dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n");
+               dev_dbg(chan2dev(chan), "prep_slave_sg: sg length is zero!\n");
                return NULL;
        }
 
@@ -689,6 +689,11 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 
                        mem = sg_dma_address(sg);
                        len = sg_dma_len(sg);
+                       if (unlikely(!len)) {
+                               dev_dbg(chan2dev(chan),
+                                       "prep_slave_sg: sg(%d) data length is zero\n", i);
+                               goto err;
+                       }
                        mem_width = 2;
                        if (unlikely(mem & 3 || len & 3))
                                mem_width = 0;
@@ -724,6 +729,11 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 
                        mem = sg_dma_address(sg);
                        len = sg_dma_len(sg);
+                       if (unlikely(!len)) {
+                               dev_dbg(chan2dev(chan),
+                                       "prep_slave_sg: sg(%d) data length is zero\n", i);
+                               goto err;
+                       }
                        mem_width = 2;
                        if (unlikely(mem & 3 || len & 3))
                                mem_width = 0;
@@ -757,6 +767,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
 
 err_desc_get:
        dev_err(chan2dev(chan), "not enough descriptors available\n");
+err:
        atc_desc_put(atchan, first);
        return NULL;
 }
index e4feba6b03c00e6f2ae412a9a1104eef21fb94f4..f5843bc80baa9b8168f6034ad167ce46a0d537bb 100644 (file)
@@ -1567,17 +1567,19 @@ static int pl330_submit_req(void *ch_id, struct pl330_req *r)
                goto xfer_exit;
        }
 
-       /* Prefer Secure Channel */
-       if (!_manager_ns(thrd))
-               r->cfg->nonsecure = 0;
-       else
-               r->cfg->nonsecure = 1;
 
        /* Use last settings, if not provided */
-       if (r->cfg)
+       if (r->cfg) {
+               /* Prefer Secure Channel */
+               if (!_manager_ns(thrd))
+                       r->cfg->nonsecure = 0;
+               else
+                       r->cfg->nonsecure = 1;
+
                ccr = _prepare_ccr(r->cfg);
-       else
+       } else {
                ccr = readl(regs + CC(thrd->id));
+       }
 
        /* If this req doesn't have valid xfer settings */
        if (!_is_valid(ccr)) {
@@ -2928,6 +2930,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
                num_chan = max_t(int, pi->pcfg.num_peri, pi->pcfg.num_chan);
 
        pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);
+       if (!pdmac->peripherals) {
+               ret = -ENOMEM;
+               dev_err(&adev->dev, "unable to allocate pdmac->peripherals\n");
+               goto probe_err5;
+       }
 
        for (i = 0; i < num_chan; i++) {
                pch = &pdmac->peripherals[i];
index 616d90bcb3a4106929523c4a98fe32fb27f6a9a6..d5dc9da7f99f95fc9dd3a6edb5d4bc302e69c2c3 100644 (file)
@@ -199,6 +199,36 @@ void *edac_align_ptr(void **p, unsigned size, int n_elems)
        return (void *)(((unsigned long)ptr) + align - r);
 }
 
+static void _edac_mc_free(struct mem_ctl_info *mci)
+{
+       int i, chn, row;
+       struct csrow_info *csr;
+       const unsigned int tot_dimms = mci->tot_dimms;
+       const unsigned int tot_channels = mci->num_cschannel;
+       const unsigned int tot_csrows = mci->nr_csrows;
+
+       if (mci->dimms) {
+               for (i = 0; i < tot_dimms; i++)
+                       kfree(mci->dimms[i]);
+               kfree(mci->dimms);
+       }
+       if (mci->csrows) {
+               for (row = 0; row < tot_csrows; row++) {
+                       csr = mci->csrows[row];
+                       if (csr) {
+                               if (csr->channels) {
+                                       for (chn = 0; chn < tot_channels; chn++)
+                                               kfree(csr->channels[chn]);
+                                       kfree(csr->channels);
+                               }
+                               kfree(csr);
+                       }
+               }
+               kfree(mci->csrows);
+       }
+       kfree(mci);
+}
+
 /**
  * edac_mc_alloc: Allocate and partially fill a struct mem_ctl_info structure
  * @mc_num:            Memory controller number
@@ -413,24 +443,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
        return mci;
 
 error:
-       if (mci->dimms) {
-               for (i = 0; i < tot_dimms; i++)
-                       kfree(mci->dimms[i]);
-               kfree(mci->dimms);
-       }
-       if (mci->csrows) {
-               for (chn = 0; chn < tot_channels; chn++) {
-                       csr = mci->csrows[chn];
-                       if (csr) {
-                               for (chn = 0; chn < tot_channels; chn++)
-                                       kfree(csr->channels[chn]);
-                               kfree(csr);
-                       }
-                       kfree(mci->csrows[i]);
-               }
-               kfree(mci->csrows);
-       }
-       kfree(mci);
+       _edac_mc_free(mci);
 
        return NULL;
 }
@@ -445,6 +458,14 @@ void edac_mc_free(struct mem_ctl_info *mci)
 {
        edac_dbg(1, "\n");
 
+       /* If we're not yet registered with sysfs free only what was allocated
+        * in edac_mc_alloc().
+        */
+       if (!device_is_registered(&mci->dev)) {
+               _edac_mc_free(mci);
+               return;
+       }
+
        /* the mci instance is freed here, when the sysfs object is dropped */
        edac_unregister_sysfs(mci);
 }
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 489e2b162b2736b4fc3d43e171ebddb25c66b12e..274d25de521e78c577d5a62456fc812024bbae79 100644 (file)
@@ -3242,7 +3242,8 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
 {
        int ret;
 
-       BUG_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT);
+       if (WARN_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
+               return -EBUSY;
 
        if (obj->gtt_space != NULL) {
                if ((alignment && obj->gtt_offset & (alignment - 1)) ||
index bc2ad348e5d8ce9e13c51b1c6dba019e0e2acc4e..c040aee1341cf2065f1ea91eb1b54fbdf54d96b8 100644 (file)
@@ -4191,12 +4191,6 @@ static void i8xx_update_pll(struct drm_crtc *crtc,
        POSTING_READ(DPLL(pipe));
        udelay(150);
 
-       I915_WRITE(DPLL(pipe), dpll);
-
-       /* Wait for the clocks to stabilize. */
-       POSTING_READ(DPLL(pipe));
-       udelay(150);
-
        /* The LVDS pin pair needs to be on before the DPLLs are enabled.
         * This is an exception to the general rule that mode_set doesn't turn
         * things on.
@@ -4204,6 +4198,12 @@ static void i8xx_update_pll(struct drm_crtc *crtc,
        if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
                intel_update_lvds(crtc, clock, adjusted_mode);
 
+       I915_WRITE(DPLL(pipe), dpll);
+
+       /* Wait for the clocks to stabilize. */
+       POSTING_READ(DPLL(pipe));
+       udelay(150);
+
        /* The pixel multiplier can only be updated once the
         * DPLL is enabled and the clocks are stable.
         *
index 98f602427eb8cb8fe9a8cc975ff1b4128ce68ae6..12dc3308ab8c982f063a4b5b0e7dcc8dd2b3519b 100644 (file)
@@ -609,7 +609,7 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
        u32 temp;
        u32 enable_bits = SDVO_ENABLE;
 
-       if (intel_hdmi->has_audio)
+       if (intel_hdmi->has_audio || mode != DRM_MODE_DPMS_ON)
                enable_bits |= SDVO_AUDIO_ENABLE;
 
        temp = I915_READ(intel_hdmi->sdvox_reg);
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 f03490534893e4772a75b4b4731b69be6286f744..c399d510b27a8611aa4524b3cffa582f9f033da7 100644 (file)
@@ -22,6 +22,7 @@
  * Authors: Ben Skeggs
  */
 
+#include <linux/dmi.h>
 #include "drmP.h"
 #include "nouveau_drv.h"
 #include "nouveau_hw.h"
@@ -110,13 +111,25 @@ nv50_gpio_isr(struct drm_device *dev)
                nv_wr32(dev, 0xe074, intr1);
 }
 
+static struct dmi_system_id gpio_reset_ids[] = {
+       {
+               .ident = "Apple Macbook 10,1",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro10,1"),
+               }
+       },
+       { }
+};
+
 int
 nv50_gpio_init(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
 
        /* initialise gpios and routing to vbios defaults */
-       nouveau_gpio_reset(dev);
+       if (dmi_check_system(gpio_reset_ids))
+               nouveau_gpio_reset(dev);
 
        /* disable, and ack any pending gpio interrupts */
        nv_wr32(dev, 0xe050, 0x00000000);
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 e721e3087b99d88556c39701605faf37e99fbc8b..2817101fb167eb1f70ac36d88e2f4f1c58dd2427 100644 (file)
@@ -1479,98 +1479,14 @@ static void radeon_legacy_atom_fixup(struct drm_crtc *crtc)
        }
 }
 
-/**
- * radeon_get_pll_use_mask - look up a mask of which pplls are in use
- *
- * @crtc: drm crtc
- *
- * Returns the mask of which PPLLs (Pixel PLLs) are in use.
- */
-static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc)
-{
-       struct drm_device *dev = crtc->dev;
-       struct drm_crtc *test_crtc;
-       struct radeon_crtc *radeon_test_crtc;
-       u32 pll_in_use = 0;
-
-       list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
-               if (crtc == test_crtc)
-                       continue;
-
-               radeon_test_crtc = to_radeon_crtc(test_crtc);
-               if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
-                       pll_in_use |= (1 << radeon_test_crtc->pll_id);
-       }
-       return pll_in_use;
-}
-
-/**
- * radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP
- *
- * @crtc: drm crtc
- *
- * Returns the PPLL (Pixel PLL) used by another crtc/encoder which is
- * also in DP mode.  For DP, a single PPLL can be used for all DP
- * crtcs/encoders.
- */
-static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc)
-{
-       struct drm_device *dev = crtc->dev;
-       struct drm_encoder *test_encoder;
-       struct radeon_crtc *radeon_test_crtc;
-
-       list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
-               if (test_encoder->crtc && (test_encoder->crtc != crtc)) {
-                       if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
-                               /* for DP use the same PLL for all */
-                               radeon_test_crtc = to_radeon_crtc(test_encoder->crtc);
-                               if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID)
-                                       return radeon_test_crtc->pll_id;
-                       }
-               }
-       }
-       return ATOM_PPLL_INVALID;
-}
-
-/**
- * radeon_atom_pick_pll - Allocate a PPLL for use by the crtc.
- *
- * @crtc: drm crtc
- *
- * Returns the PPLL (Pixel PLL) to be used by the crtc.  For DP monitors
- * a single PPLL can be used for all DP crtcs/encoders.  For non-DP
- * monitors a dedicated PPLL must be used.  If a particular board has
- * an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming
- * as there is no need to program the PLL itself.  If we are not able to
- * allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to
- * avoid messing up an existing monitor.
- *
- * Asic specific PLL information
- *
- * DCE 6.1
- * - PPLL2 is only available to UNIPHYA (both DP and non-DP)
- * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP)
- *
- * DCE 6.0
- * - PPLL0 is available to all UNIPHY (DP only)
- * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
- *
- * DCE 5.0
- * - DCPLL is available to all UNIPHY (DP only)
- * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
- *
- * DCE 3.0/4.0/4.1
- * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
- *
- */
 static int radeon_atom_pick_pll(struct drm_crtc *crtc)
 {
        struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
        struct drm_device *dev = crtc->dev;
        struct radeon_device *rdev = dev->dev_private;
        struct drm_encoder *test_encoder;
-       u32 pll_in_use;
-       int pll;
+       struct drm_crtc *test_crtc;
+       uint32_t pll_in_use = 0;
 
        if (ASIC_IS_DCE61(rdev)) {
                list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
@@ -1582,40 +1498,32 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
 
                                if ((test_radeon_encoder->encoder_id ==
                                     ENCODER_OBJECT_ID_INTERNAL_UNIPHY) &&
-                                   (dig->linkb == false))
-                                       /* UNIPHY A uses PPLL2 */
+                                   (dig->linkb == false)) /* UNIPHY A uses PPLL2 */
                                        return ATOM_PPLL2;
-                               else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
-                                       /* UNIPHY B/C/D/E/F */
-                                       if (rdev->clock.dp_extclk)
-                                               /* skip PPLL programming if using ext clock */
-                                               return ATOM_PPLL_INVALID;
-                                       else {
-                                               /* use the same PPLL for all DP monitors */
-                                               pll = radeon_get_shared_dp_ppll(crtc);
-                                               if (pll != ATOM_PPLL_INVALID)
-                                                       return pll;
-                                       }
-                               }
-                               break;
                        }
                }
                /* UNIPHY B/C/D/E/F */
-               pll_in_use = radeon_get_pll_use_mask(crtc);
-               if (!(pll_in_use & (1 << ATOM_PPLL0)))
+               list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
+                       struct radeon_crtc *radeon_test_crtc;
+
+                       if (crtc == test_crtc)
+                               continue;
+
+                       radeon_test_crtc = to_radeon_crtc(test_crtc);
+                       if ((radeon_test_crtc->pll_id == ATOM_PPLL0) ||
+                           (radeon_test_crtc->pll_id == ATOM_PPLL1))
+                               pll_in_use |= (1 << radeon_test_crtc->pll_id);
+               }
+               if (!(pll_in_use & 4))
                        return ATOM_PPLL0;
-               if (!(pll_in_use & (1 << ATOM_PPLL1)))
-                       return ATOM_PPLL1;
-               DRM_ERROR("unable to allocate a PPLL\n");
-               return ATOM_PPLL_INVALID;
+               return ATOM_PPLL1;
        } else if (ASIC_IS_DCE4(rdev)) {
                list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) {
                        if (test_encoder->crtc && (test_encoder->crtc == crtc)) {
                                /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
                                 * depending on the asic:
                                 * DCE4: PPLL or ext clock
-                                * DCE5: PPLL, DCPLL, or ext clock
-                                * DCE6: PPLL, PPLL0, or ext clock
+                                * DCE5: DCPLL or ext clock
                                 *
                                 * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip
                                 * PPLL/DCPLL programming and only program the DP DTO for the
@@ -1623,34 +1531,31 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
                                 */
                                if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) {
                                        if (rdev->clock.dp_extclk)
-                                               /* skip PPLL programming if using ext clock */
                                                return ATOM_PPLL_INVALID;
                                        else if (ASIC_IS_DCE6(rdev))
-                                               /* use PPLL0 for all DP */
                                                return ATOM_PPLL0;
                                        else if (ASIC_IS_DCE5(rdev))
-                                               /* use DCPLL for all DP */
                                                return ATOM_DCPLL;
-                                       else {
-                                               /* use the same PPLL for all DP monitors */
-                                               pll = radeon_get_shared_dp_ppll(crtc);
-                                               if (pll != ATOM_PPLL_INVALID)
-                                                       return pll;
-                                       }
                                }
-                               break;
                        }
                }
-               /* all other cases */
-               pll_in_use = radeon_get_pll_use_mask(crtc);
-               if (!(pll_in_use & (1 << ATOM_PPLL2)))
-                       return ATOM_PPLL2;
-               if (!(pll_in_use & (1 << ATOM_PPLL1)))
+
+               /* otherwise, pick one of the plls */
+               list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) {
+                       struct radeon_crtc *radeon_test_crtc;
+
+                       if (crtc == test_crtc)
+                               continue;
+
+                       radeon_test_crtc = to_radeon_crtc(test_crtc);
+                       if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) &&
+                           (radeon_test_crtc->pll_id <= ATOM_PPLL2))
+                               pll_in_use |= (1 << radeon_test_crtc->pll_id);
+               }
+               if (!(pll_in_use & 1))
                        return ATOM_PPLL1;
-               DRM_ERROR("unable to allocate a PPLL\n");
-               return ATOM_PPLL_INVALID;
+               return ATOM_PPLL2;
        } else
-               /* use PPLL1 or PPLL2 */
                return radeon_crtc->crtc_id;
 
 }
@@ -1792,7 +1697,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
                break;
        }
 done:
-       radeon_crtc->pll_id = ATOM_PPLL_INVALID;
+       radeon_crtc->pll_id = -1;
 }
 
 static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
@@ -1841,6 +1746,6 @@ void radeon_atombios_init_crtc(struct drm_device *dev,
                else
                        radeon_crtc->crtc_offset = 0;
        }
-       radeon_crtc->pll_id = ATOM_PPLL_INVALID;
+       radeon_crtc->pll_id = -1;
        drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs);
 }
index 8acb34fd3fd548aa6e34d999682d0f8fafac95fd..8d7e33a0b243585100839905205a5f11ccab5f06 100644 (file)
@@ -1182,7 +1182,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
        ring->ready = true;
        radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
 
-       if (radeon_ring_supports_scratch_reg(rdev, ring)) {
+       if (!ring->rptr_save_reg /* not resuming from suspend */
+           && radeon_ring_supports_scratch_reg(rdev, ring)) {
                r = radeon_scratch_get(rdev, &ring->rptr_save_reg);
                if (r) {
                        DRM_ERROR("failed to get scratch reg for rptr save (%d).\n", r);
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 77d2df04c97b0dbe6c34eb11b9e566ae07d5ae28..60c4e1e85913fd435ba7c3fe977db50e4fb00f6c 100644 (file)
@@ -519,6 +519,8 @@ static void tpkbd_remove_tp(struct hid_device *hdev)
        led_classdev_unregister(&data_pointer->led_mute);
 
        hid_set_drvdata(hdev, NULL);
+       kfree(data_pointer->led_micmute.name);
+       kfree(data_pointer->led_mute.name);
        kfree(data_pointer);
 }
 
index 4d524b5f52f5631179e9092d6ee471522d3735a3..9500f2f3f8fea702432e683a56dc0eea53dbf3fe 100644 (file)
@@ -193,6 +193,7 @@ static struct hid_ll_driver logi_dj_ll_driver;
 static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
                                        size_t count,
                                        unsigned char report_type);
+static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev);
 
 static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev,
                                                struct dj_report *dj_report)
@@ -233,6 +234,7 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
        if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] &
            SPFUNCTION_DEVICE_LIST_EMPTY) {
                dbg_hid("%s: device list is empty\n", __func__);
+               djrcv_dev->querying_devices = false;
                return;
        }
 
@@ -243,6 +245,12 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
                return;
        }
 
+       if (djrcv_dev->paired_dj_devices[dj_report->device_index]) {
+               /* The device is already known. No need to reallocate it. */
+               dbg_hid("%s: device is already known\n", __func__);
+               return;
+       }
+
        dj_hiddev = hid_allocate_device();
        if (IS_ERR(dj_hiddev)) {
                dev_err(&djrcv_hdev->dev, "%s: hid_allocate_device failed\n",
@@ -306,6 +314,7 @@ static void delayedwork_callback(struct work_struct *work)
        struct dj_report dj_report;
        unsigned long flags;
        int count;
+       int retval;
 
        dbg_hid("%s\n", __func__);
 
@@ -338,6 +347,25 @@ static void delayedwork_callback(struct work_struct *work)
                logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report);
                break;
        default:
+       /* A normal report (i. e. not belonging to a pair/unpair notification)
+        * arriving here, means that the report arrived but we did not have a
+        * paired dj_device associated to the report's device_index, this
+        * means that the original "device paired" notification corresponding
+        * to this dj_device never arrived to this driver. The reason is that
+        * hid-core discards all packets coming from a device while probe() is
+        * executing. */
+       if (!djrcv_dev->paired_dj_devices[dj_report.device_index]) {
+               /* ok, we don't know the device, just re-ask the
+                * receiver for the list of connected devices. */
+               retval = logi_dj_recv_query_paired_devices(djrcv_dev);
+               if (!retval) {
+                       /* everything went fine, so just leave */
+                       break;
+               }
+               dev_err(&djrcv_dev->hdev->dev,
+                       "%s:logi_dj_recv_query_paired_devices "
+                       "error:%d\n", __func__, retval);
+               }
                dbg_hid("%s: unexpected report type\n", __func__);
        }
 }
@@ -368,6 +396,12 @@ static void logi_dj_recv_forward_null_report(struct dj_receiver_dev *djrcv_dev,
        if (!djdev) {
                dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
                        " is NULL, index %d\n", dj_report->device_index);
+               kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
+
+               if (schedule_work(&djrcv_dev->work) == 0) {
+                       dbg_hid("%s: did not schedule the work item, was already "
+                       "queued\n", __func__);
+               }
                return;
        }
 
@@ -398,6 +432,12 @@ static void logi_dj_recv_forward_report(struct dj_receiver_dev *djrcv_dev,
        if (dj_device == NULL) {
                dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
                        " is NULL, index %d\n", dj_report->device_index);
+               kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
+
+               if (schedule_work(&djrcv_dev->work) == 0) {
+                       dbg_hid("%s: did not schedule the work item, was already "
+                       "queued\n", __func__);
+               }
                return;
        }
 
@@ -439,6 +479,10 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
        struct dj_report *dj_report;
        int retval;
 
+       /* no need to protect djrcv_dev->querying_devices */
+       if (djrcv_dev->querying_devices)
+               return 0;
+
        dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
        if (!dj_report)
                return -ENOMEM;
@@ -450,6 +494,7 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
        return retval;
 }
 
+
 static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
                                          unsigned timeout)
 {
index fd28a5e0ca3b84b8407791421b25f8b17bf7815a..4a4000340ce1ed8cf6be1f81ee8e0f21d8ba5f5a 100644 (file)
@@ -101,6 +101,7 @@ struct dj_receiver_dev {
        struct work_struct work;
        struct kfifo notif_fifo;
        spinlock_t lock;
+       bool querying_devices;
 };
 
 struct dj_device {
index cfec802cf9ca949b705d24a1d862a702af223193..f915eb1c29f7030e0612c80812e2b32ba25334b4 100644 (file)
@@ -87,10 +87,18 @@ static ssize_t ad7314_show_temperature(struct device *dev,
        }
 }
 
+static ssize_t ad7314_show_name(struct device *dev,
+                               struct device_attribute *devattr, char *buf)
+{
+       return sprintf(buf, "%s\n", to_spi_device(dev)->modalias);
+}
+
+static DEVICE_ATTR(name, S_IRUGO, ad7314_show_name, NULL);
 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
                          ad7314_show_temperature, NULL, 0);
 
 static struct attribute *ad7314_attributes[] = {
+       &dev_attr_name.attr,
        &sensor_dev_attr_temp1_input.dev_attr.attr,
        NULL,
 };
index e65c6e45d36b05a24241680558fd2012be3f3c85..7bf4ce3d405e4903e26c010cc9040ce87e7067ba 100644 (file)
@@ -139,6 +139,12 @@ static ssize_t show_voltage(struct device *dev,
        }
 }
 
+static ssize_t ads7871_show_name(struct device *dev,
+                                struct device_attribute *devattr, char *buf)
+{
+       return sprintf(buf, "%s\n", to_spi_device(dev)->modalias);
+}
+
 static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_voltage, NULL, 0);
 static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 1);
 static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 2);
@@ -148,6 +154,8 @@ static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 5);
 static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 6);
 static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 7);
 
+static DEVICE_ATTR(name, S_IRUGO, ads7871_show_name, NULL);
+
 static struct attribute *ads7871_attributes[] = {
        &sensor_dev_attr_in0_input.dev_attr.attr,
        &sensor_dev_attr_in1_input.dev_attr.attr,
@@ -157,6 +165,7 @@ static struct attribute *ads7871_attributes[] = {
        &sensor_dev_attr_in5_input.dev_attr.attr,
        &sensor_dev_attr_in6_input.dev_attr.attr,
        &sensor_dev_attr_in7_input.dev_attr.attr,
+       &dev_attr_name.attr,
        NULL
 };
 
index 282708860517e8de41e2f86c3aeb55a118aaca17..8f3f6f2c45fd1a5ba95664a4ba92a6ffe7e6323c 100644 (file)
 
 #define APPLESMC_MAX_DATA_LENGTH 32
 
-/* wait up to 32 ms for a status change. */
+/* wait up to 128 ms for a status change. */
 #define APPLESMC_MIN_WAIT      0x0010
 #define APPLESMC_RETRY_WAIT    0x0100
-#define APPLESMC_MAX_WAIT      0x8000
+#define APPLESMC_MAX_WAIT      0x20000
 
 #define APPLESMC_READ_CMD      0x10
 #define APPLESMC_WRITE_CMD     0x11
index 0fa356fe82ccc00fc6a70704627da99bb66fc49a..984a3f13923b615b7c6849cd59b396689680ed20 100644 (file)
@@ -815,17 +815,20 @@ static int __init coretemp_init(void)
        if (err)
                goto exit;
 
+       get_online_cpus();
        for_each_online_cpu(i)
                get_core_online(i);
 
 #ifndef CONFIG_HOTPLUG_CPU
        if (list_empty(&pdev_list)) {
+               put_online_cpus();
                err = -ENODEV;
                goto exit_driver_unreg;
        }
 #endif
 
        register_hotcpu_notifier(&coretemp_cpu_notifier);
+       put_online_cpus();
        return 0;
 
 #ifndef CONFIG_HOTPLUG_CPU
@@ -840,6 +843,7 @@ static void __exit coretemp_exit(void)
 {
        struct pdev_entry *p, *n;
 
+       get_online_cpus();
        unregister_hotcpu_notifier(&coretemp_cpu_notifier);
        mutex_lock(&pdev_list_mutex);
        list_for_each_entry_safe(p, n, &pdev_list, list) {
@@ -848,6 +852,7 @@ static void __exit coretemp_exit(void)
                kfree(p);
        }
        mutex_unlock(&pdev_list_mutex);
+       put_online_cpus();
        platform_driver_unregister(&coretemp_driver);
 }
 
index 2764b78a784b9be83f9df1fd48f558452d9b8d61..af69073b3fe87a323e8986f76268c3ec1aa78522 100644 (file)
@@ -129,12 +129,12 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4)
  * counter saturations resulting in bogus power readings.
  * We correct this value ourselves to cope with older BIOSes.
  */
-static DEFINE_PCI_DEVICE_TABLE(affected_device) = {
+static const struct pci_device_id affected_device[] = {
        { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) },
        { 0 }
 };
 
-static void __devinit tweak_runavg_range(struct pci_dev *pdev)
+static void tweak_runavg_range(struct pci_dev *pdev)
 {
        u32 val;
 
@@ -158,6 +158,16 @@ static void __devinit tweak_runavg_range(struct pci_dev *pdev)
                REG_TDP_RUNNING_AVERAGE, val);
 }
 
+#ifdef CONFIG_PM
+static int fam15h_power_resume(struct pci_dev *pdev)
+{
+       tweak_runavg_range(pdev);
+       return 0;
+}
+#else
+#define fam15h_power_resume NULL
+#endif
+
 static void __devinit fam15h_power_init_data(struct pci_dev *f4,
                                             struct fam15h_power_data *data)
 {
@@ -256,6 +266,7 @@ static struct pci_driver fam15h_power_driver = {
        .id_table = fam15h_power_id_table,
        .probe = fam15h_power_probe,
        .remove = __devexit_p(fam15h_power_remove),
+       .resume = fam15h_power_resume,
 };
 
 module_pci_driver(fam15h_power_driver);
index ee4ebc198a9448e868f45af079e8f3d5f51968ae..2e56c6ce9fb654cb0532f4cbef756fd99f618e9d 100644 (file)
@@ -328,6 +328,7 @@ static int __init via_cputemp_init(void)
        if (err)
                goto exit;
 
+       get_online_cpus();
        for_each_online_cpu(i) {
                struct cpuinfo_x86 *c = &cpu_data(i);
 
@@ -347,12 +348,14 @@ static int __init via_cputemp_init(void)
 
 #ifndef CONFIG_HOTPLUG_CPU
        if (list_empty(&pdev_list)) {
+               put_online_cpus();
                err = -ENODEV;
                goto exit_driver_unreg;
        }
 #endif
 
        register_hotcpu_notifier(&via_cputemp_cpu_notifier);
+       put_online_cpus();
        return 0;
 
 #ifndef CONFIG_HOTPLUG_CPU
@@ -367,6 +370,7 @@ static void __exit via_cputemp_exit(void)
 {
        struct pdev_entry *p, *n;
 
+       get_online_cpus();
        unregister_hotcpu_notifier(&via_cputemp_cpu_notifier);
        mutex_lock(&pdev_list_mutex);
        list_for_each_entry_safe(p, n, &pdev_list, list) {
@@ -375,6 +379,7 @@ static void __exit via_cputemp_exit(void)
                kfree(p);
        }
        mutex_unlock(&pdev_list_mutex);
+       put_online_cpus();
        platform_driver_unregister(&via_cputemp_driver);
 }
 
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 ce68e361558c650ae8eb2032798048c8030cc309..cdc252612c0b35c453b976355c13b26f6d6767e1 100644 (file)
@@ -516,9 +516,9 @@ static int __devinit imx_keypad_probe(struct platform_device *pdev)
        input_set_drvdata(input_dev, keypad);
 
        /* Ensure that the keypad will stay dormant until opened */
-       clk_enable(keypad->clk);
+       clk_prepare_enable(keypad->clk);
        imx_keypad_inhibit(keypad);
-       clk_disable(keypad->clk);
+       clk_disable_unprepare(keypad->clk);
 
        error = request_irq(irq, imx_keypad_irq_handler, 0,
                            pdev->name, keypad);
index f06231b7cab1ef762d7ad5db073b3a6b64d39987..84ec691c05aa983751492a8dff29c5ca87b27ad2 100644 (file)
@@ -74,8 +74,8 @@ static int __devinit ab8500_ponkey_probe(struct platform_device *pdev)
 
        ponkey->idev = input;
        ponkey->ab8500 = ab8500;
-       ponkey->irq_dbf = ab8500_irq_get_virq(ab8500, irq_dbf);
-       ponkey->irq_dbr = ab8500_irq_get_virq(ab8500, irq_dbr);
+       ponkey->irq_dbf = irq_dbf;
+       ponkey->irq_dbr = irq_dbr;
 
        input->name = "AB8500 POn(PowerOn) Key";
        input->dev.parent = &pdev->dev;
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 3f5649f190824408a25c495bdfd4da88b8febe9a..a261d857691957a98e732124f6370c6f8280451a 100644 (file)
@@ -721,6 +721,17 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
 
        switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) {
        case FSP_PKT_TYPE_ABS:
+
+               if ((packet[0] == 0x48 || packet[0] == 0x49) &&
+                   packet[1] == 0 && packet[2] == 0) {
+                       /*
+                        * Ignore coordinate noise when finger leaving the
+                        * surface, otherwise cursor may jump to upper-left
+                        * corner.
+                        */
+                       packet[3] &= 0xf0;
+               }
+
                abs_x = GET_ABS_X(packet);
                abs_y = GET_ABS_Y(packet);
 
index 2ffd110bd5bc756e461051d39ba31238202a0fa7..2e77246c2e5ac8293569ecd19fe1df673c394c75 100644 (file)
@@ -72,7 +72,7 @@ static int amba_kmi_open(struct serio *io)
        unsigned int divisor;
        int ret;
 
-       ret = clk_enable(kmi->clk);
+       ret = clk_prepare_enable(kmi->clk);
        if (ret)
                goto out;
 
@@ -92,7 +92,7 @@ static int amba_kmi_open(struct serio *io)
        return 0;
 
  clk_disable:
-       clk_disable(kmi->clk);
+       clk_disable_unprepare(kmi->clk);
  out:
        return ret;
 }
@@ -104,7 +104,7 @@ static void amba_kmi_close(struct serio *io)
        writeb(0, KMICR);
 
        free_irq(kmi->irq, kmi);
-       clk_disable(kmi->clk);
+       clk_disable_unprepare(kmi->clk);
 }
 
 static int __devinit amba_kmi_probe(struct amba_device *dev,
index 6918773ce02443e67181c62823023597e3ba44ce..d6cc77a53c7e2bdbe94ee3c138ab8c86f0d90135 100644 (file)
@@ -333,6 +333,12 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
                },
        },
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"),
+               },
+       },
        {
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"),
index b06a5e3a665ea1864c8824f6d7d172f87d0b3ac1..64957770b52209fcc527e3f015e21816b3165bc7 100644 (file)
@@ -566,9 +566,12 @@ static ssize_t edt_ft5x06_debugfs_raw_data_read(struct file *file,
        }
 
        read = min_t(size_t, count, tsdata->raw_bufsize - *off);
-       error = copy_to_user(buf, tsdata->raw_buffer + *off, read);
-       if (!error)
-               *off += read;
+       if (copy_to_user(buf, tsdata->raw_buffer + *off, read)) {
+               error = -EFAULT;
+               goto out;
+       }
+
+       *off += read;
 out:
        mutex_unlock(&tsdata->mutex);
        return error ?: read;
index e32709e0dd65193286bccc2e81bd4e86d717c643..721fdb3597ca9d9ecb3f971f389f6852395ff39c 100644 (file)
@@ -304,6 +304,45 @@ static int e2i_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 #define EGALAX_PKT_TYPE_REPT           0x80
 #define EGALAX_PKT_TYPE_DIAG           0x0A
 
+static int egalax_init(struct usbtouch_usb *usbtouch)
+{
+       int ret, i;
+       unsigned char *buf;
+       struct usb_device *udev = interface_to_usbdev(usbtouch->interface);
+
+       /*
+        * An eGalax diagnostic packet kicks the device into using the right
+        * protocol.  We send a "check active" packet.  The response will be
+        * read later and ignored.
+        */
+
+       buf = kmalloc(3, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       buf[0] = EGALAX_PKT_TYPE_DIAG;
+       buf[1] = 1;     /* length */
+       buf[2] = 'A';   /* command - check active */
+
+       for (i = 0; i < 3; i++) {
+               ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+                                     0,
+                                     USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                                     0, 0, buf, 3,
+                                     USB_CTRL_SET_TIMEOUT);
+               if (ret >= 0) {
+                       ret = 0;
+                       break;
+               }
+               if (ret != -EPIPE)
+                       break;
+       }
+
+       kfree(buf);
+
+       return ret;
+}
+
 static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 {
        if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT)
@@ -1056,6 +1095,7 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
                .process_pkt    = usbtouch_process_multi,
                .get_pkt_len    = egalax_get_pkt_len,
                .read_data      = egalax_read_data,
+               .init           = egalax_init,
        },
 #endif
 
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 98ee4381991189d8814600967acac3b170525b1d..7edadee487bab16c0cbcf514ab59540f35cc2a41 100644 (file)
@@ -1391,7 +1391,6 @@ static irqreturn_t ican3_irq(int irq, void *dev_id)
  */
 static int ican3_reset_module(struct ican3_dev *mod)
 {
-       u8 val = 1 << mod->num;
        unsigned long start;
        u8 runold, runnew;
 
@@ -1405,8 +1404,7 @@ static int ican3_reset_module(struct ican3_dev *mod)
        runold = ioread8(mod->dpm + TARGET_RUNNING);
 
        /* reset the module */
-       iowrite8(val, &mod->ctrl->reset_assert);
-       iowrite8(val, &mod->ctrl->reset_deassert);
+       iowrite8(0x00, &mod->dpmctrl->hwreset);
 
        /* wait until the module has finished resetting and is running */
        start = jiffies;
index 527dbcf9533561489bb33332f03462ac5f405f43..9ded21e79db5866602706ca568dea6613bc0a727 100644 (file)
@@ -984,12 +984,12 @@ static int __devexit ti_hecc_remove(struct platform_device *pdev)
        struct net_device *ndev = platform_get_drvdata(pdev);
        struct ti_hecc_priv *priv = netdev_priv(ndev);
 
+       unregister_candev(ndev);
        clk_disable(priv->clk);
        clk_put(priv->clk);
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        iounmap(priv->base);
        release_mem_region(res->start, resource_size(res));
-       unregister_candev(ndev);
        free_candev(ndev);
        platform_set_drvdata(pdev, NULL);
 
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 af20c6ee2cd9292dfa41c8693e6d8253dfe667e4..e8e97a7d1d06df9a209c741406af32c19a1313e2 100644 (file)
@@ -662,14 +662,16 @@ void bnx2x_csum_validate(struct sk_buff *skb, union eth_rx_cqe *cqe,
                                 struct bnx2x_fastpath *fp,
                                 struct bnx2x_eth_q_stats *qstats)
 {
-       /* Do nothing if no IP/L4 csum validation was done */
-
+       /* Do nothing if no L4 csum validation was done.
+        * We do not check whether IP csum was validated. For IPv4 we assume
+        * that if the card got as far as validating the L4 csum, it also
+        * validated the IP csum. IPv6 has no IP csum.
+        */
        if (cqe->fast_path_cqe.status_flags &
-           (ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG |
-            ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG))
+           ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG)
                return;
 
-       /* If both IP/L4 validation were done, check if an error was found. */
+       /* If L4 validation was done, check if an error was found. */
 
        if (cqe->fast_path_cqe.type_error_flags &
            (ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG |
index 211753e01f81530324e15c03fa5d0dc4d99b2114..0875ecfe33729e2c2860dd5149e62042ddcbc6d7 100644 (file)
@@ -9831,12 +9831,13 @@ static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp)
        }
 
 #ifdef CONFIG_PCI_MSI
-       /*
-        * It's expected that number of CAM entries for this functions is equal
-        * to the number evaluated based on the MSI-X table size. We want a
-        * harsh warning if these values are different!
+       /* Due to new PF resource allocation by MFW T7.4 and above, it's
+        * optional that number of CAM entries will not be equal to the value
+        * advertised in PCI.
+        * Driver should use the minimal value of both as the actual status
+        * block count
         */
-       WARN_ON(bp->igu_sb_cnt != igu_sb_cnt);
+       bp->igu_sb_cnt = min_t(int, bp->igu_sb_cnt, igu_sb_cnt);
 #endif
 
        if (igu_sb_cnt == 0)
index 77884191a8c6448a7eea54c94b8ba8d9ce0fef83..4e980a7886fb58758fa84071b2494f56364da1f2 100644 (file)
@@ -1086,7 +1086,7 @@ static int __init at91ether_probe(struct platform_device *pdev)
        /* Clock */
        lp->ether_clk = clk_get(&pdev->dev, "ether_clk");
        if (IS_ERR(lp->ether_clk)) {
-               res = -ENODEV;
+               res = PTR_ERR(lp->ether_clk);
                goto err_ioumap;
        }
        clk_enable(lp->ether_clk);
index 8971921cc1c84966170b7f7a6350732f93b416e9..ab6762caa95702f492bbb457deae8986257bdcc4 100644 (file)
@@ -1773,6 +1773,7 @@ static int gfar_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
 }
 
 int gfar_phc_index = -1;
+EXPORT_SYMBOL(gfar_phc_index);
 
 static int gfar_get_ts_info(struct net_device *dev,
                            struct ethtool_ts_info *info)
index c08e5d40fecb425c7f6c26b8de269d270bac727f..0daa66b8eca088735974f7ee45595d22c6be4c56 100644 (file)
@@ -515,7 +515,7 @@ static int gianfar_ptp_probe(struct platform_device *dev)
                err = PTR_ERR(etsects->clock);
                goto no_clock;
        }
-       gfar_phc_clock = ptp_clock_index(etsects->clock);
+       gfar_phc_index = ptp_clock_index(etsects->clock);
 
        dev_set_drvdata(&dev->dev, etsects);
 
@@ -539,7 +539,7 @@ static int gianfar_ptp_remove(struct platform_device *dev)
        gfar_write(&etsects->regs->tmr_temask, 0);
        gfar_write(&etsects->regs->tmr_ctrl,   0);
 
-       gfar_phc_clock = -1;
+       gfar_phc_index = -1;
        ptp_clock_unregister(etsects->clock);
        iounmap(etsects->regs);
        release_resource(etsects->rsrc);
index 3bfbb8df898935f4acf47a52ebb8be3f0f683a67..bde337ee1a34f954e90c583711f155eec87b633e 100644 (file)
@@ -3149,6 +3149,17 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
                return NETDEV_TX_OK;
        }
 
+       /* On PCI/PCI-X HW, if packet size is less than ETH_ZLEN,
+        * packets may get corrupted during padding by HW.
+        * To WA this issue, pad all small packets manually.
+        */
+       if (skb->len < ETH_ZLEN) {
+               if (skb_pad(skb, ETH_ZLEN - skb->len))
+                       return NETDEV_TX_OK;
+               skb->len = ETH_ZLEN;
+               skb_set_tail_pointer(skb, ETH_ZLEN);
+       }
+
        mss = skb_shinfo(skb)->gso_size;
        /* The controller does a simple calculation to
         * make sure there is enough room in the FIFO before
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 342b3a79bd0fd7a6a6bde8860446c20c78595ef2..a77c558d8f4078e7cc4747a5308dc315e34d99c1 100644 (file)
@@ -1378,6 +1378,10 @@ static void netxen_mask_aer_correctable(struct netxen_adapter *adapter)
        struct pci_dev *root = pdev->bus->self;
        u32 aer_pos;
 
+       /* root bus? */
+       if (!root)
+               return;
+
        if (adapter->ahw.board_type != NETXEN_BRDTYPE_P3_4_GB_MM &&
                adapter->ahw.board_type != NETXEN_BRDTYPE_P3_10G_TP)
                return;
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 c136162e6473e1746b48f50a0c7cc0adc57986d6..3be88331d17ab0e690b71f06b2ac30f50d7a7f77 100644 (file)
@@ -1066,7 +1066,7 @@ static int stmmac_open(struct net_device *dev)
        } else
                priv->tm->enable = 1;
 #endif
-       clk_enable(priv->stmmac_clk);
+       clk_prepare_enable(priv->stmmac_clk);
 
        stmmac_check_ether_addr(priv);
 
@@ -1188,7 +1188,7 @@ open_error:
        if (priv->phydev)
                phy_disconnect(priv->phydev);
 
-       clk_disable(priv->stmmac_clk);
+       clk_disable_unprepare(priv->stmmac_clk);
 
        return ret;
 }
@@ -1246,7 +1246,7 @@ static int stmmac_release(struct net_device *dev)
 #ifdef CONFIG_STMMAC_DEBUG_FS
        stmmac_exit_fs();
 #endif
-       clk_disable(priv->stmmac_clk);
+       clk_disable_unprepare(priv->stmmac_clk);
 
        return 0;
 }
@@ -2178,7 +2178,7 @@ int stmmac_suspend(struct net_device *ndev)
        else {
                stmmac_set_mac(priv->ioaddr, false);
                /* Disable clock in case of PWM is off */
-               clk_disable(priv->stmmac_clk);
+               clk_disable_unprepare(priv->stmmac_clk);
        }
        spin_unlock_irqrestore(&priv->lock, flags);
        return 0;
@@ -2203,7 +2203,7 @@ int stmmac_resume(struct net_device *ndev)
                priv->hw->mac->pmt(priv->ioaddr, 0);
        else
                /* enable the clk prevously disabled */
-               clk_enable(priv->stmmac_clk);
+               clk_prepare_enable(priv->stmmac_clk);
 
        netif_device_attach(ndev);
 
index 2a0e1abde7e73eeea25c9c457999765b5315a01f..4ccd4e2977b73a0d441f6f0dbb99ea0636c8dae0 100644 (file)
@@ -97,19 +97,19 @@ static struct clk *timer_clock;
 static void stmmac_tmu_start(unsigned int new_freq)
 {
        clk_set_rate(timer_clock, new_freq);
-       clk_enable(timer_clock);
+       clk_prepare_enable(timer_clock);
 }
 
 static void stmmac_tmu_stop(void)
 {
-       clk_disable(timer_clock);
+       clk_disable_unprepare(timer_clock);
 }
 
 int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
 {
        timer_clock = clk_get(NULL, TMU_CHANNEL);
 
-       if (timer_clock == NULL)
+       if (IS_ERR(timer_clock))
                return -1;
 
        if (tmu2_register_user(stmmac_timer_handler, (void *)dev) < 0) {
@@ -126,7 +126,7 @@ int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
 
 int stmmac_close_ext_timer(void)
 {
-       clk_disable(timer_clock);
+       clk_disable_unprepare(timer_clock);
        tmu2_unregister_user();
        clk_put(timer_clock);
        return 0;
index 256eddf1f75a1913576067742f8fc1cb3dce3e7a..795109425568623977428b1a62bffc7d11c6fa14 100644 (file)
@@ -280,7 +280,7 @@ static int sh_sir_set_baudrate(struct sh_sir_self *self, u32 baudrate)
        }
 
        clk = clk_get(NULL, "irda_clk");
-       if (!clk) {
+       if (IS_ERR(clk)) {
                dev_err(dev, "can not get irda_clk\n");
                return -EIO;
        }
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 4fd48df6b989eee8aff62ee1d5edb5014bae5e1d..32e31c5c5dc6bfe95b4d38e377a508448d85c890 100644 (file)
@@ -961,6 +961,10 @@ static const struct usb_device_id  products [] = {
        // DLink DUB-E100 H/W Ver B1 Alternate
        USB_DEVICE (0x2001, 0x3c05),
        .driver_info = (unsigned long) &ax88772_info,
+}, {
+       // DLink DUB-E100 H/W Ver C1
+       USB_DEVICE (0x2001, 0x1a02),
+       .driver_info = (unsigned long) &ax88772_info,
 }, {
        // Linksys USB1000
        USB_DEVICE (0x1737, 0x0039),
index b1ba68f1a049202dac23f6fc4b9f944f8526cb71..3543c9e578247e6ee550ef7f18f680b680be3587 100644 (file)
@@ -366,16 +366,20 @@ static const struct usb_device_id products[] = {
        },
 
        /* 2. Combined interface devices matching on class+protocol */
+       {       /* Huawei E367 and possibly others in "Windows mode" */
+               USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 7),
+               .driver_info        = (unsigned long)&qmi_wwan_info,
+       },
        {       /* Huawei E392, E398 and possibly others in "Windows mode" */
                USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 17),
                .driver_info        = (unsigned long)&qmi_wwan_shared,
        },
-       {       /* Pantech UML290 */
-               USB_DEVICE_AND_INTERFACE_INFO(0x106c, 0x3718, USB_CLASS_VENDOR_SPEC, 0xf0, 0xff),
+       {       /* Pantech UML290, P4200 and more */
+               USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf0, 0xff),
                .driver_info        = (unsigned long)&qmi_wwan_shared,
        },
        {       /* Pantech UML290 - newer firmware */
-               USB_DEVICE_AND_INTERFACE_INFO(0x106c, 0x3718, USB_CLASS_VENDOR_SPEC, 0xf1, 0xff),
+               USB_VENDOR_AND_INTERFACE_INFO(0x106c, USB_CLASS_VENDOR_SPEC, 0xf1, 0xff),
                .driver_info        = (unsigned long)&qmi_wwan_shared,
        },
 
@@ -383,6 +387,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x19d2, 0x0055, 1)},    /* ZTE (Vodafone) K3520-Z */
        {QMI_FIXED_INTF(0x19d2, 0x0063, 4)},    /* ZTE (Vodafone) K3565-Z */
        {QMI_FIXED_INTF(0x19d2, 0x0104, 4)},    /* ZTE (Vodafone) K4505-Z */
+       {QMI_FIXED_INTF(0x19d2, 0x0157, 5)},    /* ZTE MF683 */
        {QMI_FIXED_INTF(0x19d2, 0x0167, 4)},    /* ZTE MF820D */
        {QMI_FIXED_INTF(0x19d2, 0x0326, 4)},    /* ZTE MF821D */
        {QMI_FIXED_INTF(0x19d2, 0x1008, 4)},    /* ZTE (Vodafone) K3570-Z */
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 2588848f4a822a1bf879ce447f9f146c5e186873..d066f2516e4753617aa55f1522427eb96f4a1115 100644 (file)
@@ -2982,6 +2982,10 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
        case EEP_RX_MASK:
                return pBase->txrxMask & 0xf;
        case EEP_PAPRD:
+               if (AR_SREV_9462(ah))
+                       return false;
+               if (!ah->config.enable_paprd);
+                       return false;
                return !!(pBase->featureEnable & BIT(5));
        case EEP_CHAIN_MASK_REDUCE:
                return (pBase->miscConfiguration >> 0x3) & 0x1;
index 68b643c8943c4c2db074e4ada4eeb2fda397eccc..c8ef30127adb53da590bf4d6350798fa261dffa6 100644 (file)
@@ -1577,6 +1577,8 @@ int ath9k_init_debug(struct ath_hw *ah)
                            sc->debug.debugfs_phy, sc, &fops_tx_chainmask);
        debugfs_create_file("disable_ani", S_IRUSR | S_IWUSR,
                            sc->debug.debugfs_phy, sc, &fops_disable_ani);
+       debugfs_create_bool("paprd", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+                           &sc->sc_ah->config.enable_paprd);
        debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
                            sc, &fops_regidx);
        debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
index 48af40151d2310e5250ad88c0ae05b47d7cae7ea..4faf0a3958765bd07ae683fdd6dceb879a5adbfd 100644 (file)
@@ -2497,10 +2497,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
                pCap->rx_status_len = sizeof(struct ar9003_rxs);
                pCap->tx_desc_len = sizeof(struct ar9003_txc);
                pCap->txs_len = sizeof(struct ar9003_txs);
-               if (!ah->config.paprd_disable &&
-                   ah->eep_ops->get_eeprom(ah, EEP_PAPRD) &&
-                   !AR_SREV_9462(ah))
-                       pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
        } else {
                pCap->tx_desc_len = sizeof(struct ath_desc);
                if (AR_SREV_9280_20(ah))
index 6599a75f01fe3157526cf4c30f999ddaef391382..de6968fc64f42920304fe52dd93a493c3ce679c6 100644 (file)
@@ -236,7 +236,6 @@ enum ath9k_hw_caps {
        ATH9K_HW_CAP_LDPC                       = BIT(6),
        ATH9K_HW_CAP_FASTCLOCK                  = BIT(7),
        ATH9K_HW_CAP_SGI_20                     = BIT(8),
-       ATH9K_HW_CAP_PAPRD                      = BIT(9),
        ATH9K_HW_CAP_ANT_DIV_COMB               = BIT(10),
        ATH9K_HW_CAP_2GHZ                       = BIT(11),
        ATH9K_HW_CAP_5GHZ                       = BIT(12),
@@ -287,12 +286,12 @@ struct ath9k_ops_config {
        u8 pcie_clock_req;
        u32 pcie_waen;
        u8 analog_shiftreg;
-       u8 paprd_disable;
        u32 ofdm_trig_low;
        u32 ofdm_trig_high;
        u32 cck_trig_high;
        u32 cck_trig_low;
        u32 enable_ani;
+       u32 enable_paprd;
        int serialize_regmode;
        bool rx_intr_mitigation;
        bool tx_intr_mitigation;
index 825a29cc93131c4a34c22d8ac8e58e02cc41b531..7b88b9c39ccddc4ef4e3aeafb53e437d0f35a0ce 100644 (file)
@@ -423,7 +423,7 @@ set_timer:
                cal_interval = min(cal_interval, (u32)short_cal_interval);
 
        mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
-       if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) {
+       if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD) && ah->caldata) {
                if (!ah->caldata->paprd_done)
                        ieee80211_queue_work(sc->hw, &sc->paprd_work);
                else if (!ah->paprd_table_write_done)
index 49765d34b4e0b43ac947aa360fb58d1fff88aa90..7c4ee72f9d56006cb7e069a9472a0524bbebb9c9 100644 (file)
@@ -638,6 +638,8 @@ static int brcmf_sdio_pd_probe(struct platform_device *pdev)
 
                oobirq_entry = kzalloc(sizeof(struct brcmf_sdio_oobirq),
                                       GFP_KERNEL);
+               if (!oobirq_entry)
+                       return -ENOMEM;
                oobirq_entry->irq = res->start;
                oobirq_entry->flags = res->flags & IRQF_TRIGGER_MASK;
                list_add_tail(&oobirq_entry->list, &oobirq_lh);
index 2621dd3d7dcd9d3b6ac5ca05db587cdd94454011..6f70953f0bade06ef046a845829a887611c0a8b8 100644 (file)
@@ -764,8 +764,11 @@ static void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode)
 {
        char iovbuf[32];
        int retcode;
+       __le32 arp_mode_le;
 
-       brcmf_c_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
+       arp_mode_le = cpu_to_le32(arp_mode);
+       brcmf_c_mkiovar("arp_ol", (char *)&arp_mode_le, 4, iovbuf,
+                       sizeof(iovbuf));
        retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
                                   iovbuf, sizeof(iovbuf));
        retcode = retcode >= 0 ? 0 : retcode;
@@ -781,8 +784,11 @@ static void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable)
 {
        char iovbuf[32];
        int retcode;
+       __le32 arp_enable_le;
 
-       brcmf_c_mkiovar("arpoe", (char *)&arp_enable, 4,
+       arp_enable_le = cpu_to_le32(arp_enable);
+
+       brcmf_c_mkiovar("arpoe", (char *)&arp_enable_le, 4,
                        iovbuf, sizeof(iovbuf));
        retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
                                   iovbuf, sizeof(iovbuf));
@@ -800,10 +806,10 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
        char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];      /*  Room for
                                 "event_msgs" + '\0' + bitvec  */
        char buf[128], *ptr;
-       u32 roaming = 1;
-       uint bcn_timeout = 3;
-       int scan_assoc_time = 40;
-       int scan_unassoc_time = 40;
+       __le32 roaming_le = cpu_to_le32(1);
+       __le32 bcn_timeout_le = cpu_to_le32(3);
+       __le32 scan_assoc_time_le = cpu_to_le32(40);
+       __le32 scan_unassoc_time_le = cpu_to_le32(40);
        int i;
        struct brcmf_bus_dcmd *cmdlst;
        struct list_head *cur, *q;
@@ -829,14 +835,14 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
 
        /* Setup timeout if Beacons are lost and roam is off to report
                 link down */
-       brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
+       brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout_le, 4, iovbuf,
                    sizeof(iovbuf));
        brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
                                  sizeof(iovbuf));
 
        /* Enable/Disable build-in roaming to allowed ext supplicant to take
                 of romaing */
-       brcmf_c_mkiovar("roam_off", (char *)&roaming, 4,
+       brcmf_c_mkiovar("roam_off", (char *)&roaming_le, 4,
                      iovbuf, sizeof(iovbuf));
        brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
                                  sizeof(iovbuf));
@@ -848,9 +854,9 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
                                  sizeof(iovbuf));
 
        brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME,
-                        (char *)&scan_assoc_time, sizeof(scan_assoc_time));
+                (char *)&scan_assoc_time_le, sizeof(scan_assoc_time_le));
        brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME,
-                        (char *)&scan_unassoc_time, sizeof(scan_unassoc_time));
+                (char *)&scan_unassoc_time_le, sizeof(scan_unassoc_time_le));
 
        /* Set and enable ARP offload feature */
        brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE);
index c36e9231244317945107f6cc3da3aaea034cc379..50b5553b6964b95dffecf40f4d28fdb91796efc8 100644 (file)
@@ -500,8 +500,10 @@ static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
        params_le->active_time = cpu_to_le32(-1);
        params_le->passive_time = cpu_to_le32(-1);
        params_le->home_time = cpu_to_le32(-1);
-       if (ssid && ssid->SSID_len)
-               memcpy(&params_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
+       if (ssid && ssid->SSID_len) {
+               params_le->ssid_le.SSID_len = cpu_to_le32(ssid->SSID_len);
+               memcpy(&params_le->ssid_le.SSID, ssid->SSID, ssid->SSID_len);
+       }
 }
 
 static s32
index 7ed7d7577024628d228a78f6e94433c810295bc2..64a48f06d68bfa124c1687bc1fa81a799fb5be82 100644 (file)
@@ -77,7 +77,7 @@
                                         NL80211_RRF_NO_IBSS)
 
 static const struct ieee80211_regdomain brcms_regdom_x2 = {
-       .n_reg_rules = 7,
+       .n_reg_rules = 6,
        .alpha2 = "X2",
        .reg_rules = {
                BRCM_2GHZ_2412_2462,
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 04c3aef8a4f62e178fbac155a956c64c529b97c8..2925094b2d912529fb32dc5202487d1def6d9910 100644 (file)
 
 #define CHIP_VER_B                     BIT(4)
 #define CHIP_92C_BITMASK               BIT(0)
+#define CHIP_UNKNOWN                   BIT(7)
 #define CHIP_92C_1T2R                  0x03
 #define CHIP_92C                       0x01
 #define CHIP_88C                       0x00
index bd0da7ef290b3cf5cafafe4d56ec4c3d7cf33611..dd4bb0950a575ddd37c31489f10d2bacdaaab940 100644 (file)
@@ -994,8 +994,16 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw)
                version = (value32 & TYPE_ID) ? VERSION_A_CHIP_92C :
                           VERSION_A_CHIP_88C;
        } else {
-               version = (value32 & TYPE_ID) ? VERSION_B_CHIP_92C :
-                          VERSION_B_CHIP_88C;
+               version = (enum version_8192c) (CHIP_VER_B |
+                               ((value32 & TYPE_ID) ? CHIP_92C_BITMASK : 0) |
+                               ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0));
+               if ((!IS_CHIP_VENDOR_UMC(version)) && (value32 &
+                    CHIP_VER_RTL_MASK)) {
+                       version = (enum version_8192c)(version |
+                                  ((((value32 & CHIP_VER_RTL_MASK) == BIT(12))
+                                  ? CHIP_VENDOR_UMC_B_CUT : CHIP_UNKNOWN) |
+                                  CHIP_VENDOR_UMC));
+               }
        }
 
        switch (version) {
index 3aa927f8b9b93bfbf0b12d9d0194966cd24900c8..7d8f96405f42068bafa9c08d7ec6a382f2e2c7f0 100644 (file)
@@ -162,10 +162,12 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
 
        /* request fw */
        if (IS_VENDOR_UMC_A_CUT(rtlhal->version) &&
-           !IS_92C_SERIAL(rtlhal->version))
+           !IS_92C_SERIAL(rtlhal->version)) {
                rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin";
-       else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version))
+       } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) {
                rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin";
+               pr_info("****** This B_CUT device may not work with kernels 3.6 and earlier\n");
+       }
 
        rtlpriv->max_fw_size = 0x4000;
        pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
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 15370a2c5ff0b29e5286a9ffb2660beefd045f2e..0595c763dafd687ac3938f803618eed679549d76 100644 (file)
@@ -534,11 +534,11 @@ static void dasd_change_state(struct dasd_device *device)
        if (rc)
                device->target = device->state;
 
-       if (device->state == device->target)
-               wake_up(&dasd_init_waitq);
-
        /* let user-space know that the device status changed */
        kobject_uevent(&device->cdev->dev.kobj, KOBJ_CHANGE);
+
+       if (device->state == device->target)
+               wake_up(&dasd_init_waitq);
 }
 
 /*
@@ -2157,6 +2157,7 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
                    test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
                    (!dasd_eer_enabled(device))) {
                        cqr->status = DASD_CQR_FAILED;
+                       cqr->intrc = -EAGAIN;
                        continue;
                }
                /* Don't try to start requests if device is stopped */
@@ -3270,6 +3271,16 @@ void dasd_generic_path_event(struct ccw_device *cdev, int *path_event)
                        dasd_schedule_device_bh(device);
                }
                if (path_event[chp] & PE_PATHGROUP_ESTABLISHED) {
+                       if (!(device->path_data.opm & eventlpm) &&
+                           !(device->path_data.tbvpm & eventlpm)) {
+                               /*
+                                * we can not establish a pathgroup on an
+                                * unavailable path, so trigger a path
+                                * verification first
+                                */
+                               device->path_data.tbvpm |= eventlpm;
+                               dasd_schedule_device_bh(device);
+                       }
                        DBF_DEV_EVENT(DBF_WARNING, device, "%s",
                                      "Pathgroup re-established\n");
                        if (device->discipline->kick_validate)
index 157defe5e0693c06c6432ddfbd65d0f6632a6f90..6b556995bb33e9baf98663175973bbb69805522d 100644 (file)
@@ -384,6 +384,29 @@ static void _remove_device_from_lcu(struct alias_lcu *lcu,
                group->next = NULL;
 };
 
+static int
+suborder_not_supported(struct dasd_ccw_req *cqr)
+{
+       char *sense;
+       char reason;
+       char msg_format;
+       char msg_no;
+
+       sense = dasd_get_sense(&cqr->irb);
+       if (!sense)
+               return 0;
+
+       reason = sense[0];
+       msg_format = (sense[7] & 0xF0);
+       msg_no = (sense[7] & 0x0F);
+
+       /* command reject, Format 0 MSG 4 - invalid parameter */
+       if ((reason == 0x80) && (msg_format == 0x00) && (msg_no == 0x04))
+               return 1;
+
+       return 0;
+}
+
 static int read_unit_address_configuration(struct dasd_device *device,
                                           struct alias_lcu *lcu)
 {
@@ -435,6 +458,8 @@ static int read_unit_address_configuration(struct dasd_device *device,
 
        do {
                rc = dasd_sleep_on(cqr);
+               if (rc && suborder_not_supported(cqr))
+                       return -EOPNOTSUPP;
        } while (rc && (cqr->retries > 0));
        if (rc) {
                spin_lock_irqsave(&lcu->lock, flags);
@@ -521,7 +546,7 @@ static void lcu_update_work(struct work_struct *work)
         * processing the data
         */
        spin_lock_irqsave(&lcu->lock, flags);
-       if (rc || (lcu->flags & NEED_UAC_UPDATE)) {
+       if ((rc && (rc != -EOPNOTSUPP)) || (lcu->flags & NEED_UAC_UPDATE)) {
                DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
                            " alias data in lcu (rc = %d), retry later", rc);
                schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ);
index 2fb2b9ea97ecc11d7e60af84d756b9eaad8dfbed..c48c72abbefc640671af73090536bd206b1c95dc 100644 (file)
@@ -1507,7 +1507,8 @@ static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device,
  * call might change behaviour of DASD devices.
  */
 static int
-dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav)
+dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav,
+                 unsigned long flags)
 {
        struct dasd_ccw_req *cqr;
        int rc;
@@ -1516,10 +1517,19 @@ dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav)
        if (IS_ERR(cqr))
                return PTR_ERR(cqr);
 
+       /*
+        * set flags e.g. turn on failfast, to prevent blocking
+        * the calling function should handle failed requests
+        */
+       cqr->flags |= flags;
+
        rc = dasd_sleep_on(cqr);
        if (!rc)
                /* trigger CIO to reprobe devices */
                css_schedule_reprobe();
+       else if (cqr->intrc == -EAGAIN)
+               rc = -EAGAIN;
+
        dasd_sfree_request(cqr, cqr->memdev);
        return rc;
 }
@@ -1527,7 +1537,8 @@ dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav)
 /*
  * Valide storage server of current device.
  */
-static void dasd_eckd_validate_server(struct dasd_device *device)
+static int dasd_eckd_validate_server(struct dasd_device *device,
+                                    unsigned long flags)
 {
        int rc;
        struct dasd_eckd_private *private;
@@ -1536,17 +1547,18 @@ static void dasd_eckd_validate_server(struct dasd_device *device)
        private = (struct dasd_eckd_private *) device->private;
        if (private->uid.type == UA_BASE_PAV_ALIAS ||
            private->uid.type == UA_HYPER_PAV_ALIAS)
-               return;
+               return 0;
        if (dasd_nopav || MACHINE_IS_VM)
                enable_pav = 0;
        else
                enable_pav = 1;
-       rc = dasd_eckd_psf_ssc(device, enable_pav);
+       rc = dasd_eckd_psf_ssc(device, enable_pav, flags);
 
        /* may be requested feature is not available on server,
         * therefore just report error and go ahead */
        DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x "
                        "returned rc=%d", private->uid.ssid, rc);
+       return rc;
 }
 
 /*
@@ -1556,7 +1568,13 @@ static void dasd_eckd_do_validate_server(struct work_struct *work)
 {
        struct dasd_device *device = container_of(work, struct dasd_device,
                                                  kick_validate);
-       dasd_eckd_validate_server(device);
+       if (dasd_eckd_validate_server(device, DASD_CQR_FLAGS_FAILFAST)
+           == -EAGAIN) {
+               /* schedule worker again if failed */
+               schedule_work(&device->kick_validate);
+               return;
+       }
+
        dasd_put_device(device);
 }
 
@@ -1685,7 +1703,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
        if (rc)
                goto out_err2;
 
-       dasd_eckd_validate_server(device);
+       dasd_eckd_validate_server(device, 0);
 
        /* device may report different configuration data after LCU setup */
        rc = dasd_eckd_read_conf(device);
@@ -4153,7 +4171,7 @@ static int dasd_eckd_restore_device(struct dasd_device *device)
        rc = dasd_alias_make_device_known_to_lcu(device);
        if (rc)
                return rc;
-       dasd_eckd_validate_server(device);
+       dasd_eckd_validate_server(device, DASD_CQR_FLAGS_FAILFAST);
 
        /* RE-Read Configuration Data */
        rc = dasd_eckd_read_conf(device);
index ed25c8740a9ce4b0bb8e8334a32b72abc08655ae..fc916f5d731412c7146465d3ff29277979b69189 100644 (file)
@@ -1426,6 +1426,8 @@ static enum io_sch_action sch_get_action(struct subchannel *sch)
                return IO_SCH_REPROBE;
        if (cdev->online)
                return IO_SCH_VERIFY;
+       if (cdev->private->state == DEV_STATE_NOT_OPER)
+               return IO_SCH_UNREG_ATTACH;
        return IO_SCH_NOP;
 }
 
@@ -1519,11 +1521,14 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
                        goto out;
                break;
        case IO_SCH_UNREG_ATTACH:
+               spin_lock_irqsave(sch->lock, flags);
                if (cdev->private->flags.resuming) {
                        /* Device will be handled later. */
                        rc = 0;
-                       goto out;
+                       goto out_unlock;
                }
+               sch_set_cdev(sch, NULL);
+               spin_unlock_irqrestore(sch->lock, flags);
                /* Unregister ccw device. */
                ccw_device_unregister(cdev);
                break;
index 33d6630529ded9b8db625a1ca4545c6fdb2472b3..91eec60252ee1c973198ae5c230762af37607073 100644 (file)
@@ -1264,6 +1264,9 @@ int bnx2i_send_fw_iscsi_init_msg(struct bnx2i_hba *hba)
        int rc = 0;
        u64 mask64;
 
+       memset(&iscsi_init, 0x00, sizeof(struct iscsi_kwqe_init1));
+       memset(&iscsi_init2, 0x00, sizeof(struct iscsi_kwqe_init2));
+
        bnx2i_adjust_qp_size(hba);
 
        iscsi_init.flags =
index 796482badf13acfe91f4391822d90cd6339d9ffc..2b4261cb77424b52046d6e4c255f32f3359bbf2a 100644 (file)
@@ -1315,8 +1315,9 @@ static void complete_scsi_command(struct CommandList *cp)
        }
                break;
        case CMD_PROTOCOL_ERR:
+               cmd->result = DID_ERROR << 16;
                dev_warn(&h->pdev->dev, "cp %p has "
-                       "protocol error \n", cp);
+                       "protocol error\n", cp);
                break;
        case CMD_HARDWARE_ERR:
                cmd->result = DID_ERROR << 16;
index b25757d1e91b5ee8ebf2964d3ee424105939d56b..9d5a56c4b3321deea9b9001468755d222fa13b51 100644 (file)
@@ -1209,6 +1209,13 @@ _base_check_enable_msix(struct MPT2SAS_ADAPTER *ioc)
        u16 message_control;
 
 
+       /* Check whether controller SAS2008 B0 controller,
+          if it is SAS2008 B0 controller use IO-APIC instead of MSIX */
+       if (ioc->pdev->device == MPI2_MFGPAGE_DEVID_SAS2008 &&
+           ioc->pdev->revision == 0x01) {
+               return -EINVAL;
+       }
+
        base = pci_find_capability(ioc->pdev, PCI_CAP_ID_MSIX);
        if (!base) {
                dfailprintk(ioc, printk(MPT2SAS_INFO_FMT "msix not "
index c7030fbee79c254ace6a41eed0a88e6b968e6bfb..3e79a2f0004279d0b2b1175281d003a664d5aeee 100644 (file)
@@ -331,7 +331,7 @@ static void virtscsi_map_sgl(struct scatterlist *sg, unsigned int *p_idx,
        int i;
 
        for_each_sg(table->sgl, sg_elem, table->nents, i)
-               sg_set_buf(&sg[idx++], sg_virt(sg_elem), sg_elem->length);
+               sg[idx++] = *sg_elem;
 
        *p_idx = idx;
 }
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 1eff743ec4970071f8451704fb51d4b06de70950..ae60406ea8a1878cefd03d29868eda31b955578f 100644 (file)
@@ -814,6 +814,9 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev,
        hpwdt_timer_reg = pci_mem_addr + 0x70;
        hpwdt_timer_con = pci_mem_addr + 0x72;
 
+       /* Make sure that timer is disabled until /dev/watchdog is opened */
+       hpwdt_stop();
+
        /* Make sure that we have a valid soft_margin */
        if (hpwdt_change_timer(soft_margin))
                hpwdt_change_timer(DEFAULT_MARGIN);
index 6aa46a90ff028691f97627765f593d864bc885a1..3796434991faa83466c85c8779a072db1278ef33 100644 (file)
@@ -128,11 +128,12 @@ EXPORT_SYMBOL_GPL(watchdog_register_device);
 void watchdog_unregister_device(struct watchdog_device *wdd)
 {
        int ret;
-       int devno = wdd->cdev.dev;
+       int devno;
 
        if (wdd == NULL)
                return;
 
+       devno = wdd->cdev.dev;
        ret = watchdog_dev_unregister(wdd);
        if (ret)
                pr_err("error unregistering /dev/watchdog (err=%d)\n", ret);
index 1ffd03bf8e10dcb6b015e3e0b94a2a460f0d0dcd..7f1241608489de05a33e957a77145f4faa605f0e 100644 (file)
@@ -314,8 +314,9 @@ static int __unmap_grant_pages(struct grant_map *map, int offset, int pages)
                }
        }
 
-       err = gnttab_unmap_refs(map->unmap_ops + offset, map->pages + offset,
-                               pages, true);
+       err = gnttab_unmap_refs(map->unmap_ops + offset,
+                       use_ptemod ? map->kmap_ops + offset : NULL, map->pages + offset,
+                       pages);
        if (err)
                return err;
 
index 0bfc1ef11259eccaa937eb8d0913e4e14e04832e..006726688baf4f0a535896dd38c9a3ea2198c617 100644 (file)
@@ -870,7 +870,8 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
 EXPORT_SYMBOL_GPL(gnttab_map_refs);
 
 int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
-                     struct page **pages, unsigned int count, bool clear_pte)
+                     struct gnttab_map_grant_ref *kmap_ops,
+                     struct page **pages, unsigned int count)
 {
        int i, ret;
        bool lazy = false;
@@ -888,7 +889,8 @@ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
        }
 
        for (i = 0; i < count; i++) {
-               ret = m2p_remove_override(pages[i], clear_pte);
+               ret = m2p_remove_override(pages[i], kmap_ops ?
+                                      &kmap_ops[i] : NULL);
                if (ret)
                        return ret;
        }
index 7dab9c04ad524117a386c08fb21d7a886e9ca82d..53cf2aabce877ce2a8e15844ab667cf6f26a2d63 100644 (file)
@@ -328,7 +328,7 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
        }
 
 ctoUTF16_out:
-       return i;
+       return j;
 }
 
 #ifdef CONFIG_CIFS_SMB2
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 2340f6978d6e29e01c9b90ddaa9abd33beb0ee11..c5ca6ae5a30cc750e5a33b42ce746da6cf2f4591 100644 (file)
@@ -526,73 +526,51 @@ struct array_data {
        u32 elements;
 };
 
-static int u32_array_open(struct inode *inode, struct file *file)
-{
-       file->private_data = NULL;
-       return nonseekable_open(inode, file);
-}
-
-static size_t format_array(char *buf, size_t bufsize, const char *fmt,
-                          u32 *array, u32 array_size)
+static size_t u32_format_array(char *buf, size_t bufsize,
+                              u32 *array, int array_size)
 {
        size_t ret = 0;
-       u32 i;
 
-       for (i = 0; i < array_size; i++) {
+       while (--array_size >= 0) {
                size_t len;
+               char term = array_size ? ' ' : '\n';
 
-               len = snprintf(buf, bufsize, fmt, array[i]);
-               len++;  /* ' ' or '\n' */
+               len = snprintf(buf, bufsize, "%u%c", *array++, term);
                ret += len;
 
-               if (buf) {
-                       buf += len;
-                       bufsize -= len;
-                       buf[-1] = (i == array_size-1) ? '\n' : ' ';
-               }
+               buf += len;
+               bufsize -= len;
        }
-
-       ret++;          /* \0 */
-       if (buf)
-               *buf = '\0';
-
        return ret;
 }
 
-static char *format_array_alloc(const char *fmt, u32 *array,
-                                               u32 array_size)
+static int u32_array_open(struct inode *inode, struct file *file)
 {
-       size_t len = format_array(NULL, 0, fmt, array, array_size);
-       char *ret;
-
-       ret = kmalloc(len, GFP_KERNEL);
-       if (ret == NULL)
-               return NULL;
+       struct array_data *data = inode->i_private;
+       int size, elements = data->elements;
+       char *buf;
+
+       /*
+        * Max size:
+        *  - 10 digits + ' '/'\n' = 11 bytes per number
+        *  - terminating NUL character
+        */
+       size = elements*11;
+       buf = kmalloc(size+1, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+       buf[size] = 0;
+
+       file->private_data = buf;
+       u32_format_array(buf, size, data->array, data->elements);
 
-       format_array(ret, len, fmt, array, array_size);
-       return ret;
+       return nonseekable_open(inode, file);
 }
 
 static ssize_t u32_array_read(struct file *file, char __user *buf, size_t len,
                              loff_t *ppos)
 {
-       struct inode *inode = file->f_path.dentry->d_inode;
-       struct array_data *data = inode->i_private;
-       size_t size;
-
-       if (*ppos == 0) {
-               if (file->private_data) {
-                       kfree(file->private_data);
-                       file->private_data = NULL;
-               }
-
-               file->private_data = format_array_alloc("%u", data->array,
-                                                             data->elements);
-       }
-
-       size = 0;
-       if (file->private_data)
-               size = strlen(file->private_data);
+       size_t size = strlen(file->private_data);
 
        return simple_read_from_buffer(buf, len, ppos,
                                        file->private_data, size);
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;
index d7a9dd735e1e429a1787d8b0e8e1c9ddde5eff10..933b7930b8636da970a627d571388b11e8dabde7 100644 (file)
@@ -96,6 +96,7 @@ xfs_buf_lru_add(
                atomic_inc(&bp->b_hold);
                list_add_tail(&bp->b_lru, &btp->bt_lru);
                btp->bt_lru_nr++;
+               bp->b_lru_flags &= ~_XBF_LRU_DISPOSE;
        }
        spin_unlock(&btp->bt_lru_lock);
 }
@@ -154,7 +155,8 @@ xfs_buf_stale(
                struct xfs_buftarg *btp = bp->b_target;
 
                spin_lock(&btp->bt_lru_lock);
-               if (!list_empty(&bp->b_lru)) {
+               if (!list_empty(&bp->b_lru) &&
+                   !(bp->b_lru_flags & _XBF_LRU_DISPOSE)) {
                        list_del_init(&bp->b_lru);
                        btp->bt_lru_nr--;
                        atomic_dec(&bp->b_hold);
@@ -1501,6 +1503,7 @@ xfs_buftarg_shrink(
                 */
                list_move(&bp->b_lru, &dispose);
                btp->bt_lru_nr--;
+               bp->b_lru_flags |= _XBF_LRU_DISPOSE;
        }
        spin_unlock(&btp->bt_lru_lock);
 
index d03b73b9604e3d55d93f1fdc08201512b01449dd..7c0b6a0a1557c0d30db4b94e4bc27879d2614537 100644 (file)
@@ -38,27 +38,28 @@ typedef enum {
        XBRW_ZERO = 3,                  /* Zero target memory */
 } xfs_buf_rw_t;
 
-#define XBF_READ       (1 << 0) /* buffer intended for reading from device */
-#define XBF_WRITE      (1 << 1) /* buffer intended for writing to device */
-#define XBF_READ_AHEAD (1 << 2) /* asynchronous read-ahead */
-#define XBF_ASYNC      (1 << 4) /* initiator will not wait for completion */
-#define XBF_DONE       (1 << 5) /* all pages in the buffer uptodate */
-#define XBF_STALE      (1 << 6) /* buffer has been staled, do not find it */
+#define XBF_READ        (1 << 0) /* buffer intended for reading from device */
+#define XBF_WRITE       (1 << 1) /* buffer intended for writing to device */
+#define XBF_READ_AHEAD  (1 << 2) /* asynchronous read-ahead */
+#define XBF_ASYNC       (1 << 4) /* initiator will not wait for completion */
+#define XBF_DONE        (1 << 5) /* all pages in the buffer uptodate */
+#define XBF_STALE       (1 << 6) /* buffer has been staled, do not find it */
 
 /* I/O hints for the BIO layer */
-#define XBF_SYNCIO     (1 << 10)/* treat this buffer as synchronous I/O */
-#define XBF_FUA                (1 << 11)/* force cache write through mode */
-#define XBF_FLUSH      (1 << 12)/* flush the disk cache before a write */
+#define XBF_SYNCIO      (1 << 10)/* treat this buffer as synchronous I/O */
+#define XBF_FUA                 (1 << 11)/* force cache write through mode */
+#define XBF_FLUSH       (1 << 12)/* flush the disk cache before a write */
 
 /* flags used only as arguments to access routines */
-#define XBF_TRYLOCK    (1 << 16)/* lock requested, but do not wait */
-#define XBF_UNMAPPED   (1 << 17)/* do not map the buffer */
+#define XBF_TRYLOCK     (1 << 16)/* lock requested, but do not wait */
+#define XBF_UNMAPPED    (1 << 17)/* do not map the buffer */
 
 /* flags used only internally */
-#define _XBF_PAGES     (1 << 20)/* backed by refcounted pages */
-#define _XBF_KMEM      (1 << 21)/* backed by heap memory */
-#define _XBF_DELWRI_Q  (1 << 22)/* buffer on a delwri queue */
-#define _XBF_COMPOUND  (1 << 23)/* compound buffer */
+#define _XBF_PAGES      (1 << 20)/* backed by refcounted pages */
+#define _XBF_KMEM       (1 << 21)/* backed by heap memory */
+#define _XBF_DELWRI_Q   (1 << 22)/* buffer on a delwri queue */
+#define _XBF_COMPOUND   (1 << 23)/* compound buffer */
+#define _XBF_LRU_DISPOSE (1 << 24)/* buffer being discarded */
 
 typedef unsigned int xfs_buf_flags_t;
 
@@ -72,12 +73,13 @@ typedef unsigned int xfs_buf_flags_t;
        { XBF_SYNCIO,           "SYNCIO" }, \
        { XBF_FUA,              "FUA" }, \
        { XBF_FLUSH,            "FLUSH" }, \
-       { XBF_TRYLOCK,          "TRYLOCK" },    /* should never be set */\
+       { XBF_TRYLOCK,          "TRYLOCK" },    /* should never be set */\
        { XBF_UNMAPPED,         "UNMAPPED" },   /* ditto */\
        { _XBF_PAGES,           "PAGES" }, \
        { _XBF_KMEM,            "KMEM" }, \
        { _XBF_DELWRI_Q,        "DELWRI_Q" }, \
-       { _XBF_COMPOUND,        "COMPOUND" }
+       { _XBF_COMPOUND,        "COMPOUND" }, \
+       { _XBF_LRU_DISPOSE,     "LRU_DISPOSE" }
 
 typedef struct xfs_buftarg {
        dev_t                   bt_dev;
@@ -124,7 +126,12 @@ typedef struct xfs_buf {
        xfs_buf_flags_t         b_flags;        /* status flags */
        struct semaphore        b_sema;         /* semaphore for lockables */
 
+       /*
+        * concurrent access to b_lru and b_lru_flags are protected by
+        * bt_lru_lock and not by b_sema
+        */
        struct list_head        b_lru;          /* lru list */
+       xfs_buf_flags_t         b_lru_flags;    /* internal lru status flags */
        wait_queue_head_t       b_waiters;      /* unpin waiters */
        struct list_head        b_list;
        struct xfs_perag        *b_pag;         /* contains rbtree root */
index bdaf4cb9f4a2d19fc8b781f232f61d88c529ac2a..19e2380fb8679d2e8641e691eaeb0b200456bfb4 100644 (file)
@@ -919,6 +919,7 @@ xfs_fs_put_super(
        struct xfs_mount        *mp = XFS_M(sb);
 
        xfs_filestream_unmount(mp);
+       cancel_delayed_work_sync(&mp->m_sync_work);
        xfs_unmountfs(mp);
        xfs_syncd_stop(mp);
        xfs_freesb(mp);
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 bde976ee068d380a807a2d08ee609b51f33abde8..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>
@@ -208,6 +179,7 @@ struct acpi_device_pnp {
        struct list_head ids;           /* _HID and _CIDs */
        acpi_device_name device_name;   /* Driver-determined */
        acpi_device_class device_class; /*        "          */
+       union acpi_object *str_obj;     /* unicode string for _STR method */
 };
 
 #define acpi_device_bid(d)     ((d)->pnp.bus_id)
@@ -282,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 */
@@ -304,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)
@@ -381,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
  */
@@ -394,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 594b419b7d20229cf79715b1250124491abe4ca6..2451f1f7a1d969f29bb2a3137c846566bfaf614a 100644 (file)
@@ -91,7 +91,7 @@
 {                                                      \
        typeof(x) __x = x;                              \
        typeof(divisor) __d = divisor;                  \
-       (((typeof(x))-1) >= 0 || (__x) >= 0) ?          \
+       (((typeof(x))-1) > 0 || (__x) > 0) ?            \
                (((__x) + ((__d) / 2)) / (__d)) :       \
                (((__x) - ((__d) / 2)) / (__d));        \
 }                                                      \
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 33ed9d605f9195eafaaeec43b7bf1d577dd8d59a..bdb41612bfec621e1aaba5e2468c5b01c6131770 100644 (file)
@@ -274,6 +274,8 @@ struct perf_event_attr {
        __u64   branch_sample_type; /* enum branch_sample_type */
 };
 
+#define perf_flags(attr)       (*(&(attr)->read_format + 1))
+
 /*
  * Ioctls that can be done on a perf event fd:
  */
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 22e61fdf75a2bd46a656e164e046a006acd43343..28e493b5b94c9ba6d946d728a0908c84e34294db 100644 (file)
@@ -84,6 +84,8 @@ struct xfrm_replay_state {
        __u32   bitmap;
 };
 
+#define XFRMA_REPLAY_ESN_MAX   4096
+
 struct xfrm_replay_state_esn {
        unsigned int    bmp_len;
        __u32           oseq;
index 0fedbd8d747a049db1810fdc325b032d62782b1b..9fc7114159e885031550abedebf67c74f08bde76 100644 (file)
@@ -111,9 +111,8 @@ struct rt6_info {
        struct inet6_dev                *rt6i_idev;
        unsigned long                   _rt6i_peer;
 
-#ifdef CONFIG_XFRM
-       u32                             rt6i_flow_cache_genid;
-#endif
+       u32                             rt6i_genid;
+
        /* more non-fragment space at head required */
        unsigned short                  rt6i_nfheader_len;
 
index ae1cd6c9ba521bb6ca9a57706b4ca77180bdcc7a..fd87963a0ea5878cecae892541b9fc9f79e64814 100644 (file)
@@ -102,6 +102,7 @@ struct net {
 #endif
        struct netns_ipvs       *ipvs;
        struct sock             *diag_nlsk;
+       atomic_t                rt_genid;
 };
 
 
@@ -300,5 +301,14 @@ static inline void unregister_net_sysctl_table(struct ctl_table_header *header)
 }
 #endif
 
+static inline int rt_genid(struct net *net)
+{
+       return atomic_read(&net->rt_genid);
+}
+
+static inline void rt_genid_bump(struct net *net)
+{
+       atomic_inc(&net->rt_genid);
+}
 
 #endif /* __NET_NET_NAMESPACE_H */
index 1474dd65c66f558999a70f38c081dea247fbee5a..eb24dbccd81e81aff5fac76c8792e93df66e7bb6 100644 (file)
@@ -65,7 +65,6 @@ struct netns_ipv4 {
        unsigned int sysctl_ping_group_range[2];
        long sysctl_tcp_mem[3];
 
-       atomic_t rt_genid;
        atomic_t dev_addr_genid;
 
 #ifdef CONFIG_IP_MROUTE
index 776a27f1ab78ef5a385ef8b8d2f21b9e0101e115..da22243d27600cd66b5fb70da61f5cadc05d5468 100644 (file)
@@ -108,7 +108,7 @@ extern struct ip_rt_acct __percpu *ip_rt_acct;
 
 struct in_device;
 extern int             ip_rt_init(void);
-extern void            rt_cache_flush(struct net *net, int how);
+extern void            rt_cache_flush(struct net *net);
 extern void            rt_flush_dev(struct net_device *dev);
 extern struct rtable *__ip_route_output_key(struct net *, struct flowi4 *flp);
 extern struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp,
index 5f889f16b0c891dbedafd65686c48688aa7110da..08fa27244da740787539bd391ef3d61dc8060158 100644 (file)
@@ -214,7 +214,7 @@ TRACE_EVENT(mm_page_alloc,
 
        TP_printk("page=%p pfn=%lu order=%d migratetype=%d gfp_flags=%s",
                __entry->page,
-               page_to_pfn(__entry->page),
+               __entry->page ? page_to_pfn(__entry->page) : 0,
                __entry->order,
                __entry->migratetype,
                show_gfp_flags(__entry->gfp_flags))
@@ -240,7 +240,7 @@ DECLARE_EVENT_CLASS(mm_page,
 
        TP_printk("page=%p pfn=%lu order=%u migratetype=%d percpu_refill=%d",
                __entry->page,
-               page_to_pfn(__entry->page),
+               __entry->page ? page_to_pfn(__entry->page) : 0,
                __entry->order,
                __entry->migratetype,
                __entry->order == 0)
index 11e27c3af3cb45c63d9c689442096b4afd66c55f..f19fff8650e93075aae1717034f29898f1199646 100644 (file)
@@ -187,6 +187,7 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
                    struct gnttab_map_grant_ref *kmap_ops,
                    struct page **pages, unsigned int count);
 int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
-                     struct page **pages, unsigned int count, bool clear_pte);
+                     struct gnttab_map_grant_ref *kunmap_ops,
+                     struct page **pages, unsigned int count);
 
 #endif /* __ASM_GNTTAB_H__ */
index 34e5eac81424d98738246415a85d1a98a042bef1..d3b91e75cecd0df7895033aff87f588c6ba2d4df 100644 (file)
@@ -303,10 +303,11 @@ void getnstimeofday(struct timespec *ts)
                seq = read_seqbegin(&tk->lock);
 
                ts->tv_sec = tk->xtime_sec;
-               ts->tv_nsec = timekeeping_get_ns(tk);
+               nsecs = timekeeping_get_ns(tk);
 
        } while (read_seqretry(&tk->lock, seq));
 
+       ts->tv_nsec = 0;
        timespec_add_ns(ts, nsecs);
 }
 EXPORT_SYMBOL(getnstimeofday);
@@ -345,6 +346,7 @@ void ktime_get_ts(struct timespec *ts)
 {
        struct timekeeper *tk = &timekeeper;
        struct timespec tomono;
+       s64 nsec;
        unsigned int seq;
 
        WARN_ON(timekeeping_suspended);
@@ -352,13 +354,14 @@ void ktime_get_ts(struct timespec *ts)
        do {
                seq = read_seqbegin(&tk->lock);
                ts->tv_sec = tk->xtime_sec;
-               ts->tv_nsec = timekeeping_get_ns(tk);
+               nsec = timekeeping_get_ns(tk);
                tomono = tk->wall_to_monotonic;
 
        } while (read_seqretry(&tk->lock, seq));
 
-       set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec,
-                               ts->tv_nsec + tomono.tv_nsec);
+       ts->tv_sec += tomono.tv_sec;
+       ts->tv_nsec = 0;
+       timespec_add_ns(ts, nsec + tomono.tv_nsec);
 }
 EXPORT_SYMBOL_GPL(ktime_get_ts);
 
@@ -1244,6 +1247,7 @@ void get_monotonic_boottime(struct timespec *ts)
 {
        struct timekeeper *tk = &timekeeper;
        struct timespec tomono, sleep;
+       s64 nsec;
        unsigned int seq;
 
        WARN_ON(timekeeping_suspended);
@@ -1251,14 +1255,15 @@ void get_monotonic_boottime(struct timespec *ts)
        do {
                seq = read_seqbegin(&tk->lock);
                ts->tv_sec = tk->xtime_sec;
-               ts->tv_nsec = timekeeping_get_ns(tk);
+               nsec = timekeeping_get_ns(tk);
                tomono = tk->wall_to_monotonic;
                sleep = tk->total_sleep_time;
 
        } while (read_seqretry(&tk->lock, seq));
 
-       set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec + sleep.tv_sec,
-                       ts->tv_nsec + tomono.tv_nsec + sleep.tv_nsec);
+       ts->tv_sec += tomono.tv_sec + sleep.tv_sec;
+       ts->tv_nsec = 0;
+       timespec_add_ns(ts, nsec + tomono.tv_nsec + sleep.tv_nsec);
 }
 EXPORT_SYMBOL_GPL(get_monotonic_boottime);
 
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 a081ce1c05140d43473dbc02518bfc51f913f6eb..cebaae7e148b7f8a88f8b265bb625256363cde5a 100644 (file)
@@ -20,8 +20,8 @@
 #ifndef _NET_BATMAN_ADV_BITARRAY_H_
 #define _NET_BATMAN_ADV_BITARRAY_H_
 
-/* returns true if the corresponding bit in the given seq_bits indicates true
- * and curr_seqno is within range of last_seqno
+/* Returns 1 if the corresponding bit in the given seq_bits indicates true
+ * and curr_seqno is within range of last_seqno. Otherwise returns 0.
  */
 static inline int batadv_test_bit(const unsigned long *seq_bits,
                                  uint32_t last_seqno, uint32_t curr_seqno)
@@ -32,7 +32,7 @@ static inline int batadv_test_bit(const unsigned long *seq_bits,
        if (diff < 0 || diff >= BATADV_TQ_LOCAL_WINDOW_SIZE)
                return 0;
        else
-               return  test_bit(diff, seq_bits);
+               return test_bit(diff, seq_bits) != 0;
 }
 
 /* turn corresponding bit on, so we can remember that we got the packet */
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 5e5f5b410e0b24f751eb158ad235fe16bfa3ee6f..1eaacf10d19d9ea078f49f225423dff96ebee8a2 100644 (file)
@@ -58,7 +58,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
        switch (cmd) {
        case BNEPCONNADD:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
 
                if (copy_from_user(&ca, argp, sizeof(ca)))
                        return -EFAULT;
@@ -84,7 +84,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
 
        case BNEPCONNDEL:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
 
                if (copy_from_user(&cd, argp, sizeof(cd)))
                        return -EFAULT;
index 311668d14571626dac778201a65ed21f05c72cbe..32dc83dcb6b2edd669d7a9ce2fc00480d249b4be 100644 (file)
@@ -72,7 +72,7 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
        switch (cmd) {
        case CMTPCONNADD:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
 
                if (copy_from_user(&ca, argp, sizeof(ca)))
                        return -EFAULT;
@@ -97,7 +97,7 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
 
        case CMTPCONNDEL:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
 
                if (copy_from_user(&cd, argp, sizeof(cd)))
                        return -EFAULT;
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 19fdac78e555b97c44dd6826bc60ef89a888395b..d5ace1eda3ed8c3fd06f422bb7cbf340d3187c6c 100644 (file)
@@ -490,7 +490,7 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
        switch (cmd) {
        case HCISETRAW:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
 
                if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
                        return -EPERM;
@@ -510,12 +510,12 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
 
        case HCIBLOCKADDR:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
                return hci_sock_blacklist_add(hdev, (void __user *) arg);
 
        case HCIUNBLOCKADDR:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
                return hci_sock_blacklist_del(hdev, (void __user *) arg);
 
        default:
@@ -546,22 +546,22 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
 
        case HCIDEVUP:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
                return hci_dev_open(arg);
 
        case HCIDEVDOWN:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
                return hci_dev_close(arg);
 
        case HCIDEVRESET:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
                return hci_dev_reset(arg);
 
        case HCIDEVRESTAT:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
                return hci_dev_reset_stat(arg);
 
        case HCISETSCAN:
@@ -573,7 +573,7 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
        case HCISETACLMTU:
        case HCISETSCOMTU:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
                return hci_dev_cmd(cmd, argp);
 
        case HCIINQUIRY:
index 18b3f6892a36847de621954cbae7358ae719c0be..b24fb3bd862555c81746fe664e7f90270cc6a2df 100644 (file)
@@ -56,7 +56,7 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
        switch (cmd) {
        case HIDPCONNADD:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
 
                if (copy_from_user(&ca, argp, sizeof(ca)))
                        return -EFAULT;
@@ -91,7 +91,7 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
 
        case HIDPCONNDEL:
                if (!capable(CAP_NET_ADMIN))
-                       return -EACCES;
+                       return -EPERM;
 
                if (copy_from_user(&cd, argp, sizeof(cd)))
                        return -EFAULT;
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 d7fe32c946c1a472b46f086929badaea6900d432..89e33a5d4d932c54af74a08cb080809affc7dd67 100644 (file)
@@ -2134,7 +2134,8 @@ static bool can_checksum_protocol(netdev_features_t features, __be16 protocol)
 static netdev_features_t harmonize_features(struct sk_buff *skb,
        __be16 protocol, netdev_features_t features)
 {
-       if (!can_checksum_protocol(features, protocol)) {
+       if (skb->ip_summed != CHECKSUM_NONE &&
+           !can_checksum_protocol(features, protocol)) {
                features &= ~NETIF_F_ALL_CSUM;
                features &= ~NETIF_F_SG;
        } else if (illegal_highdma(skb->dev, skb)) {
@@ -3322,7 +3323,7 @@ ncls:
 
        if (pt_prev) {
                if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC)))
-                       ret = -ENOMEM;
+                       goto drop;
                else
                        ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
        } else {
index fe00d12081671a22c65d05d290069d7358dda1d6..e33ebae519c8c3283dadde917cdf46d413229a54 100644 (file)
@@ -3502,7 +3502,9 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
        if (!skb_cloned(from))
                skb_shinfo(from)->nr_frags = 0;
 
-       /* if the skb is cloned this does nothing since we set nr_frags to 0 */
+       /* if the skb is not cloned this does nothing
+        * since we set nr_frags to 0.
+        */
        for (i = 0; i < skb_shinfo(from)->nr_frags; i++)
                skb_frag_ref(from, i);
 
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 77e87aff419ab105ef3ad3b5f852ef676b18a827..47800459e4cb341c395f54f2d161c300a112c1cf 100644 (file)
@@ -1225,7 +1225,7 @@ static int arp_netdev_event(struct notifier_block *this, unsigned long event,
        switch (event) {
        case NETDEV_CHANGEADDR:
                neigh_changeaddr(&arp_tbl, dev);
-               rt_cache_flush(dev_net(dev), 0);
+               rt_cache_flush(dev_net(dev));
                break;
        default:
                break;
index 44bf82e3aef7d6d4b5afc39a357b7da6d85a44e7..e12fad773852b5271afafa414ffc1f2706ff4428 100644 (file)
@@ -725,7 +725,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
                break;
 
        case SIOCSIFFLAGS:
-               ret = -EACCES;
+               ret = -EPERM;
                if (!capable(CAP_NET_ADMIN))
                        goto out;
                break;
@@ -733,7 +733,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
        case SIOCSIFBRDADDR:    /* Set the broadcast address */
        case SIOCSIFDSTADDR:    /* Set the destination address */
        case SIOCSIFNETMASK:    /* Set the netmask for the interface */
-               ret = -EACCES;
+               ret = -EPERM;
                if (!capable(CAP_NET_ADMIN))
                        goto out;
                ret = -EINVAL;
@@ -1503,7 +1503,7 @@ static int devinet_conf_proc(ctl_table *ctl, int write,
                if (i == IPV4_DEVCONF_ACCEPT_LOCAL - 1 ||
                    i == IPV4_DEVCONF_ROUTE_LOCALNET - 1)
                        if ((new_value == 0) && (old_value != 0))
-                               rt_cache_flush(net, 0);
+                               rt_cache_flush(net);
        }
 
        return ret;
@@ -1537,7 +1537,7 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
                                dev_disable_lro(idev->dev);
                        }
                        rtnl_unlock();
-                       rt_cache_flush(net, 0);
+                       rt_cache_flush(net);
                }
        }
 
@@ -1554,7 +1554,7 @@ static int ipv4_doint_and_flush(ctl_table *ctl, int write,
        struct net *net = ctl->extra2;
 
        if (write && *valp != val)
-               rt_cache_flush(net, 0);
+               rt_cache_flush(net);
 
        return ret;
 }
index c43ae3fba7921e590859cea407ba9b9e030b16be..8e2b475da9faca9f7e27482f7e416908e7cf66fa 100644 (file)
@@ -148,7 +148,7 @@ static void fib_flush(struct net *net)
        }
 
        if (flushed)
-               rt_cache_flush(net, -1);
+               rt_cache_flush(net);
 }
 
 /*
@@ -999,11 +999,11 @@ static void nl_fib_lookup_exit(struct net *net)
        net->ipv4.fibnl = NULL;
 }
 
-static void fib_disable_ip(struct net_device *dev, int force, int delay)
+static void fib_disable_ip(struct net_device *dev, int force)
 {
        if (fib_sync_down_dev(dev, force))
                fib_flush(dev_net(dev));
-       rt_cache_flush(dev_net(dev), delay);
+       rt_cache_flush(dev_net(dev));
        arp_ifdown(dev);
 }
 
@@ -1020,7 +1020,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
                fib_sync_up(dev);
 #endif
                atomic_inc(&net->ipv4.dev_addr_genid);
-               rt_cache_flush(dev_net(dev), -1);
+               rt_cache_flush(dev_net(dev));
                break;
        case NETDEV_DOWN:
                fib_del_ifaddr(ifa, NULL);
@@ -1029,9 +1029,9 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
                        /* Last address was deleted from this interface.
                         * Disable IP.
                         */
-                       fib_disable_ip(dev, 1, 0);
+                       fib_disable_ip(dev, 1);
                } else {
-                       rt_cache_flush(dev_net(dev), -1);
+                       rt_cache_flush(dev_net(dev));
                }
                break;
        }
@@ -1045,7 +1045,7 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
        struct net *net = dev_net(dev);
 
        if (event == NETDEV_UNREGISTER) {
-               fib_disable_ip(dev, 2, -1);
+               fib_disable_ip(dev, 2);
                rt_flush_dev(dev);
                return NOTIFY_DONE;
        }
@@ -1062,14 +1062,14 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
                fib_sync_up(dev);
 #endif
                atomic_inc(&net->ipv4.dev_addr_genid);
-               rt_cache_flush(dev_net(dev), -1);
+               rt_cache_flush(dev_net(dev));
                break;
        case NETDEV_DOWN:
-               fib_disable_ip(dev, 0, 0);
+               fib_disable_ip(dev, 0);
                break;
        case NETDEV_CHANGEMTU:
        case NETDEV_CHANGE:
-               rt_cache_flush(dev_net(dev), 0);
+               rt_cache_flush(dev_net(dev));
                break;
        case NETDEV_UNREGISTER_BATCH:
                break;
index a83d74e498d23af8c104bc3d68eca5ca4a8ac228..274309d3aded0ffbf351dbf5f4ad128d87ff5a0b 100644 (file)
@@ -259,7 +259,7 @@ static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule)
 
 static void fib4_rule_flush_cache(struct fib_rules_ops *ops)
 {
-       rt_cache_flush(ops->fro_net, -1);
+       rt_cache_flush(ops->fro_net);
 }
 
 static const struct fib_rules_ops __net_initdata fib4_rules_ops_template = {
index 57bd978483e1fe47a96c964f356432e51e62d6b7..d1b93595b4a7dce1e7701bb713bd5f0bc5adf1f6 100644 (file)
@@ -1286,7 +1286,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
 
                        fib_release_info(fi_drop);
                        if (state & FA_S_ACCESSED)
-                               rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
+                               rt_cache_flush(cfg->fc_nlinfo.nl_net);
                        rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
                                tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE);
 
@@ -1333,7 +1333,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
        list_add_tail_rcu(&new_fa->fa_list,
                          (fa ? &fa->fa_list : fa_head));
 
-       rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
+       rt_cache_flush(cfg->fc_nlinfo.nl_net);
        rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id,
                  &cfg->fc_nlinfo, 0);
 succeeded:
@@ -1708,7 +1708,7 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
                trie_leaf_remove(t, l);
 
        if (fa->fa_state & FA_S_ACCESSED)
-               rt_cache_flush(cfg->fc_nlinfo.nl_net, -1);
+               rt_cache_flush(cfg->fc_nlinfo.nl_net);
 
        fib_release_info(fa->fa_info);
        alias_free_mem_rcu(fa);
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 82cf2a722b2310803ec603f60d59cdf819481a4a..fd9af60397b590dd817e02a52a33fdf99bb24c8e 100644 (file)
@@ -202,11 +202,6 @@ EXPORT_SYMBOL(ip_tos2prio);
 static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat);
 #define RT_CACHE_STAT_INC(field) __this_cpu_inc(rt_cache_stat.field)
 
-static inline int rt_genid(struct net *net)
-{
-       return atomic_read(&net->ipv4.rt_genid);
-}
-
 #ifdef CONFIG_PROC_FS
 static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
 {
@@ -447,27 +442,9 @@ static inline bool rt_is_expired(const struct rtable *rth)
        return rth->rt_genid != rt_genid(dev_net(rth->dst.dev));
 }
 
-/*
- * Perturbation of rt_genid by a small quantity [1..256]
- * Using 8 bits of shuffling ensure we can call rt_cache_invalidate()
- * many times (2^24) without giving recent rt_genid.
- * Jenkins hash is strong enough that litle changes of rt_genid are OK.
- */
-static void rt_cache_invalidate(struct net *net)
+void rt_cache_flush(struct net *net)
 {
-       unsigned char shuffle;
-
-       get_random_bytes(&shuffle, sizeof(shuffle));
-       atomic_add(shuffle + 1U, &net->ipv4.rt_genid);
-}
-
-/*
- * delay < 0  : invalidate cache (fast : entries will be deleted later)
- * delay >= 0 : invalidate & flush cache (can be long)
- */
-void rt_cache_flush(struct net *net, int delay)
-{
-       rt_cache_invalidate(net);
+       rt_genid_bump(net);
 }
 
 static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst,
@@ -2345,7 +2322,7 @@ int ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb)
 
 void ip_rt_multicast_event(struct in_device *in_dev)
 {
-       rt_cache_flush(dev_net(in_dev->dev), 0);
+       rt_cache_flush(dev_net(in_dev->dev));
 }
 
 #ifdef CONFIG_SYSCTL
@@ -2354,16 +2331,7 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
                                        size_t *lenp, loff_t *ppos)
 {
        if (write) {
-               int flush_delay;
-               ctl_table ctl;
-               struct net *net;
-
-               memcpy(&ctl, __ctl, sizeof(ctl));
-               ctl.data = &flush_delay;
-               proc_dointvec(&ctl, write, buffer, lenp, ppos);
-
-               net = (struct net *)__ctl->extra1;
-               rt_cache_flush(net, flush_delay);
+               rt_cache_flush((struct net *)__ctl->extra1);
                return 0;
        }
 
@@ -2533,8 +2501,7 @@ static __net_initdata struct pernet_operations sysctl_route_ops = {
 
 static __net_init int rt_genid_init(struct net *net)
 {
-       get_random_bytes(&net->ipv4.rt_genid,
-                        sizeof(net->ipv4.rt_genid));
+       atomic_set(&net->rt_genid, 0);
        get_random_bytes(&net->ipv4.dev_addr_genid,
                         sizeof(net->ipv4.dev_addr_genid));
        return 0;
index 2109ff4a1dafd489fbe0e2240075432df4517374..5f64193418216393448ec9d8e839f83e85636716 100644 (file)
@@ -1762,8 +1762,14 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                }
 
 #ifdef CONFIG_NET_DMA
-               if (tp->ucopy.dma_chan)
-                       dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+               if (tp->ucopy.dma_chan) {
+                       if (tp->rcv_wnd == 0 &&
+                           !skb_queue_empty(&sk->sk_async_wait_queue)) {
+                               tcp_service_net_dma(sk, true);
+                               tcp_cleanup_rbuf(sk, copied);
+                       } else
+                               dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+               }
 #endif
                if (copied >= target) {
                        /* Do not sleep, just process backlog. */
@@ -2325,10 +2331,17 @@ static int tcp_repair_options_est(struct tcp_sock *tp,
                        tp->rx_opt.mss_clamp = opt.opt_val;
                        break;
                case TCPOPT_WINDOW:
-                       if (opt.opt_val > 14)
-                               return -EFBIG;
+                       {
+                               u16 snd_wscale = opt.opt_val & 0xFFFF;
+                               u16 rcv_wscale = opt.opt_val >> 16;
+
+                               if (snd_wscale > 14 || rcv_wscale > 14)
+                                       return -EFBIG;
 
-                       tp->rx_opt.snd_wscale = opt.opt_val;
+                               tp->rx_opt.snd_wscale = snd_wscale;
+                               tp->rx_opt.rcv_wscale = rcv_wscale;
+                               tp->rx_opt.wscale_ok = 1;
+                       }
                        break;
                case TCPOPT_SACK_PERM:
                        if (opt.opt_val != 0)
index 6e38c6c23caa69601216e193507460663c1926ec..d377f4854cb853c454541062fb6f8438608d470c 100644 (file)
@@ -4661,7 +4661,7 @@ queue_and_out:
 
                if (eaten > 0)
                        kfree_skb_partial(skb, fragstolen);
-               else if (!sock_flag(sk, SOCK_DEAD))
+               if (!sock_flag(sk, SOCK_DEAD))
                        sk->sk_data_ready(sk, 0);
                return;
        }
@@ -5556,8 +5556,7 @@ no_ack:
 #endif
                        if (eaten)
                                kfree_skb_partial(skb, fragstolen);
-                       else
-                               sk->sk_data_ready(sk, 0);
+                       sk->sk_data_ready(sk, 0);
                        return 0;
                }
        }
index 0251a6005be8ff8d35cffe7fb0e2611b43296158..c4f934176cabd92ebfb4bba774335427b9f8932a 100644 (file)
@@ -175,33 +175,12 @@ void __inet6_csk_dst_store(struct sock *sk, struct dst_entry *dst,
                           const struct in6_addr *saddr)
 {
        __ip6_dst_store(sk, dst, daddr, saddr);
-
-#ifdef CONFIG_XFRM
-       {
-               struct rt6_info *rt = (struct rt6_info  *)dst;
-               rt->rt6i_flow_cache_genid = atomic_read(&flow_cache_genid);
-       }
-#endif
 }
 
 static inline
 struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
 {
-       struct dst_entry *dst;
-
-       dst = __sk_dst_check(sk, cookie);
-
-#ifdef CONFIG_XFRM
-       if (dst) {
-               struct rt6_info *rt = (struct rt6_info *)dst;
-               if (rt->rt6i_flow_cache_genid != atomic_read(&flow_cache_genid)) {
-                       __sk_dst_reset(sk);
-                       dst = NULL;
-               }
-       }
-#endif
-
-       return dst;
+       return __sk_dst_check(sk, cookie);
 }
 
 static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
index 13690d650c3e227de6579ed6ee489fbff1cbddef..286acfc21250cd760565b182cbc2d3d4490463dd 100644 (file)
@@ -819,6 +819,10 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nl_info *info)
                                        offsetof(struct rt6_info, rt6i_src),
                                        allow_create, replace_required);
 
+                       if (IS_ERR(sn)) {
+                               err = PTR_ERR(sn);
+                               sn = NULL;
+                       }
                        if (!sn) {
                                /* If it is failed, discard just allocated
                                   root, and then (in st_failure) stale node
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 8e80fd279100d7d18d111eff1be73f10fdd6eeaf..854e4018d205c826032633ce2641cbc1af2c057a 100644 (file)
@@ -226,7 +226,7 @@ static struct rt6_info ip6_null_entry_template = {
        .dst = {
                .__refcnt       = ATOMIC_INIT(1),
                .__use          = 1,
-               .obsolete       = -1,
+               .obsolete       = DST_OBSOLETE_FORCE_CHK,
                .error          = -ENETUNREACH,
                .input          = ip6_pkt_discard,
                .output         = ip6_pkt_discard_out,
@@ -246,7 +246,7 @@ static struct rt6_info ip6_prohibit_entry_template = {
        .dst = {
                .__refcnt       = ATOMIC_INIT(1),
                .__use          = 1,
-               .obsolete       = -1,
+               .obsolete       = DST_OBSOLETE_FORCE_CHK,
                .error          = -EACCES,
                .input          = ip6_pkt_prohibit,
                .output         = ip6_pkt_prohibit_out,
@@ -261,7 +261,7 @@ static struct rt6_info ip6_blk_hole_entry_template = {
        .dst = {
                .__refcnt       = ATOMIC_INIT(1),
                .__use          = 1,
-               .obsolete       = -1,
+               .obsolete       = DST_OBSOLETE_FORCE_CHK,
                .error          = -EINVAL,
                .input          = dst_discard,
                .output         = dst_discard,
@@ -281,13 +281,14 @@ static inline struct rt6_info *ip6_dst_alloc(struct net *net,
                                             struct fib6_table *table)
 {
        struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
-                                       0, DST_OBSOLETE_NONE, flags);
+                                       0, DST_OBSOLETE_FORCE_CHK, flags);
 
        if (rt) {
                struct dst_entry *dst = &rt->dst;
 
                memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
                rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers);
+               rt->rt6i_genid = rt_genid(net);
        }
        return rt;
 }
@@ -1031,6 +1032,13 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
 
        rt = (struct rt6_info *) dst;
 
+       /* All IPV6 dsts are created with ->obsolete set to the value
+        * DST_OBSOLETE_FORCE_CHK which forces validation calls down
+        * into this function always.
+        */
+       if (rt->rt6i_genid != rt_genid(dev_net(rt->dst.dev)))
+               return NULL;
+
        if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) {
                if (rt->rt6i_peer_genid != rt6_peer_genid()) {
                        if (!rt6_has_peer(rt))
@@ -1397,8 +1405,6 @@ int ip6_route_add(struct fib6_config *cfg)
                goto out;
        }
 
-       rt->dst.obsolete = -1;
-
        if (cfg->fc_flags & RTF_EXPIRES)
                rt6_set_expires(rt, jiffies +
                                clock_t_to_jiffies(cfg->fc_expires));
@@ -2080,7 +2086,6 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
        rt->dst.input = ip6_input;
        rt->dst.output = ip6_output;
        rt->rt6i_idev = idev;
-       rt->dst.obsolete = -1;
 
        rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP;
        if (anycast)
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 1b9024ee963c64f33b9240a0726dd67b83711567..7261eb81974ff9f3761976372c9272db04a62abd 100644 (file)
@@ -601,7 +601,7 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                if (!capable(CAP_NET_BIND_SERVICE)) {
                        dev_put(dev);
                        release_sock(sk);
-                       return -EACCES;
+                       return -EPERM;
                }
                nr->user_addr   = addr->fsa_digipeater[0];
                nr->source_addr = addr->fsa_ax25.sax25_call;
index e4723d31fdd56d6a46b2519afd19d612c7336749..211a212170451c41f352f087dc9e0b3af9e8ae2c 100644 (file)
@@ -865,7 +865,10 @@ static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl)
                if (mask) {
                        struct qfq_group *next = qfq_ffs(q, mask);
                        if (qfq_gt(roundedF, next->F)) {
-                               cl->S = next->F;
+                               if (qfq_gt(limit, next->F))
+                                       cl->S = next->F;
+                               else /* preserve timestamp correctness */
+                                       cl->S = limit;
                                return;
                        }
                }
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 5a2aa17e4d3c4a3667783266ddbb8992a3eff6bd..387848e900783f6e6862c6d2c0b52ab45bbcfe50 100644 (file)
@@ -585,6 +585,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
        xfrm_pol_hold(policy);
        net->xfrm.policy_count[dir]++;
        atomic_inc(&flow_cache_genid);
+       rt_genid_bump(net);
        if (delpol)
                __xfrm_policy_unlink(delpol, dir);
        policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir);
@@ -1763,7 +1764,7 @@ static struct dst_entry *make_blackhole(struct net *net, u16 family,
 
        if (!afinfo) {
                dst_release(dst_orig);
-               ret = ERR_PTR(-EINVAL);
+               return ERR_PTR(-EINVAL);
        } else {
                ret = afinfo->blackhole_route(net, dst_orig);
        }
index e75d8e47f35cab2bdddd1051e6da556ef20eb26c..289f4bf18ff05751c5938c8722b098f6a560ee00 100644 (file)
@@ -123,9 +123,21 @@ static inline int verify_replay(struct xfrm_usersa_info *p,
                                struct nlattr **attrs)
 {
        struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL];
+       struct xfrm_replay_state_esn *rs;
 
-       if ((p->flags & XFRM_STATE_ESN) && !rt)
-               return -EINVAL;
+       if (p->flags & XFRM_STATE_ESN) {
+               if (!rt)
+                       return -EINVAL;
+
+               rs = nla_data(rt);
+
+               if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8)
+                       return -EINVAL;
+
+               if (nla_len(rt) < xfrm_replay_state_esn_len(rs) &&
+                   nla_len(rt) != sizeof(*rs))
+                       return -EINVAL;
+       }
 
        if (!rt)
                return 0;
@@ -370,14 +382,15 @@ static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_es
                                         struct nlattr *rp)
 {
        struct xfrm_replay_state_esn *up;
+       int ulen;
 
        if (!replay_esn || !rp)
                return 0;
 
        up = nla_data(rp);
+       ulen = xfrm_replay_state_esn_len(up);
 
-       if (xfrm_replay_state_esn_len(replay_esn) !=
-                       xfrm_replay_state_esn_len(up))
+       if (nla_len(rp) < ulen || xfrm_replay_state_esn_len(replay_esn) != ulen)
                return -EINVAL;
 
        return 0;
@@ -388,22 +401,28 @@ static int xfrm_alloc_replay_state_esn(struct xfrm_replay_state_esn **replay_esn
                                       struct nlattr *rta)
 {
        struct xfrm_replay_state_esn *p, *pp, *up;
+       int klen, ulen;
 
        if (!rta)
                return 0;
 
        up = nla_data(rta);
+       klen = xfrm_replay_state_esn_len(up);
+       ulen = nla_len(rta) >= klen ? klen : sizeof(*up);
 
-       p = kmemdup(up, xfrm_replay_state_esn_len(up), GFP_KERNEL);
+       p = kzalloc(klen, GFP_KERNEL);
        if (!p)
                return -ENOMEM;
 
-       pp = kmemdup(up, xfrm_replay_state_esn_len(up), GFP_KERNEL);
+       pp = kzalloc(klen, GFP_KERNEL);
        if (!pp) {
                kfree(p);
                return -ENOMEM;
        }
 
+       memcpy(p, up, ulen);
+       memcpy(pp, up, ulen);
+
        *replay_esn = p;
        *preplay_esn = pp;
 
@@ -442,10 +461,11 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *
  * somehow made shareable and move it to xfrm_state.c - JHS
  *
 */
-static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs)
+static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs,
+                                 int update_esn)
 {
        struct nlattr *rp = attrs[XFRMA_REPLAY_VAL];
-       struct nlattr *re = attrs[XFRMA_REPLAY_ESN_VAL];
+       struct nlattr *re = update_esn ? attrs[XFRMA_REPLAY_ESN_VAL] : NULL;
        struct nlattr *lt = attrs[XFRMA_LTIME_VAL];
        struct nlattr *et = attrs[XFRMA_ETIMER_THRESH];
        struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH];
@@ -555,7 +575,7 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
                goto error;
 
        /* override default values from above */
-       xfrm_update_ae_params(x, attrs);
+       xfrm_update_ae_params(x, attrs, 0);
 
        return x;
 
@@ -689,6 +709,7 @@ out:
 
 static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
 {
+       memset(p, 0, sizeof(*p));
        memcpy(&p->id, &x->id, sizeof(p->id));
        memcpy(&p->sel, &x->sel, sizeof(p->sel));
        memcpy(&p->lft, &x->lft, sizeof(p->lft));
@@ -742,7 +763,7 @@ static int copy_to_user_auth(struct xfrm_algo_auth *auth, struct sk_buff *skb)
                return -EMSGSIZE;
 
        algo = nla_data(nla);
-       strcpy(algo->alg_name, auth->alg_name);
+       strncpy(algo->alg_name, auth->alg_name, sizeof(algo->alg_name));
        memcpy(algo->alg_key, auth->alg_key, (auth->alg_key_len + 7) / 8);
        algo->alg_key_len = auth->alg_key_len;
 
@@ -878,6 +899,7 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb,
 {
        struct xfrm_dump_info info;
        struct sk_buff *skb;
+       int err;
 
        skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
        if (!skb)
@@ -888,9 +910,10 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb,
        info.nlmsg_seq = seq;
        info.nlmsg_flags = 0;
 
-       if (dump_one_state(x, 0, &info)) {
+       err = dump_one_state(x, 0, &info);
+       if (err) {
                kfree_skb(skb);
-               return NULL;
+               return ERR_PTR(err);
        }
 
        return skb;
@@ -1317,6 +1340,7 @@ static void copy_from_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy
 
 static void copy_to_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_info *p, int dir)
 {
+       memset(p, 0, sizeof(*p));
        memcpy(&p->sel, &xp->selector, sizeof(p->sel));
        memcpy(&p->lft, &xp->lft, sizeof(p->lft));
        memcpy(&p->curlft, &xp->curlft, sizeof(p->curlft));
@@ -1421,6 +1445,7 @@ static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb)
                struct xfrm_user_tmpl *up = &vec[i];
                struct xfrm_tmpl *kp = &xp->xfrm_vec[i];
 
+               memset(up, 0, sizeof(*up));
                memcpy(&up->id, &kp->id, sizeof(up->id));
                up->family = kp->encap_family;
                memcpy(&up->saddr, &kp->saddr, sizeof(up->saddr));
@@ -1546,6 +1571,7 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb,
 {
        struct xfrm_dump_info info;
        struct sk_buff *skb;
+       int err;
 
        skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!skb)
@@ -1556,9 +1582,10 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb,
        info.nlmsg_seq = seq;
        info.nlmsg_flags = 0;
 
-       if (dump_one_policy(xp, dir, 0, &info) < 0) {
+       err = dump_one_policy(xp, dir, 0, &info);
+       if (err) {
                kfree_skb(skb);
-               return NULL;
+               return ERR_PTR(err);
        }
 
        return skb;
@@ -1822,7 +1849,7 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
                goto out;
 
        spin_lock_bh(&x->lock);
-       xfrm_update_ae_params(x, attrs);
+       xfrm_update_ae_params(x, attrs, 1);
        spin_unlock_bh(&x->lock);
 
        c.event = nlh->nlmsg_type;
index c3f69ae275d1f7710b5f38c02e9daf6b45b947a4..4d908d16c035c4e6c582e254e531998e7f6156ae 100644 (file)
@@ -27,7 +27,7 @@ endif
 installed-mod-fw := $(addprefix $(INSTALL_FW_PATH)/,$(mod-fw))
 
 installed-fw := $(addprefix $(INSTALL_FW_PATH)/,$(fw-shipped-all))
-installed-fw-dirs := $(sort $(dir $(installed-fw))) $(INSTALL_FW_PATH)/.
+installed-fw-dirs := $(sort $(dir $(installed-fw))) $(INSTALL_FW_PATH)/./
 
 # Workaround for make < 3.81, where .SECONDEXPANSION doesn't work.
 PHONY += $(INSTALL_FW_PATH)/$$(%) install-all-dirs
@@ -42,7 +42,7 @@ quiet_cmd_install = INSTALL $(subst $(srctree)/,,$@)
 $(installed-fw-dirs):
        $(call cmd,mkdir)
 
-$(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/% | $$(dir $(INSTALL_FW_PATH)/%)
+$(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/% | $(INSTALL_FW_PATH)/$$(dir %)
        $(call cmd,install)
 
 PHONY +=  __fw_install __fw_modinst FORCE
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 c220f314709cc1345792e4a4ddab28cd63a23177..65f67cb0aefb22f323d8048c140417555c273c9d 100644 (file)
@@ -51,6 +51,7 @@ int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
 static inline void selinux_xfrm_notify_policyload(void)
 {
        atomic_inc(&flow_cache_genid);
+       rt_genid_bump(&init_net);
 }
 #else
 static inline int selinux_xfrm_enabled(void)
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;
+}