From 3bd32b9e3b21ad5dc7e883aa017ab1f23e68c821 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 14 Feb 2011 14:04:46 +0100 Subject: [PATCH] --- yaml --- r: 233408 b: refs/heads/master c: 7576958a9d5a4a677ad7dd40901cdbb6c1110c98 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/Documentation/DocBook/drm.tmpl | 6 +- trunk/Documentation/arm/Booting | 33 +- .../devicetree/booting-without-of.txt | 40 + trunk/MAINTAINERS | 1 - trunk/Makefile | 2 +- trunk/arch/arm/Kconfig | 2 +- trunk/arch/arm/kernel/head.S | 38 +- trunk/arch/arm/kernel/hw_breakpoint.c | 44 +- trunk/arch/arm/kernel/module.c | 22 +- trunk/arch/arm/kernel/perf_event.c | 2 +- trunk/arch/arm/mach-pxa/colibri-evalboard.c | 2 +- trunk/arch/arm/mach-pxa/colibri-pxa300.c | 2 +- .../arch/arm/mach-pxa/include/mach/colibri.h | 2 +- trunk/arch/arm/mach-pxa/palm27x.c | 2 +- trunk/arch/arm/mach-pxa/pm.c | 4 +- trunk/arch/arm/mach-sa1100/collie.c | 3 - trunk/arch/arm/mm/Kconfig | 6 +- trunk/arch/arm/oprofile/common.c | 14 +- trunk/arch/arm/plat-pxa/mfp.c | 8 +- trunk/arch/m68k/include/asm/string.h | 4 +- trunk/arch/m68k/lib/string.c | 11 + trunk/arch/m68knommu/kernel/vmlinux.lds.S | 6 - trunk/arch/m68knommu/lib/Makefile | 2 +- trunk/arch/m68knommu/lib/memmove.c | 105 -- trunk/arch/m68knommu/platform/5249/intc2.c | 4 +- trunk/arch/m68knommu/platform/68328/entry.S | 1 + .../arch/m68knommu/platform/68360/commproc.c | 2 +- trunk/arch/m68knommu/platform/68360/config.c | 2 +- trunk/arch/m68knommu/platform/68360/entry.S | 1 + trunk/arch/m68knommu/platform/68360/ints.c | 4 +- .../arch/m68knommu/platform/coldfire/entry.S | 1 + trunk/arch/s390/crypto/sha_common.c | 1 - trunk/arch/s390/include/asm/processor.h | 5 + trunk/arch/s390/kernel/traps.c | 37 + trunk/arch/sparc/include/asm/pcr.h | 2 - trunk/arch/sparc/kernel/iommu.c | 5 +- trunk/arch/sparc/kernel/pcr.c | 2 + trunk/arch/sparc/kernel/smp_64.c | 2 - trunk/arch/sparc/kernel/una_asm_32.S | 4 +- trunk/arch/sparc/lib/bitext.c | 5 +- trunk/arch/x86/include/asm/apic.h | 1 - trunk/arch/x86/include/asm/cpu.h | 2 +- trunk/arch/x86/kernel/alternative.c | 2 +- trunk/arch/x86/kernel/apic/apic.c | 9 +- trunk/arch/x86/kernel/apic/io_apic.c | 3 - trunk/arch/x86/kernel/irq.c | 3 +- trunk/arch/x86/kernel/process.c | 24 +- trunk/arch/x86/kernel/smpboot.c | 4 +- trunk/drivers/acpi/acpica/evxfgpe.c | 49 +- trunk/drivers/acpi/osl.c | 25 +- trunk/drivers/acpi/video_detect.c | 5 - trunk/drivers/acpi/wakeup.c | 6 +- trunk/drivers/dma/amba-pl08x.c | 53 +- trunk/drivers/dma/imx-dma.c | 26 +- trunk/drivers/dma/imx-sdma.c | 88 +- trunk/drivers/dma/ipu/ipu_idmac.c | 50 + trunk/drivers/firmware/dmi_scan.c | 11 +- trunk/drivers/gpu/drm/drm_info.c | 9 +- trunk/drivers/gpu/drm/i915/i915_drv.c | 5 +- trunk/drivers/gpu/drm/i915/i915_drv.h | 1 - trunk/drivers/gpu/drm/i915/i915_reg.h | 4 +- trunk/drivers/gpu/drm/i915/intel_display.c | 95 +- trunk/drivers/gpu/drm/i915/intel_dp.c | 36 +- trunk/drivers/gpu/drm/i915/intel_drv.h | 1 + trunk/drivers/gpu/drm/i915/intel_hdmi.c | 39 +- trunk/drivers/gpu/drm/i915/intel_lvds.c | 12 +- trunk/drivers/gpu/drm/i915/intel_ringbuffer.c | 26 +- trunk/drivers/gpu/drm/i915/intel_sdvo.c | 66 +- trunk/drivers/gpu/drm/i915/intel_tv.c | 43 +- trunk/drivers/gpu/drm/nouveau/nouveau_bios.c | 2 +- trunk/drivers/gpu/drm/nouveau/nouveau_bo.c | 13 +- .../gpu/drm/nouveau/nouveau_connector.c | 1 - trunk/drivers/gpu/drm/nouveau/nouveau_pm.c | 2 +- trunk/drivers/gpu/drm/nouveau/nv04_dfp.c | 12 +- trunk/drivers/gpu/drm/nouveau/nv40_graph.c | 46 +- trunk/drivers/gpu/drm/radeon/atombios_crtc.c | 100 +- trunk/drivers/gpu/drm/radeon/evergreen.c | 22 +- .../gpu/drm/radeon/evergreen_blit_kms.c | 23 +- .../gpu/drm/radeon/evergreen_blit_shaders.c | 8 - trunk/drivers/gpu/drm/radeon/evergreend.h | 1 - trunk/drivers/gpu/drm/radeon/mkregtable.c | 5 +- trunk/drivers/gpu/drm/radeon/r100.c | 63 +- trunk/drivers/gpu/drm/radeon/r100_track.h | 13 +- trunk/drivers/gpu/drm/radeon/r200.c | 18 - trunk/drivers/gpu/drm/radeon/r300.c | 44 +- trunk/drivers/gpu/drm/radeon/r300_reg.h | 2 - trunk/drivers/gpu/drm/radeon/r600.c | 22 +- trunk/drivers/gpu/drm/radeon/r600_blit.c | 11 +- trunk/drivers/gpu/drm/radeon/r600_blit_kms.c | 29 +- .../gpu/drm/radeon/r600_blit_shaders.c | 4 - trunk/drivers/gpu/drm/radeon/r600_cp.c | 31 +- trunk/drivers/gpu/drm/radeon/r600_cs.c | 46 +- trunk/drivers/gpu/drm/radeon/r600d.h | 9 +- .../drivers/gpu/drm/radeon/radeon_atombios.c | 48 +- trunk/drivers/gpu/drm/radeon/radeon_combios.c | 47 - trunk/drivers/gpu/drm/radeon/radeon_device.c | 4 - trunk/drivers/gpu/drm/radeon/radeon_display.c | 10 - trunk/drivers/gpu/drm/radeon/radeon_drv.h | 1 - .../drivers/gpu/drm/radeon/radeon_encoders.c | 24 +- trunk/drivers/gpu/drm/radeon/radeon_mode.h | 1 - trunk/drivers/gpu/drm/radeon/radeon_ttm.c | 4 +- trunk/drivers/gpu/drm/radeon/reg_srcs/r300 | 6 +- trunk/drivers/gpu/drm/radeon/reg_srcs/r420 | 7 +- trunk/drivers/gpu/drm/radeon/reg_srcs/rs600 | 6 +- trunk/drivers/gpu/drm/radeon/reg_srcs/rv515 | 7 +- trunk/drivers/gpu/drm/radeon/rs690.c | 12 +- trunk/drivers/gpu/drm/radeon/rv770.c | 6 +- trunk/drivers/gpu/drm/radeon/rv770d.h | 8 +- trunk/drivers/infiniband/hw/nes/nes_hw.c | 32 +- trunk/drivers/infiniband/hw/qib/qib_rc.c | 5 +- trunk/drivers/input/input.c | 37 +- trunk/drivers/input/misc/rotary_encoder.c | 4 +- trunk/drivers/input/serio/serio.c | 11 +- trunk/drivers/input/tablet/wacom_sys.c | 2 +- trunk/drivers/input/touchscreen/ads7846.c | 38 +- trunk/drivers/input/touchscreen/wacom_w8001.c | 13 +- trunk/drivers/message/fusion/mptbase.h | 4 +- trunk/drivers/message/fusion/mptctl.c | 8 - trunk/drivers/message/fusion/mptscsih.c | 7 +- trunk/drivers/net/can/mscan/Kconfig | 2 +- trunk/drivers/pci/pci-sysfs.c | 3 +- trunk/drivers/rtc/rtc-at32ap700x.c | 19 +- trunk/drivers/rtc/rtc-at91rm9200.c | 20 +- trunk/drivers/rtc/rtc-at91sam9.c | 20 +- trunk/drivers/rtc/rtc-bfin.c | 21 +- trunk/drivers/rtc/rtc-dev.c | 21 +- trunk/drivers/rtc/rtc-ds1286.c | 41 +- trunk/drivers/rtc/rtc-ds1305.c | 43 +- trunk/drivers/rtc/rtc-ds1307.c | 49 +- trunk/drivers/rtc/rtc-ds1374.c | 37 +- trunk/drivers/rtc/rtc-m41t80.c | 30 +- trunk/drivers/rtc/rtc-m48t59.c | 21 +- trunk/drivers/rtc/rtc-mrst.c | 31 +- trunk/drivers/rtc/rtc-msm6242.c | 2 +- trunk/drivers/rtc/rtc-mv.c | 20 +- trunk/drivers/rtc/rtc-omap.c | 28 +- trunk/drivers/rtc/rtc-rp5c01.c | 2 +- trunk/drivers/rtc/rtc-rs5c372.c | 48 +- trunk/drivers/rtc/rtc-sa1100.c | 22 +- trunk/drivers/rtc/rtc-sh.c | 11 +- trunk/drivers/rtc/rtc-test.c | 21 +- trunk/drivers/rtc/rtc-vr41xx.c | 38 +- trunk/drivers/scsi/qla2xxx/qla_attr.c | 5 +- trunk/drivers/scsi/qla2xxx/qla_init.c | 10 +- trunk/drivers/scsi/qla2xxx/qla_os.c | 10 +- trunk/drivers/scsi/scsi_debug.c | 2 +- trunk/drivers/spi/pxa2xx_spi_pci.c | 61 +- trunk/drivers/target/Makefile | 3 +- trunk/drivers/target/target_core_configfs.c | 155 ++- trunk/drivers/target/target_core_device.c | 13 +- .../target/target_core_fabric_configfs.c | 92 +- trunk/drivers/target/target_core_iblock.c | 8 +- trunk/drivers/target/target_core_mib.c | 1078 +++++++++++++++++ trunk/drivers/target/target_core_mib.h | 28 + trunk/drivers/target/target_core_pscsi.c | 4 +- trunk/drivers/target/target_core_tpg.c | 29 +- trunk/drivers/target/target_core_transport.c | 48 +- trunk/drivers/tty/serial/68328serial.c | 29 +- trunk/drivers/tty/sysrq.c | 17 +- trunk/drivers/watchdog/Kconfig | 6 +- trunk/drivers/watchdog/Makefile | 2 +- .../watchdog/{m54xx_wdt.c => m548x_wdt.c} | 50 +- trunk/fs/block_dev.c | 11 +- trunk/fs/btrfs/disk-io.c | 8 +- trunk/fs/btrfs/extent-tree.c | 2 +- trunk/fs/btrfs/extent_io.c | 48 +- trunk/fs/btrfs/extent_map.c | 4 +- trunk/fs/btrfs/file.c | 1 - trunk/fs/btrfs/inode.c | 3 - trunk/fs/btrfs/ioctl.c | 10 +- trunk/fs/btrfs/relocation.c | 1 - trunk/fs/btrfs/volumes.c | 2 - trunk/fs/namei.c | 131 +- trunk/fs/nfsd/nfs4callback.c | 6 +- trunk/fs/nfsd/nfs4state.c | 186 ++- trunk/fs/nfsd/nfs4xdr.c | 8 +- trunk/fs/nfsd/state.h | 5 +- trunk/fs/nfsd/vfs.c | 21 +- trunk/fs/partitions/mac.c | 17 +- trunk/fs/proc/array.c | 3 + trunk/include/linux/huge_mm.h | 3 +- trunk/include/linux/input/matrix_keypad.h | 4 +- trunk/include/linux/list.h | 12 +- trunk/include/linux/oprofile.h | 13 +- trunk/include/target/target_core_base.h | 28 +- trunk/include/target/target_core_transport.h | 2 - trunk/kernel/power/snapshot.c | 7 +- trunk/kernel/time/timer_list.c | 4 +- trunk/kernel/timer.c | 8 +- trunk/kernel/watchdog.c | 10 +- trunk/kernel/workqueue.c | 9 + trunk/lib/Kconfig.debug | 2 +- trunk/lib/list_debug.c | 39 +- trunk/mm/huge_memory.c | 35 +- trunk/tools/perf/builtin-record.c | 4 +- trunk/tools/perf/builtin-top.c | 2 +- trunk/tools/perf/util/event.c | 18 +- trunk/tools/perf/util/event.h | 6 +- trunk/tools/power/x86/turbostat/turbostat.c | 200 +-- 200 files changed, 2792 insertions(+), 2299 deletions(-) delete mode 100644 trunk/arch/m68knommu/lib/memmove.c create mode 100644 trunk/drivers/target/target_core_mib.c create mode 100644 trunk/drivers/target/target_core_mib.h rename trunk/drivers/watchdog/{m54xx_wdt.c => m548x_wdt.c} (80%) diff --git a/[refs] b/[refs] index 5bd0b380096c..96d140dd2522 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3c18d4de86e4a7f93815c081e50e0543fa27200f +refs/heads/master: 7576958a9d5a4a677ad7dd40901cdbb6c1110c98 diff --git a/trunk/Documentation/DocBook/drm.tmpl b/trunk/Documentation/DocBook/drm.tmpl index c27915893974..2861055afd7a 100644 --- a/trunk/Documentation/DocBook/drm.tmpl +++ b/trunk/Documentation/DocBook/drm.tmpl @@ -73,8 +73,8 @@ services. - The core of every DRM driver is struct drm_driver. Drivers - will typically statically initialize a drm_driver structure, + The core of every DRM driver is struct drm_device. Drivers + will typically statically initialize a drm_device structure, then pass it to drm_init() at load time. @@ -84,7 +84,7 @@ Driver initialization Before calling the DRM initialization routines, the driver must - first create and fill out a struct drm_driver structure. + first create and fill out a struct drm_device structure. static struct drm_driver driver = { diff --git a/trunk/Documentation/arm/Booting b/trunk/Documentation/arm/Booting index 76850295af8f..4e686a2ed91e 100644 --- a/trunk/Documentation/arm/Booting +++ b/trunk/Documentation/arm/Booting @@ -65,13 +65,19 @@ looks at the connected hardware is beyond the scope of this document. The boot loader must ultimately be able to provide a MACH_TYPE_xxx value to the kernel. (see linux/arch/arm/tools/mach-types). - -4. Setup the kernel tagged list -------------------------------- +4. Setup boot data +------------------ Existing boot loaders: OPTIONAL, HIGHLY RECOMMENDED New boot loaders: MANDATORY +The boot loader must provide either a tagged list or a dtb image for +passing configuration data to the kernel. The physical address of the +boot data is passed to the kernel in register r2. + +4a. Setup the kernel tagged list +-------------------------------- + The boot loader must create and initialise the kernel tagged list. A valid tagged list starts with ATAG_CORE and ends with ATAG_NONE. The ATAG_CORE tag may or may not be empty. An empty ATAG_CORE tag @@ -101,6 +107,24 @@ The tagged list must be placed in a region of memory where neither the kernel decompressor nor initrd 'bootp' program will overwrite it. The recommended placement is in the first 16KiB of RAM. +4b. Setup the device tree +------------------------- + +The boot loader must load a device tree image (dtb) into system ram +at a 64bit aligned address and initialize it with the boot data. The +dtb format is documented in Documentation/devicetree/booting-without-of.txt. +The kernel will look for the dtb magic value of 0xd00dfeed at the dtb +physical address to determine if a dtb has been passed instead of a +tagged list. + +The boot loader must pass at a minimum the size and location of the +system memory, and the root filesystem location. The dtb must be +placed in a region of memory where the kernel decompressor will not +overwrite it. The recommended placement is in the first 16KiB of RAM +with the caveat that it may not be located at physical address 0 since +the kernel interprets a value of 0 in r2 to mean neither a tagged list +nor a dtb were passed. + 5. Calling the kernel image --------------------------- @@ -125,7 +149,8 @@ In either case, the following conditions must be met: - CPU register settings r0 = 0, r1 = machine type number discovered in (3) above. - r2 = physical address of tagged list in system RAM. + r2 = physical address of tagged list in system RAM, or + physical address of device tree block (dtb) in system RAM - CPU mode All forms of interrupts must be disabled (IRQs and FIQs) diff --git a/trunk/Documentation/devicetree/booting-without-of.txt b/trunk/Documentation/devicetree/booting-without-of.txt index 28b1c9d3d351..9381a1481027 100644 --- a/trunk/Documentation/devicetree/booting-without-of.txt +++ b/trunk/Documentation/devicetree/booting-without-of.txt @@ -13,6 +13,7 @@ Table of Contents I - Introduction 1) Entry point for arch/powerpc + 2) Entry point for arch/arm II - The DT block format 1) Header @@ -225,6 +226,45 @@ it with special cases. cannot support both configurations with Book E and configurations with classic Powerpc architectures. +2) Entry point for arch/arm +--------------------------- + + There is one single entry point to the kernel, at the start + of the kernel image. That entry point supports two calling + conventions. A summary of the interface is described here. A full + description of the boot requirements is documented in + Documentation/arm/Booting + + a) ATAGS interface. Minimal information is passed from firmware + to the kernel with a tagged list of predefined parameters. + + r0 : 0 + + r1 : Machine type number + + r2 : Physical address of tagged list in system RAM + + b) Entry with a flattened device-tree block. Firmware loads the + physical address of the flattened device tree block (dtb) into r2, + r1 is not used, but it is considered good practise to use a valid + machine number as described in Documentation/arm/Booting. + + r0 : 0 + + r1 : Valid machine type number. When using a device tree, + a single machine type number will often be assigned to + represent a class or family of SoCs. + + r2 : physical pointer to the device-tree block + (defined in chapter II) in RAM. Device tree can be located + anywhere in system RAM, but it should be aligned on a 32 bit + boundary. + + The kernel will differentiate between ATAGS and device tree booting by + reading the memory pointed to by r1 and looking for either the flattened + device tree block magic value (0xd00dfeed) or the ATAG_CORE value at + offset 0x4 from r2 (0x54410001). + II - The DT block format ======================== diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 5dd6c751e6a6..4837907a4eda 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -2126,7 +2126,6 @@ S: Supported F: fs/dlm/ DMA GENERIC OFFLOAD ENGINE SUBSYSTEM -M: Vinod Koul M: Dan Williams S: Supported F: drivers/dma/ diff --git a/trunk/Makefile b/trunk/Makefile index 5e40aa2acbff..c9c8c8fd2591 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 38 -EXTRAVERSION = -rc5 +EXTRAVERSION = -rc4 NAME = Flesh-Eating Bats with Fangs # *DOCUMENTATION* diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 26d45e5b636b..5cff165b7eb0 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -1391,7 +1391,7 @@ config AEABI config OABI_COMPAT bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)" - depends on AEABI && EXPERIMENTAL && !THUMB2_KERNEL + depends on AEABI && EXPERIMENTAL default y help This option preserves the old syscall interface along with the diff --git a/trunk/arch/arm/kernel/head.S b/trunk/arch/arm/kernel/head.S index f06ff9feb0db..c0225da3fb21 100644 --- a/trunk/arch/arm/kernel/head.S +++ b/trunk/arch/arm/kernel/head.S @@ -391,7 +391,6 @@ ENDPROC(__turn_mmu_on) #ifdef CONFIG_SMP_ON_UP - __INIT __fixup_smp: and r3, r9, #0x000f0000 @ architecture version teq r3, #0x000f0000 @ CPU ID supported? @@ -416,7 +415,18 @@ __fixup_smp_on_up: sub r3, r0, r3 add r4, r4, r3 add r5, r5, r3 - b __do_fixup_smp_on_up +2: cmp r4, r5 + movhs pc, lr + ldmia r4!, {r0, r6} + ARM( str r6, [r0, r3] ) + THUMB( add r0, r0, r3 ) +#ifdef __ARMEB__ + THUMB( mov r6, r6, ror #16 ) @ Convert word order for big-endian. +#endif + THUMB( strh r6, [r0], #2 ) @ For Thumb-2, store as two halfwords + THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r3. + THUMB( strh r6, [r0] ) + b 2b ENDPROC(__fixup_smp) .align @@ -430,31 +440,7 @@ smp_on_up: ALT_SMP(.long 1) ALT_UP(.long 0) .popsection -#endif - .text -__do_fixup_smp_on_up: - cmp r4, r5 - movhs pc, lr - ldmia r4!, {r0, r6} - ARM( str r6, [r0, r3] ) - THUMB( add r0, r0, r3 ) -#ifdef __ARMEB__ - THUMB( mov r6, r6, ror #16 ) @ Convert word order for big-endian. #endif - THUMB( strh r6, [r0], #2 ) @ For Thumb-2, store as two halfwords - THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r3. - THUMB( strh r6, [r0] ) - b __do_fixup_smp_on_up -ENDPROC(__do_fixup_smp_on_up) - -ENTRY(fixup_smp) - stmfd sp!, {r4 - r6, lr} - mov r4, r0 - add r5, r0, r1 - mov r3, #0 - bl __do_fixup_smp_on_up - ldmfd sp!, {r4 - r6, pc} -ENDPROC(fixup_smp) #include "head-common.S" diff --git a/trunk/arch/arm/kernel/hw_breakpoint.c b/trunk/arch/arm/kernel/hw_breakpoint.c index d600bd350704..c9f3f0467570 100644 --- a/trunk/arch/arm/kernel/hw_breakpoint.c +++ b/trunk/arch/arm/kernel/hw_breakpoint.c @@ -137,10 +137,11 @@ static u8 get_debug_arch(void) u32 didr; /* Do we implement the extended CPUID interface? */ - if (WARN_ONCE((((read_cpuid_id() >> 16) & 0xf) != 0xf), - "CPUID feature registers not supported. " - "Assuming v6 debug is present.\n")) + if (((read_cpuid_id() >> 16) & 0xf) != 0xf) { + pr_warning("CPUID feature registers not supported. " + "Assuming v6 debug is present.\n"); return ARM_DEBUG_ARCH_V6; + } ARM_DBG_READ(c0, 0, didr); return (didr >> 16) & 0xf; @@ -151,12 +152,6 @@ u8 arch_get_debug_arch(void) return debug_arch; } -static int debug_arch_supported(void) -{ - u8 arch = get_debug_arch(); - return arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14; -} - /* Determine number of BRP register available. */ static int get_num_brp_resources(void) { @@ -273,9 +268,6 @@ static int enable_monitor_mode(void) int hw_breakpoint_slots(int type) { - if (!debug_arch_supported()) - return 0; - /* * We can be called early, so don't rely on * our static variables being initialised. @@ -842,11 +834,11 @@ static void reset_ctrl_regs(void *unused) /* * v7 debug contains save and restore registers so that debug state - * can be maintained across low-power modes without leaving the debug - * logic powered up. It is IMPLEMENTATION DEFINED whether we can access - * the debug registers out of reset, so we must unlock the OS Lock - * Access Register to avoid taking undefined instruction exceptions - * later on. + * can be maintained across low-power modes without leaving + * the debug logic powered up. It is IMPLEMENTATION DEFINED whether + * we can write to the debug registers out of reset, so we must + * unlock the OS Lock Access Register to avoid taking undefined + * instruction exceptions later on. */ if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) { /* @@ -890,7 +882,7 @@ static int __init arch_hw_breakpoint_init(void) debug_arch = get_debug_arch(); - if (!debug_arch_supported()) { + if (debug_arch > ARM_DEBUG_ARCH_V7_ECP14) { pr_info("debug architecture 0x%x unsupported.\n", debug_arch); return 0; } @@ -907,18 +899,18 @@ static int __init arch_hw_breakpoint_init(void) pr_info("%d breakpoint(s) reserved for watchpoint " "single-step.\n", core_num_reserved_brps); - /* - * Reset the breakpoint resources. We assume that a halting - * debugger will leave the world in a nice state for us. - */ - on_each_cpu(reset_ctrl_regs, NULL, 1); - ARM_DBG_READ(c1, 0, dscr); if (dscr & ARM_DSCR_HDBGEN) { - max_watchpoint_len = 4; pr_warning("halting debug mode enabled. Assuming maximum " - "watchpoint size of %u bytes.", max_watchpoint_len); + "watchpoint size of 4 bytes."); } else { + /* + * Reset the breakpoint resources. We assume that a halting + * debugger will leave the world in a nice state for us. + */ + smp_call_function(reset_ctrl_regs, NULL, 1); + reset_ctrl_regs(NULL); + /* Work out the maximum supported watchpoint length. */ max_watchpoint_len = get_max_wp_len(); pr_info("maximum watchpoint size is %u bytes.\n", diff --git a/trunk/arch/arm/kernel/module.c b/trunk/arch/arm/kernel/module.c index 6d4105e6872f..2cfe8161b478 100644 --- a/trunk/arch/arm/kernel/module.c +++ b/trunk/arch/arm/kernel/module.c @@ -22,7 +22,6 @@ #include #include -#include #include #ifdef CONFIG_XIP_KERNEL @@ -269,28 +268,12 @@ struct mod_unwind_map { const Elf_Shdr *txt_sec; }; -static const Elf_Shdr *find_mod_section(const Elf32_Ehdr *hdr, - const Elf_Shdr *sechdrs, const char *name) -{ - const Elf_Shdr *s, *se; - const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; - - for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++) - if (strcmp(name, secstrs + s->sh_name) == 0) - return s; - - return NULL; -} - -extern void fixup_smp(const void *, unsigned long); - int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mod) { - const Elf_Shdr * __maybe_unused s = NULL; #ifdef CONFIG_ARM_UNWIND const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; - const Elf_Shdr *sechdrs_end = sechdrs + hdr->e_shnum; + const Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum; struct mod_unwind_map maps[ARM_SEC_MAX]; int i; @@ -332,9 +315,6 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, maps[i].txt_sec->sh_addr, maps[i].txt_sec->sh_size); #endif - s = find_mod_section(hdr, sechdrs, ".alt.smp.init"); - if (s && !is_smp()) - fixup_smp((void *)s->sh_addr, s->sh_size); return 0; } diff --git a/trunk/arch/arm/kernel/perf_event.c b/trunk/arch/arm/kernel/perf_event.c index d150ad1ccb5d..5efa2647a2fb 100644 --- a/trunk/arch/arm/kernel/perf_event.c +++ b/trunk/arch/arm/kernel/perf_event.c @@ -700,7 +700,7 @@ user_backtrace(struct frame_tail __user *tail, * Frame pointers should strictly progress back up the stack * (towards higher addresses). */ - if (tail + 1 >= buftail.fp) + if (tail >= buftail.fp) return NULL; return buftail.fp - 1; diff --git a/trunk/arch/arm/mach-pxa/colibri-evalboard.c b/trunk/arch/arm/mach-pxa/colibri-evalboard.c index 28f667e52ef9..6b2c800a1133 100644 --- a/trunk/arch/arm/mach-pxa/colibri-evalboard.c +++ b/trunk/arch/arm/mach-pxa/colibri-evalboard.c @@ -50,7 +50,7 @@ static void __init colibri_mmc_init(void) GPIO0_COLIBRI_PXA270_SD_DETECT; if (machine_is_colibri300()) /* PXA300 Colibri */ colibri_mci_platform_data.gpio_card_detect = - GPIO13_COLIBRI_PXA300_SD_DETECT; + GPIO39_COLIBRI_PXA300_SD_DETECT; else /* PXA320 Colibri */ colibri_mci_platform_data.gpio_card_detect = GPIO28_COLIBRI_PXA320_SD_DETECT; diff --git a/trunk/arch/arm/mach-pxa/colibri-pxa300.c b/trunk/arch/arm/mach-pxa/colibri-pxa300.c index 66dd81cbc8a0..fddb16d07eb0 100644 --- a/trunk/arch/arm/mach-pxa/colibri-pxa300.c +++ b/trunk/arch/arm/mach-pxa/colibri-pxa300.c @@ -41,7 +41,7 @@ static mfp_cfg_t colibri_pxa300_evalboard_pin_config[] __initdata = { GPIO4_MMC1_DAT1, GPIO5_MMC1_DAT2, GPIO6_MMC1_DAT3, - GPIO13_GPIO, /* GPIO13_COLIBRI_PXA300_SD_DETECT */ + GPIO39_GPIO, /* SD detect */ /* UHC */ GPIO0_2_USBH_PEN, diff --git a/trunk/arch/arm/mach-pxa/include/mach/colibri.h b/trunk/arch/arm/mach-pxa/include/mach/colibri.h index cb4236e98a0f..388a96f1ef93 100644 --- a/trunk/arch/arm/mach-pxa/include/mach/colibri.h +++ b/trunk/arch/arm/mach-pxa/include/mach/colibri.h @@ -60,7 +60,7 @@ static inline void colibri_pxa3xx_init_nand(void) {} #define GPIO113_COLIBRI_PXA270_TS_IRQ 113 /* GPIO definitions for Colibri PXA300/310 */ -#define GPIO13_COLIBRI_PXA300_SD_DETECT 13 +#define GPIO39_COLIBRI_PXA300_SD_DETECT 39 /* GPIO definitions for Colibri PXA320 */ #define GPIO28_COLIBRI_PXA320_SD_DETECT 28 diff --git a/trunk/arch/arm/mach-pxa/palm27x.c b/trunk/arch/arm/mach-pxa/palm27x.c index 35572c427fa8..405b92a29793 100644 --- a/trunk/arch/arm/mach-pxa/palm27x.c +++ b/trunk/arch/arm/mach-pxa/palm27x.c @@ -323,7 +323,7 @@ static struct platform_pwm_backlight_data palm27x_backlight_data = { .pwm_id = 0, .max_brightness = 0xfe, .dft_brightness = 0x7e, - .pwm_period_ns = 3500 * 1024, + .pwm_period_ns = 3500, .init = palm27x_backlight_init, .notify = palm27x_backlight_notify, .exit = palm27x_backlight_exit, diff --git a/trunk/arch/arm/mach-pxa/pm.c b/trunk/arch/arm/mach-pxa/pm.c index 1807c9abdde0..978e1b289544 100644 --- a/trunk/arch/arm/mach-pxa/pm.c +++ b/trunk/arch/arm/mach-pxa/pm.c @@ -33,7 +33,7 @@ int pxa_pm_enter(suspend_state_t state) #endif /* skip registers saving for standby */ - if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->save) { + if (state != PM_SUSPEND_STANDBY) { pxa_cpu_pm_fns->save(sleep_save); /* before sleeping, calculate and save a checksum */ for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++) @@ -44,7 +44,7 @@ int pxa_pm_enter(suspend_state_t state) pxa_cpu_pm_fns->enter(state); cpu_init(); - if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->restore) { + if (state != PM_SUSPEND_STANDBY) { /* after sleeping, validate the checksum */ for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++) checksum += sleep_save[i]; diff --git a/trunk/arch/arm/mach-sa1100/collie.c b/trunk/arch/arm/mach-sa1100/collie.c index bd3e1bfdd6aa..d43c5ef58eb6 100644 --- a/trunk/arch/arm/mach-sa1100/collie.c +++ b/trunk/arch/arm/mach-sa1100/collie.c @@ -241,9 +241,6 @@ static struct locomo_platform_data locomo_info = { struct platform_device collie_locomo_device = { .name = "locomo", .id = 0, - .dev = { - .platform_data = &locomo_info, - }, .num_resources = ARRAY_SIZE(locomo_resources), .resource = locomo_resources, }; diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index e4509bae8fc4..9d30c6f804b9 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -405,7 +405,7 @@ config CPU_V6 config CPU_32v6K bool "Support ARM V6K processor extensions" if !SMP depends on CPU_V6 || CPU_V7 - default y if SMP + default y if SMP && !(ARCH_MX3 || ARCH_OMAP2) help Say Y here if your ARMv6 processor supports the 'K' extension. This enables the kernel to use some instructions not present @@ -416,7 +416,7 @@ config CPU_32v6K # ARMv7 config CPU_V7 bool "Support ARM V7 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX - select CPU_32v6K + select CPU_32v6K if !ARCH_OMAP2 select CPU_32v7 select CPU_ABRT_EV7 select CPU_PABRT_V7 @@ -644,7 +644,7 @@ config ARM_THUMBEE config SWP_EMULATE bool "Emulate SWP/SWPB instructions" - depends on !CPU_USE_DOMAINS && CPU_V7 && !CPU_V6 + depends on CPU_V7 && !CPU_V6 select HAVE_PROC_CPU if PROC_FS default y if SMP help diff --git a/trunk/arch/arm/oprofile/common.c b/trunk/arch/arm/oprofile/common.c index c074e66ad224..8aa974491dfc 100644 --- a/trunk/arch/arm/oprofile/common.c +++ b/trunk/arch/arm/oprofile/common.c @@ -10,6 +10,8 @@ */ #include +#include +#include #include #include #include @@ -44,7 +46,6 @@ char *op_name_from_perf_id(void) return NULL; } } -#endif static int report_trace(struct stackframe *frame, void *d) { @@ -84,7 +85,7 @@ static struct frame_tail* user_backtrace(struct frame_tail *tail) /* frame pointers should strictly progress back up the stack * (towards higher addresses) */ - if (tail + 1 >= buftail[0].fp) + if (tail >= buftail[0].fp) return NULL; return buftail[0].fp-1; @@ -110,7 +111,6 @@ static void arm_backtrace(struct pt_regs * const regs, unsigned int depth) int __init oprofile_arch_init(struct oprofile_operations *ops) { - /* provide backtrace support also in timer mode: */ ops->backtrace = arm_backtrace; return oprofile_perf_init(ops); @@ -120,3 +120,11 @@ void __exit oprofile_arch_exit(void) { oprofile_perf_exit(); } +#else +int __init oprofile_arch_init(struct oprofile_operations *ops) +{ + pr_info("oprofile: hardware counters not available\n"); + return -ENODEV; +} +void __exit oprofile_arch_exit(void) {} +#endif /* CONFIG_HW_PERF_EVENTS */ diff --git a/trunk/arch/arm/plat-pxa/mfp.c b/trunk/arch/arm/plat-pxa/mfp.c index a9aa5ad3f4eb..b77e018d36c1 100644 --- a/trunk/arch/arm/plat-pxa/mfp.c +++ b/trunk/arch/arm/plat-pxa/mfp.c @@ -139,11 +139,10 @@ static const unsigned long mfpr_edge[] = { #define mfp_configured(p) ((p)->config != -1) /* - * perform a read-back of any valid MFPR register to make sure the + * perform a read-back of any MFPR register to make sure the * previous writings are finished */ -static unsigned long mfpr_off_readback; -#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + mfpr_off_readback) +#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + 0) static inline void __mfp_config_run(struct mfp_pin *p) { @@ -249,9 +248,6 @@ void __init mfp_init_addr(struct mfp_addr_map *map) spin_lock_irqsave(&mfp_spin_lock, flags); - /* mfp offset for readback */ - mfpr_off_readback = map[0].offset; - for (p = map; p->start != MFP_PIN_INVALID; p++) { offset = p->offset; i = p->start; diff --git a/trunk/arch/m68k/include/asm/string.h b/trunk/arch/m68k/include/asm/string.h index 32198454da70..65b131282837 100644 --- a/trunk/arch/m68k/include/asm/string.h +++ b/trunk/arch/m68k/include/asm/string.h @@ -99,12 +99,14 @@ static inline int strcmp(const char *cs, const char *ct) : "+a" (cs), "+a" (ct), "=d" (res)); return res; } -#endif /* CONFIG_COLDFIRE */ #define __HAVE_ARCH_MEMMOVE extern void *memmove(void *, const void *, __kernel_size_t); +#define __HAVE_ARCH_MEMCMP +extern int memcmp(const void *, const void *, __kernel_size_t); #define memcmp(d, s, n) __builtin_memcmp(d, s, n) +#endif /* CONFIG_COLDFIRE */ #define __HAVE_ARCH_MEMSET extern void *memset(void *, int, __kernel_size_t); diff --git a/trunk/arch/m68k/lib/string.c b/trunk/arch/m68k/lib/string.c index d399c5f25636..4253f870e54f 100644 --- a/trunk/arch/m68k/lib/string.c +++ b/trunk/arch/m68k/lib/string.c @@ -243,3 +243,14 @@ void *memmove(void *dest, const void *src, size_t n) return xdest; } EXPORT_SYMBOL(memmove); + +int memcmp(const void *cs, const void *ct, size_t count) +{ + const unsigned char *su1, *su2; + + for (su1 = cs, su2 = ct; count > 0; ++su1, ++su2, count--) + if (*su1 != *su2) + return *su1 < *su2 ? -1 : +1; + return 0; +} +EXPORT_SYMBOL(memcmp); diff --git a/trunk/arch/m68knommu/kernel/vmlinux.lds.S b/trunk/arch/m68knommu/kernel/vmlinux.lds.S index 47e15ebfd893..ef332136f96d 100644 --- a/trunk/arch/m68knommu/kernel/vmlinux.lds.S +++ b/trunk/arch/m68knommu/kernel/vmlinux.lds.S @@ -141,12 +141,6 @@ SECTIONS { *(__param) __stop___param = .; - /* Built-in module versions */ - . = ALIGN(4) ; - __start___modver = .; - *(__modver) - __stop___modver = .; - . = ALIGN(4) ; _etext = . ; } > TEXT diff --git a/trunk/arch/m68knommu/lib/Makefile b/trunk/arch/m68knommu/lib/Makefile index 32d852e586d7..d94d709665aa 100644 --- a/trunk/arch/m68knommu/lib/Makefile +++ b/trunk/arch/m68knommu/lib/Makefile @@ -4,4 +4,4 @@ lib-y := ashldi3.o ashrdi3.o lshrdi3.o \ muldi3.o mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \ - checksum.o memcpy.o memmove.o memset.o delay.o + checksum.o memcpy.o memset.o delay.o diff --git a/trunk/arch/m68knommu/lib/memmove.c b/trunk/arch/m68knommu/lib/memmove.c deleted file mode 100644 index b3dcfe9dab7e..000000000000 --- a/trunk/arch/m68knommu/lib/memmove.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -#define __IN_STRING_C - -#include -#include - -void *memmove(void *dest, const void *src, size_t n) -{ - void *xdest = dest; - size_t temp; - - if (!n) - return xdest; - - if (dest < src) { - if ((long)dest & 1) { - char *cdest = dest; - const char *csrc = src; - *cdest++ = *csrc++; - dest = cdest; - src = csrc; - n--; - } - if (n > 2 && (long)dest & 2) { - short *sdest = dest; - const short *ssrc = src; - *sdest++ = *ssrc++; - dest = sdest; - src = ssrc; - n -= 2; - } - temp = n >> 2; - if (temp) { - long *ldest = dest; - const long *lsrc = src; - temp--; - do - *ldest++ = *lsrc++; - while (temp--); - dest = ldest; - src = lsrc; - } - if (n & 2) { - short *sdest = dest; - const short *ssrc = src; - *sdest++ = *ssrc++; - dest = sdest; - src = ssrc; - } - if (n & 1) { - char *cdest = dest; - const char *csrc = src; - *cdest = *csrc; - } - } else { - dest = (char *)dest + n; - src = (const char *)src + n; - if ((long)dest & 1) { - char *cdest = dest; - const char *csrc = src; - *--cdest = *--csrc; - dest = cdest; - src = csrc; - n--; - } - if (n > 2 && (long)dest & 2) { - short *sdest = dest; - const short *ssrc = src; - *--sdest = *--ssrc; - dest = sdest; - src = ssrc; - n -= 2; - } - temp = n >> 2; - if (temp) { - long *ldest = dest; - const long *lsrc = src; - temp--; - do - *--ldest = *--lsrc; - while (temp--); - dest = ldest; - src = lsrc; - } - if (n & 2) { - short *sdest = dest; - const short *ssrc = src; - *--sdest = *--ssrc; - dest = sdest; - src = ssrc; - } - if (n & 1) { - char *cdest = dest; - const char *csrc = src; - *--cdest = *--csrc; - } - } - return xdest; -} -EXPORT_SYMBOL(memmove); diff --git a/trunk/arch/m68knommu/platform/5249/intc2.c b/trunk/arch/m68knommu/platform/5249/intc2.c index c5151f846591..d09d9da04537 100644 --- a/trunk/arch/m68knommu/platform/5249/intc2.c +++ b/trunk/arch/m68knommu/platform/5249/intc2.c @@ -50,10 +50,8 @@ static int __init mcf_intc2_init(void) int irq; /* GPIO interrupt sources */ - for (irq = MCFINTC2_GPIOIRQ0; (irq <= MCFINTC2_GPIOIRQ7); irq++) { + for (irq = MCFINTC2_GPIOIRQ0; (irq <= MCFINTC2_GPIOIRQ7); irq++) irq_desc[irq].chip = &intc2_irq_gpio_chip; - set_irq_handler(irq, handle_edge_irq); - } return 0; } diff --git a/trunk/arch/m68knommu/platform/68328/entry.S b/trunk/arch/m68knommu/platform/68328/entry.S index 676960cf022a..240a7a6e25c8 100644 --- a/trunk/arch/m68knommu/platform/68328/entry.S +++ b/trunk/arch/m68knommu/platform/68328/entry.S @@ -108,6 +108,7 @@ Luser_return: movel %d1,%a2 1: move %a2@(TI_FLAGS),%d1 /* thread_info->flags */ + andl #_TIF_WORK_MASK,%d1 jne Lwork_to_do RESTORE_ALL diff --git a/trunk/arch/m68knommu/platform/68360/commproc.c b/trunk/arch/m68knommu/platform/68360/commproc.c index 8e4e10cc0080..f27e688c404e 100644 --- a/trunk/arch/m68knommu/platform/68360/commproc.c +++ b/trunk/arch/m68knommu/platform/68360/commproc.c @@ -210,7 +210,7 @@ void cpm_install_handler(int vec, void (*handler)(), void *dev_id) { - request_irq(vec, handler, 0, "timer", dev_id); + request_irq(vec, handler, IRQ_FLG_LOCK, "timer", dev_id); /* if (cpm_vecs[vec].handler != 0) */ /* printk(KERN_INFO "CPM interrupt %x replacing %x\n", */ diff --git a/trunk/arch/m68knommu/platform/68360/config.c b/trunk/arch/m68knommu/platform/68360/config.c index 9dd5bca38749..ac629fa30099 100644 --- a/trunk/arch/m68knommu/platform/68360/config.c +++ b/trunk/arch/m68knommu/platform/68360/config.c @@ -75,7 +75,7 @@ void hw_timer_init(void) /* Set compare register 32Khz / 32 / 10 = 100 */ TCMP = 10; - request_irq(IRQ_MACHSPEC | 1, timer_routine, 0, "timer", NULL); + request_irq(IRQ_MACHSPEC | 1, timer_routine, IRQ_FLG_LOCK, "timer", NULL); #endif /* General purpose quicc timers: MC68360UM p7-20 */ diff --git a/trunk/arch/m68knommu/platform/68360/entry.S b/trunk/arch/m68knommu/platform/68360/entry.S index 46c1b18c9dcb..8a28788c0eea 100644 --- a/trunk/arch/m68knommu/platform/68360/entry.S +++ b/trunk/arch/m68knommu/platform/68360/entry.S @@ -104,6 +104,7 @@ Luser_return: movel %d1,%a2 1: move %a2@(TI_FLAGS),%d1 /* thread_info->flags */ + andl #_TIF_WORK_MASK,%d1 jne Lwork_to_do RESTORE_ALL diff --git a/trunk/arch/m68knommu/platform/68360/ints.c b/trunk/arch/m68knommu/platform/68360/ints.c index a29041c1a8a0..ad96ab1051f0 100644 --- a/trunk/arch/m68knommu/platform/68360/ints.c +++ b/trunk/arch/m68knommu/platform/68360/ints.c @@ -132,8 +132,8 @@ void init_IRQ(void) pquicc->intr_cimr = 0x00000000; for (i = 0; (i < NR_IRQS); i++) { - set_irq_chip(i, &intc_irq_chip); - set_irq_handler(i, handle_level_irq); + set_irq_chip(irq, &intc_irq_chip); + set_irq_handler(irq, handle_level_irq); } } diff --git a/trunk/arch/m68knommu/platform/coldfire/entry.S b/trunk/arch/m68knommu/platform/coldfire/entry.S index 5837cf080b6d..4ddfc3da70d8 100644 --- a/trunk/arch/m68knommu/platform/coldfire/entry.S +++ b/trunk/arch/m68knommu/platform/coldfire/entry.S @@ -138,6 +138,7 @@ Luser_return: andl #-THREAD_SIZE,%d1 /* at base of kernel stack */ movel %d1,%a0 movel %a0@(TI_FLAGS),%d1 /* get thread_info->flags */ + andl #0xefff,%d1 jne Lwork_to_do /* still work to do */ Lreturn: diff --git a/trunk/arch/s390/crypto/sha_common.c b/trunk/arch/s390/crypto/sha_common.c index 48884f89ab92..f42dbabc0d30 100644 --- a/trunk/arch/s390/crypto/sha_common.c +++ b/trunk/arch/s390/crypto/sha_common.c @@ -38,7 +38,6 @@ int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len) BUG_ON(ret != bsize); data += bsize - index; len -= bsize - index; - index = 0; } /* process as many blocks as possible */ diff --git a/trunk/arch/s390/include/asm/processor.h b/trunk/arch/s390/include/asm/processor.h index 2c79b6416271..bf3de04170a7 100644 --- a/trunk/arch/s390/include/asm/processor.h +++ b/trunk/arch/s390/include/asm/processor.h @@ -148,6 +148,11 @@ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); */ extern unsigned long thread_saved_pc(struct task_struct *t); +/* + * Print register of task into buffer. Used in fs/proc/array.c. + */ +extern void task_show_regs(struct seq_file *m, struct task_struct *task); + extern void show_code(struct pt_regs *regs); unsigned long get_wchan(struct task_struct *p); diff --git a/trunk/arch/s390/kernel/traps.c b/trunk/arch/s390/kernel/traps.c index b5a4a739b477..5eb78dd584ce 100644 --- a/trunk/arch/s390/kernel/traps.c +++ b/trunk/arch/s390/kernel/traps.c @@ -237,6 +237,43 @@ void show_regs(struct pt_regs *regs) show_last_breaking_event(regs); } +/* This is called from fs/proc/array.c */ +void task_show_regs(struct seq_file *m, struct task_struct *task) +{ + struct pt_regs *regs; + + regs = task_pt_regs(task); + seq_printf(m, "task: %p, ksp: %p\n", + task, (void *)task->thread.ksp); + seq_printf(m, "User PSW : %p %p\n", + (void *) regs->psw.mask, (void *)regs->psw.addr); + + seq_printf(m, "User GPRS: " FOURLONG, + regs->gprs[0], regs->gprs[1], + regs->gprs[2], regs->gprs[3]); + seq_printf(m, " " FOURLONG, + regs->gprs[4], regs->gprs[5], + regs->gprs[6], regs->gprs[7]); + seq_printf(m, " " FOURLONG, + regs->gprs[8], regs->gprs[9], + regs->gprs[10], regs->gprs[11]); + seq_printf(m, " " FOURLONG, + regs->gprs[12], regs->gprs[13], + regs->gprs[14], regs->gprs[15]); + seq_printf(m, "User ACRS: %08x %08x %08x %08x\n", + task->thread.acrs[0], task->thread.acrs[1], + task->thread.acrs[2], task->thread.acrs[3]); + seq_printf(m, " %08x %08x %08x %08x\n", + task->thread.acrs[4], task->thread.acrs[5], + task->thread.acrs[6], task->thread.acrs[7]); + seq_printf(m, " %08x %08x %08x %08x\n", + task->thread.acrs[8], task->thread.acrs[9], + task->thread.acrs[10], task->thread.acrs[11]); + seq_printf(m, " %08x %08x %08x %08x\n", + task->thread.acrs[12], task->thread.acrs[13], + task->thread.acrs[14], task->thread.acrs[15]); +} + static DEFINE_SPINLOCK(die_lock); void die(const char * str, struct pt_regs * regs, long err) diff --git a/trunk/arch/sparc/include/asm/pcr.h b/trunk/arch/sparc/include/asm/pcr.h index 843e4faf6a50..a2f5c61f924e 100644 --- a/trunk/arch/sparc/include/asm/pcr.h +++ b/trunk/arch/sparc/include/asm/pcr.h @@ -43,6 +43,4 @@ static inline u64 picl_value(unsigned int nmi_hz) extern u64 pcr_enable; -extern int pcr_arch_init(void); - #endif /* __PCR_H */ diff --git a/trunk/arch/sparc/kernel/iommu.c b/trunk/arch/sparc/kernel/iommu.c index 72509d0e34be..47977a77f6c6 100644 --- a/trunk/arch/sparc/kernel/iommu.c +++ b/trunk/arch/sparc/kernel/iommu.c @@ -255,9 +255,10 @@ static inline iopte_t *alloc_npages(struct device *dev, struct iommu *iommu, static int iommu_alloc_ctx(struct iommu *iommu) { int lowest = iommu->ctx_lowest_free; - int n = find_next_zero_bit(iommu->ctx_bitmap, IOMMU_NUM_CTXS, lowest); + int sz = IOMMU_NUM_CTXS - lowest; + int n = find_next_zero_bit(iommu->ctx_bitmap, sz, lowest); - if (unlikely(n == IOMMU_NUM_CTXS)) { + if (unlikely(n == sz)) { n = find_next_zero_bit(iommu->ctx_bitmap, lowest, 1); if (unlikely(n == lowest)) { printk(KERN_WARNING "IOMMU: Ran out of contexts.\n"); diff --git a/trunk/arch/sparc/kernel/pcr.c b/trunk/arch/sparc/kernel/pcr.c index 7c2ced612b8f..ae96cf52a955 100644 --- a/trunk/arch/sparc/kernel/pcr.c +++ b/trunk/arch/sparc/kernel/pcr.c @@ -167,3 +167,5 @@ int __init pcr_arch_init(void) unregister_perf_hsvc(); return err; } + +early_initcall(pcr_arch_init); diff --git a/trunk/arch/sparc/kernel/smp_64.c b/trunk/arch/sparc/kernel/smp_64.c index 555a76d1f4a1..b6a2b8f47040 100644 --- a/trunk/arch/sparc/kernel/smp_64.c +++ b/trunk/arch/sparc/kernel/smp_64.c @@ -49,7 +49,6 @@ #include #include #include -#include #include "cpumap.h" @@ -1359,7 +1358,6 @@ void __cpu_die(unsigned int cpu) void __init smp_cpus_done(unsigned int max_cpus) { - pcr_arch_init(); } void smp_send_reschedule(int cpu) diff --git a/trunk/arch/sparc/kernel/una_asm_32.S b/trunk/arch/sparc/kernel/una_asm_32.S index 8f096e84a937..8cc03458eb7e 100644 --- a/trunk/arch/sparc/kernel/una_asm_32.S +++ b/trunk/arch/sparc/kernel/una_asm_32.S @@ -24,9 +24,9 @@ retl_efault: .globl __do_int_store __do_int_store: ld [%o2], %g1 - cmp %o1, 2 + cmp %1, 2 be 2f - cmp %o1, 4 + cmp %1, 4 be 1f srl %g1, 24, %g2 srl %g1, 16, %g7 diff --git a/trunk/arch/sparc/lib/bitext.c b/trunk/arch/sparc/lib/bitext.c index 48d00e72ce15..764b3eb7b604 100644 --- a/trunk/arch/sparc/lib/bitext.c +++ b/trunk/arch/sparc/lib/bitext.c @@ -10,7 +10,7 @@ */ #include -#include +#include #include @@ -80,7 +80,8 @@ int bit_map_string_get(struct bit_map *t, int len, int align) while (test_bit(offset + i, t->map) == 0) { i++; if (i == len) { - bitmap_set(t->map, offset, len); + for (i = 0; i < len; i++) + __set_bit(offset + i, t->map); if (offset == t->first_free) t->first_free = find_next_zero_bit (t->map, t->size, diff --git a/trunk/arch/x86/include/asm/apic.h b/trunk/arch/x86/include/asm/apic.h index 3c896946f4cc..5e3969c36d7f 100644 --- a/trunk/arch/x86/include/asm/apic.h +++ b/trunk/arch/x86/include/asm/apic.h @@ -233,7 +233,6 @@ extern void sync_Arb_IDs(void); extern void init_bsp_APIC(void); extern void setup_local_APIC(void); extern void end_local_APIC_setup(void); -extern void bsp_end_local_APIC_setup(void); extern void init_apic_mappings(void); void register_lapic_address(unsigned long address); extern void setup_boot_APIC_clock(void); diff --git a/trunk/arch/x86/include/asm/cpu.h b/trunk/arch/x86/include/asm/cpu.h index 4564c8e28a33..6e6e7558e702 100644 --- a/trunk/arch/x86/include/asm/cpu.h +++ b/trunk/arch/x86/include/asm/cpu.h @@ -32,6 +32,6 @@ extern void arch_unregister_cpu(int); DECLARE_PER_CPU(int, cpu_state); -int mwait_usable(const struct cpuinfo_x86 *); +int __cpuinit mwait_usable(const struct cpuinfo_x86 *); #endif /* _ASM_X86_CPU_H */ diff --git a/trunk/arch/x86/kernel/alternative.c b/trunk/arch/x86/kernel/alternative.c index 7038b95d363f..123608531c8f 100644 --- a/trunk/arch/x86/kernel/alternative.c +++ b/trunk/arch/x86/kernel/alternative.c @@ -671,7 +671,7 @@ void __kprobes text_poke_smp_batch(struct text_poke_param *params, int n) atomic_set(&stop_machine_first, 1); wrote_text = 0; - __stop_machine(stop_machine_text_poke, (void *)&tpp, NULL); + stop_machine(stop_machine_text_poke, (void *)&tpp, NULL); } #if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL) diff --git a/trunk/arch/x86/kernel/apic/apic.c b/trunk/arch/x86/kernel/apic/apic.c index 76b96d74978a..06c196d7e59c 100644 --- a/trunk/arch/x86/kernel/apic/apic.c +++ b/trunk/arch/x86/kernel/apic/apic.c @@ -1381,17 +1381,12 @@ void __cpuinit end_local_APIC_setup(void) #endif apic_pm_activate(); -} - -void __init bsp_end_local_APIC_setup(void) -{ - end_local_APIC_setup(); /* * Now that local APIC setup is completed for BP, configure the fault * handling for interrupt remapping. */ - if (intr_remapping_enabled) + if (!smp_processor_id() && intr_remapping_enabled) enable_drhd_fault_handling(); } @@ -1761,7 +1756,7 @@ int __init APIC_init_uniprocessor(void) enable_IO_APIC(); #endif - bsp_end_local_APIC_setup(); + end_local_APIC_setup(); #ifdef CONFIG_X86_IO_APIC if (smp_found_config && !skip_ioapic_setup && nr_ioapics) diff --git a/trunk/arch/x86/kernel/apic/io_apic.c b/trunk/arch/x86/kernel/apic/io_apic.c index ca9e2a3545a9..697dc34b7b87 100644 --- a/trunk/arch/x86/kernel/apic/io_apic.c +++ b/trunk/arch/x86/kernel/apic/io_apic.c @@ -4002,9 +4002,6 @@ int mp_find_ioapic(u32 gsi) { int i = 0; - if (nr_ioapics == 0) - return -1; - /* Find the IOAPIC that manages this GSI. */ for (i = 0; i < nr_ioapics; i++) { if ((gsi >= mp_gsi_routing[i].gsi_base) diff --git a/trunk/arch/x86/kernel/irq.c b/trunk/arch/x86/kernel/irq.c index 387b6a0c9e81..52945da52a94 100644 --- a/trunk/arch/x86/kernel/irq.c +++ b/trunk/arch/x86/kernel/irq.c @@ -367,8 +367,7 @@ void fixup_irqs(void) if (irr & (1 << (vector % 32))) { irq = __this_cpu_read(vector_irq[vector]); - desc = irq_to_desc(irq); - data = &desc->irq_data; + data = irq_get_irq_data(irq); raw_spin_lock(&desc->lock); if (data->chip->irq_retrigger) data->chip->irq_retrigger(data); diff --git a/trunk/arch/x86/kernel/process.c b/trunk/arch/x86/kernel/process.c index ff4554198981..e764fc05d700 100644 --- a/trunk/arch/x86/kernel/process.c +++ b/trunk/arch/x86/kernel/process.c @@ -92,31 +92,21 @@ void show_regs(struct pt_regs *regs) void show_regs_common(void) { - const char *vendor, *product, *board; + const char *board, *product; - vendor = dmi_get_system_info(DMI_SYS_VENDOR); - if (!vendor) - vendor = ""; + board = dmi_get_system_info(DMI_BOARD_NAME); + if (!board) + board = ""; product = dmi_get_system_info(DMI_PRODUCT_NAME); if (!product) product = ""; - /* Board Name is optional */ - board = dmi_get_system_info(DMI_BOARD_NAME); - printk(KERN_CONT "\n"); - printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s", + printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s %s/%s\n", current->pid, current->comm, print_tainted(), init_utsname()->release, (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); - printk(KERN_CONT " "); - printk(KERN_CONT "%s %s", vendor, product); - if (board) { - printk(KERN_CONT "/"); - printk(KERN_CONT "%s", board); - } - printk(KERN_CONT "\n"); + init_utsname()->version, board, product); } void flush_thread(void) @@ -516,7 +506,7 @@ static void poll_idle(void) #define MWAIT_ECX_EXTENDED_INFO 0x01 #define MWAIT_EDX_C1 0xf0 -int mwait_usable(const struct cpuinfo_x86 *c) +int __cpuinit mwait_usable(const struct cpuinfo_x86 *c) { u32 eax, ebx, ecx, edx; diff --git a/trunk/arch/x86/kernel/smpboot.c b/trunk/arch/x86/kernel/smpboot.c index 08776a953487..03273b6c272c 100644 --- a/trunk/arch/x86/kernel/smpboot.c +++ b/trunk/arch/x86/kernel/smpboot.c @@ -1060,7 +1060,7 @@ static int __init smp_sanity_check(unsigned max_cpus) connect_bsp_APIC(); setup_local_APIC(); - bsp_end_local_APIC_setup(); + end_local_APIC_setup(); return -1; } @@ -1137,7 +1137,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) if (!skip_ioapic_setup && nr_ioapics) enable_IO_APIC(); - bsp_end_local_APIC_setup(); + end_local_APIC_setup(); map_cpu_to_logical_apicid(); diff --git a/trunk/drivers/acpi/acpica/evxfgpe.c b/trunk/drivers/acpi/acpica/evxfgpe.c index 3b20a3401b64..e9562a7cb2f9 100644 --- a/trunk/drivers/acpi/acpica/evxfgpe.c +++ b/trunk/drivers/acpi/acpica/evxfgpe.c @@ -212,40 +212,37 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, return_ACPI_STATUS(AE_BAD_PARAMETER); } - flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); - - /* Ensure that we have a valid GPE number */ + /* Validate wake_device is of type Device */ - gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); - if (!gpe_event_info) { - goto unlock_and_exit; + device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device); + if (device_node->type != ACPI_TYPE_DEVICE) { + return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* - * If there is no method or handler for this GPE, then the - * wake_device will be notified whenever this GPE fires (aka - * "implicit notify") Note: The GPE is assumed to be - * level-triggered (for windows compatibility). - */ - if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == - ACPI_GPE_DISPATCH_NONE) && (wake_device != ACPI_ROOT_OBJECT)) { + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); - /* Validate wake_device is of type Device */ + /* Ensure that we have a valid GPE number */ - device_node = ACPI_CAST_PTR(struct acpi_namespace_node, - wake_device); - if (device_node->type != ACPI_TYPE_DEVICE) { - goto unlock_and_exit; + gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); + if (gpe_event_info) { + /* + * If there is no method or handler for this GPE, then the + * wake_device will be notified whenever this GPE fires (aka + * "implicit notify") Note: The GPE is assumed to be + * level-triggered (for windows compatibility). + */ + if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == + ACPI_GPE_DISPATCH_NONE) { + gpe_event_info->flags = + (ACPI_GPE_DISPATCH_NOTIFY | + ACPI_GPE_LEVEL_TRIGGERED); + gpe_event_info->dispatch.device_node = device_node; } - gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY | - ACPI_GPE_LEVEL_TRIGGERED); - gpe_event_info->dispatch.device_node = device_node; - } - gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; - status = AE_OK; + gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; + status = AE_OK; + } - unlock_and_exit: acpi_os_release_lock(acpi_gbl_gpe_lock, flags); return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index c90c76aa7f8b..b0931818cf98 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -636,21 +636,17 @@ EXPORT_SYMBOL(acpi_os_write_port); acpi_status acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) { - void __iomem *virt_addr; - unsigned int size = width / 8; - bool unmap = false; u32 dummy; + void __iomem *virt_addr; + int size = width / 8, unmap = 0; rcu_read_lock(); virt_addr = acpi_map_vaddr_lookup(phys_addr, size); + rcu_read_unlock(); if (!virt_addr) { - rcu_read_unlock(); virt_addr = acpi_os_ioremap(phys_addr, size); - if (!virt_addr) - return AE_BAD_ADDRESS; - unmap = true; + unmap = 1; } - if (!value) value = &dummy; @@ -670,8 +666,6 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) if (unmap) iounmap(virt_addr); - else - rcu_read_unlock(); return AE_OK; } @@ -680,17 +674,14 @@ acpi_status acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) { void __iomem *virt_addr; - unsigned int size = width / 8; - bool unmap = false; + int size = width / 8, unmap = 0; rcu_read_lock(); virt_addr = acpi_map_vaddr_lookup(phys_addr, size); + rcu_read_unlock(); if (!virt_addr) { - rcu_read_unlock(); virt_addr = acpi_os_ioremap(phys_addr, size); - if (!virt_addr) - return AE_BAD_ADDRESS; - unmap = true; + unmap = 1; } switch (width) { @@ -709,8 +700,6 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) if (unmap) iounmap(virt_addr); - else - rcu_read_unlock(); return AE_OK; } diff --git a/trunk/drivers/acpi/video_detect.c b/trunk/drivers/acpi/video_detect.c index 5af3479714f6..42d3d72dae85 100644 --- a/trunk/drivers/acpi/video_detect.c +++ b/trunk/drivers/acpi/video_detect.c @@ -82,11 +82,6 @@ long acpi_is_video_device(struct acpi_device *device) if (!device) return 0; - /* Is this device able to support video switching ? */ - if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) || - ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy))) - video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING; - /* Is this device able to retrieve a video ROM ? */ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy))) video_caps |= ACPI_VIDEO_ROM_AVAILABLE; diff --git a/trunk/drivers/acpi/wakeup.c b/trunk/drivers/acpi/wakeup.c index 7bfbe40bc43b..ed6501452507 100644 --- a/trunk/drivers/acpi/wakeup.c +++ b/trunk/drivers/acpi/wakeup.c @@ -86,12 +86,8 @@ int __init acpi_wakeup_device_init(void) struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); - if (device_can_wakeup(&dev->dev)) { - /* Button GPEs are supposed to be always enabled. */ - acpi_enable_gpe(dev->wakeup.gpe_device, - dev->wakeup.gpe_number); + if (device_can_wakeup(&dev->dev)) device_set_wakeup_enable(&dev->dev, true); - } } mutex_unlock(&acpi_device_lock); return 0; diff --git a/trunk/drivers/dma/amba-pl08x.c b/trunk/drivers/dma/amba-pl08x.c index 07bca4970e50..297f48b0cba9 100644 --- a/trunk/drivers/dma/amba-pl08x.c +++ b/trunk/drivers/dma/amba-pl08x.c @@ -79,7 +79,6 @@ #include #include #include -#include #include #include #include @@ -236,19 +235,16 @@ static void pl08x_start_txd(struct pl08x_dma_chan *plchan, } /* - * Pause the channel by setting the HALT bit. + * Overall DMAC remains enabled always. * - * For M->P transfers, pause the DMAC first and then stop the peripheral - - * the FIFO can only drain if the peripheral is still requesting data. - * (note: this can still timeout if the DMAC FIFO never drains of data.) + * Disabling individual channels could lose data. * - * For P->M transfers, disable the peripheral first to stop it filling - * the DMAC FIFO, and then pause the DMAC. + * Disable the peripheral DMA after disabling the DMAC in order to allow + * the DMAC FIFO to drain, and hence allow the channel to show inactive */ static void pl08x_pause_phy_chan(struct pl08x_phy_chan *ch) { u32 val; - int timeout; /* Set the HALT bit and wait for the FIFO to drain */ val = readl(ch->base + PL080_CH_CONFIG); @@ -256,13 +252,8 @@ static void pl08x_pause_phy_chan(struct pl08x_phy_chan *ch) writel(val, ch->base + PL080_CH_CONFIG); /* Wait for channel inactive */ - for (timeout = 1000; timeout; timeout--) { - if (!pl08x_phy_channel_busy(ch)) - break; - udelay(1); - } - if (pl08x_phy_channel_busy(ch)) - pr_err("pl08x: channel%u timeout waiting for pause\n", ch->id); + while (pl08x_phy_channel_busy(ch)) + cpu_relax(); } static void pl08x_resume_phy_chan(struct pl08x_phy_chan *ch) @@ -276,24 +267,19 @@ static void pl08x_resume_phy_chan(struct pl08x_phy_chan *ch) } -/* - * pl08x_terminate_phy_chan() stops the channel, clears the FIFO and - * clears any pending interrupt status. This should not be used for - * an on-going transfer, but as a method of shutting down a channel - * (eg, when it's no longer used) or terminating a transfer. - */ -static void pl08x_terminate_phy_chan(struct pl08x_driver_data *pl08x, - struct pl08x_phy_chan *ch) +/* Stops the channel */ +static void pl08x_stop_phy_chan(struct pl08x_phy_chan *ch) { - u32 val = readl(ch->base + PL080_CH_CONFIG); + u32 val; - val &= ~(PL080_CONFIG_ENABLE | PL080_CONFIG_ERR_IRQ_MASK | - PL080_CONFIG_TC_IRQ_MASK); + pl08x_pause_phy_chan(ch); + /* Disable channel */ + val = readl(ch->base + PL080_CH_CONFIG); + val &= ~PL080_CONFIG_ENABLE; + val &= ~PL080_CONFIG_ERR_IRQ_MASK; + val &= ~PL080_CONFIG_TC_IRQ_MASK; writel(val, ch->base + PL080_CH_CONFIG); - - writel(1 << ch->id, pl08x->base + PL080_ERR_CLEAR); - writel(1 << ch->id, pl08x->base + PL080_TC_CLEAR); } static inline u32 get_bytes_in_cctl(u32 cctl) @@ -418,12 +404,13 @@ static inline void pl08x_put_phy_channel(struct pl08x_driver_data *pl08x, { unsigned long flags; - spin_lock_irqsave(&ch->lock, flags); - /* Stop the channel and clear its interrupts */ - pl08x_terminate_phy_chan(pl08x, ch); + pl08x_stop_phy_chan(ch); + writel((1 << ch->id), pl08x->base + PL080_ERR_CLEAR); + writel((1 << ch->id), pl08x->base + PL080_TC_CLEAR); /* Mark it as free */ + spin_lock_irqsave(&ch->lock, flags); ch->serving = NULL; spin_unlock_irqrestore(&ch->lock, flags); } @@ -1462,7 +1449,7 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, plchan->state = PL08X_CHAN_IDLE; if (plchan->phychan) { - pl08x_terminate_phy_chan(pl08x, plchan->phychan); + pl08x_stop_phy_chan(plchan->phychan); /* * Mark physical channel as free and free any slave diff --git a/trunk/drivers/dma/imx-dma.c b/trunk/drivers/dma/imx-dma.c index e18eaabe92b9..e53d438142bb 100644 --- a/trunk/drivers/dma/imx-dma.c +++ b/trunk/drivers/dma/imx-dma.c @@ -49,7 +49,6 @@ struct imxdma_channel { struct imxdma_engine { struct device *dev; - struct device_dma_parameters dma_parms; struct dma_device dma_device; struct imxdma_channel channel[MAX_DMA_CHANNELS]; }; @@ -243,21 +242,6 @@ static struct dma_async_tx_descriptor *imxdma_prep_slave_sg( else dmamode = DMA_MODE_WRITE; - switch (imxdmac->word_size) { - case DMA_SLAVE_BUSWIDTH_4_BYTES: - if (sgl->length & 3 || sgl->dma_address & 3) - return NULL; - break; - case DMA_SLAVE_BUSWIDTH_2_BYTES: - if (sgl->length & 1 || sgl->dma_address & 1) - return NULL; - break; - case DMA_SLAVE_BUSWIDTH_1_BYTE: - break; - default: - return NULL; - } - ret = imx_dma_setup_sg(imxdmac->imxdma_channel, sgl, sg_len, dma_length, imxdmac->per_address, dmamode); if (ret) @@ -345,9 +329,6 @@ static int __init imxdma_probe(struct platform_device *pdev) INIT_LIST_HEAD(&imxdma->dma_device.channels); - dma_cap_set(DMA_SLAVE, imxdma->dma_device.cap_mask); - dma_cap_set(DMA_CYCLIC, imxdma->dma_device.cap_mask); - /* Initialize channel parameters */ for (i = 0; i < MAX_DMA_CHANNELS; i++) { struct imxdma_channel *imxdmac = &imxdma->channel[i]; @@ -365,7 +346,11 @@ static int __init imxdma_probe(struct platform_device *pdev) imxdmac->imxdma = imxdma; spin_lock_init(&imxdmac->lock); + dma_cap_set(DMA_SLAVE, imxdma->dma_device.cap_mask); + dma_cap_set(DMA_CYCLIC, imxdma->dma_device.cap_mask); + imxdmac->chan.device = &imxdma->dma_device; + imxdmac->chan.chan_id = i; imxdmac->channel = i; /* Add the channel to the DMAC list */ @@ -385,9 +370,6 @@ static int __init imxdma_probe(struct platform_device *pdev) platform_set_drvdata(pdev, imxdma); - imxdma->dma_device.dev->dma_parms = &imxdma->dma_parms; - dma_set_max_seg_size(imxdma->dma_device.dev, 0xffffff); - ret = dma_async_device_register(&imxdma->dma_device); if (ret) { dev_err(&pdev->dev, "unable to register\n"); diff --git a/trunk/drivers/dma/imx-sdma.c b/trunk/drivers/dma/imx-sdma.c index b6d1455fa936..d5a5d4d9c19b 100644 --- a/trunk/drivers/dma/imx-sdma.c +++ b/trunk/drivers/dma/imx-sdma.c @@ -230,7 +230,7 @@ struct sdma_engine; * struct sdma_channel - housekeeping for a SDMA channel * * @sdma pointer to the SDMA engine for this channel - * @channel the channel number, matches dmaengine chan_id + 1 + * @channel the channel number, matches dmaengine chan_id * @direction transfer type. Needed for setting SDMA script * @peripheral_type Peripheral type. Needed for setting SDMA script * @event_id0 aka dma request line @@ -301,7 +301,6 @@ struct sdma_firmware_header { struct sdma_engine { struct device *dev; - struct device_dma_parameters dma_parms; struct sdma_channel channel[MAX_DMA_CHANNELS]; struct sdma_channel_control *channel_control; void __iomem *regs; @@ -450,7 +449,7 @@ static void sdma_handle_channel_loop(struct sdma_channel *sdmac) if (bd->mode.status & BD_RROR) sdmac->status = DMA_ERROR; else - sdmac->status = DMA_IN_PROGRESS; + sdmac->status = DMA_SUCCESS; bd->mode.status |= BD_DONE; sdmac->buf_tail++; @@ -771,15 +770,15 @@ static void sdma_enable_channel(struct sdma_engine *sdma, int channel) __raw_writel(1 << channel, sdma->regs + SDMA_H_START); } -static dma_cookie_t sdma_assign_cookie(struct sdma_channel *sdmac) +static dma_cookie_t sdma_assign_cookie(struct sdma_channel *sdma) { - dma_cookie_t cookie = sdmac->chan.cookie; + dma_cookie_t cookie = sdma->chan.cookie; if (++cookie < 0) cookie = 1; - sdmac->chan.cookie = cookie; - sdmac->desc.cookie = cookie; + sdma->chan.cookie = cookie; + sdma->desc.cookie = cookie; return cookie; } @@ -799,7 +798,7 @@ static dma_cookie_t sdma_tx_submit(struct dma_async_tx_descriptor *tx) cookie = sdma_assign_cookie(sdmac); - sdma_enable_channel(sdma, sdmac->channel); + sdma_enable_channel(sdma, tx->chan->chan_id); spin_unlock_irq(&sdmac->lock); @@ -812,6 +811,10 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan) struct imx_dma_data *data = chan->private; int prio, ret; + /* No need to execute this for internal channel 0 */ + if (chan->chan_id == 0) + return 0; + if (!data) return -EINVAL; @@ -876,7 +879,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( struct sdma_channel *sdmac = to_sdma_chan(chan); struct sdma_engine *sdma = sdmac->sdma; int ret, i, count; - int channel = sdmac->channel; + int channel = chan->chan_id; struct scatterlist *sg; if (sdmac->status == DMA_IN_PROGRESS) @@ -921,33 +924,22 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( ret = -EINVAL; goto err_out; } - - switch (sdmac->word_size) { - case DMA_SLAVE_BUSWIDTH_4_BYTES: + if (sdmac->word_size == DMA_SLAVE_BUSWIDTH_4_BYTES) bd->mode.command = 0; - if (count & 3 || sg->dma_address & 3) - return NULL; - break; - case DMA_SLAVE_BUSWIDTH_2_BYTES: - bd->mode.command = 2; - if (count & 1 || sg->dma_address & 1) - return NULL; - break; - case DMA_SLAVE_BUSWIDTH_1_BYTE: - bd->mode.command = 1; - break; - default: - return NULL; - } + else + bd->mode.command = sdmac->word_size; param = BD_DONE | BD_EXTD | BD_CONT; - if (i + 1 == sg_len) { + if (sdmac->flags & IMX_DMA_SG_LOOP) { param |= BD_INTR; - param |= BD_LAST; - param &= ~BD_CONT; + if (i + 1 == sg_len) + param |= BD_WRAP; } + if (i + 1 == sg_len) + param |= BD_INTR; + dev_dbg(sdma->dev, "entry %d: count: %d dma: 0x%08x %s%s\n", i, count, sg->dma_address, param & BD_WRAP ? "wrap" : "", @@ -961,7 +953,6 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( return &sdmac->desc; err_out: - sdmac->status = DMA_ERROR; return NULL; } @@ -972,7 +963,7 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( struct sdma_channel *sdmac = to_sdma_chan(chan); struct sdma_engine *sdma = sdmac->sdma; int num_periods = buf_len / period_len; - int channel = sdmac->channel; + int channel = chan->chan_id; int ret, i = 0, buf = 0; dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel); @@ -1075,12 +1066,14 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan, { struct sdma_channel *sdmac = to_sdma_chan(chan); dma_cookie_t last_used; + enum dma_status ret; last_used = chan->cookie; + ret = dma_async_is_complete(cookie, sdmac->last_completed, last_used); dma_set_tx_state(txstate, sdmac->last_completed, last_used, 0); - return sdmac->status; + return ret; } static void sdma_issue_pending(struct dma_chan *chan) @@ -1142,7 +1135,7 @@ static int __init sdma_get_firmware(struct sdma_engine *sdma, /* download the RAM image for SDMA */ sdma_load_script(sdma, ram_code, header->ram_code_size, - addr->ram_code_start_addr); + sdma->script_addrs->ram_code_start_addr); clk_disable(sdma->clk); sdma_add_scripts(sdma, addr); @@ -1244,6 +1237,7 @@ static int __init sdma_probe(struct platform_device *pdev) struct resource *iores; struct sdma_platform_data *pdata = pdev->dev.platform_data; int i; + dma_cap_mask_t mask; struct sdma_engine *sdma; sdma = kzalloc(sizeof(*sdma), GFP_KERNEL); @@ -1286,9 +1280,6 @@ static int __init sdma_probe(struct platform_device *pdev) sdma->version = pdata->sdma_version; - dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask); - dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask); - INIT_LIST_HEAD(&sdma->dma_device.channels); /* Initialize channel parameters */ for (i = 0; i < MAX_DMA_CHANNELS; i++) { @@ -1297,17 +1288,15 @@ static int __init sdma_probe(struct platform_device *pdev) sdmac->sdma = sdma; spin_lock_init(&sdmac->lock); + dma_cap_set(DMA_SLAVE, sdma->dma_device.cap_mask); + dma_cap_set(DMA_CYCLIC, sdma->dma_device.cap_mask); + sdmac->chan.device = &sdma->dma_device; + sdmac->chan.chan_id = i; sdmac->channel = i; - /* - * Add the channel to the DMAC list. Do not add channel 0 though - * because we need it internally in the SDMA driver. This also means - * that channel 0 in dmaengine counting matches sdma channel 1. - */ - if (i) - list_add_tail(&sdmac->chan.device_node, - &sdma->dma_device.channels); + /* Add the channel to the DMAC list */ + list_add_tail(&sdmac->chan.device_node, &sdma->dma_device.channels); } ret = sdma_init(sdma); @@ -1328,8 +1317,6 @@ static int __init sdma_probe(struct platform_device *pdev) sdma->dma_device.device_prep_dma_cyclic = sdma_prep_dma_cyclic; sdma->dma_device.device_control = sdma_control; sdma->dma_device.device_issue_pending = sdma_issue_pending; - sdma->dma_device.dev->dma_parms = &sdma->dma_parms; - dma_set_max_seg_size(sdma->dma_device.dev, 65535); ret = dma_async_device_register(&sdma->dma_device); if (ret) { @@ -1337,6 +1324,13 @@ static int __init sdma_probe(struct platform_device *pdev) goto err_init; } + /* request channel 0. This is an internal control channel + * to the SDMA engine and not available to clients. + */ + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + dma_request_channel(mask, NULL, NULL); + dev_info(sdma->dev, "initialized\n"); return 0; @@ -1354,7 +1348,7 @@ static int __init sdma_probe(struct platform_device *pdev) err_request_region: err_irq: kfree(sdma); - return ret; + return 0; } static int __exit sdma_remove(struct platform_device *pdev) diff --git a/trunk/drivers/dma/ipu/ipu_idmac.c b/trunk/drivers/dma/ipu/ipu_idmac.c index c1a125e7d1df..cb26ee9773d6 100644 --- a/trunk/drivers/dma/ipu/ipu_idmac.c +++ b/trunk/drivers/dma/ipu/ipu_idmac.c @@ -1145,6 +1145,29 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan, reg = idmac_read_icreg(ipu, IDMAC_CHA_EN); idmac_write_icreg(ipu, reg & ~chan_mask, IDMAC_CHA_EN); + /* + * Problem (observed with channel DMAIC_7): after enabling the channel + * and initialising buffers, there comes an interrupt with current still + * pointing at buffer 0, whereas it should use buffer 0 first and only + * generate an interrupt when it is done, then current should already + * point to buffer 1. This spurious interrupt also comes on channel + * DMASDC_0. With DMAIC_7 normally, is we just leave the ISR after the + * first interrupt, there comes the second with current correctly + * pointing to buffer 1 this time. But sometimes this second interrupt + * doesn't come and the channel hangs. Clearing BUFx_RDY when disabling + * the channel seems to prevent the channel from hanging, but it doesn't + * prevent the spurious interrupt. This might also be unsafe. Think + * about the IDMAC controller trying to switch to a buffer, when we + * clear the ready bit, and re-enable it a moment later. + */ + reg = idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY); + idmac_write_ipureg(ipu, 0, IPU_CHA_BUF0_RDY); + idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF0_RDY); + + reg = idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY); + idmac_write_ipureg(ipu, 0, IPU_CHA_BUF1_RDY); + idmac_write_ipureg(ipu, reg & ~(1UL << channel), IPU_CHA_BUF1_RDY); + spin_unlock_irqrestore(&ipu->lock, flags); return 0; @@ -1223,6 +1246,33 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id) /* Other interrupts do not interfere with this channel */ spin_lock(&ichan->lock); + if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 && + ((curbuf >> chan_id) & 1) == ichan->active_buffer && + !list_is_last(ichan->queue.next, &ichan->queue))) { + int i = 100; + + /* This doesn't help. See comment in ipu_disable_channel() */ + while (--i) { + curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF); + if (((curbuf >> chan_id) & 1) != ichan->active_buffer) + break; + cpu_relax(); + } + + if (!i) { + spin_unlock(&ichan->lock); + dev_dbg(dev, + "IRQ on active buffer on channel %x, active " + "%d, ready %x, %x, current %x!\n", chan_id, + ichan->active_buffer, ready0, ready1, curbuf); + return IRQ_NONE; + } else + dev_dbg(dev, + "Buffer deactivated on channel %x, active " + "%d, ready %x, %x, current %x, rest %d!\n", chan_id, + ichan->active_buffer, ready0, ready1, curbuf, i); + } + if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) || (!ichan->active_buffer && (ready0 >> chan_id) & 1) )) { diff --git a/trunk/drivers/firmware/dmi_scan.c b/trunk/drivers/firmware/dmi_scan.c index bcb1126e3d00..e28e41668177 100644 --- a/trunk/drivers/firmware/dmi_scan.c +++ b/trunk/drivers/firmware/dmi_scan.c @@ -378,17 +378,10 @@ static void __init print_filtered(const char *info) static void __init dmi_dump_ids(void) { - const char *board; /* Board Name is optional */ - printk(KERN_DEBUG "DMI: "); - print_filtered(dmi_get_system_info(DMI_SYS_VENDOR)); - printk(KERN_CONT " "); + print_filtered(dmi_get_system_info(DMI_BOARD_NAME)); + printk(KERN_CONT "/"); print_filtered(dmi_get_system_info(DMI_PRODUCT_NAME)); - board = dmi_get_system_info(DMI_BOARD_NAME); - if (board) { - printk(KERN_CONT "/"); - print_filtered(board); - } printk(KERN_CONT ", BIOS "); print_filtered(dmi_get_system_info(DMI_BIOS_VERSION)); printk(KERN_CONT " "); diff --git a/trunk/drivers/gpu/drm/drm_info.c b/trunk/drivers/gpu/drm/drm_info.c index be9a9c07d152..3cdbaf379bb5 100644 --- a/trunk/drivers/gpu/drm/drm_info.c +++ b/trunk/drivers/gpu/drm/drm_info.c @@ -283,18 +283,17 @@ int drm_vma_info(struct seq_file *m, void *data) #endif mutex_lock(&dev->struct_mutex); - seq_printf(m, "vma use count: %d, high_memory = %pK, 0x%pK\n", + seq_printf(m, "vma use count: %d, high_memory = %p, 0x%08llx\n", atomic_read(&dev->vma_count), - high_memory, (void *)virt_to_phys(high_memory)); + high_memory, (u64)virt_to_phys(high_memory)); list_for_each_entry(pt, &dev->vmalist, head) { vma = pt->vma; if (!vma) continue; seq_printf(m, - "\n%5d 0x%pK-0x%pK %c%c%c%c%c%c 0x%08lx000", - pt->pid, - (void *)vma->vm_start, (void *)vma->vm_end, + "\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000", + pt->pid, vma->vm_start, vma->vm_end, vma->vm_flags & VM_READ ? 'r' : '-', vma->vm_flags & VM_WRITE ? 'w' : '-', vma->vm_flags & VM_EXEC ? 'x' : '-', diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index 0ad533f06af9..cfb56d0ff367 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -46,9 +46,6 @@ module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); unsigned int i915_powersave = 1; module_param_named(powersave, i915_powersave, int, 0600); -unsigned int i915_enable_rc6 = 0; -module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); - unsigned int i915_lvds_downclock = 0; module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); @@ -363,7 +360,7 @@ static int i915_drm_thaw(struct drm_device *dev) /* Resume the modeset for every activated CRTC */ drm_helper_resume_force_mode(dev); - if (IS_IRONLAKE_M(dev)) + if (dev_priv->renderctx && dev_priv->pwrctx) ironlake_enable_rc6(dev); } diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index 65dfe81d0035..a0149c619cdd 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -958,7 +958,6 @@ extern unsigned int i915_fbpercrtc; extern unsigned int i915_powersave; extern unsigned int i915_lvds_downclock; extern unsigned int i915_panel_use_ssc; -extern unsigned int i915_enable_rc6; extern int i915_suspend(struct drm_device *dev, pm_message_t state); extern int i915_resume(struct drm_device *dev); diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index 15d94c63918c..5cfc68940f17 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -174,9 +174,7 @@ * address/value pairs. Don't overdue it, though, x <= 2^4 must hold! */ #define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*x-1) -#define MI_FLUSH_DW MI_INSTR(0x26, 1) /* for GEN6 */ -#define MI_INVALIDATE_TLB (1<<18) -#define MI_INVALIDATE_BSD (1<<7) +#define MI_FLUSH_DW MI_INSTR(0x26, 2) /* for GEN6 */ #define MI_BATCH_BUFFER MI_INSTR(0x30, 1) #define MI_BATCH_NON_SECURE (1) #define MI_BATCH_NON_SECURE_I965 (1<<8) diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 3b006536b3d2..7e42aa586504 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -5558,7 +5558,9 @@ static void intel_crtc_reset(struct drm_crtc *crtc) /* Reset flags back to the 'unknown' status so that they * will be correctly set on the initial modeset. */ + intel_crtc->cursor_addr = 0; intel_crtc->dpms_mode = -1; + intel_crtc->active = true; /* force the pipe off on setup_init_config */ } static struct drm_crtc_helper_funcs intel_helper_funcs = { @@ -5664,7 +5666,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; intel_crtc_reset(&intel_crtc->base); - intel_crtc->active = true; /* force the pipe off on setup_init_config */ if (HAS_PCH_SPLIT(dev)) { intel_helper_funcs.prepare = ironlake_crtc_prepare; @@ -6462,60 +6463,52 @@ void intel_enable_clock_gating(struct drm_device *dev) } } -static void ironlake_teardown_rc6(struct drm_device *dev) +void intel_disable_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; if (dev_priv->renderctx) { - i915_gem_object_unpin(dev_priv->renderctx); - drm_gem_object_unreference(&dev_priv->renderctx->base); + struct drm_i915_gem_object *obj = dev_priv->renderctx; + + I915_WRITE(CCID, 0); + POSTING_READ(CCID); + + i915_gem_object_unpin(obj); + drm_gem_object_unreference(&obj->base); dev_priv->renderctx = NULL; } if (dev_priv->pwrctx) { - i915_gem_object_unpin(dev_priv->pwrctx); - drm_gem_object_unreference(&dev_priv->pwrctx->base); - dev_priv->pwrctx = NULL; - } -} - -static void ironlake_disable_rc6(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (I915_READ(PWRCTXA)) { - /* Wake the GPU, prevent RC6, then restore RSTDBYCTL */ - I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) | RCX_SW_EXIT); - wait_for(((I915_READ(RSTDBYCTL) & RSX_STATUS_MASK) == RSX_STATUS_ON), - 50); + struct drm_i915_gem_object *obj = dev_priv->pwrctx; I915_WRITE(PWRCTXA, 0); POSTING_READ(PWRCTXA); - I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); - POSTING_READ(RSTDBYCTL); + i915_gem_object_unpin(obj); + drm_gem_object_unreference(&obj->base); + dev_priv->pwrctx = NULL; } - - ironlake_disable_rc6(dev); } -static int ironlake_setup_rc6(struct drm_device *dev) +static void ironlake_disable_rc6(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - if (dev_priv->renderctx == NULL) - dev_priv->renderctx = intel_alloc_context_page(dev); - if (!dev_priv->renderctx) - return -ENOMEM; - - if (dev_priv->pwrctx == NULL) - dev_priv->pwrctx = intel_alloc_context_page(dev); - if (!dev_priv->pwrctx) { - ironlake_teardown_rc6(dev); - return -ENOMEM; - } - - return 0; + /* Wake the GPU, prevent RC6, then restore RSTDBYCTL */ + I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) | RCX_SW_EXIT); + wait_for(((I915_READ(RSTDBYCTL) & RSX_STATUS_MASK) == RSX_STATUS_ON), + 10); + POSTING_READ(CCID); + I915_WRITE(PWRCTXA, 0); + POSTING_READ(PWRCTXA); + I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); + POSTING_READ(RSTDBYCTL); + i915_gem_object_unpin(dev_priv->renderctx); + drm_gem_object_unreference(&dev_priv->renderctx->base); + dev_priv->renderctx = NULL; + i915_gem_object_unpin(dev_priv->pwrctx); + drm_gem_object_unreference(&dev_priv->pwrctx->base); + dev_priv->pwrctx = NULL; } void ironlake_enable_rc6(struct drm_device *dev) @@ -6523,26 +6516,15 @@ void ironlake_enable_rc6(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; int ret; - /* rc6 disabled by default due to repeated reports of hanging during - * boot and resume. - */ - if (!i915_enable_rc6) - return; - - ret = ironlake_setup_rc6(dev); - if (ret) - return; - /* * GPU can automatically power down the render unit if given a page * to save state. */ ret = BEGIN_LP_RING(6); if (ret) { - ironlake_teardown_rc6(dev); + ironlake_disable_rc6(dev); return; } - OUT_RING(MI_SUSPEND_FLUSH | MI_SUSPEND_FLUSH_EN); OUT_RING(MI_SET_CONTEXT); OUT_RING(dev_priv->renderctx->gtt_offset | @@ -6559,7 +6541,6 @@ void ironlake_enable_rc6(struct drm_device *dev) I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); } - /* Set up chip specific display functions */ static void intel_init_display(struct drm_device *dev) { @@ -6802,9 +6783,21 @@ void intel_modeset_init(struct drm_device *dev) if (IS_GEN6(dev)) gen6_enable_rps(dev_priv); - if (IS_IRONLAKE_M(dev)) + if (IS_IRONLAKE_M(dev)) { + dev_priv->renderctx = intel_alloc_context_page(dev); + if (!dev_priv->renderctx) + goto skip_rc6; + dev_priv->pwrctx = intel_alloc_context_page(dev); + if (!dev_priv->pwrctx) { + i915_gem_object_unpin(dev_priv->renderctx); + drm_gem_object_unreference(&dev_priv->renderctx->base); + dev_priv->renderctx = NULL; + goto skip_rc6; + } ironlake_enable_rc6(dev); + } +skip_rc6: INIT_WORK(&dev_priv->idle_work, intel_idle_update); setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, (unsigned long)dev); diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index 51cb4e36997f..1f4242b682c8 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -1639,24 +1639,6 @@ static int intel_dp_get_modes(struct drm_connector *connector) return 0; } -static bool -intel_dp_detect_audio(struct drm_connector *connector) -{ - struct intel_dp *intel_dp = intel_attached_dp(connector); - struct edid *edid; - bool has_audio = false; - - edid = drm_get_edid(connector, &intel_dp->adapter); - if (edid) { - has_audio = drm_detect_monitor_audio(edid); - - connector->display_info.raw_edid = NULL; - kfree(edid); - } - - return has_audio; -} - static int intel_dp_set_property(struct drm_connector *connector, struct drm_property *property, @@ -1670,23 +1652,17 @@ intel_dp_set_property(struct drm_connector *connector, return ret; if (property == intel_dp->force_audio_property) { - int i = val; - bool has_audio; - - if (i == intel_dp->force_audio) + if (val == intel_dp->force_audio) return 0; - intel_dp->force_audio = i; + intel_dp->force_audio = val; - if (i == 0) - has_audio = intel_dp_detect_audio(connector); - else - has_audio = i > 0; - - if (has_audio == intel_dp->has_audio) + if (val > 0 && intel_dp->has_audio) + return 0; + if (val < 0 && !intel_dp->has_audio) return 0; - intel_dp->has_audio = has_audio; + intel_dp->has_audio = val > 0; goto done; } diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index 2c431049963c..74db2557d644 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -298,6 +298,7 @@ extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, int regno); extern void intel_enable_clock_gating(struct drm_device *dev); +extern void intel_disable_clock_gating(struct drm_device *dev); extern void ironlake_enable_drps(struct drm_device *dev); extern void ironlake_disable_drps(struct drm_device *dev); extern void gen6_enable_rps(struct drm_i915_private *dev_priv); diff --git a/trunk/drivers/gpu/drm/i915/intel_hdmi.c b/trunk/drivers/gpu/drm/i915/intel_hdmi.c index c635c9e357b9..0d0273e7b029 100644 --- a/trunk/drivers/gpu/drm/i915/intel_hdmi.c +++ b/trunk/drivers/gpu/drm/i915/intel_hdmi.c @@ -251,27 +251,6 @@ static int intel_hdmi_get_modes(struct drm_connector *connector) &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); } -static bool -intel_hdmi_detect_audio(struct drm_connector *connector) -{ - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); - struct drm_i915_private *dev_priv = connector->dev->dev_private; - struct edid *edid; - bool has_audio = false; - - edid = drm_get_edid(connector, - &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); - if (edid) { - if (edid->input & DRM_EDID_INPUT_DIGITAL) - has_audio = drm_detect_monitor_audio(edid); - - connector->display_info.raw_edid = NULL; - kfree(edid); - } - - return has_audio; -} - static int intel_hdmi_set_property(struct drm_connector *connector, struct drm_property *property, @@ -285,23 +264,17 @@ intel_hdmi_set_property(struct drm_connector *connector, return ret; if (property == intel_hdmi->force_audio_property) { - int i = val; - bool has_audio; - - if (i == intel_hdmi->force_audio) + if (val == intel_hdmi->force_audio) return 0; - intel_hdmi->force_audio = i; - - if (i == 0) - has_audio = intel_hdmi_detect_audio(connector); - else - has_audio = i > 0; + intel_hdmi->force_audio = val; - if (has_audio == intel_hdmi->has_audio) + if (val > 0 && intel_hdmi->has_audio) + return 0; + if (val < 0 && !intel_hdmi->has_audio) return 0; - intel_hdmi->has_audio = has_audio; + intel_hdmi->has_audio = val > 0; goto done; } diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index bcdba7bd5cfa..ace8d5d30dd2 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -261,6 +261,12 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, return true; } + /* Make sure pre-965s set dither correctly */ + if (INTEL_INFO(dev)->gen < 4) { + if (dev_priv->lvds_dither) + pfit_control |= PANEL_8TO6_DITHER_ENABLE; + } + /* Native modes don't need fitting */ if (adjusted_mode->hdisplay == mode->hdisplay && adjusted_mode->vdisplay == mode->vdisplay) @@ -368,16 +374,10 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, } out: - /* If not enabling scaling, be consistent and always use 0. */ if ((pfit_control & PFIT_ENABLE) == 0) { pfit_control = 0; pfit_pgm_ratios = 0; } - - /* Make sure pre-965 set dither correctly */ - if (INTEL_INFO(dev)->gen < 4 && dev_priv->lvds_dither) - pfit_control |= PANEL_8TO6_DITHER_ENABLE; - if (pfit_control != intel_lvds->pfit_control || pfit_pgm_ratios != intel_lvds->pfit_pgm_ratios) { intel_lvds->pfit_control = pfit_control; diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c index 445f27efe677..6218fa97aa1e 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1059,25 +1059,22 @@ static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring, } static int gen6_ring_flush(struct intel_ring_buffer *ring, - u32 invalidate, u32 flush) + u32 invalidate_domains, + u32 flush_domains) { - uint32_t cmd; int ret; - if (((invalidate | flush) & I915_GEM_GPU_DOMAINS) == 0) + if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) return 0; ret = intel_ring_begin(ring, 4); if (ret) return ret; - cmd = MI_FLUSH_DW; - if (invalidate & I915_GEM_GPU_DOMAINS) - cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD; - intel_ring_emit(ring, cmd); + intel_ring_emit(ring, MI_FLUSH_DW); + intel_ring_emit(ring, 0); intel_ring_emit(ring, 0); intel_ring_emit(ring, 0); - intel_ring_emit(ring, MI_NOOP); intel_ring_advance(ring); return 0; } @@ -1233,25 +1230,22 @@ static int blt_ring_begin(struct intel_ring_buffer *ring, } static int blt_ring_flush(struct intel_ring_buffer *ring, - u32 invalidate, u32 flush) + u32 invalidate_domains, + u32 flush_domains) { - uint32_t cmd; int ret; - if (((invalidate | flush) & I915_GEM_DOMAIN_RENDER) == 0) + if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) return 0; ret = blt_ring_begin(ring, 4); if (ret) return ret; - cmd = MI_FLUSH_DW; - if (invalidate & I915_GEM_DOMAIN_RENDER) - cmd |= MI_INVALIDATE_TLB; - intel_ring_emit(ring, cmd); + intel_ring_emit(ring, MI_FLUSH_DW); + intel_ring_emit(ring, 0); intel_ring_emit(ring, 0); intel_ring_emit(ring, 0); - intel_ring_emit(ring, MI_NOOP); intel_ring_advance(ring); return 0; } diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index 7c50cdce84f0..6a09c1413d60 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -46,7 +46,6 @@ SDVO_TV_MASK) #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) -#define IS_TMDS(c) (c->output_flag & SDVO_TMDS_MASK) #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) #define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK)) @@ -1360,8 +1359,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); } - } else - status = connector_status_disconnected; + } connector->display_info.raw_edid = NULL; kfree(edid); } @@ -1409,25 +1407,10 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) if ((intel_sdvo_connector->output_flag & response) == 0) ret = connector_status_disconnected; - else if (IS_TMDS(intel_sdvo_connector)) + else if (response & SDVO_TMDS_MASK) ret = intel_sdvo_hdmi_sink_detect(connector); - else { - struct edid *edid; - - /* if we have an edid check it matches the connection */ - edid = intel_sdvo_get_edid(connector); - if (edid == NULL) - edid = intel_sdvo_get_analog_edid(connector); - if (edid != NULL) { - if (edid->input & DRM_EDID_INPUT_DIGITAL) - ret = connector_status_disconnected; - else - ret = connector_status_connected; - connector->display_info.raw_edid = NULL; - kfree(edid); - } else - ret = connector_status_connected; - } + else + ret = connector_status_connected; /* May update encoder flag for like clock for SDVO TV, etc.*/ if (ret == connector_status_connected) { @@ -1463,15 +1446,10 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) edid = intel_sdvo_get_analog_edid(connector); if (edid != NULL) { - struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); - bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); - bool connector_is_digital = !!IS_TMDS(intel_sdvo_connector); - - if (connector_is_digital == monitor_is_digital) { + if (edid->input & DRM_EDID_INPUT_DIGITAL) { drm_mode_connector_update_edid_property(connector, edid); drm_add_edid_modes(connector, edid); } - connector->display_info.raw_edid = NULL; kfree(edid); } @@ -1690,22 +1668,6 @@ static void intel_sdvo_destroy(struct drm_connector *connector) kfree(connector); } -static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector) -{ - struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); - struct edid *edid; - bool has_audio = false; - - if (!intel_sdvo->is_hdmi) - return false; - - edid = intel_sdvo_get_edid(connector); - if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL) - has_audio = drm_detect_monitor_audio(edid); - - return has_audio; -} - static int intel_sdvo_set_property(struct drm_connector *connector, struct drm_property *property, @@ -1722,23 +1684,17 @@ intel_sdvo_set_property(struct drm_connector *connector, return ret; if (property == intel_sdvo_connector->force_audio_property) { - int i = val; - bool has_audio; - - if (i == intel_sdvo_connector->force_audio) + if (val == intel_sdvo_connector->force_audio) return 0; - intel_sdvo_connector->force_audio = i; + intel_sdvo_connector->force_audio = val; - if (i == 0) - has_audio = intel_sdvo_detect_hdmi_audio(connector); - else - has_audio = i > 0; - - if (has_audio == intel_sdvo->has_hdmi_audio) + if (val > 0 && intel_sdvo->has_hdmi_audio) + return 0; + if (val < 0 && !intel_sdvo->has_hdmi_audio) return 0; - intel_sdvo->has_hdmi_audio = has_audio; + intel_sdvo->has_hdmi_audio = val > 0; goto done; } diff --git a/trunk/drivers/gpu/drm/i915/intel_tv.c b/trunk/drivers/gpu/drm/i915/intel_tv.c index fe4a53a50b83..93206e4eaa6f 100644 --- a/trunk/drivers/gpu/drm/i915/intel_tv.c +++ b/trunk/drivers/gpu/drm/i915/intel_tv.c @@ -1234,8 +1234,7 @@ static const struct drm_display_mode reported_modes[] = { * \return false if TV is disconnected. */ static int -intel_tv_detect_type (struct intel_tv *intel_tv, - struct drm_connector *connector) +intel_tv_detect_type (struct intel_tv *intel_tv) { struct drm_encoder *encoder = &intel_tv->base.base; struct drm_device *dev = encoder->dev; @@ -1246,13 +1245,11 @@ intel_tv_detect_type (struct intel_tv *intel_tv, int type; /* Disable TV interrupts around load detect or we'll recurse */ - if (connector->polled & DRM_CONNECTOR_POLL_HPD) { - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - i915_disable_pipestat(dev_priv, 0, - PIPE_HOTPLUG_INTERRUPT_ENABLE | - PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); - } + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + i915_disable_pipestat(dev_priv, 0, + PIPE_HOTPLUG_INTERRUPT_ENABLE | + PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); save_tv_dac = tv_dac = I915_READ(TV_DAC); save_tv_ctl = tv_ctl = I915_READ(TV_CTL); @@ -1305,13 +1302,11 @@ intel_tv_detect_type (struct intel_tv *intel_tv, I915_WRITE(TV_CTL, save_tv_ctl); /* Restore interrupt config */ - if (connector->polled & DRM_CONNECTOR_POLL_HPD) { - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - i915_enable_pipestat(dev_priv, 0, - PIPE_HOTPLUG_INTERRUPT_ENABLE | - PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); - } + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + i915_enable_pipestat(dev_priv, 0, + PIPE_HOTPLUG_INTERRUPT_ENABLE | + PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); return type; } @@ -1361,7 +1356,7 @@ intel_tv_detect(struct drm_connector *connector, bool force) drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); if (intel_tv->base.base.crtc && intel_tv->base.base.crtc->enabled) { - type = intel_tv_detect_type(intel_tv, connector); + type = intel_tv_detect_type(intel_tv); } else if (force) { struct drm_crtc *crtc; int dpms_mode; @@ -1369,7 +1364,7 @@ intel_tv_detect(struct drm_connector *connector, bool force) crtc = intel_get_load_detect_pipe(&intel_tv->base, connector, &mode, &dpms_mode); if (crtc) { - type = intel_tv_detect_type(intel_tv, connector); + type = intel_tv_detect_type(intel_tv); intel_release_load_detect_pipe(&intel_tv->base, connector, dpms_mode); } else @@ -1663,18 +1658,6 @@ intel_tv_init(struct drm_device *dev) intel_encoder = &intel_tv->base; connector = &intel_connector->base; - /* The documentation, for the older chipsets at least, recommend - * using a polling method rather than hotplug detection for TVs. - * This is because in order to perform the hotplug detection, the PLLs - * for the TV must be kept alive increasing power drain and starving - * bandwidth from other encoders. Notably for instance, it causes - * pipe underruns on Crestline when this encoder is supposedly idle. - * - * More recent chipsets favour HDMI rather than integrated S-Video. - */ - connector->polled = - DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; - drm_connector_init(dev, connector, &intel_tv_connector_funcs, DRM_MODE_CONNECTOR_SVIDEO); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c index 6bdab891c64e..49e5e99917e2 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -6228,7 +6228,7 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb, entry->tvconf.has_component_output = false; break; case OUTPUT_LVDS: - if ((conn & 0x00003f00) >> 8 != 0x10) + if ((conn & 0x00003f00) != 0x10) entry->lvdsconf.use_straps_for_mode = true; entry->lvdsconf.use_power_scripts = true; break; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c b/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c index d38a4d9f9b0b..a7fae26f4654 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -128,7 +128,6 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, } } - nvbo->bo.mem.num_pages = size >> PAGE_SHIFT; nouveau_bo_placement_set(nvbo, flags, 0); nvbo->channel = chan; @@ -167,17 +166,17 @@ static void set_placement_range(struct nouveau_bo *nvbo, uint32_t type) { struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); - int vram_pages = dev_priv->vram_size >> PAGE_SHIFT; if (dev_priv->card_type == NV_10 && - nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) && - nvbo->bo.mem.num_pages < vram_pages / 2) { + nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM)) { /* * Make sure that the color and depth buffers are handled * by independent memory controller units. Up to a 9x * speed up when alpha-blending and depth-test are enabled * at the same time. */ + int vram_pages = dev_priv->vram_size >> PAGE_SHIFT; + if (nvbo->tile_flags & NOUVEAU_GEM_TILE_ZETA) { nvbo->placement.fpfn = vram_pages / 2; nvbo->placement.lpfn = ~0; @@ -786,7 +785,7 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, if (ret) goto out; - ret = ttm_bo_move_ttm(bo, true, no_wait_reserve, no_wait_gpu, new_mem); + ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, new_mem); out: ttm_bo_mem_put(bo, &tmp_mem); return ret; @@ -812,11 +811,11 @@ nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, if (ret) return ret; - ret = ttm_bo_move_ttm(bo, true, no_wait_reserve, no_wait_gpu, &tmp_mem); + ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, &tmp_mem); if (ret) goto out; - ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait_reserve, no_wait_gpu, new_mem); + ret = nouveau_bo_move_m2mf(bo, evict, intr, no_wait_reserve, no_wait_gpu, new_mem); if (ret) goto out; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c index 390d82c3c4b0..a21e00076839 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -507,7 +507,6 @@ nouveau_connector_native_mode(struct drm_connector *connector) int high_w = 0, high_h = 0, high_v = 0; list_for_each_entry(mode, &nv_connector->base.probed_modes, head) { - mode->vrefresh = drm_mode_vrefresh(mode); if (helper->mode_valid(connector, mode) != MODE_OK || (mode->flags & DRM_MODE_FLAG_INTERLACE)) continue; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c index 4399e2f34db4..f05c0cddfeca 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c @@ -543,7 +543,7 @@ nouveau_pm_resume(struct drm_device *dev) struct nouveau_pm_engine *pm = &dev_priv->engine.pm; struct nouveau_pm_level *perflvl; - if (!pm->cur || pm->cur == &pm->boot) + if (pm->cur == &pm->boot) return; perflvl = pm->cur; diff --git a/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c b/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c index c82db37d9f41..ef23550407b5 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/trunk/drivers/gpu/drm/nouveau/nv04_dfp.c @@ -342,8 +342,8 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder, if (nv_encoder->dcb->type == OUTPUT_LVDS) { bool duallink, dummy; - nouveau_bios_parse_lvds_table(dev, output_mode->clock, - &duallink, &dummy); + nouveau_bios_parse_lvds_table(dev, nv_connector->native_mode-> + clock, &duallink, &dummy); if (duallink) regp->fp_control |= (8 << 28); } else @@ -518,6 +518,8 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) return; if (nv_encoder->dcb->lvdsconf.use_power_scripts) { + struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder); + /* when removing an output, crtc may not be set, but PANEL_OFF * must still be run */ @@ -525,8 +527,12 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) nv04_dfp_get_bound_head(dev, nv_encoder->dcb); if (mode == DRM_MODE_DPMS_ON) { + if (!nv_connector->native_mode) { + NV_ERROR(dev, "Not turning on LVDS without native mode\n"); + return; + } call_lvds_script(dev, nv_encoder->dcb, head, - LVDS_PANEL_ON, nv_encoder->mode.clock); + LVDS_PANEL_ON, nv_connector->native_mode->clock); } else /* pxclk of 0 is fine for PANEL_OFF, and for a * disconnected LVDS encoder there is no native_mode diff --git a/trunk/drivers/gpu/drm/nouveau/nv40_graph.c b/trunk/drivers/gpu/drm/nouveau/nv40_graph.c index 18d30c2c1aa6..8870d72388c8 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/trunk/drivers/gpu/drm/nouveau/nv40_graph.c @@ -211,32 +211,18 @@ nv40_graph_set_tile_region(struct drm_device *dev, int i) struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; switch (dev_priv->chipset) { - case 0x40: - case 0x41: /* guess */ - case 0x42: - case 0x43: - case 0x45: /* guess */ - case 0x4e: - nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); - nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); - nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr); - nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tile->pitch); - nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tile->limit); - nv_wr32(dev, NV40_PGRAPH_TILE1(i), tile->addr); - break; case 0x44: case 0x4a: + case 0x4e: nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr); break; + case 0x46: case 0x47: case 0x49: case 0x4b: - case 0x4c: - case 0x67: - default: nv_wr32(dev, NV47_PGRAPH_TSIZE(i), tile->pitch); nv_wr32(dev, NV47_PGRAPH_TLIMIT(i), tile->limit); nv_wr32(dev, NV47_PGRAPH_TILE(i), tile->addr); @@ -244,6 +230,15 @@ nv40_graph_set_tile_region(struct drm_device *dev, int i) nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tile->limit); nv_wr32(dev, NV40_PGRAPH_TILE1(i), tile->addr); break; + + default: + nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); + nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); + nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr); + nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tile->pitch); + nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tile->limit); + nv_wr32(dev, NV40_PGRAPH_TILE1(i), tile->addr); + break; } } @@ -401,20 +396,17 @@ nv40_graph_init(struct drm_device *dev) break; default: switch (dev_priv->chipset) { - case 0x41: - case 0x42: - case 0x43: - case 0x45: - case 0x4e: - case 0x44: - case 0x4a: - nv_wr32(dev, 0x4009F0, nv_rd32(dev, NV04_PFB_CFG0)); - nv_wr32(dev, 0x4009F4, nv_rd32(dev, NV04_PFB_CFG1)); - break; - default: + case 0x46: + case 0x47: + case 0x49: + case 0x4b: nv_wr32(dev, 0x400DF0, nv_rd32(dev, NV04_PFB_CFG0)); nv_wr32(dev, 0x400DF4, nv_rd32(dev, NV04_PFB_CFG1)); break; + default: + nv_wr32(dev, 0x4009F0, nv_rd32(dev, NV04_PFB_CFG0)); + nv_wr32(dev, 0x4009F4, nv_rd32(dev, NV04_PFB_CFG1)); + break; } nv_wr32(dev, 0x4069F0, nv_rd32(dev, NV04_PFB_CFG0)); nv_wr32(dev, 0x4069F4, nv_rd32(dev, NV04_PFB_CFG1)); diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c index a4e5e53e0a62..b1537000a104 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c @@ -48,29 +48,29 @@ static void atombios_overscan_setup(struct drm_crtc *crtc, switch (radeon_crtc->rmx_type) { case RMX_CENTER: - args.usOverscanTop = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2); - args.usOverscanBottom = cpu_to_le16((adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2); - args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2); - args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2); + args.usOverscanTop = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; + args.usOverscanBottom = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; + args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; + args.usOverscanRight = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; break; case RMX_ASPECT: a1 = mode->crtc_vdisplay * adjusted_mode->crtc_hdisplay; a2 = adjusted_mode->crtc_vdisplay * mode->crtc_hdisplay; if (a1 > a2) { - args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2); - args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2); + args.usOverscanLeft = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2; + args.usOverscanRight = (adjusted_mode->crtc_hdisplay - (a2 / mode->crtc_vdisplay)) / 2; } else if (a2 > a1) { - args.usOverscanLeft = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2); - args.usOverscanRight = cpu_to_le16((adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2); + args.usOverscanLeft = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; + args.usOverscanRight = (adjusted_mode->crtc_vdisplay - (a1 / mode->crtc_hdisplay)) / 2; } break; case RMX_FULL: default: - args.usOverscanRight = cpu_to_le16(radeon_crtc->h_border); - args.usOverscanLeft = cpu_to_le16(radeon_crtc->h_border); - args.usOverscanBottom = cpu_to_le16(radeon_crtc->v_border); - args.usOverscanTop = cpu_to_le16(radeon_crtc->v_border); + args.usOverscanRight = radeon_crtc->h_border; + args.usOverscanLeft = radeon_crtc->h_border; + args.usOverscanBottom = radeon_crtc->v_border; + args.usOverscanTop = radeon_crtc->v_border; break; } atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); @@ -419,23 +419,23 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc, memset(&args, 0, sizeof(args)); if (ASIC_IS_DCE5(rdev)) { - args.v3.usSpreadSpectrumAmountFrac = cpu_to_le16(0); + args.v3.usSpreadSpectrumAmountFrac = 0; args.v3.ucSpreadSpectrumType = ss->type; switch (pll_id) { case ATOM_PPLL1: args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL; - args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); - args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step); + args.v3.usSpreadSpectrumAmount = ss->amount; + args.v3.usSpreadSpectrumStep = ss->step; break; case ATOM_PPLL2: args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P2PLL; - args.v3.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); - args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step); + args.v3.usSpreadSpectrumAmount = ss->amount; + args.v3.usSpreadSpectrumStep = ss->step; break; case ATOM_DCPLL: args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_DCPLL; - args.v3.usSpreadSpectrumAmount = cpu_to_le16(0); - args.v3.usSpreadSpectrumStep = cpu_to_le16(0); + args.v3.usSpreadSpectrumAmount = 0; + args.v3.usSpreadSpectrumStep = 0; break; case ATOM_PPLL_INVALID: return; @@ -447,18 +447,18 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc, switch (pll_id) { case ATOM_PPLL1: args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P1PLL; - args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); - args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step); + args.v2.usSpreadSpectrumAmount = ss->amount; + args.v2.usSpreadSpectrumStep = ss->step; break; case ATOM_PPLL2: args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P2PLL; - args.v2.usSpreadSpectrumAmount = cpu_to_le16(ss->amount); - args.v2.usSpreadSpectrumStep = cpu_to_le16(ss->step); + args.v2.usSpreadSpectrumAmount = ss->amount; + args.v2.usSpreadSpectrumStep = ss->step; break; case ATOM_DCPLL: args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_DCPLL; - args.v2.usSpreadSpectrumAmount = cpu_to_le16(0); - args.v2.usSpreadSpectrumStep = cpu_to_le16(0); + args.v2.usSpreadSpectrumAmount = 0; + args.v2.usSpreadSpectrumStep = 0; break; case ATOM_PPLL_INVALID: return; @@ -538,6 +538,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; else pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; + } list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { @@ -554,28 +555,29 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, dp_clock = dig_connector->dp_clock; } } - +/* this might work properly with the new pll algo */ +#if 0 /* doesn't work properly on some laptops */ /* use recommended ref_div for ss */ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { if (ss_enabled) { if (ss->refdiv) { - pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; pll->flags |= RADEON_PLL_USE_REF_DIV; pll->reference_div = ss->refdiv; - if (ASIC_IS_AVIVO(rdev)) - pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; } } } - +#endif if (ASIC_IS_AVIVO(rdev)) { /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) adjusted_clock = mode->clock * 2; if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; - if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) - pll->flags |= RADEON_PLL_IS_LCD; + /* rv515 needs more testing with this option */ + if (rdev->family != CHIP_RV515) { + if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) + pll->flags |= RADEON_PLL_IS_LCD; + } } else { if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; @@ -662,12 +664,10 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, index, (uint32_t *)&args); adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10; if (args.v3.sOutput.ucRefDiv) { - pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; pll->flags |= RADEON_PLL_USE_REF_DIV; pll->reference_div = args.v3.sOutput.ucRefDiv; } if (args.v3.sOutput.ucPostDiv) { - pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; pll->flags |= RADEON_PLL_USE_POST_DIV; pll->post_div = args.v3.sOutput.ucPostDiv; } @@ -721,14 +721,14 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc, * SetPixelClock provides the dividers */ args.v5.ucCRTC = ATOM_CRTC_INVALID; - args.v5.usPixelClock = cpu_to_le16(dispclk); + args.v5.usPixelClock = dispclk; args.v5.ucPpll = ATOM_DCPLL; break; case 6: /* if the default dcpll clock is specified, * SetPixelClock provides the dividers */ - args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk); + args.v6.ulDispEngClkFreq = dispclk; args.v6.ucPpll = ATOM_DCPLL; break; default: @@ -957,7 +957,11 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode /* adjust pixel clock as needed */ adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss); - if (ASIC_IS_AVIVO(rdev)) + /* rv515 seems happier with the old algo */ + if (rdev->family == CHIP_RV515) + radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, + &ref_div, &post_div); + else if (ASIC_IS_AVIVO(rdev)) radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, &ref_div, &post_div); else @@ -991,9 +995,9 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode } } -static int dce4_crtc_do_set_base(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y, int atomic) +static int evergreen_crtc_do_set_base(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int x, int y, int atomic) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; @@ -1133,6 +1137,12 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset, (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); + if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) + WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, + EVERGREEN_INTERLEAVE_EN); + else + WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); + if (!atomic && fb && fb != crtc->fb) { radeon_fb = to_radeon_framebuffer(fb); rbo = radeon_fb->obj->driver_private; @@ -1290,6 +1300,12 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); + if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) + WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, + AVIVO_D1MODE_INTERLEAVE_EN); + else + WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); + if (!atomic && fb && fb != crtc->fb) { radeon_fb = to_radeon_framebuffer(fb); rbo = radeon_fb->obj->driver_private; @@ -1313,7 +1329,7 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, struct radeon_device *rdev = dev->dev_private; if (ASIC_IS_DCE4(rdev)) - return dce4_crtc_do_set_base(crtc, old_fb, x, y, 0); + return evergreen_crtc_do_set_base(crtc, old_fb, x, y, 0); else if (ASIC_IS_AVIVO(rdev)) return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0); else @@ -1328,7 +1344,7 @@ int atombios_crtc_set_base_atomic(struct drm_crtc *crtc, struct radeon_device *rdev = dev->dev_private; if (ASIC_IS_DCE4(rdev)) - return dce4_crtc_do_set_base(crtc, fb, x, y, 1); + return evergreen_crtc_do_set_base(crtc, fb, x, y, 1); else if (ASIC_IS_AVIVO(rdev)) return avivo_crtc_do_set_base(crtc, fb, x, y, 1); else diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index d270b3ff896b..ffdc8332b76e 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -1192,11 +1192,7 @@ void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) radeon_ring_write(rdev, 1); /* FIXME: implement */ radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); - radeon_ring_write(rdev, -#ifdef __BIG_ENDIAN - (2 << 0) | -#endif - (ib->gpu_addr & 0xFFFFFFFC)); + radeon_ring_write(rdev, ib->gpu_addr & 0xFFFFFFFC); radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF); radeon_ring_write(rdev, ib->length_dw); } @@ -1211,11 +1207,7 @@ static int evergreen_cp_load_microcode(struct radeon_device *rdev) return -EINVAL; r700_cp_stop(rdev); - WREG32(CP_RB_CNTL, -#ifdef __BIG_ENDIAN - BUF_SWAP_32BIT | -#endif - RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); + WREG32(CP_RB_CNTL, RB_NO_UPDATE | (15 << 8) | (3 << 0)); fw_data = (const __be32 *)rdev->pfp_fw->data; WREG32(CP_PFP_UCODE_ADDR, 0); @@ -1334,11 +1326,7 @@ int evergreen_cp_resume(struct radeon_device *rdev) WREG32(CP_RB_WPTR, 0); /* set the wb address wether it's enabled or not */ - WREG32(CP_RB_RPTR_ADDR, -#ifdef __BIG_ENDIAN - RB_RPTR_SWAP(2) | -#endif - ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); + WREG32(CP_RB_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); @@ -2639,8 +2627,8 @@ int evergreen_irq_process(struct radeon_device *rdev) while (rptr != wptr) { /* wptr/rptr are in bytes! */ ring_index = rptr / 4; - src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; - src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; + src_id = rdev->ih.ring[ring_index] & 0xff; + src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff; switch (src_id) { case 1: /* D1 vblank/vline */ diff --git a/trunk/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/trunk/drivers/gpu/drm/radeon/evergreen_blit_kms.c index 2adfb03f479b..a1ba4b3053d0 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen_blit_kms.c @@ -55,7 +55,7 @@ set_render_target(struct radeon_device *rdev, int format, if (h < 8) h = 8; - cb_color_info = ((format << 2) | (1 << 24) | (1 << 8)); + cb_color_info = ((format << 2) | (1 << 24)); pitch = (w / 8) - 1; slice = ((w * h) / 64) - 1; @@ -133,9 +133,6 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) /* high addr, stride */ sq_vtx_constant_word2 = ((upper_32_bits(gpu_addr) & 0xff) | (16 << 8)); -#ifdef __BIG_ENDIAN - sq_vtx_constant_word2 |= (2 << 30); -#endif /* xyzw swizzles */ sq_vtx_constant_word3 = (0 << 3) | (1 << 6) | (2 << 9) | (3 << 12); @@ -176,7 +173,7 @@ set_tex_resource(struct radeon_device *rdev, sq_tex_resource_word0 = (1 << 0); /* 2D */ sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 6) | ((w - 1) << 18)); - sq_tex_resource_word1 = ((h - 1) << 0) | (1 << 28); + sq_tex_resource_word1 = ((h - 1) << 0); /* xyzw swizzles */ sq_tex_resource_word4 = (0 << 16) | (1 << 19) | (2 << 22) | (3 << 25); @@ -224,11 +221,7 @@ draw_auto(struct radeon_device *rdev) radeon_ring_write(rdev, DI_PT_RECTLIST); radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0)); - radeon_ring_write(rdev, -#ifdef __BIG_ENDIAN - (2 << 2) | -#endif - DI_INDEX_SIZE_16_BIT); + radeon_ring_write(rdev, DI_INDEX_SIZE_16_BIT); radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0)); radeon_ring_write(rdev, 1); @@ -548,7 +541,7 @@ static inline uint32_t i2f(uint32_t input) int evergreen_blit_init(struct radeon_device *rdev) { u32 obj_size; - int i, r, dwords; + int r, dwords; void *ptr; u32 packet2s[16]; int num_packet2s = 0; @@ -564,7 +557,7 @@ int evergreen_blit_init(struct radeon_device *rdev) dwords = rdev->r600_blit.state_len; while (dwords & 0xf) { - packet2s[num_packet2s++] = cpu_to_le32(PACKET2(0)); + packet2s[num_packet2s++] = PACKET2(0); dwords++; } @@ -605,10 +598,8 @@ int evergreen_blit_init(struct radeon_device *rdev) if (num_packet2s) memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), packet2s, num_packet2s * 4); - for (i = 0; i < evergreen_vs_size; i++) - *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(evergreen_vs[i]); - for (i = 0; i < evergreen_ps_size; i++) - *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(evergreen_ps[i]); + memcpy(ptr + rdev->r600_blit.vs_offset, evergreen_vs, evergreen_vs_size * 4); + memcpy(ptr + rdev->r600_blit.ps_offset, evergreen_ps, evergreen_ps_size * 4); radeon_bo_kunmap(rdev->r600_blit.shader_obj); radeon_bo_unreserve(rdev->r600_blit.shader_obj); diff --git a/trunk/drivers/gpu/drm/radeon/evergreen_blit_shaders.c b/trunk/drivers/gpu/drm/radeon/evergreen_blit_shaders.c index 3a10399e0066..ef1d28c07fbf 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen_blit_shaders.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen_blit_shaders.c @@ -311,19 +311,11 @@ const u32 evergreen_vs[] = 0x00000000, 0x3c000000, 0x67961001, -#ifdef __BIG_ENDIAN - 0x000a0000, -#else 0x00080000, -#endif 0x00000000, 0x1c000000, 0x67961000, -#ifdef __BIG_ENDIAN - 0x00020008, -#else 0x00000008, -#endif 0x00000000, }; diff --git a/trunk/drivers/gpu/drm/radeon/evergreend.h b/trunk/drivers/gpu/drm/radeon/evergreend.h index eb4acf4528ff..afec1aca2a73 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreend.h +++ b/trunk/drivers/gpu/drm/radeon/evergreend.h @@ -98,7 +98,6 @@ #define BUF_SWAP_32BIT (2 << 16) #define CP_RB_RPTR 0x8700 #define CP_RB_RPTR_ADDR 0xC10C -#define RB_RPTR_SWAP(x) ((x) << 0) #define CP_RB_RPTR_ADDR_HI 0xC110 #define CP_RB_RPTR_WR 0xC108 #define CP_RB_WPTR 0xC114 diff --git a/trunk/drivers/gpu/drm/radeon/mkregtable.c b/trunk/drivers/gpu/drm/radeon/mkregtable.c index 5a82b6b75849..607241c6a8a9 100644 --- a/trunk/drivers/gpu/drm/radeon/mkregtable.c +++ b/trunk/drivers/gpu/drm/radeon/mkregtable.c @@ -673,10 +673,8 @@ static int parser_auth(struct table *t, const char *filename) last_reg = strtol(last_reg_s, NULL, 16); do { - if (fgets(buf, 1024, file) == NULL) { - fclose(file); + if (fgets(buf, 1024, file) == NULL) return -1; - } len = strlen(buf); if (ftell(file) == end) done = 1; @@ -687,7 +685,6 @@ static int parser_auth(struct table *t, const char *filename) fprintf(stderr, "Error matching regular expression %d in %s\n", r, filename); - fclose(file); return -1; } else { buf[match[0].rm_eo] = 0; diff --git a/trunk/drivers/gpu/drm/radeon/r100.c b/trunk/drivers/gpu/drm/radeon/r100.c index 56deae5bf02e..5f15820efe12 100644 --- a/trunk/drivers/gpu/drm/radeon/r100.c +++ b/trunk/drivers/gpu/drm/radeon/r100.c @@ -1427,7 +1427,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p, } track->zb.robj = reloc->robj; track->zb.offset = idx_value; - track->zb_dirty = true; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); break; case RADEON_RB3D_COLOROFFSET: @@ -1440,7 +1439,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p, } track->cb[0].robj = reloc->robj; track->cb[0].offset = idx_value; - track->cb_dirty = true; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); break; case RADEON_PP_TXOFFSET_0: @@ -1456,7 +1454,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p, } ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); track->textures[i].robj = reloc->robj; - track->tex_dirty = true; break; case RADEON_PP_CUBIC_OFFSET_T0_0: case RADEON_PP_CUBIC_OFFSET_T0_1: @@ -1474,7 +1471,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p, track->textures[0].cube_info[i].offset = idx_value; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); track->textures[0].cube_info[i].robj = reloc->robj; - track->tex_dirty = true; break; case RADEON_PP_CUBIC_OFFSET_T1_0: case RADEON_PP_CUBIC_OFFSET_T1_1: @@ -1492,7 +1488,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p, track->textures[1].cube_info[i].offset = idx_value; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); track->textures[1].cube_info[i].robj = reloc->robj; - track->tex_dirty = true; break; case RADEON_PP_CUBIC_OFFSET_T2_0: case RADEON_PP_CUBIC_OFFSET_T2_1: @@ -1510,12 +1505,9 @@ static int r100_packet0_check(struct radeon_cs_parser *p, track->textures[2].cube_info[i].offset = idx_value; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); track->textures[2].cube_info[i].robj = reloc->robj; - track->tex_dirty = true; break; case RADEON_RE_WIDTH_HEIGHT: track->maxy = ((idx_value >> 16) & 0x7FF); - track->cb_dirty = true; - track->zb_dirty = true; break; case RADEON_RB3D_COLORPITCH: r = r100_cs_packet_next_reloc(p, &reloc); @@ -1536,11 +1528,9 @@ static int r100_packet0_check(struct radeon_cs_parser *p, ib[idx] = tmp; track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; - track->cb_dirty = true; break; case RADEON_RB3D_DEPTHPITCH: track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; - track->zb_dirty = true; break; case RADEON_RB3D_CNTL: switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { @@ -1565,8 +1555,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p, return -EINVAL; } track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); - track->cb_dirty = true; - track->zb_dirty = true; break; case RADEON_RB3D_ZSTENCILCNTL: switch (idx_value & 0xf) { @@ -1584,7 +1572,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p, default: break; } - track->zb_dirty = true; break; case RADEON_RB3D_ZPASS_ADDR: r = r100_cs_packet_next_reloc(p, &reloc); @@ -1601,7 +1588,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p, uint32_t temp = idx_value >> 4; for (i = 0; i < track->num_texture; i++) track->textures[i].enabled = !!(temp & (1 << i)); - track->tex_dirty = true; } break; case RADEON_SE_VF_CNTL: @@ -1616,14 +1602,12 @@ static int r100_packet0_check(struct radeon_cs_parser *p, i = (reg - RADEON_PP_TEX_SIZE_0) / 8; track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; - track->tex_dirty = true; break; case RADEON_PP_TEX_PITCH_0: case RADEON_PP_TEX_PITCH_1: case RADEON_PP_TEX_PITCH_2: i = (reg - RADEON_PP_TEX_PITCH_0) / 8; track->textures[i].pitch = idx_value + 32; - track->tex_dirty = true; break; case RADEON_PP_TXFILTER_0: case RADEON_PP_TXFILTER_1: @@ -1637,7 +1621,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p, tmp = (idx_value >> 27) & 0x7; if (tmp == 2 || tmp == 6) track->textures[i].roundup_h = false; - track->tex_dirty = true; break; case RADEON_PP_TXFORMAT_0: case RADEON_PP_TXFORMAT_1: @@ -1690,7 +1673,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p, } track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); - track->tex_dirty = true; break; case RADEON_PP_CUBIC_FACES_0: case RADEON_PP_CUBIC_FACES_1: @@ -1701,7 +1683,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p, track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); } - track->tex_dirty = true; break; default: printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", @@ -3337,9 +3318,9 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) unsigned long size; unsigned prim_walk; unsigned nverts; - unsigned num_cb = track->cb_dirty ? track->num_cb : 0; + unsigned num_cb = track->num_cb; - if (num_cb && !track->zb_cb_clear && !track->color_channel_mask && + if (!track->zb_cb_clear && !track->color_channel_mask && !track->blend_read_enable) num_cb = 0; @@ -3360,9 +3341,7 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) return -EINVAL; } } - track->cb_dirty = false; - - if (track->zb_dirty && track->z_enabled) { + if (track->z_enabled) { if (track->zb.robj == NULL) { DRM_ERROR("[drm] No buffer for z buffer !\n"); return -EINVAL; @@ -3379,28 +3358,6 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) return -EINVAL; } } - track->zb_dirty = false; - - if (track->aa_dirty && track->aaresolve) { - if (track->aa.robj == NULL) { - DRM_ERROR("[drm] No buffer for AA resolve buffer %d !\n", i); - return -EINVAL; - } - /* I believe the format comes from colorbuffer0. */ - size = track->aa.pitch * track->cb[0].cpp * track->maxy; - size += track->aa.offset; - if (size > radeon_bo_size(track->aa.robj)) { - DRM_ERROR("[drm] Buffer too small for AA resolve buffer %d " - "(need %lu have %lu) !\n", i, size, - radeon_bo_size(track->aa.robj)); - DRM_ERROR("[drm] AA resolve buffer %d (%u %u %u %u)\n", - i, track->aa.pitch, track->cb[0].cpp, - track->aa.offset, track->maxy); - return -EINVAL; - } - } - track->aa_dirty = false; - prim_walk = (track->vap_vf_cntl >> 4) & 0x3; if (track->vap_vf_cntl & (1 << 14)) { nverts = track->vap_alt_nverts; @@ -3460,23 +3417,13 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) prim_walk); return -EINVAL; } - - if (track->tex_dirty) { - track->tex_dirty = false; - return r100_cs_track_texture_check(rdev, track); - } - return 0; + return r100_cs_track_texture_check(rdev, track); } void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track) { unsigned i, face; - track->cb_dirty = true; - track->zb_dirty = true; - track->tex_dirty = true; - track->aa_dirty = true; - if (rdev->family < CHIP_R300) { track->num_cb = 1; if (rdev->family <= CHIP_RS200) @@ -3490,8 +3437,6 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track track->num_texture = 16; track->maxy = 4096; track->separate_cube = 0; - track->aaresolve = true; - track->aa.robj = NULL; } for (i = 0; i < track->num_cb; i++) { diff --git a/trunk/drivers/gpu/drm/radeon/r100_track.h b/trunk/drivers/gpu/drm/radeon/r100_track.h index 2fef9de7f363..af65600e6564 100644 --- a/trunk/drivers/gpu/drm/radeon/r100_track.h +++ b/trunk/drivers/gpu/drm/radeon/r100_track.h @@ -52,7 +52,14 @@ struct r100_cs_track_texture { unsigned compress_format; }; +struct r100_cs_track_limits { + unsigned num_cb; + unsigned num_texture; + unsigned max_levels; +}; + struct r100_cs_track { + struct radeon_device *rdev; unsigned num_cb; unsigned num_texture; unsigned maxy; @@ -66,17 +73,11 @@ struct r100_cs_track { struct r100_cs_track_array arrays[11]; struct r100_cs_track_cb cb[R300_MAX_CB]; struct r100_cs_track_cb zb; - struct r100_cs_track_cb aa; struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE]; bool z_enabled; bool separate_cube; bool zb_cb_clear; bool blend_read_enable; - bool cb_dirty; - bool zb_dirty; - bool tex_dirty; - bool aa_dirty; - bool aaresolve; }; int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track); diff --git a/trunk/drivers/gpu/drm/radeon/r200.c b/trunk/drivers/gpu/drm/radeon/r200.c index f24058300413..d2408c395619 100644 --- a/trunk/drivers/gpu/drm/radeon/r200.c +++ b/trunk/drivers/gpu/drm/radeon/r200.c @@ -184,7 +184,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, } track->zb.robj = reloc->robj; track->zb.offset = idx_value; - track->zb_dirty = true; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); break; case RADEON_RB3D_COLOROFFSET: @@ -197,7 +196,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, } track->cb[0].robj = reloc->robj; track->cb[0].offset = idx_value; - track->cb_dirty = true; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); break; case R200_PP_TXOFFSET_0: @@ -216,7 +214,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, } ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); track->textures[i].robj = reloc->robj; - track->tex_dirty = true; break; case R200_PP_CUBIC_OFFSET_F1_0: case R200_PP_CUBIC_OFFSET_F2_0: @@ -260,12 +257,9 @@ int r200_packet0_check(struct radeon_cs_parser *p, track->textures[i].cube_info[face - 1].offset = idx_value; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); track->textures[i].cube_info[face - 1].robj = reloc->robj; - track->tex_dirty = true; break; case RADEON_RE_WIDTH_HEIGHT: track->maxy = ((idx_value >> 16) & 0x7FF); - track->cb_dirty = true; - track->zb_dirty = true; break; case RADEON_RB3D_COLORPITCH: r = r100_cs_packet_next_reloc(p, &reloc); @@ -286,11 +280,9 @@ int r200_packet0_check(struct radeon_cs_parser *p, ib[idx] = tmp; track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; - track->cb_dirty = true; break; case RADEON_RB3D_DEPTHPITCH: track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; - track->zb_dirty = true; break; case RADEON_RB3D_CNTL: switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { @@ -320,8 +312,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, } track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); - track->cb_dirty = true; - track->zb_dirty = true; break; case RADEON_RB3D_ZSTENCILCNTL: switch (idx_value & 0xf) { @@ -339,7 +329,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, default: break; } - track->zb_dirty = true; break; case RADEON_RB3D_ZPASS_ADDR: r = r100_cs_packet_next_reloc(p, &reloc); @@ -356,7 +345,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, uint32_t temp = idx_value >> 4; for (i = 0; i < track->num_texture; i++) track->textures[i].enabled = !!(temp & (1 << i)); - track->tex_dirty = true; } break; case RADEON_SE_VF_CNTL: @@ -381,7 +369,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, i = (reg - R200_PP_TXSIZE_0) / 32; track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; - track->tex_dirty = true; break; case R200_PP_TXPITCH_0: case R200_PP_TXPITCH_1: @@ -391,7 +378,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, case R200_PP_TXPITCH_5: i = (reg - R200_PP_TXPITCH_0) / 32; track->textures[i].pitch = idx_value + 32; - track->tex_dirty = true; break; case R200_PP_TXFILTER_0: case R200_PP_TXFILTER_1: @@ -408,7 +394,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, tmp = (idx_value >> 27) & 0x7; if (tmp == 2 || tmp == 6) track->textures[i].roundup_h = false; - track->tex_dirty = true; break; case R200_PP_TXMULTI_CTL_0: case R200_PP_TXMULTI_CTL_1: @@ -447,7 +432,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, track->textures[i].tex_coord_type = 1; break; } - track->tex_dirty = true; break; case R200_PP_TXFORMAT_0: case R200_PP_TXFORMAT_1: @@ -504,7 +488,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, } track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); - track->tex_dirty = true; break; case R200_PP_CUBIC_FACES_0: case R200_PP_CUBIC_FACES_1: @@ -518,7 +501,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); } - track->tex_dirty = true; break; default: printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", diff --git a/trunk/drivers/gpu/drm/radeon/r300.c b/trunk/drivers/gpu/drm/radeon/r300.c index 069efa8c8ecf..55fe5ba7def3 100644 --- a/trunk/drivers/gpu/drm/radeon/r300.c +++ b/trunk/drivers/gpu/drm/radeon/r300.c @@ -667,7 +667,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, } track->cb[i].robj = reloc->robj; track->cb[i].offset = idx_value; - track->cb_dirty = true; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); break; case R300_ZB_DEPTHOFFSET: @@ -680,7 +679,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, } track->zb.robj = reloc->robj; track->zb.offset = idx_value; - track->zb_dirty = true; ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); break; case R300_TX_OFFSET_0: @@ -719,7 +717,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, tmp |= tile_flags; ib[idx] = tmp; track->textures[i].robj = reloc->robj; - track->tex_dirty = true; break; /* Tracked registers */ case 0x2084: @@ -746,8 +743,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, if (p->rdev->family < CHIP_RV515) { track->maxy -= 1440; } - track->cb_dirty = true; - track->zb_dirty = true; break; case 0x4E00: /* RB3D_CCTL */ @@ -757,7 +752,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, return -EINVAL; } track->num_cb = ((idx_value >> 5) & 0x3) + 1; - track->cb_dirty = true; break; case 0x4E38: case 0x4E3C: @@ -820,7 +814,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, ((idx_value >> 21) & 0xF)); return -EINVAL; } - track->cb_dirty = true; break; case 0x4F00: /* ZB_CNTL */ @@ -829,7 +822,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, } else { track->z_enabled = false; } - track->zb_dirty = true; break; case 0x4F10: /* ZB_FORMAT */ @@ -846,7 +838,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, (idx_value & 0xF)); return -EINVAL; } - track->zb_dirty = true; break; case 0x4F24: /* ZB_DEPTHPITCH */ @@ -870,17 +861,14 @@ static int r300_packet0_check(struct radeon_cs_parser *p, ib[idx] = tmp; track->zb.pitch = idx_value & 0x3FFC; - track->zb_dirty = true; break; case 0x4104: - /* TX_ENABLE */ for (i = 0; i < 16; i++) { bool enabled; enabled = !!(idx_value & (1 << i)); track->textures[i].enabled = enabled; } - track->tex_dirty = true; break; case 0x44C0: case 0x44C4: @@ -910,7 +898,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, track->textures[i].compress_format = R100_TRACK_COMP_NONE; break; case R300_TX_FORMAT_X16: - case R300_TX_FORMAT_FL_I16: case R300_TX_FORMAT_Y8X8: case R300_TX_FORMAT_Z5Y6X5: case R300_TX_FORMAT_Z6Y5X5: @@ -923,7 +910,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, track->textures[i].compress_format = R100_TRACK_COMP_NONE; break; case R300_TX_FORMAT_Y16X16: - case R300_TX_FORMAT_FL_I16A16: case R300_TX_FORMAT_Z11Y11X10: case R300_TX_FORMAT_Z10Y11X11: case R300_TX_FORMAT_W8Z8Y8X8: @@ -965,8 +951,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p, DRM_ERROR("Invalid texture format %u\n", (idx_value & 0x1F)); return -EINVAL; + break; } - track->tex_dirty = true; break; case 0x4400: case 0x4404: @@ -994,7 +980,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, if (tmp == 2 || tmp == 4 || tmp == 6) { track->textures[i].roundup_h = false; } - track->tex_dirty = true; break; case 0x4500: case 0x4504: @@ -1032,7 +1017,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, DRM_ERROR("Forbidden bit TXFORMAT_MSB\n"); return -EINVAL; } - track->tex_dirty = true; break; case 0x4480: case 0x4484: @@ -1062,7 +1046,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, track->textures[i].use_pitch = !!tmp; tmp = (idx_value >> 22) & 0xF; track->textures[i].txdepth = tmp; - track->tex_dirty = true; break; case R300_ZB_ZPASS_ADDR: r = r100_cs_packet_next_reloc(p, &reloc); @@ -1077,7 +1060,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, case 0x4e0c: /* RB3D_COLOR_CHANNEL_MASK */ track->color_channel_mask = idx_value; - track->cb_dirty = true; break; case 0x43a4: /* SC_HYPERZ_EN */ @@ -1091,8 +1073,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, case 0x4f1c: /* ZB_BW_CNTL */ track->zb_cb_clear = !!(idx_value & (1 << 5)); - track->cb_dirty = true; - track->zb_dirty = true; if (p->rdev->hyperz_filp != p->filp) { if (idx_value & (R300_HIZ_ENABLE | R300_RD_COMP_ENABLE | @@ -1104,28 +1084,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p, case 0x4e04: /* RB3D_BLENDCNTL */ track->blend_read_enable = !!(idx_value & (1 << 2)); - track->cb_dirty = true; - break; - case R300_RB3D_AARESOLVE_OFFSET: - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } - track->aa.robj = reloc->robj; - track->aa.offset = idx_value; - track->aa_dirty = true; - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); - break; - case R300_RB3D_AARESOLVE_PITCH: - track->aa.pitch = idx_value & 0x3FFE; - track->aa_dirty = true; break; - case R300_RB3D_AARESOLVE_CTL: - track->aaresolve = idx_value & 0x1; - track->aa_dirty = true; + case 0x4f28: /* ZB_DEPTHCLEARVALUE */ break; case 0x4f30: /* ZB_MASK_OFFSET */ case 0x4f34: /* ZB_ZMASK_PITCH */ diff --git a/trunk/drivers/gpu/drm/radeon/r300_reg.h b/trunk/drivers/gpu/drm/radeon/r300_reg.h index f0bce399c9f3..1a0d5362cd79 100644 --- a/trunk/drivers/gpu/drm/radeon/r300_reg.h +++ b/trunk/drivers/gpu/drm/radeon/r300_reg.h @@ -1371,8 +1371,6 @@ #define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */ #define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */ -#define R300_RB3D_AARESOLVE_OFFSET 0x4E80 -#define R300_RB3D_AARESOLVE_PITCH 0x4E84 #define R300_RB3D_AARESOLVE_CTL 0x4E88 /* gap */ diff --git a/trunk/drivers/gpu/drm/radeon/r600.c b/trunk/drivers/gpu/drm/radeon/r600.c index de88624d5f87..650672a0f5ad 100644 --- a/trunk/drivers/gpu/drm/radeon/r600.c +++ b/trunk/drivers/gpu/drm/radeon/r600.c @@ -2105,11 +2105,7 @@ static int r600_cp_load_microcode(struct radeon_device *rdev) r600_cp_stop(rdev); - WREG32(CP_RB_CNTL, -#ifdef __BIG_ENDIAN - BUF_SWAP_32BIT | -#endif - RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); + WREG32(CP_RB_CNTL, RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); /* Reset cp */ WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); @@ -2196,11 +2192,7 @@ int r600_cp_resume(struct radeon_device *rdev) WREG32(CP_RB_WPTR, 0); /* set the wb address whether it's enabled or not */ - WREG32(CP_RB_RPTR_ADDR, -#ifdef __BIG_ENDIAN - RB_RPTR_SWAP(2) | -#endif - ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); + WREG32(CP_RB_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); @@ -2636,11 +2628,7 @@ void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) { /* FIXME: implement */ radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); - radeon_ring_write(rdev, -#ifdef __BIG_ENDIAN - (2 << 0) | -#endif - (ib->gpu_addr & 0xFFFFFFFC)); + radeon_ring_write(rdev, ib->gpu_addr & 0xFFFFFFFC); radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF); radeon_ring_write(rdev, ib->length_dw); } @@ -3309,8 +3297,8 @@ int r600_irq_process(struct radeon_device *rdev) while (rptr != wptr) { /* wptr/rptr are in bytes! */ ring_index = rptr / 4; - src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; - src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; + src_id = rdev->ih.ring[ring_index] & 0xff; + src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff; switch (src_id) { case 1: /* D1 vblank/vline */ diff --git a/trunk/drivers/gpu/drm/radeon/r600_blit.c b/trunk/drivers/gpu/drm/radeon/r600_blit.c index 7f1043448d25..ca5c29f70779 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_blit.c +++ b/trunk/drivers/gpu/drm/radeon/r600_blit.c @@ -137,9 +137,9 @@ set_shaders(struct drm_device *dev) ps = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset + 256); for (i = 0; i < r6xx_vs_size; i++) - vs[i] = cpu_to_le32(r6xx_vs[i]); + vs[i] = r6xx_vs[i]; for (i = 0; i < r6xx_ps_size; i++) - ps[i] = cpu_to_le32(r6xx_ps[i]); + ps[i] = r6xx_ps[i]; dev_priv->blit_vb->used = 512; @@ -192,9 +192,6 @@ set_vtx_resource(drm_radeon_private_t *dev_priv, u64 gpu_addr) DRM_DEBUG("\n"); sq_vtx_constant_word2 = (((gpu_addr >> 32) & 0xff) | (16 << 8)); -#ifdef __BIG_ENDIAN - sq_vtx_constant_word2 |= (2 << 30); -#endif BEGIN_RING(9); OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); @@ -294,11 +291,7 @@ draw_auto(drm_radeon_private_t *dev_priv) OUT_RING(DI_PT_RECTLIST); OUT_RING(CP_PACKET3(R600_IT_INDEX_TYPE, 0)); -#ifdef __BIG_ENDIAN - OUT_RING((2 << 2) | DI_INDEX_SIZE_16_BIT); -#else OUT_RING(DI_INDEX_SIZE_16_BIT); -#endif OUT_RING(CP_PACKET3(R600_IT_NUM_INSTANCES, 0)); OUT_RING(1); diff --git a/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c b/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c index 41f7aafc97c4..86e5aa07f0db 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -54,7 +54,7 @@ set_render_target(struct radeon_device *rdev, int format, if (h < 8) h = 8; - cb_color_info = ((format << 2) | (1 << 27) | (1 << 8)); + cb_color_info = ((format << 2) | (1 << 27)); pitch = (w / 8) - 1; slice = ((w * h) / 64) - 1; @@ -165,9 +165,6 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) u32 sq_vtx_constant_word2; sq_vtx_constant_word2 = ((upper_32_bits(gpu_addr) & 0xff) | (16 << 8)); -#ifdef __BIG_ENDIAN - sq_vtx_constant_word2 |= (2 << 30); -#endif radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7)); radeon_ring_write(rdev, 0x460); @@ -202,7 +199,7 @@ set_tex_resource(struct radeon_device *rdev, if (h < 1) h = 1; - sq_tex_resource_word0 = (1 << 0) | (1 << 3); + sq_tex_resource_word0 = (1 << 0); sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) | ((w - 1) << 19)); @@ -256,11 +253,7 @@ draw_auto(struct radeon_device *rdev) radeon_ring_write(rdev, DI_PT_RECTLIST); radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0)); - radeon_ring_write(rdev, -#ifdef __BIG_ENDIAN - (2 << 2) | -#endif - DI_INDEX_SIZE_16_BIT); + radeon_ring_write(rdev, DI_INDEX_SIZE_16_BIT); radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0)); radeon_ring_write(rdev, 1); @@ -431,11 +424,7 @@ set_default_state(struct radeon_device *rdev) dwords = ALIGN(rdev->r600_blit.state_len, 0x10); gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset; radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); - radeon_ring_write(rdev, -#ifdef __BIG_ENDIAN - (2 << 0) | -#endif - (gpu_addr & 0xFFFFFFFC)); + radeon_ring_write(rdev, gpu_addr & 0xFFFFFFFC); radeon_ring_write(rdev, upper_32_bits(gpu_addr) & 0xFF); radeon_ring_write(rdev, dwords); @@ -478,7 +467,7 @@ static inline uint32_t i2f(uint32_t input) int r600_blit_init(struct radeon_device *rdev) { u32 obj_size; - int i, r, dwords; + int r, dwords; void *ptr; u32 packet2s[16]; int num_packet2s = 0; @@ -497,7 +486,7 @@ int r600_blit_init(struct radeon_device *rdev) dwords = rdev->r600_blit.state_len; while (dwords & 0xf) { - packet2s[num_packet2s++] = cpu_to_le32(PACKET2(0)); + packet2s[num_packet2s++] = PACKET2(0); dwords++; } @@ -540,10 +529,8 @@ int r600_blit_init(struct radeon_device *rdev) if (num_packet2s) memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4), packet2s, num_packet2s * 4); - for (i = 0; i < r6xx_vs_size; i++) - *(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(r6xx_vs[i]); - for (i = 0; i < r6xx_ps_size; i++) - *(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(r6xx_ps[i]); + memcpy(ptr + rdev->r600_blit.vs_offset, r6xx_vs, r6xx_vs_size * 4); + memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4); radeon_bo_kunmap(rdev->r600_blit.shader_obj); radeon_bo_unreserve(rdev->r600_blit.shader_obj); diff --git a/trunk/drivers/gpu/drm/radeon/r600_blit_shaders.c b/trunk/drivers/gpu/drm/radeon/r600_blit_shaders.c index 2d1f6c5ee2a7..e8151c1d55b2 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/trunk/drivers/gpu/drm/radeon/r600_blit_shaders.c @@ -684,11 +684,7 @@ const u32 r6xx_vs[] = 0x00000000, 0x3c000000, 0x68cd1000, -#ifdef __BIG_ENDIAN - 0x000a0000, -#else 0x00080000, -#endif 0x00000000, }; diff --git a/trunk/drivers/gpu/drm/radeon/r600_cp.c b/trunk/drivers/gpu/drm/radeon/r600_cp.c index c3ab959bdc7c..4f4cd8b286d5 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_cp.c +++ b/trunk/drivers/gpu/drm/radeon/r600_cp.c @@ -396,9 +396,6 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) r600_do_cp_stop(dev_priv); RADEON_WRITE(R600_CP_RB_CNTL, -#ifdef __BIG_ENDIAN - R600_BUF_SWAP_32BIT | -#endif R600_RB_NO_UPDATE | R600_RB_BLKSZ(15) | R600_RB_BUFSZ(3)); @@ -489,12 +486,9 @@ static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv) r600_do_cp_stop(dev_priv); RADEON_WRITE(R600_CP_RB_CNTL, -#ifdef __BIG_ENDIAN - R600_BUF_SWAP_32BIT | -#endif R600_RB_NO_UPDATE | - R600_RB_BLKSZ(15) | - R600_RB_BUFSZ(3)); + (15 << 8) | + (3 << 0)); RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); RADEON_READ(R600_GRBM_SOFT_RESET); @@ -556,12 +550,8 @@ static void r600_test_writeback(drm_radeon_private_t *dev_priv) if (!dev_priv->writeback_works) { /* Disable writeback to avoid unnecessary bus master transfer */ - RADEON_WRITE(R600_CP_RB_CNTL, -#ifdef __BIG_ENDIAN - R600_BUF_SWAP_32BIT | -#endif - RADEON_READ(R600_CP_RB_CNTL) | - R600_RB_NO_UPDATE); + RADEON_WRITE(R600_CP_RB_CNTL, RADEON_READ(R600_CP_RB_CNTL) | + RADEON_RB_NO_UPDATE); RADEON_WRITE(R600_SCRATCH_UMSK, 0); } } @@ -585,11 +575,7 @@ int r600_do_engine_reset(struct drm_device *dev) RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); cp_rb_cntl = RADEON_READ(R600_CP_RB_CNTL); - RADEON_WRITE(R600_CP_RB_CNTL, -#ifdef __BIG_ENDIAN - R600_BUF_SWAP_32BIT | -#endif - R600_RB_RPTR_WR_ENA); + RADEON_WRITE(R600_CP_RB_CNTL, R600_RB_RPTR_WR_ENA); RADEON_WRITE(R600_CP_RB_RPTR_WR, cp_ptr); RADEON_WRITE(R600_CP_RB_WPTR, cp_ptr); @@ -1852,10 +1838,7 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, + dev_priv->gart_vm_start; } RADEON_WRITE(R600_CP_RB_RPTR_ADDR, -#ifdef __BIG_ENDIAN - (2 << 0) | -#endif - (rptr_addr & 0xfffffffc)); + rptr_addr & 0xffffffff); RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, upper_32_bits(rptr_addr)); @@ -1906,7 +1889,7 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, { u64 scratch_addr; - scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR) & 0xFFFFFFFC; + scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR); scratch_addr |= ((u64)RADEON_READ(R600_CP_RB_RPTR_ADDR_HI)) << 32; scratch_addr += R600_SCRATCH_REG_OFFSET; scratch_addr >>= 8; diff --git a/trunk/drivers/gpu/drm/radeon/r600_cs.c b/trunk/drivers/gpu/drm/radeon/r600_cs.c index 153095fba62f..7831e0890210 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_cs.c +++ b/trunk/drivers/gpu/drm/radeon/r600_cs.c @@ -295,18 +295,17 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) } if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d cb pitch (%d, 0x%x, %d) invalid\n", - __func__, __LINE__, pitch, pitch_align, array_mode); + dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", + __func__, __LINE__, pitch); return -EINVAL; } if (!IS_ALIGNED(height, height_align)) { - dev_warn(p->dev, "%s:%d cb height (%d, 0x%x, %d) invalid\n", - __func__, __LINE__, height, height_align, array_mode); + dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", + __func__, __LINE__, height); return -EINVAL; } if (!IS_ALIGNED(base_offset, base_align)) { - dev_warn(p->dev, "%s offset[%d] 0x%llx 0x%llx, %d not aligned\n", __func__, i, - base_offset, base_align, array_mode); + dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset); return -EINVAL; } @@ -321,10 +320,7 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) * broken userspace. */ } else { - dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big\n", __func__, i, - array_mode, - track->cb_color_bo_offset[i], tmp, - radeon_bo_size(track->cb_color_bo[i])); + dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i])); return -EINVAL; } } @@ -459,18 +455,17 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) } if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d db pitch (%d, 0x%x, %d) invalid\n", - __func__, __LINE__, pitch, pitch_align, array_mode); + dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", + __func__, __LINE__, pitch); return -EINVAL; } if (!IS_ALIGNED(height, height_align)) { - dev_warn(p->dev, "%s:%d db height (%d, 0x%x, %d) invalid\n", - __func__, __LINE__, height, height_align, array_mode); + dev_warn(p->dev, "%s:%d db height (%d) invalid\n", + __func__, __LINE__, height); return -EINVAL; } if (!IS_ALIGNED(base_offset, base_align)) { - dev_warn(p->dev, "%s offset[%d] 0x%llx, 0x%llx, %d not aligned\n", __func__, i, - base_offset, base_align, array_mode); + dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset); return -EINVAL; } @@ -478,10 +473,9 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; tmp = ntiles * bpe * 64 * nviews; if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { - dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n", - array_mode, - track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset, - radeon_bo_size(track->db_bo)); + dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %u have %lu)\n", + track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset, + radeon_bo_size(track->db_bo)); return -EINVAL; } } @@ -1233,18 +1227,18 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i /* XXX check height as well... */ if (!IS_ALIGNED(pitch, pitch_align)) { - dev_warn(p->dev, "%s:%d tex pitch (%d, 0x%x, %d) invalid\n", - __func__, __LINE__, pitch, pitch_align, G_038000_TILE_MODE(word0)); + dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", + __func__, __LINE__, pitch); return -EINVAL; } if (!IS_ALIGNED(base_offset, base_align)) { - dev_warn(p->dev, "%s:%d tex base offset (0x%llx, 0x%llx, %d) invalid\n", - __func__, __LINE__, base_offset, base_align, G_038000_TILE_MODE(word0)); + dev_warn(p->dev, "%s:%d tex base offset (0x%llx) invalid\n", + __func__, __LINE__, base_offset); return -EINVAL; } if (!IS_ALIGNED(mip_offset, base_align)) { - dev_warn(p->dev, "%s:%d tex mip offset (0x%llx, 0x%llx, %d) invalid\n", - __func__, __LINE__, mip_offset, base_align, G_038000_TILE_MODE(word0)); + dev_warn(p->dev, "%s:%d tex mip offset (0x%llx) invalid\n", + __func__, __LINE__, mip_offset); return -EINVAL; } diff --git a/trunk/drivers/gpu/drm/radeon/r600d.h b/trunk/drivers/gpu/drm/radeon/r600d.h index 04bac0bbd3ec..a5d898b4bad2 100644 --- a/trunk/drivers/gpu/drm/radeon/r600d.h +++ b/trunk/drivers/gpu/drm/radeon/r600d.h @@ -154,14 +154,13 @@ #define ROQ_IB2_START(x) ((x) << 8) #define CP_RB_BASE 0xC100 #define CP_RB_CNTL 0xC104 -#define RB_BUFSZ(x) ((x) << 0) -#define RB_BLKSZ(x) ((x) << 8) -#define RB_NO_UPDATE (1 << 27) -#define RB_RPTR_WR_ENA (1 << 31) +#define RB_BUFSZ(x) ((x)<<0) +#define RB_BLKSZ(x) ((x)<<8) +#define RB_NO_UPDATE (1<<27) +#define RB_RPTR_WR_ENA (1<<31) #define BUF_SWAP_32BIT (2 << 16) #define CP_RB_RPTR 0x8700 #define CP_RB_RPTR_ADDR 0xC10C -#define RB_RPTR_SWAP(x) ((x) << 0) #define CP_RB_RPTR_ADDR_HI 0xC110 #define CP_RB_RPTR_WR 0xC108 #define CP_RB_WPTR 0xC114 diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c index 02d5c415f499..5c1cc7ad9a15 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c @@ -88,7 +88,7 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev /* some evergreen boards have bad data for this entry */ if (ASIC_IS_DCE4(rdev)) { if ((i == 7) && - (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && + (gpio->usClkMaskRegisterIndex == 0x1936) && (gpio->sucI2cId.ucAccess == 0)) { gpio->sucI2cId.ucAccess = 0x97; gpio->ucDataMaskShift = 8; @@ -101,7 +101,7 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev /* some DCE3 boards have bad data for this entry */ if (ASIC_IS_DCE3(rdev)) { if ((i == 4) && - (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && + (gpio->usClkMaskRegisterIndex == 0x1fda) && (gpio->sucI2cId.ucAccess == 0x94)) gpio->sucI2cId.ucAccess = 0x14; } @@ -172,7 +172,7 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) /* some evergreen boards have bad data for this entry */ if (ASIC_IS_DCE4(rdev)) { if ((i == 7) && - (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && + (gpio->usClkMaskRegisterIndex == 0x1936) && (gpio->sucI2cId.ucAccess == 0)) { gpio->sucI2cId.ucAccess = 0x97; gpio->ucDataMaskShift = 8; @@ -185,7 +185,7 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) /* some DCE3 boards have bad data for this entry */ if (ASIC_IS_DCE3(rdev)) { if ((i == 4) && - (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && + (gpio->usClkMaskRegisterIndex == 0x1fda) && (gpio->sucI2cId.ucAccess == 0x94)) gpio->sucI2cId.ucAccess = 0x14; } @@ -252,7 +252,7 @@ static inline struct radeon_gpio_rec radeon_lookup_gpio(struct radeon_device *rd pin = &gpio_info->asGPIO_Pin[i]; if (id == pin->ucGPIO_ID) { gpio.id = pin->ucGPIO_ID; - gpio.reg = le16_to_cpu(pin->usGpioPin_AIndex) * 4; + gpio.reg = pin->usGpioPin_AIndex * 4; gpio.mask = (1 << pin->ucGpioPinBitShift); gpio.valid = true; break; @@ -1274,11 +1274,11 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev) data_offset); switch (crev) { case 1: - if (le32_to_cpu(igp_info->info.ulBootUpMemoryClock)) + if (igp_info->info.ulBootUpMemoryClock) return true; break; case 2: - if (le32_to_cpu(igp_info->info_2.ulBootUpSidePortClock)) + if (igp_info->info_2.ulBootUpSidePortClock) return true; break; default: @@ -1442,7 +1442,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, for (i = 0; i < num_indices; i++) { if ((ss_info->info.asSpreadSpectrum[i].ucClockIndication == id) && - (clock <= le32_to_cpu(ss_info->info.asSpreadSpectrum[i].ulTargetClockRange))) { + (clock <= ss_info->info.asSpreadSpectrum[i].ulTargetClockRange)) { ss->percentage = le16_to_cpu(ss_info->info.asSpreadSpectrum[i].usSpreadSpectrumPercentage); ss->type = ss_info->info.asSpreadSpectrum[i].ucSpreadSpectrumMode; @@ -1456,7 +1456,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, sizeof(ATOM_ASIC_SS_ASSIGNMENT_V2); for (i = 0; i < num_indices; i++) { if ((ss_info->info_2.asSpreadSpectrum[i].ucClockIndication == id) && - (clock <= le32_to_cpu(ss_info->info_2.asSpreadSpectrum[i].ulTargetClockRange))) { + (clock <= ss_info->info_2.asSpreadSpectrum[i].ulTargetClockRange)) { ss->percentage = le16_to_cpu(ss_info->info_2.asSpreadSpectrum[i].usSpreadSpectrumPercentage); ss->type = ss_info->info_2.asSpreadSpectrum[i].ucSpreadSpectrumMode; @@ -1470,7 +1470,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3); for (i = 0; i < num_indices; i++) { if ((ss_info->info_3.asSpreadSpectrum[i].ucClockIndication == id) && - (clock <= le32_to_cpu(ss_info->info_3.asSpreadSpectrum[i].ulTargetClockRange))) { + (clock <= ss_info->info_3.asSpreadSpectrum[i].ulTargetClockRange)) { ss->percentage = le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadSpectrumPercentage); ss->type = ss_info->info_3.asSpreadSpectrum[i].ucSpreadSpectrumMode; @@ -1553,8 +1553,8 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct if (misc & ATOM_DOUBLE_CLOCK_MODE) lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN; - lvds->native_mode.width_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageHSize); - lvds->native_mode.height_mm = le16_to_cpu(lvds_info->info.sLCDTiming.usImageVSize); + lvds->native_mode.width_mm = lvds_info->info.sLCDTiming.usImageHSize; + lvds->native_mode.height_mm = lvds_info->info.sLCDTiming.usImageVSize; /* set crtc values */ drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); @@ -1569,13 +1569,13 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct lvds->linkb = false; /* parse the lcd record table */ - if (le16_to_cpu(lvds_info->info.usModePatchTableOffset)) { + if (lvds_info->info.usModePatchTableOffset) { ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record; ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record; bool bad_record = false; u8 *record = (u8 *)(mode_info->atom_context->bios + data_offset + - le16_to_cpu(lvds_info->info.usModePatchTableOffset)); + lvds_info->info.usModePatchTableOffset); while (*record != ATOM_RECORD_END_TYPE) { switch (*record) { case LCD_MODE_PATCH_RECORD_MODE_TYPE: @@ -2189,7 +2189,7 @@ static u16 radeon_atombios_get_default_vddc(struct radeon_device *rdev) firmware_info = (union firmware_info *)(mode_info->atom_context->bios + data_offset); - vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage); + vddc = firmware_info->info_14.usBootUpVDDCVoltage; } return vddc; @@ -2284,7 +2284,7 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = VOLTAGE_SW; rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = - le16_to_cpu(clock_info->evergreen.usVDDC); + clock_info->evergreen.usVDDC; } else { sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); sclk |= clock_info->r600.ucEngineClockHigh << 16; @@ -2295,7 +2295,7 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = VOLTAGE_SW; rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = - le16_to_cpu(clock_info->r600.usVDDC); + clock_info->r600.usVDDC; } if (rdev->flags & RADEON_IS_IGP) { @@ -2408,13 +2408,13 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); state_array = (struct StateArray *) (mode_info->atom_context->bios + data_offset + - le16_to_cpu(power_info->pplib.usStateArrayOffset)); + power_info->pplib.usStateArrayOffset); clock_info_array = (struct ClockInfoArray *) (mode_info->atom_context->bios + data_offset + - le16_to_cpu(power_info->pplib.usClockInfoArrayOffset)); + power_info->pplib.usClockInfoArrayOffset); non_clock_info_array = (struct NonClockInfoArray *) (mode_info->atom_context->bios + data_offset + - le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); + power_info->pplib.usNonClockInfoArrayOffset); rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * state_array->ucNumEntries, GFP_KERNEL); if (!rdev->pm.power_state) @@ -2533,7 +2533,7 @@ uint32_t radeon_atom_get_engine_clock(struct radeon_device *rdev) int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock); atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - return le32_to_cpu(args.ulReturnEngineClock); + return args.ulReturnEngineClock; } uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev) @@ -2542,7 +2542,7 @@ uint32_t radeon_atom_get_memory_clock(struct radeon_device *rdev) int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock); atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); - return le32_to_cpu(args.ulReturnMemoryClock); + return args.ulReturnMemoryClock; } void radeon_atom_set_engine_clock(struct radeon_device *rdev, @@ -2551,7 +2551,7 @@ void radeon_atom_set_engine_clock(struct radeon_device *rdev, SET_ENGINE_CLOCK_PS_ALLOCATION args; int index = GetIndexIntoMasterTable(COMMAND, SetEngineClock); - args.ulTargetEngineClock = cpu_to_le32(eng_clock); /* 10 khz */ + args.ulTargetEngineClock = eng_clock; /* 10 khz */ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } @@ -2565,7 +2565,7 @@ void radeon_atom_set_memory_clock(struct radeon_device *rdev, if (rdev->flags & RADEON_IS_IGP) return; - args.ulTargetMemoryClock = cpu_to_le32(mem_clock); /* 10 khz */ + args.ulTargetMemoryClock = mem_clock; /* 10 khz */ atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_combios.c b/trunk/drivers/gpu/drm/radeon/radeon_combios.c index cf7c8d5b4ec2..d27ef74590cd 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_combios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_combios.c @@ -1504,11 +1504,6 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) (rdev->pdev->subsystem_device == 0x4a48)) { /* Mac X800 */ rdev->mode_info.connector_table = CT_MAC_X800; - } else if ((rdev->pdev->device == 0x4150) && - (rdev->pdev->subsystem_vendor == 0x1002) && - (rdev->pdev->subsystem_device == 0x4150)) { - /* Mac G5 9600 */ - rdev->mode_info.connector_table = CT_MAC_G5_9600; } else #endif /* CONFIG_PPC_PMAC */ #ifdef CONFIG_PPC64 @@ -2027,48 +2022,6 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, &hpd); break; - case CT_MAC_G5_9600: - DRM_INFO("Connector Table: %d (mac g5 9600)\n", - rdev->mode_info.connector_table); - /* DVI - tv dac, dvo */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); - hpd.hpd = RADEON_HPD_1; /* ??? */ - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_DFP2_SUPPORT, - 0), - ATOM_DEVICE_DFP2_SUPPORT); - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT2_SUPPORT, - 2), - ATOM_DEVICE_CRT2_SUPPORT); - radeon_add_legacy_connector(dev, 0, - ATOM_DEVICE_DFP2_SUPPORT | - ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_DVII, &ddc_i2c, - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, - &hpd); - /* ADC - primary dac, internal tmds */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); - hpd.hpd = RADEON_HPD_2; /* ??? */ - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_DFP1_SUPPORT, - 0), - ATOM_DEVICE_DFP1_SUPPORT); - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - radeon_add_legacy_connector(dev, 1, - ATOM_DEVICE_DFP1_SUPPORT | - ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_DVII, &ddc_i2c, - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, - &hpd); - break; default: DRM_INFO("Connector table: %d (invalid)\n", rdev->mode_info.connector_table); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c index 4954e2d6ffa2..0d478932b1a9 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_device.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c @@ -936,11 +936,8 @@ int radeon_resume_kms(struct drm_device *dev) int radeon_gpu_reset(struct radeon_device *rdev) { int r; - int resched; radeon_save_bios_scratch_regs(rdev); - /* block TTM */ - resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); radeon_suspend(rdev); r = radeon_asic_reset(rdev); @@ -949,7 +946,6 @@ int radeon_gpu_reset(struct radeon_device *rdev) radeon_resume(rdev); radeon_restore_bios_scratch_regs(rdev); drm_helper_resume_force_mode(rdev->ddev); - ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); return 0; } /* bad news, how to tell it to userspace ? */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_display.c b/trunk/drivers/gpu/drm/radeon/radeon_display.c index 0e657095de7c..2eff98cfd728 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_display.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_display.c @@ -793,11 +793,6 @@ static void avivo_get_fb_div(struct radeon_pll *pll, tmp *= target_clock; *fb_div = tmp / pll->reference_freq; *frac_fb_div = tmp % pll->reference_freq; - - if (*fb_div > pll->max_feedback_div) - *fb_div = pll->max_feedback_div; - else if (*fb_div < pll->min_feedback_div) - *fb_div = pll->min_feedback_div; } static u32 avivo_get_post_div(struct radeon_pll *pll, @@ -831,11 +826,6 @@ static u32 avivo_get_post_div(struct radeon_pll *pll, post_div--; } - if (post_div > pll->max_post_div) - post_div = pll->max_post_div; - else if (post_div < pll->min_post_div) - post_div = pll->min_post_div; - return post_div; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.h b/trunk/drivers/gpu/drm/radeon/radeon_drv.h index 5cba46b9779a..448eba89d1e6 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.h @@ -1524,7 +1524,6 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); #define R600_CP_RB_CNTL 0xc104 # define R600_RB_BUFSZ(x) ((x) << 0) # define R600_RB_BLKSZ(x) ((x) << 8) -# define R600_BUF_SWAP_32BIT (2 << 16) # define R600_RB_NO_UPDATE (1 << 27) # define R600_RB_RPTR_WR_ENA (1 << 31) #define R600_CP_RB_RPTR_WR 0xc108 diff --git a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c index b4274883227f..d4a542247618 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_encoders.c @@ -910,7 +910,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t args.v1.ucAction = action; if (action == ATOM_TRANSMITTER_ACTION_INIT) { - args.v1.usInitInfo = cpu_to_le16(connector_object_id); + args.v1.usInitInfo = connector_object_id; } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { args.v1.asMode.ucLaneSel = lane_num; args.v1.asMode.ucLaneSet = lane_set; @@ -1140,7 +1140,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, case 3: args.v3.sExtEncoder.ucAction = action; if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) - args.v3.sExtEncoder.usConnectorId = cpu_to_le16(connector_object_id); + args.v3.sExtEncoder.usConnectorId = connector_object_id; else args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); @@ -1570,21 +1570,11 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder, } /* set scaler clears this on some chips */ - if (ASIC_IS_AVIVO(rdev) && - (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)))) { - if (ASIC_IS_DCE4(rdev)) { - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, - EVERGREEN_INTERLEAVE_EN); - else - WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); - } else { - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, - AVIVO_D1MODE_INTERLEAVE_EN); - else - WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); - } + /* XXX check DCE4 */ + if (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))) { + if (ASIC_IS_AVIVO(rdev) && (mode->flags & DRM_MODE_FLAG_INTERLACE)) + WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, + AVIVO_D1MODE_INTERLEAVE_EN); } } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_mode.h b/trunk/drivers/gpu/drm/radeon/radeon_mode.h index a670caaee29e..6794cdf91f28 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_mode.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_mode.h @@ -209,7 +209,6 @@ enum radeon_connector_table { CT_EMAC, CT_RN50_POWER, CT_MAC_X800, - CT_MAC_G5_9600, }; enum radeon_dvo_chip { diff --git a/trunk/drivers/gpu/drm/radeon/radeon_ttm.c b/trunk/drivers/gpu/drm/radeon/radeon_ttm.c index e5b2cf10cbf4..1272e4b6a1d4 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_ttm.c @@ -787,9 +787,9 @@ static int radeon_ttm_debugfs_init(struct radeon_device *rdev) radeon_mem_types_list[i].show = &radeon_mm_dump_table; radeon_mem_types_list[i].driver_features = 0; if (i == 0) - radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_VRAM].priv; + radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_VRAM].priv; else - radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_TT].priv; + radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_TT].priv; } /* Add ttm page pool to debugfs */ diff --git a/trunk/drivers/gpu/drm/radeon/reg_srcs/r300 b/trunk/drivers/gpu/drm/radeon/reg_srcs/r300 index e8a1786b6426..b506ec1cab4b 100644 --- a/trunk/drivers/gpu/drm/radeon/reg_srcs/r300 +++ b/trunk/drivers/gpu/drm/radeon/reg_srcs/r300 @@ -683,7 +683,9 @@ r300 0x4f60 0x4DF4 US_ALU_CONST_G_31 0x4DF8 US_ALU_CONST_B_31 0x4DFC US_ALU_CONST_A_31 +0x4E04 RB3D_BLENDCNTL_R3 0x4E08 RB3D_ABLENDCNTL_R3 +0x4E0C RB3D_COLOR_CHANNEL_MASK 0x4E10 RB3D_CONSTANT_COLOR 0x4E14 RB3D_COLOR_CLEAR_VALUE 0x4E18 RB3D_ROPCNTL_R3 @@ -704,11 +706,13 @@ r300 0x4f60 0x4E74 RB3D_CMASK_WRINDEX 0x4E78 RB3D_CMASK_DWORD 0x4E7C RB3D_CMASK_RDINDEX +0x4E80 RB3D_AARESOLVE_OFFSET +0x4E84 RB3D_AARESOLVE_PITCH +0x4E88 RB3D_AARESOLVE_CTL 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD 0x4F04 ZB_ZSTENCILCNTL 0x4F08 ZB_STENCILREFMASK 0x4F14 ZB_ZTOP 0x4F18 ZB_ZCACHE_CTLSTAT -0x4F28 ZB_DEPTHCLEARVALUE 0x4F58 ZB_ZPASS_DATA diff --git a/trunk/drivers/gpu/drm/radeon/reg_srcs/r420 b/trunk/drivers/gpu/drm/radeon/reg_srcs/r420 index 722074e21e2f..8c1214c2390f 100644 --- a/trunk/drivers/gpu/drm/radeon/reg_srcs/r420 +++ b/trunk/drivers/gpu/drm/radeon/reg_srcs/r420 @@ -130,6 +130,7 @@ r420 0x4f60 0x401C GB_SELECT 0x4020 GB_AA_CONFIG 0x4024 GB_FIFO_SIZE +0x4028 GB_Z_PEQ_CONFIG 0x4100 TX_INVALTAGS 0x4200 GA_POINT_S0 0x4204 GA_POINT_T0 @@ -749,7 +750,9 @@ r420 0x4f60 0x4DF4 US_ALU_CONST_G_31 0x4DF8 US_ALU_CONST_B_31 0x4DFC US_ALU_CONST_A_31 +0x4E04 RB3D_BLENDCNTL_R3 0x4E08 RB3D_ABLENDCNTL_R3 +0x4E0C RB3D_COLOR_CHANNEL_MASK 0x4E10 RB3D_CONSTANT_COLOR 0x4E14 RB3D_COLOR_CLEAR_VALUE 0x4E18 RB3D_ROPCNTL_R3 @@ -770,11 +773,13 @@ r420 0x4f60 0x4E74 RB3D_CMASK_WRINDEX 0x4E78 RB3D_CMASK_DWORD 0x4E7C RB3D_CMASK_RDINDEX +0x4E80 RB3D_AARESOLVE_OFFSET +0x4E84 RB3D_AARESOLVE_PITCH +0x4E88 RB3D_AARESOLVE_CTL 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD 0x4F04 ZB_ZSTENCILCNTL 0x4F08 ZB_STENCILREFMASK 0x4F14 ZB_ZTOP 0x4F18 ZB_ZCACHE_CTLSTAT -0x4F28 ZB_DEPTHCLEARVALUE 0x4F58 ZB_ZPASS_DATA diff --git a/trunk/drivers/gpu/drm/radeon/reg_srcs/rs600 b/trunk/drivers/gpu/drm/radeon/reg_srcs/rs600 index d9f62866bbc1..0828d80396f2 100644 --- a/trunk/drivers/gpu/drm/radeon/reg_srcs/rs600 +++ b/trunk/drivers/gpu/drm/radeon/reg_srcs/rs600 @@ -749,7 +749,9 @@ rs600 0x6d40 0x4DF4 US_ALU_CONST_G_31 0x4DF8 US_ALU_CONST_B_31 0x4DFC US_ALU_CONST_A_31 +0x4E04 RB3D_BLENDCNTL_R3 0x4E08 RB3D_ABLENDCNTL_R3 +0x4E0C RB3D_COLOR_CHANNEL_MASK 0x4E10 RB3D_CONSTANT_COLOR 0x4E14 RB3D_COLOR_CLEAR_VALUE 0x4E18 RB3D_ROPCNTL_R3 @@ -770,11 +772,13 @@ rs600 0x6d40 0x4E74 RB3D_CMASK_WRINDEX 0x4E78 RB3D_CMASK_DWORD 0x4E7C RB3D_CMASK_RDINDEX +0x4E80 RB3D_AARESOLVE_OFFSET +0x4E84 RB3D_AARESOLVE_PITCH +0x4E88 RB3D_AARESOLVE_CTL 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD 0x4F04 ZB_ZSTENCILCNTL 0x4F08 ZB_STENCILREFMASK 0x4F14 ZB_ZTOP 0x4F18 ZB_ZCACHE_CTLSTAT -0x4F28 ZB_DEPTHCLEARVALUE 0x4F58 ZB_ZPASS_DATA diff --git a/trunk/drivers/gpu/drm/radeon/reg_srcs/rv515 b/trunk/drivers/gpu/drm/radeon/reg_srcs/rv515 index 911a8fbd32bb..ef422bbacfc1 100644 --- a/trunk/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ b/trunk/drivers/gpu/drm/radeon/reg_srcs/rv515 @@ -164,6 +164,7 @@ rv515 0x6d40 0x401C GB_SELECT 0x4020 GB_AA_CONFIG 0x4024 GB_FIFO_SIZE +0x4028 GB_Z_PEQ_CONFIG 0x4100 TX_INVALTAGS 0x4114 SU_TEX_WRAP_PS3 0x4118 PS3_ENABLE @@ -460,7 +461,9 @@ rv515 0x6d40 0x4DF4 US_ALU_CONST_G_31 0x4DF8 US_ALU_CONST_B_31 0x4DFC US_ALU_CONST_A_31 +0x4E04 RB3D_BLENDCNTL_R3 0x4E08 RB3D_ABLENDCNTL_R3 +0x4E0C RB3D_COLOR_CHANNEL_MASK 0x4E10 RB3D_CONSTANT_COLOR 0x4E14 RB3D_COLOR_CLEAR_VALUE 0x4E18 RB3D_ROPCNTL_R3 @@ -481,6 +484,9 @@ rv515 0x6d40 0x4E74 RB3D_CMASK_WRINDEX 0x4E78 RB3D_CMASK_DWORD 0x4E7C RB3D_CMASK_RDINDEX +0x4E80 RB3D_AARESOLVE_OFFSET +0x4E84 RB3D_AARESOLVE_PITCH +0x4E88 RB3D_AARESOLVE_CTL 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD 0x4EF8 RB3D_CONSTANT_COLOR_AR @@ -490,5 +496,4 @@ rv515 0x6d40 0x4F14 ZB_ZTOP 0x4F18 ZB_ZCACHE_CTLSTAT 0x4F58 ZB_ZPASS_DATA -0x4F28 ZB_DEPTHCLEARVALUE 0x4FD4 ZB_STENCILREFMASK_BF diff --git a/trunk/drivers/gpu/drm/radeon/rs690.c b/trunk/drivers/gpu/drm/radeon/rs690.c index 6638c8e4c81b..0137d3e3728d 100644 --- a/trunk/drivers/gpu/drm/radeon/rs690.c +++ b/trunk/drivers/gpu/drm/radeon/rs690.c @@ -77,9 +77,9 @@ void rs690_pm_info(struct radeon_device *rdev) switch (crev) { case 1: tmp.full = dfixed_const(100); - rdev->pm.igp_sideport_mclk.full = dfixed_const(le32_to_cpu(info->info.ulBootUpMemoryClock)); + rdev->pm.igp_sideport_mclk.full = dfixed_const(info->info.ulBootUpMemoryClock); rdev->pm.igp_sideport_mclk.full = dfixed_div(rdev->pm.igp_sideport_mclk, tmp); - if (le16_to_cpu(info->info.usK8MemoryClock)) + if (info->info.usK8MemoryClock) rdev->pm.igp_system_mclk.full = dfixed_const(le16_to_cpu(info->info.usK8MemoryClock)); else if (rdev->clock.default_mclk) { rdev->pm.igp_system_mclk.full = dfixed_const(rdev->clock.default_mclk); @@ -91,16 +91,16 @@ void rs690_pm_info(struct radeon_device *rdev) break; case 2: tmp.full = dfixed_const(100); - rdev->pm.igp_sideport_mclk.full = dfixed_const(le32_to_cpu(info->info_v2.ulBootUpSidePortClock)); + rdev->pm.igp_sideport_mclk.full = dfixed_const(info->info_v2.ulBootUpSidePortClock); rdev->pm.igp_sideport_mclk.full = dfixed_div(rdev->pm.igp_sideport_mclk, tmp); - if (le32_to_cpu(info->info_v2.ulBootUpUMAClock)) - rdev->pm.igp_system_mclk.full = dfixed_const(le32_to_cpu(info->info_v2.ulBootUpUMAClock)); + if (info->info_v2.ulBootUpUMAClock) + rdev->pm.igp_system_mclk.full = dfixed_const(info->info_v2.ulBootUpUMAClock); else if (rdev->clock.default_mclk) rdev->pm.igp_system_mclk.full = dfixed_const(rdev->clock.default_mclk); else rdev->pm.igp_system_mclk.full = dfixed_const(66700); rdev->pm.igp_system_mclk.full = dfixed_div(rdev->pm.igp_system_mclk, tmp); - rdev->pm.igp_ht_link_clk.full = dfixed_const(le32_to_cpu(info->info_v2.ulHTLinkFreq)); + rdev->pm.igp_ht_link_clk.full = dfixed_const(info->info_v2.ulHTLinkFreq); rdev->pm.igp_ht_link_clk.full = dfixed_div(rdev->pm.igp_ht_link_clk, tmp); rdev->pm.igp_ht_link_width.full = dfixed_const(le16_to_cpu(info->info_v2.usMinHTLinkWidth)); break; diff --git a/trunk/drivers/gpu/drm/radeon/rv770.c b/trunk/drivers/gpu/drm/radeon/rv770.c index d8ba67690656..2211a323db41 100644 --- a/trunk/drivers/gpu/drm/radeon/rv770.c +++ b/trunk/drivers/gpu/drm/radeon/rv770.c @@ -321,11 +321,7 @@ static int rv770_cp_load_microcode(struct radeon_device *rdev) return -EINVAL; r700_cp_stop(rdev); - WREG32(CP_RB_CNTL, -#ifdef __BIG_ENDIAN - BUF_SWAP_32BIT | -#endif - RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); + WREG32(CP_RB_CNTL, RB_NO_UPDATE | (15 << 8) | (3 << 0)); /* Reset cp */ WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); diff --git a/trunk/drivers/gpu/drm/radeon/rv770d.h b/trunk/drivers/gpu/drm/radeon/rv770d.h index 79fa588e9ed5..abc8cf5a3672 100644 --- a/trunk/drivers/gpu/drm/radeon/rv770d.h +++ b/trunk/drivers/gpu/drm/radeon/rv770d.h @@ -76,10 +76,10 @@ #define ROQ_IB1_START(x) ((x) << 0) #define ROQ_IB2_START(x) ((x) << 8) #define CP_RB_CNTL 0xC104 -#define RB_BUFSZ(x) ((x) << 0) -#define RB_BLKSZ(x) ((x) << 8) -#define RB_NO_UPDATE (1 << 27) -#define RB_RPTR_WR_ENA (1 << 31) +#define RB_BUFSZ(x) ((x)<<0) +#define RB_BLKSZ(x) ((x)<<8) +#define RB_NO_UPDATE (1<<27) +#define RB_RPTR_WR_ENA (1<<31) #define BUF_SWAP_32BIT (2 << 16) #define CP_RB_RPTR 0x8700 #define CP_RB_RPTR_ADDR 0xC10C diff --git a/trunk/drivers/infiniband/hw/nes/nes_hw.c b/trunk/drivers/infiniband/hw/nes/nes_hw.c index 08c194861af5..8b606fd64022 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_hw.c +++ b/trunk/drivers/infiniband/hw/nes/nes_hw.c @@ -2610,11 +2610,9 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) netif_carrier_on(nesvnic->netdev); spin_lock(&nesvnic->port_ibevent_lock); - if (nesvnic->of_device_registered) { - if (nesdev->iw_status == 0) { - nesdev->iw_status = 1; - nes_port_ibevent(nesvnic); - } + if (nesdev->iw_status == 0) { + nesdev->iw_status = 1; + nes_port_ibevent(nesvnic); } spin_unlock(&nesvnic->port_ibevent_lock); } @@ -2644,11 +2642,9 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) netif_carrier_off(nesvnic->netdev); spin_lock(&nesvnic->port_ibevent_lock); - if (nesvnic->of_device_registered) { - if (nesdev->iw_status == 1) { - nesdev->iw_status = 0; - nes_port_ibevent(nesvnic); - } + if (nesdev->iw_status == 1) { + nesdev->iw_status = 0; + nes_port_ibevent(nesvnic); } spin_unlock(&nesvnic->port_ibevent_lock); } @@ -2707,11 +2703,9 @@ void nes_recheck_link_status(struct work_struct *work) netif_carrier_on(nesvnic->netdev); spin_lock(&nesvnic->port_ibevent_lock); - if (nesvnic->of_device_registered) { - if (nesdev->iw_status == 0) { - nesdev->iw_status = 1; - nes_port_ibevent(nesvnic); - } + if (nesdev->iw_status == 0) { + nesdev->iw_status = 1; + nes_port_ibevent(nesvnic); } spin_unlock(&nesvnic->port_ibevent_lock); } @@ -2729,11 +2723,9 @@ void nes_recheck_link_status(struct work_struct *work) netif_carrier_off(nesvnic->netdev); spin_lock(&nesvnic->port_ibevent_lock); - if (nesvnic->of_device_registered) { - if (nesdev->iw_status == 1) { - nesdev->iw_status = 0; - nes_port_ibevent(nesvnic); - } + if (nesdev->iw_status == 1) { + nesdev->iw_status = 0; + nes_port_ibevent(nesvnic); } spin_unlock(&nesvnic->port_ibevent_lock); } diff --git a/trunk/drivers/infiniband/hw/qib/qib_rc.c b/trunk/drivers/infiniband/hw/qib/qib_rc.c index eca0c41f1226..8245237b67ce 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_rc.c +++ b/trunk/drivers/infiniband/hw/qib/qib_rc.c @@ -1005,8 +1005,7 @@ void qib_rc_send_complete(struct qib_qp *qp, struct qib_ib_header *hdr) * there are still requests that haven't been acked. */ if ((psn & IB_BTH_REQ_ACK) && qp->s_acked != qp->s_tail && - !(qp->s_flags & (QIB_S_TIMER | QIB_S_WAIT_RNR | QIB_S_WAIT_PSN)) && - (ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) + !(qp->s_flags & (QIB_S_TIMER | QIB_S_WAIT_RNR | QIB_S_WAIT_PSN))) start_timer(qp); while (qp->s_last != qp->s_acked) { @@ -1440,8 +1439,6 @@ static void qib_rc_rcv_resp(struct qib_ibport *ibp, } spin_lock_irqsave(&qp->s_lock, flags); - if (!(ib_qib_state_ops[qp->state] & QIB_PROCESS_RECV_OK)) - goto ack_done; /* Ignore invalid responses. */ if (qib_cmp24(psn, qp->s_next_psn) >= 0) diff --git a/trunk/drivers/input/input.c b/trunk/drivers/input/input.c index 11905b6a3023..7985114beac7 100644 --- a/trunk/drivers/input/input.c +++ b/trunk/drivers/input/input.c @@ -75,6 +75,7 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz) * dev->event_lock held and interrupts disabled. */ static void input_pass_event(struct input_dev *dev, + struct input_handler *src_handler, unsigned int type, unsigned int code, int value) { struct input_handler *handler; @@ -93,6 +94,15 @@ static void input_pass_event(struct input_dev *dev, continue; handler = handle->handler; + + /* + * If this is the handler that injected this + * particular event we want to skip it to avoid + * filters firing again and again. + */ + if (handler == src_handler) + continue; + if (!handler->filter) { if (filtered) break; @@ -122,7 +132,7 @@ static void input_repeat_key(unsigned long data) if (test_bit(dev->repeat_key, dev->key) && is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) { - input_pass_event(dev, EV_KEY, dev->repeat_key, 2); + input_pass_event(dev, NULL, EV_KEY, dev->repeat_key, 2); if (dev->sync) { /* @@ -131,7 +141,7 @@ static void input_repeat_key(unsigned long data) * Otherwise assume that the driver will send * SYN_REPORT once it's done. */ - input_pass_event(dev, EV_SYN, SYN_REPORT, 1); + input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); } if (dev->rep[REP_PERIOD]) @@ -164,6 +174,7 @@ static void input_stop_autorepeat(struct input_dev *dev) #define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE) static int input_handle_abs_event(struct input_dev *dev, + struct input_handler *src_handler, unsigned int code, int *pval) { bool is_mt_event; @@ -207,13 +218,15 @@ static int input_handle_abs_event(struct input_dev *dev, /* Flush pending "slot" event */ if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) { input_abs_set_val(dev, ABS_MT_SLOT, dev->slot); - input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot); + input_pass_event(dev, src_handler, + EV_ABS, ABS_MT_SLOT, dev->slot); } return INPUT_PASS_TO_HANDLERS; } static void input_handle_event(struct input_dev *dev, + struct input_handler *src_handler, unsigned int type, unsigned int code, int value) { int disposition = INPUT_IGNORE_EVENT; @@ -266,7 +279,8 @@ static void input_handle_event(struct input_dev *dev, case EV_ABS: if (is_event_supported(code, dev->absbit, ABS_MAX)) - disposition = input_handle_abs_event(dev, code, &value); + disposition = input_handle_abs_event(dev, src_handler, + code, &value); break; @@ -324,7 +338,7 @@ static void input_handle_event(struct input_dev *dev, dev->event(dev, type, code, value); if (disposition & INPUT_PASS_TO_HANDLERS) - input_pass_event(dev, type, code, value); + input_pass_event(dev, src_handler, type, code, value); } /** @@ -353,7 +367,7 @@ void input_event(struct input_dev *dev, spin_lock_irqsave(&dev->event_lock, flags); add_input_randomness(type, code, value); - input_handle_event(dev, type, code, value); + input_handle_event(dev, NULL, type, code, value); spin_unlock_irqrestore(&dev->event_lock, flags); } } @@ -383,7 +397,8 @@ void input_inject_event(struct input_handle *handle, rcu_read_lock(); grab = rcu_dereference(dev->grab); if (!grab || grab == handle) - input_handle_event(dev, type, code, value); + input_handle_event(dev, handle->handler, + type, code, value); rcu_read_unlock(); spin_unlock_irqrestore(&dev->event_lock, flags); @@ -596,10 +611,10 @@ static void input_dev_release_keys(struct input_dev *dev) for (code = 0; code <= KEY_MAX; code++) { if (is_event_supported(code, dev->keybit, KEY_MAX) && __test_and_clear_bit(code, dev->key)) { - input_pass_event(dev, EV_KEY, code, 0); + input_pass_event(dev, NULL, EV_KEY, code, 0); } } - input_pass_event(dev, EV_SYN, SYN_REPORT, 1); + input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); } } @@ -874,9 +889,9 @@ int input_set_keycode(struct input_dev *dev, !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && __test_and_clear_bit(old_keycode, dev->key)) { - input_pass_event(dev, EV_KEY, old_keycode, 0); + input_pass_event(dev, NULL, EV_KEY, old_keycode, 0); if (dev->sync) - input_pass_event(dev, EV_SYN, SYN_REPORT, 1); + input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1); } out: diff --git a/trunk/drivers/input/misc/rotary_encoder.c b/trunk/drivers/input/misc/rotary_encoder.c index 7e64d01da2be..1f8e0108962e 100644 --- a/trunk/drivers/input/misc/rotary_encoder.c +++ b/trunk/drivers/input/misc/rotary_encoder.c @@ -176,7 +176,7 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) /* request the IRQs */ err = request_irq(encoder->irq_a, &rotary_encoder_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, DRV_NAME, encoder); if (err) { dev_err(&pdev->dev, "unable to request IRQ %d\n", @@ -185,7 +185,7 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) } err = request_irq(encoder->irq_b, &rotary_encoder_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, DRV_NAME, encoder); if (err) { dev_err(&pdev->dev, "unable to request IRQ %d\n", diff --git a/trunk/drivers/input/serio/serio.c b/trunk/drivers/input/serio/serio.c index 7c38d1fbabf2..db5b0bca1a1a 100644 --- a/trunk/drivers/input/serio/serio.c +++ b/trunk/drivers/input/serio/serio.c @@ -188,8 +188,7 @@ static void serio_free_event(struct serio_event *event) kfree(event); } -static void serio_remove_duplicate_events(void *object, - enum serio_event_type type) +static void serio_remove_duplicate_events(struct serio_event *event) { struct serio_event *e, *next; unsigned long flags; @@ -197,13 +196,13 @@ static void serio_remove_duplicate_events(void *object, spin_lock_irqsave(&serio_event_lock, flags); list_for_each_entry_safe(e, next, &serio_event_list, node) { - if (object == e->object) { + if (event->object == e->object) { /* * If this event is of different type we should not * look further - we only suppress duplicate events * that were sent back-to-back. */ - if (type != e->type) + if (event->type != e->type) break; list_del_init(&e->node); @@ -246,7 +245,7 @@ static void serio_handle_event(struct work_struct *work) break; } - serio_remove_duplicate_events(event->object, event->type); + serio_remove_duplicate_events(event); serio_free_event(event); } @@ -437,12 +436,10 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * } else if (!strncmp(buf, "rescan", count)) { serio_disconnect_port(serio); serio_find_driver(serio); - serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { serio_disconnect_port(serio); error = serio_bind_driver(serio, to_serio_driver(drv)); put_driver(drv); - serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); } else { error = -EINVAL; } diff --git a/trunk/drivers/input/tablet/wacom_sys.c b/trunk/drivers/input/tablet/wacom_sys.c index cf8fb9f5d4a8..fc381498b798 100644 --- a/trunk/drivers/input/tablet/wacom_sys.c +++ b/trunk/drivers/input/tablet/wacom_sys.c @@ -519,7 +519,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i /* Retrieve the physical and logical size for OEM devices */ error = wacom_retrieve_hid_descriptor(intf, features); if (error) - goto fail3; + goto fail2; wacom_setup_device_quirks(features); diff --git a/trunk/drivers/input/touchscreen/ads7846.c b/trunk/drivers/input/touchscreen/ads7846.c index 4bf2316e3284..14ea54b78e46 100644 --- a/trunk/drivers/input/touchscreen/ads7846.c +++ b/trunk/drivers/input/touchscreen/ads7846.c @@ -941,30 +941,29 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads784 struct ads7846_platform_data *pdata = spi->dev.platform_data; int err; - /* - * REVISIT when the irq can be triggered active-low, or if for some + /* REVISIT when the irq can be triggered active-low, or if for some * reason the touchscreen isn't hooked up, we don't need to access * the pendown state. */ + if (!pdata->get_pendown_state && !gpio_is_valid(pdata->gpio_pendown)) { + dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); + return -EINVAL; + } if (pdata->get_pendown_state) { ts->get_pendown_state = pdata->get_pendown_state; - } else if (gpio_is_valid(pdata->gpio_pendown)) { - - err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); - if (err) { - dev_err(&spi->dev, "failed to request pendown GPIO%d\n", - pdata->gpio_pendown); - return err; - } - - ts->gpio_pendown = pdata->gpio_pendown; + return 0; + } - } else { - dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); - return -EINVAL; + err = gpio_request(pdata->gpio_pendown, "ads7846_pendown"); + if (err) { + dev_err(&spi->dev, "failed to request pendown GPIO%d\n", + pdata->gpio_pendown); + return err; } + ts->gpio_pendown = pdata->gpio_pendown; + return 0; } @@ -1354,7 +1353,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) err_put_regulator: regulator_put(ts->reg); err_free_gpio: - if (!ts->get_pendown_state) + if (ts->gpio_pendown != -1) gpio_free(ts->gpio_pendown); err_cleanup_filter: if (ts->filter_cleanup) @@ -1384,13 +1383,8 @@ static int __devexit ads7846_remove(struct spi_device *spi) regulator_disable(ts->reg); regulator_put(ts->reg); - if (!ts->get_pendown_state) { - /* - * If we are not using specialized pendown method we must - * have been relying on gpio we set up ourselves. - */ + if (ts->gpio_pendown != -1) gpio_free(ts->gpio_pendown); - } if (ts->filter_cleanup) ts->filter_cleanup(ts->filter_data); diff --git a/trunk/drivers/input/touchscreen/wacom_w8001.c b/trunk/drivers/input/touchscreen/wacom_w8001.c index c14412ef4648..5cb8449c909d 100644 --- a/trunk/drivers/input/touchscreen/wacom_w8001.c +++ b/trunk/drivers/input/touchscreen/wacom_w8001.c @@ -51,10 +51,6 @@ MODULE_LICENSE("GPL"); #define W8001_PKTLEN_TPCCTL 11 /* control packet */ #define W8001_PKTLEN_TOUCH2FG 13 -/* resolution in points/mm */ -#define W8001_PEN_RESOLUTION 100 -#define W8001_TOUCH_RESOLUTION 10 - struct w8001_coord { u8 rdy; u8 tsw; @@ -202,7 +198,7 @@ static void parse_touchquery(u8 *data, struct w8001_touch_query *query) query->y = 1024; if (query->panel_res) query->x = query->y = (1 << query->panel_res); - query->panel_res = W8001_TOUCH_RESOLUTION; + query->panel_res = 10; } } @@ -398,8 +394,6 @@ static int w8001_setup(struct w8001 *w8001) input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); - input_abs_set_res(dev, ABS_X, W8001_PEN_RESOLUTION); - input_abs_set_res(dev, ABS_Y, W8001_PEN_RESOLUTION); input_set_abs_params(dev, ABS_PRESSURE, 0, coord.pen_pressure, 0, 0); if (coord.tilt_x && coord.tilt_y) { input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); @@ -424,17 +418,14 @@ static int w8001_setup(struct w8001 *w8001) w8001->max_touch_x = touch.x; w8001->max_touch_y = touch.y; + /* scale to pen maximum */ if (w8001->max_pen_x && w8001->max_pen_y) { - /* if pen is supported scale to pen maximum */ touch.x = w8001->max_pen_x; touch.y = w8001->max_pen_y; - touch.panel_res = W8001_PEN_RESOLUTION; } input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0); - input_abs_set_res(dev, ABS_X, touch.panel_res); - input_abs_set_res(dev, ABS_Y, touch.panel_res); switch (touch.sensor_id) { case 0: diff --git a/trunk/drivers/message/fusion/mptbase.h b/trunk/drivers/message/fusion/mptbase.h index 1735c84ff757..f71f22948477 100644 --- a/trunk/drivers/message/fusion/mptbase.h +++ b/trunk/drivers/message/fusion/mptbase.h @@ -76,8 +76,8 @@ #define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "3.04.18" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.18" +#define MPT_LINUX_VERSION_COMMON "3.04.17" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.17" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ diff --git a/trunk/drivers/message/fusion/mptctl.c b/trunk/drivers/message/fusion/mptctl.c index e8deb8ed0499..a3856ed90aef 100644 --- a/trunk/drivers/message/fusion/mptctl.c +++ b/trunk/drivers/message/fusion/mptctl.c @@ -596,13 +596,6 @@ mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) return 1; } -static int -mptctl_release(struct inode *inode, struct file *filep) -{ - fasync_helper(-1, filep, 0, &async_queue); - return 0; -} - static int mptctl_fasync(int fd, struct file *filep, int mode) { @@ -2822,7 +2815,6 @@ static const struct file_operations mptctl_fops = { .llseek = no_llseek, .fasync = mptctl_fasync, .unlocked_ioctl = mptctl_ioctl, - .release = mptctl_release, #ifdef CONFIG_COMPAT .compat_ioctl = compat_mpctl_ioctl, #endif diff --git a/trunk/drivers/message/fusion/mptscsih.c b/trunk/drivers/message/fusion/mptscsih.c index 0d9b82a44540..59b8f53d1ece 100644 --- a/trunk/drivers/message/fusion/mptscsih.c +++ b/trunk/drivers/message/fusion/mptscsih.c @@ -1873,9 +1873,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) } out: - printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p) (sn=%ld)\n", - ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval, - SCpnt, SCpnt->serial_number); + printk(MYIOC_s_INFO_FMT "task abort: %s (sc=%p)\n", + ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), SCpnt); return retval; } @@ -1912,7 +1911,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) vdevice = SCpnt->device->hostdata; if (!vdevice || !vdevice->vtarget) { - retval = 0; + retval = SUCCESS; goto out; } diff --git a/trunk/drivers/net/can/mscan/Kconfig b/trunk/drivers/net/can/mscan/Kconfig index d38706958af6..27d1d398e25e 100644 --- a/trunk/drivers/net/can/mscan/Kconfig +++ b/trunk/drivers/net/can/mscan/Kconfig @@ -1,5 +1,5 @@ config CAN_MSCAN - depends on CAN_DEV && (PPC || M68K) + depends on CAN_DEV && (PPC || M68K || M68KNOMMU) tristate "Support for Freescale MSCAN based chips" ---help--- The Motorola Scalable Controller Area Network (MSCAN) definition diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c index ea25e5bfcf23..8ecaac983923 100644 --- a/trunk/drivers/pci/pci-sysfs.c +++ b/trunk/drivers/pci/pci-sysfs.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include "pci.h" @@ -369,7 +368,7 @@ pci_read_config(struct file *filp, struct kobject *kobj, u8 *data = (u8*) buf; /* Several chips lock up trying to read undefined config space */ - if (security_capable(filp->f_cred, CAP_SYS_ADMIN) == 0) { + if (cap_raised(filp->f_cred->cap_effective, CAP_SYS_ADMIN)) { size = dev->cfg_size; } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { size = 128; diff --git a/trunk/drivers/rtc/rtc-at32ap700x.c b/trunk/drivers/rtc/rtc-at32ap700x.c index e725d51e773d..b2752b6e7a2f 100644 --- a/trunk/drivers/rtc/rtc-at32ap700x.c +++ b/trunk/drivers/rtc/rtc-at32ap700x.c @@ -134,29 +134,36 @@ static int at32_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) return ret; } -static int at32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +static int at32_rtc_ioctl(struct device *dev, unsigned int cmd, + unsigned long arg) { struct rtc_at32ap700x *rtc = dev_get_drvdata(dev); int ret = 0; spin_lock_irq(&rtc->lock); - if(enabled) { + switch (cmd) { + case RTC_AIE_ON: if (rtc_readl(rtc, VAL) > rtc->alarm_time) { ret = -EINVAL; - goto out; + break; } rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) | RTC_BIT(CTRL_TOPEN)); rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI)); rtc_writel(rtc, IER, RTC_BIT(IER_TOPI)); - } else { + break; + case RTC_AIE_OFF: rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) & ~RTC_BIT(CTRL_TOPEN)); rtc_writel(rtc, IDR, RTC_BIT(IDR_TOPI)); rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI)); + break; + default: + ret = -ENOIOCTLCMD; + break; } -out: + spin_unlock_irq(&rtc->lock); return ret; @@ -188,11 +195,11 @@ static irqreturn_t at32_rtc_interrupt(int irq, void *dev_id) } static struct rtc_class_ops at32_rtc_ops = { + .ioctl = at32_rtc_ioctl, .read_time = at32_rtc_readtime, .set_time = at32_rtc_settime, .read_alarm = at32_rtc_readalarm, .set_alarm = at32_rtc_setalarm, - .alarm_irq_enable = at32_rtc_alarm_irq_enable, }; static int __init at32_rtc_probe(struct platform_device *pdev) diff --git a/trunk/drivers/rtc/rtc-at91rm9200.c b/trunk/drivers/rtc/rtc-at91rm9200.c index 26d1cf5d19ae..bc8bbca9a2e2 100644 --- a/trunk/drivers/rtc/rtc-at91rm9200.c +++ b/trunk/drivers/rtc/rtc-at91rm9200.c @@ -195,6 +195,13 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, /* important: scrub old status before enabling IRQs */ switch (cmd) { + case RTC_AIE_OFF: /* alarm off */ + at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); + break; + case RTC_AIE_ON: /* alarm on */ + at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); + at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); + break; case RTC_UIE_OFF: /* update off */ at91_sys_write(AT91_RTC_IDR, AT91_RTC_SECEV); break; @@ -210,18 +217,6 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, return ret; } -static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) -{ - pr_debug("%s(): cmd=%08x\n", __func__, enabled); - - if (enabled) { - at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM); - at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); - } else - at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); - - return 0; -} /* * Provide additional RTC information in /proc/driver/rtc */ @@ -275,7 +270,6 @@ static const struct rtc_class_ops at91_rtc_ops = { .read_alarm = at91_rtc_readalarm, .set_alarm = at91_rtc_setalarm, .proc = at91_rtc_proc, - .alarm_irq_enable = at91_rtc_alarm_irq_enable, }; /* diff --git a/trunk/drivers/rtc/rtc-at91sam9.c b/trunk/drivers/rtc/rtc-at91sam9.c index c36749e4c926..f677e0710ca1 100644 --- a/trunk/drivers/rtc/rtc-at91sam9.c +++ b/trunk/drivers/rtc/rtc-at91sam9.c @@ -229,6 +229,12 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, dev_dbg(dev, "ioctl: cmd=%08x, arg=%08lx, mr %08x\n", cmd, arg, mr); switch (cmd) { + case RTC_AIE_OFF: /* alarm off */ + rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN); + break; + case RTC_AIE_ON: /* alarm on */ + rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN); + break; case RTC_UIE_OFF: /* update off */ rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); break; @@ -243,19 +249,6 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, return ret; } -static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) -{ - struct sam9_rtc *rtc = dev_get_drvdata(dev); - u32 mr = rtt_readl(rtc, MR); - - dev_dbg(dev, "alarm_irq_enable: enabled=%08x, mr %08x\n", enabled, mr); - if (enabled) - rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN); - else - rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN); - return 0; -} - /* * Provide additional RTC information in /proc/driver/rtc */ @@ -309,7 +302,6 @@ static const struct rtc_class_ops at91_rtc_ops = { .read_alarm = at91_rtc_readalarm, .set_alarm = at91_rtc_setalarm, .proc = at91_rtc_proc, - .alarm_irq_enabled = at91_rtc_alarm_irq_enable, }; /* diff --git a/trunk/drivers/rtc/rtc-bfin.c b/trunk/drivers/rtc/rtc-bfin.c index 17971d93354d..b4b6087f2234 100644 --- a/trunk/drivers/rtc/rtc-bfin.c +++ b/trunk/drivers/rtc/rtc-bfin.c @@ -259,6 +259,15 @@ static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long ar bfin_rtc_int_clear(~RTC_ISTAT_SEC); break; + case RTC_AIE_ON: + dev_dbg_stamp(dev); + bfin_rtc_int_set_alarm(rtc); + break; + case RTC_AIE_OFF: + dev_dbg_stamp(dev); + bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); + break; + default: dev_dbg_stamp(dev); ret = -ENOIOCTLCMD; @@ -267,17 +276,6 @@ static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long ar return ret; } -static int bfin_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) -{ - struct bfin_rtc *rtc = dev_get_drvdata(dev); - - dev_dbg_stamp(dev); - if (enabled) - bfin_rtc_int_set_alarm(rtc); - else - bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); -} - static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct bfin_rtc *rtc = dev_get_drvdata(dev); @@ -364,7 +362,6 @@ static struct rtc_class_ops bfin_rtc_ops = { .read_alarm = bfin_rtc_read_alarm, .set_alarm = bfin_rtc_set_alarm, .proc = bfin_rtc_proc, - .alarm_irq_enable = bfin_rtc_alarm_irq_enable, }; static int __devinit bfin_rtc_probe(struct platform_device *pdev) diff --git a/trunk/drivers/rtc/rtc-dev.c b/trunk/drivers/rtc/rtc-dev.c index 37c3cc1b3dd5..212b16edafc0 100644 --- a/trunk/drivers/rtc/rtc-dev.c +++ b/trunk/drivers/rtc/rtc-dev.c @@ -154,7 +154,19 @@ static long rtc_dev_ioctl(struct file *file, if (err) goto done; - /* + /* try the driver's ioctl interface */ + if (ops->ioctl) { + err = ops->ioctl(rtc->dev.parent, cmd, arg); + if (err != -ENOIOCTLCMD) { + mutex_unlock(&rtc->ops_lock); + return err; + } + } + + /* if the driver does not provide the ioctl interface + * or if that particular ioctl was not implemented + * (-ENOIOCTLCMD), we will try to emulate here. + * * Drivers *SHOULD NOT* provide ioctl implementations * for these requests. Instead, provide methods to * support the following code, so that the RTC's main @@ -317,12 +329,7 @@ static long rtc_dev_ioctl(struct file *file, return err; default: - /* Finally try the driver's ioctl interface */ - if (ops->ioctl) { - err = ops->ioctl(rtc->dev.parent, cmd, arg); - if (err == -ENOIOCTLCMD) - err = -ENOTTY; - } + err = -ENOTTY; break; } diff --git a/trunk/drivers/rtc/rtc-ds1286.c b/trunk/drivers/rtc/rtc-ds1286.c index 60ce69600828..bf430f9091ed 100644 --- a/trunk/drivers/rtc/rtc-ds1286.c +++ b/trunk/drivers/rtc/rtc-ds1286.c @@ -40,26 +40,6 @@ static inline void ds1286_rtc_write(struct ds1286_priv *priv, u8 data, int reg) __raw_writel(data, &priv->rtcregs[reg]); } - -static int ds1286_alarm_irq_enable(struct device *dev, unsigned int enabled) -{ - struct ds1286_priv *priv = dev_get_drvdata(dev); - unsigned long flags; - unsigned char val; - - /* Allow or mask alarm interrupts */ - spin_lock_irqsave(&priv->lock, flags); - val = ds1286_rtc_read(priv, RTC_CMD); - if (enabled) - val &= ~RTC_TDM; - else - val |= RTC_TDM; - ds1286_rtc_write(priv, val, RTC_CMD); - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - #ifdef CONFIG_RTC_INTF_DEV static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) @@ -69,6 +49,22 @@ static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) unsigned char val; switch (cmd) { + case RTC_AIE_OFF: + /* Mask alarm int. enab. bit */ + spin_lock_irqsave(&priv->lock, flags); + val = ds1286_rtc_read(priv, RTC_CMD); + val |= RTC_TDM; + ds1286_rtc_write(priv, val, RTC_CMD); + spin_unlock_irqrestore(&priv->lock, flags); + break; + case RTC_AIE_ON: + /* Allow alarm interrupts. */ + spin_lock_irqsave(&priv->lock, flags); + val = ds1286_rtc_read(priv, RTC_CMD); + val &= ~RTC_TDM; + ds1286_rtc_write(priv, val, RTC_CMD); + spin_unlock_irqrestore(&priv->lock, flags); + break; case RTC_WIE_OFF: /* Mask watchdog int. enab. bit */ spin_lock_irqsave(&priv->lock, flags); @@ -320,13 +316,12 @@ static int ds1286_set_alarm(struct device *dev, struct rtc_wkalrm *alm) } static const struct rtc_class_ops ds1286_ops = { - .ioctl = ds1286_ioctl, - .proc = ds1286_proc, + .ioctl = ds1286_ioctl, + .proc = ds1286_proc, .read_time = ds1286_read_time, .set_time = ds1286_set_time, .read_alarm = ds1286_read_alarm, .set_alarm = ds1286_set_alarm, - .alarm_irq_enable = ds1286_alarm_irq_enable, }; static int __devinit ds1286_probe(struct platform_device *pdev) diff --git a/trunk/drivers/rtc/rtc-ds1305.c b/trunk/drivers/rtc/rtc-ds1305.c index 57fbcc149ba7..077af1d7b9e4 100644 --- a/trunk/drivers/rtc/rtc-ds1305.c +++ b/trunk/drivers/rtc/rtc-ds1305.c @@ -139,32 +139,49 @@ static u8 hour2bcd(bool hr12, int hour) * Interface to RTC framework */ -static int ds1305_alarm_irq_enable(struct device *dev, unsigned int enabled) +#ifdef CONFIG_RTC_INTF_DEV + +/* + * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl) + */ +static int ds1305_ioctl(struct device *dev, unsigned cmd, unsigned long arg) { struct ds1305 *ds1305 = dev_get_drvdata(dev); u8 buf[2]; - long err = -EINVAL; + int status = -ENOIOCTLCMD; buf[0] = DS1305_WRITE | DS1305_CONTROL; buf[1] = ds1305->ctrl[0]; - if (enabled) { - if (ds1305->ctrl[0] & DS1305_AEI0) - goto done; - buf[1] |= DS1305_AEI0; - } else { + switch (cmd) { + case RTC_AIE_OFF: + status = 0; if (!(buf[1] & DS1305_AEI0)) goto done; buf[1] &= ~DS1305_AEI0; + break; + + case RTC_AIE_ON: + status = 0; + if (ds1305->ctrl[0] & DS1305_AEI0) + goto done; + buf[1] |= DS1305_AEI0; + break; + } + if (status == 0) { + status = spi_write_then_read(ds1305->spi, buf, sizeof buf, + NULL, 0); + if (status >= 0) + ds1305->ctrl[0] = buf[1]; } - err = spi_write_then_read(ds1305->spi, buf, sizeof buf, NULL, 0); - if (err >= 0) - ds1305->ctrl[0] = buf[1]; -done: - return err; +done: + return status; } +#else +#define ds1305_ioctl NULL +#endif /* * Get/set of date and time is pretty normal. @@ -443,12 +460,12 @@ static int ds1305_proc(struct device *dev, struct seq_file *seq) #endif static const struct rtc_class_ops ds1305_ops = { + .ioctl = ds1305_ioctl, .read_time = ds1305_get_time, .set_time = ds1305_set_time, .read_alarm = ds1305_get_alarm, .set_alarm = ds1305_set_alarm, .proc = ds1305_proc, - .alarm_irq_enable = ds1305_alarm_irq_enable, }; static void ds1305_work(struct work_struct *work) diff --git a/trunk/drivers/rtc/rtc-ds1307.c b/trunk/drivers/rtc/rtc-ds1307.c index 4724ba3acf1a..0d559b6416dd 100644 --- a/trunk/drivers/rtc/rtc-ds1307.c +++ b/trunk/drivers/rtc/rtc-ds1307.c @@ -495,27 +495,50 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t) return 0; } -static int ds1307_alarm_irq_enable(struct device *dev, unsigned int enabled) +static int ds1307_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { struct i2c_client *client = to_i2c_client(dev); struct ds1307 *ds1307 = i2c_get_clientdata(client); int ret; - if (!test_bit(HAS_ALARM, &ds1307->flags)) - return -ENOTTY; + switch (cmd) { + case RTC_AIE_OFF: + if (!test_bit(HAS_ALARM, &ds1307->flags)) + return -ENOTTY; - ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); - if (ret < 0) - return ret; + ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); + if (ret < 0) + return ret; - if (enabled) - ret |= DS1337_BIT_A1IE; - else ret &= ~DS1337_BIT_A1IE; - ret = i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, ret); - if (ret < 0) - return ret; + ret = i2c_smbus_write_byte_data(client, + DS1337_REG_CONTROL, ret); + if (ret < 0) + return ret; + + break; + + case RTC_AIE_ON: + if (!test_bit(HAS_ALARM, &ds1307->flags)) + return -ENOTTY; + + ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); + if (ret < 0) + return ret; + + ret |= DS1337_BIT_A1IE; + + ret = i2c_smbus_write_byte_data(client, + DS1337_REG_CONTROL, ret); + if (ret < 0) + return ret; + + break; + + default: + return -ENOIOCTLCMD; + } return 0; } @@ -525,7 +548,7 @@ static const struct rtc_class_ops ds13xx_rtc_ops = { .set_time = ds1307_set_time, .read_alarm = ds1337_read_alarm, .set_alarm = ds1337_set_alarm, - .alarm_irq_enable = ds1307_alarm_irq_enable, + .ioctl = ds1307_ioctl, }; /*----------------------------------------------------------------------*/ diff --git a/trunk/drivers/rtc/rtc-ds1374.c b/trunk/drivers/rtc/rtc-ds1374.c index d834a63ec4b0..47fb6357c346 100644 --- a/trunk/drivers/rtc/rtc-ds1374.c +++ b/trunk/drivers/rtc/rtc-ds1374.c @@ -307,25 +307,42 @@ static void ds1374_work(struct work_struct *work) mutex_unlock(&ds1374->mutex); } -static int ds1374_alarm_irq_enable(struct device *dev, unsigned int enabled) +static int ds1374_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { struct i2c_client *client = to_i2c_client(dev); struct ds1374 *ds1374 = i2c_get_clientdata(client); - int ret; + int ret = -ENOIOCTLCMD; mutex_lock(&ds1374->mutex); - ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR); - if (ret < 0) - goto out; + switch (cmd) { + case RTC_AIE_OFF: + ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR); + if (ret < 0) + goto out; + + ret &= ~DS1374_REG_CR_WACE; + + ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret); + if (ret < 0) + goto out; + + break; + + case RTC_AIE_ON: + ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR); + if (ret < 0) + goto out; - if (enabled) { ret |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE; ret &= ~DS1374_REG_CR_WDALM; - } else { - ret &= ~DS1374_REG_CR_WACE; + + ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret); + if (ret < 0) + goto out; + + break; } - ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret); out: mutex_unlock(&ds1374->mutex); @@ -337,7 +354,7 @@ static const struct rtc_class_ops ds1374_rtc_ops = { .set_time = ds1374_set_time, .read_alarm = ds1374_read_alarm, .set_alarm = ds1374_set_alarm, - .alarm_irq_enable = ds1374_alarm_irq_enable, + .ioctl = ds1374_ioctl, }; static int ds1374_probe(struct i2c_client *client, diff --git a/trunk/drivers/rtc/rtc-m41t80.c b/trunk/drivers/rtc/rtc-m41t80.c index 69fe664a2228..5a8daa358066 100644 --- a/trunk/drivers/rtc/rtc-m41t80.c +++ b/trunk/drivers/rtc/rtc-m41t80.c @@ -213,27 +213,41 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm) return m41t80_set_datetime(to_i2c_client(dev), tm); } -static int m41t80_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE) +static int +m41t80_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { struct i2c_client *client = to_i2c_client(dev); int rc; + switch (cmd) { + case RTC_AIE_OFF: + case RTC_AIE_ON: + break; + default: + return -ENOIOCTLCMD; + } + rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON); if (rc < 0) goto err; - - if (enabled) - rc |= M41T80_ALMON_AFE; - else + switch (cmd) { + case RTC_AIE_OFF: rc &= ~M41T80_ALMON_AFE; - + break; + case RTC_AIE_ON: + rc |= M41T80_ALMON_AFE; + break; + } if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, rc) < 0) goto err; - return 0; err: return -EIO; } +#else +#define m41t80_rtc_ioctl NULL +#endif static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t) { @@ -360,7 +374,7 @@ static struct rtc_class_ops m41t80_rtc_ops = { .read_alarm = m41t80_rtc_read_alarm, .set_alarm = m41t80_rtc_set_alarm, .proc = m41t80_rtc_proc, - .alarm_irq_enable = m41t80_rtc_alarm_irq_enable, + .ioctl = m41t80_rtc_ioctl, }; #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) diff --git a/trunk/drivers/rtc/rtc-m48t59.c b/trunk/drivers/rtc/rtc-m48t59.c index 3978f4caf724..a99a0b554eb8 100644 --- a/trunk/drivers/rtc/rtc-m48t59.c +++ b/trunk/drivers/rtc/rtc-m48t59.c @@ -263,21 +263,30 @@ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) /* * Handle commands from user-space */ -static int m48t59_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +static int m48t59_rtc_ioctl(struct device *dev, unsigned int cmd, + unsigned long arg) { struct platform_device *pdev = to_platform_device(dev); struct m48t59_plat_data *pdata = pdev->dev.platform_data; struct m48t59_private *m48t59 = platform_get_drvdata(pdev); unsigned long flags; + int ret = 0; spin_lock_irqsave(&m48t59->lock, flags); - if (enabled) - M48T59_WRITE(M48T59_INTR_AFE, M48T59_INTR); - else + switch (cmd) { + case RTC_AIE_OFF: /* alarm interrupt off */ M48T59_WRITE(0x00, M48T59_INTR); + break; + case RTC_AIE_ON: /* alarm interrupt on */ + M48T59_WRITE(M48T59_INTR_AFE, M48T59_INTR); + break; + default: + ret = -ENOIOCTLCMD; + break; + } spin_unlock_irqrestore(&m48t59->lock, flags); - return 0; + return ret; } static int m48t59_rtc_proc(struct device *dev, struct seq_file *seq) @@ -321,12 +330,12 @@ static irqreturn_t m48t59_rtc_interrupt(int irq, void *dev_id) } static const struct rtc_class_ops m48t59_rtc_ops = { + .ioctl = m48t59_rtc_ioctl, .read_time = m48t59_rtc_read_time, .set_time = m48t59_rtc_set_time, .read_alarm = m48t59_rtc_readalarm, .set_alarm = m48t59_rtc_setalarm, .proc = m48t59_rtc_proc, - .alarm_irq_enable = m48t59_rtc_alarm_irq_enable, }; static const struct rtc_class_ops m48t02_rtc_ops = { diff --git a/trunk/drivers/rtc/rtc-mrst.c b/trunk/drivers/rtc/rtc-mrst.c index 1db62db8469d..bcd0cf63eb16 100644 --- a/trunk/drivers/rtc/rtc-mrst.c +++ b/trunk/drivers/rtc/rtc-mrst.c @@ -255,21 +255,42 @@ static int mrst_irq_set_state(struct device *dev, int enabled) return 0; } +#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE) + /* Currently, the vRTC doesn't support UIE ON/OFF */ -static int mrst_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +static int +mrst_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { struct mrst_rtc *mrst = dev_get_drvdata(dev); unsigned long flags; + switch (cmd) { + case RTC_AIE_OFF: + case RTC_AIE_ON: + if (!mrst->irq) + return -EINVAL; + break; + default: + /* PIE ON/OFF is handled by mrst_irq_set_state() */ + return -ENOIOCTLCMD; + } + spin_lock_irqsave(&rtc_lock, flags); - if (enabled) - mrst_irq_enable(mrst, RTC_AIE); - else + switch (cmd) { + case RTC_AIE_OFF: /* alarm off */ mrst_irq_disable(mrst, RTC_AIE); + break; + case RTC_AIE_ON: /* alarm on */ + mrst_irq_enable(mrst, RTC_AIE); + break; + } spin_unlock_irqrestore(&rtc_lock, flags); return 0; } +#else +#define mrst_rtc_ioctl NULL +#endif #if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) @@ -296,13 +317,13 @@ static int mrst_procfs(struct device *dev, struct seq_file *seq) #endif static const struct rtc_class_ops mrst_rtc_ops = { + .ioctl = mrst_rtc_ioctl, .read_time = mrst_read_time, .set_time = mrst_set_time, .read_alarm = mrst_read_alarm, .set_alarm = mrst_set_alarm, .proc = mrst_procfs, .irq_set_state = mrst_irq_set_state, - .alarm_irq_enable = mrst_rtc_alarm_irq_enable, }; static struct mrst_rtc mrst_rtc; diff --git a/trunk/drivers/rtc/rtc-msm6242.c b/trunk/drivers/rtc/rtc-msm6242.c index 67820626e18f..b2fff0ca49f8 100644 --- a/trunk/drivers/rtc/rtc-msm6242.c +++ b/trunk/drivers/rtc/rtc-msm6242.c @@ -82,7 +82,7 @@ static inline unsigned int msm6242_read(struct msm6242_priv *priv, static inline void msm6242_write(struct msm6242_priv *priv, unsigned int val, unsigned int reg) { - __raw_writel(val, &priv->regs[reg]); + return __raw_writel(val, &priv->regs[reg]); } static inline void msm6242_set(struct msm6242_priv *priv, unsigned int val, diff --git a/trunk/drivers/rtc/rtc-mv.c b/trunk/drivers/rtc/rtc-mv.c index 60627a764514..bcca47298554 100644 --- a/trunk/drivers/rtc/rtc-mv.c +++ b/trunk/drivers/rtc/rtc-mv.c @@ -169,19 +169,25 @@ static int mv_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) return 0; } -static int mv_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +static int mv_rtc_ioctl(struct device *dev, unsigned int cmd, + unsigned long arg) { struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr; if (pdata->irq < 0) - return -EINVAL; /* fall back into rtc-dev's emulation */ - - if (enabled) - writel(1, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS); - else + return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ + switch (cmd) { + case RTC_AIE_OFF: writel(0, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS); + break; + case RTC_AIE_ON: + writel(1, ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS); + break; + default: + return -ENOIOCTLCMD; + } return 0; } @@ -210,7 +216,7 @@ static const struct rtc_class_ops mv_rtc_alarm_ops = { .set_time = mv_rtc_set_time, .read_alarm = mv_rtc_read_alarm, .set_alarm = mv_rtc_set_alarm, - .alarm_irq_enable = mv_rtc_alarm_irq_enable, + .ioctl = mv_rtc_ioctl, }; static int __devinit mv_rtc_probe(struct platform_device *pdev) diff --git a/trunk/drivers/rtc/rtc-omap.c b/trunk/drivers/rtc/rtc-omap.c index b4dbf3a319b3..e72b523c79a5 100644 --- a/trunk/drivers/rtc/rtc-omap.c +++ b/trunk/drivers/rtc/rtc-omap.c @@ -143,6 +143,8 @@ omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) u8 reg; switch (cmd) { + case RTC_AIE_OFF: + case RTC_AIE_ON: case RTC_UIE_OFF: case RTC_UIE_ON: break; @@ -154,6 +156,13 @@ omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) rtc_wait_not_busy(); reg = rtc_read(OMAP_RTC_INTERRUPTS_REG); switch (cmd) { + /* AIE = Alarm Interrupt Enable */ + case RTC_AIE_OFF: + reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM; + break; + case RTC_AIE_ON: + reg |= OMAP_RTC_INTERRUPTS_IT_ALARM; + break; /* UIE = Update Interrupt Enable (1/second) */ case RTC_UIE_OFF: reg &= ~OMAP_RTC_INTERRUPTS_IT_TIMER; @@ -173,24 +182,6 @@ omap_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) #define omap_rtc_ioctl NULL #endif -static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) -{ - u8 reg; - - local_irq_disable(); - rtc_wait_not_busy(); - reg = rtc_read(OMAP_RTC_INTERRUPTS_REG); - if (enabled) - reg |= OMAP_RTC_INTERRUPTS_IT_ALARM; - else - reg &= ~OMAP_RTC_INTERRUPTS_IT_ALARM; - rtc_wait_not_busy(); - rtc_write(reg, OMAP_RTC_INTERRUPTS_REG); - local_irq_enable(); - - return 0; -} - /* this hardware doesn't support "don't care" alarm fields */ static int tm2bcd(struct rtc_time *tm) { @@ -318,7 +309,6 @@ static struct rtc_class_ops omap_rtc_ops = { .set_time = omap_rtc_set_time, .read_alarm = omap_rtc_read_alarm, .set_alarm = omap_rtc_set_alarm, - .alarm_irq_enable = omap_rtc_alarm_irq_enable, }; static int omap_rtc_alarm; diff --git a/trunk/drivers/rtc/rtc-rp5c01.c b/trunk/drivers/rtc/rtc-rp5c01.c index 694da39b6dd2..36eb66184461 100644 --- a/trunk/drivers/rtc/rtc-rp5c01.c +++ b/trunk/drivers/rtc/rtc-rp5c01.c @@ -76,7 +76,7 @@ static inline unsigned int rp5c01_read(struct rp5c01_priv *priv, static inline void rp5c01_write(struct rp5c01_priv *priv, unsigned int val, unsigned int reg) { - __raw_writel(val, &priv->regs[reg]); + return __raw_writel(val, &priv->regs[reg]); } static void rp5c01_lock(struct rp5c01_priv *priv) diff --git a/trunk/drivers/rtc/rtc-rs5c372.c b/trunk/drivers/rtc/rtc-rs5c372.c index 6aaa1550e3b1..dd14e202c2c8 100644 --- a/trunk/drivers/rtc/rtc-rs5c372.c +++ b/trunk/drivers/rtc/rtc-rs5c372.c @@ -299,6 +299,14 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) if (rs5c->type == rtc_rs5c372a && (buf & RS5C372A_CTRL1_SL1)) return -ENOIOCTLCMD; + case RTC_AIE_OFF: + case RTC_AIE_ON: + /* these irq management calls only make sense for chips + * which are wired up to an IRQ. + */ + if (!rs5c->has_irq) + return -ENOIOCTLCMD; + break; default: return -ENOIOCTLCMD; } @@ -309,6 +317,12 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) addr = RS5C_ADDR(RS5C_REG_CTRL1); switch (cmd) { + case RTC_AIE_OFF: /* alarm off */ + buf &= ~RS5C_CTRL1_AALE; + break; + case RTC_AIE_ON: /* alarm on */ + buf |= RS5C_CTRL1_AALE; + break; case RTC_UIE_OFF: /* update off */ buf &= ~RS5C_CTRL1_CT_MASK; break; @@ -333,39 +347,6 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) #endif -static int rs5c_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) -{ - struct i2c_client *client = to_i2c_client(dev); - struct rs5c372 *rs5c = i2c_get_clientdata(client); - unsigned char buf; - int status, addr; - - buf = rs5c->regs[RS5C_REG_CTRL1]; - - if (!rs5c->has_irq) - return -EINVAL; - - status = rs5c_get_regs(rs5c); - if (status < 0) - return status; - - addr = RS5C_ADDR(RS5C_REG_CTRL1); - if (enabled) - buf |= RS5C_CTRL1_AALE; - else - buf &= ~RS5C_CTRL1_AALE; - - if (i2c_smbus_write_byte_data(client, addr, buf) < 0) { - printk(KERN_WARNING "%s: can't update alarm\n", - rs5c->rtc->name); - status = -EIO; - } else - rs5c->regs[RS5C_REG_CTRL1] = buf; - - return status; -} - - /* NOTE: Since RTC_WKALM_{RD,SET} were originally defined for EFI, * which only exposes a polled programming interface; and since * these calls map directly to those EFI requests; we don't demand @@ -485,7 +466,6 @@ static const struct rtc_class_ops rs5c372_rtc_ops = { .set_time = rs5c372_rtc_set_time, .read_alarm = rs5c_read_alarm, .set_alarm = rs5c_set_alarm, - .alarm_irq_enable = rs5c_rtc_alarm_irq_enable, }; #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) diff --git a/trunk/drivers/rtc/rtc-sa1100.c b/trunk/drivers/rtc/rtc-sa1100.c index 5dfe5ffcb0d3..88ea52b8647a 100644 --- a/trunk/drivers/rtc/rtc-sa1100.c +++ b/trunk/drivers/rtc/rtc-sa1100.c @@ -314,6 +314,16 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { switch (cmd) { + case RTC_AIE_OFF: + spin_lock_irq(&sa1100_rtc_lock); + RTSR &= ~RTSR_ALE; + spin_unlock_irq(&sa1100_rtc_lock); + return 0; + case RTC_AIE_ON: + spin_lock_irq(&sa1100_rtc_lock); + RTSR |= RTSR_ALE; + spin_unlock_irq(&sa1100_rtc_lock); + return 0; case RTC_UIE_OFF: spin_lock_irq(&sa1100_rtc_lock); RTSR &= ~RTSR_HZE; @@ -328,17 +338,6 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd, return -ENOIOCTLCMD; } -static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) -{ - spin_lock_irq(&sa1100_rtc_lock); - if (enabled) - RTSR |= RTSR_ALE; - else - RTSR &= ~RTSR_ALE; - spin_unlock_irq(&sa1100_rtc_lock); - return 0; -} - static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) { rtc_time_to_tm(RCNR, tm); @@ -411,7 +410,6 @@ static const struct rtc_class_ops sa1100_rtc_ops = { .proc = sa1100_rtc_proc, .irq_set_freq = sa1100_irq_set_freq, .irq_set_state = sa1100_irq_set_state, - .alarm_irq_enable = sa1100_rtc_alarm_irq_enable, }; static int sa1100_rtc_probe(struct platform_device *pdev) diff --git a/trunk/drivers/rtc/rtc-sh.c b/trunk/drivers/rtc/rtc-sh.c index 93314a9e7fa9..06e41ed93230 100644 --- a/trunk/drivers/rtc/rtc-sh.c +++ b/trunk/drivers/rtc/rtc-sh.c @@ -350,6 +350,10 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) unsigned int ret = 0; switch (cmd) { + case RTC_AIE_OFF: + case RTC_AIE_ON: + sh_rtc_setaie(dev, cmd == RTC_AIE_ON); + break; case RTC_UIE_OFF: rtc->periodic_freq &= ~PF_OXS; sh_rtc_setcie(dev, 0); @@ -365,12 +369,6 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) return ret; } -static int sh_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) -{ - sh_rtc_setaie(dev, enabled); - return 0; -} - static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct platform_device *pdev = to_platform_device(dev); @@ -606,7 +604,6 @@ static struct rtc_class_ops sh_rtc_ops = { .irq_set_state = sh_rtc_irq_set_state, .irq_set_freq = sh_rtc_irq_set_freq, .proc = sh_rtc_proc, - .alarm_irq_enable = sh_rtc_alarm_irq_enable, }; static int __init sh_rtc_probe(struct platform_device *pdev) diff --git a/trunk/drivers/rtc/rtc-test.c b/trunk/drivers/rtc/rtc-test.c index a82d6fe97076..51725f7755b0 100644 --- a/trunk/drivers/rtc/rtc-test.c +++ b/trunk/drivers/rtc/rtc-test.c @@ -50,9 +50,24 @@ static int test_rtc_proc(struct device *dev, struct seq_file *seq) return 0; } -static int test_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) +static int test_rtc_ioctl(struct device *dev, unsigned int cmd, + unsigned long arg) { - return 0; + /* We do support interrupts, they're generated + * using the sysfs interface. + */ + switch (cmd) { + case RTC_PIE_ON: + case RTC_PIE_OFF: + case RTC_UIE_ON: + case RTC_UIE_OFF: + case RTC_AIE_ON: + case RTC_AIE_OFF: + return 0; + + default: + return -ENOIOCTLCMD; + } } static const struct rtc_class_ops test_rtc_ops = { @@ -61,7 +76,7 @@ static const struct rtc_class_ops test_rtc_ops = { .read_alarm = test_rtc_read_alarm, .set_alarm = test_rtc_set_alarm, .set_mmss = test_rtc_set_mmss, - .alarm_irq_enable = test_rtc_alarm_irq_enable, + .ioctl = test_rtc_ioctl, }; static ssize_t test_irq_show(struct device *dev, diff --git a/trunk/drivers/rtc/rtc-vr41xx.c b/trunk/drivers/rtc/rtc-vr41xx.c index 769190ac6d11..c3244244e8cf 100644 --- a/trunk/drivers/rtc/rtc-vr41xx.c +++ b/trunk/drivers/rtc/rtc-vr41xx.c @@ -240,6 +240,26 @@ static int vr41xx_rtc_irq_set_state(struct device *dev, int enabled) static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { switch (cmd) { + case RTC_AIE_ON: + spin_lock_irq(&rtc_lock); + + if (!alarm_enabled) { + enable_irq(aie_irq); + alarm_enabled = 1; + } + + spin_unlock_irq(&rtc_lock); + break; + case RTC_AIE_OFF: + spin_lock_irq(&rtc_lock); + + if (alarm_enabled) { + disable_irq(aie_irq); + alarm_enabled = 0; + } + + spin_unlock_irq(&rtc_lock); + break; case RTC_EPOCH_READ: return put_user(epoch, (unsigned long __user *)arg); case RTC_EPOCH_SET: @@ -255,24 +275,6 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long return 0; } -static int vr41xx_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) -{ - spin_lock_irq(&rtc_lock); - if (enabled) { - if (!alarm_enabled) { - enable_irq(aie_irq); - alarm_enabled = 1; - } - } else { - if (alarm_enabled) { - disable_irq(aie_irq); - alarm_enabled = 0; - } - } - spin_unlock_irq(&rtc_lock); - return 0; -} - static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id) { struct platform_device *pdev = (struct platform_device *)dev_id; diff --git a/trunk/drivers/scsi/qla2xxx/qla_attr.c b/trunk/drivers/scsi/qla2xxx/qla_attr.c index d3e58d763b43..44578b56ad0a 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_attr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_attr.c @@ -1561,7 +1561,6 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) { struct Scsi_Host *host = rport_to_shost(rport); fc_port_t *fcport = *(fc_port_t **)rport->dd_data; - unsigned long flags; if (!fcport) return; @@ -1574,10 +1573,10 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) * Transport has effectively 'deleted' the rport, clear * all local references. */ - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irq(host->host_lock); fcport->rport = fcport->drport = NULL; *((fc_port_t **)rport->dd_data) = NULL; - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irq(host->host_lock); if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) return; diff --git a/trunk/drivers/scsi/qla2xxx/qla_init.c b/trunk/drivers/scsi/qla2xxx/qla_init.c index d9479c3fe5f8..f948e1a73aec 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_init.c +++ b/trunk/drivers/scsi/qla2xxx/qla_init.c @@ -2505,12 +2505,11 @@ qla2x00_rport_del(void *data) { fc_port_t *fcport = data; struct fc_rport *rport; - unsigned long flags; - spin_lock_irqsave(fcport->vha->host->host_lock, flags); + spin_lock_irq(fcport->vha->host->host_lock); rport = fcport->drport ? fcport->drport: fcport->rport; fcport->drport = NULL; - spin_unlock_irqrestore(fcport->vha->host->host_lock, flags); + spin_unlock_irq(fcport->vha->host->host_lock); if (rport) fc_remote_port_delete(rport); } @@ -2880,7 +2879,6 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) struct fc_rport_identifiers rport_ids; struct fc_rport *rport; struct qla_hw_data *ha = vha->hw; - unsigned long flags; qla2x00_rport_del(fcport); @@ -2895,9 +2893,9 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) "Unable to allocate fc remote port!\n"); return; } - spin_lock_irqsave(fcport->vha->host->host_lock, flags); + spin_lock_irq(fcport->vha->host->host_lock); *((fc_port_t **)rport->dd_data) = fcport; - spin_unlock_irqrestore(fcport->vha->host->host_lock, flags); + spin_unlock_irq(fcport->vha->host->host_lock); rport->supported_classes = fcport->supported_classes; diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index f27724d76cf6..c194c23ca1fb 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -562,6 +562,7 @@ qla2xxx_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *) } if (atomic_read(&fcport->state) != FCS_ONLINE) { if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD || + atomic_read(&fcport->state) == FCS_DEVICE_LOST || atomic_read(&base_vha->loop_state) == LOOP_DEAD) { cmd->result = DID_NO_CONNECT << 16; goto qc24_fail_command; @@ -2512,7 +2513,6 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, { struct fc_rport *rport; scsi_qla_host_t *base_vha; - unsigned long flags; if (!fcport->rport) return; @@ -2520,9 +2520,9 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, rport = fcport->rport; if (defer) { base_vha = pci_get_drvdata(vha->hw->pdev); - spin_lock_irqsave(vha->host->host_lock, flags); + spin_lock_irq(vha->host->host_lock); fcport->drport = rport; - spin_unlock_irqrestore(vha->host->host_lock, flags); + spin_unlock_irq(vha->host->host_lock); set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags); qla2xxx_wake_dpc(base_vha); } else @@ -3282,10 +3282,10 @@ qla2x00_do_dpc(void *data) set_user_nice(current, -20); - set_current_state(TASK_INTERRUPTIBLE); while (!kthread_should_stop()) { DEBUG3(printk("qla2x00: DPC handler sleeping\n")); + set_current_state(TASK_INTERRUPTIBLE); schedule(); __set_current_state(TASK_RUNNING); @@ -3454,9 +3454,7 @@ qla2x00_do_dpc(void *data) qla2x00_do_dpc_all_vps(base_vha); ha->dpc_active = 0; - set_current_state(TASK_INTERRUPTIBLE); } /* End of while(1) */ - __set_current_state(TASK_RUNNING); DEBUG(printk("scsi(%ld): DPC handler exiting\n", base_vha->host_no)); diff --git a/trunk/drivers/scsi/scsi_debug.c b/trunk/drivers/scsi/scsi_debug.c index a6b2d72022fc..7b310934efed 100644 --- a/trunk/drivers/scsi/scsi_debug.c +++ b/trunk/drivers/scsi/scsi_debug.c @@ -1671,7 +1671,7 @@ static int do_device_access(struct scsi_cmnd *scmd, unsigned long long lba, unsigned int num, int write) { int ret; - unsigned long long block, rest = 0; + unsigned int block, rest = 0; int (*func)(struct scsi_cmnd *, unsigned char *, int); func = write ? fetch_to_dev_buffer : fill_from_dev_buffer; diff --git a/trunk/drivers/spi/pxa2xx_spi_pci.c b/trunk/drivers/spi/pxa2xx_spi_pci.c index 19752b09e155..351d8a375b57 100644 --- a/trunk/drivers/spi/pxa2xx_spi_pci.c +++ b/trunk/drivers/spi/pxa2xx_spi_pci.c @@ -7,9 +7,10 @@ #include #include -struct ce4100_info { +struct awesome_struct { struct ssp_device ssp; - struct platform_device *spi_pdev; + struct platform_device spi_pdev; + struct pxa2xx_spi_master spi_pdata; }; static DEFINE_MUTEX(ssp_lock); @@ -50,15 +51,23 @@ void pxa_ssp_free(struct ssp_device *ssp) } EXPORT_SYMBOL_GPL(pxa_ssp_free); +static void plat_dev_release(struct device *dev) +{ + struct awesome_struct *as = container_of(dev, + struct awesome_struct, spi_pdev.dev); + + of_device_node_put(&as->spi_pdev.dev); +} + static int __devinit ce4100_spi_probe(struct pci_dev *dev, const struct pci_device_id *ent) { int ret; resource_size_t phys_beg; resource_size_t phys_len; - struct ce4100_info *spi_info; + struct awesome_struct *spi_info; struct platform_device *pdev; - struct pxa2xx_spi_master spi_pdata; + struct pxa2xx_spi_master *spi_pdata; struct ssp_device *ssp; ret = pci_enable_device(dev); @@ -75,30 +84,33 @@ static int __devinit ce4100_spi_probe(struct pci_dev *dev, return ret; } - pdev = platform_device_alloc("pxa2xx-spi", dev->devfn); spi_info = kzalloc(sizeof(*spi_info), GFP_KERNEL); - if (!pdev || !spi_info ) { + if (!spi_info) { ret = -ENOMEM; - goto err_nomem; + goto err_kz; } - memset(&spi_pdata, 0, sizeof(spi_pdata)); - spi_pdata.num_chipselect = dev->devfn; - - ret = platform_device_add_data(pdev, &spi_pdata, sizeof(spi_pdata)); - if (ret) - goto err_nomem; + ssp = &spi_info->ssp; + pdev = &spi_info->spi_pdev; + spi_pdata = &spi_info->spi_pdata; + pdev->name = "pxa2xx-spi"; + pdev->id = dev->devfn; pdev->dev.parent = &dev->dev; + pdev->dev.platform_data = &spi_info->spi_pdata; + #ifdef CONFIG_OF pdev->dev.of_node = dev->dev.of_node; #endif - ssp = &spi_info->ssp; + pdev->dev.release = plat_dev_release; + + spi_pdata->num_chipselect = dev->devfn; + ssp->phys_base = pci_resource_start(dev, 0); ssp->mmio_base = ioremap(phys_beg, phys_len); if (!ssp->mmio_base) { dev_err(&pdev->dev, "failed to ioremap() registers\n"); ret = -EIO; - goto err_nomem; + goto err_remap; } ssp->irq = dev->irq; ssp->port_id = pdev->id; @@ -110,7 +122,7 @@ static int __devinit ce4100_spi_probe(struct pci_dev *dev, pci_set_drvdata(dev, spi_info); - ret = platform_device_add(pdev); + ret = platform_device_register(pdev); if (ret) goto err_dev_add; @@ -123,21 +135,27 @@ static int __devinit ce4100_spi_probe(struct pci_dev *dev, mutex_unlock(&ssp_lock); iounmap(ssp->mmio_base); -err_nomem: - release_mem_region(phys_beg, phys_len); - platform_device_put(pdev); +err_remap: kfree(spi_info); + +err_kz: + release_mem_region(phys_beg, phys_len); + return ret; } static void __devexit ce4100_spi_remove(struct pci_dev *dev) { - struct ce4100_info *spi_info; + struct awesome_struct *spi_info; + struct platform_device *pdev; struct ssp_device *ssp; spi_info = pci_get_drvdata(dev); + ssp = &spi_info->ssp; - platform_device_unregister(spi_info->spi_pdev); + pdev = &spi_info->spi_pdev; + + platform_device_unregister(pdev); iounmap(ssp->mmio_base); release_mem_region(pci_resource_start(dev, 0), @@ -153,6 +171,7 @@ static void __devexit ce4100_spi_remove(struct pci_dev *dev) } static struct pci_device_id ce4100_spi_devices[] __devinitdata = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e6a) }, { }, }; diff --git a/trunk/drivers/target/Makefile b/trunk/drivers/target/Makefile index 973bb190ef57..5cfd70819f08 100644 --- a/trunk/drivers/target/Makefile +++ b/trunk/drivers/target/Makefile @@ -13,7 +13,8 @@ target_core_mod-y := target_core_configfs.o \ target_core_transport.o \ target_core_cdb.o \ target_core_ua.o \ - target_core_rd.o + target_core_rd.o \ + target_core_mib.o obj-$(CONFIG_TARGET_CORE) += target_core_mod.o diff --git a/trunk/drivers/target/target_core_configfs.c b/trunk/drivers/target/target_core_configfs.c index caf8dc18ee0a..2764510798b0 100644 --- a/trunk/drivers/target/target_core_configfs.c +++ b/trunk/drivers/target/target_core_configfs.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -1970,35 +1971,13 @@ static void target_core_dev_release(struct config_item *item) { struct se_subsystem_dev *se_dev = container_of(to_config_group(item), struct se_subsystem_dev, se_dev_group); - struct se_hba *hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item); - struct se_subsystem_api *t = hba->transport; - struct config_group *dev_cg = &se_dev->se_dev_group; + struct config_group *dev_cg; - kfree(dev_cg->default_groups); - /* - * This pointer will set when the storage is enabled with: - *`echo 1 > $CONFIGFS/core/$HBA/$DEV/dev_enable` - */ - if (se_dev->se_dev_ptr) { - printk(KERN_INFO "Target_Core_ConfigFS: Calling se_free_" - "virtual_device() for se_dev_ptr: %p\n", - se_dev->se_dev_ptr); - - se_free_virtual_device(se_dev->se_dev_ptr, hba); - } else { - /* - * Release struct se_subsystem_dev->se_dev_su_ptr.. - */ - printk(KERN_INFO "Target_Core_ConfigFS: Calling t->free_" - "device() for se_dev_su_ptr: %p\n", - se_dev->se_dev_su_ptr); - - t->free_device(se_dev->se_dev_su_ptr); - } + if (!(se_dev)) + return; - printk(KERN_INFO "Target_Core_ConfigFS: Deallocating se_subsystem" - "_dev_t: %p\n", se_dev); - kfree(se_dev); + dev_cg = &se_dev->se_dev_group; + kfree(dev_cg->default_groups); } static ssize_t target_core_dev_show(struct config_item *item, @@ -2161,16 +2140,7 @@ static struct configfs_attribute *target_core_alua_lu_gp_attrs[] = { NULL, }; -static void target_core_alua_lu_gp_release(struct config_item *item) -{ - struct t10_alua_lu_gp *lu_gp = container_of(to_config_group(item), - struct t10_alua_lu_gp, lu_gp_group); - - core_alua_free_lu_gp(lu_gp); -} - static struct configfs_item_operations target_core_alua_lu_gp_ops = { - .release = target_core_alua_lu_gp_release, .show_attribute = target_core_alua_lu_gp_attr_show, .store_attribute = target_core_alua_lu_gp_attr_store, }; @@ -2221,11 +2191,9 @@ static void target_core_alua_drop_lu_gp( printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Logical Unit" " Group: core/alua/lu_gps/%s, ID: %hu\n", config_item_name(item), lu_gp->lu_gp_id); - /* - * core_alua_free_lu_gp() is called from target_core_alua_lu_gp_ops->release() - * -> target_core_alua_lu_gp_release() - */ + config_item_put(item); + core_alua_free_lu_gp(lu_gp); } static struct configfs_group_operations target_core_alua_lu_gps_group_ops = { @@ -2581,16 +2549,7 @@ static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = { NULL, }; -static void target_core_alua_tg_pt_gp_release(struct config_item *item) -{ - struct t10_alua_tg_pt_gp *tg_pt_gp = container_of(to_config_group(item), - struct t10_alua_tg_pt_gp, tg_pt_gp_group); - - core_alua_free_tg_pt_gp(tg_pt_gp); -} - static struct configfs_item_operations target_core_alua_tg_pt_gp_ops = { - .release = target_core_alua_tg_pt_gp_release, .show_attribute = target_core_alua_tg_pt_gp_attr_show, .store_attribute = target_core_alua_tg_pt_gp_attr_store, }; @@ -2643,11 +2602,9 @@ static void target_core_alua_drop_tg_pt_gp( printk(KERN_INFO "Target_Core_ConfigFS: Releasing ALUA Target Port" " Group: alua/tg_pt_gps/%s, ID: %hu\n", config_item_name(item), tg_pt_gp->tg_pt_gp_id); - /* - * core_alua_free_tg_pt_gp() is called from target_core_alua_tg_pt_gp_ops->release() - * -> target_core_alua_tg_pt_gp_release(). - */ + config_item_put(item); + core_alua_free_tg_pt_gp(tg_pt_gp); } static struct configfs_group_operations target_core_alua_tg_pt_gps_group_ops = { @@ -2814,11 +2771,13 @@ static void target_core_drop_subdev( struct se_subsystem_api *t; struct config_item *df_item; struct config_group *dev_cg, *tg_pt_gp_cg; - int i; + int i, ret; hba = item_to_hba(&se_dev->se_dev_hba->hba_group.cg_item); - mutex_lock(&hba->hba_access_mutex); + if (mutex_lock_interruptible(&hba->hba_access_mutex)) + goto out; + t = hba->transport; spin_lock(&se_global->g_device_lock); @@ -2832,10 +2791,7 @@ static void target_core_drop_subdev( config_item_put(df_item); } kfree(tg_pt_gp_cg->default_groups); - /* - * core_alua_free_tg_pt_gp() is called from ->default_tg_pt_gp - * directly from target_core_alua_tg_pt_gp_release(). - */ + core_alua_free_tg_pt_gp(T10_ALUA(se_dev)->default_tg_pt_gp); T10_ALUA(se_dev)->default_tg_pt_gp = NULL; dev_cg = &se_dev->se_dev_group; @@ -2844,12 +2800,38 @@ static void target_core_drop_subdev( dev_cg->default_groups[i] = NULL; config_item_put(df_item); } + + config_item_put(item); /* - * The releasing of se_dev and associated se_dev->se_dev_ptr is done - * from target_core_dev_item_ops->release() ->target_core_dev_release(). + * This pointer will set when the storage is enabled with: + * `echo 1 > $CONFIGFS/core/$HBA/$DEV/dev_enable` */ - config_item_put(item); + if (se_dev->se_dev_ptr) { + printk(KERN_INFO "Target_Core_ConfigFS: Calling se_free_" + "virtual_device() for se_dev_ptr: %p\n", + se_dev->se_dev_ptr); + + ret = se_free_virtual_device(se_dev->se_dev_ptr, hba); + if (ret < 0) + goto hba_out; + } else { + /* + * Release struct se_subsystem_dev->se_dev_su_ptr.. + */ + printk(KERN_INFO "Target_Core_ConfigFS: Calling t->free_" + "device() for se_dev_su_ptr: %p\n", + se_dev->se_dev_su_ptr); + + t->free_device(se_dev->se_dev_su_ptr); + } + + printk(KERN_INFO "Target_Core_ConfigFS: Deallocating se_subsystem" + "_dev_t: %p\n", se_dev); + +hba_out: mutex_unlock(&hba->hba_access_mutex); +out: + kfree(se_dev); } static struct configfs_group_operations target_core_hba_group_ops = { @@ -2932,13 +2914,6 @@ SE_HBA_ATTR(hba_mode, S_IRUGO | S_IWUSR); CONFIGFS_EATTR_OPS(target_core_hba, se_hba, hba_group); -static void target_core_hba_release(struct config_item *item) -{ - struct se_hba *hba = container_of(to_config_group(item), - struct se_hba, hba_group); - core_delete_hba(hba); -} - static struct configfs_attribute *target_core_hba_attrs[] = { &target_core_hba_hba_info.attr, &target_core_hba_hba_mode.attr, @@ -2946,7 +2921,6 @@ static struct configfs_attribute *target_core_hba_attrs[] = { }; static struct configfs_item_operations target_core_hba_item_ops = { - .release = target_core_hba_release, .show_attribute = target_core_hba_attr_show, .store_attribute = target_core_hba_attr_store, }; @@ -3023,11 +2997,10 @@ static void target_core_call_delhbafromtarget( struct config_group *group, struct config_item *item) { - /* - * core_delete_hba() is called from target_core_hba_item_ops->release() - * -> target_core_hba_release() - */ + struct se_hba *hba = item_to_hba(item); + config_item_put(item); + core_delete_hba(hba); } static struct configfs_group_operations target_core_group_ops = { @@ -3049,6 +3022,7 @@ static int target_core_init_configfs(void) struct config_group *target_cg, *hba_cg = NULL, *alua_cg = NULL; struct config_group *lu_gp_cg = NULL; struct configfs_subsystem *subsys; + struct proc_dir_entry *scsi_target_proc = NULL; struct t10_alua_lu_gp *lu_gp; int ret; @@ -3154,10 +3128,21 @@ static int target_core_init_configfs(void) if (core_dev_setup_virtual_lun0() < 0) goto out; + scsi_target_proc = proc_mkdir("scsi_target", 0); + if (!(scsi_target_proc)) { + printk(KERN_ERR "proc_mkdir(scsi_target, 0) failed\n"); + goto out; + } + ret = init_scsi_target_mib(); + if (ret < 0) + goto out; + return 0; out: configfs_unregister_subsystem(subsys); + if (scsi_target_proc) + remove_proc_entry("scsi_target", 0); core_dev_release_virtual_lun0(); rd_module_exit(); out_global: @@ -3193,7 +3178,8 @@ static void target_core_exit_configfs(void) config_item_put(item); } kfree(lu_gp_cg->default_groups); - lu_gp_cg->default_groups = NULL; + core_alua_free_lu_gp(se_global->default_lu_gp); + se_global->default_lu_gp = NULL; alua_cg = &se_global->alua_group; for (i = 0; alua_cg->default_groups[i]; i++) { @@ -3202,7 +3188,6 @@ static void target_core_exit_configfs(void) config_item_put(item); } kfree(alua_cg->default_groups); - alua_cg->default_groups = NULL; hba_cg = &se_global->target_core_hbagroup; for (i = 0; hba_cg->default_groups[i]; i++) { @@ -3211,20 +3196,20 @@ static void target_core_exit_configfs(void) config_item_put(item); } kfree(hba_cg->default_groups); - hba_cg->default_groups = NULL; - /* - * We expect subsys->su_group.default_groups to be released - * by configfs subsystem provider logic.. - */ - configfs_unregister_subsystem(subsys); - kfree(subsys->su_group.default_groups); - core_alua_free_lu_gp(se_global->default_lu_gp); - se_global->default_lu_gp = NULL; + for (i = 0; subsys->su_group.default_groups[i]; i++) { + item = &subsys->su_group.default_groups[i]->cg_item; + subsys->su_group.default_groups[i] = NULL; + config_item_put(item); + } + kfree(subsys->su_group.default_groups); + configfs_unregister_subsystem(subsys); printk(KERN_INFO "TARGET_CORE[0]: Released ConfigFS Fabric" " Infrastructure\n"); + remove_scsi_target_mib(); + remove_proc_entry("scsi_target", 0); core_dev_release_virtual_lun0(); rd_module_exit(); release_se_global(); diff --git a/trunk/drivers/target/target_core_device.c b/trunk/drivers/target/target_core_device.c index 5da051a07fa3..317ce58d426d 100644 --- a/trunk/drivers/target/target_core_device.c +++ b/trunk/drivers/target/target_core_device.c @@ -373,11 +373,11 @@ int core_update_device_list_for_node( /* * deve->se_lun_acl will be NULL for demo-mode created LUNs * that have not been explictly concerted to MappedLUNs -> - * struct se_lun_acl, but we remove deve->alua_port_list from - * port->sep_alua_list. This also means that active UAs and - * NodeACL context specific PR metadata for demo-mode - * MappedLUN *deve will be released below.. + * struct se_lun_acl. */ + if (!(deve->se_lun_acl)) + return 0; + spin_lock_bh(&port->sep_alua_lock); list_del(&deve->alua_port_list); spin_unlock_bh(&port->sep_alua_lock); @@ -395,14 +395,12 @@ int core_update_device_list_for_node( printk(KERN_ERR "struct se_dev_entry->se_lun_acl" " already set for demo mode -> explict" " LUN ACL transition\n"); - spin_unlock_irq(&nacl->device_list_lock); return -1; } if (deve->se_lun != lun) { printk(KERN_ERR "struct se_dev_entry->se_lun does" " match passed struct se_lun for demo mode" " -> explict LUN ACL transition\n"); - spin_unlock_irq(&nacl->device_list_lock); return -1; } deve->se_lun_acl = lun_acl; @@ -867,6 +865,9 @@ static void se_dev_stop(struct se_device *dev) } } spin_unlock(&hba->device_lock); + + while (atomic_read(&hba->dev_mib_access_count)) + cpu_relax(); } int se_dev_check_online(struct se_device *dev) diff --git a/trunk/drivers/target/target_core_fabric_configfs.c b/trunk/drivers/target/target_core_fabric_configfs.c index b65d1c8e7740..32b148d7e261 100644 --- a/trunk/drivers/target/target_core_fabric_configfs.c +++ b/trunk/drivers/target/target_core_fabric_configfs.c @@ -214,22 +214,12 @@ TCM_MAPPEDLUN_ATTR(write_protect, S_IRUGO | S_IWUSR); CONFIGFS_EATTR_OPS(target_fabric_mappedlun, se_lun_acl, se_lun_group); -static void target_fabric_mappedlun_release(struct config_item *item) -{ - struct se_lun_acl *lacl = container_of(to_config_group(item), - struct se_lun_acl, se_lun_group); - struct se_portal_group *se_tpg = lacl->se_lun_nacl->se_tpg; - - core_dev_free_initiator_node_lun_acl(se_tpg, lacl); -} - static struct configfs_attribute *target_fabric_mappedlun_attrs[] = { &target_fabric_mappedlun_write_protect.attr, NULL, }; static struct configfs_item_operations target_fabric_mappedlun_item_ops = { - .release = target_fabric_mappedlun_release, .show_attribute = target_fabric_mappedlun_attr_show, .store_attribute = target_fabric_mappedlun_attr_store, .allow_link = target_fabric_mappedlun_link, @@ -347,21 +337,15 @@ static void target_fabric_drop_mappedlun( struct config_group *group, struct config_item *item) { - config_item_put(item); -} - -static void target_fabric_nacl_base_release(struct config_item *item) -{ - struct se_node_acl *se_nacl = container_of(to_config_group(item), - struct se_node_acl, acl_group); - struct se_portal_group *se_tpg = se_nacl->se_tpg; - struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; + struct se_lun_acl *lacl = container_of(to_config_group(item), + struct se_lun_acl, se_lun_group); + struct se_portal_group *se_tpg = lacl->se_lun_nacl->se_tpg; - tf->tf_ops.fabric_drop_nodeacl(se_nacl); + config_item_put(item); + core_dev_free_initiator_node_lun_acl(se_tpg, lacl); } static struct configfs_item_operations target_fabric_nacl_base_item_ops = { - .release = target_fabric_nacl_base_release, .show_attribute = target_fabric_nacl_base_attr_show, .store_attribute = target_fabric_nacl_base_attr_store, }; @@ -420,6 +404,9 @@ static void target_fabric_drop_nodeacl( struct config_group *group, struct config_item *item) { + struct se_portal_group *se_tpg = container_of(group, + struct se_portal_group, tpg_acl_group); + struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; struct se_node_acl *se_nacl = container_of(to_config_group(item), struct se_node_acl, acl_group); struct config_item *df_item; @@ -432,10 +419,9 @@ static void target_fabric_drop_nodeacl( nacl_cg->default_groups[i] = NULL; config_item_put(df_item); } - /* - * struct se_node_acl free is done in target_fabric_nacl_base_release() - */ + config_item_put(item); + tf->tf_ops.fabric_drop_nodeacl(se_nacl); } static struct configfs_group_operations target_fabric_nacl_group_ops = { @@ -451,18 +437,7 @@ TF_CIT_SETUP(tpg_nacl, NULL, &target_fabric_nacl_group_ops, NULL); CONFIGFS_EATTR_OPS(target_fabric_np_base, se_tpg_np, tpg_np_group); -static void target_fabric_np_base_release(struct config_item *item) -{ - struct se_tpg_np *se_tpg_np = container_of(to_config_group(item), - struct se_tpg_np, tpg_np_group); - struct se_portal_group *se_tpg = se_tpg_np->tpg_np_parent; - struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; - - tf->tf_ops.fabric_drop_np(se_tpg_np); -} - static struct configfs_item_operations target_fabric_np_base_item_ops = { - .release = target_fabric_np_base_release, .show_attribute = target_fabric_np_base_attr_show, .store_attribute = target_fabric_np_base_attr_store, }; @@ -491,7 +466,6 @@ static struct config_group *target_fabric_make_np( if (!(se_tpg_np) || IS_ERR(se_tpg_np)) return ERR_PTR(-EINVAL); - se_tpg_np->tpg_np_parent = se_tpg; config_group_init_type_name(&se_tpg_np->tpg_np_group, name, &TF_CIT_TMPL(tf)->tfc_tpg_np_base_cit); @@ -502,10 +476,14 @@ static void target_fabric_drop_np( struct config_group *group, struct config_item *item) { - /* - * struct se_tpg_np is released via target_fabric_np_base_release() - */ + struct se_portal_group *se_tpg = container_of(group, + struct se_portal_group, tpg_np_group); + struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf; + struct se_tpg_np *se_tpg_np = container_of(to_config_group(item), + struct se_tpg_np, tpg_np_group); + config_item_put(item); + tf->tf_ops.fabric_drop_np(se_tpg_np); } static struct configfs_group_operations target_fabric_np_group_ops = { @@ -836,18 +814,7 @@ TF_CIT_SETUP(tpg_param, &target_fabric_tpg_param_item_ops, NULL, NULL); */ CONFIGFS_EATTR_OPS(target_fabric_tpg, se_portal_group, tpg_group); -static void target_fabric_tpg_release(struct config_item *item) -{ - struct se_portal_group *se_tpg = container_of(to_config_group(item), - struct se_portal_group, tpg_group); - struct se_wwn *wwn = se_tpg->se_tpg_wwn; - struct target_fabric_configfs *tf = wwn->wwn_tf; - - tf->tf_ops.fabric_drop_tpg(se_tpg); -} - static struct configfs_item_operations target_fabric_tpg_base_item_ops = { - .release = target_fabric_tpg_release, .show_attribute = target_fabric_tpg_attr_show, .store_attribute = target_fabric_tpg_attr_store, }; @@ -905,6 +872,8 @@ static void target_fabric_drop_tpg( struct config_group *group, struct config_item *item) { + struct se_wwn *wwn = container_of(group, struct se_wwn, wwn_group); + struct target_fabric_configfs *tf = wwn->wwn_tf; struct se_portal_group *se_tpg = container_of(to_config_group(item), struct se_portal_group, tpg_group); struct config_group *tpg_cg = &se_tpg->tpg_group; @@ -921,28 +890,15 @@ static void target_fabric_drop_tpg( } config_item_put(item); + tf->tf_ops.fabric_drop_tpg(se_tpg); } -static void target_fabric_release_wwn(struct config_item *item) -{ - struct se_wwn *wwn = container_of(to_config_group(item), - struct se_wwn, wwn_group); - struct target_fabric_configfs *tf = wwn->wwn_tf; - - tf->tf_ops.fabric_drop_wwn(wwn); -} - -static struct configfs_item_operations target_fabric_tpg_item_ops = { - .release = target_fabric_release_wwn, -}; - static struct configfs_group_operations target_fabric_tpg_group_ops = { .make_group = target_fabric_make_tpg, .drop_item = target_fabric_drop_tpg, }; -TF_CIT_SETUP(tpg, &target_fabric_tpg_item_ops, &target_fabric_tpg_group_ops, - NULL); +TF_CIT_SETUP(tpg, NULL, &target_fabric_tpg_group_ops, NULL); /* End of tfc_tpg_cit */ @@ -976,7 +932,13 @@ static void target_fabric_drop_wwn( struct config_group *group, struct config_item *item) { + struct target_fabric_configfs *tf = container_of(group, + struct target_fabric_configfs, tf_group); + struct se_wwn *wwn = container_of(to_config_group(item), + struct se_wwn, wwn_group); + config_item_put(item); + tf->tf_ops.fabric_drop_wwn(wwn); } static struct configfs_group_operations target_fabric_wwn_group_ops = { diff --git a/trunk/drivers/target/target_core_iblock.c b/trunk/drivers/target/target_core_iblock.c index 67f0c09983c8..c6e0d757e76e 100644 --- a/trunk/drivers/target/target_core_iblock.c +++ b/trunk/drivers/target/target_core_iblock.c @@ -154,7 +154,7 @@ static struct se_device *iblock_create_virtdevice( bd = blkdev_get_by_path(ib_dev->ibd_udev_path, FMODE_WRITE|FMODE_READ|FMODE_EXCL, ib_dev); - if (IS_ERR(bd)) + if (!(bd)) goto failed; /* * Setup the local scope queue_limits from struct request_queue->limits @@ -220,10 +220,8 @@ static void iblock_free_device(void *p) { struct iblock_dev *ib_dev = p; - if (ib_dev->ibd_bd != NULL) - blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL); - if (ib_dev->ibd_bio_set != NULL) - bioset_free(ib_dev->ibd_bio_set); + blkdev_put(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ|FMODE_EXCL); + bioset_free(ib_dev->ibd_bio_set); kfree(ib_dev); } diff --git a/trunk/drivers/target/target_core_mib.c b/trunk/drivers/target/target_core_mib.c new file mode 100644 index 000000000000..d5a48aa0d2d1 --- /dev/null +++ b/trunk/drivers/target/target_core_mib.c @@ -0,0 +1,1078 @@ +/******************************************************************************* + * Filename: target_core_mib.c + * + * Copyright (c) 2006-2007 SBE, Inc. All Rights Reserved. + * Copyright (c) 2007-2010 Rising Tide Systems + * Copyright (c) 2008-2010 Linux-iSCSI.org + * + * Nicholas A. Bellinger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + ******************************************************************************/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "target_core_hba.h" +#include "target_core_mib.h" + +/* SCSI mib table index */ +static struct scsi_index_table scsi_index_table; + +#ifndef INITIAL_JIFFIES +#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ)) +#endif + +/* SCSI Instance Table */ +#define SCSI_INST_SW_INDEX 1 +#define SCSI_TRANSPORT_INDEX 1 + +#define NONE "None" +#define ISPRINT(a) ((a >= ' ') && (a <= '~')) + +static inline int list_is_first(const struct list_head *list, + const struct list_head *head) +{ + return list->prev == head; +} + +static void *locate_hba_start( + struct seq_file *seq, + loff_t *pos) +{ + spin_lock(&se_global->g_device_lock); + return seq_list_start(&se_global->g_se_dev_list, *pos); +} + +static void *locate_hba_next( + struct seq_file *seq, + void *v, + loff_t *pos) +{ + return seq_list_next(v, &se_global->g_se_dev_list, pos); +} + +static void locate_hba_stop(struct seq_file *seq, void *v) +{ + spin_unlock(&se_global->g_device_lock); +} + +/**************************************************************************** + * SCSI MIB Tables + ****************************************************************************/ + +/* + * SCSI Instance Table + */ +static void *scsi_inst_seq_start( + struct seq_file *seq, + loff_t *pos) +{ + spin_lock(&se_global->hba_lock); + return seq_list_start(&se_global->g_hba_list, *pos); +} + +static void *scsi_inst_seq_next( + struct seq_file *seq, + void *v, + loff_t *pos) +{ + return seq_list_next(v, &se_global->g_hba_list, pos); +} + +static void scsi_inst_seq_stop(struct seq_file *seq, void *v) +{ + spin_unlock(&se_global->hba_lock); +} + +static int scsi_inst_seq_show(struct seq_file *seq, void *v) +{ + struct se_hba *hba = list_entry(v, struct se_hba, hba_list); + + if (list_is_first(&hba->hba_list, &se_global->g_hba_list)) + seq_puts(seq, "inst sw_indx\n"); + + seq_printf(seq, "%u %u\n", hba->hba_index, SCSI_INST_SW_INDEX); + seq_printf(seq, "plugin: %s version: %s\n", + hba->transport->name, TARGET_CORE_VERSION); + + return 0; +} + +static const struct seq_operations scsi_inst_seq_ops = { + .start = scsi_inst_seq_start, + .next = scsi_inst_seq_next, + .stop = scsi_inst_seq_stop, + .show = scsi_inst_seq_show +}; + +static int scsi_inst_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &scsi_inst_seq_ops); +} + +static const struct file_operations scsi_inst_seq_fops = { + .owner = THIS_MODULE, + .open = scsi_inst_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/* + * SCSI Device Table + */ +static void *scsi_dev_seq_start(struct seq_file *seq, loff_t *pos) +{ + return locate_hba_start(seq, pos); +} + +static void *scsi_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + return locate_hba_next(seq, v, pos); +} + +static void scsi_dev_seq_stop(struct seq_file *seq, void *v) +{ + locate_hba_stop(seq, v); +} + +static int scsi_dev_seq_show(struct seq_file *seq, void *v) +{ + struct se_hba *hba; + struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, + g_se_dev_list); + struct se_device *dev = se_dev->se_dev_ptr; + char str[28]; + int k; + + if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) + seq_puts(seq, "inst indx role ports\n"); + + if (!(dev)) + return 0; + + hba = dev->se_hba; + if (!(hba)) { + /* Log error ? */ + return 0; + } + + seq_printf(seq, "%u %u %s %u\n", hba->hba_index, + dev->dev_index, "Target", dev->dev_port_count); + + memcpy(&str[0], (void *)DEV_T10_WWN(dev), 28); + + /* vendor */ + for (k = 0; k < 8; k++) + str[k] = ISPRINT(DEV_T10_WWN(dev)->vendor[k]) ? + DEV_T10_WWN(dev)->vendor[k] : 0x20; + str[k] = 0x20; + + /* model */ + for (k = 0; k < 16; k++) + str[k+9] = ISPRINT(DEV_T10_WWN(dev)->model[k]) ? + DEV_T10_WWN(dev)->model[k] : 0x20; + str[k + 9] = 0; + + seq_printf(seq, "dev_alias: %s\n", str); + + return 0; +} + +static const struct seq_operations scsi_dev_seq_ops = { + .start = scsi_dev_seq_start, + .next = scsi_dev_seq_next, + .stop = scsi_dev_seq_stop, + .show = scsi_dev_seq_show +}; + +static int scsi_dev_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &scsi_dev_seq_ops); +} + +static const struct file_operations scsi_dev_seq_fops = { + .owner = THIS_MODULE, + .open = scsi_dev_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/* + * SCSI Port Table + */ +static void *scsi_port_seq_start(struct seq_file *seq, loff_t *pos) +{ + return locate_hba_start(seq, pos); +} + +static void *scsi_port_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + return locate_hba_next(seq, v, pos); +} + +static void scsi_port_seq_stop(struct seq_file *seq, void *v) +{ + locate_hba_stop(seq, v); +} + +static int scsi_port_seq_show(struct seq_file *seq, void *v) +{ + struct se_hba *hba; + struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, + g_se_dev_list); + struct se_device *dev = se_dev->se_dev_ptr; + struct se_port *sep, *sep_tmp; + + if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) + seq_puts(seq, "inst device indx role busy_count\n"); + + if (!(dev)) + return 0; + + hba = dev->se_hba; + if (!(hba)) { + /* Log error ? */ + return 0; + } + + /* FIXME: scsiPortBusyStatuses count */ + spin_lock(&dev->se_port_lock); + list_for_each_entry_safe(sep, sep_tmp, &dev->dev_sep_list, sep_list) { + seq_printf(seq, "%u %u %u %s%u %u\n", hba->hba_index, + dev->dev_index, sep->sep_index, "Device", + dev->dev_index, 0); + } + spin_unlock(&dev->se_port_lock); + + return 0; +} + +static const struct seq_operations scsi_port_seq_ops = { + .start = scsi_port_seq_start, + .next = scsi_port_seq_next, + .stop = scsi_port_seq_stop, + .show = scsi_port_seq_show +}; + +static int scsi_port_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &scsi_port_seq_ops); +} + +static const struct file_operations scsi_port_seq_fops = { + .owner = THIS_MODULE, + .open = scsi_port_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/* + * SCSI Transport Table + */ +static void *scsi_transport_seq_start(struct seq_file *seq, loff_t *pos) +{ + return locate_hba_start(seq, pos); +} + +static void *scsi_transport_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + return locate_hba_next(seq, v, pos); +} + +static void scsi_transport_seq_stop(struct seq_file *seq, void *v) +{ + locate_hba_stop(seq, v); +} + +static int scsi_transport_seq_show(struct seq_file *seq, void *v) +{ + struct se_hba *hba; + struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, + g_se_dev_list); + struct se_device *dev = se_dev->se_dev_ptr; + struct se_port *se, *se_tmp; + struct se_portal_group *tpg; + struct t10_wwn *wwn; + char buf[64]; + + if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) + seq_puts(seq, "inst device indx dev_name\n"); + + if (!(dev)) + return 0; + + hba = dev->se_hba; + if (!(hba)) { + /* Log error ? */ + return 0; + } + + wwn = DEV_T10_WWN(dev); + + spin_lock(&dev->se_port_lock); + list_for_each_entry_safe(se, se_tmp, &dev->dev_sep_list, sep_list) { + tpg = se->sep_tpg; + sprintf(buf, "scsiTransport%s", + TPG_TFO(tpg)->get_fabric_name()); + + seq_printf(seq, "%u %s %u %s+%s\n", + hba->hba_index, /* scsiTransportIndex */ + buf, /* scsiTransportType */ + (TPG_TFO(tpg)->tpg_get_inst_index != NULL) ? + TPG_TFO(tpg)->tpg_get_inst_index(tpg) : + 0, + TPG_TFO(tpg)->tpg_get_wwn(tpg), + (strlen(wwn->unit_serial)) ? + /* scsiTransportDevName */ + wwn->unit_serial : wwn->vendor); + } + spin_unlock(&dev->se_port_lock); + + return 0; +} + +static const struct seq_operations scsi_transport_seq_ops = { + .start = scsi_transport_seq_start, + .next = scsi_transport_seq_next, + .stop = scsi_transport_seq_stop, + .show = scsi_transport_seq_show +}; + +static int scsi_transport_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &scsi_transport_seq_ops); +} + +static const struct file_operations scsi_transport_seq_fops = { + .owner = THIS_MODULE, + .open = scsi_transport_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/* + * SCSI Target Device Table + */ +static void *scsi_tgt_dev_seq_start(struct seq_file *seq, loff_t *pos) +{ + return locate_hba_start(seq, pos); +} + +static void *scsi_tgt_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + return locate_hba_next(seq, v, pos); +} + +static void scsi_tgt_dev_seq_stop(struct seq_file *seq, void *v) +{ + locate_hba_stop(seq, v); +} + + +#define LU_COUNT 1 /* for now */ +static int scsi_tgt_dev_seq_show(struct seq_file *seq, void *v) +{ + struct se_hba *hba; + struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, + g_se_dev_list); + struct se_device *dev = se_dev->se_dev_ptr; + int non_accessible_lus = 0; + char status[16]; + + if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) + seq_puts(seq, "inst indx num_LUs status non_access_LUs" + " resets\n"); + + if (!(dev)) + return 0; + + hba = dev->se_hba; + if (!(hba)) { + /* Log error ? */ + return 0; + } + + switch (dev->dev_status) { + case TRANSPORT_DEVICE_ACTIVATED: + strcpy(status, "activated"); + break; + case TRANSPORT_DEVICE_DEACTIVATED: + strcpy(status, "deactivated"); + non_accessible_lus = 1; + break; + case TRANSPORT_DEVICE_SHUTDOWN: + strcpy(status, "shutdown"); + non_accessible_lus = 1; + break; + case TRANSPORT_DEVICE_OFFLINE_ACTIVATED: + case TRANSPORT_DEVICE_OFFLINE_DEACTIVATED: + strcpy(status, "offline"); + non_accessible_lus = 1; + break; + default: + sprintf(status, "unknown(%d)", dev->dev_status); + non_accessible_lus = 1; + } + + seq_printf(seq, "%u %u %u %s %u %u\n", + hba->hba_index, dev->dev_index, LU_COUNT, + status, non_accessible_lus, dev->num_resets); + + return 0; +} + +static const struct seq_operations scsi_tgt_dev_seq_ops = { + .start = scsi_tgt_dev_seq_start, + .next = scsi_tgt_dev_seq_next, + .stop = scsi_tgt_dev_seq_stop, + .show = scsi_tgt_dev_seq_show +}; + +static int scsi_tgt_dev_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &scsi_tgt_dev_seq_ops); +} + +static const struct file_operations scsi_tgt_dev_seq_fops = { + .owner = THIS_MODULE, + .open = scsi_tgt_dev_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/* + * SCSI Target Port Table + */ +static void *scsi_tgt_port_seq_start(struct seq_file *seq, loff_t *pos) +{ + return locate_hba_start(seq, pos); +} + +static void *scsi_tgt_port_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + return locate_hba_next(seq, v, pos); +} + +static void scsi_tgt_port_seq_stop(struct seq_file *seq, void *v) +{ + locate_hba_stop(seq, v); +} + +static int scsi_tgt_port_seq_show(struct seq_file *seq, void *v) +{ + struct se_hba *hba; + struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, + g_se_dev_list); + struct se_device *dev = se_dev->se_dev_ptr; + struct se_port *sep, *sep_tmp; + struct se_portal_group *tpg; + u32 rx_mbytes, tx_mbytes; + unsigned long long num_cmds; + char buf[64]; + + if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) + seq_puts(seq, "inst device indx name port_index in_cmds" + " write_mbytes read_mbytes hs_in_cmds\n"); + + if (!(dev)) + return 0; + + hba = dev->se_hba; + if (!(hba)) { + /* Log error ? */ + return 0; + } + + spin_lock(&dev->se_port_lock); + list_for_each_entry_safe(sep, sep_tmp, &dev->dev_sep_list, sep_list) { + tpg = sep->sep_tpg; + sprintf(buf, "%sPort#", + TPG_TFO(tpg)->get_fabric_name()); + + seq_printf(seq, "%u %u %u %s%d %s%s%d ", + hba->hba_index, + dev->dev_index, + sep->sep_index, + buf, sep->sep_index, + TPG_TFO(tpg)->tpg_get_wwn(tpg), "+t+", + TPG_TFO(tpg)->tpg_get_tag(tpg)); + + spin_lock(&sep->sep_lun->lun_sep_lock); + num_cmds = sep->sep_stats.cmd_pdus; + rx_mbytes = (sep->sep_stats.rx_data_octets >> 20); + tx_mbytes = (sep->sep_stats.tx_data_octets >> 20); + spin_unlock(&sep->sep_lun->lun_sep_lock); + + seq_printf(seq, "%llu %u %u %u\n", num_cmds, + rx_mbytes, tx_mbytes, 0); + } + spin_unlock(&dev->se_port_lock); + + return 0; +} + +static const struct seq_operations scsi_tgt_port_seq_ops = { + .start = scsi_tgt_port_seq_start, + .next = scsi_tgt_port_seq_next, + .stop = scsi_tgt_port_seq_stop, + .show = scsi_tgt_port_seq_show +}; + +static int scsi_tgt_port_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &scsi_tgt_port_seq_ops); +} + +static const struct file_operations scsi_tgt_port_seq_fops = { + .owner = THIS_MODULE, + .open = scsi_tgt_port_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/* + * SCSI Authorized Initiator Table: + * It contains the SCSI Initiators authorized to be attached to one of the + * local Target ports. + * Iterates through all active TPGs and extracts the info from the ACLs + */ +static void *scsi_auth_intr_seq_start(struct seq_file *seq, loff_t *pos) +{ + spin_lock_bh(&se_global->se_tpg_lock); + return seq_list_start(&se_global->g_se_tpg_list, *pos); +} + +static void *scsi_auth_intr_seq_next(struct seq_file *seq, void *v, + loff_t *pos) +{ + return seq_list_next(v, &se_global->g_se_tpg_list, pos); +} + +static void scsi_auth_intr_seq_stop(struct seq_file *seq, void *v) +{ + spin_unlock_bh(&se_global->se_tpg_lock); +} + +static int scsi_auth_intr_seq_show(struct seq_file *seq, void *v) +{ + struct se_portal_group *se_tpg = list_entry(v, struct se_portal_group, + se_tpg_list); + struct se_dev_entry *deve; + struct se_lun *lun; + struct se_node_acl *se_nacl; + int j; + + if (list_is_first(&se_tpg->se_tpg_list, + &se_global->g_se_tpg_list)) + seq_puts(seq, "inst dev port indx dev_or_port intr_name " + "map_indx att_count num_cmds read_mbytes " + "write_mbytes hs_num_cmds creation_time row_status\n"); + + if (!(se_tpg)) + return 0; + + spin_lock(&se_tpg->acl_node_lock); + list_for_each_entry(se_nacl, &se_tpg->acl_node_list, acl_list) { + + atomic_inc(&se_nacl->mib_ref_count); + smp_mb__after_atomic_inc(); + spin_unlock(&se_tpg->acl_node_lock); + + spin_lock_irq(&se_nacl->device_list_lock); + for (j = 0; j < TRANSPORT_MAX_LUNS_PER_TPG; j++) { + deve = &se_nacl->device_list[j]; + if (!(deve->lun_flags & + TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) || + (!deve->se_lun)) + continue; + lun = deve->se_lun; + if (!lun->lun_se_dev) + continue; + + seq_printf(seq, "%u %u %u %u %u %s %u %u %u %u %u %u" + " %u %s\n", + /* scsiInstIndex */ + (TPG_TFO(se_tpg)->tpg_get_inst_index != NULL) ? + TPG_TFO(se_tpg)->tpg_get_inst_index(se_tpg) : + 0, + /* scsiDeviceIndex */ + lun->lun_se_dev->dev_index, + /* scsiAuthIntrTgtPortIndex */ + TPG_TFO(se_tpg)->tpg_get_tag(se_tpg), + /* scsiAuthIntrIndex */ + se_nacl->acl_index, + /* scsiAuthIntrDevOrPort */ + 1, + /* scsiAuthIntrName */ + se_nacl->initiatorname[0] ? + se_nacl->initiatorname : NONE, + /* FIXME: scsiAuthIntrLunMapIndex */ + 0, + /* scsiAuthIntrAttachedTimes */ + deve->attach_count, + /* scsiAuthIntrOutCommands */ + deve->total_cmds, + /* scsiAuthIntrReadMegaBytes */ + (u32)(deve->read_bytes >> 20), + /* scsiAuthIntrWrittenMegaBytes */ + (u32)(deve->write_bytes >> 20), + /* FIXME: scsiAuthIntrHSOutCommands */ + 0, + /* scsiAuthIntrLastCreation */ + (u32)(((u32)deve->creation_time - + INITIAL_JIFFIES) * 100 / HZ), + /* FIXME: scsiAuthIntrRowStatus */ + "Ready"); + } + spin_unlock_irq(&se_nacl->device_list_lock); + + spin_lock(&se_tpg->acl_node_lock); + atomic_dec(&se_nacl->mib_ref_count); + smp_mb__after_atomic_dec(); + } + spin_unlock(&se_tpg->acl_node_lock); + + return 0; +} + +static const struct seq_operations scsi_auth_intr_seq_ops = { + .start = scsi_auth_intr_seq_start, + .next = scsi_auth_intr_seq_next, + .stop = scsi_auth_intr_seq_stop, + .show = scsi_auth_intr_seq_show +}; + +static int scsi_auth_intr_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &scsi_auth_intr_seq_ops); +} + +static const struct file_operations scsi_auth_intr_seq_fops = { + .owner = THIS_MODULE, + .open = scsi_auth_intr_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/* + * SCSI Attached Initiator Port Table: + * It lists the SCSI Initiators attached to one of the local Target ports. + * Iterates through all active TPGs and use active sessions from each TPG + * to list the info fo this table. + */ +static void *scsi_att_intr_port_seq_start(struct seq_file *seq, loff_t *pos) +{ + spin_lock_bh(&se_global->se_tpg_lock); + return seq_list_start(&se_global->g_se_tpg_list, *pos); +} + +static void *scsi_att_intr_port_seq_next(struct seq_file *seq, void *v, + loff_t *pos) +{ + return seq_list_next(v, &se_global->g_se_tpg_list, pos); +} + +static void scsi_att_intr_port_seq_stop(struct seq_file *seq, void *v) +{ + spin_unlock_bh(&se_global->se_tpg_lock); +} + +static int scsi_att_intr_port_seq_show(struct seq_file *seq, void *v) +{ + struct se_portal_group *se_tpg = list_entry(v, struct se_portal_group, + se_tpg_list); + struct se_dev_entry *deve; + struct se_lun *lun; + struct se_node_acl *se_nacl; + struct se_session *se_sess; + unsigned char buf[64]; + int j; + + if (list_is_first(&se_tpg->se_tpg_list, + &se_global->g_se_tpg_list)) + seq_puts(seq, "inst dev port indx port_auth_indx port_name" + " port_ident\n"); + + if (!(se_tpg)) + return 0; + + spin_lock(&se_tpg->session_lock); + list_for_each_entry(se_sess, &se_tpg->tpg_sess_list, sess_list) { + if ((TPG_TFO(se_tpg)->sess_logged_in(se_sess)) || + (!se_sess->se_node_acl) || + (!se_sess->se_node_acl->device_list)) + continue; + + atomic_inc(&se_sess->mib_ref_count); + smp_mb__after_atomic_inc(); + se_nacl = se_sess->se_node_acl; + atomic_inc(&se_nacl->mib_ref_count); + smp_mb__after_atomic_inc(); + spin_unlock(&se_tpg->session_lock); + + spin_lock_irq(&se_nacl->device_list_lock); + for (j = 0; j < TRANSPORT_MAX_LUNS_PER_TPG; j++) { + deve = &se_nacl->device_list[j]; + if (!(deve->lun_flags & + TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) || + (!deve->se_lun)) + continue; + + lun = deve->se_lun; + if (!lun->lun_se_dev) + continue; + + memset(buf, 0, 64); + if (TPG_TFO(se_tpg)->sess_get_initiator_sid != NULL) + TPG_TFO(se_tpg)->sess_get_initiator_sid( + se_sess, (unsigned char *)&buf[0], 64); + + seq_printf(seq, "%u %u %u %u %u %s+i+%s\n", + /* scsiInstIndex */ + (TPG_TFO(se_tpg)->tpg_get_inst_index != NULL) ? + TPG_TFO(se_tpg)->tpg_get_inst_index(se_tpg) : + 0, + /* scsiDeviceIndex */ + lun->lun_se_dev->dev_index, + /* scsiPortIndex */ + TPG_TFO(se_tpg)->tpg_get_tag(se_tpg), + /* scsiAttIntrPortIndex */ + (TPG_TFO(se_tpg)->sess_get_index != NULL) ? + TPG_TFO(se_tpg)->sess_get_index(se_sess) : + 0, + /* scsiAttIntrPortAuthIntrIdx */ + se_nacl->acl_index, + /* scsiAttIntrPortName */ + se_nacl->initiatorname[0] ? + se_nacl->initiatorname : NONE, + /* scsiAttIntrPortIdentifier */ + buf); + } + spin_unlock_irq(&se_nacl->device_list_lock); + + spin_lock(&se_tpg->session_lock); + atomic_dec(&se_nacl->mib_ref_count); + smp_mb__after_atomic_dec(); + atomic_dec(&se_sess->mib_ref_count); + smp_mb__after_atomic_dec(); + } + spin_unlock(&se_tpg->session_lock); + + return 0; +} + +static const struct seq_operations scsi_att_intr_port_seq_ops = { + .start = scsi_att_intr_port_seq_start, + .next = scsi_att_intr_port_seq_next, + .stop = scsi_att_intr_port_seq_stop, + .show = scsi_att_intr_port_seq_show +}; + +static int scsi_att_intr_port_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &scsi_att_intr_port_seq_ops); +} + +static const struct file_operations scsi_att_intr_port_seq_fops = { + .owner = THIS_MODULE, + .open = scsi_att_intr_port_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/* + * SCSI Logical Unit Table + */ +static void *scsi_lu_seq_start(struct seq_file *seq, loff_t *pos) +{ + return locate_hba_start(seq, pos); +} + +static void *scsi_lu_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + return locate_hba_next(seq, v, pos); +} + +static void scsi_lu_seq_stop(struct seq_file *seq, void *v) +{ + locate_hba_stop(seq, v); +} + +#define SCSI_LU_INDEX 1 +static int scsi_lu_seq_show(struct seq_file *seq, void *v) +{ + struct se_hba *hba; + struct se_subsystem_dev *se_dev = list_entry(v, struct se_subsystem_dev, + g_se_dev_list); + struct se_device *dev = se_dev->se_dev_ptr; + int j; + char str[28]; + + if (list_is_first(&se_dev->g_se_dev_list, &se_global->g_se_dev_list)) + seq_puts(seq, "inst dev indx LUN lu_name vend prod rev" + " dev_type status state-bit num_cmds read_mbytes" + " write_mbytes resets full_stat hs_num_cmds creation_time\n"); + + if (!(dev)) + return 0; + + hba = dev->se_hba; + if (!(hba)) { + /* Log error ? */ + return 0; + } + + /* Fix LU state, if we can read it from the device */ + seq_printf(seq, "%u %u %u %llu %s", hba->hba_index, + dev->dev_index, SCSI_LU_INDEX, + (unsigned long long)0, /* FIXME: scsiLuDefaultLun */ + (strlen(DEV_T10_WWN(dev)->unit_serial)) ? + /* scsiLuWwnName */ + (char *)&DEV_T10_WWN(dev)->unit_serial[0] : + "None"); + + memcpy(&str[0], (void *)DEV_T10_WWN(dev), 28); + /* scsiLuVendorId */ + for (j = 0; j < 8; j++) + str[j] = ISPRINT(DEV_T10_WWN(dev)->vendor[j]) ? + DEV_T10_WWN(dev)->vendor[j] : 0x20; + str[8] = 0; + seq_printf(seq, " %s", str); + + /* scsiLuProductId */ + for (j = 0; j < 16; j++) + str[j] = ISPRINT(DEV_T10_WWN(dev)->model[j]) ? + DEV_T10_WWN(dev)->model[j] : 0x20; + str[16] = 0; + seq_printf(seq, " %s", str); + + /* scsiLuRevisionId */ + for (j = 0; j < 4; j++) + str[j] = ISPRINT(DEV_T10_WWN(dev)->revision[j]) ? + DEV_T10_WWN(dev)->revision[j] : 0x20; + str[4] = 0; + seq_printf(seq, " %s", str); + + seq_printf(seq, " %u %s %s %llu %u %u %u %u %u %u\n", + /* scsiLuPeripheralType */ + TRANSPORT(dev)->get_device_type(dev), + (dev->dev_status == TRANSPORT_DEVICE_ACTIVATED) ? + "available" : "notavailable", /* scsiLuStatus */ + "exposed", /* scsiLuState */ + (unsigned long long)dev->num_cmds, + /* scsiLuReadMegaBytes */ + (u32)(dev->read_bytes >> 20), + /* scsiLuWrittenMegaBytes */ + (u32)(dev->write_bytes >> 20), + dev->num_resets, /* scsiLuInResets */ + 0, /* scsiLuOutTaskSetFullStatus */ + 0, /* scsiLuHSInCommands */ + (u32)(((u32)dev->creation_time - INITIAL_JIFFIES) * + 100 / HZ)); + + return 0; +} + +static const struct seq_operations scsi_lu_seq_ops = { + .start = scsi_lu_seq_start, + .next = scsi_lu_seq_next, + .stop = scsi_lu_seq_stop, + .show = scsi_lu_seq_show +}; + +static int scsi_lu_seq_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &scsi_lu_seq_ops); +} + +static const struct file_operations scsi_lu_seq_fops = { + .owner = THIS_MODULE, + .open = scsi_lu_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +/****************************************************************************/ + +/* + * Remove proc fs entries + */ +void remove_scsi_target_mib(void) +{ + remove_proc_entry("scsi_target/mib/scsi_inst", NULL); + remove_proc_entry("scsi_target/mib/scsi_dev", NULL); + remove_proc_entry("scsi_target/mib/scsi_port", NULL); + remove_proc_entry("scsi_target/mib/scsi_transport", NULL); + remove_proc_entry("scsi_target/mib/scsi_tgt_dev", NULL); + remove_proc_entry("scsi_target/mib/scsi_tgt_port", NULL); + remove_proc_entry("scsi_target/mib/scsi_auth_intr", NULL); + remove_proc_entry("scsi_target/mib/scsi_att_intr_port", NULL); + remove_proc_entry("scsi_target/mib/scsi_lu", NULL); + remove_proc_entry("scsi_target/mib", NULL); +} + +/* + * Create proc fs entries for the mib tables + */ +int init_scsi_target_mib(void) +{ + struct proc_dir_entry *dir_entry; + struct proc_dir_entry *scsi_inst_entry; + struct proc_dir_entry *scsi_dev_entry; + struct proc_dir_entry *scsi_port_entry; + struct proc_dir_entry *scsi_transport_entry; + struct proc_dir_entry *scsi_tgt_dev_entry; + struct proc_dir_entry *scsi_tgt_port_entry; + struct proc_dir_entry *scsi_auth_intr_entry; + struct proc_dir_entry *scsi_att_intr_port_entry; + struct proc_dir_entry *scsi_lu_entry; + + dir_entry = proc_mkdir("scsi_target/mib", NULL); + if (!(dir_entry)) { + printk(KERN_ERR "proc_mkdir() failed.\n"); + return -1; + } + + scsi_inst_entry = + create_proc_entry("scsi_target/mib/scsi_inst", 0, NULL); + if (scsi_inst_entry) + scsi_inst_entry->proc_fops = &scsi_inst_seq_fops; + else + goto error; + + scsi_dev_entry = + create_proc_entry("scsi_target/mib/scsi_dev", 0, NULL); + if (scsi_dev_entry) + scsi_dev_entry->proc_fops = &scsi_dev_seq_fops; + else + goto error; + + scsi_port_entry = + create_proc_entry("scsi_target/mib/scsi_port", 0, NULL); + if (scsi_port_entry) + scsi_port_entry->proc_fops = &scsi_port_seq_fops; + else + goto error; + + scsi_transport_entry = + create_proc_entry("scsi_target/mib/scsi_transport", 0, NULL); + if (scsi_transport_entry) + scsi_transport_entry->proc_fops = &scsi_transport_seq_fops; + else + goto error; + + scsi_tgt_dev_entry = + create_proc_entry("scsi_target/mib/scsi_tgt_dev", 0, NULL); + if (scsi_tgt_dev_entry) + scsi_tgt_dev_entry->proc_fops = &scsi_tgt_dev_seq_fops; + else + goto error; + + scsi_tgt_port_entry = + create_proc_entry("scsi_target/mib/scsi_tgt_port", 0, NULL); + if (scsi_tgt_port_entry) + scsi_tgt_port_entry->proc_fops = &scsi_tgt_port_seq_fops; + else + goto error; + + scsi_auth_intr_entry = + create_proc_entry("scsi_target/mib/scsi_auth_intr", 0, NULL); + if (scsi_auth_intr_entry) + scsi_auth_intr_entry->proc_fops = &scsi_auth_intr_seq_fops; + else + goto error; + + scsi_att_intr_port_entry = + create_proc_entry("scsi_target/mib/scsi_att_intr_port", 0, NULL); + if (scsi_att_intr_port_entry) + scsi_att_intr_port_entry->proc_fops = + &scsi_att_intr_port_seq_fops; + else + goto error; + + scsi_lu_entry = create_proc_entry("scsi_target/mib/scsi_lu", 0, NULL); + if (scsi_lu_entry) + scsi_lu_entry->proc_fops = &scsi_lu_seq_fops; + else + goto error; + + return 0; + +error: + printk(KERN_ERR "create_proc_entry() failed.\n"); + remove_scsi_target_mib(); + return -1; +} + +/* + * Initialize the index table for allocating unique row indexes to various mib + * tables + */ +void init_scsi_index_table(void) +{ + memset(&scsi_index_table, 0, sizeof(struct scsi_index_table)); + spin_lock_init(&scsi_index_table.lock); +} + +/* + * Allocate a new row index for the entry type specified + */ +u32 scsi_get_new_index(scsi_index_t type) +{ + u32 new_index; + + if ((type < 0) || (type >= SCSI_INDEX_TYPE_MAX)) { + printk(KERN_ERR "Invalid index type %d\n", type); + return -1; + } + + spin_lock(&scsi_index_table.lock); + new_index = ++scsi_index_table.scsi_mib_index[type]; + if (new_index == 0) + new_index = ++scsi_index_table.scsi_mib_index[type]; + spin_unlock(&scsi_index_table.lock); + + return new_index; +} +EXPORT_SYMBOL(scsi_get_new_index); diff --git a/trunk/drivers/target/target_core_mib.h b/trunk/drivers/target/target_core_mib.h new file mode 100644 index 000000000000..277204633850 --- /dev/null +++ b/trunk/drivers/target/target_core_mib.h @@ -0,0 +1,28 @@ +#ifndef TARGET_CORE_MIB_H +#define TARGET_CORE_MIB_H + +typedef enum { + SCSI_INST_INDEX, + SCSI_DEVICE_INDEX, + SCSI_AUTH_INTR_INDEX, + SCSI_INDEX_TYPE_MAX +} scsi_index_t; + +struct scsi_index_table { + spinlock_t lock; + u32 scsi_mib_index[SCSI_INDEX_TYPE_MAX]; +} ____cacheline_aligned; + +/* SCSI Port stats */ +struct scsi_port_stats { + u64 cmd_pdus; + u64 tx_data_octets; + u64 rx_data_octets; +} ____cacheline_aligned; + +extern int init_scsi_target_mib(void); +extern void remove_scsi_target_mib(void); +extern void init_scsi_index_table(void); +extern u32 scsi_get_new_index(scsi_index_t); + +#endif /*** TARGET_CORE_MIB_H ***/ diff --git a/trunk/drivers/target/target_core_pscsi.c b/trunk/drivers/target/target_core_pscsi.c index f2a08477a68c..742d24609a9b 100644 --- a/trunk/drivers/target/target_core_pscsi.c +++ b/trunk/drivers/target/target_core_pscsi.c @@ -462,8 +462,8 @@ static struct se_device *pscsi_create_type_disk( */ bd = blkdev_get_by_path(se_dev->se_dev_udev_path, FMODE_WRITE|FMODE_READ|FMODE_EXCL, pdv); - if (IS_ERR(bd)) { - printk(KERN_ERR "pSCSI: blkdev_get_by_path() failed\n"); + if (!(bd)) { + printk("pSCSI: blkdev_get_by_path() failed\n"); scsi_device_put(sd); return NULL; } diff --git a/trunk/drivers/target/target_core_tpg.c b/trunk/drivers/target/target_core_tpg.c index c26f67467623..abfa81a57115 100644 --- a/trunk/drivers/target/target_core_tpg.c +++ b/trunk/drivers/target/target_core_tpg.c @@ -275,6 +275,7 @@ struct se_node_acl *core_tpg_check_initiator_node_acl( spin_lock_init(&acl->device_list_lock); spin_lock_init(&acl->nacl_sess_lock); atomic_set(&acl->acl_pr_ref_count, 0); + atomic_set(&acl->mib_ref_count, 0); acl->queue_depth = TPG_TFO(tpg)->tpg_get_default_depth(tpg); snprintf(acl->initiatorname, TRANSPORT_IQN_LEN, "%s", initiatorname); acl->se_tpg = tpg; @@ -317,6 +318,12 @@ void core_tpg_wait_for_nacl_pr_ref(struct se_node_acl *nacl) cpu_relax(); } +void core_tpg_wait_for_mib_ref(struct se_node_acl *nacl) +{ + while (atomic_read(&nacl->mib_ref_count) != 0) + cpu_relax(); +} + void core_tpg_clear_object_luns(struct se_portal_group *tpg) { int i, ret; @@ -473,6 +480,7 @@ int core_tpg_del_initiator_node_acl( spin_unlock_bh(&tpg->session_lock); core_tpg_wait_for_nacl_pr_ref(acl); + core_tpg_wait_for_mib_ref(acl); core_clear_initiator_node_from_tpg(acl, tpg); core_free_device_list_for_node(acl, tpg); @@ -693,8 +701,6 @@ EXPORT_SYMBOL(core_tpg_register); int core_tpg_deregister(struct se_portal_group *se_tpg) { - struct se_node_acl *nacl, *nacl_tmp; - printk(KERN_INFO "TARGET_CORE[%s]: Deallocating %s struct se_portal_group" " for endpoint: %s Portal Tag %u\n", (se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL) ? @@ -708,25 +714,6 @@ int core_tpg_deregister(struct se_portal_group *se_tpg) while (atomic_read(&se_tpg->tpg_pr_ref_count) != 0) cpu_relax(); - /* - * Release any remaining demo-mode generated se_node_acl that have - * not been released because of TFO->tpg_check_demo_mode_cache() == 1 - * in transport_deregister_session(). - */ - spin_lock_bh(&se_tpg->acl_node_lock); - list_for_each_entry_safe(nacl, nacl_tmp, &se_tpg->acl_node_list, - acl_list) { - list_del(&nacl->acl_list); - se_tpg->num_node_acls--; - spin_unlock_bh(&se_tpg->acl_node_lock); - - core_tpg_wait_for_nacl_pr_ref(nacl); - core_free_device_list_for_node(nacl, se_tpg); - TPG_TFO(se_tpg)->tpg_release_fabric_acl(se_tpg, nacl); - - spin_lock_bh(&se_tpg->acl_node_lock); - } - spin_unlock_bh(&se_tpg->acl_node_lock); if (se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL) core_tpg_release_virtual_lun0(se_tpg); diff --git a/trunk/drivers/target/target_core_transport.c b/trunk/drivers/target/target_core_transport.c index 236e22d8cfae..28b6292ff298 100644 --- a/trunk/drivers/target/target_core_transport.c +++ b/trunk/drivers/target/target_core_transport.c @@ -379,40 +379,6 @@ void release_se_global(void) se_global = NULL; } -/* SCSI statistics table index */ -static struct scsi_index_table scsi_index_table; - -/* - * Initialize the index table for allocating unique row indexes to various mib - * tables. - */ -void init_scsi_index_table(void) -{ - memset(&scsi_index_table, 0, sizeof(struct scsi_index_table)); - spin_lock_init(&scsi_index_table.lock); -} - -/* - * Allocate a new row index for the entry type specified - */ -u32 scsi_get_new_index(scsi_index_t type) -{ - u32 new_index; - - if ((type < 0) || (type >= SCSI_INDEX_TYPE_MAX)) { - printk(KERN_ERR "Invalid index type %d\n", type); - return -EINVAL; - } - - spin_lock(&scsi_index_table.lock); - new_index = ++scsi_index_table.scsi_mib_index[type]; - if (new_index == 0) - new_index = ++scsi_index_table.scsi_mib_index[type]; - spin_unlock(&scsi_index_table.lock); - - return new_index; -} - void transport_init_queue_obj(struct se_queue_obj *qobj) { atomic_set(&qobj->queue_cnt, 0); @@ -471,6 +437,7 @@ struct se_session *transport_init_session(void) } INIT_LIST_HEAD(&se_sess->sess_list); INIT_LIST_HEAD(&se_sess->sess_acl_list); + atomic_set(&se_sess->mib_ref_count, 0); return se_sess; } @@ -579,6 +546,12 @@ void transport_deregister_session(struct se_session *se_sess) transport_free_session(se_sess); return; } + /* + * Wait for possible reference in drivers/target/target_core_mib.c: + * scsi_att_intr_port_seq_show() + */ + while (atomic_read(&se_sess->mib_ref_count) != 0) + cpu_relax(); spin_lock_bh(&se_tpg->session_lock); list_del(&se_sess->sess_list); @@ -601,6 +574,7 @@ void transport_deregister_session(struct se_session *se_sess) spin_unlock_bh(&se_tpg->acl_node_lock); core_tpg_wait_for_nacl_pr_ref(se_nacl); + core_tpg_wait_for_mib_ref(se_nacl); core_free_device_list_for_node(se_nacl, se_tpg); TPG_TFO(se_tpg)->tpg_release_fabric_acl(se_tpg, se_nacl); @@ -4853,8 +4827,6 @@ static int transport_do_se_mem_map( return ret; } - - BUG_ON(list_empty(se_mem_list)); /* * This is the normal path for all normal non BIDI and BIDI-COMMAND * WRITE payloads.. If we need to do BIDI READ passthrough for @@ -5036,9 +5008,7 @@ transport_map_control_cmd_to_task(struct se_cmd *cmd) struct se_mem *se_mem = NULL, *se_mem_lout = NULL; u32 se_mem_cnt = 0, task_offset = 0; - if (!list_empty(T_TASK(cmd)->t_mem_list)) - se_mem = list_entry(T_TASK(cmd)->t_mem_list->next, - struct se_mem, se_list); + BUG_ON(list_empty(cmd->t_task->t_mem_list)); ret = transport_do_se_mem_map(dev, task, cmd->t_task->t_mem_list, NULL, se_mem, diff --git a/trunk/drivers/tty/serial/68328serial.c b/trunk/drivers/tty/serial/68328serial.c index de0160e3f8c4..be0ebce36e54 100644 --- a/trunk/drivers/tty/serial/68328serial.c +++ b/trunk/drivers/tty/serial/68328serial.c @@ -262,7 +262,7 @@ static void status_handle(struct m68k_serial *info, unsigned short status) static void receive_chars(struct m68k_serial *info, unsigned short rx) { - struct tty_struct *tty = info->tty; + struct tty_struct *tty = info->port.tty; m68328_uart *uart = &uart_addr[info->line]; unsigned char ch, flag; @@ -329,7 +329,7 @@ static void transmit_chars(struct m68k_serial *info) goto clear_and_return; } - if((info->xmit_cnt <= 0) || info->tty->stopped) { + if((info->xmit_cnt <= 0) || info->port.tty->stopped) { /* That's peculiar... TX ints off */ uart->ustcnt &= ~USTCNT_TX_INTR_MASK; goto clear_and_return; @@ -383,7 +383,7 @@ static void do_softint(struct work_struct *work) struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue); struct tty_struct *tty; - tty = info->tty; + tty = info->port.tty; if (!tty) return; #if 0 @@ -407,7 +407,7 @@ static void do_serial_hangup(struct work_struct *work) struct m68k_serial *info = container_of(work, struct m68k_serial, tqueue_hangup); struct tty_struct *tty; - tty = info->tty; + tty = info->port.tty; if (!tty) return; @@ -451,8 +451,8 @@ static int startup(struct m68k_serial * info) uart->ustcnt = USTCNT_UEN | USTCNT_RXEN | USTCNT_RX_INTR_MASK; #endif - if (info->tty) - clear_bit(TTY_IO_ERROR, &info->tty->flags); + if (info->port.tty) + clear_bit(TTY_IO_ERROR, &info->port.tty->flags); info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; /* @@ -486,8 +486,8 @@ static void shutdown(struct m68k_serial * info) info->xmit_buf = 0; } - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); + if (info->port.tty) + set_bit(TTY_IO_ERROR, &info->port.tty->flags); info->flags &= ~S_INITIALIZED; local_irq_restore(flags); @@ -553,9 +553,9 @@ static void change_speed(struct m68k_serial *info) unsigned cflag; int i; - if (!info->tty || !info->tty->termios) + if (!info->port.tty || !info->port.tty->termios) return; - cflag = info->tty->termios->c_cflag; + cflag = info->port.tty->termios->c_cflag; if (!(port = info->port)) return; @@ -970,6 +970,7 @@ static void send_break(struct m68k_serial * info, unsigned int duration) static int rs_ioctl(struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg) { + int error; struct m68k_serial * info = (struct m68k_serial *)tty->driver_data; int retval; @@ -1103,7 +1104,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) tty_ldisc_flush(tty); tty->closing = 0; info->event = 0; - info->tty = NULL; + info->port.tty = NULL; #warning "This is not and has never been valid so fix it" #if 0 if (tty->ldisc.num != ldiscs[N_TTY].num) { @@ -1141,7 +1142,7 @@ void rs_hangup(struct tty_struct *tty) info->event = 0; info->count = 0; info->flags &= ~S_NORMAL_ACTIVE; - info->tty = NULL; + info->port.tty = NULL; wake_up_interruptible(&info->open_wait); } @@ -1260,7 +1261,7 @@ int rs_open(struct tty_struct *tty, struct file * filp) info->count++; tty->driver_data = info; - info->tty = tty; + info->port.tty = tty; /* * Start up serial port @@ -1337,7 +1338,7 @@ rs68328_init(void) info = &m68k_soft[i]; info->magic = SERIAL_MAGIC; info->port = (int) &uart_addr[i]; - info->tty = NULL; + info->port.tty = NULL; info->irq = uart_irqs[i]; info->custom_divisor = 16; info->close_delay = 50; diff --git a/trunk/drivers/tty/sysrq.c b/trunk/drivers/tty/sysrq.c index 81f13958e751..8e0dd254eb11 100644 --- a/trunk/drivers/tty/sysrq.c +++ b/trunk/drivers/tty/sysrq.c @@ -571,7 +571,6 @@ struct sysrq_state { unsigned int alt_use; bool active; bool need_reinject; - bool reinjecting; }; static void sysrq_reinject_alt_sysrq(struct work_struct *work) @@ -582,10 +581,6 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work) unsigned int alt_code = sysrq->alt_use; if (sysrq->need_reinject) { - /* we do not want the assignment to be reordered */ - sysrq->reinjecting = true; - mb(); - /* Simulate press and release of Alt + SysRq */ input_inject_event(handle, EV_KEY, alt_code, 1); input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1); @@ -594,9 +589,6 @@ static void sysrq_reinject_alt_sysrq(struct work_struct *work) input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0); input_inject_event(handle, EV_KEY, alt_code, 0); input_inject_event(handle, EV_SYN, SYN_REPORT, 1); - - mb(); - sysrq->reinjecting = false; } } @@ -607,13 +599,6 @@ static bool sysrq_filter(struct input_handle *handle, bool was_active = sysrq->active; bool suppress; - /* - * Do not filter anything if we are in the process of re-injecting - * Alt+SysRq combination. - */ - if (sysrq->reinjecting) - return false; - switch (type) { case EV_SYN: @@ -644,7 +629,7 @@ static bool sysrq_filter(struct input_handle *handle, sysrq->alt_use = sysrq->alt; /* * If nothing else will be pressed we'll need - * to re-inject Alt-SysRq keysroke. + * to * re-inject Alt-SysRq keysroke. */ sysrq->need_reinject = true; } diff --git a/trunk/drivers/watchdog/Kconfig b/trunk/drivers/watchdog/Kconfig index 31649b7b672f..2e2400e7322e 100644 --- a/trunk/drivers/watchdog/Kconfig +++ b/trunk/drivers/watchdog/Kconfig @@ -862,12 +862,12 @@ config SBC_EPX_C3_WATCHDOG # M68K Architecture -config M54xx_WATCHDOG - tristate "MCF54xx watchdog support" +config M548x_WATCHDOG + tristate "MCF548x watchdog support" depends on M548x help To compile this driver as a module, choose M here: the - module will be called m54xx_wdt. + module will be called m548x_wdt. # MIPS Architecture diff --git a/trunk/drivers/watchdog/Makefile b/trunk/drivers/watchdog/Makefile index 20e44c4782b3..dd776651917c 100644 --- a/trunk/drivers/watchdog/Makefile +++ b/trunk/drivers/watchdog/Makefile @@ -106,7 +106,7 @@ obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o # M32R Architecture # M68K Architecture -obj-$(CONFIG_M54xx_WATCHDOG) += m54xx_wdt.o +obj-$(CONFIG_M548x_WATCHDOG) += m548x_wdt.o # MIPS Architecture obj-$(CONFIG_ATH79_WDT) += ath79_wdt.o diff --git a/trunk/drivers/watchdog/m54xx_wdt.c b/trunk/drivers/watchdog/m548x_wdt.c similarity index 80% rename from trunk/drivers/watchdog/m54xx_wdt.c rename to trunk/drivers/watchdog/m548x_wdt.c index 4d43286074aa..cabbcfe1c847 100644 --- a/trunk/drivers/watchdog/m54xx_wdt.c +++ b/trunk/drivers/watchdog/m548x_wdt.c @@ -1,7 +1,7 @@ /* - * drivers/watchdog/m54xx_wdt.c + * drivers/watchdog/m548x_wdt.c * - * Watchdog driver for ColdFire MCF547x & MCF548x processors + * Watchdog driver for ColdFire MCF548x processors * Copyright 2010 (c) Philippe De Muyter * * Adapted from the IXP4xx watchdog driver, which carries these notices: @@ -29,8 +29,8 @@ #include #include -#include -#include +#include +#include static int nowayout = WATCHDOG_NOWAYOUT; static unsigned int heartbeat = 30; /* (secs) Default is 0.5 minute */ @@ -76,7 +76,7 @@ static void wdt_keepalive(void) __raw_writel(gms0, MCF_MBAR + MCF_GPT_GMS0); } -static int m54xx_wdt_open(struct inode *inode, struct file *file) +static int m548x_wdt_open(struct inode *inode, struct file *file) { if (test_and_set_bit(WDT_IN_USE, &wdt_status)) return -EBUSY; @@ -86,7 +86,7 @@ static int m54xx_wdt_open(struct inode *inode, struct file *file) return nonseekable_open(inode, file); } -static ssize_t m54xx_wdt_write(struct file *file, const char *data, +static ssize_t m548x_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos) { if (len) { @@ -112,10 +112,10 @@ static ssize_t m54xx_wdt_write(struct file *file, const char *data, static const struct watchdog_info ident = { .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, - .identity = "Coldfire M54xx Watchdog", + .identity = "Coldfire M548x Watchdog", }; -static long m54xx_wdt_ioctl(struct file *file, unsigned int cmd, +static long m548x_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int ret = -ENOTTY; @@ -161,7 +161,7 @@ static long m54xx_wdt_ioctl(struct file *file, unsigned int cmd, return ret; } -static int m54xx_wdt_release(struct inode *inode, struct file *file) +static int m548x_wdt_release(struct inode *inode, struct file *file) { if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) wdt_disable(); @@ -177,45 +177,45 @@ static int m54xx_wdt_release(struct inode *inode, struct file *file) } -static const struct file_operations m54xx_wdt_fops = { +static const struct file_operations m548x_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, - .write = m54xx_wdt_write, - .unlocked_ioctl = m54xx_wdt_ioctl, - .open = m54xx_wdt_open, - .release = m54xx_wdt_release, + .write = m548x_wdt_write, + .unlocked_ioctl = m548x_wdt_ioctl, + .open = m548x_wdt_open, + .release = m548x_wdt_release, }; -static struct miscdevice m54xx_wdt_miscdev = { +static struct miscdevice m548x_wdt_miscdev = { .minor = WATCHDOG_MINOR, .name = "watchdog", - .fops = &m54xx_wdt_fops, + .fops = &m548x_wdt_fops, }; -static int __init m54xx_wdt_init(void) +static int __init m548x_wdt_init(void) { if (!request_mem_region(MCF_MBAR + MCF_GPT_GCIR0, 4, - "Coldfire M54xx Watchdog")) { + "Coldfire M548x Watchdog")) { printk(KERN_WARNING - "Coldfire M54xx Watchdog : I/O region busy\n"); + "Coldfire M548x Watchdog : I/O region busy\n"); return -EBUSY; } printk(KERN_INFO "ColdFire watchdog driver is loaded.\n"); - return misc_register(&m54xx_wdt_miscdev); + return misc_register(&m548x_wdt_miscdev); } -static void __exit m54xx_wdt_exit(void) +static void __exit m548x_wdt_exit(void) { - misc_deregister(&m54xx_wdt_miscdev); + misc_deregister(&m548x_wdt_miscdev); release_mem_region(MCF_MBAR + MCF_GPT_GCIR0, 4); } -module_init(m54xx_wdt_init); -module_exit(m54xx_wdt_exit); +module_init(m548x_wdt_init); +module_exit(m548x_wdt_exit); MODULE_AUTHOR("Philippe De Muyter "); -MODULE_DESCRIPTION("Coldfire M54xx Watchdog"); +MODULE_DESCRIPTION("Coldfire M548x Watchdog"); module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds (default 30s)"); diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index 4fb8a3431531..333a7bb4cb9c 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -1215,6 +1215,12 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) res = __blkdev_get(bdev, mode, 0); + /* __blkdev_get() may alter read only status, check it afterwards */ + if (!res && (mode & FMODE_WRITE) && bdev_read_only(bdev)) { + __blkdev_put(bdev, mode, 0); + res = -EACCES; + } + if (whole) { /* finish claiming */ mutex_lock(&bdev->bd_mutex); @@ -1292,11 +1298,6 @@ struct block_device *blkdev_get_by_path(const char *path, fmode_t mode, if (err) return ERR_PTR(err); - if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) { - blkdev_put(bdev, mode); - return ERR_PTR(-EACCES); - } - return bdev; } EXPORT_SYMBOL(blkdev_get_by_path); diff --git a/trunk/fs/btrfs/disk-io.c b/trunk/fs/btrfs/disk-io.c index e1aa8d607bc7..fdce8799b98d 100644 --- a/trunk/fs/btrfs/disk-io.c +++ b/trunk/fs/btrfs/disk-io.c @@ -359,14 +359,10 @@ static int csum_dirty_buffer(struct btrfs_root *root, struct page *page) tree = &BTRFS_I(page->mapping->host)->io_tree; - if (page->private == EXTENT_PAGE_PRIVATE) { - WARN_ON(1); + if (page->private == EXTENT_PAGE_PRIVATE) goto out; - } - if (!page->private) { - WARN_ON(1); + if (!page->private) goto out; - } len = page->private >> 2; WARN_ON(len == 0); diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index f3c96fc01439..4e7e012ad667 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -6583,7 +6583,7 @@ static noinline int relocate_data_extent(struct inode *reloc_inode, u64 end = start + extent_key->offset - 1; em = alloc_extent_map(GFP_NOFS); - BUG_ON(!em); + BUG_ON(!em || IS_ERR(em)); em->start = start; em->len = extent_key->offset; diff --git a/trunk/fs/btrfs/extent_io.c b/trunk/fs/btrfs/extent_io.c index 92ac5192c518..5e76a474cb7e 100644 --- a/trunk/fs/btrfs/extent_io.c +++ b/trunk/fs/btrfs/extent_io.c @@ -1946,7 +1946,6 @@ void set_page_extent_mapped(struct page *page) static void set_page_extent_head(struct page *page, unsigned long len) { - WARN_ON(!PagePrivate(page)); set_page_private(page, EXTENT_PAGE_PRIVATE_FIRST_PAGE | len << 2); } @@ -2822,17 +2821,9 @@ int try_release_extent_state(struct extent_map_tree *map, * at this point we can safely clear everything except the * locked bit and the nodatasum bit */ - ret = clear_extent_bit(tree, start, end, + clear_extent_bit(tree, start, end, ~(EXTENT_LOCKED | EXTENT_NODATASUM), 0, 0, NULL, mask); - - /* if clear_extent_bit failed for enomem reasons, - * we can't allow the release to continue. - */ - if (ret < 0) - ret = 0; - else - ret = 1; } return ret; } @@ -3203,13 +3194,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, } if (!PageUptodate(p)) uptodate = 0; - - /* - * see below about how we avoid a nasty race with release page - * and why we unlock later - */ - if (i != 0) - unlock_page(p); + unlock_page(p); } if (uptodate) set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); @@ -3233,26 +3218,9 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, atomic_inc(&eb->refs); spin_unlock(&tree->buffer_lock); radix_tree_preload_end(); - - /* - * there is a race where release page may have - * tried to find this extent buffer in the radix - * but failed. It will tell the VM it is safe to - * reclaim the, and it will clear the page private bit. - * We must make sure to set the page private bit properly - * after the extent buffer is in the radix tree so - * it doesn't get lost - */ - set_page_extent_mapped(eb->first_page); - set_page_extent_head(eb->first_page, eb->len); - if (!page0) - unlock_page(eb->first_page); return eb; free_eb: - if (eb->first_page && !page0) - unlock_page(eb->first_page); - if (!atomic_dec_and_test(&eb->refs)) return exists; btrfs_release_extent_buffer(eb); @@ -3303,11 +3271,10 @@ int clear_extent_buffer_dirty(struct extent_io_tree *tree, continue; lock_page(page); - WARN_ON(!PagePrivate(page)); - - set_page_extent_mapped(page); if (i == 0) set_page_extent_head(page, eb->len); + else + set_page_private(page, EXTENT_PAGE_PRIVATE); clear_page_dirty_for_io(page); spin_lock_irq(&page->mapping->tree_lock); @@ -3497,13 +3464,6 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, for (i = start_i; i < num_pages; i++) { page = extent_buffer_page(eb, i); - - WARN_ON(!PagePrivate(page)); - - set_page_extent_mapped(page); - if (i == 0) - set_page_extent_head(page, eb->len); - if (inc_all_pages) page_cache_get(page); if (!PageUptodate(page)) { diff --git a/trunk/fs/btrfs/extent_map.c b/trunk/fs/btrfs/extent_map.c index 2b6c12e983b3..b0e1fce12530 100644 --- a/trunk/fs/btrfs/extent_map.c +++ b/trunk/fs/btrfs/extent_map.c @@ -51,8 +51,8 @@ struct extent_map *alloc_extent_map(gfp_t mask) { struct extent_map *em; em = kmem_cache_alloc(extent_map_cache, mask); - if (!em) - return NULL; + if (!em || IS_ERR(em)) + return em; em->in_tree = 0; em->flags = 0; em->compress_type = BTRFS_COMPRESS_NONE; diff --git a/trunk/fs/btrfs/file.c b/trunk/fs/btrfs/file.c index 7084140d5940..c1d3a818731a 100644 --- a/trunk/fs/btrfs/file.c +++ b/trunk/fs/btrfs/file.c @@ -186,7 +186,6 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, split = alloc_extent_map(GFP_NOFS); if (!split2) split2 = alloc_extent_map(GFP_NOFS); - BUG_ON(!split || !split2); write_lock(&em_tree->lock); em = lookup_extent_mapping(em_tree, start, len); diff --git a/trunk/fs/btrfs/inode.c b/trunk/fs/btrfs/inode.c index fb9bd7832b6d..bcc461a9695f 100644 --- a/trunk/fs/btrfs/inode.c +++ b/trunk/fs/btrfs/inode.c @@ -644,7 +644,6 @@ static noinline int submit_compressed_extents(struct inode *inode, async_extent->ram_size - 1, 0); em = alloc_extent_map(GFP_NOFS); - BUG_ON(!em); em->start = async_extent->start; em->len = async_extent->ram_size; em->orig_start = em->start; @@ -821,7 +820,6 @@ static noinline int cow_file_range(struct inode *inode, BUG_ON(ret); em = alloc_extent_map(GFP_NOFS); - BUG_ON(!em); em->start = start; em->orig_start = em->start; ram_size = ins.offset; @@ -1171,7 +1169,6 @@ static noinline int run_delalloc_nocow(struct inode *inode, struct extent_map_tree *em_tree; em_tree = &BTRFS_I(inode)->extent_tree; em = alloc_extent_map(GFP_NOFS); - BUG_ON(!em); em->start = cur_offset; em->orig_start = em->start; em->len = num_bytes; diff --git a/trunk/fs/btrfs/ioctl.c b/trunk/fs/btrfs/ioctl.c index be2d4f6aaa5e..02d224e8c83f 100644 --- a/trunk/fs/btrfs/ioctl.c +++ b/trunk/fs/btrfs/ioctl.c @@ -2208,7 +2208,7 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) int num_types = 4; int alloc_size; int ret = 0; - u64 slot_count = 0; + int slot_count = 0; int i, c; if (copy_from_user(&space_args, @@ -2247,7 +2247,7 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) goto out; } - slot_count = min_t(u64, space_args.space_slots, slot_count); + slot_count = min_t(int, space_args.space_slots, slot_count); alloc_size = sizeof(*dest) * slot_count; @@ -2267,9 +2267,6 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) for (i = 0; i < num_types; i++) { struct btrfs_space_info *tmp; - if (!slot_count) - break; - info = NULL; rcu_read_lock(); list_for_each_entry_rcu(tmp, &root->fs_info->space_info, @@ -2291,10 +2288,7 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) memcpy(dest, &space, sizeof(space)); dest++; space_args.total_spaces++; - slot_count--; } - if (!slot_count) - break; } up_read(&info->groups_sem); } diff --git a/trunk/fs/btrfs/relocation.c b/trunk/fs/btrfs/relocation.c index 0825e4ed9447..1f5556acb530 100644 --- a/trunk/fs/btrfs/relocation.c +++ b/trunk/fs/btrfs/relocation.c @@ -1157,7 +1157,6 @@ static int clone_backref_node(struct btrfs_trans_handle *trans, new_node->bytenr = dest->node->start; new_node->level = node->level; new_node->lowest = node->lowest; - new_node->checked = 1; new_node->root = dest; if (!node->lowest) { diff --git a/trunk/fs/btrfs/volumes.c b/trunk/fs/btrfs/volumes.c index af7dbca15276..2636a051e4b2 100644 --- a/trunk/fs/btrfs/volumes.c +++ b/trunk/fs/btrfs/volumes.c @@ -1605,14 +1605,12 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) ret = find_next_devid(root, &device->devid); if (ret) { - kfree(device->name); kfree(device); goto error; } trans = btrfs_start_transaction(root, 0); if (IS_ERR(trans)) { - kfree(device->name); kfree(device); ret = PTR_ERR(trans); goto error; diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 0087cf9c2c6b..ec4b2d0190a8 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -455,6 +455,14 @@ static int nameidata_dentry_drop_rcu(struct nameidata *nd, struct dentry *dentry struct fs_struct *fs = current->fs; struct dentry *parent = nd->path.dentry; + /* + * It can be possible to revalidate the dentry that we started + * the path walk with. force_reval_path may also revalidate the + * dentry already committed to the nameidata. + */ + if (unlikely(parent == dentry)) + return nameidata_drop_rcu(nd); + BUG_ON(!(nd->flags & LOOKUP_RCU)); if (nd->root.mnt) { spin_lock(&fs->lock); @@ -563,15 +571,33 @@ void release_open_intent(struct nameidata *nd) } } -static inline int d_revalidate(struct dentry *dentry, struct nameidata *nd) +/* + * Call d_revalidate and handle filesystems that request rcu-walk + * to be dropped. This may be called and return in rcu-walk mode, + * regardless of success or error. If -ECHILD is returned, the caller + * must return -ECHILD back up the path walk stack so path walk may + * be restarted in ref-walk mode. + */ +static int d_revalidate(struct dentry *dentry, struct nameidata *nd) { - return dentry->d_op->d_revalidate(dentry, nd); + int status; + + status = dentry->d_op->d_revalidate(dentry, nd); + if (status == -ECHILD) { + if (nameidata_dentry_drop_rcu(nd, dentry)) + return status; + status = dentry->d_op->d_revalidate(dentry, nd); + } + + return status; } -static struct dentry * +static inline struct dentry * do_revalidate(struct dentry *dentry, struct nameidata *nd) { - int status = d_revalidate(dentry, nd); + int status; + + status = d_revalidate(dentry, nd); if (unlikely(status <= 0)) { /* * The dentry failed validation. @@ -580,35 +606,20 @@ do_revalidate(struct dentry *dentry, struct nameidata *nd) * to return a fail status. */ if (status < 0) { - dput(dentry); + /* If we're in rcu-walk, we don't have a ref */ + if (!(nd->flags & LOOKUP_RCU)) + dput(dentry); dentry = ERR_PTR(status); - } else if (!d_invalidate(dentry)) { - dput(dentry); - dentry = NULL; - } - } - return dentry; -} -static inline struct dentry * -do_revalidate_rcu(struct dentry *dentry, struct nameidata *nd) -{ - int status = d_revalidate(dentry, nd); - if (likely(status > 0)) - return dentry; - if (status == -ECHILD) { - if (nameidata_dentry_drop_rcu(nd, dentry)) - return ERR_PTR(-ECHILD); - return do_revalidate(dentry, nd); - } - if (status < 0) - return ERR_PTR(status); - /* Don't d_invalidate in rcu-walk mode */ - if (nameidata_dentry_drop_rcu(nd, dentry)) - return ERR_PTR(-ECHILD); - if (!d_invalidate(dentry)) { - dput(dentry); - dentry = NULL; + } else { + /* Don't d_invalidate in rcu-walk mode */ + if (nameidata_dentry_drop_rcu_maybe(nd, dentry)) + return ERR_PTR(-ECHILD); + if (!d_invalidate(dentry)) { + dput(dentry); + dentry = NULL; + } + } } return dentry; } @@ -657,6 +668,9 @@ force_reval_path(struct path *path, struct nameidata *nd) return 0; if (!status) { + /* Don't d_invalidate in rcu-walk mode */ + if (nameidata_drop_rcu(nd)) + return -ECHILD; d_invalidate(dentry); status = -ESTALE; } @@ -763,8 +777,6 @@ __do_follow_link(const struct path *link, struct nameidata *nd, void **p) int error; struct dentry *dentry = link->dentry; - BUG_ON(nd->flags & LOOKUP_RCU); - touch_atime(link->mnt, dentry); nd_set_link(nd, NULL); @@ -795,16 +807,10 @@ __do_follow_link(const struct path *link, struct nameidata *nd, void **p) * Without that kind of total limit, nasty chains of consecutive * symlinks can cause almost arbitrarily long lookups. */ -static inline int do_follow_link(struct inode *inode, struct path *path, struct nameidata *nd) +static inline int do_follow_link(struct path *path, struct nameidata *nd) { void *cookie; int err = -ELOOP; - - /* We drop rcu-walk here */ - if (nameidata_dentry_drop_rcu_maybe(nd, path->dentry)) - return -ECHILD; - BUG_ON(inode != path->dentry->d_inode); - if (current->link_count >= MAX_NESTED_LINKS) goto loop; if (current->total_link_count >= 40) @@ -1249,15 +1255,9 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, return -ECHILD; nd->seq = seq; - if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) { - dentry = do_revalidate_rcu(dentry, nd); - if (!dentry) - goto need_lookup; - if (IS_ERR(dentry)) - goto fail; - if (!(nd->flags & LOOKUP_RCU)) - goto done; - } + if (dentry->d_flags & DCACHE_OP_REVALIDATE) + goto need_revalidate; +done2: path->mnt = mnt; path->dentry = dentry; if (likely(__follow_mount_rcu(nd, path, inode, false))) @@ -1270,13 +1270,8 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, if (!dentry) goto need_lookup; found: - if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) { - dentry = do_revalidate(dentry, nd); - if (!dentry) - goto need_lookup; - if (IS_ERR(dentry)) - goto fail; - } + if (dentry->d_flags & DCACHE_OP_REVALIDATE) + goto need_revalidate; done: path->mnt = mnt; path->dentry = dentry; @@ -1318,6 +1313,16 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, mutex_unlock(&dir->i_mutex); goto found; +need_revalidate: + dentry = do_revalidate(dentry, nd); + if (!dentry) + goto need_lookup; + if (IS_ERR(dentry)) + goto fail; + if (nd->flags & LOOKUP_RCU) + goto done2; + goto done; + fail: return PTR_ERR(dentry); } @@ -1414,7 +1419,11 @@ static int link_path_walk(const char *name, struct nameidata *nd) goto out_dput; if (inode->i_op->follow_link) { - err = do_follow_link(inode, &next, nd); + /* We commonly drop rcu-walk here */ + if (nameidata_dentry_drop_rcu_maybe(nd, next.dentry)) + return -ECHILD; + BUG_ON(inode != next.dentry->d_inode); + err = do_follow_link(&next, nd); if (err) goto return_err; nd->inode = nd->path.dentry->d_inode; @@ -1458,7 +1467,10 @@ static int link_path_walk(const char *name, struct nameidata *nd) break; if (inode && unlikely(inode->i_op->follow_link) && (lookup_flags & LOOKUP_FOLLOW)) { - err = do_follow_link(inode, &next, nd); + if (nameidata_dentry_drop_rcu_maybe(nd, next.dentry)) + return -ECHILD; + BUG_ON(inode != next.dentry->d_inode); + err = do_follow_link(&next, nd); if (err) goto return_err; nd->inode = nd->path.dentry->d_inode; @@ -1492,15 +1504,12 @@ static int link_path_walk(const char *name, struct nameidata *nd) * We may need to check the cached dentry for staleness. */ if (need_reval_dot(nd->path.dentry)) { - if (nameidata_drop_rcu_last_maybe(nd)) - return -ECHILD; /* Note: we do not d_invalidate() */ err = d_revalidate(nd->path.dentry, nd); if (!err) err = -ESTALE; if (err < 0) break; - return 0; } return_base: if (nameidata_drop_rcu_last_maybe(nd)) diff --git a/trunk/fs/nfsd/nfs4callback.c b/trunk/fs/nfsd/nfs4callback.c index cde36cb0f348..3be975e18919 100644 --- a/trunk/fs/nfsd/nfs4callback.c +++ b/trunk/fs/nfsd/nfs4callback.c @@ -484,7 +484,7 @@ static int decode_cb_sequence4res(struct xdr_stream *xdr, out: return status; out_default: - return nfs_cb_stat_to_errno(nfserr); + return nfs_cb_stat_to_errno(status); } /* @@ -564,9 +564,11 @@ static int nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, if (unlikely(status)) goto out; if (unlikely(nfserr != NFS4_OK)) - status = nfs_cb_stat_to_errno(nfserr); + goto out_default; out: return status; +out_default: + return nfs_cb_stat_to_errno(status); } /* diff --git a/trunk/fs/nfsd/nfs4state.c b/trunk/fs/nfsd/nfs4state.c index 54b60bfceb8d..d98d0213285d 100644 --- a/trunk/fs/nfsd/nfs4state.c +++ b/trunk/fs/nfsd/nfs4state.c @@ -230,6 +230,9 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f dp->dl_client = clp; get_nfs4_file(fp); dp->dl_file = fp; + dp->dl_vfs_file = find_readable_file(fp); + get_file(dp->dl_vfs_file); + dp->dl_flock = NULL; dp->dl_type = type; dp->dl_stateid.si_boot = boot_time; dp->dl_stateid.si_stateownerid = current_delegid++; @@ -238,6 +241,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_stateid *stp, struct svc_f fh_copy_shallow(&dp->dl_fh, ¤t_fh->fh_handle); dp->dl_time = 0; atomic_set(&dp->dl_count, 1); + list_add(&dp->dl_perfile, &fp->fi_delegations); + list_add(&dp->dl_perclnt, &clp->cl_delegations); INIT_WORK(&dp->dl_recall.cb_work, nfsd4_do_callback_rpc); return dp; } @@ -248,30 +253,36 @@ nfs4_put_delegation(struct nfs4_delegation *dp) if (atomic_dec_and_test(&dp->dl_count)) { dprintk("NFSD: freeing dp %p\n",dp); put_nfs4_file(dp->dl_file); + fput(dp->dl_vfs_file); kmem_cache_free(deleg_slab, dp); num_delegations--; } } -static void nfs4_put_deleg_lease(struct nfs4_file *fp) +/* Remove the associated file_lock first, then remove the delegation. + * lease_modify() is called to remove the FS_LEASE file_lock from + * the i_flock list, eventually calling nfsd's lock_manager + * fl_release_callback. + */ +static void +nfs4_close_delegation(struct nfs4_delegation *dp) { - if (atomic_dec_and_test(&fp->fi_delegees)) { - vfs_setlease(fp->fi_deleg_file, F_UNLCK, &fp->fi_lease); - fp->fi_lease = NULL; - fp->fi_deleg_file = NULL; - } + dprintk("NFSD: close_delegation dp %p\n",dp); + /* XXX: do we even need this check?: */ + if (dp->dl_flock) + vfs_setlease(dp->dl_vfs_file, F_UNLCK, &dp->dl_flock); } /* Called under the state lock. */ static void unhash_delegation(struct nfs4_delegation *dp) { + list_del_init(&dp->dl_perfile); list_del_init(&dp->dl_perclnt); spin_lock(&recall_lock); - list_del_init(&dp->dl_perfile); list_del_init(&dp->dl_recall_lru); spin_unlock(&recall_lock); - nfs4_put_deleg_lease(dp->dl_file); + nfs4_close_delegation(dp); nfs4_put_delegation(dp); } @@ -947,6 +958,8 @@ expire_client(struct nfs4_client *clp) spin_lock(&recall_lock); while (!list_empty(&clp->cl_delegations)) { dp = list_entry(clp->cl_delegations.next, struct nfs4_delegation, dl_perclnt); + dprintk("NFSD: expire client. dp %p, fp %p\n", dp, + dp->dl_flock); list_del_init(&dp->dl_perclnt); list_move(&dp->dl_recall_lru, &reaplist); } @@ -2065,7 +2078,6 @@ alloc_init_file(struct inode *ino) fp->fi_inode = igrab(ino); fp->fi_id = current_fileid++; fp->fi_had_conflict = false; - fp->fi_lease = NULL; memset(fp->fi_fds, 0, sizeof(fp->fi_fds)); memset(fp->fi_access, 0, sizeof(fp->fi_access)); spin_lock(&recall_lock); @@ -2317,8 +2329,23 @@ nfs4_file_downgrade(struct nfs4_file *fp, unsigned int share_access) nfs4_file_put_access(fp, O_RDONLY); } -static void nfsd_break_one_deleg(struct nfs4_delegation *dp) +/* + * Spawn a thread to perform a recall on the delegation represented + * by the lease (file_lock) + * + * Called from break_lease() with lock_flocks() held. + * Note: we assume break_lease will only call this *once* for any given + * lease. + */ +static +void nfsd_break_deleg_cb(struct file_lock *fl) { + struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner; + + dprintk("NFSD nfsd_break_deleg_cb: dp %p fl %p\n",dp,fl); + if (!dp) + return; + /* We're assuming the state code never drops its reference * without first removing the lease. Since we're in this lease * callback (and since the lease code is serialized by the kernel @@ -2326,35 +2353,22 @@ static void nfsd_break_one_deleg(struct nfs4_delegation *dp) * it's safe to take a reference: */ atomic_inc(&dp->dl_count); + spin_lock(&recall_lock); list_add_tail(&dp->dl_recall_lru, &del_recall_lru); + spin_unlock(&recall_lock); /* only place dl_time is set. protected by lock_flocks*/ dp->dl_time = get_seconds(); - nfsd4_cb_recall(dp); -} - -/* Called from break_lease() with lock_flocks() held. */ -static void nfsd_break_deleg_cb(struct file_lock *fl) -{ - struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner; - struct nfs4_delegation *dp; - - BUG_ON(!fp); - /* We assume break_lease is only called once per lease: */ - BUG_ON(fp->fi_had_conflict); /* * We don't want the locks code to timeout the lease for us; - * we'll remove it ourself if a delegation isn't returned - * in time: + * we'll remove it ourself if the delegation isn't returned + * in time. */ fl->fl_break_time = 0; - spin_lock(&recall_lock); - fp->fi_had_conflict = true; - list_for_each_entry(dp, &fp->fi_delegations, dl_perfile) - nfsd_break_one_deleg(dp); - spin_unlock(&recall_lock); + dp->dl_file->fi_had_conflict = true; + nfsd4_cb_recall(dp); } static @@ -2445,15 +2459,13 @@ nfs4_check_delegmode(struct nfs4_delegation *dp, int flags) static struct nfs4_delegation * find_delegation_file(struct nfs4_file *fp, stateid_t *stid) { - struct nfs4_delegation *dp = NULL; + struct nfs4_delegation *dp; - spin_lock(&recall_lock); list_for_each_entry(dp, &fp->fi_delegations, dl_perfile) { if (dp->dl_stateid.si_stateownerid == stid->si_stateownerid) - break; + return dp; } - spin_unlock(&recall_lock); - return dp; + return NULL; } int share_access_to_flags(u32 share_access) @@ -2629,66 +2641,6 @@ static bool nfsd4_cb_channel_good(struct nfs4_client *clp) return clp->cl_minorversion && clp->cl_cb_state == NFSD4_CB_UNKNOWN; } -static struct file_lock *nfs4_alloc_init_lease(struct nfs4_delegation *dp, int flag) -{ - struct file_lock *fl; - - fl = locks_alloc_lock(); - if (!fl) - return NULL; - locks_init_lock(fl); - fl->fl_lmops = &nfsd_lease_mng_ops; - fl->fl_flags = FL_LEASE; - fl->fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK; - fl->fl_end = OFFSET_MAX; - fl->fl_owner = (fl_owner_t)(dp->dl_file); - fl->fl_pid = current->tgid; - return fl; -} - -static int nfs4_setlease(struct nfs4_delegation *dp, int flag) -{ - struct nfs4_file *fp = dp->dl_file; - struct file_lock *fl; - int status; - - fl = nfs4_alloc_init_lease(dp, flag); - if (!fl) - return -ENOMEM; - fl->fl_file = find_readable_file(fp); - list_add(&dp->dl_perclnt, &dp->dl_client->cl_delegations); - status = vfs_setlease(fl->fl_file, fl->fl_type, &fl); - if (status) { - list_del_init(&dp->dl_perclnt); - locks_free_lock(fl); - return -ENOMEM; - } - fp->fi_lease = fl; - fp->fi_deleg_file = fl->fl_file; - get_file(fp->fi_deleg_file); - atomic_set(&fp->fi_delegees, 1); - list_add(&dp->dl_perfile, &fp->fi_delegations); - return 0; -} - -static int nfs4_set_delegation(struct nfs4_delegation *dp, int flag) -{ - struct nfs4_file *fp = dp->dl_file; - - if (!fp->fi_lease) - return nfs4_setlease(dp, flag); - spin_lock(&recall_lock); - if (fp->fi_had_conflict) { - spin_unlock(&recall_lock); - return -EAGAIN; - } - atomic_inc(&fp->fi_delegees); - list_add(&dp->dl_perfile, &fp->fi_delegations); - spin_unlock(&recall_lock); - list_add(&dp->dl_perclnt, &dp->dl_client->cl_delegations); - return 0; -} - /* * Attempt to hand out a delegation. */ @@ -2698,6 +2650,7 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta struct nfs4_delegation *dp; struct nfs4_stateowner *sop = stp->st_stateowner; int cb_up; + struct file_lock *fl; int status, flag = 0; cb_up = nfsd4_cb_channel_good(sop->so_client); @@ -2728,11 +2681,36 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta } dp = alloc_init_deleg(sop->so_client, stp, fh, flag); - if (dp == NULL) - goto out_no_deleg; - status = nfs4_set_delegation(dp, flag); - if (status) - goto out_free; + if (dp == NULL) { + flag = NFS4_OPEN_DELEGATE_NONE; + goto out; + } + status = -ENOMEM; + fl = locks_alloc_lock(); + if (!fl) + goto out; + locks_init_lock(fl); + fl->fl_lmops = &nfsd_lease_mng_ops; + fl->fl_flags = FL_LEASE; + fl->fl_type = flag == NFS4_OPEN_DELEGATE_READ? F_RDLCK: F_WRLCK; + fl->fl_end = OFFSET_MAX; + fl->fl_owner = (fl_owner_t)dp; + fl->fl_file = find_readable_file(stp->st_file); + BUG_ON(!fl->fl_file); + fl->fl_pid = current->tgid; + dp->dl_flock = fl; + + /* vfs_setlease checks to see if delegation should be handed out. + * the lock_manager callback fl_change is used + */ + if ((status = vfs_setlease(fl->fl_file, fl->fl_type, &fl))) { + dprintk("NFSD: setlease failed [%d], no delegation\n", status); + dp->dl_flock = NULL; + locks_free_lock(fl); + unhash_delegation(dp); + flag = NFS4_OPEN_DELEGATE_NONE; + goto out; + } memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid)); @@ -2744,12 +2722,6 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta && open->op_delegate_type != NFS4_OPEN_DELEGATE_NONE) dprintk("NFSD: WARNING: refusing delegation reclaim\n"); open->op_delegate_type = flag; - return; -out_free: - nfs4_put_delegation(dp); -out_no_deleg: - flag = NFS4_OPEN_DELEGATE_NONE; - goto out; } /* @@ -2944,6 +2916,8 @@ nfs4_laundromat(void) test_val = u; break; } + dprintk("NFSD: purging unused delegation dp %p, fp %p\n", + dp, dp->dl_flock); list_move(&dp->dl_recall_lru, &reaplist); } spin_unlock(&recall_lock); @@ -3154,7 +3128,7 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, goto out; renew_client(dp->dl_client); if (filpp) { - *filpp = dp->dl_file->fi_deleg_file; + *filpp = find_readable_file(dp->dl_file); BUG_ON(!*filpp); } } else { /* open or lock stateid */ diff --git a/trunk/fs/nfsd/nfs4xdr.c b/trunk/fs/nfsd/nfs4xdr.c index 1275b8655070..956629b9cdc9 100644 --- a/trunk/fs/nfsd/nfs4xdr.c +++ b/trunk/fs/nfsd/nfs4xdr.c @@ -317,8 +317,8 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, READ_BUF(dummy32); len += (XDR_QUADLEN(dummy32) << 2); READMEM(buf, dummy32); - if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid))) - return status; + if ((host_err = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid))) + goto out_nfserr; iattr->ia_valid |= ATTR_UID; } if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) { @@ -328,8 +328,8 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, READ_BUF(dummy32); len += (XDR_QUADLEN(dummy32) << 2); READMEM(buf, dummy32); - if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid))) - return status; + if ((host_err = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid))) + goto out_nfserr; iattr->ia_valid |= ATTR_GID; } if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) { diff --git a/trunk/fs/nfsd/state.h b/trunk/fs/nfsd/state.h index 2d31224b07bf..3074656ba7bf 100644 --- a/trunk/fs/nfsd/state.h +++ b/trunk/fs/nfsd/state.h @@ -83,6 +83,8 @@ struct nfs4_delegation { atomic_t dl_count; /* ref count */ struct nfs4_client *dl_client; struct nfs4_file *dl_file; + struct file *dl_vfs_file; + struct file_lock *dl_flock; u32 dl_type; time_t dl_time; /* For recall: */ @@ -377,9 +379,6 @@ struct nfs4_file { */ atomic_t fi_readers; atomic_t fi_writers; - struct file *fi_deleg_file; - struct file_lock *fi_lease; - atomic_t fi_delegees; struct inode *fi_inode; u32 fi_id; /* used with stateowner->so_id * for stateid_hashtbl hash */ diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c index da1d9701f8e4..641117f2188d 100644 --- a/trunk/fs/nfsd/vfs.c +++ b/trunk/fs/nfsd/vfs.c @@ -808,7 +808,7 @@ nfsd_get_raparms(dev_t dev, ino_t ino) if (ra->p_count == 0) frap = rap; } - depth = nfsdstats.ra_size; + depth = nfsdstats.ra_size*11/10; if (!frap) { spin_unlock(&rab->pb_lock); return NULL; @@ -1742,13 +1742,6 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, goto out_dput_new; host_err = nfsd_break_lease(odentry->d_inode); - if (host_err) - goto out_drop_write; - if (ndentry->d_inode) { - host_err = nfsd_break_lease(ndentry->d_inode); - if (host_err) - goto out_drop_write; - } if (host_err) goto out_drop_write; host_err = vfs_rename(fdir, odentry, tdir, ndentry); @@ -1819,22 +1812,22 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, host_err = mnt_want_write(fhp->fh_export->ex_path.mnt); if (host_err) - goto out_put; + goto out_nfserr; host_err = nfsd_break_lease(rdentry->d_inode); if (host_err) - goto out_drop_write; + goto out_put; if (type != S_IFDIR) host_err = vfs_unlink(dirp, rdentry); else host_err = vfs_rmdir(dirp, rdentry); - if (!host_err) - host_err = commit_metadata(fhp); -out_drop_write: - mnt_drop_write(fhp->fh_export->ex_path.mnt); out_put: dput(rdentry); + if (!host_err) + host_err = commit_metadata(fhp); + + mnt_drop_write(fhp->fh_export->ex_path.mnt); out_nfserr: err = nfserrno(host_err); out: diff --git a/trunk/fs/partitions/mac.c b/trunk/fs/partitions/mac.c index 11f688bd76c5..68d6a216ee79 100644 --- a/trunk/fs/partitions/mac.c +++ b/trunk/fs/partitions/mac.c @@ -29,9 +29,10 @@ static inline void mac_fix_string(char *stg, int len) int mac_partition(struct parsed_partitions *state) { + int slot = 1; Sector sect; unsigned char *data; - int slot, blocks_in_map; + int blk, blocks_in_map; unsigned secsize; #ifdef CONFIG_PPC_PMAC int found_root = 0; @@ -58,14 +59,10 @@ int mac_partition(struct parsed_partitions *state) put_dev_sector(sect); return 0; /* not a MacOS disk */ } - blocks_in_map = be32_to_cpu(part->map_count); - if (blocks_in_map < 0 || blocks_in_map >= DISK_MAX_PARTS) { - put_dev_sector(sect); - return 0; - } strlcat(state->pp_buf, " [mac]", PAGE_SIZE); - for (slot = 1; slot <= blocks_in_map; ++slot) { - int pos = slot * secsize; + blocks_in_map = be32_to_cpu(part->map_count); + for (blk = 1; blk <= blocks_in_map; ++blk) { + int pos = blk * secsize; put_dev_sector(sect); data = read_part_sector(state, pos/512, §); if (!data) @@ -116,11 +113,13 @@ int mac_partition(struct parsed_partitions *state) } if (goodness > found_root_goodness) { - found_root = slot; + found_root = blk; found_root_goodness = goodness; } } #endif /* CONFIG_PPC_PMAC */ + + ++slot; } #ifdef CONFIG_PPC_PMAC if (found_root_goodness) diff --git a/trunk/fs/proc/array.c b/trunk/fs/proc/array.c index 7c99c1cf7e5c..df2b703b9d0f 100644 --- a/trunk/fs/proc/array.c +++ b/trunk/fs/proc/array.c @@ -353,6 +353,9 @@ int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, task_cap(m, task); task_cpus_allowed(m, task); cpuset_task_status_allowed(m, task); +#if defined(CONFIG_S390) + task_show_regs(m, task); +#endif task_context_switch_counts(m, task); return 0; } diff --git a/trunk/include/linux/huge_mm.h b/trunk/include/linux/huge_mm.h index df29c8fde36b..8e6c8c42bc3c 100644 --- a/trunk/include/linux/huge_mm.h +++ b/trunk/include/linux/huge_mm.h @@ -57,8 +57,7 @@ extern pmd_t *page_check_address_pmd(struct page *page, (transparent_hugepage_flags & \ (1<vm_flags & VM_HUGEPAGE))) && \ - !((__vma)->vm_flags & VM_NOHUGEPAGE) && \ - !is_vma_temporary_stack(__vma)) + !((__vma)->vm_flags & VM_NOHUGEPAGE)) #define transparent_hugepage_defrag(__vma) \ ((transparent_hugepage_flags & \ (1< #include -#define MATRIX_MAX_ROWS 32 -#define MATRIX_MAX_COLS 32 +#define MATRIX_MAX_ROWS 16 +#define MATRIX_MAX_COLS 16 #define KEY(row, col, val) ((((row) & (MATRIX_MAX_ROWS - 1)) << 24) |\ (((col) & (MATRIX_MAX_COLS - 1)) << 16) |\ diff --git a/trunk/include/linux/list.h b/trunk/include/linux/list.h index 3a54266a1e85..9a5f8a71810c 100644 --- a/trunk/include/linux/list.h +++ b/trunk/include/linux/list.h @@ -96,11 +96,6 @@ static inline void __list_del(struct list_head * prev, struct list_head * next) * in an undefined state. */ #ifndef CONFIG_DEBUG_LIST -static inline void __list_del_entry(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); -} - static inline void list_del(struct list_head *entry) { __list_del(entry->prev, entry->next); @@ -108,7 +103,6 @@ static inline void list_del(struct list_head *entry) entry->prev = LIST_POISON2; } #else -extern void __list_del_entry(struct list_head *entry); extern void list_del(struct list_head *entry); #endif @@ -141,7 +135,7 @@ static inline void list_replace_init(struct list_head *old, */ static inline void list_del_init(struct list_head *entry) { - __list_del_entry(entry); + __list_del(entry->prev, entry->next); INIT_LIST_HEAD(entry); } @@ -152,7 +146,7 @@ static inline void list_del_init(struct list_head *entry) */ static inline void list_move(struct list_head *list, struct list_head *head) { - __list_del_entry(list); + __list_del(list->prev, list->next); list_add(list, head); } @@ -164,7 +158,7 @@ static inline void list_move(struct list_head *list, struct list_head *head) static inline void list_move_tail(struct list_head *list, struct list_head *head) { - __list_del_entry(list); + __list_del(list->prev, list->next); list_add_tail(list, head); } diff --git a/trunk/include/linux/oprofile.h b/trunk/include/linux/oprofile.h index 1ca64113efe8..32fb81212fd1 100644 --- a/trunk/include/linux/oprofile.h +++ b/trunk/include/linux/oprofile.h @@ -16,8 +16,6 @@ #include #include #include -#include -#include #include /* Each escaped entry is prefixed by ESCAPE_CODE @@ -188,17 +186,10 @@ int oprofile_add_data(struct op_entry *entry, unsigned long val); int oprofile_add_data64(struct op_entry *entry, u64 val); int oprofile_write_commit(struct op_entry *entry); -#ifdef CONFIG_HW_PERF_EVENTS +#ifdef CONFIG_PERF_EVENTS int __init oprofile_perf_init(struct oprofile_operations *ops); void oprofile_perf_exit(void); char *op_name_from_perf_id(void); -#else -static inline int __init oprofile_perf_init(struct oprofile_operations *ops) -{ - pr_info("oprofile: hardware counters not available\n"); - return -ENODEV; -} -static inline void oprofile_perf_exit(void) { } -#endif /* CONFIG_HW_PERF_EVENTS */ +#endif /* CONFIG_PERF_EVENTS */ #endif /* OPROFILE_H */ diff --git a/trunk/include/target/target_core_base.h b/trunk/include/target/target_core_base.h index 0828b6c8610a..07fdfb6b9a9a 100644 --- a/trunk/include/target/target_core_base.h +++ b/trunk/include/target/target_core_base.h @@ -8,6 +8,7 @@ #include #include #include +#include "target_core_mib.h" #define TARGET_CORE_MOD_VERSION "v4.0.0-rc6" #define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGABRT)) @@ -194,21 +195,6 @@ typedef enum { SAM_TASK_ATTR_EMULATED } t10_task_attr_index_t; -/* - * Used for target SCSI statistics - */ -typedef enum { - SCSI_INST_INDEX, - SCSI_DEVICE_INDEX, - SCSI_AUTH_INTR_INDEX, - SCSI_INDEX_TYPE_MAX -} scsi_index_t; - -struct scsi_index_table { - spinlock_t lock; - u32 scsi_mib_index[SCSI_INDEX_TYPE_MAX]; -} ____cacheline_aligned; - struct se_cmd; struct t10_alua { @@ -592,6 +578,8 @@ struct se_node_acl { spinlock_t stats_lock; /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */ atomic_t acl_pr_ref_count; + /* Used for MIB access */ + atomic_t mib_ref_count; struct se_dev_entry *device_list; struct se_session *nacl_sess; struct se_portal_group *se_tpg; @@ -607,6 +595,8 @@ struct se_node_acl { } ____cacheline_aligned; struct se_session { + /* Used for MIB access */ + atomic_t mib_ref_count; u64 sess_bin_isid; struct se_node_acl *se_node_acl; struct se_portal_group *se_tpg; @@ -816,6 +806,7 @@ struct se_hba { /* Virtual iSCSI devices attached. */ u32 dev_count; u32 hba_index; + atomic_t dev_mib_access_count; atomic_t load_balance_queue; atomic_t left_queue_depth; /* Maximum queue depth the HBA can handle. */ @@ -854,12 +845,6 @@ struct se_lun { #define SE_LUN(c) ((struct se_lun *)(c)->se_lun) -struct scsi_port_stats { - u64 cmd_pdus; - u64 tx_data_octets; - u64 rx_data_octets; -} ____cacheline_aligned; - struct se_port { /* RELATIVE TARGET PORT IDENTIFER */ u16 sep_rtpi; @@ -882,7 +867,6 @@ struct se_port { } ____cacheline_aligned; struct se_tpg_np { - struct se_portal_group *tpg_np_parent; struct config_group tpg_np_group; } ____cacheline_aligned; diff --git a/trunk/include/target/target_core_transport.h b/trunk/include/target/target_core_transport.h index 246940511579..66f44e56eb80 100644 --- a/trunk/include/target/target_core_transport.h +++ b/trunk/include/target/target_core_transport.h @@ -111,8 +111,6 @@ struct se_subsystem_api; extern int init_se_global(void); extern void release_se_global(void); -extern void init_scsi_index_table(void); -extern u32 scsi_get_new_index(scsi_index_t); extern void transport_init_queue_obj(struct se_queue_obj *); extern int transport_subsystem_check_init(void); extern int transport_subsystem_register(struct se_subsystem_api *); diff --git a/trunk/kernel/power/snapshot.c b/trunk/kernel/power/snapshot.c index 64db648ff911..0dac75ea4456 100644 --- a/trunk/kernel/power/snapshot.c +++ b/trunk/kernel/power/snapshot.c @@ -1519,8 +1519,11 @@ static int swsusp_alloc(struct memory_bitmap *orig_bm, struct memory_bitmap *copy_bm, unsigned int nr_pages, unsigned int nr_highmem) { + int error = 0; + if (nr_highmem > 0) { - if (get_highmem_buffer(PG_ANY)) + error = get_highmem_buffer(PG_ANY); + if (error) goto err_out; if (nr_highmem > alloc_highmem) { nr_highmem -= alloc_highmem; @@ -1543,7 +1546,7 @@ swsusp_alloc(struct memory_bitmap *orig_bm, struct memory_bitmap *copy_bm, err_out: swsusp_free(); - return -ENOMEM; + return error; } asmlinkage int swsusp_save(void) diff --git a/trunk/kernel/time/timer_list.c b/trunk/kernel/time/timer_list.c index 3258455549f4..32a19f9397fc 100644 --- a/trunk/kernel/time/timer_list.c +++ b/trunk/kernel/time/timer_list.c @@ -41,7 +41,7 @@ static void print_name_offset(struct seq_file *m, void *sym) char symname[KSYM_NAME_LEN]; if (lookup_symbol_name((unsigned long)sym, symname) < 0) - SEQ_printf(m, "<%pK>", sym); + SEQ_printf(m, "<%p>", sym); else SEQ_printf(m, "%s", symname); } @@ -112,7 +112,7 @@ print_active_timers(struct seq_file *m, struct hrtimer_clock_base *base, static void print_base(struct seq_file *m, struct hrtimer_clock_base *base, u64 now) { - SEQ_printf(m, " .base: %pK\n", base); + SEQ_printf(m, " .base: %p\n", base); SEQ_printf(m, " .index: %d\n", base->index); SEQ_printf(m, " .resolution: %Lu nsecs\n", diff --git a/trunk/kernel/timer.c b/trunk/kernel/timer.c index d6459923d245..d53ce66daea0 100644 --- a/trunk/kernel/timer.c +++ b/trunk/kernel/timer.c @@ -959,7 +959,7 @@ EXPORT_SYMBOL(try_to_del_timer_sync); * * Synchronization rules: Callers must prevent restarting of the timer, * otherwise this function is meaningless. It must not be called from - * interrupt contexts. The caller must not hold locks which would prevent + * hardirq contexts. The caller must not hold locks which would prevent * completion of the timer's handler. The timer's handler must not call * add_timer_on(). Upon exit the timer is not queued and the handler is * not running on any CPU. @@ -971,10 +971,12 @@ int del_timer_sync(struct timer_list *timer) #ifdef CONFIG_LOCKDEP unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); + local_bh_disable(); lock_map_acquire(&timer->lockdep_map); lock_map_release(&timer->lockdep_map); - local_irq_restore(flags); + _local_bh_enable(); + raw_local_irq_restore(flags); #endif /* * don't use it in hardirq context, because it diff --git a/trunk/kernel/watchdog.c b/trunk/kernel/watchdog.c index 18bb15776c57..f37f974aa81b 100644 --- a/trunk/kernel/watchdog.c +++ b/trunk/kernel/watchdog.c @@ -363,14 +363,8 @@ static int watchdog_nmi_enable(int cpu) goto out_save; } - - /* vary the KERN level based on the returned errno */ - if (PTR_ERR(event) == -EOPNOTSUPP) - printk(KERN_INFO "NMI watchdog disabled (cpu%i): not supported (no LAPIC?)\n", cpu); - else if (PTR_ERR(event) == -ENOENT) - printk(KERN_WARNING "NMI watchdog disabled (cpu%i): hardware events not enabled\n", cpu); - else - printk(KERN_ERR "NMI watchdog disabled (cpu%i): unable to create perf event: %ld\n", cpu, PTR_ERR(event)); + printk(KERN_ERR "NMI watchdog disabled for cpu%i: unable to create perf event: %ld\n", + cpu, PTR_ERR(event)); return PTR_ERR(event); /* success path */ diff --git a/trunk/kernel/workqueue.c b/trunk/kernel/workqueue.c index 11869faa6819..90a17ca2ad0b 100644 --- a/trunk/kernel/workqueue.c +++ b/trunk/kernel/workqueue.c @@ -2047,6 +2047,15 @@ static int rescuer_thread(void *__wq) move_linked_works(work, scheduled, &n); process_scheduled_works(rescuer); + + /* + * Leave this gcwq. If keep_working() is %true, notify a + * regular worker; otherwise, we end up with 0 concurrency + * and stalling the execution. + */ + if (keep_working(gcwq)) + wake_up_worker(gcwq); + spin_unlock_irq(&gcwq->lock); } diff --git a/trunk/lib/Kconfig.debug b/trunk/lib/Kconfig.debug index 2b97418c67e2..3967c2356e37 100644 --- a/trunk/lib/Kconfig.debug +++ b/trunk/lib/Kconfig.debug @@ -805,7 +805,7 @@ config ARCH_WANT_FRAME_POINTERS config FRAME_POINTER bool "Compile the kernel with frame pointers" depends on DEBUG_KERNEL && \ - (CRIS || M68K || FRV || UML || \ + (CRIS || M68K || M68KNOMMU || FRV || UML || \ AVR32 || SUPERH || BLACKFIN || MN10300) || \ ARCH_WANT_FRAME_POINTERS default y if (DEBUG_INFO && UML) || ARCH_WANT_FRAME_POINTERS diff --git a/trunk/lib/list_debug.c b/trunk/lib/list_debug.c index b8029a5583ff..344c710d16ca 100644 --- a/trunk/lib/list_debug.c +++ b/trunk/lib/list_debug.c @@ -35,31 +35,6 @@ void __list_add(struct list_head *new, } EXPORT_SYMBOL(__list_add); -void __list_del_entry(struct list_head *entry) -{ - struct list_head *prev, *next; - - prev = entry->prev; - next = entry->next; - - if (WARN(next == LIST_POISON1, - "list_del corruption, %p->next is LIST_POISON1 (%p)\n", - entry, LIST_POISON1) || - WARN(prev == LIST_POISON2, - "list_del corruption, %p->prev is LIST_POISON2 (%p)\n", - entry, LIST_POISON2) || - WARN(prev->next != entry, - "list_del corruption. prev->next should be %p, " - "but was %p\n", entry, prev->next) || - WARN(next->prev != entry, - "list_del corruption. next->prev should be %p, " - "but was %p\n", entry, next->prev)) - return; - - __list_del(prev, next); -} -EXPORT_SYMBOL(__list_del_entry); - /** * list_del - deletes entry from list. * @entry: the element to delete from the list. @@ -68,7 +43,19 @@ EXPORT_SYMBOL(__list_del_entry); */ void list_del(struct list_head *entry) { - __list_del_entry(entry); + WARN(entry->next == LIST_POISON1, + "list_del corruption, next is LIST_POISON1 (%p)\n", + LIST_POISON1); + WARN(entry->next != LIST_POISON1 && entry->prev == LIST_POISON2, + "list_del corruption, prev is LIST_POISON2 (%p)\n", + LIST_POISON2); + WARN(entry->prev->next != entry, + "list_del corruption. prev->next should be %p, " + "but was %p\n", entry, entry->prev->next); + WARN(entry->next->prev != entry, + "list_del corruption. next->prev should be %p, " + "but was %p\n", entry, entry->next->prev); + __list_del(entry->prev, entry->next); entry->next = LIST_POISON1; entry->prev = LIST_POISON2; } diff --git a/trunk/mm/huge_memory.c b/trunk/mm/huge_memory.c index 3e29781ee762..e62ddb8f24b6 100644 --- a/trunk/mm/huge_memory.c +++ b/trunk/mm/huge_memory.c @@ -1811,8 +1811,6 @@ static void collapse_huge_page(struct mm_struct *mm, /* VM_PFNMAP vmas may have vm_ops null but vm_file set */ if (!vma->anon_vma || vma->vm_ops || vma->vm_file) goto out; - if (is_vma_temporary_stack(vma)) - goto out; VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); pgd = pgd_offset(mm, address); @@ -2034,27 +2032,32 @@ static unsigned int khugepaged_scan_mm_slot(unsigned int pages, if ((!(vma->vm_flags & VM_HUGEPAGE) && !khugepaged_always()) || (vma->vm_flags & VM_NOHUGEPAGE)) { - skip: progress++; continue; } - /* VM_PFNMAP vmas may have vm_ops null but vm_file set */ - if (!vma->anon_vma || vma->vm_ops || vma->vm_file) - goto skip; - if (is_vma_temporary_stack(vma)) - goto skip; + /* VM_PFNMAP vmas may have vm_ops null but vm_file set */ + if (!vma->anon_vma || vma->vm_ops || vma->vm_file) { + khugepaged_scan.address = vma->vm_end; + progress++; + continue; + } VM_BUG_ON(is_linear_pfn_mapping(vma) || is_pfn_mapping(vma)); hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK; hend = vma->vm_end & HPAGE_PMD_MASK; - if (hstart >= hend) - goto skip; - if (khugepaged_scan.address > hend) - goto skip; + if (hstart >= hend) { + progress++; + continue; + } if (khugepaged_scan.address < hstart) khugepaged_scan.address = hstart; - VM_BUG_ON(khugepaged_scan.address & ~HPAGE_PMD_MASK); + if (khugepaged_scan.address > hend) { + khugepaged_scan.address = hend + HPAGE_PMD_SIZE; + progress++; + continue; + } + BUG_ON(khugepaged_scan.address & ~HPAGE_PMD_MASK); while (khugepaged_scan.address < hend) { int ret; @@ -2083,7 +2086,7 @@ static unsigned int khugepaged_scan_mm_slot(unsigned int pages, breakouterloop_mmap_sem: spin_lock(&khugepaged_mm_lock); - VM_BUG_ON(khugepaged_scan.mm_slot != mm_slot); + BUG_ON(khugepaged_scan.mm_slot != mm_slot); /* * Release the current mm_slot if this mm is about to die, or * if we scanned all vmas of this mm. @@ -2238,9 +2241,9 @@ static int khugepaged(void *none) for (;;) { mutex_unlock(&khugepaged_mutex); - VM_BUG_ON(khugepaged_thread != current); + BUG_ON(khugepaged_thread != current); khugepaged_loop(); - VM_BUG_ON(khugepaged_thread != current); + BUG_ON(khugepaged_thread != current); mutex_lock(&khugepaged_mutex); if (!khugepaged_enabled()) diff --git a/trunk/tools/perf/builtin-record.c b/trunk/tools/perf/builtin-record.c index 60cac6f92e8b..b2f729fdb317 100644 --- a/trunk/tools/perf/builtin-record.c +++ b/trunk/tools/perf/builtin-record.c @@ -759,8 +759,8 @@ static int __cmd_record(int argc, const char **argv) perf_session__process_machines(session, event__synthesize_guest_os); if (!system_wide) - event__synthesize_thread_map(threads, process_synthesized_event, - session); + event__synthesize_thread(target_tid, process_synthesized_event, + session); else event__synthesize_threads(process_synthesized_event, session); diff --git a/trunk/tools/perf/builtin-top.c b/trunk/tools/perf/builtin-top.c index 5a29d9cd9486..b6998e055767 100644 --- a/trunk/tools/perf/builtin-top.c +++ b/trunk/tools/perf/builtin-top.c @@ -1306,7 +1306,7 @@ static int __cmd_top(void) return -ENOMEM; if (target_tid != -1) - event__synthesize_thread_map(threads, event__process, session); + event__synthesize_thread(target_tid, event__process, session); else event__synthesize_threads(event__process, session); diff --git a/trunk/tools/perf/util/event.c b/trunk/tools/perf/util/event.c index 50d0a931497a..1478ab4ee222 100644 --- a/trunk/tools/perf/util/event.c +++ b/trunk/tools/perf/util/event.c @@ -263,12 +263,11 @@ static int __event__synthesize_thread(event_t *comm_event, event_t *mmap_event, process, session); } -int event__synthesize_thread_map(struct thread_map *threads, - event__handler_t process, - struct perf_session *session) +int event__synthesize_thread(pid_t pid, event__handler_t process, + struct perf_session *session) { event_t *comm_event, *mmap_event; - int err = -1, thread; + int err = -1; comm_event = malloc(sizeof(comm_event->comm) + session->id_hdr_size); if (comm_event == NULL) @@ -278,15 +277,8 @@ int event__synthesize_thread_map(struct thread_map *threads, if (mmap_event == NULL) goto out_free_comm; - err = 0; - for (thread = 0; thread < threads->nr; ++thread) { - if (__event__synthesize_thread(comm_event, mmap_event, - threads->map[thread], - process, session)) { - err = -1; - break; - } - } + err = __event__synthesize_thread(comm_event, mmap_event, pid, + process, session); free(mmap_event); out_free_comm: free(comm_event); diff --git a/trunk/tools/perf/util/event.h b/trunk/tools/perf/util/event.h index cc7b52f9b492..2b7e91902f10 100644 --- a/trunk/tools/perf/util/event.h +++ b/trunk/tools/perf/util/event.h @@ -135,16 +135,14 @@ typedef union event_union { void event__print_totals(void); struct perf_session; -struct thread_map; typedef int (*event__handler_synth_t)(event_t *event, struct perf_session *session); typedef int (*event__handler_t)(event_t *event, struct sample_data *sample, struct perf_session *session); -int event__synthesize_thread_map(struct thread_map *threads, - event__handler_t process, - struct perf_session *session); +int event__synthesize_thread(pid_t pid, event__handler_t process, + struct perf_session *session); int event__synthesize_threads(event__handler_t process, struct perf_session *session); int event__synthesize_kernel_mmap(event__handler_t process, diff --git a/trunk/tools/power/x86/turbostat/turbostat.c b/trunk/tools/power/x86/turbostat/turbostat.c index 362a0cb448db..4c6983de6fd9 100644 --- a/trunk/tools/power/x86/turbostat/turbostat.c +++ b/trunk/tools/power/x86/turbostat/turbostat.c @@ -72,7 +72,7 @@ int need_reinitialize; int num_cpus; -struct counters { +typedef struct per_cpu_counters { unsigned long long tsc; /* per thread */ unsigned long long aperf; /* per thread */ unsigned long long mperf; /* per thread */ @@ -88,13 +88,13 @@ struct counters { int pkg; int core; int cpu; - struct counters *next; -}; + struct per_cpu_counters *next; +} PCC; -struct counters *cnt_even; -struct counters *cnt_odd; -struct counters *cnt_delta; -struct counters *cnt_average; +PCC *pcc_even; +PCC *pcc_odd; +PCC *pcc_delta; +PCC *pcc_average; struct timeval tv_even; struct timeval tv_odd; struct timeval tv_delta; @@ -125,7 +125,7 @@ unsigned long long get_msr(int cpu, off_t offset) return msr; } -void print_header(void) +void print_header() { if (show_pkg) fprintf(stderr, "pkg "); @@ -160,39 +160,39 @@ void print_header(void) putc('\n', stderr); } -void dump_cnt(struct counters *cnt) +void dump_pcc(PCC *pcc) { - fprintf(stderr, "package: %d ", cnt->pkg); - fprintf(stderr, "core:: %d ", cnt->core); - fprintf(stderr, "CPU: %d ", cnt->cpu); - fprintf(stderr, "TSC: %016llX\n", cnt->tsc); - fprintf(stderr, "c3: %016llX\n", cnt->c3); - fprintf(stderr, "c6: %016llX\n", cnt->c6); - fprintf(stderr, "c7: %016llX\n", cnt->c7); - fprintf(stderr, "aperf: %016llX\n", cnt->aperf); - fprintf(stderr, "pc2: %016llX\n", cnt->pc2); - fprintf(stderr, "pc3: %016llX\n", cnt->pc3); - fprintf(stderr, "pc6: %016llX\n", cnt->pc6); - fprintf(stderr, "pc7: %016llX\n", cnt->pc7); - fprintf(stderr, "msr0x%x: %016llX\n", extra_msr_offset, cnt->extra_msr); + fprintf(stderr, "package: %d ", pcc->pkg); + fprintf(stderr, "core:: %d ", pcc->core); + fprintf(stderr, "CPU: %d ", pcc->cpu); + fprintf(stderr, "TSC: %016llX\n", pcc->tsc); + fprintf(stderr, "c3: %016llX\n", pcc->c3); + fprintf(stderr, "c6: %016llX\n", pcc->c6); + fprintf(stderr, "c7: %016llX\n", pcc->c7); + fprintf(stderr, "aperf: %016llX\n", pcc->aperf); + fprintf(stderr, "pc2: %016llX\n", pcc->pc2); + fprintf(stderr, "pc3: %016llX\n", pcc->pc3); + fprintf(stderr, "pc6: %016llX\n", pcc->pc6); + fprintf(stderr, "pc7: %016llX\n", pcc->pc7); + fprintf(stderr, "msr0x%x: %016llX\n", extra_msr_offset, pcc->extra_msr); } -void dump_list(struct counters *cnt) +void dump_list(PCC *pcc) { - printf("dump_list 0x%p\n", cnt); + printf("dump_list 0x%p\n", pcc); - for (; cnt; cnt = cnt->next) - dump_cnt(cnt); + for (; pcc; pcc = pcc->next) + dump_pcc(pcc); } -void print_cnt(struct counters *p) +void print_pcc(PCC *p) { double interval_float; interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0; /* topology columns, print blanks on 1st (average) line */ - if (p == cnt_average) { + if (p == pcc_average) { if (show_pkg) fprintf(stderr, " "); if (show_core) @@ -262,24 +262,24 @@ void print_cnt(struct counters *p) putc('\n', stderr); } -void print_counters(struct counters *counters) +void print_counters(PCC *cnt) { - struct counters *cnt; + PCC *pcc; print_header(); if (num_cpus > 1) - print_cnt(cnt_average); + print_pcc(pcc_average); - for (cnt = counters; cnt != NULL; cnt = cnt->next) - print_cnt(cnt); + for (pcc = cnt; pcc != NULL; pcc = pcc->next) + print_pcc(pcc); } #define SUBTRACT_COUNTER(after, before, delta) (delta = (after - before), (before > after)) -int compute_delta(struct counters *after, - struct counters *before, struct counters *delta) + +int compute_delta(PCC *after, PCC *before, PCC *delta) { int errors = 0; int perf_err = 0; @@ -391,20 +391,20 @@ int compute_delta(struct counters *after, delta->extra_msr = after->extra_msr; if (errors) { fprintf(stderr, "ERROR cpu%d before:\n", before->cpu); - dump_cnt(before); + dump_pcc(before); fprintf(stderr, "ERROR cpu%d after:\n", before->cpu); - dump_cnt(after); + dump_pcc(after); errors = 0; } } return 0; } -void compute_average(struct counters *delta, struct counters *avg) +void compute_average(PCC *delta, PCC *avg) { - struct counters *sum; + PCC *sum; - sum = calloc(1, sizeof(struct counters)); + sum = calloc(1, sizeof(PCC)); if (sum == NULL) { perror("calloc sum"); exit(1); @@ -438,34 +438,35 @@ void compute_average(struct counters *delta, struct counters *avg) free(sum); } -void get_counters(struct counters *cnt) +void get_counters(PCC *pcc) { - for ( ; cnt; cnt = cnt->next) { - cnt->tsc = get_msr(cnt->cpu, MSR_TSC); + for ( ; pcc; pcc = pcc->next) { + pcc->tsc = get_msr(pcc->cpu, MSR_TSC); if (do_nhm_cstates) - cnt->c3 = get_msr(cnt->cpu, MSR_CORE_C3_RESIDENCY); + pcc->c3 = get_msr(pcc->cpu, MSR_CORE_C3_RESIDENCY); if (do_nhm_cstates) - cnt->c6 = get_msr(cnt->cpu, MSR_CORE_C6_RESIDENCY); + pcc->c6 = get_msr(pcc->cpu, MSR_CORE_C6_RESIDENCY); if (do_snb_cstates) - cnt->c7 = get_msr(cnt->cpu, MSR_CORE_C7_RESIDENCY); + pcc->c7 = get_msr(pcc->cpu, MSR_CORE_C7_RESIDENCY); if (has_aperf) - cnt->aperf = get_msr(cnt->cpu, MSR_APERF); + pcc->aperf = get_msr(pcc->cpu, MSR_APERF); if (has_aperf) - cnt->mperf = get_msr(cnt->cpu, MSR_MPERF); + pcc->mperf = get_msr(pcc->cpu, MSR_MPERF); if (do_snb_cstates) - cnt->pc2 = get_msr(cnt->cpu, MSR_PKG_C2_RESIDENCY); + pcc->pc2 = get_msr(pcc->cpu, MSR_PKG_C2_RESIDENCY); if (do_nhm_cstates) - cnt->pc3 = get_msr(cnt->cpu, MSR_PKG_C3_RESIDENCY); + pcc->pc3 = get_msr(pcc->cpu, MSR_PKG_C3_RESIDENCY); if (do_nhm_cstates) - cnt->pc6 = get_msr(cnt->cpu, MSR_PKG_C6_RESIDENCY); + pcc->pc6 = get_msr(pcc->cpu, MSR_PKG_C6_RESIDENCY); if (do_snb_cstates) - cnt->pc7 = get_msr(cnt->cpu, MSR_PKG_C7_RESIDENCY); + pcc->pc7 = get_msr(pcc->cpu, MSR_PKG_C7_RESIDENCY); if (extra_msr_offset) - cnt->extra_msr = get_msr(cnt->cpu, extra_msr_offset); + pcc->extra_msr = get_msr(pcc->cpu, extra_msr_offset); } } -void print_nehalem_info(void) + +void print_nehalem_info() { unsigned long long msr; unsigned int ratio; @@ -513,38 +514,38 @@ void print_nehalem_info(void) } -void free_counter_list(struct counters *list) +void free_counter_list(PCC *list) { - struct counters *p; + PCC *p; for (p = list; p; ) { - struct counters *free_me; + PCC *free_me; free_me = p; p = p->next; free(free_me); } + return; } void free_all_counters(void) { - free_counter_list(cnt_even); - cnt_even = NULL; + free_counter_list(pcc_even); + pcc_even = NULL; - free_counter_list(cnt_odd); - cnt_odd = NULL; + free_counter_list(pcc_odd); + pcc_odd = NULL; - free_counter_list(cnt_delta); - cnt_delta = NULL; + free_counter_list(pcc_delta); + pcc_delta = NULL; - free_counter_list(cnt_average); - cnt_average = NULL; + free_counter_list(pcc_average); + pcc_average = NULL; } -void insert_counters(struct counters **list, - struct counters *new) +void insert_cpu_counters(PCC **list, PCC *new) { - struct counters *prev; + PCC *prev; /* * list was empty @@ -593,16 +594,18 @@ void insert_counters(struct counters **list, */ new->next = prev->next; prev->next = new; + + return; } -void alloc_new_counters(int pkg, int core, int cpu) +void alloc_new_cpu_counters(int pkg, int core, int cpu) { - struct counters *new; + PCC *new; if (verbose > 1) printf("pkg%d core%d, cpu%d\n", pkg, core, cpu); - new = (struct counters *)calloc(1, sizeof(struct counters)); + new = (PCC *)calloc(1, sizeof(PCC)); if (new == NULL) { perror("calloc"); exit(1); @@ -610,10 +613,9 @@ void alloc_new_counters(int pkg, int core, int cpu) new->pkg = pkg; new->core = core; new->cpu = cpu; - insert_counters(&cnt_odd, new); + insert_cpu_counters(&pcc_odd, new); - new = (struct counters *)calloc(1, - sizeof(struct counters)); + new = (PCC *)calloc(1, sizeof(PCC)); if (new == NULL) { perror("calloc"); exit(1); @@ -621,9 +623,9 @@ void alloc_new_counters(int pkg, int core, int cpu) new->pkg = pkg; new->core = core; new->cpu = cpu; - insert_counters(&cnt_even, new); + insert_cpu_counters(&pcc_even, new); - new = (struct counters *)calloc(1, sizeof(struct counters)); + new = (PCC *)calloc(1, sizeof(PCC)); if (new == NULL) { perror("calloc"); exit(1); @@ -631,9 +633,9 @@ void alloc_new_counters(int pkg, int core, int cpu) new->pkg = pkg; new->core = core; new->cpu = cpu; - insert_counters(&cnt_delta, new); + insert_cpu_counters(&pcc_delta, new); - new = (struct counters *)calloc(1, sizeof(struct counters)); + new = (PCC *)calloc(1, sizeof(PCC)); if (new == NULL) { perror("calloc"); exit(1); @@ -641,7 +643,7 @@ void alloc_new_counters(int pkg, int core, int cpu) new->pkg = pkg; new->core = core; new->cpu = cpu; - cnt_average = new; + pcc_average = new; } int get_physical_package_id(int cpu) @@ -717,7 +719,7 @@ void re_initialize(void) { printf("turbostat: topology changed, re-initializing.\n"); free_all_counters(); - num_cpus = for_all_cpus(alloc_new_counters); + num_cpus = for_all_cpus(alloc_new_cpu_counters); need_reinitialize = 0; printf("num_cpus is now %d\n", num_cpus); } @@ -726,7 +728,7 @@ void dummy(int pkg, int core, int cpu) { return; } /* * check to see if a cpu came on-line */ -void verify_num_cpus(void) +void verify_num_cpus() { int new_num_cpus; @@ -738,12 +740,14 @@ void verify_num_cpus(void) num_cpus, new_num_cpus); need_reinitialize = 1; } + + return; } void turbostat_loop() { restart: - get_counters(cnt_even); + get_counters(pcc_even); gettimeofday(&tv_even, (struct timezone *)NULL); while (1) { @@ -753,24 +757,24 @@ void turbostat_loop() goto restart; } sleep(interval_sec); - get_counters(cnt_odd); + get_counters(pcc_odd); gettimeofday(&tv_odd, (struct timezone *)NULL); - compute_delta(cnt_odd, cnt_even, cnt_delta); + compute_delta(pcc_odd, pcc_even, pcc_delta); timersub(&tv_odd, &tv_even, &tv_delta); - compute_average(cnt_delta, cnt_average); - print_counters(cnt_delta); + compute_average(pcc_delta, pcc_average); + print_counters(pcc_delta); if (need_reinitialize) { re_initialize(); goto restart; } sleep(interval_sec); - get_counters(cnt_even); + get_counters(pcc_even); gettimeofday(&tv_even, (struct timezone *)NULL); - compute_delta(cnt_even, cnt_odd, cnt_delta); + compute_delta(pcc_even, pcc_odd, pcc_delta); timersub(&tv_even, &tv_odd, &tv_delta); - compute_average(cnt_delta, cnt_average); - print_counters(cnt_delta); + compute_average(pcc_delta, pcc_average); + print_counters(pcc_delta); } } @@ -888,7 +892,7 @@ void check_cpuid() * this check is valid for both Intel and AMD */ asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x80000007)); - has_invariant_tsc = edx & (1 << 8); + has_invariant_tsc = edx && (1 << 8); if (!has_invariant_tsc) { fprintf(stderr, "No invariant TSC\n"); @@ -901,7 +905,7 @@ void check_cpuid() */ asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (0x6)); - has_aperf = ecx & (1 << 0); + has_aperf = ecx && (1 << 0); if (!has_aperf) { fprintf(stderr, "No APERF MSR\n"); exit(1); @@ -948,7 +952,7 @@ void turbostat_init() check_dev_msr(); check_super_user(); - num_cpus = for_all_cpus(alloc_new_counters); + num_cpus = for_all_cpus(alloc_new_cpu_counters); if (verbose) print_nehalem_info(); @@ -958,7 +962,7 @@ int fork_it(char **argv) { int retval; pid_t child_pid; - get_counters(cnt_even); + get_counters(pcc_even); gettimeofday(&tv_even, (struct timezone *)NULL); child_pid = fork(); @@ -981,14 +985,14 @@ int fork_it(char **argv) exit(1); } } - get_counters(cnt_odd); + get_counters(pcc_odd); gettimeofday(&tv_odd, (struct timezone *)NULL); - retval = compute_delta(cnt_odd, cnt_even, cnt_delta); + retval = compute_delta(pcc_odd, pcc_even, pcc_delta); timersub(&tv_odd, &tv_even, &tv_delta); - compute_average(cnt_delta, cnt_average); + compute_average(pcc_delta, pcc_average); if (!retval) - print_counters(cnt_delta); + print_counters(pcc_delta); fprintf(stderr, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0);;