]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branch 'master' into for-linus
authorRafael J. Wysocki <rjw@sisk.pl>
Sun, 16 Aug 2009 09:50:10 +0000 (11:50 +0200)
committerRafael J. Wysocki <rjw@sisk.pl>
Sun, 16 Aug 2009 09:50:10 +0000 (11:50 +0200)
167 files changed:
Documentation/kernel-parameters.txt
Documentation/video4linux/CARDLIST.em28xx
Documentation/video4linux/CARDLIST.saa7134
MAINTAINERS
Makefile
arch/ia64/Makefile
arch/ia64/include/asm/bitops.h
arch/ia64/include/asm/pgtable.h
arch/ia64/kernel/ia64_ksyms.c
arch/ia64/kernel/iosapic.c
arch/ia64/kernel/pci-dma.c
arch/ia64/kernel/topology.c
arch/sh/boards/board-ap325rxa.c
arch/sh/boards/mach-migor/setup.c
arch/sh/kernel/cpu/sh2/setup-sh7619.c
arch/sh/kernel/cpu/sh2a/setup-mxg.c
arch/sh/kernel/cpu/sh2a/setup-sh7201.c
arch/sh/kernel/cpu/sh2a/setup-sh7203.c
arch/sh/kernel/cpu/sh2a/setup-sh7206.c
arch/sh/kernel/cpu/sh3/setup-sh7705.c
arch/sh/kernel/cpu/sh3/setup-sh770x.c
arch/sh/kernel/cpu/sh3/setup-sh7710.c
arch/sh/kernel/cpu/sh3/setup-sh7720.c
arch/sh/kernel/cpu/sh4/setup-sh4-202.c
arch/sh/kernel/cpu/sh4/setup-sh7750.c
arch/sh/kernel/cpu/sh4/setup-sh7760.c
arch/sh/kernel/cpu/sh4a/setup-sh7343.c
arch/sh/kernel/cpu/sh4a/setup-sh7366.c
arch/sh/kernel/cpu/sh4a/setup-sh7722.c
arch/sh/kernel/cpu/sh4a/setup-sh7723.c
arch/sh/kernel/cpu/sh4a/setup-sh7724.c
arch/sh/kernel/cpu/sh4a/setup-sh7763.c
arch/sh/kernel/cpu/sh4a/setup-sh7770.c
arch/sh/kernel/cpu/sh4a/setup-sh7780.c
arch/sh/kernel/cpu/sh4a/setup-sh7785.c
arch/sh/kernel/cpu/sh4a/setup-sh7786.c
arch/sh/kernel/cpu/sh4a/setup-shx3.c
arch/sh/kernel/cpu/sh5/setup-sh5.c
arch/x86/Kconfig
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/cpu/mcheck/therm_throt.c
arch/x86/kernel/cpu/perf_counter.c
arch/x86/kernel/reboot.c
drivers/ata/ahci.c
drivers/ata/libata-core.c
drivers/ata/pata_at91.c
drivers/ata/pata_atiixp.c
drivers/ata/sata_nv.c
drivers/base/platform.c
drivers/md/md.c
drivers/md/md.h
drivers/md/raid5.c
drivers/media/common/tuners/qt1010.c
drivers/media/common/tuners/tuner-xc2028.c
drivers/media/common/tuners/tuner-xc2028.h
drivers/media/dvb/dvb-usb/af9015.c
drivers/media/dvb/frontends/cx22700.c
drivers/media/dvb/frontends/cx22702.c
drivers/media/dvb/frontends/cx24110.c
drivers/media/dvb/frontends/dvb_dummy_fe.c
drivers/media/dvb/frontends/l64781.c
drivers/media/dvb/frontends/lgs8gl5.c
drivers/media/dvb/frontends/mt312.c
drivers/media/dvb/frontends/nxt6000.c
drivers/media/dvb/frontends/or51132.c
drivers/media/dvb/frontends/or51211.c
drivers/media/dvb/frontends/s5h1409.c
drivers/media/dvb/frontends/s5h1411.c
drivers/media/dvb/frontends/si21xx.c
drivers/media/dvb/frontends/sp8870.c
drivers/media/dvb/frontends/sp887x.c
drivers/media/dvb/frontends/stv0288.c
drivers/media/dvb/frontends/stv0297.c
drivers/media/dvb/frontends/stv0299.c
drivers/media/dvb/frontends/tda10021.c
drivers/media/dvb/frontends/tda10048.c
drivers/media/dvb/frontends/tda1004x.c
drivers/media/dvb/frontends/tda10086.c
drivers/media/dvb/frontends/tda8083.c
drivers/media/dvb/frontends/ves1820.c
drivers/media/dvb/frontends/ves1x93.c
drivers/media/dvb/frontends/zl10353.c
drivers/media/dvb/siano/Kconfig
drivers/media/dvb/siano/sms-cards.c
drivers/media/dvb/siano/smscoreapi.c
drivers/media/video/Kconfig
drivers/media/video/bw-qcam.c
drivers/media/video/cx18/cx18-controls.c
drivers/media/video/cx23885/cx23885-417.c
drivers/media/video/cx88/cx88-cards.c
drivers/media/video/cx88/cx88-dvb.c
drivers/media/video/cx88/cx88-mpeg.c
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/em28xx/em28xx-core.c
drivers/media/video/em28xx/em28xx-dvb.c
drivers/media/video/em28xx/em28xx-reg.h
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/em28xx/em28xx.h
drivers/media/video/hdpvr/hdpvr-video.c
drivers/media/video/ivtv/ivtv-controls.c
drivers/media/video/mt9v011.c
drivers/media/video/mt9v011.h
drivers/media/video/mx1_camera.c
drivers/media/video/mx3_camera.c
drivers/media/video/pxa_camera.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-dvb.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/sh_mobile_ceu_camera.c
drivers/media/video/stk-webcam.c
drivers/media/video/uvc/uvc_driver.c
drivers/media/video/uvc/uvc_status.c
drivers/media/video/v4l2-ioctl.c
drivers/mtd/maps/sbc8240.c [deleted file]
fs/gfs2/sys.c
fs/nfs/direct.c
fs/nfs/read.c
fs/nfs/write.c
fs/ocfs2/alloc.c
fs/ocfs2/aops.c
fs/ocfs2/dcache.c
fs/ocfs2/dcache.h
fs/ocfs2/dlm/dlmast.c
fs/ocfs2/dlm/dlmrecovery.c
fs/ocfs2/file.c
fs/ocfs2/journal.c
fs/ocfs2/journal.h
fs/ocfs2/ocfs2.h
fs/ocfs2/quota.h
fs/ocfs2/quota_global.c
fs/ocfs2/quota_local.c
fs/ocfs2/stack_o2cb.c
fs/ocfs2/super.c
fs/ocfs2/xattr.c
fs/select.c
fs/xfs/linux-2.6/xfs_buf.c
fs/xfs/xfs_attr.c
fs/xfs/xfs_bmap.c
fs/xfs/xfs_btree.c
fs/xfs/xfs_da_btree.c
fs/xfs/xfs_dir2.c
fs/xfs/xfs_fsops.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_log.c
fs/xfs/xfs_vnodeops.c
include/linux/nfs_fs.h
include/linux/perf_counter.h
include/linux/wait.h
kernel/futex.c
kernel/futex_compat.c
kernel/irq/manage.c
kernel/perf_counter.c
kernel/trace/blktrace.c
kernel/wait.c
net/socket.c
security/selinux/hooks.c
sound/pci/hda/patch_realtek.c
sound/soc/fsl/efika-audio-fabric.c
sound/soc/fsl/pcm030-audio-fabric.c
tools/perf/Makefile
tools/perf/builtin-list.c
tools/perf/builtin-record.c
tools/perf/builtin-report.c
tools/perf/util/parse-events.c
tools/perf/util/symbol.c
tools/perf/util/symbol.h

index dd1a6d4bb7473c4966a720c40e8af0492f9853c5..7936b801fe6acc8e4dfe0f6f288a2e8ce9e81e08 100644 (file)
@@ -1115,6 +1115,10 @@ and is between 256 and 4096 characters. It is defined in the file
                        libata.dma=4      Compact Flash DMA only 
                        Combinations also work, so libata.dma=3 enables DMA
                        for disks and CDROMs, but not CFs.
+       
+       libata.ignore_hpa=      [LIBATA] Ignore HPA limit
+                       libata.ignore_hpa=0       keep BIOS limits (default)
+                       libata.ignore_hpa=1       ignore limits, using full disk
 
        libata.noacpi   [LIBATA] Disables use of ACPI in libata suspend/resume
                        when set.
index 68c236c018462e2e3d687e4a078c44815786db0d..e352d754875cae415b0c27d766336c00942cd241 100644 (file)
@@ -1,5 +1,5 @@
   0 -> Unknown EM2800 video grabber             (em2800)        [eb1a:2800]
-  1 -> Unknown EM2750/28xx video grabber        (em2820/em2840) [eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883]
+  1 -> Unknown EM2750/28xx video grabber        (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883]
   2 -> Terratec Cinergy 250 USB                 (em2820/em2840) [0ccd:0036]
   3 -> Pinnacle PCTV USB 2                      (em2820/em2840) [2304:0208]
   4 -> Hauppauge WinTV USB 2                    (em2820/em2840) [2040:4200,2040:4201]
index 15562427e8a9cb51b7f7611bb38a0bc7975bfa65..c913e5614195a9a359411ee163f8c2e081d24a2a 100644 (file)
 152 -> Asus Tiger Rev:1.00                      [1043:4857]
 153 -> Kworld Plus TV Analog Lite PCI           [17de:7128]
 154 -> Avermedia AVerTV GO 007 FM Plus          [1461:f31d]
-155 -> Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid  [0070:6706,0070:6708]
-156 -> Hauppauge WinTV-HVR1110r3 DVB-T/Hybrid   [0070:6707,0070:6709,0070:670a]
+155 -> Hauppauge WinTV-HVR1150 ATSC/QAM-Hybrid  [0070:6706,0070:6708]
+156 -> Hauppauge WinTV-HVR1120 DVB-T/Hybrid     [0070:6707,0070:6709,0070:670a]
 157 -> Avermedia AVerTV Studio 507UA            [1461:a11b]
 158 -> AVerMedia Cardbus TV/Radio (E501R)       [1461:b7e9]
 159 -> Beholder BeholdTV 505 RDS                [0000:505B]
index b1114cfac6bf22b9d7fc015af9cad2e628b0bbcb..2c4326c0de9a52e684b66a0b92f4e2bed378991f 100644 (file)
@@ -2238,6 +2238,14 @@ T:       git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
 S:     Maintained
 F:     drivers/media/video/gspca/pac207.c
 
+GSPCA SN9C20X SUBDRIVER
+P:     Brian Johnson
+M:     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
+F:     drivers/media/video/gspca/sn9c20x.c
+
 GSPCA T613 SUBDRIVER
 M:     Leandro Costantino <lcostantino@gmail.com>
 L:     linux-media@vger.kernel.org
index 0d46615bffe5c95704a83cfb7cdf82d2fa792c48..abcfa85f8f825392890bc26da007e5af3fd94d6c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 31
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc6
 NAME = Man-Eating Seals of Antiquity
 
 # *DOCUMENTATION*
index 58a7e46affda28b44daf8199244ab3eca354fa8a..e7cbaa02cd0b432fa99c43d0c8de742b2c11d485 100644 (file)
@@ -41,11 +41,6 @@ $(error Sorry, you need a newer version of the assember, one that is built from
                ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz)
 endif
 
-ifeq ($(call cc-version),0304)
-       cflags-$(CONFIG_ITANIUM)        += -mtune=merced
-       cflags-$(CONFIG_MCKINLEY)       += -mtune=mckinley
-endif
-
 KBUILD_CFLAGS += $(cflags-y)
 head-y := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o
 
index e2ca800373351d26b1042394275ebe10f6c8d23e..57a2787bc9fb62e6d5cadc62a2bc394e78cca707 100644 (file)
@@ -286,7 +286,7 @@ __test_and_clear_bit(int nr, volatile void * addr)
 {
        __u32 *p = (__u32 *) addr + (nr >> 5);
        __u32 m = 1 << (nr & 31);
-       int oldbitset = *p & m;
+       int oldbitset = (*p & m) != 0;
 
        *p &= ~m;
        return oldbitset;
index 0a9cc73d35c78fac88f4733511021849a0b2a248..8840a690d1e7aa346b82fc68672186631c2e0828 100644 (file)
 #include <linux/bitops.h>
 #include <asm/cacheflush.h>
 #include <asm/mmu_context.h>
-#include <asm/processor.h>
 
 /*
  * Next come the mappings that determine how mmap() protection bits
index 2d311864e359d93036ae8e4b31d0e39f5ee56c4d..8ebccb589e1c28a5797186633a840bfc80933d1c 100644 (file)
@@ -21,6 +21,7 @@ EXPORT_SYMBOL(csum_ipv6_magic);
 
 #include <asm/page.h>
 EXPORT_SYMBOL(clear_page);
+EXPORT_SYMBOL(copy_page);
 
 #ifdef CONFIG_VIRTUAL_MEM_MAP
 #include <linux/bootmem.h>
@@ -60,9 +61,6 @@ EXPORT_SYMBOL(__udivdi3);
 EXPORT_SYMBOL(__moddi3);
 EXPORT_SYMBOL(__umoddi3);
 
-#include <asm/page.h>
-EXPORT_SYMBOL(copy_page);
-
 #if defined(CONFIG_MD_RAID456) || defined(CONFIG_MD_RAID456_MODULE)
 extern void xor_ia64_2(void);
 extern void xor_ia64_3(void);
index c48b03f2b61dd30aaf22da1fcec101d59fd0b426..dab4d393908c6323279ea61e1443f0e31961834f 100644 (file)
@@ -1072,6 +1072,10 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
        }
 
        addr = ioremap(phys_addr, 0);
+       if (addr == NULL) {
+               spin_unlock_irqrestore(&iosapic_lock, flags);
+               return -ENOMEM;
+       }
        ver = iosapic_version(addr);
        if ((err = iosapic_check_gsi_range(gsi_base, ver))) {
                iounmap(addr);
index 05695962fe4405bd8a028b33c8665158af14a2c3..f6b1ff0aea76f95b094c01be87a7b4c98393a3f2 100644 (file)
@@ -69,11 +69,6 @@ iommu_dma_init(void)
 
 int iommu_dma_supported(struct device *dev, u64 mask)
 {
-       struct dma_map_ops *ops = platform_dma_get_ops(dev);
-
-       if (ops->dma_supported)
-               return ops->dma_supported(dev, mask);
-
        /* Copied from i386. Doesn't make much sense, because it will
           only work for pci_alloc_coherent.
           The caller just has to use GFP_DMA in this case. */
index bc80dff1df7ae8a421f78d34ddab8f7ddc8cb034..8f060352e1297acf0d91db5b512b6ac12d022a36 100644 (file)
@@ -372,6 +372,10 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
        retval = kobject_init_and_add(&all_cpu_cache_info[cpu].kobj,
                                      &cache_ktype_percpu_entry, &sys_dev->kobj,
                                      "%s", "cache");
+       if (unlikely(retval < 0)) {
+               cpu_cache_sysfs_exit(cpu);
+               return retval;
+       }
 
        for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++) {
                this_object = LEAF_KOBJECT_PTR(cpu,i);
@@ -385,7 +389,7 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
                        }
                        kobject_put(&all_cpu_cache_info[cpu].kobj);
                        cpu_cache_sysfs_exit(cpu);
-                       break;
+                       return retval;
                }
                kobject_uevent(&(this_object->kobj), KOBJ_ADD);
        }
index 7ffd1b4315bd9711119d9319b7a4204c1d332fe2..b9c88cc519e2f1e5d48c3bed83326b6820407a5e 100644 (file)
@@ -547,7 +547,7 @@ static int __init ap325rxa_devices_setup(void)
        return platform_add_devices(ap325rxa_devices,
                                ARRAY_SIZE(ap325rxa_devices));
 }
-device_initcall(ap325rxa_devices_setup);
+arch_initcall(ap325rxa_devices_setup);
 
 /* Return the board specific boot mode pin configuration */
 static int ap325rxa_mode_pins(void)
index f70f4644deb4e835ed54fdea8f3a39a6d3ee2ebd..f9b2e4df35b9c10e33d3638e9a7c88787e2f4be3 100644 (file)
@@ -608,7 +608,7 @@ static int __init migor_devices_setup(void)
 
        return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices));
 }
-__initcall(migor_devices_setup);
+arch_initcall(migor_devices_setup);
 
 /* Return the board specific boot mode pin configuration */
 static int migor_mode_pins(void)
index 13798733f2db93f6db46bf40d4347a3162fcde75..8555c05e86677f7cf3512b4d773ccd781e8a4cac 100644 (file)
@@ -187,7 +187,7 @@ static int __init sh7619_devices_setup(void)
        return platform_add_devices(sh7619_devices,
                                    ARRAY_SIZE(sh7619_devices));
 }
-__initcall(sh7619_devices_setup);
+arch_initcall(sh7619_devices_setup);
 
 void __init plat_irq_setup(void)
 {
index 869c2da4820b3b763142146ab1b16deb288dcc06..b67376445315b47045433ef7118d7460faba99e4 100644 (file)
@@ -238,7 +238,7 @@ static int __init mxg_devices_setup(void)
        return platform_add_devices(mxg_devices,
                                    ARRAY_SIZE(mxg_devices));
 }
-__initcall(mxg_devices_setup);
+arch_initcall(mxg_devices_setup);
 
 void __init plat_irq_setup(void)
 {
index d8febe12806620cee8058b874a454039bc029f89..fbde5b75deb9152ba615c28af7c68652bc224ba8 100644 (file)
@@ -357,7 +357,7 @@ static int __init sh7201_devices_setup(void)
        return platform_add_devices(sh7201_devices,
                                    ARRAY_SIZE(sh7201_devices));
 }
-__initcall(sh7201_devices_setup);
+arch_initcall(sh7201_devices_setup);
 
 void __init plat_irq_setup(void)
 {
index 62e3039d2398ad0071044b0d1f4a7423d08e9d4d..d3fd536c9a842e08634a982c3c7b4330d749f05e 100644 (file)
@@ -367,7 +367,7 @@ static int __init sh7203_devices_setup(void)
        return platform_add_devices(sh7203_devices,
                                    ARRAY_SIZE(sh7203_devices));
 }
-__initcall(sh7203_devices_setup);
+arch_initcall(sh7203_devices_setup);
 
 void __init plat_irq_setup(void)
 {
index 3e6f3d7a58be990cbaa06b5022ab1624be92b8fb..a9ccc5e8d9e98af493bf45ed7fdeb4430c0cc11b 100644 (file)
@@ -338,7 +338,7 @@ static int __init sh7206_devices_setup(void)
        return platform_add_devices(sh7206_devices,
                                    ARRAY_SIZE(sh7206_devices));
 }
-__initcall(sh7206_devices_setup);
+arch_initcall(sh7206_devices_setup);
 
 void __init plat_irq_setup(void)
 {
index 88f742fed9edf445269743a6f5198c656ebc9117..c231059838780cc294d6f5f5cc7ea0a167eada0c 100644 (file)
@@ -222,7 +222,7 @@ static int __init sh7705_devices_setup(void)
        return platform_add_devices(sh7705_devices,
                                    ARRAY_SIZE(sh7705_devices));
 }
-__initcall(sh7705_devices_setup);
+arch_initcall(sh7705_devices_setup);
 
 static struct platform_device *sh7705_early_devices[] __initdata = {
        &tmu0_device,
index c56306798584f68989ab9d5c82c89071141122e1..347ab35d0697bf6cb0899f18b87153cb69117b32 100644 (file)
@@ -250,7 +250,7 @@ static int __init sh770x_devices_setup(void)
        return platform_add_devices(sh770x_devices,
                ARRAY_SIZE(sh770x_devices));
 }
-__initcall(sh770x_devices_setup);
+arch_initcall(sh770x_devices_setup);
 
 static struct platform_device *sh770x_early_devices[] __initdata = {
        &tmu0_device,
index efa76c8148f4e4d2ab7807852d07c3aa5e3cc918..717e90ae1097a00efb701ba958013c844f6a55a4 100644 (file)
@@ -226,7 +226,7 @@ static int __init sh7710_devices_setup(void)
        return platform_add_devices(sh7710_devices,
                                    ARRAY_SIZE(sh7710_devices));
 }
-__initcall(sh7710_devices_setup);
+arch_initcall(sh7710_devices_setup);
 
 static struct platform_device *sh7710_early_devices[] __initdata = {
        &tmu0_device,
index 5b2107798edbe3fc804a19940c63def3e0dc850b..74d8baaf8e9675c2f740a45e30b2cffcbd66ffc6 100644 (file)
@@ -388,7 +388,7 @@ static int __init sh7720_devices_setup(void)
        return platform_add_devices(sh7720_devices,
                                    ARRAY_SIZE(sh7720_devices));
 }
-__initcall(sh7720_devices_setup);
+arch_initcall(sh7720_devices_setup);
 
 static struct platform_device *sh7720_early_devices[] __initdata = {
        &cmt0_device,
index 6d088d12359172f8b8b9d9e99ee3162ad46f06a5..de4827df19aacc41dcb589128c6d6e62f7a147e6 100644 (file)
@@ -138,7 +138,7 @@ static int __init sh4202_devices_setup(void)
        return platform_add_devices(sh4202_devices,
                                    ARRAY_SIZE(sh4202_devices));
 }
-__initcall(sh4202_devices_setup);
+arch_initcall(sh4202_devices_setup);
 
 static struct platform_device *sh4202_early_devices[] __initdata = {
        &tmu0_device,
index 851672d15cf4a15e5f3b2208681417a269d1ba99..1b8b122e8f3dd46f5898ba0710432f83c5578b2e 100644 (file)
@@ -239,7 +239,7 @@ static int __init sh7750_devices_setup(void)
        return platform_add_devices(sh7750_devices,
                                    ARRAY_SIZE(sh7750_devices));
 }
-__initcall(sh7750_devices_setup);
+arch_initcall(sh7750_devices_setup);
 
 static struct platform_device *sh7750_early_devices[] __initdata = {
        &tmu0_device,
index 5b822519bd90cb7593b74338b9442adc734caab9..7fbb7be9284ca86950ead92da5ca337f0c0e7b99 100644 (file)
@@ -265,7 +265,7 @@ static int __init sh7760_devices_setup(void)
        return platform_add_devices(sh7760_devices,
                                    ARRAY_SIZE(sh7760_devices));
 }
-__initcall(sh7760_devices_setup);
+arch_initcall(sh7760_devices_setup);
 
 static struct platform_device *sh7760_early_devices[] __initdata = {
        &tmu0_device,
index 6307e087c8642f1527323414bf24d71a73dda184..ac4d5672ec1a25ff053191fa7c60bd46dfaf5da5 100644 (file)
@@ -325,7 +325,7 @@ static int __init sh7343_devices_setup(void)
        return platform_add_devices(sh7343_devices,
                                    ARRAY_SIZE(sh7343_devices));
 }
-__initcall(sh7343_devices_setup);
+arch_initcall(sh7343_devices_setup);
 
 static struct platform_device *sh7343_early_devices[] __initdata = {
        &cmt_device,
index c18f7d09281bbd80d333d2773b321b907044fd68..1a956b1beccc5f320f7e7fd206669bd2d69c2ac8 100644 (file)
@@ -318,7 +318,7 @@ static int __init sh7366_devices_setup(void)
        return platform_add_devices(sh7366_devices,
                                    ARRAY_SIZE(sh7366_devices));
 }
-__initcall(sh7366_devices_setup);
+arch_initcall(sh7366_devices_setup);
 
 static struct platform_device *sh7366_early_devices[] __initdata = {
        &cmt_device,
index ea524a2da3e477ffe15176a672b5936add4fa435..cda76ebf87c386a4e51f51a62f874971e41c9cd2 100644 (file)
@@ -359,7 +359,7 @@ static int __init sh7722_devices_setup(void)
        return platform_add_devices(sh7722_devices,
                                    ARRAY_SIZE(sh7722_devices));
 }
-__initcall(sh7722_devices_setup);
+arch_initcall(sh7722_devices_setup);
 
 static struct platform_device *sh7722_early_devices[] __initdata = {
        &cmt_device,
index e1bb80b2a27b55c948f95e2e15e146fe5ff82319..b45dace9539fdf23cf0af0d46159438f0f045f29 100644 (file)
@@ -473,7 +473,7 @@ static int __init sh7723_devices_setup(void)
        return platform_add_devices(sh7723_devices,
                                    ARRAY_SIZE(sh7723_devices));
 }
-__initcall(sh7723_devices_setup);
+arch_initcall(sh7723_devices_setup);
 
 static struct platform_device *sh7723_early_devices[] __initdata = {
        &cmt_device,
index e5ac9eb11c63a813612ea490f5a9ab218af925e5..a04edaab9a29172316262cd9da0549d0c8848e37 100644 (file)
@@ -508,7 +508,7 @@ static int __init sh7724_devices_setup(void)
        return platform_add_devices(sh7724_devices,
                                    ARRAY_SIZE(sh7724_devices));
 }
-device_initcall(sh7724_devices_setup);
+arch_initcall(sh7724_devices_setup);
 
 static struct platform_device *sh7724_early_devices[] __initdata = {
        &cmt_device,
index f1e0c0d36da74121e6a3d40933da1813c7bbe6e2..4659fff6b842057defff64a65b506714170d3c99 100644 (file)
@@ -314,7 +314,7 @@ static int __init sh7763_devices_setup(void)
        return platform_add_devices(sh7763_devices,
                                    ARRAY_SIZE(sh7763_devices));
 }
-__initcall(sh7763_devices_setup);
+arch_initcall(sh7763_devices_setup);
 
 static struct platform_device *sh7763_early_devices[] __initdata = {
        &tmu0_device,
index 1e86209db284357791338b5ba9f2bd771f7f358c..eead08d89d32548932e32e6840702e068a538a89 100644 (file)
@@ -368,7 +368,7 @@ static int __init sh7770_devices_setup(void)
        return platform_add_devices(sh7770_devices,
                                    ARRAY_SIZE(sh7770_devices));
 }
-__initcall(sh7770_devices_setup);
+arch_initcall(sh7770_devices_setup);
 
 static struct platform_device *sh7770_early_devices[] __initdata = {
        &tmu0_device,
index 715e05b431e5e7f4b8c027f608803fab0d8edaba..2c901f446959d3fe70fa4e08128b35f14e01d038 100644 (file)
@@ -256,7 +256,7 @@ static int __init sh7780_devices_setup(void)
        return platform_add_devices(sh7780_devices,
                                    ARRAY_SIZE(sh7780_devices));
 }
-__initcall(sh7780_devices_setup);
+arch_initcall(sh7780_devices_setup);
 
 static struct platform_device *sh7780_early_devices[] __initdata = {
        &tmu0_device,
index af561402570bdb411a026a1127b5e42a54fdc524..7f6c718b6c36e4de8722cf41b571f3c0700bd703 100644 (file)
@@ -263,7 +263,7 @@ static int __init sh7785_devices_setup(void)
        return platform_add_devices(sh7785_devices,
                                    ARRAY_SIZE(sh7785_devices));
 }
-__initcall(sh7785_devices_setup);
+arch_initcall(sh7785_devices_setup);
 
 static struct platform_device *sh7785_early_devices[] __initdata = {
        &tmu0_device,
index b70049470a0bae775c1db1cf9cb34ef79edbec86..0104a8ec53691a4ad26c6f80476d4f8c2a9ff361 100644 (file)
@@ -547,7 +547,7 @@ static int __init sh7786_devices_setup(void)
        return platform_add_devices(sh7786_devices,
                                    ARRAY_SIZE(sh7786_devices));
 }
-device_initcall(sh7786_devices_setup);
+arch_initcall(sh7786_devices_setup);
 
 void __init plat_early_device_setup(void)
 {
index 53c65fd9ccef726d015cd71b664a151842e4731d..07f078961c715813a8dfbdbcff0777a06782b5c3 100644 (file)
@@ -256,7 +256,7 @@ static int __init shx3_devices_setup(void)
        return platform_add_devices(shx3_devices,
                                    ARRAY_SIZE(shx3_devices));
 }
-__initcall(shx3_devices_setup);
+arch_initcall(shx3_devices_setup);
 
 void __init plat_early_device_setup(void)
 {
index f5ff1ac57fc2879a9cd39978fe77038e2c8981a6..6a0f82f700323ce02d06fe91f7eb766b48a9b349 100644 (file)
@@ -186,7 +186,7 @@ static int __init sh5_devices_setup(void)
        return platform_add_devices(sh5_devices,
                                    ARRAY_SIZE(sh5_devices));
 }
-__initcall(sh5_devices_setup);
+arch_initcall(sh5_devices_setup);
 
 void __init plat_early_device_setup(void)
 {
index 738bdc6b0f8b8dcd938eddefa79beb4ed77e16f2..13ffa5df37d75120e6a3965102b24a05d3ee0fb7 100644 (file)
@@ -24,6 +24,7 @@ config X86
        select HAVE_UNSTABLE_SCHED_CLOCK
        select HAVE_IDE
        select HAVE_OPROFILE
+       select HAVE_PERF_COUNTERS if (!M386 && !M486)
        select HAVE_IOREMAP_PROT
        select HAVE_KPROBES
        select ARCH_WANT_OPTIONAL_GPIOLIB
@@ -742,7 +743,6 @@ config X86_UP_IOAPIC
 config X86_LOCAL_APIC
        def_bool y
        depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC
-       select HAVE_PERF_COUNTERS if (!M386 && !M486)
 
 config X86_IO_APIC
        def_bool y
index e2485b03f1cf2649341c9c8d9412495f894eeaa4..63fddcd082cdf2a3b4cc261d54608ec2dac07b64 100644 (file)
@@ -400,6 +400,13 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
                level = cpuid_eax(1);
                if((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)
                        set_cpu_cap(c, X86_FEATURE_REP_GOOD);
+
+               /*
+                * Some BIOSes incorrectly force this feature, but only K8
+                * revision D (model = 0x14) and later actually support it.
+                */
+               if (c->x86_model < 0x14)
+                       clear_cpu_cap(c, X86_FEATURE_LAHF_LM);
        }
        if (c->x86 == 0x10 || c->x86 == 0x11)
                set_cpu_cap(c, X86_FEATURE_REP_GOOD);
index f1961c07af9a684b0fd15ad1636ef21dbf1d31ac..5ce60a88027b16a46edf3b1afb3430d550cd5012 100644 (file)
@@ -59,7 +59,30 @@ void __init setup_cpu_local_masks(void)
        alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask);
 }
 
