Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 21 Jan 2010 15:36:55 +0000 (07:36 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 21 Jan 2010 15:36:55 +0000 (07:36 -0800)
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6:
  Staging: hv: fix smp problems in the hyperv core code
  Staging: et131x: Fix 2.6.33rc1 regression in et131x
  Staging: asus_oled: fix oops in 2.6.32.2

83 files changed:
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/boot/compressed/head.S
arch/arm/boot/compressed/misc.c
arch/arm/include/asm/cacheflush.h
arch/arm/kernel/debug.S
arch/arm/kernel/elf.c
arch/arm/mach-gemini/include/mach/uncompress.h
arch/arm/mm/mmu.c
arch/arm/mm/proc-v6.S
arch/arm/mm/proc-v7.S
arch/arm/plat-mxc/include/mach/uncompress.h
arch/sh/boards/mach-se/7724/setup.c
arch/sh/include/asm/unistd_32.h
arch/sh/include/asm/unistd_64.h
arch/sh/kernel/syscalls_32.S
arch/sh/kernel/syscalls_64.S
arch/x86/kernel/acpi/boot.c
block/blk-ioc.c
block/blk-settings.c
block/cfq-iosched.c
block/genhd.c
drivers/acpi/acpi_pad.c
drivers/acpi/bus.c
drivers/acpi/ec.c
drivers/acpi/pci_link.c
drivers/acpi/pci_root.c
drivers/acpi/power.c
drivers/acpi/power_meter.c
drivers/acpi/processor_idle.c
drivers/acpi/processor_pdc.c
drivers/acpi/processor_thermal.c
drivers/acpi/sbs.c
drivers/acpi/sbshc.c
drivers/acpi/video.c
drivers/base/devtmpfs.c
drivers/base/memory.c
drivers/block/drbd/Kconfig
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_main.c
drivers/block/drbd/drbd_nl.c
drivers/block/drbd/drbd_receiver.c
drivers/md/dm-table.c
drivers/platform/x86/Kconfig
drivers/platform/x86/eeepc-laptop.c
drivers/platform/x86/sony-laptop.c
drivers/usb/core/devices.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/core/sysfs.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci-q.c
drivers/usb/host/fhci-hcd.c
drivers/usb/host/isp1362-hcd.c
drivers/usb/host/isp1760-hcd.c
drivers/usb/host/uhci-hcd.c
drivers/usb/host/uhci-hub.c
drivers/usb/serial/generic.c
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/usb.c
fs/bio.c
fs/btrfs/acl.c
fs/btrfs/extent-tree.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/ordered-data.c
fs/btrfs/relocation.c
fs/btrfs/volumes.c
fs/ecryptfs/crypto.c
fs/ecryptfs/file.c
fs/ecryptfs/inode.c
fs/ecryptfs/main.c
include/acpi/platform/aclinux.h
include/linux/acpi.h
include/linux/blkdev.h
include/linux/drbd.h
include/linux/drbd_nl.h
include/linux/genhd.h
include/linux/iocontext.h
include/linux/usb.h
mm/vmalloc.c

index c2238cd..4c33ca8 100644 (file)
@@ -729,14 +729,26 @@ config ARCH_U8500
 
 endchoice
 
+source "arch/arm/mach-aaec2000/Kconfig"
+
+source "arch/arm/mach-at91/Kconfig"
+
+source "arch/arm/mach-bcmring/Kconfig"
+
 source "arch/arm/mach-clps711x/Kconfig"
 
+source "arch/arm/mach-davinci/Kconfig"
+
+source "arch/arm/mach-dove/Kconfig"
+
 source "arch/arm/mach-ep93xx/Kconfig"
 
 source "arch/arm/mach-footbridge/Kconfig"
 
 source "arch/arm/mach-gemini/Kconfig"
 
+source "arch/arm/mach-h720x/Kconfig"
+
 source "arch/arm/mach-integrator/Kconfig"
 
 source "arch/arm/mach-iop32x/Kconfig"
@@ -751,16 +763,26 @@ source "arch/arm/mach-ixp2000/Kconfig"
 
 source "arch/arm/mach-ixp23xx/Kconfig"
 
+source "arch/arm/mach-kirkwood/Kconfig"
+
+source "arch/arm/mach-ks8695/Kconfig"
+
+source "arch/arm/mach-lh7a40x/Kconfig"
+
 source "arch/arm/mach-loki/Kconfig"
 
+source "arch/arm/mach-msm/Kconfig"
+
 source "arch/arm/mach-mv78xx0/Kconfig"
 
-source "arch/arm/mach-pxa/Kconfig"
-source "arch/arm/plat-pxa/Kconfig"
+source "arch/arm/plat-mxc/Kconfig"
 
-source "arch/arm/mach-mmp/Kconfig"
+source "arch/arm/mach-netx/Kconfig"
 
-source "arch/arm/mach-sa1100/Kconfig"
+source "arch/arm/mach-nomadik/Kconfig"
+source "arch/arm/plat-nomadik/Kconfig"
+
+source "arch/arm/mach-ns9xxx/Kconfig"
 
 source "arch/arm/plat-omap/Kconfig"
 
@@ -770,9 +792,14 @@ source "arch/arm/mach-omap2/Kconfig"
 
 source "arch/arm/mach-orion5x/Kconfig"
 
-source "arch/arm/mach-kirkwood/Kconfig"
+source "arch/arm/mach-pxa/Kconfig"
+source "arch/arm/plat-pxa/Kconfig"
 
-source "arch/arm/mach-dove/Kconfig"
+source "arch/arm/mach-mmp/Kconfig"
+
+source "arch/arm/mach-realview/Kconfig"
+
+source "arch/arm/mach-sa1100/Kconfig"
 
 source "arch/arm/plat-samsung/Kconfig"
 source "arch/arm/plat-s3c24xx/Kconfig"
@@ -800,41 +827,14 @@ if ARCH_S5PC1XX
 source "arch/arm/mach-s5pc100/Kconfig"
 endif
 
-source "arch/arm/mach-lh7a40x/Kconfig"
+source "arch/arm/mach-u300/Kconfig"
 
-source "arch/arm/mach-h720x/Kconfig"
+source "arch/arm/mach-ux500/Kconfig"
 
 source "arch/arm/mach-versatile/Kconfig"
 
-source "arch/arm/mach-aaec2000/Kconfig"
-
-source "arch/arm/mach-realview/Kconfig"
-
-source "arch/arm/mach-at91/Kconfig"
-
-source "arch/arm/plat-mxc/Kconfig"
-
-source "arch/arm/mach-nomadik/Kconfig"
-source "arch/arm/plat-nomadik/Kconfig"
-
-source "arch/arm/mach-netx/Kconfig"
-
-source "arch/arm/mach-ns9xxx/Kconfig"
-
-source "arch/arm/mach-davinci/Kconfig"
-
-source "arch/arm/mach-ks8695/Kconfig"
-
-source "arch/arm/mach-msm/Kconfig"
-
-source "arch/arm/mach-u300/Kconfig"
-
 source "arch/arm/mach-w90x900/Kconfig"
 
-source "arch/arm/mach-bcmring/Kconfig"
-
-source "arch/arm/mach-ux500/Kconfig"
-
 # Definitions to make life easier
 config ARCH_ACORN
        bool
index e9da084..9e75825 100644 (file)
@@ -146,6 +146,7 @@ machine-$(CONFIG_ARCH_MX1)          := mx1
 machine-$(CONFIG_ARCH_MX2)             := mx2
 machine-$(CONFIG_ARCH_MX25)            := mx25
 machine-$(CONFIG_ARCH_MX3)             := mx3
+machine-$(CONFIG_ARCH_MXC91231)                := mxc91231
 machine-$(CONFIG_ARCH_NETX)            := netx
 machine-$(CONFIG_ARCH_NOMADIK)         := nomadik
 machine-$(CONFIG_ARCH_NS9XXX)          := ns9xxx
@@ -171,12 +172,12 @@ machine-$(CONFIG_ARCH_U8500)              := ux500
 machine-$(CONFIG_ARCH_VERSATILE)       := versatile
 machine-$(CONFIG_ARCH_W90X900)         := w90x900
 machine-$(CONFIG_FOOTBRIDGE)           := footbridge
-machine-$(CONFIG_ARCH_MXC91231)                := mxc91231
 
 # Platform directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
 plat-$(CONFIG_ARCH_MXC)                := mxc
 plat-$(CONFIG_ARCH_OMAP)       := omap
+plat-$(CONFIG_ARCH_STMP3XXX)   := stmp3xxx
 plat-$(CONFIG_PLAT_IOP)                := iop
 plat-$(CONFIG_PLAT_NOMADIK)    := nomadik
 plat-$(CONFIG_PLAT_ORION)      := orion
@@ -184,7 +185,6 @@ plat-$(CONFIG_PLAT_PXA)             := pxa
 plat-$(CONFIG_PLAT_S3C24XX)    := s3c24xx s3c samsung
 plat-$(CONFIG_PLAT_S3C64XX)    := s3c64xx s3c samsung
 plat-$(CONFIG_PLAT_S5PC1XX)    := s5pc1xx s3c samsung
-plat-$(CONFIG_ARCH_STMP3XXX)   := stmp3xxx
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 # This is what happens if you forget the IOCS16 line.
index d356af7..4fddc50 100644 (file)
                .macro  writeb, ch, rb
                mcr     p14, 0, \ch, c0, c5, 0
                .endm
+#elif defined(CONFIG_CPU_V7)
+               .macro  loadsp, rb
+               .endm
+               .macro  writeb, ch, rb
+wait:          mrc     p14, 0, pc, c0, c1, 0
+               bcs     wait
+               mcr     p14, 0, \ch, c0, c5, 0
+               .endm
 #elif defined(CONFIG_CPU_XSCALE)
                .macro  loadsp, rb
                .endm
index 7e0fe4d..56a0d11 100644 (file)
@@ -53,6 +53,18 @@ static void icedcc_putc(int ch)
 
        asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
 }
+
+#elif defined(CONFIG_CPU_V7)
+
+static void icedcc_putc(int ch)
+{
+       asm(
+       "wait:  mrc     p14, 0, pc, c0, c1, 0                   \n\
+               bcs     wait                                    \n\
+               mcr     p14, 0, %0, c0, c5, 0                   "
+       : : "r" (ch));
+}
+
 #elif defined(CONFIG_CPU_XSCALE)
 
 static void icedcc_putc(int ch)
@@ -88,7 +100,6 @@ static void icedcc_putc(int ch)
 #endif
 
 #define putc(ch)       icedcc_putc(ch)
-#define flush()        do { } while (0)
 #endif
 
 static void putstr(const char *ptr)
index 730aefc..c77d2fa 100644 (file)
  *     Please note that the implementation of these, and the required
  *     effects are cache-type (VIVT/VIPT/PIPT) specific.
  *
- *     flush_cache_kern_all()
+ *     flush_kern_all()
  *
  *             Unconditionally clean and invalidate the entire cache.
  *
- *     flush_cache_user_mm(mm)
+ *     flush_user_all()
  *
  *             Clean and invalidate all user space cache entries
  *             before a change of page tables.
  *
- *     flush_cache_user_range(start, end, flags)
+ *     flush_user_range(start, end, flags)
  *
  *             Clean and invalidate a range of cache entries in the
  *             specified address space before a change of page tables.
  *             - start  - virtual start address
  *             - end    - virtual end address
  *
+ *     coherent_user_range(start, end)
+ *
+ *             Ensure coherency between the Icache and the Dcache in the
+ *             region described by start, end.  If you have non-snooping
+ *             Harvard caches, you need to implement this function.
+ *             - start  - virtual start address
+ *             - end    - virtual end address
+ *
+ *     flush_kern_dcache_area(kaddr, size)
+ *
+ *             Ensure that the data held in page is written back.
+ *             - kaddr  - page address
+ *             - size   - region size
+ *
  *     DMA Cache Coherency
  *     ===================
  *
index b121b60..5c91add 100644 (file)
 1002:
                .endm
 
+#elif defined(CONFIG_CPU_V7)
+
+               .macro  addruart, rx
+               .endm
+
+               .macro  senduart, rd, rx
+               mcr     p14, 0, \rd, c0, c5, 0
+               .endm
+
+               .macro  busyuart, rd, rx
+busy:          mrc     p14, 0, pc, c0, c1, 0
+               bcs     busy
+               .endm
+
+               .macro  waituart, rd, rx
+wait:          mrc     p14, 0, pc, c0, c1, 0
+               bcs     wait
+
+               .endm
+
 #elif defined(CONFIG_CPU_XSCALE)
 
                .macro  addruart, rx
index 950391f..d4a0da1 100644 (file)
@@ -78,15 +78,6 @@ int arm_elf_read_implies_exec(const struct elf32_hdr *x, int executable_stack)
                return 1;
        if (cpu_architecture() < CPU_ARCH_ARMv6)
                return 1;
-#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
-       /*
-        * If we have support for OABI programs, we can never allow NX
-        * support - our signal syscall restart mechanism relies upon
-        * being able to execute code placed on the user stack.
-        */
-       return 1;
-#else
        return 0;
-#endif
 }
 EXPORT_SYMBOL(arm_elf_read_implies_exec);
index 59c5df7..5483f61 100644 (file)
@@ -30,7 +30,9 @@ static inline void putc(char c)
        UART[UART_TX] = c;
 }
 
-#define flush() do { } while (0)
+static inline void flush(void)
+{
+}
 
 /*
  * nothing to do
index 1708da8..761ffed 100644 (file)
@@ -1067,4 +1067,6 @@ void setup_mm_for_reboot(char mode)
                pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
                flush_pmd_entry(pmd);
        }
+
+       local_flush_tlb_all();
 }
index 395cc90..7a5337e 100644 (file)
@@ -59,8 +59,6 @@ ENTRY(cpu_v6_proc_fin)
  *     to what would be the reset vector.
  *
  *     - loc   - location to jump to for soft reset
- *
- *     It is assumed that:
  */
        .align  5
 ENTRY(cpu_v6_reset)
index 3a28521..7aaf88a 100644 (file)
@@ -45,7 +45,14 @@ ENTRY(cpu_v7_proc_init)
 ENDPROC(cpu_v7_proc_init)
 
 ENTRY(cpu_v7_proc_fin)
-       mov     pc, lr
+       stmfd   sp!, {lr}
+       cpsid   if                              @ disable interrupts
+       bl      v7_flush_kern_cache_all
+       mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
+       bic     r0, r0, #0x1000                 @ ...i............
+       bic     r0, r0, #0x0006                 @ .............ca.
+       mcr     p15, 0, r0, c1, c0, 0           @ disable caches
+       ldmfd   sp!, {pc}
 ENDPROC(cpu_v7_proc_fin)
 
 /*
@@ -56,8 +63,6 @@ ENDPROC(cpu_v7_proc_fin)
  *     to what would be the reset vector.
  *
  *     - loc   - location to jump to for soft reset
- *
- *     It is assumed that:
  */
        .align  5
 ENTRY(cpu_v7_reset)
index 4d5d395..d49384c 100644 (file)
@@ -60,7 +60,9 @@ static void putc(int ch)
        UART(TXR) = ch;
 }
 
-#define flush() do { } while (0)
+static inline void flush(void)
+{
+}
 
 #define MX1_UART1_BASE_ADDR    0x00206000
 #define MX25_UART1_BASE_ADDR   0x43f90000
index 5d0f70b..858ecb2 100644 (file)
@@ -533,7 +533,7 @@ static int __init sh_eth_is_eeprom_ready(void)
        while (t--) {
                if (!ctrl_inw(EEPROM_STAT))
                        return 1;
-               cpu_relax();
+               udelay(1);
        }
 
        printk(KERN_ERR "ms7724se can not access to eeprom\n");
index f18c4f9..365744b 100644 (file)
 #define __NR_pwritev           334
 #define __NR_rt_tgsigqueueinfo 335
 #define __NR_perf_event_open   336
-#define __NR_recvmmsg          337
 
