]> git.openfabrics.org - ~shefty/rdma-dev.git/commitdiff
Merge branches 'core-urgent-for-linus' and 'irq-urgent-for-linus' of git://git.kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 6 Dec 2011 00:51:21 +0000 (16:51 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 6 Dec 2011 00:51:21 +0000 (16:51 -0800)
* 'core-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  slab, lockdep: Fix silly bug

* 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  genirq: Fix race condition when stopping the irq thread

230 files changed:
Documentation/usb/linux-cdc-acm.inf
Makefile
arch/arm/Kconfig
arch/arm/common/gic.c
arch/arm/common/pl330.c
arch/arm/include/asm/pmu.h
arch/arm/include/asm/topology.h
arch/arm/kernel/entry-armv.S
arch/arm/kernel/kprobes-arm.c
arch/arm/kernel/kprobes-test-arm.c
arch/arm/kernel/kprobes-test-thumb.c
arch/arm/kernel/kprobes-test.h
arch/arm/kernel/perf_event.c
arch/arm/kernel/pmu.c
arch/arm/kernel/process.c
arch/arm/kernel/topology.c
arch/arm/lib/bitops.h
arch/arm/lib/changebit.S
arch/arm/lib/clearbit.S
arch/arm/lib/setbit.S
arch/arm/lib/testchangebit.S
arch/arm/lib/testclearbit.S
arch/arm/lib/testsetbit.S
arch/arm/mm/cache-l2x0.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/mmap.c
arch/s390/include/asm/pgtable.h
arch/s390/kernel/ptrace.c
arch/s390/kernel/setup.c
arch/s390/kernel/signal.c
arch/x86/include/asm/system.h
arch/x86/include/asm/timer.h
arch/x86/kernel/cpu/amd.c
arch/x86/kernel/process.c
arch/x86/xen/setup.c
drivers/firmware/sigma.c
drivers/gpio/Makefile
drivers/gpu/drm/drm_crtc_helper.c
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nouveau_drv.c
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_object.c
drivers/gpu/drm/nouveau/nouveau_sgdma.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nvc0_graph.c
drivers/gpu/drm/nouveau/nvd0_display.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_cs.c
drivers/gpu/drm/radeon/evergreen_reg.h
drivers/gpu/drm/radeon/evergreend.h
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/radeon_acpi.c
drivers/gpu/drm/radeon/rs600.c
drivers/gpu/drm/radeon/rv770.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/i2c/busses/i2c-nuc900.c
drivers/isdn/divert/divert_procfs.c
drivers/isdn/i4l/isdn_net.c
drivers/net/arcnet/Kconfig
drivers/net/bonding/bond_main.c
drivers/net/can/sja1000/peak_pci.c
drivers/net/ethernet/broadcom/b44.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
drivers/net/ethernet/davicom/dm9000.c
drivers/net/ethernet/freescale/Kconfig
drivers/net/ethernet/ibm/ehea/ehea.h
drivers/net/ethernet/ibm/ehea/ehea_main.c
drivers/net/ethernet/ibm/iseries_veth.c
drivers/net/ethernet/jme.c
drivers/net/ethernet/jme.h
drivers/net/ethernet/qlogic/qlge/qlge.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/phy/Kconfig
drivers/net/wireless/p54/p54spi.c
drivers/net/wireless/prism54/isl_ioctl.c
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rtlwifi/ps.c
drivers/net/xen-netback/netback.c
drivers/s390/cio/chsc.c
drivers/s390/cio/cio.h
drivers/s390/cio/css.c
drivers/s390/cio/device.c
drivers/s390/cio/device_fsm.c
drivers/s390/cio/device_ops.c
drivers/s390/cio/io_sch.h
drivers/s390/crypto/ap_bus.c
drivers/spi/spi-nuc900.c
drivers/staging/comedi/comedi_fops.c
drivers/staging/comedi/drivers/usbduxsigma.c
drivers/staging/rts_pstor/rtsx.c
drivers/staging/usbip/vhci_rx.c
drivers/usb/gadget/amd5536udc.c
drivers/usb/gadget/f_serial.c
drivers/usb/gadget/fsl_mxc_udc.c
drivers/usb/gadget/fsl_qe_udc.c
drivers/usb/gadget/fsl_udc_core.c
drivers/usb/gadget/fsl_usb2_udc.h
drivers/usb/gadget/m66592-udc.c
drivers/usb/gadget/net2280.c
drivers/usb/gadget/r8a66597-udc.c
drivers/usb/gadget/s3c-hsotg.c
drivers/usb/gadget/s3c-hsudc.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/whci/qset.c
drivers/usb/host/xhci.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_gadget.c
drivers/usb/renesas_usbhs/mod_gadget.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/option.c
drivers/usb/storage/unusual_devs.h
fs/ocfs2/alloc.c
fs/ocfs2/aops.c
fs/ocfs2/aops.h
fs/ocfs2/cluster/heartbeat.c
fs/ocfs2/cluster/netdebug.c
fs/ocfs2/cluster/tcp.c
fs/ocfs2/cluster/tcp.h
fs/ocfs2/dir.c
fs/ocfs2/dlm/dlmcommon.h
fs/ocfs2/dlm/dlmdomain.c
fs/ocfs2/dlm/dlmlock.c
fs/ocfs2/dlm/dlmmaster.c
fs/ocfs2/dlm/dlmrecovery.c
fs/ocfs2/dlm/dlmthread.c
fs/ocfs2/dlmglue.c
fs/ocfs2/extent_map.c
fs/ocfs2/extent_map.h
fs/ocfs2/file.c
fs/ocfs2/inode.c
fs/ocfs2/inode.h
fs/ocfs2/ioctl.c
fs/ocfs2/journal.c
fs/ocfs2/journal.h
fs/ocfs2/mmap.c
fs/ocfs2/move_extents.c
fs/ocfs2/ocfs2.h
fs/ocfs2/quota_local.c
fs/ocfs2/slot_map.c
fs/ocfs2/stack_o2cb.c
fs/ocfs2/super.c
fs/ocfs2/xattr.c
fs/xfs/xfs_acl.c
fs/xfs/xfs_attr_leaf.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode.h
fs/xfs/xfs_sync.c
include/drm/drm_pciids.h
include/linux/init_task.h
include/linux/netdevice.h
include/linux/pkt_sched.h
include/linux/sigma.h
include/net/dst.h
include/net/dst_ops.h
include/net/inet_sock.h
include/net/inetpeer.h
include/net/netfilter/nf_conntrack_ecache.h
include/net/netns/conntrack.h
include/net/red.h
include/net/route.h
kernel/sched.c
kernel/sched_fair.c
kernel/sched_features.h
kernel/sched_rt.c
mm/slab.c
net/bridge/br_netlink.c
net/bridge/br_stp.c
net/caif/cffrml.c
net/core/dev.c
net/core/dev_addr_lists.c
net/core/neighbour.c
net/core/skbuff.c
net/dccp/ipv4.c
net/decnet/dn_route.c
net/decnet/dn_timer.c
net/ipv4/devinet.c
net/ipv4/igmp.c
net/ipv4/inet_diag.c
net/ipv4/ip_forward.c
net/ipv4/ip_options.c
net/ipv4/netfilter.c
net/ipv4/netfilter/Kconfig
net/ipv4/route.c
net/ipv4/udp.c
net/ipv6/inet6_connection_sock.c
net/ipv6/ipv6_sockglue.c
net/ipv6/ndisc.c
net/ipv6/netfilter/Kconfig
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/l2tp/l2tp_core.c
net/mac80211/agg-tx.c
net/mac80211/debugfs_sta.c
net/mac80211/status.c
net/netfilter/Kconfig
net/netfilter/ipset/ip_set_hash_ipport.c
net/netfilter/ipset/ip_set_hash_ipportip.c
net/netfilter/ipset/ip_set_hash_ipportnet.c
net/netfilter/nf_conntrack_ecache.c
net/netfilter/nf_conntrack_netlink.c
net/netlabel/netlabel_kapi.c
net/sched/sch_red.c
net/sched/sch_teql.c
net/sctp/auth.c
net/unix/af_unix.c
net/wireless/nl80211.c
net/wireless/reg.c
net/xfrm/xfrm_policy.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_sigmatel.c
sound/soc/atmel/Kconfig
sound/soc/atmel/Makefile
sound/soc/atmel/playpaq_wm8510.c [deleted file]
sound/soc/codecs/ad1836.h
sound/soc/codecs/cs4270.c
sound/soc/codecs/cs42l51.c
sound/soc/codecs/max9877.c
sound/soc/codecs/wm8994.c
sound/soc/fsl/mpc8610_hpcd.c
sound/soc/nuc900/nuc900-ac97.c
sound/soc/samsung/smdk_wm8994.c
sound/soc/samsung/speyside.c
sound/soc/soc-core.c
sound/usb/quirks-table.h

index 37a02ce5484176670fde42a5bb915427316587f3..f0ffc27d4c0ac9d52efa62ecc0f775fd877b7387 100644 (file)
@@ -90,10 +90,10 @@ ServiceBinary=%12%\USBSER.sys
 [SourceDisksFiles]
 [SourceDisksNames]
 [DeviceList]
-%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02
+%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02, USB\VID_1D6B&PID_0106&MI_00
 
 [DeviceList.NTamd64]
-%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02
+%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02, USB\VID_1D6B&PID_0106&MI_00
 
 
 ;------------------------------------------------------------------------------
index 3a8f0640cda0e47e985bf7e84e5a0461efb9282c..12aafc20efbd0d610430d3a88df4e6359093cfc1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 2
 SUBLEVEL = 0
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
 NAME = Saber-toothed Squirrel
 
 # *DOCUMENTATION*
index 44789eff983f444c22cd967cbe418f7e50159358..e084b7e981e8ff301aaae64ef3a2dc7e66701247 100644 (file)
@@ -1231,7 +1231,7 @@ config ARM_ERRATA_742231
          capabilities of the processor.
 
 config PL310_ERRATA_588369
-       bool "Clean & Invalidate maintenance operations do not invalidate clean lines"
+       bool "PL310 errata: Clean & Invalidate maintenance operations do not invalidate clean lines"
        depends on CACHE_L2X0
        help
           The PL310 L2 cache controller implements three types of Clean &
@@ -1256,7 +1256,7 @@ config ARM_ERRATA_720789
          entries regardless of the ASID.
 
 config PL310_ERRATA_727915
-       bool "Background Clean & Invalidate by Way operation can cause data corruption"
+       bool "PL310 errata: Background Clean & Invalidate by Way operation can cause data corruption"
        depends on CACHE_L2X0
        help
          PL310 implements the Clean & Invalidate by Way L2 cache maintenance
@@ -1289,8 +1289,8 @@ config ARM_ERRATA_751472
          operation is received by a CPU before the ICIALLUIS has completed,
          potentially leading to corrupted entries in the cache or TLB.
 
-config ARM_ERRATA_753970
-       bool "ARM errata: cache sync operation may be faulty"
+config PL310_ERRATA_753970
+       bool "PL310 errata: cache sync operation may be faulty"
        depends on CACHE_PL310
        help
          This option enables the workaround for the 753970 PL310 (r3p0) erratum.
@@ -1352,6 +1352,18 @@ config ARM_ERRATA_764369
          relevant cache maintenance functions and sets a specific bit
          in the diagnostic control register of the SCU.
 
+config PL310_ERRATA_769419
+       bool "PL310 errata: no automatic Store Buffer drain"
+       depends on CACHE_L2X0
+       help
+         On revisions of the PL310 prior to r3p2, the Store Buffer does
+         not automatically drain. This can cause normal, non-cacheable
+         writes to be retained when the memory system is idle, leading
+         to suboptimal I/O performance for drivers using coherent DMA.
+         This option adds a write barrier to the cpu_idle loop so that,
+         on systems with an outer cache, the store buffer is drained
+         explicitly.
+
 endmenu
 
 source "arch/arm/common/Kconfig"
index 0e6ae470c94f26589c0721a059dfaded9b2f30b1..410a546060a2eecf82859d76c528223e8796f9f4 100644 (file)
@@ -526,7 +526,8 @@ static void __init gic_pm_init(struct gic_chip_data *gic)
                sizeof(u32));
        BUG_ON(!gic->saved_ppi_conf);
 
-       cpu_pm_register_notifier(&gic_notifier_block);
+       if (gic == &gic_data[0])
+               cpu_pm_register_notifier(&gic_notifier_block);
 }
 #else
 static void __init gic_pm_init(struct gic_chip_data *gic)
@@ -581,13 +582,16 @@ void __init gic_init(unsigned int gic_nr, int irq_start,
         * For primary GICs, skip over SGIs.
         * For secondary GICs, skip over PPIs, too.
         */
+       domain->hwirq_base = 32;
        if (gic_nr == 0) {
                gic_cpu_base_addr = cpu_base;
-               domain->hwirq_base = 16;
-               if (irq_start > 0)
-                       irq_start = (irq_start & ~31) + 16;
-       } else
-               domain->hwirq_base = 32;
+
+               if ((irq_start & 31) > 0) {
+                       domain->hwirq_base = 16;
+                       if (irq_start != -1)
+                               irq_start = (irq_start & ~31) + 16;
+               }
+       }
 
        /*
         * Find out how many interrupts are supported.
index 7129cfbdacd6887920cf28994625be7b35f65503..f407a6b35d3dd1e6ad1e72afec38837dcfdd796a 100644 (file)
@@ -1211,8 +1211,8 @@ static inline u32 _prepare_ccr(const struct pl330_reqcfg *rqc)
        ccr |= (rqc->brst_size << CC_SRCBRSTSIZE_SHFT);
        ccr |= (rqc->brst_size << CC_DSTBRSTSIZE_SHFT);
 
-       ccr |= (rqc->dcctl << CC_SRCCCTRL_SHFT);
-       ccr |= (rqc->scctl << CC_DSTCCTRL_SHFT);
+       ccr |= (rqc->scctl << CC_SRCCCTRL_SHFT);
+       ccr |= (rqc->dcctl << CC_DSTCCTRL_SHFT);
 
        ccr |= (rqc->swap << CC_SWAP_SHFT);
 
@@ -1623,6 +1623,11 @@ static inline int _alloc_event(struct pl330_thread *thrd)
        return -1;
 }
 
+static bool _chan_ns(const struct pl330_info *pi, int i)
+{
+       return pi->pcfg.irq_ns & (1 << i);
+}
+
 /* Upon success, returns IdentityToken for the
  * allocated channel, NULL otherwise.
  */