-static const struct cpu_dev *this_cpu __cpuinitdata;
+static void __cpuinit default_init(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_X86_64
+       display_cacheinfo(c);
+#else
+       /* Not much we can do here... */
+       /* Check if at least it has cpuid */
+       if (c->cpuid_level == -1) {
+               /* No cpuid. It must be an ancient CPU */
+               if (c->x86 == 4)
+                       strcpy(c->x86_model_id, "486");
+               else if (c->x86 == 3)
+                       strcpy(c->x86_model_id, "386");
+       }
+#endif
+}
+
+static const struct cpu_dev __cpuinitconst default_cpu = {
+       .c_init         = default_init,
+       .c_vendor       = "Unknown",
+       .c_x86_vendor   = X86_VENDOR_UNKNOWN,
+};
+
+static const struct cpu_dev *this_cpu __cpuinitdata = &default_cpu;
 
 DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
 #ifdef CONFIG_X86_64
@@ -332,29 +355,6 @@ void switch_to_new_gdt(int cpu)
 
 static const struct cpu_dev *__cpuinitdata cpu_devs[X86_VENDOR_NUM] = {};
 
-static void __cpuinit default_init(struct cpuinfo_x86 *c)
-{
-#ifdef CONFIG_X86_64
-       display_cacheinfo(c);
-#else
-       /* Not much we can do here... */
-       /* Check if at least it has cpuid */
-       if (c->cpuid_level == -1) {
-               /* No cpuid. It must be an ancient CPU */
-               if (c->x86 == 4)
-                       strcpy(c->x86_model_id, "486");
-               else if (c->x86 == 3)
-                       strcpy(c->x86_model_id, "386");
-       }
-#endif
-}
-
-static const struct cpu_dev __cpuinitconst default_cpu = {
-       .c_init = default_init,
-       .c_vendor = "Unknown",
-       .c_x86_vendor = X86_VENDOR_UNKNOWN,
-};
-
 static void __cpuinit get_model_name(struct cpuinfo_x86 *c)
 {
        unsigned int *v;
index bff8dd191dd5c9ae5f3235ad22a6239bf8e8de74..8bc64cfbe9368fdc204b4ae32874f175dc5696cb 100644 (file)
@@ -36,6 +36,7 @@
 
 static DEFINE_PER_CPU(__u64, next_check) = INITIAL_JIFFIES;
 static DEFINE_PER_CPU(unsigned long, thermal_throttle_count);
+static DEFINE_PER_CPU(bool, thermal_throttle_active);
 
 static atomic_t therm_throt_en         = ATOMIC_INIT(0);
 
@@ -96,24 +97,27 @@ static int therm_throt_process(int curr)
 {
        unsigned int cpu = smp_processor_id();
        __u64 tmp_jiffs = get_jiffies_64();
+       bool was_throttled = __get_cpu_var(thermal_throttle_active);
+       bool is_throttled = __get_cpu_var(thermal_throttle_active) = curr;
 
-       if (curr)
+       if (is_throttled)
                __get_cpu_var(thermal_throttle_count)++;
 
-       if (time_before64(tmp_jiffs, __get_cpu_var(next_check)))
+       if (!(was_throttled ^ is_throttled) &&
+           time_before64(tmp_jiffs, __get_cpu_var(next_check)))
                return 0;
 
        __get_cpu_var(next_check) = tmp_jiffs + CHECK_INTERVAL;
 
        /* if we just entered the thermal event */
-       if (curr) {
+       if (is_throttled) {
                printk(KERN_CRIT "CPU%d: Temperature above threshold, "
-                      "cpu clock throttled (total events = %lu)\n", cpu,
-                      __get_cpu_var(thermal_throttle_count));
+                      "cpu clock throttled (total events = %lu)\n",
+                      cpu, __get_cpu_var(thermal_throttle_count));
 
                add_taint(TAINT_MACHINE_CHECK);
-       } else {
-               printk(KERN_CRIT "CPU%d: Temperature/speed normal\n", cpu);
+       } else if (was_throttled) {
+               printk(KERN_INFO "CPU%d: Temperature/speed normal\n", cpu);
        }
 
        return 1;
index a7aa8f900954811e046f397547a19e88291aaeb3..900332b800f870d9f3f9e03bf2c5fa12505bc914 100644 (file)
@@ -55,6 +55,7 @@ struct x86_pmu {
        int             num_counters_fixed;
        int             counter_bits;
        u64             counter_mask;
+       int             apic;
        u64             max_period;
        u64             intel_ctrl;
 };
@@ -72,8 +73,8 @@ static const u64 p6_perfmon_event_map[] =
 {
   [PERF_COUNT_HW_CPU_CYCLES]           = 0x0079,
   [PERF_COUNT_HW_INSTRUCTIONS]         = 0x00c0,
-  [PERF_COUNT_HW_CACHE_REFERENCES]     = 0x0000,
-  [PERF_COUNT_HW_CACHE_MISSES]         = 0x0000,
+  [PERF_COUNT_HW_CACHE_REFERENCES]     = 0x0f2e,
+  [PERF_COUNT_HW_CACHE_MISSES]         = 0x012e,
   [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]  = 0x00c4,
   [PERF_COUNT_HW_BRANCH_MISSES]                = 0x00c5,
   [PERF_COUNT_HW_BUS_CYCLES]           = 0x0062,
@@ -613,6 +614,7 @@ static DEFINE_MUTEX(pmc_reserve_mutex);
 
 static bool reserve_pmc_hardware(void)
 {
+#ifdef CONFIG_X86_LOCAL_APIC
        int i;
 
        if (nmi_watchdog == NMI_LOCAL_APIC)
@@ -627,9 +629,11 @@ static bool reserve_pmc_hardware(void)
                if (!reserve_evntsel_nmi(x86_pmu.eventsel + i))
                        goto eventsel_fail;
        }
+#endif
 
        return true;
 
+#ifdef CONFIG_X86_LOCAL_APIC
 eventsel_fail:
        for (i--; i >= 0; i--)
                release_evntsel_nmi(x86_pmu.eventsel + i);
@@ -644,10 +648,12 @@ perfctr_fail:
                enable_lapic_nmi_watchdog();
 
        return false;
+#endif
 }
 
 static void release_pmc_hardware(void)
 {
+#ifdef CONFIG_X86_LOCAL_APIC
        int i;
 
        for (i = 0; i < x86_pmu.num_counters; i++) {
@@ -657,6 +663,7 @@ static void release_pmc_hardware(void)
 
        if (nmi_watchdog == NMI_LOCAL_APIC)
                enable_lapic_nmi_watchdog();
+#endif
 }
 
 static void hw_perf_counter_destroy(struct perf_counter *counter)
@@ -748,6 +755,15 @@ static int __hw_perf_counter_init(struct perf_counter *counter)
                hwc->sample_period = x86_pmu.max_period;
                hwc->last_period = hwc->sample_period;
                atomic64_set(&hwc->period_left, hwc->sample_period);
+       } else {
+               /*
+                * If we have a PMU initialized but no APIC
+                * interrupts, we cannot sample hardware
+                * counters (user-space has to fall back and
+                * sample via a hrtimer based software counter):
+                */
+               if (!x86_pmu.apic)
+                       return -EOPNOTSUPP;
        }
 
        counter->destroy = hw_perf_counter_destroy;
@@ -1449,18 +1465,22 @@ void smp_perf_pending_interrupt(struct pt_regs *regs)
 
 void set_perf_counter_pending(void)
 {
+#ifdef CONFIG_X86_LOCAL_APIC
        apic->send_IPI_self(LOCAL_PENDING_VECTOR);
+#endif
 }
 
 void perf_counters_lapic_init(void)
 {
-       if (!x86_pmu_initialized())
+#ifdef CONFIG_X86_LOCAL_APIC
+       if (!x86_pmu.apic || !x86_pmu_initialized())
                return;
 
        /*
         * Always use NMI for PMU
         */
        apic_write(APIC_LVTPC, APIC_DM_NMI);
+#endif
 }
 
 static int __kprobes
@@ -1484,7 +1504,9 @@ perf_counter_nmi_handler(struct notifier_block *self,
 
        regs = args->regs;
 
+#ifdef CONFIG_X86_LOCAL_APIC
        apic_write(APIC_LVTPC, APIC_DM_NMI);
+#endif
        /*
         * Can't rely on the handled return value to say it was our NMI, two
         * counters could trigger 'simultaneously' raising two back-to-back NMIs.
@@ -1515,6 +1537,7 @@ static struct x86_pmu p6_pmu = {
        .event_map              = p6_pmu_event_map,
        .raw_event              = p6_pmu_raw_event,
        .max_events             = ARRAY_SIZE(p6_perfmon_event_map),
+       .apic                   = 1,
        .max_period             = (1ULL << 31) - 1,
        .version                = 0,
        .num_counters           = 2,
@@ -1541,6 +1564,7 @@ static struct x86_pmu intel_pmu = {
        .event_map              = intel_pmu_event_map,
        .raw_event              = intel_pmu_raw_event,
        .max_events             = ARRAY_SIZE(intel_perfmon_event_map),
+       .apic                   = 1,
        /*
         * Intel PMCs cannot be accessed sanely above 32 bit width,
         * so we install an artificial 1<<31 period regardless of
@@ -1564,6 +1588,7 @@ static struct x86_pmu amd_pmu = {
        .num_counters           = 4,
        .counter_bits           = 48,
        .counter_mask           = (1ULL << 48) - 1,
+       .apic                   = 1,
        /* use highest bit to detect overflow */
        .max_period             = (1ULL << 47) - 1,
 };
@@ -1589,13 +1614,14 @@ static int p6_pmu_init(void)
                return -ENODEV;
        }
 
+       x86_pmu = p6_pmu;
+
        if (!cpu_has_apic) {
-               pr_info("no Local APIC, try rebooting with lapic");
-               return -ENODEV;
+               pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
+               pr_info("no hardware sampling interrupt available.\n");
+               x86_pmu.apic = 0;
        }
 
-       x86_pmu                         = p6_pmu;
-
        return 0;
 }
 
index 9eb897603705724ce9daaedaf62ba778aff193dc..a06e8d1018449dd70e4aac4b1098b6b06c4b9bd1 100644 (file)
@@ -418,20 +418,20 @@ static int __init set_pci_reboot(const struct dmi_system_id *d)
 }
 
 static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
-       {       /* Handle problems with rebooting on Apple MacBook5,2 */
+       {       /* Handle problems with rebooting on Apple MacBook5 */
                .callback = set_pci_reboot,
-               .ident = "Apple MacBook",
+               .ident = "Apple MacBook5",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,2"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5"),
                },
        },
-       {       /* Handle problems with rebooting on Apple MacBookPro5,1 */
+       {       /* Handle problems with rebooting on Apple MacBookPro5 */
                .callback = set_pci_reboot,
-               .ident = "Apple MacBookPro5,1",
+               .ident = "Apple MacBookPro5",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,1"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5"),
                },
        },
        { }
index 958c1fa41900f36ff7a8de1bf51b6d01f7c5720e..fe3eba5d6b3ef93633cbe3dfc76827d986ed04cf 100644 (file)
@@ -219,6 +219,8 @@ enum {
        AHCI_HFLAG_SECT255              = (1 << 8), /* max 255 sectors */
        AHCI_HFLAG_YES_NCQ              = (1 << 9), /* force NCQ cap on */
        AHCI_HFLAG_NO_SUSPEND           = (1 << 10), /* don't suspend */
+       AHCI_HFLAG_SRST_TOUT_IS_OFFLINE = (1 << 11), /* treat SRST timeout as
+                                                       link offline */
 
        /* ap->flags bits */
 
@@ -1663,6 +1665,7 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class,
                             int (*check_ready)(struct ata_link *link))
 {
        struct ata_port *ap = link->ap;
+       struct ahci_host_priv *hpriv = ap->host->private_data;
        const char *reason = NULL;
        unsigned long now, msecs;
        struct ata_taskfile tf;
@@ -1701,12 +1704,21 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class,
 
        /* wait for link to become ready */
        rc = ata_wait_after_reset(link, deadline, check_ready);
-       /* link occupied, -ENODEV too is an error */
-       if (rc) {
+       if (rc == -EBUSY && hpriv->flags & AHCI_HFLAG_SRST_TOUT_IS_OFFLINE) {
+               /*
+                * Workaround for cases where link online status can't
+                * be trusted.  Treat device readiness timeout as link
+                * offline.
+                */
+               ata_link_printk(link, KERN_INFO,
+                               "device not ready, treating as offline\n");
+               *class = ATA_DEV_NONE;
+       } else if (rc) {
+               /* link occupied, -ENODEV too is an error */
                reason = "device not ready";
                goto fail;
-       }
-       *class = ahci_dev_classify(ap);
+       } else
+               *class = ahci_dev_classify(ap);
 
        DPRINTK("EXIT, class=%u\n", *class);
        return 0;
@@ -1773,7 +1785,8 @@ static int ahci_sb600_softreset(struct ata_link *link, unsigned int *class,
                irq_sts = readl(port_mmio + PORT_IRQ_STAT);
                if (irq_sts & PORT_IRQ_BAD_PMP) {
                        ata_link_printk(link, KERN_WARNING,
-                                       "failed due to HW bug, retry pmp=0\n");
+                                       "applying SB600 PMP SRST workaround "
+                                       "and retrying\n");
                        rc = ahci_do_softreset(link, class, 0, deadline,
                                               ahci_check_ready);
                }
@@ -2726,6 +2739,56 @@ static bool ahci_broken_suspend(struct pci_dev *pdev)
        return !ver || strcmp(ver, dmi->driver_data) < 0;
 }
 
+static bool ahci_broken_online(struct pci_dev *pdev)
+{
+#define ENCODE_BUSDEVFN(bus, slot, func)                       \
+       (void *)(unsigned long)(((bus) << 8) | PCI_DEVFN((slot), (func)))
+       static const struct dmi_system_id sysids[] = {
+               /*
+                * There are several gigabyte boards which use
+                * SIMG5723s configured as hardware RAID.  Certain
+                * 5723 firmware revisions shipped there keep the link
+                * online but fail to answer properly to SRST or
+                * IDENTIFY when no device is attached downstream
+                * causing libata to retry quite a few times leading
+                * to excessive detection delay.
+                *
+                * As these firmwares respond to the second reset try
+                * with invalid device signature, considering unknown
+                * sig as offline works around the problem acceptably.
+                */
+               {
+                       .ident = "EP45-DQ6",
+                       .matches = {
+                               DMI_MATCH(DMI_BOARD_VENDOR,
+                                         "Gigabyte Technology Co., Ltd."),
+                               DMI_MATCH(DMI_BOARD_NAME, "EP45-DQ6"),
+                       },
+                       .driver_data = ENCODE_BUSDEVFN(0x0a, 0x00, 0),
+               },
+               {
+                       .ident = "EP45-DS5",
+                       .matches = {
+                               DMI_MATCH(DMI_BOARD_VENDOR,
+                                         "Gigabyte Technology Co., Ltd."),
+                               DMI_MATCH(DMI_BOARD_NAME, "EP45-DS5"),
+                       },
+                       .driver_data = ENCODE_BUSDEVFN(0x03, 0x00, 0),
+               },
+               { }     /* terminate list */
+       };
+#undef ENCODE_BUSDEVFN
+       const struct dmi_system_id *dmi = dmi_first_match(sysids);
+       unsigned int val;
+
+       if (!dmi)
+               return false;
+
+       val = (unsigned long)dmi->driver_data;
+
+       return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff);
+}
+
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
@@ -2841,6 +2904,12 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                           "BIOS update required for suspend/resume\n");
        }
 
+       if (ahci_broken_online(pdev)) {
+               hpriv->flags |= AHCI_HFLAG_SRST_TOUT_IS_OFFLINE;
+               dev_info(&pdev->dev,
+                        "online status unreliable, applying workaround\n");
+       }
+
        /* CAP.NP sometimes indicate the index of the last enabled
         * port, at other times, that of the last possible port, so
         * determining the maximum port number requires looking at
index 8ac98ff16d7deb65f083851013c090a1cb9cfa60..072ba5ea138f8363a4b108091d0295353792e09a 100644 (file)
@@ -4302,6 +4302,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "WDC WD2500JD-00HBB0", "WD-WMAL71490727", ATA_HORKAGE_BROKEN_HPA },
        { "MAXTOR 6L080L4",     "A93.0500",     ATA_HORKAGE_BROKEN_HPA },
 
+       /* this one allows HPA unlocking but fails IOs on the area */
+       { "OCZ-VERTEX",             "1.30",     ATA_HORKAGE_BROKEN_HPA },
+
        /* Devices which report 1 sector over size HPA */
        { "ST340823A",          NULL,           ATA_HORKAGE_HPA_SIZE, },
        { "ST320413A",          NULL,           ATA_HORKAGE_HPA_SIZE, },
index 5702affcb3254458f8c4afa28fa152a44a875455..41c94b1ae4930b4a44e56a57e3e6dde6cd832e3b 100644 (file)
@@ -250,7 +250,7 @@ static int __devinit pata_at91_probe(struct platform_device *pdev)
                ata_port_desc(ap, "no IRQ, using PIO polling");
        }
 
-       info = kzalloc(sizeof(*info), GFP_KERNEL);
+       info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
 
        if (!info) {
                dev_err(dev, "failed to allocate memory for private data\n");
@@ -275,7 +275,7 @@ static int __devinit pata_at91_probe(struct platform_device *pdev)
        if (!info->ide_addr) {
                dev_err(dev, "failed to map IO base\n");
                ret = -ENOMEM;
-               goto err_ide_ioremap;
+               goto err_put;
        }
 
        info->alt_addr = devm_ioremap(dev,
@@ -284,7 +284,7 @@ static int __devinit pata_at91_probe(struct platform_device *pdev)
        if (!info->alt_addr) {
                dev_err(dev, "failed to map CTL base\n");
                ret = -ENOMEM;
-               goto err_alt_ioremap;
+               goto err_put;
        }
 
        ap->ioaddr.cmd_addr = info->ide_addr;
@@ -303,13 +303,8 @@ static int __devinit pata_at91_probe(struct platform_device *pdev)
                        irq ? ata_sff_interrupt : NULL,
                        irq_flags, &pata_at91_sht);
 
-err_alt_ioremap:
-       devm_iounmap(dev, info->ide_addr);
-
-err_ide_ioremap:
+err_put:
        clk_put(info->mck);
-       kfree(info);
-
        return ret;
 }
 
@@ -317,7 +312,6 @@ static int __devexit pata_at91_remove(struct platform_device *pdev)
 {
        struct ata_host *host = dev_get_drvdata(&pdev->dev);
        struct at91_ide_info *info;
-       struct device *dev = &pdev->dev;
 
        if (!host)
                return 0;
@@ -328,11 +322,8 @@ static int __devexit pata_at91_remove(struct platform_device *pdev)
        if (!info)
                return 0;
 
-       devm_iounmap(dev, info->ide_addr);
-       devm_iounmap(dev, info->alt_addr);
        clk_put(info->mck);
 
-       kfree(info);
        return 0;
 }
 
index bec0b8ade66d846c43fcbcc7328daec82cb4925c..45915566e4e9e63caecd553fdb1ec1739c5582af 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * pata_atiixp.c       - ATI PATA for new ATA layer
  *                       (C) 2005 Red Hat Inc
+ *                       (C) 2009 Bartlomiej Zolnierkiewicz
  *
  * Based on
  *
@@ -61,20 +62,19 @@ static void atiixp_set_pio_timing(struct ata_port *ap, struct ata_device *adev,
 
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        int dn = 2 * ap->port_no + adev->devno;
-
-       /* Check this is correct - the order is odd in both drivers */
        int timing_shift = (16 * ap->port_no) + 8 * (adev->devno ^ 1);
-       u16 pio_mode_data, pio_timing_data;
+       u32 pio_timing_data;
+       u16 pio_mode_data;
 
        pci_read_config_word(pdev, ATIIXP_IDE_PIO_MODE, &pio_mode_data);
        pio_mode_data &= ~(0x7 << (4 * dn));
        pio_mode_data |= pio << (4 * dn);
        pci_write_config_word(pdev, ATIIXP_IDE_PIO_MODE, pio_mode_data);
 
-       pci_read_config_word(pdev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data);
+       pci_read_config_dword(pdev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data);
        pio_timing_data &= ~(0xFF << timing_shift);
        pio_timing_data |= (pio_timings[pio] << timing_shift);
-       pci_write_config_word(pdev, ATIIXP_IDE_PIO_TIMING, pio_timing_data);
+       pci_write_config_dword(pdev, ATIIXP_IDE_PIO_TIMING, pio_timing_data);
 }
 
 /**
@@ -119,16 +119,17 @@ static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev)
                udma_mode_data |= dma << (4 * dn);
                pci_write_config_word(pdev, ATIIXP_IDE_UDMA_MODE, udma_mode_data);
        } else {
-               u16 mwdma_timing_data;
-               /* Check this is correct - the order is odd in both drivers */
                int timing_shift = (16 * ap->port_no) + 8 * (adev->devno ^ 1);
+               u32 mwdma_timing_data;
 
                dma -= XFER_MW_DMA_0;
 
-               pci_read_config_word(pdev, ATIIXP_IDE_MWDMA_TIMING, &mwdma_timing_data);
+               pci_read_config_dword(pdev, ATIIXP_IDE_MWDMA_TIMING,
+                                     &mwdma_timing_data);
                mwdma_timing_data &= ~(0xFF << timing_shift);
                mwdma_timing_data |= (mwdma_timings[dma] << timing_shift);
-               pci_write_config_word(pdev, ATIIXP_IDE_MWDMA_TIMING, mwdma_timing_data);
+               pci_write_config_dword(pdev, ATIIXP_IDE_MWDMA_TIMING,
+                                      mwdma_timing_data);
        }
        /*
         *      We must now look at the PIO mode situation. We may need to
index b2d11f300c39045a8ce645949409fde0dc1a971c..86a40582999ce0f80364e2bb5e0995970b6f906e 100644 (file)
@@ -602,6 +602,7 @@ MODULE_VERSION(DRV_VERSION);
 
 static int adma_enabled;
 static int swncq_enabled = 1;
+static int msi_enabled;
 
 static void nv_adma_register_mode(struct ata_port *ap)
 {
@@ -2459,6 +2460,11 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        } else if (type == SWNCQ)
                nv_swncq_host_init(host);
 
+       if (msi_enabled) {
+               dev_printk(KERN_NOTICE, &pdev->dev, "Using MSI\n");
+               pci_enable_msi(pdev);
+       }
+
        pci_set_master(pdev);
        return ata_host_activate(host, pdev->irq, ipriv->irq_handler,
                                 IRQF_SHARED, ipriv->sht);
@@ -2558,4 +2564,6 @@ module_param_named(adma, adma_enabled, bool, 0444);
 MODULE_PARM_DESC(adma, "Enable use of ADMA (Default: false)");
 module_param_named(swncq, swncq_enabled, bool, 0444);
 MODULE_PARM_DESC(swncq, "Enable use of SWNCQ (Default: true)");
+module_param_named(msi, msi_enabled, bool, 0444);
+MODULE_PARM_DESC(msi, "Enable use of MSI (Default: false)");
 
index ae5c4aa6d269c3b44dd325e7bf0882aa7615770d..d28c289e4a3fd8c99c9eaad9cb7502da920cd4c0 100644 (file)
@@ -483,9 +483,6 @@ int platform_driver_register(struct platform_driver *drv)
                drv->driver.remove = platform_drv_remove;
        if (drv->shutdown)
                drv->driver.shutdown = platform_drv_shutdown;
-       if (drv->suspend || drv->resume)
-               pr_warning("Platform driver '%s' needs updating - please use "
-                       "dev_pm_ops\n", drv->driver.name);
 
        return driver_register(&drv->driver);
 }
index 5b98bea4ff9b36ccd132398dd9f8cc5e5568b8f4..103f2d33fa8978bc5a01724846cf6628b260d0be 100644 (file)
@@ -359,6 +359,7 @@ static mddev_t * mddev_find(dev_t unit)
        else
                new->md_minor = MINOR(unit) >> MdpMinorShift;
 
+       mutex_init(&new->open_mutex);
        mutex_init(&new->reconfig_mutex);
        INIT_LIST_HEAD(&new->disks);
        INIT_LIST_HEAD(&new->all_mddevs);
@@ -1974,17 +1975,14 @@ repeat:
                /* otherwise we have to go forward and ... */
                mddev->events ++;
                if (!mddev->in_sync || mddev->recovery_cp != MaxSector) { /* not clean */
-                       /* .. if the array isn't clean, insist on an odd 'events' */
-                       if ((mddev->events&1)==0) {
-                               mddev->events++;
+                       /* .. if the array isn't clean, an 'even' event must also go
+                        * to spares. */
+                       if ((mddev->events&1)==0)
                                nospares = 0;
-                       }
                } else {
-                       /* otherwise insist on an even 'events' (for clean states) */
-                       if ((mddev->events&1)) {
-                               mddev->events++;
+                       /* otherwise an 'odd' event must go to spares */
+                       if ((mddev->events&1))
                                nospares = 0;
-                       }
                }
        }
 
@@ -3601,6 +3599,7 @@ max_sync_store(mddev_t *mddev, const char *buf, size_t len)
                if (max < mddev->resync_min)
                        return -EINVAL;
                if (max < mddev->resync_max &&
+                   mddev->ro == 0 &&
                    test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
                        return -EBUSY;
 
@@ -4304,12 +4303,11 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
        struct gendisk *disk = mddev->gendisk;
        mdk_rdev_t *rdev;
 
+       mutex_lock(&mddev->open_mutex);
        if (atomic_read(&mddev->openers) > is_open) {
                printk("md: %s still in use.\n",mdname(mddev));
-               return -EBUSY;
-       }
-
-       if (mddev->pers) {
+               err = -EBUSY;
+       } else if (mddev->pers) {
 
                if (mddev->sync_thread) {
                        set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
@@ -4367,7 +4365,10 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
                        set_disk_ro(disk, 1);
                clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
        }
-
+out:
+       mutex_unlock(&mddev->open_mutex);
+       if (err)
+               return err;
        /*
         * Free resources if final stop
         */
@@ -4433,7 +4434,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
        blk_integrity_unregister(disk);
        md_new_event(mddev);
        sysfs_notify_dirent(mddev->sysfs_state);
-out:
        return err;
 }
 
@@ -5518,12 +5518,12 @@ static int md_open(struct block_device *bdev, fmode_t mode)
        }
        BUG_ON(mddev != bdev->bd_disk->private_data);
 
-       if ((err = mutex_lock_interruptible_nested(&mddev->reconfig_mutex, 1)))
+       if ((err = mutex_lock_interruptible(&mddev->open_mutex)))
                goto out;
 
        err = 0;
        atomic_inc(&mddev->openers);
-       mddev_unlock(mddev);
+       mutex_unlock(&mddev->open_mutex);
 
        check_disk_change(bdev);
  out:
index 78f03168baf93a8949ca534aa2c13ceb34edf69b..f8fc188bc762d4b6fe1ffb5dadc9ac43a36d6dff 100644 (file)
@@ -223,6 +223,16 @@ struct mddev_s
                                                            * so we don't loop trying */
 
        int                             in_sync;        /* know to not need resync */
+       /* 'open_mutex' avoids races between 'md_open' and 'do_md_stop', so
+        * that we are never stopping an array while it is open.
+        * 'reconfig_mutex' protects all other reconfiguration.
+        * These locks are separate due to conflicting interactions
+        * with bdev->bd_mutex.
+        * Lock ordering is:
+        *  reconfig_mutex -> bd_mutex : e.g. do_md_run -> revalidate_disk
+        *  bd_mutex -> open_mutex:  e.g. __blkdev_get -> md_open
+        */
+       struct mutex                    open_mutex;
        struct mutex                    reconfig_mutex;
        atomic_t                        active;         /* general refcount */
        atomic_t                        openers;        /* number of active opens */
index 2b521ee67dfa0c86923ff2c0e1ba2790977cc63a..b8a2c5dc67ba7753d575e27ce0036f440451664d 100644 (file)
@@ -3785,7 +3785,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
                    conf->reshape_progress < raid5_size(mddev, 0, 0)) {
                        sector_nr = raid5_size(mddev, 0, 0)
                                - conf->reshape_progress;
-               } else if (mddev->delta_disks > 0 &&
+               } else if (mddev->delta_disks >= 0 &&
                           conf->reshape_progress > 0)
                        sector_nr = conf->reshape_progress;
                sector_div(sector_nr, new_data_disks);
@@ -4509,7 +4509,26 @@ static int run(mddev_t *mddev)
                           (old_disks-max_degraded));
                /* here_old is the first stripe that we might need to read
                 * from */
-               if (here_new >= here_old) {
+               if (mddev->delta_disks == 0) {
+                       /* We cannot be sure it is safe to start an in-place
+                        * reshape.  It is only safe if user-space if monitoring
+                        * and taking constant backups.
+                        * mdadm always starts a situation like this in
+                        * readonly mode so it can take control before
+                        * allowing any writes.  So just check for that.
+                        */
+                       if ((here_new * mddev->new_chunk_sectors != 
+                            here_old * mddev->chunk_sectors) ||
+                           mddev->ro == 0) {
+                               printk(KERN_ERR "raid5: in-place reshape must be started"
+                                      " in read-only mode - aborting\n");
+                               return -EINVAL;
+                       }
+               } else if (mddev->delta_disks < 0
+                   ? (here_new * mddev->new_chunk_sectors <=
+                      here_old * mddev->chunk_sectors)
+                   : (here_new * mddev->new_chunk_sectors >=
+                      here_old * mddev->chunk_sectors)) {
                        /* Reading from the same stripe as writing to - bad */
                        printk(KERN_ERR "raid5: reshape_position too early for "
                               "auto-recovery - aborting.\n");
@@ -5078,8 +5097,15 @@ static void raid5_finish_reshape(mddev_t *mddev)
                                        mddev->degraded--;
                        for (d = conf->raid_disks ;
                             d < conf->raid_disks - mddev->delta_disks;
-                            d++)
-                               raid5_remove_disk(mddev, d);
+                            d++) {
+                               mdk_rdev_t *rdev = conf->disks[d].rdev;
+                               if (rdev && raid5_remove_disk(mddev, d) == 0) {
+                                       char nm[20];
+                                       sprintf(nm, "rd%d", rdev->raid_disk);
+                                       sysfs_remove_link(&mddev->kobj, nm);
+                                       rdev->raid_disk = -1;
+                               }
+                       }
                }
                mddev->layout = conf->algorithm;
                mddev->chunk_sectors = conf->chunk_sectors;
