Merge branch 'next' into for-linus
authorJames Morris <jmorris@namei.org>
Thu, 10 Sep 2009 22:04:49 +0000 (08:04 +1000)
committerJames Morris <jmorris@namei.org>
Thu, 10 Sep 2009 22:04:49 +0000 (08:04 +1000)
260 files changed:
Documentation/filesystems/9p.txt
MAINTAINERS
Makefile
arch/arm/configs/kirkwood_defconfig
arch/arm/mach-kirkwood/ts219-setup.c
arch/arm/plat-orion/include/plat/gpio.h
arch/avr32/boards/favr-32/setup.c
arch/avr32/lib/memcpy.S
arch/ia64/kernel/dma-mapping.c
arch/ia64/lib/ip_fast_csum.S
arch/m68k/amiga/config.c
arch/m68k/include/asm/motorola_pgalloc.h
arch/m68k/include/asm/pgtable_mm.h
arch/m68k/include/asm/unistd.h
arch/m68k/kernel/entry.S
arch/m68knommu/kernel/syscalltable.S
arch/parisc/kernel/traps.c
arch/powerpc/configs/ps3_defconfig
arch/powerpc/kernel/power7-pmu.c
arch/powerpc/platforms/ps3/time.c
arch/powerpc/sysdev/xilinx_intc.c
arch/s390/kernel/setup.c
arch/sparc/configs/sparc32_defconfig
arch/sparc/configs/sparc64_defconfig
arch/sparc/include/asm/pgtable_64.h
arch/sparc/kernel/irq_64.c
arch/sparc/kernel/ktlb.S
arch/sparc/kernel/nmi.c
arch/sparc/kernel/sun4d_smp.c
arch/sparc/kernel/sun4m_smp.c
arch/sparc/kernel/sys32.S
arch/sparc/kernel/systbls_64.S
arch/sparc/mm/fault_32.c
arch/sparc/mm/fault_64.c
arch/sparc/mm/init_64.c
arch/sparc/mm/init_64.h
arch/sparc/prom/misc_64.c
arch/sparc/prom/printf.c
arch/x86/boot/compressed/Makefile
arch/x86/include/asm/pgtable.h
arch/x86/kernel/apic/ipi.c
arch/x86/kernel/apic/probe_64.c
arch/x86/kernel/cpu/Makefile
arch/x86/kernel/head_32.S
arch/x86/kernel/process.c
arch/x86/kernel/vmlinux.lds.S
arch/x86/mm/init_64.c
arch/x86/mm/pat.c
arch/x86/mm/tlb.c
arch/x86/xen/Makefile
arch/x86/xen/enlighten.c
block/blk-sysfs.c
crypto/algapi.c
drivers/acpi/acpica/exstorob.c
drivers/acpi/processor_core.c
drivers/acpi/processor_idle.c
drivers/acpi/processor_thermal.c
drivers/acpi/processor_throttling.c
drivers/acpi/video.c
drivers/ata/ata_piix.c
drivers/block/aoe/aoe.h
drivers/block/aoe/aoeblk.c
drivers/block/aoe/aoedev.c
drivers/char/agp/intel-agp.c
drivers/char/n_tty.c
drivers/char/pty.c
drivers/char/tty_ldisc.c
drivers/cpufreq/cpufreq.c
drivers/firewire/core-iso.c
drivers/firewire/ohci.c
drivers/firewire/sbp2.c
drivers/gpu/drm/drm_sysfs.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_bios.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_dvo.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_tv.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r420.c
drivers/gpu/drm/radeon/r520.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_cp.c
drivers/gpu/drm/radeon/radeon_drv.h
drivers/gpu/drm/radeon/radeon_gem.c
drivers/gpu/drm/radeon/radeon_kms.c
drivers/gpu/drm/radeon/radeon_reg.h
drivers/gpu/drm/radeon/radeon_state.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rs690.c
drivers/gpu/drm/radeon/rv515.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-stu300.c
drivers/ide/ide-cs.c
drivers/input/joydev.c
drivers/input/joystick/iforce/iforce-main.c
drivers/input/joystick/iforce/iforce-usb.c
drivers/input/keyboard/atkbd.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/tablet/wacom_sys.c
drivers/input/touchscreen/ucb1400_ts.c
drivers/leds/ledtrig-gpio.c
drivers/macintosh/via-maciisi.c
drivers/md/dm-exception-store.c
drivers/md/dm-exception-store.h
drivers/md/dm-log-userspace-base.c
drivers/md/dm-log-userspace-transfer.c
drivers/md/dm-log-userspace-transfer.h
drivers/md/dm-raid1.c
drivers/md/dm-snap-persistent.c
drivers/md/dm-snap.c
drivers/md/dm-stripe.c
drivers/md/dm-table.c
drivers/md/dm.c
drivers/media/dvb/siano/Kconfig
drivers/media/dvb/siano/Makefile
drivers/media/dvb/siano/smsdvb.c
drivers/media/dvb/siano/smssdio.c
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/em28xx/em28xx.h
drivers/media/video/gspca/Kconfig
drivers/media/video/zr364xx.c
drivers/mtd/devices/m25p80.c
drivers/mtd/nand/orion_nand.c
drivers/mtd/nftlcore.c
drivers/net/Kconfig
drivers/net/arm/w90p910_ether.c
drivers/net/e100.c
drivers/net/fec_mpc52xx.c
drivers/net/gianfar.c
drivers/net/ibm_newemac/core.c
drivers/net/irda/au1k_ir.c
drivers/net/irda/pxaficp_ir.c
drivers/net/irda/sa1100_ir.c
drivers/net/ixp2000/ixpdev.c
drivers/net/macb.c
drivers/net/mlx4/en_tx.c
drivers/net/smc91x.c
drivers/net/virtio_net.c
drivers/net/wireless/ipw2x00/ipw2200.c
drivers/net/wireless/orinoco/hw.c
drivers/net/wireless/rtl818x/rtl8187_dev.c
drivers/net/yellowfin.c
drivers/pci/iov.c
drivers/pci/pci-driver.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/setup-bus.c
drivers/pci/setup-res.c
drivers/platform/x86/toshiba_acpi.c
drivers/platform/x86/wmi.c
drivers/pps/pps.c
drivers/s390/block/dasd.c
drivers/s390/cio/device.c
drivers/sbus/char/bbc_envctrl.c
drivers/scsi/mpt2sas/mpt2sas_base.c
drivers/scsi/mpt2sas/mpt2sas_base.h
drivers/scsi/mpt2sas/mpt2sas_config.c
drivers/scsi/mpt2sas/mpt2sas_scsih.c
drivers/thermal/thermal_sys.c
drivers/video/xen-fbfront.c
drivers/watchdog/ar7_wdt.c
fs/9p/v9fs.c
fs/9p/v9fs.h
fs/9p/vfs_inode.c
fs/9p/vfs_super.c
fs/afs/file.c
fs/autofs4/expire.c
fs/btrfs/inode.c
fs/buffer.c
fs/compat.c
fs/exec.c
fs/ext2/namei.c
fs/ext3/Kconfig
fs/ext3/super.c
fs/hugetlbfs/inode.c
fs/jffs2/wbuf.c
fs/namei.c
fs/nfs/nfs4state.c
fs/nilfs2/btnode.c
fs/notify/inotify/inotify_fsnotify.c
fs/notify/inotify/inotify_user.c
fs/ocfs2/alloc.c
fs/ocfs2/aops.c
fs/ocfs2/dcache.c
fs/ocfs2/dlm/dlmunlock.c
fs/ocfs2/ocfs2_lockid.h
fs/ocfs2/quota_global.c
fs/ocfs2/super.c
fs/xfs/linux-2.6/xfs_ioctl32.c
include/acpi/processor.h
include/crypto/algapi.h
include/crypto/internal/skcipher.h
include/drm/radeon_drm.h
include/linux/binfmts.h
include/linux/bitmap.h
include/linux/cpumask.h
include/linux/device-mapper.h
include/linux/dm-log-userspace.h
include/linux/flex_array.h
include/linux/fs.h
include/linux/hugetlb.h
include/linux/lmb.h
include/linux/ucb1400.h
include/linux/workqueue.h
init/main.c
ipc/shm.c
kernel/fork.c
kernel/module.c
kernel/perf_counter.c
kernel/time/clockevents.c
kernel/time/tick-broadcast.c
kernel/time/timer_list.c
kernel/trace/ftrace.c
kernel/trace/trace.c
lib/bitmap.c
lib/dma-debug.c
lib/flex_array.c
lib/lmb.c
mm/nommu.c
mm/page_alloc.c
mm/percpu.c
mm/rmap.c
mm/slub.c
mm/vmscan.c
net/9p/client.c
net/9p/error.c
net/9p/trans_fd.c
net/9p/trans_rdma.c
net/9p/trans_virtio.c
net/core/netpoll.c
net/core/sock.c
net/ipv4/ip_output.c
net/ipv6/af_inet6.c
net/llc/af_llc.c
net/mac80211/key.c
net/netfilter/xt_quota.c
net/sched/sch_api.c
net/sunrpc/clnt.c
security/integrity/ima/ima_crypto.c
security/integrity/ima/ima_main.c
sound/core/pcm_lib.c
sound/pci/ali5451/ali5451.c
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_via.c
sound/pci/oxygen/oxygen_lib.c
sound/pci/oxygen/oxygen_pcm.c
sound/pci/vx222/vx222_ops.c
tools/perf/builtin-annotate.c
tools/perf/builtin-report.c

index bf8080640eba405d01aac5a101623e825b542d90..6208f55c44c352b3bcef39514fdd147684ac9064 100644 (file)
@@ -123,6 +123,9 @@ available from the same CVS repository.
 There are user and developer mailing lists available through the v9fs project
 on sourceforge (http://sourceforge.net/projects/v9fs).
 
+A stand-alone version of the module (which should build for any 2.6 kernel)
+is available via (http://github.com/ericvh/9p-sac/tree/master)
+
 News and other information is maintained on SWiK (http://swik.net/v9fs).
 
 Bug reports may be issued through the kernel.org bugzilla 
index 60299a9a7adbe05410f2e01d2a3facd7e3a4b81e..8dca9d89c6c1d1d04e65e58e881e902b0e450d09 100644 (file)
@@ -2239,8 +2239,7 @@ S:        Maintained
 F:     drivers/media/video/gspca/pac207.c
 
 GSPCA SN9C20X SUBDRIVER
-P:     Brian Johnson
-M:     brijohn@gmail.com
+M:     Brian Johnson <brijohn@gmail.com>
 L:     linux-media@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
 S:     Maintained
index abcfa85f8f825392890bc26da007e5af3fd94d6c..60de4ef312547da0264a363c87d0165626a6db8c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 31
-EXTRAVERSION = -rc6
+EXTRAVERSION =
 NAME = Man-Eating Seals of Antiquity
 
 # *DOCUMENTATION*
index 0a1abb978d7efe4b8b475fc588eee5a1e4e54deb..af74cc2de8b6827448b4f40e51c9c5f9c3a4638b 100644 (file)
@@ -629,7 +629,7 @@ CONFIG_SCSI_LOWLEVEL=y
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
-# CONFIG_SATA_AHCI is not set
+CONFIG_SATA_AHCI=y
 # CONFIG_SATA_SIL24 is not set
 CONFIG_ATA_SFF=y
 # CONFIG_SATA_SVW is not set
index 01aa213c0a6ffda67086c8c3aaac24dbfd4b5113..ec1a64f263d224285b9478f04a3c79cf85e173b7 100644 (file)
@@ -206,6 +206,15 @@ static void __init qnap_ts219_init(void)
 
 }
 
+static int __init ts219_pci_init(void)
+{
+   if (machine_is_ts219())
+           kirkwood_pcie_init();
+
+   return 0;
+}
+subsys_initcall(ts219_pci_init);
+
 MACHINE_START(TS219, "QNAP TS-119/TS-219")
        /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
        .phys_io        = KIRKWOOD_REGS_PHYS_BASE,
index 9646a94ed3d06aa1937f8d9889d11248777ebec3..07c430fdc9ef6489328337c05cee85fecb49524c 100644 (file)
@@ -11,6 +11,8 @@
 #ifndef __PLAT_GPIO_H
 #define __PLAT_GPIO_H
 
+#include <linux/init.h>
+
 /*
  * GENERIC_GPIO primitives.
  */
index 46c9b0a224cfb01812684d74f2f6b06fb8cfcb1c..75f19f47fb2fb92a8fea40b10ddd303d0f837ca8 100644 (file)
@@ -72,6 +72,10 @@ static struct ads7846_platform_data ads7843_data = {
        .debounce_max           = 20,
        .debounce_rep           = 4,
        .debounce_tol           = 5,
+
+       .keep_vref_on           = true,
+       .settle_delay_usecs     = 500,
+       .penirq_recheck_delay_usecs = 100,
 };
 
 static struct spi_board_info __initdata spi1_board_info[] = {
index 0abb26142b64689ae717f97be7f173a95e92861f..c2ca49d705af704da614ef7ff2dee9b4d253f975 100644 (file)
@@ -24,8 +24,8 @@ memcpy:
        brne    1f
 
        /* At this point, "from" is word-aligned */
-2:     sub     r10, 4
-       mov     r9, r12
+2:     mov     r9, r12
+5:     sub     r10, 4
        brlt    4f
 
 3:     ld.w    r8, r11++
@@ -49,6 +49,7 @@ memcpy:
 
        /* Handle unaligned "from" pointer */
 1:     sub     r10, 4
+       movlt   r9, r12
        brlt    4b
        add     r10, r9
        lsl     r9, 2
@@ -59,4 +60,13 @@ memcpy:
        st.b    r12++, r8
        ld.ub   r8, r11++
        st.b    r12++, r8
-       rjmp    2b
+       mov     r8, r12
+       add     pc, pc, r9
+       sub     r8, 1
+       nop
+       sub     r8, 1
+       nop
+       sub     r8, 1
+       nop
+       mov     r9, r8
+       rjmp    5b
index 39a3cd0a417326be10680e9d9cb52458e400051f..f2c1600da097f00a6c6c388ded1a9e5523dd39d9 100644 (file)
@@ -10,7 +10,9 @@ EXPORT_SYMBOL(dma_ops);
 
 static int __init dma_init(void)
 {
-       dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+       dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+
+       return 0;
 }
 fs_initcall(dma_init);
 
index 1f86aeb2c9485bb70054280b103fa8280bbad3dc..620d9dc5220f377c9cd2da899a81795054a27ad0 100644 (file)
@@ -96,20 +96,22 @@ END(ip_fast_csum)
 GLOBAL_ENTRY(csum_ipv6_magic)
        ld4     r20=[in0],4
        ld4     r21=[in1],4
-       dep     r15=in3,in2,32,16
+       zxt4    in2=in2
        ;;
        ld4     r22=[in0],4
        ld4     r23=[in1],4
-       mux1    r15=r15,@rev
+       dep     r15=in3,in2,32,16
        ;;
        ld4     r24=[in0],4
        ld4     r25=[in1],4
-       shr.u   r15=r15,16
+       mux1    r15=r15,@rev
        add     r16=r20,r21
        add     r17=r22,r23
+       zxt4    in4=in4
        ;;
        ld4     r26=[in0],4
        ld4     r27=[in1],4
+       shr.u   r15=r15,16
        add     r18=r24,r25
        add     r8=r16,r17
        ;;
index 6e562751ad51b5653181165d8b4ffc54f6cb1b8b..6c74751c7b821bbc5eedfeeba20a2bc9673149bb 100644 (file)
@@ -574,10 +574,11 @@ static int a2000_hwclk(int op, struct rtc_time *t)
 
        tod_2000.cntrl1 = TOD2000_CNTRL1_HOLD;
 
-       while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) {
+       while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt) {
                tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;
                udelay(70);
                tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;
+               --cnt;
        }
 
        if (!cnt)
@@ -649,10 +650,11 @@ static int amiga_set_clock_mmss(unsigned long nowtime)
 
                tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;
 
-               while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) {
+               while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt) {
                        tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;
                        udelay(70);
                        tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;
+                       --cnt;
                }
 
                if (!cnt)
index 15ee4c74a9f0621c6ca4d45380e6267475edf8e5..2f02f264e6944dd7fd11d8d4ffe0e10244fe1f60 100644 (file)
@@ -36,12 +36,10 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addres
                return NULL;
 
        pte = kmap(page);
-       if (pte) {
-               __flush_page_to_ram(pte);
-               flush_tlb_kernel_page(pte);
-               nocache_page(pte);
-       }
-       kunmap(pte);
+       __flush_page_to_ram(pte);
+       flush_tlb_kernel_page(pte);
+       nocache_page(pte);
+       kunmap(page);
        pgtable_page_ctor(page);
        return page;
 }
index 0b604f0f192d5916b74aee3026c70a7351834671..fe60e1abaee8900523cb827ea8d9ca1a410dcde8 100644 (file)
@@ -135,8 +135,6 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
 #endif
 
 #ifndef __ASSEMBLY__
-#include <asm-generic/pgtable.h>
-
 /*
  * Macro to mark a page protection value as "uncacheable".
  */
@@ -154,6 +152,7 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
            ? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S))  \
            : (prot)))
 
+#include <asm-generic/pgtable.h>
 #endif /* !__ASSEMBLY__ */
 
 /*
index aa29a8640f74819eba8ab1a07ef0ecec1826ee95..946d8691f2b007af1d35ace8b9fbd4864ce7b5ba 100644 (file)
 #define __NR_inotify_init1     328
 #define __NR_preadv            329
 #define __NR_pwritev           330
+#define __NR_rt_tgsigqueueinfo 331
+#define __NR_perf_counter_open 332
 
 #ifdef __KERNEL__
 
-#define NR_syscalls            331
+#define NR_syscalls            333
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
index 8744f60c07a99618394bd31255b7ce5cf2e12eca..c3735cd6207e585e38a788ae84190db375ccc798 100644 (file)
@@ -755,4 +755,6 @@ sys_call_table:
        .long sys_inotify_init1
        .long sys_preadv
        .long sys_pwritev               /* 330 */
+       .long sys_rt_tgsigqueueinfo
+       .long sys_perf_counter_open
 
index c0b8782832fd11f578963c54159d9e06f7f4c3e4..0ae123e089853db14487cc323a6811c6e2c2f703 100644 (file)
@@ -349,6 +349,8 @@ ENTRY(sys_call_table)
        .long sys_inotify_init1
        .long sys_preadv
        .long sys_pwritev               /* 330 */
+       .long sys_rt_tgsigqueueinfo
+       .long sys_perf_counter_open
 
        .rept NR_syscalls-(.-sys_call_table)/4
                .long sys_ni_syscall
index 528f0ff9b2738314ab61871379b0d8c980c4b530..8b58bf0b7d5aa47fd6f54317c74a0528e253b86c 100644 (file)
@@ -532,7 +532,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
                /* Kill the user process later */
                regs->iaoq[0] = 0 | 3;
                regs->iaoq[1] = regs->iaoq[0] + 4;
-               regs->iasq[0] = regs->iasq[0] = regs->sr[7];
+               regs->iasq[0] = regs->iasq[1] = regs->sr[7];
                regs->gr[0] &= ~PSW_B;
                return;
        }
index e28e65e7a0e19ea1cc862c94360b1623fe3278ff..7de127e4ceeffbf36f4ae9e718d9b9896c733198 100644 (file)
@@ -1,13 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc5
-# Fri May 15 10:37:00 2009
+# Linux kernel version: 2.6.31-rc7
+# Mon Aug 24 17:38:50 2009
 #
 CONFIG_PPC64=y
 
 #
 # Processor support
 #
+CONFIG_PPC_BOOK3S_64=y
 CONFIG_PPC_BOOK3S=y
 # CONFIG_POWER4_ONLY is not set
 CONFIG_POWER3=y
@@ -20,6 +21,7 @@ CONFIG_PPC_STD_MMU=y
 CONFIG_PPC_STD_MMU_64=y
 CONFIG_PPC_MM_SLICES=y
 CONFIG_VIRT_CPU_ACCOUNTING=y
+CONFIG_PPC_HAVE_PMU_SUPPORT=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
 CONFIG_64BIT=y
@@ -31,6 +33,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_HAVE_SETUP_PER_CPU_AREA=y
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -41,7 +44,6 @@ CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_ARCH_HAS_ILOG2_U64=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_PPC=y
@@ -62,6 +64,7 @@ CONFIG_DTC=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -113,7 +116,6 @@ CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -126,7 +128,14 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_COUNTERS=y
+
+#
+# Performance Counters
+#
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
@@ -145,6 +154,11 @@ CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
 # CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
@@ -210,7 +224,7 @@ CONFIG_PPC_CELL=y
 #
 # Cell Broadband Engine options
 #
-CONFIG_SPU_FS=y
+CONFIG_SPU_FS=m
 CONFIG_SPU_FS_64K_LS=y
 # CONFIG_SPU_TRACE is not set
 CONFIG_SPU_BASE=y
@@ -255,6 +269,7 @@ CONFIG_BINFMT_MISC=y
 CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y
 # CONFIG_IOMMU_VMERGE is not set
 CONFIG_IOMMU_HELPER=y
+# CONFIG_SWIOTLB is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
@@ -285,9 +300,9 @@ CONFIG_MIGRATION=y
 CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
-CONFIG_UNEVICTABLE_LRU=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_ARCH_MEMORY_PROBE=y
 CONFIG_PPC_HAS_HASH_64K=y
 CONFIG_PPC_4K_PAGES=y
@@ -399,6 +414,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -433,11 +449,14 @@ CONFIG_BT_HCIBTUSB=m
 CONFIG_WIRELESS=y
 CONFIG_CFG80211=m
 # CONFIG_CFG80211_REG_DEBUG is not set
+# CONFIG_CFG80211_DEBUGFS is not set
 # CONFIG_WIRELESS_OLD_REGULATORY is not set
 CONFIG_WIRELESS_EXT=y
 # CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_LIB80211 is not set
 CONFIG_MAC80211=m
+CONFIG_MAC80211_DEFAULT_PS=y
+CONFIG_MAC80211_DEFAULT_PS_VALUE=1
 
 #
 # Rate control algorithm selection
@@ -447,7 +466,6 @@ CONFIG_MAC80211_RC_PID=y
 CONFIG_MAC80211_RC_DEFAULT_PID=y
 # CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
 CONFIG_MAC80211_RC_DEFAULT="pid"
-# CONFIG_MAC80211_MESH is not set
 # CONFIG_MAC80211_LEDS is not set
 # CONFIG_MAC80211_DEBUGFS is not set
 # CONFIG_MAC80211_DEBUG_MENU is not set
@@ -472,77 +490,7 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
-CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=0
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_PARTITIONS is not set
-# CONFIG_MTD_TESTS is not set
-
-#
-# User Modules And Translation Layers
-#
-# CONFIG_MTD_CHAR is not set
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-# CONFIG_RFD_FTL is not set
-# CONFIG_SSFDC is not set
-# CONFIG_MTD_OOPS is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_ONENAND is not set
-
-#
-# LPDDR flash memory drivers
-#
-# CONFIG_MTD_LPDDR is not set
-
-#
-# UBI - Unsorted block images
-#
-# CONFIG_MTD_UBI is not set
+# CONFIG_MTD is not set
 CONFIG_OF_DEVICE=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
@@ -590,10 +538,6 @@ CONFIG_BLK_DEV_SR=y
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 CONFIG_CHR_DEV_SG=m
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 CONFIG_SCSI_MULTI_LUN=y
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -626,7 +570,6 @@ CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_UEVENT is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -646,10 +589,11 @@ CONFIG_MII=m
 # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
 CONFIG_NETDEV_1000=y
 CONFIG_GELIC_NET=y
 CONFIG_GELIC_WIRELESS=y
-CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE=y
+# CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE is not set
 # CONFIG_NETDEV_10000 is not set
 
 #
@@ -669,8 +613,7 @@ CONFIG_WLAN_80211=y
 # CONFIG_HOSTAP is not set
 # CONFIG_B43 is not set
 # CONFIG_B43LEGACY is not set
-CONFIG_ZD1211RW=m
-# CONFIG_ZD1211RW_DEBUG is not set
+# CONFIG_ZD1211RW is not set
 # CONFIG_RT2X00 is not set
 
 #
@@ -682,7 +625,7 @@ CONFIG_ZD1211RW=m
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
-CONFIG_USB_PEGASUS=m
+# CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
 CONFIG_USB_USBNET=m
 CONFIG_USB_NET_AX8817X=m
@@ -693,10 +636,11 @@ CONFIG_USB_NET_AX8817X=m
 # CONFIG_USB_NET_GL620A is not set
 # CONFIG_USB_NET_NET1080 is not set
 # CONFIG_USB_NET_PLUSB is not set
-CONFIG_USB_NET_MCS7830=m
+# CONFIG_USB_NET_MCS7830 is not set
 # CONFIG_USB_NET_RNDIS_HOST is not set
 # CONFIG_USB_NET_CDC_SUBSET is not set
 # CONFIG_USB_NET_ZAURUS is not set
+# CONFIG_USB_NET_INT51X1 is not set
 # CONFIG_WAN is not set
 CONFIG_PPP=m
 CONFIG_PPP_MULTILINK=y
@@ -771,8 +715,7 @@ CONFIG_DEVKMEM=y
 #
 CONFIG_UNIX98_PTYS=y
 # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_LEGACY_PTYS is not set
 # CONFIG_HVC_UDBG is not set
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
@@ -782,6 +725,11 @@ CONFIG_LEGACY_PTY_COUNT=16
 # CONFIG_TCG_TPM is not set
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
@@ -805,22 +753,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -898,6 +831,11 @@ CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
 # CONFIG_SND_DRIVERS is not set
 CONFIG_SND_PPC=y
 CONFIG_SND_PS3=m
@@ -930,29 +868,34 @@ CONFIG_USB_HIDDEV=y
 # Special HID drivers
 #
 # CONFIG_HID_A4TECH is not set
-# CONFIG_HID_APPLE is not set
-# CONFIG_HID_BELKIN is not set
-# CONFIG_HID_CHERRY is not set
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
 # CONFIG_HID_CHICONY is not set
 # CONFIG_HID_CYPRESS is not set
-# CONFIG_DRAGONRISE_FF is not set
-# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_DRAGONRISE is not set
+CONFIG_HID_EZKEY=m
 # CONFIG_HID_KYE is not set
 # CONFIG_HID_GYRATION is not set
 # CONFIG_HID_KENSINGTON is not set
-# CONFIG_HID_LOGITECH is not set
-# CONFIG_HID_MICROSOFT is not set
+CONFIG_HID_LOGITECH=m
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+CONFIG_HID_MICROSOFT=m
 # CONFIG_HID_MONTEREY is not set
 # CONFIG_HID_NTRIG is not set
 # CONFIG_HID_PANTHERLORD is not set
 # CONFIG_HID_PETALYNX is not set
 # CONFIG_HID_SAMSUNG is not set
 CONFIG_HID_SONY=m
-# CONFIG_HID_SUNPLUS is not set
-# CONFIG_GREENASIA_FF is not set
+CONFIG_HID_SUNPLUS=m
+# CONFIG_HID_GREENASIA is not set
+CONFIG_HID_SMARTJOYPLUS=m
+# CONFIG_SMARTJOYPLUS_FF is not set
 # CONFIG_HID_TOPSEED is not set
-# CONFIG_THRUSTMASTER_FF is not set
-# CONFIG_ZEROPLUS_FF is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_WACOM is not set
+# CONFIG_HID_ZEROPLUS is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
@@ -988,6 +931,8 @@ CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
+# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
 # CONFIG_USB_OHCI_HCD_PPC_OF is not set
 # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
 CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
@@ -1115,6 +1060,10 @@ CONFIG_RTC_DRV_PS3=m
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -1141,11 +1090,12 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1205,7 +1155,6 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
-# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -1222,6 +1171,7 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 CONFIG_LOCKD=y
@@ -1359,7 +1309,6 @@ CONFIG_DEBUG_MEMORY_INIT=y
 CONFIG_DEBUG_LIST=y
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
@@ -1374,31 +1323,21 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
 CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_FTRACE is not set
 # CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 CONFIG_DEBUG_STACKOVERFLOW=y
 # CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
index 388cf57ad827b8d187c49dc34eb0ec8deaf48db5..018d094d92f91d2af529f0eff119f3b3f27983ef 100644 (file)
@@ -317,7 +317,7 @@ static int power7_generic_events[] = {
  */
 static int power7_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
        [C(L1D)] = {            /*      RESULT_ACCESS   RESULT_MISS */
-               [C(OP_READ)] = {        0x400f0,        0xc880  },
+               [C(OP_READ)] = {        0xc880,         0x400f0 },
                [C(OP_WRITE)] = {       0,              0x300f0 },
                [C(OP_PREFETCH)] = {    0xd8b8,         0       },
        },
@@ -327,8 +327,8 @@ static int power7_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
                [C(OP_PREFETCH)] = {    0x408a,         0       },
        },
        [C(LL)] = {             /*      RESULT_ACCESS   RESULT_MISS */
-               [C(OP_READ)] = {        0x6080,         0x6084  },
-               [C(OP_WRITE)] = {       0x6082,         0x6086  },
+               [C(OP_READ)] = {        0x16080,        0x26080 },
+               [C(OP_WRITE)] = {       0x16082,        0x26082 },
                [C(OP_PREFETCH)] = {    0,              0       },
        },
        [C(DTLB)] = {           /*      RESULT_ACCESS   RESULT_MISS */
index b178a1e66c915e8ab6e85b0eec51830b6a05adf1..40b5cb433005f615381d205e3d281dbd5b1377f4 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 
+#include <asm/firmware.h>
 #include <asm/rtc.h>
 #include <asm/lv1call.h>
 #include <asm/ps3.h>
@@ -84,6 +85,9 @@ static int __init ps3_rtc_init(void)
 {
        struct platform_device *pdev;
 
+       if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
+               return -ENODEV;
+
        pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0);
        if (IS_ERR(pdev))
                return PTR_ERR(pdev);
index 3ee1fd37bbfc3b819107a8dd4d9b2496f59ecc84..40edad520770e335c1afc7a7af0463f159972ef4 100644 (file)
@@ -234,7 +234,6 @@ static void xilinx_i8259_cascade(unsigned int irq, struct irq_desc *desc)
                generic_handle_irq(cascade_irq);
 
        /* Let xilinx_intc end the interrupt */
-       desc->chip->ack(irq);
        desc->chip->unmask(irq);
 }
 
index 9717717c6fea5595b364e8b321ee6fa284580396..cbb897bc50bd5d56606c190cafb69f5c4670d8fb 100644 (file)
@@ -154,6 +154,20 @@ static int __init condev_setup(char *str)
 
 __setup("condev=", condev_setup);
 
+static void __init set_preferred_console(void)
+{
+       if (MACHINE_IS_KVM) {
+               add_preferred_console("hvc", 0, NULL);
+               s390_virtio_console_init();
+               return;
+       }
+
+       if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP)
+               add_preferred_console("ttyS", 0, NULL);
+       if (CONSOLE_IS_3270)
+               add_preferred_console("tty3270", 0, NULL);
+}
+
 static int __init conmode_setup(char *str)
 {
 #if defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE)
@@ -168,6 +182,7 @@ static int __init conmode_setup(char *str)
        if (strncmp(str, "3270", 5) == 0)
                SET_CONSOLE_3270;
 #endif
+       set_preferred_console();
         return 1;
 }
 
@@ -780,9 +795,6 @@ static void __init setup_hwcaps(void)
 void __init
 setup_arch(char **cmdline_p)
 {
-       /* set up preferred console */
-       add_preferred_console("ttyS", 0, NULL);
-
         /*
          * print what head.S has found out about the machine
          */
@@ -802,11 +814,9 @@ setup_arch(char **cmdline_p)
        if (MACHINE_IS_VM)
                pr_info("Linux is running as a z/VM "
                        "guest operating system in 64-bit mode\n");
-       else if (MACHINE_IS_KVM) {
+       else if (MACHINE_IS_KVM)
                pr_info("Linux is running under KVM in 64-bit mode\n");
-               add_preferred_console("hvc", 0, NULL);
-               s390_virtio_console_init();
-       } else
+       else
                pr_info("Linux is running natively in 64-bit mode\n");
 #endif /* CONFIG_64BIT */
 
@@ -851,6 +861,7 @@ setup_arch(char **cmdline_p)
 
         /* Setup default console */
        conmode_default();
+       set_preferred_console();
 
        /* Setup zfcpdump support */
        setup_zfcpdump(console_devno);
index 8bcd27af724bbc2ac36460b13d94c88aa19be2ce..a0f62a808edb91b4deafece2dcabf1f0efa9a838 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc2
-# Fri Apr 17 04:04:46 2009
+# Linux kernel version: 2.6.31-rc1
+# Tue Aug 18 23:45:52 2009
 #
 # CONFIG_64BIT is not set
 CONFIG_SPARC=y
@@ -17,6 +17,7 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_OF=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -74,7 +75,6 @@ CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -87,8 +87,13 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+
+#
+# Performance Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
+# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
@@ -97,6 +102,10 @@ CONFIG_SLAB=y
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+
+#
+# GCOV-based kernel profiling
+#
 # CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
@@ -109,7 +118,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -154,9 +163,9 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
-CONFIG_UNEVICTABLE_LRU=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_SUN_PM=y
 # CONFIG_SPARC_LED is not set
 CONFIG_SERIAL_CONSOLE=y
@@ -264,6 +273,7 @@ CONFIG_IPV6_TUNNEL=m
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -281,7 +291,11 @@ CONFIG_WIRELESS=y
 CONFIG_WIRELESS_OLD_REGULATORY=y
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
-# CONFIG_MAC80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+CONFIG_MAC80211_DEFAULT_PS_VALUE=0
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -335,6 +349,7 @@ CONFIG_MISC_DEVICES=y
 # EEPROM support
 #
 # CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -358,10 +373,6 @@ CONFIG_BLK_DEV_SR=m
 # CONFIG_BLK_DEV_SR_VENDOR is not set
 CONFIG_CHR_DEV_SG=m
 # CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -379,6 +390,7 @@ CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -387,6 +399,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
@@ -401,7 +414,6 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
@@ -426,13 +438,16 @@ CONFIG_SCSI_SUNESP=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -463,6 +478,7 @@ CONFIG_SUNQE=m
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
 # CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
@@ -482,6 +498,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
@@ -629,6 +646,11 @@ CONFIG_HW_RANDOM=m
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
@@ -668,22 +690,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -776,6 +783,10 @@ CONFIG_RTC_DRV_M48T59=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -799,10 +810,12 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -985,6 +998,7 @@ CONFIG_KGDB=y
 CONFIG_KGDB_SERIAL_CONSOLE=y
 CONFIG_KGDB_TESTS=y
 # CONFIG_KGDB_TESTS_ON_BOOT is not set
+# CONFIG_KMEMCHECK is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_STACK_DEBUG is not set
 
index 0123a4c596cef67a537d6a3f660b0cbf0a3b74c6..fdddf7a6f7252b12b40823ad55bc705f3c38a7fa 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30
-# Tue Jun 16 04:59:36 2009
+# Linux kernel version: 2.6.31-rc1
+# Tue Aug 18 23:56:02 2009
 #
 CONFIG_64BIT=y
 CONFIG_SPARC=y
@@ -26,6 +26,7 @@ CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_OF=y
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -119,6 +120,11 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
 # CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
@@ -204,7 +210,6 @@ CONFIG_MIGRATION=y
 CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_NR_QUICK=1
-CONFIG_UNEVICTABLE_LRU=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 CONFIG_DEFAULT_MMAP_MIN_ADDR=8192
@@ -410,6 +415,7 @@ CONFIG_MISC_DEVICES=y
 #
 # CONFIG_EEPROM_AT24 is not set
 # CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
@@ -562,6 +568,7 @@ CONFIG_BLK_DEV_DM=m
 CONFIG_DM_CRYPT=m
 CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
+# CONFIG_DM_LOG_USERSPACE is not set
 CONFIG_DM_ZERO=m
 # CONFIG_DM_MULTIPATH is not set
 # CONFIG_DM_DELAY is not set
@@ -573,7 +580,11 @@ CONFIG_DM_ZERO=m
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -667,6 +678,7 @@ CONFIG_E1000E=m
 # CONFIG_VIA_VELOCITY is not set
 CONFIG_TIGON3=m
 CONFIG_BNX2=m
+# CONFIG_CNIC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
@@ -773,6 +785,7 @@ CONFIG_MOUSE_SERIAL=y
 # CONFIG_MOUSE_APPLETOUCH is not set
 # CONFIG_MOUSE_BCM5974 is not set
 # CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
@@ -870,6 +883,7 @@ CONFIG_I2C_ALGOBIT=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
+# CONFIG_I2C_DESIGNWARE is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
 
@@ -898,13 +912,17 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
@@ -959,6 +977,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
@@ -994,23 +1013,9 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -1284,7 +1289,6 @@ CONFIG_USB=y
 #
 # Miscellaneous USB options
 #
-CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_OTG is not set
@@ -1296,6 +1300,7 @@ CONFIG_USB_DEVICEFS=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
@@ -1374,7 +1379,6 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
@@ -1420,6 +1424,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -1448,6 +1453,10 @@ CONFIG_RTC_DRV_STARFIRE=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -1480,11 +1489,11 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
@@ -1560,7 +1569,7 @@ CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
 CONFIG_SUN_PARTITION=y
-CONFIG_NLS=m
+CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_CODEPAGE_437 is not set
 # CONFIG_NLS_CODEPAGE_737 is not set
index b049abf9902fdb42d4efe145d88a731dd4b6734b..0ff92fa22064f6a335233acfa39a72a6bfb88a4d 100644 (file)
@@ -726,11 +726,17 @@ extern unsigned long pte_file(pte_t);
 extern pte_t pgoff_to_pte(unsigned long);
 #define PTE_FILE_MAX_BITS      (64UL - PAGE_SHIFT - 1UL)
 
-extern unsigned long *sparc64_valid_addr_bitmap;
+extern unsigned long sparc64_valid_addr_bitmap[];
 
 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
-#define kern_addr_valid(addr)  \
-       (test_bit(__pa((unsigned long)(addr))>>22, sparc64_valid_addr_bitmap))
+static inline bool kern_addr_valid(unsigned long addr)
+{
+       unsigned long paddr = __pa(addr);
+
+       if ((paddr >> 41UL) != 0UL)
+               return false;
+       return test_bit(paddr >> 22, sparc64_valid_addr_bitmap);
+}
 
 extern int page_in_phys_avail(unsigned long paddr);
 
index f0ee79055409d34f02947e3ca6915f0e71fe9dc1..8daab33fc17d1808a0abd55bce2d4ac98af0a5c7 100644 (file)
@@ -886,7 +886,7 @@ void notrace init_irqwork_curcpu(void)
  * Therefore you cannot make any OBP calls, not even prom_printf,
  * from these two routines.
  */
-static void __cpuinit register_one_mondo(unsigned long paddr, unsigned long type, unsigned long qmask)
+static void __cpuinit notrace register_one_mondo(unsigned long paddr, unsigned long type, unsigned long qmask)
 {
        unsigned long num_entries = (qmask + 1) / 64;
        unsigned long status;
index cef8defcd7a931785acf4a8ccb8f978ee42d86bf..3ea6e8cde8c5beba98f7460d199d8a9f128057c0 100644 (file)
@@ -151,12 +151,46 @@ kvmap_dtlb_4v:
         * Must preserve %g1 and %g6 (TAG).
         */
 kvmap_dtlb_tsb4m_miss:
-       sethi           %hi(kpte_linear_bitmap), %g2
-       or              %g2, %lo(kpte_linear_bitmap), %g2
+       /* Clear the PAGE_OFFSET top virtual bits, shift
+        * down to get PFN, and make sure PFN is in range.
+        */
+       sllx            %g4, 21, %g5
 
-       /* Clear the PAGE_OFFSET top virtual bits, then shift
-        * down to get a 256MB physical address index.
+       /* Check to see if we know about valid memory at the 4MB
+        * chunk this physical address will reside within.
         */
+       srlx            %g5, 21 + 41, %g2
+       brnz,pn         %g2, kvmap_dtlb_longpath
+        nop
+
+       /* This unconditional branch and delay-slot nop gets patched
+        * by the sethi sequence once the bitmap is properly setup.
+        */
+       .globl          valid_addr_bitmap_insn
+valid_addr_bitmap_insn:
+       ba,pt           %xcc, 2f
+        nop
+       .subsection     2
+       .globl          valid_addr_bitmap_patch
+valid_addr_bitmap_patch:
+       sethi           %hi(sparc64_valid_addr_bitmap), %g7
+       or              %g7, %lo(sparc64_valid_addr_bitmap), %g7
+       .previous
+
+       srlx            %g5, 21 + 22, %g2
+       srlx            %g2, 6, %g5
+       and             %g2, 63, %g2
+       sllx            %g5, 3, %g5
+       ldx             [%g7 + %g5], %g5
+       mov             1, %g7
+       sllx            %g7, %g2, %g7
+       andcc           %g5, %g7, %g0
+       be,pn           %xcc, kvmap_dtlb_longpath
+
+2:      sethi          %hi(kpte_linear_bitmap), %g2
+       or              %g2, %lo(kpte_linear_bitmap), %g2
+
+       /* Get the 256MB physical address index. */
        sllx            %g4, 21, %g5
        mov             1, %g7
        srlx            %g5, 21 + 28, %g5
index 2c0cc72d295b079cfab695197eff38fcbd54d586..b75bf502cd424e7305959c2ca92bffd4cc88bcf4 100644 (file)
@@ -103,7 +103,7 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
        }
        if (!touched && __get_cpu_var(last_irq_sum) == sum) {
                local_inc(&__get_cpu_var(alert_counter));
-               if (local_read(&__get_cpu_var(alert_counter)) == 5 * nmi_hz)
+               if (local_read(&__get_cpu_var(alert_counter)) == 30 * nmi_hz)
                        die_nmi("BUG: NMI Watchdog detected LOCKUP",
                                regs, panic_on_timeout);
        } else {
index 54fb02468f0d57ef00ce78c610609ba43d0c1702..68791cad7b74812e79c376563b029618328aac5a 100644 (file)
@@ -162,9 +162,6 @@ extern void cpu_panic(void);
  */
  
 extern struct linux_prom_registers smp_penguin_ctable;
-extern unsigned long trapbase_cpu1[];
-extern unsigned long trapbase_cpu2[];
-extern unsigned long trapbase_cpu3[];
 
 void __init smp4d_boot_cpus(void)
 {
@@ -235,25 +232,6 @@ void __init smp4d_smp_done(void)
        *prev = first;
        local_flush_cache_all();
 
-       /* Free unneeded trap tables */
-       ClearPageReserved(virt_to_page(trapbase_cpu1));
-       init_page_count(virt_to_page(trapbase_cpu1));
-       free_page((unsigned long)trapbase_cpu1);
-       totalram_pages++;
-       num_physpages++;
-
-       ClearPageReserved(virt_to_page(trapbase_cpu2));
-       init_page_count(virt_to_page(trapbase_cpu2));
-       free_page((unsigned long)trapbase_cpu2);
-       totalram_pages++;
-       num_physpages++;
-
-       ClearPageReserved(virt_to_page(trapbase_cpu3));
-       init_page_count(virt_to_page(trapbase_cpu3));
-       free_page((unsigned long)trapbase_cpu3);
-       totalram_pages++;
-       num_physpages++;
-
        /* Ok, they are spinning and ready to go. */
        smp_processors_ready = 1;
        sun4d_distribute_irqs();
index 960b113d0006f4ff61de665c2383dd4b522a4622..762d6eedd944c585d297078855f62f7580de7e7e 100644 (file)
@@ -121,9 +121,6 @@ void __cpuinit smp4m_callin(void)
  */
  
 extern struct linux_prom_registers smp_penguin_ctable;
-extern unsigned long trapbase_cpu1[];
-extern unsigned long trapbase_cpu2[];
-extern unsigned long trapbase_cpu3[];
 
 void __init smp4m_boot_cpus(void)
 {
@@ -193,29 +190,6 @@ void __init smp4m_smp_done(void)
        *prev = first;
        local_flush_cache_all();
 
-       /* Free unneeded trap tables */
-       if (!cpu_isset(1, cpu_present_map)) {
-               ClearPageReserved(virt_to_page(trapbase_cpu1));
-               init_page_count(virt_to_page(trapbase_cpu1));
-               free_page((unsigned long)trapbase_cpu1);
-               totalram_pages++;
-               num_physpages++;
-       }
-       if (!cpu_isset(2, cpu_present_map)) {
-               ClearPageReserved(virt_to_page(trapbase_cpu2));
-               init_page_count(virt_to_page(trapbase_cpu2));
-               free_page((unsigned long)trapbase_cpu2);
-               totalram_pages++;
-               num_physpages++;
-       }
-       if (!cpu_isset(3, cpu_present_map)) {
-               ClearPageReserved(virt_to_page(trapbase_cpu3));
-               init_page_count(virt_to_page(trapbase_cpu3));
-               free_page((unsigned long)trapbase_cpu3);
-               totalram_pages++;
-               num_physpages++;
-       }
-
        /* Ok, they are spinning and ready to go. */
 }
 
index f061c4dda9efb96dd5d8a6317169af88332b6720..aed94869ad6a6436b5d4848acb322d8900baf6ff 100644 (file)
@@ -134,10 +134,12 @@ SIGN1(sys32_getpeername, sys_getpeername, %o0)
 SIGN1(sys32_getsockname, sys_getsockname, %o0)
 SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1)
 SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2)
-SIGN2(sys32_splice, sys_splice, %o0, %o1)
+SIGN2(sys32_splice, sys_splice, %o0, %o2)
 SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5)
 SIGN2(sys32_tee, sys_tee, %o0, %o1)
 SIGN1(sys32_vmsplice, compat_sys_vmsplice, %o0)
+SIGN1(sys32_truncate, sys_truncate, %o1)
+SIGN1(sys32_ftruncate, sys_ftruncate, %o1)
 
        .globl          sys32_mmap2
 sys32_mmap2:
index 6b3ee88e253c22035d5d0f80f39c472e59219dd1..2ee7250ba7ae6b50f08300cdaf064369e9dc47c1 100644 (file)
@@ -43,8 +43,8 @@ sys_call_table32:
 /*110*/        .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
        .word sys32_getgroups, compat_sys_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
 /*120*/        .word compat_sys_readv, compat_sys_writev, compat_sys_settimeofday, sys_fchown16, sys_fchmod
-       .word sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate
-/*130*/        .word sys_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall
+       .word sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys32_truncate
+/*130*/        .word sys32_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall
        .word sys_nis_syscall, sys32_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64
 /*140*/        .word sys32_sendfile64, sys_nis_syscall, sys32_futex, sys_gettid, compat_sys_getrlimit
        .word compat_sys_setrlimit, sys_pivot_root, sys32_prctl, sys_pciconfig_read, sys_pciconfig_write
index a5e30c642ee3bf33f136cababbb99bc20a9aba07..b99f81c4906f72ae3486c54d3cc1e69d15822383 100644 (file)
@@ -319,9 +319,10 @@ no_context:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       printk("VM: killing process %s\n", tsk->comm);
-       if (from_user)
-               do_group_exit(SIGKILL);
+       if (from_user) {
+               pagefault_out_of_memory();
+               return;
+       }
        goto no_context;
 
 do_sigbus:
index e5620b27c8bf6a9877367c28ca9088889f259d99..43b0da96a4fb92c4a3f5e3e1eaac67ae611832e5 100644 (file)
@@ -447,9 +447,10 @@ handle_kernel_fault:
 out_of_memory:
        insn = get_fault_insn(regs, insn);
        up_read(&mm->mmap_sem);
-       printk("VM: killing process %s\n", current->comm);
-       if (!(regs->tstate & TSTATE_PRIV))
-               do_group_exit(SIGKILL);
+       if (!(regs->tstate & TSTATE_PRIV)) {
+               pagefault_out_of_memory();
+               return;
+       }
        goto handle_kernel_fault;
 
 intr_or_no_mm:
index ed6be6ba2f4e9f7859c3e34b27fdc8e5ccc6f5ab..a70a5e1904d9d556e43fcd893b83752856d0cd3e 100644 (file)
@@ -145,7 +145,8 @@ static void __init read_obp_memory(const char *property,
             cmp_p64, NULL);
 }
 
-unsigned long *sparc64_valid_addr_bitmap __read_mostly;
+unsigned long sparc64_valid_addr_bitmap[VALID_ADDR_BITMAP_BYTES /
+                                       sizeof(unsigned long)];
 EXPORT_SYMBOL(sparc64_valid_addr_bitmap);
 
 /* Kernel physical address base and size in bytes.  */
@@ -1874,7 +1875,7 @@ static int pavail_rescan_ents __initdata;
  * memory list again, and make sure it provides at least as much
  * memory as 'pavail' does.
  */
-static void __init setup_valid_addr_bitmap_from_pavail(void)
+static void __init setup_valid_addr_bitmap_from_pavail(unsigned long *bitmap)
 {
        int i;
 
@@ -1897,8 +1898,7 @@ static void __init setup_valid_addr_bitmap_from_pavail(void)
 
                                if (new_start <= old_start &&
                                    new_end >= (old_start + PAGE_SIZE)) {
-                                       set_bit(old_start >> 22,
-                                               sparc64_valid_addr_bitmap);
+                                       set_bit(old_start >> 22, bitmap);
                                        goto do_next_page;
                                }
                        }
@@ -1919,20 +1919,21 @@ static void __init setup_valid_addr_bitmap_from_pavail(void)
        }
 }
 
+static void __init patch_tlb_miss_handler_bitmap(void)
+{
+       extern unsigned int valid_addr_bitmap_insn[];
+       extern unsigned int valid_addr_bitmap_patch[];
+
+       valid_addr_bitmap_insn[1] = valid_addr_bitmap_patch[1];
+       mb();
+       valid_addr_bitmap_insn[0] = valid_addr_bitmap_patch[0];
+       flushi(&valid_addr_bitmap_insn[0]);
+}
+
 void __init mem_init(void)
 {
        unsigned long codepages, datapages, initpages;
        unsigned long addr, last;
-       int i;
-
-       i = last_valid_pfn >> ((22 - PAGE_SHIFT) + 6);
-       i += 1;
-       sparc64_valid_addr_bitmap = (unsigned long *) alloc_bootmem(i << 3);
-       if (sparc64_valid_addr_bitmap == NULL) {
-               prom_printf("mem_init: Cannot alloc valid_addr_bitmap.\n");
-               prom_halt();
-       }
-       memset(sparc64_valid_addr_bitmap, 0, i << 3);
 
        addr = PAGE_OFFSET + kern_base;
        last = PAGE_ALIGN(kern_size) + addr;
@@ -1941,15 +1942,19 @@ void __init mem_init(void)
                addr += PAGE_SIZE;
        }
 
-       setup_valid_addr_bitmap_from_pavail();
+       setup_valid_addr_bitmap_from_pavail(sparc64_valid_addr_bitmap);
+       patch_tlb_miss_handler_bitmap();
 
        high_memory = __va(last_valid_pfn << PAGE_SHIFT);
 
 #ifdef CONFIG_NEED_MULTIPLE_NODES
-       for_each_online_node(i) {
-               if (NODE_DATA(i)->node_spanned_pages != 0) {
-                       totalram_pages +=
-                               free_all_bootmem_node(NODE_DATA(i));
+       {
+               int i;
+               for_each_online_node(i) {
+                       if (NODE_DATA(i)->node_spanned_pages != 0) {
+                               totalram_pages +=
+                                       free_all_bootmem_node(NODE_DATA(i));
+                       }
                }
        }
 #else
index 16063870a489c784eee30e0cbfb0637a9548fd4b..c2f772dbd556ffaa5a75430500fbedb9cde3d3fd 100644 (file)
@@ -5,10 +5,13 @@
  * marked non-static so that assembler code can get at them.
  */
 
-#define MAX_PHYS_ADDRESS       (1UL << 42UL)
-#define KPTE_BITMAP_CHUNK_SZ   (256UL * 1024UL * 1024UL)
+#define MAX_PHYS_ADDRESS       (1UL << 41UL)
+#define KPTE_BITMAP_CHUNK_SZ           (256UL * 1024UL * 1024UL)
 #define KPTE_BITMAP_BYTES      \
        ((MAX_PHYS_ADDRESS / KPTE_BITMAP_CHUNK_SZ) / 8)
+#define VALID_ADDR_BITMAP_CHUNK_SZ     (4UL * 1024UL * 1024UL)
+#define VALID_ADDR_BITMAP_BYTES        \
+       ((MAX_PHYS_ADDRESS / VALID_ADDR_BITMAP_CHUNK_SZ) / 8)
 
 extern unsigned long kern_linear_pte_xor[2];
 extern unsigned long kpte_linear_bitmap[KPTE_BITMAP_BYTES / sizeof(unsigned long)];
index eedffb4fec2d64132402cd3007897275962158a4..39fc6af21b7c55ddc0e752c80c745ed6c018820a 100644 (file)
@@ -88,7 +88,7 @@ void prom_cmdline(void)
 /* Drop into the prom, but completely terminate the program.
  * No chance of continuing.
  */
-void prom_halt(void)
+void notrace prom_halt(void)
 {
 #ifdef CONFIG_SUN_LDOMS
        if (ldom_domaining_enabled)
index 660943ee4c2ac7e431822dc1f99cf9e8bac294e7..ca869266b9f3d0106e60d7b8c28f5cdcf614826b 100644 (file)
  */
 
 #include <linux/kernel.h>
+#include <linux/compiler.h>
 
 #include <asm/openprom.h>
 #include <asm/oplib.h>
 
 static char ppbuf[1024];
 
-void
-prom_write(const char *buf, unsigned int n)
+void notrace prom_write(const char *buf, unsigned int n)
 {
        char ch;
 
@@ -33,8 +33,7 @@ prom_write(const char *buf, unsigned int n)
        }
 }
 
-void
-prom_printf(const char *fmt, ...)
+void notrace prom_printf(const char *fmt, ...)
 {
        va_list args;
        int i;
index e2ff504b4ddcb7fe8e3b506f5f089276fe655e2b..f8ed0658404cc559d7c65a261330dba620017f38 100644 (file)
@@ -4,7 +4,7 @@
 # create a compressed vmlinux image from the original vmlinux
 #
 
-targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma head_$(BITS).o misc.o piggy.o
+targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma head_$(BITS).o misc.o piggy.o
 
 KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
 KBUILD_CFLAGS += -fno-strict-aliasing -fPIC
index 3cc06e3fceb8e8ba2b9a7d72b7608c520aa5b81f..16748077559abf2771ce84ec0ea38eaa82dc8298 100644 (file)
@@ -2,6 +2,7 @@
 #define _ASM_X86_PGTABLE_H
 
 #include <asm/page.h>
+#include <asm/e820.h>
 
 #include <asm/pgtable_types.h>
 
@@ -269,9 +270,16 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
 
 #define canon_pgprot(p) __pgprot(massage_pgprot(p))
 
-static inline int is_new_memtype_allowed(unsigned long flags,
-                                               unsigned long new_flags)
+static inline int is_new_memtype_allowed(u64 paddr, unsigned long size,
+                                        unsigned long flags,
+                                        unsigned long new_flags)
 {
+       /*
+        * PAT type is always WB for ISA. So no need to check.
+        */
+       if (is_ISA_range(paddr, paddr + size - 1))
+               return 1;
+
        /*
         * Certain new memtypes are not allowed with certain
         * requested memtype:
index dbf5445727a9d69d5cd02e07ff7c675c916bb0d9..6ef00ba4c8864c2c0c9b7c6ece3266a15d224404 100644 (file)
@@ -106,6 +106,9 @@ void default_send_IPI_mask_logical(const struct cpumask *cpumask, int vector)
        unsigned long mask = cpumask_bits(cpumask)[0];
        unsigned long flags;
 
+       if (WARN_ONCE(!mask, "empty IPI mask"))
+               return;
+
        local_irq_save(flags);
        WARN_ON(mask & ~cpumask_bits(cpu_online_mask)[0]);
        __default_send_IPI_dest_field(mask, vector, apic->dest_logical);
index bc3e880f9b82e76902b305d10920b70b05c440ac..fcec2f1d34a18ab37c68bbc14865a18174c21488 100644 (file)
@@ -44,6 +44,11 @@ static struct apic *apic_probe[] __initdata = {
        NULL,
 };
 
+static int apicid_phys_pkg_id(int initial_apic_id, int index_msb)
+{
+       return hard_smp_processor_id() >> index_msb;
+}
+
 /*
  * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
  */
@@ -69,6 +74,11 @@ void __init default_setup_apic_routing(void)
                printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
        }
 
+       if (is_vsmp_box()) {
+               /* need to update phys_pkg_id */
+               apic->phys_pkg_id = apicid_phys_pkg_id;
+       }
+
        /*
         * Now that apic routing model is selected, configure the
         * fault handling for intr remapping.
index 3efcb2b96a150e361f9a1f66ccbfaef692b98432..c1f253dac1552f63c0795a31ce5977b681b98592 100644 (file)
@@ -7,6 +7,10 @@ ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_common.o = -pg
 endif
 
+# Make sure load_percpu_segment has no stackprotector
+nostackp := $(call cc-option, -fno-stack-protector)
+CFLAGS_common.o                := $(nostackp)
+
 obj-y                  := intel_cacheinfo.o addon_cpuid_features.o
 obj-y                  += proc.o capflags.o powerflags.o common.o
 obj-y                  += vmware.o hypervisor.o
index 0d98a01cbdb2eff6244f4cf938f0457cd145010b..cc827ac9e8d35e71dcb702fd7748a79940642da2 100644 (file)
@@ -261,9 +261,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
  * which will be freed later
  */
 
-#ifndef CONFIG_HOTPLUG_CPU
-.section .init.text,"ax",@progbits
-#endif
+__CPUINIT
 
 #ifdef CONFIG_SMP
 ENTRY(startup_32_smp)
@@ -602,11 +600,7 @@ ignore_int:
 #endif
        iret
 
-#ifndef CONFIG_HOTPLUG_CPU
-       __CPUINITDATA
-#else
        __REFDATA
-#endif
 .align 4
 ENTRY(initial_code)
        .long i386_start_kernel
index 994dd6a4a2a004bcb5d91955fb921ac8c303eb3d..071166a4ba83b893cf3a91aeb2ee52606e9bd056 100644 (file)
@@ -519,16 +519,12 @@ static void c1e_idle(void)
                if (!cpumask_test_cpu(cpu, c1e_mask)) {
                        cpumask_set_cpu(cpu, c1e_mask);
                        /*
-                        * Force broadcast so ACPI can not interfere. Needs
-                        * to run with interrupts enabled as it uses
-                        * smp_function_call.
+                        * Force broadcast so ACPI can not interfere.
                         */
-                       local_irq_enable();
                        clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE,
                                           &cpu);
                        printk(KERN_INFO "Switch to broadcast mode on CPU%d\n",
                               cpu);
-                       local_irq_disable();
                }
                clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
 
index 78d185d797de7d3862a79adcab4a157613550ba9..9fc178255c0465e01c35c3d5439fb54866eacaf1 100644 (file)
@@ -46,11 +46,10 @@ PHDRS {
        data PT_LOAD FLAGS(7);          /* RWE */
 #ifdef CONFIG_X86_64
        user PT_LOAD FLAGS(7);          /* RWE */
-       data.init PT_LOAD FLAGS(7);     /* RWE */
 #ifdef CONFIG_SMP
        percpu PT_LOAD FLAGS(7);        /* RWE */
 #endif
-       data.init2 PT_LOAD FLAGS(7);    /* RWE */
+       init PT_LOAD FLAGS(7);          /* RWE */
 #endif
        note PT_NOTE FLAGS(0);          /* ___ */
 }
@@ -103,65 +102,43 @@ SECTIONS
                __stop___ex_table = .;
        } :text = 0x9090
 
-       RODATA
+       RO_DATA(PAGE_SIZE)
 
        /* Data */
-       . = ALIGN(PAGE_SIZE);
        .data : AT(ADDR(.data) - LOAD_OFFSET) {
                /* Start of data section */
                _sdata = .;
-               DATA_DATA
-               CONSTRUCTORS
-       } :data
+
+               /* init_task */
+               INIT_TASK_DATA(THREAD_SIZE)
 
 #ifdef CONFIG_X86_32
-       /* 32 bit has nosave before _edata */
-       . = ALIGN(PAGE_SIZE);
-       .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
-               __nosave_begin = .;
-               *(.data.nosave)
-               . = ALIGN(PAGE_SIZE);
-               __nosave_end = .;
-       }
+               /* 32 bit has nosave before _edata */
+               NOSAVE_DATA
 #endif
 
-       . = ALIGN(PAGE_SIZE);
-       .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
-               *(.data.page_aligned)
+               PAGE_ALIGNED_DATA(PAGE_SIZE)
                *(.data.idt)
-       }
 
-#ifdef CONFIG_X86_32
-       . = ALIGN(32);
-#else
-       . = ALIGN(PAGE_SIZE);
-       . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-#endif
-       .data.cacheline_aligned :
-               AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
-               *(.data.cacheline_aligned)
-       }
+               CACHELINE_ALIGNED_DATA(CONFIG_X86_L1_CACHE_BYTES)
 
-       /* rarely changed data like cpu maps */
-#ifdef CONFIG_X86_32
-       . = ALIGN(32);
-#else
-       . = ALIGN(CONFIG_X86_INTERNODE_CACHE_BYTES);
-#endif
-       .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
-               *(.data.read_mostly)
+               DATA_DATA
+               CONSTRUCTORS
+
+               /* rarely changed data like cpu maps */
+               READ_MOSTLY_DATA(CONFIG_X86_INTERNODE_CACHE_BYTES)
 
                /* End of data section */
                _edata = .;
-       }
+       } :data
 
 #ifdef CONFIG_X86_64
 
 #define VSYSCALL_ADDR (-10*1024*1024)
-#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + \
-                            SIZEOF(.data.read_mostly) + 4095) & ~(4095))
-#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + \
-                            SIZEOF(.data.read_mostly) + 4095) & ~(4095))
+#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data) + SIZEOF(.data) + \
+                            PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
+#define VSYSCALL_VIRT_ADDR ((ADDR(.data) + SIZEOF(.data) + \
+                            PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
 
 #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
 #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
@@ -227,35 +204,29 @@ SECTIONS
 
 #endif /* CONFIG_X86_64 */
 
-       /* init_task */
-       . = ALIGN(THREAD_SIZE);
-       .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
-               *(.data.init_task)
+       /* Init code and data - will be freed after init */
+       . = ALIGN(PAGE_SIZE);
+       .init.begin : AT(ADDR(.init.begin) - LOAD_OFFSET) {
+               __init_begin = .; /* paired with __init_end */
        }
-#ifdef CONFIG_X86_64
-        :data.init
-#endif
 
+#if defined(CONFIG_X86_64) && defined(CONFIG_SMP)
        /*
-        * smp_locks might be freed after init
-        * start/end must be page aligned
+        * percpu offsets are zero-based on SMP.  PERCPU_VADDR() changes the
+        * output PHDR, so the next output section - .init.text - should
+        * start another segment - init.
         */
-       . = ALIGN(PAGE_SIZE);
-       .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
-               __smp_locks = .;
-               *(.smp_locks)
-               __smp_locks_end = .;
-               . = ALIGN(PAGE_SIZE);
-       }
+       PERCPU_VADDR(0, :percpu)
+#endif
 
-       /* Init code and data - will be freed after init */
-       . = ALIGN(PAGE_SIZE);
        .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
-               __init_begin = .; /* paired with __init_end */
                _sinittext = .;
                INIT_TEXT
                _einittext = .;
        }
+#ifdef CONFIG_X86_64
+       :init
+#endif
 
        .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
                INIT_DATA
@@ -326,17 +297,7 @@ SECTIONS
        }
 #endif
 
-#if defined(CONFIG_X86_64) && defined(CONFIG_SMP)
-       /*
-        * percpu offsets are zero-based on SMP.  PERCPU_VADDR() changes the
-        * output PHDR, so the next output section - __data_nosave - should
-        * start another section data.init2.  Also, pda should be at the head of
-        * percpu area.  Preallocate it and define the percpu offset symbol
-        * so that it can be accessed as a percpu variable.
-        */
-       . = ALIGN(PAGE_SIZE);
-       PERCPU_VADDR(0, :percpu)
-#else
+#if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP)
        PERCPU(PAGE_SIZE)
 #endif
 
@@ -347,15 +308,22 @@ SECTIONS
                __init_end = .;
        }
 
+       /*
+        * smp_locks might be freed after init
+        * start/end must be page aligned
+        */
+       . = ALIGN(PAGE_SIZE);
+       .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
+               __smp_locks = .;
+               *(.smp_locks)
+               __smp_locks_end = .;
+               . = ALIGN(PAGE_SIZE);
+       }
+
 #ifdef CONFIG_X86_64
        .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
-               . = ALIGN(PAGE_SIZE);
-               __nosave_begin = .;
-               *(.data.nosave)
-               . = ALIGN(PAGE_SIZE);
-               __nosave_end = .;
-       } :data.init2
-       /* use another section data.init2, see PERCPU_VADDR() above */
+               NOSAVE_DATA
+       }
 #endif
 
        /* BSS */
index 6176fe8f29e0138ec1cb6742f65b177010846aab..ea56b8cbb6a6dd6de89ec04d9e0543ff6908395f 100644 (file)
@@ -796,7 +796,7 @@ int __init reserve_bootmem_generic(unsigned long phys, unsigned long len,
                return ret;
 
 #else
-       reserve_bootmem(phys, len, BOOTMEM_DEFAULT);
+       reserve_bootmem(phys, len, flags);
 #endif
 
        if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) {
index e6718bb280650b0a7e7500cb8d6dcda5a29c67b0..352aa9e927e26c20217725475b5c908fb91e60dd 100644 (file)
@@ -623,7 +623,8 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
                return ret;
 
        if (flags != want_flags) {
-               if (strict_prot || !is_new_memtype_allowed(want_flags, flags)) {
+               if (strict_prot ||
+                   !is_new_memtype_allowed(paddr, size, want_flags, flags)) {
                        free_memtype(paddr, paddr + size);
                        printk(KERN_ERR "%s:%d map pfn expected mapping type %s"
                                " for %Lx-%Lx, got %s\n",
index 821e97017e954a8a8e74a607950c583061412d7a..c814e144a3f0724b1d4ce56a74ca03b70cc82f25 100644 (file)
@@ -183,18 +183,17 @@ static void flush_tlb_others_ipi(const struct cpumask *cpumask,
 
        f->flush_mm = mm;
        f->flush_va = va;
-       cpumask_andnot(to_cpumask(f->flush_cpumask),
-                      cpumask, cpumask_of(smp_processor_id()));
-
-       /*
-        * We have to send the IPI only to
-        * CPUs affected.
-        */
-       apic->send_IPI_mask(to_cpumask(f->flush_cpumask),
-                     INVALIDATE_TLB_VECTOR_START + sender);
+       if (cpumask_andnot(to_cpumask(f->flush_cpumask), cpumask, cpumask_of(smp_processor_id()))) {
+               /*
+                * We have to send the IPI only to
+                * CPUs affected.
+                */
+               apic->send_IPI_mask(to_cpumask(f->flush_cpumask),
+                             INVALIDATE_TLB_VECTOR_START + sender);
 
-       while (!cpumask_empty(to_cpumask(f->flush_cpumask)))
-               cpu_relax();
+               while (!cpumask_empty(to_cpumask(f->flush_cpumask)))
+                       cpu_relax();
+       }
 
        f->flush_mm = NULL;
        f->flush_va = 0;
index 172438f86a02aaf01b3855e36318cf0bb8aaeba1..7410640db173b842db79b835dbdc2206e01c0c2a 100644 (file)
@@ -5,6 +5,10 @@ CFLAGS_REMOVE_time.o = -pg
 CFLAGS_REMOVE_irq.o = -pg
 endif
 
+# Make sure early boot has no stackprotector
+nostackp := $(call cc-option, -fno-stack-protector)
+CFLAGS_enlighten.o             := $(nostackp)
+
 obj-y          := enlighten.o setup.o multicalls.o mmu.o irq.o \
                        time.o xen-asm.o xen-asm_$(BITS).o \
                        grant-table.o suspend.o
index 0a1700a2be9c8c9a548822ca4deef1bb475b4059..eb33aaa8415de0d7b4e13d7dd18c826829a59466 100644 (file)
@@ -215,6 +215,7 @@ static __init void xen_init_cpuid_mask(void)
                          (1 << X86_FEATURE_ACPI));  /* disable ACPI */
 
        ax = 1;
+       cx = 0;
        xen_cpuid(&ax, &bx, &cx, &dx);
 
        /* cpuid claims we support xsave; try enabling it to see what happens */
@@ -974,10 +975,6 @@ asmlinkage void __init xen_start_kernel(void)
 
        xen_domain_type = XEN_PV_DOMAIN;
 
-       BUG_ON(memcmp(xen_start_info->magic, "xen-3", 5) != 0);
-
-       xen_setup_features();
-
        /* Install Xen paravirt ops */
        pv_info = xen_info;
        pv_init_ops = xen_init_ops;
@@ -986,8 +983,15 @@ asmlinkage void __init xen_start_kernel(void)
        pv_apic_ops = xen_apic_ops;
        pv_mmu_ops = xen_mmu_ops;
 
-       xen_init_irq_ops();
+#ifdef CONFIG_X86_64
+       /*
+        * Setup percpu state.  We only need to do this for 64-bit
+        * because 32-bit already has %fs set properly.
+        */
+       load_percpu_segment(0);
+#endif
 
+       xen_init_irq_ops();
        xen_init_cpuid_mask();
 
 #ifdef CONFIG_X86_LOCAL_APIC
@@ -997,6 +1001,8 @@ asmlinkage void __init xen_start_kernel(void)
        set_xen_basic_apic_ops();
 #endif
 
+       xen_setup_features();
+
        if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
                pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start;
                pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit;
@@ -1004,13 +1010,6 @@ asmlinkage void __init xen_start_kernel(void)
 
        machine_ops = xen_machine_ops;
 
-#ifdef CONFIG_X86_64
-       /*
-        * Setup percpu state.  We only need to do this for 64-bit
-        * because 32-bit already has %fs set properly.
-        */
-       load_percpu_segment(0);
-#endif
        /*
         * The only reliable way to retain the initial address of the
         * percpu gdt_page is to remember it here, so we can go and
@@ -1061,6 +1060,7 @@ asmlinkage void __init xen_start_kernel(void)
        /* set up basic CPUID stuff */
        cpu_detect(&new_cpu_data);
        new_cpu_data.hard_math = 1;
+       new_cpu_data.wp_works_ok = 1;
        new_cpu_data.x86_capability[0] = cpuid_edx(1);
 #endif
 
index 418d63619680e8df2b9ab2ba0cdd5f31bcfb4ee4..d3aa2aadb3e0e7d18645a2eb9333698f4984263a 100644 (file)
@@ -133,7 +133,7 @@ queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
                return -EINVAL;
 
        spin_lock_irq(q->queue_lock);
-       blk_queue_max_sectors(q, max_sectors_kb << 1);
+       q->limits.max_sectors = max_sectors_kb << 1;
        spin_unlock_irq(q->queue_lock);
 
        return ret;
index 56c62e2858d56a9eee11b9167fe8362a71a7c6c1..df0863d56995d7ca02c1e9492d3ab74de164ab14 100644 (file)
@@ -692,7 +692,7 @@ out:
 }
 EXPORT_SYMBOL_GPL(crypto_enqueue_request);
 
-struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
+void *__crypto_dequeue_request(struct crypto_queue *queue, unsigned int offset)
 {
        struct list_head *request;
 
@@ -707,7 +707,14 @@ struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
        request = queue->list.next;
        list_del(request);
 
-       return list_entry(request, struct crypto_async_request, list);
+       return (char *)list_entry(request, struct crypto_async_request, list) -
+              offset;
+}
+EXPORT_SYMBOL_GPL(__crypto_dequeue_request);
+
+struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
+{
+       return __crypto_dequeue_request(queue, 0);
 }
 EXPORT_SYMBOL_GPL(crypto_dequeue_request);
 
index 67340cc70142209d1aa97ae360b21587cefc321b..257706e7734f786dbe8e8d760283ef2751859838 100644 (file)
@@ -70,6 +70,12 @@ acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc,
 
        ACPI_FUNCTION_TRACE_PTR(ex_store_buffer_to_buffer, source_desc);
 
+       /* If Source and Target are the same, just return */
+
+       if (source_desc == target_desc) {
+               return_ACPI_STATUS(AE_OK);
+       }
+
        /* We know that source_desc is a buffer by now */
 
        buffer = ACPI_CAST_PTR(u8, source_desc->buffer.pointer);
@@ -161,6 +167,12 @@ acpi_ex_store_string_to_string(union acpi_operand_object *source_desc,
 
        ACPI_FUNCTION_TRACE_PTR(ex_store_string_to_string, source_desc);
 
+       /* If Source and Target are the same, just return */
+
+       if (source_desc == target_desc) {
+               return_ACPI_STATUS(AE_OK);
+       }
+
        /* We know that source_desc is a string by now */
 
        buffer = ACPI_CAST_PTR(u8, source_desc->string.pointer);
index 84e0f3c0744270b4c8474f92239b64255a27985b..2cc4b3033872979bd7a1fbeeae055ca077aba227 100644 (file)
@@ -1151,6 +1151,9 @@ static int __init acpi_processor_init(void)
 {
        int result = 0;
 
+       if (acpi_disabled)
+               return 0;
+
        memset(&errata, 0, sizeof(errata));
 
 #ifdef CONFIG_SMP
@@ -1197,6 +1200,9 @@ out_proc:
 
 static void __exit acpi_processor_exit(void)
 {
+       if (acpi_disabled)
+               return;
+
        acpi_processor_ppc_exit();
 
        acpi_thermal_cpufreq_exit();
index 0efa59e7e3afd16095fa538f333f11f37ca7a9d4..66393d5c4c7c9ccff78ea22f4635f6e1a14694f7 100644 (file)
@@ -162,8 +162,9 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr,
                pr->power.timer_broadcast_on_state = state;
 }
 
-static void lapic_timer_propagate_broadcast(struct acpi_processor *pr)
+static void lapic_timer_propagate_broadcast(void *arg)
 {
+       struct acpi_processor *pr = (struct acpi_processor *) arg;
        unsigned long reason;
 
        reason = pr->power.timer_broadcast_on_state < INT_MAX ?
@@ -635,7 +636,8 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
                working++;
        }
 
-       lapic_timer_propagate_broadcast(pr);
+       smp_call_function_single(pr->id, lapic_timer_propagate_broadcast,
+                                pr, 1);
 
        return (working);
 }
index 39838c66603265bd188f398b07fdd494a0699589..31adda1099e0d451f68ef399b8f8c0f5832f21c5 100644 (file)
@@ -66,7 +66,7 @@ static int acpi_processor_apply_limit(struct acpi_processor *pr)
                if (pr->limit.thermal.tx > tx)
                        tx = pr->limit.thermal.tx;
 
-               result = acpi_processor_set_throttling(pr, tx);
+               result = acpi_processor_set_throttling(pr, tx, false);
                if (result)
                        goto end;
        }
@@ -421,12 +421,12 @@ processor_set_cur_state(struct thermal_cooling_device *cdev,
 
        if (state <= max_pstate) {
                if (pr->flags.throttling && pr->throttling.state)
-                       result = acpi_processor_set_throttling(pr, 0);
+                       result = acpi_processor_set_throttling(pr, 0, false);
                cpufreq_set_cur_state(pr->id, state);
        } else {
                cpufreq_set_cur_state(pr->id, max_pstate);
                result = acpi_processor_set_throttling(pr,
-                               state - max_pstate);
+                               state - max_pstate, false);
        }
        return result;
 }
index 227543789ba91db984862f52040fc18d1a7758e9..ae39797aab55cc860debf1a749a1cf858edd9b64 100644 (file)
@@ -62,7 +62,8 @@ struct throttling_tstate {
 #define THROTTLING_POSTCHANGE      (2)
 
 static int acpi_processor_get_throttling(struct acpi_processor *pr);
-int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
+int acpi_processor_set_throttling(struct acpi_processor *pr,
+                                               int state, bool force);
 
 static int acpi_processor_update_tsd_coord(void)
 {
@@ -361,7 +362,7 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
                 */
                target_state = throttling_limit;
        }
-       return acpi_processor_set_throttling(pr, target_state);
+       return acpi_processor_set_throttling(pr, target_state, false);
 }
 
 /*
@@ -839,10 +840,10 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr)
        if (ret >= 0) {
                state = acpi_get_throttling_state(pr, value);
                if (state == -1) {
-                       ACPI_WARNING((AE_INFO,
-                               "Invalid throttling state, reset"));
+                       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                               "Invalid throttling state, reset\n"));
                        state = 0;
-                       ret = acpi_processor_set_throttling(pr, state);
+                       ret = acpi_processor_set_throttling(pr, state, true);
                        if (ret)
                                return ret;
                }
@@ -915,7 +916,7 @@ static int acpi_processor_get_fadt_info(struct acpi_processor *pr)
 }
 
 static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
-                                             int state)
+                                             int state, bool force)
 {
        u32 value = 0;
        u32 duty_mask = 0;
@@ -930,7 +931,7 @@ static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
        if (!pr->flags.throttling)
                return -ENODEV;
 
-       if (state == pr->throttling.state)
+       if (!force && (state == pr->throttling.state))
                return 0;
 
        if (state < pr->throttling_platform_limit)
@@ -988,7 +989,7 @@ static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
 }
 
 static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
-                                            int state)
+                                            int state, bool force)
 {
        int ret;
        acpi_integer value;
@@ -1002,7 +1003,7 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
        if (!pr->flags.throttling)
                return -ENODEV;
 
-       if (state == pr->throttling.state)
+       if (!force && (state == pr->throttling.state))
                return 0;
 
        if (state < pr->throttling_platform_limit)
@@ -1018,7 +1019,8 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
        return 0;
 }
 
-int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
+int acpi_processor_set_throttling(struct acpi_processor *pr,
+                                               int state, bool force)
 {
        cpumask_var_t saved_mask;
        int ret = 0;
@@ -1070,7 +1072,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
                /* FIXME: use work_on_cpu() */
                set_cpus_allowed_ptr(current, cpumask_of(pr->id));
                ret = p_throttling->acpi_processor_set_throttling(pr,
-                                               t_state.target_state);
+                                               t_state.target_state, force);
        } else {
                /*
                 * When the T-state coordination is SW_ALL or HW_ALL,
@@ -1103,7 +1105,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
                        set_cpus_allowed_ptr(current, cpumask_of(i));
                        ret = match_pr->throttling.
                                acpi_processor_set_throttling(
-                               match_pr, t_state.target_state);
+                               match_pr, t_state.target_state, force);
                }
        }
        /*
@@ -1201,7 +1203,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
                ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                                  "Disabling throttling (was T%d)\n",
                                  pr->throttling.state));
-               result = acpi_processor_set_throttling(pr, 0);
+               result = acpi_processor_set_throttling(pr, 0, false);
                if (result)
                        goto end;
        }
@@ -1307,7 +1309,7 @@ static ssize_t acpi_processor_write_throttling(struct file *file,
        if (strcmp(tmpbuf, charp) != 0)
                return -EINVAL;
 
-       result = acpi_processor_set_throttling(pr, state_val);
+       result = acpi_processor_set_throttling(pr, state_val, false);
        if (result)
                return result;
 
index 8851315ce858a2e2eb1e4ffd2d2b6b695fa8bfb8..60ea984c84a02c651b606d6d42aa4b3610c21882 100644 (file)
@@ -2004,8 +2004,11 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
        status = acpi_remove_notify_handler(device->dev->handle,
                                            ACPI_DEVICE_NOTIFY,
                                            acpi_video_device_notify);
-       sysfs_remove_link(&device->backlight->dev.kobj, "device");
-       backlight_device_unregister(device->backlight);
+       if (device->backlight) {
+               sysfs_remove_link(&device->backlight->dev.kobj, "device");
+               backlight_device_unregister(device->backlight);
+               device->backlight = NULL;
+       }
        if (device->cdev) {
                sysfs_remove_link(&device->dev->dev.kobj,
                                  "thermal_cooling");
index 56b8a3ff12865041af813ca0bcfa49db143e5169..9ac4e378992ef60d71634121379b91479c8660f2 100644 (file)
@@ -664,6 +664,8 @@ static int piix_pata_prereset(struct ata_link *link, unsigned long deadline)
        return ata_sff_prereset(link, deadline);
 }
 
+static DEFINE_SPINLOCK(piix_lock);
+
 /**
  *     piix_set_piomode - Initialize host controller PATA PIO timings
  *     @ap: Port whose timings we are configuring
@@ -677,8 +679,9 @@ static int piix_pata_prereset(struct ata_link *link, unsigned long deadline)
 
 static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
 {
-       unsigned int pio        = adev->pio_mode - XFER_PIO_0;
        struct pci_dev *dev     = to_pci_dev(ap->host->dev);
+       unsigned long flags;
+       unsigned int pio        = adev->pio_mode - XFER_PIO_0;
        unsigned int is_slave   = (adev->devno != 0);
        unsigned int master_port= ap->port_no ? 0x42 : 0x40;
        unsigned int slave_port = 0x44;
@@ -708,6 +711,8 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
        if (adev->class == ATA_DEV_ATA)
                control |= 4;   /* PPE enable */
 
+       spin_lock_irqsave(&piix_lock, flags);
+
        /* PIO configuration clears DTE unconditionally.  It will be
         * programmed in set_dmamode which is guaranteed to be called
         * after set_piomode if any DMA mode is available.
@@ -747,6 +752,8 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
                udma_enable &= ~(1 << (2 * ap->port_no + adev->devno));
                pci_write_config_byte(dev, 0x48, udma_enable);
        }
+
+       spin_unlock_irqrestore(&piix_lock, flags);
 }
 
 /**
@@ -764,6 +771,7 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
 static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, int isich)
 {
        struct pci_dev *dev     = to_pci_dev(ap->host->dev);
+       unsigned long flags;
        u8 master_port          = ap->port_no ? 0x42 : 0x40;
        u16 master_data;
        u8 speed                = adev->dma_mode;
@@ -777,6 +785,8 @@ static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, in
                            { 2, 1 },
                            { 2, 3 }, };
 
+       spin_lock_irqsave(&piix_lock, flags);
+
        pci_read_config_word(dev, master_port, &master_data);
        if (ap->udma_mask)
                pci_read_config_byte(dev, 0x48, &udma_enable);
@@ -867,6 +877,8 @@ static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, in
        /* Don't scribble on 0x48 if the controller does not support UDMA */
        if (ap->udma_mask)
                pci_write_config_byte(dev, 0x48, udma_enable);
+
+       spin_unlock_irqrestore(&piix_lock, flags);
 }
 
 /**
index 5e41e6dd657b9a7326ba1347346c8147c428f3c2..db195abad69889e4d499bde162ff5e818601f3b2 100644 (file)
@@ -155,7 +155,7 @@ struct aoedev {
        u16 fw_ver;             /* version of blade's firmware */
        struct work_struct work;/* disk create work struct */
        struct gendisk *gd;
-       struct request_queue blkq;
+       struct request_queue *blkq;
        struct hd_geometry geo; 
        sector_t ssize;
        struct timer_list timer;
index 2307a271bdc99e91b5c410083383a0595c4c08d0..1e15889c4b9819f837076c1b17df34fc8ef881c2 100644 (file)
@@ -264,9 +264,12 @@ aoeblk_gdalloc(void *vp)
                goto err_disk;
        }
 
-       blk_queue_make_request(&d->blkq, aoeblk_make_request);
-       if (bdi_init(&d->blkq.backing_dev_info))
+       d->blkq = blk_alloc_queue(GFP_KERNEL);
+       if (!d->blkq)
                goto err_mempool;
+       blk_queue_make_request(d->blkq, aoeblk_make_request);
+       if (bdi_init(&d->blkq->backing_dev_info))
+               goto err_blkq;
        spin_lock_irqsave(&d->lock, flags);
        gd->major = AOE_MAJOR;
        gd->first_minor = d->sysminor * AOE_PARTITIONS;
@@ -276,7 +279,7 @@ aoeblk_gdalloc(void *vp)
        snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d",
                d->aoemajor, d->aoeminor);
 
-       gd->queue = &d->blkq;
+       gd->queue = d->blkq;
        d->gd = gd;
        d->flags &= ~DEVFL_GDALLOC;
        d->flags |= DEVFL_UP;
@@ -287,6 +290,9 @@ aoeblk_gdalloc(void *vp)
        aoedisk_add_sysfs(d);
        return;
 
+err_blkq:
+       blk_cleanup_queue(d->blkq);
+       d->blkq = NULL;
 err_mempool:
        mempool_destroy(d->bufpool);
 err_disk:
index eeea477d96016596ccd729a6f75d37d5e3d30a0e..fa67027789aab80ca8c11deccad4e2d3ec225697 100644 (file)
@@ -113,6 +113,7 @@ aoedev_freedev(struct aoedev *d)
        if (d->bufpool)
                mempool_destroy(d->bufpool);
        skbpoolfree(d);
+       blk_cleanup_queue(d->blkq);
        kfree(d);
 }
 
index 8c9d50db5c3a7913fba96958a4a1a433cde90330..c58557790585dfe6a0d56dba70fabb3764a3e2c6 100644 (file)
@@ -49,6 +49,7 @@
 #define PCI_DEVICE_ID_INTEL_IGDNG_D_HB     0x0040
 #define PCI_DEVICE_ID_INTEL_IGDNG_D_IG     0x0042
 #define PCI_DEVICE_ID_INTEL_IGDNG_M_HB     0x0044
+#define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB            0x0062
 #define PCI_DEVICE_ID_INTEL_IGDNG_M_IG     0x0046
 
 /* cover 915 and 945 variants */
@@ -81,7 +82,8 @@
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \
-               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB)
+               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \
+               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB)
 
 extern int agp_memory_reserved;
 
@@ -1216,6 +1218,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
        case PCI_DEVICE_ID_INTEL_G41_HB:
        case PCI_DEVICE_ID_INTEL_IGDNG_D_HB:
        case PCI_DEVICE_ID_INTEL_IGDNG_M_HB:
+       case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB:
                *gtt_offset = *gtt_size = MB(2);
                break;
        default:
@@ -2195,6 +2198,8 @@ static const struct intel_driver_description {
            "IGDNG/D", NULL, &intel_i965_driver },
        { PCI_DEVICE_ID_INTEL_IGDNG_M_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
            "IGDNG/M", NULL, &intel_i965_driver },
+       { PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
+           "IGDNG/MA", NULL, &intel_i965_driver },
        { 0, 0, 0, NULL, NULL, NULL }
 };
 
@@ -2398,6 +2403,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
        ID(PCI_DEVICE_ID_INTEL_G41_HB),
        ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB),
        ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB),
+       ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB),
        { }
 };
 
index 973be2f441951ed0e68d658c1192c94524f33aff..4e28b35024ece708161ec948f37b926fc8455c1b 100644 (file)
@@ -300,8 +300,7 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space)
                        if (space < 2)
                                return -1;
                        tty->canon_column = tty->column = 0;
-                       tty_put_char(tty, '\r');
-                       tty_put_char(tty, c);
+                       tty->ops->write(tty, "\r\n", 2);
                        return 2;
                }
                tty->canon_column = tty->column;
index d083c73d784a76a34500c26cc582f3d68770be72..b33d6688e9109a31bb27a6b297a73a8e69c5989d 100644 (file)
@@ -109,21 +109,13 @@ static int pty_space(struct tty_struct *to)
  *     the other side of the pty/tty pair.
  */
 
-static int pty_write(struct tty_struct *tty, const unsigned char *buf,
-                                                               int count)
+static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
 {
        struct tty_struct *to = tty->link;
-       int c;
 
        if (tty->stopped)
                return 0;
 
-       /* This isn't locked but our 8K is quite sloppy so no
-          big deal */
-
-       c = pty_space(to);
-       if (c > count)
-               c = count;
        if (c > 0) {
                /* Stuff the data into the input queue of the other end */
                c = tty_insert_flip_string(to, buf, c);
index 1733d3439ad2fd31e2cac8d083c5de499c4a685d..e48af9f79219a0dec76315724eeeaaae3a4102d6 100644 (file)
@@ -508,8 +508,9 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
  *     be obtained while the delayed work queue halt ensures that no more
  *     data is fed to the ldisc.
  *
- *     In order to wait for any existing references to complete see
- *     tty_ldisc_wait_idle.
+ *     You need to do a 'flush_scheduled_work()' (outside the ldisc_mutex)
+ *     in order to make sure any currently executing ldisc work is also
+ *     flushed.
  */
 
 static int tty_ldisc_halt(struct tty_struct *tty)
@@ -753,11 +754,14 @@ void tty_ldisc_hangup(struct tty_struct *tty)
         * N_TTY.
         */
        if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
+               /* Make sure the old ldisc is quiescent */
+               tty_ldisc_halt(tty);
+               flush_scheduled_work();
+
                /* Avoid racing set_ldisc or tty_ldisc_release */
                mutex_lock(&tty->ldisc_mutex);
                if (tty->ldisc) {       /* Not yet closed */
                        /* Switch back to N_TTY */
-                       tty_ldisc_halt(tty);
                        tty_ldisc_reinit(tty);
                        /* At this point we have a closed ldisc and we want to
                           reopen it. We could defer this to the next open but
index fd69086d08d54f0fb9c2036984cc9c9c88d86446..2968ed6a9c4997003591a9ebc33546e19d6deb0b 100644 (file)
@@ -1250,20 +1250,11 @@ static int cpufreq_suspend(struct sys_device *sysdev, pm_message_t pmsg)
 {
        int ret = 0;
 
-#ifdef __powerpc__
        int cpu = sysdev->id;
-       unsigned int cur_freq = 0;
        struct cpufreq_policy *cpu_policy;
 
        dprintk("suspending cpu %u\n", cpu);
 
-       /*
-        * This whole bogosity is here because Powerbooks are made of fail.
-        * No sane platform should need any of the code below to be run.
-        * (it's entirely the wrong thing to do, as driver->get may
-        *  reenable interrupts on some architectures).
-        */
-
        if (!cpu_online(cpu))
                return 0;
 
@@ -1282,47 +1273,13 @@ static int cpufreq_suspend(struct sys_device *sysdev, pm_message_t pmsg)
 
        if (cpufreq_driver->suspend) {
                ret = cpufreq_driver->suspend(cpu_policy, pmsg);
-               if (ret) {
+               if (ret)
                        printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
                                        "step on CPU %u\n", cpu_policy->cpu);
-                       goto out;
-               }
-       }
-
-       if (cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)
-               goto out;
-
-       if (cpufreq_driver->get)
-               cur_freq = cpufreq_driver->get(cpu_policy->cpu);
-
-       if (!cur_freq || !cpu_policy->cur) {
-               printk(KERN_ERR "cpufreq: suspend failed to assert current "
-                      "frequency is what timing core thinks it is.\n");
-               goto out;
-       }
-
-       if (unlikely(cur_freq != cpu_policy->cur)) {
-               struct cpufreq_freqs freqs;
-
-               if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN))
-                       dprintk("Warning: CPU frequency is %u, "
-                              "cpufreq assumed %u kHz.\n",
-                              cur_freq, cpu_policy->cur);
-
-               freqs.cpu = cpu;
-               freqs.old = cpu_policy->cur;
-               freqs.new = cur_freq;
-
-               srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
-                                   CPUFREQ_SUSPENDCHANGE, &freqs);
-               adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs);
-
-               cpu_policy->cur = cur_freq;
        }
 
 out:
        cpufreq_cpu_put(cpu_policy);
-#endif /* __powerpc__ */
        return ret;
 }
 
@@ -1330,24 +1287,21 @@ out:
  *     cpufreq_resume -  restore proper CPU frequency handling after resume
  *
  *     1.) resume CPUfreq hardware support (cpufreq_driver->resume())
- *     2.) if ->target and !CPUFREQ_CONST_LOOPS: verify we're in sync
- *     3.) schedule call cpufreq_update_policy() ASAP as interrupts are
- *         restored.
+ *     2.) schedule call cpufreq_update_policy() ASAP as interrupts are
+ *         restored. It will verify that the current freq is in sync with
+ *         what we believe it to be. This is a bit later than when it
+ *         should be, but nonethteless it's better than calling
+ *         cpufreq_driver->get() here which might re-enable interrupts...
  */
 static int cpufreq_resume(struct sys_device *sysdev)
 {
        int ret = 0;
 
-#ifdef __powerpc__
        int cpu = sysdev->id;
        struct cpufreq_policy *cpu_policy;
 
        dprintk("resuming cpu %u\n", cpu);
 
-       /* As with the ->suspend method, all the code below is
-        * only necessary because Powerbooks suck.
-        * See commit 42d4dc3f4e1e for jokes. */
-
        if (!cpu_online(cpu))
                return 0;
 
@@ -1373,45 +1327,10 @@ static int cpufreq_resume(struct sys_device *sysdev)
                }
        }
 
-       if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
-               unsigned int cur_freq = 0;
-
-               if (cpufreq_driver->get)
-                       cur_freq = cpufreq_driver->get(cpu_policy->cpu);
-
-               if (!cur_freq || !cpu_policy->cur) {
-                       printk(KERN_ERR "cpufreq: resume failed to assert "
-                                       "current frequency is what timing core "
-                                       "thinks it is.\n");
-                       goto out;
-               }
-
-               if (unlikely(cur_freq != cpu_policy->cur)) {
-                       struct cpufreq_freqs freqs;
-
-                       if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN))
-                               dprintk("Warning: CPU frequency "
-                                      "is %u, cpufreq assumed %u kHz.\n",
-                                      cur_freq, cpu_policy->cur);
-
-                       freqs.cpu = cpu;
-                       freqs.old = cpu_policy->cur;
-                       freqs.new = cur_freq;
-
-                       srcu_notifier_call_chain(
-                                       &cpufreq_transition_notifier_list,
-                                       CPUFREQ_RESUMECHANGE, &freqs);
-                       adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs);
-
-                       cpu_policy->cur = cur_freq;
-               }
-       }
-
-out:
        schedule_work(&cpu_policy->update);
+
 fail:
        cpufreq_cpu_put(cpu_policy);
-#endif /* __powerpc__ */
        return ret;
 }
 
index 110e731f5574130cb69338a99aab0c8ec8a16916..1c0b504a42f3068e852fa1b7423ee5c37bfb0abd 100644 (file)
@@ -196,7 +196,7 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
                switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
                                irm_id, generation, SCODE_100,
                                CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE,
-                               data, sizeof(data))) {
+                               data, 8)) {
                case RCODE_GENERATION:
                        /* A generation change frees all bandwidth. */
                        return allocate ? -EAGAIN : bandwidth;
@@ -233,7 +233,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
                data[1] = old ^ c;
                switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
                                           irm_id, generation, SCODE_100,
-                                          offset, data, sizeof(data))) {
+                                          offset, data, 8)) {
                case RCODE_GENERATION:
                        /* A generation change frees all channels. */
                        return allocate ? -EAGAIN : i;
index ecddd11b797a366d105763656dd4eda2c2273add..76b321bb73f9419aa52c826a944047388d53cd0a 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
+#include <linux/pci_ids.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 
@@ -2372,6 +2373,9 @@ static void ohci_pmac_off(struct pci_dev *dev)
 #define ohci_pmac_off(dev)
 #endif /* CONFIG_PPC_PMAC */
 
+#define PCI_VENDOR_ID_AGERE            PCI_VENDOR_ID_ATT
+#define PCI_DEVICE_ID_AGERE_FW643      0x5901
+
 static int __devinit pci_probe(struct pci_dev *dev,
                               const struct pci_device_id *ent)
 {
@@ -2422,6 +2426,16 @@ static int __devinit pci_probe(struct pci_dev *dev,
        version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
        ohci->use_dualbuffer = version >= OHCI_VERSION_1_1;
 
+       /* dual-buffer mode is broken if more than one IR context is active */
+       if (dev->vendor == PCI_VENDOR_ID_AGERE &&
+           dev->device == PCI_DEVICE_ID_AGERE_FW643)
+               ohci->use_dualbuffer = false;
+
+       /* dual-buffer mode is broken */
+       if (dev->vendor == PCI_VENDOR_ID_RICOH &&
+           dev->device == PCI_DEVICE_ID_RICOH_R5C832)
+               ohci->use_dualbuffer = false;
+
 /* x86-32 currently doesn't use highmem for dma_alloc_coherent */
 #if !defined(CONFIG_X86_32)
        /* dual-buffer mode is broken with descriptor addresses above 2G */
index 8d51568ee14344ee1e9e4ac11f690ae7a2c1d6a2..e5df822a8130ca99730a009c75cf3ea454bfccab 100644 (file)
@@ -456,12 +456,12 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request,
        }
        spin_unlock_irqrestore(&card->lock, flags);
 
-       if (&orb->link != &lu->orb_list)
+       if (&orb->link != &lu->orb_list) {
                orb->callback(orb, &status);
-       else
+               kref_put(&orb->kref, free_orb);
+       } else {
                fw_error("status write for unknown orb\n");
-
-       kref_put(&orb->kref, free_orb);
+       }
 
        fw_send_response(card, request, RCODE_COMPLETE);
 }
index 85ec31b3ff00a09f1d18b0a9b66cd31b68d8ba21..f7a615b80c706a3094bb94f5f9981f1a0e5016ae 100644 (file)
 #define to_drm_minor(d) container_of(d, struct drm_minor, kdev)
 #define to_drm_connector(d) container_of(d, struct drm_connector, kdev)
 
+static struct device_type drm_sysfs_device_minor = {
+       .name = "drm_minor"
+};
+
 /**
- * drm_sysfs_suspend - DRM class suspend hook
+ * drm_class_suspend - DRM class suspend hook
  * @dev: Linux device to suspend
  * @state: power state to enter
  *
  * Just figures out what the actual struct drm_device associated with
  * @dev is and calls its suspend hook, if present.
  */
-static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
+static int drm_class_suspend(struct device *dev, pm_message_t state)
 {
-       struct drm_minor *drm_minor = to_drm_minor(dev);
-       struct drm_device *drm_dev = drm_minor->dev;
-
-       if (drm_minor->type == DRM_MINOR_LEGACY &&
-           !drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
-           drm_dev->driver->suspend)
-               return drm_dev->driver->suspend(drm_dev, state);
-
+       if (dev->type == &drm_sysfs_device_minor) {
+               struct drm_minor *drm_minor = to_drm_minor(dev);
+               struct drm_device *drm_dev = drm_minor->dev;
+
+               if (drm_minor->type == DRM_MINOR_LEGACY &&
+                   !drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
+                   drm_dev->driver->suspend)
+                       return drm_dev->driver->suspend(drm_dev, state);
+       }
        return 0;
 }
 
 /**
- * drm_sysfs_resume - DRM class resume hook
+ * drm_class_resume - DRM class resume hook
  * @dev: Linux device to resume
  *
  * Just figures out what the actual struct drm_device associated with
  * @dev is and calls its resume hook, if present.
  */
-static int drm_sysfs_resume(struct device *dev)
+static int drm_class_resume(struct device *dev)
 {
-       struct drm_minor *drm_minor = to_drm_minor(dev);
-       struct drm_device *drm_dev = drm_minor->dev;
-
-       if (drm_minor->type == DRM_MINOR_LEGACY &&
-           !drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
-           drm_dev->driver->resume)
-               return drm_dev->driver->resume(drm_dev);
-
+       if (dev->type == &drm_sysfs_device_minor) {
+               struct drm_minor *drm_minor = to_drm_minor(dev);
+               struct drm_device *drm_dev = drm_minor->dev;
+
+               if (drm_minor->type == DRM_MINOR_LEGACY &&
+                   !drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
+                   drm_dev->driver->resume)
+                       return drm_dev->driver->resume(drm_dev);
+       }
        return 0;
 }
 
@@ -99,8 +105,8 @@ struct class *drm_sysfs_create(struct module *owner, char *name)
                goto err_out;
        }
 
-       class->suspend = drm_sysfs_suspend;
-       class->resume = drm_sysfs_resume;
+       class->suspend = drm_class_suspend;
+       class->resume = drm_class_resume;
 
        err = class_create_file(class, &class_attr_version);
        if (err)
@@ -480,6 +486,7 @@ int drm_sysfs_device_add(struct drm_minor *minor)
        minor->kdev.class = drm_class;
        minor->kdev.release = drm_sysfs_device_release;
        minor->kdev.devt = minor->device;
+       minor->kdev.type = &drm_sysfs_device_minor;
        if (minor->type == DRM_MINOR_CONTROL)
                minor_str = "controlD%d";
         else if (minor->type == DRM_MINOR_RENDER)
index 7537f57d8a87399b43079c37adbb843970bd7b1d..5b4f87e556218e0574fb3a57f3e084fbaaa7a251 100644 (file)
@@ -222,6 +222,7 @@ typedef struct drm_i915_private {
        unsigned int edp_support:1;
        int lvds_ssc_freq;
 
+       int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */
        struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
        int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
        int num_fence_regs; /* 8 on pre-965, 16 otherwise */
@@ -384,6 +385,9 @@ typedef struct drm_i915_private {
                 */
                struct list_head inactive_list;
 
+               /** LRU list of objects with fence regs on them. */
+               struct list_head fence_list;
+
                /**
                 * List of breadcrumbs associated with GPU requests currently
                 * outstanding.
@@ -451,6 +455,9 @@ struct drm_i915_gem_object {
        /** This object's place on the active/flushing/inactive lists */
        struct list_head list;
 
+       /** This object's place on the fenced object LRU */
+       struct list_head fence_list;
+
        /**
         * This is set if the object is on the active or flushing lists
         * (has pending rendering), and is not set if it's on inactive (ready
index 140bee142fc253186f80f2cdc8a4d339786efe20..80e5ba490dc28c8a15c4619865f4872f82a6625e 100644 (file)
@@ -978,6 +978,7 @@ int
 i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
                          struct drm_file *file_priv)
 {
+       struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_i915_gem_set_domain *args = data;
        struct drm_gem_object *obj;
        uint32_t read_domains = args->read_domains;
@@ -1010,8 +1011,18 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
                 obj, obj->size, read_domains, write_domain);
 #endif
        if (read_domains & I915_GEM_DOMAIN_GTT) {
+               struct drm_i915_gem_object *obj_priv = obj->driver_private;
+
                ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0);
 
+               /* Update the LRU on the fence for the CPU access that's
+                * about to occur.
+                */
+               if (obj_priv->fence_reg != I915_FENCE_REG_NONE) {
+                       list_move_tail(&obj_priv->fence_list,
+                                      &dev_priv->mm.fence_list);
+               }
+
                /* Silently promote "you're not bound, there was nothing to do"
                 * to success, since the client was just asking us to
                 * make sure everything was done.
@@ -1155,8 +1166,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        }
 
        /* Need a new fence register? */
-       if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
-           obj_priv->tiling_mode != I915_TILING_NONE) {
+       if (obj_priv->tiling_mode != I915_TILING_NONE) {
                ret = i915_gem_object_get_fence_reg(obj);
                if (ret) {
                        mutex_unlock(&dev->struct_mutex);
@@ -2208,6 +2218,12 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
        struct drm_i915_gem_object *old_obj_priv = NULL;
        int i, ret, avail;
 
+       /* Just update our place in the LRU if our fence is getting used. */
+       if (obj_priv->fence_reg != I915_FENCE_REG_NONE) {
+               list_move_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list);
+               return 0;
+       }
+
        switch (obj_priv->tiling_mode) {
        case I915_TILING_NONE:
                WARN(1, "allocating a fence for non-tiled object?\n");
@@ -2229,7 +2245,6 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
        }
 
        /* First try to find a free reg */
-try_again:
        avail = 0;
        for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) {
                reg = &dev_priv->fence_regs[i];
@@ -2243,63 +2258,62 @@ try_again:
 
        /* None available, try to steal one or wait for a user to finish */
        if (i == dev_priv->num_fence_regs) {
-               uint32_t seqno = dev_priv->mm.next_gem_seqno;
+               struct drm_gem_object *old_obj = NULL;
 
                if (avail == 0)
                        return -ENOSPC;
 
-               for (i = dev_priv->fence_reg_start;
-                    i < dev_priv->num_fence_regs; i++) {
-                       uint32_t this_seqno;
-
-                       reg = &dev_priv->fence_regs[i];
-                       old_obj_priv = reg->obj->driver_private;
+               list_for_each_entry(old_obj_priv, &dev_priv->mm.fence_list,
+                                   fence_list) {
+                       old_obj = old_obj_priv->obj;
 
                        if (old_obj_priv->pin_count)
                                continue;
 
+                       /* Take a reference, as otherwise the wait_rendering
+                        * below may cause the object to get freed out from
+                        * under us.
+                        */
+                       drm_gem_object_reference(old_obj);
+
                        /* i915 uses fences for GPU access to tiled buffers */
                        if (IS_I965G(dev) || !old_obj_priv->active)
                                break;
 
-                       /* find the seqno of the first available fence */
-                       this_seqno = old_obj_priv->last_rendering_seqno;
-                       if (this_seqno != 0 &&
-                           reg->obj->write_domain == 0 &&
-                           i915_seqno_passed(seqno, this_seqno))
-                               seqno = this_seqno;
-               }
-
-               /*
-                * Now things get ugly... we have to wait for one of the
-                * objects to finish before trying again.
-                */
-               if (i == dev_priv->num_fence_regs) {
-                       if (seqno == dev_priv->mm.next_gem_seqno) {
-                               i915_gem_flush(dev,
-                                              I915_GEM_GPU_DOMAINS,
-                                              I915_GEM_GPU_DOMAINS);
-                               seqno = i915_add_request(dev, NULL,
-                                                        I915_GEM_GPU_DOMAINS);
-                               if (seqno == 0)
-                                       return -ENOMEM;
+                       /* This brings the object to the head of the LRU if it
+                        * had been written to.  The only way this should
+                        * result in us waiting longer than the expected
+                        * optimal amount of time is if there was a
+                        * fence-using buffer later that was read-only.
+                        */
+                       i915_gem_object_flush_gpu_write_domain(old_obj);
+                       ret = i915_gem_object_wait_rendering(old_obj);
+                       if (ret != 0) {
+                               drm_gem_object_unreference(old_obj);
+                               return ret;
                        }
 
-                       ret = i915_wait_request(dev, seqno);
-                       if (ret)
-                               return ret;
-                       goto try_again;
+                       break;
                }
 
                /*
                 * Zap this virtual mapping so we can set up a fence again
                 * for this object next time we need it.
                 */
-               i915_gem_release_mmap(reg->obj);
+               i915_gem_release_mmap(old_obj);
+
+               i = old_obj_priv->fence_reg;
+               reg = &dev_priv->fence_regs[i];
+
                old_obj_priv->fence_reg = I915_FENCE_REG_NONE;
+               list_del_init(&old_obj_priv->fence_list);
+
+               drm_gem_object_unreference(old_obj);
        }
 
        obj_priv->fence_reg = i;
+       list_add_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list);
+
        reg->obj = obj;
 
        if (IS_I965G(dev))
@@ -2342,6 +2356,7 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj)
 
        dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL;
        obj_priv->fence_reg = I915_FENCE_REG_NONE;
+       list_del_init(&obj_priv->fence_list);
 }
 
 /**
@@ -3595,9 +3610,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
         * Pre-965 chips need a fence register set up in order to
         * properly handle tiled surfaces.
         */
-       if (!IS_I965G(dev) &&
-           obj_priv->fence_reg == I915_FENCE_REG_NONE &&
-           obj_priv->tiling_mode != I915_TILING_NONE) {
+       if (!IS_I965G(dev) && obj_priv->tiling_mode != I915_TILING_NONE) {
                ret = i915_gem_object_get_fence_reg(obj);
                if (ret != 0) {
                        if (ret != -EBUSY && ret != -ERESTARTSYS)
@@ -3806,6 +3819,7 @@ int i915_gem_init_object(struct drm_gem_object *obj)
        obj_priv->obj = obj;
        obj_priv->fence_reg = I915_FENCE_REG_NONE;
        INIT_LIST_HEAD(&obj_priv->list);
+       INIT_LIST_HEAD(&obj_priv->fence_list);
 
        return 0;
 }
@@ -4218,15 +4232,11 @@ int
 i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
                       struct drm_file *file_priv)
 {
-       int ret;
-
        if (drm_core_check_feature(dev, DRIVER_MODESET))
                return 0;
 
-       ret = i915_gem_idle(dev);
        drm_irq_uninstall(dev);
-
-       return ret;
+       return i915_gem_idle(dev);
 }
 
 void
@@ -4253,6 +4263,7 @@ i915_gem_load(struct drm_device *dev)
        INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
        INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
        INIT_LIST_HEAD(&dev_priv->mm.request_list);
+       INIT_LIST_HEAD(&dev_priv->mm.fence_list);
        INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
                          i915_gem_retire_work_handler);
        dev_priv->mm.next_gem_seqno = 1;
index 300aee3296c2435545702030d6e66405759e5963..f806fcc54e09d3ad5a6e262b92530d6900a8afb6 100644 (file)
@@ -59,6 +59,16 @@ find_section(struct bdb_header *bdb, int section_id)
        return NULL;
 }
 
+static u16
+get_blocksize(void *p)
+{
+       u16 *block_ptr, block_size;
+
+       block_ptr = (u16 *)((char *)p - 2);
+       block_size = *block_ptr;
+       return block_size;
+}
+
 static void
 fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
                        struct lvds_dvo_timing *dvo_timing)
@@ -214,6 +224,41 @@ parse_general_features(struct drm_i915_private *dev_priv,
        }
 }
 
+static void
+parse_general_definitions(struct drm_i915_private *dev_priv,
+                         struct bdb_header *bdb)
+{
+       struct bdb_general_definitions *general;
+       const int crt_bus_map_table[] = {
+               GPIOB,
+               GPIOA,
+               GPIOC,
+               GPIOD,
+               GPIOE,
+               GPIOF,
+       };
+
+       /* Set sensible defaults in case we can't find the general block
+          or it is the wrong chipset */
+       dev_priv->crt_ddc_bus = -1;
+
+       general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
+       if (general) {
+               u16 block_size = get_blocksize(general);
+               if (block_size >= sizeof(*general)) {
+                       int bus_pin = general->crt_ddc_gmbus_pin;
+                       DRM_DEBUG("crt_ddc_bus_pin: %d\n", bus_pin);
+                       if ((bus_pin >= 1) && (bus_pin <= 6)) {
+                               dev_priv->crt_ddc_bus =
+                                       crt_bus_map_table[bus_pin-1];
+                       }
+               } else {
+                       DRM_DEBUG("BDB_GD too small (%d). Invalid.\n",
+                                 block_size);
+               }
+       }
+}
+
 static void
 parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
                       struct bdb_header *bdb)
@@ -222,7 +267,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
        struct bdb_general_definitions *p_defs;
        struct child_device_config *p_child;
        int i, child_device_num, count;
-       u16     block_size, *block_ptr;
+       u16     block_size;
 
        p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
        if (!p_defs) {
@@ -240,8 +285,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
                return;
        }
        /* get the block size of general definitions */
-       block_ptr = (u16 *)((char *)p_defs - 2);
-       block_size = *block_ptr;
+       block_size = get_blocksize(p_defs);
        /* get the number of child device */
        child_device_num = (block_size - sizeof(*p_defs)) /
                                sizeof(*p_child);
@@ -362,6 +406,7 @@ intel_init_bios(struct drm_device *dev)
 
        /* Grab useful general definitions */
        parse_general_features(dev_priv, bdb);
+       parse_general_definitions(dev_priv, bdb);
        parse_lfp_panel_data(dev_priv, bdb);
        parse_sdvo_panel_data(dev_priv, bdb);
        parse_sdvo_device_mapping(dev_priv, bdb);
index 4cf8e2e88a40eb56aae2052fedab7af3c03b45c4..590f81c8f59482b6e702d8b8191211e79cd8987b 100644 (file)
@@ -508,6 +508,7 @@ void intel_crt_init(struct drm_device *dev)
 {
        struct drm_connector *connector;
        struct intel_output *intel_output;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        u32 i2c_reg;
 
        intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
@@ -527,8 +528,12 @@ void intel_crt_init(struct drm_device *dev)
        /* Set up the DDC bus. */
        if (IS_IGDNG(dev))
                i2c_reg = PCH_GPIOA;
-       else
+       else {
                i2c_reg = GPIOA;
+               /* Use VBT information for CRT DDC if available */
+               if (dev_priv->crt_ddc_bus != -1)
+                       i2c_reg = dev_priv->crt_ddc_bus;
+       }
        intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
        if (!intel_output->ddc_bus) {
                dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
@@ -537,6 +542,10 @@ void intel_crt_init(struct drm_device *dev)
        }
 
        intel_output->type = INTEL_OUTPUT_ANALOG;
+       intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+                                  (1 << INTEL_ANALOG_CLONE_BIT) |
+                                  (1 << INTEL_SDVO_LVDS_CLONE_BIT);
+       intel_output->crtc_mask = (1 << 0) | (1 << 1);
        connector->interlace_allowed = 0;
        connector->doublescan_allowed = 0;
 
index d6fce2133413e5431bf6abda64f9e260cfca8d77..748ed50c55ca9c67683dcbdca233f6fb4aaa6e41 100644 (file)
@@ -666,7 +666,7 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
        intel_clock_t clock;
        int err = target;
 
-       if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
+       if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
            (I915_READ(LVDS)) != 0) {
                /*
                 * For LVDS, if the panel is on, just rely on its current
@@ -2005,7 +2005,21 @@ static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock,
        return;
 }
 
-const static int latency_ns = 3000; /* default for non-igd platforms */
+/*
+ * Latency for FIFO fetches is dependent on several factors:
+ *   - memory configuration (speed, channels)
+ *   - chipset
+ *   - current MCH state
+ * It can be fairly high in some situations, so here we assume a fairly
+ * pessimal value.  It's a tradeoff between extra memory fetches (if we
+ * set this value too high, the FIFO will fetch frequently to stay full)
+ * and power consumption (set it too low to save power and we might see
+ * FIFO underruns and display "flicker").
+ *
+ * A value of 5us seems to be a good balance; safe for very low end
+ * platforms but not overly aggressive on lower latency configs.
+ */
+const static int latency_ns = 5000;
 
 static int intel_get_fifo_size(struct drm_device *dev, int plane)
 {
@@ -2396,7 +2410,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                if (is_sdvo) {
                        dpll |= DPLL_DVO_HIGH_SPEED;
                        sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
-                       if (IS_I945G(dev) || IS_I945GM(dev))
+                       if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
                                dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
                        else if (IS_IGDNG(dev))
                                dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
@@ -3170,7 +3184,7 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask)
 
         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
                struct intel_output *intel_output = to_intel_output(connector);
-               if (type_mask & (1 << intel_output->type))
+               if (type_mask & intel_output->clone_mask)
                        index_mask |= (1 << entry);
                entry++;
        }
@@ -3218,30 +3232,30 @@ static void intel_setup_outputs(struct drm_device *dev)
                        intel_dp_init(dev, PCH_DP_D);
 
        } else if (IS_I9XX(dev)) {
-               int found;
-               u32 reg;
+               bool found = false;
 
                if (I915_READ(SDVOB) & SDVO_DETECTED) {
                        found = intel_sdvo_init(dev, SDVOB);
                        if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
                                intel_hdmi_init(dev, SDVOB);
+
                        if (!found && SUPPORTS_INTEGRATED_DP(dev))
                                intel_dp_init(dev, DP_B);
                }
 
                /* Before G4X SDVOC doesn't have its own detect register */
-               if (IS_G4X(dev))
-                       reg = SDVOC;
-               else
-                       reg = SDVOB;
 
-               if (I915_READ(reg) & SDVO_DETECTED) {
+               if (I915_READ(SDVOB) & SDVO_DETECTED)
                        found = intel_sdvo_init(dev, SDVOC);
-                       if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
+
+               if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) {
+
+                       if (SUPPORTS_INTEGRATED_HDMI(dev))
                                intel_hdmi_init(dev, SDVOC);
-                       if (!found && SUPPORTS_INTEGRATED_DP(dev))
+                       if (SUPPORTS_INTEGRATED_DP(dev))
                                intel_dp_init(dev, DP_C);
                }
+
                if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED))
                        intel_dp_init(dev, DP_D);
        } else
@@ -3253,51 +3267,10 @@ static void intel_setup_outputs(struct drm_device *dev)
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
                struct intel_output *intel_output = to_intel_output(connector);
                struct drm_encoder *encoder = &intel_output->enc;
-               int crtc_mask = 0, clone_mask = 0;
 
-               /* valid crtcs */
-               switch(intel_output->type) {
-               case INTEL_OUTPUT_HDMI:
-                       crtc_mask = ((1 << 0)|
-                                    (1 << 1));
-                       clone_mask = ((1 << INTEL_OUTPUT_HDMI));
-                       break;
-               case INTEL_OUTPUT_DVO:
-               case INTEL_OUTPUT_SDVO:
-                       crtc_mask = ((1 << 0)|
-                                    (1 << 1));
-                       clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
-                                     (1 << INTEL_OUTPUT_DVO) |
-                                     (1 << INTEL_OUTPUT_SDVO));
-                       break;
-               case INTEL_OUTPUT_ANALOG:
-                       crtc_mask = ((1 << 0)|
-                                    (1 << 1));
-                       clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
-                                     (1 << INTEL_OUTPUT_DVO) |
-                                     (1 << INTEL_OUTPUT_SDVO));
-                       break;
-               case INTEL_OUTPUT_LVDS:
-                       crtc_mask = (1 << 1);
-                       clone_mask = (1 << INTEL_OUTPUT_LVDS);
-                       break;
-               case INTEL_OUTPUT_TVOUT:
-                       crtc_mask = ((1 << 0) |
-                                    (1 << 1));
-                       clone_mask = (1 << INTEL_OUTPUT_TVOUT);
-                       break;
-               case INTEL_OUTPUT_DISPLAYPORT:
-                       crtc_mask = ((1 << 0) |
-                                    (1 << 1));
-                       clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT);
-                       break;
-               case INTEL_OUTPUT_EDP:
-                       crtc_mask = (1 << 1);
-                       clone_mask = (1 << INTEL_OUTPUT_EDP);
-                       break;
-               }
-               encoder->possible_crtcs = crtc_mask;
-               encoder->possible_clones = intel_connector_clones(dev, clone_mask);
+               encoder->possible_crtcs = intel_output->crtc_mask;
+               encoder->possible_clones = intel_connector_clones(dev,
+                                               intel_output->clone_mask);
        }
 }
 
index a6ff15ac548aa9074eec2647ce377a2290dc58c0..2b914d73207681b15fec693677fa2866d437b77f 100644 (file)
@@ -1254,6 +1254,18 @@ intel_dp_init(struct drm_device *dev, int output_reg)
        else
                intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
 
+       if (output_reg == DP_B)
+               intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
+       else if (output_reg == DP_C)
+               intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
+       else if (output_reg == DP_D)
+               intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
+
+       if (IS_eDP(intel_output)) {
+               intel_output->crtc_mask = (1 << 1);
+               intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
+       } else
+               intel_output->crtc_mask = (1 << 0) | (1 << 1);
        connector->interlace_allowed = true;
        connector->doublescan_allowed = 0;
 
index d6f92ea1b5538fc0928119b600f4eaa241f66ada..26a6227c15fe7c0f20f9f93594ba93254b7b3301 100644 (file)
 #define INTEL_OUTPUT_DISPLAYPORT 7
 #define INTEL_OUTPUT_EDP 8
 
+/* Intel Pipe Clone Bit */
+#define INTEL_HDMIB_CLONE_BIT 1
+#define INTEL_HDMIC_CLONE_BIT 2
+#define INTEL_HDMID_CLONE_BIT 3
+#define INTEL_HDMIE_CLONE_BIT 4
+#define INTEL_HDMIF_CLONE_BIT 5
+#define INTEL_SDVO_NON_TV_CLONE_BIT 6
+#define INTEL_SDVO_TV_CLONE_BIT 7
+#define INTEL_SDVO_LVDS_CLONE_BIT 8
+#define INTEL_ANALOG_CLONE_BIT 9
+#define INTEL_TV_CLONE_BIT 10
+#define INTEL_DP_B_CLONE_BIT 11
+#define INTEL_DP_C_CLONE_BIT 12
+#define INTEL_DP_D_CLONE_BIT 13
+#define INTEL_LVDS_CLONE_BIT 14
+#define INTEL_DVO_TMDS_CLONE_BIT 15
+#define INTEL_DVO_LVDS_CLONE_BIT 16
+#define INTEL_EDP_CLONE_BIT 17
+
 #define INTEL_DVO_CHIP_NONE 0
 #define INTEL_DVO_CHIP_LVDS 1
 #define INTEL_DVO_CHIP_TMDS 2
@@ -86,6 +105,8 @@ struct intel_output {
        bool needs_tv_clock;
        void *dev_priv;
        void (*hot_plug)(struct intel_output *);
+       int crtc_mask;
+       int clone_mask;
 };
 
 struct intel_crtc {
index 13bff20930e89f9a5bd2d83b3a4dace630252cf5..a4d2606de778c3d419713c3d8552290d828826c0 100644 (file)
@@ -435,14 +435,20 @@ void intel_dvo_init(struct drm_device *dev)
                        continue;
 
                intel_output->type = INTEL_OUTPUT_DVO;
+               intel_output->crtc_mask = (1 << 0) | (1 << 1);
                switch (dvo->type) {
                case INTEL_DVO_CHIP_TMDS:
+                       intel_output->clone_mask =
+                               (1 << INTEL_DVO_TMDS_CLONE_BIT) |
+                               (1 << INTEL_ANALOG_CLONE_BIT);
                        drm_connector_init(dev, connector,
                                           &intel_dvo_connector_funcs,
                                           DRM_MODE_CONNECTOR_DVII);
                        encoder_type = DRM_MODE_ENCODER_TMDS;
                        break;
                case INTEL_DVO_CHIP_LVDS:
+                       intel_output->clone_mask =
+                               (1 << INTEL_DVO_LVDS_CLONE_BIT);
                        drm_connector_init(dev, connector,
                                           &intel_dvo_connector_funcs,
                                           DRM_MODE_CONNECTOR_LVDS);
index 1842290cded3f074883a155269ceed3ae2e0b749..fa304e136010b0cef680590adbfc606b1776dcfa 100644 (file)
@@ -230,22 +230,28 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
 
        connector->interlace_allowed = 0;
        connector->doublescan_allowed = 0;
+       intel_output->crtc_mask = (1 << 0) | (1 << 1);
 
        /* Set up the DDC bus. */
-       if (sdvox_reg == SDVOB)
+       if (sdvox_reg == SDVOB) {
+               intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
                intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
-       else if (sdvox_reg == SDVOC)
+       } else if (sdvox_reg == SDVOC) {
+               intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
                intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
-       else if (sdvox_reg == HDMIB)
+       } else if (sdvox_reg == HDMIB) {
+               intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
                intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
                                                                "HDMIB");
-       else if (sdvox_reg == HDMIC)
+       } else if (sdvox_reg == HDMIC) {
+               intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
                intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
                                                                "HDMIC");
-       else if (sdvox_reg == HDMID)
+       } else if (sdvox_reg == HDMID) {
+               intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
                intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
                                                                "HDMID");
-
+       }
        if (!intel_output->ddc_bus)
                goto err_connector;
 
index 3f445a80c552908b251cfa9d0d688c653a2f10ab..8df02ef892617ed7a47b8ab9d88665b675cbb046 100644 (file)
@@ -916,6 +916,8 @@ void intel_lvds_init(struct drm_device *dev)
        drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
        intel_output->type = INTEL_OUTPUT_LVDS;
 
+       intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
+       intel_output->crtc_mask = (1 << 1);
        drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
        drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
        connector->display_info.subpixel_order = SubPixelHorizontalRGB;
index 5371d9332554fe9716bb5bd8403bb177b4829fd3..d3b74ba62b4a07bb1702eca5e62f28dcea017ade 100644 (file)
@@ -1458,7 +1458,7 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output)
                (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1))
                caps++;
        if (sdvo_priv->caps.output_flags &
-               (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID0))
+               (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1))
                caps++;
        if (sdvo_priv->caps.output_flags &
                (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1))
@@ -1967,6 +1967,9 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                        intel_sdvo_set_colorimetry(intel_output,
                                                   SDVO_COLORIMETRY_RGB256);
                        connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
+                       intel_output->clone_mask =
+                                       (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+                                       (1 << INTEL_ANALOG_CLONE_BIT);
                }
        } else if (flags & SDVO_OUTPUT_SVID0) {
 
@@ -1975,11 +1978,14 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
                sdvo_priv->is_tv = true;
                intel_output->needs_tv_clock = true;
+               intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
        } else if (flags & SDVO_OUTPUT_RGB0) {
 
                sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
                encoder->encoder_type = DRM_MODE_ENCODER_DAC;
                connector->connector_type = DRM_MODE_CONNECTOR_VGA;
+               intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+                                       (1 << INTEL_ANALOG_CLONE_BIT);
        } else if (flags & SDVO_OUTPUT_RGB1) {
 
                sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
@@ -1991,12 +1997,16 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
                connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
                sdvo_priv->is_lvds = true;
+               intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
+                                       (1 << INTEL_SDVO_LVDS_CLONE_BIT);
        } else if (flags & SDVO_OUTPUT_LVDS1) {
 
                sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1;
                encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
                connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
                sdvo_priv->is_lvds = true;
+               intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
+                                       (1 << INTEL_SDVO_LVDS_CLONE_BIT);
        } else {
 
                unsigned char bytes[2];
@@ -2009,6 +2019,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                                  bytes[0], bytes[1]);
                ret = false;
        }
+       intel_output->crtc_mask = (1 << 0) | (1 << 1);
 
        if (ret && registered)
                ret = drm_sysfs_connector_add(connector) == 0 ? true : false;
index da4ab4dc16306b6fc4b7727da0954f7736a290cb..5b1c9e9fdba04b89044b5131b00477c66b230c41 100644 (file)
@@ -1718,6 +1718,7 @@ intel_tv_init(struct drm_device *dev)
        if (!intel_output) {
                return;
        }
+
        connector = &intel_output->base;
 
        drm_connector_init(dev, connector, &intel_tv_connector_funcs,
@@ -1729,6 +1730,8 @@ intel_tv_init(struct drm_device *dev)
        drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
        tv_priv = (struct intel_tv_priv *)(intel_output + 1);
        intel_output->type = INTEL_OUTPUT_TVOUT;
+       intel_output->crtc_mask = (1 << 0) | (1 << 1);
+       intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT);
        intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1));
        intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
        intel_output->dev_priv = tv_priv;
index 90ff8e0ac04ee0e300cabf819da91d8513ca0791..68e728e8be4d3cda06ca678a5c363fd95a94eb84 100644 (file)
@@ -1091,6 +1091,16 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
                        tmp |= tile_flags;
                        ib[idx] = tmp;
                        break;
+               case RADEON_RB3D_ZPASS_ADDR:
+                       r = r100_cs_packet_next_reloc(p, &reloc);
+                       if (r) {
+                               DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+                                         idx, reg);
+                               r100_cs_dump_packet(p, pkt);
+                               return r;
+                       }
+                       ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+                       break;
                default:
                        /* FIXME: we don't want to allow anyothers packet */
                        break;
index c47579dcafa115022de6381f5e5f2a79b74ffd5a..051bca6e3a4f2981d1f580d7bbc174c43ac586d3 100644 (file)
@@ -448,6 +448,7 @@ void r300_gpu_init(struct radeon_device *rdev)
                /* rv350,rv370,rv380 */
                rdev->num_gb_pipes = 1;
        }
+       rdev->num_z_pipes = 1;
        gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16);
        switch (rdev->num_gb_pipes) {
        case 2:
@@ -486,7 +487,8 @@ void r300_gpu_init(struct radeon_device *rdev)
                printk(KERN_WARNING "Failed to wait MC idle while "
                       "programming pipes. Bad things might happen.\n");
        }
-       DRM_INFO("radeon: %d pipes initialized.\n", rdev->num_gb_pipes);
+       DRM_INFO("radeon: %d quad pipes, %d Z pipes initialized.\n",
+                rdev->num_gb_pipes, rdev->num_z_pipes);
 }
 
 int r300_ga_reset(struct radeon_device *rdev)
@@ -993,7 +995,7 @@ static const unsigned r300_reg_safe_bm[159] = {
        0x00000000, 0x00000000, 0x00000000, 0x00000000,
        0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF,
        0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x0003FC01, 0xFFFFFFF8, 0xFE800B19,
+       0x0003FC01, 0xFFFFFCF8, 0xFF800B19,
 };
 
 static int r300_packet0_check(struct radeon_cs_parser *p,
index dea497a979f2083548d491ca9505571696f6ecea..97426a6f370f11695276105dc8906fc10c203c9c 100644 (file)
@@ -165,7 +165,18 @@ void r420_pipes_init(struct radeon_device *rdev)
                printk(KERN_WARNING "Failed to wait GUI idle while "
                       "programming pipes. Bad things might happen.\n");
        }
-       DRM_INFO("radeon: %d pipes initialized.\n", rdev->num_gb_pipes);
+
+       if (rdev->family == CHIP_RV530) {
+               tmp = RREG32(RV530_GB_PIPE_SELECT2);
+               if ((tmp & 3) == 3)
+                       rdev->num_z_pipes = 2;
+               else
+                       rdev->num_z_pipes = 1;
+       } else
+               rdev->num_z_pipes = 1;
+
+       DRM_INFO("radeon: %d quad pipes, %d z pipes initialized.\n",
+                rdev->num_gb_pipes, rdev->num_z_pipes);
 }
 
 void r420_gpu_init(struct radeon_device *rdev)
index 09fb0b6ec7dd1748c2803e5f18d4e4a1082275d2..ebd6b0f7bdff584577a27a1feabbaa66e1cad355 100644 (file)
@@ -177,7 +177,6 @@ void r520_gpu_init(struct radeon_device *rdev)
         */
        /* workaround for RV530 */
        if (rdev->family == CHIP_RV530) {
-               WREG32(0x4124, 1);
                WREG32(0x4128, 0xFF);
        }
        r420_pipes_init(rdev);
index 79ad98264e33c69411fe37678760b68b3043f1f9..b519fb2fecbb4ba25df535c61fa15316b5032d6d 100644 (file)
@@ -655,6 +655,7 @@ struct radeon_device {
        int                             usec_timeout;
        enum radeon_pll_errata          pll_errata;
        int                             num_gb_pipes;
+       int                             num_z_pipes;
        int                             disp_priority;
        /* BIOS */
        uint8_t                         *bios;
index 7ca6c13569b5045a7ed3c71fb642e913e33604cf..93d8f88893024088624e007e36ec2bb9b106eeed 100644 (file)
@@ -266,6 +266,7 @@ static struct radeon_asic rs400_asic = {
 /*
  * rs600.
  */
+int rs600_init(struct radeon_device *dev);
 void rs600_errata(struct radeon_device *rdev);
 void rs600_vram_info(struct radeon_device *rdev);
 int rs600_mc_init(struct radeon_device *rdev);
@@ -281,7 +282,7 @@ uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg);
 void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 void rs600_bandwidth_update(struct radeon_device *rdev);
 static struct radeon_asic rs600_asic = {
-       .init = &r300_init,
+       .init = &rs600_init,
        .errata = &rs600_errata,
        .vram_info = &rs600_vram_info,
        .gpu_reset = &r300_gpu_reset,
@@ -316,7 +317,6 @@ static struct radeon_asic rs600_asic = {
 /*
  * rs690,rs740
  */
-int rs690_init(struct radeon_device *rdev);
 void rs690_errata(struct radeon_device *rdev);
 void rs690_vram_info(struct radeon_device *rdev);
 int rs690_mc_init(struct radeon_device *rdev);
@@ -325,7 +325,7 @@ uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg);
 void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 void rs690_bandwidth_update(struct radeon_device *rdev);
 static struct radeon_asic rs690_asic = {
-       .init = &rs690_init,
+       .init = &rs600_init,
        .errata = &rs690_errata,
        .vram_info = &rs690_vram_info,
        .gpu_reset = &r300_gpu_reset,
index d8356827ef17f8f7ae75a09868646c1d39bb4e4e..7a52c461145c6a48d1a7c76f13bf1f43f4513e90 100644 (file)
@@ -406,6 +406,15 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
 {
        uint32_t gb_tile_config, gb_pipe_sel = 0;
 
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) {
+               uint32_t z_pipe_sel = RADEON_READ(RV530_GB_PIPE_SELECT2);
+               if ((z_pipe_sel & 3) == 3)
+                       dev_priv->num_z_pipes = 2;
+               else
+                       dev_priv->num_z_pipes = 1;
+       } else
+               dev_priv->num_z_pipes = 1;
+
        /* RS4xx/RS6xx/R4xx/R5xx */
        if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) {
                gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT);
index 3933f8216a34d8aa43cb536b7157c0e7cc6d4c21..6fa32dac4e978e0857a8de1c8a347e630a1996a3 100644 (file)
  * 1.28- Add support for VBL on CRTC2
  * 1.29- R500 3D cmd buffer support
  * 1.30- Add support for occlusion queries
+ * 1.31- Add support for num Z pipes from GET_PARAM
  */
 #define DRIVER_MAJOR           1
-#define DRIVER_MINOR           30
+#define DRIVER_MINOR           31
 #define DRIVER_PATCHLEVEL      0
 
 /*
@@ -329,6 +330,7 @@ typedef struct drm_radeon_private {
        resource_size_t fb_aper_offset;
 
        int num_gb_pipes;
+       int num_z_pipes;
        int track_flush;
        drm_local_map_t *mmio;
 
@@ -689,6 +691,7 @@ extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pciga
 
 /* pipe config regs */
 #define R400_GB_PIPE_SELECT             0x402c
+#define RV530_GB_PIPE_SELECT2           0x4124
 #define R500_DYN_SCLK_PWMEM_PIPE        0x000d /* PLL */
 #define R300_GB_TILE_CONFIG             0x4018
 #       define R300_ENABLE_TILING       (1 << 0)
index d4ceff13bbb14580e874bdaa84dcfdf701c3e4cc..d880edf254dbad63a73e99ee7c05de40757e9ecc 100644 (file)
@@ -274,16 +274,22 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
        }
        robj = gobj->driver_private;
        r = radeon_object_busy_domain(robj, &cur_placement);
-       if (cur_placement == TTM_PL_VRAM)
+       switch (cur_placement) {
+       case TTM_PL_VRAM:
                args->domain = RADEON_GEM_DOMAIN_VRAM;
-       if (cur_placement == TTM_PL_FLAG_TT)
+               break;
+       case TTM_PL_TT:
                args->domain = RADEON_GEM_DOMAIN_GTT;
-       if (cur_placement == TTM_PL_FLAG_SYSTEM)
+               break;
+       case TTM_PL_SYSTEM:
                args->domain = RADEON_GEM_DOMAIN_CPU;
+       default:
+               break;
+       }
        mutex_lock(&dev->struct_mutex);
        drm_gem_object_unreference(gobj);
        mutex_unlock(&dev->struct_mutex);
-       return 0;
+       return r;
 }
 
 int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
index d2764bf6b2a27391519c5e9644267176dcf40fa7..dce09ada32bcc9461db496c23127b31303d8049b 100644 (file)
@@ -95,6 +95,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
        case RADEON_INFO_NUM_GB_PIPES:
                value = rdev->num_gb_pipes;
                break;
+       case RADEON_INFO_NUM_Z_PIPES:
+               value = rdev->num_z_pipes;
+               break;
        default:
                DRM_DEBUG("Invalid request %d\n", info->request);
                return -EINVAL;
@@ -318,5 +321,6 @@ struct drm_ioctl_desc radeon_ioctls_kms[] = {
        DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH),
        DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH),
        DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH),
 };
 int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms);
index 5a098f304edbfacc39832cb7a4af155084ed6e6a..4df43f62c678ae715ec0b8e0a74415d6d74056f2 100644 (file)
 #       define RADEON_RE_WIDTH_SHIFT        0
 #       define RADEON_RE_HEIGHT_SHIFT       16
 
+#define RADEON_RB3D_ZPASS_DATA 0x3290
+#define RADEON_RB3D_ZPASS_ADDR 0x3294
+
 #define RADEON_SE_CNTL                      0x1c4c
 #       define RADEON_FFACE_CULL_CW          (0 <<  0)
 #       define RADEON_FFACE_CULL_CCW         (1 <<  0)
 #define RADEON_SCRATCH_REG4            0x15f0
 #define RADEON_SCRATCH_REG5            0x15f4
 
+#define RV530_GB_PIPE_SELECT2           0x4124
+
 #endif
index 46645f3e03286e448d15659a14e72d24d79fb332..2882f40d5ec563d4ac5760314ca2a8b7b5da8282 100644 (file)
@@ -3081,6 +3081,9 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
        case RADEON_PARAM_NUM_GB_PIPES:
                value = dev_priv->num_gb_pipes;
                break;
+       case RADEON_PARAM_NUM_Z_PIPES:
+               value = dev_priv->num_z_pipes;
+               break;
        default:
                DRM_DEBUG("Invalid parameter %d\n", param->param);
                return -EINVAL;
index 7e8ce983a9089e1831d311593ce59abfdbbf61c2..02fd11aad6a28bed2f30eb111ec0a187d114cb63 100644 (file)
@@ -409,3 +409,68 @@ void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
                ((reg) & RS600_MC_ADDR_MASK));
        WREG32(RS600_MC_DATA, v);
 }
+
+static const unsigned rs600_reg_safe_bm[219] = {
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF,
+       0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000,
+       0xF0000078, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFC78, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
+       0x38FF8F50, 0xFFF88082, 0xF000000C, 0xFAE009FF,
+       0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
+       0x00000000, 0x0000C100, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x0003FC01, 0xFFFFFCF8, 0xFF800B19, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+};
+
+int rs600_init(struct radeon_device *rdev)
+{
+       rdev->config.r300.reg_safe_bm = rs600_reg_safe_bm;
+       rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rs600_reg_safe_bm);
+       return 0;
+}
index bc6b7c5339bc3d6a0bdc2c94cfa3d89510dcd5a8..879882533e45a121e47d7eb8340a76b508d5330a 100644 (file)
@@ -653,67 +653,3 @@ void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
        WREG32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK);
 }
 
-static const unsigned rs690_reg_safe_bm[219] = {
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0x17FF1FFF,0xFFFFFFFC,0xFFFFFFFF,0xFF30FFBF,
-       0xFFFFFFF8,0xC3E6FFFF,0xFFFFF6DF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFF03F,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFEFCE,0xF00EBFFF,0x007C0000,
-       0xF0000078,0xFF000009,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFF7FF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFC78,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,
-       0x38FF8F50,0xFFF88082,0xF000000C,0xFAE009FF,
-       0x0000FFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,
-       0x00000000,0x0000C100,0x00000000,0x00000000,
-       0x00000000,0x00000000,0x00000000,0x00000000,
-       0x00000000,0xFFFF0000,0xFFFFFFFF,0xFF80FFFF,
-       0x00000000,0x00000000,0x00000000,0x00000000,
-       0x0003FC01,0xFFFFFFF8,0xFE800B19,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-       0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-};
-
-int rs690_init(struct radeon_device *rdev)
-{
-       rdev->config.r300.reg_safe_bm = rs690_reg_safe_bm;
-       rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rs690_reg_safe_bm);
-       return 0;
-}
index 31a7f668ae5af2c130c2657a3a7b992f18d5a8c1..0566fb67e4607b4c50d335df74a5ef25d9d55f1a 100644 (file)
@@ -508,7 +508,7 @@ static const unsigned r500_reg_safe_bm[219] = {
        0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
        0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF80FFFF,
        0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x0003FC01, 0x3FFFFCF8, 0xFE800B19, 0xFFFFFFFF,
+       0x0003FC01, 0x3FFFFCF8, 0xFF800B19, 0xFFDFFFFF,
        0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
        0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
        0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
index d258b02aef44c4ef99c38d58b5da84a2d943b3c6..827da085813649b9348215fc77f0e8a5021fca0b 100644 (file)
@@ -674,7 +674,14 @@ omap_i2c_isr(int this_irq, void *dev_id)
 
                err = 0;
 complete:
-               omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat);
+               /*
+                * Ack the stat in one go, but [R/X]DR and [R/X]RDY should be
+                * acked after the data operation is complete.
+                * Ref: TRM SWPU114Q Figure 18-31
+                */
+               omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat &
+                               ~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
+                               OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
 
                if (stat & OMAP_I2C_STAT_NACK) {
                        err |= OMAP_I2C_STAT_NACK;
@@ -687,6 +694,9 @@ complete:
                }
                if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
                                        OMAP_I2C_STAT_AL)) {
+                       omap_i2c_ack_stat(dev, stat &
+                               (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
+                               OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
                        omap_i2c_complete_cmd(dev, err);
                        return IRQ_HANDLED;
                }
@@ -774,7 +784,7 @@ complete:
                                 * memory to the I2C interface.
                                 */
 
-                               if (cpu_is_omap34xx()) {
+                               if (dev->rev <= OMAP_I2C_REV_ON_3430) {
                                                while (!(stat & OMAP_I2C_STAT_XUDF)) {
                                                        if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
                                                                omap_i2c_ack_stat(dev, stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
index 182e711318bacf6793307b6641ab2ab6910158b8..d2728a28a8dba926e563957ad6339db653a7c632 100644 (file)
@@ -117,7 +117,8 @@ enum stu300_error {
        STU300_ERROR_NONE = 0,
        STU300_ERROR_ACKNOWLEDGE_FAILURE,
        STU300_ERROR_BUS_ERROR,
-       STU300_ERROR_ARBITRATION_LOST
+       STU300_ERROR_ARBITRATION_LOST,
+       STU300_ERROR_UNKNOWN
 };
 
 /* timeout waiting for the controller to respond */
@@ -127,7 +128,7 @@ enum stu300_error {
  * The number of address send athemps tried before giving up.
  * If the first one failes it seems like 5 to 8 attempts are required.
  */
-#define NUM_ADDR_RESEND_ATTEMPTS 10
+#define NUM_ADDR_RESEND_ATTEMPTS 12
 
 /* I2C clock speed, in Hz 0-400kHz*/
 static unsigned int scl_frequency = 100000;
@@ -149,6 +150,7 @@ module_param(scl_frequency, uint,  0644);
  * @msg_index: index of current message
  * @msg_len: length of current message
  */
+
 struct stu300_dev {
        struct platform_device  *pdev;
        struct i2c_adapter      adapter;
@@ -188,6 +190,27 @@ static inline u32 stu300_r8(void __iomem *address)
        return readl(address) & 0x000000FFU;
 }
 
+static void stu300_irq_enable(struct stu300_dev *dev)
+{
+       u32 val;
+       val = stu300_r8(dev->virtbase + I2C_CR);
+       val |= I2C_CR_INTERRUPT_ENABLE;
+       /* Twice paranoia (possible HW glitch) */
+       stu300_wr8(val, dev->virtbase + I2C_CR);
+       stu300_wr8(val, dev->virtbase + I2C_CR);
+}
+
+static void stu300_irq_disable(struct stu300_dev *dev)
+{
+       u32 val;
+       val = stu300_r8(dev->virtbase + I2C_CR);
+       val &= ~I2C_CR_INTERRUPT_ENABLE;
+       /* Twice paranoia (possible HW glitch) */
+       stu300_wr8(val, dev->virtbase + I2C_CR);
+       stu300_wr8(val, dev->virtbase + I2C_CR);
+}
+
+
 /*
  * Tells whether a certain event or events occurred in
  * response to a command. The events represent states in
@@ -196,9 +219,10 @@ static inline u32 stu300_r8(void __iomem *address)
  * documentation and can only be treated as abstract state
  * machine states.
  *
- * @ret 0 = event has not occurred, any other value means
- * the event occurred.
+ * @ret 0 = event has not occurred or unknown error, any
+ * other value means the correct event occurred or an error.
  */
+
 static int stu300_event_occurred(struct stu300_dev *dev,
                                   enum stu300_event mr_event) {
        u32 status1;
@@ -206,11 +230,28 @@ static int stu300_event_occurred(struct stu300_dev *dev,
 
        /* What event happened? */
        status1 = stu300_r8(dev->virtbase + I2C_SR1);
+
        if (!(status1 & I2C_SR1_EVF_IND))
                /* No event at all */
                return 0;
+
        status2 = stu300_r8(dev->virtbase + I2C_SR2);
 
+       /* Block any multiple interrupts */
+       stu300_irq_disable(dev);
+
+       /* Check for errors first */
+       if (status2 & I2C_SR2_AF_IND) {
+               dev->cmd_err = STU300_ERROR_ACKNOWLEDGE_FAILURE;
+               return 1;
+       } else if (status2 & I2C_SR2_BERR_IND) {
+               dev->cmd_err = STU300_ERROR_BUS_ERROR;
+               return 1;
+       } else if (status2 & I2C_SR2_ARLO_IND) {
+               dev->cmd_err = STU300_ERROR_ARBITRATION_LOST;
+               return 1;
+       }
+
        switch (mr_event) {
        case STU300_EVENT_1:
                if (status1 & I2C_SR1_ADSL_IND)
@@ -221,10 +262,6 @@ static int stu300_event_occurred(struct stu300_dev *dev,
        case STU300_EVENT_7:
        case STU300_EVENT_8:
                if (status1 & I2C_SR1_BTF_IND) {
-                       if (status2 & I2C_SR2_AF_IND)
-                               dev->cmd_err = STU300_ERROR_ACKNOWLEDGE_FAILURE;
-                       else if (status2 & I2C_SR2_BERR_IND)
-                               dev->cmd_err = STU300_ERROR_BUS_ERROR;
                        return 1;
                }
                break;
@@ -240,8 +277,6 @@ static int stu300_event_occurred(struct stu300_dev *dev,
        case STU300_EVENT_6:
                if (status2 & I2C_SR2_ENDAD_IND) {
                        /* First check for any errors */
-                       if (status2 & I2C_SR2_AF_IND)
-                               dev->cmd_err = STU300_ERROR_ACKNOWLEDGE_FAILURE;
                        return 1;
                }
                break;
@@ -252,8 +287,15 @@ static int stu300_event_occurred(struct stu300_dev *dev,
        default:
                break;
        }
-       if (status2 & I2C_SR2_ARLO_IND)
-               dev->cmd_err = STU300_ERROR_ARBITRATION_LOST;
+       /* If we get here, we're on thin ice.
+        * Here we are in a status where we have
+        * gotten a response that does not match
+        * what we requested.
+        */
+       dev->cmd_err = STU300_ERROR_UNKNOWN;
+       dev_err(&dev->pdev->dev,
+               "Unhandled interrupt! %d sr1: 0x%x sr2: 0x%x\n",
+               mr_event, status1, status2);
        return 0;
 }
 
@@ -262,21 +304,20 @@ static irqreturn_t stu300_irh(int irq, void *data)
        struct stu300_dev *dev = data;
        int res;
 
+       /* Just make sure that the block is clocked */
+       clk_enable(dev->clk);
+
        /* See if this was what we were waiting for */
        spin_lock(&dev->cmd_issue_lock);
-       if (dev->cmd_event != STU300_EVENT_NONE) {
-               res = stu300_event_occurred(dev, dev->cmd_event);
-               if (res || dev->cmd_err != STU300_ERROR_NONE) {
-                       u32 val;
-
-                       complete(&dev->cmd_complete);
-                       /* Block any multiple interrupts */
-                       val = stu300_r8(dev->virtbase + I2C_CR);
-                       val &= ~I2C_CR_INTERRUPT_ENABLE;
-                       stu300_wr8(val, dev->virtbase + I2C_CR);
-               }
-       }
+
+       res = stu300_event_occurred(dev, dev->cmd_event);
+       if (res || dev->cmd_err != STU300_ERROR_NONE)
+               complete(&dev->cmd_complete);
+
        spin_unlock(&dev->cmd_issue_lock);
+
+       clk_disable(dev->clk);
+
        return IRQ_HANDLED;
 }
 
@@ -308,7 +349,6 @@ static int stu300_start_and_await_event(struct stu300_dev *dev,
        stu300_wr8(cr_value, dev->virtbase + I2C_CR);
        ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
                                                        STU300_TIMEOUT);
-
        if (ret < 0) {
                dev_err(&dev->pdev->dev,
                       "wait_for_completion_interruptible_timeout() "
@@ -342,7 +382,6 @@ static int stu300_await_event(struct stu300_dev *dev,
                                enum stu300_event mr_event)
 {
        int ret;
-       u32 val;
 
        if (unlikely(irqs_disabled())) {
                /* TODO: implement polling for this case if need be. */
@@ -354,36 +393,18 @@ static int stu300_await_event(struct stu300_dev *dev,
        /* Is it already here? */
        spin_lock_irq(&dev->cmd_issue_lock);
        dev->cmd_err = STU300_ERROR_NONE;
-       if (stu300_event_occurred(dev, mr_event)) {
-               spin_unlock_irq(&dev->cmd_issue_lock);
-               goto exit_await_check_err;
-       }
-       init_completion(&dev->cmd_complete);
-       dev->cmd_err = STU300_ERROR_NONE;
        dev->cmd_event = mr_event;
 
-       /* Turn on the I2C interrupt for current operation */
-       val = stu300_r8(dev->virtbase + I2C_CR);
-       val |= I2C_CR_INTERRUPT_ENABLE;
-       stu300_wr8(val, dev->virtbase + I2C_CR);
-
-       /* Twice paranoia (possible HW glitch) */
-       stu300_wr8(val, dev->virtbase + I2C_CR);
+       init_completion(&dev->cmd_complete);
 
-       /* Check again: is it already here? */
-       if (unlikely(stu300_event_occurred(dev, mr_event))) {
-               /* Disable IRQ again. */
-               val &= ~I2C_CR_INTERRUPT_ENABLE;
-               stu300_wr8(val, dev->virtbase + I2C_CR);
-               spin_unlock_irq(&dev->cmd_issue_lock);
-               goto exit_await_check_err;
-       }
+       /* Turn on the I2C interrupt for current operation */
+       stu300_irq_enable(dev);
 
        /* Unlock the command block and wait for the event to occur */
        spin_unlock_irq(&dev->cmd_issue_lock);
+
        ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
                                                        STU300_TIMEOUT);
-
        if (ret < 0) {
                dev_err(&dev->pdev->dev,
                       "wait_for_completion_interruptible_timeout()"
@@ -401,7 +422,6 @@ static int stu300_await_event(struct stu300_dev *dev,
                return -ETIMEDOUT;
        }
 
- exit_await_check_err:
        if (dev->cmd_err != STU300_ERROR_NONE) {
                if (mr_event != STU300_EVENT_6) {
                        dev_err(&dev->pdev->dev, "controller "
@@ -457,18 +477,19 @@ struct stu300_clkset {
 };
 
 static const struct stu300_clkset stu300_clktable[] = {
-       { 0, 0xFFU },
-       { 2500000, I2C_OAR2_FR_25_10MHZ },
-       { 10000000, I2C_OAR2_FR_10_1667MHZ },
-       { 16670000, I2C_OAR2_FR_1667_2667MHZ },
-       { 26670000, I2C_OAR2_FR_2667_40MHZ },
-       { 40000000, I2C_OAR2_FR_40_5333MHZ },
-       { 53330000, I2C_OAR2_FR_5333_66MHZ },
-       { 66000000, I2C_OAR2_FR_66_80MHZ },
-       { 80000000, I2C_OAR2_FR_80_100MHZ },
+       { 0,         0xFFU },
+       { 2500000,   I2C_OAR2_FR_25_10MHZ },
+       { 10000000,  I2C_OAR2_FR_10_1667MHZ },
+       { 16670000,  I2C_OAR2_FR_1667_2667MHZ },
+       { 26670000,  I2C_OAR2_FR_2667_40MHZ },
+       { 40000000,  I2C_OAR2_FR_40_5333MHZ },
+       { 53330000,  I2C_OAR2_FR_5333_66MHZ },
+       { 66000000,  I2C_OAR2_FR_66_80MHZ },
+       { 80000000,  I2C_OAR2_FR_80_100MHZ },
        { 100000000, 0xFFU },
 };
 
+
 static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate)
 {
 
@@ -494,10 +515,10 @@ static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate)
 
        if (dev->speed > 100000)
                /* Fast Mode I2C */
-               val = ((clkrate/dev->speed)-9)/3;
+               val = ((clkrate/dev->speed) - 9)/3 + 1;
        else
                /* Standard Mode I2C */
-               val = ((clkrate/dev->speed)-7)/2;
+               val = ((clkrate/dev->speed) - 7)/2 + 1;
 
        /* According to spec the divider must be > 2 */
        if (val < 0x002) {
@@ -557,6 +578,7 @@ static int stu300_init_hw(struct stu300_dev *dev)
         */
        clkrate = clk_get_rate(dev->clk);
        ret = stu300_set_clk(dev, clkrate);
+
        if (ret)
                return ret;
        /*
@@ -641,7 +663,6 @@ static int stu300_xfer_msg(struct i2c_adapter *adap,
        int attempts = 0;
        struct stu300_dev *dev = i2c_get_adapdata(adap);
 
-
        clk_enable(dev->clk);
 
        /* Remove this if (0) to trace each and every message. */
@@ -715,14 +736,15 @@ static int stu300_xfer_msg(struct i2c_adapter *adap,
 
        if (attempts < NUM_ADDR_RESEND_ATTEMPTS && attempts > 0) {
                dev_dbg(&dev->pdev->dev, "managed to get address "
-                      "through after %d attempts\n", attempts);
+                       "through after %d attempts\n", attempts);
        } else if (attempts == NUM_ADDR_RESEND_ATTEMPTS) {
                dev_dbg(&dev->pdev->dev, "I give up, tried %d times "
-                      "to resend address.\n",
-                      NUM_ADDR_RESEND_ATTEMPTS);
+                       "to resend address.\n",
+                       NUM_ADDR_RESEND_ATTEMPTS);
                goto exit_disable;
        }
 
+
        if (msg->flags & I2C_M_RD) {
                /* READ: we read the actual bytes one at a time */
                for (i = 0; i < msg->len; i++) {
@@ -804,8 +826,10 @@ static int stu300_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
 {
        int ret = -1;
        int i;
+
        struct stu300_dev *dev = i2c_get_adapdata(adap);
        dev->msg_len = num;
+
        for (i = 0; i < num; i++) {
                /*
                 * Another driver appears to send stop for each message,
@@ -817,6 +841,7 @@ static int stu300_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
                dev->msg_index = i;
 
                ret = stu300_xfer_msg(adap, &msgs[i], (i == (num - 1)));
+
                if (ret != 0) {
                        num = ret;
                        break;
@@ -845,6 +870,7 @@ stu300_probe(struct platform_device *pdev)
        struct resource *res;
        int bus_nr;
        int ret = 0;
+       char clk_name[] = "I2C0";
 
        dev = kzalloc(sizeof(struct stu300_dev), GFP_KERNEL);
        if (!dev) {
@@ -854,7 +880,8 @@ stu300_probe(struct platform_device *pdev)
        }
 
        bus_nr = pdev->id;
-       dev->clk = clk_get(&pdev->dev, NULL);
+       clk_name[3] += (char)bus_nr;
+       dev->clk = clk_get(&pdev->dev, clk_name);
        if (IS_ERR(dev->clk)) {
                ret = PTR_ERR(dev->clk);
                dev_err(&pdev->dev, "could not retrieve i2c bus clock\n");
index 527908ff298c408c0f86fdf24363ea9c70d6e652..063b933d864a81f04acc0bbabdce2ec0297b7088 100644 (file)
@@ -408,6 +408,7 @@ static struct pcmcia_device_id ide_ids[] = {
        PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9),
        PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591),
        PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728),
+       PCMCIA_DEVICE_PROD_ID12("CNF   ", "CD-ROM", 0x46d7db81, 0x66536591),
        PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591),
        PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4),
        PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde),
index 4cfd084fa8972dda828fa59197eee7e383a03d0c..9a1d55b74d7a0b79296ee909a11011140f71d4a3 100644 (file)
@@ -456,8 +456,11 @@ static int joydev_ioctl_common(struct joydev *joydev,
                                unsigned int cmd, void __user *argp)
 {
        struct input_dev *dev = joydev->handle.dev;
+       size_t len;
        int i, j;
+       const char *name;
 
+       /* Process fixed-sized commands. */
        switch (cmd) {
 
        case JS_SET_CAL:
@@ -499,9 +502,22 @@ static int joydev_ioctl_common(struct joydev *joydev,
                return copy_to_user(argp, joydev->corr,
                        sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0;
 
-       case JSIOCSAXMAP:
-               if (copy_from_user(joydev->abspam, argp,
-                                  sizeof(__u8) * (ABS_MAX + 1)))
+       }
+
+       /*
+        * Process variable-sized commands (the axis and button map commands
+        * are considered variable-sized to decouple them from the values of
+        * ABS_MAX and KEY_MAX).
+        */
+       switch (cmd & ~IOCSIZE_MASK) {
+
+       case (JSIOCSAXMAP & ~IOCSIZE_MASK):
+               len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
+               /*
+                * FIXME: we should not copy into our axis map before
+                * validating the data.
+                */
+               if (copy_from_user(joydev->abspam, argp, len))
                        return -EFAULT;
 
                for (i = 0; i < joydev->nabs; i++) {
@@ -511,13 +527,17 @@ static int joydev_ioctl_common(struct joydev *joydev,
                }
                return 0;
 
-       case JSIOCGAXMAP:
-               return copy_to_user(argp, joydev->abspam,
-                       sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0;
-
-       case JSIOCSBTNMAP:
-               if (copy_from_user(joydev->keypam, argp,
-                                  sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)))
+       case (JSIOCGAXMAP & ~IOCSIZE_MASK):
+               len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
+               return copy_to_user(argp, joydev->abspam, len) ? -EFAULT : 0;
+
+       case (JSIOCSBTNMAP & ~IOCSIZE_MASK):
+               len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
+               /*
+                * FIXME: we should not copy into our keymap before
+                * validating the data.
+                */
+               if (copy_from_user(joydev->keypam, argp, len))
                        return -EFAULT;
 
                for (i = 0; i < joydev->nkey; i++) {
@@ -529,25 +549,19 @@ static int joydev_ioctl_common(struct joydev *joydev,
 
                return 0;
 
-       case JSIOCGBTNMAP:
-               return copy_to_user(argp, joydev->keypam,
-                       sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0;
+       case (JSIOCGBTNMAP & ~IOCSIZE_MASK):
+               len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
+               return copy_to_user(argp, joydev->keypam, len) ? -EFAULT : 0;
 
-       default:
-               if ((cmd & ~IOCSIZE_MASK) == JSIOCGNAME(0)) {
-                       int len;
-                       const char *name = dev->name;
-
-                       if (!name)
-                               return 0;
-                       len = strlen(name) + 1;
-                       if (len > _IOC_SIZE(cmd))
-                               len = _IOC_SIZE(cmd);
-                       if (copy_to_user(argp, name, len))
-                               return -EFAULT;
-                       return len;
-               }
+       case JSIOCGNAME(0):
+               name = dev->name;
+               if (!name)
+                       return 0;
+
+               len = min_t(size_t, _IOC_SIZE(cmd), strlen(name) + 1);
+               return copy_to_user(argp, name, len) ? -EFAULT : len;
        }
+
        return -EINVAL;
 }
 
index baabf8302645511b91c65a02c67baa5e1647218a..f6c688cae33430e877cf88e39f2bfda4553ef145 100644 (file)
@@ -74,6 +74,7 @@ static struct iforce_device iforce_device[] = {
        { 0x05ef, 0x8884, "AVB Mag Turbo Force",                        btn_avb_wheel, abs_wheel, ff_iforce },
        { 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel",   btn_avb_tw, abs_wheel, ff_iforce }, //?
        { 0x061c, 0xc0a4, "ACT LABS Force RS",                          btn_wheel, abs_wheel, ff_iforce }, //?
+       { 0x061c, 0xc084, "ACT LABS Force RS",                          btn_wheel, abs_wheel, ff_iforce },
        { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback",       btn_wheel, abs_wheel, ff_iforce }, //?
        { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel",      btn_wheel, abs_wheel, ff_iforce }, //?
        { 0x06f8, 0x0004, "Gullemot Jet Leader 3D",                     btn_joystick, abs_joystick, ff_iforce }, //?
index f83185aeb511abeab1bae588a06818f4b63c9a71..9f289d8f52c6e70dc0b6c28c0583291e46cdadaa 100644 (file)
@@ -223,6 +223,7 @@ static struct usb_device_id iforce_usb_ids [] = {
        { USB_DEVICE(0x05ef, 0x8884) },         /* AVB Mag Turbo Force */
        { USB_DEVICE(0x05ef, 0x8888) },         /* AVB Top Shot FFB Racing Wheel */
        { USB_DEVICE(0x061c, 0xc0a4) },         /* ACT LABS Force RS */
+       { USB_DEVICE(0x061c, 0xc084) },         /* ACT LABS Force RS */
        { USB_DEVICE(0x06f8, 0x0001) },         /* Guillemot Race Leader Force Feedback */
        { USB_DEVICE(0x06f8, 0x0004) },         /* Guillemot Force Feedback Racing Wheel */
        { USB_DEVICE(0x06f8, 0xa302) },         /* Guillemot Jet Leader 3D */
index 95fe0452dae48e809d4c7c6db9dab80fae57d127..6c6a09b1c0fed5f116ccddd4ab39de971c08e5a4 100644 (file)
@@ -879,6 +879,14 @@ static unsigned int atkbd_hp_zv6100_forced_release_keys[] = {
        0xae, 0xb0, -1U
 };
 
+/*
+ * Perform fixup for HP (Compaq) Presario R4000 R4100 R4200 that don't generate
+ * release for their volume buttons
+ */
+static unsigned int atkbd_hp_r4000_forced_release_keys[] = {
+       0xae, 0xb0, -1U
+};
+
 /*
  * Samsung NC10,NC20 with Fn+F? key release not working
  */
@@ -1536,6 +1544,33 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
                .callback = atkbd_setup_forced_release,
                .driver_data = atkbd_hp_zv6100_forced_release_keys,
        },
+       {
+               .ident = "HP Presario R4000",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"),
+               },
+               .callback = atkbd_setup_forced_release,
+               .driver_data = atkbd_hp_r4000_forced_release_keys,
+       },
+       {
+               .ident = "HP Presario R4100",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"),
+               },
+               .callback = atkbd_setup_forced_release,
+               .driver_data = atkbd_hp_r4000_forced_release_keys,
+       },
+       {
+               .ident = "HP Presario R4200",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"),
+               },
+               .callback = atkbd_setup_forced_release,
+               .driver_data = atkbd_hp_r4000_forced_release_keys,
+       },
        {
                .ident = "Inventec Symphony",
                .matches = {
index ae04d8a494e56e4e6e47f16922879177a6a13283..ccbf23ece8e370cc2e59fa4fef47d8cfd9ed5a09 100644 (file)
@@ -382,6 +382,14 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
                },
        },
+       {
+               .ident = "Acer Aspire 5536",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"),
+                       DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
+               },
+       },
        { }
 };
 
index a9d5031b855e5b3c529cbd5e8b8589cf46fcebab..ea30c983a33efdbd6469cbd2fbc07fe308ade8fe 100644 (file)
@@ -388,6 +388,32 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
        return result;
 }
 
+static int wacom_query_tablet_data(struct usb_interface *intf)
+{
+       unsigned char *rep_data;
+       int limit = 0;
+       int error;
+
+       rep_data = kmalloc(2, GFP_KERNEL);
+       if (!rep_data)
+               return -ENOMEM;
+
+       do {
+               rep_data[0] = 2;
+               rep_data[1] = 2;
+               error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
+                                       2, rep_data, 2);
+               if (error >= 0)
+                       error = usb_get_report(intf,
+                                               WAC_HID_FEATURE_REPORT, 2,
+                                               rep_data, 2);
+       } while ((error < 0 || rep_data[1] != 2) && limit++ < 5);
+
+       kfree(rep_data);
+
+       return error < 0 ? error : 0;
+}
+
 static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
        struct usb_device *dev = interface_to_usbdev(intf);
@@ -398,7 +424,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
        struct wacom_features *features;
        struct input_dev *input_dev;
        int error = -ENOMEM;
-       char rep_data[2], limit = 0;
        struct hid_descriptor *hid_desc;
 
        wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
@@ -489,20 +514,10 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
 
        /*
         * Ask the tablet to report tablet data if it is not a Tablet PC.
-        * Repeat until it succeeds
+        * Note that if query fails it is not a hard failure.
         */
-       if (wacom_wac->features->type != TABLETPC) {
-               do {
-                       rep_data[0] = 2;
-                       rep_data[1] = 2;
-                       error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
-                                               2, rep_data, 2);
-                       if (error >= 0)
-                               error = usb_get_report(intf,
-                                               WAC_HID_FEATURE_REPORT, 2,
-                                               rep_data, 2);
-               } while ((error < 0 || rep_data[1] != 2) && limit++ < 5);
-       }
+       if (wacom_wac->features->type != TABLETPC)
+               wacom_query_tablet_data(intf);
 
        usb_set_intfdata(intf, wacom);
        return 0;
index 6954f55001080d29b337a37c9398b6c8f867ec1a..3a7a58222f836ed5c9aea5022a1196482c7ee355 100644 (file)
@@ -170,11 +170,11 @@ static void ucb1400_handle_pending_irq(struct ucb1400_ts *ucb)
        ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, isr);
        ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);
 
-       if (isr & UCB_IE_TSPX) {
+       if (isr & UCB_IE_TSPX)
                ucb1400_ts_irq_disable(ucb->ac97);
-               enable_irq(ucb->irq);
-       } else
-               printk(KERN_ERR "ucb1400: unexpected IE_STATUS = %#x\n", isr);
+       else
+               dev_dbg(&ucb->ts_idev->dev, "ucb1400: unexpected IE_STATUS = %#x\n", isr);
+       enable_irq(ucb->irq);
 }
 
 static int ucb1400_ts_thread(void *_ucb)
@@ -345,6 +345,7 @@ static int ucb1400_ts_detect_irq(struct ucb1400_ts *ucb)
 static int ucb1400_ts_probe(struct platform_device *dev)
 {
        int error, x_res, y_res;
+       u16 fcsr;
        struct ucb1400_ts *ucb = dev->dev.platform_data;
 
        ucb->ts_idev = input_allocate_device();
@@ -382,6 +383,14 @@ static int ucb1400_ts_probe(struct platform_device *dev)
        ucb->ts_idev->evbit[0]          = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
        ucb->ts_idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
+       /*
+        * Enable ADC filter to prevent horrible jitter on Colibri.
+        * This also further reduces jitter on boards where ADCSYNC
+        * pin is connected.
+        */
+       fcsr = ucb1400_reg_read(ucb->ac97, UCB_FCSR);
+       ucb1400_reg_write(ucb->ac97, UCB_FCSR, fcsr | UCB_FCSR_AVE);
+
        ucb1400_adc_enable(ucb->ac97);
        x_res = ucb1400_ts_read_xres(ucb);
        y_res = ucb1400_ts_read_yres(ucb);
index a247ae63374f161973785a3cb3675b082947cbec..1bc5db4ece0d951e202868a8cc539a34093d5cda 100644 (file)
@@ -117,6 +117,9 @@ static ssize_t gpio_trig_inverted_store(struct device *dev,
 
        gpio_data->inverted = !!inverted;
 
+       /* After inverting, we need to update the LED. */
+       schedule_work(&gpio_data->work);
+
        return n;
 }
 static DEVICE_ATTR(inverted, 0644, gpio_trig_inverted_show,
@@ -146,20 +149,26 @@ static ssize_t gpio_trig_gpio_store(struct device *dev,
                return -EINVAL;
        }
 
+       if (gpio_data->gpio == gpio)
+               return n;
+
        if (!gpio) {
-               free_irq(gpio_to_irq(gpio_data->gpio), led);
+               if (gpio_data->gpio != 0)
+                       free_irq(gpio_to_irq(gpio_data->gpio), led);
+               gpio_data->gpio = 0;
                return n;
        }
 
-       if (gpio_data->gpio > 0 && gpio_data->gpio != gpio)
-               free_irq(gpio_to_irq(gpio_data->gpio), led);
-
-       gpio_data->gpio = gpio;
        ret = request_irq(gpio_to_irq(gpio), gpio_trig_irq,
                        IRQF_SHARED | IRQF_TRIGGER_RISING
                        | IRQF_TRIGGER_FALLING, "ledtrig-gpio", led);
-       if (ret)
+       if (ret) {
                dev_err(dev, "request_irq failed with error %d\n", ret);
+       } else {
+               if (gpio_data->gpio != 0)
+                       free_irq(gpio_to_irq(gpio_data->gpio), led);
+               gpio_data->gpio = gpio;
+       }
 
        return ret ? ret : n;
 }
@@ -211,7 +220,8 @@ static void gpio_trig_deactivate(struct led_classdev *led)
                device_remove_file(led->dev, &dev_attr_inverted);
                device_remove_file(led->dev, &dev_attr_desired_brightness);
                flush_work(&gpio_data->work);
-               free_irq(gpio_to_irq(gpio_data->gpio),led);
+               if (gpio_data->gpio != 0)
+                       free_irq(gpio_to_irq(gpio_data->gpio), led);
                kfree(gpio_data);
        }
 }
index 4d686c0bdea0f196db01d170a3d287f1e1b6a7d0..9ab5b0c34f0d0e8ff5f759c1e59dfea3948e674a 100644 (file)
@@ -288,7 +288,7 @@ static void maciisi_sync(struct adb_request *req)
        }
        /* This could be BAD... when the ADB controller doesn't respond
         * for this long, it's probably not coming back :-( */
-       if(count >= 50) /* Hopefully shouldn't happen */
+       if (count > 50) /* Hopefully shouldn't happen */
                printk(KERN_ERR "maciisi_send_request: poll timed out!\n");
 }
 
index 3710ff88fc1018a093fafcdd54777a6b9f630b14..556acff3952fe450e73e4673f46bcac84b453a47 100644 (file)
@@ -171,6 +171,14 @@ static int set_chunk_size(struct dm_exception_store *store,
         */
        chunk_size_ulong = round_up(chunk_size_ulong, PAGE_SIZE >> 9);
 
+       return dm_exception_store_set_chunk_size(store, chunk_size_ulong,
+                                                error);
+}
+
+int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
+                                     unsigned long chunk_size_ulong,
+                                     char **error)
+{
        /* Check chunk_size is a power of 2 */
        if (!is_power_of_2(chunk_size_ulong)) {
                *error = "Chunk size is not a power of 2";
@@ -183,6 +191,11 @@ static int set_chunk_size(struct dm_exception_store *store,
                return -EINVAL;
        }
 
+       if (chunk_size_ulong > INT_MAX >> SECTOR_SHIFT) {
+               *error = "Chunk size is too high";
+               return -EINVAL;
+       }
+
        store->chunk_size = chunk_size_ulong;
        store->chunk_mask = chunk_size_ulong - 1;
        store->chunk_shift = ffs(chunk_size_ulong) - 1;
index 2442c8c0789808607089722a2157ca94f4176c92..812c71872ba093643ba9a5e603fff2d22e4177fb 100644 (file)
@@ -168,6 +168,10 @@ static inline chunk_t sector_to_chunk(struct dm_exception_store *store,
 int dm_exception_store_type_register(struct dm_exception_store_type *type);
 int dm_exception_store_type_unregister(struct dm_exception_store_type *type);
 
+int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
+                                     unsigned long chunk_size_ulong,
+                                     char **error);
+
 int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
                              unsigned *args_used,
                              struct dm_exception_store **store);
index e69b96560997ee2dfd34236e8c1143d395f7550e..6e186b1a062d39bbf020788483c2d1bde85541a2 100644 (file)
@@ -21,6 +21,7 @@ struct log_c {
        struct dm_target *ti;
        uint32_t region_size;
        region_t region_count;
+       uint64_t luid;
        char uuid[DM_UUID_LEN];
 
        char *usr_argv_str;
@@ -63,7 +64,7 @@ static int userspace_do_request(struct log_c *lc, const char *uuid,
         * restored.
         */
 retry:
-       r = dm_consult_userspace(uuid, request_type, data,
+       r = dm_consult_userspace(uuid, lc->luid, request_type, data,
                                 data_size, rdata, rdata_size);
 
        if (r != -ESRCH)
@@ -74,14 +75,15 @@ retry:
                set_current_state(TASK_INTERRUPTIBLE);
                schedule_timeout(2*HZ);
                DMWARN("Attempting to contact userspace log server...");
-               r = dm_consult_userspace(uuid, DM_ULOG_CTR, lc->usr_argv_str,
+               r = dm_consult_userspace(uuid, lc->luid, DM_ULOG_CTR,
+                                        lc->usr_argv_str,
                                         strlen(lc->usr_argv_str) + 1,
                                         NULL, NULL);
                if (!r)
                        break;
        }
        DMINFO("Reconnected to userspace log server... DM_ULOG_CTR complete");
-       r = dm_consult_userspace(uuid, DM_ULOG_RESUME, NULL,
+       r = dm_consult_userspace(uuid, lc->luid, DM_ULOG_RESUME, NULL,
                                 0, NULL, NULL);
        if (!r)
                goto retry;
@@ -111,10 +113,9 @@ static int build_constructor_string(struct dm_target *ti,
                return -ENOMEM;
        }
 
-       for (i = 0, str_size = 0; i < argc; i++)
-               str_size += sprintf(str + str_size, "%s ", argv[i]);
-       str_size += sprintf(str + str_size, "%llu",
-                           (unsigned long long)ti->len);
+       str_size = sprintf(str, "%llu", (unsigned long long)ti->len);
+       for (i = 0; i < argc; i++)
+               str_size += sprintf(str + str_size, " %s", argv[i]);
 
        *ctr_str = str;
        return str_size;
@@ -154,6 +155,9 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
                return -ENOMEM;
        }
 
+       /* The ptr value is sufficient for local unique id */
+       lc->luid = (uint64_t)lc;
+
        lc->ti = ti;
 
        if (strlen(argv[0]) > (DM_UUID_LEN - 1)) {
@@ -173,7 +177,7 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
        }
 
        /* Send table string */
-       r = dm_consult_userspace(lc->uuid, DM_ULOG_CTR,
+       r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_CTR,
                                 ctr_str, str_size, NULL, NULL);
 
        if (r == -ESRCH) {
@@ -183,7 +187,7 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
 
        /* Since the region size does not change, get it now */
        rdata_size = sizeof(rdata);
-       r = dm_consult_userspace(lc->uuid, DM_ULOG_GET_REGION_SIZE,
+       r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_GET_REGION_SIZE,
                                 NULL, 0, (char *)&rdata, &rdata_size);
 
        if (r) {
@@ -212,7 +216,7 @@ static void userspace_dtr(struct dm_dirty_log *log)
        int r;
        struct log_c *lc = log->context;
 
-       r = dm_consult_userspace(lc->uuid, DM_ULOG_DTR,
+       r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_DTR,
                                 NULL, 0,
                                 NULL, NULL);
 
@@ -227,7 +231,7 @@ static int userspace_presuspend(struct dm_dirty_log *log)
        int r;
        struct log_c *lc = log->context;
 
-       r = dm_consult_userspace(lc->uuid, DM_ULOG_PRESUSPEND,
+       r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_PRESUSPEND,
                                 NULL, 0,
                                 NULL, NULL);
 
@@ -239,7 +243,7 @@ static int userspace_postsuspend(struct dm_dirty_log *log)
        int r;
        struct log_c *lc = log->context;
 
-       r = dm_consult_userspace(lc->uuid, DM_ULOG_POSTSUSPEND,
+       r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_POSTSUSPEND,
                                 NULL, 0,
                                 NULL, NULL);
 
@@ -252,7 +256,7 @@ static int userspace_resume(struct dm_dirty_log *log)
        struct log_c *lc = log->context;
 
        lc->in_sync_hint = 0;
-       r = dm_consult_userspace(lc->uuid, DM_ULOG_RESUME,
+       r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_RESUME,
                                 NULL, 0,
                                 NULL, NULL);
 
@@ -561,6 +565,7 @@ static int userspace_status(struct dm_dirty_log *log, status_type_t status_type,
                            char *result, unsigned maxlen)
 {
        int r = 0;
+       char *table_args;
        size_t sz = (size_t)maxlen;
        struct log_c *lc = log->context;
 
@@ -577,8 +582,12 @@ static int userspace_status(struct dm_dirty_log *log, status_type_t status_type,
                break;
        case STATUSTYPE_TABLE:
                sz = 0;
-               DMEMIT("%s %u %s %s", log->type->name, lc->usr_argc + 1,
-                      lc->uuid, lc->usr_argv_str);
+               table_args = strstr(lc->usr_argv_str, " ");
+               BUG_ON(!table_args); /* There will always be a ' ' */
+               table_args++;
+
+               DMEMIT("%s %u %s %s ", log->type->name, lc->usr_argc,
+                      lc->uuid, table_args);
                break;
        }
        return (r) ? 0 : (int)sz;
index 8ce74d95ae4d9b9a47e8fa5a1389e87d71f46b0d..ba0edad2d048017bd08257f0c7b34eb9f86bf1ea 100644 (file)
@@ -147,7 +147,8 @@ static void cn_ulog_callback(void *data)
 
 /**
  * dm_consult_userspace
- * @uuid: log's uuid (must be DM_UUID_LEN in size)
+ * @uuid: log's universal unique identifier (must be DM_UUID_LEN in size)
+ * @luid: log's local unique identifier
  * @request_type:  found in include/linux/dm-log-userspace.h
  * @data: data to tx to the server
  * @data_size: size of data in bytes
@@ -163,7 +164,7 @@ static void cn_ulog_callback(void *data)
  *
  * Returns: 0 on success, -EXXX on failure
  **/
-int dm_consult_userspace(const char *uuid, int request_type,
+int dm_consult_userspace(const char *uuid, uint64_t luid, int request_type,
                         char *data, size_t data_size,
                         char *rdata, size_t *rdata_size)
 {
@@ -190,6 +191,7 @@ resend:
 
        memset(tfr, 0, DM_ULOG_PREALLOCED_SIZE - overhead_size);
        memcpy(tfr->uuid, uuid, DM_UUID_LEN);
+       tfr->luid = luid;
        tfr->seq = dm_ulog_seq++;
 
        /*
index c26d8e4e2710b2dcd861d715b498bdbe32f5e962..04ee874f9153e73bdc2e2192840f2e9b36c883d2 100644 (file)
@@ -11,7 +11,7 @@
 
 int dm_ulog_tfr_init(void);
 void dm_ulog_tfr_exit(void);
-int dm_consult_userspace(const char *uuid, int request_type,
+int dm_consult_userspace(const char *uuid, uint64_t luid, int request_type,
                         char *data, size_t data_size,
                         char *rdata, size_t *rdata_size);
 
index 9726577cde493f2ca21b7fd28386d1d2a31c8786..33f179e66bf55ab5d99d3c3fee3b4d02ab475c1f 100644 (file)
@@ -648,7 +648,13 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
         */
        dm_rh_inc_pending(ms->rh, &sync);
        dm_rh_inc_pending(ms->rh, &nosync);
-       ms->log_failure = dm_rh_flush(ms->rh) ? 1 : 0;
+
+       /*
+        * If the flush fails on a previous call and succeeds here,
+        * we must not reset the log_failure variable.  We need
+        * userspace interaction to do that.
+        */
+       ms->log_failure = dm_rh_flush(ms->rh) ? 1 : ms->log_failure;
 
        /*
         * Dispatch io.
index 6e3fe4f14934811ddd0f9bba845ebdd4bb504036..d5b2e08750d59d6574884c66424916d3d3d6f6ff 100644 (file)
@@ -105,6 +105,13 @@ struct pstore {
         */
        void *zero_area;
 
+       /*
+        * An area used for header. The header can be written
+        * concurrently with metadata (when invalidating the snapshot),
+        * so it needs a separate buffer.
+        */
+       void *header_area;
+
        /*
         * Used to keep track of which metadata area the data in
         * 'chunk' refers to.
@@ -148,16 +155,27 @@ static int alloc_area(struct pstore *ps)
         */
        ps->area = vmalloc(len);
        if (!ps->area)
-               return r;
+               goto err_area;
 
        ps->zero_area = vmalloc(len);
-       if (!ps->zero_area) {
-               vfree(ps->area);
-               return r;
-       }
+       if (!ps->zero_area)
+               goto err_zero_area;
        memset(ps->zero_area, 0, len);
 
+       ps->header_area = vmalloc(len);
+       if (!ps->header_area)
+               goto err_header_area;
+
        return 0;
+
+err_header_area:
+       vfree(ps->zero_area);
+
+err_zero_area:
+       vfree(ps->area);
+
+err_area:
+       return r;
 }
 
 static void free_area(struct pstore *ps)
@@ -169,6 +187,10 @@ static void free_area(struct pstore *ps)
        if (ps->zero_area)
                vfree(ps->zero_area);
        ps->zero_area = NULL;
+
+       if (ps->header_area)
+               vfree(ps->header_area);
+       ps->header_area = NULL;
 }
 
 struct mdata_req {
@@ -188,7 +210,8 @@ static void do_metadata(struct work_struct *work)
 /*
  * Read or write a chunk aligned and sized block of data from a device.
  */
-static int chunk_io(struct pstore *ps, chunk_t chunk, int rw, int metadata)
+static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, int rw,
+                   int metadata)
 {
        struct dm_io_region where = {
                .bdev = ps->store->cow->bdev,
@@ -198,7 +221,7 @@ static int chunk_io(struct pstore *ps, chunk_t chunk, int rw, int metadata)
        struct dm_io_request io_req = {
                .bi_rw = rw,
                .mem.type = DM_IO_VMA,
-               .mem.ptr.vma = ps->area,
+               .mem.ptr.vma = area,
                .client = ps->io_client,
                .notify.fn = NULL,
        };
@@ -240,7 +263,7 @@ static int area_io(struct pstore *ps, int rw)
 
        chunk = area_location(ps, ps->current_area);
 
-       r = chunk_io(ps, chunk, rw, 0);
+       r = chunk_io(ps, ps->area, chunk, rw, 0);
        if (r)
                return r;
 
@@ -254,20 +277,7 @@ static void zero_memory_area(struct pstore *ps)
 
 static int zero_disk_area(struct pstore *ps, chunk_t area)
 {
-       struct dm_io_region where = {
-               .bdev = ps->store->cow->bdev,
-               .sector = ps->store->chunk_size * area_location(ps, area),
-               .count = ps->store->chunk_size,
-       };
-       struct dm_io_request io_req = {
-               .bi_rw = WRITE,
-               .mem.type = DM_IO_VMA,
-               .mem.ptr.vma = ps->zero_area,
-               .client = ps->io_client,
-               .notify.fn = NULL,
-       };
-
-       return dm_io(&io_req, 1, &where, NULL);
+       return chunk_io(ps, ps->zero_area, area_location(ps, area), WRITE, 0);
 }
 
 static int read_header(struct pstore *ps, int *new_snapshot)
@@ -276,6 +286,7 @@ static int read_header(struct pstore *ps, int *new_snapshot)
        struct disk_header *dh;
        chunk_t chunk_size;
        int chunk_size_supplied = 1;
+       char *chunk_err;
 
        /*
         * Use default chunk size (or hardsect_size, if larger) if none supplied
@@ -297,11 +308,11 @@ static int read_header(struct pstore *ps, int *new_snapshot)
        if (r)
                return r;
 
-       r = chunk_io(ps, 0, READ, 1);
+       r = chunk_io(ps, ps->header_area, 0, READ, 1);
        if (r)
                goto bad;
 
-       dh = (struct disk_header *) ps->area;
+       dh = ps->header_area;
 
        if (le32_to_cpu(dh->magic) == 0) {
                *new_snapshot = 1;
@@ -319,20 +330,25 @@ static int read_header(struct pstore *ps, int *new_snapshot)
        ps->version = le32_to_cpu(dh->version);
        chunk_size = le32_to_cpu(dh->chunk_size);
 
-       if (!chunk_size_supplied || ps->store->chunk_size == chunk_size)
+       if (ps->store->chunk_size == chunk_size)
                return 0;
 
-       DMWARN("chunk size %llu in device metadata overrides "
-              "table chunk size of %llu.",
-              (unsigned long long)chunk_size,
-              (unsigned long long)ps->store->chunk_size);
+       if (chunk_size_supplied)
+               DMWARN("chunk size %llu in device metadata overrides "
+                      "table chunk size of %llu.",
+                      (unsigned long long)chunk_size,
+                      (unsigned long long)ps->store->chunk_size);
 
        /* We had a bogus chunk_size. Fix stuff up. */
        free_area(ps);
 
-       ps->store->chunk_size = chunk_size;
-       ps->store->chunk_mask = chunk_size - 1;
-       ps->store->chunk_shift = ffs(chunk_size) - 1;
+       r = dm_exception_store_set_chunk_size(ps->store, chunk_size,
+                                             &chunk_err);
+       if (r) {
+               DMERR("invalid on-disk chunk size %llu: %s.",
+                     (unsigned long long)chunk_size, chunk_err);
+               return r;
+       }
 
        r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size),
                                ps->io_client);
@@ -351,15 +367,15 @@ static int write_header(struct pstore *ps)
 {
        struct disk_header *dh;
 
-       memset(ps->area, 0, ps->store->chunk_size << SECTOR_SHIFT);
+       memset(ps->header_area, 0, ps->store->chunk_size << SECTOR_SHIFT);
 
-       dh = (struct disk_header *) ps->area;
+       dh = ps->header_area;
        dh->magic = cpu_to_le32(SNAP_MAGIC);
        dh->valid = cpu_to_le32(ps->valid);
        dh->version = cpu_to_le32(ps->version);
        dh->chunk_size = cpu_to_le32(ps->store->chunk_size);
 
-       return chunk_io(ps, 0, WRITE, 1);
+       return chunk_io(ps, ps->header_area, 0, WRITE, 1);
 }
 
 /*
@@ -679,6 +695,8 @@ static int persistent_ctr(struct dm_exception_store *store,
        ps->valid = 1;
        ps->version = SNAPSHOT_DISK_VERSION;
        ps->area = NULL;
+       ps->zero_area = NULL;
+       ps->header_area = NULL;
        ps->next_free = 2;      /* skipping the header and first area */
        ps->current_committed = 0;
 
index d573165cd2b788968f7d274e03966b96c93da889..57f1bf7f3b7a1d4ffd18f51563a2d5c52b0693ad 100644 (file)
@@ -1176,6 +1176,15 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
        return 0;
 }
 
+static int snapshot_iterate_devices(struct dm_target *ti,
+                                   iterate_devices_callout_fn fn, void *data)
+{
+       struct dm_snapshot *snap = ti->private;
+
+       return fn(ti, snap->origin, 0, ti->len, data);
+}
+
+
 /*-----------------------------------------------------------------
  * Origin methods
  *---------------------------------------------------------------*/
@@ -1410,20 +1419,29 @@ static int origin_status(struct dm_target *ti, status_type_t type, char *result,
        return 0;
 }
 
+static int origin_iterate_devices(struct dm_target *ti,
+                                 iterate_devices_callout_fn fn, void *data)
+{
+       struct dm_dev *dev = ti->private;
+
+       return fn(ti, dev, 0, ti->len, data);
+}
+
 static struct target_type origin_target = {
        .name    = "snapshot-origin",
-       .version = {1, 6, 0},
+       .version = {1, 7, 0},
        .module  = THIS_MODULE,
        .ctr     = origin_ctr,
        .dtr     = origin_dtr,
        .map     = origin_map,
        .resume  = origin_resume,
        .status  = origin_status,
+       .iterate_devices = origin_iterate_devices,
 };
 
 static struct target_type snapshot_target = {
        .name    = "snapshot",
-       .version = {1, 6, 0},
+       .version = {1, 7, 0},
        .module  = THIS_MODULE,
        .ctr     = snapshot_ctr,
        .dtr     = snapshot_dtr,
@@ -1431,6 +1449,7 @@ static struct target_type snapshot_target = {
        .end_io  = snapshot_end_io,
        .resume  = snapshot_resume,
        .status  = snapshot_status,
+       .iterate_devices = snapshot_iterate_devices,
 };
 
 static int __init dm_snapshot_init(void)
index 4e0e5937e42afc6f35274fc8856c3a8190cd1c20..3e563d251733439a2431b27c6b893299e67b46c3 100644 (file)
@@ -329,9 +329,19 @@ static int stripe_iterate_devices(struct dm_target *ti,
        return ret;
 }
 
+static void stripe_io_hints(struct dm_target *ti,
+                           struct queue_limits *limits)
+{
+       struct stripe_c *sc = ti->private;
+       unsigned chunk_size = (sc->chunk_mask + 1) << 9;
+
+       blk_limits_io_min(limits, chunk_size);
+       limits->io_opt = chunk_size * sc->stripes;
+}
+
 static struct target_type stripe_target = {
        .name   = "striped",
-       .version = {1, 2, 0},
+       .version = {1, 3, 0},
        .module = THIS_MODULE,
        .ctr    = stripe_ctr,
        .dtr    = stripe_dtr,
@@ -339,6 +349,7 @@ static struct target_type stripe_target = {
        .end_io = stripe_end_io,
        .status = stripe_status,
        .iterate_devices = stripe_iterate_devices,
+       .io_hints = stripe_io_hints,
 };
 
 int __init dm_stripe_init(void)
index d952b3441913a74b15c09f6ba7ea6237bd1e8aa0..1a6cb3c7822ed96c6c0b2eaa764522c5f0e7ae89 100644 (file)
@@ -343,10 +343,10 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md)
 }
 
 /*
- * If possible, this checks an area of a destination device is valid.
+ * If possible, this checks an area of a destination device is invalid.
  */
-static int device_area_is_valid(struct dm_target *ti, struct dm_dev *dev,
-                               sector_t start, sector_t len, void *data)
+static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev,
+                                 sector_t start, sector_t len, void *data)
 {
        struct queue_limits *limits = data;
        struct block_device *bdev = dev->bdev;
@@ -357,36 +357,40 @@ static int device_area_is_valid(struct dm_target *ti, struct dm_dev *dev,
        char b[BDEVNAME_SIZE];
 
        if (!dev_size)
-               return 1;
+               return 0;
 
        if ((start >= dev_size) || (start + len > dev_size)) {
-               DMWARN("%s: %s too small for target",
-                      dm_device_name(ti->table->md), bdevname(bdev, b));
-               return 0;
+               DMWARN("%s: %s too small for target: "
+                      "start=%llu, len=%llu, dev_size=%llu",
+                      dm_device_name(ti->table->md), bdevname(bdev, b),
+                      (unsigned long long)start,
+                      (unsigned long long)len,
+                      (unsigned long long)dev_size);
+               return 1;
        }
 
        if (logical_block_size_sectors <= 1)
-               return 1;
+               return 0;
 
        if (start & (logical_block_size_sectors - 1)) {
                DMWARN("%s: start=%llu not aligned to h/w "
-                      "logical block size %hu of %s",
+                      "logical block size %u of %s",
                       dm_device_name(ti->table->md),
                       (unsigned long long)start,
                       limits->logical_block_size, bdevname(bdev, b));
-               return 0;
+               return 1;
        }
 
        if (len & (logical_block_size_sectors - 1)) {
                DMWARN("%s: len=%llu not aligned to h/w "
-                      "logical block size %hu of %s",
+                      "logical block size %u of %s",
                       dm_device_name(ti->table->md),
                       (unsigned long long)len,
                       limits->logical_block_size, bdevname(bdev, b));
-               return 0;
+               return 1;
        }
 
-       return 1;
+       return 0;
 }
 
 /*
@@ -496,8 +500,15 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev,
        }
 
        if (blk_stack_limits(limits, &q->limits, start << 9) < 0)
-               DMWARN("%s: target device %s is misaligned",
-                      dm_device_name(ti->table->md), bdevname(bdev, b));
+               DMWARN("%s: target device %s is misaligned: "
+                      "physical_block_size=%u, logical_block_size=%u, "
+                      "alignment_offset=%u, start=%llu",
+                      dm_device_name(ti->table->md), bdevname(bdev, b),
+                      q->limits.physical_block_size,
+                      q->limits.logical_block_size,
+                      q->limits.alignment_offset,
+                      (unsigned long long) start << 9);
+
 
        /*
         * Check if merge fn is supported.
@@ -698,7 +709,7 @@ static int validate_hardware_logical_block_alignment(struct dm_table *table,
 
        if (remaining) {
                DMWARN("%s: table line %u (start sect %llu len %llu) "
-                      "not aligned to h/w logical block size %hu",
+                      "not aligned to h/w logical block size %u",
                       dm_device_name(table->md), i,
                       (unsigned long long) ti->begin,
                       (unsigned long long) ti->len,
@@ -996,12 +1007,16 @@ int dm_calculate_queue_limits(struct dm_table *table,
                ti->type->iterate_devices(ti, dm_set_device_limits,
                                          &ti_limits);
 
+               /* Set I/O hints portion of queue limits */
+               if (ti->type->io_hints)
+                       ti->type->io_hints(ti, &ti_limits);
+
                /*
                 * Check each device area is consistent with the target's
                 * overall queue limits.
                 */
-               if (!ti->type->iterate_devices(ti, device_area_is_valid,
-                                              &ti_limits))
+               if (ti->type->iterate_devices(ti, device_area_is_invalid,
+                                             &ti_limits))
                        return -EINVAL;
 
 combine_limits:
index 8a311ea0d441faad7b5fdf2d0ce9a34a3d01983d..b4845b14740d6f2bb43470d7fe5f35eaf3864d07 100644 (file)
@@ -738,16 +738,22 @@ static void rq_completed(struct mapped_device *md, int run_queue)
        dm_put(md);
 }
 
+static void free_rq_clone(struct request *clone)
+{
+       struct dm_rq_target_io *tio = clone->end_io_data;
+
+       blk_rq_unprep_clone(clone);
+       free_rq_tio(tio);
+}
+
 static void dm_unprep_request(struct request *rq)
 {
        struct request *clone = rq->special;
-       struct dm_rq_target_io *tio = clone->end_io_data;
 
        rq->special = NULL;
        rq->cmd_flags &= ~REQ_DONTPREP;
 
-       blk_rq_unprep_clone(clone);
-       free_rq_tio(tio);
+       free_rq_clone(clone);
 }
 
 /*
@@ -825,8 +831,7 @@ static void dm_end_request(struct request *clone, int error)
                        rq->sense_len = clone->sense_len;
        }
 
-       BUG_ON(clone->bio);
-       free_rq_tio(tio);
+       free_rq_clone(clone);
 
        blk_end_request_all(rq, error);
 
index 88847d1dcbb5187ff3e0f645f51b2bc3534719f7..8c1aed77ea30b9af7c281b13d079d30923fe7350 100644 (file)
@@ -2,25 +2,33 @@
 # Siano Mobile Silicon Digital TV device configuration
 #
 
-config DVB_SIANO_SMS1XXX
-       tristate "Siano SMS1XXX USB dongle support"
-       depends on DVB_CORE && USB && INPUT
+config SMS_SIANO_MDTV
+       tristate "Siano SMS1xxx based MDTV receiver"
+       depends on DVB_CORE && INPUT
        ---help---
-         Choose Y here if you have a USB dongle with a SMS1XXX chipset.
+         Choose Y or M here if you have MDTV receiver with a Siano chipset.
 
-         To compile this driver as a module, choose M here: the
-         module will be called sms1xxx.
+         To compile this driver as a module, choose M here
+         (The module will be called smsmdtv).
 
-config DVB_SIANO_SMS1XXX_SMS_IDS
-       bool "Enable support for Siano Mobile Silicon default USB IDs"
-       depends on DVB_SIANO_SMS1XXX
-       default y
-       ---help---
-         Choose Y here if you have a USB dongle with a SMS1XXX chipset
-         that uses Siano Mobile Silicon's default usb vid:pid.
+         Further documentation on this driver can be found on the WWW
+         at http://www.siano-ms.com/
+
+if SMS_SIANO_MDTV
+menu "Siano module components"
 
-         Choose N here if you would prefer to use Siano's external driver.
+# Hardware interfaces support
 
-         Further documentation on this driver can be found on the WWW at
-         <http://www.siano-ms.com/>.
+config SMS_USB_DRV
+       tristate "USB interface support"
+       depends on DVB_CORE && USB
+       ---help---
+         Choose if you would like to have Siano's support for USB interface
 
+config SMS_SDIO_DRV
+       tristate "SDIO interface support"
+       depends on DVB_CORE && MMC
+       ---help---
+         Choose if you would like to have Siano's support for SDIO interface
+endmenu
+endif # SMS_SIANO_MDTV
index c6644d9094338ef252c2ca98ae4fd179199c67d7..c54140b5ab5a11e7defb883e3cda4e73d8b0406d 100644 (file)
@@ -1,8 +1,9 @@
-sms1xxx-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o
 
-obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o
-obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o
-obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsdvb.o
+smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o
+
+obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o
+obj-$(CONFIG_SMS_USB_DRV) += smsusb.o
+obj-$(CONFIG_SMS_SDIO_DRV) += smssdio.o
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 
index 3ee1c3902c56dcc9d56a26380e5dadb07459cd99..266033ae2784ebd5568ab33e6e7a4318add7e234 100644 (file)
@@ -325,6 +325,16 @@ static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
                                                0 : -ETIME;
 }
 
+static inline int led_feedback(struct smsdvb_client_t *client)
+{
+       if (client->fe_status & FE_HAS_LOCK)
+               return sms_board_led_feedback(client->coredev,
+                       (client->sms_stat_dvb.ReceptionData.BER
+                       == 0) ? SMS_LED_HI : SMS_LED_LO);
+       else
+               return sms_board_led_feedback(client->coredev, SMS_LED_OFF);
+}
+
 static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
 {
        struct smsdvb_client_t *client;
@@ -332,6 +342,8 @@ static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
 
        *stat = client->fe_status;
 
+       led_feedback(client);
+
        return 0;
 }
 
@@ -342,6 +354,8 @@ static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
 
        *ber = client->sms_stat_dvb.ReceptionData.BER;
 
+       led_feedback(client);
+
        return 0;
 }
 
@@ -359,6 +373,8 @@ static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
                                (client->sms_stat_dvb.ReceptionData.InBandPwr
                                + 95) * 3 / 2;
 
+       led_feedback(client);
+
        return 0;
 }
 
@@ -369,6 +385,8 @@ static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
 
        *snr = client->sms_stat_dvb.ReceptionData.SNR;
 
+       led_feedback(client);
+
        return 0;
 }
 
@@ -379,6 +397,8 @@ static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 
        *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets;
 
+       led_feedback(client);
+
        return 0;
 }
 
@@ -404,6 +424,8 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
                u32             Data[3];
        } Msg;
 
+       int ret;
+
        client->fe_status = FE_HAS_SIGNAL;
        client->event_fe_state = -1;
        client->event_unc_state = -1;
@@ -426,6 +448,23 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
        case BANDWIDTH_AUTO: return -EOPNOTSUPP;
        default: return -EINVAL;
        }
+       /* Disable LNA, if any. An error is returned if no LNA is present */
+       ret = sms_board_lna_control(client->coredev, 0);
+       if (ret == 0) {
+               fe_status_t status;
+
+               /* tune with LNA off at first */
+               ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+                                                 &client->tune_done);
+
+               smsdvb_read_status(fe, &status);
+
+               if (status & FE_HAS_LOCK)
+                       return ret;
+
+               /* previous tune didnt lock - enable LNA and tune again */
+               sms_board_lna_control(client->coredev, 1);
+       }
 
        return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
                                           &client->tune_done);
@@ -451,6 +490,8 @@ static int smsdvb_init(struct dvb_frontend *fe)
        struct smsdvb_client_t *client =
                container_of(fe, struct smsdvb_client_t, frontend);
 
+       sms_board_power(client->coredev, 1);
+
        sms_board_dvb3_event(client, DVB3_EVENT_INIT);
        return 0;
 }
@@ -460,6 +501,9 @@ static int smsdvb_sleep(struct dvb_frontend *fe)
        struct smsdvb_client_t *client =
                container_of(fe, struct smsdvb_client_t, frontend);
 
+       sms_board_led_feedback(client->coredev, SMS_LED_OFF);
+       sms_board_power(client->coredev, 0);
+
        sms_board_dvb3_event(client, DVB3_EVENT_SLEEP);
 
        return 0;
index dfaa49a53f325ea917bd72d21fe91cc0a8c80cae..d1d652e7f8905868b27661a60af2f47d87f6ec75 100644 (file)
@@ -46,6 +46,7 @@
 
 #define SMSSDIO_DATA           0x00
 #define SMSSDIO_INT            0x04
+#define SMSSDIO_BLOCK_SIZE     128
 
 static const struct sdio_device_id smssdio_ids[] = {
        {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR),
@@ -85,7 +86,8 @@ static int smssdio_sendrequest(void *context, void *buffer, size_t size)
        sdio_claim_host(smsdev->func);
 
        while (size >= smsdev->func->cur_blksize) {
-               ret = sdio_write_blocks(smsdev->func, SMSSDIO_DATA, buffer, 1);
+               ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
+                                       buffer, smsdev->func->cur_blksize);
                if (ret)
                        goto out;
 
@@ -94,8 +96,8 @@ static int smssdio_sendrequest(void *context, void *buffer, size_t size)
        }
 
        if (size) {
-               ret = sdio_write_bytes(smsdev->func, SMSSDIO_DATA,
-                                      buffer, size);
+               ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
+                                       buffer, size);
        }
 
 out:
@@ -125,23 +127,23 @@ static void smssdio_interrupt(struct sdio_func *func)
         */
        isr = sdio_readb(func, SMSSDIO_INT, &ret);
        if (ret) {
-               dev_err(&smsdev->func->dev,
-                       "Unable to read interrupt register!\n");
+               sms_err("Unable to read interrupt register!\n");
                return;
        }
 
        if (smsdev->split_cb == NULL) {
                cb = smscore_getbuffer(smsdev->coredev);
                if (!cb) {
-                       dev_err(&smsdev->func->dev,
-                               "Unable to allocate data buffer!\n");
+                       sms_err("Unable to allocate data buffer!\n");
                        return;
                }
 
-               ret = sdio_read_blocks(smsdev->func, cb->p, SMSSDIO_DATA, 1);
+               ret = sdio_memcpy_fromio(smsdev->func,
+                                        cb->p,
+                                        SMSSDIO_DATA,
+                                        SMSSDIO_BLOCK_SIZE);
                if (ret) {
-                       dev_err(&smsdev->func->dev,
-                               "Error %d reading initial block!\n", ret);
+                       sms_err("Error %d reading initial block!\n", ret);
                        return;
                }
 
@@ -152,7 +154,10 @@ static void smssdio_interrupt(struct sdio_func *func)
                        return;
                }
 
-               size = hdr->msgLength - smsdev->func->cur_blksize;
+               if (hdr->msgLength > smsdev->func->cur_blksize)
+                       size = hdr->msgLength - smsdev->func->cur_blksize;
+               else
+                       size = 0;
        } else {
                cb = smsdev->split_cb;
                hdr = cb->p;
@@ -162,23 +167,24 @@ static void smssdio_interrupt(struct sdio_func *func)
                smsdev->split_cb = NULL;
        }
 
-       if (hdr->msgLength > smsdev->func->cur_blksize) {
+       if (size) {
                void *buffer;
 
-               size = ALIGN(size, 128);
-               buffer = cb->p + hdr->msgLength;
+               buffer = cb->p + (hdr->msgLength - size);
+               size = ALIGN(size, SMSSDIO_BLOCK_SIZE);
 
-               BUG_ON(smsdev->func->cur_blksize != 128);
+               BUG_ON(smsdev->func->cur_blksize != SMSSDIO_BLOCK_SIZE);
 
                /*
                 * First attempt to transfer all of it in one go...
                 */
-               ret = sdio_read_blocks(smsdev->func, buffer,
-                                      SMSSDIO_DATA, size / 128);
+               ret = sdio_memcpy_fromio(smsdev->func,
+                                        buffer,
+                                        SMSSDIO_DATA,
+                                        size);
                if (ret && ret != -EINVAL) {
                        smscore_putbuffer(smsdev->coredev, cb);
-                       dev_err(&smsdev->func->dev,
-                               "Error %d reading data from card!\n", ret);
+                       sms_err("Error %d reading data from card!\n", ret);
                        return;
                }
 
@@ -191,12 +197,12 @@ static void smssdio_interrupt(struct sdio_func *func)
                 */
                if (ret == -EINVAL) {
                        while (size) {
-                               ret = sdio_read_blocks(smsdev->func,
-                                                      buffer, SMSSDIO_DATA, 1);
+                               ret = sdio_memcpy_fromio(smsdev->func,
+                                                 buffer, SMSSDIO_DATA,
+                                                 smsdev->func->cur_blksize);
                                if (ret) {
                                        smscore_putbuffer(smsdev->coredev, cb);
-                                       dev_err(&smsdev->func->dev,
-                                               "Error %d reading "
+                                       sms_err("Error %d reading "
                                                "data from card!\n", ret);
                                        return;
                                }
@@ -269,7 +275,7 @@ static int smssdio_probe(struct sdio_func *func,
        if (ret)
                goto release;
 
-       ret = sdio_set_block_size(func, 128);
+       ret = sdio_set_block_size(func, SMSSDIO_BLOCK_SIZE);
        if (ret)
                goto disable;
 
index ed281f5659459c20bc571fbfb3ed61e3348590bc..1c2e544eda73594cb362e1afbea1451b4ae94927 100644 (file)
@@ -1730,6 +1730,25 @@ static inline void em28xx_set_model(struct em28xx *dev)
                                       EM28XX_I2C_FREQ_100_KHZ;
 }
 
+
+/* FIXME: Should be replaced by a proper mt9m111 driver */
+static int em28xx_initialize_mt9m111(struct em28xx *dev)
+{
+       int i;
+       unsigned char regs[][3] = {
+               { 0x0d, 0x00, 0x01, },  /* reset and use defaults */
+               { 0x0d, 0x00, 0x00, },
+               { 0x0a, 0x00, 0x21, },
+               { 0x21, 0x04, 0x00, },  /* full readout speed, no row/col skipping */
+       };
+
+       for (i = 0; i < ARRAY_SIZE(regs); i++)
+               i2c_master_send(&dev->i2c_client, &regs[i][0], 3);
+
+       return 0;
+}
+
+
 /* FIXME: Should be replaced by a proper mt9m001 driver */
 static int em28xx_initialize_mt9m001(struct em28xx *dev)
 {
@@ -1758,7 +1777,7 @@ static int em28xx_initialize_mt9m001(struct em28xx *dev)
 
 /* HINT method: webcam I2C chips
  *
- * This method work for webcams with Micron sensors
+ * This method works for webcams with Micron sensors
  */
 static int em28xx_hint_sensor(struct em28xx *dev)
 {
@@ -1804,6 +1823,23 @@ static int em28xx_hint_sensor(struct em28xx *dev)
                dev->vinctl = 0x00;
 
                break;
+
+       case 0x143a:    /* MT9M111 as found in the ECS G200 */
+               dev->model = EM2750_BOARD_UNKNOWN;
+               em28xx_set_model(dev);
+
+               sensor_name = "mt9m111";
+               dev->board.xclk = EM28XX_XCLK_FREQUENCY_48MHZ;
+               dev->em28xx_sensor = EM28XX_MT9M111;
+               em28xx_initialize_mt9m111(dev);
+               dev->sensor_xres = 640;
+               dev->sensor_yres = 512;
+
+               dev->vinmode = 0x0a;
+               dev->vinctl = 0x00;
+
+               break;
+
        case 0x8431:
                dev->model = EM2750_BOARD_UNKNOWN;
                em28xx_set_model(dev);
@@ -1820,7 +1856,7 @@ static int em28xx_hint_sensor(struct em28xx *dev)
 
                break;
        default:
-               printk("Unknown Micron Sensor 0x%04x\n", be16_to_cpu(version));
+               printk("Unknown Micron Sensor 0x%04x\n", version);
                return -EINVAL;
        }
 
@@ -2346,7 +2382,9 @@ void em28xx_card_setup(struct em28xx *dev)
        }
 
        em28xx_tuner_setup(dev);
-       em28xx_ir_init(dev);
+
+       if(!disable_ir)
+               em28xx_ir_init(dev);
 }
 
 
index 8c2dc38bca9ffe8b9a02f7e7af5d5dcc17a9df61..a2add61f7d59dd4555b48b95b81197f337b85951 100644 (file)
@@ -367,6 +367,7 @@ enum em28xx_sensor {
        EM28XX_NOSENSOR = 0,
        EM28XX_MT9V011,
        EM28XX_MT9M001,
+       EM28XX_MT9M111,
 };
 
 enum em28xx_adecoder {
index 34f46f2bc0402af5c375e05432233e8a8553da11..e994dcac43ffb6cfa2481ed4ff9df7aa86235a4b 100644 (file)
@@ -114,7 +114,7 @@ config USB_GSPCA_SN9C20X
 
 config USB_GSPCA_SN9C20X_EVDEV
        bool "Enable evdev support"
-       depends on USB_GSPCA_SN9C20X
+       depends on USB_GSPCA_SN9C20X && INPUT
        ---help---
         Say Y here in order to enable evdev support for sn9c20x webcam button.
 
index fc976f42f4328d70bbccb9a65a1d4bd0b5173cf5..2622a6e63da1ed78b1bcaae07b164a33d13c1e66 100644 (file)
@@ -695,7 +695,7 @@ static int zr364xx_release(struct file *file)
        for (i = 0; i < 2; i++) {
                err =
                    send_control_msg(udev, 1, init[cam->method][i].value,
-                                    0, init[i][cam->method].bytes,
+                                    0, init[cam->method][i].bytes,
                                     init[cam->method][i].size);
                if (err < 0) {
                        dev_err(&udev->dev, "error during release sequence\n");
index ae5fe91867e1530ae9636a73d1a05ccc9892e7f3..10ed195c0c1cd2ff02c4fe767e3d13dd574c84b8 100644 (file)
@@ -736,7 +736,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
                        flash->partitioned = 1;
                        return add_mtd_partitions(&flash->mtd, parts, nr_parts);
                }
-       } else if (data->nr_parts)
+       } else if (data && data->nr_parts)
                dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
                                data->nr_parts, data->name);
 
index 7ad972229db4317153dee8db1a008333e7c019e9..0d9d4bc9c762fe5caeab5770419f14dfe2c81403 100644 (file)
@@ -61,7 +61,7 @@ static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
        buf64 = (uint64_t *)buf;
        while (i < len/8) {
                uint64_t x;
-               asm ("ldrd\t%0, [%1]" : "=r" (x) : "r" (io_base));
+               asm volatile ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base));
                buf64[i++] = x;
        }
        i *= 8;
index fb86cacd5bdb66adf754c8ce6ed940ff89e266a8..1002e18829966256bb77833f67501c6871d7d4ce 100644 (file)
@@ -135,16 +135,17 @@ static void nftl_remove_dev(struct mtd_blktrans_dev *dev)
 int nftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
                  size_t *retlen, uint8_t *buf)
 {
+       loff_t mask = mtd->writesize - 1;
        struct mtd_oob_ops ops;
        int res;
 
        ops.mode = MTD_OOB_PLACE;
-       ops.ooboffs = offs & (mtd->writesize - 1);
+       ops.ooboffs = offs & mask;
        ops.ooblen = len;
        ops.oobbuf = buf;
        ops.datbuf = NULL;
 
-       res = mtd->read_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
+       res = mtd->read_oob(mtd, offs & ~mask, &ops);
        *retlen = ops.oobretlen;
        return res;
 }
@@ -155,16 +156,17 @@ int nftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
 int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
                   size_t *retlen, uint8_t *buf)
 {
+       loff_t mask = mtd->writesize - 1;
        struct mtd_oob_ops ops;
        int res;
 
        ops.mode = MTD_OOB_PLACE;
-       ops.ooboffs = offs & (mtd->writesize - 1);
+       ops.ooboffs = offs & mask;
        ops.ooblen = len;
        ops.oobbuf = buf;
        ops.datbuf = NULL;
 
-       res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
+       res = mtd->write_oob(mtd, offs & ~mask, &ops);
        *retlen = ops.oobretlen;
        return res;
 }
@@ -177,17 +179,18 @@ int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
 static int nftl_write(struct mtd_info *mtd, loff_t offs, size_t len,
                      size_t *retlen, uint8_t *buf, uint8_t *oob)
 {
+       loff_t mask = mtd->writesize - 1;
        struct mtd_oob_ops ops;
        int res;
 
        ops.mode = MTD_OOB_PLACE;
-       ops.ooboffs = offs;
+       ops.ooboffs = offs & mask;
        ops.ooblen = mtd->oobsize;
        ops.oobbuf = oob;
        ops.datbuf = buf;
        ops.len = len;
 
-       res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
+       res = mtd->write_oob(mtd, offs & ~mask, &ops);
        *retlen = ops.retlen;
        return res;
 }
index 5f6509a5f640820fd89b6ef7b8b420a1ab0c8e39..5ce7cbabd7a786cb6297617f765064672a68a918 100644 (file)
@@ -1727,12 +1727,14 @@ config KS8842
        tristate "Micrel KSZ8842"
        depends on HAS_IOMEM
        help
-         This platform driver is for Micrel KSZ8842 chip.
+         This platform driver is for Micrel KSZ8842 / KS8842
+         2-port ethernet switch chip (managed, VLAN, QoS).
 
 config KS8851
        tristate "Micrel KS8851 SPI"
        depends on SPI
        select MII
+       select CRC32
        help
          SPI driver for Micrel KS8851 SPI attached network chip.
 
index 616fb7985a3481e45dd2cd7e875ab24323ac13d8..ddd231cb54b796f3e15a6b04374d027e5fb5a713 100644 (file)
@@ -1080,7 +1080,7 @@ static struct platform_driver w90p910_ether_driver = {
        .probe          = w90p910_ether_probe,
        .remove         = __devexit_p(w90p910_ether_remove),
        .driver         = {
-               .name   = "w90p910-emc",
+               .name   = "nuc900-emc",
                .owner  = THIS_MODULE,
        },
 };
@@ -1101,5 +1101,5 @@ module_exit(w90p910_ether_exit);
 MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
 MODULE_DESCRIPTION("w90p910 MAC driver!");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:w90p910-emc");
+MODULE_ALIAS("platform:nuc900-emc");
 
index 41b648a67fec34d071a5ee681b713e4cada6ee87..3a6735dc9f6a6158bf04196c22c144133de55408 100644 (file)
@@ -1899,7 +1899,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
                                nic->ru_running = RU_SUSPENDED;
                pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr,
                                               sizeof(struct rfd),
-                                              PCI_DMA_BIDIRECTIONAL);
+                                              PCI_DMA_FROMDEVICE);
                return -ENODATA;
        }
 
index cc786333d95c87cd84d34a1b189c43f9b60367c1..c40113f58963f9f765268141db1d78f367125a8c 100644 (file)
@@ -309,6 +309,7 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct mpc52xx_fec_priv *priv = netdev_priv(dev);
        struct bcom_fec_bd *bd;
+       unsigned long flags;
 
        if (bcom_queue_full(priv->tx_dmatsk)) {
                if (net_ratelimit())
@@ -316,7 +317,7 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev)
                return NETDEV_TX_BUSY;
        }
 
-       spin_lock_irq(&priv->lock);
+       spin_lock_irqsave(&priv->lock, flags);
        dev->trans_start = jiffies;
 
        bd = (struct bcom_fec_bd *)
@@ -332,7 +333,7 @@ static int mpc52xx_fec_start_xmit(struct sk_buff *skb, struct net_device *dev)
                netif_stop_queue(dev);
        }
 
-       spin_unlock_irq(&priv->lock);
+       spin_unlock_irqrestore(&priv->lock, flags);
 
        return NETDEV_TX_OK;
 }
index e212f2c5448b13cb40ede8bec2339b28ab64e264..a00ec639c38039ad56f17706a5441cabe2c3fc20 100644 (file)
@@ -491,6 +491,7 @@ static int gfar_remove(struct of_device *ofdev)
 
        dev_set_drvdata(&ofdev->dev, NULL);
 
+       unregister_netdev(priv->ndev);
        iounmap(priv->regs);
        free_netdev(priv->ndev);
 
index beb84213b6719ba614641e56af5862dd5581ad9e..f0f890803710bed42418201bf2bb4fa58f25cb99 100644 (file)
@@ -1305,6 +1305,8 @@ static int emac_close(struct net_device *ndev)
 
        free_irq(dev->emac_irq, dev);
 
+       netif_carrier_off(ndev);
+
        return 0;
 }
 
index c4361d466597c50963c9a0dc594c6cd3b3e41b7e..ee1cff5c9b21cb1918589cbe555d1706402eac60 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
-#include <linux/etherdevice.h>
 #include <linux/slab.h>
 #include <linux/rtnetlink.h>
 #include <linux/interrupt.h>
@@ -205,9 +204,6 @@ static const struct net_device_ops au1k_irda_netdev_ops = {
        .ndo_start_xmit         = au1k_irda_hard_xmit,
        .ndo_tx_timeout         = au1k_tx_timeout,
        .ndo_do_ioctl           = au1k_irda_ioctl,
-       .ndo_change_mtu         = eth_change_mtu,
-       .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_mac_address    = eth_mac_addr,
 };
 
 static int au1k_irda_net_init(struct net_device *dev)
index 3376a4f39e0a1eb02b6287a9355159c3aca7fc0f..77d10edefd2579cd06c7e53f065bdf3dda7a96e7 100644 (file)
@@ -803,9 +803,6 @@ static const struct net_device_ops pxa_irda_netdev_ops = {
        .ndo_stop               = pxa_irda_stop,
        .ndo_start_xmit         = pxa_irda_hard_xmit,
        .ndo_do_ioctl           = pxa_irda_ioctl,
-       .ndo_change_mtu         = eth_change_mtu,
-       .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_mac_address    = eth_mac_addr,
 };
 
 static int pxa_irda_probe(struct platform_device *pdev)
@@ -830,6 +827,7 @@ static int pxa_irda_probe(struct platform_device *pdev)
        if (!dev)
                goto err_mem_3;
 
+       SET_NETDEV_DEV(dev, &pdev->dev);
        si = netdev_priv(dev);
        si->dev = &pdev->dev;
        si->pdata = pdev->dev.platform_data;
index 2aeb2e6aec1bb583e6867d4716f85f5eec3bfa83..b039cb081e943c24ca6ee464c05f9a5b7b6f2c0f 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
-#include <linux/etherdevice.h>
 #include <linux/slab.h>
 #include <linux/rtnetlink.h>
 #include <linux/interrupt.h>
@@ -881,9 +880,6 @@ static const struct net_device_ops sa1100_irda_netdev_ops = {
        .ndo_stop               = sa1100_irda_stop,
        .ndo_start_xmit         = sa1100_irda_hard_xmit,
        .ndo_do_ioctl           = sa1100_irda_ioctl,
-       .ndo_change_mtu         = eth_change_mtu,
-       .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_mac_address    = eth_mac_addr,
 };
 
 static int sa1100_irda_probe(struct platform_device *pdev)
index 2a0174b62e964d613102e0ef14e32828b3b91c34..92fb8235c76689c2ea3b6f1c079a65536bd035a1 100644 (file)
@@ -41,6 +41,7 @@ static int ixpdev_xmit(struct sk_buff *skb, struct net_device *dev)
        struct ixpdev_priv *ip = netdev_priv(dev);
        struct ixpdev_tx_desc *desc;
        int entry;
+       unsigned long flags;
 
        if (unlikely(skb->len > PAGE_SIZE)) {
                /* @@@ Count drops.  */
@@ -63,11 +64,11 @@ static int ixpdev_xmit(struct sk_buff *skb, struct net_device *dev)
 
        dev->trans_start = jiffies;
 
-       local_irq_disable();
+       local_irq_save(flags);
        ip->tx_queue_entries++;
        if (ip->tx_queue_entries == TX_BUF_COUNT_PER_CHAN)
                netif_stop_queue(dev);
-       local_irq_enable();
+       local_irq_restore(flags);
 
        return 0;
 }
index 5b5c25368d1e559e9f2dbbb71013f13efa293ce7..e3601cf3f9315e8462ec530cd25866ed5a78adbc 100644 (file)
@@ -620,6 +620,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
        dma_addr_t mapping;
        unsigned int len, entry;
        u32 ctrl;
+       unsigned long flags;
 
 #ifdef DEBUG
        int i;
@@ -635,12 +636,12 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 #endif
 
        len = skb->len;
-       spin_lock_irq(&bp->lock);
+       spin_lock_irqsave(&bp->lock, flags);
 
        /* This is a hard error, log it. */
        if (TX_BUFFS_AVAIL(bp) < 1) {
                netif_stop_queue(dev);
-               spin_unlock_irq(&bp->lock);
+               spin_unlock_irqrestore(&bp->lock, flags);
                dev_err(&bp->pdev->dev,
                        "BUG! Tx Ring full when queue awake!\n");
                dev_dbg(&bp->pdev->dev, "tx_head = %u, tx_tail = %u\n",
@@ -674,7 +675,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if (TX_BUFFS_AVAIL(bp) < 1)
                netif_stop_queue(dev);
 
-       spin_unlock_irq(&bp->lock);
+       spin_unlock_irqrestore(&bp->lock, flags);
 
        dev->trans_start = jiffies;
 
index 5a88b3f576931f33063eeb2749dcb70e8eff70d4..62208401c4df36d307a83eab67d8df7cfc8f5d84 100644 (file)
@@ -437,6 +437,7 @@ static inline void mlx4_en_xmit_poll(struct mlx4_en_priv *priv, int tx_ind)
 {
        struct mlx4_en_cq *cq = &priv->tx_cq[tx_ind];
        struct mlx4_en_tx_ring *ring = &priv->tx_ring[tx_ind];
+       unsigned long flags;
 
        /* If we don't have a pending timer, set one up to catch our recent
           post in case the interface becomes idle */
@@ -445,9 +446,9 @@ static inline void mlx4_en_xmit_poll(struct mlx4_en_priv *priv, int tx_ind)
 
        /* Poll the CQ every mlx4_en_TX_MODER_POLL packets */
        if ((++ring->poll_cnt & (MLX4_EN_TX_POLL_MODER - 1)) == 0)
-               if (spin_trylock_irq(&ring->comp_lock)) {
+               if (spin_trylock_irqsave(&ring->comp_lock, flags)) {
                        mlx4_en_process_tx_cq(priv->dev, cq);
-                       spin_unlock_irq(&ring->comp_lock);
+                       spin_unlock_irqrestore(&ring->comp_lock, flags);
                }
 }
 
index 1c70e999cc50d866ab5ebdba0956b25bba83659d..7567f510eff5c3f200c0d48a12238ac2bd39666a 100644 (file)
@@ -196,21 +196,23 @@ static void PRINT_PKT(u_char *buf, int length)
 /* this enables an interrupt in the interrupt mask register */
 #define SMC_ENABLE_INT(lp, x) do {                                     \
        unsigned char mask;                                             \
-       spin_lock_irq(&lp->lock);                                       \
+       unsigned long smc_enable_flags;                                 \
+       spin_lock_irqsave(&lp->lock, smc_enable_flags);                 \
        mask = SMC_GET_INT_MASK(lp);                                    \
        mask |= (x);                                                    \
        SMC_SET_INT_MASK(lp, mask);                                     \
-       spin_unlock_irq(&lp->lock);                                     \
+       spin_unlock_irqrestore(&lp->lock, smc_enable_flags);            \
 } while (0)
 
 /* this disables an interrupt from the interrupt mask register */
 #define SMC_DISABLE_INT(lp, x) do {                                    \
        unsigned char mask;                                             \
-       spin_lock_irq(&lp->lock);                                       \
+       unsigned long smc_disable_flags;                                \
+       spin_lock_irqsave(&lp->lock, smc_disable_flags);                \
        mask = SMC_GET_INT_MASK(lp);                                    \
        mask &= ~(x);                                                   \
        SMC_SET_INT_MASK(lp, mask);                                     \
-       spin_unlock_irq(&lp->lock);                                     \
+       spin_unlock_irqrestore(&lp->lock, smc_disable_flags);           \
 } while (0)
 
 /*
@@ -520,21 +522,21 @@ static inline void  smc_rcv(struct net_device *dev)
  * any other concurrent access and C would always interrupt B. But life
  * isn't that easy in a SMP world...
  */
-#define smc_special_trylock(lock)                                      \
+#define smc_special_trylock(lock, flags)                               \
 ({                                                                     \
        int __ret;                                                      \
-       local_irq_disable();                                            \
+       local_irq_save(flags);                                          \
        __ret = spin_trylock(lock);                                     \
        if (!__ret)                                                     \
-               local_irq_enable();                                     \
+               local_irq_restore(flags);                               \
        __ret;                                                          \
 })
-#define smc_special_lock(lock)         spin_lock_irq(lock)
-#define smc_special_unlock(lock)       spin_unlock_irq(lock)
+#define smc_special_lock(lock, flags)          spin_lock_irqsave(lock, flags)
+#define smc_special_unlock(lock, flags)        spin_unlock_irqrestore(lock, flags)
 #else
-#define smc_special_trylock(lock)      (1)
-#define smc_special_lock(lock)         do { } while (0)
-#define smc_special_unlock(lock)       do { } while (0)
+#define smc_special_trylock(lock, flags)       (1)
+#define smc_special_lock(lock, flags)          do { } while (0)
+#define smc_special_unlock(lock, flags)        do { } while (0)
 #endif
 
 /*
@@ -548,10 +550,11 @@ static void smc_hardware_send_pkt(unsigned long data)
        struct sk_buff *skb;
        unsigned int packet_no, len;
        unsigned char *buf;
+       unsigned long flags;
 
        DBG(3, "%s: %s\n", dev->name, __func__);
 
-       if (!smc_special_trylock(&lp->lock)) {
+       if (!smc_special_trylock(&lp->lock, flags)) {
                netif_stop_queue(dev);
                tasklet_schedule(&lp->tx_task);
                return;
@@ -559,7 +562,7 @@ static void smc_hardware_send_pkt(unsigned long data)
 
        skb = lp->pending_tx_skb;
        if (unlikely(!skb)) {
-               smc_special_unlock(&lp->lock);
+               smc_special_unlock(&lp->lock, flags);
                return;
        }
        lp->pending_tx_skb = NULL;
@@ -569,7 +572,7 @@ static void smc_hardware_send_pkt(unsigned long data)
                printk("%s: Memory allocation failed.\n", dev->name);
                dev->stats.tx_errors++;
                dev->stats.tx_fifo_errors++;
-               smc_special_unlock(&lp->lock);
+               smc_special_unlock(&lp->lock, flags);
                goto done;
        }
 
@@ -608,7 +611,7 @@ static void smc_hardware_send_pkt(unsigned long data)
 
        /* queue the packet for TX */
        SMC_SET_MMU_CMD(lp, MC_ENQUEUE);
-       smc_special_unlock(&lp->lock);
+       smc_special_unlock(&lp->lock, flags);
 
        dev->trans_start = jiffies;
        dev->stats.tx_packets++;
@@ -633,6 +636,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct smc_local *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->base;
        unsigned int numPages, poll_count, status;
+       unsigned long flags;
 
        DBG(3, "%s: %s\n", dev->name, __func__);
 
@@ -658,7 +662,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                return 0;
        }
 
-       smc_special_lock(&lp->lock);
+       smc_special_lock(&lp->lock, flags);
 
        /* now, try to allocate the memory */
        SMC_SET_MMU_CMD(lp, MC_ALLOC | numPages);
@@ -676,7 +680,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                }
        } while (--poll_count);
 
-       smc_special_unlock(&lp->lock);
+       smc_special_unlock(&lp->lock, flags);
 
        lp->pending_tx_skb = skb;
        if (!poll_count) {
index 2a6e81d5b579aa9032ae633bb80b6444bcf1ae40..bbedf03a2124c496090c82409d6b58d23c26465e 100644 (file)
@@ -70,6 +70,9 @@ struct virtnet_info
        struct sk_buff_head recv;
        struct sk_buff_head send;
 
+       /* Work struct for refilling if we run low on memory. */
+       struct delayed_work refill;
+
        /* Chain pages by the private ptr. */
        struct page *pages;
 };
@@ -273,19 +276,22 @@ drop:
        dev_kfree_skb(skb);
 }
 
-static void try_fill_recv_maxbufs(struct virtnet_info *vi)
+static bool try_fill_recv_maxbufs(struct virtnet_info *vi, gfp_t gfp)
 {
        struct sk_buff *skb;
        struct scatterlist sg[2+MAX_SKB_FRAGS];
        int num, err, i;
+       bool oom = false;
 
        sg_init_table(sg, 2+MAX_SKB_FRAGS);
        for (;;) {
                struct virtio_net_hdr *hdr;
 
                skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN + NET_IP_ALIGN);
-               if (unlikely(!skb))
+               if (unlikely(!skb)) {
+                       oom = true;
                        break;
+               }
 
                skb_reserve(skb, NET_IP_ALIGN);
                skb_put(skb, MAX_PACKET_LEN);
@@ -296,7 +302,7 @@ static void try_fill_recv_maxbufs(struct virtnet_info *vi)
                if (vi->big_packets) {
                        for (i = 0; i < MAX_SKB_FRAGS; i++) {
                                skb_frag_t *f = &skb_shinfo(skb)->frags[i];
-                               f->page = get_a_page(vi, GFP_ATOMIC);
+                               f->page = get_a_page(vi, gfp);
                                if (!f->page)
                                        break;
 
@@ -325,31 +331,35 @@ static void try_fill_recv_maxbufs(struct virtnet_info *vi)
        if (unlikely(vi->num > vi->max))
                vi->max = vi->num;
        vi->rvq->vq_ops->kick(vi->rvq);
+       return !oom;
 }
 
-static void try_fill_recv(struct virtnet_info *vi)
+/* Returns false if we couldn't fill entirely (OOM). */
+static bool try_fill_recv(struct virtnet_info *vi, gfp_t gfp)
 {
        struct sk_buff *skb;
        struct scatterlist sg[1];
        int err;
+       bool oom = false;
 
-       if (!vi->mergeable_rx_bufs) {
-               try_fill_recv_maxbufs(vi);
-               return;
-       }
+       if (!vi->mergeable_rx_bufs)
+               return try_fill_recv_maxbufs(vi, gfp);
 
        for (;;) {
                skb_frag_t *f;
 
                skb = netdev_alloc_skb(vi->dev, GOOD_COPY_LEN + NET_IP_ALIGN);
-               if (unlikely(!skb))
+               if (unlikely(!skb)) {
+                       oom = true;
                        break;
+               }
 
                skb_reserve(skb, NET_IP_ALIGN);
 
                f = &skb_shinfo(skb)->frags[0];
-               f->page = get_a_page(vi, GFP_ATOMIC);
+               f->page = get_a_page(vi, gfp);
                if (!f->page) {
+                       oom = true;
                        kfree_skb(skb);
                        break;
                }
@@ -373,6 +383,7 @@ static void try_fill_recv(struct virtnet_info *vi)
        if (unlikely(vi->num > vi->max))
                vi->max = vi->num;
        vi->rvq->vq_ops->kick(vi->rvq);
+       return !oom;
 }
 
 static void skb_recv_done(struct virtqueue *rvq)
@@ -385,6 +396,23 @@ static void skb_recv_done(struct virtqueue *rvq)
        }
 }
 
+static void refill_work(struct work_struct *work)
+{
+       struct virtnet_info *vi;
+       bool still_empty;
+
+       vi = container_of(work, struct virtnet_info, refill.work);
+       napi_disable(&vi->napi);
+       try_fill_recv(vi, GFP_KERNEL);
+       still_empty = (vi->num == 0);
+       napi_enable(&vi->napi);
+
+       /* In theory, this can happen: if we don't get any buffers in
+        * we will *never* try to fill again. */
+       if (still_empty)
+               schedule_delayed_work(&vi->refill, HZ/2);
+}
+
 static int virtnet_poll(struct napi_struct *napi, int budget)
 {
        struct virtnet_info *vi = container_of(napi, struct virtnet_info, napi);
@@ -400,10 +428,10 @@ again:
                received++;
        }
 
-       /* FIXME: If we oom and completely run out of inbufs, we need
-        * to start a timer trying to fill more. */
-       if (vi->num < vi->max / 2)
-               try_fill_recv(vi);
+       if (vi->num < vi->max / 2) {
+               if (!try_fill_recv(vi, GFP_ATOMIC))
+                       schedule_delayed_work(&vi->refill, 0);
+       }
 
        /* Out of packets? */
        if (received < budget) {
@@ -893,6 +921,7 @@ static int virtnet_probe(struct virtio_device *vdev)
        vi->vdev = vdev;
        vdev->priv = vi;
        vi->pages = NULL;
+       INIT_DELAYED_WORK(&vi->refill, refill_work);
 
        /* If they give us a callback when all buffers are done, we don't need
         * the timer. */
@@ -941,7 +970,7 @@ static int virtnet_probe(struct virtio_device *vdev)
        }
 
        /* Last of all, set up some receive buffers. */
-       try_fill_recv(vi);
+       try_fill_recv(vi, GFP_KERNEL);
 
        /* If we didn't even get one input buffer, we're useless. */
        if (vi->num == 0) {
@@ -958,6 +987,7 @@ static int virtnet_probe(struct virtio_device *vdev)
 
 unregister:
        unregister_netdev(dev);
+       cancel_delayed_work_sync(&vi->refill);
 free_vqs:
        vdev->config->del_vqs(vdev);
 free:
@@ -986,6 +1016,7 @@ static void virtnet_remove(struct virtio_device *vdev)
        BUG_ON(vi->num != 0);
 
        unregister_netdev(vi->dev);
+       cancel_delayed_work_sync(&vi->refill);
 
        vdev->config->del_vqs(vi->vdev);
 
index 6dcac73b4d299ee80e4bbf40877387620d3066ea..f593fbbb4e525c08c82513005b58e42be55e712b 100644 (file)
@@ -2874,45 +2874,27 @@ static int ipw_fw_dma_add_command_block(struct ipw_priv *priv,
        return 0;
 }
 
-static int ipw_fw_dma_add_buffer(struct ipw_priv *priv,
-                                u32 src_phys, u32 dest_address, u32 length)
+static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, dma_addr_t *src_address,
+                                int nr, u32 dest_address, u32 len)
 {
-       u32 bytes_left = length;
-       u32 src_offset = 0;
-       u32 dest_offset = 0;
-       int status = 0;
+       int ret, i;
+       u32 size;
+
        IPW_DEBUG_FW(">> \n");
-       IPW_DEBUG_FW_INFO("src_phys=0x%x dest_address=0x%x length=0x%x\n",
-                         src_phys, dest_address, length);
-       while (bytes_left > CB_MAX_LENGTH) {
-               status = ipw_fw_dma_add_command_block(priv,
-                                                     src_phys + src_offset,
-                                                     dest_address +
-                                                     dest_offset,
-                                                     CB_MAX_LENGTH, 0, 0);
-               if (status) {
+       IPW_DEBUG_FW_INFO("nr=%d dest_address=0x%x len=0x%x\n",
+                         nr, dest_address, len);
+
+       for (i = 0; i < nr; i++) {
+               size = min_t(u32, len - i * CB_MAX_LENGTH, CB_MAX_LENGTH);
+               ret = ipw_fw_dma_add_command_block(priv, src_address[i],
+                                                  dest_address +
+                                                  i * CB_MAX_LENGTH, size,
+                                                  0, 0);
+               if (ret) {
                        IPW_DEBUG_FW_INFO(": Failed\n");
                        return -1;
                } else
                        IPW_DEBUG_FW_INFO(": Added new cb\n");
-
-               src_offset += CB_MAX_LENGTH;
-               dest_offset += CB_MAX_LENGTH;
-               bytes_left -= CB_MAX_LENGTH;
-       }
-
-       /* add the buffer tail */
-       if (bytes_left > 0) {
-               status =
-                   ipw_fw_dma_add_command_block(priv, src_phys + src_offset,
-                                                dest_address + dest_offset,
-                                                bytes_left, 0, 0);
-               if (status) {
-                       IPW_DEBUG_FW_INFO(": Failed on the buffer tail\n");
-                       return -1;
-               } else
-                       IPW_DEBUG_FW_INFO
-                           (": Adding new cb - the buffer tail\n");
        }
 
        IPW_DEBUG_FW("<< \n");
@@ -3160,59 +3142,91 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
 
 static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
 {
-       int rc = -1;
+       int ret = -1;
        int offset = 0;
        struct fw_chunk *chunk;
-       dma_addr_t shared_phys;
-       u8 *shared_virt;
+       int total_nr = 0;
+       int i;
+       struct pci_pool *pool;
+       u32 *virts[CB_NUMBER_OF_ELEMENTS_SMALL];
+       dma_addr_t phys[CB_NUMBER_OF_ELEMENTS_SMALL];
 
        IPW_DEBUG_TRACE("<< : \n");
-       shared_virt = pci_alloc_consistent(priv->pci_dev, len, &shared_phys);
 
-       if (!shared_virt)
+       pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0);
+       if (!pool) {
+               IPW_ERROR("pci_pool_create failed\n");
                return -ENOMEM;
-
-       memmove(shared_virt, data, len);
+       }
 
        /* Start the Dma */
-       rc = ipw_fw_dma_enable(priv);
+       ret = ipw_fw_dma_enable(priv);
 
        /* the DMA is already ready this would be a bug. */
        BUG_ON(priv->sram_desc.last_cb_index > 0);
 
        do {
+               u32 chunk_len;
+               u8 *start;
+               int size;
+               int nr = 0;
+
                chunk = (struct fw_chunk *)(data + offset);
                offset += sizeof(struct fw_chunk);
+               chunk_len = le32_to_cpu(chunk->length);
+               start = data + offset;
+
+               nr = (chunk_len + CB_MAX_LENGTH - 1) / CB_MAX_LENGTH;
+               for (i = 0; i < nr; i++) {
+                       virts[total_nr] = pci_pool_alloc(pool, GFP_KERNEL,
+                                                        &phys[total_nr]);
+                       if (!virts[total_nr]) {
+                               ret = -ENOMEM;
+                               goto out;
+                       }
+                       size = min_t(u32, chunk_len - i * CB_MAX_LENGTH,
+                                    CB_MAX_LENGTH);
+                       memcpy(virts[total_nr], start, size);
+                       start += size;
+                       total_nr++;
+                       /* We don't support fw chunk larger than 64*8K */
+                       BUG_ON(total_nr > CB_NUMBER_OF_ELEMENTS_SMALL);
+               }
+
                /* build DMA packet and queue up for sending */
                /* dma to chunk->address, the chunk->length bytes from data +
                 * offeset*/
                /* Dma loading */
-               rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset,
-                                          le32_to_cpu(chunk->address),
-                                          le32_to_cpu(chunk->length));
-               if (rc) {
+               ret = ipw_fw_dma_add_buffer(priv, &phys[total_nr - nr],
+                                           nr, le32_to_cpu(chunk->address),
+                                           chunk_len);
+               if (ret) {
                        IPW_DEBUG_INFO("dmaAddBuffer Failed\n");
                        goto out;
                }
 
-               offset += le32_to_cpu(chunk->length);
+               offset += chunk_len;
        } while (offset < len);
 
        /* Run the DMA and wait for the answer */
-       rc = ipw_fw_dma_kick(priv);
-       if (rc) {
+       ret = ipw_fw_dma_kick(priv);
+       if (ret) {
                IPW_ERROR("dmaKick Failed\n");
                goto out;
        }
 
-       rc = ipw_fw_dma_wait(priv);
-       if (rc) {
+       ret = ipw_fw_dma_wait(priv);
+       if (ret) {
                IPW_ERROR("dmaWaitSync Failed\n");
                goto out;
        }
-      out:
-       pci_free_consistent(priv->pci_dev, len, shared_virt, shared_phys);
-       return rc;
+ out:
+       for (i = 0; i < total_nr; i++)
+               pci_pool_free(pool, virts[i], phys[i]);
+
+       pci_pool_destroy(pool);
+
+       return ret;
 }
 
 /* stop nic */
index 632fac86a3085ee33713a1fb2f718e50527da053..b3946272c72e75ed4c3fcfebe644c8404a46d19e 100644 (file)
@@ -70,7 +70,7 @@ int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc)
        int err = 0;
        u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE];
 
-       if ((key < 0) || (key > 4))
+       if ((key < 0) || (key >= 4))
                return -EINVAL;
 
        err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV,
index 294250e294dd548bb295c620e6d52c799f03021f..87a95588a8e3c69793ee6c437a3ba242427eed07 100644 (file)
@@ -869,6 +869,9 @@ static int rtl8187b_init_hw(struct ieee80211_hw *dev)
        priv->aifsn[3] = 3; /* AIFSN[AC_BE] */
        rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0);
 
+       /* ENEDCA flag must always be set, transmit issues? */
+       rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_ENEDCA);
+
        return 0;
 }
 
@@ -1173,13 +1176,16 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
                        rtl818x_iowrite8(priv, &priv->map->BSSID[i],
                                         info->bssid[i]);
 
+               if (priv->is_rtl8187b)
+                       reg = RTL818X_MSR_ENEDCA;
+               else
+                       reg = 0;
+
                if (is_valid_ether_addr(info->bssid)) {
-                       reg = RTL818X_MSR_INFRA;
-                       if (priv->is_rtl8187b)
-                               reg |= RTL818X_MSR_ENEDCA;
+                       reg |= RTL818X_MSR_INFRA;
                        rtl818x_iowrite8(priv, &priv->map->MSR, reg);
                } else {
-                       reg = RTL818X_MSR_NO_LINK;
+                       reg |= RTL818X_MSR_NO_LINK;
                        rtl818x_iowrite8(priv, &priv->map->MSR, reg);
                }
 
index a07580138e8109c10b958498dad13ca1f200ad1c..c2fd6187773f1df97fab29504ca8dbca85a54193 100644 (file)
@@ -346,7 +346,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static int yellowfin_open(struct net_device *dev);
 static void yellowfin_timer(unsigned long data);
 static void yellowfin_tx_timeout(struct net_device *dev);
-static void yellowfin_init_ring(struct net_device *dev);
+static int yellowfin_init_ring(struct net_device *dev);
 static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance);
 static int yellowfin_rx(struct net_device *dev);
@@ -573,19 +573,24 @@ static int yellowfin_open(struct net_device *dev)
 {
        struct yellowfin_private *yp = netdev_priv(dev);
        void __iomem *ioaddr = yp->base;
-       int i;
+       int i, ret;
 
        /* Reset the chip. */
        iowrite32(0x80000000, ioaddr + DMACtrl);
 
-       i = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev);
-       if (i) return i;
+       ret = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev);
+       if (ret)
+               return ret;
 
        if (yellowfin_debug > 1)
                printk(KERN_DEBUG "%s: yellowfin_open() irq %d.\n",
                           dev->name, dev->irq);
 
-       yellowfin_init_ring(dev);
+       ret = yellowfin_init_ring(dev);
+       if (ret) {
+               free_irq(dev->irq, dev);
+               return ret;
+       }
 
        iowrite32(yp->rx_ring_dma, ioaddr + RxPtr);
        iowrite32(yp->tx_ring_dma, ioaddr + TxPtr);
@@ -725,10 +730,10 @@ static void yellowfin_tx_timeout(struct net_device *dev)
 }
 
 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
-static void yellowfin_init_ring(struct net_device *dev)
+static int yellowfin_init_ring(struct net_device *dev)
 {
        struct yellowfin_private *yp = netdev_priv(dev);
-       int i;
+       int i, j;
 
        yp->tx_full = 0;
        yp->cur_rx = yp->cur_tx = 0;
@@ -753,6 +758,11 @@ static void yellowfin_init_ring(struct net_device *dev)
                yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev,
                        skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE));
        }
+       if (i != RX_RING_SIZE) {
+               for (j = 0; j < i; j++)
+                       dev_kfree_skb(yp->rx_skbuff[j]);
+               return -ENOMEM;
+       }
        yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP);
        yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
 
@@ -769,8 +779,6 @@ static void yellowfin_init_ring(struct net_device *dev)
        yp->tx_ring[--i].dbdma_cmd = cpu_to_le32(CMD_STOP | BRANCH_ALWAYS);
 #else
 {
-       int j;
-
        /* Tx ring needs a pair of descriptors, the second for the status. */
        for (i = 0; i < TX_RING_SIZE; i++) {
                j = 2*i;
@@ -805,7 +813,7 @@ static void yellowfin_init_ring(struct net_device *dev)
 }
 #endif
        yp->tx_tail_desc = &yp->tx_status[0];
-       return;
+       return 0;
 }
 
 static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev)
index e3a87210e947cdce8d57ded76c63cfb2ba07e788..e03fe98f06193c1c6a1fa22cbf6db92a0dbd2c6a 100644 (file)
@@ -597,6 +597,29 @@ int pci_iov_resource_bar(struct pci_dev *dev, int resno,
                4 * (resno - PCI_IOV_RESOURCES);
 }
 
+/**
+ * pci_sriov_resource_alignment - get resource alignment for VF BAR
+ * @dev: the PCI device
+ * @resno: the resource number
+ *
+ * Returns the alignment of the VF BAR found in the SR-IOV capability.
+ * This is not the same as the resource size which is defined as
+ * the VF BAR size multiplied by the number of VFs.  The alignment
+ * is just the VF BAR size.
+ */
+int pci_sriov_resource_alignment(struct pci_dev *dev, int resno)
+{
+       struct resource tmp;
+       enum pci_bar_type type;
+       int reg = pci_iov_resource_bar(dev, resno, &type);
+       
+       if (!reg)
+               return 0;
+
+        __pci_read_base(dev, type, &tmp, reg);
+       return resource_alignment(&tmp);
+}
+
 /**
  * pci_restore_iov_state - restore the state of the IOV capability
  * @dev: the PCI device
index d76c4c85367e4368963c9d71092bdaaad6888ce3..f99bc7f089f1ab8c0839775c58f2cabc487e37cf 100644 (file)
@@ -508,7 +508,7 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev)
                        return error;
        }
 
-       return pci_dev->state_saved ? pci_restore_state(pci_dev) : 0;
+       return pci_restore_state(pci_dev);
 }
 
 static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
index dbd0f947f49728a3849f7e96b03a2de1f2ae180f..7b70312181d78a28cdfba11639c673626ee8eed6 100644 (file)
@@ -846,6 +846,8 @@ pci_restore_state(struct pci_dev *dev)
        int i;
        u32 val;
 
+       if (!dev->state_saved)
+               return 0;
        /* PCI Express register must be restored first */
        pci_restore_pcie_state(dev);
 
index f73bcbedf37c492344d92bed0ef5840db33ecbcc..5ff4d25bf0e938f28904f22b46b5c6505239af8e 100644 (file)
@@ -243,6 +243,7 @@ extern int pci_iov_init(struct pci_dev *dev);
 extern void pci_iov_release(struct pci_dev *dev);
 extern int pci_iov_resource_bar(struct pci_dev *dev, int resno,
                                enum pci_bar_type *type);
+extern int pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
 extern void pci_restore_iov_state(struct pci_dev *dev);
 extern int pci_iov_bus_range(struct pci_bus *bus);
 
@@ -298,4 +299,16 @@ static inline int pci_ats_enabled(struct pci_dev *dev)
 }
 #endif /* CONFIG_PCI_IOV */
 
+static inline int pci_resource_alignment(struct pci_dev *dev,
+                                        struct resource *res)
+{
+#ifdef CONFIG_PCI_IOV
+       int resno = res - dev->resource;
+
+       if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
+               return pci_sriov_resource_alignment(dev, resno);
+#endif
+       return resource_alignment(res);
+}
+
 #endif /* DRIVERS_PCI_H */
index b636e245445defa08b1b7a03d38d204388d6b717..7c443b4583ab67162dd97718636cb30cfbc93b8f 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/ioport.h>
 #include <linux/cache.h>
 #include <linux/slab.h>
-
+#include "pci.h"
 
 static void pbus_assign_resources_sorted(const struct pci_bus *bus)
 {
@@ -384,7 +384,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
                                continue;
                        r_size = resource_size(r);
                        /* For bridges size != alignment */
-                       align = resource_alignment(r);
+                       align = pci_resource_alignment(dev, r);
                        order = __ffs(align) - 20;
                        if (order > 11) {
                                dev_warn(&dev->dev, "BAR %d bad alignment %llx: "
index 1898c7b47907b81cb456d8a06391f47dc4b7f4d7..88cdd1a937d6bd3a91180690d9f4e60df92201f8 100644 (file)
@@ -144,7 +144,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
 
        size = resource_size(res);
        min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
-       align = resource_alignment(res);
+       align = pci_resource_alignment(dev, res);
 
        /* First, try exact prefetching match.. */
        ret = pci_bus_alloc_resource(bus, res, size, align, min,
@@ -178,7 +178,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
        struct pci_bus *bus;
        int ret;
 
-       align = resource_alignment(res);
+       align = pci_resource_alignment(dev, res);
        if (!align) {
                dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus "
                        "alignment) %pR flags %#lx\n",
@@ -259,7 +259,7 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
                if (!(r->flags) || r->parent)
                        continue;
 
-               r_align = resource_alignment(r);
+               r_align = pci_resource_alignment(dev, r);
                if (!r_align) {
                        dev_warn(&dev->dev, "BAR %d: bogus alignment "
                                "%pR flags %#lx\n",
@@ -271,7 +271,7 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
                        struct resource_list *ln = list->next;
 
                        if (ln)
-                               align = resource_alignment(ln->res);
+                               align = pci_resource_alignment(ln->dev, ln->res);
 
                        if (r_align > align) {
                                tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
index 81d31ea507d116e3186384d7a0a394d00dc0e3ae..51c0a8bee4144ff800ff200e463315590e2d729a 100644 (file)
@@ -335,6 +335,7 @@ static void bt_rfkill_poll(struct rfkill *rfkill, void *data)
        if (hci_result != HCI_SUCCESS) {
                /* Can't do anything useful */
                mutex_unlock(&dev->mutex);
+               return;
        }
 
        new_rfk_state = value;
index 043b208d971d58b9841d1eac1592ec0620cbd85b..f215a59191925f01893c5c65802c0f80b61eee43 100644 (file)
@@ -270,7 +270,7 @@ u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out)
        acpi_status status;
        struct acpi_object_list input;
        union acpi_object params[3];
-       char method[4] = "WM";
+       char method[5] = "WM";
 
        if (!find_guid(guid_string, &wblock))
                return AE_ERROR;
@@ -328,8 +328,8 @@ struct acpi_buffer *out)
        acpi_status status, wc_status = AE_ERROR;
        struct acpi_object_list input, wc_input;
        union acpi_object wc_params[1], wq_params[1];
-       char method[4];
-       char wc_method[4] = "WC";
+       char method[5];
+       char wc_method[5] = "WC";
 
        if (!guid_string || !out)
                return AE_BAD_PARAMETER;
@@ -410,7 +410,7 @@ const struct acpi_buffer *in)
        acpi_handle handle;
        struct acpi_object_list input;
        union acpi_object params[2];
-       char method[4] = "WS";
+       char method[5] = "WS";
 
        if (!guid_string || !in)
                return AE_BAD_DATA;
index ac8cc8cea1e386425a8df7847f57f5737d447b11..fea17e7805e9d5e846998c16d965711628e4bc8b 100644 (file)
@@ -244,7 +244,7 @@ int pps_register_cdev(struct pps_device *pps)
        }
        pps->dev = device_create(pps_class, pps->info.dev, pps->devno, NULL,
                                                        "pps%d", pps->id);
-       if (err)
+       if (IS_ERR(pps->dev))
                goto del_cdev;
        dev_set_drvdata(pps->dev, pps);
 
index 749836668655980c0111be468bbdb8c3edd70e98..3f62dd50bbbe0afeef786877c1de7234ff80662d 100644 (file)
@@ -2135,9 +2135,9 @@ static int dasd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
        struct dasd_device *base;
 
        block = bdev->bd_disk->private_data;
-       base = block->base;
        if (!block)
                return -ENODEV;
+       base = block->base;
 
        if (!base->discipline ||
            !base->discipline->fill_geometry)
index 3c57c1a18bb8772db79a73159a98244ae4c89972..d593bc76afe316478374f99e970a37f469cebbf9 100644 (file)
@@ -772,10 +772,8 @@ static struct ccw_device * io_subchannel_create_ccwdev(struct subchannel *sch)
        cdev = io_subchannel_allocate_dev(sch);
        if (!IS_ERR(cdev)) {
                ret = io_subchannel_initialize_dev(sch, cdev);
-               if (ret) {
-                       kfree(cdev);
+               if (ret)
                        cdev = ERR_PTR(ret);
-               }
        }
        return cdev;
 }
index 15dab96d05e31328108b89dabc53ee4b2b5aa573..7c815d3327f754e095212dfc608a64f514547429 100644 (file)
@@ -537,8 +537,12 @@ int bbc_envctrl_init(struct bbc_i2c_bus *bp)
        }
        if (temp_index != 0 && fan_index != 0) {
                kenvctrld_task = kthread_run(kenvctrld, NULL, "kenvctrld");
-               if (IS_ERR(kenvctrld_task))
-                       return PTR_ERR(kenvctrld_task);
+               if (IS_ERR(kenvctrld_task)) {
+                       int err = PTR_ERR(kenvctrld_task);
+
+                       kenvctrld_task = NULL;
+                       return err;
+               }
        }
 
        return 0;
@@ -561,7 +565,8 @@ void bbc_envctrl_cleanup(struct bbc_i2c_bus *bp)
        struct bbc_cpu_temperature *tp, *tpos;
        struct bbc_fan_control *fp, *fpos;
 
-       kthread_stop(kenvctrld_task);
+       if (kenvctrld_task)
+               kthread_stop(kenvctrld_task);
 
        list_for_each_entry_safe(tp, tpos, &bp->temps, bp_list) {
                list_del(&tp->bp_list);
index f3da592f7bccc204fc08d901e9fabbd2c1eb6ee7..35a13867495ee3c5c0b2ddd6e72b7433887f5c11 100644 (file)
@@ -119,6 +119,64 @@ _base_fault_reset_work(struct work_struct *work)
        spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 }
 
+/**
+ * mpt2sas_base_start_watchdog - start the fault_reset_work_q
+ * @ioc: pointer to scsi command object
+ * Context: sleep.
+ *
+ * Return nothing.
+ */
+void
+mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc)
+{
+       unsigned long    flags;
+
+       if (ioc->fault_reset_work_q)
+               return;
+
+       /* initialize fault polling */
+       INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work);
+       snprintf(ioc->fault_reset_work_q_name,
+           sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id);
+       ioc->fault_reset_work_q =
+               create_singlethread_workqueue(ioc->fault_reset_work_q_name);
+       if (!ioc->fault_reset_work_q) {
+               printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n",
+                   ioc->name, __func__, __LINE__);
+                       return;
+       }
+       spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
+       if (ioc->fault_reset_work_q)
+               queue_delayed_work(ioc->fault_reset_work_q,
+                   &ioc->fault_reset_work,
+                   msecs_to_jiffies(FAULT_POLLING_INTERVAL));
+       spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
+}
+
+/**
+ * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q
+ * @ioc: pointer to scsi command object
+ * Context: sleep.
+ *
+ * Return nothing.
+ */
+void
+mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc)
+{
+       unsigned long    flags;
+       struct workqueue_struct *wq;
+
+       spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
+       wq = ioc->fault_reset_work_q;
+       ioc->fault_reset_work_q = NULL;
+       spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
+       if (wq) {
+               if (!cancel_delayed_work(&ioc->fault_reset_work))
+                       flush_workqueue(wq);
+               destroy_workqueue(wq);
+       }
+}
+
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 /**
  * _base_sas_ioc_info - verbose translation of the ioc status
@@ -440,6 +498,10 @@ _base_sas_log_info(struct MPT2SAS_ADAPTER *ioc , u32 log_info)
        if (sas_loginfo.dw.bus_type != 3 /*SAS*/)
                return;
 
+       /* each nexus loss loginfo */
+       if (log_info == 0x31170000)
+               return;
+
        /* eat the loginfos associated with task aborts */
        if (ioc->ignore_loginfos && (log_info == 30050000 || log_info ==
            0x31140000 || log_info == 0x31130000))
@@ -1109,7 +1171,6 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
                }
        }
 
-       pci_set_drvdata(pdev, ioc->shost);
        _base_mask_interrupts(ioc);
        r = _base_enable_msix(ioc);
        if (r)
@@ -1132,7 +1193,6 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
        ioc->pci_irq = -1;
        pci_release_selected_regions(ioc->pdev, ioc->bars);
        pci_disable_device(pdev);
-       pci_set_drvdata(pdev, NULL);
        return r;
 }
 
@@ -3191,7 +3251,6 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc)
        ioc->chip_phys = 0;
        pci_release_selected_regions(ioc->pdev, ioc->bars);
        pci_disable_device(pdev);
-       pci_set_drvdata(pdev, NULL);
        return;
 }
 
@@ -3205,7 +3264,6 @@ int
 mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
 {
        int r, i;
-       unsigned long    flags;
 
        dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
            __func__));
@@ -3214,6 +3272,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
        if (r)
                return r;
 
+       pci_set_drvdata(ioc->pdev, ioc->shost);
        r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
        if (r)
                goto out_free_resources;
@@ -3288,23 +3347,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
        if (r)
                goto out_free_resources;
 
-       /* initialize fault polling */
-       INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work);
-       snprintf(ioc->fault_reset_work_q_name,
-           sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id);
-       ioc->fault_reset_work_q =
-               create_singlethread_workqueue(ioc->fault_reset_work_q_name);
-       if (!ioc->fault_reset_work_q) {
-               printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n",
-                   ioc->name, __func__, __LINE__);
-                       goto out_free_resources;
-       }
-       spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-       if (ioc->fault_reset_work_q)
-               queue_delayed_work(ioc->fault_reset_work_q,
-                   &ioc->fault_reset_work,
-                   msecs_to_jiffies(FAULT_POLLING_INTERVAL));
-       spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
+       mpt2sas_base_start_watchdog(ioc);
        return 0;
 
  out_free_resources:
@@ -3312,6 +3355,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
        ioc->remove_host = 1;
        mpt2sas_base_free_resources(ioc);
        _base_release_memory_pools(ioc);
+       pci_set_drvdata(ioc->pdev, NULL);
        kfree(ioc->tm_cmds.reply);
        kfree(ioc->transport_cmds.reply);
        kfree(ioc->config_cmds.reply);
@@ -3337,22 +3381,14 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
 void
 mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
 {
-       unsigned long    flags;
-       struct workqueue_struct *wq;
 
        dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
            __func__));
 
-       spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-       wq = ioc->fault_reset_work_q;
-       ioc->fault_reset_work_q = NULL;
-       spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
-       if (!cancel_delayed_work(&ioc->fault_reset_work))
-               flush_workqueue(wq);
-       destroy_workqueue(wq);
-
+       mpt2sas_base_stop_watchdog(ioc);
        mpt2sas_base_free_resources(ioc);
        _base_release_memory_pools(ioc);
+       pci_set_drvdata(ioc->pdev, NULL);
        kfree(ioc->pfacts);
        kfree(ioc->ctl_cmds.reply);
        kfree(ioc->base_cmds.reply);
index 286c185fa9e40a5b7347de0dc99b06c4d2f0e617..acdcff150a35015d391ae80b8b3eeb8d6f14f5c1 100644 (file)
 #define MPT2SAS_DRIVER_NAME            "mpt2sas"
 #define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>"
 #define MPT2SAS_DESCRIPTION    "LSI MPT Fusion SAS 2.0 Device Driver"
-#define MPT2SAS_DRIVER_VERSION         "01.100.03.00"
+#define MPT2SAS_DRIVER_VERSION         "01.100.04.00"
 #define MPT2SAS_MAJOR_VERSION          01
 #define MPT2SAS_MINOR_VERSION          100
-#define MPT2SAS_BUILD_VERSION          03
+#define MPT2SAS_BUILD_VERSION          04
 #define MPT2SAS_RELEASE_VERSION                00
 
 /*
@@ -673,6 +673,8 @@ typedef void (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID,
 
 /* base shared API */
 extern struct list_head mpt2sas_ioc_list;
+void mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc);
+void mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc);
 
 int mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc);
 void mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc);
index 58cfb97846f7e292a5c30a34b1e44c7cce876824..6ddee161beb36aae9d2357c0f7c9926db189079b 100644 (file)
@@ -236,17 +236,25 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
        Mpi2ConfigRequest_t *config_request;
        int r;
        u8 retry_count;
-       u8 issue_reset;
+       u8 issue_host_reset = 0;
        u16 wait_state_count;
 
+       mutex_lock(&ioc->config_cmds.mutex);
        if (ioc->config_cmds.status != MPT2_CMD_NOT_USED) {
                printk(MPT2SAS_ERR_FMT "%s: config_cmd in use\n",
                    ioc->name, __func__);
+               mutex_unlock(&ioc->config_cmds.mutex);
                return -EAGAIN;
        }
        retry_count = 0;
 
  retry_config:
+       if (retry_count) {
+               if (retry_count > 2) /* attempt only 2 retries */
+                       return -EFAULT;
+               printk(MPT2SAS_INFO_FMT "%s: attempting retry (%d)\n",
+                   ioc->name, __func__, retry_count);
+       }
        wait_state_count = 0;
        ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
        while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
@@ -254,8 +262,8 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
                        printk(MPT2SAS_ERR_FMT
                            "%s: failed due to ioc not operational\n",
                            ioc->name, __func__);
-                       ioc->config_cmds.status = MPT2_CMD_NOT_USED;
-                       return -EFAULT;
+                       r = -EFAULT;
+                       goto out;
                }
                ssleep(1);
                ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
@@ -271,8 +279,8 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
        if (!smid) {
                printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
                    ioc->name, __func__);
-               ioc->config_cmds.status = MPT2_CMD_NOT_USED;
-               return -EAGAIN;
+               r = -EAGAIN;
+               goto out;
        }
 
        r = 0;
@@ -292,9 +300,15 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
                    ioc->name, __func__);
                _debug_dump_mf(mpi_request,
                    sizeof(Mpi2ConfigRequest_t)/4);
-               if (!(ioc->config_cmds.status & MPT2_CMD_RESET))
-                       issue_reset = 1;
-               goto issue_host_reset;
+               retry_count++;
+               if (ioc->config_cmds.smid == smid)
+                       mpt2sas_base_free_smid(ioc, smid);
+               if ((ioc->shost_recovery) ||
+                   (ioc->config_cmds.status & MPT2_CMD_RESET))
+                       goto retry_config;
+               issue_host_reset = 1;
+               r = -EFAULT;
+               goto out;
        }
        if (ioc->config_cmds.status & MPT2_CMD_REPLY_VALID)
                memcpy(mpi_reply, ioc->config_cmds.reply,
@@ -302,21 +316,13 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
        if (retry_count)
                printk(MPT2SAS_INFO_FMT "%s: retry completed!!\n",
                    ioc->name, __func__);
+out:
        ioc->config_cmds.status = MPT2_CMD_NOT_USED;
-       return r;
-
- issue_host_reset:
-       if (issue_reset)
+       mutex_unlock(&ioc->config_cmds.mutex);
+       if (issue_host_reset)
                mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
                    FORCE_BIG_HAMMER);
-       ioc->config_cmds.status = MPT2_CMD_NOT_USED;
-       if (!retry_count) {
-               printk(MPT2SAS_INFO_FMT "%s: attempting retry\n",
-                   ioc->name, __func__);
-               retry_count++;
-               goto retry_config;
-       }
-       return -EFAULT;
+       return r;
 }
 
 /**
@@ -375,7 +381,6 @@ mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc,
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(config_page, 0, sizeof(Mpi2ManufacturingPage0_t));
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -417,7 +422,6 @@ mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc,
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -438,7 +442,6 @@ mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc,
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(config_page, 0, sizeof(Mpi2BiosPage2_t));
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -480,7 +483,6 @@ mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc,
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -501,7 +503,6 @@ mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(config_page, 0, sizeof(Mpi2BiosPage3_t));
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -543,7 +544,6 @@ mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -564,7 +564,6 @@ mpt2sas_config_get_iounit_pg0(struct MPT2SAS_ADAPTER *ioc,
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(config_page, 0, sizeof(Mpi2IOUnitPage0_t));
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -606,7 +605,6 @@ mpt2sas_config_get_iounit_pg0(struct MPT2SAS_ADAPTER *ioc,
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -627,7 +625,6 @@ mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(config_page, 0, sizeof(Mpi2IOUnitPage1_t));
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -669,7 +666,6 @@ mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -690,7 +686,6 @@ mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
        mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -732,7 +727,6 @@ mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -753,7 +747,6 @@ mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc,
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(config_page, 0, sizeof(Mpi2IOCPage8_t));
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -795,7 +788,6 @@ mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc,
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -818,7 +810,6 @@ mpt2sas_config_get_sas_device_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(config_page, 0, sizeof(Mpi2SasDevicePage0_t));
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -863,7 +854,6 @@ mpt2sas_config_get_sas_device_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -886,7 +876,6 @@ mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(config_page, 0, sizeof(Mpi2SasDevicePage1_t));
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -931,7 +920,6 @@ mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -953,7 +941,6 @@ mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys)
        Mpi2ConfigReply_t mpi_reply;
        Mpi2SasIOUnitPage0_t config_page;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
        mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -1002,7 +989,6 @@ mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys)
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -1026,8 +1012,6 @@ mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
        Mpi2ConfigRequest_t mpi_request;
        int r;
        struct config_request mem;
-
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(config_page, 0, sz);
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1070,7 +1054,6 @@ mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -1095,7 +1078,6 @@ mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(config_page, 0, sz);
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1138,7 +1120,6 @@ mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -1161,7 +1142,6 @@ mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(config_page, 0, sizeof(Mpi2ExpanderPage0_t));
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1206,7 +1186,6 @@ mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -1230,7 +1209,6 @@ mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(config_page, 0, sizeof(Mpi2ExpanderPage1_t));
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1277,7 +1255,6 @@ mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -1300,7 +1277,6 @@ mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(config_page, 0, sizeof(Mpi2SasEnclosurePage0_t));
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1345,7 +1321,6 @@ mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -1367,7 +1342,6 @@ mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(config_page, 0, sizeof(Mpi2SasPhyPage0_t));
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1413,7 +1387,6 @@ mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -1435,7 +1408,6 @@ mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(config_page, 0, sizeof(Mpi2SasPhyPage1_t));
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1481,7 +1453,6 @@ mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -1505,7 +1476,6 @@ mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER *ioc,
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(config_page, 0, sizeof(Mpi2RaidVolPage1_t));
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1548,7 +1518,6 @@ mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER *ioc,
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -1572,7 +1541,6 @@ mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER *ioc, u16 handle,
        struct config_request mem;
        u16 ioc_status;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        *num_pds = 0;
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1620,7 +1588,6 @@ mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER *ioc, u16 handle,
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -1645,7 +1612,6 @@ mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER *ioc,
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        memset(config_page, 0, sz);
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1687,7 +1653,6 @@ mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER *ioc,
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -1711,7 +1676,6 @@ mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
        int r;
        struct config_request mem;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        memset(config_page, 0, sizeof(Mpi2RaidPhysDiskPage0_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1754,7 +1718,6 @@ mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
@@ -1778,7 +1741,6 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
        struct config_request mem;
        u16 ioc_status;
 
-       mutex_lock(&ioc->config_cmds.mutex);
        *volume_handle = 0;
        memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
        mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1842,7 +1804,6 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
                _config_free_config_dma_memory(ioc, &mem);
 
  out:
-       mutex_unlock(&ioc->config_cmds.mutex);
        return r;
 }
 
index 2a01a5f2a84dddc4d105d5ef88030abe1adc21ab..2e9a4445596f4a8e5707d74fb770aceeaa7b908d 100644 (file)
@@ -2767,6 +2767,10 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
        char *desc_ioc_state = NULL;
        char *desc_scsi_status = NULL;
        char *desc_scsi_state = ioc->tmp_string;
+       u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
+
+       if (log_info == 0x31170000)
+               return;
 
        switch (ioc_status) {
        case MPI2_IOCSTATUS_SUCCESS:
@@ -3426,7 +3430,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
        __le64 sas_address;
        int i;
        unsigned long flags;
-       struct _sas_port *mpt2sas_port;
+       struct _sas_port *mpt2sas_port = NULL;
        int rc = 0;
 
        if (!handle)
@@ -3518,12 +3522,20 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
                    &expander_pg1, i, handle))) {
                        printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
                            ioc->name, __FILE__, __LINE__, __func__);
-                       continue;
+                       rc = -1;
+                       goto out_fail;
                }
                sas_expander->phy[i].handle = handle;
                sas_expander->phy[i].phy_id = i;
-               mpt2sas_transport_add_expander_phy(ioc, &sas_expander->phy[i],
-                   expander_pg1, sas_expander->parent_dev);
+
+               if ((mpt2sas_transport_add_expander_phy(ioc,
+                   &sas_expander->phy[i], expander_pg1,
+                   sas_expander->parent_dev))) {
+                       printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+                           ioc->name, __FILE__, __LINE__, __func__);
+                       rc = -1;
+                       goto out_fail;
+               }
        }
 
        if (sas_expander->enclosure_handle) {
@@ -3540,8 +3552,9 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
 
  out_fail:
 
-       if (sas_expander)
-               kfree(sas_expander->phy);
+       if (mpt2sas_port)
+               mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
+                   sas_expander->parent_handle);
        kfree(sas_expander);
        return rc;
 }
@@ -3663,12 +3676,11 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd)
        sas_device->hidden_raid_component = is_pd;
 
        /* get enclosure_logical_id */
-       if (!(mpt2sas_config_get_enclosure_pg0(ioc, &mpi_reply, &enclosure_pg0,
-          MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
-          sas_device->enclosure_handle))) {
+       if (sas_device->enclosure_handle && !(mpt2sas_config_get_enclosure_pg0(
+          ioc, &mpi_reply, &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
+          sas_device->enclosure_handle)))
                sas_device->enclosure_logical_id =
                    le64_to_cpu(enclosure_pg0.EnclosureLogicalID);
-       }
 
        /* get device name */
        sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName);
@@ -4250,12 +4262,6 @@ _scsih_sas_volume_add(struct MPT2SAS_ADAPTER *ioc,
        u16 handle = le16_to_cpu(element->VolDevHandle);
        int rc;
 
-#if 0 /* RAID_HACKS */
-       if (le32_to_cpu(event_data->Flags) &
-           MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG)
-               return;
-#endif
-
        mpt2sas_config_get_volume_wwid(ioc, handle, &wwid);
        if (!wwid) {
                printk(MPT2SAS_ERR_FMT
@@ -4310,12 +4316,6 @@ _scsih_sas_volume_delete(struct MPT2SAS_ADAPTER *ioc,
        unsigned long flags;
        struct MPT2SAS_TARGET *sas_target_priv_data;
 
-#if 0 /* RAID_HACKS */
-       if (le32_to_cpu(event_data->Flags) &
-           MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG)
-               return;
-#endif
-
        spin_lock_irqsave(&ioc->raid_device_lock, flags);
        raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
        spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
@@ -4428,14 +4428,38 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc,
        struct _sas_device *sas_device;
        unsigned long flags;
        u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
+       Mpi2ConfigReply_t mpi_reply;
+       Mpi2SasDevicePage0_t sas_device_pg0;
+       u32 ioc_status;
 
        spin_lock_irqsave(&ioc->sas_device_lock, flags);
        sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-       if (sas_device)
+       if (sas_device) {
                sas_device->hidden_raid_component = 1;
-       else
-               _scsih_add_device(ioc, handle, 0, 1);
+               return;
+       }
+
+       if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
+           MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
+               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+                   ioc->name, __FILE__, __LINE__, __func__);
+               return;
+       }
+
+       ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+           MPI2_IOCSTATUS_MASK;
+       if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+               printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+                   ioc->name, __FILE__, __LINE__, __func__);
+               return;
+       }
+
+       _scsih_link_change(ioc,
+           le16_to_cpu(sas_device_pg0.ParentDevHandle),
+           handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
+
+       _scsih_add_device(ioc, handle, 0, 1);
 }
 
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
@@ -4535,12 +4559,15 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
 {
        Mpi2EventIrConfigElement_t *element;
        int i;
+       u8 foreign_config;
 
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
        if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
                _scsih_sas_ir_config_change_event_debug(ioc, event_data);
 
 #endif
+       foreign_config = (le32_to_cpu(event_data->Flags) &
+           MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0;
 
        element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
        for (i = 0; i < event_data->NumElements; i++, element++) {
@@ -4548,11 +4575,13 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
                switch (element->ReasonCode) {
                case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
                case MPI2_EVENT_IR_CHANGE_RC_ADDED:
-                       _scsih_sas_volume_add(ioc, element);
+                       if (!foreign_config)
+                               _scsih_sas_volume_add(ioc, element);
                        break;
                case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
                case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
-                       _scsih_sas_volume_delete(ioc, element);
+                       if (!foreign_config)
+                               _scsih_sas_volume_delete(ioc, element);
                        break;
                case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
                        _scsih_sas_pd_hide(ioc, element);
@@ -4671,6 +4700,9 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
        u32 state;
        struct _sas_device *sas_device;
        unsigned long flags;
+       Mpi2ConfigReply_t mpi_reply;
+       Mpi2SasDevicePage0_t sas_device_pg0;
+       u32 ioc_status;
 
        if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
                return;
@@ -4687,22 +4719,40 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
        spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
        switch (state) {
-#if 0
-       case MPI2_RAID_PD_STATE_OFFLINE:
-               if (sas_device)
-                       _scsih_remove_device(ioc, handle);
-               break;
-#endif
        case MPI2_RAID_PD_STATE_ONLINE:
        case MPI2_RAID_PD_STATE_DEGRADED:
        case MPI2_RAID_PD_STATE_REBUILDING:
        case MPI2_RAID_PD_STATE_OPTIMAL:
-               if (sas_device)
+               if (sas_device) {
                        sas_device->hidden_raid_component = 1;
-               else
-                       _scsih_add_device(ioc, handle, 0, 1);
+                       return;
+               }
+
+               if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
+                   &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
+                   handle))) {
+                       printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+                           ioc->name, __FILE__, __LINE__, __func__);
+                       return;
+               }
+
+               ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+                   MPI2_IOCSTATUS_MASK;
+               if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+                       printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+                           ioc->name, __FILE__, __LINE__, __func__);
+                       return;
+               }
+
+               _scsih_link_change(ioc,
+                   le16_to_cpu(sas_device_pg0.ParentDevHandle),
+                   handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
+
+               _scsih_add_device(ioc, handle, 0, 1);
+
                break;
 
+       case MPI2_RAID_PD_STATE_OFFLINE:
        case MPI2_RAID_PD_STATE_NOT_CONFIGURED:
        case MPI2_RAID_PD_STATE_NOT_COMPATIBLE:
        case MPI2_RAID_PD_STATE_HOT_SPARE:
@@ -5774,6 +5824,7 @@ _scsih_suspend(struct pci_dev *pdev, pm_message_t state)
        struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
        u32 device_state;
 
+       mpt2sas_base_stop_watchdog(ioc);
        flush_scheduled_work();
        scsi_block_requests(shost);
        device_state = pci_choose_state(pdev, state);
@@ -5816,6 +5867,7 @@ _scsih_resume(struct pci_dev *pdev)
 
        mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, SOFT_RESET);
        scsi_unblock_requests(shost);
+       mpt2sas_base_start_watchdog(ioc);
        return 0;
 }
 #endif /* CONFIG_PM */
index 0a69672097a8195e3671e1d63b164c19fa0ababc..4e83c297ec9efdc191c084f913637b8aaa0e7d2f 100644 (file)
@@ -953,7 +953,12 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
 
        mutex_lock(&tz->lock);
 
-       tz->ops->get_temp(tz, &temp);
+       if (tz->ops->get_temp(tz, &temp)) {
+               /* get_temp failed - retry it later */
+               printk(KERN_WARNING PREFIX "failed to read out thermal zone "
+                      "%d\n", tz->id);
+               goto leave;
+       }
 
        for (count = 0; count < tz->trips; count++) {
                tz->ops->get_trip_type(tz, count, &trip_type);
@@ -1005,6 +1010,8 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
                                            THERMAL_TRIPS_NONE);
 
        tz->last_temperature = temp;
+
+      leave:
        if (tz->passive)
                thermal_zone_device_set_polling(tz, tz->passive_delay);
        else if (tz->polling_delay)
index 15502d5e3641890f1f6646cc661b5e26d4755753..54cd916101744ff7c5c1c21d68d4d4f6b028f066 100644 (file)
@@ -454,6 +454,10 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
 
        xenfb_init_shared_page(info, fb_info);
 
+       ret = xenfb_connect_backend(dev, info);
+       if (ret < 0)
+               goto error;
+
        ret = register_framebuffer(fb_info);
        if (ret) {
                fb_deferred_io_cleanup(fb_info);
@@ -464,10 +468,6 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
        }
        info->fb_info = fb_info;
 
-       ret = xenfb_connect_backend(dev, info);
-       if (ret < 0)
-               goto error;
-
        xenfb_make_preferred_console();
        return 0;
 
index 3fe9742c23caf3401a6844d1a5a057e7b5b35157..2f8643efe92c2eacba0657ac5b88479f5677d1c2 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/uaccess.h>
 
 #include <asm/addrspace.h>
-#include <asm/ar7/ar7.h>
+#include <asm/mach-ar7/ar7.h>
 
 #define DRVNAME "ar7_wdt"
 #define LONGNAME "TI AR7 Watchdog Timer"
index 332b5ff02fec11b8e8e43645c93ae09679ac9a61..f7003cfac63d3307b7797f4637985872a28f9a03 100644 (file)
@@ -76,7 +76,7 @@ static const match_table_t tokens = {
  * Return 0 upon success, -ERRNO upon failure.
  */
 
-static int v9fs_parse_options(struct v9fs_session_info *v9ses)
+static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
 {
        char *options;
        substring_t args[MAX_OPT_ARGS];
@@ -90,10 +90,10 @@ static int v9fs_parse_options(struct v9fs_session_info *v9ses)
        v9ses->debug = 0;
        v9ses->cache = 0;
 
-       if (!v9ses->options)
+       if (!opts)
                return 0;
 
-       options = kstrdup(v9ses->options, GFP_KERNEL);
+       options = kstrdup(opts, GFP_KERNEL);
        if (!options) {
                P9_DPRINTK(P9_DEBUG_ERROR,
                           "failed to allocate copy of option string\n");
@@ -206,24 +206,14 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
        v9ses->uid = ~0;
        v9ses->dfltuid = V9FS_DEFUID;
        v9ses->dfltgid = V9FS_DEFGID;
-       if (data) {
-               v9ses->options = kstrdup(data, GFP_KERNEL);
-               if (!v9ses->options) {
-                       P9_DPRINTK(P9_DEBUG_ERROR,
-                          "failed to allocate copy of option string\n");
-                       retval = -ENOMEM;
-                       goto error;
-               }
-       }
 
-       rc = v9fs_parse_options(v9ses);
+       rc = v9fs_parse_options(v9ses, data);
        if (rc < 0) {
                retval = rc;
                goto error;
        }
 
-       v9ses->clnt = p9_client_create(dev_name, v9ses->options);
-
+       v9ses->clnt = p9_client_create(dev_name, data);
        if (IS_ERR(v9ses->clnt)) {
                retval = PTR_ERR(v9ses->clnt);
                v9ses->clnt = NULL;
@@ -280,7 +270,6 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
 
        __putname(v9ses->uname);
        __putname(v9ses->aname);
-       kfree(v9ses->options);
 }
 
 /**
index a7d567192998e97cb292fdf313b25bea5f84fe81..38762bf102a9b04d124400ddfbb0b59daa007005 100644 (file)
@@ -85,7 +85,6 @@ struct v9fs_session_info {
        unsigned int afid;
        unsigned int cache;
 
-       char *options;          /* copy of mount options */
        char *uname;            /* user name to mount as */
        char *aname;            /* name of remote hierarchy being mounted */
        unsigned int maxdata;   /* max data for client interface */
index 81f8bbf12f9fe6867112e7e230a3862e46539455..06a223d50a8165d908e738ff293f572a896c1bca 100644 (file)
@@ -171,7 +171,6 @@ int v9fs_uflags2omode(int uflags, int extended)
 
 /**
  * v9fs_blank_wstat - helper function to setup a 9P stat structure
- * @v9ses: 9P session info (for determining extended mode)
  * @wstat: structure to initialize
  *
  */
@@ -207,65 +206,72 @@ v9fs_blank_wstat(struct p9_wstat *wstat)
 
 struct inode *v9fs_get_inode(struct super_block *sb, int mode)
 {
+       int err;
        struct inode *inode;
        struct v9fs_session_info *v9ses = sb->s_fs_info;
 
        P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %o\n", sb, mode);
 
        inode = new_inode(sb);
-       if (inode) {
-               inode->i_mode = mode;
-               inode->i_uid = current_fsuid();
-               inode->i_gid = current_fsgid();
-               inode->i_blocks = 0;
-               inode->i_rdev = 0;
-               inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-               inode->i_mapping->a_ops = &v9fs_addr_operations;
-
-               switch (mode & S_IFMT) {
-               case S_IFIFO:
-               case S_IFBLK:
-               case S_IFCHR:
-               case S_IFSOCK:
-                       if (!v9fs_extended(v9ses)) {
-                               P9_DPRINTK(P9_DEBUG_ERROR,
-                                     "special files without extended mode\n");
-                               return ERR_PTR(-EINVAL);
-                       }
-                       init_special_inode(inode, inode->i_mode,
-                                          inode->i_rdev);
-                       break;
-               case S_IFREG:
-                       inode->i_op = &v9fs_file_inode_operations;
-                       inode->i_fop = &v9fs_file_operations;
-                       break;
-               case S_IFLNK:
-                       if (!v9fs_extended(v9ses)) {
-                               P9_DPRINTK(P9_DEBUG_ERROR,
-                                       "extended modes used w/o 9P2000.u\n");
-                               return ERR_PTR(-EINVAL);
-                       }
-                       inode->i_op = &v9fs_symlink_inode_operations;
-                       break;
-               case S_IFDIR:
-                       inc_nlink(inode);
-                       if (v9fs_extended(v9ses))
-                               inode->i_op = &v9fs_dir_inode_operations_ext;
-                       else
-                               inode->i_op = &v9fs_dir_inode_operations;
-                       inode->i_fop = &v9fs_dir_operations;
-                       break;
-               default:
-                       P9_DPRINTK(P9_DEBUG_ERROR,
-                               "BAD mode 0x%x S_IFMT 0x%x\n",
-                               mode, mode & S_IFMT);
-                       return ERR_PTR(-EINVAL);
-               }
-       } else {
+       if (!inode) {
                P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n");
                return ERR_PTR(-ENOMEM);
        }
+
+       inode->i_mode = mode;
+       inode->i_uid = current_fsuid();
+       inode->i_gid = current_fsgid();
+       inode->i_blocks = 0;
+       inode->i_rdev = 0;
+       inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+       inode->i_mapping->a_ops = &v9fs_addr_operations;
+
+       switch (mode & S_IFMT) {
+       case S_IFIFO:
+       case S_IFBLK:
+       case S_IFCHR:
+       case S_IFSOCK:
+               if (!v9fs_extended(v9ses)) {
+                       P9_DPRINTK(P9_DEBUG_ERROR,
+                                  "special files without extended mode\n");
+                       err = -EINVAL;
+                       goto error;
+               }
+               init_special_inode(inode, inode->i_mode, inode->i_rdev);
+               break;
+       case S_IFREG:
+               inode->i_op = &v9fs_file_inode_operations;
+               inode->i_fop = &v9fs_file_operations;
+               break;
+       case S_IFLNK:
+               if (!v9fs_extended(v9ses)) {
+                       P9_DPRINTK(P9_DEBUG_ERROR,
+                                  "extended modes used w/o 9P2000.u\n");
+                       err = -EINVAL;
+                       goto error;
+               }
+               inode->i_op = &v9fs_symlink_inode_operations;
+               break;
+       case S_IFDIR:
+               inc_nlink(inode);
+               if (v9fs_extended(v9ses))
+                       inode->i_op = &v9fs_dir_inode_operations_ext;
+               else
+                       inode->i_op = &v9fs_dir_inode_operations;
+               inode->i_fop = &v9fs_dir_operations;
+               break;
+       default:
+               P9_DPRINTK(P9_DEBUG_ERROR, "BAD mode 0x%x S_IFMT 0x%x\n",
+                          mode, mode & S_IFMT);
+               err = -EINVAL;
+               goto error;
+       }
+
        return inode;
+
+error:
+       iput(inode);
+       return ERR_PTR(err);
 }
 
 /*
@@ -338,30 +344,25 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
 
        ret = NULL;
        st = p9_client_stat(fid);
-       if (IS_ERR(st)) {
-               err = PTR_ERR(st);
-               st = NULL;
-               goto error;
-       }
+       if (IS_ERR(st))
+               return ERR_CAST(st);
 
        umode = p9mode2unixmode(v9ses, st->mode);
        ret = v9fs_get_inode(sb, umode);
        if (IS_ERR(ret)) {
                err = PTR_ERR(ret);
-               ret = NULL;
                goto error;
        }
 
        v9fs_stat2inode(st, ret, sb);
        ret->i_ino = v9fs_qid2ino(&st->qid);
+       p9stat_free(st);
        kfree(st);
        return ret;
 
 error:
+       p9stat_free(st);
        kfree(st);
-       if (ret)
-               iput(ret);
-
        return ERR_PTR(err);
 }
 
@@ -403,9 +404,9 @@ v9fs_open_created(struct inode *inode, struct file *file)
  * @v9ses: session information
  * @dir: directory that dentry is being created in
  * @dentry:  dentry that is being created
+ * @extension: 9p2000.u extension string to support devices, etc.
  * @perm: create permissions
  * @mode: open mode
- * @extension: 9p2000.u extension string to support devices, etc.
  *
  */
 static struct p9_fid *
@@ -470,7 +471,10 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
                dentry->d_op = &v9fs_dentry_operations;
 
        d_instantiate(dentry, inode);
-       v9fs_fid_add(dentry, fid);
+       err = v9fs_fid_add(dentry, fid);
+       if (err < 0)
+               goto error;
+
        return ofid;
 
 error:
index 38d695d66a0b7899ff8c76ef21cfca4679722fa5..8961f1a8f6682bc04fbb7829f783bae29ec6a580 100644 (file)
@@ -81,7 +81,7 @@ static int v9fs_set_super(struct super_block *s, void *data)
 
 static void
 v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
-               int flags)
+               int flags, void *data)
 {
        sb->s_maxbytes = MAX_LFS_FILESIZE;
        sb->s_blocksize_bits = fls(v9ses->maxdata - 1);
@@ -91,6 +91,8 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
 
        sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC |
            MS_NOATIME;
+
+       save_mount_options(sb, data);
 }
 
 /**
@@ -113,14 +115,11 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
        struct v9fs_session_info *v9ses = NULL;
        struct p9_wstat *st = NULL;
        int mode = S_IRWXUGO | S_ISVTX;
-       uid_t uid = current_fsuid();
-       gid_t gid = current_fsgid();
        struct p9_fid *fid;
        int retval = 0;
 
        P9_DPRINTK(P9_DEBUG_VFS, " \n");
 
-       st = NULL;
        v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL);
        if (!v9ses)
                return -ENOMEM;
@@ -142,7 +141,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
                retval = PTR_ERR(sb);
                goto free_stat;
        }
-       v9fs_fill_super(sb, v9ses, flags);
+       v9fs_fill_super(sb, v9ses, flags, data);
 
        inode = v9fs_get_inode(sb, S_IFDIR | mode);
        if (IS_ERR(inode)) {
@@ -150,9 +149,6 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
                goto release_sb;
        }
 
-       inode->i_uid = uid;
-       inode->i_gid = gid;
-
        root = d_alloc_root(inode);
        if (!root) {
                iput(inode);
@@ -173,10 +169,8 @@ P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n");
        simple_set_mnt(mnt, sb);
        return 0;
 
-release_sb:
-       deactivate_locked_super(sb);
-
 free_stat:
+       p9stat_free(st);
        kfree(st);
 
 clunk_fid:
@@ -185,7 +179,12 @@ clunk_fid:
 close_session:
        v9fs_session_close(v9ses);
        kfree(v9ses);
+       return retval;
 
+release_sb:
+       p9stat_free(st);
+       kfree(st);
+       deactivate_locked_super(sb);
        return retval;
 }
 
@@ -207,24 +206,10 @@ static void v9fs_kill_super(struct super_block *s)
 
        v9fs_session_close(v9ses);
        kfree(v9ses);
+       s->s_fs_info = NULL;
        P9_DPRINTK(P9_DEBUG_VFS, "exiting kill_super\n");
 }
 
-/**
- * v9fs_show_options - Show mount options in /proc/mounts
- * @m: seq_file to write to
- * @mnt: mount descriptor
- *
- */
-
-static int v9fs_show_options(struct seq_file *m, struct vfsmount *mnt)
-{
-       struct v9fs_session_info *v9ses = mnt->mnt_sb->s_fs_info;
-
-       seq_printf(m, "%s", v9ses->options);
-       return 0;
-}
-
 static void
 v9fs_umount_begin(struct super_block *sb)
 {
@@ -237,7 +222,7 @@ v9fs_umount_begin(struct super_block *sb)
 static const struct super_operations v9fs_super_ops = {
        .statfs = simple_statfs,
        .clear_inode = v9fs_clear_inode,
-       .show_options = v9fs_show_options,
+       .show_options = generic_show_options,
        .umount_begin = v9fs_umount_begin,
 };
 
index 0149dab365e722c95f466e7e5d17f94cab8b9e70..681c2a7b013fc3c06bfa2d0d75d05804eafb8ffb 100644 (file)
@@ -134,9 +134,16 @@ static int afs_readpage(struct file *file, struct page *page)
 
        inode = page->mapping->host;
 
-       ASSERT(file != NULL);
-       key = file->private_data;
-       ASSERT(key != NULL);
+       if (file) {
+               key = file->private_data;
+               ASSERT(key != NULL);
+       } else {
+               key = afs_request_key(AFS_FS_S(inode->i_sb)->volume->cell);
+               if (IS_ERR(key)) {
+                       ret = PTR_ERR(key);
+                       goto error_nokey;
+               }
+       }
 
        _enter("{%x},{%lu},{%lu}", key_serial(key), inode->i_ino, page->index);
 
@@ -207,12 +214,17 @@ static int afs_readpage(struct file *file, struct page *page)
                unlock_page(page);
        }
 
+       if (!file)
+               key_put(key);
        _leave(" = 0");
        return 0;
 
 error:
        SetPageError(page);
        unlock_page(page);
+       if (!file)
+               key_put(key);
+error_nokey:
        _leave(" = %d", ret);
        return ret;
 }
index aa39ae83f0193da10f0b218954ae8ec9cf149cb3..3da18d4534881a199dccfa223d77c3019c813269 100644 (file)
@@ -77,7 +77,7 @@ static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
        }
 
        /* Update the expiry counter if fs is busy */
-       if (!may_umount_tree(mnt)) {
+       if (!may_umount_tree(path.mnt)) {
                struct autofs_info *ino = autofs4_dentry_ino(top);
                ino->last_used = jiffies;
                goto done;
index 272b9b2bea86de6f4aa1fc3182ae616bf5238dbf..59cba180fe833f08f815f4ca968956eaa7f33e18 100644 (file)
@@ -3099,8 +3099,12 @@ static void inode_tree_add(struct inode *inode)
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_inode *entry;
-       struct rb_node **p = &root->inode_tree.rb_node;
-       struct rb_node *parent = NULL;
+       struct rb_node **p;
+       struct rb_node *parent;
+
+again:
+       p = &root->inode_tree.rb_node;
+       parent = NULL;
 
        spin_lock(&root->inode_lock);
        while (*p) {
@@ -3108,13 +3112,16 @@ static void inode_tree_add(struct inode *inode)
                entry = rb_entry(parent, struct btrfs_inode, rb_node);
 
                if (inode->i_ino < entry->vfs_inode.i_ino)
-                       p = &(*p)->rb_left;
+                       p = &parent->rb_left;
                else if (inode->i_ino > entry->vfs_inode.i_ino)
-                       p = &(*p)->rb_right;
+                       p = &parent->rb_right;
                else {
                        WARN_ON(!(entry->vfs_inode.i_state &
                                  (I_WILL_FREE | I_FREEING | I_CLEAR)));
-                       break;
+                       rb_erase(parent, &root->inode_tree);
+                       RB_CLEAR_NODE(parent);
+                       spin_unlock(&root->inode_lock);
+                       goto again;
                }
        }
        rb_link_node(&BTRFS_I(inode)->rb_node, parent, p);
@@ -3126,12 +3133,12 @@ static void inode_tree_del(struct inode *inode)
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
 
+       spin_lock(&root->inode_lock);
        if (!RB_EMPTY_NODE(&BTRFS_I(inode)->rb_node)) {
-               spin_lock(&root->inode_lock);
                rb_erase(&BTRFS_I(inode)->rb_node, &root->inode_tree);
-               spin_unlock(&root->inode_lock);
                RB_CLEAR_NODE(&BTRFS_I(inode)->rb_node);
        }
+       spin_unlock(&root->inode_lock);
 }
 
 static noinline void init_btrfs_i(struct inode *inode)
index a3ef091a45bd4664e5ba5e683f9329bda3d1d3df..28f320fac4d4261ec8626d0cfe221be83778c20e 100644 (file)
@@ -1165,8 +1165,11 @@ void mark_buffer_dirty(struct buffer_head *bh)
 
        if (!test_set_buffer_dirty(bh)) {
                struct page *page = bh->b_page;
-               if (!TestSetPageDirty(page))
-                       __set_page_dirty(page, page_mapping(page), 0);
+               if (!TestSetPageDirty(page)) {
+                       struct address_space *mapping = page_mapping(page);
+                       if (mapping)
+                               __set_page_dirty(page, mapping, 0);
+               }
        }
 }
 
index 94502dab972af5ad4d2bd558f50f896cd8a35db3..6d6f98fe64a086ae02c864d1e93ab3b597ef216e 100644 (file)
@@ -1485,20 +1485,15 @@ int compat_do_execve(char * filename,
        if (!bprm)
                goto out_files;
 
-       retval = -ERESTARTNOINTR;
-       if (mutex_lock_interruptible(&current->cred_guard_mutex))
+       retval = prepare_bprm_creds(bprm);
+       if (retval)
                goto out_free;
-       current->in_execve = 1;
-
-       retval = -ENOMEM;
-       bprm->cred = prepare_exec_creds();
-       if (!bprm->cred)
-               goto out_unlock;
 
        retval = check_unsafe_exec(bprm);
        if (retval < 0)
-               goto out_unlock;
+               goto out_free;
        clear_in_exec = retval;
+       current->in_execve = 1;
 
        file = open_exec(filename);
        retval = PTR_ERR(file);
@@ -1547,7 +1542,6 @@ int compat_do_execve(char * filename,
        /* execve succeeded */
        current->fs->in_exec = 0;
        current->in_execve = 0;
-       mutex_unlock(&current->cred_guard_mutex);
        acct_update_integrals(current);
        free_bprm(bprm);
        if (displaced)
@@ -1567,10 +1561,7 @@ out_file:
 out_unmark:
        if (clear_in_exec)
                current->fs->in_exec = 0;
-
-out_unlock:
        current->in_execve = 0;
-       mutex_unlock(&current->cred_guard_mutex);
 
 out_free:
        free_bprm(bprm);
index 4a8849e45b2191ef5a91821ad3b47d0588e7b12b..172ceb6edde4df6ff8520cd9951b3bc2ca86b2c2 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -678,8 +678,8 @@ exit:
 }
 EXPORT_SYMBOL(open_exec);
 
-int kernel_read(struct file *file, unsigned long offset,
-       char *addr, unsigned long count)
+int kernel_read(struct file *file, loff_t offset,
+               char *addr, unsigned long count)
 {
        mm_segment_t old_fs;
        loff_t pos = offset;
@@ -1015,6 +1015,35 @@ out:
 
 EXPORT_SYMBOL(flush_old_exec);
 
+/*
+ * Prepare credentials and lock ->cred_guard_mutex.
+ * install_exec_creds() commits the new creds and drops the lock.
+ * Or, if exec fails before, free_bprm() should release ->cred and
+ * and unlock.
+ */
+int prepare_bprm_creds(struct linux_binprm *bprm)
+{
+       if (mutex_lock_interruptible(&current->cred_guard_mutex))
+               return -ERESTARTNOINTR;
+
+       bprm->cred = prepare_exec_creds();
+       if (likely(bprm->cred))
+               return 0;
+
+       mutex_unlock(&current->cred_guard_mutex);
+       return -ENOMEM;
+}
+
+void free_bprm(struct linux_binprm *bprm)
+{
+       free_arg_pages(bprm);
+       if (bprm->cred) {
+               mutex_unlock(&current->cred_guard_mutex);
+               abort_creds(bprm->cred);
+       }
+       kfree(bprm);
+}
+
 /*
  * install the new credentials for this executable
  */
@@ -1024,12 +1053,13 @@ void install_exec_creds(struct linux_binprm *bprm)
 
        commit_creds(bprm->cred);
        bprm->cred = NULL;
-
-       /* cred_guard_mutex must be held at least to this point to prevent
+       /*
+        * cred_guard_mutex must be held at least to this point to prevent
         * ptrace_attach() from altering our determination of the task's
-        * credentials; any time after this it may be unlocked */
-
+        * credentials; any time after this it may be unlocked.
+        */
        security_bprm_committed_creds(bprm);
+       mutex_unlock(&current->cred_guard_mutex);
 }
 EXPORT_SYMBOL(install_exec_creds);
 
@@ -1246,14 +1276,6 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
 
 EXPORT_SYMBOL(search_binary_handler);
 
-void free_bprm(struct linux_binprm *bprm)
-{
-       free_arg_pages(bprm);
-       if (bprm->cred)
-               abort_creds(bprm->cred);
-       kfree(bprm);
-}
-
 /*
  * sys_execve() executes a new program.
  */
@@ -1277,20 +1299,15 @@ int do_execve(char * filename,
        if (!bprm)
                goto out_files;
 
-       retval = -ERESTARTNOINTR;
-       if (mutex_lock_interruptible(&current->cred_guard_mutex))
+       retval = prepare_bprm_creds(bprm);
+       if (retval)
                goto out_free;
-       current->in_execve = 1;
-
-       retval = -ENOMEM;
-       bprm->cred = prepare_exec_creds();
-       if (!bprm->cred)
-               goto out_unlock;
 
        retval = check_unsafe_exec(bprm);
        if (retval < 0)
-               goto out_unlock;
+               goto out_free;
        clear_in_exec = retval;
+       current->in_execve = 1;
 
        file = open_exec(filename);
        retval = PTR_ERR(file);
@@ -1340,7 +1357,6 @@ int do_execve(char * filename,
        /* execve succeeded */
        current->fs->in_exec = 0;
        current->in_execve = 0;
-       mutex_unlock(&current->cred_guard_mutex);
        acct_update_integrals(current);
        free_bprm(bprm);
        if (displaced)
@@ -1360,10 +1376,7 @@ out_file:
 out_unmark:
        if (clear_in_exec)
                current->fs->in_exec = 0;
-
-out_unlock:
        current->in_execve = 0;
-       mutex_unlock(&current->cred_guard_mutex);
 
 out_free:
        free_bprm(bprm);
index e1dedb0f7873153199073e360dfbf255c13115c0..78d9b925fc94dc7e35d1abe920dcdeeaff92bead 100644 (file)
@@ -362,6 +362,10 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
        if (dir_de) {
                if (old_dir != new_dir)
                        ext2_set_link(old_inode, dir_de, dir_page, new_dir, 0);
+               else {
+                       kunmap(dir_page);
+                       page_cache_release(dir_page);
+               }
                inode_dec_link_count(old_dir);
        }
        return 0;
index fb3c1a21b13594d1edf76fd09e6fdc35b0a5f216..522b15498f459da163b2318348108569f1f34a92 100644 (file)
@@ -29,23 +29,25 @@ config EXT3_FS
          module will be called ext3.
 
 config EXT3_DEFAULTS_TO_ORDERED
-       bool "Default to 'data=ordered' in ext3 (legacy option)"
+       bool "Default to 'data=ordered' in ext3"
        depends on EXT3_FS
        help
-         If a filesystem does not explicitly specify a data ordering
-         mode, and the journal capability allowed it, ext3 used to
-         historically default to 'data=ordered'.
-
-         That was a rather unfortunate choice, because it leads to all
-         kinds of latency problems, and the 'data=writeback' mode is more
-         appropriate these days.
-
-         You should probably always answer 'n' here, and if you really
-         want to use 'data=ordered' mode, set it in the filesystem itself
-         with 'tune2fs -o journal_data_ordered'.
-
-         But if you really want to enable the legacy default, you can do
-         so by answering 'y' to this question.
+         The journal mode options for ext3 have different tradeoffs
+         between when data is guaranteed to be on disk and
+         performance.  The use of "data=writeback" can cause
+         unwritten data to appear in files after an system crash or
+         power failure, which can be a security issue.  However,
+         "data=ordered" mode can also result in major performance
+         problems, including seconds-long delays before an fsync()
+         call returns.  For details, see:
+
+         http://ext4.wiki.kernel.org/index.php/Ext3_data_mode_tradeoffs
+
+         If you have been historically happy with ext3's performance,
+         data=ordered mode will be a safe choice and you should
+         answer 'y' here.  If you understand the reliability and data
+         privacy issues of data=writeback and are willing to make
+         that trade off, answer 'n'.
 
 config EXT3_FS_XATTR
        bool "Ext3 extended attributes"
index 524b349c6299ca248b366cf299071939e5843aba..a8d80a7f11050d7a518e79ac003701d12865b3a7 100644 (file)
@@ -543,6 +543,19 @@ static inline void ext3_show_quota_options(struct seq_file *seq, struct super_bl
 #endif
 }
 
+static char *data_mode_string(unsigned long mode)
+{
+       switch (mode) {
+       case EXT3_MOUNT_JOURNAL_DATA:
+               return "journal";
+       case EXT3_MOUNT_ORDERED_DATA:
+               return "ordered";
+       case EXT3_MOUNT_WRITEBACK_DATA:
+               return "writeback";
+       }
+       return "unknown";
+}
+
 /*
  * Show an option if
  *  - it's set to a non-default value OR
@@ -616,13 +629,8 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
        if (test_opt(sb, NOBH))
                seq_puts(seq, ",nobh");
 
-       if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_JOURNAL_DATA)
-               seq_puts(seq, ",data=journal");
-       else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA)
-               seq_puts(seq, ",data=ordered");
-       else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)
-               seq_puts(seq, ",data=writeback");
-
+       seq_printf(seq, ",data=%s", data_mode_string(sbi->s_mount_opt &
+                                                    EXT3_MOUNT_DATA_FLAGS));
        if (test_opt(sb, DATA_ERR_ABORT))
                seq_puts(seq, ",data_err=abort");
 
@@ -1024,12 +1032,18 @@ static int parse_options (char *options, struct super_block *sb,
                datacheck:
                        if (is_remount) {
                                if ((sbi->s_mount_opt & EXT3_MOUNT_DATA_FLAGS)
-                                               != data_opt) {
-                                       printk(KERN_ERR
-                                               "EXT3-fs: cannot change data "
-                                               "mode on remount\n");
-                                       return 0;
-                               }
+                                               == data_opt)
+                                       break;
+                               printk(KERN_ERR
+                                       "EXT3-fs (device %s): Cannot change "
+                                       "data mode on remount. The filesystem "
+                                       "is mounted in data=%s mode and you "
+                                       "try to remount it in data=%s mode.\n",
+                                       sb->s_id,
+                                       data_mode_string(sbi->s_mount_opt &
+                                                       EXT3_MOUNT_DATA_FLAGS),
+                                       data_mode_string(data_opt));
+                               return 0;
                        } else {
                                sbi->s_mount_opt &= ~EXT3_MOUNT_DATA_FLAGS;
                                sbi->s_mount_opt |= data_opt;
index 941c8425c10b34493e9ad6fefef7fe54f451c84a..cb88dac8ccaae6f43dfc25edbcaa202fa0cb26cb 100644 (file)
@@ -935,26 +935,28 @@ static int can_do_hugetlb_shm(void)
        return capable(CAP_IPC_LOCK) || in_group_p(sysctl_hugetlb_shm_group);
 }
 
-struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag)
+struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag,
+                                               struct user_struct **user)
 {
        int error = -ENOMEM;
-       int unlock_shm = 0;
        struct file *file;
        struct inode *inode;
        struct dentry *dentry, *root;
        struct qstr quick_string;
-       struct user_struct *user = current_user();
 
+       *user = NULL;
        if (!hugetlbfs_vfsmount)
                return ERR_PTR(-ENOENT);
 
        if (!can_do_hugetlb_shm()) {
-               if (user_shm_lock(size, user)) {
-                       unlock_shm = 1;
+               *user = current_user();
+               if (user_shm_lock(size, *user)) {
                        WARN_ONCE(1,
                          "Using mlock ulimits for SHM_HUGETLB deprecated\n");
-               } else
+               } else {
+                       *user = NULL;
                        return ERR_PTR(-EPERM);
+               }
        }
 
        root = hugetlbfs_vfsmount->mnt_root;
@@ -996,8 +998,10 @@ out_inode:
 out_dentry:
        dput(dentry);
 out_shm_unlock:
-       if (unlock_shm)
-               user_shm_unlock(size, user);
+       if (*user) {
+               user_shm_unlock(size, *user);
+               *user = NULL;
+       }
        return ERR_PTR(error);
 }
 
index d9a721e6db70139073ca055cbea471769f6a83dd..5ef7bac265e5238495e7da7d8470fac62f922b66 100644 (file)
@@ -1268,10 +1268,20 @@ int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c) {
        if (!c->wbuf)
                return -ENOMEM;
 
+#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
+       c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
+       if (!c->wbuf_verify) {
+               kfree(c->wbuf);
+               return -ENOMEM;
+       }
+#endif
        return 0;
 }
 
 void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c) {
+#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
+       kfree(c->wbuf_verify);
+#endif
        kfree(c->wbuf);
 }
 
index ee01308a01d1c09e320c7deb97dbfbb6af9c0542..fcfc5539252c2acec1bb80c71216e17baa86d8d5 100644 (file)
@@ -1544,28 +1544,31 @@ int may_open(struct path *path, int acc_mode, int flag)
         * An append-only file must be opened in append mode for writing.
         */
        if (IS_APPEND(inode)) {
+               error = -EPERM;
                if  ((flag & FMODE_WRITE) && !(flag & O_APPEND))
-                       return -EPERM;
+                       goto err_out;
                if (flag & O_TRUNC)
-                       return -EPERM;
+                       goto err_out;
        }
 
        /* O_NOATIME can only be set by the owner or superuser */
        if (flag & O_NOATIME)
-               if (!is_owner_or_cap(inode))
-                       return -EPERM;
+               if (!is_owner_or_cap(inode)) {
+                       error = -EPERM;
+                       goto err_out;
+               }
 
        /*
         * Ensure there are no outstanding leases on the file.
         */
        error = break_lease(inode, flag);
        if (error)
-               return error;
+               goto err_out;
 
        if (flag & O_TRUNC) {
                error = get_write_access(inode);
                if (error)
-                       return error;
+                       goto err_out;
 
                /*
                 * Refuse to truncate files with mandatory locks held on them.
@@ -1583,12 +1586,17 @@ int may_open(struct path *path, int acc_mode, int flag)
                }
                put_write_access(inode);
                if (error)
-                       return error;
+                       goto err_out;
        } else
                if (flag & FMODE_WRITE)
                        vfs_dq_init(inode);
 
        return 0;
+err_out:
+       ima_counts_put(path, acc_mode ?
+                      acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC) :
+                      ACC_MODE(flag) & (MAY_READ | MAY_WRITE));
+       return error;
 }
 
 /*
index 65ca8c18476fb3d1e437fed82685f50d824a92c5..1434080aefeb22e77896c4f2a18f26e77df535bc 100644 (file)
@@ -1250,8 +1250,8 @@ static void nfs4_state_manager(struct nfs_client *clp)
                                continue;
                }
                /* Initialize or reset the session */
-               if (nfs4_has_session(clp) &&
-                  test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) {
+               if (test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)
+                  && nfs4_has_session(clp)) {
                        if (clp->cl_cons_state == NFS_CS_SESSION_INITING)
                                status = nfs4_initialize_session(clp);
                        else
index 7e0b61be212e8a18476518db9507d2d018f7fed6..c668bca579c1baca6c25fc345462d881b227edb4 100644 (file)
@@ -209,6 +209,7 @@ int nilfs_btnode_prepare_change_key(struct address_space *btnc,
                 * We cannot call radix_tree_preload for the kernels older
                 * than 2.6.23, because it is not exported for modules.
                 */
+retry:
                err = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM);
                if (err)
                        goto failed_unlock;
@@ -219,7 +220,6 @@ int nilfs_btnode_prepare_change_key(struct address_space *btnc,
                                       (unsigned long long)oldkey,
                                       (unsigned long long)newkey);
 
-retry:
                spin_lock_irq(&btnc->tree_lock);
                err = radix_tree_insert(&btnc->page_tree, newkey, obh->b_page);
                spin_unlock_irq(&btnc->tree_lock);
index 5dcbafe72d71731e3fb2f540f26406e8662580af..c9ee67b442e17b7713c8d1ca481b0ec22271b0f8 100644 (file)
@@ -105,16 +105,45 @@ static bool inotify_should_send_event(struct fsnotify_group *group, struct inode
        return send;
 }
 
+/*
+ * This is NEVER supposed to be called.  Inotify marks should either have been
+ * removed from the idr when the watch was removed or in the
+ * fsnotify_destroy_mark_by_group() call when the inotify instance was being
+ * torn down.  This is only called if the idr is about to be freed but there
+ * are still marks in it.
+ */
 static int idr_callback(int id, void *p, void *data)
 {
-       BUG();
+       struct fsnotify_mark_entry *entry;
+       struct inotify_inode_mark_entry *ientry;
+       static bool warned = false;
+
+       if (warned)
+               return 0;
+
+       warned = false;
+       entry = p;
+       ientry = container_of(entry, struct inotify_inode_mark_entry, fsn_entry);
+
+       WARN(1, "inotify closing but id=%d for entry=%p in group=%p still in "
+               "idr.  Probably leaking memory\n", id, p, data);
+
+       /*
+        * I'm taking the liberty of assuming that the mark in question is a
+        * valid address and I'm dereferencing it.  This might help to figure
+        * out why we got here and the panic is no worse than the original
+        * BUG() that was here.
+        */
+       if (entry)
+               printk(KERN_WARNING "entry->group=%p inode=%p wd=%d\n",
+                       entry->group, entry->inode, ientry->wd);
        return 0;
 }
 
 static void inotify_free_group_priv(struct fsnotify_group *group)
 {
        /* ideally the idr is empty and we won't hit the BUG in teh callback */
-       idr_for_each(&group->inotify_data.idr, idr_callback, NULL);
+       idr_for_each(&group->inotify_data.idr, idr_callback, group);
        idr_remove_all(&group->inotify_data.idr);
        idr_destroy(&group->inotify_data.idr);
 }
index dc32ed8323ba85075190590ae081846ab99bf62a..dcd2040d330c4397d8cfdaa78a9c27dd990fe9ad 100644 (file)
@@ -47,9 +47,6 @@
 
 static struct vfsmount *inotify_mnt __read_mostly;
 
-/* this just sits here and wastes global memory.  used to just pad userspace messages with zeros */
-static struct inotify_event nul_inotify_event;
-
 /* these are configurable via /proc/sys/fs/inotify/ */
 static int inotify_max_user_instances __read_mostly;
 static int inotify_max_queued_events __read_mostly;
@@ -157,7 +154,8 @@ static struct fsnotify_event *get_one_event(struct fsnotify_group *group,
 
        event = fsnotify_peek_notify_event(group);
 
-       event_size += roundup(event->name_len, event_size);
+       if (event->name_len)
+               event_size += roundup(event->name_len + 1, event_size);
 
        if (event_size > count)
                return ERR_PTR(-EINVAL);
@@ -183,7 +181,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
        struct fsnotify_event_private_data *fsn_priv;
        struct inotify_event_private_data *priv;
        size_t event_size = sizeof(struct inotify_event);
-       size_t name_len;
+       size_t name_len = 0;
 
        /* we get the inotify watch descriptor from the event private data */
        spin_lock(&event->lock);
@@ -199,8 +197,12 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
                inotify_free_event_priv(fsn_priv);
        }
 
-       /* round up event->name_len so it is a multiple of event_size */
-       name_len = roundup(event->name_len, event_size);
+       /*
+        * round up event->name_len so it is a multiple of event_size
+        * plus an extra byte for the terminating '\0'.
+        */
+       if (event->name_len)
+               name_len = roundup(event->name_len + 1, event_size);
        inotify_event.len = name_len;
 
        inotify_event.mask = inotify_mask_to_arg(event->mask);
@@ -224,8 +226,8 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
                        return -EFAULT;
                buf += event->name_len;
 
-               /* fill userspace with 0's from nul_inotify_event */
-               if (copy_to_user(buf, &nul_inotify_event, len_to_zero))
+               /* fill userspace with 0's */
+               if (clear_user(buf, len_to_zero))
                        return -EFAULT;
                buf += len_to_zero;
                event_size += name_len;
@@ -326,8 +328,9 @@ static long inotify_ioctl(struct file *file, unsigned int cmd,
                list_for_each_entry(holder, &group->notification_list, event_list) {
                        event = holder->event;
                        send_len += sizeof(struct inotify_event);
-                       send_len += roundup(event->name_len,
-                                            sizeof(struct inotify_event));
+                       if (event->name_len)
+                               send_len += roundup(event->name_len + 1,
+                                               sizeof(struct inotify_event));
                }
                mutex_unlock(&group->notification_mutex);
                ret = put_user(send_len, (int __user *) p);
@@ -364,20 +367,53 @@ static int inotify_find_inode(const char __user *dirname, struct path *path, uns
        return error;
 }
 
+/*
+ * Remove the mark from the idr (if present) and drop the reference
+ * on the mark because it was in the idr.
+ */
 static void inotify_remove_from_idr(struct fsnotify_group *group,
                                    struct inotify_inode_mark_entry *ientry)
 {
        struct idr *idr;
+       struct fsnotify_mark_entry *entry;
+       struct inotify_inode_mark_entry *found_ientry;
+       int wd;
 
        spin_lock(&group->inotify_data.idr_lock);
        idr = &group->inotify_data.idr;
-       idr_remove(idr, ientry->wd);
-       spin_unlock(&group->inotify_data.idr_lock);
+       wd = ientry->wd;
+
+       if (wd == -1)
+               goto out;
+
+       entry = idr_find(&group->inotify_data.idr, wd);
+       if (unlikely(!entry))
+               goto out;
+
+       found_ientry = container_of(entry, struct inotify_inode_mark_entry, fsn_entry);
+       if (unlikely(found_ientry != ientry)) {
+               /* We found an entry in the idr with the right wd, but it's
+                * not the entry we were told to remove.  eparis seriously
+                * fucked up somewhere. */
+               WARN_ON(1);
+               ientry->wd = -1;
+               goto out;
+       }
+
+       /* One ref for being in the idr, one ref held by the caller */
+       BUG_ON(atomic_read(&entry->refcnt) < 2);
+
+       idr_remove(idr, wd);
        ientry->wd = -1;
+
+       /* removed from the idr, drop that ref */
+       fsnotify_put_mark(entry);
+out:
+       spin_unlock(&group->inotify_data.idr_lock);
 }
+
 /*
- * Send IN_IGNORED for this wd, remove this wd from the idr, and drop the
- * internal reference help on the mark because it is in the idr.
+ * Send IN_IGNORED for this wd, remove this wd from the idr.
  */
 void inotify_ignored_and_remove_idr(struct fsnotify_mark_entry *entry,
                                    struct fsnotify_group *group)
@@ -417,9 +453,6 @@ skip_send_ignore:
        /* remove this entry from the idr */
        inotify_remove_from_idr(group, ientry);
 
-       /* removed from idr, drop that reference */
-       fsnotify_put_mark(entry);
-
        atomic_dec(&group->inotify_data.user->inotify_watches);
 }
 
@@ -431,80 +464,29 @@ static void inotify_free_mark(struct fsnotify_mark_entry *entry)
        kmem_cache_free(inotify_inode_mark_cachep, ientry);
 }
 
-static int inotify_update_watch(struct fsnotify_group *group, struct inode *inode, u32 arg)
+static int inotify_update_existing_watch(struct fsnotify_group *group,
+                                        struct inode *inode,
+                                        u32 arg)
 {
-       struct fsnotify_mark_entry *entry = NULL;
+       struct fsnotify_mark_entry *entry;
        struct inotify_inode_mark_entry *ientry;
-       struct inotify_inode_mark_entry *tmp_ientry;
-       int ret = 0;
-       int add = (arg & IN_MASK_ADD);
-       __u32 mask;
        __u32 old_mask, new_mask;
+       __u32 mask;
+       int add = (arg & IN_MASK_ADD);
+       int ret;
 
        /* don't allow invalid bits: we don't want flags set */
        mask = inotify_arg_to_mask(arg);
        if (unlikely(!mask))
                return -EINVAL;
 
-       tmp_ientry = kmem_cache_alloc(inotify_inode_mark_cachep, GFP_KERNEL);
-       if (unlikely(!tmp_ientry))
-               return -ENOMEM;
-       /* we set the mask at the end after attaching it */
-       fsnotify_init_mark(&tmp_ientry->fsn_entry, inotify_free_mark);
-       tmp_ientry->wd = -1;
-
-find_entry:
        spin_lock(&inode->i_lock);
        entry = fsnotify_find_mark_entry(group, inode);
        spin_unlock(&inode->i_lock);
-       if (entry) {
-               ientry = container_of(entry, struct inotify_inode_mark_entry, fsn_entry);
-       } else {
-               ret = -ENOSPC;
-               if (atomic_read(&group->inotify_data.user->inotify_watches) >= inotify_max_user_watches)
-                       goto out_err;
-retry:
-               ret = -ENOMEM;
-               if (unlikely(!idr_pre_get(&group->inotify_data.idr, GFP_KERNEL)))
-                       goto out_err;
-
-               spin_lock(&group->inotify_data.idr_lock);
-               ret = idr_get_new_above(&group->inotify_data.idr, &tmp_ientry->fsn_entry,
-                                       group->inotify_data.last_wd,
-                                       &tmp_ientry->wd);
-               spin_unlock(&group->inotify_data.idr_lock);
-               if (ret) {
-                       if (ret == -EAGAIN)
-                               goto retry;
-                       goto out_err;
-               }
-
-               ret = fsnotify_add_mark(&tmp_ientry->fsn_entry, group, inode);
-               if (ret) {
-                       inotify_remove_from_idr(group, tmp_ientry);
-                       if (ret == -EEXIST)
-                               goto find_entry;
-                       goto out_err;
-               }
-
-               /* tmp_ientry has been added to the inode, so we are all set up.
-                * now we just need to make sure tmp_ientry doesn't get freed and
-                * we need to set up entry and ientry so the generic code can
-                * do its thing. */
-               ientry = tmp_ientry;
-               entry = &ientry->fsn_entry;
-               tmp_ientry = NULL;
-
-               atomic_inc(&group->inotify_data.user->inotify_watches);
-
-               /* update the idr hint */
-               group->inotify_data.last_wd = ientry->wd;
-
-               /* we put the mark on the idr, take a reference */
-               fsnotify_get_mark(entry);
-       }
+       if (!entry)
+               return -ENOENT;
 
-       ret = ientry->wd;
+       ientry = container_of(entry, struct inotify_inode_mark_entry, fsn_entry);
 
        spin_lock(&entry->lock);
 
@@ -536,18 +518,107 @@ retry:
                        fsnotify_recalc_group_mask(group);
        }
 
-       /* this either matches fsnotify_find_mark_entry, or init_mark_entry
-        * depending on which path we took... */
+       /* return the wd */
+       ret = ientry->wd;
+
+       /* match the get from fsnotify_find_mark_entry() */
        fsnotify_put_mark(entry);
 
+       return ret;
+}
+
+static int inotify_new_watch(struct fsnotify_group *group,
+                            struct inode *inode,
+                            u32 arg)
+{
+       struct inotify_inode_mark_entry *tmp_ientry;
+       __u32 mask;
+       int ret;
+
+       /* don't allow invalid bits: we don't want flags set */
+       mask = inotify_arg_to_mask(arg);
+       if (unlikely(!mask))
+               return -EINVAL;
+
+       tmp_ientry = kmem_cache_alloc(inotify_inode_mark_cachep, GFP_KERNEL);
+       if (unlikely(!tmp_ientry))
+               return -ENOMEM;
+
+       fsnotify_init_mark(&tmp_ientry->fsn_entry, inotify_free_mark);
+       tmp_ientry->fsn_entry.mask = mask;
+       tmp_ientry->wd = -1;
+
+       ret = -ENOSPC;
+       if (atomic_read(&group->inotify_data.user->inotify_watches) >= inotify_max_user_watches)
+               goto out_err;
+retry:
+       ret = -ENOMEM;
+       if (unlikely(!idr_pre_get(&group->inotify_data.idr, GFP_KERNEL)))
+               goto out_err;
+
+       spin_lock(&group->inotify_data.idr_lock);
+       ret = idr_get_new_above(&group->inotify_data.idr, &tmp_ientry->fsn_entry,
+                               group->inotify_data.last_wd,
+                               &tmp_ientry->wd);
+       spin_unlock(&group->inotify_data.idr_lock);
+       if (ret) {
+               /* idr was out of memory allocate and try again */
+               if (ret == -EAGAIN)
+                       goto retry;
+               goto out_err;
+       }
+
+       /* we put the mark on the idr, take a reference */
+       fsnotify_get_mark(&tmp_ientry->fsn_entry);
+
+       /* we are on the idr, now get on the inode */
+       ret = fsnotify_add_mark(&tmp_ientry->fsn_entry, group, inode);
+       if (ret) {
+               /* we failed to get on the inode, get off the idr */
+               inotify_remove_from_idr(group, tmp_ientry);
+               goto out_err;
+       }
+
+       /* update the idr hint, who cares about races, it's just a hint */
+       group->inotify_data.last_wd = tmp_ientry->wd;
+
+       /* increment the number of watches the user has */
+       atomic_inc(&group->inotify_data.user->inotify_watches);
+
+       /* return the watch descriptor for this new entry */
+       ret = tmp_ientry->wd;
+
+       /* match the ref from fsnotify_init_markentry() */
+       fsnotify_put_mark(&tmp_ientry->fsn_entry);
+
+       /* if this mark added a new event update the group mask */
+       if (mask & ~group->mask)
+               fsnotify_recalc_group_mask(group);
+
 out_err:
-       /* could be an error, could be that we found an existing mark */
-       if (tmp_ientry) {
-               /* on the idr but didn't make it on the inode */
-               if (tmp_ientry->wd != -1)
-                       inotify_remove_from_idr(group, tmp_ientry);
+       if (ret < 0)
                kmem_cache_free(inotify_inode_mark_cachep, tmp_ientry);
-       }
+
+       return ret;
+}
+
+static int inotify_update_watch(struct fsnotify_group *group, struct inode *inode, u32 arg)
+{
+       int ret = 0;
+
+retry:
+       /* try to update and existing watch with the new arg */
+       ret = inotify_update_existing_watch(group, inode, arg);
+       /* no mark present, try to add a new one */
+       if (ret == -ENOENT)
+               ret = inotify_new_watch(group, inode, arg);
+       /*
+        * inotify_new_watch could race with another thread which did an
+        * inotify_new_watch between the update_existing and the add watch
+        * here, go back and try to update an existing mark again.
+        */
+       if (ret == -EEXIST)
+               goto retry;
 
        return ret;
 }
index f9a3e8942669f436ad64fa00b550a46f34cd44be..ab513ddaeff2f6944c5f0d54356e7484fa63cfeb 100644 (file)
@@ -6851,7 +6851,7 @@ static int ocfs2_do_truncate(struct ocfs2_super *osb,
        }
        status = 0;
 bail:
-
+       brelse(last_eb_bh);
        mlog_exit(status);
        return status;
 }
index b401654011a2b64c4e55f87c7916e3badc07f68e..8a1e61545f4169de491eb00ee6c661ebf0054a30 100644 (file)
@@ -1747,8 +1747,8 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
         * we know zeros will only be needed in the first and/or last cluster.
         */
        if (clusters_to_alloc || extents_to_split ||
-           wc->w_desc[0].c_needs_zero ||
-           wc->w_desc[wc->w_clen - 1].c_needs_zero)
+           (wc->w_clen && (wc->w_desc[0].c_needs_zero ||
+                           wc->w_desc[wc->w_clen - 1].c_needs_zero)))
                cluster_of_pages = 1;
        else
                cluster_of_pages = 0;
index 2f28b7de2c8d2cae30d052e54fc12fa7e91c740f..b4957c7d9fe2262a203a3efb3573eda9ed3d2638 100644 (file)
@@ -85,6 +85,17 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry,
                goto bail;
        }
 
+       /*
+        * If the last lookup failed to create dentry lock, let us
+        * redo it.
+        */
+       if (!dentry->d_fsdata) {
+               mlog(0, "Inode %llu doesn't have dentry lock, "
+                    "returning false\n",
+                    (unsigned long long)OCFS2_I(inode)->ip_blkno);
+               goto bail;
+       }
+
        ret = 1;
 
 bail:
index fcf879ed69308e9518d0504428d3afbe13ee9f8f..756f5b0998e0d4e389ffcda4b558f861094eeb91 100644 (file)
@@ -122,7 +122,7 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm,
         * that still has AST's pending... */
        in_use = !list_empty(&lock->ast_list);
        spin_unlock(&dlm->ast_lock);
-       if (in_use) {
+       if (in_use && !(flags & LKM_CANCEL)) {
               mlog(ML_ERROR, "lockres %.*s: Someone is calling dlmunlock "
                    "while waiting for an ast!", res->lockname.len,
                    res->lockname.name);
@@ -131,7 +131,7 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm,
 
        spin_lock(&res->spinlock);
        if (res->state & DLM_LOCK_RES_IN_PROGRESS) {
-               if (master_node) {
+               if (master_node && !(flags & LKM_CANCEL)) {
                        mlog(ML_ERROR, "lockres in progress!\n");
                        spin_unlock(&res->spinlock);
                        return DLM_FORWARD;
index fcdba091af3dd8be6706950e83a772049bf775b1..c212cf5a2bdf3ad9e8e6c02672f4b76189202f5a 100644 (file)
@@ -108,6 +108,7 @@ static char *ocfs2_lock_type_strings[] = {
        [OCFS2_LOCK_TYPE_OPEN] = "Open",
        [OCFS2_LOCK_TYPE_FLOCK] = "Flock",
        [OCFS2_LOCK_TYPE_QINFO] = "Quota",
+       [OCFS2_LOCK_TYPE_NFS_SYNC] = "NFSSync",
        [OCFS2_LOCK_TYPE_ORPHAN_SCAN] = "OrphanScan",
 };
 
index bf7742d0ee3bba05a7ceabab948aff62f27482f0..44f2a5e1d04233bae9fc5b72bf894cbdd67461f2 100644 (file)
@@ -23,6 +23,7 @@
 #include "sysfile.h"
 #include "dlmglue.h"
 #include "uptodate.h"
+#include "super.h"
 #include "quota.h"
 
 static struct workqueue_struct *ocfs2_quota_wq = NULL;
@@ -114,6 +115,15 @@ int ocfs2_read_quota_block(struct inode *inode, u64 v_block,
        int rc = 0;
        struct buffer_head *tmp = *bh;
 
+       if (i_size_read(inode) >> inode->i_sb->s_blocksize_bits <= v_block) {
+               ocfs2_error(inode->i_sb,
+                           "Quota file %llu is probably corrupted! Requested "
+                           "to read block %Lu but file has size only %Lu\n",
+                           (unsigned long long)OCFS2_I(inode)->ip_blkno,
+                           (unsigned long long)v_block,
+                           (unsigned long long)i_size_read(inode));
+               return -EIO;
+       }
        rc = ocfs2_read_virt_blocks(inode, v_block, 1, &tmp, 0,
                                    ocfs2_validate_quota_block);
        if (rc)
index b0ee0fdf799a514c9555b34f4983c734825badde..a3f8871d21fd516fb29aefbc040e30e6be016069 100644 (file)
@@ -1218,13 +1218,17 @@ static void ocfs2_kill_sb(struct super_block *sb)
 {
        struct ocfs2_super *osb = OCFS2_SB(sb);
 
+       /* Failed mount? */
+       if (!osb || atomic_read(&osb->vol_state) == VOLUME_DISABLED)
+               goto out;
+
        /* Prevent further queueing of inode drop events */
        spin_lock(&dentry_list_lock);
        ocfs2_set_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED);
        spin_unlock(&dentry_list_lock);
        /* Wait for work to finish and/or remove it */
        cancel_work_sync(&osb->dentry_lock_work);
-
+out:
        kill_block_super(sb);
 }
 
index 0882d166239a071985b8309362c257e3878dde19..eafcc7c1870687817c663816995894f0cfa4c127 100644 (file)
@@ -619,7 +619,7 @@ xfs_file_compat_ioctl(
        case XFS_IOC_GETVERSION_32:
                cmd = _NATIVE_IOC(cmd, long);
                return xfs_file_ioctl(filp, cmd, p);
-       case XFS_IOC_SWAPEXT: {
+       case XFS_IOC_SWAPEXT_32: {
                struct xfs_swapext        sxp;
                struct compat_xfs_swapext __user *sxu = arg;
 
index baf1e0a9a7ee9f4ccc309cb72e1554e7bdf46ff8..740ac3ad8fd06fc61b8e2dacc10054ec27469439 100644 (file)
@@ -174,7 +174,7 @@ struct acpi_processor_throttling {
        cpumask_var_t shared_cpu_map;
        int (*acpi_processor_get_throttling) (struct acpi_processor * pr);
        int (*acpi_processor_set_throttling) (struct acpi_processor * pr,
-                                             int state);
+                                             int state, bool force);
 
        u32 address;
        u8 duty_offset;
@@ -321,7 +321,8 @@ static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr)
 /* in processor_throttling.c */
 int acpi_processor_tstate_has_changed(struct acpi_processor *pr);
 int acpi_processor_get_throttling_info(struct acpi_processor *pr);
-extern int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
+extern int acpi_processor_set_throttling(struct acpi_processor *pr,
+                                        int state, bool force);
 extern const struct file_operations acpi_processor_throttling_fops;
 extern void acpi_processor_throttling_init(void);
 /* in processor_idle.c */
index 010545436efa22593f4a124c9a68849f78a85872..5a2bd1cc9656b56e8462c0f8569fb6b1479609f4 100644 (file)
@@ -137,6 +137,7 @@ struct crypto_instance *crypto_alloc_instance(const char *name,
 void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen);
 int crypto_enqueue_request(struct crypto_queue *queue,
                           struct crypto_async_request *request);
+void *__crypto_dequeue_request(struct crypto_queue *queue, unsigned int offset);
 struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue);
 int crypto_tfm_in_queue(struct crypto_queue *queue, struct crypto_tfm *tfm);
 
index 2ba42cd7d6aa4c4fa708ba2733b6a20a59c3c526..3a748a6bf772b25e83e8657024cddea8f40d8026 100644 (file)
@@ -79,8 +79,8 @@ static inline int skcipher_enqueue_givcrypt(
 static inline struct skcipher_givcrypt_request *skcipher_dequeue_givcrypt(
        struct crypto_queue *queue)
 {
-       return container_of(ablkcipher_dequeue_request(queue),
-                           struct skcipher_givcrypt_request, creq);
+       return __crypto_dequeue_request(
+               queue, offsetof(struct skcipher_givcrypt_request, creq.base));
 }
 
 static inline void *skcipher_givcrypt_reqctx(
index f81c3232accd6ff547b5dfaae7250e94f3e2edbc..2ba61e18fc8bc9abd78d56e7d9bdfbe6688d274e 100644 (file)
@@ -508,6 +508,7 @@ typedef struct {
 #define DRM_RADEON_INFO                        0x27
 #define DRM_RADEON_GEM_SET_TILING      0x28
 #define DRM_RADEON_GEM_GET_TILING      0x29
+#define DRM_RADEON_GEM_BUSY            0x2a
 
 #define DRM_IOCTL_RADEON_CP_INIT    DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
 #define DRM_IOCTL_RADEON_CP_START   DRM_IO(  DRM_COMMAND_BASE + DRM_RADEON_CP_START)
@@ -548,6 +549,7 @@ typedef struct {
 #define DRM_IOCTL_RADEON_INFO          DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INFO, struct drm_radeon_info)
 #define DRM_IOCTL_RADEON_SET_TILING    DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_TILING, struct drm_radeon_gem_set_tiling)
 #define DRM_IOCTL_RADEON_GET_TILING    DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_GET_TILING, struct drm_radeon_gem_get_tiling)
+#define DRM_IOCTL_RADEON_GEM_BUSY      DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_BUSY, struct drm_radeon_gem_busy)
 
 typedef struct drm_radeon_init {
        enum {
@@ -707,6 +709,7 @@ typedef struct drm_radeon_indirect {
 #define RADEON_PARAM_FB_LOCATION           14   /* FB location */
 #define RADEON_PARAM_NUM_GB_PIPES          15   /* num GB pipes */
 #define RADEON_PARAM_DEVICE_ID             16
+#define RADEON_PARAM_NUM_Z_PIPES           17   /* num Z pipes */
 
 typedef struct drm_radeon_getparam {
        int param;
@@ -895,6 +898,7 @@ struct drm_radeon_cs {
 
 #define RADEON_INFO_DEVICE_ID          0x00
 #define RADEON_INFO_NUM_GB_PIPES       0x01
+#define RADEON_INFO_NUM_Z_PIPES        0x02
 
 struct drm_radeon_info {
        uint32_t                request;
index 61ee18c1bdb44bd714b39b840d7b73b4ad02698a..2046b5b8af48ae094d0182b143450b5459b67b30 100644 (file)
@@ -117,6 +117,7 @@ extern int setup_arg_pages(struct linux_binprm * bprm,
                           int executable_stack);
 extern int bprm_mm_init(struct linux_binprm *bprm);
 extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm);
+extern int prepare_bprm_creds(struct linux_binprm *bprm);
 extern void install_exec_creds(struct linux_binprm *bprm);
 extern void do_coredump(long signr, int exit_code, struct pt_regs *regs);
 extern int set_binfmt(struct linux_binfmt *new);
index 2878811c61346f09520ffdc086742c77943e91ea..756d78b8c1c5e52195fc4b0db951c883c1a07122 100644 (file)
@@ -94,13 +94,13 @@ extern void __bitmap_shift_right(unsigned long *dst,
                         const unsigned long *src, int shift, int bits);
 extern void __bitmap_shift_left(unsigned long *dst,
                         const unsigned long *src, int shift, int bits);
-extern void __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
+extern int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
                        const unsigned long *bitmap2, int bits);
 extern void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
                        const unsigned long *bitmap2, int bits);
 extern void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
                        const unsigned long *bitmap2, int bits);
-extern void __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
+extern int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
                        const unsigned long *bitmap2, int bits);
 extern int __bitmap_intersects(const unsigned long *bitmap1,
                        const unsigned long *bitmap2, int bits);
@@ -171,13 +171,12 @@ static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
        }
 }
 
-static inline void bitmap_and(unsigned long *dst, const unsigned long *src1,
+static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
                        const unsigned long *src2, int nbits)
 {
        if (small_const_nbits(nbits))
-               *dst = *src1 & *src2;
-       else
-               __bitmap_and(dst, src1, src2, nbits);
+               return (*dst = *src1 & *src2) != 0;
+       return __bitmap_and(dst, src1, src2, nbits);
 }
 
 static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
@@ -198,13 +197,12 @@ static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1,
                __bitmap_xor(dst, src1, src2, nbits);
 }
 
-static inline void bitmap_andnot(unsigned long *dst, const unsigned long *src1,
+static inline int bitmap_andnot(unsigned long *dst, const unsigned long *src1,
                        const unsigned long *src2, int nbits)
 {
        if (small_const_nbits(nbits))
-               *dst = *src1 & ~(*src2);
-       else
-               __bitmap_andnot(dst, src1, src2, nbits);
+               return (*dst = *src1 & ~(*src2)) != 0;
+       return __bitmap_andnot(dst, src1, src2, nbits);
 }
 
 static inline void bitmap_complement(unsigned long *dst, const unsigned long *src,
index c5ac87ca7bc647d32caef606c9c26ab0bb606090..796df12091b7687a450d26e57c4acf6ecc15b34d 100644 (file)
  * int cpu_isset(cpu, mask)            true iff bit 'cpu' set in mask
  * int cpu_test_and_set(cpu, mask)     test and set bit 'cpu' in mask
  *
- * void cpus_and(dst, src1, src2)      dst = src1 & src2  [intersection]
+ * int cpus_and(dst, src1, src2)       dst = src1 & src2  [intersection]
  * void cpus_or(dst, src1, src2)       dst = src1 | src2  [union]
  * void cpus_xor(dst, src1, src2)      dst = src1 ^ src2
- * void cpus_andnot(dst, src1, src2)   dst = src1 & ~src2
+ * int cpus_andnot(dst, src1, src2)    dst = src1 & ~src2
  * void cpus_complement(dst, src)      dst = ~src
  *
  * int cpus_equal(mask1, mask2)                Does mask1 == mask2?
@@ -179,10 +179,10 @@ static inline int __cpu_test_and_set(int cpu, cpumask_t *addr)
 }
 
 #define cpus_and(dst, src1, src2) __cpus_and(&(dst), &(src1), &(src2), NR_CPUS)
-static inline void __cpus_and(cpumask_t *dstp, const cpumask_t *src1p,
+static inline int __cpus_and(cpumask_t *dstp, const cpumask_t *src1p,
                                        const cpumask_t *src2p, int nbits)
 {
-       bitmap_and(dstp->bits, src1p->bits, src2p->bits, nbits);
+       return bitmap_and(dstp->bits, src1p->bits, src2p->bits, nbits);
 }
 
 #define cpus_or(dst, src1, src2) __cpus_or(&(dst), &(src1), &(src2), NR_CPUS)
@@ -201,10 +201,10 @@ static inline void __cpus_xor(cpumask_t *dstp, const cpumask_t *src1p,
 
 #define cpus_andnot(dst, src1, src2) \
                                __cpus_andnot(&(dst), &(src1), &(src2), NR_CPUS)
-static inline void __cpus_andnot(cpumask_t *dstp, const cpumask_t *src1p,
+static inline int __cpus_andnot(cpumask_t *dstp, const cpumask_t *src1p,
                                        const cpumask_t *src2p, int nbits)
 {
-       bitmap_andnot(dstp->bits, src1p->bits, src2p->bits, nbits);
+       return bitmap_andnot(dstp->bits, src1p->bits, src2p->bits, nbits);
 }
 
 #define cpus_complement(dst, src) __cpus_complement(&(dst), &(src), NR_CPUS)
@@ -738,11 +738,11 @@ static inline void cpumask_clear(struct cpumask *dstp)
  * @src1p: the first input
  * @src2p: the second input
  */
-static inline void cpumask_and(struct cpumask *dstp,
+static inline int cpumask_and(struct cpumask *dstp,
                               const struct cpumask *src1p,
                               const struct cpumask *src2p)
 {
-       bitmap_and(cpumask_bits(dstp), cpumask_bits(src1p),
+       return bitmap_and(cpumask_bits(dstp), cpumask_bits(src1p),
                                       cpumask_bits(src2p), nr_cpumask_bits);
 }
 
@@ -779,11 +779,11 @@ static inline void cpumask_xor(struct cpumask *dstp,
  * @src1p: the first input
  * @src2p: the second input
  */
-static inline void cpumask_andnot(struct cpumask *dstp,
+static inline int cpumask_andnot(struct cpumask *dstp,
                                  const struct cpumask *src1p,
                                  const struct cpumask *src2p)
 {
-       bitmap_andnot(cpumask_bits(dstp), cpumask_bits(src1p),
+       return bitmap_andnot(cpumask_bits(dstp), cpumask_bits(src1p),
                                          cpumask_bits(src2p), nr_cpumask_bits);
 }
 
index 655e7721580a450e93c8467316244a829cd5eace..df7607e6dce80ec188d061524103fbdf822cd2a7 100644 (file)
@@ -91,6 +91,9 @@ typedef int (*dm_iterate_devices_fn) (struct dm_target *ti,
                                      iterate_devices_callout_fn fn,
                                      void *data);
 
+typedef void (*dm_io_hints_fn) (struct dm_target *ti,
+                               struct queue_limits *limits);
+
 /*
  * Returns:
  *    0: The target can handle the next I/O immediately.
@@ -151,6 +154,7 @@ struct target_type {
        dm_merge_fn merge;
        dm_busy_fn busy;
        dm_iterate_devices_fn iterate_devices;
+       dm_io_hints_fn io_hints;
 
        /* For internal device-mapper use. */
        struct list_head list;
index 642e3017b51f9415db90bd968c00484ed4a3def3..8a1f972c0fe97a0ceaf4fa8b6c99f1d42ac84d33 100644 (file)
        (DM_ULOG_REQUEST_MASK & (request_type))
 
 struct dm_ulog_request {
-       char uuid[DM_UUID_LEN]; /* Ties a request to a specific mirror log */
+       /*
+        * The local unique identifier (luid) and the universally unique
+        * identifier (uuid) are used to tie a request to a specific
+        * mirror log.  A single machine log could probably make due with
+        * just the 'luid', but a cluster-aware log must use the 'uuid' and
+        * the 'luid'.  The uuid is what is required for node to node
+        * communication concerning a particular log, but the 'luid' helps
+        * differentiate between logs that are being swapped and have the
+        * same 'uuid'.  (Think "live" and "inactive" device-mapper tables.)
+        */
+       uint64_t luid;
+       char uuid[DM_UUID_LEN];
        char padding[7];        /* Padding because DM_UUID_LEN = 129 */
 
        int32_t error;          /* Used to report back processing errors */
index 23c1ec79a31b224470cc0d8e235ebc0a661baa17..45ff184915149aa150f2d9157ac3cc997a446a5d 100644 (file)
@@ -21,7 +21,7 @@ struct flex_array {
                struct {
                        int element_size;
                        int total_nr_elements;
-                       struct flex_array_part *parts[0];
+                       struct flex_array_part *parts[];
                };
                /*
                 * This little trick makes sure that
@@ -36,12 +36,14 @@ struct flex_array {
        .total_nr_elements = (total),   \
 } } }
 
-struct flex_array *flex_array_alloc(int element_size, int total, gfp_t flags);
-int flex_array_prealloc(struct flex_array *fa, int start, int end, gfp_t flags);
+struct flex_array *flex_array_alloc(int element_size, unsigned int total,
+               gfp_t flags);
+int flex_array_prealloc(struct flex_array *fa, unsigned int start,
+               unsigned int end, gfp_t flags);
 void flex_array_free(struct flex_array *fa);
 void flex_array_free_parts(struct flex_array *fa);
-int flex_array_put(struct flex_array *fa, int element_nr, void *src,
+int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src,
                gfp_t flags);
-void *flex_array_get(struct flex_array *fa, int element_nr);
+void *flex_array_get(struct flex_array *fa, unsigned int element_nr);
 
 #endif /* _FLEX_ARRAY_H */
index 67888a9e06558d45d0ff0fc2fd97072af9aed5c8..73e9b643e45503dc6f01e31af2a8ec1f77de1264 100644 (file)
@@ -2123,7 +2123,7 @@ extern struct file *do_filp_open(int dfd, const char *pathname,
                int open_flag, int mode, int acc_mode);
 extern int may_open(struct path *, int, int);
 
-extern int kernel_read(struct file *, unsigned long, char *, unsigned long);
+extern int kernel_read(struct file *, loff_t, char *, unsigned long);
 extern struct file * open_exec(const char *);
  
 /* fs/dcache.c -- generic fs support functions */
index 2723513a5651b493a27c41191aa7be3e04b5af60..5cbc620bdfe060dba93399143b5d76e354093dc7 100644 (file)
@@ -10,6 +10,7 @@
 #include <asm/tlbflush.h>
 
 struct ctl_table;
+struct user_struct;
 
 int PageHuge(struct page *page);
 
@@ -146,7 +147,8 @@ static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb)
 
 extern const struct file_operations hugetlbfs_file_operations;
 extern struct vm_operations_struct hugetlb_vm_ops;
-struct file *hugetlb_file_setup(const char *name, size_t, int);
+struct file *hugetlb_file_setup(const char *name, size_t size, int acct,
+                                               struct user_struct **user);
 int hugetlb_get_quota(struct address_space *mapping, long delta);
 void hugetlb_put_quota(struct address_space *mapping, long delta);
 
@@ -168,7 +170,7 @@ static inline void set_file_hugepages(struct file *file)
 
 #define is_file_hugepages(file)                        0
 #define set_file_hugepages(file)               BUG()
-#define hugetlb_file_setup(name,size,acctflag) ERR_PTR(-ENOSYS)
+#define hugetlb_file_setup(name,size,acct,user)        ERR_PTR(-ENOSYS)
 
 #endif /* !CONFIG_HUGETLBFS */
 
index c46c89505dac3721e4e337d26c283419cc01a68c..2442e3f3d03335ff5e515d0876f64cadfa3f6dbe 100644 (file)
@@ -51,7 +51,7 @@ extern u64 __init lmb_alloc_base(u64 size,
 extern u64 __init __lmb_alloc_base(u64 size,
                u64 align, u64 max_addr);
 extern u64 __init lmb_phys_mem_size(void);
-extern u64 __init lmb_end_of_DRAM(void);
+extern u64 lmb_end_of_DRAM(void);
 extern void __init lmb_enforce_memory_limit(u64 memory_limit);
 extern int __init lmb_is_reserved(u64 addr);
 extern int lmb_find(struct lmb_property *res);
index ed889f4168f301a877c4e7384e207cb6fae2bb4d..ae779bb8cc0f7fb3d710be1916f1006e43f95c60 100644 (file)
 
 #define UCB_ADC_DATA           0x68
 #define UCB_ADC_DAT_VALID      (1 << 15)
+
+#define UCB_FCSR               0x6c
+#define UCB_FCSR_AVE           (1 << 12)
+
 #define UCB_ADC_DAT_MASK       0x3ff
 
 #define UCB_ID                 0x7e
index 13e1adf55c4c7c0ba30d81bbc54abe6d56b93b5e..6273fa97b527e4d8c415ebbda74c0ac68303532e 100644 (file)
@@ -240,6 +240,21 @@ static inline int cancel_delayed_work(struct delayed_work *work)
        return ret;
 }
 
+/*
+ * Like above, but uses del_timer() instead of del_timer_sync(). This means,
+ * if it returns 0 the timer function may be running and the queueing is in
+ * progress.
+ */
+static inline int __cancel_delayed_work(struct delayed_work *work)
+{
+       int ret;
+
+       ret = del_timer(&work->timer);
+       if (ret)
+               work_clear_pending(&work->work);
+       return ret;
+}
+
 extern int cancel_delayed_work_sync(struct delayed_work *work);
 
 /* Obsolete. use cancel_delayed_work_sync() */
index 2d9d6bdfe7c929358dd41ba39f7934929ef5e684..11f4f145be3fd9461cfdcd9ee1087c30fa1c48c8 100644 (file)
@@ -733,13 +733,14 @@ static void __init do_ctors(void)
 int initcall_debug;
 core_param(initcall_debug, initcall_debug, bool, 0644);
 
+static char msgbuf[64];
+static struct boot_trace_call call;
+static struct boot_trace_ret ret;
+
 int do_one_initcall(initcall_t fn)
 {
        int count = preempt_count();
        ktime_t calltime, delta, rettime;
-       char msgbuf[64];
-       struct boot_trace_call call;
-       struct boot_trace_ret ret;
 
        if (initcall_debug) {
                call.caller = task_pid_nr(current);
index 15dd238e533887b1e84f17b070bb64f0b4660961..1bc4701ef4f0d2b214e57f73a1b1096d2f5346e1 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -174,7 +174,7 @@ static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
        shm_unlock(shp);
        if (!is_file_hugepages(shp->shm_file))
                shmem_lock(shp->shm_file, 0, shp->mlock_user);
-       else
+       else if (shp->mlock_user)
                user_shm_unlock(shp->shm_file->f_path.dentry->d_inode->i_size,
                                                shp->mlock_user);
        fput (shp->shm_file);
@@ -369,8 +369,8 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
                /* hugetlb_file_setup applies strict accounting */
                if (shmflg & SHM_NORESERVE)
                        acctflag = VM_NORESERVE;
-               file = hugetlb_file_setup(name, size, acctflag);
-               shp->mlock_user = current_user();
+               file = hugetlb_file_setup(name, size, acctflag,
+                                                       &shp->mlock_user);
        } else {
                /*
                 * Do not allow no accounting for OVERCOMMIT_NEVER, even
@@ -410,6 +410,8 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
        return error;
 
 no_id:
+       if (shp->mlock_user)    /* shmflg & SHM_HUGETLB case */
+               user_shm_unlock(size, shp->mlock_user);
        fput(file);
 no_file:
        security_shm_free(shp);
index 043b5d88049b0ef7bd83ba2e8b7fc8ce4058e672..aab8579c6093bb5f1c63a26876d45546e25c21df 100644 (file)
@@ -814,11 +814,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
 {
        struct signal_struct *sig;
 
-       if (clone_flags & CLONE_THREAD) {
-               atomic_inc(&current->signal->count);
-               atomic_inc(&current->signal->live);
+       if (clone_flags & CLONE_THREAD)
                return 0;
-       }
 
        sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
        tsk->signal = sig;
@@ -876,16 +873,6 @@ void __cleanup_signal(struct signal_struct *sig)
        kmem_cache_free(signal_cachep, sig);
 }
 
-static void cleanup_signal(struct task_struct *tsk)
-{
-       struct signal_struct *sig = tsk->signal;
-
-       atomic_dec(&sig->live);
-
-       if (atomic_dec_and_test(&sig->count))
-               __cleanup_signal(sig);
-}
-
 static void copy_flags(unsigned long clone_flags, struct task_struct *p)
 {
        unsigned long new_flags = p->flags;
@@ -1238,6 +1225,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
        }
 
        if (clone_flags & CLONE_THREAD) {
+               atomic_inc(&current->signal->count);
+               atomic_inc(&current->signal->live);
                p->group_leader = current->group_leader;
                list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group);
        }
@@ -1281,7 +1270,8 @@ bad_fork_cleanup_mm:
        if (p->mm)
                mmput(p->mm);
 bad_fork_cleanup_signal:
-       cleanup_signal(p);
+       if (!(clone_flags & CLONE_THREAD))
+               __cleanup_signal(p->signal);
 bad_fork_cleanup_sighand:
        __cleanup_sighand(p->sighand);
 bad_fork_cleanup_fs:
index fd141140355889abd13630c663e66a2e87267194..2d537186191f1c93ba39a2df1990741f690f3aac 100644 (file)
@@ -909,16 +909,18 @@ void __symbol_put(const char *symbol)
 }
 EXPORT_SYMBOL(__symbol_put);
 
+/* Note this assumes addr is a function, which it currently always is. */
 void symbol_put_addr(void *addr)
 {
        struct module *modaddr;
+       unsigned long a = (unsigned long)dereference_function_descriptor(addr);
 
-       if (core_kernel_text((unsigned long)addr))
+       if (core_kernel_text(a))
                return;
 
        /* module_text_address is safe here: we're supposed to have reference
         * to module from symbol_get, so it can't go away. */
-       modaddr = __module_text_address((unsigned long)addr);
+       modaddr = __module_text_address(a);
        BUG_ON(!modaddr);
        module_put(modaddr);
 }
@@ -1272,6 +1274,10 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect,
        struct module_notes_attrs *notes_attrs;
        struct bin_attribute *nattr;
 
+       /* failed to create section attributes, so can't create notes */
+       if (!mod->sect_attrs)
+               return;
+
        /* Count notes sections and allocate structures.  */
        notes = 0;
        for (i = 0; i < nsect; i++)
index 36f65e2b8b5772f16e644bfa109f89393c893fd3..d7cbc579fc8016603f0d0644c339a470224ad0b9 100644 (file)
@@ -50,7 +50,7 @@ static atomic_t nr_task_counters __read_mostly;
  *  1 - disallow cpu counters to unpriv
  *  2 - disallow kernel profiling to unpriv
  */
-int sysctl_perf_counter_paranoid __read_mostly;
+int sysctl_perf_counter_paranoid __read_mostly = 1;
 
 static inline bool perf_paranoid_cpu(void)
 {
@@ -1791,7 +1791,7 @@ static int perf_counter_read_group(struct perf_counter *counter,
        size += err;
 
        list_for_each_entry(sub, &leader->sibling_list, list_entry) {
-               err = perf_counter_read_entry(counter, read_format,
+               err = perf_counter_read_entry(sub, read_format,
                                buf + size);
                if (err < 0)
                        return err;
@@ -4066,6 +4066,7 @@ perf_counter_alloc(struct perf_counter_attr *attr,
        hwc->sample_period = attr->sample_period;
        if (attr->freq && attr->sample_freq)
                hwc->sample_period = 1;
+       hwc->last_period = hwc->sample_period;
 
        atomic64_set(&hwc->period_left, hwc->sample_period);
 
index a6dcd67b041d200fc61f2b2de06890e8a5c65443..620b58abdc3295307990978671b81173feb8ff47 100644 (file)
@@ -137,11 +137,12 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
  */
 int clockevents_register_notifier(struct notifier_block *nb)
 {
+       unsigned long flags;
        int ret;
 
-       spin_lock(&clockevents_lock);
+       spin_lock_irqsave(&clockevents_lock, flags);
        ret = raw_notifier_chain_register(&clockevents_chain, nb);
-       spin_unlock(&clockevents_lock);
+       spin_unlock_irqrestore(&clockevents_lock, flags);
 
        return ret;
 }
@@ -178,16 +179,18 @@ static void clockevents_notify_released(void)
  */
 void clockevents_register_device(struct clock_event_device *dev)
 {
+       unsigned long flags;
+
        BUG_ON(dev->mode != CLOCK_EVT_MODE_UNUSED);
        BUG_ON(!dev->cpumask);
 
-       spin_lock(&clockevents_lock);
+       spin_lock_irqsave(&clockevents_lock, flags);
 
        list_add(&dev->list, &clockevent_devices);
        clockevents_do_notify(CLOCK_EVT_NOTIFY_ADD, dev);
        clockevents_notify_released();
 
-       spin_unlock(&clockevents_lock);
+       spin_unlock_irqrestore(&clockevents_lock, flags);
 }
 EXPORT_SYMBOL_GPL(clockevents_register_device);
 
@@ -235,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;
+       unsigned long flags;
 
-       spin_lock(&clockevents_lock);
+       spin_lock_irqsave(&clockevents_lock, flags);
        clockevents_do_notify(reason, arg);
 
        switch (reason) {
@@ -251,7 +255,7 @@ void clockevents_notify(unsigned long reason, void *arg)
        default:
                break;
        }
-       spin_unlock(&clockevents_lock);
+       spin_unlock_irqrestore(&clockevents_lock, flags);
 }
 EXPORT_SYMBOL_GPL(clockevents_notify);
 #endif
index 877dbedc3118275ac77f34c2b63a655f6c1a7617..c2ec25087a35a0cbf265258caf953d83424314f9 100644 (file)
@@ -205,11 +205,11 @@ static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
  * Powerstate information: The system enters/leaves a state, where
  * affected devices might stop
  */
-static void tick_do_broadcast_on_off(void *why)
+static void tick_do_broadcast_on_off(unsigned long *reason)
 {
        struct clock_event_device *bc, *dev;
        struct tick_device *td;
-       unsigned long flags, *reason = why;
+       unsigned long flags;
        int cpu, bc_stopped;
 
        spin_lock_irqsave(&tick_broadcast_lock, flags);
@@ -276,8 +276,7 @@ void tick_broadcast_on_off(unsigned long reason, int *oncpu)
                printk(KERN_ERR "tick-broadcast: ignoring broadcast for "
                       "offline CPU #%d\n", *oncpu);
        else
-               smp_call_function_single(*oncpu, tick_do_broadcast_on_off,
-                                        &reason, 1);
+               tick_do_broadcast_on_off(&reason);
 }
 
 /*
index a999b92a12773750daded0c912a822b6f0eebe84..fddd69d16e039a5d75f9093856d4abec8c6d10b6 100644 (file)
@@ -286,7 +286,7 @@ static int __init init_timer_list_procfs(void)
 {
        struct proc_dir_entry *pe;
 
-       pe = proc_create("timer_list", 0644, NULL, &timer_list_fops);
+       pe = proc_create("timer_list", 0444, NULL, &timer_list_fops);
        if (!pe)
                return -ENOMEM;
        return 0;
index 1e1d23c263086635ec225dd762aa47d880002b35..25edd5cc5935cae5d76342cf04e2bed40c22f00d 100644 (file)
@@ -2278,7 +2278,11 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
        read++;
        cnt--;
 
-       if (!(iter->flags & ~FTRACE_ITER_CONT)) {
+       /*
+        * If the parser haven't finished with the last write,
+        * continue reading the user input without skipping spaces.
+        */
+       if (!(iter->flags & FTRACE_ITER_CONT)) {
                /* skip white space */
                while (cnt && isspace(ch)) {
                        ret = get_user(ch, ubuf++);
@@ -2288,8 +2292,9 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
                        cnt--;
                }
 
+               /* only spaces were written */
                if (isspace(ch)) {
-                       file->f_pos += read;
+                       *ppos += read;
                        ret = read;
                        goto out;
                }
@@ -2319,12 +2324,12 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
                if (ret)
                        goto out;
                iter->buffer_idx = 0;
-       } else
+       } else {
                iter->flags |= FTRACE_ITER_CONT;
+               iter->buffer[iter->buffer_idx++] = ch;
+       }
 
-
-       file->f_pos += read;
-
+       *ppos += read;
        ret = read;
  out:
        mutex_unlock(&ftrace_regex_lock);
index c22b40f8f576c19e7c00dec5e8f1983667e7b084..8c358395d33828f1b3b6f0023027bf9e06638296 100644 (file)
@@ -3896,17 +3896,9 @@ trace_options_core_write(struct file *filp, const char __user *ubuf, size_t cnt,
        if (ret < 0)
                return ret;
 
-       switch (val) {
-       case 0:
-               trace_flags &= ~(1 << index);
-               break;
-       case 1:
-               trace_flags |= 1 << index;
-               break;
-
-       default:
+       if (val != 0 && val != 1)
                return -EINVAL;
-       }
+       set_tracer_flags(1 << index, val);
 
        *ppos += cnt;
 
index 35a1f7ff414988d86c6c081d7bbf3671733a15d6..702565821c9976fb4588dac793d84008bf93b229 100644 (file)
@@ -179,14 +179,16 @@ void __bitmap_shift_left(unsigned long *dst,
 }
 EXPORT_SYMBOL(__bitmap_shift_left);
 
-void __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
+int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
                                const unsigned long *bitmap2, int bits)
 {
        int k;
        int nr = BITS_TO_LONGS(bits);
+       unsigned long result = 0;
 
        for (k = 0; k < nr; k++)
-               dst[k] = bitmap1[k] & bitmap2[k];
+               result |= (dst[k] = bitmap1[k] & bitmap2[k]);
+       return result != 0;
 }
 EXPORT_SYMBOL(__bitmap_and);
 
@@ -212,14 +214,16 @@ void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
 }
 EXPORT_SYMBOL(__bitmap_xor);
 
-void __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
+int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
                                const unsigned long *bitmap2, int bits)
 {
        int k;
        int nr = BITS_TO_LONGS(bits);
+       unsigned long result = 0;
 
        for (k = 0; k < nr; k++)
-               dst[k] = bitmap1[k] & ~bitmap2[k];
+               result |= (dst[k] = bitmap1[k] & ~bitmap2[k]);
+       return result != 0;
 }
 EXPORT_SYMBOL(__bitmap_andnot);
 
index 65b0d99b6d0aa8f7219741e731394d1514b1706e..58a9f9fc609afaf561aa582b9d14270fe2cb3872 100644 (file)
@@ -156,9 +156,13 @@ static bool driver_filter(struct device *dev)
                return true;
 
        /* driver filter on and initialized */
-       if (current_driver && dev->driver == current_driver)
+       if (current_driver && dev && dev->driver == current_driver)
                return true;
 
+       /* driver filter on, but we can't filter on a NULL device... */
+       if (!dev)
+               return false;
+
        if (current_driver || !current_driver_name[0])
                return false;
 
@@ -183,17 +187,17 @@ static bool driver_filter(struct device *dev)
        return ret;
 }
 
-#define err_printk(dev, entry, format, arg...) do {            \
-               error_count += 1;                               \
-               if (driver_filter(dev) &&                       \
-                   (show_all_errors || show_num_errors > 0)) { \
-                       WARN(1, "%s %s: " format,               \
-                            dev_driver_string(dev),            \
-                            dev_name(dev) , ## arg);           \
-                       dump_entry_trace(entry);                \
-               }                                               \
-               if (!show_all_errors && show_num_errors > 0)    \
-                       show_num_errors -= 1;                   \
+#define err_printk(dev, entry, format, arg...) do {                    \
+               error_count += 1;                                       \
+               if (driver_filter(dev) &&                               \
+                   (show_all_errors || show_num_errors > 0)) {         \
+                       WARN(1, "%s %s: " format,                       \
+                            dev ? dev_driver_string(dev) : "NULL",     \
+                            dev ? dev_name(dev) : "NULL", ## arg);     \
+                       dump_entry_trace(entry);                        \
+               }                                                       \
+               if (!show_all_errors && show_num_errors > 0)            \
+                       show_num_errors -= 1;                           \
        } while (0);
 
 /*
index 08f1636d296ae2fa1032e0fd06d1ccd15ff1a4c3..7baed2fc3bc82920f97183c6fa70532250d165b4 100644 (file)
@@ -99,7 +99,8 @@ static inline int elements_fit_in_base(struct flex_array *fa)
  * capacity in the base structure.  Also note that no effort is made
  * to efficiently pack objects across page boundaries.
  */
-struct flex_array *flex_array_alloc(int element_size, int total, gfp_t flags)
+struct flex_array *flex_array_alloc(int element_size, unsigned int total,
+                                       gfp_t flags)
 {
        struct flex_array *ret;
        int max_size = nr_base_part_ptrs() * __elements_per_part(element_size);
@@ -115,16 +116,14 @@ struct flex_array *flex_array_alloc(int element_size, int total, gfp_t flags)
        return ret;
 }
 
-static int fa_element_to_part_nr(struct flex_array *fa, int element_nr)
+static int fa_element_to_part_nr(struct flex_array *fa,
+                                       unsigned int element_nr)
 {
        return element_nr / __elements_per_part(fa->element_size);
 }
 
 /**
  * flex_array_free_parts - just free the second-level pages
- * @src:       address of data to copy into the array
- * @element_nr:        index of the position in which to insert
- *             the new element.
  *
  * This is to be used in cases where the base 'struct flex_array'
  * has been statically allocated and should not be free.
@@ -146,14 +145,12 @@ void flex_array_free(struct flex_array *fa)
        kfree(fa);
 }
 
-static int fa_index_inside_part(struct flex_array *fa, int element_nr)
+static unsigned int index_inside_part(struct flex_array *fa,
+                                       unsigned int element_nr)
 {
-       return element_nr % __elements_per_part(fa->element_size);
-}
+       unsigned int part_offset;
 
-static int index_inside_part(struct flex_array *fa, int element_nr)
-{
-       int part_offset = fa_index_inside_part(fa, element_nr);
+       part_offset = element_nr % __elements_per_part(fa->element_size);
        return part_offset * fa->element_size;
 }
 
@@ -188,7 +185,8 @@ __fa_get_part(struct flex_array *fa, int part_nr, gfp_t flags)
  *
  * Locking must be provided by the caller.
  */
-int flex_array_put(struct flex_array *fa, int element_nr, void *src, gfp_t flags)
+int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src,
+                       gfp_t flags)
 {
        int part_nr = fa_element_to_part_nr(fa, element_nr);
        struct flex_array_part *part;
@@ -198,10 +196,11 @@ int flex_array_put(struct flex_array *fa, int element_nr, void *src, gfp_t flags
                return -ENOSPC;
        if (elements_fit_in_base(fa))
                part = (struct flex_array_part *)&fa->parts[0];
-       else
+       else {
                part = __fa_get_part(fa, part_nr, flags);
-       if (!part)
-               return -ENOMEM;
+               if (!part)
+                       return -ENOMEM;
+       }
        dst = &part->elements[index_inside_part(fa, element_nr)];
        memcpy(dst, src, fa->element_size);
        return 0;
@@ -219,7 +218,8 @@ int flex_array_put(struct flex_array *fa, int element_nr, void *src, gfp_t flags
  *
  * Locking must be provided by the caller.
  */
-int flex_array_prealloc(struct flex_array *fa, int start, int end, gfp_t flags)
+int flex_array_prealloc(struct flex_array *fa, unsigned int start,
+                       unsigned int end, gfp_t flags)
 {
        int start_part;
        int end_part;
@@ -250,18 +250,19 @@ int flex_array_prealloc(struct flex_array *fa, int start, int end, gfp_t flags)
  *
  * Locking must be provided by the caller.
  */
-void *flex_array_get(struct flex_array *fa, int element_nr)
+void *flex_array_get(struct flex_array *fa, unsigned int element_nr)
 {
        int part_nr = fa_element_to_part_nr(fa, element_nr);
        struct flex_array_part *part;
 
        if (element_nr >= fa->total_nr_elements)
                return NULL;
-       if (!fa->parts[part_nr])
-               return NULL;
        if (elements_fit_in_base(fa))
                part = (struct flex_array_part *)&fa->parts[0];
-       else
+       else {
                part = fa->parts[part_nr];
+               if (!part)
+                       return NULL;
+       }
        return &part->elements[index_inside_part(fa, element_nr)];
 }
index e4a6482d8b26e5034805a401905480974e6dcd8c..0343c05609f0d62f9b48b259bf3018db728b11a5 100644 (file)
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -429,7 +429,7 @@ u64 __init lmb_phys_mem_size(void)
        return lmb.memory.size;
 }
 
-u64 __init lmb_end_of_DRAM(void)
+u64 lmb_end_of_DRAM(void)
 {
        int idx = lmb.memory.cnt - 1;
 
index 4bde489ec4316ca41046f5826f3a57565755d90d..66e81e7e9fe98f6871cb0d159e13c6942ff8e44f 100644 (file)
@@ -1352,6 +1352,7 @@ unsigned long do_mmap_pgoff(struct file *file,
        }
 
        vma->vm_region = region;
+       add_nommu_region(region);
 
        /* set up the mapping */
        if (file && vma->vm_flags & VM_SHARED)
@@ -1361,8 +1362,6 @@ unsigned long do_mmap_pgoff(struct file *file,
        if (ret < 0)
                goto error_put_region;
 
-       add_nommu_region(region);
-
        /* okay... we have a mapping; now we have to register it */
        result = vma->vm_start;
 
index 5cc986eb9f6f605c0b88246a700d4ac46afd4b7f..a0de15f46987f65249bd60d4cad45e129fbddf29 100644 (file)
@@ -817,13 +817,15 @@ __rmqueue_fallback(struct zone *zone, int order, int start_migratetype)
                         * agressive about taking ownership of free pages
                         */
                        if (unlikely(current_order >= (pageblock_order >> 1)) ||
-                                       start_migratetype == MIGRATE_RECLAIMABLE) {
+                                       start_migratetype == MIGRATE_RECLAIMABLE ||
+                                       page_group_by_mobility_disabled) {
                                unsigned long pages;
                                pages = move_freepages_block(zone, page,
                                                                start_migratetype);
 
                                /* Claim the whole block if over half of it is free */
-                               if (pages >= (1 << (pageblock_order-1)))
+                               if (pages >= (1 << (pageblock_order-1)) ||
+                                               page_group_by_mobility_disabled)
                                        set_pageblock_migratetype(page,
                                                                start_migratetype);
 
index 5fe37842e0ea3689bcdf24ec1d77e681ba27a55c..3311c8919f375fa062faad78b2439176f436301a 100644 (file)
@@ -197,7 +197,12 @@ static unsigned long pcpu_chunk_addr(struct pcpu_chunk *chunk,
 static bool pcpu_chunk_page_occupied(struct pcpu_chunk *chunk,
                                     int page_idx)
 {
-       return *pcpu_chunk_pagep(chunk, 0, page_idx) != NULL;
+       /*
+        * Any possible cpu id can be used here, so there's no need to
+        * worry about preemption or cpu hotplug.
+        */
+       return *pcpu_chunk_pagep(chunk, raw_smp_processor_id(),
+                                page_idx) != NULL;
 }
 
 /* set the pointer to a chunk in a page struct */
@@ -297,6 +302,14 @@ static struct pcpu_chunk *pcpu_chunk_addr_search(void *addr)
                return pcpu_first_chunk;
        }
 
+       /*
+        * The address is relative to unit0 which might be unused and
+        * thus unmapped.  Offset the address to the unit space of the
+        * current processor before looking it up in the vmalloc
+        * space.  Note that any possible cpu id can be used here, so
+        * there's no need to worry about preemption or cpu hotplug.
+        */
+       addr += raw_smp_processor_id() * pcpu_unit_size;
        return pcpu_get_page_chunk(vmalloc_to_page(addr));
 }
 
index 836c6c63e1f2dbee16a922f7195da2f3ac237d83..0895b5c7cbff35fc2e5eb8dbe4b2ee8eeacf27da 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -358,6 +358,7 @@ static int page_referenced_one(struct page *page,
         */
        if (vma->vm_flags & VM_LOCKED) {
                *mapcount = 1;  /* break early from loop */
+               *vm_flags |= VM_LOCKED;
                goto out_unmap;
        }
 
index b9f1491a58a184e80769fc541d3d2958cb4919ed..b6276753626e9ade2e8bec661e980fcfc3c95374 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2594,8 +2594,6 @@ static inline int kmem_cache_close(struct kmem_cache *s)
  */
 void kmem_cache_destroy(struct kmem_cache *s)
 {
-       if (s->flags & SLAB_DESTROY_BY_RCU)
-               rcu_barrier();
        down_write(&slub_lock);
        s->refcount--;
        if (!s->refcount) {
@@ -2606,6 +2604,8 @@ void kmem_cache_destroy(struct kmem_cache *s)
                                "still has objects.\n", s->name, __func__);
                        dump_stack();
                }
+               if (s->flags & SLAB_DESTROY_BY_RCU)
+                       rcu_barrier();
                sysfs_slab_remove(s);
        } else
                up_write(&slub_lock);
index dea7abd310980daea1fa6c5a0c850a972fe37a21..94e86dd6954c295830478011fd8e71465f1a9f2d 100644 (file)
@@ -630,9 +630,14 @@ static unsigned long shrink_page_list(struct list_head *page_list,
 
                referenced = page_referenced(page, 1,
                                                sc->mem_cgroup, &vm_flags);
-               /* In active use or really unfreeable?  Activate it. */
+               /*
+                * In active use or really unfreeable?  Activate it.
+                * If page which have PG_mlocked lost isoltation race,
+                * try_to_unmap moves it to unevictable list
+                */
                if (sc->order <= PAGE_ALLOC_COSTLY_ORDER &&
-                                       referenced && page_mapping_inuse(page))
+                                       referenced && page_mapping_inuse(page)
+                                       && !(vm_flags & VM_LOCKED))
                        goto activate_locked;
 
                /*
index 787ccddb85ea6cd8c53550deef5a11e3336a4ee1..5bf5f227dbe0d83eaf28cc400a665594c6452a22 100644 (file)
@@ -60,9 +60,9 @@ static struct p9_req_t *
 p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...);
 
 /**
- * v9fs_parse_options - parse mount options into session structure
- * @options: options string passed from mount
- * @v9ses: existing v9fs session information
+ * parse_options - parse mount options into client structure
+ * @opts: options string passed from mount
+ * @clnt: existing v9fs client information
  *
  * Return 0 upon success, -ERRNO upon failure
  */
@@ -232,7 +232,7 @@ EXPORT_SYMBOL(p9_tag_lookup);
 
 /**
  * p9_tag_init - setup tags structure and contents
- * @tags: tags structure from the client struct
+ * @c:  v9fs client struct
  *
  * This initializes the tags structure for each client instance.
  *
@@ -258,7 +258,7 @@ error:
 
 /**
  * p9_tag_cleanup - cleans up tags structure and reclaims resources
- * @tags: tags structure from the client struct
+ * @c:  v9fs client struct
  *
  * This frees resources associated with the tags structure
  *
@@ -411,14 +411,9 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
                if (c->dotu)
                        err = -ecode;
 
-               if (!err) {
+               if (!err || !IS_ERR_VALUE(err))
                        err = p9_errstr2errno(ename, strlen(ename));
 
-                       /* string match failed */
-                       if (!err)
-                               err = -ESERVERFAULT;
-               }
-
                P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n", -ecode, ename);
 
                kfree(ename);
@@ -430,8 +425,8 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
 
 /**
  * p9_client_flush - flush (cancel) a request
- * c: client state
- * req: request to cancel
+ * @c: client state
+ * @oldreq: request to cancel
  *
  * This sents a flush for a particular requests and links
  * the flush request to the original request.  The current
index fdebe4314062c01e02636d5201a2068ee57a640c..52518512a93e86eb261b34af3dddf6778a9ea50f 100644 (file)
@@ -239,7 +239,7 @@ int p9_errstr2errno(char *errstr, int len)
                errstr[len] = 0;
                printk(KERN_ERR "%s: server reported unknown error %s\n",
                        __func__, errstr);
-               errno = 1;
+               errno = ESERVERFAULT;
        }
 
        return -errno;
index 8c2588e4edc0e3bf4d329661873e1875044cade1..8d934dd7fd5424049a811906e0467da91da208c3 100644 (file)
@@ -119,8 +119,8 @@ struct p9_poll_wait {
  * @wpos: write position for current frame
  * @wsize: amount of data to write for current frame
  * @wbuf: current write buffer
+ * @poll_pending_link: pending links to be polled per conn
  * @poll_wait: array of wait_q's for various worker threads
- * @poll_waddr: ????
  * @pt: poll state
  * @rq: current read work
  * @wq: current write work
@@ -700,9 +700,9 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
 }
 
 /**
- * parse_options - parse mount options into session structure
- * @options: options string passed from mount
- * @opts: transport-specific structure to parse options into
+ * parse_opts - parse mount options into p9_fd_opts structure
+ * @params: options string passed from mount
+ * @opts: fd transport-specific structure to parse options into
  *
  * Returns 0 upon success, -ERRNO upon failure
  */
index ac4990041ebb94d9935126f4cd76430fb7fa7201..65cb29db03f8cbd1440e62dfece699e4c8ff4c4f 100644 (file)
  * @pd: Protection Domain pointer
  * @qp: Queue Pair pointer
  * @cq: Completion Queue pointer
+ * @dm_mr: DMA Memory Region pointer
  * @lkey: The local access only memory region key
  * @timeout: Number of uSecs to wait for connection management events
  * @sq_depth: The depth of the Send Queue
  * @sq_sem: Semaphore for the SQ
  * @rq_depth: The depth of the Receive Queue.
+ * @rq_count: Count of requests in the Receive Queue.
  * @addr: The remote peer's address
  * @req_lock: Protects the active request list
- * @send_wait: Wait list when the SQ fills up
  * @cm_done: Completion event for connection management tracking
  */
 struct p9_trans_rdma {
@@ -154,9 +155,9 @@ static match_table_t tokens = {
 };
 
 /**
- * parse_options - parse mount options into session structure
- * @options: options string passed from mount
- * @opts: transport-specific structure to parse options into
+ * parse_opts - parse mount options into rdma options structure
+ * @params: options string passed from mount
+ * @opts: rdma transport-specific structure to parse options into
  *
  * Returns 0 upon success, -ERRNO upon failure
  */
index a49484e67e1ddf2b1dcd2ae1ed0ee71a8872521f..9bf0b737aa517fde7bee51821be494e743a67cce 100644 (file)
@@ -57,11 +57,9 @@ static int chan_index;
  * @initialized: whether the channel is initialized
  * @inuse: whether the channel is in use
  * @lock: protects multiple elements within this structure
+ * @client: client instance
  * @vdev: virtio dev associated with this channel
  * @vq: virtio queue associated with this channel
- * @tagpool: accounting for tag ids (and request slots)
- * @reqs: array of request slots
- * @max_tag: current number of request_slots allocated
  * @sg: scatter gather list which is used to pack a request (protected?)
  *
  * We keep all per-channel information in a structure.
@@ -92,7 +90,7 @@ static unsigned int rest_of_page(void *data)
 
 /**
  * p9_virtio_close - reclaim resources of a channel
- * @trans: transport state
+ * @client: client instance
  *
  * This reclaims a channel by freeing its resources and
  * reseting its inuse flag.
@@ -181,9 +179,8 @@ static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
 
 /**
  * p9_virtio_request - issue a request
- * @t: transport state
- * @tc: &p9_fcall request to transmit
- * @rc: &p9_fcall to put reponse into
+ * @client: client instance issuing the request
+ * @req: request to be issued
  *
  */
 
index df30feb2fc725b047ef744273e7c506714bbac61..1b76eb11deb4a2632a9daca75a414a2906123db4 100644 (file)
@@ -319,6 +319,11 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
 
                        udelay(USEC_PER_POLL);
                }
+
+               WARN_ONCE(!irqs_disabled(),
+                       "netpoll_send_skb(): %s enabled interrupts in poll (%pF)\n",
+                       dev->name, ops->ndo_start_xmit);
+
                local_irq_restore(flags);
        }
 
index bbb25be7ddfe614432ca8627ba4cbe791f57d569..76334228ed1c36e93513a3236957476c1e13291e 100644 (file)
@@ -1025,6 +1025,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
                sk->sk_prot = sk->sk_prot_creator = prot;
                sock_lock_init(sk);
                sock_net_set(sk, get_net(net));
+               atomic_set(&sk->sk_wmem_alloc, 1);
        }
 
        return sk;
@@ -1872,7 +1873,6 @@ void sock_init_data(struct socket *sock, struct sock *sk)
         */
        smp_wmb();
        atomic_set(&sk->sk_refcnt, 1);
-       atomic_set(&sk->sk_wmem_alloc, 1);
        atomic_set(&sk->sk_drops, 0);
 }
 EXPORT_SYMBOL(sock_init_data);
index 7d08210547291b74bc15d001e55eacdb8dd34281..7ffcd96fe591921bd139a1de925991b97f9a74f0 100644 (file)
@@ -813,6 +813,8 @@ int ip_append_data(struct sock *sk,
                        inet->cork.addr = ipc->addr;
                }
                rt = *rtp;
+               if (unlikely(!rt))
+                       return -EFAULT;
                /*
                 * We steal reference to this route, caller should not release it
                 */
index caa0278d30a9dbedb6ca0dc172144c7992e2e485..45f9a2a42d564391134797ac5df3e72c59a60621 100644 (file)
@@ -306,8 +306,10 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                    v4addr != htonl(INADDR_ANY) &&
                    chk_addr_ret != RTN_LOCAL &&
                    chk_addr_ret != RTN_MULTICAST &&
-                   chk_addr_ret != RTN_BROADCAST)
+                   chk_addr_ret != RTN_BROADCAST) {
+                       err = -EADDRNOTAVAIL;
                        goto out;
+               }
        } else {
                if (addr_type != IPV6_ADDR_ANY) {
                        struct net_device *dev = NULL;
index 9208cf5f2bd554fb4d66fba51c327bcc3d7a5aae..c45eee1c0e8d46719df66883caa4d874f806ec5f 100644 (file)
@@ -914,6 +914,7 @@ static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr,
        struct llc_sock *llc = llc_sk(sk);
        int rc = 0;
 
+       memset(&sllc, 0, sizeof(sllc));
        lock_sock(sk);
        if (sock_flag(sk, SOCK_ZAPPED))
                goto out;
index ce267565e18076ec4a852e52aa54bcdc418c0bbf..659a42d529e3cbcd20100452e018b5584fa970a9 100644 (file)
@@ -67,6 +67,8 @@ static DECLARE_WORK(todo_work, key_todo);
  *
  * @key: key to add to do item for
  * @flag: todo flag(s)
+ *
+ * Must be called with IRQs or softirqs disabled.
  */
 static void add_todo(struct ieee80211_key *key, u32 flag)
 {
@@ -140,9 +142,9 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
        ret = drv_set_key(key->local, SET_KEY, &sdata->vif, sta, &key->conf);
 
        if (!ret) {
-               spin_lock(&todo_lock);
+               spin_lock_bh(&todo_lock);
                key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
-               spin_unlock(&todo_lock);
+               spin_unlock_bh(&todo_lock);
        }
 
        if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP)
@@ -164,12 +166,12 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
        if (!key || !key->local->ops->set_key)
                return;
 
-       spin_lock(&todo_lock);
+       spin_lock_bh(&todo_lock);
        if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
-               spin_unlock(&todo_lock);
+               spin_unlock_bh(&todo_lock);
                return;
        }
-       spin_unlock(&todo_lock);
+       spin_unlock_bh(&todo_lock);
 
        sta = get_sta_for_key(key);
        sdata = key->sdata;
@@ -188,9 +190,9 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
                       wiphy_name(key->local->hw.wiphy),
                       key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
 
-       spin_lock(&todo_lock);
+       spin_lock_bh(&todo_lock);
        key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
-       spin_unlock(&todo_lock);
+       spin_unlock_bh(&todo_lock);
 }
 
 static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
@@ -437,14 +439,14 @@ void ieee80211_key_link(struct ieee80211_key *key,
 
        __ieee80211_key_replace(sdata, sta, old_key, key);
 
-       spin_unlock_irqrestore(&sdata->local->key_lock, flags);
-
        /* free old key later */
        add_todo(old_key, KEY_FLAG_TODO_DELETE);
 
        add_todo(key, KEY_FLAG_TODO_ADD_DEBUGFS);
        if (netif_running(sdata->dev))
                add_todo(key, KEY_FLAG_TODO_HWACCEL_ADD);
+
+       spin_unlock_irqrestore(&sdata->local->key_lock, flags);
 }
 
 static void __ieee80211_key_free(struct ieee80211_key *key)
@@ -547,7 +549,7 @@ static void __ieee80211_key_todo(void)
         */
        synchronize_rcu();
 
-       spin_lock(&todo_lock);
+       spin_lock_bh(&todo_lock);
        while (!list_empty(&todo_list)) {
                key = list_first_entry(&todo_list, struct ieee80211_key, todo);
                list_del_init(&key->todo);
@@ -558,7 +560,7 @@ static void __ieee80211_key_todo(void)
                                          KEY_FLAG_TODO_HWACCEL_REMOVE |
                                          KEY_FLAG_TODO_DELETE);
                key->flags &= ~todoflags;
-               spin_unlock(&todo_lock);
+               spin_unlock_bh(&todo_lock);
 
                work_done = false;
 
@@ -591,9 +593,9 @@ static void __ieee80211_key_todo(void)
 
                WARN_ON(!work_done);
 
-               spin_lock(&todo_lock);
+               spin_lock_bh(&todo_lock);
        }
-       spin_unlock(&todo_lock);
+       spin_unlock_bh(&todo_lock);
 }
 
 void ieee80211_key_todo(void)
index 98fc190e8f0eed8683e9836b6be1567ecea74382..390b7d09fe512f2957769ace3b8a579b64f64086 100644 (file)
@@ -52,7 +52,7 @@ static bool quota_mt_check(const struct xt_mtchk_param *par)
 
        q->master = kmalloc(sizeof(*q->master), GFP_KERNEL);
        if (q->master == NULL)
-               return -ENOMEM;
+               return false;
 
        q->master->quota = q->quota;
        return true;
index 24d17ce9c294f384f1a638b7888540455479f3aa..fdb694e9f75938bafad249723c9318b2e4750c3f 100644 (file)
@@ -1456,6 +1456,8 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
        nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags);
        tcm = NLMSG_DATA(nlh);
        tcm->tcm_family = AF_UNSPEC;
+       tcm->tcm__pad1 = 0;
+       tcm->tcm__pad2 = 0;
        tcm->tcm_ifindex = qdisc_dev(q)->ifindex;
        tcm->tcm_parent = q->handle;
        tcm->tcm_handle = q->handle;
index ebfcf9b8990918d65db492add437ae46fa259e30..df1039f077c257840c27dacdecdb29443089b3a6 100644 (file)
@@ -937,6 +937,7 @@ static inline void
 rpc_task_force_reencode(struct rpc_task *task)
 {
        task->tk_rqstp->rq_snd_buf.len = 0;
+       task->tk_rqstp->rq_bytes_sent = 0;
 }
 
 static inline void
index 63003a63aaeedbc6fd6e6badaa3eaa5a705b67a8..46642a19bc78928759aaf753429c10c07e1bcb54 100644 (file)
@@ -45,9 +45,9 @@ int ima_calc_hash(struct file *file, char *digest)
 {
        struct hash_desc desc;
        struct scatterlist sg[1];
-       loff_t i_size;
+       loff_t i_size, offset = 0;
        char *rbuf;
-       int rc, offset = 0;
+       int rc;
 
        rc = init_desc(&desc);
        if (rc != 0)
@@ -67,6 +67,8 @@ int ima_calc_hash(struct file *file, char *digest)
                        rc = rbuf_len;
                        break;
                }
+               if (rbuf_len == 0)
+                       break;
                offset += rbuf_len;
                sg_init_one(sg, rbuf, rbuf_len);
 
index 101c512564ec60a850bf5c56163641c43f16b513..b85e61bcf246c45be863baff63420012d6c765c1 100644 (file)
@@ -249,7 +249,11 @@ void ima_counts_put(struct path *path, int mask)
        struct inode *inode = path->dentry->d_inode;
        struct ima_iint_cache *iint;
 
-       if (!ima_initialized || !S_ISREG(inode->i_mode))
+       /* The inode may already have been freed, freeing the iint
+        * with it. Verify the inode is not NULL before dereferencing
+        * it.
+        */
+       if (!ima_initialized || !inode || !S_ISREG(inode->i_mode))
                return;
        iint = ima_iint_find_insert_get(inode);
        if (!iint)
@@ -262,6 +266,8 @@ void ima_counts_put(struct path *path, int mask)
        else if (mask & (MAY_READ | MAY_EXEC))
                iint->readcount--;
        mutex_unlock(&iint->mutex);
+
+       kref_put(&iint->refcount, iint_free);
 }
 
 /*
@@ -291,6 +297,8 @@ void ima_counts_get(struct file *file)
        if (file->f_mode & FMODE_WRITE)
                iint->writecount++;
        mutex_unlock(&iint->mutex);
+
+       kref_put(&iint->refcount, iint_free);
 }
 EXPORT_SYMBOL_GPL(ima_counts_get);
 
index 72cfd47af6b8b4196ba6a77d52002e3a52ab9e18..9db60d831bb25f67008824b18dab39bdf32b5073 100644 (file)
@@ -943,47 +943,24 @@ static int snd_interval_ratden(struct snd_interval *i,
 int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *list, unsigned int mask)
 {
         unsigned int k;
-       int changed = 0;
+       struct snd_interval list_range;
 
        if (!count) {
                i->empty = 1;
                return -EINVAL;
        }
+       snd_interval_any(&list_range);
+       list_range.min = UINT_MAX;
+       list_range.max = 0;
         for (k = 0; k < count; k++) {
                if (mask && !(mask & (1 << k)))
                        continue;
-                if (i->min == list[k] && !i->openmin)
-                        goto _l1;
-                if (i->min < list[k]) {
-                        i->min = list[k];
-                       i->openmin = 0;
-                       changed = 1;
-                        goto _l1;
-                }
-        }
-        i->empty = 1;
-        return -EINVAL;
- _l1:
-        for (k = count; k-- > 0;) {
-               if (mask && !(mask & (1 << k)))
+               if (!snd_interval_test(i, list[k]))
                        continue;
-                if (i->max == list[k] && !i->openmax)
-                        goto _l2;
-                if (i->max > list[k]) {
-                        i->max = list[k];
-                       i->openmax = 0;
-                       changed = 1;
-                        goto _l2;
-                }
+               list_range.min = min(list_range.min, list[k]);
+               list_range.max = max(list_range.max, list[k]);
         }
-        i->empty = 1;
-        return -EINVAL;
- _l2:
-       if (snd_interval_checkempty(i)) {
-               i->empty = 1;
-               return -EINVAL;
-       }
-        return changed;
+       return snd_interval_refine(i, &list_range);
 }
 
 EXPORT_SYMBOL(snd_interval_list);
index c551006e292054088e5deeaae5baf277403e883a..76d76c08339bd0bb4caedf761740c25b1947cb3e 100644 (file)
@@ -310,12 +310,16 @@ static int snd_ali_codec_ready(struct snd_ali *codec,
        unsigned int res;
        
        end_time = jiffies + msecs_to_jiffies(250);
-       do {
+
+       for (;;) {
                res = snd_ali_5451_peek(codec,port);
                if (!(res & 0x8000))
                        return 0;
+               if (!time_after_eq(end_time, jiffies))
+                       break;
                schedule_timeout_uninterruptible(1);
-       } while (time_after_eq(end_time, jiffies));
+       }
+
        snd_ali_5451_poke(codec, port, res & ~0x8000);
        snd_printdd("ali_codec_ready: codec is not ready.\n ");
        return -EIO;
@@ -327,15 +331,17 @@ static int snd_ali_stimer_ready(struct snd_ali *codec)
        unsigned long dwChk1,dwChk2;
        
        dwChk1 = snd_ali_5451_peek(codec, ALI_STIMER);
-       dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
-
        end_time = jiffies + msecs_to_jiffies(250);
-       do {
+
+       for (;;) {
                dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
                if (dwChk2 != dwChk1)
                        return 0;
+               if (!time_after_eq(end_time, jiffies))
+                       break;
                schedule_timeout_uninterruptible(1);
-       } while (time_after_eq(end_time, jiffies));
+       }
+
        snd_printk(KERN_ERR "ali_stimer_read: stimer is not ready.\n");
        return -EIO;
 }
index 3da85caf8af1318c3a3124606e57545d66f1a8ae..403588c6e3f6112fa137d76774814dba44e5c157 100644 (file)
@@ -3835,9 +3835,11 @@ static struct hda_verb ad1884a_laptop_verbs[] = {
        /* Port-F (int speaker) mixer - route only from analog mixer */
        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
-       /* Port-F pin */
-       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       /* Port-F (int speaker) pin */
+       {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+       /* required for compaq 6530s/6531s speaker output */
+       {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
        /* Port-C pin - internal mic-in */
        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
index fea976793ae5406254fda7f6571a28d3c80ef66b..30eeb304351c875af1c17fd9568a9b5e29dcabdf 100644 (file)
@@ -6423,9 +6423,9 @@ static struct hda_verb alc885_mbp_ch2_init[] = {
 };
 
 /*
- * 6ch mode
+ * 4ch mode
  */
-static struct hda_verb alc885_mbp_ch6_init[] = {
+static struct hda_verb alc885_mbp_ch4_init[] = {
        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
@@ -6434,9 +6434,9 @@ static struct hda_verb alc885_mbp_ch6_init[] = {
        { } /* end */
 };
 
-static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
+static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
        { 2, alc885_mbp_ch2_init },
-       { 6, alc885_mbp_ch6_init },
+       { 4, alc885_mbp_ch4_init },
 };
 
 /*
@@ -6497,10 +6497,11 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
 };
 
 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
-       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
-       HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
-       HDA_CODEC_MUTE  ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
-       HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
+       HDA_BIND_MUTE   ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
+       HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
+       HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
        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, 0x00, HDA_INPUT),
@@ -6814,14 +6815,18 @@ static struct hda_verb alc885_mbp3_init_verbs[] = {
        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+       /* HP mixer */
+       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+       {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
        /* Front Pin: output 0 (0x0c) */
        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
-       /* HP Pin: output 0 (0x0d) */
+       /* HP Pin: output 0 (0x0e) */
        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
-       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
        /* Mic (rear) pin: input vref at 80% */
        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -7195,10 +7200,11 @@ static struct alc_config_preset alc882_presets[] = {
                .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
                .init_verbs = { alc885_mbp3_init_verbs,
                                alc880_gpio1_init_verbs },
-               .num_dacs = ARRAY_SIZE(alc882_dac_nids),
+               .num_dacs = 2,
                .dac_nids = alc882_dac_nids,
-               .channel_mode = alc885_mbp_6ch_modes,
-               .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
+               .hp_nid = 0x04,
+               .channel_mode = alc885_mbp_4ch_modes,
+               .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
                .input_mux = &alc882_capture_source,
                .dig_out_nid = ALC882_DIGOUT_NID,
                .dig_in_nid = ALC882_DIGIN_NID,
@@ -12521,8 +12527,6 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
                           ALC268_TOSHIBA),
        SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
        SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
-       SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
-                          ALC268_TOSHIBA),
        SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
        SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
        SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
@@ -12530,6 +12534,15 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
        {}
 };
 
+/* Toshiba laptops have no unique PCI SSID but only codec SSID */
+static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
+       SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
+       SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
+       SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
+                          ALC268_TOSHIBA),
+       {}
+};
+
 static struct alc_config_preset alc268_presets[] = {
        [ALC267_QUANTA_IL1] = {
                .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
@@ -12696,6 +12709,10 @@ static int patch_alc268(struct hda_codec *codec)
                                                  alc268_models,
                                                  alc268_cfg_tbl);
 
+       if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
+               board_config = snd_hda_check_board_codec_sid_config(codec,
+                       ALC882_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
+
        if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
                printk(KERN_INFO "hda_codec: Unknown model for %s, "
                       "trying auto-probe from BIOS...\n", codec->chip_name);
index 456ef6ac12e40f442a7bb6e6867449452bbf9a5d..6990cfcb6a38e4298ee47611cc44f88862e24bb7 100644 (file)
@@ -76,6 +76,7 @@ enum {
        STAC_92HD73XX_AUTO,
        STAC_92HD73XX_NO_JD, /* no jack-detection */
        STAC_92HD73XX_REF,
+       STAC_92HD73XX_INTEL,
        STAC_DELL_M6_AMIC,
        STAC_DELL_M6_DMIC,
        STAC_DELL_M6_BOTH,
@@ -1777,6 +1778,7 @@ static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
        [STAC_92HD73XX_AUTO] = "auto",
        [STAC_92HD73XX_NO_JD] = "no-jd",
        [STAC_92HD73XX_REF] = "ref",
+       [STAC_92HD73XX_INTEL] = "intel",
        [STAC_DELL_M6_AMIC] = "dell-m6-amic",
        [STAC_DELL_M6_DMIC] = "dell-m6-dmic",
        [STAC_DELL_M6_BOTH] = "dell-m6",
@@ -1789,6 +1791,10 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
                                "DFI LanParty", STAC_92HD73XX_REF),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101,
                                "DFI LanParty", STAC_92HD73XX_REF),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5002,
+                               "Intel DG45ID", STAC_92HD73XX_INTEL),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5003,
+                               "Intel DG45FC", STAC_92HD73XX_INTEL),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254,
                                "Dell Studio 1535", STAC_DELL_M6_DMIC),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255,
index 9008b4b013aa7a6feddf45d52e55a8c994a5a45e..e8f10b10cceb046f360d8320b8ccd5e0001c2988 100644 (file)
@@ -1395,6 +1395,7 @@ static int patch_vt1708(struct hda_codec *codec)
        if (!spec->adc_nids && spec->input_mux) {
                spec->adc_nids = vt1708_adc_nids;
                spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
+               get_mux_nids(codec);
                spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
                spec->num_mixers++;
        }
index 312251d396965404b96311bcc7cda92f409b600b..9a8936e207448e792218d1c3aee804fb09db30e6 100644 (file)
@@ -260,6 +260,9 @@ oxygen_search_pci_id(struct oxygen *chip, const struct pci_device_id ids[])
         * chip didn't if the first EEPROM word was overwritten.
         */
        subdevice = oxygen_read_eeprom(chip, 2);
+       /* use default ID if EEPROM is missing */
+       if (subdevice == 0xffff)
+               subdevice = 0x8788;
        /*
         * We use only the subsystem device ID for searching because it is
         * unique even without the subsystem vendor ID, which may have been
index 3b5ca70c9d4d2745223ac6f66102f8fd78e11161..ef2345d82b8652c55df39623fc9ca6e2f6d85f87 100644 (file)
@@ -469,9 +469,11 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
        oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
                              oxygen_rate(hw_params) |
                              chip->model.dac_i2s_format |
+                             oxygen_i2s_mclk(hw_params) |
                              oxygen_i2s_bits(hw_params),
                              OXYGEN_I2S_RATE_MASK |
                              OXYGEN_I2S_FORMAT_MASK |
+                             OXYGEN_I2S_MCLK_MASK |
                              OXYGEN_I2S_BITS_MASK);
        oxygen_update_dac_routing(chip);
        oxygen_update_spdif_source(chip);
index 6416d3f0c7be8210559f1ad8dda61f1a974fc023..a69e774d0b138f46d373cab95bb78858e04c1f11 100644 (file)
@@ -885,10 +885,10 @@ static int vx_input_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
        struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
        struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
        if (ucontrol->value.integer.value[0] < 0 ||
-           ucontrol->value.integer.value[0] < MIC_LEVEL_MAX)
+           ucontrol->value.integer.value[0] > MIC_LEVEL_MAX)
                return -EINVAL;
        if (ucontrol->value.integer.value[1] < 0 ||
-           ucontrol->value.integer.value[1] < MIC_LEVEL_MAX)
+           ucontrol->value.integer.value[1] > MIC_LEVEL_MAX)
                return -EINVAL;
        mutex_lock(&_chip->mixer_mutex);
        if (chip->input_level[0] != ucontrol->value.integer.value[0] ||
index 343e7b14bf0118e3ee7d01d9caa0b70462a25fa6..5e17de984dc839d0ad86932d73bf4e2c2c85b272 100644 (file)
@@ -31,6 +31,7 @@ static char           *vmlinux = "vmlinux";
 static char            default_sort_order[] = "comm,symbol";
 static char            *sort_order = default_sort_order;
 
+static int             force;
 static int             input;
 static int             show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV;
 
@@ -1334,6 +1335,11 @@ static int __cmd_annotate(void)
                exit(-1);
        }
 
+       if (!force && (stat.st_uid != geteuid())) {
+               fprintf(stderr, "file: %s not owned by current user\n", input_name);
+               exit(-1);
+       }
+
        if (!stat.st_size) {
                fprintf(stderr, "zero-sized file, nothing to do!\n");
                exit(0);
@@ -1439,6 +1445,7 @@ static const struct option options[] = {
                    "input file name"),
        OPT_STRING('s', "symbol", &sym_hist_filter, "symbol",
                    "symbol to annotate"),
+       OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
        OPT_BOOLEAN('v', "verbose", &verbose,
                    "be more verbose (show symbol address, etc)"),
        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
index b53a60fc12de77115218a275235df61fdb61da09..8b2ec882e6e0e8b44230c1d3648007d3d91ccbfe 100644 (file)
@@ -38,6 +38,7 @@ static char           *dso_list_str, *comm_list_str, *sym_list_str,
 static struct strlist  *dso_list, *comm_list, *sym_list;
 static char            *field_sep;
 
+static int             force;
 static int             input;
 static int             show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV;
 
@@ -1856,6 +1857,11 @@ static int __cmd_report(void)
                exit(-1);
        }
 
+       if (!force && (stat.st_uid != geteuid())) {
+               fprintf(stderr, "file: %s not owned by current user\n", input_name);
+               exit(-1);
+       }
+
        if (!stat.st_size) {
                fprintf(stderr, "zero-sized file, nothing to do!\n");
                exit(0);
@@ -2064,6 +2070,7 @@ static const struct option options[] = {
        OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
                    "dump raw trace in ASCII"),
        OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
+       OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
        OPT_BOOLEAN('m', "modules", &modules,
                    "load module symbols - WARNING: use only with -k and LIVE kernel"),
        OPT_BOOLEAN('n', "show-nr-samples", &show_nr_samples,