Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 22 Dec 2009 22:18:13 +0000 (14:18 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 22 Dec 2009 22:18:13 +0000 (14:18 -0800)
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (36 commits)
  powerpc/gc/wii: Remove get_irq_desc()
  powerpc/gc/wii: hlwd-pic: convert irq_desc.lock to raw_spinlock
  powerpc/gamecube/wii: Fix off-by-one error in ugecon/usbgecko_udbg
  powerpc/mpic: Fix problem that affinity is not updated
  powerpc/mm: Fix stupid bug in subpge protection handling
  powerpc/iseries: use DECLARE_COMPLETION_ONSTACK for non-constant completion
  powerpc: Fix MSI support on U4 bridge PCIe slot
  powerpc: Handle VSX alignment faults correctly in little-endian mode
  powerpc/mm: Fix typo of cpumask_clear_cpu()
  powerpc/mm: Fix hash_utils_64.c compile errors with DEBUG enabled.
  powerpc: Convert BUG() to use unreachable()
  powerpc/pseries: Make declarations of cpu_hotplug_driver_lock() ANSI compatible.
  powerpc/pseries: Don't panic when H_PROD fails during cpu-online.
  powerpc/mm: Fix a WARN_ON() with CONFIG_DEBUG_PAGEALLOC and CONFIG_DEBUG_VM
  powerpc/defconfigs: Set HZ=100 on pseries and ppc64 defconfigs
  powerpc/defconfigs: Disable token ring in powerpc defconfigs
  powerpc/defconfigs: Reduce 64bit vmlinux by making acenic and cramfs modules
  powerpc/pseries: Select XICS and PCI_MSI PSERIES
  powerpc/85xx: Wrong variable returned on error
  powerpc/iseries: Convert to proc_fops
  ...

171 files changed:
Documentation/trace/events-kmem.txt
Makefile
arch/Kconfig
arch/alpha/Kconfig
arch/alpha/include/asm/bug.h
arch/alpha/include/asm/perf_event.h [new file with mode: 0644]
arch/alpha/include/asm/unistd.h
arch/alpha/kernel/systbls.S
arch/s390/crypto/aes_s390.c
arch/s390/hypfs/hypfs_diag.c
arch/s390/hypfs/hypfs_vm.c
arch/s390/include/asm/unistd.h
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/ipl.c
arch/s390/kernel/ptrace.c
arch/s390/kernel/syscalls.S
arch/s390/kernel/traps.c
arch/x86/Kconfig
arch/x86/include/asm/cpufeature.h
arch/x86/include/asm/hw_irq.h
arch/x86/include/asm/msr-index.h
arch/x86/include/asm/msr.h
arch/x86/include/asm/processor.h
arch/x86/include/asm/stacktrace.h
arch/x86/kernel/apic/apic_flat_64.c
arch/x86/kernel/apic/bigsmp_32.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/apic/x2apic_cluster.c
arch/x86/kernel/apic/x2apic_phys.c
arch/x86/kernel/apic/x2apic_uv_x.c
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/cpuid.c
arch/x86/kernel/dumpstack.c
arch/x86/kernel/dumpstack.h
arch/x86/kernel/dumpstack_32.c
arch/x86/kernel/dumpstack_64.c
arch/x86/kernel/e820.c
arch/x86/kernel/msr.c
arch/x86/kernel/stacktrace.c
arch/x86/kernel/tsc.c
arch/x86/kernel/uv_irq.c
arch/x86/lib/Makefile
arch/x86/lib/msr-smp.c [new file with mode: 0644]
arch/x86/lib/msr.c
arch/x86/mm/srat_32.c
arch/x86/mm/srat_64.c
arch/x86/oprofile/backtrace.c
arch/x86/tools/chkobjdump.awk
arch/x86/tools/gen-insn-attr-x86.awk
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/pata_cmd64x.c
drivers/ata/pata_hpt3x2n.c
drivers/ata/pata_octeon_cf.c
drivers/ata/sata_mv.c
drivers/bluetooth/btusb.c
drivers/char/nozomi.c
drivers/char/sonypi.c
drivers/infiniband/hw/cxgb3/cxio_hal.h
drivers/infiniband/hw/cxgb3/cxio_resource.c
drivers/isdn/mISDN/l1oip_core.c
drivers/media/video/cx23885/cx23888-ir.c
drivers/media/video/meye.c
drivers/media/video/meye.h
drivers/net/bnx2.c
drivers/net/can/at91_can.c
drivers/net/davinci_emac.c
drivers/net/e100.c
drivers/net/e1000e/82571.c
drivers/net/gianfar.c
drivers/net/gianfar.h
drivers/net/netxen/netxen_nic_main.c
drivers/net/phy/broadcom.c
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/main.c
drivers/platform/x86/fujitsu-laptop.c
drivers/platform/x86/sony-laptop.c
drivers/s390/block/dasd_alias.c
drivers/s390/block/dasd_diag.c
drivers/s390/char/fs3270.c
drivers/s390/char/tape_34xx.c
drivers/s390/char/tape_3590.c
drivers/s390/char/tape_block.c
drivers/s390/char/tape_char.c
drivers/s390/char/tape_class.c
drivers/s390/char/tape_core.c
drivers/s390/char/tape_proc.c
drivers/s390/char/tape_std.c
drivers/s390/cio/ccwreq.c
drivers/s390/cio/device.c
drivers/s390/cio/device_pgid.c
drivers/s390/cio/fcx.c
drivers/s390/cio/io_sch.h
drivers/s390/cio/qdio_main.c
drivers/s390/cio/qdio_perf.c
drivers/s390/cio/qdio_perf.h
drivers/s390/cio/qdio_setup.c
drivers/scsi/libiscsi.c
drivers/scsi/libiscsi_tcp.c
drivers/scsi/libsrp.c
drivers/usb/host/fhci-sched.c
drivers/usb/host/fhci-tds.c
drivers/usb/host/fhci.h
drivers/usb/serial/generic.c
drivers/usb/serial/usb-serial.c
drivers/watchdog/Kconfig
drivers/watchdog/geodewdt.c
fs/nfsd/nfsfh.c
fs/proc/array.c
include/linux/decompress/mm.h
include/linux/elf.h
include/linux/kfifo.h
include/linux/mm.h
include/linux/perf_counter.h [deleted file]
include/linux/rcutiny.h
include/linux/rcutree.h
include/linux/sched.h
include/scsi/libiscsi.h
include/scsi/libiscsi_tcp.h
include/scsi/libsrp.h
init/initramfs.c
init/main.c
kernel/audit_tree.c
kernel/cpu.c
kernel/kfifo.c
kernel/kthread.c
kernel/perf_event.c
kernel/resource.c
kernel/sched.c
kernel/sched_clock.c
kernel/sched_fair.c
kernel/sched_rt.c
kernel/signal.c
kernel/sys.c
kernel/time.c
kernel/time/clockevents.c
kernel/time/timekeeping.c
kernel/timer.c
kernel/trace/trace_kprobe.c
kernel/trace/trace_sysprof.c
lib/decompress_bunzip2.c
lib/string.c
mm/page_alloc.c
net/bluetooth/hidp/core.c
net/bluetooth/l2cap.c
net/dccp/probe.c
net/ipv6/reassembly.c
net/ipv6/route.c
sound/arm/aaci.c
sound/arm/aaci.h
sound/core/pcm_lib.c
sound/isa/msnd/msnd_midi.c
sound/isa/sb/emu8000.c
sound/mips/sgio2audio.c
sound/oss/pss.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
sound/soc/codecs/ak4642.c
sound/soc/codecs/stac9766.c
sound/soc/codecs/wm8974.c
sound/usb/usbaudio.c
tools/perf/Makefile
tools/perf/builtin-probe.c
tools/perf/builtin-report.c
tools/perf/util/event.h
tools/perf/util/probe-event.c
tools/perf/util/probe-finder.h

index 6ef2a86..aa82ee4 100644 (file)
@@ -1,7 +1,7 @@
                        Subsystem Trace Points: kmem
 
-The tracing system kmem captures events related to object and page allocation
-within the kernel. Broadly speaking there are four major subheadings.
+The kmem tracing system captures events related to object and page allocation
+within the kernel. Broadly speaking there are five major subheadings.
 
   o Slab allocation of small objects of unknown type (kmalloc)
   o Slab allocation of small objects of known type
@@ -9,7 +9,7 @@ within the kernel. Broadly speaking there are four major subheadings.
   o Per-CPU Allocator Activity
   o External Fragmentation
 
-This document will describe what each of the tracepoints are and why they
+This document describes what each of the tracepoints is and why they
 might be useful.
 
 1. Slab allocation of small objects of unknown type
@@ -34,7 +34,7 @@ kmem_cache_free               call_site=%lx ptr=%p
 These events are similar in usage to the kmalloc-related events except that
 it is likely easier to pin the event down to a specific cache. At the time
 of writing, no information is available on what slab is being allocated from,
-but the call_site can usually be used to extrapolate that information
+but the call_site can usually be used to extrapolate that information.
 
 3. Page allocation
 ==================
@@ -80,9 +80,9 @@ event indicating whether it is for a percpu_refill or not.
 When the per-CPU list is too full, a number of pages are freed, each one
 which triggers a mm_page_pcpu_drain event.
 
-The individual nature of the events are so that pages can be tracked
+The individual nature of the events is so that pages can be tracked
 between allocation and freeing. A number of drain or refill pages that occur
-consecutively imply the zone->lock being taken once. Large amounts of PCP
+consecutively imply the zone->lock being taken once. Large amounts of per-CPU
 refills and drains could imply an imbalance between CPUs where too much work
 is being concentrated in one place. It could also indicate that the per-CPU
 lists should be a larger size. Finally, large amounts of refills on one CPU
@@ -102,6 +102,6 @@ is important.
 
 Large numbers of this event implies that memory is fragmenting and
 high-order allocations will start failing at some time in the future. One
-means of reducing the occurange of this event is to increase the size of
+means of reducing the occurrence of this event is to increase the size of
 min_free_kbytes in increments of 3*pageblock_size*nr_online_nodes where
 pageblock_size is usually the size of the default hugepage size.
index 0ac5812..e6b06cb 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,6 +16,13 @@ NAME = Man-Eating Seals of Antiquity
 # o  print "Entering directory ...";
 MAKEFLAGS += -rR --no-print-directory
 
+# Avoid funny character set dependencies
+unexport LC_ALL
+LC_CTYPE=C
+LC_COLLATE=C
+LC_NUMERIC=C
+export LC_CTYPE LC_COLLATE LC_NUMERIC
+
 # We are using a recursive build, so we need to do a little thinking
 # to get the ordering right.
 #
index d828758..9d055b4 100644 (file)
@@ -135,9 +135,7 @@ config HAVE_DEFAULT_NO_SPIN_MUTEXES
 
 config HAVE_HW_BREAKPOINT
        bool
-       depends on HAVE_PERF_EVENTS
-       select ANON_INODES
-       select PERF_EVENTS
+       depends on PERF_EVENTS
 
 config HAVE_USER_RETURN_NOTIFIER
        bool
index 4434481..bd7261e 100644 (file)
@@ -9,6 +9,7 @@ config ALPHA
        select HAVE_IDE
        select HAVE_OPROFILE
        select HAVE_SYSCALL_WRAPPERS
+       select HAVE_PERF_EVENTS
        help
          The Alpha is a 64-bit general-purpose processor designed and
          marketed by the Digital Equipment Corporation of blessed memory,
index 1720c8a..f091682 100644 (file)
@@ -13,7 +13,8 @@
                "call_pal %0  # bugchk\n\t"                             \
                ".long %1\n\t.8byte %2"                                 \
                : : "i"(PAL_bugchk), "i"(__LINE__), "i"(__FILE__));     \
-       for ( ; ; ); } while (0)
+       unreachable();                                                  \
+  } while (0)
 
 #define HAVE_ARCH_BUG
 #endif
diff --git a/arch/alpha/include/asm/perf_event.h b/arch/alpha/include/asm/perf_event.h
new file mode 100644 (file)
index 0000000..3bef852
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __ASM_ALPHA_PERF_EVENT_H
+#define __ASM_ALPHA_PERF_EVENT_H
+
+/* Alpha only supports software events through this interface. */
+static inline void set_perf_event_pending(void) { }
+
+#define PERF_EVENT_INDEX_OFFSET 0
+
+#endif /* __ASM_ALPHA_PERF_EVENT_H */
index 7f23665..804e531 100644 (file)
 #define __IGNORE_pause
 #define __IGNORE_time
 #define __IGNORE_utime
+#define __IGNORE_umount2
 
 /*
  * Linux-specific system calls begin at 300
 #define __NR_timerfd                   477
 #define __NR_eventfd                   478
 #define __NR_recvmmsg                  479
+#define __NR_fallocate                 480
+#define __NR_timerfd_create            481
+#define __NR_timerfd_settime           482
+#define __NR_timerfd_gettime           483
+#define __NR_signalfd4                 484
+#define __NR_eventfd2                  485
+#define __NR_epoll_create1             486
+#define __NR_dup3                      487
+#define __NR_pipe2                     488
+#define __NR_inotify_init1             489
+#define __NR_preadv                    490
+#define __NR_pwritev                   491
+#define __NR_rt_tgsigqueueinfo         492
+#define __NR_perf_event_open           493
 
 #ifdef __KERNEL__
 
-#define NR_SYSCALLS                    480
+#define NR_SYSCALLS                    494
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
index cda6b8b..09acb78 100644 (file)
@@ -495,9 +495,23 @@ sys_call_table:
        .quad sys_epoll_pwait
        .quad sys_utimensat                     /* 475 */
        .quad sys_signalfd
-       .quad sys_ni_syscall
+       .quad sys_ni_syscall                    /* sys_timerfd */
        .quad sys_eventfd
        .quad sys_recvmmsg
+       .quad sys_fallocate                             /* 480 */
+       .quad sys_timerfd_create
+       .quad sys_timerfd_settime
+       .quad sys_timerfd_gettime
+       .quad sys_signalfd4
+       .quad sys_eventfd2                              /* 485 */
+       .quad sys_epoll_create1
+       .quad sys_dup3
+       .quad sys_pipe2
+       .quad sys_inotify_init1
+       .quad sys_preadv                                /* 490 */
+       .quad sys_pwritev
+       .quad sys_rt_tgsigqueueinfo
+       .quad sys_perf_event_open
 
        .size sys_call_table, . - sys_call_table
        .type sys_call_table, @object
index 6118890..6be4503 100644 (file)
@@ -174,7 +174,7 @@ static int fallback_init_cip(struct crypto_tfm *tfm)
        if (IS_ERR(sctx->fallback.cip)) {
                pr_err("Allocating AES fallback algorithm %s failed\n",
                       name);
-               return PTR_ERR(sctx->fallback.blk);
+               return PTR_ERR(sctx->fallback.cip);
        }
 
        return 0;
index 77df726..2b92d50 100644 (file)
@@ -164,7 +164,7 @@ static inline void part_hdr__part_name(enum diag204_format type, void *hdr,
                       LPAR_NAME_LEN);
        EBCASC(name, LPAR_NAME_LEN);
        name[LPAR_NAME_LEN] = 0;
-       strstrip(name);
+       strim(name);
 }
 
 struct cpu_info {
@@ -523,7 +523,7 @@ static int diag224_idx2name(int index, char *name)
        memcpy(name, diag224_cpu_names + ((index + 1) * CPU_NAME_LEN),
                CPU_NAME_LEN);
        name[CPU_NAME_LEN] = 0;
-       strstrip(name);
+       strim(name);
        return 0;
 }
 
index d01fc8f..f0b0d31 100644 (file)
@@ -124,7 +124,7 @@ static int hpyfs_vm_create_guest(struct super_block *sb,
        /* guest dir */
        memcpy(guest_name, data->guest_name, NAME_LEN);
        EBCASC(guest_name, NAME_LEN);
-       strstrip(guest_name);
+       strim(guest_name);
        guest_dir = hypfs_mkdir(sb, systems_dir, guest_name);
        if (IS_ERR(guest_dir))
                return PTR_ERR(guest_dir);
index cb5232d..192a720 100644 (file)
 #define        __NR_pwritev            329
 #define __NR_rt_tgsigqueueinfo 330
 #define __NR_perf_event_open   331
-#define NR_syscalls 332
+#define __NR_recvmmsg          332
+#define NR_syscalls 333
 
 /* 
  * There are some system calls that are not present on 64 bit, some
index 30de2d0..faeaccc 100644 (file)
@@ -1853,3 +1853,12 @@ sys32_execve_wrapper:
        llgtr   %r3,%r3                 # compat_uptr_t *
        llgtr   %r4,%r4                 # compat_uptr_t *
        jg      sys32_execve            # branch to system call
+
+       .globl  compat_sys_recvmmsg_wrapper
+compat_sys_recvmmsg_wrapper:
+       lgfr    %r2,%r2                 # int
+       llgtr   %r3,%r3                 # struct compat_mmsghdr *
+       llgfr   %r4,%r4                 # unsigned int
+       llgfr   %r5,%r5                 # unsigned int
+       llgtr   %r6,%r6                 # struct compat_timespec *
+       jg      compat_sys_recvmmsg
index 4890ac6..4d73296 100644 (file)
@@ -221,7 +221,7 @@ static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj,        \
                const char *buf, size_t len)                            \
 {                                                                      \
        strncpy(_value, buf, sizeof(_value) - 1);                       \
-       strstrip(_value);                                               \
+       strim(_value);                                                  \
        return len;                                                     \
 }                                                                      \
 static struct kobj_attribute sys_##_prefix##_##_name##_attr =          \
@@ -472,7 +472,7 @@ static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj,
                return sprintf(page, "#unknown#\n");
        memcpy(loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN);
        EBCASC(loadparm, LOADPARM_LEN);
-       strstrip(loadparm);
+       strim(loadparm);
        return sprintf(page, "%s\n", loadparm);
 }
 
@@ -776,7 +776,7 @@ static void reipl_get_ascii_loadparm(char *loadparm,
        memcpy(loadparm, ibp->ipl_info.ccw.load_parm, LOADPARM_LEN);
        EBCASC(loadparm, LOADPARM_LEN);
        loadparm[LOADPARM_LEN] = 0;
-       strstrip(loadparm);
+       strim(loadparm);
 }
 
 static ssize_t reipl_generic_loadparm_show(struct ipl_parameter_block *ipb,
index 653c6a1..13815d3 100644 (file)
@@ -959,7 +959,7 @@ static const struct user_regset s390_compat_regsets[] = {
                .set = s390_fpregs_set,
        },
        [REGSET_GENERAL_EXTENDED] = {
-               .core_note_type = NT_PRXSTATUS,
+               .core_note_type = NT_S390_HIGH_GPRS,
                .n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t),
                .size = sizeof(compat_long_t),
                .align = sizeof(compat_long_t),
index 30eca07..4f292c9 100644 (file)
@@ -340,3 +340,4 @@ SYSCALL(sys_preadv,sys_preadv,compat_sys_preadv_wrapper)
 SYSCALL(sys_pwritev,sys_pwritev,compat_sys_pwritev_wrapper)
 SYSCALL(sys_rt_tgsigqueueinfo,sys_rt_tgsigqueueinfo,compat_sys_rt_tgsigqueueinfo_wrapper) /* 330 */
 SYSCALL(sys_perf_event_open,sys_perf_event_open,sys_perf_event_open_wrapper)
+SYSCALL(sys_recvmmsg,sys_recvmmsg,compat_sys_recvmmsg_wrapper)
index c2e42cc..6e7ad63 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/errno.h>
-#include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/timer.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
@@ -382,7 +382,7 @@ void __kprobes do_single_step(struct pt_regs *regs)
                                        SIGTRAP) == NOTIFY_STOP){
                return;
        }
-       if ((current->ptrace & PT_PTRACED) != 0)
+       if (tracehook_consider_fatal_signal(current, SIGTRAP))
                force_sig(SIGTRAP, current);
 }
 
@@ -483,7 +483,7 @@ static void illegal_op(struct pt_regs * regs, long interruption_code)
                if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
                        return;
                if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
-                       if (current->ptrace & PT_PTRACED)
+                       if (tracehook_consider_fatal_signal(current, SIGTRAP))
                                force_sig(SIGTRAP, current);
                        else
                                signal = SIGILL;
index 3b2a5ac..55298e8 100644 (file)
@@ -50,6 +50,8 @@ config X86
        select HAVE_KERNEL_BZIP2
        select HAVE_KERNEL_LZMA
        select HAVE_HW_BREAKPOINT
+       select PERF_EVENTS
+       select ANON_INODES
        select HAVE_ARCH_KMEMCHECK
        select HAVE_USER_RETURN_NOTIFIER
 
index 613700f..637e1ec 100644 (file)
 #define X86_FEATURE_SSE5       (6*32+11) /* SSE-5 */
 #define X86_FEATURE_SKINIT     (6*32+12) /* SKINIT/STGI instructions */
 #define X86_FEATURE_WDT                (6*32+13) /* Watchdog timer */
+#define X86_FEATURE_NODEID_MSR (6*32+19) /* NodeId MSR */
 
 /*
  * Auxiliary flags: Linux defined - For features scattered in various
index 08c48a8..eeac829 100644 (file)
@@ -103,7 +103,8 @@ extern int assign_irq_vector(int, struct irq_cfg *, const struct cpumask *);
 extern void send_cleanup_vector(struct irq_cfg *);
 
 struct irq_desc;
-extern unsigned int set_desc_affinity(struct irq_desc *, const struct cpumask *);
+extern unsigned int set_desc_affinity(struct irq_desc *, const struct cpumask *,
+                                     unsigned int *dest_id);
 extern int IO_APIC_get_PCI_irq_vector(int bus, int devfn, int pin, struct io_apic_irq_attr *irq_attr);
 extern void setup_ioapic_dest(void);
 
index 4ffe09b..1cd58cd 100644 (file)
@@ -12,6 +12,7 @@
 #define MSR_FS_BASE            0xc0000100 /* 64bit FS base */
 #define MSR_GS_BASE            0xc0000101 /* 64bit GS base */
 #define MSR_KERNEL_GS_BASE     0xc0000102 /* SwapGS GS shadow */
+#define MSR_TSC_AUX            0xc0000103 /* Auxiliary TSC */
 
 /* EFER bits: */
 #define _EFER_SCE              0  /* SYSCALL/SYSRET */
 #define FAM10H_MMIO_CONF_BUSRANGE_SHIFT 2
 #define FAM10H_MMIO_CONF_BASE_MASK     0xfffffff
 #define FAM10H_MMIO_CONF_BASE_SHIFT    20
+#define MSR_FAM10H_NODE_ID             0xc001100c
 
 /* K8 MSRs */
 #define MSR_K8_TOP_MEM1                        0xc001001a
index 2d228fc..c5bc4c2 100644 (file)
@@ -27,6 +27,18 @@ struct msr {
        };
 };
 
+struct msr_info {
+       u32 msr_no;
+       struct msr reg;
+       struct msr *msrs;
+       int err;
+};
+
+struct msr_regs_info {
+       u32 *regs;
+       int err;
+};
+
 static inline unsigned long long native_read_tscp(unsigned int *aux)
 {
        unsigned long low, high;
@@ -240,9 +252,9 @@ do {                                                            \
 #define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val),                \
                                             (u32)((val) >> 32))
 
-#define write_tsc(val1, val2) wrmsr(0x10, (val1), (val2))
+#define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2))
 
-#define write_rdtscp_aux(val) wrmsr(0xc0000103, (val), 0)
+#define write_rdtscp_aux(val) wrmsr(MSR_TSC_AUX, (val), 0)
 
 struct msr *msrs_alloc(void);
 void msrs_free(struct msr *msrs);
index 6f8ec1c..fc801ba 100644 (file)
@@ -181,7 +181,7 @@ static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
                                unsigned int *ecx, unsigned int *edx)
 {
        /* ecx is often an input as well as an output. */
-       asm("cpuid"
+       asm volatile("cpuid"
            : "=a" (*eax),
              "=b" (*ebx),
              "=c" (*ecx),
index cf86a5e..35e8912 100644 (file)
@@ -5,6 +5,29 @@ extern int kstack_depth_to_print;
 
 int x86_is_stack_id(int id, char *name);
 
+struct thread_info;
+struct stacktrace_ops;
+
+typedef unsigned long (*walk_stack_t)(struct thread_info *tinfo,
+                                     unsigned long *stack,
+                                     unsigned long bp,
+                                     const struct stacktrace_ops *ops,
+                                     void *data,
+                                     unsigned long *end,
+                                     int *graph);
+
+extern unsigned long
+print_context_stack(struct thread_info *tinfo,
+                   unsigned long *stack, unsigned long bp,
+                   const struct stacktrace_ops *ops, void *data,
+                   unsigned long *end, int *graph);
+
+extern unsigned long
+print_context_stack_bp(struct thread_info *tinfo,
+                      unsigned long *stack, unsigned long bp,
+                      const struct stacktrace_ops *ops, void *data,
+                      unsigned long *end, int *graph);
+
 /* Generic stack tracer with callbacks */
 
 struct stacktrace_ops {
@@ -14,6 +37,7 @@ struct stacktrace_ops {
        void (*address)(void *data, unsigned long address, int reliable);
        /* On negative return stop dumping */
        int (*stack)(void *data, char *name);
+       walk_stack_t    walk_stack;
 };
 
 void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
index d0c99ab..eacbd2b 100644 (file)
@@ -306,10 +306,7 @@ physflat_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
                if (cpumask_test_cpu(cpu, cpu_online_mask))
                        break;
        }
-       if (cpu < nr_cpu_ids)
-               return per_cpu(x86_cpu_to_apicid, cpu);
-
-       return BAD_APICID;
+       return per_cpu(x86_cpu_to_apicid, cpu);
 }
 
 struct apic apic_physflat =  {
index 38dcecf..cb804c5 100644 (file)
@@ -131,10 +131,7 @@ static unsigned int bigsmp_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
                if (cpumask_test_cpu(cpu, cpu_online_mask))
                        break;
        }
-       if (cpu < nr_cpu_ids)
-               return bigsmp_cpu_to_logical_apicid(cpu);
-
-       return BAD_APICID;
+       return bigsmp_cpu_to_logical_apicid(cpu);
 }
 
 static int bigsmp_phys_pkg_id(int cpuid_apic, int index_msb)
index 11a5851..de00c46 100644 (file)
@@ -2276,26 +2276,28 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq
 
 /*
  * Either sets desc->affinity to a valid value, and returns
- * ->cpu_mask_to_apicid of that, or returns BAD_APICID and
+ * ->cpu_mask_to_apicid of that in dest_id, or returns -1 and
  * leaves desc->affinity untouched.
  */
 unsigned int
-set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask)
+set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask,
+                 unsigned int *dest_id)
 {
        struct irq_cfg *cfg;
        unsigned int irq;
 
        if (!cpumask_intersects(mask, cpu_online_mask))
-               return BAD_APICID;
+               return -1;
 
        irq = desc->irq;
        cfg = desc->chip_data;
        if (assign_irq_vector(irq, cfg, mask))
-               return BAD_APICID;
+               return -1;
 
        cpumask_copy(desc->affinity, mask);
 
-       return apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
+       *dest_id = apic->cpu_mask_to_apicid_and(desc->affinity, cfg->domain);
+       return 0;
 }
 
 static int
@@ -2311,12 +2313,11 @@ set_ioapic_affinity_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
        cfg = desc->chip_data;
 
        spin_lock_irqsave(&ioapic_lock, flags);
-       dest = set_desc_affinity(desc, mask);
-       if (dest != BAD_APICID) {
+       ret = set_desc_affinity(desc, mask, &dest);
+       if (!ret) {
                /* Only the high 8 bits are valid. */
                dest = SET_APIC_LOGICAL_ID(dest);
                __target_IO_APIC_irq(irq, dest, cfg);
-               ret = 0;
        }
        spin_unlock_irqrestore(&ioapic_lock, flags);
 
@@ -3351,8 +3352,7 @@ static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
        struct msi_msg msg;
        unsigned int dest;
 
-       dest = set_desc_affinity(desc, mask);
-       if (dest == BAD_APICID)
+       if (set_desc_affinity(desc, mask, &dest))
                return -1;
 
        cfg = desc->chip_data;
@@ -3384,8 +3384,7 @@ ir_set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask)
        if (get_irte(irq, &irte))
                return -1;
 
-       dest = set_desc_affinity(desc, mask);
-       if (dest == BAD_APICID)
+       if (set_desc_affinity(desc, mask, &dest))
                return -1;
 
        irte.vector = cfg->vector;
@@ -3567,8 +3566,7 @@ static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
        struct msi_msg msg;
        unsigned int dest;
 
-       dest = set_desc_affinity(desc, mask);
-       if (dest == BAD_APICID)
+       if (set_desc_affinity(desc, mask, &dest))
                return -1;
 
        cfg = desc->chip_data;
@@ -3623,8 +3621,7 @@ static int hpet_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
        struct msi_msg msg;
        unsigned int dest;
 
-       dest = set_desc_affinity(desc, mask);
-       if (dest == BAD_APICID)
+       if (set_desc_affinity(desc, mask, &dest))
                return -1;
 
        cfg = desc->chip_data;
@@ -3730,8 +3727,7 @@ static int set_ht_irq_affinity(unsigned int irq, const struct cpumask *mask)
        struct irq_cfg *cfg;
        unsigned int dest;
 
-       dest = set_desc_affinity(desc, mask);
-       if (dest == BAD_APICID)
+       if (set_desc_affinity(desc, mask, &dest))
                return -1;
 
        cfg = desc->chip_data;
index a5371ec..cf69c59 100644 (file)
@@ -148,10 +148,7 @@ x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
                        break;
        }
 
-       if (cpu < nr_cpu_ids)
-               return per_cpu(x86_cpu_to_logical_apicid, cpu);
-
-       return BAD_APICID;
+       return per_cpu(x86_cpu_to_logical_apicid, cpu);
 }
 
 static unsigned int x2apic_cluster_phys_get_apic_id(unsigned long x)
index a8989aa..8972f38 100644 (file)
@@ -146,10 +146,7 @@ x2apic_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
                        break;
        }
 
-       if (cpu < nr_cpu_ids)
-               return per_cpu(x86_cpu_to_apicid, cpu);
-
-       return BAD_APICID;
+       return per_cpu(x86_cpu_to_apicid, cpu);
 }
 
 static unsigned int x2apic_phys_get_apic_id(unsigned long x)
index b684bb3..d56b0ef 100644 (file)
@@ -225,10 +225,7 @@ uv_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
                if (cpumask_test_cpu(cpu, cpu_online_mask))
                        break;
        }
-       if (cpu < nr_cpu_ids)
-               return per_cpu(x86_cpu_to_apicid, cpu);
-
-       return BAD_APICID;
+       return per_cpu(x86_cpu_to_apicid, cpu);
 }
 
 static unsigned int x2apic_get_apic_id(unsigned long x)
index 8dc3ea1..e485825 100644 (file)
@@ -254,59 +254,36 @@ static int __cpuinit nearby_node(int apicid)
 
 /*
  * Fixup core topology information for AMD multi-node processors.
- * Assumption 1: Number of cores in each internal node is the same.
- * Assumption 2: Mixed systems with both single-node and dual-node
- *               processors are not supported.
+ * Assumption: Number of cores in each internal node is the same.
  */
 #ifdef CONFIG_X86_HT
 static void __cpuinit amd_fixup_dcm(struct cpuinfo_x86 *c)
 {
-#ifdef CONFIG_PCI
-       u32 t, cpn;
-       u8 n, n_id;
+       unsigned long long value;
+       u32 nodes, cores_per_node;
        int cpu = smp_processor_id();
 
+       if (!cpu_has(c, X86_FEATURE_NODEID_MSR))
+               return;
+
        /* fixup topology information only once for a core */
        if (cpu_has(c, X86_FEATURE_AMD_DCM))
                return;
 
-       /* check for multi-node processor on boot cpu */
-       t = read_pci_config(0, 24, 3, 0xe8);
-       if (!(t & (1 << 29)))
+       rdmsrl(MSR_FAM10H_NODE_ID, value);
+
+       nodes = ((value >> 3) & 7) + 1;
+       if (nodes == 1)
                return;
 
        set_cpu_cap(c, X86_FEATURE_AMD_DCM);
+       cores_per_node = c->x86_max_cores / nodes;
 
-       /* cores per node: each internal node has half the number of cores */
-       cpn = c->x86_max_cores >> 1;
+       /* store NodeID, use llc_shared_map to store sibling info */
+       per_cpu(cpu_llc_id, cpu) = value & 7;
 
-       /* even-numbered NB_id of this dual-node processor */
-       n = c->phys_proc_id << 1;
-
-       /*
-        * determine internal node id and assign cores fifty-fifty to
-        * each node of the dual-node processor
-        */
-       t = read_pci_config(0, 24 + n, 3, 0xe8);
-       n = (t>>30) & 0x3;
-       if (n == 0) {
-               if (c->cpu_core_id < cpn)
-                       n_id = 0;
-               else
-                       n_id = 1;
-       } else {
-               if (c->cpu_core_id < cpn)
-                       n_id = 1;
-               else
-                       n_id = 0;
-       }
-
-       /* compute entire NodeID, use llc_shared_map to store sibling info */
-       per_cpu(cpu_llc_id, cpu) = (c->phys_proc_id << 1) + n_id;
-
-       /* fixup core id to be in range from 0 to cpn */
-       c->cpu_core_id = c->cpu_core_id % cpn;
-#endif
+       /* fixup core id to be in range from 0 to (cores_per_node - 1) */
+       c->cpu_core_id = c->cpu_core_id % cores_per_node;
 }
 #endif
 
index 9c31e8b..879666f 100644 (file)
@@ -70,7 +70,6 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
        if (c->x86_power & (1 << 8)) {
                set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
                set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
-               set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE);
                sched_clock_stable = 1;
        }
 
index 45506d5..c223b7e 100644 (file)
@@ -2336,6 +2336,7 @@ static const struct stacktrace_ops backtrace_ops = {
        .warning_symbol         = backtrace_warning_symbol,
        .stack                  = backtrace_stack,
        .address                = backtrace_address,
+       .walk_stack             = print_context_stack_bp,
 };
 
 #include "../dumpstack.h"
index 7ef24a7..cb27fd6 100644 (file)
@@ -187,7 +187,8 @@ static int __init cpuid_init(void)
        int i, err = 0;
        i = 0;
 
-       if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) {
+       if (__register_chrdev(CPUID_MAJOR, 0, NR_CPUS,
+                             "cpu/cpuid", &cpuid_fops)) {
                printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
                       CPUID_MAJOR);
                err = -EBUSY;
@@ -216,7 +217,7 @@ out_class:
        }
        class_destroy(cpuid_class);
 out_chrdev:
-       unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
+       __unregister_chrdev(CPUID_MAJOR, 0, NR_CPUS, "cpu/cpuid");
 out:
        return err;
 }
index 0a0aa1c..c56bc28 100644 (file)
@@ -109,6 +109,30 @@ print_context_stack(struct thread_info *tinfo,
        }
        return bp;
 }
+EXPORT_SYMBOL_GPL(print_context_stack);
+
+unsigned long
+print_context_stack_bp(struct thread_info *tinfo,
+                      unsigned long *stack, unsigned long bp,
+                      const struct stacktrace_ops *ops, void *data,
+                      unsigned long *end, int *graph)
+{
+       struct stack_frame *frame = (struct stack_frame *)bp;
+       unsigned long *ret_addr = &frame->return_address;
+
+       while (valid_stack_ptr(tinfo, ret_addr, sizeof(*ret_addr), end)) {
+               unsigned long addr = *ret_addr;
+
+               if (__kernel_text_address(addr)) {
+                       ops->address(data, addr, 1);
+                       frame = frame->next_frame;
+                       ret_addr = &frame->return_address;
+                       print_ftrace_graph_addr(addr, data, ops, tinfo, graph);
+               }
+       }
+       return (unsigned long)frame;
+}
+EXPORT_SYMBOL_GPL(print_context_stack_bp);
 
 
 static void
@@ -141,10 +165,11 @@ static void print_trace_address(void *data, unsigned long addr, int reliable)
 }
 
 static const struct stacktrace_ops print_trace_ops = {
-       .warning = print_trace_warning,
-       .warning_symbol = print_trace_warning_symbol,
-       .stack = print_trace_stack,
-       .address = print_trace_address,
+       .warning                = print_trace_warning,
+       .warning_symbol         = print_trace_warning_symbol,
+       .stack                  = print_trace_stack,
+       .address                = print_trace_address,
+       .walk_stack             = print_context_stack,
 };
 
 void
index 81086c2..4fd1420 100644 (file)
 #define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :)
 #endif
 
-extern unsigned long
-print_context_stack(struct thread_info *tinfo,
-               unsigned long *stack, unsigned long bp,
-               const struct stacktrace_ops *ops, void *data,
-               unsigned long *end, int *graph);
-
 extern void
 show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
                unsigned long *stack, unsigned long bp, char *log_lvl);
index e0ed4c7..ae775ca 100644 (file)
@@ -58,7 +58,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
 
                context = (struct thread_info *)
                        ((unsigned long)stack & (~(THREAD_SIZE - 1)));
-               bp = print_context_stack(context, stack, bp, ops, data, NULL, &graph);
+               bp = ops->walk_stack(context, stack, bp, ops, data, NULL, &graph);
 
                stack = (unsigned long *)context->previous_esp;
                if (!stack)
index b13af53..0ad9597 100644 (file)
@@ -188,8 +188,8 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
                        if (ops->stack(data, id) < 0)
                                break;
 
-                       bp = print_context_stack(tinfo, stack, bp, ops,
-                                                data, estack_end, &graph);
+                       bp = ops->walk_stack(tinfo, stack, bp, ops,
+                                            data, estack_end, &graph);
                        ops->stack(data, "<EOE>");
                        /*
                         * We link to the next stack via the
index f50447d..05ed7ab 100644 (file)
@@ -724,7 +724,7 @@ core_initcall(e820_mark_nvs_memory);
 /*
  * Early reserved memory areas.
  */
-#define MAX_EARLY_RES 20
+#define MAX_EARLY_RES 32
 
 struct early_res {
        u64 start, end;
index 572b07e..4bd93c9 100644 (file)
@@ -246,7 +246,7 @@ static int __init msr_init(void)
        int i, err = 0;
        i = 0;
 
-       if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) {
+       if (__register_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr", &msr_fops)) {
                printk(KERN_ERR "msr: unable to get major %d for msr\n",
                       MSR_MAJOR);
                err = -EBUSY;
@@ -274,7 +274,7 @@ out_class:
                msr_device_destroy(i);
        class_destroy(msr_class);
 out_chrdev:
-       unregister_chrdev(MSR_MAJOR, "cpu/msr");
+       __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr");
 out:
        return err;
 }
index c3eb207..922eefb 100644 (file)
@@ -53,17 +53,19 @@ save_stack_address_nosched(void *data, unsigned long addr, int reliable)
 }
 
 static const struct stacktrace_ops save_stack_ops = {
-       .warning = save_stack_warning,
-       .warning_symbol = save_stack_warning_symbol,
-       .stack = save_stack_stack,
-       .address = save_stack_address,
+       .warning        = save_stack_warning,
+       .warning_symbol = save_stack_warning_symbol,
+       .stack          = save_stack_stack,
+       .address        = save_stack_address,
+       .walk_stack     = print_context_stack,
 };
 
 static const struct stacktrace_ops save_stack_ops_nosched = {
-       .warning = save_stack_warning,
-       .warning_symbol = save_stack_warning_symbol,
-       .stack = save_stack_stack,
-       .address = save_stack_address_nosched,
+       .warning        = save_stack_warning,
+       .warning_symbol = save_stack_warning_symbol,
+       .stack          = save_stack_stack,
+       .address        = save_stack_address_nosched,
+       .walk_stack     = print_context_stack,
 };
 
 /*
index cd982f4..597683a 100644 (file)
@@ -763,6 +763,7 @@ void mark_tsc_unstable(char *reason)
 {
        if (!tsc_unstable) {
                tsc_unstable = 1;
+               sched_clock_stable = 0;
                printk(KERN_INFO "Marking TSC unstable due to %s\n", reason);
                /* Change only the rating, when not registered */
                if (clocksource_tsc.mult)
index 61d805d..ece73d8 100644 (file)
@@ -215,8 +215,7 @@ static int uv_set_irq_affinity(unsigned int irq, const struct cpumask *mask)
        unsigned long mmr_offset;
        unsigned mmr_pnode;
 
-       dest = set_desc_affinity(desc, mask);
-       if (dest == BAD_APICID)
+       if (set_desc_affinity(desc, mask, &dest))
                return -1;
 
        mmr_value = 0;
index 45b20e4..cffd754 100644 (file)
@@ -14,7 +14,7 @@ $(obj)/inat.o: $(obj)/inat-tables.c
 
 clean-files := inat-tables.c
 
-obj-$(CONFIG_SMP) := msr.o
+obj-$(CONFIG_SMP) += msr-smp.o
 
 lib-y := delay.o
 lib-y += thunk_$(BITS).o
@@ -22,7 +22,7 @@ lib-y += usercopy_$(BITS).o getuser.o putuser.o
 lib-y += memcpy_$(BITS).o
 lib-$(CONFIG_KPROBES) += insn.o inat.o
 
-obj-y += msr-reg.o msr-reg-export.o
+obj-y += msr.o msr-reg.o msr-reg-export.o
 
 ifeq ($(CONFIG_X86_32),y)
         obj-y += atomic64_32.o
diff --git a/arch/x86/lib/msr-smp.c b/arch/x86/lib/msr-smp.c
new file mode 100644 (file)
index 0000000..a6b1b86
--- /dev/null
@@ -0,0 +1,204 @@
+#include <linux/module.h>
+#include <linux/preempt.h>
+#include <linux/smp.h>
+#include <asm/msr.h>
+
+static void __rdmsr_on_cpu(void *info)
+{
+       struct msr_info *rv = info;
+       struct msr *reg;
+       int this_cpu = raw_smp_processor_id();
+
+       if (rv->msrs)
+               reg = per_cpu_ptr(rv->msrs, this_cpu);
+       else
+               reg = &rv->reg;
+
+       rdmsr(rv->msr_no, reg->l, reg->h);
+}
+
+static void __wrmsr_on_cpu(void *info)
+{
+       struct msr_info *rv = info;
+       struct msr *reg;
+       int this_cpu = raw_smp_processor_id();
+
+       if (rv->msrs)
+               reg = per_cpu_ptr(rv->msrs, this_cpu);
+       else
+               reg = &rv->reg;
+
+       wrmsr(rv->msr_no, reg->l, reg->h);
+}
+
+int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
+{
+       int err;
+       struct msr_info rv;
+
+       memset(&rv, 0, sizeof(rv));
+
+       rv.msr_no = msr_no;
+       err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
+       *l = rv.reg.l;
+       *h = rv.reg.h;
+
+       return err;
+}
+EXPORT_SYMBOL(rdmsr_on_cpu);
+
+int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
+{
+       int err;
+       struct msr_info rv;
+
+       memset(&rv, 0, sizeof(rv));
+
+       rv.msr_no = msr_no;
+       rv.reg.l = l;
+       rv.reg.h = h;
+       err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
+
+       return err;
+}
+EXPORT_SYMBOL(wrmsr_on_cpu);
+
+static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,
+                           struct msr *msrs,
+                           void (*msr_func) (void *info))
+{
+       struct msr_info rv;
+       int this_cpu;
+
+       memset(&rv, 0, sizeof(rv));
+
+       rv.msrs   = msrs;
+       rv.msr_no = msr_no;
+
+       this_cpu = get_cpu();
+
+       if (cpumask_test_cpu(this_cpu, mask))
+               msr_func(&rv);
+
+       smp_call_function_many(mask, msr_func, &rv, 1);
+       put_cpu();
+}
+
+/* rdmsr on a bunch of CPUs
+ *
+ * @mask:       which CPUs
+ * @msr_no:     which MSR
+ * @msrs:       array of MSR values
+ *
+ */
+void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
+{
+       __rwmsr_on_cpus(mask, msr_no, msrs, __rdmsr_on_cpu);
+}
+EXPORT_SYMBOL(rdmsr_on_cpus);
+
+/*
+ * wrmsr on a bunch of CPUs
+ *
+ * @mask:       which CPUs
+ * @msr_no:     which MSR
+ * @msrs:       array of MSR values
+ *
+ */
+void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
+{
+       __rwmsr_on_cpus(mask, msr_no, msrs, __wrmsr_on_cpu);
+}
+EXPORT_SYMBOL(wrmsr_on_cpus);
+
+/* These "safe" variants are slower and should be used when the target MSR
+   may not actually exist. */
+static void __rdmsr_safe_on_cpu(void *info)
+{
+       struct msr_info *rv = info;
+
+       rv->err = rdmsr_safe(rv->msr_no, &rv->reg.l, &rv->reg.h);
+}
+
+static void __wrmsr_safe_on_cpu(void *info)
+{
+       struct msr_info *rv = info;
+
+       rv->err = wrmsr_safe(rv->msr_no, rv->reg.l, rv->reg.h);
+}
+
+int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
+{
+       int err;
+       struct msr_info rv;
+
+       memset(&rv, 0, sizeof(rv));
+
+       rv.msr_no = msr_no;
+       err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1);
+       *l = rv.reg.l;
+       *h = rv.reg.h;
+
+       return err ? err : rv.err;
+}
+EXPORT_SYMBOL(rdmsr_safe_on_cpu);
+
+int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
+{
+       int err;
+       struct msr_info rv;
+
+       memset(&rv, 0, sizeof(rv));
+
+       rv.msr_no = msr_no;
+       rv.reg.l = l;
+       rv.reg.h = h;
+       err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
+
+       return err ? err : rv.err;
+}
+EXPORT_SYMBOL(wrmsr_safe_on_cpu);
+
+/*
+ * These variants are significantly slower, but allows control over
+ * the entire 32-bit GPR set.
+ */
+static void __rdmsr_safe_regs_on_cpu(void *info)
+{
+       struct msr_regs_info *rv = info;
+
+       rv->err = rdmsr_safe_regs(rv->regs);
+}
+
+static void __wrmsr_safe_regs_on_cpu(void *info)
+{
+       struct msr_regs_info *rv = info;
+
+       rv->err = wrmsr_safe_regs(rv->regs);
+}
+
+int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
+{
+       int err;
+       struct msr_regs_info rv;
+
+       rv.regs   = regs;
+       rv.err    = -EIO;
+       err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1);
+
+       return err ? err : rv.err;
+}
+EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu);
+
+int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
+{
+       int err;
+       struct msr_regs_info rv;
+
+       rv.regs = regs;
+       rv.err  = -EIO;
+       err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1);
+
+       return err ? err : rv.err;
+}
+EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu);
index 8728341..8f8eebd 100644 (file)
@@ -1,123 +1,7 @@
 #include <linux/module.h>
 #include <linux/preempt.h>
-#include <linux/smp.h>
 #include <asm/msr.h>
 
-struct msr_info {
-       u32 msr_no;
-       struct msr reg;
-       struct msr *msrs;
-       int err;
-};
-
-static void __rdmsr_on_cpu(void *info)
-{
-       struct msr_info *rv = info;
-       struct msr *reg;
-       int this_cpu = raw_smp_processor_id();
-
-       if (rv->msrs)
-               reg = per_cpu_ptr(rv->msrs, this_cpu);
-       else
-               reg = &rv->reg;
-
-       rdmsr(rv->msr_no, reg->l, reg->h);
-}
-
-static void __wrmsr_on_cpu(void *info)
-{
-       struct msr_info *rv = info;
-       struct msr *reg;
-       int this_cpu = raw_smp_processor_id();
-
-       if (rv->msrs)
-               reg = per_cpu_ptr(rv->msrs, this_cpu);
-       else
-               reg = &rv->reg;
-
-       wrmsr(rv->msr_no, reg->l, reg->h);
-}
-
-int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
-{
-       int err;
-       struct msr_info rv;
-
-       memset(&rv, 0, sizeof(rv));
-
-       rv.msr_no = msr_no;
-       err = smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 1);
-       *l = rv.reg.l;
-       *h = rv.reg.h;
-
-       return err;
-}
-EXPORT_SYMBOL(rdmsr_on_cpu);
-
-int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
-{
-       int err;
-       struct msr_info rv;
-
-       memset(&rv, 0, sizeof(rv));
-
-       rv.msr_no = msr_no;
-       rv.reg.l = l;
-       rv.reg.h = h;
-       err = smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 1);
-
-       return err;
-}
-EXPORT_SYMBOL(wrmsr_on_cpu);
-
-static void __rwmsr_on_cpus(const struct cpumask *mask, u32 msr_no,
-                           struct msr *msrs,
-                           void (*msr_func) (void *info))
-{
-       struct msr_info rv;
-       int this_cpu;
-
-       memset(&rv, 0, sizeof(rv));
-
-       rv.msrs   = msrs;
-       rv.msr_no = msr_no;
-
-       this_cpu = get_cpu();
-
-       if (cpumask_test_cpu(this_cpu, mask))
-               msr_func(&rv);
-
-       smp_call_function_many(mask, msr_func, &rv, 1);
-       put_cpu();
-}
-
-/* rdmsr on a bunch of CPUs
- *
- * @mask:       which CPUs
- * @msr_no:     which MSR
- * @msrs:       array of MSR values
- *
- */
-void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
-{
-       __rwmsr_on_cpus(mask, msr_no, msrs, __rdmsr_on_cpu);
-}
-EXPORT_SYMBOL(rdmsr_on_cpus);
-
-/*
- * wrmsr on a bunch of CPUs
- *
- * @mask:       which CPUs
- * @msr_no:     which MSR
- * @msrs:       array of MSR values
- *
- */
-void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs)
-{
-       __rwmsr_on_cpus(mask, msr_no, msrs, __wrmsr_on_cpu);
-}
-EXPORT_SYMBOL(wrmsr_on_cpus);
-
 struct msr *msrs_alloc(void)
 {
        struct msr *msrs = NULL;
@@ -137,100 +21,3 @@ void msrs_free(struct msr *msrs)
        free_percpu(msrs);
 }
 EXPORT_SYMBOL(msrs_free);
-
-/* These "safe" variants are slower and should be used when the target MSR
-   may not actually exist. */
-static void __rdmsr_safe_on_cpu(void *info)
-{
-       struct msr_info *rv = info;
-
-       rv->err = rdmsr_safe(rv->msr_no, &rv->reg.l, &rv->reg.h);
-}
-
-static void __wrmsr_safe_on_cpu(void *info)
-{
-       struct msr_info *rv = info;
-
-       rv->err = wrmsr_safe(rv->msr_no, rv->reg.l, rv->reg.h);
-}
-
-int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
-{
-       int err;
-       struct msr_info rv;
-
-       memset(&rv, 0, sizeof(rv));
-
-       rv.msr_no = msr_no;
-       err = smp_call_function_single(cpu, __rdmsr_safe_on_cpu, &rv, 1);
-       *l = rv.reg.l;
-       *h = rv.reg.h;
-
-       return err ? err : rv.err;
-}
-EXPORT_SYMBOL(rdmsr_safe_on_cpu);
-
-int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
-{
-       int err;
-       struct msr_info rv;
-
-       memset(&rv, 0, sizeof(rv));
-
-       rv.msr_no = msr_no;
-       rv.reg.l = l;
-       rv.reg.h = h;
-       err = smp_call_function_single(cpu, __wrmsr_safe_on_cpu, &rv, 1);
-
-       return err ? err : rv.err;
-}
-EXPORT_SYMBOL(wrmsr_safe_on_cpu);
-
-/*
- * These variants are significantly slower, but allows control over
- * the entire 32-bit GPR set.
- */
-struct msr_regs_info {
-       u32 *regs;
-       int err;
-};
-
-static void __rdmsr_safe_regs_on_cpu(void *info)
-{
-       struct msr_regs_info *rv = info;
-
-       rv->err = rdmsr_safe_regs(rv->regs);
-}
-
-static void __wrmsr_safe_regs_on_cpu(void *info)
-{
-       struct msr_regs_info *rv = info;
-
-       rv->err = wrmsr_safe_regs(rv->regs);
-}
-
-int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
-{
-       int err;
-       struct msr_regs_info rv;
-
-       rv.regs   = regs;
-       rv.err    = -EIO;
-       err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1);
-
-       return err ? err : rv.err;
-}
-EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu);
-
-int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
-{
-       int err;
-       struct msr_regs_info rv;
-
-       rv.regs = regs;
-       rv.err  = -EIO;
-       err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1);
-
-       return err ? err : rv.err;
-}
-EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu);
index 6f8aa33..9324f13 100644 (file)
@@ -267,6 +267,8 @@ int __init get_memcfg_from_srat(void)
                e820_register_active_regions(chunk->nid, chunk->start_pfn,
                                             min(chunk->end_pfn, max_pfn));
        }
+       /* for out of order entries in SRAT */
+       sort_node_map();
 
        for_each_online_node(nid) {
                unsigned long start = node_start_pfn[nid];
index d890754..a271241 100644 (file)
@@ -317,7 +317,7 @@ static int __init nodes_cover_memory(const struct bootnode *nodes)
                unsigned long s = nodes[i].start >> PAGE_SHIFT;
                unsigned long e = nodes[i].end >> PAGE_SHIFT;
                pxmram += e - s;
-               pxmram -= absent_pages_in_range(s, e);
+               pxmram -= __absent_pages_in_range(i, s, e);
                if ((long)pxmram < 0)
                        pxmram = 0;
        }
@@ -373,6 +373,8 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
        for_each_node_mask(i, nodes_parsed)
                e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT,
                                                nodes[i].end >> PAGE_SHIFT);
+       /* for out of order entries in SRAT */
+       sort_node_map();
        if (!nodes_cover_memory(nodes)) {
                bad_srat();
                return -1;
index 044897b..3855096 100644 (file)
@@ -41,10 +41,11 @@ static void backtrace_address(void *data, unsigned long addr, int reliable)
 }
 
 static struct stacktrace_ops backtrace_ops = {
-       .warning = backtrace_warning,
-       .warning_symbol = backtrace_warning_symbol,
-       .stack = backtrace_stack,
-       .address = backtrace_address,
+       .warning        = backtrace_warning,
+       .warning_symbol = backtrace_warning_symbol,
+       .stack          = backtrace_stack,
+       .address        = backtrace_address,
+       .walk_stack     = print_context_stack,
 };
 
 struct frame_head {
index 0d13cd9..5bbb5a3 100644 (file)
@@ -9,7 +9,7 @@ BEGIN {
 }
 
 /^GNU/ {
-       split($4, ver, ".");
+       split($3, ver, ".");
        if (ver[1] > od_ver ||
            (ver[1] == od_ver && ver[2] >= od_sver)) {
                exit 1;
index 7a68506..eaf11f5 100644 (file)
@@ -6,8 +6,6 @@
 
 # Awk implementation sanity check
 function check_awk_implement() {
-       if (!match("abc", "[[:lower:]]+"))
-               return "Your awk doesn't support charactor-class."
        if (sprintf("%x", 0) != "0")
                return "Your awk has a printf-format problem."
        return ""
@@ -44,12 +42,12 @@ BEGIN {
        delete gtable
        delete atable
 
-       opnd_expr = "^[[:alpha:]/]"
+       opnd_expr = "^[A-Za-z/]"
        ext_expr = "^\\("
        sep_expr = "^\\|$"
-       group_expr = "^Grp[[:alnum:]]+"
+       group_expr = "^Grp[0-9A-Za-z]+"
 
-       imm_expr = "^[IJAO][[:lower:]]"
+       imm_expr = "^[IJAO][a-z]"
        imm_flag["Ib"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
        imm_flag["Jb"] = "INAT_MAKE_IMM(INAT_IMM_BYTE)"
        imm_flag["Iw"] = "INAT_MAKE_IMM(INAT_IMM_WORD)"
@@ -62,7 +60,7 @@ BEGIN {
        imm_flag["Ob"] = "INAT_MOFFSET"
        imm_flag["Ov"] = "INAT_MOFFSET"
 
-       modrm_expr = "^([CDEGMNPQRSUVW/][[:lower:]]+|NTA|T[012])"
+       modrm_expr = "^([CDEGMNPQRSUVW/][a-z]+|NTA|T[012])"
        force64_expr = "\\([df]64\\)"
        rex_expr = "^REX(\\.[XRWB]+)*"
        fpu_expr = "^ESC" # TODO
index 1683ebd..f4ea5a8 100644 (file)
@@ -3022,7 +3022,7 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
        case WRITE_16:
                return ata_scsi_rw_xlat;
 
-       case 0x93 /*WRITE_SAME_16*/:
+       case WRITE_SAME_16:
                return ata_scsi_write_same_xlat;
 
        case SYNCHRONIZE_CACHE:
index efa8773..741065c 100644 (file)
@@ -2275,7 +2275,7 @@ void ata_sff_drain_fifo(struct ata_queued_cmd *qc)
        ap = qc->ap;
        /* Drain up to 64K of data before we give up this recovery method */
        for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ)
-                                               && count < 32768; count++)
+                                               && count < 65536; count += 2)
                ioread16(ap->ioaddr.data_addr);
 
        /* Can become DEBUG later */
index dadfc35..0efb1f5 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME "pata_cmd64x"
-#define DRV_VERSION "0.3.1"
+#define DRV_VERSION "0.2.5"
 
 /*
  * CMD64x specific registers definition.
@@ -219,7 +219,7 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
                regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift;
                /* Merge the control bits */
                regU |= 1 << adev->devno; /* UDMA on */
-               if (adev->dma_mode > 2) /* 15nS timing */
+               if (adev->dma_mode > XFER_UDMA_2) /* 15nS timing */
                        regU |= 4 << adev->devno;
        } else {
                regU &= ~ (1 << adev->devno);   /* UDMA off */
@@ -254,109 +254,17 @@ static void cmd648_bmdma_stop(struct ata_queued_cmd *qc)
 }
 
 /**
- *     cmd64x_bmdma_stop       -       DMA stop callback
+ *     cmd646r1_dma_stop       -       DMA stop callback
  *     @qc: Command in progress
  *
- *     Track the completion of live DMA commands and clear the
- *     host->private_data DMA tracking flag as we do.
+ *     Stub for now while investigating the r1 quirk in the old driver.
  */
 
-static void cmd64x_bmdma_stop(struct ata_queued_cmd *qc)
+static void cmd646r1_bmdma_stop(struct ata_queued_cmd *qc)
 {
-       struct ata_port *ap = qc->ap;
        ata_bmdma_stop(qc);
-       WARN_ON(ap->host->private_data != ap);
-       ap->host->private_data = NULL;
-}
-
-/**
- *     cmd64x_qc_defer         -       Defer logic for chip limits
- *     @qc: queued command
- *
- *     Decide whether we can issue the command. Called under the host lock.
- */
-
-static int cmd64x_qc_defer(struct ata_queued_cmd *qc)
-{
-       struct ata_host *host = qc->ap->host;
-       struct ata_port *alt = host->ports[1 ^ qc->ap->port_no];
-       int rc;
-       int dma = 0;
-
-       /* Apply the ATA rules first */
-       rc = ata_std_qc_defer(qc);
-       if (rc)
-               return rc;
-
-       if (qc->tf.protocol == ATAPI_PROT_DMA ||
-                       qc->tf.protocol == ATA_PROT_DMA)
-               dma = 1;
-
-       /* If the other port is not live then issue the command */
-       if (alt == NULL || !alt->qc_active) {
-               if (dma)
-                       host->private_data = qc->ap;
-               return 0;
-       }
-       /* If there is a live DMA command then wait */
-       if (host->private_data != NULL)
-               return  ATA_DEFER_PORT;
-       if (dma)
-               /* Cannot overlap our DMA command */
-               return ATA_DEFER_PORT;
-       return 0;
 }
 
-/**
- *     cmd64x_interrupt - ATA host interrupt handler
- *     @irq: irq line (unused)
- *     @dev_instance: pointer to our ata_host information structure
- *
- *     Our interrupt handler for PCI IDE devices.  Calls
- *     ata_sff_host_intr() for each port that is flagging an IRQ. We cannot
- *     use the defaults as we need to avoid touching status/altstatus during
- *     a DMA.
- *
- *     LOCKING:
- *     Obtains host lock during operation.
- *
- *     RETURNS:
- *     IRQ_NONE or IRQ_HANDLED.
- */
-irqreturn_t cmd64x_interrupt(int irq, void *dev_instance)
-{
-       struct ata_host *host = dev_instance;
-       struct pci_dev *pdev = to_pci_dev(host->dev);
-       unsigned int i;
-       unsigned int handled = 0;
-       unsigned long flags;
-       static const u8 irq_reg[2] = { CFR, ARTTIM23 };
-       static const u8 irq_mask[2] = { 1 << 2, 1 << 4 };
-
-       /* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
-       spin_lock_irqsave(&host->lock, flags);
-
-       for (i = 0; i < host->n_ports; i++) {
-               struct ata_port *ap;
-               u8 reg;
-
-               pci_read_config_byte(pdev, irq_reg[i], &reg);
-               ap = host->ports[i];
-               if (ap && (reg & irq_mask[i]) &&
-                   !(ap->flags & ATA_FLAG_DISABLED)) {
-                       struct ata_queued_cmd *qc;
-
-                       qc = ata_qc_from_tag(ap, ap->link.active_tag);
-                       if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) &&
-                           (qc->flags & ATA_QCFLAG_ACTIVE))
-                               handled |= ata_sff_host_intr(ap, qc);
-               }
-       }
-
-       spin_unlock_irqrestore(&host->lock, flags);
-
-       return IRQ_RETVAL(handled);
-}
 static struct scsi_host_template cmd64x_sht = {
        ATA_BMDMA_SHT(DRV_NAME),
 };
@@ -365,8 +273,6 @@ static const struct ata_port_operations cmd64x_base_ops = {
        .inherits       = &ata_bmdma_port_ops,
        .set_piomode    = cmd64x_set_piomode,
        .set_dmamode    = cmd64x_set_dmamode,
-       .bmdma_stop     = cmd64x_bmdma_stop,
-       .qc_defer       = cmd64x_qc_defer,
 };
 
 static struct ata_port_operations cmd64x_port_ops = {
@@ -376,6 +282,7 @@ static struct ata_port_operations cmd64x_port_ops = {
 
 static struct ata_port_operations cmd646r1_port_ops = {
        .inherits       = &cmd64x_base_ops,
+       .bmdma_stop     = cmd646r1_bmdma_stop,
        .cable_detect   = ata_cable_40wire,
 };
 
@@ -383,7 +290,6 @@ static struct ata_port_operations cmd648_port_ops = {
        .inherits       = &cmd64x_base_ops,
        .bmdma_stop     = cmd648_bmdma_stop,
        .cable_detect   = cmd648_cable_detect,
-       .qc_defer       = ata_std_qc_defer
 };
 
 static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -432,7 +338,6 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
        const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL };
        u8 mrdmode;
        int rc;
-       struct ata_host *host;
 
        rc = pcim_enable_device(pdev);
        if (rc)
@@ -450,25 +355,20 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
                        ppi[0] = &cmd_info[3];
        }
 
-
        pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
        pci_read_config_byte(pdev, MRDMODE, &mrdmode);
        mrdmode &= ~ 0x30;      /* IRQ set up */
        mrdmode |= 0x02;        /* Memory read line enable */
        pci_write_config_byte(pdev, MRDMODE, mrdmode);
 
+       /* Force PIO 0 here.. */
+
        /* PPC specific fixup copied from old driver */
 #ifdef CONFIG_PPC
        pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
 #endif
-       rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
-       if (rc)
-               return rc;
-       /* We use this pointer to track the AP which has DMA running */
-       host->private_data = NULL;
 
-       pci_set_master(pdev);
-       return ata_pci_sff_activate_host(host, cmd64x_interrupt, &cmd64x_sht);
+       return ata_pci_sff_init_one(pdev, ppi, &cmd64x_sht, NULL);
 }
 
 #ifdef CONFIG_PM
index 9a09a1b..dd26bc7 100644 (file)
@@ -8,7 +8,7 @@
  * Copyright (C) 1999-2003             Andre Hedrick <andre@linux-ide.org>
  * Portions Copyright (C) 2001         Sun Microsystems, Inc.
  * Portions Copyright (C) 2003         Red Hat Inc
- * Portions Copyright (C) 2005-2007    MontaVista Software, Inc.
+ * Portions Copyright (C) 2005-2009    MontaVista Software, Inc.
  *
  *
  * TODO
@@ -25,7 +25,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "pata_hpt3x2n"
-#define DRV_VERSION    "0.3.7"
+#define DRV_VERSION    "0.3.8"
 
 enum {
        HPT_PCI_FAST    =       (1 << 31),
@@ -264,7 +264,7 @@ static void hpt3x2n_bmdma_stop(struct ata_queued_cmd *qc)
 
 static void hpt3x2n_set_clock(struct ata_port *ap, int source)
 {
-       void __iomem *bmdma = ap->ioaddr.bmdma_addr;
+       void __iomem *bmdma = ap->ioaddr.bmdma_addr - ap->port_no * 8;
 
        /* Tristate the bus */
        iowrite8(0x80, bmdma+0x73);
@@ -274,9 +274,9 @@ static void hpt3x2n_set_clock(struct ata_port *ap, int source)
        iowrite8(source, bmdma+0x7B);
        iowrite8(0xC0, bmdma+0x79);
 
-       /* Reset state machines */
-       iowrite8(0x37, bmdma+0x70);
-       iowrite8(0x37, bmdma+0x74);
+       /* Reset state machines, avoid enabling the disabled channels */
+       iowrite8(ioread8(bmdma+0x70) | 0x32, bmdma+0x70);
+       iowrite8(ioread8(bmdma+0x74) | 0x32, bmdma+0x74);
 
        /* Complete reset */
        iowrite8(0x00, bmdma+0x79);
@@ -286,21 +286,10 @@ static void hpt3x2n_set_clock(struct ata_port *ap, int source)
        iowrite8(0x00, bmdma+0x77);
 }
 
-/* Check if our partner interface is busy */
-
-static int hpt3x2n_pair_idle(struct ata_port *ap)
-{
-       struct ata_host *host = ap->host;
-       struct ata_port *pair = host->ports[ap->port_no ^ 1];
-
-       if (pair->hsm_task_state == HSM_ST_IDLE)
-               return 1;
-       return 0;
-}
-
 static int hpt3x2n_use_dpll(struct ata_port *ap, int writing)
 {
        long flags = (long)ap->host->private_data;
+
        /* See if we should use the DPLL */
        if (writing)
                return USE_DPLL;        /* Needed for write */
@@ -309,20 +298,35 @@ static int hpt3x2n_use_dpll(struct ata_port *ap, int writing)
        return 0;
 }
 
+static int hpt3x2n_qc_defer(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       struct ata_port *alt = ap->host->ports[ap->port_no ^ 1];
+       int rc, flags = (long)ap->host->private_data;
+       int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE);
+
+       /* First apply the usual rules */
+       rc = ata_std_qc_defer(qc);
+       if (rc != 0)
+               return rc;
+
+       if ((flags & USE_DPLL) != dpll && alt->qc_active)
+               return ATA_DEFER_PORT;
+       return 0;
+}
+
 static unsigned int hpt3x2n_qc_issue(struct ata_queued_cmd *qc)
 {
-       struct ata_taskfile *tf = &qc->tf;
        struct ata_port *ap = qc->ap;
        int flags = (long)ap->host->private_data;
+       int dpll = hpt3x2n_use_dpll(ap, qc->tf.flags & ATA_TFLAG_WRITE);
 
-       if (hpt3x2n_pair_idle(ap)) {
-               int dpll = hpt3x2n_use_dpll(ap, (tf->flags & ATA_TFLAG_WRITE));
-               if ((flags & USE_DPLL) != dpll) {
-                       if (dpll == 1)
-                               hpt3x2n_set_clock(ap, 0x21);
-                       else
-                               hpt3x2n_set_clock(ap, 0x23);
-               }
+       if ((flags & USE_DPLL) != dpll) {
+               flags &= ~USE_DPLL;
+               flags |= dpll;
+               ap->host->private_data = (void *)(long)flags;
+
+               hpt3x2n_set_clock(ap, dpll ? 0x21 : 0x23);
        }
        return ata_sff_qc_issue(qc);
 }
@@ -339,6 +343,8 @@ static struct ata_port_operations hpt3x2n_port_ops = {
        .inherits       = &ata_bmdma_port_ops,
 
        .bmdma_stop     = hpt3x2n_bmdma_stop,
+
+       .qc_defer       = hpt3x2n_qc_defer,
        .qc_issue       = hpt3x2n_qc_issue,
 
        .cable_detect   = hpt3x2n_cable_detect,
@@ -454,7 +460,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        unsigned int f_low, f_high;
        int adjust;
        unsigned long iobase = pci_resource_start(dev, 4);
-       void *hpriv = NULL;
+       void *hpriv = (void *)USE_DPLL;
        int rc;
 
        rc = pcim_enable_device(dev);
@@ -539,7 +545,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        /* Set our private data up. We only need a few flags so we use
           it directly */
        if (pci_mhz > 60) {
-               hpriv = (void *)PCI66;
+               hpriv = (void *)(PCI66 | USE_DPLL);
                /*
                 * On  HPT371N, if ATA clock is 66 MHz we must set bit 2 in
                 * the MISC. register to stretch the UltraDMA Tss timing.
index d6f6956..37ef416 100644 (file)
@@ -853,7 +853,7 @@ static int __devinit octeon_cf_probe(struct platform_device *pdev)
                        return -EINVAL;
 
                cs1 = devm_ioremap_nocache(&pdev->dev, res_cs1->start,
-                                          res_cs0->end - res_cs1->start + 1);
+                                          resource_size(res_cs1));
 
                if (!cs1)
                        return -ENOMEM;
index a8a7be0..df8ee32 100644 (file)
@@ -59,6 +59,7 @@
 #include <linux/dmapool.h>
 #include <linux/dma-mapping.h>
 #include <linux/device.h>
+#include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/ata_platform.h>
 #include <linux/mbus.h>
@@ -538,6 +539,7 @@ struct mv_port_signal {
 
 struct mv_host_priv {
        u32                     hp_flags;
+       unsigned int            board_idx;
        u32                     main_irq_mask;
        struct mv_port_signal   signal[8];
        const struct mv_hw_ops  *ops;
@@ -548,6 +550,10 @@ struct mv_host_priv {
        u32                     irq_cause_offset;
        u32                     irq_mask_offset;
        u32                     unmask_all_irqs;
+
+#if defined(CONFIG_HAVE_CLK)
+       struct clk              *clk;
+#endif
        /*
         * These consistent DMA memory pools give us guaranteed
         * alignment for hardware-accessed data structures,
@@ -2775,7 +2781,7 @@ static void mv_port_intr(struct ata_port *ap, u32 port_cause)
        struct mv_port_priv *pp;
        int edma_was_enabled;
 
-       if (!ap || (ap->flags & ATA_FLAG_DISABLED)) {
+       if (ap->flags & ATA_FLAG_DISABLED) {
                mv_unexpected_intr(ap, 0);
                return;
        }
@@ -3393,7 +3399,7 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv,
        ZERO(0x024);            /* respq outp */
        ZERO(0x020);            /* respq inp */
        ZERO(0x02c);            /* test control */
-       writel(0xbc, port_mmio + EDMA_IORDY_TMOUT);
+       writel(0x800, port_mmio + EDMA_IORDY_TMOUT);
 }
 
 #undef ZERO
@@ -3854,7 +3860,6 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
 /**
  *      mv_init_host - Perform some early initialization of the host.
  *     @host: ATA host to initialize
- *      @board_idx: controller index
  *
  *      If possible, do an early global reset of the host.  Then do
  *      our port init and clear/unmask all/relevant host interrupts.
@@ -3862,13 +3867,13 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
  *      LOCKING:
  *      Inherited from caller.
  */
-static int mv_init_host(struct ata_host *host, unsigned int board_idx)
+static int mv_init_host(struct ata_host *host)
 {
        int rc = 0, n_hc, port, hc;
        struct mv_host_priv *hpriv = host->private_data;
        void __iomem *mmio = hpriv->base;
 
-       rc = mv_chip_id(host, board_idx);
+       rc = mv_chip_id(host, hpriv->board_idx);
        if (rc)
                goto done;
 
@@ -3905,14 +3910,6 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
                void __iomem *port_mmio = mv_port_base(mmio, port);
 
                mv_port_init(&ap->ioaddr, port_mmio);
-
-#ifdef CONFIG_PCI
-               if (!IS_SOC(hpriv)) {
-                       unsigned int offset = port_mmio - mmio;
-                       ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio");
-                       ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port");
-               }
-#endif
        }
 
        for (hc = 0; hc < n_hc; hc++) {
@@ -4035,12 +4032,21 @@ static int mv_platform_probe(struct platform_device *pdev)
                return -ENOMEM;
        host->private_data = hpriv;
        hpriv->n_ports = n_ports;
+       hpriv->board_idx = chip_soc;
 
        host->iomap = NULL;
        hpriv->base = devm_ioremap(&pdev->dev, res->start,
                                   resource_size(res));
        hpriv->base -= SATAHC0_REG_BASE;
 
+#if defined(CONFIG_HAVE_CLK)
+       hpriv->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(hpriv->clk))
+               dev_notice(&pdev->dev, "cannot get clkdev\n");
+       else
+               clk_enable(hpriv->clk);
+#endif
+
        /*
         * (Re-)program MBUS remapping windows if we are asked to.
         */
@@ -4049,12 +4055,12 @@ static int mv_platform_probe(struct platform_device *pdev)
 
        rc = mv_create_dma_pools(hpriv, &pdev->dev);
        if (rc)
-               return rc;
+               goto err;
 
        /* initialize adapter */
-       rc = mv_init_host(host, chip_soc);
+       rc = mv_init_host(host);
        if (rc)
-               return rc;
+               goto err;
 
        dev_printk(KERN_INFO, &pdev->dev,
                   "slots %u ports %d\n", (unsigned)MV_MAX_Q_DEPTH,
@@ -4062,6 +4068,15 @@ static int mv_platform_probe(struct platform_device *pdev)
 
        return ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt,
                                 IRQF_SHARED, &mv6_sht);
+err:
+#if defined(CONFIG_HAVE_CLK)
+       if (!IS_ERR(hpriv->clk)) {
+               clk_disable(hpriv->clk);
+               clk_put(hpriv->clk);
+       }
+#endif
+
+       return rc;
 }
 
 /*
@@ -4076,14 +4091,66 @@ static int __devexit mv_platform_remove(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct ata_host *host = dev_get_drvdata(dev);
-
+#if defined(CONFIG_HAVE_CLK)
+       struct mv_host_priv *hpriv = host->private_data;
+#endif
        ata_host_detach(host);
+
+#if defined(CONFIG_HAVE_CLK)
+       if (!IS_ERR(hpriv->clk)) {
+               clk_disable(hpriv->clk);
+               clk_put(hpriv->clk);
+       }
+#endif
        return 0;
 }
 
+#ifdef CONFIG_PM
+static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct ata_host *host = dev_get_drvdata(&pdev->dev);
+       if (host)
+               return ata_host_suspend(host, state);
+       else
+               return 0;
+}
+
+static int mv_platform_resume(struct platform_device *pdev)
+{
+       struct ata_host *host = dev_get_drvdata(&pdev->dev);
+       int ret;
+
+       if (host) {
+               struct mv_host_priv *hpriv = host->private_data;
+               const struct mv_sata_platform_data *mv_platform_data = \
+                       pdev->dev.platform_data;
+               /*
+                * (Re-)program MBUS remapping windows if we are asked to.
+                */
+               if (mv_platform_data->dram != NULL)
+                       mv_conf_mbus_windows(hpriv, mv_platform_data->dram);
+
+               /* initialize adapter */
+               ret = mv_init_host(host);
+               if (ret) {
+                       printk(KERN_ERR DRV_NAME ": Error during HW init\n");
+                       return ret;
+               }
+               ata_host_resume(host);
+       }
+
+       return 0;
+}
+#else
+#define mv_platform_suspend NULL
+#define mv_platform_resume NULL
+#endif
+
 static struct platform_driver mv_platform_driver = {
        .probe                  = mv_platform_probe,
        .remove                 = __devexit_p(mv_platform_remove),
+       .suspend                = mv_platform_suspend,
+       .resume                 = mv_platform_resume,
        .driver                 = {
                                   .name = DRV_NAME,
                                   .owner = THIS_MODULE,
@@ -4094,6 +4161,9 @@ static struct platform_driver mv_platform_driver = {
 #ifdef CONFIG_PCI
 static int mv_pci_init_one(struct pci_dev *pdev,
                           const struct pci_device_id *ent);
+#ifdef CONFIG_PM
+static int mv_pci_device_resume(struct pci_dev *pdev);
+#endif
 
 
 static struct pci_driver mv_pci_driver = {
@@ -4101,6 +4171,11 @@ static struct pci_driver mv_pci_driver = {
        .id_table               = mv_pci_tbl,
        .probe                  = mv_pci_init_one,
        .remove                 = ata_pci_remove_one,
+#ifdef CONFIG_PM
+       .suspend                = ata_pci_device_suspend,
+       .resume                 = mv_pci_device_resume,
+#endif
+
 };
 
 /* move to PCI layer or libata core? */
@@ -4194,7 +4269,7 @@ static int mv_pci_init_one(struct pci_dev *pdev,
        const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL };
        struct ata_host *host;
        struct mv_host_priv *hpriv;
-       int n_ports, rc;
+       int n_ports, port, rc;
 
        if (!printed_version++)
                dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
@@ -4208,6 +4283,7 @@ static int mv_pci_init_one(struct pci_dev *pdev,
                return -ENOMEM;
        host->private_data = hpriv;
        hpriv->n_ports = n_ports;
+       hpriv->board_idx = board_idx;
 
        /* acquire resources */
        rc = pcim_enable_device(pdev);
@@ -4230,8 +4306,17 @@ static int mv_pci_init_one(struct pci_dev *pdev,
        if (rc)
                return rc;
 
+       for (port = 0; port < host->n_ports; port++) {
+               struct ata_port *ap = host->ports[port];
+               void __iomem *port_mmio = mv_port_base(hpriv->base, port);
+               unsigned int offset = port_mmio - hpriv->base;
+
+               ata_port_pbar_desc(ap, MV_PRIMARY_BAR, -1, "mmio");
+               ata_port_pbar_desc(ap, MV_PRIMARY_BAR, offset, "port");
+       }
+
        /* initialize adapter */
-       rc = mv_init_host(host, board_idx);
+       rc = mv_init_host(host);
        if (rc)
                return rc;
 
@@ -4247,6 +4332,27 @@ static int mv_pci_init_one(struct pci_dev *pdev,
        return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED,
                                 IS_GEN_I(hpriv) ? &mv5_sht : &mv6_sht);
 }
+
+#ifdef CONFIG_PM
+static int mv_pci_device_resume(struct pci_dev *pdev)
+{
+       struct ata_host *host = dev_get_drvdata(&pdev->dev);
+       int rc;
+
+       rc = ata_pci_device_do_resume(pdev);
+       if (rc)
+               return rc;
+
+       /* initialize adapter */
+       rc = mv_init_host(host);
+       if (rc)
+               return rc;
+
+       ata_host_resume(host);
+
+       return 0;
+}
+#endif
 #endif
 
 static int mv_platform_probe(struct platform_device *pdev);
index 4d29059..a699f09 100644 (file)
@@ -307,6 +307,7 @@ static void btusb_bulk_complete(struct urb *urb)
                return;
 
        usb_anchor_urb(urb, &data->bulk_anchor);
+       usb_mark_last_busy(data->udev);
 
        err = usb_submit_urb(urb, GFP_ATOMIC);
        if (err < 0) {
index d3400b2..7d73cd4 100644 (file)
@@ -358,7 +358,7 @@ struct port {
        u8 update_flow_control;
        struct ctrl_ul ctrl_ul;
        struct ctrl_dl ctrl_dl;
-       struct kfifo *fifo_ul;
+       struct kfifo fifo_ul;
        void __iomem *dl_addr[2];
        u32 dl_size[2];
        u8 toggle_dl;
@@ -685,8 +685,6 @@ static int nozomi_read_config_table(struct nozomi *dc)
                dump_table(dc);
 
                for (i = PORT_MDM; i < MAX_PORT; i++) {
-                       dc->port[i].fifo_ul =
-                           kfifo_alloc(FIFO_BUFFER_SIZE_UL, GFP_ATOMIC, NULL);
                        memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl));
                        memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul));
                }
@@ -798,7 +796,7 @@ static int send_data(enum port_type index, struct nozomi *dc)
        struct tty_struct *tty = tty_port_tty_get(&port->port);
 
        /* Get data from tty and place in buf for now */
-       size = __kfifo_get(port->fifo_ul, dc->send_buf,
+       size = kfifo_out(&port->fifo_ul, dc->send_buf,
                           ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX);
 
        if (size == 0) {
@@ -988,11 +986,11 @@ static int receive_flow_control(struct nozomi *dc)
 
        } else if (old_ctrl.CTS == 0 && ctrl_dl.CTS == 1) {
 
-               if (__kfifo_len(dc->port[port].fifo_ul)) {
+               if (kfifo_len(&dc->port[port].fifo_ul)) {
                        DBG1("Enable interrupt (0x%04X) on port: %d",
                                enable_ier, port);
                        DBG1("Data in buffer [%d], enable transmit! ",
-                               __kfifo_len(dc->port[port].fifo_ul));
+                               kfifo_len(&dc->port[port].fifo_ul));
                        enable_transmit_ul(port, dc);
                } else {
                        DBG1("No data in buffer...");
@@ -1433,6 +1431,16 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
                goto err_free_sbuf;
        }
 
+       for (i = PORT_MDM; i < MAX_PORT; i++) {
+               if (kfifo_alloc(&dc->port[i].fifo_ul,
+                     FIFO_BUFFER_SIZE_UL, GFP_ATOMIC)) {
+                       dev_err(&pdev->dev,
+                                       "Could not allocate kfifo buffer\n");
+                       ret = -ENOMEM;
+                       goto err_free_kfifo;
+               }
+       }
+
        spin_lock_init(&dc->spin_mutex);
 
        nozomi_setup_private_data(dc);
@@ -1445,7 +1453,7 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
                        NOZOMI_NAME, dc);
        if (unlikely(ret)) {
                dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq);
-               goto err_free_sbuf;
+               goto err_free_kfifo;
        }
 
        DBG1("base_addr: %p", dc->base_addr);
@@ -1464,13 +1472,28 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
        dc->state = NOZOMI_STATE_ENABLED;
 
        for (i = 0; i < MAX_PORT; i++) {
+               struct device *tty_dev;
+
                mutex_init(&dc->port[i].tty_sem);
                tty_port_init(&dc->port[i].port);
-               tty_register_device(ntty_driver, dc->index_start + i,
+               tty_dev = tty_register_device(ntty_driver, dc->index_start + i,
                                                        &pdev->dev);
+
+               if (IS_ERR(tty_dev)) {
+                       ret = PTR_ERR(tty_dev);
+                       dev_err(&pdev->dev, "Could not allocate tty?\n");
+                       goto err_free_tty;
+               }
        }
+
        return 0;
 
+err_free_tty:
+       for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i)
+               tty_unregister_device(ntty_driver, i);
+err_free_kfifo:
+       for (i = 0; i < MAX_PORT; i++)
+               kfifo_free(&dc->port[i].fifo_ul);
 err_free_sbuf:
        kfree(dc->send_buf);
        iounmap(dc->base_addr);
@@ -1536,8 +1559,7 @@ static void __devexit nozomi_card_exit(struct pci_dev *pdev)
        free_irq(pdev->irq, dc);
 
        for (i = 0; i < MAX_PORT; i++)
-               if (dc->port[i].fifo_ul)
-                       kfifo_free(dc->port[i].fifo_ul);
+               kfifo_free(&dc->port[i].fifo_ul);
 
        kfree(dc->send_buf);
 
@@ -1673,7 +1695,7 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer,
                goto exit;
        }
 
-       rval = __kfifo_put(port->fifo_ul, (unsigned char *)buffer, count);
+       rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count);
 
        /* notify card */
        if (unlikely(dc == NULL)) {
@@ -1721,7 +1743,7 @@ static int ntty_write_room(struct tty_struct *tty)
        if (!port->port.count)
                goto exit;
 
-       room = port->fifo_ul->size - __kfifo_len(port->fifo_ul);
+       room = port->fifo_ul.size - kfifo_len(&port->fifo_ul);
 
 exit:
        mutex_unlock(&port->tty_sem);
@@ -1878,7 +1900,7 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty)
                goto exit_in_buffer;
        }
 
-       rval = __kfifo_len(port->fifo_ul);
+       rval = kfifo_len(&port->fifo_ul);
 
 exit_in_buffer:
        return rval;
index 8c262aa..0798754 100644 (file)
@@ -487,7 +487,7 @@ static struct sonypi_device {
        int camera_power;
        int bluetooth_power;
        struct mutex lock;
-       struct kfifo *fifo;
+       struct kfifo fifo;
        spinlock_t fifo_lock;
        wait_queue_head_t fifo_proc_list;
        struct fasync_struct *fifo_async;
@@ -496,7 +496,7 @@ static struct sonypi_device {
        struct input_dev *input_jog_dev;
        struct input_dev *input_key_dev;
        struct work_struct input_work;
-       struct kfifo *input_fifo;
+       struct kfifo input_fifo;
        spinlock_t input_fifo_lock;
 } sonypi_device;
 
@@ -777,8 +777,9 @@ static void input_keyrelease(struct work_struct *work)
 {
        struct sonypi_keypress kp;
 
-       while (kfifo_get(sonypi_device.input_fifo, (unsigned char *)&kp,
-                        sizeof(kp)) == sizeof(kp)) {
+       while (kfifo_out_locked(&sonypi_device.input_fifo, (unsigned char *)&kp,
+                        sizeof(kp), &sonypi_device.input_fifo_lock)
+                       == sizeof(kp)) {
                msleep(10);
                input_report_key(kp.dev, kp.key, 0);
                input_sync(kp.dev);
@@ -827,8 +828,9 @@ static void sonypi_report_input_event(u8 event)
        if (kp.dev) {
                input_report_key(kp.dev, kp.key, 1);
                input_sync(kp.dev);
-               kfifo_put(sonypi_device.input_fifo,
-                         (unsigned char *)&kp, sizeof(kp));
+               kfifo_in_locked(&sonypi_device.input_fifo,
+                       (unsigned char *)&kp, sizeof(kp),
+                       &sonypi_device.input_fifo_lock);
                schedule_work(&sonypi_device.input_work);
        }
 }
@@ -880,7 +882,8 @@ found:
                acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event);
 #endif
 
-       kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event));
+       kfifo_in_locked(&sonypi_device.fifo, (unsigned char *)&event,
+                       sizeof(event), &sonypi_device.fifo_lock);
        kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);
        wake_up_interruptible(&sonypi_device.fifo_proc_list);
 
@@ -906,7 +909,7 @@ static int sonypi_misc_open(struct inode *inode, struct file *file)
        mutex_lock(&sonypi_device.lock);
        /* Flush input queue on first open */
        if (!sonypi_device.open_count)
-               kfifo_reset(sonypi_device.fifo);
+               kfifo_reset(&sonypi_device.fifo);
        sonypi_device.open_count++;
        mutex_unlock(&sonypi_device.lock);
        unlock_kernel();
@@ -919,17 +922,18 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf,
        ssize_t ret;
        unsigned char c;
 
-       if ((kfifo_len(sonypi_device.fifo) == 0) &&
+       if ((kfifo_len(&sonypi_device.fifo) == 0) &&
            (file->f_flags & O_NONBLOCK))
                return -EAGAIN;
 
        ret = wait_event_interruptible(sonypi_device.fifo_proc_list,
-                                      kfifo_len(sonypi_device.fifo) != 0);
+                                      kfifo_len(&sonypi_device.fifo) != 0);
        if (ret)
                return ret;
 
        while (ret < count &&
-              (kfifo_get(sonypi_device.fifo, &c, sizeof(c)) == sizeof(c))) {
+              (kfifo_out_locked(&sonypi_device.fifo, &c, sizeof(c),
+                                &sonypi_device.fifo_lock) == sizeof(c))) {
                if (put_user(c, buf++))
                        return -EFAULT;
                ret++;
@@ -946,7 +950,7 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf,
 static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait)
 {
        poll_wait(file, &sonypi_device.fifo_proc_list, wait);
-       if (kfifo_len(sonypi_device.fifo))
+       if (kfifo_len(&sonypi_device.fifo))
                return POLLIN | POLLRDNORM;
        return 0;
 }
@@ -1313,11 +1317,10 @@ static int __devinit sonypi_probe(struct platform_device *dev)
                        "http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n");
 
        spin_lock_init(&sonypi_device.fifo_lock);
-       sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
-                                        &sonypi_device.fifo_lock);
-       if (IS_ERR(sonypi_device.fifo)) {
+       error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL);
+       if (error) {
                printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
-               return PTR_ERR(sonypi_device.fifo);
+               return error;
        }
 
        init_waitqueue_head(&sonypi_device.fifo_proc_list);
@@ -1393,12 +1396,10 @@ static int __devinit sonypi_probe(struct platform_device *dev)
                }
 
                spin_lock_init(&sonypi_device.input_fifo_lock);
-               sonypi_device.input_fifo =
-                       kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
-                                   &sonypi_device.input_fifo_lock);
-               if (IS_ERR(sonypi_device.input_fifo)) {
+               error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE,
+                               GFP_KERNEL);
+               if (error) {
                        printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
-                       error = PTR_ERR(sonypi_device.input_fifo);
                        goto err_inpdev_unregister;
                }
 
@@ -1423,7 +1424,7 @@ static int __devinit sonypi_probe(struct platform_device *dev)
                pci_disable_device(pcidev);
  err_put_pcidev:
        pci_dev_put(pcidev);
-       kfifo_free(sonypi_device.fifo);
+       kfifo_free(&sonypi_device.fifo);
 
        return error;
 }
@@ -1438,7 +1439,7 @@ static int __devexit sonypi_remove(struct platform_device *dev)
        if (useinput) {
                input_unregister_device(sonypi_device.input_key_dev);
                input_unregister_device(sonypi_device.input_jog_dev);
-               kfifo_free(sonypi_device.input_fifo);
+               kfifo_free(&sonypi_device.input_fifo);
        }
 
        misc_deregister(&sonypi_misc_device);
@@ -1451,7 +1452,7 @@ static int __devexit sonypi_remove(struct platform_device *dev)
                pci_dev_put(sonypi_device.dev);
        }
 
-       kfifo_free(sonypi_device.fifo);
+       kfifo_free(&sonypi_device.fifo);
 
        return 0;
 }
index bfd03bf..f3d440c 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <linux/list.h>
 #include <linux/mutex.h>
+#include <linux/kfifo.h>
 
 #include "t3_cpl.h"
 #include "t3cdev.h"
@@ -75,13 +76,13 @@ struct cxio_hal_ctrl_qp {
 };
 
 struct cxio_hal_resource {
-       struct kfifo *tpt_fifo;
+       struct kfifo tpt_fifo;
        spinlock_t tpt_fifo_lock;
-       struct kfifo *qpid_fifo;
+       struct kfifo qpid_fifo;
        spinlock_t qpid_fifo_lock;
-       struct kfifo *cqid_fifo;
+       struct kfifo cqid_fifo;
        spinlock_t cqid_fifo_lock;
-       struct kfifo *pdid_fifo;
+       struct kfifo pdid_fifo;
        spinlock_t pdid_fifo_lock;
 };
 
index bd233c0..31f9201 100644 (file)
 #include "cxio_resource.h"
 #include "cxio_hal.h"
 
-static struct kfifo *rhdl_fifo;
+static struct kfifo rhdl_fifo;
 static spinlock_t rhdl_fifo_lock;
 
 #define RANDOM_SIZE 16
 
-static int __cxio_init_resource_fifo(struct kfifo **fifo,
+static int __cxio_init_resource_fifo(struct kfifo *fifo,
                                   spinlock_t *fifo_lock,
                                   u32 nr, u32 skip_low,
                                   u32 skip_high,
@@ -55,12 +55,11 @@ static int __cxio_init_resource_fifo(struct kfifo **fifo,
        u32 rarray[16];
        spin_lock_init(fifo_lock);
 
-       *fifo = kfifo_alloc(nr * sizeof(u32), GFP_KERNEL, fifo_lock);
-       if (IS_ERR(*fifo))
+       if (kfifo_alloc(fifo, nr * sizeof(u32), GFP_KERNEL))
                return -ENOMEM;
 
        for (i = 0; i < skip_low + skip_high; i++)
-               __kfifo_put(*fifo, (unsigned char *) &entry, sizeof(u32));
+               kfifo_in(fifo, (unsigned char *) &entry, sizeof(u32));
        if (random) {
                j = 0;
                random_bytes = random32();
@@ -72,33 +71,35 @@ static int __cxio_init_resource_fifo(struct kfifo **fifo,
                                random_bytes = random32();
                        }
                        idx = (random_bytes >> (j * 2)) & 0xF;
-                       __kfifo_put(*fifo,
+                       kfifo_in(fifo,
                                (unsigned char *) &rarray[idx],
                                sizeof(u32));
                        rarray[idx] = i;
                        j++;
                }
                for (i = 0; i < RANDOM_SIZE; i++)
-                       __kfifo_put(*fifo,
+                       kfifo_in(fifo,
                                (unsigned char *) &rarray[i],
                                sizeof(u32));
        } else
                for (i = skip_low; i < nr - skip_high; i++)
-                       __kfifo_put(*fifo, (unsigned char *) &i, sizeof(u32));
+                       kfifo_in(fifo, (unsigned char *) &i, sizeof(u32));
 
        for (i = 0; i < skip_low + skip_high; i++)
-               kfifo_get(*fifo, (unsigned char *) &entry, sizeof(u32));
+               if (kfifo_out_locked(fifo, (unsigned char *) &entry,
+                               sizeof(u32), fifo_lock) != sizeof(u32))
+                                       break;
        return 0;
 }
 
-static int cxio_init_resource_fifo(struct kfifo **fifo, spinlock_t * fifo_lock,
+static int cxio_init_resource_fifo(struct kfifo *fifo, spinlock_t * fifo_lock,
                                   u32 nr, u32 skip_low, u32 skip_high)
 {
        return (__cxio_init_resource_fifo(fifo, fifo_lock, nr, skip_low,
                                          skip_high, 0));
 }
 
-static int cxio_init_resource_fifo_random(struct kfifo **fifo,
+static int cxio_init_resource_fifo_random(struct kfifo *fifo,
                                   spinlock_t * fifo_lock,
                                   u32 nr, u32 skip_low, u32 skip_high)
 {
@@ -113,15 +114,13 @@ static int cxio_init_qpid_fifo(struct cxio_rdev *rdev_p)
 
        spin_lock_init(&rdev_p->rscp->qpid_fifo_lock);
 
-       rdev_p->rscp->qpid_fifo = kfifo_alloc(T3_MAX_NUM_QP * sizeof(u32),
-                                             GFP_KERNEL,
-                                             &rdev_p->rscp->qpid_fifo_lock);
-       if (IS_ERR(rdev_p->rscp->qpid_fifo))
+       if (kfifo_alloc(&rdev_p->rscp->qpid_fifo, T3_MAX_NUM_QP * sizeof(u32),
+                                             GFP_KERNEL))
                return -ENOMEM;
 
        for (i = 16; i < T3_MAX_NUM_QP; i++)
                if (!(i & rdev_p->qpmask))
-                       __kfifo_put(rdev_p->rscp->qpid_fifo,
+                       kfifo_in(&rdev_p->rscp->qpid_fifo,
                                    (unsigned char *) &i, sizeof(u32));
        return 0;
 }
@@ -134,7 +133,7 @@ int cxio_hal_init_rhdl_resource(u32 nr_rhdl)
 
 void cxio_hal_destroy_rhdl_resource(void)
 {
-       kfifo_free(rhdl_fifo);
+       kfifo_free(&rhdl_fifo);
 }
 
 /* nr_* must be power of 2 */
@@ -167,11 +166,11 @@ int cxio_hal_init_resource(struct cxio_rdev *rdev_p,
                goto pdid_err;
        return 0;
 pdid_err:
-       kfifo_free(rscp->cqid_fifo);
+       kfifo_free(&rscp->cqid_fifo);
 cqid_err:
-       kfifo_free(rscp->qpid_fifo);
+       kfifo_free(&rscp->qpid_fifo);
 qpid_err:
-       kfifo_free(rscp->tpt_fifo);
+       kfifo_free(&rscp->tpt_fifo);
 tpt_err:
        return -ENOMEM;
 }
@@ -179,33 +178,37 @@ tpt_err:
 /*
  * returns 0 if no resource available
  */
-static u32 cxio_hal_get_resource(struct kfifo *fifo)
+static u32 cxio_hal_get_resource(struct kfifo *fifo, spinlock_t * lock)
 {
        u32 entry;
-       if (kfifo_get(fifo, (unsigned char *) &entry, sizeof(u32)))
+       if (kfifo_out_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock))
                return entry;
        else
                return 0;       /* fifo emptry */
 }
 
-static void cxio_hal_put_resource(struct kfifo *fifo, u32 entry)
+static void cxio_hal_put_resource(struct kfifo *fifo, spinlock_t * lock,
+               u32 entry)
 {
-       BUG_ON(kfifo_put(fifo, (unsigned char *) &entry, sizeof(u32)) == 0);
+       BUG_ON(
+       kfifo_in_locked(fifo, (unsigned char *) &entry, sizeof(u32), lock)
+       == 0);
 }
 
 u32 cxio_hal_get_stag(struct cxio_hal_resource *rscp)
 {
-       return cxio_hal_get_resource(rscp->tpt_fifo);
+       return cxio_hal_get_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock);
 }
 
 void cxio_hal_put_stag(struct cxio_hal_resource *rscp, u32 stag)
 {
-       cxio_hal_put_resource(rscp->tpt_fifo, stag);
+       cxio_hal_put_resource(&rscp->tpt_fifo, &rscp->tpt_fifo_lock, stag);
 }
 
 u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp)
 {
-       u32 qpid = cxio_hal_get_resource(rscp->qpid_fifo);
+       u32 qpid = cxio_hal_get_resource(&rscp->qpid_fifo,
+                       &rscp->qpid_fifo_lock);
        PDBG("%s qpid 0x%x\n", __func__, qpid);
        return qpid;
 }
@@ -213,35 +216,35 @@ u32 cxio_hal_get_qpid(struct cxio_hal_resource *rscp)
 void cxio_hal_put_qpid(struct cxio_hal_resource *rscp, u32 qpid)
 {
        PDBG("%s qpid 0x%x\n", __func__, qpid);
-       cxio_hal_put_resource(rscp->qpid_fifo, qpid);
+       cxio_hal_put_resource(&rscp->qpid_fifo, &rscp->qpid_fifo_lock, qpid);
 }
 
 u32 cxio_hal_get_cqid(struct cxio_hal_resource *rscp)
 {
-       return cxio_hal_get_resource(rscp->cqid_fifo);
+       return cxio_hal_get_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock);
 }
 
 void cxio_hal_put_cqid(struct cxio_hal_resource *rscp, u32 cqid)
 {
-       cxio_hal_put_resource(rscp->cqid_fifo, cqid);
+       cxio_hal_put_resource(&rscp->cqid_fifo, &rscp->cqid_fifo_lock, cqid);
 }
 
 u32 cxio_hal_get_pdid(struct cxio_hal_resource *rscp)
 {
-       return cxio_hal_get_resource(rscp->pdid_fifo);
+       return cxio_hal_get_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock);
 }
 
 void cxio_hal_put_pdid(struct cxio_hal_resource *rscp, u32 pdid)
 {
-       cxio_hal_put_resource(rscp->pdid_fifo, pdid);
+       cxio_hal_put_resource(&rscp->pdid_fifo, &rscp->pdid_fifo_lock, pdid);
 }
 
 void cxio_hal_destroy_resource(struct cxio_hal_resource *rscp)
 {
-       kfifo_free(rscp->tpt_fifo);
-       kfifo_free(rscp->cqid_fifo);
-       kfifo_free(rscp->qpid_fifo);
-       kfifo_free(rscp->pdid_fifo);
+       kfifo_free(&rscp->tpt_fifo);
+       kfifo_free(&rscp->cqid_fifo);
+       kfifo_free(&rscp->qpid_fifo);
+       kfifo_free(&rscp->pdid_fifo);
        kfree(rscp);
 }
 
index 7e5f30d..f1e8af5 100644 (file)
@@ -661,7 +661,7 @@ l1oip_socket_thread(void *data)
        size_t recvbuf_size = 1500;
        int recvlen;
        struct socket *socket = NULL;
-       DECLARE_COMPLETION(wait);
+       DECLARE_COMPLETION_ONSTACK(wait);
 
        /* allocate buffer memory */
        recvbuf = kmalloc(recvbuf_size, GFP_KERNEL);
index 3ccc8af..2bf57a4 100644 (file)
@@ -124,15 +124,12 @@ struct cx23888_ir_state {
        atomic_t rxclk_divider;
        atomic_t rx_invert;
 
-       struct kfifo *rx_kfifo;
+       struct kfifo rx_kfifo;
        spinlock_t rx_kfifo_lock;
 
        struct v4l2_subdev_ir_parameters tx_params;
        struct mutex tx_params_lock;
        atomic_t txclk_divider;
-
-       struct kfifo *tx_kfifo;
-       spinlock_t tx_kfifo_lock;
 };
 
 static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd)
@@ -522,6 +519,7 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status,
 {
        struct cx23888_ir_state *state = to_state(sd);
        struct cx23885_dev *dev = state->dev;
+       unsigned long flags;
 
        u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG);
        u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG);
@@ -594,8 +592,9 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status,
                        if (i == 0)
                                break;
                        j = i * sizeof(u32);
-                       k = kfifo_put(state->rx_kfifo,
-                                     (unsigned char *) rx_data, j);
+                       k = kfifo_in_locked(&state->rx_kfifo,
+                                     (unsigned char *) rx_data, j,
+                                     &state->rx_kfifo_lock);
                        if (k != j)
                                kror++; /* rx_kfifo over run */
                }
@@ -631,8 +630,11 @@ static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status,
                cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl);
                *handled = true;
        }
-       if (kfifo_len(state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2)
+
+       spin_lock_irqsave(&state->rx_kfifo_lock, flags);
+       if (kfifo_len(&state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2)
                events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ;
+       spin_unlock_irqrestore(&state->rx_kfifo_lock, flags);
 
        if (events)
                v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events);
@@ -657,7 +659,7 @@ static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count,
                return 0;
        }
 
-       n = kfifo_get(state->rx_kfifo, buf, n);
+       n = kfifo_out_locked(&state->rx_kfifo, buf, n, &state->rx_kfifo_lock);
 
        n /= sizeof(u32);
        *num = n * sizeof(u32);
@@ -785,7 +787,12 @@ static int cx23888_ir_rx_s_parameters(struct v4l2_subdev *sd,
        o->interrupt_enable = p->interrupt_enable;
        o->enable = p->enable;
        if (p->enable) {
-               kfifo_reset(state->rx_kfifo);
+               unsigned long flags;
+
+               spin_lock_irqsave(&state->rx_kfifo_lock, flags);
+               kfifo_reset(&state->rx_kfifo);
+               /* reset tx_fifo too if there is one... */
+               spin_unlock_irqrestore(&state->rx_kfifo_lock, flags);
                if (p->interrupt_enable)
                        irqenable_rx(dev, IRQEN_RSE | IRQEN_RTE | IRQEN_ROE);
                control_rx_enable(dev, p->enable);
@@ -892,7 +899,6 @@ static int cx23888_ir_tx_s_parameters(struct v4l2_subdev *sd,
        o->interrupt_enable = p->interrupt_enable;
        o->enable = p->enable;
        if (p->enable) {
-               kfifo_reset(state->tx_kfifo);
                if (p->interrupt_enable)
                        irqenable_tx(dev, IRQEN_TSE);
                control_tx_enable(dev, p->enable);
@@ -1168,18 +1174,8 @@ int cx23888_ir_probe(struct cx23885_dev *dev)
                return -ENOMEM;
 
        spin_lock_init(&state->rx_kfifo_lock);
-       state->rx_kfifo = kfifo_alloc(CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL,
-                                     &state->rx_kfifo_lock);
-       if (state->rx_kfifo == NULL)
-               return -ENOMEM;
-
-       spin_lock_init(&state->tx_kfifo_lock);
-       state->tx_kfifo = kfifo_alloc(CX23888_IR_TX_KFIFO_SIZE, GFP_KERNEL,
-                                     &state->tx_kfifo_lock);
-       if (state->tx_kfifo == NULL) {
-               kfifo_free(state->rx_kfifo);
+       if (kfifo_alloc(&state->rx_kfifo, CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL))
                return -ENOMEM;
-       }
 
        state->dev = dev;
        state->id = V4L2_IDENT_CX23888_IR;
@@ -1211,8 +1207,7 @@ int cx23888_ir_probe(struct cx23885_dev *dev)
                       sizeof(struct v4l2_subdev_ir_parameters));
                v4l2_subdev_call(sd, ir, tx_s_parameters, &default_params);
        } else {
-               kfifo_free(state->rx_kfifo);
-               kfifo_free(state->tx_kfifo);
+               kfifo_free(&state->rx_kfifo);
        }
        return ret;
 }
@@ -1231,8 +1226,7 @@ int cx23888_ir_remove(struct cx23885_dev *dev)
 
        state = to_state(sd);
        v4l2_device_unregister_subdev(sd);
-       kfifo_free(state->rx_kfifo);
-       kfifo_free(state->tx_kfifo);
+       kfifo_free(&state->rx_kfifo);
        kfree(state);
        /* Nothing more to free() as state held the actual v4l2_subdev object */
        return 0;
index 6ffa64c..b421858 100644 (file)
@@ -800,8 +800,8 @@ again:
                return IRQ_HANDLED;
 
        if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) {
-               if (kfifo_get(meye.grabq, (unsigned char *)&reqnr,
-                             sizeof(int)) != sizeof(int)) {
+               if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr,
+                             sizeof(int), &meye.grabq_lock) != sizeof(int)) {
                        mchip_free_frame();
                        return IRQ_HANDLED;
                }
@@ -811,7 +811,8 @@ again:
                meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
                do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
                meye.grab_buffer[reqnr].sequence = sequence++;
-               kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int));
+               kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr,
+                               sizeof(int), &meye.doneq_lock);
                wake_up_interruptible(&meye.proc_list);
        } else {
                int size;
@@ -820,8 +821,8 @@ again:
                        mchip_free_frame();
                        goto again;
                }
-               if (kfifo_get(meye.grabq, (unsigned char *)&reqnr,
-                             sizeof(int)) != sizeof(int)) {
+               if (kfifo_out_locked(&meye.grabq, (unsigned char *)&reqnr,
+                             sizeof(int), &meye.grabq_lock) != sizeof(int)) {
                        mchip_free_frame();
                        goto again;
                }
@@ -831,7 +832,8 @@ again:
                meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
                do_gettimeofday(&meye.grab_buffer[reqnr].timestamp);
                meye.grab_buffer[reqnr].sequence = sequence++;
-               kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int));
+               kfifo_in_locked(&meye.doneq, (unsigned char *)&reqnr,
+                               sizeof(int), &meye.doneq_lock);
                wake_up_interruptible(&meye.proc_list);
        }
        mchip_free_frame();
@@ -859,8 +861,8 @@ static int meye_open(struct file *file)
 
        for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
                meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
-       kfifo_reset(meye.grabq);
-       kfifo_reset(meye.doneq);
+       kfifo_reset(&meye.grabq);
+       kfifo_reset(&meye.doneq);
        return 0;
 }
 
@@ -933,7 +935,8 @@ static int meyeioc_qbuf_capt(int *nb)
                mchip_cont_compression_start();
 
        meye.grab_buffer[*nb].state = MEYE_BUF_USING;
-       kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int));
+       kfifo_in_locked(&meye.grabq, (unsigned char *)nb, sizeof(int),
+                        &meye.grabq_lock);
        mutex_unlock(&meye.lock);
 
        return 0;
@@ -965,7 +968,9 @@ static int meyeioc_sync(struct file *file, void *fh, int *i)
                /* fall through */
        case MEYE_BUF_DONE:
                meye.grab_buffer[*i].state = MEYE_BUF_UNUSED;
-               kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int));
+               if (kfifo_out_locked(&meye.doneq, (unsigned char *)&unused,
+                               sizeof(int), &meye.doneq_lock) != sizeof(int))
+                                       break;
        }
        *i = meye.grab_buffer[*i].size;
        mutex_unlock(&meye.lock);
@@ -1452,7 +1457,8 @@ static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
        buf->flags |= V4L2_BUF_FLAG_QUEUED;
        buf->flags &= ~V4L2_BUF_FLAG_DONE;
        meye.grab_buffer[buf->index].state = MEYE_BUF_USING;
-       kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int));
+       kfifo_in_locked(&meye.grabq, (unsigned char *)&buf->index,
+                       sizeof(int), &meye.grabq_lock);
        mutex_unlock(&meye.lock);
 
        return 0;
@@ -1467,19 +1473,19 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
 
        mutex_lock(&meye.lock);
 
-       if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) {
+       if (kfifo_len(&meye.doneq) == 0 && file->f_flags & O_NONBLOCK) {
                mutex_unlock(&meye.lock);
                return -EAGAIN;
        }
 
        if (wait_event_interruptible(meye.proc_list,
-                                    kfifo_len(meye.doneq) != 0) < 0) {
+                                    kfifo_len(&meye.doneq) != 0) < 0) {
                mutex_unlock(&meye.lock);
                return -EINTR;
        }
 
-       if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr,
-                      sizeof(int))) {
+       if (!kfifo_out_locked(&meye.doneq, (unsigned char *)&reqnr,
+                      sizeof(int), &meye.doneq_lock)) {
                mutex_unlock(&meye.lock);
                return -EBUSY;
        }
@@ -1529,8 +1535,8 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
 {
        mutex_lock(&meye.lock);
        mchip_hic_stop();
-       kfifo_reset(meye.grabq);
-       kfifo_reset(meye.doneq);
+       kfifo_reset(&meye.grabq);
+       kfifo_reset(&meye.doneq);
 
        for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
                meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
@@ -1572,7 +1578,7 @@ static unsigned int meye_poll(struct file *file, poll_table *wait)
 
        mutex_lock(&meye.lock);
        poll_wait(file, &meye.proc_list, wait);
-       if (kfifo_len(meye.doneq))
+       if (kfifo_len(&meye.doneq))
                res = POLLIN | POLLRDNORM;
        mutex_unlock(&meye.lock);
        return res;
@@ -1745,16 +1751,14 @@ static int __devinit meye_probe(struct pci_dev *pcidev,
        }
 
        spin_lock_init(&meye.grabq_lock);
-       meye.grabq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
-                                &meye.grabq_lock);
-       if (IS_ERR(meye.grabq)) {
+       if (kfifo_alloc(&meye.grabq, sizeof(int) * MEYE_MAX_BUFNBRS,
+                               GFP_KERNEL)) {
                printk(KERN_ERR "meye: fifo allocation failed\n");
                goto outkfifoalloc1;
        }
        spin_lock_init(&meye.doneq_lock);
-       meye.doneq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL,
-                                &meye.doneq_lock);
-       if (IS_ERR(meye.doneq)) {
+       if (kfifo_alloc(&meye.doneq, sizeof(int) * MEYE_MAX_BUFNBRS,
+                               GFP_KERNEL)) {
                printk(KERN_ERR "meye: fifo allocation failed\n");
                goto outkfifoalloc2;
        }
@@ -1868,9 +1872,9 @@ outregions:
 outenabledev:
        sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0);
 outsonypienable:
-       kfifo_free(meye.doneq);
+       kfifo_free(&meye.doneq);
 outkfifoalloc2:
-       kfifo_free(meye.grabq);
+       kfifo_free(&meye.grabq);
 outkfifoalloc1:
        vfree(meye.grab_temp);
 outvmalloc:
@@ -1901,8 +1905,8 @@ static void __devexit meye_remove(struct pci_dev *pcidev)
 
        sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 0);
 
-       kfifo_free(meye.doneq);
-       kfifo_free(meye.grabq);
+       kfifo_free(&meye.doneq);
+       kfifo_free(&meye.grabq);
 
        vfree(meye.grab_temp);
 
index 5f70a10..1321ad5 100644 (file)
@@ -303,9 +303,9 @@ struct meye {
        struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS];
        int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */
        struct mutex lock;              /* mutex for open/mmap... */
-       struct kfifo *grabq;            /* queue for buffers to be grabbed */
+       struct kfifo grabq;             /* queue for buffers to be grabbed */
        spinlock_t grabq_lock;          /* lock protecting the queue */
-       struct kfifo *doneq;            /* queue for grabbed buffers */
+       struct kfifo doneq;             /* queue for grabbed buffers */
        spinlock_t doneq_lock;          /* lock protecting the queue */
        wait_queue_head_t proc_list;    /* wait queue */
        struct video_device *video_dev; /* video device parameters */
index 4bfc808..65df1de 100644 (file)
@@ -653,12 +653,20 @@ static void
 bnx2_netif_stop(struct bnx2 *bp)
 {
        bnx2_cnic_stop(bp);
-       bnx2_disable_int_sync(bp);
        if (netif_running(bp->dev)) {
+               int i;
+
                bnx2_napi_disable(bp);
                netif_tx_disable(bp->dev);
-               bp->dev->trans_start = jiffies; /* prevent tx timeout */
+               /* prevent tx timeout */
+               for (i = 0; i <  bp->dev->num_tx_queues; i++) {
+                       struct netdev_queue *txq;
+
+                       txq = netdev_get_tx_queue(bp->dev, i);
+                       txq->trans_start = jiffies;
+               }
        }
+       bnx2_disable_int_sync(bp);
 }
 
 static void
index d0ec178..166cc7e 100644 (file)
@@ -1037,7 +1037,7 @@ static int __init at91_can_probe(struct platform_device *pdev)
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        irq = platform_get_irq(pdev, 0);
-       if (!res || !irq) {
+       if (!res || irq <= 0) {
                err = -ENODEV;
                goto exit_put;
        }
index 8edac89..34e0310 100644 (file)
@@ -2272,7 +2272,7 @@ static int emac_mii_reset(struct mii_bus *bus)
        unsigned int clk_div;
        int mdio_bus_freq = emac_bus_frequency;
 
-       if (mdio_max_freq & mdio_bus_freq)
+       if (mdio_max_freq && mdio_bus_freq)
                clk_div = ((mdio_bus_freq / mdio_max_freq) - 1);
        else
                clk_div = 0xFF;
index 929701c..839fb2b 100644 (file)
@@ -1829,6 +1829,7 @@ static int e100_alloc_cbs(struct nic *nic)
                                  &nic->cbs_dma_addr);
        if (!nic->cbs)
                return -ENOMEM;
+       memset(nic->cbs, 0, count * sizeof(struct cb));
 
        for (cb = nic->cbs, i = 0; i < count; cb++, i++) {
                cb->next = (i + 1 < count) ? cb + 1 : nic->cbs;
@@ -1837,7 +1838,6 @@ static int e100_alloc_cbs(struct nic *nic)
                cb->dma_addr = nic->cbs_dma_addr + i * sizeof(struct cb);
                cb->link = cpu_to_le32(nic->cbs_dma_addr +
                        ((i+1) % count) * sizeof(struct cb));
-               cb->skb = NULL;
        }
 
        nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = nic->cbs;
index c1a42cf..b979464 100644 (file)
@@ -1290,7 +1290,6 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw)
 static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw)
 {
        u32 ctrl;
-       u32 led_ctrl;
        s32 ret_val;
 
        ctrl = er32(CTRL);
@@ -1305,11 +1304,6 @@ static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw)
                break;
        case e1000_phy_igp_2:
                ret_val = e1000e_copper_link_setup_igp(hw);
-               /* Setup activity LED */
-               led_ctrl = er32(LEDCTL);
-               led_ctrl &= IGP_ACTIVITY_LED_MASK;
-               led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
-               ew32(LEDCTL, led_ctrl);
                break;
        default:
                return -E1000_ERR_PHY;
index 6850dc0..e0620d0 100644 (file)
@@ -357,8 +357,11 @@ static void gfar_init_mac(struct net_device *ndev)
        /* Configure the coalescing support */
        gfar_configure_coalescing(priv, 0xFF, 0xFF);
 
-       if (priv->rx_filer_enable)
+       if (priv->rx_filer_enable) {
                rctrl |= RCTRL_FILREN;
+               /* Program the RIR0 reg with the required distribution */
+               gfar_write(&regs->rir0, DEFAULT_RIR0);
+       }
 
        if (priv->rx_csum_enable)
                rctrl |= RCTRL_CHECKSUMMING;
@@ -414,6 +417,36 @@ static void gfar_init_mac(struct net_device *ndev)
        gfar_write(&regs->fifo_tx_starve_shutoff, priv->fifo_starve_off);
 }
 
+static struct net_device_stats *gfar_get_stats(struct net_device *dev)
+{
+       struct gfar_private *priv = netdev_priv(dev);
+       struct netdev_queue *txq;
+       unsigned long rx_packets = 0, rx_bytes = 0, rx_dropped = 0;
+       unsigned long tx_packets = 0, tx_bytes = 0;
+       int i = 0;
+
+       for (i = 0; i < priv->num_rx_queues; i++) {
+               rx_packets += priv->rx_queue[i]->stats.rx_packets;
+               rx_bytes += priv->rx_queue[i]->stats.rx_bytes;
+               rx_dropped += priv->rx_queue[i]->stats.rx_dropped;
+       }
+
+       dev->stats.rx_packets = rx_packets;
+       dev->stats.rx_bytes = rx_bytes;
+       dev->stats.rx_dropped = rx_dropped;
+
+       for (i = 0; i < priv->num_tx_queues; i++) {
+               txq = netdev_get_tx_queue(dev, i);
+               tx_bytes += txq->tx_bytes;
+               tx_packets += txq->tx_packets;
+       }
+
+       dev->stats.tx_bytes = tx_bytes;
+       dev->stats.tx_packets = tx_packets;
+
+       return &dev->stats;
+}
+
 static const struct net_device_ops gfar_netdev_ops = {
        .ndo_open = gfar_enet_open,
        .ndo_start_xmit = gfar_start_xmit,
@@ -423,6 +456,7 @@ static const struct net_device_ops gfar_netdev_ops = {
        .ndo_tx_timeout = gfar_timeout,
        .ndo_do_ioctl = gfar_ioctl,
        .ndo_select_queue = gfar_select_queue,
+       .ndo_get_stats = gfar_get_stats,
        .ndo_vlan_rx_register = gfar_vlan_rx_register,
        .ndo_set_mac_address = eth_mac_addr,
        .ndo_validate_addr = eth_validate_addr,
@@ -1022,6 +1056,9 @@ static int gfar_probe(struct of_device *ofdev,
                priv->rx_queue[i]->rxic = DEFAULT_RXIC;
        }
 
+       /* enable filer if using multiple RX queues*/
+       if(priv->num_rx_queues > 1)
+               priv->rx_filer_enable = 1;
        /* Enable most messages by default */
        priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
 
@@ -1937,7 +1974,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        /* Update transmit stats */
-       dev->stats.tx_bytes += skb->len;
+       txq->tx_bytes += skb->len;
+       txq->tx_packets ++;
 
        txbdp = txbdp_start = tx_queue->cur_tx;
 
@@ -2295,8 +2333,6 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
        tx_queue->skb_dirtytx = skb_dirtytx;
        tx_queue->dirty_tx = bdp;
 
-       dev->stats.tx_packets += howmany;
-
        return howmany;
 }
 
@@ -2510,14 +2546,14 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)
                        }
                } else {
                        /* Increment the number of packets */
-                       dev->stats.rx_packets++;
+                       rx_queue->stats.rx_packets++;
                        howmany++;
 
                        if (likely(skb)) {
                                pkt_len = bdp->length - ETH_FCS_LEN;
                                /* Remove the FCS from the packet length */
                                skb_put(skb, pkt_len);
-                               dev->stats.rx_bytes += pkt_len;
+                               rx_queue->stats.rx_bytes += pkt_len;
 
                                gfar_process_frame(dev, skb, amount_pull);
 
@@ -2525,7 +2561,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)
                                if (netif_msg_rx_err(priv))
                                        printk(KERN_WARNING
                                               "%s: Missing skb!\n", dev->name);
-                               dev->stats.rx_dropped++;
+                               rx_queue->stats.rx_dropped++;
                                priv->extra_stats.rx_skbmissing++;
                        }
 
index cbb4510..3d72dc4 100644 (file)
@@ -333,7 +333,7 @@ extern const char gfar_driver_version[];
 #define IMASK_BSY               0x20000000
 #define IMASK_EBERR             0x10000000
 #define IMASK_MSRO             0x04000000
-#define IMASK_GRSC              0x02000000
+#define IMASK_GTSC              0x02000000
 #define IMASK_BABT             0x01000000
 #define IMASK_TXC               0x00800000
 #define IMASK_TXEEN            0x00400000
@@ -344,7 +344,7 @@ extern const char gfar_driver_version[];
 #define IMASK_XFUN             0x00010000
 #define IMASK_RXB0              0x00008000
 #define IMASK_MAG              0x00000800
-#define IMASK_GTSC              0x00000100
+#define IMASK_GRSC              0x00000100
 #define IMASK_RXFEN0           0x00000080
 #define IMASK_FIR              0x00000008
 #define IMASK_FIQ              0x00000004
@@ -401,6 +401,10 @@ extern const char gfar_driver_version[];
 #define FPR_FILER_MASK 0xFFFFFFFF
 #define MAX_FILER_IDX  0xFF
 
+/* This default RIR value directly corresponds
+ * to the 3-bit hash value generated */
+#define DEFAULT_RIR0   0x05397700
+
 /* RQFCR register bits */
 #define RQFCR_GPI              0x80000000
 #define RQFCR_HASHTBL_Q                0x00000000
@@ -936,6 +940,15 @@ struct gfar_priv_tx_q {
        unsigned short txtime;
 };
 
+/*
+ * Per RX queue stats
+ */
+struct rx_q_stats {
+       unsigned long rx_packets;
+       unsigned long rx_bytes;
+       unsigned long rx_dropped;
+};
+
 /**
  *     struct gfar_priv_rx_q - per rx queue structure
  *     @rxlock: per queue rx spin lock
@@ -958,6 +971,7 @@ struct gfar_priv_rx_q {
        struct  rxbd8 *cur_rx;
        struct  net_device *dev;
        struct gfar_priv_grp *grp;
+       struct rx_q_stats stats;
        u16     skb_currx;
        u16     qindex;
        unsigned int    rx_ring_size;
index f499684..6cae26a 100644 (file)
@@ -57,7 +57,9 @@ static int use_msi = 1;
 
 static int use_msi_x = 1;
 
-static unsigned long auto_fw_reset = AUTO_FW_RESET_ENABLED;
+static int auto_fw_reset = AUTO_FW_RESET_ENABLED;
+module_param(auto_fw_reset, int, 0644);
+MODULE_PARM_DESC(auto_fw_reset,"Auto firmware reset (0=disabled, 1=enabled");
 
 static int __devinit netxen_nic_probe(struct pci_dev *pdev,
                const struct pci_device_id *ent);
@@ -2534,42 +2536,6 @@ static struct bin_attribute bin_attr_mem = {
        .write = netxen_sysfs_write_mem,
 };
 
-#ifdef CONFIG_MODULES
-static ssize_t
-netxen_store_auto_fw_reset(struct module_attribute *mattr,
-               struct module *mod, const char *buf, size_t count)
-
-{
-       unsigned long new;
-
-       if (strict_strtoul(buf, 16, &new))
-               return -EINVAL;
-
-       if ((new == AUTO_FW_RESET_ENABLED) || (new == AUTO_FW_RESET_DISABLED)) {
-               auto_fw_reset = new;
-               return count;
-       }
-
-       return -EINVAL;
-}
-
-static ssize_t
-netxen_show_auto_fw_reset(struct module_attribute *mattr,
-               struct module *mod, char *buf)
-
-{
-       if (auto_fw_reset == AUTO_FW_RESET_ENABLED)
-               return sprintf(buf, "enabled\n");
-       else
-               return sprintf(buf, "disabled\n");
-}
-
-static struct module_attribute mod_attr_fw_reset = {
-       .attr = {.name = "auto_fw_reset", .mode = (S_IRUGO | S_IWUSR)},
-       .show = netxen_show_auto_fw_reset,
-       .store = netxen_store_auto_fw_reset,
-};
-#endif
 
 static void
 netxen_create_sysfs_entries(struct netxen_adapter *adapter)
@@ -2775,23 +2741,12 @@ static struct pci_driver netxen_driver = {
 
 static int __init netxen_init_module(void)
 {
-#ifdef CONFIG_MODULES
-       struct module *mod = THIS_MODULE;
-#endif
-
        printk(KERN_INFO "%s\n", netxen_nic_driver_string);
 
 #ifdef CONFIG_INET
        register_netdevice_notifier(&netxen_netdev_cb);
        register_inetaddr_notifier(&netxen_inetaddr_cb);
 #endif
-
-#ifdef CONFIG_MODULES
-       if (sysfs_create_file(&mod->mkobj.kobj, &mod_attr_fw_reset.attr))
-               printk(KERN_ERR "%s: Failed to create auto_fw_reset "
-                               "sysfs entry.", netxen_nic_driver_name);
-#endif
-
        return pci_register_driver(&netxen_driver);
 }
 
@@ -2799,12 +2754,6 @@ module_init(netxen_init_module);
 
 static void __exit netxen_exit_module(void)
 {
-#ifdef CONFIG_MODULES
-       struct module *mod = THIS_MODULE;
-
-       sysfs_remove_file(&mod->mkobj.kobj, &mod_attr_fw_reset.attr);
-#endif
-
        pci_unregister_driver(&netxen_driver);
 
 #ifdef CONFIG_INET
index f63c96a..c13cf64 100644 (file)
@@ -326,7 +326,8 @@ error:
 
 static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev)
 {
-       u32 val, orig;
+       u32 orig;
+       int val;
        bool clk125en = true;
 
        /* Abort if we are using an untested phy. */
index b9b371b..42611be 100644 (file)
@@ -1365,7 +1365,7 @@ static void lbs_send_confirmsleep(struct lbs_private *priv)
        priv->dnld_sent = DNLD_RES_RECEIVED;
 
        /* If nothing to do, go back to sleep (?) */
-       if (!__kfifo_len(priv->event_fifo) && !priv->resp_len[priv->resp_idx])
+       if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx])
                priv->psstate = PS_STATE_SLEEP;
 
        spin_unlock_irqrestore(&priv->driver_lock, flags);
@@ -1439,7 +1439,7 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv)
        }
 
        /* Pending events or command responses? */
-       if (__kfifo_len(priv->event_fifo) || priv->resp_len[priv->resp_idx]) {
+       if (kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) {
                allowed = 0;
                lbs_deb_host("pending events or command responses\n");
        }
index 6a8d2b2..05bb298 100644 (file)
@@ -10,7 +10,7 @@
 #include "scan.h"
 #include "assoc.h"
 
-
+#include <linux/kfifo.h>
 
 /** sleep_params */
 struct sleep_params {
@@ -120,7 +120,7 @@ struct lbs_private {
        u32 resp_len[2];
 
        /* Events sent from hardware to driver */
-       struct kfifo *event_fifo;
+       struct kfifo event_fifo;
 
        /** thread to service interrupts */
        struct task_struct *main_thread;
index db38a5a..c2975c8 100644 (file)
@@ -459,7 +459,7 @@ static int lbs_thread(void *data)
                else if (!list_empty(&priv->cmdpendingq) &&
                                        !(priv->wakeup_dev_required))
                        shouldsleep = 0;        /* We have a command to send */
-               else if (__kfifo_len(priv->event_fifo))
+               else if (kfifo_len(&priv->event_fifo))
                        shouldsleep = 0;        /* We have an event to process */
                else
                        shouldsleep = 1;        /* No command */
@@ -511,10 +511,13 @@ static int lbs_thread(void *data)
 
                /* Process hardware events, e.g. card removed, link lost */
                spin_lock_irq(&priv->driver_lock);
-               while (__kfifo_len(priv->event_fifo)) {
+               while (kfifo_len(&priv->event_fifo)) {
                        u32 event;
-                       __kfifo_get(priv->event_fifo, (unsigned char *) &event,
-                               sizeof(event));
+
+                       if (kfifo_out(&priv->event_fifo,
+                               (unsigned char *) &event, sizeof(event)) !=
+                               sizeof(event))
+                                       break;
                        spin_unlock_irq(&priv->driver_lock);
                        lbs_process_event(priv, event);
                        spin_lock_irq(&priv->driver_lock);
@@ -883,10 +886,9 @@ static int lbs_init_adapter(struct lbs_private *priv)
        priv->resp_len[0] = priv->resp_len[1] = 0;
 
        /* Create the event FIFO */
-       priv->event_fifo = kfifo_alloc(sizeof(u32) * 16, GFP_KERNEL, NULL);
-       if (IS_ERR(priv->event_fifo)) {
+       ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
+       if (ret) {
                lbs_pr_err("Out of memory allocating event FIFO buffer\n");
-               ret = -ENOMEM;
                goto out;
        }
 
@@ -901,8 +903,7 @@ static void lbs_free_adapter(struct lbs_private *priv)
        lbs_deb_enter(LBS_DEB_MAIN);
 
        lbs_free_cmd_buffer(priv);
-       if (priv->event_fifo)
-               kfifo_free(priv->event_fifo);
+       kfifo_free(&priv->event_fifo);
        del_timer(&priv->command_timer);
        del_timer(&priv->auto_deepsleep_timer);
        kfree(priv->networks);
@@ -1177,7 +1178,7 @@ void lbs_queue_event(struct lbs_private *priv, u32 event)
        if (priv->psstate == PS_STATE_SLEEP)
                priv->psstate = PS_STATE_AWAKE;
 
-       __kfifo_put(priv->event_fifo, (unsigned char *) &event, sizeof(u32));
+       kfifo_in(&priv->event_fifo, (unsigned char *) &event, sizeof(u32));
 
        wake_up_interruptible(&priv->waitq);
 
index bcd4ba8..b66029b 100644 (file)
@@ -164,7 +164,7 @@ struct fujitsu_hotkey_t {
        struct input_dev *input;
        char phys[32];
        struct platform_device *pf_device;
-       struct kfifo *fifo;
+       struct kfifo fifo;
        spinlock_t fifo_lock;
        int rfkill_supported;
        int rfkill_state;
@@ -824,12 +824,10 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
 
        /* kfifo */
        spin_lock_init(&fujitsu_hotkey->fifo_lock);
-       fujitsu_hotkey->fifo =
-           kfifo_alloc(RINGBUFFERSIZE * sizeof(int), GFP_KERNEL,
-                       &fujitsu_hotkey->fifo_lock);
-       if (IS_ERR(fujitsu_hotkey->fifo)) {
+       error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int),
+                       GFP_KERNEL);
+       if (error) {
                printk(KERN_ERR "kfifo_alloc failed\n");
-               error = PTR_ERR(fujitsu_hotkey->fifo);
                goto err_stop;
        }
 
@@ -934,7 +932,7 @@ err_unregister_input_dev:
 err_free_input_dev:
        input_free_device(input);
 err_free_fifo:
-       kfifo_free(fujitsu_hotkey->fifo);
+       kfifo_free(&fujitsu_hotkey->fifo);
 err_stop:
        return result;
 }
@@ -956,7 +954,7 @@ static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)
 
        input_free_device(input);
 
-       kfifo_free(fujitsu_hotkey->fifo);
+       kfifo_free(&fujitsu_hotkey->fifo);
 
        fujitsu_hotkey->acpi_handle = NULL;
 
@@ -1008,9 +1006,10 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event)
                                vdbg_printk(FUJLAPTOP_DBG_TRACE,
                                        "Push keycode into ringbuffer [%d]\n",
                                        keycode);
-                               status = kfifo_put(fujitsu_hotkey->fifo,
+                               status = kfifo_in_locked(&fujitsu_hotkey->fifo,
                                                   (unsigned char *)&keycode,
-                                                  sizeof(keycode));
+                                                  sizeof(keycode),
+                                                  &fujitsu_hotkey->fifo_lock);
                                if (status != sizeof(keycode)) {
                                        vdbg_printk(FUJLAPTOP_DBG_WARN,
                                            "Could not push keycode [0x%x]\n",
@@ -1021,11 +1020,12 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event)
                                }
                        } else if (keycode == 0) {
                                while ((status =
-                                       kfifo_get
-                                       (fujitsu_hotkey->fifo, (unsigned char *)
-                                        &keycode_r,
-                                        sizeof
-                                        (keycode_r))) == sizeof(keycode_r)) {
+                                       kfifo_out_locked(
+                                        &fujitsu_hotkey->fifo,
+                                        (unsigned char *) &keycode_r,
+                                        sizeof(keycode_r),
+                                        &fujitsu_hotkey->fifo_lock))
+                                        == sizeof(keycode_r)) {
                                        input_report_key(input, keycode_r, 0);
                                        input_sync(input);
                                        vdbg_printk(FUJLAPTOP_DBG_TRACE,
index 7a2cc8a..2896ca4 100644 (file)
@@ -142,7 +142,7 @@ struct sony_laptop_input_s {
        atomic_t                users;
        struct input_dev        *jog_dev;
        struct input_dev        *key_dev;
-       struct kfifo            *fifo;
+       struct kfifo            fifo;
        spinlock_t              fifo_lock;
        struct workqueue_struct *wq;
 };
@@ -300,8 +300,9 @@ static void do_sony_laptop_release_key(struct work_struct *work)
 {
        struct sony_laptop_keypress kp;
 
-       while (kfifo_get(sony_laptop_input.fifo, (unsigned char *)&kp,
-                        sizeof(kp)) == sizeof(kp)) {
+       while (kfifo_out_locked(&sony_laptop_input.fifo, (unsigned char *)&kp,
+                       sizeof(kp), &sony_laptop_input.fifo_lock)
+                       == sizeof(kp)) {
                msleep(10);
                input_report_key(kp.dev, kp.key, 0);
                input_sync(kp.dev);
@@ -362,8 +363,9 @@ static void sony_laptop_report_input_event(u8 event)
                /* we emit the scancode so we can always remap the key */
                input_event(kp.dev, EV_MSC, MSC_SCAN, event);
                input_sync(kp.dev);
-               kfifo_put(sony_laptop_input.fifo,
-                         (unsigned char *)&kp, sizeof(kp));
+               kfifo_in_locked(&sony_laptop_input.fifo,
+                         (unsigned char *)&kp, sizeof(kp),
+                         &sony_laptop_input.fifo_lock);
 
                if (!work_pending(&sony_laptop_release_key_work))
                        queue_work(sony_laptop_input.wq,
@@ -385,12 +387,10 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device)
 
        /* kfifo */
        spin_lock_init(&sony_laptop_input.fifo_lock);
-       sony_laptop_input.fifo =
-               kfifo_alloc(SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
-                           &sony_laptop_input.fifo_lock);
-       if (IS_ERR(sony_laptop_input.fifo)) {
+       error =
+        kfifo_alloc(&sony_laptop_input.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
+       if (error) {
                printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
-               error = PTR_ERR(sony_laptop_input.fifo);
                goto err_dec_users;
        }
 
@@ -474,7 +474,7 @@ err_destroy_wq:
        destroy_workqueue(sony_laptop_input.wq);
 
 err_free_kfifo:
-       kfifo_free(sony_laptop_input.fifo);
+       kfifo_free(&sony_laptop_input.fifo);
 
 err_dec_users:
        atomic_dec(&sony_laptop_input.users);
@@ -500,7 +500,7 @@ static void sony_laptop_remove_input(void)
        }
 
        destroy_workqueue(sony_laptop_input.wq);
-       kfifo_free(sony_laptop_input.fifo);
+       kfifo_free(&sony_laptop_input.fifo);
 }
 
 /*********** Platform Device ***********/
@@ -2079,7 +2079,7 @@ static struct attribute_group spic_attribute_group = {
 
 struct sonypi_compat_s {
        struct fasync_struct    *fifo_async;
-       struct kfifo            *fifo;
+       struct kfifo            fifo;
        spinlock_t              fifo_lock;
        wait_queue_head_t       fifo_proc_list;
        atomic_t                open_count;
@@ -2104,12 +2104,12 @@ static int sonypi_misc_open(struct inode *inode, struct file *file)
        /* Flush input queue on first open */
        unsigned long flags;
 
-       spin_lock_irqsave(sonypi_compat.fifo->lock, flags);
+       spin_lock_irqsave(&sonypi_compat.fifo_lock, flags);
 
        if (atomic_inc_return(&sonypi_compat.open_count) == 1)
-               __kfifo_reset(sonypi_compat.fifo);
+               kfifo_reset(&sonypi_compat.fifo);
 
-       spin_unlock_irqrestore(sonypi_compat.fifo->lock, flags);
+       spin_unlock_irqrestore(&sonypi_compat.fifo_lock, flags);
 
        return 0;
 }
@@ -2120,17 +2120,18 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf,
        ssize_t ret;
        unsigned char c;
 
-       if ((kfifo_len(sonypi_compat.fifo) == 0) &&
+       if ((kfifo_len(&sonypi_compat.fifo) == 0) &&
            (file->f_flags & O_NONBLOCK))
                return -EAGAIN;
 
        ret = wait_event_interruptible(sonypi_compat.fifo_proc_list,
-                                      kfifo_len(sonypi_compat.fifo) != 0);
+                                      kfifo_len(&sonypi_compat.fifo) != 0);
        if (ret)
                return ret;
 
        while (ret < count &&
-              (kfifo_get(sonypi_compat.fifo, &c, sizeof(c)) == sizeof(c))) {
+              (kfifo_out_locked(&sonypi_compat.fifo, &c, sizeof(c),
+                         &sonypi_compat.fifo_lock) == sizeof(c))) {
                if (put_user(c, buf++))
                        return -EFAULT;
                ret++;
@@ -2147,7 +2148,7 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf,
 static unsigned int sonypi_misc_poll(struct file *file, poll_table *wait)
 {
        poll_wait(file, &sonypi_compat.fifo_proc_list, wait);
-       if (kfifo_len(sonypi_compat.fifo))
+       if (kfifo_len(&sonypi_compat.fifo))
                return POLLIN | POLLRDNORM;
        return 0;
 }
@@ -2309,7 +2310,8 @@ static struct miscdevice sonypi_misc_device = {
 
 static void sonypi_compat_report_event(u8 event)
 {
-       kfifo_put(sonypi_compat.fifo, (unsigned char *)&event, sizeof(event));
+       kfifo_in_locked(&sonypi_compat.fifo, (unsigned char *)&event,
+                       sizeof(event), &sonypi_compat.fifo_lock);
        kill_fasync(&sonypi_compat.fifo_async, SIGIO, POLL_IN);
        wake_up_interruptible(&sonypi_compat.fifo_proc_list);
 }
@@ -2319,11 +2321,11 @@ static int sonypi_compat_init(void)
        int error;
 
        spin_lock_init(&sonypi_compat.fifo_lock);
-       sonypi_compat.fifo = kfifo_alloc(SONY_LAPTOP_BUF_SIZE, GFP_KERNEL,
-                                        &sonypi_compat.fifo_lock);
-       if (IS_ERR(sonypi_compat.fifo)) {
+       error =
+        kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
+       if (error) {
                printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
-               return PTR_ERR(sonypi_compat.fifo);
+               return error;
        }
 
        init_waitqueue_head(&sonypi_compat.fifo_proc_list);
@@ -2342,14 +2344,14 @@ static int sonypi_compat_init(void)
        return 0;
 
 err_free_kfifo:
-       kfifo_free(sonypi_compat.fifo);
+       kfifo_free(&sonypi_compat.fifo);
        return error;
 }
 
 static void sonypi_compat_exit(void)
 {
        misc_deregister(&sonypi_misc_device);
-       kfifo_free(sonypi_compat.fifo);
+       kfifo_free(&sonypi_compat.fifo);
 }
 #else
 static int sonypi_compat_init(void) { return 0; }
index fd12317..148b1dd 100644 (file)
@@ -218,7 +218,7 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device)
                spin_unlock_irqrestore(&aliastree.lock, flags);
                newlcu = _allocate_lcu(uid);
                if (IS_ERR(newlcu))
-                       return PTR_ERR(lcu);
+                       return PTR_ERR(newlcu);
                spin_lock_irqsave(&aliastree.lock, flags);
                lcu = _find_lcu(server, uid);
                if (!lcu) {
index f64d0db..6e14863 100644 (file)
@@ -8,7 +8,7 @@
  *
  */
 
-#define KMSG_COMPONENT "dasd-diag"
+#define KMSG_COMPONENT "dasd"
 
 #include <linux/stddef.h>
 #include <linux/kernel.h>
@@ -146,16 +146,16 @@ dasd_diag_erp(struct dasd_device *device)
        rc = mdsk_init_io(device, device->block->bp_block, 0, NULL);
        if (rc == 4) {
                if (!(device->features & DASD_FEATURE_READONLY)) {
-                       dev_warn(&device->cdev->dev,
-                                "The access mode of a DIAG device changed"
-                                " to read-only");
+                       pr_warning("%s: The access mode of a DIAG device "
+                                  "changed to read-only\n",
+                                  dev_name(&device->cdev->dev));
                        device->features |= DASD_FEATURE_READONLY;
                }
                rc = 0;
        }
        if (rc)
-               dev_warn(&device->cdev->dev, "DIAG ERP failed with "
-                           "rc=%d\n", rc);
+               pr_warning("%s: DIAG ERP failed with "
+                           "rc=%d\n", dev_name(&device->cdev->dev), rc);
 }
 
 /* Start a given request at the device. Return zero on success, non-zero
@@ -371,8 +371,9 @@ dasd_diag_check_device(struct dasd_device *device)
                private->pt_block = 2;
                break;
        default:
-               dev_warn(&device->cdev->dev, "Device type %d is not supported "
-                           "in DIAG mode\n", private->rdc_data.vdev_class);
+               pr_warning("%s: Device type %d is not supported "
+                          "in DIAG mode\n", dev_name(&device->cdev->dev),
+                          private->rdc_data.vdev_class);
                rc = -EOPNOTSUPP;
                goto out;
        }
@@ -413,8 +414,8 @@ dasd_diag_check_device(struct dasd_device *device)
                private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
                rc = dia250(&private->iob, RW_BIO);
                if (rc == 3) {
-                       dev_warn(&device->cdev->dev,
-                               "A 64-bit DIAG call failed\n");
+                       pr_warning("%s: A 64-bit DIAG call failed\n",
+                                  dev_name(&device->cdev->dev));
                        rc = -EOPNOTSUPP;
                        goto out_label;
                }
@@ -423,8 +424,9 @@ dasd_diag_check_device(struct dasd_device *device)
                        break;
        }
        if (bsize > PAGE_SIZE) {
-               dev_warn(&device->cdev->dev, "Accessing the DASD failed because"
-                        " of an incorrect format (rc=%d)\n", rc);
+               pr_warning("%s: Accessing the DASD failed because of an "
+                          "incorrect format (rc=%d)\n",
+                          dev_name(&device->cdev->dev), rc);
                rc = -EIO;
                goto out_label;
        }
@@ -442,18 +444,18 @@ dasd_diag_check_device(struct dasd_device *device)
                block->s2b_shift++;
        rc = mdsk_init_io(device, block->bp_block, 0, NULL);
        if (rc && (rc != 4)) {
-               dev_warn(&device->cdev->dev, "DIAG initialization "
-                       "failed with rc=%d\n", rc);
+               pr_warning("%s: DIAG initialization failed with rc=%d\n",
+                          dev_name(&device->cdev->dev), rc);
                rc = -EIO;
        } else {
                if (rc == 4)
                        device->features |= DASD_FEATURE_READONLY;
-               dev_info(&device->cdev->dev,
-                        "New DASD with %ld byte/block, total size %ld KB%s\n",
-                        (unsigned long) block->bp_block,
-                        (unsigned long) (block->blocks <<
-                                         block->s2b_shift) >> 1,
-                        (rc == 4) ? ", read-only device" : "");
+               pr_info("%s: New DASD with %ld byte/block, total size %ld "
+                       "KB%s\n", dev_name(&device->cdev->dev),
+                       (unsigned long) block->bp_block,
+                       (unsigned long) (block->blocks <<
+                                        block->s2b_shift) >> 1,
+                       (rc == 4) ? ", read-only device" : "");
                rc = 0;
        }
 out_label:
index 28e4649..247b2b9 100644 (file)
@@ -467,7 +467,7 @@ fs3270_open(struct inode *inode, struct file *filp)
        if (IS_ERR(ib)) {
                raw3270_put_view(&fp->view);
                raw3270_del_view(&fp->view);
-               rc = PTR_ERR(fp);
+               rc = PTR_ERR(ib);
                goto out;
        }
        fp->rdbuf = ib;
index 3657fe1..cb70fa1 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #define KMSG_COMPONENT "tape_34xx"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/module.h>
 #include <linux/init.h>
index 0c72aad..9821c58 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #define KMSG_COMPONENT "tape_3590"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -136,7 +137,7 @@ static void int_to_ext_kekl(struct tape3592_kekl *in,
                out->type_on_tape = TAPE390_KEKL_TYPE_LABEL;
        memcpy(out->label, in->label, sizeof(in->label));
        EBCASC(out->label, sizeof(in->label));
-       strstrip(out->label);
+       strim(out->label);
 }
 
 static void int_to_ext_kekl_pair(struct tape3592_kekl_pair *in,
index 4799cc2..9681614 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #define KMSG_COMPONENT "tape"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
 #include <linux/fs.h>
 #include <linux/module.h>
index 23d773a..2125ec7 100644 (file)
@@ -10,6 +10,9 @@
  *              Martin Schwidefsky <schwidefsky@de.ibm.com>
  */
 
+#define KMSG_COMPONENT "tape"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/proc_fs.h>
index ddc914c..b2864e3 100644 (file)
@@ -7,6 +7,10 @@
  * Author: Stefan Bader <shbader@de.ibm.com>
  * Based on simple class device code by Greg K-H
  */
+
+#define KMSG_COMPONENT "tape"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include "tape_class.h"
 
 MODULE_AUTHOR("Stefan Bader <shbader@de.ibm.com>");
index f5d6802..81b094e 100644 (file)
@@ -12,6 +12,8 @@
  */
 
 #define KMSG_COMPONENT "tape"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/init.h>             // for kernel parameters
 #include <linux/kmod.h>             // for requesting modules
index ebd820c..0ceb379 100644 (file)
@@ -11,6 +11,9 @@
  * PROCFS Functions
  */
 
+#define KMSG_COMPONENT "tape"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/seq_file.h>
index 750354a..03f07e5 100644 (file)
@@ -11,6 +11,9 @@
  *              Stefan Bader <shbader@de.ibm.com>
  */
 
+#define KMSG_COMPONENT "tape"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/bio.h>
index 9509e38..7a28a30 100644 (file)
@@ -49,7 +49,6 @@ static u16 ccwreq_next_path(struct ccw_device *cdev)
  */
 static void ccwreq_stop(struct ccw_device *cdev, int rc)
 {
-       struct subchannel *sch = to_subchannel(cdev->dev.parent);
        struct ccw_request *req = &cdev->private->req;
 
        if (req->done)
@@ -57,7 +56,6 @@ static void ccwreq_stop(struct ccw_device *cdev, int rc)
        req->done = 1;
        ccw_device_set_timeout(cdev, 0);
        memset(&cdev->private->irb, 0, sizeof(struct irb));
-       sch->lpm = sch->schib.pmcw.pam;
        if (rc && rc != -ENODEV && req->drc)
                rc = req->drc;
        req->callback(cdev, req->data, rc);
@@ -80,7 +78,6 @@ static void ccwreq_do(struct ccw_device *cdev)
                        continue;
                }
                /* Perform start function. */
-               sch->lpm = 0xff;
                memset(&cdev->private->irb, 0, sizeof(struct irb));
                rc = cio_start(sch, cp, (u8) req->mask);
                if (rc == 0) {
index 73901c9..a6c7d54 100644 (file)
@@ -1519,6 +1519,7 @@ static int ccw_device_console_enable(struct ccw_device *cdev,
        sch->driver = &io_subchannel_driver;
        /* Initialize the ccw_device structure. */
        cdev->dev.parent= &sch->dev;
+       sch_set_cdev(sch, cdev);
        io_subchannel_recog(cdev, sch);
        /* Now wait for the async. recognition to come to an end. */
        spin_lock_irq(cdev->ccwlock);
index aad188e..6facb54 100644 (file)
@@ -142,7 +142,7 @@ static void spid_do(struct ccw_device *cdev)
        u8 fn;
 
        /* Use next available path that is not already in correct state. */
-       req->lpm = lpm_adjust(req->lpm, sch->schib.pmcw.pam & ~sch->vpm);
+       req->lpm = lpm_adjust(req->lpm, cdev->private->pgid_todo_mask);
        if (!req->lpm)
                goto out_nopath;
        /* Channel program setup. */
@@ -254,15 +254,15 @@ static void pgid_analyze(struct ccw_device *cdev, struct pgid **p,
        *p = first;
 }
 
-static u8 pgid_to_vpm(struct ccw_device *cdev)
+static u8 pgid_to_donepm(struct ccw_device *cdev)
 {
        struct subchannel *sch = to_subchannel(cdev->dev.parent);
        struct pgid *pgid;
        int i;
        int lpm;
-       u8 vpm = 0;
+       u8 donepm = 0;
 
-       /* Set VPM bits for paths which are already in the target state. */
+       /* Set bits for paths which are already in the target state. */
        for (i = 0; i < 8; i++) {
                lpm = 0x80 >> i;
                if ((cdev->private->pgid_valid_mask & lpm) == 0)
@@ -282,10 +282,10 @@ static u8 pgid_to_vpm(struct ccw_device *cdev)
                        if (pgid->inf.ps.state3 != SNID_STATE3_SINGLE_PATH)
                                continue;
                }
-               vpm |= lpm;
+               donepm |= lpm;
        }
 
-       return vpm;
+       return donepm;
 }
 
 static void pgid_fill(struct ccw_device *cdev, struct pgid *pgid)
@@ -307,6 +307,7 @@ static void snid_done(struct ccw_device *cdev, int rc)
        int mismatch = 0;
        int reserved = 0;
        int reset = 0;
+       u8 donepm;
 
        if (rc)
                goto out;
@@ -316,18 +317,20 @@ static void snid_done(struct ccw_device *cdev, int rc)
        else if (mismatch)
                rc = -EOPNOTSUPP;
        else {
-               sch->vpm = pgid_to_vpm(cdev);
+               donepm = pgid_to_donepm(cdev);
+               sch->vpm = donepm & sch->opm;
+               cdev->private->pgid_todo_mask &= ~donepm;
                pgid_fill(cdev, pgid);
        }
 out:
        CIO_MSG_EVENT(2, "snid: device 0.%x.%04x: rc=%d pvm=%02x vpm=%02x "
-                     "mism=%d rsvd=%d reset=%d\n", id->ssid, id->devno, rc,
-                     cdev->private->pgid_valid_mask, sch->vpm, mismatch,
-                     reserved, reset);
+                     "todo=%02x mism=%d rsvd=%d reset=%d\n", id->ssid,
+                     id->devno, rc, cdev->private->pgid_valid_mask, sch->vpm,
+                     cdev->private->pgid_todo_mask, mismatch, reserved, reset);
        switch (rc) {
        case 0:
                /* Anything left to do? */
-               if (sch->vpm == sch->schib.pmcw.pam) {
+               if (cdev->private->pgid_todo_mask == 0) {
                        verify_done(cdev, sch->vpm == 0 ? -EACCES : 0);
                        return;
                }
@@ -411,6 +414,7 @@ static void verify_start(struct ccw_device *cdev)
        struct ccw_dev_id *devid = &cdev->private->dev_id;
 
        sch->vpm = 0;
+       sch->lpm = sch->schib.pmcw.pam;
        /* Initialize request data. */
        memset(req, 0, sizeof(*req));
        req->timeout    = PGID_TIMEOUT;
@@ -442,11 +446,14 @@ static void verify_start(struct ccw_device *cdev)
  */
 void ccw_device_verify_start(struct ccw_device *cdev)
 {
+       struct subchannel *sch = to_subchannel(cdev->dev.parent);
+
        CIO_TRACE_EVENT(4, "vrfy");
        CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id));
        /* Initialize PGID data. */
        memset(cdev->private->pgid, 0, sizeof(cdev->private->pgid));
        cdev->private->pgid_valid_mask = 0;
+       cdev->private->pgid_todo_mask = sch->schib.pmcw.pam;
        /*
         * Initialize pathgroup and multipath state with target values.
         * They may change in the course of path verification.
index 61677df..ca5e9bb 100644 (file)
@@ -163,7 +163,7 @@ void tcw_finalize(struct tcw *tcw, int num_tidaws)
        /* Add tcat to tccb. */
        tccb = tcw_get_tccb(tcw);
        tcat = (struct tccb_tcat *) &tccb->tca[tca_size(tccb)];
-       memset(tcat, 0, sizeof(tcat));
+       memset(tcat, 0, sizeof(*tcat));
        /* Calculate tcw input/output count and tcat transport count. */
        count = calc_dcw_count(tccb);
        if (tcw->w && (tcw->flags & TCW_FLAGS_OUTPUT_TIDA))
@@ -269,7 +269,7 @@ EXPORT_SYMBOL(tccb_init);
  */
 void tsb_init(struct tsb *tsb)
 {
-       memset(tsb, 0, sizeof(tsb));
+       memset(tsb, 0, sizeof(*tsb));
 }
 EXPORT_SYMBOL(tsb_init);
 
index d72ae4c..b9ce712 100644 (file)
@@ -150,6 +150,7 @@ struct ccw_device_private {
        struct ccw_request req;         /* internal I/O request */
        int iretry;
        u8 pgid_valid_mask;             /* mask of valid PGIDs */
+       u8 pgid_todo_mask;              /* mask of PGIDs to be adjusted */
        struct {
                unsigned int fast:1;    /* post with "channel end" */
                unsigned int repall:1;  /* report every interrupt status */
index 4be6e84..b2275c5 100644 (file)
@@ -486,7 +486,8 @@ static int get_inbound_buffer_frontier(struct qdio_q *q)
        case SLSB_P_INPUT_PRIMED:
                inbound_primed(q, count);
                q->first_to_check = add_buf(q->first_to_check, count);
-               atomic_sub(count, &q->nr_buf_used);
+               if (atomic_sub(count, &q->nr_buf_used) == 0)
+                       qdio_perf_stat_inc(&perf_stats.inbound_queue_full);
                break;
        case SLSB_P_INPUT_ERROR:
                announce_buffer_error(q, count);
index 968e3c7..54f7c32 100644 (file)
@@ -64,6 +64,8 @@ static int qdio_perf_proc_show(struct seq_file *m, void *v)
                   (long)atomic_long_read(&perf_stats.fast_requeue));
        seq_printf(m, "Number of outbound target full condition\t: %li\n",
                   (long)atomic_long_read(&perf_stats.outbound_target_full));
+       seq_printf(m, "Number of inbound queue full condition\t\t: %li\n",
+                  (long)atomic_long_read(&perf_stats.inbound_queue_full));
        seq_printf(m, "Number of outbound tasklet mod_timer calls\t: %li\n",
                   (long)atomic_long_read(&perf_stats.debug_tl_out_timer));
        seq_printf(m, "Number of stop polling calls\t\t\t: %li\n",
index ff4504c..1245423 100644 (file)
@@ -36,6 +36,7 @@ struct qdio_perf_stats {
        atomic_long_t outbound_handler;
        atomic_long_t fast_requeue;
        atomic_long_t outbound_target_full;
+       atomic_long_t inbound_queue_full;
 
        /* for debugging */
        atomic_long_t debug_tl_out_timer;
index 18d54fc..8c2dea5 100644 (file)
@@ -48,7 +48,6 @@ static void set_impl_params(struct qdio_irq *irq_ptr,
        if (!irq_ptr)
                return;
 
-       WARN_ON((unsigned long)&irq_ptr->qib & 0xff);
        irq_ptr->qib.pfmt = qib_param_field_format;
        if (qib_param_field)
                memcpy(irq_ptr->qib.parm, qib_param_field,
@@ -82,14 +81,12 @@ static int __qdio_allocate_qs(struct qdio_q **irq_ptr_qs, int nr_queues)
                q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL);
                if (!q)
                        return -ENOMEM;
-               WARN_ON((unsigned long)q & 0xff);
 
                q->slib = (struct slib *) __get_free_page(GFP_KERNEL);
                if (!q->slib) {
                        kmem_cache_free(qdio_q_cache, q);
                        return -ENOMEM;
                }
-               WARN_ON((unsigned long)q->slib & 0x7ff);
                irq_ptr_qs[i] = q;
        }
        return 0;
@@ -131,7 +128,7 @@ static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr,
        /* fill in sbal */
        for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) {
                q->sbal[j] = *sbals_array++;
-               WARN_ON((unsigned long)q->sbal[j] & 0xff);
+               BUG_ON((unsigned long)q->sbal[j] & 0xff);
        }
 
        /* fill in slib */
@@ -147,11 +144,6 @@ static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr,
        /* fill in sl */
        for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++)
                q->sl->element[j].sbal = (unsigned long)q->sbal[j];
-
-       DBF_EVENT("sl-slsb-sbal");
-       DBF_HEX(q->sl, sizeof(void *));
-       DBF_HEX(&q->slsb, sizeof(void *));
-       DBF_HEX(q->sbal, sizeof(void *));
 }
 
 static void setup_queues(struct qdio_irq *irq_ptr,
index b7689f3..c28a712 100644 (file)
@@ -517,7 +517,7 @@ static void iscsi_free_task(struct iscsi_task *task)
        if (conn->login_task == task)
                return;
 
-       __kfifo_put(session->cmdpool.queue, (void*)&task, sizeof(void*));
+       kfifo_in(&session->cmdpool.queue, (void*)&task, sizeof(void*));
 
        if (sc) {
                task->sc = NULL;
@@ -737,7 +737,7 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
                BUG_ON(conn->c_stage == ISCSI_CONN_INITIAL_STAGE);
                BUG_ON(conn->c_stage == ISCSI_CONN_STOPPED);
 
-               if (!__kfifo_get(session->cmdpool.queue,
+               if (!kfifo_out(&session->cmdpool.queue,
                                 (void*)&task, sizeof(void*)))
                        return NULL;
        }
@@ -1567,7 +1567,7 @@ static inline struct iscsi_task *iscsi_alloc_task(struct iscsi_conn *conn,
 {
        struct iscsi_task *task;
 
-       if (!__kfifo_get(conn->session->cmdpool.queue,
+       if (!kfifo_out(&conn->session->cmdpool.queue,
                         (void *) &task, sizeof(void *)))
                return NULL;
 
@@ -2461,12 +2461,7 @@ iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size)
        if (q->pool == NULL)
                return -ENOMEM;
 
-       q->queue = kfifo_init((void*)q->pool, max * sizeof(void*),
-                             GFP_KERNEL, NULL);
-       if (IS_ERR(q->queue)) {
-               q->queue = NULL;
-               goto enomem;
-       }
+       kfifo_init(&q->queue, (void*)q->pool, max * sizeof(void*));
 
        for (i = 0; i < max; i++) {
                q->pool[i] = kzalloc(item_size, GFP_KERNEL);
@@ -2474,7 +2469,7 @@ iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size)
                        q->max = i;
                        goto enomem;
                }
-               __kfifo_put(q->queue, (void*)&q->pool[i], sizeof(void*));
+               kfifo_in(&q->queue, (void*)&q->pool[i], sizeof(void*));
        }
 
        if (items) {
@@ -2497,7 +2492,6 @@ void iscsi_pool_free(struct iscsi_pool *q)
        for (i = 0; i < q->max; i++)
                kfree(q->pool[i]);
        kfree(q->pool);
-       kfree(q->queue);
 }
 EXPORT_SYMBOL_GPL(iscsi_pool_free);
 
@@ -2825,7 +2819,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size,
 
        /* allocate login_task used for the login/text sequences */
        spin_lock_bh(&session->lock);
-       if (!__kfifo_get(session->cmdpool.queue,
+       if (!kfifo_out(&session->cmdpool.queue,
                          (void*)&conn->login_task,
                         sizeof(void*))) {
                spin_unlock_bh(&session->lock);
@@ -2845,7 +2839,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size,
        return cls_conn;
 
 login_task_data_alloc_fail:
-       __kfifo_put(session->cmdpool.queue, (void*)&conn->login_task,
+       kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task,
                    sizeof(void*));
 login_task_alloc_fail:
        iscsi_destroy_conn(cls_conn);
@@ -2908,7 +2902,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
        free_pages((unsigned long) conn->data,
                   get_order(ISCSI_DEF_MAX_RECV_SEG_LEN));
        kfree(conn->persistent_address);
-       __kfifo_put(session->cmdpool.queue, (void*)&conn->login_task,
+       kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task,
                    sizeof(void*));
        if (session->leadconn == conn)
                session->leadconn = NULL;
index ca25ee5..db6856c 100644 (file)
@@ -445,15 +445,15 @@ void iscsi_tcp_cleanup_task(struct iscsi_task *task)
                return;
 
        /* flush task's r2t queues */
-       while (__kfifo_get(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) {
-               __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
+       while (kfifo_out(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*))) {
+               kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
                            sizeof(void*));
                ISCSI_DBG_TCP(task->conn, "pending r2t dropped\n");
        }
 
        r2t = tcp_task->r2t;
        if (r2t != NULL) {
-               __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
+               kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
                            sizeof(void*));
                tcp_task->r2t = NULL;
        }
@@ -541,7 +541,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
                return 0;
        }
 
-       rc = __kfifo_get(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*));
+       rc = kfifo_out(&tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*));
        if (!rc) {
                iscsi_conn_printk(KERN_ERR, conn, "Could not allocate R2T. "
                                  "Target has sent more R2Ts than it "
@@ -554,7 +554,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
        if (r2t->data_length == 0) {
                iscsi_conn_printk(KERN_ERR, conn,
                                  "invalid R2T with zero data len\n");
-               __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
+               kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
                            sizeof(void*));
                return ISCSI_ERR_DATALEN;
        }
@@ -570,7 +570,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
                                  "invalid R2T with data len %u at offset %u "
                                  "and total length %d\n", r2t->data_length,
                                  r2t->data_offset, scsi_out(task->sc)->length);
-               __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
+               kfifo_in(&tcp_task->r2tpool.queue, (void*)&r2t,
                            sizeof(void*));
                return ISCSI_ERR_DATALEN;
        }
@@ -580,7 +580,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
        r2t->sent = 0;
 
        tcp_task->exp_datasn = r2tsn + 1;
-       __kfifo_put(tcp_task->r2tqueue, (void*)&r2t, sizeof(void*));
+       kfifo_in(&tcp_task->r2tqueue, (void*)&r2t, sizeof(void*));
        conn->r2t_pdus_cnt++;
 
        iscsi_requeue_task(task);
@@ -951,7 +951,7 @@ int iscsi_tcp_task_init(struct iscsi_task *task)
                return conn->session->tt->init_pdu(task, 0, task->data_count);
        }
 
-       BUG_ON(__kfifo_len(tcp_task->r2tqueue));
+       BUG_ON(kfifo_len(&tcp_task->r2tqueue));
        tcp_task->exp_datasn = 0;
 
        /* Prepare PDU, optionally w/ immediate data */
@@ -982,7 +982,7 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task)
                        if (r2t->data_length <= r2t->sent) {
                                ISCSI_DBG_TCP(task->conn,
                                              "  done with r2t %p\n", r2t);
-                               __kfifo_put(tcp_task->r2tpool.queue,
+                               kfifo_in(&tcp_task->r2tpool.queue,
                                            (void *)&tcp_task->r2t,
                                            sizeof(void *));
                                tcp_task->r2t = r2t = NULL;
@@ -990,8 +990,13 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task)
                }
 
                if (r2t == NULL) {
-                       __kfifo_get(tcp_task->r2tqueue,
-                                   (void *)&tcp_task->r2t, sizeof(void *));
+                       if (kfifo_out(&tcp_task->r2tqueue,
+                           (void *)&tcp_task->r2t, sizeof(void *)) !=
+                           sizeof(void *)) {
+                               WARN_ONCE(1, "unexpected fifo state");
+                               r2t = NULL;
+                       }
+
                        r2t = tcp_task->r2t;
                }
                spin_unlock_bh(&session->lock);
@@ -1127,9 +1132,8 @@ int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session)
                }
 
                /* R2T xmit queue */
-               tcp_task->r2tqueue = kfifo_alloc(
-                     session->max_r2t * 4 * sizeof(void*), GFP_KERNEL, NULL);
-               if (tcp_task->r2tqueue == ERR_PTR(-ENOMEM)) {
+               if (kfifo_alloc(&tcp_task->r2tqueue,
+                     session->max_r2t * 4 * sizeof(void*), GFP_KERNEL)) {
                        iscsi_pool_free(&tcp_task->r2tpool);
                        goto r2t_alloc_fail;
                }
@@ -1142,7 +1146,7 @@ r2t_alloc_fail:
                struct iscsi_task *task = session->cmds[i];
                struct iscsi_tcp_task *tcp_task = task->dd_data;
 
-               kfifo_free(tcp_task->r2tqueue);
+               kfifo_free(&tcp_task->r2tqueue);
                iscsi_pool_free(&tcp_task->r2tpool);
        }
        return -ENOMEM;
@@ -1157,7 +1161,7 @@ void iscsi_tcp_r2tpool_free(struct iscsi_session *session)
                struct iscsi_task *task = session->cmds[i];
                struct iscsi_tcp_task *tcp_task = task->dd_data;
 
-               kfifo_free(tcp_task->r2tqueue);
+               kfifo_free(&tcp_task->r2tqueue);
                iscsi_pool_free(&tcp_task->r2tpool);
        }
 }
index 9ad38e8..ab19b3b 100644 (file)
@@ -58,19 +58,15 @@ static int srp_iu_pool_alloc(struct srp_queue *q, size_t max,
                goto free_pool;
 
        spin_lock_init(&q->lock);
-       q->queue = kfifo_init((void *) q->pool, max * sizeof(void *),
-                             GFP_KERNEL, &q->lock);
-       if (IS_ERR(q->queue))
-               goto free_item;
+       kfifo_init(&q->queue, (void *) q->pool, max * sizeof(void *));
 
        for (i = 0, iue = q->items; i < max; i++) {
-               __kfifo_put(q->queue, (void *) &iue, sizeof(void *));
+               kfifo_in(&q->queue, (void *) &iue, sizeof(void *));
                iue->sbuf = ring[i];
                iue++;
        }
        return 0;
 
-free_item:
        kfree(q->items);
 free_pool:
        kfree(q->pool);
@@ -167,7 +163,11 @@ struct iu_entry *srp_iu_get(struct srp_target *target)
 {
        struct iu_entry *iue = NULL;
 
-       kfifo_get(target->iu_queue.queue, (void *) &iue, sizeof(void *));
+       if (kfifo_out_locked(&target->iu_queue.queue, (void *) &iue,
+               sizeof(void *), &target->iu_queue.lock) != sizeof(void *)) {
+                       WARN_ONCE(1, "unexpected fifo state");
+                       return NULL;
+       }
        if (!iue)
                return iue;
        iue->target = target;
@@ -179,7 +179,8 @@ EXPORT_SYMBOL_GPL(srp_iu_get);
 
 void srp_iu_put(struct iu_entry *iue)
 {
-       kfifo_put(iue->target->iu_queue.queue, (void *) &iue, sizeof(void *));
+       kfifo_in_locked(&iue->target->iu_queue.queue, (void *) &iue,
+                       sizeof(void *), &iue->target->iu_queue.lock);
 }
 EXPORT_SYMBOL_GPL(srp_iu_put);
 
index 00a2985..ff43747 100644 (file)
@@ -37,7 +37,7 @@ static void recycle_frame(struct fhci_usb *usb, struct packet *pkt)
        pkt->info = 0;
        pkt->priv_data = NULL;
 
-       cq_put(usb->ep0->empty_frame_Q, pkt);
+       cq_put(&usb->ep0->empty_frame_Q, pkt);
 }
 
 /* confirm submitted packet */
@@ -57,7 +57,7 @@ void fhci_transaction_confirm(struct fhci_usb *usb, struct packet *pkt)
                if ((td->data + td->actual_len) && trans_len)
                        memcpy(td->data + td->actual_len, pkt->data,
                               trans_len);
-               cq_put(usb->ep0->dummy_packets_Q, pkt->data);
+               cq_put(&usb->ep0->dummy_packets_Q, pkt->data);
        }
 
        recycle_frame(usb, pkt);
@@ -213,7 +213,7 @@ static int add_packet(struct fhci_usb *usb, struct ed *ed, struct td *td)
        }
 
        /* update frame object fields before transmitting */
-       pkt = cq_get(usb->ep0->empty_frame_Q);
+       pkt = cq_get(&usb->ep0->empty_frame_Q);
        if (!pkt) {
                fhci_dbg(usb->fhci, "there is no empty frame\n");
                return -1;
@@ -222,7 +222,7 @@ static int add_packet(struct fhci_usb *usb, struct ed *ed, struct td *td)
 
        pkt->info = 0;
        if (data == NULL) {
-               data = cq_get(usb->ep0->dummy_packets_Q);
+               data = cq_get(&usb->ep0->dummy_packets_Q);
                BUG_ON(!data);
                pkt->info = PKT_DUMMY_PACKET;
        }
@@ -246,7 +246,7 @@ static int add_packet(struct fhci_usb *usb, struct ed *ed, struct td *td)
                list_del_init(&td->frame_lh);
                td->status = USB_TD_OK;
                if (pkt->info & PKT_DUMMY_PACKET)
-                       cq_put(usb->ep0->dummy_packets_Q, pkt->data);
+                       cq_put(&usb->ep0->dummy_packets_Q, pkt->data);
                recycle_frame(usb, pkt);
                usb->actual_frame->total_bytes -= (len + PROTOCOL_OVERHEAD);
                fhci_err(usb->fhci, "host transaction failed\n");
index b403322..d224ab4 100644 (file)
@@ -106,33 +106,33 @@ void fhci_ep0_free(struct fhci_usb *usb)
                        cpm_muram_free(cpm_muram_offset(ep->td_base));
 
                if (ep->conf_frame_Q) {
-                       size = cq_howmany(ep->conf_frame_Q);
+                       size = cq_howmany(&ep->conf_frame_Q);
                        for (; size; size--) {
-                               struct packet *pkt = cq_get(ep->conf_frame_Q);
+                               struct packet *pkt = cq_get(&ep->conf_frame_Q);
 
                                kfree(pkt);
                        }
-                       cq_delete(ep->conf_frame_Q);
+                       cq_delete(&ep->conf_frame_Q);
                }
 
                if (ep->empty_frame_Q) {
-                       size = cq_howmany(ep->empty_frame_Q);
+                       size = cq_howmany(&ep->empty_frame_Q);
                        for (; size; size--) {
-                               struct packet *pkt = cq_get(ep->empty_frame_Q);
+                               struct packet *pkt = cq_get(&ep->empty_frame_Q);
 
                                kfree(pkt);
                        }
-                       cq_delete(ep->empty_frame_Q);
+                       cq_delete(&ep->empty_frame_Q);
                }
 
                if (ep->dummy_packets_Q) {
-                       size = cq_howmany(ep->dummy_packets_Q);
+                       size = cq_howmany(&ep->dummy_packets_Q);
                        for (; size; size--) {
-                               u8 *buff = cq_get(ep->dummy_packets_Q);
+                               u8 *buff = cq_get(&ep->dummy_packets_Q);
 
                                kfree(buff);
                        }
-                       cq_delete(ep->dummy_packets_Q);
+                       cq_delete(&ep->dummy_packets_Q);
                }
 
                kfree(ep);
@@ -175,10 +175,9 @@ u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem,
        ep->td_base = cpm_muram_addr(ep_offset);
 
        /* zero all queue pointers */
-       ep->conf_frame_Q = cq_new(ring_len + 2);
-       ep->empty_frame_Q = cq_new(ring_len + 2);
-       ep->dummy_packets_Q = cq_new(ring_len + 2);
-       if (!ep->conf_frame_Q || !ep->empty_frame_Q || !ep->dummy_packets_Q) {
+       if (cq_new(&ep->conf_frame_Q, ring_len + 2) ||
+           cq_new(&ep->empty_frame_Q, ring_len + 2) ||
+           cq_new(&ep->dummy_packets_Q, ring_len + 2)) {
                err_for = "frame_queues";
                goto err;
        }
@@ -199,8 +198,8 @@ u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem,
                        err_for = "buffer";
                        goto err;
                }
-               cq_put(ep->empty_frame_Q, pkt);
-               cq_put(ep->dummy_packets_Q, buff);
+               cq_put(&ep->empty_frame_Q, pkt);
+               cq_put(&ep->dummy_packets_Q, buff);
        }
 
        /* we put the endpoint parameter RAM right behind the TD ring */
@@ -319,7 +318,7 @@ static void fhci_td_transaction_confirm(struct fhci_usb *usb)
                if ((buf == DUMMY2_BD_BUFFER) && !(td_status & ~TD_W))
                        continue;
 
-               pkt = cq_get(ep->conf_frame_Q);
+               pkt = cq_get(&ep->conf_frame_Q);
                if (!pkt)
                        fhci_err(usb->fhci, "no frame to confirm\n");
 
@@ -460,9 +459,9 @@ u32 fhci_host_transaction(struct fhci_usb *usb,
                out_be16(&td->length, pkt->len);
 
        /* put the frame to the confirmation queue */
-       cq_put(ep->conf_frame_Q, pkt);
+       cq_put(&ep->conf_frame_Q, pkt);
 
-       if (cq_howmany(ep->conf_frame_Q) == 1)
+       if (cq_howmany(&ep->conf_frame_Q) == 1)
                out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO);
 
        return 0;
index 7116284..72dae1c 100644 (file)
@@ -423,9 +423,9 @@ struct endpoint {
        struct usb_td __iomem *td_base; /* first TD in the ring */
        struct usb_td __iomem *conf_td; /* next TD for confirm after transac */
        struct usb_td __iomem *empty_td;/* next TD for new transaction req. */
-       struct kfifo *empty_frame_Q;  /* Empty frames list to use */
-       struct kfifo *conf_frame_Q;   /* frames passed to TDs,waiting for tx */
-       struct kfifo *dummy_packets_Q;/* dummy packets for the CRC overun */
+       struct kfifo empty_frame_Q;  /* Empty frames list to use */
+       struct kfifo conf_frame_Q;   /* frames passed to TDs,waiting for tx */
+       struct kfifo dummy_packets_Q;/* dummy packets for the CRC overun */
 
        bool already_pushed_dummy_bd;
 };
@@ -493,9 +493,9 @@ static inline struct usb_hcd *fhci_to_hcd(struct fhci_hcd *fhci)
 }
 
 /* fifo of pointers */
-static inline struct kfifo *cq_new(int size)
+static inline int cq_new(struct kfifo *fifo, int size)
 {
-       return kfifo_alloc(size * sizeof(void *), GFP_KERNEL, NULL);
+       return kfifo_alloc(fifo, size * sizeof(void *), GFP_KERNEL);
 }
 
 static inline void cq_delete(struct kfifo *kfifo)
@@ -505,19 +505,19 @@ static inline void cq_delete(struct kfifo *kfifo)
 
 static inline unsigned int cq_howmany(struct kfifo *kfifo)
 {
-       return __kfifo_len(kfifo) / sizeof(void *);
+       return kfifo_len(kfifo) / sizeof(void *);
 }
 
 static inline int cq_put(struct kfifo *kfifo, void *p)
 {
-       return __kfifo_put(kfifo, (void *)&p, sizeof(p));
+       return kfifo_in(kfifo, (void *)&p, sizeof(p));
 }
 
 static inline void *cq_get(struct kfifo *kfifo)
 {
        void *p = NULL;
 
-       __kfifo_get(kfifo, (void *)&p, sizeof(p));
+       kfifo_out(kfifo, (void *)&p, sizeof(p));
        return p;
 }
 
index bbe005c..b0f1183 100644 (file)
@@ -276,7 +276,7 @@ static int usb_serial_generic_write_start(struct usb_serial_port *port)
        if (port->write_urb_busy)
                start_io = false;
        else {
-               start_io = (__kfifo_len(port->write_fifo) != 0);
+               start_io = (kfifo_len(port->write_fifo) != 0);
                port->write_urb_busy = start_io;
        }
        spin_unlock_irqrestore(&port->lock, flags);
@@ -285,7 +285,7 @@ static int usb_serial_generic_write_start(struct usb_serial_port *port)
                return 0;
 
        data = port->write_urb->transfer_buffer;
-       count = kfifo_get(port->write_fifo, data, port->bulk_out_size);
+       count = kfifo_out_locked(port->write_fifo, data, port->bulk_out_size, &port->lock);
        usb_serial_debug_data(debug, &port->dev, __func__, count, data);
 
        /* set up our urb */
@@ -345,7 +345,7 @@ int usb_serial_generic_write(struct tty_struct *tty,
                return usb_serial_multi_urb_write(tty, port,
                                                  buf, count);
 
-       count = kfifo_put(port->write_fifo, buf, count);
+       count = kfifo_in_locked(port->write_fifo, buf, count, &port->lock);
        result = usb_serial_generic_write_start(port);
 
        if (result >= 0)
@@ -370,7 +370,7 @@ int usb_serial_generic_write_room(struct tty_struct *tty)
                                (serial->type->max_in_flight_urbs -
                                 port->urbs_in_flight);
        } else if (serial->num_bulk_out)
-               room = port->write_fifo->size - __kfifo_len(port->write_fifo);
+               room = port->write_fifo->size - kfifo_len(port->write_fifo);
        spin_unlock_irqrestore(&port->lock, flags);
 
        dbg("%s - returns %d", __func__, room);
index 4543f35..636a4f2 100644 (file)
@@ -939,9 +939,7 @@ int usb_serial_probe(struct usb_interface *interface,
                        dev_err(&interface->dev, "No free urbs available\n");
                        goto probe_error;
                }
-               port->write_fifo = kfifo_alloc(PAGE_SIZE, GFP_KERNEL,
-                       &port->lock);
-               if (IS_ERR(port->write_fifo))
+               if (kfifo_alloc(port->write_fifo, PAGE_SIZE, GFP_KERNEL))
                        goto probe_error;
                buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
                port->bulk_out_size = buffer_size;
index da84fd0..088f32f 100644 (file)
@@ -368,7 +368,7 @@ config ALIM7101_WDT
 
 config GEODE_WDT
        tristate "AMD Geode CS5535/CS5536 Watchdog"
-       depends on MGEODE_LX
+       depends on CS5535_MFGPT
        help
          This driver enables a watchdog capability built into the
          CS5535/CS5536 companion chips for the AMD Geode GX and LX
index 9acf001..38252ff 100644 (file)
@@ -1,6 +1,7 @@
-/* Watchdog timer for the Geode GX/LX with the CS5535/CS5536 companion chip
+/* Watchdog timer for machines with the CS5535/CS5536 companion chip
  *
  * Copyright (C) 2006-2007, Advanced Micro Devices, Inc.
+ * Copyright (C) 2009  Andres Salomon <dilinger@collabora.co.uk>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -19,7 +20,7 @@
 #include <linux/reboot.h>
 #include <linux/uaccess.h>
 
-#include <asm/geode.h>
+#include <linux/cs5535.h>
 
 #define GEODEWDT_HZ 500
 #define GEODEWDT_SCALE 6
@@ -46,25 +47,25 @@ MODULE_PARM_DESC(nowayout,
 
 static struct platform_device *geodewdt_platform_device;
 static unsigned long wdt_flags;
-static int wdt_timer;
+static struct cs5535_mfgpt_timer *wdt_timer;
 static int safe_close;
 
 static void geodewdt_ping(void)
 {
        /* Stop the counter */
-       geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0);
+       cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0);
 
        /* Reset the counter */
-       geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0);
+       cs5535_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0);
 
        /* Enable the counter */
-       geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN);
+       cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN);
 }
 
 static void geodewdt_disable(void)
 {
-       geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0);
-       geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0);
+       cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0);
+       cs5535_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0);
 }
 
 static int geodewdt_set_heartbeat(int val)
@@ -72,10 +73,10 @@ static int geodewdt_set_heartbeat(int val)
        if (val < 1 || val > GEODEWDT_MAX_SECONDS)
                return -EINVAL;
 
-       geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0);
-       geode_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, val * GEODEWDT_HZ);
-       geode_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0);
-       geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN);
+       cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, 0);
+       cs5535_mfgpt_write(wdt_timer, MFGPT_REG_CMP2, val * GEODEWDT_HZ);
+       cs5535_mfgpt_write(wdt_timer, MFGPT_REG_COUNTER, 0);
+       cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN);
 
        timeout = val;
        return 0;
@@ -215,28 +216,25 @@ static struct miscdevice geodewdt_miscdev = {
 
 static int __devinit geodewdt_probe(struct platform_device *dev)
 {
-       int ret, timer;
-
-       timer = geode_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING);
+       int ret;
 
-       if (timer == -1) {
+       wdt_timer = cs5535_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING);
+       if (!wdt_timer) {
                printk(KERN_ERR "geodewdt:  No timers were available\n");
                return -ENODEV;
        }
 
-       wdt_timer = timer;
-
        /* Set up the timer */
 
-       geode_mfgpt_write(wdt_timer, MFGPT_REG_SETUP,
+       cs5535_mfgpt_write(wdt_timer, MFGPT_REG_SETUP,
                          GEODEWDT_SCALE | (3 << 8));
 
        /* Set up comparator 2 to reset when the event fires */
-       geode_mfgpt_toggle_event(wdt_timer, MFGPT_CMP2, MFGPT_EVENT_RESET, 1);
+       cs5535_mfgpt_toggle_event(wdt_timer, MFGPT_CMP2, MFGPT_EVENT_RESET, 1);
 
        /* Set up the initial timeout */
 
-       geode_mfgpt_write(wdt_timer, MFGPT_REG_CMP2,
+       cs5535_mfgpt_write(wdt_timer, MFGPT_REG_CMP2,
                timeout * GEODEWDT_HZ);
 
        ret = misc_register(&geodewdt_miscdev);
index 1c12177..55c8e63 100644 (file)
@@ -89,7 +89,7 @@ static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp,
        int flags = nfsexp_flags(rqstp, exp);
 
        /* Check if the request originated from a secure port. */
-       if (!rqstp->rq_secure && (flags & NFSEXP_INSECURE_PORT)) {
+       if (!rqstp->rq_secure && !(flags & NFSEXP_INSECURE_PORT)) {
                RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
                dprintk(KERN_WARNING
                       "nfsd: request from insecure port %s!\n",
index 4badde1..f560325 100644 (file)
@@ -134,13 +134,16 @@ static inline void task_name(struct seq_file *m, struct task_struct *p)
  * simple bit tests.
  */
 static const char *task_state_array[] = {
-       "R (running)",          /*  0 */
-       "S (sleeping)",         /*  1 */
-       "D (disk sleep)",       /*  2 */
-       "T (stopped)",          /*  4 */
-       "T (tracing stop)",     /*  8 */
-       "Z (zombie)",           /* 16 */
-       "X (dead)"              /* 32 */
+       "R (running)",          /*   0 */
+       "S (sleeping)",         /*   1 */
+       "D (disk sleep)",       /*   2 */
+       "T (stopped)",          /*   4 */
+       "t (tracing stop)",     /*   8 */
+       "Z (zombie)",           /*  16 */
+       "X (dead)",             /*  32 */
+       "x (dead)",             /*  64 */
+       "K (wakekill)",         /* 128 */
+       "W (waking)",           /* 256 */
 };
 
 static inline const char *get_task_state(struct task_struct *tsk)
@@ -148,6 +151,8 @@ static inline const char *get_task_state(struct task_struct *tsk)
        unsigned int state = (tsk->state & TASK_REPORT) | tsk->exit_state;
        const char **p = &task_state_array[0];
 
+       BUILD_BUG_ON(1 + ilog2(TASK_STATE_MAX) != ARRAY_SIZE(task_state_array));
+
        while (state) {
                p++;
                state >>= 1;
index 12ff8c3..5032b9a 100644 (file)
@@ -25,7 +25,7 @@ static void *malloc(int size)
        void *p;
 
        if (size < 0)
-               error("Malloc error");
+               return NULL;
        if (!malloc_ptr)
                malloc_ptr = free_mem_ptr;
 
@@ -35,7 +35,7 @@ static void *malloc(int size)
        malloc_ptr += size;
 
        if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr)
-               error("Out of memory");
+               return NULL;
 
        malloc_count++;
        return p;
index 90a4ed0..0cc4d55 100644 (file)
@@ -361,7 +361,7 @@ typedef struct elf64_shdr {
 #define NT_PPC_VSX     0x102           /* PowerPC VSX registers */
 #define NT_386_TLS     0x200           /* i386 TLS slots (struct user_desc) */
 #define NT_386_IOPERM  0x201           /* x86 io permission bitmap (1=deny) */
-#define NT_PRXSTATUS   0x300           /* s390 upper register halves */
+#define NT_S390_HIGH_GPRS      0x300   /* s390 upper register halves */
 
 
 /* Note header in a PT_NOTE section */
index ad6bdf5..486e8ad 100644 (file)
@@ -1,6 +1,7 @@
 /*
- * A simple kernel FIFO implementation.
+ * A generic kernel FIFO implementation.
  *
+ * Copyright (C) 2009 Stefani Seibold <stefani@seibold.net>
  * Copyright (C) 2004 Stelian Pop <stelian@popies.net>
  *
  * This program is free software; you can redistribute it and/or modify
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  */
+
+/*
+ * Howto porting drivers to the new generic fifo API:
+ *
+ * - Modify the declaration of the "struct kfifo *" object into a
+ *   in-place "struct kfifo" object
+ * - Init the in-place object with kfifo_alloc() or kfifo_init()
+ *   Note: The address of the in-place "struct kfifo" object must be
+ *   passed as the first argument to this functions
+ * - Replace the use of __kfifo_put into kfifo_in and __kfifo_get
+ *   into kfifo_out
+ * - Replace the use of kfifo_put into kfifo_in_locked and kfifo_get
+ *   into kfifo_out_locked
+ *   Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc
+ *   must be passed now to the kfifo_in_locked and kfifo_out_locked
+ *   as the last parameter.
+ * - All formerly name __kfifo_* functions has been renamed into kfifo_*
+ */
+
 #ifndef _LINUX_KFIFO_H
 #define _LINUX_KFIFO_H
 
@@ -29,124 +49,563 @@ struct kfifo {
        unsigned int size;      /* the size of the allocated buffer */
        unsigned int in;        /* data is added at offset (in % size) */
        unsigned int out;       /* data is extracted from off. (out % size) */
-       spinlock_t *lock;       /* protects concurrent modifications */
 };
 
-extern struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size,
-                               gfp_t gfp_mask, spinlock_t *lock);
-extern struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask,
-                                spinlock_t *lock);
+/*
+ * Macros for declaration and initialization of the kfifo datatype
+ */
+
+/* helper macro */
+#define __kfifo_initializer(s, b) \
+       (struct kfifo) { \
+               .size   = s, \
+               .in     = 0, \
+               .out    = 0, \
+               .buffer = b \
+       }
+
+/**
+ * DECLARE_KFIFO - macro to declare a kfifo and the associated buffer
+ * @name: name of the declared kfifo datatype
+ * @size: size of the fifo buffer
+ *
+ * Note: the macro can be used inside struct or union declaration
+ * Note: the macro creates two objects:
+ *  A kfifo object with the given name and a buffer for the kfifo
+ *  object named name##kfifo_buffer
+ */
+#define DECLARE_KFIFO(name, size) \
+union { \
+       struct kfifo name; \
+       unsigned char name##kfifo_buffer[size + sizeof(struct kfifo)]; \
+}
+
+/**
+ * INIT_KFIFO - Initialize a kfifo declared by DECLARED_KFIFO
+ * @name: name of the declared kfifo datatype
+ * @size: size of the fifo buffer
+ */
+#define INIT_KFIFO(name) \
+       name = __kfifo_initializer(sizeof(name##kfifo_buffer) - \
+                               sizeof(struct kfifo), name##kfifo_buffer)
+
+/**
+ * DEFINE_KFIFO - macro to define and initialize a kfifo
+ * @name: name of the declared kfifo datatype
+ * @size: size of the fifo buffer
+ *
+ * Note: the macro can be used for global and local kfifo data type variables
+ * Note: the macro creates two objects:
+ *  A kfifo object with the given name and a buffer for the kfifo
+ *  object named name##kfifo_buffer
+ */
+#define DEFINE_KFIFO(name, size) \
+       unsigned char name##kfifo_buffer[size]; \
+       struct kfifo name = __kfifo_initializer(size, name##kfifo_buffer)
+
+#undef __kfifo_initializer
+
+extern void kfifo_init(struct kfifo *fifo, unsigned char *buffer,
+                       unsigned int size);
+extern __must_check int kfifo_alloc(struct kfifo *fifo, unsigned int size,
+                       gfp_t gfp_mask);
 extern void kfifo_free(struct kfifo *fifo);
-extern unsigned int __kfifo_put(struct kfifo *fifo,
-                               const unsigned char *buffer, unsigned int len);
-extern unsigned int __kfifo_get(struct kfifo *fifo,
-                               unsigned char *buffer, unsigned int len);
+extern unsigned int kfifo_in(struct kfifo *fifo,
+                               const unsigned char *from, unsigned int len);
+extern __must_check unsigned int kfifo_out(struct kfifo *fifo,
+                               unsigned char *to, unsigned int len);
 
 /**
- * __kfifo_reset - removes the entire FIFO contents, no locking version
+ * kfifo_reset - removes the entire FIFO contents
  * @fifo: the fifo to be emptied.
  */
-static inline void __kfifo_reset(struct kfifo *fifo)
+static inline void kfifo_reset(struct kfifo *fifo)
 {
        fifo->in = fifo->out = 0;
 }
 
 /**
- * kfifo_reset - removes the entire FIFO contents
+ * kfifo_reset_out - skip FIFO contents
  * @fifo: the fifo to be emptied.
  */
-static inline void kfifo_reset(struct kfifo *fifo)
+static inline void kfifo_reset_out(struct kfifo *fifo)
 {
-       unsigned long flags;
+       smp_mb();
+       fifo->out = fifo->in;
+}
 
-       spin_lock_irqsave(fifo->lock, flags);
+/**
+ * kfifo_size - returns the size of the fifo in bytes
+ * @fifo: the fifo to be used.
+ */
+static inline __must_check unsigned int kfifo_size(struct kfifo *fifo)
+{
+       return fifo->size;
+}
 
-       __kfifo_reset(fifo);
+/**
+ * kfifo_len - returns the number of used bytes in the FIFO
+ * @fifo: the fifo to be used.
+ */
+static inline unsigned int kfifo_len(struct kfifo *fifo)
+{
+       register unsigned int   out;
 
-       spin_unlock_irqrestore(fifo->lock, flags);
+       out = fifo->out;
+       smp_rmb();
+       return fifo->in - out;
 }
 
 /**
- * kfifo_put - puts some data into the FIFO
+ * kfifo_is_empty - returns true if the fifo is empty
  * @fifo: the fifo to be used.
- * @buffer: the data to be added.
- * @len: the length of the data to be added.
+ */
+static inline __must_check int kfifo_is_empty(struct kfifo *fifo)
+{
+       return fifo->in == fifo->out;
+}
+
+/**
+ * kfifo_is_full - returns true if the fifo is full
+ * @fifo: the fifo to be used.
+ */
+static inline __must_check int kfifo_is_full(struct kfifo *fifo)
+{
+       return kfifo_len(fifo) == kfifo_size(fifo);
+}
+
+/**
+ * kfifo_avail - returns the number of bytes available in the FIFO
+ * @fifo: the fifo to be used.
+ */
+static inline __must_check unsigned int kfifo_avail(struct kfifo *fifo)
+{
+       return kfifo_size(fifo) - kfifo_len(fifo);
+}
+
+/**
+ * kfifo_in_locked - puts some data into the FIFO using a spinlock for locking
+ * @fifo: the fifo to be used.
+ * @from: the data to be added.
+ * @n: the length of the data to be added.
+ * @lock: pointer to the spinlock to use for locking.
  *
- * This function copies at most @len bytes from the @buffer into
+ * This function copies at most @len bytes from the @from buffer into
  * the FIFO depending on the free space, and returns the number of
  * bytes copied.
  */
-static inline unsigned int kfifo_put(struct kfifo *fifo,
-                               const unsigned char *buffer, unsigned int len)
+static inline unsigned int kfifo_in_locked(struct kfifo *fifo,
+               const unsigned char *from, unsigned int n, spinlock_t *lock)
 {
        unsigned long flags;
        unsigned int ret;
 
-       spin_lock_irqsave(fifo->lock, flags);
+       spin_lock_irqsave(lock, flags);
 
-       ret = __kfifo_put(fifo, buffer, len);
+       ret = kfifo_in(fifo, from, n);
 
-       spin_unlock_irqrestore(fifo->lock, flags);
+       spin_unlock_irqrestore(lock, flags);
 
        return ret;
 }
 
 /**
- * kfifo_get - gets some data from the FIFO
+ * kfifo_out_locked - gets some data from the FIFO using a spinlock for locking
  * @fifo: the fifo to be used.
- * @buffer: where the data must be copied.
- * @len: the size of the destination buffer.
+ * @to: where the data must be copied.
+ * @n: the size of the destination buffer.
+ * @lock: pointer to the spinlock to use for locking.
  *
  * This function copies at most @len bytes from the FIFO into the
- * @buffer and returns the number of copied bytes.
+ * @to buffer and returns the number of copied bytes.
  */
-static inline unsigned int kfifo_get(struct kfifo *fifo,
-                                    unsigned char *buffer, unsigned int len)
+static inline __must_check unsigned int kfifo_out_locked(struct kfifo *fifo,
+       unsigned char *to, unsigned int n, spinlock_t *lock)
 {
        unsigned long flags;
        unsigned int ret;
 
-       spin_lock_irqsave(fifo->lock, flags);
+       spin_lock_irqsave(lock, flags);
 
-       ret = __kfifo_get(fifo, buffer, len);
+       ret = kfifo_out(fifo, to, n);
 
        /*
         * optimization: if the FIFO is empty, set the indices to 0
         * so we don't wrap the next time
         */
-       if (fifo->in == fifo->out)
-               fifo->in = fifo->out = 0;
+       if (kfifo_is_empty(fifo))
+               kfifo_reset(fifo);
+
+       spin_unlock_irqrestore(lock, flags);
+
+       return ret;
+}
+
+extern void kfifo_skip(struct kfifo *fifo, unsigned int len);
+
+extern __must_check unsigned int kfifo_from_user(struct kfifo *fifo,
+       const void __user *from, unsigned int n);
+
+extern __must_check unsigned int kfifo_to_user(struct kfifo *fifo,
+       void __user *to, unsigned int n);
+
+/**
+ * __kfifo_add_out internal helper function for updating the out offset
+ */
+static inline void __kfifo_add_out(struct kfifo *fifo,
+                               unsigned int off)
+{
+       smp_mb();
+       fifo->out += off;
+}
+
+/**
+ * __kfifo_add_in internal helper function for updating the in offset
+ */
+static inline void __kfifo_add_in(struct kfifo *fifo,
+                               unsigned int off)
+{
+       smp_wmb();
+       fifo->in += off;
+}
+
+/**
+ * __kfifo_off internal helper function for calculating the index of a
+ * given offeset
+ */
+static inline unsigned int __kfifo_off(struct kfifo *fifo, unsigned int off)
+{
+       return off & (fifo->size - 1);
+}
+
+/**
+ * __kfifo_peek_n internal helper function for determinate the length of
+ * the next record in the fifo
+ */
+static inline unsigned int __kfifo_peek_n(struct kfifo *fifo,
+                               unsigned int recsize)
+{
+#define __KFIFO_GET(fifo, off, shift) \
+       ((fifo)->buffer[__kfifo_off((fifo), (fifo)->out+(off))] << (shift))
+
+       unsigned int l;
+
+       l = __KFIFO_GET(fifo, 0, 0);
+
+       if (--recsize)
+               l |= __KFIFO_GET(fifo, 1, 8);
+
+       return l;
+#undef __KFIFO_GET
+}
+
+/**
+ * __kfifo_poke_n internal helper function for storing the length of
+ * the next record into the fifo
+ */
+static inline void __kfifo_poke_n(struct kfifo *fifo,
+                       unsigned int recsize, unsigned int n)
+{
+#define __KFIFO_PUT(fifo, off, val, shift) \
+               ( \
+               (fifo)->buffer[__kfifo_off((fifo), (fifo)->in+(off))] = \
+               (unsigned char)((val) >> (shift)) \
+               )
 
-       spin_unlock_irqrestore(fifo->lock, flags);
+       __KFIFO_PUT(fifo, 0, n, 0);
 
+       if (--recsize)
+               __KFIFO_PUT(fifo, 1, n, 8);
+#undef __KFIFO_PUT
+}
+
+/**
+ * __kfifo_in_... internal functions for put date into the fifo
+ * do not call it directly, use kfifo_in_rec() instead
+ */
+extern unsigned int __kfifo_in_n(struct kfifo *fifo,
+       const void *from, unsigned int n, unsigned int recsize);
+
+extern unsigned int __kfifo_in_generic(struct kfifo *fifo,
+       const void *from, unsigned int n, unsigned int recsize);
+
+static inline unsigned int __kfifo_in_rec(struct kfifo *fifo,
+       const void *from, unsigned int n, unsigned int recsize)
+{
+       unsigned int ret;
+
+       ret = __kfifo_in_n(fifo, from, n, recsize);
+
+       if (likely(ret == 0)) {
+               if (recsize)
+                       __kfifo_poke_n(fifo, recsize, n);
+               __kfifo_add_in(fifo, n + recsize);
+       }
        return ret;
 }
 
 /**
- * __kfifo_len - returns the number of bytes available in the FIFO, no locking version
+ * kfifo_in_rec - puts some record data into the FIFO
  * @fifo: the fifo to be used.
+ * @from: the data to be added.
+ * @n: the length of the data to be added.
+ * @recsize: size of record field
+ *
+ * This function copies @n bytes from the @from into the FIFO and returns
+ * the number of bytes which cannot be copied.
+ * A returned value greater than the @n value means that the record doesn't
+ * fit into the buffer.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
  */
-static inline unsigned int __kfifo_len(struct kfifo *fifo)
+static inline __must_check unsigned int kfifo_in_rec(struct kfifo *fifo,
+       void *from, unsigned int n, unsigned int recsize)
 {
-       return fifo->in - fifo->out;
+       if (!__builtin_constant_p(recsize))
+               return __kfifo_in_generic(fifo, from, n, recsize);
+       return __kfifo_in_rec(fifo, from, n, recsize);
 }
 
 /**
- * kfifo_len - returns the number of bytes available in the FIFO
+ * __kfifo_out_... internal functions for get date from the fifo
+ * do not call it directly, use kfifo_out_rec() instead
+ */
+extern unsigned int __kfifo_out_n(struct kfifo *fifo,
+       void *to, unsigned int reclen, unsigned int recsize);
+
+extern unsigned int __kfifo_out_generic(struct kfifo *fifo,
+       void *to, unsigned int n,
+       unsigned int recsize, unsigned int *total);
+
+static inline unsigned int __kfifo_out_rec(struct kfifo *fifo,
+       void *to, unsigned int n, unsigned int recsize,
+       unsigned int *total)
+{
+       unsigned int l;
+
+       if (!recsize) {
+               l = n;
+               if (total)
+                       *total = l;
+       } else {
+               l = __kfifo_peek_n(fifo, recsize);
+               if (total)
+                       *total = l;
+               if (n < l)
+                       return l;
+       }
+
+       return __kfifo_out_n(fifo, to, l, recsize);
+}
+
+/**
+ * kfifo_out_rec - gets some record data from the FIFO
  * @fifo: the fifo to be used.
+ * @to: where the data must be copied.
+ * @n: the size of the destination buffer.
+ * @recsize: size of record field
+ * @total: pointer where the total number of to copied bytes should stored
+ *
+ * This function copies at most @n bytes from the FIFO to @to and returns the
+ * number of bytes which cannot be copied.
+ * A returned value greater than the @n value means that the record doesn't
+ * fit into the @to buffer.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
  */
-static inline unsigned int kfifo_len(struct kfifo *fifo)
+static inline __must_check unsigned int kfifo_out_rec(struct kfifo *fifo,
+       void *to, unsigned int n, unsigned int recsize,
+       unsigned int *total)
+
 {
-       unsigned long flags;
-       unsigned int ret;
+       if (!__builtin_constant_p(recsize))
+               return __kfifo_out_generic(fifo, to, n, recsize, total);
+       return __kfifo_out_rec(fifo, to, n, recsize, total);
+}
+
+/**
+ * __kfifo_from_user_... internal functions for transfer from user space into
+ * the fifo. do not call it directly, use kfifo_from_user_rec() instead
+ */
+extern unsigned int __kfifo_from_user_n(struct kfifo *fifo,
+       const void __user *from, unsigned int n, unsigned int recsize);
 
-       spin_lock_irqsave(fifo->lock, flags);
+extern unsigned int __kfifo_from_user_generic(struct kfifo *fifo,
+       const void __user *from, unsigned int n, unsigned int recsize);
 
-       ret = __kfifo_len(fifo);
+static inline unsigned int __kfifo_from_user_rec(struct kfifo *fifo,
+       const void __user *from, unsigned int n, unsigned int recsize)
+{
+       unsigned int ret;
 
-       spin_unlock_irqrestore(fifo->lock, flags);
+       ret = __kfifo_from_user_n(fifo, from, n, recsize);
 
+       if (likely(ret == 0)) {
+               if (recsize)
+                       __kfifo_poke_n(fifo, recsize, n);
+               __kfifo_add_in(fifo, n + recsize);
+       }
        return ret;
 }
 
+/**
+ * kfifo_from_user_rec - puts some data from user space into the FIFO
+ * @fifo: the fifo to be used.
+ * @from: pointer to the data to be added.
+ * @n: the length of the data to be added.
+ * @recsize: size of record field
+ *
+ * This function copies @n bytes from the @from into the
+ * FIFO and returns the number of bytes which cannot be copied.
+ *
+ * If the returned value is equal or less the @n value, the copy_from_user()
+ * functions has failed. Otherwise the record doesn't fit into the buffer.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+static inline __must_check unsigned int kfifo_from_user_rec(struct kfifo *fifo,
+       const void __user *from, unsigned int n, unsigned int recsize)
+{
+       if (!__builtin_constant_p(recsize))
+               return __kfifo_from_user_generic(fifo, from, n, recsize);
+       return __kfifo_from_user_rec(fifo, from, n, recsize);
+}
+
+/**
+ * __kfifo_to_user_... internal functions for transfer fifo data into user space
+ * do not call it directly, use kfifo_to_user_rec() instead
+ */
+extern unsigned int __kfifo_to_user_n(struct kfifo *fifo,
+       void __user *to, unsigned int n, unsigned int reclen,
+       unsigned int recsize);
+
+extern unsigned int __kfifo_to_user_generic(struct kfifo *fifo,
+       void __user *to, unsigned int n, unsigned int recsize,
+       unsigned int *total);
+
+static inline unsigned int __kfifo_to_user_rec(struct kfifo *fifo,
+       void __user *to, unsigned int n,
+       unsigned int recsize, unsigned int *total)
+{
+       unsigned int l;
+
+       if (!recsize) {
+               l = n;
+               if (total)
+                       *total = l;
+       } else {
+               l = __kfifo_peek_n(fifo, recsize);
+               if (total)
+                       *total = l;
+               if (n < l)
+                       return l;
+       }
+
+       return __kfifo_to_user_n(fifo, to, n, l, recsize);
+}
+
+/**
+ * kfifo_to_user_rec - gets data from the FIFO and write it to user space
+ * @fifo: the fifo to be used.
+ * @to: where the data must be copied.
+ * @n: the size of the destination buffer.
+ * @recsize: size of record field
+ * @total: pointer where the total number of to copied bytes should stored
+ *
+ * This function copies at most @n bytes from the FIFO to the @to.
+ * In case of an error, the function returns the number of bytes which cannot
+ * be copied.
+ * If the returned value is equal or less the @n value, the copy_to_user()
+ * functions has failed. Otherwise the record doesn't fit into the @to buffer.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+static inline __must_check unsigned int kfifo_to_user_rec(struct kfifo *fifo,
+               void __user *to, unsigned int n, unsigned int recsize,
+               unsigned int *total)
+{
+       if (!__builtin_constant_p(recsize))
+               return __kfifo_to_user_generic(fifo, to, n, recsize, total);
+       return __kfifo_to_user_rec(fifo, to, n, recsize, total);
+}
+
+/**
+ * __kfifo_peek_... internal functions for peek into the next fifo record
+ * do not call it directly, use kfifo_peek_rec() instead
+ */
+extern unsigned int __kfifo_peek_generic(struct kfifo *fifo,
+                               unsigned int recsize);
+
+/**
+ * kfifo_peek_rec - gets the size of the next FIFO record data
+ * @fifo: the fifo to be used.
+ * @recsize: size of record field
+ *
+ * This function returns the size of the next FIFO record in number of bytes
+ */
+static inline __must_check unsigned int kfifo_peek_rec(struct kfifo *fifo,
+       unsigned int recsize)
+{
+       if (!__builtin_constant_p(recsize))
+               return __kfifo_peek_generic(fifo, recsize);
+       if (!recsize)
+               return kfifo_len(fifo);
+       return __kfifo_peek_n(fifo, recsize);
+}
+
+/**
+ * __kfifo_skip_... internal functions for skip the next fifo record
+ * do not call it directly, use kfifo_skip_rec() instead
+ */
+extern void __kfifo_skip_generic(struct kfifo *fifo, unsigned int recsize);
+
+static inline void __kfifo_skip_rec(struct kfifo *fifo,
+       unsigned int recsize)
+{
+       unsigned int l;
+
+       if (recsize) {
+               l = __kfifo_peek_n(fifo, recsize);
+
+               if (l + recsize <= kfifo_len(fifo)) {
+                       __kfifo_add_out(fifo, l + recsize);
+                       return;
+               }
+       }
+       kfifo_reset_out(fifo);
+}
+
+/**
+ * kfifo_skip_rec - skip the next fifo out record
+ * @fifo: the fifo to be used.
+ * @recsize: size of record field
+ *
+ * This function skips the next FIFO record
+ */
+static inline void kfifo_skip_rec(struct kfifo *fifo,
+       unsigned int recsize)
+{
+       if (!__builtin_constant_p(recsize))
+               __kfifo_skip_generic(fifo, recsize);
+       else
+               __kfifo_skip_rec(fifo, recsize);
+}
+
+/**
+ * kfifo_avail_rec - returns the number of bytes available in a record FIFO
+ * @fifo: the fifo to be used.
+ * @recsize: size of record field
+ */
+static inline __must_check unsigned int kfifo_avail_rec(struct kfifo *fifo,
+       unsigned int recsize)
+{
+       unsigned int l = kfifo_size(fifo) - kfifo_len(fifo);
+
+       return (l > recsize) ? l - recsize : 0;
+}
+
 #endif
index 849b4a6..2265f28 100644 (file)
@@ -1037,6 +1037,9 @@ extern void add_active_range(unsigned int nid, unsigned long start_pfn,
 extern void remove_active_range(unsigned int nid, unsigned long start_pfn,
                                        unsigned long end_pfn);
 extern void remove_all_active_ranges(void);
+void sort_node_map(void);
+unsigned long __absent_pages_in_range(int nid, unsigned long start_pfn,
+                                               unsigned long end_pfn);
 extern unsigned long absent_pages_in_range(unsigned long start_pfn,
                                                unsigned long end_pfn);
 extern void get_pfn_range_for_nid(unsigned int nid,
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h
deleted file mode 100644 (file)
index e3fb256..0000000
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- *  NOTE: this file will be removed in a future kernel release, it is
- *  provided as a courtesy copy of user-space code that relies on the
- *  old (pre-rename) symbols and constants.
- *
- *  Performance events:
- *
- *    Copyright (C) 2008-2009, Thomas Gleixner <tglx@linutronix.de>
- *    Copyright (C) 2008-2009, Red Hat, Inc., Ingo Molnar
- *    Copyright (C) 2008-2009, Red Hat, Inc., Peter Zijlstra
- *
- *  Data type definitions, declarations, prototypes.
- *
- *    Started by: Thomas Gleixner and Ingo Molnar
- *
- *  For licencing details see kernel-base/COPYING
- */
-#ifndef _LINUX_PERF_COUNTER_H
-#define _LINUX_PERF_COUNTER_H
-
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#include <asm/byteorder.h>
-
-/*
- * User-space ABI bits:
- */
-
-/*
- * attr.type
- */
-enum perf_type_id {
-       PERF_TYPE_HARDWARE                      = 0,
-       PERF_TYPE_SOFTWARE                      = 1,
-       PERF_TYPE_TRACEPOINT                    = 2,
-       PERF_TYPE_HW_CACHE                      = 3,
-       PERF_TYPE_RAW                           = 4,
-
-       PERF_TYPE_MAX,                          /* non-ABI */
-};
-
-/*
- * Generalized performance counter event types, used by the
- * attr.event_id parameter of the sys_perf_counter_open()
- * syscall:
- */
-enum perf_hw_id {
-       /*
-        * Common hardware events, generalized by the kernel:
-        */
-       PERF_COUNT_HW_CPU_CYCLES                = 0,
-       PERF_COUNT_HW_INSTRUCTIONS              = 1,
-       PERF_COUNT_HW_CACHE_REFERENCES          = 2,
-       PERF_COUNT_HW_CACHE_MISSES              = 3,
-       PERF_COUNT_HW_BRANCH_INSTRUCTIONS       = 4,
-       PERF_COUNT_HW_BRANCH_MISSES             = 5,
-       PERF_COUNT_HW_BUS_CYCLES                = 6,
-
-       PERF_COUNT_HW_MAX,                      /* non-ABI */
-};
-
-/*
- * Generalized hardware cache counters:
- *
- *       { L1-D, L1-I, LLC, ITLB, DTLB, BPU } x
- *       { read, write, prefetch } x
- *       { accesses, misses }
- */
-enum perf_hw_cache_id {
-       PERF_COUNT_HW_CACHE_L1D                 = 0,
-       PERF_COUNT_HW_CACHE_L1I                 = 1,
-       PERF_COUNT_HW_CACHE_LL                  = 2,
-       PERF_COUNT_HW_CACHE_DTLB                = 3,
-       PERF_COUNT_HW_CACHE_ITLB                = 4,
-       PERF_COUNT_HW_CACHE_BPU                 = 5,
-
-       PERF_COUNT_HW_CACHE_MAX,                /* non-ABI */
-};
-
-enum perf_hw_cache_op_id {
-       PERF_COUNT_HW_CACHE_OP_READ             = 0,
-       PERF_COUNT_HW_CACHE_OP_WRITE            = 1,
-       PERF_COUNT_HW_CACHE_OP_PREFETCH         = 2,
-
-       PERF_COUNT_HW_CACHE_OP_MAX,             /* non-ABI */
-};
-
-enum perf_hw_cache_op_result_id {
-       PERF_COUNT_HW_CACHE_RESULT_ACCESS       = 0,
-       PERF_COUNT_HW_CACHE_RESULT_MISS         = 1,
-
-       PERF_COUNT_HW_CACHE_RESULT_MAX,         /* non-ABI */
-};
-
-/*
- * Special "software" counters provided by the kernel, even if the hardware
- * does not support performance counters. These counters measure various
- * physical and sw events of the kernel (and allow the profiling of them as
- * well):
- */
-enum perf_sw_ids {
-       PERF_COUNT_SW_CPU_CLOCK                 = 0,
-       PERF_COUNT_SW_TASK_CLOCK                = 1,
-       PERF_COUNT_SW_PAGE_FAULTS               = 2,
-       PERF_COUNT_SW_CONTEXT_SWITCHES          = 3,
-       PERF_COUNT_SW_CPU_MIGRATIONS            = 4,
-       PERF_COUNT_SW_PAGE_FAULTS_MIN           = 5,
-       PERF_COUNT_SW_PAGE_FAULTS_MAJ           = 6,
-       PERF_COUNT_SW_ALIGNMENT_FAULTS          = 7,
-       PERF_COUNT_SW_EMULATION_FAULTS          = 8,
-
-       PERF_COUNT_SW_MAX,                      /* non-ABI */
-};
-
-/*
- * Bits that can be set in attr.sample_type to request information
- * in the overflow packets.
- */
-enum perf_counter_sample_format {
-       PERF_SAMPLE_IP                          = 1U << 0,
-       PERF_SAMPLE_TID                         = 1U << 1,
-       PERF_SAMPLE_TIME                        = 1U << 2,
-       PERF_SAMPLE_ADDR                        = 1U << 3,
-       PERF_SAMPLE_READ                        = 1U << 4,
-       PERF_SAMPLE_CALLCHAIN                   = 1U << 5,
-       PERF_SAMPLE_ID                          = 1U << 6,
-       PERF_SAMPLE_CPU                         = 1U << 7,
-       PERF_SAMPLE_PERIOD                      = 1U << 8,
-       PERF_SAMPLE_STREAM_ID                   = 1U << 9,
-       PERF_SAMPLE_RAW                         = 1U << 10,
-
-       PERF_SAMPLE_MAX = 1U << 11,             /* non-ABI */
-};
-
-/*
- * The format of the data returned by read() on a perf counter fd,
- * as specified by attr.read_format:
- *
- * struct read_format {
- *     { u64           value;
- *       { u64         time_enabled; } && PERF_FORMAT_ENABLED
- *       { u64         time_running; } && PERF_FORMAT_RUNNING
- *       { u64         id;           } && PERF_FORMAT_ID
- *     } && !PERF_FORMAT_GROUP
- *
- *     { u64           nr;
- *       { u64         time_enabled; } && PERF_FORMAT_ENABLED
- *       { u64         time_running; } && PERF_FORMAT_RUNNING
- *       { u64         value;
- *         { u64       id;           } && PERF_FORMAT_ID
- *       }             cntr[nr];
- *     } && PERF_FORMAT_GROUP
- * };
- */
-enum perf_counter_read_format {
-       PERF_FORMAT_TOTAL_TIME_ENABLED          = 1U << 0,
-       PERF_FORMAT_TOTAL_TIME_RUNNING          = 1U << 1,
-       PERF_FORMAT_ID                          = 1U << 2,
-       PERF_FORMAT_GROUP                       = 1U << 3,
-
-       PERF_FORMAT_MAX = 1U << 4,              /* non-ABI */
-};
-
-#define PERF_ATTR_SIZE_VER0    64      /* sizeof first published struct */
-
-/*
- * Hardware event to monitor via a performance monitoring counter:
- */
-struct perf_counter_attr {
-
-       /*
-        * Major type: hardware/software/tracepoint/etc.
-        */
-       __u32                   type;
-
-       /*
-        * Size of the attr structure, for fwd/bwd compat.
-        */
-       __u32                   size;
-
-       /*
-        * Type specific configuration information.
-        */
-       __u64                   config;
-
-       union {
-               __u64           sample_period;
-               __u64           sample_freq;
-       };
-
-       __u64                   sample_type;
-       __u64                   read_format;
-
-       __u64                   disabled       :  1, /* off by default        */
-                               inherit        :  1, /* children inherit it   */
-                               pinned         :  1, /* must always be on PMU */
-                               exclusive      :  1, /* only group on PMU     */
-                               exclude_user   :  1, /* don't count user      */
-                               exclude_kernel :  1, /* ditto kernel          */
-                               exclude_hv     :  1, /* ditto hypervisor      */
-                               exclude_idle   :  1, /* don't count when idle */
-                               mmap           :  1, /* include mmap data     */
-                               comm           :  1, /* include comm data     */
-                               freq           :  1, /* use freq, not period  */
-                               inherit_stat   :  1, /* per task counts       */
-                               enable_on_exec :  1, /* next exec enables     */
-                               task           :  1, /* trace fork/exit       */
-                               watermark      :  1, /* wakeup_watermark      */
-
-                               __reserved_1   : 49;
-
-       union {
-               __u32           wakeup_events;    /* wakeup every n events */
-               __u32           wakeup_watermark; /* bytes before wakeup   */
-       };
-       __u32                   __reserved_2;
-
-       __u64                   __reserved_3;
-};
-
-/*
- * Ioctls that can be done on a perf counter fd:
- */
-#define PERF_COUNTER_IOC_ENABLE                _IO ('$', 0)
-#define PERF_COUNTER_IOC_DISABLE       _IO ('$', 1)
-#define PERF_COUNTER_IOC_REFRESH       _IO ('$', 2)
-#define PERF_COUNTER_IOC_RESET         _IO ('$', 3)
-#define PERF_COUNTER_IOC_PERIOD                _IOW('$', 4, u64)
-#define PERF_COUNTER_IOC_SET_OUTPUT    _IO ('$', 5)
-#define PERF_COUNTER_IOC_SET_FILTER    _IOW('$', 6, char *)
-
-enum perf_counter_ioc_flags {
-       PERF_IOC_FLAG_GROUP             = 1U << 0,
-};
-
-/*
- * Structure of the page that can be mapped via mmap
- */
-struct perf_counter_mmap_page {
-       __u32   version;                /* version number of this structure */
-       __u32   compat_version;         /* lowest version this is compat with */
-
-       /*
-        * Bits needed to read the hw counters in user-space.
-        *
-        *   u32 seq;
-        *   s64 count;
-        *
-        *   do {
-        *     seq = pc->lock;
-        *
-        *     barrier()
-        *     if (pc->index) {
-        *       count = pmc_read(pc->index - 1);
-        *       count += pc->offset;
-        *     } else
-        *       goto regular_read;
-        *
-        *     barrier();
-        *   } while (pc->lock != seq);
-        *
-        * NOTE: for obvious reason this only works on self-monitoring
-        *       processes.
-        */
-       __u32   lock;                   /* seqlock for synchronization */
-       __u32   index;                  /* hardware counter identifier */
-       __s64   offset;                 /* add to hardware counter value */
-       __u64   time_enabled;           /* time counter active */
-       __u64   time_running;           /* time counter on cpu */
-
-               /*
-                * Hole for extension of the self monitor capabilities
-                */
-
-       __u64   __reserved[123];        /* align to 1k */
-
-       /*
-        * Control data for the mmap() data buffer.
-        *
-        * User-space reading the @data_head value should issue an rmb(), on
-        * SMP capable platforms, after reading this value -- see
-        * perf_counter_wakeup().
-        *
-        * When the mapping is PROT_WRITE the @data_tail value should be
-        * written by userspace to reflect the last read data. In this case
-        * the kernel will not over-write unread data.
-        */
-       __u64   data_head;              /* head in the data section */
-       __u64   data_tail;              /* user-space written tail */
-};
-
-#define PERF_EVENT_MISC_CPUMODE_MASK           (3 << 0)
-#define PERF_EVENT_MISC_CPUMODE_UNKNOWN                (0 << 0)
-#define PERF_EVENT_MISC_KERNEL                 (1 << 0)
-#define PERF_EVENT_MISC_USER                   (2 << 0)
-#define PERF_EVENT_MISC_HYPERVISOR             (3 << 0)
-
-struct perf_event_header {
-       __u32   type;
-       __u16   misc;
-       __u16   size;
-};
-
-enum perf_event_type {
-
-       /*
-        * The MMAP events record the PROT_EXEC mappings so that we can
-        * correlate userspace IPs to code. They have the following structure:
-        *
-        * struct {
-        *      struct perf_event_header        header;
-        *
-        *      u32                             pid, tid;
-        *      u64                             addr;
-        *      u64                             len;
-        *      u64                             pgoff;
-        *      char                            filename[];
-        * };
-        */
-       PERF_EVENT_MMAP                 = 1,
-
-       /*
-        * struct {
-        *      struct perf_event_header        header;
-        *      u64                             id;
-        *      u64                             lost;
-        * };
-        */
-       PERF_EVENT_LOST                 = 2,
-
-       /*
-        * struct {
-        *      struct perf_event_header        header;
-        *
-        *      u32                             pid, tid;
-        *      char                            comm[];
-        * };
-        */
-       PERF_EVENT_COMM                 = 3,
-
-       /*
-        * struct {
-        *      struct perf_event_header        header;
-        *      u32                             pid, ppid;
-        *      u32                             tid, ptid;
-        *      u64                             time;
-        * };
-        */
-       PERF_EVENT_EXIT                 = 4,
-
-       /*
-        * struct {
-        *      struct perf_event_header        header;
-        *      u64                             time;
-        *      u64                             id;
-        *      u64                             stream_id;
-        * };
-        */
-       PERF_EVENT_THROTTLE             = 5,
-       PERF_EVENT_UNTHROTTLE           = 6,
-
-       /*
-        * struct {
-        *      struct perf_event_header        header;
-        *      u32                             pid, ppid;
-        *      u32                             tid, ptid;
-        *      u64                             time;
-        * };
-        */
-       PERF_EVENT_FORK                 = 7,
-
-       /*
-        * struct {
-        *      struct perf_event_header        header;
-        *      u32                             pid, tid;
-        *
-        *      struct read_format              values;
-        * };
-        */
-       PERF_EVENT_READ                 = 8,
-
-       /*
-        * struct {
-        *      struct perf_event_header        header;
-        *
-        *      { u64                   ip;       } && PERF_SAMPLE_IP
-        *      { u32                   pid, tid; } && PERF_SAMPLE_TID
-        *      { u64                   time;     } && PERF_SAMPLE_TIME
-        *      { u64                   addr;     } && PERF_SAMPLE_ADDR
-        *      { u64                   id;       } && PERF_SAMPLE_ID
-        *      { u64                   stream_id;} && PERF_SAMPLE_STREAM_ID
-        *      { u32                   cpu, res; } && PERF_SAMPLE_CPU
-        *      { u64                   period;   } && PERF_SAMPLE_PERIOD
-        *
-        *      { struct read_format    values;   } && PERF_SAMPLE_READ
-        *
-        *      { u64                   nr,
-        *        u64                   ips[nr];  } && PERF_SAMPLE_CALLCHAIN
-        *
-        *      #
-        *      # The RAW record below is opaque data wrt the ABI
-        *      #
-        *      # That is, the ABI doesn't make any promises wrt to
-        *      # the stability of its content, it may vary depending
-        *      # on event, hardware, kernel version and phase of
-        *      # the moon.
-        *      #
-        *      # In other words, PERF_SAMPLE_RAW contents are not an ABI.
-        *      #
-        *
-        *      { u32                   size;
-        *        char                  data[size];}&& PERF_SAMPLE_RAW
-        * };
-        */
-       PERF_EVENT_SAMPLE               = 9,
-
-       PERF_EVENT_MAX,                 /* non-ABI */
-};
-
-enum perf_callchain_context {
-       PERF_CONTEXT_HV                 = (__u64)-32,
-       PERF_CONTEXT_KERNEL             = (__u64)-128,
-       PERF_CONTEXT_USER               = (__u64)-512,
-
-       PERF_CONTEXT_GUEST              = (__u64)-2048,
-       PERF_CONTEXT_GUEST_KERNEL       = (__u64)-2176,
-       PERF_CONTEXT_GUEST_USER         = (__u64)-2560,
-
-       PERF_CONTEXT_MAX                = (__u64)-4095,
-};
-
-#define PERF_FLAG_FD_NO_GROUP          (1U << 0)
-#define PERF_FLAG_FD_OUTPUT            (1U << 1)
-
-/*
- * In case some app still references the old symbols:
- */
-
-#define __NR_perf_counter_open         __NR_perf_event_open
-
-#define PR_TASK_PERF_COUNTERS_DISABLE  PR_TASK_PERF_EVENTS_DISABLE
-#define PR_TASK_PERF_COUNTERS_ENABLE   PR_TASK_PERF_EVENTS_ENABLE
-
-#endif /* _LINUX_PERF_COUNTER_H */
index c4ba9a7..96cc307 100644 (file)
@@ -101,4 +101,9 @@ static inline void exit_rcu(void)
 {
 }
 
+static inline int rcu_preempt_depth(void)
+{
+       return 0;
+}
+
 #endif /* __LINUX_RCUTINY_H */
index c93eee5..8044b1b 100644 (file)
@@ -45,6 +45,12 @@ extern void __rcu_read_unlock(void);
 extern void synchronize_rcu(void);
 extern void exit_rcu(void);
 
+/*
+ * Defined as macro as it is a very low level header
+ * included from areas that don't even know about current
+ */
+#define rcu_preempt_depth() (current->rcu_read_lock_nesting)
+
 #else /* #ifdef CONFIG_TREE_PREEMPT_RCU */
 
 static inline void __rcu_read_lock(void)
@@ -63,6 +69,11 @@ static inline void exit_rcu(void)
 {
 }
 
+static inline int rcu_preempt_depth(void)
+{
+       return 0;
+}
+
 #endif /* #else #ifdef CONFIG_TREE_PREEMPT_RCU */
 
 static inline void __rcu_read_lock_bh(void)
index e898578..f2f842d 100644 (file)
@@ -192,6 +192,12 @@ print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
 #define TASK_DEAD              64
 #define TASK_WAKEKILL          128
 #define TASK_WAKING            256
+#define TASK_STATE_MAX         512
+
+#define TASK_STATE_TO_CHAR_STR "RSDTtZXxKW"
+
+extern char ___assert_task_state[1 - 2*!!(
+               sizeof(TASK_STATE_TO_CHAR_STR)-1 != ilog2(TASK_STATE_MAX)+1)];
 
 /* Convenience macros for the sake of set_task_state */
 #define TASK_KILLABLE          (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)
@@ -1091,7 +1097,8 @@ struct sched_class {
                              enum cpu_idle_type idle);
        void (*pre_schedule) (struct rq *this_rq, struct task_struct *task);
        void (*post_schedule) (struct rq *this_rq);
-       void (*task_wake_up) (struct rq *this_rq, struct task_struct *task);
+       void (*task_waking) (struct rq *this_rq, struct task_struct *task);
+       void (*task_woken) (struct rq *this_rq, struct task_struct *task);
 
        void (*set_cpus_allowed)(struct task_struct *p,
                                 const struct cpumask *newmask);
@@ -1115,7 +1122,7 @@ struct sched_class {
                                         struct task_struct *task);
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
-       void (*moved_group) (struct task_struct *p);
+       void (*moved_group) (struct task_struct *p, int on_rq);
 #endif
 };
 
@@ -2594,8 +2601,6 @@ static inline void mm_init_owner(struct mm_struct *mm, struct task_struct *p)
 }
 #endif /* CONFIG_MM_OWNER */
 
-#define TASK_STATE_TO_CHAR_STR "RSDTtZX"
-
 #endif /* __KERNEL__ */
 
 #endif
index 7394e3b..ff92b46 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/mutex.h>
 #include <linux/timer.h>
 #include <linux/workqueue.h>
+#include <linux/kfifo.h>
 #include <scsi/iscsi_proto.h>
 #include <scsi/iscsi_if.h>
 #include <scsi/scsi_transport_iscsi.h>
@@ -231,7 +232,7 @@ struct iscsi_conn {
 };
 
 struct iscsi_pool {
-       struct kfifo            *queue;         /* FIFO Queue */
+       struct kfifo            queue;          /* FIFO Queue */
        void                    **pool;         /* Pool of elements */
        int                     max;            /* Max number of elements */
 };
index 9e3182e..741ae7e 100644 (file)
@@ -80,7 +80,7 @@ struct iscsi_tcp_task {
        int                     data_offset;
        struct iscsi_r2t_info   *r2t;           /* in progress solict R2T */
        struct iscsi_pool       r2tpool;
-       struct kfifo            *r2tqueue;
+       struct kfifo            r2tqueue;
        void                    *dd_data;
 };
 
index ba615e4..07e3add 100644 (file)
@@ -21,7 +21,7 @@ struct srp_buf {
 struct srp_queue {
        void *pool;
        void *items;
-       struct kfifo *queue;
+       struct kfifo queue;
        spinlock_t lock;
 };
 
index 4c00edc..b37d34b 100644 (file)
@@ -413,7 +413,7 @@ static unsigned my_inptr;   /* index of next byte to be processed in inbuf */
 
 static char * __init unpack_to_rootfs(char *buf, unsigned len)
 {
-       int written;
+       int written, res;
        decompress_fn decompress;
        const char *compress_name;
        static __initdata char msg_buf[64];
@@ -445,10 +445,12 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len)
                }
                this_header = 0;
                decompress = decompress_method(buf, len, &compress_name);
-               if (decompress)
-                       decompress(buf, len, NULL, flush_buffer, NULL,
+               if (decompress) {
+                       res = decompress(buf, len, NULL, flush_buffer, NULL,
                                   &my_inptr, error);
-               else if (compress_name) {
+                       if (res)
+                               error("decompressor failed");
+               } else if (compress_name) {
                        if (!message) {
                                snprintf(msg_buf, sizeof msg_buf,
                                         "compression method %s not configured",
index c3db4a9..dac44a9 100644 (file)
@@ -369,12 +369,6 @@ static void __init smp_init(void)
 {
        unsigned int cpu;
 
-       /*
-        * Set up the current CPU as possible to migrate to.
-        * The other ones will be done by cpu_up/cpu_down()
-        */
-       set_cpu_active(smp_processor_id(), true);
-
        /* FIXME: This should be done in userspace --RR */
        for_each_present_cpu(cpu) {
                if (num_online_cpus() >= setup_max_cpus)
@@ -486,6 +480,7 @@ static void __init boot_cpu_init(void)
        int cpu = smp_processor_id();
        /* Mark the boot cpu "present", "online" etc for SMP and UP case */
        set_cpu_online(cpu, true);
+       set_cpu_active(cpu, true);
        set_cpu_present(cpu, true);
        set_cpu_possible(cpu, true);
 }
index 2451dc6..4b05bd9 100644 (file)
@@ -277,7 +277,7 @@ static void untag_chunk(struct node *p)
                owner->root = NULL;
        }
 
-       for (i = j = 0; i < size; i++, j++) {
+       for (i = j = 0; j <= size; i++, j++) {
                struct audit_tree *s;
                if (&chunk->owners[j] == p) {
                        list_del_init(&p->list);
@@ -290,7 +290,7 @@ static void untag_chunk(struct node *p)
                if (!s) /* result of earlier fallback */
                        continue;
                get_tree(s);
-               list_replace_init(&chunk->owners[i].list, &new->owners[j].list);
+               list_replace_init(&chunk->owners[j].list, &new->owners[i].list);
        }
 
        list_replace_rcu(&chunk->hash, &new->hash);
@@ -373,15 +373,17 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
        for (n = 0; n < old->count; n++) {
                if (old->owners[n].owner == tree) {
                        spin_unlock(&hash_lock);
-                       put_inotify_watch(watch);
+                       put_inotify_watch(&old->watch);
                        return 0;
                }
        }
        spin_unlock(&hash_lock);
 
        chunk = alloc_chunk(old->count + 1);
-       if (!chunk)
+       if (!chunk) {
+               put_inotify_watch(&old->watch);
                return -ENOMEM;
+       }
 
        mutex_lock(&inode->inotify_mutex);
        if (inotify_clone_watch(&old->watch, &chunk->watch) < 0) {
@@ -425,7 +427,8 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
        spin_unlock(&hash_lock);
        inotify_evict_watch(&old->watch);
        mutex_unlock(&inode->inotify_mutex);
-       put_inotify_watch(&old->watch);
+       put_inotify_watch(&old->watch); /* pair to inotify_find_watch */
+       put_inotify_watch(&old->watch); /* and kill it */
        return 0;
 }
 
index 291ac58..1c8ddd6 100644 (file)
@@ -209,6 +209,7 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
                return -ENOMEM;
 
        cpu_hotplug_begin();
+       set_cpu_active(cpu, false);
        err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,
                                        hcpu, -1, &nr_calls);
        if (err == NOTIFY_BAD) {
@@ -280,18 +281,6 @@ int __ref cpu_down(unsigned int cpu)
                goto out;
        }
 
-       set_cpu_active(cpu, false);
-
-       /*
-        * Make sure the all cpus did the reschedule and are not
-        * using stale version of the cpu_active_mask.
-        * This is not strictly necessary becuase stop_machine()
-        * that we run down the line already provides the required
-        * synchronization. But it's really a side effect and we do not
-        * want to depend on the innards of the stop_machine here.
-        */
-       synchronize_sched();
-
        err = _cpu_down(cpu, 0);
 
 out:
@@ -382,19 +371,12 @@ int disable_nonboot_cpus(void)
                return error;
        cpu_maps_update_begin();
        first_cpu = cpumask_first(cpu_online_mask);
-       /* We take down all of the non-boot CPUs in one shot to avoid races
+       /*
+        * We take down all of the non-boot CPUs in one shot to avoid races
         * with the userspace trying to use the CPU hotplug at the same time
         */
        cpumask_clear(frozen_cpus);
 
-       for_each_online_cpu(cpu) {
-               if (cpu == first_cpu)
-                       continue;
-               set_cpu_active(cpu, false);
-       }
-
-       synchronize_sched();
-
        printk("Disabling non-boot CPUs ...\n");
        for_each_online_cpu(cpu) {
                if (cpu == first_cpu)
index 3765ff3..e92d519 100644 (file)
@@ -1,6 +1,7 @@
 /*
- * A simple kernel FIFO implementation.
+ * A generic kernel FIFO implementation.
  *
+ * Copyright (C) 2009 Stefani Seibold <stefani@seibold.net>
  * Copyright (C) 2004 Stelian Pop <stelian@popies.net>
  *
  * This program is free software; you can redistribute it and/or modify
 #include <linux/err.h>
 #include <linux/kfifo.h>
 #include <linux/log2.h>
+#include <linux/uaccess.h>
+
+static void _kfifo_init(struct kfifo *fifo, unsigned char *buffer,
+               unsigned int size)
+{
+       fifo->buffer = buffer;
+       fifo->size = size;
+
+       kfifo_reset(fifo);
+}
 
 /**
- * kfifo_init - allocates a new FIFO using a preallocated buffer
+ * kfifo_init - initialize a FIFO using a preallocated buffer
+ * @fifo: the fifo to assign the buffer
  * @buffer: the preallocated buffer to be used.
  * @size: the size of the internal buffer, this have to be a power of 2.
- * @gfp_mask: get_free_pages mask, passed to kmalloc()
- * @lock: the lock to be used to protect the fifo buffer
  *
- * Do NOT pass the kfifo to kfifo_free() after use! Simply free the
- * &struct kfifo with kfree().
  */
-struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size,
-                        gfp_t gfp_mask, spinlock_t *lock)
+void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size)
 {
-       struct kfifo *fifo;
-
        /* size must be a power of 2 */
        BUG_ON(!is_power_of_2(size));
 
-       fifo = kmalloc(sizeof(struct kfifo), gfp_mask);
-       if (!fifo)
-               return ERR_PTR(-ENOMEM);
-
-       fifo->buffer = buffer;
-       fifo->size = size;
-       fifo->in = fifo->out = 0;
-       fifo->lock = lock;
-
-       return fifo;
+       _kfifo_init(fifo, buffer, size);
 }
 EXPORT_SYMBOL(kfifo_init);
 
 /**
- * kfifo_alloc - allocates a new FIFO and its internal buffer
- * @size: the size of the internal buffer to be allocated.
+ * kfifo_alloc - allocates a new FIFO internal buffer
+ * @fifo: the fifo to assign then new buffer
+ * @size: the size of the buffer to be allocated, this have to be a power of 2.
  * @gfp_mask: get_free_pages mask, passed to kmalloc()
- * @lock: the lock to be used to protect the fifo buffer
+ *
+ * This function dynamically allocates a new fifo internal buffer
  *
  * The size will be rounded-up to a power of 2.
+ * The buffer will be release with kfifo_free().
+ * Return 0 if no error, otherwise the an error code
  */
-struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock)
+int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask)
 {
        unsigned char *buffer;
-       struct kfifo *ret;
 
        /*
         * round up to the next power of 2, since our 'let the indices
@@ -80,48 +79,91 @@ struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock)
        }
 
        buffer = kmalloc(size, gfp_mask);
-       if (!buffer)
-               return ERR_PTR(-ENOMEM);
-
-       ret = kfifo_init(buffer, size, gfp_mask, lock);
+       if (!buffer) {
+               _kfifo_init(fifo, 0, 0);
+               return -ENOMEM;
+       }
 
-       if (IS_ERR(ret))
-               kfree(buffer);
+       _kfifo_init(fifo, buffer, size);
 
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL(kfifo_alloc);
 
 /**
- * kfifo_free - frees the FIFO
+ * kfifo_free - frees the FIFO internal buffer
  * @fifo: the fifo to be freed.
  */
 void kfifo_free(struct kfifo *fifo)
 {
        kfree(fifo->buffer);
-       kfree(fifo);
 }
 EXPORT_SYMBOL(kfifo_free);
 
 /**
- * __kfifo_put - puts some data into the FIFO, no locking version
+ * kfifo_skip - skip output data
  * @fifo: the fifo to be used.
- * @buffer: the data to be added.
- * @len: the length of the data to be added.
- *
- * This function copies at most @len bytes from the @buffer into
- * the FIFO depending on the free space, and returns the number of
- * bytes copied.
- *
- * Note that with only one concurrent reader and one concurrent
- * writer, you don't need extra locking to use these functions.
+ * @len: number of bytes to skip
  */
-unsigned int __kfifo_put(struct kfifo *fifo,
-                       const unsigned char *buffer, unsigned int len)
+void kfifo_skip(struct kfifo *fifo, unsigned int len)
+{
+       if (len < kfifo_len(fifo)) {
+               __kfifo_add_out(fifo, len);
+               return;
+       }
+       kfifo_reset_out(fifo);
+}
+EXPORT_SYMBOL(kfifo_skip);
+
+static inline void __kfifo_in_data(struct kfifo *fifo,
+               const void *from, unsigned int len, unsigned int off)
 {
        unsigned int l;
 
-       len = min(len, fifo->size - fifo->in + fifo->out);
+       /*
+        * Ensure that we sample the fifo->out index -before- we
+        * start putting bytes into the kfifo.
+        */
+
+       smp_mb();
+
+       off = __kfifo_off(fifo, fifo->in + off);
+
+       /* first put the data starting from fifo->in to buffer end */
+       l = min(len, fifo->size - off);
+       memcpy(fifo->buffer + off, from, l);
+
+       /* then put the rest (if any) at the beginning of the buffer */
+       memcpy(fifo->buffer, from + l, len - l);
+}
+
+static inline void __kfifo_out_data(struct kfifo *fifo,
+               void *to, unsigned int len, unsigned int off)
+{
+       unsigned int l;
+
+       /*
+        * Ensure that we sample the fifo->in index -before- we
+        * start removing bytes from the kfifo.
+        */
+
+       smp_rmb();
+
+       off = __kfifo_off(fifo, fifo->out + off);
+
+       /* first get the data from fifo->out until the end of the buffer */
+       l = min(len, fifo->size - off);
+       memcpy(to, fifo->buffer + off, l);
+
+       /* then get the rest (if any) from the beginning of the buffer */
+       memcpy(to + l, fifo->buffer, len - l);
+}
+
+static inline unsigned int __kfifo_from_user_data(struct kfifo *fifo,
+        const void __user *from, unsigned int len, unsigned int off)
+{
+       unsigned int l;
+       int ret;
 
        /*
         * Ensure that we sample the fifo->out index -before- we
@@ -130,68 +172,229 @@ unsigned int __kfifo_put(struct kfifo *fifo,
 
        smp_mb();
 
+       off = __kfifo_off(fifo, fifo->in + off);
+
        /* first put the data starting from fifo->in to buffer end */
-       l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
-       memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);
+       l = min(len, fifo->size - off);
+       ret = copy_from_user(fifo->buffer + off, from, l);
+
+       if (unlikely(ret))
+               return ret + len - l;
 
        /* then put the rest (if any) at the beginning of the buffer */
-       memcpy(fifo->buffer, buffer + l, len - l);
+       return copy_from_user(fifo->buffer, from + l, len - l);
+}
+
+static inline unsigned int __kfifo_to_user_data(struct kfifo *fifo,
+               void __user *to, unsigned int len, unsigned int off)
+{
+       unsigned int l;
+       int ret;
 
        /*
-        * Ensure that we add the bytes to the kfifo -before-
-        * we update the fifo->in index.
+        * Ensure that we sample the fifo->in index -before- we
+        * start removing bytes from the kfifo.
         */
 
-       smp_wmb();
+       smp_rmb();
+
+       off = __kfifo_off(fifo, fifo->out + off);
+
+       /* first get the data from fifo->out until the end of the buffer */
+       l = min(len, fifo->size - off);
+       ret = copy_to_user(to, fifo->buffer + off, l);
+
+       if (unlikely(ret))
+               return ret + len - l;
+
+       /* then get the rest (if any) from the beginning of the buffer */
+       return copy_to_user(to + l, fifo->buffer, len - l);
+}
+
+unsigned int __kfifo_in_n(struct kfifo *fifo,
+       const void *from, unsigned int len, unsigned int recsize)
+{
+       if (kfifo_avail(fifo) < len + recsize)
+               return len + 1;
+
+       __kfifo_in_data(fifo, from, len, recsize);
+       return 0;
+}
+EXPORT_SYMBOL(__kfifo_in_n);
 
-       fifo->in += len;
+/**
+ * kfifo_in - puts some data into the FIFO
+ * @fifo: the fifo to be used.
+ * @from: the data to be added.
+ * @len: the length of the data to be added.
+ *
+ * This function copies at most @len bytes from the @from buffer into
+ * the FIFO depending on the free space, and returns the number of
+ * bytes copied.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_in(struct kfifo *fifo, const unsigned char *from,
+                               unsigned int len)
+{
+       len = min(kfifo_avail(fifo), len);
 
+       __kfifo_in_data(fifo, from, len, 0);
+       __kfifo_add_in(fifo, len);
        return len;
 }
-EXPORT_SYMBOL(__kfifo_put);
+EXPORT_SYMBOL(kfifo_in);
+
+unsigned int __kfifo_in_generic(struct kfifo *fifo,
+       const void *from, unsigned int len, unsigned int recsize)
+{
+       return __kfifo_in_rec(fifo, from, len, recsize);
+}
+EXPORT_SYMBOL(__kfifo_in_generic);
+
+unsigned int __kfifo_out_n(struct kfifo *fifo,
+       void *to, unsigned int len, unsigned int recsize)
+{
+       if (kfifo_len(fifo) < len + recsize)
+               return len;
+
+       __kfifo_out_data(fifo, to, len, recsize);
+       __kfifo_add_out(fifo, len + recsize);
+       return 0;
+}
+EXPORT_SYMBOL(__kfifo_out_n);
 
 /**
- * __kfifo_get - gets some data from the FIFO, no locking version
+ * kfifo_out - gets some data from the FIFO
  * @fifo: the fifo to be used.
- * @buffer: where the data must be copied.
+ * @to: where the data must be copied.
  * @len: the size of the destination buffer.
  *
  * This function copies at most @len bytes from the FIFO into the
- * @buffer and returns the number of copied bytes.
+ * @to buffer and returns the number of copied bytes.
  *
  * Note that with only one concurrent reader and one concurrent
  * writer, you don't need extra locking to use these functions.
  */
-unsigned int __kfifo_get(struct kfifo *fifo,
-                        unsigned char *buffer, unsigned int len)
+unsigned int kfifo_out(struct kfifo *fifo, unsigned char *to, unsigned int len)
 {
-       unsigned int l;
+       len = min(kfifo_len(fifo), len);
 
-       len = min(len, fifo->in - fifo->out);
+       __kfifo_out_data(fifo, to, len, 0);
+       __kfifo_add_out(fifo, len);
 
-       /*
-        * Ensure that we sample the fifo->in index -before- we
-        * start removing bytes from the kfifo.
-        */
+       return len;
+}
+EXPORT_SYMBOL(kfifo_out);
 
-       smp_rmb();
+unsigned int __kfifo_out_generic(struct kfifo *fifo,
+       void *to, unsigned int len, unsigned int recsize,
+       unsigned int *total)
+{
+       return __kfifo_out_rec(fifo, to, len, recsize, total);
+}
+EXPORT_SYMBOL(__kfifo_out_generic);
 
-       /* first get the data from fifo->out until the end of the buffer */
-       l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
-       memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
+unsigned int __kfifo_from_user_n(struct kfifo *fifo,
+       const void __user *from, unsigned int len, unsigned int recsize)
+{
+       if (kfifo_avail(fifo) < len + recsize)
+               return len + 1;
 
-       /* then get the rest (if any) from the beginning of the buffer */
-       memcpy(buffer + l, fifo->buffer, len - l);
+       return __kfifo_from_user_data(fifo, from, len, recsize);
+}
+EXPORT_SYMBOL(__kfifo_from_user_n);
 
-       /*
-        * Ensure that we remove the bytes from the kfifo -before-
-        * we update the fifo->out index.
-        */
+/**
+ * kfifo_from_user - puts some data from user space into the FIFO
+ * @fifo: the fifo to be used.
+ * @from: pointer to the data to be added.
+ * @len: the length of the data to be added.
+ *
+ * This function copies at most @len bytes from the @from into the
+ * FIFO depending and returns the number of copied bytes.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_from_user(struct kfifo *fifo,
+       const void __user *from, unsigned int len)
+{
+       len = min(kfifo_avail(fifo), len);
+       len -= __kfifo_from_user_data(fifo, from, len, 0);
+       __kfifo_add_in(fifo, len);
+       return len;
+}
+EXPORT_SYMBOL(kfifo_from_user);
 
-       smp_mb();
+unsigned int __kfifo_from_user_generic(struct kfifo *fifo,
+       const void __user *from, unsigned int len, unsigned int recsize)
+{
+       return __kfifo_from_user_rec(fifo, from, len, recsize);
+}
+EXPORT_SYMBOL(__kfifo_from_user_generic);
 
-       fifo->out += len;
+unsigned int __kfifo_to_user_n(struct kfifo *fifo,
+       void __user *to, unsigned int len, unsigned int reclen,
+       unsigned int recsize)
+{
+       unsigned int ret;
+
+       if (kfifo_len(fifo) < reclen + recsize)
+               return len;
+
+       ret = __kfifo_to_user_data(fifo, to, reclen, recsize);
 
+       if (likely(ret == 0))
+               __kfifo_add_out(fifo, reclen + recsize);
+
+       return ret;
+}
+EXPORT_SYMBOL(__kfifo_to_user_n);
+
+/**
+ * kfifo_to_user - gets data from the FIFO and write it to user space
+ * @fifo: the fifo to be used.
+ * @to: where the data must be copied.
+ * @len: the size of the destination buffer.
+ *
+ * This function copies at most @len bytes from the FIFO into the
+ * @to buffer and returns the number of copied bytes.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_to_user(struct kfifo *fifo,
+       void __user *to, unsigned int len)
+{
+       len = min(kfifo_len(fifo), len);
+       len -= __kfifo_to_user_data(fifo, to, len, 0);
+       __kfifo_add_out(fifo, len);
        return len;
 }
-EXPORT_SYMBOL(__kfifo_get);
+EXPORT_SYMBOL(kfifo_to_user);
+
+unsigned int __kfifo_to_user_generic(struct kfifo *fifo,
+       void __user *to, unsigned int len, unsigned int recsize,
+       unsigned int *total)
+{
+       return __kfifo_to_user_rec(fifo, to, len, recsize, total);
+}
+EXPORT_SYMBOL(__kfifo_to_user_generic);
+
+unsigned int __kfifo_peek_generic(struct kfifo *fifo, unsigned int recsize)
+{
+       if (recsize == 0)
+               return kfifo_avail(fifo);
+
+       return __kfifo_peek_n(fifo, recsize);
+}
+EXPORT_SYMBOL(__kfifo_peek_generic);
+
+void __kfifo_skip_generic(struct kfifo *fifo, unsigned int recsize)
+{
+       __kfifo_skip_rec(fifo, recsize);
+}
+EXPORT_SYMBOL(__kfifo_skip_generic);
+
index ab7ae57..fbb6222 100644 (file)
@@ -150,6 +150,29 @@ struct task_struct *kthread_create(int (*threadfn)(void *data),
 EXPORT_SYMBOL(kthread_create);
 
 /**
+ * kthread_bind - bind a just-created kthread to a cpu.
+ * @p: thread created by kthread_create().
+ * @cpu: cpu (might not be online, must be possible) for @k to run on.
+ *
+ * Description: This function is equivalent to set_cpus_allowed(),
+ * except that @cpu doesn't need to be online, and the thread must be
+ * stopped (i.e., just returned from kthread_create()).
+ */
+void kthread_bind(struct task_struct *p, unsigned int cpu)
+{
+       /* Must have done schedule() in kthread() before we set_task_cpu */
+       if (!wait_task_inactive(p, TASK_UNINTERRUPTIBLE)) {
+               WARN_ON(1);
+               return;
+       }
+
+       p->cpus_allowed = cpumask_of_cpu(cpu);
+       p->rt.nr_cpus_allowed = 1;
+       p->flags |= PF_THREAD_BOUND;
+}
+EXPORT_SYMBOL(kthread_bind);
+
+/**
  * kthread_stop - stop a thread created by kthread_create().
  * @k: thread created by kthread_create().
  *
index 97d1a3d..e0eb4a2 100644 (file)
@@ -1381,6 +1381,9 @@ static void perf_ctx_adjust_freq(struct perf_event_context *ctx)
                if (event->state != PERF_EVENT_STATE_ACTIVE)
                        continue;
 
+               if (event->cpu != -1 && event->cpu != smp_processor_id())
+                       continue;
+
                hwc = &event->hw;
 
                interrupts = hwc->interrupts;
@@ -3265,6 +3268,9 @@ static void perf_event_task_output(struct perf_event *event,
 
 static int perf_event_task_match(struct perf_event *event)
 {
+       if (event->cpu != -1 && event->cpu != smp_processor_id())
+               return 0;
+
        if (event->attr.comm || event->attr.mmap || event->attr.task)
                return 1;
 
@@ -3290,12 +3296,11 @@ static void perf_event_task_event(struct perf_task_event *task_event)
        rcu_read_lock();
        cpuctx = &get_cpu_var(perf_cpu_context);
        perf_event_task_ctx(&cpuctx->ctx, task_event);
-       put_cpu_var(perf_cpu_context);
-
        if (!ctx)
                ctx = rcu_dereference(task_event->task->perf_event_ctxp);
        if (ctx)
                perf_event_task_ctx(ctx, task_event);
+       put_cpu_var(perf_cpu_context);
        rcu_read_unlock();
 }
 
@@ -3372,6 +3377,9 @@ static void perf_event_comm_output(struct perf_event *event,
 
 static int perf_event_comm_match(struct perf_event *event)
 {
+       if (event->cpu != -1 && event->cpu != smp_processor_id())
+               return 0;
+
        if (event->attr.comm)
                return 1;
 
@@ -3408,15 +3416,10 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event)
        rcu_read_lock();
        cpuctx = &get_cpu_var(perf_cpu_context);
        perf_event_comm_ctx(&cpuctx->ctx, comm_event);
-       put_cpu_var(perf_cpu_context);
-
-       /*
-        * doesn't really matter which of the child contexts the
-        * events ends up in.
-        */
        ctx = rcu_dereference(current->perf_event_ctxp);
        if (ctx)
                perf_event_comm_ctx(ctx, comm_event);
+       put_cpu_var(perf_cpu_context);
        rcu_read_unlock();
 }
 
@@ -3491,6 +3494,9 @@ static void perf_event_mmap_output(struct perf_event *event,
 static int perf_event_mmap_match(struct perf_event *event,
                                   struct perf_mmap_event *mmap_event)
 {
+       if (event->cpu != -1 && event->cpu != smp_processor_id())
+               return 0;
+
        if (event->attr.mmap)
                return 1;
 
@@ -3564,15 +3570,10 @@ got_name:
        rcu_read_lock();
        cpuctx = &get_cpu_var(perf_cpu_context);
        perf_event_mmap_ctx(&cpuctx->ctx, mmap_event);
-       put_cpu_var(perf_cpu_context);
-
-       /*
-        * doesn't really matter which of the child contexts the
-        * events ends up in.
-        */
        ctx = rcu_dereference(current->perf_event_ctxp);
        if (ctx)
                perf_event_mmap_ctx(ctx, mmap_event);
+       put_cpu_var(perf_cpu_context);
        rcu_read_unlock();
 
        kfree(buf);
@@ -3863,6 +3864,9 @@ static int perf_swevent_match(struct perf_event *event,
                                struct perf_sample_data *data,
                                struct pt_regs *regs)
 {
+       if (event->cpu != -1 && event->cpu != smp_processor_id())
+               return 0;
+
        if (!perf_swevent_is_counting(event))
                return 0;
 
index dc15686..af96c1e 100644 (file)
@@ -308,37 +308,37 @@ static int find_resource(struct resource *root, struct resource *new,
                         void *alignf_data)
 {
        struct resource *this = root->child;
-       resource_size_t start, end;
+       struct resource tmp = *new;
 
-       start = root->start;
+       tmp.start = root->start;
        /*
         * Skip past an allocated resource that starts at 0, since the assignment
-        * of this->start - 1 to new->end below would cause an underflow.
+        * of this->start - 1 to tmp->end below would cause an underflow.
         */
        if (this && this->start == 0) {
-               start = this->end + 1;
+               tmp.start = this->end + 1;
                this = this->sibling;
        }
        for(;;) {
                if (this)
-                       end = this->start - 1;
+                       tmp.end = this->start - 1;
                else
-                       end = root->end;
-               if (start < min)
-                       start = min;
-               if (end > max)
-                       end = max;
-               start = ALIGN(start, align);
+                       tmp.end = root->end;
+               if (tmp.start < min)
+                       tmp.start = min;
+               if (tmp.end > max)
+                       tmp.end = max;
+               tmp.start = ALIGN(tmp.start, align);
                if (alignf)
-                       alignf(alignf_data, new, size, align);
-               if (start < end && end - start >= size - 1) {
-                       new->start = start;
-                       new->end = start + size - 1;
+                       alignf(alignf_data, &tmp, size, align);
+               if (tmp.start < tmp.end && tmp.end - tmp.start >= size - 1) {
+                       new->start = tmp.start;
+                       new->end = tmp.start + size - 1;
                        return 0;
                }
                if (!this)
                        break;
-               start = this->end + 1;
+               tmp.start = this->end + 1;
                this = this->sibling;
        }
        return -EBUSY;
index 18cceee..87f1f47 100644 (file)
@@ -2002,39 +2002,6 @@ static inline void check_class_changed(struct rq *rq, struct task_struct *p,
                p->sched_class->prio_changed(rq, p, oldprio, running);
 }
 
-/**
- * kthread_bind - bind a just-created kthread to a cpu.
- * @p: thread created by kthread_create().
- * @cpu: cpu (might not be online, must be possible) for @k to run on.
- *
- * Description: This function is equivalent to set_cpus_allowed(),
- * except that @cpu doesn't need to be online, and the thread must be
- * stopped (i.e., just returned from kthread_create()).
- *
- * Function lives here instead of kthread.c because it messes with
- * scheduler internals which require locking.
- */
-void kthread_bind(struct task_struct *p, unsigned int cpu)
-{
-       struct rq *rq = cpu_rq(cpu);
-       unsigned long flags;
-
-       /* Must have done schedule() in kthread() before we set_task_cpu */
-       if (!wait_task_inactive(p, TASK_UNINTERRUPTIBLE)) {
-               WARN_ON(1);
-               return;
-       }
-
-       raw_spin_lock_irqsave(&rq->lock, flags);
-       update_rq_clock(rq);
-       set_task_cpu(p, cpu);
-       p->cpus_allowed = cpumask_of_cpu(cpu);
-       p->rt.nr_cpus_allowed = 1;
-       p->flags |= PF_THREAD_BOUND;
-       raw_spin_unlock_irqrestore(&rq->lock, flags);
-}
-EXPORT_SYMBOL(kthread_bind);
-
 #ifdef CONFIG_SMP
 /*
  * Is this task likely cache-hot:
@@ -2044,6 +2011,9 @@ task_hot(struct task_struct *p, u64 now, struct sched_domain *sd)
 {
        s64 delta;
 
+       if (p->sched_class != &fair_sched_class)
+               return 0;
+
        /*
         * Buddy candidates are cache hot:
         */
@@ -2052,9 +2022,6 @@ task_hot(struct task_struct *p, u64 now, struct sched_domain *sd)
                         &p->se == cfs_rq_of(&p->se)->last))
                return 1;
 
-       if (p->sched_class != &fair_sched_class)
-               return 0;
-
        if (sysctl_sched_migration_cost == -1)
                return 1;
        if (sysctl_sched_migration_cost == 0)
@@ -2065,22 +2032,24 @@ task_hot(struct task_struct *p, u64 now, struct sched_domain *sd)
        return delta < (s64)sysctl_sched_migration_cost;
 }
 
-
 void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
 {
-       int old_cpu = task_cpu(p);
-       struct cfs_rq *old_cfsrq = task_cfs_rq(p),
-                     *new_cfsrq = cpu_cfs_rq(old_cfsrq, new_cpu);
+#ifdef CONFIG_SCHED_DEBUG
+       /*
+        * We should never call set_task_cpu() on a blocked task,
+        * ttwu() will sort out the placement.
+        */
+       WARN_ON_ONCE(p->state != TASK_RUNNING && p->state != TASK_WAKING &&
+                       !(task_thread_info(p)->preempt_count & PREEMPT_ACTIVE));
+#endif
 
        trace_sched_migrate_task(p, new_cpu);
 
-       if (old_cpu != new_cpu) {
-               p->se.nr_migrations++;
-               perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS,
-                                    1, 1, NULL, 0);
-       }
-       p->se.vruntime -= old_cfsrq->min_vruntime -
-                                        new_cfsrq->min_vruntime;
+       if (task_cpu(p) == new_cpu)
+               return;
+
+       p->se.nr_migrations++;
+       perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS, 1, 1, NULL, 0);
 
        __set_task_cpu(p, new_cpu);
 }
@@ -2105,13 +2074,10 @@ migrate_task(struct task_struct *p, int dest_cpu, struct migration_req *req)
 
        /*
         * If the task is not on a runqueue (and not running), then
-        * it is sufficient to simply update the task's cpu field.
+        * the next wake-up will properly place the task.
         */
-       if (!p->se.on_rq && !task_running(rq, p)) {
-               update_rq_clock(rq);
-               set_task_cpu(p, dest_cpu);
+       if (!p->se.on_rq && !task_running(rq, p))
                return 0;
-       }
 
        init_completion(&req->done);
        req->task = p;
@@ -2317,10 +2283,73 @@ void task_oncpu_function_call(struct task_struct *p,
 }
 
 #ifdef CONFIG_SMP
+static int select_fallback_rq(int cpu, struct task_struct *p)
+{
+       int dest_cpu;
+       const struct cpumask *nodemask = cpumask_of_node(cpu_to_node(cpu));
+
+       /* Look for allowed, online CPU in same node. */
+       for_each_cpu_and(dest_cpu, nodemask, cpu_active_mask)
+               if (cpumask_test_cpu(dest_cpu, &p->cpus_allowed))
+                       return dest_cpu;
+
+       /* Any allowed, online CPU? */
+       dest_cpu = cpumask_any_and(&p->cpus_allowed, cpu_active_mask);
+       if (dest_cpu < nr_cpu_ids)
+               return dest_cpu;
+
+       /* No more Mr. Nice Guy. */
+       if (dest_cpu >= nr_cpu_ids) {
+               rcu_read_lock();
+               cpuset_cpus_allowed_locked(p, &p->cpus_allowed);
+               rcu_read_unlock();
+               dest_cpu = cpumask_any_and(cpu_active_mask, &p->cpus_allowed);
+
+               /*
+                * Don't tell them about moving exiting tasks or
+                * kernel threads (both mm NULL), since they never
+                * leave kernel.
+                */
+               if (p->mm && printk_ratelimit()) {
+                       printk(KERN_INFO "process %d (%s) no "
+                              "longer affine to cpu%d\n",
+                              task_pid_nr(p), p->comm, cpu);
+               }
+       }
+
+       return dest_cpu;
+}
+
+/*
+ * Called from:
+ *
+ *  - fork, @p is stable because it isn't on the tasklist yet
+ *
+ *  - exec, @p is unstable, retry loop
+ *
+ *  - wake-up, we serialize ->cpus_allowed against TASK_WAKING so
+ *             we should be good.
+ */
 static inline
 int select_task_rq(struct task_struct *p, int sd_flags, int wake_flags)
 {
-       return p->sched_class->select_task_rq(p, sd_flags, wake_flags);
+       int cpu = p->sched_class->select_task_rq(p, sd_flags, wake_flags);
+
+       /*
+        * In order not to call set_task_cpu() on a blocking task we need
+        * to rely on ttwu() to place the task on a valid ->cpus_allowed
+        * cpu.
+        *
+        * Since this is common to all placement strategies, this lives here.
+        *
+        * [ this allows ->select_task() to simply return task_cpu(p) and
+        *   not worry about this generic constraint ]
+        */
+       if (unlikely(!cpumask_test_cpu(cpu, &p->cpus_allowed) ||
+                    !cpu_online(cpu)))
+               cpu = select_fallback_rq(task_cpu(p), p);
+
+       return cpu;
 }
 #endif
 
@@ -2375,6 +2404,10 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
        if (task_contributes_to_load(p))
                rq->nr_uninterruptible--;
        p->state = TASK_WAKING;
+
+       if (p->sched_class->task_waking)
+               p->sched_class->task_waking(rq, p);
+
        __task_rq_unlock(rq);
 
        cpu = select_task_rq(p, SD_BALANCE_WAKE, wake_flags);
@@ -2438,8 +2471,8 @@ out_running:
 
        p->state = TASK_RUNNING;
 #ifdef CONFIG_SMP
-       if (p->sched_class->task_wake_up)
-               p->sched_class->task_wake_up(rq, p);
+       if (p->sched_class->task_woken)
+               p->sched_class->task_woken(rq, p);
 
        if (unlikely(rq->idle_stamp)) {
                u64 delta = rq->clock - rq->idle_stamp;
@@ -2538,14 +2571,6 @@ static void __sched_fork(struct task_struct *p)
 #ifdef CONFIG_PREEMPT_NOTIFIERS
        INIT_HLIST_HEAD(&p->preempt_notifiers);
 #endif
-
-       /*
-        * We mark the process as running here, but have not actually
-        * inserted it onto the runqueue yet. This guarantees that
-        * nobody will actually run it, and a signal or other external
-        * event cannot wake it up and insert it on the runqueue either.
-        */
-       p->state = TASK_RUNNING;
 }
 
 /*
@@ -2556,6 +2581,12 @@ void sched_fork(struct task_struct *p, int clone_flags)
        int cpu = get_cpu();
 
        __sched_fork(p);
+       /*
+        * We mark the process as waking here. This guarantees that
+        * nobody will actually run it, and a signal or other external
+        * event cannot wake it up and insert it on the runqueue either.
+        */
+       p->state = TASK_WAKING;
 
        /*
         * Revert to default priority/policy on fork if requested.
@@ -2624,14 +2655,15 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
        struct rq *rq;
 
        rq = task_rq_lock(p, &flags);
-       BUG_ON(p->state != TASK_RUNNING);
+       BUG_ON(p->state != TASK_WAKING);
+       p->state = TASK_RUNNING;
        update_rq_clock(rq);
        activate_task(rq, p, 0);
        trace_sched_wakeup_new(rq, p, 1);
        check_preempt_curr(rq, p, WF_FORK);
 #ifdef CONFIG_SMP
-       if (p->sched_class->task_wake_up)
-               p->sched_class->task_wake_up(rq, p);
+       if (p->sched_class->task_woken)
+               p->sched_class->task_woken(rq, p);
 #endif
        task_rq_unlock(rq, &flags);
 }
@@ -3101,21 +3133,36 @@ static void double_rq_unlock(struct rq *rq1, struct rq *rq2)
 }
 
 /*
- * If dest_cpu is allowed for this process, migrate the task to it.
- * This is accomplished by forcing the cpu_allowed mask to only
- * allow dest_cpu, which will force the cpu onto dest_cpu. Then
- * the cpu_allowed mask is restored.
+ * sched_exec - execve() is a valuable balancing opportunity, because at
+ * this point the task has the smallest effective memory and cache footprint.
  */
-static void sched_migrate_task(struct task_struct *p, int dest_cpu)
+void sched_exec(void)
 {
+       struct task_struct *p = current;
        struct migration_req req;
+       int dest_cpu, this_cpu;
        unsigned long flags;
        struct rq *rq;
 
+again:
+       this_cpu = get_cpu();
+       dest_cpu = select_task_rq(p, SD_BALANCE_EXEC, 0);
+       if (dest_cpu == this_cpu) {
+               put_cpu();
+               return;
+       }
+
        rq = task_rq_lock(p, &flags);
+       put_cpu();
+
+       /*
+        * select_task_rq() can race against ->cpus_allowed
+        */
        if (!cpumask_test_cpu(dest_cpu, &p->cpus_allowed)
-           || unlikely(!cpu_active(dest_cpu)))
-               goto out;
+           || unlikely(!cpu_active(dest_cpu))) {
+               task_rq_unlock(rq, &flags);
+               goto again;
+       }
 
        /* force the process onto the specified CPU */
        if (migrate_task(p, dest_cpu, &req)) {
@@ -3130,24 +3177,10 @@ static void sched_migrate_task(struct task_struct *p, int dest_cpu)
 
                return;
        }
-out:
        task_rq_unlock(rq, &flags);
 }
 
 /*
- * sched_exec - execve() is a valuable balancing opportunity, because at
- * this point the task has the smallest effective memory and cache footprint.
- */
-void sched_exec(void)
-{
-       int new_cpu, this_cpu = get_cpu();
-       new_cpu = select_task_rq(current, SD_BALANCE_EXEC, 0);
-       put_cpu();
-       if (new_cpu != this_cpu)
-               sched_migrate_task(current, new_cpu);
-}
-
-/*
  * pull_task - move a task from a remote runqueue to the local runqueue.
  * Both runqueues must be locked.
  */
@@ -5911,14 +5944,15 @@ EXPORT_SYMBOL(wait_for_completion_killable);
  */
 bool try_wait_for_completion(struct completion *x)
 {
+       unsigned long flags;
        int ret = 1;
 
-       spin_lock_irq(&x->wait.lock);
+       spin_lock_irqsave(&x->wait.lock, flags);
        if (!x->done)
                ret = 0;
        else
                x->done--;
-       spin_unlock_irq(&x->wait.lock);
+       spin_unlock_irqrestore(&x->wait.lock, flags);
        return ret;
 }
 EXPORT_SYMBOL(try_wait_for_completion);
@@ -5933,12 +5967,13 @@ EXPORT_SYMBOL(try_wait_for_completion);
  */
 bool completion_done(struct completion *x)
 {
+       unsigned long flags;
        int ret = 1;
 
-       spin_lock_irq(&x->wait.lock);
+       spin_lock_irqsave(&x->wait.lock, flags);
        if (!x->done)
                ret = 0;
-       spin_unlock_irq(&x->wait.lock);
+       spin_unlock_irqrestore(&x->wait.lock, flags);
        return ret;
 }
 EXPORT_SYMBOL(completion_done);
@@ -6457,7 +6492,7 @@ SYSCALL_DEFINE1(sched_getscheduler, pid_t, pid)
                return -EINVAL;
 
        retval = -ESRCH;
-       read_lock(&tasklist_lock);
+       rcu_read_lock();
        p = find_process_by_pid(pid);
        if (p) {
                retval = security_task_getscheduler(p);
@@ -6465,7 +6500,7 @@ SYSCALL_DEFINE1(sched_getscheduler, pid_t, pid)
                        retval = p->policy
                                | (p->sched_reset_on_fork ? SCHED_RESET_ON_FORK : 0);
        }
-       read_unlock(&tasklist_lock);
+       rcu_read_unlock();
        return retval;
 }
 
@@ -6483,7 +6518,7 @@ SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param)
        if (!param || pid < 0)
                return -EINVAL;
 
-       read_lock(&tasklist_lock);
+       rcu_read_lock();
        p = find_process_by_pid(pid);
        retval = -ESRCH;
        if (!p)
@@ -6494,7 +6529,7 @@ SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param)
                goto out_unlock;
 
        lp.sched_priority = p->rt_priority;
-       read_unlock(&tasklist_lock);
+       rcu_read_unlock();
 
        /*
         * This one might sleep, we cannot do it with a spinlock held ...
@@ -6504,7 +6539,7 @@ SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param)
        return retval;
 
 out_unlock:
-       read_unlock(&tasklist_lock);
+       rcu_read_unlock();
        return retval;
 }
 
@@ -6515,22 +6550,18 @@ long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)
        int retval;
 
        get_online_cpus();
-       read_lock(&tasklist_lock);
+       rcu_read_lock();
 
        p = find_process_by_pid(pid);
        if (!p) {
-               read_unlock(&tasklist_lock);
+               rcu_read_unlock();
                put_online_cpus();
                return -ESRCH;
        }
 
-       /*
-        * It is not safe to call set_cpus_allowed with the
-        * tasklist_lock held. We will bump the task_struct's
-        * usage count and then drop tasklist_lock.
-        */
+       /* Prevent p going away */
        get_task_struct(p);
-       read_unlock(&tasklist_lock);
+       rcu_read_unlock();
 
        if (!alloc_cpumask_var(&cpus_allowed, GFP_KERNEL)) {
                retval = -ENOMEM;
@@ -6616,7 +6647,7 @@ long sched_getaffinity(pid_t pid, struct cpumask *mask)
        int retval;
 
        get_online_cpus();
-       read_lock(&tasklist_lock);
+       rcu_read_lock();
 
        retval = -ESRCH;
        p = find_process_by_pid(pid);
@@ -6632,7 +6663,7 @@ long sched_getaffinity(pid_t pid, struct cpumask *mask)
        task_rq_unlock(rq, &flags);
 
 out_unlock:
-       read_unlock(&tasklist_lock);
+       rcu_read_unlock();
        put_online_cpus();
 
        return retval;
@@ -6876,7 +6907,7 @@ SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid,
                return -EINVAL;
 
        retval = -ESRCH;
-       read_lock(&tasklist_lock);
+       rcu_read_lock();
        p = find_process_by_pid(pid);
        if (!p)
                goto out_unlock;
@@ -6889,13 +6920,13 @@ SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid,
        time_slice = p->sched_class->get_rr_interval(rq, p);
        task_rq_unlock(rq, &flags);
 
-       read_unlock(&tasklist_lock);
+       rcu_read_unlock();
        jiffies_to_timespec(time_slice, &t);
        retval = copy_to_user(interval, &t, sizeof(t)) ? -EFAULT : 0;
        return retval;
 
 out_unlock:
-       read_unlock(&tasklist_lock);
+       rcu_read_unlock();
        return retval;
 }
 
@@ -6986,6 +7017,7 @@ void __cpuinit init_idle(struct task_struct *idle, int cpu)
        raw_spin_lock_irqsave(&rq->lock, flags);
 
        __sched_fork(idle);
+       idle->state = TASK_RUNNING;
        idle->se.exec_start = sched_clock();
 
        cpumask_copy(&idle->cpus_allowed, cpumask_of(cpu));
@@ -7100,7 +7132,23 @@ int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask)
        struct rq *rq;
        int ret = 0;
 
+       /*
+        * Since we rely on wake-ups to migrate sleeping tasks, don't change
+        * the ->cpus_allowed mask from under waking tasks, which would be
+        * possible when we change rq->lock in ttwu(), so synchronize against
+        * TASK_WAKING to avoid that.
+        */
+again:
+       while (p->state == TASK_WAKING)
+               cpu_relax();
+
        rq = task_rq_lock(p, &flags);
+
+       if (p->state == TASK_WAKING) {
+               task_rq_unlock(rq, &flags);
+               goto again;
+       }
+
        if (!cpumask_intersects(new_mask, cpu_active_mask)) {
                ret = -EINVAL;
                goto out;
@@ -7156,7 +7204,7 @@ EXPORT_SYMBOL_GPL(set_cpus_allowed_ptr);
 static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)
 {
        struct rq *rq_dest, *rq_src;
-       int ret = 0, on_rq;
+       int ret = 0;
 
        if (unlikely(!cpu_active(dest_cpu)))
                return ret;
@@ -7172,12 +7220,13 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu)
        if (!cpumask_test_cpu(dest_cpu, &p->cpus_allowed))
                goto fail;
 
-       on_rq = p->se.on_rq;
-       if (on_rq)
+       /*
+        * If we're not on a rq, the next wake-up will ensure we're
+        * placed properly.
+        */
+       if (p->se.on_rq) {
                deactivate_task(rq_src, p, 0);
-
-       set_task_cpu(p, dest_cpu);
-       if (on_rq) {
+               set_task_cpu(p, dest_cpu);
                activate_task(rq_dest, p, 0);
                check_preempt_curr(rq_dest, p, 0);
        }
@@ -7273,37 +7322,10 @@ static int __migrate_task_irq(struct task_struct *p, int src_cpu, int dest_cpu)
 static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
 {
        int dest_cpu;
-       const struct cpumask *nodemask = cpumask_of_node(cpu_to_node(dead_cpu));
 
 again:
-       /* Look for allowed, online CPU in same node. */
-       for_each_cpu_and(dest_cpu, nodemask, cpu_active_mask)
-               if (cpumask_test_cpu(dest_cpu, &p->cpus_allowed))
-                       goto move;
-
-       /* Any allowed, online CPU? */
-       dest_cpu = cpumask_any_and(&p->cpus_allowed, cpu_active_mask);
-       if (dest_cpu < nr_cpu_ids)
-               goto move;
-
-       /* No more Mr. Nice Guy. */
-       if (dest_cpu >= nr_cpu_ids) {
-               cpuset_cpus_allowed_locked(p, &p->cpus_allowed);
-               dest_cpu = cpumask_any_and(cpu_active_mask, &p->cpus_allowed);
-
-               /*
-                * Don't tell them about moving exiting tasks or
-                * kernel threads (both mm NULL), since they never
-                * leave kernel.
-                */
-               if (p->mm && printk_ratelimit()) {
-                       printk(KERN_INFO "process %d (%s) no "
-                              "longer affine to cpu%d\n",
-                              task_pid_nr(p), p->comm, dead_cpu);
-               }
-       }
+       dest_cpu = select_fallback_rq(dead_cpu, p);
 
-move:
        /* It can have affinity changed while we were choosing. */
        if (unlikely(!__migrate_task_irq(p, dead_cpu, dest_cpu)))
                goto again;
@@ -9668,7 +9690,7 @@ void __init sched_init(void)
 #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
 static inline int preempt_count_equals(int preempt_offset)
 {
-       int nested = preempt_count() & ~PREEMPT_ACTIVE;
+       int nested = (preempt_count() & ~PREEMPT_ACTIVE) + rcu_preempt_depth();
 
        return (nested == PREEMPT_INATOMIC_BASE + preempt_offset);
 }
@@ -10083,7 +10105,7 @@ void sched_move_task(struct task_struct *tsk)
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
        if (tsk->sched_class->moved_group)
-               tsk->sched_class->moved_group(tsk);
+               tsk->sched_class->moved_group(tsk, on_rq);
 #endif
 
        if (unlikely(running))
index 479ce56..5b49613 100644 (file)
@@ -236,6 +236,18 @@ void sched_clock_idle_wakeup_event(u64 delta_ns)
 }
 EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event);
 
+unsigned long long cpu_clock(int cpu)
+{
+       unsigned long long clock;
+       unsigned long flags;
+
+       local_irq_save(flags);
+       clock = sched_clock_cpu(cpu);
+       local_irq_restore(flags);
+
+       return clock;
+}
+
 #else /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */
 
 void sched_clock_init(void)
@@ -251,17 +263,12 @@ u64 sched_clock_cpu(int cpu)
        return sched_clock();
 }
 
-#endif /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */
 
 unsigned long long cpu_clock(int cpu)
 {
-       unsigned long long clock;
-       unsigned long flags;
+       return sched_clock_cpu(cpu);
+}
 
-       local_irq_save(flags);
-       clock = sched_clock_cpu(cpu);
-       local_irq_restore(flags);
+#endif /* CONFIG_HAVE_UNSTABLE_SCHED_CLOCK */
 
-       return clock;
-}
 EXPORT_SYMBOL_GPL(cpu_clock);
index 5bedf6e..42ac3c9 100644 (file)
@@ -510,6 +510,7 @@ __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr,
        curr->sum_exec_runtime += delta_exec;
        schedstat_add(cfs_rq, exec_clock, delta_exec);
        delta_exec_weighted = calc_delta_fair(delta_exec, curr);
+
        curr->vruntime += delta_exec_weighted;
        update_min_vruntime(cfs_rq);
 }
@@ -765,16 +766,26 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
        se->vruntime = vruntime;
 }
 
+#define ENQUEUE_WAKEUP 1
+#define ENQUEUE_MIGRATE 2
+
 static void
-enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup)
+enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
 {
        /*
+        * Update the normalized vruntime before updating min_vruntime
+        * through callig update_curr().
+        */
+       if (!(flags & ENQUEUE_WAKEUP) || (flags & ENQUEUE_MIGRATE))
+               se->vruntime += cfs_rq->min_vruntime;
+
+       /*
         * Update run-time statistics of the 'current'.
         */
        update_curr(cfs_rq);
        account_entity_enqueue(cfs_rq, se);
 
-       if (wakeup) {
+       if (flags & ENQUEUE_WAKEUP) {
                place_entity(cfs_rq, se, 0);
                enqueue_sleeper(cfs_rq, se);
        }
@@ -828,6 +839,14 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep)
                __dequeue_entity(cfs_rq, se);
        account_entity_dequeue(cfs_rq, se);
        update_min_vruntime(cfs_rq);
+
+       /*
+        * Normalize the entity after updating the min_vruntime because the
+        * update can refer to the ->curr item and we need to reflect this
+        * movement in our normalized position.
+        */
+       if (!sleep)
+               se->vruntime -= cfs_rq->min_vruntime;
 }
 
 /*
@@ -1038,13 +1057,19 @@ static void enqueue_task_fair(struct rq *rq, struct task_struct *p, int wakeup)
 {
        struct cfs_rq *cfs_rq;
        struct sched_entity *se = &p->se;
+       int flags = 0;
+
+       if (wakeup)
+               flags |= ENQUEUE_WAKEUP;
+       if (p->state == TASK_WAKING)
+               flags |= ENQUEUE_MIGRATE;
 
        for_each_sched_entity(se) {
                if (se->on_rq)
                        break;
                cfs_rq = cfs_rq_of(se);
-               enqueue_entity(cfs_rq, se, wakeup);
-               wakeup = 1;
+               enqueue_entity(cfs_rq, se, flags);
+               flags = ENQUEUE_WAKEUP;
        }
 
        hrtick_update(rq);
@@ -1120,6 +1145,14 @@ static void yield_task_fair(struct rq *rq)
 
 #ifdef CONFIG_SMP
 
+static void task_waking_fair(struct rq *rq, struct task_struct *p)
+{
+       struct sched_entity *se = &p->se;
+       struct cfs_rq *cfs_rq = cfs_rq_of(se);
+
+       se->vruntime -= cfs_rq->min_vruntime;
+}
+
 #ifdef CONFIG_FAIR_GROUP_SCHED
 /*
  * effective_load() calculates the load change as seen from the root_task_group
@@ -1429,6 +1462,9 @@ static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flag
        }
 
        for_each_domain(cpu, tmp) {
+               if (!(tmp->flags & SD_LOAD_BALANCE))
+                       continue;
+
                /*
                 * If power savings logic is enabled for a domain, see if we
                 * are not overloaded, if so, don't balance wider.
@@ -1975,6 +2011,8 @@ static void task_fork_fair(struct task_struct *p)
                resched_task(rq->curr);
        }
 
+       se->vruntime -= cfs_rq->min_vruntime;
+
        raw_spin_unlock_irqrestore(&rq->lock, flags);
 }
 
@@ -2028,12 +2066,13 @@ static void set_curr_task_fair(struct rq *rq)
 }
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
-static void moved_group_fair(struct task_struct *p)
+static void moved_group_fair(struct task_struct *p, int on_rq)
 {
        struct cfs_rq *cfs_rq = task_cfs_rq(p);
 
        update_curr(cfs_rq);
-       place_entity(cfs_rq, &p->se, 1);
+       if (!on_rq)
+               place_entity(cfs_rq, &p->se, 1);
 }
 #endif
 
@@ -2073,6 +2112,8 @@ static const struct sched_class fair_sched_class = {
        .move_one_task          = move_one_task_fair,
        .rq_online              = rq_online_fair,
        .rq_offline             = rq_offline_fair,
+
+       .task_waking            = task_waking_fair,
 #endif
 
        .set_curr_task          = set_curr_task_fair,
index d2ea282..f48328a 100644 (file)
@@ -1472,7 +1472,7 @@ static void post_schedule_rt(struct rq *rq)
  * If we are not running and we are not going to reschedule soon, we should
  * try to push tasks away now
  */
-static void task_wake_up_rt(struct rq *rq, struct task_struct *p)
+static void task_woken_rt(struct rq *rq, struct task_struct *p)
 {
        if (!task_running(rq, p) &&
            !test_tsk_need_resched(rq->curr) &&
@@ -1753,7 +1753,7 @@ static const struct sched_class rt_sched_class = {
        .rq_offline             = rq_offline_rt,
        .pre_schedule           = pre_schedule_rt,
        .post_schedule          = post_schedule_rt,
-       .task_wake_up           = task_wake_up_rt,
+       .task_woken             = task_woken_rt,
        .switched_from          = switched_from_rt,
 #endif
 
index 1814e68..d09692b 100644 (file)
@@ -218,13 +218,13 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi
        struct user_struct *user;
 
        /*
-        * We won't get problems with the target's UID changing under us
-        * because changing it requires RCU be used, and if t != current, the
-        * caller must be holding the RCU readlock (by way of a spinlock) and
-        * we use RCU protection here
+        * Protect access to @t credentials. This can go away when all
+        * callers hold rcu read lock.
         */
+       rcu_read_lock();
        user = get_uid(__task_cred(t)->user);
        atomic_inc(&user->sigpending);
+       rcu_read_unlock();
 
        if (override_rlimit ||
            atomic_read(&user->sigpending) <=
@@ -1179,11 +1179,12 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid,
        int ret = -EINVAL;
        struct task_struct *p;
        const struct cred *pcred;
+       unsigned long flags;
 
        if (!valid_signal(sig))
                return ret;
 
-       read_lock(&tasklist_lock);
+       rcu_read_lock();
        p = pid_task(pid, PIDTYPE_PID);
        if (!p) {
                ret = -ESRCH;
@@ -1199,14 +1200,16 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid,
        ret = security_task_kill(p, info, sig, secid);
        if (ret)
                goto out_unlock;
-       if (sig && p->sighand) {
-               unsigned long flags;
-               spin_lock_irqsave(&p->sighand->siglock, flags);
-               ret = __send_signal(sig, info, p, 1, 0);
-               spin_unlock_irqrestore(&p->sighand->siglock, flags);
+
+       if (sig) {
+               if (lock_task_sighand(p, &flags)) {
+                       ret = __send_signal(sig, info, p, 1, 0);
+                       unlock_task_sighand(p, &flags);
+               } else
+                       ret = -ESRCH;
        }
 out_unlock:
-       read_unlock(&tasklist_lock);
+       rcu_read_unlock();
        return ret;
 }
 EXPORT_SYMBOL_GPL(kill_pid_info_as_uid);
index 20ccfb5..26a6b73 100644 (file)
@@ -162,6 +162,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
        if (niceval > 19)
                niceval = 19;
 
+       rcu_read_lock();
        read_lock(&tasklist_lock);
        switch (which) {
                case PRIO_PROCESS:
@@ -199,6 +200,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
        }
 out_unlock:
        read_unlock(&tasklist_lock);
+       rcu_read_unlock();
 out:
        return error;
 }
index c6324d9..8047980 100644 (file)
@@ -136,6 +136,7 @@ static inline void warp_clock(void)
        write_seqlock_irq(&xtime_lock);
        wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60;
        xtime.tv_sec += sys_tz.tz_minuteswest * 60;
+       update_xtime_cache(0);
        write_sequnlock_irq(&xtime_lock);
        clock_was_set();
 }
index 3d5fc0f..6f740d9 100644 (file)
@@ -238,8 +238,9 @@ void clockevents_exchange_device(struct clock_event_device *old,
  */
 void clockevents_notify(unsigned long reason, void *arg)
 {
-       struct list_head *node, *tmp;
+       struct clock_event_device *dev, *tmp;
        unsigned long flags;
+       int cpu;
 
        raw_spin_lock_irqsave(&clockevents_lock, flags);
        clockevents_do_notify(reason, arg);
@@ -250,8 +251,19 @@ void clockevents_notify(unsigned long reason, void *arg)
                 * Unregister the clock event devices which were
                 * released from the users in the notify chain.
                 */
-               list_for_each_safe(node, tmp, &clockevents_released)
-                       list_del(node);
+               list_for_each_entry_safe(dev, tmp, &clockevents_released, list)
+                       list_del(&dev->list);
+               /*
+                * Now check whether the CPU has left unused per cpu devices
+                */
+               cpu = *((int *)arg);
+               list_for_each_entry_safe(dev, tmp, &clockevent_devices, list) {
+                       if (cpumask_test_cpu(cpu, dev->cpumask) &&
+                           cpumask_weight(dev->cpumask) == 1) {
+                               BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED);
+                               list_del(&dev->list);
+                       }
+               }
                break;
        default:
                break;
index af4135f..7faaa32 100644 (file)
@@ -165,6 +165,13 @@ struct timespec raw_time;
 /* flag for if timekeeping is suspended */
 int __read_mostly timekeeping_suspended;
 
+static struct timespec xtime_cache __attribute__ ((aligned (16)));
+void update_xtime_cache(u64 nsec)
+{
+       xtime_cache = xtime;
+       timespec_add_ns(&xtime_cache, nsec);
+}
+
 /* must hold xtime_lock */
 void timekeeping_leap_insert(int leapsecond)
 {
@@ -325,6 +332,8 @@ int do_settimeofday(struct timespec *tv)
 
        xtime = *tv;
 
+       update_xtime_cache(0);
+
        timekeeper.ntp_error = 0;
        ntp_clear();
 
@@ -550,6 +559,7 @@ void __init timekeeping_init(void)
        }
        set_normalized_timespec(&wall_to_monotonic,
                                -boot.tv_sec, -boot.tv_nsec);
+       update_xtime_cache(0);
        total_sleep_time.tv_sec = 0;
        total_sleep_time.tv_nsec = 0;
        write_sequnlock_irqrestore(&xtime_lock, flags);
@@ -583,6 +593,7 @@ static int timekeeping_resume(struct sys_device *dev)
                wall_to_monotonic = timespec_sub(wall_to_monotonic, ts);
                total_sleep_time = timespec_add_safe(total_sleep_time, ts);
        }
+       update_xtime_cache(0);
        /* re-base the last cycle value */
        timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock);
        timekeeper.ntp_error = 0;
@@ -722,6 +733,7 @@ static void timekeeping_adjust(s64 offset)
                                timekeeper.ntp_error_shift;
 }
 
+
 /**
  * logarithmic_accumulation - shifted accumulation of cycles
  *
@@ -765,6 +777,7 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift)
        return offset;
 }
 
+
 /**
  * update_wall_time - Uses the current clocksource to increment the wall time
  *
@@ -774,6 +787,7 @@ void update_wall_time(void)
 {
        struct clocksource *clock;
        cycle_t offset;
+       u64 nsecs;
        int shift = 0, maxshift;
 
        /* Make sure we're fully resumed: */
@@ -839,6 +853,9 @@ void update_wall_time(void)
        timekeeper.ntp_error += timekeeper.xtime_nsec <<
                                timekeeper.ntp_error_shift;
 
+       nsecs = clocksource_cyc2ns(offset, timekeeper.mult, timekeeper.shift);
+       update_xtime_cache(nsecs);
+
        /* check to see if there is a new clocksource to use */
        update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult);
 }
@@ -875,13 +892,13 @@ void monotonic_to_bootbased(struct timespec *ts)
 
 unsigned long get_seconds(void)
 {
-       return xtime.tv_sec;
+       return xtime_cache.tv_sec;
 }
 EXPORT_SYMBOL(get_seconds);
 
 struct timespec __current_kernel_time(void)
 {
-       return xtime;
+       return xtime_cache;
 }
 
 struct timespec current_kernel_time(void)
@@ -891,7 +908,8 @@ struct timespec current_kernel_time(void)
 
        do {
                seq = read_seqbegin(&xtime_lock);
-               now = xtime;
+
+               now = xtime_cache;
        } while (read_seqretry(&xtime_lock, seq));
 
        return now;
@@ -905,7 +923,8 @@ struct timespec get_monotonic_coarse(void)
 
        do {
                seq = read_seqbegin(&xtime_lock);
-               now = xtime;
+
+               now = xtime_cache;
                mono = wall_to_monotonic;
        } while (read_seqretry(&xtime_lock, seq));
 
index 5db5a8d..15533b7 100644 (file)
@@ -656,8 +656,6 @@ __mod_timer(struct timer_list *timer, unsigned long expires,
 
        debug_activate(timer, expires);
 
-       new_base = __get_cpu_var(tvec_bases);
-
        cpu = smp_processor_id();
 
 #if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP)
index 7ecab06..375f81a 100644 (file)
@@ -282,6 +282,18 @@ static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs);
 static int kretprobe_dispatcher(struct kretprobe_instance *ri,
                                struct pt_regs *regs);
 
+/* Check the name is good for event/group */
+static int check_event_name(const char *name)
+{
+       if (!isalpha(*name) && *name != '_')
+               return 0;
+       while (*++name != '\0') {
+               if (!isalpha(*name) && !isdigit(*name) && *name != '_')
+                       return 0;
+       }
+       return 1;
+}
+
 /*
  * Allocate new trace_probe and initialize it (including kprobes).
  */
@@ -293,10 +305,11 @@ static struct trace_probe *alloc_trace_probe(const char *group,
                                             int nargs, int is_return)
 {
        struct trace_probe *tp;
+       int ret = -ENOMEM;
 
        tp = kzalloc(SIZEOF_TRACE_PROBE(nargs), GFP_KERNEL);
        if (!tp)
-               return ERR_PTR(-ENOMEM);
+               return ERR_PTR(ret);
 
        if (symbol) {
                tp->symbol = kstrdup(symbol, GFP_KERNEL);
@@ -312,14 +325,20 @@ static struct trace_probe *alloc_trace_probe(const char *group,
        else
                tp->rp.kp.pre_handler = kprobe_dispatcher;
 
-       if (!event)
+       if (!event || !check_event_name(event)) {
+               ret = -EINVAL;
                goto error;
+       }
+
        tp->call.name = kstrdup(event, GFP_KERNEL);
        if (!tp->call.name)
                goto error;
 
-       if (!group)
+       if (!group || !check_event_name(group)) {
+               ret = -EINVAL;
                goto error;
+       }
+
        tp->call.system = kstrdup(group, GFP_KERNEL);
        if (!tp->call.system)
                goto error;
@@ -330,7 +349,7 @@ error:
        kfree(tp->call.name);
        kfree(tp->symbol);
        kfree(tp);
-       return ERR_PTR(-ENOMEM);
+       return ERR_PTR(ret);
 }
 
 static void free_probe_arg(struct probe_arg *arg)
@@ -695,10 +714,10 @@ static int create_trace_probe(int argc, char **argv)
        if (!event) {
                /* Make a new event name */
                if (symbol)
-                       snprintf(buf, MAX_EVENT_NAME_LEN, "%c@%s%+ld",
+                       snprintf(buf, MAX_EVENT_NAME_LEN, "%c_%s_%ld",
                                 is_return ? 'r' : 'p', symbol, offset);
                else
-                       snprintf(buf, MAX_EVENT_NAME_LEN, "%c@0x%p",
+                       snprintf(buf, MAX_EVENT_NAME_LEN, "%c_0x%p",
                                 is_return ? 'r' : 'p', addr);
                event = buf;
        }
index f669396..a7974a5 100644 (file)
@@ -93,6 +93,7 @@ static const struct stacktrace_ops backtrace_ops = {
        .warning_symbol         = backtrace_warning_symbol,
        .stack                  = backtrace_stack,
        .address                = backtrace_address,
+       .walk_stack             = print_context_stack,
 };
 
 static int
index 7607420..a4e971d 100644 (file)
@@ -637,6 +637,8 @@ static int INIT start_bunzip(struct bunzip_data **bdp, void *inbuf, int len,
 
        /* Allocate bunzip_data.  Most fields initialize to zero. */
        bd = *bdp = malloc(i);
+       if (!bd)
+               return RETVAL_OUT_OF_MEMORY;
        memset(bd, 0, sizeof(struct bunzip_data));
        /* Setup input buffer */
        bd->inbuf = inbuf;
@@ -664,6 +666,8 @@ static int INIT start_bunzip(struct bunzip_data **bdp, void *inbuf, int len,
        bd->dbufSize = 100000*(i-BZh0);
 
        bd->dbuf = large_malloc(bd->dbufSize * sizeof(int));
+       if (!bd->dbuf)
+               return RETVAL_OUT_OF_MEMORY;
        return RETVAL_OK;
 }
 
@@ -686,7 +690,7 @@ STATIC int INIT bunzip2(unsigned char *buf, int len,
 
        if (!outbuf) {
                error("Could not allocate output bufer");
-               return -1;
+               return RETVAL_OUT_OF_MEMORY;
        }
        if (buf)
                inbuf = buf;
@@ -694,6 +698,7 @@ STATIC int INIT bunzip2(unsigned char *buf, int len,
                inbuf = malloc(BZIP2_IOBUF_SIZE);
        if (!inbuf) {
                error("Could not allocate input bufer");
+               i = RETVAL_OUT_OF_MEMORY;
                goto exit_0;
        }
        i = start_bunzip(&bd, inbuf, len, fill);
@@ -720,11 +725,14 @@ STATIC int INIT bunzip2(unsigned char *buf, int len,
        } else if (i == RETVAL_UNEXPECTED_OUTPUT_EOF) {
                error("Compressed file ends unexpectedly");
        }
+       if (!bd)
+               goto exit_1;
        if (bd->dbuf)
                large_free(bd->dbuf);
        if (pos)
                *pos = bd->inbufPos;
        free(bd);
+exit_1:
        if (!buf)
                free(inbuf);
 exit_0:
index afce96a..9f75b4e 100644 (file)
@@ -338,10 +338,10 @@ EXPORT_SYMBOL(strnchr);
 #endif
 
 /**
- * skip_spaces - Removes leading whitespace from @s.
- * @s: The string to be stripped.
+ * skip_spaces - Removes leading whitespace from @str.
+ * @str: The string to be stripped.
  *
- * Returns a pointer to the first non-whitespace character in @s.
+ * Returns a pointer to the first non-whitespace character in @str.
  */
 char *skip_spaces(const char *str)
 {
index 998eacc..d79b925 100644 (file)
@@ -3580,7 +3580,7 @@ static unsigned long __meminit zone_spanned_pages_in_node(int nid,
  * Return the number of holes in a range on a node. If nid is MAX_NUMNODES,
  * then all holes in the requested range will be accounted for.
  */
-static unsigned long __meminit __absent_pages_in_range(int nid,
+unsigned long __meminit __absent_pages_in_range(int nid,
                                unsigned long range_start_pfn,
                                unsigned long range_end_pfn)
 {
@@ -4109,7 +4109,7 @@ static int __init cmp_node_active_region(const void *a, const void *b)
 }
 
 /* sort the node_map by start_pfn */
-static void __init sort_node_map(void)
+void __init sort_node_map(void)
 {
        sort(early_node_map, (size_t)nr_nodemap_entries,
                        sizeof(struct node_active_region),
index 5697500..18e7f5a 100644 (file)
@@ -770,7 +770,7 @@ static int hidp_setup_hid(struct hidp_session *session,
 
        hid = hid_allocate_device();
        if (IS_ERR(hid))
-               return PTR_ERR(session->hid);
+               return PTR_ERR(hid);
 
        session->hid = hid;
        session->req = req;
index 5129b88..1120cf1 100644 (file)
@@ -1212,6 +1212,7 @@ static void l2cap_monitor_timeout(unsigned long arg)
        bh_lock_sock(sk);
        if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
                l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
+               bh_unlock_sock(sk);
                return;
        }
 
@@ -3435,8 +3436,8 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str
                            (pi->unacked_frames > 0))
                                __mod_retrans_timer();
 
-                       l2cap_ertm_send(sk);
                        pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+                       l2cap_ertm_send(sk);
                }
                break;
 
@@ -3471,9 +3472,9 @@ static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, str
                pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
 
                if (rx_control & L2CAP_CTRL_POLL) {
-                       l2cap_retransmit_frame(sk, tx_seq);
                        pi->expected_ack_seq = tx_seq;
                        l2cap_drop_acked_frames(sk);
+                       l2cap_retransmit_frame(sk, tx_seq);
                        l2cap_ertm_send(sk);
                        if (pi->conn_state & L2CAP_CONN_WAIT_F) {
                                pi->srej_save_reqseq = tx_seq;
index dc32842..a1362dc 100644 (file)
@@ -43,7 +43,7 @@ static int bufsize = 64 * 1024;
 static const char procname[] = "dccpprobe";
 
 static struct {
-       struct kfifo      *fifo;
+       struct kfifo      fifo;
        spinlock_t        lock;
        wait_queue_head_t wait;
        struct timespec   tstart;
@@ -67,7 +67,7 @@ static void printl(const char *fmt, ...)
        len += vscnprintf(tbuf+len, sizeof(tbuf)-len, fmt, args);
        va_end(args);
 
-       kfifo_put(dccpw.fifo, tbuf, len);
+       kfifo_in_locked(&dccpw.fifo, tbuf, len, &dccpw.lock);
        wake_up(&dccpw.wait);
 }
 
@@ -109,7 +109,7 @@ static struct jprobe dccp_send_probe = {
 
 static int dccpprobe_open(struct inode *inode, struct file *file)
 {
-       kfifo_reset(dccpw.fifo);
+       kfifo_reset(&dccpw.fifo);
        getnstimeofday(&dccpw.tstart);
        return 0;
 }
@@ -131,11 +131,11 @@ static ssize_t dccpprobe_read(struct file *file, char __user *buf,
                return -ENOMEM;
 
        error = wait_event_interruptible(dccpw.wait,
-                                        __kfifo_len(dccpw.fifo) != 0);
+                                        kfifo_len(&dccpw.fifo) != 0);
        if (error)
                goto out_free;
 
-       cnt = kfifo_get(dccpw.fifo, tbuf, len);
+       cnt = kfifo_out_locked(&dccpw.fifo, tbuf, len, &dccpw.lock);
        error = copy_to_user(buf, tbuf, cnt) ? -EFAULT : 0;
 
 out_free:
@@ -156,10 +156,8 @@ static __init int dccpprobe_init(void)
 
        init_waitqueue_head(&dccpw.wait);
        spin_lock_init(&dccpw.lock);
-       dccpw.fifo = kfifo_alloc(bufsize, GFP_KERNEL, &dccpw.lock);
-       if (IS_ERR(dccpw.fifo))
-               return PTR_ERR(dccpw.fifo);
-
+       if (kfifo_alloc(&dccpw.fifo, bufsize, GFP_KERNEL))
+               return ret;
        if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &dccpprobe_fops))
                goto err0;
 
@@ -172,14 +170,14 @@ static __init int dccpprobe_init(void)
 err1:
        proc_net_remove(&init_net, procname);
 err0:
-       kfifo_free(dccpw.fifo);
+       kfifo_free(&dccpw.fifo);
        return ret;
 }
 module_init(dccpprobe_init);
 
 static __exit void dccpprobe_exit(void)
 {
-       kfifo_free(dccpw.fifo);
+       kfifo_free(&dccpw.fifo);
        proc_net_remove(&init_net, procname);
        unregister_jprobe(&dccp_send_probe);
 
index 3b3a956..2cddea3 100644 (file)
@@ -708,7 +708,8 @@ static void ip6_frags_ns_sysctl_unregister(struct net *net)
 
        table = net->ipv6.sysctl.frags_hdr->ctl_table_arg;
        unregister_net_sysctl_table(net->ipv6.sysctl.frags_hdr);
-       kfree(table);
+       if (!net_eq(net, &init_net))
+               kfree(table);
 }
 
 static struct ctl_table_header *ip6_ctl_header;
index db3b273..c2bd74c 100644 (file)
@@ -2630,6 +2630,7 @@ struct ctl_table *ipv6_route_sysctl_init(struct net *net)
                table[6].data = &net->ipv6.sysctl.ip6_rt_gc_elasticity;
                table[7].data = &net->ipv6.sysctl.ip6_rt_mtu_expires;
                table[8].data = &net->ipv6.sysctl.ip6_rt_min_advmss;
+               table[9].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval;
        }
 
        return table;
index 1497dce..c569986 100644 (file)
@@ -172,14 +172,15 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
        return v;
 }
 
-static inline void aaci_chan_wait_ready(struct aaci_runtime *aacirun)
+static inline void
+aaci_chan_wait_ready(struct aaci_runtime *aacirun, unsigned long mask)
 {
        u32 val;
        int timeout = 5000;
 
        do {
                val = readl(aacirun->base + AACI_SR);
-       } while (val & (SR_TXB|SR_RXB) && timeout--);
+       } while (val & mask && timeout--);
 }
 
 
@@ -208,8 +209,10 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
                        writel(0, aacirun->base + AACI_IE);
                        return;
                }
-               ptr = aacirun->ptr;
 
+               spin_lock(&aacirun->lock);
+
+               ptr = aacirun->ptr;
                do {
                        unsigned int len = aacirun->fifosz;
                        u32 val;
@@ -217,9 +220,9 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
                        if (aacirun->bytes <= 0) {
                                aacirun->bytes += aacirun->period;
                                aacirun->ptr = ptr;
-                               spin_unlock(&aaci->lock);
+                               spin_unlock(&aacirun->lock);
                                snd_pcm_period_elapsed(aacirun->substream);
-                               spin_lock(&aaci->lock);
+                               spin_lock(&aacirun->lock);
                        }
                        if (!(aacirun->cr & CR_EN))
                                break;
@@ -245,7 +248,10 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
                                        ptr = aacirun->start;
                        }
                } while(1);
+
                aacirun->ptr = ptr;
+
+               spin_unlock(&aacirun->lock);
        }
 
        if (mask & ISR_URINTR) {
@@ -263,6 +269,8 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
                        return;
                }
 
+               spin_lock(&aacirun->lock);
+
                ptr = aacirun->ptr;
                do {
                        unsigned int len = aacirun->fifosz;
@@ -271,9 +279,9 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
                        if (aacirun->bytes <= 0) {
                                aacirun->bytes += aacirun->period;
                                aacirun->ptr = ptr;
-                               spin_unlock(&aaci->lock);
+                               spin_unlock(&aacirun->lock);
                                snd_pcm_period_elapsed(aacirun->substream);
-                               spin_lock(&aaci->lock);
+                               spin_lock(&aacirun->lock);
                        }
                        if (!(aacirun->cr & CR_EN))
                                break;
@@ -301,6 +309,8 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
                } while (1);
 
                aacirun->ptr = ptr;
+
+               spin_unlock(&aacirun->lock);
        }
 }
 
@@ -310,7 +320,6 @@ static irqreturn_t aaci_irq(int irq, void *devid)
        u32 mask;
        int i;
 
-       spin_lock(&aaci->lock);
        mask = readl(aaci->base + AACI_ALLINTS);
        if (mask) {
                u32 m = mask;
@@ -320,7 +329,6 @@ static irqreturn_t aaci_irq(int irq, void *devid)
                        }
                }
        }
-       spin_unlock(&aaci->lock);
 
        return mask ? IRQ_HANDLED : IRQ_NONE;
 }
@@ -330,63 +338,6 @@ static irqreturn_t aaci_irq(int irq, void *devid)
 /*
  * ALSA support.
  */
-
-struct aaci_stream {
-       unsigned char codec_idx;
-       unsigned char rate_idx;
-};
-
-static struct aaci_stream aaci_streams[] = {
-       [ACSTREAM_FRONT] = {
-               .codec_idx      = 0,
-               .rate_idx       = AC97_RATES_FRONT_DAC,
-       },
-       [ACSTREAM_SURROUND] = {
-               .codec_idx      = 0,
-               .rate_idx       = AC97_RATES_SURR_DAC,
-       },
-       [ACSTREAM_LFE] = {
-               .codec_idx      = 0,
-               .rate_idx       = AC97_RATES_LFE_DAC,
-       },
-};
-
-static inline unsigned int aaci_rate_mask(struct aaci *aaci, int streamid)
-{
-       struct aaci_stream *s = aaci_streams + streamid;
-       return aaci->ac97_bus->codec[s->codec_idx]->rates[s->rate_idx];
-}
-
-static unsigned int rate_list[] = {
-       5512, 8000, 11025, 16000, 22050, 32000, 44100,
-       48000, 64000, 88200, 96000, 176400, 192000
-};
-
-/*
- * Double-rate rule: we can support double rate iff channels == 2
- *  (unimplemented)
- */
-static int
-aaci_rule_rate_by_channels(struct snd_pcm_hw_params *p, struct snd_pcm_hw_rule *rule)
-{
-       struct aaci *aaci = rule->private;
-       unsigned int rate_mask = SNDRV_PCM_RATE_8000_48000|SNDRV_PCM_RATE_5512;
-       struct snd_interval *c = hw_param_interval(p, SNDRV_PCM_HW_PARAM_CHANNELS);
-
-       switch (c->max) {
-       case 6:
-               rate_mask &= aaci_rate_mask(aaci, ACSTREAM_LFE);
-       case 4:
-               rate_mask &= aaci_rate_mask(aaci, ACSTREAM_SURROUND);
-       case 2:
-               rate_mask &= aaci_rate_mask(aaci, ACSTREAM_FRONT);
-       }
-
-       return snd_interval_list(hw_param_interval(p, rule->var),
-                                ARRAY_SIZE(rate_list), rate_list,
-                                rate_mask);
-}
-
 static struct snd_pcm_hardware aaci_hw_info = {
        .info                   = SNDRV_PCM_INFO_MMAP |
                                  SNDRV_PCM_INFO_MMAP_VALID |
@@ -400,10 +351,7 @@ static struct snd_pcm_hardware aaci_hw_info = {
         */
        .formats                = SNDRV_PCM_FMTBIT_S16_LE,
 
-       /* should this be continuous or knot? */
-       .rates                  = SNDRV_PCM_RATE_CONTINUOUS,
-       .rate_max               = 48000,
-       .rate_min               = 4000,
+       /* rates are setup from the AC'97 codec */
        .channels_min           = 2,
        .channels_max           = 6,
        .buffer_bytes_max       = 64 * 1024,
@@ -423,6 +371,12 @@ static int __aaci_pcm_open(struct aaci *aaci,
        aacirun->substream = substream;
        runtime->private_data = aacirun;
        runtime->hw = aaci_hw_info;
+       runtime->hw.rates = aacirun->pcm->rates;
+       snd_pcm_limit_hw_rates(runtime);
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
+           aacirun->pcm->r[1].slots)
+               snd_ac97_pcm_double_rate_rules(runtime);
 
        /*
         * FIXME: ALSA specifies fifo_size in bytes.  If we're in normal
@@ -433,17 +387,6 @@ static int __aaci_pcm_open(struct aaci *aaci,
         */
        runtime->hw.fifo_size = aaci->fifosize * 2;
 
-       /*
-        * Add rule describing hardware rate dependency
-        * on the number of channels.
-        */
-       ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
-                                 aaci_rule_rate_by_channels, aaci,
-                                 SNDRV_PCM_HW_PARAM_CHANNELS,
-                                 SNDRV_PCM_HW_PARAM_RATE, -1);
-       if (ret)
-               goto out;
-
        ret = request_irq(aaci->dev->irq[0], aaci_irq, IRQF_SHARED|IRQF_DISABLED,
                          DRIVER_NAME, aaci);
        if (ret)
@@ -507,18 +450,22 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
 
        err = snd_pcm_lib_malloc_pages(substream,
                                       params_buffer_bytes(params));
-       if (err < 0)
-               goto out;
+       if (err >= 0) {
+               unsigned int rate = params_rate(params);
+               int dbl = rate > 48000;
 
-       err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
-                               params_channels(params),
-                               aacirun->pcm->r[0].slots);
-       if (err)
-               goto out;
+               err = snd_ac97_pcm_open(aacirun->pcm, rate,
+                                       params_channels(params),
+                                       aacirun->pcm->r[dbl].slots);
 
-       aacirun->pcm_open = 1;
+               aacirun->pcm_open = err == 0;
+               aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
+               aacirun->fifosz = aaci->fifosize * 4;
+
+               if (aacirun->cr & CR_COMPACT)
+                       aacirun->fifosz >>= 1;
+       }
 
- out:
        return err;
 }
 
@@ -527,7 +474,7 @@ static int aaci_pcm_prepare(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct aaci_runtime *aacirun = runtime->private_data;
 
-       aacirun->start  = (void *)runtime->dma_area;
+       aacirun->start  = runtime->dma_area;
        aacirun->end    = aacirun->start + snd_pcm_lib_buffer_bytes(substream);
        aacirun->ptr    = aacirun->start;
        aacirun->period =
@@ -627,14 +574,9 @@ static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream,
         * Enable FIFO, compact mode, 16 bits per sample.
         * FIXME: double rate slots?
         */
-       if (ret >= 0) {
-               aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
+       if (ret >= 0)
                aacirun->cr |= channels_to_txmask[channels];
 
-               aacirun->fifosz = aaci->fifosize * 4;
-               if (aacirun->cr & CR_COMPACT)
-                       aacirun->fifosz >>= 1;
-       }
        return ret;
 }
 
@@ -646,7 +588,7 @@ static void aaci_pcm_playback_stop(struct aaci_runtime *aacirun)
        ie &= ~(IE_URIE|IE_TXIE);
        writel(ie, aacirun->base + AACI_IE);
        aacirun->cr &= ~CR_EN;
-       aaci_chan_wait_ready(aacirun);
+       aaci_chan_wait_ready(aacirun, SR_TXB);
        writel(aacirun->cr, aacirun->base + AACI_TXCR);
 }
 
@@ -654,7 +596,7 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun)
 {
        u32 ie;
 
-       aaci_chan_wait_ready(aacirun);
+       aaci_chan_wait_ready(aacirun, SR_TXB);
        aacirun->cr |= CR_EN;
 
        ie = readl(aacirun->base + AACI_IE);
@@ -665,12 +607,12 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun)
 
 static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-       struct aaci *aaci = substream->private_data;
        struct aaci_runtime *aacirun = substream->runtime->private_data;
        unsigned long flags;
        int ret = 0;
 
-       spin_lock_irqsave(&aaci->lock, flags);
+       spin_lock_irqsave(&aacirun->lock, flags);
+
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
                aaci_pcm_playback_start(aacirun);
@@ -697,7 +639,8 @@ static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cm
        default:
                ret = -EINVAL;
        }
-       spin_unlock_irqrestore(&aaci->lock, flags);
+
+       spin_unlock_irqrestore(&aacirun->lock, flags);
 
        return ret;
 }
@@ -721,18 +664,10 @@ static int aaci_pcm_capture_hw_params(struct snd_pcm_substream *substream,
        int ret;
 
        ret = aaci_pcm_hw_params(substream, aacirun, params);
-
-       if (ret >= 0) {
-               aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
-
+       if (ret >= 0)
                /* Line in record: slot 3 and 4 */
                aacirun->cr |= CR_SL3 | CR_SL4;
 
-               aacirun->fifosz = aaci->fifosize * 4;
-
-               if (aacirun->cr & CR_COMPACT)
-                       aacirun->fifosz >>= 1;
-       }
        return ret;
 }
 
@@ -740,7 +675,7 @@ static void aaci_pcm_capture_stop(struct aaci_runtime *aacirun)
 {
        u32 ie;
 
-       aaci_chan_wait_ready(aacirun);
+       aaci_chan_wait_ready(aacirun, SR_RXB);
 
        ie = readl(aacirun->base + AACI_IE);
        ie &= ~(IE_ORIE | IE_RXIE);
@@ -755,7 +690,7 @@ static void aaci_pcm_capture_start(struct aaci_runtime *aacirun)
 {
        u32 ie;
 
-       aaci_chan_wait_ready(aacirun);
+       aaci_chan_wait_ready(aacirun, SR_RXB);
 
 #ifdef DEBUG
        /* RX Timeout value: bits 28:17 in RXCR */
@@ -772,12 +707,11 @@ static void aaci_pcm_capture_start(struct aaci_runtime *aacirun)
 
 static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-       struct aaci *aaci = substream->private_data;
        struct aaci_runtime *aacirun = substream->runtime->private_data;
        unsigned long flags;
        int ret = 0;
 
-       spin_lock_irqsave(&aaci->lock, flags);
+       spin_lock_irqsave(&aacirun->lock, flags);
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
@@ -806,7 +740,7 @@ static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd
                ret = -EINVAL;
        }
 
-       spin_unlock_irqrestore(&aaci->lock, flags);
+       spin_unlock_irqrestore(&aacirun->lock, flags);
 
        return ret;
 }
@@ -889,6 +823,12 @@ static struct ac97_pcm ac97_defs[] __devinitdata = {
                                          (1 << AC97_SLOT_PCM_SRIGHT) |
                                          (1 << AC97_SLOT_LFE),
                        },
+                       [1] = {
+                               .slots  = (1 << AC97_SLOT_PCM_LEFT) |
+                                         (1 << AC97_SLOT_PCM_RIGHT) |
+                                         (1 << AC97_SLOT_PCM_LEFT_0) |
+                                         (1 << AC97_SLOT_PCM_RIGHT_0),
+                       },
                },
        },
        [1] = { /* PCM in */
@@ -1001,7 +941,6 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev)
 
        aaci = card->private_data;
        mutex_init(&aaci->ac97_sem);
-       spin_lock_init(&aaci->lock);
        aaci->card = card;
        aaci->dev = dev;
 
@@ -1028,7 +967,7 @@ static int __devinit aaci_init_pcm(struct aaci *aaci)
                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops);
                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops);
                snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-                                                     NULL, 0, 64 * 104);
+                                                     NULL, 0, 64 * 1024);
        }
 
        return ret;
@@ -1088,12 +1027,14 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id)
        /*
         * Playback uses AACI channel 0
         */
+       spin_lock_init(&aaci->playback.lock);
        aaci->playback.base = aaci->base + AACI_CSCH1;
        aaci->playback.fifo = aaci->base + AACI_DR1;
 
        /*
         * Capture uses AACI channel 0
         */
+       spin_lock_init(&aaci->capture.lock);
        aaci->capture.base = aaci->base + AACI_CSCH1;
        aaci->capture.fifo = aaci->base + AACI_DR1;
 
index 924f69c..6a4a2ee 100644 (file)
 struct aaci_runtime {
        void                    __iomem *base;
        void                    __iomem *fifo;
+       spinlock_t              lock;
 
        struct ac97_pcm         *pcm;
        int                     pcm_open;
@@ -232,7 +233,6 @@ struct aaci {
        struct snd_ac97         *ac97;
 
        u32                     maincr;
-       spinlock_t              lock;
 
        struct aaci_runtime     playback;
        struct aaci_runtime     capture;
index 30f4108..a27545b 100644 (file)
@@ -758,7 +758,7 @@ int snd_interval_ratnum(struct snd_interval *i,
                int diff;
                if (q == 0)
                        q = 1;
-               den = div_down(num, q);
+               den = div_up(num, q);
                if (den < rats[k].den_min)
                        continue;
                if (den > rats[k].den_max)
@@ -794,7 +794,7 @@ int snd_interval_ratnum(struct snd_interval *i,
                        i->empty = 1;
                        return -EINVAL;
                }
-               den = div_up(num, q);
+               den = div_down(num, q);
                if (den > rats[k].den_max)
                        continue;
                if (den < rats[k].den_min)
index cb9aa4c..4be562b 100644 (file)
@@ -162,7 +162,7 @@ int snd_msndmidi_new(struct snd_card *card, int device)
        err = snd_rawmidi_new(card, "MSND-MIDI", device, 1, 1, &rmidi);
        if (err < 0)
                return err;
-       mpu = kcalloc(1, sizeof(*mpu), GFP_KERNEL);
+       mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
        if (mpu == NULL) {
                snd_device_free(card, rmidi);
                return -ENOMEM;
index 96678d5..751762f 100644 (file)
@@ -393,8 +393,6 @@ size_dram(struct snd_emu8000 *emu)
 
        while (size < EMU8000_MAX_DRAM) {
 
-               size += 512 * 1024;  /* increment 512kbytes */
-
                /* Write a unique data on the test address.
                 * if the address is out of range, the data is written on
                 * 0x200000(=EMU8000_DRAM_OFFSET).  Then the id word is
@@ -414,7 +412,9 @@ size_dram(struct snd_emu8000 *emu)
                /*snd_emu8000_read_wait(emu);*/
                EMU8000_SMLD_READ(emu); /* discard stale data  */
                if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2)
-                       break; /* we must have wrapped around */
+                       break; /* no memory at this address */
+
+               size += 512 * 1024;  /* increment 512kbytes */
 
                snd_emu8000_read_wait(emu);
 
index 8691f4c..f1d9d16 100644 (file)
@@ -609,7 +609,7 @@ static int snd_sgio2audio_pcm_hw_params(struct snd_pcm_substream *substream,
        /* alloc virtual 'dma' area */
        if (runtime->dma_area)
                vfree(runtime->dma_area);
-       runtime->dma_area = vmalloc(size);
+       runtime->dma_area = vmalloc_user(size);
        if (runtime->dma_area == NULL)
                return -ENOMEM;
        runtime->dma_bytes = size;
index 83f5ee2..e19dd5d 100644 (file)
@@ -269,7 +269,7 @@ static int pss_reset_dsp(pss_confdata * devc)
        unsigned long   i, limit = jiffies + HZ/10;
 
        outw(0x2000, REG(PSS_CONTROL));
-       for (i = 0; i < 32768 && (limit-jiffies >= 0); i++)
+       for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
                inw(REG(PSS_CONTROL));
        outw(0x0000, REG(PSS_CONTROL));
        return 1;
@@ -369,11 +369,11 @@ static int pss_download_boot(pss_confdata * devc, unsigned char *block, int size
                outw(0, REG(PSS_DATA));
 
                limit = jiffies + HZ/10;
-               for (i = 0; i < 32768 && (limit - jiffies >= 0); i++)
+               for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
                        val = inw(REG(PSS_STATUS));
 
                limit = jiffies + HZ/10;
-               for (i = 0; i < 32768 && (limit-jiffies >= 0); i++)
+               for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
                {
                        val = inw(REG(PSS_STATUS));
                        if (val & 0x4000)
index a09c03c..c578c28 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "hda_codec.h"
 #include "hda_local.h"
+#include "hda_beep.h"
 
 #define CXT_PIN_DIR_IN              0x00
 #define CXT_PIN_DIR_OUT             0x01
@@ -111,6 +112,7 @@ struct conexant_spec {
        unsigned int dell_automute;
        unsigned int port_d_mode;
        unsigned char ext_mic_bias;
+       unsigned int dell_vostro;
 };
 
 static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
@@ -476,6 +478,7 @@ static void conexant_free(struct hda_codec *codec)
                snd_array_free(&spec->jacks);
        }
 #endif
+       snd_hda_detach_beep_device(codec);
        kfree(codec->spec);
 }
 
@@ -2109,9 +2112,12 @@ static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol,
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        int val;
+       hda_nid_t nid = kcontrol->private_value & 0xff;
+       int inout = (kcontrol->private_value & 0x100) ?
+               AC_AMP_GET_INPUT : AC_AMP_GET_OUTPUT;
 
-       val = snd_hda_codec_read(codec, 0x17, 0,
-               AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_OUTPUT);
+       val = snd_hda_codec_read(codec, nid, 0,
+               AC_VERB_GET_AMP_GAIN_MUTE, inout);
 
        ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN;
        return 0;
@@ -2123,6 +2129,9 @@ static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
        unsigned int idx;
+       hda_nid_t nid = kcontrol->private_value & 0xff;
+       int inout = (kcontrol->private_value & 0x100) ?
+               AC_AMP_SET_INPUT : AC_AMP_SET_OUTPUT;
 
        if (!imux->num_items)
                return 0;
@@ -2130,9 +2139,9 @@ static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
        if (idx >= imux->num_items)
                idx = imux->num_items - 1;
 
-       snd_hda_codec_write_cache(codec, 0x17, 0,
+       snd_hda_codec_write_cache(codec, nid, 0,
                AC_VERB_SET_AMP_GAIN_MUTE,
-               AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
+               AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | inout |
                        imux->items[idx].index);
 
        return 1;
@@ -2201,10 +2210,11 @@ static struct snd_kcontrol_new cxt5066_mixers[] = {
 
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-               .name = "Analog Mic Boost Capture Enum",
+               .name = "Ext Mic Boost Capture Enum",
                .info = cxt5066_mic_boost_mux_enum_info,
                .get = cxt5066_mic_boost_mux_enum_get,
                .put = cxt5066_mic_boost_mux_enum_put,
+               .private_value = 0x17,
        },
 
        HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others),
@@ -2212,6 +2222,19 @@ static struct snd_kcontrol_new cxt5066_mixers[] = {
        {}
 };
 
+static struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
+       {
+               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+               .name = "Int Mic Boost Capture Enum",
+               .info = cxt5066_mic_boost_mux_enum_info,
+               .get = cxt5066_mic_boost_mux_enum_get,
+               .put = cxt5066_mic_boost_mux_enum_put,
+               .private_value = 0x23 | 0x100,
+       },
+       HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
+       {}
+};
+
 static struct hda_verb cxt5066_init_verbs[] = {
        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
@@ -2397,11 +2420,16 @@ static struct hda_verb cxt5066_init_verbs_portd_lo[] = {
 /* initialize jack-sensing, too */
 static int cxt5066_init(struct hda_codec *codec)
 {
+       struct conexant_spec *spec = codec->spec;
+
        snd_printdd("CXT5066: init\n");
        conexant_init(codec);
        if (codec->patch_ops.unsol_event) {
                cxt5066_hp_automute(codec);
-               cxt5066_automic(codec);
+               if (spec->dell_vostro)
+                       cxt5066_vostro_automic(codec);
+               else
+                       cxt5066_automic(codec);
        }
        return 0;
 }
@@ -2500,7 +2528,10 @@ static int patch_cxt5066(struct hda_codec *codec)
                spec->init_verbs[0] = cxt5066_init_verbs_vostro;
                spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
                spec->mixers[spec->num_mixers++] = cxt5066_mixers;
+               spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers;
                spec->port_d_mode = 0;
+               spec->dell_vostro = 1;
+               snd_hda_attach_beep_device(codec, 0x13);
 
                /* no S/PDIF out */
                spec->multiout.dig_out_nid = 0;
index aeed4cc..c746505 100644 (file)
@@ -131,8 +131,8 @@ enum {
 enum {
        ALC269_BASIC,
        ALC269_QUANTA_FL1,
-       ALC269_ASUS_EEEPC_P703,
-       ALC269_ASUS_EEEPC_P901,
+       ALC269_ASUS_AMIC,
+       ALC269_ASUS_DMIC,
        ALC269_FUJITSU,
        ALC269_LIFEBOOK,
        ALC269_AUTO,
@@ -188,6 +188,8 @@ enum {
        ALC663_ASUS_MODE4,
        ALC663_ASUS_MODE5,
        ALC663_ASUS_MODE6,
+       ALC663_ASUS_MODE7,
+       ALC663_ASUS_MODE8,
        ALC272_DELL,
        ALC272_DELL_ZM1,
        ALC272_SAMSUNG_NC10,
@@ -335,6 +337,9 @@ struct alc_spec {
        /* hooks */
        void (*init_hook)(struct hda_codec *codec);
        void (*unsol_event)(struct hda_codec *codec, unsigned int res);
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+       void (*power_hook)(struct hda_codec *codec, int power);
+#endif
 
        /* for pin sensing */
        unsigned int sense_updated: 1;
@@ -386,6 +391,7 @@ struct alc_config_preset {
        void (*init_hook)(struct hda_codec *);
 #ifdef CONFIG_SND_HDA_POWER_SAVE
        struct hda_amp_list *loopbacks;
+       void (*power_hook)(struct hda_codec *codec, int power);
 #endif
 };
 
@@ -898,6 +904,7 @@ static void setup_preset(struct hda_codec *codec,
        spec->unsol_event = preset->unsol_event;
        spec->init_hook = preset->init_hook;
 #ifdef CONFIG_SND_HDA_POWER_SAVE
+       spec->power_hook = preset->power_hook;
        spec->loopback.amplist = preset->loopbacks;
 #endif
 
@@ -1663,9 +1670,6 @@ static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
 /*  some bit here disables the other DACs. Init=0x4900 */
        {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
        {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
-/* Enable amplifiers */
-       {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
-       {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
 /* DMIC fix
  * This laptop has a stereo digital microphone. The mics are only 1cm apart
  * which makes the stereo useless. However, either the mic or the ALC889
@@ -1778,6 +1782,25 @@ static struct snd_kcontrol_new alc888_base_mixer[] = {
        { } /* end */
 };
 
+static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
+               HDA_OUTPUT),
+       HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
+       HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+       { } /* end */
+};
+
+
 static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
@@ -1808,6 +1831,16 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
        spec->autocfg.speaker_pins[2] = 0x1b;
 }
 
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static void alc889_power_eapd(struct hda_codec *codec, int power)
+{
+       snd_hda_codec_write(codec, 0x14, 0,
+                           AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0);
+       snd_hda_codec_write(codec, 0x15, 0,
+                           AC_VERB_SET_EAPD_BTLENABLE, power ? 2 : 0);
+}
+#endif
+
 /*
  * ALC880 3-stack model
  *
@@ -3601,12 +3634,29 @@ static void alc_free(struct hda_codec *codec)
        snd_hda_detach_beep_device(codec);
 }
 
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+static int alc_suspend(struct hda_codec *codec, pm_message_t state)
+{
+       struct alc_spec *spec = codec->spec;
+       if (spec && spec->power_hook)
+               spec->power_hook(codec, 0);
+       return 0;
+}
+#endif
+
 #ifdef SND_HDA_NEEDS_RESUME
 static int alc_resume(struct hda_codec *codec)
 {
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+       struct alc_spec *spec = codec->spec;
+#endif
        codec->patch_ops.init(codec);
        snd_hda_codec_resume_amp(codec);
        snd_hda_codec_resume_cache(codec);
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+       if (spec && spec->power_hook)
+               spec->power_hook(codec, 1);
+#endif
        return 0;
 }
 #endif
@@ -3623,6 +3673,7 @@ static struct hda_codec_ops alc_patch_ops = {
        .resume = alc_resume,
 #endif
 #ifdef CONFIG_SND_HDA_POWER_SAVE
+       .suspend = alc_suspend,
        .check_power_status = alc_check_power_status,
 #endif
 };
@@ -8919,7 +8970,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
        SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
        SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
-       SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
+       SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
        SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
        SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
        SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
@@ -9282,6 +9333,7 @@ static struct alc_config_preset alc882_presets[] = {
                .dac_nids = alc883_dac_nids,
                .adc_nids = alc883_adc_nids_alt,
                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
+               .capsrc_nids = alc883_capsrc_nids,
                .dig_out_nid = ALC883_DIGOUT_NID,
                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
                .channel_mode = alc883_3ST_2ch_modes,
@@ -9378,10 +9430,11 @@ static struct alc_config_preset alc882_presets[] = {
                .init_hook = alc_automute_amp,
        },
        [ALC888_ACER_ASPIRE_8930G] = {
-               .mixers = { alc888_base_mixer,
+               .mixers = { alc889_acer_aspire_8930g_mixer,
                                alc883_chmode_mixer },
                .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
-                               alc889_acer_aspire_8930g_verbs },
+                               alc889_acer_aspire_8930g_verbs,
+                               alc889_eapd_verbs},
                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
                .dac_nids = alc883_dac_nids,
                .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
@@ -9398,6 +9451,9 @@ static struct alc_config_preset alc882_presets[] = {
                .unsol_event = alc_automute_amp_unsol_event,
                .setup = alc889_acer_aspire_8930g_setup,
                .init_hook = alc_automute_amp,
+#ifdef CONFIG_SND_HDA_POWER_SAVE
+               .power_hook = alc889_power_eapd,
+#endif
        },
        [ALC888_ACER_ASPIRE_7730G] = {
                .mixers = { alc883_3ST_6ch_mixer,
@@ -9428,6 +9484,7 @@ static struct alc_config_preset alc882_presets[] = {
                .dac_nids = alc883_dac_nids,
                .adc_nids = alc883_adc_nids_alt,
                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
+               .capsrc_nids = alc883_capsrc_nids,
                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
                .channel_mode = alc883_sixstack_modes,
                .input_mux = &alc883_capture_source,
@@ -9489,6 +9546,7 @@ static struct alc_config_preset alc882_presets[] = {
                .dac_nids = alc883_dac_nids,
                .adc_nids = alc883_adc_nids_alt,
                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
+               .capsrc_nids = alc883_capsrc_nids,
                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
                .channel_mode = alc883_3ST_2ch_modes,
                .input_mux = &alc883_lenovo_101e_capture_source,
@@ -9668,6 +9726,7 @@ static struct alc_config_preset alc882_presets[] = {
                        alc880_gpio1_init_verbs },
                .adc_nids = alc883_adc_nids,
                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+               .capsrc_nids = alc883_capsrc_nids,
                .dac_nids = alc883_dac_nids,
                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
                .channel_mode = alc889A_mb31_6ch_modes,
@@ -10678,6 +10737,13 @@ static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
        {}
 };
 
+static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
+       /* Front Mic pin: input vref at 50% */
+       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
+       {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       {}
+};
+
 static struct hda_input_mux alc262_fujitsu_capture_source = {
        .num_items = 3,
        .items = {
@@ -11720,7 +11786,8 @@ static struct alc_config_preset alc262_presets[] = {
        [ALC262_LENOVO_3000] = {
                .mixers = { alc262_lenovo_3000_mixer },
                .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
-                               alc262_lenovo_3000_unsol_verbs },
+                               alc262_lenovo_3000_unsol_verbs,
+                               alc262_lenovo_3000_init_verbs },
                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
                .dac_nids = alc262_dac_nids,
                .hp_nid = 0x03,
@@ -12857,7 +12924,7 @@ static int patch_alc268(struct hda_codec *codec)
        int board_config;
        int i, has_beep, err;
 
-       spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+       spec = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
                return -ENOMEM;
 
@@ -13232,10 +13299,12 @@ static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
 /* toggle speaker-output according to the hp-jack state */
 static void alc269_speaker_automute(struct hda_codec *codec)
 {
+       struct alc_spec *spec = codec->spec;
+       unsigned int nid = spec->autocfg.hp_pins[0];
        unsigned int present;
        unsigned char bits;
 
-       present = snd_hda_jack_detect(codec, 0x15);
+       present = snd_hda_jack_detect(codec, nid);
        bits = present ? AMP_IN_MUTE(0) : 0;
        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
                                AMP_IN_MUTE(0), bits);
@@ -13460,8 +13529,8 @@ static void alc269_auto_init(struct hda_codec *codec)
 static const char *alc269_models[ALC269_MODEL_LAST] = {
        [ALC269_BASIC]                  = "basic",
        [ALC269_QUANTA_FL1]             = "quanta",
-       [ALC269_ASUS_EEEPC_P703]        = "eeepc-p703",
-       [ALC269_ASUS_EEEPC_P901]        = "eeepc-p901",
+       [ALC269_ASUS_AMIC]              = "asus-amic",
+       [ALC269_ASUS_DMIC]              = "asus-dmic",
        [ALC269_FUJITSU]                = "fujitsu",
        [ALC269_LIFEBOOK]               = "lifebook",
        [ALC269_AUTO]                   = "auto",
@@ -13470,18 +13539,41 @@ static const char *alc269_models[ALC269_MODEL_LAST] = {
 static struct snd_pci_quirk alc269_cfg_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
        SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
-                     ALC269_ASUS_EEEPC_P703),
-        SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
-        SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
-        SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
-        SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
-        SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
-        SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
+                     ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80JT", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_DMIC),
+       SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_AMIC),
+       SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_AMIC),
        SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
-                     ALC269_ASUS_EEEPC_P901),
+                     ALC269_ASUS_DMIC),
        SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
-                     ALC269_ASUS_EEEPC_P901),
-        SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
+                     ALC269_ASUS_DMIC),
+       SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_ASUS_DMIC),
+       SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_ASUS_DMIC),
        SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
        SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
        {}
@@ -13511,7 +13603,7 @@ static struct alc_config_preset alc269_presets[] = {
                .setup = alc269_quanta_fl1_setup,
                .init_hook = alc269_quanta_fl1_init_hook,
        },
-       [ALC269_ASUS_EEEPC_P703] = {
+       [ALC269_ASUS_AMIC] = {
                .mixers = { alc269_eeepc_mixer },
                .cap_mixer = alc269_epc_capture_mixer,
                .init_verbs = { alc269_init_verbs,
@@ -13525,7 +13617,7 @@ static struct alc_config_preset alc269_presets[] = {
                .setup = alc269_eeepc_amic_setup,
                .init_hook = alc269_eeepc_inithook,
        },
-       [ALC269_ASUS_EEEPC_P901] = {
+       [ALC269_ASUS_DMIC] = {
                .mixers = { alc269_eeepc_mixer },
                .cap_mixer = alc269_epc_capture_mixer,
                .init_verbs = { alc269_init_verbs,
@@ -16160,6 +16252,52 @@ static struct snd_kcontrol_new alc663_g50v_mixer[] = {
        { } /* end */
 };
 
+static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
+       .ops = &snd_hda_bind_sw,
+       .values = {
+               HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
+               HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
+               HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
+               HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
+               HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
+               0
+       },
+};
+
+static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
+       .ops = &snd_hda_bind_sw,
+       .values = {
+               HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
+               HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
+               0
+       },
+};
+
+static struct snd_kcontrol_new alc663_mode7_mixer[] = {
+       HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
+       HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
+       HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
+       HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+       { } /* end */
+};
+
+static struct snd_kcontrol_new alc663_mode8_mixer[] = {
+       HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
+       HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
+       HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
+       HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+       { } /* end */
+};
+
+
 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
        {
                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -16447,6 +16585,45 @@ static struct hda_verb alc272_dell_init_verbs[] = {
        {}
 };
 
+static struct hda_verb alc663_mode7_init_verbs[] = {
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
+       {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
+       {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+       {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+       {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+       {}
+};
+
+static struct hda_verb alc663_mode8_init_verbs[] = {
+       {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+       {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
+       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+       {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+       {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+       {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+       {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
+       {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+       {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
+       {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+       {}
+};
+
 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
        HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
        HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
@@ -16626,6 +16803,54 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
        }
 }
 
+static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
+{
+       unsigned int present1, present2;
+
+       present1 = snd_hda_codec_read(codec, 0x1b, 0,
+                       AC_VERB_GET_PIN_SENSE, 0)
+                       & AC_PINSENSE_PRESENCE;
+       present2 = snd_hda_codec_read(codec, 0x21, 0,
+                       AC_VERB_GET_PIN_SENSE, 0)
+                       & AC_PINSENSE_PRESENCE;
+
+       if (present1 || present2) {
+               snd_hda_codec_write_cache(codec, 0x14, 0,
+                       AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
+               snd_hda_codec_write_cache(codec, 0x17, 0,
+                       AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
+       } else {
+               snd_hda_codec_write_cache(codec, 0x14, 0,
+                       AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+               snd_hda_codec_write_cache(codec, 0x17, 0,
+                       AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+       }
+}
+
+static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
+{
+       unsigned int present1, present2;
+
+       present1 = snd_hda_codec_read(codec, 0x21, 0,
+                       AC_VERB_GET_PIN_SENSE, 0)
+                       & AC_PINSENSE_PRESENCE;
+       present2 = snd_hda_codec_read(codec, 0x15, 0,
+                       AC_VERB_GET_PIN_SENSE, 0)
+                       & AC_PINSENSE_PRESENCE;
+
+       if (present1 || present2) {
+               snd_hda_codec_write_cache(codec, 0x14, 0,
+                       AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
+               snd_hda_codec_write_cache(codec, 0x17, 0,
+                       AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
+       } else {
+               snd_hda_codec_write_cache(codec, 0x14, 0,
+                       AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+               snd_hda_codec_write_cache(codec, 0x17, 0,
+                       AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
+       }
+}
+
 static void alc663_m51va_unsol_event(struct hda_codec *codec,
                                           unsigned int res)
 {
@@ -16645,7 +16870,7 @@ static void alc663_m51va_setup(struct hda_codec *codec)
        spec->ext_mic.pin = 0x18;
        spec->ext_mic.mux_idx = 0;
        spec->int_mic.pin = 0x12;
-       spec->int_mic.mux_idx = 1;
+       spec->int_mic.mux_idx = 9;
        spec->auto_mic = 1;
 }
 
@@ -16657,7 +16882,17 @@ static void alc663_m51va_inithook(struct hda_codec *codec)
 
 /* ***************** Mode1 ******************************/
 #define alc663_mode1_unsol_event       alc663_m51va_unsol_event
-#define alc663_mode1_setup             alc663_m51va_setup
+
+static void alc663_mode1_setup(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       spec->ext_mic.pin = 0x18;
+       spec->ext_mic.mux_idx = 0;
+       spec->int_mic.pin = 0x19;
+       spec->int_mic.mux_idx = 1;
+       spec->auto_mic = 1;
+}
+
 #define alc663_mode1_inithook          alc663_m51va_inithook
 
 /* ***************** Mode2 ******************************/
@@ -16674,7 +16909,7 @@ static void alc662_mode2_unsol_event(struct hda_codec *codec,
        }
 }
 
-#define alc662_mode2_setup     alc663_m51va_setup
+#define alc662_mode2_setup     alc663_mode1_setup
 
 static void alc662_mode2_inithook(struct hda_codec *codec)
 {
@@ -16695,7 +16930,7 @@ static void alc663_mode3_unsol_event(struct hda_codec *codec,
        }
 }
 
-#define alc663_mode3_setup     alc663_m51va_setup
+#define alc663_mode3_setup     alc663_mode1_setup
 
 static void alc663_mode3_inithook(struct hda_codec *codec)
 {
@@ -16716,7 +16951,7 @@ static void alc663_mode4_unsol_event(struct hda_codec *codec,
        }
 }
 
-#define alc663_mode4_setup     alc663_m51va_setup
+#define alc663_mode4_setup     alc663_mode1_setup
 
 static void alc663_mode4_inithook(struct hda_codec *codec)
 {
@@ -16737,7 +16972,7 @@ static void alc663_mode5_unsol_event(struct hda_codec *codec,
        }
 }
 
-#define alc663_mode5_setup     alc663_m51va_setup
+#define alc663_mode5_setup     alc663_mode1_setup
 
 static void alc663_mode5_inithook(struct hda_codec *codec)
 {
@@ -16758,7 +16993,7 @@ static void alc663_mode6_unsol_event(struct hda_codec *codec,
        }
 }
 
-#define alc663_mode6_setup     alc663_m51va_setup
+#define alc663_mode6_setup     alc663_mode1_setup
 
 static void alc663_mode6_inithook(struct hda_codec *codec)
 {
@@ -16766,6 +17001,50 @@ static void alc663_mode6_inithook(struct hda_codec *codec)
        alc_mic_automute(codec);
 }
 
+/* ***************** Mode7 ******************************/
+static void alc663_mode7_unsol_event(struct hda_codec *codec,
+                                          unsigned int res)
+{
+       switch (res >> 26) {
+       case ALC880_HP_EVENT:
+               alc663_two_hp_m7_speaker_automute(codec);
+               break;
+       case ALC880_MIC_EVENT:
+               alc_mic_automute(codec);
+               break;
+       }
+}
+
+#define alc663_mode7_setup     alc663_mode1_setup
+
+static void alc663_mode7_inithook(struct hda_codec *codec)
+{
+       alc663_two_hp_m7_speaker_automute(codec);
+       alc_mic_automute(codec);
+}
+
+/* ***************** Mode8 ******************************/
+static void alc663_mode8_unsol_event(struct hda_codec *codec,
+                                          unsigned int res)
+{
+       switch (res >> 26) {
+       case ALC880_HP_EVENT:
+               alc663_two_hp_m8_speaker_automute(codec);
+               break;
+       case ALC880_MIC_EVENT:
+               alc_mic_automute(codec);
+               break;
+       }
+}
+
+#define alc663_mode8_setup     alc663_m51va_setup
+
+static void alc663_mode8_inithook(struct hda_codec *codec)
+{
+       alc663_two_hp_m8_speaker_automute(codec);
+       alc_mic_automute(codec);
+}
+
 static void alc663_g71v_hp_automute(struct hda_codec *codec)
 {
        unsigned int present;
@@ -16900,6 +17179,8 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
        [ALC663_ASUS_MODE4] = "asus-mode4",
        [ALC663_ASUS_MODE5] = "asus-mode5",
        [ALC663_ASUS_MODE6] = "asus-mode6",
+       [ALC663_ASUS_MODE7] = "asus-mode7",
+       [ALC663_ASUS_MODE8] = "asus-mode8",
        [ALC272_DELL]           = "dell",
        [ALC272_DELL_ZM1]       = "dell-zm1",
        [ALC272_SAMSUNG_NC10]   = "samsung-nc10",
@@ -16916,12 +17197,22 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
        SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
        SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
+       SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
        SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
+       SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
+       SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
+       SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
+       SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
        SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
        SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
        SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
        SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
        SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
+       SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
        SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
        SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
        SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
@@ -17205,6 +17496,36 @@ static struct alc_config_preset alc662_presets[] = {
                .setup = alc663_mode6_setup,
                .init_hook = alc663_mode6_inithook,
        },
+       [ALC663_ASUS_MODE7] = {
+               .mixers = { alc663_mode7_mixer },
+               .cap_mixer = alc662_auto_capture_mixer,
+               .init_verbs = { alc662_init_verbs,
+                               alc663_mode7_init_verbs },
+               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+               .hp_nid = 0x03,
+               .dac_nids = alc662_dac_nids,
+               .dig_out_nid = ALC662_DIGOUT_NID,
+               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+               .channel_mode = alc662_3ST_2ch_modes,
+               .unsol_event = alc663_mode7_unsol_event,
+               .setup = alc663_mode7_setup,
+               .init_hook = alc663_mode7_inithook,
+       },
+       [ALC663_ASUS_MODE8] = {
+               .mixers = { alc663_mode8_mixer },
+               .cap_mixer = alc662_auto_capture_mixer,
+               .init_verbs = { alc662_init_verbs,
+                               alc663_mode8_init_verbs },
+               .num_dacs = ARRAY_SIZE(alc662_dac_nids),
+               .hp_nid = 0x03,
+               .dac_nids = alc662_dac_nids,
+               .dig_out_nid = ALC662_DIGOUT_NID,
+               .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
+               .channel_mode = alc662_3ST_2ch_modes,
+               .unsol_event = alc663_mode8_unsol_event,
+               .setup = alc663_mode8_setup,
+               .init_hook = alc663_mode8_inithook,
+       },
        [ALC272_DELL] = {
                .mixers = { alc663_m51va_mixer },
                .cap_mixer = alc272_auto_capture_mixer,
@@ -17688,7 +18009,9 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
        { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
        { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
        { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
+       { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
        { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
+       { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
        { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
          .patch = patch_alc861 },
        { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
index d057e64..5cfa608 100644 (file)
@@ -51,7 +51,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s
                        return 0; /* already enough large */
                vfree(runtime->dma_area);
        }
-       runtime->dma_area = vmalloc_32(size);
+       runtime->dma_area = vmalloc_32_user(size);
        if (! runtime->dma_area)
                return -ENOMEM;
        runtime->dma_bytes = size;
index b69861d..3ef16bb 100644 (file)
@@ -470,7 +470,7 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_ak4642);
 
 static int __init ak4642_modinit(void)
 {
-       int ret;
+       int ret = 0;
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
        ret = i2c_add_driver(&ak4642_i2c_driver);
 #endif
index bbc72c2..81b8c9d 100644 (file)
@@ -191,6 +191,7 @@ static int ac97_analog_prepare(struct snd_pcm_substream *substream,
        vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS);
 
        vra |= 0x1; /* enable variable rate audio */
+       vra &= ~0x4; /* disable SPDIF output */
 
        stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra);
 
@@ -221,22 +222,6 @@ static int ac97_digital_prepare(struct snd_pcm_substream *substream,
        return stac9766_ac97_write(codec, reg, runtime->rate);
 }
 
-static int ac97_digital_trigger(struct snd_pcm_substream *substream,
-                               int cmd, struct snd_soc_dai *dai)
-{
-       struct snd_soc_codec *codec = dai->codec;
-       unsigned short vra;
-
-       switch (cmd) {
-       case SNDRV_PCM_TRIGGER_STOP:
-               vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS);
-               vra &= !0x04;
-               stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra);
-               break;
-       }
-       return 0;
-}
-
 static int stac9766_set_bias_level(struct snd_soc_codec *codec,
                                   enum snd_soc_bias_level level)
 {
@@ -315,7 +300,6 @@ static struct snd_soc_dai_ops stac9766_dai_ops_analog = {
 
 static struct snd_soc_dai_ops stac9766_dai_ops_digital = {
        .prepare = ac97_digital_prepare,
-       .trigger = ac97_digital_trigger,
 };
 
 struct snd_soc_dai stac9766_dai[] = {
index 81c57b5..a808675 100644 (file)
@@ -47,7 +47,7 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
 };
 
 #define WM8974_POWER1_BIASEN  0x08
-#define WM8974_POWER1_BUFIOEN 0x10
+#define WM8974_POWER1_BUFIOEN 0x04
 
 struct wm8974_priv {
        struct snd_soc_codec codec;
index b074a59..4963def 100644 (file)
@@ -752,7 +752,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s
                        return 0; /* already large enough */
                vfree(runtime->dma_area);
        }
-       runtime->dma_area = vmalloc(size);
+       runtime->dma_area = vmalloc_user(size);
        if (!runtime->dma_area)
                return -ENOMEM;
        runtime->dma_bytes = size;
index 7814dbb..4390d22 100644 (file)
@@ -487,10 +487,11 @@ else
        msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
 endif
 
-ifneq ($(shell sh -c "(echo '\#include <libdwarf/dwarf.h>'; echo '\#include <libdwarf/libdwarf.h>'; echo 'int main(void) { Dwarf_Debug dbg; Dwarf_Error err; Dwarf_Ranges *rng; dwarf_init(0, DW_DLC_READ, 0, 0, &dbg, &err); dwarf_get_ranges(dbg, 0, &rng, 0, 0, &err); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -ldwarf -lelf -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
+ifneq ($(shell sh -c "(echo '\#ifndef _MIPS_SZLONG'; echo '\#define _MIPS_SZLONG 0'; echo '\#endif'; echo '\#include <dwarf.h>'; echo '\#include <libdwarf.h>'; echo 'int main(void) { Dwarf_Debug dbg; Dwarf_Error err; Dwarf_Ranges *rng; dwarf_init(0, DW_DLC_READ, 0, 0, &dbg, &err); dwarf_get_ranges(dbg, 0, &rng, 0, 0, &err); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/libdwarf -ldwarf -lelf -o /dev/null $(ALL_LDFLAGS) $(EXTLIBS) "$(QUIET_STDERR)" && echo y"), y)
        msg := $(warning No libdwarf.h found or old libdwarf.h found, disables dwarf support. Please install libdwarf-dev/libdwarf-devel >= 20081231);
        BASIC_CFLAGS += -DNO_LIBDWARF
 else
+       BASIC_CFLAGS += -I/usr/include/libdwarf
        EXTLIBS += -lelf -ldwarf
        LIB_OBJS += util/probe-finder.o
 endif
index 7e741f5..c1e6774 100644 (file)
@@ -38,6 +38,7 @@
 #include "util/strlist.h"
 #include "util/event.h"
 #include "util/debug.h"
+#include "util/debugfs.h"
 #include "util/symbol.h"
 #include "util/thread.h"
 #include "util/session.h"
@@ -205,6 +206,9 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
        if ((!session.nr_probe && !session.dellist && !session.list_events))
                usage_with_options(probe_usage, options);
 
+       if (debugfs_valid_mountpoint(debugfs_path) < 0)
+               die("Failed to find debugfs path.");
+
        if (session.list_events) {
                if (session.nr_probe != 0 || session.dellist) {
                        pr_warning("  Error: Don't use --list with"
index e50a6b1..5c2ab53 100644 (file)
@@ -224,7 +224,7 @@ static int __cmd_report(void)
 
        perf_session__collapse_resort(session);
        perf_session__output_resort(session, session->events_stats.total);
-       fprintf(stdout, "# Samples: %ld\n#\n", session->events_stats.total);
+       fprintf(stdout, "# Samples: %Ld\n#\n", session->events_stats.total);
        perf_session__fprintf_hists(session, NULL, false, stdout);
        if (sort_order == default_sort_order &&
            parent_pattern == default_parent_pattern)
index 8027309..690a96d 100644 (file)
@@ -95,8 +95,8 @@ typedef union event_union {
 } event_t;
 
 struct events_stats {
-       unsigned long total;
-       unsigned long lost;
+       u64 total;
+       u64 lost;
 };
 
 void event__print_totals(void);
index 2ca6215..29465d4 100644 (file)
@@ -62,6 +62,18 @@ static int e_snprintf(char *str, size_t size, const char *format, ...)
        return ret;
 }
 
+/* Check the name is good for event/group */
+static bool check_event_name(const char *name)
+{
+       if (!isalpha(*name) && *name != '_')
+               return false;
+       while (*++name != '\0') {
+               if (!isalpha(*name) && !isdigit(*name) && *name != '_')
+                       return false;
+       }
+       return true;
+}
+
 /* Parse probepoint definition. */
 static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
 {
@@ -82,6 +94,9 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
                ptr = strchr(arg, ':');
                if (ptr)        /* Group name is not supported yet. */
                        semantic_error("Group name is not supported yet.");
+               if (!check_event_name(arg))
+                       semantic_error("%s is bad for event name -it must "
+                                      "follow C symbol-naming rule.", arg);
                pp->event = strdup(arg);
                arg = tmp;
        }
index 5e4050c..a4086aa 100644 (file)
@@ -1,9 +1,9 @@
 #ifndef _PROBE_FINDER_H
 #define _PROBE_FINDER_H
 
-#define MAX_PATH_LEN 256
-#define MAX_PROBE_BUFFER 1024
-#define MAX_PROBES 128
+#define MAX_PATH_LEN            256
+#define MAX_PROBE_BUFFER       1024
+#define MAX_PROBES              128
 
 static inline int is_c_varname(const char *name)
 {
@@ -12,48 +12,53 @@ static inline int is_c_varname(const char *name)
 }
 
 struct probe_point {
-       char    *event;         /* Event name */
-       char    *group;         /* Event group */
+       char                    *event;                 /* Event name */
+       char                    *group;                 /* Event group */
 
        /* Inputs */
-       char    *file;          /* File name */
-       int     line;           /* Line number */
+       char                    *file;                  /* File name */
+       int                     line;                   /* Line number */
 
-       char    *function;      /* Function name */
-       int     offset;         /* Offset bytes */
+       char                    *function;              /* Function name */
+       int                     offset;                 /* Offset bytes */
 
-       int     nr_args;        /* Number of arguments */
-       char    **args;         /* Arguments */
+       int                     nr_args;                /* Number of arguments */
+       char                    **args;                 /* Arguments */
 
-       int     retprobe;       /* Return probe */
+       int                     retprobe;               /* Return probe */
 
        /* Output */
-       int     found;          /* Number of found probe points */
-       char    *probes[MAX_PROBES];    /* Output buffers (will be allocated)*/
+       int                     found;                  /* Number of found probe points */
+       char                    *probes[MAX_PROBES];    /* Output buffers (will be allocated)*/
 };
 
 #ifndef NO_LIBDWARF
 extern int find_probepoint(int fd, struct probe_point *pp);
 
-#include <libdwarf/dwarf.h>
-#include <libdwarf/libdwarf.h>
+/* Workaround for undefined _MIPS_SZLONG bug in libdwarf.h: */
+#ifndef _MIPS_SZLONG
+# define _MIPS_SZLONG          0
+#endif
+
+#include <dwarf.h>
+#include <libdwarf.h>
 
 struct probe_finder {
-       struct probe_point      *pp;    /* Target probe point */
+       struct probe_point      *pp;                    /* Target probe point */
 
        /* For function searching */
-       Dwarf_Addr      addr;           /* Address */
-       Dwarf_Unsigned  fno;            /* File number */
-       Dwarf_Unsigned  lno;            /* Line number */
-       Dwarf_Off       inl_offs;       /* Inline offset */
-       Dwarf_Die       cu_die;         /* Current CU */
+       Dwarf_Addr              addr;                   /* Address */
+       Dwarf_Unsigned          fno;                    /* File number */
+       Dwarf_Unsigned          lno;                    /* Line number */
+       Dwarf_Off               inl_offs;               /* Inline offset */
+       Dwarf_Die               cu_die;                 /* Current CU */
 
        /* For variable searching */
-       Dwarf_Addr      cu_base;        /* Current CU base address */
-       Dwarf_Locdesc   fbloc;          /* Location of Current Frame Base */
-       const char      *var;           /* Current variable name */
-       char            *buf;           /* Current output buffer */
-       int             len;            /* Length of output buffer */
+       Dwarf_Addr              cu_base;                /* Current CU base address */
+       Dwarf_Locdesc           fbloc;                  /* Location of Current Frame Base */
+       const char              *var;                   /* Current variable name */
+       char                    *buf;                   /* Current output buffer */
+       int                     len;                    /* Length of output buffer */
 };
 #endif /* NO_LIBDWARF */