@@ -1647,7 +1652,8 @@ void *pl330_request_channel(const struct pl330_info *pi)
 
        for (i = 0; i < chans; i++) {
                thrd = &pl330->channels[i];
-               if (thrd->free) {
+               if ((thrd->free) && (!_manager_ns(thrd) ||
+                                       _chan_ns(pi, i))) {
                        thrd->ev = _alloc_event(thrd);
                        if (thrd->ev >= 0) {
                                thrd->free = false;
index 71d99b83cdb980178aac275e487c2db081c041fc..0bda22c094a6dd1b70100444d6e29fa1a41688ef 100644 (file)
@@ -55,16 +55,6 @@ reserve_pmu(enum arm_pmu_type type);
 extern void
 release_pmu(enum arm_pmu_type type);
 
-/**
- * init_pmu() - Initialise the PMU.
- *
- * Initialise the system ready for PMU enabling. This should typically set the
- * IRQ affinity and nothing else. The users (oprofile/perf events etc) will do
- * the actual hardware initialisation.
- */
-extern int
-init_pmu(enum arm_pmu_type type);
-
 #else /* CONFIG_CPU_HAS_PMU */
 
 #include <linux/err.h>
index a7e457ed27c31e1185ebe3a0eaa745d88c35029d..58b8b84adcd2cf5f295e6869b68350f9dcadc798 100644 (file)
@@ -25,7 +25,7 @@ extern struct cputopo_arm cpu_topology[NR_CPUS];
 
 void init_cpu_topology(void);
 void store_cpu_topology(unsigned int cpuid);
-const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
+const struct cpumask *cpu_coregroup_mask(int cpu);
 
 #else
 
index 9ad50c4208aebf5aaf7ee245444da5789935b269..b145f16c91bc786db82fcd3cd66ccdee7b740aa4 100644 (file)
@@ -497,7 +497,7 @@ ENDPROC(__und_usr)
        .popsection
        .pushsection __ex_table,"a"
        .long   1b, 4b
-#if __LINUX_ARM_ARCH__ >= 7
+#if CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7
        .long   2b, 4b
        .long   3b, 4b
 #endif
index 9fe8910308af922eda3c17ffee908c99652c1a1f..8a30c89da70ec104d4c1499f3a88a1dc4721e6e0 100644 (file)
@@ -519,10 +519,12 @@ static const union decode_item arm_cccc_0000_____1001_table[] = {
 static const union decode_item arm_cccc_0001_____1001_table[] = {
        /* Synchronization primitives                                   */
 
+#if __LINUX_ARM_ARCH__ < 6
+       /* Deprecated on ARMv6 and may be UNDEFINED on v7               */
        /* SMP/SWPB             cccc 0001 0x00 xxxx xxxx xxxx 1001 xxxx */
        DECODE_EMULATEX (0x0fb000f0, 0x01000090, emulate_rd12rn16rm0_rwflags_nopc,
                                                 REGS(NOPC, NOPC, 0, 0, NOPC)),
-
+#endif
        /* LDREX/STREX{,D,B,H}  cccc 0001 1xxx xxxx xxxx xxxx 1001 xxxx */
        /* And unallocated instructions...                              */
        DECODE_END
index fc82de8bdcce1081801cece62fa3d97480d520e1..ba32b393b3f0c514c83799687348d52655bfe1da 100644 (file)
@@ -427,18 +427,25 @@ void kprobe_arm_test_cases(void)
 
        TEST_GROUP("Synchronization primitives")
 
-       /*
-        * Use hard coded constants for SWP instructions to avoid warnings
-        * about deprecated instructions.
-        */
-       TEST_RP( ".word 0xe108e097 @ swp        lr, r",7,VAL2,", [r",8,0,"]")
-       TEST_R(  ".word 0x610d0091 @ swpvs      r0, r",1,VAL1,", [sp]")
-       TEST_RP( ".word 0xe10cd09e @ swp        sp, r",14,VAL2,", [r",12,13*4,"]")
+#if __LINUX_ARM_ARCH__ < 6
+       TEST_RP("swp    lr, r",7,VAL2,", [r",8,0,"]")
+       TEST_R( "swpvs  r0, r",1,VAL1,", [sp]")
+       TEST_RP("swp    sp, r",14,VAL2,", [r",12,13*4,"]")
+#else
+       TEST_UNSUPPORTED(".word 0xe108e097 @ swp        lr, r7, [r8]")
+       TEST_UNSUPPORTED(".word 0x610d0091 @ swpvs      r0, r1, [sp]")
+       TEST_UNSUPPORTED(".word 0xe10cd09e @ swp        sp, r14 [r12]")
+#endif
        TEST_UNSUPPORTED(".word 0xe102f091 @ swp pc, r1, [r2]")
        TEST_UNSUPPORTED(".word 0xe102009f @ swp r0, pc, [r2]")
        TEST_UNSUPPORTED(".word 0xe10f0091 @ swp r0, r1, [pc]")
-       TEST_RP( ".word 0xe148e097 @ swpb       lr, r",7,VAL2,", [r",8,0,"]")
-       TEST_R(  ".word 0x614d0091 @ swpvsb     r0, r",1,VAL1,", [sp]")
+#if __LINUX_ARM_ARCH__ < 6
+       TEST_RP("swpb   lr, r",7,VAL2,", [r",8,0,"]")
+       TEST_R( "swpvsb r0, r",1,VAL1,", [sp]")
+#else
+       TEST_UNSUPPORTED(".word 0xe148e097 @ swpb       lr, r7, [r8]")
+       TEST_UNSUPPORTED(".word 0x614d0091 @ swpvsb     r0, r1, [sp]")
+#endif
        TEST_UNSUPPORTED(".word 0xe142f091 @ swpb pc, r1, [r2]")
 
        TEST_UNSUPPORTED(".word 0xe1100090") /* Unallocated space */
@@ -550,7 +557,7 @@ void kprobe_arm_test_cases(void)
        TEST_RPR(  "strccd      r",8, VAL2,", [r",13,0, ", r",12,48,"]")
        TEST_RPR(  "strd        r",4, VAL1,", [r",2, 24,", r",3, 48,"]!")
        TEST_RPR(  "strcsd      r",12,VAL2,", [r",11,48,", -r",10,24,"]!")
-       TEST_RPR(  "strd        r",2, VAL1,", [r",3, 24,"], r",4,48,"")
+       TEST_RPR(  "strd        r",2, VAL1,", [r",5, 24,"], r",4,48,"")
        TEST_RPR(  "strd        r",10,VAL2,", [r",9, 48,"], -r",7,24,"")
        TEST_UNSUPPORTED(".word 0xe1afc0fa      @ strd r12, [pc, r10]!")
 
index 5e726c31c45aef5084a7e7ddf07bb1762ed4c403..5d8b857922220b4be4e9babf6e050c94625a56eb 100644 (file)
@@ -222,8 +222,8 @@ void kprobe_thumb16_test_cases(void)
 DONT_TEST_IN_ITBLOCK(
        TEST_BF_R(  "cbnz       r",0,0, ", 2f")
        TEST_BF_R(  "cbz        r",2,-1,", 2f")
-       TEST_BF_RX( "cbnz       r",4,1, ", 2f",0x20)
-       TEST_BF_RX( "cbz        r",7,0, ", 2f",0x40)
+       TEST_BF_RX( "cbnz       r",4,1, ", 2f", SPACE_0x20)
+       TEST_BF_RX( "cbz        r",7,0, ", 2f", SPACE_0x40)
 )
        TEST_R("sxth    r0, r",7, HH1,"")
        TEST_R("sxth    r7, r",0, HH2,"")
@@ -246,7 +246,7 @@ DONT_TEST_IN_ITBLOCK(
        TESTCASE_START(code)            \
        TEST_ARG_PTR(13, offset)        \
        TEST_ARG_END("")                \
-       TEST_BRANCH_F(code,0)           \
+       TEST_BRANCH_F(code)             \
        TESTCASE_END
 
        TEST("push      {r0}")
@@ -319,8 +319,8 @@ CONDITION_INSTRUCTIONS(8,
 
        TEST_BF(  "b    2f")
        TEST_BB(  "b    2b")
-       TEST_BF_X("b    2f", 0x400)
-       TEST_BB_X("b    2b", 0x400)
+       TEST_BF_X("b    2f", SPACE_0x400)
+       TEST_BB_X("b    2b", SPACE_0x400)
 
        TEST_GROUP("Testing instructions in IT blocks")
 
@@ -746,7 +746,7 @@ CONDITION_INSTRUCTIONS(22,
        TEST_BB("bne.w  2b")
        TEST_BF("bgt.w  2f")
        TEST_BB("blt.w  2b")
-       TEST_BF_X("bpl.w        2f",0x1000)
+       TEST_BF_X("bpl.w        2f", SPACE_0x1000)
 )
 
        TEST_UNSUPPORTED("msr   cpsr, r0")
@@ -786,11 +786,11 @@ CONDITION_INSTRUCTIONS(22,
 
        TEST_BF(  "b.w  2f")
        TEST_BB(  "b.w  2b")
-       TEST_BF_X("b.w  2f", 0x1000)
+       TEST_BF_X("b.w  2f", SPACE_0x1000)
 
        TEST_BF(  "bl.w 2f")
        TEST_BB(  "bl.w 2b")
-       TEST_BB_X("bl.w 2b", 0x1000)
+       TEST_BB_X("bl.w 2b", SPACE_0x1000)
 
        TEST_X( "blx    __dummy_arm_subroutine",
                ".arm                           \n\t"
index 0dc5d77b9356bcd86b4b0c087bf642bc6396e06e..e28a869b1ae4b7be5abfb7d088c3214bfe2caab7 100644 (file)
@@ -149,23 +149,31 @@ struct test_arg_end {
        "1:     "instruction"                           \n\t"   \
        "       nop                                     \n\t"
 
-#define TEST_BRANCH_F(instruction, xtra_dist)                  \
+#define TEST_BRANCH_F(instruction)                             \
        TEST_INSTRUCTION(instruction)                           \
-       ".if "#xtra_dist"                               \n\t"   \
        "       b       99f                             \n\t"   \
-       ".space "#xtra_dist"                            \n\t"   \
-       ".endif                                         \n\t"   \
+       "2:     nop                                     \n\t"
+
+#define TEST_BRANCH_B(instruction)                             \
+       "       b       50f                             \n\t"   \
+       "       b       99f                             \n\t"   \
+       "2:     nop                                     \n\t"   \
+       "       b       99f                             \n\t"   \
+       TEST_INSTRUCTION(instruction)
+
+#define TEST_BRANCH_FX(instruction, codex)                     \
+       TEST_INSTRUCTION(instruction)                           \
+       "       b       99f                             \n\t"   \
+       codex"                                          \n\t"   \
        "       b       99f                             \n\t"   \
        "2:     nop                                     \n\t"
 
-#define TEST_BRANCH_B(instruction, xtra_dist)                  \
+#define TEST_BRANCH_BX(instruction, codex)                     \
        "       b       50f                             \n\t"   \
        "       b       99f                             \n\t"   \
        "2:     nop                                     \n\t"   \
        "       b       99f                             \n\t"   \
-       ".if "#xtra_dist"                               \n\t"   \
-       ".space "#xtra_dist"                            \n\t"   \
-       ".endif                                         \n\t"   \
+       codex"                                          \n\t"   \
        TEST_INSTRUCTION(instruction)
 
 #define TESTCASE_END                                           \
@@ -301,47 +309,60 @@ struct test_arg_end {
        TESTCASE_START(code1 #reg1 code2)       \
        TEST_ARG_PTR(reg1, val1)                \
        TEST_ARG_END("")                        \
-       TEST_BRANCH_F(code1 #reg1 code2, 0)     \
+       TEST_BRANCH_F(code1 #reg1 code2)        \
        TESTCASE_END
 
-#define TEST_BF_X(code, xtra_dist)             \
+#define TEST_BF(code)                          \
        TESTCASE_START(code)                    \
        TEST_ARG_END("")                        \
-       TEST_BRANCH_F(code, xtra_dist)          \
+       TEST_BRANCH_F(code)                     \
        TESTCASE_END
 
-#define TEST_BB_X(code, xtra_dist)             \
+#define TEST_BB(code)                          \
        TESTCASE_START(code)                    \
        TEST_ARG_END("")                        \
-       TEST_BRANCH_B(code, xtra_dist)          \
+       TEST_BRANCH_B(code)                     \
        TESTCASE_END
 
-#define TEST_BF_RX(code1, reg, val, code2, xtra_dist)  \
-       TESTCASE_START(code1 #reg code2)                \
-       TEST_ARG_REG(reg, val)                          \
-       TEST_ARG_END("")                                \
-       TEST_BRANCH_F(code1 #reg code2, xtra_dist)      \
+#define TEST_BF_R(code1, reg, val, code2)      \
+       TESTCASE_START(code1 #reg code2)        \
+       TEST_ARG_REG(reg, val)                  \
+       TEST_ARG_END("")                        \
+       TEST_BRANCH_F(code1 #reg code2)         \
        TESTCASE_END
 
-#define TEST_BB_RX(code1, reg, val, code2, xtra_dist)  \
-       TESTCASE_START(code1 #reg code2)                \
-       TEST_ARG_REG(reg, val)                          \
-       TEST_ARG_END("")                                \
-       TEST_BRANCH_B(code1 #reg code2, xtra_dist)      \
+#define TEST_BB_R(code1, reg, val, code2)      \
+       TESTCASE_START(code1 #reg code2)        \
+       TEST_ARG_REG(reg, val)                  \
+       TEST_ARG_END("")                        \
+       TEST_BRANCH_B(code1 #reg code2)         \
        TESTCASE_END
 
-#define TEST_BF(code)  TEST_BF_X(code, 0)
-#define TEST_BB(code)  TEST_BB_X(code, 0)
-
-#define TEST_BF_R(code1, reg, val, code2) TEST_BF_RX(code1, reg, val, code2, 0)
-#define TEST_BB_R(code1, reg, val, code2) TEST_BB_RX(code1, reg, val, code2, 0)
-
 #define TEST_BF_RR(code1, reg1, val1, code2, reg2, val2, code3)        \
        TESTCASE_START(code1 #reg1 code2 #reg2 code3)           \
        TEST_ARG_REG(reg1, val1)                                \
        TEST_ARG_REG(reg2, val2)                                \
        TEST_ARG_END("")                                        \
-       TEST_BRANCH_F(code1 #reg1 code2 #reg2 code3, 0)         \
+       TEST_BRANCH_F(code1 #reg1 code2 #reg2 code3)            \
+       TESTCASE_END
+
+#define TEST_BF_X(code, codex)                 \
+       TESTCASE_START(code)                    \
+       TEST_ARG_END("")                        \
+       TEST_BRANCH_FX(code, codex)             \
+       TESTCASE_END
+
+#define TEST_BB_X(code, codex)                 \
+       TESTCASE_START(code)                    \
+       TEST_ARG_END("")                        \
+       TEST_BRANCH_BX(code, codex)             \
+       TESTCASE_END
+
+#define TEST_BF_RX(code1, reg, val, code2, codex)      \
+       TESTCASE_START(code1 #reg code2)                \
+       TEST_ARG_REG(reg, val)                          \
+       TEST_ARG_END("")                                \
+       TEST_BRANCH_FX(code1 #reg code2, codex)         \
        TESTCASE_END
 
 #define TEST_X(code, codex)                    \
@@ -372,6 +393,25 @@ struct test_arg_end {
        TESTCASE_END
 
 
+/*
+ * Macros for defining space directives spread over multiple lines.
+ * These are required so the compiler guesses better the length of inline asm
+ * code and will spill the literal pool early enough to avoid generating PC
+ * relative loads with out of range offsets.
+ */
+#define TWICE(x)       x x
+#define SPACE_0x8      TWICE(".space 4\n\t")
+#define SPACE_0x10     TWICE(SPACE_0x8)
+#define SPACE_0x20     TWICE(SPACE_0x10)
+#define SPACE_0x40     TWICE(SPACE_0x20)
+#define SPACE_0x80     TWICE(SPACE_0x40)
+#define SPACE_0x100    TWICE(SPACE_0x80)
+#define SPACE_0x200    TWICE(SPACE_0x100)
+#define SPACE_0x400    TWICE(SPACE_0x200)
+#define SPACE_0x800    TWICE(SPACE_0x400)
+#define SPACE_0x1000   TWICE(SPACE_0x800)
+
+
 /* Various values used in test cases... */
 #define N(val) (val ^ 0xffffffff)
 #define VAL1   0x12345678
index 24e2347be6b1043ad7cf87f70ab88fe6e9a270c9..c475379199b1d149adc4f8e33e00f1d544e4b595 100644 (file)
@@ -343,8 +343,14 @@ validate_group(struct perf_event *event)
 {
        struct perf_event *sibling, *leader = event->group_leader;
        struct pmu_hw_events fake_pmu;
+       DECLARE_BITMAP(fake_used_mask, ARMPMU_MAX_HWEVENTS);
 
-       memset(&fake_pmu, 0, sizeof(fake_pmu));
+       /*
+        * Initialise the fake PMU. We only need to populate the
+        * used_mask for the purposes of validation.
+        */
+       memset(fake_used_mask, 0, sizeof(fake_used_mask));
+       fake_pmu.used_mask = fake_used_mask;
 
        if (!validate_event(&fake_pmu, leader))
                return -ENOSPC;
@@ -396,6 +402,9 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
        int i, err, irq, irqs;
        struct platform_device *pmu_device = armpmu->plat_device;
 
+       if (!pmu_device)
+               return -ENODEV;
+
        err = reserve_pmu(armpmu->type);
        if (err) {
                pr_warning("unable to reserve pmu\n");
index 2c3407ee857675242c874f49adaf9d26339f79bf..2334bf8a650a16a35d5849a4b6c309d5f19eb1f1 100644 (file)
@@ -33,3 +33,4 @@ release_pmu(enum arm_pmu_type type)
 {
        clear_bit_unlock(type, pmu_lock);
 }
+EXPORT_SYMBOL_GPL(release_pmu);
index 75316f0dd02ae3b0be19e10a982f6a5c7e606ff3..3d0c6fb74ae4efe521cfc563ea11e0fa9738d465 100644 (file)
@@ -192,6 +192,9 @@ void cpu_idle(void)
 #endif
 
                        local_irq_disable();
+#ifdef CONFIG_PL310_ERRATA_769419
+                       wmb();
+#endif
                        if (hlt_counter) {
                                local_irq_enable();
                                cpu_relax();
index 1040c00405d0f362916c77030249fff754eda5e8..8200deaa14f680b553bdea41652fac0aaa58e23a 100644 (file)
@@ -43,7 +43,7 @@
 
 struct cputopo_arm cpu_topology[NR_CPUS];
 
-const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
+const struct cpumask *cpu_coregroup_mask(int cpu)
 {
        return &cpu_topology[cpu].core_sibling;
 }
index 10d868a5a48135840278022e153f3610b0b7a640..d6408d1ee543fe5e3ceabbcda01b25efb07676ba 100644 (file)
@@ -1,5 +1,9 @@
+#include <asm/unwind.h>
+
 #if __LINUX_ARM_ARCH__ >= 6
-       .macro  bitop, instr
+       .macro  bitop, name, instr
+ENTRY( \name           )
+UNWIND(        .fnstart        )
        ands    ip, r1, #3
        strneb  r1, [ip]                @ assert word-aligned
        mov     r2, #1
        cmp     r0, #0
        bne     1b
        bx      lr
+UNWIND(        .fnend          )
+ENDPROC(\name          )
        .endm
 
-       .macro  testop, instr, store
+       .macro  testop, name, instr, store
+ENTRY( \name           )
+UNWIND(        .fnstart        )
        ands    ip, r1, #3
        strneb  r1, [ip]                @ assert word-aligned
        mov     r2, #1
        cmp     r0, #0
        movne   r0, #1
 2:     bx      lr
+UNWIND(        .fnend          )
+ENDPROC(\name          )
        .endm
 #else
-       .macro  bitop, instr
+       .macro  bitop, name, instr
+ENTRY( \name           )
+UNWIND(        .fnstart        )
        ands    ip, r1, #3
        strneb  r1, [ip]                @ assert word-aligned
        and     r2, r0, #31
@@ -49,6 +61,8 @@
        str     r2, [r1, r0, lsl #2]
        restore_irqs ip
        mov     pc, lr
+UNWIND(        .fnend          )
+ENDPROC(\name          )
        .endm
 
 /**
@@ -59,7 +73,9 @@
  * Note: we can trivially conditionalise the store instruction
  * to avoid dirtying the data cache.
  */
-       .macro  testop, instr, store
+       .macro  testop, name, instr, store
+ENTRY( \name           )
+UNWIND(        .fnstart        )
        ands    ip, r1, #3
        strneb  r1, [ip]                @ assert word-aligned
        and     r3, r0, #31
@@ -73,5 +89,7 @@
        moveq   r0, #0
        restore_irqs ip
        mov     pc, lr
+UNWIND(        .fnend          )
+ENDPROC(\name          )
        .endm
 #endif
index 68ed5b62e83976d906bad4409fdabda385caaf96..f4027862172f8a4f1082ae06d7568615f3e5ad45 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_change_bit)
-       bitop   eor
-ENDPROC(_change_bit)
+bitop  _change_bit, eor
index 4c04c3b51eeb0d11bc3b755044b0a63ca6f0db1b..f6b75fb64d30557c5b22655adec3ba2bd34b0c07 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_clear_bit)
-       bitop   bic
-ENDPROC(_clear_bit)
+bitop  _clear_bit, bic
index bbee5c66a23e177494875e5db4fc19da97ed0d73..618fedae4b370aac8b65c2a39ae51046b0ff711a 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                .text
 
-ENTRY(_set_bit)
-       bitop   orr
-ENDPROC(_set_bit)
+bitop  _set_bit, orr
index 15a4d431f229440979aaf179fd423eb647b8da0f..4becdc3a59cbb60717bae345ec7b3f58243abdb6 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_change_bit)
-       testop  eor, str
-ENDPROC(_test_and_change_bit)
+testop _test_and_change_bit, eor, str
index 521b66b5b95da197fa661f142547414399a0af59..918841dcce7ad57ef5e880f1c09547404070fbe5 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_clear_bit)
-       testop  bicne, strne
-ENDPROC(_test_and_clear_bit)
+testop _test_and_clear_bit, bicne, strne
index 1c98cc2185bb0885ae0cac805193f52d34345608..8d1b2fe9e4873ba8d53ba75773a7e30e92292b7c 100644 (file)
@@ -12,6 +12,4 @@
 #include "bitops.h"
                 .text
 
-ENTRY(_test_and_set_bit)
-       testop  orreq, streq
-ENDPROC(_test_and_set_bit)
+testop _test_and_set_bit, orreq, streq
index 8ac9e9f84790bb946716016607478ad97711376d..b1e192ba8c2450cb75a8118f86f8b650be284c82 100644 (file)
@@ -61,7 +61,7 @@ static inline void cache_sync(void)
 {
        void __iomem *base = l2x0_base;
 
-#ifdef CONFIG_ARM_ERRATA_753970
+#ifdef CONFIG_PL310_ERRATA_753970
        /* write to an unmmapped register */
        writel_relaxed(0, base + L2X0_DUMMY_REG);
 #else
index e4e7f6cba1ab4823fdbf0fe7ab2109bf6df89ed7..1aa664a1999fce45c2548726b50b6fa924608ec2 100644 (file)
@@ -168,7 +168,7 @@ static int __init consistent_init(void)
        pte_t *pte;
        int i = 0;
        unsigned long base = consistent_base;
-       unsigned long num_ptes = (CONSISTENT_END - base) >> PGDIR_SHIFT;
+       unsigned long num_ptes = (CONSISTENT_END - base) >> PMD_SHIFT;
 
        consistent_pte = kmalloc(num_ptes * sizeof(pte_t), GFP_KERNEL);
        if (!consistent_pte) {
@@ -332,6 +332,15 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
        struct page *page;
        void *addr;
 
+       /*
+        * Following is a work-around (a.k.a. hack) to prevent pages
+        * with __GFP_COMP being passed to split_page() which cannot
+        * handle them.  The real problem is that this flag probably
+        * should be 0 on ARM as it is not supported on this
+        * platform; see CONFIG_HUGETLBFS.
+        */
+       gfp &= ~(__GFP_COMP);
+
        *handle = ~0;
        size = PAGE_ALIGN(size);
 
index 74be05f3e03ac58be921aff208c6f6aa460ab683..44b628e4d6ea9c0121acf892ffbcfb30d0fc40ad 100644 (file)
@@ -9,8 +9,7 @@
 #include <linux/io.h>
 #include <linux/personality.h>
 #include <linux/random.h>
-#include <asm/cputype.h>
-#include <asm/system.h>
+#include <asm/cachetype.h>
 
 #define COLOUR_ALIGN(addr,pgoff)               \
        ((((addr)+SHMLBA-1)&~(SHMLBA-1)) +      \
@@ -32,25 +31,15 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma;
        unsigned long start_addr;
-#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
-       unsigned int cache_type;
-       int do_align = 0, aliasing = 0;
+       int do_align = 0;
+       int aliasing = cache_is_vipt_aliasing();
 
        /*
         * We only need to do colour alignment if either the I or D
-        * caches alias.  This is indicated by bits 9 and 21 of the
-        * cache type register.
+        * caches alias.
         */
-       cache_type = read_cpuid_cachetype();
-       if (cache_type != read_cpuid_id()) {
-               aliasing = (cache_type | cache_type >> 12) & (1 << 11);
-               if (aliasing)
-                       do_align = filp || flags & MAP_SHARED;
-       }
-#else
-#define do_align 0
-#define aliasing 0
-#endif
+       if (aliasing)
+               do_align = filp || (flags & MAP_SHARED);
 
        /*
         * We enforce the MAP_FIXED case.
index 524d23b8610ceb65c42661a97e79226125dbadf3..4f289ff0b7fe27b7de54d8886b6aee0b8890066f 100644 (file)
@@ -599,10 +599,10 @@ static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste)
        skey = page_get_storage_key(address);
        bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED);
        /* Clear page changed & referenced bit in the storage key */
-       if (bits) {
-               skey ^= bits;
-               page_set_storage_key(address, skey, 1);
-       }
+       if (bits & _PAGE_CHANGED)
+               page_set_storage_key(address, skey ^ bits, 1);
+       else if (bits)
+               page_reset_referenced(address);
        /* Transfer page changed & referenced bit to guest bits in pgste */
        pgste_val(pgste) |= bits << 48;         /* RCP_GR_BIT & RCP_GC_BIT */
        /* Get host changed & referenced bits from pgste */
index 450931a45b684b2044106921a66a4702e1eb93f1..573bc29551ef471fee58b89d02df0ea0ff956503 100644 (file)
@@ -296,13 +296,6 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
                     ((data & PSW_MASK_EA) && !(data & PSW_MASK_BA))))
                        /* Invalid psw mask. */
                        return -EINVAL;
-               if (addr == (addr_t) &dummy->regs.psw.addr)
-                       /*
-                        * The debugger changed the instruction address,
-                        * reset system call restart, see signal.c:do_signal
-                        */
-                       task_thread_info(child)->system_call = 0;
-
                *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;
 
        } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
@@ -614,11 +607,6 @@ static int __poke_user_compat(struct task_struct *child,
                        /* Transfer 31 bit amode bit to psw mask. */
                        regs->psw.mask = (regs->psw.mask & ~PSW_MASK_BA) |
                                (__u64)(tmp & PSW32_ADDR_AMODE);
-                       /*
-                        * The debugger changed the instruction address,
-                        * reset system call restart, see signal.c:do_signal
-                        */
-                       task_thread_info(child)->system_call = 0;
                } else {
                        /* gpr 0-15 */
                        *(__u32*)((addr_t) &regs->psw + addr*2 + 4) = tmp;
@@ -905,6 +893,14 @@ static int s390_last_break_get(struct task_struct *target,
        return 0;
 }
 
+static int s390_last_break_set(struct task_struct *target,
+                              const struct user_regset *regset,
+                              unsigned int pos, unsigned int count,
+                              const void *kbuf, const void __user *ubuf)
+{
+       return 0;
+}
+
 #endif
 
 static int s390_system_call_get(struct task_struct *target,
@@ -951,6 +947,7 @@ static const struct user_regset s390_regsets[] = {
                .size = sizeof(long),
                .align = sizeof(long),
                .get = s390_last_break_get,
+               .set = s390_last_break_set,
        },
 #endif
        [REGSET_SYSTEM_CALL] = {
@@ -1116,6 +1113,14 @@ static int s390_compat_last_break_get(struct task_struct *target,
        return 0;
 }
 
+static int s390_compat_last_break_set(struct task_struct *target,
+                                     const struct user_regset *regset,
+                                     unsigned int pos, unsigned int count,
+                                     const void *kbuf, const void __user *ubuf)
+{
+       return 0;
+}
+
 static const struct user_regset s390_compat_regsets[] = {
        [REGSET_GENERAL] = {
                .core_note_type = NT_PRSTATUS,
@@ -1139,6 +1144,7 @@ static const struct user_regset s390_compat_regsets[] = {
                .size = sizeof(long),
                .align = sizeof(long),
                .get = s390_compat_last_break_get,
+               .set = s390_compat_last_break_set,
        },
        [REGSET_SYSTEM_CALL] = {
                .core_note_type = NT_S390_SYSTEM_CALL,
index e58a462949b164ea90c5697696b9ccec47bb7ff4..e54c4ff8abaaa3d1a34efd34decd0d12c713e4ef 100644 (file)
@@ -579,7 +579,7 @@ static unsigned long __init find_crash_base(unsigned long crash_size,
                *msg = "first memory chunk must be at least crashkernel size";
                return 0;
        }
-       if (is_kdump_kernel() && (crash_size == OLDMEM_SIZE))
+       if (OLDMEM_BASE && crash_size == OLDMEM_SIZE)
                return OLDMEM_BASE;
 
        for (i = MEMORY_CHUNKS - 1; i >= 0; i--) {
index 05a85bc14c98a2556e86bf40cec7e76de2dc2423..7f6f9f35454518f091e4fb86e3d39e46c8aaf391 100644 (file)
@@ -460,9 +460,9 @@ void do_signal(struct pt_regs *regs)
                                                     regs->svc_code >> 16);
                                break;
                        }
-                       /* No longer in a system call */
-                       clear_thread_flag(TIF_SYSCALL);
                }
+               /* No longer in a system call */
+               clear_thread_flag(TIF_SYSCALL);
 
                if ((is_compat_task() ?
                     handle_signal32(signr, &ka, &info, oldset, regs) :
@@ -486,6 +486,7 @@ void do_signal(struct pt_regs *regs)
        }
 
        /* No handlers present - check for system call restart */
+       clear_thread_flag(TIF_SYSCALL);
        if (current_thread_info()->system_call) {
                regs->svc_code = current_thread_info()->system_call;
                switch (regs->gprs[2]) {
@@ -500,9 +501,6 @@ void do_signal(struct pt_regs *regs)
                        regs->gprs[2] = regs->orig_gpr2;
                        set_thread_flag(TIF_SYSCALL);
                        break;
-               default:
-                       clear_thread_flag(TIF_SYSCALL);
-                       break;
                }
        }
 
index c2ff2a1d845e402249e44a70e41459805c3faaa8..2d2f01ce6dcbf1a9c8b72ebef77a159e1b3a5b1a 100644 (file)
@@ -401,6 +401,7 @@ extern unsigned long arch_align_stack(unsigned long sp);
 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
 
 void default_idle(void);
+bool set_pm_idle_to_default(void);
 
 void stop_this_cpu(void *dummy);
 
index fa7b9176b76cb33820034403fd8f4a50dc49709c..431793e5d4846f23bf5947f933fdaf9f5ae1987a 100644 (file)
@@ -32,6 +32,22 @@ extern int no_timer_check;
  *  (mathieu.desnoyers@polymtl.ca)
  *
  *                     -johnstul@us.ibm.com "math is hard, lets go shopping!"
+ *
+ * In:
+ *
+ * ns = cycles * cyc2ns_scale / SC
+ *
+ * Although we may still have enough bits to store the value of ns,
+ * in some cases, we may not have enough bits to store cycles * cyc2ns_scale,
+ * leading to an incorrect result.
+ *
+ * To avoid this, we can decompose 'cycles' into quotient and remainder
+ * of division by SC.  Then,
+ *
+ * ns = (quot * SC + rem) * cyc2ns_scale / SC
+ *    = quot * cyc2ns_scale + (rem * cyc2ns_scale) / SC
+ *
+ *                     - sqazi@google.com
  */
 
 DECLARE_PER_CPU(unsigned long, cyc2ns);
@@ -41,9 +57,14 @@ DECLARE_PER_CPU(unsigned long long, cyc2ns_offset);
 
 static inline unsigned long long __cycles_2_ns(unsigned long long cyc)
 {
+       unsigned long long quot;
+       unsigned long long rem;
        int cpu = smp_processor_id();
        unsigned long long ns = per_cpu(cyc2ns_offset, cpu);
-       ns += cyc * per_cpu(cyc2ns, cpu) >> CYC2NS_SCALE_FACTOR;
+       quot = (cyc >> CYC2NS_SCALE_FACTOR);
+       rem = cyc & ((1ULL << CYC2NS_SCALE_FACTOR) - 1);
+       ns += quot * per_cpu(cyc2ns, cpu) +
+               ((rem * per_cpu(cyc2ns, cpu)) >> CYC2NS_SCALE_FACTOR);
        return ns;
 }
 
index c7e46cb353279080f2b1f67b34e283f0086a5e83..0bab2b18bb2099c4290f046bb210035b05083869 100644 (file)
@@ -442,8 +442,6 @@ static void __cpuinit bsp_init_amd(struct cpuinfo_x86 *c)
 
 static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
 {
-       u32 dummy;
-
        early_init_amd_mc(c);
 
        /*
@@ -473,12 +471,12 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c)
                        set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
        }
 #endif
-
-       rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
 }
 
 static void __cpuinit init_amd(struct cpuinfo_x86 *c)
 {
+       u32 dummy;
+
 #ifdef CONFIG_SMP
        unsigned long long value;
 
@@ -657,6 +655,8 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
                        checking_wrmsrl(MSR_AMD64_MCx_MASK(4), mask);
                }
        }
+
+       rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
 }
 
 #ifdef CONFIG_X86_32
index b9b3b1a51643931a0405a1c0f9cc5b62eec43b1f..ee5d4fbd53b4bac72d19e3aa3000e77467f0c25e 100644 (file)
@@ -403,6 +403,14 @@ void default_idle(void)
 EXPORT_SYMBOL(default_idle);
 #endif
 
+bool set_pm_idle_to_default(void)
+{
+       bool ret = !!pm_idle;
+
+       pm_idle = default_idle;
+
+       return ret;
+}
 void stop_this_cpu(void *dummy)
 {
        local_irq_disable();
index 38d0af4fefec19f52d5e724c8f08102d391dc2e6..1093f80c162d24e5e455d760a5b77e1b16f800c5 100644 (file)
@@ -410,6 +410,6 @@ void __init xen_arch_setup(void)
 #endif
        disable_cpuidle();
        boot_option_idle_override = IDLE_HALT;
-
+       WARN_ON(set_pm_idle_to_default());
        fiddle_vdso();
 }
index f10fc521951b17491348f0cd0fbb1f3013e31eae..1eedb6f7fdabe46efa082039818bef6f31fe1591 100644 (file)
 #include <linux/module.h>
 #include <linux/sigma.h>
 
-/* Return: 0==OK, <0==error, =1 ==no more actions */
+static size_t sigma_action_size(struct sigma_action *sa)
+{
+       size_t payload = 0;
+
+       switch (sa->instr) {
+       case SIGMA_ACTION_WRITEXBYTES:
+       case SIGMA_ACTION_WRITESINGLE:
+       case SIGMA_ACTION_WRITESAFELOAD:
+               payload = sigma_action_len(sa);
+               break;
+       default:
+               break;
+       }
+
+       payload = ALIGN(payload, 2);
+
+       return payload + sizeof(struct sigma_action);
+}
+
+/*
+ * Returns a negative error value in case of an error, 0 if processing of
+ * the firmware should be stopped after this action, 1 otherwise.
+ */
 static int
-process_sigma_action(struct i2c_client *client, struct sigma_firmware *ssfw)
+process_sigma_action(struct i2c_client *client, struct sigma_action *sa)
 {
-       struct sigma_action *sa = (void *)(ssfw->fw->data + ssfw->pos);
        size_t len = sigma_action_len(sa);
-       int ret = 0;
+       int ret;
 
        pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__,
                sa->instr, sa->addr, len);
@@ -29,44 +50,50 @@ process_sigma_action(struct i2c_client *client, struct sigma_firmware *ssfw)
        case SIGMA_ACTION_WRITEXBYTES:
        case SIGMA_ACTION_WRITESINGLE:
        case SIGMA_ACTION_WRITESAFELOAD:
-               if (ssfw->fw->size < ssfw->pos + len)
-                       return -EINVAL;
                ret = i2c_master_send(client, (void *)&sa->addr, len);
                if (ret < 0)
                        return -EINVAL;
                break;
-
        case SIGMA_ACTION_DELAY:
-               ret = 0;
                udelay(len);
                len = 0;
                break;
-
        case SIGMA_ACTION_END:
-               return 1;
-
+               return 0;
        default:
                return -EINVAL;
        }
 
-       /* when arrive here ret=0 or sent data */
-       ssfw->pos += sigma_action_size(sa, len);
-       return ssfw->pos == ssfw->fw->size;
+       return 1;
 }
 
 static int
 process_sigma_actions(struct i2c_client *client, struct sigma_firmware *ssfw)
 {
-       pr_debug("%s: processing %p\n", __func__, ssfw);
+       struct sigma_action *sa;
+       size_t size;
+       int ret;
+
+       while (ssfw->pos + sizeof(*sa) <= ssfw->fw->size) {
+               sa = (struct sigma_action *)(ssfw->fw->data + ssfw->pos);
+
+               size = sigma_action_size(sa);
+               ssfw->pos += size;
+               if (ssfw->pos > ssfw->fw->size || size == 0)
+                       break;
+
+               ret = process_sigma_action(client, sa);
 
-       while (1) {
-               int ret = process_sigma_action(client, ssfw);
                pr_debug("%s: action returned %i\n", __func__, ret);
-               if (ret == 1)
-                       return 0;
-               else if (ret)
+
+               if (ret <= 0)
                        return ret;
        }
+
+       if (ssfw->pos != ssfw->fw->size)
+               return -EINVAL;
+
+       return 0;
 }
 
 int process_sigma_firmware(struct i2c_client *client, const char *name)
@@ -89,16 +116,24 @@ int process_sigma_firmware(struct i2c_client *client, const char *name)
 
        /* then verify the header */
        ret = -EINVAL;
-       if (fw->size < sizeof(*ssfw_head))
+
+       /*
+        * Reject too small or unreasonable large files. The upper limit has been
+        * chosen a bit arbitrarily, but it should be enough for all practical
+        * purposes and having the limit makes it easier to avoid integer
+        * overflows later in the loading process.
+        */
+       if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000)
                goto done;
 
        ssfw_head = (void *)fw->data;
        if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic)))
                goto done;
 
-       crc = crc32(0, fw->data, fw->size);
+       crc = crc32(0, fw->data + sizeof(*ssfw_head),
+                       fw->size - sizeof(*ssfw_head));
        pr_debug("%s: crc=%x\n", __func__, crc);
-       if (crc != ssfw_head->crc)
+       if (crc != le32_to_cpu(ssfw_head->crc))
                goto done;
 
        ssfw.pos = sizeof(*ssfw_head);
index dbcb0bcfd8dadf49ed156311594e704f81a9b9df..4e018d6a763996127cd370a6a3908273024f37a8 100644 (file)
@@ -18,7 +18,7 @@ obj-$(CONFIG_ARCH_DAVINCI)    += gpio-davinci.o
 obj-$(CONFIG_GPIO_EP93XX)      += gpio-ep93xx.o
 obj-$(CONFIG_GPIO_IT8761E)     += gpio-it8761e.o
 obj-$(CONFIG_GPIO_JANZ_TTL)    += gpio-janz-ttl.o
-obj-$(CONFIG_MACH_KS8695)      += gpio-ks8695.o
+obj-$(CONFIG_ARCH_KS8695)      += gpio-ks8695.o
 obj-$(CONFIG_GPIO_LANGWELL)    += gpio-langwell.o
 obj-$(CONFIG_ARCH_LPC32XX)     += gpio-lpc32xx.o
 obj-$(CONFIG_GPIO_MAX730X)     += gpio-max730x.o
index 3969f7553fe75bf5fa877020e3ccea53f150dfd8..d2619d72ceceb16d7b88a33b09708219483019b4 100644 (file)
@@ -456,6 +456,30 @@ done:
 EXPORT_SYMBOL(drm_crtc_helper_set_mode);
 
 
+static int
+drm_crtc_helper_disable(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_connector *connector;
+       struct drm_encoder *encoder;
+
+       /* Decouple all encoders and their attached connectors from this crtc */
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+               if (encoder->crtc != crtc)
+                       continue;
+
+               list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+                       if (connector->encoder != encoder)
+                               continue;
+
+                       connector->encoder = NULL;
+               }
+       }
+
+       drm_helper_disable_unused_functions(dev);
+       return 0;
+}
+
 /**
  * drm_crtc_helper_set_config - set a new config from userspace
  * @crtc: CRTC to setup
@@ -510,8 +534,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
                                (int)set->num_connectors, set->x, set->y);
        } else {
                DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id);
-               set->mode = NULL;
-               set->num_connectors = 0;
+               return drm_crtc_helper_disable(set->crtc);
        }
 
        dev = set->crtc->dev;
index ddbabefb4273ffa0fe071d49422dd448d21875d9..b12fd2c80812d002e0840787e8ff47481a3691a2 100644 (file)
@@ -369,3 +369,48 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
        spin_unlock_irqrestore(&dev->event_lock, flags);
        return 0;
 }
+
+int
+nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
+                           struct drm_mode_create_dumb *args)
+{
+       struct nouveau_bo *bo;
+       int ret;
+
+       args->pitch = roundup(args->width * (args->bpp / 8), 256);
+       args->size = args->pitch * args->height;
+       args->size = roundup(args->size, PAGE_SIZE);
+
+       ret = nouveau_gem_new(dev, args->size, 0, TTM_PL_FLAG_VRAM, 0, 0, &bo);
+       if (ret)
+               return ret;
+
+       ret = drm_gem_handle_create(file_priv, bo->gem, &args->handle);
+       drm_gem_object_unreference_unlocked(bo->gem);
+       return ret;
+}
+
+int
+nouveau_display_dumb_destroy(struct drm_file *file_priv, struct drm_device *dev,
+                            uint32_t handle)
+{
+       return drm_gem_handle_delete(file_priv, handle);
+}
+
+int
+nouveau_display_dumb_map_offset(struct drm_file *file_priv,
+                               struct drm_device *dev,
+                               uint32_t handle, uint64_t *poffset)
+{
+       struct drm_gem_object *gem;
+
+       gem = drm_gem_object_lookup(dev, file_priv, handle);
+       if (gem) {
+               struct nouveau_bo *bo = gem->driver_private;
+               *poffset = bo->bo.addr_space_offset;
+               drm_gem_object_unreference_unlocked(gem);
+               return 0;
+       }
+
+       return -ENOENT;
+}
index 9f7bb12952623b51bed52e21148ec04dcca902af..9791d13c9e3b8d9d223bd5bb1cae182de4bc89ee 100644 (file)
@@ -433,6 +433,10 @@ static struct drm_driver driver = {
        .gem_open_object = nouveau_gem_object_open,
        .gem_close_object = nouveau_gem_object_close,
 
+       .dumb_create = nouveau_display_dumb_create,
+       .dumb_map_offset = nouveau_display_dumb_map_offset,
+       .dumb_destroy = nouveau_display_dumb_destroy,
+
        .name = DRIVER_NAME,
        .desc = DRIVER_DESC,
 #ifdef GIT_REVISION
index 29837da1098b3a85a50bbc9ee4ccc2b0a4901dab..4c0be3a4ed882f5430ea628ba4d80fef1f1d3690 100644 (file)
@@ -1418,6 +1418,12 @@ int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
                           struct drm_pending_vblank_event *event);
 int nouveau_finish_page_flip(struct nouveau_channel *,
                             struct nouveau_page_flip_state *);
+int nouveau_display_dumb_create(struct drm_file *, struct drm_device *,
+                               struct drm_mode_create_dumb *args);
+int nouveau_display_dumb_map_offset(struct drm_file *, struct drm_device *,
+                                   uint32_t handle, uint64_t *offset);
+int nouveau_display_dumb_destroy(struct drm_file *, struct drm_device *,
+                                uint32_t handle);
 
 /* nv10_gpio.c */
 int nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
index 02222c540aee1a38f963dd13eeda7f0f7c7e8844..960c0ae0c0c3de650dac30beaec208b9bfd3558d 100644 (file)
@@ -680,7 +680,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
                return ret;
        }
 
-       ret = drm_mm_init(&chan->ramin_heap, base, size);
+       ret = drm_mm_init(&chan->ramin_heap, base, size - base);
        if (ret) {
                NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret);
                nouveau_gpuobj_ref(NULL, &chan->ramin);
index b75258a9fe44d544521431133ecd64ec0136637d..c8a463b76c89f03f96f68e48107d9993d2a2bda1 100644 (file)
@@ -67,7 +67,10 @@ nouveau_sgdma_clear(struct ttm_backend *be)
                        pci_unmap_page(dev->pdev, nvbe->pages[nvbe->nr_pages],
                                       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
                }
+               nvbe->unmap_pages = false;
        }
+
+       nvbe->pages = NULL;
 }
 
 static void
index d23ca00e7d627c65e3814891c0a8aa0136f58395..06de250fe617df89ad4e05a34d3e05be8907f126 100644 (file)
@@ -616,7 +616,7 @@ nv50_display_unk10_handler(struct drm_device *dev)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nv50_display *disp = nv50_display(dev);
        u32 unk30 = nv_rd32(dev, 0x610030), mc;
-       int i, crtc, or, type = OUTPUT_ANY;
+       int i, crtc, or = 0, type = OUTPUT_ANY;
 
        NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
        disp->irq.dcb = NULL;
@@ -708,7 +708,7 @@ nv50_display_unk20_handler(struct drm_device *dev)
        struct nv50_display *disp = nv50_display(dev);
        u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc = 0;
        struct dcb_entry *dcb;
-       int i, crtc, or, type = OUTPUT_ANY;
+       int i, crtc, or = 0, type = OUTPUT_ANY;
 
        NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30);
        dcb = disp->irq.dcb;
index a74e501afd25b44b7315d497f8ca30908dcb3995..ecfafd70cf0ed2b6f9ee0b51c74031caa337de27 100644 (file)
@@ -381,6 +381,8 @@ nvc0_graph_init_gpc_0(struct drm_device *dev)
        u8  tpnr[GPC_MAX];
        int i, gpc, tpc;
 
+       nv_wr32(dev, TP_UNIT(0, 0, 0x5c), 1); /* affects TFB offset queries */
+
        /*
         *      TP      ROP UNKVAL(magic_not_rop_nr)
         * 450: 4/0/0/0 2        3
index 23d63b4b3d77078ce4a351f82b8d7cba16d280b7..cb006a718e700f2c72cf06dfdac0c7f22e8cbdac 100644 (file)
@@ -780,7 +780,7 @@ nvd0_sor_dpms(struct drm_encoder *encoder, int mode)
                        continue;
 
                if (nv_partner != nv_encoder &&
-                   nv_partner->dcb->or == nv_encoder->or) {
+                   nv_partner->dcb->or == nv_encoder->dcb->or) {
                        if (nv_partner->last_dpms == DRM_MODE_DPMS_ON)
                                return;
                        break;
index 87631fede1f8ed2a750419200688c151f552e7e6..2b97262e3ab14af5af32b4d85711828563450b09 100644 (file)
@@ -1107,9 +1107,40 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
                return -EINVAL;
        }
 
-       if (tiling_flags & RADEON_TILING_MACRO)
+       if (tiling_flags & RADEON_TILING_MACRO) {
+               if (rdev->family >= CHIP_CAYMAN)
+                       tmp = rdev->config.cayman.tile_config;
+               else
+                       tmp = rdev->config.evergreen.tile_config;
+
+               switch ((tmp & 0xf0) >> 4) {
+               case 0: /* 4 banks */
+                       fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK);
+                       break;
+               case 1: /* 8 banks */
+               default:
+                       fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK);
+                       break;
+               case 2: /* 16 banks */
+                       fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK);
+                       break;
+               }
+
+               switch ((tmp & 0xf000) >> 12) {
+               case 0: /* 1KB rows */
+               default:
+                       fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB);
+                       break;
+               case 1: /* 2KB rows */
+                       fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB);
+                       break;
+               case 2: /* 4KB rows */
+                       fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB);
+                       break;
+               }
+
                fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1);
-       else if (tiling_flags & RADEON_TILING_MICRO)
+       else if (tiling_flags & RADEON_TILING_MICRO)
                fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);
 
        switch (radeon_crtc->crtc_id) {
index 1d603a3335db65b4bf425228a8f98221d01fcd48..5e00d1670aa9964b8d49d0e289e9da5211e501d2 100644 (file)
@@ -82,6 +82,7 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 {
        struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
        u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset);
+       int i;
 
        /* Lock the graphics update lock */
        tmp |= EVERGREEN_GRPH_UPDATE_LOCK;
@@ -99,7 +100,11 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
               (u32)crtc_base);
 
        /* Wait for update_pending to go high. */
-       while (!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING));
+       for (i = 0; i < rdev->usec_timeout; i++) {
+               if (RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING)
+                       break;
+               udelay(1);
+       }
        DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
 
        /* Unlock the lock, so double-buffering can take place inside vblank */
index 38e1bda73d33be343058b1f63f9349ca7f80e3f1..cd4590aae154154d62906d901a63b8b368fea861 100644 (file)
@@ -38,6 +38,7 @@ struct evergreen_cs_track {
        u32                     group_size;
        u32                     nbanks;
        u32                     npipes;
+       u32                     row_size;
        /* value we track */
        u32                     nsamples;
        u32                     cb_color_base_last[12];
@@ -77,6 +78,44 @@ struct evergreen_cs_track {
        struct radeon_bo        *db_s_write_bo;
 };
 
+static u32 evergreen_cs_get_aray_mode(u32 tiling_flags)
+{
+       if (tiling_flags & RADEON_TILING_MACRO)
+               return ARRAY_2D_TILED_THIN1;
+       else if (tiling_flags & RADEON_TILING_MICRO)
+               return ARRAY_1D_TILED_THIN1;
+       else
+               return ARRAY_LINEAR_GENERAL;
+}
+
+static u32 evergreen_cs_get_num_banks(u32 nbanks)
+{
+       switch (nbanks) {
+       case 2:
+               return ADDR_SURF_2_BANK;
+       case 4:
+               return ADDR_SURF_4_BANK;
+       case 8:
+       default:
+               return ADDR_SURF_8_BANK;
+       case 16:
+               return ADDR_SURF_16_BANK;
+       }
+}
+
+static u32 evergreen_cs_get_tile_split(u32 row_size)
+{
+       switch (row_size) {
+       case 1:
+       default:
+               return ADDR_SURF_TILE_SPLIT_1KB;
+       case 2:
+               return ADDR_SURF_TILE_SPLIT_2KB;
+       case 4:
+               return ADDR_SURF_TILE_SPLIT_4KB;
+       }
+}
+
 static void evergreen_cs_track_init(struct evergreen_cs_track *track)
 {
        int i;
@@ -490,12 +529,11 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
                        }
                        ib[idx] &= ~Z_ARRAY_MODE(0xf);
                        track->db_z_info &= ~Z_ARRAY_MODE(0xf);
+                       ib[idx] |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
+                       track->db_z_info |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
                        if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
-                               ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-                               track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-                       } else {
-                               ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
-                               track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+                               ib[idx] |= DB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
+                               ib[idx] |= DB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size));
                        }
                }
                break;
@@ -618,13 +656,8 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
                                                "0x%04X\n", reg);
                                return -EINVAL;
                        }
-                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
-                               ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-                               track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-                       } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
-                               ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
-                               track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
-                       }
+                       ib[idx] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
+                       track->cb_color_info[tmp] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
                }
                break;
        case CB_COLOR8_INFO:
@@ -640,13 +673,8 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
                                                "0x%04X\n", reg);
                                return -EINVAL;
                        }
-                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
-                               ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-                               track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-                       } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
-                               ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
-                               track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
-                       }
+                       ib[idx] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
+                       track->cb_color_info[tmp] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
                }
                break;
        case CB_COLOR0_PITCH:
@@ -701,6 +729,16 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
        case CB_COLOR9_ATTRIB:
        case CB_COLOR10_ATTRIB:
        case CB_COLOR11_ATTRIB:
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       dev_warn(p->dev, "bad SET_CONTEXT_REG "
+                                       "0x%04X\n", reg);
+                       return -EINVAL;
+               }
+               if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+                       ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
+                       ib[idx] |= CB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size));
+               }
                break;
        case CB_COLOR0_DIM:
        case CB_COLOR1_DIM:
@@ -1318,10 +1356,14 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
                                }
                                ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
                                if (!p->keep_tiling_flags) {
-                                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-                                               ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1);
-                                       else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
-                                               ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1);
+                                       ib[idx+1+(i*8)+1] |=
+                                               TEX_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
+                                       if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) {
+                                               ib[idx+1+(i*8)+6] |=
+                                                       TEX_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size));
+                                               ib[idx+1+(i*8)+7] |=
+                                                       TEX_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
+                                       }
                                }
                                texture = reloc->robj;
                                /* tex mip base */
@@ -1422,6 +1464,7 @@ int evergreen_cs_parse(struct radeon_cs_parser *p)
 {
        struct radeon_cs_packet pkt;
        struct evergreen_cs_track *track;
+       u32 tmp;
        int r;
 
        if (p->track == NULL) {
@@ -1430,9 +1473,63 @@ int evergreen_cs_parse(struct radeon_cs_parser *p)
                if (track == NULL)
                        return -ENOMEM;
                evergreen_cs_track_init(track);
-               track->npipes = p->rdev->config.evergreen.tiling_npipes;
-               track->nbanks = p->rdev->config.evergreen.tiling_nbanks;
-               track->group_size = p->rdev->config.evergreen.tiling_group_size;
+               if (p->rdev->family >= CHIP_CAYMAN)
+                       tmp = p->rdev->config.cayman.tile_config;
+               else
+                       tmp = p->rdev->config.evergreen.tile_config;
+
+               switch (tmp & 0xf) {
+               case 0:
+                       track->npipes = 1;
+                       break;
+               case 1:
+               default:
+                       track->npipes = 2;
+                       break;
+               case 2:
+                       track->npipes = 4;
+                       break;
+               case 3:
+                       track->npipes = 8;
+                       break;
+               }
+
+               switch ((tmp & 0xf0) >> 4) {
+               case 0:
+                       track->nbanks = 4;
+                       break;
+               case 1:
+               default:
+                       track->nbanks = 8;
+                       break;
+               case 2:
+                       track->nbanks = 16;
+                       break;
+               }
+
+               switch ((tmp & 0xf00) >> 8) {
+               case 0:
+                       track->group_size = 256;
+                       break;
+               case 1:
+               default:
+                       track->group_size = 512;
+                       break;
+               }
+
+               switch ((tmp & 0xf000) >> 12) {
+               case 0:
+                       track->row_size = 1;
+                       break;
+               case 1:
+               default:
+                       track->row_size = 2;
+                       break;
+               case 2:
+                       track->row_size = 4;
+                       break;
+               }
+
                p->track = track;
        }
        do {
index c781c92c3451285a14360f57bf18a53802dca1ab..7d7f2155e34c305729f8487c55fc8c2c741ccc44 100644 (file)
 #       define EVERGREEN_GRPH_DEPTH_8BPP                0
 #       define EVERGREEN_GRPH_DEPTH_16BPP               1
 #       define EVERGREEN_GRPH_DEPTH_32BPP               2
+#       define EVERGREEN_GRPH_NUM_BANKS(x)              (((x) & 0x3) << 2)
+#       define EVERGREEN_ADDR_SURF_2_BANK               0
+#       define EVERGREEN_ADDR_SURF_4_BANK               1
+#       define EVERGREEN_ADDR_SURF_8_BANK               2
+#       define EVERGREEN_ADDR_SURF_16_BANK              3
+#       define EVERGREEN_GRPH_Z(x)                      (((x) & 0x3) << 4)
+#       define EVERGREEN_GRPH_BANK_WIDTH(x)             (((x) & 0x3) << 6)
+#       define EVERGREEN_ADDR_SURF_BANK_WIDTH_1         0
+#       define EVERGREEN_ADDR_SURF_BANK_WIDTH_2         1
+#       define EVERGREEN_ADDR_SURF_BANK_WIDTH_4         2
+#       define EVERGREEN_ADDR_SURF_BANK_WIDTH_8         3
 #       define EVERGREEN_GRPH_FORMAT(x)                 (((x) & 0x7) << 8)
 /* 8 BPP */
 #       define EVERGREEN_GRPH_FORMAT_INDEXED            0
 #       define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102     5
 #       define EVERGREEN_GRPH_FORMAT_RGB111110          6
 #       define EVERGREEN_GRPH_FORMAT_BGR101111          7
+#       define EVERGREEN_GRPH_BANK_HEIGHT(x)            (((x) & 0x3) << 11)
+#       define EVERGREEN_ADDR_SURF_BANK_HEIGHT_1        0
+#       define EVERGREEN_ADDR_SURF_BANK_HEIGHT_2        1
+#       define EVERGREEN_ADDR_SURF_BANK_HEIGHT_4        2
+#       define EVERGREEN_ADDR_SURF_BANK_HEIGHT_8        3
+#       define EVERGREEN_GRPH_TILE_SPLIT(x)             (((x) & 0x7) << 13)
+#       define EVERGREEN_ADDR_SURF_TILE_SPLIT_64B       0
+#       define EVERGREEN_ADDR_SURF_TILE_SPLIT_128B      1
+#       define EVERGREEN_ADDR_SURF_TILE_SPLIT_256B      2
+#       define EVERGREEN_ADDR_SURF_TILE_SPLIT_512B      3
+#       define EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB       4
+#       define EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB       5
+#       define EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB       6
+#       define EVERGREEN_GRPH_MACRO_TILE_ASPECT(x)      (((x) & 0x3) << 18)
+#       define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_1  0
+#       define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_2  1
+#       define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_4  2
+#       define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_8  3
 #       define EVERGREEN_GRPH_ARRAY_MODE(x)             (((x) & 0x7) << 20)
 #       define EVERGREEN_GRPH_ARRAY_LINEAR_GENERAL      0
 #       define EVERGREEN_GRPH_ARRAY_LINEAR_ALIGNED      1
index b937c49054d9df9d63fea1279d6a1e123fd899e0..e00039e59a75b2bceb45ff69f63b740fd3193f40 100644 (file)
 #define DB_HTILE_DATA_BASE                             0x28014
 #define DB_Z_INFO                                      0x28040
 #       define Z_ARRAY_MODE(x)                          ((x) << 4)
+#       define DB_TILE_SPLIT(x)                         (((x) & 0x7) << 8)
+#       define DB_NUM_BANKS(x)                          (((x) & 0x3) << 12)
+#       define DB_BANK_WIDTH(x)                         (((x) & 0x3) << 16)
+#       define DB_BANK_HEIGHT(x)                        (((x) & 0x3) << 20)
 #define DB_STENCIL_INFO                                        0x28044
 #define DB_Z_READ_BASE                                 0x28048
 #define DB_STENCIL_READ_BASE                           0x2804c
 #      define CB_SF_EXPORT_FULL                        0
 #      define CB_SF_EXPORT_NORM                        1
 #define        CB_COLOR0_ATTRIB                                0x28c74
+#       define CB_TILE_SPLIT(x)                         (((x) & 0x7) << 5)
+#       define ADDR_SURF_TILE_SPLIT_64B                 0
+#       define ADDR_SURF_TILE_SPLIT_128B                1
+#       define ADDR_SURF_TILE_SPLIT_256B                2
+#       define ADDR_SURF_TILE_SPLIT_512B                3
+#       define ADDR_SURF_TILE_SPLIT_1KB                 4
+#       define ADDR_SURF_TILE_SPLIT_2KB                 5
+#       define ADDR_SURF_TILE_SPLIT_4KB                 6
+#       define CB_NUM_BANKS(x)                          (((x) & 0x3) << 10)
+#       define ADDR_SURF_2_BANK                         0
+#       define ADDR_SURF_4_BANK                         1
+#       define ADDR_SURF_8_BANK                         2
+#       define ADDR_SURF_16_BANK                        3
+#       define CB_BANK_WIDTH(x)                         (((x) & 0x3) << 13)
+#       define ADDR_SURF_BANK_WIDTH_1                   0
+#       define ADDR_SURF_BANK_WIDTH_2                   1
+#       define ADDR_SURF_BANK_WIDTH_4                   2
+#       define ADDR_SURF_BANK_WIDTH_8                   3
+#       define CB_BANK_HEIGHT(x)                        (((x) & 0x3) << 16)
+#       define ADDR_SURF_BANK_HEIGHT_1                  0
+#       define ADDR_SURF_BANK_HEIGHT_2                  1
+#       define ADDR_SURF_BANK_HEIGHT_4                  2
+#       define ADDR_SURF_BANK_HEIGHT_8                  3
 #define        CB_COLOR0_DIM                                   0x28c78
 /* only CB0-7 blocks have these regs */
 #define        CB_COLOR0_CMASK                                 0x28c7c
 #      define SQ_SEL_1                                 5
 #define SQ_TEX_RESOURCE_WORD5_0                         0x30014
 #define SQ_TEX_RESOURCE_WORD6_0                         0x30018
+#       define TEX_TILE_SPLIT(x)                        (((x) & 0x7) << 29)
 #define SQ_TEX_RESOURCE_WORD7_0                         0x3001c
+#       define TEX_BANK_WIDTH(x)                        (((x) & 0x3) << 8)
+#       define TEX_BANK_HEIGHT(x)                       (((x) & 0x3) << 10)
+#       define TEX_NUM_BANKS(x)                         (((x) & 0x3) << 16)
 
 #define SQ_VTX_CONSTANT_WORD0_0                                0x30000
 #define SQ_VTX_CONSTANT_WORD1_0                                0x30004
index ad158ea499015e1ceb8ca956c611d9f8944a133d..bfc08f6320f83b83569bec08a2968014c9e90a4f 100644 (file)
@@ -187,13 +187,18 @@ u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 {
        struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
        u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK;
+       int i;
 
        /* Lock the graphics update lock */
        /* update the scanout addresses */
        WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp);
 
        /* Wait for update_pending to go high. */
-       while (!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET));
+       for (i = 0; i < rdev->usec_timeout; i++) {
+               if (RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)
+                       break;
+               udelay(1);
+       }
        DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
 
        /* Unlock the lock, so double-buffering can take place inside vblank */
index 3f6636bb2d7f874abf0208cff67010f82c2f4e75..3516a6081dcfcc3acb35d4d64286ea0f321da01e 100644 (file)
@@ -35,7 +35,8 @@ static int radeon_atif_call(acpi_handle handle)
 
        /* Fail only if calling the method fails and ATIF is supported */
        if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
-               printk(KERN_DEBUG "failed to evaluate ATIF got %s\n", acpi_format_exception(status));
+               DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
+                                acpi_format_exception(status));
                kfree(buffer.pointer);
                return 1;
        }