index 825aa1412e6f0ca039cb3729aded3d970fdc266f..9f5dba244cb86e7e361e992bbd45fedd41b1a1f9 100644 (file)
@@ -64,24 +64,22 @@ static int qt1010_writereg(struct qt1010_priv *priv, u8 reg, u8 val)
 /* dump all registers */
 static void qt1010_dump_regs(struct qt1010_priv *priv)
 {
-       char buf[52], buf2[4];
        u8 reg, val;
 
        for (reg = 0; ; reg++) {
                if (reg % 16 == 0) {
                        if (reg)
-                               printk("%s\n", buf);
-                       sprintf(buf, "%02x: ", reg);
+                               printk(KERN_CONT "\n");
+                       printk(KERN_DEBUG "%02x:", reg);
                }
                if (qt1010_readreg(priv, reg, &val) == 0)
-                       sprintf(buf2, "%02x ", val);
+                       printk(KERN_CONT " %02x", val);
                else
-                       strcpy(buf2, "-- ");
-               strcat(buf, buf2);
+                       printk(KERN_CONT " --");
                if (reg == 0x2f)
                        break;
        }
-       printk("%s\n", buf);
+       printk(KERN_CONT "\n");
 }
 
 static int qt1010_set_params(struct dvb_frontend *fe,
index aa20ce8cc668ba96b566d3aa45119a6b93e37889..f270e605da8328a728f3c844fbd88d74bcfa0d4d 100644 (file)
@@ -1119,8 +1119,8 @@ static int xc2028_sleep(struct dvb_frontend *fe)
        struct xc2028_data *priv = fe->tuner_priv;
        int rc = 0;
 
-       /* Avoid firmware reload on slow devices */
-       if (no_poweroff)
+       /* Avoid firmware reload on slow devices or if PM disabled */
+       if (no_poweroff || priv->ctrl.disable_power_mgmt)
                return 0;
 
        tuner_dbg("Putting xc2028/3028 into poweroff mode.\n");
index 19de7928a74eb75b5a01177a633acdf7e7768559..a90c35d50add70c00a7deaa7476757d7d9cbd3bc 100644 (file)
@@ -38,6 +38,7 @@ struct xc2028_ctrl {
        unsigned int            input1:1;
        unsigned int            vhfbw7:1;
        unsigned int            uhfbw8:1;
+       unsigned int            disable_power_mgmt:1;
        unsigned int            demod;
        enum firmware_type      type:2;
 };
index 4cb31e7c13c2856be433e2feb3feee225d02db64..26690dfb32601b9fcde1825ba41d18392b663d08 100644 (file)
@@ -81,7 +81,6 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
 
        switch (req->cmd) {
        case GET_CONFIG:
-       case BOOT:
        case READ_MEMORY:
        case RECONNECT_USB:
        case GET_IR_CODE:
@@ -100,6 +99,7 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
        case WRITE_VIRTUAL_MEMORY:
        case COPY_FIRMWARE:
        case DOWNLOAD_FIRMWARE:
+       case BOOT:
                break;
        default:
                err("unknown command:%d", req->cmd);
index ace5cb17165daddf0e78c82a08aeaf215b5dec4d..fbd838eca268765e79268a3165f3fb34f9908a8d 100644 (file)
@@ -380,7 +380,7 @@ struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
        struct cx22700_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct cx22700_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct cx22700_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 5d1abe34bddb5cfc17694a7459877aaf0cbb86f7..00b5c7e91d5d8189ca212f297fbd0fccf908ae29 100644 (file)
@@ -580,7 +580,7 @@ struct dvb_frontend *cx22702_attach(const struct cx22702_config *config,
        struct cx22702_state *state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct cx22702_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 87ae29db024fc2aea18122996b60ac29a879b24d..ffbcfabd83f0c861aa5b0dc2c1532f7380a46750 100644 (file)
@@ -598,7 +598,7 @@ struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
        int ret;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct cx24110_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct cx24110_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index db8a937cc63008dbabe4a1225810f03e80916d31..a7fc7e53a5518f6b20edbb7d96d050c8a2a5dbe3 100644 (file)
@@ -117,7 +117,7 @@ struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
        struct dvb_dummy_fe_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* create dvb_frontend */
@@ -137,7 +137,7 @@ struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
        struct dvb_dummy_fe_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* create dvb_frontend */
@@ -157,7 +157,7 @@ struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
        struct dvb_dummy_fe_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* create dvb_frontend */
index e1e70e9e0cb9ced61f4b71f96a882bff38d40965..3051b64aa17c6bd3c8d7b3fbaad1727908d92b26 100644 (file)
@@ -501,7 +501,7 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config,
                           { .addr = config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct l64781_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct l64781_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 855852fddf22c4ab294d15c81ee4a89f5df47720..bb37ed289a059542d2821b9612261a18e7751f1e 100644 (file)
@@ -387,7 +387,7 @@ lgs8gl5_attach(const struct lgs8gl5_config *config, struct i2c_adapter *i2c)
        dprintk("%s\n", __func__);
 
        /* Allocate memory for the internal state */
-       state = kmalloc(sizeof(struct lgs8gl5_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct lgs8gl5_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index a621f727935f217eb91f78e84a025bfc7a36767b..f69daaac78c9bf431d1371914d208ad5a9f9811e 100644 (file)
@@ -782,7 +782,7 @@ struct dvb_frontend *mt312_attach(const struct mt312_config *config,
        struct mt312_state *state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct mt312_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 0eef22dbf8a041ae5f82e0aecc5cc36770ab1d0a..a763ec756f7f84df840bcb38bfb3816ee016e174 100644 (file)
@@ -545,7 +545,7 @@ struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
        struct nxt6000_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct nxt6000_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct nxt6000_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 8133ea3cddd783023ff581c47c904b412ac47c0f..38e67accb8c360af874fc9b3d57804c523d4a34a 100644 (file)
@@ -562,7 +562,7 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config,
        struct or51132_state* state = NULL;
 
        /* Allocate memory for the internal state */
-       state = kmalloc(sizeof(struct or51132_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct or51132_state), GFP_KERNEL);
        if (state == NULL)
                return NULL;
 
index 16cf2fdd5d7d1c6a14189a5b56312a4b4acb3f99..c709ce6771c86ca831e9e17e1677e03da0b05e7c 100644 (file)
@@ -527,7 +527,7 @@ struct dvb_frontend* or51211_attach(const struct or51211_config* config,
        struct or51211_state* state = NULL;
 
        /* Allocate memory for the internal state */
-       state = kmalloc(sizeof(struct or51211_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct or51211_state), GFP_KERNEL);
        if (state == NULL)
                return NULL;
 
index 3e08d985d6e50cf2f1fb36df3169274c74b22dcb..fb30115184270e38883ebee422c5f54582d58884 100644 (file)
@@ -796,7 +796,7 @@ struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config,
        u16 reg;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct s5h1409_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct s5h1409_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 66e2dd6d6fe4eb725b21f203b21e180081c8ef45..d8adf1e32019a9f7b62a712d693dd242ee79e036 100644 (file)
@@ -844,7 +844,7 @@ struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config,
        u16 reg;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct s5h1411_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct s5h1411_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 0bd16af8a6cd0723ab127f5a8de3c8d99e81e581..9552a22ccffb23b215897979fd51f45a2d8dc07a 100644 (file)
@@ -928,7 +928,7 @@ struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
        dprintk("%s\n", __func__);
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct si21xx_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 1c9a9b4051b9efdbc8a4a9eba005d74f883c4e11..b85eb60a893e34954a313382a2fad0b5d8a88499 100644 (file)
@@ -557,7 +557,7 @@ struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
        struct sp8870_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct sp8870_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct sp8870_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 559509ab4dabfc2f4376bb0b46d58315defb74fd..4a7c3d8426088bdccd39ab95b197b8b2963ab3d9 100644 (file)
@@ -557,7 +557,7 @@ struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
        struct sp887x_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct sp887x_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct sp887x_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index ff1194de34c0cf176f655329af5213754b1f4fab..2930a5d6768a71d89d38ecf8d4a85b87c55a9905 100644 (file)
@@ -570,7 +570,7 @@ struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
        int id;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct stv0288_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct stv0288_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 62caf802ed990b0343e50f8374c97f451b7a5e50..4fd7479bb62b98fdba6d933cd1f34ac14ef9b6b3 100644 (file)
@@ -663,7 +663,7 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
        struct stv0297_state *state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct stv0297_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct stv0297_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 6c1cb1973c6e09c90010a7ec0167a9e50ae5b23e..9688744697260e440221ce3017a4ebd5e0dac849 100644 (file)
@@ -667,7 +667,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
        int id;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct stv0299_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct stv0299_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index f648fdb64bb7dd33753522bb70e6619bc8c42f87..f5d7b3277a2fa585360aaafda331669a11ecd95a 100644 (file)
@@ -413,7 +413,7 @@ struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
        u8 id;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct tda10021_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index cc8862ce4aae9fff195506148f229cc4336b9eef..4e2a7c8b2f624e41f4d33adb27ef717f5172ae79 100644 (file)
@@ -1095,7 +1095,7 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config,
        dprintk(1, "%s()\n", __func__);
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct tda10048_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct tda10048_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 4981cef8b444602d5f48a00881e2199843d073d1..f2a8abe0a243b87b09d09df9098991ba23036562 100644 (file)
@@ -1269,7 +1269,7 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
        int id;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
        if (!state) {
                printk(KERN_ERR "Can't alocate memory for tda10045 state\n");
                return NULL;
@@ -1339,7 +1339,7 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
        int id;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
        if (!state) {
                printk(KERN_ERR "Can't alocate memory for tda10046 state\n");
                return NULL;
index a17ce3c4ad860c8959609e22c56679e5a004fda1..f2c8faac6f36426e0c7beb3f361e223b3b12cfcd 100644 (file)
@@ -745,7 +745,7 @@ struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
        dprintk ("%s\n", __func__);
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct tda10086_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct tda10086_state), GFP_KERNEL);
        if (!state)
                return NULL;
 
index 5b843b2e67e874c03f79cdfb1407680e16ee99ad..9369f7442f273b810c8568873047153d7a1149ba 100644 (file)
@@ -417,7 +417,7 @@ struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
        struct tda8083_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct tda8083_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct tda8083_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index a184597f1d9be0002b8f567b245a849abef6553c..6e78e486551599bc47d76addb4e0af3e284175b6 100644 (file)
@@ -374,7 +374,7 @@ struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
        struct ves1820_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct ves1820_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct ves1820_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index bd558960bd87222eed8a71e7f696554e461ea9be..8d7854c2fb0c142683a2c823a3447af61c637438 100644 (file)
@@ -456,7 +456,7 @@ struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
        u8 identity;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct ves1x93_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct ves1x93_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 148b6f7f6cb253534b785ef2e6a95769e236fa45..66f5c1fb3074e60e13d481b558d2403803e9d5eb 100644 (file)
@@ -98,7 +98,6 @@ static int zl10353_read_register(struct zl10353_state *state, u8 reg)
 static void zl10353_dump_regs(struct dvb_frontend *fe)
 {
        struct zl10353_state *state = fe->demodulator_priv;
-       char buf[52], buf2[4];
        int ret;
        u8 reg;
 
@@ -106,19 +105,18 @@ static void zl10353_dump_regs(struct dvb_frontend *fe)
        for (reg = 0; ; reg++) {
                if (reg % 16 == 0) {
                        if (reg)
-                               printk(KERN_DEBUG "%s\n", buf);
-                       sprintf(buf, "%02x: ", reg);
+                               printk(KERN_CONT "\n");
+                       printk(KERN_DEBUG "%02x:", reg);
                }
                ret = zl10353_read_register(state, reg);
                if (ret >= 0)
-                       sprintf(buf2, "%02x ", (u8)ret);
+                       printk(KERN_CONT " %02x", (u8)ret);
                else
-                       strcpy(buf2, "-- ");
-               strcat(buf, buf2);
+                       printk(KERN_CONT " --");
                if (reg == 0xff)
                        break;
        }
-       printk(KERN_DEBUG "%s\n", buf);
+       printk(KERN_CONT "\n");
 }
 
 static void zl10353_calc_nominal_rate(struct dvb_frontend *fe,
index dd863f26167244b1fa09925b6fa4bcec6ff0b682..88847d1dcbb5187ff3e0f645f51b2bc3534719f7 100644 (file)
@@ -4,7 +4,7 @@
 
 config DVB_SIANO_SMS1XXX
        tristate "Siano SMS1XXX USB dongle support"
-       depends on DVB_CORE && USB
+       depends on DVB_CORE && USB && INPUT
        ---help---
          Choose Y here if you have a USB dongle with a SMS1XXX chipset.
 
index d8b15d583bdeb2e662a3d336aabd7017d2414722..0420e2885e752971fd4ef1dbc01ac2d4d46e000f 100644 (file)
@@ -116,99 +116,21 @@ static inline void sms_gpio_assign_11xx_default_led_config(
 
 int sms_board_event(struct smscore_device_t *coredev,
                enum SMS_BOARD_EVENTS gevent) {
-       int board_id = smscore_get_board_id(coredev);
-       struct sms_board *board = sms_get_board(board_id);
        struct smscore_gpio_config MyGpioConfig;
 
        sms_gpio_assign_11xx_default_led_config(&MyGpioConfig);
 
        switch (gevent) {
        case BOARD_EVENT_POWER_INIT: /* including hotplug */
-               switch (board_id) {
-               case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-                       /* set I/O and turn off all LEDs */
-                       smscore_gpio_configure(coredev,
-                                       board->board_cfg.leds_power,
-                                       &MyGpioConfig);
-                       smscore_gpio_set_level(coredev,
-                                       board->board_cfg.leds_power, 0);
-                       smscore_gpio_configure(coredev, board->board_cfg.led0,
-                                       &MyGpioConfig);
-                       smscore_gpio_set_level(coredev,
-                                       board->board_cfg.led0, 0);
-                       smscore_gpio_configure(coredev, board->board_cfg.led1,
-                                       &MyGpioConfig);
-                       smscore_gpio_set_level(coredev,
-                                       board->board_cfg.led1, 0);
-                       break;
-               case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
-               case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
-                       /* set I/O and turn off LNA */
-                       smscore_gpio_configure(coredev,
-                                       board->board_cfg.foreign_lna0_ctrl,
-                                       &MyGpioConfig);
-                       smscore_gpio_set_level(coredev,
-                                       board->board_cfg.foreign_lna0_ctrl,
-                                       0);
-                       break;
-               }
                break; /* BOARD_EVENT_BIND */
 
        case BOARD_EVENT_POWER_SUSPEND:
-               switch (board_id) {
-               case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.leds_power, 0);
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.led0, 0);
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.led1, 0);
-                       break;
-               case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
-               case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
-                       smscore_gpio_set_level(coredev,
-                                       board->board_cfg.foreign_lna0_ctrl,
-                                       0);
-                       break;
-               }
                break; /* BOARD_EVENT_POWER_SUSPEND */
 
        case BOARD_EVENT_POWER_RESUME:
-               switch (board_id) {
-               case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.leds_power, 1);
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.led0, 1);
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.led1, 0);
-                       break;
-               case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
-               case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
-                       smscore_gpio_set_level(coredev,
-                                       board->board_cfg.foreign_lna0_ctrl,
-                                       1);
-                       break;
-               }
                break; /* BOARD_EVENT_POWER_RESUME */
 
        case BOARD_EVENT_BIND:
-               switch (board_id) {
-               case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-                       smscore_gpio_set_level(coredev,
-                               board->board_cfg.leds_power, 1);
-                       smscore_gpio_set_level(coredev,
-                               board->board_cfg.led0, 1);
-                       smscore_gpio_set_level(coredev,
-                               board->board_cfg.led1, 0);
-                       break;
-               case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
-               case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
-                       smscore_gpio_set_level(coredev,
-                                       board->board_cfg.foreign_lna0_ctrl,
-                                       1);
-                       break;
-               }
                break; /* BOARD_EVENT_BIND */
 
        case BOARD_EVENT_SCAN_PROG:
@@ -218,20 +140,8 @@ int sms_board_event(struct smscore_device_t *coredev,
        case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL:
                break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */
        case BOARD_EVENT_FE_LOCK:
-               switch (board_id) {
-               case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-                       smscore_gpio_set_level(coredev,
-                       board->board_cfg.led1, 1);
-                       break;
-               }
                break; /* BOARD_EVENT_FE_LOCK */
        case BOARD_EVENT_FE_UNLOCK:
-               switch (board_id) {
-               case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.led1, 0);
-                       break;
-               }
                break; /* BOARD_EVENT_FE_UNLOCK */
        case BOARD_EVENT_DEMOD_LOCK:
                break; /* BOARD_EVENT_DEMOD_LOCK */
@@ -248,20 +158,8 @@ int sms_board_event(struct smscore_device_t *coredev,
        case BOARD_EVENT_RECEPTION_LOST_0:
                break; /* BOARD_EVENT_RECEPTION_LOST_0 */
        case BOARD_EVENT_MULTIPLEX_OK:
-               switch (board_id) {
-               case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.led1, 1);
-                       break;
-               }
                break; /* BOARD_EVENT_MULTIPLEX_OK */
        case BOARD_EVENT_MULTIPLEX_ERRORS:
-               switch (board_id) {
-               case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.led1, 0);
-                       break;
-               }
                break; /* BOARD_EVENT_MULTIPLEX_ERRORS */
 
        default:
index a246903c3341bea1ba919f9a6b5262e73e3d6d6a..bd9ab9d0d12a27d753f09dd79fcd882d0963d31f 100644 (file)
@@ -816,7 +816,7 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
 
        sms_debug("set device mode to %d", mode);
        if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
-               if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) {
+               if (mode < DEVICE_MODE_DVBT || mode >= DEVICE_MODE_RAW_TUNER) {
                        sms_err("invalid mode specified %d", mode);
                        return -EINVAL;
                }
index 84b6fc15519d13807cf8c3601e4551ac87d72f49..dcf9fa9264bb720856775748a3e6e69d373fcee4 100644 (file)
@@ -920,6 +920,8 @@ source "drivers/media/video/pwc/Kconfig"
 config USB_ZR364XX
        tristate "USB ZR364XX Camera support"
        depends on VIDEO_V4L2
+       select VIDEOBUF_GEN
+       select VIDEOBUF_VMALLOC
        ---help---
          Say Y here if you want to connect this type of camera to your
          computer's USB port.
index 10dbd4a11b30f8e4aaf7e0ac2fad97f69bb56dbb..9e39bc5f7b00147098a2c660880e6f3853be5e6d 100644 (file)
@@ -992,7 +992,7 @@ static int accept_bwqcam(struct parport *port)
 
        if (parport[0] && strncmp(parport[0], "auto", 4) != 0) {
                /* user gave parport parameters */
-               for(n=0; parport[n] && n<MAX_CAMS; n++){
+               for (n = 0; n < MAX_CAMS && parport[n]; n++) {
                        char *ep;
                        unsigned long r;
                        r = simple_strtoul(parport[n], &ep, 0);
index 5136df198338bbbe6855889b84cf0b5486252b2d..93f0dae01350316d9c13110504df129baa4f5ecb 100644 (file)
@@ -20,6 +20,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  *  02111-1307  USA
  */
+#include <linux/kernel.h>
 
 #include "cx18-driver.h"
 #include "cx18-cards.h"
@@ -317,7 +318,7 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
                idx = p.audio_properties & 0x03;
                /* The audio clock of the digitizer must match the codec sample
                   rate otherwise you get some very strange effects. */
-               if (idx < sizeof(freqs))
+               if (idx < ARRAY_SIZE(freqs))
                        cx18_call_all(cx, audio, s_clock_freq, freqs[idx]);
                return err;
        }
index e0cf21e0b1bf52e3649841a6405d70ed3c4859ef..1a1048b18f7027c67eed1eac69b30fd1ad0b055d 100644 (file)
@@ -1715,6 +1715,8 @@ static struct video_device cx23885_mpeg_template = {
        .fops          = &mpeg_fops,
        .ioctl_ops     = &mpeg_ioctl_ops,
        .minor         = -1,
+       .tvnorms       = CX23885_NORMS,
+       .current_norm  = V4L2_STD_NTSC_M,
 };
 
 void cx23885_417_unregister(struct cx23885_dev *dev)
index a5cc1c1fc2d60c30329350a1ee1072c21efe68a5..39465301ec94ea78fa6d6f54ae467f0b9fc3e119 100644 (file)
@@ -3003,6 +3003,14 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl)
        case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
                ctl->demod = XC3028_FE_OREN538;
                break;
+       case CX88_BOARD_GENIATECH_X8000_MT:
+               /* FIXME: For this board, the xc3028 never recovers after being
+                  powered down (the reset GPIO probably is not set properly).
+                  We don't have access to the hardware so we cannot determine
+                  which GPIO is used for xc3028, so just disable power xc3028
+                  power management for now */
+               ctl->disable_power_mgmt = 1;
+               break;
        case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
        case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
        case CX88_BOARD_PROLINK_PV_8000GT:
index c44e8760021932bf907ce3be5e135db9f661c5a8..e237b507659ba82bc45a03022245118ef41fce2b 100644 (file)
@@ -501,6 +501,7 @@ static struct zl10353_config cx88_pinnacle_hybrid_pctv = {
 static struct zl10353_config cx88_geniatech_x8000_mt = {
        .demod_address = (0x1e >> 1),
        .no_tuner = 1,
+       .disable_i2c_gate_ctrl = 1,
 };
 
 static struct s5h1411_config dvico_fusionhdtv7_config = {
index da4e3912cd374991ba37f560779e2a871f05cf28..7172dcf2a4fa87ed94c4ac3c41789e1ddafc467d 100644 (file)
@@ -116,6 +116,10 @@ static int cx8802_start_dma(struct cx8802_dev    *dev,
                        udelay(100);
                        break;
                case CX88_BOARD_HAUPPAUGE_HVR1300:
+                       /* Enable MPEG parallel IO and video signal pins */
+                       cx_write(MO_PINMUX_IO, 0x88);
+                       cx_write(TS_SOP_STAT, 0);
+                       cx_write(TS_VALERR_CNTRL, 0);
                        break;
                case CX88_BOARD_PINNACLE_PCTV_HD_800i:
                        /* Enable MPEG parallel IO and video signal pins */
index 320f1f60276ec0a5fa71f58ba5eca48690d19f1a..ed281f5659459c20bc571fbfb3ed61e3348590bc 100644 (file)
@@ -218,7 +218,7 @@ static struct em28xx_reg_seq silvercrest_reg_seq[] = {
 struct em28xx_board em28xx_boards[] = {
        [EM2750_BOARD_UNKNOWN] = {
                .name          = "EM2710/EM2750/EM2751 webcam grabber",
-               .xclk          = EM28XX_XCLK_FREQUENCY_48MHZ,
+               .xclk          = EM28XX_XCLK_FREQUENCY_20MHZ,
                .tuner_type    = TUNER_ABSENT,
                .is_webcam     = 1,
                .input         = { {
@@ -622,22 +622,27 @@ struct em28xx_board em28xx_boards[] = {
        },
        [EM2861_BOARD_PLEXTOR_PX_TV100U] = {
                .name         = "Plextor ConvertX PX-TV100U",
-               .valid        = EM28XX_BOARD_NOT_VALIDATED,
                .tuner_type   = TUNER_TNF_5335MF,
+               .xclk         = EM28XX_XCLK_I2S_MSB_TIMING |
+                               EM28XX_XCLK_FREQUENCY_12MHZ,
                .tda9887_conf = TDA9887_PRESENT,
                .decoder      = EM28XX_TVP5150,
+               .has_msp34xx  = 1,
                .input        = { {
                        .type     = EM28XX_VMUX_TELEVISION,
                        .vmux     = TVP5150_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
+                       .gpio     = pinnacle_hybrid_pro_analog,
                }, {
                        .type     = EM28XX_VMUX_COMPOSITE1,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
+                       .gpio     = pinnacle_hybrid_pro_analog,
                }, {
                        .type     = EM28XX_VMUX_SVIDEO,
                        .vmux     = TVP5150_SVIDEO,
                        .amux     = EM28XX_AMUX_LINE_IN,
+                       .gpio     = pinnacle_hybrid_pro_analog,
                } },
        },
 
@@ -1544,6 +1549,8 @@ struct usb_device_id em28xx_id_table[] = {
                        .driver_info = EM2750_BOARD_UNKNOWN },
        { USB_DEVICE(0xeb1a, 0x2800),
                        .driver_info = EM2800_BOARD_UNKNOWN },
+       { USB_DEVICE(0xeb1a, 0x2710),
+                       .driver_info = EM2820_BOARD_UNKNOWN },
        { USB_DEVICE(0xeb1a, 0x2820),
                        .driver_info = EM2820_BOARD_UNKNOWN },
        { USB_DEVICE(0xeb1a, 0x2821),
@@ -1761,6 +1768,7 @@ static int em28xx_hint_sensor(struct em28xx *dev)
        __be16 version_be;
        u16 version;
 
+       /* Micron sensor detection */
        dev->i2c_client.addr = 0xba >> 1;
        cmd = 0;
        i2c_master_send(&dev->i2c_client, &cmd, 1);
@@ -1769,15 +1777,27 @@ static int em28xx_hint_sensor(struct em28xx *dev)
                return -EINVAL;
 
        version = be16_to_cpu(version_be);
-
        switch (version) {
-       case 0x8243:            /* mt9v011 640x480 1.3 Mpix sensor */
+       case 0x8232:            /* mt9v011 640x480 1.3 Mpix sensor */
+       case 0x8243:            /* mt9v011 rev B 640x480 1.3 Mpix sensor */
                dev->model = EM2820_BOARD_SILVERCREST_WEBCAM;
+               em28xx_set_model(dev);
+
                sensor_name = "mt9v011";
                dev->em28xx_sensor = EM28XX_MT9V011;
                dev->sensor_xres = 640;
                dev->sensor_yres = 480;
-               dev->sensor_xtal = 6300000;
+               /*
+                * FIXME: mt9v011 uses I2S speed as xtal clk - at least with
+                * the Silvercrest cam I have here for testing - for higher
+                * resolutions, a high clock cause horizontal artifacts, so we
+                * need to use a lower xclk frequency.
+                * Yet, it would be possible to adjust xclk depending on the
+                * desired resolution, since this affects directly the
+                * frame rate.
+                */
+               dev->board.xclk = EM28XX_XCLK_FREQUENCY_4_3MHZ;
+               dev->sensor_xtal = 4300000;
 
                /* probably means GRGB 16 bit bayer */
                dev->vinmode = 0x0d;
@@ -1786,6 +1806,8 @@ static int em28xx_hint_sensor(struct em28xx *dev)
                break;
        case 0x8431:
                dev->model = EM2750_BOARD_UNKNOWN;
+               em28xx_set_model(dev);
+
                sensor_name = "mt9m001";
                dev->em28xx_sensor = EM28XX_MT9M001;
                em28xx_initialize_mt9m001(dev);
@@ -1802,6 +1824,9 @@ static int em28xx_hint_sensor(struct em28xx *dev)
                return -EINVAL;
        }
 
+       /* Setup webcam defaults */
+       em28xx_pre_card_setup(dev);
+
        em28xx_errdev("Sensor is %s, using model %s entry.\n",
                      sensor_name, em28xx_boards[dev->model].name);
 
@@ -1813,60 +1838,6 @@ static int em28xx_hint_sensor(struct em28xx *dev)
  */
 void em28xx_pre_card_setup(struct em28xx *dev)
 {
-       int rc;
-
-       em28xx_set_model(dev);
-
-       em28xx_info("Identified as %s (card=%d)\n",
-                   dev->board.name, dev->model);
-
-       /* Set the default GPO/GPIO for legacy devices */
-       dev->reg_gpo_num = EM2880_R04_GPO;
-       dev->reg_gpio_num = EM28XX_R08_GPIO;
-
-       dev->wait_after_write = 5;
-
-       /* Based on the Chip ID, set the device configuration */
-       rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
-       if (rc > 0) {
-               dev->chip_id = rc;
-
-               switch (dev->chip_id) {
-               case CHIP_ID_EM2750:
-                       em28xx_info("chip ID is em2750\n");
-                       break;
-               case CHIP_ID_EM2820:
-                       em28xx_info("chip ID is em2710 or em2820\n");
-                       break;
-               case CHIP_ID_EM2840:
-                       em28xx_info("chip ID is em2840\n");
-                       break;
-               case CHIP_ID_EM2860:
-                       em28xx_info("chip ID is em2860\n");
-                       break;
-               case CHIP_ID_EM2870:
-                       em28xx_info("chip ID is em2870\n");
-                       dev->wait_after_write = 0;
-                       break;
-               case CHIP_ID_EM2874:
-                       em28xx_info("chip ID is em2874\n");
-                       dev->reg_gpio_num = EM2874_R80_GPIO;
-                       dev->wait_after_write = 0;
-                       break;
-               case CHIP_ID_EM2883:
-                       em28xx_info("chip ID is em2882/em2883\n");
-                       dev->wait_after_write = 0;
-                       break;
-               default:
-                       em28xx_info("em28xx chip ID = %d\n", dev->chip_id);
-               }
-       }
-
-       /* Prepopulate cached GPO register content */
-       rc = em28xx_read_reg(dev, dev->reg_gpo_num);
-       if (rc >= 0)
-               dev->reg_gpo = rc;
-
        /* Set the initial XCLK and I2C clock values based on the board
           definition */
        em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk & 0x7f);
@@ -1876,9 +1847,8 @@ void em28xx_pre_card_setup(struct em28xx *dev)
        /* request some modules */
        switch (dev->model) {
        case EM2861_BOARD_PLEXTOR_PX_TV100U:
-               /* FIXME guess */
-               /* Turn on analog audio output */
-               em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+               /* Sets the msp34xx I2S speed */
+               dev->i2s_speed = 2048000;
                break;
        case EM2861_BOARD_KWORLD_PVRTV_300U:
        case EM2880_BOARD_KWORLD_DVB_305U:
@@ -2216,7 +2186,20 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
 
 void em28xx_card_setup(struct em28xx *dev)
 {
-       em28xx_set_model(dev);
+       /*
+        * If the device can be a webcam, seek for a sensor.
+        * If sensor is not found, then it isn't a webcam.
+        */
+       if (dev->board.is_webcam) {
+               if (em28xx_hint_sensor(dev) < 0)
+                       dev->board.is_webcam = 0;
+               else
+                       dev->progressive = 1;
+       } else
+               em28xx_set_model(dev);
+
+       em28xx_info("Identified as %s (card=%d)\n",
+                   dev->board.name, dev->model);
 
        dev->tuner_type = em28xx_boards[dev->model].tuner_type;
        if (em28xx_boards[dev->model].tuner_addr)
@@ -2290,10 +2273,6 @@ void em28xx_card_setup(struct em28xx *dev)
                em28xx_gpio_set(dev, dev->board.tuner_gpio);
                em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
                break;
-       case EM2820_BOARD_SILVERCREST_WEBCAM:
-               /* FIXME: need to document the registers bellow */
-               em28xx_write_reg(dev, 0x0d, 0x42);
-               em28xx_write_reg(dev, 0x13, 0x08);
        }
 
        if (dev->board.has_snapshot_button)
@@ -2433,7 +2412,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
                           int minor)
 {
        struct em28xx *dev = *devhandle;
-       int retval = -ENOMEM;
+       int retval;
        int errCode;
 
        dev->udev = udev;
@@ -2450,6 +2429,58 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
        dev->em28xx_read_reg_req = em28xx_read_reg_req;
        dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800;
 
+       em28xx_set_model(dev);
+
+       /* Set the default GPO/GPIO for legacy devices */
+       dev->reg_gpo_num = EM2880_R04_GPO;
+       dev->reg_gpio_num = EM28XX_R08_GPIO;
+
+       dev->wait_after_write = 5;
+
+       /* Based on the Chip ID, set the device configuration */
+       retval = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
+       if (retval > 0) {
+               dev->chip_id = retval;
+
+               switch (dev->chip_id) {
+               case CHIP_ID_EM2710:
+                       em28xx_info("chip ID is em2710\n");
+                       break;
+               case CHIP_ID_EM2750:
+                       em28xx_info("chip ID is em2750\n");
+                       break;
+               case CHIP_ID_EM2820:
+                       em28xx_info("chip ID is em2820 (or em2710)\n");
+                       break;
+               case CHIP_ID_EM2840:
+                       em28xx_info("chip ID is em2840\n");
+                       break;
+               case CHIP_ID_EM2860:
+                       em28xx_info("chip ID is em2860\n");
+                       break;
+               case CHIP_ID_EM2870:
+                       em28xx_info("chip ID is em2870\n");
+                       dev->wait_after_write = 0;
+                       break;
+               case CHIP_ID_EM2874:
+                       em28xx_info("chip ID is em2874\n");
+                       dev->reg_gpio_num = EM2874_R80_GPIO;
+                       dev->wait_after_write = 0;
+                       break;
+               case CHIP_ID_EM2883:
+                       em28xx_info("chip ID is em2882/em2883\n");
+                       dev->wait_after_write = 0;
+                       break;
+               default:
+                       em28xx_info("em28xx chip ID = %d\n", dev->chip_id);
+               }
+       }
+
+       /* Prepopulate cached GPO register content */
+       retval = em28xx_read_reg(dev, dev->reg_gpo_num);
+       if (retval >= 0)
+               dev->reg_gpo = retval;
+
        em28xx_pre_card_setup(dev);
 
        if (!dev->board.is_em2800) {
@@ -2484,14 +2515,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
        dev->vinmode = 0x10;
        dev->vinctl  = 0x11;
 
-       /*
-        * If the device can be a webcam, seek for a sensor.
-        * If sensor is not found, then it isn't a webcam.
-        */
-       if (dev->board.is_webcam)
-               if (em28xx_hint_sensor(dev) < 0)
-                       dev->board.is_webcam = 0;
-
        /* Do board specific init and eeprom reading */
        em28xx_card_setup(dev);
 
index 5b78e199abd1ac9bbf433dba0012eafe02b0ab46..98e140b5d95e66a48876514721ab203369cf2e89 100644 (file)
@@ -632,6 +632,9 @@ int em28xx_capture_start(struct em28xx *dev, int start)
                return rc;
        }
 
+       if (dev->board.is_webcam)
+               rc = em28xx_write_reg(dev, 0x13, 0x0c);
+
        /* enable video capture */
        rc = em28xx_write_reg(dev, 0x48, 0x00);
 
@@ -720,7 +723,10 @@ int em28xx_resolution_set(struct em28xx *dev)
 {
        int width, height;
        width = norm_maxw(dev);
-       height = norm_maxh(dev) >> 1;
+       height = norm_maxh(dev);
+
+       if (!dev->progressive)
+               height >>= norm_maxh(dev);
 
        em28xx_set_outfmt(dev);
 
index cf0ac7f2a30d59bed6a8e617a1a1ea38e0e3e6d5..d603575431b44b71d59288ac5d860f6d7e4ae254 100644 (file)
@@ -478,7 +478,6 @@ static int dvb_init(struct em28xx *dev)
                }
                break;
        case EM2880_BOARD_KWORLD_DVB_310U:
-       case EM2880_BOARD_EMPIRE_DUAL_TV:
                dvb->frontend = dvb_attach(zl10353_attach,
                                           &em28xx_zl10353_with_xc3028,
                                           &dev->i2c_adap);
@@ -488,6 +487,7 @@ static int dvb_init(struct em28xx *dev)
                }
                break;
        case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
+       case EM2880_BOARD_EMPIRE_DUAL_TV:
                dvb->frontend = dvb_attach(zl10353_attach,
                                           &em28xx_zl10353_xc3028_no_i2c_gate,
                                           &dev->i2c_adap);
index a2676d63cfd0a673cfd26b6e0ddd593ecab10e5a..6bf84bd787df81765b25d8924463cdbb14f344a4 100644 (file)
 
 /* FIXME: Need to be populated with the other chip ID's */
 enum em28xx_chip_id {
-       CHIP_ID_EM2820 = 18,    /* Also used by em2710 */
+       CHIP_ID_EM2710 = 17,
+       CHIP_ID_EM2820 = 18,    /* Also used by some em2710 */
        CHIP_ID_EM2840 = 20,
        CHIP_ID_EM2750 = 33,
        CHIP_ID_EM2860 = 34,
index ff37b4c15f444e43c54034622113384ac8f498e0..ab079d9256c463a0c9889841ed3e0946969f1929 100644 (file)
@@ -194,15 +194,24 @@ static void em28xx_copy_video(struct em28xx *dev,
        startread = p;
        remain = len;
 
-       /* Interlaces frame */
-       if (buf->top_field)
+       if (dev->progressive)
                fieldstart = outp;
-       else
-               fieldstart = outp + bytesperline;
+       else {
+               /* Interlaces two half frames */
+               if (buf->top_field)
+                       fieldstart = outp;
+               else
+                       fieldstart = outp + bytesperline;
+       }
 
        linesdone = dma_q->pos / bytesperline;
        currlinedone = dma_q->pos % bytesperline;
-       offset = linesdone * bytesperline * 2 + currlinedone;
+
+       if (dev->progressive)
+               offset = linesdone * bytesperline + currlinedone;
+       else
+               offset = linesdone * bytesperline * 2 + currlinedone;
+
        startwrite = fieldstart + offset;
        lencopy = bytesperline - currlinedone;
        lencopy = lencopy > remain ? remain : lencopy;
@@ -376,7 +385,7 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
                        em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
                                       len, (p[2] & 1) ? "odd" : "even");
 
-                       if (!(p[2] & 1)) {
+                       if (dev->progressive || !(p[2] & 1)) {
                                if (buf != NULL)
                                        buffer_filled(dev, dma_q, buf);
                                get_next_buf(dma_q, &buf);
@@ -689,7 +698,10 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 
        /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
-       f->fmt.pix.field = dev->interlaced ?
+       if (dev->progressive)
+               f->fmt.pix.field = V4L2_FIELD_NONE;
+       else
+               f->fmt.pix.field = dev->interlaced ?
                           V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
 
        mutex_unlock(&dev->lock);
@@ -753,7 +765,11 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3;
        f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-       f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+       if (dev->progressive)
+               f->fmt.pix.field = V4L2_FIELD_NONE;
+       else
+               f->fmt.pix.field = dev->interlaced ?
+                          V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
 
        return 0;
 }
@@ -846,6 +862,41 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
        return 0;
 }
 
+static int vidioc_g_parm(struct file *file, void *priv,
+                        struct v4l2_streamparm *p)
+{
+       struct em28xx_fh   *fh  = priv;
+       struct em28xx      *dev = fh->dev;
+       int rc = 0;
+
+       if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       if (dev->board.is_webcam)
+               rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0,
+                                               video, g_parm, p);
+       else
+               v4l2_video_std_frame_period(dev->norm,
+                                                &p->parm.capture.timeperframe);
+
+       return rc;
+}
+
+static int vidioc_s_parm(struct file *file, void *priv,
+                        struct v4l2_streamparm *p)
+{
+       struct em28xx_fh   *fh  = priv;
+       struct em28xx      *dev = fh->dev;
+
+       if (!dev->board.is_webcam)
+               return -EINVAL;
+
+       if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       return v4l2_device_call_until_err(&dev->v4l2_dev, 0, video, s_parm, p);
+}
+
 static const char *iname[] = {
        [EM28XX_VMUX_COMPOSITE1] = "Composite1",
        [EM28XX_VMUX_COMPOSITE2] = "Composite2",
@@ -1624,6 +1675,7 @@ static int em28xx_v4l2_open(struct file *filp)
        struct em28xx *dev;
        enum v4l2_buf_type fh_type;
        struct em28xx_fh *fh;
+       enum v4l2_field field;
 
        dev = em28xx_get_device(minor, &fh_type, &radio);
 
@@ -1665,8 +1717,13 @@ static int em28xx_v4l2_open(struct file *filp)
 
        dev->users++;
 
+       if (dev->progressive)
+               field = V4L2_FIELD_NONE;
+       else
+               field = V4L2_FIELD_INTERLACED;
+
        videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops,
-                       NULL, &dev->slock, fh->type, V4L2_FIELD_INTERLACED,
+                       NULL, &dev->slock, fh->type, field,
                        sizeof(struct em28xx_buffer), fh);
 
        mutex_unlock(&dev->lock);
@@ -1885,6 +1942,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
        .vidioc_qbuf                = vidioc_qbuf,
        .vidioc_dqbuf               = vidioc_dqbuf,
        .vidioc_s_std               = vidioc_s_std,
+       .vidioc_g_parm              = vidioc_g_parm,
+       .vidioc_s_parm              = vidioc_s_parm,
        .vidioc_enum_input          = vidioc_enum_input,
        .vidioc_g_input             = vidioc_g_input,
        .vidioc_s_input             = vidioc_s_input,
index 45bd513f62dcb8ed42bd9e37c58956f204f1d23f..8c2dc38bca9ffe8b9a02f7e7af5d5dcc17a9df61 100644 (file)
@@ -484,6 +484,9 @@ struct em28xx {
        int sensor_xres, sensor_yres;
        int sensor_xtal;
 
+       /* Allows progressive (e. g. non-interlaced) mode */
+       int progressive;
+
        /* Vinmode/Vinctl used at the driver */
        int vinmode, vinctl;
 
index ccd47f57f42cf75633dd6c5badb91786d835d1e0..d678765cbba233a1b6bc869c858532b01735233b 100644 (file)
@@ -1220,6 +1220,8 @@ static const struct video_device hdpvr_video_template = {
                V4L2_STD_PAL_G | V4L2_STD_PAL_H | V4L2_STD_PAL_I |
                V4L2_STD_PAL_D | V4L2_STD_PAL_M | V4L2_STD_PAL_N |
                V4L2_STD_PAL_60,
+       .current_norm           = V4L2_STD_NTSC | V4L2_STD_PAL_M |
+               V4L2_STD_PAL_60,
 };
 
 int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
index a3b77ed3f08949a58729ea1edda921cb762d0dc7..4a9c8ce0ecb307cc07d167a0c6685bcd3583fefe 100644 (file)
@@ -17,6 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+#include <linux/kernel.h>
 
 #include "ivtv-driver.h"
 #include "ivtv-cards.h"
@@ -281,7 +282,7 @@ int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
                idx = p.audio_properties & 0x03;
                /* The audio clock of the digitizer must match the codec sample
                   rate otherwise you get some very strange effects. */
-               if (idx < sizeof(freqs))
+               if (idx < ARRAY_SIZE(freqs))
                        ivtv_call_all(itv, audio, s_clock_freq, freqs[idx]);
                return err;
        }
index b2260de645f0c16855dfd31ac8aa4b296a05f34f..cc85f77a570694e39fc0cc0fbc37eef118a568fa 100644 (file)
@@ -52,13 +52,34 @@ static struct v4l2_queryctrl mt9v011_qctrl[] = {
                .step = 1,
                .default_value = 0,
                .flags = 0,
-       },
+       }, {
+               .id      = V4L2_CID_HFLIP,
+               .type    = V4L2_CTRL_TYPE_BOOLEAN,
+               .name    = "Mirror",
+               .minimum = 0,
+               .maximum = 1,
+               .step    = 1,
+               .default_value = 0,
+               .flags = 0,
+       }, {
+               .id      = V4L2_CID_VFLIP,
+               .type    = V4L2_CTRL_TYPE_BOOLEAN,
+               .name    = "Vflip",
+               .minimum = 0,
+               .maximum = 1,
+               .step    = 1,
+               .default_value = 0,
+               .flags = 0,
+       }, {
+       }
 };
 
 struct mt9v011 {
        struct v4l2_subdev sd;
        unsigned width, height;
        unsigned xtal;
+       unsigned hflip:1;
+       unsigned vflip:1;
 
        u16 global_gain, red_bal, blue_bal;
 };
@@ -131,7 +152,6 @@ static const struct i2c_reg_value mt9v011_init_default[] = {
 
                { R0A_MT9V011_CLK_SPEED, 0x0000 },
                { R1E_MT9V011_DIGITAL_ZOOM,  0x0000 },
-               { R20_MT9V011_READ_MODE, 0x1000 },
 
                { R07_MT9V011_OUT_CTRL, 0x0002 },       /* chip enable */
 };
@@ -156,7 +176,7 @@ static void set_balance(struct v4l2_subdev *sd)
        mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain);
 }
 
-static void calc_fps(struct v4l2_subdev *sd)
+static void calc_fps(struct v4l2_subdev *sd, u32 *numerator, u32 *denominator)
 {
        struct mt9v011 *core = to_mt9v011(sd);
        unsigned height, width, hblank, vblank, speed;
@@ -179,6 +199,51 @@ static void calc_fps(struct v4l2_subdev *sd)
 
        v4l2_dbg(1, debug, sd, "Programmed to %u.%03u fps (%d pixel clcks)\n",
                tmp / 1000, tmp % 1000, t_time);
+
+       if (numerator && denominator) {
+               *numerator = 1000;
+               *denominator = (u32)frames_per_ms;
+       }
+}
+
+static u16 calc_speed(struct v4l2_subdev *sd, u32 numerator, u32 denominator)
+{
+       struct mt9v011 *core = to_mt9v011(sd);
+       unsigned height, width, hblank, vblank;
+       unsigned row_time, line_time;
+       u64 t_time, speed;
+
+       /* Avoid bogus calculus */
+       if (!numerator || !denominator)
+               return 0;
+
+       height = mt9v011_read(sd, R03_MT9V011_HEIGHT);
+       width = mt9v011_read(sd, R04_MT9V011_WIDTH);
+       hblank = mt9v011_read(sd, R05_MT9V011_HBLANK);
+       vblank = mt9v011_read(sd, R06_MT9V011_VBLANK);
+
+       row_time = width + 113 + hblank;
+       line_time = height + vblank + 1;
+
+       t_time = core->xtal * ((u64)numerator);
+       /* round to the closest value */
+       t_time += denominator / 2;
+       do_div(t_time, denominator);
+
+       speed = t_time;
+       do_div(speed, row_time * line_time);
+
+       /* Avoid having a negative value for speed */
+       if (speed < 2)
+               speed = 0;
+       else
+               speed -= 2;
+
+       /* Avoid speed overflow */
+       if (speed > 15)
+               return 15;
+
+       return (u16)speed;
 }
 
 static void set_res(struct v4l2_subdev *sd)
@@ -207,9 +272,23 @@ static void set_res(struct v4l2_subdev *sd)
        mt9v011_write(sd, R03_MT9V011_HEIGHT, core->height);
        mt9v011_write(sd, R06_MT9V011_VBLANK, 508 - core->height);
 
-       calc_fps(sd);
+       calc_fps(sd, NULL, NULL);
 };
 
+static void set_read_mode(struct v4l2_subdev *sd)
+{
+       struct mt9v011 *core = to_mt9v011(sd);
+       unsigned mode = 0x1000;
+
+       if (core->hflip)
+               mode |= 0x4000;
+
+       if (core->vflip)
+               mode |= 0x8000;
+
+       mt9v011_write(sd, R20_MT9V011_READ_MODE, mode);
+}
+
 static int mt9v011_reset(struct v4l2_subdev *sd, u32 val)
 {
        int i;
@@ -220,6 +299,7 @@ static int mt9v011_reset(struct v4l2_subdev *sd, u32 val)
 
        set_balance(sd);
        set_res(sd);
+       set_read_mode(sd);
 
        return 0;
 };
@@ -240,6 +320,12 @@ static int mt9v011_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
        case V4L2_CID_BLUE_BALANCE:
                ctrl->value = core->blue_bal;
                return 0;
+       case V4L2_CID_HFLIP:
+               ctrl->value = core->hflip ? 1 : 0;
+               return 0;
+       case V4L2_CID_VFLIP:
+               ctrl->value = core->vflip ? 1 : 0;
+               return 0;
        }
        return -EINVAL;
 }
@@ -288,6 +374,14 @@ static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
        case V4L2_CID_BLUE_BALANCE:
                core->blue_bal = ctrl->value;
                break;
+       case V4L2_CID_HFLIP:
+               core->hflip = ctrl->value;
+               set_read_mode(sd);
+               return 0;
+       case V4L2_CID_VFLIP:
+               core->vflip = ctrl->value;
+               set_read_mode(sd);
+               return 0;
        default:
                return -EINVAL;
        }
@@ -322,6 +416,44 @@ static int mt9v011_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
        return 0;
 }
 
+static int mt9v011_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
+{
+       struct v4l2_captureparm *cp = &parms->parm.capture;
+
+       if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       memset(cp, 0, sizeof(struct v4l2_captureparm));
+       cp->capability = V4L2_CAP_TIMEPERFRAME;
+       calc_fps(sd,
+                &cp->timeperframe.numerator,
+                &cp->timeperframe.denominator);
+
+       return 0;
+}
+
+static int mt9v011_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
+{
+       struct v4l2_captureparm *cp = &parms->parm.capture;
+       struct v4l2_fract *tpf = &cp->timeperframe;
+       u16 speed;
+
+       if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+       if (cp->extendedmode != 0)
+               return -EINVAL;
+
+       speed = calc_speed(sd, tpf->numerator, tpf->denominator);
+
+       mt9v011_write(sd, R0A_MT9V011_CLK_SPEED, speed);
+       v4l2_dbg(1, debug, sd, "Setting speed to %d\n", speed);
+
+       /* Recalculate and update fps info */
+       calc_fps(sd, &tpf->numerator, &tpf->denominator);
+
+       return 0;
+}
+
 static int mt9v011_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
 {
        struct v4l2_pix_format *pix = &fmt->fmt.pix;
@@ -393,10 +525,13 @@ static int mt9v011_s_register(struct v4l2_subdev *sd,
 static int mt9v011_g_chip_ident(struct v4l2_subdev *sd,
                                struct v4l2_dbg_chip_ident *chip)
 {
+       u16 version;
        struct i2c_client *client = v4l2_get_subdevdata(sd);
 
+       version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION);
+
        return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_MT9V011,
-                                         MT9V011_VERSION);
+                                         version);
 }
 
 static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
@@ -416,6 +551,8 @@ static const struct v4l2_subdev_video_ops mt9v011_video_ops = {
        .enum_fmt = mt9v011_enum_fmt,
        .try_fmt = mt9v011_try_fmt,
        .s_fmt = mt9v011_s_fmt,
+       .g_parm = mt9v011_g_parm,
+       .s_parm = mt9v011_s_parm,
 };
 
 static const struct v4l2_subdev_ops mt9v011_ops = {
@@ -449,8 +586,9 @@ static int mt9v011_probe(struct i2c_client *c,
 
        /* Check if the sensor is really a MT9V011 */
        version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION);
-       if (version != MT9V011_VERSION) {
-               v4l2_info(sd, "*** unknown micron chip detected (0x%04x.\n",
+       if ((version != MT9V011_VERSION) &&
+           (version != MT9V011_REV_B_VERSION)) {
+               v4l2_info(sd, "*** unknown micron chip detected (0x%04x).\n",
                          version);
                kfree(core);
                return -EINVAL;
@@ -461,8 +599,8 @@ static int mt9v011_probe(struct i2c_client *c,
        core->height = 480;
        core->xtal = 27000000;  /* Hz */
 
-       v4l_info(c, "chip found @ 0x%02x (%s)\n",
-                c->addr << 1, c->adapter->name);
+       v4l_info(c, "chip found @ 0x%02x (%s - chip version 0x%04x)\n",
+                c->addr << 1, c->adapter->name, version);
 
        return 0;
 }
index 9e443ee305585ee81da44a604c93d325ec7efd2e..3350fd6083c3d1fa8e40a4f6627f0e61c60968ac 100644 (file)
@@ -30,6 +30,7 @@
 #define R35_MT9V011_GLOBAL_GAIN                0x35
 #define RF1_MT9V011_CHIP_ENABLE                0xf1
 
-#define MT9V011_VERSION                        0x8243
+#define MT9V011_VERSION                        0x8232
+#define MT9V011_REV_B_VERSION          0x8243
 
 #endif
index 2d075205bdfe4b724e22882aa5e6a636edf81cef..736c31d23194525b233966c848ab7cae772c8dc9 100644 (file)
@@ -234,6 +234,7 @@ static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
        return ret;
 }
 
+/* Called under spinlock_irqsave(&pcdev->lock, ...) */
 static void mx1_videobuf_queue(struct videobuf_queue *vq,
                                                struct videobuf_buffer *vb)
 {
@@ -241,13 +242,10 @@ static void mx1_videobuf_queue(struct videobuf_queue *vq,
        struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
        struct mx1_camera_dev *pcdev = ici->priv;
        struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
-       unsigned long flags;
 
        dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
                vb, vb->baddr, vb->bsize);
 
-       spin_lock_irqsave(&pcdev->lock, flags);
-
        list_add_tail(&vb->queue, &pcdev->capture);
 
        vb->state = VIDEOBUF_ACTIVE;
@@ -264,8 +262,6 @@ static void mx1_videobuf_queue(struct videobuf_queue *vq,
                        __raw_writel(temp, pcdev->base + CSICR1);
                }
        }
-
-       spin_unlock_irqrestore(&pcdev->lock, flags);
 }
 
 static void mx1_videobuf_release(struct videobuf_queue *vq,
index e605c076ed89d43ae5533e98d5d4dc60009dfd19..9770cb7932caeb07fcb36be6568cac021d405094 100644 (file)
@@ -332,7 +332,10 @@ static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc)
        }
 }
 
-/* Called with .vb_lock held */
+/*
+ * Called with .vb_lock mutex held and
+ * under spinlock_irqsave(&mx3_cam->lock, ...)
+ */
 static void mx3_videobuf_queue(struct videobuf_queue *vq,
                               struct videobuf_buffer *vb)
 {
@@ -346,7 +349,8 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
        struct idmac_video_param *video = &ichan->params.video;
        const struct soc_camera_data_format *data_fmt = icd->current_fmt;
        dma_cookie_t cookie;
-       unsigned long flags;
+
+       BUG_ON(!irqs_disabled());
 
        /* This is the configuration of one sg-element */
        video->out_pixel_fmt    = fourcc_to_ipu_pix(data_fmt->fourcc);
@@ -359,8 +363,6 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
        memset((void *)vb->baddr, 0xaa, vb->bsize);
 #endif
 
-       spin_lock_irqsave(&mx3_cam->lock, flags);
-
        list_add_tail(&vb->queue, &mx3_cam->capture);
 
        if (!mx3_cam->active) {
@@ -370,24 +372,23 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
                vb->state = VIDEOBUF_QUEUED;
        }
 
-       spin_unlock_irqrestore(&mx3_cam->lock, flags);
+       spin_unlock_irq(&mx3_cam->lock);
 
        cookie = txd->tx_submit(txd);
        dev_dbg(&icd->dev, "Submitted cookie %d DMA 0x%08x\n", cookie, sg_dma_address(&buf->sg));
+
+       spin_lock_irq(&mx3_cam->lock);
+
        if (cookie >= 0)
                return;
 
        /* Submit error */
        vb->state = VIDEOBUF_PREPARED;
 
-       spin_lock_irqsave(&mx3_cam->lock, flags);
-
        list_del_init(&vb->queue);
 
        if (mx3_cam->active == buf)
                mx3_cam->active = NULL;
-
-       spin_unlock_irqrestore(&mx3_cam->lock, flags);
 }
 
 /* Called with .vb_lock held */
index 46e0d8ad880fc58e56a3928347e52907f6e70cb7..016bb45ba0c3e2f48e1801651c04dab25c262b74 100644 (file)
@@ -612,6 +612,7 @@ static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev)
        dev_dbg(pcdev->soc_host.dev, "%s\n", __func__);
 }
 
+/* Called under spinlock_irqsave(&pcdev->lock, ...) */
 static void pxa_videobuf_queue(struct videobuf_queue *vq,
                               struct videobuf_buffer *vb)
 {
@@ -619,13 +620,10 @@ static void pxa_videobuf_queue(struct videobuf_queue *vq,
        struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
        struct pxa_camera_dev *pcdev = ici->priv;
        struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
-       unsigned long flags;
 
        dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d active=%p\n", __func__,
                vb, vb->baddr, vb->bsize, pcdev->active);
 
-       spin_lock_irqsave(&pcdev->lock, flags);
-
        list_add_tail(&vb->queue, &pcdev->capture);
 
        vb->state = VIDEOBUF_ACTIVE;
@@ -633,8 +631,6 @@ static void pxa_videobuf_queue(struct videobuf_queue *vq,
 
        if (!pcdev->active)
                pxa_camera_start_capture(pcdev);
-
-       spin_unlock_irqrestore(&pcdev->lock, flags);
 }
 
 static void pxa_videobuf_release(struct videobuf_queue *vq,
@@ -1579,6 +1575,7 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
                pcdev->mclk = 20000000;
        }
 
+       pcdev->soc_host.dev = &pdev->dev;
        pcdev->mclk_divisor = mclk_get_divisor(pcdev);
 
        INIT_LIST_HEAD(&pcdev->capture);
@@ -1644,7 +1641,6 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
        pcdev->soc_host.drv_name        = PXA_CAM_DRV_NAME;
        pcdev->soc_host.ops             = &pxa_soc_camera_host_ops;
        pcdev->soc_host.priv            = pcdev;
-       pcdev->soc_host.dev             = &pdev->dev;
        pcdev->soc_host.nr              = pdev->id;
 
        err = soc_camera_host_register(&pcdev->soc_host);
index 06861b782b9529f503ac26102eb17fc2ddd68908..6eebe3ef97d37efa9f8375eafa53e6b75420f79a 100644 (file)
@@ -3331,8 +3331,8 @@ struct saa7134_board saa7134_boards[] = {
                        .gpio = 0x0200100,
                },
        },
-       [SAA7134_BOARD_HAUPPAUGE_HVR1120] = {
-               .name           = "Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid",
+       [SAA7134_BOARD_HAUPPAUGE_HVR1150] = {
+               .name           = "Hauppauge WinTV-HVR1150 ATSC/QAM-Hybrid",
                .audio_clock    = 0x00187de7,
                .tuner_type     = TUNER_PHILIPS_TDA8290,
                .radio_type     = UNSET,
@@ -3363,8 +3363,8 @@ struct saa7134_board saa7134_boards[] = {
                        .gpio = 0x0800100, /* GPIO 23 HI for FM */
                },
        },
-       [SAA7134_BOARD_HAUPPAUGE_HVR1110R3] = {
-               .name           = "Hauppauge WinTV-HVR1110r3 DVB-T/Hybrid",
+       [SAA7134_BOARD_HAUPPAUGE_HVR1120] = {
+               .name           = "Hauppauge WinTV-HVR1120 DVB-T/Hybrid",
                .audio_clock    = 0x00187de7,
                .tuner_type     = TUNER_PHILIPS_TDA8290,
                .radio_type     = UNSET,
@@ -5862,31 +5862,31 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
                .subvendor    = 0x0070,
                .subdevice    = 0x6706,
-               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1120,
+               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1150,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
                .subvendor    = 0x0070,
                .subdevice    = 0x6707,
-               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1110R3,
+               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1120,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
                .subvendor    = 0x0070,
                .subdevice    = 0x6708,
-               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1120,
+               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1150,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
                .subvendor    = 0x0070,
                .subdevice    = 0x6709,
-               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1110R3,
+               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1120,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
                .subvendor    = 0x0070,
                .subdevice    = 0x670a,
-               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1110R3,
+               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1120,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -6363,8 +6363,8 @@ static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev,
        switch (command) {
        case TDA18271_CALLBACK_CMD_AGC_ENABLE: /* 0 */
                switch (dev->board) {
+               case SAA7134_BOARD_HAUPPAUGE_HVR1150:
                case SAA7134_BOARD_HAUPPAUGE_HVR1120:
-               case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
                        ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg);
                        break;
                default:
@@ -6384,8 +6384,8 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev,
        int ret;
 
        switch (dev->board) {
+       case SAA7134_BOARD_HAUPPAUGE_HVR1150:
        case SAA7134_BOARD_HAUPPAUGE_HVR1120:
-       case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
                /* tda8290 + tda18271 */
                ret = saa7134_tda8290_18271_callback(dev, command, arg);
                break;
@@ -6427,7 +6427,7 @@ static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data)
        switch (tv.model) {
        case 67019: /* WinTV-HVR1110 (Retail, IR Blaster, hybrid, FM, SVid/Comp, 3.5mm audio in) */
        case 67109: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */
-       case 67201: /* WinTV-HVR1120 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */
+       case 67201: /* WinTV-HVR1150 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */
        case 67301: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */
        case 67209: /* WinTV-HVR1110 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */
        case 67559: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
@@ -6435,7 +6435,7 @@ static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data)
        case 67579: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM) */
        case 67589: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */
        case 67599: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */
-       case 67651: /* WinTV-HVR1120 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
+       case 67651: /* WinTV-HVR1150 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
        case 67659: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
                break;
        default:
@@ -6625,8 +6625,8 @@ int saa7134_board_init1(struct saa7134_dev *dev)
 
                saa_writeb (SAA7134_PRODUCTION_TEST_MODE, 0x00);
                break;
+       case SAA7134_BOARD_HAUPPAUGE_HVR1150:
        case SAA7134_BOARD_HAUPPAUGE_HVR1120:
-       case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
                /* GPIO 26 high for digital, low for analog */
                saa7134_set_gpio(dev, 26, 0);
                msleep(1);
@@ -6891,8 +6891,8 @@ int saa7134_board_init2(struct saa7134_dev *dev)
                       dev->name, saa7134_boards[dev->board].name);
               }
               break;
+       case SAA7134_BOARD_HAUPPAUGE_HVR1150:
        case SAA7134_BOARD_HAUPPAUGE_HVR1120:
-       case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
                hauppauge_eeprom(dev, dev->eedata+0x80);
                break;
        case SAA7134_BOARD_HAUPPAUGE_HVR1110:
index 31930f26ffc7d5963aab8d24c7b3a70c918a62e3..98f3efd1e944defe96509f6b6dcb8b79ef00a47c 100644 (file)
@@ -1119,7 +1119,7 @@ static int dvb_init(struct saa7134_dev *dev)
                                         &tda827x_cfg_2) < 0)
                        goto dettach_frontend;
                break;
-       case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
+       case SAA7134_BOARD_HAUPPAUGE_HVR1120:
                fe0->dvb.frontend = dvb_attach(tda10048_attach,
                                               &hcw_tda10048_config,
                                               &dev->i2c_adap);
@@ -1147,7 +1147,7 @@ static int dvb_init(struct saa7134_dev *dev)
                                         &tda827x_cfg_1) < 0)
                        goto dettach_frontend;
                break;