-#define NR_syscalls 338
+#define NR_syscalls 337
 
 #ifdef __KERNEL__
 
+#define __IGNORE_recvmmsg
+
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_OLD_STAT
index 3e7645d..25de158 100644 (file)
 #define __NR_rt_tgsigqueueinfo 363
 #define __NR_perf_event_open   364
 #define __NR_recvmmsg          365
+#define __NR_accept4           366
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 366
+#define NR_syscalls 367
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
index 4bd5a11..19fd11d 100644 (file)
@@ -353,4 +353,3 @@ ENTRY(sys_call_table)
        .long sys_pwritev
        .long sys_rt_tgsigqueueinfo     /* 335 */
        .long sys_perf_event_open
-       .long sys_recvmmsg
index 07d2aae..2048a20 100644 (file)
@@ -392,3 +392,4 @@ sys_call_table:
        .long sys_rt_tgsigqueueinfo
        .long sys_perf_event_open
        .long sys_recvmmsg              /* 365 */
+       .long sys_accept4
index fb1035c..036d28a 100644 (file)
@@ -1529,16 +1529,10 @@ static struct dmi_system_id __initdata acpi_dmi_table_late[] = {
  *     if acpi_blacklisted() acpi_disabled = 1;
  *     acpi_irq_model=...
  *     ...
- *
- * return value: (currently ignored)
- *     0: success
- *     !0: failure
  */
 
-int __init acpi_boot_table_init(void)
+void __init acpi_boot_table_init(void)
 {
-       int error;
-
        dmi_check_system(acpi_dmi_table);
 
        /*
@@ -1546,15 +1540,14 @@ int __init acpi_boot_table_init(void)
         * One exception: acpi=ht continues far enough to enumerate LAPICs
         */
        if (acpi_disabled && !acpi_ht)
-               return 1;
+               return
 
        /*
         * Initialize the ACPI boot-time table parser.
         */
-       error = acpi_table_init();
-       if (error) {
+       if (acpi_table_init()) {
                disable_acpi();
-               return error;
+               return;
        }
 
        acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
@@ -1562,18 +1555,15 @@ int __init acpi_boot_table_init(void)
        /*
         * blacklist may disable ACPI entirely
         */
-       error = acpi_blacklisted();
-       if (error) {
+       if (acpi_blacklisted()) {
                if (acpi_force) {
                        printk(KERN_WARNING PREFIX "acpi=force override\n");
                } else {
                        printk(KERN_WARNING PREFIX "Disabling ACPI support\n");
                        disable_acpi();
-                       return error;
+                       return;
                }
        }
-
-       return 0;
 }
 
 int __init early_acpi_boot_init(void)
index cbdabb0..98e6bf6 100644 (file)
@@ -39,8 +39,6 @@ int put_io_context(struct io_context *ioc)
 
        if (atomic_long_dec_and_test(&ioc->refcount)) {
                rcu_read_lock();
-               if (ioc->aic && ioc->aic->dtor)
-                       ioc->aic->dtor(ioc->aic);
                cfq_dtor(ioc);
                rcu_read_unlock();
 
@@ -76,8 +74,6 @@ void exit_io_context(struct task_struct *task)
        task_unlock(task);
 
        if (atomic_dec_and_test(&ioc->nr_tasks)) {
-               if (ioc->aic && ioc->aic->exit)
-                       ioc->aic->exit(ioc->aic);
                cfq_exit(ioc);
 
        }
@@ -97,7 +93,6 @@ struct io_context *alloc_io_context(gfp_t gfp_flags, int node)
                ret->ioprio = 0;
                ret->last_waited = jiffies; /* doesn't matter... */
                ret->nr_batch_requests = 0; /* because this is 0 */
-               ret->aic = NULL;
                INIT_RADIX_TREE(&ret->radix_root, GFP_ATOMIC | __GFP_HIGH);
                INIT_HLIST_HEAD(&ret->cic_list);
                ret->ioc_data = NULL;
index d52d4ad..5eeb9e0 100644 (file)
@@ -528,7 +528,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
                     sector_t offset)
 {
        sector_t alignment;
-       unsigned int top, bottom;
+       unsigned int top, bottom, ret = 0;
 
        t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors);
        t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors);
@@ -546,6 +546,8 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
        t->max_segment_size = min_not_zero(t->max_segment_size,
                                           b->max_segment_size);
 
+       t->misaligned |= b->misaligned;
+
        alignment = queue_limit_alignment_offset(b, offset);
 
        /* Bottom device has different alignment.  Check that it is
@@ -558,8 +560,10 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
                bottom = max(b->physical_block_size, b->io_min) + alignment;
 
                /* Verify that top and bottom intervals line up */
-               if (max(top, bottom) & (min(top, bottom) - 1))
+               if (max(top, bottom) & (min(top, bottom) - 1)) {
                        t->misaligned = 1;
+                       ret = -1;
+               }
        }
 
        t->logical_block_size = max(t->logical_block_size,
@@ -578,18 +582,21 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
        if (t->physical_block_size & (t->logical_block_size - 1)) {
                t->physical_block_size = t->logical_block_size;
                t->misaligned = 1;
+               ret = -1;
        }
 
        /* Minimum I/O a multiple of the physical block size? */
        if (t->io_min & (t->physical_block_size - 1)) {
                t->io_min = t->physical_block_size;
                t->misaligned = 1;
+               ret = -1;
        }
 
        /* Optimal I/O a multiple of the physical block size? */
        if (t->io_opt & (t->physical_block_size - 1)) {
                t->io_opt = 0;
                t->misaligned = 1;
+               ret = -1;
        }
 
        /* Find lowest common alignment_offset */
@@ -597,8 +604,10 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
                & (max(t->physical_block_size, t->io_min) - 1);
 
        /* Verify that new alignment_offset is on a logical block boundary */
-       if (t->alignment_offset & (t->logical_block_size - 1))
+       if (t->alignment_offset & (t->logical_block_size - 1)) {
                t->misaligned = 1;
+               ret = -1;
+       }
 
        /* Discard alignment and granularity */
        if (b->discard_granularity) {
@@ -626,10 +635,32 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
                        (t->discard_granularity - 1);
        }
 
-       return t->misaligned ? -1 : 0;
+       return ret;
 }
 EXPORT_SYMBOL(blk_stack_limits);
 
+/**
+ * bdev_stack_limits - adjust queue limits for stacked drivers
+ * @t: the stacking driver limits (top device)
+ * @bdev:  the component block_device (bottom)
+ * @start:  first data sector within component device
+ *
+ * Description:
+ *    Merges queue limits for a top device and a block_device.  Returns
+ *    0 if alignment didn't change.  Returns -1 if adding the bottom
+ *    device caused misalignment.
+ */
+int bdev_stack_limits(struct queue_limits *t, struct block_device *bdev,
+                     sector_t start)
+{
+       struct request_queue *bq = bdev_get_queue(bdev);
+
+       start += get_start_sect(bdev);
+
+       return blk_stack_limits(t, &bq->limits, start << 9);
+}
+EXPORT_SYMBOL(bdev_stack_limits);
+
 /**
  * disk_stack_limits - adjust queue limits for stacked drivers
  * @disk:  MD/DM gendisk (top)
index 918c7fd..ee130f1 100644 (file)
@@ -3076,6 +3076,12 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
        if (cfq_class_idle(cfqq))
                return true;
 
+       /*
+        * Don't allow a non-RT request to preempt an ongoing RT cfqq timeslice.
+        */
+       if (cfq_class_rt(cfqq) && !cfq_class_rt(new_cfqq))
+               return false;
+
        /*
         * if the new request is sync, but the currently running queue is
         * not, let the sync request have priority.
index b11a4ad..d13ba76 100644 (file)
@@ -867,7 +867,7 @@ static ssize_t disk_discard_alignment_show(struct device *dev,
 {
        struct gendisk *disk = dev_to_disk(dev);
 
-       return sprintf(buf, "%u\n", queue_discard_alignment(disk->queue));
+       return sprintf(buf, "%d\n", queue_discard_alignment(disk->queue));
 }
 
 static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL);
index 97991ac..7e52295 100644 (file)
@@ -208,7 +208,7 @@ static int power_saving_thread(void *data)
                 * the mechanism only works when all CPUs have RT task running,
                 * as if one CPU hasn't RT task, RT task from other CPUs will
                 * borrow CPU time from this CPU and cause RT task use > 95%
-                * CPU time. To make 'avoid staration' work, takes a nap here.
+                * CPU time. To make 'avoid starvation' work, takes a nap here.
                 */
                if (do_sleep)
                        schedule_timeout_killable(HZ * idle_pct / 100);
@@ -222,14 +222,18 @@ static struct task_struct *ps_tsks[NR_CPUS];
 static unsigned int ps_tsk_num;
 static int create_power_saving_task(void)
 {
+       int rc = -ENOMEM;
+
        ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread,
                (void *)(unsigned long)ps_tsk_num,
                "power_saving/%d", ps_tsk_num);
-       if (ps_tsks[ps_tsk_num]) {
+       rc = IS_ERR(ps_tsks[ps_tsk_num]) ? PTR_ERR(ps_tsks[ps_tsk_num]) : 0;
+       if (!rc)
                ps_tsk_num++;
-               return 0;
-       }
-       return -EINVAL;
+       else
+               ps_tsks[ps_tsk_num] = NULL;
+
+       return rc;
 }
 
 static void destroy_power_saving_task(void)
@@ -237,6 +241,7 @@ static void destroy_power_saving_task(void)
        if (ps_tsk_num > 0) {
                ps_tsk_num--;
                kthread_stop(ps_tsks[ps_tsk_num]);
+               ps_tsks[ps_tsk_num] = NULL;
        }
 }
 
@@ -253,7 +258,7 @@ static void set_power_saving_task_num(unsigned int num)
        }
 }
 
-static int acpi_pad_idle_cpus(unsigned int num_cpus)
+static void acpi_pad_idle_cpus(unsigned int num_cpus)
 {
        get_online_cpus();
 
@@ -261,7 +266,6 @@ static int acpi_pad_idle_cpus(unsigned int num_cpus)
        set_power_saving_task_num(num_cpus);
 
        put_online_cpus();
-       return 0;
 }
 
 static uint32_t acpi_pad_idle_cpus_num(void)
@@ -369,19 +373,21 @@ static void acpi_pad_remove_sysfs(struct acpi_device *device)
 static int acpi_pad_pur(acpi_handle handle, int *num_cpus)
 {
        struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-       acpi_status status;
        union acpi_object *package;
        int rev, num, ret = -EINVAL;
 
-       status = acpi_evaluate_object(handle, "_PUR", NULL, &buffer);
-       if (ACPI_FAILURE(status))
+       if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer)))
+               return -EINVAL;
+
+       if (!buffer.length || !buffer.pointer)
                return -EINVAL;
+
        package = buffer.pointer;
        if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2)
                goto out;
        rev = package->package.elements[0].integer.value;
        num = package->package.elements[1].integer.value;
-       if (rev != 1)
+       if (rev != 1 || num < 0)
                goto out;
        *num_cpus = num;
        ret = 0;
@@ -410,7 +416,7 @@ static void acpi_pad_ost(acpi_handle handle, int stat,
 
 static void acpi_pad_handle_notify(acpi_handle handle)
 {
-       int num_cpus, ret;
+       int num_cpus;
        uint32_t idle_cpus;
 
        mutex_lock(&isolated_cpus_lock);
@@ -418,12 +424,9 @@ static void acpi_pad_handle_notify(acpi_handle handle)
                mutex_unlock(&isolated_cpus_lock);
                return;
        }
-       ret = acpi_pad_idle_cpus(num_cpus);
+       acpi_pad_idle_cpus(num_cpus);
        idle_cpus = acpi_pad_idle_cpus_num();
-       if (!ret)
-               acpi_pad_ost(handle, 0, idle_cpus);
-       else
-               acpi_pad_ost(handle, 1, 0);
+       acpi_pad_ost(handle, 0, idle_cpus);
        mutex_unlock(&isolated_cpus_lock);
 }
 
index cf761b9..a52126e 100644 (file)
@@ -490,9 +490,14 @@ static void acpi_bus_osc_support(void)
 
        capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
        capbuf[OSC_SUPPORT_TYPE] = OSC_SB_PR3_SUPPORT; /* _PR3 is in use */
-#ifdef CONFIG_ACPI_PROCESSOR_AGGREGATOR
+#if defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) ||\
+                       defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE)
        capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PAD_SUPPORT;
 #endif
+
+#if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE)
+       capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PPC_OST_SUPPORT;
+#endif
        if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
                return;
        if (ACPI_SUCCESS(acpi_run_osc(handle, &context)))
index fd1801b..d6471bb 100644 (file)
@@ -201,14 +201,13 @@ unlock:
        spin_unlock_irqrestore(&ec->curr_lock, flags);
 }
 
-static void acpi_ec_gpe_query(void *ec_cxt);
+static int acpi_ec_sync_query(struct acpi_ec *ec);
 
-static int ec_check_sci(struct acpi_ec *ec, u8 state)
+static int ec_check_sci_sync(struct acpi_ec *ec, u8 state)
 {
        if (state & ACPI_EC_FLAG_SCI) {
                if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
-                       return acpi_os_execute(OSL_EC_BURST_HANDLER,
-                               acpi_ec_gpe_query, ec);
+                       return acpi_ec_sync_query(ec);
        }
        return 0;
 }
@@ -249,11 +248,6 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
 {
        unsigned long tmp;
        int ret = 0;
-       pr_debug(PREFIX "transaction start\n");
-       /* disable GPE during transaction if storm is detected */
-       if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
-               acpi_disable_gpe(NULL, ec->gpe);
-       }
        if (EC_FLAGS_MSI)
                udelay(ACPI_EC_MSI_UDELAY);
        /* start transaction */
@@ -265,20 +259,9 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
                clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
        spin_unlock_irqrestore(&ec->curr_lock, tmp);
        ret = ec_poll(ec);
-       pr_debug(PREFIX "transaction end\n");
        spin_lock_irqsave(&ec->curr_lock, tmp);
        ec->curr = NULL;
        spin_unlock_irqrestore(&ec->curr_lock, tmp);
-       if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
-               /* check if we received SCI during transaction */
-               ec_check_sci(ec, acpi_ec_read_status(ec));
-               /* it is safe to enable GPE outside of transaction */
-               acpi_enable_gpe(NULL, ec->gpe);
-       } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
-               pr_info(PREFIX "GPE storm detected, "
-                       "transactions will use polling mode\n");
-               set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
-       }
        return ret;
 }
 
@@ -321,7 +304,26 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
                status = -ETIME;
                goto end;
        }
+       pr_debug(PREFIX "transaction start\n");
+       /* disable GPE during transaction if storm is detected */
+       if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
+               acpi_disable_gpe(NULL, ec->gpe);
+       }
+
        status = acpi_ec_transaction_unlocked(ec, t);
+
+       /* check if we received SCI during transaction */
+       ec_check_sci_sync(ec, acpi_ec_read_status(ec));
+       if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
+               msleep(1);
+               /* it is safe to enable GPE outside of transaction */
+               acpi_enable_gpe(NULL, ec->gpe);
+       } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) {
+               pr_info(PREFIX "GPE storm detected, "
+                       "transactions will use polling mode\n");
+               set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
+       }
+       pr_debug(PREFIX "transaction end\n");
 end:
        if (ec->global_lock)
                acpi_release_global_lock(glk);
@@ -443,7 +445,7 @@ int ec_transaction(u8 command,
 
 EXPORT_SYMBOL(ec_transaction);
 
-static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
+static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data)
 {
        int result;
        u8 d;
@@ -452,20 +454,16 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
                                .wlen = 0, .rlen = 1};
        if (!ec || !data)
                return -EINVAL;
-
        /*
         * Query the EC to find out which _Qxx method we need to evaluate.
         * Note that successful completion of the query causes the ACPI_EC_SCI
         * bit to be cleared (and thus clearing the interrupt source).
         */