@@ -50,13 +51,13 @@ int radeon_acpi_init(struct radeon_device *rdev)
        acpi_handle handle;
        int ret;
 
-       /* No need to proceed if we're sure that ATIF is not supported */
-       if (!ASIC_IS_AVIVO(rdev) || !rdev->bios)
-               return 0;
-
        /* Get the device handle */
        handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
 
+       /* No need to proceed if we're sure that ATIF is not supported */
+       if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle)
+               return 0;
+
        /* Call the ATIF method */
        ret = radeon_atif_call(handle);
        if (ret)
index 481b99e89f6542d661c4f0697d413a6eff40f821..b1053d64042313df931b9cde933e121bfa814517 100644 (file)
@@ -62,6 +62,7 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 {
        struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
        u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
+       int i;
 
        /* Lock the graphics update lock */
        tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
@@ -74,7 +75,11 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
               (u32)crtc_base);
 
        /* Wait for update_pending to go high. */
-       while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING));
+       for (i = 0; i < rdev->usec_timeout; i++) {
+               if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
+                       break;
+               udelay(1);
+       }
        DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
 
        /* Unlock the lock, so double-buffering can take place inside vblank */
index a983f410ab89d7d549530d7b7c2f42287a6a7969..23ae1c60ab3d97b8a1576c567054b736fd70eb93 100644 (file)
@@ -47,6 +47,7 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
 {
        struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
        u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
+       int i;
 
        /* Lock the graphics update lock */
        tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
@@ -66,7 +67,11 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
               (u32)crtc_base);
 
        /* Wait for update_pending to go high. */
-       while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING));
+       for (i = 0; i < rdev->usec_timeout; i++) {
+               if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)
+                       break;
+               udelay(1);
+       }
        DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
 
        /* Unlock the lock, so double-buffering can take place inside vblank */
index 880e285d7578afa3ebeae75de4dad77443d754ce..37d40545ed77347007d1051689895d40b116cd1d 100644 (file)
@@ -1809,7 +1809,8 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
        }
 
        rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect);
-       rects = kzalloc(rects_size, GFP_KERNEL);
+       rects = kcalloc(arg->num_outputs, sizeof(struct drm_vmw_rect),
+                       GFP_KERNEL);
        if (unlikely(!rects)) {
                ret = -ENOMEM;
                goto out_unlock;
@@ -1824,10 +1825,10 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
        }
 
        for (i = 0; i < arg->num_outputs; ++i) {
-               if (rects->x < 0 ||
-                   rects->y < 0 ||
-                   rects->x + rects->w > mode_config->max_width ||
-                   rects->y + rects->h > mode_config->max_height) {
+               if (rects[i].x < 0 ||
+                   rects[i].y < 0 ||
+                   rects[i].x + rects[i].w > mode_config->max_width ||
+                   rects[i].y + rects[i].h > mode_config->max_height) {
                        DRM_ERROR("Invalid GUI layout.\n");
                        ret = -EINVAL;
                        goto out_free;
index 848a56c0279c8ac61687340c732521094428e541..af353842f75feaceadeedcc547eeb880519f86df 100644 (file)
@@ -1771,8 +1771,8 @@ static const struct hid_device_id hid_ignore_list[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30) },
index 06ce996b8b6504f65c9216c3173a38cf5a51cb34..4a441a6f996748a923204fbcb53c4850eb3af061 100644 (file)
 #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002
 
 #define USB_VENDOR_ID_GENERAL_TOUCH    0x0dfc
-#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0001
+#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0003
 
 #define USB_VENDOR_ID_GLAB             0x06c2
 #define USB_DEVICE_ID_4_PHIDGETSERVO_30        0x0038
index 835e47b39bc264535c567669d12a81784a8c90c7..03b61577888748a4d9a61cfe46b413eaaa219737 100644 (file)
@@ -593,7 +593,7 @@ static int __devinit nuc900_i2c_probe(struct platform_device *pdev)
        i2c->adap.algo_data = i2c;
        i2c->adap.dev.parent = &pdev->dev;
 
-       mfp_set_groupg(&pdev->dev);
+       mfp_set_groupg(&pdev->dev, NULL);
 
        clk_get_rate(i2c->clk);
 
index 33ec9e4677727800d5439e16300be820c92090b8..9021182c4b766e02454365f1e2b6d22822358f8a 100644 (file)
@@ -242,6 +242,12 @@ static int isdn_divert_ioctl_unlocked(struct file *file, uint cmd, ulong arg)
                case IIOCDOCFINT:
                        if (!divert_if.drv_to_name(dioctl.cf_ctrl.drvid))
                                return (-EINVAL);       /* invalid driver */
+                       if (strnlen(dioctl.cf_ctrl.msn, sizeof(dioctl.cf_ctrl.msn)) ==
+                                       sizeof(dioctl.cf_ctrl.msn))
+                               return -EINVAL;
+                       if (strnlen(dioctl.cf_ctrl.fwd_nr, sizeof(dioctl.cf_ctrl.fwd_nr)) ==
+                                       sizeof(dioctl.cf_ctrl.fwd_nr))
+                               return -EINVAL;
                        if ((i = cf_command(dioctl.cf_ctrl.drvid,
                                            (cmd == IIOCDOCFACT) ? 1 : (cmd == IIOCDOCFDIS) ? 0 : 2,
                                            dioctl.cf_ctrl.cfproc,
index 1f73d7f7e0242e4e73d55582935f4ff0a11f6646..2339d7396b9ea305dd845e592d227bd726d3d43b 100644 (file)
@@ -2756,6 +2756,9 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
                        char *c,
                        *e;
 
+                       if (strnlen(cfg->drvid, sizeof(cfg->drvid)) ==
+                                       sizeof(cfg->drvid))
+                               return -EINVAL;
                        drvidx = -1;
                        chidx = -1;
                        strcpy(drvid, cfg->drvid);
index a73d9dc80ff674d7b90de88226511470b9c8c873..84fb6349a59ab7d78c2ba37fe4d06538e5d52bd8 100644 (file)
@@ -4,7 +4,7 @@
 
 menuconfig ARCNET
        depends on NETDEVICES && (ISA || PCI || PCMCIA)
-       bool "ARCnet support"
+       tristate "ARCnet support"
        ---help---
          If you have a network card of this type, say Y and check out the
          (arguably) beautiful poetry in
index b0c577256487b4b7c35d690da3a2ca619d2deb4c..7f8756825b8abf62f924d569b3e923c7f955c413 100644 (file)
@@ -2553,30 +2553,6 @@ re_arm:
        }
 }
 
-static __be32 bond_glean_dev_ip(struct net_device *dev)
-{
-       struct in_device *idev;
-       struct in_ifaddr *ifa;
-       __be32 addr = 0;
-
-       if (!dev)
-               return 0;
-
-       rcu_read_lock();
-       idev = __in_dev_get_rcu(dev);
-       if (!idev)
-               goto out;
-
-       ifa = idev->ifa_list;
-       if (!ifa)
-               goto out;
-
-       addr = ifa->ifa_local;
-out:
-       rcu_read_unlock();
-       return addr;
-}
-
 static int bond_has_this_ip(struct bonding *bond, __be32 ip)
 {
        struct vlan_entry *vlan;
@@ -3322,6 +3298,10 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
        struct bonding *bond;
        struct vlan_entry *vlan;
 
+       /* we only care about primary address */
+       if(ifa->ifa_flags & IFA_F_SECONDARY)
+               return NOTIFY_DONE;
+
        list_for_each_entry(bond, &bn->dev_list, bond_list) {
                if (bond->dev == event_dev) {
                        switch (event) {
@@ -3329,7 +3309,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
                                bond->master_ip = ifa->ifa_local;
                                return NOTIFY_OK;
                        case NETDEV_DOWN:
-                               bond->master_ip = bond_glean_dev_ip(bond->dev);
+                               bond->master_ip = 0;
                                return NOTIFY_OK;
                        default:
                                return NOTIFY_DONE;
@@ -3345,8 +3325,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
                                        vlan->vlan_ip = ifa->ifa_local;
                                        return NOTIFY_OK;
                                case NETDEV_DOWN:
-                                       vlan->vlan_ip =
-                                               bond_glean_dev_ip(vlan_dev);
+                                       vlan->vlan_ip = 0;
                                        return NOTIFY_OK;
                                default:
                                        return NOTIFY_DONE;
index 905bce0b3a4328bdc59243481d2624c63f55b0e8..2c7f5036f570fd70d1078c1fabef3b7336d2d89e 100644 (file)
@@ -20,7 +20,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
index 4cf835dbc1222f6c90154b601bc02b76d6efbbb6..3fb66d09ece59e463c81eb20b77ba7cfa7df9fd0 100644 (file)
@@ -608,7 +608,7 @@ static void b44_tx(struct b44 *bp)
                                 skb->len,
                                 DMA_TO_DEVICE);
                rp->skb = NULL;
-               dev_kfree_skb(skb);
+               dev_kfree_skb_irq(skb);
        }
 
        bp->tx_cons = cons;
index bce203fa4b9e274c24e06e52b133a0936328c4e5..882f48f0a03cdb47568bff2e67b95cc1cdab5cb3 100644 (file)
@@ -10327,6 +10327,43 @@ static int bnx2x_54618se_config_init(struct bnx2x_phy *phy,
        return 0;
 }
 
+
+static void bnx2x_5461x_set_link_led(struct bnx2x_phy *phy,
+                                      struct link_params *params, u8 mode)
+{
+       struct bnx2x *bp = params->bp;
+       u16 temp;
+
+       bnx2x_cl22_write(bp, phy,
+               MDIO_REG_GPHY_SHADOW,
+               MDIO_REG_GPHY_SHADOW_LED_SEL1);
+       bnx2x_cl22_read(bp, phy,
+               MDIO_REG_GPHY_SHADOW,
+               &temp);
+       temp &= 0xff00;
+
+       DP(NETIF_MSG_LINK, "54618x set link led (mode=%x)\n", mode);
+       switch (mode) {
+       case LED_MODE_FRONT_PANEL_OFF:
+       case LED_MODE_OFF:
+               temp |= 0x00ee;
+               break;
+       case LED_MODE_OPER:
+               temp |= 0x0001;
+               break;
+       case LED_MODE_ON:
+               temp |= 0x00ff;
+               break;
+       default:
+               break;
+       }
+       bnx2x_cl22_write(bp, phy,
+               MDIO_REG_GPHY_SHADOW,
+               MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
+       return;
+}
+
+
 static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy,
                                     struct link_params *params)
 {
@@ -11103,7 +11140,7 @@ static struct bnx2x_phy phy_54618se = {
        .config_loopback = (config_loopback_t)bnx2x_54618se_config_loopback,
        .format_fw_ver  = (format_fw_ver_t)NULL,
        .hw_reset       = (hw_reset_t)NULL,
-       .set_link_led   = (set_link_led_t)NULL,
+       .set_link_led   = (set_link_led_t)bnx2x_5461x_set_link_led,
        .phy_specific_func = (phy_specific_func_t)NULL
 };
 /*****************************************************************/
index fc7bd0f23c0b7e656905eb590ea6d8c0d360ea44..e58073ef33b47e5dc45708d794726a7a038470a2 100644 (file)
@@ -6990,6 +6990,7 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_REG_INTR_MASK                             0x1b
 #define MDIO_REG_INTR_MASK_LINK_STATUS                 (0x1 << 1)
 #define MDIO_REG_GPHY_SHADOW                           0x1c
+#define MDIO_REG_GPHY_SHADOW_LED_SEL1                  (0x0d << 10)
 #define MDIO_REG_GPHY_SHADOW_LED_SEL2                  (0x0e << 10)
 #define MDIO_REG_GPHY_SHADOW_WR_ENA                    (0x1 << 15)
 #define MDIO_REG_GPHY_SHADOW_AUTO_DET_MED              (0x1e << 10)
index 438f4580bf66207539761761e37c42e0ef303b78..2a22f52563532201891fa4a720d11180886b714c 100644 (file)
@@ -613,7 +613,7 @@ static int dm9000_set_wol(struct net_device *dev, struct ethtool_wolinfo *w)
 
                if (!dm->wake_state)
                        irq_set_irq_wake(dm->irq_wake, 1);
-               else if (dm->wake_state & !opts)
+               else if (dm->wake_state && !opts)
                        irq_set_irq_wake(dm->irq_wake, 0);
        }
 
index c520cfd3b29805440508acff0a8748b5956fee11..5272f9d4dda9448faece5a061d413c71620f6da4 100644 (file)
@@ -24,6 +24,7 @@ config FEC
        bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
        depends on (M523x || M527x || M5272 || M528x || M520x || M532x || \
                   ARCH_MXC || ARCH_MXS)
+       default ARCH_MXC || ARCH_MXS if ARM
        select PHYLIB
        ---help---
          Say Y here if you want to use the built-in 10/100 Fast ethernet
index 410d6a1984ed400863c7e5eabd63e7041629d101..6650068c996c48158c3b09c8975b912440e00aff 100644 (file)
@@ -61,9 +61,9 @@
 #ifdef EHEA_SMALL_QUEUES
 #define EHEA_MAX_CQE_COUNT      1023
 #define EHEA_DEF_ENTRIES_SQ     1023
-#define EHEA_DEF_ENTRIES_RQ1    4095
+#define EHEA_DEF_ENTRIES_RQ1    1023
 #define EHEA_DEF_ENTRIES_RQ2    1023
-#define EHEA_DEF_ENTRIES_RQ3    1023
+#define EHEA_DEF_ENTRIES_RQ3    511
 #else
 #define EHEA_MAX_CQE_COUNT      4080
 #define EHEA_DEF_ENTRIES_SQ     4080
index 37b70f7052b68ad9a16593cb299cf6eb380a6491..bfeccbfde236237dc0c8486d0dd1d12d192d3a02 100644 (file)
@@ -371,7 +371,8 @@ static void ehea_update_stats(struct work_struct *work)
 out_herr:
        free_page((unsigned long)cb2);
 resched:
-       schedule_delayed_work(&port->stats_work, msecs_to_jiffies(1000));
+       schedule_delayed_work(&port->stats_work,
+                             round_jiffies_relative(msecs_to_jiffies(1000)));
 }
 
 static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
@@ -2434,7 +2435,8 @@ static int ehea_open(struct net_device *dev)
        }
 
        mutex_unlock(&port->port_lock);
-       schedule_delayed_work(&port->stats_work, msecs_to_jiffies(1000));
+       schedule_delayed_work(&port->stats_work,
+                             round_jiffies_relative(msecs_to_jiffies(1000)));
 
        return ret;
 }
index 4326681df382ac461c24e21eb6a6ea0ee64d4426..acc31af6594a243b91d7c9f666363581f68ddf05 100644 (file)
@@ -1421,7 +1421,7 @@ static void veth_receive(struct veth_lpar_connection *cnx,
 
                /* FIXME: do we need this? */
                memset(local_list, 0, sizeof(local_list));
-               memset(remote_list, 0, sizeof(VETH_MAX_FRAMES_PER_MSG));
+               memset(remote_list, 0, sizeof(remote_list));
 
                /* a 0 address marks the end of the valid entries */
                if (senddata->addr[startchunk] == 0)
index 7becff1f387d7c9d84fb26ab3db6f7299bb64f15..76b84573566bd850a267c02a9d533fac5b68c7c4 100644 (file)
@@ -1744,6 +1744,112 @@ jme_phy_off(struct jme_adapter *jme)
                jme_new_phy_off(jme);
 }
 
+static int
+jme_phy_specreg_read(struct jme_adapter *jme, u32 specreg)
+{
+       u32 phy_addr;
+
+       phy_addr = JM_PHY_SPEC_REG_READ | specreg;
+       jme_mdio_write(jme->dev, jme->mii_if.phy_id, JM_PHY_SPEC_ADDR_REG,
+                       phy_addr);
+       return jme_mdio_read(jme->dev, jme->mii_if.phy_id,
+                       JM_PHY_SPEC_DATA_REG);
+}
+
+static void
+jme_phy_specreg_write(struct jme_adapter *jme, u32 ext_reg, u32 phy_data)
+{
+       u32 phy_addr;
+
+       phy_addr = JM_PHY_SPEC_REG_WRITE | ext_reg;
+       jme_mdio_write(jme->dev, jme->mii_if.phy_id, JM_PHY_SPEC_DATA_REG,
+                       phy_data);
+       jme_mdio_write(jme->dev, jme->mii_if.phy_id, JM_PHY_SPEC_ADDR_REG,
+                       phy_addr);
+}
+
+static int
+jme_phy_calibration(struct jme_adapter *jme)
+{
+       u32 ctrl1000, phy_data;
+
+       jme_phy_off(jme);
+       jme_phy_on(jme);
+       /*  Enabel PHY test mode 1 */
+       ctrl1000 = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_CTRL1000);
+       ctrl1000 &= ~PHY_GAD_TEST_MODE_MSK;
+       ctrl1000 |= PHY_GAD_TEST_MODE_1;
+       jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_CTRL1000, ctrl1000);
+
+       phy_data = jme_phy_specreg_read(jme, JM_PHY_EXT_COMM_2_REG);
+       phy_data &= ~JM_PHY_EXT_COMM_2_CALI_MODE_0;
+       phy_data |= JM_PHY_EXT_COMM_2_CALI_LATCH |
+                       JM_PHY_EXT_COMM_2_CALI_ENABLE;
+       jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_2_REG, phy_data);
+       msleep(20);
+       phy_data = jme_phy_specreg_read(jme, JM_PHY_EXT_COMM_2_REG);
+       phy_data &= ~(JM_PHY_EXT_COMM_2_CALI_ENABLE |
+                       JM_PHY_EXT_COMM_2_CALI_MODE_0 |
+                       JM_PHY_EXT_COMM_2_CALI_LATCH);
+       jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_2_REG, phy_data);
+
+       /*  Disable PHY test mode */
+       ctrl1000 = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_CTRL1000);
+       ctrl1000 &= ~PHY_GAD_TEST_MODE_MSK;
+       jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_CTRL1000, ctrl1000);
+       return 0;
+}
+
+static int
+jme_phy_setEA(struct jme_adapter *jme)
+{
+       u32 phy_comm0 = 0, phy_comm1 = 0;
+       u8 nic_ctrl;
+
+       pci_read_config_byte(jme->pdev, PCI_PRIV_SHARE_NICCTRL, &nic_ctrl);
+       if ((nic_ctrl & 0x3) == JME_FLAG_PHYEA_ENABLE)
+               return 0;
+
+       switch (jme->pdev->device) {
+       case PCI_DEVICE_ID_JMICRON_JMC250:
+               if (((jme->chip_main_rev == 5) &&
+                       ((jme->chip_sub_rev == 0) || (jme->chip_sub_rev == 1) ||
+                       (jme->chip_sub_rev == 3))) ||
+                       (jme->chip_main_rev >= 6)) {
+                       phy_comm0 = 0x008A;
+                       phy_comm1 = 0x4109;
+               }
+               if ((jme->chip_main_rev == 3) &&
+                       ((jme->chip_sub_rev == 1) || (jme->chip_sub_rev == 2)))
+                       phy_comm0 = 0xE088;
+               break;
+       case PCI_DEVICE_ID_JMICRON_JMC260:
+               if (((jme->chip_main_rev == 5) &&
+                       ((jme->chip_sub_rev == 0) || (jme->chip_sub_rev == 1) ||
+                       (jme->chip_sub_rev == 3))) ||
+                       (jme->chip_main_rev >= 6)) {
+                       phy_comm0 = 0x008A;
+                       phy_comm1 = 0x4109;
+               }
+               if ((jme->chip_main_rev == 3) &&
+                       ((jme->chip_sub_rev == 1) || (jme->chip_sub_rev == 2)))
+                       phy_comm0 = 0xE088;
+               if ((jme->chip_main_rev == 2) && (jme->chip_sub_rev == 0))
+                       phy_comm0 = 0x608A;
+               if ((jme->chip_main_rev == 2) && (jme->chip_sub_rev == 2))
+                       phy_comm0 = 0x408A;
+               break;
+       default:
+               return -ENODEV;
+       }
+       if (phy_comm0)
+               jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_0_REG, phy_comm0);
+       if (phy_comm1)
+               jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_1_REG, phy_comm1);
+
+       return 0;
+}
+
 static int
 jme_open(struct net_device *netdev)
 {
@@ -1769,7 +1875,8 @@ jme_open(struct net_device *netdev)
                jme_set_settings(netdev, &jme->old_ecmd);
        else
                jme_reset_phy_processor(jme);
-
+       jme_phy_calibration(jme);
+       jme_phy_setEA(jme);
        jme_reset_link(jme);
 
        return 0;
@@ -3184,7 +3291,8 @@ jme_resume(struct device *dev)
                jme_set_settings(netdev, &jme->old_ecmd);
        else
                jme_reset_phy_processor(jme);
-
+       jme_phy_calibration(jme);
+       jme_phy_setEA(jme);
        jme_start_irq(jme);
        netif_device_attach(netdev);
 
@@ -3239,4 +3347,3 @@ MODULE_DESCRIPTION("JMicron JMC2x0 PCI Express Ethernet driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 MODULE_DEVICE_TABLE(pci, jme_pci_tbl);
-
index 02ea27c1dcb5a464f06d9b38d98259f6f080fd4c..4304072bd3c536e852a38cf6c37716df8500ed66 100644 (file)
@@ -760,6 +760,25 @@ enum jme_rxmcs_bits {
                                  RXMCS_CHECKSUM,
 };
 
+/*     Extern PHY common register 2    */
+
+#define PHY_GAD_TEST_MODE_1                    0x00002000
+#define PHY_GAD_TEST_MODE_MSK                  0x0000E000
+#define JM_PHY_SPEC_REG_READ                   0x00004000
+#define JM_PHY_SPEC_REG_WRITE                  0x00008000
+#define PHY_CALIBRATION_DELAY                  20
+#define JM_PHY_SPEC_ADDR_REG                   0x1E
+#define JM_PHY_SPEC_DATA_REG                   0x1F
+
+#define JM_PHY_EXT_COMM_0_REG                  0x30
+#define JM_PHY_EXT_COMM_1_REG                  0x31
+#define JM_PHY_EXT_COMM_2_REG                  0x32
+#define JM_PHY_EXT_COMM_2_CALI_ENABLE          0x01
+#define JM_PHY_EXT_COMM_2_CALI_MODE_0          0x02
+#define JM_PHY_EXT_COMM_2_CALI_LATCH           0x10
+#define PCI_PRIV_SHARE_NICCTRL                 0xF5
+#define JME_FLAG_PHYEA_ENABLE                  0x2
+
 /*
  * Wakeup Frame setup interface registers
  */
index 8731f79c9efc40439bac7af0363225d885f42036..b8478aab050e76efa2b734572b3f866f98da321f 100644 (file)
 
 
 #define TX_DESC_PER_IOCB 8
-/* The maximum number of frags we handle is based
- * on PAGE_SIZE...
- */
-#if (PAGE_SHIFT == 12) || (PAGE_SHIFT == 13)   /* 4k & 8k pages */
+
+#if ((MAX_SKB_FRAGS - TX_DESC_PER_IOCB) + 2) > 0
 #define TX_DESC_PER_OAL ((MAX_SKB_FRAGS - TX_DESC_PER_IOCB) + 2)
 #else /* all other page sizes */
 #define TX_DESC_PER_OAL 0
@@ -1353,7 +1351,7 @@ struct tx_ring_desc {
        struct ob_mac_iocb_req *queue_entry;
        u32 index;
        struct oal oal;
-       struct map_list map[MAX_SKB_FRAGS + 1];
+       struct map_list map[MAX_SKB_FRAGS + 2];
        int map_cnt;
        struct tx_ring_desc *next;
 };
index 8ea770a89f2556b8c762f2af345e5044d45ff9ba..72cd190b9c1a0734d401b193e1bd7b12cb49b3af 100644 (file)
@@ -781,10 +781,15 @@ static void stmmac_mmc_setup(struct stmmac_priv *priv)
        unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET |
                            MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET;
 
-       /* Do not manage MMC IRQ (FIXME) */
+       /* Mask MMC irq, counters are managed in SW and registers
+        * are cleared on each READ eventually. */
        dwmac_mmc_intr_all_mask(priv->ioaddr);
-       dwmac_mmc_ctrl(priv->ioaddr, mode);
-       memset(&priv->mmc, 0, sizeof(struct stmmac_counters));
+
+       if (priv->dma_cap.rmon) {
+               dwmac_mmc_ctrl(priv->ioaddr, mode);
+               memset(&priv->mmc, 0, sizeof(struct stmmac_counters));
+       } else
+               pr_info(" No MAC Management Counters available");
 }
 
 static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
@@ -1012,8 +1017,7 @@ static int stmmac_open(struct net_device *dev)
        memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
        priv->xstats.threshold = tc;
 
-       if (priv->dma_cap.rmon)
-               stmmac_mmc_setup(priv);
+       stmmac_mmc_setup(priv);
 
        /* Start the ball rolling... */
        DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
index bb88e12101c78b86b91def144677e4ecb10d8091..a70244306c9462830c4ebde0b87334ef7667fa0e 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 menuconfig PHYLIB
-       bool "PHY Device support and infrastructure"
+       tristate "PHY Device support and infrastructure"
        depends on !S390
        depends on NETDEVICES
        help
index f18df82eeb92caccedb8381bb95e4f55cd4d1901..78d0d6988553d40354b9fbf2396e1657eaefd9c6 100644 (file)
@@ -588,8 +588,6 @@ static void p54spi_op_stop(struct ieee80211_hw *dev)
 
        WARN_ON(priv->fw_state != FW_STATE_READY);
 
-       cancel_work_sync(&priv->work);
-
        p54spi_power_off(priv);
        spin_lock_irqsave(&priv->tx_lock, flags);
        INIT_LIST_HEAD(&priv->tx_pending);
@@ -597,6 +595,8 @@ static void p54spi_op_stop(struct ieee80211_hw *dev)
 
        priv->fw_state = FW_STATE_OFF;
        mutex_unlock(&priv->mutex);
+
+       cancel_work_sync(&priv->work);
 }
 
 static int __devinit p54spi_probe(struct spi_device *spi)