-       case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+       case SAA7134_BOARD_HAUPPAUGE_HVR1150:
                fe0->dvb.frontend = dvb_attach(lgdt3305_attach,
                                               &hcw_lgdt3305_config,
                                               &dev->i2c_adap);
index 82268848f26a4cc8817e17f7a6c5a4281a6952d4..fb564f14887cc0e814f0adcb29a738595cea937c 100644 (file)
@@ -278,8 +278,8 @@ struct saa7134_format {
 #define SAA7134_BOARD_ASUSTeK_TIGER         152
 #define SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG 153
 #define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154
-#define SAA7134_BOARD_HAUPPAUGE_HVR1120     155
-#define SAA7134_BOARD_HAUPPAUGE_HVR1110R3   156
+#define SAA7134_BOARD_HAUPPAUGE_HVR1150     155
+#define SAA7134_BOARD_HAUPPAUGE_HVR1120   156
 #define SAA7134_BOARD_AVERMEDIA_STUDIO_507UA 157
 #define SAA7134_BOARD_AVERMEDIA_CARDBUS_501 158
 #define SAA7134_BOARD_BEHOLD_505RDS         159
index 0db88a53d92c54c60830862c6867d4dbe175bdcb..e86878deea71771d16decce32551f8ae78cfe88b 100644 (file)
@@ -282,27 +282,24 @@ out:
        return ret;
 }
 