-
-       result = acpi_ec_transaction(ec, &t);
+       result = acpi_ec_transaction_unlocked(ec, &t);
        if (result)
                return result;
-
        if (!d)
                return -ENODATA;
-
        *data = d;
        return 0;
 }
@@ -509,43 +507,79 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
 
 EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
 
-static void acpi_ec_gpe_query(void *ec_cxt)
+static void acpi_ec_run(void *cxt)
 {
-       struct acpi_ec *ec = ec_cxt;
-       u8 value = 0;
-       struct acpi_ec_query_handler *handler, copy;
-
-       if (!ec || acpi_ec_query(ec, &value))
+       struct acpi_ec_query_handler *handler = cxt;
+       if (!handler)
                return;
-       mutex_lock(&ec->lock);
+       pr_debug(PREFIX "start query execution\n");
+       if (handler->func)
+               handler->func(handler->data);
+       else if (handler->handle)
+               acpi_evaluate_object(handler->handle, NULL, NULL, NULL);
+       pr_debug(PREFIX "stop query execution\n");
+       kfree(handler);
+}
+
+static int acpi_ec_sync_query(struct acpi_ec *ec)
+{
+       u8 value = 0;
+       int status;
+       struct acpi_ec_query_handler *handler, *copy;
+       if ((status = acpi_ec_query_unlocked(ec, &value)))
+               return status;
        list_for_each_entry(handler, &ec->list, node) {
                if (value == handler->query_bit) {
                        /* have custom handler for this bit */
-                       memcpy(&copy, handler, sizeof(copy));
-                       mutex_unlock(&ec->lock);
-                       if (copy.func) {
-                               copy.func(copy.data);
-                       } else if (copy.handle) {
-                               acpi_evaluate_object(copy.handle, NULL, NULL, NULL);
-                       }
-                       return;
+                       copy = kmalloc(sizeof(*handler), GFP_KERNEL);
+                       if (!copy)
+                               return -ENOMEM;
+                       memcpy(copy, handler, sizeof(*copy));
+                       pr_debug(PREFIX "push query execution (0x%2x) on queue\n", value);
+                       return acpi_os_execute((copy->func) ?
+                               OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER,
+                               acpi_ec_run, copy);
                }
        }
+       return 0;
+}
+
+static void acpi_ec_gpe_query(void *ec_cxt)
+{
+       struct acpi_ec *ec = ec_cxt;
+       if (!ec)
+               return;
+       mutex_lock(&ec->lock);
+       acpi_ec_sync_query(ec);
        mutex_unlock(&ec->lock);
 }
 
+static void acpi_ec_gpe_query(void *ec_cxt);
+
+static int ec_check_sci(struct acpi_ec *ec, u8 state)
+{
+       if (state & ACPI_EC_FLAG_SCI) {
+               if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
+                       pr_debug(PREFIX "push gpe query to the queue\n");
+                       return acpi_os_execute(OSL_NOTIFY_HANDLER,
+                               acpi_ec_gpe_query, ec);
+               }
+       }
+       return 0;
+}
+
 static u32 acpi_ec_gpe_handler(void *data)
 {
        struct acpi_ec *ec = data;
-       u8 status;
 
        pr_debug(PREFIX "~~~> interrupt\n");
-       status = acpi_ec_read_status(ec);
 
-       advance_transaction(ec, status);
-       if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0)
+       advance_transaction(ec, acpi_ec_read_status(ec));
+       if (ec_transaction_done(ec) &&
+           (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) {
                wake_up(&ec->wait);
-       ec_check_sci(ec, status);
+               ec_check_sci(ec, acpi_ec_read_status(ec));
+       }
        return ACPI_INTERRUPT_HANDLED;
 }
 
index 394ae89..04b0f00 100644 (file)
@@ -56,7 +56,7 @@ ACPI_MODULE_NAME("pci_link");
 static int acpi_pci_link_add(struct acpi_device *device);
 static int acpi_pci_link_remove(struct acpi_device *device, int type);
 
-static struct acpi_device_id link_device_ids[] = {
+static const struct acpi_device_id link_device_ids[] = {
        {"PNP0C0F", 0},
        {"", 0},
 };
index 101cce3..64f55b6 100644 (file)
@@ -46,7 +46,7 @@ static int acpi_pci_root_add(struct acpi_device *device);
 static int acpi_pci_root_remove(struct acpi_device *device, int type);
 static int acpi_pci_root_start(struct acpi_device *device);
 
-static struct acpi_device_id root_device_ids[] = {
+static const struct acpi_device_id root_device_ids[] = {
        {"PNP0A03", 0},
        {"", 0},
 };
index 22b2979..0f30c3c 100644 (file)
@@ -65,7 +65,7 @@ static int acpi_power_remove(struct acpi_device *device, int type);
 static int acpi_power_resume(struct acpi_device *device);
 static int acpi_power_open_fs(struct inode *inode, struct file *file);
 
-static struct acpi_device_id power_device_ids[] = {
+static const struct acpi_device_id power_device_ids[] = {
        {ACPI_POWER_HID, 0},
        {"", 0},
 };
index 2ef7030..dc4ffad 100644 (file)
@@ -64,7 +64,7 @@ static int can_cap_in_hardware(void)
        return force_cap_on || cap_in_hardware;
 }
 
-static struct acpi_device_id power_meter_ids[] = {
+static const struct acpi_device_id power_meter_ids[] = {
        {"ACPI000D", 0},
        {"", 0},
 };
@@ -534,6 +534,7 @@ static void remove_domain_devices(struct acpi_power_meter_resource *resource)
 
        kfree(resource->domain_devices);
        kobject_put(resource->holders_dir);
+       resource->num_domain_devices = 0;
 }
 
 static int read_domain_devices(struct acpi_power_meter_resource *resource)
@@ -740,7 +741,6 @@ skip_unsafe_cap:
 
        return res;
 error:
-       remove_domain_devices(resource);
        remove_attrs(resource);
        return res;
 }
index d1676b1..7c0441f 100644 (file)
@@ -305,6 +305,28 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
        pr->power.states[ACPI_STATE_C2].latency = acpi_gbl_FADT.C2latency;
        pr->power.states[ACPI_STATE_C3].latency = acpi_gbl_FADT.C3latency;
 
+       /*
+        * FADT specified C2 latency must be less than or equal to
+        * 100 microseconds.
+        */
+       if (acpi_gbl_FADT.C2latency > ACPI_PROCESSOR_MAX_C2_LATENCY) {
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                       "C2 latency too large [%d]\n", acpi_gbl_FADT.C2latency));
+               /* invalidate C2 */
+               pr->power.states[ACPI_STATE_C2].address = 0;
+       }
+
+       /*
+        * FADT supplied C3 latency must be less than or equal to
+        * 1000 microseconds.
+        */
+       if (acpi_gbl_FADT.C3latency > ACPI_PROCESSOR_MAX_C3_LATENCY) {
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                       "C3 latency too large [%d]\n", acpi_gbl_FADT.C3latency));
+               /* invalidate C3 */
+               pr->power.states[ACPI_STATE_C3].address = 0;
+       }
+
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                          "lvl2[0x%08x] lvl3[0x%08x]\n",
                          pr->power.states[ACPI_STATE_C2].address,
@@ -494,33 +516,6 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
        return status;
 }
 
-static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
-{
-
-       if (!cx->address)
-               return;
-
-       /*
-        * C2 latency must be less than or equal to 100
-        * microseconds.
-        */
-       else if (cx->latency > ACPI_PROCESSOR_MAX_C2_LATENCY) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                 "latency too large [%d]\n", cx->latency));
-               return;
-       }
-
-       /*
-        * Otherwise we've met all of our C2 requirements.
-        * Normalize the C2 latency to expidite policy
-        */
-       cx->valid = 1;
-
-       cx->latency_ticks = cx->latency;
-
-       return;
-}
-
 static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
                                           struct acpi_processor_cx *cx)
 {
@@ -531,16 +526,6 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
        if (!cx->address)
                return;
 
-       /*
-        * C3 latency must be less than or equal to 1000
-        * microseconds.
-        */
-       else if (cx->latency > ACPI_PROCESSOR_MAX_C3_LATENCY) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                 "latency too large [%d]\n", cx->latency));
-               return;
-       }
-
        /*
         * PIIX4 Erratum #18: We don't support C3 when Type-F (fast)
         * DMA transfers are used by any ISA device to avoid livelock.
@@ -629,7 +614,10 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
                        break;
 
                case ACPI_STATE_C2:
-                       acpi_processor_power_verify_c2(cx);
+                       if (!cx->address)
+                               break;
+                       cx->valid = 1; 
+                       cx->latency_ticks = cx->latency; /* Normalize latency */
                        break;
 
                case ACPI_STATE_C3:
index 30e4dc0..7247819 100644 (file)
@@ -144,6 +144,29 @@ void acpi_processor_set_pdc(acpi_handle handle)
 }
 EXPORT_SYMBOL_GPL(acpi_processor_set_pdc);
 
+static int early_pdc_optin;
+static int set_early_pdc_optin(const struct dmi_system_id *id)
+{
+       early_pdc_optin = 1;
+       return 0;
+}
+
+static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = {
+       {
+       set_early_pdc_optin, "HP Envy", {
+       DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"),
+       DMI_MATCH(DMI_PRODUCT_NAME, "HP Envy") }, NULL},
+       {
+       set_early_pdc_optin, "HP Pavilion dv6", {
+       DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"),
+       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv6") }, NULL},
+       {
+       set_early_pdc_optin, "HP Pavilion dv7", {
+       DMI_MATCH(DMI_BIOS_VENDOR, "Hewlett-Packard"),
+       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv7") }, NULL},
+       {},
+};
+
 static acpi_status
 early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
@@ -151,7 +174,7 @@ early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
        return AE_OK;
 }
 
-void acpi_early_processor_set_pdc(void)
+void __init acpi_early_processor_set_pdc(void)
 {
        /*
         * Check whether the system is DMI table. If yes, OSPM
@@ -159,6 +182,13 @@ void acpi_early_processor_set_pdc(void)
         */
        dmi_check_system(processor_idle_dmi_table);
 
+       /*
+        * Allow systems to opt-in to early _PDC evaluation.
+        */
+       dmi_check_system(early_pdc_optin_table);
+       if (!early_pdc_optin)
+               return;
+
        acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
                            ACPI_UINT32_MAX,
                            early_init_pdc, NULL, NULL, NULL);
index 140c5c5..6deafb4 100644 (file)
@@ -443,8 +443,7 @@ struct thermal_cooling_device_ops processor_cooling_ops = {
 #ifdef CONFIG_ACPI_PROCFS
 static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset)
 {
-       struct acpi_processor *pr = (struct acpi_processor *)seq->private;
-
+       struct acpi_processor *pr = seq->private;
 
        if (!pr)
                goto end;
index 52b9db8..b16ddbf 100644 (file)
@@ -822,7 +822,10 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 
 static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
 {
+#if defined(CONFIG_ACPI_SYSFS_POWER) || defined(CONFIG_ACPI_PROCFS_POWER)
        struct acpi_battery *battery = &sbs->battery[id];
+#endif
+
 #ifdef CONFIG_ACPI_SYSFS_POWER
        if (battery->bat.dev) {
                if (battery->have_sysfs_alarm)
index d933980..fd09229 100644 (file)
@@ -242,7 +242,7 @@ static int smbus_alarm(void *context)
                case ACPI_SBS_CHARGER:
                case ACPI_SBS_MANAGER:
                case ACPI_SBS_BATTERY:
-                       acpi_os_execute(OSL_GPE_HANDLER,
+                       acpi_os_execute(OSL_NOTIFY_HANDLER,
                                        acpi_smbus_callback, hc);
                default:;
        }
index 72e76b4..b765790 100644 (file)
@@ -78,6 +78,13 @@ MODULE_LICENSE("GPL");
 static int brightness_switch_enabled = 1;
 module_param(brightness_switch_enabled, bool, 0644);
 
+/*
+ * By default, we don't allow duplicate ACPI video bus devices
+ * under the same VGA controller
+ */
+static int allow_duplicates;
+module_param(allow_duplicates, bool, 0644);
+
 static int register_count = 0;
 static int acpi_video_bus_add(struct acpi_device *device);
 static int acpi_video_bus_remove(struct acpi_device *device, int type);
@@ -2239,11 +2246,47 @@ static int acpi_video_resume(struct acpi_device *device)
        return AE_OK;
 }
 
+static acpi_status
+acpi_video_bus_match(acpi_handle handle, u32 level, void *context,
+                       void **return_value)
+{
+       struct acpi_device *device = context;
+       struct acpi_device *sibling;
+       int result;
+
+       if (handle == device->handle)
+               return AE_CTRL_TERMINATE;
+
+       result = acpi_bus_get_device(handle, &sibling);
+       if (result)
+               return AE_OK;
+
+       if (!strcmp(acpi_device_name(sibling), ACPI_VIDEO_BUS_NAME))
+                       return AE_ALREADY_EXISTS;
+
+       return AE_OK;
+}
+
 static int acpi_video_bus_add(struct acpi_device *device)
 {
        struct acpi_video_bus *video;
        struct input_dev *input;
        int error;
+       acpi_status status;
+
+       status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
+                               device->parent->handle, 1,
+                               acpi_video_bus_match, NULL,
+                               device, NULL);
+       if (status == AE_ALREADY_EXISTS) {
+               printk(KERN_WARNING FW_BUG
+                       "Duplicate ACPI video bus devices for the"
+                       " same VGA controller, please try module "
+                       "parameter \"video.allow_duplicates=1\""
+                       "if the current driver doesn't work.\n");
+               if (!allow_duplicates)
+                       return -ENODEV;
+       }
 
        video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL);
        if (!video)
index 090dd48..42ae452 100644 (file)
@@ -354,6 +354,7 @@ int __init devtmpfs_init(void)
 {
        int err;
        struct vfsmount *mnt;
+       char options[] = "mode=0755";
 
        err = register_filesystem(&dev_fs_type);
        if (err) {
@@ -362,7 +363,7 @@ int __init devtmpfs_init(void)
                return err;
        }
 
-       mnt = kern_mount_data(&dev_fs_type, "mode=0755");
+       mnt = kern_mount_data(&dev_fs_type, options);
        if (IS_ERR(mnt)) {
                err = PTR_ERR(mnt);
                printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err);
index ae6b6c4..bd02505 100644 (file)
@@ -309,19 +309,17 @@ static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL);
  * Block size attribute stuff
  */
 static ssize_t
-print_block_size(struct sysdev_class *class,
-                struct sysdev_class_attribute *class_attr,
-                char *buf)
+print_block_size(struct class *class, char *buf)
 {
        return sprintf(buf, "%#lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
 }
 
-static SYSDEV_CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
+static CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
 
 static int block_size_init(void)
 {
        return sysfs_create_file(&memory_sysdev_class.kset.kobj,
-                               &attr_block_size_bytes.attr);
+                               &class_attr_block_size_bytes.attr);
 }
 
 /*
@@ -332,9 +330,7 @@ static int block_size_init(void)
  */
 #ifdef CONFIG_ARCH_MEMORY_PROBE
 static ssize_t
-memory_probe_store(struct sysdev_class *class,
-                  struct sysdev_class_attribute *class_attr,
-                  const char *buf, size_t count)
+memory_probe_store(struct class *class, const char *buf, size_t count)
 {
        u64 phys_addr;
        int nid;
@@ -350,12 +346,12 @@ memory_probe_store(struct sysdev_class *class,
 
        return count;
 }
-static SYSDEV_CLASS_ATTR(probe, S_IWUSR, NULL, memory_probe_store);
+static CLASS_ATTR(probe, S_IWUSR, NULL, memory_probe_store);
 
 static int memory_probe_init(void)
 {
        return sysfs_create_file(&memory_sysdev_class.kset.kobj,
-                               &attr_probe.attr);
+                               &class_attr_probe.attr);
 }
 #else
 static inline int memory_probe_init(void)
@@ -371,9 +367,7 @@ static inline int memory_probe_init(void)
 
 /* Soft offline a page */
 static ssize_t
-store_soft_offline_page(struct sysdev_class *class,
-                       struct sysdev_class_attribute *class_attr,
-                       const char *buf, size_t count)
+store_soft_offline_page(struct class *class, const char *buf, size_t count)
 {
        int ret;
        u64 pfn;
@@ -390,9 +384,7 @@ store_soft_offline_page(struct sysdev_class *class,
 
 /* Forcibly offline a page, including killing processes. */
 static ssize_t
-store_hard_offline_page(struct sysdev_class *class,
-                       struct sysdev_class_attribute *class_attr,
-                       const char *buf, size_t count)
+store_hard_offline_page(struct class *class, const char *buf, size_t count)
 {
        int ret;
        u64 pfn;
@@ -405,18 +397,18 @@ store_hard_offline_page(struct sysdev_class *class,
        return ret ? ret : count;
 }
 
-static SYSDEV_CLASS_ATTR(soft_offline_page, 0644, NULL, store_soft_offline_page);
-static SYSDEV_CLASS_ATTR(hard_offline_page, 0644, NULL, store_hard_offline_page);
+static CLASS_ATTR(soft_offline_page, 0644, NULL, store_soft_offline_page);
+static CLASS_ATTR(hard_offline_page, 0644, NULL, store_hard_offline_page);
 
 static __init int memory_fail_init(void)
 {
        int err;
 
        err = sysfs_create_file(&memory_sysdev_class.kset.kobj,
-                               &attr_soft_offline_page.attr);
+                               &class_attr_soft_offline_page.attr);
        if (!err)
                err = sysfs_create_file(&memory_sysdev_class.kset.kobj,
-                               &attr_hard_offline_page.attr);
+                               &class_attr_hard_offline_page.attr);
        return err;
 }
 #else
index f4acd04..df09837 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 comment "DRBD disabled because PROC_FS, INET or CONNECTOR not selected"
-       depends on !PROC_FS || !INET || !CONNECTOR
+       depends on PROC_FS='n' || INET='n' || CONNECTOR='n'
 
 config BLK_DEV_DRBD
        tristate "DRBD Distributed Replicated Block Device support"
index c975587..2bf3a6e 100644 (file)
@@ -1275,7 +1275,7 @@ struct bm_extent {
 #if DRBD_MAX_SECTORS_BM < DRBD_MAX_SECTORS_32
 #define DRBD_MAX_SECTORS      DRBD_MAX_SECTORS_BM
 #define DRBD_MAX_SECTORS_FLEX DRBD_MAX_SECTORS_BM
-#elif !defined(CONFIG_LBD) && BITS_PER_LONG == 32
+#elif !defined(CONFIG_LBDAF) && BITS_PER_LONG == 32
 #define DRBD_MAX_SECTORS      DRBD_MAX_SECTORS_32
 #define DRBD_MAX_SECTORS_FLEX DRBD_MAX_SECTORS_32
 #else
@@ -1371,10 +1371,9 @@ extern int is_valid_ar_handle(struct drbd_request *, sector_t);
 extern void drbd_suspend_io(struct drbd_conf *mdev);
 extern void drbd_resume_io(struct drbd_conf *mdev);
 extern char *ppsize(char *buf, unsigned long long size);
-extern sector_t drbd_new_dev_size(struct drbd_conf *,
-               struct drbd_backing_dev *);
+extern sector_t drbd_new_dev_size(struct drbd_conf *, struct drbd_backing_dev *, int);
 enum determine_dev_size { dev_size_error = -1, unchanged = 0, shrunk = 1, grew = 2 };
-extern enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *) __must_hold(local);
+extern enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *, int force) __must_hold(local);
 extern void resync_after_online_grow(struct drbd_conf *);
 extern void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int) __must_hold(local);
 extern int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role,
index 9348f33..e898ad9 100644 (file)
@@ -1298,6 +1298,7 @@ static void after_state_ch(struct drbd_conf *mdev, union drbd_state os,
                                dev_err(DEV, "Sending state in drbd_io_error() failed\n");
                }
 
+               wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt));
                lc_destroy(mdev->resync);
                mdev->resync = NULL;
                lc_destroy(mdev->act_log);
index 4e0726a..1292e06 100644 (file)
@@ -510,7 +510,7 @@ void drbd_resume_io(struct drbd_conf *mdev)
  * Returns 0 on success, negative return values indicate errors.
  * You should call drbd_md_sync() after calling this function.
  */
-enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *mdev) __must_hold(local)
+enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *mdev, int force) __must_hold(local)
 {
        sector_t prev_first_sect, prev_size; /* previous meta location */
        sector_t la_size;
@@ -541,7 +541,7 @@ enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *mdev) __must_ho
        /* TODO: should only be some assert here, not (re)init... */
        drbd_md_set_sector_offsets(mdev, mdev->ldev);
 