@@ -656,6 +656,7 @@ static int __devinit p54spi_probe(struct spi_device *spi)
        init_completion(&priv->fw_comp);
        INIT_LIST_HEAD(&priv->tx_pending);
        mutex_init(&priv->mutex);
+       spin_lock_init(&priv->tx_lock);
        SET_IEEE80211_DEV(hw, &spi->dev);
        priv->common.open = p54spi_op_start;
        priv->common.stop = p54spi_op_stop;
index d97a2caf582b3997f2378434117758a928cefbd3..bc2ba80c47bb9ff0105d8ed2c119ab3b3589364e 100644 (file)
@@ -778,7 +778,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info,
                dwrq->flags = 0;
                dwrq->length = 0;
        }
-       essid->octets[essid->length] = '\0';
+       essid->octets[dwrq->length] = '\0';
        memcpy(extra, essid->octets, dwrq->length);
        kfree(essid);
 
index 3f183a15186e09b5e05a2e296c5c66bd94426b23..1ba079dffb11573e86f1b547ac8868e313840f26 100644 (file)
@@ -3771,7 +3771,7 @@ static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i)
        /* Apparently the data is read from end to start */
        rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, &reg);
        /* The returned value is in CPU order, but eeprom is le */
-       rt2x00dev->eeprom[i] = cpu_to_le32(reg);
+       *(u32 *)&rt2x00dev->eeprom[i] = cpu_to_le32(reg);
        rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, &reg);
        *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg);
        rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, &reg);
index db526284454336e47bf2c530e1b0630123809524..55c8e50f45fd143b7e606894c71e072c97480f2a 100644 (file)
@@ -395,7 +395,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
        if (mac->link_state != MAC80211_LINKED)
                return;
 
-       spin_lock(&rtlpriv->locks.lps_lock);
+       spin_lock_irq(&rtlpriv->locks.lps_lock);
 
        /* Idle for a while if we connect to AP a while ago. */
        if (mac->cnt_after_linked >= 2) {
@@ -407,7 +407,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
                }
        }
 
-       spin_unlock(&rtlpriv->locks.lps_lock);
+       spin_unlock_irq(&rtlpriv->locks.lps_lock);
 }
 
 /*Leave the leisure power save mode.*/
@@ -416,8 +416,9 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
        struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+       unsigned long flags;
 
-       spin_lock(&rtlpriv->locks.lps_lock);
+       spin_lock_irqsave(&rtlpriv->locks.lps_lock, flags);
 
        if (ppsc->fwctrl_lps) {
                if (ppsc->dot11_psmode != EACTIVE) {
@@ -438,7 +439,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
                        rtl_lps_set_psmode(hw, EACTIVE);
                }
        }
-       spin_unlock(&rtlpriv->locks.lps_lock);
+       spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flags);
 }
 
 /* For sw LPS*/
@@ -539,9 +540,9 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
                RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
        }
 
-       spin_lock(&rtlpriv->locks.lps_lock);
+       spin_lock_irq(&rtlpriv->locks.lps_lock);
        rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS);
-       spin_unlock(&rtlpriv->locks.lps_lock);
+       spin_unlock_irq(&rtlpriv->locks.lps_lock);
 }
 
 void rtl_swlps_rfon_wq_callback(void *data)
@@ -574,9 +575,9 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
        if (rtlpriv->link_info.busytraffic)
                return;
 
-       spin_lock(&rtlpriv->locks.lps_lock);
+       spin_lock_irq(&rtlpriv->locks.lps_lock);
        rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS);
-       spin_unlock(&rtlpriv->locks.lps_lock);
+       spin_unlock_irq(&rtlpriv->locks.lps_lock);
 
        if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
                !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
index 0cb594c86090fa7c25f3578132528f5f616aef26..1ae270eed51a64a5ce167da54264f5b41cf55e57 100644 (file)
@@ -1021,7 +1021,7 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk,
                pending_idx = *((u16 *)skb->data);
                xen_netbk_idx_release(netbk, pending_idx);
                for (j = start; j < i; j++) {
-                       pending_idx = frag_get_pending_idx(&shinfo->frags[i]);
+                       pending_idx = frag_get_pending_idx(&shinfo->frags[j]);
                        xen_netbk_idx_release(netbk, pending_idx);
                }
 
index 75c3f1f8fd434301c3ba4a07a632e0ffefa6aac3..a84631a7391d3ed50c680b939129d159fc25daa3 100644 (file)
@@ -529,10 +529,7 @@ __s390_vary_chpid_on(struct subchannel_id schid, void *data)
 int chsc_chp_vary(struct chp_id chpid, int on)
 {
        struct channel_path *chp = chpid_to_chp(chpid);
-       struct chp_link link;
 
-       memset(&link, 0, sizeof(struct chp_link));
-       link.chpid = chpid;
        /* Wait until previous actions have settled. */
        css_wait_for_slow_path();
        /*
@@ -542,10 +539,10 @@ int chsc_chp_vary(struct chp_id chpid, int on)
                /* Try to update the channel path descritor. */
                chsc_determine_base_channel_path_desc(chpid, &chp->desc);
                for_each_subchannel_staged(s390_subchannel_vary_chpid_on,
-                                          __s390_vary_chpid_on, &link);
+                                          __s390_vary_chpid_on, &chpid);
        } else
                for_each_subchannel_staged(s390_subchannel_vary_chpid_off,
-                                          NULL, &link);
+                                          NULL, &chpid);
 
        return 0;
 }
index 155a82bcb9e545e2888430337d0b1c2b50239acd..4a1ff5c2eb881355204ffe8e047cfbe3bb8e3706 100644 (file)
@@ -68,8 +68,13 @@ struct schib {
        __u8 mda[4];             /* model dependent area */
 } __attribute__ ((packed,aligned(4)));
 
+/*
+ * When rescheduled, todo's with higher values will overwrite those
+ * with lower values.
+ */
 enum sch_todo {
        SCH_TODO_NOTHING,
+       SCH_TODO_EVAL,
        SCH_TODO_UNREG,
 };
 
index 92d7324acb1c78fbab348a2ea190c8901351df9d..21908e67bf6745d8dc91f791347a9d9cee538aa1 100644 (file)
@@ -195,51 +195,6 @@ void css_sch_device_unregister(struct subchannel *sch)
 }
 EXPORT_SYMBOL_GPL(css_sch_device_unregister);
 
-static void css_sch_todo(struct work_struct *work)
-{
-       struct subchannel *sch;
-       enum sch_todo todo;
-
-       sch = container_of(work, struct subchannel, todo_work);
-       /* Find out todo. */
-       spin_lock_irq(sch->lock);
-       todo = sch->todo;
-       CIO_MSG_EVENT(4, "sch_todo: sch=0.%x.%04x, todo=%d\n", sch->schid.ssid,
-                     sch->schid.sch_no, todo);
-       sch->todo = SCH_TODO_NOTHING;
-       spin_unlock_irq(sch->lock);
-       /* Perform todo. */
-       if (todo == SCH_TODO_UNREG)
-               css_sch_device_unregister(sch);
-       /* Release workqueue ref. */
-       put_device(&sch->dev);
-}
-
-/**
- * css_sched_sch_todo - schedule a subchannel operation
- * @sch: subchannel
- * @todo: todo
- *
- * Schedule the operation identified by @todo to be performed on the slow path
- * workqueue. Do nothing if another operation with higher priority is already
- * scheduled. Needs to be called with subchannel lock held.
- */
-void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo)
-{
-       CIO_MSG_EVENT(4, "sch_todo: sched sch=0.%x.%04x todo=%d\n",
-                     sch->schid.ssid, sch->schid.sch_no, todo);
-       if (sch->todo >= todo)
-               return;
-       /* Get workqueue ref. */
-       if (!get_device(&sch->dev))
-               return;
-       sch->todo = todo;
-       if (!queue_work(cio_work_q, &sch->todo_work)) {
-               /* Already queued, release workqueue ref. */
-               put_device(&sch->dev);
-       }
-}
-
 static void ssd_from_pmcw(struct chsc_ssd_info *ssd, struct pmcw *pmcw)
 {
        int i;
@@ -466,6 +421,65 @@ static void css_evaluate_subchannel(struct subchannel_id schid, int slow)
                css_schedule_eval(schid);
 }
 
+/**
+ * css_sched_sch_todo - schedule a subchannel operation
+ * @sch: subchannel
+ * @todo: todo
+ *
+ * Schedule the operation identified by @todo to be performed on the slow path
+ * workqueue. Do nothing if another operation with higher priority is already
+ * scheduled. Needs to be called with subchannel lock held.
+ */
+void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo)
+{
+       CIO_MSG_EVENT(4, "sch_todo: sched sch=0.%x.%04x todo=%d\n",
+                     sch->schid.ssid, sch->schid.sch_no, todo);
+       if (sch->todo >= todo)
+               return;
+       /* Get workqueue ref. */
+       if (!get_device(&sch->dev))
+               return;
+       sch->todo = todo;
+       if (!queue_work(cio_work_q, &sch->todo_work)) {
+               /* Already queued, release workqueue ref. */
+               put_device(&sch->dev);
+       }
+}
+
+static void css_sch_todo(struct work_struct *work)
+{
+       struct subchannel *sch;
+       enum sch_todo todo;
+       int ret;
+
+       sch = container_of(work, struct subchannel, todo_work);
+       /* Find out todo. */
+       spin_lock_irq(sch->lock);
+       todo = sch->todo;
+       CIO_MSG_EVENT(4, "sch_todo: sch=0.%x.%04x, todo=%d\n", sch->schid.ssid,
+                     sch->schid.sch_no, todo);
+       sch->todo = SCH_TODO_NOTHING;
+       spin_unlock_irq(sch->lock);
+       /* Perform todo. */
+       switch (todo) {
+       case SCH_TODO_NOTHING:
+               break;
+       case SCH_TODO_EVAL:
+               ret = css_evaluate_known_subchannel(sch, 1);
+               if (ret == -EAGAIN) {
+                       spin_lock_irq(sch->lock);
+                       css_sched_sch_todo(sch, todo);
+                       spin_unlock_irq(sch->lock);
+               }
+               break;
+       case SCH_TODO_UNREG:
+               css_sch_device_unregister(sch);
+               break;
+       }
+       /* Release workqueue ref. */
+       put_device(&sch->dev);
+}
+
 static struct idset *slow_subchannel_set;
 static spinlock_t slow_subchannel_lock;
 static wait_queue_head_t css_eval_wq;
index d734f4a0ecac23cea1d821b316a563b71087ccc6..47269858ecb662af862c38a5e96fc4f9aacfe2ca 100644 (file)
@@ -1868,9 +1868,9 @@ static void __ccw_device_pm_restore(struct ccw_device *cdev)
         */
        cdev->private->flags.resuming = 1;
        cdev->private->path_new_mask = LPM_ANYPATH;
-       css_schedule_eval(sch->schid);
+       css_sched_sch_todo(sch, SCH_TODO_EVAL);
        spin_unlock_irq(sch->lock);
-       css_complete_work();
+       css_wait_for_slow_path();
 
        /* cdev may have been moved to a different subchannel. */
        sch = to_subchannel(cdev->dev.parent);
index 52c233fa2b1281d14a2881618465606447bef365..1b853513c891ca2f010f8703b110f49c6f65afb3 100644 (file)
@@ -496,8 +496,26 @@ static void ccw_device_reset_path_events(struct ccw_device *cdev)
        cdev->private->pgid_reset_mask = 0;
 }
 