+/* Called under spinlock_irqsave(&pcdev->lock, ...) */
 static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
                                         struct videobuf_buffer *vb)
 {
        struct soc_camera_device *icd = vq->priv_data;
        struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
        struct sh_mobile_ceu_dev *pcdev = ici->priv;
-       unsigned long flags;
 
        dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
                vb, vb->baddr, vb->bsize);
 
        vb->state = VIDEOBUF_QUEUED;
-       spin_lock_irqsave(&pcdev->lock, flags);
        list_add_tail(&vb->queue, &pcdev->capture);
 
        if (!pcdev->active) {
                pcdev->active = vb;
                sh_mobile_ceu_capture(pcdev);
        }
-
-       spin_unlock_irqrestore(&pcdev->lock, flags);
 }
 
 static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq,
index 4d6785e634556fbba9bc87a89708302907f40a0c..b154bd961e3b74472d7efccf367c8447004d0f84 100644 (file)
@@ -1050,8 +1050,8 @@ static int stk_setup_format(struct stk_camera *dev)
                depth = 1;
        else
                depth = 2;
-       while (stk_sizes[i].m != dev->vsettings.mode
-                       && i < ARRAY_SIZE(stk_sizes))
+       while (i < ARRAY_SIZE(stk_sizes) &&
+                       stk_sizes[i].m != dev->vsettings.mode)
                i++;
        if (i == ARRAY_SIZE(stk_sizes)) {
                STK_ERROR("Something is broken in %s\n", __func__);
index 89927b7aec28dce2dcd9131b7e36339de826436d..04b47832fa0a5d1d416cdf429cf9e320a69fc59f 100644 (file)
@@ -1845,11 +1845,29 @@ static struct usb_device_id uvc_ids[] = {
          .bInterfaceSubClass   = 1,
          .bInterfaceProtocol   = 0,
          .driver_info          = UVC_QUIRK_STREAM_NO_FID },
-       /* ViMicro */
-       { .match_flags          = USB_DEVICE_ID_MATCH_VENDOR
+       /* ViMicro Vega */
+       { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
+                               | USB_DEVICE_ID_MATCH_INT_INFO,
+         .idVendor             = 0x0ac8,
+         .idProduct            = 0x332d,
+         .bInterfaceClass      = USB_CLASS_VIDEO,
+         .bInterfaceSubClass   = 1,
+         .bInterfaceProtocol   = 0,
+         .driver_info          = UVC_QUIRK_FIX_BANDWIDTH },
+       /* ViMicro - Minoru3D */
+       { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
+                               | USB_DEVICE_ID_MATCH_INT_INFO,
+         .idVendor             = 0x0ac8,
+         .idProduct            = 0x3410,
+         .bInterfaceClass      = USB_CLASS_VIDEO,
+         .bInterfaceSubClass   = 1,
+         .bInterfaceProtocol   = 0,
+         .driver_info          = UVC_QUIRK_FIX_BANDWIDTH },
+       /* ViMicro Venus - Minoru3D */
+       { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
                                | USB_DEVICE_ID_MATCH_INT_INFO,
          .idVendor             = 0x0ac8,
-         .idProduct            = 0x0000,
+         .idProduct            = 0x3420,
          .bInterfaceClass      = USB_CLASS_VIDEO,
          .bInterfaceSubClass   = 1,
          .bInterfaceProtocol   = 0,
index f152a9903862abe4780eebe67ba282f2bf6d9eac..1ca6dff7361241069f2a05ba4631bb00ec5b11d5 100644 (file)
@@ -145,8 +145,8 @@ static void uvc_status_complete(struct urb *urb)
                        break;
 
                default:
-                       uvc_printk(KERN_INFO, "unknown event type %u.\n",
-                               dev->status[0]);
+                       uvc_trace(UVC_TRACE_STATUS, "Unknown status event "
+                               "type %u.\n", dev->status[0]);
                        break;
                }
        }
index be64a502ea276e5a49ee3c97bea6d3f9a52a2fec..f2afc4e08379a1cee0c77201190dd698db576fbb 100644 (file)
@@ -1081,8 +1081,10 @@ static long __video_do_ioctl(struct file *file,
                /* Calls the specific handler */
                if (ops->vidioc_g_std)
                        ret = ops->vidioc_g_std(file, fh, id);
-               else
+               else if (vfd->current_norm)
                        *id = vfd->current_norm;
+               else
+                       ret = -EINVAL;
 
                if (!ret)
                        dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
@@ -1553,12 +1555,19 @@ static long __video_do_ioctl(struct file *file,
                                break;
                        ret = ops->vidioc_g_parm(file, fh, p);
                } else {
+                       v4l2_std_id std = vfd->current_norm;
+
                        if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                                return -EINVAL;
 
-                       v4l2_video_std_frame_period(vfd->current_norm,
-                                                   &p->parm.capture.timeperframe);
                        ret = 0;
+                       if (ops->vidioc_g_std)
+                               ret = ops->vidioc_g_std(file, fh, &std);
+                       else if (std == 0)
+                               ret = -EINVAL;
+                       if (ret == 0)
+                               v4l2_video_std_frame_period(std,
+                                                   &p->parm.capture.timeperframe);
                }
 
                dbgarg(cmd, "type=%d\n", p->type);
diff --git a/drivers/mtd/maps/sbc8240.c b/drivers/mtd/maps/sbc8240.c
deleted file mode 100644 (file)
index e69de29..0000000
index 23419dc3027b69659aab64eeb0a6aced7504810e..a7cbfbd340c7d53fa282f41d543a9737dbebfe8b 100644 (file)
@@ -386,16 +386,16 @@ static ssize_t jid_show(struct gfs2_sbd *sdp, char *buf)
 #define GDLM_ATTR(_name,_mode,_show,_store) \
 static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store)
 
-GDLM_ATTR(proto_name,     0444, proto_name_show,       NULL);
-GDLM_ATTR(block,          0644, block_show,            block_store);
-GDLM_ATTR(withdraw,       0644, withdraw_show,         withdraw_store);
-GDLM_ATTR(id,             0444, lkid_show,             NULL);
-GDLM_ATTR(jid,           0444, jid_show,               NULL);
-GDLM_ATTR(first,          0444, lkfirst_show,          NULL);
-GDLM_ATTR(first_done,     0444, first_done_show,       NULL);
-GDLM_ATTR(recover,        0200, NULL,                  recover_store);
-GDLM_ATTR(recover_done,   0444, recover_done_show,     NULL);
-GDLM_ATTR(recover_status, 0444, recover_status_show,   NULL);
+GDLM_ATTR(proto_name,          0444, proto_name_show,          NULL);
+GDLM_ATTR(block,               0644, block_show,               block_store);
+GDLM_ATTR(withdraw,            0644, withdraw_show,            withdraw_store);
+GDLM_ATTR(id,                  0444, lkid_show,                NULL);
+GDLM_ATTR(jid,                 0444, jid_show,                 NULL);
+GDLM_ATTR(first,               0444, lkfirst_show,             NULL);
+GDLM_ATTR(first_done,          0444, first_done_show,          NULL);
+GDLM_ATTR(recover,             0600, NULL,                     recover_store);
+GDLM_ATTR(recover_done,                0444, recover_done_show,        NULL);
+GDLM_ATTR(recover_status,      0444, recover_status_show,      NULL);
 
 static struct attribute *lock_module_attrs[] = {
        &gdlm_attr_proto_name.attr,
index 489fc01a3204e9d7b21b99bee47dcdded6fb38d0..e4e089a8f294343875f730b655a18f156b4839e3 100644 (file)
@@ -255,7 +255,7 @@ static void nfs_direct_read_release(void *calldata)
 
        if (put_dreq(dreq))
                nfs_direct_complete(dreq);
-       nfs_readdata_release(calldata);
+       nfs_readdata_free(data);
 }
 
 static const struct rpc_call_ops nfs_read_direct_ops = {
@@ -314,14 +314,14 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
                                        data->npages, 1, 0, data->pagevec, NULL);
                up_read(&current->mm->mmap_sem);
                if (result < 0) {
-                       nfs_readdata_release(data);
+                       nfs_readdata_free(data);
                        break;
                }
                if ((unsigned)result < data->npages) {
                        bytes = result * PAGE_SIZE;
                        if (bytes <= pgbase) {
                                nfs_direct_release_pages(data->pagevec, result);
-                               nfs_readdata_release(data);
+                               nfs_readdata_free(data);
                                break;
                        }
                        bytes -= pgbase;
@@ -334,7 +334,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
                data->inode = inode;
                data->cred = msg.rpc_cred;
                data->args.fh = NFS_FH(inode);
-               data->args.context = get_nfs_open_context(ctx);
+               data->args.context = ctx;
                data->args.offset = pos;
                data->args.pgbase = pgbase;
                data->args.pages = data->pagevec;
@@ -441,7 +441,7 @@ static void nfs_direct_free_writedata(struct nfs_direct_req *dreq)
                struct nfs_write_data *data = list_entry(dreq->rewrite_list.next, struct nfs_write_data, pages);
                list_del(&data->pages);
                nfs_direct_release_pages(data->pagevec, data->npages);
-               nfs_writedata_release(data);
+               nfs_writedata_free(data);
        }
 }
 
@@ -534,7 +534,7 @@ static void nfs_direct_commit_release(void *calldata)
 
        dprintk("NFS: %5u commit returned %d\n", data->task.tk_pid, status);
        nfs_direct_write_complete(dreq, data->inode);
-       nfs_commitdata_release(calldata);
+       nfs_commit_free(data);
 }
 
 static const struct rpc_call_ops nfs_commit_direct_ops = {
@@ -570,7 +570,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
        data->args.fh = NFS_FH(data->inode);
        data->args.offset = 0;
        data->args.count = 0;
-       data->args.context = get_nfs_open_context(dreq->ctx);
+       data->args.context = dreq->ctx;
        data->res.count = 0;
        data->res.fattr = &data->fattr;
        data->res.verf = &data->verf;
@@ -734,14 +734,14 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
                                        data->npages, 0, 0, data->pagevec, NULL);
                up_read(&current->mm->mmap_sem);
                if (result < 0) {
-                       nfs_writedata_release(data);
+                       nfs_writedata_free(data);
                        break;
                }
                if ((unsigned)result < data->npages) {
                        bytes = result * PAGE_SIZE;
                        if (bytes <= pgbase) {
                                nfs_direct_release_pages(data->pagevec, result);
-                               nfs_writedata_release(data);
+                               nfs_writedata_free(data);
                                break;
                        }
                        bytes -= pgbase;
@@ -756,7 +756,7 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
                data->inode = inode;
                data->cred = msg.rpc_cred;
                data->args.fh = NFS_FH(inode);
-               data->args.context = get_nfs_open_context(ctx);
+               data->args.context = ctx;
                data->args.offset = pos;
                data->args.pgbase = pgbase;
                data->args.pages = data->pagevec;
index 73ea5e8d66ceebbfab4079c4ab91b62809093ed7..12c9e66d3f1d9739147573ecd00cbc703f9f70a8 100644 (file)
@@ -60,17 +60,15 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
        return p;
 }
 
-static void nfs_readdata_free(struct nfs_read_data *p)
+void nfs_readdata_free(struct nfs_read_data *p)
 {
        if (p && (p->pagevec != &p->page_array[0]))
                kfree(p->pagevec);
        mempool_free(p, nfs_rdata_mempool);
 }
 
-void nfs_readdata_release(void *data)
+static void nfs_readdata_release(struct nfs_read_data *rdata)
 {
-       struct nfs_read_data *rdata = data;
-
        put_nfs_open_context(rdata->args.context);
        nfs_readdata_free(rdata);
 }
index 0a0a2ff767c318d5924c603a3f67ed7f5ccc9402..a34fae21fe109c8dc9fd8a90e8b8123b937d5ee3 100644 (file)
@@ -87,17 +87,15 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount)
        return p;
 }
 
-static void nfs_writedata_free(struct nfs_write_data *p)
+void nfs_writedata_free(struct nfs_write_data *p)
 {
        if (p && (p->pagevec != &p->page_array[0]))
                kfree(p->pagevec);
        mempool_free(p, nfs_wdata_mempool);
 }
 
-void nfs_writedata_release(void *data)
+static void nfs_writedata_release(struct nfs_write_data *wdata)
 {
-       struct nfs_write_data *wdata = data;
-
        put_nfs_open_context(wdata->args.context);
        nfs_writedata_free(wdata);
 }