-       size = drbd_new_dev_size(mdev, mdev->ldev);
+       size = drbd_new_dev_size(mdev, mdev->ldev, force);
 
        if (drbd_get_capacity(mdev->this_bdev) != size ||
            drbd_bm_capacity(mdev) != size) {
@@ -596,7 +596,7 @@ out:
 }
 
 sector_t
-drbd_new_dev_size(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
+drbd_new_dev_size(struct drbd_conf *mdev, struct drbd_backing_dev *bdev, int assume_peer_has_space)
 {
        sector_t p_size = mdev->p_size;   /* partner's disk size. */
        sector_t la_size = bdev->md.la_size_sect; /* last agreed size. */
@@ -606,6 +606,11 @@ drbd_new_dev_size(struct drbd_conf *mdev, struct drbd_backing_dev *bdev)
 
        m_size = drbd_get_max_capacity(bdev);
 
+       if (mdev->state.conn < C_CONNECTED && assume_peer_has_space) {
+               dev_warn(DEV, "Resize while not connected was forced by the user!\n");
+               p_size = m_size;
+       }
+
        if (p_size && m_size) {
                size = min_t(sector_t, p_size, m_size);
        } else {
@@ -965,7 +970,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
 
        /* Prevent shrinking of consistent devices ! */
        if (drbd_md_test_flag(nbc, MDF_CONSISTENT) &&
-          drbd_new_dev_size(mdev, nbc) < nbc->md.la_size_sect) {
+           drbd_new_dev_size(mdev, nbc, 0) < nbc->md.la_size_sect) {
                dev_warn(DEV, "refusing to truncate a consistent device\n");
                retcode = ERR_DISK_TO_SMALL;
                goto force_diskless_dec;
@@ -1052,7 +1057,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
            !drbd_md_test_flag(mdev->ldev, MDF_CONNECTED_IND))
                set_bit(USE_DEGR_WFC_T, &mdev->flags);
 
-       dd = drbd_determin_dev_size(mdev);
+       dd = drbd_determin_dev_size(mdev, 0);
        if (dd == dev_size_error) {
                retcode = ERR_NOMEM_BITMAP;
                goto force_diskless_dec;
@@ -1271,7 +1276,7 @@ static int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
                        goto fail;
                }
 
-               if (crypto_tfm_alg_type(crypto_hash_tfm(tfm)) != CRYPTO_ALG_TYPE_SHASH) {
+               if (!drbd_crypto_is_hash(crypto_hash_tfm(tfm))) {
                        retcode = ERR_AUTH_ALG_ND;
                        goto fail;
                }
@@ -1504,7 +1509,7 @@ static int drbd_nl_resize(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
        }
 
        mdev->ldev->dc.disk_size = (sector_t)rs.resize_size;
-       dd = drbd_determin_dev_size(mdev);
+       dd = drbd_determin_dev_size(mdev, rs.resize_force);
        drbd_md_sync(mdev);
        put_ldev(mdev);
        if (dd == dev_size_error) {
index 259c135..f22a528 100644 (file)
@@ -878,9 +878,13 @@ retry:
 
        if (mdev->cram_hmac_tfm) {
                /* drbd_request_state(mdev, NS(conn, WFAuth)); */
-               if (!drbd_do_auth(mdev)) {
+               switch (drbd_do_auth(mdev)) {
+               case -1:
                        dev_err(DEV, "Authentication of peer failed\n");
                        return -1;
+               case 0:
+                       dev_err(DEV, "Authentication of peer failed, trying again.\n");
+                       return 0;
                }
        }
 
@@ -1201,10 +1205,11 @@ static int receive_Barrier(struct drbd_conf *mdev, struct p_header *h)
 
        case WO_bdev_flush:
        case WO_drain_io:
-               D_ASSERT(rv == FE_STILL_LIVE);
-               set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &mdev->current_epoch->flags);
-               drbd_wait_ee_list_empty(mdev, &mdev->active_ee);
-               rv = drbd_flush_after_epoch(mdev, mdev->current_epoch);
+               if (rv == FE_STILL_LIVE) {
+                       set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &mdev->current_epoch->flags);
+                       drbd_wait_ee_list_empty(mdev, &mdev->active_ee);
+                       rv = drbd_flush_after_epoch(mdev, mdev->current_epoch);
+               }
                if (rv == FE_RECYCLED)
                        return TRUE;
 
@@ -2865,7 +2870,7 @@ static int receive_sizes(struct drbd_conf *mdev, struct p_header *h)
 
                /* Never shrink a device with usable data during connect.
                   But allow online shrinking if we are connected. */
-               if (drbd_new_dev_size(mdev, mdev->ldev) <
+               if (drbd_new_dev_size(mdev, mdev->ldev, 0) <
                   drbd_get_capacity(mdev->this_bdev) &&
                   mdev->state.disk >= D_OUTDATED &&
                   mdev->state.conn < C_CONNECTED) {
@@ -2880,7 +2885,7 @@ static int receive_sizes(struct drbd_conf *mdev, struct p_header *h)
 #undef min_not_zero
 
        if (get_ldev(mdev)) {
-               dd = drbd_determin_dev_size(mdev);
+         dd = drbd_determin_dev_size(mdev, 0);
                put_ldev(mdev);
                if (dd == dev_size_error)
                        return FALSE;
@@ -3830,10 +3835,17 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 {
        dev_err(DEV, "This kernel was build without CONFIG_CRYPTO_HMAC.\n");
        dev_err(DEV, "You need to disable 'cram-hmac-alg' in drbd.conf.\n");
-       return 0;
+       return -1;
 }
 #else
 #define CHALLENGE_LEN 64
+
+/* Return value:
+       1 - auth succeeded,
+       0 - failed, try again (network error),
+       -1 - auth failed, don't try again.
+*/
+
 static int drbd_do_auth(struct drbd_conf *mdev)
 {
        char my_challenge[CHALLENGE_LEN];  /* 64 Bytes... */
@@ -3854,7 +3866,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
                                (u8 *)mdev->net_conf->shared_secret, key_len);
        if (rv) {
                dev_err(DEV, "crypto_hash_setkey() failed with %d\n", rv);
-               rv = 0;
+               rv = -1;
                goto fail;
        }
 
@@ -3877,14 +3889,14 @@ static int drbd_do_auth(struct drbd_conf *mdev)
 
        if (p.length > CHALLENGE_LEN*2) {
                dev_err(DEV, "expected AuthChallenge payload too big.\n");
-               rv = 0;
+               rv = -1;
                goto fail;
        }
 
        peers_ch = kmalloc(p.length, GFP_NOIO);
        if (peers_ch == NULL) {
                dev_err(DEV, "kmalloc of peers_ch failed\n");
-               rv = 0;
+               rv = -1;
                goto fail;
        }
 
@@ -3900,7 +3912,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
        response = kmalloc(resp_size, GFP_NOIO);
        if (response == NULL) {
                dev_err(DEV, "kmalloc of response failed\n");
-               rv = 0;
+               rv = -1;
                goto fail;
        }
 
@@ -3910,7 +3922,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
        rv = crypto_hash_digest(&desc, &sg, sg.length, response);
        if (rv) {
                dev_err(DEV, "crypto_hash_digest() failed with %d\n", rv);
-               rv = 0;
+               rv = -1;
                goto fail;
        }
 
@@ -3944,9 +3956,9 @@ static int drbd_do_auth(struct drbd_conf *mdev)
        }
 
        right_response = kmalloc(resp_size, GFP_NOIO);
-       if (response == NULL) {
+       if (right_response == NULL) {
                dev_err(DEV, "kmalloc of right_response failed\n");
-               rv = 0;
+               rv = -1;
                goto fail;
        }
 
@@ -3955,7 +3967,7 @@ static int drbd_do_auth(struct drbd_conf *mdev)
        rv = crypto_hash_digest(&desc, &sg, sg.length, right_response);
        if (rv) {
                dev_err(DEV, "crypto_hash_digest() failed with %d\n", rv);
-               rv = 0;
+               rv = -1;
                goto fail;
        }
 
@@ -3964,6 +3976,8 @@ static int drbd_do_auth(struct drbd_conf *mdev)
        if (rv)
                dev_info(DEV, "Peer authenticated using %d bytes of '%s' HMAC\n",
                     resp_size, mdev->net_conf->cram_hmac_alg);
+       else
+               rv = -1;
 
  fail:
        kfree(peers_ch);
index be62547..4b22feb 100644 (file)
@@ -503,16 +503,15 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev,
                return 0;
        }
 
-       if (blk_stack_limits(limits, &q->limits, start << 9) < 0)
-               DMWARN("%s: target device %s is misaligned: "
+       if (bdev_stack_limits(limits, bdev, start) < 0)
+               DMWARN("%s: adding target device %s caused an alignment inconsistency: "
                       "physical_block_size=%u, logical_block_size=%u, "
                       "alignment_offset=%u, start=%llu",
                       dm_device_name(ti->table->md), bdevname(bdev, b),
                       q->limits.physical_block_size,
                       q->limits.logical_block_size,
                       q->limits.alignment_offset,
-                      (unsigned long long) start << 9);
-
+                      (unsigned long long) start << SECTOR_SHIFT);
 
        /*
         * Check if merge fn is supported.
@@ -1026,9 +1025,9 @@ combine_limits:
                 * for the table.
                 */
                if (blk_stack_limits(limits, &ti_limits, 0) < 0)
-                       DMWARN("%s: target device "
+                       DMWARN("%s: adding target device "
                               "(start sect %llu len %llu) "
-                              "is misaligned",
+                              "caused an alignment inconsistency",
                               dm_device_name(table->md),
                               (unsigned long long) ti->begin,
                               (unsigned long long) ti->len);
@@ -1079,15 +1078,6 @@ no_integrity:
 void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
                               struct queue_limits *limits)
 {
-       /*
-        * Each target device in the table has a data area that should normally
-        * be aligned such that the DM device's alignment_offset is 0.
-        * FIXME: Propagate alignment_offsets up the stack and warn of
-        *        sub-optimal or inconsistent settings.
-        */
-       limits->alignment_offset = 0;
-       limits->misaligned = 0;
-
        /*
         * Copy table's limits to the DM device's request_queue
         */
index db32c25..f526e73 100644 (file)
@@ -364,6 +364,7 @@ config EEEPC_LAPTOP
        select HWMON
        select LEDS_CLASS
        select NEW_LEDS
+       select INPUT_SPARSEKMAP
        ---help---
          This driver supports the Fn-Fx keys on Eee PC laptops.
 
index 5838c69..e2be6bb 100644 (file)
 #include <acpi/acpi_bus.h>
 #include <linux/uaccess.h>
 #include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
 #include <linux/rfkill.h>
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
 #include <linux/leds.h>
+#include <linux/dmi.h>
 
 #define EEEPC_LAPTOP_VERSION   "0.1"
 #define EEEPC_LAPTOP_NAME      "Eee PC Hotkey Driver"
@@ -48,6 +50,14 @@ MODULE_AUTHOR("Corentin Chary, Eric Cooper");
 MODULE_DESCRIPTION(EEEPC_LAPTOP_NAME);
 MODULE_LICENSE("GPL");
 
+static bool hotplug_disabled;
+
+module_param(hotplug_disabled, bool, 0644);
+MODULE_PARM_DESC(hotplug_disabled,
+                "Disable hotplug for wireless device. "
+                "If your laptop need that, please report to "
+                "acpi4asus-user@lists.sourceforge.net.");
+
 /*
  * Definitions for Asus EeePC
  */
@@ -120,38 +130,28 @@ static const char *cm_setv[] = {
        NULL, NULL, "PBPS", "TPDS"
 };
 
-struct key_entry {
-       char type;
-       u8 code;
-       u16 keycode;
-};
-
-enum { KE_KEY, KE_END };
-
 static const struct key_entry eeepc_keymap[] = {
-       /* Sleep already handled via generic ACPI code */
-       {KE_KEY, 0x10, KEY_WLAN },
-       {KE_KEY, 0x11, KEY_WLAN },
-       {KE_KEY, 0x12, KEY_PROG1 },
-       {KE_KEY, 0x13, KEY_MUTE },
-       {KE_KEY, 0x14, KEY_VOLUMEDOWN },
-       {KE_KEY, 0x15, KEY_VOLUMEUP },
-       {KE_KEY, 0x16, KEY_DISPLAY_OFF },
-       {KE_KEY, 0x1a, KEY_COFFEE },
-       {KE_KEY, 0x1b, KEY_ZOOM },
-       {KE_KEY, 0x1c, KEY_PROG2 },
-       {KE_KEY, 0x1d, KEY_PROG3 },
-       {KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN },
-       {KE_KEY, NOTIFY_BRN_MAX, KEY_BRIGHTNESSUP },
-       {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE },
-       {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE },
-       {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE },
-       {KE_KEY, 0x37, KEY_F13 }, /* Disable Touchpad */
-       {KE_KEY, 0x38, KEY_F14 },
-       {KE_END, 0},
+       { KE_KEY, 0x10, { KEY_WLAN } },
+       { KE_KEY, 0x11, { KEY_WLAN } },
+       { KE_KEY, 0x12, { KEY_PROG1 } },
+       { KE_KEY, 0x13, { KEY_MUTE } },
+       { KE_KEY, 0x14, { KEY_VOLUMEDOWN } },
+       { KE_KEY, 0x15, { KEY_VOLUMEUP } },
+       { KE_KEY, 0x16, { KEY_DISPLAY_OFF } },
+       { KE_KEY, 0x1a, { KEY_COFFEE } },
+       { KE_KEY, 0x1b, { KEY_ZOOM } },
+       { KE_KEY, 0x1c, { KEY_PROG2 } },
+       { KE_KEY, 0x1d, { KEY_PROG3 } },
+       { KE_KEY, NOTIFY_BRN_MIN, { KEY_BRIGHTNESSDOWN } },
+       { KE_KEY, NOTIFY_BRN_MAX, { KEY_BRIGHTNESSUP } },
+       { KE_KEY, 0x30, { KEY_SWITCHVIDEOMODE } },
+       { KE_KEY, 0x31, { KEY_SWITCHVIDEOMODE } },
+       { KE_KEY, 0x32, { KEY_SWITCHVIDEOMODE } },
+       { KE_KEY, 0x37, { KEY_F13 } }, /* Disable Touchpad */
+       { KE_KEY, 0x38, { KEY_F14 } },
+       { KE_END, 0 },
 };
 
-
 /*
  * This is the main structure, we can use it to store useful information
  */
@@ -159,6 +159,8 @@ struct eeepc_laptop {
        acpi_handle handle;             /* the handle of the acpi device */
        u32 cm_supported;               /* the control methods supported
                                           by this BIOS */
+       bool cpufv_disabled;
+       bool hotplug_disabled;
        u16 event_count[128];           /* count for each event */
 
        struct platform_device *platform_device;
@@ -378,6 +380,8 @@ static ssize_t store_cpufv(struct device *dev,
        struct eeepc_cpufv c;
        int rv, value;
 
+       if (eeepc->cpufv_disabled)
+               return -EPERM;
        if (get_cpufv(eeepc, &c))
                return -ENODEV;
        rv = parse_arg(buf, count, &value);
@@ -389,6 +393,41 @@ static ssize_t store_cpufv(struct device *dev,
        return rv;
 }
 
+static ssize_t show_cpufv_disabled(struct device *dev,
+                         struct device_attribute *attr,
+                         char *buf)
+{
+       struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%d\n", eeepc->cpufv_disabled);
+}
+
+static ssize_t store_cpufv_disabled(struct device *dev,
+                          struct device_attribute *attr,
+                          const char *buf, size_t count)
+{
+       struct eeepc_laptop *eeepc = dev_get_drvdata(dev);
+       int rv, value;
+
+       rv = parse_arg(buf, count, &value);
+       if (rv < 0)
+               return rv;
+
+       switch (value) {
+       case 0:
+               if (eeepc->cpufv_disabled)
+                       pr_warning("cpufv enabled (not officially supported "
+                               "on this model)\n");
+               eeepc->cpufv_disabled = false;
+               return rv;
+       case 1:
+               return -EPERM;
+       default:
+               return -EINVAL;
+       }
+}
+
+
 static struct device_attribute dev_attr_cpufv = {
        .attr = {
                .name = "cpufv",
@@ -404,12 +443,22 @@ static struct device_attribute dev_attr_available_cpufv = {
        .show   = show_available_cpufv
 };
 
+static struct device_attribute dev_attr_cpufv_disabled = {
+       .attr = {
+               .name = "cpufv_disabled",
+               .mode = 0644 },
+       .show   = show_cpufv_disabled,
+       .store  = store_cpufv_disabled
+};
+
+
 static struct attribute *platform_attributes[] = {
        &dev_attr_camera.attr,
        &dev_attr_cardr.attr,
        &dev_attr_disp.attr,
        &dev_attr_cpufv.attr,
        &dev_attr_available_cpufv.attr,
+       &dev_attr_cpufv_disabled.attr,
        NULL
 };
 
@@ -796,6 +845,9 @@ static int eeepc_rfkill_init(struct eeepc_laptop *eeepc)
        if (result && result != -ENODEV)
                goto exit;
 
+       if (eeepc->hotplug_disabled)
+               return 0;
+
        result = eeepc_setup_pci_hotplug(eeepc);
        /*
         * If we get -EBUSY then something else is handling the PCI hotplug -
@@ -1090,120 +1142,42 @@ static void eeepc_backlight_exit(struct eeepc_laptop *eeepc)
 /*
  * Input device (i.e. hotkeys)
  */
-static struct key_entry *eeepc_get_entry_by_scancode(
-       struct eeepc_laptop *eeepc,
-       int code)
+static int eeepc_input_init(struct eeepc_laptop *eeepc)
 {
-       struct key_entry *key;
+       struct input_dev *input;
+       int error;
 
-       for (key = eeepc->keymap; key->type != KE_END; key++)
-               if (code == key->code)
-                       return key;
-
-       return NULL;
-}
-
-static void eeepc_input_notify(struct eeepc_laptop *eeepc, int event)
-{
-       static struct key_entry *key;
-
-       key = eeepc_get_entry_by_scancode(eeepc, event);
-       if (key) {
-               switch (key->type) {
-               case KE_KEY:
-                       input_report_key(eeepc->inputdev, key->keycode,
-                                               1);
-                       input_sync(eeepc->inputdev);
-                       input_report_key(eeepc->inputdev, key->keycode,
-                                               0);
-                       input_sync(eeepc->inputdev);
-                       break;
-               }
+       input = input_allocate_device();
+       if (!input) {
+               pr_info("Unable to allocate input device\n");
+               return -ENOMEM;
        }
-}
-
-static struct key_entry *eeepc_get_entry_by_keycode(
-       struct eeepc_laptop *eeepc, int code)
-{
-       struct key_entry *key;
-
-       for (key = eeepc->keymap; key->type != KE_END; key++)
-               if (code == key->keycode && key->type == KE_KEY)
-                       return key;
 
-       return NULL;
-}
+       input->name = "Asus EeePC extra buttons";
+       input->phys = EEEPC_LAPTOP_FILE "/input0";
+       input->id.bustype = BUS_HOST;
+       input->dev.parent = &eeepc->platform_device->dev;
 
-static int eeepc_getkeycode(struct input_dev *dev, int scancode, int *keycode)
-{
-       struct eeepc_laptop *eeepc = input_get_drvdata(dev);
-       struct key_entry *key = eeepc_get_entry_by_scancode(eeepc, scancode);
-
-       if (key && key->type == KE_KEY) {
-               *keycode = key->keycode;
-               return 0;
+       error = sparse_keymap_setup(input, eeepc_keymap, NULL);
+       if (error) {
+               pr_err("Unable to setup input device keymap\n");
+               goto err_free_dev;
        }
 
-       return -EINVAL;
-}
-
-static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode)
-{
-       struct eeepc_laptop *eeepc = input_get_drvdata(dev);
-       struct key_entry *key;
-       int old_keycode;
-
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
-
-       key = eeepc_get_entry_by_scancode(eeepc, scancode);
-       if (key && key->type == KE_KEY) {
-               old_keycode = key->keycode;
-               key->keycode = keycode;
-               set_bit(keycode, dev->keybit);
-               if (!eeepc_get_entry_by_keycode(eeepc, old_keycode))
-                       clear_bit(old_keycode, dev->keybit);
-               return 0;
+       error = input_register_device(input);
+       if (error) {
+               pr_err("Unable to register input device\n");
+               goto err_free_keymap;
        }
 
-       return -EINVAL;
-}
-
-static int eeepc_input_init(struct eeepc_laptop *eeepc)
-{
-       const struct key_entry *key;
-       int result;
-
-       eeepc->inputdev = input_allocate_device();
-       if (!eeepc->inputdev) {
-               pr_info("Unable to allocate input device\n");
-               return -ENOMEM;
-       }
-       eeepc->inputdev->name = "Asus EeePC extra buttons";
-       eeepc->inputdev->dev.parent = &eeepc->platform_device->dev;
-       eeepc->inputdev->phys = EEEPC_LAPTOP_FILE "/input0";
-       eeepc->inputdev->id.bustype = BUS_HOST;
-       eeepc->inputdev->getkeycode = eeepc_getkeycode;
-       eeepc->inputdev->setkeycode = eeepc_setkeycode;
-       input_set_drvdata(eeepc->inputdev, eeepc);
-
-       eeepc->keymap = kmemdup(eeepc_keymap, sizeof(eeepc_keymap),
-                               GFP_KERNEL);
-       for (key = eeepc_keymap; key->type != KE_END; key++) {
-               switch (key->type) {
-               case KE_KEY:
-                       set_bit(EV_KEY, eeepc->inputdev->evbit);
-                       set_bit(key->keycode, eeepc->inputdev->keybit);
-                       break;
-               }
-       }
-       result = input_register_device(eeepc->inputdev);
-       if (result) {
-               pr_info("Unable to register input device\n");
-               input_free_device(eeepc->inputdev);
-               return result;
-       }
+       eeepc->inputdev = input;
        return 0;
+
+ err_free_keymap:
+       sparse_keymap_free(input);
+ err_free_dev:
+       input_free_device(input);
+       return error;
 }
 
 static void eeepc_input_exit(struct eeepc_laptop *eeepc)
@@ -1253,11 +1227,59 @@ static void eeepc_acpi_notify(struct acpi_device *device, u32 event)
                                * event will be desired value (or else ignored)
                                */
                        }
-                       eeepc_input_notify(eeepc, event);
+                       sparse_keymap_report_event(eeepc->inputdev, event,
+                                                  1, true);
                }
        } else {
                /* Everything else is a bona-fide keypress event */
-               eeepc_input_notify(eeepc, event);
+               sparse_keymap_report_event(eeepc->inputdev, event, 1, true);
+       }
+}
+
+static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
+{
+       const char *model;
+
+       model = dmi_get_system_info(DMI_PRODUCT_NAME);
+       if (!model)
+               return;
+
+       /*
+        * Blacklist for setting cpufv (cpu speed).
+        *
+        * EeePC 4G ("701") implements CFVS, but it is not supported
+        * by the pre-installed OS, and the original option to change it
+        * in the BIOS setup screen was removed in later versions.
+        *
+        * Judging by the lack of "Super Hybrid Engine" on Asus product pages,
+        * this applies to all "701" models (4G/4G Surf/2G Surf).
+        *
+        * So Asus made a deliberate decision not to support it on this model.
+        * We have several reports that using it can cause the system to hang
+        *
+        * The hang has also been reported on a "702" (Model name "8G"?).
+        *
+        * We avoid dmi_check_system() / dmi_match(), because they use
+        * substring matching.  We don't want to affect the "701SD"
+        * and "701SDX" models, because they do support S.H.E.
+        */
+       if (strcmp(model, "701") == 0 || strcmp(model, "702") == 0) {
+               eeepc->cpufv_disabled = true;
+               pr_info("model %s does not officially support setting cpu "
+                       "speed\n", model);
+               pr_info("cpufv disabled to avoid instability\n");
+       }
+
+       /*
+        * Blacklist for wlan hotplug
+        *
+        * Eeepc 1005HA doesn't work like others models and don't need the
+        * hotplug code. In fact, current hotplug code seems to unplug another
+        * device...
+        */
+       if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0) {
+               eeepc->hotplug_disabled = true;
+               pr_info("wlan hotplug disabled\n");
        }
 }
 
@@ -1342,6 +1364,10 @@ static int __devinit eeepc_acpi_add(struct acpi_device *device)
        strcpy(acpi_device_class(device), EEEPC_ACPI_CLASS);
        device->driver_data = eeepc;
 
+       eeepc->hotplug_disabled = hotplug_disabled;
+
+       eeepc_dmi_check(eeepc);
+
        result = eeepc_acpi_init(eeepc, device);
        if (result)
                goto fail_platform;
@@ -1452,10 +1478,12 @@ static int __init eeepc_laptop_init(void)
        result = acpi_bus_register_driver(&eeepc_acpi_driver);
        if (result < 0)
                goto fail_acpi_driver;
+
        if (!eeepc_device_present) {
                result = -ENODEV;
                goto fail_no_device;
        }
+
        return 0;
 
 fail_no_device:
index 5af5334..3f71a60 100644 (file)
@@ -1201,9 +1201,12 @@ static void sony_nc_rfkill_setup(struct acpi_device *device)
        /* the buffer is filled with magic numbers describing the devices
         * available, 0xff terminates the enumeration
         */
-       while ((dev_code = *(device_enum->buffer.pointer + i)) != 0xff &&
-                       i < device_enum->buffer.length) {
-               i++;
+       for (i = 0; i < device_enum->buffer.length; i++) {
+
+               dev_code = *(device_enum->buffer.pointer + i);
+               if (dev_code == 0xff)
+                       break;
+
                dprintk("Radio devices, looking at 0x%.2x\n", dev_code);
 
                if (dev_code == 0 && !sony_rfkill_devices[SONY_WIFI])
index 96f1171..355dffc 100644 (file)
@@ -494,7 +494,7 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
                return 0;
        /* allocate 2^1 pages = 8K (on i386);
         * should be more than enough for one device */
-       pages_start = (char *)__get_free_pages(GFP_KERNEL, 1);
+       pages_start = (char *)__get_free_pages(GFP_NOIO, 1);
        if (!pages_start)
                return -ENOMEM;
 
index 0495fa6..80995ef 100644 (file)
@@ -1684,6 +1684,24 @@ int usb_hcd_alloc_bandwidth(struct usb_device *udev,
                }
        }
        if (cur_alt && new_alt) {
+               struct usb_interface *iface = usb_ifnum_to_if(udev,
+                               cur_alt->desc.bInterfaceNumber);
+
+               if (iface->resetting_device) {
+                       /*
+                        * The USB core just reset the device, so the xHCI host
+                        * and the device will think alt setting 0 is installed.
+                        * However, the USB core will pass in the alternate
+                        * setting installed before the reset as cur_alt.  Dig
+                        * out the alternate setting 0 structure, or the first
+                        * alternate setting if a broken device doesn't have alt
+                        * setting 0.
+                        */
+                       cur_alt = usb_altnum_to_altsetting(iface, 0);
+                       if (!cur_alt)
+                               cur_alt = &iface->altsetting[0];
+               }
+
                /* Drop all the endpoints in the current alt setting */
                for (i = 0; i < cur_alt->desc.bNumEndpoints; i++) {
                        ret = hcd->driver->drop_endpoint(hcd, udev,
index 0cec6ca..35cc8b9 100644 (file)
@@ -3347,6 +3347,9 @@ static void hub_events(void)
                                        USB_PORT_FEAT_C_SUSPEND);
                                udev = hdev->children[i-1];
                                if (udev) {
+                                       /* TRSMRCY = 10 msec */
+                                       msleep(10);
+
                                        usb_lock_device(udev);
                                        ret = remote_wakeup(hdev->
                                                        children[i-1]);
@@ -3692,19 +3695,14 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
                        usb_enable_interface(udev, intf, true);
                        ret = 0;
                } else {
-                       /* We've just reset the device, so it will think alt
-                        * setting 0 is installed.  For usb_set_interface() to
-                        * work properly, we need to set the current alternate
-                        * interface setting to 0 (or the first alt setting, if
-                        * the device doesn't have alt setting 0).
+                       /* Let the bandwidth allocation function know that this
+                        * device has been reset, and it will have to use
+                        * alternate setting 0 as the current alternate setting.
                         */
-                       intf->cur_altsetting =
-                               usb_find_alt_setting(config, i, 0);
-                       if (!intf->cur_altsetting)
-                               intf->cur_altsetting =
-                                       &config->intf_cache[i]->altsetting[0];
+                       intf->resetting_device = 1;
                        ret = usb_set_interface(udev, desc->bInterfaceNumber,
                                        desc->bAlternateSetting);
+                       intf->resetting_device = 0;
                }
                if (ret < 0) {
                        dev_err(&udev->dev, "failed to restore interface %d "
index 1b99484..9bc95fe 100644 (file)
@@ -906,11 +906,11 @@ char *usb_cache_string(struct usb_device *udev, int index)
        if (index <= 0)
                return NULL;
 
-       buf = kmalloc(MAX_USB_STRING_SIZE, GFP_KERNEL);
+       buf = kmalloc(MAX_USB_STRING_SIZE, GFP_NOIO);
        if (buf) {
                len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE);
                if (len > 0) {
-                       smallbuf = kmalloc(++len, GFP_KERNEL);
+                       smallbuf = kmalloc(++len, GFP_NOIO);
                        if (!smallbuf)
                                return buf;
                        memcpy(smallbuf, buf, len);
@@ -1731,7 +1731,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
        if (cp) {
                nintf = cp->desc.bNumInterfaces;
                new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
-                               GFP_KERNEL);
+                               GFP_NOIO);
                if (!new_interfaces) {
                        dev_err(&dev->dev, "Out of memory\n");
                        return -ENOMEM;
@@ -1740,7 +1740,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
                for (; n < nintf; ++n) {
                        new_interfaces[n] = kzalloc(
                                        sizeof(struct usb_interface),
-                                       GFP_KERNEL);
+                                       GFP_NOIO);
                        if (!new_interfaces[n]) {
                                dev_err(&dev->dev, "Out of memory\n");
                                ret = -ENOMEM;
index 485edf9..5f3908f 100644 (file)
@@ -115,6 +115,12 @@ show_speed(struct device *dev, struct device_attribute *attr, char *buf)
        case USB_SPEED_HIGH:
                speed = "480";
                break;
+       case USB_SPEED_VARIABLE:
+               speed = "480";
+               break;
+       case USB_SPEED_SUPER:
+               speed = "5000";
+               break;
        default:
                speed = "unknown";
        }
index 5859522..1ec3857 100644 (file)
@@ -787,9 +787,10 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 
                        /* start 20 msec resume signaling from this port,
                         * and make khubd collect PORT_STAT_C_SUSPEND to
-                        * stop that signaling.
+                        * stop that signaling.  Use 5 ms extra for safety,
+                        * like usb_port_resume() does.
                         */
-                       ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
+                       ehci->reset_done[i] = jiffies + msecs_to_jiffies(25);
                        ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
                        mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
                }
index 2c6571c..c75d927 100644 (file)
@@ -120,9 +120,26 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
        del_timer_sync(&ehci->watchdog);
        del_timer_sync(&ehci->iaa_watchdog);
 
-       port = HCS_N_PORTS (ehci->hcs_params);
        spin_lock_irq (&ehci->lock);
 
+       /* Once the controller is stopped, port resumes that are already
+        * in progress won't complete.  Hence if remote wakeup is enabled
+        * for the root hub and any ports are in the middle of a resume or
+        * remote wakeup, we must fail the suspend.
+        */
+       if (hcd->self.root_hub->do_remote_wakeup) {
+               port = HCS_N_PORTS(ehci->hcs_params);
+               while (port--) {
+                       if (ehci->reset_done[port] != 0) {
+                               spin_unlock_irq(&ehci->lock);
+                               ehci_dbg(ehci, "suspend failed because "
+                                               "port %d is resuming\n",
+                                               port + 1);
+                               return -EBUSY;
+                       }
+               }
+       }
+
        /* stop schedules, clean any completed work */
        if (HC_IS_RUNNING(hcd->state)) {
                ehci_quiesce (ehci);
@@ -138,6 +155,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
         */
        ehci->bus_suspended = 0;
        ehci->owned_ports = 0;
+       port = HCS_N_PORTS(ehci->hcs_params);
        while (port--) {
                u32 __iomem     *reg = &ehci->regs->port_status [port];
                u32             t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
index a427d3b..8952177 100644 (file)
@@ -849,9 +849,10 @@ qh_make (
                                 * But interval 1 scheduling is simpler, and
                                 * includes high bandwidth.
                                 */
-                               dbg ("intr period %d uframes, NYET!",
-                                               urb->interval);
-                               goto done;
+                               urb->interval = 1;
+                       } else if (qh->period > ehci->periodic_size) {
+                               qh->period = ehci->periodic_size;
+                               urb->interval = qh->period << 3;
                        }
                } else {
                        int             think_time;
@@ -874,6 +875,10 @@ qh_make (
                                        usb_calc_bus_time (urb->dev->speed,
                                        is_input, 0, max_packet (maxp)));
                        qh->period = urb->interval;
+                       if (qh->period > ehci->periodic_size) {
+                               qh->period = ehci->periodic_size;
+                               urb->interval = qh->period;
+                       }
                }
        }
 
index 0951818..78e7c3c 100644 (file)
@@ -242,9 +242,10 @@ err:
 static void fhci_usb_free(void *lld)
 {
        struct fhci_usb *usb = lld;
-       struct fhci_hcd *fhci = usb->fhci;
+       struct fhci_hcd *fhci;
 
        if (usb) {
+               fhci = usb->fhci;
                fhci_config_transceiver(fhci, FHCI_PORT_POWER_OFF);
                fhci_ep0_free(usb);
                kfree(usb->actual_frame);
index 73352f3..4297165 100644 (file)
@@ -2270,10 +2270,10 @@ static int isp1362_mem_config(struct usb_hcd *hcd)
        dev_info(hcd->self.controller, "ISP1362 Memory usage:\n");
        dev_info(hcd->self.controller, "  ISTL:    2 * %4d:     %4d @ $%04x:$%04x\n",
                 istl_size / 2, istl_size, 0, istl_size / 2);
-       dev_info(hcd->self.controller, "  INTL: %4d * (%3lu+8):  %4d @ $%04x\n",
+       dev_info(hcd->self.controller, "  INTL: %4d * (%3zu+8):  %4d @ $%04x\n",
                 ISP1362_INTL_BUFFERS, intl_blksize - PTD_HEADER_SIZE,
                 intl_size, istl_size);
-       dev_info(hcd->self.controller, "  ATL : %4d * (%3lu+8):  %4d @ $%04x\n",
+       dev_info(hcd->self.controller, "  ATL : %4d * (%3zu+8):  %4d @ $%04x\n",
                 atl_buffers, atl_blksize - PTD_HEADER_SIZE,
                 atl_size, istl_size + intl_size);
        dev_info(hcd->self.controller, "  USED/FREE:   %4d      %4d\n", total,
@@ -2697,6 +2697,8 @@ static int __init isp1362_probe(struct platform_device *pdev)
        void __iomem *data_reg;
        int irq;
        int retval = 0;
+       struct resource *irq_res;
+       unsigned int irq_flags = 0;
 
        /* basic sanity checks first.  board-specific init logic should
         * have initialized this the three resources and probably board
@@ -2710,11 +2712,12 @@ static int __init isp1362_probe(struct platform_device *pdev)
 
        data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-       irq = platform_get_irq(pdev, 0);
-       if (!addr || !data || irq < 0) {
+       irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!addr || !data || !irq_res) {
                retval = -ENODEV;
                goto err1;
        }
+       irq = irq_res->start;
 
 #ifdef CONFIG_USB_HCD_DMA
        if (pdev->dev.dma_mask) {
@@ -2781,12 +2784,16 @@ static int __init isp1362_probe(struct platform_device *pdev)
        }
 #endif
 
-#ifdef CONFIG_ARM
-       if (isp1362_hcd->board)
-               set_irq_type(irq, isp1362_hcd->board->int_act_high ? IRQT_RISING : IRQT_FALLING);
-#endif
+       if (irq_res->flags & IORESOURCE_IRQ_HIGHEDGE)
+               irq_flags |= IRQF_TRIGGER_RISING;
+       if (irq_res->flags & IORESOURCE_IRQ_LOWEDGE)
+               irq_flags |= IRQF_TRIGGER_FALLING;
+       if (irq_res->flags & IORESOURCE_IRQ_HIGHLEVEL)
+               irq_flags |= IRQF_TRIGGER_HIGH;
+       if (irq_res->flags & IORESOURCE_IRQ_LOWLEVEL)
+               irq_flags |= IRQF_TRIGGER_LOW;
 
-       retval = usb_add_hcd(hcd, irq, IRQF_TRIGGER_LOW | IRQF_DISABLED | IRQF_SHARED);
+       retval = usb_add_hcd(hcd, irq, irq_flags | IRQF_DISABLED | IRQF_SHARED);
        if (retval != 0)
                goto err6;
        pr_info("%s, irq %d\n", hcd->product_desc, irq);
index 9600a58..27b8f7c 100644 (file)
@@ -1039,12 +1039,12 @@ static void do_atl_int(struct usb_hcd *usb_hcd)
                if (!nakcount && (dw3 & DW3_QTD_ACTIVE)) {
                        u32 buffstatus;
 
-                       /* XXX
+                       /*
                         * NAKs are handled in HW by the chip. Usually if the
                         * device is not able to send data fast enough.
-                        * This did not trigger for a long time now.
+                        * This happens mostly on slower hardware.
                         */
-                       printk(KERN_ERR "Reloading ptd %p/%p... qh %p readed: "
+                       printk(KERN_NOTICE "Reloading ptd %p/%p... qh %p read: "
                                        "%d of %zu done: %08x cur: %08x\n", qtd,
                                        urb, qh, PTD_XFERRED_LENGTH(dw3),
                                        qtd->length, done_map,
index 5cd0e48..99cd00f 100644 (file)
@@ -749,7 +749,20 @@ static int uhci_rh_suspend(struct usb_hcd *hcd)
        spin_lock_irq(&uhci->lock);
        if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
                rc = -ESHUTDOWN;
-       else if (!uhci->dead)
+       else if (uhci->dead)
+               ;               /* Dead controllers tell no tales */
+
+       /* Once the controller is stopped, port resumes that are already
+        * in progress won't complete.  Hence if remote wakeup is enabled
+        * for the root hub and any ports are in the middle of a resume or
+        * remote wakeup, we must fail the suspend.
+        */
+       else if (hcd->self.root_hub->do_remote_wakeup &&
+                       uhci->resuming_ports) {
+               dev_dbg(uhci_dev(uhci), "suspend failed because a port "
+                               "is resuming\n");
+               rc = -EBUSY;
+       } else
                suspend_rh(uhci, UHCI_RH_SUSPENDED);
        spin_unlock_irq(&uhci->lock);
        return rc;
index 885b585..8270055 100644 (file)
@@ -167,7 +167,7 @@ static void uhci_check_ports(struct uhci_hcd *uhci)
                                /* Port received a wakeup request */
                                set_bit(port, &uhci->resuming_ports);
                                uhci->ports_timeout = jiffies +
-                                               msecs_to_jiffies(20);
+                                               msecs_to_jiffies(25);
 
                                /* Make sure we see the port again
                                 * after the resuming period is over. */
index f1ea3a3..83443d6 100644 (file)
@@ -386,12 +386,12 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)
 
        dbg("%s - port %d", __func__, port->number);
 
-       if (serial->type->max_in_flight_urbs) {
-               spin_lock_irqsave(&port->lock, flags);
+       spin_lock_irqsave(&port->lock, flags);
+       if (serial->type->max_in_flight_urbs)
                chars = port->tx_bytes_flight;
-               spin_unlock_irqrestore(&port->lock, flags);
-       } else if (serial->num_bulk_out)
+       else if (serial->num_bulk_out)
                chars = kfifo_len(&port->write_fifo);
+       spin_unlock_irqrestore(&port->lock, flags);
 
        dbg("%s - returns %d", __func__, chars);
        return chars;
@@ -489,6 +489,8 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb)
        dbg("%s - port %d", __func__, port->number);
 
        if (port->serial->type->max_in_flight_urbs) {
+               kfree(urb->transfer_buffer);
+
                spin_lock_irqsave(&port->lock, flags);
                --port->urbs_in_flight;
                port->tx_bytes_flight -= urb->transfer_buffer_length;
index 64a0a2c..c932f90 100644 (file)
@@ -1807,13 +1807,6 @@ UNUSUAL_DEV(  0x2735, 0x100b, 0x0000, 0x9999,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_GO_SLOW ),
 
-/* Reported by Rohan Hart <rohan.hart17@gmail.com> */
-UNUSUAL_DEV(  0x2770, 0x915d, 0x0010, 0x0010,
-               "INTOVA",
-               "Pixtreme",
-               US_SC_DEVICE, US_PR_DEVICE, NULL,
-               US_FL_FIX_CAPACITY ),
-
 /* Reported by Frederic Marchal <frederic.marchal@wowcompany.com>
  * Mio Moov 330
  */
index 5a53d4f..e9f9954 100644 (file)
@@ -434,7 +434,8 @@ static void adjust_quirks(struct us_data *us)
        u16 vid = le16_to_cpu(us->pusb_dev->descriptor.idVendor);
        u16 pid = le16_to_cpu(us->pusb_dev->descriptor.idProduct);
        unsigned f = 0;
-       unsigned int mask = (US_FL_SANE_SENSE | US_FL_FIX_CAPACITY |
+       unsigned int mask = (US_FL_SANE_SENSE | US_FL_BAD_SENSE |
+                       US_FL_FIX_CAPACITY |
                        US_FL_CAPACITY_HEURISTICS | US_FL_IGNORE_DEVICE |
                        US_FL_NOT_LOCKABLE | US_FL_MAX_SECTORS_64 |
                        US_FL_CAPACITY_OK | US_FL_IGNORE_RESIDUE |
index 76e6713..12429c9 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -78,7 +78,7 @@ static struct kmem_cache *bio_find_or_create_slab(unsigned int extra_size)
 
        i = 0;
        while (i < bio_slab_nr) {
-               struct bio_slab *bslab = &bio_slabs[i];
+               bslab = &bio_slabs[i];
 
                if (!bslab->slab && entry == -1)
                        entry = i;
index 2e9e699..54f4798 100644 (file)
@@ -112,12 +112,14 @@ static int btrfs_set_acl(struct btrfs_trans_handle *trans,
        switch (type) {
        case ACL_TYPE_ACCESS:
                mode = inode->i_mode;
-               ret = posix_acl_equiv_mode(acl, &mode);
-               if (ret < 0)
-                       return ret;
-               ret = 0;
-               inode->i_mode = mode;
                name = POSIX_ACL_XATTR_ACCESS;
+               if (acl) {
+                       ret = posix_acl_equiv_mode(acl, &mode);
+                       if (ret < 0)
+                               return ret;
+                       inode->i_mode = mode;
+               }
+               ret = 0;
                break;
        case ACL_TYPE_DEFAULT:
                if (!S_ISDIR(inode->i_mode))
index 56e5013..432a2da 100644 (file)
@@ -83,6 +83,17 @@ static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits)
        return (cache->flags & bits) == bits;
 }
 
+void btrfs_get_block_group(struct btrfs_block_group_cache *cache)
+{
+       atomic_inc(&cache->count);
+}
+
+void btrfs_put_block_group(struct btrfs_block_group_cache *cache)
+{
+       if (atomic_dec_and_test(&cache->count))
+               kfree(cache);
+}
+
 /*
  * this adds the block group to the fs_info rb tree for the block group
  * cache
@@ -156,7 +167,7 @@ block_group_cache_tree_search(struct btrfs_fs_info *info, u64 bytenr,
                }
        }
        if (ret)
-               atomic_inc(&ret->count);
+               btrfs_get_block_group(ret);
        spin_unlock(&info->block_group_cache_lock);
 
        return ret;
@@ -407,6 +418,8 @@ err:
 
        put_caching_control(caching_ctl);
        atomic_dec(&block_group->space_info->caching_threads);
+       btrfs_put_block_group(block_group);
+
        return 0;
 }
 
@@ -447,6 +460,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache)
        up_write(&fs_info->extent_commit_sem);
 
        atomic_inc(&cache->space_info->caching_threads);
+       btrfs_get_block_group(cache);
 
        tsk = kthread_run(caching_kthread, cache, "btrfs-cache-%llu\n",
                          cache->key.objectid);
@@ -486,12 +500,6 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(
        return cache;
 }
 
-void btrfs_put_block_group(struct btrfs_block_group_cache *cache)
-{
-       if (atomic_dec_and_test(&cache->count))
-               kfree(cache);
-}
-
 static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info,
                                                  u64 flags)
 {
@@ -2582,7 +2590,7 @@ next_block_group(struct btrfs_root *root,
        if (node) {
                cache = rb_entry(node, struct btrfs_block_group_cache,
                                 cache_node);
-               atomic_inc(&cache->count);
+               btrfs_get_block_group(cache);
        } else
                cache = NULL;
        spin_unlock(&root->fs_info->block_group_cache_lock);
@@ -4227,7 +4235,7 @@ search:
                u64 offset;
                int cached;
 
-               atomic_inc(&block_group->count);
+               btrfs_get_block_group(block_group);
                search_start = block_group->key.objectid;
 
 have_block_group:
@@ -4315,7 +4323,7 @@ have_block_group:
 
                                btrfs_put_block_group(block_group);
                                block_group = last_ptr->block_group;
-                               atomic_inc(&block_group->count);
+                               btrfs_get_block_group(block_group);
                                spin_unlock(&last_ptr->lock);
                                spin_unlock(&last_ptr->refill_lock);
 
@@ -7395,9 +7403,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
                        wait_block_group_cache_done(block_group);
 
                btrfs_remove_free_space_cache(block_group);
-
-               WARN_ON(atomic_read(&block_group->count) != 1);
-               kfree(block_group);
+               btrfs_put_block_group(block_group);
 
                spin_lock(&info->block_group_cache_lock);
        }
index feaa13b..c020335 100644 (file)
@@ -506,7 +506,8 @@ next_slot:
 }
 
 static int extent_mergeable(struct extent_buffer *leaf, int slot,
-                           u64 objectid, u64 bytenr, u64 *start, u64 *end)
+                           u64 objectid, u64 bytenr, u64 orig_offset,
+                           u64 *start, u64 *end)
 {
        struct btrfs_file_extent_item *fi;
        struct btrfs_key key;
@@ -522,6 +523,7 @@ static int extent_mergeable(struct extent_buffer *leaf, int slot,
        fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
        if (btrfs_file_extent_type(leaf, fi) != BTRFS_FILE_EXTENT_REG ||
            btrfs_file_extent_disk_bytenr(leaf, fi) != bytenr ||
+           btrfs_file_extent_offset(leaf, fi) != key.offset - orig_offset ||
            btrfs_file_extent_compression(leaf, fi) ||
            btrfs_file_extent_encryption(leaf, fi) ||
            btrfs_file_extent_other_encoding(leaf, fi))
@@ -561,6 +563,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
        u64 split;
        int del_nr = 0;
        int del_slot = 0;
+       int recow;
        int ret;
 
        btrfs_drop_extent_cache(inode, start, end - 1, 0);
@@ -568,6 +571,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
        path = btrfs_alloc_path();
        BUG_ON(!path);
 again:
+       recow = 0;
        split = start;
        key.objectid = inode->i_ino;
        key.type = BTRFS_EXTENT_DATA_KEY;
@@ -591,12 +595,60 @@ again:
        bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
        num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi);
        orig_offset = key.offset - btrfs_file_extent_offset(leaf, fi);
+       memcpy(&new_key, &key, sizeof(new_key));
+
+       if (start == key.offset && end < extent_end) {
+               other_start = 0;
+               other_end = start;
+               if (extent_mergeable(leaf, path->slots[0] - 1,
+                                    inode->i_ino, bytenr, orig_offset,
+                                    &other_start, &other_end)) {
+                       new_key.offset = end;
+                       btrfs_set_item_key_safe(trans, root, path, &new_key);
+                       fi = btrfs_item_ptr(leaf, path->slots[0],
+                                           struct btrfs_file_extent_item);
+                       btrfs_set_file_extent_num_bytes(leaf, fi,
+                                                       extent_end - end);
+                       btrfs_set_file_extent_offset(leaf, fi,
+                                                    end - orig_offset);
+                       fi = btrfs_item_ptr(leaf, path->slots[0] - 1,
+                                           struct btrfs_file_extent_item);
+                       btrfs_set_file_extent_num_bytes(leaf, fi,
+                                                       end - other_start);
+                       btrfs_mark_buffer_dirty(leaf);
+                       goto out;
+               }
+       }
+
+       if (start > key.offset && end == extent_end) {
+               other_start = end;
+               other_end = 0;
+               if (extent_mergeable(leaf, path->slots[0] + 1,
+                                    inode->i_ino, bytenr, orig_offset,
+                                    &other_start, &other_end)) {
+                       fi = btrfs_item_ptr(leaf, path->slots[0],
+                                           struct btrfs_file_extent_item);
+                       btrfs_set_file_extent_num_bytes(leaf, fi,
+                                                       start - key.offset);
+                       path->slots[0]++;
+                       new_key.offset = start;
+                       btrfs_set_item_key_safe(trans, root, path, &new_key);
+
+                       fi = btrfs_item_ptr(leaf, path->slots[0],
+                                           struct btrfs_file_extent_item);
+                       btrfs_set_file_extent_num_bytes(leaf, fi,
+                                                       other_end - start);
+                       btrfs_set_file_extent_offset(leaf, fi,
+                                                    start - orig_offset);
+                       btrfs_mark_buffer_dirty(leaf);
+                       goto out;
+               }
+       }
 
        while (start > key.offset || end < extent_end) {
                if (key.offset == start)
                        split = end;
 
-               memcpy(&new_key, &key, sizeof(new_key));
                new_key.offset = split;
                ret = btrfs_duplicate_item(trans, root, path, &new_key);
                if (ret == -EAGAIN) {
@@ -631,15 +683,18 @@ again:
                        path->slots[0]--;
                        extent_end = end;
                }
+               recow = 1;
        }
 
-       fi = btrfs_item_ptr(leaf, path->slots[0],
-                           struct btrfs_file_extent_item);
-
        other_start = end;
        other_end = 0;
-       if (extent_mergeable(leaf, path->slots[0] + 1, inode->i_ino,
-                            bytenr, &other_start, &other_end)) {
+       if (extent_mergeable(leaf, path->slots[0] + 1,
+                            inode->i_ino, bytenr, orig_offset,
+                            &other_start, &other_end)) {
+               if (recow) {
+                       btrfs_release_path(root, path);
+                       goto again;
+               }
                extent_end = other_end;
                del_slot = path->slots[0] + 1;
                del_nr++;
@@ -650,8 +705,13 @@ again:
        }
        other_start = 0;
        other_end = start;
-       if (extent_mergeable(leaf, path->slots[0] - 1, inode->i_ino,
-                            bytenr, &other_start, &other_end)) {
+       if (extent_mergeable(leaf, path->slots[0] - 1,
+                            inode->i_ino, bytenr, orig_offset,
+                            &other_start, &other_end)) {
+               if (recow) {
+                       btrfs_release_path(root, path);
+                       goto again;
+               }
                key.offset = other_start;
                del_slot = path->slots[0];
                del_nr++;
@@ -660,22 +720,22 @@ again:
                                        inode->i_ino, orig_offset);
                BUG_ON(ret);
        }
+       fi = btrfs_item_ptr(leaf, path->slots[0],
+                          struct btrfs_file_extent_item);
        if (del_nr == 0) {
                btrfs_set_file_extent_type(leaf, fi,
                                           BTRFS_FILE_EXTENT_REG);
                btrfs_mark_buffer_dirty(leaf);
-               goto out;
-       }
-
-       fi = btrfs_item_ptr(leaf, del_slot - 1,
-                           struct btrfs_file_extent_item);
-       btrfs_set_file_extent_type(leaf, fi, BTRFS_FILE_EXTENT_REG);
-       btrfs_set_file_extent_num_bytes(leaf, fi,
-                                       extent_end - key.offset);
-       btrfs_mark_buffer_dirty(leaf);
+       } else {
+               btrfs_set_file_extent_type(leaf, fi,
+                                          BTRFS_FILE_EXTENT_REG);
+               btrfs_set_file_extent_num_bytes(leaf, fi,
+                                               extent_end - key.offset);
+               btrfs_mark_buffer_dirty(leaf);
 
-       ret = btrfs_del_items(trans, root, path, del_slot, del_nr);
-       BUG_ON(ret);
+               ret = btrfs_del_items(trans, root, path, del_slot, del_nr);
+               BUG_ON(ret);
+       }
 out:
        btrfs_free_path(path);
        return 0;
index 5440bab..b330e27 100644 (file)
@@ -3796,6 +3796,12 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
 
        if (location.type == BTRFS_INODE_ITEM_KEY) {
                inode = btrfs_iget(dir->i_sb, &location, root);
+               if (unlikely(root->clean_orphans) &&
+                   !(inode->i_sb->s_flags & MS_RDONLY)) {
+                       down_read(&root->fs_info->cleanup_work_sem);
+                       btrfs_orphan_cleanup(root);
+                       up_read(&root->fs_info->cleanup_work_sem);
+               }
                return inode;
        }
 
@@ -3995,7 +4001,11 @@ skip:
 
        /* Reached end of directory/root. Bump pos past the last item. */
        if (key_type == BTRFS_DIR_INDEX_KEY)
-               filp->f_pos = INT_LIMIT(off_t);
+               /*
+                * 32-bit glibc will use getdents64, but then strtol -
+                * so the last number we can serve is this.
+                */
+               filp->f_pos = 0x7fffffff;
        else
                filp->f_pos++;
 nopos:
index b10a49d..5c2a9e7 100644 (file)
@@ -626,6 +626,8 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
 
        if (ordered)
                offset = entry_end(ordered);
+       else
+               offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize);
 
        mutex_lock(&tree->mutex);
        disk_i_size = BTRFS_I(inode)->disk_i_size;
index a972868..ed3e4a2 100644 (file)
@@ -3281,8 +3281,10 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
                return -ENOMEM;
 
        path = btrfs_alloc_path();
-       if (!path)
+       if (!path) {
+               kfree(cluster);
                return -ENOMEM;
+       }
 
        rc->extents_found = 0;
        rc->extents_skipped = 0;
index 198cff2..220dad5 100644 (file)
@@ -2649,8 +2649,10 @@ again:
        em = lookup_extent_mapping(em_tree, logical, *length);
        read_unlock(&em_tree->lock);
 
-       if (!em && unplug_page)
+       if (!em && unplug_page) {
+               kfree(multi);
                return 0;
+       }
 
        if (!em) {
                printk(KERN_CRIT "unable to find logical %llu len %llu\n",
index fbb6e5e..7cb0a59 100644 (file)
@@ -1748,7 +1748,7 @@ ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm,
                            char *cipher_name, size_t *key_size)
 {
        char dummy_key[ECRYPTFS_MAX_KEY_BYTES];
-       char *full_alg_name;
+       char *full_alg_name = NULL;
        int rc;
 
        *key_tfm = NULL;
@@ -1763,7 +1763,6 @@ ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm,
        if (rc)
                goto out;
        *key_tfm = crypto_alloc_blkcipher(full_alg_name, 0, CRYPTO_ALG_ASYNC);
-       kfree(full_alg_name);
        if (IS_ERR(*key_tfm)) {
                rc = PTR_ERR(*key_tfm);
                printk(KERN_ERR "Unable to allocate crypto cipher with name "
@@ -1786,6 +1785,7 @@ ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm,
                goto out;
        }
 out:
+       kfree(full_alg_name);
        return rc;
 }
 
index 9e94405..678172b 100644 (file)
@@ -158,7 +158,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
        struct dentry *ecryptfs_dentry = file->f_path.dentry;
        /* Private value of ecryptfs_dentry allocated in
         * ecryptfs_lookup() */
-       struct dentry *lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
+       struct dentry *lower_dentry;
        struct ecryptfs_file_info *file_info;
 
        mount_crypt_stat = &ecryptfs_superblock_to_private(
@@ -191,13 +191,6 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
                                      | ECRYPTFS_ENCRYPTED);
        }
        mutex_unlock(&crypt_stat->cs_mutex);
-       if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_RDONLY)
-           && !(file->f_flags & O_RDONLY)) {
-               rc = -EPERM;
-               printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs "
-                      "file must hence be opened RO\n", __func__);
-               goto out;
-       }
        if (!ecryptfs_inode_to_private(inode)->lower_file) {
                rc = ecryptfs_init_persistent_file(ecryptfs_dentry);
                if (rc) {
@@ -208,6 +201,13 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
                        goto out;
                }
        }
+       if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_RDONLY)
+           && !(file->f_flags & O_RDONLY)) {
+               rc = -EPERM;
+               printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs "
+                      "file must hence be opened RO\n", __func__);
+               goto out;
+       }
        ecryptfs_set_file_lower(
                file, ecryptfs_inode_to_private(inode)->lower_file);
        if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
@@ -299,7 +299,6 @@ static int ecryptfs_ioctl(struct inode *inode, struct file *file,
 const struct file_operations ecryptfs_dir_fops = {
        .readdir = ecryptfs_readdir,
        .ioctl = ecryptfs_ioctl,
-       .mmap = generic_file_mmap,
        .open = ecryptfs_open,
        .flush = ecryptfs_flush,
        .release = ecryptfs_release,
index 7f85450..4a430ab 100644 (file)
@@ -282,7 +282,8 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
                goto out;
        }
        rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry,
-                               ecryptfs_dir_inode->i_sb, 1);
+                               ecryptfs_dir_inode->i_sb,
+                               ECRYPTFS_INTERPOSE_FLAG_D_ADD);
        if (rc) {
                printk(KERN_ERR "%s: Error interposing; rc = [%d]\n",
                       __func__, rc);
@@ -463,9 +464,6 @@ out_lock:
        unlock_dir(lower_dir_dentry);
        dput(lower_new_dentry);
        dput(lower_old_dentry);
-       d_drop(lower_old_dentry);
-       d_drop(new_dentry);
-       d_drop(old_dentry);
        return rc;
 }
 
@@ -614,6 +612,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        struct dentry *lower_new_dentry;
        struct dentry *lower_old_dir_dentry;
        struct dentry *lower_new_dir_dentry;
+       struct dentry *trap = NULL;
 
        lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
        lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
@@ -621,7 +620,17 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        dget(lower_new_dentry);
        lower_old_dir_dentry = dget_parent(lower_old_dentry);
        lower_new_dir_dentry = dget_parent(lower_new_dentry);
-       lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
+       trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
+       /* source should not be ancestor of target */
+       if (trap == lower_old_dentry) {
+               rc = -EINVAL;
+               goto out_lock;
+       }
+       /* target should not be ancestor of source */
+       if (trap == lower_new_dentry) {
+               rc = -ENOTEMPTY;
+               goto out_lock;
+       }
        rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
                        lower_new_dir_dentry->d_inode, lower_new_dentry);
        if (rc)
@@ -772,18 +781,23 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat,
 }
 
 /**
- * ecryptfs_truncate
+ * truncate_upper
  * @dentry: The ecryptfs layer dentry
- * @new_length: The length to expand the file to
+ * @ia: Address of the ecryptfs inode's attributes
+ * @lower_ia: Address of the lower inode's attributes
  *
  * Function to handle truncations modifying the size of the file. Note
  * that the file sizes are interpolated. When expanding, we are simply
- * writing strings of 0's out. When truncating, we need to modify the
- * underlying file size according to the page index interpolations.
+ * writing strings of 0's out. When truncating, we truncate the upper
+ * inode and update the lower_ia according to the page index
+ * interpolations. If ATTR_SIZE is set in lower_ia->ia_valid upon return,
+ * the caller must use lower_ia in a call to notify_change() to perform
+ * the truncation of the lower inode.
  *
  * Returns zero on success; non-zero otherwise
  */
-int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
+static int truncate_upper(struct dentry *dentry, struct iattr *ia,
+                         struct iattr *lower_ia)
 {
        int rc = 0;
        struct inode *inode = dentry->d_inode;
@@ -794,8 +808,10 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
        loff_t lower_size_before_truncate;
        loff_t lower_size_after_truncate;
 
-       if (unlikely((new_length == i_size)))
+       if (unlikely((ia->ia_size == i_size))) {
+               lower_ia->ia_valid &= ~ATTR_SIZE;
                goto out;
+       }
        crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
        /* Set up a fake ecryptfs file, this is used to interface with
         * the file in the underlying filesystem so that the
@@ -815,28 +831,30 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
                &fake_ecryptfs_file,
                ecryptfs_inode_to_private(dentry->d_inode)->lower_file);
        /* Switch on growing or shrinking file */
-       if (new_length > i_size) {
+       if (ia->ia_size > i_size) {
                char zero[] = { 0x00 };
 
+               lower_ia->ia_valid &= ~ATTR_SIZE;
                /* Write a single 0 at the last position of the file;
                 * this triggers code that will fill in 0's throughout
                 * the intermediate portion of the previous end of the
                 * file and the new and of the file */
                rc = ecryptfs_write(&fake_ecryptfs_file, zero,
-                                   (new_length - 1), 1);
-       } else { /* new_length < i_size_read(inode) */
-               /* We're chopping off all the pages down do the page
-                * in which new_length is located. Fill in the end of
-                * that page from (new_length & ~PAGE_CACHE_MASK) to
+                                   (ia->ia_size - 1), 1);
+       } else { /* ia->ia_size < i_size_read(inode) */
+               /* We're chopping off all the pages down to the page
+                * in which ia->ia_size is located. Fill in the end of
+                * that page from (ia->ia_size & ~PAGE_CACHE_MASK) to
                 * PAGE_CACHE_SIZE with zeros. */
                size_t num_zeros = (PAGE_CACHE_SIZE
-                                   - (new_length & ~PAGE_CACHE_MASK));
+                                   - (ia->ia_size & ~PAGE_CACHE_MASK));
 
                if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
-                       rc = vmtruncate(inode, new_length);
+                       rc = vmtruncate(inode, ia->ia_size);
                        if (rc)
                                goto out_free;
-                       rc = vmtruncate(lower_dentry->d_inode, new_length);
+                       lower_ia->ia_size = ia->ia_size;
+                       lower_ia->ia_valid |= ATTR_SIZE;
                        goto out_free;
                }
                if (num_zeros) {
@@ -848,7 +866,7 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
                                goto out_free;
                        }
                        rc = ecryptfs_write(&fake_ecryptfs_file, zeros_virt,
-                                           new_length, num_zeros);
+                                           ia->ia_size, num_zeros);
                        kfree(zeros_virt);
                        if (rc) {
                                printk(KERN_ERR "Error attempting to zero out "
@@ -857,7 +875,7 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
                                goto out_free;
                        }
                }
-               vmtruncate(inode, new_length);
+               vmtruncate(inode, ia->ia_size);
                rc = ecryptfs_write_inode_size_to_metadata(inode);
                if (rc) {
                        printk(KERN_ERR "Problem with "
@@ -870,10 +888,12 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
                lower_size_before_truncate =
                    upper_size_to_lower_size(crypt_stat, i_size);
                lower_size_after_truncate =
-                   upper_size_to_lower_size(crypt_stat, new_length);
-               if (lower_size_after_truncate < lower_size_before_truncate)
-                       vmtruncate(lower_dentry->d_inode,
-                                  lower_size_after_truncate);
+                   upper_size_to_lower_size(crypt_stat, ia->ia_size);
+               if (lower_size_after_truncate < lower_size_before_truncate) {
+                       lower_ia->ia_size = lower_size_after_truncate;
+                       lower_ia->ia_valid |= ATTR_SIZE;
+               } else
+                       lower_ia->ia_valid &= ~ATTR_SIZE;
        }
 out_free:
        if (ecryptfs_file_to_private(&fake_ecryptfs_file))
@@ -883,6 +903,33 @@ out:
        return rc;
 }
 
+/**
+ * ecryptfs_truncate
+ * @dentry: The ecryptfs layer dentry
+ * @new_length: The length to expand the file to
+ *
+ * Simple function that handles the truncation of an eCryptfs inode and
+ * its corresponding lower inode.
+ *
+ * Returns zero on success; non-zero otherwise
+ */
+int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
+{
+       struct iattr ia = { .ia_valid = ATTR_SIZE, .ia_size = new_length };
+       struct iattr lower_ia = { .ia_valid = 0 };
+       int rc;
+
+       rc = truncate_upper(dentry, &ia, &lower_ia);
+       if (!rc && lower_ia.ia_valid & ATTR_SIZE) {
+               struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
+
+               mutex_lock(&lower_dentry->d_inode->i_mutex);
+               rc = notify_change(lower_dentry, &lower_ia);
+               mutex_unlock(&lower_dentry->d_inode->i_mutex);
+       }
+       return rc;
+}
+
 static int
 ecryptfs_permission(struct inode *inode, int mask)
 {
@@ -905,6 +952,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
 {
        int rc = 0;
        struct dentry *lower_dentry;
+       struct iattr lower_ia;
        struct inode *inode;
        struct inode *lower_inode;
        struct ecryptfs_crypt_stat *crypt_stat;
@@ -943,15 +991,11 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
                }
        }
        mutex_unlock(&crypt_stat->cs_mutex);
+       memcpy(&lower_ia, ia, sizeof(lower_ia));
+       if (ia->ia_valid & ATTR_FILE)
+               lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file);
        if (ia->ia_valid & ATTR_SIZE) {
-               ecryptfs_printk(KERN_DEBUG,
-                               "ia->ia_valid = [0x%x] ATTR_SIZE" " = [0x%x]\n",
-                               ia->ia_valid, ATTR_SIZE);
-               rc = ecryptfs_truncate(dentry, ia->ia_size);
-               /* ecryptfs_truncate handles resizing of the lower file */
-               ia->ia_valid &= ~ATTR_SIZE;
-               ecryptfs_printk(KERN_DEBUG, "ia->ia_valid = [%x]\n",
-                               ia->ia_valid);
+               rc = truncate_upper(dentry, ia, &lower_ia);
                if (rc < 0)
                        goto out;
        }
@@ -960,17 +1004,32 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
         * mode change is for clearing setuid/setgid bits. Allow lower fs
         * to interpret this in its own way.
         */
-       if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
-               ia->ia_valid &= ~ATTR_MODE;
+       if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
+               lower_ia.ia_valid &= ~ATTR_MODE;
 
        mutex_lock(&lower_dentry->d_inode->i_mutex);
-       rc = notify_change(lower_dentry, ia);
+       rc = notify_change(lower_dentry, &lower_ia);
        mutex_unlock(&lower_dentry->d_inode->i_mutex);
 out:
        fsstack_copy_attr_all(inode, lower_inode);
        return rc;
 }
 
+int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
+                    struct kstat *stat)
+{
+       struct kstat lower_stat;
+       int rc;
+
+       rc = vfs_getattr(ecryptfs_dentry_to_lower_mnt(dentry),
+                        ecryptfs_dentry_to_lower(dentry), &lower_stat);
+       if (!rc) {
+               generic_fillattr(dentry->d_inode, stat);
+               stat->blocks = lower_stat.blocks;
+       }
+       return rc;
+}
+
 int
 ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
                  size_t size, int flags)
@@ -1100,6 +1159,7 @@ const struct inode_operations ecryptfs_dir_iops = {
 const struct inode_operations ecryptfs_main_iops = {
        .permission = ecryptfs_permission,
        .setattr = ecryptfs_setattr,
+       .getattr = ecryptfs_getattr,
        .setxattr = ecryptfs_setxattr,
        .getxattr = ecryptfs_getxattr,
        .listxattr = ecryptfs_listxattr,
index 567bc4b..ea2f921 100644 (file)
@@ -585,8 +585,8 @@ out:
  *                        with as much information as it can before needing
  *                        the lower filesystem.
  * ecryptfs_read_super(): this accesses the lower filesystem and uses
- *                        ecryptfs_interpolate to perform most of the linking
- * ecryptfs_interpolate(): links the lower filesystem into ecryptfs
+ *                        ecryptfs_interpose to perform most of the linking
+ * ecryptfs_interpose(): links the lower filesystem into ecryptfs (inode.c)
  */
 static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags,
                        const char *dev_name, void *raw_data,
index 9d7febd..0946997 100644 (file)
@@ -152,7 +152,7 @@ static inline void *acpi_os_acquire_object(acpi_cache_t * cache)
 #include <linux/hardirq.h>
 #define ACPI_PREEMPTION_POINT() \
        do { \
-               if (!in_atomic_preempt_off()) \
+               if (!in_atomic_preempt_off() && !irqs_disabled()) \
                        cond_resched(); \
        } while (0)
 
index 3692425..b926afe 100644 (file)
@@ -80,7 +80,7 @@ char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
 void __acpi_unmap_table(char *map, unsigned long size);
 int early_acpi_boot_init(void);
 int acpi_boot_init (void);
-int acpi_boot_table_init (void);
+void acpi_boot_table_init (void);
 int acpi_mps_check (void);
 int acpi_numa_init (void);
 
@@ -321,9 +321,9 @@ static inline int acpi_boot_init(void)
        return 0;
 }
 
-static inline int acpi_boot_table_init(void)
+static inline void acpi_boot_table_init(void)
 {
-       return 0;
+       return;
 }
 
 static inline int acpi_mps_check(void)
index 9b98173..5c80189 100644 (file)
@@ -938,6 +938,8 @@ extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt);
 extern void blk_set_default_limits(struct queue_limits *lim);
 extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
                            sector_t offset);
+extern int bdev_stack_limits(struct queue_limits *t, struct block_device *bdev,
+                           sector_t offset);
 extern void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
                              sector_t offset);
 extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b);
@@ -1148,8 +1150,11 @@ static inline int queue_discard_alignment(struct request_queue *q)
 static inline int queue_sector_discard_alignment(struct request_queue *q,
                                                 sector_t sector)
 {
-       return ((sector << 9) - q->limits.discard_alignment)
-               & (q->limits.discard_granularity - 1);
+       struct queue_limits *lim = &q->limits;
+       unsigned int alignment = (sector << 9) & (lim->discard_granularity - 1);
+
+       return (lim->discard_granularity + lim->discard_alignment - alignment)
+               & (lim->discard_granularity - 1);
 }
 
 static inline unsigned int queue_discard_zeroes_data(struct request_queue *q)
index e84f473..7896227 100644 (file)
@@ -53,7 +53,7 @@
 
 
 extern const char *drbd_buildtag(void);
-#define REL_VERSION "8.3.6"
+#define REL_VERSION "8.3.7"
 #define API_VERSION 88
 #define PRO_VERSION_MIN 86
 #define PRO_VERSION_MAX 91
index db5721a..a4d82f8 100644 (file)
@@ -69,6 +69,7 @@ NL_PACKET(disconnect, 6, )
 
 NL_PACKET(resize, 7,
        NL_INT64(               29,     T_MAY_IGNORE,   resize_size)
+       NL_BIT(                 68,     T_MAY_IGNORE,   resize_force)
 )
 
 NL_PACKET(syncer_conf, 8,
index c6c0c41..9717081 100644 (file)
@@ -256,9 +256,9 @@ extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk,
 #define part_stat_read(part, field)                                    \
 ({                                                                     \
        typeof((part)->dkstats->field) res = 0;                         \
-       int i;                                                          \
-       for_each_possible_cpu(i)                                        \
-               res += per_cpu_ptr((part)->dkstats, i)->field;          \
+       unsigned int _cpu;                                              \
+       for_each_possible_cpu(_cpu)                                     \
+               res += per_cpu_ptr((part)->dkstats, _cpu)->field;       \
        res;                                                            \
 })
 
index a632359..78ef023 100644 (file)
@@ -4,32 +4,6 @@
 #include <linux/radix-tree.h>
 #include <linux/rcupdate.h>
 
-/*
- * This is the per-process anticipatory I/O scheduler state.
- */
-struct as_io_context {
-       spinlock_t lock;
-
-       void (*dtor)(struct as_io_context *aic); /* destructor */
-       void (*exit)(struct as_io_context *aic); /* called on task exit */
-
-       unsigned long state;
-       atomic_t nr_queued; /* queued reads & sync writes */
-       atomic_t nr_dispatched; /* number of requests gone to the drivers */
-
-       /* IO History tracking */
-       /* Thinktime */
-       unsigned long last_end_request;
-       unsigned long ttime_total;
-       unsigned long ttime_samples;
-       unsigned long ttime_mean;
-       /* Layout pattern */
-       unsigned int seek_samples;
-       sector_t last_request_pos;
-       u64 seek_total;
-       sector_t seek_mean;
-};
-
 struct cfq_queue;
 struct cfq_io_context {
        void *key;
@@ -78,7 +52,6 @@ struct io_context {
        unsigned long last_waited; /* Time last woken after wait for request */
        int nr_batch_requests;     /* Number of requests left in the batch */
 
-       struct as_io_context *aic;
        struct radix_tree_root radix_root;
        struct hlist_head cic_list;
        void *ioc_data;
index e101a2d..d7ace1b 100644 (file)
@@ -192,6 +192,7 @@ struct usb_interface {
        unsigned needs_altsetting0:1;   /* switch to altsetting 0 is pending */
        unsigned needs_binding:1;       /* needs delayed unbind/rebind */
        unsigned reset_running:1;
+       unsigned resetting_device:1;    /* true: bandwidth alloc after reset */
 
        struct device dev;              /* interface specific device info */
        struct device *usb_dev;
index 37e6929..d55d905 100644 (file)
@@ -555,10 +555,8 @@ static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end,
        }
        rcu_read_unlock();
 
-       if (nr) {
-               BUG_ON(nr > atomic_read(&vmap_lazy_nr));
+       if (nr)
                atomic_sub(nr, &vmap_lazy_nr);
-       }
 
        if (nr || force_flush)
                flush_tlb_kernel_range(*start, *end);