-void
-ccw_device_verify_done(struct ccw_device *cdev, int err)
+static void create_fake_irb(struct irb *irb, int type)
+{
+       memset(irb, 0, sizeof(*irb));
+       if (type == FAKE_CMD_IRB) {
+               struct cmd_scsw *scsw = &irb->scsw.cmd;
+               scsw->cc = 1;
+               scsw->fctl = SCSW_FCTL_START_FUNC;
+               scsw->actl = SCSW_ACTL_START_PEND;
+               scsw->stctl = SCSW_STCTL_STATUS_PEND;
+       } else if (type == FAKE_TM_IRB) {
+               struct tm_scsw *scsw = &irb->scsw.tm;
+               scsw->x = 1;
+               scsw->cc = 1;
+               scsw->fctl = SCSW_FCTL_START_FUNC;
+               scsw->actl = SCSW_ACTL_START_PEND;
+               scsw->stctl = SCSW_STCTL_STATUS_PEND;
+       }
+}
+
+void ccw_device_verify_done(struct ccw_device *cdev, int err)
 {
        struct subchannel *sch;
 
@@ -520,12 +538,8 @@ callback:
                ccw_device_done(cdev, DEV_STATE_ONLINE);
                /* Deliver fake irb to device driver, if needed. */
                if (cdev->private->flags.fake_irb) {
-                       memset(&cdev->private->irb, 0, sizeof(struct irb));
-                       cdev->private->irb.scsw.cmd.cc = 1;
-                       cdev->private->irb.scsw.cmd.fctl = SCSW_FCTL_START_FUNC;
-                       cdev->private->irb.scsw.cmd.actl = SCSW_ACTL_START_PEND;
-                       cdev->private->irb.scsw.cmd.stctl =
-                               SCSW_STCTL_STATUS_PEND;
+                       create_fake_irb(&cdev->private->irb,
+                                       cdev->private->flags.fake_irb);
                        cdev->private->flags.fake_irb = 0;
                        if (cdev->handler)
                                cdev->handler(cdev, cdev->private->intparm,
index f98698d5735e887e0fb6cc46f00a63012ecdccb5..ec7fb6d3b479a25a32bfad67ecc36a3539782b39 100644 (file)
@@ -198,7 +198,7 @@ int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
        if (cdev->private->state == DEV_STATE_VERIFY) {
                /* Remember to fake irb when finished. */
                if (!cdev->private->flags.fake_irb) {
-                       cdev->private->flags.fake_irb = 1;
+                       cdev->private->flags.fake_irb = FAKE_CMD_IRB;
                        cdev->private->intparm = intparm;
                        return 0;
                } else
@@ -213,9 +213,9 @@ int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
        ret = cio_set_options (sch, flags);
        if (ret)
                return ret;
-       /* Adjust requested path mask to excluded varied off paths. */
+       /* Adjust requested path mask to exclude unusable paths. */
        if (lpm) {
-               lpm &= sch->opm;
+               lpm &= sch->lpm;
                if (lpm == 0)
                        return -EACCES;
        }
@@ -605,11 +605,21 @@ int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw,
        sch = to_subchannel(cdev->dev.parent);
        if (!sch->schib.pmcw.ena)
                return -EINVAL;
+       if (cdev->private->state == DEV_STATE_VERIFY) {
+               /* Remember to fake irb when finished. */
+               if (!cdev->private->flags.fake_irb) {
+                       cdev->private->flags.fake_irb = FAKE_TM_IRB;
+                       cdev->private->intparm = intparm;
+                       return 0;
+               } else
+                       /* There's already a fake I/O around. */
+                       return -EBUSY;
+       }
        if (cdev->private->state != DEV_STATE_ONLINE)
                return -EIO;
-       /* Adjust requested path mask to excluded varied off paths. */
+       /* Adjust requested path mask to exclude unusable paths. */
        if (lpm) {
-               lpm &= sch->opm;
+               lpm &= sch->lpm;
                if (lpm == 0)
                        return -EACCES;
        }
index 2ebb492a5c17dcb8a9e05fb23209162edb43d849..76253dfcc1be86a18eba7ac7ea4d6f53c134bc7e 100644 (file)
@@ -111,6 +111,9 @@ enum cdev_todo {
        CDEV_TODO_UNREG_EVAL,
 };
 
+#define FAKE_CMD_IRB   1
+#define FAKE_TM_IRB    2
+
 struct ccw_device_private {
        struct ccw_device *cdev;
        struct subchannel *sch;
@@ -138,7 +141,7 @@ struct ccw_device_private {
                unsigned int doverify:1;    /* delayed path verification */
                unsigned int donotify:1;    /* call notify function */
                unsigned int recog_done:1;  /* dev. recog. complete */
-               unsigned int fake_irb:1;    /* deliver faked irb */
+               unsigned int fake_irb:2;    /* deliver faked irb */
                unsigned int resuming:1;    /* recognition while resume */
                unsigned int pgroup:1;      /* pathgroup is set up */
                unsigned int mpath:1;       /* multipathing is set up */
index ec94f049e99543849ed56c90c665102c40c5b87e..96bbe9d12a79fbef17fa9b4df331adf5a24a96c3 100644 (file)
@@ -1552,6 +1552,8 @@ static void ap_reset(struct ap_device *ap_dev)
        rc = ap_init_queue(ap_dev->qid);
        if (rc == -ENODEV)
                ap_dev->unregistered = 1;
+       else
+               __ap_schedule_poll_timer();
 }
 
 static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags)
index e763254741c296169b6d662d5f398c1a90170cc2..21c70b2b83119e333ebe4c5b5e18ab70f2ce6a0a 100644 (file)
@@ -426,7 +426,7 @@ static int __devinit nuc900_spi_probe(struct platform_device *pdev)
                goto err_clk;
        }
 
-       mfp_set_groupg(&pdev->dev);
+       mfp_set_groupg(&pdev->dev, NULL);
        nuc900_init_spi(hw);
 
        err = spi_bitbang_start(&hw->bitbang);
index 21d8c1c16cd891e42bf1621d7ff1ba8f0dc5e580..5e78c77d5a08277611c183c92dae273362caed58 100644 (file)
@@ -671,7 +671,7 @@ static int do_insnlist_ioctl(struct comedi_device *dev,
        }
 
        insns =
-           kmalloc(sizeof(struct comedi_insn) * insnlist.n_insns, GFP_KERNEL);
+           kcalloc(insnlist.n_insns, sizeof(struct comedi_insn), GFP_KERNEL);
        if (!insns) {
                DPRINTK("kmalloc failed\n");
                ret = -ENOMEM;
@@ -1432,7 +1432,21 @@ static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
        return ret;
 }
 
-static void comedi_unmap(struct vm_area_struct *area)
+
+static void comedi_vm_open(struct vm_area_struct *area)
+{
+       struct comedi_async *async;
+       struct comedi_device *dev;
+
+       async = area->vm_private_data;
+       dev = async->subdevice->device;
+
+       mutex_lock(&dev->mutex);
+       async->mmap_count++;
+       mutex_unlock(&dev->mutex);
+}
+
+static void comedi_vm_close(struct vm_area_struct *area)
 {
        struct comedi_async *async;
        struct comedi_device *dev;
@@ -1446,15 +1460,13 @@ static void comedi_unmap(struct vm_area_struct *area)
 }
 
 static struct vm_operations_struct comedi_vm_ops = {
-       .close = comedi_unmap,
+       .open = comedi_vm_open,
+       .close = comedi_vm_close,
 };
 
 static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
 {
        const unsigned minor = iminor(file->f_dentry->d_inode);
-       struct comedi_device_file_info *dev_file_info =
-           comedi_get_device_file_info(minor);
-       struct comedi_device *dev = dev_file_info->device;
        struct comedi_async *async = NULL;
        unsigned long start = vma->vm_start;
        unsigned long size;
@@ -1462,6 +1474,15 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
        int i;
        int retval;
        struct comedi_subdevice *s;
+       struct comedi_device_file_info *dev_file_info;
+       struct comedi_device *dev;
+
+       dev_file_info = comedi_get_device_file_info(minor);
+       if (dev_file_info == NULL)
+               return -ENODEV;
+       dev = dev_file_info->device;
+       if (dev == NULL)
+               return -ENODEV;
 
        mutex_lock(&dev->mutex);
        if (!dev->attached) {
@@ -1528,11 +1549,17 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait)
 {
        unsigned int mask = 0;
        const unsigned minor = iminor(file->f_dentry->d_inode);
-       struct comedi_device_file_info *dev_file_info =
-           comedi_get_device_file_info(minor);
-       struct comedi_device *dev = dev_file_info->device;
        struct comedi_subdevice *read_subdev;
        struct comedi_subdevice *write_subdev;
+       struct comedi_device_file_info *dev_file_info;
+       struct comedi_device *dev;
+       dev_file_info = comedi_get_device_file_info(minor);
+
+       if (dev_file_info == NULL)
+               return -ENODEV;
+       dev = dev_file_info->device;
+       if (dev == NULL)
+               return -ENODEV;
 
        mutex_lock(&dev->mutex);
        if (!dev->attached) {
@@ -1578,9 +1605,15 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
        int n, m, count = 0, retval = 0;
        DECLARE_WAITQUEUE(wait, current);
        const unsigned minor = iminor(file->f_dentry->d_inode);
-       struct comedi_device_file_info *dev_file_info =
-           comedi_get_device_file_info(minor);
-       struct comedi_device *dev = dev_file_info->device;
+       struct comedi_device_file_info *dev_file_info;
+       struct comedi_device *dev;
+       dev_file_info = comedi_get_device_file_info(minor);
+
+       if (dev_file_info == NULL)
+               return -ENODEV;
+       dev = dev_file_info->device;
+       if (dev == NULL)
+               return -ENODEV;
 
        if (!dev->attached) {
                DPRINTK("no driver configured on comedi%i\n", dev->minor);
@@ -1640,11 +1673,11 @@ static ssize_t comedi_write(struct file *file, const char __user *buf,
                                retval = -EAGAIN;
                                break;
                        }
+                       schedule();
                        if (signal_pending(current)) {
                                retval = -ERESTARTSYS;
                                break;
                        }
-                       schedule();
                        if (!s->busy)
                                break;
                        if (s->busy != file) {
@@ -1683,9 +1716,15 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
        int n, m, count = 0, retval = 0;
        DECLARE_WAITQUEUE(wait, current);
        const unsigned minor = iminor(file->f_dentry->d_inode);
-       struct comedi_device_file_info *dev_file_info =
-           comedi_get_device_file_info(minor);
-       struct comedi_device *dev = dev_file_info->device;
+       struct comedi_device_file_info *dev_file_info;
+       struct comedi_device *dev;
+       dev_file_info = comedi_get_device_file_info(minor);
+
+       if (dev_file_info == NULL)
+               return -ENODEV;
+       dev = dev_file_info->device;
+       if (dev == NULL)
+               return -ENODEV;
 
        if (!dev->attached) {
                DPRINTK("no driver configured on comedi%i\n", dev->minor);
@@ -1741,11 +1780,11 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
                                retval = -EAGAIN;
                                break;
                        }
+                       schedule();
                        if (signal_pending(current)) {
                                retval = -ERESTARTSYS;
                                break;
                        }
-                       schedule();
                        if (!s->busy) {
                                retval = 0;
                                break;
@@ -1885,11 +1924,17 @@ ok:
 static int comedi_close(struct inode *inode, struct file *file)
 {
        const unsigned minor = iminor(inode);
-       struct comedi_device_file_info *dev_file_info =
-           comedi_get_device_file_info(minor);
-       struct comedi_device *dev = dev_file_info->device;
        struct comedi_subdevice *s = NULL;
        int i;
+       struct comedi_device_file_info *dev_file_info;
+       struct comedi_device *dev;
+       dev_file_info = comedi_get_device_file_info(minor);
+
+       if (dev_file_info == NULL)
+               return -ENODEV;
+       dev = dev_file_info->device;
+       if (dev == NULL)
+               return -ENODEV;
 
        mutex_lock(&dev->mutex);
 
@@ -1923,10 +1968,15 @@ static int comedi_close(struct inode *inode, struct file *file)
 static int comedi_fasync(int fd, struct file *file, int on)
 {
        const unsigned minor = iminor(file->f_dentry->d_inode);
-       struct comedi_device_file_info *dev_file_info =
-           comedi_get_device_file_info(minor);
+       struct comedi_device_file_info *dev_file_info;
+       struct comedi_device *dev;
+       dev_file_info = comedi_get_device_file_info(minor);
 
-       struct comedi_device *dev = dev_file_info->device;
+       if (dev_file_info == NULL)
+               return -ENODEV;
+       dev = dev_file_info->device;
+       if (dev == NULL)
+               return -ENODEV;
 
        return fasync_helper(fd, file, on, &dev->async_queue);
 }
index a8fea9a9173349799c0f2f629d23ce30412cf356..6144afb8cbaaf92a1ca09dfa5404787d72ee35ed 100644 (file)
@@ -1,4 +1,4 @@
-#define DRIVER_VERSION "v0.5"
+#define DRIVER_VERSION "v0.6"
 #define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
 #define DRIVER_DESC "Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com"
 /*
@@ -25,7 +25,7 @@ Driver: usbduxsigma
 Description: University of Stirling USB DAQ & INCITE Technology Limited
 Devices: [ITL] USB-DUX (usbduxsigma.o)
 Author: Bernd Porr <BerndPorr@f2s.com>
-Updated: 21 Jul 2011
+Updated: 8 Nov 2011
 Status: testing
 */
 /*
@@ -44,6 +44,7 @@ Status: testing
  *   0.3: proper vendor ID and driver name
  *   0.4: fixed D/A voltage range
  *   0.5: various bug fixes, health check at startup
+ *   0.6: corrected wrong input range
  */
 
 /* generates loads of debug info */
@@ -175,7 +176,7 @@ Status: testing
 /* comedi constants */
 static const struct comedi_lrange range_usbdux_ai_range = { 1, {
                                                                BIP_RANGE
-                                                               (2.65)
+                                                               (2.65/2.0)
                                                                }
 };
 
index 480b0ed2e4de8975ea315504190c5eff02e5ac59..115635f9502456d7e8e3f16470b7f4a269b23b5b 100644 (file)
@@ -1021,6 +1021,7 @@ static int __devinit rtsx_probe(struct pci_dev *pci,
        th = kthread_create(rtsx_scan_thread, dev, "rtsx-scan");
        if (IS_ERR(th)) {
                printk(KERN_ERR "Unable to start the device-scanning thread\n");
+               complete(&dev->scanning_done);
                quiesce_and_remove_host(dev);
                err = PTR_ERR(th);
                goto errout;
index 09c44abb89e8239c322bacb1671418dcd4b32e0a..3872b8cccdcf715067f273e091f3fd2cf419d6ac 100644 (file)
@@ -68,6 +68,7 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
 {
        struct usbip_device *ud = &vdev->ud;
        struct urb *urb;
+       unsigned long flags;
 
        spin_lock(&vdev->priv_lock);
        urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum);
@@ -101,9 +102,9 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
 
        usbip_dbg_vhci_rx("now giveback urb %p\n", urb);
 
-       spin_lock(&the_controller->lock);
+       spin_lock_irqsave(&the_controller->lock, flags);
        usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
-       spin_unlock(&the_controller->lock);
+       spin_unlock_irqrestore(&the_controller->lock, flags);
 
        usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status);
 
@@ -141,6 +142,7 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev,
 {
        struct vhci_unlink *unlink;
        struct urb *urb;
+       unsigned long flags;
 
        usbip_dump_header(pdu);
 
@@ -170,9 +172,9 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev,
                urb->status = pdu->u.ret_unlink.status;
                pr_info("urb->status %d\n", urb->status);
 
-               spin_lock(&the_controller->lock);
+               spin_lock_irqsave(&the_controller->lock, flags);
                usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
-               spin_unlock(&the_controller->lock);
+               spin_unlock_irqrestore(&the_controller->lock, flags);
 
                usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb,
                                     urb->status);
index 4730016d7cd42d8644e8fb5fa8791fc9df080591..45f422ac103fb61678633ee08241b33b7dfe235a 100644 (file)
@@ -1959,7 +1959,7 @@ static int amd5536_start(struct usb_gadget_driver *driver,
        u32 tmp;
 
        if (!driver || !bind || !driver->setup
-                       || driver->speed != USB_SPEED_HIGH)
+                       || driver->speed < USB_SPEED_HIGH)
                return -EINVAL;
        if (!dev)
                return -ENODEV;
index 91fdf790ed20b122bf0a13df0d3c8aed5285ac3c..cf33a8d0fd5df46ec339f5b481b68dc61121243a 100644 (file)
@@ -131,8 +131,8 @@ static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
        }
        if (!gser->port.in->desc || !gser->port.out->desc) {
                DBG(cdev, "activate generic ttyGS%d\n", gser->port_num);
-               if (!config_ep_by_speed(cdev->gadget, f, gser->port.in) ||
-                   !config_ep_by_speed(cdev->gadget, f, gser->port.out)) {
+               if (config_ep_by_speed(cdev->gadget, f, gser->port.in) ||
+                   config_ep_by_speed(cdev->gadget, f, gser->port.out)) {
                        gser->port.in->desc = NULL;
                        gser->port.out->desc = NULL;
                        return -EINVAL;
index 43a49ecc1f36ed1009eb836350bd07800a4d8c09..dcbc0a2e48dde8be9b27a5c429a4c004bfb8aa9c 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/fsl_devices.h>
 #include <linux/platform_device.h>
+#include <linux/io.h>
 
 #include <mach/hardware.h>
 
@@ -88,7 +89,6 @@ eenahb:
 void fsl_udc_clk_finalize(struct platform_device *pdev)
 {
        struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
-#if defined(CONFIG_SOC_IMX35)
        if (cpu_is_mx35()) {
                unsigned int v;
 
@@ -101,7 +101,6 @@ void fsl_udc_clk_finalize(struct platform_device *pdev)
                                        USBPHYCTRL_OTGBASE_OFFSET));
                }
        }
-#endif
 
        /* ULPI transceivers don't need usbpll */
        if (pdata->phy_mode == FSL_USB2_PHY_ULPI) {
index 2a03e4de11c1a277cfe27b670ac48f11cabc006a..e00cf92409ce5114f061801c3d3e29b6b6bae23e 100644 (file)
@@ -2336,8 +2336,7 @@ static int fsl_qe_start(struct usb_gadget_driver *driver,
        if (!udc_controller)
                return -ENODEV;
 
-       if (!driver || (driver->speed != USB_SPEED_FULL
-                       && driver->speed != USB_SPEED_HIGH)
+       if (!driver || driver->speed < USB_SPEED_FULL
                        || !bind || !driver->disconnect || !driver->setup)
                return -EINVAL;
 
index b3b3d83b7c3354744ec1fc4d4dc2765f19293a7c..dd28ef3def71f394f281b70f8ee2335b629f42e6 100644 (file)
@@ -696,12 +696,31 @@ static void fsl_free_request(struct usb_ep *_ep, struct usb_request *_req)
                kfree(req);
 }
 
-/*-------------------------------------------------------------------------*/
+/* Actually add a dTD chain to an empty dQH and let go */
+static void fsl_prime_ep(struct fsl_ep *ep, struct ep_td_struct *td)
+{
+       struct ep_queue_head *qh = get_qh_by_ep(ep);
+
+       /* Write dQH next pointer and terminate bit to 0 */
+       qh->next_dtd_ptr = cpu_to_hc32(td->td_dma
+                       & EP_QUEUE_HEAD_NEXT_POINTER_MASK);
+
+       /* Clear active and halt bit */
+       qh->size_ioc_int_sts &= cpu_to_hc32(~(EP_QUEUE_HEAD_STATUS_ACTIVE
+                                       | EP_QUEUE_HEAD_STATUS_HALT));
+
+       /* Ensure that updates to the QH will occur before priming. */
+       wmb();
+
+       /* Prime endpoint by writing correct bit to ENDPTPRIME */
+       fsl_writel(ep_is_in(ep) ? (1 << (ep_index(ep) + 16))
+                       : (1 << (ep_index(ep))), &dr_regs->endpointprime);
+}
+
+/* Add dTD chain to the dQH of an EP */
 static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
 {
-       int i = ep_index(ep) * 2 + ep_is_in(ep);
        u32 temp, bitmask, tmp_stat;
-       struct ep_queue_head *dQH = &ep->udc->ep_qh[i];
 
        /* VDBG("QH addr Register 0x%8x", dr_regs->endpointlistaddr);
        VDBG("ep_qh[%d] addr is 0x%8x", i, (u32)&(ep->udc->ep_qh[i])); */
@@ -719,7 +738,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
                        cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK);
                /* Read prime bit, if 1 goto done */
                if (fsl_readl(&dr_regs->endpointprime) & bitmask)
-                       goto out;
+                       return;
 
                do {
                        /* Set ATDTW bit in USBCMD */
@@ -736,28 +755,10 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
                fsl_writel(temp & ~USB_CMD_ATDTW, &dr_regs->usbcmd);
 
                if (tmp_stat)
-                       goto out;
+                       return;
        }
 
-       /* Write dQH next pointer and terminate bit to 0 */
-       temp = req->head->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK;
-       dQH->next_dtd_ptr = cpu_to_hc32(temp);
-
-       /* Clear active and halt bit */
-       temp = cpu_to_hc32(~(EP_QUEUE_HEAD_STATUS_ACTIVE
-                       | EP_QUEUE_HEAD_STATUS_HALT));
-       dQH->size_ioc_int_sts &= temp;
-
-       /* Ensure that updates to the QH will occur before priming. */
-       wmb();
-
-       /* Prime endpoint by writing 1 to ENDPTPRIME */
-       temp = ep_is_in(ep)
-               ? (1 << (ep_index(ep) + 16))
-               : (1 << (ep_index(ep)));
-       fsl_writel(temp, &dr_regs->endpointprime);
-out:
-       return;
+       fsl_prime_ep(ep, req->head);
 }
 
 /* Fill in the dTD structure
@@ -877,7 +878,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
                VDBG("%s, bad ep", __func__);
                return -EINVAL;
        }
-       if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
+       if (usb_endpoint_xfer_isoc(ep->desc)) {
                if (req->req.length > ep->ep.maxpacket)
                        return -EMSGSIZE;
        }
@@ -973,25 +974,20 @@ static int fsl_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
 
                /* The request isn't the last request in this ep queue */
                if (req->queue.next != &ep->queue) {
-                       struct ep_queue_head *qh;
                        struct fsl_req *next_req;
 
-                       qh = ep->qh;
                        next_req = list_entry(req->queue.next, struct fsl_req,
                                        queue);
 
-                       /* Point the QH to the first TD of next request */
-                       fsl_writel((u32) next_req->head, &qh->curr_dtd_ptr);
+                       /* prime with dTD of next request */
+                       fsl_prime_ep(ep, next_req->head);
                }
-
-               /* The request hasn't been processed, patch up the TD chain */
+       /* The request hasn't been processed, patch up the TD chain */
        } else {
                struct fsl_req *prev_req;
 
                prev_req = list_entry(req->queue.prev, struct fsl_req, queue);
-               fsl_writel(fsl_readl(&req->tail->next_td_ptr),
-                               &prev_req->tail->next_td_ptr);
-
+               prev_req->tail->next_td_ptr = req->tail->next_td_ptr;
        }
 
        done(ep, req, -ECONNRESET);
@@ -1032,7 +1028,7 @@ static int fsl_ep_set_halt(struct usb_ep *_ep, int value)
                goto out;
        }
 
-       if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
+       if (usb_endpoint_xfer_isoc(ep->desc)) {
                status = -EOPNOTSUPP;
                goto out;
        }
@@ -1068,7 +1064,7 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep)
        struct fsl_udc *udc;
        int size = 0;
        u32 bitmask;
-       struct ep_queue_head *d_qh;
+       struct ep_queue_head *qh;
 
        ep = container_of(_ep, struct fsl_ep, ep);
        if (!_ep || (!ep->desc && ep_index(ep) != 0))
@@ -1079,13 +1075,13 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep)
        if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)
                return -ESHUTDOWN;
 
-       d_qh = &ep->udc->ep_qh[ep_index(ep) * 2 + ep_is_in(ep)];
+       qh = get_qh_by_ep(ep);
 
        bitmask = (ep_is_in(ep)) ? (1 << (ep_index(ep) + 16)) :
            (1 << (ep_index(ep)));
 
        if (fsl_readl(&dr_regs->endptstatus) & bitmask)
-               size = (d_qh->size_ioc_int_sts & DTD_PACKET_SIZE)
+               size = (qh->size_ioc_int_sts & DTD_PACKET_SIZE)
                    >> DTD_LENGTH_BIT_POS;
 
        pr_debug("%s %u\n", __func__, size);
@@ -1938,8 +1934,7 @@ static int fsl_start(struct usb_gadget_driver *driver,
        if (!udc_controller)
                return -ENODEV;
 
-       if (!driver || (driver->speed != USB_SPEED_FULL
-                               && driver->speed != USB_SPEED_HIGH)
+       if (!driver || driver->speed < USB_SPEED_FULL
                        || !bind || !driver->disconnect || !driver->setup)
                return -EINVAL;
 
index 1d51be83fda87402d4a77a28ff4fa636d17bff62..f781f5dec41776629584a33a1be5817d8e6778d6 100644 (file)
@@ -569,6 +569,16 @@ static void dump_msg(const char *label, const u8 * buf, unsigned int length)
                                        * 2 + ((windex & USB_DIR_IN) ? 1 : 0))
 #define get_pipe_by_ep(EP)     (ep_index(EP) * 2 + ep_is_in(EP))
 
+static inline struct ep_queue_head *get_qh_by_ep(struct fsl_ep *ep)
+{
+       /* we only have one ep0 structure but two queue heads */
+       if (ep_index(ep) != 0)
+               return ep->qh;
+       else
+               return &ep->udc->ep_qh[(ep->udc->ep0_dir ==
+                               USB_DIR_IN) ? 1 : 0];
+}
+
 struct platform_device;
 #ifdef CONFIG_ARCH_MXC
 int fsl_udc_clk_init(struct platform_device *pdev);
index 91d0af2a24a8537728fb5c5cb176ff0108095ab5..9aa1cbbee45b64597ef9bcc44d5ba5ed219b2d6a 100644 (file)
@@ -1472,7 +1472,7 @@ static int m66592_start(struct usb_gadget_driver *driver,
        int retval;
 
        if (!driver
-                       || driver->speed != USB_SPEED_HIGH
+                       || driver->speed < USB_SPEED_HIGH
                        || !bind
                        || !driver->setup)
                return -EINVAL;
index 7f1bc9a73cda5a1fe45f8c053f426407758e0f50..da2b9d0be3ca0d444d9df8ca5f0b7a9800c3d078 100644 (file)
@@ -1881,7 +1881,7 @@ static int net2280_start(struct usb_gadget *_gadget,
         * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE)
         * "must not be used in normal operation"
         */
-       if (!driver || driver->speed != USB_SPEED_HIGH
+       if (!driver || driver->speed < USB_SPEED_HIGH
                        || !driver->setup)
                return -EINVAL;
 
index 24f84b210ce116cfd78e5bae3a1bee383d198ca0..fc719a3f855717b88417aaff8c2e89d9a2723109 100644 (file)
@@ -1746,7 +1746,7 @@ static int r8a66597_start(struct usb_gadget *gadget,
        struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget);
 
        if (!driver
-                       || driver->speed != USB_SPEED_HIGH
+                       || driver->speed < USB_SPEED_HIGH
                        || !driver->setup)
                return -EINVAL;
        if (!r8a66597)
index a552453dc94632cacee3ea5212f60aa4563fa519..b31448229f0b26c3a38014cf59e3339060253cb3 100644 (file)
@@ -2586,10 +2586,8 @@ static int s3c_hsotg_start(struct usb_gadget_driver *driver,
                return -EINVAL;
        }
 
-       if (driver->speed != USB_SPEED_HIGH &&
-           driver->speed != USB_SPEED_FULL) {
+       if (driver->speed < USB_SPEED_FULL)
                dev_err(hsotg->dev, "%s: bad speed\n", __func__);
-       }
 
        if (!bind || !driver->setup) {
                dev_err(hsotg->dev, "%s: missing entry points\n", __func__);
index 8d54f893cefe9df7c97363c1812b4f30bb822ff7..20a553b46aedc1d17ecaeaf033ff62eb8f5f472c 100644 (file)
@@ -1142,8 +1142,7 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver,
        int ret;
 
        if (!driver
-               || (driver->speed != USB_SPEED_FULL &&
-                       driver->speed != USB_SPEED_HIGH)
+               || driver->speed < USB_SPEED_FULL
                || !bind
                || !driver->unbind || !driver->disconnect || !driver->setup)
                return -EINVAL;
index 56a32033adb3485db49484d23619d1f2dcf68071..a60679cbbf858e3c97a978218e16d931635ae1a3 100644 (file)
@@ -1475,6 +1475,7 @@ iso_stream_schedule (
         * jump until after the queue is primed.
         */
        else {
+               int done = 0;
                start = SCHEDULE_SLOP + (now & ~0x07);
 
                /* NOTE:  assumes URB_ISO_ASAP, to limit complexity/bugs */
@@ -1492,18 +1493,18 @@ iso_stream_schedule (
                        if (stream->highspeed) {
                                if (itd_slot_ok(ehci, mod, start,
                                                stream->usecs, period))
-                                       break;
+                                       done = 1;
                        } else {
                                if ((start % 8) >= 6)
                                        continue;
                                if (sitd_slot_ok(ehci, mod, stream,
                                                start, sched, period))
-                                       break;
+                                       done = 1;
                        }
-               } while (start > next);
+               } while (start > next && !done);
 
                /* no room in the schedule */
-               if (start == next) {
+               if (!done) {
                        ehci_dbg(ehci, "iso resched full %p (now %d max %d)\n",
                                urb, now, now + mod);
                        status = -ENOSPC;
index d6e175428618d4b31f69bd3d323e7c5aef93deae..a403b53e86b9fd3dcc742b9da5759330fbc4d212 100644 (file)
@@ -124,7 +124,7 @@ void qset_clear(struct whc *whc, struct whc_qset *qset)
 {
        qset->td_start = qset->td_end = qset->ntds = 0;
 
-       qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T);
+       qset->qh.link = cpu_to_le64(QH_LINK_NTDS(8) | QH_LINK_T);
        qset->qh.status = qset->qh.status & QH_STATUS_SEQ_MASK;
        qset->qh.err_count = 0;
        qset->qh.scratch[0] = 0;
index aa94c01957919001e6a5804c7bc0434b923f20bc..a1afb7c39f7e70c36c12a8bccdc0a0b64b7f29d3 100644 (file)
@@ -711,7 +711,10 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
        ring = xhci->cmd_ring;
        seg = ring->deq_seg;
        do {
-               memset(seg->trbs, 0, SEGMENT_SIZE);
+               memset(seg->trbs, 0,
+                       sizeof(union xhci_trb) * (TRBS_PER_SEGMENT - 1));
+               seg->trbs[TRBS_PER_SEGMENT - 1].link.control &=
+                       cpu_to_le32(~TRB_CYCLE);
                seg = seg->next;
        } while (seg != ring->deq_seg);
 
index c1fa12ec7a9ad456a23c761f5c328a721182a070..b63ab1570103f2219afc5b44bdea08acd0531054 100644 (file)
@@ -2301,18 +2301,12 @@ static int musb_suspend(struct device *dev)
                 */
        }
 
-       musb_save_context(musb);
-
        spin_unlock_irqrestore(&musb->lock, flags);
        return 0;
 }
 
 static int musb_resume_noirq(struct device *dev)
 {
-       struct musb     *musb = dev_to_musb(dev);
-
-       musb_restore_context(musb);
-
        /* for static cmos like DaVinci, register values were preserved
         * unless for some reason the whole soc powered down or the USB
         * module got reset through the PSC (vs just being disabled).
index d51043acfe1abc5013217e70b4854e153f8bdf96..922148ff8d2969de64a808046f7ce06c6115ace1 100644 (file)
@@ -1903,7 +1903,7 @@ static int musb_gadget_start(struct usb_gadget *g,
        unsigned long           flags;
        int                     retval = -EINVAL;
 
-       if (driver->speed != USB_SPEED_HIGH)
+       if (driver->speed < USB_SPEED_HIGH)
                goto err0;
 
        pm_runtime_get_sync(musb->controller);
index d9717e0bc1ff65c6d23cae4bf0693c434d8873fe..7f4e803385702499b70e4a40fce377bc28a1e45f 100644 (file)
@@ -751,53 +751,32 @@ static int usbhsg_gadget_start(struct usb_gadget *gadget,
                struct usb_gadget_driver *driver)
 {
        struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget);
-       struct usbhs_priv *priv;
-       struct device *dev;
-       int ret;
+       struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
 
        if (!driver             ||
            !driver->setup      ||
-           driver->speed != USB_SPEED_HIGH)
+           driver->speed < USB_SPEED_FULL)
                return -EINVAL;
 
-       dev  = usbhsg_gpriv_to_dev(gpriv);
-       priv = usbhsg_gpriv_to_priv(gpriv);
-
        /* first hook up the driver ... */
        gpriv->driver = driver;
        gpriv->gadget.dev.driver = &driver->driver;
 
-       ret = device_add(&gpriv->gadget.dev);
-       if (ret) {
-               dev_err(dev, "device_add error %d\n", ret);
-               goto add_fail;
-       }
-
        return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD);
-
-add_fail:
-       gpriv->driver = NULL;
-       gpriv->gadget.dev.driver = NULL;
-
-       return ret;
 }
 
 static int usbhsg_gadget_stop(struct usb_gadget *gadget,
                struct usb_gadget_driver *driver)
 {
        struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget);
-       struct usbhs_priv *priv;
-       struct device *dev;
+       struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
 
        if (!driver             ||
            !driver->unbind)
                return -EINVAL;
 
-       dev  = usbhsg_gpriv_to_dev(gpriv);
-       priv = usbhsg_gpriv_to_priv(gpriv);
-
        usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD);
-       device_del(&gpriv->gadget.dev);
+       gpriv->gadget.dev.driver = NULL;
        gpriv->driver = NULL;
 
        return 0;
@@ -827,6 +806,13 @@ static int usbhsg_start(struct usbhs_priv *priv)
 
 static int usbhsg_stop(struct usbhs_priv *priv)
 {
+       struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
+
+       /* cable disconnect */
+       if (gpriv->driver &&
+           gpriv->driver->disconnect)
+               gpriv->driver->disconnect(&gpriv->gadget);
+
        return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED);
 }
 
@@ -876,12 +862,14 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
        /*
         * init gadget
         */
-       device_initialize(&gpriv->gadget.dev);
        dev_set_name(&gpriv->gadget.dev, "gadget");
        gpriv->gadget.dev.parent        = dev;
        gpriv->gadget.name              = "renesas_usbhs_udc";
        gpriv->gadget.ops               = &usbhsg_gadget_ops;
        gpriv->gadget.is_dualspeed      = 1;
+       ret = device_register(&gpriv->gadget.dev);
+       if (ret < 0)
+               goto err_add_udc;
 
        INIT_LIST_HEAD(&gpriv->gadget.ep_list);
 
@@ -912,12 +900,15 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
 
        ret = usb_add_gadget_udc(dev, &gpriv->gadget);
        if (ret)
-               goto err_add_udc;
+               goto err_register;
 
 
        dev_info(dev, "gadget probed\n");
 
        return 0;
+
+err_register:
+       device_unregister(&gpriv->gadget.dev);
 err_add_udc:
        kfree(gpriv->uep);
 
@@ -933,6 +924,8 @@ void usbhs_mod_gadget_remove(struct usbhs_priv *priv)
 
        usb_del_gadget_udc(&gpriv->gadget);
 
+       device_unregister(&gpriv->gadget.dev);
+
        usbhsg_controller_unregister(gpriv);
 
        kfree(gpriv->uep);
index bd4298bb6750d347f825c47026b8de0acb7096a1..ff3db5d056a56484fe594039f5817ac7d6ec4024 100644 (file)
@@ -736,6 +736,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_PROPOX_ISPCABLEIII_PID) },
        { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID),
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
        { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID),
index 571fa96b49c7749b983c8d4a8f8228f3500f975c..055b64ef0bbad7ad6dd20200860c6874dd120f1e 100644 (file)
 
 /* Propox devices */
 #define FTDI_PROPOX_JTAGCABLEII_PID    0xD738
+#define FTDI_PROPOX_ISPCABLEIII_PID    0xD739
 
 /* Lenz LI-USB Computer Interface. */
 #define FTDI_LENZ_LIUSB_PID    0xD780
index d865878c9f97449a6168fd69198af63f647ac497..e3426602dc8274dc5536f26e80f74a481eeaacd3 100644 (file)
@@ -661,6 +661,9 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) },
+       { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x08) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) },
@@ -747,6 +750,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
+       { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */
        { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) },
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
index 3041a974faf39278ef8fad4033e089f8e64b7b9c..24caba79d722a74fd2dba94f9560a7168e4bb26c 100644 (file)
@@ -1854,6 +1854,13 @@ UNUSUAL_DEV(  0x1370, 0x6828, 0x0110, 0x0110,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_IGNORE_RESIDUE ),
 
+/* Reported by Qinglin Ye <yestyle@gmail.com> */
+UNUSUAL_DEV(  0x13fe, 0x3600, 0x0100, 0x0100,
+               "Kingston",
+               "DT 101 G2",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_BULK_IGNORE_TAG ),
+
 /* Reported by Francesco Foresti <frafore@tiscali.it> */
 UNUSUAL_DEV(  0x14cd, 0x6600, 0x0201, 0x0201,
                "Super Top",
index ed553c60de827e0ebad24e3501e0e00d21c82cfc..3165aebb43c87934b743ecf08e5f02cef586d771 100644 (file)
@@ -5699,7 +5699,7 @@ int ocfs2_remove_btree_range(struct inode *inode,
                                           OCFS2_JOURNAL_ACCESS_WRITE);
        if (ret) {
                mlog_errno(ret);
-               goto out;
+               goto out_commit;
        }
 
        dquot_free_space_nodirty(inode,
index c1efe939c774e2c9b909892f6c95434d6da760ee..78b68af3b0e32627b1874277d8ae58003501acb5 100644 (file)
@@ -290,7 +290,15 @@ static int ocfs2_readpage(struct file *file, struct page *page)
        }
 
        if (down_read_trylock(&oi->ip_alloc_sem) == 0) {
+               /*
+                * Unlock the page and cycle ip_alloc_sem so that we don't
+                * busyloop waiting for ip_alloc_sem to unlock
+                */
                ret = AOP_TRUNCATED_PAGE;
+               unlock_page(page);
+               unlock = 0;
+               down_read(&oi->ip_alloc_sem);
+               up_read(&oi->ip_alloc_sem);
                goto out_inode_unlock;
        }
 
@@ -563,6 +571,7 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
 {
        struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
        int level;
+       wait_queue_head_t *wq = ocfs2_ioend_wq(inode);
 
        /* this io's submitter should not have unlocked this before we could */
        BUG_ON(!ocfs2_iocb_is_rw_locked(iocb));
@@ -570,6 +579,15 @@ static void ocfs2_dio_end_io(struct kiocb *iocb,
        if (ocfs2_iocb_is_sem_locked(iocb))
                ocfs2_iocb_clear_sem_locked(iocb);
 
+       if (ocfs2_iocb_is_unaligned_aio(iocb)) {
+               ocfs2_iocb_clear_unaligned_aio(iocb);
+
+               if (atomic_dec_and_test(&OCFS2_I(inode)->ip_unaligned_aio) &&
+                   waitqueue_active(wq)) {
+                       wake_up_all(wq);
+               }
+       }
+
        ocfs2_iocb_clear_rw_locked(iocb);
 
        level = ocfs2_iocb_rw_locked_level(iocb);
@@ -862,6 +880,12 @@ struct ocfs2_write_ctxt {
        struct page                     *w_pages[OCFS2_MAX_CTXT_PAGES];
        struct page                     *w_target_page;
 
+       /*
+        * w_target_locked is used for page_mkwrite path indicating no unlocking
+        * against w_target_page in ocfs2_write_end_nolock.
+        */
+       unsigned int                    w_target_locked:1;
+
        /*
         * ocfs2_write_end() uses this to know what the real range to
         * write in the target should be.
@@ -895,6 +919,24 @@ void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages)
 
 static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
 {
+       int i;
+
+       /*
+        * w_target_locked is only set to true in the page_mkwrite() case.
+        * The intent is to allow us to lock the target page from write_begin()
+        * to write_end(). The caller must hold a ref on w_target_page.
+        */
+       if (wc->w_target_locked) {
+               BUG_ON(!wc->w_target_page);
+               for (i = 0; i < wc->w_num_pages; i++) {
+                       if (wc->w_target_page == wc->w_pages[i]) {
+                               wc->w_pages[i] = NULL;
+                               break;
+                       }
+               }
+               mark_page_accessed(wc->w_target_page);
+               page_cache_release(wc->w_target_page);
+       }
        ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages);
 
        brelse(wc->w_di_bh);
@@ -1132,20 +1174,17 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
                         */
                        lock_page(mmap_page);
 
+                       /* Exit and let the caller retry */
                        if (mmap_page->mapping != mapping) {
+                               WARN_ON(mmap_page->mapping);
                                unlock_page(mmap_page);
-                               /*
-                                * Sanity check - the locking in
-                                * ocfs2_pagemkwrite() should ensure
-                                * that this code doesn't trigger.
-                                */
-                               ret = -EINVAL;
-                               mlog_errno(ret);
+                               ret = -EAGAIN;
                                goto out;
                        }
 
                        page_cache_get(mmap_page);
                        wc->w_pages[i] = mmap_page;
+                       wc->w_target_locked = true;
                } else {
                        wc->w_pages[i] = find_or_create_page(mapping, index,
                                                             GFP_NOFS);
@@ -1160,6 +1199,8 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping,
                        wc->w_target_page = wc->w_pages[i];
        }
 out:
+       if (ret)
+               wc->w_target_locked = false;
        return ret;
 }
 
@@ -1817,11 +1858,23 @@ try_again:
         */
        ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, len,
                                         cluster_of_pages, mmap_page);
-       if (ret) {
+       if (ret && ret != -EAGAIN) {
                mlog_errno(ret);
                goto out_quota;
        }
 
+       /*
+        * ocfs2_grab_pages_for_write() returns -EAGAIN if it could not lock
+        * the target page. In this case, we exit with no error and no target
+        * page. This will trigger the caller, page_mkwrite(), to re-try
+        * the operation.
+        */
+       if (ret == -EAGAIN) {
+               BUG_ON(wc->w_target_page);
+               ret = 0;
+               goto out_quota;
+       }
+
        ret = ocfs2_write_cluster_by_desc(mapping, data_ac, meta_ac, wc, pos,
                                          len);
        if (ret) {
index 75cf3ad987a66d911c15234a803243185ccc5a94..ffb2da370a99d05dd4b919fc64a5483dbc2df7a3 100644 (file)
@@ -78,6 +78,7 @@ enum ocfs2_iocb_lock_bits {
        OCFS2_IOCB_RW_LOCK = 0,
        OCFS2_IOCB_RW_LOCK_LEVEL,
        OCFS2_IOCB_SEM,
+       OCFS2_IOCB_UNALIGNED_IO,
        OCFS2_IOCB_NUM_LOCKS
 };
 
@@ -91,4 +92,17 @@ enum ocfs2_iocb_lock_bits {
        clear_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
 #define ocfs2_iocb_is_sem_locked(iocb) \
        test_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private)
+
+#define ocfs2_iocb_set_unaligned_aio(iocb) \
+       set_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_clear_unaligned_aio(iocb) \
+       clear_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_is_unaligned_aio(iocb) \
+       test_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private)
+
+#define OCFS2_IOEND_WQ_HASH_SZ 37
+#define ocfs2_ioend_wq(v)   (&ocfs2__ioend_wq[((unsigned long)(v)) %\
+                                           OCFS2_IOEND_WQ_HASH_SZ])
+extern wait_queue_head_t ocfs2__ioend_wq[OCFS2_IOEND_WQ_HASH_SZ];
+
 #endif /* OCFS2_FILE_H */
index 9a3e6bbff27bd4839b487c2c14282fd9ef1a4675..a4e855e3690e6ab844d37788b71649975321cb19 100644 (file)
@@ -216,6 +216,7 @@ struct o2hb_region {
 
        struct list_head        hr_all_item;
        unsigned                hr_unclean_stop:1,
+                               hr_aborted_start:1,
                                hr_item_pinned:1,
                                hr_item_dropped:1;
 
@@ -254,6 +255,10 @@ struct o2hb_region {
         * a more complete api that doesn't lead to this sort of fragility. */
        atomic_t                hr_steady_iterations;
 
+       /* terminate o2hb thread if it does not reach steady state
+        * (hr_steady_iterations == 0) within hr_unsteady_iterations */
+       atomic_t                hr_unsteady_iterations;
+
        char                    hr_dev_name[BDEVNAME_SIZE];
 
        unsigned int            hr_timeout_ms;
@@ -324,6 +329,10 @@ static void o2hb_write_timeout(struct work_struct *work)
 
 static void o2hb_arm_write_timeout(struct o2hb_region *reg)
 {
+       /* Arm writeout only after thread reaches steady state */
+       if (atomic_read(&reg->hr_steady_iterations) != 0)
+               return;
+
        mlog(ML_HEARTBEAT, "Queue write timeout for %u ms\n",
             O2HB_MAX_WRITE_TIMEOUT_MS);
 
@@ -537,9 +546,14 @@ static int o2hb_verify_crc(struct o2hb_region *reg,
        return read == computed;
 }
 
-/* We want to make sure that nobody is heartbeating on top of us --
- * this will help detect an invalid configuration. */
-static void o2hb_check_last_timestamp(struct o2hb_region *reg)
+/*
+ * Compare the slot data with what we wrote in the last iteration.
+ * If the match fails, print an appropriate error message. This is to
+ * detect errors like... another node hearting on the same slot,
+ * flaky device that is losing writes, etc.
+ * Returns 1 if check succeeds, 0 otherwise.
+ */
+static int o2hb_check_own_slot(struct o2hb_region *reg)
 {
        struct o2hb_disk_slot *slot;
        struct o2hb_disk_heartbeat_block *hb_block;
@@ -548,13 +562,13 @@ static void o2hb_check_last_timestamp(struct o2hb_region *reg)
        slot = &reg->hr_slots[o2nm_this_node()];
        /* Don't check on our 1st timestamp */
        if (!slot->ds_last_time)
-               return;
+               return 0;
 
        hb_block = slot->ds_raw_block;
        if (le64_to_cpu(hb_block->hb_seq) == slot->ds_last_time &&
            le64_to_cpu(hb_block->hb_generation) == slot->ds_last_generation &&
            hb_block->hb_node == slot->ds_node_num)
-               return;
+               return 1;
 
 #define ERRSTR1                "Another node is heartbeating on device"
 #define ERRSTR2                "Heartbeat generation mismatch on device"
@@ -574,6 +588,8 @@ static void o2hb_check_last_timestamp(struct o2hb_region *reg)
             (unsigned long long)slot->ds_last_time, hb_block->hb_node,
             (unsigned long long)le64_to_cpu(hb_block->hb_generation),
             (unsigned long long)le64_to_cpu(hb_block->hb_seq));
+
+       return 0;
 }
 
 static inline void o2hb_prepare_block(struct o2hb_region *reg,
@@ -719,17 +735,24 @@ static void o2hb_shutdown_slot(struct o2hb_disk_slot *slot)
        o2nm_node_put(node);
 }
 
-static void o2hb_set_quorum_device(struct o2hb_region *reg,
-                                  struct o2hb_disk_slot *slot)
+static void o2hb_set_quorum_device(struct o2hb_region *reg)
 {
-       assert_spin_locked(&o2hb_live_lock);
-
        if (!o2hb_global_heartbeat_active())
                return;
 
-       if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
+       /* Prevent race with o2hb_heartbeat_group_drop_item() */
+       if (kthread_should_stop())
+               return;
+
+       /* Tag region as quorum only after thread reaches steady state */
+       if (atomic_read(&reg->hr_steady_iterations) != 0)
                return;
 
+       spin_lock(&o2hb_live_lock);
+
+       if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
+               goto unlock;
+
        /*
         * A region can be added to the quorum only when it sees all
         * live nodes heartbeat on it. In other words, the region has been
@@ -737,13 +760,10 @@ static void o2hb_set_quorum_device(struct o2hb_region *reg,
         */
        if (memcmp(reg->hr_live_node_bitmap, o2hb_live_node_bitmap,
                   sizeof(o2hb_live_node_bitmap)))
-               return;
-
-       if (slot->ds_changed_samples < O2HB_LIVE_THRESHOLD)
-               return;
+               goto unlock;
 
-       printk(KERN_NOTICE "o2hb: Region %s is now a quorum device\n",
-              config_item_name(&reg->hr_item));
+       printk(KERN_NOTICE "o2hb: Region %s (%s) is now a quorum device\n",
+              config_item_name(&reg->hr_item), reg->hr_dev_name);
 
        set_bit(reg->hr_region_num, o2hb_quorum_region_bitmap);
 
@@ -754,6 +774,8 @@ static void o2hb_set_quorum_device(struct o2hb_region *reg,
        if (o2hb_pop_count(&o2hb_quorum_region_bitmap,
                           O2NM_MAX_REGIONS) > O2HB_PIN_CUT_OFF)
                o2hb_region_unpin(NULL);
+unlock:
+       spin_unlock(&o2hb_live_lock);
 }
 
 static int o2hb_check_slot(struct o2hb_region *reg,
@@ -925,8 +947,6 @@ fire_callbacks:
                slot->ds_equal_samples = 0;
        }
 out:
-       o2hb_set_quorum_device(reg, slot);
-
        spin_unlock(&o2hb_live_lock);
 
        o2hb_run_event_list(&event);
@@ -957,7 +977,8 @@ static int o2hb_highest_node(unsigned long *nodes,
 
 static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
 {
-       int i, ret, highest_node, change = 0;
+       int i, ret, highest_node;
+       int membership_change = 0, own_slot_ok = 0;
        unsigned long configured_nodes[BITS_TO_LONGS(O2NM_MAX_NODES)];
        unsigned long live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
        struct o2hb_bio_wait_ctxt write_wc;
@@ -966,7 +987,7 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
                                       sizeof(configured_nodes));
        if (ret) {
                mlog_errno(ret);
-               return ret;
+               goto bail;
        }
 
        /*
@@ -982,8 +1003,9 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
 
        highest_node = o2hb_highest_node(configured_nodes, O2NM_MAX_NODES);
        if (highest_node >= O2NM_MAX_NODES) {
-               mlog(ML_NOTICE, "ocfs2_heartbeat: no configured nodes found!\n");
-               return -EINVAL;
+               mlog(ML_NOTICE, "o2hb: No configured nodes found!\n");
+               ret = -EINVAL;
+               goto bail;
        }
 
        /* No sense in reading the slots of nodes that don't exist
@@ -993,29 +1015,27 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
        ret = o2hb_read_slots(reg, highest_node + 1);
        if (ret < 0) {
                mlog_errno(ret);
-               return ret;
+               goto bail;
        }
 
        /* With an up to date view of the slots, we can check that no
         * other node has been improperly configured to heartbeat in
         * our slot. */
-       o2hb_check_last_timestamp(reg);
+       own_slot_ok = o2hb_check_own_slot(reg);
 
        /* fill in the proper info for our next heartbeat */
        o2hb_prepare_block(reg, reg->hr_generation);
 
-       /* And fire off the write. Note that we don't wait on this I/O
-        * until later. */
        ret = o2hb_issue_node_write(reg, &write_wc);
        if (ret < 0) {
                mlog_errno(ret);
-               return ret;
+               goto bail;
        }
 
        i = -1;
        while((i = find_next_bit(configured_nodes,
                                 O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) {
-               change |= o2hb_check_slot(reg, &reg->hr_slots[i]);
+               membership_change |= o2hb_check_slot(reg, &reg->hr_slots[i]);
        }
 
        /*
@@ -1030,18 +1050,39 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg)
                 * disk */
                mlog(ML_ERROR, "Write error %d on device \"%s\"\n",
                     write_wc.wc_error, reg->hr_dev_name);
-               return write_wc.wc_error;
+               ret = write_wc.wc_error;
+               goto bail;
        }
 
-       o2hb_arm_write_timeout(reg);
+       /* Skip disarming the timeout if own slot has stale/bad data */
+       if (own_slot_ok) {
+               o2hb_set_quorum_device(reg);
+               o2hb_arm_write_timeout(reg);
+       }
 
+bail:
        /* let the person who launched us know when things are steady */
-       if (!change && (atomic_read(&reg->hr_steady_iterations) != 0)) {
-               if (atomic_dec_and_test(&reg->hr_steady_iterations))
+       if (atomic_read(&reg->hr_steady_iterations) != 0) {
+               if (!ret && own_slot_ok && !membership_change) {
+                       if (atomic_dec_and_test(&reg->hr_steady_iterations))
+                               wake_up(&o2hb_steady_queue);
+               }
+       }
+
+       if (atomic_read(&reg->hr_steady_iterations) != 0) {
+               if (atomic_dec_and_test(&reg->hr_unsteady_iterations)) {
+                       printk(KERN_NOTICE "o2hb: Unable to stabilize "
+                              "heartbeart on region %s (%s)\n",
+                              config_item_name(&reg->hr_item),
+                              reg->hr_dev_name);
+                       atomic_set(&reg->hr_steady_iterations, 0);
+                       reg->hr_aborted_start = 1;
                        wake_up(&o2hb_steady_queue);
+                       ret = -EIO;
+               }
        }
 
-       return 0;
+       return ret;
 }
 
 /* Subtract b from a, storing the result in a. a *must* have a larger
@@ -1095,7 +1136,8 @@ static int o2hb_thread(void *data)
        /* Pin node */
        o2nm_depend_this_node();
 
-       while (!kthread_should_stop() && !reg->hr_unclean_stop) {
+       while (!kthread_should_stop() &&
+              !reg->hr_unclean_stop && !reg->hr_aborted_start) {
                /* We track the time spent inside
                 * o2hb_do_disk_heartbeat so that we avoid more than
                 * hr_timeout_ms between disk writes. On busy systems
@@ -1103,10 +1145,7 @@ static int o2hb_thread(void *data)
                 * likely to time itself out. */
                do_gettimeofday(&before_hb);
 
-               i = 0;
-               do {
-                       ret = o2hb_do_disk_heartbeat(reg);
-               } while (ret && ++i < 2);
+               ret = o2hb_do_disk_heartbeat(reg);
 
                do_gettimeofday(&after_hb);
                elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb);
@@ -1117,7 +1156,8 @@ static int o2hb_thread(void *data)
                     after_hb.tv_sec, (unsigned long) after_hb.tv_usec,
                     elapsed_msec);
 
-               if (elapsed_msec < reg->hr_timeout_ms) {
+               if (!kthread_should_stop() &&
+                   elapsed_msec < reg->hr_timeout_ms) {
                        /* the kthread api has blocked signals for us so no
                         * need to record the return value. */
                        msleep_interruptible(reg->hr_timeout_ms - elapsed_msec);
@@ -1134,20 +1174,20 @@ static int o2hb_thread(void *data)
         * to timeout on this region when we could just as easily
         * write a clear generation - thus indicating to them that
         * this node has left this region.
-        *
-        * XXX: Should we skip this on unclean_stop? */
-       o2hb_prepare_block(reg, 0);
-       ret = o2hb_issue_node_write(reg, &write_wc);
-       if (ret == 0) {
-               o2hb_wait_on_io(reg, &write_wc);
-       } else {
-               mlog_errno(ret);
+        */
+       if (!reg->hr_unclean_stop && !reg->hr_aborted_start) {
+               o2hb_prepare_block(reg, 0);
+               ret = o2hb_issue_node_write(reg, &write_wc);
+               if (ret == 0)
+                       o2hb_wait_on_io(reg, &write_wc);
+               else
+                       mlog_errno(ret);
        }
 
        /* Unpin node */
        o2nm_undepend_this_node();
 
-       mlog(ML_HEARTBEAT|ML_KTHREAD, "hb thread exiting\n");
+       mlog(ML_HEARTBEAT|ML_KTHREAD, "o2hb thread exiting\n");
 
        return 0;
 }
@@ -1158,6 +1198,7 @@ static int o2hb_debug_open(struct inode *inode, struct file *file)
        struct o2hb_debug_buf *db = inode->i_private;
        struct o2hb_region *reg;
        unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+       unsigned long lts;
        char *buf = NULL;
        int i = -1;
        int out = 0;
@@ -1194,9 +1235,11 @@ static int o2hb_debug_open(struct inode *inode, struct file *file)
 
        case O2HB_DB_TYPE_REGION_ELAPSED_TIME:
                reg = (struct o2hb_region *)db->db_data;
-               out += snprintf(buf + out, PAGE_SIZE - out, "%u\n",
-                               jiffies_to_msecs(jiffies -
-                                                reg->hr_last_timeout_start));
+               lts = reg->hr_last_timeout_start;
+               /* If 0, it has never been set before */
+               if (lts)
+                       lts = jiffies_to_msecs(jiffies - lts);
+               out += snprintf(buf + out, PAGE_SIZE - out, "%lu\n", lts);
                goto done;
 
        case O2HB_DB_TYPE_REGION_PINNED:
@@ -1426,6 +1469,8 @@ static void o2hb_region_release(struct config_item *item)
        struct page *page;
        struct o2hb_region *reg = to_o2hb_region(item);
 
+       mlog(ML_HEARTBEAT, "hb region release (%s)\n", reg->hr_dev_name);
+
        if (reg->hr_tmp_block)
                kfree(reg->hr_tmp_block);
 
@@ -1792,7 +1837,10 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
                        live_threshold <<= 1;
                spin_unlock(&o2hb_live_lock);
        }
-       atomic_set(&reg->hr_steady_iterations, live_threshold + 1);
+       ++live_threshold;
+       atomic_set(&reg->hr_steady_iterations, live_threshold);
+       /* unsteady_iterations is double the steady_iterations */
+       atomic_set(&reg->hr_unsteady_iterations, (live_threshold << 1));
 
        hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s",
                              reg->hr_item.ci_name);
@@ -1809,14 +1857,12 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
        ret = wait_event_interruptible(o2hb_steady_queue,
                                atomic_read(&reg->hr_steady_iterations) == 0);
        if (ret) {
-               /* We got interrupted (hello ptrace!).  Clean up */
-               spin_lock(&o2hb_live_lock);
-               hb_task = reg->hr_task;
-               reg->hr_task = NULL;
-               spin_unlock(&o2hb_live_lock);
+               atomic_set(&reg->hr_steady_iterations, 0);
+               reg->hr_aborted_start = 1;
+       }
 
-               if (hb_task)
-                       kthread_stop(hb_task);
+       if (reg->hr_aborted_start) {
+               ret = -EIO;
                goto out;
        }
 
@@ -1833,8 +1879,8 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
                ret = -EIO;
 
        if (hb_task && o2hb_global_heartbeat_active())
-               printk(KERN_NOTICE "o2hb: Heartbeat started on region %s\n",
-                      config_item_name(&reg->hr_item));
+               printk(KERN_NOTICE "o2hb: Heartbeat started on region %s (%s)\n",
+                      config_item_name(&reg->hr_item), reg->hr_dev_name);
 
 out:
        if (filp)
@@ -2092,13 +2138,6 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group,
 
        /* stop the thread when the user removes the region dir */
        spin_lock(&o2hb_live_lock);
-       if (o2hb_global_heartbeat_active()) {
-               clear_bit(reg->hr_region_num, o2hb_region_bitmap);
-               clear_bit(reg->hr_region_num, o2hb_live_region_bitmap);
-               if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
-                       quorum_region = 1;
-               clear_bit(reg->hr_region_num, o2hb_quorum_region_bitmap);
-       }
        hb_task = reg->hr_task;
        reg->hr_task = NULL;
        reg->hr_item_dropped = 1;
@@ -2107,19 +2146,30 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group,
        if (hb_task)
                kthread_stop(hb_task);
 
+       if (o2hb_global_heartbeat_active()) {
+               spin_lock(&o2hb_live_lock);
+               clear_bit(reg->hr_region_num, o2hb_region_bitmap);
+               clear_bit(reg->hr_region_num, o2hb_live_region_bitmap);
+               if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap))
+                       quorum_region = 1;
+               clear_bit(reg->hr_region_num, o2hb_quorum_region_bitmap);
+               spin_unlock(&o2hb_live_lock);
+               printk(KERN_NOTICE "o2hb: Heartbeat %s on region %s (%s)\n",
+                      ((atomic_read(&reg->hr_steady_iterations) == 0) ?
+                       "stopped" : "start aborted"), config_item_name(item),
+                      reg->hr_dev_name);
+       }
+
        /*
         * If we're racing a dev_write(), we need to wake them.  They will
         * check reg->hr_task
         */
        if (atomic_read(&reg->hr_steady_iterations) != 0) {
+               reg->hr_aborted_start = 1;
                atomic_set(&reg->hr_steady_iterations, 0);
                wake_up(&o2hb_steady_queue);
        }
 
-       if (o2hb_global_heartbeat_active())
-               printk(KERN_NOTICE "o2hb: Heartbeat stopped on region %s\n",
-                      config_item_name(&reg->hr_item));
-
        config_item_put(item);
 
        if (!o2hb_global_heartbeat_active() || !quorum_region)
index 3a5835904b3db4d522c561908171f528bb74f6bd..dc45deb19e6885e56a1f5be46cbd39444c46f810 100644 (file)
@@ -47,6 +47,7 @@
 #define SC_DEBUG_NAME          "sock_containers"
 #define NST_DEBUG_NAME         "send_tracking"
 #define STATS_DEBUG_NAME       "stats"
+#define NODES_DEBUG_NAME       "connected_nodes"
 
 #define SHOW_SOCK_CONTAINERS   0
 #define SHOW_SOCK_STATS                1
@@ -55,6 +56,7 @@ static struct dentry *o2net_dentry;
 static struct dentry *sc_dentry;
 static struct dentry *nst_dentry;
 static struct dentry *stats_dentry;
+static struct dentry *nodes_dentry;
 
 static DEFINE_SPINLOCK(o2net_debug_lock);
 
@@ -491,53 +493,87 @@ static const struct file_operations sc_seq_fops = {
        .release = sc_fop_release,
 };
 
-int o2net_debugfs_init(void)
+static int o2net_fill_bitmap(char *buf, int len)
 {
-       o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL);
-       if (!o2net_dentry) {
-               mlog_errno(-ENOMEM);
-               goto bail;
-       }
+       unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+       int i = -1, out = 0;
 
-       nst_dentry = debugfs_create_file(NST_DEBUG_NAME, S_IFREG|S_IRUSR,
-                                        o2net_dentry, NULL,
-                                        &nst_seq_fops);
-       if (!nst_dentry) {
-               mlog_errno(-ENOMEM);
-               goto bail;
-       }
+       o2net_fill_node_map(map, sizeof(map));
 
-       sc_dentry = debugfs_create_file(SC_DEBUG_NAME, S_IFREG|S_IRUSR,
-                                       o2net_dentry, NULL,
-                                       &sc_seq_fops);
-       if (!sc_dentry) {
-               mlog_errno(-ENOMEM);
-               goto bail;
-       }
+       while ((i = find_next_bit(map, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES)
+               out += snprintf(buf + out, PAGE_SIZE - out, "%d ", i);
+       out += snprintf(buf + out, PAGE_SIZE - out, "\n");
 
-       stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, S_IFREG|S_IRUSR,
-                                          o2net_dentry, NULL,
-                                          &stats_seq_fops);
-       if (!stats_dentry) {
-               mlog_errno(-ENOMEM);
-               goto bail;
-       }
+       return out;
+}
+
+static int nodes_fop_open(struct inode *inode, struct file *file)
+{
+       char *buf;
+
+       buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       i_size_write(inode, o2net_fill_bitmap(buf, PAGE_SIZE));
+
+       file->private_data = buf;
 
        return 0;
-bail:
-       debugfs_remove(stats_dentry);
-       debugfs_remove(sc_dentry);
-       debugfs_remove(nst_dentry);
-       debugfs_remove(o2net_dentry);
-       return -ENOMEM;
 }
 
+static int o2net_debug_release(struct inode *inode, struct file *file)
+{
+       kfree(file->private_data);
+       return 0;
+}
+
+static ssize_t o2net_debug_read(struct file *file, char __user *buf,
+                               size_t nbytes, loff_t *ppos)
+{
+       return simple_read_from_buffer(buf, nbytes, ppos, file->private_data,
+                                      i_size_read(file->f_mapping->host));
+}
+
+static const struct file_operations nodes_fops = {
+       .open           = nodes_fop_open,
+       .release        = o2net_debug_release,
+       .read           = o2net_debug_read,
+       .llseek         = generic_file_llseek,
+};
+
 void o2net_debugfs_exit(void)
 {
+       debugfs_remove(nodes_dentry);
        debugfs_remove(stats_dentry);
        debugfs_remove(sc_dentry);
        debugfs_remove(nst_dentry);
        debugfs_remove(o2net_dentry);
 }
 
+int o2net_debugfs_init(void)
+{
+       mode_t mode = S_IFREG|S_IRUSR;
+
+       o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL);
+       if (o2net_dentry)
+               nst_dentry = debugfs_create_file(NST_DEBUG_NAME, mode,
+                                       o2net_dentry, NULL, &nst_seq_fops);
+       if (nst_dentry)
+               sc_dentry = debugfs_create_file(SC_DEBUG_NAME, mode,
+                                       o2net_dentry, NULL, &sc_seq_fops);
+       if (sc_dentry)
+               stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, mode,
+                                       o2net_dentry, NULL, &stats_seq_fops);
+       if (stats_dentry)
+               nodes_dentry = debugfs_create_file(NODES_DEBUG_NAME, mode,
+                                       o2net_dentry, NULL, &nodes_fops);
+       if (nodes_dentry)
+               return 0;
+
+       o2net_debugfs_exit();
+       mlog_errno(-ENOMEM);
+       return -ENOMEM;
+}
+
 #endif /* CONFIG_DEBUG_FS */
index ad7d0c155de41a3912b5a6fa330b28ca48edf790..044e7b58d31c7662a75e29f636cfb86bf2846b67 100644 (file)
@@ -546,7 +546,7 @@ static void o2net_set_nn_state(struct o2net_node *nn,
        }
 
        if (was_valid && !valid) {
-               printk(KERN_NOTICE "o2net: no longer connected to "
+               printk(KERN_NOTICE "o2net: No longer connected to "
                       SC_NODEF_FMT "\n", SC_NODEF_ARGS(old_sc));
                o2net_complete_nodes_nsw(nn);
        }
@@ -556,7 +556,7 @@ static void o2net_set_nn_state(struct o2net_node *nn,
                cancel_delayed_work(&nn->nn_connect_expired);
                printk(KERN_NOTICE "o2net: %s " SC_NODEF_FMT "\n",
                       o2nm_this_node() > sc->sc_node->nd_num ?
-                               "connected to" : "accepted connection from",
+                      "Connected to" : "Accepted connection from",
                       SC_NODEF_ARGS(sc));
        }
 
@@ -644,7 +644,7 @@ static void o2net_state_change(struct sock *sk)
                        o2net_sc_queue_work(sc, &sc->sc_connect_work);
                        break;
                default:
-                       printk(KERN_INFO "o2net: connection to " SC_NODEF_FMT
+                       printk(KERN_INFO "o2net: Connection to " SC_NODEF_FMT
                              " shutdown, state %d\n",
                              SC_NODEF_ARGS(sc), sk->sk_state);
                        o2net_sc_queue_work(sc, &sc->sc_shutdown_work);
@@ -1035,6 +1035,25 @@ static int o2net_tx_can_proceed(struct o2net_node *nn,
        return ret;
 }
 
+/* Get a map of all nodes to which this node is currently connected to */
+void o2net_fill_node_map(unsigned long *map, unsigned bytes)
+{
+       struct o2net_sock_container *sc;
+       int node, ret;
+
+       BUG_ON(bytes < (BITS_TO_LONGS(O2NM_MAX_NODES) * sizeof(unsigned long)));
+
+       memset(map, 0, bytes);
+       for (node = 0; node < O2NM_MAX_NODES; ++node) {
+               o2net_tx_can_proceed(o2net_nn_from_num(node), &sc, &ret);
+               if (!ret) {
+                       set_bit(node, map);
+                       sc_put(sc);
+               }
+       }
+}
+EXPORT_SYMBOL_GPL(o2net_fill_node_map);
+
 int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
                           size_t caller_veclen, u8 target_node, int *status)
 {
@@ -1285,11 +1304,11 @@ static int o2net_check_handshake(struct o2net_sock_container *sc)
        struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
 
        if (hand->protocol_version != cpu_to_be64(O2NET_PROTOCOL_VERSION)) {
-               mlog(ML_NOTICE, SC_NODEF_FMT " advertised net protocol "
-                    "version %llu but %llu is required, disconnecting\n",
-                    SC_NODEF_ARGS(sc),
-                    (unsigned long long)be64_to_cpu(hand->protocol_version),
-                    O2NET_PROTOCOL_VERSION);
+               printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " Advertised net "
+                      "protocol version %llu but %llu is required. "
+                      "Disconnecting.\n", SC_NODEF_ARGS(sc),
+                      (unsigned long long)be64_to_cpu(hand->protocol_version),
+                      O2NET_PROTOCOL_VERSION);
 
                /* don't bother reconnecting if its the wrong version. */
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
@@ -1303,33 +1322,33 @@ static int o2net_check_handshake(struct o2net_sock_container *sc)
         */
        if (be32_to_cpu(hand->o2net_idle_timeout_ms) !=
                                o2net_idle_timeout()) {
-               mlog(ML_NOTICE, SC_NODEF_FMT " uses a network idle timeout of "
-                    "%u ms, but we use %u ms locally.  disconnecting\n",
-                    SC_NODEF_ARGS(sc),
-                    be32_to_cpu(hand->o2net_idle_timeout_ms),
-                    o2net_idle_timeout());
+               printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a network "
+                      "idle timeout of %u ms, but we use %u ms locally. "
+                      "Disconnecting.\n", SC_NODEF_ARGS(sc),
+                      be32_to_cpu(hand->o2net_idle_timeout_ms),
+                      o2net_idle_timeout());
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
                return -1;
        }
 
        if (be32_to_cpu(hand->o2net_keepalive_delay_ms) !=
                        o2net_keepalive_delay()) {
-               mlog(ML_NOTICE, SC_NODEF_FMT " uses a keepalive delay of "
-                    "%u ms, but we use %u ms locally.  disconnecting\n",
-                    SC_NODEF_ARGS(sc),
-                    be32_to_cpu(hand->o2net_keepalive_delay_ms),
-                    o2net_keepalive_delay());
+               printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a keepalive "
+                      "delay of %u ms, but we use %u ms locally. "
+                      "Disconnecting.\n", SC_NODEF_ARGS(sc),
+                      be32_to_cpu(hand->o2net_keepalive_delay_ms),
+                      o2net_keepalive_delay());
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
                return -1;
        }
 
        if (be32_to_cpu(hand->o2hb_heartbeat_timeout_ms) !=
                        O2HB_MAX_WRITE_TIMEOUT_MS) {
-               mlog(ML_NOTICE, SC_NODEF_FMT " uses a heartbeat timeout of "
-                    "%u ms, but we use %u ms locally.  disconnecting\n",
-                    SC_NODEF_ARGS(sc),
-                    be32_to_cpu(hand->o2hb_heartbeat_timeout_ms),
-                    O2HB_MAX_WRITE_TIMEOUT_MS);
+               printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a heartbeat "
+                      "timeout of %u ms, but we use %u ms locally. "
+                      "Disconnecting.\n", SC_NODEF_ARGS(sc),
+                      be32_to_cpu(hand->o2hb_heartbeat_timeout_ms),
+                      O2HB_MAX_WRITE_TIMEOUT_MS);
                o2net_ensure_shutdown(nn, sc, -ENOTCONN);
                return -1;
        }
@@ -1540,28 +1559,16 @@ static void o2net_idle_timer(unsigned long data)
 {
        struct o2net_sock_container *sc = (struct o2net_sock_container *)data;
        struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
-
 #ifdef CONFIG_DEBUG_FS
-       ktime_t now = ktime_get();
+       unsigned long msecs = ktime_to_ms(ktime_get()) -
+               ktime_to_ms(sc->sc_tv_timer);
+#else
+       unsigned long msecs = o2net_idle_timeout();
 #endif
 
-       printk(KERN_NOTICE "o2net: connection to " SC_NODEF_FMT " has been idle for %u.%u "
-            "seconds, shutting it down.\n", SC_NODEF_ARGS(sc),
-                    o2net_idle_timeout() / 1000,
-                    o2net_idle_timeout() % 1000);
-
-#ifdef CONFIG_DEBUG_FS
-       mlog(ML_NOTICE, "Here are some times that might help debug the "
-            "situation: (Timer: %lld, Now %lld, DataReady %lld, Advance %lld-%lld, "
-            "Key 0x%08x, Func %u, FuncTime %lld-%lld)\n",
-            (long long)ktime_to_us(sc->sc_tv_timer), (long long)ktime_to_us(now),
-            (long long)ktime_to_us(sc->sc_tv_data_ready),
-            (long long)ktime_to_us(sc->sc_tv_advance_start),
-            (long long)ktime_to_us(sc->sc_tv_advance_stop),
-            sc->sc_msg_key, sc->sc_msg_type,
-            (long long)ktime_to_us(sc->sc_tv_func_start),
-            (long long)ktime_to_us(sc->sc_tv_func_stop));
-#endif
+       printk(KERN_NOTICE "o2net: Connection to " SC_NODEF_FMT " has been "
+              "idle for %lu.%lu secs, shutting it down.\n", SC_NODEF_ARGS(sc),
+              msecs / 1000, msecs % 1000);
 
        /*
         * Initialize the nn_timeout so that the next connection attempt
@@ -1694,8 +1701,8 @@ static void o2net_start_connect(struct work_struct *work)
 
 out:
        if (ret) {
-               mlog(ML_NOTICE, "connect attempt to " SC_NODEF_FMT " failed "
-                    "with errno %d\n", SC_NODEF_ARGS(sc), ret);
+               printk(KERN_NOTICE "o2net: Connect attempt to " SC_NODEF_FMT
+                      " failed with errno %d\n", SC_NODEF_ARGS(sc), ret);
                /* 0 err so that another will be queued and attempted
                 * from set_nn_state */
                if (sc)
@@ -1718,8 +1725,8 @@ static void o2net_connect_expired(struct work_struct *work)
 
        spin_lock(&nn->nn_lock);
        if (!nn->nn_sc_valid) {
-               mlog(ML_ERROR, "no connection established with node %u after "
-                    "%u.%u seconds, giving up and returning errors.\n",
+               printk(KERN_NOTICE "o2net: No connection established with "
+                      "node %u after %u.%u seconds, giving up.\n",
                     o2net_num_from_nn(nn),
                     o2net_idle_timeout() / 1000,
                     o2net_idle_timeout() % 1000);
@@ -1862,21 +1869,21 @@ static int o2net_accept_one(struct socket *sock)
 
        node = o2nm_get_node_by_ip(sin.sin_addr.s_addr);
        if (node == NULL) {
-               mlog(ML_NOTICE, "attempt to connect from unknown node at %pI4:%d\n",
-                    &sin.sin_addr.s_addr, ntohs(sin.sin_port));
+               printk(KERN_NOTICE "o2net: Attempt to connect from unknown "
+                      "node at %pI4:%d\n", &sin.sin_addr.s_addr,
+                      ntohs(sin.sin_port));
                ret = -EINVAL;
                goto out;
        }
 
        if (o2nm_this_node() >= node->nd_num) {
                local_node = o2nm_get_node_by_num(o2nm_this_node());
-               mlog(ML_NOTICE, "unexpected connect attempt seen at node '%s' ("
-                    "%u, %pI4:%d) from node '%s' (%u, %pI4:%d)\n",
-                    local_node->nd_name, local_node->nd_num,
-                    &(local_node->nd_ipv4_address),
-                    ntohs(local_node->nd_ipv4_port),
-                    node->nd_name, node->nd_num, &sin.sin_addr.s_addr,
-                    ntohs(sin.sin_port));
+               printk(KERN_NOTICE "o2net: Unexpected connect attempt seen "
+                      "at node '%s' (%u, %pI4:%d) from node '%s' (%u, "
+                      "%pI4:%d)\n", local_node->nd_name, local_node->nd_num,
+                      &(local_node->nd_ipv4_address),
+                      ntohs(local_node->nd_ipv4_port), node->nd_name,
+                      node->nd_num, &sin.sin_addr.s_addr, ntohs(sin.sin_port));
                ret = -EINVAL;
                goto out;
        }
@@ -1901,10 +1908,10 @@ static int o2net_accept_one(struct socket *sock)
                ret = 0;
        spin_unlock(&nn->nn_lock);
        if (ret) {
-               mlog(ML_NOTICE, "attempt to connect from node '%s' at "
-                    "%pI4:%d but it already has an open connection\n",
-                    node->nd_name, &sin.sin_addr.s_addr,
-                    ntohs(sin.sin_port));
+               printk(KERN_NOTICE "o2net: Attempt to connect from node '%s' "
+                      "at %pI4:%d but it already has an open connection\n",
+                      node->nd_name, &sin.sin_addr.s_addr,
+                      ntohs(sin.sin_port));
                goto out;
        }
 
@@ -1984,7 +1991,7 @@ static int o2net_open_listening_sock(__be32 addr, __be16 port)
 
        ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
        if (ret < 0) {
-               mlog(ML_ERROR, "unable to create socket, ret=%d\n", ret);
+               printk(KERN_ERR "o2net: Error %d while creating socket\n", ret);
                goto out;
        }
 
@@ -2001,16 +2008,15 @@ static int o2net_open_listening_sock(__be32 addr, __be16 port)
        sock->sk->sk_reuse = 1;
        ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin));
        if (ret < 0) {
-               mlog(ML_ERROR, "unable to bind socket at %pI4:%u, "
-                    "ret=%d\n", &addr, ntohs(port), ret);
+               printk(KERN_ERR "o2net: Error %d while binding socket at "
+                      "%pI4:%u\n", ret, &addr, ntohs(port)); 
                goto out;
        }
 
        ret = sock->ops->listen(sock, 64);
-       if (ret < 0) {
-               mlog(ML_ERROR, "unable to listen on %pI4:%u, ret=%d\n",
-                    &addr, ntohs(port), ret);
-       }
+       if (ret < 0)
+               printk(KERN_ERR "o2net: Error %d while listening on %pI4:%u\n",
+                      ret, &addr, ntohs(port));
 
 out:
        if (ret) {
index fd6179eb26d4cd2cfb43f4ff053237837712113e..5bada2a69b503cd365d626a25e4ae6d08ad50b7a 100644 (file)
@@ -106,6 +106,8 @@ int o2net_register_handler(u32 msg_type, u32 key, u32 max_len,
                           struct list_head *unreg_list);
 void o2net_unregister_handler_list(struct list_head *list);
 
+void o2net_fill_node_map(unsigned long *map, unsigned bytes);
+
 struct o2nm_node;
 int o2net_register_hb_callbacks(void);
 void o2net_unregister_hb_callbacks(void);
index e2878b5895fb543a86c11f0128b025dbb0335c38..8fe4e2892ab9ccd983304a825c338df57a5376b8 100644 (file)
@@ -1184,8 +1184,7 @@ static int __ocfs2_delete_entry(handle_t *handle, struct inode *dir,
                        if (pde)
                                le16_add_cpu(&pde->rec_len,
                                                le16_to_cpu(de->rec_len));
-                       else
-                               de->inode = 0;
+                       de->inode = 0;
                        dir->i_version++;
                        ocfs2_journal_dirty(handle, bh);
                        goto bail;
index d602abb51b610d525cc437daa05c25d2105fe0c3..a5952ceecba5a83147389ad4a1cd24972ee0bfbe 100644 (file)
@@ -859,8 +859,8 @@ void dlm_complete_recovery_thread(struct dlm_ctxt *dlm);
 void dlm_wait_for_recovery(struct dlm_ctxt *dlm);
 void dlm_kick_recovery_thread(struct dlm_ctxt *dlm);
 int dlm_is_node_dead(struct dlm_ctxt *dlm, u8 node);
-int dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout);
-int dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout);
+void dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout);
+void dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout);
 
 void dlm_put(struct dlm_ctxt *dlm);
 struct dlm_ctxt *dlm_grab(struct dlm_ctxt *dlm);
@@ -877,9 +877,8 @@ static inline void dlm_lockres_get(struct dlm_lock_resource *res)
        kref_get(&res->refs);
 }
 void dlm_lockres_put(struct dlm_lock_resource *res);