index 9edcde4974aa22a37841d8b22aac86c7e435cea6..f9a3e8942669f436ad64fa00b550a46f34cd44be 100644 (file)
@@ -1914,7 +1914,8 @@ static void ocfs2_adjust_adjacent_records(struct ocfs2_extent_rec *left_rec,
         * immediately to their right.
         */
        left_clusters = le32_to_cpu(right_child_el->l_recs[0].e_cpos);
-       if (ocfs2_is_empty_extent(&right_child_el->l_recs[0])) {
+       if (!ocfs2_rec_clusters(right_child_el, &right_child_el->l_recs[0])) {
+               BUG_ON(right_child_el->l_tree_depth);
                BUG_ON(le16_to_cpu(right_child_el->l_next_free_rec) <= 1);
                left_clusters = le32_to_cpu(right_child_el->l_recs[1].e_cpos);
        }
@@ -2476,15 +2477,37 @@ out_ret_path:
        return ret;
 }
 
-static void ocfs2_update_edge_lengths(struct inode *inode, handle_t *handle,
-                                     struct ocfs2_path *path)
+static int ocfs2_update_edge_lengths(struct inode *inode, handle_t *handle,
+                                    int subtree_index, struct ocfs2_path *path)
 {
-       int i, idx;
+       int i, idx, ret;
        struct ocfs2_extent_rec *rec;
        struct ocfs2_extent_list *el;
        struct ocfs2_extent_block *eb;
        u32 range;
 
+       /*
+        * In normal tree rotation process, we will never touch the
+        * tree branch above subtree_index and ocfs2_extend_rotate_transaction
+        * doesn't reserve the credits for them either.
+        *
+        * But we do have a special case here which will update the rightmost
+        * records for all the bh in the path.
+        * So we have to allocate extra credits and access them.
+        */
+       ret = ocfs2_extend_trans(handle,
+                                handle->h_buffer_credits + subtree_index);
+       if (ret) {
+               mlog_errno(ret);
+               goto out;
+       }
+
+       ret = ocfs2_journal_access_path(inode, handle, path);
+       if (ret) {
+               mlog_errno(ret);
+               goto out;
+       }
+
        /* Path should always be rightmost. */
        eb = (struct ocfs2_extent_block *)path_leaf_bh(path)->b_data;
        BUG_ON(eb->h_next_leaf_blk != 0ULL);
@@ -2505,6 +2528,8 @@ static void ocfs2_update_edge_lengths(struct inode *inode, handle_t *handle,
 
                ocfs2_journal_dirty(handle, path->p_node[i].bh);
        }
+out:
+       return ret;
 }
 
 static void ocfs2_unlink_path(struct inode *inode, handle_t *handle,
@@ -2717,7 +2742,12 @@ static int ocfs2_rotate_subtree_left(struct inode *inode, handle_t *handle,
        if (del_right_subtree) {
                ocfs2_unlink_subtree(inode, handle, left_path, right_path,
                                     subtree_index, dealloc);
-               ocfs2_update_edge_lengths(inode, handle, left_path);
+               ret = ocfs2_update_edge_lengths(inode, handle, subtree_index,
+                                               left_path);
+               if (ret) {
+                       mlog_errno(ret);
+                       goto out;
+               }
 
                eb = (struct ocfs2_extent_block *)path_leaf_bh(left_path)->b_data;
                ocfs2_et_set_last_eb_blk(et, le64_to_cpu(eb->h_blkno));
@@ -3034,7 +3064,12 @@ static int ocfs2_remove_rightmost_path(struct inode *inode, handle_t *handle,
 
                ocfs2_unlink_subtree(inode, handle, left_path, path,
                                     subtree_index, dealloc);
-               ocfs2_update_edge_lengths(inode, handle, left_path);
+               ret = ocfs2_update_edge_lengths(inode, handle, subtree_index,
+                                               left_path);
+               if (ret) {
+                       mlog_errno(ret);
+                       goto out;
+               }
 
                eb = (struct ocfs2_extent_block *)path_leaf_bh(left_path)->b_data;
                ocfs2_et_set_last_eb_blk(et, le64_to_cpu(eb->h_blkno));
index b2c52b3a1484f1c57c4b098bf9706fe21c186ac0..b401654011a2b64c4e55f87c7916e3badc07f68e 100644 (file)
@@ -193,6 +193,7 @@ static int ocfs2_get_block(struct inode *inode, sector_t iblock,
                             (unsigned long long)OCFS2_I(inode)->ip_blkno);
                        mlog(ML_ERROR, "Size %llu, clusters %u\n", (unsigned long long)i_size_read(inode), OCFS2_I(inode)->ip_clusters);
                        dump_stack();
+                       goto bail;
                }
 
                past_eof = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
@@ -894,18 +895,17 @@ struct ocfs2_write_cluster_desc {
         */
        unsigned        c_new;
        unsigned        c_unwritten;
+       unsigned        c_needs_zero;
 };
 
-static inline int ocfs2_should_zero_cluster(struct ocfs2_write_cluster_desc *d)
-{
-       return d->c_new || d->c_unwritten;
-}
-
 struct ocfs2_write_ctxt {
        /* Logical cluster position / len of write */
        u32                             w_cpos;
        u32                             w_clen;
 
+       /* First cluster allocated in a nonsparse extend */
+       u32                             w_first_new_cpos;
+
        struct ocfs2_write_cluster_desc w_desc[OCFS2_MAX_CLUSTERS_PER_PAGE];
 
        /*
@@ -983,6 +983,7 @@ static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp,
                return -ENOMEM;
 
        wc->w_cpos = pos >> osb->s_clustersize_bits;
+       wc->w_first_new_cpos = UINT_MAX;
        cend = (pos + len - 1) >> osb->s_clustersize_bits;
        wc->w_clen = cend - wc->w_cpos + 1;
        get_bh(di_bh);
@@ -1217,20 +1218,18 @@ out:
  */
 static int ocfs2_write_cluster(struct address_space *mapping,
                               u32 phys, unsigned int unwritten,
+                              unsigned int should_zero,
                               struct ocfs2_alloc_context *data_ac,
                               struct ocfs2_alloc_context *meta_ac,
                               struct ocfs2_write_ctxt *wc, u32 cpos,
                               loff_t user_pos, unsigned user_len)
 {
-       int ret, i, new, should_zero = 0;
+       int ret, i, new;
        u64 v_blkno, p_blkno;
        struct inode *inode = mapping->host;
        struct ocfs2_extent_tree et;
 
        new = phys == 0 ? 1 : 0;
-       if (new || unwritten)
-               should_zero = 1;
-
        if (new) {
                u32 tmp_pos;
 
@@ -1301,7 +1300,7 @@ static int ocfs2_write_cluster(struct address_space *mapping,
                if (tmpret) {
                        mlog_errno(tmpret);
                        if (ret == 0)
-                               tmpret = ret;
+                               ret = tmpret;
                }
        }
 
@@ -1341,7 +1340,9 @@ static int ocfs2_write_cluster_by_desc(struct address_space *mapping,
                        local_len = osb->s_clustersize - cluster_off;
 
                ret = ocfs2_write_cluster(mapping, desc->c_phys,
-                                         desc->c_unwritten, data_ac, meta_ac,
+                                         desc->c_unwritten,
+                                         desc->c_needs_zero,
+                                         data_ac, meta_ac,
                                          wc, desc->c_cpos, pos, local_len);
                if (ret) {
                        mlog_errno(ret);
@@ -1391,14 +1392,14 @@ static void ocfs2_set_target_boundaries(struct ocfs2_super *osb,
                 * newly allocated cluster.
                 */
                desc = &wc->w_desc[0];
-               if (ocfs2_should_zero_cluster(desc))
+               if (desc->c_needs_zero)
                        ocfs2_figure_cluster_boundaries(osb,
                                                        desc->c_cpos,
                                                        &wc->w_target_from,
                                                        NULL);
 
                desc = &wc->w_desc[wc->w_clen - 1];
-               if (ocfs2_should_zero_cluster(desc))
+               if (desc->c_needs_zero)
                        ocfs2_figure_cluster_boundaries(osb,
                                                        desc->c_cpos,
                                                        NULL,
@@ -1466,13 +1467,28 @@ static int ocfs2_populate_write_desc(struct inode *inode,
                        phys++;
                }
 
+               /*
+                * If w_first_new_cpos is < UINT_MAX, we have a non-sparse
+                * file that got extended.  w_first_new_cpos tells us
+                * where the newly allocated clusters are so we can
+                * zero them.
+                */
+               if (desc->c_cpos >= wc->w_first_new_cpos) {
+                       BUG_ON(phys == 0);
+                       desc->c_needs_zero = 1;
+               }
+
                desc->c_phys = phys;
                if (phys == 0) {
                        desc->c_new = 1;
+                       desc->c_needs_zero = 1;
                        *clusters_to_alloc = *clusters_to_alloc + 1;
                }
-               if (ext_flags & OCFS2_EXT_UNWRITTEN)
+
+               if (ext_flags & OCFS2_EXT_UNWRITTEN) {
                        desc->c_unwritten = 1;
+                       desc->c_needs_zero = 1;
+               }
 
                num_clusters--;
        }
@@ -1632,10 +1648,13 @@ static int ocfs2_expand_nonsparse_inode(struct inode *inode, loff_t pos,
        if (newsize <= i_size_read(inode))
                return 0;
 
-       ret = ocfs2_extend_no_holes(inode, newsize, newsize - len);
+       ret = ocfs2_extend_no_holes(inode, newsize, pos);
        if (ret)
                mlog_errno(ret);
 
+       wc->w_first_new_cpos =
+               ocfs2_clusters_for_bytes(inode->i_sb, i_size_read(inode));
+
        return ret;
 }
 
@@ -1644,7 +1663,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
                             struct page **pagep, void **fsdata,
                             struct buffer_head *di_bh, struct page *mmap_page)
 {
-       int ret, credits = OCFS2_INODE_UPDATE_CREDITS;
+       int ret, cluster_of_pages, credits = OCFS2_INODE_UPDATE_CREDITS;
        unsigned int clusters_to_alloc, extents_to_split;
        struct ocfs2_write_ctxt *wc;
        struct inode *inode = mapping->host;
@@ -1722,8 +1741,19 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
 
        }
 
-       ocfs2_set_target_boundaries(osb, wc, pos, len,
-                                   clusters_to_alloc + extents_to_split);
+       /*
+        * We have to zero sparse allocated clusters, unwritten extent clusters,
+        * and non-sparse clusters we just extended.  For non-sparse writes,
+        * 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)
+               cluster_of_pages = 1;
+       else
+               cluster_of_pages = 0;
+
+       ocfs2_set_target_boundaries(osb, wc, pos, len, cluster_of_pages);
 
        handle = ocfs2_start_trans(osb, credits);
        if (IS_ERR(handle)) {
@@ -1756,8 +1786,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
         * extent.
         */
        ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos,
-                                        clusters_to_alloc + extents_to_split,
-                                        mmap_page);
+                                        cluster_of_pages, mmap_page);
        if (ret) {
                mlog_errno(ret);
                goto out_quota;
index b574431a031d5cd9721de53c46a80825f752bb9d..2f28b7de2c8d2cae30d052e54fc12fa7e91c740f 100644 (file)
@@ -310,22 +310,19 @@ out_attach:
        return ret;
 }
 
-static DEFINE_SPINLOCK(dentry_list_lock);
+DEFINE_SPINLOCK(dentry_list_lock);
 
 /* We limit the number of dentry locks to drop in one go. We have
  * this limit so that we don't starve other users of ocfs2_wq. */
 #define DL_INODE_DROP_COUNT 64
 
 /* Drop inode references from dentry locks */
-void ocfs2_drop_dl_inodes(struct work_struct *work)
+static void __ocfs2_drop_dl_inodes(struct ocfs2_super *osb, int drop_count)
 {
-       struct ocfs2_super *osb = container_of(work, struct ocfs2_super,
-                                              dentry_lock_work);
        struct ocfs2_dentry_lock *dl;
-       int drop_count = DL_INODE_DROP_COUNT;
 
        spin_lock(&dentry_list_lock);
-       while (osb->dentry_lock_list && drop_count--) {
+       while (osb->dentry_lock_list && (drop_count < 0 || drop_count--)) {
                dl = osb->dentry_lock_list;
                osb->dentry_lock_list = dl->dl_next;
                spin_unlock(&dentry_list_lock);
@@ -333,11 +330,32 @@ void ocfs2_drop_dl_inodes(struct work_struct *work)
                kfree(dl);
                spin_lock(&dentry_list_lock);
        }
-       if (osb->dentry_lock_list)
+       spin_unlock(&dentry_list_lock);
+}
+
+void ocfs2_drop_dl_inodes(struct work_struct *work)
+{
+       struct ocfs2_super *osb = container_of(work, struct ocfs2_super,
+                                              dentry_lock_work);
+
+       __ocfs2_drop_dl_inodes(osb, DL_INODE_DROP_COUNT);
+       /*
+        * Don't queue dropping if umount is in progress. We flush the
+        * list in ocfs2_dismount_volume
+        */
+       spin_lock(&dentry_list_lock);
+       if (osb->dentry_lock_list &&
+           !ocfs2_test_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED))
                queue_work(ocfs2_wq, &osb->dentry_lock_work);
        spin_unlock(&dentry_list_lock);
 }
 
+/* Flush the whole work queue */
+void ocfs2_drop_all_dl_inodes(struct ocfs2_super *osb)
+{
+       __ocfs2_drop_dl_inodes(osb, -1);
+}
+
 /*
  * ocfs2_dentry_iput() and friends.
  *
@@ -368,7 +386,8 @@ static void ocfs2_drop_dentry_lock(struct ocfs2_super *osb,
        /* We leave dropping of inode reference to ocfs2_wq as that can
         * possibly lead to inode deletion which gets tricky */
        spin_lock(&dentry_list_lock);
-       if (!osb->dentry_lock_list)
+       if (!osb->dentry_lock_list &&
+           !ocfs2_test_osb_flag(osb, OCFS2_OSB_DROP_DENTRY_LOCK_IMMED))
                queue_work(ocfs2_wq, &osb->dentry_lock_work);
        dl->dl_next = osb->dentry_lock_list;
        osb->dentry_lock_list = dl;
index faa12e75f98d117a9cf2f7f0bf519a05b83c5401..f5dd1789acf1b4527373217ce7c6b0374695eb17 100644 (file)
@@ -49,10 +49,13 @@ struct ocfs2_dentry_lock {
 int ocfs2_dentry_attach_lock(struct dentry *dentry, struct inode *inode,
                             u64 parent_blkno);
 
+extern spinlock_t dentry_list_lock;
+
 void ocfs2_dentry_lock_put(struct ocfs2_super *osb,
                           struct ocfs2_dentry_lock *dl);
 
 void ocfs2_drop_dl_inodes(struct work_struct *work);
+void ocfs2_drop_all_dl_inodes(struct ocfs2_super *osb);
 
 struct dentry *ocfs2_find_local_alias(struct inode *inode, u64 parent_blkno,
                                      int skip_unhashed);
index d07ddbe4b2836d3e3e6d0f002808d8c36ef6c591..81eff8e583222747cc824ce02d6edde94378e711 100644 (file)
@@ -103,7 +103,6 @@ static void __dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock)
                     lock->ast_pending, lock->ml.type);
                BUG();
        }
-       BUG_ON(!list_empty(&lock->ast_list));
        if (lock->ast_pending)
                mlog(0, "lock has an ast getting flushed right now\n");
 
index bcb9260c37359a832c601f0c00e718094063af25..43e6e328056902a0fdd8cb98c7961b76a912c3dd 100644 (file)
@@ -1118,7 +1118,7 @@ static int dlm_send_mig_lockres_msg(struct dlm_ctxt *dlm,
 
        mlog(0, "%s:%.*s: sending mig lockres (%s) to %u\n",
             dlm->name, res->lockname.len, res->lockname.name,
-            orig_flags & DLM_MRES_MIGRATION ? "migrate" : "recovery",
+            orig_flags & DLM_MRES_MIGRATION ? "migration" : "recovery",
             send_to);
 
        /* send it */
index 62442e413a001cfbe57607c43e06d408418cf13e..aa501d3f93f1bcec3af38a24361ab61cda2cc052 100644 (file)
@@ -1851,6 +1851,7 @@ relock:
                if (ret)
                        goto out_dio;
 
+               count = ocount;
                ret = generic_write_checks(file, ppos, &count,
                                           S_ISBLK(inode->i_mode));
                if (ret)
@@ -1918,8 +1919,10 @@ out_sems:
 
        mutex_unlock(&inode->i_mutex);
 
+       if (written)
+               ret = written;
        mlog_exit(ret);
-       return written ? written : ret;
+       return ret;
 }
 
 static int ocfs2_splice_to_file(struct pipe_inode_info *pipe,
index f033760ecbeaae0dde0944d190828aedb7b9c5d0..c48b93ac6b65c55bc2b90daf8b3efa1397b9b6e4 100644 (file)
@@ -1954,10 +1954,16 @@ void ocfs2_orphan_scan_init(struct ocfs2_super *osb)
        os->os_osb = osb;
        os->os_count = 0;
        os->os_seqno = 0;
-       os->os_scantime = CURRENT_TIME;
        mutex_init(&os->os_lock);
        INIT_DELAYED_WORK(&os->os_orphan_scan_work, ocfs2_orphan_scan_work);
+}
 
+void ocfs2_orphan_scan_start(struct ocfs2_super *osb)
+{
+       struct ocfs2_orphan_scan *os;
+
+       os = &osb->osb_orphan_scan;
+       os->os_scantime = CURRENT_TIME;
        if (ocfs2_is_hard_readonly(osb) || ocfs2_mount_local(osb))
                atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE);
        else {
index 5432c7f79cc6a959d3c39cd2cbcb41663ef599b5..2c3222aec6228a83b9acac2122e42beea94042fb 100644 (file)
@@ -145,6 +145,7 @@ static inline void ocfs2_inode_set_new(struct ocfs2_super *osb,
 
 /* Exported only for the journal struct init code in super.c. Do not call. */
 void ocfs2_orphan_scan_init(struct ocfs2_super *osb);
+void ocfs2_orphan_scan_start(struct ocfs2_super *osb);
 void ocfs2_orphan_scan_stop(struct ocfs2_super *osb);
 void ocfs2_orphan_scan_exit(struct ocfs2_super *osb);
 
@@ -329,20 +330,27 @@ int                  ocfs2_journal_dirty(handle_t *handle,
 /* extended attribute block update */
 #define OCFS2_XATTR_BLOCK_UPDATE_CREDITS 1
 
+/* Update of a single quota block */
+#define OCFS2_QUOTA_BLOCK_UPDATE_CREDITS 1
+
 /* global quotafile inode update, data block */
-#define OCFS2_QINFO_WRITE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 1)
+#define OCFS2_QINFO_WRITE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + \
+                                  OCFS2_QUOTA_BLOCK_UPDATE_CREDITS)
 
+#define OCFS2_LOCAL_QINFO_WRITE_CREDITS OCFS2_QUOTA_BLOCK_UPDATE_CREDITS
 /*
  * The two writes below can accidentally see global info dirty due
  * to set_info() quotactl so make them prepared for the writes.
  */
 /* quota data block, global info */
 /* Write to local quota file */
-#define OCFS2_QWRITE_CREDITS (OCFS2_QINFO_WRITE_CREDITS + 1)
+#define OCFS2_QWRITE_CREDITS (OCFS2_QINFO_WRITE_CREDITS + \
+                             OCFS2_QUOTA_BLOCK_UPDATE_CREDITS)
 
 /* global quota data block, local quota data block, global quota inode,
  * global quota info */
-#define OCFS2_QSYNC_CREDITS (OCFS2_INODE_UPDATE_CREDITS + 3)
+#define OCFS2_QSYNC_CREDITS (OCFS2_QINFO_WRITE_CREDITS + \
+                            2 * OCFS2_QUOTA_BLOCK_UPDATE_CREDITS)
 
 static inline int ocfs2_quota_trans_credits(struct super_block *sb)
 {
@@ -355,11 +363,6 @@ static inline int ocfs2_quota_trans_credits(struct super_block *sb)
        return credits;
 }
 
-/* Number of credits needed for removing quota structure from file */
-int ocfs2_calc_qdel_credits(struct super_block *sb, int type);
-/* Number of credits needed for initialization of new quota structure */
-int ocfs2_calc_qinit_credits(struct super_block *sb, int type);
-
 /* group extend. inode update and last group update. */
 #define OCFS2_GROUP_EXTEND_CREDITS     (OCFS2_INODE_UPDATE_CREDITS + 1)
 
index c9345ebb849343873adf6b2b67ae226f8181f65e..39e1d5a39505221a458846ab37950c922d6da76b 100644 (file)
@@ -224,10 +224,12 @@ enum ocfs2_mount_options
        OCFS2_MOUNT_GRPQUOTA = 1 << 10, /* We support group quotas */
 };
 
-#define OCFS2_OSB_SOFT_RO      0x0001
-#define OCFS2_OSB_HARD_RO      0x0002
-#define OCFS2_OSB_ERROR_FS     0x0004
-#define OCFS2_DEFAULT_ATIME_QUANTUM    60
+#define OCFS2_OSB_SOFT_RO                      0x0001
+#define OCFS2_OSB_HARD_RO                      0x0002
+#define OCFS2_OSB_ERROR_FS                     0x0004
+#define OCFS2_OSB_DROP_DENTRY_LOCK_IMMED       0x0008
+
+#define OCFS2_DEFAULT_ATIME_QUANTUM            60
 
 struct ocfs2_journal;
 struct ocfs2_slot_info;
@@ -490,6 +492,18 @@ static inline void ocfs2_set_osb_flag(struct ocfs2_super *osb,
        spin_unlock(&osb->osb_lock);
 }
 
+
+static inline unsigned long  ocfs2_test_osb_flag(struct ocfs2_super *osb,
+                                                unsigned long flag)
+{
+       unsigned long ret;
+
+       spin_lock(&osb->osb_lock);
+       ret = osb->osb_flags & flag;
+       spin_unlock(&osb->osb_lock);
+       return ret;
+}
+
 static inline void ocfs2_set_ro_flag(struct ocfs2_super *osb,
                                     int hard)
 {
index 7365e2e08706ef6ea07b5f034310f5fec6fd9e4a..3fb96fcd4c81cd185db0e7b5132f831c322dedca 100644 (file)
@@ -50,7 +50,6 @@ struct ocfs2_mem_dqinfo {
        unsigned int dqi_chunks;        /* Number of chunks in local quota file */
        unsigned int dqi_blocks;        /* Number of blocks allocated for local quota file */
        unsigned int dqi_syncms;        /* How often should we sync with other nodes */
-       unsigned int dqi_syncjiff;      /* Precomputed dqi_syncms in jiffies */
        struct list_head dqi_chunk;     /* List of chunks */
        struct inode *dqi_gqinode;      /* Global quota file inode */
        struct ocfs2_lock_res dqi_gqlock;       /* Lock protecting quota information structure */
index edfa60cd155c18e9ac67a1fe6ae1476900fed8b7..bf7742d0ee3bba05a7ceabab948aff62f27482f0 100644 (file)
@@ -69,6 +69,7 @@ static void ocfs2_global_mem2diskdqb(void *dp, struct dquot *dquot)
        d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
        d->dqb_btime = cpu_to_le64(m->dqb_btime);
        d->dqb_itime = cpu_to_le64(m->dqb_itime);
+       d->dqb_pad1 = d->dqb_pad2 = 0;
 }
 
 static int ocfs2_global_is_id(void *dp, struct dquot *dquot)
@@ -211,14 +212,13 @@ ssize_t ocfs2_quota_write(struct super_block *sb, int type,
 
        mutex_lock_nested(&gqinode->i_mutex, I_MUTEX_QUOTA);
        if (gqinode->i_size < off + len) {
-               down_write(&OCFS2_I(gqinode)->ip_alloc_sem);
-               err = ocfs2_extend_no_holes(gqinode, off + len, off);
-               up_write(&OCFS2_I(gqinode)->ip_alloc_sem);
-               if (err < 0)
-                       goto out;
+               loff_t rounded_end =
+                               ocfs2_align_bytes_to_blocks(sb, off + len);
+
+               /* Space is already allocated in ocfs2_global_read_dquot() */
                err = ocfs2_simple_size_update(gqinode,
                                               oinfo->dqi_gqi_bh,
-                                              off + len);
+                                              rounded_end);
                if (err < 0)
                        goto out;
                new = 1;
@@ -234,7 +234,7 @@ ssize_t ocfs2_quota_write(struct super_block *sb, int type,
        }
        if (err) {
                mlog_errno(err);
-               return err;
+               goto out;
        }
        lock_buffer(bh);
        if (new)
@@ -342,7 +342,6 @@ int ocfs2_global_read_info(struct super_block *sb, int type)
        info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
        info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);
        oinfo->dqi_syncms = le32_to_cpu(dinfo.dqi_syncms);
-       oinfo->dqi_syncjiff = msecs_to_jiffies(oinfo->dqi_syncms);
        oinfo->dqi_gi.dqi_blocks = le32_to_cpu(dinfo.dqi_blocks);
        oinfo->dqi_gi.dqi_free_blk = le32_to_cpu(dinfo.dqi_free_blk);
        oinfo->dqi_gi.dqi_free_entry = le32_to_cpu(dinfo.dqi_free_entry);
@@ -352,7 +351,7 @@ int ocfs2_global_read_info(struct super_block *sb, int type)
        oinfo->dqi_gi.dqi_qtree_depth = qtree_depth(&oinfo->dqi_gi);
        INIT_DELAYED_WORK(&oinfo->dqi_sync_work, qsync_work_fn);
        queue_delayed_work(ocfs2_quota_wq, &oinfo->dqi_sync_work,
-                          oinfo->dqi_syncjiff);
+                          msecs_to_jiffies(oinfo->dqi_syncms));
 
 out_err:
        mlog_exit(status);
@@ -402,13 +401,36 @@ int ocfs2_global_write_info(struct super_block *sb, int type)
        return err;
 }
 
+static int ocfs2_global_qinit_alloc(struct super_block *sb, int type)
+{
+       struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;
+
+       /*
+        * We may need to allocate tree blocks and a leaf block but not the
+        * root block
+        */
+       return oinfo->dqi_gi.dqi_qtree_depth;
+}
+
+static int ocfs2_calc_global_qinit_credits(struct super_block *sb, int type)
+{
+       /* We modify all the allocated blocks, tree root, and info block */
+       return (ocfs2_global_qinit_alloc(sb, type) + 2) *
+                       OCFS2_QUOTA_BLOCK_UPDATE_CREDITS;
+}
+
 /* Read in information from global quota file and acquire a reference to it.
  * dquot_acquire() has already started the transaction and locked quota file */
 int ocfs2_global_read_dquot(struct dquot *dquot)
 {
        int err, err2, ex = 0;
-       struct ocfs2_mem_dqinfo *info =
-                       sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv;
+       struct super_block *sb = dquot->dq_sb;
+       int type = dquot->dq_type;
+       struct ocfs2_mem_dqinfo *info = sb_dqinfo(sb, type)->dqi_priv;
+       struct ocfs2_super *osb = OCFS2_SB(sb);
+       struct inode *gqinode = info->dqi_gqinode;
+       int need_alloc = ocfs2_global_qinit_alloc(sb, type);
+       handle_t *handle = NULL;
 
        err = ocfs2_qinfo_lock(info, 0);
        if (err < 0)
@@ -419,14 +441,33 @@ int ocfs2_global_read_dquot(struct dquot *dquot)
        OCFS2_DQUOT(dquot)->dq_use_count++;
        OCFS2_DQUOT(dquot)->dq_origspace = dquot->dq_dqb.dqb_curspace;
        OCFS2_DQUOT(dquot)->dq_originodes = dquot->dq_dqb.dqb_curinodes;
+       ocfs2_qinfo_unlock(info, 0);
+
        if (!dquot->dq_off) {   /* No real quota entry? */
-               /* Upgrade to exclusive lock for allocation */
-               ocfs2_qinfo_unlock(info, 0);
-               err = ocfs2_qinfo_lock(info, 1);
-               if (err < 0)
-                       goto out_qlock;
                ex = 1;
+               /*
+                * Add blocks to quota file before we start a transaction since
+                * locking allocators ranks above a transaction start
+                */
+               WARN_ON(journal_current_handle());
+               down_write(&OCFS2_I(gqinode)->ip_alloc_sem);
+               err = ocfs2_extend_no_holes(gqinode,
+                       gqinode->i_size + (need_alloc << sb->s_blocksize_bits),
+                       gqinode->i_size);
+               up_write(&OCFS2_I(gqinode)->ip_alloc_sem);
+               if (err < 0)
+                       goto out;
        }
+
+       handle = ocfs2_start_trans(osb,
+                                  ocfs2_calc_global_qinit_credits(sb, type));
+       if (IS_ERR(handle)) {
+               err = PTR_ERR(handle);
+               goto out;
+       }
+       err = ocfs2_qinfo_lock(info, ex);
+       if (err < 0)
+               goto out_trans;
        err = qtree_write_dquot(&info->dqi_gi, dquot);
        if (ex && info_dirty(sb_dqinfo(dquot->dq_sb, dquot->dq_type))) {
                err2 = __ocfs2_global_write_info(dquot->dq_sb, dquot->dq_type);
@@ -438,6 +479,9 @@ out_qlock:
                ocfs2_qinfo_unlock(info, 1);
        else
                ocfs2_qinfo_unlock(info, 0);
+out_trans:
+       if (handle)
+               ocfs2_commit_trans(osb, handle);
 out:
        if (err < 0)
                mlog_errno(err);
@@ -607,7 +651,7 @@ static void qsync_work_fn(struct work_struct *work)
 
        dquot_scan_active(sb, ocfs2_sync_dquot_helper, oinfo->dqi_type);
        queue_delayed_work(ocfs2_quota_wq, &oinfo->dqi_sync_work,
-                          oinfo->dqi_syncjiff);
+                          msecs_to_jiffies(oinfo->dqi_syncms));
 }
 
 /*
@@ -635,20 +679,18 @@ out:
        return status;
 }
 
-int ocfs2_calc_qdel_credits(struct super_block *sb, int type)
+static int ocfs2_calc_qdel_credits(struct super_block *sb, int type)
 {
-       struct ocfs2_mem_dqinfo *oinfo;
-       int features[MAXQUOTAS] = { OCFS2_FEATURE_RO_COMPAT_USRQUOTA,
-                                   OCFS2_FEATURE_RO_COMPAT_GRPQUOTA };
-
-       if (!OCFS2_HAS_RO_COMPAT_FEATURE(sb, features[type]))
-               return 0;
-
-       oinfo = sb_dqinfo(sb, type)->dqi_priv;
-       /* We modify tree, leaf block, global info, local chunk header,
-        * global and local inode */
-       return oinfo->dqi_gi.dqi_qtree_depth + 2 + 1 +
-              2 * OCFS2_INODE_UPDATE_CREDITS;
+       struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;
+       /*
+        * We modify tree, leaf block, global info, local chunk header,
+        * global and local inode; OCFS2_QINFO_WRITE_CREDITS already
+        * accounts for inode update
+        */
+       return (oinfo->dqi_gi.dqi_qtree_depth + 2) *
+              OCFS2_QUOTA_BLOCK_UPDATE_CREDITS +
+              OCFS2_QINFO_WRITE_CREDITS +
+              OCFS2_INODE_UPDATE_CREDITS;
 }
 
 static int ocfs2_release_dquot(struct dquot *dquot)
@@ -680,33 +722,10 @@ out:
        return status;
 }
 
-int ocfs2_calc_qinit_credits(struct super_block *sb, int type)
-{
-       struct ocfs2_mem_dqinfo *oinfo;
-       int features[MAXQUOTAS] = { OCFS2_FEATURE_RO_COMPAT_USRQUOTA,
-                                   OCFS2_FEATURE_RO_COMPAT_GRPQUOTA };
-       struct ocfs2_dinode *lfe, *gfe;
-
-       if (!OCFS2_HAS_RO_COMPAT_FEATURE(sb, features[type]))
-               return 0;
-
-       oinfo = sb_dqinfo(sb, type)->dqi_priv;
-       gfe = (struct ocfs2_dinode *)oinfo->dqi_gqi_bh->b_data;
-       lfe = (struct ocfs2_dinode *)oinfo->dqi_lqi_bh->b_data;
-       /* We can extend local file + global file. In local file we
-        * can modify info, chunk header block and dquot block. In
-        * global file we can modify info, tree and leaf block */
-       return ocfs2_calc_extend_credits(sb, &lfe->id2.i_list, 0) +
-              ocfs2_calc_extend_credits(sb, &gfe->id2.i_list, 0) +
-              3 + oinfo->dqi_gi.dqi_qtree_depth + 2;
-}
-
 static int ocfs2_acquire_dquot(struct dquot *dquot)
 {
-       handle_t *handle;
        struct ocfs2_mem_dqinfo *oinfo =
                        sb_dqinfo(dquot->dq_sb, dquot->dq_type)->dqi_priv;
-       struct ocfs2_super *osb = OCFS2_SB(dquot->dq_sb);
        int status = 0;
 
        mlog_entry("id=%u, type=%d", dquot->dq_id, dquot->dq_type);
@@ -715,16 +734,7 @@ static int ocfs2_acquire_dquot(struct dquot *dquot)
        status = ocfs2_lock_global_qf(oinfo, 1);
        if (status < 0)
                goto out;
-       handle = ocfs2_start_trans(osb,
-               ocfs2_calc_qinit_credits(dquot->dq_sb, dquot->dq_type));
-       if (IS_ERR(handle)) {
-               status = PTR_ERR(handle);
-               mlog_errno(status);
-               goto out_ilock;
-       }
        status = dquot_acquire(dquot);
-       ocfs2_commit_trans(osb, handle);
-out_ilock:
        ocfs2_unlock_global_qf(oinfo, 1);
 out:
        mlog_exit(status);
index 5a460fa8255384f615d2dd7ca8836d3091fc58b5..bdb09cb6e1fef216821b7e7a8d94503ce7d097fd 100644 (file)
@@ -20,6 +20,7 @@
 #include "sysfile.h"
 #include "dlmglue.h"
 #include "quota.h"
+#include "uptodate.h"
 
 /* Number of local quota structures per block */
 static inline unsigned int ol_quota_entries_per_block(struct super_block *sb)
@@ -100,7 +101,8 @@ static int ocfs2_modify_bh(struct inode *inode, struct buffer_head *bh,
        handle_t *handle;
        int status;
 
-       handle = ocfs2_start_trans(OCFS2_SB(sb), 1);
+       handle = ocfs2_start_trans(OCFS2_SB(sb),
+                                  OCFS2_QUOTA_BLOCK_UPDATE_CREDITS);
        if (IS_ERR(handle)) {
                status = PTR_ERR(handle);
                mlog_errno(status);
@@ -610,7 +612,8 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
                        goto out_bh;
                /* Mark quota file as clean if we are recovering quota file of
                 * some other node. */
-               handle = ocfs2_start_trans(osb, 1);
+               handle = ocfs2_start_trans(osb,
+                                          OCFS2_LOCAL_QINFO_WRITE_CREDITS);
                if (IS_ERR(handle)) {
                        status = PTR_ERR(handle);
                        mlog_errno(status);
@@ -940,7 +943,7 @@ static struct ocfs2_quota_chunk *ocfs2_local_quota_add_chunk(
        struct ocfs2_local_disk_chunk *dchunk;
        int status;
        handle_t *handle;
-       struct buffer_head *bh = NULL;
+       struct buffer_head *bh = NULL, *dbh = NULL;
        u64 p_blkno;
 
        /* We are protected by dqio_sem so no locking needed */
@@ -964,32 +967,35 @@ static struct ocfs2_quota_chunk *ocfs2_local_quota_add_chunk(
                mlog_errno(status);
                goto out;
        }
+       /* Local quota info and two new blocks we initialize */
+       handle = ocfs2_start_trans(OCFS2_SB(sb),
+                       OCFS2_LOCAL_QINFO_WRITE_CREDITS +
+                       2 * OCFS2_QUOTA_BLOCK_UPDATE_CREDITS);
+       if (IS_ERR(handle)) {
+               status = PTR_ERR(handle);
+               mlog_errno(status);
+               goto out;
+       }
 
+       /* Initialize chunk header */
        down_read(&OCFS2_I(lqinode)->ip_alloc_sem);
        status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks,
                                             &p_blkno, NULL, NULL);
        up_read(&OCFS2_I(lqinode)->ip_alloc_sem);
        if (status < 0) {
                mlog_errno(status);
-               goto out;
+               goto out_trans;
        }
        bh = sb_getblk(sb, p_blkno);
        if (!bh) {
                status = -ENOMEM;
                mlog_errno(status);
-               goto out;
+               goto out_trans;
        }
        dchunk = (struct ocfs2_local_disk_chunk *)bh->b_data;
-
-       handle = ocfs2_start_trans(OCFS2_SB(sb), 2);
-       if (IS_ERR(handle)) {
-               status = PTR_ERR(handle);
-               mlog_errno(status);
-               goto out;
-       }
-
+       ocfs2_set_new_buffer_uptodate(lqinode, bh);
        status = ocfs2_journal_access_dq(handle, lqinode, bh,
-                                        OCFS2_JOURNAL_ACCESS_WRITE);
+                                        OCFS2_JOURNAL_ACCESS_CREATE);
        if (status < 0) {
                mlog_errno(status);
                goto out_trans;
@@ -999,7 +1005,6 @@ static struct ocfs2_quota_chunk *ocfs2_local_quota_add_chunk(
        memset(dchunk->dqc_bitmap, 0,
               sb->s_blocksize - sizeof(struct ocfs2_local_disk_chunk) -
               OCFS2_QBLK_RESERVED_SPACE);
-       set_buffer_uptodate(bh);
        unlock_buffer(bh);
        status = ocfs2_journal_dirty(handle, bh);
        if (status < 0) {
@@ -1007,6 +1012,38 @@ static struct ocfs2_quota_chunk *ocfs2_local_quota_add_chunk(
                goto out_trans;
        }
 
+       /* Initialize new block with structures */
+       down_read(&OCFS2_I(lqinode)->ip_alloc_sem);
+       status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks + 1,
+                                            &p_blkno, NULL, NULL);
+       up_read(&OCFS2_I(lqinode)->ip_alloc_sem);
+       if (status < 0) {
+               mlog_errno(status);
+               goto out_trans;
+       }
+       dbh = sb_getblk(sb, p_blkno);
+       if (!dbh) {
+               status = -ENOMEM;
+               mlog_errno(status);
+               goto out_trans;
+       }
+       ocfs2_set_new_buffer_uptodate(lqinode, dbh);
+       status = ocfs2_journal_access_dq(handle, lqinode, dbh,
+                                        OCFS2_JOURNAL_ACCESS_CREATE);
+       if (status < 0) {
+               mlog_errno(status);
+               goto out_trans;
+       }
+       lock_buffer(dbh);
+       memset(dbh->b_data, 0, sb->s_blocksize - OCFS2_QBLK_RESERVED_SPACE);
+       unlock_buffer(dbh);
+       status = ocfs2_journal_dirty(handle, dbh);
+       if (status < 0) {
+               mlog_errno(status);
+               goto out_trans;
+       }
+
+       /* Update local quotafile info */
        oinfo->dqi_blocks += 2;
        oinfo->dqi_chunks++;
        status = ocfs2_local_write_info(sb, type);
@@ -1031,6 +1068,7 @@ out_trans:
        ocfs2_commit_trans(OCFS2_SB(sb), handle);
 out:
        brelse(bh);
+       brelse(dbh);
        kmem_cache_free(ocfs2_qf_chunk_cachep, chunk);
        return ERR_PTR(status);
 }
@@ -1048,6 +1086,8 @@ static struct ocfs2_quota_chunk *ocfs2_extend_local_quota_file(
        struct ocfs2_local_disk_chunk *dchunk;
        int epb = ol_quota_entries_per_block(sb);
        unsigned int chunk_blocks;
+       struct buffer_head *bh;
+       u64 p_blkno;
        int status;
        handle_t *handle;
 
@@ -1075,12 +1115,49 @@ static struct ocfs2_quota_chunk *ocfs2_extend_local_quota_file(
                mlog_errno(status);
                goto out;
        }
-       handle = ocfs2_start_trans(OCFS2_SB(sb), 2);
+
+       /* Get buffer from the just added block */
+       down_read(&OCFS2_I(lqinode)->ip_alloc_sem);
+       status = ocfs2_extent_map_get_blocks(lqinode, oinfo->dqi_blocks,
+                                            &p_blkno, NULL, NULL);
+       up_read(&OCFS2_I(lqinode)->ip_alloc_sem);
+       if (status < 0) {
+               mlog_errno(status);
+               goto out;
+       }
+       bh = sb_getblk(sb, p_blkno);
+       if (!bh) {
+               status = -ENOMEM;
+               mlog_errno(status);
+               goto out;
+       }
+       ocfs2_set_new_buffer_uptodate(lqinode, bh);
+
+       /* Local quota info, chunk header and the new block we initialize */
+       handle = ocfs2_start_trans(OCFS2_SB(sb),
+                       OCFS2_LOCAL_QINFO_WRITE_CREDITS +
+                       2 * OCFS2_QUOTA_BLOCK_UPDATE_CREDITS);
        if (IS_ERR(handle)) {
                status = PTR_ERR(handle);
                mlog_errno(status);
                goto out;
        }
+       /* Zero created block */
+       status = ocfs2_journal_access_dq(handle, lqinode, bh,
+                                OCFS2_JOURNAL_ACCESS_CREATE);
+       if (status < 0) {
+               mlog_errno(status);
+               goto out_trans;
+       }
+       lock_buffer(bh);
+       memset(bh->b_data, 0, sb->s_blocksize);
+       unlock_buffer(bh);
+       status = ocfs2_journal_dirty(handle, bh);
+       if (status < 0) {
+               mlog_errno(status);
+               goto out_trans;
+       }
+       /* Update chunk header */
        status = ocfs2_journal_access_dq(handle, lqinode, chunk->qc_headerbh,
                                 OCFS2_JOURNAL_ACCESS_WRITE);
        if (status < 0) {
@@ -1097,6 +1174,7 @@ static struct ocfs2_quota_chunk *ocfs2_extend_local_quota_file(
                mlog_errno(status);
                goto out_trans;
        }
+       /* Update file header */
        oinfo->dqi_blocks++;
        status = ocfs2_local_write_info(sb, type);
        if (status < 0) {
index 3f661376a2ded76e08769f1766de3c1523d448d9..e49c41050264dfa9d36afc48e742b626ee9d2755 100644 (file)
@@ -17,6 +17,7 @@
  * General Public License for more details.
  */
 
+#include <linux/kernel.h>
 #include <linux/crc32.h>
 #include <linux/module.h>
 
@@ -153,7 +154,7 @@ static int status_map[] = {
 
 static int dlm_status_to_errno(enum dlm_status status)
 {
-       BUG_ON(status > (sizeof(status_map) / sizeof(status_map[0])));
+       BUG_ON(status < 0 || status >= ARRAY_SIZE(status_map));
 
        return status_map[status];
 }
index 7efb349fb9bdafe0678bd63786db244bba410b4a..b0ee0fdf799a514c9555b34f4983c734825badde 100644 (file)
@@ -777,6 +777,7 @@ static int ocfs2_sb_probe(struct super_block *sb,
                }
                di = (struct ocfs2_dinode *) (*bh)->b_data;
                memset(stats, 0, sizeof(struct ocfs2_blockcheck_stats));
+               spin_lock_init(&stats->b_lock);
                status = ocfs2_verify_volume(di, *bh, blksize, stats);
                if (status >= 0)
                        goto bail;
@@ -1182,7 +1183,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
        wake_up(&osb->osb_mount_event);
 
        /* Start this when the mount is almost sure of being successful */
-       ocfs2_orphan_scan_init(osb);
+       ocfs2_orphan_scan_start(osb);
 
        mlog_exit(status);
        return status;
@@ -1213,14 +1214,27 @@ static int ocfs2_get_sb(struct file_system_type *fs_type,
                           mnt);
 }
 
+static void ocfs2_kill_sb(struct super_block *sb)
+{
+       struct ocfs2_super *osb = OCFS2_SB(sb);
+
+       /* 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);
+
+       kill_block_super(sb);
+}
+
 static struct file_system_type ocfs2_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "ocfs2",
        .get_sb         = ocfs2_get_sb, /* is this called when we mount
                                        * the fs? */
-       .kill_sb        = kill_block_super, /* set to the generic one
-                                            * right now, but do we
-                                            * need to change that? */
+       .kill_sb        = ocfs2_kill_sb,
+
        .fs_flags       = FS_REQUIRES_DEV|FS_RENAME_DOES_D_MOVE,
        .next           = NULL
 };
@@ -1819,6 +1833,12 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
 
        debugfs_remove(osb->osb_ctxt);
 
+       /*
+        * Flush inode dropping work queue so that deletes are
+        * performed while the filesystem is still working
+        */
+       ocfs2_drop_all_dl_inodes(osb);
+
        /* Orphan scan should be stopped as early as possible */
        ocfs2_orphan_scan_stop(osb);
 
@@ -1981,6 +2001,8 @@ static int ocfs2_initialize_super(struct super_block *sb,
        snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u",
                 MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
 
+       ocfs2_orphan_scan_init(osb);
+
        status = ocfs2_recovery_init(osb);
        if (status) {
                mlog(ML_ERROR, "Unable to initialize recovery state\n");
index ba320e250747fd01dedcd06a85df0d2e867dbe44..d1a27cda984f10811fb66fe7a7a53e76f6036d34 100644 (file)
@@ -1052,7 +1052,8 @@ static int ocfs2_xattr_block_get(struct inode *inode,
        struct ocfs2_xattr_block *xb;
        struct ocfs2_xattr_value_root *xv;
        size_t size;
-       int ret = -ENODATA, name_offset, name_len, block_off, i;
+       int ret = -ENODATA, name_offset, name_len, i;
+       int uninitialized_var(block_off);
 
        xs->bucket = ocfs2_xattr_bucket_new(inode);
        if (!xs->bucket) {
index d870237e42c74f018b2824304345aa44a90b8607..8084834e123efed4e100fe030e2e26ced3ede1c9 100644 (file)
@@ -110,6 +110,7 @@ void poll_initwait(struct poll_wqueues *pwq)
 {
        init_poll_funcptr(&pwq->pt, __pollwait);
        pwq->polling_task = current;
+       pwq->triggered = 0;
        pwq->error = 0;
        pwq->table = NULL;
        pwq->inline_index = 0;
index 0c93c7ef3d187a27dbe6b8196de4aaa08be66447..965df1227d644df44b4d2b79810f1ab42747f957 100644 (file)
@@ -770,7 +770,7 @@ xfs_buf_associate_memory(
        bp->b_pages = NULL;
        bp->b_addr = mem;
 
-       rval = _xfs_buf_get_pages(bp, page_count, 0);
+       rval = _xfs_buf_get_pages(bp, page_count, XBF_DONT_BLOCK);
        if (rval)
                return rval;
 
index db15feb906fffa0e38b0e44f23ef3967faea33fd..4ece1906bd41c0d801f8b66a41efb48bd3bcad6d 100644 (file)
@@ -2010,7 +2010,9 @@ xfs_attr_rmtval_get(xfs_da_args_t *args)
                        dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock);
                        blkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
                        error = xfs_read_buf(mp, mp->m_ddev_targp, dblkno,
-                                            blkcnt, XFS_BUF_LOCK, &bp);
+                                            blkcnt,
+                                            XFS_BUF_LOCK | XBF_DONT_BLOCK,
+                                            &bp);
                        if (error)
                                return(error);
 
@@ -2141,8 +2143,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
                dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),
                blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);
 
-               bp = xfs_buf_get_flags(mp->m_ddev_targp, dblkno,
-                                                       blkcnt, XFS_BUF_LOCK);
+               bp = xfs_buf_get_flags(mp->m_ddev_targp, dblkno, blkcnt,
+                                      XFS_BUF_LOCK | XBF_DONT_BLOCK);
                ASSERT(bp);
                ASSERT(!XFS_BUF_GETERROR(bp));
 
index 7928b9983c1d53e6d0ca3c2719ce361bb95175f8..8ee5b5a76a2aff78995fb5a86926a0c9b1546bbd 100644 (file)
@@ -6009,7 +6009,7 @@ xfs_getbmap(
         */
        error = ENOMEM;
        subnex = 16;
-       map = kmem_alloc(subnex * sizeof(*map), KM_MAYFAIL);
+       map = kmem_alloc(subnex * sizeof(*map), KM_MAYFAIL | KM_NOFS);
        if (!map)
                goto out_unlock_ilock;
 
index e9df995748291047922ef29257e9423357d386db..26717388acf5a250c0ec8b039e041dbe753c0b77 100644 (file)
@@ -120,8 +120,8 @@ xfs_btree_check_sblock(
                        XFS_RANDOM_BTREE_CHECK_SBLOCK))) {
                if (bp)
                        xfs_buftrace("SBTREE ERROR", bp);
-               XFS_ERROR_REPORT("xfs_btree_check_sblock", XFS_ERRLEVEL_LOW,
-                                cur->bc_mp);
+               XFS_CORRUPTION_ERROR("xfs_btree_check_sblock",
+                       XFS_ERRLEVEL_LOW, cur->bc_mp, block);
                return XFS_ERROR(EFSCORRUPTED);
        }
        return 0;
index 9ff6e57a50758f10ddc076dc7875dad2172963a3..2847bbc1c534db4b9e2b3bd49645773678d15e07 100644 (file)
@@ -2201,7 +2201,7 @@ kmem_zone_t *xfs_dabuf_zone;              /* dabuf zone */
 xfs_da_state_t *
 xfs_da_state_alloc(void)
 {
-       return kmem_zone_zalloc(xfs_da_state_zone, KM_SLEEP);
+       return kmem_zone_zalloc(xfs_da_state_zone, KM_NOFS);
 }
 
 /*
@@ -2261,9 +2261,9 @@ xfs_da_buf_make(int nbuf, xfs_buf_t **bps, inst_t *ra)
        int             off;
 
        if (nbuf == 1)
-               dabuf = kmem_zone_alloc(xfs_dabuf_zone, KM_SLEEP);
+               dabuf = kmem_zone_alloc(xfs_dabuf_zone, KM_NOFS);
        else
-               dabuf = kmem_alloc(XFS_DA_BUF_SIZE(nbuf), KM_SLEEP);
+               dabuf = kmem_alloc(XFS_DA_BUF_SIZE(nbuf), KM_NOFS);
        dabuf->dirty = 0;
 #ifdef XFS_DABUF_DEBUG
        dabuf->ra = ra;
index c657bec6d9513849f2ad86dca172e88417742f14..bb1d58eb398238e5e485a8f0bad9ce51ba141e63 100644 (file)
@@ -256,7 +256,7 @@ xfs_dir_cilookup_result(
                                        !(args->op_flags & XFS_DA_OP_CILOOKUP))
                return EEXIST;
 
-       args->value = kmem_alloc(len, KM_MAYFAIL);
+       args->value = kmem_alloc(len, KM_NOFS | KM_MAYFAIL);
        if (!args->value)
                return ENOMEM;
 
index cbd451bb4848b38e398e583ba9537540bbfce1d0..2d0b3e1da9e69094f798967e3ff432d679249f00 100644 (file)
@@ -167,17 +167,25 @@ xfs_growfs_data_private(
        new = nb - mp->m_sb.sb_dblocks;
        oagcount = mp->m_sb.sb_agcount;
        if (nagcount > oagcount) {
+               void *new_perag, *old_perag;
+
                xfs_filestream_flush(mp);
+
+               new_perag = kmem_zalloc(sizeof(xfs_perag_t) * nagcount,
+                                       KM_MAYFAIL);
+               if (!new_perag)
+                       return XFS_ERROR(ENOMEM);
+
                down_write(&mp->m_peraglock);
-               mp->m_perag = kmem_realloc(mp->m_perag,
-                       sizeof(xfs_perag_t) * nagcount,
-                       sizeof(xfs_perag_t) * oagcount,
-                       KM_SLEEP);
-               memset(&mp->m_perag[oagcount], 0,
-                       (nagcount - oagcount) * sizeof(xfs_perag_t));
+               memcpy(new_perag, mp->m_perag, sizeof(xfs_perag_t) * oagcount);
+               old_perag = mp->m_perag;
+               mp->m_perag = new_perag;
+
                mp->m_flags |= XFS_MOUNT_32BITINODES;
                nagimax = xfs_initialize_perag(mp, nagcount);
                up_write(&mp->m_peraglock);
+
+               kmem_free(old_perag);
        }
        tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS);
        tp->t_flags |= XFS_TRANS_RESERVE;
index 1f22d65fed0a48d230a117f848598ba220017ad1..da428b3fe0f5777980ba58aef8c5e566334f318d 100644 (file)
@@ -343,6 +343,16 @@ xfs_iformat(
                return XFS_ERROR(EFSCORRUPTED);
        }
 
+       if (unlikely((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) &&
+                    !ip->i_mount->m_rtdev_targp)) {
+               xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount,
+                       "corrupt dinode %Lu, has realtime flag set.",
+                       ip->i_ino);
+               XFS_CORRUPTION_ERROR("xfs_iformat(realtime)",
+                                    XFS_ERRLEVEL_LOW, ip->i_mount, dip);
+               return XFS_ERROR(EFSCORRUPTED);
+       }
+
        switch (ip->i_d.di_mode & S_IFMT) {
        case S_IFIFO:
        case S_IFCHR:
index 3750f04ede0bf283a4592cb05a5ce4e04884b45b..9dbdff3ea484bf008d1b634a53a2f42aedb3effc 100644 (file)
@@ -3180,7 +3180,7 @@ try_again:
 STATIC void
 xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog)
 {
-       ASSERT(spin_is_locked(&log->l_icloglock));
+       assert_spin_locked(&log->l_icloglock);
 
        if (iclog->ic_state == XLOG_STATE_ACTIVE) {
                xlog_state_switch_iclogs(log, iclog, 0);
index c4eca5ed5dabf81d6c0133294a1f6dbad73d2a4a..492d75bae2bf22f25ff52fac48953e9e95141a01 100644 (file)
@@ -538,7 +538,9 @@ xfs_readlink_bmap(
                d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
                byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
 
-               bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0);
+               bp = xfs_buf_read_flags(mp->m_ddev_targp, d, BTOBB(byte_cnt),
+                                       XBF_LOCK | XBF_MAPPED |
+                                       XBF_DONT_BLOCK);
                error = XFS_BUF_GETERROR(bp);
                if (error) {
                        xfs_ioerror_alert("xfs_readlink",
index fdffb413b19276e7f7c9a2cc49bf7ec84e80a7cf..f6b90240dd41fc9c43b624c3b844b6f3879ce2c8 100644 (file)
@@ -473,7 +473,6 @@ extern int  nfs_writepages(struct address_space *, struct writeback_control *);
 extern int  nfs_flush_incompatible(struct file *file, struct page *page);
 extern int  nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int);
 extern int nfs_writeback_done(struct rpc_task *, struct nfs_write_data *);
-extern void nfs_writedata_release(void *);
 
 /*
  * Try to write back everything synchronously (but check the
@@ -488,7 +487,6 @@ extern int nfs_wb_page_cancel(struct inode *inode, struct page* page);
 extern int  nfs_commit_inode(struct inode *, int);
 extern struct nfs_write_data *nfs_commitdata_alloc(void);
 extern void nfs_commit_free(struct nfs_write_data *wdata);
-extern void nfs_commitdata_release(void *wdata);
 #else
 static inline int
 nfs_commit_inode(struct inode *inode, int how)
@@ -507,6 +505,7 @@ nfs_have_writebacks(struct inode *inode)
  * Allocate nfs_write_data structures
  */
 extern struct nfs_write_data *nfs_writedata_alloc(unsigned int npages);
+extern void nfs_writedata_free(struct nfs_write_data *);
 
 /*
  * linux/fs/nfs/read.c
@@ -515,7 +514,6 @@ extern int  nfs_readpage(struct file *, struct page *);
 extern int  nfs_readpages(struct file *, struct address_space *,
                struct list_head *, unsigned);
 extern int  nfs_readpage_result(struct rpc_task *, struct nfs_read_data *);
-extern void nfs_readdata_release(void *data);
 extern int  nfs_readpage_async(struct nfs_open_context *, struct inode *,
                               struct page *);
 
@@ -523,6 +521,7 @@ extern int  nfs_readpage_async(struct nfs_open_context *, struct inode *,
  * Allocate nfs_read_data structures
  */
 extern struct nfs_read_data *nfs_readdata_alloc(unsigned int npages);
+extern void nfs_readdata_free(struct nfs_read_data *);
 
 /*
  * linux/fs/nfs3proc.c
index a9d823a93fe89e9bbf11db6a48169ede758af39e..b53f7006cc4e0bb5e1ad5f09ae76249d150d2ca4 100644 (file)
@@ -115,7 +115,7 @@ enum perf_counter_sample_format {
        PERF_SAMPLE_TID                         = 1U << 1,
        PERF_SAMPLE_TIME                        = 1U << 2,
        PERF_SAMPLE_ADDR                        = 1U << 3,
-       PERF_SAMPLE_GROUP                       = 1U << 4,
+       PERF_SAMPLE_READ                        = 1U << 4,
        PERF_SAMPLE_CALLCHAIN                   = 1U << 5,
        PERF_SAMPLE_ID                          = 1U << 6,
        PERF_SAMPLE_CPU                         = 1U << 7,
@@ -127,16 +127,32 @@ enum perf_counter_sample_format {
 };
 
 /*
- * Bits that can be set in attr.read_format to request that
- * reads on the counter should return the indicated quantities,
- * in increasing order of bit value, after the counter value.
+ * The format of the data returned by read() on a perf counter fd,
+ * as specified by attr.read_format:
+ *
+ * struct read_format {
+ *     { u64           value;
+ *       { u64         time_enabled; } && PERF_FORMAT_ENABLED
+ *       { u64         time_running; } && PERF_FORMAT_RUNNING
+ *       { u64         id;           } && PERF_FORMAT_ID
+ *     } && !PERF_FORMAT_GROUP
+ *
+ *     { u64           nr;
+ *       { u64         time_enabled; } && PERF_FORMAT_ENABLED
+ *       { u64         time_running; } && PERF_FORMAT_RUNNING
+ *       { u64         value;
+ *         { u64       id;           } && PERF_FORMAT_ID
+ *       }             cntr[nr];
+ *     } && PERF_FORMAT_GROUP
+ * };
  */
 enum perf_counter_read_format {
        PERF_FORMAT_TOTAL_TIME_ENABLED          = 1U << 0,
        PERF_FORMAT_TOTAL_TIME_RUNNING          = 1U << 1,
        PERF_FORMAT_ID                          = 1U << 2,
+       PERF_FORMAT_GROUP                       = 1U << 3,
 
-       PERF_FORMAT_MAX = 1U << 3,              /* non-ABI */
+       PERF_FORMAT_MAX = 1U << 4,              /* non-ABI */
 };
 
 #define PERF_ATTR_SIZE_VER0    64      /* sizeof first published struct */
@@ -343,10 +359,8 @@ enum perf_event_type {
         * struct {
         *      struct perf_event_header        header;
         *      u32                             pid, tid;
-        *      u64                             value;
-        *      { u64           time_enabled;   } && PERF_FORMAT_ENABLED
-        *      { u64           time_running;   } && PERF_FORMAT_RUNNING
-        *      { u64           parent_id;      } && PERF_FORMAT_ID
+        *
+        *      struct read_format              values;
         * };
         */
        PERF_EVENT_READ                 = 8,
@@ -364,11 +378,22 @@ enum perf_event_type {
         *      { u32                   cpu, res; } && PERF_SAMPLE_CPU
         *      { u64                   period;   } && PERF_SAMPLE_PERIOD
         *
-        *      { u64                   nr;
-        *        { u64 id, val; }      cnt[nr];  } && PERF_SAMPLE_GROUP
+        *      { struct read_format    values;   } && PERF_SAMPLE_READ
         *
         *      { u64                   nr,
         *        u64                   ips[nr];  } && PERF_SAMPLE_CALLCHAIN
+        *
+        *      #
+        *      # The RAW record below is opaque data wrt the ABI
+        *      #
+        *      # That is, the ABI doesn't make any promises wrt to
+        *      # the stability of its content, it may vary depending
+        *      # on event, hardware, kernel version and phase of
+        *      # the moon.
+        *      #
+        *      # In other words, PERF_SAMPLE_RAW contents are not an ABI.
+        *      #
+        *
         *      { u32                   size;
         *        char                  data[size];}&& PERF_SAMPLE_RAW
         * };
@@ -694,6 +719,8 @@ struct perf_sample_data {
 
 extern int perf_counter_overflow(struct perf_counter *counter, int nmi,
                                 struct perf_sample_data *data);
+extern void perf_counter_output(struct perf_counter *counter, int nmi,
+                               struct perf_sample_data *data);
 
 /*
  * Return 1 for a software counter, 0 for a hardware counter
index 6788e1a4d4ca63e8cfc3b288f87d456334064c29..cf3c2f5dba51834215b137e5385b2654f220fc42 100644 (file)
@@ -77,7 +77,14 @@ struct task_struct;
 #define __WAIT_BIT_KEY_INITIALIZER(word, bit)                          \
        { .flags = word, .bit_nr = bit, }
 
-extern void init_waitqueue_head(wait_queue_head_t *q);
+extern void __init_waitqueue_head(wait_queue_head_t *q, struct lock_class_key *);
+
+#define init_waitqueue_head(q)                         \
+       do {                                            \
+               static struct lock_class_key __key;     \
+                                                       \
+               __init_waitqueue_head((q), &__key);     \
+       } while (0)
 
 #ifdef CONFIG_LOCKDEP
 # define __WAIT_QUEUE_HEAD_INIT_ONSTACK(name) \
index 0672ff88f159f3041206750b3427fdd68aa0afc1..e18cfbdc71904d0260d505bd73a41d06a38982d9 100644 (file)
@@ -1010,15 +1010,19 @@ void requeue_futex(struct futex_q *q, struct futex_hash_bucket *hb1,
  * requeue_pi_wake_futex() - Wake a task that acquired the lock during requeue
  * q:  the futex_q
  * key:        the key of the requeue target futex
+ * hb:  the hash_bucket of the requeue target futex
  *
  * During futex_requeue, with requeue_pi=1, it is possible to acquire the
  * target futex if it is uncontended or via a lock steal.  Set the futex_q key
  * to the requeue target futex so the waiter can detect the wakeup on the right
  * futex, but remove it from the hb and NULL the rt_waiter so it can detect
- * atomic lock acquisition.  Must be called with the q->lock_ptr held.
+ * atomic lock acquisition.  Set the q->lock_ptr to the requeue target hb->lock
+ * to protect access to the pi_state to fixup the owner later.  Must be called
+ * with both q->lock_ptr and hb->lock held.
  */
 static inline
-void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key)
+void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key,
+                          struct futex_hash_bucket *hb)
 {
        drop_futex_key_refs(&q->key);
        get_futex_key_refs(key);
@@ -1030,6 +1034,11 @@ void requeue_pi_wake_futex(struct futex_q *q, union futex_key *key)
        WARN_ON(!q->rt_waiter);
        q->rt_waiter = NULL;
 
+       q->lock_ptr = &hb->lock;
+#ifdef CONFIG_DEBUG_PI_LIST
+       q->list.plist.lock = &hb->lock;
+#endif
+
        wake_up_state(q->task, TASK_NORMAL);
 }
 
@@ -1088,7 +1097,7 @@ static int futex_proxy_trylock_atomic(u32 __user *pifutex,
        ret = futex_lock_pi_atomic(pifutex, hb2, key2, ps, top_waiter->task,
                                   set_waiters);
        if (ret == 1)
-               requeue_pi_wake_futex(top_waiter, key2);
+               requeue_pi_wake_futex(top_waiter, key2, hb2);
 
        return ret;
 }
@@ -1247,8 +1256,15 @@ retry_private:
                if (!match_futex(&this->key, &key1))
                        continue;
 
-               WARN_ON(!requeue_pi && this->rt_waiter);
-               WARN_ON(requeue_pi && !this->rt_waiter);
+               /*
+                * FUTEX_WAIT_REQEUE_PI and FUTEX_CMP_REQUEUE_PI should always
+                * be paired with each other and no other futex ops.
+                */
+               if ((requeue_pi && !this->rt_waiter) ||
+                   (!requeue_pi && this->rt_waiter)) {
+                       ret = -EINVAL;
+                       break;
+               }
 
                /*
                 * Wake nr_wake waiters.  For requeue_pi, if we acquired the
@@ -1273,7 +1289,7 @@ retry_private:
                                                        this->task, 1);
                        if (ret == 1) {
                                /* We got the lock. */
-                               requeue_pi_wake_futex(this, &key2);
+                               requeue_pi_wake_futex(this, &key2, hb2);
                                continue;
                        } else if (ret) {
                                /* -EDEADLK */
index d607a5b9ee29923617d462288e9853327c7d1527..235716556bf16ed9b97c19a9578ef24dec19edb1 100644 (file)
@@ -180,7 +180,8 @@ asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
        int cmd = op & FUTEX_CMD_MASK;
 
        if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI ||
-                     cmd == FUTEX_WAIT_BITSET)) {
+                     cmd == FUTEX_WAIT_BITSET ||
+                     cmd == FUTEX_WAIT_REQUEUE_PI)) {
                if (get_compat_timespec(&ts, utime))
                        return -EFAULT;
                if (!timespec_valid(&ts))
@@ -191,7 +192,8 @@ asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
                        t = ktime_add_safe(ktime_get(), t);
                tp = &t;
        }
-       if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE)
+       if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE ||
+           cmd == FUTEX_CMP_REQUEUE_PI || cmd == FUTEX_WAKE_OP)
                val2 = (int) (unsigned long) utime;
 
        return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);
index 61c679db4687a853c52f7d5b23b5ba5e267b4c17..d222515a5a062db18a1e38e5b75f8fd5cd38f745 100644 (file)
@@ -761,7 +761,6 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
 {
        struct irq_desc *desc = irq_to_desc(irq);
        struct irqaction *action, **action_ptr;
-       struct task_struct *irqthread;
        unsigned long flags;
 
        WARN(in_interrupt(), "Trying to free IRQ %d from IRQ context!\n", irq);
@@ -809,9 +808,6 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
                        desc->chip->disable(irq);
        }
 
-       irqthread = action->thread;
-       action->thread = NULL;
-
        spin_unlock_irqrestore(&desc->lock, flags);
 
        unregister_handler_proc(irq, action);
@@ -819,12 +815,6 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
        /* Make sure it's not being used on another CPU: */
        synchronize_irq(irq);
 
-       if (irqthread) {
-               if (!test_bit(IRQTF_DIED, &action->thread_flags))
-                       kthread_stop(irqthread);
-               put_task_struct(irqthread);
-       }
-
 #ifdef CONFIG_DEBUG_SHIRQ
        /*
         * It's a shared IRQ -- the driver ought to be prepared for an IRQ
@@ -840,6 +830,13 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
                local_irq_restore(flags);
        }
 #endif
+
+       if (action->thread) {
+               if (!test_bit(IRQTF_DIED, &action->thread_flags))
+                       kthread_stop(action->thread);
+               put_task_struct(action->thread);
+       }
+
        return action;
 }
 
index b0b20a07f3942422f614a4d0f429a23d19db396e..534e20d14d631b44cefc136f99200b2257af378f 100644 (file)
@@ -88,6 +88,7 @@ void __weak hw_perf_disable(void)             { barrier(); }
 void __weak hw_perf_enable(void)               { barrier(); }
 
 void __weak hw_perf_counter_setup(int cpu)     { barrier(); }
+void __weak hw_perf_counter_setup_online(int cpu)      { barrier(); }
 
 int __weak
 hw_perf_group_sched_in(struct perf_counter *group_leader,
@@ -306,6 +307,10 @@ counter_sched_out(struct perf_counter *counter,
                return;
 
        counter->state = PERF_COUNTER_STATE_INACTIVE;
+       if (counter->pending_disable) {
+               counter->pending_disable = 0;
+               counter->state = PERF_COUNTER_STATE_OFF;
+       }
        counter->tstamp_stopped = ctx->time;
        counter->pmu->disable(counter);
        counter->oncpu = -1;
@@ -1691,7 +1696,32 @@ static int perf_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static u64 perf_counter_read_tree(struct perf_counter *counter)
+static int perf_counter_read_size(struct perf_counter *counter)
+{
+       int entry = sizeof(u64); /* value */
+       int size = 0;
+       int nr = 1;
+
+       if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
+               size += sizeof(u64);
+
+       if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
+               size += sizeof(u64);
+
+       if (counter->attr.read_format & PERF_FORMAT_ID)
+               entry += sizeof(u64);
+
+       if (counter->attr.read_format & PERF_FORMAT_GROUP) {
+               nr += counter->group_leader->nr_siblings;
+               size += sizeof(u64);
+       }
+
+       size += entry * nr;
+
+       return size;
+}
+
+static u64 perf_counter_read_value(struct perf_counter *counter)
 {
        struct perf_counter *child;
        u64 total = 0;
@@ -1703,14 +1733,96 @@ static u64 perf_counter_read_tree(struct perf_counter *counter)
        return total;
 }
 
+static int perf_counter_read_entry(struct perf_counter *counter,
+                                  u64 read_format, char __user *buf)
+{
+       int n = 0, count = 0;
+       u64 values[2];
+
+       values[n++] = perf_counter_read_value(counter);
+       if (read_format & PERF_FORMAT_ID)
+               values[n++] = primary_counter_id(counter);
+
+       count = n * sizeof(u64);
+
+       if (copy_to_user(buf, values, count))
+               return -EFAULT;
+
+       return count;
+}
+
+static int perf_counter_read_group(struct perf_counter *counter,
+                                  u64 read_format, char __user *buf)
+{
+       struct perf_counter *leader = counter->group_leader, *sub;
+       int n = 0, size = 0, err = -EFAULT;
+       u64 values[3];
+
+       values[n++] = 1 + leader->nr_siblings;
+       if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
+               values[n++] = leader->total_time_enabled +
+                       atomic64_read(&leader->child_total_time_enabled);
+       }
+       if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
+               values[n++] = leader->total_time_running +
+                       atomic64_read(&leader->child_total_time_running);
+       }
+
+       size = n * sizeof(u64);
+
+       if (copy_to_user(buf, values, size))
+               return -EFAULT;
+
+       err = perf_counter_read_entry(leader, read_format, buf + size);
+       if (err < 0)
+               return err;
+
+       size += err;
+
+       list_for_each_entry(sub, &leader->sibling_list, list_entry) {
+               err = perf_counter_read_entry(counter, read_format,
+                               buf + size);
+               if (err < 0)
+                       return err;
+
+               size += err;
+       }
+
+       return size;
+}
+
+static int perf_counter_read_one(struct perf_counter *counter,
+                                u64 read_format, char __user *buf)
+{
+       u64 values[4];
+       int n = 0;
+
+       values[n++] = perf_counter_read_value(counter);
+       if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
+               values[n++] = counter->total_time_enabled +
+                       atomic64_read(&counter->child_total_time_enabled);
+       }
+       if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
+               values[n++] = counter->total_time_running +
+                       atomic64_read(&counter->child_total_time_running);
+       }
+       if (read_format & PERF_FORMAT_ID)
+               values[n++] = primary_counter_id(counter);
+
+       if (copy_to_user(buf, values, n * sizeof(u64)))
+               return -EFAULT;
+
+       return n * sizeof(u64);
+}
+
 /*
  * Read the performance counter - simple non blocking version for now
  */
 static ssize_t
 perf_read_hw(struct perf_counter *counter, char __user *buf, size_t count)
 {
-       u64 values[4];
-       int n;
+       u64 read_format = counter->attr.read_format;
+       int ret;
 
        /*
         * Return end-of-file for a read on a counter that is in
@@ -1720,28 +1832,18 @@ perf_read_hw(struct perf_counter *counter, char __user *buf, size_t count)
        if (counter->state == PERF_COUNTER_STATE_ERROR)
                return 0;
 
+       if (count < perf_counter_read_size(counter))
+               return -ENOSPC;
+
        WARN_ON_ONCE(counter->ctx->parent_ctx);
        mutex_lock(&counter->child_mutex);
-       values[0] = perf_counter_read_tree(counter);
-       n = 1;
-       if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
-               values[n++] = counter->total_time_enabled +
-                       atomic64_read(&counter->child_total_time_enabled);
-       if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
-               values[n++] = counter->total_time_running +
-                       atomic64_read(&counter->child_total_time_running);
-       if (counter->attr.read_format & PERF_FORMAT_ID)
-               values[n++] = primary_counter_id(counter);
+       if (read_format & PERF_FORMAT_GROUP)
+               ret = perf_counter_read_group(counter, read_format, buf);
+       else
+               ret = perf_counter_read_one(counter, read_format, buf);
        mutex_unlock(&counter->child_mutex);
 
-       if (count < n * sizeof(u64))
-               return -EINVAL;
-       count = n * sizeof(u64);
-
-       if (copy_to_user(buf, values, count))
-               return -EFAULT;
-
-       return count;
+       return ret;
 }
 
 static ssize_t
@@ -2245,7 +2347,7 @@ static void perf_pending_counter(struct perf_pending_entry *entry)
 
        if (counter->pending_disable) {
                counter->pending_disable = 0;
-               perf_counter_disable(counter);
+               __perf_counter_disable(counter);
        }
 
        if (counter->pending_wakeup) {
@@ -2630,7 +2732,80 @@ static u32 perf_counter_tid(struct perf_counter *counter, struct task_struct *p)
        return task_pid_nr_ns(p, counter->ns);
 }
 
-static void perf_counter_output(struct perf_counter *counter, int nmi,
+static void perf_output_read_one(struct perf_output_handle *handle,
+                                struct perf_counter *counter)
+{
+       u64 read_format = counter->attr.read_format;
+       u64 values[4];
+       int n = 0;
+
+       values[n++] = atomic64_read(&counter->count);
+       if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
+               values[n++] = counter->total_time_enabled +
+                       atomic64_read(&counter->child_total_time_enabled);
+       }
+       if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
+               values[n++] = counter->total_time_running +
+                       atomic64_read(&counter->child_total_time_running);
+       }
+       if (read_format & PERF_FORMAT_ID)
+               values[n++] = primary_counter_id(counter);
+
+       perf_output_copy(handle, values, n * sizeof(u64));
+}
+
+/*
+ * XXX PERF_FORMAT_GROUP vs inherited counters seems difficult.
+ */
+static void perf_output_read_group(struct perf_output_handle *handle,
+                           struct perf_counter *counter)
+{
+       struct perf_counter *leader = counter->group_leader, *sub;
+       u64 read_format = counter->attr.read_format;
+       u64 values[5];
+       int n = 0;
+
+       values[n++] = 1 + leader->nr_siblings;
+
+       if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
+               values[n++] = leader->total_time_enabled;
+
+       if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
+               values[n++] = leader->total_time_running;
+
+       if (leader != counter)
+               leader->pmu->read(leader);
+
+       values[n++] = atomic64_read(&leader->count);
+       if (read_format & PERF_FORMAT_ID)
+               values[n++] = primary_counter_id(leader);
+
+       perf_output_copy(handle, values, n * sizeof(u64));
+
+       list_for_each_entry(sub, &leader->sibling_list, list_entry) {
+               n = 0;
+
+               if (sub != counter)
+                       sub->pmu->read(sub);
+
+               values[n++] = atomic64_read(&sub->count);
+               if (read_format & PERF_FORMAT_ID)
+                       values[n++] = primary_counter_id(sub);
+
+               perf_output_copy(handle, values, n * sizeof(u64));
+       }
+}
+
+static void perf_output_read(struct perf_output_handle *handle,
+                            struct perf_counter *counter)
+{
+       if (counter->attr.read_format & PERF_FORMAT_GROUP)
+               perf_output_read_group(handle, counter);
+       else
+               perf_output_read_one(handle, counter);
+}
+
+void perf_counter_output(struct perf_counter *counter, int nmi,
                                struct perf_sample_data *data)
 {
        int ret;
@@ -2641,10 +2816,6 @@ static void perf_counter_output(struct perf_counter *counter, int nmi,
        struct {
                u32 pid, tid;
        } tid_entry;
-       struct {
-               u64 id;
-               u64 counter;
-       } group_entry;
        struct perf_callchain_entry *callchain = NULL;
        int callchain_size = 0;
        u64 time;
@@ -2699,10 +2870,8 @@ static void perf_counter_output(struct perf_counter *counter, int nmi,
        if (sample_type & PERF_SAMPLE_PERIOD)
                header.size += sizeof(u64);
 
-       if (sample_type & PERF_SAMPLE_GROUP) {
-               header.size += sizeof(u64) +
-                       counter->nr_siblings * sizeof(group_entry);
-       }
+       if (sample_type & PERF_SAMPLE_READ)
+               header.size += perf_counter_read_size(counter);
 
        if (sample_type & PERF_SAMPLE_CALLCHAIN) {
                callchain = perf_callchain(data->regs);
@@ -2759,26 +2928,8 @@ static void perf_counter_output(struct perf_counter *counter, int nmi,
        if (sample_type & PERF_SAMPLE_PERIOD)
                perf_output_put(&handle, data->period);
 
-       /*
-        * XXX PERF_SAMPLE_GROUP vs inherited counters seems difficult.
-        */
-       if (sample_type & PERF_SAMPLE_GROUP) {
-               struct perf_counter *leader, *sub;
-               u64 nr = counter->nr_siblings;
-
-               perf_output_put(&handle, nr);
-
-               leader = counter->group_leader;
-               list_for_each_entry(sub, &leader->sibling_list, list_entry) {
-                       if (sub != counter)
-                               sub->pmu->read(sub);
-
-                       group_entry.id = primary_counter_id(sub);
-                       group_entry.counter = atomic64_read(&sub->count);
-
-                       perf_output_put(&handle, group_entry);
-               }
-       }
+       if (sample_type & PERF_SAMPLE_READ)
+               perf_output_read(&handle, counter);
 
        if (sample_type & PERF_SAMPLE_CALLCHAIN) {
                if (callchain)
@@ -2817,8 +2968,6 @@ struct perf_read_event {
 
        u32                             pid;
        u32                             tid;
-       u64                             value;
-       u64                             format[3];
 };
 
 static void
@@ -2830,34 +2979,20 @@ perf_counter_read_event(struct perf_counter *counter,
                .header = {
                        .type = PERF_EVENT_READ,
                        .misc = 0,
-                       .size = sizeof(event) - sizeof(event.format),
+                       .size = sizeof(event) + perf_counter_read_size(counter),
                },
                .pid = perf_counter_pid(counter, task),
                .tid = perf_counter_tid(counter, task),
-               .value = atomic64_read(&counter->count),
        };
-       int ret, i = 0;
-
-       if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
-               event.header.size += sizeof(u64);
-               event.format[i++] = counter->total_time_enabled;
-       }
-
-       if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
-               event.header.size += sizeof(u64);
-               event.format[i++] = counter->total_time_running;
-       }
-
-       if (counter->attr.read_format & PERF_FORMAT_ID) {
-               event.header.size += sizeof(u64);
-               event.format[i++] = primary_counter_id(counter);
-       }
+       int ret;
 
        ret = perf_output_begin(&handle, counter, event.header.size, 0, 0);
        if (ret)
                return;
 
-       perf_output_copy(&handle, &event, event.header.size);
+       perf_output_put(&handle, event);
+       perf_output_read(&handle, counter);
+
        perf_output_end(&handle);
 }
 
@@ -2893,10 +3028,10 @@ static void perf_counter_task_output(struct perf_counter *counter,
                return;
 
        task_event->event.pid = perf_counter_pid(counter, task);
-       task_event->event.ppid = perf_counter_pid(counter, task->real_parent);
+       task_event->event.ppid = perf_counter_pid(counter, current);
 
        task_event->event.tid = perf_counter_tid(counter, task);
-       task_event->event.ptid = perf_counter_tid(counter, task->real_parent);
+       task_event->event.ptid = perf_counter_tid(counter, current);
 
        perf_output_put(&handle, task_event->event);
        perf_output_end(&handle);
@@ -3443,40 +3578,32 @@ static void perf_swcounter_add(struct perf_counter *counter, u64 nr,
 
 static int perf_swcounter_is_counting(struct perf_counter *counter)
 {
-       struct perf_counter_context *ctx;
-       unsigned long flags;
-       int count;
-
+       /*
+        * The counter is active, we're good!
+        */
        if (counter->state == PERF_COUNTER_STATE_ACTIVE)
                return 1;
 
+       /*
+        * The counter is off/error, not counting.
+        */
        if (counter->state != PERF_COUNTER_STATE_INACTIVE)
                return 0;
 
        /*
-        * If the counter is inactive, it could be just because
-        * its task is scheduled out, or because it's in a group
-        * which could not go on the PMU.  We want to count in
-        * the first case but not the second.  If the context is
-        * currently active then an inactive software counter must
-        * be the second case.  If it's not currently active then
-        * we need to know whether the counter was active when the
-        * context was last active, which we can determine by
-        * comparing counter->tstamp_stopped with ctx->time.
-        *
-        * We are within an RCU read-side critical section,
-        * which protects the existence of *ctx.
+        * The counter is inactive, if the context is active
+        * we're part of a group that didn't make it on the 'pmu',
+        * not counting.
         */
-       ctx = counter->ctx;
-       spin_lock_irqsave(&ctx->lock, flags);
-       count = 1;
-       /* Re-check state now we have the lock */
-       if (counter->state < PERF_COUNTER_STATE_INACTIVE ||
-           counter->ctx->is_active ||
-           counter->tstamp_stopped < ctx->time)
-               count = 0;
-       spin_unlock_irqrestore(&ctx->lock, flags);
-       return count;
+       if (counter->ctx->is_active)
+               return 0;
+
+       /*
+        * We're inactive and the context is too, this means the
+        * task is scheduled out, we're counting events that happen
+        * to us, like migration events.
+        */
+       return 1;
 }
 
 static int perf_swcounter_match(struct perf_counter *counter,
@@ -3928,9 +4055,9 @@ perf_counter_alloc(struct perf_counter_attr *attr,
        atomic64_set(&hwc->period_left, hwc->sample_period);
 
        /*
-        * we currently do not support PERF_SAMPLE_GROUP on inherited counters
+        * we currently do not support PERF_FORMAT_GROUP on inherited counters
         */
-       if (attr->inherit && (attr->sample_type & PERF_SAMPLE_GROUP))
+       if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP))
                goto done;
 
        switch (attr->type) {
@@ -4592,6 +4719,11 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
                perf_counter_init_cpu(cpu);
                break;
 
+       case CPU_ONLINE:
+       case CPU_ONLINE_FROZEN:
+               hw_perf_counter_setup_online(cpu);
+               break;
+
        case CPU_DOWN_PREPARE:
        case CPU_DOWN_PREPARE_FROZEN:
                perf_counter_exit_cpu(cpu);
@@ -4616,6 +4748,8 @@ void __init perf_counter_init(void)
 {
        perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE,
                        (void *)(long)smp_processor_id());
+       perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_ONLINE,
+                       (void *)(long)smp_processor_id());
        register_cpu_notifier(&perf_cpu_nb);
 }
 
index 1090b0aed9bac6135d359e0cb07317085e6145d6..7a34cb563fec4cef90ebbf1d6bcc71dd4af4fef4 100644 (file)
@@ -267,8 +267,8 @@ static void blk_trace_free(struct blk_trace *bt)
 {
        debugfs_remove(bt->msg_file);
        debugfs_remove(bt->dropped_file);
-       debugfs_remove(bt->dir);
        relay_close(bt->rchan);
+       debugfs_remove(bt->dir);
        free_percpu(bt->sequence);
        free_percpu(bt->msg_data);
        kfree(bt);
@@ -378,18 +378,8 @@ static int blk_subbuf_start_callback(struct rchan_buf *buf, void *subbuf,
 
 static int blk_remove_buf_file_callback(struct dentry *dentry)
 {
-       struct dentry *parent = dentry->d_parent;
        debugfs_remove(dentry);
 
-       /*
-       * this will fail for all but the last file, but that is ok. what we
-       * care about is the top level buts->name directory going away, when
-       * the last trace file is gone. Then we don't have to rmdir() that
-       * manually on trace stop, so it nicely solves the issue with
-       * force killing of running traces.
-       */
-
-       debugfs_remove(parent);
        return 0;
 }
 
index ea7c3b4275cf362f75cee939aa7861f7673b95cc..c4bd3d825f35c8c8dd7ed4831cd5fee5fe6a6b9a 100644 (file)
 #include <linux/wait.h>
 #include <linux/hash.h>
 
-void init_waitqueue_head(wait_queue_head_t *q)
+void __init_waitqueue_head(wait_queue_head_t *q, struct lock_class_key *key)
 {
        spin_lock_init(&q->lock);
+       lockdep_set_class(&q->lock, key);
        INIT_LIST_HEAD(&q->task_list);
 }
 
-EXPORT_SYMBOL(init_waitqueue_head);
+EXPORT_SYMBOL(__init_waitqueue_head);
 
 void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
 {
index 791d71a36a93dfec5166fe05e2e0cb394cfa904b..6d47165590473daa4990bf69b0435d5c49b41302 100644 (file)
@@ -736,7 +736,7 @@ static ssize_t sock_sendpage(struct file *file, struct page *page,
        if (more)
                flags |= MSG_MORE;
 
-       return sock->ops->sendpage(sock, page, offset, size, flags);
+       return kernel_sendpage(sock, page, offset, size, flags);
 }
 
 static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
index 15c2a08a66f1217e92028a38e861ad4981ab3fdd..1e8cfc4c2ed6214c7accf4a7429e3e051cf63670 100644 (file)
@@ -1285,6 +1285,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
                rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX,
                                           context, len);
                if (rc == -ERANGE) {
+                       kfree(context);
+
                        /* Need a larger buffer.  Query for the right size. */
                        rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX,
                                                   NULL, 0);
@@ -1292,7 +1294,6 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
                                dput(dentry);
                                goto out_unlock;
                        }
-                       kfree(context);
                        len = rc;
                        context = kmalloc(len+1, GFP_NOFS);
                        if (!context) {
index 51c44fdbc0f0ab071d6386efc234cf51b3eb9a52..fea976793ae5406254fda7f6571a28d3c80ef66b 100644 (file)
@@ -13563,6 +13563,8 @@ static int patch_alc269(struct hda_codec *codec)
                set_capture_mixer(spec);
        set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
 
+       spec->vmaster_nid = 0x02;
+
        codec->patch_ops = alc_patch_ops;
        if (board_config == ALC269_AUTO)
                spec->init_hook = alc269_auto_init;
@@ -15577,9 +15579,12 @@ static int patch_alc861vd(struct hda_codec *codec)
        spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
        spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
 
-       spec->adc_nids = alc861vd_adc_nids;
-       spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
-       spec->capsrc_nids = alc861vd_capsrc_nids;
+       if (!spec->adc_nids) {
+               spec->adc_nids = alc861vd_adc_nids;
+               spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
+       }
+       if (!spec->capsrc_nids)
+               spec->capsrc_nids = alc861vd_capsrc_nids;
 
        set_capture_mixer(spec);
        set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
@@ -17496,9 +17501,12 @@ static int patch_alc662(struct hda_codec *codec)
        spec->stream_digital_playback = &alc662_pcm_digital_playback;
        spec->stream_digital_capture = &alc662_pcm_digital_capture;
 
-       spec->adc_nids = alc662_adc_nids;
-       spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
-       spec->capsrc_nids = alc662_capsrc_nids;
+       if (!spec->adc_nids) {
+               spec->adc_nids = alc662_adc_nids;
+               spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
+       }
+       if (!spec->capsrc_nids)
+               spec->capsrc_nids = alc662_capsrc_nids;
 
        if (!spec->cap_mixer)
                set_capture_mixer(spec);
index 85b0e75695048465728b3d5de2ee76374ff60c09..3326e2a1e8633a9ee357541c687536ec701f6f62 100644 (file)
@@ -30,6 +30,8 @@
 #include "mpc5200_psc_ac97.h"
 #include "../codecs/stac9766.h"
 
+#define DRV_NAME "efika-audio-fabric"
+
 static struct snd_soc_device device;
 static struct snd_soc_card card;
 
index 8766f7a3893d92aac0797d40652cadc77216af23..b928ef7d28eb82461e7ac3513bef6534d2addf75 100644 (file)
@@ -30,6 +30,8 @@
 #include "mpc5200_psc_ac97.h"
 #include "../codecs/wm9712.h"
 
+#define DRV_NAME "pcm030-audio-fabric"
+
 static struct snd_soc_device device;
 static struct snd_soc_card card;
 
index 60411e94113be47ee778f2d5f3e54b396945850e..c045b4271e57250fc7c983f810b77aeaced80525 100644 (file)
@@ -382,22 +382,29 @@ endif
 ifdef NO_DEMANGLE
        BASIC_CFLAGS += -DNO_DEMANGLE
 else
-
        has_bfd := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd > /dev/null 2>&1 && echo y")
 
-       has_bfd_iberty := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd -liberty > /dev/null 2>&1 && echo y")
-
-       has_bfd_iberty_z := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd -liberty -lz > /dev/null 2>&1 && echo y")
-
        ifeq ($(has_bfd),y)
                EXTLIBS += -lbfd
-       else ifeq ($(has_bfd_iberty),y)
-               EXTLIBS += -lbfd -liberty
-       else ifeq ($(has_bfd_iberty_z),y)
-               EXTLIBS += -lbfd -liberty -lz
        else
-               msg := $(warning No bfd.h/libbfd found, install binutils-dev[el] to gain symbol demangling)
-               BASIC_CFLAGS += -DNO_DEMANGLE
+               has_bfd_iberty := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd -liberty > /dev/null 2>&1 && echo y")
+               ifeq ($(has_bfd_iberty),y)
+                       EXTLIBS += -lbfd -liberty
+               else
+                       has_bfd_iberty_z := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd -liberty -lz > /dev/null 2>&1 && echo y")
+                       ifeq ($(has_bfd_iberty_z),y)
+                               EXTLIBS += -lbfd -liberty -lz
+                       else
+                               has_cplus_demangle := $(shell sh -c "(echo 'extern char *cplus_demangle(const char *, int);'; echo 'int main(void) { cplus_demangle(0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -liberty > /dev/null 2>&1 && echo y")
+                               ifeq ($(has_cplus_demangle),y)
+                                       EXTLIBS += -liberty
+                                       BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
+                               else
+                                       msg := $(warning No bfd.h/libbfd found, install binutils-dev[el] to gain symbol demangling)
+                                       BASIC_CFLAGS += -DNO_DEMANGLE
+                               endif
+                       endif
+               endif
        endif
 endif
 
index f990fa8a35c9d3312a20f3dcc1498203574c9407..d88c6961274cf2e961eec9d1b420dc0621965a6a 100644 (file)
 
 #include "perf.h"
 
-#include "util/parse-options.h"
 #include "util/parse-events.h"
+#include "util/cache.h"
 
 int cmd_list(int argc __used, const char **argv __used, const char *prefix __used)
 {
+       setup_pager();
        print_events();
        return 0;
 }
index 0345aad8eba50c35422062f4337c51f234d66b7a..3d051b9cf25ff18790edbb1cd33a7f644ece2dc0 100644 (file)
@@ -34,7 +34,9 @@ static int                    output;
 static const char              *output_name                    = "perf.data";
 static int                     group                           = 0;
 static unsigned int            realtime_prio                   = 0;
+static int                     raw_samples                     = 0;
 static int                     system_wide                     = 0;
+static int                     profile_cpu                     = -1;
 static pid_t                   target_pid                      = -1;
 static int                     inherit                         = 1;
 static int                     force                           = 0;
@@ -203,46 +205,48 @@ static void sig_atexit(void)
        kill(getpid(), signr);
 }
 
-static void pid_synthesize_comm_event(pid_t pid, int full)
+static pid_t pid_synthesize_comm_event(pid_t pid, int full)
 {
        struct comm_event comm_ev;
        char filename[PATH_MAX];
        char bf[BUFSIZ];
-       int fd;
-       size_t size;
-       char *field, *sep;
+       FILE *fp;
+       size_t size = 0;
        DIR *tasks;
        struct dirent dirent, *next;
+       pid_t tgid = 0;
 
-       snprintf(filename, sizeof(filename), "/proc/%d/stat", pid);
+       snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
 
-       fd = open(filename, O_RDONLY);
-       if (fd < 0) {
+       fp = fopen(filename, "r");
+       if (fd == NULL) {
                /*
                 * We raced with a task exiting - just return:
                 */
                if (verbose)
                        fprintf(stderr, "couldn't open %s\n", filename);
-               return;
-       }
-       if (read(fd, bf, sizeof(bf)) < 0) {
-               fprintf(stderr, "couldn't read %s\n", filename);
-               exit(EXIT_FAILURE);
+               return 0;
        }
-       close(fd);
 
-       /* 9027 (cat) R 6747 9027 6747 34816 9027 ... */
        memset(&comm_ev, 0, sizeof(comm_ev));
-       field = strchr(bf, '(');
-       if (field == NULL)
-               goto out_failure;
-       sep = strchr(++field, ')');
-       if (sep == NULL)
-               goto out_failure;
-       size = sep - field;
-       memcpy(comm_ev.comm, field, size++);
-
-       comm_ev.pid = pid;
+       while (!comm_ev.comm[0] || !comm_ev.pid) {
+               if (fgets(bf, sizeof(bf), fp) == NULL)
+                       goto out_failure;
+
+               if (memcmp(bf, "Name:", 5) == 0) {
+                       char *name = bf + 5;
+                       while (*name && isspace(*name))
+                               ++name;
+                       size = strlen(name) - 1;
+                       memcpy(comm_ev.comm, name, size++);
+               } else if (memcmp(bf, "Tgid:", 5) == 0) {
+                       char *tgids = bf + 5;
+                       while (*tgids && isspace(*tgids))
+                               ++tgids;
+                       tgid = comm_ev.pid = atoi(tgids);
+               }
+       }
+
        comm_ev.header.type = PERF_EVENT_COMM;
        size = ALIGN(size, sizeof(u64));
        comm_ev.header.size = sizeof(comm_ev) - (sizeof(comm_ev.comm) - size);
@@ -251,7 +255,7 @@ static void pid_synthesize_comm_event(pid_t pid, int full)
                comm_ev.tid = pid;
 
                write_output(&comm_ev, comm_ev.header.size);
-               return;
+               goto out_fclose;
        }
 
        snprintf(filename, sizeof(filename), "/proc/%d/task", pid);
@@ -268,7 +272,10 @@ static void pid_synthesize_comm_event(pid_t pid, int full)
                write_output(&comm_ev, comm_ev.header.size);
        }
        closedir(tasks);
-       return;
+
+out_fclose:
+       fclose(fp);
+       return tgid;
 
 out_failure:
        fprintf(stderr, "couldn't get COMM and pgid, malformed %s\n",
@@ -276,7 +283,7 @@ out_failure:
        exit(EXIT_FAILURE);
 }
 
-static void pid_synthesize_mmap_samples(pid_t pid)
+static void pid_synthesize_mmap_samples(pid_t pid, pid_t tgid)
 {
        char filename[PATH_MAX];
        FILE *fp;
@@ -328,7 +335,7 @@ static void pid_synthesize_mmap_samples(pid_t pid)
                        mmap_ev.len -= mmap_ev.start;
                        mmap_ev.header.size = (sizeof(mmap_ev) -
                                               (sizeof(mmap_ev.filename) - size));
-                       mmap_ev.pid = pid;
+                       mmap_ev.pid = tgid;
                        mmap_ev.tid = pid;
 
                        write_output(&mmap_ev, mmap_ev.header.size);
@@ -347,14 +354,14 @@ static void synthesize_all(void)
 
        while (!readdir_r(proc, &dirent, &next) && next) {
                char *end;
-               pid_t pid;
+               pid_t pid, tgid;
 
                pid = strtol(dirent.d_name, &end, 10);
                if (*end) /* only interested in proper numerical dirents */
                        continue;
 
-               pid_synthesize_comm_event(pid, 1);
-               pid_synthesize_mmap_samples(pid);
+               tgid = pid_synthesize_comm_event(pid, 1);
+               pid_synthesize_mmap_samples(pid, tgid);
        }
 
        closedir(proc);
@@ -392,7 +399,7 @@ static void create_counter(int counter, int cpu, pid_t pid)
                                  PERF_FORMAT_TOTAL_TIME_RUNNING |
                                  PERF_FORMAT_ID;
 
-       attr->sample_type       = PERF_SAMPLE_IP | PERF_SAMPLE_TID;
+       attr->sample_type       |= PERF_SAMPLE_IP | PERF_SAMPLE_TID;
 
        if (freq) {
                attr->sample_type       |= PERF_SAMPLE_PERIOD;
@@ -412,6 +419,8 @@ static void create_counter(int counter, int cpu, pid_t pid)
        if (call_graph)
                attr->sample_type       |= PERF_SAMPLE_CALLCHAIN;
 
+       if (raw_samples)
+               attr->sample_type       |= PERF_SAMPLE_RAW;
 
        attr->mmap              = track;
        attr->comm              = track;
@@ -426,6 +435,8 @@ try_again:
 
                if (err == EPERM)
                        die("Permission error - are you root?\n");
+               else if (err ==  ENODEV && profile_cpu != -1)
+                       die("No such device - did you specify an out-of-range profile CPU?\n");
 
                /*
                 * If it's cycles then fall back to hrtimer
@@ -559,16 +570,22 @@ static int __cmd_record(int argc, const char **argv)
                if (pid == -1)
                        pid = getpid();
 
-               open_counters(-1, pid);
-       } else for (i = 0; i < nr_cpus; i++)
-               open_counters(i, target_pid);
+               open_counters(profile_cpu, pid);
+       } else {
+               if (profile_cpu != -1) {
+                       open_counters(profile_cpu, target_pid);
+               } else {
+                       for (i = 0; i < nr_cpus; i++)
+                               open_counters(i, target_pid);
+               }
+       }
 
        if (file_new)
                perf_header__write(header, output);
 
        if (!system_wide) {
-               pid_synthesize_comm_event(pid, 0);
-               pid_synthesize_mmap_samples(pid);
+               pid_t tgid = pid_synthesize_comm_event(pid, 0);
+               pid_synthesize_mmap_samples(pid, tgid);
        } else
                synthesize_all();
 
@@ -636,10 +653,14 @@ static const struct option options[] = {
                    "record events on existing pid"),
        OPT_INTEGER('r', "realtime", &realtime_prio,
                    "collect data with this RT SCHED_FIFO priority"),
+       OPT_BOOLEAN('R', "raw-samples", &raw_samples,
+                   "collect raw sample records from all opened counters"),
        OPT_BOOLEAN('a', "all-cpus", &system_wide,
                            "system-wide collection from all CPUs"),
        OPT_BOOLEAN('A', "append", &append_file,
                            "append to the output file to do incremental profiling"),
+       OPT_INTEGER('C', "profile_cpu", &profile_cpu,
+                           "CPU to profile on"),
        OPT_BOOLEAN('f', "force", &force,
                        "overwrite existing data file"),
        OPT_LONG('c', "count", &default_interval,
index 99274cec0adb7515e00802000445bb548778ee04..b53a60fc12de77115218a275235df61fdb61da09 100644 (file)
@@ -1526,11 +1526,11 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
                more_data += sizeof(u64);
        }
 
-       dprintf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d: %p period: %Ld\n",
+       dprintf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n",
                (void *)(offset + head),
                (void *)(long)(event->header.size),
                event->header.misc,
-               event->ip.pid,
+               event->ip.pid, event->ip.tid,
                (void *)(long)ip,
                (long long)period);
 
@@ -1590,10 +1590,11 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
        if (show & show_mask) {
                struct symbol *sym = resolve_symbol(thread, &map, &dso, &ip);
 
-               if (dso_list && dso && dso->name && !strlist__has_entry(dso_list, dso->name))
+               if (dso_list && (!dso || !dso->name ||
+                                !strlist__has_entry(dso_list, dso->name)))
                        return 0;
 
-               if (sym_list && sym && !strlist__has_entry(sym_list, sym->name))
+               if (sym_list && (!sym || !strlist__has_entry(sym_list, sym->name)))
                        return 0;
 
                if (hist_entry__add(thread, map, dso, sym, ip, chain, level, period)) {
@@ -1612,10 +1613,11 @@ process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
        struct thread *thread = threads__findnew(event->mmap.pid);
        struct map *map = map__new(&event->mmap);
 
-       dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n",
+       dprintf("%p [%p]: PERF_EVENT_MMAP %d/%d: [%p(%p) @ %p]: %s\n",
                (void *)(offset + head),
                (void *)(long)(event->header.size),
                event->mmap.pid,
+               event->mmap.tid,
                (void *)(long)event->mmap.start,
                (void *)(long)event->mmap.len,
                (void *)(long)event->mmap.pgoff,
index 4858d83b3b6746ea50756e58ffcdb90b61f8a5d4..044178408783004c66429f48f75e937d61e32e8a 100644 (file)
@@ -379,6 +379,7 @@ static int parse_tracepoint_event(const char **strp,
                                    struct perf_counter_attr *attr)
 {
        const char *evt_name;
+       char *flags;
        char sys_name[MAX_EVENT_LENGTH];
        char id_buf[4];
        int fd;
@@ -400,6 +401,15 @@ static int parse_tracepoint_event(const char **strp,
        strncpy(sys_name, *strp, sys_length);
        sys_name[sys_length] = '\0';
        evt_name = evt_name + 1;
+
+       flags = strchr(evt_name, ':');
+       if (flags) {
+               *flags = '\0';
+               flags++;
+               if (!strncmp(flags, "record", strlen(flags)))
+                       attr->sample_type |= PERF_SAMPLE_RAW;
+       }
+
        evt_length = strlen(evt_name);
        if (evt_length >= MAX_EVENT_LENGTH)
                return 0;
index f1dcede1430753c6b61f5a9d2b696da206dc16c6..5c0f42e6b33b90ee8960ccb91845ae74da6b725e 100644 (file)
@@ -7,23 +7,8 @@
 #include <gelf.h>
 #include <elf.h>
 
-#ifndef NO_DEMANGLE
-#include <bfd.h>
-#else
-static inline
-char *bfd_demangle(void __used *v, const char __used *c, int __used i)
-{
-       return NULL;
-}
-#endif
-
 const char *sym_hist_filter;
 
-#ifndef DMGL_PARAMS
-#define DMGL_PARAMS      (1 << 0)       /* Include function args */
-#define DMGL_ANSI        (1 << 1)       /* Include const, volatile, etc */
-#endif
-
 enum dso_origin {
        DSO__ORIG_KERNEL = 0,
        DSO__ORIG_JAVA_JIT,
@@ -816,6 +801,8 @@ more:
        }
 out:
        free(name);
+       if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
+               return 0;
        return ret;
 }
 
index 1e003ec2f4b104ad4ce7c55aee22a36bacf0cea5..b53bf0125c1bcaff4d88d2ddc9dd7c766f7dfb57 100644 (file)
@@ -7,6 +7,30 @@
 #include <linux/rbtree.h>
 #include "module.h"
 
+#ifdef HAVE_CPLUS_DEMANGLE
+extern char *cplus_demangle(const char *, int);
+
+static inline char *bfd_demangle(void __used *v, const char *c, int i)
+{
+       return cplus_demangle(c, i);
+}
+#else
+#ifdef NO_DEMANGLE
+static inline char *bfd_demangle(void __used *v, const char __used *c,
+                                int __used i)
+{
+       return NULL;
+}
+#else
+#include <bfd.h>
+#endif
+#endif
+
+#ifndef DMGL_PARAMS
+#define DMGL_PARAMS      (1 << 0)       /* Include function args */
+#define DMGL_ANSI        (1 << 1)       /* Include const, volatile, etc */
+#endif
+
 struct symbol {
        struct rb_node  rb_node;
        u64             start;