-void __dlm_unhash_lockres(struct dlm_lock_resource *res);
-void __dlm_insert_lockres(struct dlm_ctxt *dlm,
-                         struct dlm_lock_resource *res);
+void __dlm_unhash_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
+void __dlm_insert_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
 struct dlm_lock_resource * __dlm_lookup_lockres_full(struct dlm_ctxt *dlm,
                                                     const char *name,
                                                     unsigned int len,
@@ -902,46 +901,15 @@ struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm,
                                          const char *name,
                                          unsigned int namelen);
 
-#define dlm_lockres_set_refmap_bit(bit,res)  \
-       __dlm_lockres_set_refmap_bit(bit,res,__FILE__,__LINE__)
-#define dlm_lockres_clear_refmap_bit(bit,res)  \
-       __dlm_lockres_clear_refmap_bit(bit,res,__FILE__,__LINE__)
+void dlm_lockres_set_refmap_bit(struct dlm_ctxt *dlm,
+                               struct dlm_lock_resource *res, int bit);
+void dlm_lockres_clear_refmap_bit(struct dlm_ctxt *dlm,
+                                 struct dlm_lock_resource *res, int bit);
 
-static inline void __dlm_lockres_set_refmap_bit(int bit,
-                                               struct dlm_lock_resource *res,
-                                               const char *file,
-                                               int line)
-{
-       //printk("%s:%d:%.*s: setting bit %d\n", file, line,
-       //     res->lockname.len, res->lockname.name, bit);
-       set_bit(bit, res->refmap);
-}
-
-static inline void __dlm_lockres_clear_refmap_bit(int bit,
-                                                 struct dlm_lock_resource *res,
-                                                 const char *file,
-                                                 int line)
-{
-       //printk("%s:%d:%.*s: clearing bit %d\n", file, line,
-       //     res->lockname.len, res->lockname.name, bit);
-       clear_bit(bit, res->refmap);
-}
-
-void __dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
-                                  struct dlm_lock_resource *res,
-                                  const char *file,
-                                  int line);
-void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
-                                  struct dlm_lock_resource *res,
-                                  int new_lockres,
-                                  const char *file,
-                                  int line);
-#define dlm_lockres_drop_inflight_ref(d,r)  \
-       __dlm_lockres_drop_inflight_ref(d,r,__FILE__,__LINE__)
-#define dlm_lockres_grab_inflight_ref(d,r)  \
-       __dlm_lockres_grab_inflight_ref(d,r,0,__FILE__,__LINE__)
-#define dlm_lockres_grab_inflight_ref_new(d,r)  \
-       __dlm_lockres_grab_inflight_ref(d,r,1,__FILE__,__LINE__)
+void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
+                                  struct dlm_lock_resource *res);
+void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
+                                  struct dlm_lock_resource *res);
 
 void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
 void dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
index 6ed6b95dcf935a6516e935b85a3ca9ffc0b8a9d8..92f2ead0fab6de22fa138cc4410dee6e1544216c 100644 (file)
@@ -157,16 +157,18 @@ static int dlm_protocol_compare(struct dlm_protocol_version *existing,
 
 static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm);
 
-void __dlm_unhash_lockres(struct dlm_lock_resource *lockres)
+void __dlm_unhash_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
 {
-       if (!hlist_unhashed(&lockres->hash_node)) {
-               hlist_del_init(&lockres->hash_node);
-               dlm_lockres_put(lockres);
-       }
+       if (hlist_unhashed(&res->hash_node))
+               return;
+
+       mlog(0, "%s: Unhash res %.*s\n", dlm->name, res->lockname.len,
+            res->lockname.name);
+       hlist_del_init(&res->hash_node);
+       dlm_lockres_put(res);
 }
 
-void __dlm_insert_lockres(struct dlm_ctxt *dlm,
-                      struct dlm_lock_resource *res)
+void __dlm_insert_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
 {
        struct hlist_head *bucket;
        struct qstr *q;
@@ -180,6 +182,9 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm,
        dlm_lockres_get(res);
 
        hlist_add_head(&res->hash_node, bucket);
+
+       mlog(0, "%s: Hash res %.*s\n", dlm->name, res->lockname.len,
+            res->lockname.name);
 }
 
 struct dlm_lock_resource * __dlm_lookup_lockres_full(struct dlm_ctxt *dlm,
@@ -539,17 +544,17 @@ again:
 
 static void __dlm_print_nodes(struct dlm_ctxt *dlm)
 {
-       int node = -1;
+       int node = -1, num = 0;
 
        assert_spin_locked(&dlm->spinlock);
 
-       printk(KERN_NOTICE "o2dlm: Nodes in domain %s: ", dlm->name);
-
+       printk("( ");
        while ((node = find_next_bit(dlm->domain_map, O2NM_MAX_NODES,
                                     node + 1)) < O2NM_MAX_NODES) {
                printk("%d ", node);
+               ++num;
        }
-       printk("\n");
+       printk(") %u nodes\n", num);
 }